s&box Package Code Search

Search C# source code, UI razor templates, shaders, and configs across s&box packages.

Showing code results for query: * (38 total matches found)
rakunsoftware.milaine / Scripts/Managers/GameManager.cs
Game game
using System;
using Milaine.TreeSkills;

namespace Milaine.Managers;

public sealed class GameManager : Component {
  [Property, Title("IdleManager")]
  [Feature("General")]
  public IdleManager IdleManagerInstance { get; set; }

  [Property, Title("InvestmentManager")]
  [Feature("General")]
  public InvestmentManager InvestmentManagerInstance { get; set; }

  [Property, Title("SkillTreeBootstrap")]
  [Feature("General")]
  public SkillTreeBootstrap SkillTreeBootstrapInstance { get; set; }

  [Property, Title("DayNightManager")]
  [Feature("General")]
  public DayNightManager DayNightManagerInstance { get; set; }

  public Action OnLooseGame { get; set; }
  public Action OnWinGame { get; set; }

  private List<SkillNodeData> skillsUsed = [];
  private int maxSkillPoints = 0;
  private int skillPoints = 0;
  private bool isPlaying = true;
  private bool isGameWin = false;

  public bool IsGameWin {
    get => isGameWin;
  }

  protected override void OnAwake() {
    TreeSkillState.Instance.OnUnlocked += OnUnlocked;
    TreeSkillState.Instance.SpendPoint += OnSpendPoint;
    TreeSkillState.Instance.GetSkillPoints = GetSkillPoints;
    DayNightManagerInstance.OnEndDay += OnEndDay;
    InvestmentManagerInstance.OnChange += OnInvestmentManagerChange;
  }

  protected override void OnDestroy() {
    TreeSkillState.Instance.OnUnlocked -= OnUnlocked;
    TreeSkillState.Instance.SpendPoint -= OnSpendPoint;
    DayNightManagerInstance.OnEndDay -= OnEndDay;
    InvestmentManagerInstance.OnChange -= OnInvestmentManagerChange;
  }

  private void OnEndDay() {
    if (DayNightManagerInstance.Day < 5) {
      return;
    }

    isPlaying = false;
    isGameWin = false;
    OnLooseGame?.Invoke();
  }

  private void OnInvestmentManagerChange(Portfolio portfolio) {
    if (!isPlaying) {
      return;
    }

    int total = (int)portfolio.investment;
    int goal = IdleManagerInstance.Goal;

    if (total >= goal) {
      isPlaying = false;
      isGameWin = true;
      DayNightManagerInstance.ResetManager();
      OnWinGame?.Invoke();
    }
  }

  private void OnUnlocked(SkillNodeData node) {
    if (skillsUsed.Contains(node)) {
      return;
    }

    skillsUsed.Add(node);

    switch (node.Category) {
      case SkillCategory.Dollars:
        IdleManagerInstance.ImprovePoint(node.Point);
        break;
      case SkillCategory.DollarAutomatic:
        IdleManagerInstance.ImprovePasiveDollar(node.Point);
        break;
      case SkillCategory.Wallet:
        InvestmentManagerInstance.ImproveWallet(node.Point);
        break;
      case SkillCategory.Investment:
        InvestmentManagerInstance.ImprovePerformance(node.Point);
        break;
      case SkillCategory.Dividends:
        InvestmentManagerInstance.ImproveDividends(node.Point);
        break;
      case SkillCategory.WalletPlus:
        InvestmentManagerInstance.ImproveDeposit(node.Point);
        break;
    }
  }

  private int GetSkillPoints() => skillPoints;

  private void OnSpendPoint() {
    skillPoints--;
  }

  public void Restart() {
    DayNightManagerInstance.Restart();
    TreeSkillState.Instance.Restart();
    skillsUsed = [];
    maxSkillPoints += 1;
    skillPoints += maxSkillPoints;

    IdleManagerInstance.Restart();
    InvestmentManagerInstance.Restart();
  }
}
rakunsoftware.milaine / Scripts/Managers/MouseManager.cs
Game game
namespace Milaine.Managers;

public enum StateMouse {
  Relased,
  Busy
}

public static class MouseManager {
  public static StateMouse State { get; set; } = StateMouse.Relased;

  public static void ShowMouse() {
    Mouse.Visibility = MouseVisibility.Visible;
  }

  public static void HideMouse() {
    Mouse.Visibility = MouseVisibility.Hidden;
  }
}
rakunsoftware.milaine / Scripts/Managers/DayNightManager.cs
Game game
using System;
using Milaine.Interfaces;

namespace Milaine.Managers;

public sealed class DayNightManager : Component, IManager {
  // 60 -> seconds
  private const int MINUTE = 60;
  // 5 mins
  private const int MAX_TIME = 5 * MINUTE;
  public const int MAX_DAYS = 5;

  [Property]
  public float DayDuration { get; set; } = MAX_TIME;

  [Property]
  public int Day { get; set; } = 1;

  // hour in 24h
  private readonly float startHour = 8f;
  private readonly float endHour = 18f;

  private bool isDayActive = false;
  private TimeUntil timeUntilNight;

  public string CurrentTimeString { get; private set; } = "8:00 AM";

  public Action OnStartDay;
  public Action OnEndDay;

  protected override void OnStart() {
    StartDay();
  }

  protected override void OnUpdate() {
    if (!isDayActive) {
      return;
    }

    float elapsedSeconds = DayDuration - timeUntilNight;
    float progress = MathX.Clamp(elapsedSeconds / DayDuration, 0f, 1f);
    float totalVirtualHours = endHour - startHour;
    float currentVirtualHour = startHour + (progress * totalVirtualHours);

    int hours = (int)MathF.Floor(currentVirtualHour);
    int minutes = (int)MathF.Floor((currentVirtualHour - hours) * 60f);

    string amPm = hours >= 12 ? "PM" : "AM";
    int displayHour = hours % 12;

    if (displayHour == 0) {
      displayHour = 12;
    }

    CurrentTimeString = $"{displayHour:D2}:{minutes:D2} {amPm}";

    if (timeUntilNight) {
      EndDay();
    }
  }

  private void StartDay() {
    if (isDayActive) {
      return;
    }

    timeUntilNight = DayDuration;
    isDayActive = true;

    OnStartDay?.Invoke();
  }

  private void EndDay() {
    ResetManager(deep: false);
    OnEndDay?.Invoke();
  }

  public void ResetManager(bool deep = false) {
    if (deep) {
      CurrentTimeString = "8:00 AM";
    }

    isDayActive = false;
  }

  public void NextDay() {
    if (Day >= MAX_DAYS) {
      return;
    }

    Day += 1;
    StartDay();
  }

  public void Restart() {
    Day = 1;
    StartDay();
  }
}
rakunsoftware.milaine / Scripts/Room/ClickableButton.cs
Game game
using System;
using Milaine.Managers;

namespace Milaine.Room;

public sealed class ClickableButton : Component {
  [Property, Group("References")]
  public SkinnedModelRenderer Model { get; set; }

  [Property, Group("Animation"), Title("Sequence Name")]
  public string PressSequence { get; set; } = "press";

  [Property, Group("Animation")]
  public bool UsesAnimGraph { get; set; } = false;

  [Property, Group("Interaction")]
  public float MaxClickDistance { get; set; } = 1000f;

  [Property, Group("Squish (Scale Z)"), Range(0.1f, 1f)]
  public float PressedScale { get; set; } = 0.8f;

  [Property, Group("Squish (Scale Z)"), Range(1f, 30f)]
  public float ScaleSpeed { get; set; } = 14f;

  public Action OnPressed { get; set; }

  private bool isHeld;
  private Vector3 originalScale;
  private float currentScaleFactor = 1f;

  protected override void OnStart() {
    if (!Model.IsValid()) {
      Model = Components.Get<SkinnedModelRenderer>();
    }

    originalScale = LocalScale;
  }

  protected override void OnUpdate() {
    if (MouseManager.State == StateMouse.Busy) {
      return;
    }

    var camera = Scene.Camera;

    if (!camera.IsValid()) {
      return;
    }

    var ray = camera.ScreenPixelToRay(Mouse.Position);
    var trace = Scene.Trace.Ray(ray, MaxClickDistance).Run();
    bool isHoveredNow = trace.Hit && trace.GameObject == GameObject;

    if ((Input.Pressed("attack1") || Input.Pressed("attack2")) && isHoveredNow) {
      Press();
      isHeld = true;
    }

    if (Input.Released("attack1") || Input.Released("attack2")) {
      isHeld = false;
    }

    float targetFactor = isHeld ? PressedScale : 1f;
    currentScaleFactor = MathX.Lerp(currentScaleFactor, targetFactor, Time.Delta * ScaleSpeed);

    LocalScale = new Vector3(originalScale.x, originalScale.y, originalScale.z * currentScaleFactor);
  }

  public void Press() {
    PlayPressAnimation();
    Sound.Play("sounds/sound_key_down.sound");
    OnPressed?.Invoke();
  }

  private void PlayPressAnimation() {
    if (!Model.IsValid()) {
      return;
    }

    if (UsesAnimGraph) {
      Model.Set(PressSequence, true);
    } else {
      Model.SceneModel.UseAnimGraph = false;
      Model.SceneModel.CurrentSequence.Name = PressSequence;
    }
  }
}
rakunsoftware.milaine / Scripts/Room/RoomManager.cs
Game game
namespace Milaine.Room;

public sealed class RoomManager : Component {
  [Property]
  public List<GameObject> Models { get; set; } = [];

  private List<GameObject> ChairChildren = [];

  protected override void OnAwake() {
    if (Models.Count == 0) {
      Log.Warning("Models list is empty");
      return;
    }

    foreach (GameObject gameObject in Models) {
      if (!gameObject.IsValid()) {
        continue;
      }

      Prop prop = gameObject.GetComponent<Prop>();

      if (!prop.IsValid()) {
        continue;
      }

      prop.IsStatic = true;

      if (gameObject.Name == "office_chair") {
        gameObject.GetComponent<ModelRenderer>().Destroy();
        gameObject.GetComponent<ModelPhysics>().Destroy();

        foreach (GameObject obj in gameObject.Children) {
          ChairChildren.Add(obj);
        }
      }
    }

  }

  protected override void OnUpdate() {
    if (ChairChildren.Count == 0) {
      return;
    }

    foreach (GameObject gameObject in ChairChildren) {
      gameObject.Destroy();
    }

    ChairChildren = [];
  }
}
rakunsoftware.milaine / Scripts/Settings/Configuration.cs
Game game
using System;

namespace Milaine.Settings;

public class ConfigurationData {
  public string Language { get; set; } = "en";
}

public sealed class Configuration : Component {
  private readonly string filename = "settings.cfg";

  [Property]
  public string Language { get; set; } = "en";

  protected override void OnAwake() {
    if (!FileSystem.Data.FileExists(filename)) {
      SaveConfig();

      return;
    }

    LoadConfig();
  }

  public void LoadConfig() {
    var config = FileSystem.Data.ReadJson<ConfigurationData>(filename);
    Language = config.Language;
  }

  public void SaveConfig() {
    try {
      var config = new ConfigurationData { Language = Language };
      FileSystem.Data.WriteJson(filename, config);
    }
    catch (Exception ex) {
      Log.Warning($"Error to try create configuration file: {ex.Message}");
    }
  }
}
rakunsoftware.milaine / UI/FloatingTextManager/FloatingTextManager.razor
Game game
@using Sandbox;
@using Sandbox.UI;
@namespace Milaine.UI
@inherits Panel

<root></root>

@code {
  public static FloatingTextManager Instance { get; set; }

  public FloatingTextManager()
  {
    Instance = this;
  }

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

    if (Instance == this)
    {
      Instance = null;
    }
  }

  public void Spawn(string text, float screenX, float screenY)
  {
    var floatingText = AddChild<FloatingText>();
    floatingText.Text = text;
    floatingText.SpawnX = screenX;
    floatingText.SpawnY = screenY;
  }
}

<style>
  FloatingTextManager {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
  }
</style>
rakunsoftware.milaine / Scripts/Utils/Outliner.cs
Game game
namespace Milaine.Utils;

public sealed class Outliner : Component {
  [Property, Group("Interaction")]
  public float MaxClickDistance { get; set; } = 1000f;

  [Property, Group("Outline"), Title("Color Hover")]
  public Color HoverOutlineColor { get; set; } = Color.White;

  [Property, Group("Outline"), Range(0.1f, 10f)]
  public float OutlineWidth { get; set; } = 0.5f;

  private HighlightOutline outline;

  protected override void OnAwake() {
  }

  protected override void OnStart() {
    outline = GameObject.GetOrAddComponent<HighlightOutline>();
    outline.Color = Color.Transparent;
    outline.Width = OutlineWidth;
  }

  protected override void OnUpdate() {
    var camera = Scene.Camera;

    if (!camera.IsValid()) {
      return;
    }

    var ray = camera.ScreenPixelToRay(Mouse.Position);
    var trace = Scene.Trace.Ray(ray, MaxClickDistance).Run();

    bool isHoveredNow = trace.Hit && trace.GameObject == GameObject;

    if (outline.IsValid()) {
      outline.Color = isHoveredNow ? HoverOutlineColor : Color.Transparent;
    }
  }
}
rakunsoftware.milaine / UI/Hud/Hud.razor
Game game
@using System.Threading.Tasks;
@using Milaine.Managers;
@using Milaine.Settings;
@using Milaine.UI;
@using Milaine.Utils;
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@namespace Sandbox

<root>
  <header class="header">
    <section class="day-manager">
      <h2>
        @TranslationsInstance.T("milaine.days", data)
        @* @Language.GetPhrase("milaine.days", data) *@
      </h2>
    </section>
    <section class="clock">
      <p>@DayNightManagerInstance.CurrentTimeString</p>
    </section>
  </header>
  <section class="progress-end-game">
    <div class="progress-bar">
      <div class="bar" style="width: @(GetPercentage())%;" />
      <p>@Formatter.ToDisplay(InvestmentManagerInstance.Total) / @Formatter.ToDisplay(IdleManagerInstance.Goal)</p>
    </div>
  </section>
  <button class="slot" style="pointer-events: @(!isPanelOpened ? "all" : "none");" onclick=@TogglePanel>
    <p class="kbd">E</p>
    <p class="title">
      @TranslationsInstance.T("milaine.tree-skills")
      @* #milaine.tree-skills *@
    </p>
  </button>
  <div class="container">
    <section class="content">
      <Image src="resources/wallet-minimal.png" class="image" style="width: 40px; height: 40px;" />
      <p class="headline">[email protected](Dollars)</p>
      <FloatingTextManager />
    </section>
  </div>
  @if (isInitializedDay) {
    <div class="day-container">
      <h2 class="heading-current-day">
        @* @Language.GetPhrase("milaine.days", data) *@
        @TranslationsInstance.T("milaine.days", data)
      </h2>
    </div>
  }
  @if (isGameWin) {
    <div
      style="background-color: black; position: absolute; top: 0; left: 0; right: 0; bottom: 0; justify-content: center; align-items: center;">
      <div style="width: 30%;justify-content:center;align-items:center;">
        <p style="font-size: 40px; font-family: 'JetBrains Mono';">
          @* #milaine.wingame *@
          @TranslationsInstance.T("milaine.wingame")
        </p>
      </div>
    </div>
  }

  @if (isDayEnd && !isGameWin) {
    <div class="day-container night">
      <div class="summary-container">
        <header class="summary-header">
          <div class="summary-title">
            <span class="circle" />
            <h2 class="normal-font">
              @* #milaine.summary.title *@
              @TranslationsInstance.T("milaine.summary.title")
            </h2>
          </div>
          <div class="separator" />
        </header>
        <div class="row">
          <div class="form-control nth mblue">
            <div class="form-control-header">
              <h3 class="normal-font">
                @* #milaine.summary.investment *@
                @TranslationsInstance.T("milaine.summary.investment")
              </h3>
              <span class="circle-base circle-blue" />
            </div>
            <p class="number">
              [email protected](InvestmentManagerInstance.Profit)
            </p>
          </div>
          <div class="form-control nth mgreen">
            <div class="form-control-header">
              <h3 class="normal-font">
                @* #milaine.summary.wallet *@
                @TranslationsInstance.T("milaine.summary.wallet")
              </h3>
              <span class="circle-base circle-green" />
            </div>
            <p class="number">
              [email protected](InvestmentManagerInstance.WalletPasive)
            </p>
          </div>
          <div class="form-control nth mred">
            <div class="form-control-header">
              <h3 class="normal-font">
                @* #milaine.summary.dollar-spent *@
                @TranslationsInstance.T("milaine.summary.dollar-spent")
              </h3>
              <span class="circle-base circle-red" />
            </div>
            <p class="number">
              [email protected](IdleManagerInstance.DollarsSpent)
            </p>
          </div>
        </div>
        <div class="separator" />

        @if (DayNightManagerInstance.Day == DayNightManager.MAX_DAYS) {
          <button class="btn-next-action normal-font" onclick=@HandleAgain>
            @* #milaine.back-to-past *@
            @TranslationsInstance.T("milaine.back-to-past")
          </button>
        } else {
          <button class="btn-next-action normal-font" onclick=@HandleNextDay>
            @* #milaine.next-day *@
            @TranslationsInstance.T("milaine.next-day")
          </button>
        }
      </div>
    </div>
  }
  <div class="version-manager">
    <p>@("v" + VersionManagerInstance.Version.ToString())</p>
  </div>
</root>

@code
{
  private const float ANIMATION_DURATION = 5f;

  [Property, Title("Translations")]
  [Feature("Managers")]
  public Translations TranslationsInstance { get; set; }

  [Property, Title("VersionManager")]
  [Feature("Managers")]
  public VersionManager VersionManagerInstance { get; set; }

  [Property, Title("IdleManager")]
  [Feature("Managers")]
  public IdleManager IdleManagerInstance { get; set; }

  [Property, Title("InvestmentManager")]
  [Feature("Managers")]
  public InvestmentManager InvestmentManagerInstance { get; set; }

  [Property, Title("DayNightManager")]
  [Feature("Managers")]
  public DayNightManager DayNightManagerInstance { get; set; }

  [Property, Title("GameManager")]
  [Feature("Managers")]
  public GameManager GameManagerInstance { get; set; }

  [Property, Title("TreeSkillPanel")]
  [Feature("General")]
  public TreeSkillPanel TreeSkillPanelInstance { get; set; }

  [Property]
  [Feature("General")]
  public int Dollars { get; set; } = 0;

  private bool isPanelOpened = false;

  private Dictionary<string, object> data = [];

  private bool isInitializedDay = false;
  private bool isDayEnd = false;

  private bool isGameWin = false;

  protected override int BuildHash() => System.HashCode.Combine(Dollars,
DayNightManagerInstance.CurrentTimeString, DayNightManagerInstance.Day, InvestmentManagerInstance.Total
, IdleManagerInstance.DollarsSpent, InvestmentManagerInstance.WalletPasive, InvestmentManagerInstance.Profit);

  protected override void OnAwake() {
    base.OnStart();

    data["Day"] = DayNightManagerInstance.Day;
    IdleManagerInstance.OnDeposit += RefreshDeposit;
    IdleManagerInstance.OnChange += Refresh;
    DayNightManagerInstance.OnStartDay += StartDay;
    DayNightManagerInstance.OnEndDay += EndDay;
    GameManagerInstance.OnWinGame += OnWinGame;
  }

  protected override void OnUpdate() {
    if (Input.Pressed("use")) {
      TogglePanel();
      return;
    }

    if (Input.EscapePressed) {
      isPanelOpened = false;
      StateHasChanged();
      TreeSkillPanelInstance.Close();
    }
  }

  protected override void OnDestroy() {
    base.OnDestroy();

    IdleManagerInstance.OnDeposit -= RefreshDeposit;
    IdleManagerInstance.OnChange -= Refresh;
    DayNightManagerInstance.OnStartDay -= StartDay;
    DayNightManagerInstance.OnEndDay -= EndDay;
    GameManagerInstance.OnWinGame -= OnWinGame;

  }

  private void OnWinGame() {
    isGameWin = GameManagerInstance.IsGameWin;
  }

  private void TogglePanel() {
    isPanelOpened = !isPanelOpened;
    StateHasChanged();

    Panel.Blur();

    if (isPanelOpened) {
      TreeSkillPanelInstance.Open();
      return;
    }

    TreeSkillPanelInstance.Close();
  }

  private string GetPercentage() {
    float Total = InvestmentManagerInstance.Total;
    float percentage = (Total / IdleManagerInstance.Goal) * 100;

    return Pixel.Inv(percentage);
  }

  private void StartDay() {
    isInitializedDay = true;
    StateHasChanged();

    _ = HideAafterDelay();
  }

  private void EndDay() {
    isDayEnd = true;
    StateHasChanged();
  }

  private void HandleNextDay() {
    isDayEnd = false;
    DayNightManagerInstance.NextDay();
    data["Day"] = DayNightManagerInstance.Day;
    StateHasChanged();
    StartDay();
  }

  private async Task HideAafterDelay() {
    await Task.DelaySeconds(ANIMATION_DURATION);
    isInitializedDay = false;
    StateHasChanged();
  }

  private void Refresh(int dollars, int amount) {
    Dollars = dollars;
    FloatingTextManager.Instance.Spawn($"+{amount}", 25f, 10f);
  }

  private void RefreshDeposit() {
    Dollars = 0;
  }

  private void HandleAgain() {
    GameManagerInstance.Restart();
  }
}
rakunsoftware.milaine / UI/PauseGamePanel/PauseGamePanel.razor
Game game
@using Milaine.Managers;
@using Milaine.Settings;
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@namespace Sandbox

<root>
  @if (PauseGameInstance.IsOpened) {
    <div class="pause-container">
      <header class="header">
        <DropDown Options=@ModeOptions Value=@SelectedMode ValueChanged=@OnOptionChanged />
      </header>
      <main>
        <div class="container">
          <button [email protected]>
            @TranslationsInstance.T("milaine.back")
          </button>
          <button onclick=@ExitGame>
            @TranslationsInstance.T("milaine.quit")
          </button>
        </div>

        <div class="credits">
          <p>Credits</p>
          <p>
            Computer Keyboard by Luke (https://sbox.game/luke/office_keyboard)
          </p>
          <p>
            Computer Monitor by Luke (https://sbox.game/luke/monitor_basic)
          </p>
          <p>
            Computer Mouse by Luke (https://sbox.game/luke/computer_mouse)
          </p>
          <p>
            Coffee_cup_01 by Small Box Studio (https://sbox.game/smallboxstudio/coffeecup01)
          </p>
          <p>
            French_fries_02 by Small Box Studio (https://sbox.game/smallboxstudio/frenchfries02)
          </p>
          <p>
            French_fries_02_empty by Small Box Studio (https://sbox.game/smallboxstudio/frenchfries02empty)
          </p>
          <p>
            Stir_fried_noodles_01 by Small Box Studio (https://sbox.game/smallboxstudio/stirfriednoodles01)
          </p>
          <p>
            Stir_fried_noodles_01_close by Small Box Studio (https://sbox.game/smallboxstudio/stirfriednoodles01close)
          </p>
        </div>>
      </main>
    </div>
    <div class="version-manager">
      <p>@("v" + VersionManagerInstance.Version.ToString())</p>
    </div>
  }

</root>

@code
{
  [Property, Title("Translations")]
  [Feature("Managers")]
  public Translations TranslationsInstance { get; set; }

  [Property, Title("VersionManager")]
  [Feature("Managers")]
  public VersionManager VersionManagerInstance { get; set; }

  [Property]
  [Feature("Settings")]
  public PauseGame PauseGameInstance { get; set; }

  public string SelectedMode { get; set; } = "en";

  public List<UI.Option> ModeOptions { get; set; } = [
    new Option{Title = "English", Value = "en"},
    new Option{Title = "Español", Value = "es"},
  ];

  protected override int BuildHash() => System.HashCode.Combine(PauseGameInstance.IsOpened, SelectedMode);

  protected override void OnStart() {
    base.OnStart();
    SelectedMode = TranslationsInstance.language;
  }

  private void ExitGame() {
    if (Application.IsStandalone) {
      Game.Close();
      return;
    }

    Game.Disconnect();
  }

  private void OnOptionChanged(object code) {
    SelectedMode = (string)code;
    TranslationsInstance.SetLanguage((string)code);
    StateHasChanged();
  }
}
rakunsoftware.milaine / Scripts/Managers/DialoguesManager.cs
Game game
namespace Milaine.Managers;


public sealed class DialoguesManager : Component {
  [Property, Title("Dialogues View")]
  public PanelComponent DialoguesView { get; set; }

  private List<Step> steps = [];

  private class Step { }

  protected override void OnStart() {
    if (!DialoguesView.IsValid()) {
      Log.Warning("Need Instances of [DialoguesView]");
    }
  }
}
rakunsoftware.milaine / Scripts/TreeSkills/SkillNodeData.cs
Game game
namespace Milaine.TreeSkills;

public enum SkillCategory {
  Dollars,
  Wallet,
  Investment,
  Dividends,
  WalletPlus,
  DollarAutomatic
}

public class SkillNodeData {
  public string Id { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }
  public string KeyDescription { get; set; }
  public int Cost { get; set; }
  public SkillCategory Category { get; set; }
  public float Point { get; set; }

  public int Row { get; set; }
  public int Column { get; set; }

  public string Icon { get; set; } = "🌕";

  public bool IsRoot { get; set; }
}
rakunsoftware.milaine / Scripts/Constants/VersionConstants.cs
Game game
namespace Milaine.Constants;

public class VersionConstants {
  public const int MAYOR = 0;
  public const int MINOR = 9;
  public const int PATCH = 1;
}
rakunsoftware.milaine / Scripts/Managers/InvestmentManager.cs
Game game
using System;
using Milaine.Interfaces;

namespace Milaine.Managers;

public struct Portfolio(int wallet = 0, float investment = 0, float profit = 0, int shares = 0) {
  public int wallet = wallet;
  public float investment = investment;
  public float profit = profit;
  public int shares = shares;
}

public sealed class InvestmentManager : Component, IManager {
  public const float DEFAULT_PERFORMANCE = 1.0f;

  [Property, Title("DayNightManager")]
  [Feature("Managers")]
  public DayNightManager DayNightManagerInstance { get; set; }

  [Property]
  [Feature("General")]
  public bool IsDayEnded { get; set; } = false;

  [Property]
  [Feature("General"), Group("Digital")]
  public int Wallet { get; set; } = 0;

  [Property]
  [Feature("General"), Group("Digital")]
  public float Investment { get; set; } = 0;

  [Property]
  [Feature("General"), Group("Digital")]
  public float Profit { get; set; } = 0;

  [Property]
  [Feature("General"), Group("Digital")]
  public int Shares { get; set; } = 0;

  public Action<Portfolio> OnChange { get; set; }

  private float performance = DEFAULT_PERFORMANCE;
  private float acc = 0f;
  private float multiplierDeposit = 1.0f;
  private bool isAvailablePerformanceWallet = false;
  private int performanceWallet = (int)DEFAULT_PERFORMANCE;

  private float accDividends = 0f;
  private bool isActivatedDividends = false;
  private float multiplierDividends = 0.0f;

  private int walletPasive = 0;

  public float Total {
    get => Wallet + Investment;
  }


  public int WalletPasive {
    get => walletPasive;
  }

  protected override void OnStart() {
    DayNightManagerInstance.OnStartDay += DayStartSubscription;
    DayNightManagerInstance.OnEndDay += DayNightSubscription;
  }

  protected override void OnDestroy() {
    DayNightManagerInstance.OnStartDay -= DayStartSubscription;
    DayNightManagerInstance.OnEndDay -= DayNightSubscription;
  }

  protected override void OnUpdate() {
    if (IsDayEnded) {
      return;
    }

    acc += Time.Delta;

    if (acc >= 1.0f) {
      if (Investment != 0f) {
        Profit += performance;
        Investment += performance;
      }

      if (isAvailablePerformanceWallet) {
        Wallet += performanceWallet;
        walletPasive += performanceWallet;
      }


      acc = 0;
    }

    accDividends += Time.Delta;

    if (accDividends >= 5.0f && isActivatedDividends) {
      Wallet += (Investment * multiplierDividends).CeilToInt();
      accDividends = 0;
    }
  }

  public void Deposit(int dollars) {
    Wallet += (multiplierDeposit * dollars).CeilToInt();
    OnChange?.Invoke(new Portfolio { wallet = Wallet, investment = Investment, profit = Profit, shares = Shares });
  }

  public void Invest() {
    Investment += Wallet;
    Wallet = 0;
    OnChange?.Invoke(new Portfolio { wallet = Wallet, investment = Investment, profit = Profit, shares = Shares });
  }

  private void DayNightSubscription() {
    IsDayEnded = true;
  }

  private void DayStartSubscription() {
    IsDayEnded = false;
    Profit = 0;
    walletPasive = 0;
  }

  public void ImprovePerformance(float amount) {
    performance += amount;
  }

  public void ImproveWallet(float amount) {
    ImproveWallet((int)amount);
  }

  private void ImproveWallet(int amount) {
    if (!isAvailablePerformanceWallet) {
      isAvailablePerformanceWallet = true;
    }

    performanceWallet = amount;
  }

  public void ImproveDeposit(float amount) {
    multiplierDeposit = amount;
  }

  public void ImproveDividends(float amount) {
    if (!isActivatedDividends) {
      isActivatedDividends = true;
    }

    multiplierDividends = amount;
  }

  public void Restart() {
    // reset all stats (wallet, profit, investment, days)
    performance = DEFAULT_PERFORMANCE;
    multiplierDeposit = 1.0f;
    isActivatedDividends = false;
    multiplierDividends = 0.0f;
    isAvailablePerformanceWallet = false;
    performanceWallet = (int)DEFAULT_PERFORMANCE;
    walletPasive = 0;
    Wallet = 0;
    Investment = 0f;
    Profit = 0;
    Shares = 0;
  }
}
rakunsoftware.milaine / Scripts/Settings/Translation.cs
Game game
using Milaine.Utils;

namespace Milaine.Settings;

public sealed class Translations : Component {
  [Property, Title("Configuration")]
  public Configuration ConfigurationInstance { get; set; }

  private Localization localization;

  public string language = "en";

  protected override void OnAwake() {
    localization = new();
    language = ConfigurationInstance.Language;
    localization.SetLanguage(ConfigurationInstance.Language);
  }

  public void SetLanguage(string language) {
    localization.SetLanguage(language);

    this.language = language;

    ConfigurationInstance.Language = language;
    ConfigurationInstance.SaveConfig();
  }

  public string T(string token, Dictionary<string, object> data = null) => localization.T(token, data);
}
rakunsoftware.milaine / UI/InvestmentPanel/InvestmentPanel.razor
Game game
@using System.Text;
@using Milaine.Managers;
@using Milaine.Settings;
@using Milaine.Utils;
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@namespace Sandbox

<root>
  <header>
    <div class="container-title">
      <Image src="resources/hexagon.png" class="image" style="width: 20px; height: 20px;" />
      <h1 class="title">SHARES // WORKS</h1>
    </div>
    <div class="content" style="pointer-events: @(MouseManager.State == StateMouse.Busy ? "none" : "all");">
      <Image src="resources/wallet-minimal.png" class="image" style="width: 20px; height: 20px;" />
      <p class="text">[email protected](InvestmentManagerInstance.Wallet)</p>
    </div>
  </header>
  <div class="container">
    <section class="card" style="pointer-events: @(MouseManager.State == StateMouse.Busy ? "none" : "all");">
      <div class="card-header">
        <div class="card-header-wrapper">
          @if (InvestmentManagerInstance.Profit == 0) {
            <Image src="resources/dot.png" />
          }
          @if (InvestmentManagerInstance.Profit > 0) {
            <Image src="resources/trending-up.png" />
          }
          @if (InvestmentManagerInstance.Profit < 0) {
            <Image src="resources/trending-down.png" />
          }
          <p class="card-title">
            @* #milaine.profit.total *@
            @TranslationsInstance.T("milaine.profit.total")
          </p>
        </div>
        <div class=@ClassName()>
          @if (InvestmentManagerInstance.Profit == 0) {
            <p>
              @* #milaine.critical.standard-profit *@
              @TranslationsInstance.T("milaine.critical.standard-profit")
            </p>
          }
          @if (InvestmentManagerInstance.Profit < 0) {
            <p>
              @* #milaine.critical.bad-profit *@
              @TranslationsInstance.T("milaine.critical.bad-profit")
            </p>
          }
          @if (InvestmentManagerInstance.Profit > 0) {
            <p>
              @* #milaine.critical.profit *@
              @TranslationsInstance.T("milaine.critical.profit")
            </p>
          }
        </div>
      </div>
      <div class="card-body">
        <div class="investment-container">
          <div class="investment-content">
            <p
              class="investment-text @(InvestmentManagerInstance.Profit == 0 ? "normal" : InvestmentManagerInstance.Profit < 0 ? "bad" : "good")">
              @BuildInvestment(InvestmentManagerInstance.Investment)
            </p>

            @if (InvestmentManagerInstance.Profit > 0) {
              <p class="shares">[email protected]</p>
            }
          </div>
          <div class="action">
            <button class="btn btn-primary" onclick=@HandleClickInvestment>
              @* #milaine.invest *@
              @TranslationsInstance.T("milaine.invest")
            </button>
            <button class="btn btn-secondary" onclick=@HandleClickDeposit>
              @* #milaine.deposit *@
              @TranslationsInstance.T("milaine.deposit")
            </button>
          </div>
        </div>
      </div>
    </section>
  </div>
</root>

@code
{
  [Property, Title("InvestmentManager")]
  [Feature("Managers")]
  public InvestmentManager InvestmentManagerInstance { get; set; }

  [Property, Title("IdleManager")]
  [Feature("Managers")]
  public IdleManager IdleManagerInstance { get; set; }

  [Property, Title("Translations")]
  [Feature("Managers")]
  public Translations TranslationsInstance { get; set; }

  public Dictionary<string, object> Data = [];

  protected override int BuildHash() => System.HashCode.Combine(Data, InvestmentManagerInstance.Wallet,
InvestmentManagerInstance.Profit, TranslationsInstance.language, MouseManager.State);

  protected override void OnStart() {
    if (!InvestmentManagerInstance.IsValid()) {
      Log.Warning("Need Instance the InvestmentManager into [InvestmentView]");
      return;
    }

    Refresh();
  }

  protected override void OnUpdate() {
    base.OnUpdate();

    if (Input.EscapePressed) {
      StateHasChanged();
    }
  }

  public string ClassName() => InvestmentManagerInstance.Profit == 0 ? "tag standard" : InvestmentManagerInstance.Profit
< 0 ? "tag low" : "tag";

  private void HandleClickInvestment() {
    InvestmentManagerInstance.Invest();
    Refresh();
  }

  private void HandleClickDeposit() {
    InvestmentManagerInstance.Deposit(IdleManagerInstance.Dollars);
    IdleManagerInstance.Deposit();
    Refresh();
  }

  private string BuildInvestment(float investment) {
    StringBuilder sb = new();
    float profit = InvestmentManagerInstance.Profit;

    if (profit < 0) {
      sb.Append("- $");
    }

    if (profit > 0) {
      sb.Append("+ $");
    }

    sb.Append(Formatter.ToDisplay(investment));

    return sb.ToString();
  }

  private void Refresh() {
    Data["WalletValue"] = Formatter.ToDisplayShort(InvestmentManagerInstance.Wallet);
    Data["InvestmentValue"] = Formatter.ToDisplay(InvestmentManagerInstance.Investment);
    Data["ProfitValue"] = Formatter.ToDisplay(InvestmentManagerInstance.Profit);
    Data["SharesValue"] = InvestmentManagerInstance.Shares;
  }
}
rakunsoftware.milaine / ui/hud/hud.razor.scss
Game game
Hud {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  flex-direction: column;
  font-weight: bold;
  border-radius: 20px;
  color: #fff;
  font-size: 25px;

  .header {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 50px;
    padding: 20px;

    .day-manager h2 {
      text-align: center;
      font-size: 30px;
      font-family: "Space Grotesk";
    }

    .clock {
      background-color: rgba(0, 0, 0, 0.5);
      color: #fff;
      display: flex;
      justify-content: center;
      align-items: center;

      p {
        text-align: center;
        font-size: 28px;
        font-family: "JetBrains Mono";
      }
    }
  }

  .container {
    position: absolute;
    bottom: 50px;
    right: 50px;
    font-family: "JetBrains Mono";

    .content {
      padding: 10px 20px;
      display: flex;
      background-color: rgba(0, 0, 0, 0.5);
      border: 1px solid rgba(39, 42, 46, 0.8);
      border-radius: 5px;
      justify-content: center;
      align-items: center;
      gap: 10px;

      .image {
        object-fit: cover;
      }

      .headline {
        color: #00ff66;
      }
    }
  }

  .slot {
    position: absolute;
    bottom: 50px;
    right: 300px;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    gap: 10px;
    border-radius: 5px;
    padding: 10px 15px;
    background-color: rgba(0, 0, 0, 0.5);
    transition: all 300ms ease;

    &:hover {
      background-color: rgba(0, 0, 0, 0.8);
      transition: all 300ms ease;
      sound-in: ui.button.over;
    }

    .kbd {
      font-family: "JetBrains Mono";
      font-size: 30px;
    }

    .title {
      font-family: "Space Grotesk";
      font-size: 21px;
    }
  }

  .progress-end-game {
    position: absolute;
    width: 70%;
    bottom: 50px;
    left: 50px;

    .progress-bar {
      width: 100%;
      height: 40px;
      padding: 4px;
      border-radius: 6px;
      overflow: hidden;
      background-color: rgba(0, 0, 0, 0.7);

      .bar {
        height: 100%;
        background-image: linear-gradient(to right, #00e55b, #00ff66, #00e3fd);
        border-radius: 2px;
      }

      p {
        position: absolute;
        font-family: "JetBrains Mono";
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
    }
  }

  .day-container {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    justify-content: center;
    align-items: center;
    background-color: rgb(7, 9, 11);
    opacity: 0;
    pointer-events: none;

    z-index: 999;

    animation-name: morning;
    animation-duration: 5s;
    animation-timing-function: ease;
    animation-fill-mode: forwards;

    .heading-current-day {
      font-size: 40px;
      text-align: center;
      font-weight: 700;
      font-family: "Space Grotesk";
      letter-spacing: 2px;
    }

    &.night {
      flex-direction: column;

      animation-name: night;
      animation-duration: 2s;

      button {
        pointer-events: all;
      }
    }

    .summary-container {
      width: 35%;
      padding: 24px;
      border: 1px solid #1e2936;
      flex-direction: column;
      background-color: rgb(18 23 30 / 0.95);
      border-radius: 12px;
      overflow: hidden;
      box-shadow:
        0 0 25px -5px rgba(0, 255, 102, 0.25),
        inset 0 0 15px -3px rgba(0, 255, 102, 0.08);

      .summary-header {
        margin-bottom: 20px;
        flex-direction: column;

        .summary-title {
          display: flex;
          align-items: center;
          justify-content: flex-start;
          gap: 10px;
          padding-bottom: 16px;

          .circle {
            width: 16px;
            height: 16px;
            border-radius: 50%;
            background-color: #00ff66;
          }

          h2 {
            font-family: "Space Grotesk";
            font-size: 40px;
          }
        }
      }

      .row {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 20px;
        gap: 20px;
      }

      .form-control {
        padding: 16px;
        background-color: rgb(13 17 22 / 0.9);
        border: 1px solid rgb(30 41 54 / 0.7);
        border-radius: 8px;
        flex-direction: column;
        margin-bottom: 20px;
        gap: 16px;
        pointer-events: all;

        transition: all 500ms ease;

        &.nth {
          flex: 1;

          h3 {
            font-size: 23px;
          }
        }

        h3 {
          font-size: 30px;
          color: #94a3b8;
        }

        .form-control-header {
          justify-content: space-between;
          align-items: center;
        }

        &:hover {
          transition: all 500ms ease;

          &.mgreen {
            border-color: #00ff66;
          }

          &.mblue {
            border-color: #00e3fd;
          }

          &.mred {
            border-color: #ff3366;
          }
        }
      }
    }

    .separator {
      width: 100%;
      height: 1px;
      background-color: rgb(30 41 54 / 0.8);
    }

    .normal-font {
      font-family: "Space Grotesk";
    }

    .number {
      font-family: "JetBrains Mono";
    }

    .btn-next-action {
      flex: 1;
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
      padding: 30px;
      background-color: rgb(13 17 22 / 0.9);
      border: 1px solid #1e2936;
      border-radius: 16px;
      margin: 20px 0;

      pointer-events: all;
    }

    .circle-base {
      width: 8px;
      height: 8px;
      border-radius: 50%;
    }

    .circle-green {
      background-color: #00ff66;
    }

    .circle-blue {
      background-color: #00e3fd;
    }

    .circle-red {
      background-color: #ff3366;
    }
  }

  .version-manager {
    position: absolute;
    top: 20px;
    left: 20px;
    background-color: rgba(0, 0, 0, 0.5);

    p {
      color: white;
      font-family: "JetBrains Mono";
      font-size: 26px;
    }
  }
}

@keyframes morning {
  0% {
    opacity: 0;
  }

  2% {
    opacity: 1;
  }

  60% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

@keyframes night {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}
rakunsoftware.milaine / Assembly.cs
Game game
global using Sandbox;
global using System.Collections.Generic;
global using System.Linq;
rakunsoftware.milaine / Scripts/Utils/Pixel.cs
Game game
using System.Globalization;

namespace Milaine.Utils;

public static class Pixel {
  public static string Inv(float numb) => numb.ToString(CultureInfo.InvariantCulture);
}
rakunsoftware.milaine / Scripts/Utils/Formatter.cs
Game game
using System;
using System.Globalization;

namespace Milaine.Utils;

public static class Formatter {
  private static readonly string[] Suffixes = ["", "k", "M", "B", "T", "Qa", "Qi"];

  /// <summary>
  /// format float numbers from 1000 to 1.000
  /// </summary>
  /// <param name="val"></param>
  /// <returns></returns>
  public static string ToDisplay(float val) {
    string native = val.ToString("#,##0", CultureInfo.InvariantCulture);
    string display = native.Replace(',', '.');

    return display;
  }

  /// <summary>
  /// format from 1000 to 1.0K
  /// </summary>
  /// <param name="val"></param>
  /// <returns></returns>
  public static string ToDisplayShort(float val) {
    double absVal = Math.Abs((double)val);

    if (absVal < 1000d) {
      return Math.Round(val).ToString(CultureInfo.InvariantCulture);
    }

    int magnitude = (int)Math.Log(absVal, 1000d);
    magnitude = Math.Min(magnitude, Suffixes.Length - 1);

    double scaled = val / Math.Pow(1000d, magnitude);

    if (Math.Round(scaled, 1) >= 1000d && magnitude < Suffixes.Length - 1) {
      magnitude++;
      scaled = val / Math.Pow(1000d, magnitude);
    }

    string number = scaled.ToString("0.0", CultureInfo.InvariantCulture);

    return $"{number}{Suffixes[magnitude]}";
  }
}
Debug: View Raw JSON Response
{
    "TotalCount": 38,
    "Files": [
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Managers/GameManager.cs",
            "FileName": "GameManager.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "using System;\r\nusing Milaine.TreeSkills;\r\n\r\nnamespace Milaine.Managers;\r\n\r\npublic sealed class GameManager : Component {\r\n  [Property, Title(\"IdleManager\")]\r\n  [Feature(\"General\")]\r\n  public IdleManager IdleManagerInstance { get; set; }\r\n\r\n  [Property, Title(\"InvestmentManager\")]\r\n  [Feature(\"General\")]\r\n  public InvestmentManager InvestmentManagerInstance { get; set; }\r\n\r\n  [Property, Title(\"SkillTreeBootstrap\")]\r\n  [Feature(\"General\")]\r\n  public SkillTreeBootstrap SkillTreeBootstrapInstance { get; set; }\r\n\r\n  [Property, Title(\"DayNightManager\")]\r\n  [Feature(\"General\")]\r\n  public DayNightManager DayNightManagerInstance { get; set; }\r\n\r\n  public Action OnLooseGame { get; set; }\r\n  public Action OnWinGame { get; set; }\r\n\r\n  private List<SkillNodeData> skillsUsed = [];\r\n  private int maxSkillPoints = 0;\r\n  private int skillPoints = 0;\r\n  private bool isPlaying = true;\r\n  private bool isGameWin = false;\r\n\r\n  public bool IsGameWin {\r\n    get => isGameWin;\r\n  }\r\n\r\n  protected override void OnAwake() {\r\n    TreeSkillState.Instance.OnUnlocked += OnUnlocked;\r\n    TreeSkillState.Instance.SpendPoint += OnSpendPoint;\r\n    TreeSkillState.Instance.GetSkillPoints = GetSkillPoints;\r\n    DayNightManagerInstance.OnEndDay += OnEndDay;\r\n    InvestmentManagerInstance.OnChange += OnInvestmentManagerChange;\r\n  }\r\n\r\n  protected override void OnDestroy() {\r\n    TreeSkillState.Instance.OnUnlocked -= OnUnlocked;\r\n    TreeSkillState.Instance.SpendPoint -= OnSpendPoint;\r\n    DayNightManagerInstance.OnEndDay -= OnEndDay;\r\n    InvestmentManagerInstance.OnChange -= OnInvestmentManagerChange;\r\n  }\r\n\r\n  private void OnEndDay() {\r\n    if (DayNightManagerInstance.Day < 5) {\r\n      return;\r\n    }\r\n\r\n    isPlaying = false;\r\n    isGameWin = false;\r\n    OnLooseGame?.Invoke();\r\n  }\r\n\r\n  private void OnInvestmentManagerChange(Portfolio portfolio) {\r\n    if (!isPlaying) {\r\n      return;\r\n    }\r\n\r\n    int total = (int)portfolio.investment;\r\n    int goal = IdleManagerInstance.Goal;\r\n\r\n    if (total >= goal) {\r\n      isPlaying = false;\r\n      isGameWin = true;\r\n      DayNightManagerInstance.ResetManager();\r\n      OnWinGame?.Invoke();\r\n    }\r\n  }\r\n\r\n  private void OnUnlocked(SkillNodeData node) {\r\n    if (skillsUsed.Contains(node)) {\r\n      return;\r\n    }\r\n\r\n    skillsUsed.Add(node);\r\n\r\n    switch (node.Category) {\r\n      case SkillCategory.Dollars:\r\n        IdleManagerInstance.ImprovePoint(node.Point);\r\n        break;\r\n      case SkillCategory.DollarAutomatic:\r\n        IdleManagerInstance.ImprovePasiveDollar(node.Point);\r\n        break;\r\n      case SkillCategory.Wallet:\r\n        InvestmentManagerInstance.ImproveWallet(node.Point);\r\n        break;\r\n      case SkillCategory.Investment:\r\n        InvestmentManagerInstance.ImprovePerformance(node.Point);\r\n        break;\r\n      case SkillCategory.Dividends:\r\n        InvestmentManagerInstance.ImproveDividends(node.Point);\r\n        break;\r\n      case SkillCategory.WalletPlus:\r\n        InvestmentManagerInstance.ImproveDeposit(node.Point);\r\n        break;\r\n    }\r\n  }\r\n\r\n  private int GetSkillPoints() => skillPoints;\r\n\r\n  private void OnSpendPoint() {\r\n    skillPoints--;\r\n  }\r\n\r\n  public void Restart() {\r\n    DayNightManagerInstance.Restart();\r\n    TreeSkillState.Instance.Restart();\r\n    skillsUsed = [];\r\n    maxSkillPoints += 1;\r\n    skillPoints += maxSkillPoints;\r\n\r\n    IdleManagerInstance.Restart();\r\n    InvestmentManagerInstance.Restart();\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Managers/MouseManager.cs",
            "FileName": "MouseManager.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "namespace Milaine.Managers;\r\n\r\npublic enum StateMouse {\r\n  Relased,\r\n  Busy\r\n}\r\n\r\npublic static class MouseManager {\r\n  public static StateMouse State { get; set; } = StateMouse.Relased;\r\n\r\n  public static void ShowMouse() {\r\n    Mouse.Visibility = MouseVisibility.Visible;\r\n  }\r\n\r\n  public static void HideMouse() {\r\n    Mouse.Visibility = MouseVisibility.Hidden;\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Managers/DayNightManager.cs",
            "FileName": "DayNightManager.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "using System;\r\nusing Milaine.Interfaces;\r\n\r\nnamespace Milaine.Managers;\r\n\r\npublic sealed class DayNightManager : Component, IManager {\r\n  // 60 -> seconds\r\n  private const int MINUTE = 60;\r\n  // 5 mins\r\n  private const int MAX_TIME = 5 * MINUTE;\r\n  public const int MAX_DAYS = 5;\r\n\r\n  [Property]\r\n  public float DayDuration { get; set; } = MAX_TIME;\r\n\r\n  [Property]\r\n  public int Day { get; set; } = 1;\r\n\r\n  // hour in 24h\r\n  private readonly float startHour = 8f;\r\n  private readonly float endHour = 18f;\r\n\r\n  private bool isDayActive = false;\r\n  private TimeUntil timeUntilNight;\r\n\r\n  public string CurrentTimeString { get; private set; } = \"8:00 AM\";\r\n\r\n  public Action OnStartDay;\r\n  public Action OnEndDay;\r\n\r\n  protected override void OnStart() {\r\n    StartDay();\r\n  }\r\n\r\n  protected override void OnUpdate() {\r\n    if (!isDayActive) {\r\n      return;\r\n    }\r\n\r\n    float elapsedSeconds = DayDuration - timeUntilNight;\r\n    float progress = MathX.Clamp(elapsedSeconds / DayDuration, 0f, 1f);\r\n    float totalVirtualHours = endHour - startHour;\r\n    float currentVirtualHour = startHour + (progress * totalVirtualHours);\r\n\r\n    int hours = (int)MathF.Floor(currentVirtualHour);\r\n    int minutes = (int)MathF.Floor((currentVirtualHour - hours) * 60f);\r\n\r\n    string amPm = hours >= 12 ? \"PM\" : \"AM\";\r\n    int displayHour = hours % 12;\r\n\r\n    if (displayHour == 0) {\r\n      displayHour = 12;\r\n    }\r\n\r\n    CurrentTimeString = $\"{displayHour:D2}:{minutes:D2} {amPm}\";\r\n\r\n    if (timeUntilNight) {\r\n      EndDay();\r\n    }\r\n  }\r\n\r\n  private void StartDay() {\r\n    if (isDayActive) {\r\n      return;\r\n    }\r\n\r\n    timeUntilNight = DayDuration;\r\n    isDayActive = true;\r\n\r\n    OnStartDay?.Invoke();\r\n  }\r\n\r\n  private void EndDay() {\r\n    ResetManager(deep: false);\r\n    OnEndDay?.Invoke();\r\n  }\r\n\r\n  public void ResetManager(bool deep = false) {\r\n    if (deep) {\r\n      CurrentTimeString = \"8:00 AM\";\r\n    }\r\n\r\n    isDayActive = false;\r\n  }\r\n\r\n  public void NextDay() {\r\n    if (Day >= MAX_DAYS) {\r\n      return;\r\n    }\r\n\r\n    Day += 1;\r\n    StartDay();\r\n  }\r\n\r\n  public void Restart() {\r\n    Day = 1;\r\n    StartDay();\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Room/ClickableButton.cs",
            "FileName": "ClickableButton.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "using System;\r\nusing Milaine.Managers;\r\n\r\nnamespace Milaine.Room;\r\n\r\npublic sealed class ClickableButton : Component {\r\n  [Property, Group(\"References\")]\r\n  public SkinnedModelRenderer Model { get; set; }\r\n\r\n  [Property, Group(\"Animation\"), Title(\"Sequence Name\")]\r\n  public string PressSequence { get; set; } = \"press\";\r\n\r\n  [Property, Group(\"Animation\")]\r\n  public bool UsesAnimGraph { get; set; } = false;\r\n\r\n  [Property, Group(\"Interaction\")]\r\n  public float MaxClickDistance { get; set; } = 1000f;\r\n\r\n  [Property, Group(\"Squish (Scale Z)\"), Range(0.1f, 1f)]\r\n  public float PressedScale { get; set; } = 0.8f;\r\n\r\n  [Property, Group(\"Squish (Scale Z)\"), Range(1f, 30f)]\r\n  public float ScaleSpeed { get; set; } = 14f;\r\n\r\n  public Action OnPressed { get; set; }\r\n\r\n  private bool isHeld;\r\n  private Vector3 originalScale;\r\n  private float currentScaleFactor = 1f;\r\n\r\n  protected override void OnStart() {\r\n    if (!Model.IsValid()) {\r\n      Model = Components.Get<SkinnedModelRenderer>();\r\n    }\r\n\r\n    originalScale = LocalScale;\r\n  }\r\n\r\n  protected override void OnUpdate() {\r\n    if (MouseManager.State == StateMouse.Busy) {\r\n      return;\r\n    }\r\n\r\n    var camera = Scene.Camera;\r\n\r\n    if (!camera.IsValid()) {\r\n      return;\r\n    }\r\n\r\n    var ray = camera.ScreenPixelToRay(Mouse.Position);\r\n    var trace = Scene.Trace.Ray(ray, MaxClickDistance).Run();\r\n    bool isHoveredNow = trace.Hit && trace.GameObject == GameObject;\r\n\r\n    if ((Input.Pressed(\"attack1\") || Input.Pressed(\"attack2\")) && isHoveredNow) {\r\n      Press();\r\n      isHeld = true;\r\n    }\r\n\r\n    if (Input.Released(\"attack1\") || Input.Released(\"attack2\")) {\r\n      isHeld = false;\r\n    }\r\n\r\n    float targetFactor = isHeld ? PressedScale : 1f;\r\n    currentScaleFactor = MathX.Lerp(currentScaleFactor, targetFactor, Time.Delta * ScaleSpeed);\r\n\r\n    LocalScale = new Vector3(originalScale.x, originalScale.y, originalScale.z * currentScaleFactor);\r\n  }\r\n\r\n  public void Press() {\r\n    PlayPressAnimation();\r\n    Sound.Play(\"sounds/sound_key_down.sound\");\r\n    OnPressed?.Invoke();\r\n  }\r\n\r\n  private void PlayPressAnimation() {\r\n    if (!Model.IsValid()) {\r\n      return;\r\n    }\r\n\r\n    if (UsesAnimGraph) {\r\n      Model.Set(PressSequence, true);\r\n    } else {\r\n      Model.SceneModel.UseAnimGraph = false;\r\n      Model.SceneModel.CurrentSequence.Name = PressSequence;\r\n    }\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Room/RoomManager.cs",
            "FileName": "RoomManager.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "namespace Milaine.Room;\r\n\r\npublic sealed class RoomManager : Component {\r\n  [Property]\r\n  public List<GameObject> Models { get; set; } = [];\r\n\r\n  private List<GameObject> ChairChildren = [];\r\n\r\n  protected override void OnAwake() {\r\n    if (Models.Count == 0) {\r\n      Log.Warning(\"Models list is empty\");\r\n      return;\r\n    }\r\n\r\n    foreach (GameObject gameObject in Models) {\r\n      if (!gameObject.IsValid()) {\r\n        continue;\r\n      }\r\n\r\n      Prop prop = gameObject.GetComponent<Prop>();\r\n\r\n      if (!prop.IsValid()) {\r\n        continue;\r\n      }\r\n\r\n      prop.IsStatic = true;\r\n\r\n      if (gameObject.Name == \"office_chair\") {\r\n        gameObject.GetComponent<ModelRenderer>().Destroy();\r\n        gameObject.GetComponent<ModelPhysics>().Destroy();\r\n\r\n        foreach (GameObject obj in gameObject.Children) {\r\n          ChairChildren.Add(obj);\r\n        }\r\n      }\r\n    }\r\n\r\n  }\r\n\r\n  protected override void OnUpdate() {\r\n    if (ChairChildren.Count == 0) {\r\n      return;\r\n    }\r\n\r\n    foreach (GameObject gameObject in ChairChildren) {\r\n      gameObject.Destroy();\r\n    }\r\n\r\n    ChairChildren = [];\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Settings/Configuration.cs",
            "FileName": "Configuration.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "using System;\r\n\r\nnamespace Milaine.Settings;\r\n\r\npublic class ConfigurationData {\r\n  public string Language { get; set; } = \"en\";\r\n}\r\n\r\npublic sealed class Configuration : Component {\r\n  private readonly string filename = \"settings.cfg\";\r\n\r\n  [Property]\r\n  public string Language { get; set; } = \"en\";\r\n\r\n  protected override void OnAwake() {\r\n    if (!FileSystem.Data.FileExists(filename)) {\r\n      SaveConfig();\r\n\r\n      return;\r\n    }\r\n\r\n    LoadConfig();\r\n  }\r\n\r\n  public void LoadConfig() {\r\n    var config = FileSystem.Data.ReadJson<ConfigurationData>(filename);\r\n    Language = config.Language;\r\n  }\r\n\r\n  public void SaveConfig() {\r\n    try {\r\n      var config = new ConfigurationData { Language = Language };\r\n      FileSystem.Data.WriteJson(filename, config);\r\n    }\r\n    catch (Exception ex) {\r\n      Log.Warning($\"Error to try create configuration file: {ex.Message}\");\r\n    }\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "UI/FloatingTextManager/FloatingTextManager.razor",
            "FileName": "FloatingTextManager.razor",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "@using Sandbox;\r\n@using Sandbox.UI;\r\n@namespace Milaine.UI\r\n@inherits Panel\r\n\r\n<root></root>\r\n\r\n@code {\r\n  public static FloatingTextManager Instance { get; set; }\r\n\r\n  public FloatingTextManager()\r\n  {\r\n    Instance = this;\r\n  }\r\n\r\n  public override void OnDeleted()\r\n  {\r\n    base.OnDeleted();\r\n\r\n    if (Instance == this)\r\n    {\r\n      Instance = null;\r\n    }\r\n  }\r\n\r\n  public void Spawn(string text, float screenX, float screenY)\r\n  {\r\n    var floatingText = AddChild<FloatingText>();\r\n    floatingText.Text = text;\r\n    floatingText.SpawnX = screenX;\r\n    floatingText.SpawnY = screenY;\r\n  }\r\n}\r\n\r\n<style>\r\n  FloatingTextManager {\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    pointer-events: none;\r\n  }\r\n</style>\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Utils/Outliner.cs",
            "FileName": "Outliner.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "namespace Milaine.Utils;\r\n\r\npublic sealed class Outliner : Component {\r\n  [Property, Group(\"Interaction\")]\r\n  public float MaxClickDistance { get; set; } = 1000f;\r\n\r\n  [Property, Group(\"Outline\"), Title(\"Color Hover\")]\r\n  public Color HoverOutlineColor { get; set; } = Color.White;\r\n\r\n  [Property, Group(\"Outline\"), Range(0.1f, 10f)]\r\n  public float OutlineWidth { get; set; } = 0.5f;\r\n\r\n  private HighlightOutline outline;\r\n\r\n  protected override void OnAwake() {\r\n  }\r\n\r\n  protected override void OnStart() {\r\n    outline = GameObject.GetOrAddComponent<HighlightOutline>();\r\n    outline.Color = Color.Transparent;\r\n    outline.Width = OutlineWidth;\r\n  }\r\n\r\n  protected override void OnUpdate() {\r\n    var camera = Scene.Camera;\r\n\r\n    if (!camera.IsValid()) {\r\n      return;\r\n    }\r\n\r\n    var ray = camera.ScreenPixelToRay(Mouse.Position);\r\n    var trace = Scene.Trace.Ray(ray, MaxClickDistance).Run();\r\n\r\n    bool isHoveredNow = trace.Hit && trace.GameObject == GameObject;\r\n\r\n    if (outline.IsValid()) {\r\n      outline.Color = isHoveredNow ? HoverOutlineColor : Color.Transparent;\r\n    }\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "UI/Hud/Hud.razor",
            "FileName": "Hud.razor",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "@using System.Threading.Tasks;\r\n@using Milaine.Managers;\r\n@using Milaine.Settings;\r\n@using Milaine.UI;\r\n@using Milaine.Utils;\r\n@using Sandbox;\r\n@using Sandbox.UI;\r\n@inherits PanelComponent\r\n@namespace Sandbox\r\n\r\n<root>\r\n  <header class=\"header\">\r\n    <section class=\"day-manager\">\r\n      <h2>\r\n        @TranslationsInstance.T(\"milaine.days\", data)\r\n        @* @Language.GetPhrase(\"milaine.days\", data) *@\r\n      </h2>\r\n    </section>\r\n    <section class=\"clock\">\r\n      <p>@DayNightManagerInstance.CurrentTimeString</p>\r\n    </section>\r\n  </header>\r\n  <section class=\"progress-end-game\">\r\n    <div class=\"progress-bar\">\r\n      <div class=\"bar\" style=\"width: @(GetPercentage())%;\" />\r\n      <p>@Formatter.ToDisplay(InvestmentManagerInstance.Total) / @Formatter.ToDisplay(IdleManagerInstance.Goal)</p>\r\n    </div>\r\n  </section>\r\n  <button class=\"slot\" style=\"pointer-events: @(!isPanelOpened ? \"all\" : \"none\");\" onclick=@TogglePanel>\r\n    <p class=\"kbd\">E</p>\r\n    <p class=\"title\">\r\n      @TranslationsInstance.T(\"milaine.tree-skills\")\r\n      @* #milaine.tree-skills *@\r\n    </p>\r\n  </button>\r\n  <div class=\"container\">\r\n    <section class=\"content\">\r\n      <Image src=\"resources/wallet-minimal.png\" class=\"image\" style=\"width: 40px; height: 40px;\" />\r\n      <p class=\"headline\">[email protected](Dollars)</p>\r\n      <FloatingTextManager />\r\n    </section>\r\n  </div>\r\n  @if (isInitializedDay) {\r\n    <div class=\"day-container\">\r\n      <h2 class=\"heading-current-day\">\r\n        @* @Language.GetPhrase(\"milaine.days\", data) *@\r\n        @TranslationsInstance.T(\"milaine.days\", data)\r\n      </h2>\r\n    </div>\r\n  }\r\n  @if (isGameWin) {\r\n    <div\r\n      style=\"background-color: black; position: absolute; top: 0; left: 0; right: 0; bottom: 0; justify-content: center; align-items: center;\">\r\n      <div style=\"width: 30%;justify-content:center;align-items:center;\">\r\n        <p style=\"font-size: 40px; font-family: 'JetBrains Mono';\">\r\n          @* #milaine.wingame *@\r\n          @TranslationsInstance.T(\"milaine.wingame\")\r\n        </p>\r\n      </div>\r\n    </div>\r\n  }\r\n\r\n  @if (isDayEnd && !isGameWin) {\r\n    <div class=\"day-container night\">\r\n      <div class=\"summary-container\">\r\n        <header class=\"summary-header\">\r\n          <div class=\"summary-title\">\r\n            <span class=\"circle\" />\r\n            <h2 class=\"normal-font\">\r\n              @* #milaine.summary.title *@\r\n              @TranslationsInstance.T(\"milaine.summary.title\")\r\n            </h2>\r\n          </div>\r\n          <div class=\"separator\" />\r\n        </header>\r\n        <div class=\"row\">\r\n          <div class=\"form-control nth mblue\">\r\n            <div class=\"form-control-header\">\r\n              <h3 class=\"normal-font\">\r\n                @* #milaine.summary.investment *@\r\n                @TranslationsInstance.T(\"milaine.summary.investment\")\r\n              </h3>\r\n              <span class=\"circle-base circle-blue\" />\r\n            </div>\r\n            <p class=\"number\">\r\n              [email protected](InvestmentManagerInstance.Profit)\r\n            </p>\r\n          </div>\r\n          <div class=\"form-control nth mgreen\">\r\n            <div class=\"form-control-header\">\r\n              <h3 class=\"normal-font\">\r\n                @* #milaine.summary.wallet *@\r\n                @TranslationsInstance.T(\"milaine.summary.wallet\")\r\n              </h3>\r\n              <span class=\"circle-base circle-green\" />\r\n            </div>\r\n            <p class=\"number\">\r\n              [email protected](InvestmentManagerInstance.WalletPasive)\r\n            </p>\r\n          </div>\r\n          <div class=\"form-control nth mred\">\r\n            <div class=\"form-control-header\">\r\n              <h3 class=\"normal-font\">\r\n                @* #milaine.summary.dollar-spent *@\r\n                @TranslationsInstance.T(\"milaine.summary.dollar-spent\")\r\n              </h3>\r\n              <span class=\"circle-base circle-red\" />\r\n            </div>\r\n            <p class=\"number\">\r\n              [email protected](IdleManagerInstance.DollarsSpent)\r\n            </p>\r\n          </div>\r\n        </div>\r\n        <div class=\"separator\" />\r\n\r\n        @if (DayNightManagerInstance.Day == DayNightManager.MAX_DAYS) {\r\n          <button class=\"btn-next-action normal-font\" onclick=@HandleAgain>\r\n            @* #milaine.back-to-past *@\r\n            @TranslationsInstance.T(\"milaine.back-to-past\")\r\n          </button>\r\n        } else {\r\n          <button class=\"btn-next-action normal-font\" onclick=@HandleNextDay>\r\n            @* #milaine.next-day *@\r\n            @TranslationsInstance.T(\"milaine.next-day\")\r\n          </button>\r\n        }\r\n      </div>\r\n    </div>\r\n  }\r\n  <div class=\"version-manager\">\r\n    <p>@(\"v\" + VersionManagerInstance.Version.ToString())</p>\r\n  </div>\r\n</root>\r\n\r\n@code\r\n{\r\n  private const float ANIMATION_DURATION = 5f;\r\n\r\n  [Property, Title(\"Translations\")]\r\n  [Feature(\"Managers\")]\r\n  public Translations TranslationsInstance { get; set; }\r\n\r\n  [Property, Title(\"VersionManager\")]\r\n  [Feature(\"Managers\")]\r\n  public VersionManager VersionManagerInstance { get; set; }\r\n\r\n  [Property, Title(\"IdleManager\")]\r\n  [Feature(\"Managers\")]\r\n  public IdleManager IdleManagerInstance { get; set; }\r\n\r\n  [Property, Title(\"InvestmentManager\")]\r\n  [Feature(\"Managers\")]\r\n  public InvestmentManager InvestmentManagerInstance { get; set; }\r\n\r\n  [Property, Title(\"DayNightManager\")]\r\n  [Feature(\"Managers\")]\r\n  public DayNightManager DayNightManagerInstance { get; set; }\r\n\r\n  [Property, Title(\"GameManager\")]\r\n  [Feature(\"Managers\")]\r\n  public GameManager GameManagerInstance { get; set; }\r\n\r\n  [Property, Title(\"TreeSkillPanel\")]\r\n  [Feature(\"General\")]\r\n  public TreeSkillPanel TreeSkillPanelInstance { get; set; }\r\n\r\n  [Property]\r\n  [Feature(\"General\")]\r\n  public int Dollars { get; set; } = 0;\r\n\r\n  private bool isPanelOpened = false;\r\n\r\n  private Dictionary<string, object> data = [];\r\n\r\n  private bool isInitializedDay = false;\r\n  private bool isDayEnd = false;\r\n\r\n  private bool isGameWin = false;\r\n\r\n  protected override int BuildHash() => System.HashCode.Combine(Dollars,\r\nDayNightManagerInstance.CurrentTimeString, DayNightManagerInstance.Day, InvestmentManagerInstance.Total\r\n, IdleManagerInstance.DollarsSpent, InvestmentManagerInstance.WalletPasive, InvestmentManagerInstance.Profit);\r\n\r\n  protected override void OnAwake() {\r\n    base.OnStart();\r\n\r\n    data[\"Day\"] = DayNightManagerInstance.Day;\r\n    IdleManagerInstance.OnDeposit += RefreshDeposit;\r\n    IdleManagerInstance.OnChange += Refresh;\r\n    DayNightManagerInstance.OnStartDay += StartDay;\r\n    DayNightManagerInstance.OnEndDay += EndDay;\r\n    GameManagerInstance.OnWinGame += OnWinGame;\r\n  }\r\n\r\n  protected override void OnUpdate() {\r\n    if (Input.Pressed(\"use\")) {\r\n      TogglePanel();\r\n      return;\r\n    }\r\n\r\n    if (Input.EscapePressed) {\r\n      isPanelOpened = false;\r\n      StateHasChanged();\r\n      TreeSkillPanelInstance.Close();\r\n    }\r\n  }\r\n\r\n  protected override void OnDestroy() {\r\n    base.OnDestroy();\r\n\r\n    IdleManagerInstance.OnDeposit -= RefreshDeposit;\r\n    IdleManagerInstance.OnChange -= Refresh;\r\n    DayNightManagerInstance.OnStartDay -= StartDay;\r\n    DayNightManagerInstance.OnEndDay -= EndDay;\r\n    GameManagerInstance.OnWinGame -= OnWinGame;\r\n\r\n  }\r\n\r\n  private void OnWinGame() {\r\n    isGameWin = GameManagerInstance.IsGameWin;\r\n  }\r\n\r\n  private void TogglePanel() {\r\n    isPanelOpened = !isPanelOpened;\r\n    StateHasChanged();\r\n\r\n    Panel.Blur();\r\n\r\n    if (isPanelOpened) {\r\n      TreeSkillPanelInstance.Open();\r\n      return;\r\n    }\r\n\r\n    TreeSkillPanelInstance.Close();\r\n  }\r\n\r\n  private string GetPercentage() {\r\n    float Total = InvestmentManagerInstance.Total;\r\n    float percentage = (Total / IdleManagerInstance.Goal) * 100;\r\n\r\n    return Pixel.Inv(percentage);\r\n  }\r\n\r\n  private void StartDay() {\r\n    isInitializedDay = true;\r\n    StateHasChanged();\r\n\r\n    _ = HideAafterDelay();\r\n  }\r\n\r\n  private void EndDay() {\r\n    isDayEnd = true;\r\n    StateHasChanged();\r\n  }\r\n\r\n  private void HandleNextDay() {\r\n    isDayEnd = false;\r\n    DayNightManagerInstance.NextDay();\r\n    data[\"Day\"] = DayNightManagerInstance.Day;\r\n    StateHasChanged();\r\n    StartDay();\r\n  }\r\n\r\n  private async Task HideAafterDelay() {\r\n    await Task.DelaySeconds(ANIMATION_DURATION);\r\n    isInitializedDay = false;\r\n    StateHasChanged();\r\n  }\r\n\r\n  private void Refresh(int dollars, int amount) {\r\n    Dollars = dollars;\r\n    FloatingTextManager.Instance.Spawn($\"+{amount}\", 25f, 10f);\r\n  }\r\n\r\n  private void RefreshDeposit() {\r\n    Dollars = 0;\r\n  }\r\n\r\n  private void HandleAgain() {\r\n    GameManagerInstance.Restart();\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "UI/PauseGamePanel/PauseGamePanel.razor",
            "FileName": "PauseGamePanel.razor",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "@using Milaine.Managers;\r\n@using Milaine.Settings;\r\n@using Sandbox;\r\n@using Sandbox.UI;\r\n@inherits PanelComponent\r\n@namespace Sandbox\r\n\r\n<root>\r\n  @if (PauseGameInstance.IsOpened) {\r\n    <div class=\"pause-container\">\r\n      <header class=\"header\">\r\n        <DropDown Options=@ModeOptions Value=@SelectedMode ValueChanged=@OnOptionChanged />\r\n      </header>\r\n      <main>\r\n        <div class=\"container\">\r\n          <button [email protected]>\r\n            @TranslationsInstance.T(\"milaine.back\")\r\n          </button>\r\n          <button onclick=@ExitGame>\r\n            @TranslationsInstance.T(\"milaine.quit\")\r\n          </button>\r\n        </div>\r\n\r\n        <div class=\"credits\">\r\n          <p>Credits</p>\r\n          <p>\r\n            Computer Keyboard by Luke (https://sbox.game/luke/office_keyboard)\r\n          </p>\r\n          <p>\r\n            Computer Monitor by Luke (https://sbox.game/luke/monitor_basic)\r\n          </p>\r\n          <p>\r\n            Computer Mouse by Luke (https://sbox.game/luke/computer_mouse)\r\n          </p>\r\n          <p>\r\n            Coffee_cup_01 by Small Box Studio (https://sbox.game/smallboxstudio/coffeecup01)\r\n          </p>\r\n          <p>\r\n            French_fries_02 by Small Box Studio (https://sbox.game/smallboxstudio/frenchfries02)\r\n          </p>\r\n          <p>\r\n            French_fries_02_empty by Small Box Studio (https://sbox.game/smallboxstudio/frenchfries02empty)\r\n          </p>\r\n          <p>\r\n            Stir_fried_noodles_01 by Small Box Studio (https://sbox.game/smallboxstudio/stirfriednoodles01)\r\n          </p>\r\n          <p>\r\n            Stir_fried_noodles_01_close by Small Box Studio (https://sbox.game/smallboxstudio/stirfriednoodles01close)\r\n          </p>\r\n        </div>>\r\n      </main>\r\n    </div>\r\n    <div class=\"version-manager\">\r\n      <p>@(\"v\" + VersionManagerInstance.Version.ToString())</p>\r\n    </div>\r\n  }\r\n\r\n</root>\r\n\r\n@code\r\n{\r\n  [Property, Title(\"Translations\")]\r\n  [Feature(\"Managers\")]\r\n  public Translations TranslationsInstance { get; set; }\r\n\r\n  [Property, Title(\"VersionManager\")]\r\n  [Feature(\"Managers\")]\r\n  public VersionManager VersionManagerInstance { get; set; }\r\n\r\n  [Property]\r\n  [Feature(\"Settings\")]\r\n  public PauseGame PauseGameInstance { get; set; }\r\n\r\n  public string SelectedMode { get; set; } = \"en\";\r\n\r\n  public List<UI.Option> ModeOptions { get; set; } = [\r\n    new Option{Title = \"English\", Value = \"en\"},\r\n    new Option{Title = \"Espa\u00f1ol\", Value = \"es\"},\r\n  ];\r\n\r\n  protected override int BuildHash() => System.HashCode.Combine(PauseGameInstance.IsOpened, SelectedMode);\r\n\r\n  protected override void OnStart() {\r\n    base.OnStart();\r\n    SelectedMode = TranslationsInstance.language;\r\n  }\r\n\r\n  private void ExitGame() {\r\n    if (Application.IsStandalone) {\r\n      Game.Close();\r\n      return;\r\n    }\r\n\r\n    Game.Disconnect();\r\n  }\r\n\r\n  private void OnOptionChanged(object code) {\r\n    SelectedMode = (string)code;\r\n    TranslationsInstance.SetLanguage((string)code);\r\n    StateHasChanged();\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Managers/DialoguesManager.cs",
            "FileName": "DialoguesManager.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "namespace Milaine.Managers;\r\n\r\n\r\npublic sealed class DialoguesManager : Component {\r\n  [Property, Title(\"Dialogues View\")]\r\n  public PanelComponent DialoguesView { get; set; }\r\n\r\n  private List<Step> steps = [];\r\n\r\n  private class Step { }\r\n\r\n  protected override void OnStart() {\r\n    if (!DialoguesView.IsValid()) {\r\n      Log.Warning(\"Need Instances of [DialoguesView]\");\r\n    }\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/TreeSkills/SkillNodeData.cs",
            "FileName": "SkillNodeData.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "namespace Milaine.TreeSkills;\r\n\r\npublic enum SkillCategory {\r\n  Dollars,\r\n  Wallet,\r\n  Investment,\r\n  Dividends,\r\n  WalletPlus,\r\n  DollarAutomatic\r\n}\r\n\r\npublic class SkillNodeData {\r\n  public string Id { get; set; }\r\n  public string Name { get; set; }\r\n  public string Description { get; set; }\r\n  public string KeyDescription { get; set; }\r\n  public int Cost { get; set; }\r\n  public SkillCategory Category { get; set; }\r\n  public float Point { get; set; }\r\n\r\n  public int Row { get; set; }\r\n  public int Column { get; set; }\r\n\r\n  public string Icon { get; set; } = \"\ud83c\udf15\";\r\n\r\n  public bool IsRoot { get; set; }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Constants/VersionConstants.cs",
            "FileName": "VersionConstants.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "namespace Milaine.Constants;\r\n\r\npublic class VersionConstants {\r\n  public const int MAYOR = 0;\r\n  public const int MINOR = 9;\r\n  public const int PATCH = 1;\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Managers/InvestmentManager.cs",
            "FileName": "InvestmentManager.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "using System;\r\nusing Milaine.Interfaces;\r\n\r\nnamespace Milaine.Managers;\r\n\r\npublic struct Portfolio(int wallet = 0, float investment = 0, float profit = 0, int shares = 0) {\r\n  public int wallet = wallet;\r\n  public float investment = investment;\r\n  public float profit = profit;\r\n  public int shares = shares;\r\n}\r\n\r\npublic sealed class InvestmentManager : Component, IManager {\r\n  public const float DEFAULT_PERFORMANCE = 1.0f;\r\n\r\n  [Property, Title(\"DayNightManager\")]\r\n  [Feature(\"Managers\")]\r\n  public DayNightManager DayNightManagerInstance { get; set; }\r\n\r\n  [Property]\r\n  [Feature(\"General\")]\r\n  public bool IsDayEnded { get; set; } = false;\r\n\r\n  [Property]\r\n  [Feature(\"General\"), Group(\"Digital\")]\r\n  public int Wallet { get; set; } = 0;\r\n\r\n  [Property]\r\n  [Feature(\"General\"), Group(\"Digital\")]\r\n  public float Investment { get; set; } = 0;\r\n\r\n  [Property]\r\n  [Feature(\"General\"), Group(\"Digital\")]\r\n  public float Profit { get; set; } = 0;\r\n\r\n  [Property]\r\n  [Feature(\"General\"), Group(\"Digital\")]\r\n  public int Shares { get; set; } = 0;\r\n\r\n  public Action<Portfolio> OnChange { get; set; }\r\n\r\n  private float performance = DEFAULT_PERFORMANCE;\r\n  private float acc = 0f;\r\n  private float multiplierDeposit = 1.0f;\r\n  private bool isAvailablePerformanceWallet = false;\r\n  private int performanceWallet = (int)DEFAULT_PERFORMANCE;\r\n\r\n  private float accDividends = 0f;\r\n  private bool isActivatedDividends = false;\r\n  private float multiplierDividends = 0.0f;\r\n\r\n  private int walletPasive = 0;\r\n\r\n  public float Total {\r\n    get => Wallet + Investment;\r\n  }\r\n\r\n\r\n  public int WalletPasive {\r\n    get => walletPasive;\r\n  }\r\n\r\n  protected override void OnStart() {\r\n    DayNightManagerInstance.OnStartDay += DayStartSubscription;\r\n    DayNightManagerInstance.OnEndDay += DayNightSubscription;\r\n  }\r\n\r\n  protected override void OnDestroy() {\r\n    DayNightManagerInstance.OnStartDay -= DayStartSubscription;\r\n    DayNightManagerInstance.OnEndDay -= DayNightSubscription;\r\n  }\r\n\r\n  protected override void OnUpdate() {\r\n    if (IsDayEnded) {\r\n      return;\r\n    }\r\n\r\n    acc += Time.Delta;\r\n\r\n    if (acc >= 1.0f) {\r\n      if (Investment != 0f) {\r\n        Profit += performance;\r\n        Investment += performance;\r\n      }\r\n\r\n      if (isAvailablePerformanceWallet) {\r\n        Wallet += performanceWallet;\r\n        walletPasive += performanceWallet;\r\n      }\r\n\r\n\r\n      acc = 0;\r\n    }\r\n\r\n    accDividends += Time.Delta;\r\n\r\n    if (accDividends >= 5.0f && isActivatedDividends) {\r\n      Wallet += (Investment * multiplierDividends).CeilToInt();\r\n      accDividends = 0;\r\n    }\r\n  }\r\n\r\n  public void Deposit(int dollars) {\r\n    Wallet += (multiplierDeposit * dollars).CeilToInt();\r\n    OnChange?.Invoke(new Portfolio { wallet = Wallet, investment = Investment, profit = Profit, shares = Shares });\r\n  }\r\n\r\n  public void Invest() {\r\n    Investment += Wallet;\r\n    Wallet = 0;\r\n    OnChange?.Invoke(new Portfolio { wallet = Wallet, investment = Investment, profit = Profit, shares = Shares });\r\n  }\r\n\r\n  private void DayNightSubscription() {\r\n    IsDayEnded = true;\r\n  }\r\n\r\n  private void DayStartSubscription() {\r\n    IsDayEnded = false;\r\n    Profit = 0;\r\n    walletPasive = 0;\r\n  }\r\n\r\n  public void ImprovePerformance(float amount) {\r\n    performance += amount;\r\n  }\r\n\r\n  public void ImproveWallet(float amount) {\r\n    ImproveWallet((int)amount);\r\n  }\r\n\r\n  private void ImproveWallet(int amount) {\r\n    if (!isAvailablePerformanceWallet) {\r\n      isAvailablePerformanceWallet = true;\r\n    }\r\n\r\n    performanceWallet = amount;\r\n  }\r\n\r\n  public void ImproveDeposit(float amount) {\r\n    multiplierDeposit = amount;\r\n  }\r\n\r\n  public void ImproveDividends(float amount) {\r\n    if (!isActivatedDividends) {\r\n      isActivatedDividends = true;\r\n    }\r\n\r\n    multiplierDividends = amount;\r\n  }\r\n\r\n  public void Restart() {\r\n    // reset all stats (wallet, profit, investment, days)\r\n    performance = DEFAULT_PERFORMANCE;\r\n    multiplierDeposit = 1.0f;\r\n    isActivatedDividends = false;\r\n    multiplierDividends = 0.0f;\r\n    isAvailablePerformanceWallet = false;\r\n    performanceWallet = (int)DEFAULT_PERFORMANCE;\r\n    walletPasive = 0;\r\n    Wallet = 0;\r\n    Investment = 0f;\r\n    Profit = 0;\r\n    Shares = 0;\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Settings/Translation.cs",
            "FileName": "Translation.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "using Milaine.Utils;\r\n\r\nnamespace Milaine.Settings;\r\n\r\npublic sealed class Translations : Component {\r\n  [Property, Title(\"Configuration\")]\r\n  public Configuration ConfigurationInstance { get; set; }\r\n\r\n  private Localization localization;\r\n\r\n  public string language = \"en\";\r\n\r\n  protected override void OnAwake() {\r\n    localization = new();\r\n    language = ConfigurationInstance.Language;\r\n    localization.SetLanguage(ConfigurationInstance.Language);\r\n  }\r\n\r\n  public void SetLanguage(string language) {\r\n    localization.SetLanguage(language);\r\n\r\n    this.language = language;\r\n\r\n    ConfigurationInstance.Language = language;\r\n    ConfigurationInstance.SaveConfig();\r\n  }\r\n\r\n  public string T(string token, Dictionary<string, object> data = null) => localization.T(token, data);\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "UI/InvestmentPanel/InvestmentPanel.razor",
            "FileName": "InvestmentPanel.razor",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "@using System.Text;\r\n@using Milaine.Managers;\r\n@using Milaine.Settings;\r\n@using Milaine.Utils;\r\n@using Sandbox;\r\n@using Sandbox.UI;\r\n@inherits PanelComponent\r\n@namespace Sandbox\r\n\r\n<root>\r\n  <header>\r\n    <div class=\"container-title\">\r\n      <Image src=\"resources/hexagon.png\" class=\"image\" style=\"width: 20px; height: 20px;\" />\r\n      <h1 class=\"title\">SHARES // WORKS</h1>\r\n    </div>\r\n    <div class=\"content\" style=\"pointer-events: @(MouseManager.State == StateMouse.Busy ? \"none\" : \"all\");\">\r\n      <Image src=\"resources/wallet-minimal.png\" class=\"image\" style=\"width: 20px; height: 20px;\" />\r\n      <p class=\"text\">[email protected](InvestmentManagerInstance.Wallet)</p>\r\n    </div>\r\n  </header>\r\n  <div class=\"container\">\r\n    <section class=\"card\" style=\"pointer-events: @(MouseManager.State == StateMouse.Busy ? \"none\" : \"all\");\">\r\n      <div class=\"card-header\">\r\n        <div class=\"card-header-wrapper\">\r\n          @if (InvestmentManagerInstance.Profit == 0) {\r\n            <Image src=\"resources/dot.png\" />\r\n          }\r\n          @if (InvestmentManagerInstance.Profit > 0) {\r\n            <Image src=\"resources/trending-up.png\" />\r\n          }\r\n          @if (InvestmentManagerInstance.Profit < 0) {\r\n            <Image src=\"resources/trending-down.png\" />\r\n          }\r\n          <p class=\"card-title\">\r\n            @* #milaine.profit.total *@\r\n            @TranslationsInstance.T(\"milaine.profit.total\")\r\n          </p>\r\n        </div>\r\n        <div class=@ClassName()>\r\n          @if (InvestmentManagerInstance.Profit == 0) {\r\n            <p>\r\n              @* #milaine.critical.standard-profit *@\r\n              @TranslationsInstance.T(\"milaine.critical.standard-profit\")\r\n            </p>\r\n          }\r\n          @if (InvestmentManagerInstance.Profit < 0) {\r\n            <p>\r\n              @* #milaine.critical.bad-profit *@\r\n              @TranslationsInstance.T(\"milaine.critical.bad-profit\")\r\n            </p>\r\n          }\r\n          @if (InvestmentManagerInstance.Profit > 0) {\r\n            <p>\r\n              @* #milaine.critical.profit *@\r\n              @TranslationsInstance.T(\"milaine.critical.profit\")\r\n            </p>\r\n          }\r\n        </div>\r\n      </div>\r\n      <div class=\"card-body\">\r\n        <div class=\"investment-container\">\r\n          <div class=\"investment-content\">\r\n            <p\r\n              class=\"investment-text @(InvestmentManagerInstance.Profit == 0 ? \"normal\" : InvestmentManagerInstance.Profit < 0 ? \"bad\" : \"good\")\">\r\n              @BuildInvestment(InvestmentManagerInstance.Investment)\r\n            </p>\r\n\r\n            @if (InvestmentManagerInstance.Profit > 0) {\r\n              <p class=\"shares\">[email protected]</p>\r\n            }\r\n          </div>\r\n          <div class=\"action\">\r\n            <button class=\"btn btn-primary\" onclick=@HandleClickInvestment>\r\n              @* #milaine.invest *@\r\n              @TranslationsInstance.T(\"milaine.invest\")\r\n            </button>\r\n            <button class=\"btn btn-secondary\" onclick=@HandleClickDeposit>\r\n              @* #milaine.deposit *@\r\n              @TranslationsInstance.T(\"milaine.deposit\")\r\n            </button>\r\n          </div>\r\n        </div>\r\n      </div>\r\n    </section>\r\n  </div>\r\n</root>\r\n\r\n@code\r\n{\r\n  [Property, Title(\"InvestmentManager\")]\r\n  [Feature(\"Managers\")]\r\n  public InvestmentManager InvestmentManagerInstance { get; set; }\r\n\r\n  [Property, Title(\"IdleManager\")]\r\n  [Feature(\"Managers\")]\r\n  public IdleManager IdleManagerInstance { get; set; }\r\n\r\n  [Property, Title(\"Translations\")]\r\n  [Feature(\"Managers\")]\r\n  public Translations TranslationsInstance { get; set; }\r\n\r\n  public Dictionary<string, object> Data = [];\r\n\r\n  protected override int BuildHash() => System.HashCode.Combine(Data, InvestmentManagerInstance.Wallet,\r\nInvestmentManagerInstance.Profit, TranslationsInstance.language, MouseManager.State);\r\n\r\n  protected override void OnStart() {\r\n    if (!InvestmentManagerInstance.IsValid()) {\r\n      Log.Warning(\"Need Instance the InvestmentManager into [InvestmentView]\");\r\n      return;\r\n    }\r\n\r\n    Refresh();\r\n  }\r\n\r\n  protected override void OnUpdate() {\r\n    base.OnUpdate();\r\n\r\n    if (Input.EscapePressed) {\r\n      StateHasChanged();\r\n    }\r\n  }\r\n\r\n  public string ClassName() => InvestmentManagerInstance.Profit == 0 ? \"tag standard\" : InvestmentManagerInstance.Profit\r\n< 0 ? \"tag low\" : \"tag\";\r\n\r\n  private void HandleClickInvestment() {\r\n    InvestmentManagerInstance.Invest();\r\n    Refresh();\r\n  }\r\n\r\n  private void HandleClickDeposit() {\r\n    InvestmentManagerInstance.Deposit(IdleManagerInstance.Dollars);\r\n    IdleManagerInstance.Deposit();\r\n    Refresh();\r\n  }\r\n\r\n  private string BuildInvestment(float investment) {\r\n    StringBuilder sb = new();\r\n    float profit = InvestmentManagerInstance.Profit;\r\n\r\n    if (profit < 0) {\r\n      sb.Append(\"- $\");\r\n    }\r\n\r\n    if (profit > 0) {\r\n      sb.Append(\"+ $\");\r\n    }\r\n\r\n    sb.Append(Formatter.ToDisplay(investment));\r\n\r\n    return sb.ToString();\r\n  }\r\n\r\n  private void Refresh() {\r\n    Data[\"WalletValue\"] = Formatter.ToDisplayShort(InvestmentManagerInstance.Wallet);\r\n    Data[\"InvestmentValue\"] = Formatter.ToDisplay(InvestmentManagerInstance.Investment);\r\n    Data[\"ProfitValue\"] = Formatter.ToDisplay(InvestmentManagerInstance.Profit);\r\n    Data[\"SharesValue\"] = InvestmentManagerInstance.Shares;\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "ui/hud/hud.razor.scss",
            "FileName": "hud.razor.scss",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "Hud {\r\n  position: absolute;\r\n  top: 0;\r\n  left: 0;\r\n  right: 0;\r\n  bottom: 0;\r\n  flex-direction: column;\r\n  font-weight: bold;\r\n  border-radius: 20px;\r\n  color: #fff;\r\n  font-size: 25px;\r\n\r\n  .header {\r\n    display: flex;\r\n    justify-content: flex-end;\r\n    align-items: center;\r\n    gap: 50px;\r\n    padding: 20px;\r\n\r\n    .day-manager h2 {\r\n      text-align: center;\r\n      font-size: 30px;\r\n      font-family: \"Space Grotesk\";\r\n    }\r\n\r\n    .clock {\r\n      background-color: rgba(0, 0, 0, 0.5);\r\n      color: #fff;\r\n      display: flex;\r\n      justify-content: center;\r\n      align-items: center;\r\n\r\n      p {\r\n        text-align: center;\r\n        font-size: 28px;\r\n        font-family: \"JetBrains Mono\";\r\n      }\r\n    }\r\n  }\r\n\r\n  .container {\r\n    position: absolute;\r\n    bottom: 50px;\r\n    right: 50px;\r\n    font-family: \"JetBrains Mono\";\r\n\r\n    .content {\r\n      padding: 10px 20px;\r\n      display: flex;\r\n      background-color: rgba(0, 0, 0, 0.5);\r\n      border: 1px solid rgba(39, 42, 46, 0.8);\r\n      border-radius: 5px;\r\n      justify-content: center;\r\n      align-items: center;\r\n      gap: 10px;\r\n\r\n      .image {\r\n        object-fit: cover;\r\n      }\r\n\r\n      .headline {\r\n        color: #00ff66;\r\n      }\r\n    }\r\n  }\r\n\r\n  .slot {\r\n    position: absolute;\r\n    bottom: 50px;\r\n    right: 300px;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n    flex-direction: column;\r\n    gap: 10px;\r\n    border-radius: 5px;\r\n    padding: 10px 15px;\r\n    background-color: rgba(0, 0, 0, 0.5);\r\n    transition: all 300ms ease;\r\n\r\n    &:hover {\r\n      background-color: rgba(0, 0, 0, 0.8);\r\n      transition: all 300ms ease;\r\n      sound-in: ui.button.over;\r\n    }\r\n\r\n    .kbd {\r\n      font-family: \"JetBrains Mono\";\r\n      font-size: 30px;\r\n    }\r\n\r\n    .title {\r\n      font-family: \"Space Grotesk\";\r\n      font-size: 21px;\r\n    }\r\n  }\r\n\r\n  .progress-end-game {\r\n    position: absolute;\r\n    width: 70%;\r\n    bottom: 50px;\r\n    left: 50px;\r\n\r\n    .progress-bar {\r\n      width: 100%;\r\n      height: 40px;\r\n      padding: 4px;\r\n      border-radius: 6px;\r\n      overflow: hidden;\r\n      background-color: rgba(0, 0, 0, 0.7);\r\n\r\n      .bar {\r\n        height: 100%;\r\n        background-image: linear-gradient(to right, #00e55b, #00ff66, #00e3fd);\r\n        border-radius: 2px;\r\n      }\r\n\r\n      p {\r\n        position: absolute;\r\n        font-family: \"JetBrains Mono\";\r\n        top: 50%;\r\n        left: 50%;\r\n        transform: translate(-50%, -50%);\r\n      }\r\n    }\r\n  }\r\n\r\n  .day-container {\r\n    position: fixed;\r\n    top: 0;\r\n    left: 0;\r\n    right: 0;\r\n    bottom: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    justify-content: center;\r\n    align-items: center;\r\n    background-color: rgb(7, 9, 11);\r\n    opacity: 0;\r\n    pointer-events: none;\r\n\r\n    z-index: 999;\r\n\r\n    animation-name: morning;\r\n    animation-duration: 5s;\r\n    animation-timing-function: ease;\r\n    animation-fill-mode: forwards;\r\n\r\n    .heading-current-day {\r\n      font-size: 40px;\r\n      text-align: center;\r\n      font-weight: 700;\r\n      font-family: \"Space Grotesk\";\r\n      letter-spacing: 2px;\r\n    }\r\n\r\n    &.night {\r\n      flex-direction: column;\r\n\r\n      animation-name: night;\r\n      animation-duration: 2s;\r\n\r\n      button {\r\n        pointer-events: all;\r\n      }\r\n    }\r\n\r\n    .summary-container {\r\n      width: 35%;\r\n      padding: 24px;\r\n      border: 1px solid #1e2936;\r\n      flex-direction: column;\r\n      background-color: rgb(18 23 30 / 0.95);\r\n      border-radius: 12px;\r\n      overflow: hidden;\r\n      box-shadow:\r\n        0 0 25px -5px rgba(0, 255, 102, 0.25),\r\n        inset 0 0 15px -3px rgba(0, 255, 102, 0.08);\r\n\r\n      .summary-header {\r\n        margin-bottom: 20px;\r\n        flex-direction: column;\r\n\r\n        .summary-title {\r\n          display: flex;\r\n          align-items: center;\r\n          justify-content: flex-start;\r\n          gap: 10px;\r\n          padding-bottom: 16px;\r\n\r\n          .circle {\r\n            width: 16px;\r\n            height: 16px;\r\n            border-radius: 50%;\r\n            background-color: #00ff66;\r\n          }\r\n\r\n          h2 {\r\n            font-family: \"Space Grotesk\";\r\n            font-size: 40px;\r\n          }\r\n        }\r\n      }\r\n\r\n      .row {\r\n        display: flex;\r\n        justify-content: space-between;\r\n        align-items: center;\r\n        margin-bottom: 20px;\r\n        gap: 20px;\r\n      }\r\n\r\n      .form-control {\r\n        padding: 16px;\r\n        background-color: rgb(13 17 22 / 0.9);\r\n        border: 1px solid rgb(30 41 54 / 0.7);\r\n        border-radius: 8px;\r\n        flex-direction: column;\r\n        margin-bottom: 20px;\r\n        gap: 16px;\r\n        pointer-events: all;\r\n\r\n        transition: all 500ms ease;\r\n\r\n        &.nth {\r\n          flex: 1;\r\n\r\n          h3 {\r\n            font-size: 23px;\r\n          }\r\n        }\r\n\r\n        h3 {\r\n          font-size: 30px;\r\n          color: #94a3b8;\r\n        }\r\n\r\n        .form-control-header {\r\n          justify-content: space-between;\r\n          align-items: center;\r\n        }\r\n\r\n        &:hover {\r\n          transition: all 500ms ease;\r\n\r\n          &.mgreen {\r\n            border-color: #00ff66;\r\n          }\r\n\r\n          &.mblue {\r\n            border-color: #00e3fd;\r\n          }\r\n\r\n          &.mred {\r\n            border-color: #ff3366;\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    .separator {\r\n      width: 100%;\r\n      height: 1px;\r\n      background-color: rgb(30 41 54 / 0.8);\r\n    }\r\n\r\n    .normal-font {\r\n      font-family: \"Space Grotesk\";\r\n    }\r\n\r\n    .number {\r\n      font-family: \"JetBrains Mono\";\r\n    }\r\n\r\n    .btn-next-action {\r\n      flex: 1;\r\n      display: flex;\r\n      flex-direction: row;\r\n      justify-content: center;\r\n      align-items: center;\r\n      padding: 30px;\r\n      background-color: rgb(13 17 22 / 0.9);\r\n      border: 1px solid #1e2936;\r\n      border-radius: 16px;\r\n      margin: 20px 0;\r\n\r\n      pointer-events: all;\r\n    }\r\n\r\n    .circle-base {\r\n      width: 8px;\r\n      height: 8px;\r\n      border-radius: 50%;\r\n    }\r\n\r\n    .circle-green {\r\n      background-color: #00ff66;\r\n    }\r\n\r\n    .circle-blue {\r\n      background-color: #00e3fd;\r\n    }\r\n\r\n    .circle-red {\r\n      background-color: #ff3366;\r\n    }\r\n  }\r\n\r\n  .version-manager {\r\n    position: absolute;\r\n    top: 20px;\r\n    left: 20px;\r\n    background-color: rgba(0, 0, 0, 0.5);\r\n\r\n    p {\r\n      color: white;\r\n      font-family: \"JetBrains Mono\";\r\n      font-size: 26px;\r\n    }\r\n  }\r\n}\r\n\r\n@keyframes morning {\r\n  0% {\r\n    opacity: 0;\r\n  }\r\n\r\n  2% {\r\n    opacity: 1;\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n  }\r\n\r\n  100% {\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes night {\r\n  0% {\r\n    opacity: 0;\r\n  }\r\n\r\n  100% {\r\n    opacity: 1;\r\n  }\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Assembly.cs",
            "FileName": "Assembly.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "global using Sandbox;\r\nglobal using System.Collections.Generic;\r\nglobal using System.Linq;\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Utils/Pixel.cs",
            "FileName": "Pixel.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "using System.Globalization;\r\n\r\nnamespace Milaine.Utils;\r\n\r\npublic static class Pixel {\r\n  public static string Inv(float numb) => numb.ToString(CultureInfo.InvariantCulture);\r\n}\r\n"
        },
        {
            "Ident": "rakunsoftware.milaine",
            "Path": "Scripts/Utils/Formatter.cs",
            "FileName": "Formatter.cs",
            "PackageType": "game",
            "CodeKind": "Game",
            "AssetVersionId": 394495,
            "IsPrivate": false,
            "Code": "using System;\r\nusing System.Globalization;\r\n\r\nnamespace Milaine.Utils;\r\n\r\npublic static class Formatter {\r\n  private static readonly string[] Suffixes = [\"\", \"k\", \"M\", \"B\", \"T\", \"Qa\", \"Qi\"];\r\n\r\n  /// <summary>\r\n  /// format float numbers from 1000 to 1.000\r\n  /// </summary>\r\n  /// <param name=\"val\"></param>\r\n  /// <returns></returns>\r\n  public static string ToDisplay(float val) {\r\n    string native = val.ToString(\"#,##0\", CultureInfo.InvariantCulture);\r\n    string display = native.Replace(',', '.');\r\n\r\n    return display;\r\n  }\r\n\r\n  /// <summary>\r\n  /// format from 1000 to 1.0K\r\n  /// </summary>\r\n  /// <param name=\"val\"></param>\r\n  /// <returns></returns>\r\n  public static string ToDisplayShort(float val) {\r\n    double absVal = Math.Abs((double)val);\r\n\r\n    if (absVal < 1000d) {\r\n      return Math.Round(val).ToString(CultureInfo.InvariantCulture);\r\n    }\r\n\r\n    int magnitude = (int)Math.Log(absVal, 1000d);\r\n    magnitude = Math.Min(magnitude, Suffixes.Length - 1);\r\n\r\n    double scaled = val / Math.Pow(1000d, magnitude);\r\n\r\n    if (Math.Round(scaled, 1) >= 1000d && magnitude < Suffixes.Length - 1) {\r\n      magnitude++;\r\n      scaled = val / Math.Pow(1000d, magnitude);\r\n    }\r\n\r\n    string number = scaled.ToString(\"0.0\", CultureInfo.InvariantCulture);\r\n\r\n    return $\"{number}{Suffixes[magnitude]}\";\r\n  }\r\n}\r\n"
        }
    ]
}