Core/SmartScripts: added SMART_ACTION_SET_COUNTER and SMART_EVENT_COUNTER_SET

as per request of DB developers

(cherry picked from commit 23b1c042ad)

Conflicts:
	src/server/game/AI/SmartScripts/SmartScript.h
This commit is contained in:
MitchesD
2015-04-02 18:02:34 +02:00
parent d8ef63040a
commit 1de02764c7
4 changed files with 92 additions and 3 deletions

View File

@@ -60,6 +60,7 @@ SmartScript::~SmartScript()
delete itr->second;
delete mTargetStorage;
mCounterList.clear();
}
void SmartScript::OnReset()
@@ -76,6 +77,7 @@ void SmartScript::OnReset()
}
ProcessEventsFor(SMART_EVENT_RESET);
mLastInvoker.Clear();
mCounterList.clear();
}
void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
@@ -1317,6 +1319,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
ENSURE_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim != 0);
break;
}
case SMART_ACTION_SET_COUNTER:
{
StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset);
break;
}
case SMART_ACTION_WP_START:
{
if (!IsSmart())
@@ -3206,6 +3213,10 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
break;
}
case SMART_EVENT_COUNTER_SET:
if (GetCounterId(e.event.counter.id) != 0 && GetCounterValue(e.event.counter.id) == e.event.counter.value)
ProcessTimedAction(e, e.event.counter.cooldownMax, e.event.counter.cooldownMax);
break;
default:
TC_LOG_ERROR("sql.sql", "SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType());
break;

View File

@@ -145,8 +145,37 @@ class SmartScript
return NULL;
}
GameObject* FindGameObjectNear(WorldObject* searchObject, uint32 guid) const
void StoreCounter(uint32 id, uint32 value, uint32 reset)
{
CounterMap::const_iterator itr = mCounterList.find(id);
if (itr != mCounterList.end())
{
if (reset == 0)
value += GetCounterValue(id);
mCounterList.erase(id);
}
mCounterList.insert(std::make_pair(id, value));
ProcessEventsFor(SMART_EVENT_COUNTER_SET);
}
uint32 GetCounterId(uint32 id)
{
CounterMap::iterator itr = mCounterList.find(id);
if (itr != mCounterList.end())
return itr->first;
return 0;
}
uint32 GetCounterValue(uint32 id)
{
CounterMap::iterator itr = mCounterList.find(id);
if (itr != mCounterList.end())
return itr->second;
return 0;
}
GameObject* FindGameObjectNear(WorldObject* searchObject, ObjectGuid::LowType guid) const {
GameObject* gameObject = NULL;
CellCoord p(Trinity::ComputeCellCoord(searchObject->GetPositionX(), searchObject->GetPositionY()));
@@ -205,6 +234,8 @@ class SmartScript
void SetScript9(SmartScriptHolder& e, uint32 entry);
Unit* GetLastInvoker();
ObjectGuid mLastInvoker;
typedef std::unordered_map<uint32, uint32> CounterMap;
CounterMap mCounterList;
private:
void IncPhase(int32 p = 1)

View File

@@ -689,6 +689,22 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
}
break;
case SMART_EVENT_COUNTER_SET:
if (!IsMinMaxValid(e, e.event.counter.cooldownMin, e.event.counter.cooldownMax))
return false;
if (e.event.counter.id == 0)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Event SMART_EVENT_COUNTER_SET using invalid counter id %u, skipped.", e.event.counter.id);
return false;
}
if (e.event.counter.value == 0)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Event SMART_EVENT_COUNTER_SET using invalid value %u, skipped.", e.event.counter.value);
return false;
}
break;
case SMART_EVENT_LINK:
case SMART_EVENT_GO_STATE_CHANGED:
case SMART_EVENT_GO_EVENT_INFORM:
@@ -991,6 +1007,20 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Map entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.teleport.mapID);
return false;
}
break;
case SMART_ACTION_SET_COUNTER:
if (e.action.setCounter.counterId == 0)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses wrong counterId %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.setCounter.counterId);
return false;
}
if (e.action.setCounter.value == 0)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses wrong value %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.setCounter.value);
return false;
}
break;
case SMART_ACTION_INSTALL_AI_TEMPLATE:
if (e.action.installTtemplate.id >= SMARTAI_TEMPLATE_END)

View File

@@ -167,8 +167,9 @@ enum SMART_EVENT
SMART_EVENT_FRIENDLY_HEALTH_PCT = 74, // minHpPct, maxHpPct, repeatMin, repeatMax
SMART_EVENT_DISTANCE_CREATURE = 75, // guid, entry, distance, repeat
SMART_EVENT_DISTANCE_GAMEOBJECT = 76, // guid, entry, distance, repeat
SMART_EVENT_COUNTER_SET = 77, // id, value, cooldownMin, cooldownMax
SMART_EVENT_END = 77
SMART_EVENT_END = 78
};
struct SmartEvent
@@ -396,6 +397,14 @@ struct SmartEvent
uint32 repeat;
} distance;
struct
{
uint32 id;
uint32 value;
uint32 cooldownMin;
uint32 cooldownMax;
} counter;
struct
{
uint32 param1;
@@ -479,7 +488,7 @@ enum SMART_ACTION
SMART_ACTION_SET_FLY = 60, // 0/1
SMART_ACTION_SET_SWIM = 61, // 0/1
SMART_ACTION_TELEPORT = 62, // mapID,
// 63 unused
SMART_ACTION_SET_COUNTER = 63, // id, value, reset (0/1)
SMART_ACTION_STORE_TARGET_LIST = 64, // varID,
SMART_ACTION_WP_RESUME = 65, // none
SMART_ACTION_SET_ORIENTATION = 66, //
@@ -822,6 +831,13 @@ struct SmartAction
uint32 mapID;
} teleport;
struct
{
uint32 counterId;
uint32 value;
uint32 reset;
} setCounter;
struct
{
uint32 id;
@@ -1294,6 +1310,7 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] =
{SMART_EVENT_FRIENDLY_HEALTH_PCT, SMART_SCRIPT_TYPE_MASK_CREATURE },
{SMART_EVENT_DISTANCE_CREATURE, SMART_SCRIPT_TYPE_MASK_CREATURE },
{SMART_EVENT_DISTANCE_GAMEOBJECT, SMART_SCRIPT_TYPE_MASK_CREATURE },
{SMART_EVENT_COUNTER_SET, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }
};
enum SmartEventFlags