Perk class that spawns arc bullets when the player kills an enemy with a punch. It registers a perk called "Backblast", computes number of bullets, spread and damage, then spawns and randomizes arc bullets around the enemy position on punch kills.
using System;
using Sandbox;
[Perk( Rarity.Common, includedAtStart: false, locked: true, minUnlocksReq: 2, alwaysOfferDebug: false, IncludedCategories = new[] { PerkCategory.NumProjectiles, PerkCategory.ArcBullets })]
public class PerkPunchBullets : Perk
{
private enum Mod { NumBullets, SpreadModifier };
static PerkPunchBullets()
{
Register<PerkPunchBullets>(
name: "Backblast",
imagePath: "textures/icons/vector/punch_bullets.png",
description: level => $"Lob {(int)GetValue( level, Mod.NumBullets )} bullet-icon from enemies\nyou kill with punches",
upgradeDescription: level => $"Lob {(int)GetValue( level - 1, Mod.NumBullets )}→{(int)GetValue( level, Mod.NumBullets )} bullet-icon from enemies\nyou kill with punches"
);
}
public override void Start()
{
base.Start();
}
public override void Refresh()
{
base.Refresh();
}
public override void OnKill( Enemy enemy, DamageType damageType, bool countsAsKill )
{
base.OnKill( enemy, damageType, countsAsKill );
if ( !countsAsKill ) return;
if ( damageType != DamageType.Punch )
return;
int numBullets = (int)GetValue( Level, Mod.NumBullets );
float damage = Player.GetBulletDamage( isFromClip: false, isLastAmmo: false );
float spread = Player.Stats[PlayerStat.BulletSpread] * GetValue( Level, Mod.SpreadModifier );
var dir = Player.FacingDir;
float currAngleOffset = numBullets == 1 ? 0f : -spread * 0.5f;
float increment = numBullets == 1 ? 0f : spread / (float)(numBullets - 1);
for ( int i = 0; i < numBullets; i++ )
{
var spawnOffset = 10f;
var currDir = Utils.RotateVector( dir, currAngleOffset + increment * i );
var pos = enemy.Position2D + currDir * spawnOffset * Player.Stats[PlayerStat.Scale];
var bullet = Player.SpawnBullet( pos, currDir, damage, isFromClip: false );
bullet.SetupArc( arcHeight: Game.Random.Float( 120f, 160f ), Player.Stats[PlayerStat.ArcBulletBounces] );
bullet.Velocity *= Game.Random.Float( 0.05f, 0.45f );
bullet.Stats[BulletStat.Lifetime] *= Game.Random.Float( 1f, 1.4f );
}
}
private static float GetValue( int level, Mod mod, bool isPercent = false )
{
switch ( mod )
{
case Mod.NumBullets:
default:
switch(level)
{
case 1: default: return 2;
case 2: return 3;
case 3: return 4;
case 4: return 5;
case 5: return 6;
case 6: return 7;
case 7: return 8;
}
case Mod.SpreadModifier:
return 1.3f + 0.55f * level;
}
}
}