Phobos icon indicating copy to clipboard operation
Phobos copied to clipboard

Initialize Transact Warhead System

Open MortonPL opened this issue 4 years ago • 13 comments

Transact Warhead

  • It is now possible to increase, decrease or transfer specific "values" (referred to as Currency) between Technos.
    • To enable this feature, Transact=true must be set and at least one X.Source or X.Target tag needs to be non-zero.
    • Source is the Techno that fired the warhead, target is a Techno (or a group) that is affected by the warhead.
    • X.Flat values grant absolute Currency, while X.Percent values grant Currency calculated relatively to the unit's state.
      • In case of experience, value from X.Percent is calculated by multiplying it by current unit cost.
      • By default X.Source.Percent (percent of value that Source will receive) is calculated from Source unit cost, however it is possible to force calculation from Target cost with CalcFromTarget (Target and CalcFromSource behaves analogically).
      • When both X.Flat and X.Percent values are set, the one that yields more Currency is used.
    • If final Currency amount is positive or negative for both Source and Target, then all affected units gain or lose Currency.
    • When the final amount of Currency is negative only for either Source or Target, Transfer occurs.
      • In transfer, if the absolute value of Currency for Source and Target are different, then the smaller of them is used.
      • In transfer, if it is not possible to transfer the whole amount (i.e. a unit has not enough Currency), then only the possible amount is transferred.
    • Source values are ignored if the warhead is not created by a unit (i.e. via a super weapon, animation weapon or map action).
    • Transact.SpreadAmongTargets has effect on warheads with CellSpread. When set, instead of applying the full Currency amount to each Target separately, the value will be evenly distributed among the victims.
    • Transact.Experience.IgnoreNotTrainable=true will allow to give experience to units with Trainable=false set.
    • Transact.RequiresValidTarget=false will allow the source unit to lose/obtain Currency when the warhead doesn't detonate on a valid target (i.e. having 0% versus a unit). However, target remains unaffected and if Source was supposed to take part in a transfer, nothing will happen!
    • Transact.RequiresAnyTarget=false will allow the source unit to lose/obtain Currency when the warhead doesn't detonate on any target (i.e. force firing on the ground). However, if Source was supposed to take part in a transfer, nothing will happen! This tag takes priority over Transact.RequiresValidTarget.
It is impossible to revert veterancy-caused unit type conversion from Ares by demoting a unit!

Currently supported "values" are:

  • Experience

In rulesmd.ini:

[SOMEWARHEAD]                                           ; Warhead
Transact=false                                          ; boolean
Transact.RequiresAnyTarget=true                         ; boolean
Transact.RequiresValidTarget=true                       ; boolean
Transact.SpreadAmongTargets=false                       ; boolean
Transact.Experience.IgnoreNotTrainable=false            ; boolean
Transact.Experience.Source.Flat=0                       ; integer
Transact.Experience.Source.Percent=0.0                  ; float, percents or absolute (-1.0 - 1.0)
Transact.Experience.Source.Percent.CalcFromTarget=false ; boolean
Transact.Experience.Target.Flat=0                       ; integer
Transact.Experience.Target.Percent=0.0                  ; float, percents or absolute (-1.0 - 1.0)
Transact.Experience.Target.Percent.CalcFromSource=false ; boolean

MortonPL avatar Feb 07 '21 21:02 MortonPL

Move "AddNoNegative" function to somewhere out "GeneralUtils" to "Hook.cpp" for example , this will fix the compiler problems

Otamaa avatar Mar 02 '21 12:03 Otamaa

Since the fork is automatically rechecked, I've got some things to explain here:

  • cellspread support is here, but still requires additional testing to search and destroy possible bugs.
  • that <abstract_cast>(TechnoClass*) is to stay - build errors are no more and normal cast causes fatals,
  • as of now warhead doesn't work with GenericWarhead SW,
  • in other cases everything's fine

MortonPL avatar Mar 03 '21 23:03 MortonPL

This is a repost of the comments made in #phobos-project to keep feedback easily found:

  • Experience has been working well so far, the only noticed issue I have currently is that the effect ignores Trainable=no and will promote even civilian structures.
  • In addition, infantry firing inside an opentopped transport will promote as expected when Experience.FirerGetsExp=yes. When inside a garrisoned structure however, the building itself receives the experience and the firer receives none.

SMxReaver avatar Mar 18 '21 20:03 SMxReaver

Nightly build for this pull request:

github-actions[bot] avatar Mar 29 '21 18:03 github-actions[bot]

For reference, the suggested tags for this are:

Transact.Source.Experience.Flat=0
Transact.Source.Experience.Percent=0
Transact.Source.Experience.Percent.CalcFromTarget=false

Transact.Target.Experience.Flat=0
Transact.Target.Experience.Percent=0
Transact.Target.Experience.Percent.CalcFromSource=false

Transact.SpreadAmongAffectedTargets=true

The way it works is that you calculate the availability of specified value changes for target and source in form of 0-1 coeffitient (or, say, percentage from 0% to 100%), and then take the lowest coeffitient and use it for transfer. If there's no transfer (only source or only targets are affected) then you just apply that one coeffitient.

SpreadAmongAffectedTargets is for switching the CellSpread mode: if it's true - then the transact values are spread amongst all targets affected by this warhead (so 20 exp. flat source/target transfer divided among 4 units would transfer as 5 to each, 20 total from source), if false - then full transfer would be applied to each affected target (same situation would result in 20 to each of 4 units, 80 from source).

This is to lay out the foundation for Transact warhead expansion.

Metadorius avatar Aug 21 '21 13:08 Metadorius

After a long-needed rework, the now Transact Warhead should be ready for preliminary testing.

MortonPL avatar Mar 16 '22 22:03 MortonPL

Tested 4 times all resulted in an IE. 7C0A74F6 - rookie source & rookie aircraft target 783C1AF1 - veteran source & rookie unit target 78811AF1 - veteran source & veteran unit target Uploaded dumps to discord.

Used default settings with Transact=true Tried changing some of the exp tags but no luck, still get IEs. All attempts were with rookie and veteran units alike.

ayylmaoRotE avatar Mar 17 '22 05:03 ayylmaoRotE

541F1BB2 on CellSpread

[ExperienceWH] Verses=10%,10%,10%,10%,10%,10%,10%,10%,10%,10%,10% CellSpread=5 Transact=true ; boolean Transact.SpreadAmongTargets=false ; boolean Transact.Experience.Source.Flat=0 ; integer Transact.Experience.Source.Percent=0.0 ; float, percents or absolute (-1.0 - 1.0) Transact.Experience.Source.Percent.CalcFromTarget=false ; boolean Transact.Experience.Target.Flat=0 ; integer Transact.Experience.Target.Percent=2.0 ; float, percents or absolute (-1.0 - 1.0) Transact.Experience.Target.Percent.CalcFromSource=false ; boolean

ayylmaoRotE avatar Mar 18 '22 03:03 ayylmaoRotE

Same IE happens when you smash too many EXPs into a single unit too quickly: e.g. [PilotWH] Verses=0%,0%,0%,10%,10%,10%,0%,0%,0%,0%,0% Versus.t2mediump=0% Transact=true ; boolean Transact.SpreadAmongTargets=false ; boolean Transact.Experience.Source.Flat=0 ; integer Transact.Experience.Source.Percent=0.0 ; float, percents or absolute (-1.0 - 1.0) Transact.Experience.Source.Percent.CalcFromTarget=false ; boolean Transact.Experience.Target.Flat=0 ; integer Transact.Experience.Target.Percent=10.0 ; float, percents or absolute (-1.0 - 1.0) Transact.Experience.Target.Percent.CalcFromSource=false ; boolean

EDIT: some further tests, if the unit does not die mid EXP transfer, no crashes, but the Weapon I use kills the unit (not via Suicide but via Anim=), I think this is why the crash happens, maybe store the unit info like anim2unit directions is stored?

even with Percent=2.0, though I can't reproduce every time, especially if you do it 1 by 1 initially. See vids below:

https://user-images.githubusercontent.com/69301373/158943007-f646fd80-938f-4911-905c-c63efd6d8d0d.mp4

https://user-images.githubusercontent.com/69301373/158943014-c6f61e9e-2bb0-4c05-8af3-04dfbd2996b5.mp4

https://user-images.githubusercontent.com/69301373/158943016-d46b0de5-cd2d-45d3-8a63-176e3891fa3c.mp4

https://user-images.githubusercontent.com/69301373/158943025-5303baba-46ce-4cdd-9868-1b0bdb5063af.mp4

:

ayylmaoRotE avatar Mar 18 '22 05:03 ayylmaoRotE

Some more findings (bugs):

  1. The Transact.Experience aspect of the warhead will ignore verses/versus and whether the target is Trainable=yes or not e.g. if the WH has CellSpread=6 and Verses=0%,0%,0%,10%,10%,10%,0%,0%,0%,0%,0%, everything will be affected, infantry and buildings too.

CellSpread=<1 or no CellSpread:

  • Flat: Works on source and target
  • Percent: Works on source and target

CellSpread=1>:

  • Flat: Works on source and target
  • Percent: Works on source and target
  • Only works on weapons, if triggered via SW (GenericWarhead) it will crash
  1. If an infantry has IsDesolator=yes (AreaFire potentially affects this too), this breaks CellSpread on the Exp WH, e.g.:

CellSpread=<1 or no CellSpread:

  • Flat: Does not work at all
  • Percent: Does not work at all

CellSpread=1>:

  • Flat: The correct value will be given to the source only, e.g. 500
  • Percent: The source will instantly gain the maximum experience possible regardless of the value used
  • CellSpread value is actually ignored, it won't affect any nearby targets
  1. Trainable=no is ignored, e.g. MCVs, Engineers, buildings etc will also gain veterancy

ayylmaoRotE avatar Mar 25 '22 06:03 ayylmaoRotE

EDIT: some further tests, if the unit does not die mid EXP transfer, no crashes, but the Weapon I use kills the unit (not via Suicide but via Anim=), I think this is why the crash happens, maybe store the unit info like anim2unit directions is stored?

I can confirm the on-death crashes (although in my case i tried it with Death.NoAmmo=yes).

  1. Trainable=no is ignored, e.g. MCVs, Engineers, buildings etc will also gain veterancy

I would ask for it to be kept that way, because with it and Ares' conversion-on-promotion, modders can make units that don't gain experience, but still morph into a different one when affected by an SW or attacked by something. If someone wants to exclude specific units from gaining experience, there's Versus.X for that. But preferably, it might be best if whether Trainable=no units are affected was a separate tag.

mevitar avatar May 06 '22 21:05 mevitar

3. If an infantry has IsDesolator=yes (AreaFire potentially affects this too), this breaks CellSpread on the Exp WH, e.g.:

It's not AreaFire=yes, that one works fine. CellSpread also appears to works fine for me (tried with CellSpread=3). Did you perhaps try it on a test infantry? I made that mistake and it didn't work at first because incorrect sequence forced it to use primary on deploy. Once i put the weapon on a proper YuriClone-like infantry, it worked fine (except for the fact that verses were still completely ignored and everything in the area got the experience...).

mevitar avatar May 06 '22 22:05 mevitar

Reopening after a long break. All reported crashes and issues (ignoring verses and Trainable) should be addressed, updated documentation is in PR description.

MortonPL avatar Sep 20 '22 16:09 MortonPL