aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bindings/scripts/include/sc_instance.h9
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp5
-rw-r--r--src/game/Creature.cpp6
-rw-r--r--src/game/GameObject.cpp3
-rw-r--r--src/game/InstanceData.cpp89
-rw-r--r--src/game/InstanceData.h44
-rw-r--r--src/game/Map.cpp7
-rw-r--r--src/game/SpellAuras.cpp3
-rw-r--r--src/game/SpellEffects.cpp6
-rw-r--r--src/game/SpellMgr.cpp28
-rw-r--r--src/game/SpellMgr.h1
-rw-r--r--src/game/Unit.cpp11
-rw-r--r--src/game/Unit.h1
13 files changed, 179 insertions, 34 deletions
diff --git a/src/bindings/scripts/include/sc_instance.h b/src/bindings/scripts/include/sc_instance.h
index 42205f1ec34..cdf0e03aa37 100644
--- a/src/bindings/scripts/include/sc_instance.h
+++ b/src/bindings/scripts/include/sc_instance.h
@@ -8,15 +8,6 @@
#include "InstanceData.h"
#include "Map.h"
-enum EncounterState
-{
- NOT_STARTED = 0,
- IN_PROGRESS = 1,
- FAIL = 2,
- DONE = 3,
- SPECIAL = 4
-};
-
#define OUT_SAVE_INST_DATA debug_log("TSCR: Saving Instance Data for Instance %s (Map %d, Instance Id %d)", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
#define OUT_SAVE_INST_DATA_COMPLETE debug_log("TSCR: Saving Instance Data for Instance %s (Map %d, Instance Id %d) completed.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
#define OUT_LOAD_INST_DATA(a) debug_log("TSCR: Loading Instance Data for Instance %s (Map %d, Instance Id %d). Input is '%s'", instance->GetMapName(), instance->GetId(), instance->GetInstanceId(), a)
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp
index f9aa3200a6a..cac1d386c62 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp
@@ -250,9 +250,8 @@ struct TRINITY_DLL_DECL boss_fathomlord_karathressAI : public ScriptedAI
if (!target)
target = m_creature->getVictim();
- int32 dmg = target->GetMaxHealth() / 2;
- m_creature->CastCustomSpell(target, SPELL_CATACLYSMIC_BOLT, &dmg, NULL, NULL, false, NULL, NULL, m_creature->GetGUID());
-
+ if(target)
+ DoCast(target, SPELL_CATACLYSMIC_BOLT);
CataclysmicBolt_Timer = 10000;
}else CataclysmicBolt_Timer -= diff;
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index fc3e7ad7bac..d856c8b1f0f 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -184,7 +184,9 @@ void Creature::RemoveFromWorld()
{
if(IsInWorld())
{
- // Clear formation info
+ if(Map *map = FindMap())
+ if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
+ ((InstanceMap*)map)->GetInstanceData()->OnCreatureRemove(this);
if(m_formation)
formation_mgr.RemoveCreatureFromGroup(m_formation, this);
Unit::RemoveFromWorld();
@@ -1382,7 +1384,7 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const
//Notify the map's instance data.
//Only works if you create the object in it, not if it is moves to that map.
//Normally non-players do not teleport to other maps.
- Map *map = MapManager::Instance().FindMap(GetMapId(), GetInstanceId());
+ Map *map = FindMap();
if(map && map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
{
((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this, Entry);
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index 61e742735fb..54760a99b78 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -93,6 +93,9 @@ void GameObject::RemoveFromWorld()
///- Remove the gameobject from the accessor
if(IsInWorld())
{
+ if(Map *map = FindMap())
+ if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
+ ((InstanceMap*)map)->GetInstanceData()->OnObjectRemove(this);
// Possible crash at access to deleted GO in Unit::m_gameobj
if(uint64 owner_guid = GetOwnerGUID())
{
diff --git a/src/game/InstanceData.cpp b/src/game/InstanceData.cpp
index 785cea8f38c..45ff9862b7d 100644
--- a/src/game/InstanceData.cpp
+++ b/src/game/InstanceData.cpp
@@ -40,3 +40,92 @@ void InstanceData::HandleGameObject(uint64 GUID, bool open, GameObject *go)
debug_log("TSCR: InstanceData: HandleGameObject failed");
}
+bool InstanceData::IsEncounterInProgress() const
+{
+ for(std::vector<BossInfo>::const_iterator itr = bosses.begin(); itr != bosses.end(); ++itr)
+ if(itr->state == IN_PROGRESS)
+ return true;
+
+ return false;
+}
+
+void InstanceData::AddBossRoomDoor(uint32 id, GameObject *door)
+{
+ if(id < bosses.size())
+ {
+ BossInfo *bossInfo = &bosses[id];
+ bossInfo->roomDoor.insert(door);
+ // Room door is only closed when encounter is in progress
+ if(bossInfo->state == IN_PROGRESS)
+ door->SetGoState(1);
+ else
+ door->SetGoState(0);
+ }
+}
+
+void InstanceData::AddBossPassageDoor(uint32 id, GameObject *door)
+{
+ if(id < bosses.size())
+ {
+ BossInfo *bossInfo = &bosses[id];
+ bossInfo->passageDoor.insert(door);
+ // Passage door is only opened when boss is defeated
+ if(bossInfo->state == DONE)
+ door->SetGoState(0);
+ else
+ door->SetGoState(1);
+ }
+}
+
+void InstanceData::RemoveBossRoomDoor(uint32 id, GameObject *door)
+{
+ if(id < bosses.size())
+ {
+ bosses[id].roomDoor.erase(door);
+ }
+}
+
+void InstanceData::RemoveBossPassageDoor(uint32 id, GameObject *door)
+{
+ if(id < bosses.size())
+ {
+ bosses[id].passageDoor.erase(door);
+ }
+}
+
+void InstanceData::SetBossState(uint32 id, EncounterState state)
+{
+ if(id < bosses.size())
+ {
+ BossInfo *bossInfo = &bosses[id];
+
+ bossInfo->state = state;
+ switch(state)
+ {
+ case NOT_STARTED:
+ // Open all room doors, close all passage doors
+ for(DoorSet::iterator i = bossInfo->roomDoor.begin(); i != bossInfo->roomDoor.end(); ++i)
+ (*i)->SetGoState(0);
+ for(DoorSet::iterator i = bossInfo->passageDoor.begin(); i != bossInfo->passageDoor.end(); ++i)
+ (*i)->SetGoState(1);
+ break;
+ case IN_PROGRESS:
+ // Close all doors
+ for(DoorSet::iterator i = bossInfo->roomDoor.begin(); i != bossInfo->roomDoor.end(); ++i)
+ (*i)->SetGoState(1);
+ for(DoorSet::iterator i = bossInfo->passageDoor.begin(); i != bossInfo->passageDoor.end(); ++i)
+ (*i)->SetGoState(1);
+ break;
+ case DONE:
+ // Open all doors
+ for(DoorSet::iterator i = bossInfo->roomDoor.begin(); i != bossInfo->roomDoor.end(); ++i)
+ (*i)->SetGoState(0);
+ for(DoorSet::iterator i = bossInfo->passageDoor.begin(); i != bossInfo->passageDoor.end(); ++i)
+ (*i)->SetGoState(0);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
diff --git a/src/game/InstanceData.h b/src/game/InstanceData.h
index c33beccfffb..64fcec634ec 100644
--- a/src/game/InstanceData.h
+++ b/src/game/InstanceData.h
@@ -31,6 +31,24 @@ class Player;
class GameObject;
class Creature;
+enum EncounterState
+{
+ NOT_STARTED = 0,
+ IN_PROGRESS = 1,
+ FAIL = 2,
+ DONE = 3,
+ SPECIAL = 4
+};
+
+typedef std::set<GameObject*> DoorSet;
+
+struct BossInfo
+{
+ BossInfo() : state(NOT_STARTED) {}
+ EncounterState state;
+ DoorSet roomDoor, passageDoor;
+};
+
class TRINITY_DLL_SPEC InstanceData
{
public:
@@ -56,7 +74,7 @@ class TRINITY_DLL_SPEC InstanceData
//Used by the map's CanEnter function.
//This is to prevent players from entering during boss encounters.
- virtual bool IsEncounterInProgress() const { return false; };
+ virtual bool IsEncounterInProgress() const;
//Called when a player successfully enters the instance.
virtual void OnPlayerEnter(Player *) {}
@@ -67,6 +85,8 @@ class TRINITY_DLL_SPEC InstanceData
//called on creature creation
virtual void OnCreatureCreate(Creature * /*creature*/, uint32 /*creature_entry*/) {}
+ virtual void OnCreatureRemove(Creature*) {}
+ virtual void OnObjectRemove(GameObject*) {}
//All-purpose data storage 64 bit
virtual uint64 GetData64(uint32 /*Data*/) { return 0; }
virtual void SetData64(uint32 /*Data*/, uint64 /*Value*/) { }
@@ -78,7 +98,27 @@ class TRINITY_DLL_SPEC InstanceData
//Handle open / close objects
//use HandleGameObject(NULL,boolen,GO); in OnObjectCreate in instance scripts
//use HandleGameObject(GUID,boolen,NULL); in any other script
- virtual void HandleGameObject(uint64 GUID, bool open, GameObject *go = NULL);
+ void HandleGameObject(uint64 GUID, bool open, GameObject *go = NULL);
+
+ protected:
+ void AddBossRoomDoor(uint32 id, GameObject *door);
+ void AddBossPassageDoor(uint32 id, GameObject *door);
+ void RemoveBossRoomDoor(uint32 id, GameObject *door);
+ void RemoveBossPassageDoor(uint32 id, GameObject *door);
+
+ void SetBossState(uint32 id, EncounterState state);
+
+ std::string GetBossSave()
+ {
+ std::ostringstream saveStream;
+ for(std::vector<BossInfo>::iterator i = bosses.begin(); i != bosses.end(); ++i)
+ saveStream << (uint32)i->state << " ";
+ return saveStream.str();
+ }
+
+ private:
+ std::vector<BossInfo> bosses;
+
};
#endif
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 0989c4b4dab..b6aae4131d5 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -2429,6 +2429,8 @@ void InstanceMap::CreateInstanceData(bool load)
if(!i_data)
return;
+ i_data->Initialize();
+
if(load)
{
// TODO: make a global storage for this
@@ -2445,11 +2447,6 @@ void InstanceMap::CreateInstanceData(bool load)
delete result;
}
}
- else
- {
- sLog.outDebug("New instance data, \"%s\" ,initialized!", objmgr.GetScriptName(i_script_id));
- i_data->Initialize();
- }
}
/*
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index fa3e6ef937a..0f3056e043d 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -2975,8 +2975,7 @@ void AuraEffect::HandleAuraModShapeshift(bool apply, bool Real)
case FORM_FLIGHT:
case FORM_MOONKIN:
// remove movement affects
- m_target->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
- m_target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
+ m_target->RemoveMovementImpairingAuras();
// and polymorphic affects
if(m_target->IsPolymorphed())
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index abac18f7a79..0eab6a025fa 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -2930,6 +2930,8 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
return;
Script->GOHello(player, gameObjTarget);
+ sWorld.ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget);
+
gameObjTarget->AddUniqueUse(player);
gameObjTarget->SetLootState(GO_JUST_DEACTIVATED);
@@ -2943,10 +2945,6 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
if(uint32 trapEntry = gameObjTarget->GetGOInfo()->goober.linkedTrapId)
gameObjTarget->TriggeringLinkedGameObject(trapEntry,m_caster);
- // activate GO scripts
- Script->GOHello(player, gameObjTarget);
- sWorld.ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget);
-
return;
case GAMEOBJECT_TYPE_CHEST:
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index a22441614af..e3dfaf50477 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -2309,13 +2309,12 @@ void SpellMgr::LoadSpellCustomAttr()
case SPELL_AURA_OBS_MOD_HEALTH:
mSpellCustomAttr[i] |= SPELL_ATTR_CU_AURA_HOT;
break;
- case SPELL_AURA_MOD_POSSESS:
- case SPELL_AURA_MOD_CONFUSE:
- case SPELL_AURA_MOD_CHARM:
- case SPELL_AURA_MOD_FEAR:
- case SPELL_AURA_MOD_STUN:
case SPELL_AURA_MOD_ROOT:
mSpellCustomAttr[i] |= SPELL_ATTR_CU_AURA_CC;
+ mSpellCustomAttr[i] |= SPELL_ATTR_CU_MOVEMENT_IMPAIR;
+ break;
+ case SPELL_AURA_MOD_DECREASE_SPEED:
+ mSpellCustomAttr[i] |= SPELL_ATTR_CU_MOVEMENT_IMPAIR;
break;
default:
break;
@@ -2343,16 +2342,31 @@ void SpellMgr::LoadSpellCustomAttr()
spellInfo->Effect[j] = SPELL_EFFECT_TRIGGER_MISSILE;
break;
}
-
+
switch(SpellTargetType[spellInfo->EffectImplicitTargetA[j]])
{
case TARGET_TYPE_UNIT_TARGET:
case TARGET_TYPE_DEST_TARGET:
spellInfo->Targets |= TARGET_FLAG_UNIT;
break;
- }
+ }
}
+ for(uint32 j = 0; j < 3; ++j)
+ {
+ switch(spellInfo->EffectApplyAuraName[j])
+ {
+ case SPELL_AURA_MOD_POSSESS:
+ case SPELL_AURA_MOD_CONFUSE:
+ case SPELL_AURA_MOD_CHARM:
+ case SPELL_AURA_MOD_FEAR:
+ case SPELL_AURA_MOD_STUN:
+ mSpellCustomAttr[i] |= SPELL_ATTR_CU_AURA_CC;
+ mSpellCustomAttr[i] &= ~SPELL_ATTR_CU_MOVEMENT_IMPAIR;
+ break;
+ }
+ }
+
if(spellInfo->SpellVisual[0] == 3879)
mSpellCustomAttr[i] |= SPELL_ATTR_CU_CONE_BACK;
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 5f5fe37ec02..8913eb84c2a 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -661,6 +661,7 @@ inline bool IsProfessionSkill(uint32 skill)
#define SPELL_ATTR_CU_LINK_HIT 0x00000800
#define SPELL_ATTR_CU_LINK_AURA 0x00001000
#define SPELL_ATTR_CU_LINK_REMOVE 0x00002000
+#define SPELL_ATTR_CU_MOVEMENT_IMPAIR 0x00004000
typedef std::vector<uint32> SpellCustomAttribute;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 70a6c461f4a..b509bb0226c 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -452,6 +452,17 @@ void Unit::GetRandomContactPoint( const Unit* obj, float &x, float &y, float &z,
, GetAngle(obj) + (attacker_number ? (M_PI/2 - M_PI * rand_norm()) * (float)attacker_number / combat_reach / 3 : 0));
}
+void Unit::RemoveMovementImpairingAuras()
+{
+ for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
+ {
+ if(spellmgr.GetSpellCustomAttr(iter->second->GetId()) & SPELL_ATTR_CU_MOVEMENT_IMPAIR)
+ RemoveAura(iter);
+ else
+ ++iter;
+ }
+}
+
void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
{
if(!(m_interruptMask & flag))
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 8e008e1357e..7dceb66f5b1 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1305,6 +1305,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void RemoveNotOwnSingleTargetAuras();
bool RemoveNoStackAurasDueToAura(Aura *Aur);
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = NULL);
+ void RemoveMovementImpairingAuras();
void RemoveAllAuras();
void RemoveArenaAuras(bool onleave = false);
void RemoveAllAurasOnDeath();