[Dialogue Window / Saylinks] Missing Changes (#1574)

* Implement auto saylink injection

* Cover Lua say since it takes a different code path

* [Dialogue] Dialogue Window Middleware (#1526)

* Dialogue window quest dialogue work

* Add rest of DialogueWindow hooks

* Remove spacing
This commit is contained in:
Chris Miles 2021-10-01 22:09:21 -05:00 committed by GitHub
parent 0762ffa3dc
commit 3883adcefc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 107 additions and 13 deletions

View File

@ -601,6 +601,8 @@ RULE_INT(Chat, KarmaGlobalChatLimit, 72, "Amount of karma you need to be able to
RULE_INT(Chat, GlobalChatLevelLimit, 8, "Level limit you need to of reached to talk in ooc/auction/chat if your karma is too low")
RULE_BOOL(Chat, AutoInjectSaylinksToSay, true, "Automatically injects saylinks into dialogue that has [brackets in them]")
RULE_BOOL(Chat, AutoInjectSaylinksToClientMessage, true, "Automatically injects saylinks into dialogue that has [brackets in them]")
RULE_BOOL(Chat, QuestDialogueUsesDialogueWindow, false, "Pipes all quest dialogue to dialogue window")
RULE_BOOL(Chat, DialogueWindowAnimatesNPCsIfNoneSet, true, "If there is no animation specified in the dialogue window markdown then it will choose a random greet animation such as wave or salute")
RULE_CATEGORY_END()
RULE_CATEGORY(Merchant)

View File

@ -4,6 +4,10 @@ void DialogueWindow::Render(Client *c, std::string markdown)
{
std::string output = markdown;
if (!c->ClientDataLoaded()) {
return;
}
// this is the NPC that the client is interacting with if there is dialogue going on
Mob *target;
if (c->GetTarget()) {
@ -81,6 +85,21 @@ void DialogueWindow::Render(Client *c, std::string markdown)
}
}
if (animation.empty() && RuleB(Chat, DialogueWindowAnimatesNPCsIfNoneSet)) {
std::vector<int> greet_animations = {
29, // wave
48, // nodyes
64, // point
67, // salute
69, // tapfoot
70, // bowto
};
int random_animation = rand() % (greet_animations.size() - 1) + 0;
target->DoAnim(greet_animations[random_animation]);
}
// window expire time
std::string expire_time = get_between(output, "=", "=");
uint32 window_expire_seconds = 0;
@ -266,6 +285,33 @@ void DialogueWindow::Render(Client *c, std::string markdown)
std::vector<std::string> responses;
std::vector<std::string> bracket_responses;
if (markdown.find('[') != std::string::npos && markdown.find(']') != std::string::npos) {
// record any saylinks that may be in saylink form
std::string strip_saylinks = output;
std::map<std::string, std::string> replacements = {};
while (strip_saylinks.find('[') != std::string::npos && strip_saylinks.find(']') != std::string::npos) {
std::string bracket_message = get_between(strip_saylinks, "[", "]");
// strip saylinks and normalize to [regular message]
size_t link_open = bracket_message.find('\x12');
size_t link_close = bracket_message.find_last_of('\x12');
if (link_open != link_close && (bracket_message.length() - link_open) > EQ::constants::SAY_LINK_BODY_SIZE) {
replacements.insert(
std::pair<std::string, std::string>(
bracket_message,
bracket_message.substr(EQ::constants::SAY_LINK_BODY_SIZE + 1)
)
);
}
find_replace(strip_saylinks, fmt::format("[{}]", bracket_message), "");
}
// write replacement strips
for (auto &replacement: replacements) {
find_replace(output, replacement.first, replacement.second.substr(0, replacement.second.size() - 1));
}
// copy
std::string content = output;
@ -426,7 +472,6 @@ void DialogueWindow::Render(Client *c, std::string markdown)
}
}
// build the final output string
std::string final_output;
final_output = fmt::format("{}{}{} <br><br> {}", quote_string, output, quote_string, click_response);

View File

@ -43,6 +43,7 @@
#include "water_map.h"
#include "npc_scale_manager.h"
#include "../common/say_link.h"
#include "dialogue_window.h"
#ifdef _WINDOWS
#define snprintf _snprintf
@ -4202,8 +4203,25 @@ void EntityList::QuestJournalledSayClose(
buf.WriteInt32(0);
buf.WriteInt32(0);
// auto inject saylinks (say)
if (RuleB(Chat, AutoInjectSaylinksToSay)) {
if (RuleB(Chat, QuestDialogueUsesDialogueWindow)) {
for (auto &e : GetCloseMobList(sender, (dist * dist))) {
Mob *mob = e.second;
if (!mob->IsClient()) {
continue;
}
Client *client = mob->CastToClient();
if (client->GetTarget() && client->GetTarget()->IsMob() && client->GetTarget()->CastToMob() == sender) {
std::string window_markdown = message;
DialogueWindow::Render(client, window_markdown);
}
}
return;
}
else if (RuleB(Chat, AutoInjectSaylinksToSay)) {
std::string new_message = EQ::SayLinkEngine::InjectSaylinksIfNotExist(message);
buf.WriteString(new_message);
}

View File

@ -11,6 +11,7 @@
#include "lua_hate_list.h"
#include "lua_client.h"
#include "lua_stat_bonuses.h"
#include "dialogue_window.h"
struct SpecialAbilities { };
@ -757,7 +758,11 @@ void Lua_Mob::Message(int type, const char *message) {
Lua_Safe_Call_Void();
// auto inject saylinks
if (RuleB(Chat, AutoInjectSaylinksToClientMessage)) {
if (RuleB(Chat, QuestDialogueUsesDialogueWindow) && self->IsClient()) {
std::string window_markdown = message;
DialogueWindow::Render(self->CastToClient(), window_markdown);
}
else if (RuleB(Chat, AutoInjectSaylinksToClientMessage)) {
std::string new_message = EQ::SayLinkEngine::InjectSaylinksIfNotExist(message);
self->Message(type, new_message.c_str());
}

View File

@ -26,6 +26,7 @@
#include "worldserver.h"
#include "mob_movement_manager.h"
#include "water_map.h"
#include "dialogue_window.h"
#include <limits.h>
#include <math.h>
@ -2974,16 +2975,35 @@ void Mob::Say(const char *format, ...)
talker = this;
}
if (RuleB(Chat, AutoInjectSaylinksToSay)) {
int16 distance = 200;
if (RuleB(Chat, QuestDialogueUsesDialogueWindow)) {
for (auto &e : entity_list.GetCloseMobList(talker, (distance * distance))) {
Mob *mob = e.second;
if (!mob->IsClient()) {
continue;
}
Client *client = mob->CastToClient();
if (client->GetTarget() && client->GetTarget()->IsMob() && client->GetTarget()->CastToMob() == talker) {
std::string window_markdown = buf;
DialogueWindow::Render(client, window_markdown);
}
}
return;
}
else if (RuleB(Chat, AutoInjectSaylinksToSay)) {
std::string new_message = EQ::SayLinkEngine::InjectSaylinksIfNotExist(buf);
entity_list.MessageCloseString(
talker, false, 200, 10,
talker, false, distance, Chat::NPCQuestSay,
GENERIC_SAY, GetCleanName(), new_message.c_str()
);
}
else {
entity_list.MessageCloseString(
talker, false, 200, 10,
talker, false, distance, Chat::NPCQuestSay,
GENERIC_SAY, GetCleanName(), buf
);
}

View File

@ -41,6 +41,7 @@ typedef const char Const_char;
#include "mob.h"
#include "client.h"
#include "../common/spdat.h"
#include "dialogue_window.h"
#ifdef BOTS
#include "bot.h"
@ -2621,8 +2622,11 @@ XS(XS_Mob_Message) {
char *message = (char *) SvPV_nolen(ST(2));
VALIDATE_THIS_IS_MOB;
// auto inject saylinks
if (RuleB(Chat, AutoInjectSaylinksToClientMessage)) {
if (RuleB(Chat, QuestDialogueUsesDialogueWindow) && THIS->IsClient()) {
std::string window_markdown = message;
DialogueWindow::Render(THIS->CastToClient(), window_markdown);
}
else if (RuleB(Chat, AutoInjectSaylinksToClientMessage)) {
std::string new_message = EQ::SayLinkEngine::InjectSaylinksIfNotExist(message);
THIS->Message(type, new_message.c_str());
}