diff options
Diffstat (limited to 'railcart')
| -rw-r--r-- | railcart/LICENSE.txt | 19 | ||||
| -rw-r--r-- | railcart/README.txt | 30 | ||||
| -rw-r--r-- | railcart/depends.txt | 1 | ||||
| -rw-r--r-- | railcart/init.lua | 154 | ||||
| -rw-r--r-- | railcart/models/cart.png | bin | 0 -> 422 bytes | |||
| -rw-r--r-- | railcart/models/railcart.x | 339 | ||||
| -rw-r--r-- | railcart/railcart.lua | 252 | ||||
| -rw-r--r-- | railcart/textures/cart.png | bin | 0 -> 422 bytes | |||
| -rw-r--r-- | railcart/textures/cart_bottom.png | bin | 0 -> 154 bytes | |||
| -rw-r--r-- | railcart/textures/cart_side.png | bin | 0 -> 192 bytes | |||
| -rw-r--r-- | railcart/textures/cart_top.png | bin | 0 -> 262 bytes | 
11 files changed, 795 insertions, 0 deletions
| diff --git a/railcart/LICENSE.txt b/railcart/LICENSE.txt new file mode 100644 index 0000000..5f3db02 --- /dev/null +++ b/railcart/LICENSE.txt @@ -0,0 +1,19 @@ +Minetest Mod - Railcart [railcart] +================================== + +License Source Code: LGPL v2.1 + +License of media (textures, sounds and models): CC-0 + +Authors of media files: +----------------------- + +kddekadenz: +  cart_bottom.png +  cart_side.png +  cart_top.png + +Zeg9: +  cart.x +  cart.png + diff --git a/railcart/README.txt b/railcart/README.txt new file mode 100644 index 0000000..dd4d70e --- /dev/null +++ b/railcart/README.txt @@ -0,0 +1,30 @@ +Minetest Mod - Railcart [railcart] +================================== + +Minetest version: 0.4.13 + +Depends: railtrack + +Proof of concept ground up re-write of the carts mod. Currently uses media files +borrowed from the original carts mod by PilzAdam. + +Please note, this mod makes heavy use of metadata so that carts are able to +travel through unloaded map chunks, therefor a 'carts' privilege is required +to place or pick up carts in multiplayer mode. + +Crafting +-------- + +S = Steel Ingot [default:steel_ingot] +W = Wood [group:wood] + +Railcart: [railcart:cart] + ++---+---+---+ +| S |   | S | ++---+---+---+ +| S |   | S | ++---+---+---+ +| W | S | W | ++---+---+---+ + diff --git a/railcart/depends.txt b/railcart/depends.txt new file mode 100644 index 0000000..e602f16 --- /dev/null +++ b/railcart/depends.txt @@ -0,0 +1 @@ +railtrack diff --git a/railcart/init.lua b/railcart/init.lua new file mode 100644 index 0000000..df9d4f1 --- /dev/null +++ b/railcart/init.lua @@ -0,0 +1,154 @@ +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +dofile(modpath.."/railcart.lua") + +local worldpath = minetest.get_worldpath() +local input = io.open(worldpath.."/railcart.txt", "r") +if input then +	local data = input:read('*all') +	if data then +		local carts = minetest.deserialize(data) or {} +		for id, ref in pairs(carts) do +			railcart.allcarts[id] = railcart.cart:new(ref) +		end +	end +	input = nil +end + +local function is_valid_player(object) +	if object then +		return object:is_player() +	end +end + +minetest.register_globalstep(function(dtime) +	for _, cart in pairs(railcart.allcarts) do +		cart:on_step(dtime) +	end +	railcart.timer = railcart.timer + dtime +	if railcart.timer > RAILCART_OBJECT_SAVE_TIME then +		railcart:save() +		railcart.timer = 0 +	end +end) + +minetest.register_privilege("carts", "Player can pick-up and place carts.") + +minetest.register_entity("railcart:cart_entity", { +	physical = false, +	collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, +	visual = "mesh", +	mesh = "railcart.x", +	visual_size = {x=1, y=1}, +	textures = {"cart.png"}, +	cart = nil, +	driver = nil, +	timer = 0, +	on_activate = function(self, staticdata, dtime_s) +		self.object:set_armor_groups({immortal=1}) +		if staticdata == "expired" then +			self.object:remove() +		end +	end, +	on_punch = function(self, puncher, _, _, direction) +		if not is_valid_player(puncher) then +			return +		end	 +		if puncher:get_player_control().sneak then +			if self.cart then +				if self.cart.id then +					railcart.allcarts[self.cart.id] = nil +				end +			end +			self.object:remove() +			local inv = puncher:get_inventory() +			if minetest.setting_getbool("creative_mode") then +				if not inv:contains_item("main", "railcart:cart") then +					inv:add_item("main", "railcart:cart") +				end +			else +				inv:add_item("main", "railcart:cart") +			end +			return +		end +		if self.cart and direction then +			local pos = vector.round(self.object:getpos()) +			local dir = vector.round(vector.normalize(direction)) +			self.timer = 0 +			self.cart.target = nil +			self.cart.prev = pos +			self.cart.vel = vector.multiply(dir, 4) +			self.cart.accel = railtrack:get_acceleration(pos) +			self.object:setvelocity(self.cart.vel) +		end +	end, +	on_rightclick = function(self, clicker) +		if not is_valid_player(clicker) then +			return +		end +		if self.driver and clicker == self.driver then +			self.driver = nil +			clicker:set_detach() +		elseif not self.driver then +			self.driver = clicker +			clicker:set_attach(self.object, "", {x=0,y=5,z=0}, {x=0,y=0,z=0}) +		end +	end, +	on_step = function(self, dtime) +		local cart = self.cart +		local object = self.object +		if not cart or not object then +			return +		end +		self.timer = self.timer - dtime +		if self.timer > 0 then +			return +		end +		self.timer = railcart:update(cart, RAILCART_ENTITY_UPDATE_TIME, object) +	end, +	get_staticdata = function(self) +		return "expired" +	end, +}) + +minetest.register_craftitem("railcart:cart", { +	description = "Railcart", +	inventory_image = minetest.inventorycube("cart_top.png", "cart_side.png", "cart_side.png"), +	wield_image = "cart_side.png", +	on_place = function(itemstack, placer, pointed_thing) +		local name = placer:get_player_name() +		if not name or pointed_thing.type ~= "node" then +			return +		end +		local pos = pointed_thing.under +		if not railtrack:is_railnode(pos) then +			return +		end +		if not minetest.is_singleplayer() then +			if not minetest.check_player_privs(name, {carts=true}) then +				minetest.chat_send_player(name, "Requires carts privilege") +				return +			end +		end +		local cart = railcart.cart:new() +		cart.id = #railcart.allcarts + 1 +		cart.pos = pos +		cart.prev = vector.new(pos) +		cart.accel = railtrack:get_acceleration(pos) +		table.insert(railcart.allcarts, cart) +		if not minetest.setting_getbool("creative_mode") then +			itemstack:take_item() +		end +		return itemstack +	end, +}) + +minetest.register_craft({ +	output = "railcart:cart", +	recipe = { +		{"default:steel_ingot", "", "default:steel_ingot"}, +		{"default:steel_ingot", "", "default:steel_ingot"}, +		{"group:wood", "default:steel_ingot", "group:wood"}, +	}, +}) + diff --git a/railcart/models/cart.png b/railcart/models/cart.pngBinary files differ new file mode 100644 index 0000000..1f9f568 --- /dev/null +++ b/railcart/models/cart.png diff --git a/railcart/models/railcart.x b/railcart/models/railcart.x new file mode 100644 index 0000000..3325aaf --- /dev/null +++ b/railcart/models/railcart.x @@ -0,0 +1,339 @@ +xof 0303txt 0032 + +Frame Root { +  FrameTransformMatrix { +     1.000000, 0.000000, 0.000000, 0.000000, +     0.000000, 0.000000, 1.000000, 0.000000, +     0.000000, 1.000000,-0.000000, 0.000000, +     0.000000, 0.000000, 0.000000, 1.000000;; +  } +  Frame Cube { +    FrameTransformMatrix { +       5.000000, 0.000000,-0.000000, 0.000000, +      -0.000000, 3.535534, 3.535534, 0.000000, +       0.000000,-3.535534, 3.535534, 0.000000, +       0.000000,-3.000000, 3.000000, 1.000000;; +    } +    Mesh { //Cube_001 Mesh +      72; +      -1.000000; 1.000000;-1.000000;, +      -1.000000;-1.000000;-1.000000;, +       1.000000;-1.000000;-1.000000;, +       1.000000; 1.000000;-1.000000;, +      -0.833334;-1.000000; 1.000000;, +      -1.000000;-1.000000; 1.000000;, +      -1.000000;-0.833333; 1.000000;, +      -0.833334;-0.833333; 1.000000;, +      -1.000000;-1.000000;-1.000000;, +      -1.000000;-1.000000; 1.000000;, +       0.999999;-1.000001; 1.000000;, +       1.000000;-1.000000;-1.000000;, +       0.999999;-1.000001; 1.000000;, +       0.833332;-1.000000; 1.000000;, +       0.833333;-0.833334; 1.000000;, +       1.000000;-0.833334; 1.000000;, +       0.833332;-1.000000; 1.000000;, +      -0.833334;-1.000000; 1.000000;, +      -0.833334;-0.833333; 1.000000;, +       0.833333;-0.833334; 1.000000;, +       1.000000; 0.833333; 1.000000;, +       0.833334; 0.833333; 1.000000;, +       0.833334; 1.000000; 1.000000;, +       1.000000; 0.999999; 1.000000;, +       1.000000;-0.833334; 1.000000;, +       0.833333;-0.833334; 1.000000;, +       0.833334; 0.833333; 1.000000;, +       1.000000; 0.833333; 1.000000;, +       0.833334; 0.833333; 1.000000;, +      -0.833333; 0.833333; 1.000000;, +      -0.833333; 1.000000; 1.000000;, +       0.833334; 1.000000; 1.000000;, +       0.833334; 0.833333;-0.800000;, +      -0.833333; 0.833333;-0.800000;, +      -0.833333; 0.833333; 1.000000;, +       0.833334; 0.833333; 1.000000;, +      -0.833333; 0.833333; 1.000000;, +      -1.000000; 0.833333; 1.000000;, +      -1.000000; 1.000000; 1.000000;, +      -0.833333; 1.000000; 1.000000;, +      -0.833334;-0.833333; 1.000000;, +      -1.000000;-0.833333; 1.000000;, +      -1.000000; 0.833333; 1.000000;, +      -0.833333; 0.833333; 1.000000;, +       0.833333;-0.833334;-0.800000;, +      -0.833334;-0.833333;-0.800000;, +      -0.833333; 0.833333;-0.800000;, +       0.833334; 0.833333;-0.800000;, +      -0.833333; 0.833333;-0.800000;, +      -0.833334;-0.833333;-0.800000;, +      -0.833334;-0.833333; 1.000000;, +      -0.833333; 0.833333; 1.000000;, +      -0.833334;-0.833333;-0.800000;, +       0.833333;-0.833334;-0.800000;, +       0.833333;-0.833334; 1.000000;, +      -0.833334;-0.833333; 1.000000;, +       0.833333;-0.833334;-0.800000;, +       0.833334; 0.833333;-0.800000;, +       0.833334; 0.833333; 1.000000;, +       0.833333;-0.833334; 1.000000;, +      -1.000000; 1.000000;-1.000000;, +      -1.000000; 1.000000; 1.000000;, +      -1.000000;-1.000000; 1.000000;, +      -1.000000;-1.000000;-1.000000;, +      -1.000000; 1.000000; 1.000000;, +      -1.000000; 1.000000;-1.000000;, +       1.000000; 1.000000;-1.000000;, +       1.000000; 0.999999; 1.000000;, +       1.000000;-1.000000;-1.000000;, +       0.999999;-1.000001; 1.000000;, +       1.000000; 0.999999; 1.000000;, +       1.000000; 1.000000;-1.000000;; +      18; +      4;0;1;2;3;, +      4;4;5;6;7;, +      4;8;9;10;11;, +      4;12;13;14;15;, +      4;16;17;18;19;, +      4;20;21;22;23;, +      4;24;25;26;27;, +      4;28;29;30;31;, +      4;32;33;34;35;, +      4;36;37;38;39;, +      4;40;41;42;43;, +      4;44;45;46;47;, +      4;48;49;50;51;, +      4;52;53;54;55;, +      4;56;57;58;59;, +      4;60;61;62;63;, +      4;64;65;66;67;, +      4;68;69;70;71;; +      MeshNormals { //Cube_001 Normals +        72; +         0.000000; 0.000000;-1.000000;, +         0.000000; 0.000000;-1.000000;, +         0.000000; 0.000000;-1.000000;, +         0.000000; 0.000000;-1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +        -0.000000;-1.000000;-0.000000;, +        -0.000000;-1.000000;-0.000000;, +        -0.000000;-1.000000;-0.000000;, +        -0.000000;-1.000000;-0.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +        -0.000000;-1.000000; 0.000000;, +        -0.000000;-1.000000; 0.000000;, +        -0.000000;-1.000000; 0.000000;, +        -0.000000;-1.000000; 0.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         0.000000;-0.000000; 1.000000;, +         1.000000;-0.000000; 0.000000;, +         1.000000;-0.000000; 0.000000;, +         1.000000;-0.000000; 0.000000;, +         1.000000;-0.000000; 0.000000;, +         0.000000; 1.000000; 0.000000;, +         0.000000; 1.000000; 0.000000;, +         0.000000; 1.000000; 0.000000;, +         0.000000; 1.000000; 0.000000;, +        -1.000000; 0.000000; 0.000000;, +        -1.000000; 0.000000; 0.000000;, +        -1.000000; 0.000000; 0.000000;, +        -1.000000; 0.000000; 0.000000;, +        -1.000000; 0.000000;-0.000000;, +        -1.000000; 0.000000;-0.000000;, +        -1.000000; 0.000000;-0.000000;, +        -1.000000; 0.000000;-0.000000;, +         0.000000; 1.000000; 0.000000;, +         0.000000; 1.000000; 0.000000;, +         0.000000; 1.000000; 0.000000;, +         0.000000; 1.000000; 0.000000;, +         1.000000;-0.000000; 0.000000;, +         1.000000;-0.000000; 0.000000;, +         1.000000;-0.000000; 0.000000;, +         1.000000;-0.000000; 0.000000;; +        18; +        4;0;1;2;3;, +        4;4;5;6;7;, +        4;8;9;10;11;, +        4;12;13;14;15;, +        4;16;17;18;19;, +        4;20;21;22;23;, +        4;24;25;26;27;, +        4;28;29;30;31;, +        4;32;33;34;35;, +        4;36;37;38;39;, +        4;40;41;42;43;, +        4;44;45;46;47;, +        4;48;49;50;51;, +        4;52;53;54;55;, +        4;56;57;58;59;, +        4;60;61;62;63;, +        4;64;65;66;67;, +        4;68;69;70;71;; +      } //End of Cube_001 Normals +      MeshMaterialList { //Cube_001 Material List +        1; +        18; +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0, +        0;; +        Material Material { +           0.640000; 0.640000; 0.640000; 1.000000;; +           96.078431; +           0.500000; 0.500000; 0.500000;; +           0.000000; 0.000000; 0.000000;; +          TextureFilename {"cart.png";} +        } +      } //End of Cube_001 Material List +      MeshTextureCoords { //Cube_001 UV Coordinates +        72; +         0.000000; 0.500000;, +         0.500000; 0.500000;, +         0.500000; 1.000000;, +         0.000000; 1.000000;, +         0.031250; 0.500000;, +        -0.000000; 0.500000;, +        -0.000000; 0.468750;, +         0.031250; 0.468750;, +         0.500000; 0.500000;, +         0.500000; 0.000000;, +         1.000000; 0.000000;, +         1.000000; 0.500000;, +         0.468750; 0.468750;, +         0.500000; 0.468750;, +         0.500000; 0.500000;, +         0.468750; 0.500000;, +         0.031250; 0.468750;, +         0.468750; 0.468750;, +         0.468750; 0.500000;, +         0.031250; 0.500000;, +         0.468750; 0.000000;, +         0.500000; 0.000000;, +         0.500000; 0.031250;, +         0.468750; 0.031250;, +         0.468750; 0.031250;, +         0.500000; 0.031250;, +         0.500000; 0.468750;, +         0.468750; 0.468750;, +         0.468750; 0.031250;, +         0.031250; 0.031250;, +         0.031250; 0.000000;, +         0.468750; 0.000000;, +         1.000000; 0.500000;, +         0.500000; 0.500000;, +         0.500000; 0.000000;, +         1.000000; 0.000000;, +         0.031250; 0.031250;, +         0.000000; 0.031250;, +         0.000000; 0.000000;, +         0.031250; 0.000000;, +         0.031250; 0.468750;, +        -0.000000; 0.468750;, +         0.000000; 0.031250;, +         0.031250; 0.031250;, +         0.000000; 0.500000;, +         0.500000; 0.500000;, +         0.500000; 1.000000;, +         0.000000; 1.000000;, +         1.000000; 0.500000;, +         0.500000; 0.500000;, +         0.500000; 0.000000;, +         1.000000; 0.000000;, +         1.000000; 0.500000;, +         0.500000; 0.500000;, +         0.500000; 0.000000;, +         1.000000; 0.000000;, +         1.000000; 0.500000;, +         0.500000; 0.500000;, +         0.500000; 0.000000;, +         1.000000; 0.000000;, +         0.500000; 0.500000;, +         0.500000; 0.000000;, +         1.000000; 0.000000;, +         1.000000; 0.500000;, +         1.000000; 0.000000;, +         1.000000; 0.500000;, +         0.500000; 0.500000;, +         0.500000; 0.000000;, +         0.500000; 0.500000;, +         0.500000; 0.000000;, +         1.000000; 0.000000;, +         1.000000; 0.500000;; +      } //End of Cube_001 UV Coordinates +    } //End of Cube_001 Mesh +  } //End of Cube +} //End of Root Frame +AnimationSet { +  Animation { +    {Cube} +    AnimationKey { //Position +      2; +      4; +      0;3;     0.000000, 0.000000, 0.000000;;, +      1;3;     0.000000, 3.000000, 3.000000;;, +      2;3;     0.000000,-3.000000, 3.000000;;, +      3;3;     0.000000,-3.000000, 3.000000;;; +    } +    AnimationKey { //Rotation +      0; +      4; +      0;4;    -1.000000, 0.000000, 0.000000, 0.000000;;, +      1;4;    -0.923880,-0.382683,-0.000000, 0.000000;;, +      2;4;    -0.923880, 0.382683, 0.000000, 0.000000;;, +      3;4;    -0.923880, 0.382683, 0.000000, 0.000000;;; +    } +    AnimationKey { //Scale +      1; +      4; +      0;3;     5.000000, 5.000000, 5.000000;;, +      1;3;     5.000000, 5.000000, 5.000000;;, +      2;3;     5.000000, 5.000000, 5.000000;;, +      3;3;     5.000000, 5.000000, 5.000000;;; +    } +  } +} //End of AnimationSet diff --git a/railcart/railcart.lua b/railcart/railcart.lua new file mode 100644 index 0000000..917da44 --- /dev/null +++ b/railcart/railcart.lua @@ -0,0 +1,252 @@ +RAILCART_ENTITY_UPDATE_TIME = 1 +RAILCART_OBJECT_UPDATE_TIME = 5 +RAILCART_OBJECT_SAVE_TIME = 10 +RAILCART_RELOAD_DISTANCE = 32 +RAILCART_SNAP_DISTANCE = 0.5 +RAILCART_SPEED_MIN = 0.1 +RAILCART_SPEED_MAX = 10 + +railcart = { +	timer = 0, +	allcarts = {}, +} + +railcart.cart = { +	id = nil, +	entity = {}, +	pos = nil, +	target = nil, +	prev = nil, +	accel = nil, +	dir = {x=0, y=0, z=0}, +	vel = {x=0, y=0, z=0}, +	acc = {x=0, y=0, z=0}, +	timer = 0, +} + +function railcart.cart:new(obj) +	obj = obj or {} +	setmetatable(obj, self) +	self.__index = self +	return obj +end + +function railcart.cart:is_loaded() +	for _, player in pairs(minetest.get_connected_players()) do +		local pos = player:getpos() +		if pos then +			local dist = railtrack:get_distance(pos, self.pos) +			if dist <= RAILCART_RELOAD_DISTANCE then +				return true +			end +		end +	end +	return false +end + +function railcart.cart:on_step(dtime) +	self.timer = self.timer - dtime +	if self.timer > 0 then +		return +	end +	self.timer = RAILCART_OBJECT_UPDATE_TIME +	local entity = railcart:get_cart_ref(self.id) +	if entity.object then +		return +	end +	if self:is_loaded() then +		local object = minetest.add_entity(self.pos, "railcart:cart_entity") +		if object then +			entity = object:get_luaentity() or {} +			entity.cart = self +			object:setvelocity(self.vel) +			object:setacceleration(self.acc) +		end +	else +		self.timer = railcart:update(self, self.timer) +	end +end + +function railcart:save() +	local carts = {} +	for id, cart in pairs(railcart.allcarts) do +		local ref = {} +		for k, v in pairs(cart) do +			ref[k] = v +		end +		ref.entity = nil +		table.insert(carts, ref) +	end +	local output = io.open(minetest.get_worldpath().."/railcart.txt",'w') +	if output then +		output:write(minetest.serialize(carts)) +		io.close(output) +	end +end + +function railcart:get_cart_ref(id) +	local cart_ref = {} +	for _, ref in pairs(minetest.luaentities) do +		if ref.cart then +			if ref.cart.id == id then +				cart_ref = ref +				break +			end +		end +	end +	return cart_ref +end + +function railcart:get_delta_time(vel, acc, dist) +	if vel > 0 then +		if acc == 0 then +			return dist / vel +		end +		local r = math.sqrt(vel * vel + 2 * acc * dist) +		if r > 0 then +			return (-vel + r) / acc +		end +	end +	return 9999 --INF +end + +function railcart:velocity_to_dir(v) +	if math.abs(v.x) > math.abs(v.z) then +		return {x=railtrack:get_sign(v.x), y=railtrack:get_sign(v.y), z=0} +	else +		return {x=0, y=railtrack:get_sign(v.y), z=railtrack:get_sign(v.z)} +	end +end + +function railcart:velocity_to_speed(vel) +	local speed = math.max(math.abs(vel.x), math.abs(vel.z)) +	if speed < RAILCART_SPEED_MIN then +		speed = 0 +	elseif speed > RAILCART_SPEED_MAX then +		speed = RAILCART_SPEED_MAX +	end +	return speed +end + +function railcart:get_target(pos, vel) +	local meta = minetest.get_meta(vector.round(pos)) +	local dir = self:velocity_to_dir(vel) +	local targets = {} +	local rots = RAILTRACK_ROTATIONS +	local contype = meta:get_string("contype") or "" +	local s_junc = meta:get_string("junctions") or "" +	local s_cons = meta:get_string("connections") or "" +	local s_rots = meta:get_string("rotations") or "" +	if contype == "section" then +		local junctions = minetest.deserialize(s_junc) or {} +		for _, p in pairs(junctions) do +			table.insert(targets, p) +		end +	else +		local cons = minetest.deserialize(s_cons) or {} +		for _, p in pairs(cons) do +			table.insert(targets, p) +		end +		if s_rots ~= "" then +			local fwd = false +			for _, p in pairs(cons) do +				if vector.equals(vector.add(pos, dir), p) then +					fwd = true +				end +			end +			if fwd == true or #cons == 1 then +				rots = s_rots +			end +		end +	end +	local rotations = railtrack:get_rotations(rots, dir) +	for _, r in ipairs(rotations) do +		for _, t in pairs(targets) do +			local d = railtrack:get_direction(t, pos) +			if r.x == d.x and r.z == d.z then +				return t +			end +		end +	end +end + +function railcart:update(cart, time, object) +	if object then +		cart.pos = object:getpos() +		cart.vel = object:getvelocity() +	end +	if not cart.target then +		cart.pos = vector.new(cart.prev) +		cart.target = railcart:get_target(cart.pos, cart.vel) +		if object then +			object:moveto(cart.pos) +		end +	end +	local speed = railcart:velocity_to_speed(cart.vel) +	if not cart.target then +		speed = 0 +	end +	if speed > RAILCART_SPEED_MIN then +		cart.dir = railtrack:get_direction(cart.target, cart.pos) +		local d1 = railtrack:get_distance(cart.prev, cart.target) +		local d2 = railtrack:get_distance(cart.prev, cart.pos) +		local dist = d1 - d2 +		if dist > RAILCART_SNAP_DISTANCE then +			local accel = RAILTRACK_ACCEL_FLAT +			if cart.dir.y == -1 then +				accel = RAILTRACK_ACCEL_DOWN +			elseif cart.dir.y == 1 then +				accel = RAILTRACK_ACCEL_UP +			end +			accel = cart.accel or accel +			local dt = railcart:get_delta_time(speed, accel, dist) +			if dt < time then +				time = dt +			end +			local dp = speed * time + 0.5 * accel * time * time +			local vf = speed + accel * time +			if object then +				if vf <= 0 then +					speed = 0 +					accel = 0 +				end +				cart.vel = vector.multiply(cart.dir, speed) +				cart.acc = vector.multiply(cart.dir, accel) +			elseif dp > 0 then +				cart.vel = vector.multiply(cart.dir, vf) +				cart.pos = vector.add(cart.pos, vector.multiply(cart.dir, dp)) +			end +		else +			cart.pos = vector.new(cart.target) +			cart.prev = vector.new(cart.target) +			cart.accel = railtrack:get_acceleration(cart.target) +			cart.target = nil +			return 0 +		end +	else +		cart.vel = {x=0, y=0, z=0} +		cart.acc = {x=0, y=0, z=0} +	end +	if object then +		if cart.dir.y == -1 then +			object:set_animation({x=1, y=1}, 1, 0) +		elseif cart.dir.y == 1 then +			object:set_animation({x=2, y=2}, 1, 0) +		else +			object:set_animation({x=0, y=0}, 1, 0) +		end +		if cart.dir.x < 0 then +			object:setyaw(math.pi / 2) +		elseif cart.dir.x > 0 then +			object:setyaw(3 * math.pi / 2) +		elseif cart.dir.z < 0 then +			object:setyaw(math.pi) +		elseif cart.dir.z > 0 then +			object:setyaw(0) +		end +		object:setvelocity(cart.vel) +		object:setacceleration(cart.acc) +	end +	return time +end + diff --git a/railcart/textures/cart.png b/railcart/textures/cart.pngBinary files differ new file mode 100644 index 0000000..1f9f568 --- /dev/null +++ b/railcart/textures/cart.png diff --git a/railcart/textures/cart_bottom.png b/railcart/textures/cart_bottom.pngBinary files differ new file mode 100644 index 0000000..f84b1ae --- /dev/null +++ b/railcart/textures/cart_bottom.png diff --git a/railcart/textures/cart_side.png b/railcart/textures/cart_side.pngBinary files differ new file mode 100644 index 0000000..79f6c32 --- /dev/null +++ b/railcart/textures/cart_side.png diff --git a/railcart/textures/cart_top.png b/railcart/textures/cart_top.pngBinary files differ new file mode 100644 index 0000000..8140fc7 --- /dev/null +++ b/railcart/textures/cart_top.png | 
