So, here is an improved version of the script:
items:
- type: STR_HANDCUFFS
battleType: 6
invWidth: 1
invHeight: 2
medikitType: 2 #stimulant only
medikitTargetSelf: false #not for user
medikitTargetImmune: true #can use also on an bleed units
medikitTargetMatrix: 21 #only for all stunned bodies
medikitActionName: STR_HANDCUFFS_ACTION
stimulant: 1
stunRecovery: 0 #no matter what value is here - script overrides it
isConsumable: true
costUse:
time: 75
energy: 10
twoHanded: true
blockBothHands: true
listOrder: 46290
tags:
HANDCUFF_STRENGTH: 40
armors:
- type: CIVM_ARMOR
tags:
HANDCUFF_PROTECTION: 10
- type: CIVF_ARMOR
tags:
HANDCUFF_PROTECTION: 5
extended:
tags:
RuleItem:
HANDCUFF_STRENGTH: int #the handcuff strength in ruleset for items
RuleArmor:
HANDCUFF_PROTECTION: int #the handcuff protection in ruleset for units
BattleItem:
ITEM_HANDCUFF_STRENGTH: int #the handcuff strength for every copy of item in battlescape
BattleUnit:
UNIT_HANDCUFF_PROTECTION: int #the handcuff protection for every copy of unit in battlescape
IS_HANDCUFFED: int #is this unit under handcuffs?
VIRTUAL_STUN_LEVEL: int #real stunlevel for every copy of unit on battlescape
scripts:
createItem:
- offset: 1
code: |
var ptr RuleItem ItemRuleset;
var int HandcuffStrength 0;
item.getRuleItem ItemRuleset;
ItemRuleset.getTag HandcuffStrength Tag.HANDCUFF_STRENGTH;
if gt HandcuffStrength 0;
item.setTag Tag.ITEM_HANDCUFF_STRENGTH HandcuffStrength;
debug_log "createItem: STR_HANDCUFF with tag ITEM_HANDCUFF_STRENGTH: " HandcuffStrength;
end;
return;
createUnit:
- offset: 1
code: |
var ptr RuleArmor UnitRuleset;
var int HandcuffProtection 0;
var int UnitID 0;
unit.getId UnitID;
unit.getRuleArmor UnitRuleset;
UnitRuleset.getTag HandcuffProtection Tag.HANDCUFF_PROTECTION;
if gt HandcuffProtection 0;
unit.setTag Tag.UNIT_HANDCUFF_PROTECTION HandcuffProtection;
debug_log "createUnit: ID " UnitID " with tag UNIT_HANDCUFF_PROTECTION: " HandcuffProtection;
end;
return;
healUnit:
- offset: 1
code: |
var int HandcuffStrength 0;
var int HandcuffProtection 0;
var int CurrStun;
var int NewStun;
var int UnitID 0;
target.getId UnitID;
item.getTag HandcuffStrength Tag.ITEM_HANDCUFF_STRENGTH;
target.getTag HandcuffProtection Tag.UNIT_HANDCUFF_PROTECTION;
debug_log "healUnit: used item with ITEM_HANDCUFF_STRENGTH: " HandcuffStrength " on target " UnitID " with UNIT_HANDCUFF_PROTECTION: " HandcuffProtection;
if and gt HandcuffStrength 0 gt HandcuffStrength HandcuffProtection;
target.setTag Tag.IS_HANDCUFFED 1;
debug_log "healUnit: if item with ITEM_HANDCUFF_STRENGTH (" HandcuffStrength ") > 0 and item with ITEM_HANDCUFF_STRENGTH (" HandcuffStrength ") > target " UnitID " with UNIT_HANDCUFF_PROTECTION (" HandcuffProtection ") then: set to target " UnitID " tag IS_HANDCUFFED: " 1;
target.getStunMax NewStun;
target.getStun CurrStun;
target.setTag Tag.VIRTUAL_STUN_LEVEL CurrStun;
target.setStun NewStun;
debug_log "healUnit: set to target " UnitID " VIRTUAL_STUN_LEVEL: " CurrStun " and real stun level: " NewStun;
end;
return;
newTurnUnit:
- offset: 2
code: |
var int IsHandcuff;
var int NewStun;
var int CurrStrength 0;
var int CurrStun 0;
var int PrevStun 0;
var int StrengthLevel 0;
var int RandomValue 0;
var int UnitID 0;
unit.getId UnitID;
debug_log "---------- Turn " turn ", unit " UnitID ":";
unit.getTag IsHandcuff Tag.IS_HANDCUFFED;
if gt IsHandcuff 0;
unit.Stats.getStrength CurrStrength;
debug_log "newTurnUnit: for unit " UnitID " get strength: " CurrStrength;
battle_game.randomRange RandomValue 1 100;
debug_log "newTurnUnit: generate RandomValue (1..100): " RandomValue;
if and ge CurrStrength 0 le CurrStrength 39;
set StrengthLevel 1;
else and ge CurrStrength 40 le CurrStrength 49;
set StrengthLevel 5;
else and ge CurrStrength 50 le CurrStrength 59;
set StrengthLevel 10;
else and ge CurrStrength 60 le CurrStrength 69;
set StrengthLevel 20;
else and ge CurrStrength 70 le CurrStrength 79;
set StrengthLevel 30;
else and ge CurrStrength 80 le CurrStrength 89;
set StrengthLevel 40;
else and ge CurrStrength 90 le CurrStrength 99;
set StrengthLevel 50;
else and ge CurrStrength 100 le CurrStrength 109;
set StrengthLevel 60;
else and ge CurrStrength 110 le CurrStrength 119;
set StrengthLevel 70;
else and ge CurrStrength 120 le CurrStrength 129;
set StrengthLevel 80;
else and ge CurrStrength 130 le CurrStrength 139;
set StrengthLevel 90;
else ge CurrStrength 140;
set StrengthLevel 100;
end;
debug_log "newTurnUnit: unit " UnitID " got StrengthLevel: " StrengthLevel;
unit.getTag PrevStun Tag.VIRTUAL_STUN_LEVEL;
if le RandomValue StrengthLevel;
if lt PrevStun 0;
clear PrevStun;
end;
unit.setStun PrevStun;
unit.setTag Tag.IS_HANDCUFFED 0;
unit.setTag Tag.VIRTUAL_STUN_LEVEL 0;
debug_log "newTurnUnit: if RandomValue (" RandomValue ") <= unit " UnitID " StrengthLevel (" StrengthLevel ") then set real stun: " PrevStun " and remove tag IS_HANDCUFFED";
else gt RandomValue StrengthLevel;
unit.getStun CurrStun;
unit.getStunMax NewStun;
sub CurrStun NewStun;
add PrevStun CurrStun;
unit.setTag Tag.VIRTUAL_STUN_LEVEL PrevStun;
unit.setStun NewStun;
debug_log "newTurnUnit: if RandomValue (" RandomValue ") > unit " UnitID " StrengthLevel (" StrengthLevel ") then set VIRTUAL_STUN_LEVEL: " PrevStun " and real stun: " NewStun;
end;
end;
return;
Each type of handcuffs must have a HANDCUFF_STRENGTH parameter in the "tags" section. By default, it is zero, which means the item is not handcuffs.
For each type of armor, you can specify the HANDCUFF_PROTECTION parameter in the "tags" section. By default, it is equal to zero, which means that the creature can be handcuffed of any handcuffs strength.
When trying to put on handcuffs, the condition is checked: if HANDCUFF_STRENGTH is greater than HANDCUFF_PROTECTION, then the handcuffs will be put on, otherwise not.
The unit, that is handcuffed, is assigned the parameter IS_HANDCUFFED: 1.
Each turn, each unit, in which the IS_HANDCUFFED parameter is 1, is checked for the possibility to free, based on his strength:
if strength in 0..39 then unit has 1% chance to be free,
if 40..49 - 5%,
if 50..59 - 10%,
if 60..69 - 20%,
if 70..79 - 30%,
if 80..89 - 40%,
if 90..99 - 50%,
if 100..109 - 60%,
if 110..119 - 70%,
if 120..129 - 80%,
if 130..139 - 90%,
if 140..infinity - 100%.
Each turn checks how much the unit’s stunning level has changed and this change is recorded to the VIRTUAL_STUN_LEVEL variable in the unit's "tags" section.
If the unit was able to free, its stun level from the VIRTUAL_STUN_LEVEL variable is returned to his stunLevel" and the script finishes its work with this unit.
For understandable how script works, I provided almost every action with a message output to the "openxcom.log" file, because for the player there are no visible changes in the game.