diff options
Diffstat (limited to 'src')
64 files changed, 1256 insertions, 621 deletions
diff --git a/src/bindings/scripts/Makefile.am b/src/bindings/scripts/Makefile.am index 74e1674619a..87cdb11db0a 100644 --- a/src/bindings/scripts/Makefile.am +++ b/src/bindings/scripts/Makefile.am @@ -381,6 +381,7 @@ scripts/zone/uldaman/instance_uldaman.cpp \ scripts/zone/uldaman/boss_ironaya.cpp \ scripts/zone/uldaman/uldaman.cpp \ scripts/zone/undercity/undercity.cpp \ +scripts/zone/ungoro_crater/ungoro_crater.cpp \ scripts/zone/wailing_caverns/instance_wailing_caverns.cpp \ scripts/zone/western_plaguelands/western_plaguelands.cpp \ scripts/zone/westfall/westfall.cpp \ diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp index a4d75f6aeb2..bcd7ec54a54 100644 --- a/src/bindings/scripts/ScriptMgr.cpp +++ b/src/bindings/scripts/ScriptMgr.cpp @@ -563,6 +563,8 @@ extern void AddSC_instance_uldaman(); extern void AddSC_undercity(); //Un'Goro Crater +extern void AddSC_ungoro_crater(); + //Upper blackrock spire //Wailing caverns @@ -1770,6 +1772,8 @@ void ScriptsInit() AddSC_undercity(); //Un'Goro Crater + AddSC_ungoro_crater(); + //Upper blackrock spire //Wailing caverns diff --git a/src/bindings/scripts/VC71/71ScriptDev2.vcproj b/src/bindings/scripts/VC71/71ScriptDev2.vcproj index a9ed124ebec..2559d4a9bff 100644 --- a/src/bindings/scripts/VC71/71ScriptDev2.vcproj +++ b/src/bindings/scripts/VC71/71ScriptDev2.vcproj @@ -1236,6 +1236,10 @@ <Filter Name="Un'Goro Crater" > + <File + RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp" + > + </File> </Filter> <Filter Name="Aunchindoun" diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj index 5d84995e2ed..1c7bbd6e3c0 100644 --- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj +++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj @@ -1498,6 +1498,10 @@ <Filter Name="Un'Goro Crater" > + <File + RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp" + > + </File> </Filter> <Filter Name="Aunchindoun" diff --git a/src/bindings/scripts/VC90/90ScriptDev2.vcproj b/src/bindings/scripts/VC90/90ScriptDev2.vcproj index 635c7c67bf9..8dfa9aafe8c 100644 --- a/src/bindings/scripts/VC90/90ScriptDev2.vcproj +++ b/src/bindings/scripts/VC90/90ScriptDev2.vcproj @@ -1518,6 +1518,10 @@ <Filter Name="Un'Goro Crater" > + <File + RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp" + > + </File> </Filter> <Filter Name="Aunchindoun" diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 20c5600dc02..12992eedc52 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -711,11 +711,23 @@ void ScriptedAI::DoResetThreat() { Unit* pUnit = NULL; pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid()); - if(pUnit && m_creature->getThreatManager().getThreat(pUnit)) - m_creature->getThreatManager().modifyThreatPercent(pUnit, -100); + if(pUnit && DoGetThreat(pUnit)) + DoModifyThreatPercent(pUnit, -100); } } +float ScriptedAI::DoGetThreat(Unit* pUnit) +{ + if(!pUnit) return 0.0f; + return m_creature->getThreatManager().getThreat(pUnit); +} + +void ScriptedAI::DoModifyThreatPercent(Unit *pUnit, int32 pct) +{ + if(!pUnit) return; + m_creature->getThreatManager().modifyThreatPercent(pUnit, pct); +} + void ScriptedAI::DoTeleportPlayer(Unit* pUnit, float x, float y, float z, float o) { if(!pUnit || pUnit->GetTypeId() != TYPEID_PLAYER) diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 9c7ffc022eb..12ec3f0cbf5 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -144,6 +144,9 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI //Drops all threat to 0%. Does not remove players from the threat list void DoResetThreat(); + float DoGetThreat(Unit *u); + void DoModifyThreatPercent(Unit *pUnit, int32 pct); + //Teleports a player without dropping threat (only teleports to same map) void DoTeleportPlayer(Unit* pUnit, float x, float y, float z, float o); void DoTeleportAll(float x, float y, float z, float o); diff --git a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp index d764fb02c2e..456a88ab3bb 100644 --- a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp +++ b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp @@ -684,7 +684,7 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI Unit* target = GetTargetByType(param2, pActionInvoker); if (target) - m_creature->getThreatManager().modifyThreatPercent(target, param1); + DoModifyThreatPercent(target, param1); } break; case ACTION_T_THREAT_ALL_PCT: @@ -696,7 +696,7 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI { Temp = Unit::GetUnit((*m_creature),(*i)->getUnitGuid()); if (Temp) - m_creature->getThreatManager().modifyThreatPercent(Temp, param1); + DoModifyThreatPercent(Temp, param1); } } break; diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp index bbffd9db814..567c9302704 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp @@ -189,8 +189,8 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI pUnit = Unit::GetUnit((*m_creature), guid); if(pUnit) { - if(m_creature->getThreatManager().getThreat(pUnit)) - m_creature->getThreatManager().modifyThreatPercent(pUnit, -100); + if(DoGetThreat(pUnit)) + DoModifyThreatPercent(pUnit, -100); if(TargetThreat) m_creature->AddThreat(pUnit, TargetThreat); } @@ -231,7 +231,7 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI if(BewilderingStrikeTimer < diff) { DoCast(m_creature->getVictim(), SPELL_BEWILDERING_STRIKE); - float mt_threat = m_creature->getThreatManager().getThreat(m_creature->getVictim()); + float mt_threat = DoGetThreat(m_creature->getVictim()); if (Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 1)) m_creature->AddThreat(target, mt_threat); BewilderingStrikeTimer = 20000; @@ -240,7 +240,7 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI if(EjectTimer < diff) { DoCast(m_creature->getVictim(), SPELL_EJECT1); - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(), -40); + DoModifyThreatPercent(m_creature->getVictim(), -40); EjectTimer = 15000; }else EjectTimer -= diff; @@ -286,11 +286,11 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI { Phase1 = false; - TargetThreat = m_creature->getThreatManager().getThreat(target); + TargetThreat = DoGetThreat(target); TargetGUID = target->GetGUID(); target->CastSpell(m_creature, SPELL_TAUNT_GURTOGG, true); - if(m_creature->getThreatManager().getThreat(target)) - m_creature->getThreatManager().modifyThreatPercent(target, -100); + if(DoGetThreat(target)) + DoModifyThreatPercent(target, -100); m_creature->AddThreat(target, 50000000.0f); // If VMaps are disabled, this spell can call the whole instance DoCast(m_creature, SPELL_INSIGNIFIGANCE, true); diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp index 4f01ea56348..133978d8b00 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp @@ -316,7 +316,7 @@ struct TRINITY_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid()); if(pUnit && pUnit->isAlive()) { - float threat = m_creature->getThreatManager().getThreat(pUnit); + float threat = DoGetThreat(pUnit); Blossom->AddThreat(pUnit, threat); } } diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp index 470f9152152..560adc63011 100644 --- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp +++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp @@ -104,8 +104,8 @@ struct TRINITY_DLL_DECL boss_broodlordAI : public ScriptedAI { DoCast(m_creature->getVictim(),SPELL_KNOCKBACK); //Drop 50% aggro - if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50); + if (DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-50); KnockBack_Timer = 15000 + rand()%15000; }else KnockBack_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp index dbc5d2bf9a3..532657e3063 100644 --- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp +++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp @@ -63,8 +63,8 @@ struct TRINITY_DLL_DECL boss_firemawAI : public ScriptedAI if (WingBuffet_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_WINGBUFFET); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-75); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-75); WingBuffet_Timer = 25000; }else WingBuffet_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp index 9ff952bb4da..5af096fa4ac 100644 --- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp +++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp @@ -65,8 +65,8 @@ struct TRINITY_DLL_DECL boss_flamegorAI : public ScriptedAI if (WingBuffet_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_WINGBUFFET); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-75); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-75); WingBuffet_Timer = 25000; }else WingBuffet_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp index e079ef35e95..e706a22ff6e 100644 --- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp +++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp @@ -97,8 +97,8 @@ struct TRINITY_DLL_DECL boss_razorgoreAI : public ScriptedAI DoCast(m_creature->getVictim(),SPELL_CONFLAGRATION); //We will remove this threat reduction and add an aura check. - //if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - //m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50); + //if(DoGetThreat(m_creature->getVictim())) + //DoModifyThreatPercent(m_creature->getVictim(),-50); Conflagration_Timer = 12000; }else Conflagration_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp index 7a61d678bff..b1bb9b9e63a 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp @@ -291,7 +291,7 @@ struct TRINITY_DLL_DECL mob_doomfire_targettingAI : public ScriptedAI target = SelectUnit(SELECT_TARGET_RANDOM, 1); if(target && target->isAlive()) { - m_creature->AddThreat(target, m_creature->getThreatManager().getThreat(m_creature->getVictim())); + m_creature->AddThreat(target, DoGetThreat(m_creature->getVictim())); m_creature->GetMotionMaster()->MoveChase(target); } break; @@ -469,7 +469,7 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public ScriptedAI if(!m_creature->IsWithinDistInMap(target, m_creature->GetAttackDistance(target))) return true; // Cast Finger of Death else // This target is closest, he is our new tank - m_creature->AddThreat(target, m_creature->getThreatManager().getThreat(m_creature->getVictim())); + m_creature->AddThreat(target, DoGetThreat(m_creature->getVictim())); } return false; diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp index 833bb03bce2..a44231dc1b3 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp @@ -101,7 +101,7 @@ struct TRINITY_DLL_DECL mob_inner_demonAI : public ScriptedAI if(done_by->GetGUID() != victimGUID && done_by->GetGUID() != m_creature->GetGUID()) { damage = 0; - m_creature->getThreatManager().modifyThreatPercent(done_by, -100); + DoModifyThreatPercent(done_by, -100); } } @@ -343,7 +343,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI if( pUnit_target && pUnit_target->isAlive()) { pUnit->CastSpell(pUnit_target, SPELL_CONSUMING_MADNESS, true); - m_creature->getThreatManager().modifyThreatPercent(pUnit_target, -100); + DoModifyThreatPercent(pUnit_target, -100); } } } diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp index 08ee10967a1..4c644f4af65 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp @@ -519,7 +519,7 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI if(axe) { float threat = 1000000.0f; - if(axe->getVictim() && m_creature->getThreatManager().getThreat(axe->getVictim())) + if(axe->getVictim() && DoGetThreat(axe->getVictim())) { threat = axe->getThreatManager().getThreat(axe->getVictim()); axe->getThreatManager().modifyThreatPercent(axe->getVictim(), -100); diff --git a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp index 7f7dd02961b..5574ce20128 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp @@ -795,9 +795,9 @@ struct TRINITY_DLL_DECL boss_bigbadwolfAI : public ScriptedAI DoScriptText(SAY_WOLF_HOOD, m_creature); DoCast(target, SPELL_LITTLE_RED_RIDING_HOOD, true); - TempThreat = m_creature->getThreatManager().getThreat(target); + TempThreat = DoGetThreat(target); if(TempThreat) - m_creature->getThreatManager().modifyThreatPercent(target, -100); + DoModifyThreatPercent(target, -100); HoodGUID = target->GetGUID(); m_creature->AddThreat(target, 1000000.0f); ChaseTimer = 20000; @@ -811,8 +811,8 @@ struct TRINITY_DLL_DECL boss_bigbadwolfAI : public ScriptedAI if(target) { HoodGUID = 0; - if(m_creature->getThreatManager().getThreat(target)) - m_creature->getThreatManager().modifyThreatPercent(target, -100); + if(DoGetThreat(target)) + DoModifyThreatPercent(target, -100); m_creature->AddThreat(target, TempThreat); TempThreat = 0; } diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp index 6c11ac87c29..a2219096968 100644 --- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp +++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp @@ -187,7 +187,7 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid()); if(pUnit && pUnit->isAlive()) { - float threat = m_creature->getThreatManager().getThreat(pUnit); + float threat = DoGetThreat(pUnit); SummonedUnit->AddThreat(pUnit, 0.1f); } } diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp index fcfc36c5ec4..a0ffe784c6c 100644 --- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp +++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp @@ -508,7 +508,7 @@ struct TRINITY_DLL_DECL boss_kagani_nightstrikeAI : public boss_priestess_guestA if(Gouge_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_GOUGE); - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100); + DoModifyThreatPercent(m_creature->getVictim(),-100); Gouge_Timer = 5500; }else Gouge_Timer -= diff; @@ -758,7 +758,7 @@ struct TRINITY_DLL_DECL boss_yazzaiAI : public boss_priestess_guestAI if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_POLYMORPH); - m_creature->getThreatManager().modifyThreatPercent(target,-100); + DoModifyThreatPercent(target,-100); Polymorph_Timer = 20000; } }else Polymorph_Timer -= diff; @@ -1022,7 +1022,7 @@ struct TRINITY_DLL_DECL boss_garaxxasAI : public boss_priestess_guestAI if(Freezing_Trap_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_FREEZING_TRAP); - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100); + DoModifyThreatPercent(m_creature->getVictim(),-100); Freezing_Trap_Timer = 30000; }else Freezing_Trap_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp index 540128a92c4..93002e53976 100644 --- a/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp +++ b/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp @@ -105,8 +105,8 @@ struct TRINITY_DLL_DECL boss_darkmaster_gandlingAI : public ScriptedAI target = SelectUnit(SELECT_TARGET_RANDOM,0); if (target && target->GetTypeId() == TYPEID_PLAYER) { - if(m_creature->getThreatManager().getThreat(target)) - m_creature->getThreatManager().modifyThreatPercent(target, -100); + if(DoGetThreat(target)) + DoModifyThreatPercent(target, -100); switch(rand()%6) { diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp index 31f1b90aa3f..b0168a506a0 100644 --- a/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp +++ b/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp @@ -115,7 +115,7 @@ struct TRINITY_DLL_DECL boss_jandicebarovAI : public ScriptedAI m_creature->setFaction(35); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,11686); // Invisible Model - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-99); + DoModifyThreatPercent(m_creature->getVictim(),-99); //Summon 10 Illusions attacking random gamers Unit* target = NULL; diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp index 16d56dd99f1..6b00ce594f4 100644 --- a/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp +++ b/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp @@ -247,8 +247,8 @@ struct TRINITY_DLL_DECL boss_dathrohan_balnazzarAI : public ScriptedAI if (rand()%100 < 60) //60% chance to cast { DoCast(m_creature->getVictim(),SPELL_PSYCHICSCREAM); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-50); } //15 seconds until we should cast this again PsychicScream_Timer = 20000; diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp index f8512982ead..2f52eef8c05 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp @@ -139,8 +139,8 @@ struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI DoCast(m_creature->getVictim(),SPELL_KNOCK_AWAY); //Drop 25% aggro - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-25); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-25); KnockAway_Timer = 30000; }else KnockAway_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp index 387c40c17f1..8f06423482f 100644 --- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp +++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp @@ -187,8 +187,8 @@ struct TRINITY_DLL_DECL boss_vemAI : public ScriptedAI if (KnockBack_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_KNOCKBACK); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-80); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-80); KnockBack_Timer = 15000 + rand()%10000; }else KnockBack_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp index a9164b90876..34dd5c7c30e 100644 --- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp +++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp @@ -127,8 +127,8 @@ struct TRINITY_DLL_DECL boss_fankrissAI : public ScriptedAI { DoCast(target, SPELL_ROOT); - if(m_creature->getThreatManager().getThreat(target)) - m_creature->getThreatManager().modifyThreatPercent(target, -100); + if(DoGetThreat(target)) + DoModifyThreatPercent(target, -100); switch(rand()%3) { diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp index 356fd85ef68..461f41de6eb 100644 --- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp +++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp @@ -116,7 +116,7 @@ struct TRINITY_DLL_DECL boss_twinemperorsAI : public ScriptedAI if (ohealth <= 0) { pOtherBoss->setDeathState(JUST_DIED); - pOtherBoss->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); } } } @@ -128,7 +128,7 @@ struct TRINITY_DLL_DECL boss_twinemperorsAI : public ScriptedAI { pOtherBoss->SetHealth(0); pOtherBoss->setDeathState(JUST_DIED); - pOtherBoss->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); ((boss_twinemperorsAI *)pOtherBoss->AI())->DontYellWhenDead = true; } if (!DontYellWhenDead) // I hope AI is not threaded diff --git a/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp b/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp index bcd2d8994e7..47ba4a33e1d 100644 --- a/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp +++ b/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: Terokkar_Forest SD%Complete: 80 -SDComment: Quest support: 9889(test script only, sql inside script), 10009, 10873, 10896, 11096. Skettis->Ogri'la Flight +SDComment: Quest support: 9889, 10009, 10873, 10896, 11096, 10052, 10051. Skettis->Ogri'la Flight SDCategory: Terokkar Forest EndScriptData */ @@ -28,9 +28,11 @@ mob_rotting_forest_rager mob_netherweb_victim npc_floon npc_skyguard_handler_deesak +npc_isla_starmane EndContentData */ #include "precompiled.h" +#include "../../npc/npc_escortAI.h" /*###### ## mob_unkor_the_ruthless @@ -354,9 +356,138 @@ bool GossipSelect_npc_skyguard_handler_deesak(Player *player, Creature *_Creatur } /*###### -## AddSC +## npc_isla_starmane ######*/ +#define SAY_PROGRESS_1 "Ok let's get out of here!" +#define SAY_PROGRESS_2 "You sure you're ready? Take a moment." +#define SAY_PROGRESS_3 "Alright, let's do this!" +#define SAY_PROGRESS_4 "Ok, I think I can make it on my own from here. Thank you so much for breaking me out of there!" + +#define QUEST_EFTW_H 10052 +#define QUEST_EFTW_A 10051 +#define GO_CAGE 182794 +#define SPELL_CAT 32447 + +struct TRINITY_DLL_DECL npc_isla_starmaneAI : public npc_escortAI +{ + npc_isla_starmaneAI(Creature* c) : npc_escortAI(c) {Reset();} + + bool Completed; + + void WaypointReached(uint32 i) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + if(!player) + return; + + switch(i) + { + case 0: + { + GameObject* Cage = FindGameObject(GO_CAGE, 99); + if(Cage) + Cage->SetGoState(0); + }break; + case 2: DoSay(SAY_PROGRESS_1, LANG_UNIVERSAL, player); break; + case 5: DoSay(SAY_PROGRESS_2, LANG_UNIVERSAL, player); break; + case 6: DoSay(SAY_PROGRESS_3, LANG_UNIVERSAL, player); break; + case 29:DoSay(SAY_PROGRESS_4, LANG_UNIVERSAL, player); + if (player) + { + if(((Player*)player)->GetTeam() == ALLIANCE) + ((Player*)player)->GroupEventHappens(QUEST_EFTW_A, m_creature); + else if(((Player*)player)->GetTeam() == HORDE) + ((Player*)player)->GroupEventHappens(QUEST_EFTW_H, m_creature); + } Completed = true; + m_creature->SetInFront(player); break; + case 30: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); break; + case 31: DoCast(m_creature, SPELL_CAT); + m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); break; + } + } + + void Reset() + { + Completed = false; + } + + void Aggro(Unit* who){} + + void JustDied(Unit* killer) + { + if (PlayerGUID) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + if (player && !Completed) + { + if(((Player*)player)->GetTeam() == ALLIANCE) + ((Player*)player)->FailQuest(QUEST_EFTW_A); + else if(((Player*)player)->GetTeam() == HORDE) + ((Player*)player)->FailQuest(QUEST_EFTW_H); + } + } + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } +}; + +bool QuestAccept_npc_isla_starmane(Player* player, Creature* creature, Quest const* quest) +{ + if (quest->GetQuestId() == QUEST_EFTW_H || quest->GetQuestId() == QUEST_EFTW_A) + { + ((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID()); + } + return true; +} + +CreatureAI* GetAI_npc_isla_starmaneAI(Creature *_Creature) +{ + npc_isla_starmaneAI* thisAI = new npc_isla_starmaneAI(_Creature); + + thisAI->AddWaypoint(0, -2265.21, 3091.14, 13.91); + thisAI->AddWaypoint(1, -2266.80, 3091.33, 13.82, 1000); + thisAI->AddWaypoint(2, -2268.20, 3091.14, 13.82, 7000);//progress1 + thisAI->AddWaypoint(3, -2278.32, 3098.98, 13.82); + thisAI->AddWaypoint(4, -2294.82, 3110.59, 13.82); + thisAI->AddWaypoint(5, -2300.71, 3114.60, 13.82, 20000);//progress2 + thisAI->AddWaypoint(6, -2300.71, 3114.60, 13.82, 3000);//progress3 + thisAI->AddWaypoint(7, -2307.36, 3122.76, 13.79); + thisAI->AddWaypoint(8, -2312.83, 3130.55, 12.04); + thisAI->AddWaypoint(9, -2345.02, 3151.00, 8.38); + thisAI->AddWaypoint(10, -2351.97, 3157.61, 6.27); + thisAI->AddWaypoint(11, -2360.35, 3171.48, 3.31); + thisAI->AddWaypoint(12, -2371.44, 3185.41, 0.89); + thisAI->AddWaypoint(13, -2371.21, 3197.92, -0.96); + thisAI->AddWaypoint(14, -2380.35, 3210.45, -1.08); + thisAI->AddWaypoint(15, -2384.74, 3221.25, -1.17); + thisAI->AddWaypoint(16, -2386.15, 3233.39, -1.29); + thisAI->AddWaypoint(17, -2383.45, 3247.79, -1.32); + thisAI->AddWaypoint(18, -2367.50, 3265.64, -1.33); + thisAI->AddWaypoint(19, -2354.90, 3273.30, -1.50); + thisAI->AddWaypoint(20, -2348.88, 3280.58, -0.09); + thisAI->AddWaypoint(21, -2349.06, 3295.86, -0.95); + thisAI->AddWaypoint(22, -2350.43, 3328.27, -2.10); + thisAI->AddWaypoint(23, -2346.76, 3356.27, -2.82); + thisAI->AddWaypoint(24, -2340.56, 3370.68, -4.02); + thisAI->AddWaypoint(25, -2318.84, 3384.60, -7.61); + thisAI->AddWaypoint(26, -2313.99, 3398.61, -10.40); + thisAI->AddWaypoint(27, -2320.85, 3414.49, -11.49); + thisAI->AddWaypoint(28, -2338.26, 3426.06, -11.46); + thisAI->AddWaypoint(29, -2342.67, 3439.44, -11.32, 12000);//progress4 + thisAI->AddWaypoint(30, -2342.67, 3439.44, -11.32, 7000);//emote bye + thisAI->AddWaypoint(31, -2342.67, 3439.44, -11.32, 5000);//cat form + thisAI->AddWaypoint(32, -2344.60, 3461.27, -10.44); + thisAI->AddWaypoint(33, -2396.81, 3517.17, -3.55); + thisAI->AddWaypoint(34, -2439.23, 3523.00, -1.05); + + return (CreatureAI*)thisAI; +} + void AddSC_terokkar_forest() { Script *newscript; @@ -392,4 +523,10 @@ void AddSC_terokkar_forest() newscript->pGossipHello = &GossipHello_npc_skyguard_handler_deesak; newscript->pGossipSelect = &GossipSelect_npc_skyguard_handler_deesak; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name= "npc_isla_starmane"; + newscript->GetAI = &GetAI_npc_isla_starmaneAI; + newscript->pQuestAccept = &QuestAccept_npc_isla_starmane; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp b/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp new file mode 100644 index 00000000000..51cb2b4456d --- /dev/null +++ b/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp @@ -0,0 +1,208 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* ScriptData +SDName: Ungoro Crater +SD%Complete: 100 +SDComment: Support for Quest: 4245 +SDCategory: Ungoro Crater +EndScriptData */ + +/* ContentData +npc_a-me +EndContentData */ + +#include "precompiled.h" +#include "../../npc/npc_escortAI.h" + +#define SAY_READY -1000200 +#define SAY_AGGRO1 -1000201 +#define SAY_SEARCH -1000202 +#define SAY_AGGRO2 -1000203 +#define SAY_AGGRO3 -1000204 +#define SAY_FINISH -1000205 + +#define SPELL_DEMORALIZINGSHOUT 13730 + +#define QUEST_CHASING_AME 4245 +#define ENTRY_TARLORD 6519 +#define ENTRY_TARLORD1 6519 +#define ENTRY_STOMPER 6513 + + +struct TRINITY_DLL_DECL npc_ameAI : public npc_escortAI +{ + npc_ameAI(Creature *c) : npc_escortAI(c) {Reset();} + + uint32 DEMORALIZINGSHOUT_Timer; + + void WaypointReached(uint32 i) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + if (!player) + return; + + switch (i) + { + + case 19: + m_creature->SummonCreature(ENTRY_STOMPER, -6391.69, -1730.49, -272.83, 4.96, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + DoScriptText(SAY_AGGRO1, m_creature, player); + break; + case 28: + DoScriptText(SAY_SEARCH, m_creature, player); + break; + case 38: + m_creature->SummonCreature(ENTRY_TARLORD, -6370.75, -1382.84, -270.51, 6.06, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + DoScriptText(SAY_AGGRO2, m_creature, player); + break; + case 49: + m_creature->SummonCreature(ENTRY_TARLORD1, -6324.44, -1181.05, -270.17, 4.34, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + DoScriptText(SAY_AGGRO3, m_creature, player); + break; + case 55: + DoScriptText(SAY_FINISH, m_creature, player); + if (player && player->GetTypeId() == TYPEID_PLAYER) + ((Player*)player)->GroupEventHappens(QUEST_CHASING_AME,m_creature); + break; + + } + } + + void Reset() + { + DEMORALIZINGSHOUT_Timer = 5000; + } + + void Aggro(Unit* who) + {} + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(m_creature); + } + + void JustDied(Unit* killer) + { + if (PlayerGUID) + { + if (Unit* player = Unit::GetUnit((*m_creature), PlayerGUID)) + ((Player*)player)->FailQuest(QUEST_CHASING_AME); + } + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) + return; + + if (DEMORALIZINGSHOUT_Timer < diff) + { + DoCast(m_creature->getVictim(),SPELL_DEMORALIZINGSHOUT); + DEMORALIZINGSHOUT_Timer = 70000; + }else DEMORALIZINGSHOUT_Timer -= diff; + + } +}; + +bool QuestAccept_npc_ame(Player* player, Creature* creature, Quest const* quest) +{ + if (quest->GetQuestId() == QUEST_CHASING_AME) + { + ((npc_escortAI*)(creature->AI()))->Start(false, true, false, player->GetGUID()); + DoScriptText(SAY_READY, creature, player); + // Change faction so mobs attack + creature->setFaction(775); + } + return true; +} + +CreatureAI* GetAI_npc_ame(Creature *_Creature) +{ + npc_ameAI* thisAI = new npc_ameAI(_Creature); + + thisAI->AddWaypoint(1, -6380.38, -1965.14, -258.292, 5000); + thisAI->AddWaypoint(2, -6383.06, -1962.9, -258.936); + thisAI->AddWaypoint(3, -6391.09, -1956.13, -260.291); + thisAI->AddWaypoint(4, -6395.29, -1933.58, -262.949); + thisAI->AddWaypoint(5, -6396.58, -1919.93, -263.838); + thisAI->AddWaypoint(6, -6389.01, -1912.64, -260.689); + thisAI->AddWaypoint(7, -6369.19, -1892.87, -255.924); + thisAI->AddWaypoint(8, -6373.77, -1879.36, -259.268); + thisAI->AddWaypoint(9, -6377.55, -1869.56, -260.503); + thisAI->AddWaypoint(10, -6376.58, -1860.79, -260.026); + thisAI->AddWaypoint(11, -6373.13, -1847.22, -259.249); + thisAI->AddWaypoint(12, -6370.54, -1837.04, -260.007); + thisAI->AddWaypoint(13, -6372.52, -1829.16, -260.071); + thisAI->AddWaypoint(14, -6377.13, -1815.94, -262.632); + thisAI->AddWaypoint(15, -6380.27, -1806.95, -265.53); + thisAI->AddWaypoint(16, -6386.04, -1790.43, -268.546); + thisAI->AddWaypoint(17, -6386.72, -1776.29, -269.851); + thisAI->AddWaypoint(18, -6385.92, -1762.31, -271.494); + thisAI->AddWaypoint(19, -6384.69, -1744.86, -272.196); + thisAI->AddWaypoint(20, -6383.8, -1732.66, -272.222); + thisAI->AddWaypoint(21, -6382.66, -1716.96, -272.235); + thisAI->AddWaypoint(22, -6381.5, -1703.01, -272.964); + thisAI->AddWaypoint(23, -6379.96, -1685.58, -272.842); + thisAI->AddWaypoint(24, -6379.34, -1678.61, -272.34); + thisAI->AddWaypoint(25, -6364.45, -1636.27, -271.065); + thisAI->AddWaypoint(26, -6371.85, -1626.36, -272.188); + thisAI->AddWaypoint(27, -6383.5, -1629.01, -272.206); + thisAI->AddWaypoint(28, -6388.09, -1635.37, -272.105, 5000); + thisAI->AddWaypoint(29, -6375.42, -1637.33, -272.193); + thisAI->AddWaypoint(30, -6365.46, -1617.25, -272.141); + thisAI->AddWaypoint(31, -6353.79, -1603.48, -271.932); + thisAI->AddWaypoint(32, -6340.24, -1592.41, -269.435); + thisAI->AddWaypoint(33, -6329.45, -1566.89, -269.895); + thisAI->AddWaypoint(34, -6312.2, -1499.06, -269.507); + thisAI->AddWaypoint(35, -6304.55, -1468.5, -269.431); + thisAI->AddWaypoint(36, -6310.36, -1440.94, -268.427); + thisAI->AddWaypoint(37, -6321, -1418.91, -266.525); + thisAI->AddWaypoint(38, -6358.76, -1389.97, -267.522); + thisAI->AddWaypoint(39, -6378.65, -1375.67, -271.749); + thisAI->AddWaypoint(40, -6387.22, -1360.95, -272.109); + thisAI->AddWaypoint(41, -6406.95, -1323.87, -271.586); + thisAI->AddWaypoint(42, -6405, -1311.92, -271.906); + thisAI->AddWaypoint(43, -6395.56, -1303.62, -271.902); + thisAI->AddWaypoint(44, -6375.97, -1296.08, -271.865); + thisAI->AddWaypoint(45, -6364.39, -1281.23, -269.012); + thisAI->AddWaypoint(46, -6353.71, -1263.19, -267.95); + thisAI->AddWaypoint(47, -6340.09, -1248.65, -267.441); + thisAI->AddWaypoint(48, -6338.21, -1237.11, -267.844); + thisAI->AddWaypoint(49, -6336.6, -1219.69, -269.196); + thisAI->AddWaypoint(50, -6334.44, -1202.33, -271.527); + thisAI->AddWaypoint(51, -6329.56, -1189.82, -270.947); + thisAI->AddWaypoint(52, -6324.66, -1179.46, -270.103); + thisAI->AddWaypoint(53, -6315.08, -1176.74, -269.735); + thisAI->AddWaypoint(54, -6308.49, -1179.12, -269.57); + thisAI->AddWaypoint(55, -6302.43, -1181.32, -269.328, 5000); + thisAI->AddWaypoint(56, -6298.87, -1185.79, -269.278); + + return (CreatureAI*)thisAI; +} + +void AddSC_ungoro_crater() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_ame"; + newscript->GetAI = &GetAI_npc_ame; + newscript->pQuestAccept = &QuestAccept_npc_ame; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp index 7f0b2d92b22..caa37fd188f 100644 --- a/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp +++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp @@ -184,8 +184,8 @@ struct TRINITY_DLL_DECL boss_arlokkAI : public ScriptedAI if(PhaseTwo && Gouge_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_GOUGE); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-80); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-80); Gouge_Timer = 17000+rand()%10000; }else Gouge_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp index 95717222b36..11e9fcd36fb 100644 --- a/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp +++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp @@ -59,8 +59,8 @@ struct TRINITY_DLL_DECL boss_grilekAI : public ScriptedAI target = SelectUnit(SELECT_TARGET_RANDOM,1); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-50); if (target) AttackStart(target); diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp index fb902612622..7ed29debb42 100644 --- a/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp +++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp @@ -98,8 +98,8 @@ struct TRINITY_DLL_DECL boss_jindoAI : public ScriptedAI { DoCast(m_creature->getVictim(), SPELL_HEX); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-80); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-80); Hex_Timer = 12000 + rand()%8000; }else Hex_Timer -= diff; @@ -127,8 +127,8 @@ struct TRINITY_DLL_DECL boss_jindoAI : public ScriptedAI { DoTeleportPlayer(target, -11583.7783,-1249.4278,77.5471,4.745); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(target,-100); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(target,-100); Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); Skeletons->AI()->AttackStart(target); diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp index b26c8108d4e..1e095ef3f0b 100644 --- a/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp +++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp @@ -146,8 +146,8 @@ struct TRINITY_DLL_DECL boss_marliAI : public ScriptedAI m_creature->UpdateDamagePhysical(BASE_ATTACK); DoCast(m_creature->getVictim(),SPELL_ENVOLWINGWEB); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-100); PhaseTwo = true; Transform_Timer = 35000 + rand()%25000; diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp index 8b993815c00..889a80e111c 100644 --- a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp +++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp @@ -117,8 +117,8 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,1); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-50); if (target) AttackStart(target); diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp index 4340b47438b..cd44ec16382 100644 --- a/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp +++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp @@ -434,8 +434,8 @@ struct TRINITY_DLL_DECL mob_zealot_zathAI : public ScriptedAI { DoCast(m_creature->getVictim(),SPELL_GOUGE); - if(m_creature->getThreatManager().getThreat(m_creature->getVictim())) - m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100); + if(DoGetThreat(m_creature->getVictim())) + DoModifyThreatPercent(m_creature->getVictim(),-100); Gouge_Timer = 17000+rand()%10000; }else Gouge_Timer -= diff; diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp index bcaa2c80768..ea59facefd9 100644 --- a/src/game/ChatHandler.cpp +++ b/src/game/ChatHandler.cpp @@ -316,9 +316,9 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) break; Group *group = GetPlayer()->GetGroup(); - if(!group || !group->isRaidGroup()) + if(!group || !group->isRaidGroup() || group->isBGGroup()) return; - + WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(),NULL); group->BroadcastPacket(&data); @@ -342,7 +342,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) break; Group *group = GetPlayer()->GetGroup(); - if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID())) + if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()) || group->isBGGroup()) return; WorldPacket data; @@ -362,7 +362,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) break; Group *group = GetPlayer()->GetGroup(); - if(!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID()))) + if(!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup()) return; WorldPacket data; @@ -383,7 +383,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) break; Group *group = GetPlayer()->GetGroup(); - if(!group || !group->isRaidGroup()) + if(!group || !group->isRaidGroup() || !group->isBGGroup()) return; WorldPacket data; @@ -404,7 +404,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) break; Group *group = GetPlayer()->GetGroup(); - if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID())) + if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()) || !group->isBGGroup()) return; WorldPacket data; @@ -587,4 +587,4 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data ) void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); -}
\ No newline at end of file +} diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index e2124feff53..ee39245fc3b 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -594,10 +594,6 @@ bool Creature::AIM_Initialize(CreatureAI* ai) return false; } - // don't allow AI switch when possessed - if (isPossessed()) - return false; - CreatureAI * oldAI = i_AI; i_motionMaster.Initialize(); i_AI = ai ? ai : FactorySelector::selectAI(this); @@ -621,6 +617,8 @@ void Creature::DisablePossessedAI() { if (!i_AI_possessed) return; + delete i_AI_possessed; + // Signal the old AI that it's been re-enabled i_AI->OnPossess(false); } @@ -1158,6 +1156,7 @@ void Creature::SetLootRecipient(Unit *unit) if (!unit) { m_lootRecipient = 0; + RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER); return; } diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index ad663d13b38..71046e2f154 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -19,7 +19,45 @@ */ #include "CreatureAI.h" +#include "Creature.h" +#include "Pet.h" +#include "SpellAuras.h" CreatureAI::~CreatureAI() { } + +SimpleCharmedAI::SimpleCharmedAI(Unit &u) : me(u) +{ +} + +void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) +{ + Creature *charmer = (Creature*)me.GetCharmer(); + + //kill self if charm aura has infinite duration + if(charmer->IsInEvadeMode()) + { + Unit::AuraList const& auras = me.GetAurasByType(SPELL_AURA_MOD_CHARM); + for(Unit::AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) + if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->IsPermanent()) + { + charmer->Kill(&me); + return; + } + } + + if(!charmer->isInCombat()) + me.GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + + Unit *target = me.getVictim(); + if(!target || !charmer->canAttack(target)) + { + target = charmer->SelectNearestTarget(); + if(!target) + return; + + me.GetMotionMaster()->MoveChase(target); + me.Attack(target, true); + } +} diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index a1f78be1e86..b5fda95ef85 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -69,7 +69,22 @@ enum SelectAggroTarget SELECT_TARGET_FARTHEST, }; -class TRINITY_DLL_SPEC CreatureAI +class TRINITY_DLL_SPEC UnitAI +{ + public: + virtual void UpdateAI(const uint32 diff) = 0; +}; + +class TRINITY_DLL_SPEC SimpleCharmedAI +{ + public: + SimpleCharmedAI(Unit &u); + virtual void UpdateAI(const uint32 diff); + private: + Unit &me; +}; + +class TRINITY_DLL_SPEC CreatureAI : public UnitAI { public: diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index 5e15efafe6f..9927ff34df3 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -34,6 +34,9 @@ namespace FactorySelector { CreatureAI* selectAI(Creature *creature) { + //if(creature->isPossessed()) + // creature->InitPossessedAI(); + // Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets) if((!creature->isPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed()) if(CreatureAI* scriptedAI = Script->GetAI(creature)) @@ -62,8 +65,6 @@ namespace FactorySelector ai_factory = ai_registry.GetRegistryItem("TotemAI"); else if(creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); - else if(creature->isPossessed()) - creature->InitPossessedAI(); } // select by permit check diff --git a/src/game/CreatureGroups.h b/src/game/CreatureGroups.h index 3b864ef1073..0f4474106de 100644 --- a/src/game/CreatureGroups.h +++ b/src/game/CreatureGroups.h @@ -63,4 +63,4 @@ extern UNORDERED_MAP<uint32, FormationMember*> CreatureGroupMap; #define formation_mgr Trinity::Singleton<CreatureGroupManager>::Instance() -#endif
\ No newline at end of file +#endif diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 3ac749531fb..601f7f6bdfb 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -6889,7 +6889,7 @@ bool ChatHandler::HandlePossessCommand(const char* args) if (pUnit->GetTypeId() == TYPEID_PLAYER) return false; - m_session->GetPlayer()->Possess(pUnit); + pUnit->SetCharmedOrPossessedBy(m_session->GetPlayer(), true); return true; } @@ -6897,11 +6897,7 @@ bool ChatHandler::HandlePossessCommand(const char* args) bool ChatHandler::HandleUnPossessCommand(const char* args) { // Use this command to also unpossess ourselves - if (m_session->GetPlayer()->isPossessed()) - m_session->GetPlayer()->UnpossessSelf(false); - else - m_session->GetPlayer()->RemovePossess(false); - + m_session->GetPlayer()->RemoveCharmedOrPossessedBy(NULL); return true; } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index f765cf97d20..1af68fce07e 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1403,7 +1403,7 @@ bool Map::CheckGridIntegrity(Creature* c, bool moved) const Cell xy_cell(xy_val); if(xy_cell != cur_cell) { - sLog.outError("ERROR: %s (GUID: %u) X: %f Y: %f (%s) in grid[%u,%u]cell[%u,%u] instead grid[%u,%u]cell[%u,%u]", + sLog.outDebug("ERROR: %s (GUID: %u) X: %f Y: %f (%s) in grid[%u,%u]cell[%u,%u] instead grid[%u,%u]cell[%u,%u]", (c->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature"),c->GetGUIDLow(), c->GetPositionX(),c->GetPositionY(),(moved ? "final" : "original"), cur_cell.GridX(), cur_cell.GridY(), cur_cell.CellX(), cur_cell.CellY(), diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 47be039d415..e78de5571bc 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -247,17 +247,23 @@ MapManager::Update(time_t diff) if( !i_timer.Passed() ) return; + sWorld.RecordTimeDiff(NULL); ObjectAccessor::Instance().UpdatePlayers(i_timer.GetCurrent()); + sWorld.RecordTimeDiff("UpdatePlayers"); + for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) { checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day iter->second->Update(i_timer.GetCurrent()); + sWorld.RecordTimeDiff("UpdateMap %u", iter->second->GetId()); } ObjectAccessor::Instance().Update(i_timer.GetCurrent()); + sWorld.RecordTimeDiff("UpdateObjectAccessor"); for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter) (*iter)->Update(i_timer.GetCurrent()); + sWorld.RecordTimeDiff("UpdateTransports"); i_timer.SetCurrent(0); } diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 7eedfdcdefb..6cd897a071d 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1648,3 +1648,15 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, UpdateGroundPositionZ(x,y,z); } + +void WorldObject::GetClosePointAt(float &x, float &y, float &z, float dist, float angle) +{ + angle += GetOrientation(); + x += dist * cos(angle); + y += dist * sin(angle); + Trinity::NormalizeMapCoord(x); + Trinity::NormalizeMapCoord(y); + UpdateGroundPositionZ(x, y, z); +} + + diff --git a/src/game/Object.h b/src/game/Object.h index f943d0f3d21..fec06ec8419 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -394,6 +394,12 @@ class TRINITY_DLL_SPEC WorldObject : public Object // angle calculated from current orientation GetNearPoint(NULL,x,y,z,size,distance2d,GetOrientation() + angle); } + void GetClosePointAt(float &x, float &y, float &z, float dist, float angle); + void GetClosePoint(float &x, float &y, float &z, float dist, float angle) + { + GetPosition(x, y, z); + GetClosePointAt(x, y, z, dist, angle); + } void GetContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const { // angle to face `obj` to `this` using distance includes size of `obj` diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0b046d36aba..e106073fb0c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1746,6 +1746,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati ResetContestedPvP(); + DestroyForNearbyPlayers(); + m_clientGUIDs.clear(); + // remove player from battleground on far teleport (when changing maps) if(BattleGround const* bg = GetBattleGround()) { @@ -19512,150 +19515,12 @@ void Player::HandleFallUnderMap() } } -void Player::Possess(Unit *target) -{ - if(!target || target == this) - return; - - // Don't allow possession of someone else's pet - if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && target != GetPet()) - return; - - // Don't allow possession on transports or when in flight; also remove possession from the now-to-be-possessed - if (target->GetTypeId() == TYPEID_PLAYER) - { - if (((Player*)target)->m_transport || ((Player*)target)->isInFlight()) - return; - if (target->isPossessing()) - ((Player*)target)->RemovePossess(true); - } - - // Remove any previous possession from the target - if (target->isPossessedByPlayer()) - ((Player*)target->GetCharmer())->RemovePossess(false); - else if (target->isCharmed()) - target->UncharmSelf(); // Target isn't possessed, but charmed; uncharm before possessing - - // Remove our previous possession - if (isPossessing()) - RemovePossess(true); - else if (GetCharm()) // We are charming a creature, not possessing it; uncharm ourself first - Uncharm(); - - // Interrupt any current casting of the target - if(target->IsNonMeleeSpellCasted(true)) - target->InterruptNonMeleeSpells(true); - - // Update the proper unit fields - SetPossessedTarget(target); - - // Start channeling packets to possessor - target->AddPlayerToVision(this); - - target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction()); - target->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); - target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - - if(target->GetTypeId() == TYPEID_UNIT) - { - ((Creature*)target)->InitPossessedAI(); // Initialize the possessed AI - target->StopMoving(); - target->GetMotionMaster()->Clear(false); - target->GetMotionMaster()->MoveIdle(); - } - - target->CombatStop(); - target->DeleteThreatList(); - - // Pets already have a properly initialized CharmInfo, don't overwrite it. - if(target->GetTypeId() == TYPEID_PLAYER || (target->GetTypeId() == TYPEID_UNIT && !((Creature*)target)->isPet())) - { - CharmInfo* charmInfo = target->InitCharmInfo(target); - charmInfo->InitPossessCreateSpells(); - } - - // Disable control for target player and remove AFK - if(target->GetTypeId() == TYPEID_PLAYER) - { - if(((Player*)target)->isAFK()) - ((Player*)target)->ToggleAFK(); - ((Player*)target)->SetViewport(target->GetGUID(), false); - } - - // Set current viewport to target unit, controllable - SetViewport(target->GetGUID(), true); - - PossessSpellInitialize(); -} - void Player::RemovePossess(bool attack) { - Unit* target = GetCharm(); - if(!target || !target->isPossessed()) - return; - - // Remove area auras from possessed - Unit::AuraMap& tAuras = target->GetAuras(); - for(Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();) - { - if(itr->second && itr->second->IsAreaAura()) - target->RemoveAura(itr); - else - ++itr; - } + if(Unit *u = GetCharm()) + u->RemoveCharmedOrPossessedBy(this); - // Interrupt any current casting of the target - if(target->IsNonMeleeSpellCasted(true)) - target->InterruptNonMeleeSpells(true); - - RemovePossessedTarget(); - - // Stop channeling packets back to possessor - target->RemovePlayerFromVision(this); - - if(target->GetTypeId() == TYPEID_PLAYER) - ((Player*)target)->setFactionForRace(target->getRace()); - else if(target->GetTypeId() == TYPEID_UNIT) - { - if(((Creature*)target)->isPet()) - { - if(Unit* owner = target->GetOwner()) - target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction()); - } else - { - if(CreatureInfo const* cInfo = ((Creature*)target)->GetCreatureInfo()) - target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, cInfo->faction_A); - } - } - - target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - - // Remove pet spell action bar - WorldPacket data(SMSG_PET_SPELLS, 8); - data << uint64(0); - m_session->SendPacket(&data); - - // Restore original view - SetViewport(GetGUID(), true); - if(target->GetTypeId() == TYPEID_PLAYER) - ((Player*)target)->SetViewport(target->GetGUID(), true); - else - { - target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - // Reinitialize the pet bar and make the pet come back to the owner - if(((Creature*)target)->isPet()) - { - PetSpellInitialize(); - if (!target->getVictim()) - { - target->GetMotionMaster()->MoveFollow(this, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW); - } - } - else if (target->isAlive()) + /*else if (target->isAlive()) { // If we're still hostile to our target, continue attacking otherwise reset threat and go home if (Unit* victim = target->getVictim()) @@ -19682,10 +19547,7 @@ void Player::RemovePossess(bool attack) // Add high amount of threat on the player if(attack) target->AddThreat(this, 1000000.0f); - } - // Disable the assigned possessed AI - ((Creature*)target)->DisablePossessedAI(); - } + }*/ } void Player::SetViewport(uint64 guid, bool moveable) diff --git a/src/game/Player.h b/src/game/Player.h index 63e11ea1cfe..19bf2e22906 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -962,8 +962,14 @@ class TRINITY_DLL_SPEC Player : public Unit void RemoveFromWorld(); void SetViewport(uint64 guid, bool movable); - void Possess(Unit *target); - void RemovePossess(bool attack = true); + void RemovePossess(bool attack = true); + void StopCharmOrPossess() + { + if(isPossessing()) + RemovePossess(true); + else if(GetCharm()) + Uncharm(); + } WorldObject* GetFarsightTarget() const; void ClearFarsight(); void RemoveFarsightTarget(); @@ -2430,6 +2436,7 @@ class TRINITY_DLL_SPEC Player : public Unit MapReference m_mapRef; void UpdateCharmedAI(); + UnitAI *i_AI; }; void AddItemsSetItem(Player*player,Item *item); diff --git a/src/game/PlayerDump.cpp b/src/game/PlayerDump.cpp index 7c07e51769b..fb22e963ca0 100644 --- a/src/game/PlayerDump.cpp +++ b/src/game/PlayerDump.cpp @@ -26,7 +26,7 @@ #include "ObjectMgr.h" // Character Dump tables -#define DUMP_TABLE_COUNT 19 +#define DUMP_TABLE_COUNT 18 struct DumpTable { diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index d192495c70a..c19777653e6 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -896,23 +896,33 @@ enum Targets TARGET_DEST_TARGET_BACK = 65, // uses in teleport behind spells TARGET_DEST_TARGET_RIGHT = 66, TARGET_DEST_TARGET_LEFT = 67, - TARGET_DEST_TARGET_ENEMY_UNKNOWN2 = 70, + TARGET_DEST_TARGET_FRONT_LEFT = 68, + TARGET_DEST_TARGET_BACK_LEFT = 69, + TARGET_DEST_TARGET_BACK_RIGHT = 70, + TARGET_DEST_TARGET_FRONT_RIGHT = 71, TARGET_DEST_CASTER_RANDOM = 72, TARGET_DEST_CASTER_RADIUS = 73, TARGET_DEST_TARGET_RANDOM = 74, TARGET_DEST_TARGET_RADIUS = 75, TARGET_DEST_CHANNEL = 76, - TARGET_SINGLE_ENEMY = 77, TARGET_UNIT_CHANNEL = 77, - TARGET_DEST_CASTER_FRONT_UNKNOWN = 78, - TARGET_DEST_TABLE_UNKNOWN2 = 80, + TARGET_DEST_DEST_FRONT = 78, + TARGET_DEST_DEST_BACK = 79, + TARGET_DEST_DEST_RIGHT = 80, + TARGET_DEST_DEST_LEFT = 81, + TARGET_DEST_DEST_FRONT_LEFT = 82, + TARGET_DEST_DEST_BACK_LEFT = 83, + TARGET_DEST_DEST_BACK_RIGHT = 84, + TARGET_DEST_DEST_FRONT_RIGHT = 85, TARGET_DEST_DEST_RANDOM = 86, TARGET_DEST_DEST = 87, TARGET_UNIT_AREA_ALL_CHANNEL = 88, + TARGET_DEST_TRAJ = 89, TARGET_UNIT_MINIPET = 90, + TARGET_CORPSE_AREA_ENEMY_PLAYER = 93, }; -#define TOTAL_SPELL_TARGETS 91 +#define TOTAL_SPELL_TARGETS 94 enum SpellMissInfo { diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 7214fdd103b..0007ba874e8 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -171,6 +171,7 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster ) return false; *data >> m_targetMask; + sLog.outDebug("Spell read, target mask = %u", m_targetMask); if(m_targetMask == TARGET_FLAG_SELF) return true; @@ -229,6 +230,7 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster ) void SpellCastTargets::write ( WorldPacket * data ) { *data << uint32(m_targetMask); + sLog.outDebug("Spell write, target mask = %u", m_targetMask); if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK2 ) ) { @@ -276,6 +278,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi ASSERT( info == sSpellStore.LookupEntry( info->Id ) && "`info` must be pointer to sSpellStore element"); m_spellInfo = info; + m_customAttr = spellmgr.GetSpellCustomAttr(m_spellInfo->Id); m_caster = Caster; m_selfContainer = NULL; m_triggeringContainer = triggeringContainer; @@ -1012,7 +1015,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) { m_caster->CombatStart(unit); } - else if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_AURA_CC) + else if(m_customAttr & SPELL_ATTR_CU_AURA_CC) { if(!unit->IsStandState()) unit->SetStandState(PLAYER_STATE_NONE); @@ -1067,7 +1070,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) } unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL); - if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_AURA_CC) + if(m_customAttr & SPELL_ATTR_CU_AURA_CC) unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CC); } else @@ -1138,12 +1141,11 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) } //This is not needed with procflag patch - /*if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) && m_originalCaster) + /*if(m_originalCaster) { - uint32 flag = spellmgr.GetSpellCustomAttr(m_spellInfo->Id); - if(flag & SPELL_ATTR_CU_EFFECT_HEAL) + if(m_customAttr & SPELL_ATTR_CU_EFFECT_HEAL) m_originalCaster->ProcDamageAndSpell(unit, PROC_FLAG_HEAL, PROC_FLAG_NONE, 0, GetSpellSchoolMask(m_spellInfo), m_spellInfo); - if(m_originalCaster != unit && (flag & SPELL_ATTR_CU_EFFECT_DAMAGE)) + if(m_originalCaster != unit && (m_customAttr & SPELL_ATTR_CU_EFFECT_DAMAGE)) m_originalCaster->ProcDamageAndSpell(unit, PROC_FLAG_HIT_SPELL, PROC_FLAG_STRUCK_SPELL, 0, GetSpellSchoolMask(m_spellInfo), m_spellInfo); }*/ } @@ -1582,7 +1584,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) AddItemTarget(m_targets.getItemTarget(), i); }break; - case TARGET_DEST_TABLE_UNKNOWN2: case TARGET_TABLE_X_Y_Z_COORDINATES: if(SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id)) { @@ -1605,9 +1606,9 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) case TARGET_IN_FRONT_OF_CASTER: case TARGET_UNIT_CONE_ENEMY_UNKNOWN: - if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_CONE_BACK) + if(m_customAttr & SPELL_ATTR_CU_CONE_BACK) SearchAreaTarget(TagUnitMap, radius, PUSH_IN_BACK, SPELL_TARGETS_AOE_DAMAGE); - else if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_CONE_LINE) + else if(m_customAttr & SPELL_ATTR_CU_CONE_LINE) SearchAreaTarget(TagUnitMap, radius, PUSH_IN_LINE, SPELL_TARGETS_AOE_DAMAGE); else SearchAreaTarget(TagUnitMap, radius, PUSH_IN_FRONT, SPELL_TARGETS_AOE_DAMAGE); @@ -1831,15 +1832,12 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) float x, y, z, angle, dist; - if (m_spellInfo->EffectRadiusIndex[i]) - dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); - else - dist = 3.0f;//do we need this? - if (cur == TARGET_DEST_CASTER_RANDOM) - dist *= rand_norm(); // This case we need to consider caster size - else - dist -= m_caster->GetObjectSize(); // Size is calculated in GetNearPoint(), but we do not need it - //need a new function to remove this repeated work + float objSize = m_caster->GetObjectSize(); + dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + if(dist < objSize) + dist = objSize; + else if(cur == TARGET_DEST_CASTER_RANDOM) + dist = objSize + (dist - objSize) * rand_norm(); switch(cur) { @@ -1849,7 +1847,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) case TARGET_DEST_CASTER_FRONT_RIGHT:angle = M_PI/4; break; case TARGET_MINION: case TARGET_DEST_CASTER_FRONT_LEAP: - case TARGET_DEST_CASTER_FRONT_UNKNOWN: case TARGET_DEST_CASTER_FRONT: angle = 0.0f; break; case TARGET_DEST_CASTER_BACK: angle = M_PI; break; case TARGET_DEST_CASTER_RIGHT: angle = M_PI/2; break; @@ -1857,7 +1854,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) default: angle = rand_norm()*2*M_PI; break; } - m_caster->GetClosePoint(x, y, z, 0, dist, angle); + m_caster->GetClosePoint(x, y, z, dist, angle); m_targets.setDestination(x, y, z); // do not know if has ground visual }break; @@ -1883,15 +1880,12 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) float x, y, z, angle, dist; - if (m_spellInfo->EffectRadiusIndex[i]) - dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); - else - dist = 3.0f;//do we need this? - if (cur == TARGET_DEST_TARGET_RANDOM) - dist *= rand_norm(); // This case we need to consider caster size - else - dist -= target->GetObjectSize(); // Size is calculated in GetNearPoint(), but we do not need it - //need a new function to remove this repeated work + float objSize = target->GetObjectSize(); + dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + if(dist < objSize) + dist = objSize; + else if(cur == TARGET_DEST_CASTER_RANDOM) + dist = objSize + (dist - objSize) * rand_norm(); switch(cur) { @@ -1899,10 +1893,14 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) case TARGET_DEST_TARGET_BACK: angle = M_PI; break; case TARGET_DEST_TARGET_RIGHT: angle = M_PI/2; break; case TARGET_DEST_TARGET_LEFT: angle = -M_PI/2; break; + case TARGET_DEST_TARGET_FRONT_LEFT: angle = -M_PI/4; break; + case TARGET_DEST_TARGET_BACK_LEFT: angle = -3*M_PI/4; break; + case TARGET_DEST_TARGET_BACK_RIGHT: angle = 3*M_PI/4; break; + case TARGET_DEST_TARGET_FRONT_RIGHT:angle = M_PI/4; break; default: angle = rand_norm()*2*M_PI; break; } - target->GetClosePoint(x, y, z, 0, dist, angle); + target->GetClosePoint(x, y, z, dist, angle); m_targets.setDestination(x, y, z); // do not know if has ground visual }break; @@ -1914,61 +1912,59 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) break; } + if(cur == TARGET_DEST_DEST) + break; + + float x, y, z, angle, dist; + + dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + if (cur == TARGET_DEST_DEST_RANDOM) + dist *= rand_norm(); + switch(cur) { - case TARGET_DEST_DEST_RANDOM: - { - - float x, y, z, dist, px, py, pz; - dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); - x = m_targets.m_destX; - y = m_targets.m_destY; - z = m_targets.m_destZ; - m_caster->GetRandomPoint(x, y, z, dist, px, py, pz); - m_targets.setDestination(px, py, pz); - } - break; - case TARGET_DEST_DEST: - break; + case TARGET_DEST_DEST_FRONT: angle = 0.0f; break; + case TARGET_DEST_DEST_BACK: angle = M_PI; break; + case TARGET_DEST_DEST_RIGHT: angle = M_PI/2; break; + case TARGET_DEST_DEST_LEFT: angle = -M_PI/2; break; + case TARGET_DEST_DEST_FRONT_LEFT: angle = -M_PI/4; break; + case TARGET_DEST_DEST_BACK_LEFT: angle = -3*M_PI/4; break; + case TARGET_DEST_DEST_BACK_RIGHT: angle = 3*M_PI/4; break; + case TARGET_DEST_DEST_FRONT_RIGHT:angle = M_PI/4; break; + default: angle = rand_norm()*2*M_PI; break; } + + x = m_targets.m_destX; + y = m_targets.m_destY; + z = m_targets.m_destZ; + m_caster->GetClosePointAt(x, y, z, dist, angle); + m_targets.setDestination(x, y, z); // do not know if has ground visual }break; default: break; } - if (unMaxTargets && TagUnitMap.size() > unMaxTargets) + if(unMaxTargets) { - // make sure one unit is always removed per iteration - uint32 removed_utarget = 0; - for (std::list<Unit*>::iterator itr = TagUnitMap.begin(), next; itr != TagUnitMap.end(); itr = next) + if(m_targets.getUnitTarget()) { - next = itr; - ++next; - if (!*itr) continue; - if ((*itr) == m_targets.getUnitTarget()) - { - TagUnitMap.erase(itr); - removed_utarget = 1; - // break; - } + TagUnitMap.remove(m_targets.getUnitTarget()); + if(m_spellInfo->Id != 5246) //Intimidating Shout + --unMaxTargets; } + // remove random units from the map - while (TagUnitMap.size() > unMaxTargets - removed_utarget) + std::list<Unit*>::iterator itr; + while(TagUnitMap.size() > unMaxTargets) { - uint32 poz = urand(0, TagUnitMap.size()-1); - for (std::list<Unit*>::iterator itr = TagUnitMap.begin(); itr != TagUnitMap.end(); ++itr, --poz) - { - if (!*itr) continue; - if (!poz) - { - TagUnitMap.erase(itr); - break; - } - } + itr = TagUnitMap.begin(); + advance(itr, urand(0, TagUnitMap.size() - 1)); + TagUnitMap.erase(itr); } + // the player's target will always be added to the map - if (removed_utarget && m_targets.getUnitTarget()) + if(m_targets.getUnitTarget() && m_spellInfo->Id != 5246) TagUnitMap.push_back(m_targets.getUnitTarget()); } } @@ -2045,7 +2041,8 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura) // set timer base at cast time ReSetTimer(); - if(m_IsTriggeredSpell) + //item: first cast may destroy item and second cast causes crash + if(m_IsTriggeredSpell || !m_casttime && !m_spellInfo->StartRecoveryTime && !m_castItemGUID && GetCurrentContainer() == CURRENT_GENERIC_SPELL) cast(true); else { @@ -2161,16 +2158,8 @@ void Spell::cast(bool skipCheck) FillTargetMap(); - if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(m_spellInfo->Id)) - { - for(std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i) - { - if(spell_triggered < 0) - m_caster->RemoveAurasDueToSpell(-(*i)); - else - m_caster->CastSpell(m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster, *i, true); - } - } + if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE) + CalculateDamageDoneForAllTargets(); // traded items have trade slot instead of guid in m_itemTargetGUID // set to real guid to be sent later to the client @@ -2189,7 +2178,7 @@ void Spell::cast(bool skipCheck) if(!m_IsTriggeredSpell) { - TakePower(); + //TakePower(); TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot } @@ -2202,8 +2191,6 @@ void Spell::cast(bool skipCheck) SendCastResult(castResult); SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()... - CalculateDamageDoneForAllTargets(); - // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells if (m_spellInfo->speed > 0.0f && !IsChanneledSpell(m_spellInfo)) { @@ -2223,20 +2210,20 @@ void Spell::cast(bool skipCheck) handle_immediate(); } - // Clear combo at finish state - if(m_caster->GetTypeId() == TYPEID_PLAYER && NeedsComboPoints(m_spellInfo)) + if(!m_IsTriggeredSpell) { - // Not drop combopoints if negative spell and if any miss on enemy exist - bool needDrop = true; - //if (!IsPositiveSpell(m_spellInfo->Id)) - for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) - if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS/* && ihit->targetGUID!=m_caster->GetGUID()*/) - { - needDrop = false; - break; - } - if (needDrop) - ((Player*)m_caster)->ClearComboPoints(); + TakePower(); + } + + if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(m_spellInfo->Id)) + { + for(std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i) + { + if(spell_triggered < 0) + m_caster->RemoveAurasDueToSpell(-(*i)); + else + m_caster->CastSpell(m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster, *i, true); + } } SetExecutedCurrently(false); @@ -3256,9 +3243,25 @@ void Spell::TakeCastItem() void Spell::TakePower() { - if(m_CastItem || m_triggeredByAuraSpell) + if(m_CastItem || m_triggeredByAuraSpell || !m_powerCost) return; + bool hit = true; + if(m_caster->GetTypeId() == TYPEID_PLAYER) + { + if(m_spellInfo->powerType == POWER_RAGE || m_spellInfo->powerType == POWER_ENERGY) + if(uint64 targetGUID = m_targets.getUnitTargetGUID()) + for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + if(ihit->targetGUID == targetGUID) + { + if(ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS/* && ihit->targetGUID!=m_caster->GetGUID()*/) + hit = false; + break; + } + if(hit && NeedsComboPoints(m_spellInfo)) + ((Player*)m_caster)->ClearComboPoints(); + } + // health as power used if(m_spellInfo->powerType == POWER_HEALTH) { @@ -3280,7 +3283,10 @@ void Spell::TakePower() return; } - m_caster->ModifyPower(powerType, -(int32)m_powerCost); + if(hit) + m_caster->ModifyPower(powerType, -m_powerCost); + else + m_caster->ModifyPower(powerType, -irand(0, m_powerCost/4)); // Set the five second timer if (powerType == POWER_MANA && m_powerCost > 0) @@ -5326,6 +5332,10 @@ bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase ) return false; } + //Do not check LOS for triggered spells + if(m_IsTriggeredSpell) + return true; + //Check targets for LOS visibility (except spells without range limitations ) switch(m_spellInfo->Effect[eff]) { @@ -5630,8 +5640,14 @@ int32 Spell::CalculateDamageDone(Unit *unit, const uint32 effectMask, float *mul break; } - if(m_damage > 0 && m_originalCaster) - m_damage = m_originalCaster->SpellDamageBonus(unit, m_spellInfo, m_damage, SPELL_DIRECT_DAMAGE); + if(m_damage > 0) + { + if(IsAreaEffectTarget[m_spellInfo->EffectImplicitTargetA[i]] || IsAreaEffectTarget[m_spellInfo->EffectImplicitTargetB[i]]) + { + if(int32 reducedPct = unit->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE)) + m_damage = m_damage * (100 + reducedPct) / 100; + } + } if(m_applyMultiplierMask & (1 << i)) { m_damage *= m_damageMultipliers[i]; diff --git a/src/game/Spell.h b/src/game/Spell.h index 206145087d1..75c6db1356e 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -600,6 +600,8 @@ class Spell // we can't store original aura link to prevent access to deleted auras // and in same time need aura data and after aura deleting. SpellEntry const* m_triggeredByAuraSpell; + + uint32 m_customAttr; }; namespace Trinity diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 808b04c8cc1..0f8ff486880 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -612,10 +612,13 @@ void Aura::Update(uint32 diff) // update before applying (aura can be removed in TriggerSpell or PeriodicTick calls) m_periodicTimer += m_modifier.periodictime; - if(m_isTrigger) - TriggerSpell(); - else - PeriodicTick(); + if(!m_target->hasUnitState(UNIT_STAT_ISOLATED)) + { + if(m_isTrigger) + TriggerSpell(); + else + PeriodicTick(); + } } } } @@ -633,6 +636,9 @@ void AreaAura::Update(uint32 diff) switch(m_areaAuraType) { + case AREA_AURA_PARTY: + caster->GetPartyMember(targets, m_radius); + break; case AREA_AURA_RAID: caster->GetRaidMember(targets, m_radius); break; @@ -705,39 +711,13 @@ void AreaAura::Update(uint32 diff) } else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group { - // not check group if target == owner or target == pet - if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID()) - { - Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself(); - - Group *pGroup = check ? check->GetGroup() : NULL; - if( pGroup ) - { - Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself(); - if(!checkTarget || !pGroup->SameSubGroup(check, checkTarget)) - tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); - } - else - tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); - } + if(!tmp_target->IsInPartyWith(caster)) + tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); } else if( m_areaAuraType == AREA_AURA_RAID) // TODO: fix me! { - // not check group if target == owner or target == pet - if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID()) - { - Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself(); - - Group *pGroup = check ? check->GetGroup() : NULL; - if( pGroup ) - { - Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself(); - if(!checkTarget) - tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); - } - else - tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); - } + if(!tmp_target->IsInRaidWith(caster)) + tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); } else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER ) { @@ -836,15 +816,6 @@ void Aura::_AddAura() // not call total regen auras at adding switch (m_modifier.m_auraname) { - /*case SPELL_AURA_PERIODIC_DAMAGE: - case SPELL_AURA_PERIODIC_LEECH: - if(caster) - m_modifier.m_amount = caster->SpellDamageBonus(m_target, m_spellProto, m_modifier.m_amount, DOT); - break; - case SPELL_AURA_PERIODIC_HEAL: - if(caster) - m_modifier.m_amount = caster->SpellHealingBonus(m_spellProto, m_modifier.m_amount, DOT, m_target); - break;*/ case SPELL_AURA_OBS_MOD_HEALTH: case SPELL_AURA_OBS_MOD_MANA: m_periodicTimer = m_modifier.periodictime; @@ -2976,7 +2947,7 @@ void Aura::HandleAuraModScale(bool apply, bool Real) m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_modifier.m_amount,apply); } -void Aura::HandleModPossess(bool apply, bool Real) +/*void Aura::HandleModPossess(bool apply, bool Real) { if(!Real) return; @@ -2994,12 +2965,28 @@ void Aura::HandleModPossess(bool apply, bool Real) if( apply ) { - if (caster->GetTypeId() == TYPEID_PLAYER) - ((Player*)caster)->Possess(m_target); + m_target->SetCharmerGUID(GetCasterGUID()); + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction()); + caster->SetCharm(m_target); + + m_target->CombatStop(); + m_target->DeleteThreatList(); + if(m_target->GetTypeId() == TYPEID_UNIT) + { + m_target->StopMoving(); + m_target->GetMotionMaster()->Clear(); + m_target->GetMotionMaster()->MoveIdle(); + CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target); + charmInfo->InitPossessCreateSpells(); + } + + if(caster->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)caster)->PossessSpellInitialize(); + } } else - m_target->UnpossessSelf(true); - /*{ + { m_target->SetCharmerGUID(0); if(m_target->GetTypeId() == TYPEID_PLAYER) @@ -3028,7 +3015,7 @@ void Aura::HandleModPossess(bool apply, bool Real) } } if(caster->GetTypeId() == TYPEID_PLAYER) - ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);*/ + ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL); } void Aura::HandleModPossessPet(bool apply, bool Real) @@ -3055,14 +3042,12 @@ void Aura::HandleModPossessPet(bool apply, bool Real) if(apply) { - ((Player*)caster)->Possess(m_target); + pet->StopMoving(); + pet->GetMotionMaster()->Clear(); + pet->GetMotionMaster()->MoveIdle(); } else { - ((Player*)caster)->RemovePossess(false); - /*pet->StopMoving(); - pet->GetMotionMaster()->Clear(); - pet->GetMotionMaster()->MoveIdle();*/ pet->AttackStop(); pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE); @@ -3079,93 +3064,85 @@ void Aura::HandleModCharm(bool apply, bool Real) return; Unit* caster = GetCaster(); + if(!caster) + return; - if( apply ) + if(int32(m_target->getLevel()) <= m_modifier.m_amount) { - if(!caster) - return; - - if(int32(m_target->getLevel()) > m_modifier.m_amount) - return; - - m_target->SetCharmerGUID(GetCasterGUID()); - m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction()); - m_target->CastStop(m_target==caster ? GetId() : 0); - caster->SetCharm(m_target); - - m_target->CombatStop(); - m_target->DeleteThreatList(); - - if(m_target->GetTypeId() == TYPEID_UNIT) + if( apply ) { - ((Creature*)m_target)->AIM_Initialize(); - CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target); - charmInfo->InitCharmCreateSpells(); - charmInfo->SetReactState( REACT_DEFENSIVE ); + m_target->SetCharmerGUID(GetCasterGUID()); + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction()); + m_target->CastStop(m_target==caster ? GetId() : 0); + caster->SetCharm(m_target); + + m_target->CombatStop(); + m_target->DeleteThreatList(); - if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK) + if(m_target->GetTypeId() == TYPEID_UNIT) { - CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); - if(cinfo && cinfo->type == CREATURE_TYPE_DEMON) + ((Creature*)m_target)->AIM_Initialize(); + CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target); + charmInfo->InitCharmCreateSpells(); + charmInfo->SetReactState( REACT_DEFENSIVE ); + + if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK) { - //to prevent client crash - m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048); - //just to enable stat window - charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true); - //if charmed two demons the same session, the 2nd gets the 1st one's name - m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); + CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); + if(cinfo && cinfo->type == CREATURE_TYPE_DEMON) + { + //to prevent client crash + m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048); + //just to enable stat window + charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true); + //if charmed two demons the same session, the 2nd gets the 1st one's name + m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); + } } } - } - if(caster->GetTypeId() == TYPEID_PLAYER) - { - ((Player*)caster)->CharmSpellInitialize(); + if(caster->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)caster)->CharmSpellInitialize(); + } } - } - else - { - m_target->SetCharmerGUID(0); - - if(m_target->GetTypeId() == TYPEID_PLAYER) - ((Player*)m_target)->setFactionForRace(m_target->getRace()); else { - CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); + m_target->SetCharmerGUID(0); - // restore faction - if(((Creature*)m_target)->isPet()) + if(m_target->GetTypeId() == TYPEID_PLAYER) + ((Player*)m_target)->setFactionForRace(m_target->getRace()); + else { - if(Unit* owner = m_target->GetOwner()) - m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction()); - else if(cinfo) + CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); + + // restore faction + if(((Creature*)m_target)->isPet()) + { + if(Unit* owner = m_target->GetOwner()) + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction()); + else if(cinfo) + m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A); + } + else if(cinfo) // normal creature m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A); - } - else if(cinfo) // normal creature - m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A); - // restore UNIT_FIELD_BYTES_0 - if(caster && cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON) - { - CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon(); - if(cainfo && cainfo->bytes0 != 0) - m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0); - else - m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048); + // restore UNIT_FIELD_BYTES_0 + if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON) + { + CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon(); + if(cainfo && cainfo->bytes0 != 0) + m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0); + else + m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048); - if(m_target->GetCharmInfo()) - m_target->GetCharmInfo()->SetPetNumber(0, true); - else - sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId()); + if(m_target->GetCharmInfo()) + m_target->GetCharmInfo()->SetPetNumber(0, true); + else + sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId()); + } } - ((Creature*)m_target)->AIM_Initialize(); - if(((Creature*)m_target)->AI() && caster) - ((Creature*)m_target)->AI()->AttackStart(caster); - } - - if(caster) - { caster->SetCharm(0); if(caster->GetTypeId() == TYPEID_PLAYER) @@ -3175,9 +3152,15 @@ void Aura::HandleModCharm(bool apply, bool Real) data << uint32(0); ((Player*)caster)->GetSession()->SendPacket(&data); } + if(m_target->GetTypeId() == TYPEID_UNIT) + { + ((Creature*)m_target)->AIM_Initialize(); + if (((Creature*)m_target)->AI()) + ((Creature*)m_target)->AI()->AttackStart(caster); + } } } -} +}*/ void Aura::HandleModConfuse(bool apply, bool Real) { @@ -6655,3 +6638,71 @@ void Aura::HandleModAttackerSpellHitChance(bool apply, bool Real) //cloak of shadows : flare m_target->ApplySpellImmune(31224, IMMUNITY_ID, 1543, apply); } + +void Aura::HandleModPossess(bool apply, bool Real) +{ + if(!Real) + return; + + Unit* caster = GetCaster(); + if(caster && caster->GetTypeId() == TYPEID_UNIT) + { + HandleModCharm(apply, Real); + return; + } + + if(apply) + { + if(m_target->getLevel() > m_modifier.m_amount) + return; + + m_target->SetCharmedOrPossessedBy(caster, true); + } + else + m_target->RemoveCharmedOrPossessedBy(caster); +} + +void Aura::HandleModPossessPet(bool apply, bool Real) +{ + if(!Real) + return; + + Unit* caster = GetCaster(); + if(!caster || caster->GetTypeId() != TYPEID_PLAYER) + return; + if(caster->GetPet() != m_target) + return; + + if(apply) + m_target->SetCharmedOrPossessedBy(caster, true); + else + { + m_target->RemoveCharmedOrPossessedBy(caster); + + // Reinitialize the pet bar and make the pet come back to the owner + ((Player*)caster)->PetSpellInitialize(); + if(!m_target->getVictim()) + { + m_target->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + m_target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW); + } + } +} + +void Aura::HandleModCharm(bool apply, bool Real) +{ + if(!Real) + return; + + Unit* caster = GetCaster(); + + if(apply) + { + if(int32(m_target->getLevel()) > m_modifier.m_amount) + return; + + m_target->SetCharmedOrPossessedBy(caster, false); + } + else + m_target->RemoveCharmedOrPossessedBy(caster); +} diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 3de1f958c1a..17514f9d386 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -325,7 +325,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) } // Meteor like spells (divided damage to targets) - if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_SHARE_DAMAGE) + if(m_customAttr & SPELL_ATTR_CU_SHARE_DAMAGE) { uint32 count = 0; for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) @@ -682,8 +682,11 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) } } - if(damage >= 0) - m_damage+= damage; + if(m_originalCaster) + damage = m_originalCaster->SpellDamageBonus(unitTarget, m_spellInfo, damage, SPELL_DIRECT_DAMAGE); + + if(damage > 0) + m_damage += damage; } } @@ -2367,7 +2370,9 @@ void Spell::EffectPowerBurn(uint32 i) new_damage = int32(new_damage*multiplier); //m_damage+=new_damage; should not apply spell bonus //TODO: no log - unitTarget->ModifyHealth(-new_damage); + //unitTarget->ModifyHealth(-new_damage); + if(m_originalCaster) + m_originalCaster->DealDamage(unitTarget, new_damage); } void Spell::EffectHeal( uint32 /*i*/ ) @@ -3759,7 +3764,7 @@ void Spell::EffectSummonPossessed(uint32 i) TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN; Creature* c = m_caster->SummonCreature(creatureEntry, px, py, pz, m_caster->GetOrientation(), summonType, duration); - ((Player*)m_caster)->Possess(c); + if(c) c->SetCharmedOrPossessedBy(m_caster, true); } void Spell::EffectTeleUnitsFaceCaster(uint32 i) @@ -6570,4 +6575,4 @@ void Spell::EffectRedirectThreat(uint32 /*i*/) { if(unitTarget) m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID()); -}
\ No newline at end of file +} diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 4bb733b8285..e3f8808cc4e 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -126,11 +126,14 @@ SpellMgr::SpellMgr() SpellTargetType[i] = TARGET_TYPE_AREA_DEST; break; case TARGET_DEST_TARGET_ENEMY: - case TARGET_DEST_TARGET_ENEMY_UNKNOWN: case TARGET_DEST_TARGET_FRONT: case TARGET_DEST_TARGET_BACK: case TARGET_DEST_TARGET_RIGHT: case TARGET_DEST_TARGET_LEFT: + case TARGET_DEST_TARGET_FRONT_LEFT: + case TARGET_DEST_TARGET_BACK_LEFT: + case TARGET_DEST_TARGET_BACK_RIGHT: + case TARGET_DEST_TARGET_FRONT_RIGHT: case TARGET_DEST_TARGET_RANDOM: case TARGET_DEST_TARGET_RADIUS: SpellTargetType[i] = TARGET_TYPE_DEST_TARGET; @@ -144,7 +147,6 @@ SpellMgr::SpellMgr() case TARGET_DEST_CASTER_FRONT: case TARGET_MINION: case TARGET_DEST_CASTER_FRONT_LEAP: - case TARGET_DEST_CASTER_FRONT_UNKNOWN: case TARGET_DEST_CASTER_BACK: case TARGET_DEST_CASTER_RIGHT: case TARGET_DEST_CASTER_LEFT: @@ -152,8 +154,16 @@ SpellMgr::SpellMgr() case TARGET_DEST_CASTER_RADIUS: SpellTargetType[i] = TARGET_TYPE_DEST_CASTER; break; - case TARGET_DEST_DEST_RANDOM: case TARGET_DEST_DEST: + case TARGET_DEST_DEST_FRONT_LEFT: + case TARGET_DEST_DEST_BACK_LEFT: + case TARGET_DEST_DEST_BACK_RIGHT: + case TARGET_DEST_DEST_FRONT_RIGHT: + case TARGET_DEST_DEST_FRONT: + case TARGET_DEST_DEST_BACK: + case TARGET_DEST_DEST_RIGHT: + case TARGET_DEST_DEST_LEFT: + case TARGET_DEST_DEST_RANDOM: SpellTargetType[i] = TARGET_TYPE_DEST_DEST; break; default: @@ -475,7 +485,7 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB) case TARGET_IN_FRONT_OF_CASTER: case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: case TARGET_CURRENT_ENEMY_COORDINATES: - case TARGET_SINGLE_ENEMY: + case TARGET_UNIT_CHANNEL: return false; case TARGET_ALL_AROUND_CASTER: return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER); @@ -2064,6 +2074,17 @@ void SpellMgr::LoadSpellCustomAttr() default: break; } + + switch(spellInfo->Effect[j]) + { + case SPELL_EFFECT_SCHOOL_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: + case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: + case SPELL_EFFECT_HEAL: + mSpellCustomAttr[i] |= SPELL_ATTR_CU_DIRECT_DAMAGE; + } } if(spellInfo->SpellVisual[0] == 3879) diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 1f6101c6114..a8b7f08e476 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -416,12 +416,17 @@ inline bool IsAreaAuraEffect(uint32 effect) inline bool IsDispelSpell(SpellEntry const *spellInfo) { + //spellsteal is also dispel if (spellInfo->Effect[0] == SPELL_EFFECT_DISPEL || + spellInfo->Effect[0] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF || spellInfo->Effect[1] == SPELL_EFFECT_DISPEL || - spellInfo->Effect[2] == SPELL_EFFECT_DISPEL ) + spellInfo->Effect[1] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF || + spellInfo->Effect[2] == SPELL_EFFECT_DISPEL || + spellInfo->Effect[2] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF) return true; return false; } + inline bool isSpellBreakStealth(SpellEntry const* spellInfo) { return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH); @@ -745,6 +750,7 @@ inline bool IsProfessionSkill(uint32 skill) #define SPELL_ATTR_CU_AURA_DOT 0x00000020 #define SPELL_ATTR_CU_AURA_CC 0x00000040 #define SPELL_ATTR_CU_AURA_SPELL 0x00000080 +#define SPELL_ATTR_CU_DIRECT_DAMAGE 0x00000100 typedef std::vector<uint32> SpellCustomAttribute; diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index dde5a2cfb40..50f0ed66bd7 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -982,23 +982,6 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged) frost = 0; SetBonusDamage( int32(frost * 0.4f)); } - //force of nature - else if(GetEntry() == 1964) - { - int32 spellDmg = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_NATURE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_NATURE); - if(spellDmg > 0) - SetBonusDamage(int32(spellDmg * 0.09f)); - } - //greater fire elemental - else if(GetEntry() == 15438) - { - if(Unit* shaman = owner->GetOwner()) - { - int32 spellDmg = int32(shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE); - if(spellDmg > 0) - SetBonusDamage(int32(spellDmg * 0.4f)); - } - } } SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, val + bonusAP); @@ -1024,11 +1007,33 @@ void Pet::UpdateDamagePhysical(WeaponAttackType attType) if(attType > BASE_ATTACK) return; + float bonusDamage = 0.0f; + if(Unit* owner = GetOwner()) + { + //force of nature + if(GetEntry() == 1964) + { + int32 spellDmg = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_NATURE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_NATURE); + if(spellDmg > 0) + bonusDamage = spellDmg * 0.09f; + } + //greater fire elemental + else if(GetEntry() == 15438) + { + if(Unit* shaman = owner->GetOwner()) + { + int32 spellDmg = int32(shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE); + if(spellDmg > 0) + bonusDamage = spellDmg * 0.4f; + } + } + } + UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND; float att_speed = float(GetAttackTime(BASE_ATTACK))/1000.0f; - float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed; + float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed + bonusDamage; float base_pct = GetModifierValue(unitMod, BASE_PCT); float total_value = GetModifierValue(unitMod, TOTAL_VALUE); float total_pct = GetModifierValue(unitMod, TOTAL_PCT); diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp index 357a32b4ecb..553f7644b64 100644 --- a/src/game/TemporarySummon.cpp +++ b/src/game/TemporarySummon.cpp @@ -172,9 +172,9 @@ void TemporarySummon::Summon(TempSummonType type, uint32 lifetime) void TemporarySummon::UnSummon() { - CombatStop(); + RemoveCharmedOrPossessedBy(NULL); - UnpossessSelf(false); + CombatStop(); CleanupsBeforeDelete(); AddObjectToRemoveList(); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 2c3432abb57..535465d52d2 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -158,7 +158,6 @@ Unit::Unit() m_removedAuras = 0; m_charmInfo = NULL; m_unit_movement_flags = 0; - m_isPossessed = false; m_reducedThreatPercent = 0; m_misdirectionTargetGUID = 0; @@ -567,7 +566,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo(); if(cInfo && cInfo->lootid) - pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + pVictim->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); // some critters required for quests if(GetTypeId() == TYPEID_PLAYER) @@ -1160,17 +1159,14 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType) { - SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask); - Unit *pVictim = damageInfo->target; - if (damage < 0) return; - if(!this || !pVictim) - return; - if(!this->isAlive() || !pVictim->isAlive()) + Unit *pVictim = damageInfo->target; + if(!pVictim || !pVictim->isAlive()) return; + SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask); uint32 crTypeMask = pVictim->GetCreatureTypeMask(); // Check spell crit chance bool crit = isSpellCrit(pVictim, spellInfo, damageSchoolMask, attackType); @@ -1185,17 +1181,10 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama // Physical Damage if ( damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL ) { - //Calculate armor mitigation - //damage = CalcArmorReducedDamage(pVictim, damage); // Get blocked status blocked = isSpellBlocked(pVictim, spellInfo, attackType); } - // Magical Damage - /*else - { - // Calculate damage bonus - damage = SpellDamageBonus(pVictim, spellInfo, damage, SPELL_DIRECT_DAMAGE); - }*/ + if (crit) { damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT; @@ -1240,8 +1229,6 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama case SPELL_DAMAGE_CLASS_NONE: case SPELL_DAMAGE_CLASS_MAGIC: { - // Calculate damage bonus - //damage = SpellDamageBonus(pVictim, spellInfo, damage, SPELL_DIRECT_DAMAGE); // If crit add critical bonus if (crit) { @@ -7038,10 +7025,11 @@ void Unit::SetPet(Pet* pet) void Unit::SetCharm(Unit* pet) { - SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0); - if(GetTypeId() == TYPEID_PLAYER) + { + SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0); ((Player*)this)->m_mover = pet ? pet : this; + } } void Unit::AddPlayerToVision(Player* plr) @@ -7084,21 +7072,6 @@ void Unit::UncharmSelf() RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM); } -void Unit::UnpossessSelf(bool attack) -{ - if (!isPossessed() || !GetCharmer()) - return; - - if (GetCharmer()->GetTypeId() == TYPEID_PLAYER) - ((Player*)GetCharmer())->RemovePossess(attack); - else - { - GetCharmer()->SetCharm(0); - SetCharmerGUID(0); - m_isPossessed = false; - } -} - void Unit::UnsummonAllTotems() { for (int8 i = 0; i < MAX_TOTEM; ++i) @@ -7142,8 +7115,8 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE ) return pdamage; - if(spellProto->SchoolMask == SPELL_SCHOOL_MASK_NORMAL) - return pdamage; + //if(spellProto->SchoolMask == SPELL_SCHOOL_MASK_NORMAL) + // return pdamage; //damage = CalcArmorReducedDamage(pVictim, damage); int32 BonusDamage = 0; @@ -7521,7 +7494,9 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 // Spellmod SpellDamage //float SpellModSpellDamage = 100.0f; - float CoefficientPtc = ((float)CastingTime/3500.0f)*DotFactor*100.0f; + float CoefficientPtc = DotFactor * 100.0f; + if(spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL) + CoefficientPtc *= ((float)CastingTime/3500.0f); if(Player* modOwner = GetSpellModOwner()) //modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage); @@ -7531,10 +7506,11 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 CoefficientPtc /= 100.0f; //float DoneActualBenefit = DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty; + float DoneActualBenefit = DoneAdvertisedBenefit * CoefficientPtc * LvlPenalty; - float TakenActualBenefit = TakenAdvertisedBenefit; - if(spellProto->SpellFamilyName) - TakenActualBenefit *= (CastingTime / 3500.0f) * DotFactor * LvlPenalty; + float TakenActualBenefit = TakenAdvertisedBenefit * DotFactor * LvlPenalty; + if(spellProto->SpellFamilyName && spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL) + TakenActualBenefit *= ((float)CastingTime / 3500.0f); float tmpDamage = (float(pdamage)+DoneActualBenefit)*DoneTotalMod; @@ -8642,6 +8618,24 @@ bool Unit::canDetectStealthOf(Unit const* target, float distance) const return distance < visibleDistance; } +void Unit::DestroyForNearbyPlayers() +{ + if(!IsInWorld()) + return; + + std::list<Unit*> targets; + Trinity::AnyUnitInObjectRangeCheck check(this, World::GetMaxVisibleDistance()); + Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(targets, check); + VisitNearbyWorldObject(World::GetMaxVisibleDistance(), searcher); + for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter) + if(*iter != this && (*iter)->GetTypeId() == TYPEID_PLAYER + && ((Player*)(*iter))->HaveAtClient(this)) + { + DestroyForPlayer((Player*)(*iter)); + ((Player*)(*iter))->m_clientGUIDs.erase(GetGUID()); + } +} + void Unit::SetVisibility(UnitVisibility x) { m_Visibility = x; @@ -8650,27 +8644,7 @@ void Unit::SetVisibility(UnitVisibility x) SetToNotify(); if(x == VISIBILITY_GROUP_STEALTH) - { - std::list<Unit*> targets; - Trinity::AnyUnitInObjectRangeCheck check(this, World::GetMaxVisibleDistance()); - Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(targets, check); - VisitNearbyWorldObject(World::GetMaxVisibleDistance(), searcher); - for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter) - if(*iter != this && (*iter)->GetTypeId() == TYPEID_PLAYER - && ((Player*)(*iter))->HaveAtClient(this)) - { - DestroyForPlayer((Player*)(*iter)); - ((Player*)(*iter))->m_clientGUIDs.erase(GetGUID()); - } - } - /*{ - Map *m = GetMap(); - - if(GetTypeId()==TYPEID_PLAYER) - m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); - else - m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); - }*/ + DestroyForNearbyPlayers(); } void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) @@ -8905,7 +8879,7 @@ void Unit::setDeathState(DeathState s) UnsummonAllTotems(); // Possessed unit died, restore control to possessor - UnpossessSelf(false); + RemoveCharmedOrPossessedBy(NULL); RemoveAllFromVision(); ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false); @@ -9779,7 +9753,7 @@ void Unit::CleanupsBeforeDelete() { if(m_uint32Values) // only for fully created object { - UnpossessSelf(false); + RemoveCharmedOrPossessedBy(NULL); RemoveAllFromVision(); InterruptNonMeleeSpells(true); m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList @@ -11439,22 +11413,236 @@ void Unit::SetConfused(bool apply) ((Player*)this)->SetClientControl(this, !apply); } +void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess) +{ + if(!charmer) + return; + + assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER); + + if(this == charmer) + return; + + if(isInFlight()) + return; + + if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->GetTransport()) + return; + + RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + CastStop(); + CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells) + DeleteThreatList(); + + // Charmer stop charming + if(charmer->GetTypeId() == TYPEID_PLAYER) + ((Player*)charmer)->StopCharmOrPossess(); + + // Charmed stop charming + if(GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->StopCharmOrPossess(); + + // Charmed stop being charmed + RemoveCharmedOrPossessedBy(NULL); + + // Set charmed + charmer->SetCharm(this); + SetCharmerGUID(charmer->GetGUID()); + setFaction(charmer->getFaction()); + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + + if(GetTypeId() == TYPEID_UNIT) + { + ((Creature*)this)->InitPossessedAI(); + StopMoving(); + GetMotionMaster()->Clear(false); + GetMotionMaster()->MoveIdle(); + } + else + { + if(((Player*)this)->isAFK()) + ((Player*)this)->ToggleAFK(); + ((Player*)this)->SetViewport(GetGUID(), false); + } + + // Pets already have a properly initialized CharmInfo, don't overwrite it. + if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet()) + { + CharmInfo *charmInfo = InitCharmInfo(this); + charmInfo->SetReactState(REACT_DEFENSIVE); + if(possess) + charmInfo->InitPossessCreateSpells(); + else + charmInfo->InitCharmCreateSpells(); + } + + //Set possessed + if(possess) + { + addUnitState(UNIT_STAT_POSSESSED); + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + AddPlayerToVision((Player*)charmer); + ((Player*)charmer)->SetViewport(GetGUID(), true); + charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + } + // Charm demon + else if(GetTypeId() == TYPEID_UNIT && charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK) + { + CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo(); + if(cinfo && cinfo->type == CREATURE_TYPE_DEMON) + { + //to prevent client crash + SetFlag(UNIT_FIELD_BYTES_0, 2048); + + //just to enable stat window + if(GetCharmInfo()) + GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true); + + //if charmed two demons the same session, the 2nd gets the 1st one's name + SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); + } + } + + if(possess) + ((Player*)charmer)->PossessSpellInitialize(); + else if(charmer->GetTypeId() == TYPEID_PLAYER) + ((Player*)charmer)->CharmSpellInitialize(); +} + +void Unit::RemoveCharmedOrPossessedBy(Unit *charmer) +{ + if(!isCharmed()) + return; + + if(!charmer) + charmer = GetCharmer(); + else if(charmer != GetCharmer()) // one aura overrides another? + return; + + bool possess = hasUnitState(UNIT_STAT_POSSESSED); + + CastStop(); + CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells) + getHostilRefManager().deleteReferences(); + DeleteThreatList(); + SetCharmerGUID(0); + RestoreFaction(); + + if(possess) + { + clearUnitState(UNIT_STAT_POSSESSED); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + } + + if(GetTypeId() == TYPEID_UNIT) + { + if(!((Creature*)this)->isPet()) + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + + ((Creature*)this)->DisablePossessedAI(); + if(isAlive() && ((Creature*)this)->AI()) + { + if(charmer && !IsFriendlyTo(charmer)) + { + ((Creature*)this)->AddThreat(charmer, 10000.0f); + ((Creature*)this)->AI()->AttackStart(charmer); + } + else + ((Creature*)this)->AI()->EnterEvadeMode(); + } + } + else + ((Player*)this)->SetViewport(GetGUID(), true); + + // If charmer still exists + if(!charmer) + return; + + assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER); + + charmer->SetCharm(0); + if(possess) + { + RemovePlayerFromVision((Player*)charmer); + ((Player*)charmer)->SetViewport(charmer->GetGUID(), true); + charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + } + // restore UNIT_FIELD_BYTES_0 + else if(GetTypeId() == TYPEID_UNIT && charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK) + { + CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo(); + if(cinfo && cinfo->type == CREATURE_TYPE_DEMON) + { + CreatureDataAddon const *cainfo = ((Creature*)this)->GetCreatureAddon(); + if(cainfo && cainfo->bytes0 != 0) + SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0); + else + RemoveFlag(UNIT_FIELD_BYTES_0, 2048); + + if(GetCharmInfo()) + GetCharmInfo()->SetPetNumber(0, true); + else + sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId()); + } + } + + if(possess || charmer->GetTypeId() == TYPEID_PLAYER) + { + // Remove pet spell action bar + WorldPacket data(SMSG_PET_SPELLS, 8); + data << uint64(0); + ((Player*)charmer)->GetSession()->SendPacket(&data); + } +} + +void Unit::RestoreFaction() +{ + if(GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->setFactionForRace(getRace()); + else + { + CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo(); + + if(((Creature*)this)->isPet()) + { + if(Unit* owner = GetOwner()) + setFaction(owner->getFaction()); + else if(cinfo) + setFaction(cinfo->faction_A); + } + else if(cinfo) // normal creature + setFaction(cinfo->faction_A); + } +} + bool Unit::IsInPartyWith(Unit const *unit) const { - const Player *p1 = GetCharmerOrOwnerPlayerOrPlayerItself(); - const Player *p2 = unit->GetCharmerOrOwnerPlayerOrPlayerItself(); - if(p1 && p2) - return p1->IsInSameGroupWith(p2); + if(this == unit) + return true; + + const Unit *u1 = GetCharmerOrOwnerOrSelf(); + const Unit *u2 = unit->GetCharmerOrOwnerOrSelf(); + if(u1 == u2) + return true; + + if(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER) + return ((Player*)u1)->IsInSameGroupWith((Player*)u2); else return false; } bool Unit::IsInRaidWith(Unit const *unit) const { - const Player *p1 = GetCharmerOrOwnerPlayerOrPlayerItself(); - const Player *p2 = unit->GetCharmerOrOwnerPlayerOrPlayerItself(); - if(p1 && p2) - return p1->IsInSameRaidWith(p2); + if(this == unit) + return true; + + const Unit *u1 = GetCharmerOrOwnerOrSelf(); + const Unit *u2 = unit->GetCharmerOrOwnerOrSelf(); + if(u1 == u2) + return true; + + if(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER) + return ((Player*)u1)->IsInSameRaidWith((Player*)u2); else return false; } diff --git a/src/game/Unit.h b/src/game/Unit.h index 10efed0570c..ced25f4667c 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -364,27 +364,28 @@ enum DeathState enum UnitState { - UNIT_STAT_DIED = 0x0001, - UNIT_STAT_MELEE_ATTACKING = 0x0002, // player is melee attacking someone - //UNIT_STAT_MELEE_ATTACK_BY = 0x0004, // player is melee attack by someone - UNIT_STAT_STUNNED = 0x0008, - UNIT_STAT_ROAMING = 0x0010, - UNIT_STAT_CHASE = 0x0020, - UNIT_STAT_SEARCHING = 0x0040, - UNIT_STAT_FLEEING = 0x0080, + UNIT_STAT_DIED = 0x00000001, + UNIT_STAT_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone + //UNIT_STAT_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone + UNIT_STAT_STUNNED = 0x00000008, + UNIT_STAT_ROAMING = 0x00000010, + UNIT_STAT_CHASE = 0x00000020, + UNIT_STAT_SEARCHING = 0x00000040, + UNIT_STAT_FLEEING = 0x00000080, + UNIT_STAT_IN_FLIGHT = 0x00000100, // player is in flight mode + UNIT_STAT_FOLLOW = 0x00000200, + UNIT_STAT_ROOT = 0x00000400, + UNIT_STAT_CONFUSED = 0x00000800, + UNIT_STAT_DISTRACTED = 0x00001000, + UNIT_STAT_ISOLATED = 0x00002000, // area auras do not affect other players + UNIT_STAT_ATTACK_PLAYER = 0x00004000, + UNIT_STAT_CASTING = 0x00008000, + UNIT_STAT_POSSESSED = 0x00010000, UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING), - UNIT_STAT_IN_FLIGHT = 0x0100, // player is in flight mode - UNIT_STAT_FOLLOW = 0x0200, - UNIT_STAT_ROOT = 0x0400, - UNIT_STAT_CONFUSED = 0x0800, - UNIT_STAT_DISTRACTED = 0x1000, - UNIT_STAT_ISOLATED = 0x2000, // area auras do not affect other players - UNIT_STAT_ATTACK_PLAYER = 0x4000, - UNIT_STAT_CASTING = 0x8000, UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING), UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CHASE | UNIT_STAT_SEARCHING), UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING), - UNIT_STAT_ALL_STATE = 0xffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT) + UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT) }; enum UnitMoveType @@ -937,7 +938,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } void RemoveSpellbyDamageTaken(uint32 damage, uint32 spell); - uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss); + uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *spellProto = NULL, bool durabilityLoss = true); void Kill(Unit *pVictim, bool durabilityLoss = true); void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellEntry const *procSpell = NULL); @@ -1093,35 +1094,24 @@ class TRINITY_DLL_SPEC Unit : public WorldObject Unit* GetCharmer() const; Unit* GetCharm() const; Unit* GetCharmerOrOwner() const { return GetCharmerGUID() ? GetCharmer() : GetOwner(); } - Unit* GetCharmerOrOwnerOrSelf() + Unit* GetCharmerOrOwnerOrSelf() const { - if(Unit* u = GetCharmerOrOwner()) + if(Unit *u = GetCharmerOrOwner()) return u; - return this; + return (Unit*)this; } Player* GetCharmerOrOwnerPlayerOrPlayerItself() const; void SetPet(Pet* pet); void SetCharm(Unit* pet); - void SetPossessedTarget(Unit* target) - { - if (!target) return; - SetCharm(target); - target->SetCharmerGUID(GetGUID()); - target->m_isPossessed = true; - } - void RemovePossessedTarget() - { - if (!GetCharm()) return; - GetCharm()->SetCharmerGUID(0); - GetCharm()->m_isPossessed = false; - SetCharm(0); - } + void SetCharmedOrPossessedBy(Unit* charmer, bool possess); + void RemoveCharmedOrPossessedBy(Unit* charmer); + void RestoreFaction(); bool isCharmed() const { return GetCharmerGUID() != 0; } - bool isPossessed() const { return m_isPossessed; } - bool isPossessedByPlayer() const { return m_isPossessed && IS_PLAYER_GUID(GetCharmerGUID()); } + bool isPossessed() const { return hasUnitState(UNIT_STAT_POSSESSED); } + bool isPossessedByPlayer() const { return hasUnitState(UNIT_STAT_POSSESSED) && IS_PLAYER_GUID(GetCharmerGUID()); } bool isPossessing() const { if(Unit *u = GetCharm()) @@ -1139,7 +1129,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void RemovePlayerFromVision(Player* plr); void RemoveAllFromVision(); void UncharmSelf(); - void UnpossessSelf(bool attack); Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0); @@ -1260,6 +1249,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject // Visibility system UnitVisibility GetVisibility() const { return m_Visibility; } void SetVisibility(UnitVisibility x); + void DestroyForNearbyPlayers(); // common function for visibility checks for player/creatures with detection code virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const; @@ -1510,7 +1500,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject float m_speed_rate[MAX_MOVE_TYPE]; CharmInfo *m_charmInfo; - bool m_isPossessed; SharedVisionList m_sharedVision; virtual SpellSchoolMask GetMeleeDamageSchoolMask() const; diff --git a/src/game/World.cpp b/src/game/World.cpp index f8bdd9f24c2..3d230a3edbe 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1036,6 +1036,7 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_NO_RESET_TALENT_COST] = sConfig.GetBoolDefault("NoResetTalentsCost", false); m_configs[CONFIG_SHOW_KICK_IN_WORLD] = sConfig.GetBoolDefault("ShowKickInWorld", false); m_configs[CONFIG_INTERVAL_LOG_UPDATE] = sConfig.GetIntDefault("RecordUpdateTimeDiffInterval", 60000); + m_configs[CONFIG_MIN_LOG_UPDATE] = sConfig.GetIntDefault("MinRecordUpdateTimeDiff", 10); std::string forbiddenmaps = sConfig.GetStringDefault("ForbiddenMaps", ""); char * forbiddenMaps = new char[forbiddenmaps.length() + 1]; @@ -1471,14 +1472,29 @@ void World::DetectDBCLang() sLog.outString("Using %s DBC Locale as default. All available DBC locales: %s",localeNames[m_defaultDbcLocale],availableLocalsStr.empty() ? "<none>" : availableLocalsStr.c_str()); } -void World::RecordTimeDiff(const char *text) +void World::RecordTimeDiff(const char *text, ...) { if(m_updateTimeCount != 1) return; - sLog.outDebugInLine("Difftime "); - sLog.outDebugInLine(text); - uint32 thisTime = getMSTime(); - sLog.outDebug(": %u.", getMSTimeDiff(m_currentTime, thisTime)); + if(!text) + { + m_currentTime = getMSTime(); + return; + } + + uint32 thisTime = getMSTime(); + uint32 diff = getMSTimeDiff(m_currentTime, thisTime); + + if(diff > m_configs[CONFIG_MIN_LOG_UPDATE]) + { + va_list ap; + char str [256]; + va_start(ap, text); + vsnprintf(str,256,text, ap ); + va_end(ap); + sLog.outDetail("Difftime %s: %u.", str, diff); + } + m_currentTime = thisTime; } @@ -1493,7 +1509,6 @@ void World::Update(time_t diff) sLog.outString("Update time diff: %u. Players online: %u.", m_updateTimeSum / m_updateTimeCount, GetActiveSessionCount()); m_updateTimeSum = m_updateTime; m_updateTimeCount = 1; - m_currentTime = getMSTime(); } else { @@ -1580,8 +1595,8 @@ void World::Update(time_t diff) } } } - RecordTimeDiff("UpdateAuction"); + RecordTimeDiff(NULL); /// <li> Handle session updates when the timer has passed if (m_timers[WUPDATE_SESSIONS].Passed()) { @@ -1621,7 +1636,6 @@ void World::Update(time_t diff) m_timers[WUPDATE_UPTIME].Reset(); WorldDatabase.PExecute("UPDATE uptime SET uptime = %d, maxplayers = %d WHERE starttime = " I64FMTD, tmpDiff, maxClientsNum, uint64(m_startTime)); } - RecordTimeDiff("UpdateWeatherAndUptime"); /// <li> Handle all other objects if (m_timers[WUPDATE_OBJECTS].Passed()) @@ -1630,16 +1644,20 @@ void World::Update(time_t diff) ///- Update objects when the timer has passed (maps, transport, creatures,...) MapManager::Instance().Update(diff); // As interval = 0 + RecordTimeDiff(NULL); ///- Process necessary scripts if (!m_scriptSchedule.empty()) ScriptsProcess(); + RecordTimeDiff("UpdateScriptsProcess"); sBattleGroundMgr.Update(diff); + RecordTimeDiff("UpdateBattleGroundMgr"); sOutdoorPvPMgr.Update(diff); + RecordTimeDiff("UpdateOutdoorPvPMgr"); } - RecordTimeDiff("UpdateMaps"); + RecordTimeDiff(NULL); // execute callbacks from sql queries that were queued recently UpdateResultQueue(); RecordTimeDiff("UpdateResultQueue"); @@ -1670,7 +1688,6 @@ void World::Update(time_t diff) // And last, but not least handle the issued cli commands ProcessCliCommands(); - RecordTimeDiff("UpdateRemainingThings"); } void World::ForceGameEventUpdate() diff --git a/src/game/World.h b/src/game/World.h index 615cd950231..786982a81e7 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -207,6 +207,7 @@ enum WorldConfigs CONFIG_NO_RESET_TALENT_COST, CONFIG_SHOW_KICK_IN_WORLD, CONFIG_INTERVAL_LOG_UPDATE, + CONFIG_MIN_LOG_UPDATE, CONFIG_ENABLE_SINFO_LOGIN, CONFIG_VALUE_COUNT @@ -528,6 +529,7 @@ class World void SetScriptsVersion(char const* version) { m_ScriptsVersion = version ? version : "unknown scripting library"; } char const* GetScriptsVersion() { return m_ScriptsVersion.c_str(); } + void RecordTimeDiff(const char * text, ...); protected: void _UpdateGameTime(); void ScriptsProcess(); @@ -550,7 +552,6 @@ class World uint32 m_updateTime, m_updateTimeSum; uint32 m_updateTimeCount; uint32 m_currentTime; - void RecordTimeDiff(const char * text); typedef UNORDERED_MAP<uint32, Weather*> WeatherMap; WeatherMap m_weathers; diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 231d7783d9e..78bc11f62e0 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -249,6 +249,14 @@ void WorldSession::LogoutPlayer(bool Save) if (_player) { + // Unpossess the current possessed unit of player + _player->StopCharmOrPossess(); + + // Remove any possession of this player on logout + _player->RemoveCharmedOrPossessedBy(NULL); + + _player->DestroyForNearbyPlayers(); + if (uint64 lguid = GetPlayer()->GetLootGUID()) DoLootRelease(lguid); @@ -374,13 +382,6 @@ void WorldSession::LogoutPlayer(bool Save) if(_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket) _player->RemoveFromGroup(); - // Unpossess the current possessed unit of player - if (_player->isPossessing()) - _player->RemovePossess(false); - - // Remove any possession of this player on logout - _player->UnpossessSelf(false); - ///- Remove the player from the world // the player may not be in the world when logging out // e.g if he got disconnected during a transfer to another map diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index db4a22fe223..91b0209acd4 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -1265,6 +1265,9 @@ Ra.Secure = 1 # >0 = Interval # 0 = Disable # +# MinRecordUpdateTimeDiff +# only record update time diff which is greater than this value +# # PlayerStart.String # If set to anything else than "", this string will be displayed to players when they login # to a newly created character. @@ -1285,4 +1288,5 @@ PvPToken.ItemCount = 1 NoResetTalentsCost = 0 ShowKickInWorld = 0 RecordUpdateTimeDiffInterval = 60000 -PlayerStart.String = ""
\ No newline at end of file +MinRecordUpdateTimeDiff = 10 +PlayerStart.String = "" |