Author Topic: [Documentation] New Script hooks / data access  (Read 1442 times)

Offline memmaker

  • Captain
  • ***
  • Posts: 95
    • View Profile
[Documentation] New Script hooks / data access
« on: January 26, 2020, 07:33:17 pm »
So, I have the honor to present some new features which have been added to OXCE ModScripts.

  • Getters for BattleUnit position - Enables scripts to check distances and allows for Area-of-Effect
  • getTurnsSinceSpotted exposed to scripts - Allows to check if enemies have spotted this unit
  • TimeUnits spent for action now exposed to scripts - Example use case: (Partially) refund TU for an action
  • New healUnit script hook - Gets executed whenever a medikit is used

Example script for BattleUnit position:
Code: [Select]
    newTurnUnit:
      - offset: 31   # for aim
        code: |
          var int is_kneeling;
          var int pos_x;
          var int pos_y;
          var int pos_z;
          var int aim;
          var int kneeling;
          if eq side 0; # xcom turns
            unit.getTag aim Tag.AIM_STATE;
            unit.isKneeled kneeling;

            if and gt aim 0 gt kneeling 0;
              unit.getPosition.getX pos_x;
              unit.getPosition.getY pos_y;
              unit.getPosition.getZ pos_z;

              unit.setTag Tag.AIM_STATE 2; # was kneeling at the beginning of the turn
             
              unit.setTag Tag.AIM_X pos_x;
              unit.setTag Tag.AIM_Y pos_y;
              unit.setTag Tag.AIM_Z pos_z;
            end;
          end;
          return;

Example Script for getTurnsSinceSpotted

Code: [Select]
    hitUnit:
      - offset: 32   # for shadowstrike
        code: |
          var int camo_state;
          var int shadowstrike_state;
          var int turns_since_spotted;
          var int temp;

          attacker.getTag camo_state Tag.PHANTOM_STATE;
          attacker.getTag shadowstrike_state Tag.SHADOWSTRIKE_STATE;
          if and gt shadowstrike_state 0 gt camo_state 0;
            attacker.getTurnsSinceSpotted turns_since_spotted;
            if or eq turns_since_spotted 255 le turns_since_spotted -1;
              # shadowstrike activate
              debug_log "Shadowstrike Crit Chance (inc.):" shadowstrike_state;
              attacker.getTag temp Tag.CRIT_CHANCE_NEXT_HIT;
              add temp shadowstrike_state;
              attacker.setTag Tag.CRIT_CHANCE_NEXT_HIT temp;
            end;
          end;
          return power part side;

Example code for Action TimeUnits

Code: [Select]
    hitUnit:
      - offset: 37   # for guardian
        code: |
          var int guardian;
          var int activation_chance;
          var int turn_side;
          var int action_time_units;
          var int current_time_units;

          set activation_chance 50;
          battle_game.getTag turn_side Tag.TURN_SIDE;

          attacker.getTag guardian Tag.GUARDIAN_STATE;

          if and gt guardian 0 eq turn_side 1; # guardian only activates on enemy turn
            battle_game.randomChance activation_chance;
            if gt activation_chance 1;
              damaging_item.getActionCost.getTimeUnits action_time_units attacker battle_action;
              attacker.getTimeUnits current_time_units;
              add current_time_units action_time_units;

              attacker.setTimeUnits current_time_units;
              debug_log "Guardian Activated! Reaction TU refunded.";
            end;
          end;
               
          return power part side;

Example code for healUnit

Code: [Select]
    healUnit:
      - offset: 24   # for savior
        code: |
          var int savior;
          var int health_to_heal;

          actor.getTag savior Tag.SAVIOR_STATE;

          if gt savior 0;
            if eq medikit_action_type 1; # heal
              debug_log "Savior activated.";
              debug_log " - Health recovered (org.):" health_recovery;
              set health_recovery savior;
              debug_log " - Health recovered (adj.):" health_recovery;
            end;
          end;

          return;
« Last Edit: January 29, 2020, 11:38:49 pm by memmaker »

Offline Yankes

  • Moderator
  • Commander
  • ***
  • Posts: 2838
    • View Profile
Re: [Documentation] New ModScript hooks / data access
« Reply #1 on: January 27, 2020, 07:34:15 pm »
I think you should name my script different way, because game have already MapScripts and it is something different.
I would prefer simply script or y-script as some people name it.

Offline memmaker

  • Captain
  • ***
  • Posts: 95
    • View Profile
Re: [Documentation] New Script hooks / data access
« Reply #2 on: February 04, 2020, 10:30:20 pm »
We got one more script hook, merged some days ago. It will soon become available.

tryPsiAttackUnit: Enables scripts to change the success of a psi attack. It gets the attackers and defenders strength and the pre-calculated outcome.

An example script that would change the success rate to 100% looks like this

Code: [Select]
    tryPsiAttackUnit:
      - offset: 23   # for Scripted Items - Automatic Success
        code: |
          var int battle_type;
          var ptr RuleItem item_rule;
          var int energy_max;
         
          item.getRuleItem item_rule;

          item_rule.getBattleType battle_type;
         
          if eq battle_type 9; # scripted psi amp
            if or eq battle_action 13 eq battle_action 14;
              debug_log "PsiAttack with scripted item. Automatic success!";
              set psi_attack_success 1;
            end;
          end;
          return psi_attack_success;

Offline memmaker

  • Captain
  • ***
  • Posts: 95
    • View Profile
Re: [Documentation] New Script hooks / data access
« Reply #3 on: February 04, 2020, 10:32:41 pm »
There is also a new function available on the BattleGame called tryConcealUnit. It allows scripts to try and hide units from the AIs sights. Basically resetting the status to before this unit was spotted.

An example invocation looks like this:

Code: [Select]
              battle_game.tryConcealUnit unit result;
              if gt result 0;
                unit.getTag temp Tag.PHANTOM_STATE_ORIGINAL;
                unit.setTag Tag.PHANTOM_STATE temp;
                set spend_tu 1;
              else;
                battle_game.flashMessage "Failed. You have been spotted.";
              end;