-local path = minetest.get_modpath("minecart")
-dofile(path.."/rail.lua")
+local pool = {}
---this begins the minecart library
-local minecart = {}
+local dirs = {
+ {x= 1,y= 0,z= 0},
+ {x=-1,y= 0,z= 0},
+ {x= 1,y= 1,z= 0},
+ {x=-1,y= 1,z= 0},
---these are the variables for the minecart
-minecart.max_speed = 15
-minecart.speed = 0
-minecart.rider = nil
+ {x= 1,y=-1,z= 0},
+ {x=-1,y=-1,z= 0},
---binary direction
-minecart.get_dir = function(pos,pos2)
- return(minetest.facedir_to_dir(minetest.dir_to_facedir(vector.direction(pos2,pos))))
-end
---this gets the node position that the minecart is in
-minecart.round_pos = function(pos)
- return(vector.round(pos))
-end
+ {x= 0,y= 0,z= 1},
+ {x= 0,y= 0,z=-1},
---this is called when a player is standing next to the minecart
---it will take their position and convert it into binary then
---will begin movement
-minecart.set_direction = function(self,dir)
- if not self.goal then
- --reset the y to 0 since we will be checking up and down anyways
- dir.y = 0
- local pos = vector.add(minecart.round_pos(self.object:get_pos()),dir)
- local node = minetest.get_node(pos).name
- local node_above = minetest.get_node(vector.new(pos.x,pos.y+1,pos.z)).name
- local node_under = minetest.get_node(vector.new(pos.x,pos.y-1,pos.z)).name
-
- --next to
- if node == "minecart:rail" and node_under ~= "minecart:rail" then
- self.dir = dir
- self.goal = pos
- --downhill
- elseif node == "air" and node_under == "minecart:rail" then
- self.dir = vector.new(dir.x,dir.y-1,dir.z)
- self.goal = vector.new(pos.x,pos.y-1,pos.z)
- --uphill
- elseif node ~= "minecart:rail" and node_above == "minecart:rail" then
- self.dir = vector.new(dir.x,dir.y+1,dir.z)
- self.goal = vector.new(pos.x,pos.y+1,pos.z)
- --rail not found
- else
- self.goal = nil
- end
+ {x= 0,y= 1,z= 1},
+ {x= 0,y= 1,z=-1},
+
+ {x= 0,y=-1,z= 1},
+ {x= 0,y=-1,z=-1},
+}
+
+local axis_order = {
+
+}
+local function data_injection(pos,data)
+ if data then
+ pool[minetest.hash_node_position(pos)] = true
+ else
+ pool[minetest.hash_node_position(pos)] = nil
end
end
---this will turn the z into x and x into z
-minecart.flip_direction_axis = function(self)
- self.dir = vector.new(self.dir.z,0,self.dir.x)
-end
---this makes the minecart move in "blocks"
---it will go to it's goal then when it has reached the goal, move to another goal
-minecart.movement = function(self)
- if self.dir and self.goal then
- local pos = self.object:get_pos()
- local distance_from_goal = vector.distance(pos,self.goal)
-
-
- --make minecart slow down, but only so much
-
- --speed up going downhill
- if self.dir and (self.dir.y == -1 or self.rider) and self.speed < 10 then
- self.speed = self.speed + 0.1
- --slow down going uphill
- elseif self.dir and self.dir.y == 1 then
- self.speed = self.speed - 0.12
- --normal flat friction slowdown
- elseif self.speed > 0.1 then
- self.speed = self.speed - 0.01
+local function create_axis(pos)
+ local possible_dirs = {}
+ for _,dir in pairs(dirs) do
+ local pos2 = vector.add(pos,dir)
+ if pool[minetest.hash_node_position(pos2)] then
+ table.insert(possible_dirs,dir)
end
-
- --
- --if the minecart is slowed down below 1 nph (node per hour)
- --try to flip direction if pointing up
- --then stop it if failed
- if self.speed < 0.2 then
- if self.dir.y == 1 then
- self.dir = vector.multiply(self.dir, -1)
- minecart.set_direction(self,self.dir)
- self.goal = nil
- else
- self.speed = 0
- self.dir = nil
- self.goal = nil
- end
- end
-
- --this checks how far the minecart is from the "goal node"
- --aka the node that the minecart was supposed to go to
- if distance_from_goal < 0.2 or self.goal == nil then
- self.object:set_velocity(vector.new(0,0,0))
- self.goal = nil
- --self.object:move_to(minecart.round_pos(self.object:get_pos()))
-
- --otherwise try to keep going
- if self.dir then
- --test to see if minecart will keep moving
- minecart.set_direction(self,self.dir)
-
- --if not rail ahead then we'll try to turn
- if not self.goal then
- minecart.flip_direction_axis(self)
-
- minecart.set_direction(self,self.dir)
-
- --if trying to turn that direcion failed we'll try the other
- if not self.goal then
- self.dir = vector.multiply(self.dir, -1)
- minecart.set_direction(self,self.dir)
- end
- end
-
- --and if everything fails, give up and stop
- if not self.goal then
- self.speed = 0
- end
- end
- end
-
- if self.dir and self.goal then
- local movement = vector.direction(pos,self.goal)
- self.object:set_velocity(vector.multiply(movement,self.speed))
- end
-
- --stop the minecart from flying off into the distance
- elseif not vector.equals(self.object:get_velocity(), vector.new(0,0,0)) and (self.speed == 0 or not self.speed) then
- self.object:set_velocity(vector.new(0,0,0))
- --this is when the minecart is stopped
- --gotta figure out some way to apply gravity and make it physical
- --without breaking the rest of it
- elseif self.speed == 0 then
- --self.object:add_velocity(vector.new(0,-10,0))
end
-
-
+ print(dump(possible_dirs))
end
---this simply sets the mesh based on if the minecart is moving up or down
---this will be replaced by set animation in the future
-minecart.set_mesh = function(self)
- if self.dir and self.dir.y < 0 then
- self.object:set_animation({x=2,y=2}, 15, 0, true)
- elseif self.dir and self.dir.y > 0 then
- self.object:set_animation({x=1,y=1}, 15, 0, true)
- else
- self.object:set_animation({x=0,y=0}, 15, 0, true)
- end
-end
+
+
+local minecart = {}
+
+
minecart.on_step = function(self,dtime)
- local pos = self.object:get_pos()
-
- --get player input (standing next to the minecart)
- for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
- if self.object ~= object and object:is_player() and object:get_player_name() ~= self.rider then
- local pos2 = object:get_pos()
- minecart.set_direction(self, minecart.get_dir(pos,pos2))
- self.speed = 7
- end
- end
-
- --this makes the minecart actually move, it is also
- --the begining of it's logic
- minecart.movement(self)
-
- --set the minecart's mesh
- minecart.set_mesh(self)
+ local pos = vector.round(self.object:get_pos())
+ create_axis(pos)
end
---make the player ride the minecart
---or make the player get off
minecart.on_rightclick = function(self,clicker)
- if not clicker or not clicker:is_player() then return end
- local name = clicker:get_player_name()
-
- --get on the minecart
- if not self.rider then
- self.rider = name
- clicker:set_attach(self.object, "", {x=0, y=0, z=0}, {x=0, y=0, z=0})
- --get off the minecart
- elseif name == self.rider then
- self.rider = nil
- clicker:set_detach()
- end
end
--get old data
if type(data) ~= "table" then
return
end
- self.dir = data.dir
- self.goal = data.goal
- self.speed = data.speed
-
- --run through if there was a rider then check if they exist and put them back on
- --and if they don't exist then nillify the rider value
- if data.rider then
- if minetest.player_exists(data.rider) then
- self.rider = data.rider
- local player = minetest.get_player_by_name(data.rider)
- player:set_attach(self.object, "", {x=0, y=0, z=0}, {x=0, y=0, z=0})
- else
- self.rider = nil
- end
- else
- self.rider = nil
- end
-
-
+
end
---remember data
+
minecart.get_staticdata = function(self)
return minetest.serialize({
- dir = self.dir,
- goal = self.goal,
- speed = self.speed,
- rider = self.rider
})
end
mesh = "minecart.x",
visual_size = {x=1, y=1},
textures = {"minecart.png"},
- automatic_face_movement_dir = 90.0,
- automatic_face_movement_max_rotation_per_sec = 1200,
}
minecart.on_punch = function(self,puncher, time_from_last_punch, tool_capabilities, dir, damage)
- local obj = minetest.add_item(self.object:getpos(), "minecart:minecart")
- self.object:remove()
+ --local obj = minetest.add_item(self.object:getpos(), "minecart:minecart")
+ --self.object:remove()
end
{"main:iron", "main:iron", "main:iron"},
},
})
+
+
+
+
+
+minetest.register_node("minecart:rail",{
+ description = "Rail",
+ wield_image = "rail.png",
+ tiles = {
+ "rail.png", "railcurve.png",
+ "railt.png", "railcross.png"
+ },
+ drawtype = "raillike",
+ paramtype = "light",
+ sunlight_propagates = true,
+ is_ground_content = false,
+ walkable = false,
+ node_placement_prediction = "",
+ selection_box = {
+ type = "fixed",
+ fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
+ },
+ sounds = main.stoneSound(),
+ after_place_node = function(pos)
+ data_injection(pos,true)
+ end,
+ after_destruct = function(pos)
+ data_injection(pos)
+ end,
+ groups={stone=1,wood=1,rail=1,attached_node=1},
+})
+
+
+minetest.register_lbm({
+ name = "minecart:rail",
+ nodenames = {"minecart:rail"},
+ run_at_every_load = true,
+ action = function(pos)
+ data_injection(pos,true)
+ print("buildin dat cash")
+ end,
+})
+
+minetest.register_craft({
+ output = "minecart:rail 32",
+ recipe = {
+ {"main:iron","","main:iron"},
+ {"main:iron","main:stick","main:iron"},
+ {"main:iron","","main:iron"}
+ }
+})
-minetest.register_node("minecart:rail",{
- description = "Rail",
- wield_image = "rail.png",
- tiles = {
- "rail.png", "railcurve.png",
- "railt.png", "railcross.png"
- },
- drawtype = "raillike",
- paramtype = "light",
- sunlight_propagates = true,
- is_ground_content = false,
- walkable = false,
- node_placement_prediction = "",
- selection_box = {
- type = "fixed",
- fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
- },
- sounds = main.stoneSound(),
- on_place = function(itemstack, placer, pointed_thing)
- if not pointed_thing.type == "node" then
- return
- end
-
- local sneak = placer:get_player_control().sneak
- local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
- if not sneak and noddef.on_rightclick then
- minetest.item_place(itemstack, placer, pointed_thing)
- return
- end
- local buildable = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name].buildable_to
- --replace buildable
- if buildable and minetest.get_node_group(minetest.get_node(vector.new(pointed_thing.under.x,pointed_thing.under.y-1,pointed_thing.under.z)).name, "soil") > 0 then
- return(minetest.item_place(itemstack, placer, pointed_thing))
- end
- --replace buildable above
- local buildable = minetest.registered_nodes[minetest.get_node(pointed_thing.above).name].buildable_to
- if buildable and minetest.get_node_group(minetest.get_node(vector.new(pointed_thing.above.x,pointed_thing.above.y-1,pointed_thing.above.z)).name, "soil") > 0 then
- return(minetest.item_place(itemstack, placer, pointed_thing))
- end
- --normal
- local pos = pointed_thing.above
- if minetest.registered_nodes[minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name].walkable and minetest.get_node(pointed_thing.above).name == "air" then
- minetest.set_node(pointed_thing.above, {name="minecart:rail"})
- itemstack:take_item(1)
- minetest.sound_play("stone",{pos=pointed_thing.above})
- return(itemstack)
- end
- end,
- groups={stone=1,wood=1,rail=1},
-})
-
-minetest.register_craft({
- output = "minecart:rail 32",
- recipe = {
- {"main:iron","","main:iron"},
- {"main:iron","main:stick","main:iron"},
- {"main:iron","","main:iron"}
- }
-})