Author Topic: [Solved] A few questions about this "Poison Script"  (Read 2946 times)

Offline The Martian

  • Commander
  • *****
  • Posts: 754
  • "It implores you to listen to its arguments..."
    • View Profile
[Solved] A few questions about this "Poison Script"
« on: January 01, 2020, 03:54:40 pm »
This poison script created by Yankes looks very useful.

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

I have a few questions about how it is used.


(Question #1):
Which *.rul file does it need to be in to function?

Can I place it in its own PoisonScript.rul file or does it need to be in the same file as the *.rul that has the items: section in it?



(Question #2):
I'm guessing that the variable POISON_STRENGTH: on the item and POISON_SUSCEPTIBILITY: on the unit armor determine how much HP is lost by a poisoned unit per turn and either the number of turns the unit is poisoned or a resistance to the applied poison effect, I'm not sure exactly which from trying to read the code.

How do this work?




(Question #3):
Although the above question may answer this, I'll ask directly as it would be odd to see mechanical tanks succumbing to the effects of poisoning.

Is it possible to prevent a unit from being able to be afflicted with the poison script's effects?



(Question #4):
If a unit is already poisoned and is afflicted with poison again, what happens?
. Does it overwrite the Poison with the new value?
. Does it overwrite the Poison with the highest value?
. Does increase the value of the Poison by combining both?
. Do the instances of Poison stack each running separately?
. Or can a unit already effected by poison not be poisoned further?



(Question #5):
The words recolorUnitSprite: seem to suggest that the poisoned unit will display its affliction by shifting colour to a greenish tint.

Is it possible to cause this effect to display as other colours?
(Red/Blue/Yellow)



(Question #6):
Can a poisoned unit be cured of the poison effect, or must it run its course once inflicted?

For example by a medkit?




(Question #7):
Is it possible to have several versions of this script running simultaneously if these three varables are renamed in an additional copy of the script which is also present in a *.rul file along side the original?
POISON_STRENGTH:
POISON_SUSCEPTIBILITY:
POISON_LEVEL:

For example:
POISON_STRENGTH_B:
POISON_SUSCEPTIBILITY_B:
POISON_LEVEL_B:


If that is possible and the scripts unit affliction display colour can be altered then one version of the script could cause an effected unit to become green coloured when hit while others could switch to different colours representing other damaging afflictions.
(Also they would both have separate instances of damage if applied to the same unit.)

This would be very useful.
« Last Edit: February 12, 2023, 02:36:21 pm by Meridian »

Offline Yankes

  • Commander
  • *****
  • Posts: 3194
    • View Profile
Re: A few questions about this "Poison Script" (OXCE)
« Reply #1 on: January 01, 2020, 10:35:02 pm »
This poison script created by Yankes looks very useful.

I have a few questions about how it is used.


(Question #1):
Which *.rul file does it need to be in to function?

Can I place it in its own PoisonScript.rul file or does it need to be in the same file as the *.rul that has the items: section in it?

No, only this part need be copy-pasted to any file that want interact with this script:

Code: [Select]
extended:
  tags:
    RuleItem:
      POISON_STRENGTH: int
    RuleArmor:
      POISON_SUSCEPTIBILITY: int
    BattleUnit:
      POISON_LEVEL: int






(Question #2):
I'm guessing that the variable POISON_STRENGTH: on the item and POISON_SUSCEPTIBILITY: on the unit armor determine how much HP is lost by a poisoned unit per turn and either the number of turns the unit is poisoned or a resistance to the applied poison effect, I'm not sure exactly which from trying to read the code.

How do this work?


Code: [Select]
            mul strength susceptibility;
            div strength 10;
            unit.getTag temp Tag.POISON_LEVEL;
            if lt temp strength;
              unit.setTag Tag.POISON_LEVEL strength;
            end;
This part set current poison level on unit custom variable.
Code: [Select]
            unit.getHealth hp;
            sub hp poison;
            unit.setHealth hp;
This part change unit HP of given unit.

Both part can be changes to fit your needs or balance (right now is dumb version where damage tick with 5,4,3,2,1 values).





(Question #3):
Although the above question may answer this, I'll ask directly as it would be odd to see mechanical tanks succumbing to the effects of poisoning.

Is it possible to prevent a unit from being able to be afflicted with the poison script's effects?


`POISON_SUSCEPTIBILITY` if it 0 it will make unit unit immune to poison, or you can add check if unit is 2x2 or some thing like that.





(Question #4):
If a unit is already poisoned and is afflicted with poison again, what happens?
. Does it overwrite the Poison with the new value?
. Does it overwrite the Poison with the highest value?
. Does increase the value of the Poison by combining both?
. Do the instances of Poison stack each running separately?
. Or can a unit already effected by poison not be poisoned further?


only one poison effect, and bigger win. Overall engine only allow fixed number of variables this mean you can't create in scripts multiple same effects that do work in parallel.





(Question #5):
The words recolorUnitSprite: seem to suggest that the poisoned unit will display its affliction by shifting colour to a greenish tint.

Is it possible to cause this effect to display as other colours?
(Red/Blue/Yellow)

Code: [Select]
          if gt poison 0;
            set_color new_pixel 4; #green color
          end;
set any value instead of `4` and you will have your color (see Ufo palettes to see what colors are available).






(Question #6):
Can a poisoned unit be cured of the poison effect, or must it run its course once inflicted?

For example by a medkit?


medkit? no, another bullet? yes.

Some script need set `unit.setTag Tag.POISON_LEVEL 0;`
As medkits are not scripted, they cant affect it, when someone add hooks for them then it will be able to do this.






(Question #7):
Is it possible to have several versions of this script running simultaneously if these three varables are renamed in an additional copy of the script which is also present in a *.rul file along side the original?
POISON_STRENGTH:
POISON_SUSCEPTIBILITY:
POISON_LEVEL:

For example:
POISON_STRENGTH_B:
POISON_SUSCEPTIBILITY_B:
POISON_LEVEL_B:


If that is possible and the scripts unit affliction display colour can be altered then one version of the script could cause an effected unit to become green coloured when hit while others could switch to different colours representing other damaging afflictions.
(Also they would both have separate instances of damage if applied to the same unit.)

This would be very useful.

If you copy paste it and replace variable names then yes. Probably easier would be alter current script and add logic to it to check for both version.

Overall it will be useful in `recolorUnitSprite` to reduce script competition for unit color, it could even check if unit have both poison types to even further change unit color.
« Last Edit: January 01, 2020, 10:57:48 pm by Yankes »

Offline The Martian

  • Commander
  • *****
  • Posts: 754
  • "It implores you to listen to its arguments..."
    • View Profile
Re: A few questions about this "Poison Script" (OXCE)
« Reply #2 on: January 03, 2020, 07:59:55 am »
No, only this part need be copy-pasted to any file that want interact with this script:

Code: [Select]
extended:
  tags:
    RuleItem:
      POISON_STRENGTH: int
    RuleArmor:
      POISON_SUSCEPTIBILITY: int
    BattleUnit:
      POISON_LEVEL: int

If I add that code to the *.rul files containing items: or armors: sections the armor and weapon equipment doesn't appear when I try to test it in the "New Battle - Mission Generator" from the main menu.

However if I only have this block of code inside of the *.rul file containing the scripts: section it works:

Code: [Select]
extended:
  tags:
    RuleItem:
      POISON_STRENGTH: int
    RuleArmor:
      POISON_SUSCEPTIBILITY: int
    BattleUnit:
      POISON_LEVEL: int

Have I misunderstood your instructions?

I've attached two *.zip files to this post to better show what I mean, one has the *.rul files with the above code contained in the items: armors: & scripts: files. The other only contains the code for the extended: section inside of the scripts: *.rul.
« Last Edit: January 03, 2020, 01:04:08 pm by The Martian »

Offline Yankes

  • Commander
  • *****
  • Posts: 3194
    • View Profile
Re: A few questions about this "Poison Script" (OXCE)
« Reply #3 on: January 03, 2020, 03:40:56 pm »
You mess up this file, what editor you used to edit this files?
When I diff correct version and your corrupted I get diff like this:
Code: [Select]

-items:
+ďťżitems:
 # Weapon for the poison ammo.

This `ďťż` is BOM from start of UTF-8 file but in your file its in the middle of file and it corrupt name of node.

Offline The Martian

  • Commander
  • *****
  • Posts: 754
  • "It implores you to listen to its arguments..."
    • View Profile
Re: A few questions about this "Poison Script" (OXCE)
« Reply #4 on: January 04, 2020, 08:27:19 am »
You mess up this file, what editor you used to edit this files?
Thank you for catching that.

Normally I use Notepad++ but for those files I used the editor that came with Linux Mint called simply "Text Editor".

I'll stick with using Notepad++ exclusively while editing code from now on.






I'm only starting to read through YAML's documentation so my attempts to alter your script are mostly through experimentation mixed with some guess work and copying the already present formatting and syntax.

My ideal goal would be if a weapon or ammo could be configured so that it had four values:
(1) The amount of damage the poison inflicts per turn.
(2) The amount of turns the poison will last.
(3) The amount the poison damage is reduced by each turn until it hits 0 and the effect is removed.
(4) The amount being struck by this weapon reduces the remaining poison time on an already poisoned unit.


If the last two variables can be applied to an existing poisoned state they can also be used on defencive X-Com equipment to cure the poison afflictions. Either immediately on striking the unit using the fourth variable or gradually via a reduction in damage each turn using the third variable.


So far I've noticed that if "sub poison 1;" is changed to "sub poison 0;" the strength of the poison damage does not decrease between turns.
(So I'm proceeding under the assumption that the "sub" command is to subtract 1 from the poison variable)

When using an item with "POISON_STRENGTH: 1" an infected soldier loses 2 HP per turn while poisoned. I'm not sure why this is 2 and not 1 hp though.

When using an item with "POISON_STRENGTH: 2" an infected soldier loses 4 HP per turn while poisoned.

When using an item with "POISON_STRENGTH: 3" an infected soldier loses 6 HP per turn while poisoned.

So it is pretty clear the POISON_STRENGTH value is being doubled, but I haven't been able to pick out the part of the code that is doing that yet but it does seem to be related to POISON_SUSCEPTIBILITY.


I think it is this section of the code:
Code: [Select]
            mul strength susceptibility;
            div strength 10;

I'm assuming that the command "mul" is multiply and "div" is divide.



POISON_SUSCEPTIBILITY appears to be a resistance setting with 5 as normal damage (Matching the POISON_STRENGTH value) and 10 as double that.

Code: [Select]
      POISON_STRENGTH: 2
POISON_SUSCEPTIBILITY: 10

36
32
28
24
20
16
12
8
4
0  <Dead>

      POISON_STRENGTH: 2
POISON_SUSCEPTIBILITY: 20

36
28
20
12
4
0  <Dead>

      POISON_STRENGTH: 2
POISON_SUSCEPTIBILITY: 5

36
34
32
30
28
26
24
22
20
18
16
14
12
10
8
6
4
2
0 <Dead>



By changing "sub poison 0;" it appears the poison effect no longer runs out.

So I tried counteracting this by adding a new variable POISON_TIME.

Code: [Select]
extended:
  tags:
    RuleItem:
      POISON_STRENGTH: int
      POISON_TIME: int
    RuleArmor:
      POISON_SUSCEPTIBILITY: int
    BattleUnit:
      POISON_LEVEL: int

and altered the code in the scripts: and items: sections as follows:

Code: [Select]
  - type: STR_POISON_EXAMPLE_GUN_AMMO
    tags:
      POISON_STRENGTH: 2
      POISON_TIME: 4

    newTurnUnit:
      - offset: 1
        code: |
          var int poison;
          var int hp;
          unit.getTag poisonTime Tag.POISON_TIME;
          unit.getTag poison Tag.POISON_LEVEL;
          if gt poison 0;
            unit.getHealth hp;
            sub hp poison;
            unit.setHealth hp;
            sub poisonTime 1;
            unit.setTag Tag.POISON_LEVEL poisonTime;
          end;
          return;

However now the unit just appears to change to a green colour and never removes the poison or takes any damage from it.

I thought that the line "unit.getTag poisonTime Tag.POISON_TIME;" was performing the following action:
(1) "unit.getTag"
The poisoned unit's stored tags: values are loaded.

(2) "poisonTime Tag.POISON_TIME"
The variable 'poisonTime' stores the value contained on the poisoned unit in the Tag.POISON_TIME variable.

Is that incorrect?



I've attached a *.zip of the code to make it easier to see what I've done.
« Last Edit: January 04, 2020, 08:50:16 am by The Martian »

Offline Yankes

  • Commander
  • *****
  • Posts: 3194
    • View Profile
Re: A few questions about this "Poison Script" (OXCE)
« Reply #5 on: January 04, 2020, 05:46:47 pm »
First of all, `POISON_STRENGTH` is not doubled, it remove exactly same value of health as is current one, but there is important thing, WHEN it is done. "Turn" is not that you think, this is not when you click "Next Turn" but it done for EACH faction that is present in battle scape, this mean one for XCOM, one for Aliens and one for Civilians.

For units colors you need look on `recolorUnitSprite` and see what is checked to determine color of unit. Right now you left `if gt poison 0;` and your script do not clear this tag. When you change "definition" of poisoned unit then you need update other checks too to mach new definition.


If you want see all list of operation available in scripts you should enabled verbose logging in OXCE, it will dump whole config of scripts to log.
You will see there definition of `mul` and see that is multiplication of two variables.