Core/AI: enable SmartScripts on Scenes + add scene related actions/events
Closes #19194
This commit is contained in:
@@ -0,0 +1 @@
|
||||
ALTER TABLE `smart_scripts` ADD COLUMN `event_param_string` VARCHAR(255) DEFAULT '' NOT NULL AFTER `event_param4`;
|
||||
@@ -26,7 +26,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(WORLD_DEL_CRELINKED_RESPAWN, "DELETE FROM linked_respawn WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_REP_CREATURE_LINKED_RESPAWN, "REPLACE INTO linked_respawn (guid, linkedGuid) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_TEXT, "SELECT entry, groupid, id, text, type, language, probability, emote, duration, sound, BroadcastTextId, TextRange FROM creature_text", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, target_type, target_param1, target_param2, target_param3, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, event_param_string, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, target_type, target_param1, target_param2, target_param3, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_SMARTAI_WP, "SELECT entry, pointid, position_x, position_y, position_z FROM waypoints ORDER BY entry, pointid", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_DEL_GAMEOBJECT, "DELETE FROM gameobject WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_DEL_EVENT_GAMEOBJECT, "DELETE FROM game_event_gameobject WHERE guid = ?", CONNECTION_ASYNC);
|
||||
|
||||
@@ -979,7 +979,42 @@ class SmartTrigger : public AreaTriggerScript
|
||||
}
|
||||
};
|
||||
|
||||
class SmartScene : public SceneScript
|
||||
{
|
||||
public:
|
||||
SmartScene() : SceneScript("SmartScene") { }
|
||||
|
||||
void OnSceneStart(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate) override
|
||||
{
|
||||
SmartScript smartScript;
|
||||
smartScript.OnInitialize(nullptr, nullptr, sceneTemplate);
|
||||
smartScript.ProcessEventsFor(SMART_EVENT_SCENE_START, player);
|
||||
}
|
||||
|
||||
void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate, std::string const& triggerName) override
|
||||
{
|
||||
SmartScript smartScript;
|
||||
smartScript.OnInitialize(nullptr, nullptr, sceneTemplate);
|
||||
smartScript.ProcessEventsFor(SMART_EVENT_SCENE_TRIGGER, player, 0, 0, false, nullptr, nullptr, triggerName);
|
||||
}
|
||||
|
||||
void OnSceneCancel(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate) override
|
||||
{
|
||||
SmartScript smartScript;
|
||||
smartScript.OnInitialize(nullptr, nullptr, sceneTemplate);
|
||||
smartScript.ProcessEventsFor(SMART_EVENT_SCENE_CANCEL, player);
|
||||
}
|
||||
|
||||
void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate) override
|
||||
{
|
||||
SmartScript smartScript;
|
||||
smartScript.OnInitialize(nullptr, nullptr, sceneTemplate);
|
||||
smartScript.ProcessEventsFor(SMART_EVENT_SCENE_COMPLETE, player);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_SmartScripts()
|
||||
{
|
||||
new SmartTrigger();
|
||||
new SmartScene();
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ SmartScript::SmartScript()
|
||||
go = nullptr;
|
||||
me = nullptr;
|
||||
trigger = nullptr;
|
||||
sceneTemplate = nullptr;
|
||||
mEventPhase = 0;
|
||||
mPathId = 0;
|
||||
mTargetStorage = new ObjectListMap();
|
||||
@@ -80,7 +81,7 @@ void SmartScript::OnReset()
|
||||
mCounterList.clear();
|
||||
}
|
||||
|
||||
void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
|
||||
void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob, std::string const& varString)
|
||||
{
|
||||
for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
|
||||
{
|
||||
@@ -90,11 +91,11 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
|
||||
|
||||
if (eventType == e /*&& (!i->event.event_phase_mask || IsInPhase(i->event.event_phase_mask)) && !(i->event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && i->runOnce)*/)
|
||||
if (sConditionMgr->IsObjectMeetingSmartEventConditions(i->entryOrGuid, i->event_id, i->source_type, unit, GetBaseObject()))
|
||||
ProcessEvent(*i, unit, var0, var1, bvar, spell, gob);
|
||||
ProcessEvent(*i, unit, var0, var1, bvar, spell, gob, varString);
|
||||
}
|
||||
}
|
||||
|
||||
void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
|
||||
void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob, std::string const& varString)
|
||||
{
|
||||
//calc random
|
||||
if (e.GetEventType() != SMART_EVENT_LINK && e.event.event_chance < 100 && e.event.event_chance)
|
||||
@@ -1264,7 +1265,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
}
|
||||
case SMART_ACTION_SUMMON_CREATURE:
|
||||
{
|
||||
WorldObject* summoner = GetBaseObjectOrUnit(unit);
|
||||
if (!summoner)
|
||||
break;
|
||||
|
||||
ObjectList* targets = GetTargets(e, unit);
|
||||
|
||||
if (targets)
|
||||
{
|
||||
float x, y, z, o;
|
||||
@@ -1275,7 +1281,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
y += e.target.y;
|
||||
z += e.target.z;
|
||||
o += e.target.o;
|
||||
if (Creature* summon = GetBaseObject()->SummonCreature(e.action.summonCreature.creature, x, y, z, o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration))
|
||||
if (Creature* summon = summoner->SummonCreature(e.action.summonCreature.creature, x, y, z, o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration))
|
||||
if (e.action.summonCreature.attackInvoker)
|
||||
summon->AI()->AttackStart((*itr)->ToUnit());
|
||||
}
|
||||
@@ -1286,14 +1292,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (e.GetTargetType() != SMART_TARGET_POSITION)
|
||||
break;
|
||||
|
||||
if (Creature* summon = GetBaseObject()->SummonCreature(e.action.summonCreature.creature, e.target.x, e.target.y, e.target.z, e.target.o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration))
|
||||
if (Creature* summon = summoner->SummonCreature(e.action.summonCreature.creature, e.target.x, e.target.y, e.target.z, e.target.o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration))
|
||||
if (unit && e.action.summonCreature.attackInvoker)
|
||||
summon->AI()->AttackStart(unit);
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_SUMMON_GO:
|
||||
{
|
||||
if (!GetBaseObject())
|
||||
WorldObject* summoner = GetBaseObjectOrUnit(unit);
|
||||
if (!summoner)
|
||||
break;
|
||||
|
||||
ObjectList* targets = GetTargets(e, unit);
|
||||
@@ -1306,7 +1313,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
Position pos = (*itr)->GetPositionWithOffset(Position(e.target.x, e.target.y, e.target.z, e.target.o));
|
||||
G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f);
|
||||
GetBaseObject()->SummonGameObject(e.action.summonGO.entry, pos, rot, e.action.summonGO.despawnTime);
|
||||
summoner->SummonGameObject(e.action.summonGO.entry, pos, rot, e.action.summonGO.despawnTime);
|
||||
}
|
||||
|
||||
delete targets;
|
||||
@@ -1316,7 +1323,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
break;
|
||||
|
||||
G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(e.target.o, 0.f, 0.f);
|
||||
GetBaseObject()->SummonGameObject(e.action.summonGO.entry, Position(e.target.x, e.target.y, e.target.z, e.target.o), rot, e.action.summonGO.despawnTime);
|
||||
summoner->SummonGameObject(e.action.summonGO.entry, Position(e.target.x, e.target.y, e.target.z, e.target.o), rot, e.action.summonGO.despawnTime);
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_KILL_UNIT:
|
||||
@@ -2465,6 +2472,30 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
delete targets;
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_SCENE_PLAY:
|
||||
{
|
||||
ObjectList* targets = GetTargets(e, unit);
|
||||
if (!targets)
|
||||
break;
|
||||
|
||||
for (WorldObject* target : *targets)
|
||||
if (Player* playerTarget = target->ToPlayer())
|
||||
playerTarget->GetSceneMgr().PlayScene(e.action.scene.sceneId);
|
||||
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_SCENE_CANCEL:
|
||||
{
|
||||
ObjectList* targets = GetTargets(e, unit);
|
||||
if (!targets)
|
||||
break;
|
||||
|
||||
for (WorldObject* target : *targets)
|
||||
if (Player* playerTarget = target->ToPlayer())
|
||||
playerTarget->GetSceneMgr().CancelSceneBySceneId(e.action.scene.sceneId);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry " SI64FMTD " SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||
break;
|
||||
@@ -2474,16 +2505,16 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
{
|
||||
SmartScriptHolder& linked = SmartAIMgr::FindLinkedEvent(mEvents, e.link);
|
||||
if (linked)
|
||||
ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);
|
||||
ProcessEvent(linked, unit, var0, var1, bvar, spell, gob, varString);
|
||||
else
|
||||
TC_LOG_DEBUG("sql.sql", "SmartScript::ProcessAction: Entry " SI64FMTD " SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
|
||||
}
|
||||
}
|
||||
|
||||
void SmartScript::ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
|
||||
void SmartScript::ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob, std::string const& varString)
|
||||
{
|
||||
if (sConditionMgr->IsObjectMeetingSmartEventConditions(e.entryOrGuid, e.event_id, e.source_type, unit, GetBaseObject()))
|
||||
ProcessAction(e, unit, var0, var1, bvar, spell, gob);
|
||||
ProcessAction(e, unit, var0, var1, bvar, spell, gob, varString);
|
||||
|
||||
RecalcTimer(e, min, max);
|
||||
}
|
||||
@@ -2910,7 +2941,7 @@ ObjectList* SmartScript::GetWorldObjectsInDist(float dist)
|
||||
return targets;
|
||||
}
|
||||
|
||||
void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
|
||||
void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob, std::string const& varString)
|
||||
{
|
||||
if (!e.active && e.GetEventType() != SMART_EVENT_LINK)
|
||||
return;
|
||||
@@ -3448,6 +3479,21 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
||||
if (GetCounterId(e.event.counter.id) != 0 && GetCounterValue(e.event.counter.id) == e.event.counter.value)
|
||||
ProcessTimedAction(e, e.event.counter.cooldownMin, e.event.counter.cooldownMax);
|
||||
break;
|
||||
case SMART_EVENT_SCENE_START:
|
||||
case SMART_EVENT_SCENE_CANCEL:
|
||||
case SMART_EVENT_SCENE_COMPLETE:
|
||||
{
|
||||
ProcessAction(e, unit);
|
||||
break;
|
||||
}
|
||||
case SMART_EVENT_SCENE_TRIGGER:
|
||||
{
|
||||
if (e.event.param_string != varString)
|
||||
return;
|
||||
|
||||
ProcessAction(e, unit, var0, 0, false, nullptr, nullptr, varString);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType());
|
||||
break;
|
||||
@@ -3633,7 +3679,7 @@ void SmartScript::OnUpdate(uint32 const diff)
|
||||
}
|
||||
}
|
||||
|
||||
void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at)
|
||||
void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene)
|
||||
{
|
||||
if (e.empty())
|
||||
{
|
||||
@@ -3641,6 +3687,8 @@ void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEn
|
||||
TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for Entry %u is empty but is using SmartScript.", obj->GetEntry());
|
||||
if (at)
|
||||
TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for AreaTrigger %u is empty but is using SmartScript.", at->ID);
|
||||
if (scene)
|
||||
TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for SceneId %u is empty but is using SmartScript.", scene->SceneId);
|
||||
return;
|
||||
}
|
||||
for (SmartAIEventList::iterator i = e.begin(); i != e.end(); ++i)
|
||||
@@ -3667,6 +3715,8 @@ void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEn
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript: Entry %u has events but no events added to list because of instance flags.", obj->GetEntry());
|
||||
if (mEvents.empty() && at)
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript: AreaTrigger %u has events but no events added to list because of instance flags. NOTE: triggers can not handle any instance flags.", at->ID);
|
||||
if (mEvents.empty() && scene)
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript: SceneId %u has events but no events added to list because of instance flags. NOTE: scenes can not handle any instance flags.", scene->SceneId);
|
||||
}
|
||||
|
||||
void SmartScript::GetScript()
|
||||
@@ -3677,23 +3727,28 @@ void SmartScript::GetScript()
|
||||
e = sSmartScriptMgr->GetScript(-((int32)me->GetSpawnId()), mScriptType);
|
||||
if (e.empty())
|
||||
e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType);
|
||||
FillScript(e, me, nullptr);
|
||||
FillScript(e, me, nullptr, nullptr);
|
||||
}
|
||||
else if (go)
|
||||
{
|
||||
e = sSmartScriptMgr->GetScript(-((int32)go->GetSpawnId()), mScriptType);
|
||||
if (e.empty())
|
||||
e = sSmartScriptMgr->GetScript((int32)go->GetEntry(), mScriptType);
|
||||
FillScript(e, go, nullptr);
|
||||
FillScript(e, go, nullptr, nullptr);
|
||||
}
|
||||
else if (trigger)
|
||||
{
|
||||
e = sSmartScriptMgr->GetScript((int32)trigger->ID, mScriptType);
|
||||
FillScript(e, nullptr, trigger);
|
||||
FillScript(e, nullptr, trigger, nullptr);
|
||||
}
|
||||
else if (sceneTemplate)
|
||||
{
|
||||
e = sSmartScriptMgr->GetScript(sceneTemplate->SceneId, mScriptType);
|
||||
FillScript(e, nullptr, nullptr, sceneTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at)
|
||||
void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene)
|
||||
{
|
||||
if (obj)//handle object based scripts
|
||||
{
|
||||
@@ -3713,12 +3768,19 @@ void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at)
|
||||
TC_LOG_ERROR("misc", "SmartScript::OnInitialize: Unhandled TypeID !WARNING!");
|
||||
return;
|
||||
}
|
||||
} else if (at)
|
||||
}
|
||||
else if (at)
|
||||
{
|
||||
mScriptType = SMART_SCRIPT_TYPE_AREATRIGGER;
|
||||
trigger = at;
|
||||
TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is AreaTrigger %u", trigger->ID);
|
||||
}
|
||||
else if (scene)
|
||||
{
|
||||
mScriptType = SMART_SCRIPT_TYPE_SCENE;
|
||||
sceneTemplate = scene;
|
||||
TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is Scene with id %u", scene->SceneId);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_ERROR("misc", "SmartScript::OnInitialize: !WARNING! Initialized objects are NULL.");
|
||||
|
||||
@@ -28,24 +28,26 @@
|
||||
#include "SmartScriptMgr.h"
|
||||
//#include "SmartAI.h"
|
||||
|
||||
class Player;
|
||||
|
||||
class TC_GAME_API SmartScript
|
||||
{
|
||||
public:
|
||||
SmartScript();
|
||||
~SmartScript();
|
||||
|
||||
void OnInitialize(WorldObject* obj, AreaTriggerEntry const* at = nullptr);
|
||||
void OnInitialize(WorldObject* obj, AreaTriggerEntry const* at = nullptr, SceneTemplate const* scene = nullptr);
|
||||
void GetScript();
|
||||
void FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at);
|
||||
void FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene);
|
||||
|
||||
void ProcessEventsFor(SMART_EVENT e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr);
|
||||
void ProcessEvent(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr);
|
||||
void ProcessEventsFor(SMART_EVENT e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
|
||||
void ProcessEvent(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
|
||||
bool CheckTimer(SmartScriptHolder const& e) const;
|
||||
void RecalcTimer(SmartScriptHolder& e, uint32 min, uint32 max);
|
||||
void UpdateTimer(SmartScriptHolder& e, uint32 const diff);
|
||||
void InitTimer(SmartScriptHolder& e);
|
||||
void ProcessAction(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr);
|
||||
void ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr);
|
||||
void ProcessAction(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
|
||||
void ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
|
||||
ObjectList* GetTargets(SmartScriptHolder const& e, Unit* invoker = nullptr);
|
||||
ObjectList* GetWorldObjectsInDist(float dist);
|
||||
void InstallTemplate(SmartScriptHolder const& e);
|
||||
@@ -62,6 +64,15 @@ class TC_GAME_API SmartScript
|
||||
obj = go;
|
||||
return obj;
|
||||
}
|
||||
WorldObject* GetBaseObjectOrUnit(Unit* unit)
|
||||
{
|
||||
WorldObject* summoner = GetBaseObject();
|
||||
|
||||
if (!summoner && unit)
|
||||
return unit;
|
||||
|
||||
return summoner;
|
||||
}
|
||||
|
||||
static bool IsUnit(WorldObject* obj)
|
||||
{
|
||||
@@ -274,6 +285,7 @@ class TC_GAME_API SmartScript
|
||||
GameObject* go;
|
||||
ObjectGuid goOrigGUID;
|
||||
AreaTriggerEntry const* trigger;
|
||||
SceneTemplate const* sceneTemplate;
|
||||
SmartScriptType mScriptType;
|
||||
uint32 mEventPhase;
|
||||
|
||||
|
||||
@@ -190,6 +190,15 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_SCRIPT_TYPE_SCENE:
|
||||
{
|
||||
if (!sObjectMgr->GetSceneTemplate((uint32)temp.entryOrGuid))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Scene id (%u) does not exist, skipped loading.", uint32(temp.entryOrGuid));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_SCRIPT_TYPE_TIMED_ACTIONLIST:
|
||||
break;//nothing to check, really
|
||||
default:
|
||||
@@ -232,23 +241,24 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
||||
temp.event.raw.param2 = fields[9].GetUInt32();
|
||||
temp.event.raw.param3 = fields[10].GetUInt32();
|
||||
temp.event.raw.param4 = fields[11].GetUInt32();
|
||||
temp.event.param_string = fields[12].GetString();
|
||||
|
||||
temp.action.type = (SMART_ACTION)fields[12].GetUInt8();
|
||||
temp.action.raw.param1 = fields[13].GetUInt32();
|
||||
temp.action.raw.param2 = fields[14].GetUInt32();
|
||||
temp.action.raw.param3 = fields[15].GetUInt32();
|
||||
temp.action.raw.param4 = fields[16].GetUInt32();
|
||||
temp.action.raw.param5 = fields[17].GetUInt32();
|
||||
temp.action.raw.param6 = fields[18].GetUInt32();
|
||||
temp.action.type = (SMART_ACTION)fields[13].GetUInt8();
|
||||
temp.action.raw.param1 = fields[14].GetUInt32();
|
||||
temp.action.raw.param2 = fields[15].GetUInt32();
|
||||
temp.action.raw.param3 = fields[16].GetUInt32();
|
||||
temp.action.raw.param4 = fields[17].GetUInt32();
|
||||
temp.action.raw.param5 = fields[18].GetUInt32();
|
||||
temp.action.raw.param6 = fields[19].GetUInt32();
|
||||
|
||||
temp.target.type = (SMARTAI_TARGETS)fields[19].GetUInt8();
|
||||
temp.target.raw.param1 = fields[20].GetUInt32();
|
||||
temp.target.raw.param2 = fields[21].GetUInt32();
|
||||
temp.target.raw.param3 = fields[22].GetUInt32();
|
||||
temp.target.x = fields[23].GetFloat();
|
||||
temp.target.y = fields[24].GetFloat();
|
||||
temp.target.z = fields[25].GetFloat();
|
||||
temp.target.o = fields[26].GetFloat();
|
||||
temp.target.type = (SMARTAI_TARGETS)fields[20].GetUInt8();
|
||||
temp.target.raw.param1 = fields[21].GetUInt32();
|
||||
temp.target.raw.param2 = fields[22].GetUInt32();
|
||||
temp.target.raw.param3 = fields[23].GetUInt32();
|
||||
temp.target.x = fields[24].GetFloat();
|
||||
temp.target.y = fields[25].GetFloat();
|
||||
temp.target.z = fields[26].GetFloat();
|
||||
temp.target.o = fields[27].GetFloat();
|
||||
|
||||
//check target
|
||||
if (!IsTargetValid(temp))
|
||||
@@ -754,6 +764,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
case SMART_EVENT_JUST_CREATED:
|
||||
case SMART_EVENT_FOLLOW_COMPLETED:
|
||||
case SMART_EVENT_ON_SPELLCLICK:
|
||||
case SMART_EVENT_SCENE_START:
|
||||
case SMART_EVENT_SCENE_CANCEL:
|
||||
case SMART_EVENT_SCENE_COMPLETE:
|
||||
case SMART_EVENT_SCENE_TRIGGER:
|
||||
break;
|
||||
default:
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Not handled event_type(%u), Entry " SI64FMTD " SourceType %u Event %u Action %u, skipped.", e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||
@@ -1217,6 +1231,26 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_SCENE_PLAY:
|
||||
{
|
||||
if (!sObjectMgr->GetSceneTemplate(e.action.scene.sceneId))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SCENE_PLAY uses sceneId %u but scene don't exist, skipped", e.action.scene.sceneId);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_SCENE_CANCEL:
|
||||
{
|
||||
if (!sObjectMgr->GetSceneTemplate(e.action.scene.sceneId))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SCENE_CANCEL uses sceneId %u but scene don't exist, skipped", e.action.scene.sceneId);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_START_CLOSEST_WAYPOINT:
|
||||
case SMART_ACTION_FOLLOW:
|
||||
case SMART_ACTION_SET_ORIENTATION:
|
||||
|
||||
@@ -179,8 +179,12 @@ enum SMART_EVENT
|
||||
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_SCENE_START = 78, // none
|
||||
SMART_EVENT_SCENE_TRIGGER = 79, // param_string : triggerName
|
||||
SMART_EVENT_SCENE_CANCEL = 80, // none
|
||||
SMART_EVENT_SCENE_COMPLETE = 81, // none
|
||||
|
||||
SMART_EVENT_END = 78
|
||||
SMART_EVENT_END = 82
|
||||
};
|
||||
|
||||
struct SmartEvent
|
||||
@@ -421,6 +425,11 @@ struct SmartEvent
|
||||
uint32 cooldownMax;
|
||||
} counter;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 sceneId;
|
||||
} scene;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 param1;
|
||||
@@ -429,6 +438,8 @@ struct SmartEvent
|
||||
uint32 param4;
|
||||
} raw;
|
||||
};
|
||||
|
||||
std::string param_string;
|
||||
};
|
||||
|
||||
enum SMART_SCRIPT_RESPAWN_CONDITION
|
||||
@@ -558,9 +569,12 @@ enum SMART_ACTION
|
||||
SMART_ACTION_RANDOM_SOUND = 115, // soundId1, soundId2, soundId3, soundId4, soundId5, onlySelf
|
||||
SMART_ACTION_SET_CORPSE_DELAY = 116, // timer
|
||||
SMART_ACTION_DISABLE_EVADE = 117, // 0/1 (1 = disabled, 0 = enabled)
|
||||
// 118 - 127 : 3.3.5 reserved
|
||||
SMART_ACTION_PLAY_ANIMKIT = 128, // id, type (0 = oneShot, 1 = aiAnim, 2 = meleeAnim, 3 = movementAnim)
|
||||
SMART_ACTION_SCENE_PLAY = 129, // sceneId
|
||||
SMART_ACTION_SCENE_CANCEL = 130, // sceneId
|
||||
|
||||
SMART_ACTION_END = 129
|
||||
SMART_ACTION_END = 131
|
||||
};
|
||||
|
||||
struct SmartAction
|
||||
@@ -1081,6 +1095,11 @@ struct SmartAction
|
||||
uint32 type;
|
||||
} animKit;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 sceneId;
|
||||
} scene;
|
||||
|
||||
//! Note for any new future actions
|
||||
//! All parameters must have type uint32
|
||||
|
||||
@@ -1257,7 +1276,8 @@ enum SmartScriptType
|
||||
SMART_SCRIPT_TYPE_TRANSPORT = 7, //
|
||||
SMART_SCRIPT_TYPE_INSTANCE = 8, //
|
||||
SMART_SCRIPT_TYPE_TIMED_ACTIONLIST = 9, //
|
||||
SMART_SCRIPT_TYPE_MAX = 10
|
||||
SMART_SCRIPT_TYPE_SCENE = 10, //done
|
||||
SMART_SCRIPT_TYPE_MAX = 11
|
||||
};
|
||||
|
||||
enum SmartAITypeMaskId
|
||||
@@ -1271,7 +1291,8 @@ enum SmartAITypeMaskId
|
||||
SMART_SCRIPT_TYPE_MASK_SPELL = 64,
|
||||
SMART_SCRIPT_TYPE_MASK_TRANSPORT = 128,
|
||||
SMART_SCRIPT_TYPE_MASK_INSTANCE = 256,
|
||||
SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST = 512
|
||||
SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST = 512,
|
||||
SMART_SCRIPT_TYPE_MASK_SCENE = 1024
|
||||
};
|
||||
|
||||
const uint32 SmartAITypeMask[SMART_SCRIPT_TYPE_MAX][2] =
|
||||
@@ -1285,7 +1306,8 @@ const uint32 SmartAITypeMask[SMART_SCRIPT_TYPE_MAX][2] =
|
||||
{SMART_SCRIPT_TYPE_SPELL, SMART_SCRIPT_TYPE_MASK_SPELL },
|
||||
{SMART_SCRIPT_TYPE_TRANSPORT, SMART_SCRIPT_TYPE_MASK_TRANSPORT },
|
||||
{SMART_SCRIPT_TYPE_INSTANCE, SMART_SCRIPT_TYPE_MASK_INSTANCE },
|
||||
{SMART_SCRIPT_TYPE_TIMED_ACTIONLIST, SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST }
|
||||
{SMART_SCRIPT_TYPE_TIMED_ACTIONLIST, SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST },
|
||||
{SMART_SCRIPT_TYPE_SCENE, SMART_SCRIPT_TYPE_MASK_SCENE }
|
||||
};
|
||||
|
||||
const uint32 SmartAIEventMask[SMART_EVENT_END][2] =
|
||||
@@ -1367,7 +1389,11 @@ 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 },
|
||||
{SMART_EVENT_SCENE_START, SMART_SCRIPT_TYPE_MASK_SCENE },
|
||||
{SMART_EVENT_SCENE_TRIGGER, SMART_SCRIPT_TYPE_MASK_SCENE },
|
||||
{SMART_EVENT_SCENE_CANCEL, SMART_SCRIPT_TYPE_MASK_SCENE },
|
||||
{SMART_EVENT_SCENE_COMPLETE, SMART_SCRIPT_TYPE_MASK_SCENE }
|
||||
};
|
||||
|
||||
enum SmartEventFlags
|
||||
|
||||
@@ -157,6 +157,18 @@ void SceneMgr::AddInstanceIdToSceneMap(uint32 sceneInstanceID, SceneTemplate con
|
||||
_scenesByInstance[sceneInstanceID] = sceneTemplate;
|
||||
}
|
||||
|
||||
void SceneMgr::CancelSceneBySceneId(uint32 sceneId)
|
||||
{
|
||||
std::vector<uint32> instancesIds;
|
||||
|
||||
for (auto const& itr : _scenesByInstance)
|
||||
if (itr.second->SceneId == sceneId)
|
||||
instancesIds.push_back(itr.first);
|
||||
|
||||
for (uint32 sceneInstanceID : instancesIds)
|
||||
CancelScene(sceneInstanceID);
|
||||
}
|
||||
|
||||
void SceneMgr::CancelSceneByPackageId(uint32 sceneScriptPackageId)
|
||||
{
|
||||
std::vector<uint32> instancesIds;
|
||||
|
||||
@@ -52,6 +52,7 @@ public:
|
||||
bool HasScene(uint32 sceneInstanceID, uint32 sceneScriptPackageId = 0) const;
|
||||
|
||||
void AddInstanceIdToSceneMap(uint32 sceneInstanceID, SceneTemplate const* sceneTemplate);
|
||||
void CancelSceneBySceneId(uint32 sceneId);
|
||||
void CancelSceneByPackageId(uint32 sceneScriptPackageId);
|
||||
void RemoveSceneInstanceId(uint32 sceneInstanceID);
|
||||
void RemoveAurasDueToSceneId(uint32 sceneId);
|
||||
|
||||
Reference in New Issue
Block a user