void UnitStateMgr::DropAction(UnitActionPriority priority) { // Don't remove action with NONE priority - static if (priority < UNIT_ACTION_PRIORITY_IDLE) return; UnitActionStorage::iterator itr = m_actions.find(priority); if (itr != m_actions.end()) { bool bActiveActionChanged = false; ActionInfo* oldInfo = CurrentState(); UnitActionPtr oldAction = oldInfo ? oldInfo->Action() : UnitActionPtr(); // if dropped current active state... if (oldInfo && itr->second.Action() == oldInfo->Action() && !oldInfo->HasFlag(ACTION_STATE_FINALIZED)) bActiveActionChanged = true; // in first - erasing current action, if his active if (itr->second.Action() == m_oldAction) m_oldAction = UnitActionPtr(NULL); // Possible erasing by iterator more fast and logic, but by Key much more safe m_actions.erase(priority); // Finalized not ActionInfo, but real action (saved before), due to ActionInfo wrapper already deleted. if (bActiveActionChanged && oldAction) { DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "DropAction: %s finalize (direct) action %s", GetOwnerStr().c_str(), oldAction->Name()); oldAction->Finalize(*GetOwner()); } // in this point we delete last link to UnitActionPtr, after this UnitAction be auto-deleted... } }
void UnitStateMgr::PushAction(UnitActionId actionId, UnitActionPtr state, UnitActionPriority priority, eActionType restoreable) { ActionInfo* oldInfo = CurrentState(); UnitActionPriority _priority = oldInfo ? oldInfo->priority : UNIT_ACTION_PRIORITY_IDLE; // Only interrupt action, if not drop his below and action lower by priority if (oldInfo && oldInfo->HasFlag(ACTION_STATE_ACTIVE) && oldInfo->Id != actionId && _priority < priority) oldInfo->Interrupt(this); if (_priority > UNIT_ACTION_PRIORITY_IDLE) { // Some speedup - testing - not need drop Idle/None actions DropAction(actionId, priority); DropAction(priority); } bool needInsert = true; if (restoreable != ACTION_TYPE_NONRESTOREABLE) { // Don't replace (only interrupt and reset!) restoreable actions UnitActionStorage::iterator itr = m_actions.find(priority); if (itr != m_actions.end()) { if (itr->second.Id == actionId) { itr->second.Reset(this); needInsert = false; } } } if (needInsert) m_actions.insert(UnitActionStorage::value_type(priority,ActionInfo(actionId, state, priority, restoreable))); IncreaseCounter(actionId); /* ActionInfo* newInfo = CurrentState(); if (newInfo && newInfo != oldInfo) { if (!newInfo->HasFlag(ACTION_STATE_INITIALIZED)) newInfo->Initialize(this); } */ }