From ced150bc5b1cb79a484f013b1bb4fe154493a600 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Tue, 22 Jul 2014 23:15:43 +0200 Subject: [PATCH] Upload --- README.txt | 23 +++ depends.txt | 1 + functions.lua | 103 ++++++++++++ init.lua | 208 ++++++++++++++++++++++++ models/cart.png | Bin 0 -> 216 bytes models/cart.x | 339 +++++++++++++++++++++++++++++++++++++++ rails.lua | 16 ++ textures/cart_bottom.png | Bin 0 -> 114 bytes textures/cart_side.png | Bin 0 -> 147 bytes textures/cart_top.png | Bin 0 -> 131 bytes 10 files changed, 690 insertions(+) create mode 100644 README.txt create mode 100644 depends.txt create mode 100644 functions.lua create mode 100644 init.lua create mode 100644 models/cart.png create mode 100644 models/cart.x create mode 100644 rails.lua create mode 100644 textures/cart_bottom.png create mode 100644 textures/cart_side.png create mode 100644 textures/cart_top.png diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..4ec9bb8 --- /dev/null +++ b/README.txt @@ -0,0 +1,23 @@ +Minetest mod: boost_cart +======================= +Based on the mod "carts" by PilzAdam +Target: Run smoothly and do not use too much CPU + +License of source code: +----------------------- +WTFPL + +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/depends.txt b/depends.txt new file mode 100644 index 0000000..331d858 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/functions.lua b/functions.lua new file mode 100644 index 0000000..b6bab4e --- /dev/null +++ b/functions.lua @@ -0,0 +1,103 @@ +function boost_cart:get_sign(z) + if z == 0 then + return 0 + else + return z / math.abs(z) + end +end + +function boost_cart:velocity_to_dir(v) + if math.abs(v.x) > math.abs(v.z) then + return {x=boost_cart:get_sign(v.x), y=boost_cart:get_sign(v.y), z=0} + else + return {x=0, y=boost_cart:get_sign(v.y), z=boost_cart:get_sign(v.z)} + end +end + +function boost_cart:is_rail(pos) + local node = minetest.get_node(pos).name + return minetest.get_item_group(node, "rail") ~= 0 +end + +function boost_cart:get_rail_direction(pos_, dir_) + local pos = vector.round(pos_) + local dir = vector.new(dir_) + local cur = nil + + -- Front + dir.y = 0 + cur = vector.add(pos, dir) + if boost_cart:is_rail(cur) then + return dir + end + + -- Down + dir.y = -1 + cur = vector.add(pos, dir) + if boost_cart:is_rail(cur) then + return dir + end + + -- Up + dir.y = 1 + cur = vector.add(pos, dir) + if boost_cart:is_rail(cur) then + return dir + end + + -- Left, right + dir.y = 0 + + -- Check left and right + local view, opposite, val + + if dir.x == 0 and dir.z ~= 0 then + view = "z" + other = "x" + if dir.z < 0 then + val = {1, -1} + else + val = {-1, 1} + end + elseif dir.z == 0 and dir.x ~= 0 then + view = "x" + other = "z" + if dir.x > 0 then + val = {1, -1} + else + val = {-1, 1} + end + else + return {x=0, y=0, z=0} + end + + dir[view] = 0 + dir[other] = val[1] + cur = vector.add(pos, dir) + if boost_cart:is_rail(cur) then + return dir + end + + -- Down + dir.y = -1 + cur = vector.add(pos, dir) + if boost_cart:is_rail(cur) then + return dir + end + dir.y = 0 + + dir[other] = val[2] + cur = vector.add(pos, dir) + if boost_cart:is_rail(cur) then + return dir + end + + -- Down + dir.y = -1 + cur = vector.add(pos, dir) + if boost_cart:is_rail(cur) then + return dir + end + + return {x=0, y=0, z=0} +end diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..ca4adbb --- /dev/null +++ b/init.lua @@ -0,0 +1,208 @@ +-- TODO: +-- Fix way-up +-- Add rail-cross switching +-- Prevent from floating carts +-- Speed up and brake rails + +boost_cart = {} +boost_cart.modpath = minetest.get_modpath("boost_cart") +boost_cart.speed_max = 8 + +dofile(boost_cart.modpath.."/functions.lua") +dofile(boost_cart.modpath.."/rails.lua") + +boost_cart.cart = { + physical = false, + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + visual = "mesh", + mesh = "cart.x", + visual_size = {x=1, y=1}, + textures = {"cart.png"}, + + driver = nil, + punch = false, -- used to re-send velocity and position + velocity = {x=0, y=0, z=0}, -- only used on punch + old_dir = {x=0, y=0, z=0}, + old_pos = nil +} + +function boost_cart.cart:on_rightclick(clicker) + if not clicker or not clicker:is_player() then + return + end + local player_name = clicker:get_player_name() + if self.driver and player_name == self.driver then + self.driver = nil + clicker:set_detach() + elseif not self.driver then + self.driver = player_name + clicker:set_attach(self.object, "", {x=0,y=5,z=0}, {x=0,y=0,z=0}) + end +end + +function boost_cart.cart:on_activate(staticdata, dtime_s) + self.object:set_armor_groups({immortal=1}) + self.old_pos = self.object:getpos() +end + +function boost_cart.cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) + if not puncher or not puncher:is_player() then + return + end + + if puncher:get_player_control().sneak then + if self.driver then + local player = minetest.get_player_by_name(self.driver) + if player then + player:set_detach() + end + end + self.object:remove() + puncher:get_inventory():add_item("main", "boost_cart:cart") + return + end + + local vel = self.velocity + if puncher:get_player_name() == self.driver then + if math.abs(vel.x) > 2 or math.abs(vel.z) > 2 then + return + end + end + + local cart_dir = boost_cart:velocity_to_dir(direction) + if cart_dir.x == 0 and cart_dir.z == 0 then + local fd = minetest.dir_to_facedir(puncher:get_look_dir()) + if fd == 0 then + cart_dir.x = 1 + elseif fd == 1 then + cart_dir.z = -1 + elseif fd == 2 then + cart_dir.x = -1 + elseif fd == 3 then + cart_dir.z = 1 + end + end + + if time_from_last_punch > tool_capabilities.full_punch_interval then + time_from_last_punch = tool_capabilities.full_punch_interval + end + local dir = boost_cart:get_rail_direction(self.object:getpos(), cart_dir) + + local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval) + vel.x = dir.x * f + vel.z = dir.y * f + vel.z = dir.z * f + self.velocity = vel + self.punch = true +end + +function boost_cart.cart:on_step(dtime) + local vel = self.object:getvelocity() + if self.punch then + vel = vector.add(vel, self.velocity) + self.velocity = {x=0,y=0,z=0} + elseif vector.equals(vel, {x=0,y=0,z=0}) then + return + end + + local pos = self.object:getpos() + local fpos, fold_pos = vector.round(pos), vector.round(self.old_pos) + if vector.equals(fpos, fold_pos) and not self.punch then + return + end + self.old_pos = vector.new(pos) + + local cart_dir = { + x = boost_cart:get_sign(vel.x), + y = boost_cart:get_sign(vel.y), + z = boost_cart:get_sign(vel.z) + } + local dir = boost_cart:get_rail_direction(pos, cart_dir) + if vector.equals(dir, {x=0, y=0, z=0}) then + vel = {x=0, y=0, z=0} + self.object:setacceleration({x=0, y=0, z=0}) + self.punch = true + else + -- If the direction changed + if dir.x ~= 0 and self.old_dir.z ~= 0 then + vel.x = dir.x * math.abs(vel.z) + vel.z = 0 + pos.z = math.floor(pos.z + 0.5) + self.punch = true + end + if dir.z ~= 0 and self.old_dir.x ~= 0 then + vel.z = dir.z * math.abs(vel.x) + vel.x = 0 + pos.x = math.floor(pos.x + 0.5) + self.punch = true + end + -- Up, down? + if dir.y ~= self.old_dir.y then + vel.y = dir.y * (math.abs(vel.x) + math.abs(vel.z)) + pos.y = math.floor(pos.y + 0.5) + self.punch = true + end + + -- Slow down or speed up.. + local acc = -2 * dir.y - 0.4 + self.object:setacceleration({ + x = dir.x * acc, + y = dir.y * (math.abs(dir.x) + math.abs(dir.z)) * acc, + z = dir.z * acc + }) + end + + self.old_dir = vector.new(dir) + + -- Limits + for _,v in ipairs({"x","y","z"}) do + if math.abs(vel[v]) > boost_cart.speed_max then + vel[v] = boost_cart:get_sign(vel[v]) * boost_cart.speed_max + self.punch = true + end + end + + if dir.x < 0 then + self.object:setyaw(math.pi / 2) + elseif dir.x > 0 then + self.object:setyaw(3 * math.pi / 2) + elseif dir.z < 0 then + self.object:setyaw(math.pi) + elseif dir.z > 0 then + self.object:setyaw(0) + end + + if dir.y == -1 then + self.object:set_animation({x=1, y=1}, 1, 0) + elseif dir.y == 1 then + self.object:set_animation({x=2, y=2}, 1, 0) + else + self.object:set_animation({x=0, y=0}, 1, 0) + end + if self.punch then + self.object:setvelocity(vel) + self.object:setpos(pos) + self.old_pos = {x=0, y=0, z=0} + end + self.punch = false +end + +minetest.register_entity("boost_cart:cart", boost_cart.cart) +minetest.register_craftitem("boost_cart:cart", { + description = "Cart", + 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) + if not pointed_thing.type == "node" then + return + end + if boost_cart:is_rail(pointed_thing.under) then + minetest.add_entity(pointed_thing.under, "boost_cart:cart") + elseif boost_cart:is_rail(pointed_thing.above) then + minetest.add_entity(pointed_thing.above, "boost_cart:cart") + else return end + + itemstack:take_item() + return itemstack + end, +}) \ No newline at end of file diff --git a/models/cart.png b/models/cart.png new file mode 100644 index 0000000000000000000000000000000000000000..d4b12d63ca534fbd5889e2def721946927aa4e4b GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv#Q>iWS4|liQ+0JmLqmT%yNvMg zveeX;;^G;doin?-mQ0)W|NnohH!BK&iivYp|Kl?r1=Gg}Y-{!4*^ zDxNNmAsn*FDFR#L4{N+S@Il@wWp5fs;u)sGPDO_RL&S3j3^P6m{<_R#4O5|&djEeV3x=s#=;!@%J@Op0o_(h aW`=)D1y^r%+vEn+$KdJe=d#Wzp$PzFcOdNm literal 0 HcmV?d00001