Vehicles mod code style fixed

master
Ilya Zhuravlev 2012-04-24 22:32:08 +04:00
parent 3d74b1e93e
commit 2abfdf7a7c
1 changed files with 170 additions and 169 deletions

View File

@ -10,44 +10,44 @@ local stepsize = 0.05
local eps = 0.1
local cart = {
physical = true,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- TODO: make better collisionbox
visual = "cube",
textures = {"vehicles_cart_top.png", "vehicles_cart_side.png", "vehicles_cart_side.png", "vehicles_cart_side.png", "vehicles_cart_side.png", "vehicles_cart_side.png"},
attached_to = false,
time = 0.0,
vec = {x = 0, z = 0},
health = 3,
moving = false,
stopnow = false
physical = true,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- TODO: make better collisionbox
visual = "cube",
textures = {"vehicles_cart_top.png", "vehicles_cart_side.png", "vehicles_cart_side.png", "vehicles_cart_side.png", "vehicles_cart_side.png", "vehicles_cart_side.png"},
attached_to = false,
time = 0.0,
vec = {x = 0, z = 0},
health = 3,
moving = false,
stopnow = false
}
local round = function(num)
return math.floor(num + 0.5)
return math.floor(num + 0.5)
end
local sign = function(num)
if math.abs(num) < eps then
return 0
end
if num > 0 then
return 1
else
return -1
end
if math.abs(num) < eps then
return 0
end
if num > 0 then
return 1
else
return -1
end
end
-- rotate vector by 90 degrees
local rotated = function(v)
return {x = -v.z, z = v.x}
return {x = -v.z, z = v.x}
end
-- make set from list
local Set = function (list)
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
end
-- TODO: use .walkable property
@ -55,205 +55,206 @@ local air_equivalent = Set{"air", "default:torch", "water"}
-- is there air/something airlike on {pos}
local is_air = function(pos)
return air_equivalent[minetest.env:get_node(pos).name]
return air_equivalent[minetest.env:get_node(pos).name]
end
local rail_equivalent = Set{"default:rail"}
-- is there something raillike on {pos}?
local is_rail = function(pos)
if rail_equivalent[minetest.env:get_node(pos).name] then
return true
else
return false
end
if rail_equivalent[minetest.env:get_node(pos).name] then
return true
else
return false
end
end
-- returns vector length
local length = function(v)
return math.sqrt(v.x*v.x+v.y*v.y+v.z*v.z)
return math.sqrt(v.x*v.x+v.y*v.y+v.z*v.z)
end
-- returns resized vector
local resize = function(v, l)
local len = length(v)
return {x = v.x / len * l, y = v.y / len * l, z = v.z / len * l}
local len = length(v)
return {x = v.x / len * l, y = v.y / len * l, z = v.z / len * l}
end
-- moves point P on vector V
local move = function(p, v)
return {x = p.x + v.x, y = p.y + v.y, z = p.z + v.z}
return {x = p.x + v.x, y = p.y + v.y, z = p.z + v.z}
end
-- is float a == float b
local eq = function(a, b)
return math.abs(a - b) < eps
return math.abs(a - b) < eps
end
-- returns distance between a and b
local dist = function(a, b)
return math.sqrt((a.x-b.x)*(a.x-b.x) + (a.z-b.z)*(a.z-b.z))
return math.sqrt((a.x-b.x)*(a.x-b.x) + (a.z-b.z)*(a.z-b.z))
end
function cart:on_step(dtime)
--self.object:setacceleration({x = 0, y = -10, z = 0})
--self.object:setacceleration({x = 0, y = -10, z = 0})
if self.attached_to == false then
return
end
return
end
self.time = self.time + dtime
if self.time >= stepsize then
self.time = 0
end
self.time = self.time + dtime
if self.time >= stepsize then
self.time = 0
end
-- first state: cart is moving
if self.moving ~= false and self.time == 0 then
local pos_f = self.object:getpos()
if self.moving ~= false then
if eq(pos_f.x, self.moving.x) and eq(pos_f.y, self.moving.y) and eq(pos_f.z, self.moving.z) then
self.moving = false
self.object:setacceleration({x = 0, y = -10, z = 0})
if self.stopnow then
self.stopnow = false
self.attached_to = false
end
else
local needed = {x = self.moving.x - pos_f.x,
y = self.moving.y - pos_f.y,
z = self.moving.z - pos_f.z}
needed = resize(needed, math.min(length(needed), speed))
self.object:setpos(move(pos_f, needed))
-- move player that attached to this cart; FIXME
local player = minetest.env:get_player_by_name(self.attached_to)
player:setpos(self.object:getpos())
-- first state: cart is moving
if self.moving ~= false and self.time == 0 then
local pos_f = self.object:getpos()
if self.moving ~= false then
if eq(pos_f.x, self.moving.x) and eq(pos_f.y, self.moving.y) and eq(pos_f.z, self.moving.z) then
self.moving = false
self.object:setacceleration({x = 0, y = -10, z = 0})
if self.stopnow then
self.stopnow = false
self.attached_to = false
end
else
local needed = {x = self.moving.x - pos_f.x,
y = self.moving.y - pos_f.y,
z = self.moving.z - pos_f.z}
needed = resize(needed, math.min(length(needed), speed))
self.object:setpos(move(pos_f, needed))
-- move player that attached to this cart; FIXME
local player = minetest.env:get_player_by_name(self.attached_to)
local cur_pos = self.object:getpos()
player:setpos({x = cur_pos.x, y = cur_pos.y - 0.5, z = cur_pos.z})
end
return
end
end
-- second state: cart just need to check whether to move next self.time==0
if self.moving == false then
--print("position: "..pos_f.x.." "..pos_f.y.." "..pos_f.z)
local pos_f = self.object:getpos()
local pos = {x = round(pos_f.x), y = round(pos_f.y), z = round(pos_f.z)}
-- if cart is not on rails now, don't move it
local node_below = minetest.env:get_node(pos)
if node_below.name ~= "default:rail" then
self.attached_to = false
return
end
local v = {x = self.vec.x, z = self.vec.z}
local pos_next = {x = pos.x, y = pos.y, z = pos.z}
local node_next
--print("vector: "..v.x.." "..v.z)
local our_direction = true
local on_different_y = false
local on_different_y_vec = false
for i = 1, 4 do
for dy = -1, 1 do
pos_next.x = pos.x + v.x
pos_next.z = pos.z + v.z
pos_next.y = pos.y + dy
return
end
end
--print("position: "..pos.x.." "..pos.z.." at: ("..pos_next.x.."; "..pos_next.z.."): ".." v is "..v.x.." "..dy.." "..v.z)
if is_rail(pos_next) and (v.x ~= -self.vec.x or v.z ~= -self.vec.z) then
if dy ~= 0 then
if on_different_y == false and
(dy == 1 and is_air({x = pos.x, y = pos.y + 1, z = pos.z})) or
(dy == -1 and is_air({x = pos_next.x, y = pos_next.y + 1, z = pos_next.z})) then
on_different_y = {x = pos_next.x, y = pos_next.y, z = pos_next.z}
on_different_y_vec = {x = v.x, z = v.z}
end
end
--print(minetest.env:get_node({x = pos_next.x, y = pos_next.y + 1, z = pos_next.z}).name)
if (dy == 0) or our_direction then
if dy ~= 0 then
self.object:setacceleration({x = 0, y = 0, z = 0})
end
self.moving = pos_next
self.vec = v
return
end
end
end
-- second state: cart just need to check whether to move next self.time==0
if self.moving == false then
--print("position: "..pos_f.x.." "..pos_f.y.." "..pos_f.z)
local pos_f = self.object:getpos()
local pos = {x = round(pos_f.x), y = round(pos_f.y), z = round(pos_f.z)}
-- rotate our vector
v = rotated(v)
our_direction = false
end
if on_different_y ~= false then
--print("moving between Y")
self.moving = on_different_y
self.vec = on_different_y_vec
self.object:setacceleration({x = 0, y = 0, z = 0})
return
end
-- if cart is not on rails now, don't move it
local node_below = minetest.env:get_node(pos)
if node_below.name ~= "default:rail" then
self.attached_to = false
return
end
-- if not moved - stop
self.attached_to = false
end
local v = {x = self.vec.x, z = self.vec.z}
local pos_next = {x = pos.x, y = pos.y, z = pos.z}
local node_next
--print("vector: "..v.x.." "..v.z)
local our_direction = true
local on_different_y = false
local on_different_y_vec = false
for i = 1, 4 do
for dy = -1, 1 do
pos_next.x = pos.x + v.x
pos_next.z = pos.z + v.z
pos_next.y = pos.y + dy
--print("position: "..pos.x.." "..pos.z.." at: ("..pos_next.x.."; "..pos_next.z.."): ".." v is "..v.x.." "..dy.." "..v.z)
if is_rail(pos_next) and (v.x ~= -self.vec.x or v.z ~= -self.vec.z) then
if dy ~= 0 then
if on_different_y == false and
(dy == 1 and is_air({x = pos.x, y = pos.y + 1, z = pos.z})) or
(dy == -1 and is_air({x = pos_next.x, y = pos_next.y + 1, z = pos_next.z})) then
on_different_y = {x = pos_next.x, y = pos_next.y, z = pos_next.z}
on_different_y_vec = {x = v.x, z = v.z}
end
end
--print(minetest.env:get_node({x = pos_next.x, y = pos_next.y + 1, z = pos_next.z}).name)
if (dy == 0) or our_direction then
if dy ~= 0 then
self.object:setacceleration({x = 0, y = 0, z = 0})
end
self.moving = pos_next
self.vec = v
return
end
end
end
-- rotate our vector
v = rotated(v)
our_direction = false
end
if on_different_y ~= false then
--print("moving between Y")
self.moving = on_different_y
self.vec = on_different_y_vec
self.object:setacceleration({x = 0, y = 0, z = 0})
return
end
-- if not moved - stop
self.attached_to = false
end
end
function cart:on_rightclick(clicker)
if self.attached_to == false then
self.attached_to = clicker:get_player_name()
local playerpos = clicker:getpos()
local selfpos = self.object:getpos()
local best = 1e15
-- find initial moving direction by searching through 4 nearby possibly positions
self.vec = {x = 1, z = 0}
for dx = -1,1 do
for dz = -1,1 do
if (dx * dz == 0) and (dx ~= 0 or dz ~= 0) then
local dst = dist(playerpos, {x = selfpos.x + dx, z = selfpos.z + dz})
if dst < best
and (is_rail({x = selfpos.x - dx, y = selfpos.y, z = selfpos.z - dz})
or is_rail({x = selfpos.x - dx, y = selfpos.y + 1, z = selfpos.z - dz})
or is_rail({x = selfpos.x - dx, y = selfpos.y - 1, z = selfpos.z - dz})) then
best = dst
self.vec = {x = -dx, z = -dz}
end
end
end
end
else
self.stopnow = true
end
if self.attached_to == false then
self.attached_to = clicker:get_player_name()
local playerpos = clicker:getpos()
local selfpos = self.object:getpos()
local best = 1e15
-- find initial moving direction by searching through 4 nearby possibly positions
self.vec = {x = 1, z = 0}
for dx = -1,1 do
for dz = -1,1 do
if (dx * dz == 0) and (dx ~= 0 or dz ~= 0) then
local dst = dist(playerpos, {x = selfpos.x + dx, z = selfpos.z + dz})
if dst < best
and (is_rail({x = selfpos.x - dx, y = selfpos.y, z = selfpos.z - dz})
or is_rail({x = selfpos.x - dx, y = selfpos.y + 1, z = selfpos.z - dz})
or is_rail({x = selfpos.x - dx, y = selfpos.y - 1, z = selfpos.z - dz})) then
best = dst
self.vec = {x = -dx, z = -dz}
end
end
end
end
else
self.stopnow = true
end
end
function cart:on_punch(hitter)
self.health = self.health - 1
if self.health <= 0 then
self.object:remove()
hitter:get_inventory():add_item("main", "vehicles:cart 1")
return ""
self.health = self.health - 1
if self.health <= 0 then
self.object:remove()
hitter:get_inventory():add_item("main", "vehicles:cart 1")
return ""
end
end
function cart:on_activate(staticdata)
self.object:setacceleration({x = 0, y = -10, z = 0})
self.object:setacceleration({x = 0, y = -10, z = 0})
end
minetest.register_entity("vehicles:cart", cart)
minetest.register_craftitem("vehicles:cart", {
inventory_image = "vehicles_cart_inventory.png",
on_drop = function(itemstack, dropper, pos)
inventory_image = "vehicles_cart_inventory.png",
on_drop = function(itemstack, dropper, pos)
minetest.env:add_entity({x = round(pos.x), y = round(pos.y), z = round(pos.z)}, "vehicles:cart")
--return true
end
--return true
end
})
minetest.register_craft({
output = '"vehicles:cart" 1',
recipe = {
{'default:steel_ingot', '', 'default:steel_ingot'},
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}
}
output = '"vehicles:cart" 1',
recipe = {
{'default:steel_ingot', '', 'default:steel_ingot'},
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}
}
})