123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- local modpath = minetest.get_modpath("sailing_canoe")
- local float_or_fall, turn, handle_wind, move =
- dofile(modpath .. "/movement.lua")
- local toggle_sail, turn_sail =
- dofile(modpath .. "/sail.lua")
- local set_colors, dye, spawn_particles, show_wind =
- dofile(modpath .. "/visuals.lua")
- local canoe = {
- hp_max = 300,
- initial_properties =
- {
- physical = true,
- -- Warning: Do not change the position of the collisionbox top surface,
- -- lowering it causes the boat to fall through the world if underwater
- collisionbox = {-1.3, -0.35, -1.3, 1.3, 0.3, 1.3},
- visual = "mesh",
- mesh = "sailing_canoe_canoe.obj",
- textures = {"sailing_canoe_entity.png"},
- },
- driver = nil,
- cargo = nil,
- equipment = nil,
- removed = false,
- sail = nil,
- sail_color = nil,
- sail_yaw = 0,
- control_cooldown = 0,
- speed = 0,
- flag = nil,
- flag_color = nil,
- }
- local driver_attach = {x = -10.5, y = 2, z = 0}
- local cargo_attach = {x = -10.5, y = 4, z = -10}
- local function remove(self)
- --TODO: drop item
- if self.sail
- then
- self.sail:remove()
- end
- if self.flag
- then
- self.flag:remove()
- end
- self.object:remove()
- end
- local function load_cargo(self)
- if self.control_cooldown > 0
- then
- return
- end
- self.control_cooldown = 0.25
- if self.cargo
- then
- --unload
- self.cargo:set_detach()
- self.cargo = nil
- else
- local pos = self.object:get_pos()
- local objs = minetest.get_objects_inside_radius(pos, 6)
- for _, obj in ipairs(objs)
- do
- if obj ~= self.object and
- obj ~= self.driver and
- obj ~= self.flag and
- obj ~= self.sail and
- not obj:is_player()
- then
- obj:set_attach(
- self.object,
- "",
- cargo_attach,
- {x = 0, y = 0, z = 0})
- self.cargo = obj
- break
- end
- end
- end
- end
- local function handle_control(self)
- if not self.driver
- then
- return
- end
- local ctrl = self.driver:get_player_control()
- if ctrl.sneak
- then
- turn_sail(self, ctrl.left, ctrl.right)
- else
- turn(self, ctrl.left, ctrl.right)
- end
- if ctrl.jump
- then
- toggle_sail(self)
- set_colors(self)
- end
- if ctrl.aux1
- then
- load_cargo(self)
- end
- end
- ------------------------------------------------------------------------
- function canoe.on_step(self, dtime)
- self.control_cooldown = self.control_cooldown - dtime
- handle_control(self)
- handle_wind(self)
- float_or_fall(self)
- move(self)
- spawn_particles(self)
- show_wind(self)
- end
- function canoe.on_detach_child(self, child)
- if child:is_player()
- then
- self.driver = nil
- end
- end
- function canoe.get_staticdata(self)
- local data =
- {
- flag_color = self.flag_color,
- sail_color = self.sail_color,
- hp = self.object:get_hp(),
- }
- return minetest.serialize(data)
- end
- function canoe.on_activate(self, staticdata)
- local data = minetest.deserialize(staticdata) or {}
- if not data.flag_color
- then
- data.flag_color = "red"
- end
- self.flag_color = data.flag_color
- if not data.sail_color
- then
- data.sail_color = "white"
- end
- self.sail_color = data.sail_color
- if data.hp
- then
- self.object:set_hp(data.hp)
- end
- local pos = self.object:get_pos()
- self.flag = minetest.add_entity(pos, "sailing_canoe:flag")
- if self.flag
- then
- self.flag:set_attach(
- self.object,
- "",
- nil,
- {x = 0, y = self.sail_yaw, z = 0})
- end
- set_colors(self)
- end
- function canoe.on_rightclick(self, clicker)
- if not clicker
- then
- return
- end
- if dye(self, clicker)
- then
- return
- end
- local name = clicker:get_player_name()
- if self.driver == clicker
- then
- --dismount
- clicker:set_detach()
- self.driver = nil
- if player_api
- then
- player_api.player_attached[name] = nil
- end
- elseif not self.driver
- then
- --mount
- self.driver = clicker
- clicker:set_attach(
- self.object,
- "",
- driver_attach,
- {x = 0, y = 0, z = 0})
- if player_api
- then
- player_api.player_attached[name] = true
- minetest.after(0.1, player_api.set_animation, clicker, "sit", 30)
- end
- end
- end
- function canoe.on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
- local hp = self.object:get_hp() - damage
- if puncher then
- --put item into inventory or drop it
- local name = puncher:get_player_name()
- if name ~= '' then
- local inv = puncher:get_inventory()
- local stack = ItemStack("sailing_canoe:canoe")
- local meta = stack:get_meta()
- meta:set_string("flag_color", self.flag_color)
- meta:set_string("sail_color", self.sail_color)
- --check if player is in creative and already has
- --the same item
- --takes sail and flag colors into account
- if not (creative and creative.is_enabled_for
- and creative.is_enabled_for(name)
- and inv:contains_item("main", stack, true))
- then
- stack = inv:add_item("main", stack)
- if not stack:is_empty()
- then
- minetest.add_item(self.object:get_pos(), stack)
- end
- end
- remove(self)
- elseif name == '' then
- if hp <= 0 then
- local pos = self.object:get_pos()
- local objs = minetest.get_objects_inside_radius(pos, 3)
- for _, obj in pairs(objs) do
- if obj:is_player() then
- local name = obj:get_player_name()
- obj:set_detach()
- self.driver = nil
- if player_api
- then
- player_api.player_attached[name] = nil
- end
- end
- end
- end
- end
- end
- end
- local sail =
- {
- initial_properties =
- {
- physical = false,
- visual = "mesh",
- mesh = "sailing_canoe_sail.obj",
- static_save = false,
- }
- }
- local flag =
- {
- initial_properties =
- {
- physical = false,
- visual = "mesh",
- mesh = "sailing_canoe_flag.obj",
- static_save = false,
- visual_size = {x = 0.1, y = 0.1, z = 0.1},
- }
- }
- local function attachment_on_step(self)
- if not self.object:get_attach()
- then
- self.object:remove()
- end
- end
- sail.on_step = attachment_on_step
- flag.on_step = attachment_on_step
- minetest.register_entity("sailing_canoe:canoe", canoe)
- minetest.register_entity("sailing_canoe:sail", sail)
- minetest.register_entity("sailing_canoe:flag", flag)
|