[9581] Fixed apply damage reduction to melee/ranged damage.
[getmangos.git] / src / game / GuildHandler.cpp
blobcaba6462c80286c4f34808dae20dcde1bea38d8c
1 /*
2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "WorldPacket.h"
21 #include "WorldSession.h"
22 #include "World.h"
23 #include "ObjectMgr.h"
24 #include "Log.h"
25 #include "Opcodes.h"
26 #include "Guild.h"
27 #include "GossipDef.h"
28 #include "SocialMgr.h"
30 void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket)
32 sLog.outDebug("WORLD: Received CMSG_GUILD_QUERY");
34 uint32 guildId;
35 recvPacket >> guildId;
37 if(Guild *guild = sObjectMgr.GetGuildById(guildId))
39 guild->Query(this);
40 return;
43 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
46 void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket)
48 sLog.outDebug("WORLD: Received CMSG_GUILD_CREATE");
50 std::string gname;
51 recvPacket >> gname;
53 if(GetPlayer()->GetGuildId()) // already in guild
54 return;
56 Guild *guild = new Guild;
57 if(!guild->Create(GetPlayer(), gname))
59 delete guild;
60 return;
63 sObjectMgr.AddGuild(guild);
66 void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket)
68 sLog.outDebug("WORLD: Received CMSG_GUILD_INVITE");
70 std::string Invitedname, plname;
71 Player * player = NULL;
73 recvPacket >> Invitedname;
75 if(normalizePlayerName(Invitedname))
76 player = ObjectAccessor::FindPlayerByName(Invitedname.c_str());
78 if(!player)
80 SendGuildCommandResult(GUILD_INVITE_S, Invitedname, ERR_GUILD_PLAYER_NOT_FOUND_S);
81 return;
84 Guild *guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
85 if(!guild)
87 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
88 return;
91 // OK result but not send invite
92 if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
93 return;
95 // not let enemies sign guild charter
96 if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
98 SendGuildCommandResult(GUILD_INVITE_S, Invitedname, ERR_GUILD_NOT_ALLIED);
99 return;
102 if(player->GetGuildId())
104 plname = player->GetName();
105 SendGuildCommandResult(GUILD_INVITE_S, plname, ERR_ALREADY_IN_GUILD_S);
106 return;
109 if(player->GetGuildIdInvited())
111 plname = player->GetName();
112 SendGuildCommandResult(GUILD_INVITE_S, plname, ERR_ALREADY_INVITED_TO_GUILD_S);
113 return;
116 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_INVITE))
118 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
119 return;
122 sLog.outDebug("Player %s Invited %s to Join his Guild", GetPlayer()->GetName(), Invitedname.c_str());
124 player->SetGuildIdInvited(GetPlayer()->GetGuildId());
125 // Put record into guildlog
126 guild->LogGuildEvent(GUILD_EVENT_LOG_INVITE_PLAYER, GetPlayer()->GetGUIDLow(), player->GetGUIDLow(), 0);
128 WorldPacket data(SMSG_GUILD_INVITE, (8+10)); // guess size
129 data << GetPlayer()->GetName();
130 data << guild->GetName();
131 player->GetSession()->SendPacket(&data);
133 sLog.outDebug("WORLD: Sent (SMSG_GUILD_INVITE)");
136 void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket)
138 sLog.outDebug("WORLD: Received CMSG_GUILD_REMOVE");
140 std::string plName;
141 recvPacket >> plName;
143 if(!normalizePlayerName(plName))
144 return;
146 Guild* guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
147 if(!guild)
149 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
150 return;
153 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE))
155 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
156 return;
159 uint64 plGuid;
160 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
161 if(!slot)
163 SendGuildCommandResult(GUILD_INVITE_S, plName, ERR_GUILD_PLAYER_NOT_IN_GUILD_S);
164 return;
167 if(slot->RankId == GR_GUILDMASTER)
169 SendGuildCommandResult(GUILD_QUIT_S, "", ERR_GUILD_LEADER_LEAVE);
170 return;
173 // do not allow to kick player with same or higher rights
174 if(GetPlayer()->GetRank() >= slot->RankId)
176 SendGuildCommandResult(GUILD_QUIT_S, plName, ERR_GUILD_RANK_TOO_HIGH_S);
177 return;
180 guild->DelMember(plGuid);
181 // Put record into guild log
182 guild->LogGuildEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), 0);
184 guild->BroadcastEvent(GE_REMOVED, 0, 2, plName, _player->GetName(), "");
187 void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/)
189 Guild *guild;
190 Player *player = GetPlayer();
192 sLog.outDebug("WORLD: Received CMSG_GUILD_ACCEPT");
194 guild = sObjectMgr.GetGuildById(player->GetGuildIdInvited());
195 if(!guild || player->GetGuildId())
196 return;
198 // not let enemies sign guild charter
199 if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != sObjectMgr.GetPlayerTeamByGUID(guild->GetLeader()))
200 return;
202 if(!guild->AddMember(GetPlayer()->GetGUID(),guild->GetLowestRank()))
203 return;
204 // Put record into guild log
205 guild->LogGuildEvent(GUILD_EVENT_LOG_JOIN_GUILD, GetPlayer()->GetGUIDLow(), 0, 0);
207 guild->BroadcastEvent(GE_JOINED, player->GetGUID(), 1, player->GetName(), "", "");
210 void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/)
212 sLog.outDebug("WORLD: Received CMSG_GUILD_DECLINE");
214 GetPlayer()->SetGuildIdInvited(0);
215 GetPlayer()->SetInGuild(0);
218 void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/)
220 sLog.outDebug("WORLD: Received CMSG_GUILD_INFO");
222 Guild *guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
223 if(!guild)
225 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
226 return;
229 WorldPacket data(SMSG_GUILD_INFO, (5*4 + guild->GetName().size() + 1));
230 data << guild->GetName();
231 data << guild->GetCreatedDay();
232 data << guild->GetCreatedMonth();
233 data << guild->GetCreatedYear();
234 data << guild->GetMemberSize();
235 data << guild->GetMemberSize();
237 SendPacket(&data);
240 void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/)
242 sLog.outDebug("WORLD: Received CMSG_GUILD_ROSTER");
244 if(Guild* guild = sObjectMgr.GetGuildById(_player->GetGuildId()))
245 guild->Roster(this);
248 void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket)
250 sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE");
252 std::string plName;
253 recvPacket >> plName;
255 if(!normalizePlayerName(plName))
256 return;
258 Guild* guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
259 if(!guild)
261 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
262 return;
264 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE))
266 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
267 return;
270 uint64 plGuid;
271 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
273 if(!slot)
275 SendGuildCommandResult(GUILD_INVITE_S, plName, ERR_GUILD_PLAYER_NOT_IN_GUILD_S);
276 return;
279 if(plGuid == GetPlayer()->GetGUID())
281 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_NAME_INVALID);
282 return;
285 // allow to promote only to lower rank than member's rank
286 // guildmaster's rank = 0
287 // GetPlayer()->GetRank() + 1 is highest rank that current player can promote to
288 if(GetPlayer()->GetRank() + 1 >= slot->RankId)
290 SendGuildCommandResult(GUILD_INVITE_S, plName, ERR_GUILD_RANK_TOO_HIGH_S);
291 return;
294 uint32 newRankId = slot->RankId - 1; //when promoting player, rank is decreased
296 guild->ChangeRank(plGuid, newRankId);
297 // Put record into guild log
298 guild->LogGuildEvent(GUILD_EVENT_LOG_PROMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), newRankId);
300 guild->BroadcastEvent(GE_PROMOTION, 0, 3, _player->GetName(), plName, guild->GetRankName(newRankId));
303 void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket)
305 sLog.outDebug("WORLD: Received CMSG_GUILD_DEMOTE");
307 std::string plName;
308 recvPacket >> plName;
310 if(!normalizePlayerName(plName))
311 return;
313 Guild* guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
315 if(!guild)
317 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
318 return;
321 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_DEMOTE))
323 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
324 return;
327 uint64 plGuid;
328 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
330 if (!slot)
332 SendGuildCommandResult(GUILD_INVITE_S, plName, ERR_GUILD_PLAYER_NOT_IN_GUILD_S);
333 return;
336 if(plGuid == GetPlayer()->GetGUID())
338 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_NAME_INVALID);
339 return;
342 // do not allow to demote same or higher rank
343 if(GetPlayer()->GetRank() >= slot->RankId)
345 SendGuildCommandResult(GUILD_INVITE_S, plName, ERR_GUILD_RANK_TOO_HIGH_S);
346 return;
349 // do not allow to demote lowest rank
350 if(slot->RankId >= guild->GetLowestRank())
352 SendGuildCommandResult(GUILD_INVITE_S, plName, ERR_GUILD_RANK_TOO_LOW_S);
353 return;
356 uint32 newRankId = slot->RankId + 1; //when demoting player, rank is increased
358 guild->ChangeRank(plGuid, newRankId);
359 // Put record into guild log
360 guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), newRankId);
362 guild->BroadcastEvent(GE_DEMOTION, 0, 3, _player->GetName(), plName, guild->GetRankName(slot->RankId));
365 void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/)
367 sLog.outDebug("WORLD: Received CMSG_GUILD_LEAVE");
369 Guild *guild = sObjectMgr.GetGuildById(_player->GetGuildId());
370 if(!guild)
372 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
373 return;
376 if(_player->GetGUID() == guild->GetLeader() && guild->GetMemberSize() > 1)
378 SendGuildCommandResult(GUILD_QUIT_S, "", ERR_GUILD_LEADER_LEAVE);
379 return;
382 if(_player->GetGUID() == guild->GetLeader())
384 guild->Disband();
385 return;
388 guild->DelMember(_player->GetGUID());
389 // Put record into guild log
390 guild->LogGuildEvent(GUILD_EVENT_LOG_LEAVE_GUILD, _player->GetGUIDLow(), 0, 0);
392 guild->BroadcastEvent(GE_LEFT, _player->GetGUID(), 1, _player->GetName(), "", "");
394 SendGuildCommandResult(GUILD_QUIT_S, guild->GetName(), ERR_PLAYER_NO_MORE_IN_GUILD);
397 void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/)
399 sLog.outDebug("WORLD: Received CMSG_GUILD_DISBAND");
401 Guild *guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
402 if(!guild)
404 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
405 return;
408 if(GetPlayer()->GetGUID() != guild->GetLeader())
410 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
411 return;
414 guild->Disband();
416 sLog.outDebug("WORLD: Guild Successfully Disbanded");
419 void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket)
421 sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER");
423 std::string name;
424 recvPacket >> name;
426 Player *oldLeader = GetPlayer();
428 if(!normalizePlayerName(name))
429 return;
431 Guild *guild = sObjectMgr.GetGuildById(oldLeader->GetGuildId());
433 if (!guild)
435 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
436 return;
439 if (oldLeader->GetGUID() != guild->GetLeader())
441 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
442 return;
445 uint64 newLeaderGUID;
446 MemberSlot* slot = guild->GetMemberSlot(name, newLeaderGUID);
448 if (!slot)
450 SendGuildCommandResult(GUILD_INVITE_S, name, ERR_GUILD_PLAYER_NOT_IN_GUILD_S);
451 return;
454 guild->SetLeader(newLeaderGUID);
455 guild->ChangeRank(oldLeader->GetGUID(), GR_OFFICER);
457 guild->BroadcastEvent(GE_LEADER_CHANGED, 0, 2, oldLeader->GetName(), name, "");
460 void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket)
462 sLog.outDebug("WORLD: Received CMSG_GUILD_MOTD");
464 std::string MOTD;
466 if(!recvPacket.empty())
467 recvPacket >> MOTD;
468 else
469 MOTD = "";
471 Guild *guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
472 if(!guild)
474 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
475 return;
477 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_SETMOTD))
479 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
480 return;
483 guild->SetMOTD(MOTD);
485 guild->BroadcastEvent(GE_MOTD, 0, 1, MOTD, "", "");
488 void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket)
490 sLog.outDebug("WORLD: Received CMSG_GUILD_SET_PUBLIC_NOTE");
492 std::string name,PNOTE;
493 recvPacket >> name;
495 if(!normalizePlayerName(name))
496 return;
498 Guild* guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
500 if (!guild)
502 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
503 return;
506 if (!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE))
508 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
509 return;
512 uint64 plGuid;
513 MemberSlot* slot = guild->GetMemberSlot(name, plGuid);
515 if (!slot)
517 SendGuildCommandResult(GUILD_INVITE_S, name, ERR_GUILD_PLAYER_NOT_IN_GUILD_S);
518 return;
521 recvPacket >> PNOTE;
522 guild->SetPNOTE(plGuid, PNOTE);
524 guild->Roster(this);
527 void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket)
529 sLog.outDebug("WORLD: Received CMSG_GUILD_SET_OFFICER_NOTE");
531 std::string plName, OFFNOTE;
532 recvPacket >> plName;
534 if (!normalizePlayerName(plName))
535 return;
537 Guild* guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
539 if (!guild)
541 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
542 return;
544 if (!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE))
546 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
547 return;
550 uint64 plGuid;
551 MemberSlot* slot = guild->GetMemberSlot(plName, plGuid);
553 if (!slot)
555 SendGuildCommandResult(GUILD_INVITE_S, plName, ERR_GUILD_PLAYER_NOT_IN_GUILD_S);
556 return;
559 recvPacket >> OFFNOTE;
560 guild->SetOFFNOTE(plGuid, OFFNOTE);
562 guild->Roster(this);
565 void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket)
567 std::string rankname;
568 uint32 rankId;
569 uint32 rights, MoneyPerDay;
571 sLog.outDebug("WORLD: Received CMSG_GUILD_RANK");
573 Guild *guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
574 if(!guild)
576 recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam
577 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
578 return;
580 else if(GetPlayer()->GetGUID() != guild->GetLeader())
582 recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam
583 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
584 return;
587 recvPacket >> rankId;
588 recvPacket >> rights;
589 recvPacket >> rankname;
590 recvPacket >> MoneyPerDay;
592 for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
594 uint32 BankRights;
595 uint32 BankSlotPerDay;
597 recvPacket >> BankRights;
598 recvPacket >> BankSlotPerDay;
599 guild->SetBankRightsAndSlots(rankId, uint8(i), uint16(BankRights & 0xFF), uint16(BankSlotPerDay), true);
602 sLog.outDebug("WORLD: Changed RankName to %s , Rights to 0x%.4X", rankname.c_str(), rights);
604 guild->SetBankMoneyPerDay(rankId, MoneyPerDay);
605 guild->SetRankName(rankId, rankname);
607 if (rankId == GR_GUILDMASTER) // prevent loss leader rights
608 rights = GR_RIGHT_ALL;
610 guild->SetRankRights(rankId, rights);
612 guild->Query(this);
613 guild->Roster(); // broadcast for tab rights update
616 void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket)
618 sLog.outDebug("WORLD: Received CMSG_GUILD_ADD_RANK");
620 std::string rankname;
621 recvPacket >> rankname;
623 Guild *guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
624 if(!guild)
626 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
627 return;
630 if(GetPlayer()->GetGUID() != guild->GetLeader())
632 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
633 return;
636 if(guild->GetRanksSize() >= GUILD_RANKS_MAX_COUNT) // client not let create more 10 than ranks
637 return;
639 guild->CreateRank(rankname, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
641 guild->Query(this);
642 guild->Roster(); // broadcast for tab rights update
645 void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/)
647 sLog.outDebug("WORLD: Received CMSG_GUILD_DEL_RANK");
649 Guild *guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
650 if(!guild)
652 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
653 return;
655 else if(GetPlayer()->GetGUID() != guild->GetLeader())
657 SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS);
658 return;
661 guild->DelRank();
663 guild->Query(this);
664 guild->Roster(); // broadcast for tab rights update
667 void WorldSession::SendGuildCommandResult(uint32 typecmd, const std::string& str,uint32 cmdresult)
669 WorldPacket data(SMSG_GUILD_COMMAND_RESULT, (8+str.size()+1));
670 data << typecmd;
671 data << str;
672 data << cmdresult;
673 SendPacket(&data);
675 sLog.outDebug("WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)");
678 void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket)
680 sLog.outDebug("WORLD: Received CMSG_GUILD_INFO_TEXT");
682 std::string GINFO;
683 recvPacket >> GINFO;
685 Guild *guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
686 if(!guild)
688 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
689 return;
692 if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_MODIFY_GUILD_INFO))
694 SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PERMISSIONS);
695 return;
698 guild->SetGINFO(GINFO);
701 void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket)
703 sLog.outDebug("WORLD: Received MSG_SAVE_GUILD_EMBLEM");
705 uint64 vendorGuid;
706 uint32 EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor;
708 recvPacket >> vendorGuid;
709 recvPacket >> EmblemStyle >> EmblemColor >> BorderStyle >> BorderColor >> BackgroundColor;
711 Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorGuid,UNIT_NPC_FLAG_TABARDDESIGNER);
712 if (!pCreature)
714 //"That's not an emblem vendor!"
715 SendSaveGuildEmblem(ERR_GUILDEMBLEM_INVALIDVENDOR);
716 sLog.outDebug("WORLD: HandleSaveGuildEmblemOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(vendorGuid));
717 return;
720 // remove fake death
721 if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
722 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
724 Guild *guild = sObjectMgr.GetGuildById(GetPlayer()->GetGuildId());
725 if(!guild)
727 //"You are not part of a guild!";
728 SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOGUILD);
729 return;
732 if (guild->GetLeader() != GetPlayer()->GetGUID())
734 //"Only guild leaders can create emblems."
735 SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTGUILDMASTER);
736 return;
739 if(GetPlayer()->GetMoney() < 10*GOLD)
741 //"You can't afford to do that."
742 SendSaveGuildEmblem(ERR_GUILDEMBLEM_NOTENOUGHMONEY);
743 return;
746 GetPlayer()->ModifyMoney(-10*GOLD);
747 guild->SetEmblem(EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor);
749 //"Guild Emblem saved."
750 SendSaveGuildEmblem(ERR_GUILDEMBLEM_SUCCESS);
752 guild->Query(this);
755 void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */)
757 // empty
758 sLog.outDebug("WORLD: Received (MSG_GUILD_EVENT_LOG_QUERY)");
760 if(uint32 GuildId = GetPlayer()->GetGuildId())
761 if(Guild *pGuild = sObjectMgr.GetGuildById(GuildId))
762 pGuild->DisplayGuildEventLog(this);
765 /****** GUILD BANK *******/
767 void WorldSession::HandleGuildBankMoneyWithdrawn( WorldPacket & /* recv_data */ )
769 sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_MONEY_WITHDRAWN)");
771 if(uint32 GuildId = GetPlayer()->GetGuildId())
772 if(Guild *pGuild = sObjectMgr.GetGuildById(GuildId))
773 pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
776 void WorldSession::HandleGuildPermissions( WorldPacket& /* recv_data */ )
778 sLog.outDebug("WORLD: Received (MSG_GUILD_PERMISSIONS)");
780 if(uint32 GuildId = GetPlayer()->GetGuildId())
782 if(Guild *pGuild = sObjectMgr.GetGuildById(GuildId))
784 uint32 rankId = GetPlayer()->GetRank();
786 WorldPacket data(MSG_GUILD_PERMISSIONS, 4*15+1);
787 data << uint32(rankId); // guild rank id
788 data << uint32(pGuild->GetRankRights(rankId)); // rank rights
789 // money per day left
790 data << uint32(pGuild->GetMemberMoneyWithdrawRem(GetPlayer()->GetGUIDLow()));
791 data << uint8(pGuild->GetPurchasedTabs()); // tabs count
792 // why sending all info when not all tabs are purchased???
793 for(int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
795 data << uint32(pGuild->GetBankRights(rankId, uint8(i)));
796 data << uint32(pGuild->GetMemberSlotWithdrawRem(GetPlayer()->GetGUIDLow(), uint8(i)));
798 SendPacket(&data);
799 sLog.outDebug("WORLD: Sent (MSG_GUILD_PERMISSIONS)");
804 /* Called when clicking on Guild bank gameobject */
805 void WorldSession::HandleGuildBankerActivate( WorldPacket & recv_data )
807 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANKER_ACTIVATE)");
809 uint64 GoGuid;
810 uint8 unk;
811 recv_data >> GoGuid >> unk;
813 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
814 return;
816 if (uint32 GuildId = GetPlayer()->GetGuildId())
818 if(Guild *pGuild = sObjectMgr.GetGuildById(GuildId))
820 pGuild->DisplayGuildBankTabsInfo(this); // this also will load guild bank if not yet
821 return;
825 SendGuildCommandResult(GUILD_UNK1, "", ERR_GUILD_PLAYER_NOT_IN_GUILD);
828 /* Called when opening guild bank tab only (first one) */
829 void WorldSession::HandleGuildBankQueryTab( WorldPacket & recv_data )
831 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_QUERY_TAB)");
833 uint64 GoGuid;
834 uint8 TabId, unk1;
835 recv_data >> GoGuid >> TabId >> unk1;
837 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
838 return;
840 uint32 GuildId = GetPlayer()->GetGuildId();
841 if (!GuildId)
842 return;
844 Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
845 if (!pGuild)
846 return;
848 if (TabId >= pGuild->GetPurchasedTabs())
849 return;
851 // Let's update the amount of gold the player can withdraw before displaying the content
852 // This is useful if money withdraw right has changed
853 pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
854 pGuild->DisplayGuildBankContent(this, TabId);
857 void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data )
859 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_DEPOSIT_MONEY)");
861 uint64 GoGuid;
862 uint32 money;
863 recv_data >> GoGuid >> money;
865 if (!money)
866 return;
868 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
869 return;
871 if (GetPlayer()->GetMoney() < money)
872 return;
874 uint32 GuildId = GetPlayer()->GetGuildId();
875 if (!GuildId)
876 return;
878 Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
879 if (!pGuild)
880 return;
882 if (!pGuild->GetPurchasedTabs())
883 return;
885 CharacterDatabase.BeginTransaction();
887 pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
888 GetPlayer()->ModifyMoney(-int(money));
889 GetPlayer()->SaveGoldToDB();
891 CharacterDatabase.CommitTransaction();
893 // logging money
894 if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE))
896 sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)",
897 _player->GetName(),_player->GetSession()->GetAccountId(),money,GuildId);
900 // log
901 pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
903 pGuild->DisplayGuildBankTabsInfo(this);
904 pGuild->DisplayGuildBankContent(this, 0);
905 pGuild->DisplayGuildBankMoneyUpdate(this);
908 void WorldSession::HandleGuildBankWithdrawMoney( WorldPacket & recv_data )
910 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_WITHDRAW_MONEY)");
912 uint64 GoGuid;
913 uint32 money;
914 recv_data >> GoGuid >> money;
916 if (!money)
917 return;
919 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
920 return;
922 uint32 GuildId = GetPlayer()->GetGuildId();
923 if (GuildId == 0)
924 return;
926 Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
927 if(!pGuild)
928 return;
930 if (!pGuild->GetPurchasedTabs())
931 return;
933 if (pGuild->GetGuildBankMoney()<money) // not enough money in bank
934 return;
936 if (!pGuild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_WITHDRAW_GOLD))
937 return;
939 CharacterDatabase.BeginTransaction();
941 if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow()))
943 CharacterDatabase.RollbackTransaction();
944 return;
947 GetPlayer()->ModifyMoney(money);
948 GetPlayer()->SaveGoldToDB();
950 CharacterDatabase.CommitTransaction();
952 // Log
953 pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
955 pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
956 pGuild->DisplayGuildBankTabsInfo(this);
957 pGuild->DisplayGuildBankContent(this, 0);
958 pGuild->DisplayGuildBankMoneyUpdate(this);
961 void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
963 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_SWAP_ITEMS)");
965 uint64 GoGuid;
966 uint8 BankToBank;
968 uint8 BankTab, BankTabSlot, AutoStore;
969 uint8 PlayerSlot = NULL_SLOT;
970 uint8 PlayerBag = NULL_BAG;
971 uint8 BankTabDst, BankTabSlotDst, unk2;
972 uint8 ToChar = 1;
973 uint32 ItemEntry, unk1;
974 uint32 AutoStoreCount = 0;
975 uint32 SplitedAmount = 0;
977 recv_data >> GoGuid >> BankToBank;
979 uint32 GuildId = GetPlayer()->GetGuildId();
980 if (!GuildId)
982 recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
983 return;
986 Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
987 if (!pGuild)
989 recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
990 return;
993 if (BankToBank)
995 recv_data >> BankTabDst;
996 recv_data >> BankTabSlotDst;
997 recv_data >> unk1; // always 0
998 recv_data >> BankTab;
999 recv_data >> BankTabSlot;
1000 recv_data >> ItemEntry;
1001 recv_data >> unk2; // always 0
1002 recv_data >> SplitedAmount;
1004 if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS ||
1005 (BankTabDst == BankTab && BankTabSlotDst == BankTabSlot) ||
1006 BankTab >= pGuild->GetPurchasedTabs() ||
1007 BankTabDst >= pGuild->GetPurchasedTabs())
1009 recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
1010 return;
1013 else
1015 recv_data >> BankTab;
1016 recv_data >> BankTabSlot;
1017 recv_data >> ItemEntry;
1018 recv_data >> AutoStore;
1019 if (AutoStore)
1021 recv_data >> AutoStoreCount;
1022 recv_data.read_skip<uint8>(); // ToChar (?), always and expected to be 1 (autostore only triggered in guild->ToChar)
1023 recv_data.read_skip<uint32>(); // unknown, always 0
1025 else
1027 recv_data >> PlayerBag;
1028 recv_data >> PlayerSlot;
1029 recv_data >> ToChar;
1030 recv_data >> SplitedAmount;
1033 if ((BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF) ||
1034 BankTab >= pGuild->GetPurchasedTabs())
1036 recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
1037 return;
1041 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
1042 return;
1044 // Bank <-> Bank
1045 if (BankToBank)
1047 pGuild->SwapItems(_player, BankTab, BankTabSlot, BankTabDst, BankTabSlotDst, SplitedAmount);
1048 return;
1051 // Player <-> Bank
1053 // allow work with inventory only
1054 if(!Player::IsInventoryPos(PlayerBag, PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) )
1056 _player->SendEquipError( EQUIP_ERR_NONE, NULL, NULL );
1057 return;
1060 // BankToChar swap or char to bank remaining
1061 if (ToChar) // Bank -> Char cases
1062 pGuild->MoveFromBankToChar(_player, BankTab, BankTabSlot, PlayerBag, PlayerSlot, SplitedAmount);
1063 else // Char -> Bank cases
1064 pGuild->MoveFromCharToBank(_player, PlayerBag, PlayerSlot, BankTab, BankTabSlot, SplitedAmount);
1067 void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
1069 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_BUY_TAB)");
1071 uint64 GoGuid;
1072 uint8 TabId;
1074 recv_data >> GoGuid;
1075 recv_data >> TabId;
1077 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
1078 return;
1080 uint32 GuildId = GetPlayer()->GetGuildId();
1081 if (!GuildId)
1082 return;
1084 Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
1085 if(!pGuild)
1086 return;
1088 // m_PurchasedTabs = 0 when buying Tab 0, that is why this check can be made
1089 if (TabId != pGuild->GetPurchasedTabs())
1090 return;
1092 uint32 TabCost = GetGuildBankTabPrice(TabId) * GOLD;
1093 if (!TabCost)
1094 return;
1096 if (GetPlayer()->GetMoney() < TabCost) // Should not happen, this is checked by client
1097 return;
1099 // Go on with creating tab
1100 pGuild->CreateNewBankTab();
1101 GetPlayer()->ModifyMoney(-int(TabCost));
1102 pGuild->SetBankRightsAndSlots(GetPlayer()->GetRank(), TabId, GUILD_BANK_RIGHT_FULL, WITHDRAW_SLOT_UNLIMITED, true);
1103 pGuild->Roster(); // broadcast for tab rights update
1104 pGuild->DisplayGuildBankTabsInfo(this);
1107 void WorldSession::HandleGuildBankUpdateTab( WorldPacket & recv_data )
1109 sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_UPDATE_TAB)");
1111 uint64 GoGuid;
1112 uint8 TabId;
1113 std::string Name;
1114 std::string IconIndex;
1116 recv_data >> GoGuid;
1117 recv_data >> TabId;
1118 recv_data >> Name;
1119 recv_data >> IconIndex;
1121 if(Name.empty())
1122 return;
1124 if(IconIndex.empty())
1125 return;
1127 if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
1128 return;
1130 uint32 GuildId = GetPlayer()->GetGuildId();
1131 if (!GuildId)
1132 return;
1134 Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
1135 if (!pGuild)
1136 return;
1138 if (TabId >= pGuild->GetPurchasedTabs())
1139 return;
1141 pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex);
1142 pGuild->DisplayGuildBankTabsInfo(this);
1143 pGuild->DisplayGuildBankContent(this, TabId);
1146 void WorldSession::HandleGuildBankLogQuery( WorldPacket & recv_data )
1148 sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)");
1150 uint8 TabId;
1151 recv_data >> TabId;
1153 uint32 GuildId = GetPlayer()->GetGuildId();
1154 if (!GuildId)
1155 return;
1157 Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
1158 if (!pGuild)
1159 return;
1161 // GUILD_BANK_MAX_TABS send by client for money log
1162 if (TabId >= pGuild->GetPurchasedTabs() && TabId != GUILD_BANK_MAX_TABS)
1163 return;
1165 pGuild->DisplayGuildBankLogs(this, TabId);
1168 void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recv_data)
1170 sLog.outDebug("WORLD: Received MSG_QUERY_GUILD_BANK_TEXT");
1172 uint8 TabId;
1173 recv_data >> TabId;
1175 uint32 GuildId = GetPlayer()->GetGuildId();
1176 if (!GuildId)
1177 return;
1179 Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
1180 if (!pGuild)
1181 return;
1183 if (TabId >= pGuild->GetPurchasedTabs())
1184 return;
1186 pGuild->SendGuildBankTabText(this, TabId);
1189 void WorldSession::HandleSetGuildBankTabText(WorldPacket &recv_data)
1191 sLog.outDebug("WORLD: Received CMSG_SET_GUILD_BANK_TEXT");
1193 uint8 TabId;
1194 std::string Text;
1195 recv_data >> TabId;
1196 recv_data >> Text;
1198 uint32 GuildId = GetPlayer()->GetGuildId();
1199 if (!GuildId)
1200 return;
1202 Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
1203 if (!pGuild)
1204 return;
1206 if (TabId >= pGuild->GetPurchasedTabs())
1207 return;
1209 pGuild->SetGuildBankTabText(TabId, Text);
1212 void WorldSession::SendSaveGuildEmblem( uint32 msg )
1214 WorldPacket data(MSG_SAVE_GUILD_EMBLEM, 4);
1215 data << uint32(msg); // not part of guild
1216 SendPacket( &data );