Skip to content

Advanced constructs

Zezombye edited this page Sep 21, 2020 · 5 revisions

Switches

Switches are a good way to transform an if/elif/else chain into something more optimized:

switch A:
    case Hero.ANA:
        B = 2
        break
    case Hero.ASHE:
        B = 3
        break
    default:
        B = 4

This is equivalent to:

if A == Hero.ANA:
    B = 2
elif A == Hero.ASHE:
    B = 3
else:
    B = 4

However, the switch statement compiles to a Skip with automatically calculated indexes, which has the advantage of not reevaluating A.

Keep in mind that fallthrough is enabled, so if you don't have a break instruction, the execution continues to the next case statement.

Dictionaries

In the above case, we always set the same variable. Therefore, a dictionary can be used:

B = {
    0: 4,
    Hero.ANA: 2,
    Hero.ASHE: 3,
}[A]

The workshop has no concept of exceptions, and therefore if a key doesn't exist, the first value of the dictionary is taken.

This dictionary is internally converted to:

B = [4, 2, 3][max(false, [0, Hero.ANA, Hero.ASHE].index(A))]

Therefore, a dictionary cannot be declared alone; it must always be accessed.

Enums

Enums can be declared to avoid manually declaring several macros:

enum GameStatus:
    GAME_NOT_STARTED = 1,
    GAME_IN_PROGRESS,
    GAME_FINISHED

enum Team:
    HUMANS = Team.2,
    ZOMBIES = Team.1,

rule "Kill zombies when game has finished":
    @Condition gameStatus == GameStatus.GAME_FINISHED
    kill(getPlayers(Team.ZOMBIES), null)

If an enum member is not given a value, it will take the previous value plus 1 (or 0 if it is the first value). You can also extend existing enums, such as the Team enum in this example.