Numeric constants for ConditionExpression

This commit is contained in:
atlimit8
2017-02-06 12:13:00 -06:00
parent 65725efd04
commit 73895d07e2
7 changed files with 178 additions and 92 deletions

View File

@@ -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));
} }

View File

@@ -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");

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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