A Perk implementation named PerkPerspective. When leveled it grants the player a temporary perspective camera stat, spawns a number of random perks and one curse as perk items (queued and given over time), and toggles the manager orthographic camera state.
using System;
using Sandbox;
[Perk( Rarity.Unique, locked: true, minUnlocksReq: 3, alwaysOfferDebug: false )]
public class PerkPerspective : Perk
{
private enum Mod { NumPerks };
private TimeSince _timeSincePerk;
private List<TypeDescription> _perkTypes = new();
static PerkPerspective()
{
Register<PerkPerspective>(
name: "New Perspective",
imagePath: "textures/icons/vector/perspective.png",
description: level => $"Stereo vision\n +{(int)GetValue(level, Mod.NumPerks)} random perks\n[-]+1[/-] curse"
);
}
public override void Start()
{
base.Start();
}
public override void IncreaseLevel()
{
base.IncreaseLevel();
ShouldUpdate = true;
_timeSincePerk = 0f;
int numPerks = (int)GetValue( Level, Mod.NumPerks );
List<TypeDescription> newPerks = new();
for ( int i = 0; i < numPerks; i++ )
newPerks.Add( Player.GetRandomPerkType() );
List<TypeDescription> newCurses = new();
for ( int i = 0; i < 1; i++ )
newCurses.Add( Player.GetRandomPerkType( curseSelection: CurseSelection.OnlyCurses ) );
var perkTokens = "";
foreach ( var p in newPerks ) perkTokens += $" {Perk.GetRichTextToken( p )}";
Manager.Instance.Chat.AddLocalChatMessage( $"{Perk.GetRichTextToken( GetType() )} Got {numPerks} random perks:{perkTokens}", from: "" );
var curseTokens = "";
foreach ( var p in newCurses ) curseTokens += $" {Perk.GetRichTextToken( p )}";
Manager.Instance.Chat.AddLocalChatMessage( $"{Perk.GetRichTextToken( GetType() )} Got a curse:{curseTokens}", from: "" );
_perkTypes.AddRange( newPerks );
_perkTypes.AddRange( newCurses );
}
public override void Refresh()
{
base.Refresh();
Player.Modify( this, PlayerStat.PerspectiveCamera, 1f, ModifierType.Add );
Manager.Instance.SetOrthoCamera( false );
}
public override void Update( float dt )
{
base.Update( dt );
if ( _perkTypes.Count > 0 && _timeSincePerk > 0.33f )
{
var type = _perkTypes[0];
var attrib = type.GetAttribute<PerkAttribute>();
Player.GivePerkItem( type, dir: Utils.GetRandomVectorInCone( -Player.FacingDir ), forceToCollect: attrib.Curse );
_perkTypes.RemoveAt( 0 );
if ( _perkTypes.Count <= 0 )
ShouldUpdate = false;
_timeSincePerk = 0f;
}
}
private static float GetValue( int level, Mod mod, bool isPercent = false )
{
switch ( mod )
{
case Mod.NumPerks:
default:
return 5;
}
}
public override void Remove( bool restart = false )
{
base.Remove( restart );
if ( !(Player.Stats[PlayerStat.PerspectiveCamera] > 0f) )
{
Manager.Instance.SetOrthoCamera( true );
//Manager.Instance.Camera.OrthographicHeight = 500f;
}
}
}