From 2a06dcb0c98529a5a529f3aaa7f905d4152a4cba Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Tue, 5 Jul 2022 18:46:37 +0700 Subject: [PATCH] Document health component more --- config/AcediaSystem.ini | 24 +++++++++++++ .../KF1Frontend/Health/KF1_HealthComponent.uc | 34 +++++++++++++++++-- sources/ServerLevelCore.uc | 2 +- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/config/AcediaSystem.ini b/config/AcediaSystem.ini index 1fe229e..980a049 100644 --- a/config/AcediaSystem.ini +++ b/config/AcediaSystem.ini @@ -18,6 +18,30 @@ usedInjectionLevel=BHIJ_Root [AcediaCore.KF1_HealthComponent] +; Unfortunately, thanks to the TWI's code, there's no way to catch events +; of when certain kinds of damage are dealt: from welder, bloat's bile and +; siren's scream. At least not without something drastic, like replacing game +; type class. +; As a workaround, Acedia can optionally replace bloat and siren damage +; type to at least catch damage dealt by zeds (as being dealt welder damage is +; pretty rare and insignificant). This change has several unfortunate +; side-effects: +; 1. Potentially breaking mods that are looking for `DamTypeVomit` and +; `SirenScreamDamage` damage types specifically. Fixing this issue +; would require these mods to either also try and catch Acedia's +; replacements `AcediaCore.Dummy_DamTypeVomit` and +; `AcediaCore.Dummy_SirenScreamDamage` or to catch any child classes +; of `DamTypeVomit` and `SirenScreamDamage` (as Acedia's replacements +; are also their child classes). +; 2. Breaking some achievements that rely on +; `KFSteamStatsAndAchievements`'s `KilledEnemyWithBloatAcid()` method +; being called. This is mostly dealt with by Acedia calling it +; manually. However it relies on killed pawn to have +; `lastDamagedByType` set to `DamTypeVomit`, which sometimes might not +; be the case. Achievements should still be obtainable. +; 3. A lot of siren's visual damage effects code does direct checks for +; `SirenScreamDamage` class. These can also break, stopping working as +; intended. replaceBloatAndSirenDamageTypes=true [AcediaCore.UserAPI] diff --git a/sources/Gameplay/KF1Frontend/Health/KF1_HealthComponent.uc b/sources/Gameplay/KF1Frontend/Health/KF1_HealthComponent.uc index 643a5ff..5f3bf80 100644 --- a/sources/Gameplay/KF1Frontend/Health/KF1_HealthComponent.uc +++ b/sources/Gameplay/KF1Frontend/Health/KF1_HealthComponent.uc @@ -21,13 +21,38 @@ class KF1_HealthComponent extends AHealthComponent dependson(ConnectionService) config(AcediaSystem); -// TODO: document here and in config +/** + * Unfortunately, thanks to the TWI's code, there's no way to catch events + * of when certain kinds of damage are dealt: from welder, bloat's bile and + * siren's scream. At least not without something drastic, like replacing game + * type class. + * As a workaround, Acedia can optionally replace bloat and siren damage + * type to at least catch damage dealt by zeds (as being dealt welder damage is + * pretty rare and insignificant). This change has several unfortunate + * side-effects: + * 1. Potentially breaking mods that are looking for `DamTypeVomit` and + * `SirenScreamDamage` damage types specifically. Fixing this issue + * would require these mods to either also try and catch Acedia's + * replacements `AcediaCore.Dummy_DamTypeVomit` and + * `AcediaCore.Dummy_SirenScreamDamage` or to catch any child classes + * of `DamTypeVomit` and `SirenScreamDamage` (as Acedia's replacements + * are also their child classes). + * 2. Breaking some achievements that rely on + * `KFSteamStatsAndAchievements`'s `KilledEnemyWithBloatAcid()` method + * being called. This is mostly dealt with by Acedia calling it + * manually. However it relies on killed pawn to have + * `lastDamagedByType` set to `DamTypeVomit`, which sometimes might not + * be the case. Achievements should still be obtainable. + * 3. A lot of siren's visual damage effects code does direct checks for + * `SirenScreamDamage` class. These can also break, stopping working as + * intended. + */ var private const config bool replaceBloatAndSirenDamageTypes; var private LoggerAPI.Definition infoReplacingDamageTypes, errNoServerLevelCore; var private LoggerAPI.Definition infoRestoringReplacingDamageTypes; -public function PresudoConstructor() +public function PseudoConstructor() { local LevelCore core; _.unreal.gameRules.OnNetDamage(self).connect = OnNetDamageHandler; @@ -39,6 +64,7 @@ public function PresudoConstructor() if (core != none) { ReplaceDamageTypes(core); + // Fixes achievements _.unreal.gameRules.OnScoreKill(self).connect = UpdateBileAchievement; core.OnShutdown(self).connect = RestoreDamageTypes; } @@ -50,6 +76,7 @@ public function PresudoConstructor() protected function Finalizer() { _.unreal.gameRules.OnNetDamage(self).Disconnect(); + _.unreal.gameRules.OnScoreKill(self).Disconnect(); if (replaceBloatAndSirenDamageTypes) { RestoreDamageTypes(); } @@ -73,6 +100,7 @@ private final function ReplaceDamageTypes(LevelCore core) class'Dummy_SirenScreamDamage'; class'ZombieSiren_CIRCUS'.default.screamDamageType = class'Dummy_SirenScreamDamage'; + // In case Acedia has started mid-game foreach core.AllActors(class'KFBloatVomit', nextVomit) { nextVomit.myDamageType = class'Dummy_DamTypeVomit'; } @@ -83,6 +111,8 @@ private final function ReplaceDamageTypes(LevelCore core) private final function RestoreDamageTypes() { + // No need to restore damage type values for all the preexisting `Actor`s, + // since Acedia is not meant to be shutdown mid-game _.logger.Auto(infoRestoringReplacingDamageTypes); class'KFBloatVomit'.default.myDamageType = class'DamTypeVomit'; class'ZombieSirenBase'.default.screamDamageType = class'SirenScreamDamage'; diff --git a/sources/ServerLevelCore.uc b/sources/ServerLevelCore.uc index a882047..dd49b53 100644 --- a/sources/ServerLevelCore.uc +++ b/sources/ServerLevelCore.uc @@ -22,7 +22,7 @@ protected function Constructor() { super.Constructor(); // TODO: this is hack, needs to be redone later - KF1_HealthComponent(_.kf.health).PresudoConstructor(); + KF1_HealthComponent(_.kf.health).PseudoConstructor(); } public static function LevelCore CreateLevelCore(Actor source)