Perk class that triggers when this player heals another player. It computes a damage value based on the heal amount and perk level, spawns a bullet toward the nearest enemy (or random direction), and shows a brief highlight and scale visual effect.
using System;
using Sandbox;
[Perk( Rarity.Rare, multiplayerMode: MultiplayerMode.OnlyMultiplayer, alwaysOfferDebug: false )]
public class PerkHealPlayerShoot : Perk
{
private enum Mod { DamagePercent };
// todo: too op with PerkBulletHealTeammate?
// todo: only offer once you can do some healing?
static PerkHealPlayerShoot()
{
Register<PerkHealPlayerShoot>(
name: "Protector Shots",
imagePath: "textures/icons/vector/heal_player_shoot.png",
description: level => $"When you heal another player, launch a bullet-icon with\n[+]{GetValue( level, Mod.DamagePercent, true )}%[/+] of the hp as dmg",
upgradeDescription: level => $"When you heal another player, launch a bullet-icon with\n{GetValue( level - 1, Mod.DamagePercent, true )}%→{GetValue( level, Mod.DamagePercent, true )}% of the hp as dmg"
);
}
public override void Start()
{
base.Start();
HighlightColor = new Color( 0.6f, 1f, 1f );
HighlightDuration = 0.2f;
HighlightOpacity = 1.5f;
}
public override void Refresh()
{
base.Refresh();
}
private static float GetValue( int level, Mod mod, bool isPercent = false )
{
switch ( mod )
{
case Mod.DamagePercent:
default:
return isPercent
? 150f + 100f * level
: 1.5f + 1.00f * level;
}
}
public override void OnHealOther( float amount, Player other )
{
base.OnHealOther( amount, other );
Shoot( amount );
}
void Shoot( float healAmount )
{
var closestEnemy = Manager.Instance.GetClosestEnemy( Player.Position2D, 400f );
Vector2 dir = closestEnemy != null ? (closestEnemy.Position2D - Player.Position2D).Normal : Utils.GetRandomVector();
var pos = Player.Position2D + dir * Player.BULLET_SPAWN_OFFSET * Player.Stats[PlayerStat.Scale];
var damage = healAmount * GetValue( Level, Mod.DamagePercent );
damage *= Player.Stats[PlayerStat.BulletDamageMultiplier];
damage = MathF.Max( damage, Player.MIN_BULLET_DAMAGE );
Player.SpawnBullet( pos, dir, damage );
//bullet.Stats[BulletStat.HealTeammateAmount] = 0f;
Highlight();
Player.ScaleHeightRpc( amount: Utils.Map( damage, 1f, 20f, 1.25f, 1.5f ), time: Game.Random.Float( 0.05f, 0.06f ) );
}
}