Compare commits

...

2 Commits

18 changed files with 5504 additions and 7 deletions

View File

@@ -6,5 +6,5 @@
[resource]
script = ExtResource("1_ei6wr")
Scene = ExtResource("1_uho8r")
Threshold = 40000
Threshold = 100
metadata/_custom_type_script = "uid://c7hh0cy0yrdt8"

View File

@@ -6,5 +6,5 @@
[resource]
script = ExtResource("2_vr1nw")
Scene = ExtResource("1_trlm4")
Threshold = 600000
Threshold = 400
metadata/_custom_type_script = "uid://c7hh0cy0yrdt8"

View File

@@ -6,5 +6,5 @@
[resource]
script = ExtResource("2_74x2g")
Scene = ExtResource("1_ex2nw")
Threshold = 1200000
Threshold = 1000
metadata/_custom_type_script = "uid://c7hh0cy0yrdt8"

View File

@@ -5,6 +5,7 @@
[node name="HutTier2" type="Node2D"]
script = ExtResource("1_22ax8")
Tier = 1
metadata/_custom_type_script = "uid://cj5libcgnhjml"
[node name="Hut" type="Sprite2D" parent="."]

View File

@@ -5,6 +5,7 @@
[node name="HutTier3" type="Node2D"]
script = ExtResource("1_ltla2")
Tier = 2
metadata/_custom_type_script = "uid://cj5libcgnhjml"
[node name="Hut" type="Sprite2D" parent="."]

File diff suppressed because it is too large Load Diff

7
Scenes/tree.tscn Normal file
View File

@@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://8w7tvsgkev1y"]
[ext_resource type="Texture2D" uid="uid://cemch3556ibiy" path="res://Sprites/Tree.png" id="1_0vwjc"]
[node name="Tree" type="Sprite2D"]
scale = Vector2(0.01, 0.01)
texture = ExtResource("1_0vwjc")

View File

@@ -30,12 +30,15 @@ public class GameLogic
public bool TryToPerformMiracle(GameState state, MiracleDefinition miracle)
{
if (state.Get(Stat.Faith) < miracle.FaithCost || state.Get(Stat.Followers) < miracle.FollowersRequired)
if (state.Get(Stat.Faith) < miracle.FaithCost ||
state.Get(Stat.Followers) < miracle.FollowersRequired ||
state.Get(Stat.Production) < miracle.ProductionRequired)
{
return false;
}
state.Modify(Stat.Faith, -miracle.FaithCost);
state.Modify(Stat.Production, -miracle.ProductionRequired);
if (miracle.Effects != null)
{

View File

@@ -21,8 +21,8 @@ public class GameState
Set(Stat.Faith, 50);
Set(Stat.Followers, 40);
Set(Stat.FaithPerFollower, 0.5);
Set(Stat.ProductionPerSecond, 1.0);
Set(Stat.CorruptionPerSecond, 0.1);
Set(Stat.ProductionPerSecond, 0.0);
Set(Stat.CorruptionPerSecond, 0.01);
}
public double Get(Stat stat) => _stats[stat].Value;

View File

@@ -13,6 +13,7 @@ public partial class MiracleDefinition : Resource
[Export] public string Name { get; set; }
[Export] public double FaithCost { get; set; }
[Export] public long FollowersRequired { get; set; }
[Export] public double ProductionRequired { get; set; }
[Export] public Array<Effect> Effects { get; set; }
}

View File

@@ -32,6 +32,7 @@ public class MiracleDto
public string Name { get; set; }
public double FaithCost { get; set; }
public long FollowersRequired { get; set; }
public double ProductionRequired { get; set; }
public bool UnlockedByDefault { get; set; }
public List<EffectDto> Effects { get; set; }
}

View File

@@ -69,6 +69,7 @@ public static class MiracleLoader
Name = miracleDto.Name,
FaithCost = miracleDto.FaithCost,
FollowersRequired = miracleDto.FollowersRequired,
ProductionRequired = miracleDto.ProductionRequired,
Effects = []
};

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Godot;
using ParasiticGod.Scripts.Core;
using ParasiticGod.Scripts.Singletons;
namespace ParasiticGod.Scripts;
[GlobalClass]
public partial class ForestVisualizer : Node
{
[Export] private Node2D _treesContainer;
private List<Node2D> _trees = [];
private int _lastKnownTreesToShow = -1;
private bool _isUpdating = false;
public override void _Ready()
{
foreach (var child in _treesContainer.GetChildren())
{
if (child is Node2D tree)
{
_trees.Add(tree);
}
}
var rng = new RandomNumberGenerator();
rng.Randomize();
_trees = _trees.OrderBy(_ => Guid.NewGuid()).ToList();
GameBus.Instance.StateChanged += OnStateChanged;
}
public override void _ExitTree()
{
GameBus.Instance.StateChanged -= OnStateChanged;
}
private void OnStateChanged(GameState newState)
{
if (_isUpdating) return;
var corruptionRatio = newState.Get(Stat.Corruption) / 100.0;
var treesToShow = (int)(_trees.Count * (1.0 - corruptionRatio));
if (treesToShow != _lastKnownTreesToShow)
{
UpdateForestProgressively(treesToShow);
}
}
private async void UpdateForestProgressively(int treesToShow)
{
_isUpdating = true;
for (var i = 0; i < _trees.Count; i++)
{
var tree = _trees[i];
var shouldBeVisible = i < treesToShow;
var needsChange = tree.Visible != shouldBeVisible;
if (needsChange)
{
tree.Visible = shouldBeVisible;
await ToSignal(GetTree().CreateTimer(0.01f), SceneTreeTimer.SignalName.Timeout);
}
}
_lastKnownTreesToShow = treesToShow;
_isUpdating = false;
}
}

View File

@@ -0,0 +1 @@
uid://furbvcmw31bx

View File

@@ -110,5 +110,7 @@ public partial class PopulationVisualizer : Node
_lastKnownUnitCount = currentUnitCount;
_lastKnownTierIndex = newTierIndex;
_isUpdating = false;
GameBus.Instance.NotifyPopulationVisualsUpdated();
}
}

103
Scripts/RoadManager.cs Normal file
View File

@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Godot;
using ParasiticGod.Scripts.Core;
using ParasiticGod.Scripts.Singletons;
namespace ParasiticGod.Scripts;
[GlobalClass]
public partial class RoadManager : Node2D
{
[Export] private Node2D _markersContainer;
[Export] private float _roadWidth = 4.0f;
[Export] private Color _roadColor = new("saddlebrown");
[Export] private Follower.FollowerTier _minimumTierForRoads = Follower.FollowerTier.Tier2;
private Line2D _roadNetwork;
public override void _Ready()
{
_roadNetwork = new Line2D
{
Width = _roadWidth,
DefaultColor = _roadColor,
};
AddChild(_roadNetwork);
Callable.From(() =>
{
GenerateRoads();
GameBus.Instance.PopulationVisualsUpdated += GenerateRoads;
}).CallDeferred();
}
public override void _ExitTree()
{
if (GameBus.Instance != null)
{
GameBus.Instance.PopulationVisualsUpdated -= GenerateRoads;
}
}
private void GenerateRoads()
{
_roadNetwork.ClearPoints();
var activeMarkers = _markersContainer.GetChildren()
.OfType<FollowerMarker>()
.Where(m => m.IsOccupied && m.FollowerInstance != null &&
m.FollowerInstance.Tier >= _minimumTierForRoads)
.ToList();
if (activeMarkers.Count < 2) return;
var treeNodes = new HashSet<FollowerMarker>();
var remainingNodes = new List<FollowerMarker>(activeMarkers);
var edges = new List<(Vector2, Vector2)>();
var startNode = remainingNodes[0];
treeNodes.Add(startNode);
remainingNodes.RemoveAt(0);
while (remainingNodes.Any())
{
FollowerMarker bestSource = null;
FollowerMarker bestDest = null;
var minDistanceSq = float.MaxValue;
foreach (var source in treeNodes)
{
foreach (var dest in remainingNodes)
{
var distSq = source.GlobalPosition.DistanceSquaredTo(dest.GlobalPosition);
if (distSq < minDistanceSq)
{
minDistanceSq = distSq;
bestSource = source;
bestDest = dest;
}
}
}
if (bestDest != null)
{
treeNodes.Add(bestDest);
remainingNodes.Remove(bestDest);
edges.Add((bestSource.Position, bestDest.Position));
}
else
{
break;
}
}
foreach (var (start, end) in edges)
{
_roadNetwork.AddPoint(start);
_roadNetwork.AddPoint(end);
}
}
}

View File

@@ -0,0 +1 @@
uid://cw8gpeaq3yfjn

View File

@@ -18,6 +18,7 @@ public partial class GameBus : Node
public event Action<MiracleDefinition> MiraclePerformed;
public event Action<List<MiracleDefinition>> MiraclesUnlocked;
public event Action<MiracleDefinition> MiracleCompleted;
public event Action PopulationVisualsUpdated;
public override void _EnterTree()
{
@@ -74,6 +75,11 @@ public partial class GameBus : Node
}
}
public void NotifyPopulationVisualsUpdated()
{
PopulationVisualsUpdated?.Invoke();
}
public void SubscribeToStat(Stat stat, Action<double> listener) => _gameState.Subscribe(stat, listener);
public void UnsubscribeFromStat(Stat stat, Action<double> listener) => _gameState.Unsubscribe(stat, listener);