Project

Profile

Help

Python code under triggers, aliases and macros

Added by Francisco Del Roio over 5 years ago

Hello,

I'm posting here because I am not sure if it is a valid topic for an issue.

I was reading code for execute in the Engine class (SharpScript). I am not sure what happens with multiline instructions like for, while and so on.

Another thing is data persistense between scripts, for taking for example HP differences. How does work this? Or it is a feature not implemented yet?

Cheers,


Replies (1)

RE: Python code under triggers, aliases and macros - Added by Vincent Le Goff over 5 years ago

Hi,

In both cases, the answer is extended SharpScript with Python instructions. It looks like this:

#action {param1} {param2} {+
    # that's a Python block in which you can use whatever you want like
    if thingie:
        play('sound/boom.ogg')
}

This syntax allows to extend the SharpScript abilities. SharpScript was never intended to be a programming language of its own and it limits features to limit complexity. However, it was also intended to include Python code itself. Python can be used to make the alias, trigger, macro or whatever else much more powerful.

What about data persistence? Using Python code, you have access to the same variables you had used beforehand. It means no Python running in SharpScript is independent of others. Variables are shared. This also makes distributing data much easier. Here's a real-world example I have to intercept a line like:

HP: 80/100 EP: 50/200

(Being understood that all four figures can be different):

#trigger {^HP: ([0-9]+)/([0-9]+) *EP: ([0-9]+)/([0-9]+)} {+
    # Keep old values of health and endurance points
    try:
        old_HP = HP
        old_EP = EP
    except NameError:
        old_HP = 0
        old_EP = 0

    # Get the 4 numbers out of the trigger
    HP = int(args["1"])
    HP_max = int(args["2"])
    EP = int(args["3"])
    EP_max = int(args["4"])

    # Restore max values if necessary
    try:
        assert HP_max >= HP
    except (NameError, AssertionError):
        HP_max = HP

    try:
        assert EP_max >= EP
    except (NameError, AssertionError):
        EP_max = EP

    # Play a different sound depending on health
    if HP != old_HP:
        level = int(HP * 10 / HP_max)
        # Play one of health_0.wav, health_1.wav, health_2.wav... health_10.wav
        play("sounds/health_{}.wav".format(level))
} +mute

This looks like a complicated trigger at first, so here's a short explanation:

  1. The trigger intercepts the line with health, maximum health, endurance, maximum endurance (see the example above).
  2. If they exist, the old health and endurance are stored in separate variables (we'll need it for the last step of the trigger).
  3. We then extract the current health, maximum health, endurance, maximum endurance from the trigger line. This is basic regexes. Notice we use args which contains the expression arguments.
  4. We update maximum values (that is sometimes necessary) for health and endurance.
  5. Finally we play a sound to let the player know what is health value is. This sound helps the player knows if her health goes down too much in a fight for instance. Note that the `sounds/health_X.wav@ must exist, they're not provided.

Each time the trigger is called, it has access to the same variables and the old variables are still here (hence the check on HP and EP). So in the same configuration, we can set a very simple macro:

#macro {Ctrl + J} {#say $HP}
#macro {Ctrl + K} {#say $EP}

Since the variables exist, there's nothing else to be done.

Adding pure Python in triggers like this can seem strange at first. However, the previous trigger would be extremely difficult to do in SharpScript or any scripting language I have seen in games. This was the compromise. You can read more about SharpScript with Python in the last section of this page.

    (1-1/1)

    Please register to reply