Page 1 of 1

Be able to set IPlayer behavior when received enough overkill damage

Posted: Wed Aug 07, 2019 2:22 am
by NearHuscarl
Context: when using IPlayer.SetHitEffect(PlayerHitEffect.Metal) to make robot-like sound effect for player. After the player died and received enough overkill damage, it bursts into blood and gore which breaks the immersion. I'd like something like IPlayer.SetDestroyAnimation() where I can determine if the IPlayer explodes into gore or into metal pieces like the streetsweeper or something.

Re: Be able to set IPlayer behavior when received enough overkill damage

Posted: Wed Aug 07, 2019 2:51 pm
by JakSparro98
NearHuscarl wrote:
Wed Aug 07, 2019 2:22 am
Context: when using IPlayer.SetHitEffect(PlayerHitEffect.Metal) to make robot-like sound effect for player. After the player died and received enough overkill damage, it bursts into blood and gore which breaks the immersion. I'd like something like IPlayer.SetDestroyAnimation() where I can determine if the IPlayer explodes into gore or into metal pieces like the streetsweeper or something.
Sometimes you just need to think a little bit out of the box, here is the code to replace giblets with metal debris randomly set on fire, plus some effects to try to cover the blood sprite:

Code: Select all

Vector2 BL, TR;
bool MetalGibbing = false;
Random RNG = new Random();
const int GIB_AREA_SIZE = 15;
List < String > DebrisList = new List < String > {
 "MetalDebris00A",
 "MetalDebris00B",
 "MetalDebris00C",
 "MetalDebris00D",
 "MetalDebris00E"
};

public void OnStartup() {
 Events.PlayerDeathCallback.Start(OnPlayerDeath);
 Events.UpdateCallback.Start(OnUpdate);
}

public void OnPlayerDeath(IPlayer player, PlayerDeathArgs args) {
 if (args.Removed) {
  Vector2 pos = player.GetWorldPosition();
  BL = new Vector2(pos.X - (GIB_AREA_SIZE / 2), pos.Y - (GIB_AREA_SIZE / 2));
  TR = new Vector2(pos.X + (GIB_AREA_SIZE / 2), pos.Y + (GIB_AREA_SIZE / 2));
  Game.PlayEffect("BulletHitMetal", player.GetWorldPosition());
  for (int i = 0; i < 10; i++)
   Game.PlayEffect("S_P", player.GetWorldPosition());
  Game.PlayEffect(" EXP", player.GetWorldPosition());
  MetalGibbing = true;
 }
}

public void OnUpdate(float elapsed) {
 if (MetalGibbing) {
  foreach(IObject Giblet in Game.GetObjectsByArea(new Area(BL, TR))) {
   if (Giblet.Name.StartsWith("Gib")) {
    IObject debris = Game.CreateObject(RandomDebris(), Giblet.GetWorldPosition(), Giblet.GetAngle(), Giblet.GetLinearVelocity(), Giblet.GetAngularVelocity());
    if (RNG.Next(0, 101) < 50)
     debris.SetMaxFire();
    Giblet.Remove();
   }
  }
  MetalGibbing = false;
 }
}

String RandomDebris() {
 return DebrisList[RNG.Next(0, DebrisList.Count())];
}
Keep in mind that the code will be triggered by any gibbed body, if you need to make it happen only on certain players you need to filter them based on your already code implementation.

Re: Be able to set IPlayer behavior when received enough overkill damage

Posted: Wed Aug 07, 2019 4:45 pm
by NearHuscarl
I thought about that workaround, but the giblet objects still appear like 1 frame before being removed. You can still see the blood effect, that's what annoys me. But I will keep that solution in mind if they cannot add my suggestions for whatever reasons

Re: Be able to set IPlayer behavior when received enough overkill damage

Posted: Wed Aug 07, 2019 7:53 pm
by Danger Ross
Gurt's job isn't to make scripting simpler. If he adds something to the API it's usually to expand the potential of scripting.

Anyways, if it's a bullet that overkills your robot you can use the OnProjectileHit event to check if the shot will gib it or not, and if it does you can remove the bullet and the robot and replace it with metal scraps. OnProjectileHit activates before it hits btw, so it wont gib your robot before activating.

If it's melee damage you can track how much damage it takes using playerModifiers and remove the bot before it gets too close to the threshhold damage.

If it's a rocket or explosive Jak's method is the best solution I can think of.

Re: Be able to set IPlayer behavior when received enough overkill damage

Posted: Thu Aug 08, 2019 6:10 pm
by NearHuscarl
Thanks everyone for your help. I ended up with similar solution to JakSparro98's one. Adding more debris effects seem to hide the blood pretty well.

https://github.com/NearHuscarl/SFDScrip ... imation.cs

Re: Be able to set IPlayer behavior when received enough overkill damage

Posted: Thu Aug 08, 2019 6:56 pm
by Danger Ross
I just realized there's an explosion hit event as well. If you figure out how to use it you may be able to destroy the body before it's blown up into gibs if it works anything like the projectile hit event.

Re: Be able to set IPlayer behavior when received enough overkill damage

Posted: Sat Aug 10, 2019 10:24 am
by Gurt
This is a case we have never used ourselves. But the PlayerHitEffect.Metal shouldn't really show the gib effect. Changing this to the next update.
PlayerHitEffect.Metal will play the break sound together with the DestroyMetal effect when the player is gibbed.