Numeric constants for ConditionExpression
This commit is contained in:
@@ -61,6 +61,13 @@ namespace OpenRA.Support
|
|||||||
: base(symbol, index, Associativity.Left, 0) { }
|
: base(symbol, index, Associativity.Left, 0) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NumberToken : Token
|
||||||
|
{
|
||||||
|
public readonly int Value;
|
||||||
|
public NumberToken(int index, string symbol)
|
||||||
|
: base(symbol, index, Associativity.Left, 0) { Value = int.Parse(symbol); }
|
||||||
|
}
|
||||||
|
|
||||||
class AndToken : BinaryOperationToken { public AndToken(int index) : base("&&", index) { } }
|
class AndToken : BinaryOperationToken { public AndToken(int index) : base("&&", index) { } }
|
||||||
class OrToken : BinaryOperationToken { public OrToken(int index) : base("||", index) { } }
|
class OrToken : BinaryOperationToken { public OrToken(int index) : base("||", index) { } }
|
||||||
class EqualsToken : BinaryOperationToken { public EqualsToken(int index) : base("==", index) { } }
|
class EqualsToken : BinaryOperationToken { public EqualsToken(int index) : base("==", index) { } }
|
||||||
@@ -120,17 +127,17 @@ namespace OpenRA.Support
|
|||||||
|
|
||||||
for (var i = 0; i < tokens.Count - 1; i++)
|
for (var i = 0; i < tokens.Count - 1; i++)
|
||||||
{
|
{
|
||||||
// Unary tokens must be followed by a variable, another unary token, or an opening parenthesis
|
// Unary tokens must be followed by a variable, number, another unary token, or an opening parenthesis
|
||||||
if (tokens[i] is UnaryOperationToken && !(tokens[i + 1] is VariableToken || tokens[i + 1] is UnaryOperationToken
|
if (tokens[i] is UnaryOperationToken && !(tokens[i + 1] is VariableToken || tokens[i + 1] is NumberToken
|
||||||
|| tokens[i + 1] is OpenParenToken))
|
|| tokens[i + 1] is UnaryOperationToken || tokens[i + 1] is OpenParenToken))
|
||||||
throw new InvalidDataException("Unexpected token `{0}` at index {1}".F(tokens[i].Symbol, tokens[i].Index));
|
throw new InvalidDataException("Unexpected token `{0}` at index {1}".F(tokens[i].Symbol, tokens[i].Index));
|
||||||
|
|
||||||
// Disallow empty parentheses
|
// Disallow empty parentheses
|
||||||
if (tokens[i] is OpenParenToken && tokens[i + 1] is CloseParenToken)
|
if (tokens[i] is OpenParenToken && tokens[i + 1] is CloseParenToken)
|
||||||
throw new InvalidDataException("Empty parenthesis at index {0}".F(tokens[i].Index));
|
throw new InvalidDataException("Empty parenthesis at index {0}".F(tokens[i].Index));
|
||||||
|
|
||||||
// A variable must be followed by a binary operation or by a closing parenthesis
|
// A variable or number must be followed by a binary operation or by a closing parenthesis
|
||||||
if (tokens[i] is VariableToken && !(tokens[i + 1] is BinaryOperationToken || tokens[i + 1] is CloseParenToken))
|
if ((tokens[i] is VariableToken || tokens[i] is NumberToken) && !(tokens[i + 1] is BinaryOperationToken || tokens[i + 1] is CloseParenToken))
|
||||||
throw new InvalidDataException("Missing binary operation at index {0}".F(tokens[i + 1].Index));
|
throw new InvalidDataException("Missing binary operation at index {0}".F(tokens[i + 1].Index));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,8 +154,8 @@ namespace OpenRA.Support
|
|||||||
for (var i = 1; i < tokens.Count - 1; i++)
|
for (var i = 1; i < tokens.Count - 1; i++)
|
||||||
{
|
{
|
||||||
if (tokens[i] is BinaryOperationToken && (
|
if (tokens[i] is BinaryOperationToken && (
|
||||||
!(tokens[i - 1] is CloseParenToken || tokens[i - 1] is VariableToken) ||
|
!(tokens[i - 1] is CloseParenToken || tokens[i - 1] is VariableToken || tokens[i - 1] is NumberToken) ||
|
||||||
!(tokens[i + 1] is OpenParenToken || tokens[i + 1] is VariableToken || tokens[i + 1] is UnaryOperationToken)))
|
!(tokens[i + 1] is OpenParenToken || tokens[i + 1] is VariableToken || tokens[i + 1] is NumberToken || tokens[i + 1] is UnaryOperationToken)))
|
||||||
throw new InvalidDataException("Unexpected token `{0}` at index `{1}`".F(tokens[i].Symbol, tokens[i].Index));
|
throw new InvalidDataException("Unexpected token `{0}` at index `{1}`".F(tokens[i].Symbol, tokens[i].Index));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,6 +213,27 @@ namespace OpenRA.Support
|
|||||||
throw new InvalidDataException("Unexpected character '|' at index {0}".F(start));
|
throw new InvalidDataException("Unexpected character '|' at index {0}".F(start));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scan forwards until we find an non-digit character
|
||||||
|
if (c == '-' || char.IsDigit(expression[i]))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
for (; i < expression.Length; i++)
|
||||||
|
{
|
||||||
|
c = expression[i];
|
||||||
|
if (!char.IsDigit(c))
|
||||||
|
{
|
||||||
|
if (!char.IsWhiteSpace(c) && c != '(' && c != ')' && c != '!' && c != '&' && c != '|' && c != '=' && c != '+')
|
||||||
|
throw new InvalidDataException("Number and variable merged at index {0}".F(start));
|
||||||
|
|
||||||
|
// Put the bad character back for the next parse attempt
|
||||||
|
i--;
|
||||||
|
return new NumberToken(start, expression.Substring(start, i - start + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NumberToken(start, expression.Substring(start));
|
||||||
|
}
|
||||||
|
|
||||||
// Scan forwards until we find an invalid name character
|
// Scan forwards until we find an invalid name character
|
||||||
for (; i < expression.Length; i++)
|
for (; i < expression.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -255,7 +283,7 @@ namespace OpenRA.Support
|
|||||||
while (!((temp = s.Pop()) is OpenParenToken))
|
while (!((temp = s.Pop()) is OpenParenToken))
|
||||||
yield return temp;
|
yield return temp;
|
||||||
}
|
}
|
||||||
else if (t is VariableToken)
|
else if (t is VariableToken || t is NumberToken)
|
||||||
yield return t;
|
yield return t;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -286,6 +314,8 @@ namespace OpenRA.Support
|
|||||||
ApplyBinaryOperation(s, (x, y) => (y == x) ? 1 : 0);
|
ApplyBinaryOperation(s, (x, y) => (y == x) ? 1 : 0);
|
||||||
else if (t is NotToken)
|
else if (t is NotToken)
|
||||||
ApplyUnaryOperation(s, x => (x > 0) ? 0 : 1);
|
ApplyUnaryOperation(s, x => (x > 0) ? 0 : 1);
|
||||||
|
else if (t is NumberToken)
|
||||||
|
s.Push(((NumberToken)t).Value);
|
||||||
else if (t is VariableToken)
|
else if (t is VariableToken)
|
||||||
s.Push(ParseSymbol((VariableToken)t, symbols));
|
s.Push(ParseSymbol((VariableToken)t, symbols));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,11 +37,27 @@ namespace OpenRA.Test
|
|||||||
Assert.True(new ConditionExpression(expression).Evaluate(testValues) > 0, expression);
|
Assert.True(new ConditionExpression(expression).Evaluate(testValues) > 0, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssertValue(string expression, int value)
|
||||||
|
{
|
||||||
|
Assert.AreEqual(value, new ConditionExpression(expression).Evaluate(testValues), expression);
|
||||||
|
}
|
||||||
|
|
||||||
void AssertParseFailure(string expression)
|
void AssertParseFailure(string expression)
|
||||||
{
|
{
|
||||||
Assert.Throws(typeof(InvalidDataException), () => new ConditionExpression(expression).Evaluate(testValues), expression);
|
Assert.Throws(typeof(InvalidDataException), () => new ConditionExpression(expression).Evaluate(testValues), expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase(TestName = "Numbers")]
|
||||||
|
public void TestNumbers()
|
||||||
|
{
|
||||||
|
AssertParseFailure("1a");
|
||||||
|
AssertValue("0", 0);
|
||||||
|
AssertValue("1", 1);
|
||||||
|
AssertValue("12", 12);
|
||||||
|
AssertValue("-1", -1);
|
||||||
|
AssertValue("-12", -12);
|
||||||
|
}
|
||||||
|
|
||||||
[TestCase(TestName = "AND operation")]
|
[TestCase(TestName = "AND operation")]
|
||||||
public void TestAnd()
|
public void TestAnd()
|
||||||
{
|
{
|
||||||
@@ -49,6 +65,10 @@ namespace OpenRA.Test
|
|||||||
AssertFalse("false && false");
|
AssertFalse("false && false");
|
||||||
AssertFalse("true && false");
|
AssertFalse("true && false");
|
||||||
AssertFalse("false && true");
|
AssertFalse("false && true");
|
||||||
|
AssertValue("2 && false", 0);
|
||||||
|
AssertValue("false && 2", 0);
|
||||||
|
AssertValue("3 && 2", 2);
|
||||||
|
AssertValue("2 && 3", 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(TestName = "OR operation")]
|
[TestCase(TestName = "OR operation")]
|
||||||
@@ -58,6 +78,10 @@ namespace OpenRA.Test
|
|||||||
AssertFalse("false || false");
|
AssertFalse("false || false");
|
||||||
AssertTrue("true || false");
|
AssertTrue("true || false");
|
||||||
AssertTrue("false || true");
|
AssertTrue("false || true");
|
||||||
|
AssertValue("2 || false", 2);
|
||||||
|
AssertValue("false || 2", 2);
|
||||||
|
AssertValue("3 || 2", 3);
|
||||||
|
AssertValue("2 || 3", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(TestName = "Equals operation")]
|
[TestCase(TestName = "Equals operation")]
|
||||||
@@ -67,6 +91,15 @@ namespace OpenRA.Test
|
|||||||
AssertTrue("false == false");
|
AssertTrue("false == false");
|
||||||
AssertFalse("true == false");
|
AssertFalse("true == false");
|
||||||
AssertFalse("false == true");
|
AssertFalse("false == true");
|
||||||
|
AssertTrue("1 == 1");
|
||||||
|
AssertTrue("0 == 0");
|
||||||
|
AssertFalse("1 == 0");
|
||||||
|
AssertTrue("1 == true");
|
||||||
|
AssertFalse("1 == false");
|
||||||
|
AssertTrue("0 == false");
|
||||||
|
AssertFalse("0 == true");
|
||||||
|
AssertValue("12 == 12", 1);
|
||||||
|
AssertValue("1 == 12", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(TestName = "Not-equals operation")]
|
[TestCase(TestName = "Not-equals operation")]
|
||||||
@@ -76,15 +109,26 @@ namespace OpenRA.Test
|
|||||||
AssertFalse("false != false");
|
AssertFalse("false != false");
|
||||||
AssertTrue("true != false");
|
AssertTrue("true != false");
|
||||||
AssertTrue("false != true");
|
AssertTrue("false != true");
|
||||||
|
AssertValue("1 != 2", 1);
|
||||||
|
AssertValue("1 != 1", 0);
|
||||||
|
AssertFalse("1 != true");
|
||||||
|
AssertFalse("0 != false");
|
||||||
|
AssertTrue("1 != false");
|
||||||
|
AssertTrue("0 != true");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(TestName = "NOT operation")]
|
[TestCase(TestName = "NOT operation")]
|
||||||
public void TestNOT()
|
public void TestNOT()
|
||||||
{
|
{
|
||||||
AssertFalse("!true");
|
AssertValue("!true", 0);
|
||||||
AssertTrue("!false");
|
AssertValue("!false", 1);
|
||||||
AssertTrue("!!true");
|
AssertValue("!!true", 1);
|
||||||
AssertFalse("!!false");
|
AssertValue("!!false", 0);
|
||||||
|
AssertValue("!0", 1);
|
||||||
|
AssertValue("!1", 0);
|
||||||
|
AssertValue("!5", 0);
|
||||||
|
AssertValue("!!5", 1);
|
||||||
|
AssertValue("!-5", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(TestName = "Precedence")]
|
[TestCase(TestName = "Precedence")]
|
||||||
@@ -134,7 +178,7 @@ namespace OpenRA.Test
|
|||||||
AssertParseFailure("true false");
|
AssertParseFailure("true false");
|
||||||
AssertParseFailure("true & false");
|
AssertParseFailure("true & false");
|
||||||
AssertParseFailure("true | false");
|
AssertParseFailure("true | false");
|
||||||
AssertParseFailure("true / false");
|
AssertParseFailure("true : false");
|
||||||
AssertParseFailure("true & false && !");
|
AssertParseFailure("true & false && !");
|
||||||
AssertParseFailure("(true && !)");
|
AssertParseFailure("(true && !)");
|
||||||
AssertParseFailure("&& false");
|
AssertParseFailure("&& false");
|
||||||
|
|||||||
@@ -17,66 +17,69 @@
|
|||||||
^GainsExperience:
|
^GainsExperience:
|
||||||
GainsExperience:
|
GainsExperience:
|
||||||
Conditions:
|
Conditions:
|
||||||
200: rank-veteran-1
|
200: rank-veteran
|
||||||
400: rank-veteran-2
|
400: rank-veteran
|
||||||
800: rank-veteran-3
|
800: rank-veteran
|
||||||
1600: rank-elite
|
1600: rank-veteran
|
||||||
|
GrantCondition@RANK-ELITE:
|
||||||
|
RequiresCondition: rank-veteran == 4
|
||||||
|
Condition: rank-elite
|
||||||
DamageMultiplier@RANK-1:
|
DamageMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 95
|
Modifier: 95
|
||||||
DamageMultiplier@RANK-2:
|
DamageMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 90
|
Modifier: 90
|
||||||
DamageMultiplier@RANK-3:
|
DamageMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 85
|
Modifier: 85
|
||||||
DamageMultiplier@RANK-ELITE:
|
DamageMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 75
|
Modifier: 75
|
||||||
FirepowerMultiplier@RANK-1:
|
FirepowerMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 105
|
Modifier: 105
|
||||||
FirepowerMultiplier@RANK-2:
|
FirepowerMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 110
|
Modifier: 110
|
||||||
FirepowerMultiplier@RANK-3:
|
FirepowerMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 120
|
Modifier: 120
|
||||||
FirepowerMultiplier@RANK-ELITE:
|
FirepowerMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 130
|
Modifier: 130
|
||||||
SpeedMultiplier@RANK-1:
|
SpeedMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 105
|
Modifier: 105
|
||||||
SpeedMultiplier@RANK-2:
|
SpeedMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 110
|
Modifier: 110
|
||||||
SpeedMultiplier@RANK-3:
|
SpeedMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 120
|
Modifier: 120
|
||||||
SpeedMultiplier@RANK-ELITE:
|
SpeedMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 140
|
Modifier: 140
|
||||||
ReloadDelayMultiplier@RANK-1:
|
ReloadDelayMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 95
|
Modifier: 95
|
||||||
ReloadDelayMultiplier@RANK-2:
|
ReloadDelayMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 90
|
Modifier: 90
|
||||||
ReloadDelayMultiplier@RANK-3:
|
ReloadDelayMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 85
|
Modifier: 85
|
||||||
ReloadDelayMultiplier@RANK-ELITE:
|
ReloadDelayMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 75
|
Modifier: 75
|
||||||
InaccuracyMultiplier@RANK-1:
|
InaccuracyMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 90
|
Modifier: 90
|
||||||
InaccuracyMultiplier@RANK-2:
|
InaccuracyMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 80
|
Modifier: 80
|
||||||
InaccuracyMultiplier@RANK-3:
|
InaccuracyMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 70
|
Modifier: 70
|
||||||
InaccuracyMultiplier@RANK-ELITE:
|
InaccuracyMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
@@ -92,21 +95,21 @@
|
|||||||
Sequence: rank-veteran-1
|
Sequence: rank-veteran-1
|
||||||
Palette: effect
|
Palette: effect
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@RANK-2:
|
WithDecoration@RANK-2:
|
||||||
Image: rank
|
Image: rank
|
||||||
Sequence: rank-veteran-2
|
Sequence: rank-veteran-2
|
||||||
Palette: effect
|
Palette: effect
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@RANK-3:
|
WithDecoration@RANK-3:
|
||||||
Image: rank
|
Image: rank
|
||||||
Sequence: rank-veteran-3
|
Sequence: rank-veteran-3
|
||||||
Palette: effect
|
Palette: effect
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@RANK-ELITE:
|
WithDecoration@RANK-ELITE:
|
||||||
Image: rank
|
Image: rank
|
||||||
|
|||||||
@@ -17,66 +17,69 @@
|
|||||||
^GainsExperience:
|
^GainsExperience:
|
||||||
GainsExperience:
|
GainsExperience:
|
||||||
Conditions:
|
Conditions:
|
||||||
200: rank-veteran-1
|
200: rank-veteran
|
||||||
400: rank-veteran-2
|
400: rank-veteran
|
||||||
800: rank-veteran-3
|
800: rank-veteran
|
||||||
1600: rank-elite
|
1600: rank-veteran
|
||||||
|
GrantCondition@RANK-ELITE:
|
||||||
|
RequiresCondition: rank-veteran == 4
|
||||||
|
Condition: rank-elite
|
||||||
DamageMultiplier@RANK-1:
|
DamageMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 96
|
Modifier: 96
|
||||||
DamageMultiplier@RANK-2:
|
DamageMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 92
|
Modifier: 92
|
||||||
DamageMultiplier@RANK-3:
|
DamageMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 88
|
Modifier: 88
|
||||||
DamageMultiplier@RANK-ELITE:
|
DamageMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 80
|
Modifier: 80
|
||||||
FirepowerMultiplier@RANK-1:
|
FirepowerMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 105
|
Modifier: 105
|
||||||
FirepowerMultiplier@RANK-2:
|
FirepowerMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 110
|
Modifier: 110
|
||||||
FirepowerMultiplier@RANK-3:
|
FirepowerMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 115
|
Modifier: 115
|
||||||
FirepowerMultiplier@RANK-ELITE:
|
FirepowerMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 125
|
Modifier: 125
|
||||||
SpeedMultiplier@RANK-1:
|
SpeedMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 105
|
Modifier: 105
|
||||||
SpeedMultiplier@RANK-2:
|
SpeedMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 110
|
Modifier: 110
|
||||||
SpeedMultiplier@RANK-3:
|
SpeedMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 115
|
Modifier: 115
|
||||||
SpeedMultiplier@RANK-ELITE:
|
SpeedMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 125
|
Modifier: 125
|
||||||
ReloadDelayMultiplier@RANK-1:
|
ReloadDelayMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 96
|
Modifier: 96
|
||||||
ReloadDelayMultiplier@RANK-2:
|
ReloadDelayMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 92
|
Modifier: 92
|
||||||
ReloadDelayMultiplier@RANK-3:
|
ReloadDelayMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 88
|
Modifier: 88
|
||||||
ReloadDelayMultiplier@RANK-ELITE:
|
ReloadDelayMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 80
|
Modifier: 80
|
||||||
InaccuracyMultiplier@RANK-1:
|
InaccuracyMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 90
|
Modifier: 90
|
||||||
InaccuracyMultiplier@RANK-2:
|
InaccuracyMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 80
|
Modifier: 80
|
||||||
InaccuracyMultiplier@RANK-3:
|
InaccuracyMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 70
|
Modifier: 70
|
||||||
InaccuracyMultiplier@RANK-ELITE:
|
InaccuracyMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
@@ -93,21 +96,21 @@
|
|||||||
Sequence: rank-veteran-1
|
Sequence: rank-veteran-1
|
||||||
Palette: effect
|
Palette: effect
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@RANK-2:
|
WithDecoration@RANK-2:
|
||||||
Image: rank
|
Image: rank
|
||||||
Sequence: rank-veteran-2
|
Sequence: rank-veteran-2
|
||||||
Palette: effect
|
Palette: effect
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@RANK-3:
|
WithDecoration@RANK-3:
|
||||||
Image: rank
|
Image: rank
|
||||||
Sequence: rank-veteran-3
|
Sequence: rank-veteran-3
|
||||||
Palette: effect
|
Palette: effect
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@RANK-ELITE:
|
WithDecoration@RANK-ELITE:
|
||||||
Image: rank
|
Image: rank
|
||||||
|
|||||||
@@ -59,14 +59,11 @@ V05:
|
|||||||
DOG:
|
DOG:
|
||||||
# HACK: Disable experience without killing the linter
|
# HACK: Disable experience without killing the linter
|
||||||
-GainsExperience:
|
-GainsExperience:
|
||||||
ExternalCondition@RANK-VETERAN-1:
|
ExternalCondition@RANK-VETERAN:
|
||||||
Condition: rank-veteran-1
|
Condition: rank-veteran
|
||||||
ExternalCondition@RANK-VETERAN-2:
|
|
||||||
Condition: rank-veteran-2
|
|
||||||
ExternalCondition@RANK-VETERAN-3:
|
|
||||||
Condition: rank-veteran-3
|
|
||||||
ExternalCondition@RANK-ELITE:
|
ExternalCondition@RANK-ELITE:
|
||||||
Condition: rank-elite
|
Condition: rank-elite
|
||||||
|
-GrantCondition@RANK-ELITE:
|
||||||
|
|
||||||
SPY:
|
SPY:
|
||||||
Mobile:
|
Mobile:
|
||||||
|
|||||||
@@ -16,66 +16,69 @@
|
|||||||
^GainsExperience:
|
^GainsExperience:
|
||||||
GainsExperience:
|
GainsExperience:
|
||||||
Conditions:
|
Conditions:
|
||||||
200: rank-veteran-1
|
200: rank-veteran
|
||||||
400: rank-veteran-2
|
400: rank-veteran
|
||||||
800: rank-veteran-3
|
800: rank-veteran
|
||||||
1600: rank-elite
|
1600: rank-veteran
|
||||||
|
GrantCondition@RANK-ELITE:
|
||||||
|
RequiresCondition: rank-veteran == 4
|
||||||
|
Condition: rank-elite
|
||||||
DamageMultiplier@RANK-1:
|
DamageMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 95
|
Modifier: 95
|
||||||
DamageMultiplier@RANK-2:
|
DamageMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 90
|
Modifier: 90
|
||||||
DamageMultiplier@RANK-3:
|
DamageMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 85
|
Modifier: 85
|
||||||
DamageMultiplier@RANK-ELITE:
|
DamageMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 75
|
Modifier: 75
|
||||||
FirepowerMultiplier@RANK-1:
|
FirepowerMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 105
|
Modifier: 105
|
||||||
FirepowerMultiplier@RANK-2:
|
FirepowerMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 110
|
Modifier: 110
|
||||||
FirepowerMultiplier@RANK-3:
|
FirepowerMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 120
|
Modifier: 120
|
||||||
FirepowerMultiplier@RANK-ELITE:
|
FirepowerMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 130
|
Modifier: 130
|
||||||
SpeedMultiplier@RANK-1:
|
SpeedMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 105
|
Modifier: 105
|
||||||
SpeedMultiplier@RANK-2:
|
SpeedMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 110
|
Modifier: 110
|
||||||
SpeedMultiplier@RANK-3:
|
SpeedMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 120
|
Modifier: 120
|
||||||
SpeedMultiplier@RANK-ELITE:
|
SpeedMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 140
|
Modifier: 140
|
||||||
ReloadDelayMultiplier@RANK-1:
|
ReloadDelayMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 95
|
Modifier: 95
|
||||||
ReloadDelayMultiplier@RANK-2:
|
ReloadDelayMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 90
|
Modifier: 90
|
||||||
ReloadDelayMultiplier@RANK-3:
|
ReloadDelayMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 85
|
Modifier: 85
|
||||||
ReloadDelayMultiplier@RANK-ELITE:
|
ReloadDelayMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 75
|
Modifier: 75
|
||||||
InaccuracyMultiplier@RANK-1:
|
InaccuracyMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
Modifier: 90
|
Modifier: 90
|
||||||
InaccuracyMultiplier@RANK-2:
|
InaccuracyMultiplier@RANK-2:
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
Modifier: 80
|
Modifier: 80
|
||||||
InaccuracyMultiplier@RANK-3:
|
InaccuracyMultiplier@RANK-3:
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
Modifier: 70
|
Modifier: 70
|
||||||
InaccuracyMultiplier@RANK-ELITE:
|
InaccuracyMultiplier@RANK-ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
@@ -91,21 +94,21 @@
|
|||||||
Sequence: rank-veteran-1
|
Sequence: rank-veteran-1
|
||||||
Palette: effect
|
Palette: effect
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran-1 && !rank-veteran-2
|
RequiresCondition: rank-veteran == 1
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@RANK-2:
|
WithDecoration@RANK-2:
|
||||||
Image: rank
|
Image: rank
|
||||||
Sequence: rank-veteran-2
|
Sequence: rank-veteran-2
|
||||||
Palette: effect
|
Palette: effect
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran-2 && !rank-veteran-3
|
RequiresCondition: rank-veteran == 2
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@RANK-3:
|
WithDecoration@RANK-3:
|
||||||
Image: rank
|
Image: rank
|
||||||
Sequence: rank-veteran-3
|
Sequence: rank-veteran-3
|
||||||
Palette: effect
|
Palette: effect
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran-3 && !rank-elite
|
RequiresCondition: rank-veteran == 3
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@RANK-ELITE:
|
WithDecoration@RANK-ELITE:
|
||||||
Image: rank
|
Image: rank
|
||||||
|
|||||||
@@ -18,28 +18,34 @@
|
|||||||
^GainsExperience:
|
^GainsExperience:
|
||||||
GainsExperience:
|
GainsExperience:
|
||||||
Conditions:
|
Conditions:
|
||||||
500: rank-veteran
|
500: rank
|
||||||
1000: rank-elite
|
1000: rank
|
||||||
|
GrantCondition@RANK-VETERAN:
|
||||||
|
RequiresCondition: rank == 1
|
||||||
|
Condition: rank-veteran
|
||||||
|
GrantCondition@RANK-ELITE:
|
||||||
|
RequiresCondition: rank == 2
|
||||||
|
Condition: rank-elite
|
||||||
FirepowerMultiplier@VETERAN:
|
FirepowerMultiplier@VETERAN:
|
||||||
RequiresCondition: rank-veteran && !rank-elite
|
RequiresCondition: rank-veteran
|
||||||
Modifier: 110
|
Modifier: 110
|
||||||
FirepowerMultiplier@ELITE:
|
FirepowerMultiplier@ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 130
|
Modifier: 130
|
||||||
DamageMultiplier@VETERAN:
|
DamageMultiplier@VETERAN:
|
||||||
RequiresCondition: rank-veteran && !rank-elite
|
RequiresCondition: rank-veteran
|
||||||
Modifier: 90
|
Modifier: 90
|
||||||
DamageMultiplier@ELITE:
|
DamageMultiplier@ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 75
|
Modifier: 75
|
||||||
SpeedMultiplier@VETERAN:
|
SpeedMultiplier@VETERAN:
|
||||||
RequiresCondition: rank-veteran && !rank-elite
|
RequiresCondition: rank-veteran
|
||||||
Modifier: 120
|
Modifier: 120
|
||||||
SpeedMultiplier@ELITE:
|
SpeedMultiplier@ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
Modifier: 140
|
Modifier: 140
|
||||||
ReloadDelayMultiplier@VETERAN:
|
ReloadDelayMultiplier@VETERAN:
|
||||||
RequiresCondition: rank-veteran && !rank-elite
|
RequiresCondition: rank-veteran
|
||||||
Modifier: 90
|
Modifier: 90
|
||||||
ReloadDelayMultiplier@ELITE:
|
ReloadDelayMultiplier@ELITE:
|
||||||
RequiresCondition: rank-elite
|
RequiresCondition: rank-elite
|
||||||
@@ -55,7 +61,7 @@
|
|||||||
Sequence: veteran
|
Sequence: veteran
|
||||||
Palette: ra
|
Palette: ra
|
||||||
ReferencePoint: Bottom, Right
|
ReferencePoint: Bottom, Right
|
||||||
RequiresCondition: rank-veteran && !rank-elite
|
RequiresCondition: rank-veteran
|
||||||
ZOffset: 256
|
ZOffset: 256
|
||||||
WithDecoration@ELITE:
|
WithDecoration@ELITE:
|
||||||
Image: rank
|
Image: rank
|
||||||
|
|||||||
Reference in New Issue
Block a user