Is it possible, and how might one go about, finding out how much of a player's model is covered? I ask because I'd like to adjust the damage taken by a player based on how much of the model or collision box (whichever at this point) is visible to the attacking player/object. So if you were hiding behind a column and got hit, you'd take less damage than if you were out in the open.
Announcement
Collapse
No announcement yet.
Finding out how much of a player is covered?
Collapse
X
-
I've come back to this little project of mine after mucking about with some other things. As mentioned above, my goal is to reduce damage taken by a player based on how much of him/her is covered. Right now I'm doing this stuff in the NetDamage of a mutator's GameRules:
Code:function int NetDamage( int OriginalDamage, int Damage, pawn injured, pawn instigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType ) { local bool bFeet, bHead; if ( NextGameRules != None ) return NextGameRules.NetDamage( OriginalDamage,Damage,injured,instigatedBy,HitLocation,Momentum,DamageType ); // new stuff here bFeet = FastTrace((injured.Location - ((injured.CollisionHeight * 0.9) * vect(0,0,1))) + (100 * vect(1,0,0)), HitLocation); bHead = FastTrace((injured.Location + ((injured.CollisionHeight * 0.9) * vect(0,0,1))) + (100 * vect(1,0,0)), HitLocation); //if ( !FastTrace(injured.Location, instigatedBy.Location + instigatedBy.EyeHeight * vect(0,0,1)) ) if (!bFeet && !bHead) { Damage *= 0.25; injured.ClientMessage("You're covered well!"); instigatedBy.ClientMessage("Target is under heavy cover!"); } else if (!bFeet || !bHead) { Damage *= 0.5; injured.ClientMessage("You're covered!"); instigatedBy.ClientMessage("Target is under cover!"); } // end new stuff return Damage; }
DM-Serpentine is a good map to test this on, as it has that covered ledge running around the middle level. And my code doesn't work how it's supposed to (I KNOW my player's head's within 100 units of cover on that ledge and I get no client messages, while sometimes I'll be in the open and get them). I think I could handle this if someone could tell me what my screwed-up math is doing in the first place?
Comment
-
Update: I seem to have it working to some extent. The NetDamage function takes the direction between the hitlocation and the firer and traces out 220 units from the victim's head, chest, and feet in that direction. Every trace that hits world geometry will subtract a percentage of the damage taken.
Problems: In the case of projectiles, it won't always give the right values because you can lob a shell around a corner, or the victim might be behind cover and caught in the blast radius anyway - the code traces the line from the victim to the -firer-, not the actual projectile that dealt the damage. Any help with this would be greatly appreciated, but for now it works for me.
Code:function int NetDamage( int OriginalDamage, int Damage, pawn injured, pawn instigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType ) { local bool bFeet, bHead, bChest; local vector CheckFootCover, CheckHeadCover, CheckChestCover; local float Cover, DispCover; Cover = 1.0; if ( NextGameRules != None ) return NextGameRules.NetDamage( OriginalDamage,Damage,injured,instigatedBy,HitLocation,Momentum,DamageType ); // new stuff here //CheckFootCover = HitLocation - vector(rotator(HitLocation - instigatedBy.Location)) * 220; CheckFootCover = (injured.Location - ((injured.CollisionHeight * 0.9) * vect(0,0,1))) - vector(rotator(HitLocation - instigatedBy.Location)) * 220; CheckHeadCover = (injured.Location + (injured.CollisionHeight * vect(0,0,1))) - vector(rotator(HitLocation - instigatedBy.Location)) * 220; CheckChestCover = injured.Location - vector(rotator(HitLocation - instigatedBy.Location)) * 220; bFeet = FastTrace(CheckFootCover, (injured.Location - ((injured.CollisionHeight * 0.9) * vect(0,0,1))) ); if (!bFeet) Cover -= 0.25; bHead = FastTrace(CheckHeadCover, (injured.Location + (injured.CollisionHeight * vect(0,0,1))) ); if (!bHead) Cover -= 0.25; bChest = FastTrace(CheckChestCover, injured.Location); if (!bChest) Cover -= 0.35; Damage *= Cover; if (Cover < 1.0) { DispCover = 1.0 - Cover; injured.ClientMessage("Your Cover: "$DispCover$"%"); instigatedBy.ClientMessage("Target's Cover: "$DispCover$"%"); } //Spawn(class'ShockImpactFlare',,, CheckFootCover, rotator(HitLocation)); // end new stuff return Damage; }
Comment
-
Originally posted by ADS
Problems: In the case of projectiles, it won't always give the right values because you can lob a shell around a corner, or the victim might be behind cover and caught in the blast radius anyway - the code traces the line from the victim to the -firer-, not the actual projectile that dealt the damage. Any help with this would be greatly appreciated, but for now it works for me. [/code]
Comment
Comment