Author Topic: Scripting basics  (Read 3808 times)

Offline Meridian

  • Global Moderator
  • Commander
  • ***
  • Posts: 6274
  • Aaand we're back!
    • View Profile
    • My Wiki
Re: Scripting basics
« Reply #45 on: August 26, 2019, 12:05:44 pm »
Code: [Select]
extended:
  tags:
    RuleSoldier:
      MY_TAG: int
  scripts:
    accuracyMultiplierBonusStats:
      - offset: 10
        code: |
          var int myTagValue;
          var ptr RuleSoldier ruleSoldier;
          unit.getRuleSoldier ruleSoldier;
          ruleSoldier.getTag myTagValue Tag.MY_TAG;
          debug_log 2019 myTagValue;
          return bonus;
soldiers:
  - type: STR_SOLDIER
    tags:
      MY_TAG: 77

Don't forget to check ruleSoldier for NULL for doing anything serious.
« Last Edit: August 26, 2019, 12:09:39 pm by Meridian »

Offline Kzer-Za

  • Colonel
  • ****
  • Posts: 140
    • View Profile
Re: Scripting basics
« Reply #46 on: August 26, 2019, 12:26:23 pm »
Aaah, the type of rule in "extended" that has this tag! Not BattleUnit but RuleSoldier. Thanks!

Offline Kzer-Za

  • Colonel
  • ****
  • Posts: 140
    • View Profile
Re: Scripting basics
« Reply #47 on: August 26, 2019, 02:59:25 pm »
I just found that damageUnit is not triggered when a soldier loses health due to bleeding. So if I want to get the amount of health that he/she loses due to bleeding, I guess, I have to use "newTurnUnit" and "unit.getFatalwoundsTotal", and no shorter way for it?

Offline Yankes

  • Moderator
  • Commander
  • ***
  • Posts: 2313
    • View Profile
Re: Scripting basics
« Reply #48 on: August 26, 2019, 10:07:56 pm »
Thanks, but how do I declare the variable for holding "getGeoscapeSoldier"? I tried this:

Code: [Select]
          var ptr BattleUnit isSoldier;
         
          unit.getGeoscapeSoldier isSoldier;
          if neq isSoldier null;
            debug_log 0 12345;
          end;

But I get an error "Conflicting overloads for operator 'clear'". If I try "var ptr GeoscapeSoldier isSoldier;", I get "invalid type" error.
Ok, after looking to this example I saw that I do not registered correctly this type for all scripts. I will fix it in next version.

I just found that damageUnit is not triggered when a soldier loses health due to bleeding. So if I want to get the amount of health that he/she loses due to bleeding, I guess, I have to use "newTurnUnit" and "unit.getFatalwoundsTotal", and no shorter way for it?
Yes, this is similar to fire damage that is handled by other part of code in next turn event.

Offline Kzer-Za

  • Colonel
  • ****
  • Posts: 140
    • View Profile
Re: Scripting basics
« Reply #49 on: August 27, 2019, 09:08:58 pm »
Sorry to bother you again, but is there a way to get RuleArmor from BattleUnit? I'm interested in getting the unit's armor from "accuracyMultiplierBonusStats" hook, it is needed for this: https://openxcom.org/forum/index.php/topic,7326.msg116055.html#msg116055

Offline Yankes

  • Moderator
  • Commander
  • ***
  • Posts: 2313
    • View Profile
Re: Scripting basics
« Reply #50 on: August 27, 2019, 10:47:03 pm »
`getRuleArmor` don't work?

Offline Kzer-Za

  • Colonel
  • ****
  • Posts: 140
    • View Profile
Re: Scripting basics
« Reply #51 on: August 28, 2019, 10:51:35 am »
Oh, it does. I probably tried using "getArmor" before. Thanks!

Offline Kzer-Za

  • Colonel
  • ****
  • Posts: 140
    • View Profile
Re: Scripting basics
« Reply #52 on: August 30, 2019, 07:36:26 pm »
Sorry, but I have several questions again :)

1. How do I get the thickness of armor? I tried:

Code: [Select]
        var ptr RuleArmor armorRuleset;
        var int newArmor;

        unit.getRuleArmor armorRuleset;
        armorRuleset.getArmor 0 newArmor;

As far as I undestand, I have to specify the side, with 0 being the frontal armor. I also tried switching 0 and "newArmor" places, since I'm not sure about the order of the arguments, but it didn't work either.

2. How can I "truly" kill a unit the moment it is spawned? I mean, I can use "unit.setHealth 0;" in "createUnit", but the unit is spawned in alive state, and dies only when it is hit (even for 0 damage) or after the end of turn. Is there a way to kill it right off? I need it because I have a "createUnit" script that subtracts hitpoints depending on different conditions and in some cases I want a unit to be spawned dead.

3. Can I make a "createUnit" script affect only the units that are spawned during the combat, but not the "default" units that are supposed to be "prespawned" before the combat is started? I tried checking for "turn" variable, but these units are considered to be spawned during the turn 1. And this turn also covers the first player's turn as well as the first aliens' turn. And I need these turns to be treated as "during the combat" already. Could you think of a condition that would exclude these "prespawned" units?

Offline Yankes

  • Moderator
  • Commander
  • ***
  • Posts: 2313
    • View Profile
Re: Scripting basics
« Reply #53 on: August 30, 2019, 10:47:50 pm »
1.
Code: [Select]
    unit.getArmor value side;
    unit.getArmorMax value side;
btw, in next version I will add new consts: this is already added, I looked on wrong init function.
Code: [Select]
SIDE_FRONT
SIDE_LEFT
SIDE_RIGHT
SIDE_REAR
SIDE_UNDER

2. There is special code in game that handle dying units, problem is that it is not run after unit spawn and unit will be "undead" unit this function is called (like you shoot any thing or press next turn). Probably correct fix is call this function after unit is spawned. I can do it.

3. Good point, I can change turn value to 0 when unit/item is spawned before you start first turn.
« Last Edit: August 30, 2019, 11:44:36 pm by Yankes »

Offline Kzer-Za

  • Colonel
  • ****
  • Posts: 140
    • View Profile
Re: Scripting basics
« Reply #54 on: August 31, 2019, 02:24:11 pm »
1. Thanks, now I got it!

2, 3. That's great to hear! When (approximately) is it expected to be introduced?

Offline Yankes

  • Moderator
  • Commander
  • ***
  • Posts: 2313
    • View Profile
Re: Scripting basics
« Reply #55 on: September 01, 2019, 12:01:49 pm »
3 is already done, 2 will be soon (TM from Valve or Blizzard :>)

Offline Kzer-Za

  • Colonel
  • ****
  • Posts: 140
    • View Profile
Re: Scripting basics
« Reply #56 on: September 01, 2019, 01:30:34 pm »
Great! :)

I have run into one problem after updating today to OXCE version 5.6.2 (v2019-08-28). You obviously fixed something, but I, not knowing that it was not supposed to work, relied on this in one mod (it even already found some users), it's the one about cloning Celatids, I asked you about it a lot earlier in this theme :)

So, I used this code:

Code: [Select]
      newTurnItem: |
        var ptre BattleUnit itemOwner;
        var int itemOwnerTUmax;
        var int timer;
        item.getOwner itemOwner;
        # unprime gemmae not held by a Celatid
        if eq itemOwner null;
          item.setFuseTimer -1;
        end;
        # spend time on cloning
        item.getFuseTimer timer;
        if eq timer 0;
          itemOwner.getTimeUnitsMax itemOwnerTUmax;
          div itemOwnerTUmax 2;
          itemOwner.setTimeUnits itemOwnerTUmax;
        end;
        return;

It worked before, but now I get these errors:

Code: [Select]
[01-09-2019_13-14-02] [ERROR] Can't match overload for operator 'BattleItem.getOwner' for:
[01-09-2019_13-14-02] [ERROR]   [ptre BattleItem] [var ptre BattleUnit]
[01-09-2019_13-14-02] [ERROR] Excepted:
[01-09-2019_13-14-02] [ERROR]   [ptr BattleItem] [var ptr BattleUnit]
[01-09-2019_13-14-02] [ERROR]   [ptre BattleItem] [var ptr BattleUnit]
[01-09-2019_13-14-02] [ERROR] Error in parsing script 'newTurnItem' for 'STR_CELATID_GEMMA': invalid operation in line: 'item.getOwner itemOwner;'

As far as I understand, now it's impossible to addres to a BattleUnit as a ptre from BattleItem. And I kinda need it to change the amount of TUs of the Celatid on the turn, on which it clones itself. The problem is I don't want them to spawn clones on exact turns 5, 11, ..., so during the "createItem", the fuse timer is randomized a little. I can't think of a way for a Celatid to get the fuse timers from the grenades it is carrying, that is why I went the other way and changed the TUs of the item owner from the item (grenade), since from the grenade I can get its timer.

So I was wandering how I can do it now?

Offline Yankes

  • Moderator
  • Commander
  • ***
  • Posts: 2313
    • View Profile
Re: Scripting basics
« Reply #57 on: September 01, 2019, 02:16:58 pm »
What version worked and what do not? Recently I made some refactor using C++17 features and there is possibility I break something.

Error is clear:
Code: [Select]
[01-09-2019_13-14-02] [ERROR] Can't match overload for operator 'BattleItem.getOwner' for:
[01-09-2019_13-14-02] [ERROR]   [ptre BattleItem] [var ptre BattleUnit]
[01-09-2019_13-14-02] [ERROR] Excepted:
[01-09-2019_13-14-02] [ERROR]   [ptr BattleItem] [var ptr BattleUnit]
[01-09-2019_13-14-02] [ERROR]   [ptre BattleItem] [var ptr BattleUnit]
He did not see version when we have editable item and want editable unit. And AFAIR there should be version like that available.

Offline Kzer-Za

  • Colonel
  • ****
  • Posts: 140
    • View Profile
Re: Scripting basics
« Reply #58 on: September 01, 2019, 02:28:36 pm »
The version that I used up to this morning was 5.6.1 (v2019-08-03), that's where things worked. Today I compiled the new version, which is 5.6.2 (v2019-08-28), that's where the error occurs.

Offline Yankes

  • Moderator
  • Commander
  • ***
  • Posts: 2313
    • View Profile
Re: Scripting basics
« Reply #59 on: September 01, 2019, 02:48:36 pm »
I can confirm I made error that incorrectly detect "return type".
I will soon fix this bug.

[ps]

fix should be ready, you can compile fresh version and see if it work correcly
« Last Edit: September 01, 2019, 03:33:15 pm by Yankes »