stuck1a Posted December 4, 2022 Share Posted December 4, 2022 (edited) Hey there. I'm just struggling a bit with my "construction site tile". I use tryBuild() of a derviced ISBaseObject to place it as special tile object at the very beginning of the build process. Of course, it shall disappear whenever any action of the action queue becomes interrupted however. Unfortunately, I could not find a way to transfer appropriate callbacks, so I've decived to derive all TimedAction which might occur and add an additional call for the tile removal check in their stop() functions. Not elegant, but workes. Bad luck - the faceDirection function is no TA on its own, so I've tried to hook into TimedActionQueue:tick() with no luck because of the static nature and lack of polymorphic. So for now I've set an event listener to work around the problem by calling a derived variant of queue:tick(). It works, but as you can imagine, I'm not very happy with this solution because of the high performance impact such a listener comes with. Surely I just overlooked the obvious solution, I guess a more elegant solution can be implemented with waitToStart() or the ISQueueActionsAction class, but I really can't figure it out right now. If somehow possible, I'd like to avoid replacing the whole vanilla queue class for best possible compatibility with future updates. Here the merged code for a better understanding of what I'm trying to achieve: --- Removes the construction site tile object linked to the active action item --- @param isoTile IsoObject construction site tile pointer local function removeConstructionSite(isoTile) local square = isoTile:getSquare() -- there might be several construction sites on the square, so remove only the assigned one local specialTiles = square:getSpecialObjects() for i=0, specialTiles:size()-1 do if specialTiles:get(i) == isoTile then square:transmitRemoveItemFromSquare(isoTile) square:RemoveTileObject(isoTile) isoTile = nil return end end end require 'TimedActions/ISBaseTimedAction' ---@class ISExtBuildAction : ISBuildAction ISExtBuildAction = ISBuildAction:derive('ISExtBuildAction') function ISExtBuildAction:new(character, item, x, y, z, north, spriteName, time, tool1, tool2, isoTile) local o = ISBuildAction.new(self, character, item, x, y, z, north, spriteName, time) setmetatable(o, self) self.__index = self -- [...] (shortened) o.isoTile = isoTile return o end function ISExtBuildAction:perform() -- [...] (shortened) if self.isoTile ~= nil then removeConstructionSite(self.isoTile) end ISBuildAction.perform(self) end function ISExtBuildAction:stop() ISBuildAction.stop(self) if self.isoTile ~= nil then removeConstructionSite(self.isoTile) end end -- DERVICED VARIANTS OF ALL POSSIBLY USED TA's ---@class ISExtInventoryTransferAction : ISInventoryTransferAction ISExtInventoryTransferAction = ISInventoryTransferAction:derive('ISExtInventoryTransferAction') function ISExtInventoryTransferAction:new(character, item, srcContainer, destContainer, isoTile) local o = ISInventoryTransferAction:new(character, item, srcContainer, destContainer) setmetatable(o, self) self.__index = self o.isoTile = isoTile return o end function ISExtInventoryTransferAction:stop() ISInventoryTransferAction.stop(self) if self.isoTile ~= nil then removeConstructionSite(self.isoTile) end end -- and so on.... -- NOT VERY NICE, BUT WORKS FOR NOW... ---@class ISExtTimedActionQueue : ISTimedActionQueue ISExtTimedActionQueue = ISTimedActionQueue:derive('ISExtTimedActionQueue') function ISExtTimedActionQueue:clearQueue() ISTimedActionQueue.clearQueue(self) end function ISExtTimedActionQueue:resetQueue() ISTimedActionQueue.resetQueue(self) end function ISExtTimedActionQueue:new(character) local o = ISTimedActionQueue:new(character) setmetatable(o, self) self.__index = self return o end function ISExtTimedActionQueue.getTimedActionQueue(character) local queue = ISExtTimedActionQueue.queues[character] if queue == nil then queue = ISExtTimedActionQueue:new(character) end return queue end function ISExtTimedActionQueue.add(action) if action.ignoreAction then return end if instanceof(action.character, 'IsoGameCharacter') and action.character:isAsleep() then return end local queue = ISExtTimedActionQueue.getTimedActionQueue(action.character) local current = queue.queue[1] if current and (current.Type == 'ISQueueActionsAction') and current.isAddingActions then table.insert(queue.queue, current.indexToAdd, action) current.indexToAdd = current.indexToAdd + 1 return queue end queue:addToQueue(action) return queue end function ISExtTimedActionQueue.queueActions(character, addActionsFunction, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) local action = ISQueueActionsAction:new(character, addActionsFunction, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) return ISExtTimedActionQueue.add(action) end function ISExtTimedActionQueue.hasAction(action) if action == nil then return false end local queue = ISExtTimedActionQueue.queues[action.character] if queue == nil then return false end return queue:indexOf(action) ~= -1 end function ISExtTimedActionQueue.clear(character) character:StopAllActionQueue() local queue = ISExtTimedActionQueue.getTimedActionQueue(character) queue:clearQueue() return queue end function ISExtTimedActionQueue:tick() local action = self.queue[1] if action == nil then self:clearQueue() return end if not action.character:getCharacterActions():contains(action.action) then if action.isoTile ~= nil then removeConstructionSite(action.isoTile) end self:resetQueue() return end end function ISExtTimedActionQueue.onTick() for _,queue in pairs(ISExtTimedActionQueue.queues) do queue:tick() end end Events.OnRenderTick.Add(ISExtTimedActionQueue.onTick) Edited December 8, 2022 by stuck1a marked as solved Link to comment Share on other sites More sharing options...
stuck1a Posted December 8, 2022 Author Share Posted December 8, 2022 (edited) Well, forget about that... While searching the Java classes for any custom event system I've totally overseen LuaEventManager::AddEvent() I already was surprised that it wouldn't exist, but lo and behold, there it is. And I really was about to use IsoPlayer:setVariable() to work around the RenderTick-Event Well that makes most part of the posted stuff unnecessary. Just for the sake of completeness: local function TestEventListener() print('TestEvent fired') end LuaEventManager.AddEvent('TestEvent') Events.TestEvent.Add(TestEventListener) Shame on me Edited December 8, 2022 by stuck1a Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now