Cmangos commits applied

Cmangos commits applied
This commit is contained in:
Charles A Edwards 2016-09-14 13:21:23 +01:00 committed by Antz
parent df3ab5df8e
commit 068c67b932
12 changed files with 261 additions and 138 deletions

View file

@ -987,7 +987,7 @@ bool ChatHandler::HandleModifyTalentCommand(char* args)
else if (((Creature*)target)->IsPet())
{
Unit* owner = target->GetOwner();
if (owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet*)target)->IsPermanentPetFor((Player*)owner))
if (owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet*)target)->isControlled())
{
// check online security
if (HasLowerSecurity((Player*)owner))

View file

@ -5281,7 +5281,7 @@ bool ChatHandler::HandleResetTalentsCommand(char* args)
if (!*args && creature && creature->IsPet())
{
Unit* owner = creature->GetOwner();
if (owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet*)creature)->IsPermanentPetFor((Player*)owner))
if (owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet*)creature)->isControlled())
{
((Pet*)creature)->resetTalents(true);
((Player*)owner)->SendTalentsInfoData(true);

View file

@ -190,7 +190,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c
return true;
}
m_charmInfo->SetPetNumber(pet_number, IsPermanentPetFor(owner));
m_charmInfo->SetPetNumber(pet_number, isControlled());
SetOwnerGuid(owner->GetObjectGuid());
SetDisplayId(fields[3].GetUInt32());
@ -722,6 +722,8 @@ void Pet::GivePetXP(uint32 xp)
if (level >= maxlevel)
return;
xp *= sWorld.getConfig(CONFIG_FLOAT_RATE_PET_XP_KILL);
uint32 nextLvlXP = GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP);
uint32 curXP = GetUInt32Value(UNIT_FIELD_PETEXPERIENCE);
uint32 newXP = curXP + xp;
@ -1914,29 +1916,6 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
}
}
bool Pet::IsPermanentPetFor(Player* owner)
{
switch (getPetType())
{
case SUMMON_PET:
switch (owner->getClass())
{
// oddly enough, Mage's Water Elemental is still treated as temporary pet with Glyph of Eternal Water
// i.e. does not unsummon at mounting, gets dismissed at teleport etc.
case CLASS_WARLOCK:
return GetCreatureInfo()->CreatureType == CREATURE_TYPE_DEMON;
case CLASS_DEATH_KNIGHT:
return GetCreatureInfo()->CreatureType == CREATURE_TYPE_UNDEAD;
default:
return false;
}
case HUNTER_PET:
return true;
default:
return false;
}
}
bool Pet::Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, uint32 pet_number)
{
SetMap(cPos.GetMap());
@ -1989,10 +1968,11 @@ void Pet::LearnPetPassives()
void Pet::CastPetAuras(bool current)
{
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
if (!isControlled())
return;
Unit* owner = GetOwner();
for (PetAuraSet::const_iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end();)
{
PetAura const* pa = *itr;

View file

@ -56,12 +56,17 @@ enum PetSaveMode
// There might be a lot more
enum PetModeFlags
{
PET_MODE_UNKNOWN_0 = 0x0000001,
PET_MODE_UNKNOWN_2 = 0x0000100,
PET_MODE_STAY = 0x0000000,
PET_MODE_FOLLOW = 0x0000001,
PET_MODE_ATTACK = 0x0000002,
PET_MODE_PASSIVE = 0x0000000,
PET_MODE_DEFENSIVE = 0x0000100,
PET_MODE_AGGRESSIVE = 0x0000200,
PET_MODE_DISABLE_ACTIONS = 0x8000000,
// autoset in client at summon
PET_MODE_DEFAULT = PET_MODE_UNKNOWN_0 | PET_MODE_UNKNOWN_2,
PET_MODE_DEFAULT = PET_MODE_FOLLOW | PET_MODE_DEFENSIVE,
};
enum PetSpellState
@ -146,9 +151,7 @@ class Pet : public Creature
void setPetType(PetType type) { m_petType = type; }
bool isControlled() const { return getPetType() == SUMMON_PET || getPetType() == HUNTER_PET; }
bool isTemporarySummoned() const { return m_duration > 0; }
bool IsPermanentPetFor(Player* owner); // pet have tab in character windows and set UNIT_FIELD_PETNUMBER
bool Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, uint32 pet_number);
bool CreateBaseAtCreature(Creature* creature);
bool LoadPetFromDB(Player* owner, uint32 petentry = 0, uint32 petnumber = 0, bool current = false);

View file

@ -128,6 +128,15 @@ void PetAI::UpdateAI(const uint32 diff)
return;
Unit* owner = m_creature->GetCharmerOrOwner();
Unit* victim = nullptr;
if (!((Pet*)m_creature)->isControlled())
m_creature->SelectHostileTarget();
// Creature pets and guardians will always look in threat list for victim
if (!(m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)
|| (m_creature->IsPet() && ((Pet*)m_creature)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)))
victim = m_creature->getVictim();
if (m_updateAlliesTimer <= diff)
// UpdateAllies self set update timer
@ -135,62 +144,68 @@ void PetAI::UpdateAI(const uint32 diff)
else
m_updateAlliesTimer -= diff;
if (inCombat && (!m_creature->getVictim() || (m_creature->IsPet() && ((Pet*)m_creature)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)))
_stopAttack();
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
if (m_creature->getVictim())
if (inCombat && !victim)
{
if (_needToStop())
{
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "PetAI (guid = %u) is stopping attack.", m_creature->GetGUIDLow());
_stopAttack();
return;
}
bool meleeReach = m_creature->CanReachWithMeleeAttack(m_creature->getVictim());
if (m_creature->IsStopped() || meleeReach)
{
// required to be stopped cases
if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
{
if (m_creature->hasUnitState(UNIT_STAT_FOLLOW_MOVE))
m_creature->InterruptNonMeleeSpells(false);
else
return;
}
// not required to be stopped case
else if (DoMeleeAttackIfReady())
{
if (!m_creature->getVictim())
return;
// if pet misses its target, it will also be the first in threat list
m_creature->getVictim()->AddThreat(m_creature);
if (_needToStop())
_stopAttack();
}
}
m_creature->AttackStop(true);
inCombat = false;
}
else if (owner && m_creature->GetCharmInfo())
if (((Pet*)m_creature)->GetIsRetreating())
{
if (owner->IsInCombat() && !(m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) || m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY)))
{
AttackStart(owner->getAttackerForHelper());
}
else if (m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
if (!owner->IsWithinDistInMap(m_creature, (PET_FOLLOW_DIST * 2)))
{
if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW))
{
m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
}
}
}
return;
}
else
((Pet*)m_creature)->SetIsRetreating();
}
else if (((Pet*)m_creature)->GetSpellOpener() != 0) // have opener stored
{
uint32 minRange = ((Pet*)m_creature)->GetSpellOpenerMinRange();
if (!(victim = m_creature->getVictim())
|| (minRange != 0 && m_creature->IsWithinDistInMap(victim, minRange)))
((Pet*)m_creature)->SetSpellOpener();
else if (m_creature->IsWithinDistInMap(victim, ((Pet*)m_creature)->GetSpellOpenerMaxRange())
&& m_creature->IsWithinLOSInMap(victim))
{
// stop moving
m_creature->clearUnitState(UNIT_STAT_MOVING);
// auto turn to target
m_creature->SetInFront(victim);
if (victim->GetTypeId() == TYPEID_PLAYER)
m_creature->SendCreateUpdateToPlayer((Player*)victim);
if (owner->GetTypeId() == TYPEID_PLAYER)
m_creature->SendCreateUpdateToPlayer((Player*)owner);
uint32 spell_id = ((Pet*)m_creature)->GetSpellOpener();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id);
Spell* spell = new Spell(m_creature, spellInfo, false);
SpellCastResult result = spell->CheckPetCast(victim);
if (result == SPELL_CAST_OK)
{
m_creature->AddCreatureSpellCooldown(spell_id);
spell->SpellStart(&(spell->m_targets));
}
else
delete spell;
((Pet*)m_creature)->SetSpellOpener();
}
else
return;
}
// Autocast (casted only in combat or persistent spells in any state)
if (!m_creature->IsNonMeleeSpellCasted(false))
else if (!m_creature->IsNonMeleeSpellCasted(false))
{
typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
@ -220,7 +235,6 @@ void PetAI::UpdateAI(const uint32 diff)
// Consume Shadows, Lesser Invisibility, so ignore checks for its
if (!IsNonCombatSpell(spellInfo))
{
// allow only spell without spell cost or with spell cost but not duration limit
int32 duration = GetSpellDuration(spellInfo);
SpellPowerEntry const* spellPower = spellInfo->GetSpellPower();
if (spellPower && (spellPower->manaCost || spellPower->ManaCostPercentage || spellPower->manaPerSecond) && duration > 0)
@ -228,22 +242,21 @@ void PetAI::UpdateAI(const uint32 diff)
// allow only spell without cooldown > duration
int32 cooldown = GetSpellRecoveryTime(spellInfo);
if (cooldown >= 0 && duration >= 0 && cooldown > duration)
// allow only spell not on cooldown
if (cooldown != 0 && duration < cooldown)
continue;
}
}
else
{
// just ignore non-combat spells
if (IsNonCombatSpell(spellInfo))
continue;
}
// just ignore non-combat spells
else if (IsNonCombatSpell(spellInfo))
continue;
Spell* spell = new Spell(m_creature, spellInfo, false);
if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(victim))
{
targetSpellStore.push_back(TargetSpellList::value_type(m_creature->getVictim(), spell));
targetSpellStore.push_back(TargetSpellList::value_type(victim, spell));
continue;
}
else
@ -301,6 +314,105 @@ void PetAI::UpdateAI(const uint32 diff)
for (TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr)
delete itr->second;
}
// Guardians will always look in threat list for victim
if (!((Pet*)m_creature)->isControlled())
m_creature->SelectHostileTarget();
if (!(m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)
|| (m_creature->IsPet() && ((Pet*)m_creature)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)))
victim = m_creature->getVictim();
// Stop here if casting spell (No melee and no movement)
if (m_creature->IsNonMeleeSpellCasted(false))
return;
if (victim)
{
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
// This is needed for charmed creatures, as once their target was reset other effects can trigger threat
if ((m_creature->IsCharmed() && victim == m_creature->GetCharmer()) || !victim->IsTargetableForAttack())
{
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "PetAI (guid = %u) is stopping attack.", m_creature->GetGUIDLow());
m_creature->CombatStop();
inCombat = false;
return;
}
// if pet misses its target, it will also be the first in threat list
if (!(m_creature->GetCreatureInfo()->ExtraFlags & CREATURE_EXTRA_FLAG_NO_MELEE)
&& m_creature->CanReachWithMeleeAttack(victim))
{
if (!m_creature->HasInArc(2 * M_PI_F / 3, victim))
{
m_creature->SetInFront(victim);
if (victim->GetTypeId() == TYPEID_PLAYER)
m_creature->SendCreateUpdateToPlayer((Player*)victim);
if (owner && owner->GetTypeId() == TYPEID_PLAYER)
m_creature->SendCreateUpdateToPlayer((Player*)owner);
}
if (DoMeleeAttackIfReady())
victim->AddThreat(m_creature);
}
else if (!(m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)
|| m_creature->hasUnitState(UNIT_STAT_MOVING)))
AttackStart(victim);
}
else if (owner)
{
CharmInfo* charmInfo = m_creature->GetCharmInfo();
if (owner->IsInCombat() && !(m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)
|| (charmInfo && charmInfo->HasReactState(REACT_PASSIVE))))
AttackStart(owner->getAttackerForHelper());
else if (!m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
{
if (charmInfo && charmInfo->HasCommandState(COMMAND_STAY))
{
if (Pet* pet = (Pet*)m_creature)
{
//if stay command is set but we dont have stay pos set then we need to establish current pos as stay position
if (!pet->IsStayPosSet())
pet->SetStayPosition(true);
float stayPosX = pet->GetStayPosX();
float stayPosY = pet->GetStayPosY();
float stayPosZ = pet->GetStayPosZ();
if (m_creature->GetPositionX() == stayPosX
&& m_creature->GetPositionY() == stayPosY
&& m_creature->GetPositionZ() == stayPosZ)
{
float StayPosO = pet->GetStayPosO();
if (m_creature->hasUnitState(UNIT_STAT_MOVING))
{
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
}
else if (m_creature->GetOrientation() != StayPosO)
m_creature->SetOrientation(StayPosO);
}
else
pet->GetMotionMaster()->MovePoint(0, stayPosX, stayPosY, stayPosZ, false);
}
}
else if (m_creature->hasUnitState(UNIT_STAT_FOLLOW))
{
if (owner->IsWithinDistInMap(m_creature, PET_FOLLOW_DIST))
{
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
}
}
else if (charmInfo && charmInfo->HasCommandState(COMMAND_FOLLOW)
&& !owner->IsWithinDistInMap(m_creature, (PET_FOLLOW_DIST * 2)))
m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
}
}
}
bool PetAI::_isVisible(Unit* u) const
@ -350,8 +462,9 @@ void PetAI::UpdateAllies()
void PetAI::AttackedBy(Unit* attacker)
{
// when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway
if (!m_creature->getVictim() && m_creature->GetCharmInfo() && !m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
(!m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY) || m_creature->CanReachWithMeleeAttack(attacker)))
// when attacked, fight back if no victim unless we have a charm state set to passive
if (!(m_creature->getVictim() || ((Pet*)m_creature)->GetIsRetreating() == true)
&& !(m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)
|| (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE))))
AttackStart(attacker);
}

View file

@ -18416,7 +18416,7 @@ void Player::PetSpellInitialize()
uint8 addlist = 0;
data << uint8(addlist); // placeholder
if (pet->IsPermanentPetFor(this))
if (pet->isControlled())
{
// spells loop
for (PetSpellMap::const_iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)
@ -21328,7 +21328,7 @@ struct UpdateZoneDependentPetsHelper
explicit UpdateZoneDependentPetsHelper(Player* _owner, uint32 zone, uint32 area) : owner(_owner), zone_id(zone), area_id(area) {}
void operator()(Unit* unit) const
{
if (unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->IsPet() && !((Pet*)unit)->IsPermanentPetFor(owner))
if (unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->IsPet() && !((Pet*)unit)->isControlled())
if (uint32 spell_id = unit->GetUInt32Value(UNIT_CREATED_BY_SPELL))
if (SpellEntry const* spellEntry = sSpellStore.LookupEntry(spell_id))
if (sSpellMgr.GetSpellAllowedInLocationError(spellEntry, owner->GetMapId(), zone_id, area_id, owner) != SPELL_CAST_OK)

View file

@ -251,6 +251,10 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recv_data)
if (!s_show)
continue;
// 49 is maximum player count sent to client
if (++matchcount > 49)
continue;
++displaycount;
data << pname; // player name

View file

@ -95,17 +95,27 @@ void WorldSession::HandlePetAction(WorldPacket& recv_data)
switch (spellid)
{
case COMMAND_STAY: // flat=1792 // STAY
pet->clearUnitState(UNIT_STAT_MOVING);
{
pet->StopMoving();
pet->GetMotionMaster()->Clear(false);
pet->GetMotionMaster()->MoveIdle();
pet->AttackStop(true);
pet->GetMotionMaster()->Clear();
((Pet*)pet)->SetStayPosition(true);
((Pet*)pet)->SetIsRetreating();
((Pet*)pet)->SetSpellOpener();
charmInfo->SetCommandState(COMMAND_STAY);
break;
}
case COMMAND_FOLLOW: // spellid=1792 // FOLLOW
pet->AttackStop();
pet->GetMotionMaster()->MoveFollow(_player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
{
pet->StopMoving();
pet->AttackStop(true);
pet->GetMotionMaster()->Clear();
((Pet*)pet)->SetStayPosition();
((Pet*)pet)->SetIsRetreating(true);
((Pet*)pet)->SetSpellOpener();
charmInfo->SetCommandState(COMMAND_FOLLOW);
break;
}
case COMMAND_ATTACK: // spellid=1792 // ATTACK
{
Unit* TargetUnit = _player->GetMap()->GetUnit(targetGuid);
@ -182,10 +192,16 @@ void WorldSession::HandlePetAction(WorldPacket& recv_data)
switch (spellid)
{
case REACT_PASSIVE: // passive
{
pet->AttackStop(true);
((Pet*)pet)->SetSpellOpener();
}
case REACT_DEFENSIVE: // recovery
case REACT_AGGRESSIVE: // activete
{
charmInfo->SetReactState(ReactStates(spellid));
break;
}
}
break;
case ACT_DISABLED: // 0x81 spell (disabled), ignore
@ -226,6 +242,28 @@ void WorldSession::HandlePetAction(WorldPacket& recv_data)
SpellCastResult result = spell->CheckPetCast(unit_target);
const SpellRangeEntry* sRange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
if (unit_target && !(pet->IsWithinDistInMap(unit_target, sRange->maxRange) && pet->IsWithinLOSInMap(unit_target))
&& !(GetPlayer()->IsFriendlyTo(unit_target) || pet->HasAuraType(SPELL_AURA_MOD_POSSESS)))
{
((Pet*)pet)->SetSpellOpener(spellid, sRange->minRange, sRange->maxRange);
spell->finish(false);
delete spell;
pet->AttackStop();
pet->GetMotionMaster()->Clear();
((Creature*)pet)->AI()->AttackStart(unit_target);
// 10% chance to play special warlock pet attack talk, else growl
if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10))
pet->SendPetTalk((uint32)PET_TALK_ATTACK);
pet->SendPetAIReaction();
return;
}
// auto turn to target unless possessed
if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
{
@ -253,28 +291,7 @@ void WorldSession::HandlePetAction(WorldPacket& recv_data)
unit_target = spell->m_targets.getUnitTarget();
// 10% chance to play special pet attack talk, else growl
// actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (((Creature*)pet)->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
{
pet->SendPetAIReaction();
}
if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
{
// This is true if pet has no target or has target but targets differs.
if (pet->getVictim() != unit_target)
{
if (pet->getVictim())
pet->AttackStop();
pet->GetMotionMaster()->Clear();
if (((Creature*)pet)->AI())
((Creature*)pet)->AI()->AttackStart(unit_target);
}
}
((Pet*)pet)->SetSpellOpener();
spell->SpellStart(&(spell->m_targets));
}
else
@ -291,6 +308,7 @@ void WorldSession::HandlePetAction(WorldPacket& recv_data)
if (!((Creature*)pet)->HasSpellCooldown(spellid))
GetPlayer()->SendClearCooldown(spellid, pet);
((Pet*)pet)->SetSpellOpener();
spell->finish(false);
delete spell;
}
@ -702,20 +720,10 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
spell->m_cast_count = cast_count; // probably pending spell cast
spell->m_targets = targets;
SpellCastResult result = triggeredByAura ? SPELL_CAST_OK : spell->CheckPetCast(NULL);
SpellCastResult result = triggeredByAura ? SPELL_CAST_OK : spell->CheckPetCast(nullptr);
if (result == SPELL_CAST_OK)
{
pet->AddCreatureSpellCooldown(spellid);
if (pet->IsPet())
{
// 10% chance to play special pet attack talk, else growl
// actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (((Pet*)pet)->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction();
}
spell->SpellStart(&(spell->m_targets), triggeredByAura);
}
else

View file

@ -7497,6 +7497,11 @@ void Spell::UpdatePointers()
UpdateOriginalCasterPointer();
m_targets.Update(m_caster);
if (m_caster->GetTypeId() == TYPEID_PLAYER)
m_CastItem = ((Player *)m_caster)->GetItemByGuid(m_CastItemGuid);
else
m_CastItem = NULL;
}
bool Spell::CheckTargetCreatureType(Unit* target) const
@ -8063,6 +8068,7 @@ void Spell::ClearCastItem()
m_targets.setItemTarget(NULL);
m_CastItem = NULL;
m_CastItemGuid.Clear();
}
bool Spell::HasGlobalCooldown()

View file

@ -470,9 +470,10 @@ void World::LoadConfigSettings(bool reload)
setConfigPos(CONFIG_FLOAT_RATE_DROP_MONEY, "Rate.Drop.Money", 1.0f);
setConfigPos(CONFIG_FLOAT_RATE_DROP_CURRENCY, "Rate.Drop.Currency", 1.0f);
setConfigPos(CONFIG_FLOAT_RATE_DROP_CURRENCY_AMOUNT, "Rate.Drop.Currency.Amount", 1.0f);
setConfig(CONFIG_FLOAT_RATE_XP_KILL, "Rate.XP.Kill", 1.0f);
setConfig(CONFIG_FLOAT_RATE_XP_QUEST, "Rate.XP.Quest", 1.0f);
setConfig(CONFIG_FLOAT_RATE_XP_EXPLORE, "Rate.XP.Explore", 1.0f);
setConfig(CONFIG_FLOAT_RATE_PET_XP_KILL, "Rate.Pet.XP.Kill", 1.0f);
setConfig(CONFIG_FLOAT_RATE_XP_KILL, "Rate.XP.Kill", 1.0f);
setConfig(CONFIG_FLOAT_RATE_XP_QUEST, "Rate.XP.Quest", 1.0f);
setConfig(CONFIG_FLOAT_RATE_XP_EXPLORE, "Rate.XP.Explore", 1.0f);
setConfig(CONFIG_FLOAT_RATE_REPUTATION_GAIN, "Rate.Reputation.Gain", 1.0f);
setConfig(CONFIG_FLOAT_RATE_REPUTATION_LOWLEVEL_KILL, "Rate.Reputation.LowLevel.Kill", 1.0f);
setConfig(CONFIG_FLOAT_RATE_REPUTATION_LOWLEVEL_QUEST, "Rate.Reputation.LowLevel.Quest", 1.0f);

View file

@ -267,6 +267,7 @@ enum eConfigFloatValues
CONFIG_FLOAT_RATE_DROP_MONEY,
CONFIG_FLOAT_RATE_DROP_CURRENCY,
CONFIG_FLOAT_RATE_DROP_CURRENCY_AMOUNT,
CONFIG_FLOAT_RATE_PET_XP_KILL,
CONFIG_FLOAT_RATE_XP_KILL,
CONFIG_FLOAT_RATE_XP_QUEST,
CONFIG_FLOAT_RATE_XP_EXPLORE,

View file

@ -203,6 +203,10 @@ BindIP = "0.0.0.0"
# Default: 1 (Enable)
# 0 (Disabled)
#
# MaxWhoListReturns
# Set the max number of players returned in the /who list and interface (0 means unlimited)
# Default: 49 - (stable)
#
################################################################################
UseProcessors = 0
@ -231,6 +235,7 @@ UpdateUptimeInterval = 10
MaxCoreStuckTime = 0
AddonChannel = 1
CleanCharacterDB = 1
MaxWhoListReturns = 49
################################################################################
# SERVER LOGGING
@ -1282,6 +1287,7 @@ Visibility.AIRelocationNotifyDelay = 1000
# Drop rate for currency amount
# Default: 1
#
# Rate.Pet.XP.Kill
# Rate.XP.Kill
# Rate.XP.Quest
# Rate.XP.Explore
@ -1428,6 +1434,7 @@ Rate.Drop.Item.Quest = 1
Rate.Drop.Money = 1
Rate.Drop.Currency = 1
Rate.Drop.Currency.Amount = 1
Rate.Pet.XP.Kill = 1
Rate.XP.Kill = 1
Rate.XP.Quest = 1
Rate.XP.Explore = 1