perks/PerkDamageSlowerReload.cs

A perk definition class for a game, named Preparation. It registers UI metadata (name, icon, descriptions) and applies two player stat modifiers when active: increases overall damage multiplier and decreases reload speed based on perk level.

Networking
using System;
using Sandbox;

[Perk( Rarity.Common, locked: true, alwaysOfferDebug: false )]
public class PerkDamageSlowerReload : Perk
{
	private enum Mod { OverallDamageMultiplier, ReloadSpeed };

	static PerkDamageSlowerReload()
	{
		Register<PerkDamageSlowerReload>(
			name: "Preparation",
			imagePath: "textures/icons/vector/overall_damage_slower_reload.png",
			description: level => $"+{GetValue( level, Mod.OverallDamageMultiplier, true )}% dmg\n-{GetValue( level, Mod.ReloadSpeed, true )}% reload speed",
			upgradeDescription: level => $"+{GetValue( level - 1, Mod.OverallDamageMultiplier, true )}%→{GetValue( level, Mod.OverallDamageMultiplier, true )}% dmg\n-{GetValue( level - 1, Mod.ReloadSpeed, true )}%→-{GetValue( level, Mod.ReloadSpeed, true )}% reload speed"
		);
	}

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

		ShouldUpdate = true;
	}

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

		// todo: change to non-bullet dmg only?
		Player.Modify( this, PlayerStat.OverallDamageMultiplier, GetValue( Level, Mod.OverallDamageMultiplier ), ModifierType.Mult );
		Player.Modify( this, PlayerStat.ReloadSpeed, GetValue( Level, Mod.ReloadSpeed ), ModifierType.Mult );
	}
	private static float GetValue( int level, Mod mod, bool isPercent = false )
	{
		switch ( mod )
		{
			case Mod.OverallDamageMultiplier:
			default:
				return isPercent
					? 2f + 6f * level
					: 1f + 0.02f + 0.06f * level;
			case Mod.ReloadSpeed:
				return isPercent
					? 4f + 5f * level
					: 1f - (0.04f + 0.05f * level);
		}
	}
}