perks/PerkMiniPlayer.cs

PerkMiniPlayer is a legendary perk that makes the player smaller. It modifies camera distance, player scale, and move speed based on perk level and updates the player's scale when refreshed or removed.

Networking
using System;
using Sandbox;

[Perk( Rarity.Legendary, alwaysOfferDebug: false )]
public class PerkMiniPlayer : Perk
{
	private enum Mod { CameraDistance, Scale, MoveSpeed };

	// todo: fix giant nametag

	// todo: fix camera when combined with PerkFpsMode

	static PerkMiniPlayer()
	{
		Register<PerkMiniPlayer>(
			name: "Miniaturize",
			imagePath: "textures/icons/vector/mini_player.png",
			description: level => $"[+]-{(int)GetValue( level, Mod.Scale, true )}%[/+] size\n+{(int)GetValue( level, Mod.MoveSpeed, true )}% move speed\n-{(int)GetValue( level, Mod.CameraDistance, true )}% camera distance",
			upgradeDescription: level => $"[+]-{(int)GetValue( level - 1, Mod.Scale, true )}%→-{(int)GetValue( level, Mod.Scale, true )}%[/+] size\n+{(int)GetValue( level - 1, Mod.MoveSpeed, true )}%→{(int)GetValue( level, Mod.MoveSpeed, true )}% move speed\n-{(int)GetValue( level - 1, Mod.CameraDistance, true )}%→-{(int)GetValue( level, Mod.CameraDistance, true )}% camera distance"
		);
	}

	public override void Start()
	{
		base.Start();

	}

	public override void Refresh()
	{
		base.Refresh();

		// todo: scale floater text (based on player scale, or camera distance?)
		// scale health bar size too ?

		// todo: reduce player weight?

		Player.Modify( this, PlayerStat.CameraDistance, GetValue( Level, Mod.CameraDistance ), ModifierType.Mult );
		Player.Modify( this, PlayerStat.Scale, GetValue( Level, Mod.Scale ), ModifierType.Mult );
		Player.Modify( this, PlayerStat.MoveSpeedMultiplier, GetValue( Level, Mod.MoveSpeed ), ModifierType.Mult );

		Player.SetScale( Player.Stats[PlayerStat.Scale] );
	}

	private static float GetValue( int level, Mod mod, bool isPercent = false )
	{
		switch ( mod )
		{
			case Mod.CameraDistance:
			default:
				return isPercent
					? (level == 1 ? 30f : 50f)
					: 1f - (level == 1 ? 0.30f : 0.50f);
			case Mod.Scale:
				return isPercent
					? 22f * level
					: 1f - 0.22f * level;
			case Mod.MoveSpeed:
				return isPercent
					? 5f + 5f * level
					: 1f + (0.05f + 0.05f * level);
		}
	}

	public override void Remove( bool restart = false )
	{
		base.Remove( restart );

		Player.SetScale( Player.Stats[PlayerStat.Scale] );
	}
}