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.cpp170
1 files changed, 100 insertions, 70 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 5b5c859097f..ea2a0224f4d 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -179,7 +179,7 @@ void PlayerTaxi::AppendTaximaskTo( ByteBuffer& data, bool all )
if(all)
{
for (uint8 i=0; i<TaxiMaskSize; i++)
- data << sTaxiNodesMask[i]; // all existed nodes
+ data << uint32(sTaxiNodesMask[i]); // all existed nodes
}
else
{
@@ -188,7 +188,7 @@ void PlayerTaxi::AppendTaximaskTo( ByteBuffer& data, bool all )
}
}
-bool PlayerTaxi::LoadTaxiDestinationsFromString( std::string values )
+bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values )
{
ClearTaxiDestinations();
@@ -489,7 +489,7 @@ void Player::CleanupsBeforeDelete()
Unit::CleanupsBeforeDelete();
}
-bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId )
+bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 class_, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId )
{
//FIXME: outfitId not used in player creating
@@ -507,13 +507,6 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
for (int i = 0; i < PLAYER_SLOTS_COUNT; i++)
m_items[i] = NULL;
- //for(int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; j++)
- //{
- // SetUInt64Value(PLAYER_FIELD_VENDORBUYBACK_SLOT_1+j*2,0);
- // SetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1+j,0);
- // SetUInt32Value(PLAYER_FIELD_BUYBACK_TIMESTAMP_1+j,0);
- //}
-
m_race = race;
m_class = class_;
@@ -859,9 +852,8 @@ void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 da
data << (uint32)damage;
data << (uint32)0;
data << (uint32)0;
- //m_session->SendPacket(&data);
- //Let other players see that you get damage
SendMessageToSet(&data, true);
+
DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
if(type==DAMAGE_FALL && !isAlive()) // DealDamage not apply item durability loss at self damage
@@ -907,7 +899,7 @@ void Player::HandleDrowning()
m_isunderwater|= 0x04;
StartMirrorTimer(BREATH_TIMER, UnderWaterTime);
}
- //continius trigger drowning "Damage"
+ //continuous trigger drowning "Damage"
if ((m_breathTimer == 0) && (m_isunderwater & 0x01))
{
//TODO: Check this formula
@@ -1029,7 +1021,7 @@ void Player::SetDrunkValue(uint16 newDrunkenValue, uint32 itemId)
return;
WorldPacket data(SMSG_CROSSED_INEBRIATION_THRESHOLD, (8+4+4));
- data << GetGUID();
+ data << uint64(GetGUID());
data << uint32(newDrunkenState);
data << uint32(itemId);
@@ -1407,7 +1399,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
*p_data << uint8(getLevel()); // player level
// do not use GetMap! it will spawn a new instance since the bound instances are not loaded
uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY());
-
+ sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId);
*p_data << zoneId;
*p_data << GetMapId();
@@ -1651,6 +1643,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
else
// this will be used instead of the current location in SaveToDB
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
+ SetFallInformation(0, z);
//BuildHeartBeatMsg(&data);
//SendMessageToSet(&data, true);
@@ -1798,6 +1791,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
}
m_teleport_dest = WorldLocation(mapid, final_x, final_y, final_z, final_o);
+ SetFallInformation(0, final_z);
// if the player is saved before worldportack (at logout for example)
// this will be used instead of the current location in SaveToDB
@@ -2119,23 +2113,23 @@ bool Player::IsInSameGroupWith(Player const* p) const
/// \todo Shouldn't we also check if there is no other invitees before disbanding the group?
void Player::UninviteFromGroup()
{
- if(GetGroupInvite()) // uninvited invitee
- {
- Group* group = GetGroupInvite();
- group->RemoveInvite(this);
+ Group* group = GetGroupInvite();
+ if(!group)
+ return;
- if(group->GetMembersCount() <= 1) // group has just 1 member => disband
- {
- if(group->IsCreated())
- {
- group->Disband(true);
- objmgr.RemoveGroup(group);
- }
- else
- group->RemoveAllInvites();
+ group->RemoveInvite(this);
- delete group;
+ if(group->GetMembersCount() <= 1) // group has just 1 member => disband
+ {
+ if(group->IsCreated())
+ {
+ group->Disband(true);
+ objmgr.RemoveGroup(group);
}
+ else
+ group->RemoveAllInvites();
+
+ delete group;
}
}
@@ -2472,7 +2466,6 @@ void Player::SendInitialSpells()
continue;
data << uint16(itr->first);
- //data << uint16(itr->second->slotId);
data << uint16(0); // it's not slot id
spellCount +=1;
@@ -2499,13 +2492,13 @@ void Player::SendInitialSpells()
data << uint16(sEntry->Category); // spell category
if(sEntry->Category) // may be wrong, but anyway better than nothing...
{
- data << uint32(0);
- data << uint32(cooldown);
+ data << uint32(0); // cooldown
+ data << uint32(cooldown); // category cooldown
}
else
{
- data << uint32(cooldown);
- data << uint32(0);
+ data << uint32(cooldown); // cooldown
+ data << uint32(0); // category cooldown
}
}
@@ -3491,7 +3484,6 @@ void Player::DestroyForPlayer( Player *target ) const
if(target == this)
{
-
for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
{
if(m_items[i] == NULL)
@@ -3682,7 +3674,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
uint32 pl_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
- WorldSession::SendReturnToSender(MAIL_NORMAL, pl_account, guid, sender, subject, itemTextId, &mi, money, 0, mailTemplateId);
+ WorldSession::SendReturnToSender(MAIL_NORMAL, pl_account, guid, sender, subject, itemTextId, &mi, money, mailTemplateId);
}
while (resultMail->NextRow());
@@ -6629,23 +6621,23 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
break;
case ITEM_MOD_AGILITY: // modify agility
HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_AGILITY, val, apply);
+ ApplyStatBuffMod(STAT_AGILITY, float(val), apply);
break;
case ITEM_MOD_STRENGTH: //modify strength
HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_STRENGTH, val, apply);
+ ApplyStatBuffMod(STAT_STRENGTH, float(val), apply);
break;
case ITEM_MOD_INTELLECT: //modify intellect
HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_INTELLECT, val, apply);
+ ApplyStatBuffMod(STAT_INTELLECT, float(val), apply);
break;
case ITEM_MOD_SPIRIT: //modify spirit
HandleStatModifier(UNIT_MOD_STAT_SPIRIT, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_SPIRIT, val, apply);
+ ApplyStatBuffMod(STAT_SPIRIT, float(val), apply);
break;
case ITEM_MOD_STAMINA: //modify stamina
HandleStatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(val), apply);
- ApplyStatBuffMod(STAT_STAMINA, val, apply);
+ ApplyStatBuffMod(STAT_STAMINA, float(val), apply);
break;
case ITEM_MOD_DEFENSE_SKILL_RATING:
ApplyRatingMod(CR_DEFENSE_SKILL, int32(val), apply);
@@ -9199,7 +9191,7 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
}
else // equipped bag
{
- // we need check 2 time (specilized/non_specialized), use NULL_BAG to prevent skipping bag
+ // we need check 2 time (specialized/non_specialized), use NULL_BAG to prevent skipping bag
res = _CanStoreItem_InBag(bag,dest,pProto,count,true,false,pItem,NULL_BAG,slot);
if(res!=EQUIP_ERR_OK)
res = _CanStoreItem_InBag(bag,dest,pProto,count,true,true,pItem,NULL_BAG,slot);
@@ -10657,7 +10649,6 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update )
if( bag == INVENTORY_SLOT_BAG_0 )
{
-
SetUInt64Value((uint16)(PLAYER_FIELD_INV_SLOT_HEAD + (slot*2)), 0);
// equipment and equipped bags can have applied bonuses
@@ -12488,7 +12479,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
if(pQuest->GetCharTitleId())
{
if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId()))
- SetFlag64(PLAYER__FIELD_KNOWN_TITLES, (uint64(1) << titleEntry->bit_index));
+ SetTitle(titleEntry);
}
// Send reward mail
@@ -13506,7 +13497,7 @@ void Player::SendQuestComplete( uint32 quest_id )
if( quest_id )
{
WorldPacket data( SMSG_QUESTUPDATE_COMPLETE, 4 );
- data << quest_id;
+ data << uint32(quest_id);
GetSession()->SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest_id );
}
@@ -13878,6 +13869,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
uint32 transGUID = fields[24].GetUInt32();
Relocate(fields[6].GetFloat(),fields[7].GetFloat(),fields[8].GetFloat(),fields[10].GetFloat());
+ SetFallInformation(0, fields[8].GetFloat());
SetMapId(fields[9].GetUInt32());
SetDifficulty(fields[32].GetUInt32()); // may be changed in _LoadGroup
@@ -14094,14 +14086,14 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
SetUInt32Value(UNIT_CHANNEL_SPELL,0);
// clear charm/summon related fields
- SetUInt64Value(UNIT_FIELD_CHARM,0);
- SetUInt64Value(UNIT_FIELD_SUMMON,0);
- SetUInt64Value(UNIT_FIELD_CHARMEDBY,0);
- SetUInt64Value(UNIT_FIELD_SUMMONEDBY,0);
- SetUInt64Value(UNIT_FIELD_CREATEDBY,0);
+ SetCharm(NULL);
+ SetPet(NULL);
+ SetCharmerGUID(NULL);
+ SetOwnerGUID(NULL);
+ SetCreatorGUID(NULL);
// reset some aura modifiers before aura apply
- SetUInt64Value(PLAYER_FARSIGHT, 0);
+ SetFarSight(NULL);
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
@@ -14186,7 +14178,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded
if(uint32 curTitle = GetUInt32Value(PLAYER_CHOSEN_TITLE))
{
- if(!HasFlag64(PLAYER__FIELD_KNOWN_TITLES,uint64(1) << curTitle))
+ if(!HasTitle(curTitle))
SetUInt32Value(PLAYER_CHOSEN_TITLE,0);
}
@@ -14801,7 +14793,7 @@ void Player::_LoadQuestStatus(QueryResult *result)
if(pQuest->GetCharTitleId())
{
if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId()))
- SetFlag64(PLAYER__FIELD_KNOWN_TITLES, (uint64(1) << titleEntry->bit_index));
+ SetTitle(titleEntry);
}
}
@@ -16116,8 +16108,8 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
m_guardianPets.erase(pet->GetGUID());
break;
default:
- if(GetPetGUID()==pet->GetGUID())
- SetPet(0);
+ if(GetPetGUID() == pet->GetGUID())
+ SetPet(NULL);
break;
}
@@ -16202,7 +16194,7 @@ void Player::Uncharm()
charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
}
-void Player::BuildPlayerChat(WorldPacket *data, uint8 msgtype, std::string text, uint32 language) const
+void Player::BuildPlayerChat(WorldPacket *data, uint8 msgtype, const std::string& text, uint32 language) const
{
*data << (uint8)msgtype;
*data << (uint32)language;
@@ -16214,28 +16206,28 @@ void Player::BuildPlayerChat(WorldPacket *data, uint8 msgtype, std::string text,
*data << (uint8)chatTag();
}
-void Player::Say(const std::string text, const uint32 language)
+void Player::Say(const std::string& text, const uint32 language)
{
WorldPacket data(SMSG_MESSAGECHAT, 200);
BuildPlayerChat(&data, CHAT_MSG_SAY, text, language);
SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),true);
}
-void Player::Yell(const std::string text, const uint32 language)
+void Player::Yell(const std::string& text, const uint32 language)
{
WorldPacket data(SMSG_MESSAGECHAT, 200);
BuildPlayerChat(&data, CHAT_MSG_YELL, text, language);
SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),true);
}
-void Player::TextEmote(const std::string text)
+void Player::TextEmote(const std::string& text)
{
WorldPacket data(SMSG_MESSAGECHAT, 200);
BuildPlayerChat(&data, CHAT_MSG_EMOTE, text, LANG_UNIVERSAL);
SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true, !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT), true );
}
-void Player::Whisper(std::string text, uint32 language,uint64 receiver)
+void Player::Whisper(const std::string& text, uint32 language,uint64 receiver)
{
if (language != LANG_ADDON) // if not addon data
language = LANG_UNIVERSAL; // whispers should always be readable
@@ -18853,10 +18845,25 @@ Player* Player::GetNextRandomRaidMember(float radius)
return nearMembers[randTarget];
}
+PartyResult Player::CanUninviteFromGroup() const
+{
+ const Group* grp = GetGroup();
+ if(!grp)
+ return PARTY_RESULT_YOU_NOT_IN_GROUP;
+
+ if(!grp->IsLeader(GetGUID()) && !grp->IsAssistant(GetGUID()))
+ return PARTY_RESULT_YOU_NOT_LEADER;
+
+ if(InBattleGround())
+ return PARTY_RESULT_INVITE_RESTRICTED;
+
+ return PARTY_RESULT_OK;
+}
+
void Player::UpdateUnderwaterState( Map* m, float x, float y, float z )
{
float water_z = m->GetWaterLevel(x,y);
- float height_z = m->GetHeight(x,y,z, false); // use .map base surface height
+ float height_z = m->GetHeight(x,y,z, false); // use .map base surface height
uint8 flag1 = m->GetTerrainType(x,y);
//!Underwater check, not in water if underground or above water level
@@ -18902,20 +18909,24 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
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() &&
+ // calculate total z distance of the fall
+ float z_diff = m_lastFallZ - movementInfo.z;
+ sLog.outDebug("zDiff = %f", z_diff);
+
+ //Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
+ // 14.57 can be calculated by resolving damageperc formular below to 0
+ if (z_diff >= 14.57f && !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
+ //Safe fall, fall height 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
+ float damageperc = 0.018f*(z_diff-safe_fall)-0.2426f;
+
+ if(damageperc >0 )
{
- //Fall Damage calculation
- float fallperc = float(fall_time)/1100;
- uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
+ uint32 damage = (uint32)(damageperc * GetMaxHealth()*sWorld.getRate(RATE_DAMAGE_FALL));
float height = movementInfo.z;
UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
@@ -19201,6 +19212,25 @@ bool Player::isAllowUseBattleGroundObject()
);
}
+bool Player::HasTitle(uint32 bitIndex)
+{
+ if (bitIndex > 128)
+ return false;
+
+ uint32 fieldIndexOffset = bitIndex/32;
+ uint32 flag = 1 << (bitIndex%32);
+ return HasFlag(PLAYER__FIELD_KNOWN_TITLES+fieldIndexOffset, flag);
+}
+
+void Player::SetTitle(CharTitlesEntry const* title)
+{
+ uint32 fieldIndexOffset = title->bit_index/32;
+ uint32 flag = 1 << (title->bit_index%32);
+ SetFlag(PLAYER__FIELD_KNOWN_TITLES+fieldIndexOffset, flag);
+}
+
+
+/*-----------------------TRINITY--------------------------*/
bool Player::isTotalImmunity()
{
AuraList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);
@@ -19255,4 +19285,4 @@ void Player::UpdateCharmedAI()
GetMotionMaster()->MoveChase(target);
Attack(target, true);
}
-} \ No newline at end of file
+}