Author Topic: [Documentation] OXCE Y-Script examples  (Read 18566 times)

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
[Documentation] OXCE Y-Script examples
« on: January 29, 2017, 05:11:23 pm »
Parrot animation:
Code: [Select]
armors:
  - type: PARROT_ARMOR
    drawingRoutine: 4
    scripts:
      selectUnitSprite: |
        #this script will always run move animation of unit.
        var int temp;
        var int walking;
        unit.isWalking walking;
        if eq walking 0;
          unit.getId temp;
          offsetmod temp 11 0 8; #desync animation of different units
          add temp anim_frame;
          wavegen_saw temp 8 8 7;
          mul sprite_offset 8;
          add sprite_offset 8;
          add sprite_offset temp;
          set sprite_index sprite_offset;
        else;
          add sprite_index sprite_offset;
        end;
        return sprite_index;

2x2 unit animation:
Code: [Select]
armors:
  - type: TANK_ARMOR
    drawingRoutine: 20
    movementType: 1
    spriteSheet: FDEAMON.PCK
    scripts:
      selectUnitSprite: |
        var int temp;
        var int walking;
        var int floating;
        unit.isWalking walking;
        unit.isFloating floating;
        if and eq walking 0 eq floating 1;
          unit.getId temp;
          offsetmod temp 11 0 8; #desync animation of different units
          add temp anim_frame;
          wavegen_saw temp 4 4 4;
          add sprite_offset 1;
          add sprite_offset temp;
          add sprite_index sprite_offset;
        else;
          add sprite_index sprite_offset;
        end;
        return sprite_index;

Animation for Floater
Code: [Select]
  - type: FLOATER_ARMOR0
    drawingRoutine: 1
    scripts:
      selectUnitSprite: |
        var int temp;
        var int walking;
        unit.isWalking walking;
        if and eq walking 0 eq blit_part BODYPART_TORSO;
          unit.getId temp;
          offsetmod temp 11 0 8; #desync animation of different units
          add temp anim_frame;
          wavegen_saw temp 5 5 5;
         
         
          mul sprite_offset 5; # `drawingRoutine: 1` have blocks of 5 frames per direction, we convert `0,1,2,...` to `0,5,10,...` offsets
          add sprite_offset temp;
         
          add sprite_index 8; #moving animations frames starts after 8 standing one
          add sprite_index sprite_offset;
        else;
          add sprite_index sprite_offset;
        end;
        return sprite_index;

Hit confirm by red "flash":
Code: [Select]
extended:
  tags:
    BattleUnit:
      LAST_HIT_FRAME: int

  scripts:
    damageUnit:
      - offset: 10
        code: |
          var int temp;
          battle_game.getAnimFrame temp;
          unit.setTag Tag.LAST_HIT_FRAME temp;
          return;

    recolorUnitSprite:
      - offset: 10
        code: |
          var int temp;
         
          unit.getTag temp Tag.LAST_HIT_FRAME;
          if neq temp 0;
            sub temp anim_frame;
            if gt temp -3; #only 3 frames after hit have changed color
              set_color new_pixel 2; #red color
            end;
          end;
         
          return new_pixel;
         
« Last Edit: February 12, 2023, 03:09:13 pm by Meridian »

Offline ohartenstein23

  • Commander
  • *****
  • Posts: 1933
  • Flamethrowers fry cyberdisk circuits
    • View Profile
Re: OXCE Script examples
« Reply #1 on: January 31, 2017, 08:17:14 pm »
Changing a weapon's sprites based on the ammunition loaded:
Code: [Select]
extended:
  tags: # Remember to add these tags to the same file as items ruleset
    RuleItem:
      ALLOW_AMMO_TO_RESPRITE: int
      NEW_BIGOB_FOR_WEAPON: int
      NEW_FLOOROB_FOR_WEAPON: int
      NEW_HANDOB_FOR_WEAPON: int
      CURRENT_MOD_OFFSET: RuleList

  scripts:
    selectItemSprite:
# Select weapon bigSprite based on ammo item
      - offset: 1
        code: |
          var ptr BattleItem ammoItem;
          var ptr RuleItem weaponRuleset;
          var ptr RuleItem ammoRuleset;
          var int doResprite;
          var int newSprite;
          var int modOffset;

          if eq blit_part blit_item_big;
            item.getRuleItem weaponRuleset;
            weaponRuleset.getTag doResprite Tag.ALLOW_AMMO_TO_RESPRITE;

            if eq doResprite 1;
              item.getAmmoItem ammoItem;
              ammoItem.getRuleItem ammoRuleset;
              ammoRuleset.getTag newSprite Tag.NEW_BIGOB_FOR_WEAPON;

              if neq newSprite 0;
                ammoRuleset.getTag sprite_index Tag.NEW_BIGOB_FOR_WEAPON;
                ammoRuleset.getTag modOffset Tag.CURRENT_MOD_OFFSET;
                rules.getSpriteOffsetBigobs sprite_index modOffset;
                return sprite_index;

              end;

            end;

          end;

          return sprite_index;

# Select weapon floorSprite based on ammo item
      - offset: 2
        code: |
          var ptr BattleItem ammoItem;
          var ptr RuleItem weaponRuleset;
          var ptr RuleItem ammoRuleset;
          var int doResprite;
          var int newSprite;
          var int modOffset;

          if eq blit_part blit_item_floor;
            item.getRuleItem weaponRuleset;
            weaponRuleset.getTag doResprite Tag.ALLOW_AMMO_TO_RESPRITE;

            if eq doResprite 1;
              item.getAmmoItem ammoItem;
              ammoItem.getRuleItem ammoRuleset;
              ammoRuleset.getTag newSprite Tag.NEW_FLOOROB_FOR_WEAPON;

              if neq newSprite 0;
                ammoRuleset.getTag sprite_index Tag.NEW_FLOOROB_FOR_WEAPON;
                ammoRuleset.getTag modOffset Tag.CURRENT_MOD_OFFSET;
                rules.getSpriteOffsetFloorob sprite_index modOffset;
                return sprite_index;

              end;

            end;

          end;

          return sprite_index;

# Select weapon handSprite based on ammo item
      - offset: 3
        code: |
          var ptr BattleItem ammoItem;
          var ptr RuleItem weaponRuleset;
          var ptr RuleItem ammoRuleset;
          var int doResprite;
          var int newSprite;
          var int modOffset;

          if or eq blit_part blit_item_lefthand eq blit_part blit_item_righthand;
            item.getRuleItem weaponRuleset;
            weaponRuleset.getTag doResprite Tag.ALLOW_AMMO_TO_RESPRITE;

            if eq doResprite 1;
              item.getAmmoItem ammoItem;
              ammoItem.getRuleItem ammoRuleset;
              ammoRuleset.getTag newSprite Tag.NEW_HANDOB_FOR_WEAPON;

              if neq newSprite 0;
                add newSprite sprite_offset;
                set sprite_index newSprite;

                ammoRuleset.getTag modOffset Tag.CURRENT_MOD_OFFSET;
                rules.getSpriteOffsetBigobs sprite_index modOffset;
                return sprite_index;

              end;

            end;

          end;

          return sprite_index;

Set the tag ALLOW_AMMO_TO_RESPRITE: 1 on the weapon you wish to change sprites, then on the ammunition you wish to do the change for, set NEW_BIGOB_FOR_WEAPON, NEW_FLOOROB_FOR_WEAPON, and NEW_HANDOB_FOR_WEAPON tags to the sprites you want, and add CURRENT_MOD_OFFSET: current to the tags as well.

Note: with the way tags are handled, this will not change sprites if you choose a sprite index of 0.  Also, since Handobs are lacking a proper function for getting the mod offset (coming in OXCE 3.7), this may not work if you have mods with different index offsets for handobs and bigobs - you can check your verbose log to see if the offsets are the same or not.

Also, this may not be useful if you want to have multiple weapons changing sprites but all share the same types of ammunition - I'll probably work fixing that at some point.
« Last Edit: January 31, 2017, 08:29:52 pm by ohartenstein23 »

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
Re: OXCE Script examples
« Reply #2 on: February 01, 2017, 12:31:34 am »
Simple poison bullets that do damage over time:

Code: [Select]
extended:
  tags:
    RuleItem:
      POISON_STRENGTH: int
    RuleArmor:
      POISON_SUSCEPTIBILITY: int
    BattleUnit:
      POISON_LEVEL: int
  scripts:
    damageUnit:
      - offset: 1
        code: |
          var int susceptibility 0;
          var int strength 0;
          var int temp 0;
          var ptr RuleArmor armor_rule;
          var ptr RuleItem item_rule;
         
          unit.getRuleArmor armor_rule;
          armor_rule.getTag susceptibility Tag.POISON_SUSCEPTIBILITY;
          damaging_item.getRuleItem item_rule;
          item_rule.getTag strength Tag.POISON_STRENGTH;
         
          debug_log 1 strength;
          debug_log 2 susceptibility;
          if and gt strength 0 gt susceptibility 0;
          debug_log 3 3;
            mul strength susceptibility;
            div strength 10;
            unit.getTag temp Tag.POISON_LEVEL;
            if lt temp strength;
              unit.setTag Tag.POISON_LEVEL strength;
            end;
          end;
         
          return;
    newTurnUnit:
      - offset: 1
        code: |
          var int poison;
          var int hp;
          unit.getTag poison Tag.POISON_LEVEL;
          if gt poison 0;
            unit.getHealth hp;
            sub hp poison;
            unit.setHealth hp;
            sub poison 1;
            unit.setTag Tag.POISON_LEVEL poison;
          end;
          return;
    recolorUnitSprite:
      - offset: 4
        code: |
          var int poison;
          unit.getTag poison Tag.POISON_LEVEL;
          if gt poison 0;
            set_color new_pixel 4; #green color
          end;
          return new_pixel;
items:
  - type: STR_PISTOL_CLIP
    tags:
      POISON_STRENGTH: 6
     

armors:
  - type: STR_SOME_MARTIAN
    tags:
      POISON_SUSCEPTIBILITY: 20


Laser rifle with overcharge, be careful it last only limited time and weapon is destroyed after that. But during this time you will melt all enemies.
Code: [Select]
extended:
  tags:
    RuleItem:
      OVERCHARGE_WEAPON: int
     
  scripts:
    hitUnit:
      - offset: 1
        code: |
          var int temp;
          var int primed;
          var ptr RuleItem rule;
          damaging_item.getRuleItem rule;
          damaging_item.getFuseTimer primed;
          rule.getTag temp Tag.OVERCHARGE_WEAPON;
          if and gt temp 0 gt primed 0;
            unit.reduceByResistance temp 4; #4 - laser damage type
            add power temp;
          end;
          return power part side; #part - body part, side - armor side
items:
  - type: STR_LASER_RIFLE
    fuseType: 3
    isExplodingInHands: true
    isConsumable: true #when primed is not recoverable anymore
    primeActionName: STR_LASER_RIFLE_OVERCHARGE
    primeActionMessage: STR_LASER_RIFLE_OVERCHARGE_MESSAGE
    tags:
      OVERCHARGE_WEAPON: 50
    scripts:
      recolorItemSprite: |
        var int color;
        var int temp;
        get_color color new_pixel;
        if eq color 2;
          item.getFuseTimer temp;
          if gt temp 0;
            set temp anim_frame;
            wavegen_tri temp 16 16 15;
            mul temp -1;
            add temp 8;
            add_shade new_pixel temp;
          else;
            set_shade new_pixel 15;
          end;
        end;
        return new_pixel;

extraStrings:
  - type: en-US
    strings:
      STR_LASER_RIFLE_OVERCHARGE: "Overcharge"
      STR_LASER_RIFLE_OVERCHARGE_MESSAGE: "Rifle is Overcharged"
   

Offline ohartenstein23

  • Commander
  • *****
  • Posts: 1933
  • Flamethrowers fry cyberdisk circuits
    • View Profile
Re: OXCE Script examples
« Reply #3 on: February 01, 2017, 05:17:06 pm »
'Vampiric' weapons, items, and armor:
Code: [Select]
extended:
  tags: # Remember to add tag definitions to same file as item/armor rulesets!
    RuleItem:
      DAMAGE_RETURNED_AS_HP: int
      DAMAGE_RETURNED_RESIST_TYPE: int
    RuleArmor:
      DAMAGE_RETURNED_AS_HP_BUFF: int
      DAMAGE_RETURNED_RESIST_TYPE_ARMOR: int

  scripts:
    damageUnit:
      - offset: 3
        code: |
          var ptre BattleUnit attackingUnit;
          var ptre BattleItem attackingItem;
          var ptr RuleItem itemRuleset;
          var ptr RuleArmor attackerArmor;
          var int hpReturnedCoefficient;
          var int hpReturnedResistType;
          var int hpDamageDone;
          var int hpTarget;
          var int hpAttacker;
          var int hpMaxAttacker;
          var int hpReturned;
          var int temp;

          damaging_item.getRuleItem itemRuleset;
          itemRuleset.getTag hpReturnedCoefficient Tag.DAMAGE_RETURNED_AS_HP;

          damaging_item.getOwner attackingUnit;
          attackingUnit.getLeftHandWeapon attackingItem;
          if and neq attackingItem null neq attackingItem damaging_item;
            attackingItem.getRuleItem itemRuleset;
            itemRuleset.getTag temp Tag.DAMAGE_RETURNED_AS_HP;
            add hpReturnedCoefficient temp;
          end;
          attackingUnit.getRightHandWeapon attackingItem;
          if and neq attackingItem null neq attackingItem damaging_item;
            attackingItem.getRuleItem itemRuleset;
            itemRuleset.getTag temp Tag.DAMAGE_RETURNED_AS_HP;
            add hpReturnedCoefficient temp;
          end;

          attackingUnit.getRuleArmor attackerArmor;
          attackerArmor.getTag temp Tag.DAMAGE_RETURNED_AS_HP_BUFF;
          add hpReturnedCoefficient temp;

          if eq hpReturnedCoefficient 0;
            return;
          else;
            unit.getHealth hpTarget;
            set hpDamageDone to_health;
            if gt hpDamageDone hpTarget;
              set hpReturned hpTarget;
            else;
              set hpReturned hpDamageDone;
            end;

            mul hpReturned hpReturnedCoefficient;
            div hpReturned 100;

            itemRuleset.getTag hpReturnedResistType Tag.DAMAGE_RETURNED_RESIST_TYPE;
            if eq hpReturnedResistType 0;
              attackerArmor.getTag hpReturnedResistType Tag.DAMAGE_RETURNED_RESIST_TYPE_ARMOR;
            end;
            unit.reduceByResistance hpReturned hpReturnedResistType;

            attackingUnit.getHealth hpAttacker;
            attackingUnit.getHealthMax hpMaxAttacker;
            add hpReturned hpAttacker;

            if gt hpReturned hpMaxAttacker;
              attackingUnit.setHealth hpMaxAttacker;
            else;
              attackingUnit.setHealth hpReturned;
            end;
          end;

          return;

items:
   - type: STR_SOME_WEAPON_OR_HELD_ITEM
     tags:
       DAMAGE_RETURNED_AS_HP: 10
       DAMAGE_RETURNED_RESIST_TYPE: 6
armors:
   - type: STR_SOME_ARMOR
     tags:
       DAMAGE_RETURNED_AS_HP_BUFF: 20

When you deal damage to a target, the items in your soldier's hands and their armor is checked for these tags, so the vampirism is an additive percent of damage done (e.g. item1: 10 + item2: 5 + armor: 15 = 30% of health damage done is returned), and modified by the chosen resist type on the enemy, so you can choose which enemies from which you suck blood by resistances.

Offline crutchmaster

  • Squaddie
  • *
  • Posts: 6
    • View Profile
Re: OXCE Script examples
« Reply #4 on: February 02, 2017, 10:41:50 am »
Code: [Select]

if and eq walking 0 eq floating 1;
...
offsetmod temp 11 0 8;
...
if and neq attackingItem null neq attackingItem damaging_item;
I require ECMA support.

Offline ohartenstein23

  • Commander
  • *****
  • Posts: 1933
  • Flamethrowers fry cyberdisk circuits
    • View Profile
Re: OXCE Script examples
« Reply #5 on: February 03, 2017, 07:51:17 pm »
Inspired by the example of the overcharged laser using priming as a mechanic, I present single-use personal energy shields!

Code: [Select]
extended:
  tags:
    RuleItem:
      ENERGY_SHIELD_CAPACITY: int
      ENERGY_SHIELD_PER_TURN: int
    BattleItem:
      ENERGY_SHIELD_HP: int
      ENERGY_SHIELD_IS_PRIMED: int
    BattleUnit:
      UNIT_RECOLOR_COLOR: int
      UNIT_RECOLOR_START_FRAME: int
      UNIT_RECOLOR_FRAME_LENGTH: int

  scripts:
    hitUnit:
      - offset: 1
        code: |
          var ptre BattleItem shieldItem;
          var ptr RuleItem shieldRule;
          var int shieldCapacity;
          var int shieldTimer;
          var int shieldHp;
          var int temp;

          # Script to handle consumable (primed) energy shields on hit
          # Check for item in left hand
          unit.getLeftHandWeapon shieldItem;

          if neq shieldItem null;
            # Check to see if the item has a shield capacity tag
            shieldItem.getRuleItem shieldRule;
            shieldRule.getTag shieldCapacity Tag.ENERGY_SHIELD_CAPACITY;

            if neq shieldCapacity 0;
              shieldItem.getFuseTimer shieldTimer;

              if gt shieldTimer 0; # Primed consumable shields have positive timer
                shieldItem.getTag temp Tag.ENERGY_SHIELD_IS_PRIMED;

                if eq temp 0; # If we just primed and haven't been hit yet, need to set shield HP
                  shieldItem.setTag Tag.ENERGY_SHIELD_IS_PRIMED 1;
                  shieldItem.setTag Tag.ENERGY_SHIELD_HP shieldCapacity;
                end;

                # Get the item's HP value and reduce damage by it
                # Resistance consideration goes here when Yankes gets to it
                shieldItem.getTag shieldHp Tag.ENERGY_SHIELD_HP;
                set temp shieldHp;
                sub temp power; # get shield value leftover after hit
                sub power shieldHp; # reduce hit by hp

                # Apply limits to make sure no negative power/HP
                limit_lower power 0;
                limit_lower temp 0;

                # Set the shield's new HP value
                shieldItem.setTag Tag.ENERGY_SHIELD_HP temp;

                # Make the unit flash a color to denote shield was hit
                if and gt temp 0 eq power 0; # But only if shield is left over
                  battle_game.getAnimFrame temp;
                  unit.setTag Tag.UNIT_RECOLOR_START_FRAME temp;
                  unit.setTag Tag.UNIT_RECOLOR_FRAME_LENGTH 3;
                  unit.setTag Tag.UNIT_RECOLOR_COLOR COLOR_X1_BLUE1; # add tag to configure?
                end;
              end;
            end;
          end;

          # Now do it for a right hand shield
          unit.getRightHandWeapon shieldItem;

          if neq shieldItem null;
            # Check to see if the item has a shield capacity tag
            shieldItem.getRuleItem shieldRule;
            shieldRule.getTag shieldCapacity Tag.ENERGY_SHIELD_CAPACITY;

            if neq shieldCapacity 0;
              shieldItem.getFuseTimer shieldTimer;

              if gt shieldTimer 0; # Primed consumable shields have positive timer
                shieldItem.getTag temp Tag.ENERGY_SHIELD_IS_PRIMED;

                if eq temp 0; # If we just primed and haven't been hit yet, need to set shield HP
                  shieldItem.setTag Tag.ENERGY_SHIELD_IS_PRIMED 1;
                  shieldItem.setTag Tag.ENERGY_SHIELD_HP shieldCapacity;
                end;

                # Get the item's HP value and reduce damage by it
                # Resistance consideration goes here when Yankes gets to it
                shieldItem.getTag shieldHp Tag.ENERGY_SHIELD_HP;
                set temp shieldHp;
                sub temp power; # get shield value leftover after hit
                sub power shieldHp; # reduce hit by hp

                # Apply limits to make sure no negative power/HP
                limit_lower power 0;
                limit_lower temp 0;

                # Set the shield's new HP value
                shieldItem.setTag Tag.ENERGY_SHIELD_HP temp;

                # Make the unit flash a color to denote shield was hit
                if and gt temp 0 eq power 0; # But only if shield is left over
                  battle_game.getAnimFrame temp;
                  unit.setTag Tag.UNIT_RECOLOR_START_FRAME temp;
                  unit.setTag Tag.UNIT_RECOLOR_FRAME_LENGTH 3;
                  unit.setTag Tag.UNIT_RECOLOR_COLOR COLOR_X1_BLUE1; # add tag to configure?
                end;
              end;
            end;
          end;

          # return modified power
          return power part side;

    recolorUnitSprite:
      - offset: 10
        code: |
          var int frame;
          var int frameLength;
          var int color;
          var int temp;

          unit.getTag frame Tag.UNIT_RECOLOR_START_FRAME;
          unit.getTag frameLength Tag.UNIT_RECOLOR_FRAME_LENGTH;

          if neq frame 0;
            set temp anim_frame;
            sub temp frame;

            if lt temp frameLength;
              unit.getTag color Tag.UNIT_RECOLOR_COLOR;
              set_color new_pixel color;
            end;
          end;

          return new_pixel;

    recolorItemSprite:
      - offset: 10
        code: |
          var ptr RuleItem shieldItem;
          var int shieldCapacity;
          var int shieldTimer;
          var int shieldHp;
          var int shieldPercent;
          var int shieldIsPrimed;
          var int color;
          var int shadeIndex;
          var int temp;

          item.getRuleItem shieldItem;
          shieldItem.getTag shieldCapacity Tag.ENERGY_SHIELD_CAPACITY;

          if eq shieldCapacity 0;
            return new_pixel;
          else;
            item.getFuseTimer shieldTimer;

            if gt shieldTimer 0;
              item.getTag shieldHp Tag.ENERGY_SHIELD_HP;
              set shieldPercent shieldHp;
              muldiv shieldPercent 100 shieldCapacity;

              item.getTag shieldIsPrimed Tag.ENERGY_SHIELD_IS_PRIMED;
              if eq shieldIsPrimed 0; # Haven't been hit yet, but should show shield
                set shieldPercent 100;
              end;

              # Choose color to replace on sprite
              get_color color new_pixel;

              if eq color COLOR_X1_YELLOW;
                get_shade shadeIndex new_pixel;

                if gt shieldPercent 20; # Choose critical shields at 20%, make tag later?
                  set color COLOR_X1_BLUE1;
                else;
                  set color COLOR_X1_RED;
                end;

                set temp shieldPercent;
                sub temp 100;
                abs temp;
                muldiv temp 15 100;
                add shadeIndex temp;
                limit shadeIndex 0 15;
                set_color new_pixel color;
                set_shade new_pixel shadeIndex;
              end;
            end;
          end;

          return new_pixel;

    newTurnItem:
      - offset: 2
        code: |
          var ptr RuleItem shieldRule;
          var int shieldCapacity;
          var int shieldTimer;
          var int shieldIsPrimed;
          var int shieldPerTurn;
          var int shieldHp;
          var int temp;

          # Recharge/decay handling for consumable shield items
          item.getRuleItem shieldRule;
          shieldRule.getTag shieldCapacity Tag.ENERGY_SHIELD_CAPACITY;

          if eq shieldCapacity 0;
            return;
          else;
            item.getFuseTimer shieldTimer;

            if gt shieldTimer 0; # Consumable shields have positive timers when on
              # Make sure it's primed, if not, do so now
              item.getTag shieldIsPrimed Tag.ENERGY_SHIELD_IS_PRIMED;

              if eq shieldIsPrimed 0;
                item.setTag Tag.ENERGY_SHIELD_IS_PRIMED 1;
                item.setTag Tag.ENERGY_SHIELD_HP shieldCapacity;
              end;

              shieldRule.getTag shieldPerTurn Tag.ENERGY_SHIELD_PER_TURN;
              item.getTag shieldHp Tag.ENERGY_SHIELD_HP;

              # Recharge/decay shield, respecting capacity and 0
              add shieldHp shieldPerTurn;
              limit shieldHp 0 shieldCapacity;
              item.setTag Tag.ENERGY_SHIELD_HP shieldHp;
            end;
          end;

          return;

items:
  - type: STR_PERSONAL_SHIELD
    battleType: 10
    tags:
      ENERGY_SHIELD_CAPACITY: 50
      ENERGY_SHIELD_PER_TURN: -5
    bigSprite: 55
    floorSprite: 72
    costBuy: 5000
    power: 20
    fuseType: 5
    costPrime:
      time: 25
    primeActionName: STR_PRIME_ENERGY_SHIELD
    primeActionMessage: STR_ENERGY_SHIELD_ACTIVE
    unprimeActionMessage: STR_ENERGY_SHIELD_INACTIVE
    isConsumable: true
    isExplodingInHands: true

extraStrings:
  - type: en-US
    strings:
      STR_PERSONAL_SHIELD: "Personal Shield"
      STR_PRIME_ENERGY_SHIELD: "Activate Shield"
      STR_ENERGY_SHIELD_ACTIVE: "Shield is Active"
      STR_ENERGY_SHIELD_INACTIVE: "Shield is Inactive"

Prime before battle and that rookie can (mostly) safely run down the Skyranger ramp!

Edit:  Needed to tweak a bit after testing.  Also, I should tell you it only works if you're holding it in your hand when you're hit!
« Last Edit: February 03, 2017, 09:35:17 pm by ohartenstein23 »

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
Re: OXCE Script examples
« Reply #6 on: February 10, 2017, 09:30:45 pm »
Script for OXCE+ where is more than 10 damage types, instead of using them as separate damage types you can use them as sub-resistances:
Code: [Select]
extended:
  scripts:
    damageUnit:
      - offset: 50
        code: |
          unit.reduceByResistance to_health 10;
          unit.reduceByResistance to_stun 11;
          unit.reduceByResistance to_time 12;
          unit.reduceByResistance to_wound 13;
          unit.reduceByResistance to_energy 14;
          unit.reduceByResistance to_morale 15;
          return;
extraStrings:
  - type: en-US
    strings:
      STR_DAMAGE_10: "Health damage multipler"
      STR_DAMAGE_11: "Stun damage multipler"
      STR_DAMAGE_12: "Time damage multipler"
      STR_DAMAGE_13: "Wound damage multipler"
      STR_DAMAGE_14: "Energy damage multipler"
      STR_DAMAGE_15: "Morale damage multipler"

Offline KingMob4313

  • Commander
  • *****
  • Posts: 543
  • Never let me down again.
    • View Profile
    • Mod Hub for Equal Terms 2.0
Re: [Documentation] OXCE Script examples
« Reply #7 on: July 10, 2020, 07:33:16 am »
My first script

A script I am using for my stream to keep soldiers from being wounded more than 13 days.

Code: [Select]
    returnFromMissionUnit:
      - offset: -2 # Changing injured time to less than 13
        code: |
          var int currentRecoveryDays 0;
          var int maxRecoveryDays 13;
          var int newRecoveryDays 0;
          debug_log "Original Recovery Time:" recovery_time;
          set currentRecoveryDays recovery_time;
          div currentRecoveryDays 5;
          debug_log "Changed Recovery Time:" currentRecoveryDays;
          if gt currentRecoveryDays 13;
            debug_log "Changed MAX Days Recovery from" currentRecoveryDays;
            set currentRecoveryDays 13;
          end;
          set recovery_time currentRecoveryDays;
          return;

Offline cevaralien

  • Captain
  • ***
  • Posts: 96
    • View Profile
Re: [Documentation] OXCE Script examples
« Reply #8 on: September 06, 2020, 05:30:03 pm »
Post edited/removed by Meridian, please use this thread only to post working scripts you want to share with others.

Original post here: https://openxcom.org/forum/index.php/topic,8476.msg131427.html#msg131427
« Last Edit: September 06, 2020, 06:59:01 pm by Meridian »

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
Re: [Documentation][y-script] OXCE Script examples
« Reply #9 on: February 19, 2021, 09:15:08 pm »
Code what find all units that are 2 tile way from `unit`
Code: [Select]

          begin;
            var int range 2;
            var int l 0;
            var int rangeVoxel;
            var int sx;
            var int sy;
            var int sz;
            var ptr Tile st;
           
            unit.getPosition.getX sx;
            unit.getPosition.getY sy;
            unit.getPosition.getZ sz;
            battle_game.getTile st sx sy sz;
           
            set l range;
            mul l 2;
            add l 1;
           
            set rangeVoxel range;
            mul rangeVoxel 16;
            add rangeVoxel 8; #half tile buffer for max distance
           
            loop var x l;
              add x sx;
              sub x range;
             
              loop var y l;
                add y sy;
                sub y range;
               
                loop var z l;
                  add z sz;
                  sub z range;
                 
                  begin;
                    var ptr Tile t;
                    var int tileDistance;
                    var ptr BattleUnit bu;
                   
                    battle_game.getTile t x y z;
                    t.getUnit bu;
                    st.getDistanceVoxel tileDistance t;
                    if and neq bu null gt tileDistance 0 lt tileDistance rangeVoxel;
                     
                      #check other close units
                      debug_log "unit" bu "at" t;
                    end;
                  end;
                end;
              end;
            end;
           
          end;

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3350
    • View Profile
Re: [Documentation][y-script] OXCE Script examples
« Reply #10 on: February 21, 2021, 06:07:47 pm »
Iterate whole inventory of unit and special weapons (like buildin alien PSI attack)
Code: [Select]
          begin;
            var int size;
            unit.getInventoryItem.size size;
            loop var i size;
              var ptre BattleItem item;
              unit.getInventoryItem item i;
             
              debug_log "unit" unit "have in inv" item;
            end;
          end;
         
          begin;
            var int size;
            unit.getSpecialItem.size size;
            loop var i size;
              var ptre BattleItem item;
              unit.getSpecialItem item i;
             
              debug_log "unit" unit "have in spec" item;
            end;
          end;

result:

Code: [Select]
[21-02-2021_17-04-09] [DEBUG] Script debug log: unit BattleUnit(type: "STR_ETHEREAL_SOLDIER" race: "STR_ETHEREAL" id: 1000017 faction: Hostile hp: 1/100) have in inv BattleItem(name: "STR_HEAVY_PLASMA" id: 117)
[21-02-2021_17-04-09] [DEBUG] Script debug log: unit BattleUnit(type: "STR_ETHEREAL_SOLDIER" race: "STR_ETHEREAL" id: 1000017 faction: Hostile hp: 1/100) have in inv BattleItem(name: "STR_ALIEN_GRENADE" id: 119)
[21-02-2021_17-04-09] [DEBUG] Script debug log: unit BattleUnit(type: "STR_ETHEREAL_SOLDIER" race: "STR_ETHEREAL" id: 1000017 faction: Hostile hp: 1/100) have in inv BattleItem(name: "STR_HEAVY_PLASMA_CLIP" id: 120 ammo: 35/35)
[21-02-2021_17-04-09] [DEBUG] Script debug log: unit BattleUnit(type: "STR_ETHEREAL_SOLDIER" race: "STR_ETHEREAL" id: 1000017 faction: Hostile hp: 1/100) have in spec BattleItem(name: "ALIEN_PSI_WEAPON" id: 116)

Offline Finnik

  • Commander
  • *****
  • Posts: 508
  • Finnik#0257
    • View Profile
Re: [Documentation][y-script] OXCE Script examples
« Reply #11 on: February 23, 2021, 11:55:47 pm »
That is overcool! Last argument like bah, YS is not so cool as Lua or Python has fallen in my eyes. Great job!

Offline scarf

  • Sergeant
  • **
  • Posts: 27
  • hello world
    • View Profile
    • reddit page
Re: [Documentation][y-script] OXCE Script examples
« Reply #12 on: April 20, 2021, 01:23:04 pm »
1. Environmental Damages
script that deals additional environmental damage (smoke & fire) to units every turn. also getSmoke gets the intensity of EITHER FIRE or SMOKE (thanks meridian)

Code: [Select]

extended:
  scripts:
    newTurnUnit:
      - offset: 2
        code: |
          var int LOG 0; # 0: none; 1: simple 2: detailed


          var ptr Tile tile_info;


          var int x;
          var int y;
          var int z;


          var int Hazard_Intensity;
          var int Fire_Duration;


          unit.getPosition.getX x;
          unit.getPosition.getY y;
          unit.getPosition.getZ z;


          battle_game.getTile tile_info x y z;


          tile_info.getSmoke Hazard_Intensity;
          tile_info.getFire Fire_Duration;
          #debug_log "hazard intensity:" Hazard_Intensity "fire duration:" Fire_Duration;


          if and gt Fire_Duration 0 gt Hazard_Intensity 0;
            begin;
              var int Fire_Damage 0;
              var int Total_Fire_Damage 0;


              var ptr RuleArmor Unit_Armor;
              var int Unit_Size; # 1 for small, 2 for big
              var int Unit_Armor_Under;
              var int Resist_Under 70;


              unit.getRuleArmor Unit_Armor;
              Unit_Armor.getSize Unit_Size;
              Unit_Armor.getArmor Unit_Armor_Under 4;
              sub Resist_Under Unit_Armor_Under;




              if ge LOG 1;debug_log "trauma report for:" unit;end;
              if ge LOG 1;debug_log "original hazard intensity:" Hazard_Intensity;end;
              if ge LOG 2;debug_log " armor size" Unit_Size;end;


              #normalizing
              # from 01 02 03 04 05 06 07 08 09 10 11 12
              # to   06 06 06 06 07 07 07 07 08 08 08 08
              if gt Hazard_Intensity 8;
                set Hazard_Intensity 8;
              else gt Hazard_Intensity 4;
                set Hazard_Intensity 7;
              else gt Hazard_Intensity 0;
                set Hazard_Intensity 6;
              end;
              if gt Unit_Size 1;
                div Hazard_Intensity 4;
              end;
              if ge LOG 2;debug_log "normalized hazard intensity:" Hazard_Intensity;end;
              loop var i Hazard_Intensity;
                #set Fire_Damage Hazard_Intensity;
                battle_game.randomRange Fire_Damage 0 Hazard_Intensity;
                unit.reduceByResistance Fire_Damage 2;
                mul Fire_Damage Resist_Under;
                div Fire_Damage 70; # under armor over 70 completely negates fire damage
                mul Fire_Damage -1;
                if ge LOG 2;debug_log "   fire damage for loop" i ":" Fire_Damage;end;
                if lt Fire_Damage 0;
                  unit.addHealth Fire_Damage;
                  unit.addMorale Fire_Damage;
                  add Total_Fire_Damage Fire_Damage;
                end;
              end;
              if ge LOG 1;debug_log "total fire damage [" Total_Fire_Damage "]";end;
              #adds fatal damage (2x2 units are immune)
              if and le Total_Fire_Damage -10 eq Unit_Size 1;
                # START WOUNDED_PART
                # TORSO 1 RL 4 LL 5
                var int Wounded_Part;
                battle_game.randomRange Wounded_Part 3 5;
                if eq Wounded_Part 3; sub Wounded_Part 2; end;
                # FINISH WOUNDED PART
                mul Total_Fire_Damage -1;
                div Total_Fire_Damage 2;
                battle_game.randomRange Total_Fire_Damage 1 Total_Fire_Damage;
                unit.addFatalwounds Wounded_Part Total_Fire_Damage;
                if ge LOG 1;debug_log Total_Fire_Damage "wound to" Wounded_Part;end;
              end;
            end;
          else gt Hazard_Intensity 0;
            div Hazard_Intensity 4;
            battle_game.randomRange Hazard_Intensity 0 Hazard_Intensity;
            unit.reduceByResistance Hazard_Intensity 9;
            if gt Hazard_Intensity 0;
              if ge LOG 1;debug_log "total smoke damage:" Hazard_Intensity;end;
              unit.addStun Hazard_Intensity;
            end;
          end;
          return;



2. More Fatal Wounds
this script overrides vanilla fatal wound limit of 1 to 3. code below deals roughly 1/4 inflicted damage to fatal wounds.
Code: [Select]

extended:
  scripts:
    damageUnit:
      - offset: 1
        code: |
          var int LOG 2; # 0: none; 1: simple 2: detailed


          var int Temp 0;


          if ge LOG 2;debug_log "start:" to_health to_wound unit;end;


          set to_wound 0;


          loop var i to_health;
            battle_game.randomRange Temp 0 3; #25% chance
            if eq Temp 0; add to_wound 1;end;
          end;


          if ge LOG 1;debug_log "end:" to_health to_wound;end;
          return;
3. Fatal Wounds inflict Moral Loss
Code: [Select]

extended:
  scripts:
    newTurnUnit:
      - offset: 1
        code: |
          var int Fatal_Wounds;
          var int Moral_Damage;


          unit.getFatalwoundsTotal Fatal_Wounds;


          if gt Fatal_Wounds 0;
            begin;
              loop var i 4;
                unit.reduceByBravery Fatal_Wounds;
                battle_game.randomRange Moral_Damage 0 Fatal_Wounds;
                mul Moral_Damage -1;
                unit.addMorale Moral_Damage;
                #debug_log "moral dmg:" Moral_Damage;
              end;
            end;
          end;
          return;
4. Automatic Priming
script that automatically primes grenades tagged as START_PRIMED. newTurnItem methods are preferred as it does not prime grenades on floor.

  • code attached on createItem automatically primes grenades regardless its position if it's tagged. (since items can be created 'before' start of mission, you can't search for grenade that isn't on ground then prime it)
  • code attached on newTurnItem only primes grenades if it's tagged and also start of mission (turn 1) and not on ground (so no introductory crash mission explosions from dead aliens and havoc from 20 primed grenades on skyranger floor).
Code: [Select]
extended:
  tags:
    RuleItem:
      START_PRIMED: int
  scripts:
    newTurnItem:
      - offset: 52
        code: |
          var int Current_Turn;
          battle_game.getTurn Current_Turn;


          if eq Current_Turn 1;
            var ptr RuleInventory Items_Inventory;
            var int Inventory_Slot;
            item.getSlot Items_Inventory;
            Items_Inventory.getType Inventory_Slot;


            if neq Inventory_Slot INV_GROUND;
              var int Start_Primed;
              item.getTag Start_Primed Tag.START_PRIMED;


              if eq Start_Primed 1;
                item.setFuseTimer 0;
                return;
              end;
            end;
          end;
          return;

5. change ammo sprite by rounds left
Code: [Select]
extended:
  tags:
    RuleItem:
      ALLOW_AMMO_TO_RESPRITE: int # 0: NO, 1 ~ 4: how many ammos to compute, recommended max 3
      PAEDIA_OFFSET: int # on ufopaedia weapon on max loadout is shown; negates that offset. usu. sum of ommo offsets
      OFFSET_BIGOB_WEAPON: int # 0: empty, 1 ~ 4: ammo type 1 ~ 4
  scripts:
    selectItemSprite:
      - offset: 1
        code: |
          var int Ammo_Types;


          if eq blit_part blit_item_big; # if blit_part == blit_item_big; -> on bliting big item
            item.getTag Ammo_Types Tag.ALLOW_AMMO_TO_RESPRITE; # find matching tag: ALLOW_AMMO_TO_RESPRITE


            if gt Ammo_Types 0; # if Ammo_Types > 0; -> tagged as resprite
              var int Paedia_Offset;
              var int Ammo_Offset;
              var ptr BattleItem Loaded_Ammo;


              # NEGATES PEDIA OFFSET
              item.getTag Paedia_Offset Tag.PAEDIA_OFFSET;
              sub sprite_index Paedia_Offset;


              # LOOP THROUGH AMMO SLOTS
              loop var i Ammo_Types;
                item.getAmmoForSlot Loaded_Ammo i; # get ammo item as Loaded_Ammo
                Loaded_Ammo.getTag Ammo_Offset Tag.OFFSET_BIGOB_WEAPON; # find offset value as Ammo_Offset
                add sprite_index Ammo_Offset; # ammo offset applied to sprite_index
              end;
            end;
          end;
          return sprite_index;
« Last Edit: October 03, 2022, 11:45:48 am by greenscarf »

Offline Meridian

  • Global Moderator
  • Commander
  • *****
  • Posts: 9101
    • View Profile
Re: [Documentation][y-script] OXCE Script examples
« Reply #13 on: April 20, 2021, 02:00:01 pm »
`getFire` is not fire intensity, it's fire duration

fire intensity is in `getSmoke`

Offline scarf

  • Sergeant
  • **
  • Posts: 27
  • hello world
    • View Profile
    • reddit page
Re: [Documentation][y-script] OXCE Script examples
« Reply #14 on: April 20, 2021, 02:38:38 pm »
`getFire` is not fire intensity, it's fire duration

fire intensity is in `getSmoke`


oh, I've misunderstood, changed it to more suitable one. thank you!