diff --git a/.editorconfig b/.editorconfig index dc88eee..e1f631b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -61,4 +61,4 @@ dotnet_diagnostic.IDE0058.severity = none dotnet_diagnostic.CS0649.severity = none # CA1707: Identifiers should not contain underscores -dotnet_diagnostic.CA1707.severity = none \ No newline at end of file +dotnet_diagnostic.CA1707.severity = none diff --git a/About/About.xml b/About/About.xml index 97382bc..9afb9f5 100644 --- a/About/About.xml +++ b/About/About.xml @@ -6,9 +6,8 @@ 5.0.0 Level up notifications! https://github.com/krafs/LevelUp - LevelUp/Icon + LevelUp/Icon -
  • 1.4
  • 1.5
  • diff --git a/Defs/Actions.xml b/Defs/Actions.xml index 9fb2248..f7dcfb7 100644 --- a/Defs/Actions.xml +++ b/Defs/Actions.xml @@ -1,5 +1,6 @@  + LevelUpActionDef_Sound @@ -27,4 +28,5 @@ Displays a text message on the colonist. LevelUp.OverheadMessageAction - \ No newline at end of file + + diff --git a/Defs/Flecks.xml b/Defs/Flecks.xml index e3c8524..d200894 100644 --- a/Defs/Flecks.xml +++ b/Defs/Flecks.xml @@ -1,5 +1,6 @@  + LevelUpAnimation_Radiance @@ -76,4 +77,5 @@ 0.5 (0,0,2) - \ No newline at end of file + + diff --git a/Defs/Sounds.xml b/Defs/Sounds.xml index 5eb98a8..ad63f54 100644 --- a/Defs/Sounds.xml +++ b/Defs/Sounds.xml @@ -1,5 +1,6 @@  + LevelUpSound_Ding @@ -194,4 +195,5 @@ - \ No newline at end of file + + diff --git a/Languages/ChineseSimplified/Keyed/ChineseSimplified.xml b/Languages/ChineseSimplified/Keyed/ChineseSimplified.xml index 7f1bde1..444da8c 100644 --- a/Languages/ChineseSimplified/Keyed/ChineseSimplified.xml +++ b/Languages/ChineseSimplified/Keyed/ChineseSimplified.xml @@ -2,4 +2,4 @@ {PAWN} 的{SKILL}技能到达{LEVEL}级。]]> {PAWN} 的{SKILL}技能降至{LEVEL}级。]]> - \ No newline at end of file + diff --git a/Languages/English/DefInjected/FleckDefs/FleckDefs.xml b/Languages/English/DefInjected/FleckDefs/FleckDefs.xml index e87b889..aa42221 100644 --- a/Languages/English/DefInjected/FleckDefs/FleckDefs.xml +++ b/Languages/English/DefInjected/FleckDefs/FleckDefs.xml @@ -9,4 +9,4 @@ Upward Chevron Downward Chevron - \ No newline at end of file + diff --git a/Languages/English/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml b/Languages/English/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml index 51c5256..cea696a 100644 --- a/Languages/English/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml +++ b/Languages/English/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml @@ -16,4 +16,4 @@ Overhead message Displays a text message on the colonist. - \ No newline at end of file + diff --git a/Languages/English/DefInjected/SoundDefs/SoundDefs.xml b/Languages/English/DefInjected/SoundDefs/SoundDefs.xml index be4138d..99e286b 100644 --- a/Languages/English/DefInjected/SoundDefs/SoundDefs.xml +++ b/Languages/English/DefInjected/SoundDefs/SoundDefs.xml @@ -15,4 +15,4 @@ Strum Tada Fanfare - \ No newline at end of file + diff --git a/Languages/English/Keyed/English.xml b/Languages/English/Keyed/English.xml index 8d0c1c4..0495bb4 100644 --- a/Languages/English/Keyed/English.xml +++ b/Languages/English/Keyed/English.xml @@ -8,11 +8,6 @@ List of actions that, if active, are executed when a colonist levels up a skill. List of actions that, if active, are executed when a colonist levels down a skill. - Cooldown - The duration of a cooldown specified in real-time seconds.\n\nIf applied to an action, the action will not execute for the same colonist and skill again until the cooldown has run out. - Whether or not Cooldown should apply for this action.\n\nIf applied, this action will not execute for the same colonist and skill again until the cooldown has run out. - - General Historical Whether or not the message should be saved in history. @@ -27,4 +22,5 @@ {PAWN} reached level {LEVEL} in {SKILL}.]]> {SKILL}\nlevel {LEVEL} {SKILL}\nlevel {LEVEL} - \ No newline at end of file + + diff --git a/Languages/French/Keyed/French.xml b/Languages/French/Keyed/French.xml index 30d9d04..c7ff0eb 100644 --- a/Languages/French/Keyed/French.xml +++ b/Languages/French/Keyed/French.xml @@ -2,4 +2,4 @@ {PAWN} a atteint le niveau {LEVEL} en {SKILL}.]]> {PAWN} est retombé au niveau {LEVEL} en {SKILL}.]]> - \ No newline at end of file + diff --git a/Languages/German/DefInjected/FleckDefs/FleckDefs.xml b/Languages/German/DefInjected/FleckDefs/FleckDefs.xml index 5c106d8..0b473ae 100644 --- a/Languages/German/DefInjected/FleckDefs/FleckDefs.xml +++ b/Languages/German/DefInjected/FleckDefs/FleckDefs.xml @@ -10,4 +10,4 @@ Doppelspitze nach unten - \ No newline at end of file + diff --git a/Languages/German/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml b/Languages/German/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml index f515464..331874d 100644 --- a/Languages/German/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml +++ b/Languages/German/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml @@ -21,4 +21,4 @@ Zeigt eine Textnachricht auf dem Kolonisten an. - \ No newline at end of file + diff --git a/Languages/German/DefInjected/SoundDefs/SoundDefs.xml b/Languages/German/DefInjected/SoundDefs/SoundDefs.xml index b75ab9a..ecbc104 100644 --- a/Languages/German/DefInjected/SoundDefs/SoundDefs.xml +++ b/Languages/German/DefInjected/SoundDefs/SoundDefs.xml @@ -22,4 +22,4 @@ Tada-Fanfare - \ No newline at end of file + diff --git a/Languages/German/Keyed/German.xml b/Languages/German/Keyed/German.xml index c0742ea..c48ad58 100644 --- a/Languages/German/Keyed/German.xml +++ b/Languages/German/Keyed/German.xml @@ -12,15 +12,6 @@ Eine Liste von Aktionen, die, sofern aktiv, ausgeführt werden, wenn ein Kolonist Fertigkeitsstufen verliert. - - Abklingzeit - - Die Dauer einer Abklingzeit in echten Sekunden.\n\nAktiviert man eine Abklingzeit bei einer Aktion, wird die Aktion für denselben Kolonisten und dieselbe Fertigkeit erst nach einer gewissen Zeit wieder ausgeführt. - - Ob eine Abklingzeit bei dieser Aktion aktiviert werden soll oder nicht.\n\nIm aktivierten Zustand wird die Aktion für denselben Kolonisten und dieselbe Fertigkeit erst nach einer gewissen Zeit wieder ausgeführt. - - - Allgemein Im Nachrichtenverlauf anzeigen diff --git a/Languages/Italian/Deflnjected/FleckDefs/FleckDefs.xml b/Languages/Italian/Deflnjected/FleckDefs/FleckDefs.xml index 095ab84..e5a745a 100644 --- a/Languages/Italian/Deflnjected/FleckDefs/FleckDefs.xml +++ b/Languages/Italian/Deflnjected/FleckDefs/FleckDefs.xml @@ -6,4 +6,4 @@ Chevron verso l'alto Chevron verso il basso - \ No newline at end of file + diff --git a/Languages/Italian/Deflnjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml b/Languages/Italian/Deflnjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml index 300a970..472b40a 100644 --- a/Languages/Italian/Deflnjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml +++ b/Languages/Italian/Deflnjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml @@ -13,4 +13,4 @@ Messaggio in alto Mostra un messaggio testuale sul colono. - \ No newline at end of file + diff --git a/Languages/Italian/Deflnjected/SoundDefs/SoundDefs.xml b/Languages/Italian/Deflnjected/SoundDefs/SoundDefs.xml index fcfa955..3a6add2 100644 --- a/Languages/Italian/Deflnjected/SoundDefs/SoundDefs.xml +++ b/Languages/Italian/Deflnjected/SoundDefs/SoundDefs.xml @@ -12,4 +12,4 @@ Strum Tada-Fanfare - \ No newline at end of file + diff --git a/Languages/Italian/Keyed/Italian.xml b/Languages/Italian/Keyed/Italian.xml index d086068..e90b751 100644 --- a/Languages/Italian/Keyed/Italian.xml +++ b/Languages/Italian/Keyed/Italian.xml @@ -7,12 +7,7 @@ Elenco di azioni che, se attive, vengono eseguite quando un colono aumenta di livello un'abilità. Elenco di azioni che, se attive, vengono eseguite quando un colono diminuisce di livello un'abilità. - - Cooldown - La durata di un cooldown è specificato in secondi (del tempo reale).\n\nSe viene applicato a un'azione, questa non verrà eseguita per lo stesso colono e stessa abilità fino a quando il cooldown non sarà terminato. - Indipendentemente dal fatto che il cooldown debba essere applicato per questa azione.\n\nSe applicato, l'azione non verrà eseguita nuovamente per lo stesso colono e stessa abilità fino a quando il cooldown non sarà terminato. - - Generale + Cronologia Indipendentemente dal fatto che il messaggio debba essere salvato nella cronologia. @@ -27,4 +22,5 @@ {PAWN} ha raggiunto il livello {LEVEL} in {SKILL}.]]> {SKILL}\nlivello {LEVEL} {SKILL}\nlivello {LEVEL} - \ No newline at end of file + + diff --git a/Languages/PortugueseBrazilian/Keyed/PortugueseBrazilian.xml b/Languages/PortugueseBrazilian/Keyed/PortugueseBrazilian.xml index 3fa0f0c..feb76e6 100644 --- a/Languages/PortugueseBrazilian/Keyed/PortugueseBrazilian.xml +++ b/Languages/PortugueseBrazilian/Keyed/PortugueseBrazilian.xml @@ -2,4 +2,4 @@ {PAWN} chegou ao nível {LEVEL} em {SKILL}.]]> {PAWN} desceu para o nível {LEVEL} em {SKILL}.]]> - \ No newline at end of file + diff --git a/Languages/Russian/Keyed/Russian.xml b/Languages/Russian/Keyed/Russian.xml index 8396952..d0bb9ee 100644 --- a/Languages/Russian/Keyed/Russian.xml +++ b/Languages/Russian/Keyed/Russian.xml @@ -2,4 +2,4 @@ {PAWN} достигнут уровень {LEVEL} в {SKILL}.]]> {PAWN} понижен уровень {LEVEL} в {SKILL}.]]> - \ No newline at end of file + diff --git a/Languages/Spanish/DefInjected/FleckDefs/FleckDefs.xml b/Languages/Spanish/DefInjected/FleckDefs/FleckDefs.xml index 4ac3891..b9066e3 100644 --- a/Languages/Spanish/DefInjected/FleckDefs/FleckDefs.xml +++ b/Languages/Spanish/DefInjected/FleckDefs/FleckDefs.xml @@ -6,4 +6,4 @@ Chevron ascendente Chevron descendente - \ No newline at end of file + diff --git a/Languages/Spanish/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml b/Languages/Spanish/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml index 53d198d..dd0bff5 100644 --- a/Languages/Spanish/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml +++ b/Languages/Spanish/DefInjected/LevelUp.ActionDefs/LevelUp.ActionDefs.xml @@ -13,4 +13,4 @@ Mensaje superior Muestra un mensaje de texto en el colono. - \ No newline at end of file + diff --git a/Languages/Spanish/DefInjected/SoundDefs/SoundDefs.xml b/Languages/Spanish/DefInjected/SoundDefs/SoundDefs.xml index 2d1ffc9..c6c7b82 100644 --- a/Languages/Spanish/DefInjected/SoundDefs/SoundDefs.xml +++ b/Languages/Spanish/DefInjected/SoundDefs/SoundDefs.xml @@ -12,4 +12,4 @@ Rasgueo Fanfarria de Tada - \ No newline at end of file + diff --git a/Languages/Spanish/Keyed/Spanish.xml b/Languages/Spanish/Keyed/Spanish.xml index f9f0f9f..d5307d1 100644 --- a/Languages/Spanish/Keyed/Spanish.xml +++ b/Languages/Spanish/Keyed/Spanish.xml @@ -8,11 +8,6 @@ Lista de acciones que, si están activas, se ejecutan cuando un colono sube de nivel una habilidad. Lista de acciones que, si están activas, se ejecutan cuando un colono baja de nivel una habilidad. - Enfriamiento - La duración de un enfriamiento especificado en segundos en tiempo real.\n\nSi se aplica a una acción, la acción no se ejecutará para el mismo colono y habilidad de nuevo hasta que el enfriamiento se haya agotado. - Si se aplica o no el enfriamiento para esta acción.\n\nSi se aplica, esta acción no se ejecutará para el mismo colono y habilidad nuevamente hasta que se agote el tiempo de reutilización. - - General Histórico Si el mensaje debe guardarse o no en el historial. @@ -27,5 +22,5 @@ {PAWN} ha alcanzado el nivel {LEVEL} en {SKILL}.]]> {SKILL}\nnivel {LEVEL} {SKILL}\nnivel {LEVEL} + - diff --git a/Source/ActionDef.cs b/Source/ActionDef.cs index bfc2f9d..41969ae 100644 --- a/Source/ActionDef.cs +++ b/Source/ActionDef.cs @@ -4,11 +4,9 @@ namespace LevelUp; -[Serializable] -public class ActionDef : Def +public sealed class ActionDef : Def { - private readonly Type actionClass = null!; - public Type ActionClass => actionClass; + internal readonly Type actionClass = null!; public override IEnumerable ConfigErrors() { diff --git a/Source/ActionMaker.cs b/Source/ActionMaker.cs index fe4951d..721df76 100644 --- a/Source/ActionMaker.cs +++ b/Source/ActionMaker.cs @@ -1,5 +1,4 @@ using RimWorld; -using System; using System.Collections.Generic; using UnityEngine; using Verse; @@ -7,41 +6,30 @@ namespace LevelUp; -[Serializable] -public class ActionMaker : IExposable +public sealed class ActionMaker : IExposable { - private List actions = []; + internal List actions = []; private Vector2 scrollPosition; private readonly List preparedActions = []; - private readonly List preparedCooldownActions = []; - public List Actions => actions; - public void Prepare() + internal void Prepare() { preparedActions.Clear(); - preparedCooldownActions.Clear(); foreach (LevelingAction action in actions) { - if (!action.Active) + if (!action.active) { continue; } - if (action.Cooldown) - { - preparedCooldownActions.Add(action); - } - else - { - preparedActions.Add(action); - } + preparedActions.Add(action); action.Prepare(); } } - public void ExecuteActions(LevelingInfo levelingInfo) + internal void ExecuteActions(LevelingInfo levelingInfo) { if (!levelingInfo.Pawn.IsFreeColonist) { @@ -52,24 +40,9 @@ public void ExecuteActions(LevelingInfo levelingInfo) { preparedActions[i].Execute(levelingInfo); } - - bool changedExactlyOneLevel = Math.Abs(levelingInfo.OldLevel - levelingInfo.SkillRecord.Level) == 1; - bool cooldownPassed = PawnSkillTimerCache.EnoughTimeHasPassed(levelingInfo); - - // If changed more than one level we want to ignore cooldown, because this is an event the player probably wants to know about - // E.g. used neurotrainer directly after leveled in that same skill - if (changedExactlyOneLevel && !cooldownPassed) - { - return; - } - - for (int i = 0; i < preparedCooldownActions.Count; i++) - { - preparedCooldownActions[i].Execute(levelingInfo); - } } - public void Draw(Rect rect, ref IDrawer selectedAction) + internal void Draw(Rect rect, ref LevelingAction? selectedAction) { float listHeight = actions.Count * 24f; Rect viewRect = new(rect) { xMax = rect.xMax - 15f, height = listHeight }; @@ -79,17 +52,17 @@ public void Draw(Rect rect, ref IDrawer selectedAction) { LevelingAction action = actions[i]; Rect checkboxRect = new(rowRect) { xMin = rowRect.xMax - rowRect.height, width = rowRect.height }; - bool isActive = action.Active; + bool isActive = action.active; Widgets.Checkbox(checkboxRect.x, checkboxRect.y, ref isActive); - action.Active = isActive; + action.active = isActive; Rect labelRect = new(rowRect) { xMax = checkboxRect.xMin }; - Widgets.Label(labelRect, action.ActionDef.label); + Widgets.Label(labelRect, action.actionDef.label); if (Widgets.ButtonInvisible(labelRect)) { SoundDefOf.Click.PlayOneShotOnCamera(); - selectedAction = selectedAction == action ? Drawer.Empty : action; + selectedAction = selectedAction == action ? null : action; } if (selectedAction == action) diff --git a/Source/Actions/AnimationAction.cs b/Source/Actions/AnimationAction.cs index 7a683cb..6d1e7e0 100644 --- a/Source/Actions/AnimationAction.cs +++ b/Source/Actions/AnimationAction.cs @@ -1,13 +1,12 @@ -using System; +using RimWorld; using System.Collections.Generic; using System.Linq; -using RimWorld; using UnityEngine; using Verse; namespace LevelUp; -public class AnimationAction : LevelingAction +public sealed class AnimationAction : LevelingAction { private FleckDef fleckDef; private Graphic_Single graphic = null!; @@ -26,9 +25,7 @@ internal FleckDef FleckDef public AnimationAction() { - fleckDef = DefDatabase.AllDefs - .Where(x => x.HasModExtension()) - .RandomElement(); + fleckDef = DefOfs.Radiance; Prepare(); } @@ -61,15 +58,11 @@ internal override void Execute(LevelingInfo levelingInfo) internal override void Prepare() { defExtension = fleckDef.GetModExtension(); - - graphic = fleckDef.graphicData.Graphic is Graphic_Single graphicSingle - ? graphicSingle - : throw new InvalidOperationException("Null graphic on FleckDef."); - + graphic = (Graphic_Single)fleckDef.graphicData.Graphic; texture = ContentFinder.Get(fleckDef.graphicData.texPath); } - public override void Draw(Rect rect) + internal override void Draw(Rect rect) { Rect rowRect = new(rect) { height = 24f }; Rect buttonRect = new(rowRect) { width = rowRect.width / 2 }; @@ -85,13 +78,8 @@ public override void Draw(Rect rect) Rect imageRect = new(rect.x, buttonRect.yMax + 10f, rect.width / 2, rect.width / 2); Widgets.DrawMenuSection(imageRect); - DrawGraphic(imageRect); - } - - private void DrawGraphic(Rect rect) - { Widgets.DrawTextureFitted( - outerRect: rect, + outerRect: imageRect, tex: texture, scale: 1f, texProportions: new Vector2(texture.width, texture.height), diff --git a/Source/Actions/LevelingAction.cs b/Source/Actions/LevelingAction.cs index c1a241d..55d12f9 100644 --- a/Source/Actions/LevelingAction.cs +++ b/Source/Actions/LevelingAction.cs @@ -1,37 +1,23 @@ -using System; using UnityEngine; using Verse; namespace LevelUp; -[Serializable] -public abstract class LevelingAction : IExposable, IDrawer +public abstract class LevelingAction : IExposable { - private ActionDef actionDef = null!; - private bool active; - private bool cooldown = true; - - internal ActionDef ActionDef { get => actionDef; set => actionDef = value; } - internal bool Active { get => active; set => active = value; } - internal bool Cooldown { get => cooldown; set => cooldown = value; } + internal ActionDef actionDef = null!; + internal bool active; internal virtual void Prepare() - { - if (actionDef is null) - { - throw new InvalidOperationException("def is null."); - } - } + { } internal abstract void Execute(LevelingInfo levelingInfo); - public virtual void Draw(Rect rect) - { } + internal abstract void Draw(Rect rect); public virtual void ExposeData() { Scribe_Defs.Look(ref actionDef, "def"); Scribe_Values.Look(ref active, "active"); - Scribe_Values.Look(ref cooldown, "cooldown", true); } } diff --git a/Source/Actions/MessageAction.cs b/Source/Actions/MessageAction.cs index b0f5ffd..2cee33c 100644 --- a/Source/Actions/MessageAction.cs +++ b/Source/Actions/MessageAction.cs @@ -1,24 +1,22 @@ -using System; using RimWorld; using UnityEngine; using Verse; namespace LevelUp; -[Serializable] -public class MessageAction : TextAction +public sealed class MessageAction : TextAction { private bool historical; internal override void Execute(LevelingInfo levelingInfo) { - string resolvedText = ResolveText(levelingInfo, Text); + string resolvedText = ResolveText(levelingInfo, text); Message message = new(resolvedText, MessageTypeDefOf.SilentInput, levelingInfo.Pawn); Messages.Message(message, historical); } - public override void Draw(Rect rect) + internal override void Draw(Rect rect) { rect.yMin = DrawTextBuilder(rect).yMax; diff --git a/Source/Actions/OverheadMessageAction.cs b/Source/Actions/OverheadMessageAction.cs index 42f2cbc..0dba954 100644 --- a/Source/Actions/OverheadMessageAction.cs +++ b/Source/Actions/OverheadMessageAction.cs @@ -1,12 +1,10 @@ -using System; using RimWorld; using UnityEngine; using Verse; namespace LevelUp; -[Serializable] -public class OverheadMessageAction : TextAction +public sealed class OverheadMessageAction : TextAction { private bool historical; @@ -18,7 +16,7 @@ internal override void Execute(LevelingInfo levelingInfo) return; } - string resolvedText = ResolveText(levelingInfo, Text); + string resolvedText = ResolveText(levelingInfo, text); MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, resolvedText); if (historical) @@ -28,7 +26,7 @@ internal override void Execute(LevelingInfo levelingInfo) } } - public override void Draw(Rect rect) + internal override void Draw(Rect rect) { rect.yMin = DrawTextBuilder(rect).yMax; diff --git a/Source/Actions/SoundAction.cs b/Source/Actions/SoundAction.cs index a421aa7..7c603e7 100644 --- a/Source/Actions/SoundAction.cs +++ b/Source/Actions/SoundAction.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -7,35 +6,18 @@ namespace LevelUp; -[Serializable] -public class SoundAction : LevelingAction +public sealed class SoundAction : LevelingAction { private const float MinVolume = 0f; private const float MaxVolume = 1.5f; - private SoundDef soundDef = null!; + private SoundDef soundDef = DefOfs.Ding; private float volume = 0.5f; public SoundDef SoundDef { get => soundDef; - set - { - soundDef = value; - Prepare(); - } - } - - public SoundAction() - { - soundDef = DefDatabase.AllDefs - .Where(x => x.HasModExtension()) - .RandomElement(); - } - - internal override void Prepare() - { - base.Prepare(); + set => soundDef = value; } internal override void Execute(LevelingInfo levelingInfo) @@ -45,10 +27,9 @@ internal override void Execute(LevelingInfo levelingInfo) soundDef.PlayOneShot(soundInfo); } - public override void Draw(Rect rect) + internal override void Draw(Rect rect) { Rect rowRect = new(rect) { height = 24f }; - Rect dropDownRect = new(rowRect) { width = rect.width / 2 }; if (Widgets.ButtonText(dropDownRect, soundDef.LabelCap)) diff --git a/Source/Actions/TextAction.cs b/Source/Actions/TextAction.cs index 64582f6..052fd7b 100644 --- a/Source/Actions/TextAction.cs +++ b/Source/Actions/TextAction.cs @@ -1,26 +1,17 @@ -using System; +using RimWorld; using System.Globalization; using System.Text; -using RimWorld; using UnityEngine; using Verse; namespace LevelUp; -[Serializable] public abstract class TextAction : LevelingAction { private static readonly StringBuilder stringBuilder = new(); - private string text = string.Empty; - public string Text { get => text; set => text = value; } - - internal override void Prepare() - { - base.Prepare(); - text ??= string.Empty; - } + internal string text = string.Empty; - protected static string ResolveText(LevelingInfo levelingInfo, string text) + internal static string ResolveText(LevelingInfo levelingInfo, string text) { return ResolveText(levelingInfo.Pawn.LabelShortCap, levelingInfo.SkillRecord.Level, levelingInfo.SkillRecord.def.LabelCap, text); } @@ -45,14 +36,14 @@ protected Rect DrawTextBuilder(Rect rect) Rect rowRect = new(rect) { height = 24f }; Rect exampleTextRect = new(rowRect) { height = rowRect.height * 2 }; - TextAnchor curAnchor = Verse.Text.Anchor; - Verse.Text.Anchor = TextAnchor.MiddleCenter; - Widgets.Label(exampleTextRect, ResolveText(pawnLabel, skillLevel, skillLabel, Text)); - Verse.Text.Anchor = curAnchor; + TextAnchor curAnchor = Text.Anchor; + Text.Anchor = TextAnchor.MiddleCenter; + Widgets.Label(exampleTextRect, ResolveText(pawnLabel, skillLevel, skillLabel, text)); + Text.Anchor = curAnchor; rowRect.y = rowRect.yMax + 5f; Rect textEntryRect = new(rowRect) { y = exampleTextRect.yMax, height = rowRect.height * 3 }; - text = Widgets.TextArea(textEntryRect, Text); + text = Widgets.TextArea(textEntryRect, text); rowRect.y = textEntryRect.yMax + 5f; Rect guideRect = new(rowRect) { height = 24f * 11 }; @@ -60,7 +51,7 @@ protected Rect DrawTextBuilder(Rect rect) Widgets.DrawMenuSection(guideRect); Rect guideRowRect = new(innerGuideRect) { height = 24f }; Rect label2Rect = new(guideRowRect) { x = guideRowRect.x + (guideRowRect.width / 2) }; - Widgets.Label(guideRowRect, I18n.InjectableValuesLabel.Bold()); + Widgets.Label(guideRowRect, $"{I18n.InjectableValuesLabel}"); guideRowRect.y = guideRowRect.yMax; label2Rect.y = label2Rect.yMax; @@ -79,34 +70,34 @@ protected Rect DrawTextBuilder(Rect rect) guideRowRect.y = guideRowRect.yMax + 5f; label2Rect.y = label2Rect.yMax + 5f; - Widgets.Label(guideRowRect, I18n.FormattingLabel.Bold()); + Widgets.Label(guideRowRect, $"{I18n.FormattingLabel}"); guideRowRect.y = guideRowRect.yMax; label2Rect.y = label2Rect.yMax; - Verse.Text.CurFontStyle.richText = false; - Widgets.Label(guideRowRect, I18n.FormattingBoldLabel.Bold()); - Verse.Text.CurFontStyle.richText = true; - Widgets.Label(label2Rect, I18n.FormattingBoldLabel.Bold()); + Text.CurFontStyle.richText = false; + Widgets.Label(guideRowRect, $"{I18n.FormattingBoldLabel}"); + Text.CurFontStyle.richText = true; + Widgets.Label(label2Rect, $"{I18n.FormattingBoldLabel}"); guideRowRect.y = guideRowRect.yMax; label2Rect.y = label2Rect.yMax; - Verse.Text.CurFontStyle.richText = false; - Widgets.Label(guideRowRect, I18n.FormattingItalicLabel.Italic()); - Verse.Text.CurFontStyle.richText = true; - Widgets.Label(label2Rect, I18n.FormattingItalicLabel.Italic()); + Text.CurFontStyle.richText = false; + Widgets.Label(guideRowRect, $"{I18n.FormattingItalicLabel}"); + Text.CurFontStyle.richText = true; + Widgets.Label(label2Rect, $"{I18n.FormattingItalicLabel}"); guideRowRect.y = guideRowRect.yMax; label2Rect.y = label2Rect.yMax; - Verse.Text.CurFontStyle.richText = false; + Text.CurFontStyle.richText = false; Widgets.Label(guideRowRect, $"{I18n.FormattingColorLabel}"); - Verse.Text.CurFontStyle.richText = true; + Text.CurFontStyle.richText = true; Widgets.Label(label2Rect, $"{I18n.FormattingColorLabel}"); guideRowRect.y = guideRowRect.yMax; label2Rect.y = label2Rect.yMax; - Verse.Text.CurFontStyle.richText = false; + Text.CurFontStyle.richText = false; Widgets.Label(guideRowRect, $"{I18n.FormattingColorLabel}"); - Verse.Text.CurFontStyle.richText = true; + Text.CurFontStyle.richText = true; Widgets.Label(label2Rect, $"{I18n.FormattingColorLabel}"); return new Rect(rect) { yMax = guideRect.yMax + 15f }; diff --git a/Source/CooldownTracker.cs b/Source/CooldownTracker.cs deleted file mode 100644 index 6c29855..0000000 --- a/Source/CooldownTracker.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Verse; - -namespace LevelUp; - -internal sealed class CooldownTracker -{ - private const int CooldownSecondsDefault = 20; - - private Dictionary cache = []; - internal int cooldownSeconds = CooldownSecondsDefault; - - internal bool EnoughTimeHasPassed(LevelingInfo levelingInfo) - { - DateTime now = DateTime.UtcNow; - - int key = levelingInfo.Pawn.GetHashCode() + levelingInfo.SkillRecord.def.GetHashCode(); - - if (cache.TryGetValue(key, out DateTime lastCacheTime)) - { - if (lastCacheTime.AddSeconds(cooldownSeconds) > now) - { - return false; - } - } - - cache[key] = now; - - return true; - } - - internal void ExposeData() - { - Scribe_Values.Look(ref cooldownSeconds, "cooldownSeconds", CooldownSecondsDefault); - - if (Scribe.mode == LoadSaveMode.Saving) - { - UpdateCache(); - } - } - - internal void UpdateCache() - { - cache = cache.Where(ShouldKeepEntry).ToDictionary(x => x.Key, x => x.Value); - } - - private bool ShouldKeepEntry(KeyValuePair entry) - { - TimeSpan cooldown = TimeSpan.FromSeconds(cooldownSeconds); - DateTime now = DateTime.UtcNow; - - return entry.Value + cooldown < now; - } -} diff --git a/Source/DefOfs.cs b/Source/DefOfs.cs new file mode 100644 index 0000000..e6487c8 --- /dev/null +++ b/Source/DefOfs.cs @@ -0,0 +1,25 @@ +using RimWorld; +using Verse; + +namespace LevelUp; + +[DefOf] +internal static class DefOfs +{ + static DefOfs() + { + DefOfHelper.EnsureInitializedInCtor(typeof(DefOfs)); + } + + [DefAlias("LevelUpAnimation_Radiance")] + public static FleckDef Radiance = null!; + + [DefAlias("LevelUpAnimation_Drain")] + public static FleckDef Drain = null!; + + [DefAlias("LevelUpSound_Ding")] + public static SoundDef Ding = null!; + + [DefAlias("LevelUpSound_Negative")] + public static SoundDef Negative = null!; +} diff --git a/Source/Drawer.cs b/Source/Drawer.cs deleted file mode 100644 index 5bdc62b..0000000 --- a/Source/Drawer.cs +++ /dev/null @@ -1,14 +0,0 @@ -using UnityEngine; - -namespace LevelUp; - -public sealed class Drawer : IDrawer -{ - public static IDrawer Empty { get; } = new Drawer(); - - private Drawer() - { } - - public void Draw(Rect rect) - { } -} diff --git a/Source/GeneralSettingsContent.cs b/Source/GeneralSettingsContent.cs deleted file mode 100644 index f2c22ac..0000000 --- a/Source/GeneralSettingsContent.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using UnityEngine; -using Verse; - -namespace LevelUp; - -[Serializable] -public class GeneralSettingsContent : IExposable, IDrawer -{ - private int cooldownSeconds = 20; - private string? cooldownEditBuffer; - - public int CooldownSeconds => cooldownSeconds; - - public void Draw(Rect rect) - { - Rect rowRect = new(rect) { height = 24f }; - string cooldownLabel = I18n.CooldownLabel; - Vector2 cooldownSize = Text.CalcSize(cooldownLabel); - Rect cooldownLabelRect = new(rowRect) { width = cooldownSize.x }; - Widgets.Label(cooldownLabelRect, cooldownLabel); - TooltipHandler.TipRegion(cooldownLabelRect, I18n.CooldownEntryDescription); - Rect cooldownEntryRect = new(rowRect) { x = cooldownLabelRect.xMax + 5f, width = 180f }; - Widgets.IntEntry(cooldownEntryRect, ref cooldownSeconds, ref cooldownEditBuffer); - } - - public void ExposeData() - { - Scribe_Values.Look(ref cooldownSeconds, "cooldownSeconds"); - } -} diff --git a/Source/HarmonyPatching.cs b/Source/HarmonyPatching.cs deleted file mode 100644 index ddde4ea..0000000 --- a/Source/HarmonyPatching.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Reflection; -using HarmonyLib; -using RimWorld; -using UnityEngine; -using Verse; - -namespace LevelUp; - -[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Injected Harmony parameters must be prefixed with underscores")] -public static class HarmonyPatching -{ - internal static void ApplyPatches(Harmony harmony) - { - MethodInfo skillRecordLearnOriginal = AccessTools.Method(typeof(SkillRecord), nameof(SkillRecord.Learn)); - MethodInfo skillRecordDirtyAptitudesOriginal = AccessTools.Method(typeof(SkillRecord), nameof(SkillRecord.DirtyAptitudes)); - MethodInfo compUseEffectLearnSkillDoEffectOriginal = AccessTools.Method(typeof(CompUseEffect_LearnSkill), nameof(CompUseEffect_LearnSkill.DoEffect)); - - HarmonyMethod prefix = new(typeof(HarmonyPatching), nameof(Prefix)); - HarmonyMethod postfix = new(typeof(HarmonyPatching), nameof(Postfix)); - - HarmonyMethod removeMoteThrowCallTranspiler = new(typeof(HarmonyPatching), nameof(RemoveMoteThrowCall)); - HarmonyMethod removeMessageCallTranspiler = new(typeof(HarmonyPatching), nameof(RemoveMessageCall)); - - harmony.Patch(skillRecordLearnOriginal, prefix, postfix, removeMoteThrowCallTranspiler); - harmony.Patch(skillRecordDirtyAptitudesOriginal, prefix, postfix); - - harmony.Patch(compUseEffectLearnSkillDoEffectOriginal, transpiler: removeMessageCallTranspiler); - } - - private static void Prefix(out int __state, SkillRecord __instance) - { - __state = __instance.Level; - } - - private static void Postfix(int __state, Pawn ___pawn, SkillRecord __instance) - { - int previousLevel = __state; - int currentLevel = __instance.Level; - - if (currentLevel == previousLevel) - { - return; - } - else if (currentLevel > previousLevel) - { - Notifier.OnLevelUp(__instance, ___pawn); - } - else - { - Notifier.OnLevelDown(__instance, ___pawn); - } - } - - private static IEnumerable RemoveMoteThrowCall(IEnumerable instructions) - { - MethodInfo original = SymbolExtensions.GetMethodInfo(() => MoteMaker.ThrowText(default, default, default, default)); - MethodInfo replacement = SymbolExtensions.GetMethodInfo(() => MoteThrowTextProxy); - - return instructions.MethodReplacer(original, replacement); - } - - private static IEnumerable RemoveMessageCall(IEnumerable instructions) - { - MethodInfo original = SymbolExtensions.GetMethodInfo(() => Messages.Message(default, default, default, default)); - MethodInfo replacement = SymbolExtensions.GetMethodInfo(() => MessageProxy); - - return instructions.MethodReplacer(original, replacement); - } - - private static void MoteThrowTextProxy(Vector3 loc, Map map, string text, float timeBeforeStartFadeout) - { } - - private static void MessageProxy(string text, LookTargets lookTargets, MessageTypeDef def, bool historical) - { } -} diff --git a/Source/I18n.cs b/Source/I18n.cs index edc9a72..a3c50d0 100644 --- a/Source/I18n.cs +++ b/Source/I18n.cs @@ -1,6 +1,7 @@ using Verse; namespace LevelUp; + internal static class I18n { private const string TranslatePrefix = "LevelUp."; @@ -8,10 +9,6 @@ internal static class I18n internal static string LevelDownActionsLabel { get; } = "LevelDownActionsLabel".TranslateInternal(); internal static string LevelUpActionHeaderDescription { get; } = "LevelUpActionHeaderDescription".TranslateInternal(); internal static string LevelDownActionHeaderDescription { get; } = "LevelDownActionHeaderDescription".TranslateInternal(); - internal static string CooldownLabel { get; } = "CooldownLabel".TranslateInternal(); - internal static string CooldownEntryDescription { get; } = "CooldownEntryDescription".TranslateInternal(); - internal static string CooldownOnActionDescription { get; } = "CooldownOnActionDescription".TranslateInternal(); - internal static string GeneralSettingsLabel { get; } = "GeneralSettingsLabel".TranslateInternal(); internal static string HistoricalLabel { get; } = "HistoricalLabel".TranslateInternal(); internal static string HistoricalDescription { get; } = "HistoricalDescription".TranslateInternal(); internal static string InjectableValuesLabel { get; } = "InjectableValuesLabel".TranslateInternal(); diff --git a/Source/IDrawer.cs b/Source/IDrawer.cs deleted file mode 100644 index c0cdf4d..0000000 --- a/Source/IDrawer.cs +++ /dev/null @@ -1,8 +0,0 @@ -using UnityEngine; - -namespace LevelUp; - -public interface IDrawer -{ - void Draw(Rect rect); -} diff --git a/Source/LevelUpMod.cs b/Source/LevelUpMod.cs index 22f774b..f7b0bb6 100644 --- a/Source/LevelUpMod.cs +++ b/Source/LevelUpMod.cs @@ -4,12 +4,13 @@ namespace LevelUp; -public class LevelUpMod : Mod +public sealed class LevelUpMod : Mod { public LevelUpMod(ModContentPack content) : base(content) { - Harmony harmony = new("krafs.levelup"); - HarmonyPatching.ApplyPatches(harmony); + Harmony harmony = new(content.PackageId); + Patcher.ApplyPatches(harmony); + LongEventHandler.ExecuteWhenFinished(() => LoadedModManager.GetMod().GetSettings()); } public override string SettingsCategory() @@ -19,6 +20,6 @@ public override string SettingsCategory() public override void DoSettingsWindowContents(Rect inRect) { - GetSettings().Profile.Draw(inRect); + Settings.profile.Draw(inRect); } } diff --git a/Source/LevelingInfo.cs b/Source/LevelingInfo.cs index 5419099..138038b 100644 --- a/Source/LevelingInfo.cs +++ b/Source/LevelingInfo.cs @@ -3,8 +3,8 @@ namespace LevelUp; -public readonly ref struct LevelingInfo(Pawn pawn, SkillRecord skillRecord) +internal readonly ref struct LevelingInfo(Pawn pawn, SkillRecord skillRecord) { - public readonly Pawn Pawn => pawn; - public readonly SkillRecord SkillRecord => skillRecord; + internal readonly Pawn Pawn => pawn; + internal readonly SkillRecord SkillRecord => skillRecord; } diff --git a/Source/Notifier.cs b/Source/Notifier.cs deleted file mode 100644 index 841b0b7..0000000 --- a/Source/Notifier.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RimWorld; -using Verse; - -namespace LevelUp; - -[StaticConstructorOnStartup] -public static class Notifier -{ - static Notifier() - { - // Force initialize Settings to make sure profile is set up. - _ = LoadedModManager.GetMod().GetSettings().Profile; - } - - public static void OnLevelUp(SkillRecord skillRecord, Pawn pawn) - { - Settings.CurrentProfile.LevelUpActionMaker.ExecuteActions(new LevelingInfo(pawn, skillRecord)); - } - - public static void OnLevelDown(SkillRecord skillRecord, Pawn pawn) - { - Settings.CurrentProfile.LevelDownActionMaker.ExecuteActions(new LevelingInfo(pawn, skillRecord)); - } -} diff --git a/Source/Patcher.cs b/Source/Patcher.cs new file mode 100644 index 0000000..7d74b80 --- /dev/null +++ b/Source/Patcher.cs @@ -0,0 +1,129 @@ +using HarmonyLib; +using RimWorld; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using UnityEngine; +using Verse; + +namespace LevelUp; + +internal static class Patcher +{ + internal static void ApplyPatches(Harmony harmony) + { + MethodInfo skillRecordLearnOriginal = AccessTools.Method(typeof(SkillRecord), nameof(SkillRecord.Learn)); + MethodInfo skillRecordDirtyAptitudesOriginal = AccessTools.Method(typeof(SkillRecord), nameof(SkillRecord.DirtyAptitudes)); + MethodInfo compUseEffectLearnSkillDoEffectOriginal = AccessTools.Method(typeof(CompUseEffect_LearnSkill), nameof(CompUseEffect_LearnSkill.DoEffect)); + + HarmonyMethod prefix = new(typeof(Patcher), nameof(Prefix)); + HarmonyMethod dirtyAptitudesPostfix = new(typeof(Patcher), nameof(DirtyAptitudesPostfix)); + HarmonyMethod learnPostfix = new(typeof(Patcher), nameof(LearnPostfix)); + + HarmonyMethod removeMoteThrowCallTranspiler = new(typeof(Patcher), nameof(RemoveMoteThrowCall)); + HarmonyMethod removeMessageCallTranspiler = new(typeof(Patcher), nameof(RemoveMessageCall)); + + harmony.Patch(skillRecordLearnOriginal, prefix, learnPostfix, removeMoteThrowCallTranspiler); + harmony.Patch(skillRecordDirtyAptitudesOriginal, prefix, dirtyAptitudesPostfix); + + harmony.Patch(compUseEffectLearnSkillDoEffectOriginal, transpiler: removeMessageCallTranspiler); + } + + [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Harmony naming convention")] + private static void Prefix(out int __state, SkillRecord __instance) + { + __state = __instance.Level; + } + + [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Harmony naming convention")] + private static void DirtyAptitudesPostfix(int __state, SkillRecord __instance, Pawn ___pawn) + { + int previousLevel = __state; + int currentLevel = __instance.Level; + + if (currentLevel == previousLevel) + { + return; + } + else if (currentLevel > previousLevel) + { + Settings.profile.levelUpActionMaker.ExecuteActions(new LevelingInfo(___pawn, __instance)); + } + else + { + Settings.profile.levelDownActionMaker.ExecuteActions(new LevelingInfo(___pawn, __instance)); + } + } + + [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Harmony naming convention")] + private static void LearnPostfix(int __state, SkillRecord __instance, Pawn ___pawn, bool direct) + { + int previousLevel = __state; + int currentLevel = __instance.Level; + + if (currentLevel == previousLevel) + { + return; + } + + bool isProbablyNaturalLearningOrDecay = !direct; + if (isProbablyNaturalLearningOrDecay) + { + // Likely unnecessarily optimized cache :/ + int currentTime = (int)Time.time; + int pawnHash = ___pawn.GetHashCode(); + ushort defHash = __instance.def.shortHash; + // Ensure that defHash fits within the upper 16 bits + pawnHash &= 0xFFFF; // Mask the upper 16 bits to ensure they are clear + + // Combine pawnHash and defHash + int key = (pawnHash << 16) | defHash; + if (Settings.timerCache.TryGetValue(key, out int nextAllowedTime)) + { + bool enoughTimeHasPassed = currentTime > nextAllowedTime; + if (enoughTimeHasPassed) + { + Settings.timerCache.Remove(key); + } + else + { + return; + } + } + + Settings.timerCache[key] = currentTime + 20; + } + + LevelingInfo levelingInfo = new(___pawn, __instance); + if (currentLevel > previousLevel) + { + Settings.profile.levelUpActionMaker.ExecuteActions(levelingInfo); + } + else + { + Settings.profile.levelDownActionMaker.ExecuteActions(levelingInfo); + } + } + + private static IEnumerable RemoveMoteThrowCall(IEnumerable instructions) + { + MethodInfo original = SymbolExtensions.GetMethodInfo(() => MoteMaker.ThrowText(default, default, default, default)); + MethodInfo replacement = SymbolExtensions.GetMethodInfo(() => MoteThrowTextProxy); + + return instructions.MethodReplacer(original, replacement); + } + + private static IEnumerable RemoveMessageCall(IEnumerable instructions) + { + MethodInfo original = SymbolExtensions.GetMethodInfo(() => Messages.Message(default, default, default, default)); + MethodInfo replacement = SymbolExtensions.GetMethodInfo(() => MessageProxy); + + return instructions.MethodReplacer(original, replacement); + } + + private static void MoteThrowTextProxy(Vector3 loc, Map map, string text, float timeBeforeStartFadeout) + { } + + private static void MessageProxy(string text, LookTargets lookTargets, MessageTypeDef def, bool historical) + { } +} diff --git a/Source/PawnSkillTimerCache.cs b/Source/PawnSkillTimerCache.cs deleted file mode 100644 index 2ac8eaa..0000000 --- a/Source/PawnSkillTimerCache.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using RimWorld; -using Verse; - -namespace LevelUp; - -public static class PawnSkillTimerCache -{ - private static readonly Dictionary, DateTime> timerCache = []; - private static readonly Settings settings = LoadedModManager.GetMod().GetSettings(); - - public static bool EnoughTimeHasPassed(LevelingInfo levelingInfo) - { - DateTime currentDateTime = DateTime.UtcNow; - (Pawn, SkillDef) key = new(levelingInfo.Pawn, levelingInfo.SkillRecord.def); - if (timerCache.TryGetValue(key, out DateTime lastEntryDateTime)) - { - DateTime nextAllowedDateTime = lastEntryDateTime.AddSeconds(settings.Profile.GeneralSettingsContent.CooldownSeconds); - if (currentDateTime < nextAllowedDateTime) - { - return false; - } - } - - timerCache[key] = currentDateTime; - - return true; - } -} diff --git a/Source/Profile.cs b/Source/Profile.cs index 00e8ab1..cdbdbff 100644 --- a/Source/Profile.cs +++ b/Source/Profile.cs @@ -1,37 +1,21 @@ -using System; -using RimWorld; using UnityEngine; using Verse; -using Verse.Sound; namespace LevelUp; -[Serializable] -public class Profile : IExposable +public sealed class Profile : IExposable { - private ActionMaker levelUpActionMaker; - private ActionMaker levelDownActionMaker; - private GeneralSettingsContent generalSettingsContent; - private IDrawer selected = Drawer.Empty; + internal ActionMaker levelUpActionMaker = new(); + internal ActionMaker levelDownActionMaker = new(); + private LevelingAction? selected; - public ActionMaker LevelUpActionMaker => levelUpActionMaker; - public ActionMaker LevelDownActionMaker => levelDownActionMaker; - public GeneralSettingsContent GeneralSettingsContent => generalSettingsContent; - - public Profile() - { - levelUpActionMaker = new ActionMaker(); - levelDownActionMaker = new ActionMaker(); - generalSettingsContent = new GeneralSettingsContent(); - } - - public void Prepare() + internal void Prepare() { levelUpActionMaker.Prepare(); levelDownActionMaker.Prepare(); } - public void Draw(Rect rect) + internal void Draw(Rect rect) { Rect leftRect = new(rect) { width = rect.width / 3 }; Rect rightRect = new(rect) { xMin = leftRect.xMax }; @@ -47,23 +31,17 @@ public void Draw(Rect rect) private void DoLeft(Rect rect) { - Rect generalRect = new(rect) { height = 24f, xMax = rect.xMax - 15f }; - DoGeneralRect(generalRect); - - Widgets.DrawLineHorizontal(generalRect.x, generalRect.yMax + 5f, generalRect.width); - Rect levelList = new(rect) { yMin = generalRect.yMax + 10f }; + Rect levelUpListRect = new(rect) { height = rect.height / 2 }; + DoList(levelUpListRect, levelUpActionMaker, I18n.LevelUpActionsLabel, I18n.LevelUpActionHeaderDescription); - Rect levelUpListRect = new(levelList) { height = levelList.height / 2 }; - DoList(levelUpListRect, LevelUpActionMaker, I18n.LevelUpActionsLabel, I18n.LevelUpActionHeaderDescription); - - Rect levelDownListRect = new(levelList) { yMin = levelUpListRect.yMax }; - DoList(levelDownListRect, LevelDownActionMaker, I18n.LevelDownActionsLabel, I18n.LevelDownActionHeaderDescription); + Rect levelDownListRect = new(rect) { yMin = levelUpListRect.yMax }; + DoList(levelDownListRect, levelDownActionMaker, I18n.LevelDownActionsLabel, I18n.LevelDownActionHeaderDescription); } private void DoList(Rect rect, ActionMaker actionMaker, string header, string headerTooltip) { Rect labelRect = new(rect) { height = 24f, xMax = rect.xMax - 15f }; - Widgets.Label(labelRect, header.Bold()); + Widgets.Label(labelRect, $"{header}"); TooltipHandler.TipRegion(labelRect, headerTooltip); Widgets.DrawHighlight(labelRect); @@ -72,59 +50,24 @@ private void DoList(Rect rect, ActionMaker actionMaker, string header, string he actionMaker.Draw(rect, ref selected); } - private void DoGeneralRect(Rect rect) - { - string generalLabel = I18n.GeneralSettingsLabel; - Widgets.Label(rect, generalLabel.Bold()); - Widgets.DrawLightHighlight(rect); - if (Widgets.ButtonInvisible(rect)) - { - SoundDefOf.Click.PlayOneShotOnCamera(); - selected = selected == GeneralSettingsContent ? Drawer.Empty : GeneralSettingsContent; - } - - if (selected == GeneralSettingsContent) - { - Widgets.DrawHighlightSelected(rect); - } - else if (Mouse.IsOver(rect)) - { - Widgets.DrawHighlight(rect); - } - } - private void DoRight(Rect rect) { - if (selected is LevelingAction selectedAction) - { - DoActionContent(rect, ref selectedAction); - } - else + if (selected is not null) { - selected.Draw(rect); + DoActionContent(rect, ref selected); } } private static void DoActionContent(Rect rect, ref LevelingAction selectedAction) { Rect rowRect = new(rect) { height = 24f }; - Rect cooldownCheckbox = new(rowRect) { xMin = rowRect.xMax - rowRect.height }; - string cooldownLabel = I18n.CooldownLabel; - Vector2 cooldownLabelSize = Text.CalcSize(cooldownLabel); - Rect cooldownLabelRect = new(cooldownCheckbox.xMin - cooldownLabelSize.x, rowRect.y, cooldownLabelSize.x, rowRect.height); - Widgets.Label(cooldownLabelRect, cooldownLabel); - - TooltipHandler.TipRegion(cooldownLabelRect, I18n.CooldownOnActionDescription); - bool hasCooldown = selectedAction.Cooldown; - Widgets.Checkbox(cooldownCheckbox.x, cooldownCheckbox.y, ref hasCooldown); - selectedAction.Cooldown = hasCooldown; - - string actionLabel = selectedAction.ActionDef.label; + + string actionLabel = selectedAction.actionDef.label; Vector2 actionLabelSize = Text.CalcSize(actionLabel); actionLabelSize.x += 15f; Rect actionLabelRect = new(rowRect) { width = actionLabelSize.x }; - Widgets.Label(actionLabelRect, selectedAction.ActionDef.label.Bold()); - TooltipHandler.TipRegion(actionLabelRect, selectedAction.ActionDef.description); + Widgets.Label(actionLabelRect, $"{selectedAction.actionDef.label}"); + TooltipHandler.TipRegion(actionLabelRect, selectedAction.actionDef.description); rect.y = rowRect.yMax; Widgets.DrawLineHorizontal(rect.x, rect.y, rect.width); @@ -137,6 +80,5 @@ public void ExposeData() { Scribe_Deep.Look(ref levelUpActionMaker, "levelUpActionMaker"); Scribe_Deep.Look(ref levelDownActionMaker, "levelDownActionMaker"); - Scribe_Deep.Look(ref generalSettingsContent, "generalSettingsContent"); } } diff --git a/Source/ProfileInitializer.cs b/Source/ProfileInitializer.cs index 0a1f626..f51882e 100644 --- a/Source/ProfileInitializer.cs +++ b/Source/ProfileInitializer.cs @@ -3,77 +3,77 @@ namespace LevelUp; -public static class ProfileInitializer +internal static class ProfileInitializer { - public static void InitializeProfile(Profile profile) + internal static void InitializeProfile(Profile profile) { // Level up foreach (ActionDef actionDef in DefDatabase.AllDefs) { - if (!profile.LevelUpActionMaker.Actions.Any(x => x.ActionDef == actionDef)) + if (!profile.levelUpActionMaker.actions.Any(x => x.actionDef == actionDef)) { - if (Activator.CreateInstance(actionDef.ActionClass) is not LevelingAction action) + if (Activator.CreateInstance(actionDef.actionClass) is not LevelingAction action) { throw new InvalidOperationException("action is null"); } - action.ActionDef = actionDef; - profile.LevelUpActionMaker.Actions.Add(action); + action.actionDef = actionDef; + profile.levelUpActionMaker.actions.Add(action); if (action is SoundAction soundAction) { - soundAction.Active = true; - soundAction.SoundDef = DefDatabase.GetNamed("LevelUpSound_Ding"); + soundAction.active = true; + soundAction.SoundDef = DefOfs.Ding; } else if (action is MessageAction messageAction) { - messageAction.Active = true; - messageAction.Text = I18n.DefaultLevelUpMessage; + messageAction.active = true; + messageAction.text = I18n.DefaultLevelUpMessage; } else if (action is OverheadMessageAction overheadMessageAction) { - overheadMessageAction.Text = I18n.DefaultLevelUpOverheadMessage; + overheadMessageAction.text = I18n.DefaultLevelUpOverheadMessage; } else if (action is AnimationAction animationAction) { - animationAction.Active = true; - animationAction.FleckDef = DefDatabase.GetNamed("LevelUpAnimation_Radiance"); + animationAction.active = true; + animationAction.FleckDef = DefOfs.Radiance; } } } - profile.LevelUpActionMaker.Actions.SortBy(x => x.ActionDef.LabelCap.RawText); + profile.levelUpActionMaker.actions.SortBy(x => x.actionDef.LabelCap.RawText); // Level down foreach (ActionDef actionDef in DefDatabase.AllDefs) { - if (!profile.LevelDownActionMaker.Actions.Any(x => x.ActionDef == actionDef)) + if (!profile.levelDownActionMaker.actions.Any(x => x.actionDef == actionDef)) { - if (Activator.CreateInstance(actionDef.ActionClass) is not LevelingAction action) + if (Activator.CreateInstance(actionDef.actionClass) is not LevelingAction action) { throw new InvalidOperationException("action is null"); } - action.ActionDef = actionDef; - profile.LevelDownActionMaker.Actions.Add(action); + action.actionDef = actionDef; + profile.levelDownActionMaker.actions.Add(action); if (action is SoundAction soundAction) { - soundAction.SoundDef = DefDatabase.GetNamed("LevelUpSound_Negative"); + soundAction.SoundDef = DefOfs.Negative; } else if (action is MessageAction messageAction) { - messageAction.Text = I18n.DefaultLevelDownMessage; + messageAction.text = I18n.DefaultLevelDownMessage; } else if (action is OverheadMessageAction overheadMessageAction) { - overheadMessageAction.Text = I18n.DefaultLevelDownOverheadMessage; + overheadMessageAction.text = I18n.DefaultLevelDownOverheadMessage; } else if (action is AnimationAction animationAction) { - animationAction.FleckDef = DefDatabase.GetNamed("LevelUpAnimation_Drain"); + animationAction.FleckDef = DefOfs.Drain; } } } - profile.LevelDownActionMaker.Actions.SortBy(x => x.ActionDef.LabelCap.RawText); + profile.levelDownActionMaker.actions.SortBy(x => x.actionDef.LabelCap.RawText); } } diff --git a/Source/Settings.cs b/Source/Settings.cs index e4887e9..dd05d6d 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -1,14 +1,12 @@ -using System; +using System.Collections.Generic; using Verse; namespace LevelUp; -[Serializable] -public class Settings : ModSettings +public sealed class Settings : ModSettings { - private Profile profile = null!; - public Profile Profile => profile; - public static Profile CurrentProfile { get; private set; } = null!; + internal static Dictionary timerCache = []; + internal static Profile profile = new(); public Settings() { @@ -31,9 +29,8 @@ public override void ExposeData() } } - private void EnsureInitialized() + private static void EnsureInitialized() { - CurrentProfile = profile ??= new Profile(); ProfileInitializer.InitializeProfile(profile); profile.Prepare(); } diff --git a/Source/SoundDefExtension.cs b/Source/SoundDefExtension.cs index 04e5512..293317c 100644 --- a/Source/SoundDefExtension.cs +++ b/Source/SoundDefExtension.cs @@ -2,5 +2,4 @@ namespace LevelUp; -internal sealed class SoundDefExtension : DefModExtension -{ } +internal sealed class SoundDefExtension : DefModExtension; diff --git a/Source/StringFormatExtensions.cs b/Source/StringFormatExtensions.cs deleted file mode 100644 index 7e4ed0c..0000000 --- a/Source/StringFormatExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace LevelUp; - -internal static class StringFormatExtensions -{ - internal static string Bold(this string str) - { - return $"{str}"; - } - - internal static string Italic(this string str) - { - return $"{str}"; - } -} diff --git a/Textures/LevelUp/Icon.png b/Textures/LevelUp/Icon.png index 7e32755..3489d48 100644 Binary files a/Textures/LevelUp/Icon.png and b/Textures/LevelUp/Icon.png differ