21 static const int BLOOD_CLOTHES_UPDATE_PERIOD = 1000;
24 const float DEATH_BLEEDOUT_SCALE = 4;
82 [
Attribute(
"0.3",
UIWidgets.Auto,
"Resilience regeneration scale while unconscious\n[x * 100%]")]
91 [
Attribute(defvalue:
"4", uiwidget:
UIWidgets.EditBox,
desc:
"When higher, less damage is needed to reach max aimingDamage",
category:
"Damage penalties")]
94 [
Attribute(defvalue:
"3", uiwidget:
UIWidgets.EditBox,
desc:
"When higher, less damage is needed to reach m_fMaxMovementDamage",
category:
"Damage penalties")]
97 [
Attribute(defvalue:
"0.8", uiwidget:
UIWidgets.EditBox,
desc:
"Maximum movement damage. 1 Means max-damage/immobilized",
category:
"Damage penalties")]
100 [
Attribute(defvalue:
"true", uiwidget:
UIWidgets.CheckBox,
desc:
"Allow this character to show bleeding effects on any clothing items when damaged or bleeding",
category:
"Bleeding")]
128 vector characterPosition = character.AimingPosition();
129 vector impactPosition = contact.Position;
130 return impactPosition[1] > characterPosition[1];
142 if (bloodHZ.GetDamageStateThreshold(bloodState) <= bloodHZ.GetDamageStateThreshold(
ECharacterBloodState.UNCONSCIOUS))
153 CharacterControllerComponent controller = character.GetCharacterController();
159 if (controller.IsUnconscious())
161 if (resilienceHZ.GetDamageStateThreshold(resilienceState) <= resilienceHZ.GetDamageStateThreshold(
ECharacterResilienceState.WEAKENED))
166 if (resilienceHZ.GetDamageStateThreshold(resilienceState) <= resilienceHZ.GetDamageStateThreshold(
ECharacterResilienceState.UNCONSCIOUS))
198 CharacterControllerComponent controller = character.GetCharacterController();
202 controller.SetUnconscious(unconscious);
217 resilienceHZ.HandleDamage(resilienceHZ.GetMaxHealth() - (resilienceHZ.GetMaxHealth() * resilienceHealth),
EDamageType.TRUE, null);
266 foreach (
string hitZoneName : armorAttr.m_aProtectedHitZones)
268 SCR_CharacterHitZone hitZone = SCR_CharacterHitZone.Cast(GetHitZoneByName(hitZoneName));
279 armorAttr.m_eProtection,
280 armorAttr.m_aProtectedHitZones,
281 armorAttr.m_aProtectedDamageTypes,
282 armorAttr.m_MaterialResourceName
293 SCR_CharacterHitZone charHitZone = SCR_CharacterHitZone.Cast(struckHitzone);
301 if (!armorData.m_Material)
304 return armorData.m_Material.GetResource().ToBaseContainer();
328 foreach (
EDamageType protectedType : localArmorData.m_aProtectedDamageTypes)
330 if (damageType == protectedType)
331 return localArmorData.m_eProtection;
345 CharacterControllerComponent controller = character.GetCharacterController();
365 super.OnDamageEffectAdded(dmgEffect);
367 if (dmgEffect.GetAffectedHitZone().IsProxy())
370 if (dmgEffect.GetDamageType() ==
EDamageType.HEALING)
379 array<ref SCR_PersistentDamageEffect> effects = {};
392 super.OnDamageEffectRemoved(dmgEffect);
394 if (dmgEffect.GetAffectedHitZone().IsProxy())
397 EDamageType localDamageType = dmgEffect.GetDamageType();
420 if (damageContext.damageType ==
EDamageType.COLLISION && damageContext.struckHitZone == GetDefaultHitZone())
422 if (damageContext.damageValue > damageContext.struckHitZone.GetDamageThreshold())
444 CharacterControllerComponent controller = character.GetCharacterController();
448 SCR_InventoryStorageManagerComponent storageMgr = SCR_InventoryStorageManagerComponent.Cast(controller.GetInventoryStorageManager());
453 if (!characterStorage)
458 hatIIC.DetachHelmet(damageContext.damageValue, damageContext.damageType, damageContext.hitDirection, damageContext.hitPosition, character);
467 array<ref SCR_PersistentDamageEffect> persistentEffects = {};
468 GetPersistentEffects(persistentEffects);
471 if (effect.Type() != effectType)
489 array<ref SCR_PersistentDamageEffect> persistentEffects = {};
490 GetPersistentEffects(persistentEffects);
493 if (effect != broadcastingEffect)
504 if (!broadcastingEffect.ExecuteSynchronizedSoundPlayback(
this))
516 array<ref SCR_PersistentDamageEffect> persistentEffects = {};
517 GetPersistentEffects(persistentEffects);
523 effect.ExecuteSynchronizedSoundPlayback(
this);
590 bleedingRate = DEATH_BLEEDOUT_SCALE *
m_pBloodHitZone.GetTotalBleedingAmount();
593 if (bleedingRate > 0)
609 EquipedLoadoutStorageComponent loadoutStorage = EquipedLoadoutStorageComponent.Cast(
GetOwner().FindComponent(EquipedLoadoutStorageComponent));
613 array<ref LoadoutAreaType> bleedingAreas = hitZone.GetBleedingAreas();
619 clothEntity = loadoutStorage.GetClothFromArea(bleedingArea.Type());
624 if (!materialComponent)
627 float newBloodValue = materialComponent.GetUserParam2() +
Math.Ceil(immediateBloodEffect * 0.1);
628 materialComponent.SetUserParam2(
Math.Clamp(newBloodValue, 1, 255));
635 array<ref SCR_PersistentDamageEffect> effects = {};
636 GetPersistentEffects(effects);
639 array<HitZone> hitZones = {};
640 GetAllHitZonesInHierarchy(hitZones);
641 foreach (
HitZone hitZone : hitZones)
643 if (hitZone && hitZone.GetDamageState() !=
EDamageState.UNDAMAGED)
651 if (ignoreHealingDOT)
663 override void FullHeal(
bool ignoreHealingDOT =
true)
665 if (!ignoreHealingDOT)
667 array<ref SCR_PersistentDamageEffect> effects = {};
668 GetPersistentEffects(effects);
680 super.FullHeal(ignoreHealingDOT);
690 GetGame().GetCallqueue().CallLater(ClearDamageHistory, 1500);
698 ClearDamageHistory();
722 if (criticalBloodLevel >= 1)
726 if (currentBloodLevel < criticalBloodLevel)
729 float resilienceRegenScale = (currentBloodLevel - criticalBloodLevel) / (1 - criticalBloodLevel);
735 if (character.GetCharacterController().GetLifeState() ==
ECharacterLifeState.INCAPACITATED)
739 return resilienceRegenScale;
812 if (timeToUnconscious < timeToWake)
873 AddDamageEffect(effect);
884 if (hitZone.IsProxy())
888 float hitZoneDamageMultiplier = hitZone.GetHealthScaled();
889 float bleedingRate = hitZone.GetMaxBleedingRate() - hitZone.GetMaxBleedingRate() * hitZoneDamageMultiplier;
892 if (colliderDescriptorIndex == -1)
894 int descriptorCnt = hitZone.GetNumColliderDescriptors();
895 if (descriptorCnt == 1)
896 colliderDescriptorIndex = 0;
897 else if (descriptorCnt > 1)
898 colliderDescriptorIndex =
Math.RandomInt(0, descriptorCnt - 1);
901 hitZoneBleeding.m_iColliderDescriptorIndex = colliderDescriptorIndex;
903 hitZoneBleeding.SetMaxDuration(0);
904 hitZoneBleeding.SetDamageType(
EDamageType.BLEEDING);
905 hitZoneBleeding.SetAffectedHitZone(hitZone);
907 AddDamageEffect(hitZoneBleeding);
942 if (
System.IsConsoleApp())
952 SCR_CharacterHitZone characterHitZone = SCR_CharacterHitZone.Cast(hitZone);
953 if (!characterHitZone || characterHitZone.IsCovered())
956 array<HitZone> groupHitZones = {};
960 foreach (
HitZone groupHitZone : groupHitZones)
974 if (!hitZone.TryGetColliderDescription(
GetOwner(), colliderDescriptorIndex, transform, boneIndex, boneNode))
980 spawnParams.PivotID = boneNode;
982 if (
System.IsConsoleApp())
985 if (!particleEmitter)
987 Print(
"Particle emitter: " + particleEmitter.ToString() +
" There was a problem with creating the particle emitter: " +
m_sBleedingParticle,
LogLevel.WARNING);
998 Particles particles = particleEmitter.GetParticles();
1013 array<HitZone> hitZones = {};
1017 hitZone = effect.GetAffectedHitZone();
1018 if (!hitZones.Contains(hitZone))
1019 hitZones.Insert(hitZone);
1022 foreach (
HitZone hz : hitZones)
1038 if (particleEmitter)
1040 particleEmitter.StopEmission();
1065 array<ref SCR_PersistentDamageEffect> effects = {};
1066 array<HitZone> hitZones = {};
1069 foreach (
HitZone hitZone : hitZones)
1071 FindDamageEffectsOnHitZone(hitZone, effects);
1074 if (effect.GetDamageType() ==
EDamageType.BLEEDING)
1075 TerminateDamageEffect(effect)
1086 SCR_CharacterHitZone targetHitZone = SCR_CharacterHitZone.Cast( GetHitZoneByName(hitZoneName));
1088 if (!targetHitZone || targetHitZone.IsProxy())
1096 if (intensityFloat < 0)
1097 targetHitZone.SetHealthScaled(targetHitZone.GetDamageStateThreshold(
ECharacterDamageState.WOUNDED));
1099 targetHitZone.SetHealthScaled(intensityFloat);
1108 array<HitZone> hitZones = {};
1109 array<HitZone> validHitZones = {};
1112 foreach (
HitZone hitZone: hitZones)
1115 SCR_CharacterHitZone characterHitZone = SCR_CharacterHitZone.Cast(hitZone);
1116 if (!characterHitZone)
1120 if (!includeBleedingHZs)
1127 validHitZones.Insert(characterHitZone);
1130 if (validHitZones.IsEmpty())
1133 SCR_CharacterHitZone hitZone = SCR_CharacterHitZone.Cast(validHitZones.GetRandomElement());
1147 array<HitZone> hitZones = {};
1150 SCR_CharacterHitZone charHitZone;
1152 foreach (
HitZone hitZone : hitZones)
1154 charHitZone = SCR_CharacterHitZone.Cast(hitZone);
1155 if (charHitZone && charHitZone.GetBodyPartToHeal() == bodyPartToBandage)
1156 return charHitZone.GetHitZoneGroup();
1165 array<HitZone> hitZones = {};
1168 SCR_CharacterHitZone charHitZone;
1170 foreach (
HitZone hitZone : hitZones)
1172 charHitZone = SCR_CharacterHitZone.Cast(hitZone);
1173 if (charHitZone && charHitZone.GetHitZoneGroup() == hitZoneGroup)
1174 return charHitZone.GetBodyPartToHeal();
1183 array<HitZone> allGroupedHitZones = {};
1184 GetAllHitZones(allGroupedHitZones);
1185 SCR_CharacterHitZone charHitZone;
1187 foreach (
HitZone hitZone : allGroupedHitZones)
1189 charHitZone = SCR_CharacterHitZone.Cast(hitZone);
1190 if (charHitZone && charHitZone.GetBodyPartToHeal() == eBandagingAnimBodyParts)
1191 GroupHitZones.Insert(hitZone);
1198 float totalGroupHealth;
1199 float hitZoneQuantity;
1201 array<HitZone> allGroupedHitZones = {};
1202 GetAllHitZones(allGroupedHitZones);
1203 SCR_CharacterHitZone charHitZone;
1205 foreach (
HitZone hitZone : allGroupedHitZones)
1207 charHitZone = SCR_CharacterHitZone.Cast(hitZone);
1208 if (!charHitZone || charHitZone.GetHitZoneGroup() != hitZoneGroup)
1211 totalGroupHealth += charHitZone.GetHealthScaled();
1215 if (hitZoneQuantity <= 0)
1218 return totalGroupHealth / hitZoneQuantity;
1224 float totalGroupDOT;
1225 array<HitZone> groupHitZones = {};
1229 array<ref PersistentDamageEffect> effects = {};
1230 foreach (
HitZone hitZone : groupHitZones)
1237 return totalGroupDOT;
1249 if (setTourniquetted)
1281 if (setIsBeingHealed)
1313 if (setSalineBagged)
1338 array<ref SCR_PersistentDamageEffect> effects = {};
1339 GetPersistentEffects(effects);
1342 if (effect.GetDamageType() ==
EDamageType.BLEEDING)
1355 array<HitZone> hitZones = {};
1357 if (includeVirtualHZs)
1358 GetAllHitZones(hitZones);
1362 foreach (
HitZone hitZone : hitZones)
1366 SCR_CharacterHitZone charHitZone = SCR_CharacterHitZone.Cast(hitZone);
1370 if (!allowedGroups.Contains(charHitZone.GetHitZoneGroup()))
1375 array<ref SCR_PersistentDamageEffect> damageEffects = {};
1376 FindDamageEffectsOnHitZone(hitZone, damageEffects);
1380 if (damageType != effect.GetDamageType())
1387 localDOT += dotEffect.GetDPS();
1390 if (localDOT > highestDOT)
1392 highestDOT = localDOT;
1393 highestDOTHitZone = hitZone;
1396 return highestDOTHitZone;
1400 static void GetAllLimbs(notnull out array<ECharacterHitZoneGroup> limbs)
1414 const float TOURNIQUETTED_LEG_DAMAGE = 0.7;
1415 const float TOURNIQUETTED_ARMS_DAMAGE = 0.7;
1419 float leftLegDamage;
1421 leftLegDamage = TOURNIQUETTED_LEG_DAMAGE;
1425 float rightLegDamage;
1427 rightLegDamage = TOURNIQUETTED_LEG_DAMAGE;
1438 float leftArmDamage;
1440 leftArmDamage = TOURNIQUETTED_ARMS_DAMAGE;
1444 float rightArmDamage;
1446 rightArmDamage = TOURNIQUETTED_ARMS_DAMAGE;
1451 SetAimingDamage(armDamage);
1466 array<float> DOTValues = {};
1468 int groupCount = groupEnum.GetVariableCount();
1470 for (
int i; i < groupCount; i++)
1471 DOTValues.Insert(0);
1474 array<HitZone> hitZones = {};
1477 SCR_CharacterHitZone charHitZone;
1480 foreach (
HitZone hitZone : hitZones)
1482 charHitZone = SCR_CharacterHitZone.Cast(hitZone);
1487 group = charHitZone.GetHitZoneGroup();
1495 float DOT = charHitZone.GetHitZoneDamageOverTime(
EDamageType.BLEEDING);
1503 if (ignoreTQdHitZones)
1513 if (ignoreIfBeingTreated)
1525 for (
int i; i < groupCount; i++)
1527 if (DOTValues[i] > highestDOT)
1529 highestDOT = DOTValues[i];
1530 mostDOTHitZoneGroup = i;
1560 return "LeftForeArm";
1565 return "RightForeArm";
1579 return string.Empty;
1585 super.OnPostInit(owner);
1602 RplComponent rpl = RplComponent.Cast(owner.
FindComponent(RplComponent));
1605 auto hz = GetDefaultHitZone();
1606 if (hz && !hz.IsProxy())
1608 SCR_CharacterBuoyancyComponent charBuoyancyComp = SCR_CharacterBuoyancyComponent.Cast(owner.
FindComponent(SCR_CharacterBuoyancyComponent));
1609 if (charBuoyancyComp)
1610 charBuoyancyComp.GetOnWaterEnter().Insert(
OnWaterEnter);
1623 if (
System.IsCLIParam(
"logPlayerDamage"))
1634 regen.SetAffectedHitZone(GetDefaultHitZone());
1637 regen.SkipRegenDelay(skipRegenDelay);
1638 AddDamageEffect(regen);
1653 regen.SetAffectedHitZone(targetHitZone);
1656 regen.SkipRegenDelay(skipRegenDelay);
1657 AddDamageEffect(regen);
1680 vector totalVelocity = physics.GetVelocity();
1684 vector ownerTransform[4];
1685 physics.GetDirectWorldTransform(ownerTransform);
1695 if (!
IsFallingVehicle(owner, other, contact) && (
Math.AbsFloat(contact.GetRelativeNormalVelocityBefore()) <= 3))
1699 float relativeNormalVelocityBefore =
Math.AbsFloat(contact.GetRelativeNormalVelocityBefore());
1703 if (!super.FilterContact(owner, other, contact))
1710 if (!otherPhys.IsDynamic())
1713 float otherMomentum = contact.VelocityBefore2.Length() * otherPhys.GetMass();
1721 vector otherPositionBeforeContact = contact.Position - (contact.VelocityBefore2.Normalized());
1722 vector ownerPositionBeforeContact = contact.Position - (contact.VelocityBefore1.Normalized());
1724 vector otherDirectionToCollisionPoint =
vector.Direction(otherPositionBeforeContact, contact.Position).Normalized();
1725 vector ownerDirectionToCollisionPoint =
vector.Direction(ownerPositionBeforeContact, contact.Position).Normalized();
1727 float otherDot =
vector.Dot(contact.VelocityBefore2.Normalized(), otherDirectionToCollisionPoint);
1731 otherMomentum *= otherDot;
1733 float ownerDot =
vector.Dot(contact.VelocityBefore1.Normalized(), ownerDirectionToCollisionPoint);
1734 float ownerMomentum = contact.VelocityBefore1.Length() * ownerPhys.GetMass() * ownerDot;
1736 float directionalMomentum = otherMomentum + ownerMomentum;
1746 if (remainingTime == -1)
1773 float relativeNormalVelocityBefore =
Math.AbsFloat(contact.GetRelativeNormalVelocityBefore());
1788 HitZone defaultHitZone = GetDefaultHitZone();
1789 if (defaultHitZone.GetDamageState() ==
EDamageState.DESTROYED)
1792 if (instantUnconsciousness)
1797 float damageScaleToCharacter = (momentumCharacterDestroy - momentumCharacterThreshold) * 0.0001;
1801 float damageValue = damageScaleToCharacter * (impactMomentum - momentumCharacterThreshold);
1802 if (damageValue <= 0)
1807 const int impulseDelay = 200;
1809 if (remainingTime == -1)
1823 HitZone defaultHitZone = GetDefaultHitZone();
1824 if (defaultHitZone.GetDamageState() ==
EDamageState.DESTROYED)
1829 float damage =
Math.InverseLerp(prefabData.GetFallDamageLimitNoDamage(), prefabData.GetFallDamageLimitFullDamage(), velocityVector.Length());
1846 array<HitZone> targetHitZones = {};
1849 if (targetHitZones.IsEmpty())
1852 const float overDamageCutOff = 50;
1853 if (damage > overDamageCutOff)
1861 foreach (
HitZone hitZone : targetHitZones)
1863 context.struckHitZone = hitZone;
1868 SCR_CharacterAnimationComponent animComp = SCR_CharacterAnimationComponent.Cast(
GetOwner().FindComponent(SCR_CharacterAnimationComponent));
1871 float randomDirectional =
Math.RandomFloat(-0.5, 0.3);
1872 animComp.AddRagdollEffectorDamage(
Vector(randomDirectional, 1, 0),
Vector(randomDirectional, -0.5, 0.3).Normalized(), 82, 15, 2);
1879 array<int> colliderIDs = {};
1880 contactingHitZone.GetColliderIDs(colliderIDs);
1881 if (colliderIDs.IsEmpty())
1884 vector colliderTransform[4];
1887 physics.GetGeomWorldTransform(colliderIDs[0], colliderTransform);
1889 array<HitZone> targetHitZones = {};
1893 if (targetHitZones.IsEmpty())
1897 hitPosDirNorm[0] = colliderTransform[3];
1902 foreach (
HitZone hitZone : targetHitZones)
1904 context.struckHitZone = hitZone;
1915 HitZone defaultHitZone = GetDefaultHitZone();
1916 if (defaultHitZone.GetDamageState() ==
EDamageState.DESTROYED)
1919 array<HitZone> characterHitZones = {};
1920 GetAllHitZones(characterHitZones);
1923 const int hitZonesReturnAmount = 6;
1927 if (vehicle && vehicle.GetPilot())
1928 other = vehicle.GetPilot();
1931 hitPosDirNorm[0] = collisionPosition;
1935 foreach (
HitZone characterHitZone : characterHitZones)
1937 if (characterHitZone.GetDamageState() ==
EDamageState.DESTROYED)
1940 context.struckHitZone = characterHitZone;
1950 if (soundEventName.IsEmpty())
1957 soundComp.SoundEvent(soundEventName);
1967 if (nearestHitZones.IsEmpty())
1970 array<vector> colliderDistances = {};
1971 array<int> IDs = {};
1974 vector colliderTransform[4];
1978 foreach (
HitZone hitZone : nearestHitZones)
1980 if (!hitZone.HasColliderNodes())
1984 hitZone.GetColliderIDs(IDs);
1985 foreach (
int ID : IDs)
1987 physics.GetGeomWorldTransform(
ID, colliderTransform);
1988 relativePosition = worldPosition - colliderTransform[3];
1989 colliderDistance = {relativePosition.LengthSq(),
ID, 0};
1990 colliderDistances.Insert(colliderDistance);
1995 colliderDistances.Sort();
1997 array<int> closestIDs = {};
1998 for (
int i; i < hitZonesReturnAmount; i++)
2000 closestIDs.InsertAt(colliderDistances[i][1], i);
2003 nearestHitZones.Clear();
2004 GetHitZonesByColliderIDs(nearestHitZones, closestIDs);
2012 if (newInstigator.GetInstigatorEntity() ==
GetOwner())
2015 if (character && character.GetCharacterController().GetLifeState() ==
ECharacterLifeState.INCAPACITATED)
2019 return super.ShouldOverrideInstigator(currentInstigator, newInstigator);
2026 super.OnDamageStateChanged(newState, previousDamageState, isJIP);
2035 super.OnDamage(damageContext);
2037 if (damageContext.damageValue > 0)
2052 string instigatorName;
2053 int instigatorID = damageContext.instigator.GetInstigatorPlayerID();
2054 IEntity instigatorEntity = damageContext.instigator.GetInstigatorEntity();
2056 if (instigatorID > 0)
2058 instigatorName =
GetGame().GetPlayerManager().GetPlayerName(instigatorID);
2063 if (instigatorEntity)
2067 prefabName = prefabData.GetPrefabName();
2070 if (prefabName.IsEmpty())
2072 if (instigatorEntity)
2078 instigatorName = instigatorEntity.ToString();
2084 prefabName.Split(
"/", strs,
true);
2085 instigatorName = ((instigatorEntity.
GetID()).
ToString()) + strs[strs.Count() - 1];
2090 int hzOwnerID =
GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(hzOwner);
2093 hzOwnerName =
GetGame().GetPlayerManager().GetPlayerName(hzOwnerID);
2100 if (prefabName.IsEmpty())
2107 prefabName.Split(
"/", strs,
true);
2108 hzOwnerName = ((hzOwner.
GetID()).
ToString()) + strs[strs.Count() - 1];
2113 PrintFormat(
"HIT LOG: (%1) damaged (%2) - [Damage = %3, Speed = %4]", instigatorName, hzOwnerName, damageContext.damageValue, damageContext.impactVelocity);
2121 override void DiagOnlyIfPossessedByPlayerController(notnull
IEntity owner)
2129 DbgUI.Text(
"See: GameCode >> Hit Zones >> Player HitZones for damages");
2130 DbgUI.Text(
"Applying damage from client is NOT possible");
2131 DbgUI.Text(
"Only conventional DOT damage are shown in debug");
2132 DbgUI.Text(
"Y to damage every hitZone for 4 damage");
2133 DbgUI.Text(
"U to reduce chest health by 10");
2134 DbgUI.Text(
"I to reduce right thigh health by 10");
2135 DbgUI.Text(
"O to reduce left thigh health by 10");
2136 DbgUI.Text(
"P to add bleeding to right thigh");
2137 DbgUI.Text(
"T to add bleeding to left thigh");
2138 DbgUI.Text(
"K to reset damage effect");
2140 vector hitPosDirNorm[3];
2162 SCR_DamageContext damageContext =
new SCR_DamageContext(
EDamageType.TRUE, 10, hitPosDirNorm, owner, GetHitZoneByName(
"RThigh"), Instigator.CreateInstigator(owner), null, -1, -1);
2169 SCR_DamageContext damageContext =
new SCR_DamageContext(
EDamageType.TRUE, 10, hitPosDirNorm, owner, GetHitZoneByName(
"LThigh"), Instigator.CreateInstigator(owner), null, -1, -1);
ArmaReforgerScripted GetGame()
SCR_BaseGameMode GetGameMode()
override bool HandleDamage(BaseDamageContext damageContext, IEntity owner)
EBandagingAnimationBodyParts
ECharacterResilienceState
SCR_CharacterSoundComponentClass GetComponentData()
int GetHitZonesOfGroupsFromOwner(notnull array< EHitZoneGroup > hitZoneGroups, out notnull array< HitZone > groupHitZones)
int GetHitZonesOfGroupFromOwner(EHitZoneGroup hitZoneGroup, out notnull array< HitZone > groupHitZones, bool clearArray=true)
void GetPhysicalHitZones(out notnull array< HitZone > physicalHitZones)
Return hit zones with colliders assigned.
void Kill(notnull Instigator instigator)
float HealHitZones(float healthToDistribute, bool sequential=false, float maxHealThresholdScaled=1, array< HitZone > alternativeHitZones=null)
void ParticleEffectEntity(IEntitySource src, IEntity parent)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
enum EVehicleType IEntity
proto external Managed FindComponent(typename typeName)
proto external Physics GetPhysics()
proto external EntityID GetID()
proto external EntityPrefabData GetPrefabData()
SCR_GameModeHealthSettings GetGameModeHealthSettings()
Blood - does not receive damage directly, only via scripted events.
ref OnLifeStateChangedInvoker m_OnLifeStateChanged
void UpdateConsciousness()
SCR_CharacterHeadHitZone GetHeadHitZone()
float m_fTourniquetStrengthMultiplier
SCR_CommunicationSoundComponent m_CommunicationSound
float GetGroupHealthScaled(ECharacterHitZoneGroup hitZoneGroup)
override void OnHandleFallDamage(EFallDamageType fallDamageType, vector velocityVector)
void SetOverrideCharacterMedicalGMAttribute(bool permit)
void SetResilienceHitZone(HitZone hitZone)
void SetBloodHitZone(HitZone hitZone)
bool m_bOverrideCharacterMedicalGMAttribute
bool GetPermitUnconsciousness()
Returns whether unconsciousness is permitted. Character prefab has highest authority,...
void HandleRagdollFallDamage(notnull HitZone contactingHitZone, float damage)
ref map< SCR_CharacterHitZone, ref SCR_ArmoredClothItemData > m_mClothItemDataMap
float m_fMaxMovementDamage
bool SynchronizedSoundEvent(typename effectType)
void KnockOffTheHelmet(notnull BaseDamageContext damageContext)
override GameMaterial OverrideHitMaterial(HitZone struckHitzone)
static SCR_GameModeHealthSettings s_HealthSettings
static const ref array< ECharacterHitZoneGroup > EXTREMITY_LIMB_GROUPS
ref array< ECharacterHitZoneGroup > m_aTourniquettedGroups
const int MIN_OTHER_MOMENTUM
override bool FilterContact(IEntity owner, IEntity other, Contact contact)
Filter out any contacts under a reasonable speed for damage.
void SetBleedingScale(float rate, bool changed)
void CalculateCollisionDamage(IEntity owner, IEntity other, vector collisionPosition, float highestCachedImpulse=0, bool instantUnconsciousness=true)
ref array< HitZone > m_aBleedingHitZones
ECharacterHitZoneGroup GetCharMostDOTHitzoneGroup(EDamageType damageType, bool onlyExtremities=false, bool ignoreTQdHitZones=false, bool ignoreIfBeingTreated=false)
ref array< ECharacterHitZoneGroup > m_aSalineBaggedGroups
void ApplyCollisionDamage(IEntity other, vector collisionPosition, float damageValue)
bool GetGroupIsBeingHealed(ECharacterHitZoneGroup hitZoneGroup)
static ref array< ECharacterHitZoneGroup > LIMB_GROUPS
void TryClearDamageHistory()
int m_fMinWaterFallDamageVelocity
float m_fAimingDamageMultiplier
float GetTourniquetStrengthMultiplier()
float m_fVehicleFallDamage
void PlaySoundEvent(string soundEventName)
void SetGroupIsBeingHealed(ECharacterHitZoneGroup hitZoneGroup, bool setIsBeingHealed)
bool GetGroupSalineBagged(ECharacterHitZoneGroup hitZoneGroup)
void SetPermitUnconsciousness(bool permit, bool changed)
static void GetAllExtremities(notnull out array< ECharacterHitZoneGroup > limbs)
SCR_CharacterBloodHitZone m_pBloodHitZone
float m_fWaterFallDamageMultiplier
void RemoveArmorData(notnull SCR_CharacterHitZone charHitZone)
Remove armor data from clothing item prefab from map, delete map if empty.
SCR_CharacterHitZone GetRandomPhysicalHitZone(bool includeBleedingHZs=false)
Get a random physical hitZone.
bool m_bUnconsciousnessSettingsChangedByGM
void RegenVirtualHitZone(SCR_RegeneratingHitZone targetHitZone, float dps=-1, bool skipRegenDelay=false)
void SetExactMinImpulse(IEntity owner)
void ArmorHitEventEffects(float damage)
Function called from SCR_ArmorDamageManagerComponent in case player is shot in armor....
float GetArmorProtection(notnull SCR_CharacterHitZone charHitZone, EDamageType damageType)
Get protection value of particular hitZone stored on m_mClothItemDataMap.
SCR_CharacterResilienceHitZone GetResilienceHitZone()
void ArmorHitEventDamage(EDamageType type, float damage, IEntity instigator)
Function called from SCR_ArmorDamageManagerComponent in case player is shot in armor....
ref array< float > m_aGroupBleedingRates
void CreateBleedingParticleEffect(notnull HitZone hitZone, int colliderDescriptorIndex)
Called to start bleeding effect on a specificied bone.
bool m_bAllowBloodyClothes
override void FullHeal(bool ignoreHealingDOT=true)
bool IsFallingVehicle(IEntity owner, IEntity other, Contact contact)
float GetPoisonBuildupFactor()
override void OnDamage(notnull BaseDamageContext damageContext)
bool GetOverrideCharacterMedicalGMAttribute()
bool m_bRegenScaleChangedByGM
void RegenPhysicalHitZones(bool skipRegenDelay=false)
bool IsIndefinitelyUnconscious(bool onlyPlayers=true)
Returns whether this character will remain unconscious with no chance to wake up without intervention...
string GetBoneName(ECharacterHitZoneGroup hzGroup)
Get bone name for given hz group.
void HandleAnimatedFallDamage(float damage)
bool m_bPermitUnconsciousness
float m_fPoisonBuildupFactor
void SoundHit(bool critical, EDamageType damageType)
override void OnDamageEffectRemoved(notnull SCR_DamageEffect dmgEffect)
HitZone GetMostDOTHitZone(EDamageType damageType, bool includeVirtualHZs=false, array< EHitZoneGroup > allowedGroups=null)
float m_fBleedingParticleRateScale
void AddRandomBleeding()
Add bleeding to a random physical hitZone.
SCR_CharacterBloodHitZone GetBloodHitZone()
SCR_CharacterResilienceHitZone m_pResilienceHitZone
bool GetGroupTourniquetted(ECharacterHitZoneGroup hitZoneGroup)
const int MINIMUM_IMPULSE_RESET_TIME
void RemoveGroupBleeding(ECharacterHitZoneGroup charHZGroup)
Terminate all bleeding effects on every hitZone of a group.
void InsertArmorData(notnull SCR_CharacterHitZone charHitZone, SCR_ArmoredClothItemData attributes)
Insert armor data from clothing item prefab into map, create map if null.
void RemoveAllBleedings()
Stop all bleeding.
float m_fMovementDamageMultiplier
bool ShouldBeUnconscious()
Check whether character health state meets requirements for consciousness.
bool m_bDOTScaleChangedByGM
void RemoveAllBleedingParticles()
Remove all bleeding particle effects from all bleeding hitZones.
float m_fUnconsciousRegenerationScale
void GetHealingAnimHitzones(EBandagingAnimationBodyParts eBandagingAnimBodyParts, out notnull array< HitZone > GroupHitZones)
void SetRegenScale(float rate, bool changed)
bool IsBleeding()
the official and globally used way of checking if bleeding tests for any PERSISTENT damage effects of...
void OnLifeStateChanged(ECharacterLifeState previousLifeState, ECharacterLifeState newLifeState, bool isJIP)
void AddSpecialContactEffect(notnull SCR_SpecialCollisionDamageEffect effect)
void SoundDeath(int previousLifestate)
Tell m_CommunicationSound that this character is now dead.
void SetTourniquettedGroup(ECharacterHitZoneGroup hitZoneGroup, bool setTourniquetted)
void AddBleedingToArray(notnull HitZone hitZone)
Register hitzone in array as bleeding.
void UpdateCharacterGroupDamage(ECharacterHitZoneGroup hitZoneGroup)
void SetSalineBaggedGroup(ECharacterHitZoneGroup hitZoneGroup, bool setSalineBagged)
ref array< int > m_aBeingHealedGroup
SCR_CharacterHeadHitZone m_pHeadHitZone
void UpdateArmorDataMap(notnull SCR_ArmoredClothItemData armorAttr, bool remove)
If !remove, take data from prefab and insert to map as class. If remove, remove this hitZone's stored...
override void OnDamageStateChanged(EDamageState newState, EDamageState previousDamageState, bool isJIP)
Invoked when damage state changes.
void RemoveAllBleedingParticlesAfterDeath()
Clean up blood particle sources after death.
void GetNearestHitZones(vector worldPosition, notnull inout array< HitZone > nearestHitZones, int hitZonesReturnAmount)
SCR_ArmoredClothItemData GetArmorData(notnull SCR_CharacterHitZone charHitZone)
Get data from m_mClothItemDataMap.
EBandagingAnimationBodyParts FindAssociatedBandagingBodyPart(ECharacterHitZoneGroup hitZoneGroup)
void AddBleedingEffectOnHitZone(notnull SCR_CharacterHitZone hitZone, int colliderDescriptorIndex=-1)
float GetResilienceRegenScale()
array< HitZone > GetBleedingHitZones()
override void OnDamageEffectAdded(notnull SCR_DamageEffect dmgEffect)
override void OnPostInit(IEntity owner)
void OnFilteredContact(IEntity owner, IEntity other, Contact contact)
ECharacterHitZoneGroup FindAssociatedHitZoneGroup(EBandagingAnimationBodyParts bodyPartToBandage)
ref map< HitZone, ParticleEffectEntity > m_mBleedingParticles
void RemoveBleedingParticleEffect(HitZone hitZone)
void SetHeadHitZone(HitZone hitZone)
void SoundKnockout()
Tell m_CommunicationSound to stop character from screaming, otherwise ignore.
override bool HijackDamageHandling(notnull BaseDamageContext damageContext)
Hijack collisiondamage in case it's applied to defaultHZ, since that means it's falldamage.
float m_fVehicleFallTriggerVelocity
void AddParticularBleeding(string hitZoneName="Chest", ECharacterDamageState intensityEnum=ECharacterDamageState.WOUNDED, float intensityFloat=-1)
Add bleeding to a particular physical hitZone.
void Do_SynchronizedSoundEvent(int effectId)
void ForceUnconsciousness(float resilienceHealth=0)
ResourceName m_sBleedingParticle
void AddBloodToClothes(notnull SCR_CharacterHitZone hitZone, float immediateBloodEffect)
static void GetAllLimbs(notnull out array< ECharacterHitZoneGroup > limbs)
bool SynchronizedSoundEvent(notnull SCR_PersistentDamageEffect broadcastingEffect, int effectId=-1)
override bool ShouldOverrideInstigator(notnull Instigator currentInstigator, notnull Instigator newInstigator)
Called whenever an instigator is going to be set.
override bool CanBeHealed(bool ignoreHealingDOT=true)
void RemoveBleedingFromArray(notnull HitZone hitZone)
Unregister hitzone from array.
override float GetGroupDamageOverTime(ECharacterHitZoneGroup hitZoneGroup, EDamageType damageType)
InventoryItemComponent GetItemFromLoadoutSlot(LoadoutAreaType eSlot)
void ApplyDamagePassRules(notnull BaseDamageContext damageContext)
float GetHitZoneDamageOverTime(EDamageType targetDamageType)
Get current total damage per second of this hitZone.
enum EPhysicsLayerPresets Vehicle
IEntity GetOwner()
Owner entity of the fuel tank.
array< ref SCR_PersistentDamageEffect > GetAllPersistentEffectsOfType(typename effectTypeName, bool includeInheritedTypes=false)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
proto void PrintFormat(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL, LogLevel level=LogLevel.NORMAL)
SCR_FieldOfViewSettings Attribute
proto external EParticleEffectState GetState()
BaseProjectileComponentClass GameComponentClass GetInstigator()
void RplRpc(RplChannel channel, RplRcver rcver, RplCondition condition=RplCondition.None, string customConditionName="")
RplChannel
Communication channel. Reliable is guaranteed to be delivered. Unreliable not.
array< string > TStringArray
proto external string ToString()
Plain C++ pointer, no weak pointers, no memory management.
proto native vector Vector(float x, float y, float z)
@ ID
Ordered by Group application ID.