1-- =====================================================
2-- BOAT NAVIGATION SYSTEM
3-- AID 40000 = Embark (dock tile -> water)
4-- AID 40001 = Disembark (water tile -> dock)
5-- =====================================================
6
7-- Helper: apply boat outfit and store original
8local function applyBoatOutfit(player, item, position, fromPosition)
9 local playerOutfit = player:getOutfit()
10
11 -- Store current outfit
12 player:setStorageValue(709919, playerOutfit.lookType)
13 player:setStorageValue(709920, playerOutfit.lookAddons)
14 player:setStorageValue(709921, playerOutfit.lookWings or 0)
15 player:setStorageValue(709922, playerOutfit.lookAura or 0)
16 player:setStorageValue(709923, playerOutfit.lookShader or 0)
17
18 -- Check equipped ship using the custom inventory storage system
19 -- _SYSTEM.INVENTARIO[07] = RING slot, UID_01 = storage 1061
20 local shipId = player:getStorageValue(_SYSTEM.INVENTARIO[07].UID_01)
21
22 local boatLookType = 0
23 if shipId == 42430 then boatLookType = 9017
24 elseif shipId == 42431 then boatLookType = 9018
25 elseif shipId == 42432 then boatLookType = 9019
26 elseif shipId == 42433 then boatLookType = 9541
27 elseif shipId == 42434 then boatLookType = 9542
28 elseif shipId == 42435 then boatLookType = 9543
29 elseif shipId == 42436 then boatLookType = 9544
30 end
31
32 if boatLookType > 0 then
33 playerOutfit.lookType = boatLookType
34 playerOutfit.lookAddons = 0
35 playerOutfit.lookWings = 0
36 playerOutfit.lookAura = 0
37 playerOutfit.lookShader = 0
38 player:setOutfit(playerOutfit)
39 return true
40 end
41
42 return false
43end
44
45-- Helper: restore original outfit
46local function restoreOutfit(player)
47 local storedLookType = player:getStorageValue(709919)
48 local storedLookAddons = player:getStorageValue(709920)
49 local storedLookWings = player:getStorageValue(709921)
50 local storedLookAura = player:getStorageValue(709922)
51 local storedLookShader = player:getStorageValue(709923)
52
53 if storedLookType > 0 then
54 local playerOutfit = player:getOutfit()
55 playerOutfit.lookType = storedLookType
56 playerOutfit.lookAddons = storedLookAddons
57 playerOutfit.lookWings = storedLookWings
58 playerOutfit.lookAura = storedLookAura
59 playerOutfit.lookShader = storedLookShader
60 player:setOutfit(playerOutfit)
61 end
62end
63
64-- =====================================================
65-- TELEPORT EVENT (AID 40000 = embark / AID 40001 = disembark)
66-- =====================================================
67local boatTeleport = MoveEvent()
68
69function boatTeleport.onStepIn(creature, item, position, fromPosition)
70 local player = creature:getPlayer()
71 if not player then
72 return true
73 end
74
75 local actionId = item:getActionId()
76
77 -- Prevent trigger if player was already on a tile with the same AID
78 -- (avoids loop when teleporting onto another AID tile)
79 local fromTile = Tile(fromPosition)
80 if fromTile then
81 local items = fromTile:getItems()
82 if items then
83 for _, i in ipairs(items) do
84 if i:getActionId() == actionId then
85 return true
86 end
87 end
88 end
89 end
90
91 -- Calculate movement direction (1 step = 1 tile difference)
92 local diffX = position.x - fromPosition.x
93 local diffY = position.y - fromPosition.y
94
95 if diffX == 0 and diffY == 0 then
96 return true
97 end
98
99 -- Project destination 4 tiles ahead in walking direction
100 local targetPos = Position(
101 position.x + (diffX * 4),
102 position.y + (diffY * 4),
103 position.z
104 )
105
106 if actionId == 40000 then
107 -- EMBARK: verify boat equipped, apply outfit, teleport to water (Z+1)
108 if not applyBoatOutfit(player, item, position, fromPosition) then
109 player:teleportTo(fromPosition, true)
110 player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
111 player:say("You need to equip a boat in your ring slot to sail.", TALKTYPE_MONSTER_SAY)
112 return false
113 end
114
115 targetPos.z = position.z + 1
116 player:teleportTo(targetPos)
117 targetPos:sendMagicEffect(CONST_ME_TELEPORT)
118
119 elseif actionId == 40001 then
120 -- DISEMBARK: restore outfit and teleport to dock (Z-1)
121 restoreOutfit(player)
122 targetPos.z = position.z - 1
123 player:teleportTo(targetPos)
124 targetPos:sendMagicEffect(CONST_ME_TELEPORT)
125 end
126
127 return true
128end
129
130boatTeleport:aid(40000, 40001)
131boatTeleport:register()
132