mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
fix: chat prefix, hostile faction display, and game object looting
- Add BG_SYSTEM_NEUTRAL/ALLIANCE/HORDE chat types (0x52-0x54) and reclassify them as SYSTEM in the parser — prevents bogus [Say] prefix on arena/BG system messages - Remove fallback [TypeName] bracket for sender-less SAY/YELL/WHISPER messages; only group-channel types (Party/Guild/Raid/BG) show brackets without a sender - Remove factionTemplate != 0 guard — units with FT=0 now get setHostile() like any other unit (defaulting to hostile from the map default), fixing NPCs that appeared friendly due to unset faction template - Enable CMSG_LOOT for WotLK type=3 (chest) game objects in addition to CMSG_GAMEOBJ_USE — fixes Milly's Harvest and other quest gather objects on AzerothCore WotLK servers
This commit is contained in:
parent
942df21c66
commit
1a370fef76
4 changed files with 52 additions and 19 deletions
|
|
@ -615,7 +615,11 @@ enum class ChatType : uint8_t {
|
||||||
MONSTER_WHISPER = 42,
|
MONSTER_WHISPER = 42,
|
||||||
RAID_BOSS_WHISPER = 43,
|
RAID_BOSS_WHISPER = 43,
|
||||||
RAID_BOSS_EMOTE = 44,
|
RAID_BOSS_EMOTE = 44,
|
||||||
MONSTER_PARTY = 50
|
MONSTER_PARTY = 50,
|
||||||
|
// BG/Arena system messages (WoW 3.3.5a — no sender, treated as SYSTEM in display)
|
||||||
|
BG_SYSTEM_NEUTRAL = 82,
|
||||||
|
BG_SYSTEM_ALLIANCE = 83,
|
||||||
|
BG_SYSTEM_HORDE = 84
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -7930,10 +7930,10 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
if (ghostStateCallback_) ghostStateCallback_(true);
|
if (ghostStateCallback_) ghostStateCallback_(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Determine hostility from faction template for online creatures
|
// Determine hostility from faction template for online creatures.
|
||||||
if (unit->getFactionTemplate() != 0) {
|
// Always call isHostileFaction — factionTemplate=0 defaults to hostile
|
||||||
unit->setHostile(isHostileFaction(unit->getFactionTemplate()));
|
// in the lookup rather than silently staying at the struct default (false).
|
||||||
}
|
unit->setHostile(isHostileFaction(unit->getFactionTemplate()));
|
||||||
// Trigger creature spawn callback for units/players with displayId
|
// Trigger creature spawn callback for units/players with displayId
|
||||||
if (block.objectType == ObjectType::UNIT && unit->getDisplayId() == 0) {
|
if (block.objectType == ObjectType::UNIT && unit->getDisplayId() == 0) {
|
||||||
LOG_WARNING("[Spawn] UNIT guid=0x", std::hex, block.guid, std::dec,
|
LOG_WARNING("[Spawn] UNIT guid=0x", std::hex, block.guid, std::dec,
|
||||||
|
|
@ -14287,8 +14287,9 @@ void GameHandler::performGameObjectInteractionNow(uint64_t guid) {
|
||||||
// animation/sound and expects the client to request the mail list.
|
// animation/sound and expects the client to request the mail list.
|
||||||
bool isMailbox = false;
|
bool isMailbox = false;
|
||||||
bool chestLike = false;
|
bool chestLike = false;
|
||||||
// Stock-like behavior: GO use opens GO loot context. Keep eager CMSG_LOOT only
|
// Chest-type game objects (type=3): on all expansions, also send CMSG_LOOT so
|
||||||
// as Classic/Turtle fallback behavior.
|
// the server opens the loot response. Other harvestable/interactive types rely
|
||||||
|
// on the server auto-sending SMSG_LOOT_RESPONSE after CMSG_GAMEOBJ_USE.
|
||||||
bool shouldSendLoot = isActiveExpansion("classic") || isActiveExpansion("turtle");
|
bool shouldSendLoot = isActiveExpansion("classic") || isActiveExpansion("turtle");
|
||||||
if (entity && entity->getType() == ObjectType::GAMEOBJECT) {
|
if (entity && entity->getType() == ObjectType::GAMEOBJECT) {
|
||||||
auto go = std::static_pointer_cast<GameObject>(entity);
|
auto go = std::static_pointer_cast<GameObject>(entity);
|
||||||
|
|
@ -14305,6 +14306,8 @@ void GameHandler::performGameObjectInteractionNow(uint64_t guid) {
|
||||||
refreshMailList();
|
refreshMailList();
|
||||||
} else if (info && info->type == 3) {
|
} else if (info && info->type == 3) {
|
||||||
chestLike = true;
|
chestLike = true;
|
||||||
|
// Type-3 chests require CMSG_LOOT on all expansions (AzerothCore WotLK included)
|
||||||
|
shouldSendLoot = true;
|
||||||
} else if (turtleMode) {
|
} else if (turtleMode) {
|
||||||
// Turtle compatibility: keep eager loot open behavior.
|
// Turtle compatibility: keep eager loot open behavior.
|
||||||
shouldSendLoot = true;
|
shouldSendLoot = true;
|
||||||
|
|
@ -14315,21 +14318,19 @@ void GameHandler::performGameObjectInteractionNow(uint64_t guid) {
|
||||||
std::transform(lower.begin(), lower.end(), lower.begin(),
|
std::transform(lower.begin(), lower.end(), lower.begin(),
|
||||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||||
chestLike = (lower.find("chest") != std::string::npos);
|
chestLike = (lower.find("chest") != std::string::npos);
|
||||||
|
if (chestLike) shouldSendLoot = true;
|
||||||
}
|
}
|
||||||
// For WotLK chest-like gameobjects, report use but let server open loot.
|
// For WotLK chest-like gameobjects, also send CMSG_GAMEOBJ_REPORT_USE.
|
||||||
if (!isMailbox && chestLike) {
|
if (!isMailbox && chestLike && isActiveExpansion("wotlk")) {
|
||||||
if (isActiveExpansion("wotlk")) {
|
network::Packet reportUse(wireOpcode(Opcode::CMSG_GAMEOBJ_REPORT_USE));
|
||||||
network::Packet reportUse(wireOpcode(Opcode::CMSG_GAMEOBJ_REPORT_USE));
|
reportUse.writeUInt64(guid);
|
||||||
reportUse.writeUInt64(guid);
|
socket->send(reportUse);
|
||||||
socket->send(reportUse);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (shouldSendLoot) {
|
if (shouldSendLoot) {
|
||||||
lootTarget(guid);
|
lootTarget(guid);
|
||||||
}
|
}
|
||||||
// Retry use briefly to survive packet loss/order races. Keep loot retries only
|
// Retry use briefly to survive packet loss/order races.
|
||||||
// when we intentionally use eager loot-open mode.
|
const bool retryLoot = shouldSendLoot;
|
||||||
const bool retryLoot = shouldSendLoot && (turtleMode || isActiveExpansion("classic"));
|
|
||||||
const bool retryUse = turtleMode || isActiveExpansion("classic");
|
const bool retryUse = turtleMode || isActiveExpansion("classic");
|
||||||
if (retryUse || retryLoot) {
|
if (retryUse || retryLoot) {
|
||||||
pendingGameObjectLootRetries_.push_back(PendingLootRetry{guid, 0.15f, 2, retryLoot});
|
pendingGameObjectLootRetries_.push_back(PendingLootRetry{guid, 0.15f, 2, retryLoot});
|
||||||
|
|
|
||||||
|
|
@ -1422,6 +1422,14 @@ bool MessageChatParser::parse(network::Packet& packet, MessageChatData& data) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ChatType::BG_SYSTEM_NEUTRAL:
|
||||||
|
case ChatType::BG_SYSTEM_ALLIANCE:
|
||||||
|
case ChatType::BG_SYSTEM_HORDE:
|
||||||
|
// BG/Arena system messages — no sender GUID or name field, just message.
|
||||||
|
// Reclassify as SYSTEM for consistent display.
|
||||||
|
data.type = ChatType::SYSTEM;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// SAY, GUILD, PARTY, YELL, WHISPER, WHISPER_INFORM, RAID, etc.
|
// SAY, GUILD, PARTY, YELL, WHISPER, WHISPER_INFORM, RAID, etc.
|
||||||
// All have receiverGuid (typically senderGuid repeated)
|
// All have receiverGuid (typically senderGuid repeated)
|
||||||
|
|
|
||||||
|
|
@ -1251,8 +1251,25 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
|
||||||
renderTextWithLinks(fullMsg, color);
|
renderTextWithLinks(fullMsg, color);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::string fullMsg = tsPrefix + "[" + std::string(getChatTypeName(msg.type)) + "] " + processedMessage;
|
// No sender name. For group/channel types show a bracket prefix;
|
||||||
renderTextWithLinks(fullMsg, color);
|
// for sender-specific types (SAY, YELL, WHISPER, etc.) just show the
|
||||||
|
// raw message — these are server-side announcements without a speaker.
|
||||||
|
bool isGroupType =
|
||||||
|
msg.type == game::ChatType::PARTY ||
|
||||||
|
msg.type == game::ChatType::GUILD ||
|
||||||
|
msg.type == game::ChatType::OFFICER ||
|
||||||
|
msg.type == game::ChatType::RAID ||
|
||||||
|
msg.type == game::ChatType::RAID_LEADER ||
|
||||||
|
msg.type == game::ChatType::RAID_WARNING ||
|
||||||
|
msg.type == game::ChatType::BATTLEGROUND ||
|
||||||
|
msg.type == game::ChatType::BATTLEGROUND_LEADER;
|
||||||
|
if (isGroupType) {
|
||||||
|
std::string fullMsg = tsPrefix + "[" + std::string(getChatTypeName(msg.type)) + "] " + processedMessage;
|
||||||
|
renderTextWithLinks(fullMsg, color);
|
||||||
|
} else {
|
||||||
|
// SAY, YELL, WHISPER, unknown BG_SYSTEM_* types, etc. — no prefix
|
||||||
|
renderTextWithLinks(tsPrefix + processedMessage, color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3421,6 +3438,9 @@ const char* GameScreen::getChatTypeName(game::ChatType type) const {
|
||||||
case game::ChatType::ACHIEVEMENT: return "Achievement";
|
case game::ChatType::ACHIEVEMENT: return "Achievement";
|
||||||
case game::ChatType::DND: return "DND";
|
case game::ChatType::DND: return "DND";
|
||||||
case game::ChatType::AFK: return "AFK";
|
case game::ChatType::AFK: return "AFK";
|
||||||
|
case game::ChatType::BG_SYSTEM_NEUTRAL:
|
||||||
|
case game::ChatType::BG_SYSTEM_ALLIANCE:
|
||||||
|
case game::ChatType::BG_SYSTEM_HORDE: return "System";
|
||||||
default: return "Unknown";
|
default: return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue