mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
Merge remote branch 'origin/master' into 330
This commit is contained in:
commit
90ee507cf7
83 changed files with 1629 additions and 737 deletions
|
|
@ -1335,7 +1335,7 @@ void Player::Update( uint32 p_time )
|
|||
SendUpdateToOutOfRangeGroupMembers();
|
||||
|
||||
Pet* pet = GetPet();
|
||||
if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID())))
|
||||
if(pet && !pet->IsWithinDistInMap(this, GetMap()->GetVisibilityDistance()) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID())))
|
||||
{
|
||||
RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
|
||||
}
|
||||
|
|
@ -1651,7 +1651,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
|||
if (!(options & TELE_TO_NOT_UNSUMMON_PET))
|
||||
{
|
||||
//same map, only remove pet if out of range for new position
|
||||
if(pet && !pet->IsWithinDist3d(x,y,z, OWNER_MAX_DISTANCE))
|
||||
if(pet && !pet->IsWithinDist3d(x,y,z,GetMap()->GetVisibilityDistance()))
|
||||
UnsummonPetTemporaryIfAny();
|
||||
}
|
||||
|
||||
|
|
@ -5025,15 +5025,12 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)
|
|||
if(!skill_id)
|
||||
return false;
|
||||
|
||||
uint16 i=0;
|
||||
for (; i < PLAYER_MAX_SKILLS; ++i)
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill_id)
|
||||
break;
|
||||
|
||||
if(i>=PLAYER_MAX_SKILLS)
|
||||
SkillStatusMap::iterator itr = mSkillStatus.find(skill_id);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return false;
|
||||
|
||||
uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i));
|
||||
uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos);
|
||||
uint32 data = GetUInt32Value(valueIndex);
|
||||
uint32 value = SKILL_VALUE(data);
|
||||
uint32 max = SKILL_MAX(data);
|
||||
|
||||
|
|
@ -5046,7 +5043,9 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)
|
|||
if(new_value > max)
|
||||
new_value = max;
|
||||
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,max));
|
||||
SetUInt32Value(valueIndex,MAKE_SKILL_VALUE(new_value,max));
|
||||
if(itr->second.uState != SKILL_NEW)
|
||||
itr->second.uState = SKILL_CHANGED;
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL,skill_id);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -5155,13 +5154,13 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
|
|||
return false;
|
||||
}
|
||||
|
||||
uint16 i=0;
|
||||
for (; i < PLAYER_MAX_SKILLS; ++i)
|
||||
if ( SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_INDEX(i))) == SkillId ) break;
|
||||
if ( i >= PLAYER_MAX_SKILLS )
|
||||
SkillStatusMap::iterator itr = mSkillStatus.find(SkillId);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return false;
|
||||
|
||||
uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i));
|
||||
uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos);
|
||||
|
||||
uint32 data = GetUInt32Value(valueIndex);
|
||||
uint16 SkillValue = SKILL_VALUE(data);
|
||||
uint16 MaxValue = SKILL_MAX(data);
|
||||
|
||||
|
|
@ -5176,7 +5175,9 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
|
|||
if(new_value > MaxValue)
|
||||
new_value = MaxValue;
|
||||
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,MaxValue));
|
||||
SetUInt32Value(valueIndex,MAKE_SKILL_VALUE(new_value,MaxValue));
|
||||
if(itr->second.uState != SKILL_NEW)
|
||||
itr->second.uState = SKILL_CHANGED;
|
||||
for(uint32* bsl = &bonusSkillLevels[0]; *bsl; ++bsl)
|
||||
{
|
||||
if((SkillValue < *bsl && new_value >= *bsl))
|
||||
|
|
@ -5274,19 +5275,20 @@ void Player::UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, bool de
|
|||
|
||||
void Player::ModifySkillBonus(uint32 skillid,int32 val, bool talent)
|
||||
{
|
||||
for (uint16 i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skillid)
|
||||
{
|
||||
uint32 bonus_val = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i));
|
||||
int16 temp_bonus = SKILL_TEMP_BONUS(bonus_val);
|
||||
int16 perm_bonus = SKILL_PERM_BONUS(bonus_val);
|
||||
|
||||
if(talent) // permanent bonus stored in high part
|
||||
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),MAKE_SKILL_BONUS(temp_bonus,perm_bonus+val));
|
||||
else // temporary/item bonus stored in low part
|
||||
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),MAKE_SKILL_BONUS(temp_bonus+val,perm_bonus));
|
||||
SkillStatusMap::const_iterator itr = mSkillStatus.find(skillid);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 bonusIndex = PLAYER_SKILL_BONUS_INDEX(itr->second.pos);
|
||||
|
||||
uint32 bonus_val = GetUInt32Value(bonusIndex);
|
||||
int16 temp_bonus = SKILL_TEMP_BONUS(bonus_val);
|
||||
int16 perm_bonus = SKILL_PERM_BONUS(bonus_val);
|
||||
|
||||
if(talent) // permanent bonus stored in high part
|
||||
SetUInt32Value(bonusIndex,MAKE_SKILL_BONUS(temp_bonus,perm_bonus+val));
|
||||
else // temporary/item bonus stored in low part
|
||||
SetUInt32Value(bonusIndex,MAKE_SKILL_BONUS(temp_bonus+val,perm_bonus));
|
||||
}
|
||||
|
||||
void Player::UpdateSkillsForLevel()
|
||||
|
|
@ -5296,10 +5298,12 @@ void Player::UpdateSkillsForLevel()
|
|||
|
||||
bool alwaysMaxSkill = sWorld.getConfig(CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL);
|
||||
|
||||
for (uint16 i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
if (GetUInt32Value(PLAYER_SKILL_INDEX(i)))
|
||||
for(SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end(); ++itr)
|
||||
{
|
||||
uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
|
||||
if(itr->second.uState == SKILL_DELETED)
|
||||
continue;
|
||||
|
||||
uint32 pskill = itr->first;
|
||||
|
||||
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(pskill);
|
||||
if(!pSkill)
|
||||
|
|
@ -5308,37 +5312,52 @@ void Player::UpdateSkillsForLevel()
|
|||
if(GetSkillRangeType(pSkill,false) != SKILL_RANGE_LEVEL)
|
||||
continue;
|
||||
|
||||
uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i));
|
||||
uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos);
|
||||
uint32 data = GetUInt32Value(valueIndex);
|
||||
uint32 max = SKILL_MAX(data);
|
||||
uint32 val = SKILL_VALUE(data);
|
||||
|
||||
/// update only level dependent max skill values
|
||||
if(max!=1)
|
||||
{
|
||||
/// miximize skill always
|
||||
/// maximize skill always
|
||||
if(alwaysMaxSkill)
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(maxSkill,maxSkill));
|
||||
/// update max skill value if current max skill not maximized
|
||||
else if(max != maxconfskill)
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(val,maxSkill));
|
||||
{
|
||||
SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(maxSkill,maxSkill));
|
||||
if(itr->second.uState != SKILL_NEW)
|
||||
itr->second.uState = SKILL_CHANGED;
|
||||
}
|
||||
else if(max != maxconfskill) /// update max skill value if current max skill not maximized
|
||||
{
|
||||
SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(val,maxSkill));
|
||||
if(itr->second.uState != SKILL_NEW)
|
||||
itr->second.uState = SKILL_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::UpdateSkillsToMaxSkillsForLevel()
|
||||
{
|
||||
for (uint16 i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
if (GetUInt32Value(PLAYER_SKILL_INDEX(i)))
|
||||
for(SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end(); ++itr)
|
||||
{
|
||||
uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
|
||||
if(itr->second.uState == SKILL_DELETED)
|
||||
continue;
|
||||
|
||||
uint32 pskill = itr->first;
|
||||
if( IsProfessionOrRidingSkill(pskill))
|
||||
continue;
|
||||
uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i));
|
||||
uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos);
|
||||
uint32 data = GetUInt32Value(valueIndex);
|
||||
|
||||
uint32 max = SKILL_MAX(data);
|
||||
|
||||
if(max > 1)
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(max,max));
|
||||
{
|
||||
SetUInt32Value(valueIndex,MAKE_SKILL_VALUE(max,max));
|
||||
if(itr->second.uState != SKILL_NEW)
|
||||
itr->second.uState = SKILL_CHANGED;
|
||||
}
|
||||
|
||||
if(pskill == SKILL_DEFENSE)
|
||||
UpdateDefenseBonusesMod();
|
||||
|
|
@ -5352,15 +5371,16 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
|
|||
if(!id)
|
||||
return;
|
||||
|
||||
uint16 i=0;
|
||||
for (; i < PLAYER_MAX_SKILLS; ++i)
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == id) break;
|
||||
SkillStatusMap::iterator itr = mSkillStatus.find(id);
|
||||
|
||||
if(i<PLAYER_MAX_SKILLS) //has skill
|
||||
//has skill
|
||||
if(itr != mSkillStatus.end() && itr->second.uState != SKILL_DELETED)
|
||||
{
|
||||
if(currVal)
|
||||
{
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal));
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos),MAKE_SKILL_VALUE(currVal,maxVal));
|
||||
if(itr->second.uState != SKILL_NEW)
|
||||
itr->second.uState = SKILL_CHANGED;
|
||||
learnSkillRewardedSpells(id, currVal);
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL,id);
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL,id);
|
||||
|
|
@ -5368,9 +5388,15 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
|
|||
else //remove
|
||||
{
|
||||
// clear skill fields
|
||||
SetUInt32Value(PLAYER_SKILL_INDEX(i),0);
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),0);
|
||||
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
|
||||
SetUInt32Value(PLAYER_SKILL_INDEX(itr->second.pos),0);
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos),0);
|
||||
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos),0);
|
||||
|
||||
// mark as deleted or simply remove from map if not saved yet
|
||||
if(itr->second.uState != SKILL_NEW)
|
||||
itr->second.uState = SKILL_DELETED;
|
||||
else
|
||||
mSkillStatus.erase(itr);
|
||||
|
||||
// remove all spells that related to this skill
|
||||
for (uint32 j=0; j<sSkillLineAbilityStore.GetNumRows(); ++j)
|
||||
|
|
@ -5381,7 +5407,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
|
|||
}
|
||||
else if(currVal) //add
|
||||
{
|
||||
for (i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
for (int i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
if (!GetUInt32Value(PLAYER_SKILL_INDEX(i)))
|
||||
{
|
||||
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id);
|
||||
|
|
@ -5399,6 +5425,15 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
|
|||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL,id);
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL,id);
|
||||
|
||||
// insert new entry or update if not deleted old entry yet
|
||||
if(itr != mSkillStatus.end())
|
||||
{
|
||||
itr->second.pos = i;
|
||||
itr->second.uState = SKILL_CHANGED;
|
||||
}
|
||||
else
|
||||
mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(i, SKILL_NEW)));
|
||||
|
||||
// apply skill bonuses
|
||||
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
|
||||
|
||||
|
|
@ -5423,15 +5458,11 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
|
|||
|
||||
bool Player::HasSkill(uint32 skill) const
|
||||
{
|
||||
if(!skill)return false;
|
||||
for (uint16 i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
{
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if(!skill)
|
||||
return false;
|
||||
|
||||
SkillStatusMap::const_iterator itr = mSkillStatus.find(skill);
|
||||
return (itr != mSkillStatus.end() && itr->second.uState != SKILL_DELETED);
|
||||
}
|
||||
|
||||
uint16 Player::GetSkillValue(uint32 skill) const
|
||||
|
|
@ -5439,78 +5470,71 @@ uint16 Player::GetSkillValue(uint32 skill) const
|
|||
if(!skill)
|
||||
return 0;
|
||||
|
||||
for (uint16 i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
{
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
|
||||
{
|
||||
uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i));
|
||||
SkillStatusMap::const_iterator itr = mSkillStatus.find(skill);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return 0;
|
||||
|
||||
int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i))));
|
||||
result += SKILL_TEMP_BONUS(bonus);
|
||||
result += SKILL_PERM_BONUS(bonus);
|
||||
return result < 0 ? 0 : result;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos));
|
||||
|
||||
int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))));
|
||||
result += SKILL_TEMP_BONUS(bonus);
|
||||
result += SKILL_PERM_BONUS(bonus);
|
||||
return result < 0 ? 0 : result;
|
||||
}
|
||||
|
||||
uint16 Player::GetMaxSkillValue(uint32 skill) const
|
||||
{
|
||||
if(!skill)return 0;
|
||||
for (uint16 i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
{
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
|
||||
{
|
||||
uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i));
|
||||
if(!skill)
|
||||
return 0;
|
||||
|
||||
int32 result = int32(SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i))));
|
||||
result += SKILL_TEMP_BONUS(bonus);
|
||||
result += SKILL_PERM_BONUS(bonus);
|
||||
return result < 0 ? 0 : result;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
SkillStatusMap::const_iterator itr = mSkillStatus.find(skill);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return 0;
|
||||
|
||||
uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos));
|
||||
|
||||
int32 result = int32(SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))));
|
||||
result += SKILL_TEMP_BONUS(bonus);
|
||||
result += SKILL_PERM_BONUS(bonus);
|
||||
return result < 0 ? 0 : result;
|
||||
}
|
||||
|
||||
uint16 Player::GetPureMaxSkillValue(uint32 skill) const
|
||||
{
|
||||
if(!skill)return 0;
|
||||
for (uint16 i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
{
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
|
||||
{
|
||||
return SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
if(!skill)
|
||||
return 0;
|
||||
|
||||
SkillStatusMap::const_iterator itr = mSkillStatus.find(skill);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return 0;
|
||||
|
||||
return SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)));
|
||||
}
|
||||
|
||||
uint16 Player::GetBaseSkillValue(uint32 skill) const
|
||||
{
|
||||
if(!skill)return 0;
|
||||
for (uint16 i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
{
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
|
||||
{
|
||||
int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i))));
|
||||
result += SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i)));
|
||||
return result < 0 ? 0 : result;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
if(!skill)
|
||||
return 0;
|
||||
|
||||
SkillStatusMap::const_iterator itr = mSkillStatus.find(skill);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return 0;
|
||||
|
||||
int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))));
|
||||
result += SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos)));
|
||||
return result < 0 ? 0 : result;
|
||||
}
|
||||
|
||||
uint16 Player::GetPureSkillValue(uint32 skill) const
|
||||
{
|
||||
if(!skill)return 0;
|
||||
for (uint16 i=0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
{
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
|
||||
{
|
||||
return SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
if(!skill)
|
||||
return 0;
|
||||
|
||||
SkillStatusMap::const_iterator itr = mSkillStatus.find(skill);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return 0;
|
||||
|
||||
return SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)));
|
||||
}
|
||||
|
||||
int16 Player::GetSkillPermBonusValue(uint32 skill) const
|
||||
|
|
@ -5518,15 +5542,11 @@ int16 Player::GetSkillPermBonusValue(uint32 skill) const
|
|||
if(!skill)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
{
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
|
||||
{
|
||||
return SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i)));
|
||||
}
|
||||
}
|
||||
SkillStatusMap::const_iterator itr = mSkillStatus.find(skill);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
return SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos)));
|
||||
}
|
||||
|
||||
int16 Player::GetSkillTempBonusValue(uint32 skill) const
|
||||
|
|
@ -5534,15 +5554,11 @@ int16 Player::GetSkillTempBonusValue(uint32 skill) const
|
|||
if(!skill)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
{
|
||||
if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
|
||||
{
|
||||
return SKILL_TEMP_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i)));
|
||||
}
|
||||
}
|
||||
SkillStatusMap::const_iterator itr = mSkillStatus.find(skill);
|
||||
if(itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
return SKILL_TEMP_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos)));
|
||||
}
|
||||
|
||||
void Player::SendInitialActionButtons() const
|
||||
|
|
@ -9005,11 +9021,11 @@ uint8 Player::_CanStoreItem_InBag( uint8 bag, ItemPosCountVec &dest, ItemPrototy
|
|||
Item* pItem2 = GetItemByPos( bag, j );
|
||||
|
||||
// ignore move item (this slot will be empty at move)
|
||||
if (pItem2==pSrcItem)
|
||||
if (pItem2 == pSrcItem)
|
||||
pItem2 = NULL;
|
||||
|
||||
// if merge skip empty, if !merge skip non-empty
|
||||
if ((pItem2!=NULL)!=merge)
|
||||
if ((pItem2 != NULL) != merge)
|
||||
continue;
|
||||
|
||||
if (pItem2)
|
||||
|
|
@ -9066,7 +9082,7 @@ uint8 Player::_CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end,
|
|||
pItem2 = NULL;
|
||||
|
||||
// if merge skip empty, if !merge skip non-empty
|
||||
if ((pItem2!=NULL)!=merge)
|
||||
if ((pItem2 != NULL) != merge)
|
||||
continue;
|
||||
|
||||
if (pItem2)
|
||||
|
|
@ -9971,6 +9987,9 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
|
|||
if (!pItem)
|
||||
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
|
||||
|
||||
if (pItem->m_lootGenerated)
|
||||
return EQUIP_ERR_ITEM_LOCKED;
|
||||
|
||||
uint32 count = pItem->GetCount();
|
||||
|
||||
sLog.outDebug( "STORAGE: CanBankItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, pItem->GetEntry(), pItem->GetCount());
|
||||
|
|
@ -14484,7 +14503,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
|
||||
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
|
||||
|
||||
_LoadSkills();
|
||||
// cleanup aura list explicitly before skill load wher some spells can be applied
|
||||
RemoveAllAuras();
|
||||
|
||||
_LoadSkills(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSKILLS));
|
||||
|
||||
// make sure the unit is considered out of combat for proper loading
|
||||
ClearInCombat();
|
||||
|
|
@ -14742,7 +14764,7 @@ void Player::_LoadActions(QueryResult *result)
|
|||
|
||||
void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
||||
{
|
||||
RemoveAllAuras();
|
||||
//RemoveAllAuras(); -- some spells casted before aura load, for example in LoadSkills, aura list explcitly cleaned early
|
||||
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
||||
|
||||
|
|
@ -15748,6 +15770,7 @@ void Player::SaveToDB()
|
|||
_SaveSpellCooldowns();
|
||||
_SaveActions();
|
||||
_SaveAuras();
|
||||
_SaveSkills();
|
||||
m_achievementMgr.SaveToDB();
|
||||
m_reputationMgr.SaveToDB();
|
||||
_SaveEquipmentSets();
|
||||
|
|
@ -16028,6 +16051,46 @@ void Player::_SaveDailyQuestStatus()
|
|||
GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx),uint64(m_lastDailyQuestTime));
|
||||
}
|
||||
|
||||
|
||||
void Player::_SaveSkills()
|
||||
{
|
||||
// we don't need transactions here.
|
||||
for( SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end(); )
|
||||
{
|
||||
if(itr->second.uState == SKILL_UNCHANGED)
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(itr->second.uState == SKILL_DELETED)
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM character_skills WHERE guid = '%u' AND skill = '%u' ", GetGUIDLow(), itr->first );
|
||||
mSkillStatus.erase(itr++);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 valueData = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos));
|
||||
uint16 value = SKILL_VALUE(valueData);
|
||||
uint16 max = SKILL_MAX(valueData);
|
||||
|
||||
switch (itr->second.uState)
|
||||
{
|
||||
case SKILL_NEW:
|
||||
CharacterDatabase.PExecute("INSERT INTO character_skills (guid, skill, value, max) VALUES ('%u', '%u', '%u', '%u')",
|
||||
GetGUIDLow(), itr->first, value, max);
|
||||
break;
|
||||
case SKILL_CHANGED:
|
||||
CharacterDatabase.PExecute("UPDATE character_skills SET value = '%u',max = '%u'WHERE guid = '%u' AND skill = '%u' ",
|
||||
value, max, GetGUIDLow(), itr->first );
|
||||
break;
|
||||
};
|
||||
itr->second.uState = SKILL_UNCHANGED;
|
||||
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::_SaveSpells()
|
||||
{
|
||||
for (PlayerSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end();)
|
||||
|
|
@ -18092,12 +18155,27 @@ bool Player::IsVisibleGloballyFor( Player* u ) const
|
|||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void BeforeVisibilityDestroy(T* /*t*/, Player* /*p*/)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void BeforeVisibilityDestroy<Creature>(Creature* t, Player* p)
|
||||
{
|
||||
if (p->GetPetGUID()==t->GetGUID() && ((Creature*)t)->isPet())
|
||||
((Pet*)t)->Remove(PET_SAVE_NOT_IN_SLOT, true);
|
||||
}
|
||||
|
||||
void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target)
|
||||
{
|
||||
if(HaveAtClient(target))
|
||||
{
|
||||
if(!target->isVisibleForInState(this, viewPoint, true))
|
||||
{
|
||||
if (target->GetTypeId()==TYPEID_UNIT)
|
||||
BeforeVisibilityDestroy<Creature>((Creature*)target,this);
|
||||
|
||||
target->DestroyForPlayer(this);
|
||||
m_clientGUIDs.erase(target->GetGUID());
|
||||
|
||||
|
|
@ -18151,6 +18229,8 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, T* target, UpdateD
|
|||
{
|
||||
if(!target->isVisibleForInState(this,viewPoint,true))
|
||||
{
|
||||
BeforeVisibilityDestroy<T>(target,this);
|
||||
|
||||
target->BuildOutOfRangeUpdateBlock(&data);
|
||||
m_clientGUIDs.erase(target->GetGUID());
|
||||
|
||||
|
|
@ -19862,43 +19942,78 @@ void Player::learnSpellHighRank(uint32 spellid)
|
|||
sSpellMgr.doForHighRanks(spellid,worker);
|
||||
}
|
||||
|
||||
void Player::_LoadSkills()
|
||||
void Player::_LoadSkills(QueryResult *result)
|
||||
{
|
||||
// Note: skill data itself loaded from `data` field. This is only cleanup part of load
|
||||
// 0 1 2
|
||||
// SetPQuery(PLAYER_LOGIN_QUERY_LOADSKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
|
||||
// reset skill modifiers and set correct unlearn flags
|
||||
for (uint32 i = 0; i < PLAYER_MAX_SKILLS; ++i)
|
||||
uint32 count = 0;
|
||||
if (result)
|
||||
{
|
||||
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
|
||||
|
||||
// set correct unlearn bit
|
||||
uint32 id = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
|
||||
if(!id) continue;
|
||||
|
||||
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id);
|
||||
if(!pSkill) continue;
|
||||
|
||||
// enable unlearn button for primary professions only
|
||||
if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION)
|
||||
SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,1));
|
||||
else
|
||||
SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));
|
||||
|
||||
// set fixed skill ranges
|
||||
switch(GetSkillRangeType(pSkill,false))
|
||||
do
|
||||
{
|
||||
case SKILL_RANGE_LANGUAGE: // 300..300
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(300,300));
|
||||
break;
|
||||
case SKILL_RANGE_MONO: // 1..1, grey monolite bar
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(1,1));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
uint32 vskill = SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)));
|
||||
learnSkillRewardedSpells(id, vskill);
|
||||
uint16 skill = fields[0].GetUInt16();
|
||||
uint16 value = fields[1].GetUInt16();
|
||||
uint16 max = fields[2].GetUInt16();
|
||||
|
||||
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill);
|
||||
if(!pSkill)
|
||||
{
|
||||
sLog.outError("Character %u has skill %u that does not exist.", GetGUIDLow(), skill);
|
||||
continue;
|
||||
}
|
||||
|
||||
// set fixed skill ranges
|
||||
switch(GetSkillRangeType(pSkill,false))
|
||||
{
|
||||
case SKILL_RANGE_LANGUAGE: // 300..300
|
||||
value = max = 300;
|
||||
break;
|
||||
case SKILL_RANGE_MONO: // 1..1, grey monolite bar
|
||||
value = max = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(value == 0)
|
||||
{
|
||||
sLog.outError("Character %u has skill %u with value 0. Will be deleted.", GetGUIDLow(), skill);
|
||||
CharacterDatabase.PExecute("DELETE FROM character_skills WHERE guid = '%u' AND skill = '%u' ", GetGUIDLow(), skill );
|
||||
continue;
|
||||
}
|
||||
|
||||
// enable unlearn button for primary professions only
|
||||
if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION)
|
||||
SetUInt32Value(PLAYER_SKILL_INDEX(count), MAKE_PAIR32(skill,1));
|
||||
else
|
||||
SetUInt32Value(PLAYER_SKILL_INDEX(count), MAKE_PAIR32(skill,0));
|
||||
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(count),MAKE_SKILL_VALUE(value, max));
|
||||
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(count),0);
|
||||
|
||||
mSkillStatus.insert(SkillStatusMap::value_type(skill, SkillStatusData(count, SKILL_UNCHANGED)));
|
||||
|
||||
learnSkillRewardedSpells(skill, value);
|
||||
|
||||
++count;
|
||||
|
||||
if(count >= PLAYER_MAX_SKILLS) // client limit
|
||||
{
|
||||
sLog.outError("Character %u has more than %u skills.", PLAYER_MAX_SKILLS);
|
||||
break;
|
||||
}
|
||||
} while (result->NextRow());
|
||||
delete result;
|
||||
}
|
||||
|
||||
for (; count < PLAYER_MAX_SKILLS; ++count)
|
||||
{
|
||||
SetUInt32Value(PLAYER_SKILL_INDEX(count), 0);
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(count),0);
|
||||
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(count),0);
|
||||
}
|
||||
|
||||
// special settings
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue