2012-12-20 23:16:34 +00:00
|
|
|
#include "defines.hpp"
|
|
|
|
|
2022-08-03 00:00:54 +02:00
|
|
|
#include <algorithm>
|
2013-01-01 11:59:05 -08:00
|
|
|
#include <sstream>
|
2012-12-20 23:16:34 +00:00
|
|
|
#include <string>
|
2023-02-01 17:49:11 +01:00
|
|
|
#include <string_view>
|
2012-12-20 23:16:34 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2018-08-14 19:42:41 +04:00
|
|
|
#include <components/debug/debuglog.hpp>
|
2023-02-01 17:49:11 +01:00
|
|
|
#include <components/misc/strings/algorithm.hpp>
|
2015-12-07 21:58:30 +01:00
|
|
|
|
2012-12-20 23:16:34 +00:00
|
|
|
namespace Interpreter
|
|
|
|
{
|
|
|
|
|
2023-02-01 17:49:11 +01:00
|
|
|
bool check(std::string_view str, std::string_view escword, size_t& i, size_t& start)
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2023-02-01 17:49:11 +01:00
|
|
|
bool found = Misc::StringUtils::ciStartsWith(str, escword);
|
|
|
|
if (found)
|
2012-12-20 23:16:34 +00:00
|
|
|
{
|
2023-02-01 17:49:11 +01:00
|
|
|
i += escword.length();
|
|
|
|
start = i + 1;
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
return found;
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> globals;
|
|
|
|
|
2023-02-01 17:49:11 +01:00
|
|
|
bool longerStr(std::string_view a, std::string_view b)
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2012-12-20 23:16:34 +00:00
|
|
|
return a.length() > b.length();
|
|
|
|
}
|
|
|
|
|
2023-02-01 17:49:11 +01:00
|
|
|
static std::string fixDefinesReal(std::string_view text, bool dialogue, Context& context)
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2023-02-01 17:49:11 +01:00
|
|
|
size_t start = 0;
|
2013-01-01 11:59:05 -08:00
|
|
|
std::ostringstream retval;
|
2023-02-01 17:49:11 +01:00
|
|
|
for (size_t i = 0; i < text.length(); ++i)
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2016-02-16 14:55:13 +01:00
|
|
|
char eschar = text[i];
|
|
|
|
if (eschar == '%' || eschar == '^')
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2013-01-01 11:59:05 -08:00
|
|
|
retval << text.substr(start, i - start);
|
2023-02-01 17:49:11 +01:00
|
|
|
std::string_view temp = text.substr(i + 1, 100);
|
2022-08-02 23:57:09 +02:00
|
|
|
|
2014-10-28 16:07:37 +01:00
|
|
|
bool found = false;
|
|
|
|
try
|
|
|
|
{
|
2023-02-01 17:49:11 +01:00
|
|
|
if ((found = check(temp, "actionslideright", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sRight}");
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionreadymagic", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sReady_Magic}");
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionprevweapon", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2014-12-20 00:06:14 +01:00
|
|
|
retval << context.getActionBinding("#{sPrevWeapon}");
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionnextweapon", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2014-12-20 00:06:14 +01:00
|
|
|
retval << context.getActionBinding("#{sNextWeapon}");
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actiontogglerun", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sAuto_Run}");
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionslideleft", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sLeft}");
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionreadyitem", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sReady_Weapon}");
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionprevspell", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2014-12-20 00:06:14 +01:00
|
|
|
retval << context.getActionBinding("#{sPrevSpell}");
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionnextspell", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2014-12-20 00:06:14 +01:00
|
|
|
retval << context.getActionBinding("#{sNextSpell}");
|
2014-10-28 16:07:37 +01:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionrestmenu", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sRestKey}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionmenumode", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sInventory}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionactivate", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sActivate}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionjournal", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sJournal}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionforward", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sForward}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "pccrimelevel", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getPCBounty();
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actioncrouch", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sCrouch_Sneak}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionjump", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sJump}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionback", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sBack}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionuse", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sUse}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "actionrun", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getActionBinding("#{sRun}");
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "pcclass", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2013-01-01 11:59:05 -08:00
|
|
|
retval << context.getPCClass();
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "pcrace", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2013-01-01 11:59:05 -08:00
|
|
|
retval << context.getPCRace();
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "pcname", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2013-01-01 11:59:05 -08:00
|
|
|
retval << context.getPCName();
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "cell", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getCurrentCellName();
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
|
|
|
|
2016-02-18 01:25:52 +01:00
|
|
|
else if (dialogue)
|
|
|
|
{ // In Dialogue, not messagebox
|
2023-02-01 17:49:11 +01:00
|
|
|
if ((found = check(temp, "faction", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getNPCFaction();
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "nextpcrank", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getPCNextRank();
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "pcnextrank", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getPCNextRank();
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "pcrank", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getPCRank();
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "rank", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getNPCRank();
|
2012-12-26 18:07:56 +00:00
|
|
|
}
|
|
|
|
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "class", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getNPCClass();
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "race", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getNPCRace();
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "name", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
2018-09-16 20:47:51 +04:00
|
|
|
retval << context.getActorName();
|
2014-10-28 16:07:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // In messagebox or book, not dialogue
|
|
|
|
|
|
|
|
/* empty outside dialogue */
|
2023-02-01 17:49:11 +01:00
|
|
|
if ((found = check(temp, "faction", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
;
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "nextpcrank", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
;
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "pcnextrank", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
;
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "pcrank", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
;
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "rank", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
/* uses pc in messageboxes */
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "class", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getPCClass();
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "race", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getPCRace();
|
|
|
|
}
|
2023-02-01 17:49:11 +01:00
|
|
|
else if ((found = check(temp, "name", i, start)))
|
2014-10-28 16:07:37 +01:00
|
|
|
{
|
|
|
|
retval << context.getPCName();
|
|
|
|
}
|
|
|
|
}
|
2012-12-20 23:16:34 +00:00
|
|
|
|
2014-10-28 16:07:37 +01:00
|
|
|
/* Not a builtin, try global variables */
|
|
|
|
if (!found)
|
|
|
|
{
|
|
|
|
/* if list of globals is empty, grab it and sort it by descending string length */
|
|
|
|
if (globals.empty())
|
|
|
|
{
|
|
|
|
globals = context.getGlobals();
|
|
|
|
sort(globals.begin(), globals.end(), longerStr);
|
|
|
|
}
|
|
|
|
|
2023-02-01 17:49:11 +01:00
|
|
|
for (const std::string& global : globals)
|
2022-08-02 23:57:09 +02:00
|
|
|
{
|
2023-02-01 17:49:11 +01:00
|
|
|
if (global.length() > temp.length()) // Just in case there's a global with a huuuge name
|
|
|
|
temp = text.substr(i + 1, global.length());
|
2014-10-28 16:07:37 +01:00
|
|
|
|
2023-02-01 17:49:11 +01:00
|
|
|
found = check(temp, global, i, start);
|
2021-04-21 09:31:44 +04:00
|
|
|
if (found)
|
|
|
|
{
|
2023-02-01 17:49:11 +01:00
|
|
|
char type = context.getGlobalType(global);
|
2014-10-28 16:07:37 +01:00
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case 's':
|
2023-02-01 17:49:11 +01:00
|
|
|
retval << context.getGlobalShort(global);
|
2014-10-28 16:07:37 +01:00
|
|
|
break;
|
|
|
|
case 'l':
|
2023-02-01 17:49:11 +01:00
|
|
|
retval << context.getGlobalLong(global);
|
2014-10-28 16:07:37 +01:00
|
|
|
break;
|
|
|
|
case 'f':
|
2023-02-01 17:49:11 +01:00
|
|
|
retval << context.getGlobalFloat(global);
|
2014-10-28 16:07:37 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-10-28 16:07:37 +01:00
|
|
|
catch (std::exception& e)
|
|
|
|
{
|
2018-08-14 19:42:41 +04:00
|
|
|
Log(Debug::Error) << "Error: Failed to replace escape character, with the following error: "
|
|
|
|
<< e.what();
|
|
|
|
Log(Debug::Error) << "Full text below:\n" << text;
|
2014-10-28 16:07:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Not found, or error
|
2012-12-20 23:16:34 +00:00
|
|
|
if (!found)
|
|
|
|
{
|
|
|
|
/* leave unmodified */
|
|
|
|
i += 1;
|
|
|
|
start = i;
|
2013-01-01 11:59:05 -08:00
|
|
|
retval << eschar;
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-01-01 11:59:05 -08:00
|
|
|
retval << text.substr(start, text.length() - start);
|
|
|
|
return retval.str();
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
|
|
|
|
2016-02-16 14:55:13 +01:00
|
|
|
std::string fixDefinesDialog(const std::string& text, Context& context)
|
|
|
|
{
|
|
|
|
return fixDefinesReal(text, true, context);
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
|
|
|
|
2016-02-16 14:55:13 +01:00
|
|
|
std::string fixDefinesMsgBox(const std::string& text, Context& context)
|
|
|
|
{
|
|
|
|
return fixDefinesReal(text, false, context);
|
2012-12-26 18:07:56 +00:00
|
|
|
}
|
|
|
|
|
2016-02-16 14:55:13 +01:00
|
|
|
std::string fixDefinesBook(const std::string& text, Context& context)
|
|
|
|
{
|
|
|
|
return fixDefinesReal(text, false, context);
|
2012-12-20 23:16:34 +00:00
|
|
|
}
|
|
|
|
}
|