diff options
author | Vincent-Michael <Vincent_Michael@gmx.de> | 2014-04-19 19:57:46 +0200 |
---|---|---|
committer | Vincent-Michael <Vincent_Michael@gmx.de> | 2014-04-19 19:57:46 +0200 |
commit | 8a110f2645efdba4e15ddd13745b1b4110a7c8cb (patch) | |
tree | 1197c8abce2c2acf0d2384663551df663ff1d220 /src | |
parent | 5454e10b52c6e8c75afba25a1cc8fb13c6ef8dcc (diff) | |
parent | 93a68a66c3009ea86569076ea05a39ce87dfb78d (diff) |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts:
src/server/game/DataStores/DBCStores.cpp
src/server/game/DataStores/DBCStructure.h
src/server/game/DataStores/DBCfmt.h
src/server/game/Entities/Unit/Unit.cpp
src/server/game/Spells/SpellMgr.cpp
src/server/scripts/Commands/cs_gobject.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_kilnara.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp
src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp
src/server/scripts/Spells/spell_paladin.cpp
Diffstat (limited to 'src')
27 files changed, 400 insertions, 178 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 3cfa79ed8d0..b82c77f029d 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -1147,6 +1147,7 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS: case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: // This also behaves like ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA + case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN: SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; // std case: increment at miscValue1 diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 91f62c1a697..0686272f191 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -800,6 +800,24 @@ Creature* ChatHandler::getSelectedCreature() return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(), m_session->GetPlayer()->GetTarget()); } +Player* ChatHandler::getSelectedPlayerOrSelf() +{ + if (!m_session) + return NULL; + + uint64 selected = m_session->GetPlayer()->GetTarget(); + if (!selected) + return m_session->GetPlayer(); + + // first try with selected target + Player* targetPlayer = ObjectAccessor::FindPlayer(selected); + // if the target is not a player, then return self + if (!targetPlayer) + targetPlayer = m_session->GetPlayer(); + + return targetPlayer; +} + char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1) { // skip empty diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index eb4c89bb8ea..5c541d07b5a 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -98,6 +98,8 @@ class ChatHandler Creature* getSelectedCreature(); Unit* getSelectedUnit(); WorldObject* getSelectedObject(); + // Returns either the selected player or self if there is no selected player + Player* getSelectedPlayerOrSelf(); char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL); char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL); diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 5b96f8b8271..9a3e5dcf0fd 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -76,6 +76,7 @@ DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt); DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore(ChrClassesXPowerTypesfmt); DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt); DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt); +DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt); DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt); DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore(CreatureModelDatafmt); DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt); @@ -376,6 +377,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");//15595 LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");//15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc");//15595 LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc");//15595 LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc");//15595 LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc");//15595 diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index ca91f1da1f2..af7007a17ae 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -103,6 +103,7 @@ extern DBCStorage <ChrRacesEntry> sChrRacesStore; extern DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore; extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore; extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore; +extern DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore; extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore; extern DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore; extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 6a548615c3b..1e5c2093b53 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -726,7 +726,7 @@ struct ChrClassesEntry struct ChrRacesEntry { uint32 RaceID; // 0 - // 1 unused + uint32 Flags; // 1 uint32 FactionID; // 2 facton template id // 3 unused uint32 model_m; // 4 @@ -780,7 +780,7 @@ struct CreatureDisplayInfoEntry uint32 Displayid; // 0 m_ID uint32 ModelId; // 1 m_modelID // 2 m_soundID - // 3 m_extendedDisplayInfoID + uint32 ExtraId; // 3 m_extendedDisplayInfoID float scale; // 4 m_creatureModelScale // 5 m_creatureModelAlpha // 6-8 m_textureVariation[3] @@ -794,6 +794,31 @@ struct CreatureDisplayInfoEntry // 16 }; +struct CreatureDisplayInfoExtraEntry +{ + //uint32 Id; // 0 + uint32 Race; // 1 + uint32 Gender; // 2 + //uint32 SkinColor; // 3 + //uint32 FaceType; // 4 + //uint32 HairType; // 5 + //uint32 HairStyle; // 6 + //uint32 FacialHair; // 7 + //uint32 HelmDisplayId; // 8 + //uint32 ShoulderDisplayId; // 9 + //uint32 ShirtDisplayId; // 10 + //uint32 ChestDisplayId; // 11 + //uint32 BeltDisplayId; // 12 + //uint32 LegsDisplayId; // 13 + //uint32 BootsDisplayId; // 14 + //uint32 WristDisplayId; // 15 + //uint32 GlovesDisplayId; // 16 + //uint32 TabardDisplayId; // 17 + //uint32 CloakDisplayId; // 18 + //uint32 CanEquip; // 19 + //char const* Texture; // 20 +}; + struct CreatureFamilyEntry { uint32 ID; // 0 m_ID @@ -812,7 +837,7 @@ struct CreatureFamilyEntry struct CreatureModelDataEntry { uint32 Id; - //uint32 Flags; + uint32 Flags; //char* ModelPath //uint32 Unk1; //float Scale; // Used in calculation of unit collision data diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 4b7f59bf380..41dc6afd4f7 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -40,11 +40,12 @@ char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxx char const CharTitlesEntryfmt[] = "nxssix"; char const ChatChannelsEntryfmt[] = "nixsx"; char const ChrClassesEntryfmt[] = "nixsxxxixiiiii"; -char const ChrRacesEntryfmt[] = "nxixiixixxxxixsxxxxxixxx"; +char const ChrRacesEntryfmt[] = "niixiixixxxxixsxxxxxixxx"; char const ChrClassesXPowerTypesfmt[] = "nii"; char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx"; -char const CreatureDisplayInfofmt[] = "nixxfxxxxxxxxxxxx"; -char const CreatureModelDatafmt[] = "nxxxxxxxxxxxxxffxxxxxxxxxxxxxxx"; +char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxxx"; +char const CreatureDisplayInfoExtrafmt[] = "diixxxxxxxxxxxxxxxxxx"; +char const CreatureModelDatafmt[] = "nixxxxxxxxxxxxffxxxxxxxxxxxxxxx"; char const CreatureFamilyfmt[] = "nfifiiiiixsx"; char const CreatureSpellDatafmt[] = "niiiixxxx"; char const CreatureTypefmt[] = "nxx"; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3c29288f88a..9b54c1f104b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -25704,7 +25704,7 @@ void Player::HandleFall(MovementInfo const& movementInfo) if (damageperc > 0) { uint32 damage = (uint32)(damageperc * GetMaxHealth()*sWorld->getRate(RATE_DAMAGE_FALL)); - + if (GetCommandStatus(CHEAT_GOD)) damage = 0; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 3e19a5f0420..a00a9596f91 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11311,9 +11311,35 @@ bool Unit::IsInFeralForm() const bool Unit::IsInDisallowedMountForm() const { - ShapeshiftForm form = GetShapeshiftForm(); - return form != FORM_NONE && form != FORM_BATTLESTANCE && form != FORM_BERSERKERSTANCE && form != FORM_DEFENSIVESTANCE && - form != FORM_SHADOW && form != FORM_STEALTH && form != FORM_UNDEAD; + if (ShapeshiftForm form = GetShapeshiftForm()) + { + SpellShapeshiftFormEntry const* shapeshift = sSpellShapeshiftFormStore.LookupEntry(form); + if (!shapeshift) + return true; + + if (!(shapeshift->flags1 & 0x1)) + return true; + } + + if (GetDisplayId() == GetNativeDisplayId()) + return false; + + CreatureDisplayInfoEntry const* display = sCreatureDisplayInfoStore.LookupEntry(GetDisplayId()); + if (!display) + return true; + + CreatureDisplayInfoExtraEntry const* displayExtra = sCreatureDisplayInfoExtraStore.LookupEntry(display->ExtraId); + if (!displayExtra) + return true; + + CreatureModelDataEntry const* model = sCreatureModelDataStore.LookupEntry(display->ModelId); + ChrRacesEntry const* race = sChrRacesStore.LookupEntry(displayExtra->Race); + + if (model && !(model->Flags & 0x80)) + if (race && !(race->Flags & 0x4)) + return true; + + return false; } /*####################################### diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 47b9e840504..b49fc6a7b26 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -5219,6 +5219,8 @@ void ObjectMgr::LoadGossipText() gText.Options[i].Text_0 = fields[cic++].GetString(); gText.Options[i].Text_1 = fields[cic++].GetString(); + gText.Options[i].BroadcastTextID = fields[cic++].GetUInt32(); // Need for correct loading order + gText.Options[i].Language = fields[cic++].GetUInt8(); gText.Options[i].Probability = fields[cic++].GetFloat(); diff --git a/src/server/game/Handlers/NPCHandler.h b/src/server/game/Handlers/NPCHandler.h index 8aa34eaafa7..7210d9a53b5 100644 --- a/src/server/game/Handlers/NPCHandler.h +++ b/src/server/game/Handlers/NPCHandler.h @@ -31,6 +31,7 @@ struct GossipTextOption { std::string Text_0; std::string Text_1; + uint32 BroadcastTextID; uint32 Language; float Probability; QEmote Emotes[MAX_GOSSIP_TEXT_EMOTES]; diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 6c79d66b9ca..c9e2a5acd7a 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -387,7 +387,7 @@ class ItemScript : public ScriptObject // Called when the item expires (is destroyed). virtual bool OnExpire(Player* /*player*/, ItemTemplate const* /*proto*/) { return false; } - + // Called when the item is destroyed. virtual bool OnRemove(Player* /*player*/, Item* /*item*/) { return false; } }; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index a1339f73119..b958adb0d6d 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6036,7 +6036,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const } uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; - uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS; + uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; uint32 procEx = (crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT) | PROC_EX_INTERNAL_HOT; // ignore item heals if (!haveCastItem) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index cbc245ba967..e4f8516839f 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -787,42 +787,61 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr bool hasFamilyMask = false; - /* Check Periodic Auras + /** - *Dots can trigger if spell has no PROC_FLAG_SUCCESSFUL_NEGATIVE_MAGIC_SPELL - nor PROC_FLAG_TAKEN_POSITIVE_MAGIC_SPELL + * @brief Check auras procced by periodics - *Only Hots can trigger if spell has PROC_FLAG_TAKEN_POSITIVE_MAGIC_SPELL + *Only damaging Dots can proc auras with PROC_FLAG_TAKEN_DAMAGE - *Only dots can trigger if spell has both positivity flags or PROC_FLAG_SUCCESSFUL_NEGATIVE_MAGIC_SPELL + *Both Dots and hots can proc if ONLY has PROC_FLAG_DONE_PERIODIC or PROC_FLAG_TAKEN_PERIODIC. Such auras need support in Unit::HandleAuraProc. + + *Only Dots can proc auras with PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG or PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG + + *Only Hots can proc auras with PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS or PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS + + *Only Dots can proc auras with PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG or PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG + + *Only Hots can proc auras with PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS or PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS + + * @param procSpell the spell proccing the aura + * @param procFlags proc_flags of spellProc + * @param procExtra proc_EX of procSpell + * @param EventProcFlag proc_flags of aura to be procced - *Aura has to have PROC_FLAG_TAKEN_POSITIVE_MAGIC_SPELL or spellfamily specified to trigger from Hot */ - if (procFlags & PROC_FLAG_DONE_PERIODIC) + /// Quick Check - If PROC_FLAG_TAKEN_DAMAGE is set for aura and procSpell dealt damage, proc no matter what kind of spell that deals the damage. + if (procFlags & PROC_FLAG_TAKEN_DAMAGE && EventProcFlag & PROC_FLAG_TAKEN_DAMAGE) + return true; + + /// Any aura that has only PROC_FLAG_DONE_PERIODIC or PROC_FLAG_TAKEN_PERIODIC should always proc, if procSpell is correct or not is checked in Unit::HandleAuraProc + if (EventProcFlag == PROC_FLAG_DONE_PERIODIC || EventProcFlag == PROC_FLAG_TAKEN_PERIODIC) + return true; + + if (procFlags & PROC_FLAG_DONE_PERIODIC && EventProcFlag & PROC_FLAG_DONE_PERIODIC) { - if (EventProcFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) + /// Aura must have positive procflags for a HOT to proc + if (procExtra & PROC_EX_INTERNAL_HOT) { - if (!(procExtra & PROC_EX_INTERNAL_DOT)) + if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS))) return false; } - else if (procExtra & PROC_EX_INTERNAL_HOT) - procExtra |= PROC_EX_INTERNAL_REQ_FAMILY; - else if (EventProcFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) + /// Aura must have negative procflags for a DOT to proc + else if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG))) return false; } - if (procFlags & PROC_FLAG_TAKEN_PERIODIC) + if (procFlags & PROC_FLAG_TAKEN_PERIODIC && EventProcFlag & PROC_FLAG_TAKEN_PERIODIC) { - if (EventProcFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS) + /// Aura must have positive procflags for a HOT to proc + if (procExtra & PROC_EX_INTERNAL_HOT) { - if (!(procExtra & PROC_EX_INTERNAL_DOT)) + if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS))) return false; } - else if (procExtra & PROC_EX_INTERNAL_HOT) - procExtra |= PROC_EX_INTERNAL_REQ_FAMILY; - else if (EventProcFlag & PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS) + /// Aura must have negative procflags for a DOT to proc + else if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG))) return false; } // Trap casts are active by default @@ -2989,15 +3008,9 @@ void SpellMgr::LoadSpellInfoCorrections() switch (spellInfo->Id) { - case 42730: // Woe Strike - spellInfo->Effects[EFFECT_1].TriggerSpell = 42739; - break; case 42436: // Drink! (Brewfest) spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY); break; - case 59735: // Woe Strike - spellInfo->Effects[EFFECT_1].TriggerSpell = 59736; - break; case 52611: // Summon Skeletons case 52612: // Summon Skeletons spellInfo->Effects[EFFECT_0].MiscValueB = 64; diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 1359b9f2002..b1a3d982409 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -691,7 +691,7 @@ class SpellMgr // SpellInfo object management SpellInfo const* GetSpellInfo(uint32 spellId) const { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; } // Use this only with 100% valid spellIds - SpellInfo const* EnsureSpellInfo(uint32 spellId) const + SpellInfo const* EnsureSpellInfo(uint32 spellId) const { ASSERT(spellId < GetSpellInfoStoreSize()); SpellInfo const* spellInfo = mSpellInfoMap[spellId]; diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 2aa78964ffd..e556854c2ab 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -166,7 +166,11 @@ public: // fill the gameobject data and save to the db object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMgr().GetPhaseMaskForSpawn()); + // delete the old object and do a clean load from DB with a fresh new GameObject instance. + // this is required to avoid weird behavior and memory leaks + delete object; + object = new GameObject(); // this will generate a new guid if the object is in an instance if (!object->LoadGameObjectFromDB(guidLow, map)) { @@ -209,6 +213,13 @@ public: uint32 objectId = atoi(id); + if (!sObjectMgr->GetGameObjectTemplate(objectId)) + { + handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, objectId); + handler->SetSentErrorMessage(true); + return false; + } + player->SummonGameObject(objectId, x, y, z, ang, 0, 0, rot2, rot3, spawntm); return true; diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 37e7177cbc6..e1821c69095 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -127,8 +127,8 @@ public: int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS; int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS; - handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx); - handler->PSendSysMessage("gridloc [%i, %i]", gx, gy); + handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gx, gy); + handler->PSendSysMessage("gridloc [%i, %i]", gy, gx); // calculate navmesh tile location dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 98b1f688867..b099a8e21de 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -476,7 +476,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -524,7 +524,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -569,7 +569,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -614,7 +614,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -659,7 +659,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp index 31c565e5be2..3541ad0f1a3 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -286,8 +286,8 @@ class npc_prince_taldaram_flame_sphere : public CreatureScript struct npc_prince_taldaram_flame_sphereAI : public ScriptedAI { - npc_prince_taldaram_flame_sphereAI(Creature* creature) : ScriptedAI(creature) - { + npc_prince_taldaram_flame_sphereAI(Creature* creature) : ScriptedAI(creature) + { _flameSphereTargetGUID = 0; } diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp index 1281d40fe5c..916f60bd78a 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp @@ -438,7 +438,7 @@ class npc_watcher_gashra : public CreatureScript _events.ScheduleEvent(EVENT_WEB_WRAP_GASHRA, 11000); _events.ScheduleEvent(EVENT_INFECTED_BITE_GASHRA, 4000); } - + void JustDied(Unit* /*killer*/) OVERRIDE { Creature* krikthir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); @@ -511,7 +511,7 @@ class npc_watcher_narjil : public CreatureScript _events.ScheduleEvent(EVENT_INFECTED_BITE_NARJIL, 4000); _events.ScheduleEvent(EVENT_BINDING_WEBS, 17000); } - + void JustDied(Unit* /*killer*/) OVERRIDE { Creature* krikthir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER)); @@ -600,7 +600,7 @@ class npc_watcher_silthik : public CreatureScript { if (!UpdateVictim()) return; - + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 2091b82e20c..762277ec4fa 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -70,15 +70,13 @@ enum Events EVENT_TRIGGER, EVENT_PHASE, - EVENT_MORTAL_WOUND, + EVENT_MORTAL_WOUND }; enum Spells { SPELL_FROST_BOLT = 28478, - H_SPELL_FROST_BOLT = 55802, SPELL_FROST_BOLT_AOE = 28479, - H_SPELL_FROST_BOLT_AOE = 55807, SPELL_SHADOW_FISURE = 27810, SPELL_VOID_BLAST = 27812, SPELL_MANA_DETONATION = 27819, @@ -122,7 +120,7 @@ enum Spells // Abomination spells SPELL_FRENZY = 28468, - SPELL_MORTAL_WOUND = 28467, + SPELL_MORTAL_WOUND = 28467 }; enum Creatures @@ -133,7 +131,7 @@ enum Creatures NPC_ICECROWN = 16441 // Guardians of Icecrown }; -const Position Pos[12] = +Position const Pos[12] = { {3783.272705f, -5062.697266f, 143.711203f, 3.617599f}, //LEFT_FAR {3730.291260f, -5027.239258f, 143.956909f, 4.461900f}, //LEFT_MIDDLE @@ -146,13 +144,13 @@ const Position Pos[12] = {3732.02f, -5028.53f, 143.92f, 4.49f}, //WINDOW_PORTAL02 {3687.571777f, -5126.831055f, 142.017807f, 0.604023f}, //RIGHT_FAR {3707.990733f, -5151.450195f, 142.032562f, 1.376855f}, //RIGHT_MIDDLE - {3782.76f, -5062.97f, 143.79f, 3.82f}, //WINDOW_PORTAL03 + {3782.76f, -5062.97f, 143.79f, 3.82f} //WINDOW_PORTAL03 }; //creatures in corners //Unstoppable Abominations #define MAX_ABOMINATIONS 21 -const Position PosAbominations[MAX_ABOMINATIONS] = +Position const PosAbominations[MAX_ABOMINATIONS] = { {3755.52f, -5155.22f, 143.480f, 2.0f}, {3744.35f, -5164.03f, 143.590f, 2.00f}, @@ -174,12 +172,12 @@ const Position PosAbominations[MAX_ABOMINATIONS] = {3669.74f, -5149.63f, 143.678f, 0.528643f}, {3695.53f, -5169.53f, 143.671f, 2.11908f}, {3701.98f, -5166.51f, 143.395f, 1.24257f}, - {3709.62f, -5169.15f, 143.576f, 5.97695f}, + {3709.62f, -5169.15f, 143.576f, 5.97695f} }; //Soldiers of the Frozen Wastes #define MAX_WASTES 49 -const Position PosWastes[MAX_WASTES] = +Position const PosWastes[MAX_WASTES] = { {3754.41f, -5147.24f, 143.204f, 2.0f}, {3754.68f, -5156.17f, 143.418f, 2.0f}, @@ -229,12 +227,12 @@ const Position PosWastes[MAX_WASTES] = {3708.53f, -5172.19f, 143.573f, 3.26575f}, {3712.49f, -5167.62f, 143.657f, 5.63295f}, {3704.89f, -5161.84f, 143.239f, 5.63295f}, - {3695.66f, -5164.63f, 143.674f, 1.54416f}, + {3695.66f, -5164.63f, 143.674f, 1.54416f} }; //Soul Weavers #define MAX_WEAVERS 7 -const Position PosWeavers[MAX_WEAVERS] = +Position const PosWeavers[MAX_WEAVERS] = { {3752.45f, -5168.35f, 143.562f, 1.6094f}, {3772.2f, -5070.04f, 143.329f, 1.93686f}, @@ -242,7 +240,7 @@ const Position PosWeavers[MAX_WEAVERS] = {3689.05f, -5055.7f, 143.172f, 6.09554f}, {3649.45f, -5093.17f, 143.299f, 2.51805f}, {3659.7f, -5144.49f, 143.363f, 4.08806f}, - {3704.71f, -5175.96f, 143.597f, 3.36549f}, + {3704.71f, -5175.96f, 143.597f, 3.36549f} }; // predicate function to select not charmed target @@ -278,9 +276,6 @@ public: std::map<uint64, float> chained; - uint64 PortalsGUID[4]; - uint64 KTTriggerGUID; - SummonList spawns; // adds spawn by the trigger. kept in separated list (i.e. not in summons) void ResetPlayerScale() @@ -299,36 +294,29 @@ public: { _Reset(); - PortalsGUID[0] = PortalsGUID[1] = PortalsGUID[2] = PortalsGUID[3] = 0; - KTTriggerGUID = 0; - me->setFaction(35); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE); ResetPlayerScale(); spawns.DespawnAll(); - FindGameObjects(); - instance->SetData(DATA_ABOMINATION_KILLED, 0); - if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID)) + if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) { - pKTTrigger->ResetDoorOrButton(); - pKTTrigger->SetPhaseMask(1, true); + trigger->ResetDoorOrButton(); + trigger->SetPhaseMask(1, true); } for (uint8 i = 0; i <= 3; ++i) { - if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i])) - { - if (!((pPortal->getLootState() == GO_READY) || (pPortal->getLootState() == GO_NOT_READY))) - pPortal->ResetDoorOrButton(); - } + if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_PORTAL01 + i))) + if (!((portal->getLootState() == GO_READY) || (portal->getLootState() == GO_NOT_READY))) + portal->ResetDoorOrButton(); } nGuardiansOfIcecrownCount = 0; - uiGuardiansOfIcecrownTimer = 5000; //5 seconds for summoning each Guardian of Icecrown in phase 3 + uiGuardiansOfIcecrownTimer = 5000; // 5 seconds for summoning each Guardian of Icecrown in phase 3 Phase = 0; nAbomination = 0; @@ -353,11 +341,10 @@ public: me->setFaction(uiFaction); _EnterCombat(); - FindGameObjects(); for (uint8 i = 0; i <= 3; ++i) { - if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i])) - pPortal->ResetDoorOrButton(); + if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_PORTAL01 + i))) + portal->ResetDoorOrButton(); } DoCast(me, SPELL_KELTHUZAD_CHANNEL, false); Talk(SAY_SUMMON_MINIONS); @@ -372,15 +359,6 @@ public: events.ScheduleEvent(EVENT_PHASE, 228000); } - void FindGameObjects() - { - PortalsGUID[0] = instance->GetData64(DATA_KELTHUZAD_PORTAL01); - PortalsGUID[1] = instance->GetData64(DATA_KELTHUZAD_PORTAL02); - PortalsGUID[2] = instance->GetData64(DATA_KELTHUZAD_PORTAL03); - PortalsGUID[3] = instance->GetData64(DATA_KELTHUZAD_PORTAL04); - KTTriggerGUID = instance->GetData64(DATA_KELTHUZAD_TRIGGER); - } - void UpdateAI(uint32 diff) OVERRIDE { if (!UpdateVictim()) @@ -419,8 +397,8 @@ public: events.PopEvent(); break; case EVENT_TRIGGER: - if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID)) - pKTTrigger->SetPhaseMask(2, true); + if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) + trigger->SetPhaseMask(2, true); events.PopEvent(); break; case EVENT_PHASE: @@ -461,11 +439,9 @@ public: for (uint8 i = 0; i <= 3; ++i) { - if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i])) - { - if (pPortal->getLootState() == GO_READY) - pPortal->UseDoorOrButton(); - } + if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_PORTAL01 + i))) + if (portal->getLootState() == GO_READY) + portal->UseDoorOrButton(); } } } @@ -474,8 +450,8 @@ public: if (uiGuardiansOfIcecrownTimer <= diff) { /// @todo Add missing text - if (Creature* pGuardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)])) - pGuardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2); + if (Creature* guardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)])) + guardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2); ++nGuardiansOfIcecrownCount; uiGuardiansOfIcecrownTimer = 5000; } @@ -490,11 +466,11 @@ public: switch (eventId) { case EVENT_BOLT: - DoCastVictim(RAID_MODE(SPELL_FROST_BOLT, H_SPELL_FROST_BOLT)); + DoCastVictim(SPELL_FROST_BOLT); events.RepeatEvent(urand(5000, 10000)); break; case EVENT_NOVA: - DoCastAOE(RAID_MODE(SPELL_FROST_BOLT_AOE, H_SPELL_FROST_BOLT_AOE)); + DoCastAOE(SPELL_FROST_BOLT_AOE); events.RepeatEvent(urand(15000, 30000)); break; case EVENT_CHAIN: @@ -666,7 +642,7 @@ public: if (!instance || instance->IsEncounterInProgress() || instance->GetBossState(BOSS_KELTHUZAD) == DONE) return false; - Creature* pKelthuzad = Unit::GetCreature(*player, instance->GetData64(DATA_KELTHUZAD)); + Creature* pKelthuzad = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_KELTHUZAD)); if (!pKelthuzad) return false; @@ -675,7 +651,7 @@ public: return false; pKelthuzadAI->AttackStart(player); - if (GameObject* trigger = instance->instance->GetGameObject(instance->GetData64(DATA_KELTHUZAD_TRIGGER))) + if (GameObject* trigger = ObjectAccessor::GetGameObject(*player, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) { if (trigger->getLootState() == GO_READY) trigger->UseDoorOrButton(); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp index cc37dde57dd..fe29f4e9f7c 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp @@ -18,28 +18,25 @@ /* ScriptData SDName: Boss_Ingvar_The_Plunderer SD%Complete: 95 -SDComment: Some Problems with Annhylde Movement, Blizzlike Timers (just shadow axe summon needs a new timer) -SDCategory: Udgarde Keep +SDComment: Blizzlike Timers (just shadow axe summon needs a new timer) +SDCategory: Utgarde Keep EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" #include "utgarde_keep.h" enum Yells { - // Ingvar (Human) - SAY_AGGRO_1 = 0, - SAY_SLAY_1 = 1, - SAY_DEATH_1 = 2, - - // Ingvar (Undead) - SAY_AGGRO_2 = 3, - SAY_SLAY_2 = 4, - SAY_DEATH_2 = 5, + // Ingvar (Human/Undead) + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_DEATH = 2, // Annhylde The Caller - YELL_RESURRECT = 0 + YELL_RESURRECT = 0 }; enum Events @@ -83,8 +80,10 @@ enum Spells SPELL_DARK_SMASH = 42723, SPELL_DREADFUL_ROAR = 42729, SPELL_WOE_STRIKE = 42730, + SPELL_WOE_STRIKE_EFFECT = 42739, SPELL_SHADOW_AXE_SUMMON = 42748, + SPELL_SHADOW_AXE_PERIODIC_DAMAGE = 42750, // Spells for Annhylde SPELL_SCOURG_RESURRECTION_HEAL = 42704, // Heal Max + DummyAura @@ -105,16 +104,14 @@ class boss_ingvar_the_plunderer : public CreatureScript struct boss_ingvar_the_plundererAI : public BossAI { - boss_ingvar_the_plundererAI(Creature* creature) : BossAI(creature, DATA_INGVAR) - { - _isUndead = false; - } + boss_ingvar_the_plundererAI(Creature* creature) : BossAI(creature, DATA_INGVAR) { } void Reset() OVERRIDE { - _isUndead = false; + if (me->GetEntry() != NPC_INGVAR) + me->UpdateEntry(NPC_INGVAR); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); _Reset(); events.SetPhase(PHASE_HUMAN); @@ -132,12 +129,12 @@ class boss_ingvar_the_plunderer : public CreatureScript me->RemoveAllAuras(); DoCast(me, SPELL_INGVAR_FEIGN_DEATH, true); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); events.SetPhase(PHASE_EVENT); events.ScheduleEvent(EVENT_SUMMON_BANSHEE, 3 * IN_MILLISECONDS, 0, PHASE_EVENT); - Talk(SAY_DEATH_1); + Talk(SAY_DEATH); } if (events.IsInPhase(PHASE_EVENT)) @@ -152,26 +149,22 @@ class boss_ingvar_the_plunderer : public CreatureScript void StartZombiePhase() { - _isUndead = true; me->RemoveAura(SPELL_INGVAR_FEIGN_DEATH); - DoCast(me, SPELL_INGVAR_TRANSFORM, true); /// @todo: should be death persistent + DoCast(me, SPELL_INGVAR_TRANSFORM, true); + me->UpdateEntry(NPC_INGVAR_UNDEAD); events.ScheduleEvent(EVENT_JUST_TRANSFORMED, 2 * IN_MILLISECONDS, 0, PHASE_EVENT); - - Talk(SAY_AGGRO_2); } void EnterCombat(Unit* /*who*/) OVERRIDE { _EnterCombat(); - - if (!_isUndead) - Talk(SAY_AGGRO_1); + Talk(SAY_AGGRO); } void JustDied(Unit* /*killer*/) OVERRIDE { _JustDied(); - Talk(SAY_DEATH_2); + Talk(SAY_DEATH); } void ScheduleSecondPhase() @@ -183,9 +176,10 @@ class boss_ingvar_the_plunderer : public CreatureScript events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD); } - void KilledUnit(Unit* /*victim*/) OVERRIDE + void KilledUnit(Unit* who) OVERRIDE { - Talk(_isUndead ? SAY_SLAY_1 : SAY_SLAY_2); + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } void UpdateAI(uint32 diff) OVERRIDE @@ -220,7 +214,7 @@ class boss_ingvar_the_plunderer : public CreatureScript events.ScheduleEvent(EVENT_SMASH, urand(12, 16)*IN_MILLISECONDS, 0, PHASE_HUMAN); break; case EVENT_JUST_TRANSFORMED: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); DoZoneInCombat(); ScheduleSecondPhase(); return; @@ -241,20 +235,18 @@ class boss_ingvar_the_plunderer : public CreatureScript events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10, 14)*IN_MILLISECONDS, 0, PHASE_UNDEAD); break; case EVENT_SHADOW_AXE: - if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) DoCast(target, SPELL_SHADOW_AXE_SUMMON); - events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD); break; + default: + break; } } if (!events.IsInPhase(PHASE_EVENT)) DoMeleeAttackIfReady(); } - - private: - bool _isUndead; }; CreatureAI* GetAI(Creature* creature) const OVERRIDE @@ -279,12 +271,8 @@ class npc_annhylde_the_caller : public CreatureScript { _events.Reset(); - //! HACK: Creature's can't have MOVEMENTFLAG_FLYING - me->SetHover(true); - me->GetPosition(x, y, z); - DoTeleportTo(x+1, y, z+30); - me->GetMotionMaster()->MovePoint(1, x, y, z+15); + me->GetMotionMaster()->MovePoint(1, x, y, z - 15.0f); } void MovementInform(uint32 type, uint32 id) OVERRIDE @@ -339,7 +327,7 @@ class npc_annhylde_the_caller : public CreatureScript ingvar->AI()->DoAction(ACTION_START_PHASE_2); } - me->GetMotionMaster()->MovePoint(2, x+1, y, z+30); + me->GetMotionMaster()->MovePoint(2, x, y, z + 15.0f); break; default: break; @@ -359,52 +347,112 @@ class npc_annhylde_the_caller : public CreatureScript } }; -enum ShadowAxe -{ - SPELL_SHADOW_AXE_DAMAGE = 42750, - H_SPELL_SHADOW_AXE_DAMAGE = 59719, - POINT_TARGET = 28 -}; - class npc_ingvar_throw_dummy : public CreatureScript { -public: - npc_ingvar_throw_dummy() : CreatureScript("npc_ingvar_throw_dummy") { } + public: + npc_ingvar_throw_dummy() : CreatureScript("npc_ingvar_throw_dummy") { } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_ingvar_throw_dummyAI(creature); - } + struct npc_ingvar_throw_dummyAI : public ScriptedAI + { + npc_ingvar_throw_dummyAI(Creature* creature) : ScriptedAI(creature) { } + + void Reset() OVERRIDE + { + me->SetReactState(REACT_PASSIVE); + + if (Creature* target = me->FindNearestCreature(NPC_THROW_TARGET, 200.0f)) + { + float x, y, z; + target->GetPosition(x, y, z); + me->GetMotionMaster()->MoveCharge(x, y, z); + target->DespawnOrUnsummon(); + } + else + me->DespawnOrUnsummon(); + } + + void MovementInform(uint32 type, uint32 id) OVERRIDE + { + if (type == EFFECT_MOTION_TYPE && id == EVENT_CHARGE) + { + me->CastSpell(me, SPELL_SHADOW_AXE_PERIODIC_DAMAGE, true); + me->DespawnOrUnsummon(10000); + } + } + }; - struct npc_ingvar_throw_dummyAI : public ScriptedAI - { - npc_ingvar_throw_dummyAI(Creature* creature) : ScriptedAI(creature) + CreatureAI* GetAI(Creature* creature) const OVERRIDE { + return new npc_ingvar_throw_dummyAI(creature); } +}; + +// 42912 - Summon Banshee +class spell_ingvar_summon_banshee : public SpellScriptLoader +{ + public: + spell_ingvar_summon_banshee() : SpellScriptLoader("spell_ingvar_summon_banshee") { } - void Reset() OVERRIDE + class spell_ingvar_summon_banshee_SpellScript : public SpellScript { - if (Creature* target = me->FindNearestCreature(NPC_THROW_TARGET, 50.0f)) + PrepareSpellScript(spell_ingvar_summon_banshee_SpellScript); + + void SetDest(SpellDestination& dest) { - float x, y, z; - target->GetPosition(x, y, z); - me->GetMotionMaster()->MoveCharge(x, y, z, 42.0f, POINT_TARGET); - target->DisappearAndDie(); + dest.RelocateOffset({ 0.0f, 0.0f, 30.0f, 0.0f }); } - else - me->DisappearAndDie(); + + void Register() OVERRIDE + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_ingvar_summon_banshee_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_BACK); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_ingvar_summon_banshee_SpellScript(); } +}; - void MovementInform(uint32 type, uint32 id) OVERRIDE +// 42730, 59735 - Woe Strike +class spell_ingvar_woe_strike : public SpellScriptLoader +{ + public: + spell_ingvar_woe_strike() : SpellScriptLoader("spell_ingvar_woe_strike") { } + + class spell_ingvar_woe_strike_AuraScript : public AuraScript { - if (type == EFFECT_MOTION_TYPE && id == POINT_TARGET) + PrepareAuraScript(spell_ingvar_woe_strike_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_WOE_STRIKE_EFFECT)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetHealInfo()->GetHeal(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetActor(), SPELL_WOE_STRIKE_EFFECT, true, NULL, aurEff); + } + + void Register() OVERRIDE { - DoCast(me, SPELL_SHADOW_AXE_DAMAGE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - me->DespawnOrUnsummon(10000); + DoCheckProc += AuraCheckProcFn(spell_ingvar_woe_strike_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_ingvar_woe_strike_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_ingvar_woe_strike_AuraScript(); } - }; }; void AddSC_boss_ingvar_the_plunderer() @@ -412,4 +460,6 @@ void AddSC_boss_ingvar_the_plunderer() new boss_ingvar_the_plunderer(); new npc_annhylde_the_caller(); new npc_ingvar_throw_dummy(); + new spell_ingvar_summon_banshee(); + new spell_ingvar_woe_strike(); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index abb14a9cc5d..992f6fdbcfb 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -60,6 +60,8 @@ enum PaladinSpells SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790, SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA = 63531, SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 = 31869, + SPELL_PALADIN_SANCTIFIED_WRATH = 57318, + SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1 = 53375, SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS = 25742, SPELL_PALADIN_SWIFT_RETRIBUTION_R1 = 53379 }; @@ -227,6 +229,52 @@ class spell_pal_aura_mastery_immune : public SpellScriptLoader } }; +// 31884 - Avenging Wrath +class spell_pal_avenging_wrath : public SpellScriptLoader +{ + public: + spell_pal_avenging_wrath() : SpellScriptLoader("spell_pal_avenging_wrath") { } + + class spell_pal_avenging_wrath_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_avenging_wrath_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_SANCTIFIED_WRATH) + || !sSpellMgr->GetSpellInfo(SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1)) + return false; + return true; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (AuraEffect const* aurEff = target->GetAuraEffectOfRankedSpell(SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1, EFFECT_2)) + { + int32 basepoints = aurEff->GetAmount(); + target->CastCustomSpell(target, SPELL_PALADIN_SANCTIFIED_WRATH, &basepoints, &basepoints, NULL, true, NULL, aurEff); + } + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_PALADIN_SANCTIFIED_WRATH); + } + + void Register() OVERRIDE + { + OnEffectApply += AuraEffectApplyFn(spell_pal_avenging_wrath_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_pal_avenging_wrath_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_pal_avenging_wrath_AuraScript(); + } +}; + // 53651 - Beacon of Light class spell_pal_beacon_of_light : public SpellScriptLoader { @@ -288,6 +336,7 @@ class spell_pal_beacon_of_light : public SpellScriptLoader } }; + // 37877 - Blessing of Faith class spell_pal_blessing_of_faith : public SpellScriptLoader { @@ -1149,6 +1198,7 @@ void AddSC_paladin_spell_scripts() //new spell_pal_ardent_defender(); new spell_pal_aura_mastery(); new spell_pal_aura_mastery_immune(); + new spell_pal_avenging_wrath(); new spell_pal_beacon_of_light(); new spell_pal_blessing_of_faith(); new spell_pal_divine_sacrifice(); diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index d1b32570795..b9fd07293cd 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -2276,6 +2276,46 @@ class spell_q13400_illidan_kill_master : public SpellScriptLoader } }; +enum RelicOfTheEarthenRing +{ + SPELL_TOTEM_OF_THE_EARTHEN_RING = 66747 +}; + +// 66744 - Make Player Destroy Totems +class spell_q14100_q14111_make_player_destroy_totems : public SpellScriptLoader +{ + public: + spell_q14100_q14111_make_player_destroy_totems() : SpellScriptLoader("spell_q14100_q14111_make_player_destroy_totems") { } + + class spell_q14100_q14111_make_player_destroy_totems_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q14100_q14111_make_player_destroy_totems_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_TOTEM_OF_THE_EARTHEN_RING)) + return false; + return true; + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Player* player = GetHitPlayer()) + player->CastSpell(player, SPELL_TOTEM_OF_THE_EARTHEN_RING, TRIGGERED_FULL_MASK); // ignore reagent cost, consumed by quest + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_q14100_q14111_make_player_destroy_totems_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_q14100_q14111_make_player_destroy_totems_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -2331,4 +2371,5 @@ void AddSC_quest_spell_scripts() new spell_q12919_gymers_grab(); new spell_q12919_gymers_throw(); new spell_q13400_illidan_kill_master(); + new spell_q14100_q14111_make_player_destroy_totems(); } diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index d60924a83f9..cc24035b05e 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -553,7 +553,9 @@ namespace MMAP config.borderSize = config.walkableRadius + 3; config.maxEdgeLen = VERTEX_PER_TILE + 1; // anything bigger than tileSize config.walkableHeight = m_bigBaseUnit ? 3 : 6; - config.walkableClimb = m_bigBaseUnit ? 2 : 4; // keep less than walkableHeight + // a value >= 3|6 allows npcs to walk over some fences + // a value >= 4|8 allows npcs to walk over all fences + config.walkableClimb = m_bigBaseUnit ? 4 : 8; config.minRegionArea = rcSqr(60); config.mergeRegionArea = rcSqr(50); config.maxSimplificationError = 1.8f; // eliminates most jagged edges (tiny polygons) diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index 33f45a86549..86a6db2077c 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -61,7 +61,7 @@ namespace MMAP class MapBuilder { public: - MapBuilder(float maxWalkableAngle = 55.f, + MapBuilder(float maxWalkableAngle = 70.f, bool skipLiquid = false, bool skipContinents = false, bool skipJunkMaps = true, diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 1df24cfa332..d88ab8ca16d 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -242,7 +242,7 @@ int finish(const char* message, int returnValue) int main(int argc, char** argv) { int threads = 3, mapnum = -1; - float maxAngle = 55.0f; + float maxAngle = 70.0f; int tileX = -1, tileY = -1; bool skipLiquid = false, skipContinents = false, |