X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=mods%2Fboat%2Finit.lua;h=62d8169912d539fc221569bb8e43799215fa571f;hb=48aa89197636250b3e494e9124c7c5c6e2d63dea;hp=033cde157d294207dca8fd49831305a1aef40ed6;hpb=db183435cc4b6471c52332be498693f0ef88927a;p=Crafter.git diff --git a/mods/boat/init.lua b/mods/boat/init.lua index 033cde1..62d8169 100644 --- a/mods/boat/init.lua +++ b/mods/boat/init.lua @@ -1 +1,517 @@ + +local +minetest,vector,math,pairs += +minetest,vector,math,pairs + +local name +local pos +local node +local node_above +local goalx +local goalz +local currentvel +local level +local level2 +local nodename +local acceleration + +local function lavaflow(self) + pos = self.object:get_pos() + pos.y = pos.y + self.object:get_properties().collisionbox[2] + pos = vector.round(pos) + node = minetest.get_node(pos).name + node_above = minetest.get_node(vector.new(pos.x,pos.y+1,pos.z)).name + goalx = 0 + goalz = 0 + found = false + if node == "main:lavaflow" then + currentvel = self.object:get_velocity() + level = minetest.get_node_level(pos) + for x = -1,1 do + for z = -1,1 do + if found == false then + nodename = minetest.get_node(vector.new(pos.x+x,pos.y,pos.z+z)).name + level2 = minetest.get_node_level(vector.new(pos.x+x,pos.y,pos.z+z)) + if level2 > level and nodename == "main:lavaflow" or nodename == "main:lava" then + goalx = -x + goalz = -z + --diagonal flow + if goalx ~= 0 and goalz ~= 0 then + found = true + end + end + end + end + end + --only add velocity if there is one + --else this stops the player + if goalx ~= 0 and goalz ~= 0 then + acceleration = vector.new(goalx-currentvel.x,0,goalz-currentvel.z) + self.object:add_velocity(acceleration) + elseif goalx ~= 0 or goalz ~= 0 then + acceleration = vector.new(goalx-currentvel.x,0,goalz-currentvel.z) + self.object:add_velocity(acceleration) + end + end +end + --minetest.get_node_level(pos) +minetest.register_entity("boat:boat", { + initial_properties = { + hp_max = 1, + physical = true, + collide_with_objects = false, + collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4}, + visual = "mesh", + mesh = "boat.x", + textures = {"boat.png"}, + visual_size = {x=1,y=1,z=1}, + is_visible = true, + automatic_face_movement_dir = -90.0, + automatic_face_movement_max_rotation_per_sec = 600, + }, + + rider = nil, + boat = true, + + get_staticdata = function(self) + return minetest.serialize({ + --itemstring = self.itemstring, + }) + end, + + on_activate = function(self, staticdata, dtime_s) + if string.sub(staticdata, 1, string.len("return")) == "return" then + local data = minetest.deserialize(staticdata) + if data and type(data) == "table" then + --self.itemstring = data.itemstring + end + else + --self.itemstring = staticdata + end + self.object:set_armor_groups({immortal = 1}) + self.object:set_velocity({x = 0, y = 0, z = 0}) + self.object:set_acceleration({x = 0, y = 0, z = 0}) + end, + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) + local pos = self.object:get_pos() + minetest.add_item(pos, "boat:boat") + self.object:remove() + end, + + + on_rightclick = function(self,clicker) + if not clicker or not clicker:is_player() then + return + end + local player_name = clicker:get_player_name() + + if self.rider and player_name == self.rider then + clicker:set_detach() + local pos = self.object:get_pos() + pos.y = pos.y + 1 + clicker:move_to(pos) + clicker:add_player_velocity(vector.new(0,11,0)) + self.rider = nil + + player_is_attached(clicker,false) + force_update_animation(clicker) + + elseif not self.rider then + self.rider = player_name + clicker:set_attach(self.object, "", {x=0, y=2, z=0}, {x=0, y=0, z=0}) + + set_player_animation(clicker,"sit",0) + player_is_attached(clicker,true) + end + end, + --check if the boat is stuck on land + check_if_on_land = function(self) + local pos = self.object:get_pos() + pos.y = pos.y - 0.37 + local bottom_node = minetest.get_node(pos).name + if (bottom_node == "main:water" or bottom_node == "main:waterflow" or bottom_node == "air") then + self.on_land = false + else + self.on_land = true + end + + end, + + --players drive the baot + drive = function(self) + if self.rider then + local rider = minetest.get_player_by_name(self.rider) + local move = rider:get_player_control().up + self.moving = nil + if move then + + local currentvel = self.object:get_velocity() + local goal = rider:get_look_dir() + if self.on_land == true then + goal = vector.multiply(goal,1) + else + goal = vector.multiply(goal,20) + end + local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z) + acceleration = vector.multiply(acceleration, 0.01) + self.object:add_velocity(acceleration) + self.moving = true + end + else + self.moving = nil + end + end, + + --players push boat + push = function(self) + local pos = self.object:get_pos() + for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do + if object:is_player() and object:get_player_name() ~= self.rider then + local player_pos = object:get_pos() + pos.y = 0 + player_pos.y = 0 + + local currentvel = self.object:get_velocity() + local vel = vector.subtract(pos, player_pos) + vel = vector.normalize(vel) + local distance = vector.distance(pos,player_pos) + distance = (1-distance)*10 + vel = vector.multiply(vel,distance) + local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z) + self.object:add_velocity(acceleration) + acceleration = vector.multiply(acceleration, -1) + object:add_player_velocity(acceleration) + end + end + end, + + --makes the boat float + float = function(self) + local pos = self.object:get_pos() + local node = minetest.get_node(pos).name + self.swimming = false + + --flow normally if floating else don't + if node == "main:water" or node =="main:waterflow" then + self.object:set_acceleration(vector.new(0,0,0)) + self.swimming = true + local vel = self.object:get_velocity() + local goal = 9 + local acceleration = vector.new(0,goal-vel.y,0) + acceleration = vector.multiply(acceleration, 0.01) + self.object:add_velocity(acceleration) + --self.object:set_acceleration(vector.new(0,0,0)) + else + self.object:set_acceleration(vector.new(0,-10,0)) + end + end, + + + --slows the boat down + slowdown = function(self) + if not self.moving == true then + local vel = self.object:get_velocity() + local acceleration = vector.new(-vel.x,0,-vel.z) + local deceleration = vector.multiply(acceleration, 0.01) + self.object:add_velocity(deceleration) + end + end, + + lag_correction = function(self,dtime) + local pos = self.object:get_pos() + local velocity = self.object:get_velocity() + if self.lag_check then + local chugent = minetest.get_us_time()/1000000 - self.lag_check + + --print("lag = "..chugent.." ms") + if chugent > 1 and self.old_pos and self.old_velocity then + self.object:move_to(self.old_pos) + self.object:set_velocity(self.old_velocity) + end + end + self.old_pos = pos + self.old_velocity = velocity + self.lag_check = minetest.get_us_time()/1000000 + end, + + flow = function(self) + local flow_dir = flow(self.object:get_pos()) + if flow_dir then + flow_dir = vector.multiply(flow_dir,10) + local vel = self.object:get_velocity() + local acceleration = vector.new(flow_dir.x-vel.x,flow_dir.y-vel.y,flow_dir.z-vel.z) + acceleration = vector.multiply(acceleration, 0.01) + self.object:add_velocity(acceleration) + end + end, + + on_step = function(self, dtime) + self.check_if_on_land(self) + self.push(self) + self.drive(self) + self.float(self) + self.flow(self) + self.slowdown(self) + self.lag_correction(self,dtime) + end, +}) + +minetest.register_craftitem("boat:boat", { + description = "Boat", + inventory_image = "boatitem.png", + wield_image = "boatitem.png", + liquids_pointable = true, + on_place = function(itemstack, placer, pointed_thing) + if not pointed_thing.type == "node" then + return + end + + local sneak = placer:get_player_control().sneak + local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] + if not sneak and noddef.on_rightclick then + minetest.item_place(itemstack, placer, pointed_thing) + return + end + + minetest.add_entity(pointed_thing.above, "boat:boat") + + itemstack:take_item() + + return itemstack + end, +}) + +minetest.register_craft({ + output = "boat:boat", + recipe = { + {"main:wood", "", "main:wood"}, + {"main:wood", "main:wood", "main:wood"}, + }, +}) + +---------------------------------- + + + +minetest.register_entity("boat:iron_boat", { + initial_properties = { + hp_max = 1, + physical = true, + collide_with_objects = false, + collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4}, + visual = "mesh", + mesh = "boat.x", + textures = {"iron_boat.png"}, + visual_size = {x=1,y=1,z=1}, + is_visible = true, + automatic_face_movement_dir = -90.0, + automatic_face_movement_max_rotation_per_sec = 600, + }, + + rider = nil, + iron_boat = true, + + get_staticdata = function(self) + return minetest.serialize({ + --itemstring = self.itemstring, + }) + end, + + on_activate = function(self, staticdata, dtime_s) + if string.sub(staticdata, 1, string.len("return")) == "return" then + local data = minetest.deserialize(staticdata) + if data and type(data) == "table" then + --self.itemstring = data.itemstring + end + else + --self.itemstring = staticdata + end + self.object:set_armor_groups({immortal = 1}) + self.object:set_velocity({x = 0, y = 0, z = 0}) + self.object:set_acceleration({x = 0, y = 0, z = 0}) + end, + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) + local pos = self.object:get_pos() + minetest.add_item(pos, "boat:iron_boat") + self.object:remove() + end, + + + on_rightclick = function(self,clicker) + if not clicker or not clicker:is_player() then + return + end + local player_name = clicker:get_player_name() + + if self.rider and player_name == self.rider then + clicker:set_detach() + local pos = self.object:get_pos() + pos.y = pos.y + 1 + clicker:move_to(pos) + clicker:add_player_velocity(vector.new(0,11,0)) + self.rider = nil + + player_is_attached(clicker,false) + force_update_animation(clicker) + + elseif not self.rider then + self.rider = player_name + clicker:set_attach(self.object, "", {x=0, y=2, z=0}, {x=0, y=0, z=0}) + + set_player_animation(clicker,"sit",0) + player_is_attached(clicker,true) + end + end, + --check if the boat is stuck on land + check_if_on_land = function(self) + local pos = self.object:get_pos() + pos.y = pos.y - 0.37 + local bottom_node = minetest.get_node(pos).name + if (bottom_node == "nether:lava" or bottom_node == "nether:lavaflow" or bottom_node == "air") then + self.on_land = false + else + self.on_land = true + end + + end, + + --players drive the baot + drive = function(self) + if self.rider and not self.on_land == true then + local rider = minetest.get_player_by_name(self.rider) + local move = rider:get_player_control().up + self.moving = nil + if move then + local currentvel = self.object:get_velocity() + local goal = rider:get_look_dir() + goal = vector.multiply(goal,20) + local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z) + acceleration = vector.multiply(acceleration, 0.01) + self.object:add_velocity(acceleration) + self.moving = true + end + else + self.moving = nil + end + end, + + --players push boat + push = function(self) + local pos = self.object:get_pos() + for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do + if object:is_player() and object:get_player_name() ~= self.rider then + local player_pos = object:get_pos() + pos.y = 0 + player_pos.y = 0 + + local currentvel = self.object:get_velocity() + local vel = vector.subtract(pos, player_pos) + vel = vector.normalize(vel) + local distance = vector.distance(pos,player_pos) + distance = (1-distance)*10 + vel = vector.multiply(vel,distance) + local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z) + self.object:add_velocity(acceleration) + acceleration = vector.multiply(acceleration, -1) + object:add_player_velocity(acceleration) + end + end + end, + + --makes the boat float + float = function(self) + local pos = self.object:get_pos() + local node = minetest.get_node(pos).name + self.swimming = false + + --flow normally if floating else don't + if node == "nether:lava" or node =="nether:lavaflow" then + self.swimming = true + local vel = self.object:get_velocity() + local goal = 9 + local acceleration = vector.new(0,goal-vel.y,0) + acceleration = vector.multiply(acceleration, 0.01) + self.object:add_velocity(acceleration) + --self.object:set_acceleration(vector.new(0,0,0)) + else + local vel = self.object:get_velocity() + local goal = -9.81 + local acceleration = vector.new(0,goal-vel.y,0) + acceleration = vector.multiply(acceleration, 0.01) + self.object:add_velocity(acceleration) + --self.object:set_acceleration(vector.new(0,0,0)) + end + end, + + --slows the boat down + slowdown = function(self) + if not self.moving == true then + local vel = self.object:get_velocity() + local acceleration = vector.new(-vel.x,0,-vel.z) + local deceleration = vector.multiply(acceleration, 0.01) + self.object:add_velocity(deceleration) + end + end, + + lag_correction = function(self,dtime) + local pos = self.object:get_pos() + local velocity = self.object:get_velocity() + if self.lag_check then + local chugent = minetest.get_us_time()/1000000- self.lag_check + + --print("lag = "..chugent.." ms") + if chugent > 70 and self.old_pos and self.old_velocity then + self.object:move_to(self.old_pos) + self.object:set_velocity(self.old_velocity) + end + end + self.old_pos = pos + self.old_velocity = velocity + self.lag_check = minetest.get_us_time()/1000000 + end, + + on_step = function(self, dtime) + self.check_if_on_land(self) + self.push(self) + self.drive(self) + self.float(self) + lavaflow(self) + self.slowdown(self) + self.lag_correction(self,dtime) + end, +}) + +minetest.register_craftitem("boat:iron_boat", { + description = "Nether Iron Boat", + inventory_image = "iron_boatitem.png", + wield_image = "iron_boatitem.png", + liquids_pointable = true, + on_place = function(itemstack, placer, pointed_thing) + if not pointed_thing.type == "node" then + return + end + + local sneak = placer:get_player_control().sneak + local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] + if not sneak and noddef.on_rightclick then + minetest.item_place(itemstack, placer, pointed_thing) + return + end + + minetest.add_entity(pointed_thing.above, "boat:iron_boat") + + itemstack:take_item() + + return itemstack + end, +}) + +minetest.register_craft({ + output = "boat:iron_boat", + recipe = { + {"main:iron", "main:coal", "main:iron"}, + {"main:iron", "main:iron", "main:iron"}, + }, +})