Add event handling improvements; implement timeout for event choices and new event definitions

This commit is contained in:
2025-08-24 00:01:09 +02:00
parent cdd944b9b5
commit 6d8139fd44
11 changed files with 274 additions and 5 deletions

View File

@@ -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
}
]
}
]
}

View File

@@ -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
}
]
}
]
}

View File

@@ -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
}
]
}
]
}

24
Mods/Events/doomsday.json Normal file
View File

@@ -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
}
]
}
]
}

View File

@@ -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
}
]
}
]
}

View File

@@ -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
}
]
}
]
}

View File

@@ -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
}
]
}
]
}

View File

@@ -189,6 +189,7 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2
[node name="Camera2D" type="Camera2D" parent="."] [node name="Camera2D" type="Camera2D" parent="."]

View File

@@ -4,8 +4,11 @@
[ext_resource type="PackedScene" uid="uid://b2o5rufqn8dpf" path="res://Scenes/UI/event_option_button.tscn" id="2_gk0qx"] [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")] [node name="EventPopup" type="PanelContainer" node_paths=PackedStringArray("_titleLabel", "_descriptionLabel", "_optionsContainer")]
offset_right = 40.0 anchors_preset = 15
offset_bottom = 40.0 anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_lkb7n") script = ExtResource("1_lkb7n")
_titleLabel = NodePath("VBoxContainer/Title") _titleLabel = NodePath("VBoxContainer/Title")
_descriptionLabel = NodePath("VBoxContainer/Description") _descriptionLabel = NodePath("VBoxContainer/Description")
@@ -14,13 +17,21 @@ _optionButtonScene = ExtResource("2_gk0qx")
[node name="VBoxContainer" type="VBoxContainer" parent="."] [node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
alignment = 1
[node name="Title" type="Label" parent="VBoxContainer"] [node name="Title" type="Label" parent="VBoxContainer"]
layout_mode = 2 layout_mode = 2
size_flags_vertical = 6
text = "TITLE" text = "TITLE"
[node name="Description" type="RichTextLabel" parent="VBoxContainer"] [node name="Description" type="RichTextLabel" parent="VBoxContainer"]
custom_minimum_size = Vector2(320, 128)
layout_mode = 2 layout_mode = 2
size_flags_vertical = 3
fit_content = true
[node name="OptionButtons" type="VBoxContainer" parent="VBoxContainer"] [node name="OptionButtons" type="VBoxContainer" parent="VBoxContainer"]
layout_mode = 2 layout_mode = 2
size_flags_vertical = 3

View File

@@ -50,7 +50,6 @@ public partial class EventManager : Node
private void FireEvent(EventDefinition eventDef) private void FireEvent(EventDefinition eventDef)
{ {
GD.Print($"Firing event: {eventDef.Title}");
GetTree().Paused = true; GetTree().Paused = true;
var popup = _eventPopupScene.Instantiate<EventPopup>(); var popup = _eventPopupScene.Instantiate<EventPopup>();

View File

@@ -11,9 +11,15 @@ public partial class EventPopup : PanelContainer
[Export] private RichTextLabel _descriptionLabel; [Export] private RichTextLabel _descriptionLabel;
[Export] private VBoxContainer _optionsContainer; [Export] private VBoxContainer _optionsContainer;
[Export] private PackedScene _optionButtonScene; // A scene for a single button [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) public void DisplayEvent(EventDefinition eventDef)
{ {
_eventDef = eventDef;
_titleLabel.Text = eventDef.Title; _titleLabel.Text = eventDef.Title;
_descriptionLabel.Text = eventDef.Description; _descriptionLabel.Text = eventDef.Description;
@@ -30,11 +36,36 @@ public partial class EventPopup : PanelContainer
button.Pressed += () => button.Pressed += () =>
{ {
GameBus.Instance.ExecuteEffects(option.Effects); _timeoutTimer.Stop();
QueueFree(); HandleChoice(option);
}; };
_optionsContainer.AddChild(button); _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();
} }
} }