doors.lua

main 119 lines · 3.9 KB Raw
Alex Alex Commit Server upload 18/10/2026 23:38
1local positionOffsets = {
2 Position(1, 0, 0), -- east
3 Position(0, 1, 0), -- south
4 Position(-1, 0, 0), -- west
5 Position(0, -1, 0) -- north
6}
7
8--[[
9When closing a door with a creature in it findPushPosition will find the most appropriate
10adjacent position following a prioritization order.
11The function returns the position of the first tile that fulfills all the checks in a round.
12The function loops trough east -> south -> west -> north on each following line in that order.
13In round 1 it checks if there's an unhindered walkable tile without any creature.
14In round 2 it checks if there's a tile with a creature.
15In round 3 it checks if there's a tile blocked by a movable tile-blocking item.
16In round 4 it checks if there's a tile blocked by a magic wall or wild growth.
17]]
18local function findPushPosition(creature, round)
19 local pos = creature:getPosition()
20 for _, offset in ipairs(positionOffsets) do
21 local offsetPosition = pos + offset
22 local tile = Tile(offsetPosition)
23 if tile then
24 local creatureCount = tile:getCreatureCount()
25 if round == 1 then
26 if tile:queryAdd(creature) == RETURNVALUE_NOERROR and creatureCount == 0 then
27 if not tile:hasFlag(TILESTATE_PROTECTIONZONE) or (tile:hasFlag(TILESTATE_PROTECTIONZONE) and creature:canAccessPz()) then
28 return offsetPosition
29 end
30 end
31 elseif round == 2 then
32 if creatureCount > 0 then
33 if not tile:hasFlag(TILESTATE_PROTECTIONZONE) or (tile:hasFlag(TILESTATE_PROTECTIONZONE) and creature:canAccessPz()) then
34 return offsetPosition
35 end
36 end
37 elseif round == 3 then
38 local topItem = tile:getTopDownItem()
39 if topItem then
40 if topItem:getType():isMovable() then
41 return offsetPosition
42 end
43 end
44 else
45 if tile:getItemById(ITEM_MAGICWALL) or tile:getItemById(ITEM_WILDGROWTH) then
46 return offsetPosition
47 end
48 end
49 end
50 end
51 if round < 4 then
52 return findPushPosition(creature, round + 1)
53 end
54end
55
56function onUse(player, item, fromPosition, target, toPosition, isHotkey)
57 local itemId = item:getId()
58 if table.contains(questDoors, itemId) then
59 if player:getStorageValue(item.actionid) ~= -1 then
60 item:transform(itemId + 1)
61 player:teleportTo(toPosition, true)
62 else
63 player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door seems to be sealed against unwanted intruders.")
64 end
65 return true
66 elseif table.contains(levelDoors, itemId) then
67 if item.actionid > 0 and player:getLevel() >= item.actionid - actionIds.levelDoor then
68 item:transform(itemId + 1)
69 player:teleportTo(toPosition, true)
70 else
71 player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only the worthy may pass.")
72 end
73 return true
74 elseif table.contains(keys, itemId) then
75 if target.actionid > 0 then
76 if item.actionid == target.actionid and doors[target.itemid] then
77 target:transform(doors[target.itemid])
78 return true
79 end
80 player:sendTextMessage(MESSAGE_STATUS_SMALL, "The key does not match.")
81 return true
82 end
83 return false
84 end
85
86 if table.contains(horizontalOpenDoors, itemId) or table.contains(verticalOpenDoors, itemId) then
87 local creaturePositionTable = {}
88 local doorCreatures = Tile(toPosition):getCreatures()
89 if doorCreatures and #doorCreatures > 0 then
90 for _, doorCreature in pairs(doorCreatures) do
91 local pushPosition = findPushPosition(doorCreature, 1)
92 if not pushPosition then
93 player:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM)
94 return true
95 end
96 table.insert(creaturePositionTable, {creature = doorCreature, position = pushPosition})
97 end
98 for _, tableCreature in ipairs(creaturePositionTable) do
99 tableCreature.creature:teleportTo(tableCreature.position, true)
100 end
101 end
102
103 if not table.contains(openSpecialDoors, itemId) then
104 item:transform(itemId - 1)
105 end
106 return true
107 end
108
109 if doors[itemId] then
110 if item.actionid == 0 then
111 item:transform(doors[itemId])
112 else
113 player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is locked.")
114 end
115 return true
116 end
117 return false
118end
119
Top