diff options
author | Hume2 <teratux.mail@gmail.com> | 2018-08-27 14:12:36 +0200 |
---|---|---|
committer | Hume2 <teratux.mail@gmail.com> | 2018-08-27 14:12:36 +0200 |
commit | 8f92e519edfecbae1f8565386ee68dcea2f64a50 (patch) | |
tree | 0fff6ea624eb3a5e6a218c6aef5fec85cb6e4a4e /init.lua |
Something like bike
Diffstat (limited to 'init.lua')
-rw-r--r-- | init.lua | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..3747107 --- /dev/null +++ b/init.lua @@ -0,0 +1,243 @@ +-- +-- Helper functions +-- + +local function is_water(pos) + local nn = minetest.get_node(pos).name + return minetest.get_item_group(nn, "liquid") ~= 0 +end + + +local function get_sign(i) + if i == 0 then + return 0 + else + return i / math.abs(i) + end +end + + +local function get_velocity(v, yaw, y) + local x = -math.sin(yaw) * v + local z = math.cos(yaw) * v + return {x = x, y = y, z = z} +end + + +local function get_v(v) + return math.sqrt(v.x ^ 2 + v.z ^ 2) +end + +-- +-- bike entity +-- + +local bike = { + physical = true, + -- Warning: Do not change the position of the collisionbox top surface, + -- lowering it causes the bike to fall through the world if underwater + collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, + visual = "mesh", + mesh = "bike_bike.obj", + textures = {"default_wood.png"}, + stepheight = 0.6, + + driver = nil, + v = 0, + last_v = 0, + removed = false +} + + +function bike.on_rightclick(self, clicker) + if not clicker or not clicker:is_player() then + return + end + local name = clicker:get_player_name() + if self.driver and clicker == self.driver then + self.object:setvelocity({x = 0, y = 0, z = 0}) + self.v = 0 + + self.driver = nil + clicker:set_detach() + default.player_attached[name] = false + default.player_set_animation(clicker, "stand" , 30) + local pos = clicker:getpos() + pos = {x = pos.x, y = pos.y + 0.2, z = pos.z} + minetest.after(0.1, function() + clicker:setpos(pos) + end) + elseif not self.driver then + local attach = clicker:get_attach() + if attach and attach:get_luaentity() then + local luaentity = attach:get_luaentity() + if luaentity.driver then + luaentity.driver = nil + end + clicker:set_detach() + end + self.driver = clicker + clicker:set_attach(self.object, "", + {x = 0, y = 11, z = -3}, {x = 0, y = 0, z = 0}) + default.player_attached[name] = true + minetest.after(0.2, function() + default.player_set_animation(clicker, "sit" , 30) + end) + clicker:set_look_horizontal(self.object:getyaw()) + end +end + + +function bike.on_activate(self, staticdata, dtime_s) + self.object:setacceleration({x = 0, y = -9.8, z = 0}) + self.object:set_armor_groups({immortal = 1}) + if staticdata then + self.v = tonumber(staticdata) + end + self.last_v = self.v +end + + +function bike.get_staticdata(self) + return tostring(self.v) +end + + +function bike.on_punch(self, puncher) + if not puncher or not puncher:is_player() or self.removed then + return + end + if self.driver and puncher == self.driver then + self.driver = nil + puncher:set_detach() + default.player_attached[puncher:get_player_name()] = false + end + if not self.driver then + self.removed = true + local inv = puncher:get_inventory() + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(puncher:get_player_name())) + or not inv:contains_item("main", "bike:bike") then + local leftover = inv:add_item("main", "bike:bike") + -- if no room in inventory add a replacement bike to the world + if not leftover:is_empty() then + minetest.add_item(self.object:getpos(), leftover) + end + end + -- delay remove to ensure player is detached + minetest.after(0.1, function() + self.object:remove() + end) + end +end + + +function bike.on_step(self, dtime) + if self.driver then + local ctrl = self.driver:get_player_control() + local yaw = self.object:getyaw() + if ctrl.up then + self.v = self.v + 0.1 + elseif ctrl.down then + self.v = self.v - 0.1 + end + if ctrl.left then + if self.v < 0 then + self.object:setyaw(yaw - (1 + dtime) * 0.03) + else + self.object:setyaw(yaw + (1 + dtime) * 0.03) + end + elseif ctrl.right then + if self.v < 0 then + self.object:setyaw(yaw + (1 + dtime) * 0.03) + else + self.object:setyaw(yaw - (1 + dtime) * 0.03) + end + end + end + local velo = self.object:getvelocity() + if self.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then + self.object:setpos(self.object:getpos()) + return + end + local s = get_sign(self.v) + self.v = self.v - 0.004 * s + if s ~= get_sign(self.v) then + self.object:setvelocity({x = 0, y = 0, z = 0}) + self.v = 0 + return + end + if self.v > 10 then + self.v = 10 + elseif self.v < 0 then + self.v = 0 + end + + local p = self.object:getpos() + if is_water(p) then + self.v = self.v / 1.3 + end + + local new_velo + new_velo = get_velocity(self.v, self.object:getyaw(), self.object:getvelocity().y) + self.object:setpos(self.object:getpos()) + self.object:setvelocity(new_velo) +end + + +minetest.register_entity("bike:bike", bike) + + +minetest.register_craftitem("bike:bike", { + description = "bike", + inventory_image = "bike_inventory.png", + wield_image = "bike_wield.png", + wield_scale = {x = 2, y = 2, z = 1}, + liquids_pointable = true, + groups = {flammable = 2}, + + on_place = function(itemstack, placer, pointed_thing) + local under = pointed_thing.under + local node = minetest.get_node(under) + local udef = minetest.registered_nodes[node.name] + if udef and udef.on_rightclick and + not (placer and placer:is_player() and + placer:get_player_control().sneak) then + return udef.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + + if pointed_thing.type ~= "node" then + return itemstack + end + + bike = minetest.add_entity(pointed_thing.above, "bike:bike") + if bike then + if placer then + bike:setyaw(placer:get_look_horizontal()) + end + local player_name = placer and placer:get_player_name() or "" + if not (creative and creative.is_enabled_for and + creative.is_enabled_for(player_name)) then + itemstack:take_item() + end + end + return itemstack + end, +}) + + +--[[minetest.register_craft({ + output = "bike:bike", + recipe = { + {"", "", "" }, + {"group:wood", "", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + }, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "bike:bike", + burntime = 20, +})--]] |