1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-22 12:39:59 +00:00

Merge branch 'morrowland_scripting' into 'master'

Morrowland scripting

Closes #6363

See merge request OpenMW/openmw!1318
This commit is contained in:
psi29a 2021-10-26 10:07:45 +00:00
commit 3006c496fc
10 changed files with 43 additions and 7 deletions

View File

@ -59,6 +59,7 @@
Bug #6323: Wyrmhaven: Alboin doesn't follower the player character out of his house Bug #6323: Wyrmhaven: Alboin doesn't follower the player character out of his house
Bug #6326: Detect Enchantment/Key should detect items in unresolved containers Bug #6326: Detect Enchantment/Key should detect items in unresolved containers
Bug #6347: PlaceItem/PlaceItemCell/PlaceAt should work with levelled creatures Bug #6347: PlaceItem/PlaceItemCell/PlaceAt should work with levelled creatures
Bug #6363: Some scripts in Morrowland fail to work
Feature #890: OpenMW-CS: Column filtering Feature #890: OpenMW-CS: Column filtering
Feature #2554: Modifying an object triggers the instances table to scroll to the corresponding record Feature #2554: Modifying an object triggers the instances table to scroll to the corresponding record
Feature #2780: A way to see current OpenMW version in the console Feature #2780: A way to see current OpenMW version in the console

View File

@ -90,6 +90,16 @@ bool Compiler::DeclarationParser::parseSpecial (int code, const TokenLoc& loc, S
return Parser::parseSpecial (code, loc, scanner); return Parser::parseSpecial (code, loc, scanner);
} }
bool Compiler::DeclarationParser::parseInt(int value, const TokenLoc& loc, Scanner& scanner)
{
if(mState == State_Name)
{
// Allow integers to be used as variable names
return parseName(loc.mLiteral, loc, scanner);
}
return Parser::parseInt(value, loc, scanner);
}
void Compiler::DeclarationParser::reset() void Compiler::DeclarationParser::reset()
{ {
mState = State_Begin; mState = State_Begin;

View File

@ -35,6 +35,10 @@ namespace Compiler
///< Handle a special character token. ///< Handle a special character token.
/// \return fetch another token? /// \return fetch another token?
bool parseInt (int value, const TokenLoc& loc, Scanner& scanner) override;
///< Handle an int token.
/// \return fetch another token?
void reset() override; void reset() override;
}; };

View File

@ -632,7 +632,7 @@ namespace Compiler
} }
int ExprParser::parseArguments (const std::string& arguments, Scanner& scanner, int ExprParser::parseArguments (const std::string& arguments, Scanner& scanner,
std::vector<Interpreter::Type_Code>& code, int ignoreKeyword) std::vector<Interpreter::Type_Code>& code, int ignoreKeyword, bool expectNames)
{ {
bool optional = false; bool optional = false;
int optionalCount = 0; int optionalCount = 0;
@ -717,6 +717,8 @@ namespace Compiler
if (optional) if (optional)
parser.setOptional (true); parser.setOptional (true);
if(expectNames)
scanner.enableExpectName();
scanner.scan (parser); scanner.scan (parser);

View File

@ -96,7 +96,7 @@ namespace Compiler
/// \return Type ('l': integer, 'f': float) /// \return Type ('l': integer, 'f': float)
int parseArguments (const std::string& arguments, Scanner& scanner, int parseArguments (const std::string& arguments, Scanner& scanner,
std::vector<Interpreter::Type_Code>& code, int ignoreKeyword = -1); std::vector<Interpreter::Type_Code>& code, int ignoreKeyword = -1, bool expectNames = false);
///< Parse sequence of arguments specified by \a arguments. ///< Parse sequence of arguments specified by \a arguments.
/// \param arguments Uses ScriptArgs typedef /// \param arguments Uses ScriptArgs typedef
/// \see Compiler::ScriptArgs /// \see Compiler::ScriptArgs

View File

@ -553,7 +553,7 @@ namespace Compiler
extensions.registerFunction("getpos",'f',"c",opcodeGetPos,opcodeGetPosExplicit); extensions.registerFunction("getpos",'f',"c",opcodeGetPos,opcodeGetPosExplicit);
extensions.registerFunction("getstartingpos",'f',"c",opcodeGetStartingPos,opcodeGetStartingPosExplicit); extensions.registerFunction("getstartingpos",'f',"c",opcodeGetStartingPos,opcodeGetStartingPosExplicit);
extensions.registerInstruction("position","ffffz",opcodePosition,opcodePositionExplicit); extensions.registerInstruction("position","ffffz",opcodePosition,opcodePositionExplicit);
extensions.registerInstruction("positioncell","ffffcX",opcodePositionCell,opcodePositionCellExplicit); extensions.registerInstruction("positioncell","ffffczz",opcodePositionCell,opcodePositionCellExplicit);
extensions.registerInstruction("placeitemcell","ccffffX",opcodePlaceItemCell); extensions.registerInstruction("placeitemcell","ccffffX",opcodePlaceItemCell);
extensions.registerInstruction("placeitem","cffffX",opcodePlaceItem); extensions.registerInstruction("placeitem","cffffX",opcodePlaceItem);
extensions.registerInstruction("placeatpc","clflX",opcodePlaceAtPc); extensions.registerInstruction("placeatpc","clflX",opcodePlaceAtPc);

View File

@ -67,6 +67,11 @@ namespace Compiler
parseExpression (scanner, loc); parseExpression (scanner, loc);
return true; return true;
} }
else if (mState == SetState)
{
// Allow ints to be used as variable names
return parseName(loc.mLiteral, loc, scanner);
}
return Parser::parseInt (value, loc, scanner); return Parser::parseInt (value, loc, scanner);
} }
@ -140,7 +145,7 @@ namespace Compiler
if (!arguments.empty()) if (!arguments.empty())
{ {
mExprParser.reset(); mExprParser.reset();
mExprParser.parseArguments (arguments, scanner, mCode); mExprParser.parseArguments (arguments, scanner, mCode, -1, true);
} }
mName = name; mName = name;

View File

@ -130,7 +130,8 @@ namespace Compiler
{ {
bool cont = false; bool cont = false;
if (scanInt (c, parser, cont)) bool scanned = mExpectName ? scanName(c, parser, cont) : scanInt(c, parser, cont);
if (scanned)
{ {
mLoc.mLiteral.clear(); mLoc.mLiteral.clear();
return cont; return cont;
@ -387,6 +388,8 @@ namespace Compiler
bool Scanner::scanSpecial (MultiChar& c, Parser& parser, bool& cont) bool Scanner::scanSpecial (MultiChar& c, Parser& parser, bool& cont)
{ {
bool expectName = mExpectName;
mExpectName = false;
int special = -1; int special = -1;
if (c=='\n') if (c=='\n')
@ -541,15 +544,16 @@ namespace Compiler
if (special==S_newline) if (special==S_newline)
mLoc.mLiteral = "<newline>"; mLoc.mLiteral = "<newline>";
else if (mExpectName && (special == S_member || special == S_minus)) else if (expectName && (special == S_member || special == S_minus))
{ {
mExpectName = false;
bool tolerant = mTolerantNames; bool tolerant = mTolerantNames;
mTolerantNames = true; mTolerantNames = true;
bool out = scanName(c, parser, cont); bool out = scanName(c, parser, cont);
mTolerantNames = tolerant; mTolerantNames = tolerant;
return out; return out;
} }
else if (expectName && special == S_comma)
mExpectName = true;
TokenLoc loc (mLoc); TokenLoc loc (mLoc);
mLoc.mLiteral.clear(); mLoc.mLiteral.clear();

View File

@ -86,6 +86,12 @@ namespace Compiler
return Parser::parseSpecial (code, loc, scanner); return Parser::parseSpecial (code, loc, scanner);
} }
bool StringParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
{
reportWarning("Treating integer argument as a string", loc);
return parseName(loc.mLiteral, loc, scanner);
}
void StringParser::append (std::vector<Interpreter::Type_Code>& code) void StringParser::append (std::vector<Interpreter::Type_Code>& code)
{ {
std::copy (mCode.begin(), mCode.end(), std::back_inserter (code)); std::copy (mCode.begin(), mCode.end(), std::back_inserter (code));

View File

@ -43,6 +43,10 @@ namespace Compiler
///< Handle a special character token. ///< Handle a special character token.
/// \return fetch another token? /// \return fetch another token?
bool parseInt (int value, const TokenLoc& loc, Scanner& scanner) override;
///< Handle an int token.
/// \return fetch another token?
void append (std::vector<Interpreter::Type_Code>& code); void append (std::vector<Interpreter::Type_Code>& code);
///< Append code for parsed string. ///< Append code for parsed string.