require "ISBaseObject" ISTimedActionQueue = ISBaseObject:derive("ISTimedActionQueue"); ISTimedActionQueue.IDMax = 1; ISTimedActionQueue.queues = {} function ISTimedActionQueue:addToQueue (action) --[[ if isKeyDown(Keyboard.KEY_ESCAPE) then self:clearQueue() end --]] local count = #self.queue; table.insert(self.queue, action ); --self.queue[ISTimedActionQueue.IDMax] = {id = ISTimedActionQueue.IDMax, character = character, action = action}; --print("action inserted. found "..count.." items on queue."); -- none in queue, so go! if count == 0 then self.current = action; action:begin(); --print("action started."); -- ISTimedActionQueue.IDMax = ISTimedActionQueue.IDMax + 1; end end function ISTimedActionQueue:indexOf(action) for i,v in ipairs(self.queue) do if v == action then return i end end return -1 end function ISTimedActionQueue:removeFromQueue(action) local i = self:indexOf(action) if i ~= -1 then table.remove(self.queue, i) end end function ISTimedActionQueue:clearQueue() table.wipe(self.queue) end function ISTimedActionQueue:onCompleted(action) --~ print "removing completed action."; self:removeFromQueue(action) self.current = self.queue[1] if self.current then --~ print ("starting next queued action: "..i); if self.current:isValidStart() then self.current:begin() else print('bugged action, cleared queue ', self.current.Type or "???") self:resetQueue() return end end end function ISTimedActionQueue:resetQueue() --print("Clearing action queue."); table.wipe(self.queue) self.current = nil; end function ISTimedActionQueue:tick() local action = self.queue[1] if action == nil then self:clearQueue() return end if not action.character:getCharacterActions():contains(action.action) then print('bugged action, cleared queue ', action.Type or "???") self:resetQueue() return end if action.action:hasStalled() then self:onCompleted(action) return end end --************************************************************************-- --** ISTimedActionQueue:new --** --************************************************************************-- function ISTimedActionQueue:new (character) local o = {} setmetatable(o, self) self.__index = self o.character = character; o.queue = {} ISTimedActionQueue.queues[character] = o; return o end ISTimedActionQueue.getTimedActionQueue = function(character) local queue = ISTimedActionQueue.queues[character]; if queue == nil then queue = ISTimedActionQueue:new(character); end return queue; end ISTimedActionQueue.add = function(action) if action.ignoreAction then return; end if instanceof(action.character, "IsoGameCharacter") and action.character:isAsleep() then return; end local queue = ISTimedActionQueue.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 ISTimedActionQueue.addAfter = function(previousAction, action) if action.ignoreAction then return nil; end if instanceof(action.character, "IsoGameCharacter") and action.character:isAsleep() then return nil; end local queue = ISTimedActionQueue.getTimedActionQueue(action.character); local i = queue:indexOf(previousAction) if i ~= -1 then table.insert(queue.queue, i + 1, action); return queue,action; end return nil end ISTimedActionQueue.queueActions = function(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 ISTimedActionQueue.add(action) end ISTimedActionQueue.clear = function(character) --print("Stopping current action.") character:StopAllActionQueue(); --print("Clearing queue.") local queue = ISTimedActionQueue.getTimedActionQueue(character); queue:clearQueue(); return queue; end ISTimedActionQueue.hasAction = function(action) if action == nil then return false end local queue = ISTimedActionQueue.queues[action.character] if queue == nil then return false end return queue:indexOf(action) ~= -1 end local STATES = {} STATES[ClimbThroughWindowState.instance()] = true STATES[ClimbOverFenceState.instance()] = true STATES[ClimbOverWallState.instance()] = true STATES[ClimbSheetRopeState.instance()] = true STATES[ClimbDownSheetRopeState.instance()] = true STATES[CloseWindowState.instance()] = true STATES[OpenWindowState.instance()] = true ISTimedActionQueue.isPlayerDoingAction = function(playerObj) if not playerObj then return false end if playerObj:isDead() then return false end if not playerObj:getCharacterActions():isEmpty() then return true end local state = playerObj:getCurrentState() if STATES[state] then return true end return false end -- master function for stalled queues ISTimedActionQueue.onTick = function() for _,queue in pairs(ISTimedActionQueue.queues) do queue:tick() end if not getCore():getOptionTimedActionGameSpeedReset() then return end local isDoingAction = false for playerNum = 1,getNumActivePlayers() do local playerObj = getSpecificPlayer(playerNum-1) if ISTimedActionQueue.isPlayerDoingAction(playerObj) then isDoingAction = true break end end if isDoingAction then ISTimedActionQueue.shouldResetGameSpeed = true elseif ISTimedActionQueue.shouldResetGameSpeed then ISTimedActionQueue.shouldResetGameSpeed = false if UIManager.getSpeedControls() and (UIManager.getSpeedControls():getCurrentGameSpeed() > 1) then UIManager.getSpeedControls():SetCurrentGameSpeed(1) end end end Events.OnTick.Add(ISTimedActionQueue.onTick);