• Tracker

    Spaces
    Browse
    Statistics
  • Issues
  • Using HitZone::SetHealthScaled during damage handling can cause wrong damage state
Back

2

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

Character

Issue Key

ARGF-169

State

Assigned

Access

Public

Group

Arma Reforger

Project

Game Feedback

Creator

kexanone

Created

Jul 5, 2026

Views

121

Attachments

No attachments

Platform

PC

Game Version

1.7.0.54

Mission

 

Is it modded?

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

Activity

    about 2 months ago

  • kexanone
    created issueabout 2 months ago
  • kexanone
    changedabout 2 months ago
  • kexanone
    changedabout 2 months ago
  • kexanone
    changedabout 2 months ago
  • about 2 months ago

  • l909
    changed state to
    ASSIGNED
    about 2 months ago

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

Issue Key

ARGF-169

State

Assigned

Access

Public

Group

Arma Reforger

Project

Game Feedback

Creator

kexanone

Created

Jul 5, 2026

Views

121

Attachments

No attachments