Core/Players: Added support for profession equipment slots
Port From (https://github.com/TrinityCore/TrinityCore/commit/aaa0db28801784e64a845d2df90a0e285062d3a8)
This commit is contained in:
@@ -105,6 +105,7 @@ namespace Framework.Constants
|
||||
|
||||
public const byte End = 30;
|
||||
public const byte Start = Profession1Tool;
|
||||
public const byte MaxCount = Profession2Tool - Profession1Tool;
|
||||
}
|
||||
|
||||
public struct InventorySlots
|
||||
@@ -886,7 +887,7 @@ namespace Framework.Constants
|
||||
Max = 1
|
||||
}
|
||||
|
||||
public enum ItemSubclassPorfession
|
||||
public enum ItemSubclassProfession
|
||||
{
|
||||
Blacksmithing = 0,
|
||||
Leatherworking = 1,
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Framework.Database
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_GLYPHS, "SELECT talentGroup, glyphId FROM character_glyphs WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_TALENTS, "SELECT talentId, talentGroup FROM character_talent WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_PVP_TALENTS, "SELECT talentId0, talentId1, talentId2, talentId3, talentGroup FROM character_pvp_talent WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_SKILLS, "SELECT skill, value, max, professionSlot FROM character_skills WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_RANDOMBG, "SELECT guid FROM character_battleground_random WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_BANNED, "SELECT guid FROM character_banned WHERE guid = ? AND active = 1");
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_QUESTSTATUSREW, "SELECT quest FROM character_queststatus_rewarded WHERE guid = ? AND active = 1");
|
||||
@@ -611,8 +611,8 @@ namespace Framework.Database
|
||||
PrepareStatement(CharStatements.UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, "UPDATE character_queststatus_rewarded SET active = 0 WHERE quest = ? AND guid = ?");
|
||||
PrepareStatement(CharStatements.DEL_INVALID_QUEST_PROGRESS_CRITERIA, "DELETE FROM character_queststatus_objectives_criteria WHERE questObjectiveId = ?");
|
||||
PrepareStatement(CharStatements.DEL_CHAR_SKILL_BY_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?");
|
||||
PrepareStatement(CharStatements.INS_CHAR_SKILLS, "INSERT INTO character_skills (guid, skill, value, max) VALUES (?, ?, ?, ?)");
|
||||
PrepareStatement(CharStatements.UPD_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?");
|
||||
PrepareStatement(CharStatements.INS_CHAR_SKILLS, "INSERT INTO character_skills (guid, skill, value, max, professionSlot) VALUES (?, ?, ?, ?)");
|
||||
PrepareStatement(CharStatements.UPD_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ?, professionSlot = ? WHERE guid = ? AND skill = ?");
|
||||
PrepareStatement(CharStatements.INS_CHAR_SPELL, "INSERT INTO character_spell (guid, spell, active, disabled) VALUES (?, ?, ?, ?)");
|
||||
PrepareStatement(CharStatements.DEL_CHAR_SPELL_FAVORITE, "DELETE FROM character_spell_favorite WHERE guid = ? AND spell = ?");
|
||||
PrepareStatement(CharStatements.DEL_CHAR_SPELL_FAVORITE_BY_CHAR, "DELETE FROM character_spell_favorite WHERE guid = ?");
|
||||
|
||||
@@ -63,23 +63,29 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
static SkillType[] item_weapon_skills =
|
||||
{
|
||||
SkillType.Axes, SkillType.TwoHandedAxes, SkillType.Bows, SkillType.Guns, SkillType.Maces,
|
||||
SkillType.TwoHandedMaces, SkillType.Polearms, SkillType.Swords, SkillType.TwoHandedSwords, SkillType.Warglaives,
|
||||
SkillType.Staves, 0, 0, SkillType.FistWeapons, 0,
|
||||
SkillType.Daggers, 0, 0, SkillType.Crossbows, SkillType.Wands,
|
||||
SkillType.Fishing
|
||||
};
|
||||
|
||||
static SkillType[] item_armor_skills =
|
||||
{
|
||||
0, SkillType.Cloth, SkillType.Leather, SkillType.Mail, SkillType.PlateMail, 0, SkillType.Shield, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static SkillType[] itemProfessionSkills =
|
||||
{
|
||||
SkillType.Blacksmithing, SkillType.Leatherworking, SkillType.Alchemy, SkillType.Herbalism, SkillType.Cooking,
|
||||
SkillType.Mining, SkillType.Tailoring, SkillType.Engineering, SkillType.Enchanting, SkillType.Fishing,
|
||||
SkillType.Skinning, SkillType.Jewelcrafting, SkillType.Inscription, SkillType.Archaeology
|
||||
};
|
||||
|
||||
public SkillType GetSkill()
|
||||
{
|
||||
SkillType[] item_weapon_skills =
|
||||
{
|
||||
SkillType.Axes, SkillType.TwoHandedAxes, SkillType.Bows, SkillType.Guns, SkillType.Maces,
|
||||
SkillType.TwoHandedMaces, SkillType.Polearms, SkillType.Swords, SkillType.TwoHandedSwords, SkillType.Warglaives,
|
||||
SkillType.Staves, 0, 0, SkillType.FistWeapons, 0,
|
||||
SkillType.Daggers, 0, 0, SkillType.Crossbows, SkillType.Wands,
|
||||
SkillType.Fishing
|
||||
};
|
||||
|
||||
SkillType[] item_armor_skills =
|
||||
{
|
||||
0, SkillType.Cloth, SkillType.Leather, SkillType.Mail, SkillType.PlateMail, 0, SkillType.Shield, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
|
||||
switch (GetClass())
|
||||
{
|
||||
case ItemClass.Weapon:
|
||||
@@ -87,13 +93,16 @@ namespace Game.Entities
|
||||
return 0;
|
||||
else
|
||||
return item_weapon_skills[GetSubClass()];
|
||||
|
||||
case ItemClass.Armor:
|
||||
if (GetSubClass() >= (int)ItemSubClassArmor.Max)
|
||||
return 0;
|
||||
else
|
||||
return item_armor_skills[GetSubClass()];
|
||||
|
||||
case ItemClass.Profession:
|
||||
if (GetSubClass() >= (int)ItemSubclassProfession.Max)
|
||||
return 0;
|
||||
else
|
||||
return itemProfessionSkills[GetSubClass()];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -335,6 +335,7 @@ namespace Game.Entities
|
||||
Race race = GetRace();
|
||||
uint count = 0;
|
||||
Dictionary<uint, uint> loadedSkillValues = new();
|
||||
List<ushort> loadedProfessionsWithoutSlot = new(); // fixup old characters
|
||||
if (!result.IsEmpty())
|
||||
{
|
||||
do
|
||||
@@ -348,6 +349,7 @@ namespace Game.Entities
|
||||
var skill = result.Read<ushort>(0);
|
||||
var value = result.Read<ushort>(1);
|
||||
var max = result.Read<ushort>(2);
|
||||
var professionSlot = result.Read<sbyte>(3);
|
||||
|
||||
SkillRaceClassInfoRecord rcEntry = Global.DB2Mgr.GetSkillRaceClassInfo(skill, race, GetClass());
|
||||
if (rcEntry == null)
|
||||
@@ -391,14 +393,14 @@ namespace Game.Entities
|
||||
|
||||
if (skillLine.ParentSkillLineID != 0 && skillLine.ParentTierIndex != 0)
|
||||
{
|
||||
int professionSlot = FindProfessionSlotFor(skill);
|
||||
if (professionSlot != -1)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, (int)professionSlot), skill);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, professionSlot), skill);
|
||||
else
|
||||
loadedProfessionsWithoutSlot.Add(skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SetSkillLineId(skillStatusData.Pos, skill);
|
||||
SetSkillStep(skillStatusData.Pos, step);
|
||||
SetSkillRank(skillStatusData.Pos, value);
|
||||
@@ -433,9 +435,20 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ushort skill in loadedProfessionsWithoutSlot)
|
||||
{
|
||||
int emptyProfessionSlot = FindEmptyProfessionSlotFor(skill);
|
||||
if (emptyProfessionSlot != -1)
|
||||
{
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, emptyProfessionSlot), skill);
|
||||
mSkillStatus[skill].State = SkillState.Changed;
|
||||
}
|
||||
}
|
||||
|
||||
if (HasSkill(SkillType.FistWeapons))
|
||||
SetSkill(SkillType.FistWeapons, 0, GetSkillValue(SkillType.Unarmed), GetMaxSkillValueForLevel());
|
||||
}
|
||||
|
||||
void _LoadSpells(SQLResult result, SQLResult favoritesResult)
|
||||
{
|
||||
if (!result.IsEmpty())
|
||||
@@ -1786,6 +1799,7 @@ namespace Game.Entities
|
||||
|
||||
ushort value = skillInfoField.SkillRank[pair.Value.Pos];
|
||||
ushort max = skillInfoField.SkillMaxRank[pair.Value.Pos];
|
||||
sbyte professionSlot = (sbyte)GetProfessionSlotFor(pair.Key);
|
||||
|
||||
switch (pair.Value.State)
|
||||
{
|
||||
@@ -1795,14 +1809,16 @@ namespace Game.Entities
|
||||
stmt.AddValue(1, (ushort)pair.Key);
|
||||
stmt.AddValue(2, value);
|
||||
stmt.AddValue(3, max);
|
||||
stmt.AddValue(4, professionSlot);
|
||||
trans.Append(stmt);
|
||||
break;
|
||||
case SkillState.Changed:
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.UPD_CHAR_SKILLS);
|
||||
stmt.AddValue(0, value);
|
||||
stmt.AddValue(1, max);
|
||||
stmt.AddValue(2, GetGUID().GetCounter());
|
||||
stmt.AddValue(3, (ushort)pair.Key);
|
||||
stmt.AddValue(2, professionSlot);
|
||||
stmt.AddValue(3, GetGUID().GetCounter());
|
||||
stmt.AddValue(4, (ushort)pair.Key);
|
||||
trans.Append(stmt);
|
||||
break;
|
||||
case SkillState.Deleted:
|
||||
|
||||
@@ -4829,6 +4829,65 @@ namespace Game.Entities
|
||||
slots[2] = InventorySlots.BagStart + 2;
|
||||
slots[3] = InventorySlots.BagStart + 3;
|
||||
break;
|
||||
case InventoryType.ProfessionTool:
|
||||
case InventoryType.ProfessionGear:
|
||||
{
|
||||
bool isProfessionTool = item.GetTemplate().GetInventoryType() == InventoryType.ProfessionTool;
|
||||
|
||||
// Validate item class
|
||||
if (!(item.GetTemplate().GetClass() == ItemClass.Profession))
|
||||
return ItemConst.NullSlot;
|
||||
|
||||
// Check if player has profession skill
|
||||
uint itemSkill = (uint)item.GetTemplate().GetSkill();
|
||||
if (!HasSkill(itemSkill))
|
||||
return ItemConst.NullSlot;
|
||||
|
||||
switch ((ItemSubclassProfession)item.GetTemplate().GetSubClass())
|
||||
{
|
||||
case ItemSubclassProfession.Cooking:
|
||||
slots[0] = isProfessionTool ? ProfessionSlots.CookingTool : ProfessionSlots.CookingGear1;
|
||||
break;
|
||||
case ItemSubclassProfession.Fishing:
|
||||
{
|
||||
// Fishing doesn't make use of gear slots (clientside)
|
||||
if (!isProfessionTool)
|
||||
return ItemConst.NullSlot;
|
||||
|
||||
slots[0] = ProfessionSlots.FishingTool;
|
||||
break;
|
||||
}
|
||||
case ItemSubclassProfession.Blacksmithing :
|
||||
case ItemSubclassProfession.Leatherworking :
|
||||
case ItemSubclassProfession.Alchemy :
|
||||
case ItemSubclassProfession.Herbalism :
|
||||
case ItemSubclassProfession.Mining :
|
||||
case ItemSubclassProfession.Tailoring :
|
||||
case ItemSubclassProfession.Engineering :
|
||||
case ItemSubclassProfession.Enchanting :
|
||||
case ItemSubclassProfession.Skinning :
|
||||
case ItemSubclassProfession.Jewelcrafting :
|
||||
case ItemSubclassProfession.Inscription :
|
||||
{
|
||||
int professionSlot = GetProfessionSlotFor(itemSkill);
|
||||
if (professionSlot == -1)
|
||||
return ItemConst.NullSlot;
|
||||
|
||||
if (isProfessionTool)
|
||||
slots[0] = (byte)(ProfessionSlots.Profession1Tool + professionSlot * ProfessionSlots.MaxCount);
|
||||
else
|
||||
{
|
||||
slots[0] = (byte)(ProfessionSlots.Profession1Gear1 + professionSlot * ProfessionSlots.MaxCount);
|
||||
slots[0] = (byte)(ProfessionSlots.Profession1Gear2 + professionSlot * ProfessionSlots.MaxCount);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return ItemConst.NullSlot;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return ItemConst.NullSlot;
|
||||
}
|
||||
@@ -4970,8 +5029,50 @@ namespace Game.Entities
|
||||
if (!swap && GetItemByPos(InventorySlots.Bag0, eslot) != null)
|
||||
return InventoryResult.NoSlotAvailable;
|
||||
|
||||
// if we are swapping 2 equiped items, CanEquipUniqueItem check
|
||||
// should ignore the item we are trying to swap, and not the
|
||||
// destination item. CanEquipUniqueItem should ignore destination
|
||||
// item only when we are swapping weapon from bag
|
||||
byte ignore = ItemConst.NullSlot;
|
||||
switch (eslot)
|
||||
{
|
||||
case EquipmentSlot.MainHand:
|
||||
ignore = EquipmentSlot.OffHand;
|
||||
break;
|
||||
case EquipmentSlot.OffHand:
|
||||
ignore = EquipmentSlot.MainHand;
|
||||
break;
|
||||
case EquipmentSlot.Finger1:
|
||||
ignore = EquipmentSlot.Finger2;
|
||||
break;
|
||||
case EquipmentSlot.Finger2:
|
||||
ignore = EquipmentSlot.Finger1;
|
||||
break;
|
||||
case EquipmentSlot.Trinket1:
|
||||
ignore = EquipmentSlot.Trinket2;
|
||||
break;
|
||||
case EquipmentSlot.Trinket2:
|
||||
ignore = EquipmentSlot.Trinket1;
|
||||
break;
|
||||
case ProfessionSlots.Profession1Gear1:
|
||||
ignore = ProfessionSlots.Profession1Gear2;
|
||||
break;
|
||||
case ProfessionSlots.Profession1Gear2:
|
||||
ignore = ProfessionSlots.Profession1Gear1;
|
||||
break;
|
||||
case ProfessionSlots.Profession2Gear1:
|
||||
ignore = ProfessionSlots.Profession2Gear2;
|
||||
break;
|
||||
case ProfessionSlots.Profession2Gear2:
|
||||
ignore = ProfessionSlots.Profession2Gear1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ignore == ItemConst.NullSlot || pItem != GetItemByPos(InventorySlots.Bag0, ignore))
|
||||
ignore = eslot;
|
||||
|
||||
// if swap ignore item (equipped also)
|
||||
InventoryResult res2 = CanEquipUniqueItem(pItem, swap ? eslot : ItemConst.NullSlot);
|
||||
InventoryResult res2 = CanEquipUniqueItem(pItem, swap ? ignore : ItemConst.NullSlot);
|
||||
if (res2 != InventoryResult.Ok)
|
||||
return res2;
|
||||
|
||||
|
||||
@@ -828,6 +828,11 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
public void ModifySkillBonus(SkillType skillid, int val, bool talent)
|
||||
{
|
||||
ModifySkillBonus((uint)skillid, val, talent);
|
||||
}
|
||||
|
||||
public void ModifySkillBonus(uint skillid, int val, bool talent)
|
||||
{
|
||||
SkillInfo skillInfoField = m_activePlayerData.Skill;
|
||||
|
||||
@@ -839,6 +844,12 @@ namespace Game.Entities
|
||||
SetSkillPermBonus(skillStatusData.Pos, (ushort)(skillInfoField.SkillPermBonus[skillStatusData.Pos] + val));
|
||||
else
|
||||
SetSkillTempBonus(skillStatusData.Pos, (ushort)(skillInfoField.SkillTempBonus[skillStatusData.Pos] + val));
|
||||
|
||||
// Apply/Remove bonus to child skill lines
|
||||
var childSkillLines = Global.DB2Mgr.GetSkillLinesForParentSkill(skillid);
|
||||
if (childSkillLines != null)
|
||||
foreach (var childSkillLine in childSkillLines)
|
||||
ModifySkillBonus(childSkillLine.Id, val, talent);
|
||||
}
|
||||
|
||||
public void StopCastingBindSight()
|
||||
@@ -1029,13 +1040,34 @@ namespace Game.Entities
|
||||
}
|
||||
public void SetSkill(uint id, uint step, uint newVal, uint maxVal)
|
||||
{
|
||||
if (id == 0)
|
||||
SkillLineRecord skillEntry = CliDB.SkillLineStorage.LookupByKey(id);
|
||||
if (skillEntry == null)
|
||||
{
|
||||
Log.outError(LogFilter.Misc, $"Player::SetSkill: Skill (SkillID: {id}) not found in SkillLineStore for player '{GetName()}' ({GetGUID()})");
|
||||
return;
|
||||
}
|
||||
|
||||
ushort currVal;
|
||||
var skillStatusData = mSkillStatus.LookupByKey(id);
|
||||
SkillInfo skillInfoField = m_activePlayerData.Skill;
|
||||
|
||||
void refreshSkillBonusAuras()
|
||||
{
|
||||
// Temporary bonuses
|
||||
foreach (AuraEffect effect in GetAuraEffectsByType(AuraType.ModSkill))
|
||||
if (effect.GetMiscValue() == id)
|
||||
effect.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
|
||||
foreach (AuraEffect effect in GetAuraEffectsByType(AuraType.ModSkill2))
|
||||
if (effect.GetMiscValue() == id)
|
||||
effect.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
|
||||
// Permanent bonuses
|
||||
foreach (AuraEffect effect in GetAuraEffectsByType(AuraType.ModSkillTalent))
|
||||
if (effect.GetMiscValue() == id)
|
||||
effect.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
}
|
||||
|
||||
// Handle already stored skills
|
||||
if (skillStatusData != null)
|
||||
{
|
||||
@@ -1067,16 +1099,56 @@ namespace Game.Entities
|
||||
UpdateCriteria(CriteriaType.AchieveSkillStep, id);
|
||||
|
||||
// update skill state
|
||||
if (skillStatusData.State == SkillState.Unchanged)
|
||||
if (skillStatusData.State == SkillState.Unchanged || skillStatusData.State == SkillState.Deleted)
|
||||
{
|
||||
if (currVal == 0) // activated skill, mark as new to save into database
|
||||
{
|
||||
skillStatusData.State = SkillState.New;
|
||||
|
||||
// Set profession line
|
||||
int freeProfessionSlot = FindEmptyProfessionSlotFor(id);
|
||||
if (freeProfessionSlot != -1)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, freeProfessionSlot), id);
|
||||
|
||||
refreshSkillBonusAuras();
|
||||
}
|
||||
else // updated skill, mark as changed to save into database
|
||||
skillStatusData.State = SkillState.Changed;
|
||||
}
|
||||
}
|
||||
else if (currVal != 0 && newVal == 0) // Deactivate skill line
|
||||
{
|
||||
// Try to store profession tools and accessories into the bag
|
||||
// If we can't, we can't unlearn the profession
|
||||
int professionSlot = GetProfessionSlotFor(id);
|
||||
if (professionSlot != -1)
|
||||
{
|
||||
byte professionSlotStart = (byte)(ProfessionSlots.Profession1Tool + professionSlot * ProfessionSlots.MaxCount);
|
||||
|
||||
// Get all profession items equipped
|
||||
for (byte slotOffset = 0; slotOffset < ProfessionSlots.MaxCount; ++slotOffset)
|
||||
{
|
||||
Item professionItem = GetItemByPos(InventorySlots.Bag0, (byte)(professionSlotStart + slotOffset));
|
||||
if (professionItem != null)
|
||||
{
|
||||
// Store item in bag
|
||||
List<ItemPosCount> professionItemDest = new();
|
||||
|
||||
if (CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, professionItemDest, professionItem, false) != InventoryResult.Ok)
|
||||
{
|
||||
SendPacket(new DisplayGameError(GameError.InvFull));
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveItem(InventorySlots.Bag0, professionItem.GetSlot(), true);
|
||||
StoreItem(professionItemDest, professionItem, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear profession lines
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, professionSlot), 0u);
|
||||
}
|
||||
|
||||
//remove enchantments needing this skill
|
||||
UpdateSkillEnchantments(id, currVal, 0);
|
||||
// clear skill fields
|
||||
@@ -1088,10 +1160,8 @@ namespace Game.Entities
|
||||
SetSkillPermBonus(skillStatusData.Pos, 0);
|
||||
|
||||
// mark as deleted so the next save will delete the data from the database
|
||||
if (skillStatusData.State != SkillState.New)
|
||||
skillStatusData.State = SkillState.Deleted;
|
||||
else
|
||||
skillStatusData.State = SkillState.Unchanged;
|
||||
skillStatusData.State = SkillState.Deleted;
|
||||
|
||||
|
||||
// remove all spells that related to this skill
|
||||
List<SkillLineAbilityRecord> skillLineAbilities = Global.DB2Mgr.GetSkillLineAbilitiesBySkill(id);
|
||||
@@ -1107,12 +1177,6 @@ namespace Game.Entities
|
||||
SetSkill(childSkillLine.Id, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear profession lines
|
||||
if (m_activePlayerData.ProfessionSkillLine[0] == id)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, 0), 0u);
|
||||
else if (m_activePlayerData.ProfessionSkillLine[1] == id)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, 1), 0u);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1136,13 +1200,6 @@ namespace Game.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
SkillLineRecord skillEntry = CliDB.SkillLineStorage.LookupByKey(id);
|
||||
if (skillEntry == null)
|
||||
{
|
||||
Log.outError(LogFilter.Misc, $"Player.SetSkill: Skill (SkillID: {id}) not found in SkillLineStore for player '{GetName()}' ({GetGUID()})");
|
||||
return;
|
||||
}
|
||||
|
||||
if (skillEntry.ParentSkillLineID != 0)
|
||||
{
|
||||
if (skillEntry.ParentTierIndex > 0)
|
||||
@@ -1168,12 +1225,9 @@ namespace Game.Entities
|
||||
if (!HasSkill((SkillType)childSkillLine.Id))
|
||||
SetSkill(childSkillLine.Id, 0, 0, 0);
|
||||
|
||||
if (skillEntry.CategoryID == SkillCategory.Profession)
|
||||
{
|
||||
int freeProfessionSlot = FindProfessionSlotFor(id);
|
||||
if (freeProfessionSlot != -1)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, freeProfessionSlot), id);
|
||||
}
|
||||
int freeProfessionSlot = FindEmptyProfessionSlotFor(id);
|
||||
if (freeProfessionSlot != -1)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ProfessionSkillLine, freeProfessionSlot), id);
|
||||
}
|
||||
|
||||
if (skillStatusData == null)
|
||||
@@ -1194,19 +1248,7 @@ namespace Game.Entities
|
||||
|
||||
if (newVal != 0)
|
||||
{
|
||||
// temporary bonuses
|
||||
foreach (var auraEffect in GetAuraEffectsByType(AuraType.ModSkill))
|
||||
if (auraEffect.GetMiscValue() == id)
|
||||
auraEffect.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
|
||||
foreach (var auraEffect in GetAuraEffectsByType(AuraType.ModSkill2))
|
||||
if (auraEffect.GetMiscValue() == id)
|
||||
auraEffect.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
|
||||
// permanent bonuses
|
||||
foreach (var auraEffect in GetAuraEffectsByType(AuraType.ModSkillTalent))
|
||||
if (auraEffect.GetMiscValue() == id)
|
||||
auraEffect.HandleEffect(this, AuraEffectHandleModes.Skill, true);
|
||||
refreshSkillBonusAuras();
|
||||
|
||||
// Learn all spells for skill
|
||||
LearnSkillRewardedSpells(id, newVal, GetRace());
|
||||
@@ -1609,12 +1651,24 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
int FindProfessionSlotFor(uint skillId)
|
||||
int GetProfessionSlotFor(uint skillId)
|
||||
{
|
||||
for (var i = 0; i < m_activePlayerData.ProfessionSkillLine.GetSize(); ++i)
|
||||
if (m_activePlayerData.ProfessionSkillLine[i] == skillId)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FindEmptyProfessionSlotFor(uint skillId)
|
||||
{
|
||||
SkillLineRecord skillEntry = CliDB.SkillLineStorage.LookupByKey(skillId);
|
||||
if (skillEntry == null)
|
||||
return -1;
|
||||
|
||||
if (skillEntry.ParentSkillLineID != 0 || skillEntry.CategoryID != SkillCategory.Profession)
|
||||
return -1;
|
||||
|
||||
int index = 0;
|
||||
// if there is no same profession, find any free slot
|
||||
foreach (var b in m_activePlayerData.ProfessionSkillLine)
|
||||
|
||||
Reference in New Issue
Block a user