diff --git a/init.lua b/init.lua deleted file mode 100644 index 7ec9d93..0000000 --- a/init.lua +++ /dev/null @@ -1,598 +0,0 @@ -local S = minetest.get_translator(minetest.get_current_modname()) - --- globalscope var for the whole mod -sum_airship = { - speed_mult = 4, - fuel_time = 10, -- per second - i = {}, -} - -local boat_visual_size = {x = 1, y = 1, z = 1} -local boat_y_offset = 0.35 -local boat_y_offset_ground = boat_y_offset + 0.6 -local boat_side_offset = 1.001 -local boat_max_hp = 4 - - - -local has_air_currents = minetest.get_modpath("sum_air_currents") ~= nil -local mcl = minetest.get_modpath("mcl_player") ~= nil - -dofile(minetest.get_modpath("sum_airship") .. DIR_DELIM .. "crafts.lua") - -local function is_group(pos, group) - local nn = minetest.get_node(pos).name - return minetest.get_item_group(nn, group) ~= 0 -end - -local function is_river_water(p) - return true -end - -local function is_ice(pos) - return false -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 - -local function check_object(obj) - return obj and (obj:is_player() or obj:get_luaentity()) and obj -end - -local function get_visual_size(obj) - return obj:is_player() and {x = 1, y = 1, z = 1} or obj:get_luaentity()._old_visual_size or obj:get_properties().visual_size -end - -local function set_attach(boat) - boat._driver:set_attach(boat.object, "", - {x = 0, y = 0.42, z = -2}, {x = 0, y = 0, z = 0}) -end - -local function set_double_attach(boat) - boat._driver:set_attach(boat.object, "", - {x = 0, y = 0.8, z = -2}, {x = 0, y = 0, z = 0}) - boat._passenger:set_attach(boat.object, "", - {x = 0, y = 0.8, z = -3.2}, {x = 0, y = 0, z = 0}) -end - -local function attach_object(self, obj) - if self._driver then - if self._driver:is_player() then - self._passenger = obj - else - self._passenger = self._driver - self._driver = obj - end - set_double_attach(self) - else - self._driver = obj - set_attach(self) - end - - local visual_size = get_visual_size(obj) - local yaw = self.object:get_yaw() - obj:set_properties({visual_size = vector.divide(visual_size, boat_visual_size)}) - if obj:is_player() then - local name = obj:get_player_name() - if mcl then mcl_player.player_attached[name] = true end - minetest.after(0.2, function(player) - if player and mcl then - mcl_player.player_set_animation(player, "sit" , 30) - end - end, obj) - obj:set_look_horizontal(yaw) - else - obj:get_luaentity()._old_visual_size = visual_size - end -end - -local function detach_object(obj, change_pos) - obj:set_detach() - obj:set_properties({visual_size = get_visual_size(obj)}) - if obj:is_player() and mcl then - mcl_player.player_attached[obj:get_player_name()] = false - mcl_player.player_set_animation(obj, "stand" , 30) - else - local luaent = obj:get_luaentity() - if luaent then luaent._old_visual_size = nil end - end - if change_pos then - obj:set_pos(vector.add(obj:get_pos(), vector.new(0, 0.2, 0))) - end - obj:set_pos(vector.offset(obj:get_pos(), 0, 0.7, 0)) - minetest.after(0.1, function(obj, change_pos) - obj:set_pos(vector.offset(obj:get_pos(), 0, 0.7, 0)) - end, obj, change_pos) -end - --- --- Boat entity --- - -local ship = { - physical = true, - pointable = true, - -- collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, - visual = "mesh", - mesh = "sum_airship_boat.b3d", - textures = {"sum_airship_texture_oak_boat.png"}, - animations = { - idle = {x= 10, y= 90}, - fly = {x= 91, y= 170}, - boost = {x= 91, y= 170}, - }, - visual_size = boat_visual_size, - hp_max = boat_max_hp, - damage_texture_modifier = "^[colorize:white:0", - - _driver = nil, -- Attached driver (player) or nil if none - _passenger = nil, - _v = 0, -- Speed - _last_v = 0, -- Temporary speed variable - _removed = false, -- If true, boat entity is considered removed (e.g. after punch) and should be ignored - _itemstring = "sum_airship:boat", -- Itemstring of the boat item (implies boat type) - _animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling forwards - _regen_timer = 0, - _damage_anim = 0, - _fuel = 0, - _sounds = { - engine = { - handle = nil, - gain = 0.1, - playing = false, - time_elapsed = 0, - }, - engine_stop = { - handle = nil, - gain = 0.1, - playing = false, - time_elapsed = 0, - }, - } -} - - -function ship.on_activate(self, staticdata, dtime_s) - self.object:set_armor_groups({fleshy = 100}) - self.object:set_animation(self.animations.idle, 25) - local data = minetest.deserialize(staticdata) - if type(data) == "table" then - self._v = data.v - self._last_v = self._v - self._itemstring = data.itemstring - self._fuel = data.fuel - end - self._sounds = { -- workaround for copy vs reference issue - engine = { - handle = nil, - gain = 0.1, - playing = false, - time_elapsed = 0, - }, - engine_stop = { - handle = nil, - gain = 0.1, - playing = false, - time_elapsed = 0, - }, - } -end - -function ship.get_staticdata(self) - return minetest.serialize({ - v = self._v, - itemstring = self._itemstring, - fuel = self._fuel, - textures = self.object:get_properties().textures - }) -end - -function ship.on_death(self, killer) - if killer and killer:is_player() and minetest.is_creative_enabled(killer:get_player_name()) then - local inv = killer:get_inventory() - if not inv:contains_item("main", self._itemstring) then - inv:add_item("main", self._itemstring) - end - else - minetest.add_item(self.object:get_pos(), self._itemstring) - end - if self._driver then - detach_object(self._driver) - end - if self._passenger then - detach_object(self._passenger) - end - self._driver = nil - self._passenger = nil - - -- stop sounds - if self._sounds then - if self._sounds.engine - and self._sounds.engine.handle then - ship.sound_stop(self._sounds.engine) - end - if self._sounds.engine_stop - and self._sounds.engine_stop.handle then - ship.sound_stop(self._sounds.engine_stop) - end - end -end - -function ship.on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) - if damage > 0 then - self._regen_timer = 0 - end -end - -function ship.sound_countdown(self, dtime) - for _, sound in pairs(self._sounds) do - if sound.playing then - sound.time_elapsed = sound.time_elapsed + dtime - end - end -end - - --- 10, 5, 5 --- this system ensures collision kind of works with balloons. --- does not include entity to entity collisions -local balloon = {} -balloon.offset = 6 -balloon.length = 3.5 -balloon.height = 2.5 -local balloon_nodes = {} -balloon_nodes[0] = { -- top - p = vector.new(0, balloon.offset + balloon.height, 0), - dir = vector.new(0, -5, 0),} -balloon_nodes[1] = { -- front - p = vector.new(0, balloon.offset, balloon.length), - dir = vector.new(0, -0.5, -1),} -balloon_nodes[2] = { -- back - p = vector.new(0, balloon.offset, -balloon.length), - dir = vector.new(0, 0, 1),} -balloon_nodes[3] = { -- left or right - p = vector.new(balloon.length, balloon.offset, 0), - dir = vector.new(-1, 0, 0),} -balloon_nodes[4] = { -- left or right - p = vector.new(-balloon.length, balloon.offset, 0), - dir = vector.new(1, 0, 0),} --- diagonals -local vdiag = 0.7 -balloon_nodes[5] = { - p = vector.new(-balloon.length*vdiag, balloon.offset, -balloon.length*vdiag), - dir = vector.new(vdiag, 0, vdiag),} -balloon_nodes[6] = { - p = vector.new(balloon.length*vdiag, balloon.offset, -balloon.length*vdiag), - dir = vector.new(-vdiag, 0, vdiag),} -balloon_nodes[7] = { - p = vector.new(-balloon.length*vdiag, balloon.offset, balloon.length*vdiag), - dir = vector.new(vdiag, 0, -vdiag),} -balloon_nodes[8] = { - p = vector.new(balloon.length*vdiag, balloon.offset, balloon.length*vdiag), - dir = vector.new(-vdiag, 0, -vdiag),} - -function ship.get_balloon_collide(self) - local force = vector.new() - local o = self.object:get_pos() - for _, check in pairs(balloon_nodes) do - local n = minetest.get_node(vector.add(check.p, o)) - if n and minetest.registered_nodes[n.name] - and minetest.registered_nodes[n.name].walkable then - force = vector.add(force, check.dir) - end - end - return force -end - -function ship.on_step(self, dtime, moveresult) - ship.sound_countdown(self, dtime) - self._v = get_v(self.object:get_velocity()) * get_sign(self._v) - local v_factor = 1 - local v = self.object:get_velocity() - local p = self.object:get_pos() - local in_water = minetest.get_item_group(minetest.get_node(p).name, "liquid") ~= 0 - local on_water = (minetest.get_item_group(minetest.get_node(vector.offset(p, 0, -0.2, 0)).name, "liquid") ~= 0 and not in_water) - local node_below = minetest.get_node(vector.offset(p, 0, -0.3, 0)).name - local is_on_floor = minetest.registered_nodes[node_below].walkable - - local hp = self.object:get_hp() - local regen_timer = self._regen_timer + dtime - if hp >= boat_max_hp then - regen_timer = 0 - elseif regen_timer >= 3 then - hp = hp + 1 - self.object:set_hp(hp) - regen_timer = 0 - end - self._regen_timer = regen_timer - - local climb = 0 - local forward = 0 - - - local had_passenger = self._passenger - - self._driver = check_object(self._driver) - self._passenger = check_object(self._passenger) - - if self._passenger then - if not self._driver then - self._driver = self._passenger - self._passenger = nil - else - local ctrl = self._passenger:get_player_control() - if ctrl and ctrl.sneak then - detach_object(self._passenger, true) - self._passenger = nil - end - end - end - - local has_controls = false - if self._driver then - if mcl then - mcl_player.player_attached[self._driver:get_player_name()] = true - mcl_player.player_set_animation(self._driver, "walk" , 30) - mcl_player.player_set_animation(self._driver, "sit" , 30) - end - if had_passenger and not self._passenger then - set_attach(self) - end - local ctrl = self._driver:get_player_control() - if ctrl then has_controls = true end - if ctrl and ctrl.sneak then - detach_object(self._driver, true) - self._driver = nil - return - end - local yaw = self.object:get_yaw() - -- if mcl and mcl_player.player_get_animation(self._driver).animation ~= "sit" then - -- mcl_player.player_set_animation(self._driver, "sit" , 30) - -- end - if ctrl and not in_water then - if ctrl.up then - -- Forwards - forward = forward + 1 - elseif ctrl.down then - forward = forward - 1 - end - if ctrl.aux1 then - climb = climb - 1 - elseif ctrl.jump then - climb = climb + 1 - end - - if ctrl.left then - if self._v < 0 then - self.object:set_yaw(yaw - (1 + dtime) * 0.03 * v_factor) - else - self.object:set_yaw(yaw + (1 + dtime) * 0.03 * v_factor) - end - elseif ctrl.right then - if self._v < 0 then - self.object:set_yaw(yaw + (1 + dtime) * 0.03 * v_factor) - else - self.object:set_yaw(yaw - (1 + dtime) * 0.03 * v_factor) - end - end - end - end - - -- for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do - -- local entity = obj:get_luaentity() - -- if entity and entity.is_mob then - -- attach_object(self, obj) - -- break - -- end - -- end - local s = get_sign(self._v) - - local yaw = self.object:get_yaw() - local yaw_dir = minetest.yaw_to_dir(yaw) - local anim = (boat_max_hp - hp - regen_timer / 3) / boat_max_hp * math.pi / 8 - - self.object:set_rotation(vector.new(anim, yaw, anim)) - - local vel = vector.new(0, 0, 0) - if true then - local speed = sum_airship.speed_mult - if self._fuel > 0 then - self._fuel = self._fuel - dtime - speed = speed * 3 - end - dir = vector.multiply(yaw_dir, forward) - dir.y = climb - vel = vector.multiply(dir, speed) - if not self._driver then - vel.y = vel.y - 0.6 - end - end - if in_water then - vel = {x=0, y=5, z=0} - elseif on_water and not self._driver then - vel = {x=0, y=0, z=0} - v = {x=0, y=0, z=0} - end - - local wind_vel = vector.new(0,0,0) - if has_air_currents then - wind_vel = sum_air_currents.get_wind(p) - if self._driver or not is_on_floor then - vel = vector.add(wind_vel, vel) - end - end - - local slowdown = 0.983 - if forward == 0 then - slowdown = 0.97 - end - - if self._driver then - local collide_force = ship.get_balloon_collide(self) - -- collide_force = vector.normalize(collide_force) - if collide_force ~= vector.new() then - collide_force = vector.multiply(collide_force, 0.1) - v = vector.multiply(v, 0.95) - end - v = vector.add(v, collide_force) - end - - if is_on_floor and not self._driver then - vel = vector.new(0, 0, 0) - self.object:set_velocity(vel) - else - v.x = v.x * slowdown - v.z = v.z * slowdown - v.y = v.y * 0.97 - self.object:set_velocity(v) - end - - self.object:set_acceleration(vel) - - local chimney_pos = ship.get_chimney_pos(self) - - ship.update_sound(self, dtime, forward) - - local is_thrust = self._driver and forward ~= 0 - - local spread = 0.06 - if self._fuel > 0 or (math.random(0,100) > 80 and is_thrust) or math.random(0,100) > 95 then - minetest.add_particle({ - pos = vector.offset(chimney_pos, math.random(-1, 1)*spread, 0, math.random(-1, 1)*spread), - velocity = vector.add(wind_vel, {x=0, y=math.random(0.2*100,0.7*100)/100, z=0}), - expirationtime = math.random(0.5, 2), - size = math.random(0.1, 4), - collisiondetection = false, - vertical = false, - texture = "sum_airship_smoke.png", - }) - end - -- animations - if self._fuel > 0 then - self.object:set_animation(self.animations.boost, 25) - elseif is_thrust then - self.object:set_animation(self.animations.fly, 25) - else - self.object:set_animation(self.animations.idle, 25) - end -end - --- Register one entity for all boat types -minetest.register_entity("sum_airship:boat", ship) - -local boat_ids = { "main" } -local names = { S("Oak Airship") } -local images = { "oak" } - -for b=1, #boat_ids do - local itemstring = "sum_airship:"..boat_ids[b] - - local longdesc, usagehelp, tt_help, help, helpname - help = false - -- Only create one help entry for all boats - if b == 1 then - help = true - longdesc = S("Airship are used to travel in the air and stuff.") - usagehelp = S("thing") - helpname = S("Airship") - end - tt_help = S("Air vehicle") - - minetest.register_craftitem(itemstring, { - description = names[b], - _tt_help = tt_help, - _doc_items_create_entry = help, - _doc_items_entry_name = helpname, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - inventory_image = "sum_airship_"..images[b].."_boat.png", - liquids_pointable = true, - groups = { boat = 1, transport = 1}, - stack_max = 1, - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - return itemstack - end - - -- Call on_rightclick if the pointed node defines it - local node = minetest.get_node(pointed_thing.under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack - end - end - - local pos = table.copy(pointed_thing.under) - local dir = vector.subtract(pointed_thing.above, pointed_thing.under) - - if math.abs(dir.x) > 0.9 or math.abs(dir.z) > 0.9 then - pos = vector.add(pos, vector.multiply(dir, boat_side_offset)) - else - pos = vector.add(pos, vector.multiply(dir, boat_y_offset_ground)) - end - local boat = minetest.add_entity(pos, "sum_airship:boat") - local texture = "sum_airship_texture_"..images[b].."_boat.png" - boat:get_luaentity()._itemstring = itemstring - boat:set_properties({textures = { texture, texture, texture, texture, texture }}) - boat:set_yaw(placer:get_look_horizontal()) - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() - end - return itemstack - end, - _on_dispense = function(stack, pos, droppos, dropnode, dropdir) - local below = {x=droppos.x, y=droppos.y-1, z=droppos.z} - local belownode = minetest.get_node(below) - -- Place boat as entity on or in water - if minetest.get_item_group(dropnode.name, "water") ~= 0 or (dropnode.name == "air" and minetest.get_item_group(belownode.name, "water") ~= 0) then - minetest.add_entity(droppos, "sum_airship:boat") - else - minetest.add_item(droppos, stack) - end - end, - }) - - local cvs = "sum_airship:canvas_roll" - local hul = "sum_airship:hull" - local sng = "default:paper" - local iro = "default:steel_ingot" - if minetest.get_modpath("mcl_mobitems") - and minetest.get_modpath("mcl_core") then - sng = "mcl_mobitems:string" - iro = "mcl_core:iron_ingot" - end - minetest.register_craft({ - output = itemstring, - recipe = { - {cvs, cvs, cvs}, - {sng, iro, sng}, - {sng, hul, sng}, - }, - }) -end - -minetest.register_craft({ - type = "fuel", - recipe = "group:boat", - burntime = 20, -}) - -if minetest.get_modpath("doc_identifier") and doc.sub.identifier then - doc.sub.identifier.register_object("sum_airship:boat", "craftitems", "sum_airship:boat") -end diff --git a/textures/sum_airship_oak_boat.png b/textures/sum_airship_oak_boat.png deleted file mode 100644 index defdfaf..0000000 Binary files a/textures/sum_airship_oak_boat.png and /dev/null differ