diff --git a/Mods/Events/a_plague_descends.json b/Mods/Events/a_plague_descends.json new file mode 100644 index 0000000..ad9444d --- /dev/null +++ b/Mods/Events/a_plague_descends.json @@ -0,0 +1,37 @@ +{ + "id": "event_plague_descends", + "title": "A Plague Descends", + "description": "A virulent disease is sweeping through the population, sickening your followers and halting progress. Drastic measures may be required.", + "meanTimeToHappen": 300, + "trigger": { + "minFollowers": 500, + "maxCorruption": 80 + }, + "options": [ + { + "text": "We must sacrifice the sick.", + "tooltip": "Immediately lose 20% of your Followers, but the plague is stopped.", + "effects": [ + { + "type": "ModifyStat", + "targetStat": "Followers", + "op": "Multiply", + "value": 0.8 + } + ] + }, + { + "text": "We will pray for their recovery.", + "tooltip": "Lose all passive Follower generation for 120 seconds as the plague runs its course.", + "effects": [ + { + "type": "ApplyBuff", + "buffId": "plague_debuff", + "targetStat": "FollowersPerSecond", + "multiplier": 0, + "duration": 120 + } + ] + } + ] +} diff --git a/Mods/Events/a_prophets_rise.json b/Mods/Events/a_prophets_rise.json new file mode 100644 index 0000000..8c0800a --- /dev/null +++ b/Mods/Events/a_prophets_rise.json @@ -0,0 +1,34 @@ +{ + "id": "event_prophets_rise", + "title": "A Prophet's Rise", + "description": "A charismatic leader has emerged among your followers, inspiring them to new heights of devotion and ingenuity. How shall you guide their efforts?", + "meanTimeToHappen": 200, + "trigger": { + "minFollowers": 800, + "maxCorruption": 60 + }, + "options": [ + { + "text": "Focus their zeal on industry.", + "tooltip": "Gain a large, one-time boost to Production.", + "effects": [ + { + "type": "AddResource", + "targetResource": "Production", + "value": 750 + } + ] + }, + { + "text": "Inspire a population boom.", + "tooltip": "Gain a large, one-time boost to Followers.", + "effects": [ + { + "type": "AddResource", + "targetResource": "Followers", + "value": 250 + } + ] + } + ] +} diff --git a/Mods/Events/divine_inspiration.json b/Mods/Events/divine_inspiration.json new file mode 100644 index 0000000..5aa46ae --- /dev/null +++ b/Mods/Events/divine_inspiration.json @@ -0,0 +1,38 @@ +{ + "id": "event_divine_inspiration", + "title": "Divine Inspiration", + "description": "You feel a surge of pure cosmic energy. You can channel this power to inspire your followers in their efforts to either build or cleanse.", + "meanTimeToHappen": 250, + "trigger": { + "minFollowers": 1500, + "maxCorruption": 75 + }, + "options": [ + { + "text": "Inspire frantic construction.", + "tooltip": "Greatly increases all passive Production for 2 minutes.", + "effects": [ + { + "type": "ApplyBuff", + "buffId": "inspiration_production_buff", + "targetStat": "ProductionPerSecond", + "multiplier": 3, + "duration": 120 + } + ] + }, + { + "text": "Inspire planetary healing.", + "tooltip": "Greatly reduces all passive Corruption for 2 minutes.", + "effects": [ + { + "type": "ApplyBuff", + "buffId": "inspiration_cleansing_buff", + "targetStat": "CorruptionPerSecond", + "multiplier": -2, + "duration": 120 + } + ] + } + ] +} diff --git a/Mods/Events/doomsday.json b/Mods/Events/doomsday.json new file mode 100644 index 0000000..ea6f45b --- /dev/null +++ b/Mods/Events/doomsday.json @@ -0,0 +1,24 @@ +{ + "id": "event_dooms_day", + "title": "DOOMS DAY!", + "description": "A catastrophic event is unfolding, threatening to annihilate everything in its path", + "meanTimeToHappen": 2000, + "trigger": { + "minFollowers": 500, + "maxCorruption": 99 + }, + "options": [ + { + "text": "NOT TODAY...", + "tooltip": "Increase Corruption by 200. (Instant game over)", + "effects": [ + { + "type": "ModifyStat", + "targetStat": "Corruption", + "op": "Add", + "value": 200 + } + ] + } + ] +} diff --git a/Mods/Events/ecological_collapse.json b/Mods/Events/ecological_collapse.json new file mode 100644 index 0000000..87296d9 --- /dev/null +++ b/Mods/Events/ecological_collapse.json @@ -0,0 +1,35 @@ +{ + "id": "event_ecological_collapse", + "title": "Ecological Collapse", + "description": "The planet's ecosystem has reached a breaking point. Widespread famine and resource scarcity are imminent. We must choose what to prioritize for survival.", + "meanTimeToHappen": 400, + "trigger": { + "minFollowers": 3000, + "maxCorruption": 85 + }, + "options": [ + { + "text": "Ration food for the workers.", + "tooltip": "Maintain your production, but lose a significant number of followers to famine.", + "effects": [ + { + "type": "AddResource", + "targetResource": "Followers", + "value": -1000 + } + ] + }, + { + "text": "Divert all efforts to food production.", + "tooltip": "Save your population, but suffer a permanent blow to your industrial efficiency.", + "effects": [ + { + "type": "ModifyStat", + "targetStat": "ProductionPerFollower", + "op": "Multiply", + "value": 0.75 + } + ] + } + ] +} diff --git a/Mods/Events/industrial_breakthrough.json b/Mods/Events/industrial_breakthrough.json new file mode 100644 index 0000000..22179d6 --- /dev/null +++ b/Mods/Events/industrial_breakthrough.json @@ -0,0 +1,24 @@ +{ + "id": "event_industrial_breakthrough", + "title": "Industrial Breakthrough", + "description": "One of your followers has made a revolutionary discovery in manufacturing techniques! This will permanently increase the efficiency of all future industry.", + "meanTimeToHappen": 240, + "trigger": { + "minFollowers": 1000, + "maxCorruption": 70 + }, + "options": [ + { + "text": "A brilliant mind!", + "tooltip": "Permanently increases base Production Per Second by 2.", + "effects": [ + { + "type": "ModifyStat", + "targetStat": "ProductionPerSecond", + "op": "Add", + "value": 2 + } + ] + } + ] +} diff --git a/Mods/Events/unstable_rift.json b/Mods/Events/unstable_rift.json new file mode 100644 index 0000000..c553178 --- /dev/null +++ b/Mods/Events/unstable_rift.json @@ -0,0 +1,35 @@ +{ + "id": "event_unstable_rift", + "title": "Unstable Rift", + "description": "The planet groans under the weight of your power. A rift of pure corruption has torn open, spewing filth into the environment.", + "meanTimeToHappen": 180, + "trigger": { + "minFollowers": 2000, + "maxCorruption": 90 + }, + "options": [ + { + "text": "Seal it with our power.", + "tooltip": "Lose a large amount of Production to seal the rift.", + "effects": [ + { + "type": "AddResource", + "targetResource": "Production", + "value": -1000 + } + ] + }, + { + "text": "This is a necessary evil.", + "tooltip": "The rift remains, permanently increasing passive Corruption gain.", + "effects": [ + { + "type": "ModifyStat", + "targetStat": "CorruptionPerSecond", + "op": "Add", + "value": 0.5 + } + ] + } + ] +} diff --git a/Scenes/Main/Main.tscn b/Scenes/Main/Main.tscn index dba3360..07ef3a5 100644 --- a/Scenes/Main/Main.tscn +++ b/Scenes/Main/Main.tscn @@ -189,6 +189,7 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +mouse_filter = 2 [node name="Camera2D" type="Camera2D" parent="."] diff --git a/Scenes/UI/event_popup.tscn b/Scenes/UI/event_popup.tscn index 591de2e..07a04f8 100644 --- a/Scenes/UI/event_popup.tscn +++ b/Scenes/UI/event_popup.tscn @@ -4,8 +4,11 @@ [ext_resource type="PackedScene" uid="uid://b2o5rufqn8dpf" path="res://Scenes/UI/event_option_button.tscn" id="2_gk0qx"] [node name="EventPopup" type="PanelContainer" node_paths=PackedStringArray("_titleLabel", "_descriptionLabel", "_optionsContainer")] -offset_right = 40.0 -offset_bottom = 40.0 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 script = ExtResource("1_lkb7n") _titleLabel = NodePath("VBoxContainer/Title") _descriptionLabel = NodePath("VBoxContainer/Description") @@ -14,13 +17,21 @@ _optionButtonScene = ExtResource("2_gk0qx") [node name="VBoxContainer" type="VBoxContainer" parent="."] layout_mode = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +alignment = 1 [node name="Title" type="Label" parent="VBoxContainer"] layout_mode = 2 +size_flags_vertical = 6 text = "TITLE" [node name="Description" type="RichTextLabel" parent="VBoxContainer"] +custom_minimum_size = Vector2(320, 128) layout_mode = 2 +size_flags_vertical = 3 +fit_content = true [node name="OptionButtons" type="VBoxContainer" parent="VBoxContainer"] layout_mode = 2 +size_flags_vertical = 3 diff --git a/Scripts/Components/EventManager.cs b/Scripts/Components/EventManager.cs index 4bdb7b4..9d1ea20 100644 --- a/Scripts/Components/EventManager.cs +++ b/Scripts/Components/EventManager.cs @@ -50,7 +50,6 @@ public partial class EventManager : Node private void FireEvent(EventDefinition eventDef) { - GD.Print($"Firing event: {eventDef.Title}"); GetTree().Paused = true; var popup = _eventPopupScene.Instantiate(); diff --git a/Scripts/UI/EventPopup.cs b/Scripts/UI/EventPopup.cs index 418c7aa..b6b91d4 100644 --- a/Scripts/UI/EventPopup.cs +++ b/Scripts/UI/EventPopup.cs @@ -11,9 +11,15 @@ public partial class EventPopup : PanelContainer [Export] private RichTextLabel _descriptionLabel; [Export] private VBoxContainer _optionsContainer; [Export] private PackedScene _optionButtonScene; // A scene for a single button + [Export] private float _choiceTimeout = 30.0f; + + private EventDefinition _eventDef; + private Timer _timeoutTimer; + private readonly RandomNumberGenerator _rng = new(); public void DisplayEvent(EventDefinition eventDef) { + _eventDef = eventDef; _titleLabel.Text = eventDef.Title; _descriptionLabel.Text = eventDef.Description; @@ -30,11 +36,36 @@ public partial class EventPopup : PanelContainer button.Pressed += () => { - GameBus.Instance.ExecuteEffects(option.Effects); - QueueFree(); + _timeoutTimer.Stop(); + HandleChoice(option); }; _optionsContainer.AddChild(button); } + + _timeoutTimer = new Timer { WaitTime = _choiceTimeout, OneShot = true }; + AddChild(_timeoutTimer); + _timeoutTimer.Timeout += OnTimeout; + _timeoutTimer.Start(); + } + + private void OnTimeout() + { + if (_eventDef.Options.Count > 0) + { + var randomIndex = _rng.RandiRange(0, _eventDef.Options.Count - 1); + HandleChoice(_eventDef.Options[randomIndex]); + } + else + { + QueueFree(); + GetTree().Paused = false; + } + } + + private void HandleChoice(EventOptionDefinition option) + { + GameBus.Instance.ExecuteEffects(option.Effects); + QueueFree(); } } \ No newline at end of file