Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardcore mode #5160

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions simulation_parameters/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,8 @@ public static class Constants
/// </summary>
public const float MICROBE_MIN_ABSORB_RADIUS = 3;

public const float HARDCORE_AUTOSAVE_INTERVAL = 60;

public const float PROCEDURAL_CACHE_CLEAN_INTERVAL = 9.3f;
public const float PROCEDURAL_CACHE_MEMBRANE_KEEP_TIME = 500;
public const float PROCEDURAL_CACHE_MICROBE_SHAPE_TIME = 7000;
Expand Down
106 changes: 106 additions & 0 deletions src/general/NewGameSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Godot;
using Xoshiro.PRNG64;
using Container = Godot.Container;
Expand Down Expand Up @@ -211,6 +212,12 @@ public partial class NewGameSettings : ControlWithInput
private Button includeMulticellularButton = null!;
private Button easterEggsButton = null!;

[Export]
private Button hardcoreModeButton = null!;

[Export]
private LineEdit hardcoreModeName = null!;

// Other
private Container checkOptionsMenuAdviceContainer = null!;
#pragma warning restore CA2213
Expand All @@ -228,6 +235,10 @@ public partial class NewGameSettings : ControlWithInput
private DifficultyPreset normal = null!;
private DifficultyPreset custom = null!;

private Task<List<string>>? saveListTask;
private bool isListingSaves;
private bool listedSavesDone;

[Signal]
public delegate void OnNewGameSettingsClosedEventHandler();

Expand Down Expand Up @@ -348,6 +359,37 @@ public override void _Ready()
}
}

public override void _Process(double delta)
{
if (!isListingSaves || saveListTask == null)
return;

if (saveListTask.IsCanceled)
{
saveListTask.Dispose();
saveListTask = null;

isListingSaves = false;
listedSavesDone = false;

startButton.Disabled = false;

return;
}

if (saveListTask.IsCompleted)
{
// saveListTask disposing is handled further down in the code
isListingSaves = false;
listedSavesDone = true;

startButton.Disabled = false;

// Re-do the start button pressed action as it is what started the task
OnConfirmPressed();
}
}

[RunOnKeyDown("ui_cancel", Priority = Constants.SUBMENU_CANCEL_PRIORITY)]
public bool OnEscapePressed()
{
Expand Down Expand Up @@ -424,6 +466,7 @@ public void OpenFromDescendScreen(GameProperties currentGame)
lawkButton.ButtonPressed = false;

easterEggsButton.ButtonPressed = settings.EasterEggs;
hardcoreModeButton.ButtonPressed = settings.HardcoreMode;
}

public void ReportValidityOfGameSeed(bool valid)
Expand Down Expand Up @@ -497,6 +540,12 @@ protected override void Dispose(bool disposing)
StartButtonPath.Dispose();
CheckOptionsMenuAdviceContainerPath.Dispose();
}

if (saveListTask != null)
{
saveListTask.Dispose();
saveListTask = null;
}
}

base.Dispose(disposing);
Expand Down Expand Up @@ -608,6 +657,12 @@ private void StartGame()

settings.IncludeMulticellular = includeMulticellularButton.ButtonPressed;
settings.EasterEggs = easterEggsButton.ButtonPressed;
settings.HardcoreMode = hardcoreModeButton.ButtonPressed;

if (settings.HardcoreMode)
settings.HardcoreModeName = hardcoreModeName.Text;
else
settings.HardcoreModeName = null;

// Stop music for the video (stop is used instead of pause to stop the menu music playing a bit after the video
// before the stage music starts)
Expand Down Expand Up @@ -691,6 +746,52 @@ private void SetAdvancedView(bool advanced)

private void OnConfirmPressed()
{
if (hardcoreModeButton.ButtonPressed)
{
// Hardcore mode name must not be null or empty
if (string.IsNullOrEmpty(hardcoreModeName.Text))
return;

// Check if there isn't any saves with same name as new hardcore mode name
if (!isListingSaves)
{
if (listedSavesDone)
{
isListingSaves = false;
listedSavesDone = false;
var saveList = saveListTask!.Result;

saveListTask.Dispose();
saveListTask = null;

// Final check
foreach (var saveName in saveList)
{
if (saveName.GetBaseName().GetFile() == hardcoreModeName.Text)
{
return;
}
}
}
else
{
isListingSaves = true;

saveListTask = new Task<List<string>>(() => SaveHelper.CreateListOfSaves());
TaskExecutor.Instance.AddTask(saveListTask);

// Greys out start button for more information
startButton.Disabled = true;

return;
}
}
else
{
return;
}
}

GUICommon.Instance.PlayButtonPressSound();

StartGame();
Expand Down Expand Up @@ -968,6 +1069,11 @@ private void OnEasterEggsToggled(bool pressed)
_ = pressed;
}

private void OnHardcoreModeToggled(bool pressed)
{
hardcoreModeName.Editable = pressed;
}

private void PerformanceNoteLinkClicked(Variant meta)
{
if (meta.VariantType != Variant.Type.String)
Expand Down
28 changes: 27 additions & 1 deletion src/general/NewGameSettings.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ font = ExtResource("5_otvf3")

[sub_resource type="StyleBoxEmpty" id="4"]

[node name="NewGameSettings" type="Control"]
[node name="NewGameSettings" type="Control" node_paths=PackedStringArray("hardcoreModeButton", "hardcoreModeName")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
Expand Down Expand Up @@ -82,6 +82,8 @@ IncludeMulticellularButtonPath = NodePath("CenterContainer/VBoxContainer/Advance
EasterEggsButtonPath = NodePath("CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer/VBoxContainer3/EasterEggs")
StartButtonPath = NodePath("CenterContainer/VBoxContainer/HBoxContainer/Start")
CheckOptionsMenuAdviceContainerPath = NodePath("CenterContainer/VBoxContainer/BasicOptions/Main/VBoxContainer/CheckPerformanceSettingsContainer")
hardcoreModeButton = NodePath("CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer/VBoxContainer4/HardcoreMode")
hardcoreModeName = NodePath("CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer/VBoxContainer4/HardcoreGameName")

[node name="CenterContainer" type="CenterContainer" parent="."]
layout_mode = 0
Expand Down Expand Up @@ -910,6 +912,29 @@ text = "EASTER_EGGS_EXPLANATION"
label_settings = ExtResource("5_rnvau")
autowrap_mode = 3

[node name="VBoxContainer4" type="VBoxContainer" parent="CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer"]
layout_mode = 2

[node name="HardcoreMode" type="CheckBox" parent="CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer/VBoxContainer4"]
layout_mode = 2
size_flags_horizontal = 0
text = "HARDCORE_MODE"

[node name="Label" type="Label" parent="CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer/VBoxContainer4"]
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
size_flags_horizontal = 3
text = "HARDCORE_MODE_EXPLANATION"
label_settings = ExtResource("5_rnvau")
autowrap_mode = 3

[node name="HardcoreGameName" type="LineEdit" parent="CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer/VBoxContainer4"]
editor_description = "PLACEHOLDER"
custom_minimum_size = Vector2(175, 0)
layout_mode = 2
tooltip_text = "RANDOM_SEED_TOOLTIP"
editable = false

[node name="HBoxContainer" type="HBoxContainer" parent="CenterContainer/VBoxContainer"]
layout_mode = 2

Expand Down Expand Up @@ -986,6 +1011,7 @@ text = "START_GAME"
[connection signal="pressed" from="CenterContainer/VBoxContainer/AdvancedOptions/Planet/VBoxContainer/HBoxContainer3/HBoxContainer/RandomizeButtonAdvanced" to="." method="OnRandomisedGameSeedPressed"]
[connection signal="toggled" from="CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer/VBoxContainer2/IncludeMulticellular" to="." method="OnIncludeMulticellularToggled"]
[connection signal="toggled" from="CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer/VBoxContainer3/EasterEggs" to="." method="OnEasterEggsToggled"]
[connection signal="toggled" from="CenterContainer/VBoxContainer/AdvancedOptions/Misc/VBoxContainer/VBoxContainer4/HardcoreMode" to="." method="OnHardcoreModeToggled"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/HBoxContainer/Back" to="." method="OnBackPressed"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/HBoxContainer/Basic" to="." method="OnBasicPressed"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/HBoxContainer/Advanced" to="." method="OnAdvancedPressed"]
Expand Down
16 changes: 16 additions & 0 deletions src/general/PauseMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,14 @@ private void OpenLoadPressed()
{
GUICommon.Instance.PlayButtonPressSound();

if (GameProperties != null)
{
if (GameProperties.GameWorld.WorldSettings.HardcoreMode)
{
return;
}
}

ActiveMenu = ActiveMenuType.Load;
}

Expand Down Expand Up @@ -545,6 +553,14 @@ private void OpenSavePressed()
{
GUICommon.Instance.PlayButtonPressSound();

if (GameProperties != null)
{
if (GameProperties.GameWorld.WorldSettings.HardcoreMode)
{
return;
}
}

ActiveMenu = ActiveMenuType.Save;
}

Expand Down
11 changes: 11 additions & 0 deletions src/general/WorldGenerationSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ public enum LifeOrigin
/// </summary>
public bool EasterEggs { get; set; } = true;

/// <summary>
/// This thing right here... It is... unforgiving.
/// </summary>
public bool HardcoreMode { get; set; }

/// <summary>
/// Unchangeable name for hardcore mode save
/// </summary>
public string? HardcoreModeName { get; set; }

/// <summary>
/// The auto-evo configuration this world uses
/// </summary>
Expand Down Expand Up @@ -186,6 +196,7 @@ public override string ToString()
$", Day length: {DayLength}" +
$", Include multicellular: {IncludeMulticellular}" +
$", Easter eggs: {EasterEggs}" +
$", Hardcore mode: {HardcoreMode}" +
"]";
}
}
5 changes: 5 additions & 0 deletions src/general/base_stage/EditorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,11 @@ protected virtual void PerformQuickSave()
throw new GodotAbstractMethodNotOverriddenException();
}

protected virtual void PerformHardcoreModeSave()
{
throw new GodotAbstractMethodNotOverriddenException();
}

protected virtual void SaveGame(string name)
{
throw new GodotAbstractMethodNotOverriddenException();
Expand Down
23 changes: 23 additions & 0 deletions src/general/base_stage/StageBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ public partial class StageBase : NodeWithInput, IStageBase, IGodotEarlyNodeResol
/// </summary>
private double elapsedSinceLightLevelUpdate = 1;

/// <summary>
/// Hardcore mode auto-saves during gameplay regularly.
/// </summary>
private double hardcoreModeAutosaveTimer = 2;

protected StageBase()
{
}
Expand Down Expand Up @@ -127,6 +132,19 @@ public override void _Process(double delta)
wantsToSave = false;
}

if (CurrentGame != null)
{
if (CurrentGame.GameWorld.WorldSettings.HardcoreMode)
{
hardcoreModeAutosaveTimer -= delta;
if (hardcoreModeAutosaveTimer <= 0)
{
hardcoreModeAutosaveTimer = Constants.HARDCORE_AUTOSAVE_INTERVAL;
AutoSave();
}
}
}

GameWorld.Process((float)delta);

elapsedSinceLightLevelUpdate += delta;
Expand Down Expand Up @@ -271,6 +289,11 @@ protected virtual void PerformQuickSave()
throw new GodotAbstractMethodNotOverriddenException();
}

protected virtual void PerformHardcoreModeSave()
{
throw new GodotAbstractMethodNotOverriddenException();
}

protected virtual void OnLightLevelUpdate()
{
throw new GodotAbstractMethodNotOverriddenException();
Expand Down
Loading