mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[8874] Extract player skills from data blob.
Thanks to vladimir for the update query. Please make sure to make BACKUPs before you update your database. The update might take a while depending on the size of your database. Signed-off-by: hunuza <hunuza@gmail.com>
This commit is contained in:
parent
689d931f63
commit
4a6da1ad32
8 changed files with 356 additions and 166 deletions
|
|
@ -5026,15 +5026,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);
|
||||
|
||||
|
|
@ -5047,7 +5044,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;
|
||||
}
|
||||
|
|
@ -5156,13 +5155,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);
|
||||
|
||||
|
|
@ -5177,7 +5176,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))
|
||||
|
|
@ -5275,19 +5276,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()
|
||||
|
|
@ -5297,10 +5299,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)
|
||||
|
|
@ -5309,37 +5313,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();
|
||||
|
|
@ -5353,15 +5372,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);
|
||||
|
|
@ -5369,9 +5389,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)
|
||||
|
|
@ -5382,7 +5408,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);
|
||||
|
|
@ -5400,6 +5426,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);
|
||||
|
||||
|
|
@ -5424,15 +5459,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
|
||||
|
|
@ -5440,78 +5471,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
|
||||
|
|
@ -5519,15 +5543,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
|
||||
|
|
@ -5535,15 +5555,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
|
||||
|
|
@ -14487,7 +14503,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
|
||||
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
|
||||
|
||||
_LoadSkills();
|
||||
_LoadSkills(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSKILLS));
|
||||
|
||||
// make sure the unit is considered out of combat for proper loading
|
||||
ClearInCombat();
|
||||
|
|
@ -15751,6 +15767,7 @@ void Player::SaveToDB()
|
|||
_SaveSpellCooldowns();
|
||||
_SaveActions();
|
||||
_SaveAuras();
|
||||
_SaveSkills();
|
||||
m_achievementMgr.SaveToDB();
|
||||
m_reputationMgr.SaveToDB();
|
||||
_SaveEquipmentSets();
|
||||
|
|
@ -16031,6 +16048,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();)
|
||||
|
|
@ -19882,43 +19939,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