From 3703f4891def906b405d37787b7b993e2a652491 Mon Sep 17 00:00:00 2001 From: mknjc Date: Thu, 7 May 2009 18:20:55 +0200 Subject: Backported TC2 commit 3157 (megamage: *Fix the bug that fishing bobber does not have correct position.) --HG-- branch : trunk --- src/game/Spell.cpp | 14 ++++++++++++-- src/game/SpellMgr.h | 6 ++++++ 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 91d6622425e..664e52b26c0 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1593,9 +1593,19 @@ void Spell::SetTargetMap(uint32 i, uint32 cur) switch(cur) { case TARGET_UNIT_CASTER: - case TARGET_UNIT_CASTER_FISHING: AddUnitTarget(m_caster, i); break; + case TARGET_UNIT_CASTER_FISHING: + { + AddUnitTarget(m_caster, i); + float min_dis = GetSpellMinRange(m_spellInfo, true); + float max_dis = GetSpellMaxRange(m_spellInfo, true); + float dis = rand_norm() * (max_dis - min_dis) + min_dis; + float x, y, z; + m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis); + m_targets.setDestination(x, y, z); + break; + } case TARGET_UNIT_MASTER: if(Unit* owner = m_caster->GetCharmerOrOwner()) AddUnitTarget(owner, i); @@ -2471,7 +2481,7 @@ void Spell::_handle_immediate_phase() { if(spellmgr.EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_DEST) { - if(!m_targets.HasDst()) + if(!m_targets.HasDst()) // FIXME: this will ignore dest set in effect m_targets.setDestination(m_caster); HandleEffects(m_originalCaster, NULL, NULL, j); } diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 70b81403a52..7c5a0874e41 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -326,6 +326,12 @@ inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect) return true; return false; } +inline float GetSpellMinRange(SpellEntry const *spellInfo, bool positive) +{ + return positive + ? GetSpellMinRangeForFriend(sSpellRangeStore.LookupEntry(spellInfo->rangeIndex)) + : GetSpellMinRangeForHostile(sSpellRangeStore.LookupEntry(spellInfo->rangeIndex)); +} //bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); -- cgit v1.2.3 From 3dc839536ae74e264fbe553ec257a220ff6b0156 Mon Sep 17 00:00:00 2001 From: Anubisss Date: Thu, 7 May 2009 20:48:17 +0200 Subject: *Fix a typo in Alar's script pointed by jojo. Thank you. --HG-- branch : trunk --- src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp index 52c2433ae43..a66d8b7e9e8 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp @@ -410,7 +410,8 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI else { Unit *target = NULL; - if(Phase1 && target && (target = m_creature->SelectNearestTarget(5))) + target = m_creature->SelectNearestTarget(5); + if(Phase1 && target) m_creature->AI()->AttackStart(target); else { -- cgit v1.2.3 From 5b9dae20b11243a19c37570392ab25a4bcdd63cd Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 7 May 2009 18:06:20 -0500 Subject: *Fix build. By Kudlaty. --HG-- branch : trunk --- src/game/Spell.cpp | 4 ++-- src/game/SpellMgr.h | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 664e52b26c0..2227bc4c92b 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1598,8 +1598,8 @@ void Spell::SetTargetMap(uint32 i, uint32 cur) case TARGET_UNIT_CASTER_FISHING: { AddUnitTarget(m_caster, i); - float min_dis = GetSpellMinRange(m_spellInfo, true); - float max_dis = GetSpellMaxRange(m_spellInfo, true); + float min_dis = GetSpellMinRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); + float max_dis = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); float dis = rand_norm() * (max_dis - min_dis) + min_dis; float x, y, z; m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis); diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 7c5a0874e41..70b81403a52 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -326,12 +326,6 @@ inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect) return true; return false; } -inline float GetSpellMinRange(SpellEntry const *spellInfo, bool positive) -{ - return positive - ? GetSpellMinRangeForFriend(sSpellRangeStore.LookupEntry(spellInfo->rangeIndex)) - : GetSpellMinRangeForHostile(sSpellRangeStore.LookupEntry(spellInfo->rangeIndex)); -} //bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); -- cgit v1.2.3 From 51b46c53b84295658eb1197657e350c7a7a34271 Mon Sep 17 00:00:00 2001 From: krz Date: Fri, 8 May 2009 17:16:14 +0200 Subject: Fix enchantment application in case item is broken. --HG-- branch : trunk --- src/game/Player.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 387ea279969..743d457d689 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6581,8 +6581,8 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply) if(slot >= INVENTORY_SLOT_BAG_END || !item) return; - // not apply/remove mods for broken item - if(item->IsBroken()) + // not apply mods for broken item + if(item->IsBroken() && apply) return; ItemPrototype const *proto = item->GetProto(); -- cgit v1.2.3 From ca370ddbbecace13e8836366fbb743000592d232 Mon Sep 17 00:00:00 2001 From: Anubisss Date: Fri, 8 May 2009 23:13:15 +0200 Subject: *Correct elapsed time in BG/Arena by Trojan. Thank you. --HG-- branch : trunk --- src/game/BattleGround.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index c0ec88b78fb..6c8185b97d2 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -126,7 +126,9 @@ void BattleGround::Update(time_t diff) //BG is empty return; - WorldPacket data; + m_StartTime += diff; + + // WorldPacket data; if(GetRemovedPlayersSize()) { -- cgit v1.2.3 From 5346498dea71f651e672e14f093137bbd6622ce9 Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 18:39:04 -0500 Subject: *Update sapphiron script (not finished yet). --HG-- branch : trunk --- .../scripts/zone/naxxramas/boss_patchwerk.cpp | 13 +- .../scripts/zone/naxxramas/boss_sapphiron.cpp | 299 +++++++++++++-------- src/game/Unit.cpp | 7 + src/game/Unit.h | 1 + 4 files changed, 194 insertions(+), 126 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp index 3f51fc08ee4..99f8741c897 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp @@ -88,15 +88,14 @@ struct TRINITY_DLL_DECL boss_patchwerkAI : public ScriptedAI //amount of HP within melee distance uint32 MostHP = 0; Unit* pMostHPTarget = NULL; - std::list::iterator i = m_creature->getThreatManager().getThreatList().begin(); - for(; i != m_creature->getThreatManager().getThreatList().end();) + std::list::iterator i = me->getThreatManager().getThreatList().begin(); + for(; i != me->getThreatManager().getThreatList().end(); ++i) { - Unit* pTemp = Unit::GetUnit(*m_creature, (*i)->getUnitGuid()); - ++i; - if (pTemp && pTemp->isAlive() && pTemp->GetHealth() > MostHP && m_creature->IsWithinMeleeRange(pTemp)) + Unit* target = (*i)->getTarget(); + if (target->isAlive() && target->GetHealth() > MostHP && me->IsWithinMeleeRange(target)) { - MostHP = pTemp->GetHealth(); - pMostHPTarget = pTemp; + MostHP = target->GetHealth(); + pMostHPTarget = target; } } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp index a0cfb77c06c..44e2def1c88 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp @@ -26,159 +26,220 @@ EndScriptData */ #define EMOTE_BREATH -1533082 #define EMOTE_ENRAGE -1533083 -#define SPELL_ICEBOLT 28522 -#define SPELL_FROST_BREATH 29318 #define SPELL_FROST_AURA HEROIC(28531,55799) -#define SPELL_LIFE_DRAIN HEROIC(28542,55665) -//#define SPELL_CHILL 28560 -#define SPELL_BLIZZARD 28547 -#define SPELL_BESERK 26662 #define SPELL_CLEAVE 19983 -#define SPELL_TAIL_SWEEP 55697 +#define SPELL_TAIL_SWEEP HEROIC(55697,55696) +#define SPELL_SUMMON_BLIZZARD 28560 +#define SPELL_LIFE_DRAIN HEROIC(28542,55665) +#define SPELL_ICEBOLT 28522 +#define SPELL_FROST_BREATH 29318 +#define SPELL_FROST_BREATH2 28524 +#define SPELL_BERSERK 26662 + +#define SPELL_CHILL HEROIC(28547,55699) + +#define MOB_BLIZZARD 16474 +#define GO_ICEBLOCK 181247 + +enum Phases +{ + PHASE_NULL = 0, + PHASE_GROUND, + PHASE_FLIGHT, +}; + +enum Events +{ + EVENT_BERSERK = 1, + EVENT_CLEAVE, + EVENT_TAIL, + EVENT_DRAIN, + EVENT_BLIZZARD, + EVENT_FLIGHT, + EVENT_LIFTOFF, + EVENT_ICEBOLT, + EVENT_BREATH, + EVENT_LAND, + EVENT_GROUND, +}; +typedef std::map IceBlockMap; struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI { - boss_sapphironAI(Creature* c) : ScriptedAI(c) {} - - uint32 Icebolt_Count; - uint32 Icebolt_Timer; - uint32 FrostBreath_Timer; - uint32 FrostAura_Timer; - uint32 LifeDrain_Timer; - uint32 Blizzard_Timer; - uint32 Tail_Sweep_Timer; - uint32 Cleave_Timer; - uint32 Fly_Timer; - uint32 Fly2_Timer; - uint32 Beserk_Timer; - uint32 phase; - bool IsInFly; - uint32 land_Timer; + boss_sapphironAI(Creature* c) : ScriptedAI(c) + , phase(PHASE_NULL) + { + } + + EventMap events; + Phases phase; + uint32 iceboltCount; + IceBlockMap iceblocks; void Reset() { - FrostAura_Timer = 2000; - LifeDrain_Timer = 24000; - Blizzard_Timer = 20000; - Tail_Sweep_Timer=(rand()%2+9)*1000; - Cleave_Timer=10000; - Fly_Timer = 45000; - Icebolt_Timer = 4000; - land_Timer = 0; - Beserk_Timer = 15*60000; - phase = 1; - Icebolt_Count = 0; - IsInFly = false; - - m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); + if(phase = PHASE_FLIGHT) + ClearIceBlock(); + + events.Reset(); + phase = PHASE_NULL; } void EnterCombat(Unit *who) { DoZoneInCombat(); me->CastSpell(me, SPELL_FROST_AURA, true); + + events.ScheduleEvent(EVENT_BERSERK, 15*60000); + EnterPhaseGround(); } - void UpdateAI(const uint32 diff) + void SpellHitTarget(Unit *target, const SpellEntry *spell) { - if (!UpdateVictim()) - return; - - if(phase == 1) + if(spell->Id == SPELL_ICEBOLT) { - if(LifeDrain_Timer < diff) + IceBlockMap::iterator itr = iceblocks.find(target->GetGUID()); + if(itr != iceblocks.end() && !itr->second) { - DoCastAOE(SPELL_LIFE_DRAIN); - LifeDrain_Timer = 24000; - }else LifeDrain_Timer -= diff; + if(GameObject *iceblock = me->SummonGameObject(GO_ICEBLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, 0, 0, 0, 0, 25000)) + itr->second = iceblock->GetGUID(); + } + } + } - if(Blizzard_Timer < diff) - { - if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) - { - DoCast(target,SPELL_BLIZZARD); - //It seems NO damage? - } - Blizzard_Timer = 20000; - }else Blizzard_Timer -= diff; + void EnterPhaseGround() + { + events.SetPhase(PHASE_GROUND); + events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_BLIZZARD, 5000+rand()%15000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_FLIGHT, 45000); + } - //SPELL_CLEAVE - if(Cleave_Timer < diff) - { - DoCast(m_creature->getVictim(),SPELL_CLEAVE); - Cleave_Timer = 10000; - }else Cleave_Timer -= diff; + void ClearIceBlock() + { + for(IceBlockMap::iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr) + { + if(Player *player = Unit::GetPlayer(itr->first)) + player->RemoveAura(SPELL_ICEBOLT); + if(GameObject *go = GameObject::GetGameObject(*me, itr->second)) + go->Delete(); + } + iceblocks.clear(); + } - //Tail Sweep_Timer, - if(Tail_Sweep_Timer < diff) - { - DoCast(m_creature,SPELL_TAIL_SWEEP); - Tail_Sweep_Timer=(rand()%2+9)*1000; - }else Tail_Sweep_Timer -= diff; + void UpdateAI(const uint32 diff) + { + if(!phase) + return; - if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 10) - { - if(Fly_Timer < diff) - { - phase = 2; - m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); - m_creature->GetMotionMaster()->Clear(false); - m_creature->GetMotionMaster()->MoveIdle(); - m_creature->SetHover(true); - Icebolt_Timer = 4000; - Icebolt_Count = 0; - IsInFly = true; - }else Fly_Timer -= diff; - } - } + events.Update(diff); - if (phase == 2) + if(phase == PHASE_GROUND) { - if(Icebolt_Timer < diff && Icebolt_Count < 5) + if(!UpdateVictim()) + return; + + while(uint32 eventId = events.ExecuteEvent()) { - if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) + switch(eventId) { - DoCast(target,SPELL_ICEBOLT); - ++Icebolt_Count; - error_log("Count incremented"); + case EVENT_BERSERK: + DoScriptText(EMOTE_ENRAGE, m_creature); + DoCast(me, SPELL_BERSERK); + return; + case EVENT_CLEAVE: + DoCast(me->getVictim(), SPELL_CLEAVE); + events.ScheduleEvent(EVENT_CLEAVE, 10000, 0, PHASE_GROUND); + return; + case EVENT_TAIL: + DoCastAOE(SPELL_TAIL_SWEEP); + events.ScheduleEvent(EVENT_TAIL, (rand()%2+9)*1000, 0, PHASE_GROUND); + return; + case EVENT_DRAIN: + DoCastAOE(SPELL_LIFE_DRAIN); + events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND); + return; + case EVENT_BLIZZARD: + if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) + DoCast(target,SPELL_SUMMON_BLIZZARD); + events.ScheduleEvent(EVENT_BLIZZARD, 20000, 0, PHASE_GROUND); + break; + case EVENT_FLIGHT: + phase = PHASE_FLIGHT; + events.SetPhase(PHASE_FLIGHT); + events.ScheduleEvent(EVENT_LIFTOFF, 0); + return; } - FrostBreath_Timer = 6000; - Icebolt_Timer = 4000; - }else Icebolt_Timer -= diff; + } - if(Icebolt_Count == 5 && IsInFly && FrostBreath_Timer < diff ) + DoMeleeAttackIfReady(); + } + else + { + if(me->getThreatManager().isThreatListEmpty()) { - DoScriptText(EMOTE_BREATH, m_creature); - DoCast(m_creature->getVictim(),SPELL_FROST_BREATH); - land_Timer = 2000; - IsInFly = false; - FrostBreath_Timer = 6000; - }else FrostBreath_Timer -= diff; - - if(!IsInFly && land_Timer < diff) + EnterEvadeMode(); + return; + } + + if(uint32 eventId = events.ExecuteEvent()) { - phase = 1; - m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); - m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); - m_creature->GetMotionMaster()->Clear(false); - m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); - m_creature->SetHover(true); - land_Timer = 0; - Fly_Timer = 67000; - }else land_Timer -= diff; - } + switch(eventId) + { + case EVENT_LIFTOFF: + me->AttackStop(); + me->GetMotionMaster()->MoveIdle(); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); + me->SendMovementFlagUpdate(); + events.ScheduleEvent(EVENT_ICEBOLT, 1000); + iceboltCount = HeroicMode ? 3 : 2; + return; + case EVENT_ICEBOLT: + { + std::vector targets; + std::list::iterator i = me->getThreatManager().getThreatList().begin(); + for(; i != me->getThreatManager().getThreatList().end(); ++i) + if((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT)) + targets.push_back((*i)->getTarget()); - if (Beserk_Timer < diff) - { - DoScriptText(EMOTE_ENRAGE, m_creature); - DoCast(m_creature,SPELL_BESERK); - Beserk_Timer = 300000; - }else Beserk_Timer -= diff; + if(targets.empty()) + iceboltCount = 0; + else + { + std::vector::iterator itr = targets.begin(); + advance(itr, rand()%targets.size()); + iceblocks.insert(std::make_pair((*itr)->GetGUID(), 0)); + DoCast(*itr, SPELL_ICEBOLT); + --iceboltCount; + } - if (phase!=2) - DoMeleeAttackIfReady(); + if(iceboltCount) + events.ScheduleEvent(EVENT_ICEBOLT, 1000); + else + events.ScheduleEvent(EVENT_BREATH, 1000); + return; + } + case EVENT_BREATH: + DoScriptText(EMOTE_BREATH, me); + ClearIceBlock(); + events.ScheduleEvent(EVENT_LAND, 1000); + return; + case EVENT_LAND: + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); + me->SendMovementFlagUpdate(); + events.ScheduleEvent(EVENT_GROUND, 1000); + return; + case EVENT_GROUND: + EnterPhaseGround(); + return; + } + }//if(uint32 eventId = events.ExecuteEvent()) + }//if(phase == PHASE_GROUND) } }; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 514a26349ba..5782ec9d5a4 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -12163,6 +12163,13 @@ void Unit::StopMoving() SendMessageToSet(&data,false); } +void Unit::SendMovementFlagUpdate() +{ + WorldPacket data; + BuildHeartBeatMsg(&data); + SendMessageToSet(&data, false); +} + /* void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID) { diff --git a/src/game/Unit.h b/src/game/Unit.h index fcfc14b5394..54384854089 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1212,6 +1212,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end); void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); + void SendMovementFlagUpdate(); bool isAlive() const { return (m_deathState == ALIVE); }; bool isDead() const { return ( m_deathState == DEAD || m_deathState == CORPSE ); }; -- cgit v1.2.3 From d72855e25fb00af6c7d5c599514de8d3aff429b0 Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 18:43:06 -0500 Subject: [7794] Add DK pet type support for proper show it in client Pet tab. Author: Astellar --HG-- branch : trunk --- src/game/Pet.cpp | 30 ++++++++++++++++++++++++------ src/game/Pet.h | 4 ++++ src/game/Player.cpp | 4 ++-- 3 files changed, 30 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index e846f7004c0..7edc9144bdc 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -190,10 +190,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool return true; } - if (getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK)) - m_charmInfo->SetPetNumber(pet_number, true); - else - m_charmInfo->SetPetNumber(pet_number, false); + m_charmInfo->SetPetNumber(pet_number, IsPermanentPetFor(owner)); // set current pet as current // 0=current @@ -1685,6 +1682,27 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply) } } +bool Pet::IsPermanentPetFor(Player* owner) +{ + switch(getPetType()) + { + case SUMMON_PET: + switch(owner->getClass()) + { + case CLASS_WARLOCK: + return GetCreatureInfo()->type == CREATURE_TYPE_DEMON; + case CLASS_DEATH_KNIGHT: + return GetCreatureInfo()->type == CREATURE_TYPE_UNDEAD; + default: + return false; + } + case HUNTER_PET: + return true; + default: + return false; + } +} + bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number) { SetMapId(map->GetId()); @@ -1735,10 +1753,10 @@ void Pet::LearnPetPassives() void Pet::CastPetAuras(bool current) { Unit* owner = GetOwner(); - if(!owner) + if(!owner || owner->GetTypeId()!=TYPEID_PLAYER) return; - if(getPetType() != HUNTER_PET && (getPetType() != SUMMON_PET || owner->getClass() != CLASS_WARLOCK)) + if(!IsPermanentPetFor((Player*)owner)) return; for(PetAuraSet::const_iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end();) diff --git a/src/game/Pet.h b/src/game/Pet.h index 90414a321de..ea82b7360bc 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -126,6 +126,8 @@ typedef std::vector AutoSpellList; #define PET_FOLLOW_DIST 1 #define PET_FOLLOW_ANGLE (M_PI/2) +class Player; + class Pet : public Guardian { public: @@ -140,6 +142,8 @@ class Pet : public Guardian bool isControlled() const { return getPetType()==SUMMON_PET || getPetType()==HUNTER_PET; } bool isTemporarySummoned() const { return m_duration > 0; } + bool IsPermanentPetFor(Player* owner); // pet have tab in character windows and set UNIT_FIELD_PETNUMBER + bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number); bool CreateBaseAtCreature(Creature* creature); bool LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false ); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 494334466f4..c0b2b384938 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1505,7 +1505,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) uint32 petFamily = 0; // show pet at selection character in character list only for non-ghost character - if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER)) + if (result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER || pClass == CLASS_DEATH_KNIGHT)) { uint32 entry = fields[10].GetUInt32(); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(entry); @@ -16712,7 +16712,7 @@ void Player::PetSpellInitialize() uint8 addlist = 0; data << uint8(addlist); // placeholder - if(pet->isControlled() && ((pet->getPetType() == HUNTER_PET) || ((pet->GetCreatureInfo()->type == CREATURE_TYPE_DEMON) && (getClass() == CLASS_WARLOCK)))) + if (pet->IsPermanentPetFor(this)) { // spells loop for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) -- cgit v1.2.3 From 6fbebffbafc123b4948ad23303743e2b10f2ded4 Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 18:45:26 -0500 Subject: [7795] Added comments. Author: AlexDereka --HG-- branch : trunk --- src/shared/Common.h | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/shared/Common.h b/src/shared/Common.h index abe804bb3a4..5cbd7f285f6 100644 --- a/src/shared/Common.h +++ b/src/shared/Common.h @@ -62,26 +62,17 @@ #include "Platform/Define.h" #if COMPILER == COMPILER_MICROSOFT - -#pragma warning(disable:4996) - +# pragma warning(disable:4996) // 'function': was declared deprecated #ifndef __SHOW_STUPID_WARNINGS__ - -#pragma warning(disable:4244) - -#pragma warning(disable:4267) - -#pragma warning(disable:4800) - -#pragma warning(disable:4018) - -#pragma warning(disable:4311) - -#pragma warning(disable:4305) - -#pragma warning(disable:4005) - -#pragma warning(disable:4522)//warning when class has 2 constructosr +# pragma warning(disable:4005) // 'identifier' : macro redefinition +# pragma warning(disable:4018) // 'expression' : signed/unsigned mismatch +# pragma warning(disable:4244) // 'argument' : conversion from 'type1' to 'type2', possible loss of data +# pragma warning(disable:4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data +# pragma warning(disable:4305) // 'identifier' : truncation from 'type1' to 'type2' +# pragma warning(disable:4311) // 'variable' : pointer truncation from 'type' to 'type' +# pragma warning(disable:4355) // 'this' : used in base member initializer list +# pragma warning(disable:4800) // 'type' : forcing value to bool 'true' or 'false' (performance warning) +# pragma warning(disable:4522) //warning when class has 2 constructosr #endif // __SHOW_STUPID_WARNINGS__ #endif // __GNUC__ -- cgit v1.2.3 From e85e4c386b76e345cf615c743a3268408d72bffb Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 18:47:27 -0500 Subject: [7796] Implement .lookup taxinode and .go taxinode commands. Author: VladimirMangos --HG-- branch : trunk --- sql/mangos.sql | 8 ++- .../7782_01_mangos_spell_proc_event.sql.obs | 4 ++ sql/updates/7796_01_mangos_command.sql | 7 +++ sql/updates/7796_02_mangos_mangos_string.sql | 8 +++ src/game/Chat.cpp | 3 ++ src/game/Chat.h | 2 + src/game/DBCStructure.h | 2 +- src/game/DBCfmt.h | 2 +- src/game/Language.h | 10 ++-- src/game/Level1.cpp | 45 ++++++++++++++++ src/game/Level3.cpp | 62 ++++++++++++++++++++++ src/game/SpellEffects.cpp | 2 +- 12 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 sql/updates/7782_01_mangos_spell_proc_event.sql.obs create mode 100644 sql/updates/7796_01_mangos_command.sql create mode 100644 sql/updates/7796_02_mangos_mangos_string.sql (limited to 'src') diff --git a/sql/mangos.sql b/sql/mangos.sql index 0a036be48a3..077f617b7c1 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, - `required_7777_01_mangos_spell_proc_event` bit(1) default NULL + `required_7796_02_mangos_mangos_string` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -322,6 +322,7 @@ INSERT INTO `command` VALUES ('go graveyard',1,'Syntax: .go graveyard #graveyardId\r\n Teleport to graveyard with the graveyardId specified.'), ('go grid',1,'Syntax: .go grid #gridX #gridY [#mapId]\r\n\r\nTeleport the gm to center of grid with provided indexes at map #mapId (or current map if it not provided).'), ('go object',1,'Syntax: .go object #object_guid\r\nTeleport your character to gameobject with guid #object_guid'), +('go taxinode',1,'Syntax: .go taxinode #taxinode\r\n\r\nTeleport player to taxinode coordinates. You can look up zone using .lookup taxinode $namepart'), ('go trigger',1,'Syntax: .go trigger #trigger_id\r\n\r\nTeleport your character to areatrigger with id #trigger_id. Character will be teleported to trigger target if selected areatrigger is telporting trigger.'), ('go xy',1,'Syntax: .go xy #x #y [#mapid]\r\n\r\nTeleport player to point with (#x,#y) coordinates at ground(water) level at map #mapid or same map if #mapid not provided.'), ('go xyz',1,'Syntax: .go xyz #x #y #z [#mapid]\r\n\r\nTeleport player to point with (#x,#y,#z) coordinates at ground(water) level at map #mapid or same map if #mapid not provided.'), @@ -384,6 +385,7 @@ INSERT INTO `command` VALUES ('lookup quest',3,'Syntax: .lookup quest $namepart\r\n\r\nLooks up a quest by $namepart, and returns all matches with their quest ID\'s.'), ('lookup skill',3,'Syntax: .lookup skill $$namepart\r\n\r\nLooks up a skill by $namepart, and returns all matches with their skill ID\'s.'), ('lookup spell',3,'Syntax: .lookup spell $namepart\r\n\r\nLooks up a spell by $namepart, and returns all matches with their spell ID\'s.'), +('lookup taxinode',3,'Syntax: .lookup taxinode $substring\r\n\r\nSearch and output all taxinodes with provide $substring in name.'), ('lookup tele',1,'Syntax: .lookup tele $substring\r\n\r\nSearch and output all .tele command locations with provide $substring in name.'), ('maxskill',3,'Syntax: .maxskill\r\nSets all skills of the targeted player to their maximum VALUESfor its current level.'), ('modify arena',1,'Syntax: .modify arena #value\r\nAdd $amount arena points to the selected player.'), @@ -2688,6 +2690,7 @@ INSERT INTO `mangos_string` VALUES (344,'You already have pet.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (345,'Forced customize for player %s will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (346,'Forced customize for player %s (GUID #%u) will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(347,'TaxiNode ID %u not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (400,'|cffff0000[System Message]:|rScripts reloaded',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (401,'You change security level of account %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (402,'%s changed your security level to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2753,6 +2756,7 @@ INSERT INTO `mangos_string` VALUES (463,'Teleport location added.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (464,'Teleport location NOT added: database error.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (465,'Teleport location deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(466,'No taxinodes found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (467,'Target unit has %d auras:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (468,'id: %d eff: %d type: %d duration: %d maxduration: %d name: %s%s%s caster: %s %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (469,'Target unit has %d auras of type %d:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -3052,6 +3056,8 @@ INSERT INTO `mangos_string` VALUES (1125,'Your pet learned all talents',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1126,'Your pet talents have been reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1127,'Talents of %s\'s pet reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1128,'%d - |cffffffff|Htaxinode:%u|h[%s %s]|h|r (Map:%u X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1129,'%d - %s %s (Map:%u X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1200,'You try to view cinemitic %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1201,'You try to view movie %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; diff --git a/sql/updates/7782_01_mangos_spell_proc_event.sql.obs b/sql/updates/7782_01_mangos_spell_proc_event.sql.obs new file mode 100644 index 00000000000..8efa5573b3c --- /dev/null +++ b/sql/updates/7782_01_mangos_spell_proc_event.sql.obs @@ -0,0 +1,4 @@ +ALTER TABLE db_version CHANGE COLUMN required_7777_01_mangos_spell_proc_event required_7782_01_mangos_spell_proc_event bit; + +DELETE FROM spell_proc_event WHERE entry = 34074; +INSERT INTO spell_proc_event VALUES (34074, 0, 9, 522819, 8917121, 513, 0, 0, 0, 0, 0); \ No newline at end of file diff --git a/sql/updates/7796_01_mangos_command.sql b/sql/updates/7796_01_mangos_command.sql new file mode 100644 index 00000000000..0a5c7c34221 --- /dev/null +++ b/sql/updates/7796_01_mangos_command.sql @@ -0,0 +1,7 @@ +ALTER TABLE db_version CHANGE COLUMN required_7782_01_mangos_spell_proc_event required_7796_01_mangos_command bit; + +DELETE FROM `command` WHERE `name` IN ('go taxinode','lookup taxinode'); + +INSERT INTO `command` VALUES +('go taxinode',1,'Syntax: .go taxinode #taxinode\r\n\r\nTeleport player to taxinode coordinates. You can look up zone using .lookup taxinode $namepart'), +('lookup taxinode',3,'Syntax: .lookup taxinode $substring\r\n\r\nSearch and output all taxinodes with provide $substring in name.'); diff --git a/sql/updates/7796_02_mangos_mangos_string.sql b/sql/updates/7796_02_mangos_mangos_string.sql new file mode 100644 index 00000000000..ae47b9803a5 --- /dev/null +++ b/sql/updates/7796_02_mangos_mangos_string.sql @@ -0,0 +1,8 @@ +ALTER TABLE db_version CHANGE COLUMN required_7796_01_mangos_command required_7796_02_mangos_mangos_string bit; + +DELETE FROM mangos_string WHERE entry IN(347,466,1128,1129); +INSERT INTO mangos_string VALUES +(347,'TaxiNode ID %u not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(466,'No taxinodes found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1128,'%d - |cffffffff|Htaxinode:%u|h[%s %s]|h|r (Map:%u X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1129,'%d - %s %s (Map:%u X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 1bc6eb304e4..bf8ee9d3a77 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -49,6 +49,7 @@ // |color|Hskill:skill_id|h[name]|h|r // |color|Hspell:spell_id|h[name]|h|r - client, spellbook spell icon shift-click // |color|Htalent:talent_id,rank|h[name]|h|r - client, talent icon shift-click +// |color|Htaxinode:id|h[name]|h|r // |color|Htele:id|h[name]|h|r // |color|Htrade:spell_id,cur_value,max_value,unk3int,unk3str|h[name]|h|r - client, spellbook profession icon shift-click @@ -194,6 +195,7 @@ ChatCommand * ChatHandler::getCommandTable() { "graveyard", SEC_MODERATOR, false, &ChatHandler::HandleGoGraveyardCommand, "", NULL }, { "grid", SEC_MODERATOR, false, &ChatHandler::HandleGoGridCommand, "", NULL }, { "object", SEC_MODERATOR, false, &ChatHandler::HandleGoObjectCommand, "", NULL }, + { "taxinode", SEC_MODERATOR, false, &ChatHandler::HandleGoTaxinodeCommand, "", NULL }, { "trigger", SEC_MODERATOR, false, &ChatHandler::HandleGoTriggerCommand, "", NULL }, { "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL }, { "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL }, @@ -301,6 +303,7 @@ ChatCommand * ChatHandler::getCommandTable() { "player", SEC_GAMEMASTER, true, NULL, "", lookupPlayerCommandTable }, { "skill", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSkillCommand, "", NULL }, { "spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSpellCommand, "", NULL }, + { "taxinode", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupTaxiNodeCommand, "", NULL }, { "tele", SEC_MODERATOR, true, &ChatHandler::HandleLookupTeleCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; diff --git a/src/game/Chat.h b/src/game/Chat.h index cc7de6731a6..97570d2f250 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -195,6 +195,7 @@ class ChatHandler bool HandleGoGraveyardCommand(const char* args); bool HandleGoGridCommand(const char* args); bool HandleGoObjectCommand(const char* args); + bool HandleGoTaxinodeCommand(const char* args); bool HandleGoTriggerCommand(const char* args); bool HandleGoXYCommand(const char* args); bool HandleGoXYZCommand(const char* args); @@ -247,6 +248,7 @@ class ChatHandler bool HandleLookupQuestCommand(const char* args); bool HandleLookupSkillCommand(const char* args); bool HandleLookupSpellCommand(const char* args); + bool HandleLookupTaxiNodeCommand(const char * args); bool HandleLookupTeleCommand(const char * args); bool HandleModifyKnownTitlesCommand(const char* args); diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 8c8195c018b..3798785ca03 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1517,7 +1517,7 @@ struct TaxiNodesEntry float x; // 2 m_x float y; // 3 m_y float z; // 4 m_z - //char* name[16]; // 5-21 m_Name_lang + char* name[16]; // 5-21 m_Name_lang // 22 string flags uint32 MountCreatureID[2]; // 23-24 m_MountCreatureID[2] }; diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index ea2198ef22c..170fd25dd9f 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -96,7 +96,7 @@ const char StableSlotPricesfmt[] = "ni"; const char SummonPropertiesfmt[] = "niiiii"; const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx"; const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix"; -const char TaxiNodesEntryfmt[]="nifffxxxxxxxxxxxxxxxxxii"; +const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii"; const char TaxiPathEntryfmt[]="niii"; const char TaxiPathNodeEntryfmt[]="diiifffiixx"; const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; diff --git a/src/game/Language.h b/src/game/Language.h index 69bfbf00159..8bc01a7deea 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -328,7 +328,8 @@ enum TrinityStrings LANG_YOU_ALREADY_HAVE_PET = 344, LANG_CUSTOMIZE_PLAYER = 345, LANG_CUSTOMIZE_PLAYER_GUID = 346, - // Room for more level 2 345-399 not used + LANG_COMMAND_GOTAXINODENOTFOUND = 347, + // Room for more level 2 348-399 not used // level 3 chat LANG_SCRIPTS_RELOADED = 400, @@ -403,8 +404,7 @@ enum TrinityStrings LANG_COMMAND_TP_ADDED = 463, LANG_COMMAND_TP_ADDEDERR = 464, LANG_COMMAND_TP_DELETED = 465, - // 466, // not used - + LANG_COMMAND_NOTAXINODEFOUND = 466, LANG_COMMAND_TARGET_LISTAURAS = 467, LANG_COMMAND_TARGET_AURADETAIL = 468, LANG_COMMAND_TARGET_LISTAURATYPE = 469, @@ -765,7 +765,9 @@ enum TrinityStrings LANG_COMMAND_LEARN_PET_TALENTS = 1125, LANG_RESET_PET_TALENTS = 1126, LANG_RESET_PET_TALENTS_ONLINE = 1127, - // Room for more level 3 1128-1199 not used + LANG_TAXINODE_ENTRY_LIST_CHAT = 1128, + LANG_TAXINODE_ENTRY_LIST_CONSOLE = 1129, + // Room for more level 3 1130-1199 not used // Debug commands LANG_CINEMATIC_NOT_EXIST = 1200, diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 963e79f8829..832f2ada5e3 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -2753,6 +2753,51 @@ bool ChatHandler::HandleGroupgoCommand(const char* args) return true; } +bool ChatHandler::HandleGoTaxinodeCommand(const char* args) +{ + Player* _player = m_session->GetPlayer(); + + if (!*args) + return false; + + char* cNodeId = extractKeyFromLink((char*)args,"Htaxinode"); + if (!cNodeId) + return false; + + int32 i_nodeId = atoi(cNodeId); + if (!i_nodeId) + return false; + + TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i_nodeId); + if (!node) + { + PSendSysMessage(LANG_COMMAND_GOTAXINODENOTFOUND,i_nodeId); + SetSentErrorMessage(true); + return false; + } + + if (node->x == 0.0f && node->y == 0.0f && node->z == 0.0f || + !MapManager::IsValidMapCoord(node->map_id,node->x,node->y,node->z)) + { + PSendSysMessage(LANG_INVALID_TARGET_COORD,node->x,node->y,node->map_id); + SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(node->map_id, node->x, node->y, node->z, _player->GetOrientation()); + return true; +} + //teleport at coordinates bool ChatHandler::HandleGoXYCommand(const char* args) { diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 474a79c5680..1130bcec070 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -3694,6 +3694,68 @@ bool ChatHandler::HandleLookupObjectCommand(const char* args) return true; } +bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + uint32 counter = 0; // Counter for figure out that we found smth. + + // Search in TaxiNodes.dbc + for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++) + { + TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id); + if(nodeEntry) + { + int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); + std::string name = nodeEntry->name[loc]; + if(name.empty()) + continue; + + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(m_session && loc==m_session->GetSessionDbcLocale()) + continue; + + name = nodeEntry->name[loc]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) + { + // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format + if (m_session) + PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(),localeNames[loc], + nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z); + else + PSendSysMessage (LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc], + nodeEntry->map_id,nodeEntry->x,nodeEntry->y,nodeEntry->z); + ++counter; + } + } + } + if (counter == 0) // if counter == 0 then we found nth + SendSysMessage(LANG_COMMAND_NOSPELLFOUND); + return true; +} + /** \brief GM command level 3 - Create a guild. * * This command allows a GM (level 3) to create a guild. diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 14b012b6f73..c411ea69bff 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -6534,4 +6534,4 @@ void Spell::EffectRenamePet(uint32 /*eff_idx*/) return; unitTarget->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED); -} +} \ No newline at end of file -- cgit v1.2.3 From 7277ddd1140d388939ae135f135d5bf58871dacf Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 18:49:07 -0500 Subject: [7797] Use DBC data for mount model selection in more cases. Author: VladimirMangos * Use alt.team mount data for take player team model id if DB not provide own team creature id in spell taxi call case. * Remove unddeded hacks for model ids from Spell::EffectSendTaxi * Provide spell target for SPELL_EFFECT_SEND_TAXI for spell with target mode 0 for this effect. --HG-- branch : trunk --- src/game/CharacterHandler.cpp | 2 +- src/game/ObjectMgr.cpp | 9 ++++++++- src/game/ObjectMgr.h | 2 +- src/game/Player.cpp | 6 +++--- src/game/Spell.cpp | 1 + src/game/SpellEffects.cpp | 31 +------------------------------ 6 files changed, 15 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index ca6a96c3b08..d82f0a0b518 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -769,7 +769,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { sLog.outDebug( "WORLD: Restart character %u taxi flight", pCurrChar->GetGUIDLow() ); - uint32 MountId = objmgr.GetTaxiMount(sourceNode, pCurrChar->GetTeam()); + uint32 MountId = objmgr.GetTaxiMount(sourceNode, pCurrChar->GetTeam(),true); uint32 path = pCurrChar->m_taxi.GetCurrentTaxiPath(); // search appropriate start path node diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 12fb26f0ad8..a448a73f1dc 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -4837,7 +4837,7 @@ void ObjectMgr::GetTaxiPath( uint32 source, uint32 destination, uint32 &path, ui path = dest_i->second.ID; } -uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team ) +uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team /* = false */) { uint16 mount_entry = 0; uint16 mount_id = 0; @@ -4848,6 +4848,9 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team ) if (team == ALLIANCE) { mount_entry = node->MountCreatureID[1]; + if(!mount_entry && allowed_alt_team) + mount_entry = node->MountCreatureID[0]; + CreatureInfo const *ci = GetCreatureTemplate(mount_entry); if(ci) mount_id = ci->Modelid_A1; @@ -4855,6 +4858,10 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team ) if (team == HORDE) { mount_entry = node->MountCreatureID[0]; + + if(!mount_entry && allowed_alt_team) + mount_entry = node->MountCreatureID[1]; + CreatureInfo const *ci = GetCreatureTemplate(mount_entry); if(ci) mount_id = ci->Modelid_H1; diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index eff1f3812a1..3fe373f6a34 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -418,7 +418,7 @@ class ObjectMgr uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid, uint32 team ); void GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost); - uint16 GetTaxiMount( uint32 id, uint32 team ); + uint16 GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team = false); void GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector& mapIds ); void GetTransportPathNodes( uint32 path, TransportPath &pathnodes ); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c0b2b384938..07b5a71cf83 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -230,7 +230,7 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values, uint } // can't load taxi path without mount set (quest taxi path?) - if(!objmgr.GetTaxiMount(GetTaxiSource(),team)) + if(!objmgr.GetTaxiMount(GetTaxiSource(),team,true)) return false; return true; @@ -17232,8 +17232,8 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, uint32 mount_i prevnode = lastnode; } - if(!mount_id) // if not provide then attempt use default. - mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam()); + if(!mount_id) // if not provide then attempt use default, allow seelct alt team mount creature model but for proper team in spell case. + mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam(), npc == NULL); if (mount_id == 0 || sourcepath == 0) { diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 5934542f64f..168e6ddd16f 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -598,6 +598,7 @@ void Spell::FillTargetMap() case SPELL_EFFECT_SELF_RESURRECT: case SPELL_EFFECT_REPUTATION: case SPELL_EFFECT_LEARN_SPELL: + case SPELL_EFFECT_SEND_TAXI: if(m_targets.getUnitTarget()) AddUnitTarget(m_targets.getUnitTarget(), i); // Triggered spells have additional spell targets - cast them even if no explicit unit target is given (required for spell 50516 for example) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index c411ea69bff..63fdf335ad5 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5901,36 +5901,7 @@ void Spell::EffectSendTaxi(uint32 i) nodes[0] = entry->from; nodes[1] = entry->to; - uint32 mountid = 0; - switch(m_spellInfo->Id) - { - case 31606: //Stormcrow Amulet - mountid = 17447; - break; - case 45071: //Quest - Sunwell Daily - Dead Scar Bombing Run - case 45113: //Quest - Sunwell Daily - Ship Bombing Run - case 45353: //Quest - Sunwell Daily - Ship Bombing Run Return - mountid = 22840; - break; - case 34905: //Stealth Flight - mountid = 6851; - break; - case 45883: //Amber Ledge to Beryl Point - mountid = 23524; - break; - case 46064: //Amber Ledge to Coldarra - mountid = 6371; - break; - case 53335: //Stormwind Harbor Flight - Peaceful - mountid = 6852; - break; - case 41533: //Fly of the Netherwing - case 41540: //Fly of the Netherwing - mountid = 23468; - break; - } - - ((Player*)unitTarget)->ActivateTaxiPathTo(nodes,mountid); + ((Player*)unitTarget)->ActivateTaxiPathTo(nodes); } -- cgit v1.2.3 From 29921b5bea032c1f701dda5f4fe64e10dc0b067a Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 18:52:12 -0500 Subject: [7798] More Player::ActivateTaxiPathTo use improvements Author: VladimirMangos * Provide more explicit way about spell that cast taxi flight if any * Remove incorrect states instead error reporting in case non-taximaster flight start (cast/script) * Remove mount_id arg from ActivateTaxiPathTo and implement support for 0 mount_id case (spell 32474) * Implement spell 32474 (except finilize part) * Provided Player::ActivateTaxiPathTo(uint32 taxi_path_id) function version for simplify one node to node paths use by id. --HG-- branch : trunk --- src/game/Player.cpp | 91 +++++++++++++++++++++++++++++++++-------------- src/game/Player.h | 3 +- src/game/SpellAuras.cpp | 11 +++++- src/game/SpellAuras.h | 1 + src/game/SpellEffects.cpp | 13 +------ src/game/TaxiHandler.cpp | 7 ++-- 6 files changed, 83 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 07b5a71cf83..a1ec4606d2a 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -17114,43 +17114,68 @@ void Player::HandleStealthedUnitsDetection() } } -bool Player::ActivateTaxiPathTo(std::vector const& nodes, uint32 mount_id, Creature* npc) +bool Player::ActivateTaxiPathTo(std::vector const& nodes, Creature* npc /*= NULL*/, uint32 spellid /*= 0*/) { if(nodes.size() < 2) return false; - // not let cheating with start flight mounted - if(IsMounted()) + // not let cheating with start flight in time of logout process || if casting not finished || while in combat || if not use Spell's with EffectSendTaxi + if(GetSession()->isLogingOut() || isInCombat()) { WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); - data << uint32(ERR_TAXIPLAYERALREADYMOUNTED); + data << uint32(ERR_TAXIPLAYERBUSY); GetSession()->SendPacket(&data); return false; } - if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) - { - WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); - data << uint32(ERR_TAXIPLAYERSHAPESHIFTED); - GetSession()->SendPacket(&data); + if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)) return false; - } - // not let cheating with start flight in time of logout process || if casting not finished || while in combat || if not use Spell's with EffectSendTaxi - if(GetSession()->isLogingOut() || - (!m_currentSpells[CURRENT_GENERIC_SPELL] || - m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Effect[0] != SPELL_EFFECT_SEND_TAXI)&& - IsNonMeleeSpellCasted(false) || - isInCombat()) + // taximaster case + if(npc) { - WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); - data << uint32(ERR_TAXIPLAYERBUSY); - GetSession()->SendPacket(&data); - return false; + // not let cheating with start flight mounted + if(IsMounted()) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIPLAYERALREADYMOUNTED); + GetSession()->SendPacket(&data); + return false; + } + + if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIPLAYERSHAPESHIFTED); + GetSession()->SendPacket(&data); + return false; + } + + // not let cheating with start flight in time of logout process || if casting not finished || while in combat || if not use Spell's with EffectSendTaxi + if(IsNonMeleeSpellCasted(false)) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIPLAYERBUSY); + GetSession()->SendPacket(&data); + return false; + } } + // cast case or scripted call case + else + { + RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); - if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)) - return false; + if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) + RemoveAurasDueToSpell(m_ShapeShiftFormSpellId); + + if(m_currentSpells[CURRENT_GENERIC_SPELL] && m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id != spellid) + InterruptSpell(CURRENT_GENERIC_SPELL,false); + + InterruptSpell(CURRENT_AUTOREPEAT_SPELL,false); + + if(m_currentSpells[CURRENT_CHANNELED_SPELL] && m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id != spellid) + InterruptSpell(CURRENT_CHANNELED_SPELL,true); + } uint32 sourcenode = nodes[0]; @@ -17180,7 +17205,7 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, uint32 mount_i } } // node must have pos if not spell case (npc!=0) - else if(npc) + else if(!spellid) { WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); data << uint32(ERR_TAXIUNSPECIFIEDSERVERERROR); @@ -17232,10 +17257,9 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, uint32 mount_i prevnode = lastnode; } - if(!mount_id) // if not provide then attempt use default, allow seelct alt team mount creature model but for proper team in spell case. - mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam(), npc == NULL); + uint16 mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam(), spellid != 0); - if (mount_id == 0 || sourcepath == 0) + if (mount_id == 0 && spellid == 0 || sourcepath == 0) { WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); data << uint32(ERR_TAXIUNSPECIFIEDSERVERERROR); @@ -17277,6 +17301,21 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, uint32 mount_i return true; } +bool Player::ActivateTaxiPathTo( uint32 taxi_path_id, uint32 spellid /*= 0*/ ) +{ + TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(taxi_path_id); + if(!entry) + return false; + + std::vector nodes; + + nodes.resize(2); + nodes[0] = entry->from; + nodes[1] = entry->to; + + return ActivateTaxiPathTo(nodes,NULL,spellid); +} + void Player::ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs ) { // last check 2.0.10 diff --git a/src/game/Player.h b/src/game/Player.h index ecab25122bf..be509972e71 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -867,7 +867,8 @@ class TRINITY_DLL_SPEC Player : public Unit PlayerTaxi m_taxi; void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); } - bool ActivateTaxiPathTo(std::vector const& nodes, uint32 mount_id = 0 , Creature* npc = NULL); + bool ActivateTaxiPathTo(std::vector const& nodes, Creature* npc = NULL, uint32 spellid = 0); + bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0); // mount_id can be used in scripting calls bool isAcceptWhispers() const { return m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS; } void SetAcceptWhispers(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_ACCEPT_WHISPERS; else m_ExtraFlags &= ~PLAYER_EXTRA_ACCEPT_WHISPERS; } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index f7f13acc3f8..3885be1c517 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -196,7 +196,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &AuraEffect::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE &AuraEffect::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT &AuraEffect::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE - &AuraEffect::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes + &AuraEffect::HandleAuraSafeFall, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes &AuraEffect::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS &AuraEffect::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE &AuraEffect::HandleModStateImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK @@ -6973,3 +6973,12 @@ void Aura::UnregisterSingleCastAura() m_isSingleTargetAura = false; } } + +void Aura::HandleAuraSafeFall( bool Apply, bool Real ) +{ + // implemented in WorldSession::HandleMovementOpcodes + + // only special case + if(Apply && Real && GetId()==32474 && m_target->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_target)->ActivateTaxiPathTo(506,GetId()); +} diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index f0120596ce9..973272a75d2 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -217,6 +217,7 @@ class TRINITY_DLL_SPEC AuraEffect void HandlePeriodicTriggerSpellWithValue(bool apply, bool Real); void HandlePeriodicEnergize(bool Apply, bool Real); void HandleAuraModResistanceExclusive(bool Apply, bool Real); + void HandleAuraSafeFall(bool Apply, bool Real); void HandleAuraModPetTalentsPoints(bool Apply, bool Real); void HandleModStealth(bool Apply, bool Real); void HandleInvisibility(bool Apply, bool Real); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 63fdf335ad5..3226ccdbec0 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5891,18 +5891,7 @@ void Spell::EffectSendTaxi(uint32 i) if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(m_spellInfo->EffectMiscValue[i]); - if(!entry) - return; - - std::vector nodes; - - nodes.resize(2); - nodes[0] = entry->from; - nodes[1] = entry->to; - - ((Player*)unitTarget)->ActivateTaxiPathTo(nodes); - + ((Player*)unitTarget)->ActivateTaxiPathTo(m_spellInfo->EffectMiscValue[i],m_spellInfo->Id); } void Spell::EffectPlayerPull(uint32 i) diff --git a/src/game/TaxiHandler.cpp b/src/game/TaxiHandler.cpp index 24c6aca147a..5ba65c00660 100644 --- a/src/game/TaxiHandler.cpp +++ b/src/game/TaxiHandler.cpp @@ -128,7 +128,8 @@ void WorldSession::SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode ) while(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE) GetPlayer()->GetMotionMaster()->MovementExpired(false); - GetPlayer()->Mount( MountId ); + if (MountId) + GetPlayer()->Mount( MountId ); GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path,pathNode); } @@ -190,7 +191,7 @@ void WorldSession::HandleActivateTaxiFarOpcode ( WorldPacket & recv_data ) sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXIEXPRESS from %d to %d" ,nodes.front(),nodes.back()); - GetPlayer()->ActivateTaxiPathTo(nodes, 0, npc); + GetPlayer()->ActivateTaxiPathTo(nodes, npc); } void WorldSession::HandleTaxiNextDestinationOpcode(WorldPacket& /*recv_data*/) @@ -275,6 +276,6 @@ void WorldSession::HandleActivateTaxiOpcode( WorldPacket & recv_data ) return; } - GetPlayer()->ActivateTaxiPathTo(nodes, 0, npc); + GetPlayer()->ActivateTaxiPathTo(nodes, npc); } -- cgit v1.2.3 From 1fb48b3e3420d9a3a4b6142f062bb3d0cf6156c2 Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 19:01:40 -0500 Subject: [7799] Use single function for SMSG_SPELLNONMELEEDAMAGELOG prepare. Merge comments, replace values by enums. Author: VladimirMangos --HG-- branch : trunk --- src/game/Player.cpp | 2 +- src/game/SharedDefines.h | 7 ++++--- src/game/Unit.cpp | 44 +++++++++++++++++++------------------------- src/game/Unit.h | 37 +++++++++++++++++++------------------ 4 files changed, 43 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index a1ec4606d2a..9e27d2d3bec 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -17163,7 +17163,7 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, Creature* npc // cast case or scripted call case else { - RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + RemoveAurasByType(SPELL_AURA_MOUNTED); if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) RemoveAurasDueToSpell(m_ShapeShiftFormSpellId); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index cc8db7c30f8..5a32744da7c 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1109,9 +1109,10 @@ enum SpellHitType { SPELL_HIT_TYPE_UNK1 = 0x00001, SPELL_HIT_TYPE_CRIT = 0x00002, - SPELL_HIT_TYPE_UNK2 = 0x00004, - SPELL_HIT_TYPE_UNK3 = 0x00008, - SPELL_HIT_TYPE_UNK4 = 0x00020 + SPELL_HIT_TYPE_UNK3 = 0x00004, + SPELL_HIT_TYPE_UNK4 = 0x00008, + SPELL_HIT_TYPE_UNK5 = 0x00010, // replace caster? + SPELL_HIT_TYPE_UNK6 = 0x00020 }; enum SpellDmgClass diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 5782ec9d5a4..c9461d4b218 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4483,38 +4483,32 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log) data.append(log->target->GetPackGUID()); data.append(log->attacker->GetPackGUID()); data << uint32(log->SpellID); - data << uint32(log->damage); //damage amount + data << uint32(log->damage); // damage amount data << uint32(int32 (log->target->GetHealth()-log->damage ) >0 ? 0 : log->damage - log->target->GetHealth()); - data << uint8 (log->schoolMask); //damage school - data << uint32(log->absorb); //AbsorbedDamage - data << uint32(log->resist); //resist - data << uint8 (log->phusicalLog); // damsge type? flag - data << uint8 (log->unused); //unused - data << uint32(log->blocked); //blocked + //data << uint32(log->overkill); // overkill + data << uint8 (log->schoolMask); // damage school + data << uint32(log->absorb); // AbsorbedDamage + data << uint32(log->resist); // resist + data << uint8 (log->physicalLog); // if 1, then client show spell name (example: %s's ranged shot hit %s for %u school or %s suffers %u school damage from %s's spell_name + data << uint8 (log->unused); // unused + data << uint32(log->blocked); // blocked data << uint32(log->HitInfo); - data << uint8 (0); // flag to use extend data + data << uint8 (0); // flag to use extend data SendMessageToSet( &data, true ); } void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit) { - sLog.outDebug("Sending: SMSG_SPELLNONMELEEDAMAGELOG"); - WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16+4+4+1+4+4+1+1+4+4+1)); // we guess size - data.append(target->GetPackGUID()); - data.append(GetPackGUID()); - data << uint32(SpellID); - int32 damageDone = Damage-AbsorbedDamage-Resist-Blocked; - data << uint32(damageDone); - data << uint32(int32 (target->GetHealth()-damageDone ) >0 ? 0 : damageDone - target->GetHealth());// wotlk - data << uint8(damageSchoolMask); // spell school - data << uint32(AbsorbedDamage); // AbsorbedDamage - data << uint32(Resist); // resist - data << uint8(PhysicalDamage); // if 1, then client show spell name (example: %s's ranged shot hit %s for %u school or %s suffers %u school damage from %s's spell_name - data << uint8(0); // unk isFromAura - data << uint32(Blocked); // blocked - data << uint32(CriticalHit ? 0x27 : 0x25); // hitType, flags: 0x2 - SPELL_HIT_TYPE_CRIT, 0x10 - replace caster? - data << uint8(0); // isDebug? - SendMessageToSet( &data, true ); + SpellNonMeleeDamage log(this,target,SpellID,damageSchoolMask); + log.damage = Damage-AbsorbedDamage-Resist-Blocked; + log.absorb = AbsorbedDamage; + log.resist = Resist; + log.physicalLog = PhysicalDamage; + log.blocked = Blocked; + log.HitInfo = SPELL_HIT_TYPE_UNK1 | SPELL_HIT_TYPE_UNK3 | SPELL_HIT_TYPE_UNK6; + if(CriticalHit) + log.HitInfo |= SPELL_HIT_TYPE_CRIT; + SendSpellNonMeleeDamageLog(&log); } void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellEntry const *procSpell) diff --git a/src/game/Unit.h b/src/game/Unit.h index 54384854089..d0173315c7b 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -745,24 +745,25 @@ struct CalcDamageInfo // Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode struct SpellNonMeleeDamage{ - SpellNonMeleeDamage(Unit *_attacker, Unit *_target, uint32 _SpellID, uint32 _schoolMask) - : target(_target), attacker(_attacker), SpellID(_SpellID), damage(0), schoolMask(_schoolMask), - absorb(0), resist(0), phusicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0) - {} - - Unit *target; - Unit *attacker; - uint32 SpellID; - uint32 damage; - uint32 schoolMask; - uint32 absorb; - uint32 resist; - bool phusicalLog; - bool unused; - uint32 blocked; - uint32 HitInfo; - // Used for help - uint32 cleanDamage; + SpellNonMeleeDamage(Unit *_attacker, Unit *_target, uint32 _SpellID, uint32 _schoolMask) + : target(_target), attacker(_attacker), SpellID(_SpellID), damage(0), overkill(0), schoolMask(_schoolMask), + absorb(0), resist(0), physicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0) + {} + + Unit *target; + Unit *attacker; + uint32 SpellID; + uint32 damage; + uint32 overkill; + uint32 schoolMask; + uint32 absorb; + uint32 resist; + bool physicalLog; + bool unused; + uint32 blocked; + uint32 HitInfo; + // Used for help + uint32 cleanDamage; }; uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition); -- cgit v1.2.3 From b7b7262c7c13c8a7c809543f86459a352153e1d1 Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 19:03:56 -0500 Subject: [7800] Small fixes for scripting case ActivateTaxiPathTo use: Author: VladimirMangos * Allow wide mount model lookup in DBC data for script case * Allow 0-coordinates node use in script case --HG-- branch : trunk --- src/game/OutdoorPvPEP.cpp | 2 +- src/game/Player.cpp | 8 +++++--- src/game/SpellAuras.cpp | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/game/OutdoorPvPEP.cpp b/src/game/OutdoorPvPEP.cpp index f0ff85574c0..fc688314e0c 100644 --- a/src/game/OutdoorPvPEP.cpp +++ b/src/game/OutdoorPvPEP.cpp @@ -768,7 +768,7 @@ bool OutdoorPvPObjectiveEP_PWT::HandleGossipOption(Player *plr, uint64 guid, uin nodes[1] = dst; plr->PlayerTalkClass->CloseGossip(); - plr->ActivateTaxiPathTo(nodes, 0, cr); + plr->ActivateTaxiPathTo(nodes, cr); // leave the opvp, seems like moveinlineofsight isn't called when entering a taxi HandlePlayerLeave(plr); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 9e27d2d3bec..4e58fa5b885 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -17204,8 +17204,8 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, Creature* npc return false; } } - // node must have pos if not spell case (npc!=0) - else if(!spellid) + // node must have pos if taxi master case (npc != NULL) + else if (npc) { WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); data << uint32(ERR_TAXIUNSPECIFIEDSERVERERROR); @@ -17257,8 +17257,10 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, Creature* npc prevnode = lastnode; } - uint16 mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam(), spellid != 0); + // get mount model (in case non taximaster (npc==NULL) allow more wide lookup) + uint16 mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam(), npc == NULL); + // in spell case allow 0 model if (mount_id == 0 && spellid == 0 || sourcepath == 0) { WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 3885be1c517..01fc612018d 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -6974,7 +6974,7 @@ void Aura::UnregisterSingleCastAura() } } -void Aura::HandleAuraSafeFall( bool Apply, bool Real ) +void AuraEffect::HandleAuraSafeFall( bool Apply, bool Real ) { // implemented in WorldSession::HandleMovementOpcodes -- cgit v1.2.3 From bd33ebf6d37705547d8db9446918ce502bc8b737 Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 19:20:28 -0500 Subject: [7801] Apply damage mods from scripts or target state not in DealDamage but in new function before send data to client. Author: VladimirMangos * Fixed bug with health decrease (client side visual bug) at spell damage by target with AI::DamageTaken damage set to 0 * Fixed bug with ignore .die command and instant kill damage in some cases. --HG-- branch : trunk --- src/game/Level3.cpp | 22 ++++++++++------- src/game/Player.cpp | 2 ++ src/game/Spell.cpp | 1 + src/game/SpellAuras.cpp | 12 ++++++++-- src/game/SpellEffects.cpp | 3 +-- src/game/Unit.cpp | 60 ++++++++++++++++++++++++++++++++++++++--------- src/game/Unit.h | 1 + 7 files changed, 77 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 1130bcec070..f4ec15bcfb0 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -4028,31 +4028,34 @@ bool ChatHandler::HandleDamageCommand(const char * args) Unit* target = getSelectedUnit(); - if(!target || !m_session->GetPlayer()->GetSelection()) + if (!target || !m_session->GetPlayer()->GetSelection()) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } - if( !target->isAlive() ) + if (!target->isAlive()) return true; char* damageStr = strtok((char*)args, " "); - if(!damageStr) + if (!damageStr) return false; - int32 damage = atoi((char*)damageStr); - if(damage <=0) + int32 damage_int = atoi((char*)damageStr); + if(damage_int <=0) return true; + uint32 damage = damage_int; + char* schoolStr = strtok((char*)NULL, " "); // flat melee damage without resistence/etc reduction - if(!schoolStr) + if (!schoolStr) { m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0); + if (target != m_session->GetPlayer()) + m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0); return true; } @@ -4068,7 +4071,7 @@ bool ChatHandler::HandleDamageCommand(const char * args) char* spellStr = strtok((char*)NULL, " "); // melee damage by specific school - if(!spellStr) + if (!spellStr) { uint32 absorb = 0; uint32 resist = 0; @@ -4080,6 +4083,7 @@ bool ChatHandler::HandleDamageCommand(const char * args) damage -= absorb + resist; + m_session->GetPlayer()->DealDamageMods(target,damage,&absorb); m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0); return true; @@ -4089,7 +4093,7 @@ bool ChatHandler::HandleDamageCommand(const char * args) // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spellid = extractSpellIdFromLink((char*)args); - if(!spellid || !sSpellStore.LookupEntry(spellid)) + if (!spellid || !sSpellStore.LookupEntry(spellid)) return false; m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4e58fa5b885..23bfea068d8 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -897,6 +897,8 @@ void Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage) damage-=absorb+resist; + DealDamageMods(this,damage,&absorb); + WorldPacket data(SMSG_ENVIRONMENTALDAMAGELOG, (21)); data << uint64(GetGUID()); data << uint8(type!=DAMAGE_FALL_TO_VOID ? type : DAMAGE_FALL); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 168e6ddd16f..d4e2207964b 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1028,6 +1028,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) // Add bonuses and fill damageInfo struct caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo); + caster->DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb); // Send log damage message to client caster->SendSpellNonMeleeDamageLog(&damageInfo); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 01fc612018d..5b941a0440f 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -5800,6 +5800,8 @@ void AuraEffect::PeriodicTick() sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u", GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb); + pCaster->DealDamageMods(m_target,pdamage,&absorb); + WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size data.append(m_target->GetPackGUID()); data.appendPackGUID(GetCasterGUID()); @@ -5983,10 +5985,13 @@ void AuraEffect::PeriodicTick() } else { - pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), gain, GetSpellSchoolMask(GetSpellProto()), 0, 0, false, 0, false); + uint32 damage = gain; + uint32 absorb = 0; + pCaster->DealDamageMods(pCaster,damage,&absorb); + pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), damage, GetSpellSchoolMask(GetSpellProto()), absorb, 0, false, 0, false); CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL ); - pCaster->DealDamage(pCaster, gain, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true); + pCaster->DealDamage(pCaster, damage, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true); } } @@ -6202,6 +6207,9 @@ void AuraEffect::PeriodicTick() SpellNonMeleeDamage damageInfo(pCaster, m_target, spellProto->Id, spellProto->SchoolMask); //no SpellDamageBonus for burn mana pCaster->CalculateSpellDamageTaken(&damageInfo, gain, spellProto); + + pCaster->DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb); + pCaster->SendSpellNonMeleeDamageLog(&damageInfo); // Set trigger flag diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 3226ccdbec0..c7119c993ec 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -286,8 +286,7 @@ void Spell::EffectInstaKill(uint32 /*i*/) if(m_caster==unitTarget) // prevent interrupt message finish(); - uint32 health = unitTarget->GetHealth(); - m_caster->DealDamage(unitTarget, health, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_caster->DealDamage(unitTarget, unitTarget->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } void Spell::EffectEnvirinmentalDMG(uint32 i) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c9461d4b218..39e23db5fb9 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -535,10 +535,15 @@ void Unit::RemoveSpellbyDamageTaken(uint32 damage, uint32 spell) } } -uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss) +void Unit::DealDamageMods(Unit *pVictim, uint32 &damage, uint32* absorb) { if (!pVictim->isAlive() || pVictim->hasUnitState(UNIT_STAT_UNATTACKABLE) || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode()) - return 0; + { + if(absorb) + absorb += damage; + damage = 0; + return; + } //You don't lose health from damage taken from another player while in a sanctuary //You still see it in the combat log though @@ -546,14 +551,30 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa { const AreaTableEntry *area = GetAreaEntryByAreaID(pVictim->GetAreaId()); if(area && area->flags & AREA_FLAG_SANCTUARY) //sanctuary - return 0; + { + if(absorb) + absorb += damage; + damage = 0; + } } + uint32 originalDamage = damage; + + //Script Event damage Deal + //if( GetTypeId()== TYPEID_UNIT && ((Creature *)this)->AI()) + // ((Creature *)this)->AI()->DamageDeal(pVictim, damage); //Script Event damage taken if( pVictim->GetTypeId()== TYPEID_UNIT && ((Creature *)pVictim)->IsAIEnabled ) - { ((Creature *)pVictim)->AI()->DamageTaken(this, damage); + if(absorb && originalDamage > damage) + absorb += (originalDamage - damage); +} + +uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss) +{ + if( pVictim->GetTypeId()== TYPEID_UNIT) + { // Set tagging if(!pVictim->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER) && !((Creature*)pVictim)->isPet()) { @@ -1203,6 +1224,7 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage SpellNonMeleeDamage damageInfo(this, pVictim, spellInfo->Id, spellInfo->SchoolMask); damage = SpellDamageBonus(pVictim, spellInfo, damage, SPELL_DIRECT_DAMAGE); CalculateSpellDamageTaken(&damageInfo, damage, spellInfo); + DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb); SendSpellNonMeleeDamageLog(&damageInfo); DealSpellDamage(&damageInfo, true); return damageInfo.damage; @@ -1706,6 +1728,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss) //CalcAbsorbResist(pVictim, SpellSchools(spellProto->School), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); //damage-=absorb + resist; + pVictim->DealDamageMods(this,damage,NULL); + WorldPacket data(SMSG_SPELLDAMAGESHIELD,(8+8+4+4+4+4)); data << uint64(pVictim->GetGUID()); data << uint64(GetGUID()); @@ -2082,8 +2106,12 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe int32 canabsorb = caster->GetHealth(); if (canabsorb < absorbed) absorbed = canabsorb; - DealDamage(caster, absorbed, NULL, damagetype, schoolMask, 0, false); + RemainingDamage -= absorbed; + + uint32 ab_damage = absorbed; + DealDamageMods(caster,ab_damage,NULL); + DealDamage(caster, ab_damage, NULL, damagetype, schoolMask, 0, false); continue; } break; @@ -2192,10 +2220,15 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe RemainingDamage -= currentAbsorb; - SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, currentAbsorb, schoolMask, 0, 0, false, 0, false); - CleanDamage cleanDamage = CleanDamage(currentAbsorb, BASE_ATTACK, MELEE_HIT_NORMAL); - DealDamage(caster, currentAbsorb, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false); + uint32 splitted = currentAbsorb; + uint32 splitted_absorb = 0; + DealDamageMods(caster,splitted,&splitted_absorb); + + SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, splitted_absorb, 0, false, 0, false); + + CleanDamage cleanDamage = CleanDamage(splitted, BASE_ATTACK, MELEE_HIT_NORMAL); + DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false); } AuraEffectList const& vSplitDamagePct = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_PCT); @@ -2212,11 +2245,14 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe if(!caster || caster == pVictim || !caster->IsInWorld() || !caster->isAlive()) continue; - int32 splitted = int32(RemainingDamage * (*i)->GetAmount() / 100.0f); + uint32 splitted = uint32(RemainingDamage * (*i)->GetAmount() / 100.0f); + + RemainingDamage -= int32(splitted); - RemainingDamage -= splitted; + uint32 split_absorb = 0; + DealDamageMods(caster,splitted,&split_absorb); - SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, 0, 0, false, 0, false); + SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, schoolMask, split_absorb, 0, false, 0, false); CleanDamage cleanDamage = CleanDamage(splitted, BASE_ATTACK, MELEE_HIT_NORMAL); DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false); @@ -2351,6 +2387,7 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex CalcDamageInfo damageInfo; CalculateMeleeDamage(pVictim, 0, &damageInfo, attType); // Send log damage message to client + DealDamageMods(pVictim,damageInfo.damage,&damageInfo.absorb); SendAttackStateUpdate(&damageInfo); ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, damageInfo.attackType); DealMeleeDamage(&damageInfo,true); @@ -11916,6 +11953,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag SpellNonMeleeDamage damageInfo(this, pTarget, spellInfo->Id, spellInfo->SchoolMask); uint32 damage = SpellDamageBonus(pTarget, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE); CalculateSpellDamageTaken(&damageInfo, damage, spellInfo); + DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb); SendSpellNonMeleeDamageLog(&damageInfo); DealSpellDamage(&damageInfo, true); break; diff --git a/src/game/Unit.h b/src/game/Unit.h index d0173315c7b..49e8264b277 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1073,6 +1073,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); + void DealDamageMods(Unit *pVictim, uint32 &damage, uint32* absorb); 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); int32 DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellProto, bool critical = false); -- cgit v1.2.3 From ff8d1cf55c3b24230f7567a1689ee14173e2e572 Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 19:22:17 -0500 Subject: [7802] Use more appropriate field types in `character_achievement*` tables. Better check data at loading. Author: VladimirMangos --HG-- branch : trunk --- sql/characters.sql | 14 +++++----- .../7802_01_characters_character_achievement.sql | 6 +++++ ...2_characters_character_achievement_progress.sql | 7 +++++ src/game/AchievementMgr.cpp | 31 +++++++++++++++++++--- 4 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 sql/updates/7802_01_characters_character_achievement.sql create mode 100644 sql/updates/7802_02_characters_character_achievement_progress.sql (limited to 'src') diff --git a/sql/characters.sql b/sql/characters.sql index 4cab438342a..098be23596e 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -316,9 +316,9 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `character_achievement`; CREATE TABLE `character_achievement` ( - `guid` int(11) NOT NULL, - `achievement` int(11) NOT NULL, - `date` int(11) NOT NULL, + `guid` int(11) unsigned NOT NULL, + `achievement` int(11) unsigned NOT NULL, + `date` bigint(11) unsigned NOT NULL default '0', PRIMARY KEY (`guid`,`achievement`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -337,10 +337,10 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `character_achievement_progress`; CREATE TABLE `character_achievement_progress` ( - `guid` int(11) NOT NULL, - `criteria` int(11) NOT NULL, - `counter` int(11) NOT NULL, - `date` int(11) NOT NULL, + `guid` int(11) unsigned NOT NULL, + `criteria` int(11) unsigned NOT NULL, + `counter` int(11) unsigned NOT NULL, + `date` bigint(11) unsigned NOT NULL default '0', PRIMARY KEY (`guid`,`criteria`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/7802_01_characters_character_achievement.sql b/sql/updates/7802_01_characters_character_achievement.sql new file mode 100644 index 00000000000..774d1f6b3a9 --- /dev/null +++ b/sql/updates/7802_01_characters_character_achievement.sql @@ -0,0 +1,6 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_7644_01_characters_character_pet required_7802_01_characters_character_achievement bit; + +ALTER TABLE character_achievement + CHANGE COLUMN guid guid int(11) unsigned NOT NULL, + CHANGE COLUMN achievement achievement int(11) unsigned NOT NULL, + CHANGE COLUMN date date bigint(11) unsigned NOT NULL default '0'; diff --git a/sql/updates/7802_02_characters_character_achievement_progress.sql b/sql/updates/7802_02_characters_character_achievement_progress.sql new file mode 100644 index 00000000000..318a430acc4 --- /dev/null +++ b/sql/updates/7802_02_characters_character_achievement_progress.sql @@ -0,0 +1,7 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_7802_01_characters_character_achievement required_7802_02_characters_character_achievement_progress bit; + +ALTER TABLE character_achievement_progress + CHANGE COLUMN guid guid int(11) unsigned NOT NULL, + CHANGE COLUMN criteria criteria int(11) unsigned NOT NULL, + CHANGE COLUMN counter counter int(11) unsigned NOT NULL, + CHANGE COLUMN date date bigint(11) unsigned NOT NULL default '0'; diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index 321922f821e..84ae9cb659e 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -407,7 +407,14 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri do { Field *fields = achievementResult->Fetch(); - CompletedAchievementData& ca = m_completedAchievements[fields[0].GetUInt32()]; + + uint32 achievement_id = fields[0].GetUInt32(); + + // don't must happen: cleanup at server startup in achievementmgr.LoadCompletedAchievements() + if(!sAchievementStore.LookupEntry(achievement_id)) + continue; + + CompletedAchievementData& ca = m_completedAchievements[achievement_id]; ca.date = time_t(fields[1].GetUInt64()); ca.changed = false; } while(achievementResult->NextRow()); @@ -425,7 +432,15 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri time_t date = time_t(fields[2].GetUInt64()); AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id); - if (!criteria || (criteria->timeLimit && time_t(date + criteria->timeLimit) < time(NULL))) + if (!criteria) + { + // we will remove not existed criteria for all characters + sLog.outError("Not existed achievement creataria %u data removed from table `character_achievement_progress`.",id); + CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE criteria = %u",id); + continue; + } + + if (criteria->timeLimit && time_t(date + criteria->timeLimit) < time(NULL)) continue; CriteriaProgress& progress = m_criteriaProgress[id]; @@ -1763,7 +1778,17 @@ void AchievementGlobalMgr::LoadCompletedAchievements() { bar.step(); Field *fields = result->Fetch(); - m_allCompletedAchievements.insert(fields[0].GetUInt32()); + + uint32 achievement_id = fields[0].GetUInt32(); + if(!sAchievementStore.LookupEntry(achievement_id)) + { + // we will remove not existed achievement for all characters + sLog.outError("Not existed achievement %u data removed from table `character_achievement`.",achievement_id); + CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE achievement = %u",achievement_id); + continue; + } + + m_allCompletedAchievements.insert(achievement_id); } while(result->NextRow()); delete result; -- cgit v1.2.3 From 23a5a8033662f1080385788339b4d4599403a66f Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 19:23:24 -0500 Subject: [7803] Prevent ignore max money limit at use .modify money command. Author: VladimirMangos --HG-- branch : trunk --- src/game/Level1.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 832f2ada5e3..45137c5b214 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -2091,12 +2091,12 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args) uint32 moneyuser = chr->GetMoney(); - if(addmoney < 0) + if (addmoney < 0) { - int32 newmoney = moneyuser + addmoney; + int32 newmoney = int32(moneyuser) + addmoney; sLog.outDetail(GetTrinityString(LANG_CURRENT_MONEY), moneyuser, addmoney, newmoney); - if(newmoney <= 0 ) + if (newmoney <= 0 ) { PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, GetNameLink(chr).c_str()); if (needReportToTarget(chr)) @@ -2106,6 +2106,9 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args) } else { + if (newmoney > MAX_MONEY_AMOUNT) + newmoney = MAX_MONEY_AMOUNT; + PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), GetNameLink(chr).c_str()); if (needReportToTarget(chr)) ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, GetNameLink().c_str(), abs(addmoney)); @@ -2117,7 +2120,11 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args) PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, GetNameLink(chr).c_str()); if (needReportToTarget(chr)) ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, GetNameLink().c_str(), addmoney); - chr->ModifyMoney( addmoney ); + + if (addmoney >=MAX_MONEY_AMOUNT) + chr->SetMoney(MAX_MONEY_AMOUNT); + else + chr->ModifyMoney( addmoney ); } sLog.outDetail(GetTrinityString(LANG_NEW_MONEY), moneyuser, addmoney, chr->GetMoney() ); -- cgit v1.2.3 From efb79ea169cc6d1a7ca1a4c27b3adc32386d4522 Mon Sep 17 00:00:00 2001 From: megamage Date: Fri, 8 May 2009 19:27:04 -0500 Subject: *Fix build. --HG-- branch : trunk --- src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp b/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp index 1a3c40273af..104ef575de5 100644 --- a/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp +++ b/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp @@ -416,7 +416,8 @@ bool GossipSelect_npc_susurrus(Player *player, Creature *_Creature, uint32 sende nodes.resize(2); nodes[0] = 92; //from susurrus nodes[1] = 91; //end at exodar - player->ActivateTaxiPathTo(nodes,11686); //TaxiPath 506. Using invisible model, possible Trinity must allow 0(from dbc) for cases like this. +// player->ActivateTaxiPathTo(nodes,11686); //TaxiPath 506. Using invisible model, possible Trinity must allow 0(from dbc) for cases like this. + player->ActivateTaxiPathTo(nodes); } return true; } -- cgit v1.2.3 From 6592e99f4aa8972452ee5fd426893f2cf832e291 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 10:48:14 -0500 Subject: *Some update of spell target selection. --HG-- branch : trunk --- src/game/GameObject.cpp | 2 +- src/game/Spell.cpp | 27 +++++++++++++++++++-------- src/game/SpellAuras.cpp | 2 +- src/game/SpellEffects.cpp | 20 ++++++++++---------- 4 files changed, 31 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 2f1014eb769..1a2ed5fb6db 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -198,7 +198,7 @@ void GameObject::Update(uint32 /*p_time*/) { // Arming Time for GAMEOBJECT_TYPE_TRAP (6) Unit* owner = GetOwner(); - if (owner && ((Player*)owner)->isInCombat()) + if (owner && owner->isInCombat()) m_cooldownTime = time(NULL) + GetGOInfo()->trap.startDelay; m_lootState = GO_READY; break; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index d4e2207964b..9f0a5dc0fde 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1597,6 +1597,8 @@ WorldObject* Spell::SearchNearbyTarget(float range, SpellTargets TargetType) break; } case SPELL_TARGET_TYPE_CREATURE: + if(m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetEntry() == i_spellST->second.targetEntry) + return m_targets.getUnitTarget(); case SPELL_TARGET_TYPE_DEAD: default: { @@ -1925,7 +1927,13 @@ void Spell::SetTargetMap(uint32 i, uint32 cur) m_targets.setDestination(st->target_X, st->target_Y, st->target_Z); } else - sLog.outError( "SPELL: unknown target coordinates for spell ID %u\n", m_spellInfo->Id ); + { + sLog.outError( "SPELL: unknown target coordinates for spell ID %u", m_spellInfo->Id ); + Unit *target = NULL; + if(uint64 guid = m_caster->GetUInt64Value(UNIT_FIELD_TARGET)) + target = ObjectAccessor::GetUnit(*m_caster, guid); + m_targets.setDestination(target ? target : m_caster); + } break; case TARGET_DST_HOME: if(m_caster->GetTypeId() == TYPEID_PLAYER) @@ -2045,7 +2053,7 @@ void Spell::SetTargetMap(uint32 i, uint32 cur) else if(pushType) { // Dummy, just for client - if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] == SPELL_REQUIRE_DEST) + if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] != SPELL_REQUIRE_UNIT) return; float radius; @@ -3971,13 +3979,16 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_NOT_IN_ARENA; // zone check - uint32 zone, area; - m_caster->GetZoneAndAreaId(zone,area); + if(m_caster->GetTypeId() == TYPEID_UNIT || !((Player*)m_caster)->isGameMaster()) + { + uint32 zone, area; + m_caster->GetZoneAndAreaId(zone,area); - SpellCastResult locRes= spellmgr.GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),zone,area, - m_caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_caster) : NULL); - if(locRes != SPELL_CAST_OK) - return locRes; + SpellCastResult locRes= spellmgr.GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),zone,area, + m_caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_caster) : NULL); + if(locRes != SPELL_CAST_OK) + return locRes; + } // not let players cast spells at mount (and let do it to creatures) if( m_caster->IsMounted() && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell && diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 5b941a0440f..f9bdc6fcd88 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1000,7 +1000,7 @@ void Aura::_AddAura() for(std::vector::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) { if(*itr < 0) - m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), m_target); + m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), true); else if(Unit* caster = GetCaster()) caster->AddAura(*itr, m_target); } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index c7119c993ec..d213040ede4 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4775,17 +4775,17 @@ void Spell::EffectScriptEffect(uint32 effIndex) unitTarget->CastSpell(unitTarget, 44870, true); break; } - // spell of Brutallus - Stomp - case 45185: - { - if(!unitTarget) - return; - - if(unitTarget->HasAura(46394)) // spell of Brutallus - Burn - unitTarget->RemoveAurasDueToSpell(46394); + // spell of Brutallus - Stomp + case 45185: + { + if(!unitTarget) + return; - break; - } + if(unitTarget->HasAura(46394)) // spell of Brutallus - Burn + unitTarget->RemoveAurasDueToSpell(46394); + + break; + } // Negative Energy case 46289: { -- cgit v1.2.3 From f5bae4d5ae97e15a8af6f0003de15c25acb65026 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 10:48:55 -0500 Subject: *Init player motionmaster after field value are initialized. --HG-- branch : trunk --- src/game/CharacterHandler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index d82f0a0b518..93256cea150 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -571,7 +571,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) uint64 playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); - pCurrChar->GetMotionMaster()->Initialize(); // for send server info and strings (config) ChatHandler chH = ChatHandler(pCurrChar); @@ -585,6 +584,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) return; } + pCurrChar->GetMotionMaster()->Initialize(); + SetPlayer(pCurrChar); pCurrChar->SendDungeonDifficulty(false); -- cgit v1.2.3 From 1de3e5d8e846c7bfe48ca4982df7615c392abb9e Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 10:49:55 -0500 Subject: *Some update of random movement generator --HG-- branch : trunk --- src/game/RandomMovementGenerator.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp index 6d147f15b8d..2e0e0174a40 100644 --- a/src/game/RandomMovementGenerator.cpp +++ b/src/game/RandomMovementGenerator.cpp @@ -58,6 +58,9 @@ RandomMovementGenerator::_setRandomLocation(Creature &creature) bool is_water_ok = creature.canSwim(); bool is_air_ok = creature.canFly(); + for(uint32 i = 0;; ++i) + { + const float angle = rand_norm()*(M_PI*2); const float range = rand_norm()*wander_distance; const float distanceX = range * cos(angle); @@ -72,6 +75,12 @@ RandomMovementGenerator::_setRandomLocation(Creature &creature) dist = (nx - X)*(nx - X) + (ny - Y)*(ny - Y); + if(i == 5) + { + nz = Z; + break; + } + if (is_air_ok) // 3D system above ground and above water (flying mode) { const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change @@ -79,12 +88,13 @@ RandomMovementGenerator::_setRandomLocation(Creature &creature) float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height. float wz = map->GetWaterLevel(nx, ny); if (tz >= nz || wz >= nz) - return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick + continue; // Problem here, we must fly above the ground and water, not under. Let's try on next tick } //else if (is_water_ok) // 3D system under water and above ground (swimming mode) else // 2D only { dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE) + // The fastest way to get an accurate result 90% of the time. // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check @@ -95,11 +105,14 @@ RandomMovementGenerator::_setRandomLocation(Creature &creature) { nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher if (fabs(nz-Z)>dist) - return; // let's forget this bad coords where a z cannot be find and retry at next tick + continue; // let's forget this bad coords where a z cannot be find and retry at next tick } } } + break; + } + Traveller traveller(creature); creature.SetOrientation(creature.GetAngle(nx,ny)); i_destinationHolder.SetDestination(traveller, nx, ny, nz); @@ -130,7 +143,8 @@ RandomMovementGenerator::Initialize(Creature &creature) if(!creature.isAlive()) return; - wander_distance = creature.GetRespawnRadius(); + if(!wander_distance) + wander_distance = creature.GetRespawnRadius(); if (creature.canFly()) creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); -- cgit v1.2.3 From e35d07ad81f5acedcbe436bf429db5581edc6b81 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 10:50:41 -0500 Subject: *Update Sapphiron script. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 22 +++- src/bindings/scripts/include/sc_creature.h | 3 +- .../scripts/creature/mob_generic_creature.cpp | 52 ++++++++ .../scripts/zone/naxxramas/boss_sapphiron.cpp | 131 ++++++++++++++++++--- .../scripts/scripts/zone/naxxramas/def_naxxramas.h | 3 + .../scripts/zone/naxxramas/instance_naxxramas.cpp | 11 ++ src/game/Object.cpp | 18 ++- src/game/Object.h | 1 + 8 files changed, 219 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 258c7627dce..a76fbb8e1ef 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -785,13 +785,29 @@ void LoadOverridenSQLData() goInfo->goober.lockId = 57; // need LOCKTYPE_QUICK_OPEN } +#define SPELL(x) const_cast(GetSpellStore()->LookupEntry(x)) + void LoadOverridenDBCData() { SpellEntry *spellInfo; // Black Temple : Illidan : Parasitic Shadowfiend Passive - spellInfo = const_cast(GetSpellStore()->LookupEntry(41913)); - if(spellInfo) + if(spellInfo = SPELL(41913)) spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends -} + // Naxxramas : Sapphiron : Frost Breath Visual Effect + //if(spellInfo = SPELL(30101)) + // spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST; // orig 18 + + //temp, not needed in 310 + if(spellInfo = SPELL(28531)) + { + spellInfo->DurationIndex = 21; + spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; + } + if(spellInfo = SPELL(55799)) + { + spellInfo->DurationIndex = 21; + spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; + } +} diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 638b6926a27..c2c93a520a9 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -137,7 +137,7 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI void JustRespawned(); //Called at waypoint reached or PointMovement end - void MovementInform(uint32, uint32){} + void MovementInform(uint32 type, uint32 id){} // Called when AI is temporarily replaced or put back when possess is applied or removed void OnPossess(bool apply) {} @@ -264,7 +264,6 @@ struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI void MoveInLineOfSight(Unit *) {} void AttackStart(Unit *) {} void EnterEvadeMode() {} - bool IsVisible(Unit *) const { return false; } void UpdateAI(const uint32) {} }; diff --git a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp index 2f2d5349f2a..56155a9ff2f 100644 --- a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp +++ b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp @@ -156,11 +156,58 @@ struct TRINITY_DLL_DECL generic_creatureAI : public ScriptedAI } } }; + CreatureAI* GetAI_generic_creature(Creature *_Creature) { return new generic_creatureAI (_Creature); } +struct TRINITY_DLL_DECL trigger_periodicAI : public NullCreatureAI +{ + trigger_periodicAI(Creature* c) : NullCreatureAI(c) + { + if(me->m_spells[0]) + { + if(me->m_spells[1]) + spell = GetSpellStore()->LookupEntry(HEROIC(me->m_spells[0], me->m_spells[1])); + else + spell = GetSpellStore()->LookupEntry(me->m_spells[0]); + } + else + spell = NULL; + + if(me->m_spells[2]) + { + if(me->m_spells[3]) + interval = HEROIC(me->m_spells[2], me->m_spells[3]); + else + interval = me->m_spells[2]; + } + else + interval = 1000; + timer = interval; + } + + uint32 timer, interval; + const SpellEntry * spell; + + void UpdateAI(const uint32 diff) + { + if(timer < diff) + { + if(spell) + me->CastSpell(me, spell, true); + timer = interval; + } + else + timer -= diff; + } +}; + +CreatureAI* GetAI_trigger_periodic(Creature *_Creature) +{ + return new trigger_periodicAI (_Creature); +} void AddSC_generic_creature() { @@ -169,5 +216,10 @@ void AddSC_generic_creature() newscript->Name="generic_creature"; newscript->GetAI = &GetAI_generic_creature; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="trigger_periodic"; + newscript->GetAI = &GetAI_trigger_periodic; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp index 44e2def1c88..97165d4a389 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp @@ -22,6 +22,7 @@ SDCategory: Naxxramas EndScriptData */ #include "precompiled.h" +#include "def_naxxramas.h" #define EMOTE_BREATH -1533082 #define EMOTE_ENRAGE -1533083 @@ -33,8 +34,10 @@ EndScriptData */ #define SPELL_LIFE_DRAIN HEROIC(28542,55665) #define SPELL_ICEBOLT 28522 #define SPELL_FROST_BREATH 29318 -#define SPELL_FROST_BREATH2 28524 +#define SPELL_FROST_EXPLOSION 28524 +#define SPELL_FROST_MISSILE 30101 #define SPELL_BERSERK 26662 +#define SPELL_DIES 29357 #define SPELL_CHILL HEROIC(28547,55699) @@ -44,6 +47,7 @@ EndScriptData */ enum Phases { PHASE_NULL = 0, + PHASE_BIRTH, PHASE_GROUND, PHASE_FLIGHT, }; @@ -59,8 +63,10 @@ enum Events EVENT_LIFTOFF, EVENT_ICEBOLT, EVENT_BREATH, + EVENT_EXPLOSION, EVENT_LAND, EVENT_GROUND, + EVENT_BIRTH, }; typedef std::map IceBlockMap; @@ -77,6 +83,17 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI uint32 iceboltCount; IceBlockMap iceblocks; + void InitializeAI() + { + float x, y, z; + me->GetPosition(x, y, z); + me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0); + me->SetVisibility(VISIBILITY_OFF); + me->SetReactState(REACT_PASSIVE); + + Reset(); + } + void Reset() { if(phase = PHASE_FLIGHT) @@ -108,13 +125,35 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI } } + void JustDied(Unit*) + { + me->CastSpell(me, SPELL_DIES, true); + } + + void MovementInform(uint32, uint32 id) + { + if(id == 1) + events.ScheduleEvent(EVENT_LIFTOFF, 0); + } + + void DoAction(const int32 param) + { + if(param == DATA_SAPPHIRON_BIRTH) + { + phase = PHASE_BIRTH; + events.ScheduleEvent(EVENT_BIRTH, 25000); + } + } + void EnterPhaseGround() { + phase = PHASE_GROUND; + me->SetReactState(REACT_AGGRESSIVE); events.SetPhase(PHASE_GROUND); events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND); events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND); events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND); - events.ScheduleEvent(EVENT_BLIZZARD, 5000+rand()%15000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_BLIZZARD, 5000+rand()%5000, 0, PHASE_GROUND); events.ScheduleEvent(EVENT_FLIGHT, 45000); } @@ -152,25 +191,37 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI return; case EVENT_CLEAVE: DoCast(me->getVictim(), SPELL_CLEAVE); - events.ScheduleEvent(EVENT_CLEAVE, 10000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND); return; case EVENT_TAIL: DoCastAOE(SPELL_TAIL_SWEEP); - events.ScheduleEvent(EVENT_TAIL, (rand()%2+9)*1000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND); return; case EVENT_DRAIN: DoCastAOE(SPELL_LIFE_DRAIN); events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND); return; case EVENT_BLIZZARD: - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(target,SPELL_SUMMON_BLIZZARD); - events.ScheduleEvent(EVENT_BLIZZARD, 20000, 0, PHASE_GROUND); + { + //DoCastAOE(SPELL_SUMMON_BLIZZARD); + float x, y, z; + me->GetGroundPointAroundUnit(x, y, z, rand_norm()*20, rand_norm()*2*M_PI); + if(Creature *summon = me->SummonCreature(MOB_BLIZZARD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 25000+rand()%5000)) + { + summon->setFaction(me->getFaction()); + summon->GetMotionMaster()->MoveRandom(40); + } + events.ScheduleEvent(EVENT_BLIZZARD, HEROIC(20000,7000), 0, PHASE_GROUND); break; + } case EVENT_FLIGHT: phase = PHASE_FLIGHT; events.SetPhase(PHASE_FLIGHT); - events.ScheduleEvent(EVENT_LIFTOFF, 0); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + float x, y, z, o; + me->GetHomePosition(x, y, z, o); + me->GetMotionMaster()->MovePoint(1, x, y, z); return; } } @@ -179,24 +230,22 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI } else { - if(me->getThreatManager().isThreatListEmpty()) + /*if(me->getThreatManager().isThreatListEmpty()) { EnterEvadeMode(); return; - } + }*/ if(uint32 eventId = events.ExecuteEvent()) { switch(eventId) { case EVENT_LIFTOFF: - me->AttackStop(); - me->GetMotionMaster()->MoveIdle(); me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); me->SendMovementFlagUpdate(); - events.ScheduleEvent(EVENT_ICEBOLT, 1000); - iceboltCount = HeroicMode ? 3 : 2; + events.ScheduleEvent(EVENT_ICEBOLT, 1500); + iceboltCount = HEROIC(2,3); return; case EVENT_ICEBOLT: { @@ -224,23 +273,73 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI return; } case EVENT_BREATH: + { DoScriptText(EMOTE_BREATH, me); + DoCastAOE(SPELL_FROST_MISSILE); + events.ScheduleEvent(EVENT_EXPLOSION, 8000); + return; + } + case EVENT_EXPLOSION: + CastExplosion(); ClearIceBlock(); - events.ScheduleEvent(EVENT_LAND, 1000); + events.ScheduleEvent(EVENT_LAND, 3000); return; case EVENT_LAND: me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); me->SendMovementFlagUpdate(); - events.ScheduleEvent(EVENT_GROUND, 1000); + events.ScheduleEvent(EVENT_GROUND, 1500); return; case EVENT_GROUND: EnterPhaseGround(); return; + case EVENT_BIRTH: + me->SetVisibility(VISIBILITY_ON); + me->SetReactState(REACT_AGGRESSIVE); + return; } }//if(uint32 eventId = events.ExecuteEvent()) }//if(phase == PHASE_GROUND) } + + void CastExplosion() + { + DoZoneInCombat(); // make sure everyone is in threatlist + std::vector targets; + std::list::iterator i = me->getThreatManager().getThreatList().begin(); + for(; i != me->getThreatManager().getThreatList().end(); ++i) + { + Unit *target = (*i)->getTarget(); + if(target->GetTypeId() != TYPEID_PLAYER) + continue; + + if(target->HasAura(SPELL_ICEBOLT)) + { + target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); + targets.push_back(target); + continue; + } + + for(IceBlockMap::iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr) + { + if(GameObject *go = GameObject::GetGameObject(*me, itr->second)) + { + if(go->IsInBetween(me, target, 2.0f) + && me->GetExactDistance2d(target->GetPositionX(), target->GetPositionY()) - me->GetExactDistance2d(go->GetPositionX(), go->GetPositionY()) < 5.0f) + { + target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); + targets.push_back(target); + break; + } + } + } + } + + me->CastSpell(me, SPELL_FROST_EXPLOSION, true); + + for(std::vector::iterator itr = targets.begin(); itr != targets.end(); ++itr) + (*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false); + } }; CreatureAI* GetAI_boss_sapphiron(Creature *_Creature) diff --git a/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h b/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h index b0931c556fe..12c1dc6edfa 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h +++ b/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h @@ -29,7 +29,10 @@ enum Encounter enum Data { DATA_HEIGAN_ERUPT, + DATA_SAPPHIRON_BIRTH, }; +#define GO_BIRTH 181356 + #endif diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index dfa085f39be..4743a44f2d3 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -58,11 +58,21 @@ inline uint32 GetEruptionSection(float x, float y) struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance { instance_naxxramas(Map *map) : ScriptedInstance(map) + , Sapphiron(NULL) { SetBossNumber(15); } std::set HeiganEruption[4]; + Creature *Sapphiron; + + void OnCreatureCreate(Creature *creature, bool add) + { + switch(creature->GetEntry()) + { + case 15989: Sapphiron = add ? creature : NULL; break; + } + } void OnObjectCreate(GameObject* go, bool add) { @@ -83,6 +93,7 @@ struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance case 181202: SetBossRoomDoor(BOSS_HEIGAN, go, add); break; case 181203: SetBossPassageDoor(BOSS_HEIGAN, go, add); break; case 181241: SetBossRoomDoor(BOSS_LOATHEB, go, add); break; + case GO_BIRTH: if(!add && Sapphiron) Sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); break; } } diff --git a/src/game/Object.cpp b/src/game/Object.cpp index f649164e21b..6b7a3cdd4ac 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1309,6 +1309,21 @@ bool WorldObject::HasInArc(const float arcangle, const WorldObject* obj) const return (( angle >= lborder ) && ( angle <= rborder )); } +bool WorldObject::IsInBetween(const WorldObject *obj1, const WorldObject *obj2, float size) const +{ + if(GetPositionX() > std::max(obj1->GetPositionX(), obj2->GetPositionX()) + || GetPositionX() < std::min(obj1->GetPositionX(), obj2->GetPositionX()) + || GetPositionY() > std::max(obj1->GetPositionY(), obj2->GetPositionY()) + || GetPositionY() < std::min(obj1->GetPositionY(), obj2->GetPositionY())) + return false; + + if(!size) + size = GetObjectSize() / 2; + + float angle = obj1->GetAngle(this) - obj1->GetAngle(obj2); + return abs(sin(angle)) * GetExactDistance2d(obj1->GetPositionX(), obj1->GetPositionY()) < size; +} + void WorldObject::GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z) const { if(distance==0) @@ -1658,6 +1673,8 @@ TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float a return NULL; } + summon->SetHomePosition(x, y, z, angle); + summon->InitStats(duration); Add((Creature*)summon); summon->InitSummon(); @@ -1680,7 +1697,6 @@ TempSummon* WorldObject::SummonCreature(uint32 entry, float x, float y, float z, if(!pCreature) return NULL; - pCreature->SetHomePosition(x, y, z, ang); pCreature->SetTempSummonType(spwtype); return pCreature; diff --git a/src/game/Object.h b/src/game/Object.h index 68438c4df85..e7e03501dc1 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -480,6 +480,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object float GetAngle( const float x, const float y ) const; void GetSinCos(const float x, const float y, float &vsin, float &vcos); bool HasInArc( const float arcangle, const WorldObject* obj ) const; + bool IsInBetween(const WorldObject *obj1, const WorldObject *obj2, float size = 0) const; virtual void SendMessageToSet(WorldPacket *data, bool self, bool to_possessor = true); virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor = true); -- cgit v1.2.3 From 0681a2131edf0e05adfe1794829f48fe7a4742e3 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 10:58:31 -0500 Subject: *Fix a bug that guardian pets do not have correct stats. --HG-- branch : trunk --- src/game/TemporarySummon.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp index 170e590fd9c..14a347ee4bd 100644 --- a/src/game/TemporarySummon.cpp +++ b/src/game/TemporarySummon.cpp @@ -309,6 +309,8 @@ void Guardian::InitStats(uint32 duration) { Minion::InitStats(duration); + InitStatsForLevel(m_owner->getLevel()); + if(m_owner->GetTypeId() == TYPEID_PLAYER) m_charmInfo->InitCharmCreateSpells(); -- cgit v1.2.3 From 08a0c543d1bde434a2d994ae3ab71035343c8039 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 14:08:11 -0500 Subject: *Fix some typos of script functions. --HG-- branch : trunk --- src/game/CreatureAI.cpp | 4 ++-- src/game/GameObject.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 5fd35150b52..5cde80aaccb 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -86,14 +86,14 @@ void CreatureAI::DoZoneInCombat(Creature* creature) if(!creature->getVictim()) { if(Unit *target = creature->SelectNearestTarget()) - AttackStart(target); + creature->AI()->AttackStart(target); else if(creature->isSummon()) { if(Unit *summoner = ((TempSummon*)creature)->GetSummoner()) { if(summoner->getVictim() && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(summoner->getVictim()))) - AttackStart(summoner->getVictim()); + creature->AI()->AttackStart(summoner->getVictim()); } } } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 1a2ed5fb6db..540ea1e0dd7 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -174,7 +174,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa //Normally non-players do not teleport to other maps. if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData()) { - ((InstanceMap*)map)->GetInstanceData()->OnObjectCreate(this); + ((InstanceMap*)map)->GetInstanceData()->OnObjectCreate(this, true); } return true; -- cgit v1.2.3 From 36a3696f350a244e84ccad642b3c98335dc088c2 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 14:08:42 -0500 Subject: *Update instance script functions. --HG-- branch : trunk --- src/game/InstanceData.cpp | 104 ++++++++++++++++++++++++---------------------- src/game/InstanceData.h | 41 ++++++++++++++---- 2 files changed, 86 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/game/InstanceData.cpp b/src/game/InstanceData.cpp index 92e4b4afe3d..80e728f7b3c 100644 --- a/src/game/InstanceData.cpp +++ b/src/game/InstanceData.cpp @@ -57,42 +57,66 @@ void InstanceData::OnCreatureCreate(Creature *creature, bool add) OnCreatureCreate(creature, creature->GetEntry()); } -void InstanceData::SetBossRoomDoor(uint32 id, GameObject *door, bool add) +void InstanceData::LoadDoorData(const DoorData *data) { - if(id < bosses.size()) + while(data->entry) { - if(add) + if(data->bossId < bosses.size()) + doors.insert(std::make_pair(data->entry, DoorInfo(&bosses[data->bossId], data->type))); + + ++data; + } + sLog.outDebug("InstanceData::LoadDoorData: %u doors loaded.", doors.size()); +} + +void InstanceData::UpdateDoorState(GameObject *door) +{ + DoorInfoMap::iterator lower = doors.lower_bound(door->GetEntry()); + DoorInfoMap::iterator upper = doors.upper_bound(door->GetEntry()); + if(lower == upper) + return; + + bool open = true; + for(DoorInfoMap::iterator itr = lower; itr != upper; ++itr) + { + if(itr->second.type == DOOR_TYPE_ROOM) { - BossInfo *bossInfo = &bosses[id]; - bossInfo->roomDoor.insert(door); - // Room door is only closed when encounter is in progress - if(bossInfo->state == IN_PROGRESS) - door->SetGoState(GO_STATE_READY); - else - door->SetGoState(GO_STATE_ACTIVE); + if(itr->second.bossInfo->state == IN_PROGRESS) + { + open = false; + break; + } + } + else if(itr->second.type == DOOR_TYPE_PASSAGE) + { + if(itr->second.bossInfo->state != DONE) + { + open = false; + break; + } } - else - bosses[id].roomDoor.erase(door); } + + door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY); } -void InstanceData::SetBossPassageDoor(uint32 id, GameObject *door, bool add) +void InstanceData::AddDoor(GameObject *door, bool add) { - if(id < bosses.size()) + DoorInfoMap::iterator lower = doors.lower_bound(door->GetEntry()); + DoorInfoMap::iterator upper = doors.upper_bound(door->GetEntry()); + if(lower == upper) + return; + + for(DoorInfoMap::iterator itr = lower; itr != upper; ++itr) { if(add) - { - BossInfo *bossInfo = &bosses[id]; - bossInfo->passageDoor.insert(door); - // Passage door is only opened when boss is defeated - if(bossInfo->state == DONE) - door->SetGoState(GO_STATE_ACTIVE); - else - door->SetGoState(GO_STATE_READY); - } + itr->second.bossInfo->door[itr->second.type].insert(door); else - bosses[id].passageDoor.erase(door); + itr->second.bossInfo->door[itr->second.type].erase(door); } + + if(add) + UpdateDoorState(door); } void InstanceData::SetBossState(uint32 id, EncounterState state) @@ -100,33 +124,13 @@ void InstanceData::SetBossState(uint32 id, EncounterState state) if(id < bosses.size()) { BossInfo *bossInfo = &bosses[id]; + if(bossInfo->state == state) + return; + bossInfo->state = state; - switch(state) - { - case NOT_STARTED: - // Open all room doors, close all passage doors - for(DoorSet::iterator i = bossInfo->roomDoor.begin(); i != bossInfo->roomDoor.end(); ++i) - (*i)->SetGoState(GO_STATE_ACTIVE); - for(DoorSet::iterator i = bossInfo->passageDoor.begin(); i != bossInfo->passageDoor.end(); ++i) - (*i)->SetGoState(GO_STATE_READY); - break; - case IN_PROGRESS: - // Close all doors - for(DoorSet::iterator i = bossInfo->roomDoor.begin(); i != bossInfo->roomDoor.end(); ++i) - (*i)->SetGoState(GO_STATE_READY); - for(DoorSet::iterator i = bossInfo->passageDoor.begin(); i != bossInfo->passageDoor.end(); ++i) - (*i)->SetGoState(GO_STATE_READY); - break; - case DONE: - // Open all doors - for(DoorSet::iterator i = bossInfo->roomDoor.begin(); i != bossInfo->roomDoor.end(); ++i) - (*i)->SetGoState(GO_STATE_ACTIVE); - for(DoorSet::iterator i = bossInfo->passageDoor.begin(); i != bossInfo->passageDoor.end(); ++i) - (*i)->SetGoState(GO_STATE_ACTIVE); - break; - default: - break; - } + for(uint32 type = 0; type < MAX_DOOR_TYPES; ++type) + for(DoorSet::iterator i = bossInfo->door[type].begin(); i != bossInfo->door[type].end(); ++i) + UpdateDoorState(*i); } } diff --git a/src/game/InstanceData.h b/src/game/InstanceData.h index 2d7e5f84746..d68cb7ff7f8 100644 --- a/src/game/InstanceData.h +++ b/src/game/InstanceData.h @@ -42,11 +42,34 @@ enum EncounterState typedef std::set DoorSet; +enum DoorType +{ + DOOR_TYPE_ROOM = 0, + DOOR_TYPE_PASSAGE, + MAX_DOOR_TYPES, +}; + struct BossInfo { BossInfo() : state(NOT_STARTED) {} EncounterState state; - DoorSet roomDoor, passageDoor; + DoorSet door[MAX_DOOR_TYPES]; +}; + +struct DoorInfo +{ + explicit DoorInfo(BossInfo *_bossInfo, DoorType _type) + : bossInfo(_bossInfo), type(_type) {} + BossInfo *bossInfo; + DoorType type; +}; + +typedef std::multimap DoorInfoMap; + +struct DoorData +{ + uint32 entry, bossId; + DoorType type; }; class TRINITY_DLL_SPEC InstanceData @@ -80,15 +103,10 @@ class TRINITY_DLL_SPEC InstanceData virtual void OnPlayerEnter(Player *) {} //Called when a gameobject is created - virtual void OnObjectCreate(GameObject *go, bool add) - { - OnObjectCreate(go); - } - virtual void OnObjectCreate(GameObject *) {} + virtual void OnObjectCreate(GameObject *go, bool add) { OnObjectCreate(go); } //called on creature creation virtual void OnCreatureCreate(Creature *, bool add); - virtual void OnCreatureCreate(Creature *, uint32 entry) {} //All-purpose data storage 64 bit virtual uint64 GetData64(uint32 /*Data*/) { return 0; } @@ -105,9 +123,11 @@ class TRINITY_DLL_SPEC InstanceData void SetBossState(uint32 id, EncounterState state); protected: + void LoadDoorData(const DoorData *data); + void SetBossNumber(uint32 number) { bosses.resize(number); } - void SetBossRoomDoor(uint32 id, GameObject *door, bool add); - void SetBossPassageDoor(uint32 id, GameObject *door, bool add); + void AddDoor(GameObject *door, bool add); + void UpdateDoorState(GameObject *door); std::string GetBossSave() { @@ -119,7 +139,10 @@ class TRINITY_DLL_SPEC InstanceData private: std::vector bosses; + DoorInfoMap doors; + virtual void OnObjectCreate(GameObject *) {} + virtual void OnCreatureCreate(Creature *, uint32 entry) {} }; #endif -- cgit v1.2.3 From 4a0bdedc58db98755a64d9cfb289efe06780c987 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 14:09:11 -0500 Subject: *Update naxx scripts. --HG-- branch : trunk --- .../scripts/scripts/zone/naxxramas/boss_noth.cpp | 29 +++++++++++++++++++--- .../scripts/zone/naxxramas/boss_sapphiron.cpp | 2 +- .../scripts/zone/naxxramas/instance_naxxramas.cpp | 22 +++++++++++----- 3 files changed, 42 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp index 087bc8dc12c..a0ab51a9a2b 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp @@ -45,8 +45,16 @@ EndScriptData */ #define TELE_Z 274.040 #define TELE_O 6.277 -// IMPORTANT: BALCONY TELEPORT NOT ADDED YET! WILL BE ADDED SOON! -// Dev note 26.12.2008: When is soon? :) +#define MAX_SUMMON_POS 5 + +const float SummonPos[MAX_SUMMON_POS][4] = +{ + {2728.12, -3544.43, 261.91, 6.04}, + {2729.05, -3544.47, 261.91, 5.58}, + {2728.24, -3465.08, 264.20, 3.56}, + {2704.11, -3456.81, 265.53, 4.51}, + {2663.56, -3464.43, 262.66, 5.20}, +}; enum Events { @@ -71,6 +79,7 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI { events.Reset(); summons.DespawnAll(); + me->setActive(false); instance->SetBossState(BOSS_NOTH, NOT_STARTED); } @@ -78,6 +87,7 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI { DoScriptText(SAY_AGGRO, me); DoZoneInCombat(); + me->setActive(true); events.ScheduleEvent(EVENT_CURSE, 20000+rand()%10000); events.ScheduleEvent(EVENT_WARRIOR, 30000); @@ -95,6 +105,7 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI void JustSummoned(Creature *summon) { summons.Summon(summon); + summon->setActive(true); DoZoneInCombat(summon); } @@ -102,10 +113,21 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI void JustDied(Unit* Killer) { + summons.DespawnAll(); DoScriptText(SAY_DEATH, me); instance->SetBossState(BOSS_NOTH, DONE); } + void SummonUndead(uint32 entry, uint32 num) + { + for(uint32 i = 0; i < num; ++i) + { + uint32 pos = rand()%MAX_SUMMON_POS; + me->SummonCreature(entry, SummonPos[pos][0], SummonPos[pos][1], SummonPos[pos][2], + SummonPos[pos][3], TEMPSUMMON_CORPSE_DESPAWN, 60000); + } + } + void UpdateAI(const uint32 diff) { if(!UpdateVictim()) @@ -123,8 +145,7 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI return; case EVENT_WARRIOR: DoScriptText(SAY_SUMMON, me); - for(uint8 i = 0; i < 6; i++) - m_creature->SummonCreature(MOB_WARRIOR,2684.804,-3502.517,261.313,0,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,80000); + SummonUndead(MOB_WARRIOR, HEROIC(2,3)); events.ScheduleEvent(EVENT_WARRIOR, 30000); return; case EVENT_BLINK: diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp index 97165d4a389..9ba4bd1f7ee 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp @@ -141,7 +141,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI if(param == DATA_SAPPHIRON_BIRTH) { phase = PHASE_BIRTH; - events.ScheduleEvent(EVENT_BIRTH, 25000); + events.ScheduleEvent(EVENT_BIRTH, 23000); } } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index 4743a44f2d3..034141e2580 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -24,6 +24,18 @@ EndScriptData */ #include "precompiled.h" #include "def_naxxramas.h" +const DoorData doorData[] = +{ + {181200, BOSS_NOTH, DOOR_TYPE_ROOM}, + {181201, BOSS_NOTH, DOOR_TYPE_PASSAGE}, + {181202, BOSS_NOTH, DOOR_TYPE_PASSAGE}, + {181202, BOSS_HEIGAN, DOOR_TYPE_ROOM}, + {181203, BOSS_HEIGAN, DOOR_TYPE_PASSAGE}, + {181241, BOSS_HEIGAN, DOOR_TYPE_PASSAGE}, + {181241, BOSS_LOATHEB, DOOR_TYPE_ROOM}, + {0, 0, DOOR_TYPE_ROOM}, // EOF +}; + #define SPELL_ERUPTION 29371 const float HeiganPos[2] = {2796, -3707}; @@ -61,6 +73,7 @@ struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance , Sapphiron(NULL) { SetBossNumber(15); + LoadDoorData(doorData); } std::set HeiganEruption[4]; @@ -88,13 +101,10 @@ struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance switch(go->GetEntry()) { - case 181200: SetBossRoomDoor(BOSS_NOTH, go, add); break; - case 181201: SetBossPassageDoor(BOSS_NOTH, go, add); break; - case 181202: SetBossRoomDoor(BOSS_HEIGAN, go, add); break; - case 181203: SetBossPassageDoor(BOSS_HEIGAN, go, add); break; - case 181241: SetBossRoomDoor(BOSS_LOATHEB, go, add); break; - case GO_BIRTH: if(!add && Sapphiron) Sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); break; + case GO_BIRTH: if(!add && Sapphiron) Sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); return; } + + AddDoor(go, add); } void SetData(uint32 id, uint32 value) -- cgit v1.2.3 From 025a24f96ef04b4c76e54f0feb2f513dd7abe7de Mon Sep 17 00:00:00 2001 From: raczman Date: Sat, 9 May 2009 22:33:18 +0200 Subject: Correct percent of threat redirected for Misdirection aura. By tvaroh This patch is only 2.4.3 valid, please do not pull it to TC2. --HG-- branch : trunk --- src/game/SpellEffects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index efdcf30a1f9..9ee2050a6ab 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -6280,6 +6280,6 @@ void Spell::EffectQuestFail(uint32 i) void Spell::EffectRedirectThreat(uint32 /*i*/) { if(unitTarget) - m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID()); + m_caster->SetReducedThreatPercent(100, unitTarget->GetGUID()); } -- cgit v1.2.3 From e5f93acf31fb3864d19393da003a261cd8881daf Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 19:41:26 -0500 Subject: *Fix the bug that player get fall damage after taxi flight. --HG-- branch : trunk --- src/game/WaypointMovementGenerator.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index 7cabd63acf1..ae7ef0bce00 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -251,6 +251,7 @@ void FlightPathMovementGenerator::Initialize(Player &player) player.getHostilRefManager().setOnlineOfflineState(false); player.addUnitState(UNIT_STAT_IN_FLIGHT); player.SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); + player.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); LoadPath(player); Traveller traveller(player); // do not send movement, it was sent already @@ -270,6 +271,7 @@ void FlightPathMovementGenerator::Finalize(Player & player) player.Unmount(); player.RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); + player.RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING2); if(player.m_taxi.empty()) { -- cgit v1.2.3 From a7f663a748f862f15ace6f5468dfb0bac161b7e0 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 19:58:30 -0500 Subject: *Fix a bug of teleport visual effect. --HG-- branch : trunk --- src/game/Unit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 39e23db5fb9..6bd9c52c7d5 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -13937,7 +13937,7 @@ void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool ca DestroyForNearbyPlayers(); GetMap()->CreatureRelocation((Creature*)this, x, y, z, orientation); - ObjectAccessor::UpdateObjectVisibility(this); + //ObjectAccessor::UpdateObjectVisibility(this); //WorldPacket data; // Work strange for many spells: triggered active mover set for targeted player to creature -- cgit v1.2.3 From dddc39c1abaf028531ffe218d48008e01bc3fe26 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 19:58:55 -0500 Subject: *Fix a typo in canSeeSpellClickOn. --HG-- branch : trunk --- src/game/Player.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 23bfea068d8..bfd47aa8279 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1800,7 +1800,7 @@ void Player::AddToWorld() ///- The player should only be added when logging in Unit::AddToWorld(); - for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++) + for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i) { if(m_items[i]) m_items[i]->AddToWorld(); @@ -1817,7 +1817,7 @@ void Player::RemoveFromWorld() StopCastingBindSight(); } - for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++) + for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i) { if(m_items[i]) m_items[i]->RemoveFromWorld(); @@ -20552,12 +20552,14 @@ void Player::ResummonPetTemporaryUnSummonedIfAny() bool Player::canSeeSpellClickOn(Creature const *c) const { - SpellClickInfoMap const& map = objmgr.mSpellClickInfoMap; - if(map.empty()) + SpellClickInfoMap::const_iterator lower = objmgr.mSpellClickInfoMap.lower_bound(c->GetEntry()); + SpellClickInfoMap::const_iterator upper = objmgr.mSpellClickInfoMap.upper_bound(c->GetEntry()); + if(lower == upper) return true; - for(SpellClickInfoMap::const_iterator itr = map.lower_bound(c->GetEntry()); itr != map.upper_bound(c->GetEntry()); ++itr) + for(SpellClickInfoMap::const_iterator itr = lower; itr != upper; ++itr) { + sLog.outError("%u %u %u %u", (uint32)itr->second.castFlags, itr->second.questId, itr->second.spellId); if(itr->second.questId == 0 || GetQuestStatus(itr->second.questId) == QUEST_STATUS_INCOMPLETE) return true; } -- cgit v1.2.3 From ecc953dd3d5bc948fea774d5a55c0b98f5795833 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 21:58:33 -0500 Subject: *Fix some bugs of spell target selection. Thanks to StarJoker. --HG-- branch : trunk --- src/game/Spell.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 9f0a5dc0fde..122caa96373 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1756,15 +1756,15 @@ void Spell::SetTargetMap(uint32 i, uint32 cur) if(!target) return; - else if(target->GetTypeId() == TYPEID_UNIT) + else if(target->GetTypeId() == TYPEID_GAMEOBJECT) + AddGOTarget((GameObject*)target, i); + else { pushType = PUSH_CHAIN; - if(!m_targets.getUnitTarget()) + if(m_targets.getUnitTarget() != target) m_targets.setUnitTarget((Unit*)target); } - else if(target->GetTypeId() == TYPEID_GAMEOBJECT) - AddGOTarget((GameObject*)target, i); break; } @@ -2235,9 +2235,20 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura if(!m_targets.getUnitTargetGUID() && m_spellInfo->Targets & TARGET_FLAG_UNIT) { - if(Unit *target = ObjectAccessor::GetUnit(*m_caster, m_caster->GetUInt64Value(UNIT_FIELD_TARGET))) - if(IsValidSingleTargetSpell(target)) - m_targets.setUnitTarget(target); + Unit *target = NULL; + if(m_caster->GetTypeId() == TYPEID_UNIT) + target = m_caster->getVictim(); + else + target = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection()); + + if(target && IsValidSingleTargetSpell(target)) + m_targets.setUnitTarget(target); + else + { + SendCastResult(SPELL_FAILED_BAD_TARGETS); + finish(false); + return; + } } m_spellState = SPELL_STATE_PREPARING; -- cgit v1.2.3 From 3b14179f65d3c0cd14604d8698d5af438cca25e3 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 21:59:01 -0500 Subject: *Allow dismiss possessed units. --HG-- branch : trunk --- src/game/PetHandler.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src') diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 42d0093510b..bfbe8ca7df4 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -89,10 +89,6 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid switch(flag) { case ACT_COMMAND: //0x0700 - // Possessed or shared vision pets are only able to attack - if ((pet->isPossessed() || pet->HasAuraType(SPELL_AURA_BIND_SIGHT)) && spellid != COMMAND_ATTACK) - return; - switch(spellid) { case COMMAND_STAY: //flat=1792 //STAY @@ -162,10 +158,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid } case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) if(pet->GetCharmerGUID() == GetPlayer()->GetGUID()) - { - if(GetPlayer()->m_seer != pet) - _player->StopCastingCharm(); - } + _player->StopCastingCharm(); else if(pet->GetOwnerGUID() == GetPlayer()->GetGUID()) { assert(pet->GetTypeId() == TYPEID_UNIT); -- cgit v1.2.3 From 67876f9dfe14783e9c81bf5a8bab6843d30b22bc Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 22:00:18 -0500 Subject: *Fix a creature spell use bug. --HG-- branch : trunk --- sql/world_spell_full.sql | 5 +++-- .../scripts/creature/mob_generic_creature.cpp | 21 ++------------------- src/game/TemporarySummon.cpp | 5 +---- 3 files changed, 6 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/sql/world_spell_full.sql b/sql/world_spell_full.sql index 915aabeb669..c892b3291fa 100644 --- a/sql/world_spell_full.sql +++ b/sql/world_spell_full.sql @@ -151,13 +151,14 @@ INSERT INTO creature_template (entry, spell1, flags_extra, scriptname) VALUES (23069, 40029, 128, ''), # demon fire (24187, 43218, 128, ''), # pillar of fire (17662, 30914, 128, ''), # Broggok Poison Cloud -(25879, 46262, 128, '') # Void Zone Periodic +(25879, 46262, 128, ''), # Void Zone Periodic +(16363, 28158, 128, ''), # Grobbulus Cloud +(29379, 54362, 128, ''), # Grobbulus Cloud (H) ON DUPLICATE KEY UPDATE spell1 = VALUES(spell1), flags_extra = VALUES(flags_extra), scriptname = VALUES(scriptname); -UPDATE creature_template SET spell1 = 28158, spell2 = 54362, flags_extra = 128 WHERE entry = 16363; UPDATE creature_template SET speed = 1.0 WHERE entry = 23095; # molten_flame diff --git a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp index 56155a9ff2f..ec987e31c0e 100644 --- a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp +++ b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp @@ -166,25 +166,8 @@ struct TRINITY_DLL_DECL trigger_periodicAI : public NullCreatureAI { trigger_periodicAI(Creature* c) : NullCreatureAI(c) { - if(me->m_spells[0]) - { - if(me->m_spells[1]) - spell = GetSpellStore()->LookupEntry(HEROIC(me->m_spells[0], me->m_spells[1])); - else - spell = GetSpellStore()->LookupEntry(me->m_spells[0]); - } - else - spell = NULL; - - if(me->m_spells[2]) - { - if(me->m_spells[3]) - interval = HEROIC(me->m_spells[2], me->m_spells[3]); - else - interval = me->m_spells[2]; - } - else - interval = 1000; + spell = me->m_spells[0] ? GetSpellStore()->LookupEntry(me->m_spells[0]) : NULL; + interval = me->m_spells[1] ? me->m_spells[1] : 1000; timer = interval; } diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp index 14a347ee4bd..afea0e5ed53 100644 --- a/src/game/TemporarySummon.cpp +++ b/src/game/TemporarySummon.cpp @@ -208,10 +208,7 @@ void TempSummon::InitSummon() if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER && m_spells[0]) { setFaction(owner->getFaction()); - if(m_spells[1] && GetMap()->IsHeroic()) - CastSpell(this, m_spells[1], false, 0, 0, m_summonerGUID); - else - CastSpell(this, m_spells[0], false, 0, 0, m_summonerGUID); + CastSpell(this, m_spells[0], false, 0, 0, m_summonerGUID); } } } -- cgit v1.2.3 From 883c2ef77da57f12887cfcdbaed03bf1ea50e6b9 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 22:31:53 -0500 Subject: *Do not allow persistant auras from the same caster stack on target. --HG-- branch : trunk --- src/game/Creature.cpp | 6 +++--- src/game/GridNotifiersImpl.h | 7 +++++-- src/game/SpellAuras.cpp | 6 ++++-- src/game/Unit.cpp | 14 +++++--------- src/game/Unit.h | 2 +- 5 files changed, 18 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 01f43ac8163..a47afda5cd2 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -164,8 +164,8 @@ Creature::~Creature() i_AI = NULL; } - if(m_uint32Values) - sLog.outDetail("Deconstruct Creature Entry = %u", GetEntry()); + //if(m_uint32Values) + // sLog.outDetail("Deconstruct Creature Entry = %u", GetEntry()); } void Creature::AddToWorld() @@ -2105,7 +2105,7 @@ bool Creature::LoadCreaturesAddon(bool reload) continue; } - AddAuraEffect(AdditionalSpellInfo->Id, cAura->effect_idx, this); + AddAuraEffect(AdditionalSpellInfo, cAura->effect_idx, this); sLog.outDebug("Spell: %u with Aura %u added to creature (GUIDLow: %u Entry: %u )", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[cAura->effect_idx],GetGUIDLow(),GetEntry()); } } diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index 7726d5647bd..7b7911820c6 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -178,8 +178,11 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target) if (i_dynobject.IsAffecting(target)) return; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId()); uint32 eff_index = i_dynobject.GetEffIndex(); + if(target->HasAuraEffect(i_dynobject.GetSpellId(), eff_index, i_check->GetGUID())) + return; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId()); if(spellInfo->EffectImplicitTargetB[eff_index] == TARGET_DEST_DYNOBJ_ALLY || spellInfo->EffectImplicitTargetB[eff_index] == TARGET_UNIT_AREA_ALLY_DST) { @@ -205,7 +208,7 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target) if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index)) return; // Apply PersistentAreaAura on target - target->AddAuraEffect(spellInfo->Id, eff_index, i_dynobject.GetCaster()); + target->AddAuraEffect(spellInfo, eff_index, i_dynobject.GetCaster()); i_dynobject.AddAffected(target); } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index f9bdc6fcd88..b8f65626e7d 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -750,7 +750,7 @@ void AreaAuraEffect::Update(uint32 diff) // recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?) //if(actualSpellInfo != GetSpellProto()) // actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex]; - Aura * aur = (*tIter)->AddAuraEffect(actualSpellInfo->Id, GetEffIndex(), caster, &m_currentBasePoints); + (*tIter)->AddAuraEffect(actualSpellInfo, GetEffIndex(), caster, &m_currentBasePoints); if(m_areaAuraType == AREA_AURA_ENEMY) caster->CombatStart(*tIter); @@ -5698,6 +5698,7 @@ void AuraEffect::PeriodicTick() if(!pCaster) return; + // Consecrate ticks can miss and will not show up in the combat log if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA && pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE) return; @@ -5746,7 +5747,8 @@ void AuraEffect::PeriodicTick() } } m_amount = 100 * m_tickNumber; - }break; + break; + } default: break; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 6bd9c52c7d5..7a3385acabf 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -13610,16 +13610,12 @@ void Unit::AddAura(uint32 spellId, Unit* target) target->AddAura(Aur); } -Aura * Unit::AddAuraEffect(uint32 spellId, uint8 effIndex, Unit* caster, int32 * basePoints) +Aura * Unit::AddAuraEffect(const SpellEntry * spellInfo, uint8 effIndex, Unit* caster, int32 * basePoints) { - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); - if(!spellInfo || !caster) - return NULL; - // can't do that for passive auras - they stack from same caster so there is no way to get exact aura which should get effect //assert (!IsPassiveSpell(spellInfo)); - Aura * aur = GetAura(spellId, caster->GetGUID()); + Aura *aur = GetAura(spellInfo->Id, caster->GetGUID()); if (aur) { @@ -13636,10 +13632,10 @@ Aura * Unit::AddAuraEffect(uint32 spellId, uint8 effIndex, Unit* caster, int32 * aur = new Aura(spellInfo, 1< Date: Sat, 9 May 2009 22:36:04 -0500 Subject: *Set creature trigger have the same level as caster. --HG-- branch : trunk --- src/game/TemporarySummon.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp index afea0e5ed53..993ece988a0 100644 --- a/src/game/TemporarySummon.cpp +++ b/src/game/TemporarySummon.cpp @@ -208,6 +208,7 @@ void TempSummon::InitSummon() if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER && m_spells[0]) { setFaction(owner->getFaction()); + SetLevel(owner->getLevel()); CastSpell(this, m_spells[0], false, 0, 0, m_summonerGUID); } } -- cgit v1.2.3 From aba285664fe9660a545bb4abc3d31cedb5142540 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 01:19:39 -0500 Subject: *Fix the bug that totem can only apply the first aura effect. --HG-- branch : trunk --- src/game/Spell.cpp | 4 ++-- src/game/SpellAuras.cpp | 30 +++++++++++++++--------------- src/game/Unit.cpp | 4 +++- 3 files changed, 20 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 122caa96373..5d4dae7f0b5 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1188,8 +1188,8 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) if (aura_effmask) { - Unit * caster = m_originalCaster ? m_originalCaster : m_caster; - Aura * Aur= new Aura(m_spellInfo, aura_effmask, &m_currentBasePoints[0], unit, caster , m_CastItem, m_caster); + Unit * caster = m_originalCaster ? m_originalCaster : m_caster; + Aura * Aur = new Aura(m_spellInfo, aura_effmask, m_currentBasePoints, unit, caster, m_CastItem, m_caster); if (!Aur->IsAreaAura()) { diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index b8f65626e7d..3045e89f315 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -721,28 +721,28 @@ void AreaAuraEffect::Update(uint32 diff) } } - for(std::list::iterator tIter = targets.begin(); tIter != targets.end(); tIter++) + for(std::list::iterator tIter = targets.begin(); tIter != targets.end(); tIter++) { - bool skip=false; - for(Unit::AuraMap::iterator iter = (*tIter)->GetAuras().begin(); iter != (*tIter)->GetAuras().end();++iter) + if(Aura *aur = (*tIter)->GetAura(GetId(), m_formalCasterGUID)) { - bool samecaster = iter->second->GetCasterGUID() == GetCasterGUID(); - if (samecaster && iter->first == GetId()) + if(aur->HasEffect(GetEffIndex())) + continue; + } + else + { + bool skip = false; + for(Unit::AuraMap::iterator iter = (*tIter)->GetAuras().begin(); iter != (*tIter)->GetAuras().end();++iter) { - if (AuraEffect * aurEff = iter->second->GetPartAura(m_effIndex)) + bool samecaster = iter->second->GetCasterGUID() == m_formalCasterGUID; + if(spellmgr.IsNoStackSpellDueToSpell(GetId(), iter->first, samecaster)) { - skip=true; + skip = true; + break; } - break; - } - if (spellmgr.IsNoStackSpellDueToSpell(GetId(), iter->first,samecaster)) - { - skip=true; - break; } + if(skip) + continue; } - if(skip) - continue; if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel())) { diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 7a3385acabf..6a9f122adf4 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4306,7 +4306,7 @@ bool Unit::HasAura(Aura * aur) const bool Unit::HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster) const { if (Aura * aur = GetAura(spellId, caster)) - return bool(aur->HasEffect(effIndex)); + return aur->HasEffect(effIndex); return false; } @@ -13615,6 +13615,8 @@ Aura * Unit::AddAuraEffect(const SpellEntry * spellInfo, uint8 effIndex, Unit* c // can't do that for passive auras - they stack from same caster so there is no way to get exact aura which should get effect //assert (!IsPassiveSpell(spellInfo)); + sLog.outDebug("AddAuraEffect: spell id: %u, effect index: %u", spellInfo->Id, (uint32)effIndex); + Aura *aur = GetAura(spellInfo->Id, caster->GetGUID()); if (aur) -- cgit v1.2.3 From d0bf6edd3603e978a0b1aa47dd25526245e28549 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 01:20:12 -0500 Subject: *Show correct duration for persistent aura. --HG-- branch : trunk --- src/game/GridNotifiersImpl.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index 7b7911820c6..12f3706c4e2 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -208,7 +208,9 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target) if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index)) return; // Apply PersistentAreaAura on target - target->AddAuraEffect(spellInfo, eff_index, i_dynobject.GetCaster()); + if(Aura *aur = target->AddAuraEffect(spellInfo, eff_index, i_dynobject.GetCaster())) + aur->SetAuraDuration(i_dynobject.GetDuration()); + i_dynobject.AddAffected(target); } -- cgit v1.2.3 From 1576a44d38eb1d9c035652e2bc109488d12f1ce4 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 01:22:51 -0500 Subject: *Update naxx script. --HG-- branch : trunk --- sql/updates/3233_world_scripts_naxx.sql | 34 +++++++++ src/bindings/scripts/include/sc_creature.cpp | 13 +++- .../scripts/scripts/zone/naxxramas/boss_noth.cpp | 87 +++++++++++++++++++--- .../scripts/zone/naxxramas/boss_sapphiron.cpp | 5 +- 4 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 sql/updates/3233_world_scripts_naxx.sql (limited to 'src') diff --git a/sql/updates/3233_world_scripts_naxx.sql b/sql/updates/3233_world_scripts_naxx.sql new file mode 100644 index 00000000000..7272b328f8e --- /dev/null +++ b/sql/updates/3233_world_scripts_naxx.sql @@ -0,0 +1,34 @@ +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (-28169); +INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES +(-28169, 28206, 0, 'Mutating Injection - Mutagen Explosion'), +(-28169, 28240, 0, 'Mutating Injection - Poison Cloud'); + +UPDATE creature_template SET scriptname = 'boss_grobbulus' WHERE entry = 15931; + +INSERT INTO creature_template (entry, spell1, flags_extra, scriptname) VALUES +(16363, 28158, 128, ''), # Grobbulus Cloud +(29379, 54362, 128, '') # Grobbulus Cloud (H) +ON DUPLICATE KEY UPDATE +spell1 = VALUES(spell1), +flags_extra = VALUES(flags_extra), +scriptname = VALUES(scriptname); + +INSERT INTO creature_template (entry, spell1, spell2, flags_extra, scriptname) VALUES +(16474, 28547, 1000, 128, 'trigger_periodic'), # Blizzard (Sapphiron) +(30000, 55699, 1000, 128, 'trigger_periodic') # Blizzard (Sapphiron) (H) +ON DUPLICATE KEY UPDATE +spell1 = VALUES(spell1), +spell2 = VALUES(spell2), +flags_extra = VALUES(flags_extra), +scriptname = VALUES(scriptname); + +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (29912); +INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `quest_id`, `cast_flags`) VALUES +(29912, 55479, 0, 1); # Obedience Crystal - Force Obedience + +DELETE FROM `spell_script_target` WHERE `entry` IN (55479); +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES +(55479, 1, 16803); # Force Obedience - Death Knight Understudy + +# Death Knight Understudy +UPDATE creature_template SET spell1=0, spell2=0, spell3=0, spell4=61696, spell5=29060, spell6=29061 WHERE entry IN (16803,29941); diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index a76fbb8e1ef..82743bcd9e5 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -775,14 +775,21 @@ void Scripted_NoMovementAI::AttackStart(Unit* who) } } +#define GOBJECT(x) (const_cast(GetGameObjectInfo(x))) + void LoadOverridenSQLData() { GameObjectInfo *goInfo; // Sunwell Plateau : Kalecgos : Spectral Rift - goInfo = const_cast(GetGameObjectInfo(187055)); - if(goInfo && goInfo->type == GAMEOBJECT_TYPE_GOOBER) - goInfo->goober.lockId = 57; // need LOCKTYPE_QUICK_OPEN + if(goInfo = GOBJECT(187055)) + if(goInfo->type == GAMEOBJECT_TYPE_GOOBER) + goInfo->goober.lockId = 57; // need LOCKTYPE_QUICK_OPEN + + // Naxxramas : Sapphiron Birth + if(goInfo = GOBJECT(181356)) + if(goInfo->type == GAMEOBJECT_TYPE_TRAP) + goInfo->trap.radius = 50; } #define SPELL(x) const_cast(GetSpellStore()->LookupEntry(x)) diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp index a0ab51a9a2b..22796094557 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp @@ -34,6 +34,7 @@ EndScriptData */ #define SPELL_CURSE_PLAGUEBRINGER HEROIC(29213,54835) #define SPELL_BLINK RAND(29208,29209,29210,29211) #define SPELL_CRIPPLE HEROIC(29212,54814) +#define SPELL_TELEPORT 29216 #define MOB_WARRIOR 16984 #define MOB_CHAMPION 16983 @@ -62,6 +63,9 @@ enum Events EVENT_CURSE, EVENT_BLINK, EVENT_WARRIOR, + EVENT_BALCONY, + EVENT_WAVE, + EVENT_GROUND, }; struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI @@ -74,6 +78,7 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI EventMap events; SummonList summons; ScriptedInstance *instance; + uint32 waveCount, balconyCount; void Reset() { @@ -86,27 +91,38 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI void EnterCombat(Unit *who) { DoScriptText(SAY_AGGRO, me); - DoZoneInCombat(); me->setActive(true); - - events.ScheduleEvent(EVENT_CURSE, 20000+rand()%10000); - events.ScheduleEvent(EVENT_WARRIOR, 30000); - if(HeroicMode) - events.ScheduleEvent(EVENT_BLINK, 20000+rand()%10000); - + balconyCount = 0; + EnterPhaseGround(); instance->SetBossState(BOSS_NOTH, IN_PROGRESS); } + void EnterPhaseGround() + { + DoZoneInCombat(); + if(me->getThreatManager().isThreatListEmpty()) + EnterEvadeMode(); + else + { + events.ScheduleEvent(EVENT_BALCONY, 11000); + events.ScheduleEvent(EVENT_CURSE, 20000+rand()%10000); + events.ScheduleEvent(EVENT_WARRIOR, 30000); + if(HeroicMode) + events.ScheduleEvent(EVENT_BLINK, 20000+rand()%10000); + } + } + void KilledUnit(Unit* victim) { - DoScriptText(SAY_SLAY, me); + if(!(rand()%5)) + DoScriptText(SAY_SLAY, me); } void JustSummoned(Creature *summon) { summons.Summon(summon); summon->setActive(true); - DoZoneInCombat(summon); + summon->AI()->DoZoneInCombat(); } void SummonedCreatureDespawn(Creature *summon) { summons.Despawn(summon); } @@ -130,8 +146,19 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI void UpdateAI(const uint32 diff) { - if(!UpdateVictim()) - return; + if(me->HasReactState(REACT_AGGRESSIVE)) // ground + { + if(!UpdateVictim()) + return; + } + else // balcony + { + if(me->getThreatManager().isThreatListEmpty()) // if no enemy, go back at once + { + events.Reset(); + events.ScheduleEvent(EVENT_GROUND, 0); + } + } events.Update(diff); @@ -154,10 +181,46 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI DoResetThreat(); events.ScheduleEvent(EVENT_BLINK, 20000+rand()%10000); return; + case EVENT_BALCONY: + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->AttackStop(); + me->RemoveAllAuras(); + me->NearTeleportTo(TELE_X, TELE_Y, TELE_Z, TELE_O); + events.Reset(); + events.ScheduleEvent(EVENT_WAVE, 2000); + waveCount = 0; + return; + case EVENT_WAVE: + DoScriptText(SAY_SUMMON, me); + switch(balconyCount) + { + case 0: SummonUndead(MOB_CHAMPION, HEROIC(2,4)); break; + case 1: SummonUndead(MOB_CHAMPION, HEROIC(1,2)); + SummonUndead(MOB_GUARDIAN, HEROIC(1,2)); break; + case 2: SummonUndead(MOB_GUARDIAN, HEROIC(2,4)); break; + default:SummonUndead(MOB_CHAMPION, HEROIC(5,10)); + SummonUndead(MOB_GUARDIAN, HEROIC(5,10));break; + } + ++waveCount; + events.ScheduleEvent(waveCount < 2 ? EVENT_WAVE : EVENT_GROUND, 34000); + return; + case EVENT_GROUND: + { + ++balconyCount; + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + float x, y, z, o; + me->GetHomePosition(x, y, z, o); + me->NearTeleportTo(x, y, z, o); + EnterPhaseGround(); + return; + } } } - DoMeleeAttackIfReady(); + if(me->HasReactState(REACT_AGGRESSIVE)) + DoMeleeAttackIfReady(); } }; diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp index 9ba4bd1f7ee..682f6cee3a9 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp @@ -89,6 +89,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI me->GetPosition(x, y, z); me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0); me->SetVisibility(VISIBILITY_OFF); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_PASSIVE); Reset(); @@ -207,10 +208,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI float x, y, z; me->GetGroundPointAroundUnit(x, y, z, rand_norm()*20, rand_norm()*2*M_PI); if(Creature *summon = me->SummonCreature(MOB_BLIZZARD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 25000+rand()%5000)) - { - summon->setFaction(me->getFaction()); summon->GetMotionMaster()->MoveRandom(40); - } events.ScheduleEvent(EVENT_BLIZZARD, HEROIC(20000,7000), 0, PHASE_GROUND); break; } @@ -295,6 +293,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI return; case EVENT_BIRTH: me->SetVisibility(VISIBILITY_ON); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_AGGRESSIVE); return; } -- cgit v1.2.3 From c153f7f272d574cf72c7c96825db19973655d209 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 12:41:05 -0500 Subject: *A temp fix for the crash caused by feared statue. I will push a better fix later. Thanks to Drahy. --HG-- branch : trunk --- src/game/Spell.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 5d4dae7f0b5..5b53647fe4c 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2856,8 +2856,7 @@ void Spell::finish(bool ok) m_caster->clearUnitState(UNIT_STAT_CASTING); // Unsummon summon as possessed creatures on spell cancel - if(IsChanneledSpell(m_spellInfo) - && m_caster->GetTypeId() == TYPEID_PLAYER) + if(IsChanneledSpell(m_spellInfo) && m_caster->GetTypeId() == TYPEID_PLAYER) { if (Unit * charm = m_caster->GetCharm()) for(int i = 0; i < 3; ++i) @@ -2875,7 +2874,12 @@ void Spell::finish(bool ok) } } } - else if (m_caster->GetTypeId()==TYPEID_UNIT && ((Creature*)m_caster)->isSummon()) + + // other code related only to successfully finished spells + if(!ok) + return; + + if (m_caster->GetTypeId()==TYPEID_UNIT && ((Creature*)m_caster)->isSummon()) { // Unsummon statue uint32 spell = m_caster->GetUInt32Value(UNIT_CREATED_BY_SPELL); @@ -2888,10 +2892,6 @@ void Spell::finish(bool ok) } } - // other code related only to successfully finished spells - if(!ok) - return; - //remove spell mods if (m_caster->GetTypeId() == TYPEID_PLAYER) ((Player*)m_caster)->RemoveSpellMods(this); -- cgit v1.2.3 From 6f87cf18b4962c37bff2366d8442568d96ec41d4 Mon Sep 17 00:00:00 2001 From: Anubisss Date: Sun, 10 May 2009 21:03:25 +0200 Subject: *Remove Mana Tap from players and Drop Mana Tap's code. This spell not needed in 3.0.2+ --HG-- branch : trunk --- sql/TBC-WLK_converter/TBC-WLK_characters.sql | 6 ++++++ sql/TBC-WLK_converter/TBC-WLK_world.sql | 24 ++++++------------------ sql/updates/3235_characters.sql | 4 ++++ sql/updates/3235_world.sql | 6 ++++++ sql/world.sql | 24 ++++++------------------ src/game/SpellAuras.cpp | 18 ++---------------- src/game/SpellEffects.cpp | 11 ----------- 7 files changed, 30 insertions(+), 63 deletions(-) create mode 100644 sql/updates/3235_characters.sql create mode 100644 sql/updates/3235_world.sql (limited to 'src') diff --git a/sql/TBC-WLK_converter/TBC-WLK_characters.sql b/sql/TBC-WLK_converter/TBC-WLK_characters.sql index 214c19fef14..9d6115a4a09 100644 --- a/sql/TBC-WLK_converter/TBC-WLK_characters.sql +++ b/sql/TBC-WLK_converter/TBC-WLK_characters.sql @@ -261,6 +261,12 @@ DELETE FROM `character_spell` WHERE `spell` IN (27354,24513,24512,24511,24494,21 UPDATE IGNORE character_spell SET spell = 2108 WHERE spell = 3104; DELETE FROM character_spell WHERE spell = 3104; +/* Remove Mana Tap */ +DELETE FROM `character_action` WHERE `type` = 0 AND `action` = 28734; +DELETE FROM `character_aura` WHERE `spell` = 28734; +DELETE FROM `character_spell` WHERE `spell` = 28734; +DELETE FROM `character_spell_cooldown` WHERE `spell` = 28734; + /* This cleanup character_action. This is like delete from character_action where type=0 and action not in character_spell for same player */ DELETE FROM ca,cs USING `character_action` ca LEFT JOIN `character_spell` cs ON ca.`guid`=cs.`guid` AND ca.`action`=cs.`spell` WHERE ca.`type`=0 AND cs.`guid` IS NULL; diff --git a/sql/TBC-WLK_converter/TBC-WLK_world.sql b/sql/TBC-WLK_converter/TBC-WLK_world.sql index a2e3833c2e4..969f8ce4c2c 100644 --- a/sql/TBC-WLK_converter/TBC-WLK_world.sql +++ b/sql/TBC-WLK_converter/TBC-WLK_world.sql @@ -314,29 +314,25 @@ INSERT IGNORE INTO `playercreateinfo_action` (`race`, `class`, `button`, `action (10, 2, 0, 6603, 0, 0), (10, 2, 1, 21084, 0, 0), (10, 2, 2, 635, 0, 0), -(10, 2, 3, 28734, 0, 0), -(10, 2, 4, 28730, 0, 0), +(10, 2, 3, 28730, 0, 0), (10, 2, 10, 159, 128, 0), (10, 2, 11, 20857, 128, 0), (10, 3, 0, 6603, 0, 0), (10, 3, 1, 2973, 0, 0), (10, 3, 2, 75, 0, 0), -(10, 3, 3, 28734, 0, 0), -(10, 3, 4, 28730, 0, 0), +(10, 3, 3, 28730, 0, 0), (10, 3, 10, 159, 128, 0), (10, 3, 11, 20857, 128, 0), (10, 4, 0, 6603, 0, 0), (10, 4, 1, 1752, 0, 0), (10, 4, 2, 2098, 0, 0), (10, 4, 3, 2764, 0, 0), -(10, 4, 4, 28734, 0, 0), -(10, 4, 5, 25046, 0, 0), +(10, 4, 4, 25046, 0, 0), (10, 4, 11, 20857, 128, 0), (10, 5, 0, 6603, 0, 0), (10, 5, 1, 585, 0, 0), (10, 5, 2, 2050, 0, 0), -(10, 5, 3, 28734, 0, 0), -(10, 5, 4, 28730, 0, 0), +(10, 5, 3, 28730, 0, 0), (10, 5, 10, 159, 128, 0), (10, 5, 11, 20857, 128, 0), (10, 6, 0, 6603, 0, 0), @@ -349,14 +345,12 @@ INSERT IGNORE INTO `playercreateinfo_action` (`race`, `class`, `button`, `action (10, 8, 0, 6603, 0, 0), (10, 8, 1, 133, 0, 0), (10, 8, 2, 168, 0, 0), -(10, 8, 3, 28734, 0, 0), -(10, 8, 4, 28730, 0, 0), +(10, 8, 3, 28730, 0, 0), (10, 8, 10, 159, 128, 0), (10, 8, 11, 20857, 128, 0), (10, 9, 11, 20857, 128, 0), (10, 9, 10, 159, 128, 0), -(10, 9, 4, 28730, 0, 0), -(10, 9, 3, 28734, 0, 0), +(10, 9, 3, 28730, 0, 0), (10, 9, 2, 687, 0, 0), (10, 9, 1, 686, 0, 0), (10, 9, 0, 6603, 0, 0), @@ -2647,7 +2641,6 @@ INSERT IGNORE INTO `playercreateinfo_spell` (`race`, `class`, `Spell`, `Note`) V (10, 2, 22810, 'Opening - No Text'), (10, 2, 27762, 'Libram'), (10, 2, 28730, 'Arcane Torrent'), -(10, 2, 28734, 'Mana Tap'), (10, 2, 28877, 'Arcane Affinity'), (10, 3, 75, 'Auto Shot'), (10, 3, 81, 'Dodge'), @@ -2684,7 +2677,6 @@ INSERT IGNORE INTO `playercreateinfo_spell` (`race`, `class`, `Spell`, `Note`) V (10, 3, 22810, 'Opening - No Text'), (10, 3, 24949, 'Defensive State 2 (DND)'), (10, 3, 28730, 'Arcane Torrent'), -(10, 3, 28734, 'Mana Tap'), (10, 3, 28877, 'Arcane Affinity'), (10, 3, 34082, 'Advantaged State (DND)'), (10, 4, 81, 'Dodge'), @@ -2723,7 +2715,6 @@ INSERT IGNORE INTO `playercreateinfo_spell` (`race`, `class`, `Spell`, `Note`) V (10, 4, 22027, 'Remove Insignia'), (10, 4, 22810, 'Opening - No Text'), (10, 4, 25046, 'Arcane Torrent'), -(10, 4, 28734, 'Mana Tap'), (10, 4, 28877, 'Arcane Affinity'), (10, 5, 81, 'Dodge'), (10, 5, 198, 'One-Handed Maces'), @@ -2758,7 +2749,6 @@ INSERT IGNORE INTO `playercreateinfo_spell` (`race`, `class`, `Spell`, `Note`) V (10, 5, 22027, 'Remove Insignia'), (10, 5, 22810, 'Opening - No Text'), (10, 5, 28730, 'Arcane Torrent'), -(10, 5, 28734, 'Mana Tap'), (10, 5, 28877, 'Arcane Affinity'), (10, 6, 81, 'Dodge'), (10, 6, 196, 'One-Handed Axes'), @@ -2860,7 +2850,6 @@ INSERT IGNORE INTO `playercreateinfo_spell` (`race`, `class`, `Spell`, `Note`) V (10, 8, 22027, 'Remove Insignia'), (10, 8, 22810, 'Opening - No Text'), (10, 8, 28730, 'Arcane Torrent'), -(10, 8, 28734, 'Mana Tap'), (10, 8, 28877, 'Arcane Affinity'), (10, 9, 81, 'Dodge'), (10, 9, 203, 'Unarmed'), @@ -2895,7 +2884,6 @@ INSERT IGNORE INTO `playercreateinfo_spell` (`race`, `class`, `Spell`, `Note`) V (10, 9, 22027, 'Remove Insignia'), (10, 9, 22810, 'Opening - No Text'), (10, 9, 28730, 'Arcane Torrent'), -(10, 9, 28734, 'Mana Tap'), (10, 9, 28877, 'Arcane Affinity'), (10, 9, 58284, 'Chaos Bolt Passive'), (11, 1, 78, 'Heroic Strike'), diff --git a/sql/updates/3235_characters.sql b/sql/updates/3235_characters.sql new file mode 100644 index 00000000000..814b2dda67c --- /dev/null +++ b/sql/updates/3235_characters.sql @@ -0,0 +1,4 @@ +DELETE FROM `character_action` WHERE `type` = 0 AND `action` = 28734; +DELETE FROM `character_aura` WHERE `spell` = 28734; +DELETE FROM `character_spell` WHERE `spell` = 28734; +DELETE FROM `character_spell_cooldown` WHERE `spell` = 28734; diff --git a/sql/updates/3235_world.sql b/sql/updates/3235_world.sql new file mode 100644 index 00000000000..68c18dfc886 --- /dev/null +++ b/sql/updates/3235_world.sql @@ -0,0 +1,6 @@ +DELETE FROM `playercreateinfo_action` WHERE `type` = 0 AND `action` = 28734; +DELETE FROM `playercreateinfo_spell` WHERE `spell` = 28734; +DELETE FROM `playercreateinfo_spell_custom` WHERE `spell` = 28734; + +UPDATE `playercreateinfo_action` SET `button` = 3 WHERE `race` = 10 AND `class` IN (2, 3, 5, 8, 9) AND `action` = 28730 AND `type` = 0; +UPDATE `playercreateinfo_action` SET `button` = 4 WHERE `race` = 10 AND `class` = 4 AND `action` = 25046 AND `type` = 0; diff --git a/sql/world.sql b/sql/world.sql index f11a5ca0411..c466956739a 100644 --- a/sql/world.sql +++ b/sql/world.sql @@ -9886,29 +9886,25 @@ INSERT INTO `playercreateinfo_action` VALUES (10,2,0,6603,0,0), (10,2,1,21084,0,0), (10,2,2,635,0,0), -(10,2,3,28734,0,0), -(10,2,4,28730,0,0), +(10,2,3,28730,0,0), (10,2,10,159,128,0), (10,2,11,20857,128,0), (10,3,0,6603,0,0), (10,3,1,2973,0,0), (10,3,2,75,0,0), -(10,3,3,28734,0,0), -(10,3,4,28730,0,0), +(10,3,3,28730,0,0), (10,3,10,159,128,0), (10,3,11,20857,128,0), (10,4,0,6603,0,0), (10,4,1,1752,0,0), (10,4,2,2098,0,0), (10,4,3,2764,0,0), -(10,4,4,28734,0,0), -(10,4,5,25046,0,0), +(10,4,4,25046,0,0), (10,4,11,20857,128,0), (10,5,0,6603,0,0), (10,5,1,585,0,0), (10,5,2,2050,0,0), -(10,5,3,28734,0,0), -(10,5,4,28730,0,0), +(10,5,3,28730,0,0), (10,5,10,159,128,0), (10,5,11,20857,128,0), (10,6,0,6603,0,0), @@ -9921,14 +9917,12 @@ INSERT INTO `playercreateinfo_action` VALUES (10,8,0,6603,0,0), (10,8,1,133,0,0), (10,8,2,168,0,0), -(10,8,3,28734,0,0), -(10,8,4,28730,0,0), +(10,8,3,28730,0,0), (10,8,10,159,128,0), (10,8,11,20857,128,0), (10,9,11,20857,128,0), (10,9,10,159,128,0), -(10,9,4,28730,0,0), -(10,9,3,28734,0,0), +(10,9,3,28730,0,0), (10,9,2,687,0,0), (10,9,1,686,0,0), (10,9,0,6603,0,0), @@ -12170,7 +12164,6 @@ INSERT INTO `playercreateinfo_spell` VALUES (10,2,22810,'Opening - No Text',1), (10,2,27762,'Libram',1), (10,2,28730,'Arcane Torrent',1), -(10,2,28734,'Mana Tap',1), (10,2,28877,'Arcane Affinity',1), (10,3,75,'Auto Shot',1), (10,3,81,'Dodge',1), @@ -12207,7 +12200,6 @@ INSERT INTO `playercreateinfo_spell` VALUES (10,3,22810,'Opening - No Text',1), (10,3,24949,'Defensive State 2(DND)',1), (10,3,28730,'Arcane Torrent',1), -(10,3,28734,'Mana Tap',1), (10,3,28877,'Arcane Affinity',1), (10,3,34082,'Advantaged State(DND)',1), (10,4,81,'Dodge',1), @@ -12246,7 +12238,6 @@ INSERT INTO `playercreateinfo_spell` VALUES (10,4,22027,'Remove Insignia',1), (10,4,22810,'Opening - No Text',1), (10,4,25046,'Arcane Torrent',1), -(10,4,28734,'Mana Tap',1), (10,4,28877,'Arcane Affinity',1), (10,5,81,'Dodge',1), (10,5,198,'One-Handed Maces',1), @@ -12281,7 +12272,6 @@ INSERT INTO `playercreateinfo_spell` VALUES (10,5,22027,'Remove Insignia',1), (10,5,22810,'Opening - No Text',1), (10,5,28730,'Arcane Torrent',1), -(10,5,28734,'Mana Tap',1), (10,5,28877,'Arcane Affinity',1), (10,6,81,'Dodge',1), (10,6,196,'One-Handed Axes',1), @@ -12383,7 +12373,6 @@ INSERT INTO `playercreateinfo_spell` VALUES (10,8,22027,'Remove Insignia',1), (10,8,22810,'Opening - No Text',1), (10,8,28730,'Arcane Torrent',1), -(10,8,28734,'Mana Tap',1), (10,8,28877,'Arcane Affinity',1), (10,9,81,'Dodge',1), (10,9,203,'Unarmed',1), @@ -12418,7 +12407,6 @@ INSERT INTO `playercreateinfo_spell` VALUES (10,9,22027,'Remove Insignia',1), (10,9,22810,'Opening - No Text',1), (10,9,28730,'Arcane Torrent',1), -(10,9,28734,'Mana Tap',1), (10,9,28877,'Arcane Affinity',1), (11,1,78,'Heroic Strike',1), (11,1,81,'Dodge',1), diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 3045e89f315..fa0360eadf1 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3880,25 +3880,11 @@ void AuraEffect::HandleAuraModSilence(bool apply, bool Real) if (m_target->m_currentSpells[i] && m_target->m_currentSpells[i]->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) m_target->InterruptSpell(i,false); // Stop spells on prepare or casting state + /* switch (GetId()) { - // Arcane Torrent (Energy) - case 25046: - { - Unit * caster = GetCaster(); - if (!caster) - return; - - // Search Mana Tap auras on caster - AuraEffect * dummy = caster->GetDummyAura(28734); - if (dummy) - { - int32 bp = dummy->GetParentAura()->GetStackAmount() * 10; - caster->CastCustomSpell(caster, 25048, &bp, NULL, NULL, true); - m_target->RemoveAurasDueToSpell(28734); - } - } } + */ } else { diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index d213040ede4..09c596e4979 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1011,17 +1011,6 @@ void Spell::EffectDummy(uint32 i) m_caster->CastSpell(unitTarget,29294,true); return; } - case 28730: // Arcane Torrent (Mana) - { - Aura * dummy = m_caster->GetAura(28734, m_caster->GetGUID()); - if (dummy) - { - int32 bp = damage * dummy->GetStackAmount(); - m_caster->CastCustomSpell(m_caster, 28733, &bp, NULL, NULL, true); - m_caster->RemoveAurasDueToSpell(28734); - } - return; - } case 29200: // Purify Helboar Meat { if( m_caster->GetTypeId() != TYPEID_PLAYER ) -- cgit v1.2.3 From 40a8e6d3aba7410fe34c4b6b81f4036f26e0f338 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 14:29:28 -0500 Subject: *Rename some script functions (no real change). --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 150 +-------------------- src/bindings/scripts/include/sc_creature.h | 4 +- .../shadow_labyrinth/boss_grandmaster_vorpil.cpp | 2 +- .../aunchindoun/shadow_labyrinth/boss_murmur.cpp | 4 +- .../scripts/zone/black_temple/boss_illidan.cpp | 12 +- .../scripts/zone/black_temple/boss_supremus.cpp | 4 +- .../zone/black_temple/boss_warlord_najentus.cpp | 2 +- .../zone/caverns_of_time/hyjal/boss_anetheron.cpp | 6 +- .../zone/caverns_of_time/hyjal/boss_azgalor.cpp | 6 +- .../hyjal/boss_rage_winterchill.cpp | 2 +- .../zone/caverns_of_time/hyjal/hyjal_trash.cpp | 2 +- .../serpent_shrine/boss_lurker_below.cpp | 2 +- .../serpent_shrine/boss_morogrim_tidewalker.cpp | 4 +- .../underbog/boss_the_black_stalker.cpp | 2 +- .../scripts/scripts/zone/naxxramas/boss_gothik.cpp | 5 +- .../scripts/zone/sunwell_plateau/boss_felmyst.cpp | 8 +- .../zone/sunwell_plateau/boss_kiljaeden.cpp | 8 +- .../scripts/zone/sunwell_plateau/boss_muru.cpp | 10 +- .../zone/tempest_keep/the_eye/boss_alar.cpp | 2 +- .../zone/tempest_keep/the_eye/boss_astromancer.cpp | 4 +- .../zone/tempest_keep/the_eye/boss_kaelthas.cpp | 6 +- .../zone/temple_of_ahnqiraj/boss_twinemperors.cpp | 6 +- .../scripts/scripts/zone/zulaman/boss_akilzon.cpp | 2 +- .../scripts/scripts/zone/zulaman/boss_hexlord.cpp | 2 +- .../scripts/scripts/zone/zulaman/boss_nalorakk.cpp | 2 +- src/game/CreatureAI.cpp | 144 ++++++++++++++++++++ src/game/CreatureAI.h | 34 ++++- src/game/Object.cpp | 8 ++ src/game/Object.h | 1 + src/game/Unit.cpp | 4 +- src/game/Unit.h | 4 +- 31 files changed, 246 insertions(+), 206 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 82743bcd9e5..4a9f8ec61e8 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -259,147 +259,7 @@ Unit* ScriptedAI::SelectUnit(SelectAggroTarget target, uint32 position) return NULL; } -struct TargetDistanceOrder : public std::binary_function -{ - const Unit* me; - TargetDistanceOrder(const Unit* Target) : me(Target) {}; - // functor for operator ">" - bool operator()(const Unit* _Left, const Unit* _Right) const - { - return (me->GetDistance(_Left) < me->GetDistance(_Right)); - } -}; - -Unit* ScriptedAI::SelectUnit(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly) -{ - if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) - { - std::list &m_threatlist = m_creature->getThreatManager().getThreatList(); - if(m_threatlist.empty()) return NULL; - std::list targetList; - std::list::iterator itr = m_threatlist.begin(); - for(; itr!= m_threatlist.end(); ++itr) - { - Unit *target = (*itr)->getTarget(); - if(!target - || playerOnly && target->GetTypeId() != TYPEID_PLAYER - || dist && !m_creature->IsWithinCombatRange(target, dist)) - { - continue; - } - targetList.push_back(target); - } - if(position >= targetList.size()) - return NULL; - targetList.sort(TargetDistanceOrder(m_creature)); - if(targetType == SELECT_TARGET_NEAREST) - { - std::list::iterator i = targetList.begin(); - advance(i, position); - return *i; - } - else - { - std::list::reverse_iterator i = targetList.rbegin(); - advance(i, position); - return *i; - } - } - else - { - std::list m_threatlist = m_creature->getThreatManager().getThreatList(); - std::list::iterator i; - Unit *target; - while(position < m_threatlist.size()) - { - if(targetType == SELECT_TARGET_BOTTOMAGGRO) - { - i = m_threatlist.end(); - advance(i, - (int32)position - 1); - } - else - { - i = m_threatlist.begin(); - if(targetType == SELECT_TARGET_TOPAGGRO) - advance(i, position); - else // random - advance(i, position + rand()%(m_threatlist.size() - position)); - } - - target = (*i)->getTarget(); - if(!target - || playerOnly && target->GetTypeId() != TYPEID_PLAYER - || dist && !m_creature->IsWithinCombatRange(target, dist)) - { - m_threatlist.erase(i); - } - else - { - return target; - } - } - } - - return NULL; -} - -void ScriptedAI::SelectUnitList(std::list &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly) -{ - if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) - { - std::list &m_threatlist = m_creature->getThreatManager().getThreatList(); - if(m_threatlist.empty()) return; - std::list::iterator itr = m_threatlist.begin(); - for(; itr!= m_threatlist.end(); ++itr) - { - Unit *target = (*itr)->getTarget(); - if(!target - || playerOnly && target->GetTypeId() != TYPEID_PLAYER - || dist && !m_creature->IsWithinCombatRange(target, dist)) - { - continue; - } - targetList.push_back(target); - } - targetList.sort(TargetDistanceOrder(m_creature)); - targetList.resize(num); - if(targetType == SELECT_TARGET_FARTHEST) - targetList.reverse(); - } - else - { - std::list m_threatlist = m_creature->getThreatManager().getThreatList(); - std::list::iterator i; - Unit *target; - while(m_threatlist.size() && num) - { - if(targetType == SELECT_TARGET_BOTTOMAGGRO) - { - i = m_threatlist.end(); - --i; - } - else - { - i = m_threatlist.begin(); - if(targetType == SELECT_TARGET_RANDOM) - advance(i, rand()%m_threatlist.size()); - } - - target = (*i)->getTarget(); - m_threatlist.erase(i); - if(!target - || playerOnly && target->GetTypeId() != TYPEID_PLAYER - || dist && !m_creature->IsWithinCombatRange(target, dist)) - { - continue; - } - targetList.push_back(target); - --num; - } - } -} - -SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effects) +SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTargetType Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effects) { //No target so we can't cast if (!Target) @@ -531,7 +391,7 @@ void FillSpellSummary() SpellEntry const* TempSpell; - for (int i=0; i < GetSpellStore()->GetNumRows(); i++ ) + for(uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i) { SpellSummary[i].Effects = 0; SpellSummary[i].Targets = 0; @@ -541,7 +401,7 @@ void FillSpellSummary() if (!TempSpell) continue; - for (int j=0; j<3; j++) + for(uint32 j = 0; j < 3; ++j) { //Spell targets self if ( TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ) @@ -802,10 +662,6 @@ void LoadOverridenDBCData() if(spellInfo = SPELL(41913)) spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends - // Naxxramas : Sapphiron : Frost Breath Visual Effect - //if(spellInfo = SPELL(30101)) - // spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST; // orig 18 - //temp, not needed in 310 if(spellInfo = SPELL(28531)) { diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index c2c93a520a9..44caf063162 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -227,13 +227,11 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI //Selects a unit from the creature's current aggro list Unit* SelectUnit(SelectAggroTarget target, uint32 position); - Unit* SelectUnit(SelectAggroTarget target, uint32 position, float dist, bool playerOnly); - void SelectUnitList(std::list &targetList, uint32 num, SelectAggroTarget target, float dist, bool playerOnly); bool HealthBelowPct(uint32 pct) const { return me->GetHealth() * 100 < m_creature->GetMaxHealth() * pct; } //Returns spells that meet the specified criteria from the creatures spell list - SpellEntry const* SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effect); + SpellEntry const* SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTargetType Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effect); //Checks if you can cast the specified spell bool CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered = false); diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp index 89fd75b9bc8..52e5a3e8915 100644 --- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp +++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp @@ -262,7 +262,7 @@ struct TRINITY_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI if (HeroicMode && banish_Timer < diff) { - Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0,30,false); + Unit *target = SelectTarget(SELECT_TARGET_RANDOM,0,30,false); if (target) { DoCast(target,SPELL_BANISH); diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp index 99bce54be62..599767b591f 100644 --- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp +++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp @@ -118,7 +118,7 @@ struct TRINITY_DLL_DECL boss_murmurAI : public Scripted_NoMovementAI // Murmur's Touch if (MurmursTouch_Timer < diff) { - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,80,true)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,80,true)) DoCast(target, SPELL_MURMURS_TOUCH); MurmursTouch_Timer = 25000 + rand()%10000; }else MurmursTouch_Timer -= diff; @@ -162,7 +162,7 @@ struct TRINITY_DLL_DECL boss_murmurAI : public Scripted_NoMovementAI // Sonic Shock if(SonicShock_Timer < diff) { - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,20,false)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,20,false)) if(target->isAlive()) DoCast(target, SPELL_SONIC_SHOCK); SonicShock_Timer = 10000+rand()%10000; diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp index 60c51f0be33..68431cb81ee 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp @@ -785,7 +785,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI case EVENT_PARASITIC_SHADOWFIEND: { - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1, 200, true)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true)) m_creature->CastSpell(target, SPELL_PARASITIC_SHADOWFIEND, true); Timer[EVENT_PARASITIC_SHADOWFIEND] = 35000 + rand()%10000; }break; @@ -907,7 +907,7 @@ struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI void ChargeCheck() { - Unit* target = SelectUnit(SELECT_TARGET_FARTHEST, 0, 200, false); + Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0, 200, false); if(target && (!m_creature->IsWithinCombatRange(target, FLAME_CHARGE_DISTANCE))) { m_creature->AddThreat(target, 5000000.0f); @@ -1765,7 +1765,7 @@ struct TRINITY_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI { if(!m_creature->getVictim()) { - if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true)) + if(Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true)) AttackStart(target); else { @@ -1862,15 +1862,15 @@ void boss_illidan_stormrageAI::JustSummoned(Creature* summon) summon->setDeathState(JUST_DIED); return; } - Unit *target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0, 999, true); + Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, 999, true); if(!target || target->HasAura(SPELL_PARASITIC_SHADOWFIEND) || target->HasAura(SPELL_PARASITIC_SHADOWFIEND2)) - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true); if(target) summon->AI()->AttackStart(target); }break; case SHADOW_DEMON: - if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true)) // only on players. + if(Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true)) // only on players. { summon->AddThreat(target, 5000000.0f); summon->AI()->AttackStart(target); diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp index c01db75bd58..fdfdef396bb 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp @@ -198,7 +198,7 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE); break; case EVENT_SWITCH_TARGET: - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1, 100, true)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true)) { DoResetThreat(); m_creature->AddThreat(target, 5000000.0f); @@ -208,7 +208,7 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI break; case EVENT_VOLCANO: { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true); if(!target) target = m_creature->getVictim(); if(target) { diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp index 7d6b7140a9d..032bccc57ed 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp @@ -171,7 +171,7 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI { //m_creature->CastSpell(m_creature, SPELL_NEEDLE_SPINE, true); std::list target; - SelectUnitList(target, 3, SELECT_TARGET_RANDOM, 80, true); + SelectTargetList(target, 3, SELECT_TARGET_RANDOM, 80, true); for(std::list::iterator i = target.begin(); i != target.end(); ++i) m_creature->CastSpell(*i, 39835, true); events.ScheduleEvent(EVENT_NEEDLE, 15000+rand()%10000, GCD_CAST); diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp index 21b39fa378b..13b0c78ebc1 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp @@ -148,7 +148,7 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI if(SwarmTimer < diff) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,100,true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,100,true); if(target) DoCast(target,SPELL_CARRION_SWARM); @@ -170,7 +170,7 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI { for(uint8 i=0;i<3;++i) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,100,true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,100,true); if(target) target->CastSpell(target,SPELL_SLEEP,true); } @@ -194,7 +194,7 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI }else AuraTimer -= diff; if(InfernoTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,0,100,true), SPELL_INFERNO); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,100,true), SPELL_INFERNO); InfernoTimer = 45000; switch(rand()%2) { diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp index 15085963b20..33e3d344da2 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp @@ -140,13 +140,13 @@ struct TRINITY_DLL_DECL boss_azgalorAI : public hyjal_trashAI if(RainTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,0,30,true), SPELL_RAIN_OF_FIRE); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,30,true), SPELL_RAIN_OF_FIRE); RainTimer = 20000+rand()%15000; }else RainTimer -= diff; if(DoomTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,1,100,true), SPELL_DOOM);//never on tank + DoCast(SelectTarget(SELECT_TARGET_RANDOM,1,100,true), SPELL_DOOM);//never on tank DoomTimer = 45000+rand()%5000; }else DoomTimer -= diff; @@ -260,7 +260,7 @@ struct TRINITY_DLL_DECL mob_lesser_doomguardAI : public hyjal_trashAI if(CrippleTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,0,100,true), SPELL_CRIPPLE); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,100,true), SPELL_CRIPPLE); CrippleTimer = 25000+rand()%5000; }else CrippleTimer -= diff; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp index addbddab5b8..3e6b2bc8e98 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp @@ -169,7 +169,7 @@ struct TRINITY_DLL_DECL boss_rage_winterchillAI : public hyjal_trashAI }else NovaTimer -= diff; if(IceboltTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,0,40,true), SPELL_ICEBOLT); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,40,true), SPELL_ICEBOLT); IceboltTimer = 11000+rand()%20000; }else IceboltTimer -= diff; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp index 583c7831af5..30f0c14caaf 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp @@ -724,7 +724,7 @@ struct mob_necromancerAI : public hyjal_trashAI void JustSummoned(Creature* summon) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,30,true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,30,true); if(target && summon) summon->Attack(target,false); summons.Summon(summon); diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp index eb35a3c74b4..254a4d1d899 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp @@ -322,7 +322,7 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI if(WaterboltTimer < diff) { - Unit* target = SelectUnit(SELECT_TARGET_NEAREST,0,14,true); + Unit* target = SelectTarget(SELECT_TARGET_NEAREST,0,14,true); if(!target) { target = SelectUnit(SELECT_TARGET_RANDOM,0); diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp index cea591182d5..f8d27df5bb0 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp @@ -235,7 +235,7 @@ struct TRINITY_DLL_DECL boss_morogrim_tidewalkerAI : public ScriptedAI for(uint8 i = 0; i < 4; i++) { counter = 0; - do{target = SelectUnit(SELECT_TARGET_RANDOM, 1, 50, true); //target players only + do{target = SelectTarget(SELECT_TARGET_RANDOM, 1, 50, true); //target players only if(counter < Playercount) break; if(target) itr = list.find(target->GetGUID()); @@ -272,7 +272,7 @@ struct TRINITY_DLL_DECL boss_morogrim_tidewalkerAI : public ScriptedAI for (int8 g = 0; g < 4; g++) //one unit cant cast more than one spell per update, so some players have to cast for us XD { counter = 0; - do {globuletarget = SelectUnit(SELECT_TARGET_RANDOM, 0,50,true); + do {globuletarget = SelectTarget(SELECT_TARGET_RANDOM, 0,50,true); if(globuletarget) itr = globulelist.find(globuletarget->GetGUID()); if (counter > Playercount) break; diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp index 370b07c8adc..72c7992e109 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp @@ -165,7 +165,7 @@ struct TRINITY_DLL_DECL boss_the_black_stalkerAI : public ScriptedAI // Static Charge if(StaticCharge_Timer < diff) { - if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0,30,true)) + if(Unit *target = SelectTarget(SELECT_TARGET_RANDOM,0,30,true)) DoCast(target, SPELL_STATIC_CHARGE); StaticCharge_Timer = 10000; }else StaticCharge_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp index 0becff399da..3a9c6a5b47a 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp @@ -30,8 +30,9 @@ EndScriptData */ //Gothik #define SPELL_HARVESTSOUL 28679 -#define SPELL_SHADOWBOLT 29317 -#define H_SPELL_SHADOWBOLT 56405 +#define SPELL_SHADOWBOLT HEROIC(29317,56405) +#define SPELL_SOUL_SIPHON 43591 // cannot find the correct spell + //Unrelenting Trainee #define SPELL_EAGLECLAW 30285 #define SPELL_KNOCKDOWN_PASSIVE 6961 diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp index 8e42d074f88..e753d0b6047 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp @@ -306,7 +306,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI case 2:{ error_log("Summon Vapor case 2"); Unit* target; - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 150, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true); if(!target) target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_PLAYER_GUID)); if(target) { @@ -331,7 +331,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI error_log("Summon Vapor case3"); //m_creature->CastSpell(m_creature, SPELL_VAPOR_SELECT); need core support Unit* target; - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 150, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true); if(!target) target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_PLAYER_GUID)); if(target) { @@ -358,7 +358,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI break; case 5:{ Unit* target; - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 150, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true); if(!target) target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_PLAYER_GUID)); if(target) { @@ -471,7 +471,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI Timer[EVENT_GAS_NOVA] = 20000 + rand()%5 * 1000; break; case EVENT_ENCAPSULATE: - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 150, true)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true)) { m_creature->CastSpell(target, SPELL_ENCAPSULATE_CHANNEL, false); target->CastSpell(target, SPELL_ENCAPSULATE_EFFECT, true);// linked aura, need core patch to remove this hack diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp index 98cbfda7a7f..a0bd75cb156 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp @@ -540,7 +540,7 @@ struct TRINITY_DLL_DECL boss_kiljaedenAI : public Scripted_NoMovementAI float x,y,z; Unit* target; for(uint8 z = 0; z < 6; ++z){ - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!target->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break; } target->GetPosition(x,y,z); @@ -584,7 +584,7 @@ struct TRINITY_DLL_DECL boss_kiljaedenAI : public Scripted_NoMovementAI if(!m_creature->IsNonMeleeSpellCasted(false)){ m_creature->RemoveAurasDueToSpell(SPELL_SOUL_FLAY); for(uint8 z = 0; z < 6; ++z){ - randomPlayer = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + randomPlayer = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!randomPlayer->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break; } if(randomPlayer)DoCast(randomPlayer, SPELL_LEGION_LIGHTNING, false); @@ -658,7 +658,7 @@ struct TRINITY_DLL_DECL boss_kiljaedenAI : public Scripted_NoMovementAI case TIMER_ARMAGEDDON: //Phase 4 Unit* target; for(uint8 z = 0; z < 6; ++z){ - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!target->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break; } if(target){ @@ -1199,7 +1199,7 @@ struct TRINITY_DLL_DECL mob_sinster_reflectionAI : public ScriptedAI Timer[1] = 4000; } if(Timer[2] < diff){ - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_SR_CURSE_OF_AGONY, true); + DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_SR_CURSE_OF_AGONY, true); Timer[2] = 3000; } DoMeleeAttackIfReady(); diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_muru.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_muru.cpp index 6000ee474e0..b38607e1a7f 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_muru.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_muru.cpp @@ -155,7 +155,7 @@ struct TRINITY_DLL_DECL boss_entropiusAI : public ScriptedAI m_creature->SummonCreature(CREATURE_DARK_FIENDS, x,y,z,o, TEMPSUMMON_CORPSE_DESPAWN, 0); break; } - summoned->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM,0, 50, true)); + summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM,0, 50, true)); Summons.Summon(summoned); } @@ -180,10 +180,10 @@ struct TRINITY_DLL_DECL boss_entropiusAI : public ScriptedAI }else EnrageTimer -= diff; if(BlackHoleSummonTimer < diff){ - Unit* random = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + Unit* random = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if(!random)return; DoCast(random, SPELL_DARKNESS_E, false); - random = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + random = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if(!random)return; random->CastSpell(random, SPELL_BLACKHOLE, false); BlackHoleSummonTimer = 15000; @@ -260,7 +260,7 @@ struct TRINITY_DLL_DECL boss_muruAI : public Scripted_NoMovementAI summoned->CastSpell(summoned,SPELL_DARKFIEND_VISUAL,false); break; } - summoned->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM,0, 50, true)); + summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM,0, 50, true)); Summons.Summon(summoned); } @@ -441,7 +441,7 @@ struct TRINITY_DLL_DECL npc_dark_fiendAI : public ScriptedAI if(!InAction){ m_creature->clearUnitState(UNIT_STAT_STUNNED); DoCastAOE(SPELL_DARKFIEND_SKIN, false); - AttackStart(SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true)); + AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)); InAction = true; WaitTimer = 500; }else{ diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp index 168f0f48e3a..af44d96d417 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp @@ -352,7 +352,7 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI if(Charge_Timer < diff) { - Unit *target= SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_CHARGE), true); + Unit *target= SelectTarget(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_CHARGE), true); if(target) DoCast(target, SPELL_CHARGE); Charge_Timer = 30000; diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp index 83cb789b189..6af14eceeed 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp @@ -230,7 +230,7 @@ struct TRINITY_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI if( Wrath_Timer < diff) { m_creature->InterruptNonMeleeSpells(false); - DoCast(SelectUnit(SELECT_TARGET_RANDOM,1,100,true), SPELL_WRATH_OF_THE_ASTROMANCER, true); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,1,100,true), SPELL_WRATH_OF_THE_ASTROMANCER, true); Wrath_Timer = 20000+rand()%5000; }else Wrath_Timer -= diff; @@ -260,7 +260,7 @@ struct TRINITY_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI if (MarkOfTheAstromancer_Timer < diff) //A debuff that lasts for 5 seconds, cast several times each phase on a random raid member, but not the main tank { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1, 100, true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); if(target) DoCast(target, SPELL_MARK_OF_THE_ASTROMANCER); else DoCast(m_creature->getVictim(), SPELL_MARK_OF_THE_ASTROMANCER); diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp index 6745c4fd9ec..7557e03f8e5 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp @@ -804,7 +804,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI if (FlameStrike_Timer < diff) { - if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0, 70, true)) + if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true)) DoCast(pUnit, SPELL_FLAME_STRIKE); FlameStrike_Timer = 30000; @@ -816,7 +816,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI for (uint32 i = 0; i < 3; i++) { - Unit* target =SelectUnit(SELECT_TARGET_RANDOM, 1, 70, true); + Unit* target =SelectTarget(SELECT_TARGET_RANDOM, 1, 70, true); if(!target) target = m_creature->getVictim(); debug_log("TSCR: Kael'Thas mind control not supported."); if(target) @@ -1080,7 +1080,7 @@ struct TRINITY_DLL_DECL boss_thaladred_the_darkenerAI : public advisorbase_ai //Gaze_Timer if(Gaze_Timer < diff) { - if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { DoResetThreat(); if(target) 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 c3d4d0f35eb..d2fff0e569f 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 @@ -465,7 +465,7 @@ struct TRINITY_DLL_DECL boss_veknilashAI : public boss_twinemperorsAI if (UpperCut_Timer < diff) { - Unit* randomMelee = SelectUnit(SELECT_TARGET_RANDOM, 0, NOMINAL_MELEE_RANGE, true); + Unit* randomMelee = SelectTarget(SELECT_TARGET_RANDOM, 0, NOMINAL_MELEE_RANGE, true); if (randomMelee) DoCast(randomMelee,SPELL_UPPERCUT); UpperCut_Timer = 15000+rand()%15000; @@ -560,7 +560,7 @@ struct TRINITY_DLL_DECL boss_veklorAI : public boss_twinemperorsAI if (Blizzard_Timer < diff) { Unit* target = NULL; - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 45, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45, true); if (target) DoCast(target,SPELL_BLIZZARD); Blizzard_Timer = 15000+rand()%15000; @@ -569,7 +569,7 @@ struct TRINITY_DLL_DECL boss_veklorAI : public boss_twinemperorsAI if (ArcaneBurst_Timer < diff) { Unit *mvic; - if ((mvic=SelectUnit(SELECT_TARGET_NEAREST, 0, NOMINAL_MELEE_RANGE, true))!=NULL) + if ((mvic=SelectTarget(SELECT_TARGET_NEAREST, 0, NOMINAL_MELEE_RANGE, true))!=NULL) { DoCast(mvic,SPELL_ARCANEBURST); ArcaneBurst_Timer = 5000; diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp index f31f944a3d4..85ba26ef20d 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp @@ -297,7 +297,7 @@ struct TRINITY_DLL_DECL boss_akilzonAI : public ScriptedAI } if (ElectricalStorm_Timer < diff) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 50, true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true); if(!target) { EnterEvadeMode(); diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp index 7fb8dc9b321..26229261905 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp @@ -383,7 +383,7 @@ struct TRINITY_DLL_DECL boss_hex_lord_malacrassAI : public ScriptedAI if(SiphonSoul_Timer < diff) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 70, true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true); Unit *trigger = DoSpawnCreature(MOB_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); if(!target || !trigger) { diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp index 9fc50e621ac..68b92590025 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp @@ -406,7 +406,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI { DoYell(YELL_SURGE, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_YELL_SURGE); - Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_SURGE), true); + Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_SURGE), true); if(target) DoCast(target, SPELL_SURGE); Surge_Timer = 15000 + rand()%5000; diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 5cde80aaccb..0713ef592d3 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -71,6 +71,8 @@ void CreatureAI::OnCharmed(bool apply) me->IsAIEnabled = false; } +AISpellInfoType *AISpellInfo; + void CreatureAI::DoZoneInCombat(Creature* creature) { if (!creature) @@ -151,6 +153,148 @@ void CreatureAI::EnterEvadeMode() me->GetMotionMaster()->MoveTargetedHome(); } +inline bool SelectTargetHelper(const Unit * me, const Unit * target, const bool &playerOnly, const float &dist, const int32 &aura) +{ + if(playerOnly && target->GetTypeId() != TYPEID_PLAYER) + return false; + + if(dist && !me->IsWithinCombatRange(target, dist)) + return false; + + if(aura) + { + if(aura > 0) + { + if(!target->HasAura(aura)) + return false; + } + else + { + if(target->HasAura(aura)) + return false; + } + } + + return true; +} + +struct TargetDistanceOrder : public std::binary_function +{ + const Unit * me; + TargetDistanceOrder(const Unit* Target) : me(Target) {}; + // functor for operator ">" + bool operator()(const Unit * _Left, const Unit * _Right) const + { + return (me->GetDistanceSq(_Left) < me->GetDistanceSq(_Right)); + } +}; + +Unit* CreatureAI::SelectTarget(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly, int32 aura) +{ + if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) + { + std::list &m_threatlist = me->getThreatManager().getThreatList(); + if(position >= m_threatlist.size()) + return NULL; + + std::list targetList; + for(std::list::iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) + if(SelectTargetHelper(me, (*itr)->getTarget(), playerOnly, dist, aura)) + targetList.push_back((*itr)->getTarget()); + + if(position >= targetList.size()) + return NULL; + + targetList.sort(TargetDistanceOrder(m_creature)); + + if(targetType == SELECT_TARGET_NEAREST) + { + std::list::iterator i = targetList.begin(); + advance(i, position); + return *i; + } + else + { + std::list::reverse_iterator i = targetList.rbegin(); + advance(i, position); + return *i; + } + } + else + { + std::list m_threatlist = me->getThreatManager().getThreatList(); + std::list::iterator i; + while(position < m_threatlist.size()) + { + if(targetType == SELECT_TARGET_BOTTOMAGGRO) + { + i = m_threatlist.end(); + advance(i, - (int32)position - 1); + } + else + { + i = m_threatlist.begin(); + if(targetType == SELECT_TARGET_TOPAGGRO) + advance(i, position); + else // random + advance(i, position + rand()%(m_threatlist.size() - position)); + } + + if(SelectTargetHelper(me, (*i)->getTarget(), playerOnly, dist, aura)) + return (*i)->getTarget(); + else + m_threatlist.erase(i); + } + } + + return NULL; +} + +void CreatureAI::SelectTargetList(std::list &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly, int32 aura) +{ + if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) + { + std::list &m_threatlist = m_creature->getThreatManager().getThreatList(); + if(m_threatlist.empty()) + return; + + for(std::list::iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) + if(SelectTargetHelper(me, (*itr)->getTarget(), playerOnly, dist, aura)) + targetList.push_back((*itr)->getTarget()); + + targetList.sort(TargetDistanceOrder(me)); + targetList.resize(num); + if(targetType == SELECT_TARGET_FARTHEST) + targetList.reverse(); + } + else + { + std::list m_threatlist = me->getThreatManager().getThreatList(); + std::list::iterator i; + while(!m_threatlist.empty() && num) + { + if(targetType == SELECT_TARGET_BOTTOMAGGRO) + { + i = m_threatlist.end(); + --i; + } + else + { + i = m_threatlist.begin(); + if(targetType == SELECT_TARGET_RANDOM) + advance(i, rand()%m_threatlist.size()); + } + + if(SelectTargetHelper(me, (*i)->getTarget(), playerOnly, dist, aura)) + { + targetList.push_back((*i)->getTarget()); + --num; + } + m_threatlist.erase(i); + } + } +} + void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) { Creature *charmer = (Creature*)me->GetCharmer(); diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index e3a5a674e68..16271775728 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -37,7 +37,7 @@ struct SpellEntry; #define VISIBILITY_RANGE 10000 //Spell targets used by SelectSpell -enum SelectTarget +enum SelectTargetType { SELECT_TARGET_DONTCARE = 0, //All target types allowed @@ -77,6 +77,35 @@ enum SCEquip EQUIP_UNEQUIP = 0 }; +enum AITarget +{ + AITARGET_SELF, + AITARGET_VICTIM, + AITARGET_ENEMY, + AITARGET_ALLY, + AITARGET_BUFF, + AITARGET_DEBUFF, +}; + +enum AICondition +{ + AICOND_AGGRO, + AICOND_COMBAT, + AICOND_DIE, +}; + +#define AI_DEFAULT_COOLDOWN 5000 + +struct AISpellInfoType +{ + AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {} + AITarget target; + AICondition condition; + uint32 cooldown; +}; + +extern AISpellInfoType *AISpellInfo; + class EventMap : private std::map { private: @@ -273,6 +302,9 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI // Pointer to controlled by AI creature //Creature* const m_creature; + + Unit* SelectTarget(SelectAggroTarget target, uint32 position = 0, float dist = 0, bool playerOnly = false, int32 aura = 0); + void SelectTargetList(std::list &targetList, uint32 num, SelectAggroTarget target, float dist = 0, bool playerOnly = false, int32 aura = 0); }; struct SelectableAI : public FactoryHolder, public Permissible diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 6b7a3cdd4ac..a436732f0a6 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1194,6 +1194,14 @@ float WorldObject::GetDistanceSq(const float &x, const float &y, const float &z) return dx*dx + dy*dy + dz*dz; } +float WorldObject::GetDistanceSq(const WorldObject *obj) const +{ + float dx = GetPositionX() - obj->GetPositionX(); + float dy = GetPositionY() - obj->GetPositionY(); + float dz = GetPositionZ() - obj->GetPositionZ(); + return dx*dx + dy*dy + dz*dz; +} + float WorldObject::GetDistance2d(const WorldObject* obj) const { float dx = GetPositionX() - obj->GetPositionX(); diff --git a/src/game/Object.h b/src/game/Object.h index e7e03501dc1..01c31d5b9b4 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -463,6 +463,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object float GetDistance( const WorldObject* obj ) const; float GetDistance(const float x, const float y, const float z) const; float GetDistanceSq(const float &x, const float &y, const float &z) const; + float GetDistanceSq(const WorldObject *obj) const; float GetDistance2d(const WorldObject* obj) const; float GetDistance2d(const float x, const float y) const; float GetExactDistance2d(const float x, const float y) const; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 6a9f122adf4..3f09eec9351 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -413,7 +413,7 @@ void Unit::resetAttackTimer(WeaponAttackType type) m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); } -bool Unit::IsWithinCombatRange(Unit *obj, float dist2compare) const +bool Unit::IsWithinCombatRange(const Unit *obj, float dist2compare) const { if (!obj || !IsInMap(obj)) return false; @@ -428,7 +428,7 @@ bool Unit::IsWithinCombatRange(Unit *obj, float dist2compare) const return distsq < maxdist * maxdist; } -bool Unit::IsWithinMeleeRange(Unit *obj, float dist) const +bool Unit::IsWithinMeleeRange(const Unit *obj, float dist) const { if (!obj || !IsInMap(obj)) return false; diff --git a/src/game/Unit.h b/src/game/Unit.h index 5d08cbfa2fb..bb303473e7b 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -940,8 +940,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void SetCanDualWield(bool value) { m_canDualWield = value; } float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; } float GetMeleeReach() const { float reach = m_floatValues[UNIT_FIELD_COMBATREACH]; return reach > MIN_MELEE_REACH ? reach : MIN_MELEE_REACH; } - bool IsWithinCombatRange(Unit *obj, float dist2compare) const; - bool IsWithinMeleeRange(Unit *obj, float dist = MELEE_RANGE) const; + bool IsWithinCombatRange(const Unit *obj, float dist2compare) const; + bool IsWithinMeleeRange(const Unit *obj, float dist = MELEE_RANGE) const; void GetRandomContactPoint( const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const; uint32 m_extraAttacks; bool m_canDualWield; -- cgit v1.2.3 From 66c4b7b56086e59eb8e6fc324f48d90e92fb44f6 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 14:30:04 -0500 Subject: [7804] Allow swap and move by bag slots equipped ammopouch and quiver Author: Foks --HG-- branch : trunk --- src/game/Player.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index bfd47aa8279..4185e18ee47 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -9848,14 +9848,17 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo { if( Item* pBag = GetItemByPos( INVENTORY_SLOT_BAG_0, i ) ) { - if( ItemPrototype const* pBagProto = pBag->GetProto() ) + if( pBag != pItem ) { - if( pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot ) ) + if( ItemPrototype const* pBagProto = pBag->GetProto() ) { - if(pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH) - return EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH; - else - return EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER; + if( pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot ) ) + { + if(pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH) + return EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH; + else + return EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER; + } } } } -- cgit v1.2.3 From 6b8f75af99376929bb1ac99237aaf23c0fdfd565 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 14:43:29 -0500 Subject: [7805] Refactoring batleground rewards code for cleanup and useful state for custom reward reuse. Author: Nezemnoy --HG-- branch : trunk --- src/game/BattleGround.cpp | 75 +++++++++++++++++++++++++++++------------------ src/game/BattleGround.h | 4 ++- 2 files changed, 50 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index d179ec33691..7a6b96070a1 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -726,12 +726,10 @@ void BattleGround::EndBattleGround(uint32 winner) if (team == winner) { RewardMark(plr,ITEM_WINNER_COUNT); - RewardQuest(plr); + RewardQuestComplete(plr); } - else if(winner !=0) - { + else if(winner) RewardMark(plr,ITEM_LOSER_COUNT); - } plr->CombatStopWithPets(true); @@ -785,13 +783,6 @@ uint32 BattleGround::GetBattlemasterEntry() const void BattleGround::RewardMark(Player *plr,uint32 count) { - // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens - if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) - return; - - if(!plr || !count) - return; - BattleGroundMarks mark; switch(GetTypeID()) { @@ -811,21 +802,53 @@ void BattleGround::RewardMark(Player *plr,uint32 count) return; } - if ( objmgr.GetItemPrototype( mark ) ) + //if (IsSpell) + // RewardSpellCast(plr,mark); + //else + RewardItem(plr,mark,count); +} + +void BattleGround::RewardSpellCast(Player *plr, uint32 spell_id) +{ + // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens + if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) + return; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); + if(!spellInfo) { - ItemPosCountVec dest; - uint32 no_space_count = 0; - uint8 msg = plr->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, mark, count, &no_space_count ); - if( msg != EQUIP_ERR_OK ) // convert to possible store amount - count -= no_space_count; + sLog.outError("Battleground reward casting spell %u not exist.",spell_id); + return; + } - if(!dest.empty()) // can add some - if(Item* item = plr->StoreNewItem( dest, mark, true, 0)) - plr->SendNewItem(item,count,false,true); + plr->CastSpell(plr, spellInfo, true); +} + +void BattleGround::RewardItem(Player *plr, uint32 item_id, uint32 count) +{ + // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens + if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) + return; - if (no_space_count > 0) - SendRewardMarkByMail(plr,mark,no_space_count); + ItemPosCountVec dest; + uint32 no_space_count = 0; + uint8 msg = plr->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item_id, count, &no_space_count ); + + if( msg == EQUIP_ERR_ITEM_NOT_FOUND) + { + sLog.outErrorDb("Battleground reward item (Entry %u) not exist in `item_template`.",item_id); + return; } + + if( msg != EQUIP_ERR_OK ) // convert to possible store amount + count -= no_space_count; + + if( count != 0 && !dest.empty()) // can add some + if (Item* item = plr->StoreNewItem( dest, item_id, true, 0)) + plr->SendNewItem(item,count,false,true); + + if (no_space_count > 0) + SendRewardMarkByMail(plr,item_id,no_space_count); } void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count) @@ -865,12 +888,8 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count) } } -void BattleGround::RewardQuest(Player *plr) +void BattleGround::RewardQuestComplete(Player *plr) { - // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens - if (plr->GetDummyAura(SPELL_AURA_PLAYER_INACTIVE)) - return; - uint32 quest; switch(GetTypeID()) { @@ -890,7 +909,7 @@ void BattleGround::RewardQuest(Player *plr) return; } - plr->CastSpell(plr, quest, true); + RewardSpellCast(plr, quest); } void BattleGround::BlockMovement(Player *plr) diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 9788f264502..509ba6eb972 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -421,7 +421,9 @@ class BattleGround void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID); void RewardMark(Player *plr,uint32 count); void SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count); - void RewardQuest(Player *plr); + void RewardItem(Player *plr, uint32 item_id, uint32 count); + void RewardQuestComplete(Player *plr); + void RewardSpellCast(Player *plr, uint32 spell_id); void UpdateWorldState(uint32 Field, uint32 Value); void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source); void EndBattleGround(uint32 winner); -- cgit v1.2.3 From fe0b73c3a62d18c42d8e232603e40f0e0895a5a3 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 14:43:58 -0500 Subject: [7806] Defines for known gossip icon value cases. Author: NoFantasy --HG-- branch : trunk --- src/game/Creature.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/game/Creature.h b/src/game/Creature.h index 36cfee78c5f..76470495e91 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -108,6 +108,21 @@ enum Gossip_Guard_Skill GOSSIP_GUARD_SKILL_ENGINERING = 91 }; +enum GossipOptionIcon +{ + GOSSIP_ICON_CHAT = 0, //white chat bubble + GOSSIP_ICON_VENDOR = 1, //brown bag + GOSSIP_ICON_TAXI = 2, //flight + GOSSIP_ICON_TRAINER = 3, //book + GOSSIP_ICON_INTERACT_1 = 4, //interaction wheel + GOSSIP_ICON_INTERACT_2 = 5, //interaction wheel + GOSSIP_ICON_MONEY_BAG = 6, //brown bag with yellow dot + GOSSIP_ICON_TALK = 7, //white chat bubble with black dots + GOSSIP_ICON_TABARD = 8, //tabard + GOSSIP_ICON_BATTLE = 9, //two swords + GOSSIP_ICON_DOT = 10 //yellow dot +}; + struct GossipOption { uint32 Id; -- cgit v1.2.3 From f8645d8706d1d3a78b15f8c7419d85af2ee4bbdd Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 14:45:06 -0500 Subject: [7807] Drop dead code after switch to 3.0.x. Author: VladimirMangos --HG-- branch : trunk --- src/game/SpellAuras.cpp | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'src') diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 3045e89f315..3e9c3a922f2 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2667,25 +2667,6 @@ void AuraEffect::HandleAuraDummy(bool apply, bool Real) } case SPELLFAMILY_HUNTER: { - // Improved Aspect of the Viper - if( GetId()==38390 && m_target->GetTypeId()==TYPEID_PLAYER ) - { - if(apply) - { - // + effect value for Aspect of the Viper - SpellModifier *mod = new SpellModifier; - mod->op = SPELLMOD_EFFECT1; - mod->value = m_amount; - mod->type = SPELLMOD_FLAT; - mod->spellId = GetId(); - mod->mask[1] = 0x40000; - - m_spellmod = mod; - } - - ((Player*)m_target)->AddSpellMod(m_spellmod, apply); - return; - } // Glyph of Aspect of the Monkey if(m_spellProto->Id==56833) { -- cgit v1.2.3 From b8e82a23a6ddfd5ee506745bb04dbfd654112cdc Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 14:47:56 -0500 Subject: [7808] Move corpse search code in function with template arg for class-check. Author: Astellar This let reuse code for other similar near corpse target selection spells. Also provided currently not used class-checks for 2 spells --HG-- branch : trunk --- src/game/Creature.h | 1 + src/game/GridNotifiers.h | 59 ++++++++++++++++++++++++++++++++++++++++-------- src/game/SharedDefines.h | 1 + src/game/Spell.cpp | 41 ++++++++++++++++++++++++--------- src/game/Spell.h | 2 ++ 5 files changed, 84 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/game/Creature.h b/src/game/Creature.h index 76470495e91..b90642547dd 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -650,6 +650,7 @@ class TRINITY_DLL_SPEC Creature : public Unit bool IsVisibleInGridForPlayer(Player const* pl) const; void RemoveCorpse(); + bool isDeadByDefault() const { return m_isDeadByDefault; }; time_t const& GetRespawnTime() const { return m_respawnTime; } time_t GetRespawnTimeEx() const; diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index 03d8ea11b16..195f7206264 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -499,6 +499,53 @@ namespace Trinity // CHECKS && DO classes // WorldObject check classes + class RaiseDeadObjectCheck + { + public: + RaiseDeadObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {} + bool operator()(Creature* u) + { + if (i_funit->GetTypeId()!=TYPEID_PLAYER || !((Player*)i_funit)->isHonorOrXPTarget(u) || + u->getDeathState() != CORPSE || u->isDeadByDefault() || u->isInFlight() || + ( u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1)) )==0 || + (u->GetDisplayId() != u->GetNativeDisplayId())) + return false; + + return i_funit->IsWithinDistInMap(u, i_range); + } + template bool operator()(NOT_INTERESTED*) { return false; } + private: + Unit* const i_funit; + float i_range; + }; + + class ExplodeCorpseObjectCheck + { + public: + ExplodeCorpseObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {} + bool operator()(Player* u) + { + if (u->getDeathState()!=CORPSE || u->isInFlight() || + u->HasAuraType(SPELL_AURA_GHOST) || (u->GetDisplayId() != u->GetNativeDisplayId())) + return false; + + return i_funit->IsWithinDistInMap(u, i_range); + } + bool operator()(Creature* u) + { + if (u->getDeathState()!=CORPSE || u->isInFlight() || u->isDeadByDefault() || + (u->GetDisplayId() != u->GetNativeDisplayId()) || + (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)!=0) + return false; + + return i_funit->IsWithinDistInMap(u, i_range); + } + template bool operator()(NOT_INTERESTED*) { return false; } + private: + Unit* const i_funit; + float i_range; + }; + class CannibalizeObjectCheck { public: @@ -508,22 +555,16 @@ namespace Trinity if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ) return false; - if(i_funit->IsWithinDistInMap(u, i_range) ) - return true; - - return false; + return i_funit->IsWithinDistInMap(u, i_range); } bool operator()(Corpse* u); bool operator()(Creature* u) { - if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() || + if (i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() || (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD)==0) return false; - if(i_funit->IsWithinDistInMap(u, i_range) ) - return true; - - return false; + return i_funit->IsWithinDistInMap(u, i_range); } template bool operator()(NOT_INTERESTED*) { return false; } private: diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 5a32744da7c..e592bebf1de 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1820,6 +1820,7 @@ enum CreatureType }; uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD = (1 << (CREATURE_TYPE_HUMANOID-1)) | (1 << (CREATURE_TYPE_UNDEAD-1)); +uint32 const CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL = (1 << (CREATURE_TYPE_MECHANICAL-1)) | (1 << (CREATURE_TYPE_ELEMENTAL-1)); // CreatureFamily.dbc enum CreatureFamily diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 5b53647fe4c..0835273a36c 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -476,6 +476,35 @@ Spell::~Spell() delete m_spellValue; } +template +WorldObject* Spell::FindCorpseUsing() +{ + // non-standard target selection + float max_range = GetSpellMaxRange(m_spellInfo, false); + + CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + WorldObject* result = NULL; + + T u_check(m_caster, max_range); + MaNGOS::WorldObjectSearcher searcher(m_caster, result, u_check); + + TypeContainerVisitor, GridTypeMapContainer > grid_searcher(searcher); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap()); + + if (!result) + { + TypeContainerVisitor, WorldTypeMapContainer > world_searcher(searcher); + cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap()); + } + + return result; +} + void Spell::FillTargetMap() { for(uint32 i = 0; i < 3; ++i) @@ -535,17 +564,7 @@ void Spell::FillTargetMap() { case 20577: // Cannibalize { - // non-standard target selection - SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); - float max_range = GetSpellMaxRangeForHostile(srange); - WorldObject* result = NULL; - - Trinity::CannibalizeObjectCheck u_check(m_caster, max_range); - Trinity::WorldObjectSearcher searcher(m_caster, result, u_check); - m_caster->VisitNearbyGridObject(max_range, searcher); - if(!result) - m_caster->VisitNearbyWorldObject(max_range, searcher); - + WorldObject* result = FindCorpseUsing (); if(result) { diff --git a/src/game/Spell.h b/src/game/Spell.h index 6dc8477dcdb..642c40de474 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -412,6 +412,8 @@ class Spell void SetTargetMap(uint32 i, uint32 cur); + template WorldObject* FindCorpseUsing(); + bool CheckTarget( Unit* target, uint32 eff ); bool CanAutoCast(Unit* target); void CheckSrc() { if(!m_targets.HasSrc()) m_targets.setSrc(m_caster); } -- cgit v1.2.3 From ff3332f0661e0f19a2afa34a96997066bf99cc8a Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 14:51:51 -0500 Subject: [7809] Replace repeating "remove cooldown and send update to client" code by function call. Author: VladimirMangos --HG-- branch : trunk --- src/game/Level3.cpp | 6 +----- src/game/Player.cpp | 14 ++++++++++++++ src/game/Player.h | 2 +- src/game/Spell.cpp | 10 +--------- src/game/SpellEffects.cpp | 36 ++++-------------------------------- 5 files changed, 21 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index f4ec15bcfb0..9d43c348831 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -1612,11 +1612,7 @@ bool ChatHandler::HandleCooldownCommand(const char* args) return false; } - WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) ); - data << uint32(spell_id); - data << uint64(target->GetGUID()); - target->GetSession()->SendPacket(&data); - target->RemoveSpellCooldown(spell_id); + target->RemoveSpellCooldown(spell_id,true); PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str()); } return true; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4185e18ee47..b3aad430b32 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -3289,6 +3289,20 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_ } } + +void Player::RemoveSpellCooldown( uint32 spell_id, bool update /* = false */ ) +{ + m_spellCooldowns.erase(spell_id); + + if(update) + { + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(spell_id); + data << uint64(GetGUID()); + SendDirectMessage(&data); + } +} + void Player::RemoveArenaSpellCooldowns() { // remove cooldowns on spells that has < 15 min CD diff --git a/src/game/Player.h b/src/game/Player.h index be509972e71..b322209a6f5 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1384,7 +1384,7 @@ class TRINITY_DLL_SPEC Player : public Unit void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time); void SendCooldownEvent(SpellEntry const *spellInfo, uint32 itemId = 0, Spell* spell = NULL); void ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs ); - void RemoveSpellCooldown(uint32 spell_id) { m_spellCooldowns.erase(spell_id); } + void RemoveSpellCooldown(uint32 spell_id, bool update = false); void RemoveArenaSpellCooldowns(); void RemoveAllSpellCooldown(); void _LoadSpellCooldowns(QueryResult *result); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 0835273a36c..b8b92cbbadf 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -585,15 +585,7 @@ void Spell::FillTargetMap() { // clear cooldown at fail if(m_caster->GetTypeId()==TYPEID_PLAYER) - { - ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(m_spellInfo->Id); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); - } - + ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id,true); SendCastResult(SPELL_FAILED_NO_EDIBLE_CORPSES); finish(false); } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index d213040ede4..ae513a84dfd 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1323,12 +1323,7 @@ void Spell::EffectDummy(uint32 i) (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST) && spellInfo->Id != 11958 && GetSpellRecoveryTime(spellInfo) > 0 ) { - ((Player*)m_caster)->RemoveSpellCooldown(classspell); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(classspell); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); + ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); } } return; @@ -1579,14 +1574,7 @@ void Spell::EffectDummy(uint32 i) SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags[1] & 0x00000240 || spellInfo->SpellFamilyFlags[0] & 0x00000860)) - { - ((Player*)m_caster)->RemoveSpellCooldown(classspell); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(classspell); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); - } + ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); } return; } @@ -1613,14 +1601,7 @@ void Spell::EffectDummy(uint32 i) SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->Id != 23989 && GetSpellRecoveryTime(spellInfo) > 0 ) - { - ((Player*)m_caster)->RemoveSpellCooldown(classspell); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(classspell); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); - } + ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); } return; } @@ -1715,17 +1696,8 @@ void Spell::EffectDummy(uint32 i) // non-standard cast requirement check if (!unitTarget || unitTarget->getAttackers().empty()) { - // clear cooldown at fail if(m_caster->GetTypeId()==TYPEID_PLAYER) - { - ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(m_spellInfo->Id); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); - } - + ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id,true); SendCastResult(SPELL_FAILED_TARGET_AFFECTING_COMBAT); return; } -- cgit v1.2.3 From 518ac83fbf51eb60d02d619e7c2a176272768c97 Mon Sep 17 00:00:00 2001 From: Anubisss Date: Sun, 10 May 2009 23:06:39 +0200 Subject: *Fix two typos. --HG-- branch : trunk --- src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp | 2 +- .../scripts/scripts/zone/utgarde_keep/utgarde_keep/utgarde_keep.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index 034141e2580..23ffb7b8c4d 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -143,6 +143,6 @@ void AddSC_instance_naxxramas() Script *newscript; newscript = new Script; newscript->Name = "instance_naxxramas"; - newscript->GetInstanceData = GetInstanceData_instance_naxxramas; + newscript->GetInstanceData = &GetInstanceData_instance_naxxramas; newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/utgarde_keep.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/utgarde_keep.cpp index 3c2b898653d..923328627e4 100644 --- a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/utgarde_keep.cpp +++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/utgarde_keep.cpp @@ -155,6 +155,6 @@ void AddSC_utgarde_keep() newscript = new Script; newscript->Name="npc_dragonflayer_forge_master"; - newscript->GetAI = GetAI_npc_dragonflayer_forge_master; + newscript->GetAI = &GetAI_npc_dragonflayer_forge_master; newscript->RegisterSelf(); -} \ No newline at end of file +} -- cgit v1.2.3 From dcf41256ddaa341b532bd7c565c3d18a7c3b6757 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 16:07:49 -0500 Subject: *Move some AI functions to core. No real change. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 1 - src/bindings/scripts/include/sc_creature.h | 76 ++----- src/game/CMakeLists.txt | 5 +- src/game/CreatureAI.cpp | 64 +----- src/game/CreatureAI.h | 166 +------------- src/game/CreatureAIFactory.h | 53 +++++ src/game/CreatureAIImpl.h | 153 ++++++++++++- src/game/CreatureAIRegistry.cpp | 3 +- src/game/CreatureAISelector.cpp | 2 +- src/game/InstanceSaveMgr.cpp | 2 + src/game/NullCreatureAI.h | 1 + src/game/PossessedAI.cpp | 20 -- src/game/PossessedAI.h | 25 --- src/game/UnitAI.cpp | 84 ++++++++ src/game/UnitAI.h | 68 ++++++ win/VC80/game.vcproj | 224 +++++++++---------- win/VC90/game.vcproj | 309 ++++++++++++++------------- 17 files changed, 653 insertions(+), 603 deletions(-) create mode 100644 src/game/CreatureAIFactory.h delete mode 100644 src/game/PossessedAI.cpp delete mode 100644 src/game/PossessedAI.h create mode 100644 src/game/UnitAI.cpp create mode 100644 src/game/UnitAI.h (limited to 'src') diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 4a9f8ec61e8..42ee15074ed 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -375,7 +375,6 @@ bool ScriptedAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered) return true; } - float GetSpellMaxRangeForHostile(uint32 id) { SpellEntry const *spellInfo = GetSpellStore()->LookupEntry(id); diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 44caf063162..8336df545b6 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -8,75 +8,25 @@ #ifndef SC_CREATURE_H #define SC_CREATURE_H -#include "CreatureAI.h" #include "Creature.h" - -#define HEROIC(n,h) (HeroicMode ? h : n) - -template -inline -const T& RAND(const T& v1, const T& v2) -{ - return rand()%2 ? v1 : v2; -} - -template -inline -const T& RAND(const T& v1, const T& v2, const T& v3) -{ - switch(rand()%3) - { - default: - case 0: return v1; - case 1: return v2; - case 2: return v3; - } -} - -template -inline -const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4) -{ - switch(rand()%4) - { - default: - case 0: return v1; - case 1: return v2; - case 2: return v3; - case 3: return v4; - } -} - -template -inline -const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) -{ - switch(rand()%4) - { - default: - case 0: return v1; - case 1: return v2; - case 2: return v3; - case 3: return v4; - case 4: return v5; - } -} - -float GetSpellMaxRangeForHostile(uint32 id); +#include "CreatureAI.h" +#include "CreatureAIImpl.h" class SummonList : private std::list { -public: - explicit SummonList(Creature* creature) : m_creature(creature) {} - void Summon(Creature *summon) { push_back(summon->GetGUID()); } - void Despawn(Creature *summon) { remove(summon->GetGUID()); } - void DespawnEntry(uint32 entry); - void DespawnAll(); - void DoAction(uint32 entry, uint32 info); -private: - Creature *m_creature; + public: + explicit SummonList(Creature* creature) : m_creature(creature) {} + void Summon(Creature *summon) { push_back(summon->GetGUID()); } + void Despawn(Creature *summon) { remove(summon->GetGUID()); } + void DespawnEntry(uint32 entry); + void DespawnAll(); + void DoAction(uint32 entry, uint32 info); + private: + Creature *m_creature; }; +float GetSpellMaxRangeForHostile(uint32 id); + //Get a single creature of given entry Unit* FindCreature(uint32 entry, float range, Unit* Finder); diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index 081d9669696..89a9e460968 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -68,6 +68,7 @@ SET(game_STAT_SRCS Corpse.h CreatureAI.cpp CreatureAI.h + CreatureAIFactory.h CreatureAIImpl.h CreatureAIRegistry.cpp CreatureAIRegistry.h @@ -208,8 +209,6 @@ SET(game_STAT_SRCS PointMovementGenerator.h PoolHandler.cpp PoolHandler.h - PossessedAI.cpp - PossessedAI.h QueryHandler.cpp QuestDef.cpp QuestDef.h @@ -262,6 +261,8 @@ SET(game_STAT_SRCS Traveller.h Unit.cpp Unit.h + UnitAI.cpp + UnitAI.h UnitEvents.h UpdateData.cpp UpdateData.h diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 0713ef592d3..2390b359731 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -19,50 +19,12 @@ */ #include "CreatureAI.h" +#include "CreatureAIImpl.h" #include "Creature.h" #include "Player.h" #include "Pet.h" -#include "SpellAuras.h" #include "World.h" -void UnitAI::AttackStart(Unit *victim) -{ - if(!victim) - return; - - if(me->Attack(victim, true)) - { - //DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", me->GetName(), victim->GetGUIDLow()); - me->GetMotionMaster()->MoveChase(victim); - } -} - -void UnitAI::DoMeleeAttackIfReady() -{ - //Make sure our attack is ready and we aren't currently casting before checking distance - if (me->isAttackReady() && !me->hasUnitState(UNIT_STAT_CASTING)) - { - //If we are within range melee the target - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim()); - me->resetAttackTimer(); - } - } - if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK) && !me->hasUnitState(UNIT_STAT_CASTING)) - { - //If we are within range melee the target - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim(), OFF_ATTACK); - me->resetAttackTimer(OFF_ATTACK); - } - } -} - -//Enable PlayerAI when charmed -void PlayerAI::OnCharmed(bool apply) { me->IsAIEnabled = apply; } - //Disable CreatureAI when charmed void CreatureAI::OnCharmed(bool apply) { @@ -295,30 +257,6 @@ void CreatureAI::SelectTargetList(std::list &targetList, uint32 num, Sele } } -void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) -{ - Creature *charmer = (Creature*)me->GetCharmer(); - - //kill self if charm aura has infinite duration - if(charmer->IsInEvadeMode()) - { - Unit::AuraEffectList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM); - for(Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) - if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->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)) - AttackStart(charmer->SelectNearestTarget()); -} - /*void CreatureAI::AttackedBy( Unit* attacker ) { if(!m_creature->getVictim()) diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index 16271775728..6df7dcfbe95 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -23,9 +23,7 @@ #include "Common.h" #include "Platform/Define.h" -#include "Policies/Singleton.h" -#include "Dynamic/ObjectRegistry.h" -#include "Dynamic/FactoryHolder.h" +#include "UnitAI.h" class WorldObject; class Unit; @@ -77,149 +75,11 @@ enum SCEquip EQUIP_UNEQUIP = 0 }; -enum AITarget -{ - AITARGET_SELF, - AITARGET_VICTIM, - AITARGET_ENEMY, - AITARGET_ALLY, - AITARGET_BUFF, - AITARGET_DEBUFF, -}; - -enum AICondition -{ - AICOND_AGGRO, - AICOND_COMBAT, - AICOND_DIE, -}; - -#define AI_DEFAULT_COOLDOWN 5000 - -struct AISpellInfoType -{ - AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {} - AITarget target; - AICondition condition; - uint32 cooldown; -}; - -extern AISpellInfoType *AISpellInfo; - -class EventMap : private std::map -{ - private: - uint32 m_time, m_phase; - public: - explicit EventMap() : m_phase(0), m_time(0) {} - - void Reset() { clear(); m_time = 0; m_phase = 0; } - - void Update(uint32 time) { m_time += time; } - - void SetPhase(uint32 phase) - { - if(phase && phase < 9) - m_phase = (1 << (phase + 24)); - } - - void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) - { - time += m_time; - if(gcd && gcd < 9) - eventId |= (1 << (gcd + 16)); - if(phase && phase < 9) - eventId |= (1 << (phase + 24)); - iterator itr = find(time); - while(itr != end()) - { - ++time; - itr = find(time); - } - insert(std::make_pair(time, eventId)); - } - - uint32 ExecuteEvent() - { - while(!empty()) - { - if(begin()->first > m_time) - return 0; - else if(m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase)) - erase(begin()); - else - { - uint32 eventId = (begin()->second & 0x0000FFFF); - erase(begin()); - return eventId; - } - } - return 0; - } - - void DelayEvents(uint32 time, uint32 gcd) - { - time += m_time; - gcd = (1 << (gcd + 16)); - for(iterator itr = begin(); itr != end();) - { - if(itr->first >= time) - break; - if(itr->second & gcd) - { - ScheduleEvent(time, itr->second); - erase(itr++); - } - else - ++itr; - } - } -}; - -class TRINITY_DLL_SPEC UnitAI -{ - protected: - Unit* const me; - public: - explicit UnitAI(Unit *u) : me(u) {} - virtual void AttackStart(Unit *); - virtual void UpdateAI(const uint32 diff) = 0; - - virtual void InitializeAI() { Reset(); } - - virtual void Reset() {}; - - // Called when unit is charmed - virtual void OnCharmed(bool apply) = 0; - - // Pass parameters between AI - virtual void DoAction(const int32 param) {} - - //Do melee swing of current victim if in rnage and ready and not casting - void DoMeleeAttackIfReady(); -}; - -class TRINITY_DLL_SPEC PlayerAI : public UnitAI -{ - protected: - Player* const me; - public: - explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {} - - void OnCharmed(bool apply); -}; - -class TRINITY_DLL_SPEC SimpleCharmedAI : public PlayerAI -{ - public: - void UpdateAI(const uint32 diff); -}; - class TRINITY_DLL_SPEC CreatureAI : public UnitAI { protected: - Creature* const me; - Creature* const m_creature; + Creature * const me; + Creature * const m_creature; bool UpdateVictim(); public: @@ -307,22 +167,6 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI void SelectTargetList(std::list &targetList, uint32 num, SelectAggroTarget target, float dist = 0, bool playerOnly = false, int32 aura = 0); }; -struct SelectableAI : public FactoryHolder, public Permissible -{ - - SelectableAI(const char *id) : FactoryHolder(id) {} -}; - -template -struct CreatureAIFactory : public SelectableAI -{ - CreatureAIFactory(const char *name) : SelectableAI(name) {} - - CreatureAI* Create(void *) const; - - int Permit(const Creature *c) const { return REAL_AI::Permissible(c); } -}; - enum Permitions { PERMIT_BASE_NO = -1, @@ -333,8 +177,4 @@ enum Permitions PERMIT_BASE_SPECIAL = 800 }; -typedef FactoryHolder CreatureAICreator; -typedef FactoryHolder::FactoryHolderRegistry CreatureAIRegistry; -typedef FactoryHolder::FactoryHolderRepository CreatureAIRepository; #endif - diff --git a/src/game/CreatureAIFactory.h b/src/game/CreatureAIFactory.h new file mode 100644 index 00000000000..d546c2b1720 --- /dev/null +++ b/src/game/CreatureAIFactory.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2009 Trinity + * + * 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 + */ +#ifndef TRINITY_CREATUREAIFACTORY_H +#define TRINITY_CREATUREAIFACTORY_H + +//#include "Policies/Singleton.h" +#include "Dynamic/ObjectRegistry.h" +#include "Dynamic/FactoryHolder.h" + +struct SelectableAI : public FactoryHolder, public Permissible +{ + SelectableAI(const char *id) : FactoryHolder(id) {} +}; + +template +struct CreatureAIFactory : public SelectableAI +{ + CreatureAIFactory(const char *name) : SelectableAI(name) {} + + CreatureAI* Create(void *) const; + + int Permit(const Creature *c) const { return REAL_AI::Permissible(c); } +}; + +template +inline CreatureAI* +CreatureAIFactory::Create(void *data) const +{ + Creature* creature = reinterpret_cast(data); + return (new REAL_AI(creature)); +} + +typedef FactoryHolder CreatureAICreator; +typedef FactoryHolder::FactoryHolderRegistry CreatureAIRegistry; +typedef FactoryHolder::FactoryHolderRepository CreatureAIRepository; +#endif diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h index a8b8271c5ff..823f4cbcca6 100644 --- a/src/game/CreatureAIImpl.h +++ b/src/game/CreatureAIImpl.h @@ -20,14 +20,155 @@ #ifndef CREATUREAIIMPL_H #define CREATUREAIIMPL_H -#include "CreatureAI.h" +#define HEROIC(n,h) (HeroicMode ? h : n) -template -inline CreatureAI* -CreatureAIFactory::Create(void *data) const +template +inline +const T& RAND(const T& v1, const T& v2) { - Creature* creature = reinterpret_cast(data); - return (new REAL_AI(creature)); + return rand()%2 ? v1 : v2; } + +template +inline +const T& RAND(const T& v1, const T& v2, const T& v3) +{ + switch(rand()%3) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + } +} + +template +inline +const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4) +{ + switch(rand()%4) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + case 3: return v4; + } +} + +template +inline +const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) +{ + switch(rand()%4) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + case 3: return v4; + case 4: return v5; + } +} + +class EventMap : private std::map +{ + private: + uint32 m_time, m_phase; + public: + explicit EventMap() : m_phase(0), m_time(0) {} + + void Reset() { clear(); m_time = 0; m_phase = 0; } + + void Update(uint32 time) { m_time += time; } + + void SetPhase(uint32 phase) + { + if(phase && phase < 9) + m_phase = (1 << (phase + 24)); + } + + void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) + { + time += m_time; + if(gcd && gcd < 9) + eventId |= (1 << (gcd + 16)); + if(phase && phase < 9) + eventId |= (1 << (phase + 24)); + iterator itr = find(time); + while(itr != end()) + { + ++time; + itr = find(time); + } + insert(std::make_pair(time, eventId)); + } + + uint32 ExecuteEvent() + { + while(!empty()) + { + if(begin()->first > m_time) + return 0; + else if(m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase)) + erase(begin()); + else + { + uint32 eventId = (begin()->second & 0x0000FFFF); + erase(begin()); + return eventId; + } + } + return 0; + } + + void DelayEvents(uint32 time, uint32 gcd) + { + time += m_time; + gcd = (1 << (gcd + 16)); + for(iterator itr = begin(); itr != end();) + { + if(itr->first >= time) + break; + if(itr->second & gcd) + { + ScheduleEvent(time, itr->second); + erase(itr++); + } + else + ++itr; + } + } +}; + +enum AITarget +{ + AITARGET_SELF, + AITARGET_VICTIM, + AITARGET_ENEMY, + AITARGET_ALLY, + AITARGET_BUFF, + AITARGET_DEBUFF, +}; + +enum AICondition +{ + AICOND_AGGRO, + AICOND_COMBAT, + AICOND_DIE, +}; + +#define AI_DEFAULT_COOLDOWN 5000 + +struct AISpellInfoType +{ + AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {} + AITarget target; + AICondition condition; + uint32 cooldown; +}; + +extern AISpellInfoType *AISpellInfo; + #endif diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp index 6253c06b8bc..36f49d28521 100644 --- a/src/game/CreatureAIRegistry.cpp +++ b/src/game/CreatureAIRegistry.cpp @@ -28,11 +28,12 @@ #include "OutdoorPvPObjectiveAI.h" #include "CreatureEventAI.h" #include "RandomMovementGenerator.h" -#include "CreatureAIImpl.h" #include "MovementGeneratorImpl.h" #include "CreatureAIRegistry.h" #include "WaypointMovementGenerator.h" +#include "CreatureAIFactory.h" +#include "CreatureAIImpl.h" namespace AIRegistry { void Initialize() diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index a698d094e18..b270de289c7 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -19,7 +19,6 @@ */ #include "Creature.h" -#include "CreatureAIImpl.h" #include "CreatureAISelector.h" #include "NullCreatureAI.h" #include "Policies/SingletonImp.h" @@ -27,6 +26,7 @@ #include "ScriptCalls.h" #include "Pet.h" #include "TemporarySummon.h" +#include "CreatureAIFactory.h" INSTANTIATE_SINGLETON_1(CreatureAIRegistry); INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry); diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index 9332f4b8f0a..131d26e90f7 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -40,6 +40,8 @@ #include "Group.h" #include "InstanceData.h" #include "ProgressBar.h" +#include "Policies/Singleton.h" +#include "Policies/SingletonImp.h" INSTANTIATE_SINGLETON_1( InstanceSaveManager ); diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h index d5c12d8c9a0..f8a5d8480f0 100644 --- a/src/game/NullCreatureAI.h +++ b/src/game/NullCreatureAI.h @@ -22,6 +22,7 @@ #define TRINITY_NULLCREATUREAI_H #include "CreatureAI.h" +#include "CreatureAIImpl.h" class TRINITY_DLL_DECL PassiveAI : public CreatureAI { diff --git a/src/game/PossessedAI.cpp b/src/game/PossessedAI.cpp deleted file mode 100644 index 8fd2e5ca014..00000000000 --- a/src/game/PossessedAI.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2008-2009 Trinity - * - * Thanks to the original authors: MaNGOS - * - * 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 - */ - diff --git a/src/game/PossessedAI.h b/src/game/PossessedAI.h deleted file mode 100644 index bef7853246e..00000000000 --- a/src/game/PossessedAI.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2008-2009 Trinity - * - * Thanks to the original authors: MaNGOS - * - * 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 - */ - -#ifndef MANGOS_POSSESSEDAI_H -#define MANGOS_POSSESSEDAI_H - - -#endif diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp new file mode 100644 index 00000000000..4914bd36b7c --- /dev/null +++ b/src/game/UnitAI.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2009 Trinity + * + * 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 + */ + +#include "UnitAI.h" +#include "SpellAuras.h" + +void UnitAI::AttackStart(Unit *victim) +{ + if(!victim) + return; + + if(me->Attack(victim, true)) + { + //DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", me->GetName(), victim->GetGUIDLow()); + me->GetMotionMaster()->MoveChase(victim); + } +} + +void UnitAI::DoMeleeAttackIfReady() +{ + //Make sure our attack is ready and we aren't currently casting before checking distance + if (me->isAttackReady() && !me->hasUnitState(UNIT_STAT_CASTING)) + { + //If we are within range melee the target + if (me->IsWithinMeleeRange(me->getVictim())) + { + me->AttackerStateUpdate(me->getVictim()); + me->resetAttackTimer(); + } + } + if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK) && !me->hasUnitState(UNIT_STAT_CASTING)) + { + //If we are within range melee the target + if (me->IsWithinMeleeRange(me->getVictim())) + { + me->AttackerStateUpdate(me->getVictim(), OFF_ATTACK); + me->resetAttackTimer(OFF_ATTACK); + } + } +} + +//Enable PlayerAI when charmed +void PlayerAI::OnCharmed(bool apply) { me->IsAIEnabled = apply; } + +void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) +{ + Creature *charmer = (Creature*)me->GetCharmer(); + + //kill self if charm aura has infinite duration + if(charmer->IsInEvadeMode()) + { + Unit::AuraEffectList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM); + for(Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) + if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->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)) + AttackStart(charmer->SelectNearestTarget()); +} diff --git a/src/game/UnitAI.h b/src/game/UnitAI.h new file mode 100644 index 00000000000..04de74f480e --- /dev/null +++ b/src/game/UnitAI.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2009 Trinity + * + * 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 + */ + +#ifndef TRINITY_UNITAI_H +#define TRINITY_UNITAI_H + +#include "Platform/Define.h" + +class Unit; +class Player; + +class TRINITY_DLL_SPEC UnitAI +{ + protected: + Unit * const me; + public: + explicit UnitAI(Unit *u) : me(u) {} + virtual void AttackStart(Unit *); + virtual void UpdateAI(const uint32 diff) = 0; + + virtual void InitializeAI() { Reset(); } + + virtual void Reset() {}; + + // Called when unit is charmed + virtual void OnCharmed(bool apply) = 0; + + // Pass parameters between AI + virtual void DoAction(const int32 param) {} + + //Do melee swing of current victim if in rnage and ready and not casting + void DoMeleeAttackIfReady(); +}; + +class TRINITY_DLL_SPEC PlayerAI : public UnitAI +{ + protected: + Player* const me; + public: + explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {} + + void OnCharmed(bool apply); +}; + +class TRINITY_DLL_SPEC SimpleCharmedAI : public PlayerAI +{ + public: + void UpdateAI(const uint32 diff); +}; + +#endif diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj index 7cd964ca9a1..002b5e7fb2d 100644 --- a/win/VC80/game.vcproj +++ b/win/VC80/game.vcproj @@ -1069,14 +1069,6 @@ - - - - @@ -1137,50 +1129,6 @@ RelativePath="..\..\src\game\Creature.h" > - - - - - - - - - - - - - - - - - - - - - - @@ -1229,14 +1177,6 @@ RelativePath="..\..\src\game\GameObject.h" > - - - - @@ -1305,14 +1245,6 @@ RelativePath="..\..\src\game\MovementGenerator.h" > - - - - @@ -1341,14 +1273,6 @@ RelativePath="..\..\src\game\ObjectMgr.h" > - - - - @@ -1357,14 +1281,6 @@ RelativePath="..\..\src\game\Pet.h" > - - - - @@ -1381,14 +1297,6 @@ RelativePath="..\..\src\game\PointMovementGenerator.h" > - - - - @@ -1397,14 +1305,6 @@ RelativePath="..\..\src\game\RandomMovementGenerator.h" > - - - - @@ -1465,14 +1365,6 @@ RelativePath="..\..\src\game\Totem.h" > - - - - @@ -1682,6 +1574,122 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index fcd4f3c3ddd..15fc293a02c 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -1,11 +1,12 @@ @@ -185,7 +183,7 @@ /> @@ -1069,14 +1070,6 @@ - - - - @@ -1137,50 +1130,6 @@ RelativePath="..\..\src\game\Creature.h" > - - - - - - - - - - - - - - - - - - - - - - @@ -1229,14 +1178,6 @@ RelativePath="..\..\src\game\GameObject.h" > - - - - @@ -1305,14 +1246,6 @@ RelativePath="..\..\src\game\MovementGenerator.h" > - - - - @@ -1341,14 +1274,6 @@ RelativePath="..\..\src\game\ObjectMgr.h" > - - - - @@ -1357,14 +1282,6 @@ RelativePath="..\..\src\game\Pet.h" > - - - - @@ -1381,14 +1298,6 @@ RelativePath="..\..\src\game\PointMovementGenerator.h" > - - - - @@ -1397,14 +1306,6 @@ RelativePath="..\..\src\game\RandomMovementGenerator.h" > - - - - @@ -1465,14 +1366,6 @@ RelativePath="..\..\src\game\Totem.h" > - - - - @@ -1682,6 +1575,122 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1695,7 +1704,7 @@ /> Date: Sun, 10 May 2009 16:31:43 -0500 Subject: *Fix build. --HG-- branch : trunk --- src/game/CreatureAI.cpp | 20 +++++++++++++++++++- src/game/CreatureAI.h | 6 ++++-- src/game/CreatureAIImpl.h | 5 +++-- src/game/CreatureAIRegistry.cpp | 2 -- 4 files changed, 26 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 2390b359731..011ffab22e5 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -33,7 +33,7 @@ void CreatureAI::OnCharmed(bool apply) me->IsAIEnabled = false; } -AISpellInfoType *AISpellInfo; +AISpellInfoType * CreatureAI::AISpellInfo; void CreatureAI::DoZoneInCombat(Creature* creature) { @@ -257,6 +257,24 @@ void CreatureAI::SelectTargetList(std::list &targetList, uint32 num, Sele } } +void CreatureAI::FillAISpellInfo() +{ + AISpellInfo = new AISpellInfoType[GetSpellStore()->GetNumRows()]; + + const SpellEntry * spellInfo; + + for(uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i) + { + spellInfo = GetSpellStore()->LookupEntry(i); + if (!spellInfo) + continue; + + for(uint32 j = 0; j < 3; ++j) + { + } + } +} + /*void CreatureAI::AttackedBy( Unit* attacker ) { if(!m_creature->getVictim()) diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index 6df7dcfbe95..ca13275dea1 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -21,8 +21,6 @@ #ifndef TRINITY_CREATUREAI_H #define TRINITY_CREATUREAI_H -#include "Common.h" -#include "Platform/Define.h" #include "UnitAI.h" class WorldObject; @@ -30,6 +28,7 @@ class Unit; class Creature; class Player; struct SpellEntry; +struct AISpellInfoType; #define TIME_INTERVAL_LOOK 5000 #define VISIBILITY_RANGE 10000 @@ -165,6 +164,9 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI Unit* SelectTarget(SelectAggroTarget target, uint32 position = 0, float dist = 0, bool playerOnly = false, int32 aura = 0); void SelectTargetList(std::list &targetList, uint32 num, SelectAggroTarget target, float dist = 0, bool playerOnly = false, int32 aura = 0); + + static AISpellInfoType *AISpellInfo; + static void FillAISpellInfo(); }; enum Permitions diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h index 823f4cbcca6..7edebb709fd 100644 --- a/src/game/CreatureAIImpl.h +++ b/src/game/CreatureAIImpl.h @@ -20,6 +20,9 @@ #ifndef CREATUREAIIMPL_H #define CREATUREAIIMPL_H +#include "Common.h" +#include "Platform/Define.h" + #define HEROIC(n,h) (HeroicMode ? h : n) template @@ -168,7 +171,5 @@ struct AISpellInfoType uint32 cooldown; }; -extern AISpellInfoType *AISpellInfo; - #endif diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp index 36f49d28521..fc7130b0913 100644 --- a/src/game/CreatureAIRegistry.cpp +++ b/src/game/CreatureAIRegistry.cpp @@ -23,7 +23,6 @@ #include "AggressorAI.h" #include "GuardAI.h" #include "PetAI.h" -#include "PossessedAI.h" #include "TotemAI.h" #include "OutdoorPvPObjectiveAI.h" #include "CreatureEventAI.h" @@ -47,7 +46,6 @@ namespace AIRegistry (new CreatureAIFactory("PetAI"))->RegisterSelf(); (new CreatureAIFactory("TotemAI"))->RegisterSelf(); (new CreatureAIFactory("OutdoorPvPObjectiveAI"))->RegisterSelf(); - (new CreatureAIFactory("PossessedAI"))->RegisterSelf(); (new CreatureAIFactory("EventAI"))->RegisterSelf(); (new MovementGeneratorFactory >(RANDOM_MOTION_TYPE))->RegisterSelf(); -- cgit v1.2.3 From 50bf49bd81beef68192478c861af28732f1fbdf2 Mon Sep 17 00:00:00 2001 From: QAston Date: Mon, 11 May 2009 00:05:36 +0200 Subject: Allow class specific periodic dummy and dummy auras to always stack --HG-- branch : trunk --- src/game/SpellMgr.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 945255f883a..a23f32d1a52 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1472,6 +1472,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool //if spells have exactly the same effect they cannot stack for(uint32 i = 0; i < 3; ++i) if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i] + // Overkill and master of subtlety need this + || spellInfo_1->EffectApplyAuraName[i] == SPELL_AURA_DUMMY + || spellInfo_1->EffectApplyAuraName[i] == SPELL_AURA_PERIODIC_DUMMY + || spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i] || spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i]) // paladin resist aura return false; // need itemtype check? need an example to add that check -- cgit v1.2.3 From 904300b4c2f0c708bc98812ec2a0be04249a81d4 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 22:47:03 -0500 Subject: *Use better summon positions for summon spells with more than one summons. (Still a temp fix) --HG-- branch : trunk --- src/game/Spell.h | 2 +- src/game/SpellEffects.cpp | 30 ++++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/game/Spell.h b/src/game/Spell.h index 642c40de474..e2ce4668952 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -609,7 +609,7 @@ class Spell void SpellDamageWeaponDmg(uint32 i); void SpellDamageHeal(uint32 i); - void GetSummonPosition(float &x, float &y, float &z, float radius = 0.0f, uint32 count = 0); + void GetSummonPosition(uint32 i, float &x, float &y, float &z, float radius = 0.0f, uint32 count = 0); void SummonGuardian (uint32 entry, SummonPropertiesEntry const *properties); SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index eeeeb478ca1..a3401a77e21 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3190,7 +3190,7 @@ void Spell::EffectSummonType(uint32 i) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); float x, y, z; - GetSummonPosition(x, y, z); + GetSummonPosition(i, x, y, z); /*//totem must be at same Z in case swimming caster and etc. if( fabs( z - m_caster->GetPositionZ() ) > 5 ) @@ -3291,7 +3291,7 @@ void Spell::EffectSummonType(uint32 i) for(int32 count = 0; count < amount; ++count) { float px, py, pz; - GetSummonPosition(px, py, pz, radius, count); + GetSummonPosition(i, px, py, pz, radius, count); TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; @@ -6212,7 +6212,7 @@ void Spell::EffectSummonDemon(uint32 i) for(int32 count = 0; count < amount; ++count) { float px, py, pz; - GetSummonPosition(px, py, pz, radius, count); + GetSummonPosition(i, px, py, pz, radius, count); int32 duration = GetSpellDuration(m_spellInfo); @@ -6412,7 +6412,7 @@ void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties for(int32 count = 0; count < amount; ++count) { float px, py, pz; - GetSummonPosition(px, py, pz, radius, count); + GetSummonPosition(0, px, py, pz, radius, count); TempSummon *summon = map->SummonCreature(entry, px, py, pz, m_caster->GetOrientation(), properties, duration, caster); if(!summon) @@ -6427,7 +6427,7 @@ void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties } } -void Spell::GetSummonPosition(float &x, float &y, float &z, float radius, uint32 count) +void Spell::GetSummonPosition(uint32 i, float &x, float &y, float &z, float radius, uint32 count) { if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) { @@ -6440,7 +6440,25 @@ void Spell::GetSummonPosition(float &x, float &y, float &z, float radius, uint32 } // Summon in random point all other units if location present else - m_caster->GetRandomPoint(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,radius,x,y,z); + { + //This is a workaround. Do not have time to write much about it + switch(m_spellInfo->EffectImplicitTargetA[i]) + { + case TARGET_MINION: + case TARGET_DEST_CASTER_RANDOM: + m_caster->GetGroundPointAroundUnit(x, y, z, radius * rand_norm(), rand_norm()*2*M_PI); + break; + case TARGET_DEST_DEST_RANDOM: + case TARGET_DEST_TARGET_RANDOM: + m_caster->GetRandomPoint(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,radius,x,y,z); + break; + default: + x = m_targets.m_destX; + y = m_targets.m_destY; + z = m_targets.m_destZ; + break; + } + } } // Summon if dest location not present near caster else -- cgit v1.2.3 From 82f886e3c1daa6ae9049bb0c0c0c00219e9735ba Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 22:48:22 -0500 Subject: *Update AI scripts. Use better default AI. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 32 +++++++ src/bindings/scripts/include/sc_creature.h | 27 ++++++ src/game/AggressorAI.cpp | 125 +++++++++++++-------------- src/game/AggressorAI.h | 34 ++++---- src/game/CreatureAI.cpp | 38 +++++++- src/game/CreatureAIRegistry.cpp | 1 + src/game/CreatureAISelector.cpp | 12 +++ src/game/SpellMgr.cpp | 3 + src/game/Unit.cpp | 16 ++-- src/game/UnitAI.cpp | 7 +- 10 files changed, 205 insertions(+), 90 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 42ee15074ed..e5a6eb958e0 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -55,6 +55,7 @@ void SummonList::DespawnAll() else { erase(begin()); + summon->SetVisibility(VISIBILITY_OFF); summon->setDeathState(JUST_DIED); summon->RemoveCorpse(); } @@ -634,6 +635,37 @@ void Scripted_NoMovementAI::AttackStart(Unit* who) } } +void BossAI::_Reset() +{ + events.Reset(); + summons.DespawnAll(); + instance->SetBossState(bossId, NOT_STARTED); +} + +void BossAI::_JustDied() +{ + events.Reset(); + summons.DespawnAll(); + instance->SetBossState(bossId, DONE); +} + +void BossAI::_EnterCombat() +{ + DoZoneInCombat(); + instance->SetBossState(bossId, IN_PROGRESS); +} + +void BossAI::JustSummoned(Creature *summon) +{ + summons.Summon(summon); + DoZoneInCombat(summon); +} + +void BossAI::SummonedCreatureDespawn(Creature *summon) +{ + summons.Despawn(summon); +} + #define GOBJECT(x) (const_cast(GetGameObjectInfo(x))) void LoadOverridenSQLData() diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 8336df545b6..26bf5fb400b 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -12,6 +12,8 @@ #include "CreatureAI.h" #include "CreatureAIImpl.h" +class ScriptedInstance; + class SummonList : private std::list { public: @@ -216,5 +218,30 @@ struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI void UpdateAI(const uint32) {} }; +struct TRINITY_DLL_DECL BossAI : public ScriptedAI +{ + BossAI(Creature *c, uint32 id) : ScriptedAI(c), bossId(id) + , summons(me), instance((ScriptedInstance*)c->GetInstanceData()) + {} + + uint32 bossId; + EventMap events; + SummonList summons; + ScriptedInstance *instance; + + void JustSummoned(Creature *summon); + void SummonedCreatureDespawn(Creature *summon); + + void UpdateAI(const uint32 diff) = 0; + + void _Reset(); + void _EnterCombat(); + void _JustDied(); + + void Reset() { _Reset(); } + void EnterCombat(Unit *who) { _EnterCombat(); } + void JustDied(Unit *killer) { _JustDied(); } +}; + #endif diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index a637e7e40f0..286138fc991 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -19,16 +19,9 @@ */ #include "AggressorAI.h" -#include "Errors.h" -#include "Creature.h" -#include "ObjectAccessor.h" -#include "VMapFactory.h" -#include "World.h" +#include "SpellMgr.h" -#include - -int -AggressorAI::Permissible(const Creature *creature) +int AggressorAI::Permissible(const Creature *creature) { // have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight if( !creature->isCivilian() && !creature->IsNeutralToAll() ) @@ -37,79 +30,83 @@ AggressorAI::Permissible(const Creature *creature) return PERMIT_BASE_NO; } -AggressorAI::AggressorAI(Creature *c) : CreatureAI(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) +void AggressorAI::UpdateAI(const uint32 /*diff*/) { + if(!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); } -void AggressorAI::EnterEvadeMode() +int SpellAI::Permissible(const Creature *creature) { - if( !m_creature->isAlive() ) - { - DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow()); - i_victimGuid = 0; - m_creature->CombatStop(true); - m_creature->DeleteThreatList(); - return; - } + return PERMIT_BASE_NO; +} - Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid ); +void SpellAI::InitializeAI() +{ + for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + if(me->m_spells[i] && GetSpellStore()->LookupEntry(me->m_spells[i])) + spells.push_back(me->m_spells[i]); +} - if( !victim ) - { - DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow()); - } - else if( !victim->isAlive() ) - { - DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", m_creature->GetGUIDLow()); - } - else if( victim->HasStealthAura() ) - { - DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow()); - } - else if( victim->isInFlight() ) - { - DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow()); - } - else - { - DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", m_creature->GetGUIDLow()); - //i_state = STATE_LOOK_AT_VICTIM; - //i_tracker.Reset(TIME_INTERVAL_LOOK); - } +void SpellAI::Reset() +{ + events.Reset(); +} - if(!m_creature->GetCharmerOrOwner()) - { - m_creature->RemoveAllAuras(); +void SpellAI::JustDied(Unit *killer) +{ + for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) + if(AISpellInfo[*i].condition == AICOND_DIE) + me->CastSpell(killer, *i, true); +} - // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead - if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE ) - m_creature->GetMotionMaster()->MoveTargetedHome(); +void SpellAI::EnterCombat(Unit *who) +{ + for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) + { + if(AISpellInfo[*i].condition == AICOND_AGGRO) + me->CastSpell(who, *i, true); + else if(AISpellInfo[*i].condition == AICOND_COMBAT) + events.ScheduleEvent(*i, AISpellInfo[*i].cooldown + rand()%AISpellInfo[*i].cooldown); } - else if (m_creature->GetOwner() && m_creature->GetOwner()->isAlive()) - m_creature->GetMotionMaster()->MoveFollow(m_creature->GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); - - m_creature->DeleteThreatList(); - i_victimGuid = 0; - m_creature->CombatStop(true); - m_creature->SetLootRecipient(NULL); } -void -AggressorAI::UpdateAI(const uint32 /*diff*/) +void SpellAI::UpdateAI(const uint32 diff) { - // update i_victimGuid if m_creature->getVictim() !=0 and changed if(!UpdateVictim()) return; - i_victimGuid = m_creature->getVictim()->GetGUID(); + events.Update(diff); - if( m_creature->isAttackReady() ) + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + + if(uint32 spellId = events.ExecuteEvent()) { - if( m_creature->IsWithinMeleeRange(m_creature->getVictim())) + Unit *target = NULL; + //sLog.outError("aggre %u %u", spellId, (uint32)AISpellInfo[spellId].target); + switch(AISpellInfo[spellId].target) { - m_creature->AttackerStateUpdate(m_creature->getVictim()); - m_creature->resetAttackTimer(); + default: + case AITARGET_SELF: target = me; break; + case AITARGET_VICTIM: target = me->getVictim(); break; + case AITARGET_ENEMY: target = SelectTarget(SELECT_TARGET_RANDOM); break; + case AITARGET_ALLY: target = me; break; + case AITARGET_BUFF: target = me; break; + case AITARGET_DEBUFF: + { + const SpellEntry * spellInfo = GetSpellStore()->LookupEntry(spellId); + bool playerOnly = spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY; + float range = GetSpellMaxRange(spellInfo, false); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, range, playerOnly, -(int32)spellId); + break; + } } + me->CastSpell(target, spellId, false); + events.ScheduleEvent(spellId, AISpellInfo[spellId].cooldown + rand()%AISpellInfo[spellId].cooldown); } + else + DoMeleeAttackIfReady(); } - diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h index 983498716e6..94a6b0b3bf1 100644 --- a/src/game/AggressorAI.h +++ b/src/game/AggressorAI.h @@ -22,31 +22,35 @@ #define TRINITY_AGGRESSORAI_H #include "CreatureAI.h" -#include "Timer.h" +#include "CreatureAIImpl.h" class Creature; class TRINITY_DLL_DECL AggressorAI : public CreatureAI { - enum AggressorState - { - STATE_NORMAL = 1, - STATE_LOOK_AT_VICTIM = 2 - }; - public: - - explicit AggressorAI(Creature *c); - - void EnterEvadeMode(); + explicit AggressorAI(Creature *c) : CreatureAI(c) {} void UpdateAI(const uint32); static int Permissible(const Creature *); +}; + +typedef std::vector SpellVct; +class TRINITY_DLL_DECL SpellAI : public CreatureAI +{ + public: + explicit SpellAI(Creature *c) : CreatureAI(c) {} + + void InitializeAI(); + void Reset(); + void EnterCombat(Unit* who); + void JustDied(Unit *killer); + void UpdateAI(const uint32 diff); + static int Permissible(const Creature *); private: - uint64 i_victimGuid; - AggressorState i_state; - TimeTracker i_tracker; + EventMap events; + SpellVct spells; }; -#endif +#endif diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 011ffab22e5..123fa1182a1 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -21,9 +21,8 @@ #include "CreatureAI.h" #include "CreatureAIImpl.h" #include "Creature.h" -#include "Player.h" -#include "Pet.h" #include "World.h" +#include "SpellMgr.h" //Disable CreatureAI when charmed void CreatureAI::OnCharmed(bool apply) @@ -261,16 +260,47 @@ void CreatureAI::FillAISpellInfo() { AISpellInfo = new AISpellInfoType[GetSpellStore()->GetNumRows()]; + AISpellInfoType *AIInfo = AISpellInfo; const SpellEntry * spellInfo; - for(uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i) + for(uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i, ++AIInfo) { spellInfo = GetSpellStore()->LookupEntry(i); - if (!spellInfo) + if(!spellInfo) continue; + if(spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_DEAD) + AIInfo->condition = AICOND_DIE; + else if(IsPassiveSpell(i) || GetSpellDuration(spellInfo) == -1) + AIInfo->condition = AICOND_AGGRO; + else + AIInfo->condition = AICOND_COMBAT; + + if(AIInfo->cooldown < spellInfo->RecoveryTime) + AIInfo->cooldown = spellInfo->RecoveryTime; + for(uint32 j = 0; j < 3; ++j) { + if(spellInfo->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY + || spellInfo->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY) + { + if(AIInfo->target < AITARGET_VICTIM) + AIInfo->target = AITARGET_VICTIM; + } + + if(spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AURA) + { + if(spellInfo->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY) + { + if(AIInfo->target < AITARGET_DEBUFF) + AIInfo->target = AITARGET_DEBUFF; + } + else if(IsPositiveSpell(i)) + { + if(AIInfo->target < AITARGET_BUFF) + AIInfo->target = AITARGET_BUFF; + } + } } } } diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp index fc7130b0913..162ebd9b47c 100644 --- a/src/game/CreatureAIRegistry.cpp +++ b/src/game/CreatureAIRegistry.cpp @@ -46,6 +46,7 @@ namespace AIRegistry (new CreatureAIFactory("PetAI"))->RegisterSelf(); (new CreatureAIFactory("TotemAI"))->RegisterSelf(); (new CreatureAIFactory("OutdoorPvPObjectiveAI"))->RegisterSelf(); + (new CreatureAIFactory("SpellAI"))->RegisterSelf(); (new CreatureAIFactory("EventAI"))->RegisterSelf(); (new MovementGeneratorFactory >(RANDOM_MOTION_TYPE))->RegisterSelf(); diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index b270de289c7..bac4f3a4973 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -69,6 +69,18 @@ namespace FactorySelector ai_factory = ai_registry.GetRegistryItem("CritterAI"); } + if(!ai_factory) + { + for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + { + if(creature->m_spells[i]) + { + ai_factory = ai_registry.GetRegistryItem("SpellAI"); + break; + } + } + } + // select by permit check if(!ai_factory) { diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index a23f32d1a52..9b1cb798849 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -27,6 +27,7 @@ #include "Chat.h" #include "Spell.h" #include "BattleGroundMgr.h" +#include "CreatureAI.h" bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS]; @@ -2520,6 +2521,8 @@ void SpellMgr::LoadSpellCustomAttr() SummonPropertiesEntry *properties = const_cast(sSummonPropertiesStore.LookupEntry(121)); properties->Type = SUMMON_TYPE_TOTEM; + + CreatureAI::FillAISpellInfo(); } void SpellMgr::LoadSpellLinked() diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 3f09eec9351..28d2fbd619b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -11607,11 +11607,14 @@ void CharmInfo::InitPossessCreateSpells() { for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) { - uint32 spellid = ((Creature*)m_unit)->m_spells[i]; - if(IsPassiveSpell(spellid)) - m_unit->CastSpell(m_unit, spellid, true); + uint32 spellId = ((Creature*)m_unit)->m_spells[i]; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(spellInfo && spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_DEAD) + spellId = 0; + if(IsPassiveSpell(spellId)) + m_unit->CastSpell(m_unit, spellId, true); else - AddSpellToAB(0, spellid, ACT_DISABLED); + AddSpellToAB(0, spellId, ACT_DISABLED); } } } @@ -11629,6 +11632,10 @@ void CharmInfo::InitCharmCreateSpells() for(uint32 x = 0; x < MAX_SPELL_CHARM; ++x) { uint32 spellId = ((Creature*)m_unit)->m_spells[x]; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(spellInfo && spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_DEAD) + spellId = 0; + m_charmspells[x].spellId = spellId; if(!spellId) @@ -11643,7 +11650,6 @@ void CharmInfo::InitCharmCreateSpells() { ActiveStates newstate; bool onlyselfcast = true; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); if(!spellInfo) onlyselfcast = false; for(uint32 i = 0;i<3 && onlyselfcast;++i) //non existent spell will not make any problems as onlyselfcast would be false -> break right away diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp index 4914bd36b7c..c991c75603d 100644 --- a/src/game/UnitAI.cpp +++ b/src/game/UnitAI.cpp @@ -35,8 +35,11 @@ void UnitAI::AttackStart(Unit *victim) void UnitAI::DoMeleeAttackIfReady() { + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + //Make sure our attack is ready and we aren't currently casting before checking distance - if (me->isAttackReady() && !me->hasUnitState(UNIT_STAT_CASTING)) + if (me->isAttackReady()) { //If we are within range melee the target if (me->IsWithinMeleeRange(me->getVictim())) @@ -45,7 +48,7 @@ void UnitAI::DoMeleeAttackIfReady() me->resetAttackTimer(); } } - if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK) && !me->hasUnitState(UNIT_STAT_CASTING)) + if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK)) { //If we are within range melee the target if (me->IsWithinMeleeRange(me->getVictim())) -- cgit v1.2.3 From 4fef015112f7bc5fd114c116a384515859b95e9d Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 22:50:15 -0500 Subject: *Update Naxx scripts. --HG-- branch : trunk --- sql/updates/3233_world_scripts_naxx.sql | 20 ++- .../scripts/zone/naxxramas/boss_anubrekhan.cpp | 38 +----- .../scripts/zone/naxxramas/boss_grobbulus.cpp | 29 +--- .../scripts/scripts/zone/naxxramas/boss_heigan.cpp | 29 +--- .../scripts/scripts/zone/naxxramas/boss_noth.cpp | 32 +---- .../scripts/zone/naxxramas/boss_patchwerk.cpp | 20 +-- .../scripts/zone/naxxramas/boss_razuvious.cpp | 150 ++++++++------------- .../scripts/zone/naxxramas/boss_sapphiron.cpp | 26 ++-- .../scripts/scripts/zone/naxxramas/def_naxxramas.h | 16 ++- .../scripts/zone/naxxramas/instance_naxxramas.cpp | 28 ++-- 10 files changed, 149 insertions(+), 239 deletions(-) (limited to 'src') diff --git a/sql/updates/3233_world_scripts_naxx.sql b/sql/updates/3233_world_scripts_naxx.sql index 7272b328f8e..d84a4462537 100644 --- a/sql/updates/3233_world_scripts_naxx.sql +++ b/sql/updates/3233_world_scripts_naxx.sql @@ -30,5 +30,21 @@ DELETE FROM `spell_script_target` WHERE `entry` IN (55479); INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES (55479, 1, 16803); # Force Obedience - Death Knight Understudy -# Death Knight Understudy -UPDATE creature_template SET spell1=0, spell2=0, spell3=0, spell4=61696, spell5=29060, spell6=29061 WHERE entry IN (16803,29941); +INSERT INTO creature_template (entry, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8) VALUES +(16803, 0, 0, 0, 61696, 29060, 29061, 0, 0), # Death Knight Understudy +(29941, 0, 0, 0, 61696, 29060, 29061, 0, 0), # Death Knight Understudy (H) +(16573, 15284, 28991, 28969, 34970, 28864, 0, 0, 0), # Crypt Guard +(29256, 15284, 28991, 56098, 34970, 28864, 0, 0, 0), # Crypt Guard (H) +(16984, 15496, 0, 0, 0, 0, 0, 0, 0), # Plagued Warrior +(29632, 15496, 0, 0, 0, 0, 0, 0, 0), # Plagued Warrior (H) +(16290, 28156, 0, 0, 0, 0, 0, 0, 0), # Fallout Slime +(29388, 54367, 0, 0, 0, 0, 0, 0, 0) # Fallout Slime (H) +ON DUPLICATE KEY UPDATE +spell1 = VALUES(spell1), +spell2 = VALUES(spell2), +spell3 = VALUES(spell3), +spell4 = VALUES(spell4), +spell5 = VALUES(spell5), +spell6 = VALUES(spell6), +spell7 = VALUES(spell7), +spell8 = VALUES(spell8); diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp index 0a0fb17cce4..c675c8d7c27 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_anubrekhan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2008 - 2009 Trinity * 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 @@ -14,14 +14,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Anubrekhan -SD%Complete: 100 -SDComment: -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" +#include "def_naxxramas.h" #define SAY_GREET RAND(-1533000,-1533004,-1533005,-1533006,-1533007) #define SAY_AGGRO RAND(-1533001,-1533002,-1533003) @@ -31,46 +25,29 @@ EndScriptData */ #define SPELL_LOCUSTSWARM HEROIC(28785,54021) #define SPELL_SELF_SPAWN_5 29105 //This spawns 5 corpse scarabs ontop of us (most likely the player casts this on death) -#define SPELL_SELF_SPAWN_10 28864 //This is used by the crypt guards when they die #define EVENT_IMPALE 1 #define EVENT_LOCUST 2 #define MOB_CRYPT_GUARD 16573 -struct TRINITY_DLL_DECL boss_anubrekhanAI : public ScriptedAI +struct TRINITY_DLL_DECL boss_anubrekhanAI : public BossAI { - boss_anubrekhanAI(Creature *c) : ScriptedAI(c), summons(me) {} + boss_anubrekhanAI(Creature *c) : BossAI(c, BOSS_ANUBREKHAN) {} bool HasTaunted; - EventMap events; - SummonList summons; void Prepare() { HasTaunted = false; - DoSpawnCreature(MOB_CRYPT_GUARD, 0, 10, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000); + DoSpawnCreature(MOB_CRYPT_GUARD, 0, 10, 0, me->GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000); if(HeroicMode) - DoSpawnCreature(MOB_CRYPT_GUARD, 0, -10, 0, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000); + DoSpawnCreature(MOB_CRYPT_GUARD, 0, -10, 0, me->GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000); } void InitializeAI() { Prepare(); } void JustReachedHome() { Prepare(); } - void Reset() - { - events.Reset(); - summons.DespawnAll(); - } - - void JustSummoned(Creature *summon) - { - summons.Summon(summon); - DoZoneInCombat(summon); - } - - void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);} - void KilledUnit(Unit* victim) { //Force the player to spawn corpse scarabs via spell @@ -82,9 +59,8 @@ struct TRINITY_DLL_DECL boss_anubrekhanAI : public ScriptedAI void EnterCombat(Unit *who) { + _EnterCombat(); DoScriptText(SAY_AGGRO, me); - DoZoneInCombat(); - events.ScheduleEvent(EVENT_IMPALE, 15000, 1); events.ScheduleEvent(EVENT_LOCUST, 80000 + rand()%40000, 1); } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_grobbulus.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_grobbulus.cpp index f18cd81064a..45f54611ae3 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_grobbulus.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_grobbulus.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2008 - 2009 Trinity * 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 @@ -14,20 +14,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Grobbulus -SD%Complete: 0 -SDComment: Place holder -SDCategory: Naxxramas -EndScriptData */ - -/*Poison Cloud 26590 -Slime Spray 28157 -Fallout slime 28218 -Mutating Injection 28169 -Enrages 26527*/ - #include "precompiled.h" +#include "def_naxxramas.h" #define SPELL_BOMBARD_SLIME 28280 @@ -43,20 +31,13 @@ Enrages 26527*/ #define MOB_FALLOUT_SLIME 16290 -struct TRINITY_DLL_DECL boss_grobbulusAI : public ScriptedAI +struct TRINITY_DLL_DECL boss_grobbulusAI : public BossAI { - boss_grobbulusAI(Creature *c) : ScriptedAI(c) {} - - EventMap events; - - void Reset() - { - events.Reset(); - } + boss_grobbulusAI(Creature *c) : BossAI(c, BOSS_GROBBULUS) {} void EnterCombat(Unit *who) { - DoZoneInCombat(); + _EnterCombat(); events.ScheduleEvent(EVENT_CLOUD, 15000); events.ScheduleEvent(EVENT_INJECT, 20000); events.ScheduleEvent(EVENT_SPRAY, 15000+rand()%15000); //not sure diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_heigan.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_heigan.cpp index 9207b2c09a2..0302a93c488 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_heigan.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_heigan.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2008 - 2009 Trinity * 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 @@ -14,13 +14,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Heigan -SD%Complete: 0 -SDComment: Place Holder -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" #include "def_naxxramas.h" @@ -50,25 +43,14 @@ enum Phases //Spell by eye stalks #define SPELL_MIND_FLAY 26143 -struct TRINITY_DLL_DECL boss_heiganAI : public ScriptedAI +struct TRINITY_DLL_DECL boss_heiganAI : public BossAI { - boss_heiganAI(Creature *c) : ScriptedAI(c) - { - instance = ((ScriptedInstance*)c->GetInstanceData()); - } + boss_heiganAI(Creature *c) : BossAI(c, BOSS_HEIGAN) {} - EventMap events; - ScriptedInstance *instance; uint32 eruptSection; bool eruptDirection; Phases phase; - void Reset() - { - events.Reset(); - instance->SetBossState(BOSS_HEIGAN, NOT_STARTED); - } - void KilledUnit(Unit* Victim) { if(!(rand()%5)) @@ -77,16 +59,15 @@ struct TRINITY_DLL_DECL boss_heiganAI : public ScriptedAI void JustDied(Unit* Killer) { + _JustDied(); DoScriptText(SAY_DEATH, me); - instance->SetBossState(BOSS_HEIGAN, DONE); } void EnterCombat(Unit *who) { + _EnterCombat(); DoScriptText(SAY_AGGRO, me); - DoZoneInCombat(); EnterPhase(PHASE_FIGHT); - instance->SetBossState(BOSS_HEIGAN, IN_PROGRESS); } void EnterPhase(Phases newPhase) diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp index 22796094557..1f7b1a55daa 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2008 - 2009 Trinity * 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 @@ -14,13 +14,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Noth -SD%Complete: 40 -SDComment: Missing Balcony stage -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" #include "def_naxxramas.h" @@ -68,33 +61,25 @@ enum Events EVENT_GROUND, }; -struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI +struct TRINITY_DLL_DECL boss_nothAI : public BossAI { - boss_nothAI(Creature *c) : ScriptedAI(c), summons(me) - { - instance = ((ScriptedInstance*)c->GetInstanceData()); - } + boss_nothAI(Creature *c) : BossAI(c, BOSS_NOTH) {} - EventMap events; - SummonList summons; - ScriptedInstance *instance; uint32 waveCount, balconyCount; void Reset() { - events.Reset(); - summons.DespawnAll(); + _Reset(); me->setActive(false); - instance->SetBossState(BOSS_NOTH, NOT_STARTED); } void EnterCombat(Unit *who) { + _EnterCombat(); DoScriptText(SAY_AGGRO, me); me->setActive(true); balconyCount = 0; EnterPhaseGround(); - instance->SetBossState(BOSS_NOTH, IN_PROGRESS); } void EnterPhaseGround() @@ -104,7 +89,7 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI EnterEvadeMode(); else { - events.ScheduleEvent(EVENT_BALCONY, 11000); + events.ScheduleEvent(EVENT_BALCONY, 110000); events.ScheduleEvent(EVENT_CURSE, 20000+rand()%10000); events.ScheduleEvent(EVENT_WARRIOR, 30000); if(HeroicMode) @@ -125,13 +110,10 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI summon->AI()->DoZoneInCombat(); } - void SummonedCreatureDespawn(Creature *summon) { summons.Despawn(summon); } - void JustDied(Unit* Killer) { - summons.DespawnAll(); + _JustDied(); DoScriptText(SAY_DEATH, me); - instance->SetBossState(BOSS_NOTH, DONE); } void SummonUndead(uint32 entry, uint32 num) diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp index 99f8741c897..a05685264d6 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2008 - 2009 Trinity * 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 @@ -14,14 +14,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Patchwerk -SD%Complete: 80 -SDComment: Some issues with hateful strike inturrupting the melee swing timer. -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" +#include "def_naxxramas.h" #define SAY_AGGRO RAND(-1533017,-1533018) #define SAY_SLAY -1533019 @@ -39,16 +33,15 @@ EndScriptData */ #define EVENT_HATEFUL 2 #define EVENT_SLIME 3 -struct TRINITY_DLL_DECL boss_patchwerkAI : public ScriptedAI +struct TRINITY_DLL_DECL boss_patchwerkAI : public BossAI { - boss_patchwerkAI(Creature *c) : ScriptedAI(c) {} + boss_patchwerkAI(Creature *c) : BossAI(c, BOSS_PATCHWERK) {} bool Enraged; - EventMap events; void Reset() { - events.Reset(); + _Reset(); Enraged = false; } @@ -60,13 +53,14 @@ struct TRINITY_DLL_DECL boss_patchwerkAI : public ScriptedAI void JustDied(Unit* Killer) { + _JustDied(); DoScriptText(SAY_DEATH, me); } void EnterCombat(Unit *who) { + _EnterCombat(); DoScriptText(SAY_AGGRO, me); - DoZoneInCombat(); events.ScheduleEvent(EVENT_HATEFUL, 1200); events.ScheduleEvent(EVENT_BERSERK, 360000); } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp index 64147eaea8a..120220172cd 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp @@ -1,4 +1,6 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* + * Copyright (C) 2008 - 2009 Trinity + * * 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 @@ -14,14 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Razuvious -SD%Complete: 50 -SDComment: Missing adds and event is impossible without Mind Control -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" +#include "def_naxxramas.h" //Razuvious - NO TEXT sound only //8852 aggro01 - Hah hah, I'm just getting warmed up! @@ -37,121 +33,86 @@ EndScriptData */ //8860 death - An honorable... death... //8947 - Aggro Mixed? - ? -#define SOUND_AGGRO1 8852 -#define SOUND_AGGRO2 8853 -#define SOUND_AGGRO3 8854 -#define SOUND_SLAY1 8861 -#define SOUND_SLAY2 8863 -#define SOUND_COMMND1 8855 -#define SOUND_COMMND2 8856 -#define SOUND_COMMND3 8858 -#define SOUND_COMMND4 8859 -#define SOUND_COMMND5 8861 +#define SOUND_AGGRO RAND(8852,8853,8854) +#define SOUND_SLAY RAND(8861,8863) +#define SOUND_COMMND RAND(8855,8856,8858,8859,8861) #define SOUND_DEATH 8860 #define SOUND_AGGROMIX 8847 -#define SPELL_UNBALANCINGSTRIKE 26613 -#define SPELL_DISRUPTINGSHOUT 29107 +#define SPELL_UNBALANCING_STRIKE 26613 +#define SPELL_DISRUPTING_SHOUT HEROIC(29107,55543) +#define SPELL_JAGGED_KNIFE 55550 +#define SPELL_HOPELESS 29105 -struct TRINITY_DLL_DECL boss_razuviousAI : public ScriptedAI +enum Events { - boss_razuviousAI(Creature *c) : ScriptedAI(c) {} - - uint32 UnbalancingStrike_Timer; - uint32 DisruptingShout_Timer; - uint32 CommandSound_Timer; + EVENT_STRIKE, + EVENT_SHOUT, + EVENT_KNIFE, + EVENT_COMMAND, +}; - void Reset() - { - UnbalancingStrike_Timer = 30000; //30 seconds - DisruptingShout_Timer = 25000; //25 seconds - CommandSound_Timer = 40000; //40 seconds - } +struct TRINITY_DLL_DECL boss_razuviousAI : public BossAI +{ + boss_razuviousAI(Creature *c) : BossAI(c, BOSS_RAZUVIOUS) {} - void KilledUnit(Unit* Victim) + void KilledUnit(Unit* victim) { - if (rand()%3) - return; - - switch (rand()%2) - { - case 0: - DoPlaySoundToSet(m_creature, SOUND_SLAY1); - break; - case 1: - DoPlaySoundToSet(m_creature, SOUND_SLAY2); - break; - } + if(!(rand()%3)) + DoPlaySoundToSet(me, SOUND_SLAY); } - void JustDied(Unit* Killer) + void JustDied(Unit* killer) { - DoPlaySoundToSet(m_creature, SOUND_DEATH); + _JustDied(); + DoPlaySoundToSet(me, SOUND_DEATH); + me->CastSpell(me, SPELL_HOPELESS, true); } void EnterCombat(Unit *who) { - switch (rand()%3) - { - case 0: - DoPlaySoundToSet(m_creature, SOUND_AGGRO1); - break; - case 1: - DoPlaySoundToSet(m_creature, SOUND_AGGRO2); - break; - case 2: - DoPlaySoundToSet(m_creature, SOUND_AGGRO3); - break; - } + _EnterCombat(); + DoPlaySoundToSet(m_creature, SOUND_AGGRO); + events.ScheduleEvent(EVENT_STRIKE, 30000); + events.ScheduleEvent(EVENT_SHOUT, 25000); + events.ScheduleEvent(EVENT_COMMAND, 40000); } void UpdateAI(const uint32 diff) { - if (!UpdateVictim()) + if(!UpdateVictim()) return; - //UnbalancingStrike_Timer - if (UnbalancingStrike_Timer < diff) - { - DoCast(m_creature->getVictim(),SPELL_UNBALANCINGSTRIKE); - UnbalancingStrike_Timer = 30000; - }else UnbalancingStrike_Timer -= diff; - - //DisruptingShout_Timer - if (DisruptingShout_Timer < diff) - { - DoCast(m_creature->getVictim(), SPELL_DISRUPTINGSHOUT); - DisruptingShout_Timer = 25000; - }else DisruptingShout_Timer -= diff; + events.Update(diff); - //CommandSound_Timer - if (CommandSound_Timer < diff) + while(uint32 eventId = events.ExecuteEvent()) { - switch (rand()%5) + switch(eventId) { - case 0: - DoPlaySoundToSet(m_creature, SOUND_COMMND1); - break; - case 1: - DoPlaySoundToSet(m_creature, SOUND_COMMND2); - break; - case 2: - DoPlaySoundToSet(m_creature, SOUND_COMMND3); - break; - case 3: - DoPlaySoundToSet(m_creature, SOUND_COMMND4); - break; - case 4: - DoPlaySoundToSet(m_creature, SOUND_COMMND5); - break; + case EVENT_STRIKE: + DoCast(me->getVictim(), SPELL_UNBALANCING_STRIKE); + events.ScheduleEvent(EVENT_STRIKE, 30000); + return; + case EVENT_SHOUT: + DoCastAOE(SPELL_DISRUPTING_SHOUT); + events.ScheduleEvent(EVENT_SHOUT, 25000); + return; + case EVENT_KNIFE: + if(Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45)) + DoCast(target, SPELL_JAGGED_KNIFE); + events.ScheduleEvent(EVENT_KNIFE, 25000); + return; + case EVENT_COMMAND: + DoPlaySoundToSet(me, SOUND_COMMND); + events.ScheduleEvent(EVENT_COMMAND, 40000); + return; } - - CommandSound_Timer = 40000; - }else CommandSound_Timer -= diff; + } DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI_boss_razuvious(Creature *_Creature) { return new boss_razuviousAI (_Creature); @@ -165,4 +126,3 @@ void AddSC_boss_razuvious() newscript->GetAI = &GetAI_boss_razuvious; newscript->RegisterSelf(); } - diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp index 682f6cee3a9..71259df7824 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp @@ -1,4 +1,6 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* + * Copyright (C) 2008 - 2009 Trinity + * * 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 @@ -14,13 +16,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Sapphiron -SD%Complete: 0 -SDComment: Place Holder -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" #include "def_naxxramas.h" @@ -71,14 +66,12 @@ enum Events typedef std::map IceBlockMap; -struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI +struct TRINITY_DLL_DECL boss_sapphironAI : public BossAI { - boss_sapphironAI(Creature* c) : ScriptedAI(c) + boss_sapphironAI(Creature* c) : BossAI(c, BOSS_SAPPHIRON) , phase(PHASE_NULL) - { - } + {} - EventMap events; Phases phase; uint32 iceboltCount; IceBlockMap iceblocks; @@ -97,16 +90,18 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI void Reset() { + _Reset(); + if(phase = PHASE_FLIGHT) ClearIceBlock(); - events.Reset(); phase = PHASE_NULL; } void EnterCombat(Unit *who) { - DoZoneInCombat(); + _EnterCombat(); + me->CastSpell(me, SPELL_FROST_AURA, true); events.ScheduleEvent(EVENT_BERSERK, 15*60000); @@ -128,6 +123,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI void JustDied(Unit*) { + _JustDied(); me->CastSpell(me, SPELL_DIES, true); } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h b/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h index 12c1dc6edfa..383200d4600 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h +++ b/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Trinity + * Copyright (C) 2008 - 2009 Trinity * * 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 @@ -21,14 +21,28 @@ enum Encounter { + BOSS_ANUBREKHAN, + BOSS_FAERLINA, + BOSS_MAEXXNA, BOSS_NOTH, BOSS_HEIGAN, BOSS_LOATHEB, + BOSS_PATCHWERK, + BOSS_GROBBULUS, + BOSS_GLUTH, + BOSS_THADDIUS, + BOSS_RAZUVIOUS, + BOSS_GOTHIK, + BOSS_HORSEMEN, + BOSS_SAPPHIRON, + BOSS_KELTHUZAD, + MAX_BOSS_NUMBER }; enum Data { DATA_HEIGAN_ERUPT, + DATA_GOTHIK_GATE, DATA_SAPPHIRON_BIRTH, }; diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index 23ffb7b8c4d..4dc189723f3 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2008 - 2009 Trinity * 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 @@ -14,18 +14,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Instance_Naxxramas -SD%Complete: 0 -SDComment: Place holder -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" #include "def_naxxramas.h" const DoorData doorData[] = { + {181126, BOSS_ANUBREKHAN,DOOR_TYPE_ROOM}, + {181195, BOSS_ANUBREKHAN,DOOR_TYPE_PASSAGE}, + {194022, BOSS_FAERLINA, DOOR_TYPE_PASSAGE}, + {181209, BOSS_FAERLINA, DOOR_TYPE_PASSAGE}, + {181209, BOSS_MAEXXNA, DOOR_TYPE_ROOM}, {181200, BOSS_NOTH, DOOR_TYPE_ROOM}, {181201, BOSS_NOTH, DOOR_TYPE_PASSAGE}, {181202, BOSS_NOTH, DOOR_TYPE_PASSAGE}, @@ -33,9 +31,21 @@ const DoorData doorData[] = {181203, BOSS_HEIGAN, DOOR_TYPE_PASSAGE}, {181241, BOSS_HEIGAN, DOOR_TYPE_PASSAGE}, {181241, BOSS_LOATHEB, DOOR_TYPE_ROOM}, + {181123, BOSS_PATCHWERK, DOOR_TYPE_PASSAGE}, + {181123, BOSS_GROBBULUS, DOOR_TYPE_ROOM}, + {181120, BOSS_GLUTH, DOOR_TYPE_PASSAGE}, + {181121, BOSS_GLUTH, DOOR_TYPE_PASSAGE}, + {181121, BOSS_THADDIUS, DOOR_TYPE_ROOM}, + {181124, BOSS_RAZUVIOUS, DOOR_TYPE_PASSAGE}, + {181124, BOSS_GOTHIK, DOOR_TYPE_ROOM}, + {181125, BOSS_GOTHIK, DOOR_TYPE_PASSAGE}, + {181119, BOSS_GOTHIK, DOOR_TYPE_PASSAGE}, + {181119, BOSS_HORSEMEN, DOOR_TYPE_ROOM}, {0, 0, DOOR_TYPE_ROOM}, // EOF }; +#define GO_GOTHIK_GATE 181170 + #define SPELL_ERUPTION 29371 const float HeiganPos[2] = {2796, -3707}; @@ -72,7 +82,7 @@ struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance instance_naxxramas(Map *map) : ScriptedInstance(map) , Sapphiron(NULL) { - SetBossNumber(15); + SetBossNumber(MAX_BOSS_NUMBER); LoadDoorData(doorData); } -- cgit v1.2.3 From f9f5d078fda410c0551f1376197094bc4a7bfe08 Mon Sep 17 00:00:00 2001 From: megamage Date: Mon, 11 May 2009 03:17:13 -0500 Subject: *Update instance script functions. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.h | 4 +-- src/bindings/scripts/include/sc_instance.h | 13 ------- .../shadow_labyrinth/instance_shadow_labyrinth.cpp | 2 +- .../azjol_nerub/ahnkahet/instance_ahnkahet.cpp | 2 +- .../azjol_nerub/instance_azjol_nerub.cpp | 2 +- .../zone/black_temple/instance_black_temple.cpp | 2 +- .../blackrock_depths/instance_blackrock_depths.cpp | 2 +- .../zone/caverns_of_time/hyjal/instance_hyjal.cpp | 2 +- .../serpent_shrine/instance_serpent_shrine.cpp | 2 +- .../steam_vault/instance_steam_vault.cpp | 2 +- .../zone/gruuls_lair/instance_gruuls_lair.cpp | 2 +- .../scripts/zone/karazhan/instance_karazhan.cpp | 2 +- .../scripts/zone/naxxramas/instance_naxxramas.cpp | 20 +++++++++-- .../shadowfang_keep/instance_shadowfang_keep.cpp | 2 +- .../sunwell_plateau/instance_sunwell_plateau.cpp | 2 +- .../zone/tempest_keep/the_eye/instance_the_eye.cpp | 2 +- .../utgarde_keep/instance_utgarde_keep.cpp | 2 +- .../scripts/zone/zulaman/instance_zulaman.cpp | 2 +- src/game/InstanceData.cpp | 41 ++++++++++++++++++---- src/game/InstanceData.h | 21 +++++------ src/game/InstanceSaveMgr.cpp | 8 ++--- src/game/Map.cpp | 2 +- 22 files changed, 83 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 26bf5fb400b..444b16e6cdf 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -221,13 +221,13 @@ struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI struct TRINITY_DLL_DECL BossAI : public ScriptedAI { BossAI(Creature *c, uint32 id) : ScriptedAI(c), bossId(id) - , summons(me), instance((ScriptedInstance*)c->GetInstanceData()) + , summons(me), instance(c->GetInstanceData()) {} uint32 bossId; EventMap events; SummonList summons; - ScriptedInstance *instance; + InstanceData *instance; void JustSummoned(Creature *summon); void SummonedCreatureDespawn(Creature *summon); diff --git a/src/bindings/scripts/include/sc_instance.h b/src/bindings/scripts/include/sc_instance.h index cdf0e03aa37..0620e89af07 100644 --- a/src/bindings/scripts/include/sc_instance.h +++ b/src/bindings/scripts/include/sc_instance.h @@ -17,20 +17,7 @@ class TRINITY_DLL_DECL ScriptedInstance : public InstanceData { public: - ScriptedInstance(Map *map) : InstanceData(map) {} - ~ScriptedInstance() {} - - //All-purpose data storage 64 bit - virtual uint64 GetData64(uint32 Data) { return 0; } - virtual void SetData64(uint32 Data, uint64 Value) { } - - // Called every instance update - virtual void Update(uint32) {} - - // Save and Load instance data to the database - const char* Save() { return NULL; } - void Load(const char* in) { } }; #endif diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp index 3cfb0af2fa1..37194a89b21 100644 --- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp +++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp @@ -191,7 +191,7 @@ struct TRINITY_DLL_DECL instance_shadow_labyrinth : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp index 41cb91f86b7..595a05a727f 100644 --- a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp +++ b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp @@ -129,7 +129,7 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp index bd3fccd98d9..7e0252f2009 100644 --- a/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp +++ b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp @@ -117,7 +117,7 @@ struct TRINITY_DLL_DECL instance_azjol_nerub : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; diff --git a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp index 43646746505..bf5d62a7b86 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp @@ -303,7 +303,7 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp index 6e26f3a0c03..d9f3ecd808a 100644 --- a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp +++ b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp @@ -265,7 +265,7 @@ struct TRINITY_DLL_DECL instance_blackrock_depths : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp index 0dfa99198ac..cdcd6cb6b66 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp @@ -279,7 +279,7 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance }else debug_log("TSCR: Instance Hyjal: UpdateWorldState, but PlayerList is empty!"); } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp index 6c4ae72aec1..8aa759a87c8 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp @@ -236,7 +236,7 @@ struct TRINITY_DLL_DECL instance_serpentshrine_cavern : public ScriptedInstance } return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp index 6d01da7f625..d375d073c35 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp @@ -209,7 +209,7 @@ struct TRINITY_DLL_DECL instance_steam_vault : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp b/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp index 34943449b1e..4c90fdf49a8 100644 --- a/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp +++ b/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp @@ -144,7 +144,7 @@ struct TRINITY_DLL_DECL instance_gruuls_lair : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp index e8dccdd62a4..62ad6fcf42c 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp @@ -247,7 +247,7 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance } } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index 4dc189723f3..23f44f5daf8 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -77,9 +77,9 @@ inline uint32 GetEruptionSection(float x, float y) return 3; } -struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance +struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData { - instance_naxxramas(Map *map) : ScriptedInstance(map) + instance_naxxramas(Map *map) : InstanceData(map) , Sapphiron(NULL) { SetBossNumber(MAX_BOSS_NUMBER); @@ -88,12 +88,14 @@ struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance std::set HeiganEruption[4]; Creature *Sapphiron; + std::set Worshipper; void OnCreatureCreate(Creature *creature, bool add) { switch(creature->GetEntry()) { case 15989: Sapphiron = add ? creature : NULL; break; + case 16506: if(add) Worshipper.insert(creature); else Worshipper.erase(creature); break; } } @@ -117,6 +119,20 @@ struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance AddDoor(go, add); } + void SetBossState(uint32 id, EncounterState state) + { + InstanceData::SetBossState(id, state); + switch(id) + { + case BOSS_FAERLINA: + if(state == NOT_STARTED) + for(std::set::iterator itr = Worshipper.begin(); itr != Worshipper.end(); ++itr) + if(!(*itr)->isAlive()) + (*itr)->Respawn(); + break; + } + } + void SetData(uint32 id, uint32 value) { switch(id) diff --git a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp index caf18778abb..30f843badb0 100644 --- a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp +++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp @@ -185,7 +185,7 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp index f8bba5acf21..597103b62cf 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp @@ -236,7 +236,7 @@ struct TRINITY_DLL_DECL instance_sunwell_plateau : public ScriptedInstance { } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp index 66e595ab729..55ef8c60bbd 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp @@ -129,7 +129,7 @@ struct TRINITY_DLL_DECL instance_the_eye : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp index d6f5828d295..d483006642d 100644 --- a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp +++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp @@ -231,7 +231,7 @@ struct TRINITY_DLL_DECL instance_utgarde_keep : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; diff --git a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp index 4ebf541515b..8ff01927908 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp @@ -179,7 +179,7 @@ struct TRINITY_DLL_DECL instance_zulaman : public ScriptedInstance instance->SendToPlayers(&data); } - const char* Save() + std::string GetSaveData() { std::ostringstream ss; ss << "S " << BossKilled << " " << ChestLooted << " " << QuestMinute; diff --git a/src/game/InstanceData.cpp b/src/game/InstanceData.cpp index 80e728f7b3c..96c10f7b85c 100644 --- a/src/game/InstanceData.cpp +++ b/src/game/InstanceData.cpp @@ -26,8 +26,9 @@ void InstanceData::SaveToDB() { - if(!Save()) return; - std::string data = Save(); + std::string data = GetSaveData(); + if(data.empty()) + return; CharacterDatabase.escape_string(data); CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%d'", data.c_str(), instance->GetInstanceId()); } @@ -124,13 +125,41 @@ void InstanceData::SetBossState(uint32 id, EncounterState state) if(id < bosses.size()) { BossInfo *bossInfo = &bosses[id]; - if(bossInfo->state == state) - return; - - bossInfo->state = state; + if(bossInfo->state == TO_BE_DECIDED) // loading + bossInfo->state = state; + else + { + if(bossInfo->state == state) + return; + bossInfo->state = state; + SaveToDB(); + } + for(uint32 type = 0; type < MAX_DOOR_TYPES; ++type) for(DoorSet::iterator i = bossInfo->door[type].begin(); i != bossInfo->door[type].end(); ++i) UpdateDoorState(*i); } } +std::string InstanceData::LoadBossState(const char * data) +{ + if(!data) return NULL; + std::istringstream loadStream(data); + uint32 buff; + uint32 bossId = 0; + for(std::vector::iterator i = bosses.begin(); i != bosses.end(); ++i, ++bossId) + { + loadStream >> buff; + if(buff < TO_BE_DECIDED) + SetBossState(bossId, (EncounterState)buff); + } + return loadStream.str(); +} + +std::string InstanceData::GetBossSaveData() +{ + std::ostringstream saveStream; + for(std::vector::iterator i = bosses.begin(); i != bosses.end(); ++i) + saveStream << (uint32)i->state << " "; + return saveStream.str(); +} diff --git a/src/game/InstanceData.h b/src/game/InstanceData.h index d68cb7ff7f8..91f589384a0 100644 --- a/src/game/InstanceData.h +++ b/src/game/InstanceData.h @@ -37,7 +37,8 @@ enum EncounterState IN_PROGRESS = 1, FAIL = 2, DONE = 3, - SPECIAL = 4 + SPECIAL = 4, + TO_BE_DECIDED = 5, }; typedef std::set DoorSet; @@ -51,7 +52,7 @@ enum DoorType struct BossInfo { - BossInfo() : state(NOT_STARTED) {} + BossInfo() : state(TO_BE_DECIDED) {} EncounterState state; DoorSet door[MAX_DOOR_TYPES]; }; @@ -85,10 +86,10 @@ class TRINITY_DLL_SPEC InstanceData virtual void Initialize() {} //On load - virtual void Load(const char* /*data*/) {} + virtual void Load(const char * data) { LoadBossState(data); } //When save is needed, this function generates the data - virtual const char* Save() { return ""; } + virtual std::string GetSaveData() { return GetBossSaveData(); } void SaveToDB(); @@ -121,7 +122,7 @@ class TRINITY_DLL_SPEC InstanceData //use HandleGameObject(GUID,boolen,NULL); in any other script void HandleGameObject(uint64 GUID, bool open, GameObject *go = NULL); - void SetBossState(uint32 id, EncounterState state); + virtual void SetBossState(uint32 id, EncounterState state); protected: void LoadDoorData(const DoorData *data); @@ -129,14 +130,8 @@ class TRINITY_DLL_SPEC InstanceData void AddDoor(GameObject *door, bool add); void UpdateDoorState(GameObject *door); - std::string GetBossSave() - { - std::ostringstream saveStream; - for(std::vector::iterator i = bosses.begin(); i != bosses.end(); ++i) - saveStream << (uint32)i->state << " "; - return saveStream.str(); - } - + std::string LoadBossState(const char * data); + std::string GetBossSaveData(); private: std::vector bosses; DoorInfoMap doors; diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index 131d26e90f7..7e2ad67c518 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -165,11 +165,11 @@ void InstanceSave::SaveToDB() if(map) { assert(map->IsDungeon()); - InstanceData *iData = ((InstanceMap *)map)->GetInstanceData(); - if(iData && iData->Save()) + if(InstanceData *iData = ((InstanceMap*)map)->GetInstanceData()) { - data = iData->Save(); - CharacterDatabase.escape_string(data); + data = iData->GetSaveData(); + if(!data.empty()) + CharacterDatabase.escape_string(data); } } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 3884f39f5a4..3280970750b 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -2503,7 +2503,7 @@ void InstanceMap::CreateInstanceData(bool load) { Field* fields = result->Fetch(); const char* data = fields[0].GetString(); - if(data) + if(data && data != "") { sLog.outDebug("Loading instance data for `%s` with id %u", objmgr.GetScriptName(i_script_id), i_InstanceId); i_data->Load(data); -- cgit v1.2.3 From 565896311778a76a86cee66406447e166d5344cd Mon Sep 17 00:00:00 2001 From: megamage Date: Mon, 11 May 2009 03:17:48 -0500 Subject: *Update Naxx scripts. --HG-- branch : trunk --- sql/updates/3233_world_scripts_naxx.sql | 28 ++++- .../scripts/zone/naxxramas/boss_faerlina.cpp | 129 +++++++++------------ .../scripts/zone/naxxramas/boss_patchwerk.cpp | 7 +- .../scripts/zone/naxxramas/boss_razuvious.cpp | 4 +- 4 files changed, 81 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/sql/updates/3233_world_scripts_naxx.sql b/sql/updates/3233_world_scripts_naxx.sql index d84a4462537..8b8140c17fe 100644 --- a/sql/updates/3233_world_scripts_naxx.sql +++ b/sql/updates/3233_world_scripts_naxx.sql @@ -1,5 +1,7 @@ -DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (-28169); +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (-28169,28732,54097); INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES +( 28732,-28798, 1, 'Widow\'s Embrace - Frenzy'), +( 54097,-54100, 1, 'Widow\'s Embrace - Frenzy (H)'), (-28169, 28206, 0, 'Mutating Injection - Mutagen Explosion'), (-28169, 28240, 0, 'Mutating Injection - Poison Cloud'); @@ -26,19 +28,33 @@ DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (29912); INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `quest_id`, `cast_flags`) VALUES (29912, 55479, 0, 1); # Obedience Crystal - Force Obedience -DELETE FROM `spell_script_target` WHERE `entry` IN (55479); +DELETE FROM `spell_script_target` WHERE `entry` IN +(28732,54097,55479, +27892,27893,27928,27929,27935,27936); INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES -(55479, 1, 16803); # Force Obedience - Death Knight Understudy +(28732, 1, 15953), # Widow's Embrace +(54097, 1, 15953), # Widow's Embrace +(55479, 1, 16803), # Force Obedience - Death Knight Understudy +# (29105, 1, 16803), # Hopeless - Death Knight Understudy +(27892, 1, 16060), # To Anchor 1 - Gothik +(27893, 1, 16060), # To Anchor 2 - Gothik +(27928, 1, 16060), # To Anchor 1 - Gothik +(27929, 1, 16060), # To Anchor 2 - Gothik +(27935, 1, 16060), # To Anchor 1 - Gothik +(27936, 1, 16060); # To Anchor 2 - Gothik + INSERT INTO creature_template (entry, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8) VALUES -(16803, 0, 0, 0, 61696, 29060, 29061, 0, 0), # Death Knight Understudy -(29941, 0, 0, 0, 61696, 29060, 29061, 0, 0), # Death Knight Understudy (H) (16573, 15284, 28991, 28969, 34970, 28864, 0, 0, 0), # Crypt Guard (29256, 15284, 28991, 56098, 34970, 28864, 0, 0, 0), # Crypt Guard (H) +(16506, 54095, 28732, 0, 0, 0, 0, 0, 0), # Naxxramas Worshipper +(29274, 54096, 54097, 0, 0, 0, 0, 0, 0), # Naxxramas Worshipper (H) (16984, 15496, 0, 0, 0, 0, 0, 0, 0), # Plagued Warrior (29632, 15496, 0, 0, 0, 0, 0, 0, 0), # Plagued Warrior (H) (16290, 28156, 0, 0, 0, 0, 0, 0, 0), # Fallout Slime -(29388, 54367, 0, 0, 0, 0, 0, 0, 0) # Fallout Slime (H) +(29388, 54367, 0, 0, 0, 0, 0, 0, 0), # Fallout Slime (H) +(16803, 0, 0, 0, 61696, 29060, 29061, 0, 0), # Death Knight Understudy +(29941, 0, 0, 0, 61696, 29060, 29061, 0, 0) # Death Knight Understudy (H) ON DUPLICATE KEY UPDATE spell1 = VALUES(spell1), spell2 = VALUES(spell2), diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp index 5ec67a8920b..9ee594b02b5 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_faerlina.cpp @@ -1,4 +1,6 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* + * Copyright (C) 2008 - 2009 Trinity + * * 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 @@ -14,83 +16,63 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Faerlina -SD%Complete: 50 -SDComment: -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" +#include "def_naxxramas.h" -#define SAY_GREET -1533009 -#define SAY_AGGRO1 -1533010 -#define SAY_AGGRO2 -1533011 -#define SAY_AGGRO3 -1533012 -#define SAY_AGGRO4 -1533013 -#define SAY_SLAY1 -1533014 -#define SAY_SLAY2 -1533015 -#define SAY_DEATH -1533016 +#define SAY_GREET -1533009 +#define SAY_AGGRO RAND(-1533010,-1533011,-1533012,-1533013) +#define SAY_SLAY RAND(-1533014,-1533015) +#define SAY_DEATH -1533016 //#define SOUND_RANDOM_AGGRO 8955 //soundId containing the 4 aggro sounds, we not using this -#define SPELL_POSIONBOLT_VOLLEY 28796 -#define H_SPELL_POSIONBOLT_VOLLEY 54098 -#define SPELL_ENRAGE 28798 -#define H_SPELL_ENRAGE 54100 -#define SPELL_RAINOFFIRE 28794 //Not sure if targeted AoEs work if casted directly upon a player +#define SPELL_POSION_BOLT_VOLLEY HEROIC(28796,54098) +#define SPELL_RAIN_OF_FIRE HEROIC(28794,54099) +#define SPELL_FRENZY HEROIC(28798,54100) +#define SPELL_WIDOWS_EMBRACE HEROIC(28732,54097) -struct TRINITY_DLL_DECL boss_faerlinaAI : public ScriptedAI +enum Events { - boss_faerlinaAI(Creature *c) : ScriptedAI(c) {} + EVENT_POSION = 1, + EVENT_FIRE, + EVENT_FRENZY, +}; - uint32 PoisonBoltVolley_Timer; - uint32 RainOfFire_Timer; - uint32 Enrage_Timer; - bool HasTaunted; +struct TRINITY_DLL_DECL boss_faerlinaAI : public BossAI +{ + boss_faerlinaAI(Creature *c) : BossAI(c, BOSS_FAERLINA), greet(false) {} - void Reset() - { - PoisonBoltVolley_Timer = 8000; - RainOfFire_Timer = 16000; - Enrage_Timer = 60000; - HasTaunted = false; - } + bool greet; void EnterCombat(Unit *who) { - switch (rand()%4) - { - case 0: DoScriptText(SAY_AGGRO1, m_creature); break; - case 1: DoScriptText(SAY_AGGRO2, m_creature); break; - case 2: DoScriptText(SAY_AGGRO3, m_creature); break; - case 3: DoScriptText(SAY_AGGRO4, m_creature); break; - } + _EnterCombat(); + DoScriptText(SAY_AGGRO, me); + events.ScheduleEvent(EVENT_POSION, 10000 + rand()%15000); + events.ScheduleEvent(EVENT_FIRE, 5000 + rand()%15000); + events.ScheduleEvent(EVENT_FRENZY, 60000 + rand()%20000); } void MoveInLineOfSight(Unit *who) { - if (!HasTaunted && m_creature->IsWithinDistInMap(who, 60.0f)) - { - DoScriptText(SAY_GREET, m_creature); - HasTaunted = true; - + if(!greet) + { + DoScriptText(SAY_GREET, me); + greet = true; } - ScriptedAI::MoveInLineOfSight(who); + BossAI::MoveInLineOfSight(who); } void KilledUnit(Unit* victim) { - switch (rand()%2) - { - case 0: DoScriptText(SAY_SLAY1, m_creature); break; - case 1: DoScriptText(SAY_SLAY2, m_creature); break; - } + if(!(rand()%3)) + DoScriptText(SAY_SLAY, me); } void JustDied(Unit* Killer) { - DoScriptText(SAY_DEATH, m_creature); + _JustDied(); + DoScriptText(SAY_DEATH, me); } void UpdateAI(const uint32 diff) @@ -98,31 +80,33 @@ struct TRINITY_DLL_DECL boss_faerlinaAI : public ScriptedAI if (!UpdateVictim()) return; - //PoisonBoltVolley_Timer - if (PoisonBoltVolley_Timer < diff) - { - DoCast(m_creature->getVictim(),SPELL_POSIONBOLT_VOLLEY); - PoisonBoltVolley_Timer = 11000; - }else PoisonBoltVolley_Timer -= diff; + events.Update(diff); - //RainOfFire_Timer - if (RainOfFire_Timer < diff) + while(uint32 eventId = events.ExecuteEvent()) { - if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(target,SPELL_RAINOFFIRE); - RainOfFire_Timer = 16000; - }else RainOfFire_Timer -= diff; - - //Enrage_Timer - if (Enrage_Timer < diff) - { - DoCast(m_creature,SPELL_ENRAGE); - Enrage_Timer = 61000; - }else Enrage_Timer -= diff; + switch(eventId) + { + case EVENT_POSION: + if(!me->HasAura(SPELL_WIDOWS_EMBRACE)) + DoCastAOE(SPELL_POSION_BOLT_VOLLEY); + events.ScheduleEvent(EVENT_POSION, 10000 + rand()%15000); + return; + case EVENT_FIRE: + if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_RAIN_OF_FIRE); + events.ScheduleEvent(EVENT_FIRE, 5000 + rand()%15000); + return; + case EVENT_FRENZY: + DoCast(me,SPELL_FRENZY); + events.ScheduleEvent(EVENT_FRENZY, 60000 + rand()%20000); + return; + } + } DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI_boss_faerlina(Creature *_Creature) { return new boss_faerlinaAI (_Creature); @@ -136,4 +120,3 @@ void AddSC_boss_faerlina() newscript->GetAI = &GetAI_boss_faerlina; newscript->RegisterSelf(); } - diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp index a05685264d6..7886fad94cc 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp @@ -39,12 +39,6 @@ struct TRINITY_DLL_DECL boss_patchwerkAI : public BossAI bool Enraged; - void Reset() - { - _Reset(); - Enraged = false; - } - void KilledUnit(Unit* Victim) { if(!(rand()%5)) @@ -60,6 +54,7 @@ struct TRINITY_DLL_DECL boss_patchwerkAI : public BossAI void EnterCombat(Unit *who) { _EnterCombat(); + Enraged = false; DoScriptText(SAY_AGGRO, me); events.ScheduleEvent(EVENT_HATEFUL, 1200); events.ScheduleEvent(EVENT_BERSERK, 360000); diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp index 120220172cd..67fcaee7de3 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_razuvious.cpp @@ -42,7 +42,7 @@ #define SPELL_UNBALANCING_STRIKE 26613 #define SPELL_DISRUPTING_SHOUT HEROIC(29107,55543) #define SPELL_JAGGED_KNIFE 55550 -#define SPELL_HOPELESS 29105 +#define SPELL_HOPELESS 29125 enum Events { @@ -66,7 +66,7 @@ struct TRINITY_DLL_DECL boss_razuviousAI : public BossAI { _JustDied(); DoPlaySoundToSet(me, SOUND_DEATH); - me->CastSpell(me, SPELL_HOPELESS, true); + me->CastSpell(me, SPELL_HOPELESS, true); // TODO: this may affect other creatures } void EnterCombat(Unit *who) -- cgit v1.2.3 From f631b2a2d69775b818814f6c2ee0bc3daa3d616b Mon Sep 17 00:00:00 2001 From: megamage Date: Mon, 11 May 2009 11:46:48 -0500 Subject: *Update creature AI functions. --HG-- branch : trunk --- src/bindings/scripts/include/precompiled.h | 3 ++- src/bindings/scripts/include/sc_creature.cpp | 26 +++++----------------- src/bindings/scripts/include/sc_creature.h | 20 ----------------- .../scripts/zone/black_temple/boss_supremus.cpp | 4 +++- src/game/AggressorAI.h | 2 +- src/game/CreatureAI.cpp | 2 ++ src/game/CreatureAI.h | 2 +- src/game/NullCreatureAI.h | 18 ++++++++++----- src/game/TemporarySummon.h | 2 +- 9 files changed, 27 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/include/precompiled.h b/src/bindings/scripts/include/precompiled.h index 2c36cc924e0..fa676f460ef 100644 --- a/src/bindings/scripts/include/precompiled.h +++ b/src/bindings/scripts/include/precompiled.h @@ -12,10 +12,11 @@ #include "GridNotifiersImpl.h" #include "Unit.h" #include "GameObject.h" -#include "TemporarySummon.h" #include "sc_creature.h" #include "sc_gossip.h" #include "sc_instance.h" +#include "AggressorAI.h" +#include "NullCreatureAI.h" #ifdef WIN32 #include diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index e5a6eb958e0..0b874773ffc 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -9,6 +9,7 @@ #include "Item.h" #include "Spell.h" #include "ObjectMgr.h" +#include "TemporarySummon.h" // Spell summary for ScriptedAI::SelectSpell struct TSpellSummary { @@ -56,7 +57,10 @@ void SummonList::DespawnAll() { erase(begin()); summon->SetVisibility(VISIBILITY_OFF); - summon->setDeathState(JUST_DIED); + if(summon->HasSummonMask(SUMMON_MASK_SUMMON) && !summon->isPet()) + ((TempSummon*)summon)->UnSummon(); + else + summon->setDeathState(JUST_DIED); summon->RemoveCorpse(); } } @@ -109,26 +113,6 @@ void ScriptedAI::UpdateAI(const uint32 diff) } } -void ScriptedAI::EnterEvadeMode() -{ - //m_creature->InterruptNonMeleeSpells(true); - m_creature->RemoveAllAuras(); - m_creature->DeleteThreatList(); - m_creature->CombatStop(); - m_creature->LoadCreaturesAddon(); - m_creature->SetLootRecipient(NULL); - - if(m_creature->isAlive()) - m_creature->GetMotionMaster()->MoveTargetedHome(); - - Reset(); -} - -void ScriptedAI::JustRespawned() -{ - Reset(); -} - void ScriptedAI::DoStartMovement(Unit* victim, float distance, float angle) { if (!victim) diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 444b16e6cdf..0fb716bbe0e 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -58,9 +58,6 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI void AttackStart(Unit *); void AttackStart(Unit *, bool melee); - //Called at stoping attack by any attacker - void EnterEvadeMode(); - // Called at any Damage from any attacker (before damage apply) void DamageTaken(Unit *done_by, uint32 &damage) {} @@ -85,9 +82,6 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI // Called when spell hits a target void SpellHitTarget(Unit* target, const SpellEntry*) {} - // Called when creature is spawned or respawned (for reseting variables) - void JustRespawned(); - //Called at waypoint reached or PointMovement end void MovementInform(uint32 type, uint32 id){} @@ -204,20 +198,6 @@ struct TRINITY_DLL_DECL Scripted_NoMovementAI : public ScriptedAI void AttackStart(Unit *); }; -struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI -{ - NullCreatureAI(Creature* c) : ScriptedAI(c) {} - ~NullCreatureAI() {} - - void Reset() {} - void EnterCombat(Unit*) {} - void MoveInLineOfSight(Unit *) {} - void AttackStart(Unit *) {} - void EnterEvadeMode() {} - - void UpdateAI(const uint32) {} -}; - struct TRINITY_DLL_DECL BossAI : public ScriptedAI { BossAI(Creature *c, uint32 id) : ScriptedAI(c), bossId(id) diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp index fdfdef396bb..ff90f7e6a81 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp @@ -53,7 +53,9 @@ EndScriptData */ struct TRINITY_DLL_DECL molten_flameAI : public NullCreatureAI { - molten_flameAI(Creature *c) : NullCreatureAI(c) + molten_flameAI(Creature *c) : NullCreatureAI(c) {} + + void InitializeAI() { float x, y, z; me->GetNearPoint(me, x, y, z, 1, 50, M_PI*2*rand_norm()); diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h index 94a6b0b3bf1..2c43ccf82b7 100644 --- a/src/game/AggressorAI.h +++ b/src/game/AggressorAI.h @@ -37,7 +37,7 @@ class TRINITY_DLL_DECL AggressorAI : public CreatureAI typedef std::vector SpellVct; -class TRINITY_DLL_DECL SpellAI : public CreatureAI +class TRINITY_DLL_SPEC SpellAI : public CreatureAI { public: explicit SpellAI(Creature *c) : CreatureAI(c) {} diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 123fa1182a1..8633ee2e1f4 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -112,6 +112,8 @@ void CreatureAI::EnterEvadeMode() if(me->isAlive()) me->GetMotionMaster()->MoveTargetedHome(); + + Reset(); } inline bool SelectTargetHelper(const Unit * me, const Unit * target, const bool &playerOnly, const float &dist, const int32 &aura) diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index ca13275dea1..6b031005463 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -123,7 +123,7 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI //virtual void AttackedBy(Unit* attacker); // Called when creature is spawned or respawned (for reseting variables) - virtual void JustRespawned() {} + virtual void JustRespawned() { Reset(); } // Called at waypoint reached or point movement finished virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {} diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h index f8a5d8480f0..347f52228b4 100644 --- a/src/game/NullCreatureAI.h +++ b/src/game/NullCreatureAI.h @@ -28,35 +28,41 @@ class TRINITY_DLL_DECL PassiveAI : public CreatureAI { public: explicit PassiveAI(Creature *c) : CreatureAI(c) {} - ~PassiveAI() {} void MoveInLineOfSight(Unit *) {} void AttackStart(Unit *) {} - void UpdateAI(const uint32); + static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; } }; -class TRINITY_DLL_DECL PossessedAI : public PassiveAI +class TRINITY_DLL_DECL PossessedAI : public CreatureAI { public: - explicit PossessedAI(Creature *c) : PassiveAI(c) {} + explicit PossessedAI(Creature *c) : CreatureAI(c) {} + void MoveInLineOfSight(Unit *) {} void AttackStart(Unit *target); void UpdateAI(const uint32); void EnterEvadeMode() {} void JustDied(Unit*); void KilledUnit(Unit* victim); + + static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; } }; -class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI +class TRINITY_DLL_DECL NullCreatureAI : public CreatureAI { public: - explicit NullCreatureAI(Creature *c) : PassiveAI(c) {} + explicit NullCreatureAI(Creature *c) : CreatureAI(c) {} + void MoveInLineOfSight(Unit *) {} + void AttackStart(Unit *) {} void UpdateAI(const uint32) {} void EnterEvadeMode() {} + + static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; } }; class TRINITY_DLL_DECL CritterAI : public PassiveAI diff --git a/src/game/TemporarySummon.h b/src/game/TemporarySummon.h index 09e7f22afb0..e089c77c96e 100644 --- a/src/game/TemporarySummon.h +++ b/src/game/TemporarySummon.h @@ -23,7 +23,7 @@ #include "Creature.h" -class TempSummon : public Creature +class TRINITY_DLL_SPEC TempSummon : public Creature { public: explicit TempSummon(SummonPropertiesEntry const *properties, Unit *owner); -- cgit v1.2.3 From 91558b8b29f2f81a4a121a3941cf9aaa7243fe96 Mon Sep 17 00:00:00 2001 From: megamage Date: Mon, 11 May 2009 13:15:16 -0500 Subject: *Try to fix build in Linux. --HG-- branch : trunk --- src/game/CreatureAI.h | 1 + src/game/UnitAI.cpp | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index 6b031005463..605e904c71a 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -22,6 +22,7 @@ #define TRINITY_CREATUREAI_H #include "UnitAI.h" +#include "Common.h" class WorldObject; class Unit; diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp index c991c75603d..76460bd8cc0 100644 --- a/src/game/UnitAI.cpp +++ b/src/game/UnitAI.cpp @@ -19,6 +19,7 @@ */ #include "UnitAI.h" +#include "Unit.h" #include "SpellAuras.h" void UnitAI::AttackStart(Unit *victim) -- cgit v1.2.3 From 8fc07d443acb86ca436caa05b435c86ea6e9071d Mon Sep 17 00:00:00 2001 From: megamage Date: Mon, 11 May 2009 13:27:10 -0500 Subject: *Change waypoint data structure. Use creature db guid as path id. If a creature uses waypoint movement as default movement type, the path id should be DBGUID*10. For paths of script use, the path id should be DBGUID*10+1 ~ DBGUID*10+9. *Two sql queries are included. Converter is used to convert the existing path id to new path id. "...creature_add..." is used to change table structure. You can first run the converter, then run the other one. Or run the other one directly and get the new data from the db team. Because it may take hours to run the converter. *If you have custom data, you may need to run the converter. We suggest you use console to run it It is extremely slow to run the query. If you have multiple paths for a creature in your db, you need to do more work to convert it. However, if you know how to use multiple paths, you should already have more db knowledge than I do and you should know how to convert it. *There may be a faster query to convert the db. If you know, please tell us. I am no sql expert. *Backup your db first! *Thanks to X-Savior and subhuman_bob. --HG-- branch : trunk --- .../3257_world_creature_addon_(waypoint).sql | 2 + sql/updates/3257_world_waypoint_data_converter.sql | 6 ++ src/game/Creature.cpp | 27 ++++++-- src/game/Creature.h | 9 ++- src/game/Level2.cpp | 71 +++++++++++++--------- src/game/SpellMgr.cpp | 30 ++++----- src/game/WaypointManager.cpp | 21 +++---- src/game/WaypointManager.h | 11 ++-- src/game/WaypointMovementGenerator.cpp | 6 +- src/game/WaypointMovementGenerator.h | 4 +- src/shared/Database/SQLStorage.cpp | 4 +- 11 files changed, 116 insertions(+), 75 deletions(-) create mode 100644 sql/updates/3257_world_creature_addon_(waypoint).sql create mode 100644 sql/updates/3257_world_waypoint_data_converter.sql (limited to 'src') diff --git a/sql/updates/3257_world_creature_addon_(waypoint).sql b/sql/updates/3257_world_creature_addon_(waypoint).sql new file mode 100644 index 00000000000..1398baf1ccd --- /dev/null +++ b/sql/updates/3257_world_creature_addon_(waypoint).sql @@ -0,0 +1,2 @@ +ALTER TABLE creature_template_addon DROP COLUMN path_id; +ALTER TABLE creature_addon DROP COLUMN path_id; \ No newline at end of file diff --git a/sql/updates/3257_world_waypoint_data_converter.sql b/sql/updates/3257_world_waypoint_data_converter.sql new file mode 100644 index 00000000000..3533f948747 --- /dev/null +++ b/sql/updates/3257_world_waypoint_data_converter.sql @@ -0,0 +1,6 @@ +ALTER TABLE waypoint_data ADD COLUMN id_old int(10) unsigned NOT NULL default '0' COMMENT 'Creature GUID' AFTER wpguid; +UPDATE waypoint_data SET id_old=id; +UPDATE waypoint_data,creature_addon SET waypoint_data.id=creature_addon.guid*10 WHERE creature_addon.path_id > 0 AND creature_addon.path_id=waypoint_data.id_old; +UPDATE waypoint_data SET id = 1343801 WHERE id_old = 2084; +UPDATE waypoint_scripts SET datalong = 1343801 WHERE id = 515; +ALTER TABLE waypoint_data DROP COLUMN id_old; \ No newline at end of file diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index a47afda5cd2..85109997390 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -175,7 +175,7 @@ void Creature::AddToWorld() { ObjectAccessor::Instance().AddObject(this); Unit::AddToWorld(); - SearchFormation(); + SearchFormationAndPath(); AIM_Initialize(); } } @@ -194,7 +194,7 @@ void Creature::RemoveFromWorld() } } -void Creature::SearchFormation() +void Creature::SearchFormationAndPath() { if(isSummon()) return; @@ -203,9 +203,28 @@ void Creature::SearchFormation() if(!lowguid) return; + bool usePath = (GetDefaultMovementType() == WAYPOINT_MOTION_TYPE); CreatureGroupInfoType::iterator frmdata = CreatureGroupMap.find(lowguid); if(frmdata != CreatureGroupMap.end()) + { + if(usePath && lowguid != frmdata->second->leaderGUID) + { + SetDefaultMovementType(IDLE_MOTION_TYPE); + usePath = false; + } formation_mgr.AddCreatureToGroup(frmdata->second->leaderGUID, this); + } + + if(usePath) + { + if(WaypointMgr.GetPath(lowguid * 10)) + SetWaypointPathId(lowguid * 10); + else + { + sLog.outErrorDb("Creature DBGUID %u has waypoint motion type, but it does not have a waypoint path!", lowguid); + SetDefaultMovementType(IDLE_MOTION_TYPE); + } + } } void Creature::RemoveCorpse() @@ -2081,10 +2100,6 @@ bool Creature::LoadCreaturesAddon(bool reload) if (cainfo->move_flags != 0) SetUnitMovementFlags(cainfo->move_flags); - //Load Path - if (cainfo->path_id != 0) - m_path_id = cainfo->path_id; - if(cainfo->auras) { for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura) diff --git a/src/game/Creature.h b/src/game/Creature.h index b90642547dd..f57f0592da5 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -315,7 +315,6 @@ struct CreatureDataAddonAura struct CreatureDataAddon { uint32 guidOrEntry; - uint32 path_id; uint32 mount; uint32 bytes0; uint32 bytes1; @@ -692,13 +691,13 @@ class TRINITY_DLL_SPEC Creature : public Unit uint32 GetGlobalCooldown() const { return m_GlobalCooldown; } - uint32 GetWaypointPath(){return m_path_id;} - void LoadPath(uint32 pathid) { m_path_id = pathid; } + uint32 GetWaypointPathId() const { return m_pathId; } + void SetWaypointPathId(uint32 pathid) { m_pathId = pathid; } uint32 GetCurrentWaypointID(){return m_waypointID;} void UpdateWaypointID(uint32 wpID){m_waypointID = wpID;} - void SearchFormation(); + void SearchFormationAndPath(); CreatureGroup *GetFormation() {return m_formation;} void SetFormation(CreatureGroup *formation) {m_formation = formation;} @@ -759,7 +758,7 @@ class TRINITY_DLL_SPEC Creature : public Unit private: //WaypointMovementGenerator vars uint32 m_waypointID; - uint32 m_path_id; + uint32 m_pathId; //Formation var CreatureGroup *m_formation; diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index bc83aa7a352..782b0f9c44e 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1288,7 +1288,7 @@ bool ChatHandler::HandleNpcAddMoveCommand(const char* args) // update movement type WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid); - if(pCreature && pCreature->GetWaypointPath()) + if(pCreature && pCreature->GetWaypointPathId()) { pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); pCreature->GetMotionMaster()->Initialize(); @@ -1609,7 +1609,7 @@ bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args) { // update movement type if(doNotDelete == false) - pCreature->LoadPath(0); + pCreature->SetWaypointPathId(0); pCreature->SetDefaultMovementType(move_type); pCreature->GetMotionMaster()->Initialize(); @@ -2639,7 +2639,7 @@ bool ChatHandler::HandleWpAddCommand(const char* args) if (!path_number) { if(target) - pathid = target->GetWaypointPath(); + pathid = target->GetWaypointPathId(); else { QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(id) FROM waypoint_data"); @@ -2694,7 +2694,6 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args) if(*args) path_number = strtok((char*)args, " "); - uint32 pathid = 0; uint32 guidlow = 0; Creature* target = getSelectedCreature(); @@ -2725,6 +2724,7 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args) return true; } + /* guidlow = target->GetDBTableGUIDLow(); QueryResult *result = WorldDatabase.PQuery( "SELECT guid FROM creature_addon WHERE guid = '%u'",guidlow); @@ -2735,10 +2735,11 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args) } else WorldDatabase.PExecute("INSERT INTO creature_addon(guid,path_id) VALUES ('%u','%u')", guidlow, pathid); + */ WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE, guidlow); - target->LoadPath(pathid); + target->SetWaypointPathId(pathid); target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); target->GetMotionMaster()->Initialize(); target->MonsterSay("Path loaded.",0,0); @@ -2746,20 +2747,19 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args) return true; } - bool ChatHandler::HandleReloadAllPaths(const char* args) { -if(!*args) - return false; + if(!*args) + return false; -uint32 id = atoi(args); + uint32 id = atoi(args); -if(!id) - return false; + if(!id) + return false; PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id); WaypointMgr.UpdatePath(id); - return true; + return true; } bool ChatHandler::HandleWpUnLoadPathCommand(const char *args) @@ -2773,24 +2773,39 @@ bool ChatHandler::HandleWpUnLoadPathCommand(const char *args) return true; } - if(target->GetCreatureAddon()) + if(target->GetWaypointPathId()) { - if(target->GetCreatureAddon()->path_id != 0) + uint32 pathId = target->GetDBTableGUIDLow() * 10; + if(target->GetWaypointPathId() == pathId) { - WorldDatabase.PExecute("DELETE FROM creature_addon WHERE guid = %u", target->GetGUIDLow()); - target->UpdateWaypointID(0); - WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, guidlow); - target->LoadPath(0); - target->SetDefaultMovementType(IDLE_MOTION_TYPE); - target->GetMotionMaster()->MoveTargetedHome(); - target->GetMotionMaster()->Initialize(); - target->MonsterSay("Path unloaded.",0,0); - return true; + for(uint32 i = 1; i < 11; ++i) + { + if(i == 10) + { + PSendSysMessage("%s%s|r", "|cffff33ff", "Target cannot have more than 9 script paths. Unloading failed."); + break; + } + + if(WaypointMgr.GetPath(++pathId)) + continue; + + WorldDatabase.PExecute("UPDATE waypoint_data SET id = %u WHERE id = %u", pathId, target->GetDBTableGUIDLow() * 10); + WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, guidlow); + target->SetWaypointPathId(0); + target->UpdateWaypointID(0); + target->SetDefaultMovementType(IDLE_MOTION_TYPE); + target->GetMotionMaster()->Initialize(); + target->GetMotionMaster()->MoveTargetedHome(); + PSendSysMessage("Path unloaded."); + break; + } } - PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path."); - return true; + else + PSendSysMessage("%s%s|r", "|cffff33ff", "Target has path but that path is not its default path. Unloading failed."); } - PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path."); + else + PSendSysMessage("%s%s|r", "|cffff33ff", "Target has no loaded path."); + return true; } @@ -3264,7 +3279,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args) return false; } - pathid = target->GetWaypointPath(); + pathid = target->GetWaypointPathId(); } else @@ -4629,7 +4644,7 @@ bool ChatHandler::HandleNpcAddFormationCommand(const char* args) group_member->groupAI = 0; CreatureGroupMap[lowguid] = group_member; - pCreature->SearchFormation(); + pCreature->SearchFormationAndPath(); WorldDatabase.PExecuteLog("INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`) VALUES ('%u','%u','%f', '%f', '%u')", leaderGUID, lowguid, group_member->follow_dist, group_member->follow_angle, group_member->groupAI); diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 9b1cb798849..4e5a4744e9a 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2431,31 +2431,32 @@ void SpellMgr::LoadSpellCustomAttr() case 45976: // Muru Portal Channel case 39365: // Thundering Storm case 41071: // Raise Dead (HACK) - case 28542: // Life Drain - Sapphiron spellInfo->MaxAffectedTargets = 1; break; case 41376: // Spite case 39992: // Needle Spine - case 29576: //Multi-Shot - case 40816: //Saber Lash - case 37790: //Spread Shot - case 46771: //Flame Sear - case 45248: //Shadow Blades + case 29576: // Multi-Shot + case 40816: // Saber Lash + case 37790: // Spread Shot + case 46771: // Flame Sear + case 45248: // Shadow Blades case 41303: // Soul Drain case 54172: // Divine Storm (heal) - case 29213: // Curse of the Plaguebringer + case 29213: // Curse of the Plaguebringer - Noth + case 28542: // Life Drain - Sapphiron spellInfo->MaxAffectedTargets = 3; break; case 38310: //Multi-Shot spellInfo->MaxAffectedTargets = 4; break; case 42005: // Bloodboil - case 38296: //Spitfire Totem - case 37676: //Insidious Whisper - case 46009: //Negative Energy - case 45641: //Fire Bloom - case 54937: //Glyph of Holy Light - case 55665: // Life Drain - Sapphiron + case 38296: // Spitfire Totem + case 37676: // Insidious Whisper + case 46009: // Negative Energy + case 45641: // Fire Bloom + case 54937: // Glyph of Holy Light + case 55665: // Life Drain - Sapphiron (H) + case 28796: // Poison Bolt Volly - Faerlina spellInfo->MaxAffectedTargets = 5; break; case 40827: // Sinful Beam @@ -2463,7 +2464,8 @@ void SpellMgr::LoadSpellCustomAttr() case 40860: // Vile Beam case 40861: // Wicked Beam case 57669: // Replenishment - case 54835: // Curse of the Plaguebringer + case 54835: // Curse of the Plaguebringer - Noth (H) + case 54098: // Poison Bolt Volly - Faerlina (H) spellInfo->MaxAffectedTargets = 10; break; case 8122: case 8124: case 10888: case 10890: // Psychic Scream diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp index a677fd5b6d2..26be14d89fa 100644 --- a/src/game/WaypointManager.cpp +++ b/src/game/WaypointManager.cpp @@ -24,12 +24,12 @@ #include "ProgressBar.h" #include "MapManager.h" -UNORDERED_MAP waypoint_map; +WaypointPathMap WaypointPathHolder; WaypointStore WaypointMgr; void WaypointStore::Free() { - waypoint_map.clear(); + WaypointPathHolder.clear(); } void WaypointStore::Load() @@ -37,7 +37,7 @@ void WaypointStore::Load() QueryResult *result = WorldDatabase.PQuery("SELECT MAX(`id`) FROM `waypoint_data`"); if(!result) { - sLog.outError(" an error occured while loading the table `waypoint_data` ( maybe it doesn't exist ?)\n"); + sLog.outError("an error occured while loading the table `waypoint_data` (maybe it doesn't exist ?)"); exit(1); // Stop server at loading non exited table or not accessable table } @@ -47,7 +47,7 @@ void WaypointStore::Load() result = WorldDatabase.PQuery("SELECT `id`,`point`,`position_x`,`position_y`,`position_z`,`move_flag`,`delay`,`action`,`action_chance` FROM `waypoint_data` ORDER BY `id`, `point`"); if(!result) { - sLog.outErrorDb("The table `creature_addon` is empty or corrupted"); + sLog.outErrorDb("The table `waypoint_data` is empty or corrupted"); return; } @@ -87,22 +87,21 @@ void WaypointStore::Load() path_data->push_back(wp); - if(id != last_id) - waypoint_map[id] = path_data; + if(id != last_id) + WaypointPathHolder[id] = path_data; last_id = id; } while(result->NextRow()) ; - delete result; } void WaypointStore::UpdatePath(uint32 id) { - - if(waypoint_map.find(id)!= waypoint_map.end()) - waypoint_map[id]->clear(); + // TODO: this will cause memory leak + if(WaypointPathHolder.find(id) != WaypointPathHolder.end()) + WaypointPathHolder[id]->clear(); QueryResult *result; @@ -145,7 +144,7 @@ void WaypointStore::UpdatePath(uint32 id) }while (result->NextRow()); - waypoint_map[id] = path_data; + WaypointPathHolder[id] = path_data; delete result; } diff --git a/src/game/WaypointManager.h b/src/game/WaypointManager.h index 85f8b765d45..a8f2d5746e9 100644 --- a/src/game/WaypointManager.h +++ b/src/game/WaypointManager.h @@ -34,7 +34,9 @@ struct WaypointData }; typedef std::vector WaypointPath; -extern UNORDERED_MAP waypoint_map; +typedef UNORDERED_MAP WaypointPathMap; + +extern WaypointPathMap WaypointPathHolder; class WaypointStore { @@ -48,9 +50,10 @@ class WaypointStore WaypointPath* GetPath(uint32 id) { - if(waypoint_map.find(id) != waypoint_map.end()) - return waypoint_map[id]; - else return 0; + WaypointPathMap::iterator itr = WaypointPathHolder.find(id); + if(itr != WaypointPathHolder.end()) + return itr->second; + return NULL; } inline uint32 GetRecordsCount() { return records; } diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index ae7ef0bce00..effc78d8026 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -100,7 +100,7 @@ WaypointMovementGenerator::Initialize(Creature &u) //i_nextMoveTime.Reset(0); StopedByPlayer = false; if(!path_id) - path_id = u.GetWaypointPath(); + path_id = u.GetWaypointPathId(); waypoints = WaypointMgr.GetPath(path_id); i_currentNode = 0; if(waypoints && waypoints->size()) @@ -226,7 +226,7 @@ template bool WaypointMovementGenerator::Update(Player &, const uint32 & template void WaypointMovementGenerator::MovementInform(Player &); //----------------------------------------------------// -void FlightPathMovementGenerator::LoadPath(Player &) +void FlightPathMovementGenerator::SetWaypointPathId(Player &) { objmgr.GetTaxiPathNodes(i_pathId, i_path,i_mapIds); } @@ -252,7 +252,7 @@ void FlightPathMovementGenerator::Initialize(Player &player) player.addUnitState(UNIT_STAT_IN_FLIGHT); player.SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); player.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); - LoadPath(player); + SetWaypointPathId(player); Traveller traveller(player); // do not send movement, it was sent already i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false); diff --git a/src/game/WaypointMovementGenerator.h b/src/game/WaypointMovementGenerator.h index 9804c150d63..9c93486a675 100644 --- a/src/game/WaypointMovementGenerator.h +++ b/src/game/WaypointMovementGenerator.h @@ -50,7 +50,7 @@ class TRINITY_DLL_SPEC PathMovementBase bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); } - void LoadPath(T &); + void SetWaypointPathId(T &); void ReloadPath(T &); uint32 GetCurrentNode() const { return i_currentNode; } @@ -104,7 +104,7 @@ public PathMovementBase bool Update(Player &, const uint32 &); MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; } - void LoadPath(Player &); + void SetWaypointPathId(Player &); void ReloadPath(Player &) { /* don't reload flight path */ } Path& GetPath() { return i_path; } diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index 8561afc4a33..67091174c77 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -29,9 +29,9 @@ extern DatabaseMysql WorldDatabase; const char CreatureInfosrcfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifflliiis"; const char CreatureInfodstfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifflliiii"; -const char CreatureDataAddonInfofmt[]="iiiiiiiis"; +const char CreatureDataAddonInfofmt[]="iiiiiiis"; const char CreatureModelfmt[]="iffbi"; -const char CreatureInfoAddonInfofmt[]="iiiiiiiis"; +const char CreatureInfoAddonInfofmt[]="iiiiiiis"; const char EquipmentInfofmt[]="iiii"; const char GameObjectInfosrcfmt[]="iiisssiifiiiiiiiiiiiiiiiiiiiiiiiis"; const char GameObjectInfodstfmt[]="iiisssiifiiiiiiiiiiiiiiiiiiiiiiiii"; -- cgit v1.2.3 From 2024577488134480b1f2c443732f8889fa384449 Mon Sep 17 00:00:00 2001 From: megamage Date: Tue, 12 May 2009 00:52:16 -0500 Subject: *Try to fix build in Linux. --HG-- branch : trunk --- src/game/UnitAI.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp index 76460bd8cc0..12dc20692c6 100644 --- a/src/game/UnitAI.cpp +++ b/src/game/UnitAI.cpp @@ -19,7 +19,8 @@ */ #include "UnitAI.h" -#include "Unit.h" +#include "Player.h" +#include "Creature.h" #include "SpellAuras.h" void UnitAI::AttackStart(Unit *victim) -- cgit v1.2.3 From 65b10830b84646848221833f93aded68fc78e974 Mon Sep 17 00:00:00 2001 From: megamage Date: Tue, 12 May 2009 10:01:09 -0500 Subject: *Fix a bug that arena never ends if the last player is killed with spirit of redemption talent. --HG-- branch : trunk --- src/game/BattleGround.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 7a6b96070a1..b76e0c7835c 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -1758,7 +1758,7 @@ uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const if (itr->second.Team == Team) { Player * pl = objmgr.GetPlayer(itr->first); - if (pl && pl->isAlive()) + if (pl && pl->isAlive() && !pl->HasByteFlag(UNIT_FIELD_BYTES_2, 3, FORM_SPIRITOFREDEMPTION)) ++count; } } -- cgit v1.2.3 From df4e8b456becd90ca839b8f64fbe326042aaabd9 Mon Sep 17 00:00:00 2001 From: megamage Date: Tue, 12 May 2009 10:11:54 -0500 Subject: *Move MoveFollow owner from MoveTargetedHome to enterevademode. --HG-- branch : trunk --- src/game/CreatureAI.cpp | 12 ++++++++++-- src/game/CreatureEventAI.cpp | 9 +-------- src/game/MotionMaster.cpp | 10 +--------- src/game/SpellEffects.cpp | 4 ++-- 4 files changed, 14 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 8633ee2e1f4..ea65d233a17 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -104,14 +104,22 @@ bool CreatureAI::UpdateVictim() void CreatureAI::EnterEvadeMode() { + if(me->IsInEvadeMode()) + return; + me->RemoveAllAuras(); me->DeleteThreatList(); - me->CombatStop(); + me->CombatStop(true); me->LoadCreaturesAddon(); me->SetLootRecipient(NULL); if(me->isAlive()) - me->GetMotionMaster()->MoveTargetedHome(); + { + if(Unit *owner = me->GetCharmerOrOwner()) + me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_IDLE); + else + me->GetMotionMaster()->MoveTargetedHome(); + } Reset(); } diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index fb7b7119860..470225e0da0 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -1054,14 +1054,7 @@ void CreatureEventAI::JustReachedHome() void CreatureEventAI::EnterEvadeMode() { - m_creature->RemoveAllAuras(); - m_creature->DeleteThreatList(); - m_creature->CombatStop(true); - - if (m_creature->isAlive()) - m_creature->GetMotionMaster()->MoveTargetedHome(); - - m_creature->SetLootRecipient(NULL); + CreatureAI::EnterEvadeMode(); if (bEmptyList) return; diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp index b31d3231a3b..52b9ba56e3e 100644 --- a/src/game/MotionMaster.cpp +++ b/src/game/MotionMaster.cpp @@ -203,14 +203,7 @@ MotionMaster::MoveTargetedHome() Clear(false); - if(Unit *target = i_owner->GetCharmerOrOwner()) - { - DEBUG_LOG("Pet or controlled unit (Entry: %u GUID: %u) targeting home", - i_owner->GetEntry(), i_owner->GetGUIDLow() ); - - MoveFollow(target, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_IDLE); - } - else if(i_owner->GetTypeId() == TYPEID_UNIT) + if(i_owner->GetTypeId() == TYPEID_UNIT) { DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted home", i_owner->GetEntry(), i_owner->GetGUIDLow()); Mutate(new HomeMovementGenerator(), MOTION_SLOT_ACTIVE); @@ -218,7 +211,6 @@ MotionMaster::MoveTargetedHome() else { sLog.outError("Player (GUID: %u) attempt targeted home", i_owner->GetGUIDLow() ); - return; } } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index a3401a77e21..0f04822546b 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3275,7 +3275,7 @@ void Spell::EffectSummonType(uint32 i) summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - summon->GetMotionMaster()->MoveTargetedHome(); + summon->AI()->EnterEvadeMode(); std::string name = m_originalCaster->GetName(); name.append(petTypeSuffix[3]); @@ -6423,7 +6423,7 @@ void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); - summon->GetMotionMaster()->MoveTargetedHome(); + summon->AI()->EnterEvadeMode(); } } -- cgit v1.2.3 From 722701381b7bc99483241e73b2aeb6b177e2e457 Mon Sep 17 00:00:00 2001 From: megamage Date: Tue, 12 May 2009 10:25:47 -0500 Subject: *Do not allow a spell proc itself. This fixes the crash caused by item 32500. --HG-- branch : trunk --- src/game/Unit.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 28d2fbd619b..3939877647d 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -6778,6 +6778,9 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig // Set trigger spell id, target, custom basepoints uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()]; + if(procSpell && procSpell->Id == trigger_spell_id) + return false; + Unit* target = NULL; int32 basepoints0 = 0; -- cgit v1.2.3 From 1fbc7377d1acfcee7397771c9d0def5ae345da8a Mon Sep 17 00:00:00 2001 From: megamage Date: Tue, 12 May 2009 11:16:26 -0500 Subject: *Do not show error for not assigned example scripts. --HG-- branch : trunk --- src/bindings/scripts/ScriptMgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp index 18465bfacf7..4d7ed09fff4 100644 --- a/src/bindings/scripts/ScriptMgr.cpp +++ b/src/bindings/scripts/ScriptMgr.cpp @@ -1657,7 +1657,7 @@ void Script::RegisterSelf() m_scripts[id] = this; ++num_sc_scripts; } - else + else if(Name.find("example") == std::string::npos) { error_db_log("CRASH ALERT! TrinityScript: RegisterSelf, but script named %s does not have ScriptName assigned in database.",(this)->Name.c_str()); delete this; -- cgit v1.2.3 From 8db26443d06bffa32293b64ff9f0fffcdeec99b0 Mon Sep 17 00:00:00 2001 From: Farah Date: Wed, 13 May 2009 17:05:51 +0200 Subject: *Fix Glyph of Prayer of healing --HG-- branch : trunk --- src/game/Unit.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 3939877647d..af000f67416 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5607,6 +5607,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger triggered_spell_id = 56160; break; } + // Glyph of Prayer of Healing + case 55680: + { + basepoints0 = int32(damage * 20 / 100 / 2); // divided in two ticks + triggered_spell_id = 56161; + break; + } // Improved Shadowform case 47570: case 47569: -- cgit v1.2.3 From cfe64e00e7520414339276f5c512df1024152a80 Mon Sep 17 00:00:00 2001 From: QAston Date: Wed, 13 May 2009 17:19:09 +0200 Subject: *Do not parry/dodge judgements. --HG-- branch : trunk --- src/game/Unit.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index af000f67416..95547b68621 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2809,7 +2809,9 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell) return SPELL_MISS_NONE; // Ranged attack cannot be parry/dodge only deflect - if (attType == RANGED_ATTACK) + // Check damage class instead of attack type to correctly handle judgements + // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class + if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) { // only if in front if (pVictim->HasInArc(M_PI,this)) -- cgit v1.2.3 From f1fed2d9472e8f9cb4cd2f7d570006d0bf3cfabe Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 13 May 2009 10:52:55 -0500 Subject: *Allow passive unit to call entercombat function. --HG-- branch : trunk --- sql/updates/3233_world_scripts_naxx.sql | 24 +++++++++++++++++++----- src/game/Unit.cpp | 2 +- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/sql/updates/3233_world_scripts_naxx.sql b/sql/updates/3233_world_scripts_naxx.sql index 54d6c49a82b..67a8615951d 100644 --- a/sql/updates/3233_world_scripts_naxx.sql +++ b/sql/updates/3233_world_scripts_naxx.sql @@ -44,16 +44,30 @@ INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES (27936, 1, 16060); # To Anchor 2 - Gothik INSERT INTO creature_template (entry, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8) VALUES -(16573, 15284, 28991, 28969, 34970, 28864, 0, 0, 0), # Crypt Guard -(29256, 15284, 28991, 56098, 34970, 28864, 0, 0, 0), # Crypt Guard (H) -(16506, 54095, 28732, 0, 0, 0, 0, 0, 0), # Naxxramas Worshipper -(29274, 54096, 54097, 0, 0, 0, 0, 0, 0), # Naxxramas Worshipper (H) +(16573, 15284, 28991, 28969, 34970, 0, 0, 0, 28864), # Crypt Guard +(29256, 15284, 28991, 56098, 34970, 0, 0, 0, 28864), # Crypt Guard (H) +(16506, 54095, 0, 0, 0, 0, 0, 0, 28732), # Naxxramas Worshipper +(29274, 54096, 0, 0, 0, 0, 0, 0, 54097), # Naxxramas Worshipper (H) (16984, 15496, 0, 0, 0, 0, 0, 0, 0), # Plagued Warrior (29632, 15496, 0, 0, 0, 0, 0, 0, 0), # Plagued Warrior (H) (16290, 28156, 0, 0, 0, 0, 0, 0, 0), # Fallout Slime (29388, 54367, 0, 0, 0, 0, 0, 0, 0), # Fallout Slime (H) (16803, 0, 0, 0, 61696, 29060, 29061, 0, 0), # Death Knight Understudy -(29941, 0, 0, 0, 61696, 29060, 29061, 0, 0) # Death Knight Understudy (H) +(29941, 0, 0, 0, 61696, 29060, 29061, 0, 0), # Death Knight Understudy (H) +(16124, 55604, 0, 0, 0, 0, 0, 0, 27892), # Unrelenting Trainee +(16125, 27825, 0, 0, 0, 0, 0, 0, 27928), # Unrelenting Death Knight +(16126, 27831, 55606, 0, 0, 0, 0, 0, 27935), # Unrelenting Rider +(16127, 27989, 0, 0, 0, 0, 0, 0, 0), # Spectral Trainee +(16148, 56408, 0, 0, 0, 0, 0, 0, 0), # Spectral Death Knight +(16150, 27994, 55648, 55606, 0, 0, 0, 0, 0), # Spectral Rider +(16149, 27993, 0, 0, 0, 0, 0, 0, 0), # Spectral Horse +(29985, 55645, 0, 0, 0, 0, 0, 0, 27892), # Unrelenting Trainee (H) +(29986, 27825, 0, 0, 0, 0, 0, 0, 27928), # Unrelenting Death Knight (H) +(29987, 55638, 55608, 0, 0, 0, 0, 0, 27935), # Unrelenting Rider (H) +(30264, 56407, 0, 0, 0, 0, 0, 0, 0), # Spectral Trainee (H) +(29990, 56408, 0, 0, 0, 0, 0, 0, 0), # Spectral Death Knight (H) +(29988, 55646, 27995, 55608, 0, 0, 0, 0, 0), # Spectral Rider (H) +(29989, 27993, 0, 0, 0, 0, 0, 0, 0) # Spectral Horse (H) ON DUPLICATE KEY UPDATE spell1 = VALUES(spell1), spell2 = VALUES(spell2), diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 95547b68621..259140a74de 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9958,7 +9958,7 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy) ((Creature*)this)->SetHomePosition(GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); if(enemy) { - if(!((Creature*)this)->HasReactState(REACT_PASSIVE) && ((Creature*)this)->IsAIEnabled) + if(((Creature*)this)->IsAIEnabled) ((Creature*)this)->AI()->EnterCombat(enemy); if(((Creature*)this)->GetFormation()) ((Creature*)this)->GetFormation()->MemberAttackStart((Creature*)this, enemy); -- cgit v1.2.3 From 4cf3ca42f09fc66d48740f53cb33a8f0788b8e7a Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 13 May 2009 10:53:31 -0500 Subject: *Process events for dead creatures. This allows delayed spells to work after caster is dead. --HG-- branch : trunk --- src/game/Creature.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 85109997390..f322d8326e1 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -455,6 +455,9 @@ void Creature::Update(uint32 diff) } else { + // for delayed spells + m_Events.Update( diff ); + m_deathTimer -= diff; if (m_groupLootTimer && lootingGroupLeaderGUID) { -- cgit v1.2.3 From 8994cbe08188b483c8c85a23d456003816157cad Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 13 May 2009 10:54:11 -0500 Subject: *Update some script functions. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 79 +++++++++++++++++++++------- src/bindings/scripts/include/sc_creature.h | 4 ++ src/game/AggressorAI.cpp | 2 +- src/game/CreatureAI.cpp | 55 +++++++++++-------- src/game/CreatureAI.h | 3 ++ 5 files changed, 101 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 0b874773ffc..e575e40fac1 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -17,13 +17,26 @@ struct TSpellSummary { uint8 Effects; // set of enum SelectEffect } *SpellSummary; +void SummonList::DoZoneInCombat(uint32 entry) +{ + for(iterator i = begin(); i != end();) + { + Creature *summon = Unit::GetCreature(*m_creature, *i); + ++i; + if(summon && summon->IsAIEnabled + && (!entry || summon->GetEntry() == entry)) + summon->AI()->DoZoneInCombat(); + } +} + void SummonList::DoAction(uint32 entry, uint32 info) { for(iterator i = begin(); i != end();) { Creature *summon = Unit::GetCreature(*m_creature, *i); ++i; - if(summon && summon->IsAIEnabled) + if(summon && summon->IsAIEnabled + && (!entry || summon->GetEntry() == entry)) summon->AI()->DoAction(info); } } @@ -213,6 +226,19 @@ Creature* ScriptedAI::DoSpawnCreature(uint32 id, float x, float y, float z, floa return m_creature->SummonCreature(id,m_creature->GetPositionX() + x,m_creature->GetPositionY() + y,m_creature->GetPositionZ() + z, angle, (TempSummonType)type, despawntime); } +Creature *ScriptedAI::DoSummon(uint32 entry, const float pos[4], uint32 despawntime, TempSummonType type) +{ + return me->SummonCreature(entry, pos[0], pos[1], pos[2], pos[3], type, despawntime); +} + +Creature *ScriptedAI::DoSummon(uint32 entry, WorldObject *obj, float radius, uint32 despawntime, TempSummonType type) +{ + float x, y, z; + obj->GetGroundPointAroundUnit(x, y, z, radius * rand_norm(), rand_norm()*2*M_PI); + return me->SummonCreature(entry, x, y, z, me->GetOrientation(), type, despawntime); +} + + Unit* ScriptedAI::SelectUnit(SelectAggroTarget target, uint32 position) { //ThreatList m_threatlist; @@ -493,6 +519,11 @@ void ScriptedAI::DoTeleportTo(float x, float y, float z, uint32 time) m_creature->SendMonsterMove(x, y, z, time); } +void ScriptedAI::DoTeleportTo(const float pos[4]) +{ + me->NearTeleportTo(pos[0], pos[1], pos[2], pos[3]); +} + void ScriptedAI::DoTeleportPlayer(Unit* pUnit, float x, float y, float z, float o) { if(!pUnit || pUnit->GetTypeId() != TYPEID_PLAYER) @@ -642,7 +673,8 @@ void BossAI::_EnterCombat() void BossAI::JustSummoned(Creature *summon) { summons.Summon(summon); - DoZoneInCombat(summon); + if(me->isInCombat()) + DoZoneInCombat(summon); } void BossAI::SummonedCreatureDespawn(Creature *summon) @@ -667,25 +699,36 @@ void LoadOverridenSQLData() goInfo->trap.radius = 50; } -#define SPELL(x) const_cast(GetSpellStore()->LookupEntry(x)) - void LoadOverridenDBCData() { SpellEntry *spellInfo; - - // Black Temple : Illidan : Parasitic Shadowfiend Passive - if(spellInfo = SPELL(41913)) - spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends - - //temp, not needed in 310 - if(spellInfo = SPELL(28531)) - { - spellInfo->DurationIndex = 21; - spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; - } - if(spellInfo = SPELL(55799)) + for(uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i) { - spellInfo->DurationIndex = 21; - spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; + spellInfo = (SpellEntry*)GetSpellStore()->LookupEntry(i); + if(!spellInfo) + continue; + + switch(i) + { + // Black Temple : Illidan : Parasitic Shadowfiend Passive + case 41013: + spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends + break; + //temp, not needed in 310 + case 28531: + case 55799: + spellInfo->DurationIndex = 21; + spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; + break; + // Naxxramas: Gothik : Inform Inf range + case 27892: + case 27928: + case 27935: + case 27915: + case 27931: + case 27937: + spellInfo->rangeIndex = 13; + break; + } } } diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 0fb716bbe0e..80016619e8b 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -23,6 +23,7 @@ class SummonList : private std::list void DespawnEntry(uint32 entry); void DespawnAll(); void DoAction(uint32 entry, uint32 info); + void DoZoneInCombat(uint32 entry = 0); private: Creature *m_creature; }; @@ -152,6 +153,7 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI void DoModifyThreatPercent(Unit *pUnit, int32 pct); void DoTeleportTo(float x, float y, float z, uint32 time = 0); + void DoTeleportTo(const float pos[4]); void DoAction(const int32 param) {} @@ -170,6 +172,8 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI //Spawns a creature relative to m_creature Creature* DoSpawnCreature(uint32 id, float x, float y, float z, float angle, uint32 type, uint32 despawntime); + Creature *DoSummon(uint32 entry, const float pos[4], uint32 despawntime = 30000, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN); + Creature *DoSummon(uint32 entry, WorldObject *obj, float radius = 5.0f, uint32 despawntime = 30000, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN); //Selects a unit from the creature's current aggro list Unit* SelectUnit(SelectAggroTarget target, uint32 position); diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index 286138fc991..22ebe87cdc6 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -104,7 +104,7 @@ void SpellAI::UpdateAI(const uint32 diff) break; } } - me->CastSpell(target, spellId, false); + if(target) me->CastSpell(target, spellId, false); events.ScheduleEvent(spellId, AISpellInfo[spellId].cooldown + rand()%AISpellInfo[spellId].cooldown); } else diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index ea65d233a17..0864bc973ab 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -39,6 +39,9 @@ void CreatureAI::DoZoneInCombat(Creature* creature) if (!creature) creature = me; + if(!creature->CanHaveThreatList()) + return; + Map *map = creature->GetMap(); if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated { @@ -46,7 +49,7 @@ void CreatureAI::DoZoneInCombat(Creature* creature) return; } - if(!creature->getVictim()) + if(!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim()) { if(Unit *target = creature->SelectNearestTarget()) creature->AI()->AttackStart(target); @@ -54,29 +57,30 @@ void CreatureAI::DoZoneInCombat(Creature* creature) { if(Unit *summoner = ((TempSummon*)creature)->GetSummoner()) { - if(summoner->getVictim() - && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(summoner->getVictim()))) - creature->AI()->AttackStart(summoner->getVictim()); + Unit *target = summoner->getAttackerForHelper(); + if(!target && summoner->CanHaveThreatList() && !summoner->getThreatManager().isThreatListEmpty()) + target = summoner->getThreatManager().getHostilTarget(); + if(target && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(target))) + creature->AI()->AttackStart(target); } } } - if (!creature->CanHaveThreatList() || !creature->getVictim()) + if(!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim()) { - sLog.outError("DoZoneInCombat called for creature that either cannot have threat list or has empty threat list (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? ((Creature*)creature)->GetEntry() : 0); + sLog.outError("DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry()); return; } Map::PlayerList const &PlayerList = map->GetPlayers(); for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { - if (Player* i_pl = i->getSource()) - if (i_pl->isAlive()) - { - creature->SetInCombatWith(i_pl); - i_pl->SetInCombatWith(creature); - creature->AddThreat(i_pl, 0.0f); - } + if (i->getSource()->isAlive()) + { + creature->SetInCombatWith(i->getSource()); + i->getSource()->SetInCombatWith(creature); + creature->AddThreat(i->getSource(), 0.0f); + } } } @@ -102,10 +106,10 @@ bool CreatureAI::UpdateVictim() return me->getVictim(); } -void CreatureAI::EnterEvadeMode() +bool CreatureAI::_EnterEvadeMode() { - if(me->IsInEvadeMode()) - return; + if(me->IsInEvadeMode() || !me->isAlive()) + return false; me->RemoveAllAuras(); me->DeleteThreatList(); @@ -113,13 +117,18 @@ void CreatureAI::EnterEvadeMode() me->LoadCreaturesAddon(); me->SetLootRecipient(NULL); - if(me->isAlive()) - { - if(Unit *owner = me->GetCharmerOrOwner()) - me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_IDLE); - else - me->GetMotionMaster()->MoveTargetedHome(); - } + return true; +} + +void CreatureAI::EnterEvadeMode() +{ + if(!_EnterEvadeMode()) + return; + + if(Unit *owner = me->GetCharmerOrOwner()) + me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_IDLE); + else + me->GetMotionMaster()->MoveTargetedHome(); Reset(); } diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index 605e904c71a..c46dd2a54f2 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -168,6 +168,9 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI static AISpellInfoType *AISpellInfo; static void FillAISpellInfo(); + + protected: + bool _EnterEvadeMode(); }; enum Permitions -- cgit v1.2.3 From 80c19013432ec49fb5c1b57bf2d5aca7be0d53c7 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 13 May 2009 10:59:00 -0500 Subject: *Add script for Gothik. Please apply 3233_world_scripts_naxx.sql for new contents. --HG-- branch : trunk --- sql/updates/3233_world_scripts_naxx.sql | 1 + sql/world_scripts_full.sql | 1 + src/bindings/scripts/ScriptMgr.cpp | 2 + .../scripts/scripts/zone/naxxramas/boss_gothik.cpp | 361 +++++++++++++++++++-- .../scripts/zone/naxxramas/instance_naxxramas.cpp | 8 +- 5 files changed, 338 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/sql/updates/3233_world_scripts_naxx.sql b/sql/updates/3233_world_scripts_naxx.sql index 67a8615951d..a5a71ba6233 100644 --- a/sql/updates/3233_world_scripts_naxx.sql +++ b/sql/updates/3233_world_scripts_naxx.sql @@ -6,6 +6,7 @@ INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comm (-28169, 28240, 0, 'Mutating Injection - Poison Cloud'); UPDATE creature_template SET scriptname = 'boss_grobbulus' WHERE entry = 15931; +update creature_template set scriptname='mob_gothik_minion' where entry in (16124,16125,16126,16127,16148,16149,16150); INSERT INTO creature_template (entry, spell1, flags_extra, scriptname) VALUES (16363, 28158, 128, ''), # Grobbulus Cloud diff --git a/sql/world_scripts_full.sql b/sql/world_scripts_full.sql index a1df130d207..8b28c3bc370 100644 --- a/sql/world_scripts_full.sql +++ b/sql/world_scripts_full.sql @@ -645,6 +645,7 @@ UPDATE `creature_template` SET `ScriptName`='boss_heigan' WHERE `entry`=15936; UPDATE `creature_template` SET `ScriptName`='boss_loatheb' WHERE `entry`=16011; UPDATE `creature_template` SET `ScriptName`='boss_razuvious' WHERE `entry`=16061; UPDATE `creature_template` SET `ScriptName`='boss_gothik' WHERE `entry`=16060; +UPDATE `creature_template` SET `ScriptName`='mob_gothik_minion' where `entry` IN (16124,16125,16126,16127,16148,16149,16150); UPDATE `creature_template` SET `ScriptName`='boss_thane_korthazz' WHERE `entry`=16064; UPDATE `creature_template` SET `ScriptName`='boss_sir_zeliek' WHERE `entry`=16063; UPDATE `creature_template` SET `ScriptName`='boss_lady_blaumeux' WHERE `entry`=16065; diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp index 4d7ed09fff4..849c4d64be5 100644 --- a/src/bindings/scripts/ScriptMgr.cpp +++ b/src/bindings/scripts/ScriptMgr.cpp @@ -389,6 +389,7 @@ extern void AddSC_boss_sapphiron(); extern void AddSC_boss_four_horsemen(); extern void AddSC_boss_faerlina(); extern void AddSC_boss_heigan(); +extern void AddSC_boss_gothik(); extern void AddSC_instance_naxxramas(); //Netherstorm @@ -1327,6 +1328,7 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf") AddSC_boss_sapphiron(); AddSC_boss_four_horsemen(); AddSC_boss_heigan(); + AddSC_boss_gothik(); AddSC_instance_naxxramas(); //Netherstorm diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp index 3a9c6a5b47a..7def6c370f4 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2008 - 2009 Trinity * 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 @@ -14,14 +14,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Gothik -SD%Complete: 0 -SDComment: Placeholder -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" +#include "def_naxxramas.h" #define SAY_SPEECH -1533040 #define SAY_KILL -1533041 @@ -29,37 +23,336 @@ EndScriptData */ #define SAY_TELEPORT -1533043 //Gothik -#define SPELL_HARVESTSOUL 28679 -#define SPELL_SHADOWBOLT HEROIC(29317,56405) -#define SPELL_SOUL_SIPHON 43591 // cannot find the correct spell +#define SPELL_HARVEST_SOUL 28679 +#define SPELL_SHADOW_BOLT HEROIC(29317,56405) + +#define SPELL_INFORM_LIVE_TRAINEE 27892 +#define SPELL_INFORM_LIVE_KNIGHT 27928 +#define SPELL_INFORM_LIVE_RIDER 27935 +#define SPELL_INFORM_DEAD_TRAINEE 27915 +#define SPELL_INFORM_DEAD_KNIGHT 27931 +#define SPELL_INFORM_DEAD_RIDER 27937 + +#define MOB_LIVE_TRAINEE 16124 +#define MOB_LIVE_KNIGHT 16125 +#define MOB_LIVE_RIDER 16126 +#define MOB_DEAD_TRAINEE 16127 +#define MOB_DEAD_KNIGHT 16148 +#define MOB_DEAD_RIDER 16150 +#define MOB_DEAD_HORSE 16149 + +const struct Waves { uint32 entry, number, time; } +waves[] = +{ + {MOB_LIVE_TRAINEE, 2, 20000}, + {MOB_LIVE_TRAINEE, 2, 20000}, + {MOB_LIVE_TRAINEE, 2, 10000}, + {MOB_LIVE_KNIGHT, 1, 10000}, + {MOB_LIVE_TRAINEE, 2, 15000}, + {MOB_LIVE_KNIGHT, 1, 10000}, + {MOB_LIVE_TRAINEE, 2, 15000}, + {MOB_LIVE_TRAINEE, 2, 0}, + {MOB_LIVE_KNIGHT, 1, 10000}, + {MOB_LIVE_RIDER, 1, 10000}, + {MOB_LIVE_TRAINEE, 2, 5000}, + {MOB_LIVE_KNIGHT, 1, 15000}, + {MOB_LIVE_TRAINEE, 2, 0}, + {MOB_LIVE_RIDER, 1, 10000}, + {MOB_LIVE_KNIGHT, 2, 10000}, + {MOB_LIVE_TRAINEE, 2, 10000}, + {MOB_LIVE_RIDER, 1, 5000}, + {MOB_LIVE_KNIGHT, 1, 5000}, + {MOB_LIVE_TRAINEE, 2, 20000}, + {MOB_LIVE_TRAINEE, 2, 0}, + {MOB_LIVE_KNIGHT, 1, 0}, + {MOB_LIVE_RIDER, 1, 15000}, + {MOB_LIVE_TRAINEE, 2, 29000}, + {0, 0, 0}, +}; + +#define POS_Y_GATE -3360.78f + +enum Events +{ + EVENT_SUMMON = 1, + EVENT_HARVEST, + EVENT_BOLT, +}; + +#define POS_LIVE 3 +#define POS_DEAD 5 + +const float PosSummonLive[POS_LIVE][4] = +{ + {2669.7, -3430.9, 268.56, 1.6}, + {2692.0, -3430.9, 268.56, 1.6}, + {2714.1, -3430.9, 268.56, 1.6}, +}; + +const float PosSummonDead[POS_DEAD][4] = +{ + {2725.1, -3310.0, 268.85, 3.4}, + {2699.3, -3322.8, 268.60, 3.3}, + {2733.1, -3348.5, 268.84, 3.1}, + {2682.8, -3304.2, 268.85, 3.9}, + {2664.8, -3340.7, 268.23, 3.7}, +}; + +const float PosGround[4] = {2691.2, -3362.7, 267.68, 1.7}; +const float PosPlatform[4] = {2640.5, -3360.6, 285.26, 0}; + +struct TRINITY_DLL_DECL boss_gothikAI : public BossAI +{ + boss_gothikAI(Creature *c) : BossAI(c, BOSS_GOTHIK) {} + + uint32 waveCount; + std::vector liveTrigger; + std::vector deadTrigger; + + void Reset() + { + liveTrigger.clear(); + deadTrigger.clear(); + me->setActive(false); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + me->SetReactState(REACT_PASSIVE); + _Reset(); + } + + void EnterCombat(Unit *who) + { + for(uint32 i = 0; i < POS_LIVE; ++i) + if(Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonLive[i])) + liveTrigger.push_back(trigger); + for(uint32 i = 0; i < POS_DEAD; ++i) + if(Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonDead[i])) + deadTrigger.push_back(trigger); + + if(liveTrigger.size() < POS_LIVE || deadTrigger.size() < POS_DEAD) + { + error_log("Script Gothik: cannot summon triggers!"); + EnterEvadeMode(); + return; + } + + _EnterCombat(); + me->setActive(true); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + waveCount = 0; + events.ScheduleEvent(EVENT_SUMMON, 30000); + DoTeleportTo(PosPlatform); + DoScriptText(SAY_SPEECH, me); + if(instance) + instance->SetData(DATA_GOTHIK_GATE, 1); + } + + void JustSummoned(Creature *summon) + { + if(summon->GetEntry() == WORLD_TRIGGER) + summon->setActive(true); + else + { + summon->AI()->DoAction(me->HasReactState(REACT_PASSIVE) ? 1 : 0); + summon->AI()->EnterEvadeMode(); + } + summons.Summon(summon); + } + + void KilledUnit(Unit* victim) + { + if(!(rand()%5)) + DoScriptText(SAY_KILL, me); + } + + void JustDied(Unit* Killer) + { + _JustDied(); + DoScriptText(SAY_DEATH, me); + } + + void SpellHit(Unit *caster, const SpellEntry *spell) + { + uint32 spellId = 0; + switch(spell->Id) + { + case SPELL_INFORM_LIVE_TRAINEE: spellId = SPELL_INFORM_DEAD_TRAINEE; break; + case SPELL_INFORM_LIVE_KNIGHT: spellId = SPELL_INFORM_DEAD_KNIGHT; break; + case SPELL_INFORM_LIVE_RIDER: spellId = SPELL_INFORM_DEAD_RIDER; break; + } + if(spellId && me->isInCombat()) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST); + me->CastSpell(deadTrigger[rand()%POS_DEAD], spellId, true); + } + } + + void SpellHitTarget(Unit *target, const SpellEntry *spell) + { + if(!me->isInCombat()) + return; + + switch(spell->Id) + { + case SPELL_INFORM_DEAD_TRAINEE: DoSummon(MOB_DEAD_TRAINEE, target, 0); break; + case SPELL_INFORM_DEAD_KNIGHT: DoSummon(MOB_DEAD_KNIGHT, target, 0); break; + case SPELL_INFORM_DEAD_RIDER: DoSummon(MOB_DEAD_RIDER, target, 1.0f); + DoSummon(MOB_DEAD_HORSE, target, 1.0f); break; + } + } + + void UpdateAI(const uint32 diff) + { + if(!me->isInCombat()) + return; + + if(me->getThreatManager().isThreatListEmpty()) + { + EnterEvadeMode(); + return; + } + + if(me->HasReactState(REACT_AGGRESSIVE) && !UpdateVictim()) + return; + + events.Update(diff); + + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + + while(uint32 eventId = events.ExecuteEvent()) + { + switch(eventId) + { + case EVENT_SUMMON: + if(waves[waveCount].entry) + { + for(uint32 i = 0; i < waves[waveCount].number; ++i) + DoSummon(waves[waveCount].entry, liveTrigger[rand()%POS_LIVE], 1.0f); + events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); + ++waveCount; + } + else + { + DoScriptText(SAY_TELEPORT, me); + DoTeleportTo(PosGround); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + if(instance) + instance->SetData(DATA_GOTHIK_GATE, 0); + summons.DoAction(0, 0); + summons.DoZoneInCombat(); + events.ScheduleEvent(EVENT_BOLT, 1000); + events.ScheduleEvent(EVENT_HARVEST, 15000); + } + break; + case EVENT_BOLT: + DoCast(me->getVictim(), SPELL_SHADOW_BOLT); + events.ScheduleEvent(EVENT_BOLT, 1000); + return; + case EVENT_HARVEST: + DoCast(me->getVictim(), SPELL_HARVEST_SOUL); + events.ScheduleEvent(EVENT_HARVEST, 15000); + return; + } + } + + DoMeleeAttackIfReady(); + } +}; + +struct TRINITY_DLL_DECL mob_gothik_minionAI : public SpellAI +{ + mob_gothik_minionAI(Creature *c) : SpellAI(c) + { + liveSide = me->GetPositionY() < POS_Y_GATE; + } + + bool liveSide; + bool gateClose; + +#define SIDE_CHECK(who) (liveSide == (who->GetPositionY() < POS_Y_GATE)) + + void DoAction(const int32 param) + { + gateClose = param; + } + + void DamageTaken(Unit *attacker, uint32 &damage) + { + if(gateClose && !SIDE_CHECK(attacker)) + damage = 0; + } + + void JustDied(Unit *killer) + { + if(me->isSummon()) + { + if(Unit *owner = ((TempSummon*)me)->GetSummoner()) + SpellAI::JustDied(owner); + } + } + + void EnterEvadeMode() + { + if(!gateClose) + { + SpellAI::EnterEvadeMode(); + return; + } + + if(!_EnterEvadeMode()) + return; -//Unrelenting Trainee -#define SPELL_EAGLECLAW 30285 -#define SPELL_KNOCKDOWN_PASSIVE 6961 + Map *map = me->GetMap(); + if(map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if(i->getSource()->isAlive() && SIDE_CHECK(i->getSource())) + { + AttackStart(i->getSource()); + return; + } + } + } -//Unrelenting Deathknight -#define SPELL_CHARGE 22120 -#define SPELL_SHADOW_MARK 27825 + me->GetMotionMaster()->MoveIdle(); + Reset(); + } -//Unrelenting Rider -#define SPELL_UNHOLY_AURA 55606 -#define H_SPELL_UNHOLY_AURA 55608 -#define SPELL_SHADOWBOLT_VOLLEY 27831 //Search thru targets and find those who have the SHADOW_MARK to cast this on -#define H_SPELL_SHADOWBOLT_VOLLEY 55638 + void UpdateAI(const uint32 diff) + { + if(gateClose && (!SIDE_CHECK(me) || me->getVictim() && !SIDE_CHECK(me->getVictim()))) + { + EnterEvadeMode(); + return; + } -//Spectral Trainee -#define SPELL_ARCANE_EXPLOSION 27989 + SpellAI::UpdateAI(diff); + } +}; -//Spectral Deathknight -#define SPELL_WHIRLWIND 28334 -#define SPELL_SUNDER_ARMOR 25051 //cannot find sunder that reduces armor by 2950 -#define SPELL_CLEAVE 20677 -#define SPELL_MANA_BURN 17631 +CreatureAI* GetAI_boss_gothik(Creature *_Creature) +{ + return new boss_gothikAI (_Creature); +} -//Spectral Rider -#define SPELL_LIFEDRAIN 24300 -//USES SAME UNHOLY AURA AS UNRELENTING RIDER +CreatureAI* GetAI_mob_gothik_minion(Creature *_Creature) +{ + return new mob_gothik_minionAI (_Creature); +} -//Spectral Horse -#define SPELL_STOMP 27993 +void AddSC_boss_gothik() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_gothik"; + newscript->GetAI = &GetAI_boss_gothik; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name="mob_gothik_minion"; + newscript->GetAI = &GetAI_mob_gothik_minion; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index 23f44f5daf8..e5913660c3f 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -86,9 +86,10 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData LoadDoorData(doorData); } + std::set Worshipper; std::set HeiganEruption[4]; + GameObject *GothikGate; Creature *Sapphiron; - std::set Worshipper; void OnCreatureCreate(Creature *creature, bool add) { @@ -114,6 +115,7 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData switch(go->GetEntry()) { case GO_BIRTH: if(!add && Sapphiron) Sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); return; + case GO_GOTHIK_GATE: GothikGate = add ? go : NULL; break; } AddDoor(go, add); @@ -140,6 +142,10 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData case DATA_HEIGAN_ERUPT: HeiganErupt(value); break; + case DATA_GOTHIK_GATE: + if(GothikGate) + GothikGate->SetGoState(GOState(value)); + break; } } -- cgit v1.2.3 From 90561654534ed4ecbf169f1da52a87baf2f543df Mon Sep 17 00:00:00 2001 From: QAston Date: Wed, 13 May 2009 18:00:07 +0200 Subject: *Fix sudden death proc execute damage. --HG-- branch : trunk --- src/game/SpellEffects.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 0f04822546b..4f8a25698e3 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1350,24 +1350,29 @@ void Spell::EffectDummy(uint32 i) if(!unitTarget) return; - uint32 rage = m_caster->GetPower(POWER_RAGE); + uint32 rage=0; // Glyph of Execution bonus if (AuraEffect *aura = m_caster->GetDummyAura(58367)) rage+=aura->GetAmount(); spell_id = 20647; - bp = damage+int32(rage * m_spellInfo->DmgMultiplier[i] + - m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); // Sudden death cost modifier if (Aura * aur = m_caster->GetAura(52437)) { + rage += m_powerCost; m_caster->ModifyPower(POWER_RAGE,- m_powerCost); if (m_caster->GetPower(POWER_RAGE)<100) m_caster->SetPower(POWER_RAGE,100); m_caster->RemoveAura(aur); } else + { + rage += m_caster->GetPower(POWER_RAGE); m_caster->SetPower(POWER_RAGE,0); + } + + bp = damage+int32(rage * m_spellInfo->DmgMultiplier[i] + + m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); break; } // Slam -- cgit v1.2.3 From 9aab3899376258c09b7caab7743494495b6374a1 Mon Sep 17 00:00:00 2001 From: QAston Date: Wed, 13 May 2009 18:32:32 +0200 Subject: *Better fix for judgements --HG-- branch : trunk --- src/game/Unit.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 95547b68621..f142ea623a5 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2767,7 +2767,9 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell) { WeaponAttackType attType = BASE_ATTACK; - if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED && IsRangedWeaponSpell(spell)) + // Check damage class instead of attack type to correctly handle judgements + // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class + if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) attType = RANGED_ATTACK; // bonus from skills is 0.04% per skill Diff @@ -2809,9 +2811,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell) return SPELL_MISS_NONE; // Ranged attack cannot be parry/dodge only deflect - // Check damage class instead of attack type to correctly handle judgements - // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class - if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) + if (attType == RANGED_ATTACK) { // only if in front if (pVictim->HasInArc(M_PI,this)) -- cgit v1.2.3 From 9dd5a1c6d7a6656b8ec71ff33659acd2294633ad Mon Sep 17 00:00:00 2001 From: Anubisss Date: Wed, 13 May 2009 18:37:02 +0200 Subject: *Better way in Glyph of Prayer of Healing. --HG-- branch : trunk --- src/game/Unit.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 66576396dfa..aacdc9aff52 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5612,8 +5612,26 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger // Glyph of Prayer of Healing case 55680: { - basepoints0 = int32(damage * 20 / 100 / 2); // divided in two ticks triggered_spell_id = 56161; + + SpellEntry const* GoPoH = sSpellStore.LookupEntry(triggered_spell_id); + if(!GoPoH) + return false; + + int EffIndex = 0; + for(int i = 0; i < MAX_SPELL_EFFECTS; i++) + { + if(GoPoH->Effect[i] == SPELL_EFFECT_APPLY_AURA) + { + EffIndex = i; + break; + } + } + int32 tickcount = GetSpellMaxDuration(GoPoH) / GoPoH->EffectAmplitude[EffIndex]; + if(!tickcount) + return false; + + basepoints0 = damage * triggerAmount / tickcount / 100; break; } // Improved Shadowform -- cgit v1.2.3 From 25e5c99dec793dfcc45a41873af1760392ee8844 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 13 May 2009 18:22:21 -0500 Subject: [7810] Moved ZThread related code on ACE framework. Author: Ambal Remove ZThread source code from mangos. --HG-- branch : trunk --- Makefile.am | 9 +- configure.ac | 1 - dep/include/Makefile.am | 48 -- dep/src/Makefile.am | 2 +- dep/src/zthread/AtomicCount.cxx | 57 -- src/bindings/scripts/VC80/80ScriptDev2.vcproj | 16 +- src/bindings/scripts/VC90/90ScriptDev2.vcproj | 16 +- src/framework/Platform/Define.h | 6 + src/game/InstanceSaveMgr.h | 4 +- src/game/Map.h | 23 +- src/game/MapManager.cpp | 4 +- src/game/MapManager.h | 6 +- src/game/ObjectAccessor.cpp | 6 +- src/game/ObjectAccessor.h | 12 +- src/game/SharedDefines.h | 3 - src/game/World.h | 4 +- src/game/WorldLog.cpp | 4 +- src/game/WorldLog.h | 4 +- src/game/WorldSession.h | 3 +- src/shared/Common.h | 12 +- src/shared/Database/Database.cpp | 3 +- src/shared/Database/Database.h | 9 +- src/shared/Database/DatabaseImpl.h | 4 +- src/shared/Database/DatabaseMysql.cpp | 29 +- src/shared/Database/DatabaseMysql.h | 7 +- src/shared/Database/DatabasePostgre.cpp | 31 +- src/shared/Database/DatabasePostgre.h | 7 +- src/shared/Database/QueryResult.h | 2 +- src/shared/Database/SqlDelayThread.cpp | 2 +- src/shared/Database/SqlDelayThread.h | 15 +- src/shared/Database/SqlOperations.h | 7 +- src/shared/Log.h | 2 +- src/shared/Makefile.am | 3 + src/shared/Util.cpp | 20 +- src/trinitycore/CliRunnable.cpp | 4 +- src/trinitycore/CliRunnable.h | 2 +- src/trinitycore/Makefile.am | 5 + src/trinitycore/Master.cpp | 20 +- src/trinitycore/WorldRunnable.cpp | 2 +- src/trinitycore/WorldRunnable.h | 2 +- src/trinityrealm/AuthSocket.cpp | 16 +- src/trinityrealm/AuthSocket.h | 3 +- src/trinityrealm/Makefile.am | 5 + win/TrinityCore&Script VC71.sln | 4 - win/TrinityCore&Script VC80.sln | 2 - win/TrinityCore&Script VC90.sln | 2 - win/VC71/ScriptsInterfaces.vcproj | 14 + win/VC71/TrinityCore.vcproj | 6 +- win/VC71/TrinityRealm.vcproj | 45 +- win/VC71/shared.vcproj | 41 ++ win/VC71/zthread.vcproj | 381 ------------ win/VC80/ScriptsInterfaces.vcproj | 44 +- win/VC80/TrinityCore.vcproj | 58 +- win/VC80/TrinityRealm.vcproj | 94 +-- win/VC80/shared.vcproj | 18 + win/VC90/ScriptsInterfaces.vcproj | 40 +- win/VC90/TrinityCore.vcproj | 58 +- win/VC90/TrinityRealm.vcproj | 94 +-- win/VC90/shared.vcproj | 18 + win/VC90/zthread.vcproj | 799 -------------------------- 60 files changed, 489 insertions(+), 1669 deletions(-) delete mode 100644 dep/src/zthread/AtomicCount.cxx delete mode 100644 win/VC71/zthread.vcproj delete mode 100644 win/VC90/zthread.vcproj (limited to 'src') diff --git a/Makefile.am b/Makefile.am index c7da2a438ef..eb58ac488f2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,8 +31,7 @@ EXTRA_DIST = \ win/VC71/realmd.vcproj \ win/VC71/shared.vcproj \ win/VC71/zlib.vcproj \ - win/VC71/g3dlite.vcproj \ - win/VC71/zthread.vcproj + win/VC71/g3dlite.vcproj # Win32 project workspace for Visual Studio .NET 2005 EXTRA_DIST += \ @@ -43,8 +42,7 @@ EXTRA_DIST += \ win/VC80/realmd.vcproj \ win/VC80/shared.vcproj \ win/VC80/zlib.vcproj \ - win/VC80/g3dlite.vcproj \ - win/VC80/zthread.vcproj + win/VC80/g3dlite.vcproj # Win32 project workspace for Visual Studio .NET 2008 EXTRA_DIST += \ @@ -55,6 +53,5 @@ EXTRA_DIST += \ win/VC90/realmd.vcproj \ win/VC90/shared.vcproj \ win/VC90/zlib.vcproj \ - win/VC90/g3dlite.vcproj \ - win/VC90/zthread.vcproj + win/VC90/g3dlite.vcproj diff --git a/configure.ac b/configure.ac index ede1118be95..d1ec818ac99 100644 --- a/configure.ac +++ b/configure.ac @@ -340,7 +340,6 @@ AC_CONFIG_FILES([ dep/src/g3dlite/Makefile dep/src/sockets/Makefile dep/src/zlib/Makefile - dep/src/zthread/Makefile dep/Makefile doc/Doxyfile doc/Makefile diff --git a/dep/include/Makefile.am b/dep/include/Makefile.am index 3991d1e6274..455f0a81307 100644 --- a/dep/include/Makefile.am +++ b/dep/include/Makefile.am @@ -199,54 +199,6 @@ EXTRA_DIST += \ zlib/zconf.h \ zlib/zlib.h -# ZThread header files for Win32 builds -EXTRA_DIST += \ - zthread/AtomicCount.h \ - zthread/Barrier.h \ - zthread/BiasedReadWriteLock.h \ - zthread/BlockingQueue.h \ - zthread/BoundedQueue.h \ - zthread/Cancelable.h \ - zthread/ClassLockable.h \ - zthread/ConcurrentExecutor.h \ - zthread/Condition.h \ - zthread/Config.h \ - zthread/CountedPtr.h \ - zthread/CountingSemaphore.h \ - zthread/Exceptions.h \ - zthread/Executor.h \ - zthread/FairReadWriteLock.h \ - zthread/FastMutex.h \ - zthread/FastRecursiveMutex.h \ - zthread/Guard.h \ - zthread/GuardedClass.h \ - zthread/Lockable.h \ - zthread/LockedQueue.h \ - zthread/MonitoredQueue.h \ - zthread/Mutex.h \ - zthread/NonCopyable.h \ - zthread/PoolExecutor.h \ - zthread/Priority.h \ - zthread/PriorityCondition.h \ - zthread/PriorityInheritanceMutex.h \ - zthread/PriorityMutex.h \ - zthread/PrioritySemaphore.h \ - zthread/Queue.h \ - zthread/ReadWriteLock.h \ - zthread/RecursiveMutex.h \ - zthread/Runnable.h \ - zthread/Semaphore.h \ - zthread/Singleton.h \ - zthread/SynchronousExecutor.h \ - zthread/Task.h \ - zthread/Thread.h \ - zthread/ThreadLocal.h \ - zthread/ThreadLocalImpl.h \ - zthread/ThreadedExecutor.h \ - zthread/Time.h \ - zthread/Waitable.h \ - zthread/ZThread.h - # Mersenne Twister random number generator header files EXTRA_DIST += \ mersennetwister/MersenneTwister.h diff --git a/dep/src/Makefile.am b/dep/src/Makefile.am index 6ae2808895c..50814f8ff13 100644 --- a/dep/src/Makefile.am +++ b/dep/src/Makefile.am @@ -19,7 +19,7 @@ ## Process this file with automake to produce Makefile.in ## Sub-directories to parse -SUBDIRS = g3dlite sockets zlib zthread +SUBDIRS = g3dlite sockets zlib ## Additional files to include when running 'make dist' # Nothing yet. diff --git a/dep/src/zthread/AtomicCount.cxx b/dep/src/zthread/AtomicCount.cxx deleted file mode 100644 index ac0d0773b12..00000000000 --- a/dep/src/zthread/AtomicCount.cxx +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2005, Eric Crahen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __ZTATOMICCOUNTSELECT_H__ -#define __ZTATOMICCOUNTSELECT_H__ - -#include "zthread/AtomicCount.h" -#include "zthread/Config.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* -// Select the correct AtomicCount implementation based on -// what the compilation environment has defined - -#ifndef ZT_VANILLA - -#if defined(HAVE_ATOMIC_LINUX) -# include "linux/AtomicCount.cxx" -#elif defined(ZT_WIN32) -# include "win32/AtomicCount.cxx" -#elif defined(ZT_WIN9X) -# include "win9x/AtomicCount.cxx" -#endif - -#endif - -// Default to an AtomicCount that just uses a FastLock -#ifndef __ZTATOMICCOUNTIMPL_H__ -# include "vanilla/SimpleAtomicCount.cxx" -#endif -*/ - -# include "vanilla/SimpleAtomicCount.cxx" - -#endif // __ZTATOMICCOUNTSELECT_H__ diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj index c442ae52a2d..28875c526ab 100644 --- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj +++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj @@ -68,10 +68,10 @@ /> #include #include "Utilities/UnorderedMap.h" @@ -113,7 +113,7 @@ class InstanceSave bool m_canReset; }; -class TRINITY_DLL_DECL InstanceSaveManager : public Trinity::Singleton > +class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::Singleton > { friend class InstanceSave; public: diff --git a/src/game/Map.h b/src/game/Map.h index d85eb459171..a4309504435 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -23,9 +23,9 @@ #include "Platform/Define.h" #include "Policies/ThreadingModel.h" -#include "zthread/Lockable.h" -#include "zthread/Mutex.h" -#include "zthread/FairReadWriteLock.h" +#include "ace/RW_Thread_Mutex.h" +#include "ace/Thread_Mutex.h" + #include "DBCStructure.h" #include "GridDefines.h" #include "Cell.h" @@ -46,13 +46,8 @@ class WorldObject; class TempSummon; class CreatureGroup; -namespace ZThread -{ - class Lockable; - class ReadWriteLock; -} -typedef ZThread::FairReadWriteLock GridRWLock; +typedef ACE_RW_Thread_Mutex GridRWLock; template struct RGuard @@ -68,9 +63,9 @@ struct WGuard Trinity::GeneralLock i_lock; }; -typedef RGuard GridReadGuard; -typedef WGuard GridWriteGuard; -typedef Trinity::SingleThreaded::Lock NullGuard; +typedef RGuard GridReadGuard; +typedef WGuard GridWriteGuard; +typedef MaNGOS::SingleThreaded::Lock NullGuard; //****************************************** // Map file format defines @@ -251,7 +246,7 @@ typedef UNORDERED_MAP CreatureMoveList; typedef std::map CreatureGroupHolderType; -class TRINITY_DLL_SPEC Map : public GridRefManager, public Trinity::ObjectLevelLockable +class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::ObjectLevelLockable { friend class MapReference; public: @@ -466,7 +461,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager, public Trinity::O protected: void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } - typedef Trinity::ObjectLevelLockable::Lock Guard; + typedef MaNGOS::ObjectLevelLockable::Lock Guard; MapEntry const* i_mapEntry; uint8 i_spawnMode; diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 061e0252a13..d75ba22b19a 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -34,9 +34,9 @@ #include "ObjectMgr.h" #include "Language.h" -#define CLASS_LOCK Trinity::ClassLevelLockable +#define CLASS_LOCK MaNGOS::ClassLevelLockable INSTANTIATE_SINGLETON_2(MapManager, CLASS_LOCK); -INSTANTIATE_CLASS_MUTEX(MapManager, ZThread::Mutex); +INSTANTIATE_CLASS_MUTEX(MapManager, ACE_Thread_Mutex); extern GridState* si_GridStates[]; // debugging code, should be deleted some day diff --git a/src/game/MapManager.h b/src/game/MapManager.h index 143248de162..b54c1cfbfa1 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -23,14 +23,14 @@ #include "Platform/Define.h" #include "Policies/Singleton.h" -#include "zthread/Mutex.h" +#include "ace/Thread_Mutex.h" #include "Common.h" #include "Map.h" #include "GridStates.h" class Transport; -class TRINITY_DLL_DECL MapManager : public Trinity::Singleton > +class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton > { friend class Trinity::OperatorNew; @@ -149,7 +149,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singletonsecond); } - typedef Trinity::ClassLevelLockable::Lock Guard; + typedef MaNGOS::ClassLevelLockable::Lock Guard; uint32 i_gridCleanUpDelay; MapMapType i_maps; IntervalTimer i_timer; diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 1fa0bd6d1ca..da6279e068a 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -41,9 +41,9 @@ #include -#define CLASS_LOCK Trinity::ClassLevelLockable +#define CLASS_LOCK MaNGOS::ClassLevelLockable INSTANTIATE_SINGLETON_2(ObjectAccessor, CLASS_LOCK); -INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ZThread::FastMutex); +INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ACE_Thread_Mutex); ObjectAccessor::ObjectAccessor() {} ObjectAccessor::~ObjectAccessor() {} @@ -470,7 +470,7 @@ ObjectAccessor::UpdateObjectVisibility(WorldObject *obj) /// Define the static member of HashMapHolder template UNORDERED_MAP< uint64, T* > HashMapHolder::m_objectMap; -template ZThread::FastMutex HashMapHolder::i_lock; +template ACE_Thread_Mutex HashMapHolder::i_lock; /// Global definitions for the hashmap storage diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index dd8e02b81ab..f4452b81cab 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -23,7 +23,7 @@ #include "Platform/Define.h" #include "Policies/Singleton.h" -#include "zthread/FastMutex.h" +#include #include "Utilities/UnorderedMap.h" #include "Policies/ThreadingModel.h" @@ -51,8 +51,8 @@ class HashMapHolder public: typedef UNORDERED_MAP< uint64, T* > MapType; - typedef ZThread::FastMutex LockType; - typedef Trinity::GeneralLock Guard; + typedef ACE_Thread_Mutex LockType; + typedef MaNGOS::GeneralLock Guard; static void Insert(T* o) { m_objectMap[o->GetGUID()] = o; } @@ -80,7 +80,7 @@ class HashMapHolder static MapType m_objectMap; }; -class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton > +class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton > { friend class Trinity::OperatorNew; @@ -228,8 +228,8 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton Guard; + typedef ACE_Thread_Mutex LockType; + typedef MaNGOS::GeneralLock Guard; static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &); static void _buildPacket(Player *, Object *, UpdateDataMapType &); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index e592bebf1de..a068815bb1c 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -24,9 +24,6 @@ #include "Platform/Define.h" #include -#define MaNGOS Trinity -#define GetMangosString GetTrinityString - enum Gender { GENDER_MALE = 0, diff --git a/src/game/World.h b/src/game/World.h index 27075885368..80d5717f981 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -626,7 +626,7 @@ class World static float m_VisibleObjectGreyDistance; // CLI command holder to be thread safe - ZThread::LockedQueue cliCmdQueue; + ACE_Based::LockedQueue cliCmdQueue; SqlResultQueue *m_resultQueue; // next daily quests reset time @@ -637,7 +637,7 @@ class World //sessions that are added async void AddSession_(WorldSession* s); - ZThread::LockedQueue addSessQueue; + ACE_Based::LockedQueue addSessQueue; //used versions std::string m_DBVersion; diff --git a/src/game/WorldLog.cpp b/src/game/WorldLog.cpp index 52eb1e8b59c..978514ac7d7 100644 --- a/src/game/WorldLog.cpp +++ b/src/game/WorldLog.cpp @@ -27,9 +27,9 @@ #include "Config/ConfigEnv.h" #include "Log.h" -#define CLASS_LOCK Trinity::ClassLevelLockable +#define CLASS_LOCK MaNGOS::ClassLevelLockable INSTANTIATE_SINGLETON_2(WorldLog, CLASS_LOCK); -INSTANTIATE_CLASS_MUTEX(WorldLog, ZThread::FastMutex); +INSTANTIATE_CLASS_MUTEX(WorldLog, ACE_Thread_Mutex); #define WORLD_LOG_FILE_STRING "world.log" diff --git a/src/game/WorldLog.h b/src/game/WorldLog.h index 01f34535dd9..e6b72e654f7 100644 --- a/src/game/WorldLog.h +++ b/src/game/WorldLog.h @@ -32,13 +32,13 @@ #include /// %Log packets to a file -class TRINITY_DLL_DECL WorldLog : public Trinity::Singleton > +class MANGOS_DLL_DECL WorldLog : public MaNGOS::Singleton > { friend class Trinity::OperatorNew; WorldLog(); WorldLog(const WorldLog &); WorldLog& operator=(const WorldLog &); - typedef Trinity::ClassLevelLockable::Lock Guard; + typedef MaNGOS::ClassLevelLockable::Lock Guard; /// Close the file in destructor ~WorldLog(); diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index d514586957a..a8d6db72809 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -719,8 +719,7 @@ class TRINITY_DLL_SPEC WorldSession uint32 m_latency; AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]; AddonsList m_addonsList; - - ZThread::LockedQueue _recvQueue; + ACE_Based::LockedQueue _recvQueue; }; #endif /// @} diff --git a/src/shared/Common.h b/src/shared/Common.h index 5cbd7f285f6..37ced4c8e11 100644 --- a/src/shared/Common.h +++ b/src/shared/Common.h @@ -84,6 +84,7 @@ #include #include #include +#include #if PLATFORM == PLATFORM_WINDOWS #define STRCASECMP stricmp @@ -99,10 +100,13 @@ #include #include -#include -#include -#include -#include +#include "LockedQueue.h" +#include "Threading.h" + +#include +#include +#include + #if PLATFORM == PLATFORM_WINDOWS # define FD_SETSIZE 4096 diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp index 07ece3b0cd9..783b520ded3 100644 --- a/src/shared/Database/Database.cpp +++ b/src/shared/Database/Database.cpp @@ -110,7 +110,8 @@ bool Database::PExecuteLog(const char * format,...) void Database::SetResultQueue(SqlResultQueue * queue) { - m_queryQueues[ZThread::ThreadImpl::current()] = queue; + m_queryQueues[ACE_Based::Thread::current()] = queue; + } QueryResult* Database::PQuery(const char *format,...) diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h index 92a1c991dcc..a9f7285c223 100644 --- a/src/shared/Database/Database.h +++ b/src/shared/Database/Database.h @@ -21,8 +21,7 @@ #ifndef DATABASE_H #define DATABASE_H -#include "zthread/Thread.h" -#include "../src/zthread/ThreadImpl.h" +#include "Threading.h" #include "Utilities/UnorderedMap.h" #include "Database/SqlDelayThread.h" @@ -30,8 +29,8 @@ class SqlTransaction; class SqlResultQueue; class SqlQueryHolder; -typedef UNORDERED_MAP TransactionQueues; -typedef UNORDERED_MAP QueryQueues; +typedef UNORDERED_MAP TransactionQueues; +typedef UNORDERED_MAP QueryQueues; #define MAX_QUERY_LEN 32*1024 @@ -43,7 +42,7 @@ class TRINITY_DLL_SPEC Database TransactionQueues m_tranQueues; ///< Transaction queues from diff. threads QueryQueues m_queryQueues; ///< Query queues from diff threads SqlDelayThread* m_threadBody; ///< Pointer to delay sql executer - ZThread::Thread* m_delayThread; ///< Pointer to executer thread + ACE_Based::Thread* m_delayThread; ///< Pointer to executer thread public: diff --git a/src/shared/Database/DatabaseImpl.h b/src/shared/Database/DatabaseImpl.h index 3d3c53f0873..7cbd0ed8ba5 100644 --- a/src/shared/Database/DatabaseImpl.h +++ b/src/shared/Database/DatabaseImpl.h @@ -29,7 +29,7 @@ QueryQueues::iterator queue_itr; \ \ { \ - ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current(); \ + ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \ queue_itr = m_queryQueues.find(queryThread); \ if (queue_itr == m_queryQueues.end()) return false; \ } @@ -59,7 +59,7 @@ QueryQueues::iterator queue_itr; \ \ { \ - ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current(); \ + ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \ queue_itr = m_queryQueues.find(queryThread); \ if (queue_itr == m_queryQueues.end()) return false; \ } diff --git a/src/shared/Database/DatabaseMysql.cpp b/src/shared/Database/DatabaseMysql.cpp index 5dc02c0a738..92b303a167d 100644 --- a/src/shared/Database/DatabaseMysql.cpp +++ b/src/shared/Database/DatabaseMysql.cpp @@ -23,7 +23,7 @@ #include "Util.h" #include "Policies/SingletonImp.h" #include "Platform/Define.h" -#include "../src/zthread/ThreadImpl.h" +#include "Threading.h" #include "DatabaseEnv.h" #include "Database/MySQLDelayThread.h" #include "Database/SqlOperations.h" @@ -203,8 +203,8 @@ QueryResult* DatabaseMysql::Query(const char *sql) { // guarded block for thread-safe mySQL request - ZThread::Guard query_connection_guard(mMutex); - #ifdef TRINITY_DEBUG + ACE_Guard query_connection_guard(mMutex); + #ifdef MANGOS_DEBUG uint32 _s = getMSTime(); #endif if(mysql_query(mMysql, sql)) @@ -251,7 +251,7 @@ bool DatabaseMysql::Execute(const char *sql) // don't use queued execution if it has not been initialized if (!m_threadBody) return DirectExecute(sql); - tranThread = ZThread::ThreadImpl::current(); // owner of this transaction + tranThread = ACE_Based::Thread::current(); // owner of this transaction TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) { // Statement for transaction @@ -273,8 +273,9 @@ bool DatabaseMysql::DirectExecute(const char* sql) { // guarded block for thread-safe mySQL request - ZThread::Guard query_connection_guard(mMutex); - #ifdef TRINITY_DEBUG + ACE_Guard query_connection_guard(mMutex); + + #ifdef MANGOS_DEBUG uint32 _s = getMSTime(); #endif if(mysql_query(mMysql, sql)) @@ -318,8 +319,9 @@ bool DatabaseMysql::BeginTransaction() // don't use queued execution if it has not been initialized if (!m_threadBody) { - if (tranThread==ZThread::ThreadImpl::current()) + if (tranThread == ACE_Based::Thread::current()) return false; // huh? this thread already started transaction + mMutex.acquire(); if (!_TransactionCmd("START TRANSACTION")) { @@ -329,7 +331,7 @@ bool DatabaseMysql::BeginTransaction() return true; // transaction started } - tranThread = ZThread::ThreadImpl::current(); // owner of this transaction + tranThread = ACE_Based::Thread::current(); // owner of this transaction TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) // If for thread exists queue and also contains transaction @@ -349,7 +351,7 @@ bool DatabaseMysql::CommitTransaction() // don't use queued execution if it has not been initialized if (!m_threadBody) { - if (tranThread!=ZThread::ThreadImpl::current()) + if (tranThread != ACE_Based::Thread::current()) return false; bool _res = _TransactionCmd("COMMIT"); tranThread = NULL; @@ -357,7 +359,7 @@ bool DatabaseMysql::CommitTransaction() return _res; } - tranThread = ZThread::ThreadImpl::current(); + tranThread = ACE_Based::Thread::current(); TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) { @@ -377,7 +379,7 @@ bool DatabaseMysql::RollbackTransaction() // don't use queued execution if it has not been initialized if (!m_threadBody) { - if (tranThread!=ZThread::ThreadImpl::current()) + if (tranThread != ACE_Based::Thread::current()) return false; bool _res = _TransactionCmd("ROLLBACK"); tranThread = NULL; @@ -385,7 +387,7 @@ bool DatabaseMysql::RollbackTransaction() return _res; } - tranThread = ZThread::ThreadImpl::current(); + tranThread = ACE_Based::Thread::current(); TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) { @@ -408,7 +410,8 @@ void DatabaseMysql::InitDelayThread() assert(!m_delayThread); //New delay thread for delay execute - m_delayThread = new ZThread::Thread(m_threadBody = new MySQLDelayThread(this)); + m_threadBody = new MySQLDelayThread(this); + m_delayThread = new ACE_Based::Thread(*m_threadBody); } void DatabaseMysql::HaltDelayThread() diff --git a/src/shared/Database/DatabaseMysql.h b/src/shared/Database/DatabaseMysql.h index 2fa157e75a5..7f5730f9579 100644 --- a/src/shared/Database/DatabaseMysql.h +++ b/src/shared/Database/DatabaseMysql.h @@ -25,7 +25,8 @@ #include "Database.h" #include "Policies/Singleton.h" -#include "zthread/FastMutex.h" +#include "ace/Thread_Mutex.h" +#include "ace/Guard_T.h" #ifdef WIN32 #define FD_SETSIZE 1024 @@ -65,9 +66,9 @@ class TRINITY_DLL_SPEC DatabaseMysql : public Database // must be call before finish thread run void ThreadEnd(); private: - ZThread::FastMutex mMutex; + ACE_Thread_Mutex mMutex; - ZThread::ThreadImpl* tranThread; + ACE_Based::Thread * tranThread; MYSQL *mMysql; diff --git a/src/shared/Database/DatabasePostgre.cpp b/src/shared/Database/DatabasePostgre.cpp index 79e1c87f5e3..d4f48b99fb1 100644 --- a/src/shared/Database/DatabasePostgre.cpp +++ b/src/shared/Database/DatabasePostgre.cpp @@ -23,7 +23,7 @@ #include "Util.h" #include "Policies/SingletonImp.h" #include "Platform/Define.h" -#include "../src/zthread/ThreadImpl.h" +#include "Threading.h" #include "DatabaseEnv.h" #include "Database/PGSQLDelayThread.h" #include "Database/SqlOperations.h" @@ -126,8 +126,13 @@ QueryResult* DatabasePostgre::Query(const char *sql) uint32 fieldCount = 0; // guarded block for thread-safe request +<<<<<<< HEAD:src/shared/Database/DatabasePostgre.cpp ZThread::Guard query_connection_guard(mMutex); #ifdef TRINITY_DEBUG +======= + ACE_Guard query_connection_guard(mMutex); + #ifdef MANGOS_DEBUG +>>>>>>> 00c7d15a78b1dcdbf888b768c55424183b2231e4:src/shared/Database/DatabasePostgre.cpp uint32 _s = getMSTime(); #endif // Send the query @@ -174,9 +179,10 @@ bool DatabasePostgre::Execute(const char *sql) return false; // don't use queued execution if it has not been initialized - if (!m_threadBody) return DirectExecute(sql); + if (!m_threadBody) + return DirectExecute(sql); - tranThread = ZThread::ThreadImpl::current(); // owner of this transaction + tranThread = ACE_Based::Thread::current(); // owner of this transaction TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) { // Statement for transaction @@ -197,8 +203,8 @@ bool DatabasePostgre::DirectExecute(const char* sql) return false; { // guarded block for thread-safe request - ZThread::Guard query_connection_guard(mMutex); - #ifdef TRINITY_DEBUG + ACE_Guard query_connection_guard(mMutex); + #ifdef MANGOS_DEBUG uint32 _s = getMSTime(); #endif PGresult *res = PQexec(mPGconn, sql); @@ -247,7 +253,7 @@ bool DatabasePostgre::BeginTransaction() // don't use queued execution if it has not been initialized if (!m_threadBody) { - if (tranThread==ZThread::ThreadImpl::current()) + if (tranThread == ACE_Based::Thread::current()) return false; // huh? this thread already started transaction mMutex.acquire(); if (!_TransactionCmd("START TRANSACTION")) @@ -258,7 +264,7 @@ bool DatabasePostgre::BeginTransaction() return true; } // transaction started - tranThread = ZThread::ThreadImpl::current(); // owner of this transaction + tranThread = ACE_Based::Thread::current(); // owner of this transaction TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) // If for thread exists queue and also contains transaction @@ -278,14 +284,14 @@ bool DatabasePostgre::CommitTransaction() // don't use queued execution if it has not been initialized if (!m_threadBody) { - if (tranThread!=ZThread::ThreadImpl::current()) + if (tranThread != ACE_Based::Thread::current()) return false; bool _res = _TransactionCmd("COMMIT"); tranThread = NULL; mMutex.release(); return _res; } - tranThread = ZThread::ThreadImpl::current(); + tranThread = ACE_Based::Thread::current(); TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) { @@ -304,14 +310,14 @@ bool DatabasePostgre::RollbackTransaction() // don't use queued execution if it has not been initialized if (!m_threadBody) { - if (tranThread!=ZThread::ThreadImpl::current()) + if (tranThread != ACE_Based::Thread::current()) return false; bool _res = _TransactionCmd("ROLLBACK"); tranThread = NULL; mMutex.release(); return _res; } - tranThread = ZThread::ThreadImpl::current(); + tranThread = ACE_Based::Thread::current(); TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) { @@ -334,7 +340,8 @@ void DatabasePostgre::InitDelayThread() assert(!m_delayThread); //New delay thread for delay execute - m_delayThread = new ZThread::Thread(m_threadBody = new PGSQLDelayThread(this)); + m_threadBody = new PGSQLDelayThread(this); + m_delayThread = new ACE_Based::Thread(*m_threadBody); } void DatabasePostgre::HaltDelayThread() diff --git a/src/shared/Database/DatabasePostgre.h b/src/shared/Database/DatabasePostgre.h index c7242add572..53f0802f86c 100644 --- a/src/shared/Database/DatabasePostgre.h +++ b/src/shared/Database/DatabasePostgre.h @@ -22,7 +22,6 @@ #define _DatabasePostgre_H #include "Policies/Singleton.h" -#include "zthread/FastMutex.h" #include #ifdef WIN32 @@ -63,10 +62,8 @@ class DatabasePostgre : public Database // must be call before finish thread run void ThreadEnd(); private: - ZThread::FastMutex mMutex; - ZThread::FastMutex tranMutex; - - ZThread::ThreadImpl* tranThread; + ACE_Thread_Mutex mMutex; + ACE_Based::Thread * tranThread; PGconn *mPGconn; diff --git a/src/shared/Database/QueryResult.h b/src/shared/Database/QueryResult.h index 01da45ed281..39228dd4ba9 100644 --- a/src/shared/Database/QueryResult.h +++ b/src/shared/Database/QueryResult.h @@ -40,7 +40,7 @@ class TRINITY_DLL_SPEC QueryResult if(iter->second == name) return iter->first; } - assert(false && "unknown field name"); + ASSERT(false && "unknown field name"); return uint32(-1); } diff --git a/src/shared/Database/SqlDelayThread.cpp b/src/shared/Database/SqlDelayThread.cpp index 27f58510a0a..9a92fd5dd63 100644 --- a/src/shared/Database/SqlDelayThread.cpp +++ b/src/shared/Database/SqlDelayThread.cpp @@ -37,7 +37,7 @@ void SqlDelayThread::run() { // if the running state gets turned off while sleeping // empty the queue before exiting - ZThread::Thread::sleep(10); + ACE_Based::Thread::Sleep(10); while (!m_sqlQueue.empty()) { s = m_sqlQueue.next(); diff --git a/src/shared/Database/SqlDelayThread.h b/src/shared/Database/SqlDelayThread.h index cbae0c1e5eb..3c24d3525b7 100644 --- a/src/shared/Database/SqlDelayThread.h +++ b/src/shared/Database/SqlDelayThread.h @@ -21,21 +21,22 @@ #ifndef __SQLDELAYTHREAD_H #define __SQLDELAYTHREAD_H -#include "zthread/Thread.h" -#include "zthread/Runnable.h" -#include "zthread/FastMutex.h" -#include "zthread/LockedQueue.h" +#include "ace/Thread_Mutex.h" +#include "LockedQueue.h" +#include "Threading.h" + class Database; class SqlOperation; -class SqlDelayThread : public ZThread::Runnable +class SqlDelayThread : public ACE_Based::Runnable { - typedef ZThread::LockedQueue SqlQueue; + typedef ACE_Based::LockedQueue SqlQueue; + private: SqlQueue m_sqlQueue; ///< Queue of SQL statements Database* m_dbEngine; ///< Pointer to used Database engine - bool m_running; + volatile bool m_running; SqlDelayThread(); public: diff --git a/src/shared/Database/SqlOperations.h b/src/shared/Database/SqlOperations.h index 61eef4bb7c4..e91d83b6611 100644 --- a/src/shared/Database/SqlOperations.h +++ b/src/shared/Database/SqlOperations.h @@ -23,9 +23,8 @@ #include "Common.h" -#include "zthread/LockedQueue.h" -#include "zthread/FastMutex.h" -#include "zthread/Thread.h" +#include "ace/Thread_Mutex.h" +#include "LockedQueue.h" #include #include "Utilities/Callback.h" @@ -72,7 +71,7 @@ class SqlResultQueue; /// queue for thread class SqlQueryHolder; /// groups several async quries class SqlQueryHolderEx; /// points to a holder, added to the delay thread -class SqlResultQueue : public ZThread::LockedQueue +class SqlResultQueue : public ACE_Based::LockedQueue { public: SqlResultQueue() {} diff --git a/src/shared/Log.h b/src/shared/Log.h index 654f3c0f04c..23555995020 100644 --- a/src/shared/Log.h +++ b/src/shared/Log.h @@ -82,7 +82,7 @@ enum ColorTypes const int Colors = int(WHITE)+1; -class Log : public Trinity::Singleton > +class Log : public Trinity::Singleton > { friend class Trinity::OperatorNew; Log(); diff --git a/src/shared/Makefile.am b/src/shared/Makefile.am index 6b99351cb26..60af5b8a4b5 100644 --- a/src/shared/Makefile.am +++ b/src/shared/Makefile.am @@ -38,6 +38,7 @@ libmangosshared_a_SOURCES = \ Common.cpp \ Common.h \ Errors.h \ + LockedQueue.h \ Log.cpp \ Log.h \ MemoryLeaks.cpp \ @@ -45,6 +46,8 @@ libmangosshared_a_SOURCES = \ ProgressBar.cpp \ ProgressBar.h \ Timer.h \ + Threading.cpp \ + Threading.h \ Util.cpp \ Util.h \ WorldPacket.h \ diff --git a/src/shared/Util.cpp b/src/shared/Util.cpp index 767b65e441c..ac57fc3c9e9 100644 --- a/src/shared/Util.cpp +++ b/src/shared/Util.cpp @@ -23,40 +23,34 @@ #include "sockets/socket_include.h" #include "utf8cpp/utf8.h" #include "mersennetwister/MersenneTwister.h" -#include "zthread/ThreadLocal.h" +#include -typedef ZThread::ThreadLocal MTRandTSS; - -/* NOTE: Not sure if static initialization is ok for TSS objects , - * as I see zthread uses custom implementation of the TSS - * ,and in the consturctor there is no code ,so I suppose its ok - * If its not ok ,change it to use singleton. - */ +typedef ACE_TSS MTRandTSS; static MTRandTSS mtRand; int32 irand (int32 min, int32 max) { - return int32 (mtRand.get ().randInt (max - min)) + min; + return int32 (mtRand->randInt (max - min)) + min; } uint32 urand (uint32 min, uint32 max) { - return mtRand.get ().randInt (max - min) + min; + return mtRand->randInt (max - min) + min; } int32 rand32 () { - return mtRand.get ().randInt (); + return mtRand->randInt (); } double rand_norm(void) { - return mtRand.get ().randExc (); + return mtRand->randExc (); } double rand_chance (void) { - return mtRand.get ().randExc (100.0); + return mtRand->randExc (100.0); } Tokens StrSplit(const std::string &src, const std::string &sep) diff --git a/src/trinitycore/CliRunnable.cpp b/src/trinitycore/CliRunnable.cpp index 91f37cd1b48..d53ee8c24be 100644 --- a/src/trinitycore/CliRunnable.cpp +++ b/src/trinitycore/CliRunnable.cpp @@ -155,7 +155,7 @@ bool ChatHandler::HandleCharacterDeleteCommand(const char* args) } /// Exit the realm -bool ChatHandler::HandleServerExitCommand(const char* args) +bool ChatHandler::HandleServerExitCommand(const char* /*args*/) { SendSysMessage(LANG_COMMAND_EXIT); World::StopNow(SHUTDOWN_EXIT_CODE); @@ -163,7 +163,7 @@ bool ChatHandler::HandleServerExitCommand(const char* args) } /// Display info on users currently in the realm -bool ChatHandler::HandleAccountOnlineListCommand(const char* args) +bool ChatHandler::HandleAccountOnlineListCommand(const char* /*args*/) { ///- Get the list of accounts ID logged to the realm QueryResult *resultDB = CharacterDatabase.Query("SELECT name,account FROM characters WHERE online > 0"); diff --git a/src/trinitycore/CliRunnable.h b/src/trinitycore/CliRunnable.h index 20ff58f27ba..cf745bbb195 100644 --- a/src/trinitycore/CliRunnable.h +++ b/src/trinitycore/CliRunnable.h @@ -26,7 +26,7 @@ #define __CLIRUNNABLE_H /// Command Line Interface handling thread -class CliRunnable : public ZThread::Runnable +class CliRunnable : public ACE_Based::Runnable { public: void run(); diff --git a/src/trinitycore/Makefile.am b/src/trinitycore/Makefile.am index 7e1cd086d3c..f0ac432dab1 100644 --- a/src/trinitycore/Makefile.am +++ b/src/trinitycore/Makefile.am @@ -35,8 +35,13 @@ trinity_worldd_SOURCES = \ WorldRunnable.h ## Link world daemon against the shared library +<<<<<<< HEAD:src/mangosd/Makefile.am trinity_worldd_LDADD = ../bindings/scripts/libtrinityscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a trinity_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/scripts/ -L$(libdir) $(TRINI_LIBS) -export-dynamic +======= +mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/g3dlite/libg3dlite.a +mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/g3dlite -L../bindings/universal/ -L$(libdir) $(MANGOS_LIBS) -export-dynamic +>>>>>>> 00c7d15a78b1dcdbf888b768c55424183b2231e4:src/mangosd/Makefile.am ## Additional files to include when running 'make dist' # Include world daemon configuration diff --git a/src/trinitycore/Master.cpp b/src/trinitycore/Master.cpp index 6a952b936d3..2e2d75d5c3c 100644 --- a/src/trinitycore/Master.cpp +++ b/src/trinitycore/Master.cpp @@ -60,7 +60,7 @@ INSTANTIATE_SINGLETON_1( Master ); volatile uint32 Master::m_masterLoopCounter = 0; -class FreezeDetectorRunnable : public ZThread::Runnable +class FreezeDetectorRunnable : public ACE_Based::Runnable { public: FreezeDetectorRunnable() { _delaytime = 0; } @@ -79,7 +79,7 @@ public: w_lastchange = 0; while(!World::IsStopped()) { - ZThread::Thread::sleep(1000); + ACE_Based::Thread::Sleep(1000); uint32 curtime = getMSTime(); //DEBUG_LOG("anti-freeze: time=%u, counters=[%u; %u]",curtime,Master::m_masterLoopCounter,World::m_worldLoopCounter); @@ -115,7 +115,7 @@ public: } }; -class RARunnable : public ZThread::Runnable +class RARunnable : public ACE_Based::Runnable { public: uint32 numLoops, loopCounter; @@ -181,7 +181,7 @@ public: { while (!World::IsStopped()) { - ZThread::Thread::sleep (static_cast (socketSelecttime / 1000)); + ACE_Based::Thread::Sleep (static_cast (socketSelecttime / 1000)); checkping (); } } @@ -237,8 +237,8 @@ int Master::Run() _HookSignals(); ///- Launch WorldRunnable thread - ZThread::Thread t(new WorldRunnable); - t.setPriority ((ZThread::Priority )2); + ACE_Based::Thread t(*new WorldRunnable); + t.setPriority ((ACE_Based::Priority )2); // set server online LoginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID); @@ -250,10 +250,10 @@ int Master::Run() #endif { ///- Launch CliRunnable thread - ZThread::Thread td1(new CliRunnable); + ACE_Based::Thread td1(*new CliRunnable); } - ZThread::Thread td2(new RARunnable); + ACE_Based::Thread td2(*new RARunnable); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 @@ -314,8 +314,8 @@ int Master::Run() { FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable(); fdr->SetDelayTime(freeze_delay*1000); - ZThread::Thread t(fdr); - t.setPriority(ZThread::High); + ACE_Based::Thread t(*fdr); + t.setPriority(ACE_Based::High); } ///- Launch the world listener socket diff --git a/src/trinitycore/WorldRunnable.cpp b/src/trinitycore/WorldRunnable.cpp index e49e4ad74b8..bd4d3170c52 100644 --- a/src/trinitycore/WorldRunnable.cpp +++ b/src/trinitycore/WorldRunnable.cpp @@ -76,7 +76,7 @@ void WorldRunnable::run() if (diff <= WORLD_SLEEP_CONST+prevSleepTime) { prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff; - ZThread::Thread::sleep(prevSleepTime); + ACE_Based::Thread::Sleep(prevSleepTime); } else prevSleepTime = 0; diff --git a/src/trinitycore/WorldRunnable.h b/src/trinitycore/WorldRunnable.h index 8df3a6a0c89..07ce246b04f 100644 --- a/src/trinitycore/WorldRunnable.h +++ b/src/trinitycore/WorldRunnable.h @@ -26,7 +26,7 @@ #define __WORLDRUNNABLE_H /// Heartbeat thread for the World -class WorldRunnable : public ZThread::Runnable +class WorldRunnable : public ACE_Based::Runnable { public: void run(); diff --git a/src/trinityrealm/AuthSocket.cpp b/src/trinityrealm/AuthSocket.cpp index c5c81593737..8c9eab653ec 100644 --- a/src/trinityrealm/AuthSocket.cpp +++ b/src/trinityrealm/AuthSocket.cpp @@ -173,7 +173,7 @@ typedef struct AuthHandler #endif /// Launch a thread to transfer a patch to the client -class PatcherRunnable: public ZThread::Runnable +class PatcherRunnable: public ACE_Based::Runnable { public: PatcherRunnable(class AuthSocket *); @@ -236,7 +236,8 @@ AuthSocket::AuthSocket(ISocketHandler &h) : TcpSocket(h) /// Close patch file descriptor before leaving AuthSocket::~AuthSocket() { - ZThread::Guard g(patcherLock); + ACE_Guard g(patcherLock); + if(pPatch) fclose(pPatch); } @@ -912,7 +913,7 @@ bool AuthSocket::_HandleXferResume() ibuf.Read((char*)&start,sizeof(start)); fseek(pPatch,start,0); - ZThread::Thread u(new PatcherRunnable(this)); + ACE_Based::Thread u(*new PatcherRunnable(this)); return true; } @@ -924,7 +925,6 @@ bool AuthSocket::_HandleXferCancel() ///- Close and delete the socket ibuf.Remove(1); //clear input buffer - //ZThread::Thread::sleep(15); SetCloseAndDelete(); return true; @@ -946,8 +946,7 @@ bool AuthSocket::_HandleXferAccept() ibuf.Remove(1); //clear input buffer fseek(pPatch,0,0); - ZThread::Thread u(new PatcherRunnable(this)); - + ACE_Based::Thread u(*new PatcherRunnable(this)); return true; } @@ -965,7 +964,8 @@ PatcherRunnable::PatcherRunnable(class AuthSocket * as) /// Send content of patch file to the client void PatcherRunnable::run() { - ZThread::Guard g(mySocket->patcherLock); + ACE_Guard g(mySocket->patcherLock); + XFER_DATA_STRUCT xfdata; xfdata.opcode = XFER_DATA; @@ -974,7 +974,7 @@ void PatcherRunnable::run() ///- Wait until output buffer is reasonably empty while(mySocket->Ready() && mySocket->IsLag()) { - ZThread::Thread::sleep(1); + ACE_Based::Thread::Sleep(1); } ///- And send content of the patch file to the client xfdata.data_size=fread(&xfdata.data,1,ChunkSize,mySocket->pPatch); diff --git a/src/trinityrealm/AuthSocket.h b/src/trinityrealm/AuthSocket.h index 3cae54c7789..43b880a1e74 100644 --- a/src/trinityrealm/AuthSocket.h +++ b/src/trinityrealm/AuthSocket.h @@ -33,7 +33,6 @@ #include "sockets/Utility.h" #include "sockets/Parse.h" #include "sockets/Socket.h" -#include "zthread/Mutex.h" /// Handle login commands class AuthSocket: public TcpSocket @@ -61,7 +60,7 @@ class AuthSocket: public TcpSocket void _SetVSFields(const std::string& rI); FILE *pPatch; - ZThread::Mutex patcherLock; + ACE_Thread_Mutex patcherLock; bool IsLag(); private: diff --git a/src/trinityrealm/Makefile.am b/src/trinityrealm/Makefile.am index a14b50c847a..197d6ebf8c4 100644 --- a/src/trinityrealm/Makefile.am +++ b/src/trinityrealm/Makefile.am @@ -32,8 +32,13 @@ trinity_realmd_SOURCES = \ RealmList.h ## Link realm list daemon against the shared library +<<<<<<< HEAD:src/realmd/Makefile.am trinity_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la trinity_realmd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L$(libdir) $(TRINI_LIBS) +======= +mangos_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a +mangos_realmd_LDFLAGS = -L../../dep/src/sockets -L$(libdir) $(MANGOS_LIBS) +>>>>>>> 00c7d15a78b1dcdbf888b768c55424183b2231e4:src/realmd/Makefile.am ## Additional files to include when running 'make dist' # Include realm list daemon configuration diff --git a/win/TrinityCore&Script VC71.sln b/win/TrinityCore&Script VC71.sln index 8c4432075b4..2eee999cede 100644 --- a/win/TrinityCore&Script VC71.sln +++ b/win/TrinityCore&Script VC71.sln @@ -14,10 +14,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared", "VC71\shared.vcpro {DE0380F9-C910-4E99-A841-93550D0E61D7} = {DE0380F9-C910-4E99-A841-93550D0E61D7} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zthread", "VC71\zthread.vcproj", "{262199E8-EEDF-4700-A1D1-E9CC901CF480}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "VC71\zlib.vcproj", "{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}" ProjectSection(ProjectDependencies) = postProject EndProjectSection diff --git a/win/TrinityCore&Script VC80.sln b/win/TrinityCore&Script VC80.sln index 167b00a4b8b..cb880001dc2 100644 --- a/win/TrinityCore&Script VC80.sln +++ b/win/TrinityCore&Script VC80.sln @@ -23,8 +23,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrinityCore", "VC80\Trinity {563E9905-3657-460C-AE63-0AC39D162E23} = {563E9905-3657-460C-AE63-0AC39D162E23} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zthread", "VC80\zthread.vcproj", "{262199E8-EEDF-4700-A1D1-E9CC901CF480}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "VC80\zlib.vcproj", "{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "framework", "VC80\framework.vcproj", "{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}" diff --git a/win/TrinityCore&Script VC90.sln b/win/TrinityCore&Script VC90.sln index 2904ca6f20a..a81cbfc570e 100644 --- a/win/TrinityCore&Script VC90.sln +++ b/win/TrinityCore&Script VC90.sln @@ -23,8 +23,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrinityCore", "VC90\Trinity {1DC6C4DA-A028-41F3-877D-D5400C594F88} = {1DC6C4DA-A028-41F3-877D-D5400C594F88} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zthread", "VC90\zthread.vcproj", "{262199E8-EEDF-4700-A1D1-E9CC901CF480}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "VC90\zlib.vcproj", "{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "framework", "VC90\framework.vcproj", "{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}" diff --git a/win/VC71/ScriptsInterfaces.vcproj b/win/VC71/ScriptsInterfaces.vcproj index 5d229de138a..813f477dd35 100644 --- a/win/VC71/ScriptsInterfaces.vcproj +++ b/win/VC71/ScriptsInterfaces.vcproj @@ -33,10 +33,17 @@ Name="VCCustomBuildTool"/> >>>>>> 00c7d15a78b1dcdbf888b768c55424183b2231e4:win/VC71/script.vcproj GenerateDebugInformation="TRUE" ProgramDatabaseFile="$(OutDir)/TrinityScript.pdb" SubSystem="2" @@ -83,10 +90,17 @@ Name="VCCustomBuildTool"/> >>>>>> 00c7d15a78b1dcdbf888b768c55424183b2231e4:win/VC71/script.vcproj GenerateDebugInformation="FALSE" SubSystem="2" OptimizeReferences="2" diff --git a/win/VC71/TrinityCore.vcproj b/win/VC71/TrinityCore.vcproj index 1da3ad630dd..df6ab1c709e 100644 --- a/win/VC71/TrinityCore.vcproj +++ b/win/VC71/TrinityCore.vcproj @@ -4,7 +4,7 @@ Version="7.10" Name="TrinityCore" ProjectGUID="{D1EA3EE9-4DCF-4CB9-BA6E-B9321E0D552A}" - RootNamespace="mangosd" + RootNamespace="trinitycore" SccProjectName="" SccLocalPath=""> @@ -58,7 +58,7 @@ ImportLibrary="$(OutDir)\trinitycore.lib"/> + TypeLibraryName=".\trinitycore__$(PlatformName)_$(ConfigurationName)\trinitycore.tlb"/> + TypeLibraryName=".\trinitycore__$(PlatformName)_$(ConfigurationName)\trinitycore.tlb"/> @@ -15,7 +15,7 @@ >>>>>> 00c7d15a78b1dcdbf888b768c55424183b2231e4:win/VC71/TrinityRealm.vcproj LinkIncremental="1" SuppressStartupBanner="TRUE" - AdditionalLibraryDirectories=""..\..\dep\lib\$(PlatformName)_$(ConfigurationName)";".\zthread__$(PlatformName)_$(ConfigurationName)"" + AdditionalLibraryDirectories="..\..\dep\lib\$(PlatformName)_$(ConfigurationName)" GenerateDebugInformation="TRUE" ProgramDatabaseFile="..\..\bin\$(PlatformName)_$(ConfigurationName)\TrinityRealm.pdb" GenerateMapFile="TRUE" @@ -57,7 +62,7 @@ LargeAddressAware="2"/> + TypeLibraryName=".\TrinityRealm__$(PlatformName)_$(ConfigurationName)\TrinityRealm.tlb"/> @@ -83,7 +88,7 @@ >>>>>> 00c7d15a78b1dcdbf888b768c55424183b2231e4:win/VC71/TrinityRealm.vcproj SuppressStartupBanner="TRUE" - AdditionalLibraryDirectories=""..\..\dep\lib\$(PlatformName)_$(ConfigurationName)";".\zthread__$(PlatformName)_$(ConfigurationName)"" + AdditionalLibraryDirectories="..\..\dep\lib\$(PlatformName)_$(ConfigurationName)" GenerateDebugInformation="TRUE" ProgramDatabaseFile="..\..\bin\$(PlatformName)_$(ConfigurationName)\TrinityRealm.pdb" GenerateMapFile="TRUE" @@ -125,7 +136,7 @@ FixedBaseAddress="1"/> + TypeLibraryName=".\TrinityRealm__$(PlatformName)_$(ConfigurationName)\TrinityRealm.tlb"/> diff --git a/win/VC71/shared.vcproj b/win/VC71/shared.vcproj index 2bd75f70231..81da9f674f8 100644 --- a/win/VC71/shared.vcproj +++ b/win/VC71/shared.vcproj @@ -44,6 +44,7 @@ Name="VCLibrarianTool" AdditionalDependencies=".\g3dlite__$(PlatformName)_$(ConfigurationName)\g3dlite.lib" OutputFile=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib" + AdditionalLibraryDirectories="dep\lib\$(PlatformName)_$(ConfigurationName)" SuppressStartupBanner="TRUE"/> @@ -98,6 +99,7 @@ Name="VCLibrarianTool" AdditionalDependencies=".\g3dlite__$(PlatformName)_$(ConfigurationName)\g3dlite.lib" OutputFile=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib" + AdditionalLibraryDirectories="dep\lib\$(PlatformName)_$(ConfigurationName)" SuppressStartupBanner="TRUE"/> @@ -374,6 +376,7 @@ +<<<<<<< HEAD:win/VC71/shared.vcproj @@ -399,6 +402,38 @@ Outputs="revision.h" /> +======= + + + + + + + + + + + +>>>>>>> 00c7d15a78b1dcdbf888b768c55424183b2231e4:win/VC71/shared.vcproj @@ -409,6 +444,12 @@ + + + + diff --git a/win/VC71/zthread.vcproj b/win/VC71/zthread.vcproj deleted file mode 100644 index 723c90ed7a5..00000000000 --- a/win/VC71/zthread.vcproj +++ /dev/null @@ -1,381 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/win/VC80/ScriptsInterfaces.vcproj b/win/VC80/ScriptsInterfaces.vcproj index 72c7626138d..d4329a747cc 100644 --- a/win/VC80/ScriptsInterfaces.vcproj +++ b/win/VC80/ScriptsInterfaces.vcproj @@ -65,10 +65,10 @@ /> + + @@ -895,6 +905,14 @@ RelativePath="..\..\src\shared\SystemConfig.h" > + + + + diff --git a/win/VC90/ScriptsInterfaces.vcproj b/win/VC90/ScriptsInterfaces.vcproj index 34ad97341e5..7037cffdf68 100644 --- a/win/VC90/ScriptsInterfaces.vcproj +++ b/win/VC90/ScriptsInterfaces.vcproj @@ -67,10 +67,10 @@ /> @@ -42,7 +42,7 @@ /> @@ -41,20 +41,20 @@ /> + + @@ -926,6 +936,14 @@ RelativePath="..\..\src\shared\SystemConfig.h" > + + + + diff --git a/win/VC90/zthread.vcproj b/win/VC90/zthread.vcproj deleted file mode 100644 index a381daa3198..00000000000 --- a/win/VC90/zthread.vcproj +++ /dev/null @@ -1,799 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 88107fa1d67441afe81a92d37a681c47555c8827 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 13 May 2009 18:24:35 -0500 Subject: [7811] do not reload already loaded map coordinats at runtime. Author: Ambal --HG-- branch : trunk --- src/game/Map.cpp | 5 ++++- src/game/Map.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 3280970750b..140904bfb19 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -120,7 +120,7 @@ void Map::LoadVMap(int gx,int gy) } } -void Map::LoadMap(int gx,int gy) +void Map::LoadMap(int gx,int gy, bool reload) { if( i_InstanceId != 0 ) { @@ -138,6 +138,9 @@ void Map::LoadMap(int gx,int gy) return; } + if(GridMaps[gx][gy] && !reload) + return; + //map already load, delete it before reloading (Is it necessary? Do we really need the ability the reload maps during runtime?) if(GridMaps[gx][gy]) { diff --git a/src/game/Map.h b/src/game/Map.h index a4309504435..c69fe5f7345 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -421,7 +421,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj private: void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); - void LoadMap(int gx,int gy); + void LoadMap(int gx,int gy, bool reload = false); GridMap *GetGrid(float x, float y); void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; } -- cgit v1.2.3 From cd2857fc3f36884d6187310a98c6febb2d9b679c Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 13 May 2009 18:26:11 -0500 Subject: [7813] Fixed build x64 debug on win. Author: AlexDereka --HG-- branch : trunk --- src/shared/MemoryLeaks.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/shared/MemoryLeaks.h b/src/shared/MemoryLeaks.h index fcea1f557b1..c8b8fb8e1b1 100644 --- a/src/shared/MemoryLeaks.h +++ b/src/shared/MemoryLeaks.h @@ -31,9 +31,9 @@ //# include //# include #else -# define _CRTDBG_MAP_ALLOC -# include -# include +//# define _CRTDBG_MAP_ALLOC +//# include +//# include #endif #endif -- cgit v1.2.3 From 54572864167640fa7ccadb53f6cc607e42f29561 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 13 May 2009 18:28:21 -0500 Subject: [7815] Apply mangos code style: Replace tabs by spaces in recent added code. Author: VladimirMangos --HG-- branch : trunk --- src/game/World.h | 4 ++-- src/shared/Database/Database.cpp | 2 +- src/shared/Database/DatabaseMysql.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/game/World.h b/src/game/World.h index 80d5717f981..11a83678d35 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -626,7 +626,7 @@ class World static float m_VisibleObjectGreyDistance; // CLI command holder to be thread safe - ACE_Based::LockedQueue cliCmdQueue; + ACE_Based::LockedQueue cliCmdQueue; SqlResultQueue *m_resultQueue; // next daily quests reset time @@ -637,7 +637,7 @@ class World //sessions that are added async void AddSession_(WorldSession* s); - ACE_Based::LockedQueue addSessQueue; + ACE_Based::LockedQueue addSessQueue; //used versions std::string m_DBVersion; diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp index 783b520ded3..d5ccc581232 100644 --- a/src/shared/Database/Database.cpp +++ b/src/shared/Database/Database.cpp @@ -110,7 +110,7 @@ bool Database::PExecuteLog(const char * format,...) void Database::SetResultQueue(SqlResultQueue * queue) { - m_queryQueues[ACE_Based::Thread::current()] = queue; + m_queryQueues[ACE_Based::Thread::current()] = queue; } diff --git a/src/shared/Database/DatabaseMysql.cpp b/src/shared/Database/DatabaseMysql.cpp index 92b303a167d..9574d3dc2ac 100644 --- a/src/shared/Database/DatabaseMysql.cpp +++ b/src/shared/Database/DatabaseMysql.cpp @@ -351,7 +351,7 @@ bool DatabaseMysql::CommitTransaction() // don't use queued execution if it has not been initialized if (!m_threadBody) { - if (tranThread != ACE_Based::Thread::current()) + if (tranThread != ACE_Based::Thread::current()) return false; bool _res = _TransactionCmd("COMMIT"); tranThread = NULL; -- cgit v1.2.3 From 42aa8efe477ee3f0a7ea25957cc5b03f3d0b19f0 Mon Sep 17 00:00:00 2001 From: QAston Date: Thu, 14 May 2009 06:32:35 +0200 Subject: Backed out changeset 1f92b07df94a --HG-- branch : trunk --- sql/updates/3233_world_scripts_naxx.sql | 1 - sql/world_scripts_full.sql | 1 - src/bindings/scripts/ScriptMgr.cpp | 2 - .../scripts/scripts/zone/naxxramas/boss_gothik.cpp | 361 ++------------------- .../scripts/zone/naxxramas/instance_naxxramas.cpp | 8 +- 5 files changed, 35 insertions(+), 338 deletions(-) (limited to 'src') diff --git a/sql/updates/3233_world_scripts_naxx.sql b/sql/updates/3233_world_scripts_naxx.sql index a5a71ba6233..67a8615951d 100644 --- a/sql/updates/3233_world_scripts_naxx.sql +++ b/sql/updates/3233_world_scripts_naxx.sql @@ -6,7 +6,6 @@ INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comm (-28169, 28240, 0, 'Mutating Injection - Poison Cloud'); UPDATE creature_template SET scriptname = 'boss_grobbulus' WHERE entry = 15931; -update creature_template set scriptname='mob_gothik_minion' where entry in (16124,16125,16126,16127,16148,16149,16150); INSERT INTO creature_template (entry, spell1, flags_extra, scriptname) VALUES (16363, 28158, 128, ''), # Grobbulus Cloud diff --git a/sql/world_scripts_full.sql b/sql/world_scripts_full.sql index 8b28c3bc370..a1df130d207 100644 --- a/sql/world_scripts_full.sql +++ b/sql/world_scripts_full.sql @@ -645,7 +645,6 @@ UPDATE `creature_template` SET `ScriptName`='boss_heigan' WHERE `entry`=15936; UPDATE `creature_template` SET `ScriptName`='boss_loatheb' WHERE `entry`=16011; UPDATE `creature_template` SET `ScriptName`='boss_razuvious' WHERE `entry`=16061; UPDATE `creature_template` SET `ScriptName`='boss_gothik' WHERE `entry`=16060; -UPDATE `creature_template` SET `ScriptName`='mob_gothik_minion' where `entry` IN (16124,16125,16126,16127,16148,16149,16150); UPDATE `creature_template` SET `ScriptName`='boss_thane_korthazz' WHERE `entry`=16064; UPDATE `creature_template` SET `ScriptName`='boss_sir_zeliek' WHERE `entry`=16063; UPDATE `creature_template` SET `ScriptName`='boss_lady_blaumeux' WHERE `entry`=16065; diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp index 849c4d64be5..4d7ed09fff4 100644 --- a/src/bindings/scripts/ScriptMgr.cpp +++ b/src/bindings/scripts/ScriptMgr.cpp @@ -389,7 +389,6 @@ extern void AddSC_boss_sapphiron(); extern void AddSC_boss_four_horsemen(); extern void AddSC_boss_faerlina(); extern void AddSC_boss_heigan(); -extern void AddSC_boss_gothik(); extern void AddSC_instance_naxxramas(); //Netherstorm @@ -1328,7 +1327,6 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf") AddSC_boss_sapphiron(); AddSC_boss_four_horsemen(); AddSC_boss_heigan(); - AddSC_boss_gothik(); AddSC_instance_naxxramas(); //Netherstorm diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp index 7def6c370f4..3a9c6a5b47a 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2008 - 2009 Trinity +/* Copyright (C) 2006 - 2009 ScriptDev2 * 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 @@ -14,8 +14,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* ScriptData +SDName: Boss_Gothik +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Naxxramas +EndScriptData */ + #include "precompiled.h" -#include "def_naxxramas.h" #define SAY_SPEECH -1533040 #define SAY_KILL -1533041 @@ -23,336 +29,37 @@ #define SAY_TELEPORT -1533043 //Gothik -#define SPELL_HARVEST_SOUL 28679 -#define SPELL_SHADOW_BOLT HEROIC(29317,56405) - -#define SPELL_INFORM_LIVE_TRAINEE 27892 -#define SPELL_INFORM_LIVE_KNIGHT 27928 -#define SPELL_INFORM_LIVE_RIDER 27935 -#define SPELL_INFORM_DEAD_TRAINEE 27915 -#define SPELL_INFORM_DEAD_KNIGHT 27931 -#define SPELL_INFORM_DEAD_RIDER 27937 - -#define MOB_LIVE_TRAINEE 16124 -#define MOB_LIVE_KNIGHT 16125 -#define MOB_LIVE_RIDER 16126 -#define MOB_DEAD_TRAINEE 16127 -#define MOB_DEAD_KNIGHT 16148 -#define MOB_DEAD_RIDER 16150 -#define MOB_DEAD_HORSE 16149 - -const struct Waves { uint32 entry, number, time; } -waves[] = -{ - {MOB_LIVE_TRAINEE, 2, 20000}, - {MOB_LIVE_TRAINEE, 2, 20000}, - {MOB_LIVE_TRAINEE, 2, 10000}, - {MOB_LIVE_KNIGHT, 1, 10000}, - {MOB_LIVE_TRAINEE, 2, 15000}, - {MOB_LIVE_KNIGHT, 1, 10000}, - {MOB_LIVE_TRAINEE, 2, 15000}, - {MOB_LIVE_TRAINEE, 2, 0}, - {MOB_LIVE_KNIGHT, 1, 10000}, - {MOB_LIVE_RIDER, 1, 10000}, - {MOB_LIVE_TRAINEE, 2, 5000}, - {MOB_LIVE_KNIGHT, 1, 15000}, - {MOB_LIVE_TRAINEE, 2, 0}, - {MOB_LIVE_RIDER, 1, 10000}, - {MOB_LIVE_KNIGHT, 2, 10000}, - {MOB_LIVE_TRAINEE, 2, 10000}, - {MOB_LIVE_RIDER, 1, 5000}, - {MOB_LIVE_KNIGHT, 1, 5000}, - {MOB_LIVE_TRAINEE, 2, 20000}, - {MOB_LIVE_TRAINEE, 2, 0}, - {MOB_LIVE_KNIGHT, 1, 0}, - {MOB_LIVE_RIDER, 1, 15000}, - {MOB_LIVE_TRAINEE, 2, 29000}, - {0, 0, 0}, -}; - -#define POS_Y_GATE -3360.78f - -enum Events -{ - EVENT_SUMMON = 1, - EVENT_HARVEST, - EVENT_BOLT, -}; - -#define POS_LIVE 3 -#define POS_DEAD 5 - -const float PosSummonLive[POS_LIVE][4] = -{ - {2669.7, -3430.9, 268.56, 1.6}, - {2692.0, -3430.9, 268.56, 1.6}, - {2714.1, -3430.9, 268.56, 1.6}, -}; - -const float PosSummonDead[POS_DEAD][4] = -{ - {2725.1, -3310.0, 268.85, 3.4}, - {2699.3, -3322.8, 268.60, 3.3}, - {2733.1, -3348.5, 268.84, 3.1}, - {2682.8, -3304.2, 268.85, 3.9}, - {2664.8, -3340.7, 268.23, 3.7}, -}; - -const float PosGround[4] = {2691.2, -3362.7, 267.68, 1.7}; -const float PosPlatform[4] = {2640.5, -3360.6, 285.26, 0}; - -struct TRINITY_DLL_DECL boss_gothikAI : public BossAI -{ - boss_gothikAI(Creature *c) : BossAI(c, BOSS_GOTHIK) {} - - uint32 waveCount; - std::vector liveTrigger; - std::vector deadTrigger; - - void Reset() - { - liveTrigger.clear(); - deadTrigger.clear(); - me->setActive(false); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); - me->SetReactState(REACT_PASSIVE); - _Reset(); - } - - void EnterCombat(Unit *who) - { - for(uint32 i = 0; i < POS_LIVE; ++i) - if(Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonLive[i])) - liveTrigger.push_back(trigger); - for(uint32 i = 0; i < POS_DEAD; ++i) - if(Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonDead[i])) - deadTrigger.push_back(trigger); - - if(liveTrigger.size() < POS_LIVE || deadTrigger.size() < POS_DEAD) - { - error_log("Script Gothik: cannot summon triggers!"); - EnterEvadeMode(); - return; - } - - _EnterCombat(); - me->setActive(true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); - waveCount = 0; - events.ScheduleEvent(EVENT_SUMMON, 30000); - DoTeleportTo(PosPlatform); - DoScriptText(SAY_SPEECH, me); - if(instance) - instance->SetData(DATA_GOTHIK_GATE, 1); - } - - void JustSummoned(Creature *summon) - { - if(summon->GetEntry() == WORLD_TRIGGER) - summon->setActive(true); - else - { - summon->AI()->DoAction(me->HasReactState(REACT_PASSIVE) ? 1 : 0); - summon->AI()->EnterEvadeMode(); - } - summons.Summon(summon); - } - - void KilledUnit(Unit* victim) - { - if(!(rand()%5)) - DoScriptText(SAY_KILL, me); - } - - void JustDied(Unit* Killer) - { - _JustDied(); - DoScriptText(SAY_DEATH, me); - } - - void SpellHit(Unit *caster, const SpellEntry *spell) - { - uint32 spellId = 0; - switch(spell->Id) - { - case SPELL_INFORM_LIVE_TRAINEE: spellId = SPELL_INFORM_DEAD_TRAINEE; break; - case SPELL_INFORM_LIVE_KNIGHT: spellId = SPELL_INFORM_DEAD_KNIGHT; break; - case SPELL_INFORM_LIVE_RIDER: spellId = SPELL_INFORM_DEAD_RIDER; break; - } - if(spellId && me->isInCombat()) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST); - me->CastSpell(deadTrigger[rand()%POS_DEAD], spellId, true); - } - } - - void SpellHitTarget(Unit *target, const SpellEntry *spell) - { - if(!me->isInCombat()) - return; - - switch(spell->Id) - { - case SPELL_INFORM_DEAD_TRAINEE: DoSummon(MOB_DEAD_TRAINEE, target, 0); break; - case SPELL_INFORM_DEAD_KNIGHT: DoSummon(MOB_DEAD_KNIGHT, target, 0); break; - case SPELL_INFORM_DEAD_RIDER: DoSummon(MOB_DEAD_RIDER, target, 1.0f); - DoSummon(MOB_DEAD_HORSE, target, 1.0f); break; - } - } - - void UpdateAI(const uint32 diff) - { - if(!me->isInCombat()) - return; - - if(me->getThreatManager().isThreatListEmpty()) - { - EnterEvadeMode(); - return; - } - - if(me->HasReactState(REACT_AGGRESSIVE) && !UpdateVictim()) - return; - - events.Update(diff); - - if(me->hasUnitState(UNIT_STAT_CASTING)) - return; - - while(uint32 eventId = events.ExecuteEvent()) - { - switch(eventId) - { - case EVENT_SUMMON: - if(waves[waveCount].entry) - { - for(uint32 i = 0; i < waves[waveCount].number; ++i) - DoSummon(waves[waveCount].entry, liveTrigger[rand()%POS_LIVE], 1.0f); - events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); - ++waveCount; - } - else - { - DoScriptText(SAY_TELEPORT, me); - DoTeleportTo(PosGround); - me->SetReactState(REACT_AGGRESSIVE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); - if(instance) - instance->SetData(DATA_GOTHIK_GATE, 0); - summons.DoAction(0, 0); - summons.DoZoneInCombat(); - events.ScheduleEvent(EVENT_BOLT, 1000); - events.ScheduleEvent(EVENT_HARVEST, 15000); - } - break; - case EVENT_BOLT: - DoCast(me->getVictim(), SPELL_SHADOW_BOLT); - events.ScheduleEvent(EVENT_BOLT, 1000); - return; - case EVENT_HARVEST: - DoCast(me->getVictim(), SPELL_HARVEST_SOUL); - events.ScheduleEvent(EVENT_HARVEST, 15000); - return; - } - } - - DoMeleeAttackIfReady(); - } -}; - -struct TRINITY_DLL_DECL mob_gothik_minionAI : public SpellAI -{ - mob_gothik_minionAI(Creature *c) : SpellAI(c) - { - liveSide = me->GetPositionY() < POS_Y_GATE; - } - - bool liveSide; - bool gateClose; - -#define SIDE_CHECK(who) (liveSide == (who->GetPositionY() < POS_Y_GATE)) - - void DoAction(const int32 param) - { - gateClose = param; - } - - void DamageTaken(Unit *attacker, uint32 &damage) - { - if(gateClose && !SIDE_CHECK(attacker)) - damage = 0; - } - - void JustDied(Unit *killer) - { - if(me->isSummon()) - { - if(Unit *owner = ((TempSummon*)me)->GetSummoner()) - SpellAI::JustDied(owner); - } - } - - void EnterEvadeMode() - { - if(!gateClose) - { - SpellAI::EnterEvadeMode(); - return; - } - - if(!_EnterEvadeMode()) - return; +#define SPELL_HARVESTSOUL 28679 +#define SPELL_SHADOWBOLT HEROIC(29317,56405) +#define SPELL_SOUL_SIPHON 43591 // cannot find the correct spell - Map *map = me->GetMap(); - if(map->IsDungeon()) - { - Map::PlayerList const &PlayerList = map->GetPlayers(); - for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - { - if(i->getSource()->isAlive() && SIDE_CHECK(i->getSource())) - { - AttackStart(i->getSource()); - return; - } - } - } +//Unrelenting Trainee +#define SPELL_EAGLECLAW 30285 +#define SPELL_KNOCKDOWN_PASSIVE 6961 - me->GetMotionMaster()->MoveIdle(); - Reset(); - } +//Unrelenting Deathknight +#define SPELL_CHARGE 22120 +#define SPELL_SHADOW_MARK 27825 - void UpdateAI(const uint32 diff) - { - if(gateClose && (!SIDE_CHECK(me) || me->getVictim() && !SIDE_CHECK(me->getVictim()))) - { - EnterEvadeMode(); - return; - } +//Unrelenting Rider +#define SPELL_UNHOLY_AURA 55606 +#define H_SPELL_UNHOLY_AURA 55608 +#define SPELL_SHADOWBOLT_VOLLEY 27831 //Search thru targets and find those who have the SHADOW_MARK to cast this on +#define H_SPELL_SHADOWBOLT_VOLLEY 55638 - SpellAI::UpdateAI(diff); - } -}; +//Spectral Trainee +#define SPELL_ARCANE_EXPLOSION 27989 -CreatureAI* GetAI_boss_gothik(Creature *_Creature) -{ - return new boss_gothikAI (_Creature); -} +//Spectral Deathknight +#define SPELL_WHIRLWIND 28334 +#define SPELL_SUNDER_ARMOR 25051 //cannot find sunder that reduces armor by 2950 +#define SPELL_CLEAVE 20677 +#define SPELL_MANA_BURN 17631 -CreatureAI* GetAI_mob_gothik_minion(Creature *_Creature) -{ - return new mob_gothik_minionAI (_Creature); -} +//Spectral Rider +#define SPELL_LIFEDRAIN 24300 +//USES SAME UNHOLY AURA AS UNRELENTING RIDER -void AddSC_boss_gothik() -{ - Script *newscript; - newscript = new Script; - newscript->Name="boss_gothik"; - newscript->GetAI = &GetAI_boss_gothik; - newscript->RegisterSelf(); +//Spectral Horse +#define SPELL_STOMP 27993 - newscript = new Script; - newscript->Name="mob_gothik_minion"; - newscript->GetAI = &GetAI_mob_gothik_minion; - newscript->RegisterSelf(); -} diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index e5913660c3f..23f44f5daf8 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -86,10 +86,9 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData LoadDoorData(doorData); } - std::set Worshipper; std::set HeiganEruption[4]; - GameObject *GothikGate; Creature *Sapphiron; + std::set Worshipper; void OnCreatureCreate(Creature *creature, bool add) { @@ -115,7 +114,6 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData switch(go->GetEntry()) { case GO_BIRTH: if(!add && Sapphiron) Sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); return; - case GO_GOTHIK_GATE: GothikGate = add ? go : NULL; break; } AddDoor(go, add); @@ -142,10 +140,6 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData case DATA_HEIGAN_ERUPT: HeiganErupt(value); break; - case DATA_GOTHIK_GATE: - if(GothikGate) - GothikGate->SetGoState(GOState(value)); - break; } } -- cgit v1.2.3 From 2ed9222ac9c735211e2c10879c20a41992fd2c8f Mon Sep 17 00:00:00 2001 From: raczman Date: Thu, 14 May 2009 13:25:35 +0200 Subject: Fixed build on linux. Tested on Arch linux, still need someone to fixup .vcproj's for windows. --HG-- branch : trunk --- src/shared/CMakeLists.txt | 5 + src/shared/Database/DatabasePostgre.cpp | 5 - src/shared/LockedQueue.h | 144 ++++++++++++++++++++++ src/shared/Threading.cpp | 205 ++++++++++++++++++++++++++++++++ src/shared/Threading.h | 99 +++++++++++++++ 5 files changed, 453 insertions(+), 5 deletions(-) create mode 100644 src/shared/LockedQueue.h create mode 100644 src/shared/Threading.cpp create mode 100644 src/shared/Threading.h (limited to 'src') diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt index 8ecfccad34f..b271e2b9545 100644 --- a/src/shared/CMakeLists.txt +++ b/src/shared/CMakeLists.txt @@ -14,6 +14,7 @@ SET(shared_STAT_SRCS Log.h ProgressBar.cpp ProgressBar.h + Threading.cpp Timer.h Util.cpp Util.h @@ -22,3 +23,7 @@ SET(shared_STAT_SRCS ) add_library(shared STATIC ${shared_STAT_SRCS}) +target_link_libraries( +shared +${ACE_LIBRARY} +) diff --git a/src/shared/Database/DatabasePostgre.cpp b/src/shared/Database/DatabasePostgre.cpp index d4f48b99fb1..12875b33200 100644 --- a/src/shared/Database/DatabasePostgre.cpp +++ b/src/shared/Database/DatabasePostgre.cpp @@ -126,13 +126,8 @@ QueryResult* DatabasePostgre::Query(const char *sql) uint32 fieldCount = 0; // guarded block for thread-safe request -<<<<<<< HEAD:src/shared/Database/DatabasePostgre.cpp - ZThread::Guard query_connection_guard(mMutex); - #ifdef TRINITY_DEBUG -======= ACE_Guard query_connection_guard(mMutex); #ifdef MANGOS_DEBUG ->>>>>>> 00c7d15a78b1dcdbf888b768c55424183b2231e4:src/shared/Database/DatabasePostgre.cpp uint32 _s = getMSTime(); #endif // Send the query diff --git a/src/shared/LockedQueue.h b/src/shared/LockedQueue.h new file mode 100644 index 00000000000..b085dd09b83 --- /dev/null +++ b/src/shared/LockedQueue.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2009 MaNGOS + * + * 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 + */ + +#ifndef LOCKEDQUEUE_H +#define LOCKEDQUEUE_H + +#include +#include +#include +#include +#include "Errors.h" + +namespace ACE_Based +{ + + template > + class LockedQueue + { + + //! Serialize access to the Queue + LockType _lock; + + //! Storage backing the queue + StorageType _queue; + + //! Cancellation flag + volatile bool _canceled; + + public: + + //! Create a LockedQueue + LockedQueue() : _canceled(false) {} + + //! Destroy a LockedQueue + virtual ~LockedQueue() { } + + /** + * @see Queue::add(const T& item) + */ + void add(const T& item) + { + + ACE_Guard g(_lock); + + ASSERT(!_canceled); + // throw Cancellation_Exception(); + + _queue.push_back(item); + + } + + /** + * @see Queue::next() + */ + T next() + { + + ACE_Guard g(_lock); + + ASSERT (!_queue.empty() || !_canceled); + // throw Cancellation_Exception(); + + T item = _queue.front(); + _queue.pop_front(); + + return item; + + } + + T front() + { + ACE_Guard g(_lock); + + ASSERT (!_queue.empty()); + // throw NoSuchElement_Exception(); + + return _queue.front(); + } + + /** + * @see Queue::cancel() + */ + void cancel() + { + + ACE_Guard g(_lock); + + _canceled = true; + + } + + /** + * @see Queue::isCanceled() + */ + bool isCanceled() + { + + // Faster check since the queue will not become un-canceled + if(_canceled) + return true; + + ACE_Guard g(_lock); + + return _canceled; + + } + + /** + * @see Queue::size() + */ + size_t size() + { + + ACE_Guard g(_lock); + return _queue.size(); + + } + + bool empty() + { + + ACE_Guard g(_lock); + return _queue.empty(); + } + + }; + +} +#endif diff --git a/src/shared/Threading.cpp b/src/shared/Threading.cpp new file mode 100644 index 00000000000..496e86353ca --- /dev/null +++ b/src/shared/Threading.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2009 MaNGOS + * + * 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 + */ + +#include "Threading.h" +#include +#include +#include + +using namespace ACE_Based; + +ThreadPriority::ThreadPriority() +{ + for (int i = Idle; i < MAXPRIORITYNUM; ++i) + m_priority[i] = ACE_THR_PRI_OTHER_DEF; + + m_priority[Idle] = ACE_Sched_Params::priority_min(ACE_SCHED_OTHER); + m_priority[Realtime] = ACE_Sched_Params::priority_max(ACE_SCHED_OTHER); + + std::vector _tmp; + + ACE_Sched_Params::Policy _policy = ACE_SCHED_OTHER; + ACE_Sched_Priority_Iterator pr_iter(_policy); + + while (pr_iter.more()) + { + _tmp.push_back(pr_iter.priority()); + pr_iter.next(); + } + + ASSERT (!_tmp.empty()); + + if(_tmp.size() >= MAXPRIORITYNUM) + { + const size_t max_pos = _tmp.size(); + size_t min_pos = 1; + size_t norm_pos = 0; + for (size_t i = 0; i < max_pos; ++i) + { + if(_tmp[i] == ACE_THR_PRI_OTHER_DEF) + { + norm_pos = i + 1; + break; + } + } + + //since we have only 7(seven) values in enum Priority + //and 3 we know already (Idle, Normal, Realtime) so + //we need to split each list [Idle...Normal] and [Normal...Realtime] + //into ¹ piesces + const size_t _divider = 4; + size_t _div = (norm_pos - min_pos) / _divider; + if(_div == 0) + _div = 1; + + min_pos = (norm_pos - 1); + + m_priority[Low] = _tmp[min_pos -= _div]; + m_priority[Lowest] = _tmp[min_pos -= _div ]; + + _div = (max_pos - norm_pos) / _divider; + if(_div == 0) + _div = 1; + + min_pos = norm_pos - 1; + + m_priority[High] = _tmp[min_pos += _div]; + m_priority[Highest] = _tmp[min_pos += _div]; + } +} + +int ThreadPriority::getPriority(Priority p) const +{ + if(p < Idle) + p = Idle; + + if(p > Realtime) + p = Realtime; + + return m_priority[p]; +} + +#define THREADFLAG (THR_NEW_LWP | THR_SCHED_DEFAULT| THR_JOINABLE) + +Thread::Thread() : m_task(0), m_iThreadId(0), m_hThreadHandle(0) +{ + +} + +Thread::Thread(Runnable& instance) : m_task(&instance), m_iThreadId(0), m_hThreadHandle(0) +{ + bool _start = start(); + ASSERT (_start); +} + +Thread::~Thread() +{ + //Wait(); +} + +//initialize Thread's class static member +Thread::ThreadStorage Thread::m_ThreadStorage; +ThreadPriority Thread::m_TpEnum; + +bool Thread::start() +{ + if(m_task == 0 || m_iThreadId != 0) + return false; + + return (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0); +} + +bool Thread::wait() +{ + if(!m_hThreadHandle || !m_task) + return false; + + ACE_THR_FUNC_RETURN _value = ACE_THR_FUNC_RETURN(-1); + int _res = ACE_Thread::join(m_hThreadHandle, &_value); + + m_iThreadId = 0; + m_hThreadHandle = 0; + + return (_res == 0); +} + +void Thread::destroy() +{ + ACE_Thread::kill(m_iThreadId, -1); +} + +void Thread::suspend() +{ + ACE_Thread::suspend(m_hThreadHandle); +} + +void Thread::resume() +{ + ACE_Thread::resume(m_hThreadHandle); +} + +ACE_THR_FUNC_RETURN Thread::ThreadTask(void * param) +{ + Runnable * _task = (Runnable*)param; + _task->run(); + + return (ACE_THR_FUNC_RETURN)0; +} + +ACE_thread_t Thread::currentId() +{ + return ACE_Thread::self(); +} + +ACE_hthread_t Thread::currentHandle() +{ + ACE_hthread_t _handle; + ACE_Thread::self(_handle); + + return _handle; +} + +Thread * Thread::current() +{ + Thread * _thread = m_ThreadStorage.ts_object(); + if(!_thread) + { + _thread = new Thread(); + _thread->m_iThreadId = Thread::currentId(); + _thread->m_hThreadHandle = Thread::currentHandle(); + + Thread * _oldValue = m_ThreadStorage.ts_object(_thread); + if(_oldValue) + delete _oldValue; + } + + return _thread; +} + +void Thread::setPriority(Priority type) +{ + int _priority = m_TpEnum.getPriority(type); + int _ok = ACE_Thread::setprio(m_hThreadHandle, _priority); + //remove this ASSERT in case you don't want to know is thread priority change was successful or not + ASSERT (_ok == 0); +} + +void Thread::Sleep(unsigned long msecs) +{ + ACE_OS::sleep(ACE_Time_Value(0, 1000 * msecs)); +} diff --git a/src/shared/Threading.h b/src/shared/Threading.h new file mode 100644 index 00000000000..eac3c0e8efb --- /dev/null +++ b/src/shared/Threading.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2009 MaNGOS + * + * 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 + */ + +#ifndef THREADING_H +#define THREADING_H + +#include +#include +#include +#include "Errors.h" + +namespace ACE_Based +{ + + class Runnable + { + public: + virtual ~Runnable() {} + virtual void run() = 0; + }; + + enum Priority + { + Idle, + Lowest, + Low, + Normal, + High, + Highest, + Realtime, + }; + +#define MAXPRIORITYNUM (Realtime + 1) + + class ThreadPriority + { + public: + ThreadPriority(); + int getPriority(Priority p) const; + + private: + int m_priority[MAXPRIORITYNUM]; + }; + + class Thread + { + public: + Thread(); + Thread(Runnable& instance); + ~Thread(); + + bool start(); + bool wait(); + void destroy(); + + void suspend(); + void resume(); + + void setPriority(Priority type); + + static void Sleep(unsigned long msecs); + static ACE_thread_t currentId(); + static ACE_hthread_t currentHandle(); + static Thread * current(); + + private: + Thread(const Thread&); + Thread& operator=(const Thread&); + + static ACE_THR_FUNC_RETURN ThreadTask(void * param); + + ACE_thread_t m_iThreadId; + ACE_hthread_t m_hThreadHandle; + Runnable * m_task; + + typedef ACE_TSS ThreadStorage; + //global object - container for Thread class representation of every thread + static ThreadStorage m_ThreadStorage; + //use this object to determine current OS thread priority values mapped to enum Priority{} + static ThreadPriority m_TpEnum; + }; + +} +#endif -- cgit v1.2.3 From 1b52fa4206fee1917453f4a5a4e5b6ac84afcdf8 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 11:40:02 -0500 Subject: Backed out changeset: 5201ecc6b309 --HG-- branch : trunk --- sql/updates/3233_world_scripts_naxx.sql | 1 + sql/world_scripts_full.sql | 1 + src/bindings/scripts/ScriptMgr.cpp | 2 + .../scripts/scripts/zone/naxxramas/boss_gothik.cpp | 361 +++++++++++++++++++-- .../scripts/zone/naxxramas/instance_naxxramas.cpp | 8 +- 5 files changed, 338 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/sql/updates/3233_world_scripts_naxx.sql b/sql/updates/3233_world_scripts_naxx.sql index 67a8615951d..a5a71ba6233 100644 --- a/sql/updates/3233_world_scripts_naxx.sql +++ b/sql/updates/3233_world_scripts_naxx.sql @@ -6,6 +6,7 @@ INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comm (-28169, 28240, 0, 'Mutating Injection - Poison Cloud'); UPDATE creature_template SET scriptname = 'boss_grobbulus' WHERE entry = 15931; +update creature_template set scriptname='mob_gothik_minion' where entry in (16124,16125,16126,16127,16148,16149,16150); INSERT INTO creature_template (entry, spell1, flags_extra, scriptname) VALUES (16363, 28158, 128, ''), # Grobbulus Cloud diff --git a/sql/world_scripts_full.sql b/sql/world_scripts_full.sql index a1df130d207..8b28c3bc370 100644 --- a/sql/world_scripts_full.sql +++ b/sql/world_scripts_full.sql @@ -645,6 +645,7 @@ UPDATE `creature_template` SET `ScriptName`='boss_heigan' WHERE `entry`=15936; UPDATE `creature_template` SET `ScriptName`='boss_loatheb' WHERE `entry`=16011; UPDATE `creature_template` SET `ScriptName`='boss_razuvious' WHERE `entry`=16061; UPDATE `creature_template` SET `ScriptName`='boss_gothik' WHERE `entry`=16060; +UPDATE `creature_template` SET `ScriptName`='mob_gothik_minion' where `entry` IN (16124,16125,16126,16127,16148,16149,16150); UPDATE `creature_template` SET `ScriptName`='boss_thane_korthazz' WHERE `entry`=16064; UPDATE `creature_template` SET `ScriptName`='boss_sir_zeliek' WHERE `entry`=16063; UPDATE `creature_template` SET `ScriptName`='boss_lady_blaumeux' WHERE `entry`=16065; diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp index 4d7ed09fff4..849c4d64be5 100644 --- a/src/bindings/scripts/ScriptMgr.cpp +++ b/src/bindings/scripts/ScriptMgr.cpp @@ -389,6 +389,7 @@ extern void AddSC_boss_sapphiron(); extern void AddSC_boss_four_horsemen(); extern void AddSC_boss_faerlina(); extern void AddSC_boss_heigan(); +extern void AddSC_boss_gothik(); extern void AddSC_instance_naxxramas(); //Netherstorm @@ -1327,6 +1328,7 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf") AddSC_boss_sapphiron(); AddSC_boss_four_horsemen(); AddSC_boss_heigan(); + AddSC_boss_gothik(); AddSC_instance_naxxramas(); //Netherstorm diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp index 3a9c6a5b47a..7def6c370f4 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2008 - 2009 Trinity * 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 @@ -14,14 +14,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* ScriptData -SDName: Boss_Gothik -SD%Complete: 0 -SDComment: Placeholder -SDCategory: Naxxramas -EndScriptData */ - #include "precompiled.h" +#include "def_naxxramas.h" #define SAY_SPEECH -1533040 #define SAY_KILL -1533041 @@ -29,37 +23,336 @@ EndScriptData */ #define SAY_TELEPORT -1533043 //Gothik -#define SPELL_HARVESTSOUL 28679 -#define SPELL_SHADOWBOLT HEROIC(29317,56405) -#define SPELL_SOUL_SIPHON 43591 // cannot find the correct spell +#define SPELL_HARVEST_SOUL 28679 +#define SPELL_SHADOW_BOLT HEROIC(29317,56405) + +#define SPELL_INFORM_LIVE_TRAINEE 27892 +#define SPELL_INFORM_LIVE_KNIGHT 27928 +#define SPELL_INFORM_LIVE_RIDER 27935 +#define SPELL_INFORM_DEAD_TRAINEE 27915 +#define SPELL_INFORM_DEAD_KNIGHT 27931 +#define SPELL_INFORM_DEAD_RIDER 27937 + +#define MOB_LIVE_TRAINEE 16124 +#define MOB_LIVE_KNIGHT 16125 +#define MOB_LIVE_RIDER 16126 +#define MOB_DEAD_TRAINEE 16127 +#define MOB_DEAD_KNIGHT 16148 +#define MOB_DEAD_RIDER 16150 +#define MOB_DEAD_HORSE 16149 + +const struct Waves { uint32 entry, number, time; } +waves[] = +{ + {MOB_LIVE_TRAINEE, 2, 20000}, + {MOB_LIVE_TRAINEE, 2, 20000}, + {MOB_LIVE_TRAINEE, 2, 10000}, + {MOB_LIVE_KNIGHT, 1, 10000}, + {MOB_LIVE_TRAINEE, 2, 15000}, + {MOB_LIVE_KNIGHT, 1, 10000}, + {MOB_LIVE_TRAINEE, 2, 15000}, + {MOB_LIVE_TRAINEE, 2, 0}, + {MOB_LIVE_KNIGHT, 1, 10000}, + {MOB_LIVE_RIDER, 1, 10000}, + {MOB_LIVE_TRAINEE, 2, 5000}, + {MOB_LIVE_KNIGHT, 1, 15000}, + {MOB_LIVE_TRAINEE, 2, 0}, + {MOB_LIVE_RIDER, 1, 10000}, + {MOB_LIVE_KNIGHT, 2, 10000}, + {MOB_LIVE_TRAINEE, 2, 10000}, + {MOB_LIVE_RIDER, 1, 5000}, + {MOB_LIVE_KNIGHT, 1, 5000}, + {MOB_LIVE_TRAINEE, 2, 20000}, + {MOB_LIVE_TRAINEE, 2, 0}, + {MOB_LIVE_KNIGHT, 1, 0}, + {MOB_LIVE_RIDER, 1, 15000}, + {MOB_LIVE_TRAINEE, 2, 29000}, + {0, 0, 0}, +}; + +#define POS_Y_GATE -3360.78f + +enum Events +{ + EVENT_SUMMON = 1, + EVENT_HARVEST, + EVENT_BOLT, +}; + +#define POS_LIVE 3 +#define POS_DEAD 5 + +const float PosSummonLive[POS_LIVE][4] = +{ + {2669.7, -3430.9, 268.56, 1.6}, + {2692.0, -3430.9, 268.56, 1.6}, + {2714.1, -3430.9, 268.56, 1.6}, +}; + +const float PosSummonDead[POS_DEAD][4] = +{ + {2725.1, -3310.0, 268.85, 3.4}, + {2699.3, -3322.8, 268.60, 3.3}, + {2733.1, -3348.5, 268.84, 3.1}, + {2682.8, -3304.2, 268.85, 3.9}, + {2664.8, -3340.7, 268.23, 3.7}, +}; + +const float PosGround[4] = {2691.2, -3362.7, 267.68, 1.7}; +const float PosPlatform[4] = {2640.5, -3360.6, 285.26, 0}; + +struct TRINITY_DLL_DECL boss_gothikAI : public BossAI +{ + boss_gothikAI(Creature *c) : BossAI(c, BOSS_GOTHIK) {} + + uint32 waveCount; + std::vector liveTrigger; + std::vector deadTrigger; + + void Reset() + { + liveTrigger.clear(); + deadTrigger.clear(); + me->setActive(false); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + me->SetReactState(REACT_PASSIVE); + _Reset(); + } + + void EnterCombat(Unit *who) + { + for(uint32 i = 0; i < POS_LIVE; ++i) + if(Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonLive[i])) + liveTrigger.push_back(trigger); + for(uint32 i = 0; i < POS_DEAD; ++i) + if(Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonDead[i])) + deadTrigger.push_back(trigger); + + if(liveTrigger.size() < POS_LIVE || deadTrigger.size() < POS_DEAD) + { + error_log("Script Gothik: cannot summon triggers!"); + EnterEvadeMode(); + return; + } + + _EnterCombat(); + me->setActive(true); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + waveCount = 0; + events.ScheduleEvent(EVENT_SUMMON, 30000); + DoTeleportTo(PosPlatform); + DoScriptText(SAY_SPEECH, me); + if(instance) + instance->SetData(DATA_GOTHIK_GATE, 1); + } + + void JustSummoned(Creature *summon) + { + if(summon->GetEntry() == WORLD_TRIGGER) + summon->setActive(true); + else + { + summon->AI()->DoAction(me->HasReactState(REACT_PASSIVE) ? 1 : 0); + summon->AI()->EnterEvadeMode(); + } + summons.Summon(summon); + } + + void KilledUnit(Unit* victim) + { + if(!(rand()%5)) + DoScriptText(SAY_KILL, me); + } + + void JustDied(Unit* Killer) + { + _JustDied(); + DoScriptText(SAY_DEATH, me); + } + + void SpellHit(Unit *caster, const SpellEntry *spell) + { + uint32 spellId = 0; + switch(spell->Id) + { + case SPELL_INFORM_LIVE_TRAINEE: spellId = SPELL_INFORM_DEAD_TRAINEE; break; + case SPELL_INFORM_LIVE_KNIGHT: spellId = SPELL_INFORM_DEAD_KNIGHT; break; + case SPELL_INFORM_LIVE_RIDER: spellId = SPELL_INFORM_DEAD_RIDER; break; + } + if(spellId && me->isInCombat()) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST); + me->CastSpell(deadTrigger[rand()%POS_DEAD], spellId, true); + } + } + + void SpellHitTarget(Unit *target, const SpellEntry *spell) + { + if(!me->isInCombat()) + return; + + switch(spell->Id) + { + case SPELL_INFORM_DEAD_TRAINEE: DoSummon(MOB_DEAD_TRAINEE, target, 0); break; + case SPELL_INFORM_DEAD_KNIGHT: DoSummon(MOB_DEAD_KNIGHT, target, 0); break; + case SPELL_INFORM_DEAD_RIDER: DoSummon(MOB_DEAD_RIDER, target, 1.0f); + DoSummon(MOB_DEAD_HORSE, target, 1.0f); break; + } + } + + void UpdateAI(const uint32 diff) + { + if(!me->isInCombat()) + return; + + if(me->getThreatManager().isThreatListEmpty()) + { + EnterEvadeMode(); + return; + } + + if(me->HasReactState(REACT_AGGRESSIVE) && !UpdateVictim()) + return; + + events.Update(diff); + + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + + while(uint32 eventId = events.ExecuteEvent()) + { + switch(eventId) + { + case EVENT_SUMMON: + if(waves[waveCount].entry) + { + for(uint32 i = 0; i < waves[waveCount].number; ++i) + DoSummon(waves[waveCount].entry, liveTrigger[rand()%POS_LIVE], 1.0f); + events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); + ++waveCount; + } + else + { + DoScriptText(SAY_TELEPORT, me); + DoTeleportTo(PosGround); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + if(instance) + instance->SetData(DATA_GOTHIK_GATE, 0); + summons.DoAction(0, 0); + summons.DoZoneInCombat(); + events.ScheduleEvent(EVENT_BOLT, 1000); + events.ScheduleEvent(EVENT_HARVEST, 15000); + } + break; + case EVENT_BOLT: + DoCast(me->getVictim(), SPELL_SHADOW_BOLT); + events.ScheduleEvent(EVENT_BOLT, 1000); + return; + case EVENT_HARVEST: + DoCast(me->getVictim(), SPELL_HARVEST_SOUL); + events.ScheduleEvent(EVENT_HARVEST, 15000); + return; + } + } + + DoMeleeAttackIfReady(); + } +}; + +struct TRINITY_DLL_DECL mob_gothik_minionAI : public SpellAI +{ + mob_gothik_minionAI(Creature *c) : SpellAI(c) + { + liveSide = me->GetPositionY() < POS_Y_GATE; + } + + bool liveSide; + bool gateClose; + +#define SIDE_CHECK(who) (liveSide == (who->GetPositionY() < POS_Y_GATE)) + + void DoAction(const int32 param) + { + gateClose = param; + } + + void DamageTaken(Unit *attacker, uint32 &damage) + { + if(gateClose && !SIDE_CHECK(attacker)) + damage = 0; + } + + void JustDied(Unit *killer) + { + if(me->isSummon()) + { + if(Unit *owner = ((TempSummon*)me)->GetSummoner()) + SpellAI::JustDied(owner); + } + } + + void EnterEvadeMode() + { + if(!gateClose) + { + SpellAI::EnterEvadeMode(); + return; + } + + if(!_EnterEvadeMode()) + return; -//Unrelenting Trainee -#define SPELL_EAGLECLAW 30285 -#define SPELL_KNOCKDOWN_PASSIVE 6961 + Map *map = me->GetMap(); + if(map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if(i->getSource()->isAlive() && SIDE_CHECK(i->getSource())) + { + AttackStart(i->getSource()); + return; + } + } + } -//Unrelenting Deathknight -#define SPELL_CHARGE 22120 -#define SPELL_SHADOW_MARK 27825 + me->GetMotionMaster()->MoveIdle(); + Reset(); + } -//Unrelenting Rider -#define SPELL_UNHOLY_AURA 55606 -#define H_SPELL_UNHOLY_AURA 55608 -#define SPELL_SHADOWBOLT_VOLLEY 27831 //Search thru targets and find those who have the SHADOW_MARK to cast this on -#define H_SPELL_SHADOWBOLT_VOLLEY 55638 + void UpdateAI(const uint32 diff) + { + if(gateClose && (!SIDE_CHECK(me) || me->getVictim() && !SIDE_CHECK(me->getVictim()))) + { + EnterEvadeMode(); + return; + } -//Spectral Trainee -#define SPELL_ARCANE_EXPLOSION 27989 + SpellAI::UpdateAI(diff); + } +}; -//Spectral Deathknight -#define SPELL_WHIRLWIND 28334 -#define SPELL_SUNDER_ARMOR 25051 //cannot find sunder that reduces armor by 2950 -#define SPELL_CLEAVE 20677 -#define SPELL_MANA_BURN 17631 +CreatureAI* GetAI_boss_gothik(Creature *_Creature) +{ + return new boss_gothikAI (_Creature); +} -//Spectral Rider -#define SPELL_LIFEDRAIN 24300 -//USES SAME UNHOLY AURA AS UNRELENTING RIDER +CreatureAI* GetAI_mob_gothik_minion(Creature *_Creature) +{ + return new mob_gothik_minionAI (_Creature); +} -//Spectral Horse -#define SPELL_STOMP 27993 +void AddSC_boss_gothik() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_gothik"; + newscript->GetAI = &GetAI_boss_gothik; + newscript->RegisterSelf(); + newscript = new Script; + newscript->Name="mob_gothik_minion"; + newscript->GetAI = &GetAI_mob_gothik_minion; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index 23f44f5daf8..e5913660c3f 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -86,9 +86,10 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData LoadDoorData(doorData); } + std::set Worshipper; std::set HeiganEruption[4]; + GameObject *GothikGate; Creature *Sapphiron; - std::set Worshipper; void OnCreatureCreate(Creature *creature, bool add) { @@ -114,6 +115,7 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData switch(go->GetEntry()) { case GO_BIRTH: if(!add && Sapphiron) Sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); return; + case GO_GOTHIK_GATE: GothikGate = add ? go : NULL; break; } AddDoor(go, add); @@ -140,6 +142,10 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData case DATA_HEIGAN_ERUPT: HeiganErupt(value); break; + case DATA_GOTHIK_GATE: + if(GothikGate) + GothikGate->SetGoState(GOState(value)); + break; } } -- cgit v1.2.3 From 22b082519ee4c2edd33dc1dfdf58366a0a250cca Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 11:44:27 -0500 Subject: Backed out changeset: 7dcbf5239f55 --HG-- branch : trunk --- src/game/Unit.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index f142ea623a5..95547b68621 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2767,9 +2767,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell) { WeaponAttackType attType = BASE_ATTACK; - // Check damage class instead of attack type to correctly handle judgements - // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class - if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) + if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED && IsRangedWeaponSpell(spell)) attType = RANGED_ATTACK; // bonus from skills is 0.04% per skill Diff @@ -2811,7 +2809,9 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell) return SPELL_MISS_NONE; // Ranged attack cannot be parry/dodge only deflect - if (attType == RANGED_ATTACK) + // Check damage class instead of attack type to correctly handle judgements + // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class + if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) { // only if in front if (pVictim->HasInArc(M_PI,this)) -- cgit v1.2.3 From bf82601817c8282c801ecf0f1e87bf5631f12441 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 11:56:02 -0500 Subject: [7818] Implement SPELL_AURA_MOD_FACTION_REPUTATION_GAIN. Author: DonTomika --HG-- branch : trunk --- src/game/Player.cpp | 19 +++++++++++-------- src/game/Player.h | 2 +- src/game/SpellAuras.cpp | 3 +-- 3 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4efb3703c1f..2dffafc095a 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -5745,23 +5745,26 @@ ReputationRank Player::GetReputationRank(uint32 faction) const } //Calculate total reputation percent player gain with quest/creature level -int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest) +int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest) { float percent = 100.0f; float rate = for_quest ? sWorld.getRate(RATE_REPUTATION_LOWLEVEL_QUEST) : sWorld.getRate(RATE_REPUTATION_LOWLEVEL_KILL); - if(rate != 1.0f && creatureOrQuestLevel <= MaNGOS::XP::GetGrayLevel(getLevel())) + if (rate != 1.0f && creatureOrQuestLevel <= MaNGOS::XP::GetGrayLevel(getLevel())) percent *= rate; - int32 repMod = GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN); + float repMod = GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN); + + if (!for_quest) + repMod += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction); percent += rep > 0 ? repMod : -repMod; - if(percent <= 0.0f) + if (percent <= 0.0f) return 0; - return int32(sWorld.getRate(RATE_REPUTATION_GAIN)*rep*percent/100); + return int32(sWorld.getRate(RATE_REPUTATION_GAIN)*rep*percent/100.0f); } //Calculates how many reputation points player gains in victim's enemy factions @@ -5780,7 +5783,7 @@ void Player::RewardReputation(Unit *pVictim, float rate) if(Rep->repfaction1 && (!Rep->team_dependent || GetTeam()==ALLIANCE)) { - int32 donerep1 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue1,false); + int32 donerep1 = CalculateReputationGain(pVictim->getLevel(), Rep->repvalue1, Rep->repfaction1, false); donerep1 = int32(donerep1*rate); FactionEntry const *factionEntry1 = sFactionStore.LookupEntry(Rep->repfaction1); uint32 current_reputation_rank1 = GetReputationMgr().GetRank(factionEntry1); @@ -5798,7 +5801,7 @@ void Player::RewardReputation(Unit *pVictim, float rate) if(Rep->repfaction2 && (!Rep->team_dependent || GetTeam()==HORDE)) { - int32 donerep2 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue2,false); + int32 donerep2 = CalculateReputationGain(pVictim->getLevel(), Rep->repvalue2, Rep->repfaction2, false); donerep2 = int32(donerep2*rate); FactionEntry const *factionEntry2 = sFactionStore.LookupEntry(Rep->repfaction2); uint32 current_reputation_rank2 = GetReputationMgr().GetRank(factionEntry2); @@ -5823,7 +5826,7 @@ void Player::RewardReputation(Quest const *pQuest) { if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] ) { - int32 rep = CalculateReputationGain(GetQuestLevel(pQuest),pQuest->RewRepValue[i],true); + int32 rep = CalculateReputationGain(GetQuestLevel(pQuest), pQuest->RewRepValue[i], pQuest->RewRepFaction[i], true); FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]); if(factionEntry) GetReputationMgr().ModifyReputation(factionEntry, rep); diff --git a/src/game/Player.h b/src/game/Player.h index b322209a6f5..e9400c04430 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2257,7 +2257,7 @@ class TRINITY_DLL_SPEC Player : public Unit Item* _StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, bool update ); void UpdateKnownCurrencies(uint32 itemId, bool apply); - int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest); + int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest); void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData ); GridReference m_gridRef; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index c950371e517..68a254cf0a8 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -242,8 +242,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &AuraEffect::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance &AuraEffect::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance &AuraEffect::HandleModRating, //189 SPELL_AURA_MOD_RATING - &AuraEffect::HandleNULL, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN - &AuraEffect::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED + &AuraEffect::HandleNoImmediateEffect, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain &AuraEffect::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED &AuraEffect::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE &AuraEffect::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct) &AuraEffect::HandleNULL, //194 SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist -- cgit v1.2.3 From 8782d2d31a256cbde829a09fe66f5ab529b618a5 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 11:56:51 -0500 Subject: [7819] Correct use item ScalingStatValues data (ScalingStatValues.dbc): Author: DiSlord - ScalingStatDistribution stats multiplier - Armor bonus from ssv - Damage from ssv - Feral AP from ssv - Feral AP from ssv dps bonus Use item->StatsCount in apply mods Not allow equip item if level > ScalingStatDistribution->maxlevel field TODO find more info about ScalingStatValuesEntry->spellBonus --HG-- branch : trunk --- src/game/DBCStructure.h | 55 +++++++++++++++++++++++++++++++++-- src/game/ItemPrototype.h | 44 ++-------------------------- src/game/Player.cpp | 75 ++++++++++++++++++++++++++++++++---------------- 3 files changed, 105 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 3798785ca03..d5078e8b408 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1143,7 +1143,7 @@ struct RandomPropertiesPointsEntry struct ScalingStatDistributionEntry { uint32 Id; - uint32 StatMod[10]; + int32 StatMod[10]; uint32 Modifier[10]; uint32 MaxLevel; }; @@ -1152,7 +1152,58 @@ struct ScalingStatValuesEntry { uint32 Id; uint32 Level; - uint32 Multiplier[17]; + uint32 ssdMultiplier[5]; // Multiplier for ScalingStatDistribution + uint32 armorMod[4]; // Armor for level + uint32 dpsMod[6]; // DPS mod for level + uint32 spellBonus; // not sure.. TODO: need more info about + uint32 feralBonus; // Feral AP bonus + + uint32 getssdMultiplier(uint32 mask) const + { + if (mask&0x001F) + { + if(mask & 0x00000001) return ssdMultiplier[0]; + if(mask & 0x00000002) return ssdMultiplier[1]; + if(mask & 0x00000004) return ssdMultiplier[2]; + if(mask & 0x00000008) return ssdMultiplier[3]; + if(mask & 0x00000010) return ssdMultiplier[4]; + } + return 0; + } + uint32 getArmorMod(uint32 mask) const + { + if (mask&0x01E0) + { + if(mask & 0x00000020) return armorMod[0]; + if(mask & 0x00000040) return armorMod[1]; + if(mask & 0x00000080) return armorMod[2]; + if(mask & 0x00000100) return armorMod[3]; + } + return 0; + } + uint32 getDPSMod(uint32 mask) const + { + if (mask&0x7E00) + { + if(mask & 0x00000200) return dpsMod[0]; + if(mask & 0x00000400) return dpsMod[1]; + if(mask & 0x00000800) return dpsMod[2]; + if(mask & 0x00001000) return dpsMod[3]; + if(mask & 0x00002000) return dpsMod[4]; + if(mask & 0x00004000) return dpsMod[5]; + } + return 0; + } + uint32 getSpellBonus(uint32 mask) const + { + if (mask & 0x00008000) return spellBonus; + return 0; + } + uint32 getFeralBonus(uint32 mask) const + { + if (mask & 0x00010000) return feralBonus; + return 0; + } }; //struct SkillLineCategoryEntry{ diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index f87e52b2e22..e7a37dc8e14 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -600,46 +600,6 @@ struct ItemPrototype return false; } - uint32 GetScalingStatValuesColumn() const - { - if(ScalingStatValue & 0x00000001) // stat mod - return 0; - if(ScalingStatValue & 0x00000002) // stat mod - return 1; - if(ScalingStatValue & 0x00000004) // stat mod - return 2; - if(ScalingStatValue & 0x00000008) // stat mod - return 3; - if(ScalingStatValue & 0x00000010) // stat mod - return 4; - if(ScalingStatValue & 0x00000020) // armor mod - return 5; - if(ScalingStatValue & 0x00000040) // armor mod - return 6; - if(ScalingStatValue & 0x00000080) // armor mod - return 7; - if(ScalingStatValue & 0x00000100) // armor mod - return 8; - if(ScalingStatValue & 0x00000200) // damage mod - return 9; - if(ScalingStatValue & 0x00000400) // damage mod - return 10; - if(ScalingStatValue & 0x00000800) // damage mod - return 11; - if(ScalingStatValue & 0x00001000) // damage mod - return 12; - if(ScalingStatValue & 0x00002000) // damage mod - return 13; - if(ScalingStatValue & 0x00004000) // damage mod - return 14; - if(ScalingStatValue & 0x00008000) // spell power - return 15; - if(ScalingStatValue & 0x00020000) // feral AP - return 16; - - return 0; - } - uint32 GetMaxStackSize() const { return Stackable > 0 ? uint32(Stackable) : uint32(0x7FFFFFFF-1); } float getDPS() const @@ -652,12 +612,12 @@ struct ItemPrototype return temp*500/Delay; } - int32 getFeralBonus() const + int32 getFeralBonus(int32 extraDPS = 0) const { // 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc if (Class == ITEM_CLASS_WEAPON && (1<= INVENTORY_SLOT_BAG_END || !proto) return; + ScalingStatDistributionEntry const *ssd = proto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution) : 0; + ScalingStatValuesEntry const *ssv = proto->ScalingStatValue ? sScalingStatValuesStore.LookupEntry(getLevel()) : 0; + for (int i = 0; i < MAX_ITEM_PROTO_STATS; ++i) { uint32 statType = 0; - int32 val = 0; - - if(proto->ScalingStatDistribution) + int32 val = 0; + // If set ScalingStatDistribution need get stats and values from it + if (ssd && ssv) { - if(ScalingStatDistributionEntry const *ssd = sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution)) - { - statType = ssd->StatMod[i]; - - if(uint32 modifier = ssd->Modifier[i]) - { - uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel()); - if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level)) - { - uint32 multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()]; - val = (multiplier * modifier) / 10000; - } - } - } + if (ssd->StatMod[i] < 0) + continue; + statType = ssd->StatMod[i]; + val = (ssv->getssdMultiplier(proto->ScalingStatValue) * ssd->Modifier[i]) / 10000; } else { + if (proto->StatsCount >= i) + continue; statType = proto->ItemStat[i].ItemStatType; val = proto->ItemStat[i].ItemStatValue; } @@ -6661,8 +6656,15 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl } } - if (proto->Armor) - HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(proto->Armor), apply); + // If set ScalingStatValue armor get it or use item armor + uint32 armor = proto->Armor; + if (ssv) + { + if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue)) + armor = ssvarmor; + } + if (armor) + HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply); if (proto->Block) HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply); @@ -6699,23 +6701,42 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl attType = OFF_ATTACK; } - if (proto->Damage[0].DamageMin > 0 ) + float minDamage = proto->Damage[0].DamageMin; + float maxDamage = proto->Damage[0].DamageMax; + int32 extraDPS = 0; + // If set dpsMod in ScalingStatValue use it for min (70% from avernge), max (130% from averange) damage + if (ssv) + { + if (extraDPS = ssv->getDPSMod(proto->ScalingStatValue)) + { + float averange = extraDPS * proto->Delay / 1000.0f; + minDamage = 0.7f * averange; + maxDamage = 1.3f * averange; + } + } + if (minDamage > 0 ) { - damage = apply ? proto->Damage[0].DamageMin : BASE_MINDAMAGE; + damage = apply ? minDamage : BASE_MINDAMAGE; SetBaseWeaponDamage(attType, MINDAMAGE, damage); //sLog.outError("applying mindam: assigning %f to weapon mindamage, now is: %f", damage, GetWeaponDamageRange(attType, MINDAMAGE)); } - if (proto->Damage[0].DamageMax > 0 ) + if (maxDamage > 0 ) { - damage = apply ? proto->Damage[0].DamageMax : BASE_MAXDAMAGE; + damage = apply ? maxDamage : BASE_MAXDAMAGE; SetBaseWeaponDamage(attType, MAXDAMAGE, damage); } - // Druids get feral AP bonus from weapon dps + // Apply feral bonus from ScalingStatValue if set + if (ssv) + { + if (int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue)) + ApplyFeralAPBonus(feral_bonus, apply); + } + // Druids get feral AP bonus from weapon dps (lso use DPS from ScalingStatValue) if(getClass() == CLASS_DRUID) { - int32 feral_bonus = proto->getFeralBonus(); + int32 feral_bonus = proto->getFeralBonus(extraDPS); if (feral_bonus > 0) ApplyFeralAPBonus(feral_bonus, apply); } @@ -9844,6 +9865,10 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo return EQUIP_ERR_CANT_DO_RIGHT_NOW; } + ScalingStatDistributionEntry const *ssd = pProto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(pProto->ScalingStatDistribution) : 0; + if (ssd && ssd->MaxLevel < getLevel()) + return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; + uint8 eslot = FindEquipSlot( pProto, slot, swap ); if( eslot == NULL_SLOT ) return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; -- cgit v1.2.3 From 43b84c7b0786c941f2029797a93e05254276af83 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 11:57:25 -0500 Subject: Code style and cleanups in item equip checks. Author: VladimirMangos --HG-- branch : trunk --- src/game/Player.cpp | 86 ++++++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c29c9abe065..ba86b6b5bec 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -9870,17 +9870,17 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; uint8 eslot = FindEquipSlot( pProto, slot, swap ); - if( eslot == NULL_SLOT ) + if (eslot == NULL_SLOT) return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; - uint8 msg = CanUseItem( pItem , not_loading ); - if( msg != EQUIP_ERR_OK ) + uint8 msg = CanUseItem(pItem , not_loading); + if (msg != EQUIP_ERR_OK) return msg; - if( !swap && GetItemByPos( INVENTORY_SLOT_BAG_0, eslot ) ) + if (!swap && GetItemByPos(INVENTORY_SLOT_BAG_0, eslot)) return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE; // if swap ignore item (equipped also) - if(uint8 res2 = CanEquipUniqueItem(pItem, swap ? eslot : NULL_SLOT)) + if (uint8 res2 = CanEquipUniqueItem(pItem, swap ? eslot : NULL_SLOT)) return res2; // check unique-equipped special item classes @@ -9888,19 +9888,16 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo { for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { - if( Item* pBag = GetItemByPos( INVENTORY_SLOT_BAG_0, i ) ) + if (Item* pBag = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { - if( pBag != pItem ) + if (pBag != pItem) { - if( ItemPrototype const* pBagProto = pBag->GetProto() ) + if (ItemPrototype const* pBagProto = pBag->GetProto()) { - if( pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot ) ) - { - if(pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH) - return EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH; - else - return EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER; - } + if (pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot)) + return (pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH) + ? EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH + : EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER; } } } @@ -9909,25 +9906,25 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo uint32 type = pProto->InventoryType; - if(eslot == EQUIPMENT_SLOT_OFFHAND) + if (eslot == EQUIPMENT_SLOT_OFFHAND) { if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND) { - if(!CanDualWield()) + if (!CanDualWield()) return EQUIP_ERR_CANT_DUAL_WIELD; } else if (type == INVTYPE_2HWEAPON) { - if(!CanDualWield() || !CanTitanGrip()) + if (!CanDualWield() || !CanTitanGrip()) return EQUIP_ERR_CANT_DUAL_WIELD; } - if(IsTwoHandUsed()) + if (IsTwoHandUsed()) return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED; } // equip two-hand weapon case (with possible unequip 2 items) - if( type == INVTYPE_2HWEAPON ) + if (type == INVTYPE_2HWEAPON) { if (eslot == EQUIPMENT_SLOT_OFFHAND) { @@ -9942,9 +9939,9 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo // offhand item must can be stored in inventory for offhand item and it also must be unequipped Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); ItemPosCountVec off_dest; - if( offItem && (!not_loading || + if (offItem && (!not_loading || CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK || - CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) ) + CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK )) return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; } } @@ -9952,10 +9949,8 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo return EQUIP_ERR_OK; } } - if( !swap ) - return EQUIP_ERR_ITEM_NOT_FOUND; - else - return EQUIP_ERR_ITEMS_CANT_BE_SWAPPED; + + return !swap ? EQUIP_ERR_ITEM_NOT_FOUND : EQUIP_ERR_ITEMS_CANT_BE_SWAPPED; } uint8 Player::CanUnequipItem( uint16 pos, bool swap ) const @@ -10174,38 +10169,49 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p uint8 Player::CanUseItem( Item *pItem, bool not_loading ) const { - if( pItem ) + if (pItem) { sLog.outDebug( "STORAGE: CanUseItem item = %u", pItem->GetEntry()); - if( !isAlive() && not_loading ) + + if (!isAlive() && not_loading) return EQUIP_ERR_YOU_ARE_DEAD; - //if( isStunned() ) + + //if (isStunned()) // return EQUIP_ERR_YOU_ARE_STUNNED; + ItemPrototype const *pProto = pItem->GetProto(); - if( pProto ) + if (pProto) { - if( pItem->IsBindedNotWith(GetGUID()) ) + if (pItem->IsBindedNotWith(GetGUID())) return EQUIP_ERR_DONT_OWN_THAT_ITEM; - if( (pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0 ) + + if ((pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0) return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; - if( pItem->GetSkill() != 0 ) + + if (pItem->GetSkill() != 0) { - if( GetSkillValue( pItem->GetSkill() ) == 0 ) + if (GetSkillValue( pItem->GetSkill() ) == 0) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; } - if( pProto->RequiredSkill != 0 ) + + if (pProto->RequiredSkill != 0) { - if( GetSkillValue( pProto->RequiredSkill ) == 0 ) + if (GetSkillValue( pProto->RequiredSkill ) == 0) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; - else if( GetSkillValue( pProto->RequiredSkill ) < pProto->RequiredSkillRank ) + + if (GetSkillValue( pProto->RequiredSkill ) < pProto->RequiredSkillRank) return EQUIP_ERR_ERR_CANT_EQUIP_SKILL; } - if( pProto->RequiredSpell != 0 && !HasSpell( pProto->RequiredSpell ) ) + + if (pProto->RequiredSpell != 0 && !HasSpell(pProto->RequiredSpell)) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; - if( pProto->RequiredReputationFaction && uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank ) + + if (pProto->RequiredReputationFaction && uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) return EQUIP_ERR_CANT_EQUIP_REPUTATION; - if( getLevel() < pProto->RequiredLevel ) + + if (getLevel() < pProto->RequiredLevel) return EQUIP_ERR_CANT_EQUIP_LEVEL_I; + return EQUIP_ERR_OK; } } -- cgit v1.2.3 From c6407a8b4c795a3a757daa170489588ce59c7a5e Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 11:58:01 -0500 Subject: [7820] Fixed typo in [7819] that not allow correct work non-scalling item stats. Author: VladimirMangos --HG-- branch : trunk --- src/game/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index ba86b6b5bec..3b40880bef8 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6500,7 +6500,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl } else { - if (proto->StatsCount >= i) + if (i >= proto->StatsCount) continue; statType = proto->ItemStat[i].ItemStatType; val = proto->ItemStat[i].ItemStatValue; -- cgit v1.2.3 From d3839aaaf023efaf11635fb88298956a3a26b4f4 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 11:58:35 -0500 Subject: [7821] Fixed typo in comment and var. name. Author: KAPATEJIb --HG-- branch : trunk --- src/game/Player.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 3b40880bef8..f78fd969379 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6704,14 +6704,14 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl float minDamage = proto->Damage[0].DamageMin; float maxDamage = proto->Damage[0].DamageMax; int32 extraDPS = 0; - // If set dpsMod in ScalingStatValue use it for min (70% from avernge), max (130% from averange) damage + // If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage if (ssv) { if (extraDPS = ssv->getDPSMod(proto->ScalingStatValue)) { - float averange = extraDPS * proto->Delay / 1000.0f; - minDamage = 0.7f * averange; - maxDamage = 1.3f * averange; + float average = extraDPS * proto->Delay / 1000.0f; + minDamage = 0.7f * average; + maxDamage = 1.3f * average; } } if (minDamage > 0 ) -- cgit v1.2.3 From 9831dab114e72cec718315a97190c7d0806d08a2 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 11:59:15 -0500 Subject: [7822] Avoid declined names form show in case disabled config option with russian client at non-russian realm. Author: Foks --HG-- branch : trunk --- src/game/CharacterHandler.cpp | 2 +- src/game/Player.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 93256cea150..29a54da5d06 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -173,7 +173,7 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) // 0 1 2 3 4 5 6 7 8 "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " // 9 10 11 12 13 14 - "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, genitive " + "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, character_declinedname.genitive " "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' " "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " "LEFT JOIN guild_member ON characters.guid = guild_member.guid " diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f78fd969379..bb3bcb1b391 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1492,7 +1492,12 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_GHOST; if(HasAtLoginFlag(AT_LOGIN_RENAME)) char_flags |= CHARACTER_FLAG_RENAME; - if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && (fields[14].GetCppString() != "")) + if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED)) + { + if(!fields[14].GetCppString().empty()) + char_flags |= CHARACTER_FLAG_DECLINED; + } + else char_flags |= CHARACTER_FLAG_DECLINED; *p_data << uint32(char_flags); // character flags -- cgit v1.2.3 From 5823e2c47166118fb26d41465378bdbdbdf4f3af Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 15:37:56 -0500 Subject: [7824] Implement use ArmorDamageModifier bonus for armor Author: DiSlord --HG-- branch : trunk --- src/game/Player.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/game/Player.cpp b/src/game/Player.cpp index bb3bcb1b391..e7fab7ac107 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6668,6 +6668,9 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue)) armor = ssvarmor; } + // Add armor bonus from ArmorDamageModifier if > 0 + if (proto->ArmorDamageModifier > 0) + armor+=proto->ArmorDamageModifier; if (armor) HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply); -- cgit v1.2.3 From 811eee356ddd3c0b486a828b39822daffd8ac97e Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 15:38:20 -0500 Subject: [7825] Fixed typo in comment and var. name. Author: BombermaG --HG-- branch : trunk --- src/game/DBCEnums.h | 2 +- src/game/SpellEffects.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index 655c9967989..44ab34d7a11 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -48,7 +48,7 @@ enum AchievementFlags ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value) ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??) ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value) - ACHIEVEMENT_FLAG_AVERANGE = 0x00000040, // Show as averange value (value / time_in_days) depend from other flag (by def use last criteria value) + ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, // Show as average value (value / time_in_days) depend from other flag (by def use last criteria value) ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value) ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, // ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, // diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 4f8a25698e3..330b0b9027b 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -651,9 +651,9 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) else if(m_spellInfo->SpellFamilyFlags[1]&0x00040000) { // Add main hand dps * effect[2] amount - float averange = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2; + float average = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2; int32 count = m_caster->CalculateSpellDamage(m_spellInfo, 2, m_spellInfo->EffectBasePoints[2], unitTarget); - damage += count * int32(averange * IN_MILISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); + damage += count * int32(average * IN_MILISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); } // Shield of Righteousness else if(m_spellInfo->SpellFamilyFlags[1]&0x00100000) -- cgit v1.2.3 From 047cc95388a67d5f33cb86082bbef03f654acec1 Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 16:50:47 -0500 Subject: *Add some distance check functions. By VladimirMangos. --HG-- branch : trunk --- src/game/Creature.cpp | 4 +- src/game/CreatureEventAI.cpp | 12 +- src/game/GridNotifiers.h | 2 +- src/game/Group.cpp | 14 +- src/game/GuardAI.cpp | 2 +- src/game/LootHandler.cpp | 2 +- src/game/MiscHandler.cpp | 4 +- src/game/Object.cpp | 305 ++++++++++++++++++++++++++++++++++- src/game/Object.h | 23 ++- src/game/Pet.h | 2 +- src/game/Player.cpp | 2 +- src/game/RandomMovementGenerator.cpp | 2 +- src/game/Spell.cpp | 9 +- src/game/Spell.h | 8 +- src/game/TradeHandler.cpp | 26 +-- src/game/Unit.cpp | 4 +- src/game/Unit.h | 4 +- 17 files changed, 364 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index f322d8326e1..8d7b877d4f5 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -2058,12 +2058,12 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const if(sMapStore.LookupEntry(GetMapId())->IsDungeon()) return false; - float length = pVictim->GetDistance(mHome_X, mHome_Y, mHome_Z); float AttackDist = GetAttackDistance(pVictim); uint32 ThreatRadius = sWorld.getConfig(CONFIG_THREAT_RADIUS); //Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and out of combat every update tick. - return ( length > (ThreatRadius > AttackDist ? ThreatRadius : AttackDist)); + return !pVictim->IsWithinDist3d(mHome_X,mHome_Y,mHome_Z, + ThreatRadius > AttackDist ? ThreatRadius : AttackDist); } CreatureDataAddon const* Creature::GetCreatureAddon() const diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 470225e0da0..5a84d43e80f 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -1288,13 +1288,10 @@ void CreatureEventAI::UpdateAI(const uint32 diff) break; case EVENT_T_RANGE: if (Combat) - { - if (m_creature->IsWithinDistInMap(m_creature->getVictim(),(float)(*i).Event.event_param2)) - { - if (m_creature->GetDistance(m_creature->getVictim()) >= (float)(*i).Event.event_param1) + if (m_creature->IsInMap(m_creature->getVictim())) + if (m_creature->IsInRange(m_creature->getVictim(), + (float)(*i).Event.event_param1,(float)(*i).Event.event_param2)) ProcessEvent(*i); - } - } break; } } @@ -1548,8 +1545,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge return false; //Unit is out of range of this spell - if (me->GetDistance(Target) > me->GetSpellMaxRangeForTarget(Target, TempRange) - || me->GetDistance(Target) < me->GetSpellMinRangeForTarget(Target, TempRange)) + if (!m_creature->IsInRange(Target,TempRange->minRangeHostile,TempRange->maxRangeHostile)) return false; return true; diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index 195f7206264..a9925f67406 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -489,7 +489,7 @@ namespace Trinity void Visit(PlayerMapType &m) { for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->GetDistance(i_searcher) <= i_dist) + if (itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->IsWithinDist(i_searcher,i_dist)) i_do(itr->getSource()); } diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 02fc72f2022..d2c17680e52 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -571,7 +571,7 @@ void Group::GroupLoot(const uint64& playerGUID, Loot *loot, Creature *creature) continue; if ( i->AllowedForPlayer(member) ) { - if (member->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (member->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { r->playerVote[member->GetGUID()] = NOT_EMITED_YET; ++r->totalPlayersRolling; @@ -621,7 +621,7 @@ void Group::NeedBeforeGreed(const uint64& playerGUID, Loot *loot, Creature *crea if (playerToRoll->CanUseItem(item) && i->AllowedForPlayer(playerToRoll) ) { - if (playerToRoll->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (playerToRoll->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET; ++r->totalPlayersRolling; @@ -669,7 +669,7 @@ void Group::MasterLoot(const uint64& playerGUID, Loot* /*loot*/, Creature *creat if (!looter->IsInWorld()) continue; - if (looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (looter->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { data << looter->GetGUID(); ++real_count; @@ -681,7 +681,7 @@ void Group::MasterLoot(const uint64& playerGUID, Loot* /*loot*/, Creature *creat for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) { Player *looter = itr->getSource(); - if (looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (looter->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) looter->GetSession()->SendPacket(&data); } } @@ -1338,7 +1338,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed ) { // not update if only update if need and ok Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid); - if(looter && looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if(looter && looter->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) return; } ++guid_itr; @@ -1351,7 +1351,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed ) { if(Player* pl = ObjectAccessor::FindPlayer(itr->guid)) { - if (pl->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (pl->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { bool refresh = pl->GetLootGUID()==creature->GetGUID(); @@ -1372,7 +1372,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed ) { if(Player* pl = ObjectAccessor::FindPlayer(itr->guid)) { - if (pl->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (pl->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { bool refresh = pl->GetLootGUID()==creature->GetGUID(); diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp index b716642ebd7..b7268758583 100644 --- a/src/game/GuardAI.cpp +++ b/src/game/GuardAI.cpp @@ -126,7 +126,7 @@ void GuardAI::UpdateAI(const uint32 /*diff*/) bool GuardAI::IsVisible(Unit *pl) const { - return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER) + return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_GUARDER)) && pl->isVisibleForOrDetect(m_creature,true); } diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index f8e2a6cde15..172a6ef46c2 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -224,7 +224,7 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ ) Player* playerGroup = itr->getSource(); if(!playerGroup) continue; - if (player->GetDistance2d(playerGroup) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (player->IsWithinDist(playerGroup,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) playersNear.push_back(playerGroup); } diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index a75141e2937..5a1f97cdf8c 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -775,9 +775,7 @@ void WorldSession::HandleCorpseReclaimOpcode(WorldPacket &recv_data) if(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType()==CORPSE_RESURRECTABLE_PVP) > time(NULL)) return; - float dist = corpse->GetDistance2d(GetPlayer()); - sLog.outDebug("Corpse 2D Distance: \t%f",dist); - if (dist > CORPSE_RECLAIM_RADIUS) + if (!corpse->IsWithinDist(GetPlayer(),CORPSE_RECLAIM_RADIUS,false)) return; uint64 guid; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index a436732f0a6..5c186921524 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1148,7 +1148,6 @@ InstanceData* WorldObject::GetInstanceData() Map *map = GetMap(); return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL; } - //slow float WorldObject::GetDistance(const WorldObject* obj) const { @@ -1176,7 +1175,7 @@ float WorldObject::GetExactDistance2d(const float x, const float y) const return sqrt((dx*dx) + (dy*dy)); } -float WorldObject::GetDistance(const float x, const float y, const float z) const +float WorldObject::GetDistance(float x, float y, float z) const { float dx = GetPositionX() - x; float dy = GetPositionY() - y; @@ -1219,10 +1218,33 @@ float WorldObject::GetDistanceZ(const WorldObject* obj) const return ( dist > 0 ? dist : 0); } -bool WorldObject::IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D) const +bool WorldObject::IsWithinDist3d(float x, float y, float z, float dist2compare) const { - if (!obj || !IsInMap(obj)) return false; + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float dz = GetPositionZ() - z; + float distsq = dx*dx + dy*dy + dz*dz; + + float sizefactor = GetObjectSize(); + float maxdist = dist2compare + sizefactor; + + return distsq < maxdist * maxdist; +} + +bool WorldObject::IsWithinDist2d(float x, float y, float dist2compare) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float distsq = dx*dx + dy*dy; + + float sizefactor = GetObjectSize(); + float maxdist = dist2compare + sizefactor; + + return distsq < maxdist * maxdist; +} +bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const +{ float dx = GetPositionX() - obj->GetPositionX(); float dy = GetPositionY() - obj->GetPositionY(); float distsq = dx*dx + dy*dy; @@ -1245,7 +1267,7 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const return(IsWithinLOS(ox, oy, oz )); } -bool WorldObject::IsWithinLOS(const float ox, const float oy, const float oz ) const +bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const { float x,y,z; GetPosition(x,y,z); @@ -1253,6 +1275,83 @@ bool WorldObject::IsWithinLOS(const float ox, const float oy, const float oz ) c return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f); } +bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D /* = true */) const +{ + float dx1 = GetPositionX() - obj1->GetPositionX(); + float dy1 = GetPositionY() - obj1->GetPositionY(); + float distsq1 = dx1*dx1 + dy1*dy1; + if(is3D) + { + float dz1 = GetPositionZ() - obj1->GetPositionZ(); + distsq1 += dz1*dz1; + } + + float dx2 = GetPositionX() - obj2->GetPositionX(); + float dy2 = GetPositionY() - obj2->GetPositionY(); + float distsq2 = dx2*dx2 + dy2*dy2; + if(is3D) + { + float dz2 = GetPositionZ() - obj2->GetPositionZ(); + distsq2 += dz2*dz2; + } + + return distsq1 < distsq2; +} + +bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D /* = true */) const +{ + float dx = GetPositionX() - obj->GetPositionX(); + float dy = GetPositionY() - obj->GetPositionY(); + float distsq = dx*dx + dy*dy; + if(is3D) + { + float dz = GetPositionZ() - obj->GetPositionZ(); + distsq += dz*dz; + } + + float sizefactor = GetObjectSize() + obj->GetObjectSize(); + + float mindist = minRange + sizefactor; + if(distsq < mindist * mindist) + return false; + + float maxdist = maxRange + sizefactor; + return distsq < maxdist * maxdist; +} + +bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float distsq = dx*dx + dy*dy; + + float sizefactor = GetObjectSize(); + + float mindist = minRange + sizefactor; + if(distsq < mindist * mindist) + return false; + + float maxdist = maxRange + sizefactor; + return distsq < maxdist * maxdist; +} + +bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float maxRange) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float dz = GetPositionZ() - z; + float distsq = dx*dx + dy*dy + dz*dz; + + float sizefactor = GetObjectSize(); + + float mindist = minRange + sizefactor; + if(distsq < mindist * mindist) + return false; + + float maxdist = maxRange + sizefactor; + return distsq < maxdist * maxdist; +} + float WorldObject::GetAngle(const WorldObject* obj) const { if(!obj) return 0; @@ -1914,6 +2013,81 @@ Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint3 return summon; } +/* +namespace MaNGOS +{ + class NearUsedPosDo + { + public: + NearUsedPosDo(WorldObject const& obj, WorldObject const* searcher, float angle, ObjectPosSelector& selector) + : i_object(obj), i_searcher(searcher), i_angle(angle), i_selector(selector) {} + + void operator()(Corpse*) const {} + void operator()(DynamicObject*) const {} + + void operator()(Creature* c) const + { + // skip self or target + if(c==i_searcher || c==&i_object) + return; + + float x,y,z; + + if( !c->isAlive() || c->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) || + !c->GetMotionMaster()->GetDestination(x,y,z) ) + { + x = c->GetPositionX(); + y = c->GetPositionY(); + } + + add(c,x,y); + } + + template + void operator()(T* u) const + { + // skip self or target + if(u==i_searcher || u==&i_object) + return; + + float x,y; + + x = u->GetPositionX(); + y = u->GetPositionY(); + + add(u,x,y); + } + + // we must add used pos that can fill places around center + void add(WorldObject* u, float x, float y) const + { + // u is too nearest/far away to i_object + if(!i_object.IsInRange2d(x,y,i_selector.m_dist - i_selector.m_size,i_selector.m_dist + i_selector.m_size)) + return; + + float angle = i_object.GetAngle(u)-i_angle; + + // move angle to range -pi ... +pi + while( angle > M_PI) + angle -= 2.0f * M_PI; + while(angle < -M_PI) + angle += 2.0f * M_PI; + + // dist include size of u + float dist2d = i_object.GetDistance2d(x,y); + i_selector.AddUsedPos(u->GetObjectSize(),angle,dist2d + i_object.GetObjectSize()); + } + private: + WorldObject const& i_object; + WorldObject const* i_searcher; + float i_angle; + ObjectPosSelector& i_selector; + }; +} // namespace MaNGOS +*/ + +//=================================================================================================== + void WorldObject::GetNearPoint2D(float &x, float &y, float distance2d, float absAngle ) const { x = GetPositionX() + (GetObjectSize() + distance2d) * cos(absAngle); @@ -1926,10 +2100,127 @@ void WorldObject::GetNearPoint2D(float &x, float &y, float distance2d, float abs void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle ) const { GetNearPoint2D(x,y,distance2d+searcher_size,absAngle); - z = GetPositionZ(); - UpdateGroundPositionZ(x,y,z); + + /* + // if detection disabled, return first point + if(!sWorld.getConfig(CONFIG_DETECT_POS_COLLISION)) + { + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + return; + } + + // or remember first point + float first_x = x; + float first_y = y; + bool first_los_conflict = false; // first point LOS problems + + // prepare selector for work + ObjectPosSelector selector(GetPositionX(),GetPositionY(),GetObjectSize(),distance2d+searcher_size); + + // adding used positions around object + { + CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::NearUsedPosDo u_do(*this,searcher,absAngle,selector); + MaNGOS::WorldObjectWorker worker(this,u_do); + + TypeContainerVisitor, GridTypeMapContainer > grid_obj_worker(worker); + TypeContainerVisitor, WorldTypeMapContainer > world_obj_worker(worker); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap()); + cell_lock->Visit(cell_lock, world_obj_worker, *GetMap()); + } + + // maybe can just place in primary position + if( selector.CheckOriginal() ) + { + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + + first_los_conflict = true; // first point have LOS problems + } + + float angle; // candidate of angle for free pos + + // special case when one from list empty and then empty side preferred + if(selector.FirstAngle(angle)) + { + GetNearPoint2D(x,y,distance2d,absAngle+angle); + z = GetPositionZ(); + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + } + + // set first used pos in lists + selector.InitializeAngle(); + + // select in positions after current nodes (selection one by one) + while(selector.NextAngle(angle)) // angle for free pos + { + GetNearPoint2D(x,y,distance2d,absAngle+angle); + z = GetPositionZ(); + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + } + + // BAD NEWS: not free pos (or used or have LOS problems) + // Attempt find _used_ pos without LOS problem + + if(!first_los_conflict) + { + x = first_x; + y = first_y; + + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + return; + } + + // special case when one from list empty and then empty side preferred + if( selector.IsNonBalanced() ) + { + if(!selector.FirstAngle(angle)) // _used_ pos + { + GetNearPoint2D(x,y,distance2d,absAngle+angle); + z = GetPositionZ(); + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + } + } + + // set first used pos in lists + selector.InitializeAngle(); + + // select in positions after current nodes (selection one by one) + while(selector.NextUsedAngle(angle)) // angle for used pos but maybe without LOS problem + { + GetNearPoint2D(x,y,distance2d,absAngle+angle); + z = GetPositionZ(); + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + + if(IsWithinLOS(x,y,z)) + return; + } + + // BAD BAD NEWS: all found pos (free and used) have LOS problem :( + x = first_x; + y = first_y; + + UpdateGroundPositionZ(x,y,z); // update to LOS height if available + */ } void WorldObject::GetGroundPoint(float &x, float &y, float &z, float dist, float angle) diff --git a/src/game/Object.h b/src/game/Object.h index 01c31d5b9b4..326b09cfb73 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -461,11 +461,11 @@ class TRINITY_DLL_SPEC WorldObject : public Object virtual const char* GetNameForLocaleIdx(int32 /*locale_idx*/) const { return GetName(); } float GetDistance( const WorldObject* obj ) const; - float GetDistance(const float x, const float y, const float z) const; + float GetDistance(float x, float y, float z) const; float GetDistanceSq(const float &x, const float &y, const float &z) const; float GetDistanceSq(const WorldObject *obj) const; float GetDistance2d(const WorldObject* obj) const; - float GetDistance2d(const float x, const float y) const; + float GetDistance2d(float x, float y) const; float GetExactDistance2d(const float x, const float y) const; float GetDistanceZ(const WorldObject* obj) const; bool IsInMap(const WorldObject* obj) const @@ -473,9 +473,24 @@ class TRINITY_DLL_SPEC WorldObject : public Object return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj); } - bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D = true) const; - bool IsWithinLOS(const float x, const float y, const float z ) const; + bool IsWithinDist3d(float x, float y, float z, float dist2compare) const; + bool IsWithinDist2d(float x, float y, float dist2compare) const; + bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const; + bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const + // use only if you will sure about placing both object at same map + { + return obj && _IsWithinDist(obj,dist2compare,is3D); + } + bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const + { + return obj && IsInMap(obj) && _IsWithinDist(obj,dist2compare,is3D); + } + bool IsWithinLOS(float x, float y, float z) const; bool IsWithinLOSInMap(const WorldObject* obj) const; + bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const; + bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const; + bool IsInRange2d(float x, float y, float minRange, float maxRange) const; + bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const; float GetAngle( const WorldObject* obj ) const; float GetAngle( const float x, const float y ) const; diff --git a/src/game/Pet.h b/src/game/Pet.h index ea82b7360bc..b76b53ab554 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -121,7 +121,7 @@ typedef std::vector AutoSpellList; #define ACTIVE_SPELLS_MAX 4 -#define OWNER_MAX_DISTANCE 100 +#define OWNER_MAX_DISTANCE 100.0f #define PET_FOLLOW_DIST 1 #define PET_FOLLOW_ANGLE (M_PI/2) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index e7fab7ac107..a68002445bc 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1673,7 +1673,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!(options & TELE_TO_NOT_UNSUMMON_PET)) { //same map, only remove pet if out of range for new position - if(pet && pet->GetDistance(x,y,z) >= OWNER_MAX_DISTANCE) + if(pet && !pet->IsWithinDist3d(x,y,z, OWNER_MAX_DISTANCE)) UnsummonPetTemporaryIfAny(); } diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp index 2e0e0174a40..93e10ad6115 100644 --- a/src/game/RandomMovementGenerator.cpp +++ b/src/game/RandomMovementGenerator.cpp @@ -195,7 +195,7 @@ RandomMovementGenerator::Update(Creature &creature, const uint32 &diff creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE); _setRandomLocation(creature); } - else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f) + else if(creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(),PET_FOLLOW_DIST+2.5f)) { creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE); _setRandomLocation(creature); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index b8b92cbbadf..2c778616d78 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1425,7 +1425,7 @@ struct TargetDistanceOrder : public std::binary_function" bool operator()(const Unit* _Left, const Unit* _Right) const { - return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right)); + return MainTarget->GetDistanceOrder(_Left,_Right); } }; @@ -1490,7 +1490,7 @@ void Spell::SearchChainTarget(std::list &TagUnitMap, float max_range, uin if(cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) break; while(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE - && !m_caster->isInFront(*next, max_range) + && !m_caster->isInFrontInMap(*next, max_range) || !m_caster->canSeeOrDetect(*next, false) || !cur->IsWithinLOSInMap(*next)) { @@ -4857,10 +4857,9 @@ SpellCastResult Spell::CheckRange(bool strict) if(m_targets.m_targetMask == TARGET_FLAG_DEST_LOCATION && m_targets.m_destX != 0 && m_targets.m_destY != 0 && m_targets.m_destZ != 0) { - float dist = m_caster->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); - if(dist > max_range) + if(!m_caster->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,max_range)) return SPELL_FAILED_OUT_OF_RANGE; - if(dist < min_range) + if(m_caster->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,min_range)) return SPELL_FAILED_TOO_CLOSE; } diff --git a/src/game/Spell.h b/src/game/Spell.h index e2ce4668952..694bcf11277 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -668,6 +668,10 @@ namespace Trinity { Unit *target = (Unit*)itr->getSource(); + // mostly phase check + if(!itr->getSource()->IsInMap(i_source)) + continue; + switch (i_TargetType) { case SPELL_TARGETS_ENEMY: @@ -708,11 +712,11 @@ namespace Trinity i_data->push_back(target); break; case PUSH_IN_FRONT: - if(i_source->isInFront(target, i_radius, M_PI/3)) + if(i_source->isInFrontInMap(target, i_radius, M_PI/3)) i_data->push_back(target); break; case PUSH_IN_BACK: - if(i_source->isInBack(target, i_radius, M_PI/3)) + if(i_source->isInBackInMap(target, i_radius, M_PI/3)) i_data->push_back(target); break; case PUSH_IN_LINE: diff --git a/src/game/TradeHandler.cpp b/src/game/TradeHandler.cpp index 439626861fd..3cead4551c1 100644 --- a/src/game/TradeHandler.cpp +++ b/src/game/TradeHandler.cpp @@ -461,30 +461,30 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) { CHECK_PACKET_SIZE(recvPacket,8); - if( GetPlayer()->pTrader ) + if (GetPlayer()->pTrader) return; uint64 ID; - if( !GetPlayer()->isAlive() ) + if (!GetPlayer()->isAlive()) { SendTradeStatus(TRADE_STATUS_YOU_DEAD); return; } - if( GetPlayer()->hasUnitState(UNIT_STAT_STUNNED) ) + if (GetPlayer()->hasUnitState(UNIT_STAT_STUNNED)) { SendTradeStatus(TRADE_STATUS_YOU_STUNNED); return; } - if( isLogingOut() ) + if (isLogingOut()) { SendTradeStatus(TRADE_STATUS_YOU_LOGOUT); return; } - if( GetPlayer()->isInFlight() ) + if (GetPlayer()->isInFlight()) { SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); return; @@ -494,43 +494,43 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) Player* pOther = ObjectAccessor::FindPlayer( ID ); - if( !pOther ) + if (!pOther) { SendTradeStatus(TRADE_STATUS_NO_TARGET); return; } - if( pOther == GetPlayer() || pOther->pTrader ) + if (pOther == GetPlayer() || pOther->pTrader) { SendTradeStatus(TRADE_STATUS_BUSY); return; } - if( !pOther->isAlive() ) + if (!pOther->isAlive()) { SendTradeStatus(TRADE_STATUS_TARGET_DEAD); return; } - if( pOther->isInFlight() ) + if (pOther->isInFlight()) { SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); return; } - if( pOther->hasUnitState(UNIT_STAT_STUNNED) ) + if (pOther->hasUnitState(UNIT_STAT_STUNNED)) { SendTradeStatus(TRADE_STATUS_TARGET_STUNNED); return; } - if( pOther->GetSession()->isLogingOut() ) + if (pOther->GetSession()->isLogingOut()) { SendTradeStatus(TRADE_STATUS_TARGET_LOGOUT); return; } - if( pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()) ) + if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendTradeStatus(TRADE_STATUS_IGNORE_YOU); return; @@ -542,7 +542,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) return; } - if( pOther->GetDistance2d( _player ) > 10.0f ) + if (!pOther->IsWithinDistInMap(_player,10.0f,false)) { SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); return; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 2c1c50c20ae..e176405d043 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3562,7 +3562,7 @@ Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const return NULL; } -bool Unit::isInFront(Unit const* target, float distance, float arc) const +bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const { return IsWithinDistInMap(target, distance) && HasInArc( arc, target ); } @@ -3572,7 +3572,7 @@ void Unit::SetInFront(Unit const* target) SetOrientation(GetAngle(target)); } -bool Unit::isInBack(Unit const* target, float distance, float arc) const +bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const { return IsWithinDistInMap(target, distance) && !HasInArc( 2 * M_PI - arc, target ); } diff --git a/src/game/Unit.h b/src/game/Unit.h index bb303473e7b..bbd7471b1b8 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1403,9 +1403,9 @@ class TRINITY_DLL_SPEC Unit : public WorldObject float GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const; void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; } - bool isInFront(Unit const* target,float distance, float arc = M_PI) const; + bool isInFrontInMap(Unit const* target,float distance, float arc = M_PI) const; void SetInFront(Unit const* target); - bool isInBack(Unit const* target, float distance, float arc = M_PI) const; + bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const; bool isInLine(Unit const* target, float distance) const; // Visibility system -- cgit v1.2.3 From 662dbb97448dddef46cc5cad61bef6afaa2c19bd Mon Sep 17 00:00:00 2001 From: megamage Date: Thu, 14 May 2009 20:02:10 -0500 Subject: *Fix a typo that cause crash. Thanks to Drahy. --HG-- branch : trunk --- src/game/SpellAuras.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 68a254cf0a8..f7643747a21 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -242,7 +242,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &AuraEffect::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance &AuraEffect::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance &AuraEffect::HandleModRating, //189 SPELL_AURA_MOD_RATING - &AuraEffect::HandleNoImmediateEffect, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain &AuraEffect::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED + &AuraEffect::HandleNoImmediateEffect, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain + &AuraEffect::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED &AuraEffect::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE &AuraEffect::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct) &AuraEffect::HandleNULL, //194 SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist -- cgit v1.2.3 From 854e791c2fcebc3d5244e5924574acb6f20ad896 Mon Sep 17 00:00:00 2001 From: Genars & Aokromes Date: Thu, 14 May 2009 23:07:17 +0200 Subject: New server options to block adding GMs to friends by players and to block inviting GMs to parties --HG-- branch : trunk --- src/game/GroupHandler.cpp | 6 ++++++ src/game/MiscHandler.cpp | 39 ++++++++++++++++++++--------------- src/game/World.cpp | 4 +++- src/game/World.h | 2 ++ src/trinitycore/trinitycore.conf.dist | 12 +++++++++++ 5 files changed, 45 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index b0094989e19..cd7004f5a07 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -78,6 +78,12 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) return; } + // restrict invite to GMs + if (!sWorld.getConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster()) + { + SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); + return; + } // can't group with if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 5a1f97cdf8c..f7c53e536c4 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -44,6 +44,7 @@ #include "Pet.h" #include "SocialMgr.h" #include "CellImpl.h" +#include "AccountMgr.h" #include "Vehicle.h" #include "CreatureAI.h" @@ -561,12 +562,13 @@ void WorldSession::HandleAddFriendOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: %s asked to add friend : '%s'", GetPlayer()->GetName(), friendName.c_str() ); - CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddFriendOpcodeCallBack, GetAccountId(), friendNote, "SELECT guid, race FROM characters WHERE name = '%s'", friendName.c_str()); + CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddFriendOpcodeCallBack, GetAccountId(), friendNote, "SELECT guid, race, account FROM characters WHERE name = '%s'", friendName.c_str()); } void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult *result, uint32 accountId, std::string friendNote) { uint64 friendGuid; + uint64 friendAcctid; uint32 team; FriendsResult friendResult; @@ -582,30 +584,33 @@ void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult *result, uint32 acc { friendGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER); team = Player::TeamForRace((*result)[1].GetUInt8()); + friendAcctid = (*result)[2].GetUInt32(); delete result; - if(friendGuid) + if ( session->GetSecurity() >= SEC_MODERATOR || sWorld.getConfig(CONFIG_ALLOW_GM_FRIEND) || accmgr.GetSecurity(friendAcctid) < SEC_MODERATOR) { - if(friendGuid==session->GetPlayer()->GetGUID()) - friendResult = FRIEND_SELF; - else if(session->GetPlayer()->GetTeam() != team && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && session->GetSecurity() < SEC_MODERATOR) - friendResult = FRIEND_ENEMY; - else if(session->GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid))) - friendResult = FRIEND_ALREADY; - else + if(friendGuid) { - Player* pFriend = ObjectAccessor::FindPlayer(friendGuid); - if( pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(session->GetPlayer())) - friendResult = FRIEND_ADDED_ONLINE; + if(friendGuid==session->GetPlayer()->GetGUID()) + friendResult = FRIEND_SELF; + else if(session->GetPlayer()->GetTeam() != team && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && session->GetSecurity() < SEC_MODERATOR) + friendResult = FRIEND_ENEMY; + else if(session->GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid))) + friendResult = FRIEND_ALREADY; else - friendResult = FRIEND_ADDED_OFFLINE; - if(!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false)) { - friendResult = FRIEND_LIST_FULL; - sLog.outDebug( "WORLD: %s's friend list is full.", session->GetPlayer()->GetName()); + Player* pFriend = ObjectAccessor::FindPlayer(friendGuid); + if( pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(session->GetPlayer())) + friendResult = FRIEND_ADDED_ONLINE; + else + friendResult = FRIEND_ADDED_OFFLINE; + if(!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false)) + { + friendResult = FRIEND_LIST_FULL; + sLog.outDebug( "WORLD: %s's friend list is full.", session->GetPlayer()->GetName()); + } } - session->GetPlayer()->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote); } } diff --git a/src/game/World.cpp b/src/game/World.cpp index fa44e527da5..665fb6d4bdc 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -792,7 +792,9 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList", false); m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList", false); m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false); - m_configs[CONFIG_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1); + m_configs[CONFIG_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1); + m_configs[CONFIG_ALLOW_GM_GROUP] = sConfig.GetBoolDefault("GM.AllowInvite", false); + m_configs[CONFIG_ALLOW_GM_FRIEND] = sConfig.GetBoolDefault("GM.AllowFriend", false); if(m_configs[CONFIG_START_GM_LEVEL] < m_configs[CONFIG_START_PLAYER_LEVEL]) { sLog.outError("GM.StartLevel (%i) must be in range StartPlayerLevel(%u)..%u. Set to %u.", diff --git a/src/game/World.h b/src/game/World.h index 11a83678d35..62648ebce2c 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -141,6 +141,8 @@ enum WorldConfigs CONFIG_GM_IN_GM_LIST, CONFIG_GM_IN_WHO_LIST, CONFIG_GM_LOG_TRADE, + CONFIG_ALLOW_GM_GROUP, + CONFIG_ALLOW_GM_FRIEND, CONFIG_START_GM_LEVEL, CONFIG_GM_LOWER_SECURITY, CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS, diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index 018ddf378b5..2748c92529a 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -1006,6 +1006,16 @@ Channel.SilentlyGMJoin = 0 # GM starting level (1-100) # Default: 1 # +# GM.AllowInvite +# Is GM accepting invites from players by default or not +# Default: 0 (false) +# 1 (true) +# +# GM.AllowFriend +# Are players allowed to add GMs to their friend list +# Default: 0 (false) +# 1 (true) +# # GM.LowerSecurity # Disallow a lower security member to interact with a higher one using commands # Default: 0 (disable) @@ -1027,6 +1037,8 @@ GM.InGMList = 0 GM.InWhoList = 0 GM.LogTrade = 1 GM.StartLevel = 80 +GM.AllowInvite = 0 +GM.AllowFriend = 0 GM.LowerSecurity = 0 GM.AllowAchievementGain = 1 -- cgit v1.2.3 From 7549076a38cc720acf2605422e78cc6ef8bda868 Mon Sep 17 00:00:00 2001 From: BroodWyrm Date: Fri, 15 May 2009 16:52:59 +0200 Subject: *Rewrite Moroes Script to fix reset bug --HG-- branch : trunk --- .../scripts/scripts/zone/karazhan/boss_moroes.cpp | 168 ++++++++------------- 1 file changed, 66 insertions(+), 102 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp index 115dfeab269..52e6f2e363c 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_moroes.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 +/* Copyright (C) 2006 - 2008 ScriptDev2 * 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 @@ -62,7 +62,10 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI { boss_moroesAI(Creature *c) : ScriptedAI(c) { - FirstTime = true; + for(int i = 0; i < 4; i++) + { + AddId[i] = 0; + } pInstance = ((ScriptedInstance*)c->GetInstanceData()); } @@ -77,7 +80,6 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI uint32 CheckAdds_Timer; uint32 AddId[4]; - bool FirstTime; bool InVanish; bool Enrage; @@ -91,12 +93,10 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI Enrage = false; InVanish = false; - - SpawnAdds(); - - m_creature->setFaction(16); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if(m_creature->GetHealth() > 0) + { + SpawnAdds(); + } if(pInstance) pInstance->SetData(DATA_MOROES_EVENT, NOT_STARTED); @@ -106,9 +106,11 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI { if(pInstance) pInstance->SetData(DATA_MOROES_EVENT, IN_PROGRESS); + + DoZoneInCombat(); } - void EnterCombat(Unit* who) + void Aggro(Unit* who) { StartEvent(); @@ -129,7 +131,7 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI void JustDied(Unit* victim) { - DoScriptText(SAY_DEATH, m_creature); + DoScriptText(SAY_DEATH, m_creature); if (pInstance) pInstance->SetData(DATA_MOROES_EVENT, DONE); @@ -147,33 +149,21 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { - if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_GARROTE)) + if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_GARROTE,0)) i->getSource()->RemoveAurasDueToSpell(SPELL_GARROTE); } } } - uint8 CheckAdd(uint64 guid) - { - Unit* pUnit = Unit::GetUnit((*m_creature), guid); - if (pUnit) - { - if (!pUnit->isAlive()) - return 1; // Exists but is dead - else - return 2; // Exists and is alive - } - return 0; // Does not exist - } - void SpawnAdds() { - Creature *pCreature = NULL; - - if (FirstTime) + DeSpawnAdds(); + if(isAddlistEmpty()) { + Creature *pCreature = NULL; std::vector AddList; + for(uint8 i = 0; i < 6; ++i) AddList.push_back(Adds[i]); @@ -193,48 +183,44 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI } ++i; } - - FirstTime = false; - } - else + }else { - for(uint8 i = 0; i < 4; ++i) + for(int i = 0; i < 4; i++) { - switch(CheckAdd(AddGUID[i])) + Creature *pCreature = m_creature->SummonCreature(AddId[i], Locations[i][0], Locations[i][1], POS_Z, Locations[i][2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + if (pCreature) { - case 0: - pCreature = m_creature->SummonCreature(AddId[i], Locations[i][0], Locations[i][1], POS_Z, Locations[i][2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - if (pCreature) - AddGUID[i] = pCreature->GetGUID(); - break; - case 1: - pCreature = (Unit::GetCreature((*m_creature), AddGUID[i])); - if (pCreature) - { - pCreature->Respawn(); - pCreature->AI()->EnterEvadeMode(); - } - break; - case 2: - pCreature = (Unit::GetCreature((*m_creature), AddGUID[i])); - if (!pCreature->IsInEvadeMode()) - pCreature->AI()->EnterEvadeMode(); - break; + AddGUID[i] = pCreature->GetGUID(); } } } } + bool isAddlistEmpty() + { + for(int i = 0; i < 4; i++) + { + if(AddId[i] == 0) + return true; + } + return false; + } + void DeSpawnAdds() { for(uint8 i = 0; i < 4 ; ++i) { - Unit* Temp = NULL; + Creature* Temp = NULL; if (AddGUID[i]) { - Temp = Unit::GetUnit((*m_creature),AddGUID[i]); + Temp = Creature::GetCreature((*m_creature),AddGUID[i]); if (Temp && Temp->isAlive()) + { + (*Temp).GetMotionMaster()->Clear(true); Temp->DealDamage(Temp, Temp->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + Temp->RemoveCorpse(); + } + } } } @@ -246,7 +232,7 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI Creature* Temp = NULL; if (AddGUID[i]) { - Temp = Unit::GetCreature(*m_creature, AddGUID[i]); + Temp = Creature::GetCreature((*m_creature),AddGUID[i]); if (Temp && Temp->isAlive()) { Temp->AI()->AttackStart(m_creature->getVictim()); @@ -295,39 +281,12 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI //Cast Vanish, then Garrote random victim if (Vanish_Timer < diff) { - m_creature->setFaction(35); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoCast(m_creature, SPELL_VANISH); InVanish = true; Vanish_Timer = 30000; Wait_Timer = 5000; }else Vanish_Timer -= diff; - if (InVanish) - { - if (Wait_Timer < diff) - { - switch(rand()%2) - { - case 0: DoScriptText(SAY_SPECIAL_1, m_creature); break; - case 1: DoScriptText(SAY_SPECIAL_2, m_creature); break; - } - - if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) - target->CastSpell(target, SPELL_GARROTE,true); - - m_creature->setFaction(16); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); - m_creature->AI()->AttackStart(m_creature->getVictim()); - InVanish = false; - }else Wait_Timer -= diff; - } - - //Gouge highest aggro, and attack second highest if (Gouge_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_GOUGE); @@ -336,27 +295,32 @@ struct TRINITY_DLL_DECL boss_moroesAI : public ScriptedAI if (Blind_Timer < diff) { - Unit* target = NULL; - std::list t_list = m_creature->getThreatManager().getThreatList(); - - if (t_list.empty()) - return; + Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (target && target->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinMeleeRange(target)) + { + DoCast(target, SPELL_BLIND); + Blind_Timer = 40000; + } + else + Blind_Timer = 1000; + }else Blind_Timer -= diff; + } - std::vector target_list; - for (std::list::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + if (InVanish) + { + if (Wait_Timer < diff) + { + switch(rand()%2) { - target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); - if (target && target->GetDistance2d(m_creature) < 5) - target_list.push_back(target); + case 0: DoScriptText(SAY_SPECIAL_1, m_creature); break; + case 1: DoScriptText(SAY_SPECIAL_2, m_creature); break; } - if (target_list.size()) - target = *(target_list.begin()+rand()%target_list.size()); - if (target) - DoCast(target, SPELL_BLIND); + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + target->CastSpell(target, SPELL_GARROTE,true); - Blind_Timer = 40000; - }else Blind_Timer -= diff; + InVanish = false; + }else Wait_Timer -= diff; } if (!InVanish) @@ -384,7 +348,7 @@ struct TRINITY_DLL_DECL boss_moroes_guestAI : public ScriptedAI pInstance->SetData(DATA_MOROES_EVENT, NOT_STARTED); } - void EnterCombat(Unit* who) {} + void Aggro(Unit* who) {} void AcquireGUID() { @@ -542,7 +506,7 @@ struct TRINITY_DLL_DECL boss_baron_rafe_dreugerAI : public boss_moroes_guestAI struct TRINITY_DLL_DECL boss_lady_catriona_von_indiAI : public boss_moroes_guestAI { //Holy Priest - boss_lady_catriona_von_indiAI(Creature *c) : boss_moroes_guestAI(c) {Reset();} + boss_lady_catriona_von_indiAI(Creature *c) : boss_moroes_guestAI(c) {} uint32 DispelMagic_Timer; uint32 GreaterHeal_Timer; @@ -612,7 +576,7 @@ struct TRINITY_DLL_DECL boss_lady_catriona_von_indiAI : public boss_moroes_guest struct TRINITY_DLL_DECL boss_lady_keira_berrybuckAI : public boss_moroes_guestAI { //Holy Pally - boss_lady_keira_berrybuckAI(Creature *c) : boss_moroes_guestAI(c) {Reset();} + boss_lady_keira_berrybuckAI(Creature *c) : boss_moroes_guestAI(c) {} uint32 Cleanse_Timer; uint32 GreaterBless_Timer; @@ -729,7 +693,7 @@ struct TRINITY_DLL_DECL boss_lord_robin_darisAI : public boss_moroes_guestAI struct TRINITY_DLL_DECL boss_lord_crispin_ferenceAI : public boss_moroes_guestAI { //Arms Warr - boss_lord_crispin_ferenceAI(Creature *c) : boss_moroes_guestAI(c) {Reset();} + boss_lord_crispin_ferenceAI(Creature *c) : boss_moroes_guestAI(c) {} uint32 Disarm_Timer; uint32 HeroicStrike_Timer; -- cgit v1.2.3 From e6cd40a6191ba42bee1941359db48188809a0325 Mon Sep 17 00:00:00 2001 From: Anubisss Date: Fri, 15 May 2009 17:54:10 +0200 Subject: *Implement GetSpellCooldowns() for get m_spellCooldowns(Player's map of spell CDs). --HG-- branch : trunk --- src/game/Player.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/Player.h b/src/game/Player.h index e9400c04430..0223364cce0 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1669,6 +1669,8 @@ class TRINITY_DLL_SPEC Player : public Unit //End of PvP System + inline SpellCooldowns GetSpellCooldowns() const { return m_spellCooldowns; } + void SetDrunkValue(uint16 newDrunkValue, uint32 itemid=0); uint16 GetDrunkValue() const { return m_drunk; } static DrunkenState GetDrunkenstateByValue(uint16 value); @@ -2152,7 +2154,6 @@ class TRINITY_DLL_SPEC Player : public Unit PlayerMails m_mail; PlayerSpellMap m_spells; - SpellCooldowns m_spellCooldowns; uint32 m_lastPotionId; // last used health/mana potion in combat, that block next potion use ActionButtonList m_actionButtons; @@ -2285,6 +2286,8 @@ class TRINITY_DLL_SPEC Player : public Unit AchievementMgr m_achievementMgr; ReputationMgr m_reputationMgr; + + SpellCooldowns m_spellCooldowns; }; void AddItemsSetItem(Player*player,Item *item); -- cgit v1.2.3 From ad92f5e210b7a2c0584cdabd30560fe723d160be Mon Sep 17 00:00:00 2001 From: Anubisss Date: Fri, 15 May 2009 17:58:06 +0200 Subject: *Fix Glyph of Ice Block. *Thanks QAston for the help in the SpellFamilyMask. --HG-- branch : trunk --- sql/updates/3323_world_spell_proc_event.sql | 4 ++++ sql/world_spell_full.sql | 3 ++- src/game/Unit.cpp | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 sql/updates/3323_world_spell_proc_event.sql (limited to 'src') diff --git a/sql/updates/3323_world_spell_proc_event.sql b/sql/updates/3323_world_spell_proc_event.sql new file mode 100644 index 00000000000..e1ed1649994 --- /dev/null +++ b/sql/updates/3323_world_spell_proc_event.sql @@ -0,0 +1,4 @@ +-- Glyph of Ice Block -- +DELETE FROM `spell_proc_event` WHERE `entry` = 56372; +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(56372, 0x00, 3, 0x00000000, 0x00000080, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0); diff --git a/sql/world_spell_full.sql b/sql/world_spell_full.sql index af93f1f4cd2..12a3f5d2745 100644 --- a/sql/world_spell_full.sql +++ b/sql/world_spell_full.sql @@ -1491,5 +1491,6 @@ INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `Spell (974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3), (9782, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0), (9784, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0), -(9799, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0); +(9799, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0), +(56372, 0, 3, 0, 128, 0, 16384, 0, 0, 0, 0); -- (42370, 0x00, 11, 0x00000080, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); \ No newline at end of file diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index e176405d043..5c7bf244571 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5331,6 +5331,25 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger CastSpell(this, 28682, true, castItem, triggeredByAura); return (procEx & PROC_EX_CRITICAL_HIT);// charge update only at crit hits, no hidden cooldowns } + // Glyph of Ice Block + case 56372: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + SpellCooldowns SpellCDs = ((Player*)this)->GetSpellCooldowns(); + // remove cooldowns on all ranks of Frost Nova + for(SpellCooldowns::const_iterator itr = SpellCDs.begin(); itr != SpellCDs.end(); itr++) + { + SpellEntry const* SpellCDs_entry = sSpellStore.LookupEntry(itr->first); + // Frost Nova + if(SpellCDs_entry && SpellCDs_entry->SpellFamilyName == SPELLFAMILY_MAGE && SpellCDs_entry->SpellFamilyFlags[0] & 0x00000040) + { + ((Player*)this)->RemoveSpellCooldown(SpellCDs_entry->Id, true); + } + } + break; + } } break; } -- cgit v1.2.3