Author Topic: [solved] Actions with units within a certain radius from a soldier  (Read 203 times)

Offline Kozinsky

  • Colonel
  • ****
  • Posts: 142
  • Sorry for my bEd English
    • View Profile
I'm trying to adapt this script to my needs.

What I want to do:
When using skillUseUnit hook, I check for enemy units in a certain radius around the soldier that triggered the hook. Then I need to set a certain tag for all found enemy units and change some values of their characteristics.

Problem:
The Tile.getUnit function returns a pointer to a read-only unit:
Code: [Select]
Name: Tile.getUnit                            Args: [ptr Tile] [var ptr BattleUnit] But to change the tag for that unit, the BattleUnit.setTag function needs a pointer to a unit that is writable:
Code: [Select]
Name: BattleUnit.setTag                       Args: [ptre BattleUnit] [BattleUnit.Tag] [int]        Desc: Set tag of BattleUnit
How can I convert a readable unit (ptr) to a writable unit (ptre)? Or is there some other solution to my problem?
« Last Edit: December 10, 2024, 03:16:06 pm by Kozinsky »

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3374
    • View Profile
Re: [question] How to convert [ptr BattleUnit] to [ptre BattleUnit]?
« Reply #1 on: December 10, 2024, 12:14:36 pm »
You can't, whole point of two versions is to prevent this. When code use `ptr` its means script is run at point when engine do not expect that something change objects in game.
On other hand if you have access to writable `BattleGameSave` then you should be able to grab writable unit and set its tags.

I think only thing right now OXCE miss is dedicated scripts hooks that run after every item use, it could be good place to place logic like you want and would allow cleanup after all script effects.

Offline Kozinsky

  • Colonel
  • ****
  • Posts: 142
  • Sorry for my bEd English
    • View Profile
Re: [question] How to convert [ptr BattleUnit] to [ptre BattleUnit]?
« Reply #2 on: December 10, 2024, 01:05:11 pm »
Now discovered new to me features (I haven't updated the script manual in a while :) ) BattleGame.getUnits.byFaction.list and BattleGame.getUnits.list:
Code: [Select]
Name: BattleGame.getUnits.byFaction.list      Args: [ptre BattleGame] [int] [__] [var int] [var int] [__] [var ptre BattleUnit]     Desc: Get list of units from faction
Name: BattleGame.getUnits.list                Args: [ptre BattleGame] [__] [var int] [var int] [__] [var ptre BattleUnit]   Desc: Get list of all units

Maybe this is something that will work for me. Are there any examples of working with lists? How do I get a pointer to a specific unit from this list?

Offline Yankes

  • Global Moderator
  • Commander
  • *****
  • Posts: 3374
    • View Profile
Re: [question] How to convert [ptr BattleUnit] to [ptre BattleUnit]?
« Reply #3 on: December 10, 2024, 01:37:11 pm »
Code: [Select]
          loop var u battle_game.getUnits.list;
             debug_log "given unit in game" u;
          end;
you can check by id or by comparing units itself `eq u otherUnit`.

Offline Kozinsky

  • Colonel
  • ****
  • Posts: 142
  • Sorry for my bEd English
    • View Profile
Re: [question] How to convert [ptr BattleUnit] to [ptre BattleUnit]?
« Reply #4 on: December 10, 2024, 03:13:40 pm »
Well, it's working great for me  :)
Code: [Select]
skillUseUnit:
  - offset: 1
    code: |
      var int skillRange 5;       #radius (in tiles) at which the effect of the skill is felt
      var int skillPower 40;      #magnitude (percentage) of decrease in the maximum TU of the target
      var int rangeVoxel;         #maximum distance between soldier and target in voxels
      var ptr Tile actorTile;     #tile pointer under the soldier
      var ptr Tile targetTile;    #tile pointer under the target
      var int posX;               #tile coordinates
      var int posY;
      var int posZ;
      var int targetFaction;      #game faction of the target
      var int tileDistance;       #current distance between soldier and target in voxels
      var int statValue;          #maximum amount of target's TU
      #---------- Find the tile where the soldier who activated the script is located:
      actor.getPosition.getX posX;
      actor.getPosition.getY posY;
      actor.getPosition.getZ posZ;
      battle_game.getTile actorTile posX posY posZ;
      #---------- Determine the radius of the skill in voxels from the found tile:
      set rangeVoxel skillRange;
      mul rangeVoxel 16;
      add rangeVoxel 8; #half tile buffer for max distance
      #---------- Checking every unit that exists on the map:
      debug_log "Check units around" actor "(position:" posX "," posY "," posZ ") within" rangeVoxel "voxels:";
      loop var targetUnit battle_game.getUnits.list;
        #---------- Check that the found unit is not under the control of the player
        targetUnit.getFaction targetFaction;
        if neq targetFaction FACTION_PLAYER; 
          #---------- Find the tile where the target unit is located:
          targetUnit.getPosition.getX posX;
          targetUnit.getPosition.getY posY;
          targetUnit.getPosition.getZ posZ;
          #---------- Determine the distance in voxels between the soldier's tile and the target's tile:
          battle_game.getTile targetTile posX posY posZ;
          actorTile.getDistanceVoxel tileDistance targetTile;
          #---------- If this distance is less than the maximum skill range, apply effects to the target:
          if and gt tileDistance 0 lt tileDistance rangeVoxel;
            debug_log "       found" targetUnit "(position:" posX "," posY "," posZ ") within" tileDistance "voxels";     
            targetUnit.setTag Tag.SOME_TAG 1;
            targetUnit.Stats.getTimeUnits statValue;
            muldiv statValue skillPower 100;
            targetUnit.Stats.setTimeUnits statValue;
            debug_log "              and reduce max TU to" statValue;
          end;
        end;
      end;
      return;

Code: [Select]
[10-12-2024_15-26-59] [DEBUG] Script debug log: Check units around BattleUnit(type: "SOLDIER" name: "17 Martial artist-9" id: 17 faction: Player hp: 60/60) (position: 54 , 16 , 1 ) within 88 voxels:
[10-12-2024_15-26-59] [DEBUG] Script debug log:        found BattleUnit(type: "STR_SUPPORTER_OF_DAGON" race: "STR_CHURCH_OF_DAGON" id: 1000001 faction: Hostile hp: 40/40) (position: 55 , 12 , 2 ) within 70 voxels
[10-12-2024_15-26-59] [DEBUG] Script debug log:               and reduce max TU to 23
[10-12-2024_15-26-59] [DEBUG] Script debug log:        found BattleUnit(type: "STR_SUPPORTER_OF_DAGON" race: "STR_CHURCH_OF_DAGON" id: 1000014 faction: Hostile hp: 40/40) (position: 53 , 20 , 1 ) within 65 voxels
[10-12-2024_15-26-59] [DEBUG] Script debug log:               and reduce max TU to 23
[10-12-2024_15-26-59] [DEBUG] Script debug log:        found BattleUnit(type: "STR_DISCIPLE_OF_DAGON" race: "STR_CHURCH_OF_DAGON" id: 1000024 faction: Hostile hp: 35/35) (position: 55 , 19 , 1 ) within 50 voxels
[10-12-2024_15-26-59] [DEBUG] Script debug log:               and reduce max TU to 22
[10-12-2024_15-26-59] [DEBUG] Script debug log:        found BattleUnit(type: "STR_DISCIPLE_OF_DAGON" race: "STR_CHURCH_OF_DAGON" id: 1000026 faction: Hostile hp: 35/35) (position: 53 , 11 , 1 ) within 81 voxels
[10-12-2024_15-26-59] [DEBUG] Script debug log:               and reduce max TU to 22
[10-12-2024_15-26-59] [DEBUG] Script debug log:        found BattleUnit(type: "STR_PRIEST_OF_DAGON" race: "STR_CHURCH_OF_DAGON" id: 1000031 faction: Hostile hp: 50/50) (position: 50 , 14 , 0 ) within 75 voxels
[10-12-2024_15-26-59] [DEBUG] Script debug log:               and reduce max TU to 24
[10-12-2024_15-26-59] [DEBUG] Script debug log:        found BattleUnit(type: "STR_JANISSARY_TERRORIST" race: "STR_JANISSARY" id: 1000038 faction: Hostile hp: 35/35) (position: 55 , 14 , 1 ) within 35 voxels
[10-12-2024_15-26-59] [DEBUG] Script debug log:               and reduce max TU to 12
[10-12-2024_15-26-59] [DEBUG] Script debug log:        found BattleUnit(type: "STR_ALIEN_CYBERWATCH_TURRET" race: "STR_ALIEN_TURRET" id: 1000048 faction: Hostile hp: 35/35) (position: 56 , 19 , 0 ) within 62 voxels
[10-12-2024_15-26-59] [DEBUG] Script debug log:               and reduce max TU to 6
« Last Edit: December 10, 2024, 03:31:16 pm by Kozinsky »