• Tracker

    Spaces
    Browse
    Statistics
  • /
  • /Game Feedback
  • /ARGF-169
Back
2

Using HitZone::SetHealthScaled during damage handling can cause wrong damage state

Character
2

State

Assigned
Issue key
ARGF-169
Access
Public
Space
Arma Reforger
Project
Game Feedback
Creator
kexanone
Created
Jul 5, 2026
Views
216
Platform
PC
Game Version
1.7.0.54
Mission
—
Is it modded?
no
Description

Since 1.7 there are reports that ACE Medical's second chance feature can cause characters to end up with 0 resilience health without becoming unconscious. ACE uses HitZone::SetHealthScaled to set the health of resilience to 0 when second chance gets triggered. I managed to trace back the issue to a conflict between HitZone::SetHealthScaled and damage handling, which leads the character to end up in the wrong damage state.


Steps to reproduce:

  1. Open Workbench with no mods

  2. Put the code below in a script file and compile it (It will apply damage to the head, use SetHealthScaled(0.0) on resilience when the damage state of the head changes and log resilience health and state in ShouldBeUnconscious)

    //-----------------------------------------------------------------------------------------------------------
    modded class SCR_CharacterHeadHitZone
    {
    	//-----------------------------------------------------------------------------------------------------------
    	//! Set resilience to zero when head hit zone changes state
    	override protected void OnDamageStateChanged(EDamageState newState, EDamageState previousDamageState, bool isJIP)
    	{
    		super.OnDamageStateChanged(newState, previousDamageState, isJIP);
    
    		SCR_CharacterDamageManagerComponent damageManager = SCR_CharacterDamageManagerComponent.Cast(GetHitZoneContainer());
    		if (damageManager)
    			damageManager.GetResilienceHitZone().SetHealthScaled(0.0);
    	}
    }
    
    //-----------------------------------------------------------------------------------------------------------
    modded class SCR_CharacterResilienceHitZone
    {
    	//-----------------------------------------------------------------------------------------------------------
    	//! Turn off resilience regen to keep the broken state
    	override float CalculatePassiveRegenDPS(bool considerRegenScale = true)
    	{
    		return 0;
    	}
    }
    
    //-----------------------------------------------------------------------------------------------------------
    modded class SCR_PlayerController
    {
    	//-----------------------------------------------------------------------------------------------------------
    	//! Apply damage to head when taking control of a character
    	override protected void OnControlledEntityChanged(IEntity from, IEntity to)
    	{
    		super.OnControlledEntityChanged(from, to);
    		
    		SCR_ChimeraCharacter char = SCR_ChimeraCharacter.Cast(to);
    		if (!char)
    			return;
    		
    		SCR_CharacterDamageManagerComponent damageManager = SCR_CharacterDamageManagerComponent.Cast(char.GetDamageManager());
    		if (!damageManager)
    			return;
    		
    		vector hitPosDirNorm[3];
    		SCR_DamageContext damageContext = new SCR_DamageContext(
    			EDamageType.TRUE,
    			1.0,
    			hitPosDirNorm,
    			char,
    			damageManager.GetHitZoneByName("Head"),
    			damageManager.GetInstigator(),
    			null,
    			16,
    			83
    		);
    		damageManager.HandleDamage(damageContext);
    	}
    }
    
    //-----------------------------------------------------------------------------------------------------------
    modded class SCR_CharacterDamageManagerComponent
    {
    	//-----------------------------------------------------------------------------------------------------------
    	//! Log resilience state and health when checking consciousness
    	override bool ShouldBeUnconscious()
    	{
    		HitZone resilienceHZ = GetResilienceHitZone();
    		PrintFormat("|ResilienceDamageState=%1|ResilienceHealth=%2|", SCR_Enum.GetEnumName(ECharacterResilienceState, resilienceHZ.GetDamageState()), resilienceHZ.GetHealth());		
    		return super.ShouldBeUnconscious();
    	}
    }
  3. Run MpTest.ent and check console output:

    SCRIPT       : |ResilienceDamageState=DESTROYED|ResilienceHealth=0|
    SCRIPT       : |ResilienceDamageState=INTERMEDIARY|ResilienceHealth=0|

    Indicating that initially we got the correct state (DESTROYED), but then transition to an incorrect one (INTERMEDIARY)

Related: https://github.com/acemod/ACE-Anvil/issues/464

Reactions

Activity

    3 months ago
  • kexanone
    created issue3 months ago
  • kexanone
    changed3 months ago
  • kexanone
    changed3 months ago
  • kexanone
    changed3 months ago
  • 3 months ago
  • l909
    changed state to
    ASSIGNED
    3 months ago

You are not signed in. Please sign in to see more details and to reply.

State

Assigned
Issue key
ARGF-169
Access
Public
Space
Arma Reforger
Project
Game Feedback
Creator
kexanone
Created
Jul 5, 2026
Views
216