From 1fd77f1c15afb321beb063aaaf0803ce266d43b1 Mon Sep 17 00:00:00 2001 From: Shtoyan Date: Sun, 23 Jan 2022 16:33:31 +0400 Subject: [PATCH] much better way to bleed pawns --- sources/Zeds/Mean/MeanBleedInventory.uc | 87 +++++++++++++++++++++++++ sources/Zeds/Mean/MeanZombieStalker.uc | 42 +++++++++--- 2 files changed, 120 insertions(+), 9 deletions(-) create mode 100644 sources/Zeds/Mean/MeanBleedInventory.uc diff --git a/sources/Zeds/Mean/MeanBleedInventory.uc b/sources/Zeds/Mean/MeanBleedInventory.uc new file mode 100644 index 0000000..b5d2701 --- /dev/null +++ b/sources/Zeds/Mean/MeanBleedInventory.uc @@ -0,0 +1,87 @@ +class MeanBleedInventory extends Inventory; + + +const dmtype_bleed=class'NiceDamTypeStalkerBleed'; +var private int maxBleedCount; +var private float fBleedPeriod; + +var private float fNextBleedTime; + +var float bleedLevel; +var MeanZombieCrawler stalker; + + +function Tick(float DeltaTime) +{ + fNextBleedTime = Level.TimeSeconds; + // start the timer + SetTimer(0.1, true); + // disable me, coz im too fast and resource hungry + Disable('Tick'); +} + + +event Timer() +{ + local pawn locpawn; + local bool amAlive; + local float bleedDamage; + + locpawn = Pawn(Owner); + amAlive = locpawn != none && locpawn.Health > 0; + + // if pawn owner is dead or bleed count is done - destroy + if (!amAlive || maxBleedCount < 0) + Destroy(); + + if (fNextBleedTime < Level.TimeSeconds) + { + maxBleedCount--; + fNextBleedTime += fBleedPeriod; + + bleedDamage = calcBleedDamage(bleedLevel, rand(7)); + if (bleedDamage < 1.0) + { + maxBleedCount = 0; + return; + } + + if (stalker != none) + locpawn.TakeDamage(bleedDamage, stalker, locpawn.Location, + vect(0, 0, 0), dmtype_bleed); + else + locpawn.TakeDamage(bleedDamage, locpawn, locpawn.Location, + vect(0, 0, 0), dmtype_bleed); + + if (locpawn.isA('KFPawn')) + { + KFPawn(locpawn).HealthToGive -= 2 * bleedLevel; + } + } +} + + +// Returns bleed damage, corresponding to given bleed level and damage scale. +// Rand(7) should be used as a scale. +// Separate function created to allow for lowest/highest damage value computing. +final private function int calcBleedDamage(float level, int scale) +{ + return level * (3 + scale); +} + + +// cleanup +function Destroyed() +{ + if (stalker != none) + stalker = none; + + super.Destroyed(); +} + + +defaultproperties +{ + maxBleedCount=7 + fBleedPeriod=1.500000 +} \ No newline at end of file diff --git a/sources/Zeds/Mean/MeanZombieStalker.uc b/sources/Zeds/Mean/MeanZombieStalker.uc index 53111d2..8d688e6 100644 --- a/sources/Zeds/Mean/MeanZombieStalker.uc +++ b/sources/Zeds/Mean/MeanZombieStalker.uc @@ -190,20 +190,44 @@ function bool MeleeDamageTarget(int hitdamage, vector pushdir) if (result && targetPawn != none) { - if (targetPawn.ShieldStrength > 100) - return result; - else if (targetPawn.ShieldStrength < 0) - effectStrenght = 1.0; - else - effectStrenght = (100 - targetPawn.ShieldStrength) * 0.01; + if (targetPawn.ShieldStrength > 100) + return result; + else if (targetPawn.ShieldStrength < 0) + effectStrenght = 1.0; + else + effectStrenght = (100 - targetPawn.ShieldStrength) * 0.01; - class'MeanReplicationInfo'.static - .findSZri(targetPawn.PlayerReplicationInfo) - .setBleeding(Self, effectStrenght); + MakeBleed(targetPawn, effectStrenght); } return result; } +final private function MakeBleed(NiceHumanPawn poorpawn, float effectStrenght) +{ + local Inventory I; + local bool bFoundPoison; + + if (poorpawn.Inventory != none) + { + for (I = poorpawn.Inventory; I != none; I = I.Inventory) + { + if (MeanBleedInventory(I) != none) + { + bFoundPoison = true; + MeanBleedInventory(I).stalker = self; + MeanBleedInventory(I).bleedLevel = effectStrenght; + } + } + } + if (!bFoundPoison) + { + I = Controller.Spawn(class(DynamicLoadObject(string(class'MeanBleedInventory'), class'Class'))); + MeanBleedInventory(I).stalker = self; + MeanBleedInventory(I).bleedLevel = effectStrenght; + I.GiveTo(poorpawn); + } +} + function RemoveHead() { Super(NiceMonster).RemoveHead();