many updates

can now control land, sea, and air mountables
This commit is contained in:
blert2112 2016-08-13 14:58:24 -04:00
parent cfb0afbe4c
commit 8c83022992
2 changed files with 169 additions and 103 deletions

View File

@ -3,17 +3,5 @@ Minetest mod: lib_mount
======================= =======================
by blert2112 by blert2112
Based on the Boats mod by PilzAdam. Based on the Boats mod by: PilzAdam.
License of source code: WTFPL
-----------------------------------------------------------
-----------------------------------------------------------
Minetest Game mod: boats
========================
by PilzAdam
License of source code:
-----------------------
WTFPL

256
init.lua
View File

@ -1,16 +1,32 @@
local mobs_redo = false local mobs_redo = false
if mobs.mod and mobs.mod == "redo" then if minetest.get_modpath("mobs") then
mobs_redo = true if mobs.mod and mobs.mod == "redo" then
mobs_redo = true
end
end end
-- --
-- Helper functions -- Helper functions
-- --
local function is_group(pos, group) --local function is_group(pos, group)
local nn = minetest.get_node(pos).name -- local nn = minetest.get_node(pos).name
return minetest.get_item_group(nn, group) ~= 0 -- return minetest.get_item_group(nn, group) ~= 0
--end
local function node_is(pos)
local node = minetest.get_node(pos)
if node.name == "air" then
return "air"
end
if minetest.get_item_group(node.name, "liquid") ~= 0 then
return "liquid"
end
if minetest.get_item_group(node.name, "walkable") ~= 0 then
return "walkable"
end
return "other"
end end
local function get_sign(i) local function get_sign(i)
@ -69,13 +85,21 @@ end)
lib_mount = {} lib_mount = {}
local half_a_pie = math.pi/2 local rot_steer, rot_view = math.pi/2, 0
function lib_mount.attach(entity, player, attach_at, eye_offset) function lib_mount.attach(entity, player, attach_at, eye_offset, rotation)
eye_offset = eye_offset or {x=0, y=0, z=0} eye_offset = eye_offset or {x=0, y=0, z=0}
rotation = rotation or {x=0, y=0, z=0}
if rotation.y == 90 then
rot_steer = 0
rot_view = math.pi/2
else
rot_steer = math.pi/2
rot_view = 0
end
force_detach(player) force_detach(player)
entity.driver = player entity.driver = player
player:set_attach(entity.object, "", attach_at, {x=0, y=0, z=0}) player:set_attach(entity.object, "", attach_at, rotation)
player:set_properties({visual_size = {x=1, y=1}}) player:set_properties({visual_size = {x=1, y=1}})
@ -84,15 +108,12 @@ function lib_mount.attach(entity, player, attach_at, eye_offset)
minetest.after(0.2, function() minetest.after(0.2, function()
default.player_set_animation(player, "sit" , 30) default.player_set_animation(player, "sit" , 30)
end) end)
entity.object:setyaw(player:get_look_yaw() - half_a_pie) player:set_look_yaw(entity.object:getyaw() - rot_view)
end end
function lib_mount.detach(entity, player, offset) function lib_mount.detach(player, offset)
entity.driver = nil force_detach(player)
player:set_detach()
default.player_attached[player:get_player_name()] = false
default.player_set_animation(player, "stand" , 30) default.player_set_animation(player, "stand" , 30)
player:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0})
local pos = player:getpos() local pos = player:getpos()
pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z}
minetest.after(0.1, function() minetest.after(0.1, function()
@ -100,115 +121,172 @@ function lib_mount.detach(entity, player, offset)
end) end)
end end
function lib_mount.drive(entity, dtime, moving_anim, stand_anim, jump_height, can_fly) function lib_mount.drive(entity, dtime, is_mob, moving_anim, stand_anim, jump_height, can_fly)
if can_fly and can_fly == true then if can_fly and can_fly == true then
jump_height = 0 jump_height = 0
end end
local velo = entity.object:getvelocity() if is_mob and not entity.v2 then
entity.v = get_v(velo) * get_sign(entity.v) entity.v2 = 0
entity.max_spd_f = 6
local ctrl = entity.driver:get_player_control() entity.max_spd_r = entity.max_spd_f-1
if ctrl.up then entity.accel = entity.max_spd_f
entity.v = entity.v + 0.1 entity.braking = entity.max_spd_f
elseif ctrl.down then entity.turn_spd = entity.max_spd_f+1
entity.v = entity.v - 0.1
end
if ctrl.aux1 then
entity.object:setyaw(entity.driver:get_look_yaw() - half_a_pie)
else
local yaw = entity.object:getyaw()
if ctrl.left then
if entity.v < 0 then
entity.object:setyaw(yaw - (1 + dtime) * 0.03)
else
entity.object:setyaw(yaw + (1 + dtime) * 0.03)
end
elseif ctrl.right then
if entity.v < 0 then
entity.object:setyaw(yaw + (1 + dtime) * 0.03)
else
entity.object:setyaw(yaw - (1 + dtime) * 0.03)
end
end
end end
local acce_y = 0 local acce_y = 0
if ctrl.jump then
if jump_height > 0 and velo.y == 0 then local velo = entity.object:getvelocity()
velo.y = velo.y + (jump_height * 3) + 1 entity.v = get_v(velo) * get_sign(entity.v)
acce_y = acce_y + (acce_y * 3) + 1
-- process controls
if entity.driver then
local ctrl = entity.driver:get_player_control()
if ctrl.up then
if get_sign(entity.v) >= 0 then
entity.v = entity.v + entity.accel/10
else
entity.v = entity.v + entity.braking/10
end
elseif ctrl.down then
if get_sign(entity.v) < 0 then
entity.v = entity.v - entity.accel/10
else
entity.v = entity.v - entity.braking/10
end
end end
if can_fly and can_fly == true then if ctrl.aux1 then
velo.y = velo.y + 1 entity.object:setyaw(entity.driver:get_look_yaw() - rot_steer)
acce_y = acce_y + 1 else
local yaw = entity.object:getyaw()
if ctrl.left then
entity.object:setyaw(entity.object:getyaw()+get_sign(entity.v)*math.rad(1+dtime)*entity.turn_spd)
elseif ctrl.right then
entity.object:setyaw(entity.object:getyaw()-get_sign(entity.v)*math.rad(1+dtime)*entity.turn_spd)
end
end
if ctrl.jump then
if jump_height > 0 and velo.y == 0 then
velo.y = velo.y + (jump_height * 3) + 1
acce_y = acce_y + (acce_y * 3) + 1
end
if can_fly and can_fly == true then
velo.y = velo.y + 1
acce_y = acce_y + 1
end
end
if ctrl.sneak then
if can_fly and can_fly == true then
velo.y = velo.y - 1
acce_y = acce_y - 1
end
end end
end end
-- if not moving then set animation and return
if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
if stand_anim and stand_anim ~= nil and mobs_redo == true then if is_mob then
set_animation(entity, stand_anim) if stand_anim and stand_anim ~= nil and mobs_redo == true then
set_animation(entity, stand_anim)
end
end end
--entity.object:setpos(entity.object:getpos())
return return
end end
if moving_anim and moving_anim ~= nil and mobs_redo == true then
set_animation(entity, moving_anim) -- set animation
if is_mob then
if moving_anim and moving_anim ~= nil and mobs_redo == true then
set_animation(entity, moving_anim)
end
end end
-- Stop!
local s = get_sign(entity.v) local s = get_sign(entity.v)
entity.v = entity.v - 0.02 * s entity.v = entity.v - 0.02 * s
if s ~= get_sign(entity.v) then if s ~= get_sign(entity.v) then
entity.object:setvelocity({x = 0, y = 0, z = 0}) entity.object:setvelocity({x=0, y=0, z=0})
entity.v = 0 entity.v = 0
return return
end end
if math.abs(entity.v) > 5 then
entity.v = 5 * get_sign(entity.v) -- enforce speed limit forward and reverse
local max_spd = entity.max_spd_r
if get_sign(entity.v) >= 0 then
max_spd = entity.max_spd_f
end
if math.abs(entity.v) > max_spd then
entity.v = entity.v - get_sign(entity.v)
end end
-- Set position, velocity and acceleration
local p = entity.object:getpos() local p = entity.object:getpos()
local new_velo = {x=0, y=0, z=0}
local new_acce = {x=0, y=-9.8, z=0}
p.y = p.y - 0.5 p.y = p.y - 0.5
local new_velo = {x = 0, y = 0, z = 0} local ni = node_is(p)
local new_acce = {x = 0, y = 0, z = 0} local v = entity.v
if not is_group(p, "crumbly") then if ni == "air" then
local nodedef = minetest.registered_nodes[minetest.get_node(p).name] if can_fly == true then
if (not nodedef) or nodedef.walkable then new_acce.y = 0
entity.v = 0
new_acce = {x = 0, y = 1, z = 0}
else
new_acce = {x = 0, y = -9.8, z = 0}
end end
new_velo = get_velocity(entity.v, entity.object:getyaw(), velo.y) elseif ni == "liquid" then
--entity.object:setpos(entity.object:getpos()) if entity.is_boat == true then
else new_acce.y = 0
p.y = p.y + 1 p.y = p.y + 1
if is_group(p, "crumbly") then if node_is(p) == "liquid" then
local y = velo.y if velo.y >= 5 then
if y >= 5 then velo.y = 5
y = 5 elseif velo.y < 0 then
elseif y < 0 then new_acce.y = 20
new_acce = {x = 0, y = 20, z = 0} else
new_acce.y = 5
end
else else
new_acce = {x = 0, y = 5, z = 0} new_acce.y = 0
if math.abs(velo.y) < 1 then
local pos = entity.object:getpos()
pos.y = math.floor(pos.y) + 0.5
entity.object:setpos(pos)
velo.y = 0
end
end end
new_velo = get_velocity(entity.v, entity.object:getyaw(), y)
--entity.object:setpos(entity.object:getpos())
else else
new_acce = {x = 0, y = 0, z = 0} v = v*0.75
if math.abs(velo.y) < 1 then
local pos = entity.object:getpos()
pos.y = math.floor(pos.y) + 0.5
--entity.object:setpos(pos)
new_velo = get_velocity(entity.v, entity.object:getyaw(), 0)
else
new_velo = get_velocity(entity.v, entity.object:getyaw(), velo.y)
--entity.object:setpos(entity.object:getpos())
end
end end
elseif ni == "walkable" then
v = 0
new_acce.y = 1
end end
new_velo = get_velocity(v, entity.object:getyaw() - rot_view, velo.y)
new_acce.y = new_acce.y + acce_y new_acce.y = new_acce.y + acce_y
entity.object:setvelocity(new_velo) entity.object:setvelocity(new_velo)
entity.object:setacceleration(new_acce) entity.object:setacceleration(new_acce)
-- CRASH!
local intensity = entity.v2 - entity.v
if intensity >= 10 then
if is_mob then
entity.object:set_hp(entity.object:get_hp() - intensity)
else
if entity.driver then
local drvr = entity.driver
lib_mount.detach(drvr, {x=0, y=0, z=0})
drvr:setvelocity(new_velo)
drvr:set_hp(drvr:get_hp() - intensity)
end
local pos = entity.object:getpos()
minetest.add_item(pos, entity.drop_on_destroy)
entity.removed = true
-- delay remove to ensure player is detached
minetest.after(0.1, function()
entity.object:remove()
end)
end
end
entity.v2 = entity.v
end end