diff --git a/balloon.lua b/balloon.lua index 8021cff..9a79036 100644 --- a/balloon.lua +++ b/balloon.lua @@ -9,10 +9,153 @@ me.vars = { fuel_time = 30, } +local ship = { + physical = true, + pointable = true, + collisionbox = {-0.6, -0.2, -0.6, 0.6, 0.3, 0.6}, + selectionbox = {-0.7, -0.35, -0.7, 0.7, 0.3, 0.7}, + hp_max = 3, + visual = "mesh", + backface_culling = false, + mesh = "sum_airship_boat.b3d", + textures = {"sum_airship_texture.png"}, + animations = { + idle = {x= 10, y= 90}, + fly = {x= 91, y= 170}, + boost = {x= 91, y= 170}, + }, + on_rightclick = me.on_rightclick, + on_activate = me.on_activate, + get_staticdata = me.get_staticdata, + on_death = me.on_death, + on_step = me.on_step, + _driver = nil, + _removed = false, + _flags = {}, + _itemstring = "sum_hot_air_balloon:balloon_item", +} + +local sounds = { + engine_idle = { + sound_name = "sum_airship_lip_trill", + gain = 1.4, + max_hear_distance = 10, + loop = false, + pitch = 0.75, + }, + engine_stop = { + sound_name = "sum_airship_lip_trill_end", + gain = 2.2, + max_hear_distance = 10, + loop = false, + pitch = 1, + }, + engine_boost = { + sound_name = "sum_airship_lip_trill", + gain = 40, + max_hear_distance = 10, + loop = false, + pitch = 1, + }, +} + +function ship.sound_play(self, sound_obj, sound_instance) + sound_instance.handle = minetest.sound_play(sound_obj.sound_name, { + gain = sound_obj.gain, + max_hear_distance = sound_obj.max_hear_distance, + loop = sound_obj.loop, + pitch = sound_obj.pitch or 1, + object = self.object, + }) + sound_instance.playing = true + sound_instance.time_elapsed = 0 +end + +function ship.sound_stop(sound_instance) + if sound_instance.handle then + minetest.sound_stop(sound_instance.handle) + end + sound_instance.playing = false + sound_instance.time_elapsed = 0 + sound_instance.handle = nil +end + +function ship.update_sound(self, dtime, forward) + local fuel = self._fuel + local is_thrust = forward ~= 0 and self._driver + if not fuel or not type(fuel) == "number" then self._fuel = 0 end + + if self._sounds.engine.time_elapsed > 2.1 + and self._sounds.engine.handle + and self._sounds.engine.playing then + ship.sound_stop(self._sounds.engine) + end + if not self._sounds.engine.playing then + if self._fuel > 1 then + ship.sound_play(self, sounds.engine_boost, self._sounds.engine) + elseif is_thrust then + ship.sound_play(self, sounds.engine_idle, self._sounds.engine) + end + if self._fuel > 1 and self._sounds.engine_stop.playing then + ship.sound_stop(self._sounds.engine_stop) + end + end + + if self._fuel <= 1 and self._sounds.engine.playing then + if self._fuel > 0 and not self._sounds.engine_stop.playing + and self._sounds.engine_stop.time_elapsed == 0 then + ship.sound_play(self, sounds.engine_stop, self._sounds.engine_stop) + end + if not is_thrust + or (self._sounds.engine_stop.time_elapsed == 0 + and self._sounds.engine_stop.playing) then + ship.sound_stop(self._sounds.engine) + end + end +end + +minetest.register_on_respawnplayer(detach_object) + +function ship.on_rightclick(self, clicker) + local item = clicker:get_wielded_item() + local item_name = item:get_name() + if clicker and (string.find(item_name, ":coal") + or string.find(item_name, ":charcoal")) then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + item:take_item() + clicker:set_wielded_item(item) + end + self._fuel = self._fuel + sum_airship.fuel_time + ship.sound_stop(self._sounds.engine) + minetest.sound_play("sum_airship_fire", { + gain = 1, + object = self.object, + }) + else + attach_object(self, clicker) + end +end + +ship.chimney_dist = -1.0 +ship.chimney_yaw = 0.13 +ship.chimney_height = 0.9 +function ship.get_chimney_pos(self) + local p = self.object:get_pos() + local yaw = self.object:get_yaw() + local ret = { + x = p.x + (ship.chimney_dist * math.sin(-yaw + ship.chimney_yaw)), + y = p.y + ship.chimney_height, + z = p.z + (ship.chimney_dist * math.cos(-yaw + ship.chimney_yaw))} + return ret +end + function me.on_activate(self, staticdata, dtime_s) 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 if data._driver then self._driver = minetest.get_player_by_name((data._driver:get_player_name())) else @@ -216,35 +359,7 @@ function me.on_step(self, dtime, moveresult) end -minetest.register_entity("sum_hot_air_balloon:balloon_ENTITY", { - physical = true, - pointable = true, - collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.2, 0.5}, - selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.2, 0.5}, - hp_max = 3, - visual = "mesh", - mesh = "sum_hot_air_balloon.b3d", - backface_culling = false, - textures = { - "sum_hot_air_balloon_canvas.png", -- balloon - "sum_wood_ash_planks.png", -- cradle - "sum_wood_oak_plank.png", -- lining - "sum_wood_oak_plank.png", -- strut - "sum_wood_oak_plank.png", -- strut - "sum_hot_air_balloon_canvas.png", -- burner - "sum_wood_oak_plank.png", -- small strut - "sum_wood_oak_plank.png", -- small strut - }, - on_rightclick = me.on_rightclick, - on_activate = me.on_activate, - get_staticdata = me.get_staticdata, - on_death = me.on_death, - on_step = me.on_step, - _driver = nil, - _removed = false, - _flags = {}, - _itemstring = "sum_hot_air_balloon:balloon_item", -}) +minetest.register_entity("sum_hot_air_balloon:balloon_ENTITY", ship) minetest.register_craftitem("sum_hot_air_balloon:balloon_item", { description = "Hot air balloon", diff --git a/init.lua b/init.lua index 6005bc8..7ec9d93 100644 --- a/init.lua +++ b/init.lua @@ -125,12 +125,10 @@ end -- Boat entity -- -local boat = { +local ship = { physical = true, pointable = true, -- collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, - collisionbox = {-0.6, -0.2, -0.6, 0.6, 0.3, 0.6}, - selectionbox = {-0.7, -0.35, -0.7, 0.7, 0.3, 0.7}, visual = "mesh", mesh = "sum_airship_boat.b3d", textures = {"sum_airship_texture_oak_boat.png"}, @@ -169,121 +167,8 @@ local boat = { } } -local sounds = { - engine_idle = { - sound_name = "sum_airship_lip_trill", - gain = 1.4, - max_hear_distance = 10, - loop = false, - pitch = 0.75, - }, - engine_stop = { - sound_name = "sum_airship_lip_trill_end", - gain = 2.2, - max_hear_distance = 10, - loop = false, - pitch = 1, - }, - engine_boost = { - sound_name = "sum_airship_lip_trill", - gain = 40, - max_hear_distance = 10, - loop = false, - pitch = 1, - }, -} -function boat.sound_play(self, sound_obj, sound_instance) - sound_instance.handle = minetest.sound_play(sound_obj.sound_name, { - gain = sound_obj.gain, - max_hear_distance = sound_obj.max_hear_distance, - loop = sound_obj.loop, - pitch = sound_obj.pitch or 1, - object = self.object, - }) - sound_instance.playing = true - sound_instance.time_elapsed = 0 -end - -function boat.sound_stop(sound_instance) - if sound_instance.handle then - minetest.sound_stop(sound_instance.handle) - end - sound_instance.playing = false - sound_instance.time_elapsed = 0 - sound_instance.handle = nil -end - -function boat.update_sound(self, dtime, forward) - local fuel = self._fuel - local is_thrust = forward ~= 0 and self._driver - if not fuel or not type(fuel) == "number" then self._fuel = 0 end - - if self._sounds.engine.time_elapsed > 2.1 - and self._sounds.engine.handle - and self._sounds.engine.playing then - boat.sound_stop(self._sounds.engine) - end - if not self._sounds.engine.playing then - if self._fuel > 1 then - boat.sound_play(self, sounds.engine_boost, self._sounds.engine) - elseif is_thrust then - boat.sound_play(self, sounds.engine_idle, self._sounds.engine) - end - if self._fuel > 1 and self._sounds.engine_stop.playing then - boat.sound_stop(self._sounds.engine_stop) - end - end - - if self._fuel <= 1 and self._sounds.engine.playing then - if self._fuel > 0 and not self._sounds.engine_stop.playing - and self._sounds.engine_stop.time_elapsed == 0 then - boat.sound_play(self, sounds.engine_stop, self._sounds.engine_stop) - end - if not is_thrust - or (self._sounds.engine_stop.time_elapsed == 0 - and self._sounds.engine_stop.playing) then - boat.sound_stop(self._sounds.engine) - end - end -end - -minetest.register_on_respawnplayer(detach_object) - -function boat.on_rightclick(self, clicker) - local item = clicker:get_wielded_item() - local item_name = item:get_name() - if clicker and (string.find(item_name, ":coal") - or string.find(item_name, ":charcoal")) then - if not minetest.is_creative_enabled(clicker:get_player_name()) then - item:take_item() - clicker:set_wielded_item(item) - end - self._fuel = self._fuel + sum_airship.fuel_time - boat.sound_stop(self._sounds.engine) - minetest.sound_play("sum_airship_fire", { - gain = 1, - object = self.object, - }) - else - attach_object(self, clicker) - end -end - -boat.chimney_dist = -1.0 -boat.chimney_yaw = 0.13 -boat.chimney_height = 0.9 -function boat.get_chimney_pos(self) - local p = self.object:get_pos() - local yaw = self.object:get_yaw() - local ret = { - x = p.x + (boat.chimney_dist * math.sin(-yaw + boat.chimney_yaw)), - y = p.y + boat.chimney_height, - z = p.z + (boat.chimney_dist * math.cos(-yaw + boat.chimney_yaw))} - return ret -end - -function boat.on_activate(self, staticdata, dtime_s) +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) @@ -292,12 +177,6 @@ function boat.on_activate(self, staticdata, dtime_s) self._last_v = self._v self._itemstring = data.itemstring self._fuel = data.fuel - - while #data.textures < 5 do - table.insert(data.textures, data.textures[1]) - end - - self.object:set_properties({textures = data.textures}) end self._sounds = { -- workaround for copy vs reference issue engine = { @@ -315,7 +194,7 @@ function boat.on_activate(self, staticdata, dtime_s) } end -function boat.get_staticdata(self) +function ship.get_staticdata(self) return minetest.serialize({ v = self._v, itemstring = self._itemstring, @@ -324,10 +203,7 @@ function boat.get_staticdata(self) }) end -function boat.on_death(self, killer) - if minetest.get_modpath("mcl_burning") then - mcl_burning.extinguish(self.object) 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 @@ -345,26 +221,26 @@ function boat.on_death(self, killer) self._driver = nil self._passenger = nil --- stop sounds + -- stop sounds if self._sounds then if self._sounds.engine and self._sounds.engine.handle then - boat.sound_stop(self._sounds.engine) + ship.sound_stop(self._sounds.engine) end if self._sounds.engine_stop and self._sounds.engine_stop.handle then - boat.sound_stop(self._sounds.engine_stop) + ship.sound_stop(self._sounds.engine_stop) end end end -function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) +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 boat.sound_countdown(self, dtime) +function ship.sound_countdown(self, dtime) for _, sound in pairs(self._sounds) do if sound.playing then sound.time_elapsed = sound.time_elapsed + dtime @@ -411,18 +287,11 @@ balloon_nodes[8] = { p = vector.new(balloon.length*vdiag, balloon.offset, balloon.length*vdiag), dir = vector.new(-vdiag, 0, -vdiag),} -function boat.get_balloon_collide(self) +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)) - -- minetest.add_particle({ - -- pos = vector.add(o, check.p), - -- velocity = vector.new(0, 1, 0), - -- expirationtime = math.random(0.5, 2), - -- size = math.random(0.1, 4), - -- texture = "sum_airship_smoke.png", - -- }) if n and minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable then force = vector.add(force, check.dir) @@ -431,15 +300,11 @@ function boat.get_balloon_collide(self) return force end -function boat.on_step(self, dtime, moveresult) - boat.sound_countdown(self, dtime) - if minetest.get_modpath("mcl_burning") then - mcl_burning.tick(self.object, dtime, self) 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_slowdown = 0.1 - local v = self.object:get_velocity() + 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) @@ -457,18 +322,8 @@ function boat.on_step(self, dtime, moveresult) end self._regen_timer = regen_timer - if moveresult and moveresult.collides then - for _, collision in pairs(moveresult.collisions) do - local pos = collision.node_pos - if collision.type == "node" and minetest.get_item_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then - minetest.dig_node(pos) - end - end - end - - - local climb = 0 - local forward = 0 + local climb = 0 + local forward = 0 local had_passenger = self._passenger @@ -514,14 +369,14 @@ function boat.on_step(self, dtime, moveresult) if ctrl.up then -- Forwards forward = forward + 1 - elseif ctrl.down then - forward = forward - 1 - end + elseif ctrl.down then + forward = forward - 1 + end if ctrl.aux1 then climb = climb - 1 - elseif ctrl.jump then - climb = climb + 1 - end + elseif ctrl.jump then + climb = climb + 1 + end if ctrl.left then if self._v < 0 then @@ -589,7 +444,7 @@ function boat.on_step(self, dtime, moveresult) end if self._driver then - local collide_force = boat.get_balloon_collide(self) + 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) @@ -610,9 +465,9 @@ function boat.on_step(self, dtime, moveresult) self.object:set_acceleration(vel) - local chimney_pos = boat.get_chimney_pos(self) + local chimney_pos = ship.get_chimney_pos(self) - boat.update_sound(self, dtime, forward) + ship.update_sound(self, dtime, forward) local is_thrust = self._driver and forward ~= 0 @@ -639,7 +494,7 @@ function boat.on_step(self, dtime, moveresult) end -- Register one entity for all boat types -minetest.register_entity("sum_airship:boat", boat) +minetest.register_entity("sum_airship:boat", ship) local boat_ids = { "main" } local names = { S("Oak Airship") } diff --git a/textures/sum_airship.png b/textures/sum_airship.png new file mode 100644 index 0000000..5b675d7 Binary files /dev/null and b/textures/sum_airship.png differ diff --git a/textures/sum_airship_texture_oak_boat.png b/textures/sum_airship_texture_oak_boat.png index ed74bf8..572d301 100644 Binary files a/textures/sum_airship_texture_oak_boat.png and b/textures/sum_airship_texture_oak_boat.png differ