From 6a410efa3622ee522cacfb68a26c3d56d1604605 Mon Sep 17 00:00:00 2001 From: P-Kito Date: Fri, 17 Apr 2020 00:40:06 +0200 Subject: [PATCH] feat(Core/AI): CU_SAI - Custom Event Options (#2881) --- .../game/AI/SmartScripts/SmartScript.cpp | 36 +++++++++++- .../game/AI/SmartScripts/SmartScriptMgr.cpp | 4 +- .../game/AI/SmartScripts/SmartScriptMgr.h | 55 ++++++++++++++++++- 3 files changed, 90 insertions(+), 5 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 83dfb39a5..311bb57e7 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -4300,6 +4300,34 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui ProcessTimedAction(e, e.event.counter.cooldownMin, e.event.counter.cooldownMax); break; + case SMART_EVENT_NEAR_PLAYERS: + { + float range = (float)e.event.nearPlayer.radius; + ObjectList* units = GetWorldObjectsInDist(range); + if (!units->empty()) + { + units->remove_if([](WorldObject* unit) { return unit->GetTypeId() != TYPEID_PLAYER; }); + + if (units->size() >= e.event.nearPlayer.minCount) + ProcessAction(e, unit); + } + RecalcTimer(e, e.event.nearPlayer.checkTimer, e.event.nearPlayer.checkTimer); + break; + } + case SMART_EVENT_NEAR_PLAYERS_NEGATION: + { + float range = (float)e.event.nearPlayerNegation.radius; + ObjectList* units = GetWorldObjectsInDist(range); + if (!units->empty()) + { + units->remove_if([](WorldObject* unit) { return unit->GetTypeId() != TYPEID_PLAYER; }); + + if (units->size() < e.event.nearPlayerNegation.minCount) + ProcessAction(e, unit); + } + RecalcTimer(e, e.event.nearPlayerNegation.checkTimer, e.event.nearPlayerNegation.checkTimer); + break; + } default: sLog->outErrorDb("SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType()); break; @@ -4310,7 +4338,11 @@ void SmartScript::InitTimer(SmartScriptHolder& e) { switch (e.GetEventType()) { - //set only events which have initial timers + //set only events which have initial timers + case SMART_EVENT_NEAR_PLAYERS: + case SMART_EVENT_NEAR_PLAYERS_NEGATION: + RecalcTimer(e, e.event.nearPlayer.firstTimer, e.event.nearPlayer.firstTimer); + break; case SMART_EVENT_UPDATE: case SMART_EVENT_UPDATE_IC: case SMART_EVENT_UPDATE_OOC: @@ -4369,6 +4401,8 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff) e.active = true;//activate events with cooldown switch (e.GetEventType())//process ONLY timed events { + case SMART_EVENT_NEAR_PLAYERS: + case SMART_EVENT_NEAR_PLAYERS_NEGATION: case SMART_EVENT_UPDATE: case SMART_EVENT_UPDATE_OOC: case SMART_EVENT_UPDATE_IC: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 7cb5a4310..4ee2abe6d 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -354,7 +354,7 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) { - if (e.event.type >= SMART_EVENT_END) + if ((e.event.type >= SMART_EVENT_TC_END && e.event.type <= SMART_EVENT_AC_START) || e.event.type >= SMART_EVENT_AC_END) { sLog->outErrorDb("SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetEventType()); return false; @@ -716,6 +716,8 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) break; case SMART_EVENT_GO_STATE_CHANGED: case SMART_EVENT_GO_EVENT_INFORM: + case SMART_EVENT_NEAR_PLAYERS: + case SMART_EVENT_NEAR_PLAYERS_NEGATION: case SMART_EVENT_TIMED_EVENT_TRIGGERED: case SMART_EVENT_INSTANCE_PLAYER_ENTER: case SMART_EVENT_TRANSPORT_RELOCATE: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 7dd060775..08b1e31b3 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -167,7 +167,15 @@ enum SMART_EVENT SMART_EVENT_DISTANCE_GAMEOBJECT = 76, // guid, entry, distance, repeat SMART_EVENT_COUNTER_SET = 77, // id, value, cooldownMin, cooldownMax - SMART_EVENT_END = 78 + SMART_EVENT_TC_END = 78, + + /* AC Custom Events */ + SMART_EVENT_AC_START = 100, + + SMART_EVENT_NEAR_PLAYERS = 101, // min, radius, first timer, check timer + SMART_EVENT_NEAR_PLAYERS_NEGATION = 102, // min, radius, first timer, check timer + + SMART_EVENT_AC_END = 103 }; struct SmartEvent @@ -409,6 +417,22 @@ struct SmartEvent uint32 cooldownMax; } counter; + struct + { + uint32 minCount; + uint32 radius; + uint32 firstTimer; + uint32 checkTimer; + } nearPlayer; + + struct + { + uint32 minCount; + uint32 radius; + uint32 firstTimer; + uint32 checkTimer; + } nearPlayerNegation; + struct { uint32 param1; @@ -1466,7 +1490,7 @@ const uint32 SmartAITypeMask[SMART_SCRIPT_TYPE_MAX][2] = {SMART_SCRIPT_TYPE_TIMED_ACTIONLIST, SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST } }; -const uint32 SmartAIEventMask[SMART_EVENT_END][2] = +const uint32 SmartAIEventMask[SMART_EVENT_AC_END][2] = { {SMART_EVENT_UPDATE_IC, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST}, {SMART_EVENT_UPDATE_OOC, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT + SMART_SCRIPT_TYPE_MASK_INSTANCE }, @@ -1545,7 +1569,32 @@ 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 } + {SMART_EVENT_COUNTER_SET, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, + { 0, 0 }, // 78 + { 0, 0 }, // 79 + { 0, 0 }, // 80 + { 0, 0 }, // 81 + { 0, 0 }, // 82 + { 0, 0 }, // 83 + { 0, 0 }, // 84 + { 0, 0 }, // 85 + { 0, 0 }, // 86 + { 0, 0 }, // 87 + { 0, 0 }, // 88 + { 0, 0 }, // 89 + { 0, 0 }, // 90 + { 0, 0 }, // 91 + { 0, 0 }, // 92 + { 0, 0 }, // 93 + { 0, 0 }, // 94 + { 0, 0 }, // 95 + { 0, 0 }, // 96 + { 0, 0 }, // 97 + { 0, 0 }, // 98 + { 0, 0 }, // 99 + { 0, 0 }, // 100 + {SMART_EVENT_NEAR_PLAYERS, SMART_SCRIPT_TYPE_MASK_CREATURE }, + {SMART_EVENT_NEAR_PLAYERS_NEGATION, SMART_SCRIPT_TYPE_MASK_CREATURE } }; enum SmartEventFlags