-
Notifications
You must be signed in to change notification settings - Fork 10
Expressions
It is not necessary to #include "zcommon.acs"
in order to use the boolean literals. The boolean literals true
and false
are now keywords.
The assignment operation now produces a result. The result is the value being assigned. As a consequence, you can chain together multiple assignments or use an assignment in a condition.
script "Main" open {
int a, b, c;
a = b = c = 123; // `a`, `b`, and `c` now have the value 123.
// First a random number is generated. Then the random number is assigned to
// variable `a`. The result of the assignment, which is the random number,
// is then checked if it's not 3.
while ( ( a = random( 0, 10 ) ) != 3 ) {
Print( s: "Discarding number: ", d: a );
}
}
For strcpy()
, the a:
is optional, unless you want to use the extra parameters:
script "Main" {
static int v[ 10 ];
strcpy( v, "abc" );
strcpy( a: ( v, 0, 1 ), "abc" );
}
In ACS, both of the operands to &&
and ||
are evaluated at all times. In BCS, the right operand is only evaluated if necessary. For example, if the left operand to &&
is false, there is no need to evaluate the right operand because the result of the operation will still be false. Similarly, if the left operand to ||
is true, there is no need to evaluate the right operand because the result of the operation will still be true. This is called short-circuit evaluation:
int Zero() {
return 0;
}
int One() {
return 1;
}
script "Main" open {
// Zero() makes the && operation false, so calling One() is not necessary
// because the result will still be false.
Zero() && One();
// One() makes the || operation true, so calling Zero() is not necessary
// because the result will still be true.
One() || Zero();
}
Along with decimal and hexadecimal literals, there are now also octal and binary literals. Octal literals are base-8 numbers, use the digits, 0 to 7, and start with 0o
. Binary literals are base-2 numbers, use the digits, 0 and 1, and start with 0b
.
script "Main" open {
Print( d: 0b101 ); // Output: 5
Print( d: 0o123 ); // Output: 83
}
Like ACS, BCS supports radix constants, which allow you to specify the base of the number. The base can range from 2 to 36. The valid digits are, 0 to 9, and after that, a
to z
. The base and the number are separated by r
(works only in BCS) or _
(works in both BCS and ACS):
script "Main" open {
Print( d: 2r101 ); // Base-2 (Binary). Output: 5
Print( d: 8r123 ); // Base-8 (Octal). Output: 83
Print( d: 16_FF ); // Base-16 (Hexadecimal). Output: 255
Print( d: 36_ZZ ); // Base-36. Output: 1295
}
To improve readability of long numbers, a single quotation mark ('
) can be used to separate digits into easily recognizable groups:
script "Main" open {
Print( d: 2'000'000'000 ); // Output: 2000000000
Print( d: 0b'1101'0111'0100'0110 ); // Output: 55110
}
left ? middle : right left ? : right
The ?:
operator is similar to the if
statement. The left operand is evaluated first. If the result is true
, then the middle operand is evaluated and returned; otherwise, the right operand is evaluated and returned:
script "Main" open {
Print( d: 1 ? 123 : 321 ); // Output: 123
Print( d: 0 ? 123 : 321 ); // Output: 321
}
The middle operand can be left out. In this case, the left operand is evaluated first. After an implicit conversion to bool
, if the result is true
, then the result before the implicit conversion is returned; otherwise, the right operand is evaluated and returned:
script "Main" open {
Print( d: 123 ?: 321 ); // Output: 123
Print( d: 0 ?: 321 ); // Output: 321
}
memcpy()
is similar in syntax and functionality to strcpy()
, but instead of copying strings, memcpy()
copies arrays and structure variables.
bool memcpy ( a: ( destination [, int offset [, int elementsToCopy]] ) , source [, int sourceOffset] )
int arrayA[] = { 1, 2, 3 };
int arrayB[] = { 4, 5, 6 };
script "Main" open {
memcpy( arrayA, arrayB );
// The elements of `arrayA` will now have the same value as the elements of
// the `arrayB` array.
Print( d: arrayA[ 1 ] ); // Output: 5
}
bool memcpy ( destination , source )
struct {
int value;
} structA = { 123 }, structB = { 321 };
script "Main" open {
memcpy( structA, structB );
// The members of `structA` will now have the same value as the members of
// the `structB` variable.
Print( d: structA.value ); // Output: 321
}
memcpy()
is not a feature of the game engine. It is implemented by the compiler. The compiler will generate extra code behind the scenes to make it work. So be aware of that when writing performance critical code.