aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSovak <Sovak007@gmail.com>2012-09-09 14:39:34 +0200
committerNay <dnpd.dd@gmail.com>2012-09-09 22:43:44 +0100
commit2440a2875567905df48ce9073041a960e9ebd0bd (patch)
treee7dcaeb9d405c77b2de9d11f8c380a720dae1f98 /src
parent271e9cb9e628177d37d45effbd39e7a31f8c9910 (diff)
Core/Guilds: Implemented guild news & guild rewards tab
Signed-off-by: Sovak <Sovak007@gmail.com> Signed-off-by: Nay <dnpd.dd@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp8
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.h3
-rw-r--r--src/server/game/Entities/Player/Player.cpp13
-rw-r--r--src/server/game/Guilds/Guild.cpp129
-rwxr-xr-xsrc/server/game/Guilds/Guild.h59
-rw-r--r--src/server/game/Guilds/GuildMgr.cpp59
-rw-r--r--src/server/game/Guilds/GuildMgr.h2
-rwxr-xr-xsrc/server/game/Handlers/GuildHandler.cpp77
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp10
-rwxr-xr-xsrc/server/game/Server/WorldSession.h3
-rw-r--r--src/server/game/Spells/SpellEffects.cpp6
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.cpp2
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.h2
13 files changed, 363 insertions, 10 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index a0400dad77a..a664a6dca06 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -1854,6 +1854,10 @@ void AchievementMgr<T>::CompletedAchievement(AchievementEntry const* achievement
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID))
return;
+ if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS)
+ if (Guild* guild = sGuildMgr->GetGuildById(referencePlayer->GetGuildId()))
+ guild->GetNewsLog().AddNewEvent(GUILD_NEWS_PLAYER_ACHIEVEMENT, time(NULL), referencePlayer->GetGUID(), achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER, achievement->ID);
+
if (!GetOwner()->GetSession()->PlayerLoading())
SendAchievementEarned(achievement);
@@ -1929,6 +1933,10 @@ void AchievementMgr<Guild>::CompletedAchievement(AchievementEntry const* achieve
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID))
return;
+ if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS)
+ if (Guild* guild = sGuildMgr->GetGuildById(referencePlayer->GetGuildId()))
+ guild->GetNewsLog().AddNewEvent(GUILD_NEWS_GUILD_ACHIEVEMENT, time(NULL), 0, achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER, achievement->ID);
+
SendAchievementEarned(achievement);
CompletedAchievementData& ca = m_completedAchievements[achievement->ID];
ca.date = time(NULL);
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index 98ae2aa5ff6..9e8dc76d832 100755
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -51,7 +51,8 @@ enum ContentLevels
CONTENT_1_60 = 0,
CONTENT_61_70 = 1,
CONTENT_71_80 = 2,
- CONTENT_81_85 = 3
+ CONTENT_81_85 = 3,
+ MAX_CONTENT
};
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index ed3f7a144b3..9b80750437c 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -21496,7 +21496,13 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
return false;
}
- return crItem->maxcount != 0;
+ bool bought = crItem->maxcount != 0;
+
+ if (bought)
+ if ((pProto->Quality == ITEM_QUALITY_EPIC && pProto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)]) || pProto->Quality > ITEM_QUALITY_EPIC)
+ if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId()))
+ guild->GetNewsLog().AddNewEvent(GUILD_NEWS_ITEM_PURCHASED, time(NULL), GetGUID(), 0, item);
+ return bought;
}
uint32 Player::GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot) const
@@ -24230,6 +24236,11 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
--loot->unlootedCount;
+ if (const ItemTemplate* proto = sObjectMgr->GetItemTemplate(item->itemid))
+ if ((proto->Quality == ITEM_QUALITY_EPIC && proto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)]) || proto->Quality > ITEM_QUALITY_EPIC)
+ if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId()))
+ guild->GetNewsLog().AddNewEvent(GUILD_NEWS_ITEM_LOOTED, time(NULL), GetGUID(), 0, item->itemid);
+
SendNewItem(newitem, uint32(item->count), false, false, true);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count);
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 322e953be4a..09188843d52 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -1061,7 +1061,7 @@ InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap)
///////////////////////////////////////////////////////////////////////////////
// Guild
Guild::Guild() : m_id(0), m_leaderGuid(0), m_createdDate(0), m_accountsNumber(0), m_bankMoney(0), m_eventLog(NULL),
- m_achievementMgr(this), _level(1), _experience(0), _todayExperience(0)
+ m_achievementMgr(this), _level(1), _experience(0), _todayExperience(0), _newsLog(this)
{
memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*));
}
@@ -3234,6 +3234,7 @@ void Guild::GiveXP(uint32 xp, Player* source)
}
}
+ GetNewsLog().AddNewEvent(GUILD_NEWS_LEVEL_UP, time(NULL), 0, 0, _level);
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL, GetLevel(), 0, NULL, source);
}
@@ -3258,3 +3259,129 @@ void Guild::ResetDailyExperience()
if (Player* player = itr->second->FindPlayer())
SendGuildXP(player->GetSession());
}
+
+void Guild::GuildNewsLog::AddNewEvent(GuildNews eventType, time_t date, uint64 playerGuid, uint32 flags, uint32 data)
+{
+ uint32 id = _newsLog.size();
+ GuildNewsEntry& log = _newsLog[id];
+ log.EventType = eventType;
+ log.PlayerGuid = playerGuid;
+ log.Data = data;
+ log.Flags = flags;
+ log.Date = date;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SAVE_GUILD_NEWS);
+ stmt->setUInt32(0, GetGuild()->GetId());
+ stmt->setUInt32(1, id);
+ stmt->setUInt32(2, log.EventType);
+ stmt->setUInt64(3, log.PlayerGuid);
+ stmt->setUInt32(4, log.Data);
+ stmt->setUInt32(5, log.Flags);
+ stmt->setUInt32(6, uint32(log.Date));
+ CharacterDatabase.Execute(stmt);
+
+ WorldPacket pData;
+ BuildNewsData(id, log, pData);
+ GetGuild()->BroadcastPacket(&pData);
+}
+
+void Guild::GuildNewsLog::LoadFromDB(PreparedQueryResult result)
+{
+ if (!result)
+ return;
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 id = fields[0].GetInt32();
+ GuildNewsEntry& log = _newsLog[id];
+ log.EventType = GuildNews(fields[1].GetInt32());
+ log.PlayerGuid = fields[2].GetInt64();
+ log.Data = fields[3].GetInt32();
+ log.Flags = fields[4].GetInt32();
+ log.Date = time_t(fields[5].GetInt32());
+ }
+ while (result->NextRow());
+}
+
+void Guild::GuildNewsLog::BuildNewsData(uint32 id, GuildNewsEntry& guildNew, WorldPacket& data)
+{
+ data.Initialize(SMSG_GUILD_NEWS_UPDATE);
+ data.WriteBits(1, 21);
+
+ data.WriteBits(0, 26); // Other Guids NYI
+ ObjectGuid guid = guildNew.PlayerGuid;
+
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[2]);
+
+ data.FlushBits();
+
+ data.WriteByteSeq(guid[5]);
+
+ data << uint32(guildNew.Flags); // 1 sticky
+ data << uint32(guildNew.Data);
+ data << uint32(0);
+
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[1]);
+
+ data << uint32(id);
+ data << uint32(guildNew.EventType);
+ data << uint32(secsToTimeBitFields(guildNew.Date));
+}
+
+void Guild::GuildNewsLog::BuildNewsData(WorldPacket& data)
+{
+ data.Initialize(SMSG_GUILD_NEWS_UPDATE);
+ data.WriteBits(_newsLog.size(), 21);
+
+ for (GuildNewsLogMap::const_iterator it = _newsLog.begin(); it != _newsLog.end(); it++)
+ {
+ data.WriteBits(0, 26); // Not yet implemented used for guild achievements
+ ObjectGuid guid = it->second.PlayerGuid;
+
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[2]);
+ }
+
+ data.FlushBits();
+
+ for (GuildNewsLogMap::const_iterator it = _newsLog.begin(); it != _newsLog.end(); it++)
+ {
+ ObjectGuid guid = it->second.PlayerGuid;
+ data.WriteByteSeq(guid[5]);
+
+ data << uint32(it->second.Flags); // 1 sticky
+ data << uint32(it->second.Data);
+ data << uint32(0);
+
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[1]);
+
+ data << uint32(it->first);
+ data << uint32(it->second.EventType);
+ data << uint32(secsToTimeBitFields(it->second.Date));
+ }
+}
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index b7613957a45..d846e814357 100755
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -24,6 +24,7 @@
#include "WorldPacket.h"
#include "ObjectMgr.h"
#include "Player.h"
+#include "DBCStore.h"
class Item;
@@ -225,6 +226,38 @@ enum GuildMemberFlags
GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app
};
+enum GuildNews
+{
+ GUILD_NEWS_GUILD_ACHIEVEMENT = 0,
+ GUILD_NEWS_PLAYER_ACHIEVEMENT = 1,
+ GUILD_NEWS_DUNGEON_ENCOUNTER = 2, // Todo Implement
+ GUILD_NEWS_ITEM_LOOTED = 3,
+ GUILD_NEWS_ITEM_CRAFTED = 4,
+ GUILD_NEWS_ITEM_PURCHASED = 5,
+ GUILD_NEWS_LEVEL_UP = 6,
+};
+
+struct GuildNewsEntry
+{
+ GuildNews EventType;
+ time_t Date;
+ uint64 PlayerGuid;
+ uint32 Flags;
+ uint32 Data;
+};
+
+struct GuildReward
+{
+ uint32 Entry;
+ uint8 Standing;
+ int32 Racemask;
+ uint64 Price;
+ uint32 AchievementId;
+};
+
+uint32 const MinNewsItemLevel[MAX_CONTENT] = { 61, 90, 200, 353 };
+
+typedef std::map<uint32, GuildNewsEntry> GuildNewsLogMap;
#define GUILD_EXPERIENCE_UNCAPPED_LEVEL 20 ///> Hardcoded in client, starting from this level, guild daily experience gain is unlimited.
////////////////////////////////////////////////////////////////////////////////////////////
@@ -347,6 +380,30 @@ private:
RemainingValue m_bankRemaining[GUILD_BANK_MAX_TABS + 1];
};
+ // News Log class
+ class GuildNewsLog
+ {
+ public:
+ GuildNewsLog(Guild* guild) : _guild(guild) { }
+
+ void LoadFromDB(PreparedQueryResult result);
+ void BuildNewsData(WorldPacket& data);
+ void BuildNewsData(uint32 id, GuildNewsEntry& guildNew, WorldPacket& data);
+ void AddNewEvent(GuildNews eventType, time_t date, uint64 playerGuid, uint32 flags, uint32 data);
+ GuildNewsEntry* GetNewById(uint32 id)
+ {
+ GuildNewsLogMap::iterator itr = _newsLog.find(id);
+ if (itr != _newsLog.end())
+ return &itr->second;
+ return NULL;
+ }
+ Guild* GetGuild() const {return _guild; }
+
+ private:
+ Guild* _guild;
+ GuildNewsLogMap _newsLog;
+ };
+
// Base class for event entries
class LogEntry
{
@@ -727,6 +784,7 @@ public:
uint64 GetExperience() const { return _experience; }
uint64 GetTodayExperience() const { return _todayExperience; }
void ResetDailyExperience();
+ GuildNewsLog& GetNewsLog() { return _newsLog; }
protected:
uint32 m_id;
@@ -749,6 +807,7 @@ protected:
LogHolder* m_bankEventLog[GUILD_BANK_MAX_TABS + 1];
AchievementMgr<Guild> m_achievementMgr;
+ GuildNewsLog _newsLog;
uint32 _level;
uint64 _experience;
diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp
index 726add2cf44..c611732ab48 100644
--- a/src/server/game/Guilds/GuildMgr.cpp
+++ b/src/server/game/Guilds/GuildMgr.cpp
@@ -433,8 +433,18 @@ void GuildMgr::LoadGuilds()
itr->second->GetAchievementMgr().LoadFromDB(achievementResult, criteriaResult);
}
}
+ // 10. Loading Guild news
+ sLog->outInfo(LOG_FILTER_GENERAL, "Loading Guild News");
+ {
+ for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); itr++)
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_GUILD_NEWS);
+ stmt->setInt32(0, itr->first);
+ itr->second->GetNewsLog().LoadFromDB(CharacterDatabase.Query(stmt));
+ }
+ }
- // 10. Validate loaded guild data
+ // 11. Validate loaded guild data
sLog->outInfo(LOG_FILTER_GENERAL, "Validating data of loaded guilds...");
{
uint32 oldMSTime = getMSTime();
@@ -507,5 +517,50 @@ void GuildMgr::LoadGuildXpForLevel()
void GuildMgr::LoadGuildRewards()
{
- /// @TODO: Implement
+ uint32 oldMSTime = getMSTime();
+
+ // 0 1 2 3 4
+ QueryResult result = WorldDatabase.Query("SELECT entry, standing, racemask, price, achievement FROM guild_rewards");
+
+ if (!result)
+ {
+ sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 guild reward definitions. DB table `guild_rewards` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+
+ do
+ {
+ GuildReward reward;
+ Field* fields = result->Fetch();
+ reward.Entry = fields[0].GetUInt32();
+ reward.Standing = fields[1].GetUInt8();
+ reward.Racemask = fields[2].GetInt32();
+ reward.Price = fields[3].GetUInt64();
+ reward.AchievementId = fields[4].GetUInt32();
+
+ if (!sObjectMgr->GetItemTemplate(reward.Entry))
+ {
+ sLog->outError(LOG_FILTER_SERVER_LOADING, "Guild rewards constains not existing item entry %u", reward.Entry);
+ continue;
+ }
+
+ if (reward.AchievementId != 0 && (!sAchievementStore.LookupEntry(reward.AchievementId)))
+ {
+ sLog->outError(LOG_FILTER_SERVER_LOADING, "Guild rewards constains not existing achievement entry %u", reward.AchievementId);
+ continue;
+ }
+
+ if (reward.Standing >= MAX_REPUTATION_RANK)
+ {
+ sLog->outError(LOG_FILTER_SERVER_LOADING, "Guild rewards contains wrong reputation standing %u, max is %u", uint32(reward.Standing), MAX_REPUTATION_RANK - 1);
+ continue;
+ }
+
+ GuildRewards.push_back(reward);
+ ++count;
+ } while (result->NextRow());
+
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u guild reward definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h
index a2bf6d268b5..24c1a4c0d5d 100644
--- a/src/server/game/Guilds/GuildMgr.h
+++ b/src/server/game/Guilds/GuildMgr.h
@@ -52,11 +52,13 @@ public:
void SetNextGuildId(uint32 Id) { NextGuildId = Id; }
uint32 GetXPForGuildLevel(uint8 level) const;
+ std::vector<GuildReward> const& GetGuildRewards() const { return GuildRewards; }
protected:
uint32 NextGuildId;
GuildContainer GuildStore;
std::vector<uint64> GuildXPperLevel;
+ std::vector<GuildReward> GuildRewards;
};
#define sGuildMgr ACE_Singleton<GuildMgr, ACE_Null_Mutex>::instance()
diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp
index d45c79d1b84..f5f69b18b62 100755
--- a/src/server/game/Handlers/GuildHandler.cpp
+++ b/src/server/game/Handlers/GuildHandler.cpp
@@ -782,3 +782,80 @@ void WorldSession::HandleAutoDeclineGuildInvites(WorldPacket& recvPakcet)
GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_AUTO_DECLINE_GUILD, enable);
}
+
+void WorldSession::HandleGuildRewardsQueryOpcode(WorldPacket& recvPacket)
+{
+ recvPacket.read_skip<uint32>(); // Unk
+
+ if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
+ {
+ std::vector<GuildReward> const& rewards = sGuildMgr->GetGuildRewards();
+
+ WorldPacket data(SMSG_GUILD_REWARDS_LIST, (3 + rewards.size() * (4 + 4 + 4 +8 + 4 +4)));
+ data.WriteBits(rewards.size(), 21);
+ data.FlushBits();
+
+ for (uint32 i = 0; i < rewards.size(); i++)
+ {
+ data << uint32(rewards[i].Standing);
+ data << int32(rewards[i].Racemask);
+ data << uint32(rewards[i].Entry);
+ data << uint64(rewards[i].Price);
+ data << uint32(0); // Unused
+ data << uint32(rewards[i].AchievementId);
+ }
+ data << uint32(time(NULL));
+ SendPacket(&data);
+ }
+}
+
+void WorldSession::HandleGuildQueryNewsOpcode(WorldPacket& recvPacket)
+{
+ recvPacket.read_skip<uint32>();
+
+ if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
+ {
+ WorldPacket data;
+ guild->GetNewsLog().BuildNewsData(data);
+ SendPacket(&data);
+ }
+}
+
+void WorldSession::HandleGuildNewsUpdateStickyOpcode(WorldPacket& recvPacket)
+{
+ uint32 newId;
+ bool unk;
+ ObjectGuid guid;
+
+ recvPacket >> newId;
+
+ unk = recvPacket.ReadBit();
+ guid[2] = recvPacket.ReadBit();
+ guid[4] = recvPacket.ReadBit();
+ guid[3] = recvPacket.ReadBit();
+ guid[0] = recvPacket.ReadBit();
+ guid[6] = recvPacket.ReadBit();
+ guid[7] = recvPacket.ReadBit();
+ guid[1] = recvPacket.ReadBit();
+ guid[5] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guid[6]);
+ recvPacket.ReadByteSeq(guid[2]);
+ recvPacket.ReadByteSeq(guid[1]);
+ recvPacket.ReadByteSeq(guid[0]);
+ recvPacket.ReadByteSeq(guid[5]);
+ recvPacket.ReadByteSeq(guid[3]);
+ recvPacket.ReadByteSeq(guid[7]);
+ recvPacket.ReadByteSeq(guid[4]);
+
+ if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
+ {
+ if (GuildNewsEntry* guildNew = guild->GetNewsLog().GetNewById(newId))
+ {
+ guildNew->Flags ^= 1;
+ WorldPacket data;
+ guild->GetNewsLog().BuildNewsData(newId, *guildNew, data);
+ SendPacket(&data);
+ }
+ }
+}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 8399c69782d..3ed5c0fe7f8 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -268,11 +268,11 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(CMSG_GUILD_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaveOpcode );
DEFINE_OPCODE_HANDLER(CMSG_GUILD_MEMBER_SEND_SOR_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER(CMSG_GUILD_MOTD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildMOTDOpcode );
- DEFINE_OPCODE_HANDLER(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildNewsUpdateStickyOpcode);
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_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_LOGGEDIN, PROCESS_INPLACE, &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 );
@@ -419,7 +419,7 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_REWARDS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_REWARDS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildRewardsQueryOpcode );
DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_XP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryXPOpcode ); // STATUS_AUTHED
DEFINE_OPCODE_HANDLER(CMSG_QUERY_INSPECT_ACHIEVEMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryInspectAchievements );
DEFINE_OPCODE_HANDLER(CMSG_QUERY_QUESTS_COMPLETED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryQuestsCompleted );
@@ -874,7 +874,7 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(SMSG_GUILD_MOVE_COMPLETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_MOVE_STARTING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -885,7 +885,7 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_WEEKLY_CAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_RESET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_UPDATE_ROSTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_XP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index e44514847d6..543f04e305b 100755
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -576,6 +576,7 @@ class WorldSession
void HandleGuildDeclineOpcode(WorldPacket& recvPacket);
void HandleGuildEventLogQueryOpcode(WorldPacket& recvPacket);
void HandleGuildRosterOpcode(WorldPacket& recvPacket);
+ void HandleGuildRewardsQueryOpcode(WorldPacket& recvPacket);
void HandleGuildPromoteOpcode(WorldPacket& recvPacket);
void HandleGuildDemoteOpcode(WorldPacket& recvPacket);
void HandleGuildAssignRankOpcode(WorldPacket& recvPacket);
@@ -583,8 +584,10 @@ class WorldSession
void HandleGuildDisbandOpcode(WorldPacket& recvPacket);
void HandleGuildLeaderOpcode(WorldPacket& recvPacket);
void HandleGuildMOTDOpcode(WorldPacket& recvPacket);
+ void HandleGuildNewsUpdateStickyOpcode(WorldPacket& recvPacket);
void HandleGuildSetNoteOpcode(WorldPacket& recvPacket);
void HandleGuildQueryRanksOpcode(WorldPacket& recvPacket);
+ void HandleGuildQueryNewsOpcode(WorldPacket& recvPacket);
void HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket);
void HandleGuildAddRankOpcode(WorldPacket& recvPacket);
void HandleGuildDelRankOpcode(WorldPacket& recvPacket);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 7e32ce9137e..095cceab7bf 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -63,6 +63,8 @@
#include "GameObjectAI.h"
#include "AccountMgr.h"
#include "InstanceScript.h"
+#include "Guild.h"
+#include "GuildMgr.h"
pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
{
@@ -1567,6 +1569,10 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
// create the new item and store it
Item* pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid));
+ if ((pProto->Quality == ITEM_QUALITY_EPIC && pProto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)]) || pProto->Quality > ITEM_QUALITY_EPIC)
+ if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId()))
+ guild->GetNewsLog().AddNewEvent(GUILD_NEWS_ITEM_CRAFTED, time(NULL), player->GetGUID(), 0, pProto->ItemId);
+
// was it successful? return error if not
if (!pItem)
{
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index bb958be8ca7..1b17c35284b 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -241,6 +241,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, "SELECT criteria, counter, date, completedGuid FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH)
PREPARE_STATEMENT(CHAR_UPD_GUILD_EXPERIENCE, "UPDATE guild SET level = ?, experience = ?, todayExperience = ? WHERE guildId = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE, "UPDATE guild SET todayExperience = 0", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_LOAD_GUILD_NEWS, "SELECT id, eventType, playerGuid, data, flags, date FROM guild_news_log WHERE guild = ? ORDER BY guild ASC, id ASC", CONNECTION_SYNCH);
+ PREPARE_STATEMENT(CHAR_SAVE_GUILD_NEWS, "INSERT INTO guild_news_log values (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
// Chat channel handling
PREPARE_STATEMENT(CHAR_SEL_CHANNEL, "SELECT announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH)
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 9c06c547b39..20454798f98 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -236,6 +236,8 @@ enum CharacterDatabaseStatements
CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA,
CHAR_UPD_GUILD_EXPERIENCE,
CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE,
+ CHAR_LOAD_GUILD_NEWS,
+ CHAR_SAVE_GUILD_NEWS,
CHAR_SEL_CHANNEL,
CHAR_INS_CHANNEL,