Core/Guilds: implement Guild Challenges
This commit is contained in:
1 parent
8a63294194
commit
be1615d5f4
16 files changed
+369
-101
No files matched your search
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE `guild`
|
||||
ADD COLUMN `completedDungeonChallenges` int(10) unsigned DEFAULT '0' AFTER `todayExperience`,
|
||||
ADD COLUMN `completedRaidChallenges` int(10) unsigned DEFAULT '0' AFTER `completedDungeonChallenges`,
|
||||
ADD COLUMN `completedRatedBattlegroundChallenges` int(10) unsigned DEFAULT '0' AFTER `completedRaidChallenges`;
|
||||
@@ -235,6 +235,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE, "UPDATE guild SET todayExperience = 0", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_GUILD_NEWS, "INSERT INTO guild_newslog (guildid, LogGuid, EventType, PlayerGuid, Flags, Value, Timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)"
|
||||
" ON DUPLICATE KEY UPDATE LogGuid = VALUES (LogGuid), EventType = VALUES (EventType), PlayerGuid = VALUES (PlayerGuid), Flags = VALUES (Flags), Value = VALUES (Value), Timestamp = VALUES (Timestamp)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_GUILD_CHALLENGE, "UPDATE guild SET completedDungeonChallenges = ?, completedRaidChallenges = ?, completedRatedBattlegroundChallenges = ? WHERE guildId = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_GUILD_RESET_CHALLENGE, "UPDATE guild SET completedDungeonChallenges = 0, completedRaidChallenges = 0, completedRatedBattlegroundChallenges = 0 WHERE guildId = ?", CONNECTION_ASYNC);
|
||||
|
||||
// Chat channel handling
|
||||
PrepareStatement(CHAR_SEL_CHANNEL, "SELECT name, announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH);
|
||||
|
||||
@@ -202,6 +202,8 @@ enum CharacterDatabaseStatements
|
||||
CHAR_UPD_GUILD_EXPERIENCE,
|
||||
CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE,
|
||||
CHAR_INS_GUILD_NEWS,
|
||||
CHAR_UPD_GUILD_CHALLENGE,
|
||||
CHAR_UPD_GUILD_RESET_CHALLENGE,
|
||||
|
||||
CHAR_SEL_CHANNEL,
|
||||
CHAR_INS_CHANNEL,
|
||||
|
||||
@@ -220,6 +220,19 @@ bool CharacterCache::GetCharacterNameByGuid(ObjectGuid guid, std::string& name)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CharacterCache::GetPlayerGuildIdByGUID(ObjectGuid guid, uint32& guildId) const
|
||||
{
|
||||
auto itr = _characterCacheStore.find(guid);
|
||||
if (itr == _characterCacheStore.end())
|
||||
return false;
|
||||
|
||||
if (!itr->second.GuildId)
|
||||
return false;
|
||||
|
||||
guildId = itr->second.GuildId;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 CharacterCache::GetCharacterTeamByGuid(ObjectGuid guid) const
|
||||
{
|
||||
auto itr = _characterCacheStore.find(guid);
|
||||
|
||||
@@ -58,6 +58,7 @@ class TC_GAME_API CharacterCache
|
||||
|
||||
ObjectGuid GetCharacterGuidByName(std::string const& name) const;
|
||||
bool GetCharacterNameByGuid(ObjectGuid guid, std::string& name) const;
|
||||
bool GetPlayerGuildIdByGUID(ObjectGuid guid, uint32 &guildId) const;
|
||||
uint32 GetCharacterTeamByGuid(ObjectGuid guid) const;
|
||||
uint32 GetCharacterAccountIdByGuid(ObjectGuid guid) const;
|
||||
uint32 GetCharacterAccountIdByName(std::string const& name) const;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ObjectMgr.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "Group.h"
|
||||
#include "Guild.h"
|
||||
#include "Formulas.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Battleground.h"
|
||||
@@ -205,7 +206,8 @@ void Group::LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uin
|
||||
member.guid = ObjectGuid(HighGuid::Player, guidLow);
|
||||
|
||||
// skip non-existed member
|
||||
if (!sCharacterCache->GetCharacterNameByGuid(member.guid, member.name))
|
||||
if (!sCharacterCache->GetCharacterNameByGuid(member.guid, member.name) ||
|
||||
!sCharacterCache->GetPlayerGuildIdByGUID(member.guid, member.guildId))
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER);
|
||||
stmt->setUInt32(0, guidLow);
|
||||
@@ -411,6 +413,7 @@ bool Group::AddMember(Player* player)
|
||||
member.group = subGroup;
|
||||
member.flags = 0;
|
||||
member.roles = 0;
|
||||
member.guildId = player->GetGuildId();
|
||||
m_memberSlots.push_back(member);
|
||||
|
||||
SubGroupCounterIncrease(subGroup);
|
||||
@@ -1867,6 +1870,87 @@ bool Group::_setMembersGroup(ObjectGuid guid, uint8 group)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Group::MemberLevelIsInRange(uint32 levelMin, uint32 levelMax)
|
||||
{
|
||||
for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
|
||||
if (Player *member = ObjectAccessor::FindPlayer(itr->guid))
|
||||
if (member->getLevel() < levelMin || member->getLevel() > levelMax)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Group::IsGuildGroupFor(Player* player)
|
||||
{
|
||||
if (!IsMember(player->GetGUID()))
|
||||
return false;
|
||||
|
||||
if (!player->GetGuildId())
|
||||
return false;
|
||||
|
||||
if (!player->GetMap()->IsDungeon() &&
|
||||
!(player->InArena() && player->GetBattleground()->isRated()))
|
||||
return false;
|
||||
|
||||
if (GetMembersCountOfGuild(player->GetGuildId()) < GetNeededMembersOfSameGuild((player->InArena() && player->GetBattleground()->isRated())
|
||||
? player->GetBattleground()->GetArenaType() : 0, player->GetMap()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 Group::GetMembersCountOfGuild(uint32 guildId)
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
|
||||
if (itr->guildId == guildId)
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32 Group::GetNeededMembersOfSameGuild(uint8 arenaType, Map const *map)
|
||||
{
|
||||
// For arena (100% of member)
|
||||
if (arenaType && map->IsBattleArena())
|
||||
return arenaType;
|
||||
|
||||
if (map->IsNonRaidDungeon())
|
||||
return 3;
|
||||
|
||||
if (map->IsRaid())
|
||||
{
|
||||
if (map->GetEntry()->Expansion() == 0) // classic
|
||||
return 10;
|
||||
|
||||
if (map->GetEntry()->Expansion() == 1) // TBC
|
||||
return 8;
|
||||
|
||||
if (map->Is25ManRaid())
|
||||
return 20;
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Group::UpdateGuildFor(ObjectGuid guid, uint32 guildId)
|
||||
{
|
||||
for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
|
||||
{
|
||||
if (itr->guid == guid)
|
||||
itr->guildId = guildId; // Change guild ID
|
||||
|
||||
// Update guild flag
|
||||
if (itr->guildId == guildId)
|
||||
if (Player* member = ObjectAccessor::FindPlayer(itr->guid))
|
||||
if (Guild* guild = member->GetGuild())
|
||||
guild->HandleGuildPartyRequest(member->GetSession());
|
||||
}
|
||||
}
|
||||
|
||||
bool Group::SameSubGroup(Player const* member1, Player const* member2) const
|
||||
{
|
||||
if (!member1 || !member2)
|
||||
|
||||
@@ -172,6 +172,7 @@ class TC_GAME_API Group
|
||||
uint8 group;
|
||||
uint8 flags;
|
||||
uint8 roles;
|
||||
uint32 guildId;
|
||||
};
|
||||
typedef std::list<MemberSlot> MemberSlotList;
|
||||
typedef MemberSlotList::const_iterator member_citerator;
|
||||
@@ -353,6 +354,13 @@ class TC_GAME_API Group
|
||||
// FG: evil hacks
|
||||
void BroadcastGroupUpdate(void);
|
||||
|
||||
// guild misc
|
||||
bool IsGuildGroupFor(Player* player);
|
||||
uint32 GetMembersCountOfGuild(uint32 guildId);
|
||||
uint32 GetNeededMembersOfSameGuild(uint8 arenaType, Map const* map);
|
||||
bool MemberLevelIsInRange(uint32 levelMin, uint32 levelMax);
|
||||
void UpdateGuildFor(ObjectGuid guid, uint32 guildId);
|
||||
|
||||
protected:
|
||||
bool _setMembersGroup(ObjectGuid guid, uint8 group);
|
||||
void _homebindIfInstance(Player* player);
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Group.h"
|
||||
#include "Battleground.h"
|
||||
|
||||
#define MAX_GUILD_BANK_TAB_TEXT_LEN 500
|
||||
#define EMBLEM_PRICE 10 * GOLD
|
||||
@@ -1175,6 +1177,9 @@ Guild::Guild():
|
||||
_todayExperience(0)
|
||||
{
|
||||
memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*));
|
||||
|
||||
for (uint8 i = 0; i < MAX_GUILD_CHALLENGE_TYPE; i++)
|
||||
_currChallengeCount[i] = 0;
|
||||
}
|
||||
|
||||
Guild::~Guild()
|
||||
@@ -1224,6 +1229,9 @@ bool Guild::Create(Player* pLeader, std::string const& name)
|
||||
_todayExperience = 0;
|
||||
_CreateLogHolders();
|
||||
|
||||
for (uint8 i = 0; i < MAX_GUILD_CHALLENGE_TYPE; i++)
|
||||
_currChallengeCount[i] = 0;
|
||||
|
||||
TC_LOG_DEBUG("guild", "GUILD: creating guild [%s] for leader %s (%u)",
|
||||
name.c_str(), pLeader->GetName().c_str(), m_leaderGuid.GetCounter());
|
||||
|
||||
@@ -2177,18 +2185,29 @@ void Guild::HandleDisband(WorldSession* session)
|
||||
void Guild::HandleGuildPartyRequest(WorldSession* session)
|
||||
{
|
||||
Player* player = session->GetPlayer();
|
||||
Group* group = player->GetGroup();
|
||||
|
||||
// Make sure player is a member of the guild and that he is in a group.
|
||||
if (!IsMember(player->GetGUID()) || !group)
|
||||
if (!IsMember(player->GetGUID()))
|
||||
return;
|
||||
|
||||
bool guildParty = false;
|
||||
float xpMultiplier = 0.0f;
|
||||
uint32 CurrGuildPartyMembers = 0, NeededGuildPartyMembers = 0;
|
||||
|
||||
if (Group* group = player->GetGroup())
|
||||
{
|
||||
guildParty = group->IsGuildGroupFor(player);
|
||||
CurrGuildPartyMembers = group->GetMembersCountOfGuild(player->GetGuildId());
|
||||
NeededGuildPartyMembers = group->GetNeededMembersOfSameGuild((player->InArena() && player->GetBattleground()->isRated()) ?
|
||||
player->GetBattleground()->GetArenaType() : 0, player->GetMap());
|
||||
}
|
||||
|
||||
WorldPacket data(SMSG_GUILD_PARTY_STATE_RESPONSE, 13);
|
||||
data.WriteBit(player->GetMap()->GetOwnerGuildId(player->GetTeam()) == GetId()); // Is guild group
|
||||
data.WriteBit(guildParty); // Is guild group
|
||||
data.FlushBits();
|
||||
data << float(0.f); // Guild XP multiplier
|
||||
data << uint32(0); // Current guild members
|
||||
data << uint32(0); // Needed guild members
|
||||
data << float(xpMultiplier); // Guild XP multiplier
|
||||
data << uint32(CurrGuildPartyMembers); // Current guild members
|
||||
data << uint32(NeededGuildPartyMembers); // Needed guild members
|
||||
|
||||
session->SendPacket(&data);
|
||||
TC_LOG_DEBUG("guild", "SMSG_GUILD_PARTY_STATE_RESPONSE [%s]", session->GetPlayerInfo().c_str());
|
||||
@@ -2196,22 +2215,32 @@ void Guild::HandleGuildPartyRequest(WorldSession* session)
|
||||
|
||||
void Guild::HandleGuildRequestChallengeUpdate(WorldSession* session)
|
||||
{
|
||||
WorldPacket data(SMSG_GUILD_CHALLENGE_UPDATED, 4 * GUILD_CHALLENGES_TYPES * 5);
|
||||
WorldPacket data(SMSG_GUILD_CHALLENGE_UPDATED, 80);
|
||||
|
||||
for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
|
||||
data << uint32(GuildChallengeXPReward[i]);
|
||||
data << uint32(0);
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_DUNGEON_XP));
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RAID_XP));
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RATEDBG_XP));
|
||||
|
||||
for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
|
||||
data << uint32(GuildChallengeGoldReward[i]);
|
||||
data << uint32(0);
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_DUNGEON_GOLD) * 2);
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RAID_GOLD) * 2);
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RATEDBG_GOLD) * 2);
|
||||
|
||||
for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
|
||||
data << uint32(GuildChallengesPerWeek[i]);
|
||||
data << uint32(0);
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_DUNGEON_NEEDED));
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RAID_NEEDED));
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RATEDBG_NEEDED));
|
||||
|
||||
for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
|
||||
data << uint32(GuildChallengeMaxLevelGoldReward[i]);
|
||||
data << uint32(0);
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_DUNGEON_GOLD));
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RAID_GOLD));
|
||||
data << uint32(sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RATEDBG_GOLD));
|
||||
|
||||
for (int i = 0; i < GUILD_CHALLENGES_TYPES; ++i)
|
||||
data << uint32(0); /// @todo current count
|
||||
data << uint32(0);
|
||||
data << uint32(_currChallengeCount[GUILD_CHALLENGE_TYPE_DUNGEON]);
|
||||
data << uint32(_currChallengeCount[GUILD_CHALLENGE_TYPE_RAID]);
|
||||
data << uint32(_currChallengeCount[GUILD_CHALLENGE_TYPE_RATED_BG]);
|
||||
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
@@ -2445,6 +2474,11 @@ bool Guild::LoadFromDB(Field* fields)
|
||||
for (uint8 i = 0; i < purchasedTabs; ++i)
|
||||
m_bankTabs[i] = new BankTab(m_id, i);
|
||||
|
||||
_currChallengeCount[GUILD_CHALLENGE_TYPE_DUNGEON] = uint8(fields[16].GetUInt32());
|
||||
_currChallengeCount[GUILD_CHALLENGE_TYPE_RAID] = uint8(fields[17].GetUInt32());
|
||||
_currChallengeCount[GUILD_CHALLENGE_TYPE_RATED_BG] = uint8(fields[18].GetUInt32());
|
||||
|
||||
|
||||
_CreateLogHolders();
|
||||
return true;
|
||||
}
|
||||
@@ -2810,6 +2844,11 @@ bool Guild::AddMember(SQLTransaction& trans, ObjectGuid guid, uint8 rankId)
|
||||
_BroadcastEvent(GE_JOINED, guid, name.c_str());
|
||||
sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(lowguid);
|
||||
|
||||
// Update GuildId in group
|
||||
if (player)
|
||||
if (Group* group = player->GetGroup())
|
||||
group->UpdateGuildFor(guid, m_id);
|
||||
|
||||
// Call scripts if member was succesfully added (and stored to database)
|
||||
sScriptMgr->OnGuildAddMember(this, player, rankId);
|
||||
|
||||
@@ -2874,6 +2913,10 @@ void Guild::DeleteMember(SQLTransaction& trans, ObjectGuid guid, bool isDisbandi
|
||||
if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i))
|
||||
if (entry->Level <= GetLevel())
|
||||
player->RemoveSpell(entry->SpellId, false, false);
|
||||
|
||||
// Update GuildId in group
|
||||
if (Group* group = player->GetGroup())
|
||||
group->UpdateGuildFor(guid, 0);
|
||||
}
|
||||
else
|
||||
sCharacterCache->UpdateCharacterGuildId(guid, 0);
|
||||
@@ -3609,7 +3652,74 @@ void Guild::SendGuildRanksUpdate(ObjectGuid setterGuid, ObjectGuid targetGuid, u
|
||||
targetGuid.ToString().c_str(), setterGuid.ToString().c_str(), rank);
|
||||
}
|
||||
|
||||
void Guild::GiveXP(uint32 xp, Player* source)
|
||||
void Guild::CompleteChallenge(uint8 challengeType, Player* source)
|
||||
{
|
||||
/*
|
||||
source is used to complete guild level achievement (UpdateAchievementCriteria need a player)
|
||||
*/
|
||||
|
||||
uint32 countNeeded = 0;
|
||||
uint32 gold = 0;
|
||||
uint32 xp = 0;
|
||||
|
||||
switch (challengeType)
|
||||
{
|
||||
case GUILD_CHALLENGE_TYPE_DUNGEON:
|
||||
gold = sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_DUNGEON_GOLD);
|
||||
xp = sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_DUNGEON_XP);
|
||||
countNeeded = sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_DUNGEON_NEEDED);
|
||||
break;
|
||||
case GUILD_CHALLENGE_TYPE_RAID:
|
||||
gold = sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RAID_GOLD);
|
||||
xp = sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RAID_XP);
|
||||
countNeeded = sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RAID_NEEDED);
|
||||
break;
|
||||
case GUILD_CHALLENGE_TYPE_RATED_BG:
|
||||
gold = sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RATEDBG_GOLD);
|
||||
xp = sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RATEDBG_XP);
|
||||
countNeeded = sWorld->getIntConfig(CONFIG_GUILD_CHALLENGE_RATEDBG_NEEDED);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currChallengeCount[challengeType] >= countNeeded)
|
||||
return;
|
||||
|
||||
_currChallengeCount[challengeType] += 1;
|
||||
|
||||
if (GetLevel() >= sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL))
|
||||
gold *= 2;
|
||||
|
||||
// Send notification
|
||||
WorldPacket data(SMSG_GUILD_CHALLENGE_COMPLETED, 20);
|
||||
data << uint32(challengeType);
|
||||
data << gold;
|
||||
data << uint32(_currChallengeCount[challengeType]);
|
||||
data << xp;
|
||||
data << countNeeded;
|
||||
BroadcastPacket(&data);
|
||||
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE_TYPE, challengeType, 0, 0, NULL, source);
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE, 0, 0, 0, NULL, source);
|
||||
|
||||
// Give Reward now
|
||||
GiveXP(xp, source, true);
|
||||
SaveToDB(); // Save xp
|
||||
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
_ModifyBankMoney(trans, uint64(gold * 10000), true);
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_CHALLENGE);
|
||||
stmt->setUInt32(0, _currChallengeCount[GUILD_CHALLENGE_TYPE_DUNGEON]);
|
||||
stmt->setUInt32(1, _currChallengeCount[GUILD_CHALLENGE_TYPE_RAID]);
|
||||
stmt->setUInt32(2, _currChallengeCount[GUILD_CHALLENGE_TYPE_RATED_BG]);
|
||||
stmt->setUInt32(3, m_id);
|
||||
trans->Append(stmt);
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
void Guild::GiveXP(uint32 xp, Player* source, bool rewardedByChallenge)
|
||||
{
|
||||
if (!sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED))
|
||||
return;
|
||||
@@ -3622,12 +3732,16 @@ void Guild::GiveXP(uint32 xp, Player* source)
|
||||
if (GetLevel() < GUILD_EXPERIENCE_UNCAPPED_LEVEL)
|
||||
xp = std::min(xp, sWorld->getIntConfig(CONFIG_GUILD_DAILY_XP_CAP) - uint32(_todayExperience));
|
||||
|
||||
WorldPacket data(SMSG_GUILD_XP_GAIN, 8);
|
||||
data << uint64(xp);
|
||||
source->GetSession()->SendPacket(&data);
|
||||
|
||||
_experience += xp;
|
||||
_todayExperience += xp;
|
||||
|
||||
if (!rewardedByChallenge)
|
||||
{
|
||||
_todayExperience += xp;
|
||||
|
||||
WorldPacket data(SMSG_GUILD_XP_GAIN, 8);
|
||||
data << uint64(xp);
|
||||
source->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
if (!xp)
|
||||
return;
|
||||
@@ -3663,6 +3777,10 @@ void Guild::GiveXP(uint32 xp, Player* source)
|
||||
|
||||
++oldLevel;
|
||||
}
|
||||
|
||||
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
if (Player* player = itr->second->FindPlayer())
|
||||
SendGuildXP(player->GetSession());
|
||||
}
|
||||
|
||||
void Guild::SendGuildXP(WorldSession* session /* = NULL */) const
|
||||
@@ -3691,6 +3809,17 @@ void Guild::SendGuildReputationWeeklyCap(WorldSession* session, uint32 reputatio
|
||||
void Guild::ResetTimes(bool weekly)
|
||||
{
|
||||
_todayExperience = 0;
|
||||
|
||||
if (weekly)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_GUILD_CHALLENGE_TYPE; i++)
|
||||
_currChallengeCount[i] = 0;
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RESET_CHALLENGE);
|
||||
stmt->setInt32(0, m_id);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
itr->second->ResetValues(weekly);
|
||||
|
||||
@@ -269,12 +269,13 @@ struct GuildReward
|
||||
uint32 const MinNewsItemLevel[MAX_CONTENT] = { 61, 90, 200, 353 };
|
||||
|
||||
// Guild Challenge
|
||||
#define GUILD_CHALLENGES_TYPES 4
|
||||
|
||||
const uint32 GuildChallengeGoldReward[GUILD_CHALLENGES_TYPES] = { 0, 250, 1000, 500 };
|
||||
const uint32 GuildChallengeMaxLevelGoldReward[GUILD_CHALLENGES_TYPES] = { 0, 125, 500, 250 };
|
||||
const uint32 GuildChallengeXPReward[GUILD_CHALLENGES_TYPES] = { 0, 300000, 3000000, 1500000 };
|
||||
const uint32 GuildChallengesPerWeek[GUILD_CHALLENGES_TYPES] = { 0, 7, 1, 3 };
|
||||
enum GuildChallengeTypes
|
||||
{
|
||||
GUILD_CHALLENGE_TYPE_DUNGEON = 1,
|
||||
GUILD_CHALLENGE_TYPE_RAID = 2,
|
||||
GUILD_CHALLENGE_TYPE_RATED_BG = 3,
|
||||
MAX_GUILD_CHALLENGE_TYPE,
|
||||
};
|
||||
|
||||
// Emblem info
|
||||
class TC_GAME_API EmblemInfo
|
||||
@@ -882,10 +883,12 @@ public:
|
||||
|
||||
// Guild leveling
|
||||
uint8 GetLevel() const { return _level; }
|
||||
void GiveXP(uint32 xp, Player* source);
|
||||
void GiveXP(uint32 xp, Player* source, bool rewardedByChallenge = false);
|
||||
uint64 GetExperience() const { return _experience; }
|
||||
uint64 GetTodayExperience() const { return _todayExperience; }
|
||||
|
||||
void CompleteChallenge(uint8 challengeType, Player* source);
|
||||
|
||||
void AddGuildNews(uint8 type, ObjectGuid guid, uint32 flags, uint32 value);
|
||||
|
||||
EmblemInfo const& GetEmblemInfo() const { return m_emblemInfo; }
|
||||
@@ -920,6 +923,8 @@ protected:
|
||||
uint64 _experience;
|
||||
uint64 _todayExperience;
|
||||
|
||||
uint8 _currChallengeCount[MAX_GUILD_CHALLENGE_TYPE];
|
||||
|
||||
private:
|
||||
inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); }
|
||||
inline const RankInfo* GetRankInfo(uint8 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : nullptr; }
|
||||
|
||||
@@ -128,7 +128,9 @@ void GuildMgr::LoadGuilds()
|
||||
// 0 1 2 3 4 5 6
|
||||
QueryResult result = CharacterDatabase.Query("SELECT g.guildid, g.name, g.leaderguid, g.EmblemStyle, g.EmblemColor, g.BorderStyle, g.BorderColor, "
|
||||
// 7 8 9 10 11 12 13 14 15
|
||||
"g.BackgroundColor, g.info, g.motd, g.createdate, g.BankMoney, g.level, g.experience, g.todayExperience, COUNT(gbt.guildid) "
|
||||
"g.BackgroundColor, g.info, g.motd, g.createdate, g.BankMoney, g.level, g.experience, g.todayExperience, COUNT(gbt.guildid), "
|
||||
// 16 17 18
|
||||
"g.completedDungeonChallenges, g.completedRaidChallenges, g.completedRatedBattlegroundChallenges "
|
||||
"FROM guild g LEFT JOIN guild_bank_tab gbt ON g.guildid = gbt.guildid GROUP BY g.guildid ORDER BY g.guildid ASC");
|
||||
|
||||
if (!result)
|
||||
|
||||
@@ -1021,59 +1021,3 @@ void WorldSession::HandleGuildRenameCallback(std::string newName, PreparedQueryR
|
||||
if(pGuild && hasRenamed)
|
||||
pGuild->SetName(newName);
|
||||
}
|
||||
/*
|
||||
void WorldSession::HandleGuildChallengeRequest(WorldPacket& recvPacket)
|
||||
{
|
||||
uint8 counter = 4;
|
||||
|
||||
if (Guild* pGuild = GetPlayer()->GetGuild())
|
||||
{
|
||||
if (Guild::ChallengesMgr* challengesMgr = pGuild->GetChallengesMgr())
|
||||
{
|
||||
// First check if it's time to reset the challenges.
|
||||
time_t thisTime = time(NULL);
|
||||
if (pGuild->GetChallengesMgr()->CompletedFirstChallenge(pGuild->GetId()) && pGuild->GetChallengesMgr()->GetFirstCompletedChallengeTime(pGuild->GetId()) + WEEK <= thisTime)
|
||||
pGuild->GetChallengesMgr()->ResetWeeklyChallenges();
|
||||
|
||||
WorldPacket data(SMSG_GUILD_CHALLENGE_UPDATED, 5 * 4 * 4);
|
||||
|
||||
//Guild Experience Reward block
|
||||
|
||||
data << uint32(0); //in the block its always 1
|
||||
data << challengesMgr->GetXPRewardForType(CHALLENGE_TYPE_DUNGEON); //dungeon
|
||||
data << challengesMgr->GetXPRewardForType(CHALLENGE_TYPE_RAID); //raid
|
||||
data << challengesMgr->GetXPRewardForType(CHALLENGE_TYPE_RATEDBG); //rated BG
|
||||
|
||||
//Gold Bonus block
|
||||
data << uint32(0); //in the block its always 1
|
||||
data << challengesMgr->GetGoldBonusForType(CHALLENGE_TYPE_DUNGEON); //dungeon
|
||||
data << challengesMgr->GetGoldBonusForType(CHALLENGE_TYPE_RAID); //raid
|
||||
data << challengesMgr->GetGoldBonusForType(CHALLENGE_TYPE_RATEDBG); //rated BG
|
||||
|
||||
//Total Count block
|
||||
|
||||
data << uint32(0); //in the block its always 1
|
||||
data << challengesMgr->GetTotalCountFor(CHALLENGE_TYPE_DUNGEON); //dungeon
|
||||
data << challengesMgr->GetTotalCountFor(CHALLENGE_TYPE_RAID); //raid
|
||||
data << challengesMgr->GetTotalCountFor(CHALLENGE_TYPE_RATEDBG); //rated BG
|
||||
|
||||
//Completion Gold Reward block
|
||||
|
||||
data << uint32(0); //in the block its always 1
|
||||
data << challengesMgr->GetGoldRewardForType(CHALLENGE_TYPE_DUNGEON); //dungeon
|
||||
data << challengesMgr->GetGoldRewardForType(CHALLENGE_TYPE_RAID); //raid
|
||||
data << challengesMgr->GetGoldRewardForType(CHALLENGE_TYPE_RATEDBG); //rated BG
|
||||
|
||||
//Current Count block
|
||||
|
||||
data << uint32(0); //in the block its always 1
|
||||
data << challengesMgr->GetCurrentCountFor(CHALLENGE_TYPE_DUNGEON); //dungeon
|
||||
data << challengesMgr->GetCurrentCountFor(CHALLENGE_TYPE_RAID); //raid
|
||||
data << challengesMgr->GetCurrentCountFor(CHALLENGE_TYPE_RATEDBG); //rated BG
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "Pet.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Guild.h"
|
||||
#include "ScriptReloadMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
@@ -654,6 +655,7 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi
|
||||
return;
|
||||
|
||||
uint32 dungeonId = 0;
|
||||
uint32 encounterId = 0;
|
||||
|
||||
for (DungeonEncounterList::const_iterator itr = encounters->begin(); itr != encounters->end(); ++itr)
|
||||
{
|
||||
@@ -661,6 +663,7 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi
|
||||
if (encounter->creditType == type && encounter->creditEntry == creditEntry)
|
||||
{
|
||||
completedEncounters |= 1 << encounter->dbcEntry->encounterIndex;
|
||||
encounterId = encounter->dbcEntry->id;
|
||||
if (encounter->lastEncounterDungeon)
|
||||
{
|
||||
if (instance->GetDifficulty() != sLFGDungeonStore.LookupEntry(encounter->lastEncounterDungeon)->difficulty)
|
||||
@@ -674,19 +677,48 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi
|
||||
}
|
||||
}
|
||||
|
||||
if (dungeonId)
|
||||
bool LFGRewarded = false;
|
||||
std::vector<uint32> guildList;
|
||||
Map::PlayerList const& players = instance->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
||||
{
|
||||
Map::PlayerList const& players = instance->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
||||
{
|
||||
if (Player* player = i->GetSource())
|
||||
if (Group* grp = player->GetGroup())
|
||||
if (grp->isLFGGroup())
|
||||
if (Player* player = i->GetSource())
|
||||
if (Group* grp = player->GetGroup())
|
||||
{
|
||||
bool guildAlreadyUpdate = false;
|
||||
for (std::vector<uint32>::const_iterator guildItr = guildList.begin(); guildItr != guildList.end(); guildItr++)
|
||||
if (*guildItr == player->GetGuildId())
|
||||
guildAlreadyUpdate = true;
|
||||
|
||||
if (!guildAlreadyUpdate)
|
||||
{
|
||||
if (Guild* guild = player->GetGuild())
|
||||
{
|
||||
sLFGMgr->FinishDungeon(grp->GetGUID(), dungeonId, instance);
|
||||
return;
|
||||
if (grp->IsGuildGroupFor(player))
|
||||
{
|
||||
if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
|
||||
{
|
||||
if (grp->MemberLevelIsInRange(dungeon->minlevel, dungeon->maxlevel))
|
||||
{
|
||||
if (dungeonId)
|
||||
guild->CompleteChallenge(instance->IsNonRaidDungeon() ? GUILD_CHALLENGE_TYPE_DUNGEON : GUILD_CHALLENGE_TYPE_RAID, player);
|
||||
else if (instance->IsRaid())
|
||||
guild->CompleteChallenge(GUILD_CHALLENGE_TYPE_RAID, player);
|
||||
}
|
||||
}
|
||||
|
||||
guild->AddGuildNews(GUILD_NEWS_DUNGEON_ENCOUNTER, player->GetGUID(), 0, encounterId);
|
||||
guildList.push_back(player->GetGuildId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (grp->isLFGGroup() && !LFGRewarded && dungeonId)
|
||||
{
|
||||
sLFGMgr->FinishDungeon(grp->GetGUID(), dungeonId, instance);
|
||||
LFGRewarded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -271,7 +271,7 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_OPCODE_HANDLER(CMSG_GUILD_PERMISSIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPermissions );
|
||||
DEFINE_OPCODE_HANDLER(CMSG_GUILD_PROMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPromoteOpcode );
|
||||
DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryOpcode );
|
||||
DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildQueryNewsOpcode );
|
||||
DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryNewsOpcode );
|
||||
DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_RANKS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryRanksOpcode );
|
||||
DEFINE_OPCODE_HANDLER(CMSG_GUILD_REMOVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRemoveOpcode );
|
||||
DEFINE_OPCODE_HANDLER(CMSG_GUILD_REPLACE_GUILD_MASTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
@@ -853,7 +853,7 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_MONEY_WITHDRAWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_TEXT_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHANGE_NAME_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
DEFINE_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||
|
||||
@@ -1362,7 +1362,7 @@ void World::LoadConfigSettings(bool reload)
|
||||
// MySQL ping time interval
|
||||
m_int_configs[CONFIG_DB_PING_INTERVAL] = sConfigMgr->GetIntDefault("MaxPingTime", 30);
|
||||
|
||||
// Guild save interval
|
||||
// Guild configs
|
||||
m_bool_configs[CONFIG_GUILD_LEVELING_ENABLED] = sConfigMgr->GetBoolDefault("Guild.LevelingEnabled", true);
|
||||
m_int_configs[CONFIG_GUILD_SAVE_INTERVAL] = sConfigMgr->GetIntDefault("Guild.SaveInterval", 15);
|
||||
m_int_configs[CONFIG_GUILD_MAX_LEVEL] = sConfigMgr->GetIntDefault("Guild.MaxLevel", 25);
|
||||
@@ -1370,6 +1370,15 @@ void World::LoadConfigSettings(bool reload)
|
||||
rate_values[RATE_XP_GUILD_MODIFIER] = sConfigMgr->GetFloatDefault("Guild.XPModifier", 0.25f);
|
||||
m_int_configs[CONFIG_GUILD_DAILY_XP_CAP] = sConfigMgr->GetIntDefault("Guild.DailyXPCap", 7807500);
|
||||
m_int_configs[CONFIG_GUILD_WEEKLY_REP_CAP] = sConfigMgr->GetIntDefault("Guild.WeeklyReputationCap", 4375);
|
||||
m_int_configs[CONFIG_GUILD_CHALLENGE_DUNGEON_XP] = sConfigMgr->GetIntDefault("Guild.Challenge.DungeonXP", 300000);
|
||||
m_int_configs[CONFIG_GUILD_CHALLENGE_DUNGEON_GOLD] = sConfigMgr->GetIntDefault("Guild.Challenge.DungeonGold", 125);
|
||||
m_int_configs[CONFIG_GUILD_CHALLENGE_DUNGEON_NEEDED] = sConfigMgr->GetIntDefault("Guild.Challenge.DungeonsNedeed", 7);
|
||||
m_int_configs[CONFIG_GUILD_CHALLENGE_RAID_XP] = sConfigMgr->GetIntDefault("Guild.Challenge.RaidXP", 3000000);
|
||||
m_int_configs[CONFIG_GUILD_CHALLENGE_RAID_GOLD] = sConfigMgr->GetIntDefault("Guild.Challenge.RaidGold", 500);
|
||||
m_int_configs[CONFIG_GUILD_CHALLENGE_RAID_NEEDED] = sConfigMgr->GetIntDefault("Guild.Challenge.RaidsNedeed", 1);
|
||||
m_int_configs[CONFIG_GUILD_CHALLENGE_RATEDBG_XP] = sConfigMgr->GetIntDefault("Guild.Challenge.RatedBattlegroundXP", 1500000);
|
||||
m_int_configs[CONFIG_GUILD_CHALLENGE_RATEDBG_GOLD] = sConfigMgr->GetIntDefault("Guild.Challenge.RatedBattlegroundGold", 250);
|
||||
m_int_configs[CONFIG_GUILD_CHALLENGE_RATEDBG_NEEDED] = sConfigMgr->GetIntDefault("Guild.Challenge.RatedBattlegroundsNedeed", 3);
|
||||
|
||||
// misc
|
||||
m_bool_configs[CONFIG_PDUMP_NO_PATHS] = sConfigMgr->GetBoolDefault("PlayerDump.DisallowPaths", true);
|
||||
|
||||
@@ -386,6 +386,15 @@ enum WorldIntConfigs
|
||||
CONFIG_GUILD_UNDELETABLE_LEVEL,
|
||||
CONFIG_GUILD_DAILY_XP_CAP,
|
||||
CONFIG_GUILD_WEEKLY_REP_CAP,
|
||||
CONFIG_GUILD_CHALLENGE_DUNGEON_XP,
|
||||
CONFIG_GUILD_CHALLENGE_DUNGEON_GOLD,
|
||||
CONFIG_GUILD_CHALLENGE_DUNGEON_NEEDED,
|
||||
CONFIG_GUILD_CHALLENGE_RAID_XP,
|
||||
CONFIG_GUILD_CHALLENGE_RAID_GOLD,
|
||||
CONFIG_GUILD_CHALLENGE_RAID_NEEDED,
|
||||
CONFIG_GUILD_CHALLENGE_RATEDBG_XP,
|
||||
CONFIG_GUILD_CHALLENGE_RATEDBG_GOLD,
|
||||
CONFIG_GUILD_CHALLENGE_RATEDBG_NEEDED,
|
||||
CONFIG_PACKET_SPOOF_POLICY,
|
||||
CONFIG_PACKET_SPOOF_BANMODE,
|
||||
CONFIG_PACKET_SPOOF_BANDURATION,
|
||||
|
||||
@@ -3879,6 +3879,30 @@ Guild.DailyXPCap = 7807500
|
||||
|
||||
Guild.WeeklyReputationCap = 4375
|
||||
|
||||
#
|
||||
# Guild.Challenge
|
||||
# Description: defines the required challenge completions and reward amount for completing guild challenges
|
||||
# Default: 300000 - (DungeonXP)
|
||||
# 125 - (DungeonGold)
|
||||
# 7 - (DungeonsNeeded)
|
||||
# 3000000 - (RaidXP)
|
||||
# 125 - (RaidGold)
|
||||
# 1 - (RaidsNeeded)
|
||||
# 1500000 - (RatedBattlegroundXP)
|
||||
# 250 - (RatedBattlegroundGold)
|
||||
# 3 - (RatedBattlegroundsNedeed)
|
||||
#
|
||||
|
||||
Guild.Challenge.DungeonXP = 300000
|
||||
Guild.Challenge.DungeonGold = 125
|
||||
Guild.Challenge.DungeonsNedeed = 7
|
||||
Guild.Challenge.RaidXP = 3000000
|
||||
Guild.Challenge.RaidGold = 500
|
||||
Guild.Challenge.RaidsNedeed = 1
|
||||
Guild.Challenge.RatedBattlegroundXP = 1500000
|
||||
Guild.Challenge.RatedBattlegroundGold = 250
|
||||
Guild.Challenge.RatedBattlegroundsNedeed = 3
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
|
||||
Reference in new issue
Block a user