diff options
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r-- | src/game/Player.cpp | 1349 |
1 files changed, 353 insertions, 996 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 712ecbc59ec..4b187023be4 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -64,7 +64,6 @@ #include "Spell.h" #include "SocialMgr.h" #include "GameEvent.h" -#include "AchievementMgr.h" #include <cmath> @@ -133,7 +132,7 @@ PlayerTaxi::PlayerTaxi() memset(m_taximask, 0, sizeof(m_taximask)); } -void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level) +void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 level) { // capital and taxi hub masks switch(race) @@ -150,13 +149,6 @@ void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 leve case RACE_BLOODELF: SetTaximaskNode(82); break; // Blood Elf case RACE_DRAENEI: SetTaximaskNode(94); break; // Draenei } - - switch(chrClass) - { - case CLASS_DEATH_KNIGHT: // TODO: figure out initial known nodes - break; - } - // new continent starting masks (It will be accessible only at new map) switch(Player::TeamForRace(race)) { @@ -259,7 +251,7 @@ const int32 Player::ReputationRank_Length[MAX_REPUTATION_RANK] = {36000, 3000, 3 UpdateMask Player::updateVisualBits; -Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) +Player::Player (WorldSession *session): Unit() { m_transport = 0; @@ -372,7 +364,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) m_canParry = false; m_canBlock = false; m_canDualWield = false; - m_canTitanGrip = false; m_ammoDPS = 0.0f; m_temporaryUnsummonedPetNumber = 0; @@ -417,9 +408,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) m_auraBaseMod[i][PCT_MOD] = 1.0f; } - for (int i = 0; i < MAX_COMBAT_RATING; i++) - m_baseRatingValue[i] = 0; - // Honor System m_lastHonorUpdateTime = time(NULL); @@ -433,8 +421,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) //Default movement to run mode m_unit_movement_flags = 0; - m_mover = NULL; - m_miniPet = 0; m_bgAfkReportedTimer = 0; m_contestedPvPTimer = 0; @@ -444,8 +430,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) m_isActive = true; m_farsightVision = false; - - m_runes = NULL; } Player::~Player () @@ -493,7 +477,6 @@ Player::~Player () RemovePossess(false); delete m_declinedname; - delete m_runes; } void Player::CleanupsBeforeDelete() @@ -539,9 +522,9 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 uint8 powertype = cEntry->powerType; - //uint32 unitfield; + uint32 unitfield; - /*switch(powertype) + switch(powertype) { case POWER_ENERGY: case POWER_MANA: @@ -550,16 +533,13 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 case POWER_RAGE: unitfield = 0x00110000; break; - case POWER_RUNIC_POWER: - unitfield = 0x0000EE00; //TODO: find correct unitfield here - break; default: sLog.outError("Invalid default powertype %u for player (class %u)",powertype,class_); return false; - }*/ + } - SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); - SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f); + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE ); + SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH ); switch(gender) { @@ -582,14 +562,12 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 uint32 RaceClassGender = ( race ) | ( class_ << 8 ) | ( gender << 16 ); SetUInt32Value(UNIT_FIELD_BYTES_0, ( RaceClassGender | ( powertype << 24 ) ) ); - //SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); - SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP ); - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); - SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER); + SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 ); + SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // fix cast time showed in spell tooltip on client - SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); // default for players in 3.0.3 - // -1 is default value + //-1 is default value SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); SetUInt32Value(PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24))); @@ -601,35 +579,17 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 SetUInt32Value( PLAYER_GUILD_TIMESTAMP, 0 ); SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES, 0 ); // 0=disabled - SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES1, 0 ); // 0=disabled SetUInt32Value( PLAYER_CHOSEN_TITLE, 0 ); SetUInt32Value( PLAYER_FIELD_KILLS, 0 ); SetUInt32Value( PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0 ); SetUInt32Value( PLAYER_FIELD_TODAY_CONTRIBUTION, 0 ); SetUInt32Value( PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0 ); - for(uint32 i = 0; i < sGlyphSlotStore.GetNumRows(); ++i) - { - GlyphSlotEntry const * gs = sGlyphSlotStore.LookupEntry(i); - if(gs && gs->Order) - SetGlyphSlot(gs->Order - 1, gs->Id); - } - // set starting level - uint32 start_level = getClass() != CLASS_DEATH_KNIGHT - ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL) - : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); - if (GetSession()->GetSecurity() >= SEC_MODERATOR) - { - uint32 gm_level = sWorld.getConfig(CONFIG_START_GM_LEVEL); - if(gm_level > start_level) - start_level = gm_level; - } - - SetUInt32Value(UNIT_FIELD_LEVEL, start_level); - - InitRunes(); + SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_GM_LEVEL)); + else + SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)); SetUInt32Value (PLAYER_FIELD_COINAGE, sWorld.getConfig(CONFIG_START_PLAYER_MONEY)); SetUInt32Value (PLAYER_FIELD_HONOR_CURRENCY, sWorld.getConfig(CONFIG_START_HONOR_POINTS)); @@ -693,7 +653,6 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 // base stats and related field values InitStatsForLevel(); InitTaxiNodesForLevel(); - InitGlyphsForLevel(); InitTalentForLevel(); InitPrimaryProffesions(); // to max set before any spell added @@ -706,14 +665,6 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 SetPower(POWER_MANA,GetMaxPower(POWER_MANA)); } - if(getPowerType() == POWER_RUNIC_POWER) - { - SetPower(POWER_RUNE, 8); - SetMaxPower(POWER_RUNE, 8); - SetPower(POWER_RUNIC_POWER, 0); - SetMaxPower(POWER_RUNIC_POWER, 1000); - } - // original spells learnDefaultSpells(true); @@ -757,11 +708,6 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 uint32 item_id = oEntry->ItemId[j]; - - // Hack for not existed item id in dbc 3.0.3 - if(item_id==40582) - continue; - ItemPrototype const* iProto = objmgr.GetItemPrototype(item_id); if(!iProto) { @@ -989,29 +935,53 @@ void Player::HandleDrowning() void Player::HandleLava() { + bool ValidArea = false; + if ((m_isunderwater & 0x80) && isAlive()) { - // Single trigger Set BreathTimer + //Single trigger Set BreathTimer if (!(m_isunderwater & 0x80)) { m_isunderwater|= 0x04; m_breathTimer = 1000; } - - // Reset BreathTimer and still in the lava + //Reset BreathTimer and still in the lava if (!m_breathTimer) { uint64 guid = GetGUID(); uint32 damage = urand(600, 700); // TODO: Get more detailed information about lava damage + uint32 dmgZone = GetZoneId(); // TODO: Find correct "lava dealing zone" flag in Area Table + + // Deal lava damage only in lava zones. + switch(dmgZone) + { + case 0x8D: + ValidArea = false; + break; + case 0x94: + ValidArea = false; + break; + case 0x2CE: + ValidArea = false; + break; + case 0x2CF: + ValidArea = false; + break; + default: + if (dmgZone / 5 & 0x408) + ValidArea = true; + } - // if not gamemaster then deal damage - if ( !isGameMaster() ) + // if is valid area and is not gamemaster then deal damage + if ( ValidArea && !isGameMaster() ) EnvironmentalDamage(guid, DAMAGE_LAVA, damage); m_breathTimer = 1000; } + } - else if (m_deathState == DEAD) // Disable breath timer and reset underwater flags + //Death timer disabled and WaterFlags reset + else if (m_deathState == DEAD) { m_breathTimer = 0; m_isunderwater = 0; @@ -1346,7 +1316,6 @@ void Player::Update( uint32 p_time ) Pet* pet = GetPet(); if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && !pet->isPossessed()) - //if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID()))) { RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); return; @@ -1396,7 +1365,6 @@ void Player::setDeathState(DeathState s) // passive spell if(!ressSpellId) ressSpellId = GetResurrectionSpellId(); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1); } Unit::setDeathState(s); @@ -1417,15 +1385,13 @@ void Player::setDeathState(DeathState s) void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) { - Field *fields = result->Fetch(); - - *p_data << uint64(GetGUID()); + *p_data << GetGUID(); *p_data << m_name; - *p_data << uint8(getRace()); + *p_data << getRace(); uint8 pClass = getClass(); - *p_data << uint8(pClass); - *p_data << uint8(getGender()); + *p_data << pClass; + *p_data << getGender(); uint32 bytes = GetUInt32Value(PLAYER_BYTES); *p_data << uint8(bytes); @@ -1440,15 +1406,14 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) // 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 << uint32(zoneId); - *p_data << uint32(GetMapId()); + *p_data << zoneId; + *p_data << GetMapId(); *p_data << GetPositionX(); *p_data << GetPositionY(); *p_data << GetPositionZ(); - // guild id - *p_data << (result ? fields[13].GetUInt32() : 0); + *p_data << (result ? result->Fetch()[13].GetUInt32() : 0); uint32 char_flags = 0; if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) @@ -1459,13 +1424,14 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_GHOST; if(HasAtLoginFlag(AT_LOGIN_RENAME)) char_flags |= CHARACTER_FLAG_RENAME; - if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && (fields[14].GetCppString() != "")) + // always send the flag if declined names aren't used + // to let the client select a default method of declining the name + if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[14].GetCppString() != "")) char_flags |= CHARACTER_FLAG_DECLINED; - *p_data << uint32(char_flags); // character flags - // character customize (flags?) - *p_data << uint32(HasAtLoginFlag(AT_LOGIN_CUSTOMIZE) ? 1 : 0); - *p_data << uint8(1); // unknown + *p_data << (uint32)char_flags; // character flags + + *p_data << (uint8)1; // unknown // Pets info { @@ -1476,6 +1442,8 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) // show pet at selection character in character list only for non-ghost character if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER)) { + Field* fields = result->Fetch(); + uint32 entry = fields[10].GetUInt32(); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry); if(cInfo) @@ -1486,11 +1454,36 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) } } - *p_data << uint32(petDisplayId); - *p_data << uint32(petLevel); - *p_data << uint32(petFamily); + *p_data << (uint32)petDisplayId; + *p_data << (uint32)petLevel; + *p_data << (uint32)petFamily; } + /*ItemPrototype const *items[EQUIPMENT_SLOT_END]; + for (int i = 0; i < EQUIPMENT_SLOT_END; i++) + items[i] = NULL; + + QueryResult *result = CharacterDatabase.PQuery("SELECT slot,item_template FROM character_inventory WHERE guid = '%u' AND bag = 0",GetGUIDLow()); + if (result) + { + do + { + Field *fields = result->Fetch(); + uint8 slot = fields[0].GetUInt8() & 255; + uint32 item_id = fields[1].GetUInt32(); + if( slot >= EQUIPMENT_SLOT_END ) + continue; + + items[slot] = objmgr.GetItemPrototype(item_id); + if(!items[slot]) + { + sLog.outError( "Player::BuildEnumData: Player %s have unknown item (id: #%u) in inventory, skipped.", GetName(),item_id ); + continue; + } + } while (result->NextRow()); + delete result; + }*/ + for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; slot++) { uint32 visualbase = PLAYER_VISIBLE_ITEM_1_0 + (slot * MAX_VISIBLE_ITEM_OFFSET); @@ -1507,20 +1500,20 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) if (proto != NULL) { - *p_data << uint32(proto->DisplayInfoID); - *p_data << uint8(proto->InventoryType); - *p_data << uint32(enchant ? enchant->aura_id : 0); + *p_data << (uint32)proto->DisplayInfoID; + *p_data << (uint8)proto->InventoryType; + *p_data << (uint32)(enchant?enchant->aura_id:0); } else { - *p_data << uint32(0); - *p_data << uint8(0); - *p_data << uint32(0); // enchant? + *p_data << (uint32)0; + *p_data << (uint8)0; + *p_data << (uint32)0; // enchant? } } - *p_data << uint32(0); // first bag display id - *p_data << uint8(0); // first bag inventory type - *p_data << uint32(0); // enchant? + *p_data << (uint32)0; // first bag display id + *p_data << (uint8)0; // first bag inventory type + *p_data << (uint32)0; // enchant? } bool Player::ToggleAFK() @@ -1592,7 +1585,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if(GetTransport()) RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :) - SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL, mEntry->Expansion()); + SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL1); return false; // normal client can't teleport to this map... } @@ -1901,20 +1894,13 @@ void Player::RegenerateAll() { RegenerateHealth(); if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) - { Regenerate(POWER_RAGE); - if(getClass() == CLASS_DEATH_KNIGHT) - Regenerate(POWER_RUNIC_POWER); - } } Regenerate( POWER_ENERGY ); Regenerate( POWER_MANA ); - if(getClass() == CLASS_DEATH_KNIGHT) - Regenerate( POWER_RUNE ); - m_regenTimer = regenDelay; } @@ -1934,11 +1920,11 @@ void Player::Regenerate(Powers power) if (recentCast) { // Trinity Updates Mana in intervals of 2s, which is correct - addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 2.00f; + addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT) * ManaIncreaseRate * 2.00f; } else { - addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 2.00f; + addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN) * ManaIncreaseRate * 2.00f; } } break; case POWER_RAGE: // Regenerate rage @@ -1949,17 +1935,6 @@ void Player::Regenerate(Powers power) case POWER_ENERGY: // Regenerate energy (rogue) addvalue = 20; break; - case POWER_RUNIC_POWER: - { - float RunicPowerDecreaseRate = sWorld.getRate(RATE_POWER_RUNICPOWER_LOSS); - addvalue = 30 * RunicPowerDecreaseRate; // 3 RunicPower by tick - } break; - case POWER_RUNE: - { - for(uint32 i = 0; i < MAX_RUNES; ++i) - if(uint8 cd = GetRuneCooldown(i)) // if we have cooldown, reduce it... - SetRuneCooldown(i, cd - 1); // ... by 2 sec (because update is every 2 sec) - } break; case POWER_FOCUS: case POWER_HAPPINESS: break; @@ -1975,7 +1950,7 @@ void Player::Regenerate(Powers power) addvalue *= ((*i)->GetModifierValue() + 100) / 100.0f; } - if (power != POWER_RAGE && power != POWER_RUNIC_POWER) + if (power != POWER_RAGE) { curValue += uint32(addvalue); if (curValue > maxValue) @@ -2259,8 +2234,6 @@ void Player::GiveLevel(uint32 level) data << uint32(0); data << uint32(0); data << uint32(0); - data << uint32(0); - data << uint32(0); // end for for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4) data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i))); @@ -2284,7 +2257,6 @@ void Player::GiveLevel(uint32 level) InitTalentForLevel(); InitTaxiNodesForLevel(); - InitGlyphsForLevel(); UpdateAllStats(); @@ -2304,7 +2276,6 @@ void Player::GiveLevel(uint32 level) Pet* pet = GetPet(); if(pet && pet->getPetType()==SUMMON_PET) pet->GivePetLevel(level); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); } void Player::InitTalentForLevel() @@ -2441,9 +2412,6 @@ void Player::InitStatsForLevel(bool reapplyMods) SetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER+i,0.0f); SetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,0.0f); } - // Reset no reagent cost field - for(int i = 0; i < 3; i++) - SetUInt32Value(PLAYER_NO_REAGENT_COST_1 + i, 0); // Init data for form but skip reapply item mods for form InitDataForForm(reapplyMods); @@ -2460,7 +2428,7 @@ void Player::InitStatsForLevel(bool reapplyMods) RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_SILENCED | UNIT_FLAG_PACIFIED | - UNIT_FLAG_STUNNED | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED | + UNIT_FLAG_DISABLE_ROTATE | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED | UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_SKINNABLE | UNIT_FLAG_MOUNT | UNIT_FLAG_TAXI_FLIGHT ); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); // must be set @@ -2484,7 +2452,6 @@ void Player::InitStatsForLevel(bool reapplyMods) SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE)); SetPower(POWER_FOCUS, 0); SetPower(POWER_HAPPINESS, 0); - SetPower(POWER_RUNIC_POWER, 0); } void Player::SendInitialSpells() @@ -2899,6 +2866,8 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading, continue; if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL || + // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL + pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 || // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 ) { @@ -2935,12 +2904,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading, } } - if(!loading) - { - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS); - } - // return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell return active && !disabled && !superceded_old; } @@ -3090,6 +3053,8 @@ void Player::removeSpell(uint32 spell_id, bool disabled) continue; if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL || + // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL + pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 || // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 ) { @@ -3389,46 +3354,50 @@ void Player::InitVisibleBits() { updateVisualBits.SetCount(PLAYER_END); + // TODO: really implement OWNER_ONLY and GROUP_ONLY. Flags can be found in UpdateFields.h + updateVisualBits.SetBit(OBJECT_FIELD_GUID); updateVisualBits.SetBit(OBJECT_FIELD_TYPE); - updateVisualBits.SetBit(OBJECT_FIELD_ENTRY); updateVisualBits.SetBit(OBJECT_FIELD_SCALE_X); - updateVisualBits.SetBit(UNIT_FIELD_CHARM + 0); - updateVisualBits.SetBit(UNIT_FIELD_CHARM + 1); - updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 0); - updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 1); - updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 0); - updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 1); - updateVisualBits.SetBit(UNIT_FIELD_TARGET + 0); - updateVisualBits.SetBit(UNIT_FIELD_TARGET + 1); - updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 0); - updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 1); - updateVisualBits.SetBit(UNIT_FIELD_BYTES_0); + + updateVisualBits.SetBit(UNIT_FIELD_CHARM); + updateVisualBits.SetBit(UNIT_FIELD_CHARM+1); + + updateVisualBits.SetBit(UNIT_FIELD_SUMMON); + updateVisualBits.SetBit(UNIT_FIELD_SUMMON+1); + + updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY); + updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY+1); + + updateVisualBits.SetBit(UNIT_FIELD_TARGET); + updateVisualBits.SetBit(UNIT_FIELD_TARGET+1); + + updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT); + updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT+1); + updateVisualBits.SetBit(UNIT_FIELD_HEALTH); updateVisualBits.SetBit(UNIT_FIELD_POWER1); updateVisualBits.SetBit(UNIT_FIELD_POWER2); updateVisualBits.SetBit(UNIT_FIELD_POWER3); updateVisualBits.SetBit(UNIT_FIELD_POWER4); updateVisualBits.SetBit(UNIT_FIELD_POWER5); - updateVisualBits.SetBit(UNIT_FIELD_POWER6); - updateVisualBits.SetBit(UNIT_FIELD_POWER7); + updateVisualBits.SetBit(UNIT_FIELD_MAXHEALTH); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER1); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER2); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER3); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER4); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER5); - updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER6); - updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER7); + updateVisualBits.SetBit(UNIT_FIELD_LEVEL); updateVisualBits.SetBit(UNIT_FIELD_FACTIONTEMPLATE); - updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 0); - updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 1); - updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 2); + updateVisualBits.SetBit(UNIT_FIELD_BYTES_0); updateVisualBits.SetBit(UNIT_FIELD_FLAGS); updateVisualBits.SetBit(UNIT_FIELD_FLAGS_2); + for(uint16 i = UNIT_FIELD_AURA; i < UNIT_FIELD_AURASTATE; ++i) + updateVisualBits.SetBit(i); updateVisualBits.SetBit(UNIT_FIELD_AURASTATE); - updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 0); + updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME); updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 1); updateVisualBits.SetBit(UNIT_FIELD_BOUNDINGRADIUS); updateVisualBits.SetBit(UNIT_FIELD_COMBATREACH); @@ -3441,12 +3410,10 @@ void Player::InitVisibleBits() updateVisualBits.SetBit(UNIT_DYNAMIC_FLAGS); updateVisualBits.SetBit(UNIT_CHANNEL_SPELL); updateVisualBits.SetBit(UNIT_MOD_CAST_SPEED); - updateVisualBits.SetBit(UNIT_FIELD_BASE_MANA); updateVisualBits.SetBit(UNIT_FIELD_BYTES_2); - updateVisualBits.SetBit(UNIT_FIELD_HOVERHEIGHT); - updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 0); - updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 1); + updateVisualBits.SetBit(PLAYER_DUEL_ARBITER); + updateVisualBits.SetBit(PLAYER_DUEL_ARBITER+1); updateVisualBits.SetBit(PLAYER_FLAGS); updateVisualBits.SetBit(PLAYER_GUILDID); updateVisualBits.SetBit(PLAYER_GUILDRANK); @@ -3457,29 +3424,29 @@ void Player::InitVisibleBits() updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP); // PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)... - for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += 4) + for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i+=4) updateVisualBits.SetBit(i); - // Players visible items are not inventory stuff - for(uint16 i = 0; i < EQUIPMENT_SLOT_END; ++i) + //Players visible items are not inventory stuff + //431) = 884 (0x374) = main weapon + for(uint16 i = 0; i < EQUIPMENT_SLOT_END; i++) { - uint32 offset = i * MAX_VISIBLE_ITEM_OFFSET; - // item creator - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 0 + offset); - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 1 + offset); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 0); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 1); + + uint16 visual_base = PLAYER_VISIBLE_ITEM_1_0 + (i*MAX_VISIBLE_ITEM_OFFSET); // item entry - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 0 + offset); + updateVisualBits.SetBit(visual_base + 0); - // item enchantments - for(uint8 j = 0; j < MAX_ENCHANTMENT_SLOT; ++j) - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 1 + j + offset); + // item enchantment IDs + for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) + updateVisualBits.SetBit(visual_base + 1 + j); // random properties - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + offset); - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_SEED + offset); - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PAD + offset); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 0 + (i*MAX_VISIBLE_ITEM_OFFSET)); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 1 + (i*MAX_VISIBLE_ITEM_OFFSET)); } updateVisualBits.SetBit(PLAYER_CHOSEN_TITLE); @@ -3497,6 +3464,7 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) if(target == this) { + for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) { if(m_items[i] == NULL) @@ -3504,7 +3472,7 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) m_items[i]->BuildCreateUpdateBlockForPlayer( data, target ); } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { if(m_items[i] == NULL) continue; @@ -3537,7 +3505,7 @@ void Player::DestroyForPlayer( Player *target ) const m_items[i]->DestroyForPlayer( target ); } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { if(m_items[i] == NULL) continue; @@ -3767,8 +3735,6 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC CharacterDatabase.PExecute("DELETE FROM mail_items WHERE receiver = '%u'",guid); CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u'",guid); CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid); - CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = '%u'",guid); - CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid); CharacterDatabase.CommitTransaction(); //loginDatabase.PExecute("UPDATE realmcharacters SET numchars = numchars - 1 WHERE acctid = %d AND realmid = %d", accountId, realmID); @@ -3799,10 +3765,6 @@ void Player::SetMovement(PlayerMovementType pType) */ void Player::BuildPlayerRepop() { - WorldPacket data(SMSG_PRE_RESURRECT, GetPackGUID().size()); - data.append(GetPackGUID()); - GetSession()->SendPacket(&data); - if(getRace() == RACE_NIGHTELF) CastSpell(this, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) CastSpell(this, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) @@ -3923,7 +3885,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,i)) { Aur->SetAuraDuration(delta*1000); - Aur->SendAuraUpdate(false); + Aur->UpdateAuraDuration(); } } } @@ -4460,7 +4422,7 @@ uint32 Player::GetShieldBlockValue() const { BaseModGroup modGroup = SHIELD_BLOCK_VALUE; - float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH) * 0.5f - 10; + float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH)/20 - 1; value = (value < 0) ? 0 : value; @@ -4649,18 +4611,7 @@ float Player::OCTRegenMPPerSpirit() void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply) { - m_baseRatingValue[cr]+=(apply ? value : -value); - - int32 amount = uint32(m_baseRatingValue[cr]); - // Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT - // stat used stored in miscValueB for this aura - AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT); - for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i) - if ((*i)->GetMiscValue() & (1<<cr)) - amount += GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetModifier()->m_amount / 100.0f; - if (amount < 0) - amount = 0; - SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount)); + ApplyModUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, value, apply); float RatingCoeffecient = GetRatingCoefficient(cr); float RatingChange = 0.0f; @@ -4683,13 +4634,16 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply) UpdateBlockPercentage(); break; case CR_HIT_MELEE: - UpdateMeleeHitChances(); + RatingChange = value / RatingCoeffecient; + m_modMeleeHitChance += apply ? RatingChange : -RatingChange; break; case CR_HIT_RANGED: - UpdateRangedHitChances(); + RatingChange = value / RatingCoeffecient; + m_modRangedHitChance += apply ? RatingChange : -RatingChange; break; case CR_HIT_SPELL: - UpdateSpellHitChances(); + RatingChange = value / RatingCoeffecient; + m_modSpellHitChance += apply ? RatingChange : -RatingChange; break; case CR_CRIT_MELEE: if(affectStats) @@ -4787,7 +4741,6 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step) new_value = max; SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,max)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL); return true; } @@ -4850,7 +4803,6 @@ bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLeve case SKILL_HERBALISM: case SKILL_LOCKPICKING: case SKILL_JEWELCRAFTING: - case SKILL_INSCRIPTION: return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator,gathering_skill_gain); case SKILL_SKINNING: if( sWorld.getConfig(CONFIG_SKILL_CHANCE_SKINNING_STEPS)==0) @@ -4913,7 +4865,6 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) new_value = MaxValue; SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,MaxValue)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL); sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% taken", Chance/10.0); return true; } @@ -5101,10 +5052,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal) if(i<PLAYER_MAX_SKILLS) //has skill { if(currVal) - { SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL); - } else //remove { // clear skill fields @@ -5152,7 +5100,6 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal) else SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0)); SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL); // apply skill bonuses SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0); @@ -5467,8 +5414,6 @@ void Player::CheckExploreSystem() { SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA); - AreaTableEntry const *p = GetAreaEntryByAreaFlagAndMap(areaFlag,GetMapId()); if(!p) { @@ -5565,7 +5510,6 @@ void Player::SendFactionState(FactionState const* faction) const { WorldPacket data(SMSG_SET_FACTION_STANDING, (16)); // last check 2.4.0 data << (float) 0; // unk 2.4.0 - data << (uint8) 0; // wotlk 8634 data << (uint32) 1; // count // for data << (uint32) faction->ReputationListID; @@ -5897,8 +5841,7 @@ bool Player::ModifyOneFactionReputation(FactionEntry const* factionEntry, int32 } } } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION); + SendFactionState(&(itr->second)); return true; @@ -5964,8 +5907,6 @@ bool Player::SetOneFactionReputation(FactionEntry const* factionEntry, int32 sta SetFactionAtWar(&itr->second,true); SendFactionState(&(itr->second)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION); return true; } return false; @@ -6676,43 +6617,19 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply) sLog.outDebug("_ApplyItemMods complete."); } -void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool apply) +void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply) { if(slot >= INVENTORY_SLOT_BAG_END || !proto) return; for (int i = 0; i < 10; i++) { - uint32 statType = 0; - int32 val = 0; + float val = float (proto->ItemStat[i].ItemStatValue); - if(proto->ScalingStatDistribution) - { - if(ScalingStatDistributionEntry const *ssd = sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution)) - { - statType = ssd->StatMod[i]; - - if(uint32 modifier = ssd->Modifier[i]) - { - uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel()); - if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level)) - { - int multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()]; - val = (multiplier * modifier) / 10000; - } - } - } - } - else - { - statType = proto->ItemStat[i].ItemStatType; - val = float(proto->ItemStat[i].ItemStatValue); - } - - if(val == 0) + if(val==0) continue; - switch (statType) + switch (proto->ItemStat[i].ItemStatType) { case ITEM_MOD_MANA: HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply); @@ -6830,9 +6747,6 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl case ITEM_MOD_EXPERTISE_RATING: ApplyRatingMod(CR_EXPERTISE, int32(val), apply); break; - case ITEM_MOD_ARMOR_PENETRATION_RATING: - ApplyRatingMod(CR_ARMOR_PENETRATION, int32(val), apply); - break; } } @@ -7448,17 +7362,6 @@ void Player::SendLoot(uint64 guid, LootType loot_type) loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this); } } - else if(loot_type == LOOT_MILLING) - { - loot = &item->loot; - - if(!item->m_lootGenerated) - { - item->m_lootGenerated = true; - loot->clear(); - loot->FillLoot(item->GetEntry(), LootTemplates_Milling, this); - } - } else { loot = &item->loot; @@ -7654,8 +7557,8 @@ void Player::SendLoot(uint64 guid, LootType loot_type) conditional_list = itr->second; } - // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING, LOOT_INSIGNIA and LOOT_MILLING unsupported by client, sending LOOT_SKINNING instead - if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA || loot_type == LOOT_MILLING) + // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING and LOOT_INSIGNIA unsupported by client, sending LOOT_SKINNING instead + if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA) loot_type = LOOT_SKINNING; if(loot_type == LOOT_FISHINGHOLE) @@ -8379,8 +8282,7 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap // (this will be replace mainhand weapon at auto equip instead unwonted "you don't known dual wielding" ... if(CanDualWield()) slots[1] = EQUIPMENT_SLOT_OFFHAND; - break; - }; + };break; case INVTYPE_SHIELD: slots[0] = EQUIPMENT_SLOT_OFFHAND; break; @@ -8389,8 +8291,6 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap break; case INVTYPE_2HWEAPON: slots[0] = EQUIPMENT_SLOT_MAINHAND; - if (CanDualWield() && CanTitanGrip()) - slots[1] = EQUIPMENT_SLOT_OFFHAND; break; case INVTYPE_TABARD: slots[0] = EQUIPMENT_SLOT_TABARD; @@ -8436,10 +8336,6 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap if (pClass == CLASS_WARLOCK) slots[0] = EQUIPMENT_SLOT_RANGED; break; - case ITEM_SUBCLASS_ARMOR_SIGIL: - if (pClass == CLASS_DEATH_KNIGHT) - slots[0] = EQUIPMENT_SLOT_RANGED; - break; } break; } @@ -8465,8 +8361,14 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap { if ( slots[i] != NULL_SLOT && !GetItemByPos( INVENTORY_SLOT_BAG_0, slots[i] ) ) { - // in case 2hand equipped weapon (without titan grip) offhand slot empty but not free - if(slots[i]!=EQUIPMENT_SLOT_OFFHAND || !IsTwoHandUsed()) + // in case 2hand equipped weapon offhand slot empty but not free + if(slots[i]==EQUIPMENT_SLOT_OFFHAND) + { + Item* mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); + if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON) + return slots[i]; + } + else return slots[i]; } } @@ -8516,7 +8418,7 @@ uint8 Player::CanUnequipItems( uint32 item, uint32 count ) const return EQUIP_ERR_OK; } } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->GetEntry() == item ) @@ -8558,7 +8460,7 @@ uint32 Player::GetItemCount( uint32 item, bool inBankAlso, Item* skipItem ) cons if( pItem && pItem != skipItem && pItem->GetEntry() == item ) count += pItem->GetCount(); } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem != skipItem && pItem->GetEntry() == item ) @@ -8618,7 +8520,7 @@ Item* Player::GetItemByGuid( uint64 guid ) const if( pItem && pItem->GetGUID() == guid ) return pItem; } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->GetGUID() == guid ) @@ -8664,7 +8566,7 @@ Item* Player::GetItemByPos( uint16 pos ) const Item* Player::GetItemByPos( uint8 bag, uint8 slot ) const { - if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) ) + if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) ) return m_items[slot]; else if(bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END || bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END ) @@ -8742,7 +8644,7 @@ bool Player::IsInventoryPos( uint8 bag, uint8 slot ) return true; if( bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END ) return true; - if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) ) + if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) ) return true; return false; } @@ -8863,7 +8765,7 @@ bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const return true; } } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->GetEntry() == item ) @@ -8985,7 +8887,7 @@ bool Player::HasItemTotemCategory( uint32 TotemCategory ) const if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory )) return true; } - for(uint8 i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; ++i) + for(uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) { pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory )) @@ -9025,18 +8927,6 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV if(slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS)) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - // vanitypet case - if(slot >= VANITYPET_SLOT_START && slot < VANITYPET_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS)) - return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - - // currencytoken case - if(slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)) - return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - - // guestbag case - if(slot >= QUESTBAG_SLOT_START && slot < QUESTBAG_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS)) - return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - // prevent cheating if(slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END || slot >= PLAYER_SLOT_END) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; @@ -9281,7 +9171,7 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 { if( bag == INVENTORY_SLOT_BAG_0 ) // inventory { - res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot); + res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot); if(res!=EQUIP_ERR_OK) { if(no_space_count) @@ -9368,66 +9258,6 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } } - else if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS) - { - res = _CanStoreItem_InInventorySlots(VANITYPET_SLOT_START,VANITYPET_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) - { - res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS) - { - res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot); if(res!=EQUIP_ERR_OK) @@ -9477,7 +9307,7 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 // search stack for merge to if( pProto->Stackable > 1 ) { - res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot); + res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot); if(res!=EQUIP_ERR_OK) { if(no_space_count) @@ -9575,66 +9405,6 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } } - else if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS) - { - res = _CanStoreItem_InInventorySlots(VANITYPET_SLOT_START,VANITYPET_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) - { - res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS) - { - res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { @@ -9705,16 +9475,10 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const int inv_slot_items[INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START]; int inv_bags[INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE]; int inv_keys[KEYRING_SLOT_END-KEYRING_SLOT_START]; - int inv_pets[VANITYPET_SLOT_END-VANITYPET_SLOT_START]; - int inv_tokens[CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START]; - int inv_quests[QUESTBAG_SLOT_END-QUESTBAG_SLOT_START]; memset(inv_slot_items,0,sizeof(int)*(INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START)); memset(inv_bags,0,sizeof(int)*(INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START)*MAX_BAG_SIZE); memset(inv_keys,0,sizeof(int)*(KEYRING_SLOT_END-KEYRING_SLOT_START)); - memset(inv_pets,0,sizeof(int)*(VANITYPET_SLOT_END-VANITYPET_SLOT_START)); - memset(inv_tokens,0,sizeof(int)*(CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START)); - memset(inv_quests,0,sizeof(int)*(QUESTBAG_SLOT_END-QUESTBAG_SLOT_START)); for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) { @@ -9736,36 +9500,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const } } - for(int i = VANITYPET_SLOT_START; i < VANITYPET_SLOT_END; i++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - - if (pItem2 && !pItem2->IsInTrade()) - { - inv_pets[i-VANITYPET_SLOT_START] = pItem2->GetCount(); - } - } - - for(int i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - - if (pItem2 && !pItem2->IsInTrade()) - { - inv_tokens[i-CURRENCYTOKEN_SLOT_START] = pItem2->GetCount(); - } - } - - for(int i = QUESTBAG_SLOT_START; i < QUESTBAG_SLOT_END; i++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - - if (pItem2 && !pItem2->IsInTrade()) - { - inv_quests[i-QUESTBAG_SLOT_START] = pItem2->GetCount(); - } - } - for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i )) @@ -9825,42 +9559,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const } if (b_found) continue; - for(int t = VANITYPET_SLOT_START; t < VANITYPET_SLOT_END; t++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); - if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_pets[t-VANITYPET_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) - { - inv_pets[t-VANITYPET_SLOT_START] += pItem->GetCount(); - b_found = true; - break; - } - } - if (b_found) continue; - - for(int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; t++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); - if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_tokens[t-CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) - { - inv_tokens[t-CURRENCYTOKEN_SLOT_START] += pItem->GetCount(); - b_found = true; - break; - } - } - if (b_found) continue; - - for(int t = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; t++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); - if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_quests[t-QUESTBAG_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) - { - inv_quests[t-QUESTBAG_SLOT_START] += pItem->GetCount(); - b_found = true; - break; - } - } - if (b_found) continue; - for(int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; t++) { pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); @@ -9913,51 +9611,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const if (b_found) continue; - if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS) - { - for(uint32 t = VANITYPET_SLOT_START; t < VANITYPET_SLOT_END; ++t) - { - if( inv_pets[t-VANITYPET_SLOT_START] == 0 ) - { - inv_pets[t-VANITYPET_SLOT_START] = 1; - b_found = true; - break; - } - } - } - - if (b_found) continue; - - if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) - { - for(uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t) - { - if( inv_tokens[t-CURRENCYTOKEN_SLOT_START] == 0 ) - { - inv_tokens[t-CURRENCYTOKEN_SLOT_START] = 1; - b_found = true; - break; - } - } - } - - if (b_found) continue; - - if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS) - { - for(uint32 t = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; ++t) - { - if( inv_quests[t-QUESTBAG_SLOT_START] == 0 ) - { - inv_quests[t-QUESTBAG_SLOT_START] = 1; - b_found = true; - break; - } - } - } - - if (b_found) continue; - for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++) { pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t ); @@ -10143,42 +9796,33 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo if(eslot == EQUIPMENT_SLOT_OFFHAND) { - if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND) + if( type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND ) { if(!CanDualWield()) return EQUIP_ERR_CANT_DUAL_WIELD; } - else if (type == INVTYPE_2HWEAPON) + + Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); + if(mainItem) { - if(!CanDualWield() || !CanTitanGrip()) - return EQUIP_ERR_CANT_DUAL_WIELD; + if(mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON) + return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED; } - - if(IsTwoHandUsed()) - return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED; } // equip two-hand weapon case (with possible unequip 2 items) if( type == INVTYPE_2HWEAPON ) { - if (eslot == EQUIPMENT_SLOT_OFFHAND) - { - if (!CanTitanGrip()) - return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; - } - else if (eslot != EQUIPMENT_SLOT_MAINHAND) + if(eslot != EQUIPMENT_SLOT_MAINHAND) return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; - if (!CanTitanGrip()) - { - // offhand item must can be stored in inventory for offhand item and it also must be unequipped - Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); - ItemPosCountVec off_dest; - if( offItem && (!not_loading || - CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK || - CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) ) - return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; - } + // offhand item must can be stored in inventory for offhand item and it also must be unequipped + Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); + ItemPosCountVec off_dest; + if( offItem && (!not_loading || + CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK || + CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) ) + return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; } dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot); return EQUIP_ERR_OK; @@ -11098,7 +10742,7 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq } } } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->GetEntry() == item ) @@ -11201,7 +10845,7 @@ void Player::DestroyZoneLimitedItem( bool update, uint32 new_zone ) if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) DestroyItem( INVENTORY_SLOT_BAG_0, i, update); } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) @@ -12198,10 +11842,6 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a ((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply); sLog.outDebug("+ %u EXPERTISE", enchant_amount); break; - case ITEM_MOD_ARMOR_PENETRATION_RATING: - ((Player*)this)->ApplyRatingMod(CR_ARMOR_PENETRATION, enchant_amount, apply); - sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount); - break; default: break; } @@ -12924,10 +12564,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver } if(pQuest->IsDaily()) - { SetDailyQuestStatus(quest_id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, 1); - } if ( !pQuest->IsRepeatable() ) SetQuestStatus(quest_id, QUEST_STATUS_COMPLETE); @@ -12940,8 +12577,6 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver SendQuestReward( pQuest, XP, questGiver ); if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST); } void Player::FailQuest( uint32 quest_id ) @@ -13567,7 +13202,6 @@ void Player::ItemAddedQuestCheck( uint32 entry, uint32 count ) } } UpdateForQuestsGO(); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, entry); } void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count ) @@ -13614,7 +13248,6 @@ void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count ) void Player::KilledMonster( uint32 entry, uint64 guid ) { uint32 addkillcount = 1; - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, entry, addkillcount); for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) { uint32 questid = GetQuestSlotQuestId(i); @@ -13893,12 +13526,13 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive uint32 questid = pQuest->GetQuestId(); sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid ); gameeventmgr.HandleQuestComplete(questid); - WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4) ); - data << uint32(questid); + WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4+4+pQuest->GetRewItemsCount()*8) ); + data << questid; + data << uint32(0x03); if ( getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ) { - data << uint32(XP); + data << XP; data << uint32(pQuest->GetRewOrReqMoney()); } else @@ -13906,9 +13540,16 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive data << uint32(0); data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY))); } + data << uint32(0); // new 2.3.0, HonorPoints? + data << uint32( pQuest->GetRewItemsCount() ); // max is 5 - data << uint32(10*Trinity::Honor::hk_honor_at_level(getLevel(), pQuest->GetRewHonorableKills())); - data << uint32(pQuest->GetBonusTalents()); // bonus talents + for (uint32 i = 0; i < pQuest->GetRewItemsCount(); ++i) + { + if ( pQuest->RewItemId[i] > 0 ) + data << pQuest->RewItemId[i] << pQuest->RewItemCount[i]; + else + data << uint32(0) << uint32(0); + } GetSession()->SendPacket( &data ); if (pQuest->GetQuestCompleteScript() != 0) @@ -13919,9 +13560,8 @@ void Player::SendQuestFailed( uint32 quest_id ) { if( quest_id ) { - WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4+4 ); + WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4 ); data << quest_id; - data << uint32(0); // failed reason (4 for inventory is full) GetSession()->SendPacket( &data ); sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED"); } @@ -13960,10 +13600,10 @@ void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg ) void Player::SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count ) { - WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, 0 ); + WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, (4+4) ); sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM" ); - //data << pQuest->ReqItemId[item_idx]; - //data << count; + data << pQuest->ReqItemId[item_idx]; + data << count; GetSession()->SendPacket( &data ); } @@ -14009,7 +13649,7 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid ) if(!LoadValues( fields[1].GetString())) { - sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded for character list.",GUID_LOPART(guid)); + sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid)); if(delete_result) delete result; return false; } @@ -14079,7 +13719,7 @@ void Player::_LoadArenaTeamInfo(QueryResult *result) ArenaTeam* aTeam = objmgr.GetArenaTeamById(arenateamid); if(!aTeam) { - sLog.outError("Player::_LoadArenaTeamInfo: couldn't load arenateam %u, week %u, season %u, rating %u", arenateamid, played_week, played_season, personal_rating); + sLog.outError("FATAL: couldn't load arenateam %u", arenateamid); continue; } uint8 arenaSlot = aTeam->GetSlot(); @@ -14481,10 +14121,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) uint32 extraflags = fields[25].GetUInt32(); m_stableSlots = fields[26].GetUInt32(); - if(m_stableSlots > 4) + if(m_stableSlots > 2) { - sLog.outError("Player can have not more 4 stable slots, but have in DB %u",uint32(m_stableSlots)); - m_stableSlots = 4; + sLog.outError("Player can have not more 2 stable slots, but have in DB %u",uint32(m_stableSlots)); + m_stableSlots = 2; } m_atLoginFlags = fields[27].GetUInt32(); @@ -14553,8 +14193,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) // reset stats before loading any modifiers InitStatsForLevel(); InitTaxiNodesForLevel(); - InitGlyphsForLevel(); - InitRunes(); // apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods() @@ -14711,8 +14349,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) _LoadDeclinedNames(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES)); - m_achievementMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS), holder->GetResult(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS)); - m_achievementMgr.CheckAllAchievementCriteria(); return true; } @@ -14766,6 +14402,10 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) for (int i = 0; i < TOTAL_AURAS; i++) m_modAuras[i].clear(); + // all aura related fields + for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i) + SetUInt32Value(i, 0); + //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow()); if(result) @@ -15677,7 +15317,7 @@ void Player::SaveToDB() SetByteValue(UNIT_FIELD_BYTES_1, 0, 0); // stand state SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); // shapeshift SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); // stand flags? - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); SetDisplayId(GetNativeDisplayId()); bool inworld = IsInWorld(); @@ -15828,7 +15468,7 @@ void Player::SaveToDB() pet->SavePetToDB(PET_SAVE_AS_CURRENT); //to prevent access to DB we should cache some data, which is used very often - /*CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow()); + CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow()); if(_iter != objmgr.m_mPlayerInfoMap.end())//skip new players { _iter->second->unLevel = getLevel(); @@ -15842,8 +15482,7 @@ void Player::SaveToDB() _iter->second->unArenaInfoId0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6)); _iter->second->unArenaInfoId1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6)); _iter->second->unArenaInfoId2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6)); - }*/ - m_achievementMgr.SaveToDB(); + } } // fast save function for item/money cheating preventing - save only inventory and money state @@ -16305,42 +15944,6 @@ void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid) Player::SetUInt32ValueInDB(index, temp, guid); } -void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair) -{ - Tokens tokens; - if(!LoadValuesArrayFromDB(tokens, guid)) - return; - - uint32 unit_bytes0 = GetUInt32ValueFromArray(tokens, UNIT_FIELD_BYTES_0); - uint8 race = unit_bytes0 & 0xFF; - uint8 class_ = (unit_bytes0 >> 8) & 0xFF; - - PlayerInfo const* info = objmgr.GetPlayerInfo(race, class_); - if(!info) - return; - - unit_bytes0 &= ~(0xFF << 16); - unit_bytes0 |= (gender << 16); - SetUInt32ValueInArray(tokens, UNIT_FIELD_BYTES_0, unit_bytes0); - - SetUInt32ValueInArray(tokens, UNIT_FIELD_DISPLAYID, gender ? info->displayId_f : info->displayId_m); - SetUInt32ValueInArray(tokens, UNIT_FIELD_NATIVEDISPLAYID, gender ? info->displayId_f : info->displayId_m); - - SetUInt32ValueInArray(tokens, PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24))); - - uint32 player_bytes2 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_2); - player_bytes2 &= ~0xFF; - player_bytes2 |= facialHair; - SetUInt32ValueInArray(tokens, PLAYER_BYTES_2, player_bytes2); - - uint32 player_bytes3 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_3); - player_bytes3 &= ~0xFF; - player_bytes3 |= gender; - SetUInt32ValueInArray(tokens, PLAYER_BYTES_3, player_bytes3); - - SaveValuesArrayInDB(tokens, guid); -} - void Player::SendAttackSwingNotStanding() { WorldPacket data(SMSG_ATTACKSWING_NOTSTANDING, 0); @@ -16373,8 +15976,7 @@ void Player::SendAttackSwingBadFacingAttack() void Player::SendAutoRepeatCancel() { - WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, GetPackGUID().size()); - data.append(GetPackGUID()); // may be it's target guid + WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, 0); GetSession()->SendPacket( &data ); } @@ -16603,7 +16205,6 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) { WorldPacket data(SMSG_PET_SPELLS, 8); data << uint64(0); - data << uint32(0); GetSession()->SendPacket(&data); if(GetGroup()) @@ -16735,79 +16336,65 @@ void Player::PetSpellInitialize() { Pet* pet = GetPet(); - if(!pet) - return; - - sLog.outDebug("Pet Spells Groups"); - - CharmInfo *charmInfo = pet->GetCharmInfo(); - - WorldPacket data(SMSG_PET_SPELLS, 8+4+4+4+10*4); - data << uint64(pet->GetGUID()); - data << uint32(pet->GetCreatureInfo()->family); // creature family (required for pet talents) - data << uint32(0); - data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); - - // action bar loop - for(uint32 i = 0; i < 10; i++) + if(pet) { - data << uint32(charmInfo->GetActionBarEntry(i)->Raw); - } + uint8 addlist = 0; - size_t spellsCountPos = data.wpos(); + sLog.outDebug("Pet Spells Groups"); - // spells count - uint8 addlist = 0; - data << uint8(addlist); // placeholder + CreatureInfo const *cinfo = pet->GetCreatureInfo(); - if(pet->isControlled() && ((pet->getPetType() == HUNTER_PET) || ((pet->GetCreatureInfo()->type == CREATURE_TYPE_DEMON) && (getClass() == CLASS_WARLOCK)))) - { - // spells loop - for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) + if(pet->isControlled() && (pet->getPetType() == HUNTER_PET || cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)) { - if(itr->second->state == PETSPELL_REMOVED) - continue; - - data << uint16(itr->first); - data << uint16(itr->second->active); // pet spell active state isn't boolean - ++addlist; + for(PetSpellMap::iterator itr = pet->m_spells.begin();itr != pet->m_spells.end();++itr) + { + if(itr->second->state == PETSPELL_REMOVED) + continue; + ++addlist; + } } - } - data.put<uint8>(spellsCountPos, addlist); + // first line + actionbar + spellcount + spells + last adds + WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25); - uint8 cooldownsCount = pet->m_CreatureSpellCooldowns.size() + pet->m_CreatureCategoryCooldowns.size(); - data << uint8(cooldownsCount); + CharmInfo *charmInfo = pet->GetCharmInfo(); - time_t curTime = time(NULL); + //16 + data << (uint64)pet->GetGUID() << uint32(0x00000000) << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); - for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr) - { - time_t cooldown = 0; + for(uint32 i = 0; i < 10; i++) //40 + { + data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type); + } - if(itr->second > curTime) - cooldown = (itr->second - curTime) * 1000; + data << uint8(addlist); //1 - data << uint16(itr->first); // spellid - data << uint16(0); // spell category? - data << uint32(itr->second); // cooldown - data << uint32(0); // category cooldown - } + if(addlist && pet->isControlled()) + { + for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) + { + if(itr->second->state == PETSPELL_REMOVED) + continue; - for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr) - { - time_t cooldown = 0; + data << uint16(itr->first); + data << uint16(itr->second->active); // pet spell active state isn't boolean + } + } - if(itr->second > curTime) - cooldown = (itr->second - curTime) * 1000; + //data << uint8(0x01) << uint32(0x6010) << uint32(0x01) << uint32(0x05) << uint16(0x00); //15 + uint8 count = 3; //1+8+8+8=25 - data << uint16(itr->first); // spellid - data << uint16(0); // spell category? - data << uint32(0); // cooldown - data << uint32(itr->second); // category cooldown - } + // if count = 0, then end of packet... + data << count; + // uint32 value is spell id... + // uint64 value is constant 0, unknown... + data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 + //data << uint32(0x5fd1) << uint64(0); // if count = 2 + data << uint32(0x8e8c) << uint64(0); // if count = 3 + data << uint32(0x8e8b) << uint64(0); // if count = 3 - GetSession()->SendPacket(&data); + GetSession()->SendPacket(&data); + } } void Player::PossessSpellInitialize() @@ -16829,10 +16416,7 @@ void Player::PossessSpellInitialize() WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds //16 - data << uint64(charm->GetGUID()); - data << uint32(0x00000000); - data << uint32(0); - data << uint8(0) << uint8(0) << uint16(0); + data << (uint64)charm->GetGUID() << uint32(0x00000000) << uint8(0) << uint8(0) << uint16(0); for(uint32 i = 0; i < 10; i++) //40 { @@ -16841,8 +16425,11 @@ void Player::PossessSpellInitialize() data << uint8(addlist); //1 - uint8 count = 0; - data << uint8(count); // cooldowns count + uint8 count = 3; + data << count; + data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 + data << uint32(0x8e8c) << uint64(0); // if count = 3 + data << uint32(0x8e8b) << uint64(0); // if count = 3 GetSession()->SendPacket(&data); } @@ -16879,13 +16466,13 @@ void Player::CharmSpellInitialize() WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds - data << uint64(charm->GetGUID()); - data << uint32(0x00000000); - data << uint32(0); + data << (uint64)charm->GetGUID() << uint32(0x00000000); + if(charm->GetTypeId() != TYPEID_PLAYER) data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()); else data << uint8(0) << uint8(0); + data << uint16(0); for(uint32 i = 0; i < 10; i++) //40 @@ -16908,12 +16495,51 @@ void Player::CharmSpellInitialize() } } - uint8 count = 0; - data << uint8(count); // cooldowns count + uint8 count = 3; + data << count; + data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 + data << uint32(0x8e8c) << uint64(0); // if count = 3 + data << uint32(0x8e8b) << uint64(0); // if count = 3 GetSession()->SendPacket(&data); } +int32 Player::GetTotalFlatMods(uint32 spellId, SpellModOp op) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) return 0; + int32 total = 0; + for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) + { + SpellModifier *mod = *itr; + + if(!IsAffectedBySpellmod(spellInfo,mod)) + continue; + + if (mod->type == SPELLMOD_FLAT) + total += mod->value; + } + return total; +} + +int32 Player::GetTotalPctMods(uint32 spellId, SpellModOp op) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) return 0; + int32 total = 0; + for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) + { + SpellModifier *mod = *itr; + + if(!IsAffectedBySpellmod(spellInfo,mod)) + continue; + + if (mod->type == SPELLMOD_PCT) + total += mod->value; + } + return total; +} + bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell) { if (!mod || !spellInfo) @@ -16931,25 +16557,22 @@ bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mo return false; } - return spellmgr.IsAffectedByMod(spellInfo, mod); + return spellmgr.IsAffectedBySpell(spellInfo,mod->spellId,mod->effectId,mod->mask); } void Player::AddSpellMod(SpellModifier* mod, bool apply) { uint16 Opcode= (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER; - for(int eff=0;eff<96;++eff) + for(int eff=0;eff<64;++eff) { - uint64 _mask = 0; - uint64 _mask2= 0; - if (eff<64) _mask = uint64(1) << (eff- 0); - else _mask2= uint64(1) << (eff-64); - if ( mod->mask & _mask || mod->mask2 & _mask2) + uint64 _mask = uint64(1) << eff; + if ( mod->mask & _mask) { int32 val = 0; for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr) { - if ((*itr)->type == mod->type && ((*itr)->mask & _mask || (*itr)->mask2 & _mask2)) + if ((*itr)->type == mod->type && (*itr)->mask & _mask) val += (*itr)->value; } val += apply ? mod->value : -(mod->value); @@ -17097,7 +16720,7 @@ void Player::HandleStealthedUnitsDetection() // send data at target visibility change (adding to client) if((*i)!=this && (*i)->isType(TYPEMASK_UNIT)) { - SendAurasForTarget(*i); + SendAuraDurationsForTarget(*i); //if(((Unit*)(*i))->isAlive()) //should be always alive { if((*i)->GetTypeId()==TYPEID_UNIT) @@ -18091,7 +17714,7 @@ void Player::UpdateVisibilityOf(WorldObject* target) // send data at target visibility change (adding to client) if(target!=this && target->isType(TYPEMASK_UNIT)) { - SendAurasForTarget((Unit*)target); + SendAuraDurationsForTarget((Unit*)target); if(((Unit*)target)->isAlive()) { if(target->GetTypeId()==TYPEID_UNIT) @@ -18270,7 +17893,7 @@ void Player::SetGroup(Group *group, int8 subgroup) void Player::SendInitialPacketsBeforeAddToMap() { - WorldPacket data(SMSG_SET_REST_START_OBSOLETE, 4); + WorldPacket data(SMSG_SET_REST_START, 4); data << uint32(0); // unknown, may be rest state time or experience GetSession()->SendPacket(&data); @@ -18298,7 +17921,6 @@ void Player::SendInitialPacketsBeforeAddToMap() SendInitialActionButtons(); SendInitialReputations(); - m_achievementMgr.SendAllAchievementData(); UpdateZone(GetZoneId()); SendInitWorldStates(); @@ -18309,23 +17931,13 @@ void Player::SendInitialPacketsBeforeAddToMap() data << (float)0.01666667f; // game speed GetSession()->SendPacket( &data ); - data.Initialize(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement - data << uint32(0x00000000); // on blizz it increments periodically - GetSession()->SendPacket(&data); - // set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight()) AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); - - m_mover = this; } void Player::SendInitialPacketsAfterAddToMap() { - WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement - data << uint32(0x00000000); // on blizz it increments periodically - GetSession()->SendPacket(&data); - CastSpell(this, 836, true); // LOGINEFFECT // set some aura effects that send packet to player client after add player to map @@ -18356,7 +17968,6 @@ void Player::SendInitialPacketsAfterAddToMap() SendMessageToSet(&data,true); } - SendAurasForTarget(this); SendEnchantmentDurations(); // must be after add to map SendItemDurations(); // must be after add to map } @@ -18374,19 +17985,11 @@ void Player::SendUpdateToOutOfRangeGroupMembers() pet->ResetAuraUpdateMask(); } -void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg) +void Player::SendTransferAborted(uint32 mapid, uint16 reason) { WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2); data << uint32(mapid); - data << uint8(reason); // transfer abort reason - switch(reason) - { - case TRANSFER_ABORT_INSUF_EXPAN_LVL: - case TRANSFER_ABORT_DIFFICULTY: - case TRANSFER_ABORT_UNIQUE_MESSAGE: - data << uint8(arg); - break; - } + data << uint16(reason); // transfer abort reason GetSession()->SendPacket(&data); } @@ -18596,51 +18199,16 @@ void Player::learnSkillRewardedSpells() } } -void Player::SendAurasForTarget(Unit *target) +void Player::SendAuraDurationsForTarget(Unit* target) { - if(target->GetVisibleAuras()->empty()) // speedup things - return; - - WorldPacket data(SMSG_AURA_UPDATE_ALL); - data.append(target->GetPackGUID()); - - Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras(); - for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr) + for(Unit::AuraMap::const_iterator itr = target->GetAuras().begin(); itr != target->GetAuras().end(); ++itr) { - for(uint32 j = 0; j < 3; ++j) - { - if(Aura *aura = target->GetAura(itr->second, j)) - { - data << uint8(aura->GetAuraSlot()); - data << uint32(aura->GetId()); - - if(aura->GetId()) - { - uint8 auraFlags = aura->GetAuraFlags(); - // flags - data << uint8(auraFlags); - // level - data << uint8(aura->GetAuraLevel()); - // charges - data << uint8(aura->m_procCharges >= 0 ? aura->m_procCharges : 0 ); - - if(!(auraFlags & AFLAG_NOT_CASTER)) - { - data << uint8(0); // packed GUID of someone (caster?) - } + Aura* aura = itr->second; + if(aura->GetAuraSlot() >= MAX_AURAS || aura->IsPassive() || aura->GetCasterGUID()!=GetGUID()) + continue; - if(auraFlags & AFLAG_DURATION) // include aura duration - { - data << uint32(aura->GetAuraMaxDuration()); - data << uint32(aura->GetAuraDuration()); - } - } - break; - } - } + aura->SendAuraDurationForCaster(this); } - - GetSession()->SendPacket(&data); } void Player::SetDailyQuestStatus( uint32 quest_id ) @@ -18702,15 +18270,15 @@ uint32 Player::GetMinLevelForBattleGroundQueueId(uint32 queue_id) if(queue_id < 1) return 0; - if(queue_id >=7) - queue_id = 7; + if(queue_id >=6) + queue_id = 6; return 10*(queue_id+1); } uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id) { - if(queue_id >=7) + if(queue_id >=6) return 255; // hardcoded max level return 10*(queue_id+2)-1; @@ -18722,8 +18290,8 @@ uint32 Player::GetBattleGroundQueueIdFromLevel() const uint32 level = getLevel(); if(level <= 19) return 0; - else if (level > 79) - return 7; + else if (level > 69) + return 6; else return level/10 - 1; // 20..29 -> 1, 30-39 -> 2, ... /* @@ -18869,8 +18437,9 @@ void Player::AutoUnequipOffhandIfNeed() if(!offItem) return; - // need unequip for 2h-weapon without TitanGrip - if (!IsTwoHandUsed()) + Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); + + if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON) return; ItemPosCountVec off_dest; @@ -18936,23 +18505,6 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons return false; } -bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const -{ - // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP - if (spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && - HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)) - return true; - - // Check no reagent use mask - uint64 noReagentMask_0_1 = GetUInt64Value(PLAYER_NO_REAGENT_COST_1); - uint32 noReagentMask_2 = GetUInt64Value(PLAYER_NO_REAGENT_COST_1+2); - if (spellInfo->SpellFamilyFlags & noReagentMask_0_1 || - spellInfo->SpellFamilyFlags2 & noReagentMask_2) - return true; - - return false; -} - void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) { AuraMap& auras = GetAuras(); @@ -18998,7 +18550,7 @@ uint32 Player::GetResurrectionSpellId() for(AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) { // Soulstone Resurrection // prio: 3 (max, non death persistent) - if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual[0] == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 ) + if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 ) { switch((*itr)->GetId()) { @@ -19157,9 +18709,6 @@ uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const void Player::ResurectUsingRequestData() { - /// Teleport before resurrecting, otherwise the player might get attacked from creatures near his corpse - TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); - ResurrectPlayer(0.0f,false); if(GetMaxHealth() > m_resurrectHealth) @@ -19177,6 +18726,8 @@ void Player::ResurectUsingRequestData() SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY) ); SpawnCorpseBones(); + + TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); } void Player::SetClientControl(Unit* target, uint8 allowMove) @@ -19190,8 +18741,8 @@ void Player::SetClientControl(Unit* target, uint8 allowMove) void Player::UpdateZoneDependentAuras( uint32 newZone ) { // remove new continent flight forms - uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), newZone); - if( !isGameMaster() && v_map != 530 && v_map != 571) + if( !isGameMaster() && + GetVirtualMapForMapAndZone(GetMapId(),newZone) != 530) { RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED); RemoveSpellsCausingAura(SPELL_AURA_FLY); @@ -19411,8 +18962,8 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const void Player::HandleFallDamage(MovementInfo& movementInfo) { - //if(movementInfo.fallTime < 1500) - // return; + if(movementInfo.fallTime < 1500) + return; // calculate total z distance of the fall float z_diff = m_lastFallZ - movementInfo.z; @@ -19718,152 +19269,6 @@ bool Player::isAllowUseBattleGroundObject() ); } -uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair) -{ - uint32 level = getLevel(); - - if(level > GT_MAX_LEVEL) - level = GT_MAX_LEVEL; // max level in this dbc - - uint8 hairstyle = GetByteValue(PLAYER_BYTES, 2); - uint8 haircolor = GetByteValue(PLAYER_BYTES, 3); - uint8 facialhair = GetByteValue(PLAYER_BYTES_2, 0); - - if((hairstyle == newhairstyle) && (haircolor == newhaircolor) && (facialhair == newfacialhair)) - return 0; - - GtBarberShopCostBaseEntry const *bsc = sGtBarberShopCostBaseStore.LookupEntry(level - 1); - - if(!bsc) // shouldn't happen - return 0xFFFFFFFF; - - float cost = 0; - - if(hairstyle != newhairstyle) - cost += bsc->cost; // full price - - if((haircolor != newhaircolor) && (hairstyle == newhairstyle)) - cost += bsc->cost * 0.5f; // +1/2 of price - - if(facialhair != newfacialhair) - cost += bsc->cost * 0.75f; // +3/4 of price - - return uint32(cost); -} - -void Player::InitGlyphsForLevel() -{ - uint32 level = getLevel(); - uint32 value = 0; - - // 0x3F = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 for 80 level - if(level >= 15) - value |= (0x01 | 0x02); - if(level >= 30) - value |= 0x04; - if(level >= 50) - value |= 0x08; - if(level >= 70) - value |= 0x10; - if(level >= 80) - value |= 0x20; - - SetUInt32Value(PLAYER_GLYPHS_ENABLED, value); -} - -void Player::EnterVehicle(Vehicle *vehicle) -{ - VehicleEntry const *ve = sVehicleStore.LookupEntry(vehicle->GetVehicleId()); - if(!ve) - return; - - VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(ve->m_seatID[0]); - if(!veSeat) - return; - - vehicle->SetCharmerGUID(GetGUID()); - vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); - vehicle->setFaction(getFaction()); - - SetCharm(vehicle); // charm - SetFarSight(vehicle->GetGUID()); // set view - - SetClientControl(vehicle, 1); // redirect controls to vehicle - - WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); - GetSession()->SendPacket(&data); - - data.Initialize(MSG_MOVE_TELEPORT_ACK, 30); - data.append(GetPackGUID()); - data << uint32(0); // counter? - data << uint32(MOVEMENTFLAG_ONTRANSPORT); // transport - data << uint16(0); // special flags - data << uint32(getMSTime()); // time - data << vehicle->GetPositionX(); // x - data << vehicle->GetPositionY(); // y - data << vehicle->GetPositionZ(); // z - data << vehicle->GetOrientation(); // o - // transport part, TODO: load/calculate seat offsets - data << uint64(vehicle->GetGUID()); // transport guid - data << float(veSeat->m_attachmentOffsetX); // transport offsetX - data << float(veSeat->m_attachmentOffsetY); // transport offsetY - data << float(veSeat->m_attachmentOffsetZ); // transport offsetZ - data << float(0); // transport orientation - data << uint32(getMSTime()); // transport time - data << uint8(0); // seat - // end of transport part - data << uint32(0); // fall time - GetSession()->SendPacket(&data); - - data.Initialize(SMSG_PET_SPELLS, 8+4+4+4+4*10+1+1); - data << uint64(vehicle->GetGUID()); - data << uint32(0x00000000); - data << uint32(0x00000000); - data << uint32(0x00000101); - - for(uint32 i = 0; i < 10; ++i) - data << uint16(0) << uint8(0) << uint8(i+8); - - data << uint8(0); - data << uint8(0); - GetSession()->SendPacket(&data); -} - -void Player::ExitVehicle(Vehicle *vehicle) -{ - vehicle->SetCharmerGUID(0); - vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); - vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H); - - SetCharm(NULL); - SetFarSight(NULL); - - SetClientControl(vehicle, 0); - - WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30); - data.append(GetPackGUID()); - data << uint32(0); // counter? - data << uint32(MOVEMENTFLAG_FLY_UNK1); // fly unk - data << uint16(0x40); // special flags - data << uint32(getMSTime()); // time - data << vehicle->GetPositionX(); // x - data << vehicle->GetPositionY(); // y - data << vehicle->GetPositionZ(); // z - data << vehicle->GetOrientation(); // o - data << uint32(0); // fall time - GetSession()->SendPacket(&data); - - data.Initialize(SMSG_PET_SPELLS, 8+4); - data << uint64(0); - data << uint32(0); - GetSession()->SendPacket(&data); - - // only for flyable vehicles? - CastSpell(this, 45472, true); // Parachute -} - bool Player::HasTitle(uint32 bitIndex) { if (bitIndex > 128) @@ -19881,6 +19286,7 @@ void Player::SetTitle(CharTitlesEntry const* title) SetFlag(PLAYER__FIELD_KNOWN_TITLES+fieldIndexOffset, flag); } + /*-----------------------TRINITY--------------------------*/ bool Player::isTotalImmunity() { @@ -19937,52 +19343,3 @@ void Player::UpdateCharmedAI() Attack(target, true); } } - -void Player::ConvertRune(uint8 index, uint8 newType) -{ - SetCurrentRune(index, newType); - - WorldPacket data(SMSG_CONVERT_RUNE, 2); - data << uint8(index); - data << uint8(newType); - GetSession()->SendPacket(&data); -} - -void Player::ResyncRunes(uint8 count) -{ - WorldPacket data(SMSG_RESYNC_RUNES, count * 2); - for(uint32 i = 0; i < count; ++i) - { - data << uint8(GetCurrentRune(i)); // rune type - data << uint8(255 - (GetRuneCooldown(i) * 51)); // passed cooldown time (0-255) - } - GetSession()->SendPacket(&data); -} - -void Player::AddRunePower(uint8 index) -{ - WorldPacket data(SMSG_ADD_RUNE_POWER, 4); - data << uint32(1 << index); // mask (0x00-0x3F probably) - GetSession()->SendPacket(&data); -} - -void Player::InitRunes() -{ - if(getClass() != CLASS_DEATH_KNIGHT) - return; - - m_runes = new Runes; - - m_runes->runeState = 0; - - for(uint32 i = 0; i < MAX_RUNES; ++i) - { - SetBaseRune(i, i / 2); // init base types - SetCurrentRune(i, i / 2); // init current types - SetRuneCooldown(i, 0); // reset cooldowns - m_runes->SetRuneState(i); - } - - for(uint32 i = 0; i < NUM_RUNE_TYPES; ++i) - SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f); -} |