Add guild features, fix channel joining, and improve whisper reply

Guild: add disband, leader transfer, public/officer note commands with
roster context menu showing rank names and officer notes column. Auto-refresh
roster after guild events.

Channels: fix city/region channels not working by accepting SMSG_CHANNEL_NOTIFY
during ENTERING_WORLD state (server auto-joins before VERIFY_WORLD) and handling
PLAYER_ALREADY_MEMBER notification.

Whisper: /r now switches to whisper tab and sets target to last sender,
matching WoW behavior.

Camera: extend WMO collision raycasting to work outside WMOs too.
This commit is contained in:
Kelsi 2026-02-16 20:16:14 -08:00
parent 6dd811a926
commit 0d4a9c38f7
9 changed files with 271 additions and 9 deletions

View file

@ -340,6 +340,10 @@ public:
void leaveGuild();
void inviteToGuild(const std::string& playerName);
void kickGuildMember(const std::string& playerName);
void disbandGuild();
void setGuildLeader(const std::string& name);
void setGuildPublicNote(const std::string& name, const std::string& note);
void setGuildOfficerNote(const std::string& name, const std::string& note);
void acceptGuildInvite();
void declineGuildInvite();
void queryGuildInfo(uint32_t guildId);
@ -353,6 +357,7 @@ public:
const std::string& getGuildName() const { return guildName_; }
const GuildRosterData& getGuildRoster() const { return guildRoster_; }
bool hasGuildRoster() const { return hasGuildRoster_; }
const std::vector<std::string>& getGuildRankNames() const { return guildRankNames_; }
bool hasPendingGuildInvite() const { return pendingGuildInvite_; }
const std::string& getPendingGuildInviterName() const { return pendingGuildInviterName_; }
const std::string& getPendingGuildInviteGuildName() const { return pendingGuildInviteGuildName_; }

View file

@ -117,6 +117,10 @@ enum class LogicalOpcode : uint16_t {
SMSG_GUILD_QUERY_RESPONSE,
SMSG_GUILD_INVITE,
CMSG_GUILD_REMOVE,
CMSG_GUILD_DISBAND,
CMSG_GUILD_LEADER,
CMSG_GUILD_SET_PUBLIC_NOTE,
CMSG_GUILD_SET_OFFICER_NOTE,
SMSG_GUILD_EVENT,
SMSG_GUILD_COMMAND_RESULT,

View file

@ -1003,6 +1003,30 @@ public:
static network::Packet build(const std::string& playerName);
};
/** CMSG_GUILD_DISBAND packet builder (empty body) */
class GuildDisbandPacket {
public:
static network::Packet build();
};
/** CMSG_GUILD_LEADER packet builder */
class GuildLeaderPacket {
public:
static network::Packet build(const std::string& playerName);
};
/** CMSG_GUILD_SET_PUBLIC_NOTE packet builder */
class GuildSetPublicNotePacket {
public:
static network::Packet build(const std::string& playerName, const std::string& note);
};
/** CMSG_GUILD_SET_OFFICER_NOTE packet builder */
class GuildSetOfficerNotePacket {
public:
static network::Packet build(const std::string& playerName, const std::string& note);
};
/** CMSG_GUILD_ACCEPT packet builder (empty body) */
class GuildAcceptPacket {
public:

View file

@ -64,6 +64,10 @@ private:
bool showChatWindow = true;
bool showPlayerInfo = false;
bool showGuildRoster_ = false;
std::string selectedGuildMember_;
bool showGuildNoteEdit_ = false;
bool editingOfficerNote_ = false;
char guildNoteEditBuffer_[256] = {0};
bool refocusChatInput = false;
bool chatWindowLocked = true;
ImVec2 chatWindowPos_ = ImVec2(0.0f, 0.0f);