Merge branch 'master' into Playerbot
This commit is contained in:
@@ -640,12 +640,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
me->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlags);
|
||||
LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CAST: Unit {} casts spell {} on target {} with castflags {}",
|
||||
me->GetGUID().ToString().c_str(), e.action.cast.spell, target->GetGUID().ToString().c_str(), e.action.cast.castFlags);
|
||||
me->GetGUID().ToString(), e.action.cast.spell, target->GetGUID().ToString(), e.action.cast.castFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("scripts.ai", "Spell {} not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target {} already has the aura",
|
||||
e.action.cast.spell, target->GetGUID().ToString().c_str());
|
||||
e.action.cast.spell, target->GetGUID().ToString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -729,12 +729,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
tempLastInvoker->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlags);
|
||||
LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INVOKER_CAST: Invoker {} casts spell {} on target {} with castflags {}",
|
||||
tempLastInvoker->GetGUID().ToString().c_str(), e.action.cast.spell, target->GetGUID().ToString().c_str(), e.action.cast.castFlags);
|
||||
tempLastInvoker->GetGUID().ToString(), e.action.cast.spell, target->GetGUID().ToString(), e.action.cast.castFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("scripts.ai", "Spell {} not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target {} already has the aura",
|
||||
e.action.cast.spell, target->GetGUID().ToString().c_str());
|
||||
e.action.cast.spell, target->GetGUID().ToString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2797,6 +2797,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_DISABLE:
|
||||
{
|
||||
for (WorldObject* target : targets)
|
||||
{
|
||||
if (IsUnit(target))
|
||||
{
|
||||
target->ToUnit()->SetImmuneToAll(!e.action.disable.state);
|
||||
target->ToUnit()->SetVisible(e.action.disable.state);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||
break;
|
||||
|
||||
@@ -762,6 +762,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
||||
case SMART_ACTION_LOAD_GRID: return NO_PARAMS;
|
||||
case SMART_ACTION_MUSIC: return sizeof(SmartAction::music);
|
||||
case SMART_ACTION_SET_GUID: return sizeof(SmartAction::setGuid);
|
||||
case SMART_ACTION_DISABLE: return sizeof(SmartAction::disable);
|
||||
default:
|
||||
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||
@@ -1918,6 +1919,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
case SMART_ACTION_ATTACK_STOP:
|
||||
case SMART_ACTION_PLAY_CINEMATIC:
|
||||
case SMART_ACTION_SET_GUID:
|
||||
case SMART_ACTION_DISABLE:
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type({}), event_type({}), Entry {} SourceType {} Event {}, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
|
||||
|
||||
@@ -693,8 +693,9 @@ enum SMART_ACTION
|
||||
SMART_ACTION_DO_ACTION = 223, // ActionId
|
||||
SMART_ACTION_ATTACK_STOP = 224, //
|
||||
SMART_ACTION_SET_GUID = 225, // Sends the invoker's or the base object's own ObjectGuid to target
|
||||
SMART_ACTION_DISABLE = 226, // Disable the targeted creatures, setting them Invisible and Immune to All
|
||||
|
||||
SMART_ACTION_AC_END = 226, // placeholder
|
||||
SMART_ACTION_AC_END = 227, // placeholder
|
||||
};
|
||||
|
||||
enum class SmartActionSummonCreatureFlags
|
||||
@@ -1365,6 +1366,11 @@ struct SmartAction
|
||||
SAIBool invokerGUID;
|
||||
uint32 index;
|
||||
} setGuid;
|
||||
|
||||
struct
|
||||
{
|
||||
SAIBool state;
|
||||
} disable;
|
||||
//! Note for any new future actions
|
||||
//! All parameters must have type uint32
|
||||
|
||||
|
||||
@@ -2683,7 +2683,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
|
||||
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
|
||||
LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has ScriptName set for non-scripted data type (Entry: {}, type {}), useless data.", criteria_id, dataType);
|
||||
else
|
||||
scriptId = sObjectMgr->GetScriptId(scriptName.c_str());
|
||||
scriptId = sObjectMgr->GetScriptId(scriptName);
|
||||
}
|
||||
|
||||
AchievementCriteriaData data(dataType, fields[2].Get<uint32>(), fields[3].Get<uint32>(), scriptId);
|
||||
|
||||
@@ -459,7 +459,7 @@ uint32 CalendarMgr::GetPlayerNumPending(ObjectGuid guid)
|
||||
std::string CalendarEvent::BuildCalendarMailSubject(ObjectGuid remover) const
|
||||
{
|
||||
std::ostringstream strm;
|
||||
strm << remover.ToString().c_str() << ':' << _title;
|
||||
strm << remover.ToString() << ':' << _title;
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ void LoadM2Cameras(std::string const& dataPath)
|
||||
// Reject if not at least the size of the header
|
||||
if (static_cast<uint32>(fileSize) < sizeof(M2Header))
|
||||
{
|
||||
LOG_ERROR("server.loading", "Camera file {} is damaged. File is smaller than header size", filename.string().c_str());
|
||||
LOG_ERROR("server.loading", "Camera file {} is damaged. File is smaller than header size", filename.string());
|
||||
m2file.close();
|
||||
continue;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ void LoadM2Cameras(std::string const& dataPath)
|
||||
// Check file has correct magic (MD20)
|
||||
if (strcmp(fileCheck, "MD20"))
|
||||
{
|
||||
LOG_ERROR("server.loading", "Camera file {} is damaged. File identifier not found", filename.string().c_str());
|
||||
LOG_ERROR("server.loading", "Camera file {} is damaged. File identifier not found", filename.string());
|
||||
m2file.close();
|
||||
continue;
|
||||
}
|
||||
@@ -240,14 +240,14 @@ void LoadM2Cameras(std::string const& dataPath)
|
||||
|
||||
if (header->ofsCameras + sizeof(M2Camera) > static_cast<uint32>(fileSize))
|
||||
{
|
||||
LOG_ERROR("server.loading", "Camera file {} is damaged. Camera references position beyond file end", filename.string().c_str());
|
||||
LOG_ERROR("server.loading", "Camera file {} is damaged. Camera references position beyond file end", filename.string());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get camera(s) - Main header, then dump them.
|
||||
M2Camera const* cam = reinterpret_cast<M2Camera const*>(buffer.data() + header->ofsCameras);
|
||||
if (!readCamera(cam, fileSize, header, dbcentry))
|
||||
LOG_ERROR("server.loading", "Camera file {} is damaged. Camera references position beyond file end", filename.string().c_str());
|
||||
LOG_ERROR("server.loading", "Camera file {} is damaged. Camera references position beyond file end", filename.string());
|
||||
}
|
||||
|
||||
LOG_INFO("server.loading", ">> Loaded {} Cinematic Waypoint Sets in {} ms", (uint32)sFlyByCameraStore.size(), GetMSTimeDiffToNow(oldMSTime));
|
||||
|
||||
@@ -484,7 +484,7 @@ namespace lfg
|
||||
[[nodiscard]] std::string toString() const // for debugging
|
||||
{
|
||||
std::ostringstream o;
|
||||
o << guids[0].ToString().c_str() << "," << guids[1].ToString().c_str() << "," << guids[2].ToString().c_str() << "," << guids[3].ToString().c_str() << "," << guids[4].ToString().c_str() << ":" << (roles ? 1 : 0);
|
||||
o << guids[0].ToString() << "," << guids[1].ToString() << "," << guids[2].ToString() << "," << guids[3].ToString() << "," << guids[4].ToString() << ":" << (roles ? 1 : 0);
|
||||
return o.str();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1124,11 +1124,11 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
|
||||
SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, GetCreateMana());
|
||||
|
||||
// xinef: added some multipliers so debuffs can affect pets in any way...
|
||||
SetCreateStat(STAT_STRENGTH, 22 + 2 * petlevel);
|
||||
SetCreateStat(STAT_AGILITY, 22 + 1.5f * petlevel);
|
||||
SetCreateStat(STAT_STAMINA, 25 + 2 * petlevel);
|
||||
SetCreateStat(STAT_INTELLECT, 28 + 2 * petlevel);
|
||||
SetCreateStat(STAT_SPIRIT, 27 + 1.5f * petlevel);
|
||||
SetCreateStat(STAT_STRENGTH, 22);
|
||||
SetCreateStat(STAT_AGILITY, 22);
|
||||
SetCreateStat(STAT_STAMINA, 25);
|
||||
SetCreateStat(STAT_INTELLECT, 28);
|
||||
SetCreateStat(STAT_SPIRIT, 27);
|
||||
}
|
||||
|
||||
switch (petType)
|
||||
@@ -1348,6 +1348,14 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
|
||||
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
|
||||
break;
|
||||
}
|
||||
case NPC_VENOMOUS_SNAKE:
|
||||
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 0.7 - 38));
|
||||
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 0.8 - 40));
|
||||
break;
|
||||
case NPC_VIPER:
|
||||
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(1.3 * petlevel - 64));
|
||||
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(1.5 * petlevel - 68));
|
||||
break;
|
||||
case NPC_GENERIC_IMP:
|
||||
case NPC_GENERIC_VOIDWALKER:
|
||||
{
|
||||
|
||||
@@ -122,6 +122,10 @@ enum NPCEntries
|
||||
NPC_ARMY_OF_THE_DEAD = 24207,
|
||||
NPC_EBON_GARGOYLE = 27829,
|
||||
|
||||
// Hunter
|
||||
NPC_VENOMOUS_SNAKE = 19833,
|
||||
NPC_VIPER = 19921,
|
||||
|
||||
// Generic
|
||||
NPC_GENERIC_IMP = 12922,
|
||||
NPC_GENERIC_VOIDWALKER = 8996
|
||||
|
||||
@@ -166,6 +166,7 @@ void KillRewarder::_RewardXP(Player* player, float rate)
|
||||
AddPct(xp, (*i)->GetAmount());
|
||||
|
||||
// 4.2.3. Give XP to player.
|
||||
sScriptMgr->OnGivePlayerXP(player, xp, _victim, PlayerXPSource::XPSOURCE_KILL);
|
||||
player->GiveXP(xp, _victim, _groupRate);
|
||||
if (Pet* pet = player->GetPet())
|
||||
// 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case).
|
||||
|
||||
@@ -2372,8 +2372,6 @@ void Player::GiveXP(uint32 xp, Unit* victim, float group_rate, bool isLFGReward)
|
||||
|
||||
uint8 level = GetLevel();
|
||||
|
||||
sScriptMgr->OnGivePlayerXP(this, xp, victim);
|
||||
|
||||
// Favored experience increase START
|
||||
uint32 zone = GetZoneId();
|
||||
float favored_exp_mult = 0;
|
||||
@@ -5147,7 +5145,7 @@ float Player::OCTRegenHPPerSpirit()
|
||||
if (baseSpirit > 50)
|
||||
baseSpirit = 50;
|
||||
float moreSpirit = spirit - baseSpirit;
|
||||
float regen = baseSpirit * baseRatio->ratio + moreSpirit * moreRatio->ratio;
|
||||
float regen = (baseSpirit * baseRatio->ratio + moreSpirit * moreRatio->ratio) * 2;
|
||||
return regen;
|
||||
}
|
||||
|
||||
@@ -5732,6 +5730,7 @@ void Player::CheckAreaExploreAndOutdoor()
|
||||
XP = uint32(sObjectMgr->GetBaseXP(areaEntry->area_level) * sWorld->getRate(RATE_XP_EXPLORE));
|
||||
}
|
||||
|
||||
sScriptMgr->OnGivePlayerXP(this, XP, nullptr, PlayerXPSource::XPSOURCE_EXPLORE);
|
||||
GiveXP(XP, nullptr);
|
||||
SendExplorationExperience(areaId, XP);
|
||||
}
|
||||
@@ -6121,7 +6120,11 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool awar
|
||||
bg->UpdatePlayerScore(this, SCORE_BONUS_HONOR, honor, false); //false: prevent looping
|
||||
// Xinef: Only for BG activities
|
||||
if (!uVictim)
|
||||
GiveXP(uint32(honor * (3 + GetLevel() * 0.30f)), nullptr);
|
||||
{
|
||||
uint32 xp = uint32(honor * (3 + GetLevel() * 0.30f));
|
||||
sScriptMgr->OnGivePlayerXP(this, xp, nullptr, PlayerXPSource::XPSOURCE_BATTLEGROUND);
|
||||
GiveXP(xp, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (sWorld->getBoolConfig(CONFIG_PVP_TOKEN_ENABLE))
|
||||
@@ -7074,7 +7077,8 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply,
|
||||
|
||||
LOG_DEBUG("entities.player", "WORLD: cast {} Equip spellId - {}", (item ? "item" : "itemset"), spellInfo->Id);
|
||||
|
||||
CastSpell(this, spellInfo, true, item);
|
||||
//Ignore spellInfo->DurationEntry, cast with -1 duration
|
||||
CastCustomSpell(spellInfo->Id, SPELLVALUE_AURA_DURATION, -1, this, true, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -995,6 +995,16 @@ enum PlayerCommandStates
|
||||
CHEAT_WATERWALK = 0x10
|
||||
};
|
||||
|
||||
// Used for OnGiveXP PlayerScript hook
|
||||
enum PlayerXPSource
|
||||
{
|
||||
XPSOURCE_KILL = 0,
|
||||
XPSOURCE_QUEST = 1,
|
||||
XPSOURCE_QUEST_DF = 2,
|
||||
XPSOURCE_EXPLORE = 3,
|
||||
XPSOURCE_BATTLEGROUND = 4
|
||||
};
|
||||
|
||||
enum InstantFlightGossipAction
|
||||
{
|
||||
GOSSIP_ACTION_TOGGLE_INSTANT_FLIGHT = 500
|
||||
|
||||
@@ -756,6 +756,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
}
|
||||
else
|
||||
{
|
||||
sScriptMgr->OnGivePlayerXP(this, XP, nullptr, isLFGReward ? PlayerXPSource::XPSOURCE_QUEST_DF : PlayerXPSource::XPSOURCE_QUEST);
|
||||
GiveXP(XP, nullptr, isLFGReward);
|
||||
}
|
||||
|
||||
|
||||
@@ -6978,7 +6978,7 @@ bool Player::CheckInstanceLoginValid()
|
||||
if (GetMap()->IsRaid())
|
||||
{
|
||||
// cannot be in raid instance without a group
|
||||
if (!GetGroup())
|
||||
if (!GetGroup() && !sWorld->getBoolConfig(CONFIG_INSTANCE_IGNORE_RAID))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -812,14 +812,8 @@ void Unit::DealDamageMods(Unit const* victim, uint32& damage, uint32* absorb)
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss, bool /*allowGM*/, Spell const* damageSpell /*= nullptr*/, bool delayed)
|
||||
uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss, bool /*allowGM*/, Spell const* damageSpell /*= nullptr*/)
|
||||
{
|
||||
if (delayed && attacker->GetTypeId() == TYPEID_PLAYER && attacker->GetGUID() != victim->GetGUID())
|
||||
{
|
||||
sWorld->AddDelayedDamage(attacker, victim, damage, cleanDamage, damagetype, damageSchoolMask, spellProto, durabilityLoss);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Xinef: initialize damage done for rage calculations
|
||||
// Xinef: its rare to modify damage in hooks, however training dummy's sets damage to 0
|
||||
uint32 rage_damage = damage + ((cleanDamage != nullptr) ? cleanDamage->absorbed_damage : 0);
|
||||
@@ -1460,7 +1454,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss,
|
||||
|
||||
// Call default DealDamage
|
||||
CleanDamage cleanDamage(damageInfo->cleanDamage, damageInfo->absorb, BASE_ATTACK, MELEE_HIT_NORMAL);
|
||||
Unit::DealDamage(this, victim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss, false, spell, true);
|
||||
Unit::DealDamage(this, victim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss, false, spell);
|
||||
}
|
||||
|
||||
// @todo for melee need create structure as in
|
||||
@@ -10392,7 +10386,7 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
|
||||
creature->SendAIReaction(AI_REACTION_HOSTILE);
|
||||
|
||||
/// @todo: Implement aggro range, detection range and assistance range templates
|
||||
if (!(creature->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE))
|
||||
if (!(creature->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE))
|
||||
{
|
||||
creature->CallAssistance();
|
||||
}
|
||||
@@ -20081,6 +20075,9 @@ void Unit::_ExitVehicle(Position const* exitPosition)
|
||||
Unit* vehicleBase = m_vehicle->GetBase();
|
||||
m_vehicle = nullptr;
|
||||
|
||||
if (!vehicleBase)
|
||||
return;
|
||||
|
||||
SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
|
||||
|
||||
Position pos;
|
||||
|
||||
@@ -757,18 +757,6 @@ struct CleanDamage
|
||||
struct CalcDamageInfo;
|
||||
struct SpellNonMeleeDamage;
|
||||
|
||||
struct DelayedDamage
|
||||
{
|
||||
Unit* attacker;
|
||||
Unit* victim;
|
||||
uint32 damage;
|
||||
CleanDamage const* cleanDamage;
|
||||
DamageEffectType damagetype;
|
||||
SpellSchoolMask damageSchoolMask;
|
||||
SpellInfo const* spellProto;
|
||||
bool durabilityLoss;
|
||||
};
|
||||
|
||||
class DamageInfo
|
||||
{
|
||||
private:
|
||||
@@ -1571,7 +1559,7 @@ public:
|
||||
|
||||
uint16 GetMaxSkillValueForLevel(Unit const* target = nullptr) const { return (target ? getLevelForTarget(target) : GetLevel()) * 5; }
|
||||
static void DealDamageMods(Unit const* victim, uint32& damage, uint32* absorb);
|
||||
static uint32 DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true, bool allowGM = false, Spell const* spell = nullptr, bool delayed = false);
|
||||
static uint32 DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true, bool allowGM = false, Spell const* spell = nullptr);
|
||||
static void Kill(Unit* killer, Unit* victim, bool durabilityLoss = true, WeaponAttackType attackType = BASE_ATTACK, SpellInfo const* spellProto = nullptr, Spell const* spell = nullptr);
|
||||
void KillSelf(bool durabilityLoss = true, WeaponAttackType attackType = BASE_ATTACK, SpellInfo const* spellProto = nullptr, Spell const* spell = nullptr) { Kill(this, this, durabilityLoss, attackType, spellProto, spell); };
|
||||
static int32 DealHeal(Unit* healer, Unit* victim, uint32 addhealth);
|
||||
|
||||
@@ -2885,7 +2885,7 @@ void ObjectMgr::LoadItemTemplates()
|
||||
}
|
||||
if (itemTemplate.Material != dbcitem->Material)
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Item (Entry: {%u}}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material);
|
||||
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material);
|
||||
if (enforceDBCAttributes)
|
||||
itemTemplate.Material = dbcitem->Material;
|
||||
}
|
||||
@@ -2897,7 +2897,7 @@ void ObjectMgr::LoadItemTemplates()
|
||||
}
|
||||
if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID)
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Item (Entry: {%u}}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID);
|
||||
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID);
|
||||
if (enforceDBCAttributes)
|
||||
itemTemplate.DisplayInfoID = dbcitem->DisplayInfoID;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPackets::LFG::LFGJoin& packet)
|
||||
|
||||
if (packet.Slots.empty())
|
||||
{
|
||||
LOG_DEBUG("lfg", "CMSG_LFG_JOIN {} no dungeons selected", GetPlayerInfo().c_str());
|
||||
LOG_DEBUG("lfg", "CMSG_LFG_JOIN {} no dungeons selected", GetPlayerInfo());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -953,21 +953,21 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPackets::Pet::PetSpellAutoc
|
||||
Creature* checkPet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.PetGUID);
|
||||
if (!checkPet)
|
||||
{
|
||||
LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: Pet {} not found.", packet.PetGUID.ToString().c_str());
|
||||
LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: Pet {} not found.", packet.PetGUID.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.SpellID);
|
||||
if (!spellInfo)
|
||||
{
|
||||
LOG_ERROR("spells.pet", "WorldSession::HandlePetSpellAutocastOpcode: Unknown spell id {} used by {}.", packet.SpellID, packet.PetGUID.ToString().c_str());
|
||||
LOG_ERROR("spells.pet", "WorldSession::HandlePetSpellAutocastOpcode: Unknown spell id {} used by {}.", packet.SpellID, packet.PetGUID.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkPet != _player->GetGuardianPet() && checkPet != _player->GetCharm())
|
||||
{
|
||||
LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: {} isn't pet of player {} ({}).",
|
||||
packet.PetGUID.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str());
|
||||
packet.PetGUID.ToString(), GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
bool HasQuestDrop(LootTemplateMap const& store) const; // True if group includes at least 1 quest drop entry
|
||||
bool HasQuestDropForPlayer(Player const* player, LootTemplateMap const& store) const;
|
||||
// The same for active quests of the player
|
||||
void Process(Loot& loot, Player const* player, LootStore const& lootstore, uint16 lootMode) const; // Rolls an item from the group (if any) and adds the item to the loot
|
||||
void Process(Loot& loot, Player const* player, LootStore const& lootstore, uint16 lootMode, uint16 nonRefIterationsLeft) const; // Rolls an item from the group (if any) and adds the item to the loot
|
||||
float RawTotalChance() const; // Overall chance for the group (without equal chanced items)
|
||||
float TotalChance() const; // Overall chance for the group
|
||||
|
||||
@@ -570,7 +570,8 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo
|
||||
items.reserve(MAX_NR_LOOT_ITEMS);
|
||||
quest_items.reserve(MAX_NR_QUEST_ITEMS);
|
||||
|
||||
tab->Process(*this, store, lootMode, lootOwner); // Processing is done there, callback via Loot::AddItem()
|
||||
// Initial group is 0, top level set to True
|
||||
tab->Process(*this, store, lootMode, lootOwner, 0, true); // Processing is done there, callback via Loot::AddItem()
|
||||
|
||||
sScriptMgr->OnAfterLootTemplateProcess(this, tab, store, lootOwner, personal, noEmptyError, lootMode);
|
||||
|
||||
@@ -1413,7 +1414,7 @@ void LootTemplate::LootGroup::CopyConditions(ConditionList /*conditions*/)
|
||||
}
|
||||
|
||||
// Rolls an item from the group (if any takes its chance) and adds the item to the loot
|
||||
void LootTemplate::LootGroup::Process(Loot& loot, Player const* player, LootStore const& store, uint16 lootMode) const
|
||||
void LootTemplate::LootGroup::Process(Loot& loot, Player const* player, LootStore const& store, uint16 lootMode, uint16 nonRefIterationsLeft) const
|
||||
{
|
||||
if (LootStoreItem const* item = Roll(loot, player, store, lootMode))
|
||||
{
|
||||
@@ -1426,7 +1427,9 @@ void LootTemplate::LootGroup::Process(Loot& loot, Player const* player, LootStor
|
||||
uint32 maxcount = uint32(float(item->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT));
|
||||
sScriptMgr->OnAfterRefCount(player, loot, rate, lootMode, const_cast<LootStoreItem*>(item), maxcount, store);
|
||||
for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator
|
||||
Referenced->Process(loot, store, lootMode, player, item->groupid);
|
||||
// This reference needs to be processed further, but it is marked isTopLevel=false so that any groups inside
|
||||
// the reference are not multiplied by Rate.Drop.Item.GroupAmount
|
||||
Referenced->Process(loot, store, lootMode, player, item->groupid, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1434,6 +1437,14 @@ void LootTemplate::LootGroup::Process(Loot& loot, Player const* player, LootStor
|
||||
// Plain entries (not a reference, not grouped)
|
||||
sScriptMgr->OnBeforeDropAddItem(player, loot, rate, lootMode, const_cast<LootStoreItem*>(item), store);
|
||||
loot.AddItem(*item); // Chance is already checked, just add
|
||||
|
||||
// If we still have non-ref runs to do for this group AND this item wasn't a reference,
|
||||
// recursively call this function to produce more items for this group.
|
||||
// However, if this is a quest item we shouldn't multiply this group.
|
||||
if (nonRefIterationsLeft > 1 && !item->needs_quest)
|
||||
{
|
||||
this->Process(loot, player, store, lootMode, nonRefIterationsLeft-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1665,7 +1676,7 @@ bool LootTemplate::CopyConditions(LootItem* li, uint32 conditionLootId) const
|
||||
}
|
||||
|
||||
// Rolls for every item in the template and adds the rolled items the the loot
|
||||
void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode, Player const* player, uint8 groupId) const
|
||||
void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode, Player const* player, uint8 groupId, bool isTopLevel) const
|
||||
{
|
||||
bool rate = store.IsRatesAllowed();
|
||||
|
||||
@@ -1677,7 +1688,15 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode,
|
||||
if (!Groups[groupId - 1])
|
||||
return;
|
||||
|
||||
Groups[groupId - 1]->Process(loot, player, store, lootMode);
|
||||
// Rate.Drop.Item.GroupAmount is only in effect for the top loot template level
|
||||
if (isTopLevel)
|
||||
{
|
||||
Groups[groupId - 1]->Process(loot, player, store, lootMode, sWorld->getRate(RATE_DROP_ITEM_GROUP_AMOUNT));
|
||||
}
|
||||
else
|
||||
{
|
||||
Groups[groupId - 1]->Process(loot, player, store, lootMode, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1687,7 +1706,6 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode,
|
||||
LootStoreItem* item = *i;
|
||||
if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
|
||||
continue;
|
||||
|
||||
if (!item->Roll(rate, player, loot, store))
|
||||
continue; // Bad luck for the entry
|
||||
|
||||
@@ -1700,7 +1718,8 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode,
|
||||
uint32 maxcount = uint32(float(item->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT));
|
||||
sScriptMgr->OnAfterRefCount(player, loot, rate, lootMode, item, maxcount, store);
|
||||
for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator
|
||||
Referenced->Process(loot, store, lootMode, player, item->groupid);
|
||||
// we're no longer in the top level, so isTopLevel is false
|
||||
Referenced->Process(loot, store, lootMode, player, item->groupid, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1713,7 +1732,17 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint16 lootMode,
|
||||
// Now processing groups
|
||||
for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
|
||||
if (LootGroup* group = *i)
|
||||
group->Process(loot, player, store, lootMode);
|
||||
{
|
||||
// Rate.Drop.Item.GroupAmount is only in effect for the top loot template level
|
||||
if (isTopLevel)
|
||||
{
|
||||
group->Process(loot, player, store, lootMode, sWorld->getRate(RATE_DROP_ITEM_GROUP_AMOUNT));
|
||||
}
|
||||
else
|
||||
{
|
||||
group->Process(loot, player, store, lootMode, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// True if template includes at least 1 quest drop entry
|
||||
|
||||
@@ -253,7 +253,7 @@ public:
|
||||
// Adds an entry to the group (at loading stage)
|
||||
void AddEntry(LootStoreItem* item);
|
||||
// Rolls for every item in the template and adds the rolled items the the loot
|
||||
void Process(Loot& loot, LootStore const& store, uint16 lootMode, Player const* player, uint8 groupId = 0) const;
|
||||
void Process(Loot& loot, LootStore const& store, uint16 lootMode, Player const* player, uint8 groupId = 0, bool isTopLevel = true) const;
|
||||
void CopyConditions(ConditionList conditions);
|
||||
bool CopyConditions(LootItem* li, uint32 conditionLootId = 0) const;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class Item;
|
||||
class Object;
|
||||
class Player;
|
||||
|
||||
#define MAIL_BODY_ITEM_TEMPLATE 8383 // - plain letter, A Dusty Unsent Letter: 889
|
||||
#define MAIL_BODY_ITEM_TEMPLATE 9311 // - plain letter, A Dusty Unsent Letter: 889
|
||||
#define MAX_MAIL_ITEMS 12
|
||||
|
||||
enum MailMessageType
|
||||
|
||||
@@ -375,7 +375,7 @@ void FlightPathMovementGenerator::DoReset(Player* player)
|
||||
|
||||
if (currentNodeId == end)
|
||||
{
|
||||
LOG_DEBUG("movement.flightpath", "FlightPathMovementGenerator::DoReset: trying to start a flypath from the end point. {}", player->GetGUID().ToString().c_str());
|
||||
LOG_DEBUG("movement.flightpath", "FlightPathMovementGenerator::DoReset: trying to start a flypath from the end point. {}", player->GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/)
|
||||
bool departureEvent = true;
|
||||
do
|
||||
{
|
||||
ASSERT(i_currentNode < i_path.size(), "Point Id: {}\n{}", pointId, player->GetGUID().ToString().c_str());
|
||||
ASSERT(i_currentNode < i_path.size(), "Point Id: {}\n{}", pointId, player->GetGUID().ToString());
|
||||
|
||||
DoEventIfAny(player, i_path[i_currentNode], departureEvent);
|
||||
while (!_pointsForPathSwitch.empty() && _pointsForPathSwitch.front().PathIndex <= i_currentNode)
|
||||
@@ -460,7 +460,7 @@ void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry
|
||||
{
|
||||
if (uint32 eventid = departure ? node->departureEventID : node->arrivalEventID)
|
||||
{
|
||||
LOG_DEBUG("maps.script", "Taxi {} event {} of node {} of path {} for player {}", departure ? "departure" : "arrival", eventid, node->index, node->path, player->GetName().c_str());
|
||||
LOG_DEBUG("maps.script", "Taxi {} event {} of node {} of path {} for player {}", departure ? "departure" : "arrival", eventid, node->index, node->path, player->GetName());
|
||||
player->GetMap()->ScriptsStart(sEventScripts, eventid, player, player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,9 +113,9 @@ inline Player* Map::_GetScriptPlayerSourceOrTarget(Object* source, Object* targe
|
||||
|
||||
if (!player)
|
||||
LOG_ERROR("maps.script", "{} neither source nor target object is player (source: TypeId: {}, Entry: {}, GUID: {}; target: TypeId: {}, Entry: {}, GUID: {}), skipping.",
|
||||
scriptInfo->GetDebugInfo().c_str(),
|
||||
source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUID().ToString().c_str() : "",
|
||||
target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUID().ToString().c_str() : "");
|
||||
scriptInfo->GetDebugInfo(),
|
||||
source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUID().ToString() : "",
|
||||
target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUID().ToString() : "");
|
||||
}
|
||||
return player;
|
||||
}
|
||||
@@ -146,9 +146,9 @@ inline Creature* Map::_GetScriptCreatureSourceOrTarget(Object* source, Object* t
|
||||
|
||||
if (!creature)
|
||||
LOG_ERROR("maps.script", "{} neither source nor target are creatures (source: TypeId: {}, Entry: {}, GUID: {}; target: TypeId: {}, Entry: {}, GUID: {}), skipping.",
|
||||
scriptInfo->GetDebugInfo().c_str(),
|
||||
source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUID().ToString().c_str() : "",
|
||||
target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUID().ToString().c_str() : "");
|
||||
scriptInfo->GetDebugInfo(),
|
||||
source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUID().ToString() : "",
|
||||
target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUID().ToString() : "");
|
||||
}
|
||||
return creature;
|
||||
}
|
||||
@@ -533,7 +533,7 @@ void Map::ScriptsProcess()
|
||||
else
|
||||
{
|
||||
LOG_ERROR("maps.script", "{} neither source nor target is player (source: {}; target: {}), skipping.",
|
||||
step.script->GetDebugInfo().c_str(), source->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str());
|
||||
step.script->GetDebugInfo(), source->GetGUID().ToString(), target->GetGUID().ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,11 +154,11 @@ void ScriptMgr::OnBeforeLootMoney(Player* player, Loot* loot)
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim)
|
||||
void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource)
|
||||
{
|
||||
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||
{
|
||||
script->OnGiveXP(player, amount, victim);
|
||||
script->OnGiveXP(player, amount, victim, xpSource);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ void ScriptMgr::CheckIfScriptsInDatabaseExist()
|
||||
{
|
||||
for (auto const& scriptName : sObjectMgr->GetScriptNames())
|
||||
{
|
||||
if (uint32 sid = sObjectMgr->GetScriptId(scriptName.c_str()))
|
||||
if (uint32 sid = sObjectMgr->GetScriptId(scriptName))
|
||||
{
|
||||
if (!ScriptRegistry<SpellScriptLoader>::GetScriptById(sid) &&
|
||||
!ScriptRegistry<ServerScript>::GetScriptById(sid) &&
|
||||
|
||||
@@ -1037,7 +1037,7 @@ public:
|
||||
virtual void OnBeforeLootMoney(Player* /*player*/, Loot* /*loot*/) {}
|
||||
|
||||
// Called when a player gains XP (before anything is given)
|
||||
virtual void OnGiveXP(Player* /*player*/, uint32& /*amount*/, Unit* /*victim*/) { }
|
||||
virtual void OnGiveXP(Player* /*player*/, uint32& /*amount*/, Unit* /*victim*/, uint8 /*xpSource*/) { }
|
||||
|
||||
// Called when a player's reputation changes (before it is actually changed)
|
||||
virtual bool OnReputationChange(Player* /*player*/, uint32 /*factionID*/, int32& /*standing*/, bool /*incremental*/) { return true; }
|
||||
@@ -2281,7 +2281,7 @@ public: /* PlayerScript */
|
||||
void OnPlayerTalentsReset(Player* player, bool noCost);
|
||||
void OnPlayerMoneyChanged(Player* player, int32& amount);
|
||||
void OnBeforeLootMoney(Player* player, Loot* loot);
|
||||
void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim);
|
||||
void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource);
|
||||
bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental);
|
||||
void OnPlayerReputationRankChange(Player* player, uint32 factionID, ReputationRank newRank, ReputationRank oldRank, bool increased);
|
||||
void OnPlayerLearnSpell(Player* player, uint32 spellID);
|
||||
|
||||
@@ -6387,7 +6387,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
|
||||
SpellPeriodicAuraLogInfo pInfo(this, damage, overkill, absorb, resist, 0.0f, crit);
|
||||
target->SendPeriodicAuraLog(&pInfo);
|
||||
|
||||
Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true, false);
|
||||
Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
|
||||
|
||||
Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo);
|
||||
}
|
||||
|
||||
@@ -3430,19 +3430,13 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
// Seal of Command Unleashed
|
||||
if (m_spellInfo->Id == 20467)
|
||||
{
|
||||
spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
|
||||
spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()));
|
||||
}
|
||||
|
||||
switch (m_spellInfo->Id)
|
||||
{
|
||||
case 20424: // Seal of Command
|
||||
case 42463: // Seal of Vengeance
|
||||
case 53739: // Seal of Corruption
|
||||
case 53385: // Divine Storm
|
||||
case 20467: // Seal of Command Unleashed
|
||||
spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
|
||||
spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()));
|
||||
break;
|
||||
case 53385: // Divine Storm deals normalized damage
|
||||
normalized = true;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -2104,6 +2104,7 @@ AuraStateType SpellInfo::LoadAuraState() const
|
||||
case 35331: // Black Blood
|
||||
case 9806: // Phantom Strike
|
||||
case 35325: // Glowing Blood
|
||||
case 35328: // Lambent Blood
|
||||
case 16498: // Faerie Fire
|
||||
case 6950:
|
||||
case 20656:
|
||||
|
||||
@@ -213,6 +213,15 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->MaxAffectedTargets = 4;
|
||||
});
|
||||
|
||||
ApplySpellFix({
|
||||
20424, // Seal of Command
|
||||
42463, // Seal of Vengeance
|
||||
53739 // Seal of Corruption
|
||||
}, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
|
||||
});
|
||||
|
||||
// Spitfire Totem
|
||||
ApplySpellFix({ 38296 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
@@ -4500,6 +4509,31 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
|
||||
});
|
||||
|
||||
// Absorb Life
|
||||
ApplySpellFix({ 34239 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].ValueMultiplier = 1;
|
||||
});
|
||||
|
||||
// Summon a Warp Rift in Void Ridge
|
||||
ApplySpellFix({ 35036 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(1); // 0s
|
||||
});
|
||||
|
||||
// Hit Rating (Dungeon T3 - 2P Bonus - Wastewalker, Doomplate)
|
||||
ApplySpellFix({ 37608, 37610 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(0);
|
||||
spellInfo->Effects[EFFECT_0].MiscValue = 224;
|
||||
});
|
||||
|
||||
// Target Fissures
|
||||
ApplySpellFix({ 30745 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->MaxAffectedTargets = 1;
|
||||
});
|
||||
|
||||
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
|
||||
{
|
||||
SpellInfo* spellInfo = mSpellInfoMap[i];
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "IWorld.h"
|
||||
|
||||
class Unit;
|
||||
class IWorld;
|
||||
|
||||
void IWorld::AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss)
|
||||
{
|
||||
DelayedDamage delayedDamage;
|
||||
delayedDamage.attacker = attacker;
|
||||
delayedDamage.victim = victim;
|
||||
delayedDamage.damage = damage;
|
||||
delayedDamage.cleanDamage = cleanDamage;
|
||||
delayedDamage.damagetype = damagetype;
|
||||
delayedDamage.damageSchoolMask = damageSchoolMask;
|
||||
delayedDamage.spellProto = spellProto;
|
||||
delayedDamage.durabilityLoss = durabilityLoss;
|
||||
_delayedDamages.push_back(delayedDamage);
|
||||
}
|
||||
@@ -24,17 +24,15 @@
|
||||
#include "ObjectGuid.h"
|
||||
#include "QueryResult.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Unit.h"
|
||||
#include <atomic>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
class IWorld;
|
||||
class Player;
|
||||
class WorldPacket;
|
||||
class WorldSession;
|
||||
class Player;
|
||||
|
||||
/// Storage class for commands issued for delayed execution
|
||||
struct AC_GAME_API CliCommandHolder
|
||||
@@ -438,8 +436,8 @@ enum Rates
|
||||
RATE_DROP_ITEM_LEGENDARY,
|
||||
RATE_DROP_ITEM_ARTIFACT,
|
||||
RATE_DROP_ITEM_REFERENCED,
|
||||
|
||||
RATE_DROP_ITEM_REFERENCED_AMOUNT,
|
||||
RATE_DROP_ITEM_GROUP_AMOUNT,
|
||||
RATE_SELLVALUE_ITEM_POOR,
|
||||
RATE_SELLVALUE_ITEM_NORMAL,
|
||||
RATE_SELLVALUE_ITEM_UNCOMMON,
|
||||
@@ -518,13 +516,10 @@ enum Rates
|
||||
class IWorld
|
||||
{
|
||||
public:
|
||||
std::list<DelayedDamage> _delayedDamages;
|
||||
|
||||
virtual ~IWorld() = default;
|
||||
[[nodiscard]] virtual WorldSession* FindSession(uint32 id) const = 0;
|
||||
[[nodiscard]] virtual WorldSession* FindOfflineSession(uint32 id) const = 0;
|
||||
[[nodiscard]] virtual WorldSession* FindOfflineSessionForCharacterGUID(ObjectGuid::LowType guidLow) const = 0;
|
||||
virtual void AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss);
|
||||
virtual void AddSession(WorldSession* s) = 0;
|
||||
virtual bool KickSession(uint32 id) = 0;
|
||||
virtual void UpdateMaxSessionCounters() = 0;
|
||||
|
||||
@@ -493,7 +493,9 @@ void World::LoadConfigSettings(bool reload)
|
||||
_rate_values[RATE_DROP_ITEM_ARTIFACT] = sConfigMgr->GetOption<float>("Rate.Drop.Item.Artifact", 1.0f);
|
||||
_rate_values[RATE_DROP_ITEM_REFERENCED] = sConfigMgr->GetOption<float>("Rate.Drop.Item.Referenced", 1.0f);
|
||||
_rate_values[RATE_DROP_ITEM_REFERENCED_AMOUNT] = sConfigMgr->GetOption<float>("Rate.Drop.Item.ReferencedAmount", 1.0f);
|
||||
_rate_values[RATE_DROP_ITEM_GROUP_AMOUNT] = sConfigMgr->GetOption<float>("Rate.Drop.Item.GroupAmount", 1.0f);
|
||||
_rate_values[RATE_DROP_MONEY] = sConfigMgr->GetOption<float>("Rate.Drop.Money", 1.0f);
|
||||
|
||||
_rate_values[RATE_REWARD_BONUS_MONEY] = sConfigMgr->GetOption<float>("Rate.RewardBonusMoney", 1.0f);
|
||||
_rate_values[RATE_XP_KILL] = sConfigMgr->GetOption<float>("Rate.XP.Kill", 1.0f);
|
||||
_rate_values[RATE_XP_BG_KILL_AV] = sConfigMgr->GetOption<float>("Rate.XP.BattlegroundKillAV", 1.0f);
|
||||
@@ -2065,8 +2067,6 @@ void World::SetInitialWorldSettings()
|
||||
|
||||
_mail_expire_check_timer = GameTime::GetGameTime() + 6h;
|
||||
|
||||
_timers[WUPDATE_DELAYED_DAMAGES].SetInterval(400);
|
||||
|
||||
///- Initialize MapMgr
|
||||
LOG_INFO("server.loading", "Starting Map System");
|
||||
LOG_INFO("server.loading", " ");
|
||||
@@ -2313,12 +2313,6 @@ void World::Update(uint32 diff)
|
||||
{
|
||||
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Check quest reset times"));
|
||||
|
||||
if (_timers[WUPDATE_DELAYED_DAMAGES].Passed())
|
||||
{
|
||||
_timers[WUPDATE_DELAYED_DAMAGES].Reset();
|
||||
ProcessDelayedDamages();
|
||||
}
|
||||
|
||||
/// Handle daily quests reset time
|
||||
if (currentGameTime > _nextDailyQuestReset)
|
||||
{
|
||||
@@ -3351,24 +3345,3 @@ CliCommandHolder::~CliCommandHolder()
|
||||
{
|
||||
free(m_command);
|
||||
}
|
||||
|
||||
void World::AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss)
|
||||
{
|
||||
DelayedDamage delayedDamage;
|
||||
delayedDamage.attacker = attacker;
|
||||
delayedDamage.victim = victim;
|
||||
delayedDamage.damage = damage;
|
||||
delayedDamage.cleanDamage = cleanDamage;
|
||||
delayedDamage.damagetype = damagetype;
|
||||
delayedDamage.damageSchoolMask = damageSchoolMask;
|
||||
delayedDamage.spellProto = spellProto;
|
||||
delayedDamage.durabilityLoss = durabilityLoss;
|
||||
_delayedDamages.push_back(delayedDamage);
|
||||
}
|
||||
|
||||
void World::ProcessDelayedDamages()
|
||||
{
|
||||
for (auto& damage : _delayedDamages)
|
||||
Unit::DealDamage(damage.attacker, damage.victim, damage.damage, damage.cleanDamage, damage.damagetype, damage.damageSchoolMask, damage.spellProto, damage.durabilityLoss);
|
||||
_delayedDamages.clear();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "QueryResult.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Timer.h"
|
||||
#include "Unit.h"
|
||||
#include <atomic>
|
||||
#include <list>
|
||||
#include <map>
|
||||
@@ -71,7 +70,6 @@ enum WorldTimers
|
||||
WUPDATE_PINGDB,
|
||||
WUPDATE_5_SECS,
|
||||
WUPDATE_WHO_LIST,
|
||||
WUPDATE_DELAYED_DAMAGES,
|
||||
WUPDATE_COUNT
|
||||
};
|
||||
|
||||
@@ -155,8 +153,6 @@ public:
|
||||
World();
|
||||
~World() override;
|
||||
|
||||
std::list<DelayedDamage> _delayedDamages;
|
||||
|
||||
static World* instance();
|
||||
|
||||
static uint32 m_worldLoopCounter;
|
||||
@@ -357,10 +353,6 @@ public:
|
||||
|
||||
void RemoveOldCorpses() override;
|
||||
|
||||
void AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss) override;
|
||||
|
||||
void ProcessDelayedDamages();
|
||||
|
||||
protected:
|
||||
void _UpdateGameTime();
|
||||
// callback for UpdateRealmCharacters
|
||||
|
||||
Reference in New Issue
Block a user