[Quest API] Port DiaWind Plugin to Native Quest API (#1521)

* Port DiaWind plugin to native Quest API

* Add no logging aliases
This commit is contained in:
Chris Miles 2021-09-05 20:29:21 -05:00 committed by GitHub
parent e7dd8d49a9
commit c078257f70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 874 additions and 327 deletions

View File

@ -124,6 +124,7 @@ namespace Logs {
Scheduler,
Cheat,
ClientList,
DiaWind,
MaxCategoryID /* Don't Remove this */
};
@ -206,6 +207,7 @@ namespace Logs {
"Scheduler",
"Cheat",
"ClientList",
"DialogueWindow",
};
}

View File

@ -666,6 +666,16 @@
OutF(LogSys, Logs::Detail, Logs::ClientList, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDiaWind(message, ...) do {\
if (LogSys.log_settings[Logs::DiaWind].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::DiaWind, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDiaWindDetail(message, ...) do {\
if (LogSys.log_settings[Logs::DiaWind].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::DiaWind, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@ -1050,6 +1060,12 @@
#define LogClientListDetail(message, ...) do {\
} while (0)
#define LogDiaWind(message, ...) do {\
} while (0)
#define LogDiaWindDetail(message, ...) do {\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
} while (0)

View File

@ -116,6 +116,42 @@ std::vector<std::string> SplitString(const std::string &str, const char delim) {
return ret;
}
// this one takes delimiter length into consideration
std::vector<std::string> split_string(std::string s, std::string delimiter)
{
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
std::string token;
std::vector<std::string> res;
while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {
token = s.substr(pos_start, pos_end - pos_start);
pos_start = pos_end + delim_len;
res.push_back(token);
}
res.push_back(s.substr(pos_start));
return res;
}
std::string get_between(const std::string &s, std::string start_delim, std::string stop_delim)
{
if (s.find(start_delim) == std::string::npos && s.find(stop_delim) == std::string::npos) {
return "";
}
auto first_split = split_string(s, start_delim);
if (!first_split.empty()) {
std::string remaining_block = first_split[1];
auto second_split = split_string(remaining_block, stop_delim);
if (!second_split.empty()) {
std::string between = second_split[0];
return between;
}
}
return "";
}
std::string::size_type search_deliminated_string(const std::string &haystack, const std::string &needle, const char deliminator)
{
// this shouldn't go out of bounds, even without obvious bounds checks
@ -280,7 +316,16 @@ void find_replace(std::string &string_subject, const std::string &search_string,
string_subject.replace(start_pos, search_string.length(), replace_string);
start_pos += replace_string.length();
}
}
std::string replace_string(std::string subject, const std::string &search, const std::string &replace)
{
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
}
void ParseAccountString(const std::string &s, std::string &account, std::string &loginserver)

View File

@ -177,6 +177,8 @@ std::vector<std::string> join_tuple(const std::string &glue, const std::pair<cha
}
std::vector<std::string> SplitString(const std::string &s, const char delim = ',');
std::vector<std::string> split_string(std::string s, std::string delimiter);
std::string get_between(const std::string &s, std::string start_delim, std::string stop_delim);
std::string::size_type search_deliminated_string(const std::string &haystack, const std::string &needle, const char deliminator = ',');
std::string EscapeString(const char *src, size_t sz);
std::string EscapeString(const std::string &s);
@ -185,6 +187,7 @@ void ToLowerString(std::string &s);
void ToUpperString(std::string &s);
std::string JoinString(const std::vector<std::string>& ar, const std::string &delim);
void find_replace(std::string& string_subject, const std::string& search_string, const std::string& replace_string);
std::string replace_string(std::string subject, const std::string &search, const std::string &replace);
void ParseAccountString(const std::string &s, std::string &account, std::string &loginserver);
//const char based

View File

@ -23,6 +23,7 @@ SET(zone_sources
corpse.cpp
data_bucket.cpp
doors.cpp
dialogue_window.cpp
dynamic_zone.cpp
effects.cpp
embparser.cpp
@ -182,6 +183,7 @@ SET(zone_headers
corpse.h
data_bucket.h
doors.h
dialogue_window.h
dynamic_zone.h
embparser.h
embperl.h

View File

@ -203,7 +203,9 @@ enum eInnateSkill {
InnateDisabled = 255
};
const uint32 POPUPID_UPDATE_SHOWSTATSWINDOW = 1000000;
const std::string DIAWIND_RESPONSE_KEY = "diawind_npcresponse";
const uint32 POPUPID_DIAWIND = 999;
const uint32 POPUPID_UPDATE_SHOWSTATSWINDOW = 1000000;
struct ClientReward
{

View File

@ -11132,6 +11132,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
/**
* Handle any EQEmu defined popup Ids first
*/
std::string response;
switch (popup_response->popupid) {
case POPUPID_UPDATE_SHOWSTATSWINDOW:
if (GetTarget() && GetTarget()->IsClient()) {
@ -11143,6 +11144,13 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
return;
break;
case POPUPID_DIAWIND:
response = GetEntityVariable(DIAWIND_RESPONSE_KEY.c_str());
if (!response.empty()) {
ChannelMessageReceived(8, 0, 100, response.c_str());
}
break;
case EQ::popupresponse::MOB_INFO_DISMISS:
SetDisplayMobInfoWindow(false);
Message(Chat::Yellow, "[DevTools] Window snoozed in this zone...");

338
zone/dialogue_window.cpp Normal file
View File

@ -0,0 +1,338 @@
#include "dialogue_window.h"
void DialogueWindow::Render(Client *c, std::string markdown)
{
std::string output = markdown;
// this is the NPC that the client is interacting with if there is dialogue going on
Mob *target;
if (c->GetTarget()) {
target = c->GetTarget();
}
// zero this out
c->SetEntityVariable(DIAWIND_RESPONSE_KEY.c_str(), "");
// simple find and replace for the markdown
find_replace(output, "~", "</c>");
find_replace(output, "{y}", "<c \"#CCFF33\">");
find_replace(output, "{lb}", "<c \"#00FFFF\">");
find_replace(output, "{r}", "<c \"#FF0000\">");
find_replace(output, "{g}", "<c \"#00FF00\">");
find_replace(output, "{gold}", "<c \"#FFFF66\">");
find_replace(output, "{orange}", "<c \"#FFA500\">");
find_replace(output, "{gray}", "<c \"#808080\">");
find_replace(output, "{tan}", "<c \"#daa520\">");
find_replace(output, "{bullet}", "");
find_replace(output, "{name}", "$name");
find_replace(output, "{linebreak}", "--------------------------------------------------------------------");
find_replace(output, "{rowpad}", R"(<tr><td>{tdpad}<"td><td>{tdpad}<"td><"tr>)");
find_replace(output, "{tdpad}", "----------------------");
find_replace(output, "{in}", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
// mysterious voice
bool render_mysterious_voice = false;
if (markdown.find("mysterious") != std::string::npos) {
render_mysterious_voice = true;
LogDiaWind("Client [{}] Rendering mysterious voice", c->GetCleanName());
find_replace(output, "mysterious", "");
}
// noquotes
bool render_noquotes = false;
if (markdown.find("noquotes") != std::string::npos) {
render_noquotes = true;
LogDiaWind("Client [{}] Rendering noquotes", c->GetCleanName());
find_replace(output, "noquotes", "");
}
// nobracket
bool render_nobracket = false;
if (markdown.find("nobracket") != std::string::npos) {
render_nobracket = true;
LogDiaWind("Client [{}] Rendering nobracket", c->GetCleanName());
find_replace(output, "nobracket", "");
}
// animations
std::string animation = get_between(output, "+", "+");
if (!animation.empty()) {
LogDiaWind("Client [{}] Animation is not empty, contents are [{}]", c->GetCleanName(), animation);
find_replace(output, fmt::format("+{}+", animation), "");
// we treat the animation field differently if it is a number
if (StringIsNumber(animation)) {
LogDiaWindDetail("Client [{}] Animation is a number, firing animation [{}]", c->GetCleanName(), animation);
target->DoAnim(std::stoi(animation));
}
else {
for (auto &a: animations) {
if (a.first.find(str_tolower(animation)) != std::string::npos) {
LogDiaWindDetail(
"Client [{}] Animation is a string, firing animation [{}] [{}]",
c->GetCleanName(),
a.second,
a.first
);
target->DoAnim(a.second);
}
}
}
}
// window expire time
std::string expire_time = get_between(output, "=", "=");
uint32 window_expire_seconds = 0;
if (!expire_time.empty()) {
LogDiaWind("Client [{}] Window expire time is not empty, contents are [{}]", c->GetCleanName(), expire_time);
find_replace(output, fmt::format("={}=", expire_time), "");
// we treat the animation field differently if it is a number
if (StringIsNumber(expire_time)) {
LogDiaWindDetail(
"Client [{}] Window expire time is a number, setting expiration to [{}]",
c->GetCleanName(),
expire_time
);
window_expire_seconds = std::stoi(expire_time);
}
}
uint32 popup_id = POPUPID_DIAWIND;
uint32 negative_id = 0;
char *button_name_0 = nullptr;
char *button_name_1 = nullptr;
uint32 sound_controls = 0;
// window type
std::string wintype;
if (markdown.find("wintype") != std::string::npos) {
LogDiaWind("Client [{}] Rendering wintype option", c->GetCleanName());
auto first_split = split_string(output, "wintype:");
if (!first_split.empty()) {
// assumed that there is more after the wintype declaration
// wintype:0 +animation+ etc.
auto second_split = split_string(first_split[1], " ");
if (!second_split.empty()) {
wintype = second_split[0];
LogDiaWindDetail("Client [{}] Rendering wintype option wintype [{}]", c->GetCleanName(), wintype);
}
// if we're dealing with a string that is at the end
// example wintype:0");
if (first_split[1].length() == 1) {
wintype = first_split[1];
LogDiaWindDetail(
"Client [{}] Rendering wintype (end) option wintype [{}]",
c->GetCleanName(),
wintype
);
}
find_replace(output, fmt::format("wintype:{}", wintype), "");
}
}
// popupid
std::string popupid;
if (markdown.find("popupid") != std::string::npos) {
LogDiaWind("Client [{}] Rendering popupid option", c->GetCleanName());
auto first_split = split_string(output, "popupid:");
if (!first_split.empty()) {
// assumed that there is more after the popupid declaration
// popupid:0 +animation+ etc.
auto second_split = split_string(first_split[1], " ");
if (!second_split.empty()) {
popupid = second_split[0];
LogDiaWindDetail("Client [{}] Rendering popupid option popupid [{}]", c->GetCleanName(), popupid);
}
// if we're dealing with a string that is at the end
// example popupid:0");
if (first_split[1].length() == 1) {
popupid = first_split[1];
LogDiaWindDetail(
"Client [{}] Rendering popupid (end) option popupid [{}]",
c->GetCleanName(),
popupid
);
}
find_replace(output, fmt::format("popupid:{}", popupid), "");
// set the popup id
if (!popupid.empty()) {
popup_id = (StringIsNumber(popupid) ? std::atoi(popupid.c_str()) : 0);
}
}
}
// bracket responses
std::vector<std::string> responses;
std::vector<std::string> bracket_responses;
if (markdown.find('[') != std::string::npos && markdown.find(']') != std::string::npos) {
// copy
std::string content = output;
// while brackets still exist
int response_index = 0;
while (content.find('[') != std::string::npos && content.find(']') != std::string::npos) {
std::string bracket_message = get_between(content, "[", "]");
LogDiaWindDetail(
"Client [{}] Rendering responses ({}) [{}]",
c->GetCleanName(),
response_index,
bracket_message
);
// pop message onto responses
responses.emplace_back(bracket_message);
// pop the response off of the message
find_replace(content, fmt::format("[{}]", bracket_message), "");
response_index++;
}
}
// build saylinks
if (responses.size() > 1) {
for (auto &r: responses) {
bracket_responses.emplace_back(
fmt::format("[{}]", EQ::SayLinkEngine::GenerateQuestSaylink(r, false, r))
);
}
}
// handle silent prompts from the [> silent syntax
std::string silent_message;
if (responses.empty() && markdown.find('[') != std::string::npos && markdown.find('>') != std::string::npos) {
silent_message = get_between(output, "[", ">");
// temporary and used during the response
c->SetEntityVariable(DIAWIND_RESPONSE_KEY.c_str(), silent_message.c_str());
// pop the silent message off
find_replace(output, fmt::format("[{}>", silent_message), "");
}
else if (!responses.empty()) {
// handle silent prompts from the single respond bracket syntax []
silent_message = responses[0];
// temporary and used during the response
c->SetEntityVariable(DIAWIND_RESPONSE_KEY.c_str(), silent_message.c_str());
// pop the silent message off
find_replace(output, fmt::format("[{}]", silent_message), "");
}
// strip brackets
if (render_nobracket) {
find_replace(output, "[", "");
find_replace(output, "]", "");
}
// render title
std::string title;
std::string speaking;
if (target) {
speaking = fmt::format("{} says", target->GetCleanName());
}
if (render_mysterious_voice) {
speaking = "A Mysterious Voice says";
}
title = fmt::format("Dialogue [{}]", speaking);
// render quotes
std::string quote_string = "'";
if (render_noquotes) {
quote_string = "";
}
// click response
// window type response
uint32 window_type = (StringIsNumber(wintype) ? std::atoi(wintype.c_str()) : 0);
std::string click_response_button = (window_type == 1 ? "Yes" : "OK");
std::string click_response = fmt::format(
"<c \"#F07F00\">Click [{}] to continue...</c>",
click_response_button
);
// different response when a timer is set
if (window_expire_seconds > 0) {
click_response = fmt::format(
"<c \"#F07F00\">This message will disappear in {} second(s)...</c>",
window_expire_seconds
);
}
// respond with silent message
if (!silent_message.empty()) {
click_response = fmt::format(
"<c \"#F07F00\">Click [{}] to respond with [{}]...</c>",
click_response_button,
silent_message
);
}
// post processing of color markdowns
// {spring_green_1} = <c "#5EFB6E">
if (markdown.find('{') != std::string::npos && markdown.find('}') != std::string::npos) {
// while brackets still exist
int tag_index = 0;
while (output.find('{') != std::string::npos && output.find('}') != std::string::npos) {
std::string color_tag = get_between(output, "{", "}");
LogDiaWindDetail(
"Client [{}] Rendering color tags ({}) [{}]",
c->GetCleanName(),
tag_index,
color_tag
);
std::string html_tag;
for (const auto& color : html_colors) {
if (color_tag.find(color.first) != std::string::npos) {
// build html tag
html_tag = fmt::format("<c \"{}\">", color.second);
// pop the response off of the message
find_replace(output, fmt::format("{{{}}}", color.first), html_tag);
}
}
tag_index++;
}
}
// build the final output string
std::string final_output;
final_output = fmt::format("{}{}{} <br><br> {}", quote_string, output, quote_string, click_response);
// send popup
c->SendFullPopup(
title.c_str(),
final_output.c_str(),
popup_id,
negative_id,
window_type,
window_expire_seconds,
button_name_0,
button_name_1,
sound_controls
);
// if multiple brackets are presented, send message
if (!bracket_responses.empty()) {
c->Message(Chat::White, " --- Select Response from Options --- ");
c->Message(Chat::White, implode(" ", bracket_responses).c_str());
}
}

394
zone/dialogue_window.h Normal file
View File

@ -0,0 +1,394 @@
#ifndef EQEMU_DIALOGUE_WINDOW_H
#define EQEMU_DIALOGUE_WINDOW_H
#include <string>
#include "client.h"
static const std::map<std::string, std::string> html_colors = {
{"black", "#000000"},
{"brown", "#804000"},
{"burgundy", "#800000"},
{"cadet_blue", "#77BFC7"},
{"cadet_blue_1", "#4C787E"},
{"chartreuse", "#8AFB17"},
{"chartreuse_1", "#7FE817"},
{"chartreuse_2", "#6CC417"},
{"chartreuse_3", "#437C17"},
{"chocolate", "#C85A17"},
{"coral", "#F76541"},
{"coral_1", "#E55B3C"},
{"coral_2", "#C34A2C"},
{"cornflower_blue", "#151B8D"},
{"cyan", "#00FFFF"},
{"cyan_1", "#57FEFF"},
{"cyan_2", "#50EBEC"},
{"cyan_3", "#46C7C7"},
{"cyan_4", "#307D7E"},
{"dark_blue", "#0000A0"},
{"dark_goldenrod", "#AF7817"},
{"dark_goldenrod_1", "#FBB117"},
{"dark_goldenrod_2", "#E8A317"},
{"dark_goldenrod_3", "#C58917"},
{"dark_goldenrod_4", "#7F5217"},
{"dark_green", "#254117"},
{"dark_grey", "#808080"},
{"dark_olive_green", "#CCFB5D"},
{"dark_olive_green_2", "#BCE954"},
{"dark_olive_green_3", "#A0C544"},
{"dark_olive_green_4", "#667C26"},
{"dark_orange", "#F88017"},
{"dark_orange_1", "#F87217"},
{"dark_orange_2", "#E56717"},
{"dark_orange_3", "#7E3117"},
{"dark_orange_3", "#C35617"},
{"dark_orchid", "#7D1B7E"},
{"dark_orchid_1", "#B041FF"},
{"dark_orchid_2", "#A23BEC"},
{"dark_orchid_3", "#8B31C7"},
{"dark_orchid_4", "#571B7e"},
{"dark_purple", "#800080"},
{"dark_salmon", "#E18B6B"},
{"dark_sea_green", "#8BB381"},
{"dark_sea_green_1", "#C3FDB8"},
{"dark_sea_green_2", "#B5EAAA"},
{"dark_sea_green_3", "#99C68E"},
{"dark_sea_green_4", "#617C58"},
{"dark_slate_blue", "#2B3856"},
{"dark_slate_gray", "#25383C"},
{"dark_slate_gray_1", "#9AFEFF"},
{"dark_slate_gray_2", "#8EEBEC"},
{"dark_slate_gray_3", "#78c7c7"},
{"dark_slate_gray_4", "#4C7D7E"},
{"dark_turquoise", "#3B9C9C"},
{"dark_violet", "#842DCE"},
{"deep_pink", "#F52887"},
{"deep_pink_1", "#E4287C"},
{"deep_pink_2", "#C12267"},
{"deep_pink_3", "#7D053F"},
{"deep_sky_blue", "#3BB9FF"},
{"deep_sky_blue_1", "#38ACEC"},
{"deep_sky_blue_2", "#3090C7"},
{"deep_sky_blue_3", "#25587E"},
{"dim_gray", "#463E41"},
{"dodger_blue", "#1589FF"},
{"dodger_blue_1", "#157DEC"},
{"dodger_blue_2", "#1569C7"},
{"dodger_blue_3", "#153E7E"},
{"firebrick", "#800517"},
{"firebrick_1", "#F62817"},
{"firebrick_2", "#E42217"},
{"firebrick_3", "#C11B17"},
{"forest_green", "#4E9258"},
{"forest_green_1", "#808000"},
{"gold", "#D4A017"},
{"gold_1", "#FDD017"},
{"gold_2", "#EAC117"},
{"gold_3", "#C7A317"},
{"gold_4", "#806517"},
{"goldenrod", "#EDDA74"},
{"goldenrod_1", "#FBB917"},
{"goldenrod_2", "#E9AB17"},
{"goldenrod_3", "#C68E17"},
{"goldenrod_4", "#805817"},
{"grass_green", "#408080"},
{"gray", "#736F6E"},
{"gray_1", "#150517"},
{"gray_2", "#250517"},
{"gray_3", "#2B1B17"},
{"gray_4", "#302217"},
{"gray_5", "#302226"},
{"gray_6", "#342826"},
{"gray_7", "#34282C"},
{"gray_8", "#382D2C"},
{"gray_9", "#3b3131"},
{"gray_10", "#3E3535"},
{"gray_11", "#413839"},
{"gray_12", "#41383C"},
{"gray_13", "#463E3F"},
{"gray_14", "#4A4344"},
{"gray_15", "#4C4646"},
{"gray_16", "#4E4848"},
{"gray_17", "#504A4B"},
{"gray_18", "#544E4F"},
{"gray_19", "#565051"},
{"gray_19", "#595454"},
{"gray_20", "#5C5858"},
{"gray_21", "#5F5A59"},
{"gray_22", "#625D5D"},
{"gray_23", "#646060"},
{"gray_24", "#666362"},
{"gray_25", "#696565"},
{"gray_26", "#6D6968"},
{"gray_27", "#6E6A6B"},
{"gray_28", "#726E6D"},
{"gray_29", "#747170"},
{"green", "#00FF00"},
{"green_1", "#5FFB17"},
{"green_2", "#59E817"},
{"green_3", "#4CC417"},
{"green_4", "#347C17"},
{"green_yellow", "#B1FB17"},
{"hot_pink", "#F660AB"},
{"hot_pink_1", "#F665AB"},
{"hot_pink_2", "#E45E9D"},
{"hot_pink_3", "#C25283"},
{"hot_pink_4", "#7D2252"},
{"indian_red", "#F75D59"},
{"indian_red_2", "#E55451"},
{"indian_red_3", "#C24641"},
{"indian_red_4", "#7E2217"},
{"khaki", "#ADA96E"},
{"khaki_1", "#FFF380"},
{"khaki_2", "#EDE275"},
{"khaki_3", "#C9BE62"},
{"khaki_4", "#827839"},
{"lavender", "#E3E4FA"},
{"lavender_blush", "#FDEEF4"},
{"lavender_blush_1", "#EBDDE2"},
{"lavender_blush_2", "#C8BBBE"},
{"lavender_blush_3", "#817679"},
{"lawn_green", "#87F717"},
{"lemon_chiffon", "#FFF8C6"},
{"lemon_chiffon_1", "#ECE5B6"},
{"lemon_chiffon_2", "#C9C299"},
{"lemon_chiffon_3", "#827B60"},
{"light_blue", "#0000FF"},
{"light_blue_1", "#ADDFFF"},
{"light_blue_2", "#BDEDFF"},
{"light_blue_3", "#AFDCEC"},
{"light_blue_4", "#95B9C7"},
{"light_blue_5", "#5E767E"},
{"light_coral", "#E77471"},
{"light_cyan", "#E0FFFF"},
{"light_cyan_1", "#CFECEC"},
{"light_cyan_2", "#AFC7C7"},
{"light_cyan_3", "#717D7D"},
{"light_golden", "#ECD672"},
{"light_goldenrod", "#ECD872"},
{"light_goldenrod_1", "#FFE87C"},
{"light_goldenrod_2", "#C8B560"},
{"light_goldenrod_3", "#817339"},
{"light_goldenrod_yellow", "#FAF8CC"},
{"light_grey", "#C0C0C0"},
{"light_pink", "#FAAFBA"},
{"light_pink_1", "#F9A7B0"},
{"light_pink_2", "#E799A3"},
{"light_pink_3", "#C48189"},
{"light_pink_4", "#7F4E52"},
{"light_purple", "#FF0080"},
{"light_salmon", "#F9966B"},
{"light_salmon_1", "#E78A61"},
{"light_salmon_2", "#C47451"},
{"light_salmon_3", "#7F462C"},
{"light_sea_green", "#3EA99F"},
{"light_sky_blue", "#82CAFA"},
{"light_sky_blue_1", "#A0CFEC"},
{"light_sky_blue_2", "#87AFC7"},
{"light_sky_blue_3", "#566D7E"},
{"light_slate_blue", "#736AFF"},
{"light_slate_gray", "#6D7B8D"},
{"light_steel_blue", "#728FCE"},
{"light_steel_blue_1", "#C6DEFF"},
{"light_steel_blue_2", "#B7CEEC"},
{"light_steel_blue_3", "#646D7E"},
{"lime_green", "#41A317"},
{"magenta", "#FF00FF"},
{"magenta_1", "#F433FF"},
{"magenta_2", "#E238EC"},
{"magenta_3", "#C031C7"},
{"maroon", "#810541"},
{"maroon_1", "#F535AA"},
{"maroon_2", "#E3319D"},
{"maroon_3", "#C12283"},
{"maroon_4", "#7D0552"},
{"medium_aquamarine", "#348781"},
{"medium_forest_green", "#347235"},
{"medium_orchid", "#B048B5"},
{"medium_orchid_1", "#D462FF"},
{"medium_orchid_2", "#C45AEC"},
{"medium_orchid_3", "#A74AC7"},
{"medium_orchid_4", "#6A287E"},
{"medium_purple", "#8467D7"},
{"medium_purple_1", "#9E7BFF"},
{"medium_purple_2", "#9172EC"},
{"medium_purple_3", "#7A5DC7"},
{"medium_purple_4", "#4E387E"},
{"medium_sea_green", "#306754"},
{"medium_slate_blue", "#5E5A80"},
{"medium_spring_green", "#348017"},
{"medium_turquoise", "#48CCCD"},
{"medium_violet_red", "#CA226B"},
{"midnight_blue", "#151B54"},
{"orange", "#FF8040"},
{"pale_turquoise", "#92C7C7"},
{"pale_turquoise_1", "#5E7D7E"},
{"pale_violet_red", "#D16587"},
{"pale_violet_red_1", "#F778A1"},
{"pale_violet_red_2", "#E56E94"},
{"pale_violet_red_3", "#C25A7C"},
{"pale_violet_red_4", "#7E354D"},
{"pastel_green", "#00FF00"},
{"pink", "#FAAFBE"},
{"pink_1", "#FF00FF"},
{"pink_2", "#E7A1B0"},
{"pink_3", "#C48793"},
{"pink_4", "#7F525D"},
{"plum", "#B93B8F"},
{"plum_1", "#F9B7FF"},
{"plum_2", "#E6A9EC"},
{"plum_3", "#C38EC7"},
{"plum_4", "#7E587E"},
{"purple", "#8E35EF"},
{"purple_1", "#893BFF"},
{"purple_2", "#7F38EC"},
{"purple_3", "#6C2DC7"},
{"purple_4", "#461B7E"},
{"red", "#FF0000"},
{"red_1", "#F62217"},
{"red_2", "#E41B17"},
{"rosy_brown", "#B38481"},
{"rosy_brown_1", "#FBBBB9"},
{"rosy_brown_2", "#E8ADAA"},
{"rosy_brown_3", "#C5908E"},
{"rosy_brown_4", "#7F5A58"},
{"royal_blue", "#2B60DE"},
{"royal_blue_1", "#306EFF"},
{"royal_blue_2", "#2B65EC"},
{"royal_blue_3", "#2554C7"},
{"royal_blue_4", "#15317E"},
{"salmon_1", "#F88158"},
{"salmon_2", "#E67451"},
{"salmon_3", "#C36241"},
{"salmon_4", "#7E3817"},
{"sandy_brown", "#EE9A4D"},
{"sea_green", "#4E8975"},
{"sea_green_1", "#6AFB92"},
{"sea_green_2", "#64E986"},
{"sea_green_3", "#54C571"},
{"sea_green_4", "#387C44"},
{"sienna", "#8A4117"},
{"sienna_1", "#F87431"},
{"sienna_2", "#E66C2C"},
{"sienna_3", "#C35817"},
{"sienna_4", "#7E3517"},
{"sky_blue", "#82CAFF"},
{"sky_blue_1", "#6698FF"},
{"sky_blue_2", "#79BAEC"},
{"sky_blue_3", "#659EC7"},
{"sky_blue_4", "#41627E"},
{"slate_blue", "#357EC7"},
{"slate_blue_1", "#737CA1"},
{"slate_blue_2", "#6960EC"},
{"slate_blue_3", "#342D7E"},
{"slate_gray", "#657383"},
{"slate_gray_1", "#C2DFFF"},
{"slate_gray_2", "#B4CFEC"},
{"slate_gray_3", "#98AFC7"},
{"slate_gray_4", "#616D7E"},
{"spring_green", "#4AA02C"},
{"spring_green_1", "#5EFB6E"},
{"spring_green_2", "#57E964"},
{"spring_green_3", "#4CC552"},
{"spring_green_4", "#347C2C"},
{"steel_blue", "#4863A0"},
{"steel_blue_1", "#5CB3FF"},
{"steel_blue_2", "#56A5EC"},
{"steel_blue_3", "#488AC7"},
{"steel_blue_4", "#2B547E"},
{"thistle", "#D2B9D3"},
{"thistle_1", "#FCDFFF"},
{"thistle_2", "#E9CFEC"},
{"thistle_3", "#C6AEC7"},
{"thistle_4", "#806D7E"},
{"turquoise", "#00FFFF"},
{"turquoise_1", "#43C6DB"},
{"turquoise_2", "#52F3FF"},
{"turquoise_3", "#4EE2EC"},
{"turquoise_4", "#43BFC7"},
{"violet", "#8D38C9"},
{"violet_red", "#F6358A"},
{"violet_red_1", "#F6358A"},
{"violet_red_2", "#E4317F"},
{"violet_red_3", "#C12869"},
{"violet_red_4", "#7D0541"},
{"white", "#FFFFFF"},
{"yellow", "#FFFF00"},
{"yellow_1", "#FFFC17"},
{"yellow_green", "#52D017"}
};
const std::map<std::string, int> animations = {
{"kick", 1},
{"pierce", 2},
{"2hslash", 3},
{"2hblunt", 4},
{"2hpierce", 4},
{"throw", 5},
{"offhand", 6},
{"bash", 7},
{"mainhand", 8},
{"bow", 9},
{"swim", 10},
{"roundkick", 11},
{"gethit", 12},
{"gethit2", 13},
{"falling", 14},
{"drowning", 15},
{"death", 16},
{"standby", 17},
{"standby2", 18},
{"lunge", 19},
{"jump", 20},
{"falling2", 21},
{"duckwalk", 22},
{"ladderclimb", 23},
{"crouch", 24},
{"swim2", 25},
{"idle", 26},
{"cheer", 27},
{"disgusted", 28},
{"wave", 29},
{"rude", 30},
{"yawn", 31},
{"movetoside", 33},
{"iceslide", 35},
{"kneel", 36},
{"swim3", 37},
{"sit", 38},
{"cast", 42},
{"cast2", 43},
{"cast3", 44},
{"flykick", 45},
{"tigerclaw", 46},
{"eaglestrike", 47},
{"nodyes", 48},
{"shakeno", 49},
{"plead", 50},
{"clap", 51},
{"blush", 52},
{"chuckle", 54},
{"headtilt", 57},
{"dance", 58},
{"disagree", 59},
{"glare", 60},
{"peer", 61},
{"kneel", 62},
{"laugh", 63},
{"point", 64},
{"shrug", 65},
{"handraise", 66},
{"salute", 67},
{"shiver", 68},
{"tapfoot", 69},
{"bowto", 70},
};
class DialogueWindow {
public:
static void Render(Client *c, std::string markdown);
};
#endif //EQEMU_DIALOGUE_WINDOW_H

View File

@ -15,6 +15,7 @@
#include "lua_group.h"
#include "lua_raid.h"
#include "lua_packet.h"
#include "dialogue_window.h"
#include "../common/expedition_lockout_timer.h"
struct InventoryWhere { };
@ -1824,6 +1825,11 @@ int Lua_Client::GetClientMaxLevel() {
return self->GetClientMaxLevel();
}
void Lua_Client::DialogueWindow(std::string markdown) {
Lua_Safe_Call_Void();
DialogueWindow::Render(self, std::move(markdown));
}
DynamicZoneLocation GetDynamicZoneLocationFromTable(const luabind::object& lua_table)
{
DynamicZoneLocation zone_location;
@ -2496,6 +2502,9 @@ luabind::scope lua_register_client() {
.def("GetAlternateCurrencyValue", (int(Lua_Client::*)(uint32))&Lua_Client::GetAlternateCurrencyValue)
.def("SendWebLink", (void(Lua_Client::*)(const char *))&Lua_Client::SendWebLink)
.def("HasSpellScribed", (bool(Lua_Client::*)(int))&Lua_Client::HasSpellScribed)
.def("DiaWind", (void(Lua_Client::*)(std::string))&Lua_Client::DialogueWindow)
.def("DialogueWindow", (void(Lua_Client::*)(std::string))&Lua_Client::DialogueWindow)
.def("SetAccountFlag", (void(Lua_Client::*)(std::string,std::string))&Lua_Client::SetAccountFlag)
.def("SetAccountFlag", (void(Lua_Client::*)(std::string,std::string))&Lua_Client::SetAccountFlag)
.def("GetAccountFlag", (std::string(Lua_Client::*)(std::string))&Lua_Client::GetAccountFlag)
.def("GetGroup", (Lua_Group(Lua_Client::*)(void))&Lua_Client::GetGroup)

View File

@ -379,6 +379,8 @@ public:
void SetClientMaxLevel(int value);
int GetClientMaxLevel();
void DialogueWindow(std::string markdown);
Lua_Expedition CreateExpedition(luabind::object expedition_info);
Lua_Expedition CreateExpedition(std::string zone_name, uint32 version, uint32 duration, std::string expedition_name, uint32 min_players, uint32 max_players);
Lua_Expedition CreateExpedition(std::string zone_name, uint32 version, uint32 duration, std::string expedition_name, uint32 min_players, uint32 max_players, bool disable_messages);

View File

@ -39,6 +39,7 @@
#include "client.h"
#include "expedition.h"
#include "titles.h"
#include "dialogue_window.h"
#ifdef THIS /* this macro seems to leak out on some systems */
#undef THIS
@ -2111,11 +2112,11 @@ XS(XS_Client_IsStanding)
XSRETURN(1);
}
XS(XS_Client_Sit);
XS(XS_Client_Sit);
XS(XS_Client_Sit) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Client::Sit(THIS)");
Perl_croak(aTHX_ "Usage: Client::Sit(THIS)");
{
Client *THIS;
VALIDATE_THIS_IS_CLIENT;
@ -5052,7 +5053,7 @@ XS(XS_Client_Fling) {
VALIDATE_THIS_IS_CLIENT;
if (items > 5)
ignore_los = (bool) SvTRUE(ST(5));
if (items > 6)
clipping = (bool) SvTRUE(ST(6));
@ -5124,7 +5125,7 @@ XS(XS_Client_GetLearnableDisciplines) {
min_level = (uint8)SvUV(ST(1));
if (items > 2)
max_level = (uint8)SvUV(ST(2));
Client* THIS;
VALIDATE_THIS_IS_CLIENT;
auto learnable_disciplines = THIS->GetLearnableDisciplines(min_level, max_level);
@ -5146,7 +5147,7 @@ XS(XS_Client_GetLearnedDisciplines) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Client::GetLearnedDisciplines(THIS)");
Client* THIS;
VALIDATE_THIS_IS_CLIENT;
auto learned_disciplines = THIS->GetLearnedDisciplines();
@ -5168,7 +5169,7 @@ XS(XS_Client_GetMemmedSpells) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Client::GetMemmedSpells(THIS)");
Client* THIS;
VALIDATE_THIS_IS_CLIENT;
auto memmed_spells = THIS->GetMemmedSpells();
@ -5190,7 +5191,7 @@ XS(XS_Client_GetScribeableSpells) {
dXSARGS;
if (items < 1 || items > 3)
Perl_croak(aTHX_ "Usage: Client::GetScribeableSpells(THIS, [uint8 min_level, uint8 max_level])");
uint8 min_level = 1;
uint8 max_level = 0;
if (items > 1)
@ -5219,7 +5220,7 @@ XS(XS_Client_GetScribedSpells) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Client::GetScribedSpells(THIS)");
Client* THIS;
VALIDATE_THIS_IS_CLIENT;
auto scribed_spells = THIS->GetScribedSpells();
@ -5262,7 +5263,7 @@ XS(XS_Client_GetAAEXPModifier) {
double aa_modifier = 1.0f;
uint32 zone_id = (uint32)SvUV(ST(1));
dXSTARG;
VALIDATE_THIS_IS_CLIENT;
VALIDATE_THIS_IS_CLIENT;
aa_modifier = THIS->GetAAEXPModifier(zone_id);
XSprePUSH;
PUSHn((double) aa_modifier);
@ -5432,6 +5433,39 @@ XS(XS_Client_RemoveItem) {
XSRETURN_EMPTY;
}
XS(XS_Client_DialogueWindow); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_DialogueWindow) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::DialogueWindow(THIS, string window_markdown)"); // @categories Script Utility
{
Client *THIS;
dXSTARG;
VALIDATE_THIS_IS_CLIENT;
std::string window_markdown(SvPV_nolen(ST(1)));
DialogueWindow::Render(THIS, window_markdown);
}
XSRETURN_EMPTY;
}
XS(XS_Client_DiaWind); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_DiaWind) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::DiaWind(THIS, string window_markdown)"); // @categories Script Utility
{
Client *THIS;
dXSTARG;
VALIDATE_THIS_IS_CLIENT;
std::string window_markdown(SvPV_nolen(ST(1)));
DialogueWindow::Render(THIS, window_markdown);
}
XSRETURN_EMPTY;
}
#ifdef __cplusplus
extern "C"
#endif
@ -5486,6 +5520,8 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "DecreaseByID"), XS_Client_DecreaseByID, file, "$$$");
newXSproto(strcpy(buf, "DeleteItemInInventory"), XS_Client_DeleteItemInInventory, file, "$$;$$");
newXSproto(strcpy(buf, "Disconnect"), XS_Client_Disconnect, file, "$");
newXSproto(strcpy(buf, "DiaWind"), XS_Client_DiaWind, file, "$$");
newXSproto(strcpy(buf, "DialogueWindow"), XS_Client_DialogueWindow, file, "$$");
newXSproto(strcpy(buf, "DropItem"), XS_Client_DropItem, file, "$$");
newXSproto(strcpy(buf, "Duck"), XS_Client_Duck, file, "$");
newXSproto(strcpy(buf, "DyeArmorBySlot"), XS_Client_DyeArmorBySlot, file, "$$$$$;$");

View File

@ -36,6 +36,7 @@
#include "zone.h"
#include "zonedb.h"
#include "zone_store.h"
#include "dialogue_window.h"
#include <iostream>
#include <limits.h>
@ -1118,17 +1119,17 @@ uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
int spells_learned = 0;
if (spell_count > 0) {
for (auto spell_id : spell_ids) {
if (book_slot == -1) {
if (book_slot == -1) {
initiator->Message(
Chat::Red,
"Unable to scribe spell %s (%i) to Spell Book: Spell Book is Full.", spells[spell_id].name, spell_id
);
break;
}
if (initiator->HasSpellScribed(spell_id))
continue;
initiator->ScribeSpell(spell_id, book_slot);
book_slot = initiator->GetNextAvailableSpellBookSlot(book_slot);
spells_learned++;
@ -2506,7 +2507,7 @@ void QuestManager::message(int color, const char *message) {
QuestManagerCurrentQuestVars();
if (!initiator)
return;
initiator->Message(color, message);
}
@ -4277,319 +4278,8 @@ std::string QuestManager::secondstotime(int duration) {
}
std::string QuestManager::gethexcolorcode(std::string color_name) {
static const std::map<std::string, std::string> colors = {
{ "Black", "#000000" },
{ "Brown", "#804000" },
{ "Burgundy", "#800000" },
{ "Cadet Blue", "#77BFC7" },
{ "Cadet Blue1", "#4C787E" },
{ "Chartreuse", "#8AFB17" },
{ "Chartreuse1", "#7FE817" },
{ "Chartreuse2", "#6CC417" },
{ "Chartreuse3", "#437C17" },
{ "Chocolate", "#C85A17" },
{ "Coral", "#F76541" },
{ "Coral1", "#E55B3C" },
{ "Coral2", "#C34A2C" },
{ "Cornflower Blue", "#151B8D" },
{ "Cyan", "#00FFFF" },
{ "Cyan1", "#57FEFF" },
{ "Cyan2", "#50EBEC" },
{ "Cyan3", "#46C7C7" },
{ "Cyan4", "#307D7E" },
{ "Dark Blue", "#0000A0" },
{ "Dark Goldenrod", "#AF7817" },
{ "Dark Goldenrod1", "#FBB117" },
{ "Dark Goldenrod2", "#E8A317" },
{ "Dark Goldenrod3", "#C58917" },
{ "Dark Goldenrod4", "#7F5217" },
{ "Dark Green", "#254117" },
{ "Dark Grey", "#808080" },
{ "Dark Olive Green", "#CCFB5D" },
{ "Dark Olive Green2", "#BCE954" },
{ "Dark Olive Green3", "#A0C544" },
{ "Dark Olive Green4", "#667C26" },
{ "Dark Orange", "#F88017" },
{ "Dark Orange1", "#F87217" },
{ "Dark Orange2", "#E56717" },
{ "Dark Orange3", "#7E3117" },
{ "Dark Orange3", "#C35617" },
{ "Dark Orchid", "#7D1B7E" },
{ "Dark Orchid1", "#B041FF" },
{ "Dark Orchid2", "#A23BEC" },
{ "Dark Orchid3", "#8B31C7" },
{ "Dark Orchid4", "#571B7e" },
{ "Dark Purple", "#800080" },
{ "Dark Salmon", "#E18B6B" },
{ "Dark Sea Green", "#8BB381" },
{ "Dark Sea Green1", "#C3FDB8" },
{ "Dark Sea Green2", "#B5EAAA" },
{ "Dark Sea Green3", "#99C68E" },
{ "Dark Sea Green4", "#617C58" },
{ "Dark Slate Blue", "#2B3856" },
{ "Dark Slate Gray", "#25383C" },
{ "Dark Slate Gray1", "#9AFEFF" },
{ "Dark Slate Gray2", "#8EEBEC" },
{ "Dark Slate Gray3", "#78c7c7" },
{ "Dark Slate Gray4", "#4C7D7E" },
{ "Dark Turquoise", "#3B9C9C" },
{ "Dark Violet", "#842DCE" },
{ "Deep Pink", "#F52887" },
{ "Deep Pink1", "#E4287C" },
{ "Deep Pink2", "#C12267" },
{ "Deep Pink3", "#7D053F" },
{ "Deep Sky Blue", "#3BB9FF" },
{ "Deep Sky Blue1", "#38ACEC" },
{ "Deep Sky Blue2", "#3090C7" },
{ "Deep Sky Blue3", "#25587E" },
{ "Dim Gray", "#463E41" },
{ "Dodger Blue", "#1589FF" },
{ "Dodger Blue1", "#157DEC" },
{ "Dodger Blue2", "#1569C7" },
{ "Dodger Blue3", "#153E7E" },
{ "Firebrick", "#800517" },
{ "Firebrick1", "#F62817" },
{ "Firebrick2", "#E42217" },
{ "Firebrick3", "#C11B17" },
{ "Forest Green", "#4E9258" },
{ "Forest Green1", "#808000" },
{ "Gold", "#D4A017" },
{ "Gold1", "#FDD017" },
{ "Gold2", "#EAC117" },
{ "Gold3", "#C7A317" },
{ "Gold4", "#806517" },
{ "Goldenrod", "#EDDA74" },
{ "Goldenrod1", "#FBB917" },
{ "Goldenrod2", "#E9AB17" },
{ "Goldenrod3", "#C68E17" },
{ "Goldenrod4", "#805817" },
{ "Grass Green", "#408080" },
{ "Gray", "#736F6E" },
{ "Gray1", "#150517" },
{ "Gray2", "#250517" },
{ "Gray3", "#2B1B17" },
{ "Gray4", "#302217" },
{ "Gray5", "#302226" },
{ "Gray6", "#342826" },
{ "Gray7", "#34282C" },
{ "Gray8", "#382D2C" },
{ "Gray9", "#3b3131" },
{ "Gray10", "#3E3535" },
{ "Gray11", "#413839" },
{ "Gray12", "#41383C" },
{ "Gray13", "#463E3F" },
{ "Gray14", "#4A4344" },
{ "Gray15", "#4C4646" },
{ "Gray16", "#4E4848" },
{ "Gray17", "#504A4B" },
{ "Gray18", "#544E4F" },
{ "Gray19", "#565051" },
{ "Gray19", "#595454" },
{ "Gray20", "#5C5858" },
{ "Gray21", "#5F5A59" },
{ "Gray22", "#625D5D" },
{ "Gray23", "#646060" },
{ "Gray24", "#666362" },
{ "Gray25", "#696565" },
{ "Gray26", "#6D6968" },
{ "Gray27", "#6E6A6B" },
{ "Gray28", "#726E6D" },
{ "Gray29", "#747170" },
{ "Green", "#00FF00" },
{ "Green1", "#5FFB17" },
{ "Green2", "#59E817" },
{ "Green3", "#4CC417" },
{ "Green4", "#347C17" },
{ "Green Yellow", "#B1FB17" },
{ "Hot Pink", "#F660AB" },
{ "Hot Pink1", "#F665AB" },
{ "Hot Pink2", "#E45E9D" },
{ "Hot Pink3", "#C25283" },
{ "Hot Pink4", "#7D2252" },
{ "Indian Red", "#F75D59" },
{ "Indian Red2", "#E55451" },
{ "Indian Red3", "#C24641" },
{ "Indian Red4", "#7E2217" },
{ "Khaki", "#ADA96E" },
{ "Khaki1", "#FFF380" },
{ "Khaki2", "#EDE275" },
{ "Khaki3", "#C9BE62" },
{ "Khaki4", "#827839" },
{ "Lavender", "#E3E4FA" },
{ "Lavender Blush", "#FDEEF4" },
{ "Lavender Blush1", "#EBDDE2" },
{ "Lavender Blush2", "#C8BBBE" },
{ "Lavender Blush3", "#817679" },
{ "Lawn Green", "#87F717" },
{ "Lemon Chiffon", "#FFF8C6" },
{ "Lemon Chiffon1", "#ECE5B6" },
{ "Lemon Chiffon2", "#C9C299" },
{ "Lemon Chiffon3", "#827B60" },
{ "Light Blue", "#0000FF" },
{ "Light Blue1", "#ADDFFF" },
{ "Light Blue2", "#BDEDFF" },
{ "Light Blue3", "#AFDCEC" },
{ "Light Blue4", "#95B9C7" },
{ "Light Blue5", "#5E767E" },
{ "Light Coral", "#E77471" },
{ "Light Cyan", "#E0FFFF" },
{ "Light Cyan1", "#CFECEC" },
{ "Light Cyan2", "#AFC7C7" },
{ "Light Cyan3", "#717D7D" },
{ "Light Golden", "#ECD672" },
{ "Light Goldenrod", "#ECD872" },
{ "Light Goldenrod1", "#FFE87C" },
{ "Light Goldenrod2", "#C8B560" },
{ "Light Goldenrod3", "#817339" },
{ "Light Goldenrod Yellow", "#FAF8CC" },
{ "Light Grey", "#C0C0C0" },
{ "Light Pink", "#FAAFBA" },
{ "Light Pink1", "#F9A7B0" },
{ "Light Pink2", "#E799A3" },
{ "Light Pink3", "#C48189" },
{ "Light Pink4", "#7F4E52" },
{ "Light Purple", "#FF0080" },
{ "Light Salmon", "#F9966B" },
{ "Light Salmon1", "#E78A61" },
{ "Light Salmon2", "#C47451" },
{ "Light Salmon3", "#7F462C" },
{ "Light Sea Green", "#3EA99F" },
{ "Light Sky Blue", "#82CAFA" },
{ "Light Sky Blue1", "#A0CFEC" },
{ "Light Sky Blue2", "#87AFC7" },
{ "Light Sky Blue3", "#566D7E" },
{ "Light Slate Blue", "#736AFF" },
{ "Light Slate Gray", "#6D7B8D" },
{ "Light Steel Blue", "#728FCE" },
{ "Light Steel Blue1", "#C6DEFF" },
{ "Light Steel Blue2", "#B7CEEC" },
{ "Light Steel Blue3", "#646D7E" },
{ "Lime Green", "#41A317" },
{ "Magenta", "#FF00FF" },
{ "Magenta1", "#F433FF" },
{ "Magenta2", "#E238EC" },
{ "Magenta3", "#C031C7" },
{ "Maroon", "#810541" },
{ "Maroon1", "#F535AA" },
{ "Maroon2", "#E3319D" },
{ "Maroon3", "#C12283" },
{ "Maroon4", "#7D0552" },
{ "Medium Aquamarine", "#348781" },
{ "Medium Forest Green", "#347235" },
{ "Medium Orchid", "#B048B5" },
{ "Medium Orchid1", "#D462FF" },
{ "Medium Orchid2", "#C45AEC" },
{ "Medium Orchid3", "#A74AC7" },
{ "Medium Orchid4", "#6A287E" },
{ "Medium Purple", "#8467D7" },
{ "Medium Purple1", "#9E7BFF" },
{ "Medium Purple2", "#9172EC" },
{ "Medium Purple3", "#7A5DC7" },
{ "Medium Purple4", "#4E387E" },
{ "Medium Sea Green", "#306754" },
{ "Medium Slate Blue", "#5E5A80" },
{ "Medium Spring Green", "#348017" },
{ "Medium Turquoise", "#48CCCD" },
{ "Medium Violet Red", "#CA226B" },
{ "Midnight Blue", "#151B54" },
{ "Orange", "#FF8040" },
{ "Pale Turquoise", "#92C7C7" },
{ "Pale Turquoise1", "#5E7D7E" },
{ "Pale Violet Red", "#D16587" },
{ "Pale Violet Red1", "#F778A1" },
{ "Pale Violet Red2", "#E56E94" },
{ "Pale Violet Red3", "#C25A7C" },
{ "Pale Violet Red4", "#7E354D" },
{ "Pastel Green", "#00FF00" },
{ "Pink", "#FAAFBE" },
{ "Pink1", "#FF00FF" },
{ "Pink2", "#E7A1B0" },
{ "Pink3", "#C48793" },
{ "Pink4", "#7F525D" },
{ "Plum", "#B93B8F" },
{ "Plum1", "#F9B7FF" },
{ "Plum2", "#E6A9EC" },
{ "Plum3", "#C38EC7" },
{ "Plum4", "#7E587E" },
{ "Purple", "#8E35EF" },
{ "Purple1", "#893BFF" },
{ "Purple2", "#7F38EC" },
{ "Purple3", "#6C2DC7" },
{ "Purple4", "#461B7E" },
{ "Red", "#FF0000" },
{ "Red1", "#F62217" },
{ "Red2", "#E41B17" },
{ "Rosy Brown", "#B38481" },
{ "Rosy Brown1", "#FBBBB9" },
{ "Rosy Brown2", "#E8ADAA" },
{ "Rosy Brown3", "#C5908E" },
{ "Rosy Brown4", "#7F5A58" },
{ "Royal Blue", "#2B60DE" },
{ "Royal Blue1", "#306EFF" },
{ "Royal Blue2", "#2B65EC" },
{ "Royal Blue3", "#2554C7" },
{ "Royal Blue4", "#15317E" },
{ "Salmon1", "#F88158" },
{ "Salmon2", "#E67451" },
{ "Salmon3", "#C36241" },
{ "Salmon4", "#7E3817" },
{ "Sandy Brown", "#EE9A4D" },
{ "Sea Green", "#4E8975" },
{ "Sea Green1", "#6AFB92" },
{ "Sea Green2", "#64E986" },
{ "Sea Green3", "#54C571" },
{ "Sea Green4", "#387C44" },
{ "Sienna", "#8A4117" },
{ "Sienna1", "#F87431" },
{ "Sienna2", "#E66C2C" },
{ "Sienna3", "#C35817" },
{ "Sienna4", "#7E3517" },
{ "Sky Blue", "#82CAFF" },
{ "Sky Blue1", "#6698FF" },
{ "Sky Blue2", "#79BAEC" },
{ "Sky Blue3", "#659EC7" },
{ "Sky Blue4", "#41627E" },
{ "Slate Blue", "#357EC7" },
{ "Slate Blue1", "#737CA1" },
{ "Slate Blue2", "#6960EC" },
{ "Slate Blue3", "#342D7E" },
{ "Slate Gray", "#657383" },
{ "Slate Gray1", "#C2DFFF" },
{ "Slate Gray2", "#B4CFEC" },
{ "Slate Gray3", "#98AFC7" },
{ "Slate Gray4", "#616D7E" },
{ "Spring Green", "#4AA02C" },
{ "Spring Green1", "#5EFB6E" },
{ "Spring Green2", "#57E964" },
{ "Spring Green3", "#4CC552" },
{ "Spring Green4", "#347C2C" },
{ "Steel Blue", "#4863A0" },
{ "Steel Blue1", "#5CB3FF" },
{ "Steel Blue2", "#56A5EC" },
{ "Steel Blue3", "#488AC7" },
{ "Steel Blue4", "#2B547E" },
{ "Thistle", "#D2B9D3" },
{ "Thistle1", "#FCDFFF" },
{ "Thistle2", "#E9CFEC" },
{ "Thistle3", "#C6AEC7" },
{ "Thistle4", "#806D7E" },
{ "Turquoise", "#00FFFF" },
{ "Turquoise1", "#43C6DB" },
{ "Turquoise2", "#52F3FF" },
{ "Turquoise3", "#4EE2EC" },
{ "Turquoise4", "#43BFC7" },
{ "Violet", "#8D38C9" },
{ "Violet Red", "#F6358A" },
{ "Violet Red1", "#F6358A" },
{ "Violet Red2", "#E4317F" },
{ "Violet Red3", "#C12869" },
{ "Violet Red4", "#7D0541" },
{ "White", "#FFFFFF" },
{ "Yellow", "#FFFF00" },
{ "Yellow1", "#FFFC17" },
{ "Yellow Green", "#52D017" }
};
for (auto color : colors) {
for (auto color : html_colors) {
if (!strcasecmp(color.first.c_str(), color_name.c_str())) {
return color.second;
}