Core/Guilds: implement guild profession fields for guild roster packets

This commit is contained in:
Ovahlord
2019-09-03 16:31:59 +02:00
parent d17d8e9277
commit 6d759dc6e8
6 changed files with 107 additions and 4 deletions

View File

@@ -121,7 +121,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER_BGDATA, "SELECT instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT talentGroup, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_TALENTS, "SELECT spell, talentGroup FROM character_talent WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHARACTER_RANDOMBG, "SELECT guid FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_BANNED, "SELECT guid FROM character_banned WHERE guid = ? AND active = 1", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUSREW, "SELECT quest FROM character_queststatus_rewarded WHERE guid = ? AND active = 1", CONNECTION_ASYNC);

View File

@@ -6118,6 +6118,9 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
}
}
}
if (Guild * guild = GetGuild())
guild->UpdateMemberData(this, GUILD_MEMBER_DATA_PROFESSIONS, 0);
}
bool Player::HasSkill(uint32 skill) const
@@ -17330,6 +17333,34 @@ bool Player::LoadPositionFromDB(uint32& mapid, float& x, float& y, float& z, flo
return true;
}
void Player::LoadPrimaryProfessionsFromDB(ObjectGuid guid, std::vector<PrimaryProfessionData>& data)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SKILLS);
stmt->setUInt32(0, guid.GetCounter());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (result)
{
do
{
Field* fields = result->Fetch();
uint16 skill = fields[0].GetUInt16();
uint16 value = fields[1].GetUInt16();
uint16 max = fields[2].GetUInt16();
SkillLineEntry const* skillLine = sSkillLineStore.LookupEntry(skill);
if (!skillLine || skillLine->categoryId != SKILL_CATEGORY_PROFESSION)
continue;
PrimaryProfessionData profession;
profession.SkillId = skill;
profession.Step = max / 75;
profession.Rank = value;
data.push_back(profession);
} while (result->NextRow());
}
}
void Player::SetHomebind(WorldLocation const& loc, uint32 areaId)
{
loc.GetPosition(m_homebindX, m_homebindY, m_homebindZ);
@@ -28584,3 +28615,26 @@ void Player::SendTamePetFailure(PetTameFailureReason reason)
data << uint8(reason);
SendDirectMessage(&data);
}
void Player::GetPrimaryProfessionData(PrimaryProfessionData* data)
{
for (uint8 i = 0; i < 2; i++)
{
uint32 skillId = GetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1 + i);
SkillStatusMap::iterator itr = mSkillStatus.find(skillId);
if (itr != mSkillStatus.end() && itr->second.uState != SKILL_DELETED)
{
uint16 field = itr->second.pos / 2;
uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
data[i].SkillId = skillId;
data[i].Step = GetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset);
data[i].Rank = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset);
}
else
{
data[i].SkillId = 0;
data[i].Step = 0;
data[i].Rank = 0;
}
}
}

View File

@@ -376,6 +376,13 @@ struct EnchantDuration
typedef std::list<EnchantDuration> EnchantDurationList;
typedef std::list<Item*> ItemDurationList;
struct PrimaryProfessionData
{
uint32 SkillId = 0;
uint32 Step = 0;
uint32 Rank = 0;
};
enum DrunkenState
{
DRUNKEN_SOBER = 0,
@@ -1089,6 +1096,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SendTamePetFailure(PetTameFailureReason reason);
void GetPrimaryProfessionData(PrimaryProfessionData* professions);
PlayerTaxi m_taxi;
void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = nullptr, uint32 spellid = 0);
@@ -1493,6 +1502,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
static float GetFloatValueFromArray(Tokenizer const& data, uint16 index);
static uint32 GetZoneIdFromDB(ObjectGuid guid);
static bool LoadPositionFromDB(uint32& mapid, float& x, float& y, float& z, float& o, bool& in_flight, ObjectGuid guid);
static void LoadPrimaryProfessionsFromDB(ObjectGuid guid, std::vector<PrimaryProfessionData>& data);
static bool IsValidGender(uint8 Gender) { return Gender <= GENDER_FEMALE; }
static bool ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, bool create = false);

View File

@@ -676,6 +676,7 @@ Guild::Member::Member(ObjectGuid::LowType guildId, ObjectGuid guid, uint8 rankId
m_weekReputation(0)
{
memset(m_bankWithdraw, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(int32));
memset(m_professions, 0, GUILD_PROFESSION_COUNT * sizeof(PrimaryProfessionData));
}
void Guild::Member::SetStats(Player* player)
@@ -799,7 +800,21 @@ bool Guild::Member::LoadFromDB(Field* fields)
m_zoneId = Player::GetZoneIdFromDB(m_guid);
}
std::vector<PrimaryProfessionData> professions;
Player::LoadPrimaryProfessionsFromDB(m_guid, professions);
if (professions.size() > GUILD_PROFESSION_COUNT)
TC_LOG_ERROR("guild", "Guild::Member::LoadFromDB: Character %s has too many primary professions. Skipped loading profession data.", m_guid.ToString().c_str());
else
{
uint8 index = 0;
for (PrimaryProfessionData profession : professions)
{
m_professions[index].SkillId = profession.SkillId;
m_professions[index].Rank = profession.Rank;
m_professions[index].Step = profession.Step;
index++;
}
}
ResetFlags();
return true;
@@ -899,6 +914,15 @@ void Guild::Member::ResetWeekActivityAndReputation()
CharacterDatabase.CommitTransaction(trans);
}
void Guild::Member::UpdatePrimaryProfessionData()
{
if (!IsOnline())
return;
Player* player = FindConnectedPlayer();
player->GetPrimaryProfessionData(m_professions);
}
// Get amount of money/slots left for today.
// If (tabId == GUILD_BANK_MAX_TABS) return money amount.
// Otherwise return remaining items amount for specified tab.
@@ -1477,6 +1501,9 @@ void Guild::UpdateMemberData(Player* player, uint8 dataid, uint32 value)
case GUILD_MEMBER_DATA_LEVEL:
member->SetLevel(value);
break;
case GUILD_MEMBER_DATA_PROFESSIONS:
member->UpdatePrimaryProfessionData();
break;
default:
TC_LOG_ERROR("guild", "Guild::UpdateMemberData: Called with incorrect DATAID %u (value %u)", dataid, value);
return;
@@ -1556,7 +1583,12 @@ void Guild::HandleRoster(WorldSession* session)
memberData.LastSave = member->GetInactiveDays();
memberData.GuildRepToCap = sWorld->getIntConfig(CONFIG_GUILD_WEEKLY_REP_CAP) - member->GetWeekReputation();
//GuildRosterProfessionData
for (uint8 i = 0; i < GUILD_PROFESSION_COUNT; i++)
{
memberData.Profession[i].DbID = member->GetPrimaryProfessionData(i).SkillId;
memberData.Profession[i].Step = member->GetPrimaryProfessionData(i).Step;
memberData.Profession[i].Rank = member->GetPrimaryProfessionData(i).Rank;
}
memberData.VirtualRealmAddress = 0;
memberData.Status = member->GetFlags();
@@ -2927,6 +2959,7 @@ bool Guild::AddMember(SQLTransaction& trans, ObjectGuid guid, uint8 rankId)
player->SetGuildIdInvited(0);
player->SetRank(rankId);
player->SetGuildLevel(GetLevel());
member->UpdatePrimaryProfessionData();
SendLoginInfo(player->GetSession());
name = player->GetName();
}

View File

@@ -33,6 +33,7 @@ class Unit;
class WorldPacket;
class WorldSession;
struct ItemPosCount;
struct PrimaryProfessionData;
enum AchievementCriteriaTypes : uint8;
enum InventoryResult : uint8;
enum LocaleConstant : uint8;
@@ -49,6 +50,7 @@ enum GuildMisc
GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF,
GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF,
GUILD_EXPERIENCE_UNCAPPED_LEVEL = 20, ///> Hardcoded in client, starting from this level, guild daily experience gain is unlimited.
GUILD_PROFESSION_COUNT = 2,
TAB_UNDEFINED = 0xFF,
};
@@ -57,6 +59,7 @@ enum GuildMemberData
GUILD_MEMBER_DATA_ZONEID,
GUILD_MEMBER_DATA_ACHIEVEMENT_POINTS,
GUILD_MEMBER_DATA_LEVEL,
GUILD_MEMBER_DATA_PROFESSIONS
};
enum GuildDefaultRanks
@@ -354,6 +357,7 @@ private:
void AddActivity(uint64 activity);
void SetWeekReputation(uint32 reputation) { m_weekReputation = reputation; }
void AddReputation(uint32 rep, Player *player);
void UpdatePrimaryProfessionData();
void AddFlag(uint8 var) { m_flags |= var; }
void RemFlag(uint8 var) { m_flags &= ~var; }
@@ -381,6 +385,7 @@ private:
uint64 GetWeekActivity() const { return m_weekActivity; }
uint32 GetTotalReputation() const { return m_totalReputation; }
uint32 GetWeekReputation() const { return m_weekReputation; }
PrimaryProfessionData GetPrimaryProfessionData(uint8 index) const { return m_professions[index]; }
std::set<uint32> GetTrackedCriteriaIds() const { return m_trackedCriteriaIds; }
void SetTrackedCriteriaIds(std::set<uint32> criteriaIds) { m_trackedCriteriaIds.swap(criteriaIds); }
@@ -427,6 +432,7 @@ private:
uint64 m_weekActivity;
uint32 m_totalReputation;
uint32 m_weekReputation;
PrimaryProfessionData m_professions[GUILD_PROFESSION_COUNT];
};
// Base class for event entries

View File

@@ -256,8 +256,8 @@ WorldPacket const* WorldPackets::Guild::GuildRoster::Write()
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRosterProfessionData const& rosterProfessionData)
{
data << uint32(rosterProfessionData.Rank);
data << uint32(rosterProfessionData.Step);
data << uint32(rosterProfessionData.Rank);
data << uint32(rosterProfessionData.DbID);
return data;