diff options
Diffstat (limited to 'src')
39 files changed, 454 insertions, 754 deletions
diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/authserver/Server/BattlenetBitStream.h index c1c95236360..82c2a0a6d5d 100644 --- a/src/server/authserver/Server/BattlenetBitStream.h +++ b/src/server/authserver/Server/BattlenetBitStream.h @@ -59,16 +59,16 @@ namespace Battlenet static uint32 const MaxSize = 0x4000; // length : The maximum number of bytes to read - BitStream(uint32 length) : _numBits(length * 8), _readPos(0), _writePos(0) + BitStream(uint32 length) : _writePos(length * 8), _readPos(0) { _buffer.resize(length, 0); } - BitStream(MessageBuffer&& buffer) : _buffer(buffer.Move()), _numBits(_buffer.size() * 8), _readPos(0), _writePos(0) + BitStream(MessageBuffer&& buffer) : _writePos(buffer.GetReadyDataSize() * 8), _readPos(0), _buffer(buffer.Move()) { } - BitStream() : _numBits(0), _readPos(0), _writePos(0) + BitStream() : _writePos(0), _readPos(0) { _buffer.reserve(0x1000); } @@ -91,8 +91,8 @@ namespace Battlenet std::unique_ptr<uint8[]> ReadBytes(uint32 count) { AlignToNextByte(); - if (_readPos + count * 8 > _numBits) - throw BitStreamPositionException(true, count * 8, _readPos, _numBits); + if (_readPos + count * 8 > _writePos) + throw BitStreamPositionException(true, count * 8, _readPos, _writePos); std::unique_ptr<uint8[]> buf(new uint8[count]); memcpy(buf.get(), &_buffer[_readPos >> 3], count); @@ -125,8 +125,8 @@ namespace Battlenet { static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "T must be an integer type"); - if (_readPos + bitCount >= _numBits) - throw BitStreamPositionException(true, bitCount, _readPos, _numBits); + if (_readPos + bitCount >= _writePos) + throw BitStreamPositionException(true, bitCount, _readPos, _writePos); uint64 ret = 0; while (bitCount != 0) @@ -214,26 +214,23 @@ namespace Battlenet void SetReadPos(uint32 bits) { - if (bits >= _numBits) - throw BitStreamPositionException(true, bits, 0, _numBits); + if (bits >= _writePos) + throw BitStreamPositionException(true, bits, 0, _writePos); _readPos = bits; } - bool IsRead() const { return _readPos >= _numBits; } + bool IsRead() const { return _readPos >= _writePos; } uint8* GetBuffer() { return _buffer.data(); } uint8 const* GetBuffer() const { return _buffer.data(); } - size_t GetSize() const { return _buffer.size(); } - - void FinishReading() { _readPos = _numBits; } + size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; } private: - std::vector<uint8> _buffer; - uint32 _numBits; - uint32 _readPos; uint32 _writePos; + uint32 _readPos; + std::vector<uint8> _buffer; }; template<> diff --git a/src/server/authserver/Server/BattlenetSession.cpp b/src/server/authserver/Server/BattlenetSession.cpp index e345cd35200..9dc43d4bedb 100644 --- a/src/server/authserver/Server/BattlenetSession.cpp +++ b/src/server/authserver/Server/BattlenetSession.cpp @@ -554,12 +554,12 @@ void Battlenet::Session::ReadDataHandler() if (header.Channel != AUTHENTICATION && !_authed) { - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::AsyncRead Received not allowed packet %s", header.ToString().c_str()); + TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Received not allowed packet %s", header.ToString().c_str()); CloseSocket(); return; } - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::AsyncRead %s", header.ToString().c_str()); + TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", header.ToString().c_str()); std::map<PacketHeader, PacketHandler>::const_iterator itr = Handlers.find(header); if (itr != Handlers.end()) { @@ -568,7 +568,7 @@ void Battlenet::Session::ReadDataHandler() } else { - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::AsyncRead Unhandled opcode %s", header.ToString().c_str()); + TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Unhandled opcode %s", header.ToString().c_str()); break; } @@ -576,7 +576,7 @@ void Battlenet::Session::ReadDataHandler() } catch (BitStreamPositionException const& e) { - TC_LOG_ERROR("server.battlenet", "Battlenet::Session::AsyncRead Exception: %s", e.what()); + TC_LOG_ERROR("server.battlenet", "Battlenet::Session::ReadDataHandler Exception: %s", e.what()); CloseSocket(); return; } diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index afbd306c184..3643bccdb6f 100644 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -68,7 +68,7 @@ namespace FactorySelector else ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); } - else if (creature->GetCreatureType() == CREATURE_TYPE_CRITTER && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) + else if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) ai_factory = ai_registry.GetRegistryItem("CritterAI"); } diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 8b83cae3d99..9dba0fe3bf9 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3223,7 +3223,7 @@ void SmartScript::InitTimer(SmartScriptHolder& e) void SmartScript::RecalcTimer(SmartScriptHolder& e, uint32 min, uint32 max) { // min/max was checked at loading! - e.timer = urand(uint32(min), uint32(max)); + e.timer = urand(min, max); e.active = e.timer ? false : true; } diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 2bbdffc1e7b..06e19b6ebd1 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -3356,7 +3356,7 @@ void AchievementGlobalMgr::LoadRewardLocales() AchievementRewardLocale& data = m_achievementRewardLocales[entry]; - for (int i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; ObjectMgr::AddLocaleString(fields[1 + 2 * (i - 1)].GetString(), locale, data.subject); @@ -3365,7 +3365,7 @@ void AchievementGlobalMgr::LoadRewardLocales() } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu achievement reward locale strings in %u ms", (unsigned long)m_achievementRewardLocales.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u achievement reward locale strings in %u ms", uint32(m_achievementRewardLocales.size()), GetMSTimeDiffToNow(oldMSTime)); } AchievementEntry const* AchievementGlobalMgr::GetAchievement(uint32 achievementId) const diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 4a515d311d3..4690e4d174e 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -385,9 +385,9 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/) RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); - SetAttackTime(BASE_ATTACK, cInfo->baseattacktime); - SetAttackTime(OFF_ATTACK, cInfo->baseattacktime); - SetAttackTime(RANGED_ATTACK, cInfo->rangeattacktime); + SetAttackTime(BASE_ATTACK, cInfo->BaseAttackTime); + SetAttackTime(OFF_ATTACK, cInfo->BaseAttackTime); + SetAttackTime(RANGED_ATTACK, cInfo->RangeAttackTime); SelectLevel(); @@ -819,7 +819,7 @@ bool Creature::Create(uint32 guidlow, Map* map, uint32 /*phaseMask*/, uint32 ent void Creature::InitializeReactState() { - if (IsTotem() || IsTrigger() || GetCreatureType() == CREATURE_TYPE_CRITTER || IsSpiritService()) + if (IsTotem() || IsTrigger() || IsCritter() || IsSpiritService()) SetReactState(REACT_PASSIVE); /* else if (IsCivilian()) diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 64f7fca8ffa..0f4dda4c319 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -65,12 +65,12 @@ enum CreatureFlagsExtra CREATURE_FLAG_EXTRA_NO_SKILLGAIN | CREATURE_FLAG_EXTRA_TAUNT_DIMINISH | CREATURE_FLAG_EXTRA_ALL_DIMINISH | \ CREATURE_FLAG_EXTRA_GUARD | CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING) -#define MAX_KILL_CREDIT 2 #define CREATURE_REGEN_INTERVAL 2 * IN_MILLISECONDS +#define MAX_KILL_CREDIT 2 +#define MAX_CREATURE_MODELS 4 #define MAX_CREATURE_QUEST_ITEMS 6 - -#define MAX_EQUIPMENT_ITEMS 3 +#define CREATURE_MAX_SPELLS 8 // from `creature_template` table struct CreatureTemplate @@ -97,13 +97,11 @@ struct CreatureTemplate float speed_run; float scale; uint32 rank; - float mindmg; - float maxdmg; uint32 dmgschool; - uint32 attackpower; - float dmg_multiplier; - uint32 baseattacktime; - uint32 rangeattacktime; + uint32 BaseAttackTime; + uint32 RangeAttackTime; + float BaseVariance; + float RangeVariance; uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures. uint32 unit_flags; // enum UnitFlags mask values uint32 unit_flags2; // enum UnitFlags2 mask values @@ -112,9 +110,6 @@ struct CreatureTemplate uint32 trainer_type; uint32 trainer_class; uint32 trainer_race; - float minrangedmg; - float maxrangedmg; - uint32 rangedattackpower; uint32 type; // enum CreatureType values uint32 type_flags; // enum CreatureTypeFlags mask values uint32 type_flags2; // unknown enum, only set for 4 creatures (with value 1) @@ -135,6 +130,8 @@ struct CreatureTemplate float ModMana; float ModManaExtra; // Added in 4.x, this value is usually 2 for a small group of creatures with double mana float ModArmor; + float ModDamage; + float ModExperience; bool RacialLeader; uint32 questItems[MAX_CREATURE_QUEST_ITEMS]; uint32 movementId; @@ -242,6 +239,8 @@ struct PointOfInterestLocale StringVector IconName; }; +#define MAX_EQUIPMENT_ITEMS 3 + struct EquipmentInfo { uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 6c6d8c75f7d..108eb3ce0b7 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -885,14 +885,16 @@ namespace Trinity class ObjectDistanceOrderPred { public: - ObjectDistanceOrderPred(WorldObject const* pRefObj, bool ascending = true) : m_refObj(pRefObj), m_ascending(ascending) { } - bool operator()(WorldObject const* pLeft, WorldObject const* pRight) const + ObjectDistanceOrderPred(WorldObject const* refObj, bool ascending = true) : _refObj(refObj), _ascending(ascending) { } + + bool operator()(WorldObject const* left, WorldObject const* right) const { - return m_ascending ? m_refObj->GetDistanceOrder(pLeft, pRight) : !m_refObj->GetDistanceOrder(pLeft, pRight); + return _refObj->GetDistanceOrder(left, right) == _ascending; } + private: - WorldObject const* m_refObj; - const bool m_ascending; + WorldObject const* _refObj; + bool _ascending; }; } diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 5c731c6f8f7..46c9e61886a 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -186,8 +186,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c setFaction(owner->getFaction()); SetUInt32Value(UNIT_CREATED_BY_SPELL, summonSpellId); - CreatureTemplate const* cinfo = GetCreatureTemplate(); - if (cinfo->type == CREATURE_TYPE_CRITTER) + if (IsCritter()) { float px, py, pz; owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, GetFollowAngle()); @@ -982,7 +981,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetCreateHealth(30*petlevel); // wolf attack speed is 1.5s - SetAttackTime(BASE_ATTACK, cinfo->baseattacktime); + SetAttackTime(BASE_ATTACK, cinfo->BaseAttackTime); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel))); diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 06179692845..6ef74785d16 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -901,17 +901,21 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged) void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) { + float variance = 1.0f; UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: + variance = GetCreatureTemplate()->BaseVariance; unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: + variance = GetCreatureTemplate()->BaseVariance; unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: + variance = GetCreatureTemplate()->RangeVariance; unitMod = UNIT_MOD_DAMAGE_RANGED; break; } @@ -934,11 +938,11 @@ void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float attackPower = GetTotalAttackPowerValue(attType); float attackSpeedMulti = GetAPMultiplier(attType, normalized); - float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower / 14.0f); + float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower / 14.0f) * variance; float basePct = GetModifierValue(unitMod, BASE_PCT) * attackSpeedMulti; float totalValue = GetModifierValue(unitMod, TOTAL_VALUE); float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; - float dmgMultiplier = GetCreatureTemplate()->dmg_multiplier; // = dmg_multiplier * _GetDamageMod(rank); + float dmgMultiplier = GetCreatureTemplate()->ModDamage; // = ModDamage * _GetDamageMod(rank); minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; maxDamage = ((weaponMaxDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 843cc937baa..9b4e7e5ac45 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11133,6 +11133,10 @@ int32 Unit::ModSpellDuration(SpellInfo const* spellProto, Unit const* target, in if (duration < 0) return duration; + // some auras are not affected by duration modifiers + if (spellProto->AttributesEx7 & SPELL_ATTR7_IGNORE_DURATION_MODS) + return duration; + // cut duration only of negative effects if (!positive) { @@ -13026,7 +13030,7 @@ Unit* Unit::SelectNearbyTarget(Unit* exclude, float dist) const // remove not LoS targets for (std::list<Unit*>::iterator tIter = targets.begin(); tIter != targets.end();) { - if (!IsWithinLOSInMap(*tIter) || (*tIter)->IsTotem() || (*tIter)->IsSpiritService() || (*tIter)->GetCreatureType() == CREATURE_TYPE_CRITTER) + if (!IsWithinLOSInMap(*tIter) || (*tIter)->IsTotem() || (*tIter)->IsSpiritService() || (*tIter)->IsCritter()) targets.erase(tIter++); else ++tIter; @@ -13679,7 +13683,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) if (Unit* owner = GetOwner()) owner->ProcDamageAndSpell(victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_EX_NONE, 0); - if (victim->GetCreatureType() != CREATURE_TYPE_CRITTER) + if (!victim->IsCritter()) ProcDamageAndSpell(victim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0); // Proc auras on death - must be before aura/combat remove diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index d5e732989e0..d80b4697f48 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -266,7 +266,6 @@ enum UnitRename UNIT_CAN_BE_ABANDONED = 0x02 }; -#define CREATURE_MAX_SPELLS 8 #define MAX_SPELL_CHARM 4 #define MAX_SPELL_VEHICLE 6 #define MAX_SPELL_POSSESS 8 @@ -1538,6 +1537,7 @@ class Unit : public WorldObject bool IsArmorer() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_REPAIR); } bool IsServiceProvider() const; bool IsSpiritService() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE); } + bool IsCritter() const { return GetCreatureType() == CREATURE_TYPE_CRITTER; } bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 93c06146c06..f16ab30567f 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -348,7 +348,7 @@ void ObjectMgr::LoadCreatureLocales() CreatureLocale& data = _creatureLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; AddLocaleString(fields[1 + 3 * (i - 1)].GetString(), locale, data.Name); @@ -357,7 +357,7 @@ void ObjectMgr::LoadCreatureLocales() } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu creature locale strings in %u ms", (unsigned long)_creatureLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u creature locale strings in %u ms", uint32(_creatureLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadGossipMenuItemsLocales() @@ -385,7 +385,7 @@ void ObjectMgr::LoadGossipMenuItemsLocales() GossipMenuItemsLocale& data = _gossipMenuItemsLocaleStore[MAKE_PAIR32(menuId, id)]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; AddLocaleString(fields[2 + 2 * (i - 1)].GetString(), locale, data.OptionText); @@ -394,7 +394,7 @@ void ObjectMgr::LoadGossipMenuItemsLocales() } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu gossip_menu_option locale strings in %u ms", (unsigned long)_gossipMenuItemsLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u gossip_menu_option locale strings in %u ms", uint32(_gossipMenuItemsLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadPointOfInterestLocales() @@ -416,34 +416,36 @@ void ObjectMgr::LoadPointOfInterestLocales() PointOfInterestLocale& data = _pointOfInterestLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.IconName); } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu points_of_interest locale strings in %u ms", (unsigned long)_pointOfInterestLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u points_of_interest locale strings in %u ms", uint32(_pointOfInterestLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadCreatureTemplates() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 8 + // 0 1 2 3 4 5 6 7 8 QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, " - // 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + // 9 10 11 12 13 14 15 16 17 18 19 20 21 22 "modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, " - // 23 24 25 26 27 28 29 30 31 32 33 34 - "scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, " - // 35 36 37 38 39 40 41 42 43 - "dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, " - // 44 45 46 47 48 49 50 51 52 53 54 + // 23 24 25 26 27 28 29 30 31 32 + "scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, " + // 33 34 35 36 37 38 + "dynamicflags, family, trainer_type, trainer_class, trainer_race, type, " + // 39 40 41 42 43 44 45 46 47 48 49 "type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, " - // 55 56 57 58 59 60 61 62 63 64 65 66 67 68 + // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " - // 69 70 71 72 73 74 75 76 77 78 79 80 - "InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, " - // 81 82 83 84 85 86 - " questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName " - "FROM creature_template;"); + // 64 65 66 67 68 69 70 71 + "InhabitType, HoverHeight, HealthModifier, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, " + // 72 73 74 75 76 77 78 + "RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, " + // 79 80 81 82 83 + "movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName " + "FROM creature_template"); if (!result) { @@ -456,93 +458,7 @@ void ObjectMgr::LoadCreatureTemplates() do { Field* fields = result->Fetch(); - - uint32 entry = fields[0].GetUInt32(); - - - CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry]; - - creatureTemplate.Entry = entry; - - for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i) - creatureTemplate.DifficultyEntry[i] = fields[1 + i].GetUInt32(); - - for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i) - creatureTemplate.KillCredit[i] = fields[4 + i].GetUInt32(); - - creatureTemplate.Modelid1 = fields[6].GetUInt32(); - creatureTemplate.Modelid2 = fields[7].GetUInt32(); - creatureTemplate.Modelid3 = fields[8].GetUInt32(); - creatureTemplate.Modelid4 = fields[9].GetUInt32(); - creatureTemplate.Name = fields[10].GetString(); - creatureTemplate.FemaleName = fields[11].GetString(); - creatureTemplate.SubName = fields[12].GetString(); - creatureTemplate.IconName = fields[13].GetString(); - creatureTemplate.GossipMenuId = fields[14].GetUInt32(); - creatureTemplate.minlevel = fields[15].GetUInt8(); - creatureTemplate.maxlevel = fields[16].GetUInt8(); - creatureTemplate.expansion = uint32(fields[17].GetInt16()); - creatureTemplate.expansionUnknown = uint32(fields[18].GetUInt16()); - creatureTemplate.faction = uint32(fields[19].GetUInt16()); - creatureTemplate.npcflag = fields[20].GetUInt32(); - creatureTemplate.speed_walk = fields[21].GetFloat(); - creatureTemplate.speed_run = fields[22].GetFloat(); - creatureTemplate.scale = fields[23].GetFloat(); - creatureTemplate.rank = uint32(fields[24].GetUInt8()); - creatureTemplate.mindmg = fields[25].GetFloat(); - creatureTemplate.maxdmg = fields[26].GetFloat(); - creatureTemplate.dmgschool = uint32(fields[27].GetInt8()); - creatureTemplate.attackpower = fields[28].GetUInt32(); - creatureTemplate.dmg_multiplier = fields[29].GetFloat(); - creatureTemplate.baseattacktime = fields[30].GetUInt32(); - creatureTemplate.rangeattacktime = fields[31].GetUInt32(); - creatureTemplate.unit_class = uint32(fields[32].GetUInt8()); - creatureTemplate.unit_flags = fields[33].GetUInt32(); - creatureTemplate.unit_flags2 = fields[34].GetUInt32(); - creatureTemplate.dynamicflags = fields[35].GetUInt32(); - creatureTemplate.family = uint32(fields[36].GetUInt8()); - creatureTemplate.trainer_type = uint32(fields[37].GetUInt8()); - creatureTemplate.trainer_class = uint32(fields[38].GetUInt8()); - creatureTemplate.trainer_race = uint32(fields[39].GetUInt8()); - creatureTemplate.minrangedmg = fields[40].GetFloat(); - creatureTemplate.maxrangedmg = fields[41].GetFloat(); - creatureTemplate.rangedattackpower = uint32(fields[42].GetUInt16()); - creatureTemplate.type = uint32(fields[43].GetUInt8()); - creatureTemplate.type_flags = fields[44].GetUInt32(); - creatureTemplate.type_flags2 = fields[45].GetUInt32(); - creatureTemplate.lootid = fields[46].GetUInt32(); - creatureTemplate.pickpocketLootId = fields[47].GetUInt32(); - creatureTemplate.SkinLootId = fields[48].GetUInt32(); - - for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16(); - - for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - creatureTemplate.spells[i] = fields[55 + i].GetUInt32(); - - creatureTemplate.PetSpellDataId = fields[63].GetUInt32(); - creatureTemplate.VehicleId = fields[64].GetUInt32(); - creatureTemplate.mingold = fields[65].GetUInt32(); - creatureTemplate.maxgold = fields[66].GetUInt32(); - creatureTemplate.AIName = fields[67].GetString(); - creatureTemplate.MovementType = uint32(fields[68].GetUInt8()); - creatureTemplate.InhabitType = uint32(fields[69].GetUInt8()); - creatureTemplate.HoverHeight = fields[70].GetFloat(); - creatureTemplate.ModHealth = fields[71].GetFloat(); - creatureTemplate.ModMana = fields[72].GetFloat(); - creatureTemplate.ModManaExtra = fields[73].GetFloat(); - creatureTemplate.ModArmor = fields[74].GetFloat(); - creatureTemplate.RacialLeader = fields[75].GetBool(); - - for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - creatureTemplate.questItems[i] = fields[76 + i].GetUInt32(); - - creatureTemplate.movementId = fields[82].GetUInt32(); - creatureTemplate.RegenHealth = fields[83].GetBool(); - creatureTemplate.MechanicImmuneMask = fields[84].GetUInt32(); - creatureTemplate.flags_extra = fields[85].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[86].GetCString()); - + LoadCreatureTemplate(fields); ++count; } while (result->NextRow()); @@ -554,6 +470,91 @@ void ObjectMgr::LoadCreatureTemplates() TC_LOG_INFO("server.loading", ">> Loaded %u creature definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadCreatureTemplate(Field* fields) +{ + uint32 entry = fields[0].GetUInt32(); + + CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry]; + + creatureTemplate.Entry = entry; + + for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i) + creatureTemplate.DifficultyEntry[i] = fields[1 + i].GetUInt32(); + + for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i) + creatureTemplate.KillCredit[i] = fields[4 + i].GetUInt32(); + + creatureTemplate.Modelid1 = fields[6].GetUInt32(); + creatureTemplate.Modelid2 = fields[7].GetUInt32(); + creatureTemplate.Modelid3 = fields[8].GetUInt32(); + creatureTemplate.Modelid4 = fields[9].GetUInt32(); + creatureTemplate.Name = fields[10].GetString(); + creatureTemplate.FemaleName = fields[11].GetString(); + creatureTemplate.SubName = fields[12].GetString(); + creatureTemplate.IconName = fields[13].GetString(); + creatureTemplate.GossipMenuId = fields[14].GetUInt32(); + creatureTemplate.minlevel = fields[15].GetUInt8(); + creatureTemplate.maxlevel = fields[16].GetUInt8(); + creatureTemplate.expansion = uint32(fields[17].GetInt16()); + creatureTemplate.expansionUnknown = uint32(fields[18].GetUInt16()); + creatureTemplate.faction = uint32(fields[19].GetUInt16()); + creatureTemplate.npcflag = fields[20].GetUInt32(); + creatureTemplate.speed_walk = fields[21].GetFloat(); + creatureTemplate.speed_run = fields[22].GetFloat(); + creatureTemplate.scale = fields[23].GetFloat(); + creatureTemplate.rank = uint32(fields[24].GetUInt8()); + creatureTemplate.dmgschool = uint32(fields[25].GetInt8()); + creatureTemplate.BaseAttackTime = fields[26].GetUInt32(); + creatureTemplate.RangeAttackTime = fields[27].GetUInt32(); + creatureTemplate.BaseVariance = fields[28].GetFloat(); + creatureTemplate.RangeVariance = fields[29].GetFloat(); + creatureTemplate.unit_class = uint32(fields[30].GetUInt8()); + creatureTemplate.unit_flags = fields[31].GetUInt32(); + creatureTemplate.unit_flags2 = fields[32].GetUInt32(); + creatureTemplate.dynamicflags = fields[33].GetUInt32(); + creatureTemplate.family = uint32(fields[34].GetUInt8()); + creatureTemplate.trainer_type = uint32(fields[35].GetUInt8()); + creatureTemplate.trainer_class = uint32(fields[36].GetUInt8()); + creatureTemplate.trainer_race = uint32(fields[37].GetUInt8()); + creatureTemplate.type = uint32(fields[38].GetUInt8()); + creatureTemplate.type_flags = fields[39].GetUInt32(); + creatureTemplate.type_flags2 = fields[40].GetUInt32(); + creatureTemplate.lootid = fields[41].GetUInt32(); + creatureTemplate.pickpocketLootId = fields[42].GetUInt32(); + creatureTemplate.SkinLootId = fields[43].GetUInt32(); + + for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) + creatureTemplate.resistance[i] = fields[44 + i - 1].GetInt16(); + + for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) + creatureTemplate.spells[i] = fields[50 + i].GetUInt32(); + + creatureTemplate.PetSpellDataId = fields[58].GetUInt32(); + creatureTemplate.VehicleId = fields[59].GetUInt32(); + creatureTemplate.mingold = fields[60].GetUInt32(); + creatureTemplate.maxgold = fields[61].GetUInt32(); + creatureTemplate.AIName = fields[62].GetString(); + creatureTemplate.MovementType = uint32(fields[63].GetUInt8()); + creatureTemplate.InhabitType = uint32(fields[64].GetUInt8()); + creatureTemplate.HoverHeight = fields[65].GetFloat(); + creatureTemplate.ModHealth = fields[66].GetFloat(); + creatureTemplate.ModMana = fields[67].GetFloat(); + creatureTemplate.ModManaExtra = fields[68].GetFloat(); + creatureTemplate.ModArmor = fields[69].GetFloat(); + creatureTemplate.ModDamage = fields[70].GetFloat(); + creatureTemplate.ModExperience = fields[71].GetFloat(); + creatureTemplate.RacialLeader = fields[72].GetBool(); + + for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) + creatureTemplate.questItems[i] = fields[73 + i].GetUInt32(); + + creatureTemplate.movementId = fields[79].GetUInt32(); + creatureTemplate.RegenHealth = fields[80].GetBool(); + creatureTemplate.MechanicImmuneMask = fields[81].GetUInt32(); + creatureTemplate.flags_extra = fields[82].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[83].GetCString()); +} + void ObjectMgr::LoadCreatureTemplateAddons() { uint32 oldMSTime = getMSTime(); @@ -887,11 +888,11 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) const_cast<CreatureTemplate*>(cInfo)->dmgschool = SPELL_SCHOOL_NORMAL; } - if (cInfo->baseattacktime == 0) - const_cast<CreatureTemplate*>(cInfo)->baseattacktime = BASE_ATTACK_TIME; + if (cInfo->BaseAttackTime == 0) + const_cast<CreatureTemplate*>(cInfo)->BaseAttackTime = BASE_ATTACK_TIME; - if (cInfo->rangeattacktime == 0) - const_cast<CreatureTemplate*>(cInfo)->rangeattacktime = BASE_ATTACK_TIME; + if (cInfo->RangeAttackTime == 0) + const_cast<CreatureTemplate*>(cInfo)->RangeAttackTime = BASE_ATTACK_TIME; if ((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE) TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong trainer type %u.", cInfo->Entry, cInfo->trainer_type); @@ -992,7 +993,7 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) const_cast<CreatureTemplate*>(cInfo)->flags_extra &= CREATURE_FLAG_EXTRA_DB_ALLOWED; } - const_cast<CreatureTemplate*>(cInfo)->dmg_multiplier *= Creature::_GetDamageMod(cInfo->rank); + const_cast<CreatureTemplate*>(cInfo)->ModDamage *= Creature::_GetDamageMod(cInfo->rank); } void ObjectMgr::LoadCreatureAddons() @@ -2252,7 +2253,7 @@ void ObjectMgr::LoadItemLocales() ItemLocale& data = _itemLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; AddLocaleString(fields[1 + 2 * (i - 1)].GetString(), locale, data.Name); @@ -2260,7 +2261,7 @@ void ObjectMgr::LoadItemLocales() } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu Item locale strings in %u ms", (unsigned long)_itemLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u Item locale strings in %u ms", uint32(_itemLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void FillItemDamageFields(float* minDamage, float* maxDamage, float* dps, uint32 itemLevel, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32 delay, float statScalingFactor, uint32 inventoryType, uint32 flags2) @@ -4569,7 +4570,7 @@ void ObjectMgr::LoadQuestLocales() QuestLocale& data = _questLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; @@ -4591,7 +4592,7 @@ void ObjectMgr::LoadQuestLocales() } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu Quest locale strings in %u ms", (unsigned long)_questLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u Quest locale strings in %u ms", uint32(_questLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadScripts(ScriptsType type) @@ -5202,11 +5203,11 @@ void ObjectMgr::LoadPageTextLocales() PageTextLocale& data = _pageTextLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.Text); } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu PageText locale strings in %u ms", (unsigned long)_pageTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u PageText locale strings in %u ms", uint32(_pageTextLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadInstanceTemplate() @@ -5465,10 +5466,10 @@ void ObjectMgr::LoadNpcTextLocales() NpcTextLocale& data = _npcTextLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; - for (uint8 j = 0; j < MAX_LOCALES; ++j) + for (uint8 j = 0; j < MAX_GOSSIP_TEXT_OPTIONS; ++j) { AddLocaleString(fields[1 + 8 * 2 * (i - 1) + 2 * j].GetString(), locale, data.Text_0[j]); AddLocaleString(fields[1 + 8 * 2 * (i - 1) + 2 * j + 1].GetString(), locale, data.Text_1[j]); @@ -5476,7 +5477,7 @@ void ObjectMgr::LoadNpcTextLocales() } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu NpcText locale strings in %u ms", (unsigned long)_npcTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u NpcText locale strings in %u ms", uint32(_npcTextLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } //not very fast function but it is called only once a day, or on starting-up @@ -6507,14 +6508,14 @@ void ObjectMgr::LoadGameObjectLocales() GameObjectLocale& data = _gameObjectLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) + { AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.Name); - - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) AddLocaleString(fields[i + (TOTAL_LOCALES - 1)].GetString(), LocaleConstant(i), data.CastBarCaption); + } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu gameobject locale strings in %u ms", (unsigned long)_gameObjectLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u gameobject locale strings in %u ms", uint32(_gameObjectLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } inline void CheckGOLockId(GameObjectTemplate const* goInfo, uint32 dataN, uint32 N) @@ -7850,7 +7851,7 @@ bool ObjectMgr::LoadTrinityStrings(const char* table, int32 min_value, int32 max data.Content.resize(1); ++count; - for (uint8 i = 0; i < TOTAL_LOCALES; ++i) + for (int8 i = TOTAL_LOCALES - 1; i >= 0; --i) AddLocaleString(fields[i + 1].GetString(), LocaleConstant(i), data.Content); } while (result->NextRow()); @@ -8887,11 +8888,11 @@ void ObjectMgr::LoadBroadcastTextLocales() continue; } - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = LocaleConstant(i); - ObjectMgr::AddLocaleString(fields[1 + (i - 1)].GetString(), locale, bct->second.MaleText); - ObjectMgr::AddLocaleString(fields[9 + (i - 1)].GetString(), locale, bct->second.FemaleText); + AddLocaleString(fields[1 + (i - 1)].GetString(), locale, bct->second.MaleText); + AddLocaleString(fields[9 + (i - 1)].GetString(), locale, bct->second.FemaleText); } ++count; diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 45671f016c8..f9f5269e485 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -984,6 +984,7 @@ class ObjectMgr void LoadGraveyardOrientations(); void LoadCreatureTemplates(); void LoadCreatureTemplateAddons(); + void LoadCreatureTemplate(Field* fields); void CheckCreatureTemplate(CreatureTemplate const* cInfo); void LoadTempSummons(); void LoadCreatures(); diff --git a/src/server/game/Handlers/NPCHandler.h b/src/server/game/Handlers/NPCHandler.h index 7210d9a53b5..855536c7d9e 100644 --- a/src/server/game/Handlers/NPCHandler.h +++ b/src/server/game/Handlers/NPCHandler.h @@ -51,10 +51,10 @@ struct PageTextLocale struct NpcTextLocale { - NpcTextLocale() { Text_0.resize(8); Text_1.resize(8); } + NpcTextLocale() { } - std::vector<StringVector> Text_0; - std::vector<StringVector> Text_1; + StringVector Text_0[MAX_GOSSIP_TEXT_OPTIONS]; + StringVector Text_1[MAX_GOSSIP_TEXT_OPTIONS]; }; #endif diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h index 924320ac198..537fa7543f7 100644 --- a/src/server/game/Miscellaneous/Formulas.h +++ b/src/server/game/Miscellaneous/Formulas.h @@ -163,27 +163,32 @@ namespace Trinity inline uint32 Gain(Player* player, Unit* u) { - uint32 gain; + Creature* creature = u->ToCreature(); + uint32 gain = 0; - if (u->GetTypeId() == TYPEID_UNIT && - (((Creature*)u)->IsTotem() || ((Creature*)u)->IsPet() || - (((Creature*)u)->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL) || - ((Creature*)u)->GetCreatureTemplate()->type == CREATURE_TYPE_CRITTER)) - gain = 0; - else + if (!creature || (!creature->IsTotem() && !creature->IsPet() && !creature->IsCritter() && + !(creature->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL))) { + float xpMod = 1.0f; + gain = BaseGain(player->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(u->GetMapId(), u->GetZoneId())); - if (gain != 0 && u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->isElite()) + if (gain && creature) { - // Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus. - if (u->GetMap() && u->GetMap()->IsDungeon()) - gain = uint32(gain * 2.75); - else - gain *= 2; + if (creature->isElite()) + { + // Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus. + if (u->GetMap() && u->GetMap()->IsDungeon()) + xpMod *= 2.75f; + else + xpMod *= 2.0f; + } + + xpMod *= creature->GetCreatureTemplate()->ModExperience; } - gain = uint32(gain * sWorld->getRate(RATE_XP_KILL)); + xpMod *= sWorld->getRate(RATE_XP_KILL); + gain = uint32(gain * xpMod); } sScriptMgr->OnGainCalculation(gain, player, u); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index da48d749cab..6e90412a3b6 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -538,7 +538,7 @@ enum SpellAttr6 enum SpellAttr7 { SPELL_ATTR7_UNK0 = 0x00000001, // 0 Shaman's new spells (Call of the ...), Feign Death. - SPELL_ATTR7_UNK1 = 0x00000002, // 1 Not set in 3.2.2a. + SPELL_ATTR7_IGNORE_DURATION_MODS = 0x00000002, // 1 Duration is not affected by duration modifiers SPELL_ATTR7_REACTIVATE_AT_RESURRECT = 0x00000004, // 2 Paladin's auras and 65607 only. SPELL_ATTR7_IS_CHEAT_SPELL = 0x00000008, // 3 Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS SPELL_ATTR7_UNK4 = 0x00000010, // 4 Only 47883 (Soulstone Resurrection) and test spell. diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 29107a72a9e..9bdf591103d 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -266,7 +266,6 @@ void AddSC_blasted_lands(); void AddSC_burning_steppes(); void AddSC_duskwood(); void AddSC_eastern_plaguelands(); -void AddSC_eversong_woods(); void AddSC_ghostlands(); void AddSC_hinterlands(); void AddSC_isle_of_queldanas(); diff --git a/src/server/game/Server/WorldPacket.h b/src/server/game/Server/WorldPacket.h index bdacefabbeb..b047b20bce2 100644 --- a/src/server/game/Server/WorldPacket.h +++ b/src/server/game/Server/WorldPacket.h @@ -65,7 +65,7 @@ class WorldPacket : public ByteBuffer Opcodes GetOpcode() const { return m_opcode; } void SetOpcode(Opcodes opcode) { m_opcode = opcode; } - bool IsCompressed() const { return m_opcode & COMPRESSED_OPCODE_MASK; } + bool IsCompressed() const { return (m_opcode & COMPRESSED_OPCODE_MASK) != 0; } void Compress(z_stream_s* compressionStream); void Compress(z_stream_s* compressionStream, WorldPacket const* source); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 227be6ec45b..f7269ae977c 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -380,17 +380,22 @@ class WorldSession void SetLatency(uint32 latency) { m_latency = latency; } void ResetClientTimeDelay() { m_clientTimeDelay = 0; } - std::atomic<time_t> m_timeOutTime; + std::atomic<int32> m_timeOutTime; void UpdateTimeOutTime(uint32 diff) { - if (time_t(diff) > m_timeOutTime) - m_timeOutTime = 0; - else - m_timeOutTime -= diff; + m_timeOutTime -= int32(diff); + } + + void ResetTimeOutTime() + { + m_timeOutTime = int32(sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME)); + } + + bool IsConnectionIdle() const + { + return m_timeOutTime <= 0 && !m_inQueue; } - void ResetTimeOutTime() { m_timeOutTime = sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME); } - bool IsConnectionIdle() const { return (m_timeOutTime <= 0 && !m_inQueue); } // Recruit-A-Friend Handling uint32 GetRecruiterId() const { return recruiterId; } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index df754440c40..e75ef03d392 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5151,7 +5151,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_TARGET_UNSKINNABLE; Creature* creature = m_targets.GetUnitTarget()->ToCreature(); - if (creature->GetCreatureType() != CREATURE_TYPE_CRITTER && !creature->loot.isLooted()) + if (!creature->IsCritter() && !creature->loot.isLooted()) return SPELL_FAILED_TARGET_NOT_LOOTED; uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill(); diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 3fbbd34777b..9e05e4874bc 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -180,7 +180,7 @@ void CreatureTextMgr::LoadCreatureTextLocales() { Field* fields = result->Fetch(); CreatureTextLocale& loc = mLocaleTextMap[CreatureTextId(fields[0].GetUInt32(), uint32(fields[1].GetUInt8()), uint32(fields[2].GetUInt8()))]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = LocaleConstant(i); ObjectMgr::AddLocaleString(fields[3 + i - 1].GetString(), locale, loc.Text); diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp index 2f74132fe21..121da6489a3 100644 --- a/src/server/scripts/Commands/cs_ban.cpp +++ b/src/server/scripts/Commands/cs_ban.cpp @@ -109,21 +109,23 @@ public: return false; } - switch (sWorld->BanCharacter(name, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "")) + std::string author = handler->GetSession() ? handler->GetSession()->GetPlayerName() : "Server"; + + switch (sWorld->BanCharacter(name, durationStr, reasonStr, author)) { case BAN_SUCCESS: { if (atoi(durationStr) > 0) { if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) - sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), name.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUBANNEDMESSAGE_WORLD, author.c_str(), name.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); else handler->PSendSysMessage(LANG_BAN_YOUBANNED, name.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); } else { if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) - sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUPERMBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), name.c_str(), reasonStr); + sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUPERMBANNEDMESSAGE_WORLD, author.c_str(), name.c_str(), reasonStr); else handler->PSendSysMessage(LANG_BAN_YOUPERMBANNED, name.c_str(), reasonStr); } @@ -195,20 +197,22 @@ public: break; } - switch (sWorld->BanAccount(mode, nameOrIP, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "")) + std::string author = handler->GetSession() ? handler->GetSession()->GetPlayerName() : "Server"; + + switch (sWorld->BanAccount(mode, nameOrIP, durationStr, reasonStr, author)) { case BAN_SUCCESS: if (atoi(durationStr) > 0) { if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) - sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUBANNEDMESSAGE_WORLD, author.c_str(), nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); else handler->PSendSysMessage(LANG_BAN_YOUBANNED, nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); } else { if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) - sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameOrIP.c_str(), reasonStr); + sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD, author.c_str(), nameOrIP.c_str(), reasonStr); else handler->PSendSysMessage(LANG_BAN_YOUPERMBANNED, nameOrIP.c_str(), reasonStr); } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 9d763cb8d71..2afdff94a0b 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1610,16 +1610,7 @@ public: banReason = fields[3].GetString(); } - // Can be used to query data from World database - stmt2 = WorldDatabase.GetPreparedStatement(WORLD_SEL_REQ_XP); - stmt2->setUInt8(0, level); - PreparedQueryResult result3 = WorldDatabase.Query(stmt2); - if (result3) - { - Field* fields = result3->Fetch(); - xptotal = fields[0].GetUInt32(); - } // Can be used to query data from Characters database stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_XP); @@ -1631,6 +1622,7 @@ public: Field* fields = result4->Fetch(); xp = fields[0].GetUInt32(); // Used for "current xp" output and "%u XP Left" calculation uint32 gguid = fields[1].GetUInt32(); // We check if have a guild for the person, so we might not require to query it at all + xptotal = sObjectMgr->GetXPForLevel(level); if (gguid != 0) { @@ -1767,10 +1759,10 @@ public: Player* player = handler->GetSession()->GetPlayer(); // accept only explicitly selected target (not implicitly self targeting case) - Unit* target = handler->getSelectedUnit(); - if (player->GetTarget() && target) + Creature* target = player->GetTarget() ? handler->getSelectedCreature() : nullptr; + if (target) { - if (target->GetTypeId() != TYPEID_UNIT || target->IsPet()) + if (target->IsPet()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); @@ -1778,19 +1770,13 @@ public: } if (target->isDead()) - target->ToCreature()->Respawn(); + target->Respawn(); return true; } - CellCoord p(Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY())); - Cell cell(p); - cell.SetNoCreate(); - Trinity::RespawnDo u_do; Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(player, u_do); - - TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker); - cell.Visit(p, obj_worker, *player->GetMap(), *player, player->GetGridActivationRange()); + player->VisitNearbyGridObject(player->GetGridActivationRange(), worker); return true; } @@ -1844,14 +1830,9 @@ public: std::string nameLink = handler->playerLink(targetName); if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD)) - { - sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); - } - else - { - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); - } + sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, muteBy.c_str(), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); } else { @@ -1866,10 +1847,11 @@ public: LoginDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); - if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD) && !target) - sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, handler->GetSession()->GetPlayerName().c_str(), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); - else - handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD) && !target) + sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, muteBy.c_str(), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + else + handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + return true; } diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 2988c2c50c9..4b78ab880d4 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -438,7 +438,7 @@ public: continue; } - CreatureTemplate* cInfo = const_cast<CreatureTemplate*>(sObjectMgr->GetCreatureTemplate(entry)); + CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry); if (!cInfo) { handler->PSendSysMessage(LANG_COMMAND_CREATURESTORAGE_NOTFOUND, entry); @@ -448,86 +448,7 @@ public: TC_LOG_INFO("misc", "Reloading creature template entry %u", entry); Field* fields = result->Fetch(); - - for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i) - cInfo->DifficultyEntry[i] = fields[0 + i].GetUInt32(); - - for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i) - cInfo->KillCredit[i] = fields[3 + i].GetUInt32(); - - cInfo->Modelid1 = fields[5].GetUInt32(); - cInfo->Modelid2 = fields[6].GetUInt32(); - cInfo->Modelid3 = fields[7].GetUInt32(); - cInfo->Modelid4 = fields[8].GetUInt32(); - cInfo->Name = fields[9].GetString(); - cInfo->SubName = fields[10].GetString(); - cInfo->FemaleName = fields[11].GetString(); - cInfo->IconName = fields[12].GetString(); - cInfo->GossipMenuId = fields[13].GetUInt32(); - cInfo->minlevel = fields[14].GetUInt8(); - cInfo->maxlevel = fields[15].GetUInt8(); - cInfo->expansion = fields[16].GetUInt16(); - cInfo->expansionUnknown = fields[17].GetUInt16(); - cInfo->faction = fields[18].GetUInt16(); - cInfo->npcflag = fields[19].GetUInt32(); - cInfo->speed_walk = fields[20].GetFloat(); - cInfo->speed_run = fields[21].GetFloat(); - cInfo->scale = fields[22].GetFloat(); - cInfo->rank = fields[23].GetUInt8(); - cInfo->mindmg = fields[24].GetFloat(); - cInfo->maxdmg = fields[25].GetFloat(); - cInfo->dmgschool = fields[26].GetUInt8(); - cInfo->attackpower = fields[27].GetUInt32(); - cInfo->dmg_multiplier = fields[28].GetFloat(); - cInfo->baseattacktime = fields[29].GetUInt32(); - cInfo->rangeattacktime = fields[30].GetUInt32(); - cInfo->unit_class = fields[31].GetUInt8(); - cInfo->unit_flags = fields[32].GetUInt32(); - cInfo->unit_flags2 = fields[33].GetUInt32(); - cInfo->dynamicflags = fields[34].GetUInt32(); - cInfo->family = fields[35].GetUInt8(); - cInfo->trainer_type = fields[36].GetUInt8(); - cInfo->trainer_class = fields[37].GetUInt8(); - cInfo->trainer_race = fields[38].GetUInt8(); - cInfo->minrangedmg = fields[39].GetFloat(); - cInfo->maxrangedmg = fields[40].GetFloat(); - cInfo->rangedattackpower = fields[41].GetUInt16(); - cInfo->type = fields[42].GetUInt8(); - cInfo->type_flags = fields[43].GetUInt32(); - cInfo->type_flags2 = fields[44].GetUInt32(); - cInfo->lootid = fields[45].GetUInt32(); - cInfo->pickpocketLootId = fields[46].GetUInt32(); - cInfo->SkinLootId = fields[47].GetUInt32(); - - for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - cInfo->resistance[i] = fields[48 + i -1].GetUInt16(); - - for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - cInfo->spells[i] = fields[54 + i].GetUInt32(); - - cInfo->PetSpellDataId = fields[62].GetUInt32(); - cInfo->VehicleId = fields[63].GetUInt32(); - cInfo->mingold = fields[64].GetUInt32(); - cInfo->maxgold = fields[65].GetUInt32(); - cInfo->AIName = fields[66].GetString(); - cInfo->MovementType = fields[67].GetUInt8(); - cInfo->InhabitType = fields[68].GetUInt8(); - cInfo->HoverHeight = fields[69].GetFloat(); - cInfo->ModHealth = fields[70].GetFloat(); - cInfo->ModMana = fields[71].GetFloat(); - cInfo->ModManaExtra = fields[72].GetFloat(); - cInfo->ModArmor = fields[73].GetFloat(); - cInfo->RacialLeader = fields[74].GetBool(); - - for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - cInfo->questItems[i] = fields[75 + i].GetUInt32(); - - cInfo->movementId = fields[81].GetUInt32(); - cInfo->RegenHealth = fields[82].GetBool(); - cInfo->MechanicImmuneMask = fields[83].GetUInt32(); - cInfo->flags_extra = fields[84].GetUInt32(); - cInfo->ScriptID = sObjectMgr->GetScriptId(fields[85].GetCString()); - + sObjectMgr->LoadCreatureTemplate(fields); sObjectMgr->CheckCreatureTemplate(cInfo); } diff --git a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp index f996bcc6f70..e3021ff7a95 100644 --- a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp +++ b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp @@ -47,27 +47,20 @@ class npc_willix : public CreatureScript public: npc_willix() : CreatureScript("npc_willix") { } - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_WILLIX_THE_IMPORTER) - { - ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - creature->AI()->Talk(SAY_READY, player); - creature->setFaction(113); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_willixAI(creature); - } - struct npc_willixAI : public npc_escortAI { npc_willixAI(Creature* creature) : npc_escortAI(creature) { } + void sQuestAccept(Player* player, Quest const* quest) override + { + if (quest->GetQuestId() == QUEST_WILLIX_THE_IMPORTER) + { + Start(true, false, player->GetGUID()); + Talk(SAY_READY, player); + me->setFaction(113); + } + } + void WaypointReached(uint32 waypointId) override { Player* player = GetPlayerForEscort(); @@ -137,6 +130,10 @@ public: } }; + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_willixAI(creature); + } }; enum SnufflenoseGopher @@ -147,18 +144,6 @@ enum SnufflenoseGopher POINT_TUBBER = 0 }; -struct DistanceOrder : public std::binary_function<GameObject, GameObject, bool> -{ - DistanceOrder(Creature* me) : me(me) { } - - bool operator() (GameObject* first, GameObject* second) - { - return me->GetDistanceOrder(first, second); - } - - Creature* me; -}; - struct npc_snufflenose_gopher : public CreatureScript { public: @@ -208,18 +193,14 @@ public: if (tubbersInRange.empty()) return; - tubbersInRange.sort(DistanceOrder(me)); - GameObject* nearestTubber = NULL; - - for (std::list<GameObject*>::const_iterator itr = tubbersInRange.begin(); itr != tubbersInRange.end(); ++itr) + tubbersInRange.remove_if([](GameObject* go) { - if (!(*itr)->isSpawned() && (*itr)->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND)) - { - nearestTubber = *itr; - break; - } - } + return go->isSpawned() || !go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + }); + tubbersInRange.sort(Trinity::ObjectDistanceOrderPred(me)); + + GameObject* nearestTubber = tubbersInRange.front(); if (!nearestTubber) return; @@ -259,21 +240,16 @@ class spell_snufflenose_command : public SpellScriptLoader { PrepareSpellScript(spell_snufflenose_commandSpellScript); - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - void HandleAfterCast() + void HandleEffect(SpellEffIndex /*effIndex*/) { - if (Unit* target = GetCaster()->ToPlayer()->GetSelectedUnit()) + if (Creature* target = GetHitCreature()) if (target->GetEntry() == NPC_SNUFFLENOSE_GOPHER) - target->ToCreature()->AI()->DoAction(ACTION_FIND_NEW_TUBBER); + target->AI()->DoAction(ACTION_FIND_NEW_TUBBER); } void Register() override { - AfterCast += SpellCastFn(spell_snufflenose_commandSpellScript::HandleAfterCast); + OnEffectHitTarget += SpellEffectFn(spell_snufflenose_commandSpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index e1658e564ec..5ef84c7bb40 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -299,6 +299,12 @@ class boss_deathbringer_saurfang : public CreatureScript _introDone = true; + if (GameObject* teleporter = GameObject::GetGameObject(*me, instance->GetData64(GO_SCOURGE_TRANSPORTER_DEATHBRINGER))) + { + instance->HandleGameObject(0, false, teleporter); + teleporter->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + Talk(SAY_AGGRO); events.ScheduleEvent(EVENT_SUMMON_BLOOD_BEAST, 30000, 0, PHASE_COMBAT); events.ScheduleEvent(EVENT_BERSERK, IsHeroic() ? 360000 : 480000, 0, PHASE_COMBAT); @@ -538,12 +544,6 @@ class boss_deathbringer_saurfang : public CreatureScript case PHASE_INTRO_A: case PHASE_INTRO_H: { - if (GameObject* teleporter = GameObject::GetGameObject(*me, instance->GetData64(GO_SCOURGE_TRANSPORTER_SAURFANG))) - { - instance->HandleGameObject(0, false, teleporter); - teleporter->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // controls what events will execute events.SetPhase(uint32(action)); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 592c44940a4..e85ddc21dda 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -2102,7 +2102,15 @@ class at_icc_shutdown_traps : public AreaTriggerScript bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override { if (InstanceScript* instance = player->GetInstanceScript()) - instance->SetData(DATA_COLDFLAME_JETS, DONE); + { + instance->SetData(DATA_UPPERSPIRE_TELE_ACT, DONE); + uint64 teleporterGUID = instance->GetData64(GO_SCOURGE_TRANSPORTER_UPPERSPIRE); + if (GameObject* go = instance->instance->GetGameObject(teleporterGUID)) + { + go->SetGoState(GO_STATE_ACTIVE); + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + } return true; } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index da4a8f089cc..fbd3a715fb8 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -116,7 +116,8 @@ enum DataTypes DATA_HIGHLORD_TIRION_FORDRING = 37, DATA_ARTHAS_PLATFORM = 38, DATA_TERENAS_MENETHIL = 39, - DATA_ENEMY_GUNSHIP = 40 + DATA_ENEMY_GUNSHIP = 40, + DATA_UPPERSPIRE_TELE_ACT = 41, }; enum CreaturesIds @@ -322,6 +323,15 @@ enum CreaturesIds enum GameObjectsIds { + // ICC Teleporters + GO_SCOURGE_TRANSPORTER_LICHKING = 202223, + GO_SCOURGE_TRANSPORTER_UPPERSPIRE = 202235, + GO_SCOURGE_TRANSPORTER_LIGHTSHAMMER = 202242, + GO_SCOURGE_TRANSPORTER_RAMPART = 202243, + GO_SCOURGE_TRANSPORTER_DEATHBRINGER = 202244, + GO_SCOURGE_TRANSPORTER_ORATORY = 202245, + GO_SCOURGE_TRANSPORTER_SINDRAGOSA = 202246, + // Lower Spire Trash GO_SPIRIT_ALARM_1 = 201814, GO_SPIRIT_ALARM_2 = 201815, @@ -359,7 +369,6 @@ enum GameObjectsIds GO_DEATHBRINGER_S_CACHE_25N = 202240, GO_DEATHBRINGER_S_CACHE_10H = 202238, GO_DEATHBRINGER_S_CACHE_25H = 202241, - GO_SCOURGE_TRANSPORTER_SAURFANG = 202244, // Professor Putricide GO_ORANGE_PLAGUE_MONSTER_ENTRANCE = 201371, @@ -404,7 +413,6 @@ enum GameObjectsIds GO_SIGIL_OF_THE_FROSTWING = 202181, // The Lich King - GO_SCOURGE_TRANSPORTER_LK = 202223, GO_ARTHAS_PLATFORM = 202161, GO_ARTHAS_PRECIPICE = 202078, GO_DOODAD_ICECROWN_THRONEFROSTYWIND01 = 202188, diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp index 537c3c7354d..469bfc1d310 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp @@ -31,19 +31,23 @@ class icecrown_citadel_teleport : public GameObjectScript bool OnGossipHello(Player* player, GameObject* go) override { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Light's Hammer.", GOSSIP_SENDER_ICC_PORT, LIGHT_S_HAMMER_TELEPORT); if (InstanceScript* instance = go->GetInstanceScript()) { if (instance->GetBossState(DATA_LORD_MARROWGAR) == DONE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Oratory of the Damned.", GOSSIP_SENDER_ICC_PORT, ORATORY_OF_THE_DAMNED_TELEPORT); - if (instance->GetBossState(DATA_LADY_DEATHWHISPER) == DONE) + { + if (go->GetEntry() != GO_SCOURGE_TRANSPORTER_LIGHTSHAMMER) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Light's Hammer.", GOSSIP_SENDER_ICC_PORT, LIGHT_S_HAMMER_TELEPORT); + if (go->GetEntry() != GO_SCOURGE_TRANSPORTER_ORATORY) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Oratory of the Damned.", GOSSIP_SENDER_ICC_PORT, ORATORY_OF_THE_DAMNED_TELEPORT); + } + if (instance->GetBossState(DATA_LADY_DEATHWHISPER) == DONE && go->GetEntry() != GO_SCOURGE_TRANSPORTER_RAMPART) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Rampart of Skulls.", GOSSIP_SENDER_ICC_PORT, RAMPART_OF_SKULLS_TELEPORT); - if (instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE) + if (instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE && go->GetEntry() != GO_SCOURGE_TRANSPORTER_DEATHBRINGER) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Deathbringer's Rise.", GOSSIP_SENDER_ICC_PORT, DEATHBRINGER_S_RISE_TELEPORT); - if (instance->GetData(DATA_COLDFLAME_JETS) == DONE) + if (instance->GetData(DATA_UPPERSPIRE_TELE_ACT) == DONE && go->GetEntry() != GO_SCOURGE_TRANSPORTER_UPPERSPIRE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Upper Spire.", GOSSIP_SENDER_ICC_PORT, UPPER_SPIRE_TELEPORT); /// @todo Gauntlet event before Sindragosa - if (instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) == DONE) + if (instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) == DONE && go->GetEntry() != GO_SCOURGE_TRANSPORTER_SINDRAGOSA) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Sindragosa's Lair", GOSSIP_SENDER_ICC_PORT, SINDRAGOSA_S_LAIR_TELEPORT); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index febcf22ba6d..86e4efc5db7 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -127,7 +127,13 @@ class instance_icecrown_citadel : public InstanceMapScript DeathbringerSaurfangDoorGUID = 0; DeathbringerSaurfangEventGUID = 0; DeathbringersCacheGUID = 0; - SaurfangTeleportGUID = 0; + TeleporterLichKingGUID = 0; + TeleporterUpperSpireGUID = 0; + TeleporterLightsHammerGUID = 0; + TeleporterRampartsGUID = 0; + TeleporterDeathBringerGUID = 0; + TeleporterOratoryGUID = 0; + TeleporterSindragosaGUID = 0; PlagueSigilGUID = 0; BloodwingSigilGUID = 0; FrostwingSigilGUID = 0; @@ -164,10 +170,26 @@ class instance_icecrown_citadel : public InstanceMapScript IsNauseaEligible = true; IsOrbWhispererEligible = true; ColdflameJetsState = NOT_STARTED; + UpperSpireTeleporterActiveState = NOT_STARTED; BloodQuickeningState = NOT_STARTED; BloodQuickeningMinutes = 0; } + // A function to help reduce the number of lines for teleporter management. + void SetTeleporterState(GameObject* go, bool usable) + { + if (usable) + { + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + go->SetGoState(GO_STATE_ACTIVE); + } + else + { + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + go->SetGoState(GO_STATE_READY); + } + } + void FillInitialWorldStates(WorldPacket& data) override { data << uint32(WORLDSTATE_SHOW_TIMER) << uint32(BloodQuickeningState == IN_PROGRESS); @@ -542,8 +564,37 @@ class instance_icecrown_citadel : public InstanceMapScript case GO_DEATHBRINGER_S_CACHE_25H: DeathbringersCacheGUID = go->GetGUID(); break; - case GO_SCOURGE_TRANSPORTER_SAURFANG: - SaurfangTeleportGUID = go->GetGUID(); + case GO_SCOURGE_TRANSPORTER_LICHKING: + TeleporterLichKingGUID = go->GetGUID(); + if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE) + go->SetGoState(GO_STATE_ACTIVE); + break; + case GO_SCOURGE_TRANSPORTER_UPPERSPIRE: + TeleporterUpperSpireGUID = go->GetGUID(); + if (GetBossState(DATA_DEATHBRINGER_SAURFANG) != DONE || GetData(DATA_UPPERSPIRE_TELE_ACT) != DONE) + SetTeleporterState(go, false); + else + SetTeleporterState(go, true); + break; + case GO_SCOURGE_TRANSPORTER_LIGHTSHAMMER: + TeleporterLightsHammerGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_LORD_MARROWGAR) == DONE); + break; + case GO_SCOURGE_TRANSPORTER_RAMPART: + TeleporterRampartsGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_LADY_DEATHWHISPER) == DONE); + break; + case GO_SCOURGE_TRANSPORTER_DEATHBRINGER: + TeleporterDeathBringerGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE); + break; + case GO_SCOURGE_TRANSPORTER_ORATORY: + TeleporterOratoryGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_LORD_MARROWGAR) == DONE); + break; + case GO_SCOURGE_TRANSPORTER_SINDRAGOSA: + TeleporterSindragosaGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_VALITHRIA_DREAMWALKER) == DONE); break; case GO_PLAGUE_SIGIL: PlagueSigilGUID = go->GetGUID(); @@ -600,11 +651,6 @@ class instance_icecrown_citadel : public InstanceMapScript go->SetLootRecipient(valithria->GetLootRecipient()); go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); break; - case GO_SCOURGE_TRANSPORTER_LK: - TheLichKingTeleportGUID = go->GetGUID(); - if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE) - go->SetGoState(GO_STATE_ACTIVE); - break; case GO_ARTHAS_PLATFORM: ArthasPlatformGUID = go->GetGUID(); break; @@ -690,6 +736,8 @@ class instance_icecrown_citadel : public InstanceMapScript return RimefangTrash.size(); case DATA_COLDFLAME_JETS: return ColdflameJetsState; + case DATA_UPPERSPIRE_TELE_ACT: + return UpperSpireTeleporterActiveState; case DATA_TEAM_IN_INSTANCE: return TeamInInstance; case DATA_BLOOD_QUICKENING_STATE: @@ -717,8 +765,20 @@ class instance_icecrown_citadel : public InstanceMapScript return DeathbringerSaurfangEventGUID; case GO_SAURFANG_S_DOOR: return DeathbringerSaurfangDoorGUID; - case GO_SCOURGE_TRANSPORTER_SAURFANG: - return SaurfangTeleportGUID; + case GO_SCOURGE_TRANSPORTER_LICHKING: + return TeleporterLichKingGUID; + case GO_SCOURGE_TRANSPORTER_UPPERSPIRE: + return TeleporterUpperSpireGUID; + case GO_SCOURGE_TRANSPORTER_LIGHTSHAMMER: + return TeleporterLightsHammerGUID; + case GO_SCOURGE_TRANSPORTER_RAMPART: + return TeleporterRampartsGUID; + case GO_SCOURGE_TRANSPORTER_DEATHBRINGER: + return TeleporterDeathBringerGUID; + case GO_SCOURGE_TRANSPORTER_ORATORY: + return TeleporterOratoryGUID; + case GO_SCOURGE_TRANSPORTER_SINDRAGOSA: + return TeleporterSindragosaGUID; case DATA_FESTERGUT: return FestergutGUID; case DATA_ROTFACE: @@ -780,10 +840,24 @@ class instance_icecrown_citadel : public InstanceMapScript switch (type) { + case DATA_LORD_MARROWGAR: + { + if (state == DONE) + { + if (GameObject* teleporter = instance->GetGameObject(TeleporterLightsHammerGUID)) + SetTeleporterState(teleporter, true); + if (GameObject* teleporter = instance->GetGameObject(TeleporterOratoryGUID)) + SetTeleporterState(teleporter, true); + } + break; + } case DATA_LADY_DEATHWHISPER: { if (state == DONE) { + if (GameObject* teleporter = instance->GetGameObject(TeleporterRampartsGUID)) + SetTeleporterState(teleporter, true); + if (GameObject* elevator = instance->GetGameObject(LadyDeathwisperElevatorGUID)) { elevator->SetUInt32Value(GAMEOBJECT_LEVEL, 0); @@ -797,6 +871,9 @@ class instance_icecrown_citadel : public InstanceMapScript case DATA_ICECROWN_GUNSHIP_BATTLE: if (state == DONE) { + if (GameObject* teleporter = instance->GetGameObject(TeleporterDeathBringerGUID)) + SetTeleporterState(teleporter, true); + if (GameObject* loot = instance->GetGameObject(GunshipArmoryGUID)) loot->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); } @@ -807,20 +884,28 @@ class instance_icecrown_citadel : public InstanceMapScript switch (state) { case DONE: + { if (GameObject* loot = instance->GetGameObject(DeathbringersCacheGUID)) { if (Creature* deathbringer = instance->GetCreature(DeathbringerSaurfangGUID)) loot->SetLootRecipient(deathbringer->GetLootRecipient()); loot->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); } - // no break + + if (GameObject* teleporter = instance->GetGameObject(TeleporterUpperSpireGUID)) + SetTeleporterState(teleporter, true); + + if (GameObject* teleporter = instance->GetGameObject(TeleporterDeathBringerGUID)) + SetTeleporterState(teleporter, true); + break; + } case NOT_STARTED: - if (GameObject* teleporter = instance->GetGameObject(SaurfangTeleportGUID)) - { - HandleGameObject(SaurfangTeleportGUID, true, teleporter); - teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } + { + if (GameObject* teleporter = instance->GetGameObject(TeleporterDeathBringerGUID)) + SetTeleporterState(teleporter, true); + break; + } default: break; } @@ -890,8 +975,13 @@ class instance_icecrown_citadel : public InstanceMapScript } break; case DATA_VALITHRIA_DREAMWALKER: - if (state == DONE && sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[8].questId[instance->GetSpawnMode() & 1])) - instance->SummonCreature(NPC_VALITHRIA_DREAMWALKER_QUEST, ValithriaSpawnPos); + if (state == DONE) + { + if (sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[8].questId[instance->GetSpawnMode() & 1])) + instance->SummonCreature(NPC_VALITHRIA_DREAMWALKER_QUEST, ValithriaSpawnPos); + if (GameObject* teleporter = instance->GetGameObject(TeleporterSindragosaGUID)) + SetTeleporterState(teleporter, true); + } break; case DATA_SINDRAGOSA: HandleGameObject(FrostwingSigilGUID, state != DONE); @@ -1025,6 +1115,11 @@ class instance_icecrown_citadel : public InstanceMapScript SaveToDB(); break; } + case DATA_UPPERSPIRE_TELE_ACT: + UpperSpireTeleporterActiveState = data; + if (UpperSpireTeleporterActiveState == DONE) + SaveToDB(); + break; default: break; } @@ -1231,7 +1326,7 @@ class instance_icecrown_citadel : public InstanceMapScript std::ostringstream saveStream; saveStream << "I C " << GetBossSaveData() << HeroicAttempts << ' ' - << ColdflameJetsState << ' ' << BloodQuickeningState << ' ' << BloodQuickeningMinutes; + << ColdflameJetsState << ' ' << BloodQuickeningState << ' ' << BloodQuickeningMinutes << ' ' << UpperSpireTeleporterActiveState; OUT_SAVE_INST_DATA_COMPLETE; return saveStream.str(); @@ -1267,11 +1362,17 @@ class instance_icecrown_citadel : public InstanceMapScript uint32 temp = 0; loadStream >> temp; - ColdflameJetsState = temp ? DONE : NOT_STARTED; + if (temp == IN_PROGRESS) + ColdflameJetsState = NOT_STARTED; + else + ColdflameJetsState = temp ? DONE : NOT_STARTED; loadStream >> temp; BloodQuickeningState = temp ? DONE : NOT_STARTED; // DONE means finished (not success/fail) loadStream >> BloodQuickeningMinutes; + + loadStream >> temp; + UpperSpireTeleporterActiveState = temp ? DONE : NOT_STARTED; } else OUT_LOAD_INST_DATA_FAIL; @@ -1412,7 +1513,13 @@ class instance_icecrown_citadel : public InstanceMapScript uint64 DeathbringerSaurfangDoorGUID; uint64 DeathbringerSaurfangEventGUID; // Muradin Bronzebeard or High Overlord Saurfang uint64 DeathbringersCacheGUID; - uint64 SaurfangTeleportGUID; + uint64 TeleporterLichKingGUID; + uint64 TeleporterUpperSpireGUID; + uint64 TeleporterLightsHammerGUID; + uint64 TeleporterRampartsGUID; + uint64 TeleporterDeathBringerGUID; + uint64 TeleporterOratoryGUID; + uint64 TeleporterSindragosaGUID; uint64 PlagueSigilGUID; uint64 BloodwingSigilGUID; uint64 FrostwingSigilGUID; @@ -1449,6 +1556,7 @@ class instance_icecrown_citadel : public InstanceMapScript uint64 PillarsUnchainedGUID; uint32 TeamInInstance; uint32 ColdflameJetsState; + uint32 UpperSpireTeleporterActiveState; std::set<uint32> FrostwyrmGUIDs; std::set<uint32> SpinestalkerTrash; std::set<uint32> RimefangTrash; diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp index 42be5ba8c90..f82c1f5fb58 100644 --- a/src/server/scripts/Outland/zone_netherstorm.cpp +++ b/src/server/scripts/Outland/zone_netherstorm.cpp @@ -19,13 +19,11 @@ /* ScriptData SDName: Netherstorm SD%Complete: 80 -SDComment: Quest support: 10337, 10438, 10652 (special flight paths), 10299, 10321, 10322, 10323, 10329, 10330, 10338, 10365(Shutting Down Manaforge), 10198, 10191 +SDComment: Quest support: 10337, 10438, 10652 (special flight paths), 10198, 10191 SDCategory: Netherstorm EndScriptData */ /* ContentData -npc_manaforge_control_console -go_manaforge_control_console npc_commander_dawnforge npc_bessy npc_maxx_a_million @@ -39,323 +37,6 @@ EndContentData */ #include "Player.h" /*###### -## npc_manaforge_control_console -######*/ - -//used by 20209, 20417, 20418, 20440, signed for 20209 -enum ManaforgeConsoleData -{ - EMOTE_START = 0, - EMOTE_60 = 1, - EMOTE_30 = 2, - EMOTE_10 = 3, - EMOTE_COMPLETE = 4, - EMOTE_ABORT = 5, - - ENTRY_BNAAR_C_CONSOLE = 20209, - ENTRY_CORUU_C_CONSOLE = 20417, - ENTRY_DURO_C_CONSOLE = 20418, - ENTRY_ARA_C_CONSOLE = 20440, - - ENTRY_SUNFURY_TECH = 20218, - ENTRY_SUNFURY_PROT = 20436, - - ENTRY_ARA_TECH = 20438, - ENTRY_ARA_ENGI = 20439, - ENTRY_ARA_GORKLONN = 20460, - - SPELL_DISABLE_VISUAL = 35031, - SPELL_INTERRUPT_1 = 35016, //ACID mobs should cast this - SPELL_INTERRUPT_2 = 35176, //ACID mobs should cast this (Manaforge Ara-version) -}; - -class npc_manaforge_control_console : public CreatureScript -{ -public: - npc_manaforge_control_console() : CreatureScript("npc_manaforge_control_console") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_manaforge_control_consoleAI(creature); - } - - struct npc_manaforge_control_consoleAI : public ScriptedAI - { - npc_manaforge_control_consoleAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 Event_Timer; - uint32 Wave_Timer; - uint32 Phase; - bool Wave; - uint64 someplayer; - uint64 goConsole; - Creature* add; - - void Reset() override - { - Event_Timer = 3000; - Wave_Timer = 0; - Phase = 1; - Wave = false; - someplayer = 0; - goConsole = 0; - add = NULL; - } - - void EnterCombat(Unit* /*who*/) override { } - - /*void SpellHit(Unit* caster, const SpellInfo* spell) override - { - //we have no way of telling the Creature was hit by spell -> got aura applied after 10-12 seconds - //then no way for the mobs to actually stop the shutdown as intended. - if (spell->Id == SPELL_INTERRUPT_1) - DoSay("Silence! I kill you!", LANG_UNIVERSAL, NULL); - }*/ - - void JustDied(Unit* /*killer*/) override - { - Talk(EMOTE_ABORT); - - if (someplayer) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, someplayer)) - { - switch (me->GetEntry()) - { - case ENTRY_BNAAR_C_CONSOLE: - player->FailQuest(10299); - player->FailQuest(10329); - break; - case ENTRY_CORUU_C_CONSOLE: - player->FailQuest(10321); - player->FailQuest(10330); - break; - case ENTRY_DURO_C_CONSOLE: - player->FailQuest(10322); - player->FailQuest(10338); - break; - case ENTRY_ARA_C_CONSOLE: - player->FailQuest(10323); - player->FailQuest(10365); - break; - } - } - } - - if (goConsole) - if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } - - void DoWaveSpawnForCreature(Creature* creature) - { - switch (creature->GetEntry()) - { - case ENTRY_BNAAR_C_CONSOLE: - if (rand32() % 2) - { - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2933.68f, 4162.55f, 164.00f, 1.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2927.36f, 4212.97f, 164.00f); - } - else - { - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2927.36f, 4212.97f, 164.00f, 4.94f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2933.68f, 4162.55f, 164.00f); - } - Wave_Timer = 30000; - break; - case ENTRY_CORUU_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2445.21f, 2765.26f, 134.49f, 3.93f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2424.21f, 2740.15f, 133.81f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2429.86f, 2731.85f, 134.53f, 1.31f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2435.37f, 2766.04f, 133.81f); - Wave_Timer = 20000; - break; - case ENTRY_DURO_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2986.80f, 2205.36f, 165.37f, 3.74f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2985.15f, 2197.32f, 164.79f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2952.91f, 2191.20f, 165.32f, 0.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2060.01f, 2185.27f, 164.67f); - Wave_Timer = 15000; - break; - case ENTRY_ARA_C_CONSOLE: - if (rand32() % 2) - { - add = me->SummonCreature(ENTRY_ARA_TECH, 4035.11f, 4038.97f, 194.27f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); - add = me->SummonCreature(ENTRY_ARA_TECH, 4033.66f, 4036.79f, 194.28f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); - add = me->SummonCreature(ENTRY_ARA_TECH, 4037.13f, 4037.30f, 194.23f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); - } - else - { - add = me->SummonCreature(ENTRY_ARA_TECH, 3099.59f, 4049.30f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); - add = me->SummonCreature(ENTRY_ARA_TECH, 3999.72f, 4046.75f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); - add = me->SummonCreature(ENTRY_ARA_TECH, 3996.81f, 4048.26f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); - } - Wave_Timer = 15000; - break; - } - } - void DoFinalSpawnForCreature(Creature* creature) - { - switch (creature->GetEntry()) - { - case ENTRY_BNAAR_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2946.52f, 4201.42f, 163.47f, 3.54f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2927.49f, 4192.81f, 163.00f); - break; - case ENTRY_CORUU_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2453.88f, 2737.85f, 133.27f, 2.59f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2441.62f, 2735.32f, 134.49f, 1.97f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2450.73f, 2754.50f, 134.49f, 3.29f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); - break; - case ENTRY_DURO_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2956.18f, 2202.85f, 165.32f, 5.45f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2975.30f, 2211.50f, 165.32f, 4.55f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); - add = me->SummonCreature(ENTRY_SUNFURY_PROT, 2965.02f, 2217.45f, 164.16f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); - break; - case ENTRY_ARA_C_CONSOLE: - add = me->SummonCreature(ENTRY_ARA_ENGI, 3994.51f, 4020.46f, 192.18f, 0.91f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4008.35f, 4035.04f, 192.70f); - add = me->SummonCreature(ENTRY_ARA_GORKLONN, 4021.56f, 4059.35f, 193.59f, 4.44f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4016.62f, 4039.89f, 193.46f); - break; - } - } - - void UpdateAI(uint32 diff) override - { - if (Event_Timer <= diff) - { - switch (Phase) - { - case 1: - if (someplayer) - { - Unit* u = ObjectAccessor::GetUnit(*me, someplayer); - if (u && u->GetTypeId() == TYPEID_PLAYER) - Talk(EMOTE_START, u); - } - Event_Timer = 60000; - Wave = true; - ++Phase; - break; - case 2: - Talk(EMOTE_60); - Event_Timer = 30000; - ++Phase; - break; - case 3: - Talk(EMOTE_30); - Event_Timer = 20000; - DoFinalSpawnForCreature(me); - ++Phase; - break; - case 4: - Talk(EMOTE_10); - Event_Timer = 10000; - Wave = false; - ++Phase; - break; - case 5: - Talk(EMOTE_COMPLETE); - if (someplayer) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, someplayer)) - player->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); - DoCast(me, SPELL_DISABLE_VISUAL); - } - - if (goConsole) - if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - - ++Phase; - break; - } - } - else - Event_Timer -= diff; - - if (Wave) - { - if (Wave_Timer <= diff) - { - DoWaveSpawnForCreature(me); - } - else - Wave_Timer -= diff; - } - } - }; -}; - -/*###### -## go_manaforge_control_console -######*/ - -/// @todo clean up this workaround when Trinity adds support to do it properly (with gossip selections instead of instant summon) -class go_manaforge_control_console : public GameObjectScript -{ -public: - go_manaforge_control_console() : GameObjectScript("go_manaforge_control_console") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - if (go->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) - { - player->PrepareQuestMenu(go->GetGUID()); - player->SendPreparedQuest(go->GetGUID()); - } - - Creature* manaforge = NULL; - - switch (go->GetAreaId()) - { - case 3726: //b'naar - if ((player->GetQuestStatus(10299) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10329) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29366)) - manaforge = player->SummonCreature(ENTRY_BNAAR_C_CONSOLE, 2918.95f, 4189.98f, 161.88f, 0.34f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - case 3730: //coruu - if ((player->GetQuestStatus(10321) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10330) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29396)) - manaforge = player->SummonCreature(ENTRY_CORUU_C_CONSOLE, 2426.77f, 2750.38f, 133.24f, 2.14f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - case 3734: //duro - if ((player->GetQuestStatus(10322) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10338) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29397)) - manaforge = player->SummonCreature(ENTRY_DURO_C_CONSOLE, 2976.48f, 2183.29f, 163.20f, 1.85f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - case 3722: //ara - if ((player->GetQuestStatus(10323) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10365) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29411)) - manaforge = player->SummonCreature(ENTRY_ARA_C_CONSOLE, 4013.71f, 4028.76f, 192.10f, 1.25f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - } - - if (manaforge) - { - ENSURE_AI(npc_manaforge_control_console::npc_manaforge_control_consoleAI, manaforge->AI())->someplayer = player->GetGUID(); - ENSURE_AI(npc_manaforge_control_console::npc_manaforge_control_consoleAI, manaforge->AI())->goConsole = go->GetGUID(); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } - return true; - } -}; - -/*###### ## npc_commander_dawnforge ######*/ @@ -1054,8 +735,6 @@ class go_captain_tyralius_prison : public GameObjectScript void AddSC_netherstorm() { - new go_manaforge_control_console(); - new npc_manaforge_control_console(); new npc_commander_dawnforge(); new at_commander_dawnforge(); new npc_professor_dabiri(); diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp index 7dbdc7af63f..8fd6cb54b0e 100644 --- a/src/server/scripts/Pet/pet_hunter.cpp +++ b/src/server/scripts/Pet/pet_hunter.cpp @@ -57,7 +57,7 @@ class npc_pet_hunter_snake_trap : public CreatureScript me->SetMaxHealth(uint32(107 * (me->getLevel() - 40) * 0.025f)); // Add delta to make them not all hit the same time uint32 delta = (rand32() % 7) * 100; - me->SetAttackTime(BASE_ATTACK, Info->baseattacktime + delta); + me->SetAttackTime(BASE_ATTACK, Info->BaseAttackTime + delta); //me->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER, float(Info->attackpower)); // Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index c4bd473f1d1..70451888c07 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -991,7 +991,7 @@ class spell_item_unsated_craving : public SpellScriptLoader return false; Unit* target = procInfo.GetActionTarget(); - if (!target || target->GetTypeId() != TYPEID_UNIT || target->GetCreatureType() == CREATURE_TYPE_CRITTER || (target->GetEntry() != NPC_SINDRAGOSA && target->IsSummon())) + if (!target || target->GetTypeId() != TYPEID_UNIT || target->IsCritter() || (target->GetEntry() != NPC_SINDRAGOSA && target->IsSummon())) return false; return true; diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index 53f3b5519cd..e5aeaf46c15 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -76,7 +76,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); + PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH); @@ -89,6 +89,4 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_INS_DISABLES, "INSERT INTO disables (entry, sourceType, flags, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(WORLD_SEL_DISABLES, "SELECT entry FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_DEL_DISABLES, "DELETE FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_ASYNC); - // 0: uint8 - PrepareStatement(WORLD_SEL_REQ_XP, "SELECT xp_for_next_level FROM player_xp_for_level WHERE lvl = ?", CONNECTION_SYNCH); } diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h index 625dfc68ce6..8a5bd206021 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.h +++ b/src/server/shared/Database/Implementation/WorldDatabase.h @@ -110,7 +110,6 @@ enum WorldDatabaseStatements WORLD_SEL_DISABLES, WORLD_INS_DISABLES, WORLD_DEL_DISABLES, - WORLD_SEL_REQ_XP, MAX_WORLDDATABASE_STATEMENTS }; diff --git a/src/server/shared/Networking/MessageBuffer.h b/src/server/shared/Networking/MessageBuffer.h index 547b39130a4..c7f8ba31a71 100644 --- a/src/server/shared/Networking/MessageBuffer.h +++ b/src/server/shared/Networking/MessageBuffer.h @@ -40,6 +40,10 @@ public: bool IsMessageReady() const { return _wpos == _storage.size(); } + size_type GetSize() const { return _storage.size(); } + + size_type GetReadyDataSize() const { return _wpos; } + size_type GetMissingSize() const { return _storage.size() - _wpos; } uint8* Data() { return _storage.data(); } @@ -55,8 +59,6 @@ public: void ResetWritePointer() { _wpos = 0; } - size_type GetSize() const { return _storage.size(); } - std::vector<uint8>&& Move() { _wpos = 0; diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h index dd638c059a5..a13a079ff6c 100644 --- a/src/server/shared/Networking/Socket.h +++ b/src/server/shared/Networking/Socket.h @@ -146,8 +146,8 @@ public: uint8* GetHeaderBuffer() { return _readHeaderBuffer.Data(); } uint8* GetDataBuffer() { return _readDataBuffer.Data(); } - size_t GetHeaderSize() const { return _readHeaderBuffer.GetSize(); } - size_t GetDataSize() const { return _readDataBuffer.GetSize(); } + size_t GetHeaderSize() const { return _readHeaderBuffer.GetReadyDataSize(); } + size_t GetDataSize() const { return _readDataBuffer.GetReadyDataSize(); } MessageBuffer&& MoveHeader() { return std::move(_readHeaderBuffer); } MessageBuffer&& MoveData() { return std::move(_readDataBuffer); } diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h index accb0aebb11..a76b8b0b5c0 100644 --- a/src/server/shared/Threading/ProducerConsumerQueue.h +++ b/src/server/shared/Threading/ProducerConsumerQueue.h @@ -39,10 +39,8 @@ public: void Push(const T& value) { - { - std::lock_guard<std::mutex> lock(_queueLock); - _queue.push(std::move(value)); - } + std::lock_guard<std::mutex> lock(_queueLock); + _queue.push(std::move(value)); _condition.notify_one(); } @@ -72,10 +70,7 @@ public: { std::unique_lock<std::mutex> lock(_queueLock); - while (_queue.empty() && !_shutdown) - { - _condition.wait(lock); - } + _condition.wait(lock, [this]() { return !_queue.empty() || _shutdown; }); if (_queue.empty() || _shutdown) return; |