diff options
Diffstat (limited to 'src')
36 files changed, 590 insertions, 515 deletions
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 2d2266a865d..d77ee5b7f61 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -782,6 +782,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 f9000f636c5..a56b79077d7 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -97,6 +97,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/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp index 66758930f7f..12f4b082a9c 100644 --- a/src/server/game/Chat/ChatLink.cpp +++ b/src/server/game/Chat/ChatLink.cpp @@ -314,7 +314,8 @@ bool SpellChatLink::ValidateName(char* buffer, const char* context) // found the prefix, remove it to perform spellname validation below // -2 = strlen(": ") uint32 spellNameLength = strlen(buffer) - skillLineNameLength - 2; - memcpy(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1); + memmove(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1); + break; } } } diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 37f4f4c1930..9b0465a4536 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -73,6 +73,7 @@ DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt); DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt); DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt); DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt); +DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt); DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt); DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore(CreatureModelDatafmt); DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt); @@ -306,6 +307,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 39747141322..b77db950541 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -92,6 +92,7 @@ extern DBCStorage <ChrClassesEntry> sChrClassesStore; extern DBCStorage <ChrRacesEntry> sChrRacesStore; 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 976b4355957..abe7bde4bf5 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -690,7 +690,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 @@ -736,7 +736,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] @@ -749,6 +749,31 @@ struct CreatureDisplayInfoEntry // 15 m_objectEffectPackageID }; +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 @@ -768,7 +793,7 @@ struct CreatureFamilyEntry struct CreatureModelDataEntry { uint32 Id; - //uint32 Flags; + uint32 Flags; //char* ModelPath[16] //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 448a8066434..35a8eecb708 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -36,11 +36,12 @@ char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxx char const CharTitlesEntryfmt[] = "nxssssssssssssssssxssssssssssssssssxi"; char const ChatChannelsEntryfmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxx"; char const ChrClassesEntryfmt[] = "nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; -char const ChrRacesEntryfmt[] = "nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; +char const ChrRacesEntryfmt[] = "niixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx"; -char const CreatureDisplayInfofmt[] = "nixxfxxxxxxxxxxx"; +char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxx"; +char const CreatureDisplayInfoExtrafmt[] = "diixxxxxxxxxxxxxxxxxx"; char const CreatureFamilyfmt[] = "nfifiiiiixssssssssssssssssxx"; -char const CreatureModelDatafmt[] = "nxxxfxxxxxxxxxxffxxxxxxxxxxx"; +char const CreatureModelDatafmt[] = "nixxfxxxxxxxxxxffxxxxxxxxxxx"; char const CreatureSpellDatafmt[] = "niiiixxxx"; char const CreatureTypefmt[] = "nxxxxxxxxxxxxxxxxxx"; char const CurrencyTypesfmt[] = "xnxi"; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 67f7b1a46b2..cdd9e1441e7 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -52,7 +52,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(), m_spellId = 0; m_cooldownTime = 0; m_goInfo = NULL; - m_ritualOwner = NULL; + m_ritualOwnerGUID = 0; m_goData = NULL; m_DBTableGuid = 0; @@ -1444,9 +1444,16 @@ void GameObject::Use(Unit* user) GameObjectTemplate const* info = GetGOInfo(); + Player* m_ritualOwner = NULL; + if (m_ritualOwnerGUID) + m_ritualOwner = ObjectAccessor::FindPlayer(m_ritualOwnerGUID); + // ritual owner is set for GO's without owner (not summoned) if (!m_ritualOwner && !owner) + { + m_ritualOwnerGUID = player->GetGUID(); m_ritualOwner = player; + } if (owner) { @@ -1517,7 +1524,7 @@ void GameObject::Use(Unit* user) else { // reset ritual for this GO - m_ritualOwner = NULL; + m_ritualOwnerGUID = 0; m_unique_users.clear(); m_usetimes = 0; } diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 48db64a3687..581208f1abd 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -846,7 +846,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map // For traps this: spell casting cooldown, for doors/buttons: reset time. std::list<uint32> m_SkillupList; - Player* m_ritualOwner; // used for GAMEOBJECT_TYPE_SUMMONING_RITUAL where GO is not summoned (no owner) + uint64 m_ritualOwnerGUID; // used for GAMEOBJECT_TYPE_SUMMONING_RITUAL where GO is not summoned (no owner) std::set<uint64> m_unique_users; uint32 m_usetimes; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 69f7073ce1b..c0a54060298 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2489,125 +2489,36 @@ void WorldObject::GetNearPoint(WorldObject const* /*searcher*/, float &x, float { GetNearPoint2D(x, y, distance2d+searcher_size, absAngle); z = GetPositionZ(); + // Should "searcher" be used instead of "this" when updating z coordinate ? UpdateAllowedPositionZ(x, y, z); - /* // if detection disabled, return first point - if (!sWorld->getIntConfig(CONFIG_DETECT_POS_COLLISION)) - { - UpdateGroundPositionZ(x, y, z); // update to LOS height if available + if (!sWorld->getBoolConfig(CONFIG_DETECT_POS_COLLISION)) 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 - { - CellCoord p(Trinity::ComputeCellCoord(GetPositionX(), GetPositionY())); - Cell cell(p); - cell.SetNoCreate(); - - Trinity::NearUsedPosDo u_do(*this, searcher, absAngle, selector); - Trinity::WorldObjectWorker<Trinity::NearUsedPosDo> worker(this, u_do); - - TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::NearUsedPosDo>, GridTypeMapContainer > grid_obj_worker(worker); - TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::NearUsedPosDo>, WorldTypeMapContainer > world_obj_worker(worker); - - CellLock<GridReadGuard> cell_lock(cell, p); - cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap(), *this, distance2d); - cell_lock->Visit(cell_lock, world_obj_worker, *GetMap(), *this, distance2d); - } - - // 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 if the point is already in LoS + if (IsWithinLOS(x, y, z)) 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(); + // remember first point + float first_x = x; + float first_y = y; + float first_z = z; - // select in positions after current nodes (selection one by one) - while (selector.NextUsedAngle(angle)) // angle for used pos but maybe without LOS problem + // loop in a circle to look for a point in LoS using small steps + for (float angle = M_PI / 8; angle < M_PI * 2; angle += M_PI / 8) { - GetNearPoint2D(x, y, distance2d, absAngle+angle); + GetNearPoint2D(x, y, distance2d + searcher_size, absAngle + angle); z = GetPositionZ(); - UpdateGroundPositionZ(x, y, z); // update to LOS height if available - + UpdateAllowedPositionZ(x, y, z); if (IsWithinLOS(x, y, z)) return; } - // BAD BAD NEWS: all found pos (free and used) have LOS problem :( + // still not in LoS, give up and return first position found x = first_x; y = first_y; - - UpdateGroundPositionZ(x, y, z); // update to LOS height if available - */ + z = first_z; } void WorldObject::GetClosePoint(float &x, float &y, float &z, float size, float distance2d /*= 0*/, float angle /*= 0*/) const diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e8bb7981c79..2691a6870f2 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -25058,6 +25058,9 @@ 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; float height = movementInfo.pos.m_positionZ; UpdateGroundPositionZ(movementInfo.pos.m_positionX, movementInfo.pos.m_positionY, height); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 98072e11632..9cc214b7390 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2515,7 +2515,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras modHitChance += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE, schoolMask); // Reduce spell hit chance for Area of effect spells from victim SPELL_AURA_MOD_AOE_AVOIDANCE aura - if (spellInfo->IsTargetingArea()) + if (spellInfo->IsAffectingArea()) modHitChance -= victim->GetTotalAuraModifier(SPELL_AURA_MOD_AOE_AVOIDANCE); // Decrease hit chance from victim rating bonus @@ -10443,7 +10443,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas default: return false; } - break; + // Do not add a break here, case fallthrough is intentional! Adding a break will make above spells unable to crit. case SPELL_DAMAGE_CLASS_MAGIC: { if (schoolMask & SPELL_SCHOOL_MASK_NORMAL) @@ -13051,9 +13051,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()) + { + SpellShapeshiftEntry const* shapeshift = sSpellShapeshiftStore.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/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index fbc78564ea5..e0b29523a3a 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -107,20 +107,12 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) case CHAT_MSG_GUILD: case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_WHISPER: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) - { - std::string msg = ""; - recvData >> msg; - - if (msg.empty()) - return; - - sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg); - } - - // Disabled addon channel? + // check if addon messages are disabled if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) + { + recvData.rfinish(); return; + } break; default: TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination", diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 28e58c87323..c59762066ae 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -159,10 +159,15 @@ bool TargetedMovementGeneratorMedium<T, D>::DoUpdate(T* owner, uint32 time_diff) if (TransportBase* transport = owner->GetDirectTransport()) transport->CalculatePassengerPosition(dest.x, dest.y, dest.z); + // First check distance if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->CanFly()) targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist); else targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist); + + // then, if the target is in range, check also Line of Sight. + if (!targetMoved) + targetMoved = !i_target->IsWithinLOSInMap(owner); } if (i_recalculateTravel || targetMoved) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 4a0c14b4783..bd24038d88d 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6095,7 +6095,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const caster->DealDamage(caster, funnelDamage, &cleanDamage, NODAMAGE, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true); } - uint32 procAttacker = PROC_FLAG_DONE_PERIODIC | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS; + uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS; uint32 procEx = (crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT) | PROC_EX_INTERNAL_HOT; // ignore item heals diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 609c9ba05be..28bc659050a 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3595,9 +3595,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) } return; } - case 45204: // Clone Me! - m_caster->CastSpell(unitTarget, damage, true); - break; case 55693: // Remove Collapsing Cave Aura if (!unitTarget) return; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 0ae4b22b3e4..e8f20441605 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2913,15 +2913,9 @@ void SpellMgr::LoadSpellInfoCorrections() case 53096: // Quetz'lun's Judgment spellInfo->MaxAffectedTargets = 1; break; - case 42730: - spellInfo->Effects[EFFECT_1].TriggerSpell = 42739; - break; case 42436: // Drink! (Brewfest) spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY); break; - case 59735: - 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/World/World.cpp b/src/server/game/World/World.cpp index 729dfac6497..8f2941865fa 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1177,17 +1177,6 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_NUMTHREADS] = sConfigMgr->GetIntDefault("MapUpdate.Threads", 1); m_int_configs[CONFIG_MAX_RESULTS_LOOKUP_COMMANDS] = sConfigMgr->GetIntDefault("Command.LookupMaxResults", 0); - // chat logging - m_bool_configs[CONFIG_CHATLOG_CHANNEL] = sConfigMgr->GetBoolDefault("ChatLogs.Channel", false); - m_bool_configs[CONFIG_CHATLOG_WHISPER] = sConfigMgr->GetBoolDefault("ChatLogs.Whisper", false); - m_bool_configs[CONFIG_CHATLOG_SYSCHAN] = sConfigMgr->GetBoolDefault("ChatLogs.SysChan", false); - m_bool_configs[CONFIG_CHATLOG_PARTY] = sConfigMgr->GetBoolDefault("ChatLogs.Party", false); - m_bool_configs[CONFIG_CHATLOG_RAID] = sConfigMgr->GetBoolDefault("ChatLogs.Raid", false); - m_bool_configs[CONFIG_CHATLOG_GUILD] = sConfigMgr->GetBoolDefault("ChatLogs.Guild", false); - m_bool_configs[CONFIG_CHATLOG_PUBLIC] = sConfigMgr->GetBoolDefault("ChatLogs.Public", false); - m_bool_configs[CONFIG_CHATLOG_ADDON] = sConfigMgr->GetBoolDefault("ChatLogs.Addon", false); - m_bool_configs[CONFIG_CHATLOG_BGROUND] = sConfigMgr->GetBoolDefault("ChatLogs.Battleground", false); - // Warden m_bool_configs[CONFIG_WARDEN_ENABLED] = sConfigMgr->GetBoolDefault("Warden.Enabled", false); m_int_configs[CONFIG_WARDEN_NUM_MEM_CHECKS] = sConfigMgr->GetIntDefault("Warden.NumMemChecks", 3); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 4c43507d038..a58dcc82acc 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -139,15 +139,6 @@ enum WorldBoolConfigs CONFIG_SHOW_KICK_IN_WORLD, CONFIG_SHOW_MUTE_IN_WORLD, CONFIG_SHOW_BAN_IN_WORLD, - CONFIG_CHATLOG_CHANNEL, - CONFIG_CHATLOG_WHISPER, - CONFIG_CHATLOG_SYSCHAN, - CONFIG_CHATLOG_PARTY, - CONFIG_CHATLOG_RAID, - CONFIG_CHATLOG_GUILD, - CONFIG_CHATLOG_PUBLIC, - CONFIG_CHATLOG_ADDON, - CONFIG_CHATLOG_BGROUND, CONFIG_AUTOBROADCAST, CONFIG_ALLOW_TICKETS, CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES, diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 423a47eb3c8..ce0bee0d8c5 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->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 61598bf0945..47cb5636672 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 c2d6bf47154..4cd7228a24a 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/EasternKingdoms/zone_tirisfal_glades.cpp b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp index 925d0d73a70..e11e387ab0a 100644 --- a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp +++ b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp @@ -177,12 +177,13 @@ public: if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE) return false; - if (GameObject* pTrigger = player->FindNearestGameObject(GO_TRIGGER, 30.0f)) - { - pTrigger->SetGoState(GO_STATE_READY); - player->SummonCreature(NPC_ULAG, 2390.26f, 336.47f, 40.01f, 2.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000); - return false; - } + if (!player->FindNearestCreature(NPC_ULAG, 50.0f)) + if (GameObject* pTrigger = player->FindNearestGameObject(GO_TRIGGER, 30.0f)) + { + pTrigger->SetGoState(GO_STATE_READY); + player->SummonCreature(NPC_ULAG, 2390.26f, 336.47f, 40.01f, 2.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000); + return false; + } return false; } diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp index d0b0db2e1ab..8ac095971bc 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp @@ -229,14 +229,14 @@ class npc_onyx_flamecaller : public CreatureScript void IsSummonedBy(Unit* /*summoner*/) OVERRIDE { - // Let Zarithrian count as summoner. _instance cant be null since we got GetRubySanctumAI + // Let Zarithrian count as summoner. if (Creature* zarithrian = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_GENERAL_ZARITHRIAN))) zarithrian->AI()->JustSummoned(me); } void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == MAX_PATH_FLAMECALLER_WAYPOINTS || waypointId == MAX_PATH_FLAMECALLER_WAYPOINTS*2) + if (waypointId == MAX_PATH_FLAMECALLER_WAYPOINTS - 1 || waypointId == MAX_PATH_FLAMECALLER_WAYPOINTS * 2 - 1) { DoZoneInCombat(); SetEscortPaused(true); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index c35c9ba2d11..47c876f2a52 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -394,6 +394,13 @@ class boss_halion : public CreatureScript if (events.IsInPhase(PHASE_TWO)) return; + // Rough radius, it is not an exactly perfect circle + if (me->GetDistance2d(HalionControllerSpawnPos.GetPositionX(), HalionControllerSpawnPos.GetPositionY()) > 48.5f) + { + EnterEvadeMode(); + return; + } + generic_halionAI::UpdateAI(diff); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index d0a25d2b216..c98a3db2334 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -116,6 +116,7 @@ class instance_ulduar : public InstanceMapScript SetBossNumber(MAX_ENCOUNTER); LoadDoorData(doorData); LoadMinionData(minionData); + LeviathanGUID = 0; IgnisGUID = 0; RazorscaleGUID = 0; RazorscaleController = 0; @@ -154,6 +155,7 @@ class instance_ulduar : public InstanceMapScript keepersCount = 0; conSpeedAtory = false; Unbroken = true; + IsDriveMeCrazyEligible = true; _algalonSummoned = false; _summonAlgalon = false; 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_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 68c16a1b2d6..65aa22c776d 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -711,7 +711,7 @@ class spell_gen_clone : public SpellScriptLoader void HandleScriptEffect(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell(GetCaster(), GetEffectValue(), true); + GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); } void Register() OVERRIDE @@ -751,10 +751,7 @@ class spell_gen_clone_weapon : public SpellScriptLoader void HandleScriptEffect(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - Unit* caster = GetCaster(); - - if (Unit* target = GetHitUnit()) - caster->CastSpell(target, GetEffectValue(), true); + GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); } void Register() OVERRIDE @@ -778,8 +775,6 @@ class spell_gen_clone_weapon_aura : public SpellScriptLoader { PrepareAuraScript(spell_gen_clone_weapon_auraScript); - uint32 prevItem; - bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE { if (!sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_AURA) || @@ -792,6 +787,12 @@ class spell_gen_clone_weapon_aura : public SpellScriptLoader return true; } + bool Load() OVERRIDE + { + prevItem = 0; + return true; + } + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* caster = GetCaster(); @@ -877,6 +878,8 @@ class spell_gen_clone_weapon_aura : public SpellScriptLoader OnEffectRemove += AuraEffectRemoveFn(spell_gen_clone_weapon_auraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); } + private: + uint32 prevItem; }; AuraScript* GetAuraScript() const OVERRIDE @@ -3282,6 +3285,33 @@ class spell_gen_summon_tournament_mount : public SpellScriptLoader } }; +// 41213, 43416, 69222, 73076 - Throw Shield +class spell_gen_throw_shield : public SpellScriptLoader +{ + public: + spell_gen_throw_shield() : SpellScriptLoader("spell_gen_throw_shield") { } + + class spell_gen_throw_shield_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_throw_shield_SpellScript); + + void HandleScriptEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_gen_throw_shield_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_gen_throw_shield_SpellScript(); + } +}; enum MountedDuelSpells { @@ -3773,6 +3803,7 @@ void AddSC_generic_spell_scripts() new spell_gen_summon_elemental("spell_gen_summon_fire_elemental", SPELL_SUMMON_FIRE_ELEMENTAL); new spell_gen_summon_elemental("spell_gen_summon_earth_elemental", SPELL_SUMMON_EARTH_ELEMENTAL); new spell_gen_summon_tournament_mount(); + new spell_gen_throw_shield(); new spell_gen_tournament_duel(); new spell_gen_tournament_pennant(); new spell_pvp_trinket_wotf_shared_cd(); 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/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index d0ba39e8b09..e48f16d6558 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -28,6 +28,7 @@ enum WarriorSpells { + SPELL_WARRIOR_BLADESTORM_PERIODIC_WHIRLWIND = 50622, SPELL_WARRIOR_BLOODTHIRST = 23885, SPELL_WARRIOR_BLOODTHIRST_DAMAGE = 23881, SPELL_WARRIOR_CHARGE = 34846, @@ -45,7 +46,8 @@ enum WarriorSpells SPELL_WARRIOR_RETALIATION_DAMAGE = 22858, SPELL_WARRIOR_SLAM = 50783, SPELL_WARRIOR_SUNDER_ARMOR = 58567, - SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK = 26654, + SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1 = 12723, + SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2 = 26654, SPELL_WARRIOR_TAUNT = 355, SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_1 = 46859, SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_2 = 46860, @@ -686,7 +688,7 @@ class spell_warr_sweeping_strikes : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE { - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK)) + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2)) return false; return true; } @@ -703,10 +705,23 @@ class spell_warr_sweeping_strikes : public SpellScriptLoader return _procTarget; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK, true, NULL, aurEff); + if (eventInfo.GetDamageInfo()) + { + SpellInfo const* spellInfo = eventInfo.GetDamageInfo()->GetSpellInfo(); + if (spellInfo && (spellInfo->Id == SPELL_WARRIOR_BLADESTORM_PERIODIC_WHIRLWIND || (spellInfo->Id == SPELL_WARRIOR_EXECUTE && !_procTarget->HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT)))) + { + // If triggered by Execute (while target is not under 20% hp) or Bladestorm deals normalized weapon damage + GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2, true, NULL, aurEff); + } + else + { + int32 damage = eventInfo.GetDamageInfo()->GetDamage(); + GetTarget()->CastCustomSpell(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1, SPELLVALUE_BASE_POINT0, damage, _procTarget, true, NULL, aurEff); + } + } } void Register() OVERRIDE diff --git a/src/server/scripts/World/chat_log.cpp b/src/server/scripts/World/chat_log.cpp index ef854246d20..7074de3ed48 100644 --- a/src/server/scripts/World/chat_log.cpp +++ b/src/server/scripts/World/chat_log.cpp @@ -22,144 +22,133 @@ class ChatLogScript : public PlayerScript { -public: - ChatLogScript() : PlayerScript("ChatLogScript") { } + public: + ChatLogScript() : PlayerScript("ChatLogScript") { } - void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg) - { - switch (type) + void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg) OVERRIDE { - case CHAT_MSG_ADDON: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) - TC_LOG_DEBUG("chat.log", "[ADDON] Player %s sends: %s", - player->GetName().c_str(), msg.c_str()); - break; - - case CHAT_MSG_SAY: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_PUBLIC)) - TC_LOG_DEBUG("chat.log", "[SAY] Player %s says (language %u): %s", + switch (type) + { + case CHAT_MSG_SAY: + TC_LOG_DEBUG("chat.log.say", "Player %s says (language %u): %s", player->GetName().c_str(), lang, msg.c_str()); - break; + break; - case CHAT_MSG_EMOTE: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_PUBLIC)) - TC_LOG_DEBUG("chat.log", "[TEXTEMOTE] Player %s emotes: %s", + case CHAT_MSG_EMOTE: + TC_LOG_DEBUG("chat.log.emote", "Player %s emotes: %s", player->GetName().c_str(), msg.c_str()); - break; + break; - case CHAT_MSG_YELL: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_PUBLIC)) - TC_LOG_DEBUG("chat.log", "[YELL] Player %s yells (language %u): %s", + case CHAT_MSG_YELL: + TC_LOG_DEBUG("chat.log.yell", "Player %s yells (language %u): %s", player->GetName().c_str(), lang, msg.c_str()); - break; + break; + } + } + + void OnChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Player* receiver) OVERRIDE + { + if (lang != LANG_ADDON) + TC_LOG_DEBUG("chat.log.whisper", "Player %s tells %s: %s", + player->GetName().c_str(), receiver ? receiver->GetName().c_str() : "<unknown>", msg.c_str()); + else + TC_LOG_DEBUG("chat.log.addon.whisper", "Player %s tells %s: %s", + player->GetName().c_str(), receiver ? receiver->GetName().c_str() : "<unknown>", msg.c_str()); } - } - - void OnChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Player* receiver) - { - if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_WHISPER)) - TC_LOG_DEBUG("chat.log", "[WHISPER] Player %s tells %s: %s", - player->GetName().c_str(), receiver ? receiver->GetName().c_str() : "<unknown>", msg.c_str()); - else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) - TC_LOG_DEBUG("chat.log", "[ADDON] Player %s tells %s: %s", - player->GetName().c_str(), receiver ? receiver->GetName().c_str() : "<unknown>", msg.c_str()); - } - - void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group) - { - //! NOTE: - //! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER" - switch (type) + + void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group) OVERRIDE { - case CHAT_MSG_PARTY: - if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_PARTY)) - TC_LOG_DEBUG("chat.log", "[PARTY] Player %s tells group with leader %s: %s", - player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); - else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) - TC_LOG_DEBUG("chat.log", "[ADDON] Player %s tells group with leader %s: %s", - player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); - break; - - case CHAT_MSG_PARTY_LEADER: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_PARTY)) - TC_LOG_DEBUG("chat.log", "[PARTY] Leader %s tells group: %s", + //! NOTE: + //! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER" + switch (type) + { + case CHAT_MSG_PARTY: + if (lang != LANG_ADDON) + TC_LOG_DEBUG("chat.log.party", "Player %s tells group with leader %s: %s", + player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); + else + TC_LOG_DEBUG("chat.log.addon.party", "Player %s tells group with leader %s: %s", + player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); + break; + + case CHAT_MSG_PARTY_LEADER: + TC_LOG_DEBUG("chat.log.party", "Leader %s tells group: %s", player->GetName().c_str(), msg.c_str()); - break; - - case CHAT_MSG_RAID: - if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_RAID)) - TC_LOG_DEBUG("chat.log", "[RAID] Player %s tells raid with leader %s: %s", - player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); - else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) - TC_LOG_DEBUG("chat.log", "[ADDON] Player %s tells raid with leader %s: %s", - player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); - break; - - case CHAT_MSG_RAID_LEADER: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_RAID)) - TC_LOG_DEBUG("chat.log", "[RAID] Leader player %s tells raid: %s", + break; + + case CHAT_MSG_RAID: + if (lang != LANG_ADDON) + TC_LOG_DEBUG("chat.log.raid", "Player %s tells raid with leader %s: %s", + player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); + else + TC_LOG_DEBUG("chat.log.addon.raid", "Player %s tells raid with leader %s: %s", + player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); + break; + + case CHAT_MSG_RAID_LEADER: + TC_LOG_DEBUG("chat.log.raid", "Leader player %s tells raid: %s", player->GetName().c_str(), msg.c_str()); - break; + break; - case CHAT_MSG_RAID_WARNING: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_RAID)) - TC_LOG_DEBUG("chat.log", "[RAID] Leader player %s warns raid with: %s", + case CHAT_MSG_RAID_WARNING: + TC_LOG_DEBUG("chat.log.raid", "Leader player %s warns raid with: %s", player->GetName().c_str(), msg.c_str()); - break; - - case CHAT_MSG_BATTLEGROUND: - if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_BGROUND)) - TC_LOG_DEBUG("chat.log", "[BATTLEGROUND] Player %s tells battleground with leader %s: %s", - player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); - else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) - TC_LOG_DEBUG("chat.log", "[ADDON] Player %s tells battleground with leader %s: %s", - player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); - break; - - case CHAT_MSG_BATTLEGROUND_LEADER: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_BGROUND)) - TC_LOG_DEBUG("chat.log", "[BATTLEGROUND] Leader player %s tells battleground: %s", + break; + + case CHAT_MSG_BATTLEGROUND: + if (lang != LANG_ADDON) + TC_LOG_DEBUG("chat.log.bg", "Player %s tells battleground with leader %s: %s", + player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); + else + TC_LOG_DEBUG("chat.log.addon.bg", "Player %s tells battleground with leader %s: %s", + player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); + break; + + case CHAT_MSG_BATTLEGROUND_LEADER: + TC_LOG_DEBUG("chat.log.bg", "Leader player %s tells battleground: %s", player->GetName().c_str(), msg.c_str()); - break; + break; + } } - } - void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) - { - switch (type) + void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) OVERRIDE { - case CHAT_MSG_GUILD: - if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_GUILD)) - TC_LOG_DEBUG("chat.log", "[GUILD] Player %s tells guild %s: %s", - player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str()); - else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) - TC_LOG_DEBUG("chat.log", "[ADDON] Player %s sends to guild %s: %s", + switch (type) + { + case CHAT_MSG_GUILD: + if (lang != LANG_ADDON) + TC_LOG_DEBUG("chat.log.guild", "Player %s tells guild %s: %s", + player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str()); + else + TC_LOG_DEBUG("chat.log.addon.guild", "Player %s sends to guild %s: %s", + player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str()); + break; + + case CHAT_MSG_OFFICER: + TC_LOG_DEBUG("chat.log.guild.officer", "Player %s tells guild %s officers: %s", player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str()); - break; + break; + } + } - case CHAT_MSG_OFFICER: - if (sWorld->getBoolConfig(CONFIG_CHATLOG_GUILD)) - TC_LOG_DEBUG("chat.log", "[OFFICER] Player %s tells guild %s officers: %s", - player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str()); - break; + void OnChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Channel* channel) OVERRIDE + { + bool isSystem = channel && + (channel->HasFlag(CHANNEL_FLAG_TRADE) || + channel->HasFlag(CHANNEL_FLAG_GENERAL) || + channel->HasFlag(CHANNEL_FLAG_CITY) || + channel->HasFlag(CHANNEL_FLAG_LFG)); + + if (isSystem) + TC_LOG_DEBUG("chat.log.system", "Player %s tells channel %s: %s", + player->GetName().c_str(), channel->GetName().c_str(), msg.c_str()); + else + { + std::string channelName = channel ? channel->GetName() : "<unknown>"; + TC_LOG_DEBUG("chat.log.channel." + channelName, "Player %s tells channel %s: %s", + player->GetName().c_str(), channelName.c_str(), msg.c_str()); + } } - } - - void OnChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Channel* channel) - { - bool isSystem = channel && - (channel->HasFlag(CHANNEL_FLAG_TRADE) || - channel->HasFlag(CHANNEL_FLAG_GENERAL) || - channel->HasFlag(CHANNEL_FLAG_CITY) || - channel->HasFlag(CHANNEL_FLAG_LFG)); - - if (sWorld->getBoolConfig(CONFIG_CHATLOG_SYSCHAN) && isSystem) - TC_LOG_DEBUG("chat.log", "[SYSCHAN] Player %s tells channel %s: %s", - player->GetName().c_str(), channel->GetName().c_str(), msg.c_str()); - else if (sWorld->getBoolConfig(CONFIG_CHATLOG_CHANNEL)) - TC_LOG_DEBUG("chat.log", "[CHANNEL] Player %s tells channel %s: %s", - player->GetName().c_str(), channel ? channel->GetName().c_str() : "<unknown>", msg.c_str()); - } }; void AddSC_chat_log() diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp index e838c42d32d..3b6bd3d2cc8 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp @@ -29,15 +29,23 @@ inline LPTSTR ErrorMessage(DWORD dw) { LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL); - return (LPTSTR)lpMsgBuf; + DWORD formatResult = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL); + if (formatResult != 0) + return (LPTSTR)lpMsgBuf; + else + { + LPTSTR msgBuf = (LPTSTR)LocalAlloc(LPTR, 30); + sprintf(msgBuf, "Unknown error: %u", dw); + return msgBuf; + } + } //============================== Global Variables ============================= @@ -878,6 +886,17 @@ char* suffix) if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME, &pwszTypeName)) { + // handle special cases + if (wcscmp(pwszTypeName, L"std::basic_string<char,std::char_traits<char>,std::allocator<char> >") == 0) + { + LocalFree(pwszTypeName); + pszCurrBuffer += sprintf(pszCurrBuffer, " %s", "std::string"); + pszCurrBuffer = FormatOutputValue(pszCurrBuffer, btStdString, 0, (PVOID)offset); + pszCurrBuffer += sprintf(pszCurrBuffer, "\r\n"); + bHandled = true; + return pszCurrBuffer; + } + pszCurrBuffer += sprintf(pszCurrBuffer, " %ls", pwszTypeName); LocalFree(pwszTypeName); } @@ -928,6 +947,19 @@ char* suffix) FormatOutputValue(&addressStr[1], btVoid, sizeof(PVOID), (PVOID)offset); pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1, address, bHandled, "", addressStr); + + if (!bHandled) + { + BasicType basicType = GetBasicType(dwTypeIndex, modBase); + pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]); + // Get the size of the child member + ULONG64 length; + SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_LENGTH, &length); + pszCurrBuffer = FormatOutputValue(pszCurrBuffer, basicType, length, (PVOID)address); + pszCurrBuffer += sprintf(pszCurrBuffer, "\r\n"); + bHandled = true; + return pszCurrBuffer; + } } } break; @@ -1027,13 +1059,6 @@ char* suffix) ULONG64 length; SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_LENGTH, &length); - // BasicType basicType = GetBasicType(children.ChildId[i], modBase); - // - // pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]); - // - // Emit the variable name - // pszCurrBuffer += sprintf(pszCurrBuffer, "\'%s\'", Name); - pszCurrBuffer = FormatOutputValue(pszCurrBuffer, basicType, length, (PVOID)dwFinalOffset); @@ -1052,49 +1077,60 @@ PVOID pAddress) { __try { - // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!) - if (length == 1) - pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PBYTE)pAddress); - else if (length == 2) - pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PWORD)pAddress); - else if (length == 4) + switch (basicType) { - if (basicType == btFloat) - { - pszCurrBuffer += sprintf(pszCurrBuffer, " = %f", *(PFLOAT)pAddress); - } - else if (basicType == btChar) - { - if (!IsBadStringPtr(*(PSTR*)pAddress, 32)) + case btChar: + pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%s\"", pAddress); + break; + case btStdString: + pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%s\"", static_cast<std::string*>(pAddress)->c_str()); + break; + default: + // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!) + if (length == 1) + pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PBYTE)pAddress); + else if (length == 2) + pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PWORD)pAddress); + else if (length == 4) { - pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"", - *(PSTR*)pAddress); + if (basicType == btFloat) + { + pszCurrBuffer += sprintf(pszCurrBuffer, " = %f", *(PFLOAT)pAddress); + } + else if (basicType == btChar) + { + if (!IsBadStringPtr(*(PSTR*)pAddress, 32)) + { + pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"", + *(PSTR*)pAddress); + } + else + pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", + *(PDWORD)pAddress); + } + else + pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PDWORD)pAddress); + } + else if (length == 8) + { + if (basicType == btFloat) + { + pszCurrBuffer += sprintf(pszCurrBuffer, " = %lf", + *(double *)pAddress); + } + else + pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", + *(DWORD64*)pAddress); } else - pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", - *(PDWORD)pAddress); - } - else - pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PDWORD)pAddress); - } - else if (length == 8) - { - if (basicType == btFloat) - { - pszCurrBuffer += sprintf(pszCurrBuffer, " = %lf", - *(double *)pAddress); - } - else - pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", - *(DWORD64*)pAddress); - } - else - { -#if _WIN64 - pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", (DWORD64*)pAddress); -#else - pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", (PDWORD)pAddress); -#endif + { + #if _WIN64 + pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", (DWORD64*)pAddress); + #else + pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", (PDWORD)pAddress); + #endif + } + break; } } __except (EXCEPTION_EXECUTE_HANDLER) diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h index 74330370509..f6d6b7f4b9e 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.h +++ b/src/server/shared/Debugging/WheatyExceptionReport.h @@ -31,7 +31,10 @@ enum BasicType // Stolen from CVCON btComplex = 28, btBit = 29, btBSTR = 30, - btHresult = 31 + btHresult = 31, + + // Custom types + btStdString = 101 }; const char* const rgBaseType[] = diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index d7d70e7d4ea..bc002668b3b 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -250,13 +250,13 @@ void Log::ReadLoggersFromConfig() AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE); appenders[appender->getId()] = appender; - Logger& logger = loggers[LOGGER_ROOT]; - logger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR); - logger.addAppender(appender->getId(), appender); + Logger& rootLogger = loggers[LOGGER_ROOT]; + rootLogger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR); + rootLogger.addAppender(appender->getId(), appender); - logger = loggers["server"]; - logger.Create("server", LOG_LEVEL_ERROR); - logger.addAppender(appender->getId(), appender); + Logger& serverLogger = loggers["server"]; + serverLogger.Create("server", LOG_LEVEL_INFO); + serverLogger.addAppender(appender->getId(), appender); } } diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index dcac93e5a60..73c5601b95b 100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -103,16 +103,12 @@ inline Logger const* Log::GetLoggerByType(std::string const& originalType) } while (!logger); - cachedLoggers[type] = logger; + cachedLoggers[originalType] = logger; return logger; } inline bool Log::ShouldLog(std::string const& type, LogLevel level) { - // TODO: Use cache to store "Type.sub1.sub2": "Type" equivalence, should - // Speed up in cases where requesting "Type.sub1.sub2" but only configured - // Logger "Type" - Logger const* logger = GetLoggerByType(type); if (!logger) return false; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 1762859afae..f71ef5d064b 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -410,78 +410,6 @@ PidFile = "" PacketLogFile = "" -# -# ChatLogs.Channel -# Description: Log custom channel chat. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -ChatLogs.Channel = 0 - -# -# ChatLogs.Whisper -# Description: Log whispers between players. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -ChatLogs.Whisper = 0 - -# -# ChatLogs.SysChan -# Description: Log system channel messages. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -ChatLogs.SysChan = 0 - -# -# ChatLogs.Party -# Description: Log party chat. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -ChatLogs.Party = 0 - -# -# ChatLogs.Raid -# Description: Log raid chat. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -ChatLogs.Raid = 0 - -# -# ChatLogs.Guild -# Description: Log guild chat. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -ChatLogs.Guild = 0 - -# -# ChatLogs.Public -# Description: Log public chat (say/yell/emote). -# Default: 0 - (Disabled) -# 1 - (Enabled) - -ChatLogs.Public = 0 - -# -# ChatLogs.Addon -# Description: Log addon messages. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -ChatLogs.Addon = 0 - -# -# ChatLogs.BattleGround -# Description: Log battleground chat. -# Default: 0 - (Disabled) -# 1 - (Enabled) - -ChatLogs.BattleGround = 0 - # Extended Logging system configuration moved to end of file (on purpose) # ################################################################################################### |