feat(Core/SmartScripts): Warn when an unused parameter is set in the database (#10124)

This commit is contained in:
IntelligentQuantum
2022-02-15 20:32:39 +03:30
committed by GitHub
parent 77bab657e5
commit 38a33e7ef0
4 changed files with 1538 additions and 96 deletions

View File

@@ -196,14 +196,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
if (IsCreature(*itr))
sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.simpleTalk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
else if (IsPlayer(*itr) && me)
{
Unit* templastInvoker = GetLastInvoker();
sCreatureTextMgr->SendChat(me, uint8(e.action.talk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_NEUTRAL, false, (*itr)->ToPlayer());
sCreatureTextMgr->SendChat(me, uint8(e.action.simpleTalk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_NEUTRAL, false, (*itr)->ToPlayer());
}
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction:: SMART_ACTION_SIMPLE_TALK: talker: {} ({}), textGroupId: {}",
(*itr)->GetName(), (*itr)->GetGUID().ToString(), uint8(e.action.talk.textGroupID));
(*itr)->GetName(), (*itr)->GetGUID().ToString(), uint8(e.action.simpleTalk.textGroupID));
}
delete targets;
@@ -777,9 +778,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
if (IsUnit(*itr))
{
(*itr)->ToUnit()->AddAura(e.action.cast.spell, (*itr)->ToUnit());
(*itr)->ToUnit()->AddAura(e.action.addAura.spell, (*itr)->ToUnit());
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction:: SMART_ACTION_ADD_AURA: Adding aura {} to unit {}",
e.action.cast.spell, (*itr)->GetGUID().ToString());
e.action.addAura.spell, (*itr)->GetGUID().ToString());
}
}
@@ -2166,7 +2167,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsCreature(*itr))
(*itr)->ToUnit()->SetUInt32Value(UNIT_NPC_FLAGS, e.action.unitFlag.flag);
(*itr)->ToUnit()->SetUInt32Value(UNIT_NPC_FLAGS, e.action.flag.flag);
delete targets;
break;
@@ -2179,7 +2180,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsCreature(*itr))
(*itr)->ToUnit()->SetFlag(UNIT_NPC_FLAGS, e.action.unitFlag.flag);
(*itr)->ToUnit()->SetFlag(UNIT_NPC_FLAGS, e.action.flag.flag);
delete targets;
break;
@@ -2192,7 +2193,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsCreature(*itr))
(*itr)->ToUnit()->RemoveFlag(UNIT_NPC_FLAGS, e.action.unitFlag.flag);
(*itr)->ToUnit()->RemoveFlag(UNIT_NPC_FLAGS, e.action.flag.flag);
delete targets;
break;
@@ -2295,7 +2296,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST:
{
uint32 id = urand(e.action.randTimedActionList.entry1, e.action.randTimedActionList.entry2);
uint32 id = urand(e.action.randRangeTimedActionList.idMin, e.action.randRangeTimedActionList.idMax);
if (e.GetTargetType() == SMART_TARGET_NONE)
{
LOG_ERROR("sql.sql", "SmartScript: Entry {} SourceType {} Event {} Action {} is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
@@ -2427,7 +2428,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
(*itr)->ToUnit()->SetUInt32Value(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag);
(*itr)->ToUnit()->SetUInt32Value(UNIT_DYNAMIC_FLAGS, e.action.flag.flag);
delete targets;
break;
@@ -2440,7 +2441,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
(*itr)->ToUnit()->SetFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag);
(*itr)->ToUnit()->SetFlag(UNIT_DYNAMIC_FLAGS, e.action.flag.flag);
delete targets;
break;
@@ -2453,7 +2454,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
(*itr)->ToUnit()->RemoveFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag);
(*itr)->ToUnit()->RemoveFlag(UNIT_DYNAMIC_FLAGS, e.action.flag.flag);
delete targets;
break;
@@ -2941,7 +2942,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
me->AddThreat((*itr)->ToUnit(), (float)e.action.threatPCT.threatINC - (float)e.action.threatPCT.threatDEC);
me->AddThreat((*itr)->ToUnit(), (float)e.action.threat.threatINC - (float)e.action.threat.threatDEC);
delete targets;
break;
@@ -3808,14 +3809,14 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
}
case SMART_TARGET_CLOSEST_CREATURE:
{
Creature* target = GetClosestCreatureWithEntry(GetBaseObject(), e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead);
Creature* target = GetClosestCreatureWithEntry(GetBaseObject(), e.target.unitClosest.entry, (float)(e.target.unitClosest.dist ? e.target.unitClosest.dist : 100), !e.target.unitClosest.dead);
if (target)
l->push_back(target);
break;
}
case SMART_TARGET_CLOSEST_GAMEOBJECT:
{
GameObject* target = GetClosestGameObjectWithEntry(GetBaseObject(), e.target.closestGameobject.entry, (float)(e.target.closestGameobject.dist ? e.target.closestGameobject.dist : 100), e.target.closestGameobject.onlySpawned);
GameObject* target = GetClosestGameObjectWithEntry(GetBaseObject(), e.target.goClosest.entry, (float)(e.target.goClosest.dist ? e.target.goClosest.dist : 100), e.target.goClosest.onlySpawned);
if (target)
l->push_back(target);
break;
@@ -3875,7 +3876,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
if (Unit* temp = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
// Xinef: added distance check
if (e.target.hostilRandom.maxDist == 0 || me->IsWithinCombatRange(temp, (float)e.target.hostilRandom.maxDist))
if (e.target.threatList.maxDist == 0 || me->IsWithinCombatRange(temp, (float)e.target.threatList.maxDist))
l->push_back(temp);
}
break;
@@ -3958,7 +3959,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (me && me->IsVehicle())
{
if (Unit* target = me->GetVehicleKit()->GetPassenger(e.target.vehicle.seat))
if (Unit* target = me->GetVehicleKit()->GetPassenger(e.target.vehicle.seatMask))
{
l->push_back(target);
}

View File

@@ -17,6 +17,7 @@
#include "SmartScriptMgr.h"
#include "CellImpl.h"
#include "CreatureTextMgr.h"
#include "DatabaseEnv.h"
#include "GameEventMgr.h"
#include "GridDefines.h"
@@ -415,9 +416,8 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
AC_SAI_IS_BOOLEAN_VALID(e, e.target.farthest.playerOnly);
AC_SAI_IS_BOOLEAN_VALID(e, e.target.farthest.isInLos);
break;
case SMART_TARGET_CLOSEST_GAMEOBJECT:
case SMART_TARGET_CLOSEST_CREATURE:
AC_SAI_IS_BOOLEAN_VALID(e, e.target.closest.dead);
AC_SAI_IS_BOOLEAN_VALID(e, e.target.unitClosest.dead);
break;
case SMART_TARGET_CLOSEST_ENEMY:
AC_SAI_IS_BOOLEAN_VALID(e, e.target.closestAttackable.playerOnly);
@@ -435,6 +435,7 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
case SMART_TARGET_LOOT_RECIPIENTS:
case SMART_EVENT_SUMMONED_UNIT_DIES:
case SMART_TARGET_PLAYER_RANGE:
case SMART_TARGET_CLOSEST_GAMEOBJECT:
case SMART_TARGET_SELF:
case SMART_TARGET_VICTIM:
case SMART_TARGET_POSITION:
@@ -445,9 +446,369 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
LOG_ERROR("sql.sql", "SmartAIMgr: Not handled target_type({}), Entry {} SourceType {} Event {} Action {}, skipped.", e.GetTargetType(), e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
if (!CheckUnusedTargetParams(e))
{
return false;
}
return true;
}
bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e)
{
size_t paramsStructSize = [&]() -> size_t
{
constexpr size_t NO_PARAMS = size_t(0);
switch (e.event.type)
{
case SMART_EVENT_UPDATE_IC: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_UPDATE_OOC: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_HEALTH_PCT: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_MANA_PCT: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_AGGRO: return NO_PARAMS;
case SMART_EVENT_KILL: return sizeof(SmartEvent::kill);
case SMART_EVENT_DEATH: return NO_PARAMS;
case SMART_EVENT_EVADE: return NO_PARAMS;
case SMART_EVENT_SPELLHIT: return sizeof(SmartEvent::spellHit);
case SMART_EVENT_RANGE: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_OOC_LOS: return sizeof(SmartEvent::los);
case SMART_EVENT_RESPAWN: return sizeof(SmartEvent::respawn);
case SMART_EVENT_TARGET_HEALTH_PCT: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_VICTIM_CASTING: return sizeof(SmartEvent::targetCasting);
case SMART_EVENT_FRIENDLY_HEALTH: return sizeof(SmartEvent::friendlyHealth);
case SMART_EVENT_FRIENDLY_IS_CC: return sizeof(SmartEvent::friendlyCC);
case SMART_EVENT_FRIENDLY_MISSING_BUFF: return sizeof(SmartEvent::missingBuff);
case SMART_EVENT_SUMMONED_UNIT: return sizeof(SmartEvent::summoned);
case SMART_EVENT_TARGET_MANA_PCT: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_ACCEPTED_QUEST: return sizeof(SmartEvent::quest);
case SMART_EVENT_REWARD_QUEST: return sizeof(SmartEvent::quest);
case SMART_EVENT_REACHED_HOME: return NO_PARAMS;
case SMART_EVENT_RECEIVE_EMOTE: return sizeof(SmartEvent::emote);
case SMART_EVENT_HAS_AURA: return sizeof(SmartEvent::aura);
case SMART_EVENT_TARGET_BUFFED: return sizeof(SmartEvent::aura);
case SMART_EVENT_RESET: return NO_PARAMS;
case SMART_EVENT_IC_LOS: return sizeof(SmartEvent::los);
case SMART_EVENT_PASSENGER_BOARDED: return sizeof(SmartEvent::minMax);
case SMART_EVENT_PASSENGER_REMOVED: return sizeof(SmartEvent::minMax);
// case SMART_EVENT_CHARMED: return sizeof(SmartEvent::charm);
case SMART_EVENT_CHARMED_TARGET: return NO_PARAMS;
case SMART_EVENT_SPELLHIT_TARGET: return sizeof(SmartEvent::spellHit);
case SMART_EVENT_DAMAGED: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_DAMAGED_TARGET: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_MOVEMENTINFORM: return sizeof(SmartEvent::movementInform);
case SMART_EVENT_SUMMON_DESPAWNED: return sizeof(SmartEvent::summoned);
case SMART_EVENT_CORPSE_REMOVED: return NO_PARAMS;
case SMART_EVENT_AI_INIT: return NO_PARAMS;
case SMART_EVENT_DATA_SET: return sizeof(SmartEvent::dataSet);
case SMART_EVENT_WAYPOINT_START: return sizeof(SmartEvent::waypoint);
case SMART_EVENT_WAYPOINT_REACHED: return sizeof(SmartEvent::waypoint);
case SMART_EVENT_TRANSPORT_ADDPLAYER: return NO_PARAMS;
case SMART_EVENT_TRANSPORT_ADDCREATURE: return sizeof(SmartEvent::transportAddCreature);
case SMART_EVENT_TRANSPORT_REMOVE_PLAYER: return NO_PARAMS;
case SMART_EVENT_TRANSPORT_RELOCATE: return sizeof(SmartEvent::transportRelocate);
case SMART_EVENT_INSTANCE_PLAYER_ENTER: return sizeof(SmartEvent::instancePlayerEnter);
case SMART_EVENT_AREATRIGGER_ONTRIGGER: return sizeof(SmartEvent::areatrigger);
case SMART_EVENT_QUEST_ACCEPTED: return NO_PARAMS;
case SMART_EVENT_QUEST_OBJ_COMPLETION: return NO_PARAMS;
case SMART_EVENT_QUEST_COMPLETION: return NO_PARAMS;
case SMART_EVENT_QUEST_REWARDED: return NO_PARAMS;
case SMART_EVENT_QUEST_FAIL: return NO_PARAMS;
case SMART_EVENT_TEXT_OVER: return sizeof(SmartEvent::textOver);
case SMART_EVENT_RECEIVE_HEAL: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_JUST_SUMMONED: return NO_PARAMS;
case SMART_EVENT_WAYPOINT_PAUSED: return sizeof(SmartEvent::waypoint);
case SMART_EVENT_WAYPOINT_RESUMED: return sizeof(SmartEvent::waypoint);
case SMART_EVENT_WAYPOINT_STOPPED: return sizeof(SmartEvent::waypoint);
case SMART_EVENT_WAYPOINT_ENDED: return sizeof(SmartEvent::waypoint);
case SMART_EVENT_TIMED_EVENT_TRIGGERED: return sizeof(SmartEvent::timedEvent);
case SMART_EVENT_UPDATE: return sizeof(SmartEvent::minMaxRepeat);
case SMART_EVENT_LINK: return NO_PARAMS;
case SMART_EVENT_GOSSIP_SELECT: return sizeof(SmartEvent::gossip);
case SMART_EVENT_JUST_CREATED: return NO_PARAMS;
case SMART_EVENT_GOSSIP_HELLO: return sizeof(SmartEvent::gossipHello);
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::behindTarget);
case SMART_EVENT_GAME_EVENT_START: return sizeof(SmartEvent::gameEvent);
case SMART_EVENT_GAME_EVENT_END: return sizeof(SmartEvent::gameEvent);
// case SMART_EVENT_GO_LOOT_STATE_CHANGED: return sizeof(SmartEvent::goLootStateChanged);
case SMART_EVENT_GO_EVENT_INFORM: return sizeof(SmartEvent::eventInform);
case SMART_EVENT_ACTION_DONE: return sizeof(SmartEvent::doAction);
case SMART_EVENT_ON_SPELLCLICK: return NO_PARAMS;
case SMART_EVENT_FRIENDLY_HEALTH_PCT: return sizeof(SmartEvent::friendlyHealthPct);
case SMART_EVENT_DISTANCE_CREATURE: return sizeof(SmartEvent::distance);
case SMART_EVENT_DISTANCE_GAMEOBJECT: return sizeof(SmartEvent::distance);
case SMART_EVENT_COUNTER_SET: return sizeof(SmartEvent::counter);
//case SMART_EVENT_SCENE_START: return sizeof(SmartEvent::raw);
//case SMART_EVENT_SCENE_TRIGGER: return sizeof(SmartEvent::raw);
//case SMART_EVENT_SCENE_CANCEL: return sizeof(SmartEvent::raw);
//case SMART_EVENT_SCENE_COMPLETE: return sizeof(SmartEvent::raw);
case SMART_EVENT_SUMMONED_UNIT_DIES: return sizeof(SmartEvent::summoned);
default:
LOG_WARN("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u is using an event with no unused params specified in SmartAIMgr::CheckUnusedEventParams(), please report this.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return sizeof(SmartEvent::raw);
}
}();
static size_t rawCount = sizeof(SmartEvent::raw) / sizeof(uint32);
size_t paramsCount = paramsStructSize / sizeof(uint32);
bool valid = true;
for (size_t index = paramsCount; index < rawCount; index++)
{
uint32 value = ((uint32*)&e.event.raw)[index];
if (value != 0)
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has unused event_param{} with value {}, it must be 0, skipped.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), index + 1, value);
valid = false;
}
}
return valid;
}
bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
{
size_t paramsStructSize = [&]() -> size_t
{
constexpr size_t NO_PARAMS = size_t(0);
switch (e.action.type)
{
case SMART_ACTION_NONE: return NO_PARAMS;
case SMART_ACTION_TALK: return sizeof(SmartAction::talk);
case SMART_ACTION_SET_FACTION: return sizeof(SmartAction::faction);
case SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: return sizeof(SmartAction::morphOrMount);
case SMART_ACTION_SOUND: return sizeof(SmartAction::sound);
case SMART_ACTION_PLAY_EMOTE: return sizeof(SmartAction::emote);
case SMART_ACTION_FAIL_QUEST: return sizeof(SmartAction::quest);
case SMART_ACTION_OFFER_QUEST: return sizeof(SmartAction::questOffer);
case SMART_ACTION_SET_REACT_STATE: return sizeof(SmartAction::react);
case SMART_ACTION_ACTIVATE_GOBJECT: return NO_PARAMS;
case SMART_ACTION_RANDOM_EMOTE: return sizeof(SmartAction::randomEmote);
case SMART_ACTION_CAST: return sizeof(SmartAction::cast);
case SMART_ACTION_SUMMON_CREATURE: return sizeof(SmartAction::summonCreature);
case SMART_ACTION_THREAT_SINGLE_PCT: return sizeof(SmartAction::threatPCT);
case SMART_ACTION_THREAT_ALL_PCT: return sizeof(SmartAction::threatPCT);
case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: return sizeof(SmartAction::quest);
//case SMART_ACTION_RESERVED_16: return sizeof(SmartAction::raw);
case SMART_ACTION_SET_EMOTE_STATE: return sizeof(SmartAction::emote);
case SMART_ACTION_SET_UNIT_FLAG: return sizeof(SmartAction::unitFlag);
case SMART_ACTION_REMOVE_UNIT_FLAG: return sizeof(SmartAction::unitFlag);
case SMART_ACTION_AUTO_ATTACK: return sizeof(SmartAction::autoAttack);
case SMART_ACTION_ALLOW_COMBAT_MOVEMENT: return sizeof(SmartAction::combatMove);
case SMART_ACTION_SET_EVENT_PHASE: return sizeof(SmartAction::setEventPhase);
case SMART_ACTION_INC_EVENT_PHASE: return sizeof(SmartAction::incEventPhase);
// case SMART_ACTION_EVADE: return sizeof(SmartAction::evade);
// case SMART_ACTION_FLEE_FOR_ASSIST: return sizeof(SmartAction::fleeAssist);
case SMART_ACTION_CALL_GROUPEVENTHAPPENS: return sizeof(SmartAction::quest);
case SMART_ACTION_COMBAT_STOP: return NO_PARAMS;
case SMART_ACTION_REMOVEAURASFROMSPELL: return sizeof(SmartAction::removeAura);
case SMART_ACTION_FOLLOW: return sizeof(SmartAction::follow);
case SMART_ACTION_RANDOM_PHASE: return sizeof(SmartAction::randomPhase);
case SMART_ACTION_RANDOM_PHASE_RANGE: return sizeof(SmartAction::randomPhaseRange);
case SMART_ACTION_RESET_GOBJECT: return NO_PARAMS;
case SMART_ACTION_CALL_KILLEDMONSTER: return sizeof(SmartAction::killedMonster);
case SMART_ACTION_SET_INST_DATA: return sizeof(SmartAction::setInstanceData);
case SMART_ACTION_SET_INST_DATA64: return sizeof(SmartAction::setInstanceData64);
case SMART_ACTION_UPDATE_TEMPLATE: return sizeof(SmartAction::updateTemplate);
case SMART_ACTION_DIE: return NO_PARAMS;
case SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: return NO_PARAMS;
case SMART_ACTION_CALL_FOR_HELP: return sizeof(SmartAction::callHelp);
case SMART_ACTION_SET_SHEATH: return sizeof(SmartAction::setSheath);
case SMART_ACTION_FORCE_DESPAWN: return sizeof(SmartAction::forceDespawn);
case SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL: return sizeof(SmartAction::invincHP);
case SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL: return sizeof(SmartAction::morphOrMount);
case SMART_ACTION_SET_INGAME_PHASE_MASK: return sizeof(SmartAction::ingamePhaseMask);
case SMART_ACTION_SET_DATA: return sizeof(SmartAction::setData);
case SMART_ACTION_ATTACK_STOP: return NO_PARAMS;
case SMART_ACTION_SET_VISIBILITY: return sizeof(SmartAction::visibility);
// case SMART_ACTION_SET_ACTIVE: return sizeof(SmartAction::active);
case SMART_ACTION_ATTACK_START: return NO_PARAMS;
case SMART_ACTION_SUMMON_GO: return sizeof(SmartAction::summonGO);
case SMART_ACTION_KILL_UNIT: return NO_PARAMS;
case SMART_ACTION_ACTIVATE_TAXI: return sizeof(SmartAction::taxi);
case SMART_ACTION_WP_START: return sizeof(SmartAction::wpStart);
case SMART_ACTION_WP_PAUSE: return sizeof(SmartAction::wpPause);
case SMART_ACTION_WP_STOP: return sizeof(SmartAction::wpStop);
case SMART_ACTION_ADD_ITEM: return sizeof(SmartAction::item);
case SMART_ACTION_REMOVE_ITEM: return sizeof(SmartAction::item);
case SMART_ACTION_INSTALL_AI_TEMPLATE: return sizeof(SmartAction::installTtemplate);
case SMART_ACTION_SET_RUN: return sizeof(SmartAction::setRun);
// case SMART_ACTION_SET_DISABLE_GRAVITY: return sizeof(SmartAction::setDisableGravity);
case SMART_ACTION_SET_SWIM: return sizeof(SmartAction::setSwim);
case SMART_ACTION_TELEPORT: return sizeof(SmartAction::teleport);
case SMART_ACTION_SET_COUNTER: return sizeof(SmartAction::setCounter);
case SMART_ACTION_STORE_TARGET_LIST: return sizeof(SmartAction::storeTargets);
case SMART_ACTION_WP_RESUME: return NO_PARAMS;
case SMART_ACTION_SET_ORIENTATION: return NO_PARAMS;
case SMART_ACTION_CREATE_TIMED_EVENT: return sizeof(SmartAction::timeEvent);
case SMART_ACTION_PLAYMOVIE: return sizeof(SmartAction::movie);
case SMART_ACTION_MOVE_TO_POS: return sizeof(SmartAction::moveToPos);
// case SMART_ACTION_ENABLE_TEMP_GOBJ: return sizeof(SmartAction::enableTempGO);
case SMART_ACTION_EQUIP: return sizeof(SmartAction::equip);
case SMART_ACTION_CLOSE_GOSSIP: return NO_PARAMS;
case SMART_ACTION_TRIGGER_TIMED_EVENT: return sizeof(SmartAction::timeEvent);
case SMART_ACTION_REMOVE_TIMED_EVENT: return sizeof(SmartAction::timeEvent);
case SMART_ACTION_ADD_AURA: return sizeof(SmartAction::addAura);
case SMART_ACTION_OVERRIDE_SCRIPT_BASE_OBJECT: return NO_PARAMS;
case SMART_ACTION_RESET_SCRIPT_BASE_OBJECT: return NO_PARAMS;
case SMART_ACTION_CALL_SCRIPT_RESET: return NO_PARAMS;
case SMART_ACTION_SET_RANGED_MOVEMENT: return sizeof(SmartAction::setRangedMovement);
case SMART_ACTION_CALL_TIMED_ACTIONLIST: return sizeof(SmartAction::timedActionList);
case SMART_ACTION_SET_NPC_FLAG: return sizeof(SmartAction::flag);
case SMART_ACTION_ADD_NPC_FLAG: return sizeof(SmartAction::flag);
case SMART_ACTION_REMOVE_NPC_FLAG: return sizeof(SmartAction::flag);
case SMART_ACTION_SIMPLE_TALK: return sizeof(SmartAction::simpleTalk);
// case SMART_ACTION_SELF_CAST: return sizeof(SmartAction::cast);
case SMART_ACTION_CROSS_CAST: return sizeof(SmartAction::crossCast);
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST: return sizeof(SmartAction::randTimedActionList);
case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST: return sizeof(SmartAction::randRangeTimedActionList);
case SMART_ACTION_RANDOM_MOVE: return sizeof(SmartAction::moveRandom);
case SMART_ACTION_SET_UNIT_FIELD_BYTES_1: return sizeof(SmartAction::setunitByte);
case SMART_ACTION_REMOVE_UNIT_FIELD_BYTES_1: return sizeof(SmartAction::delunitByte);
case SMART_ACTION_INTERRUPT_SPELL: return sizeof(SmartAction::interruptSpellCasting);
case SMART_ACTION_SEND_GO_CUSTOM_ANIM: return sizeof(SmartAction::sendGoCustomAnim);
case SMART_ACTION_SET_DYNAMIC_FLAG: return sizeof(SmartAction::flag);
case SMART_ACTION_ADD_DYNAMIC_FLAG: return sizeof(SmartAction::flag);
case SMART_ACTION_REMOVE_DYNAMIC_FLAG: return sizeof(SmartAction::flag);
case SMART_ACTION_JUMP_TO_POS: return sizeof(SmartAction::jump);
case SMART_ACTION_SEND_GOSSIP_MENU: return sizeof(SmartAction::sendGossipMenu);
case SMART_ACTION_GO_SET_LOOT_STATE: return sizeof(SmartAction::setGoLootState);
case SMART_ACTION_SEND_TARGET_TO_TARGET: return sizeof(SmartAction::sendTargetToTarget);
case SMART_ACTION_SET_HOME_POS: return NO_PARAMS;
case SMART_ACTION_SET_HEALTH_REGEN: return sizeof(SmartAction::setHealthRegen);
case SMART_ACTION_SET_ROOT: return sizeof(SmartAction::setRoot);
case SMART_ACTION_SET_GO_FLAG: return sizeof(SmartAction::goFlag);
case SMART_ACTION_ADD_GO_FLAG: return sizeof(SmartAction::goFlag);
case SMART_ACTION_REMOVE_GO_FLAG: return sizeof(SmartAction::goFlag);
case SMART_ACTION_SUMMON_CREATURE_GROUP: return sizeof(SmartAction::creatureGroup);
case SMART_ACTION_SET_POWER: return sizeof(SmartAction::power);
case SMART_ACTION_ADD_POWER: return sizeof(SmartAction::power);
case SMART_ACTION_REMOVE_POWER: return sizeof(SmartAction::power);
case SMART_ACTION_GAME_EVENT_STOP: return sizeof(SmartAction::gameEventStop);
case SMART_ACTION_GAME_EVENT_START: return sizeof(SmartAction::gameEventStart);
case SMART_ACTION_START_CLOSEST_WAYPOINT: return sizeof(SmartAction::closestWaypointFromList);
// case SMART_ACTION_MOVE_OFFSET: return NO_PARAMS;
case SMART_ACTION_RANDOM_SOUND: return sizeof(SmartAction::randomSound);
case SMART_ACTION_SET_CORPSE_DELAY: return sizeof(SmartAction::corpseDelay);
case SMART_ACTION_DISABLE_EVADE: return sizeof(SmartAction::disableEvade);
case SMART_ACTION_GO_SET_GO_STATE: return sizeof(SmartAction::goState);
case SMART_ACTION_SET_CAN_FLY: return sizeof(SmartAction::setFly);
// case SMART_ACTION_REMOVE_AURAS_BY_TYPE: return sizeof(SmartAction::auraType);
case SMART_ACTION_SET_SIGHT_DIST: return sizeof(SmartAction::sightDistance);
case SMART_ACTION_FLEE: return sizeof(SmartAction::flee);
case SMART_ACTION_ADD_THREAT: return sizeof(SmartAction::threat);
case SMART_ACTION_LOAD_EQUIPMENT: return sizeof(SmartAction::loadEquipment);
case SMART_ACTION_TRIGGER_RANDOM_TIMED_EVENT: return sizeof(SmartAction::randomTimedEvent);
case SMART_ACTION_REMOVE_ALL_GAMEOBJECTS: return NO_PARAMS;
// case SMART_ACTION_PAUSE_MOVEMENT: return sizeof(SmartAction::pauseMovement);
//case SMART_ACTION_PLAY_ANIMKIT: return sizeof(SmartAction::raw);
//case SMART_ACTION_SCENE_PLAY: return sizeof(SmartAction::raw);
//case SMART_ACTION_SCENE_CANCEL: return sizeof(SmartAction::raw);
// case SMART_ACTION_SPAWN_SPAWNGROUP: return sizeof(SmartAction::groupSpawn);
// case SMART_ACTION_DESPAWN_SPAWNGROUP: return sizeof(SmartAction::groupSpawn);
// case SMART_ACTION_RESPAWN_BY_SPAWNID: return sizeof(SmartAction::respawnData);
// case SMART_ACTION_INVOKER_CAST: return sizeof(SmartAction::cast);
// case SMART_ACTION_PLAY_CINEMATIC: return sizeof(SmartAction::cinematic);
case SMART_ACTION_SET_MOVEMENT_SPEED: return sizeof(SmartAction::movementSpeed);
//case SMART_ACTION_PLAY_SPELL_VISUAL_KIT: return sizeof(SmartAction::raw);
// case SMART_ACTION_OVERRIDE_LIGHT: return sizeof(SmartAction::overrideLight);
// case SMART_ACTION_OVERRIDE_WEATHER: return sizeof(SmartAction::overrideWeather);
//case SMART_ACTION_SET_AI_ANIM_KIT: return sizeof(SmartAction::raw);
case SMART_ACTION_SET_HOVER: return sizeof(SmartAction::setHover);
case SMART_ACTION_SET_HEALTH_PCT: return sizeof(SmartAction::setHealthPct);
//case SMART_ACTION_CREATE_CONVERSATION: return sizeof(SmartAction::raw);
default:
LOG_WARN("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return sizeof(SmartAction::raw);
}
}();
static size_t rawCount = sizeof(SmartAction::raw) / sizeof(uint32);
size_t paramsCount = paramsStructSize / sizeof(uint32);
bool valid = true;
for (size_t index = paramsCount; index < rawCount; index++)
{
uint32 value = ((uint32*)&e.action.raw)[index];
if (value != 0)
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has unused action_param%zu with value %u, it must be 0, skipped.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), index + 1, value);
valid = false;
}
}
return valid;
}
bool SmartAIMgr::CheckUnusedTargetParams(SmartScriptHolder const& e)
{
size_t paramsStructSize = [&]() -> size_t
{
constexpr size_t NO_PARAMS = size_t(0);
switch (e.target.type)
{
case SMART_TARGET_NONE: return NO_PARAMS;
case SMART_TARGET_SELF: return NO_PARAMS;
case SMART_TARGET_VICTIM: return NO_PARAMS;
case SMART_TARGET_HOSTILE_SECOND_AGGRO: return sizeof(SmartTarget::hostilRandom);
case SMART_TARGET_HOSTILE_LAST_AGGRO: return sizeof(SmartTarget::hostilRandom);
case SMART_TARGET_HOSTILE_RANDOM: return sizeof(SmartTarget::hostilRandom);
case SMART_TARGET_HOSTILE_RANDOM_NOT_TOP: return sizeof(SmartTarget::hostilRandom);
case SMART_TARGET_ACTION_INVOKER: return NO_PARAMS;
case SMART_TARGET_POSITION: return NO_PARAMS; //uses x,y,z,o
case SMART_TARGET_CREATURE_RANGE: return sizeof(SmartTarget::unitRange);
case SMART_TARGET_CREATURE_GUID: return sizeof(SmartTarget::unitGUID);
case SMART_TARGET_CREATURE_DISTANCE: return sizeof(SmartTarget::unitDistance);
case SMART_TARGET_STORED: return sizeof(SmartTarget::stored);
case SMART_TARGET_GAMEOBJECT_RANGE: return sizeof(SmartTarget::goRange);
case SMART_TARGET_GAMEOBJECT_GUID: return sizeof(SmartTarget::goGUID);
case SMART_TARGET_GAMEOBJECT_DISTANCE: return sizeof(SmartTarget::goDistance);
case SMART_TARGET_INVOKER_PARTY: return NO_PARAMS;
case SMART_TARGET_PLAYER_RANGE: return sizeof(SmartTarget::playerRange);
case SMART_TARGET_PLAYER_DISTANCE: return sizeof(SmartTarget::playerDistance);
case SMART_TARGET_CLOSEST_CREATURE: return sizeof(SmartTarget::unitClosest);
case SMART_TARGET_CLOSEST_GAMEOBJECT: return sizeof(SmartTarget::goClosest);
case SMART_TARGET_CLOSEST_PLAYER: return sizeof(SmartTarget::playerDistance);
case SMART_TARGET_ACTION_INVOKER_VEHICLE: return NO_PARAMS;
case SMART_TARGET_OWNER_OR_SUMMONER: return sizeof(SmartTarget::owner);
case SMART_TARGET_THREAT_LIST: return sizeof(SmartTarget::threatList);
case SMART_TARGET_CLOSEST_ENEMY: return sizeof(SmartTarget::closestAttackable);
case SMART_TARGET_CLOSEST_FRIENDLY: return sizeof(SmartTarget::closestFriendly);
case SMART_TARGET_LOOT_RECIPIENTS: return NO_PARAMS;
case SMART_TARGET_FARTHEST: return sizeof(SmartTarget::farthest);
case SMART_TARGET_VEHICLE_PASSENGER: return sizeof(SmartTarget::vehicle);
// case SMART_TARGET_CLOSEST_UNSPAWNED_GAMEOBJECT: return sizeof(SmartTarget::goClosest);
default:
LOG_WARN("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u is using a target with no unused params specified in SmartAIMgr::CheckUnusedTargetParams(), please report this.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return sizeof(SmartTarget::raw);
}
}();
static size_t rawCount = sizeof(SmartTarget::raw) / sizeof(uint32);
size_t paramsCount = paramsStructSize / sizeof(uint32);
bool valid = true;
for (size_t index = paramsCount; index < rawCount; index++)
{
uint32 value = ((uint32*)&e.target.raw)[index];
if (value != 0)
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has unused target_param%zu with value %u, it must be 0, skipped.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), index + 1, value);
valid = false;
}
}
return valid;
}
bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
{
if ((e.event.type >= SMART_EVENT_TC_END && e.event.type <= SMART_EVENT_AC_START) || e.event.type >= SMART_EVENT_AC_END)
@@ -862,6 +1223,11 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
}
}
if (!CheckUnusedEventParams(e))
{
return false;
}
switch (e.GetActionType())
{
case SMART_ACTION_SET_FACTION:
@@ -974,7 +1340,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (e.action.randomEmote.emote6 && !IsEmoteValid(e, e.action.randomEmote.emote6))
return false;
break;
case SMART_ACTION_ADD_AURA:
case SMART_ACTION_CAST:
case SMART_ACTION_INVOKER_CAST:
if (!IsSpellValid(e, e.action.cast.spell))
@@ -988,6 +1353,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (!IsSpellValid(e, e.action.castCustom.spell))
return false;
break;
case SMART_ACTION_ADD_AURA:
if (!IsSpellValid(e, e.action.addAura.spell))
return false;
break;
case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS:
case SMART_ACTION_CALL_GROUPEVENTHAPPENS:
if (Quest const* qid = sObjectMgr->GetQuestTemplate(e.action.quest.quest))
@@ -1165,7 +1534,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
}
case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST:
{
if (!IsMinMaxValid(e, e.action.randTimedActionList.entry1, e.action.randTimedActionList.entry2))
if (!IsMinMaxValid(e, e.action.randRangeTimedActionList.idMin, e.action.randRangeTimedActionList.idMax))
return false;
break;
}
@@ -1355,6 +1724,20 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
AC_SAI_IS_BOOLEAN_VALID(e, e.action.loadEquipment.force);
break;
}
case SMART_ACTION_TALK:
AC_SAI_IS_BOOLEAN_VALID(e, e.action.talk.useTalkTarget);
if (!IsTextValid(e, e.action.talk.textGroupID))
return false;
break;
case SMART_ACTION_SIMPLE_TALK:
if (!IsTextValid(e, e.action.simpleTalk.textGroupID))
return false;
break;
case SMART_ACTION_SET_HEALTH_REGEN:
{
AC_SAI_IS_BOOLEAN_VALID(e, e.action.setHealthRegen.regenHealth);
break;
}
case SMART_ACTION_FLEE_FOR_ASSIST:
case SMART_ACTION_MOVE_TO_POS:
case SMART_ACTION_CALL_TIMED_ACTIONLIST:
@@ -1395,10 +1778,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_SET_NPC_FLAG:
case SMART_ACTION_ADD_NPC_FLAG:
case SMART_ACTION_REMOVE_NPC_FLAG:
case SMART_ACTION_TALK:
AC_SAI_IS_BOOLEAN_VALID(e, e.action.talk.useTalkTarget);
[[fallthrough]];
case SMART_ACTION_SIMPLE_TALK:
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:
case SMART_ACTION_RANDOM_MOVE:
case SMART_ACTION_SET_UNIT_FIELD_BYTES_1:
@@ -1413,7 +1792,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_GO_SET_GO_STATE:
case SMART_ACTION_SEND_TARGET_TO_TARGET:
case SMART_ACTION_SET_HOME_POS:
case SMART_ACTION_SET_HEALTH_REGEN:
case SMART_ACTION_SET_GO_FLAG:
case SMART_ACTION_ADD_GO_FLAG:
case SMART_ACTION_REMOVE_GO_FLAG:
@@ -1452,32 +1830,55 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
}
if (!CheckUnusedActionParams(e))
return false;
return true;
}
/*bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused
bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id)
{
bool error = false;
if (e.GetScriptType() != SMART_SCRIPT_TYPE_CREATURE)
return true;
uint32 entry = 0;
if (e.entryOrGuid >= 0)
entry = uint32(e.entryOrGuid);
else {
entry = uint32(std::abs(e.entryOrGuid));
CreatureData const* data = sObjectMgr->GetCreatureData(entry);
if (!data)
{
LOG_ERROR("scripts.ai.sai", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} using non-existent Creature guid {}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
return false;
}
else
entry = data->id;
}
if (!entry || !sCreatureTextMgr->TextExist(entry, uint8(id)))
error = true;
if (error)
if (e.GetEventType() == SMART_EVENT_TEXT_OVER)
{
LOG_ERROR("scripts.ai.sai", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} using non-existent Text id {}, skipped.", e.entryOrGuid, e.GetScriptType(), e.source_type, e.GetActionType(), id);
entry = e.event.textOver.creatureEntry;
}
else
{
switch (e.GetTargetType())
{
case SMART_TARGET_CREATURE_DISTANCE:
case SMART_TARGET_CREATURE_RANGE:
case SMART_TARGET_CLOSEST_CREATURE:
return true; // ignore
default:
if (e.entryOrGuid < 0)
{
ObjectGuid::LowType guid = ObjectGuid::LowType(-e.entryOrGuid);
CreatureData const* data = sObjectMgr->GetCreatureData(guid);
if (!data)
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} using non-existent Creature guid {}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), guid);
return false;
}
else
entry = data->id1;
}
else
entry = uint32(e.entryOrGuid);
break;
}
}
if (!entry || !sCreatureTextMgr->TextExist(entry, uint8(id)))
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} using non-existent Text id {}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), id);
return false;
}
return true;
}*/
}

View File

@@ -310,14 +310,6 @@ struct SmartEvent
uint32 repeatMax;
} aura;
struct
{
uint32 spell;
uint32 count;
uint32 repeatMin;
uint32 repeatMax;
} targetAura;
struct
{
uint32 type;
@@ -382,12 +374,6 @@ struct SmartEvent
uint32 action;
} gossip;
struct
{
uint32 spell;
uint32 effIndex;
} dummy;
struct
{
uint32 cooldownMin;
@@ -670,6 +656,12 @@ struct SmartAction
SAIBool useTalkTarget;
} talk;
struct
{
uint32 textGroupID;
uint32 duration;
} simpleTalk;
struct
{
uint32 factionID;
@@ -790,23 +782,9 @@ struct SmartAction
struct
{
uint32 flag1;
uint32 flag2;
uint32 flag3;
uint32 flag4;
uint32 flag5;
uint32 flag6;
} addUnitFlag;
struct
{
uint32 flag1;
uint32 flag2;
uint32 flag3;
uint32 flag4;
uint32 flag5;
uint32 flag6;
} removeUnitFlag;
uint32 threatINC;
uint32 threatDEC;
} threat;
struct
{
@@ -829,6 +807,11 @@ struct SmartAction
uint32 dec;
} incEventPhase;
struct
{
uint32 spell;
} addAura;
struct
{
uint32 spell;
@@ -1048,6 +1031,11 @@ struct SmartAction
uint32 type;
} unitFlag;
struct
{
uint32 flag;
} flag;
struct
{
uint32 byte1;
@@ -1060,11 +1048,6 @@ struct SmartAction
uint32 type;
} delunitByte;
struct
{
uint32 seat;
} enterVehicle;
struct
{
uint32 id;
@@ -1081,6 +1064,12 @@ struct SmartAction
uint32 entry6;
} randTimedActionList;
struct
{
uint32 idMin;
uint32 idMax;
} randRangeTimedActionList;
struct
{
SAIBool withDelayed;
@@ -1147,7 +1136,7 @@ struct SmartAction
struct
{
uint32 regenHealth;
SAIBool regenHealth;
} setHealthRegen;
struct
@@ -1494,8 +1483,10 @@ struct SmartTarget
struct
{
uint32 map;
} position;
uint32 entry;
uint32 dist;
SAIBool dead;
} unitClosest;
struct
{
@@ -1504,17 +1495,20 @@ struct SmartTarget
struct
{
uint32 entry;
uint32 dist;
SAIBool dead;
} closest;
uint32 seatMask;
} vehicle;
struct
{
uint32 maxDist;
} threatList;
struct
{
uint32 entry;
uint32 dist;
uint32 onlySpawned;
} closestGameobject;
} goClosest;
struct
{
@@ -1550,11 +1544,6 @@ struct SmartTarget
uint32 param3;
uint32 param4;
} raw;
struct
{
uint32 seat;
} vehicle;
};
};
@@ -2027,7 +2016,10 @@ private:
return true;
}
//bool IsTextValid(SmartScriptHolder const& e, uint32 id);
static bool IsTextValid(SmartScriptHolder const& e, uint32 id);
static bool CheckUnusedEventParams(SmartScriptHolder const& e);
static bool CheckUnusedActionParams(SmartScriptHolder const& e);
static bool CheckUnusedTargetParams(SmartScriptHolder const& e);
};
#define sSmartScriptMgr SmartAIMgr::instance()