Compare commits

...

2 Commits

14 changed files with 374 additions and 9 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
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[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"]
[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

View File

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

View File

@@ -1,4 +1,5 @@
using Godot;
using ParasiticGod.Scripts.Singletons;
namespace ParasiticGod.Scripts.Components;
@@ -13,17 +14,30 @@ public partial class PauseManager : CanvasLayer
ProcessMode = ProcessModeEnum.Always;
_pauseMenu.Hide();
_pauseButton.Pressed += TogglePause;
GameBus.Instance.PauseStateChanged += OnPauseStateChanged;
}
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("pause")) TogglePause();
}
public override void _ExitTree()
{
if (GameBus.Instance != null)
{
GameBus.Instance.PauseStateChanged -= OnPauseStateChanged;
}
}
private void TogglePause()
{
var isPaused = !GetTree().Paused;
GetTree().Paused = isPaused;
GameBus.Instance.SetPause(!GetTree().Paused);
}
private void OnPauseStateChanged(bool isPaused)
{
_pauseMenu.Visible = isPaused;
}
}

View File

@@ -32,6 +32,7 @@ public partial class GameBus : Node
public event Action PopulationVisualsUpdated;
public event Action<string> AgeAdvanced;
public event Action GameWon;
public event Action<bool> PauseStateChanged;
public override void _EnterTree()
{
@@ -133,12 +134,18 @@ public partial class GameBus : Node
{
effect.Execute(_gameState);
}
GetTree().Paused = false;
SetPause(false);
}
public void SubscribeToStat(Stat stat, Action<double> listener) => _gameState.Subscribe(stat, listener);
public void UnsubscribeFromStat(Stat stat, Action<double> listener) => _gameState.Unsubscribe(stat, listener);
public void SetPause(bool isPaused)
{
GetTree().Paused = isPaused;
PauseStateChanged?.Invoke(isPaused);
}
public GameState CurrentState => _gameState;
[ConsoleCommand("set_stat", "Sets the value of a specified stat.")]

View File

@@ -11,9 +11,20 @@ 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 override void _Ready()
{
ProcessMode = ProcessModeEnum.Always;
}
public void DisplayEvent(EventDefinition eventDef)
{
_eventDef = eventDef;
_titleLabel.Text = eventDef.Title;
_descriptionLabel.Text = eventDef.Description;
@@ -30,11 +41,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();
}
}

View File

@@ -42,3 +42,73 @@ rm -rf \"{temp_dir}\""
dotnet/include_scripts_content=false
dotnet/include_debug_symbols=false
dotnet/embed_build_outputs=false
[preset.1]
name="Windows Desktop"
platform="Windows Desktop"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path=""
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.1.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
binary_format/architecture="x86_64"
codesign/enable=false
codesign/timestamp=true
codesign/timestamp_server_url=""
codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=true
application/icon=""
application/console_wrapper_icon=""
application/icon_interpolation=4
application/file_version=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
application/export_angle=0
application/export_d3d12=0
application/d3d12_agility_sdk_multiarch=true
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
Start-ScheduledTask -TaskName godot_remote_debug
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
Remove-Item -Recurse -Force '{temp_dir}'"
dotnet/include_scripts_content=false
dotnet/include_debug_symbols=true
dotnet/embed_build_outputs=false