Just developped this for my dungeon and though it could be useful to others.
The new onEquipItem and onUnequipItem hooks do not unfortunately have a "return false" option which would prevent the player from putting the item in or removing the item from an inventory slot. So here's my solution:
1. Put this in a script entity named equipStopper:
Code: Select all
-- Diarmuid's Equip/Unequip Stopper
-- v1.0
timersTable = {}
function stopEquip(champion, slot)
-- Remove item
champion:removeItem(slot)
-- Call delay function
item = getMouseItem()
createDelayTimer(item.name, item.id, champion:getOrdinal(), slot, "equip")
end
function stopUnequip(champion, slot)
-- Remove item
setMouseItem(nil)
-- Call delay function
item = champion:getItem(slot)
createDelayTimer(item.name, item.id, champion:getOrdinal(), slot, "unequip")
end
function createDelayTimer(itemName, itemId, championOrdinal, slot, type)
-- Create Timer
local timerId = itemId..".delay"
if findEntity(timerId) ~= nil then
findEntity(timerId):destroy()
end
local delayTimer = spawn("timer", party.level, party.x, party.y, 0, timerId)
delayTimer:addConnector('activate', 'equipStopper', 'timerCallback')
delayTimer:setTimerInterval(0.01)
delayTimer:activate()
-- Pack timer callback arguments
timersTable[timerId] = {}
timersTable[timerId].itemName = itemName
timersTable[timerId].itemId = itemId
timersTable[timerId].championOrdinal = championOrdinal
timersTable[timerId].slot = slot
timersTable[timerId].type = type
end
function timerCallback(self)
-- Unpack timer callback arguments
timerId = self.id
itemName = timersTable[timerId].itemName
itemId = timersTable[timerId].itemId
championOrdinal = timersTable[timerId].championOrdinal
slot = timersTable[timerId].slot
type = timersTable[timerId].type
-- Numerical Id renamer by jKos
if (itemId and string.find(itemId, "^%d+$")) then
itemId = nil
end
-- Respawn item
if type == "equip" then
setMouseItem(spawn(itemName, nil, nil, nil, nil, itemId))
elseif type == "unequip" then
local champion
for i = 1,4 do
if party:getChampion(i):getOrdinal() == championOrdinal then
champion = party:getChampion(i)
end
end
champion:insertItem(slot,spawn(itemName, nil, nil, nil, nil, itemId))
end
-- Destroy timer
self:destroy()
end
- equipStopper.stopEquip(champion, slot)
- equipStopper.stopUnequip(champion, slot)
How it works:
- This code first removes the item from the slot/mouse it was put it (equivalent to :destroy(), the item doesn't exist anymore).
- Then it respawns the item in its original place 0.01s later, giving the illusion that the item was never moved. This can for example prevent a champion from equipping a Sword of Chivalry until annointed knight by a King, or prevent putting a torch in hand in a darkness zone, or putting a magical stone in a fighter or rogue inventory, or whatever you can think of. EDIT: Or create cursed items, thanks Neikun.
The delay is crucial, as the game seems to remove the item after the hook has finished executing. So if you put the item back right away, it gets deleted.
Example, using Balthasar's test object:
Code: Select all
cloneObject{
name = "curse_cap",
baseObject = "peasant_cap",
uiName = "Cursed Hat",
onUnequipItem = function(champion, slot)
if slot == 1 then
hudPrint("This hat is cursed!")
equipStopper.stopUnequip(champion, slot)
end
end
}