aboutsummaryrefslogtreecommitdiff
path: root/src/game/Player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r--src/game/Player.cpp261
1 files changed, 146 insertions, 115 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index ec882ef1154..11ffba972a3 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -799,7 +799,7 @@ void Player::StopMirrorTimer(MirrorTimerType Type)
GetSession()->SendPacket( &data );
}
-void Player::EnvironmentalDamage(uint64 guid, EnvironmentalDamageType type, uint32 damage)
+void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 damage)
{
WorldPacket data(SMSG_ENVIRONMENTALDAMAGELOG, (21));
data << (uint64)guid;
@@ -1641,7 +1641,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
else
{
// far teleport to another map
- Map* oldmap = IsInWorld() ? MapManager::Instance().GetMap(GetMapId(), this) : NULL;
+ Map* oldmap = IsInWorld() ? GetMap() : NULL;
// check if we can enter before stopping combat / removing pet / totems / interrupting spells
// Check enter rights before map getting to avoid creating instance copy for player
@@ -3750,7 +3750,7 @@ void Player::SendDelayResponse(const uint32 ml_seconds)
GetSession()->SendPacket( &data );
}
-void Player::ResurrectPlayer(float restore_percent, bool updateToWorld, bool applySickness)
+void Player::ResurrectPlayer(float restore_percent, bool applySickness)
{
WorldPacket data(SMSG_DEATH_RELEASE_LOC, 4*4); // remove spirit healer position
data << uint32(-1);
@@ -4281,7 +4281,7 @@ void Player::UpdateDefense()
}
}
-void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply, bool affectStats)
+void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply)
{
if(modGroup >= BASEMOD_END || modType >= MOD_END)
{
@@ -5243,7 +5243,7 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele
return false;
}
- Map *m = MapManager::Instance().GetMap(GetMapId(), this);
+ Map *m = GetMap();
const float old_x = GetPositionX();
const float old_y = GetPositionY();
@@ -5261,7 +5261,7 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele
m->PlayerRelocation(this, x, y, z, orientation);
// reread after Map::Relocation
- m = MapManager::Instance().GetMap(GetMapId(), this);
+ m = GetMap();
x = GetPositionX();
y = GetPositionY();
z = GetPositionZ();
@@ -6176,7 +6176,9 @@ uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)
if(!result)
return 0;
- return (*result)[0].GetUInt32();
+ uint32 id = (*result)[0].GetUInt32();
+ delete result;
+ return id;
}
uint32 Player::GetZoneIdFromDB(uint64 guid)
@@ -6707,7 +6709,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
SetBaseWeaponDamage(attType, MAXDAMAGE, damage);
}
- if(!IsUseEquippedWeapon(slot==EQUIPMENT_SLOT_MAINHAND))
+ if(!IsUseEquipedWeapon(slot==EQUIPMENT_SLOT_MAINHAND))
return;
if (proto->Delay)
@@ -8485,7 +8487,7 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) cons
if(!useable)
return item;
- if( item->IsBroken() || !IsUseEquippedWeapon(attackType==BASE_ATTACK) )
+ if( item->IsBroken() || !IsUseEquipedWeapon(attackType==BASE_ATTACK) )
return NULL;
return item;
@@ -8640,6 +8642,7 @@ bool Player::IsValidPos( uint8 bag, uint8 slot )
return false;
}
+
bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const
{
uint32 tempcount = 0;
@@ -10155,7 +10158,7 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
if( pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP ||
pItem->GetProto()->Bonding == BIND_QUEST_ITEM ||
- pItem->GetProto()->Bonding == BIND_WHEN_EQUIPPED && IsBagPos(pos) )
+ pItem->GetProto()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos) )
pItem->SetBinding( true );
if( bag == INVENTORY_SLOT_BAG_0 )
@@ -10201,7 +10204,7 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
{
if( pItem2->GetProto()->Bonding == BIND_WHEN_PICKED_UP ||
pItem2->GetProto()->Bonding == BIND_QUEST_ITEM ||
- pItem2->GetProto()->Bonding == BIND_WHEN_EQUIPPED && IsBagPos(pos) )
+ pItem2->GetProto()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos) )
pItem2->SetBinding( true );
pItem2->SetCount( pItem2->GetCount() + count );
@@ -10403,7 +10406,7 @@ void Player::VisualizeItem( uint8 slot, Item *pItem)
return;
// check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
- if( pItem->GetProto()->Bonding == BIND_WHEN_EQUIPPED || pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetProto()->Bonding == BIND_QUEST_ITEM )
+ if( pItem->GetProto()->Bonding == BIND_WHEN_EQUIPED || pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetProto()->Bonding == BIND_QUEST_ITEM )
pItem->SetBinding( true );
sLog.outDebug( "STORAGE: EquipItem slot = %u, item = %u", slot, pItem->GetEntry());
@@ -10548,8 +10551,6 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update )
if(pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow());
- ItemPrototype const *pProto = pItem->GetProto();
-
RemoveEnchantmentDurations(pItem);
RemoveItemDurations(pItem);
@@ -14207,7 +14208,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i)
SetUInt32Value(i, 0);
- //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
if(result)
{
@@ -14217,10 +14218,11 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
uint64 caster_guid = fields[0].GetUInt64();
uint32 spellid = fields[1].GetUInt32();
uint32 effindex = fields[2].GetUInt32();
- int32 damage = (int32)fields[3].GetUInt32();
- int32 maxduration = (int32)fields[4].GetUInt32();
- int32 remaintime = (int32)fields[5].GetUInt32();
- int32 remaincharges = (int32)fields[6].GetUInt32();
+ uint32 stackcount = fields[3].GetUInt32();
+ int32 damage = (int32)fields[4].GetUInt32();
+ int32 maxduration = (int32)fields[5].GetUInt32();
+ int32 remaintime = (int32)fields[6].GetUInt32();
+ int32 remaincharges = (int32)fields[7].GetUInt32();
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
if(!spellproto)
@@ -14257,11 +14259,15 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
continue;
- Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
- if(!damage)
- damage = aura->GetModifier()->m_amount;
- aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
- AddAura(aura);
+ for(uint32 i=0; i<stackcount; i++)
+ {
+ Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
+ if(!damage)
+ damage = aura->GetModifier()->m_amount;
+ aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
+ AddAura(aura);
+ sLog.outString("Added aura spellid %u, effect %u", spellproto->Id, effindex);
+ }
}
while( result->NextRow() );
@@ -15320,31 +15326,54 @@ void Player::_SaveAuras()
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
AuraMap const& auras = GetAuras();
- for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+
+ if (auras.empty())
+ return;
+
+ spellEffectPair lastEffectPair = auras.begin()->first;
+ uint32 stackCounter = 1;
+
+ for(AuraMap::const_iterator itr = auras.begin(); ; ++itr)
{
- SpellEntry const *spellInfo = itr->second->GetSpellProto();
+ if(itr == auras.end() || lastEffectPair != itr->first)
+ {
+ AuraMap::const_iterator itr2 = itr;
+ // save previous spellEffectPair to db
+ itr2--;
+ SpellEntry const *spellInfo = itr2->second->GetSpellProto();
- //skip all auras from spells that are passive or need a shapeshift
- if (itr->second->IsPassive() || itr->second->IsRemovedOnShapeLost())
- continue;
+ //skip all auras from spells that are passive or need a shapeshift
+ if (!(itr2->second->IsPassive() || itr2->second->IsRemovedOnShapeLost()))
+ {
+ //do not save single target auras (unless they were cast by the player)
+ if (!(itr2->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo)))
+ {
+ uint8 i;
+ // or apply at cast SPELL_AURA_MOD_SHAPESHIFT or SPELL_AURA_MOD_STEALTH auras
+ for (i = 0; i < 3; i++)
+ if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT ||
+ spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH)
+ break;
- //do not save single target auras (unless they were cast by the player)
- if (itr->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo))
- continue;
+ if (i == 3)
+ {
+ CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) "
+ "VALUES ('%u', '" I64FMTD "' ,'%u', '%u', '%u', '%d', '%d', '%d', '%d')",
+ GetGUIDLow(), itr2->second->GetCasterGUID(), (uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->m_procCharges));
+ }
+ }
+ }
- uint8 i;
- // or apply at cast SPELL_AURA_MOD_SHAPESHIFT or SPELL_AURA_MOD_STEALTH auras
- for (i = 0; i < 3; i++)
- if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT ||
- spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH)
+ if(itr == auras.end())
break;
+ }
- if (i == 3)
+ if (lastEffectPair == itr->first)
+ stackCounter++;
+ else
{
- CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u' and spell = '%u' and effect_index= '%u'",GetGUIDLow(),(uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex());
- CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges) "
- "VALUES ('%u', '" I64FMTD "' ,'%u', '%u', '%d', '%d', '%d', '%d')",
- GetGUIDLow(), itr->second->GetCasterGUID(), (uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex(), (*itr).second->GetModifier()->m_amount,int((*itr).second->GetAuraMaxDuration()),int((*itr).second->GetAuraDuration()),int((*itr).second->m_procCharges));
+ lastEffectPair = itr->first;
+ stackCounter = 1;
}
}
}
@@ -17910,7 +17939,7 @@ void Player::learnSkillRewardedSpells(uint32 skill_id )
if (pAbility->classmask && !(pAbility->classmask & classMask))
continue;
- if (SpellEntry const* spellentry = sSpellStore.LookupEntry(pAbility->spellId))
+ if (sSpellStore.LookupEntry(pAbility->spellId))
{
// Ok need learn spell
learnSpell(pAbility->spellId);
@@ -18323,7 +18352,6 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
Player* member_with_max_level = NULL;
Player* not_gray_member_with_max_level = NULL;
- // gets the max member level of the group, and the max member level that still gets XP
pGroup->GetDataForXPAtKill(pVictim,count,sum_level,member_with_max_level,not_gray_member_with_max_level);
if(member_with_max_level)
@@ -18332,7 +18360,7 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
// also no XP gained if there is no member below gray level
xp = (PvP || !not_gray_member_with_max_level) ? 0 : Trinity::XP::Gain(not_gray_member_with_max_level, pVictim);
- // skip in check PvP case (for speed, not used)
+ /// skip in check PvP case (for speed, not used)
bool is_raid = PvP ? false : sMapStore.LookupEntry(GetMapId())->IsRaid() && pGroup->isRaidGroup();
bool is_dungeon = PvP ? false : sMapStore.LookupEntry(GetMapId())->IsDungeon();
float group_rate = Trinity::XP::xp_in_group_rate(count,is_raid);
@@ -18660,70 +18688,82 @@ void Player::SetCanBlock( bool value )
UpdateBlockPercentage();
}
-void Player::HandleFallDamage(MovementInfo& movementInfo)
+bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
{
- //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored
- if (!isInFlight() && movementInfo.fallTime > 1100 && !isDead() && !isGameMaster() &&
- !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) &&
- !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) )
- {
- //Safe fall, fall time reduction
- int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
- uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0;
-
- if(fall_time > 1100) //Prevent damage if fall time < 1100
- {
- //Fall Damage calculation
- float fallperc = float(fall_time)/1100;
- uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
-
- float height = movementInfo.z;
- UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
-
- if (damage > 0)
- {
- //Prevent fall damage from being more than the player maximum health
- if (damage > GetMaxHealth())
- damage = GetMaxHealth();
-
- // Gust of Wind
- if (GetDummyAura(43621))
- damage = GetMaxHealth()/2;
-
- EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage);
- }
-
- //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
- DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
- }
- }
+ for(ItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end();++itr)
+ if(itr->pos == pos)
+ return true;
+ return false;
}
-void Player::HandleFallUnderMap()
-{
- if(InBattleGround() && GetBattleGround()
- && GetBattleGround()->HandlePlayerUnderMap(this))
- {
- // do nothing, the handle already did if returned true
- }
- else
- {
- // NOTE: this is actually called many times while falling
- // even after the player has been teleported away
- // TODO: discard movement packets after the player is rooted
- if(isAlive())
- {
- EnvironmentalDamage(GetGUID(),DAMAGE_FALL_TO_VOID, GetMaxHealth());
- // change the death state to CORPSE to prevent the death timer from
- // starting in the next player update
- KillPlayer();
- BuildPlayerRepop();
- }
-
- // cancel the death timer here if started
- RepopAtGraveyard();
- }
-}
+//***********************************
+//-------------TRINITY---------------
+//***********************************
+
+void Player::HandleFallDamage(MovementInfo& movementInfo)
+{
+ //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored
+ if (!isInFlight() && movementInfo.fallTime > 1100 && !isDead() && !isGameMaster() &&
+ !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) &&
+ !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) )
+ {
+ //Safe fall, fall time reduction
+ int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
+ uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0;
+
+ if(fall_time > 1100) //Prevent damage if fall time < 1100
+ {
+ //Fall Damage calculation
+ float fallperc = float(fall_time)/1100;
+ uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
+
+ float height = movementInfo.z;
+ UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
+
+ if (damage > 0)
+ {
+ //Prevent fall damage from being more than the player maximum health
+ if (damage > GetMaxHealth())
+ damage = GetMaxHealth();
+
+ // Gust of Wind
+ if (GetDummyAura(43621))
+ damage = GetMaxHealth()/2;
+
+ EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage);
+ }
+
+ //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
+ DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
+ }
+ }
+}
+
+void Player::HandleFallUnderMap()
+{
+ if(InBattleGround() && GetBattleGround()
+ && GetBattleGround()->HandlePlayerUnderMap(this))
+ {
+ // do nothing, the handle already did if returned true
+ }
+ else
+ {
+ // NOTE: this is actually called many times while falling
+ // even after the player has been teleported away
+ // TODO: discard movement packets after the player is rooted
+ if(isAlive())
+ {
+ EnvironmentalDamage(GetGUID(),DAMAGE_FALL_TO_VOID, GetMaxHealth());
+ // change the death state to CORPSE to prevent the death timer from
+ // starting in the next player update
+ KillPlayer();
+ BuildPlayerRepop();
+ }
+
+ // cancel the death timer here if started
+ RepopAtGraveyard();
+ }
+}
void Player::Possess(Unit *target)
{
@@ -18961,15 +19001,6 @@ bool Player::isAllowUseBattleGroundObject()
);
}
-bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
-{
- for(ItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end();++itr)
- if(itr->pos == this->pos)
- return true;
-
- return false;
-}
-
bool Player::isTotalImmunity()
{
AuraList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);