diff options
author | stujones11 <stujones111@gmail.com> | 2016-01-10 17:47:02 +0000 |
---|---|---|
committer | stujones11 <stujones111@gmail.com> | 2016-01-10 17:47:02 +0000 |
commit | 6dfdaf78522a9c92e4323fa5bb77eb3a7c11aa30 (patch) | |
tree | 4f932364c6688275ab7128aa69ace9e387200809 |
Initial commit
39 files changed, 1411 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a57dbc9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +## Generic ignorable patterns and files +*~ +.*.swp +*bak* +tags +*.vim + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..511244e --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,18 @@ +Minetest Modpack - Railnet [minetest-railnet] +============================================= + +**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 + +rarkenin: + cart_rail_*.png + diff --git a/README.md b/README.md new file mode 100644 index 0000000..94229ab --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +Modpack - Railnet [0.1.0] +========================= + +**Minetest version:** 0.4.13 + +This modpack is still very much a work-in-progress and is not recommended for +existing worlds or public servers at this stage. + +[mod] Railtrack [railtrack] +--------------------------- + +**Depends:** default + +Proof of concept rail networking system which enables rail-carts to travel +through unloaded map chunks. + +[mod] Railcart [railcart] +------------------------- + +**Depends:** railtrack + +Proof of concept ground up re-write based on the original carts mod by PilzAdam. + diff --git a/modpack.txt b/modpack.txt new file mode 100644 index 0000000..33d91f5 --- /dev/null +++ b/modpack.txt @@ -0,0 +1 @@ +The presence of this file indicates that the current folder is a modpack.
\ No newline at end of file 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.png Binary files differnew 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.png Binary files differnew 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.png Binary files differnew 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.png Binary files differnew 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.png Binary files differnew file mode 100644 index 0000000..8140fc7 --- /dev/null +++ b/railcart/textures/cart_top.png diff --git a/railtrack/LICENSE.txt b/railtrack/LICENSE.txt new file mode 100644 index 0000000..c43348a --- /dev/null +++ b/railtrack/LICENSE.txt @@ -0,0 +1,13 @@ +Minetest Mod - Railtrack [railtrack] +==================================== + +License Source Code: LGPL v2.1 + +License of media (textures, sounds and models): CC-0 + +Authors of media files: +----------------------- + +rarkenin: + cart_rail_*.png + diff --git a/railtrack/README.txt b/railtrack/README.txt new file mode 100644 index 0000000..b371e29 --- /dev/null +++ b/railtrack/README.txt @@ -0,0 +1,72 @@ +Minetest Mod - Railtrack [railtrack] +==================================== + +Minetest version: 0.4.13 + +Depends: default + +Proof of concept rail networking system which enables rail-carts to travel +through unloaded map chunks. + +Please note, this mod makes heavy use of metadata so that much of the processing +gets done as tracks are laid, for this reason a 'rails' privilege is required in +order to place rails when using multiplayer mode. + +Crafting +-------- + +R = Rail [default:rail] +F = Mese Crystal Fragment [default:mese_crystal_fragment] +C = Coal Lump [default:coal_lump] +D = Diamond [default:diamond] +M = Mese Block [default:mese] + +Powered Rail: [railtrack:powerrail] + +By default these rails apply a positive acceleration during the time a cart +remains on a given section of track. When used with the mesecons mod the rails +will require power from a mesecon source to become active. + ++---+---+---+ +| R | F | R | ++---+---+---+ + +Braking Rail: [railtrack:brakerail] + +By default these rails apply a negative acceleration during the time a cart +remains on a given section of track. When used with the mesecons mod the rails +will require power from a mesecon source to become active. + ++---+---+---+ +| R | C | R | ++---+---+---+ + +Superconducting Rail: [railtrack:superrail] + +Zero friction rails that are easier to manage and are also a little less +cpu-intensive by avoiding the use of square root calculations. + ++---+---+---+ +| R | D | R | ++---+---+---+ + +Switching Rail: [railtrack:switchrail] + +Currently depends on mesecons to do much other than provide a convenient, zero +friction union to join long sections of superconducting rails. + ++---+---+---+ +| R | M | R | ++---+---+---+ + +Misc Items +---------- + +Rail Fixer: [railtrack:fixer] + +Only available in creative menu or with give(me) privileges. + +Rail Inspector [railtrack:inspector] + +Only available in creative menu or with give(me) privileges. + diff --git a/railtrack/depends.txt b/railtrack/depends.txt new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/railtrack/depends.txt @@ -0,0 +1 @@ +default diff --git a/railtrack/init.lua b/railtrack/init.lua new file mode 100644 index 0000000..373fcaa --- /dev/null +++ b/railtrack/init.lua @@ -0,0 +1,197 @@ +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +dofile(modpath.."/railtrack.lua") + +railtrack:register_rail(":default:rail", { + description = "Rail", + tiles = {"default_rail.png", "default_rail_curved.png", + "default_rail_t_junction.png", "default_rail_crossing.png"}, + railtype = "rail", +}) + +railtrack:register_rail("railtrack:superrail", { + description = "Superconducting Rail", + tiles = {"carts_rail_sup.png", "carts_rail_curved_sup.png", + "carts_rail_t_junction_sup.png", "carts_rail_crossing_sup.png"}, + railtype = "superrail", + acceleration = 0, +}) + +railtrack:register_rail("railtrack:powerrail", { + description = "Powered Rail", + tiles = {"carts_rail_pwr.png", "carts_rail_curved_pwr.png", + "carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png"}, + railtype = "powerrail", + acceleration = 4, + mesecons = { + effector = { + action_on = function(pos, node) + railtrack:set_acceleration(pos, 4) + end, + action_off = function(pos, node) + railtrack:set_acceleration(pos, RAILTRACK_FRICTION_FLAT) + end, + }, + }, +}) + +railtrack:register_rail("railtrack:brakerail", { + description = "Braking Rail", + tiles = {"carts_rail_brk.png", "carts_rail_curved_brk.png", + "carts_rail_t_junction_brk.png", "carts_rail_crossing_brk.png"}, + railtype = "brakerail", + acceleration = -4, + mesecons = { + effector = { + action_on = function(pos, node) + railtrack:set_acceleration(pos, -4) + end, + action_off = function(pos, node) + railtrack:set_acceleration(pos, RAILTRACK_FRICTION_FLAT) + end, + }, + }, +}) + +railtrack:register_rail("railtrack:switchrail", { + description = "Switching Rail", + tiles = {"carts_rail_swt.png", "carts_rail_curved_swt.png", + "carts_rail_t_junction_swt.png", "carts_rail_crossing_swt.png"}, + railtype = "switchrail", + acceleration = 0, + mesecons = { + effector = { + action_on = function(pos, node) + local meta = minetest.get_meta(pos) + meta:set_string("rotations", "RFLB") + end, + action_off = function(pos, node) + local meta = minetest.get_meta(pos) + meta:set_string("rotations", nil) + end, + }, + }, +}) + +minetest.register_privilege("rails", "Player can dig and place rails.") + +minetest.register_tool("railtrack:fixer", { + description = "Rail Fixer", + inventory_image = "railtrack_fixer.png", + wield_image = "railtrack_fixer.png", + on_use = function(itemstack, user, pointed_thing) + local pos = minetest.get_pointed_thing_position(pointed_thing, false) + local name = user:get_player_name() + if not pos or not name or pointed_thing.type ~= "node" then + return + end + if not railtrack:is_railnode(pos) then + minetest.chat_send_player(name, "Not a rail node!") + return + end + if not minetest.is_singleplayer() then + if not minetest.check_player_privs(name, {rails=true}) then + minetest.chat_send_player(name, "Requires rails privilege") + return + end + end + local node = minetest.get_node(pos) + minetest.remove_node(pos) + set_node(pos, node) + local def = minetest.registered_items[node.name] or {} + if type(def.after_place_node) == "function" then + def.after_place_node(pos, user, node) + end + end, +}) + +minetest.register_tool("railtrack:inspector", { + description = "Rail Inspector", + inventory_image = "railtrack_inspector.png", + wield_image = "railtrack_inspector.png", + on_use = function(itemstack, user, pointed_thing) + local name = user:get_player_name() + local pos = minetest.get_pointed_thing_position(pointed_thing, false) + if not name or not pos then + return + end + local node = minetest.get_node(pos) or {} + if not railtrack:is_railnode(pos) or not node.name then + minetest.chat_send_player(name, "Not a rail node!") + return + end + local ref = minetest.registered_items[node.name] or {} + local meta = minetest.get_meta(pos) + local form = "" + local size = 2.5 + form = form.."label[0.5,0.5;POS: "..minetest.pos_to_string(pos).."]" + local railtype = ref.railtype or "NIL" + form = form.."label[0.5,1.0;RAILTYPE: "..railtype.."]" + local contype = meta:get_string("contype") or "NIL" + form = form.."label[0.5,1.5;CONTYPE: "..contype.."]" + local accel = meta:get_string("acceleration") or "NIL" + form = form.."label[0.5,2.0;ACCEL: "..accel.."]" + local s_junc = meta:get_string("junctions") + if s_junc then + local junctions = minetest.deserialize(s_junc) + if junctions then + form = form.."label[0.5,2.5;JUNCTIONS:]" + for i, p in ipairs(junctions) do + size = size + 0.5 + form = form.."label[0.5,"..size..";#"..i.." " + ..minetest.pos_to_string(p).."]" + end + end + end + local s_cons = meta:get_string("connections") + if s_cons then + local cons = minetest.deserialize(s_cons) + if cons then + size = size + 0.5 + form = form.."label[0.5,"..size..";CONNECTIONS:]" + for i, p in pairs(cons) do + size = size + 0.5 + form = form.."label[0.5,"..size..";#"..i.." " + ..minetest.pos_to_string(p).."]" + end + end + end + local s_rots = meta:get_string("rotations") + if s_rots then + size = size + 0.5 + form = form.."label[0.5,"..size..";ROTATIONS: "..s_rots.."]" + end + form = form.."button_exit[3.0,"..(size + 1)..";2,0.5;;Ok]" + form = "size[8,"..(size + 2).."]"..form + minetest.show_formspec(name, "info", form) + end, +}) + +minetest.register_craft({ + output = "railtrack:powerrail 2", + recipe = { + {"default:rail", "default:mese_crystal_fragment", "default:rail"}, + } +}) + +minetest.register_craft({ + output = "railtrack:brakerail 2", + recipe = { + {"default:rail", "default:coal_lump", "default:rail"}, + } +}) + +minetest.register_craft({ + output = "railtrack:switchrail 2", + recipe = { + {"default:rail", "default:mese", "default:rail"}, + } +}) + +minetest.register_craft({ + output = "railtrack:superrail 2", + recipe = { + {"default:rail", "default:diamond", "default:rail"}, + } +}) + diff --git a/railtrack/railtrack.lua b/railtrack/railtrack.lua new file mode 100644 index 0000000..3a1f714 --- /dev/null +++ b/railtrack/railtrack.lua @@ -0,0 +1,284 @@ +RAILTRACK_WARN_SECTION_LEN = 20 +RAILTRACK_ROTATIONS = "FLR" +RAILTRACK_ACCEL_FLAT = -0.5 +RAILTRACK_ACCEL_UP = -2 +RAILTRACK_ACCEL_DOWN = 2 + +railtrack = {} + +railtrack.default_rail = { + description = "Rail", + drawtype = "raillike", + tiles = {"default_rail.png", "default_rail_curved.png", + "default_rail_t_junction.png", "default_rail_crossing.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + is_ground_content = false, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + groups = {bendy = 2, dig_immediate = 2, attached_node = 1, + connect_to_raillike = minetest.raillike_group("rail")}, + railtype = "rail", + on_place = function(itemstack, placer, pointed_thing) + local name = placer:get_player_name() + if not name or pointed_thing.type ~= "node" then + return + end + if not minetest.is_singleplayer() then + if not minetest.check_player_privs(name, {rails=true}) then + minetest.chat_send_player(name, "Requires rails privilege") + return + end + end + end, + after_place_node = function(pos, placer, itemstack) + local meta = minetest.get_meta(pos) + local def = itemstack:get_definition() or {} + if def.acceleration then + meta:set_string("acceleration", def.acceleration) + end + local junc = {} + local contype = meta:get_string("contype") or "" + local s_cons = meta:get_string("connections") or "" + if contype == "section" then + railtrack:warn_section_len(placer, pos, meta) + elseif s_cons ~= "" then + local cons = minetest.deserialize(s_cons) + for _, con in pairs(cons) do + if railtrack:warn_section_len(placer, con) then + break + end + end + end + end, + on_construct = function(pos) + railtrack:update_rails(pos) + end, + after_destruct = function(pos) + local cons = railtrack:get_connections(pos) + for _, p in pairs(cons) do + railtrack:update_rails(p) + end + end, +} + +function railtrack:register_rail(name, def) + for k, v in pairs(railtrack.default_rail) do + if not def[k] then + def[k] = v + end + end + def.inventory_image = def.inventory_image or def.tiles[1] + def.wield_image = def.wield_image or def.tiles[1] + minetest.register_node(name, def) +end + +function railtrack:warn_section_len(player, pos, meta) + meta = meta or minetest.get_meta(pos) + local contype = meta:get_string("contype") or "" + if contype == "section" then + local s_junc = meta:get_string("junctions") or "" + if s_junc ~= "" then + local junc = minetest.deserialize(s_junc) + if #junc == 2 then + local dist = railtrack:get_distance(junc[1], junc[2]) + if dist > RAILTRACK_WARN_SECTION_LEN then + local name = player:get_player_name() + if name then + minetest.chat_send_player(name, "Warning, section" + .." length "..dist.." exceeds the recommended" + .." maximum of "..RAILTRACK_WARN_SECTION_LEN) + return true + end + end + end + end + end +end + +function railtrack:is_railnode(pos) + local node = minetest.get_node(pos) + if node then + return minetest.get_item_group(node.name, "connect_to_raillike") > 0 + end +end + +function railtrack:get_sign(z) + if z == 0 then + return 0 + else + return z / math.abs(z) + end +end + +function railtrack:get_rotations(s_rots, dir) + local rots = {} + for i = 1, string.len(s_rots) do + local r = string.sub(s_rots, i, i) + local rot = nil + if r == "F" then + rot = {x=dir.x, z=dir.z} + elseif r == "L" then + rot = {x=-dir.z, z=dir.x} + elseif r == "R" then + rot = {x=dir.z, z=-dir.x} + elseif r == "B" then + rot = {x=-dir.x, z=-dir.z} + end + if rot then + table.insert(rots, rot) + end + end + return rots +end + +function railtrack:get_acceleration(pos) + local meta = minetest.get_meta(pos) + local accel = meta:get_string("acceleration") or "" + if accel ~= "" then + return tonumber(accel) + end +end + +function railtrack:get_direction(p1, p2) + local v = vector.subtract(p1, p2) + return { + x = railtrack:get_sign(v.x), + y = railtrack:get_sign(v.y), + z = railtrack:get_sign(v.z), + } +end + +function railtrack:get_distance(p1, p2) + local dx = p1.x - p2.x + local dz = p1.z - p2.z + return math.abs(dx) + math.abs(dz) +end + + +function railtrack:get_railtype(pos) + local node = minetest.get_node(pos) or {} + if node.name then + local ref = minetest.registered_items[node.name] or {} + return ref.railtype + end +end + +function railtrack:get_connection_type(pos, cons) + local railtype = railtrack:get_railtype(pos) + if #cons == 0 then + return "single" + elseif #cons == 1 then + return "junction" + elseif #cons == 2 then + if cons[1].x == cons[2].x or cons[1].z == cons[2].z then + if (cons[1].y == cons[2].y and cons[1].y == pos.y) or + (math.abs(cons[1].y - cons[2].y) == 2) then + if railtype == railtrack:get_railtype(cons[1]) and + railtype == railtrack:get_railtype(cons[2]) then + return "section" + end + end + end + end + return "junction" +end + +function railtrack:get_connections(pos) + local connections = {} + for y = -1, 1 do + for x = -1, 1 do + for z = -1, 1 do + if math.abs(x) ~= math.abs(z) then + local p = vector.add(pos, {x=x, y=y, z=z}) + if railtrack:is_railnode(p) then + table.insert(connections, p) + end + end + end + end + end + return connections +end + +function railtrack:get_junctions(pos, last_pos, junctions) + junctions = junctions or {} + local cons = railtrack:get_connections(pos) + local contype = railtrack:get_connection_type(pos, cons) + if contype == "junction" then + table.insert(junctions, pos) + elseif contype == "section" then + if last_pos then + for i, p in pairs(cons) do + if vector.equals(p, last_pos) then + cons[i] = nil + end + end + end + for _, p in pairs(cons) do + railtrack:get_junctions(p, pos, junctions) + end + end + return junctions +end + +function railtrack:set_acceleration(pos, accel) + local meta = minetest.get_meta(pos) + local contype = meta:get_string("contype") + if contype == "section" then + local s_junc = meta:get_string("junctions") or "" + local junc = minetest.deserialize(s_junc) or {} + if #junc == 2 then + local p = vector.new(junc[2]) + local dir = railtrack:get_direction(junc[1], junc[2]) + local dist = railtrack:get_distance(junc[1], junc[2]) + for i = 0, dist do + local m = minetest.get_meta(p) + if m then + m:set_string("acceleration", tostring(accel)) + end + p = vector.add(dir, p) + end + end + else + meta:set_string("acceleration", tostring(accel)) + end +end + +function railtrack:update_rails(pos, last_pos, level) + local connections = {} + local junctions = {} + local meta = minetest.get_meta(pos) + local cons = railtrack:get_connections(pos) + local contype = railtrack:get_connection_type(pos, cons) + level = level or 0 + for i, p in pairs(cons) do + connections[i] = p + end + if contype == "junction" then + level = level + 1 + end + if contype == "section" or level < 2 then + if last_pos then + for i, p in pairs(cons) do + if vector.equals(p, last_pos) then + cons[i] = nil + end + end + end + for _, p in pairs(cons) do + railtrack:update_rails(p, pos, level) + end + end + if contype == "section" then + junctions = railtrack:get_junctions(pos) + connections = {} + end + meta:set_string("connections", minetest.serialize(connections)) + meta:set_string("junctions", minetest.serialize(junctions)) + meta:set_string("contype", contype) +end + diff --git a/railtrack/textures/carts_rail_brk.png b/railtrack/textures/carts_rail_brk.png Binary files differnew file mode 100644 index 0000000..f3e0ff9 --- /dev/null +++ b/railtrack/textures/carts_rail_brk.png diff --git a/railtrack/textures/carts_rail_crossing_brk.png b/railtrack/textures/carts_rail_crossing_brk.png Binary files differnew file mode 100644 index 0000000..3ace508 --- /dev/null +++ b/railtrack/textures/carts_rail_crossing_brk.png diff --git a/railtrack/textures/carts_rail_crossing_pwr.png b/railtrack/textures/carts_rail_crossing_pwr.png Binary files differnew file mode 100644 index 0000000..d63f133 --- /dev/null +++ b/railtrack/textures/carts_rail_crossing_pwr.png diff --git a/railtrack/textures/carts_rail_crossing_sup.png b/railtrack/textures/carts_rail_crossing_sup.png Binary files differnew file mode 100644 index 0000000..b51467d --- /dev/null +++ b/railtrack/textures/carts_rail_crossing_sup.png diff --git a/railtrack/textures/carts_rail_crossing_swt.png b/railtrack/textures/carts_rail_crossing_swt.png Binary files differnew file mode 100644 index 0000000..a780cf2 --- /dev/null +++ b/railtrack/textures/carts_rail_crossing_swt.png diff --git a/railtrack/textures/carts_rail_curved_brk.png b/railtrack/textures/carts_rail_curved_brk.png Binary files differnew file mode 100644 index 0000000..5a84918 --- /dev/null +++ b/railtrack/textures/carts_rail_curved_brk.png diff --git a/railtrack/textures/carts_rail_curved_pwr.png b/railtrack/textures/carts_rail_curved_pwr.png Binary files differnew file mode 100644 index 0000000..e2ac67a --- /dev/null +++ b/railtrack/textures/carts_rail_curved_pwr.png diff --git a/railtrack/textures/carts_rail_curved_sup.png b/railtrack/textures/carts_rail_curved_sup.png Binary files differnew file mode 100644 index 0000000..326d544 --- /dev/null +++ b/railtrack/textures/carts_rail_curved_sup.png diff --git a/railtrack/textures/carts_rail_curved_swt.png b/railtrack/textures/carts_rail_curved_swt.png Binary files differnew file mode 100644 index 0000000..0ed9287 --- /dev/null +++ b/railtrack/textures/carts_rail_curved_swt.png diff --git a/railtrack/textures/carts_rail_pwr.png b/railtrack/textures/carts_rail_pwr.png Binary files differnew file mode 100644 index 0000000..95f33f6 --- /dev/null +++ b/railtrack/textures/carts_rail_pwr.png diff --git a/railtrack/textures/carts_rail_sup.png b/railtrack/textures/carts_rail_sup.png Binary files differnew file mode 100644 index 0000000..4c812a9 --- /dev/null +++ b/railtrack/textures/carts_rail_sup.png diff --git a/railtrack/textures/carts_rail_swt.png b/railtrack/textures/carts_rail_swt.png Binary files differnew file mode 100644 index 0000000..b7da323 --- /dev/null +++ b/railtrack/textures/carts_rail_swt.png diff --git a/railtrack/textures/carts_rail_t_junction_brk.png b/railtrack/textures/carts_rail_t_junction_brk.png Binary files differnew file mode 100644 index 0000000..0c2c1cb --- /dev/null +++ b/railtrack/textures/carts_rail_t_junction_brk.png diff --git a/railtrack/textures/carts_rail_t_junction_pwr.png b/railtrack/textures/carts_rail_t_junction_pwr.png Binary files differnew file mode 100644 index 0000000..7f97fc7 --- /dev/null +++ b/railtrack/textures/carts_rail_t_junction_pwr.png diff --git a/railtrack/textures/carts_rail_t_junction_sup.png b/railtrack/textures/carts_rail_t_junction_sup.png Binary files differnew file mode 100644 index 0000000..fbdc89c --- /dev/null +++ b/railtrack/textures/carts_rail_t_junction_sup.png diff --git a/railtrack/textures/carts_rail_t_junction_swt.png b/railtrack/textures/carts_rail_t_junction_swt.png Binary files differnew file mode 100644 index 0000000..b03844d --- /dev/null +++ b/railtrack/textures/carts_rail_t_junction_swt.png diff --git a/railtrack/textures/default_rail.png b/railtrack/textures/default_rail.png Binary files differnew file mode 100644 index 0000000..26fed02 --- /dev/null +++ b/railtrack/textures/default_rail.png diff --git a/railtrack/textures/railtrack_fixer.png b/railtrack/textures/railtrack_fixer.png Binary files differnew file mode 100644 index 0000000..17af383 --- /dev/null +++ b/railtrack/textures/railtrack_fixer.png diff --git a/railtrack/textures/railtrack_inspector.png b/railtrack/textures/railtrack_inspector.png Binary files differnew file mode 100644 index 0000000..671fd38 --- /dev/null +++ b/railtrack/textures/railtrack_inspector.png |