Enums#
Basic Enums#
Enums allow you to define an enumerated list of constants, each incremented from the previous. Their most simple syntax is as follows:
enum
{
A, // 0
B, // 1
C, // 2
D, // 3
};
By default, the constants are of type const int
, and increment by 1
each.
To define constants of a different pre-existing type, you can use syntax like:
enum = long
{
A, // 0L
B, // 1L
C, // 2L
D, // 3L
};
These constants will be of type const long
instead of const int
.
Additionally, you can manually assign a value to any of the listed constants- the automatic increment will continue from the assigned value.
enum
{
A, // 0
B, // 1
C = 15, // 15
D, // 16
};
Custom Increment#
Additionally, you can change how much the enum increments by between each number.
Firstly, using enum = long
has the special behavior of incrementing by 1L
instead of 1
already. But, additionally, you can use the @Increment
annotation to directly specify an amount to increment by.
@Increment(2)
enum
{
A, // 0
B, // 2
C, // 4
D, // 6
};
Added in version 3.0: @Increment
Custom Type Creation#
By placing an identifier after the keyword enum
, you can define the enum as a
brand-new custom type. The constants in the enum will be const
of the custom type.
Customly-typed enums inherently cast back to int
, so they can still be used
just like normal int
values if you need to- but, they also have additional effects.
enum ItemID
{
IT_MONEY_1, // 0
IT_ARROW_1 = 13,
IT_ARROW_2, // 14
IT_ARROW_3 = 57,
};
// Works as a normal 'int' when needed
Hero->Item[IT_ARROW_1] = true;
Why use custom types?#
Type Safety#
Now, what reason is there to actually do this? The custom type can be used
to declare either variable or function parameters. Attempting to use
a normal int
will NOT work with these, and will create a compile error-
you can only use values of the type, i.e. the constants declared in the enum.
void give_item(ItemID id)
{
itemsprite itm = Screen->CreateItem(id);
itm->ForceGrab = true; // forces the Hero to pick up the item
}
<error>give_item(5);</error> // error; cannot cast 'int' to 'ItemID'
give_item(IT_ARROW_1); // works
<error>give_item(14);</error> // error; cannot cast 'int' to 'ItemID'
This prevents you (or others using your code) from making a mistake, and calling the function with a value it isn’t meant to handle. In this case, only valid item IDs that you’ve listed out for your quest can be passed to the function.
Non-restrictive#
You can override this via casting if you desire; though be sure you know what you’re doing when using casting with code you are unfamiliar with, as you may run into issues with the function not handling ‘bad’ values well.
give_item(<ItemID>91); // works!
Enum bitflags#
The @Bitflags
annotation turns an enum into a bitflags enum, which has two consequences:
Auto-incrementing values starting at 1 and doubling the previous for each new enum member
For type safety, bitwise operations on enum bitflags are only allowed with the same type
For example:
@Bitflags("int") // "long" is also supported
enum SomeBitflags
{
Fast, // 1
Big, // 2
Loud, // 4
};
@Bitflags("int")
enum OtherBitflags
{
Combo, // 1
Enemy, // 2
Weapon, // 4
};
auto x = Fast | Big; // inferred type is SomeBitflags
if (<error>x & Enemy</error>) // Errors, scripter accidentally used the wrong enum.
// ...