Skip to content

Conversation

@DaloLorn
Copy link

@DaloLorn DaloLorn commented Dec 17, 2025

Implements #1539.

Testing

I didn't think I'd be able to include testing screenshots for this one, but it occurred to me that YAF1 might base its tooltips off an effect's WatchRule. I was right!

✅ When POISONED_TICKS_AFTER_TURN is true, poison ticks on turn end:

Details image

✅ When BLEEDING_TICKS_AFTER_TURN is true, bleeding ticks on turn end:

Details image

✅ When "Fire" is added to BURN_TYPES_TICKING_AFTER_TURN, fire ticks on turn end:

Details image

✅ While "Acid" is absent from BURN_TYPES_TICKING_AFTER_TURN, acid still uses the vanilla behavior of ticking on turn start:

Details image

✅ When POISONED_TICKS_AFTER_TURN is false, poison uses the vanilla behavior of ticking on turn start:

Detailsimage

✅ When BLEEDING_TICKS_AFTER_TURN is false, bleeding uses the vanilla behavior of ticking on turn start:

Detailsimage

💡 These configs can be changed (to some extent?) during tactical combat! I wasn't sure if that was going to work... but a keen eye will notice both sets of poison/bleed tests were on the same map.

❓ Effects ticking on turn end will still force the camera to look at the victim on turn start? This is in addition to looking at them when they're damaged... I don't remember that being a thing before, so might've done something wrong. Something with the visualizer, maybe?

@Tedster59 Tedster59 added this to the 1.31.0 milestone Dec 31, 2025
@Tedster59
Copy link
Contributor

@DaloLorn - Can you pull the VSCode Tasks stuff into a separate PR? I'd like to keep the game-related stuff and infrastructure-related stuff separate.

@Tedster59
Copy link
Contributor

❓ Effects ticking on turn end will still force the camera to look at the victim on turn start? This is in addition to looking at them when they're damaged... I don't remember that being a thing before, so might've done something wrong. Something with the visualizer, maybe?

Did you test with a different mission as well as changing it mid-mission? I expect changing the watch rule mid-mission is not appropriate. You may want to use X2DebugVisualizers to see what the camera is doing.

@chrishayesmu
Copy link

chrishayesmu commented Dec 31, 2025

I would second Tedster's suggestion to test what's going on with the camera using a clean slate approach. Set up the config with the game closed and don't touch it while running. That's what players/mods will be doing, and we should match it in our testing.

Terminology nitpick throughout this PR: the correct terminology as used by the game rule is "player turn end", but the configs use the phrasing "ticks after turn". I would prefer consistency, e.g. POISONED_TICKS_AT_TURN_END. This is more clear about the exact triggering event of the tick, rather than nebulously being some time after the turn.


//Begin Issue #1539
/// HL-Docs: feature:DOTsTickAfterTurn; issue:1539; tags:tactical
/// In the base game, DoTs such as bleeding, burning, or poison typically tick at the

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: DOTs instead of DoTs (for consistency)

///
/// This should cover all instances of these effects in the base game, but mods can potentially
/// disregard these helper methods, or explicitly override the effect's `WatchRule` property
/// after calling the helper.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would append a small addendum here: "Mods which create DOT effects without these helper methods should consider accessing these configs to implement similar behavior. This improves compatibility between mods and provides more consistency for the player."

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would that be in addition to the existing paragraph? If so, I might go with something more like this:

"However, it is recommended that mods which create DOT effects either use the appropriate helper methods, or access these configs to implement similar behavior. This improves compatibility between mods and provides more consistency for the player."

If it's replacing the paragraph, I might want to object, on the grounds that someone might have a legitimate interest in knowing how to bypass this feature.

Comment on lines +4 to +6
; Add damage types whose burn DOTs should tick on turn end.
; These must be the same `DamageType` passed to SetBurnDamage() for a given DOT.
;+BURN_TYPES_TICKING_AFTER_TURN="Fire" ; Make burn DOT tick on turn end!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like treating burn separately from other damage types here, unless there's a mod author who has already indicated that, if their DOT effect were moved to end-of-turn, they would add its damage type to the start-of-turn list to explicitly counter it. If such fine-grained control is required, let it be a separate issue raised by whoever wants to use it. We can implement it when (and if) it comes up without any backwards compatibility issues.

Copy link
Author

@DaloLorn DaloLorn Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(...) unless there's a mod author who has already indicated (...)

... There's me. 😂

I actually got into Highlander development to support an extensive TJ-based, LWR-inspired combat overhaul I've been thinking of. (As of yesterday, I've gotten it all to a point where I can playtest it!) I'm not actually sure whether I'll release it to the public yet - partly because it wants all my configs/events to make it into the Highlander in some form - and the closest thing I've got to a formal design doc is in a media/rambling thread in the LWotC Discord, but here's the gist of it:

  • Install Ablative Vests and Energy Shield Overhaul, because why adopt them when I can configure them?
  • Make a derivative of Ablative Vests which does the same thing for armor. (I think all the other mods that already did that were doing other things I didn't agree with or want to include?)
  • Make LW Plating items give armor instead of ablative HP.
  • Make Psi, Bleeding, and Poison damage ignore all defenses: armor, cover, ablative HP, and shields are all useless, all the time. (Might want to compensate by making the DoTs tick on turn end to make Vipers a little less oppressive. [This thought is the whole reason I made this proposal!])
  • Make half of Fire, Napalm, Cold, and Electric damage bypass ablative HP and go straight to HP. [Partial shield bypassing across an entire damage type will require either extensive OPTCing or a far more invasive event than anything I've already had to make for Add events required for cover DR and point-blank bonuses #1540, so I've decided not to do it right now.]
  • Make cover work basically as in LWR: 33/50% DR, no effect at melee range (or versus certain special abilities like the Akimbo's Trick Shot ability). This includes removing the aim penalty and granting the +40% flanking crit chance, essentially dynamically changing the weapon to use the same rules as Trick Shot.
  • Make armor/cover apply before ablative, and can reduce damage to 0. (This is just enabling a few Highlander features, I don't need to do anything besides continuing to use the mod I already use.)
  • Adjust ADVENT units to no longer be giant blobs of HP, and have a percentage of their HP pool converted to ablative HP to represent their armor. Except Avatars and Ethereals, because those can be fluffed as psionic shielding or something.
  • Make Psionic Reaper/Warp Rifle/Psionic Repeater do Psi damage now? [I settled for OPTCing the XCOM weapons to use the same Projectile_BeamAvatar damage type as the Avatar weapons, and then setting that damage type to bypass defenses... though it only now occurs to me that I need to add ESO configs for the same effect.]

TL;DR: While all of my proposals are aiming for maximum flexibility (to the extent that I'm disappointed by my current event payloads for #1540 and #1542 being so laser-focused on the exact data I'm reading), a good chunk of this is because I already need a lot of that flexibility for my own purposes. I probably wouldn't have thought of it otherwise.

Comment on lines +12 to +13
;POISONED_TICKS_AFTER_TURN=true ; Make poison DOT tick on turn end
;BLEEDING_TICKS_AFTER_TURN=true ; Make bleeding DOT tick on turn end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add "instead of turn start" to these. With the lines above the inverse case is clear (ignores/does not ignore shields). For tick timing, it's not as obvious (after turn/before turn/during turn/some other trigger).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be moot, depending on the outcome of our conversation in #1539, but I'll keep it in mind!

Comment on lines +58 to +59
// This isn't how I expected to do this, but I made one critical oversight
// in my initial research: SetBurnDamage isn't what calls BuildPersistentEffect. :o

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite this comment to be less conversational. An observation of where this is handled for poison/bleed, and why the same approach doesn't work for burning, would be sufficient.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this sound?

  // While the helpers used to build poison/bleed DOTs do call BuildPersistentEffect,
  // it appears that burns don't have an equivalent shared behavior we could hook into.
  // Fortunately, burns typically call SetBurnDamage after BuildPersistentEffect,
  // so we can set the WatchRule directly, overriding whatever it was previously set to.

///
///```ini
///[XComGame.X2Effect_Burning]
///+BURN_TYPES_TICKING_AFTER_TURN=Fire ; Make fire burn DOT tick on turn end!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the "!" at end of line for consistency

local X2Effect_ApplyWeaponDamage DamageEffect;
local X2Condition_UnitProperty UnitPropCondition;
//Begin Issue #1539

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know HL convention here. I'd personally leave a comment pointing to the HLDocs comment within CreatePoisonedStatusEffect, but that can be disregarded if it's not consistent.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked at it too thoroughly, but historical precedent (... including the shield bypass features this PR is derivative of...) appears to be to tag every line or block of code with the issue number, but only define HL-Docs in one location.

I suspect the HL-Docs definitions exist primarily to build the online documentation, and nobody's wanted to clog the Highlander up with duplicate doc sheets.

@DaloLorn
Copy link
Author

DaloLorn commented Jan 4, 2026

... Did I not post a comment replying to Ted earlier? 😕

Anyway, took a while to retest the camera panning because XCOM's units being on fire doesn't really come up organically in the early months of a campaign. Now that it finally happened? I couldn't reproduce the issue unless the burn caused a bleedout, and at that point I'm thinking it's either intended behavior or interference from my modlist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants