mirror of
https://github.com/mangosfour/server.git
synced 2025-12-26 16:37:06 +00:00
Over 100 camangos Cata commits applied (to c12950)
Over 100 camangos Cata commits applied. up to and inclusing c12950.
This commit is contained in:
parent
b4ec0440aa
commit
eef77eadb9
117 changed files with 4314 additions and 3547 deletions
|
|
@ -147,7 +147,7 @@ AggressorAI::IsVisible(Unit* pl) const
|
|||
void
|
||||
AggressorAI::AttackStart(Unit* u)
|
||||
{
|
||||
if (!u)
|
||||
if (!u || !m_creature->CanAttackByItself())
|
||||
return;
|
||||
|
||||
if (m_creature->Attack(u, true))
|
||||
|
|
|
|||
|
|
@ -351,8 +351,6 @@ void ArenaTeam::Disband(WorldSession* session)
|
|||
|
||||
void ArenaTeam::Roster(WorldSession* session)
|
||||
{
|
||||
Player* pl = NULL;
|
||||
|
||||
uint8 unk308 = 0;
|
||||
|
||||
WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
|
||||
|
|
@ -363,7 +361,7 @@ void ArenaTeam::Roster(WorldSession* session)
|
|||
|
||||
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
pl = sObjectMgr.GetPlayer(itr->guid);
|
||||
Player* pl = sObjectMgr.GetPlayer(itr->guid);
|
||||
|
||||
data << itr->guid; // guid
|
||||
data << uint8((pl ? 1 : 0)); // online flag
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ void CalendarMgr::RemoveEvent(uint64 eventId, Player* remover)
|
|||
// Add invit to an event and inform client
|
||||
// some check done before so it may fail and raison is sent to client
|
||||
// return value is the CalendarInvite pointer on success
|
||||
CalendarInvite* CalendarMgr::AddInvite(CalendarEvent* event, ObjectGuid const& senderGuid, ObjectGuid const& inviteeGuid, CalendarInviteStatus status, CalendarModerationRank rank, std::string text, time_t statusTime)
|
||||
CalendarInvite* CalendarMgr::AddInvite(CalendarEvent* event, ObjectGuid const& senderGuid, ObjectGuid const& inviteeGuid, CalendarInviteStatus status, CalendarModerationRank rank, const std::string& text, time_t statusTime)
|
||||
{
|
||||
Player* sender = sObjectMgr.GetPlayer(senderGuid);
|
||||
if (!event || !sender)
|
||||
|
|
@ -481,7 +481,7 @@ void CalendarMgr::CopyEvent(uint64 eventId, time_t newTime, ObjectGuid const& gu
|
|||
return;
|
||||
|
||||
if (newEvent->IsGuildAnnouncement())
|
||||
AddInvite(newEvent, guid, guid, CALENDAR_STATUS_CONFIRMED, CALENDAR_RANK_OWNER, "", time(NULL));
|
||||
AddInvite(newEvent, guid, guid, CALENDAR_STATUS_CONFIRMED, CALENDAR_RANK_OWNER, "", time(nullptr));
|
||||
else
|
||||
{
|
||||
// copy all invitees, set new owner as the one who make the copy, set invitees status to invited
|
||||
|
|
@ -490,18 +490,19 @@ void CalendarMgr::CopyEvent(uint64 eventId, time_t newTime, ObjectGuid const& gu
|
|||
|
||||
while (ci_itr != cInvMap->end())
|
||||
{
|
||||
if (ci_itr->second->InviteeGuid == guid)
|
||||
const CalendarInvite* invite = ci_itr->second;
|
||||
if (invite->InviteeGuid == guid)
|
||||
{
|
||||
AddInvite(newEvent, guid, ci_itr->second->InviteeGuid, CALENDAR_STATUS_CONFIRMED, CALENDAR_RANK_OWNER, "", time(NULL));
|
||||
AddInvite(newEvent, guid, invite->InviteeGuid, CALENDAR_STATUS_CONFIRMED, CALENDAR_RANK_OWNER, "", time(nullptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
CalendarModerationRank rank = CALENDAR_RANK_PLAYER;
|
||||
// copy moderator rank
|
||||
if (ci_itr->second->Rank == CALENDAR_RANK_MODERATOR)
|
||||
if (invite->Rank == CALENDAR_RANK_MODERATOR)
|
||||
rank = CALENDAR_RANK_MODERATOR;
|
||||
|
||||
AddInvite(newEvent, guid, ci_itr->second->InviteeGuid, CALENDAR_STATUS_INVITED, rank, "", time(NULL));
|
||||
AddInvite(newEvent, guid, invite->InviteeGuid, CALENDAR_STATUS_INVITED, rank, "", time(nullptr));
|
||||
}
|
||||
++ci_itr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,8 +234,8 @@ class CalendarMgr
|
|||
|
||||
CalendarEvent* AddEvent(ObjectGuid const& guid, std::string title, std::string description, uint32 type, uint32 repeatable, uint32 maxInvites,
|
||||
int32 dungeonId, time_t eventTime, time_t unkTime, uint32 flags);
|
||||
|
||||
CalendarInvite* AddInvite(CalendarEvent* event, ObjectGuid const& senderGuid, ObjectGuid const& inviteeGuid, CalendarInviteStatus status, CalendarModerationRank rank, std::string text, time_t statusTime);
|
||||
|
||||
CalendarInvite* AddInvite(CalendarEvent* event, ObjectGuid const& senderGuid, ObjectGuid const& inviteeGuid, CalendarInviteStatus status, CalendarModerationRank rank, const std::string& text, time_t statusTime);
|
||||
|
||||
void RemoveEvent(uint64 eventId, Player* remover);
|
||||
bool RemoveInvite(uint64 eventId, uint64 inviteId, ObjectGuid const& removerGuid);
|
||||
|
|
|
|||
|
|
@ -168,8 +168,7 @@ Creature::Creature(CreatureSubtype subtype) : Unit(),
|
|||
m_corpseDecayTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_aggroDelay(0), m_respawnradius(5.0f),
|
||||
m_subtype(subtype), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),
|
||||
m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false),
|
||||
m_regenHealth(true), m_AI_locked(false), m_IsDeadByDefault(false),
|
||||
m_temporaryFactionFlags(TEMPFACTION_NONE),
|
||||
m_AI_locked(false), m_IsDeadByDefault(false), m_temporaryFactionFlags(TEMPFACTION_NONE),
|
||||
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0),
|
||||
m_creatureInfo(NULL)
|
||||
{
|
||||
|
|
@ -252,6 +251,12 @@ void Creature::RemoveCorpse()
|
|||
if (AI())
|
||||
{ AI()->CorpseRemoved(respawnDelay); }
|
||||
|
||||
if (m_isCreatureLinkingTrigger)
|
||||
GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_DESPAWN, this);
|
||||
|
||||
if (InstanceData* mapInstance = GetInstanceData())
|
||||
mapInstance->OnCreatureDespawn(this);
|
||||
|
||||
// script can set time (in seconds) explicit, override the original
|
||||
if (respawnDelay)
|
||||
{ m_respawnTime = time(NULL) + respawnDelay; }
|
||||
|
|
@ -335,6 +340,24 @@ bool Creature::InitEntry(uint32 Entry, CreatureData const* data /*=NULL*/, GameE
|
|||
|
||||
SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
|
||||
|
||||
// set PowerType based on unit class
|
||||
switch (cinfo->UnitClass)
|
||||
{
|
||||
case CLASS_WARRIOR:
|
||||
SetPowerType(POWER_RAGE);
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
case CLASS_MAGE:
|
||||
SetPowerType(POWER_MANA);
|
||||
break;
|
||||
case CLASS_ROGUE:
|
||||
SetPowerType(POWER_ENERGY);
|
||||
break;
|
||||
default:
|
||||
sLog.outErrorDb("Creature (Entry: %u) has unhandled unit class. Power type will not be set!", Entry);
|
||||
break;
|
||||
}
|
||||
|
||||
// Load creature equipment
|
||||
if (eventData && eventData->equipment_id)
|
||||
{
|
||||
|
|
@ -663,33 +686,68 @@ void Creature::RegenerateAll(uint32 update_diff)
|
|||
if (!IsInCombat() || IsPolymorphed())
|
||||
RegenerateHealth();
|
||||
|
||||
RegenerateMana();
|
||||
RegeneratePower();
|
||||
|
||||
m_regenTimer = REGEN_TIME_FULL;
|
||||
}
|
||||
|
||||
void Creature::RegenerateMana()
|
||||
void Creature::RegeneratePower()
|
||||
{
|
||||
uint32 curValue = GetPower(POWER_MANA);
|
||||
uint32 maxValue = GetMaxPower(POWER_MANA);
|
||||
if (!IsRegeneratingPower())
|
||||
return;
|
||||
|
||||
Powers powerType = GetPowerType();
|
||||
uint32 curValue = GetPower(powerType);
|
||||
uint32 maxValue = GetMaxPower(powerType);
|
||||
|
||||
if (curValue >= maxValue)
|
||||
return;
|
||||
|
||||
uint32 addvalue = 0;
|
||||
float addValue = 0.0f;
|
||||
|
||||
// Combat and any controlled creature
|
||||
if (IsInCombat() || GetCharmerOrOwnerGuid())
|
||||
switch (powerType)
|
||||
{
|
||||
float ManaIncreaseRate = sWorld.getConfig(CONFIG_FLOAT_RATE_POWER_MANA);
|
||||
float Spirit = GetStat(STAT_SPIRIT);
|
||||
case POWER_MANA:
|
||||
// Combat and any controlled creature
|
||||
if (IsInCombat() || GetCharmerOrOwnerGuid())
|
||||
{
|
||||
float ManaIncreaseRate = sWorld.getConfig(CONFIG_FLOAT_RATE_POWER_MANA);
|
||||
float Spirit = GetStat(STAT_SPIRIT);
|
||||
|
||||
addvalue = uint32((Spirit / 5.0f + 17.0f) * ManaIncreaseRate);
|
||||
addValue = uint32(Spirit / 5.0f + 17.0f) * ManaIncreaseRate;
|
||||
}
|
||||
else
|
||||
addValue = maxValue / 3.0f;
|
||||
break;
|
||||
case POWER_ENERGY:
|
||||
// ToDo: for vehicle this is different - NEEDS TO BE FIXED!
|
||||
addValue = 20 * sWorld.getConfig(CONFIG_FLOAT_RATE_POWER_ENERGY);
|
||||
break;
|
||||
case POWER_FOCUS:
|
||||
addValue = 24 * sWorld.getConfig(CONFIG_FLOAT_RATE_POWER_FOCUS);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
else
|
||||
addvalue = maxValue / 3;
|
||||
|
||||
ModifyPower(POWER_MANA, addvalue);
|
||||
// Apply modifiers (if any)
|
||||
AuraList const& ModPowerRegenAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN);
|
||||
for (AuraList::const_iterator i = ModPowerRegenAuras.begin(); i != ModPowerRegenAuras.end(); ++i)
|
||||
{
|
||||
Modifier const* modifier = (*i)->GetModifier();
|
||||
if (modifier->m_miscvalue == int32(powerType))
|
||||
addValue += modifier->m_amount;
|
||||
}
|
||||
|
||||
AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
|
||||
for (AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
|
||||
{
|
||||
Modifier const* modifier = (*i)->GetModifier();
|
||||
if (modifier->m_miscvalue == int32(powerType))
|
||||
addValue *= (modifier->m_amount + 100) / 100.0f;
|
||||
}
|
||||
|
||||
ModifyPower(powerType, int32(addValue));
|
||||
}
|
||||
|
||||
void Creature::RegenerateHealth()
|
||||
|
|
@ -1237,12 +1295,12 @@ void Creature::SelectLevel(const CreatureInfo* cinfo, float percentHealth /*= 10
|
|||
|
||||
switch (i)
|
||||
{
|
||||
case POWER_MANA: maxValue = mana; break;
|
||||
case POWER_RAGE: maxValue = 0; break;
|
||||
case POWER_FOCUS: maxValue = POWER_FOCUS_DEFAULT; break;
|
||||
case POWER_ENERGY: maxValue = POWER_ENERGY_DEFAULT * cinfo->PowerMultiplier; break;
|
||||
case POWER_RUNE: maxValue = 0; break;
|
||||
case POWER_RUNIC_POWER: maxValue = 0; break;
|
||||
case POWER_MANA: maxValue = mana; break;
|
||||
case POWER_RAGE: maxValue = 0; break;
|
||||
case POWER_FOCUS: maxValue = POWER_FOCUS_DEFAULT; break;
|
||||
case POWER_ENERGY: maxValue = POWER_ENERGY_DEFAULT * cinfo->PowerMultiplier; break;
|
||||
case POWER_RUNE: maxValue = 0; break;
|
||||
case POWER_RUNIC_POWER: maxValue = 0; break;
|
||||
}
|
||||
|
||||
uint32 value = maxValue;
|
||||
|
|
@ -1313,22 +1371,22 @@ float Creature::_GetDamageMod(int32 Rank)
|
|||
}
|
||||
}
|
||||
|
||||
float Creature::GetSpellDamageMod(int32 Rank)
|
||||
float Creature::_GetSpellDamageMod(int32 Rank)
|
||||
{
|
||||
switch (Rank) // define rates for each elite rank
|
||||
{
|
||||
case CREATURE_ELITE_NORMAL:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_NORMAL_SPELLDAMAGE);
|
||||
case CREATURE_ELITE_ELITE:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE);
|
||||
case CREATURE_ELITE_RAREELITE:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_RAREELITE_SPELLDAMAGE);
|
||||
case CREATURE_ELITE_WORLDBOSS:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_WORLDBOSS_SPELLDAMAGE);
|
||||
case CREATURE_ELITE_RARE:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_RARE_SPELLDAMAGE);
|
||||
default:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE);
|
||||
case CREATURE_ELITE_NORMAL:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_NORMAL_SPELLDAMAGE);
|
||||
case CREATURE_ELITE_ELITE:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE);
|
||||
case CREATURE_ELITE_RAREELITE:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_RAREELITE_SPELLDAMAGE);
|
||||
case CREATURE_ELITE_WORLDBOSS:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_WORLDBOSS_SPELLDAMAGE);
|
||||
case CREATURE_ELITE_RARE:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_RARE_SPELLDAMAGE);
|
||||
default:
|
||||
return sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1581,7 +1639,7 @@ void Creature::SetDeathState(DeathState s)
|
|||
if ((s == JUST_DIED && !m_IsDeadByDefault) || (s == JUST_ALIVED && m_IsDeadByDefault))
|
||||
{
|
||||
m_corpseDecayTimer = m_corpseDelay * IN_MILLISECONDS; // the max/default time for corpse decay (before creature is looted/AllLootRemovedFromCorpse() is called)
|
||||
m_respawnTime = time(NULL) + m_respawnDelay; // respawn delay (spawntimesecs)
|
||||
m_respawnTime = time(nullptr) + m_respawnDelay; // respawn delay (spawntimesecs)
|
||||
|
||||
// always save boss respawn time at death to prevent crash cheating
|
||||
if (sWorld.getConfig(CONFIG_BOOL_SAVE_RESPAWN_TIME_IMMEDIATELY) || IsWorldBoss())
|
||||
|
|
@ -1614,7 +1672,7 @@ void Creature::SetDeathState(DeathState s)
|
|||
Unit::SetDeathState(ALIVE);
|
||||
|
||||
SetHealth(GetMaxHealth());
|
||||
SetLootRecipient(NULL);
|
||||
SetLootRecipient(nullptr);
|
||||
if (GetTemporaryFactionFlags() & TEMPFACTION_RESTORE_RESPAWN)
|
||||
ClearTemporaryFaction();
|
||||
|
||||
|
|
@ -2523,6 +2581,10 @@ void Creature::SetFactionTemporary(uint32 factionId, uint32 tempFactionFlags)
|
|||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_PASSIVE)
|
||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
|
||||
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_PACIFIED)
|
||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
|
||||
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_NOT_SELECTABLE)
|
||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void Creature::ClearTemporaryFaction()
|
||||
|
|
@ -2535,13 +2597,17 @@ void Creature::ClearTemporaryFaction()
|
|||
|
||||
// Reset to original faction
|
||||
setFaction(GetCreatureInfo()->FactionAlliance);
|
||||
// Reset UNIT_FLAG_NON_ATTACKABLE, UNIT_FLAG_OOC_NOT_ATTACKABLE or UNIT_FLAG_PASSIVE flags
|
||||
// Reset UNIT_FLAG_NON_ATTACKABLE, UNIT_FLAG_OOC_NOT_ATTACKABLE, UNIT_FLAG_PASSIVE, UNIT_FLAG_PACIFIED or UNIT_FLAG_NOT_SELECTABLE flags
|
||||
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_NON_ATTACKABLE && GetCreatureInfo()->UnitFlags & UNIT_FLAG_NON_ATTACKABLE)
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_OOC_NOT_ATTACK && GetCreatureInfo()->UnitFlags & UNIT_FLAG_OOC_NOT_ATTACKABLE && !IsInCombat())
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_PASSIVE && GetCreatureInfo()->UnitFlags & UNIT_FLAG_PASSIVE)
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
|
||||
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_PACIFIED && GetCreatureInfo()->UnitFlags & UNIT_FLAG_PACIFIED)
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
|
||||
if (m_temporaryFactionFlags & TEMPFACTION_TOGGLE_NOT_SELECTABLE && GetCreatureInfo()->UnitFlags & UNIT_FLAG_NOT_SELECTABLE)
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
m_temporaryFactionFlags = TEMPFACTION_NONE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -612,6 +612,8 @@ enum TemporaryFactionFlags // Used at real fact
|
|||
TEMPFACTION_TOGGLE_NON_ATTACKABLE = 0x08, // Remove UNIT_FLAG_NON_ATTACKABLE(0x02) when faction is changed (reapply when temp-faction is removed)
|
||||
TEMPFACTION_TOGGLE_OOC_NOT_ATTACK = 0x10, // Remove UNIT_FLAG_OOC_NOT_ATTACKABLE(0x100) when faction is changed (reapply when temp-faction is removed)
|
||||
TEMPFACTION_TOGGLE_PASSIVE = 0x20, // Remove UNIT_FLAG_PASSIVE(0x200) when faction is changed (reapply when temp-faction is removed)
|
||||
TEMPFACTION_TOGGLE_PACIFIED = 0x40, // Remove UNIT_FLAG_PACIFIED(0x20000) when faction is changed (reapply when temp-faction is removed)
|
||||
TEMPFACTION_TOGGLE_NOT_SELECTABLE = 0x80, // Remove UNIT_FLAG_NOT_SELECTABLE(0x2000000) when faction is changed (reapply when temp-faction is removed)
|
||||
TEMPFACTION_ALL,
|
||||
};
|
||||
|
||||
|
|
@ -732,7 +734,10 @@ class Creature : public Unit
|
|||
void UpdateAttackPowerAndDamage(bool ranged = false) override;
|
||||
void UpdateDamagePhysical(WeaponAttackType attType) override;
|
||||
uint32 GetCurrentEquipmentId() { return m_equipmentId; }
|
||||
float GetSpellDamageMod(int32 Rank);
|
||||
|
||||
static float _GetHealthMod(int32 Rank); ///< Get custom factor to scale health (default 1, CONFIG_FLOAT_RATE_CREATURE_*_HP)
|
||||
static float _GetDamageMod(int32 Rank); ///< Get custom factor to scale damage (default 1, CONFIG_FLOAT_RATE_*_DAMAGE)
|
||||
static float _GetSpellDamageMod(int32 Rank); ///< Get custom factor to scale spell damage (default 1, CONFIG_FLOAT_RATE_*_SPELLDAMAGE)
|
||||
|
||||
VendorItemData const* GetVendorItems() const;
|
||||
VendorItemData const* GetVendorTemplateItems() const;
|
||||
|
|
@ -921,9 +926,6 @@ class Creature : public Unit
|
|||
|
||||
void _RealtimeSetCreatureInfo();
|
||||
|
||||
static float _GetHealthMod(int32 Rank);
|
||||
static float _GetDamageMod(int32 Rank);
|
||||
|
||||
uint32 m_lootMoney;
|
||||
ObjectGuid m_lootRecipientGuid; // player who will have rights for looting if m_lootGroupRecipient==0 or group disbanded
|
||||
uint32 m_lootGroupRecipientId; // group who will have rights for looting if set and exist
|
||||
|
|
@ -937,7 +939,7 @@ class Creature : public Unit
|
|||
float m_respawnradius;
|
||||
|
||||
CreatureSubtype m_subtype; // set in Creatures subclasses for fast it detect without dynamic_cast use
|
||||
void RegenerateMana();
|
||||
void RegeneratePower();
|
||||
void RegenerateHealth();
|
||||
MovementGeneratorType m_defaultMovementType;
|
||||
Cell m_currentCell; // store current cell where creature listed
|
||||
|
|
@ -946,7 +948,6 @@ class Creature : public Unit
|
|||
// below fields has potential for optimization
|
||||
bool m_AlreadyCallAssistance;
|
||||
bool m_AlreadySearchedAssistance;
|
||||
bool m_regenHealth;
|
||||
bool m_AI_locked;
|
||||
bool m_IsDeadByDefault;
|
||||
uint32 m_temporaryFactionFlags; // used for real faction changes (not auras etc)
|
||||
|
|
|
|||
|
|
@ -154,12 +154,13 @@ void CreatureAI::SetCombatMovement(bool enable, bool stopOrStartMovement /*=fals
|
|||
|
||||
void CreatureAI::HandleMovementOnAttackStart(Unit* victim)
|
||||
{
|
||||
MotionMaster* creatureMotion = m_creature->GetMotionMaster();
|
||||
if (m_isCombatMovement)
|
||||
m_creature->GetMotionMaster()->MoveChase(victim, m_attackDistance, m_attackAngle);
|
||||
creatureMotion->MoveChase(victim, m_attackDistance, m_attackAngle);
|
||||
// TODO - adapt this to only stop OOC-MMGens when MotionMaster rewrite is finished
|
||||
else if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE || m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == RANDOM_MOTION_TYPE)
|
||||
else if (creatureMotion->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE || creatureMotion->GetCurrentMovementGeneratorType() == RANDOM_MOTION_TYPE)
|
||||
{
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
creatureMotion->MoveIdle();
|
||||
m_creature->StopMoving();
|
||||
}
|
||||
}
|
||||
|
|
@ -223,10 +224,20 @@ void CreatureAI::SendAIEventAround(AIEventType eventType, Unit* pInvoker, uint32
|
|||
{
|
||||
std::list<Creature*> receiverList;
|
||||
|
||||
// Use this check here to collect only assitable creatures in case of CALL_ASSISTANCE, else be less strict
|
||||
MaNGOS::AnyAssistCreatureInRangeCheck u_check(m_creature, eventType == AI_EVENT_CALL_ASSISTANCE ? pInvoker : NULL, fRadius);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck> searcher(receiverList, u_check);
|
||||
Cell::VisitGridObjects(m_creature, searcher, fRadius);
|
||||
// Allow sending custom AI events to all units in range
|
||||
if (eventType >= AI_EVENT_CUSTOM_EVENTAI_A && eventType <= AI_EVENT_CUSTOM_EVENTAI_F && eventType != AI_EVENT_GOT_CCED)
|
||||
{
|
||||
MaNGOS::AnyUnitInObjectRangeCheck u_check(m_creature, fRadius);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::AnyUnitInObjectRangeCheck> searcher(receiverList, u_check);
|
||||
Cell::VisitGridObjects(m_creature, searcher, fRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use this check here to collect only assitable creatures in case of CALL_ASSISTANCE, else be less strict
|
||||
MaNGOS::AnyAssistCreatureInRangeCheck u_check(m_creature, eventType == AI_EVENT_CALL_ASSISTANCE ? pInvoker : NULL, fRadius);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck> searcher(receiverList, u_check);
|
||||
Cell::VisitGridObjects(m_creature, searcher, fRadius);
|
||||
}
|
||||
|
||||
if (!receiverList.empty())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -85,19 +85,23 @@ enum AIEventType
|
|||
AI_EVENT_CUSTOM_EVENTAI_A = 5, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
|
||||
AI_EVENT_CUSTOM_EVENTAI_B = 6, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
|
||||
AI_EVENT_GOT_CCED = 7, // Sender = CCed Npc, Invoker = Caster that CCed
|
||||
MAXIMAL_AI_EVENT_EVENTAI = 8,
|
||||
AI_EVENT_CUSTOM_EVENTAI_C = 8, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
|
||||
AI_EVENT_CUSTOM_EVENTAI_D = 9, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
|
||||
AI_EVENT_CUSTOM_EVENTAI_E = 10, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
|
||||
AI_EVENT_CUSTOM_EVENTAI_F = 11, // Sender = Npc that throws custom event, Invoker = TARGET_T_ACTION_INVOKER (if exists)
|
||||
MAXIMAL_AI_EVENT_EVENTAI = 12,
|
||||
|
||||
// Internal Use
|
||||
AI_EVENT_CALL_ASSISTANCE = 10, // Sender = Attacked Npc, Invoker = Enemy
|
||||
AI_EVENT_CALL_ASSISTANCE = 13, // Sender = Attacked Npc, Invoker = Enemy
|
||||
|
||||
// Predefined for SD3
|
||||
// Predefined for SD2
|
||||
AI_EVENT_START_ESCORT = 100, // Invoker = Escorting Player
|
||||
AI_EVENT_START_ESCORT_B = 101, // Invoker = Escorting Player
|
||||
AI_EVENT_START_EVENT = 102, // Invoker = EventStarter
|
||||
AI_EVENT_START_EVENT_A = 103, // Invoker = EventStarter
|
||||
AI_EVENT_START_EVENT_B = 104, // Invoker = EventStarter
|
||||
|
||||
// Some IDs for special cases in SD3
|
||||
// Some IDs for special cases in SD2
|
||||
AI_EVENT_CUSTOM_A = 1000,
|
||||
AI_EVENT_CUSTOM_B = 1001,
|
||||
AI_EVENT_CUSTOM_C = 1002,
|
||||
|
|
|
|||
|
|
@ -91,16 +91,21 @@ inline bool IsEventFlagsFitForNormalMap(uint8 eFlags)
|
|||
CreatureEventAI::CreatureEventAI(Creature* c) : CreatureAI(c),
|
||||
m_Phase(0),
|
||||
m_MeleeEnabled(true),
|
||||
m_DynamicMovement(false),
|
||||
m_HasOOCLoSEvent(false),
|
||||
m_InvinceabilityHpLevel(0),
|
||||
m_throwAIEventMask(0),
|
||||
m_throwAIEventStep(0)
|
||||
m_throwAIEventStep(0),
|
||||
m_LastSpellMaxRange(0)
|
||||
{
|
||||
// Need make copy for filter unneeded steps and safe in case table reload
|
||||
CreatureEventAI_Event_Map::const_iterator creatureEventsItr = sEventAIMgr.GetCreatureEventAIMap().find(m_creature->GetEntry());
|
||||
if (creatureEventsItr != sEventAIMgr.GetCreatureEventAIMap().end())
|
||||
{
|
||||
uint32 events_count = 0;
|
||||
for (CreatureEventAI_Event_Vec::const_iterator i = creatureEventsItr->second.begin(); i != creatureEventsItr->second.end(); ++i)
|
||||
|
||||
const CreatureEventAI_Event_Vec& creatureEvent = creatureEventsItr->second;
|
||||
for (CreatureEventAI_Event_Vec::const_iterator i = creatureEvent.begin(); i != creatureEvent.end(); ++i)
|
||||
{
|
||||
// Debug check
|
||||
#ifndef MANGOS_DEBUG
|
||||
|
|
@ -119,27 +124,33 @@ CreatureEventAI::CreatureEventAI(Creature* c) : CreatureAI(c),
|
|||
}
|
||||
// EventMap had events but they were not added because they must be for instance
|
||||
if (events_count == 0)
|
||||
sLog.outErrorEventAI("Creature %u has events but no events added to list because of instance flags.", m_creature->GetEntry());
|
||||
sLog.outErrorEventAI("Creature %u has events but no events added to list because of instance flags (spawned in map %u, difficulty %u).", m_creature->GetEntry(), m_creature->GetMapId(), m_creature->GetMap()->GetDifficulty());
|
||||
else
|
||||
{
|
||||
m_CreatureEventAIList.reserve(events_count);
|
||||
for (CreatureEventAI_Event_Vec::const_iterator i = creatureEventsItr->second.begin(); i != creatureEventsItr->second.end(); ++i)
|
||||
for (CreatureEventAI_Event_Vec::const_iterator i = creatureEvent.begin(); i != creatureEvent.end(); ++i)
|
||||
{
|
||||
// Debug check
|
||||
#ifndef MANGOS_DEBUG
|
||||
if (i->event_flags & EFLAG_DEBUG_ONLY)
|
||||
continue;
|
||||
#endif
|
||||
bool storeEvent = false;
|
||||
if (m_creature->GetMap()->IsDungeon())
|
||||
{
|
||||
if ((1 << (m_creature->GetMap()->GetSpawnMode() + 1)) & i->event_flags)
|
||||
{
|
||||
// event flagged for instance mode
|
||||
m_CreatureEventAIList.push_back(CreatureEventAIHolder(*i));
|
||||
}
|
||||
storeEvent = true;
|
||||
}
|
||||
else if (IsEventFlagsFitForNormalMap(i->event_flags))
|
||||
storeEvent = true;
|
||||
|
||||
if (storeEvent)
|
||||
{
|
||||
m_CreatureEventAIList.push_back(CreatureEventAIHolder(*i));
|
||||
// Cache for fast use
|
||||
if (i->event_type == EVENT_T_OOC_LOS)
|
||||
m_HasOOCLoSEvent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1191,7 +1202,7 @@ void CreatureEventAI::EnterCombat(Unit* enemy)
|
|||
|
||||
void CreatureEventAI::AttackStart(Unit* who)
|
||||
{
|
||||
if (!who)
|
||||
if (!who || !m_creature->CanAttackByItself())
|
||||
return;
|
||||
|
||||
if (m_creature->Attack(who, m_MeleeEnabled))
|
||||
|
|
|
|||
|
|
@ -689,6 +689,7 @@ class CreatureEventAI : public CreatureAI
|
|||
// Note that Step 100 means that AI_EVENT_GOT_FULL_HEALTH was sent
|
||||
// Steps 0..2 correspond to AI_EVENT_LOST_SOME_HEALTH(90%), AI_EVENT_LOST_HEALTH(50%), AI_EVENT_CRITICAL_HEALTH(10%)
|
||||
uint32 m_throwAIEventStep; // Used for damage taken/ received heal
|
||||
float m_LastSpellMaxRange; // Maximum spell range that was cast during dynamic movement
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ void GameObject::RemoveFromWorld()
|
|||
Object::RemoveFromWorld();
|
||||
}
|
||||
|
||||
bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, QuaternionData rotation, uint8 animprogress, GOState go_state)
|
||||
bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, const QuaternionData& rotation, uint8 animprogress, GOState go_state)
|
||||
{
|
||||
MANGOS_ASSERT(map);
|
||||
Relocate(x, y, z, ang);
|
||||
|
|
@ -1134,8 +1134,8 @@ void GameObject::Use(Unit* user)
|
|||
// Some may have have animation and/or are expected to despawn.
|
||||
|
||||
// TODO: Improve this when more information is available, currently these traps are known that must send the anim (Onyxia/ Heigan Fissures/ Trap in DireMaul)
|
||||
if (GetDisplayId() == 4392 || GetDisplayId() == 4472 || GetDisplayId() == 6785 || GetDisplayId() == 3073)
|
||||
{ SendGameObjectCustomAnim(GetObjectGuid()); }
|
||||
if (GetDisplayId() == 4392 || GetDisplayId() == 4472 || GetDisplayId() == 4491 || GetDisplayId() == 6785 || GetDisplayId() == 3073 || GetDisplayId() == 7998)
|
||||
SendGameObjectCustomAnim(GetObjectGuid());
|
||||
|
||||
// TODO: Despawning of traps? (Also related to code in ::Update)
|
||||
return;
|
||||
|
|
@ -1733,7 +1733,7 @@ void GameObject::SetWorldRotation(float qx, float qy, float qz, float qw)
|
|||
m_worldRotation.w = rotation.w;
|
||||
}
|
||||
|
||||
void GameObject::SetTransportPathRotation(QuaternionData rotation)
|
||||
void GameObject::SetTransportPathRotation(const QuaternionData& rotation)
|
||||
{
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION + 0, rotation.x);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION + 1, rotation.y);
|
||||
|
|
|
|||
|
|
@ -647,9 +647,8 @@ class GameObject : public WorldObject
|
|||
void AddToWorld() override;
|
||||
void RemoveFromWorld() override;
|
||||
|
||||
bool Create(uint32 guidlow, uint32 name_id, Map* map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state);
|
||||
bool Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang,
|
||||
QuaternionData rotation = QuaternionData(), uint8 animprogress = GO_ANIMPROGRESS_DEFAULT, GOState go_state = GO_STATE_READY);
|
||||
const QuaternionData& rotation = QuaternionData(), uint8 animprogress = GO_ANIMPROGRESS_DEFAULT, GOState go_state = GO_STATE_READY);
|
||||
void Update(uint32 update_diff, uint32 p_time) override;
|
||||
GameObjectInfo const* GetGOInfo() const;
|
||||
|
||||
|
|
@ -660,7 +659,7 @@ class GameObject : public WorldObject
|
|||
// z_rot, y_rot, x_rot - rotation angles around z, y and x axes
|
||||
void SetWorldRotationAngles(float z_rot, float y_rot, float x_rot);
|
||||
void SetWorldRotation(float qx, float qy, float qz, float qw);
|
||||
void SetTransportPathRotation(QuaternionData rotation); // transforms(rotates) transport's path
|
||||
void SetTransportPathRotation(const QuaternionData& rotation); // transforms(rotates) transport's path
|
||||
int64 GetPackedWorldRotation() const { return m_packedRotation; }
|
||||
|
||||
// overwrite WorldObject function for proper name localization
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ bool Guild::Create(Player* leader, std::string gname)
|
|||
|
||||
m_LeaderGuid = leader->GetObjectGuid();
|
||||
m_Name = gname;
|
||||
GINFO = "";
|
||||
GINFO.clear();
|
||||
MOTD = "No message set.";
|
||||
m_GuildBankMoney = 0;
|
||||
m_Id = sObjectMgr.GenerateGuildId();
|
||||
|
|
@ -319,8 +319,11 @@ bool Guild::CheckGuildStructure()
|
|||
|
||||
// Allow only 1 guildmaster, set other to officer
|
||||
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
if (itr->second.RankId == GR_GUILDMASTER && m_LeaderGuid != itr->second.guid)
|
||||
itr->second.ChangeRank(GR_OFFICER);
|
||||
{
|
||||
MemberSlot& member = itr->second;
|
||||
if (member.RankId == GR_GUILDMASTER && m_LeaderGuid != member.guid)
|
||||
member.ChangeRank(GR_OFFICER);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -580,18 +583,22 @@ bool Guild::ChangeMemberRank(ObjectGuid guid, uint8 newRank)
|
|||
|
||||
void Guild::BroadcastToGuild(WorldSession* session, const std::string& msg, uint32 language)
|
||||
{
|
||||
if (session && session->GetPlayer() && HasRankRight(session->GetPlayer()->GetRank(), GR_RIGHT_GCHATSPEAK))
|
||||
if (!session)
|
||||
return;
|
||||
|
||||
Player* player = session->GetPlayer();
|
||||
if (!player || !HasRankRight(player->GetRank(), GR_RIGHT_GCHATSPEAK))
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_GUILD, msg.c_str(), Language(language), player->GetChatTag(), player->GetObjectGuid(), player->GetName());
|
||||
|
||||
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_GUILD, msg.c_str(), Language(language), session->GetPlayer()->GetChatTag(), session->GetPlayer()->GetObjectGuid(), session->GetPlayer()->GetName());
|
||||
Player* pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first));
|
||||
|
||||
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
Player* pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first));
|
||||
|
||||
if (pl && pl->GetSession() && HasRankRight(pl->GetRank(), GR_RIGHT_GCHATLISTEN) && !pl->GetSocial()->HasIgnore(session->GetPlayer()->GetObjectGuid()))
|
||||
pl->GetSession()->SendPacket(&data);
|
||||
}
|
||||
if (pl && pl->GetSession() && HasRankRight(pl->GetRank(), GR_RIGHT_GCHATLISTEN) && !pl->GetSocial()->HasIgnore(player->GetObjectGuid()))
|
||||
pl->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -690,12 +697,12 @@ void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 max
|
|||
return;
|
||||
}
|
||||
|
||||
MemberSlot const* member = &itr->second;
|
||||
uint32 level = Player::GetLevelFromDB(member->guid);
|
||||
MemberSlot const& member = itr->second;
|
||||
uint32 level = Player::GetLevelFromDB(member.guid);
|
||||
|
||||
if (member->guid != session->GetPlayer()->GetObjectGuid() && level >= minLevel && level <= maxLevel && member->RankId <= minRank)
|
||||
if (member.guid != session->GetPlayer()->GetObjectGuid() && level >= minLevel && level <= maxLevel && member.RankId <= minRank)
|
||||
{
|
||||
data << member->guid.WriteAsPacked();
|
||||
data << member.guid.WriteAsPacked();
|
||||
data << uint8(level);
|
||||
++count;
|
||||
}
|
||||
|
|
@ -1521,21 +1528,22 @@ uint32 Guild::GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId)
|
|||
if (itr == members.end())
|
||||
return 0;
|
||||
|
||||
if (itr->second.RankId == GR_GUILDMASTER)
|
||||
MemberSlot& member = itr->second;
|
||||
if (member.RankId == GR_GUILDMASTER)
|
||||
return WITHDRAW_SLOT_UNLIMITED;
|
||||
|
||||
if ((GetBankRights(itr->second.RankId, TabId) & GUILD_BANK_RIGHT_VIEW_TAB) != GUILD_BANK_RIGHT_VIEW_TAB)
|
||||
if ((GetBankRights(member.RankId, TabId) & GUILD_BANK_RIGHT_VIEW_TAB) != GUILD_BANK_RIGHT_VIEW_TAB)
|
||||
return 0;
|
||||
|
||||
uint32 curTime = uint32(time(NULL) / MINUTE);
|
||||
if (curTime - itr->second.BankResetTimeTab[TabId] >= 24 * HOUR / MINUTE)
|
||||
uint32 curTime = uint32(time(nullptr) / MINUTE);
|
||||
if (curTime - member.BankResetTimeTab[TabId] >= 24 * HOUR / MINUTE)
|
||||
{
|
||||
itr->second.BankResetTimeTab[TabId] = curTime;
|
||||
itr->second.BankRemSlotsTab[TabId] = GetBankSlotPerDay(itr->second.RankId, TabId);
|
||||
member.BankResetTimeTab[TabId] = curTime;
|
||||
member.BankRemSlotsTab[TabId] = GetBankSlotPerDay(member.RankId, TabId);
|
||||
CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeTab%u='%u', BankRemSlotsTab%u='%u' WHERE guildid='%u' AND guid='%u'",
|
||||
uint32(TabId), itr->second.BankResetTimeTab[TabId], uint32(TabId), itr->second.BankRemSlotsTab[TabId], m_Id, LowGuid);
|
||||
uint32(TabId), member.BankResetTimeTab[TabId], uint32(TabId), member.BankRemSlotsTab[TabId], m_Id, LowGuid);
|
||||
}
|
||||
return itr->second.BankRemSlotsTab[TabId];
|
||||
return member.BankRemSlotsTab[TabId];
|
||||
}
|
||||
|
||||
uint64 Guild::GetMemberMoneyWithdrawRem(uint32 LowGuid)
|
||||
|
|
@ -1544,19 +1552,20 @@ uint64 Guild::GetMemberMoneyWithdrawRem(uint32 LowGuid)
|
|||
if (itr == members.end())
|
||||
return 0;
|
||||
|
||||
if (itr->second.RankId == GR_GUILDMASTER)
|
||||
MemberSlot& member = itr->second;
|
||||
if (member.RankId == GR_GUILDMASTER)
|
||||
return WITHDRAW_MONEY_UNLIMITED;
|
||||
|
||||
uint32 curTime = uint32(time(NULL) / MINUTE); // minutes
|
||||
uint32 curTime = uint32(time(nullptr) / MINUTE); // minutes
|
||||
// 24 hours
|
||||
if (curTime > itr->second.BankResetTimeMoney + 24 * HOUR / MINUTE)
|
||||
if (curTime > member.BankResetTimeMoney + 24 * HOUR / MINUTE)
|
||||
{
|
||||
itr->second.BankResetTimeMoney = curTime;
|
||||
itr->second.BankRemMoney = GetBankMoneyPerDay(itr->second.RankId);
|
||||
member.BankResetTimeMoney = curTime;
|
||||
member.BankRemMoney = GetBankMoneyPerDay(member.RankId);
|
||||
CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeMoney='%u', BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'",
|
||||
itr->second.BankResetTimeMoney, itr->second.BankRemMoney, m_Id, LowGuid);
|
||||
member.BankResetTimeMoney, member.BankRemMoney, m_Id, LowGuid);
|
||||
}
|
||||
return itr->second.BankRemMoney;
|
||||
return member.BankRemMoney;
|
||||
}
|
||||
|
||||
void Guild::SetBankMoneyPerDay(uint32 rankId, uint32 money)
|
||||
|
|
@ -1570,8 +1579,11 @@ void Guild::SetBankMoneyPerDay(uint32 rankId, uint32 money)
|
|||
m_Ranks[rankId].BankMoneyPerDay = money;
|
||||
|
||||
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
if (itr->second.RankId == rankId)
|
||||
itr->second.BankResetTimeMoney = 0;
|
||||
{
|
||||
MemberSlot& member = itr->second;
|
||||
if (member.RankId == rankId)
|
||||
member.BankResetTimeMoney = 0;
|
||||
}
|
||||
|
||||
CharacterDatabase.PExecute("UPDATE guild_rank SET BankMoneyPerDay='%u' WHERE rid='%u' AND guildid='%u'", money, rankId, m_Id);
|
||||
CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeMoney='0' WHERE guildid='%u' AND rank='%u'", m_Id, rankId);
|
||||
|
|
@ -2401,10 +2413,9 @@ void Guild::MoveFromBankToChar(Player* pl, uint8 BankTab, uint8 BankTabSlot, uin
|
|||
{
|
||||
pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
|
||||
pItemChar->DeleteFromInventoryDB();
|
||||
StoreItem(BankTab, gDest, pItemChar);
|
||||
}
|
||||
|
||||
if (pItemChar)
|
||||
StoreItem(BankTab, gDest, pItemChar);
|
||||
pl->MoveItemToInventory(iDest, pItemBank, true);
|
||||
pl->SaveInventoryAndGoldToDB();
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,8 @@ uint32 GetItemEnchantMod(int32 entry)
|
|||
double dRoll = rand_chance();
|
||||
float fCount = 0;
|
||||
|
||||
for (EnchStoreList::const_iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
|
||||
const EnchStoreList& enchantList = tab->second;
|
||||
for (EnchStoreList::const_iterator ench_iter = enchantList.begin(); ench_iter != enchantList.end(); ++ench_iter)
|
||||
{
|
||||
fCount += ench_iter->chance;
|
||||
|
||||
|
|
@ -141,7 +142,7 @@ uint32 GetItemEnchantMod(int32 entry)
|
|||
dRoll = (irand(0, (int)floor(fCount * 100) + 1)) / 100;
|
||||
fCount = 0;
|
||||
|
||||
for (EnchStoreList::const_iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
|
||||
for (EnchStoreList::const_iterator ench_iter = enchantList.begin(); ench_iter != enchantList.end(); ++ench_iter)
|
||||
{
|
||||
fCount += ench_iter->chance;
|
||||
|
||||
|
|
|
|||
|
|
@ -1592,7 +1592,7 @@ namespace MaNGOS
|
|||
: i_object(obj), i_msgtype(msgtype), i_textData(textData), i_language(language), i_target(target) {}
|
||||
void operator()(WorldPacket& data, int32 loc_idx)
|
||||
{
|
||||
char const* text = nullptr;
|
||||
char const* text = NULL;
|
||||
if ((int32)i_textData->Content.size() > loc_idx + 1 && !i_textData->Content[loc_idx + 1].empty())
|
||||
text = i_textData->Content[loc_idx + 1].c_str();
|
||||
else
|
||||
|
|
|
|||
|
|
@ -39,13 +39,15 @@
|
|||
#define CONTACT_DISTANCE 0.5f
|
||||
#define INTERACTION_DISTANCE 5.0f
|
||||
#define ATTACK_DISTANCE 5.0f
|
||||
#define MAX_VISIBILITY_DISTANCE 333.0f // max distance for visible object show, limited in 333 yards
|
||||
#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
|
||||
#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
|
||||
#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
|
||||
#define INSPECT_DISTANCE 28.0f
|
||||
#define TRADE_DISTANCE 11.11f
|
||||
#define MAX_VISIBILITY_DISTANCE 333.0f // max distance for visible object show, limited in 333 yards
|
||||
#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
|
||||
#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
|
||||
#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
|
||||
|
||||
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // currently used (correctly?) for any non Unit world objects. This is actually the bounding_radius, like player/creature from creature_model_data
|
||||
#define DEFAULT_OBJECT_SCALE 1.0f // player/item Scale as default, npc/go from database, pets from dbc
|
||||
#define DEFAULT_OBJECT_SCALE 1.0f // player/item scale as default, npc/go from database, pets from dbc
|
||||
|
||||
#define MAX_STEALTH_DETECT_RANGE 45.0f
|
||||
|
||||
|
|
@ -601,8 +603,8 @@ class WorldObject : public Object
|
|||
virtual void SendMessageToSetInRange(WorldPacket* data, float dist, bool self) const;
|
||||
void SendMessageToSetExcept(WorldPacket* data, Player const* skipped_receiver) const;
|
||||
|
||||
void MonsterSay(const char* text, uint32 language, Unit const* target = nullptr) const;
|
||||
void MonsterYell(const char* text, uint32 language, Unit const* target = nullptr) const;
|
||||
void MonsterSay(const char* text, uint32 language, Unit const* target = NULL) const;
|
||||
void MonsterYell(const char* text, uint32 language, Unit const* target = NULL) const;
|
||||
void MonsterTextEmote(const char* text, Unit const* target, bool IsBossEmote = false) const;
|
||||
void MonsterWhisper(const char* text, Unit const* target, bool IsBossWhisper = false) const;
|
||||
void MonsterText(MangosStringLocale const* textData, Unit const* target) const;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,9 @@
|
|||
#include "InstanceData.h"
|
||||
#include "DB2Structure.h"
|
||||
#include "DB2Stores.h"
|
||||
#include "PhaseMgr.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "CellImpl.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
|
@ -192,15 +194,6 @@ ObjectMgr::~ObjectMgr()
|
|||
|
||||
for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr)
|
||||
itr->second.Clear();
|
||||
|
||||
for (PhaseDefinitionStore::iterator itr = _PhaseDefinitionStore.begin(); itr != _PhaseDefinitionStore.end(); ++itr)
|
||||
{
|
||||
for (PhaseDefinitionContainer::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
|
||||
delete *itr2;
|
||||
}
|
||||
|
||||
for (SpellPhaseStore::iterator itr = _SpellPhaseStore.begin(); itr != _SpellPhaseStore.end(); ++itr)
|
||||
delete itr->second;
|
||||
}
|
||||
|
||||
Group* ObjectMgr::GetGroupById(uint32 id) const
|
||||
|
|
@ -984,14 +977,14 @@ void ObjectMgr::LoadCreatureClassLvlStats()
|
|||
CreatureClassLvlStats const* ObjectMgr::GetCreatureClassLvlStats(uint32 level, uint32 unitClass, int32 expansion) const
|
||||
{
|
||||
if (expansion < 0)
|
||||
return nullptr;
|
||||
return NULL;
|
||||
|
||||
CreatureClassLvlStats const* cCLS = &m_creatureClassLvlStats[level][classToIndex[unitClass]][expansion];
|
||||
|
||||
if (cCLS->BaseHealth != 0 && cCLS->BaseDamage > 0.1f)
|
||||
return cCLS;
|
||||
|
||||
return nullptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadEquipmentTemplates()
|
||||
|
|
@ -5091,19 +5084,17 @@ void ObjectMgr::LoadGossipText()
|
|||
BarGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u npc texts", count);
|
||||
sLog.outString();
|
||||
return;
|
||||
}
|
||||
|
||||
int cic;
|
||||
|
||||
BarGoLink bar(result->GetRowCount());
|
||||
|
||||
do
|
||||
{
|
||||
++count;
|
||||
cic = 0;
|
||||
int cic = 0;
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
|
|
@ -5135,8 +5126,8 @@ void ObjectMgr::LoadGossipText()
|
|||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u npc texts", count);
|
||||
sLog.outString();
|
||||
delete result;
|
||||
}
|
||||
|
||||
|
|
@ -7354,11 +7345,15 @@ void ObjectMgr::LoadNPCSpellClickSpells()
|
|||
continue;
|
||||
}
|
||||
|
||||
SpellEntry const* spellinfo = sSpellStore.LookupEntry(info.spellId);
|
||||
if (!spellinfo)
|
||||
// spell can be 0 for special or custom cases
|
||||
if (info.spellId)
|
||||
{
|
||||
sLog.outErrorDb("Table npc_spellclick_spells references unknown spellid %u. Skipping entry.", info.spellId);
|
||||
continue;
|
||||
SpellEntry const* spellinfo = sSpellStore.LookupEntry(info.spellId);
|
||||
if (!spellinfo)
|
||||
{
|
||||
sLog.outErrorDb("Table npc_spellclick_spells references unknown spellid %u. Skipping entry.", info.spellId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (info.conditionId && !sConditionStorage.LookupEntry<PlayerCondition const*>(info.conditionId))
|
||||
|
|
@ -7704,7 +7699,7 @@ static LanguageType GetRealmLanguageType(bool create)
|
|||
}
|
||||
}
|
||||
|
||||
bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bool create = false)
|
||||
bool isValidString(const std::wstring& wstr, uint32 strictMask, bool numericOrSpace, bool create = false)
|
||||
{
|
||||
if (strictMask == 0) // any language, ignore realm
|
||||
{
|
||||
|
|
@ -8159,8 +8154,7 @@ bool ObjectMgr::IsPlayerMeetToCondition(uint16 conditionId, Player const* pPlaye
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectMgr::CheckDeclinedNames(std::wstring mainpart, DeclinedName const& names)
|
||||
bool ObjectMgr::CheckDeclinedNames(const std::wstring& mainpart, DeclinedName const& names)
|
||||
{
|
||||
for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
|
||||
{
|
||||
|
|
@ -8490,6 +8484,16 @@ bool PlayerCondition::Meets(Player const* player, Map const* map, WorldObject co
|
|||
case 3: // Creature source is dead
|
||||
return !source || source->GetTypeId() != TYPEID_UNIT || !((Unit*)source)->IsAlive();
|
||||
}
|
||||
case CONDITION_CREATURE_IN_RANGE:
|
||||
{
|
||||
Creature* creature = NULL;
|
||||
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck creature_check(*player, m_value1, true, false, m_value2, true);
|
||||
MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(creature, creature_check);
|
||||
Cell::VisitGridObjects(player, searcher, m_value2);
|
||||
|
||||
return creature;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -8945,6 +8949,19 @@ bool PlayerCondition::IsValid(uint16 entry, ConditionType condition, uint32 valu
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CONDITION_CREATURE_IN_RANGE:
|
||||
{
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo> (value1))
|
||||
{
|
||||
sLog.outErrorDb("Creature in range condition (entry %u, type %u) has an invalid value in value1. (Creature %u does not exist in the database), skipping.", entry, condition, value1);
|
||||
return false;
|
||||
}
|
||||
if (value2 <= 0)
|
||||
{
|
||||
sLog.outErrorDb("Creature in range condition (entry %u, type %u) has an invalid value in value2. (Range %u must be greater than 0), skipping.", entry, condition, value2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case CONDITION_NONE:
|
||||
break;
|
||||
default:
|
||||
|
|
@ -10422,117 +10439,6 @@ bool DoDisplayText(WorldObject* source, int32 entry, Unit const* target /*=NULL*
|
|||
return true;
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadPhaseDefinitions()
|
||||
{
|
||||
for (PhaseDefinitionStore::iterator itr = _PhaseDefinitionStore.begin(); itr != _PhaseDefinitionStore.end(); ++itr)
|
||||
{
|
||||
for (PhaseDefinitionContainer::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
|
||||
delete *itr2;
|
||||
}
|
||||
|
||||
_PhaseDefinitionStore.clear();
|
||||
|
||||
// 0 1 2 3 4 5 6
|
||||
QueryResult* result = WorldDatabase.Query("SELECT zoneId, entry, phasemask, phaseId, terrainswapmap, flags, condition_id FROM `phase_definitions` ORDER BY `entry` ASC");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sLog.outString(">> Loaded 0 phasing definitions. DB table `phase_definitions` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
PhaseDefinition* phaseDefinition = new PhaseDefinition();
|
||||
|
||||
phaseDefinition->zoneId = fields[0].GetUInt32();
|
||||
phaseDefinition->entry = fields[1].GetUInt32();
|
||||
phaseDefinition->phasemask = fields[2].GetUInt32();
|
||||
phaseDefinition->phaseId = fields[3].GetUInt32();
|
||||
phaseDefinition->terrainswapmap = fields[4].GetUInt32();
|
||||
phaseDefinition->flags = fields[5].GetUInt32();
|
||||
phaseDefinition->conditionId = fields[6].GetUInt16();
|
||||
|
||||
// Checks
|
||||
if ((phaseDefinition->flags & PHASE_FLAG_OVERWRITE_EXISTING) && (phaseDefinition->flags & PHASE_FLAG_NEGATE_PHASE))
|
||||
{
|
||||
sLog.outError("Flags defined in phase_definitions in zoneId %d and entry %u does contain PHASE_FLAG_OVERWRITE_EXISTING and PHASE_FLAG_NEGATE_PHASE. Setting flags to PHASE_FLAG_OVERWRITE_EXISTING", phaseDefinition->zoneId, phaseDefinition->entry);
|
||||
phaseDefinition->flags &= ~PHASE_FLAG_NEGATE_PHASE;
|
||||
}
|
||||
|
||||
if (!sConditionStorage.LookupEntry<PlayerCondition>(phaseDefinition->conditionId))
|
||||
{
|
||||
sLog.outError("Condition id defined in phase_definitions in zoneId %d and entry %u does not exists. Skipping condition.", phaseDefinition->zoneId, phaseDefinition->entry);
|
||||
phaseDefinition->conditionId = 0;
|
||||
}
|
||||
|
||||
_PhaseDefinitionStore[phaseDefinition->zoneId].push_back(phaseDefinition);
|
||||
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
delete result;
|
||||
|
||||
sLog.outString(">> Loaded %u phasing definitions.", count);
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadSpellPhaseInfo()
|
||||
{
|
||||
for (SpellPhaseStore::iterator itr = _SpellPhaseStore.begin(); itr != _SpellPhaseStore.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
_SpellPhaseStore.clear();
|
||||
|
||||
// 0 1 2
|
||||
QueryResult* result = WorldDatabase.Query("SELECT id, phasemask, terrainswapmap FROM `spell_phase`");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sLog.outString(">> Loaded 0 spell dbc infos. DB table `spell_phase` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
SpellPhaseInfo* spellPhaseInfo = new SpellPhaseInfo();
|
||||
spellPhaseInfo->spellId = fields[0].GetUInt32();
|
||||
|
||||
SpellEntry const* spell = sSpellStore.LookupEntry(spellPhaseInfo->spellId);
|
||||
if (!spell)
|
||||
{
|
||||
sLog.outError("Spell %u defined in `spell_phase` does not exists, skipped.", spellPhaseInfo->spellId);
|
||||
delete spellPhaseInfo;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsSpellHaveAura(spell, SPELL_AURA_PHASE) && !IsSpellHaveAura(spell, SPELL_AURA_PHASE_2))
|
||||
{
|
||||
sLog.outError("Spell %u defined in `spell_phase` does not have aura effect type SPELL_AURA_PHASE or SPELL_AURA_PHASE_2, useless value.", spellPhaseInfo->spellId);
|
||||
delete spellPhaseInfo;
|
||||
continue;
|
||||
}
|
||||
|
||||
spellPhaseInfo->phasemask = fields[1].GetUInt32();
|
||||
spellPhaseInfo->terrainswapmap = fields[2].GetUInt32();
|
||||
|
||||
_SpellPhaseStore[spellPhaseInfo->spellId] = spellPhaseInfo;
|
||||
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
delete result;
|
||||
|
||||
sLog.outString(">> Loaded %u spell phase dbc infos.", count);
|
||||
}
|
||||
|
||||
CreatureDataPair const* FindCreatureData::GetResult() const
|
||||
{
|
||||
if (i_spawnedData)
|
||||
|
|
|
|||
|
|
@ -448,6 +448,7 @@ enum ConditionType
|
|||
CONDITION_GENDER = 35, // 0=male, 1=female, 2=none (see enum Gender)
|
||||
CONDITION_DEAD_OR_AWAY = 36, // value1: 0=player dead, 1=player is dead (with group dead), 2=player in instance are dead, 3=creature is dead
|
||||
// value2: if != 0 only consider players in range of this value
|
||||
CONDITION_CREATURE_IN_RANGE = 37, // value1: creature entry; value2: range; returns only alive creatures
|
||||
};
|
||||
|
||||
enum ConditionSource // From where was the condition called?
|
||||
|
|
@ -462,7 +463,6 @@ enum ConditionSource // From where was th
|
|||
CONDITION_FROM_SPELL_AREA = 7, // Used to check a condition from spell_area table
|
||||
CONDITION_FROM_SPELLCLICK = 8, // Used to check a condition from npc_spellclick_spells table
|
||||
CONDITION_FROM_DBSCRIPTS = 9, // Used to check a condition from DB Scripts Engine
|
||||
CONDITION_FROM_PHASEMGR = 10, // Used to check a condition from phase manager
|
||||
};
|
||||
|
||||
class PlayerCondition
|
||||
|
|
@ -1041,7 +1041,7 @@ class ObjectMgr
|
|||
static PetNameInvalidReason CheckPetName(const std::string& name);
|
||||
static bool IsValidCharterName(const std::string& name);
|
||||
|
||||
static bool CheckDeclinedNames(std::wstring mainpart, DeclinedName const& names);
|
||||
static bool CheckDeclinedNames(const std::wstring& mainpart, DeclinedName const& names);
|
||||
|
||||
int GetIndexForLocale(LocaleConstant loc);
|
||||
LocaleConstant GetLocaleForIndex(int i);
|
||||
|
|
@ -1192,11 +1192,11 @@ class ObjectMgr
|
|||
|
||||
uint32 GetModelForRace(uint32 sourceModelId, uint32 racemask);
|
||||
/**
|
||||
* \brief: Data returned is used to compute health, mana, armor, damage of creatures. May be nullptr.
|
||||
* \brief: Data returned is used to compute health, mana, armor, damage of creatures. May be NULL.
|
||||
* \param uint32 level creature level
|
||||
* \param uint32 unitClass creature class, related to CLASSMASK_ALL_CREATURES
|
||||
* \param uint32 expansion creature expansion (we could have creature exp = 0 for wotlk as well as exp = 1 or exp = 2)
|
||||
* \return: CreatureClassLvlStats const* or nullptr
|
||||
* \return: CreatureClassLvlStats const* or NULL
|
||||
*
|
||||
* Description: GetCreatureClassLvlStats give fast access to creature stats data.
|
||||
* FullName: ObjectMgr::GetCreatureClassLvlStats
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c
|
|||
m_charmInfo->SetReactState(ReactStates(fields[6].GetUInt8()));
|
||||
|
||||
uint32 savedhealth = fields[10].GetUInt32();
|
||||
uint32 savedmana = fields[11].GetUInt32();
|
||||
uint32 savedpower = fields[11].GetUInt32();
|
||||
|
||||
// set current pet as current
|
||||
// 0=current
|
||||
|
|
@ -274,17 +274,20 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c
|
|||
{
|
||||
LearnPetPassives();
|
||||
CastPetAuras(current);
|
||||
CastOwnerTalentAuras();
|
||||
}
|
||||
|
||||
Powers powerType = GetPowerType();
|
||||
|
||||
if (getPetType() == SUMMON_PET && !current) // all (?) summon pets come with full health when called, but not when they are current
|
||||
{
|
||||
SetHealth(GetMaxHealth());
|
||||
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
|
||||
SetPower(powerType, GetMaxPower(powerType));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth);
|
||||
SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana);
|
||||
SetPower(powerType, savedpower > GetMaxPower(powerType) ? GetMaxPower(powerType) : savedpower);
|
||||
}
|
||||
|
||||
AIM_Initialize();
|
||||
|
|
@ -369,7 +372,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
|||
}
|
||||
|
||||
uint32 curhealth = GetHealth();
|
||||
uint32 curmana = GetPower(POWER_MANA);
|
||||
uint32 curpower = GetPower(GetPowerType());
|
||||
|
||||
// stable and not in slot saves
|
||||
if (mode != PET_SAVE_AS_CURRENT)
|
||||
|
|
@ -423,7 +426,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
|||
savePet.addString(m_name);
|
||||
savePet.addUInt32(uint32(HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ? 0 : 1));
|
||||
savePet.addUInt32((curhealth < 1 ? 1 : curhealth));
|
||||
savePet.addUInt32(curmana);
|
||||
savePet.addUInt32(curpower);
|
||||
|
||||
std::ostringstream ss;
|
||||
for (uint32 i = ACTION_BAR_INDEX_START; i < ACTION_BAR_INDEX_END; ++i)
|
||||
|
|
@ -565,20 +568,10 @@ void Pet::RegenerateAll(uint32 update_diff)
|
|||
// regenerate focus for hunter pets or energy for deathknight's ghoul
|
||||
if (m_regenTimer <= update_diff)
|
||||
{
|
||||
switch (GetPowerType())
|
||||
{
|
||||
case POWER_FOCUS:
|
||||
case POWER_ENERGY:
|
||||
Regenerate(GetPowerType());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IsInCombat() || IsPolymorphed())
|
||||
RegenerateHealth();
|
||||
|
||||
RegenerateMana();
|
||||
RegeneratePower();
|
||||
|
||||
m_regenTimer = 4000;
|
||||
}
|
||||
|
|
@ -586,43 +579,6 @@ void Pet::RegenerateAll(uint32 update_diff)
|
|||
m_regenTimer -= update_diff;
|
||||
}
|
||||
|
||||
void Pet::Regenerate(Powers power)
|
||||
{
|
||||
uint32 curValue = GetPower(power);
|
||||
uint32 maxValue = GetMaxPower(power);
|
||||
|
||||
if (curValue >= maxValue)
|
||||
return;
|
||||
|
||||
float addvalue = 0.0f;
|
||||
|
||||
switch (power)
|
||||
{
|
||||
case POWER_FOCUS:
|
||||
{
|
||||
// For hunter pets.
|
||||
addvalue = 24 * sWorld.getConfig(CONFIG_FLOAT_RATE_POWER_FOCUS);
|
||||
break;
|
||||
}
|
||||
case POWER_ENERGY:
|
||||
{
|
||||
// For deathknight's ghoul.
|
||||
addvalue = 20;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply modifiers (if any).
|
||||
AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
|
||||
for (AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
|
||||
if ((*i)->GetModifier()->m_miscvalue == int32(power))
|
||||
addvalue *= ((*i)->GetModifier()->m_amount + 100) / 100.0f;
|
||||
|
||||
ModifyPower(power, (int32)addvalue);
|
||||
}
|
||||
|
||||
bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
|
||||
{
|
||||
uint8 activecount = 1;
|
||||
|
|
@ -1060,7 +1016,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel, Unit* owner)
|
|||
UpdateAllStats();
|
||||
|
||||
SetHealth(GetMaxHealth());
|
||||
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
|
||||
SetPower(GetPowerType(), GetMaxPower(GetPowerType()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1912,6 +1868,7 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
|
|||
return;
|
||||
|
||||
PetSpellMap::iterator itr = m_spells.find(spellid);
|
||||
PetSpell& petSpell = itr->second;
|
||||
|
||||
uint32 i;
|
||||
|
||||
|
|
@ -1924,11 +1881,11 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
|
|||
{
|
||||
m_autospells.push_back(spellid);
|
||||
|
||||
if (itr->second.active != ACT_ENABLED)
|
||||
if (petSpell.active != ACT_ENABLED)
|
||||
{
|
||||
itr->second.active = ACT_ENABLED;
|
||||
if (itr->second.state != PETSPELL_NEW)
|
||||
itr->second.state = PETSPELL_CHANGED;
|
||||
petSpell.active = ACT_ENABLED;
|
||||
if (petSpell.state != PETSPELL_NEW)
|
||||
petSpell.state = PETSPELL_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1941,11 +1898,11 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
|
|||
if (i < m_autospells.size())
|
||||
{
|
||||
m_autospells.erase(itr2);
|
||||
if (itr->second.active != ACT_DISABLED)
|
||||
if (petSpell.active != ACT_DISABLED)
|
||||
{
|
||||
itr->second.active = ACT_DISABLED;
|
||||
if (itr->second.state != PETSPELL_NEW)
|
||||
itr->second.state = PETSPELL_CHANGED;
|
||||
petSpell.active = ACT_DISABLED;
|
||||
if (petSpell.state != PETSPELL_NEW)
|
||||
petSpell.state = PETSPELL_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2042,6 +1999,44 @@ void Pet::CastPetAuras(bool current)
|
|||
}
|
||||
}
|
||||
|
||||
void Pet::CastOwnerTalentAuras()
|
||||
{
|
||||
if (!GetOwner() || GetOwner()->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player* pOwner = static_cast<Player*>(GetOwner());
|
||||
|
||||
// Handle Ferocious Inspiration Talent
|
||||
if (pOwner && pOwner->getClass() == CLASS_HUNTER)
|
||||
{
|
||||
// clear any existing Ferocious Inspiration auras
|
||||
RemoveAurasDueToSpell(75593);
|
||||
RemoveAurasDueToSpell(75446);
|
||||
RemoveAurasDueToSpell(75447);
|
||||
|
||||
if (IsAlive())
|
||||
{
|
||||
const SpellEntry* seTalent = pOwner->GetKnownTalentRankById(1800); // Ferocious Inspiration
|
||||
|
||||
if (seTalent)
|
||||
{
|
||||
switch (seTalent->Id)
|
||||
{
|
||||
case 34455: // Ferocious Inspiration Rank 1
|
||||
CastSpell(this, 75593, true); // Ferocious Inspiration 1%
|
||||
break;
|
||||
case 34459: // Ferocious Inspiration Rank 2
|
||||
CastSpell(this, 75446, true); // Ferocious Inspiration 2%
|
||||
break;
|
||||
case 34460: // Ferocious Inspiration Rank 3
|
||||
CastSpell(this, 75447, true); // Ferocious Inspiration 3%
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End Ferocious Inspiration Talent
|
||||
}
|
||||
|
||||
void Pet::CastPetAura(PetAura const* aura)
|
||||
{
|
||||
uint32 auraId = aura->GetAura(GetEntry());
|
||||
|
|
|
|||
|
|
@ -178,7 +178,6 @@ class Pet : public Creature
|
|||
}
|
||||
|
||||
void RegenerateAll(uint32 update_diff) override; // overwrite Creature::RegenerateAll
|
||||
void Regenerate(Powers power);
|
||||
void GivePetXP(uint32 xp);
|
||||
void GivePetLevel(uint32 level);
|
||||
void SynchronizeLevelWithOwner();
|
||||
|
|
@ -198,6 +197,11 @@ class Pet : public Creature
|
|||
void UpdateMaxPower(Powers power) override;
|
||||
void UpdateAttackPowerAndDamage(bool ranged = false) override;
|
||||
void UpdateDamagePhysical(WeaponAttackType attType) override;
|
||||
uint32 GetCurrentEquipmentId() const { return m_equipmentId; }
|
||||
|
||||
static float _GetHealthMod(int32 Rank); ///< Get custom factor to scale health (default 1, CONFIG_FLOAT_RATE_CREATURE_*_HP)
|
||||
static float _GetDamageMod(int32 Rank); ///< Get custom factor to scale damage (default 1, CONFIG_FLOAT_RATE_*_DAMAGE)
|
||||
static float _GetSpellDamageMod(int32 Rank); ///< Get custom factor to scale spell damage (default 1, CONFIG_FLOAT_RATE_*_SPELLDAMAGE)
|
||||
|
||||
bool CanTakeMoreActiveSpells(uint32 SpellIconID);
|
||||
void ToggleAutocast(uint32 spellid, bool apply);
|
||||
|
|
@ -209,6 +213,7 @@ class Pet : public Creature
|
|||
|
||||
void LearnPetPassives();
|
||||
void CastPetAuras(bool current);
|
||||
void CastOwnerTalentAuras();
|
||||
void CastPetAura(PetAura const* aura);
|
||||
|
||||
void _LoadSpellCooldowns();
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@
|
|||
#include "SQLStorages.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Calendar.h"
|
||||
#include "PhaseMgr.h"
|
||||
#ifdef ENABLE_ELUNA
|
||||
#include "LuaEngine.h"
|
||||
#endif /*ENABLE_ELUNA*/
|
||||
|
|
@ -568,8 +567,6 @@ Player::Player(WorldSession* session): Unit(), m_mover(this), m_camera(this), m_
|
|||
m_cachedGS = 0;
|
||||
|
||||
m_slot = 255;
|
||||
|
||||
phaseMgr = new PhaseMgr(this);
|
||||
}
|
||||
|
||||
Player::~Player()
|
||||
|
|
@ -610,8 +607,6 @@ Player::~Player()
|
|||
|
||||
delete m_declinedname;
|
||||
delete m_runes;
|
||||
|
||||
delete phaseMgr;
|
||||
}
|
||||
|
||||
void Player::CleanupsBeforeDelete()
|
||||
|
|
@ -853,6 +848,9 @@ bool Player::Create(uint32 guidlow, const std::string& name, uint8 race, uint8 c
|
|||
}
|
||||
// all item positions resolved
|
||||
|
||||
if (info->phaseMap != 0)
|
||||
CharacterDatabase.PExecute("REPLACE INTO `character_phase_data` (`guid`, `map`) VALUES (%u, %u)", guidlow, info->phaseMap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -958,7 +956,11 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
|
|||
data << uint32(resist);
|
||||
SendMessageToSet(&data, true);
|
||||
|
||||
uint32 final_damage = DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
DamageEffectType damageType = SELF_DAMAGE;
|
||||
if (type == DAMAGE_FALL && getClass() == CLASS_ROGUE)
|
||||
damageType = SELF_DAMAGE_ROGUE_FALL;
|
||||
|
||||
uint32 final_damage = DealDamage(this, damage, NULL, damageType, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
|
||||
if (!IsAlive())
|
||||
{
|
||||
|
|
@ -1390,8 +1392,8 @@ void Player::Update(uint32 update_diff, uint32 p_time)
|
|||
HandleSobering();
|
||||
}
|
||||
|
||||
// Not auto-free ghost from body in instances
|
||||
if (m_deathTimer > 0 && !GetMap()->Instanceable())
|
||||
// Not auto-free ghost from body in instances; also check for resurrection prevention
|
||||
if (m_deathTimer > 0 && !GetMap()->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
|
||||
{
|
||||
if (p_time >= m_deathTimer)
|
||||
{
|
||||
|
|
@ -2448,7 +2450,15 @@ void Player::SetGameMaster(bool on)
|
|||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
|
||||
|
||||
// restore phase
|
||||
SetPhaseMask(phaseMgr->GetCurrentPhasemask(), false);
|
||||
AuraList const& phases = GetAurasByType(SPELL_AURA_PHASE);
|
||||
AuraList const& phases2 = GetAurasByType(SPELL_AURA_PHASE_2);
|
||||
|
||||
if (!phases.empty())
|
||||
SetPhaseMask(phases.front()->GetMiscValue(), false);
|
||||
else if (!phases2.empty())
|
||||
SetPhaseMask(phases2.front()->GetMiscValue(), false);
|
||||
else
|
||||
SetPhaseMask(PHASEMASK_NORMAL, false);
|
||||
|
||||
CallForAllControlledUnits(SetGameMasterOffHelper(getFaction()), CONTROLLED_PET | CONTROLLED_TOTEMS | CONTROLLED_GUARDIANS | CONTROLLED_CHARM);
|
||||
|
||||
|
|
@ -2460,9 +2470,6 @@ void Player::SetGameMaster(bool on)
|
|||
UpdateArea(m_areaUpdateId);
|
||||
|
||||
getHostileRefManager().setOnlineOfflineState(true);
|
||||
|
||||
phaseMgr->AddUpdateFlag(PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED);
|
||||
phaseMgr->Update();
|
||||
}
|
||||
|
||||
m_camera.UpdateVisibilityForOwner();
|
||||
|
|
@ -2691,11 +2698,6 @@ void Player::GiveLevel(uint32 level)
|
|||
MailDraft(mailReward->mailTemplateId).SendMailTo(this, MailSender(MAIL_CREATURE, mailReward->senderEntry));
|
||||
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
|
||||
|
||||
PhaseUpdateData phaseUdateData;
|
||||
phaseUdateData.AddConditionType(CONDITION_LEVEL);
|
||||
|
||||
phaseMgr->NotifyConditionChanged(phaseUdateData);
|
||||
}
|
||||
|
||||
void Player::UpdateFreeTalentPoints(bool resetIfNeed)
|
||||
|
|
@ -3080,7 +3082,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
|
||||
PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED;
|
||||
|
||||
bool dependent_set = false;
|
||||
bool disabled_case = false;
|
||||
bool superceded_old = false;
|
||||
|
||||
|
|
@ -3088,6 +3089,8 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
if (itr != m_spells.end())
|
||||
{
|
||||
uint32 next_active_spell_id = 0;
|
||||
bool dependent_set = false;
|
||||
|
||||
// fix activate state for non-stackable low rank (and find next spell for !active case)
|
||||
if (sSpellMgr.IsRankedSpellNonStackableInSpellBook(spellInfo))
|
||||
{
|
||||
|
|
@ -4688,7 +4691,7 @@ void Player::KillPlayer()
|
|||
// SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_IN_PVP );
|
||||
|
||||
SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
|
||||
ApplyModByteFlag(PLAYER_FIELD_BYTES, 0, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(GetMapId())->Instanceable());
|
||||
ApplyModByteFlag(PLAYER_FIELD_BYTES, 0, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(GetMapId())->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESURRECTION));
|
||||
|
||||
// 6 minutes until repop at graveyard
|
||||
m_deathTimer = 6 * MINUTE * IN_MILLISECONDS;
|
||||
|
|
@ -6884,11 +6887,7 @@ void Player::UpdateArea(uint32 newArea)
|
|||
SetFFAPvP(false);
|
||||
}
|
||||
|
||||
phaseMgr->AddUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE);
|
||||
|
||||
UpdateAreaDependentAuras();
|
||||
|
||||
phaseMgr->RemoveUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE);
|
||||
}
|
||||
|
||||
bool Player::CanUseCapturePoint()
|
||||
|
|
@ -8498,7 +8497,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
|
|||
// 0 - Battle for Wintergrasp in progress, 1 - otherwise
|
||||
FillInitialWorldState(data, count, 0xED9, 1);
|
||||
// Time when next Battle for Wintergrasp starts
|
||||
FillInitialWorldState(data, count, 0x1102, uint32(time(nullptr) + 9000));
|
||||
FillInitialWorldState(data, count, 0x1102, uint32(time(NULL) + 9000));
|
||||
|
||||
switch (zoneid)
|
||||
{
|
||||
|
|
@ -8844,10 +8843,10 @@ InventoryResult Player::CanUnequipItems(uint32 item, uint32 count) const
|
|||
return EQUIP_ERR_OK;
|
||||
}
|
||||
}
|
||||
Bag* pBag;
|
||||
|
||||
for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
|
||||
{
|
||||
pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i);
|
||||
Bag* pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i);
|
||||
if (pBag)
|
||||
{
|
||||
for (uint32 j = 0; j < pBag->GetBagSize(); ++j)
|
||||
|
|
@ -13211,7 +13210,7 @@ void Player::SendPreparedQuest(ObjectGuid guid)
|
|||
{
|
||||
qe._Delay = 0; // TEXTEMOTE_MESSAGE; // zyg: player emote
|
||||
qe._Emote = 0; // TEXTEMOTE_HELLO; // zyg: NPC emote
|
||||
title = "";
|
||||
title.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -14423,11 +14422,6 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
|
|||
q_status.uState = QUEST_CHANGED;
|
||||
}
|
||||
|
||||
PhaseUpdateData phaseUdateData;
|
||||
phaseUdateData.AddQuestUpdate(quest_id);
|
||||
|
||||
phaseMgr->NotifyConditionChanged(phaseUdateData);
|
||||
|
||||
UpdateForQuestWorldObjects();
|
||||
}
|
||||
|
||||
|
|
@ -18965,18 +18959,14 @@ void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
|
|||
WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + m_spells.size() * 8);
|
||||
data << GetObjectGuid();
|
||||
data << uint8(0x0); // flags (0x1, 0x2)
|
||||
time_t curTime = time(NULL);
|
||||
time_t curTime = time(nullptr);
|
||||
for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
|
||||
{
|
||||
if (itr->second.state == PLAYERSPELL_REMOVED)
|
||||
continue;
|
||||
uint32 unSpellId = itr->first;
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(unSpellId);
|
||||
if (!spellInfo)
|
||||
{
|
||||
MANGOS_ASSERT(spellInfo);
|
||||
continue;
|
||||
}
|
||||
MANGOS_ASSERT(spellInfo);
|
||||
|
||||
// Not send cooldown for this spells
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR_DISABLED_WHILE_ACTIVE))
|
||||
|
|
@ -22103,6 +22093,25 @@ void Player::_LoadSkills(QueryResult* result)
|
|||
}
|
||||
}
|
||||
|
||||
uint32 Player::GetPhaseMaskForSpawn() const
|
||||
{
|
||||
uint32 phase = PHASEMASK_NORMAL;
|
||||
if (!isGameMaster())
|
||||
phase = GetPhaseMask();
|
||||
else
|
||||
{
|
||||
AuraList const& phases = GetAurasByType(SPELL_AURA_PHASE);
|
||||
if (!phases.empty())
|
||||
phase = phases.front()->GetMiscValue();
|
||||
}
|
||||
|
||||
// some aura phases include 1 normal map in addition to phase itself
|
||||
if (uint32 n_phase = phase & ~PHASEMASK_NORMAL)
|
||||
return n_phase;
|
||||
|
||||
return PHASEMASK_NORMAL;
|
||||
}
|
||||
|
||||
InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limit_count) const
|
||||
{
|
||||
ItemPrototype const* pProto = pItem->GetProto();
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class PlayerSocial;
|
|||
class DungeonPersistentState;
|
||||
class Spell;
|
||||
class Item;
|
||||
class PhaseMgr;
|
||||
|
||||
struct AreaTrigger;
|
||||
|
||||
|
|
@ -1209,7 +1208,7 @@ class Player : public Unit
|
|||
|
||||
void RemovePet(PetSaveMode mode);
|
||||
|
||||
PhaseMgr* GetPhaseMgr() { return phaseMgr; }
|
||||
uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
|
||||
|
||||
void Say(const std::string& text, const uint32 language);
|
||||
void Yell(const std::string& text, const uint32 language);
|
||||
|
|
@ -2854,8 +2853,6 @@ class Player : public Unit
|
|||
uint32 m_timeSyncServer;
|
||||
|
||||
uint32 m_cachedGS;
|
||||
|
||||
PhaseMgr* phaseMgr;
|
||||
};
|
||||
|
||||
void AddItemsSetItem(Player* player, Item* item);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ ReactorAI::MoveInLineOfSight(Unit*)
|
|||
void
|
||||
ReactorAI::AttackStart(Unit* p)
|
||||
{
|
||||
if (!p)
|
||||
if (!p || !m_creature->CanAttackByItself())
|
||||
return;
|
||||
|
||||
if (m_creature->Attack(p, true))
|
||||
|
|
|
|||
|
|
@ -142,13 +142,14 @@ void ReputationMgr::SendState(FactionState const* faction, bool anyRankIncreased
|
|||
|
||||
for (FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
|
||||
{
|
||||
if (itr->second.needSend)
|
||||
FactionState& subFaction = itr->second;
|
||||
if (subFaction.needSend)
|
||||
{
|
||||
itr->second.needSend = false;
|
||||
if (itr->second.ReputationListID != faction->ReputationListID)
|
||||
subFaction.needSend = false;
|
||||
if (subFaction.ReputationListID != faction->ReputationListID)
|
||||
{
|
||||
data << uint32(itr->second.ReputationListID);
|
||||
data << uint32(itr->second.Standing);
|
||||
data << uint32(subFaction.ReputationListID);
|
||||
data << uint32(subFaction.Standing);
|
||||
|
||||
++count;
|
||||
}
|
||||
|
|
@ -317,36 +318,39 @@ bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, in
|
|||
FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID);
|
||||
if (itr != m_factions.end())
|
||||
{
|
||||
FactionState& faction = itr->second;
|
||||
int32 BaseRep = GetBaseReputation(factionEntry);
|
||||
|
||||
if (incremental)
|
||||
standing += itr->second.Standing + BaseRep;
|
||||
standing += faction.Standing + BaseRep;
|
||||
|
||||
if (standing > Reputation_Cap)
|
||||
standing = Reputation_Cap;
|
||||
else if (standing < Reputation_Bottom)
|
||||
standing = Reputation_Bottom;
|
||||
|
||||
ReputationRank old_rank = ReputationToRank(itr->second.Standing + BaseRep);
|
||||
ReputationRank old_rank = ReputationToRank(faction.Standing + BaseRep);
|
||||
ReputationRank new_rank = ReputationToRank(standing);
|
||||
|
||||
itr->second.Standing = standing - BaseRep;
|
||||
itr->second.needSend = true;
|
||||
itr->second.needSave = true;
|
||||
faction.Standing = standing - BaseRep;
|
||||
faction.needSend = true;
|
||||
faction.needSave = true;
|
||||
|
||||
SetVisible(&itr->second);
|
||||
SetVisible(&faction);
|
||||
|
||||
if (new_rank <= REP_HOSTILE)
|
||||
SetAtWar(&itr->second, true);
|
||||
SetAtWar(&faction, true);
|
||||
|
||||
UpdateRankCounters(old_rank, new_rank);
|
||||
|
||||
m_player->ReputationChanged(factionEntry);
|
||||
m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID);
|
||||
m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID);
|
||||
m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID);
|
||||
m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID);
|
||||
m_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID);
|
||||
|
||||
AchievementMgr& achievementManager = m_player->GetAchievementMgr();
|
||||
achievementManager.UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID);
|
||||
achievementManager.UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID);
|
||||
achievementManager.UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID);
|
||||
achievementManager.UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID);
|
||||
achievementManager.UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID);
|
||||
|
||||
if (new_rank > old_rank)
|
||||
return true;
|
||||
|
|
@ -532,11 +536,12 @@ void ReputationMgr::SaveToDB()
|
|||
|
||||
for (FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
|
||||
{
|
||||
if (itr->second.needSave)
|
||||
FactionState& faction = itr->second;
|
||||
if (faction.needSave)
|
||||
{
|
||||
stmtDel.PExecute(m_player->GetGUIDLow(), itr->second.ID);
|
||||
stmtIns.PExecute(m_player->GetGUIDLow(), itr->second.ID, itr->second.Standing, itr->second.Flags);
|
||||
itr->second.needSave = false;
|
||||
stmtDel.PExecute(m_player->GetGUIDLow(), faction.ID);
|
||||
stmtIns.PExecute(m_player->GetGUIDLow(), faction.ID, faction.Standing, faction.Flags);
|
||||
faction.needSave = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,19 +138,20 @@ void PlayerSocial::SendSocialList()
|
|||
|
||||
for (PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr)
|
||||
{
|
||||
sSocialMgr.GetFriendInfo(plr, itr->first, itr->second);
|
||||
FriendInfo& friendInfo = itr->second;
|
||||
sSocialMgr.GetFriendInfo(plr, itr->first, friendInfo);
|
||||
|
||||
data << ObjectGuid(HIGHGUID_PLAYER, itr->first); // player guid
|
||||
data << uint32(itr->second.Flags); // player flag (0x1-friend?, 0x2-ignored?, 0x4-muted?)
|
||||
data << itr->second.Note; // string note
|
||||
if (itr->second.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend()
|
||||
data << uint32(friendInfo.Flags); // player flag (0x1-friend?, 0x2-ignored?, 0x4-muted?)
|
||||
data << friendInfo.Note; // string note
|
||||
if (friendInfo.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend()
|
||||
{
|
||||
data << uint8(itr->second.Status); // online/offline/etc?
|
||||
if (itr->second.Status) // if online
|
||||
data << uint8(friendInfo.Status); // online/offline/etc?
|
||||
if (friendInfo.Status) // if online
|
||||
{
|
||||
data << uint32(itr->second.Area); // player area
|
||||
data << uint32(itr->second.Level); // player level
|
||||
data << uint32(itr->second.Class); // player class
|
||||
data << uint32(friendInfo.Area); // player area
|
||||
data << uint32(friendInfo.Level); // player level
|
||||
data << uint32(friendInfo.Class); // player class
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -776,6 +776,8 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex)
|
|||
// some explicitly required script effect sets
|
||||
switch (spellproto->Id)
|
||||
{
|
||||
case 42436: // Drink!
|
||||
case 42492: // Cast Energized
|
||||
case 46650: // Open Brutallus Back Door
|
||||
case 62488: // Activate Construct
|
||||
case 64503: // Water
|
||||
|
|
@ -903,6 +905,7 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex)
|
|||
case SPELL_AURA_PERIODIC_LEECH:
|
||||
case SPELL_AURA_MOD_STALKED:
|
||||
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
|
||||
case SPELL_AURA_PREVENT_RESURRECTION:
|
||||
return false;
|
||||
case SPELL_AURA_PERIODIC_DAMAGE: // used in positive spells also.
|
||||
// part of negative spell if casted at self (prevent cancel)
|
||||
|
|
@ -2231,6 +2234,25 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
|
|||
if ((spellInfo_1->Id == 62559 && spellInfo_2->Id == 62538) ||
|
||||
(spellInfo_2->Id == 62559 && spellInfo_1->Id == 62538))
|
||||
return false;
|
||||
|
||||
// Phase 2 Transform and Shadowy Barrier
|
||||
if ((spellInfo_1->Id == 65157 && spellInfo_2->Id == 64775) ||
|
||||
(spellInfo_2->Id == 65157 && spellInfo_1->Id == 64775))
|
||||
return false;
|
||||
|
||||
// Empowered (dummy) and Empowered
|
||||
if ((spellInfo_1->Id == 64161 && spellInfo_2->Id == 65294) ||
|
||||
(spellInfo_2->Id == 64161 && spellInfo_1->Id == 65294))
|
||||
return false;
|
||||
|
||||
// Spectral Realm (reaction) and Spectral Realm (invisibility)
|
||||
if ((spellInfo_1->Id == 44852 && spellInfo_2->Id == 46021) ||
|
||||
(spellInfo_2->Id == 44852 && spellInfo_1->Id == 46021))
|
||||
return false;
|
||||
|
||||
// Halls of Reflection Clone
|
||||
if (spellInfo_1->SpellIconID == 692 && spellInfo_2->SpellIconID == 692)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_MAGE:
|
||||
|
|
@ -3489,7 +3511,11 @@ void SpellMgr::LoadSpellScriptTarget()
|
|||
spellEffect->EffectImplicitTargetA == TARGET_AREAEFFECT_GO_AROUND_SOURCE ||
|
||||
spellEffect->EffectImplicitTargetB == TARGET_AREAEFFECT_GO_AROUND_SOURCE ||
|
||||
spellEffect->EffectImplicitTargetA == TARGET_AREAEFFECT_GO_AROUND_DEST ||
|
||||
spellEffect->EffectImplicitTargetB == TARGET_AREAEFFECT_GO_AROUND_DEST)
|
||||
spellEffect->EffectImplicitTargetB == TARGET_AREAEFFECT_GO_AROUND_DEST ||
|
||||
spellEffect->EffectImplicitTargetA == TARGET_NARROW_FRONTAL_CONE ||
|
||||
spellEffect->EffectImplicitTargetB == TARGET_NARROW_FRONTAL_CONE ||
|
||||
spellEffect->EffectImplicitTargetA == TARGET_NARROW_FRONTAL_CONE_2 ||
|
||||
spellEffect->EffectImplicitTargetB == TARGET_NARROW_FRONTAL_CONE_2)
|
||||
{
|
||||
targetfound = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1128,8 +1128,8 @@ class SpellMgr
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 IsHighRankOfSpell(uint32 spell1, uint32 spell2) const
|
||||
|
||||
bool IsHighRankOfSpell(uint32 spell1, uint32 spell2) const
|
||||
{
|
||||
SpellChainMap::const_iterator itr = mSpellChains.find(spell1);
|
||||
|
||||
|
|
|
|||
|
|
@ -217,3 +217,11 @@ void TemporarySummon::UnSummon()
|
|||
void TemporarySummon::SaveToDB()
|
||||
{
|
||||
}
|
||||
|
||||
TemporarySummonWaypoint::TemporarySummonWaypoint(ObjectGuid summoner, uint32 waypoint_id, int32 path_id, uint32 pathOrigin) :
|
||||
TemporarySummon(summoner),
|
||||
m_waypoint_id(waypoint_id),
|
||||
m_path_id(path_id),
|
||||
m_pathOrigin(pathOrigin)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,4 +55,20 @@ class TemporarySummon : public Creature
|
|||
uint32 m_lifetime;
|
||||
ObjectGuid m_summoner;
|
||||
};
|
||||
|
||||
class TemporarySummonWaypoint : public TemporarySummon
|
||||
{
|
||||
public:
|
||||
explicit TemporarySummonWaypoint(ObjectGuid summoner, uint32 waypoint_id, int32 path_id, uint32 pathOrigin);
|
||||
|
||||
uint32 GetWaypointId() const { return m_waypoint_id; }
|
||||
int32 GetPathId() const { return m_path_id; }
|
||||
uint32 GetPathOrigin() const { return m_pathOrigin; }
|
||||
|
||||
private:
|
||||
uint32 m_waypoint_id;
|
||||
int32 m_path_id;
|
||||
uint32 m_pathOrigin;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -189,8 +189,13 @@ void Totem::SetTypeBySummonSpell(SpellEntry const* spellProto)
|
|||
|
||||
bool Totem::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const
|
||||
{
|
||||
// Totem may affected by some specific spells
|
||||
// Mana Spring, Healing stream, Mana tide
|
||||
// Flags : 0x00000002000 | 0x00000004000 | 0x00004000000 -> 0x00004006000
|
||||
if (spellInfo->GetSpellFamilyName() == SPELLFAMILY_SHAMAN && spellInfo->IsFitToFamilyMask(UI64LIT(0x00004006000)))
|
||||
return false;
|
||||
SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(index);
|
||||
if(spellEffect)
|
||||
if (spellEffect)
|
||||
{
|
||||
// TODO: possibly all negative auras immune?
|
||||
switch(spellEffect->Effect)
|
||||
|
|
|
|||
|
|
@ -883,14 +883,12 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||
// remove affects from attacker at any non-DoT damage (including 0 damage)
|
||||
if (damagetype != DOT)
|
||||
{
|
||||
RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
if (damagetype != SELF_DAMAGE_ROGUE_FALL)
|
||||
RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
if (pVictim != this)
|
||||
RemoveSpellsCausingAura(SPELL_AURA_MOD_INVISIBILITY);
|
||||
|
||||
if (pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->IsStandState() && !pVictim->hasUnitState(UNIT_STAT_STUNNED))
|
||||
{ pVictim->SetStandState(UNIT_STAND_STATE_STAND); }
|
||||
pVictim->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
}
|
||||
|
||||
if (!damage)
|
||||
|
|
@ -952,7 +950,7 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||
|
||||
((Creature*)pVictim)->SetLootRecipient(this);
|
||||
|
||||
JustKilledCreature((Creature*)pVictim, nullptr);
|
||||
JustKilledCreature((Creature*)pVictim, NULL);
|
||||
pVictim->SetHealth(0);
|
||||
|
||||
return damage;
|
||||
|
|
@ -978,7 +976,7 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||
{
|
||||
SpellEntry const* shareSpell = (*itr)->GetSpellProto();
|
||||
uint32 shareDamage = uint32(damage*(*itr)->GetModifier()->m_amount / 100.0f);
|
||||
DealDamageMods(shareTarget, shareDamage, nullptr);
|
||||
DealDamageMods(shareTarget, shareDamage, NULL);
|
||||
DealDamage(shareTarget, shareDamage, 0, damagetype, GetSpellSchoolMask(shareSpell), shareSpell, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -4335,7 +4333,7 @@ bool Unit::AddSpellAuraHolder(SpellAuraHolder* holder)
|
|||
|
||||
switch (aurNameReal)
|
||||
{
|
||||
// DoT/HoT/etc
|
||||
// DoT/HoT/etc
|
||||
case SPELL_AURA_DUMMY: // allow stack
|
||||
case SPELL_AURA_PERIODIC_DAMAGE:
|
||||
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
|
||||
|
|
@ -4346,7 +4344,7 @@ bool Unit::AddSpellAuraHolder(SpellAuraHolder* holder)
|
|||
case SPELL_AURA_OBS_MOD_MANA:
|
||||
case SPELL_AURA_POWER_BURN_MANA:
|
||||
case SPELL_AURA_CONTROL_VEHICLE:
|
||||
case SPELL_AURA_284: // SPELL_AURA_LINKED_AURA, unknown how it is handled, but let it stack like vehicle control aura
|
||||
case SPELL_AURA_TRIGGER_LINKED_AURA:
|
||||
case SPELL_AURA_PERIODIC_DUMMY:
|
||||
break;
|
||||
case SPELL_AURA_PERIODIC_ENERGIZE: // all or self or clear non-stackable
|
||||
|
|
@ -4367,7 +4365,7 @@ bool Unit::AddSpellAuraHolder(SpellAuraHolder* holder)
|
|||
if (!IsPassiveSpell(aurSpellInfo) || !IsPassiveSpellStackableWithRanks(aurSpellInfo))
|
||||
{
|
||||
// Hack exceptions for Vehicle/Linked auras
|
||||
if (!IsSpellHaveAura(aurSpellInfo, SPELL_AURA_CONTROL_VEHICLE) && !IsSpellHaveAura(aurSpellInfo, SPELL_AURA_284) &&
|
||||
if (!IsSpellHaveAura(aurSpellInfo, SPELL_AURA_CONTROL_VEHICLE) && !IsSpellHaveAura(aurSpellInfo, SPELL_AURA_TRIGGER_LINKED_AURA) &&
|
||||
!RemoveNoStackAurasDueToAuraHolder(holder))
|
||||
{
|
||||
delete holder;
|
||||
|
|
@ -5750,8 +5748,10 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, SpellSchoolMask d
|
|||
|
||||
void Unit::SetPowerType(Powers new_powertype)
|
||||
{
|
||||
// set power type
|
||||
SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype);
|
||||
|
||||
// group updates
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (((Player*)this)->GetGroup())
|
||||
|
|
@ -5768,22 +5768,38 @@ void Unit::SetPowerType(Powers new_powertype)
|
|||
}
|
||||
}
|
||||
|
||||
switch (new_powertype)
|
||||
// special cases for power type switching (druid and pets only)
|
||||
if (GetTypeId() == TYPEID_PLAYER || (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->IsPet()))
|
||||
{
|
||||
default:
|
||||
case POWER_MANA:
|
||||
break;
|
||||
case POWER_RAGE:
|
||||
SetMaxPower(POWER_RAGE, GetCreatePowers(POWER_RAGE));
|
||||
SetPower(POWER_RAGE, 0);
|
||||
break;
|
||||
case POWER_FOCUS:
|
||||
SetMaxPower(POWER_FOCUS, GetCreatePowers(POWER_FOCUS));
|
||||
SetPower(POWER_FOCUS, GetCreatePowers(POWER_FOCUS));
|
||||
break;
|
||||
case POWER_ENERGY:
|
||||
SetMaxPower(POWER_ENERGY, GetCreatePowers(POWER_ENERGY));
|
||||
break;
|
||||
uint32 maxValue = GetCreatePowers(new_powertype);
|
||||
uint32 curValue = maxValue;
|
||||
|
||||
// special cases with current power = 0
|
||||
switch (new_powertype)
|
||||
{
|
||||
case POWER_RAGE:
|
||||
case POWER_RUNE:
|
||||
case POWER_RUNIC_POWER:
|
||||
curValue = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// set power (except for mana)
|
||||
if (new_powertype != POWER_MANA)
|
||||
{
|
||||
SetMaxPower(new_powertype, maxValue);
|
||||
SetPower(new_powertype, curValue);
|
||||
}
|
||||
|
||||
// send power type update to client
|
||||
WorldPacket data(SMSG_POWER_UPDATE);
|
||||
data << GetPackGUID();
|
||||
data << uint32(1); // power count
|
||||
data << uint8(new_powertype);
|
||||
data << uint32(curValue);
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6717,7 +6733,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u
|
|||
|
||||
// Creature damage
|
||||
if (GetTypeId() == TYPEID_UNIT && !((Creature*)this)->IsPet())
|
||||
DoneTotalMod *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->Rank);
|
||||
DoneTotalMod *= ((Creature*)this)->_GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->Rank);
|
||||
|
||||
AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
|
||||
for (AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
|
||||
|
|
@ -9269,6 +9285,10 @@ void Unit::SetDeathState(DeathState s)
|
|||
if (IsVehicle())
|
||||
m_vehicleInfo->RemoveAccessoriesFromMap();
|
||||
|
||||
// Unboard from transport
|
||||
if (GetTransportInfo() && ((Unit*)GetTransportInfo()->GetTransport())->IsVehicle())
|
||||
((Unit*)GetTransportInfo()->GetTransport())->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE, GetObjectGuid());
|
||||
|
||||
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
|
||||
ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
|
||||
// remove aurastates allowing special moves
|
||||
|
|
@ -10417,14 +10437,14 @@ uint32 Unit::GetCreatePowers(Powers power) const
|
|||
{
|
||||
case POWER_HEALTH: return 0; // is it really should be here?
|
||||
case POWER_MANA: return GetCreateMana();
|
||||
case POWER_RAGE: return 1000;
|
||||
case POWER_RAGE: return POWER_RAGE_DEFAULT;
|
||||
case POWER_FOCUS:
|
||||
if(GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_HUNTER)
|
||||
return 100;
|
||||
return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100);
|
||||
case POWER_ENERGY: return 100;
|
||||
case POWER_RUNE: return GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_DEATH_KNIGHT ? 8 : 0;
|
||||
case POWER_RUNIC_POWER: return GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_DEATH_KNIGHT ? 1000 : 0;
|
||||
return POWER_FOCUS_DEFAULT;
|
||||
return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : POWER_FOCUS_DEFAULT);
|
||||
case POWER_ENERGY: return POWER_ENERGY_DEFAULT;
|
||||
case POWER_RUNE: return GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_DEATH_KNIGHT ? POWER_RUNE_DEFAULT : 0;
|
||||
case POWER_RUNIC_POWER: return GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_DEATH_KNIGHT ? POWER_RUNIC_POWER_DEFAULT : 0;
|
||||
case POWER_SOUL_SHARDS: return 0;
|
||||
case POWER_ECLIPSE: return 0; // TODO: fix me
|
||||
case POWER_HOLY_POWER: return 0;
|
||||
|
|
@ -10438,9 +10458,9 @@ uint32 Unit::GetCreateMaxPowers(Powers power) const
|
|||
switch (power)
|
||||
{
|
||||
case POWER_HOLY_POWER:
|
||||
return GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_PALADIN ? 3 : 0;
|
||||
return GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_PALADIN ? POWER_HOLY_POWER_DEFAULT : 0;
|
||||
case POWER_SOUL_SHARDS:
|
||||
return GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_WARLOCK ? 3 : 0;
|
||||
return GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_WARLOCK ? POWER_SOUL_SHARDS_DEFAULT : 0;
|
||||
default:
|
||||
return GetCreatePowers(power);
|
||||
}
|
||||
|
|
@ -10593,7 +10613,6 @@ void CharmInfo::InitCharmCreateSpells()
|
|||
bool onlyselfcast = true;
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
|
||||
|
||||
if (!spellInfo) onlyselfcast = false;
|
||||
for (uint32 i = 0; i < 3 && onlyselfcast; ++i) // nonexistent spell will not make any problems as onlyselfcast would be false -> break right away
|
||||
{
|
||||
SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i));
|
||||
|
|
@ -10843,7 +10862,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* pTarget, uint32 procFlag,
|
|||
if (itr->second->IsDeleted())
|
||||
continue;
|
||||
|
||||
SpellProcEventEntry const* spellProcEvent = nullptr;
|
||||
SpellProcEventEntry const* spellProcEvent = NULL;
|
||||
// check if that aura is triggered by proc event (then it will be managed by proc handler)
|
||||
if (!IsTriggeredAtSpellProcEvent(pTarget, itr->second, procSpell, procFlag, procExtra, attType, isVictim, spellProcEvent))
|
||||
{
|
||||
|
|
@ -11031,8 +11050,7 @@ void Unit::StopMoving(bool forceSendStop /*=false*/)
|
|||
return;
|
||||
|
||||
Movement::MoveSplineInit init(*this);
|
||||
init.SetFacing(GetOrientation());
|
||||
init.Launch();
|
||||
init.Stop();
|
||||
}
|
||||
|
||||
void Unit::InterruptMoving(bool forceSendStop /*=false*/)
|
||||
|
|
@ -11644,6 +11662,24 @@ void Unit::SetFFAPvP(bool state)
|
|||
CallForAllControlledUnits(SetFFAPvPHelper(state), CONTROLLED_PET | CONTROLLED_TOTEMS | CONTROLLED_GUARDIANS | CONTROLLED_CHARM);
|
||||
}
|
||||
|
||||
void Unit::RestoreOriginalFaction()
|
||||
{
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)this)->setFactionForRace(getRace());
|
||||
else
|
||||
{
|
||||
Creature* creature = (Creature*)this;
|
||||
|
||||
if (creature->IsPet() || creature->IsTotem())
|
||||
{
|
||||
if (Unit* owner = GetOwner())
|
||||
setFaction(owner->getFaction());
|
||||
}
|
||||
else
|
||||
setFaction(creature->GetCreatureInfo()->FactionAlliance);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::KnockBackFrom(Unit* target, float horizontalSpeed, float verticalSpeed)
|
||||
{
|
||||
float angle = this == target ? GetOrientation() + M_PI_F : target->GetAngle(this);
|
||||
|
|
|
|||
|
|
@ -753,6 +753,7 @@ class MovementInfo
|
|||
MovementFlags GetMovementFlags() const { return MovementFlags(moveFlags); }
|
||||
void SetMovementFlags(MovementFlags f) { moveFlags = f; }
|
||||
MovementFlags2 GetMovementFlags2() const { return MovementFlags2(moveFlags2); }
|
||||
void AddMovementFlags2(MovementFlags2 f) { moveFlags2 |= f; }
|
||||
|
||||
// Position manipulations
|
||||
Position const* GetPos() const { return &pos; }
|
||||
|
|
@ -1256,13 +1257,13 @@ enum IgnoreUnitState
|
|||
// Power type values defines
|
||||
enum PowerDefaults
|
||||
{
|
||||
POWER_RAGE_DEFAULT = 1000,
|
||||
POWER_FOCUS_DEFAULT = 100,
|
||||
POWER_ENERGY_DEFAULT = 100,
|
||||
POWER_RUNE_DEFAULT = 8,
|
||||
POWER_RUNIC_POWER_DEFAULT = 1000,
|
||||
POWER_HOLY_POWER_DEFAULT = 3,
|
||||
POWER_SOUL_SHARDS_DEFAULT = 3,
|
||||
POWER_RAGE_DEFAULT = 1000,
|
||||
POWER_FOCUS_DEFAULT = 100,
|
||||
POWER_ENERGY_DEFAULT = 100,
|
||||
POWER_RUNE_DEFAULT = 8,
|
||||
POWER_RUNIC_POWER_DEFAULT = 1000,
|
||||
POWER_HOLY_POWER_DEFAULT = 3,
|
||||
POWER_SOUL_SHARDS_DEFAULT = 3,
|
||||
};
|
||||
|
||||
struct SpellProcEventEntry; // used only privately
|
||||
|
|
@ -1861,6 +1862,10 @@ class Unit : public WorldObject
|
|||
*/
|
||||
void setFaction(uint32 faction) { SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction); }
|
||||
FactionTemplateEntry const* getFactionTemplateEntry() const;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void RestoreOriginalFaction();
|
||||
/**
|
||||
* Are we hostile towards the given Unit?
|
||||
* @param unit the unit we want to check against
|
||||
|
|
@ -3384,6 +3389,7 @@ class Unit : public WorldObject
|
|||
SpellAuraProcResult HandleManaShieldAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleModResistanceAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleRemoveByDamageChanceProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleInvisibilityAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||
SpellAuraProcResult HandleNULLProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* /*triggeredByAura*/, SpellEntry const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/)
|
||||
{
|
||||
// no proc handler for this aura type
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ VehicleInfo::VehicleInfo(Unit* owner, VehicleEntry const* vehicleEntry, uint32 o
|
|||
if (IsUsableSeatForCreature(seatEntry->m_flags))
|
||||
m_creatureSeats |= 1 << i;
|
||||
|
||||
if (IsUsableSeatForPlayer(seatEntry->m_flags))
|
||||
if (IsUsableSeatForPlayer(seatEntry->m_flags, seatEntry->m_flagsB))
|
||||
m_playerSeats |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
|
@ -146,6 +146,32 @@ void VehicleInfo::Initialize()
|
|||
summoned->CastCustomSpell((Unit*)m_owner, SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, NULL, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize movement limitations
|
||||
uint32 vehicleFlags = GetVehicleEntry()->m_flags;
|
||||
Unit* pVehicle = (Unit*)m_owner;
|
||||
|
||||
if (vehicleFlags & VEHICLE_FLAG_NO_STRAFE)
|
||||
pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_NO_STRAFE);
|
||||
if (vehicleFlags & VEHICLE_FLAG_NO_JUMPING)
|
||||
pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_NO_JUMPING);
|
||||
if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDTURNING)
|
||||
pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_FULLSPEEDTURNING);
|
||||
if (vehicleFlags & VEHICLE_FLAG_ALLOW_PITCHING)
|
||||
pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_ALLOW_PITCHING);
|
||||
if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDPITCHING)
|
||||
pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_FULLSPEEDPITCHING);
|
||||
|
||||
if (vehicleFlags & VEHICLE_FLAG_FIXED_POSITION)
|
||||
pVehicle->SetRoot(true);
|
||||
|
||||
// Initialize power type based on DBC values (creatures only)
|
||||
if (pVehicle->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
if (PowerDisplayEntry const* powerEntry = sPowerDisplayStore.LookupEntry(GetVehicleEntry()->m_powerDisplayID))
|
||||
pVehicle->SetPowerType(Powers(powerEntry->power));
|
||||
}
|
||||
|
||||
m_isInitialized = true;
|
||||
}
|
||||
|
||||
|
|
@ -304,6 +330,7 @@ void VehicleInfo::UnBoard(Unit* passenger, bool changeVehicle)
|
|||
{
|
||||
Player* pPlayer = (Player*)passenger;
|
||||
pPlayer->ResummonPetTemporaryUnSummonedIfAny();
|
||||
pPlayer->SetFallInformation(0, pPlayer->GetPositionZ());
|
||||
|
||||
// SMSG_PET_DISMISS_SOUND (?)
|
||||
}
|
||||
|
|
@ -473,9 +500,13 @@ uint8 VehicleInfo::GetTakenSeatsMask() const
|
|||
return takenSeatsMask;
|
||||
}
|
||||
|
||||
bool VehicleInfo:: IsUsableSeatForPlayer(uint32 seatFlags) const
|
||||
bool VehicleInfo::IsUsableSeatForPlayer(uint32 seatFlags, uint32 seatFlagsB) const
|
||||
{
|
||||
return seatFlags & SEAT_FLAG_USABLE;
|
||||
return seatFlags & SEAT_FLAG_CAN_EXIT ||
|
||||
seatFlags & SEAT_FLAG_UNCONTROLLED ||
|
||||
seatFlagsB &
|
||||
(SEAT_FLAG_B_USABLE_FORCED | SEAT_FLAG_B_USABLE_FORCED_2 |
|
||||
SEAT_FLAG_B_USABLE_FORCED_3 | SEAT_FLAG_B_USABLE_FORCED_4);
|
||||
}
|
||||
|
||||
/// Add control and such modifiers to a passenger if required
|
||||
|
|
@ -483,10 +514,17 @@ void VehicleInfo::ApplySeatMods(Unit* passenger, uint32 seatFlags)
|
|||
{
|
||||
Unit* pVehicle = (Unit*)m_owner; // Vehicles are alawys Unit
|
||||
|
||||
if (seatFlags & SEAT_FLAG_NOT_SELECTABLE)
|
||||
passenger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
if (passenger->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Player* pPlayer = (Player*)passenger;
|
||||
|
||||
// group update
|
||||
if (pPlayer->GetGroup())
|
||||
pPlayer->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_VEHICLE_SEAT);
|
||||
|
||||
if (seatFlags & SEAT_FLAG_CAN_CONTROL)
|
||||
{
|
||||
pPlayer->GetCamera().SetView(pVehicle);
|
||||
|
|
@ -511,10 +549,13 @@ void VehicleInfo::ApplySeatMods(Unit* passenger, uint32 seatFlags)
|
|||
{
|
||||
((Creature*)pVehicle)->SetWalk(true, true);
|
||||
}
|
||||
|
||||
// set vehicle faction as per the controller faction
|
||||
((Creature*)pVehicle)->SetFactionTemporary(pPlayer->getFaction(), TEMPFACTION_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (seatFlags & (SEAT_FLAG_USABLE | SEAT_FLAG_CAN_CAST))
|
||||
if (seatFlags & SEAT_FLAG_CAN_CAST)
|
||||
{
|
||||
CharmInfo* charmInfo = pVehicle->InitCharmInfo(pVehicle);
|
||||
charmInfo->InitVehicleCreateSpells();
|
||||
|
|
@ -543,35 +584,47 @@ void VehicleInfo::RemoveSeatMods(Unit* passenger, uint32 seatFlags)
|
|||
{
|
||||
Unit* pVehicle = (Unit*)m_owner;
|
||||
|
||||
if (seatFlags & SEAT_FLAG_NOT_SELECTABLE)
|
||||
passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
if (passenger->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Player* pPlayer = (Player*)passenger;
|
||||
|
||||
// group update
|
||||
if (pPlayer->GetGroup())
|
||||
pPlayer->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_VEHICLE_SEAT);
|
||||
|
||||
if (seatFlags & SEAT_FLAG_CAN_CONTROL)
|
||||
{
|
||||
pPlayer->SetCharm(NULL);
|
||||
pPlayer->SetCharm(nullptr);
|
||||
pVehicle->SetCharmerGuid(ObjectGuid());
|
||||
|
||||
pPlayer->SetClientControl(pVehicle, 0);
|
||||
pPlayer->SetMover(NULL);
|
||||
pPlayer->SetMover(nullptr);
|
||||
|
||||
pVehicle->clearUnitState(UNIT_STAT_CONTROLLED);
|
||||
pVehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
|
||||
// must be called after movement control unapplying
|
||||
pPlayer->GetCamera().ResetView();
|
||||
|
||||
// reset vehicle faction
|
||||
if (pVehicle->GetTypeId() == TYPEID_UNIT)
|
||||
((Creature*)pVehicle)->ClearTemporaryFaction();
|
||||
}
|
||||
|
||||
if (seatFlags & (SEAT_FLAG_USABLE | SEAT_FLAG_CAN_CAST))
|
||||
if (seatFlags & SEAT_FLAG_CAN_CAST)
|
||||
pPlayer->RemovePetActionBar();
|
||||
}
|
||||
else if (passenger->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
if (seatFlags & SEAT_FLAG_CAN_CONTROL)
|
||||
{
|
||||
passenger->SetCharm(NULL);
|
||||
passenger->SetCharm(nullptr);
|
||||
pVehicle->SetCharmerGuid(ObjectGuid());
|
||||
}
|
||||
|
||||
// Reinitialize movement
|
||||
((Creature*)passenger)->AI()->SetCombatMovement(true, true);
|
||||
if (!passenger->getVictim())
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ class VehicleInfo : public TransportBase
|
|||
~VehicleInfo();
|
||||
|
||||
VehicleEntry const* GetVehicleEntry() const { return m_vehicleEntry; }
|
||||
VehicleSeatEntry const* GetSeatEntry(uint8 seat) const;
|
||||
|
||||
void Board(Unit* passenger, uint8 seat); // Board a passenger to a vehicle
|
||||
void SwitchSeat(Unit* passenger, uint8 seat); // Used to switch seats of a passenger
|
||||
|
|
@ -89,7 +90,6 @@ class VehicleInfo : public TransportBase
|
|||
void CalculateBoardingPositionOf(float gx, float gy, float gz, float go, float& lx, float& ly, float& lz, float& lo) const;
|
||||
|
||||
// Seat information
|
||||
VehicleSeatEntry const* GetSeatEntry(uint8 seat) const;
|
||||
bool GetUsableSeatFor(Unit* passenger, uint8& seat) const;
|
||||
bool IsSeatAvailableFor(Unit* passenger, uint8 seat) const;
|
||||
|
||||
|
|
@ -97,8 +97,8 @@ class VehicleInfo : public TransportBase
|
|||
uint8 GetEmptySeatsMask() const { return ~GetTakenSeatsMask(); }
|
||||
uint8 GetEmptySeats() const { return m_vehicleSeats.size() - m_passengers.size(); }
|
||||
|
||||
bool IsUsableSeatForPlayer(uint32 seatFlags) const;
|
||||
bool IsUsableSeatForCreature(uint32 seatFlags) const { return true; } // special flag?, !IsUsableSeatForPlayer(seatFlags)?
|
||||
bool IsUsableSeatForPlayer(uint32 seatFlags, uint32 seatFlagsB) const;
|
||||
bool IsUsableSeatForCreature(uint32 /*seatFlags*/) const { return true; } // special flag?, !IsUsableSeatForPlayer(seatFlags)?
|
||||
|
||||
// Apply/ Remove Controlling of the vehicle
|
||||
void ApplySeatMods(Unit* passenger, uint32 seatFlags);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue