Author Topic: Fun with Scripts  (Read 534 times)

Offline luke83

  • Commander
  • *****
  • Posts: 1443
    • View Profile
    • openxcommods
Fun with Scripts
« on: January 23, 2019, 07:17:02 am »
Hey,
 So its pretty clear i have no idea what i am doing with script ( see below) but even if i get the LOGIC right, how do i link it to a specific unit type/ sprite? Perhaps i should say, how do i get the game to call and trigger the script, i must need to link it to something else in my rulesets right?

Code: [Select]
        ShowHealthOnSprite_on_land:
#*** Update units Health Bar graphic for each player unit***
      - offset: 1
        code: |
          # var int frame;
          # var int frameLength;
          # var int recolorPeriod;
          # var int desync;
          var int color;
          Var int HealthValue # see current health value
          Var int MaxHealth # See Max Health Value
          Var int HealthPercentage # Hold Percentage of Health values
          Var int ColourOrange; # Mid Health
          Var int ColourRed;  #low health
          Var int colorToReplace # how do i select this?
          var int newShade;
          var int temp;
          # var ptr RuleArmor armorRuleset;
          var int hpDamageDone;

          if hpDamageDone;
          unit.getTag Maxhealth =getHealthMax;
          unit.getTag HealthValue =getHealthMax;
          HealthPercentage = ( HealthValue/MaxHealth ) * 100

            if HealthPercentage <30;

            #turn RED
              get_color colorToReplace
              set_color ColourRed
              return new_pixel;

            else if HealthPecentage >30 AND <70;

            #turn ORANGE
              get_color colorToReplace
              set_color ColourOrange
              return new_pixel;

            end;

          end;




« Last Edit: January 23, 2019, 07:49:42 am by luke83 »

Offline Yankes

  • Commander
  • *****
  • Posts: 2083
    • View Profile
Re: Fun with Scripts
« Reply #1 on: January 23, 2019, 03:04:15 pm »
First of all scripts are case sensitive, `Var` will not compile it need be `var`.
Second, how match it to unit? One solution is add copy of this script to unit data like:
Code: [Select]
armors:
  - type: PARROT_ARMOR
    drawingRoutine: 4
    scripts:
      recolorUnitSprite: |
        #text there
Each unit can have it own script (it will be call with offset `0`)

Next is global script:
Code: [Select]
extended:
  scripts:
    recolorUnitSprite:
      - offset: 1 #if you set `-1` it will call before script set in `armors`
        code: |
          #code there

But this will call for every unit in game, one way to change it it alter logic to check for custom tags that enable this behavior:
Code: [Select]
extended:
  tags:
    RuleArmor:
      LUKE_MOD_HEALTH_BAR: int
  scripts:
    recolorUnitSprite:
      - offset: 1 #if you set `-1` it will call before script set in `armors`
        code: |
          var int recolor;
          unit.getTag recolor Tag.LUKE_MOD_HEALTH_BAR;
          if and gt recolor 0 eq current_color new_pixel;
            set_color new_pixel 4; #green color
          end;
          return new_pixel;

armors:
  - type: STR_NONE_UC
    tags:
      LUKE_MOD_HEALTH_BAR: 16 #definition of tag in each armor that should use it, default have `0`

Another import thing is test if your mod work correctly, you can add debug lines to see what happens exacly using:
Code: [Select]
debug_log 10; #will print 10 to `openxcom.log`
debug_log recolor; #will current value of this to `openxcom.log`
debug_log 111 unit; #will print 111 and some basic info about unit to `openxcom.log`
debug_log 1 2 3 4 5; #it can have multiple values pass

Offline luke83

  • Commander
  • *****
  • Posts: 1443
    • View Profile
    • openxcommods
Re: Fun with Scripts
« Reply #2 on: January 23, 2019, 06:28:21 pm »
Thanks mate, i will digest this information tonight after work and see how i go.

Thanks again.
« Last Edit: January 23, 2019, 06:42:57 pm by luke83 »

Offline Yankes

  • Commander
  • *****
  • Posts: 2083
    • View Profile
Re: Fun with Scripts
« Reply #3 on: January 23, 2019, 07:49:59 pm »
I look bit closer to your scipt and I see that it expeced more high level langrage, my scripts are more assmeble :>

setting value you use `set valueName something;`,

When I will have some free time I will fix your script.

Offline luke83

  • Commander
  • *****
  • Posts: 1443
    • View Profile
    • openxcommods
Re: Fun with Scripts
« Reply #4 on: January 23, 2019, 10:08:09 pm »
My limited exposure to programming has been VB and Python, so i dont really understand the difference between assembly vs high level other than in high level ones i dont need to manage memory.

I assume some of the sytax i have used is wrong and that is to be expected until I learn how you define things here but i look forward to keep learning as i want to get my head around your scripting options as it will be super useful moving forward on my mod.

Made some minor changes hopefully i am setting values right now:)

Code: [Select]
    ShowHealthOnSprite_on_land:
#*** Update units Health Bar graphic for each player unit***
      - offset: 1
        code: |

          var int color;
          var int HealthValue # see current health value
          var int MaxHealth # See Max Health Value
          var int HealthPercentage # Hold Percentage of Health values
          var int ColourOrange; # Mid Health
          var int ColourRed;  #low health
          var int colorToReplace # how do i select this?
          # var int newShade;
          # var int temp;
          var int hpDamageDone;

          set ColourOrange 6; # how do i know what colout is what in the pallet, how is it labeled?
          set ColourRed 2;   # how do i know what colout is what in the pallet, how is it labeled? 

          if hpDamageDone;
          set MaxHealth unit.getTag Maxhealth;
          set HealthValue unit.getTag HealthValue;
          set HealthPercentage = ( HealthValue/MaxHealth ) * 100

            if HealthPercentage <30;

            #turn RED
              get_color colorToReplace
              set_color ColourRed
              return new_pixel;

            else if HealthPecentage >30 AND <70;

            #turn ORANGE
              get_color colorToReplace
              set_color ColourOrange
              return new_pixel;

            end;

          end;
« Last Edit: January 24, 2019, 10:03:24 am by luke83 »

Offline Yankes

  • Commander
  • *****
  • Posts: 2083
    • View Profile
Re: Fun with Scripts
« Reply #5 on: January 25, 2019, 10:37:49 pm »
Code: [Select]
COLOR_X1_NULL 0
COLOR_X1_YELLOW 1
COLOR_X1_RED 2
COLOR_X1_GREEN0 3
COLOR_X1_GREEN1 4
COLOR_X1_GRAY 5
COLOR_X1_BROWN0 6
COLOR_X1_BLUE0 7
COLOR_X1_BLUE1 8
COLOR_X1_BROWN1 9
COLOR_X1_BROWN2 10
COLOR_X1_PURPLE0 11
COLOR_X1_PURPLE1 12
COLOR_X1_BLUE2 13
COLOR_X1_SILVER 14
COLOR_X1_SPECIAL 15
Predefined colors for UFO.

There fixed script:
Code: [Select]
extended:
  scripts:
    recolorUnitSprite:
      - offset: 1
        code: |
          var int color;
          var int HealthValue; # see current health value
          var int MaxHealth; # See Max Health Value
          var int HealthPercentage; # Hold Percentage of Health values
          var int ColourOrange; # Mid Health
          var int ColourRed;  #low health
          var int CurrentColor;
          var int colorToReplace COLOR_X1_GRAY; # how do i select this?
         
          set ColourOrange COLOR_X1_BROWN0;
          set ColourRed COLOR_X1_RED; 
         
         
          unit.getHealthMax  MaxHealth;
          unit.getHealth  HealthValue;
          set HealthPercentage HealthValue;
          muldiv HealthPercentage 100 MaxHealth;
         
          get_color CurrentColor new_pixel;
          if eq CurrentColor colorToReplace;
            if lt HealthPercentage 30;
              #turn RED
              set_color new_pixel ColourRed;
            else lt HealthPercentage 70;
              #turn ORANGE
              set_color new_pixel ColourOrange;
            end;
          end;
          return new_pixel;

One important thing when you write scripts, as my script have VERY simple simple syntax it only support operations like:
Code: [Select]
operation arg1 arg2 arg3 arg4;
This mean there is no `(` or `*`.

Only exception is method of game objects.
Code: [Select]
#in reality they work in this way:
BattleUnit.getHealth unit healthVariable;

#but you can write this as:
unit.getHealth healthVariable;

If you want know what is available for any script you can set `verboseLogging: true` in config file, with this in log you will get full dump of all symbols from scripts.