{"TotalCount":166,"Files":[{"Ident":"pwegg.planet_meat","Path":"Effects/PreparedEffects.cs","FileName":"PreparedEffects.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Group( \u0022Planet Meat - Effects\u0022 ), Title( \u0022Prepared Effects\u0022 ), Icon( \u0022border_outer\u0022 )]\r\npublic sealed class PreparedEffects : Component\r\n{\r\n\t[Property] private List\u003CGameObject\u003E Effects { get; set; } = [];\r\n\t[Property] private List\u003CSoundEvent\u003E Sounds { get; set; } = [];\r\n\t[Property] private float DefaultRadius { get; set; } = 100.0f;\r\n\r\n\tpublic void PerformEffects( float radius )\r\n\t{\r\n\t\tforeach ( var e in Effects )\r\n\t\t{\r\n\t\t\tif ( e is GameObject p \u0026\u0026 p.Clone( WorldPosition ).Components.Get\u003CScaledEffect\u003E() is ScaledEffect s )\r\n\t\t\t\ts.ScaleTo( radius );\r\n\t\t}\r\n\r\n\t\tif ( Sounds.Count \u003E 0 )\r\n\t\t\tSoundEffectsBundle.Create( WorldPosition, Sounds );\r\n\t}\r\n\tpublic void PerformEffects() =\u003E PerformEffects( DefaultRadius );\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Player/PlayerTool.cs","FileName":"PlayerTool.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Group( \u0022Planet Meat - Player\u0022 ), Title( \u0022Player Tool\u0022 ), Icon( \u0022touch_app\u0022 )]\r\npublic abstract class PlayerTool : Component, IAttackBlame\r\n{\r\n\tpublic static PlayerTool Selected { get; private set; } = null;\r\n\tpublic static List\u003CPlayerTool\u003E Toolbox { get; } = [];\r\n\r\n\tprivate IWorldRing GhostRing\r\n\t{\r\n\t\tget;\r\n\t\tset\r\n\t\t{\r\n\t\t\tif ( field?.GameObject is GameObject ringGo \u0026\u0026 ringGo.IsValid )\r\n\t\t\t\tringGo.Destroy();\r\n\t\t\tfield = value;\r\n\t\t}\r\n\t}\r\n\r\n\tprotected virtual IWorldRing NextWorldRing =\u003E null;\r\n\r\n\tprotected IWorldRing CreateWorldRing( Vector3 position, bool ghost = false )\r\n\t{\r\n\t\tvar ring = NextWorldRing;\r\n\t\tif ( ring is null )\r\n\t\t\treturn null;\r\n\r\n\t\tring.WorldPosition = position;\r\n\t\tif ( ghost )\r\n\t\t\tring.MultiplyAlpha( 0.4f );\r\n\t\treturn ring;\r\n\t}\r\n\tprotected IWorldRing CreateWorldRing( bool ghost = false ) =\u003E CreateWorldRing( WorldPosition, ghost );\r\n\r\n\tprivate void TryCreateGhostRing()\r\n\t{\r\n\t\tGhostRing = IsSelected \u0026\u0026 IsUsable ? CreateWorldRing( true ) : null;\r\n\t}\r\n\r\n\tpublic static void BakeTools( IEnumerable\u003CPlayerTool\u003E allTools )\r\n\t{\r\n\t\tToolbox.Clear();\r\n\t\tToolbox.AddRange( allTools.Where( t =\u003E t.Available ) );\r\n\t\tToolbox.Sort( SortTools );\r\n\t}\r\n\r\n\tprivate static int SortTools( PlayerTool a, PlayerTool b )\r\n\t{\r\n\t\tvar aTech = a.Tech;\r\n\t\tvar bTech = b.Tech;\r\n\r\n\t\tvar aFree = aTech is null;\r\n\t\tvar bFree = bTech is null;\r\n\t\tif ( aFree != bFree )\r\n\t\t\treturn aFree ? -1 : 1;\r\n\r\n\t\tif ( !aFree \u0026\u0026 !bFree )\r\n\t\t{\r\n\t\t\tvar costComparison = aTech.Duration.CompareTo( bTech.Duration );\r\n\t\t\tif ( costComparison != 0 )\r\n\t\t\t\treturn costComparison;\r\n\t\t}\r\n\r\n\t\treturn a.Ident.CompareTo( b.Ident );\r\n\t}\r\n\r\n\tpublic static int IndexToSlotNumber( int i ) =\u003E i \u003C 9 ? 1 \u002B i : (i == 9 ? 0 : -1);\r\n\tpublic static string IndexToSlotName( int i ) =\u003E i \u003C 10 ? \u0022Slot\u0022 \u002B IndexToSlotNumber( i ) : \u0022\u0022;\r\n\tpublic static bool IndexSlotPressed( int i ) =\u003E i \u003C 10 \u0026\u0026 Input.Pressed( IndexToSlotName( i ) );\r\n\r\n\t[Property] public string Ident { get; set; } = \u0022\u0022;\r\n\t[Property] public string Icon { get; set; } = \u0022\u0022;\r\n\t[Property] public string RequiredTech { get; set; } = \u0022\u0022;\r\n\tprivate BaseTech Tech =\u003E Research.Current.GetTech( RequiredTech );\r\n\t[Property] public string RechargeImprovementIdent { get; set; } = \u0022\u0022;\r\n\r\n\tprivate bool _needsTechCheck = true;\r\n\tprivate bool HasTech\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\tif ( _needsTechCheck )\r\n\t\t\t{\r\n\t\t\t\t_needsTechCheck = false;\r\n\t\t\t\tfield = Tech.Completed;\r\n\t\t\t}\r\n\t\t\treturn field;\r\n\t\t}\r\n\t}\r\n\tpublic virtual bool Available =\u003E HasTech;\r\n\r\n\tpublic virtual float BaseCooldown =\u003E 1.0f;\r\n\tpublic ValueAggregator\u003Cfloat\u003E AggregateRecharge =\u003E field ??= ValueAggregator\u003Cfloat\u003E.FromImprovement( RechargeImprovementIdent, 1.0f );\r\n\tpublic float Cooldown =\u003E BaseCooldown / AggregateRecharge.Total;\r\n\r\n\tpublic float CooldownRemaining { get; private set; }\r\n\tpublic bool IsOnCooldown =\u003E CooldownRemaining \u003E 0.0f;\r\n\tpublic virtual bool IsUsable =\u003E !IsOnCooldown;\r\n\tpublic virtual bool IsSelectable =\u003E true;\r\n\r\n\tpublic bool IsSelected =\u003E this == Selected;\r\n\r\n\tpublic void BeginUse()\r\n\t{\r\n\t\tif ( IsSelectable \u0026\u0026 Agenda.Current.Phase == Agenda.Phases.Wave )\r\n\t\t{\r\n\t\t\tSelected?.EndUse();\r\n\t\t\tSelected = this;\r\n\t\t\tOnUseBegins();\r\n\t\t}\r\n\t}\r\n\tprotected virtual void OnUseBegins()\r\n\t{\r\n\t\tTryCreateGhostRing();\r\n\t}\r\n\r\n\tpublic void EndUse()\r\n\t{\r\n\t\tif ( IsSelected )\r\n\t\t\tSelected = null;\r\n\t\tOnUseEnds();\r\n\t}\r\n\tprotected virtual void OnUseEnds()\r\n\t{\r\n\t\tGhostRing = null;\r\n\t}\r\n\r\n\tpublic void ToggleUse()\r\n\t{\r\n\t\tif ( IsSelected )\r\n\t\t\tEndUse();\r\n\t\telse\r\n\t\t\tBeginUse();\r\n\t}\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\tbase.OnUpdate();\r\n\t\tif ( IsOnCooldown )\r\n\t\t{\r\n\t\t\tCooldownRemaining -= Time.Delta;\r\n\t\t\tif ( !IsOnCooldown )\r\n\t\t\t\tEndCooldown();\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void StartCooldown()\r\n\t{\r\n\t\tCooldownRemaining = Cooldown;\r\n\t\tOnCooldownStarted();\r\n\t}\r\n\tprotected virtual void OnCooldownStarted()\r\n\t{\r\n\t\tGhostRing = null;\r\n\t}\r\n\r\n\tpublic void EndCooldown()\r\n\t{\r\n\t\tCooldownRemaining = 0.0f;\r\n\t\tOnCooldownEnded();\r\n\t}\r\n\tprotected virtual void OnCooldownEnded()\r\n\t{\r\n\t\tTryCreateGhostRing();\r\n\t}\r\n\r\n\tpublic virtual void OnHover( Vector3 position )\r\n\t{\r\n\t\tGhostRing?.WorldPosition = position;\r\n\t}\r\n\r\n\tpublic virtual void OnPlaceStarted( Vector3 position ) { }\r\n\tpublic virtual void OnPlaceUpdated( Vector3 fromPosition, Vector3 toPosition ) { }\r\n\tpublic virtual void OnPlaceEnded( Vector3 position ) { }\r\n\r\n\tpublic virtual void OnCancel( Vector3 position )\r\n\t{\r\n\t\tEndUse();\r\n\t}\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Spending/Progressions.cs","FileName":"Progressions.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"using System;\r\n\r\nnamespace PlanetMeat;\r\n\r\npublic static class Progressions\r\n{\r\n\t// https://www.desmos.com/calculator/omqcpghpkb\r\n\r\n\tpublic static int Intify( float value, int min = 1 ) =\u003E Math.Max( min, (int)MathF.Round( value ) );\r\n\tpublic static int Intify( double value, int min = 1 ) =\u003E Math.Max( min, (int)Math.Round( value ) );\r\n\tpublic static int Intify( Func\u003Cdouble, double\u003E p, double x, int min = 1 ) =\u003E Intify( p( Math.Floor( x ) ), min );\r\n\r\n\tpublic static double Exponential( double x ) =\u003E Math.Pow( 2.0, x );\r\n\r\n\tpublic static double StairSlow( double x ) =\u003E Exponential( Math.Floor( Math.Sqrt( x ) ) - 1.0 );\r\n\tpublic static int StairSlowInt( double x ) =\u003E Intify( StairSlow, x );\r\n\r\n\tpublic static double StairCrawl( double x ) =\u003E Math.Ceiling( Math.Sqrt( StairSlow( x ) ) );\r\n\tpublic static int StairCrawlInt( double x ) =\u003E Intify( StairCrawl, x );\r\n\r\n\tpublic static double ExpSlow( double x ) =\u003E Exponential( Math.Sqrt( x ) - 1.0 );\r\n\tpublic static int ExpSlowInt( double x ) =\u003E Intify( ExpSlow, x );\r\n\tpublic static double ExpCrawl( double x ) =\u003E Math.Sqrt( ExpSlow( x ) );\r\n\tpublic static int ExpCrawlInt( double x ) =\u003E Intify( ExpCrawl, x );\r\n\r\n\tpublic static double PowLog( double x ) =\u003E x \u003C 1.0 ? x : Math.Pow( x, Math.Log( x, 100.0 ) );\r\n\tpublic static double PowLogZeroed( double x ) =\u003E x \u003C 0.1 ? x : PowLog( x ) - 0.9;\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Spending/Upgrades/Meat/MeatRateUpgrade.cs","FileName":"MeatRateUpgrade.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Title( \u0022Meat Upgrade - Rate\u0022 )]\r\npublic sealed class MeatRateUpgrade : PercentageMeatUpgrade\r\n{\r\n\tprotected override ValueAggregator\u003Cfloat\u003E Agg =\u003E MeatImprover.AggregateRate;\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Spending/Upgrades/Targetable/RegenTargetableUpgrade.cs","FileName":"RegenTargetableUpgrade.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Title( \u0022Target Upgrade - Regen\u0022 )]\r\npublic sealed class RegenTargetableUpgrade : PercentageAggregateUpgrade\u003CTargetable\u003E\r\n{\r\n\tprotected override ValueAggregator\u003Cfloat\u003E FindAggregate =\u003E TargetComponent?.AggregateRegen;\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Spending/Upgrades/Targeter/RangeTargeterUpgrade.cs","FileName":"RangeTargeterUpgrade.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Title( \u0022Targeter Upgrade - Range\u0022 )]\r\npublic sealed class RangeTargeterUpgrade : BaseComponentUpgrade\u003CTargeter, int\u003E\r\n{\r\n\tprotected override int EffectBase =\u003E (int)(TargetComponent?.GetRangeWithout( this ) ?? 0);\r\n\tprotected override int GetEffectAt( int rank ) =\u003E EffectPerRank.MultiplyCapped( rank );\r\n\r\n\tprotected override void OnRankChanged()\r\n\t{\r\n\t\tTargetComponent?.ContributeRange( this, CurrentEffect );\r\n\t}\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Units/Lifesteal.cs","FileName":"Lifesteal.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"using System;\r\n\r\nnamespace PlanetMeat;\r\n\r\n[Group( \u0022Planet Meat - Units\u0022 ), Title( \u0022Lifesteal\u0022 ), Icon( \u0022vaccines\u0022 )]\r\npublic sealed class Lifesteal : Component\r\n{\r\n\tpublic static List\u003CLifesteal\u003E All =\u003E field ??= [];\r\n\r\n\t[Property] public string DamageStealImprovement { get; set; } = \u0022\u0022;\r\n\tpublic ValueAggregator\u003Cfloat\u003E AggregateDamageSteal =\u003E field ??= ValueAggregator\u003Cfloat\u003E.FromImprovement( DamageStealImprovement, 0.0f );\r\n\r\n\t[Property] public string KillHealAmountImprovement { get; set; } = \u0022\u0022;\r\n\tpublic ValueAggregator\u003Cint\u003E AggregateKillHealAmount =\u003E field ??= ValueAggregator\u003Cint\u003E.FromImprovement( KillHealAmountImprovement, 0 );\r\n\r\n\t[Property] public string KillHealRateImprovement { get; set; } = \u0022\u0022;\r\n\tpublic ValueAggregator\u003Cfloat\u003E AggregateKillHealRate =\u003E field ??= ValueAggregator\u003Cfloat\u003E.FromImprovement( KillHealRateImprovement, 0.0f );\r\n\tprivate float KillHealProgress { get; set; } = 0.0f;\r\n\r\n\tprivate Targetable Targetable =\u003E field ??= this.FindNearestUpwards\u003CTargetable\u003E();\r\n\tfloat damageDebt = 0.0f;\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tbase.OnStart();\r\n\t\tAll.Add( this );\r\n\t}\r\n\r\n\tprotected override void OnDestroy()\r\n\t{\r\n\t\tAll.Remove( this );\r\n\t\tbase.OnDestroy();\r\n\t}\r\n\r\n\tpublic void StealDamage( Targetable victim, int dmg )\r\n\t{\r\n\t\tif ( IsValidTarget( victim ) )\r\n\t\t{\r\n\t\t\tvar steal = dmg * AggregateDamageSteal.Total \u002B damageDebt;\r\n\t\t\tvar wholeSteal = (int)Math.Round( steal );\r\n\t\t\tTargetable.CurrentHp \u002B= wholeSteal;\r\n\t\t\tdamageDebt \u002B= steal - wholeSteal;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void KillHeal( Targetable victim )\r\n\t{\r\n\t\tif ( IsValidTarget( victim ) )\r\n\t\t{\r\n\t\t\tKillHealProgress \u002B= AggregateKillHealRate.Total;\r\n\t\t\tif ( KillHealProgress \u003E 0.99f )\r\n\t\t\t{\r\n\t\t\t\tTargetable.CurrentHp \u002B= AggregateKillHealAmount.Total;\r\n\t\t\t\tKillHealProgress -= 1.0f;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprivate bool IsValidTarget( Targetable t ) =\u003E !Targetable.IsFriendlyTo( t );\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Units/Targeter.cs","FileName":"Targeter.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Group( \u0022Planet Meat - Units\u0022 ), Title( \u0022Targeter\u0022 ), Icon( \u0022visibility\u0022 )]\r\npublic sealed class Targeter : Component\r\n{\r\n\tpublic enum TargetingStrategies { Nearest, Healthiest }\r\n\r\n\t[Property]\r\n\tpublic TargetingStrategies TargetingStrategy\r\n\t{\r\n\t\tget;\r\n\t\tset\r\n\t\t{\r\n\t\t\tfield = value;\r\n\t\t\tTargetingComparer = null;\r\n\t\t}\r\n\t} = TargetingStrategies.Nearest;\r\n\r\n\t[Property] public bool CanTargetEnemies { get; set; } = true;\r\n\t[Property] public bool CanTargetFriends { get; set; } = false;\r\n\t[Property] public bool CanTargetLiving { get; set; } = true;\r\n\t[Property] public bool CanTargetDead { get; set; } = false;\r\n\r\n\tpublic int NumTargets\r\n\t{\r\n\t\tget;\r\n\t\tset\r\n\t\t{\r\n\t\t\tif ( _nextTargets is not null \u0026\u0026 _nextTargets.Capacity \u003C value \u002B 1 )\r\n\t\t\t\t_nextTargets.Capacity = value \u002B 1;\r\n\t\t\tfield = value;\r\n\t\t}\r\n\t} = 1;\r\n\r\n\tpublic Targetable SoleFocus { get; set; }\r\n\r\n\tprivate List\u003CTargetable\u003E _nextTargets;\r\n\tpublic List\u003CTargetable\u003E NextTargets\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\tif ( _nextTargets is null )\r\n\t\t\t\t_nextTargets = new List\u003CTargetable\u003E( NumTargets \u002B 1 );\r\n\t\t\telse\r\n\t\t\t\t_nextTargets.Clear();\r\n\r\n\t\t\tif ( SoleFocus is null )\r\n\t\t\t{\r\n\t\t\t\tif ( TargetingComparer is IComparer\u003CTargetable\u003E comparer )\r\n\t\t\t\t{\r\n\t\t\t\t\tforeach ( var t in TargetsInRange )\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tvar index = _nextTargets.BinarySearch( t, comparer );\r\n\t\t\t\t\t\tif ( index \u003C 0 ) index = ~index;\r\n\r\n\t\t\t\t\t\tif ( index \u003C NumTargets )\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t_nextTargets.Insert( index, t );\r\n\t\t\t\t\t\t\tif ( _nextTargets.Count \u003E NumTargets )\r\n\t\t\t\t\t\t\t\t_nextTargets.RemoveAt( NumTargets );\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if ( IsValidTarget( SoleFocus ) )\r\n\t\t\t{\r\n\t\t\t\t_nextTargets.Add( SoleFocus );\r\n\t\t\t}\r\n\r\n\t\t\treturn _nextTargets;\r\n\t\t}\r\n\t}\r\n\tpublic IEnumerable\u003CTargetable\u003E TargetsInRange =\u003E Scene\r\n\t\t.FindInPhysics( new Sphere( WorldPosition, Range ) )\r\n\t\t.Select( g =\u003E g.Components.Get\u003CTargetable\u003E() )\r\n\t\t.Where( t =\u003E t is not null \u0026\u0026 CanTarget( t ) );\r\n\r\n\tpublic ITargeterStatus Status =\u003E field ??= this.FindNearestUpwards\u003CITargeterStatus\u003E();\r\n\r\n\tpublic float Range =\u003E AggregateRange.Total;\r\n\tprivate float RangeSq\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\tif ( float.IsNaN( field ) )\r\n\t\t\t{\r\n\t\t\t\tvar r = Range;\r\n\t\t\t\tfield = r \u003E 0 ? r * r : -1;\r\n\t\t\t}\r\n\t\t\treturn field;\r\n\t\t}\r\n\t\tset;\r\n\t} = float.NaN;\r\n\r\n\t[Property] public int BaseRange { get; set; } = 2048;\r\n\t[Property] public string RangeImprovement { get; set; }\r\n\tprivate ValueAggregator\u003Cint\u003E AggregateRange\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\tif ( field is null )\r\n\t\t\t{\r\n\t\t\t\tfield = ValueAggregator\u003Cint\u003E.FromImprovement( RangeImprovement, BaseRange );\r\n\t\t\t\tDirtyRange();\r\n\t\t\t}\r\n\t\t\treturn field;\r\n\t\t}\r\n\t}\r\n\r\n\t[Property] public float Arc { get; set; } = -1.0f;\r\n\r\n\tprivate float DistSqTo( Targetable t ) =\u003E t.WorldPosition.DistanceSquared( WorldPosition );\r\n\tprivate bool InRange( Targetable t ) =\u003E RangeSq \u003C 0 || DistSqTo( t ) \u003C= RangeSq;\r\n\tprivate bool InArc( Targetable t ) =\u003E Arc \u003C -0.99f || (t.WorldPosition - WorldPosition).Normal.Dot( WorldRotation.Forward ) \u003E 0.5f;\r\n\tprivate bool CanSee( Targetable t ) =\u003E InRange( t ) \u0026\u0026 InArc( t );\r\n\tpublic bool IsValidTarget( Targetable t ) =\u003E t is not null \u0026\u0026 CanTarget( t ) \u0026\u0026 CanSee( t );\r\n\r\n\tprivate delegate I TargetCompare\u003Cin T, out I\u003E( T leader, T challenger );\r\n\tprivate IComparer\u003CTargetable\u003E TargetingComparer\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\treturn field ??= Comparer\u003CTargetable\u003E.Create( TargetingStrategy switch\r\n\t\t\t{\r\n\t\t\t\tTargetingStrategies.Healthiest =\u003E CompareHealthiest,\r\n\t\t\t\t_ =\u003E CompareNearest\r\n\t\t\t} );\r\n\t\t}\r\n\t\tset;\r\n\t} = null;\r\n\r\n\tprivate int CompareNearest( Targetable a, Targetable b )\r\n\t{\r\n\t\tif ( a is null )\r\n\t\t\treturn 1;\r\n\t\tif ( b is null )\r\n\t\t\treturn -1;\r\n\r\n\t\treturn (int)(DistSqTo( a ) - DistSqTo( b ));\r\n\t}\r\n\r\n\tprivate int CompareHealthiest( Targetable a, Targetable b )\r\n\t{\r\n\t\tif ( a is null )\r\n\t\t\treturn 1;\r\n\t\tif ( b is null )\r\n\t\t\treturn -1;\r\n\r\n\t\tvar compareCurrent = b.CurrentHp.CompareTo( a.CurrentHp );\r\n\t\tif ( compareCurrent != 0 )\r\n\t\t\treturn compareCurrent;\r\n\r\n\t\tvar compareMax = b.MaxHp.CompareTo( a.MaxHp );\r\n\t\tif ( compareMax != 0 )\r\n\t\t\treturn compareMax;\r\n\r\n\t\treturn (int)(DistSqTo( a ) - DistSqTo( b ));\r\n\t}\r\n\r\n\tpublic void DirtyRange()\r\n\t{\r\n\t\tRangeSq = float.NaN;\r\n\t}\r\n\r\n\tpublic void ContributeRange( string source, int amount )\r\n\t{\r\n\t\tAggregateRange.SetContribution( source, amount );\r\n\t\tDirtyRange();\r\n\t}\r\n\r\n\tpublic void ContributeRange( Component comp, int amount )\r\n\t{\r\n\t\tAggregateRange.SetContribution( comp, amount );\r\n\t\tDirtyRange();\r\n\t}\r\n\r\n\tpublic float GetRangeWithout( Component contributor )\r\n\t{\r\n\t\treturn AggregateRange.Without( contributor );\r\n\t}\r\n\r\n\tpublic bool CanTarget( Targetable t )\r\n\t{\r\n\t\treturn t.IsValid\r\n\t\t\t\u0026\u0026 (t.Killed ? CanTargetDead : CanTargetLiving)\r\n\t\t\t\u0026\u0026 (Status.IsFriendlyTo( t ) ? CanTargetFriends : CanTargetEnemies);\r\n\t}\r\n\r\n\tprotected override void DrawGizmos()\r\n\t{\r\n\t\tbase.DrawGizmos();\r\n\t\tGizmo.Draw.Color = Color.Orange;\r\n\t\tGizmo.Draw.LineSphere( Vector3.Zero, BaseRange );\r\n\t}\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"UI/HQ/Elements/CampaignStatsReadout.razor","FileName":"CampaignStatsReadout.razor","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"@using Sandbox.UI;\r\n@using System;\r\n@inherits Panel\r\n@namespace PlanetMeat\r\n\r\n\u003Croot\u003E\r\n\t@{\r\n\t\t\u003Cdiv class=\u0022game-title\u0022\u003E\r\n\t\t\t\u003Cspan\u003E#game.by.title\u003C/span\u003E\r\n\t\t\u003C/div\u003E\r\n\t\t\u003Cdiv class=\u0022game-by\u0022\u003E\r\n\t\t\t\u003Cspan\u003E#game.by.alxl\u003C/span\u003E\r\n\t\t\u003C/div\u003E\r\n\t\t\u003Cdiv\u003E\u003C/div\u003E\r\n\t\tvar ctx = Career.Current.CareerStats;\r\n\t\t\u003Cdiv class=\u0022category\u0022\u003E\r\n\t\t\t@{\r\n\t\t\t\tvar (myAllDmg, globalAllDmg) = GetDamageText(ctx, \u0022all\u0022);\r\n\t\t\t\t\u003Cspan class=\u0022title key\u0022\u003E#stats.dmg.all\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myAllDmg\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalAllDmg\u003C/span\u003E\r\n\t\t\t}\r\n\t\t\t@foreach (var tool in Catalogue.Current.BlameTools)\r\n\t\t\t{\r\n\t\t\t\tvar (myDmg, globalDmg) = GetDamageText(ctx, \u0022by_\u0022 \u002B tool);\r\n\t\t\t\tif (myDmg != \u0022\u0022 \u0026\u0026 globalDmg != \u0022\u0022)\r\n\t\t\t\t{\r\n\t\t\t\t\t\u003Cspan class=\u0022key\u0022\u003E#tool.@(tool).title\u003C/span\u003E\r\n\t\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myDmg\u003C/span\u003E\r\n\t\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalDmg\u003C/span\u003E\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\u003C/div\u003E\r\n\r\n\t\t@foreach (var (header, headerStat, statPrefix, statIter, getDisplayName) in Categories)\r\n\t\t{\r\n\t\t\tvar (myHeadStat, globalHeadStat) = GetGenericText(ctx, headerStat);\r\n\t\t\t\u003Cdiv class=\u0022category\u0022\u003E\r\n\t\t\t\t\u003Cspan class=\u0022title key\u0022\u003E#stats.@header\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myHeadStat\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalHeadStat\u003C/span\u003E\r\n\t\t\t\t@foreach (var stat in statIter)\r\n\t\t\t\t{\r\n\t\t\t\t\tvar (myStat, globalStat) = GetGenericText(ctx, statPrefix \u002B stat);\r\n\t\t\t\t\tif (myStat != \u0022\u0022 \u0026\u0026 globalStat != \u0022\u0022)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\u003Cspan class=\u0022key\u0022\u003E#@(getDisplayName.Invoke(stat))\u003C/span\u003E\r\n\t\t\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myStat\u003C/span\u003E\r\n\t\t\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalStat\u003C/span\u003E\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\u003C/div\u003E\r\n\t\t}\r\n\r\n\t\t\u003Cdiv class=\u0022category\u0022\u003E\r\n\t\t\t@{\r\n\t\t\t\tvar (myBank, globalBank) = GetDamageText(ctx, \u0022meat_banked\u0022);\r\n\t\t\t\t\u003Cspan class=\u0022title key\u0022\u003E#stats.meat.banked\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myBank\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalBank\u003C/span\u003E\r\n\r\n\t\t\t\tvar (myLosses, globalLosses) = GetDamageText(ctx, \u0022meat_lost\u0022);\r\n\t\t\t\t\u003Cspan class=\u0022key\u0022\u003E#stats.meat.lost\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myLosses\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalLosses\u003C/span\u003E\r\n\r\n\t\t\t\tvar (myWins, globalWins) = GetDamageText(ctx, \u0022runs_banked\u0022);\r\n\t\t\t\t\u003Cspan class=\u0022key\u0022\u003E#stats.runs.banked\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myWins\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalWins\u003C/span\u003E\r\n\r\n\t\t\t\tvar (myRounds, globalRounds) = GetDamageText(ctx, \u0022round\u0022);\r\n\t\t\t\t\u003Cspan class=\u0022key\u0022\u003E#stats.rounds.passed\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myRounds\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalRounds\u003C/span\u003E\r\n\t\t\t}\r\n\t\t\u003C/div\u003E\r\n\r\n\t\t\u003Cdiv class=\u0022category\u0022\u003E\r\n\t\t\t@{\r\n\t\t\t\tvar (mySpent, globalSpent) = GetDamageText(ctx, \u0022meat_spent\u0022);\r\n\t\t\t\t\u003Cspan class=\u0022title key\u0022\u003E#stats.meat.spent\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@mySpent\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalSpent\u003C/span\u003E\r\n\r\n\t\t\t\tvar (myImps, globalImps) = GetDamageText(ctx, \u0022improvements\u0022);\r\n\t\t\t\t\u003Cspan class=\u0022key\u0022\u003E#stats.improvements.bought\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myImps\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalImps\u003C/span\u003E\r\n\r\n\t\t\t\tvar (myTechs, globalTechs) = GetDamageText(ctx, \u0022tech\u0022);\r\n\t\t\t\t\u003Cspan class=\u0022key\u0022\u003E#stats.tech.researched\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@myTechs\u003C/span\u003E\r\n\t\t\t\t\u003Cspan class=\u0022value\u0022\u003E@globalTechs\u003C/span\u003E\r\n\t\t\t}\r\n\t\t\u003C/div\u003E\r\n\r\n\t\t\u003Cdiv\u003E\u003C/div\u003E\r\n\t\t\u003Cdiv\u003E\u003C/div\u003E\r\n\t\t\u003Cdiv class=\u0022hint\u0022\u003E\r\n\t\t\t\u003Cspan\u003E#stats.hint\u003C/span\u003E\r\n\t\t\u003C/div\u003E\r\n\t}\r\n\u003C/root\u003E\r\n\r\n@code\r\n{\r\n\tprivate IEnumerable\u003C(string, string, string, IEnumerable\u003Cstring\u003E, Func\u003Cstring, string\u003E)\u003E Categories =\u003E field ??= [\r\n\t\t(\u0022kill_weps.all\u0022, \u0022wep_kills\u0022, \u0022kills_by_\u0022, Catalogue.Current.BlameTools, (t) =\u003E \u0022tool.\u0022 \u002B t \u002B \u0022.title\u0022),\r\n\t\t(\u0022kill_types.all\u0022, \u0022kills_all\u0022, \u0022kills_\u0022, Agenda.Current.AllVariantIdents, EnemyVariant.GetDisplayName),\r\n\t\t(\u0022runs.lost\u0022, \u0022runs_lost\u0022, \u0022defeated_by_\u0022, Agenda.Current.AllVariantIdents, EnemyVariant.GetDisplayName),\r\n\t];\r\n\r\n\tprivate static string GetDamageString(double dmg, double overkill) =\u003E LargeNumberString.ToCompact(dmg - overkill) \u002B \u0022 \u00B7 \u0022 \u002B LargeNumberString.ToCompact(overkill);\r\n\r\n\tprivate (string, string) GetDamageText(StatContext ctx, string scope)\r\n\t{\r\n\t\tvar dmgIdent = \u0022damage_\u0022 \u002B scope;\r\n\t\tvar overkillIdent = \u0022overkill_\u0022 \u002B scope;\r\n\r\n\t\tvar myDmg = ctx.GetNow(dmgIdent);\r\n\t\tvar myOverkill = ctx.GetNow(overkillIdent);\r\n\t\tvar worldDmg = Career.GetGlobalStat(dmgIdent);\r\n\t\tvar worldOverkill = Career.GetGlobalStat(overkillIdent);\r\n\r\n\t\treturn (GetDamageString(myDmg, myOverkill), \u0022(\u0022 \u002B GetDamageString(worldDmg, worldOverkill) \u002B \u0022)\u0022);\r\n\t}\r\n\r\n\tprivate (string, string) GetGenericText(StatContext ctx, string ident)\r\n\t{\r\n\t\tvar me = ctx.GetNow(ident);\r\n\t\tvar world = Career.GetGlobalStat(ident);\r\n\r\n\t\treturn (LargeNumberString.ToCompact(me), \u0022(\u0022 \u002B LargeNumberString.ToCompact(world) \u002B \u0022)\u0022);\r\n\t}\r\n\r\n\tprotected override int BuildHash() =\u003E HashCode.Combine(\r\n\t\tHqNavigator.View\r\n\t);\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"ui/components/progressbar.razor.scss","FileName":"progressbar.razor.scss","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"ProgressBar {\r\n\talign-self: stretch;\r\n\toverflow: hidden;\r\n\twidth: 100%;\r\n\tposition: relative;\r\n\tcolor: #fff;\r\n\r\n\t.progress-fill {\r\n\t\theight: 100%;\r\n\t\tbackground-color: #999;\r\n\t}\r\n\r\n\t.progress-text {\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t\tposition: absolute;\r\n\t\tleft: 0px;\r\n\t\tright: 0px;\r\n\t\ttop: 0px;\r\n\t\tbottom: 0px;\r\n\t}\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Agenda/Career.cs","FileName":"Career.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"using System.Text.Json.Nodes;\r\nusing Sandbox.Services;\r\n\r\nnamespace PlanetMeat;\r\n\r\npublic sealed class Career( Scene scene ) : GameObjectSystem\u003CCareer\u003E( scene )\r\n{\r\n\tconst string ENTRY_TYPE_SAVE = \u0022save\u0022;\r\n\tconst string PROGRESS_FILE_NAME = \u0022progress.json\u0022;\r\n\tconst string STATS_FILE_NAME = \u0022stats.json\u0022;\r\n\r\n\tprivate IEnumerable\u003CKeyValuePair\u003Cstring, ISaveTarget\u003E\u003E ProgressSaveTargets =\u003E field ??= [\r\n\t\tnew(\u0022Meat\u0022, Bank.Current.GetAccount( \u0022meat\u0022 )),\r\n\t\tnew(\u0022Research\u0022, Research.Current),\r\n\t];\r\n\r\n\tpublic bool IsFreshSave { get; private set; } = true;\r\n\tpublic int HighestRoundCompleted\r\n\t{\r\n\t\tget;\r\n\t\tset\r\n\t\t{\r\n\t\t\tif ( value == 0 || value \u003E field )\r\n\t\t\t{\r\n\t\t\t\tfield = value;\r\n\t\t\t\tif ( value \u003E 0 )\r\n\t\t\t\t\tStats.SetValue( \u0022peak_round\u0022, value );\r\n\t\t\t}\r\n\t\t}\r\n\t} = 0;\r\n\r\n\tpublic StatContext RoundStats { get; } = new();\r\n\tpublic StatContext RunStats { get; } = new();\r\n\tpublic StatContext CareerStats { get; } = new();\r\n\r\n\tprivate Storage.Entry _saveEntry = null;\r\n\tprivate Storage.Entry SaveEntry\r\n\t{\r\n\t\tget\r\n\t\t{\r\n\t\t\tif ( NeedsLoad )\r\n\t\t\t\tLoadSave();\r\n\t\t\treturn _saveEntry;\r\n\t\t}\r\n\t\tset =\u003E LoadSave( value );\r\n\t}\r\n\tpublic bool NeedsLoad =\u003E _saveEntry is null;\r\n\r\n\tprivate static Storage.Entry FetchSave()\r\n\t{\r\n\t\tvar extantSaves = Storage.GetAll( ENTRY_TYPE_SAVE );\r\n\t\tif ( extantSaves.Length \u003E 0 )\r\n\t\t\treturn extantSaves[0];\r\n\t\treturn Storage.CreateEntry( ENTRY_TYPE_SAVE );\r\n\t}\r\n\r\n\tpublic void LoadSave( Storage.Entry s = null )\r\n\t{\r\n\t\ts ??= FetchSave();\r\n\t\tIsFreshSave = !s.Files.FileExists( PROGRESS_FILE_NAME );\r\n\t\tif ( _saveEntry != s )\r\n\t\t{\r\n\t\t\t_saveEntry = s;\r\n\t\t\tif ( s.Files.ReadJson\u003CJsonObject\u003E( PROGRESS_FILE_NAME ) is JsonObject progress )\r\n\t\t\t\tProgressSaveTargets.LoadFromSaveObject( progress );\r\n\t\t\tif ( s.Files.ReadJson\u003CJsonObject\u003E( STATS_FILE_NAME ) is JsonObject stats )\r\n\t\t\t\tCareerStats.LoadFromSave( stats );\r\n\r\n\t\t\tHighestRoundCompleted = 0;\r\n\t\t\tHighestRoundCompleted = s.GetMeta( nameof( HighestRoundCompleted ), 0 );\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void SaveProgress()\r\n\t{\r\n\t\tSaveEntry.Files.WriteJson( PROGRESS_FILE_NAME, ProgressSaveTargets.ToSaveObject() );\r\n\t\tSaveEntry.SetMeta( nameof( HighestRoundCompleted ), HighestRoundCompleted );\r\n\t\tIsFreshSave = false;\r\n\t}\r\n\r\n\tpublic void Reset()\r\n\t{\r\n\t\tHqNavigator.View = HqNavigator.Views.None;\r\n\r\n\t\tRoundStats.Reset();\r\n\t\tRunStats.Reset();\r\n\t\tCareerStats.Reset();\r\n\r\n\t\tProgressSaveTargets.ClearSavedInfo();\r\n\r\n\t\tSaveEntry.Delete();\r\n\t\tSaveEntry = null;\r\n\t}\r\n\r\n\tpublic void SetStat( string ident, double value )\r\n\t{\r\n\t\tStats.SetValue( ident, value );\r\n\t\tRoundStats.SetStat( ident, value );\r\n\t}\r\n\r\n\tpublic void IncrementStat( string ident, double amount = 1.0 )\r\n\t{\r\n\t\tStats.Increment( ident, amount );\r\n\t\tRoundStats.IncrementStat( ident, amount );\r\n\t}\r\n\r\n\tpublic void CommitRoundStats()\r\n\t{\r\n\t\tRoundStats.MergeInto( RunStats );\r\n\t}\r\n\r\n\tpublic void CommitRunStats()\r\n\t{\r\n\t\tCommitRoundStats();\r\n\t\tRunStats.MergeInto( CareerStats );\r\n\t\tSaveEntry.Files.WriteJson( STATS_FILE_NAME, CareerStats.NextSave );\r\n\t}\r\n\r\n\tpublic static double GetGlobalStat( string ident )\r\n\t{\r\n\t\treturn Stats.Global.Get( ident ).Sum;\r\n\t}\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Effects/Ring/TimedRing.cs","FileName":"TimedRing.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Group( \u0022Planet Meat - Effects\u0022 ), Title( \u0022Timed Ring\u0022 ), Icon( \u0022radar\u0022 )]\r\npublic class TimedRing : Component, IWorldRing\r\n{\r\n\tprivate static GameObject Prefab =\u003E GameObject.GetPrefab( \u0022tools/timed_ring.prefab\u0022 );\r\n\tpublic static TimedRing Create( Vector3 position, float radius )\r\n\t{\r\n\t\tvar go = Prefab.Clone( position );\r\n\t\tif ( go.Components.Get\u003CTimedRing\u003E() is TimedRing ring )\r\n\t\t{\r\n\t\t\tring.EffectRadius = radius;\r\n\t\t\treturn ring;\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\t[Property] public AoeRing EffectRing { get; set; }\r\n\t[Property] public AoeRing TimerRing { get; set; }\r\n\r\n\tpublic float EffectRadius\r\n\t{\r\n\t\tget =\u003E EffectRing.Radius;\r\n\t\tset =\u003E EffectRing.Radius = value;\r\n\t}\r\n\r\n\tprotected float TimerStartRadius { get; set; }\r\n\tprotected float TimerFinalRadius { get; set; }\r\n\tprotected float ProgressMax { get; set; } = float.NaN;\r\n\tprotected float Progress\r\n\t{\r\n\t\tget;\r\n\t\tset\r\n\t\t{\r\n\t\t\tvar pMax = ProgressMax;\r\n\t\t\tif ( !float.IsNaN( pMax ) )\r\n\t\t\t{\r\n\t\t\t\tLerp( value / pMax );\r\n\r\n\t\t\t\tif ( value \u003E= pMax )\r\n\t\t\t\t{\r\n\t\t\t\t\tProgressMax = float.NaN;\r\n\t\t\t\t\tfield = 0.0f;\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tfield = value;\r\n\t\t}\r\n\t} = 0.0f;\r\n\r\n\tprotected virtual void Lerp( float frac )\r\n\t{\r\n\t\tTimerRing.Radius = TimerStartRadius.LerpTo( TimerFinalRadius, frac );\r\n\t}\r\n\r\n\tprotected virtual void ShowTimer( bool show )\r\n\t{\r\n\t\tTimerRing.Components.Get\u003CWorldPanel\u003E()?.Enabled = show;\r\n\t}\r\n\r\n\tprivate void ApplyTimerVisibility()\r\n\t{\r\n\t\tShowTimer( !float.IsNaN( ProgressMax ) );\r\n\t}\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tbase.OnStart();\r\n\t\tApplyTimerVisibility();\r\n\t}\r\n\r\n\tpublic virtual void MultiplyAlpha( float mult )\r\n\t{\r\n\t\tEffectRing.RingColor = EffectRing.RingColor.WithAlphaMultiplied( mult );\r\n\t\tTimerRing.RingColor = TimerRing.RingColor.WithAlphaMultiplied( mult );\r\n\t}\r\n\r\n\tprotected void StartTimer( float duration )\r\n\t{\r\n\t\tProgressMax = duration;\r\n\t\tProgress = 0.0f;\r\n\t}\r\n\r\n\tpublic void StartBasicTimer( float duration, bool inwards )\r\n\t{\r\n\t\tTimerStartRadius = inwards ? EffectRadius : 0.0f;\r\n\t\tTimerFinalRadius = inwards ? 0.0f : EffectRadius;\r\n\t\tStartTimer( duration );\r\n\t}\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\tbase.OnUpdate();\r\n\t\tif ( !float.IsNaN( ProgressMax ) )\r\n\t\t\tProgress \u002B= Time.Delta;\r\n\t}\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Effects/WorldSound.cs","FileName":"WorldSound.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Group( \u0022Planet Meat - Effects\u0022 ), Title( \u0022SFX Bundle\u0022 ), Icon( \u0022speaker_group\u0022 )]\r\npublic sealed class SoundEffectsBundle : Component\r\n{\r\n\tprivate static GameObject Prefab =\u003E GameObject.GetPrefab( \u0022effects/point_sound.prefab\u0022 );\r\n\tpublic static SoundEffectsBundle Create( Vector3 position, IEnumerable\u003CSoundEvent\u003E sounds )\r\n\t{\r\n\t\tif ( Prefab.Clone( position ).Components.Get\u003CSoundEffectsBundle\u003E() is SoundEffectsBundle sfb )\r\n\t\t{\r\n\t\t\tforeach ( var s in sounds )\r\n\t\t\t\tsfb.AddSound( s );\r\n\t\t\treturn sfb;\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\tpublic void AddSound( SoundEvent sound )\r\n\t{\r\n\t\tvar soundComp = Components.Create\u003CSoundPointComponent\u003E();\r\n\t\tsoundComp.TargetMixer = \u0022Game\u0022;\r\n\t\tsoundComp.SoundEvent = sound;\r\n\t\tsoundComp.StartSound();\r\n\t}\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Spending/Upgrades/AutoWeapon/MultishotDamageUpgrade.cs","FileName":"MultishotDamageUpgrade.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Title( \u0022Multishot Upgrade - Damage\u0022 )]\r\npublic sealed class MultishotDamageUpgrade : PercentageAggregateUpgrade\u003CAutoWeapon\u003E\r\n{\r\n\tprotected override ValueAggregator\u003Cfloat\u003E FindAggregate =\u003E TargetComponent?.AggregateMultishotDamage;\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Spending/Upgrades/Meat/BaseMeatUpgrade.cs","FileName":"BaseMeatUpgrade.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\npublic abstract class PercentageMeatUpgrade : BaseComponentUpgrade\u003CMeatImprover, float\u003E\r\n{\r\n\tprotected abstract ValueAggregator\u003Cfloat\u003E Agg { get; }\r\n\r\n\tprotected override float EffectBase =\u003E TargetComponent?.GetWithout( Agg ) ?? 0.0f;\r\n\tprotected override float GetEffectAt( int rank ) =\u003E EffectPerRank.MultiplyCapped( rank );\r\n\r\n\tprotected override void OnRankChanged()\r\n\t{\r\n\t\tTargetComponent?.Contribute( Agg, CurrentEffect );\r\n\t}\r\n\r\n\tpublic override string GetDisplayedEffectAt( int rank ) =\u003E PercentageEffectImprovement.GetDisplayedPercentage( GetOveralEffect( rank ), DecimalPlaces );\r\n}\r\n\r\npublic abstract class IntMeatUpgrade : BaseComponentUpgrade\u003CMeatImprover, int\u003E\r\n{\r\n\tprotected abstract ValueAggregator\u003Cint\u003E Agg { get; }\r\n\r\n\tprotected override int EffectBase =\u003E TargetComponent?.GetWithout( Agg ) ?? 0;\r\n\tprotected override int GetEffectAt( int rank ) =\u003E EffectPerRank.MultiplyCapped( rank );\r\n\r\n\tprotected override void OnRankChanged()\r\n\t{\r\n\t\tTargetComponent?.Contribute( Agg, CurrentEffect );\r\n\t}\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Spending/Upgrades/Targetable/RepairTargetableUpgrade.cs","FileName":"RepairTargetableUpgrade.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"using System;\r\n\r\nnamespace PlanetMeat;\r\n\r\n[Title( \u0022Target Upgrade - Repair\u0022 )]\r\npublic sealed class RepairTargetableUpgrade : BaseUpgrade\r\n{\r\n\tconst int HP_PER_RANK = 10;\r\n\r\n\tprivate Targetable Targetable =\u003E field ??= this.FindNearestUpwards\u003CTargetable\u003E();\r\n\r\n\tpublic override bool Purchaseable =\u003E Targetable.CurrentHp \u003C Targetable.MaxHp;\r\n\tpublic override double NextCost =\u003E Math.Round( Agenda.Current.RoundNum \u002B Progressions.StairSlow( Rank ) );\r\n\tprivate int RepairResult =\u003E Math.Min( Targetable.CurrentHp \u002B HP_PER_RANK, Targetable.MaxHp );\r\n\r\n\tprotected override void OnRankChanged()\r\n\t{\r\n\t\tTargetable?.CurrentHp = RepairResult;\r\n\t}\r\n\r\n\tpublic override string GetDisplayedEffectAt( int rank )\r\n\t{\r\n\t\tif ( rank == Rank )\r\n\t\t\treturn Targetable.CurrentHp.ToString();\r\n\t\treturn RepairResult.ToString();\r\n\t}\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Spending/Upgrades/Targetable/ResistFlatTargetableUpgrade.cs","FileName":"ResistFlatTargetableUpgrade.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Title( \u0022Target Upgrade - Resistance (Flat)\u0022 )]\r\npublic sealed class ResistFlatTargetableUpgrade : IntAggregateUpgrade\u003CTargetable\u003E\r\n{\r\n\tprotected override ValueAggregator\u003Cint\u003E FindAggregate =\u003E TargetComponent?.AggregateResistFlat;\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Units/Animator.cs","FileName":"Animator.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"using Sandbox.Citizen;\r\n\r\nnamespace PlanetMeat;\r\n\r\n[Group( \u0022Planet Meat - Units\u0022 ), Title( \u0022Animator\u0022 ), Icon( \u0022emoji_people\u0022 )]\r\npublic sealed class Animator : Component\r\n{\r\n\t[RequireComponent] public CitizenAnimationHelper AnimHelper { get; set; }\r\n\tpublic SkinnedModelRenderer SkinnedModel =\u003E AnimHelper.Target;\r\n\r\n\t[Property] public CitizenAnimationHelper.HoldTypes StartingHold { get; set; }\r\n\t[Property] public CitizenAnimationHelper.Hand StartingHandedness { get; set; }\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tbase.OnStart();\r\n\t\tAnimHelper.HoldType = StartingHold;\r\n\t\tAnimHelper.Handedness = StartingHandedness;\r\n\t}\r\n\r\n\tpublic void Move( Vector3 velocity, Vector3 look )\r\n\t{\r\n\t\tAnimHelper.WithVelocity( velocity / SkinnedModel.WorldScale.x );\r\n\t\tAnimHelper.WithLook( look - WorldPosition );\r\n\t}\r\n\tpublic void Move( Vector3 velocity ) =\u003E Move( velocity, SkinnedModel.WorldTransform.Forward );\r\n\tpublic void StopMoving() =\u003E Move( Vector3.Zero );\r\n\r\n\tpublic void Attack()\r\n\t{\r\n\t\tAnimHelper.Target.Set( \u0022b_attack\u0022, true );\r\n\t}\r\n\r\n\tpublic void TurnTo( Rotation worldRotation )\r\n\t{\r\n\t\tSkinnedModel.WorldRotation = worldRotation;\r\n\t}\r\n\tpublic void TurnTo( Vector3 direction ) =\u003E TurnTo( Rotation.LookAt( direction ) );\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Units/AttackBlame.cs","FileName":"AttackBlame.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\n[Group( \u0022Planet Meat - Units\u0022 ), Title( \u0022AttackBlame\u0022 ), Icon( \u0022ads_click\u0022 )]\r\npublic sealed class AttackBlame : Component, IAttackBlame\r\n{\r\n\t[Property] public string Ident { get; set; }\r\n}\r\n"},{"Ident":"pwegg.planet_meat","Path":"Units/IAttackBlame.cs","FileName":"IAttackBlame.cs","PackageType":"game","CodeKind":"Game","AssetVersionId":392803,"IsPrivate":false,"Code":"namespace PlanetMeat;\r\n\r\npublic interface IAttackBlame\r\n{\r\n\tpublic string Ident { get; }\r\n}\r\n"}]}