26 local function data_injection(pos,data)
28 pool[minetest.hash_node_position(pos)] = true
30 pool[minetest.hash_node_position(pos)] = nil
35 local function create_axis(pos)
36 local possible_dirs = {}
37 for _,dir in pairs(dirs) do
38 local pos2 = vector.add(pos,dir)
39 if pool[minetest.hash_node_position(pos2)] then
40 table.insert(possible_dirs,dir)
46 local function collision_detect(self)
47 if not self.axis_lock then return end
48 local pos = self.object:get_pos()
50 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
51 if object:is_player() then
52 local pos2 = object:get_pos()
53 if self.axis_lock == "x" then
54 local velocity = (5-vector.distance(vector.new(pos.x,0,0),vector.new(pos2.x,0,0)))/10
56 local dir = vector.direction(vector.new(pos2.x,0,0),vector.new(pos.x,0,0))
57 --self.object:add_velocity(vector.multiply(dir,velocity))
58 self.velocity = vector.multiply(dir,velocity)
60 elseif self.axis_lock == "z" then
61 local velocity = (5-vector.distance(vector.new(0,0,pos.z),vector.new(0,0,pos2.z)))/10
63 local dir = vector.direction(vector.new(0,0,pos2.z),vector.new(0,0,pos.z))
64 --self.object:add_velocity(vector.multiply(dir,velocity))
65 self.velocity = vector.multiply(dir,velocity)
73 local function direction_snap(self)
75 local yaw = minetest.dir_to_yaw(dir)
76 self.object:set_rotation(vector.new(0,yaw,0))
79 local function turn_snap(pos,self,dir,dir2)
80 if dir.x ~= 0 and dir2.z ~= 0 then
81 --local inertia = math.abs(self.object:get_velocity().x)
82 local inertia = math.abs(self.velocity.x)
83 --self.object:set_velocity(vector.multiply(dir2,inertia))
85 self.velocity = vector.multiply(dir2,inertia)
88 self.object:set_pos(pos)
91 elseif dir.z ~= 0 and dir2.x ~= 0 then
92 --local inertia = math.abs(self.object:get_velocity().z)
93 --print(dump(self.velocity))
94 local inertia = math.abs(self.velocity.z)
95 --self.object:set_velocity(vector.multiply(dir2,inertia))
97 self.velocity = vector.multiply(dir2,inertia)
101 self.object:set_pos(pos)
107 local function rail_brain(self,pos)
108 if not self.dir then return end
110 --if self.dir then print(dump(self.dir)) end
112 local pos2 = self.object:get_pos()
116 local triggered = false
118 if dir.x < 0 and pos2.x < pos.x then
120 elseif dir.x > 0 and pos2.x > pos.x then
122 elseif dir.z < 0 and pos2.z < pos.z then
124 elseif dir.z > 0 and pos2.z > pos.z then
129 if triggered and not pool[minetest.hash_node_position(vector.add(pos,dir))] then
130 local possible_dirs = create_axis(pos)
131 if table.getn(possible_dirs) == 0 then
132 --print("train fails")
133 --stop slow down become physical, something
135 for _,dir2 in pairs(possible_dirs) do
136 if turn_snap(pos,self,dir,dir2) then
149 minecart.on_step = function(self,dtime)
150 local float_pos = self.object:get_pos()
151 local pos = vector.round(float_pos)
153 if self.velocity then
154 local new_vel = dtime/0.01
156 local test = vector.multiply(self.velocity,new_vel)
158 if test.x >= 0.5 then
159 test.x = 0.4999999999
160 elseif test.x <= -0.5 then
161 test.x = -0.4999999999
163 if test.z >= 0.5 then
164 test.z = 0.4999999999
165 elseif test.z <= -0.5 then
166 test.z = -0.4999999999
168 self.object:move_to(vector.add(float_pos,test))
172 --stop minecarts from derailing when going super fast
173 if self.old_pos and vector.distance(float_pos,self.old_pos) > 0.5 then
174 self.object:move_to(self.old_pos)
175 float_pos = self.object:get_pos()
176 pos = vector.round(self.old_pos)
179 if not self.axis_lock then
180 local possible_dirs = create_axis(pos)
181 for _,dir in pairs(possible_dirs) do
185 elseif dir.z ~= 0 then
191 collision_detect(self)
194 self.old_pos = float_pos
197 minecart.on_rightclick = function(self,clicker)
201 minecart.on_activate = function(self,staticdata, dtime_s)
202 self.object:set_armor_groups({immortal=1})
203 if string.sub(staticdata, 1, string.len("return")) ~= "return" then
206 local data = minetest.deserialize(staticdata)
207 if type(data) ~= "table" then
210 self.old_pos = self.object:get_pos()
211 self.velocity = vector.new(0,0,0)
214 minecart.get_staticdata = function(self)
215 return minetest.serialize({
221 minecart.initial_properties = {
222 physical = false, -- otherwise going uphill breaks
223 collisionbox = {-0.4, -0.5, -0.4, 0.4, 0.45, 0.4},--{-0.5, -0.4, -0.5, 0.5, 0.25, 0.5},
226 visual_size = {x=1, y=1},
227 textures = {"minecart.png"},
231 minecart.on_punch = function(self,puncher, time_from_last_punch, tool_capabilities, dir, damage)
232 --local obj = minetest.add_item(self.object:getpos(), "minecart:minecart")
233 --self.object:remove()
238 minetest.register_entity("minecart:minecart", minecart)
251 minetest.register_craftitem("minecart:minecart", {
252 description = "Minecart",
253 inventory_image = "minecartitem.png",
254 wield_image = "minecartitem.png",
255 on_place = function(itemstack, placer, pointed_thing)
256 if not pointed_thing.type == "node" then
260 local sneak = placer:get_player_control().sneak
261 local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
262 if not sneak and noddef.on_rightclick then
263 minetest.item_place(itemstack, placer, pointed_thing)
267 if minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "rail")>0 then
268 minetest.add_entity(pointed_thing.under, "minecart:minecart")
273 itemstack:take_item()
279 minetest.register_craft({
280 output = "minecart:minecart",
282 {"main:iron", "", "main:iron"},
283 {"main:iron", "main:iron", "main:iron"},
291 minetest.register_node("minecart:rail",{
292 description = "Rail",
293 wield_image = "rail.png",
295 "rail.png", "railcurve.png",
296 "railt.png", "railcross.png"
298 drawtype = "raillike",
300 sunlight_propagates = true,
301 is_ground_content = false,
303 node_placement_prediction = "",
306 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
308 sounds = main.stoneSound(),
309 after_place_node = function(pos)
310 data_injection(pos,true)
312 after_destruct = function(pos)
315 groups={stone=1,wood=1,rail=1,attached_node=1},
319 minetest.register_lbm({
320 name = "minecart:rail",
321 nodenames = {"minecart:rail"},
322 run_at_every_load = true,
323 action = function(pos)
324 data_injection(pos,true)
325 print("buildin dat cash")
329 minetest.register_craft({
330 output = "minecart:rail 32",
332 {"main:iron","","main:iron"},
333 {"main:iron","main:stick","main:iron"},
334 {"main:iron","","main:iron"}