mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-30 12:32:36 +00:00
42e45723b7
Fixes issue when fetching MyGui values that were stored as RefId but fetched as String Removed some uncessary copies, fixed issues with lowercase and uneeded changes
284 lines
12 KiB
C++
284 lines
12 KiB
C++
#include "defines.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <components/debug/debuglog.hpp>
|
|
#include <components/misc/strings/lower.hpp>
|
|
|
|
namespace Interpreter
|
|
{
|
|
|
|
bool check(const std::string& str, const std::string& escword, unsigned int* i, unsigned int* start)
|
|
{
|
|
bool retval = str.find(escword) == 0;
|
|
if (retval)
|
|
{
|
|
(*i) += escword.length();
|
|
(*start) = (*i) + 1;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
std::vector<std::string> globals;
|
|
|
|
bool longerStr(const std::string& a, const std::string& b)
|
|
{
|
|
return a.length() > b.length();
|
|
}
|
|
|
|
static std::string fixDefinesReal(const std::string& text, bool dialogue, Context& context)
|
|
{
|
|
unsigned int start = 0;
|
|
std::ostringstream retval;
|
|
for (unsigned int i = 0; i < text.length(); i++)
|
|
{
|
|
char eschar = text[i];
|
|
if (eschar == '%' || eschar == '^')
|
|
{
|
|
retval << text.substr(start, i - start);
|
|
std::string temp = Misc::StringUtils::lowerCase(std::string_view(text).substr(i + 1, 100));
|
|
|
|
bool found = false;
|
|
try
|
|
{
|
|
if ((found = check(temp, "actionslideright", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sRight}");
|
|
}
|
|
else if ((found = check(temp, "actionreadymagic", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sReady_Magic}");
|
|
}
|
|
else if ((found = check(temp, "actionprevweapon", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sPrevWeapon}");
|
|
}
|
|
else if ((found = check(temp, "actionnextweapon", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sNextWeapon}");
|
|
}
|
|
else if ((found = check(temp, "actiontogglerun", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sAuto_Run}");
|
|
}
|
|
else if ((found = check(temp, "actionslideleft", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sLeft}");
|
|
}
|
|
else if ((found = check(temp, "actionreadyitem", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sReady_Weapon}");
|
|
}
|
|
else if ((found = check(temp, "actionprevspell", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sPrevSpell}");
|
|
}
|
|
else if ((found = check(temp, "actionnextspell", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sNextSpell}");
|
|
}
|
|
else if ((found = check(temp, "actionrestmenu", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sRestKey}");
|
|
}
|
|
else if ((found = check(temp, "actionmenumode", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sInventory}");
|
|
}
|
|
else if ((found = check(temp, "actionactivate", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sActivate}");
|
|
}
|
|
else if ((found = check(temp, "actionjournal", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sJournal}");
|
|
}
|
|
else if ((found = check(temp, "actionforward", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sForward}");
|
|
}
|
|
else if ((found = check(temp, "pccrimelevel", &i, &start)))
|
|
{
|
|
retval << context.getPCBounty();
|
|
}
|
|
else if ((found = check(temp, "actioncrouch", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sCrouch_Sneak}");
|
|
}
|
|
else if ((found = check(temp, "actionjump", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sJump}");
|
|
}
|
|
else if ((found = check(temp, "actionback", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sBack}");
|
|
}
|
|
else if ((found = check(temp, "actionuse", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sUse}");
|
|
}
|
|
else if ((found = check(temp, "actionrun", &i, &start)))
|
|
{
|
|
retval << context.getActionBinding("#{sRun}");
|
|
}
|
|
else if ((found = check(temp, "pcclass", &i, &start)))
|
|
{
|
|
retval << context.getPCClass();
|
|
}
|
|
else if ((found = check(temp, "pcrace", &i, &start)))
|
|
{
|
|
retval << context.getPCRace();
|
|
}
|
|
else if ((found = check(temp, "pcname", &i, &start)))
|
|
{
|
|
retval << context.getPCName();
|
|
}
|
|
else if ((found = check(temp, "cell", &i, &start)))
|
|
{
|
|
retval << context.getCurrentCellName();
|
|
}
|
|
|
|
else if (dialogue)
|
|
{ // In Dialogue, not messagebox
|
|
if ((found = check(temp, "faction", &i, &start)))
|
|
{
|
|
retval << context.getNPCFaction();
|
|
}
|
|
else if ((found = check(temp, "nextpcrank", &i, &start)))
|
|
{
|
|
retval << context.getPCNextRank();
|
|
}
|
|
else if ((found = check(temp, "pcnextrank", &i, &start)))
|
|
{
|
|
retval << context.getPCNextRank();
|
|
}
|
|
else if ((found = check(temp, "pcrank", &i, &start)))
|
|
{
|
|
retval << context.getPCRank();
|
|
}
|
|
else if ((found = check(temp, "rank", &i, &start)))
|
|
{
|
|
retval << context.getNPCRank();
|
|
}
|
|
|
|
else if ((found = check(temp, "class", &i, &start)))
|
|
{
|
|
retval << context.getNPCClass();
|
|
}
|
|
else if ((found = check(temp, "race", &i, &start)))
|
|
{
|
|
retval << context.getNPCRace();
|
|
}
|
|
else if ((found = check(temp, "name", &i, &start)))
|
|
{
|
|
retval << context.getActorName();
|
|
}
|
|
}
|
|
else
|
|
{ // In messagebox or book, not dialogue
|
|
|
|
/* empty outside dialogue */
|
|
if ((found = check(temp, "faction", &i, &start)))
|
|
;
|
|
else if ((found = check(temp, "nextpcrank", &i, &start)))
|
|
;
|
|
else if ((found = check(temp, "pcnextrank", &i, &start)))
|
|
;
|
|
else if ((found = check(temp, "pcrank", &i, &start)))
|
|
;
|
|
else if ((found = check(temp, "rank", &i, &start)))
|
|
;
|
|
|
|
/* uses pc in messageboxes */
|
|
else if ((found = check(temp, "class", &i, &start)))
|
|
{
|
|
retval << context.getPCClass();
|
|
}
|
|
else if ((found = check(temp, "race", &i, &start)))
|
|
{
|
|
retval << context.getPCRace();
|
|
}
|
|
else if ((found = check(temp, "name", &i, &start)))
|
|
{
|
|
retval << context.getPCName();
|
|
}
|
|
}
|
|
|
|
/* 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);
|
|
}
|
|
|
|
for (unsigned int j = 0; j < globals.size(); j++)
|
|
{
|
|
if (globals[j].length() > temp.length()) // Just in case there's a global with a huuuge name
|
|
temp = Misc::StringUtils::lowerCase(
|
|
std::string_view(text).substr(i + 1, globals[j].length()));
|
|
|
|
found = check(temp, globals[j], &i, &start);
|
|
if (found)
|
|
{
|
|
char type = context.getGlobalType(globals[j]);
|
|
|
|
switch (type)
|
|
{
|
|
case 's':
|
|
retval << context.getGlobalShort(globals[j]);
|
|
break;
|
|
case 'l':
|
|
retval << context.getGlobalLong(globals[j]);
|
|
break;
|
|
case 'f':
|
|
retval << context.getGlobalFloat(globals[j]);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (std::exception& e)
|
|
{
|
|
Log(Debug::Error) << "Error: Failed to replace escape character, with the following error: "
|
|
<< e.what();
|
|
Log(Debug::Error) << "Full text below:\n" << text;
|
|
}
|
|
|
|
// Not found, or error
|
|
if (!found)
|
|
{
|
|
/* leave unmodified */
|
|
i += 1;
|
|
start = i;
|
|
retval << eschar;
|
|
}
|
|
}
|
|
}
|
|
retval << text.substr(start, text.length() - start);
|
|
return retval.str();
|
|
}
|
|
|
|
std::string fixDefinesDialog(const std::string& text, Context& context)
|
|
{
|
|
return fixDefinesReal(text, true, context);
|
|
}
|
|
|
|
std::string fixDefinesMsgBox(const std::string& text, Context& context)
|
|
{
|
|
return fixDefinesReal(text, false, context);
|
|
}
|
|
|
|
std::string fixDefinesBook(const std::string& text, Context& context)
|
|
{
|
|
return fixDefinesReal(text, false, context);
|
|
}
|
|
}
|