aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp11
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp14
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h8
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp73
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h1
-rw-r--r--src/server/game/Entities/GameObject/GameObjectData.h49
-rw-r--r--src/server/game/Spells/SpellEffects.cpp69
7 files changed, 132 insertions, 93 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 7eae8e1d039..b24f7b76773 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -2381,6 +2381,17 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
break;
}
+ case SMART_ACTION_ACTIVATE_GAMEOBJECT:
+ {
+ for (WorldObject* target : targets)
+ {
+ if (GameObject* targetGo = target->ToGameObject())
+ {
+ targetGo->ActivateObject(GameObjectActions(e.action.activateGameObject.gameObjectAction));
+ }
+ }
+ break;
+ }
default:
TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
break;
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 6f8299c22da..578b1f958fe 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -943,6 +943,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
case SMART_ACTION_SET_IMMUNE_PC: return sizeof(SmartAction::setImmunePC);
case SMART_ACTION_SET_IMMUNE_NPC: return sizeof(SmartAction::setImmuneNPC);
case SMART_ACTION_SET_UNINTERACTIBLE: return sizeof(SmartAction::setUninteractible);
+ case SMART_ACTION_ACTIVATE_GAMEOBJECT: return sizeof(SmartAction::activateGameObject);
default:
TC_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());
@@ -2123,6 +2124,19 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
TC_SAI_IS_BOOLEAN_VALID(e, e.action.setUninteractible.uninteractible);
break;
}
+ case SMART_ACTION_ACTIVATE_GAMEOBJECT:
+ {
+ if (!NotNULL(e, e.action.activateGameObject.gameObjectAction))
+ return false;
+
+ if (e.action.activateGameObject.gameObjectAction >= uint32(GameObjectActions::Max))
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has gameObjectAction parameter out of range (max allowed %u, current value %u), skipped.",
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), uint32(GameObjectActions::Max), e.action.activateGameObject.gameObjectAction);
+ return false;
+ }
+ break;
+ }
case SMART_ACTION_FOLLOW:
case SMART_ACTION_SET_ORIENTATION:
case SMART_ACTION_STORE_TARGET_LIST:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index d422377b628..7d3600f51a4 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -589,8 +589,9 @@ enum SMART_ACTION
SMART_ACTION_SET_IMMUNE_PC = 144, // 0/1
SMART_ACTION_SET_IMMUNE_NPC = 145, // 0/1
SMART_ACTION_SET_UNINTERACTIBLE = 146, // 0/1
+ SMART_ACTION_ACTIVATE_GAMEOBJECT = 147, // GameObjectActions
- SMART_ACTION_END = 147
+ SMART_ACTION_END = 148
};
enum class SmartActionSummonCreatureFlags
@@ -1197,6 +1198,11 @@ struct SmartAction
SAIBool uninteractible;
} setUninteractible;
+ struct
+ {
+ uint32 gameObjectAction;
+ } activateGameObject;
+
//! Note for any new future actions
//! All parameters must have type uint32
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 4a290700fc4..2df3f55d7fa 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1432,6 +1432,79 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = f
m_cooldownTime = time_to_restore ? (GameTime::GetGameTimeMS() + time_to_restore) : 0;
}
+void GameObject::ActivateObject(GameObjectActions action, WorldObject* spellCaster, uint32 spellId, int32 effectIndex)
+{
+ Unit* unitCaster = spellCaster ? spellCaster->ToUnit() : nullptr;
+
+ switch (action)
+ {
+ case GameObjectActions::AnimateCustom0:
+ case GameObjectActions::AnimateCustom1:
+ case GameObjectActions::AnimateCustom2:
+ case GameObjectActions::AnimateCustom3:
+ SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
+ break;
+ case GameObjectActions::Disturb: // What's the difference with Open?
+ case GameObjectActions::Open:
+ if (unitCaster)
+ Use(unitCaster);
+ break;
+ case GameObjectActions::OpenAndUnlock:
+ if (unitCaster)
+ UseDoorOrButton(0, false, unitCaster);
+ [[fallthrough]];
+ case GameObjectActions::Unlock:
+ case GameObjectActions::Lock:
+ ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
+ break;
+ case GameObjectActions::Close:
+ case GameObjectActions::Rebuild:
+ ResetDoorOrButton();
+ break;
+ case GameObjectActions::Despawn:
+ DespawnOrUnsummon();
+ break;
+ case GameObjectActions::MakeInert:
+ case GameObjectActions::MakeActive:
+ ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
+ break;
+ case GameObjectActions::CloseAndLock:
+ ResetDoorOrButton();
+ SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ break;
+ case GameObjectActions::Destroy:
+ if (unitCaster)
+ UseDoorOrButton(0, true, unitCaster);
+ break;
+ case GameObjectActions::UseArtKit0:
+ case GameObjectActions::UseArtKit1:
+ case GameObjectActions::UseArtKit2:
+ case GameObjectActions::UseArtKit3:
+ {
+ GameObjectTemplateAddon const* templateAddon = GetTemplateAddon();
+
+ uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
+
+ uint32 artKitValue = 0;
+ if (templateAddon != nullptr)
+ artKitValue = templateAddon->artKits[artKitIndex];
+
+ if (artKitValue == 0)
+ TC_LOG_ERROR("sql.sql", "GameObject %d hit by spell %d needs `artkit%d` in `gameobject_template_addon`", GetEntry(), spellId, artKitIndex);
+ else
+ SetGoArtKit(artKitValue);
+
+ break;
+ }
+ case GameObjectActions::None:
+ TC_LOG_FATAL("spell", "Spell %d has action type NONE in effect %d", spellId, effectIndex);
+ break;
+ default:
+ TC_LOG_ERROR("spell", "Spell %d has unhandled action %d in effect %d", spellId, int32(action), effectIndex);
+ break;
+ }
+}
+
void GameObject::SetGoArtKit(uint8 kit)
{
SetByteValue(GAMEOBJECT_BYTES_1, 2, kit);
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index f06a4fcbdd3..ec0547c2aaa 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -226,6 +226,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false, Unit* user = nullptr);
// 0 = use `gameobject`.`spawntimesecs`
void ResetDoorOrButton();
+ void ActivateObject(GameObjectActions action, WorldObject* spellCaster = nullptr, uint32 spellId = 0, int32 effectIndex = -1);
void TriggeringLinkedGameObject(uint32 trapEntry, Unit* target);
diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h
index ef7c95035e0..087eb8c18bd 100644
--- a/src/server/game/Entities/GameObject/GameObjectData.h
+++ b/src/server/game/Entities/GameObject/GameObjectData.h
@@ -675,30 +675,31 @@ struct GameObjectData : public SpawnData
enum class GameObjectActions : uint32
{
// Name from client executable // Comments
- None, // -NONE-
- AnimateCustom0, // Animate Custom0
- AnimateCustom1, // Animate Custom1
- AnimateCustom2, // Animate Custom2
- AnimateCustom3, // Animate Custom3
- Disturb, // Disturb // Triggers trap
- Unlock, // Unlock // Resets GO_FLAG_LOCKED
- Lock, // Lock // Sets GO_FLAG_LOCKED
- Open, // Open // Sets GO_STATE_ACTIVE
- OpenAndUnlock, // Open + Unlock // Sets GO_STATE_ACTIVE and resets GO_FLAG_LOCKED
- Close, // Close // Sets GO_STATE_READY
- ToggleOpen, // Toggle Open
- Destroy, // Destroy // Sets GO_STATE_DESTROYED
- Rebuild, // Rebuild // Resets from GO_STATE_DESTROYED
- Creation, // Creation
- Despawn, // Despawn
- MakeInert, // Make Inert // Disables interactions
- MakeActive, // Make Active // Enables interactions
- CloseAndLock, // Close + Lock // Sets GO_STATE_READY and sets GO_FLAG_LOCKED
- UseArtKit0, // Use ArtKit0 // 46904: 121
- UseArtKit1, // Use ArtKit1 // 36639: 81, 46903: 122
- UseArtKit2, // Use ArtKit2
- UseArtKit3, // Use ArtKit3
- SetTapList, // Set Tap List
+ None = 0, // -NONE-
+ AnimateCustom0 = 1, // Animate Custom0
+ AnimateCustom1 = 2, // Animate Custom1
+ AnimateCustom2 = 3, // Animate Custom2
+ AnimateCustom3 = 4, // Animate Custom3
+ Disturb = 5, // Disturb // Triggers trap
+ Unlock = 6, // Unlock // Resets GO_FLAG_LOCKED
+ Lock = 7, // Lock // Sets GO_FLAG_LOCKED
+ Open = 8, // Open // Sets GO_STATE_ACTIVE
+ OpenAndUnlock = 9, // Open + Unlock // Sets GO_STATE_ACTIVE and resets GO_FLAG_LOCKED
+ Close = 10, // Close // Sets GO_STATE_READY
+ ToggleOpen = 11, // Toggle Open
+ Destroy = 12, // Destroy // Sets GO_STATE_DESTROYED
+ Rebuild = 13, // Rebuild // Resets from GO_STATE_DESTROYED
+ Creation = 14, // Creation
+ Despawn = 15, // Despawn
+ MakeInert = 16, // Make Inert // Disables interactions
+ MakeActive = 17, // Make Active // Enables interactions
+ CloseAndLock = 18, // Close + Lock // Sets GO_STATE_READY and sets GO_FLAG_LOCKED
+ UseArtKit0 = 19, // Use ArtKit0 // 46904: 121
+ UseArtKit1 = 20, // Use ArtKit1 // 36639: 81, 46903: 122
+ UseArtKit2 = 21, // Use ArtKit2
+ UseArtKit3 = 22, // Use ArtKit3
+ SetTapList = 23, // Set Tap List
+ Max
};
#endif // GameObjectData_h__
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 1a910fc16d1..720aadbb2d0 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -3762,74 +3762,7 @@ void Spell::EffectActivateObject()
GameObjectActions action = GameObjectActions(effectInfo->MiscValue);
- switch (action)
- {
- case GameObjectActions::AnimateCustom0:
- case GameObjectActions::AnimateCustom1:
- case GameObjectActions::AnimateCustom2:
- case GameObjectActions::AnimateCustom3:
- gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
- break;
- case GameObjectActions::Disturb: // What's the difference with Open?
- case GameObjectActions::Open:
- if (Unit* unitCaster = m_caster->ToUnit())
- gameObjTarget->Use(unitCaster);
- break;
- case GameObjectActions::OpenAndUnlock:
- if (Unit* unitCaster = m_caster->ToUnit())
- gameObjTarget->UseDoorOrButton(0, false, unitCaster);
- [[fallthrough]];
- case GameObjectActions::Unlock:
- case GameObjectActions::Lock:
- gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
- break;
- case GameObjectActions::Close:
- case GameObjectActions::Rebuild:
- gameObjTarget->ResetDoorOrButton();
- break;
- case GameObjectActions::Despawn:
- gameObjTarget->DespawnOrUnsummon();
- break;
- case GameObjectActions::MakeInert:
- case GameObjectActions::MakeActive:
- gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
- break;
- case GameObjectActions::CloseAndLock:
- gameObjTarget->ResetDoorOrButton();
- gameObjTarget->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
- break;
- case GameObjectActions::Destroy:
- if (Unit* unitCaster = m_caster->ToUnit())
- gameObjTarget->UseDoorOrButton(0, true, unitCaster);
- break;
- case GameObjectActions::UseArtKit0:
- case GameObjectActions::UseArtKit1:
- case GameObjectActions::UseArtKit2:
- case GameObjectActions::UseArtKit3:
- {
- GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
-
- uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
-
- uint32 artKitValue = 0;
- if (templateAddon != nullptr)
- artKitValue = templateAddon->artKits[artKitIndex];
-
- if (artKitValue == 0)
- TC_LOG_ERROR("sql.sql", "GameObject %d hit by spell %d needs `artkit%d` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
- else
- gameObjTarget->SetGoArtKit(artKitValue);
-
- break;
- }
- case GameObjectActions::None:
- TC_LOG_FATAL("spell", "Spell %d has action type NONE in effect %d", m_spellInfo->Id, int32(effectInfo->EffectIndex));
- break;
- default:
- TC_LOG_ERROR("spell", "Spell %d has unhandled action %d in effect %d", m_spellInfo->Id, int32(action), int32(effectInfo->EffectIndex));
- break;
- }
-
+ gameObjTarget->ActivateObject(action, m_caster, m_spellInfo->Id, int32(effectInfo->EffectIndex));
}
void Spell::EffectApplyGlyph()