diff --git a/data/sql/updates/pending_db_world/rev_1731654149568045673.sql b/data/sql/updates/pending_db_world/rev_1731654149568045673.sql new file mode 100644 index 000000000..a44364270 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1731654149568045673.sql @@ -0,0 +1,6 @@ +-- +-- SMART_EVENT_IS_IN_MELEE_RANGE invert, SMARTCAST_TRIGGERED, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST +UPDATE `smart_scripts` SET `event_type` = 110, `event_param1` = 0, `event_param3` = 3000, `event_param4` = 3500, `event_param6` = 1, `action_param2` = (`action_param2` | 0x2 | 0x40), `action_param3` = (`action_param3` | 0x4), `comment` = 'Irespeaker - On Not In Melee Range - Cast \'Fel Fireball\'' WHERE (`entryorguid` = 24999) AND (`source_type` = 0) AND (`id` = 0); + +-- SMART_EVENT_IS_IN_MELEE_RANGE, SMARTCAST_TRIGGERED TRIGGERED_IGNORE_POWER_AND_REAGENT_COST +UPDATE `smart_scripts` SET `event_type` = 110, `action_param2` = (`action_param2` | 0x2), `action_param3` = (`action_param3` | 0x4), `comment` = 'Irespeaker - On In Melee Range - Cast \'Fel Consumption\'' WHERE (`entryorguid` = 24999) AND (`source_type` = 0) AND (`id` = 1); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index f2c8412c3..122c640d0 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -4231,6 +4231,18 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, victim); } + break; + } + case SMART_EVENT_IS_IN_MELEE_RANGE: + { + if (!me) + return; + + if (Unit* victim = me->GetVictim()) + if ((!e.event.meleeRange.invert && me->IsWithinMeleeRange(victim, static_cast(e.event.meleeRange.dist))) || + (e.event.meleeRange.invert && !me->IsWithinMeleeRange(victim, static_cast(e.event.meleeRange.dist)))) + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, victim); + break; } case SMART_EVENT_RECEIVE_EMOTE: @@ -4793,6 +4805,7 @@ void SmartScript::InitTimer(SmartScriptHolder& e) case SMART_EVENT_AREA_CASTING: case SMART_EVENT_IS_BEHIND_TARGET: case SMART_EVENT_FRIENDLY_HEALTH_PCT: + case SMART_EVENT_IS_IN_MELEE_RANGE: RecalcTimer(e, e.event.minMaxRepeat.min, e.event.minMaxRepeat.max); break; case SMART_EVENT_DISTANCE_CREATURE: @@ -4878,6 +4891,7 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff) case SMART_EVENT_FRIENDLY_HEALTH_PCT: case SMART_EVENT_DISTANCE_CREATURE: case SMART_EVENT_DISTANCE_GAMEOBJECT: + case SMART_EVENT_IS_IN_MELEE_RANGE: { ASSERT(executionStack.empty()); executionStack.emplace_back(SmartScriptFrame{ e, nullptr, 0, 0, false, nullptr, nullptr }); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index b309f4696..44c85241d 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -268,6 +268,7 @@ void SmartAIMgr::LoadSmartAIFromDB() case SMART_EVENT_AREA_RANGE: case SMART_EVENT_AREA_CASTING: case SMART_EVENT_IS_BEHIND_TARGET: + case SMART_EVENT_IS_IN_MELEE_RANGE: if (temp.event.minMaxRepeat.repeatMin == 0 && temp.event.minMaxRepeat.repeatMax == 0) temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; break; @@ -347,6 +348,7 @@ void SmartAIMgr::LoadSmartAIFromDB() case SMART_EVENT_NEAR_PLAYERS: case SMART_EVENT_SUMMONED_UNIT_EVADE: case SMART_EVENT_DATA_SET: + case SMART_EVENT_IS_IN_MELEE_RANGE: return true; default: return false; @@ -553,6 +555,7 @@ bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e) case SMART_EVENT_FOLLOW_COMPLETED: return NO_PARAMS; case SMART_EVENT_EVENT_PHASE_CHANGE: return sizeof(SmartEvent::eventPhaseChange); case SMART_EVENT_IS_BEHIND_TARGET: return sizeof(SmartEvent::minMaxRepeat); + case SMART_EVENT_IS_IN_MELEE_RANGE: return sizeof(SmartEvent::meleeRange); case SMART_EVENT_GAME_EVENT_START: return sizeof(SmartEvent::gameEvent); case SMART_EVENT_GAME_EVENT_END: return sizeof(SmartEvent::gameEvent); case SMART_EVENT_GO_STATE_CHANGED: return sizeof(SmartEvent::goStateChanged); @@ -964,6 +967,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_EVENT_AREA_CASTING: case SMART_EVENT_IS_BEHIND_TARGET: case SMART_EVENT_RANGE: + case SMART_EVENT_IS_IN_MELEE_RANGE: if (!IsMinMaxValid(e, e.event.minMaxRepeat.min, e.event.minMaxRepeat.max)) return false; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index fcf631446..be8508e6b 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -215,8 +215,9 @@ enum SMART_EVENT SMART_EVENT_SUMMONED_UNIT_EVADE = 107, // CreatureId(0 all), CooldownMin, CooldownMax SMART_EVENT_WAYPOINT_DATA_REACHED = 108, // PointId (0: any), pathId (0: any) SMART_EVENT_WAYPOINT_DATA_ENDED = 109, // PointId (0: any), pathId (0: any) + SMART_EVENT_IS_IN_MELEE_RANGE = 110, // min, max, repeatMin, repeatMax, dist, invert (0: false, 1: true) - SMART_EVENT_AC_END = 110 + SMART_EVENT_AC_END = 111 }; struct SmartEvent @@ -499,6 +500,16 @@ struct SmartEvent uint32 timer; } nearUnit; + struct + { + uint32 min; + uint32 max; + uint32 repeatMin; + uint32 repeatMax; + uint32 dist; + uint32 invert; + } meleeRange; + struct { uint32 type; @@ -1890,6 +1901,7 @@ const uint32 SmartAIEventMask[SMART_EVENT_AC_END][2] = {SMART_EVENT_SUMMONED_UNIT_EVADE, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_WAYPOINT_DATA_REACHED, SMART_SCRIPT_TYPE_MASK_CREATURE }, {SMART_EVENT_WAYPOINT_DATA_ENDED, SMART_SCRIPT_TYPE_MASK_CREATURE }, + {SMART_EVENT_IS_IN_MELEE_RANGE, SMART_SCRIPT_TYPE_MASK_CREATURE }, }; enum SmartEventFlags