From 6793335983e6824d25f0a724b751cedad4b07dcd Mon Sep 17 00:00:00 2001 From: ktyl Date: Tue, 13 Dec 2022 00:26:58 +0000 Subject: [PATCH 1/8] wild tiles take heat damage from developed tiles #7 --- half-earth/resources/overlays/no_overlay.tres | 2 ++ .../resources/tiles/tile_types/developed.tres | 2 +- half-earth/resources/tiles/tile_types/wild.tres | 7 ++++--- half-earth/scripts/WorldGrid.cs | 17 ++++++++++++++++- half-earth/scripts/overlays/NoOverlay.cs | 15 +++++++++++++++ half-earth/scripts/tile/IDamageable.cs | 4 ++++ half-earth/scripts/tile/Tile.cs | 1 + half-earth/scripts/tile/TileGrid.cs | 3 ++- half-earth/scripts/tile/Wild.cs | 7 +++++++ 9 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 half-earth/scripts/tile/IDamageable.cs create mode 100644 half-earth/scripts/tile/Wild.cs diff --git a/half-earth/resources/overlays/no_overlay.tres b/half-earth/resources/overlays/no_overlay.tres index d4a783f..5f79807 100644 --- a/half-earth/resources/overlays/no_overlay.tres +++ b/half-earth/resources/overlays/no_overlay.tres @@ -4,3 +4,5 @@ [resource] script = ExtResource( 1 ) +_healthy = Color( 0.0431373, 0.541176, 0.0235294, 1 ) +_depleted = Color( 0.670588, 0.572549, 0.27451, 1 ) diff --git a/half-earth/resources/tiles/tile_types/developed.tres b/half-earth/resources/tiles/tile_types/developed.tres index 8f5f1d1..d9ffdac 100644 --- a/half-earth/resources/tiles/tile_types/developed.tres +++ b/half-earth/resources/tiles/tile_types/developed.tres @@ -7,4 +7,4 @@ script = ExtResource( 1 ) Name = "Developed" Key = 68 Color = Color( 0.372549, 0.372549, 0.372549, 1 ) -HeatGeneration = 0.4 +HeatGeneration = 0.15 diff --git a/half-earth/resources/tiles/tile_types/wild.tres b/half-earth/resources/tiles/tile_types/wild.tres index 370bb83..20cc915 100644 --- a/half-earth/resources/tiles/tile_types/wild.tres +++ b/half-earth/resources/tiles/tile_types/wild.tres @@ -1,10 +1,11 @@ [gd_resource type="Resource" load_steps=2 format=2] -[ext_resource path="res://scripts/tile/TileType.cs" type="Script" id=1] +[ext_resource path="res://scripts/tile/Wild.cs" type="Script" id=1] [resource] script = ExtResource( 1 ) Name = "Wild" Key = 87 -Color = Color( 0, 0.545098, 0.0196078, 1 ) -HeatGeneration = -0.2 +Color = Color( 0.14902, 1, 0, 0 ) +HeatGeneration = -0.02 +Threshold = 0.6 diff --git a/half-earth/scripts/WorldGrid.cs b/half-earth/scripts/WorldGrid.cs index 6a7b01a..83c546e 100644 --- a/half-earth/scripts/WorldGrid.cs +++ b/half-earth/scripts/WorldGrid.cs @@ -96,7 +96,7 @@ public class WorldGrid : Node2D TileView view = default; view.material = (ShaderMaterial)canvasItem.Material; - view.material.SetShaderParam("lowColor", _tileGrid.StartTileType.Color); + //view.material.SetShaderParam("lowColor", _tileGrid.StartTileType.Color); _tileViews[i] = view; } } @@ -129,6 +129,20 @@ public class WorldGrid : Node2D py = y < _tileGrid.Size - 1 ? _tileGrid[x, y + 1].temperature : t; } + private void ApplyHeatDamage(ref Tile tile) + { + if (!(tile.type is IDamageable damageable)) + return; + + var surplus = tile.temperature - damageable.Threshold; + if (surplus < 0) + return; + + // TODO: parameterised balancing + tile.currentHealth -= surplus; + tile.currentHealth = Mathf.Clamp(tile.currentHealth, 0, 1); + } + private void GenerateHeat() { for (int i = 0; i < _tileGrid.Count; i++) @@ -136,6 +150,7 @@ public class WorldGrid : Node2D var tile = _tileGrid[i]; var type = tile.type; tile.temperature += type.HeatGeneration; + ApplyHeatDamage(ref tile); _tileGrid[i] = tile; } } diff --git a/half-earth/scripts/overlays/NoOverlay.cs b/half-earth/scripts/overlays/NoOverlay.cs index 49f8b1b..1222cec 100644 --- a/half-earth/scripts/overlays/NoOverlay.cs +++ b/half-earth/scripts/overlays/NoOverlay.cs @@ -2,10 +2,25 @@ using Godot; public class NoOverlay : Overlay { + [Export] + private Color _healthy; + + [Export] + private Color _depleted; + // in this view we want to draw tiles with their normal colour public override void Apply(Tile tile, ShaderMaterial material) { var type = tile.type; + + if (type is Wild wild) + { + material.SetShaderParam("lowColor", _depleted); + material.SetShaderParam("highColor", _healthy); + material.SetShaderParam("t", tile.currentHealth); + return; + } + material.SetShaderParam("lowColor", type.Color); material.SetShaderParam("t", 0); } diff --git a/half-earth/scripts/tile/IDamageable.cs b/half-earth/scripts/tile/IDamageable.cs new file mode 100644 index 0000000..6279a0d --- /dev/null +++ b/half-earth/scripts/tile/IDamageable.cs @@ -0,0 +1,4 @@ +public interface IDamageable +{ + float Threshold { get; } +} \ No newline at end of file diff --git a/half-earth/scripts/tile/Tile.cs b/half-earth/scripts/tile/Tile.cs index 662c72c..3a51b55 100644 --- a/half-earth/scripts/tile/Tile.cs +++ b/half-earth/scripts/tile/Tile.cs @@ -5,4 +5,5 @@ public struct Tile public bool isHighlighted; public float temperature; public TileType type; + public float currentHealth; } \ No newline at end of file diff --git a/half-earth/scripts/tile/TileGrid.cs b/half-earth/scripts/tile/TileGrid.cs index 7a2eb08..ef2c812 100644 --- a/half-earth/scripts/tile/TileGrid.cs +++ b/half-earth/scripts/tile/TileGrid.cs @@ -10,7 +10,7 @@ public class TileGrid : Resource, IReadOnlyList [Export] private Resource _startTileTypeResource; - public TileType StartTileType => (TileType)_startTileTypeResource; + private TileType StartTileType => (TileType)_startTileTypeResource; public int Count => Size * Size; @@ -58,6 +58,7 @@ public class TileGrid : Resource, IReadOnlyList tile.isHighlighted = false; tile.temperature = 0.0f; tile.type = StartTileType; + tile.currentHealth = 1.0f; tiles.Add(tile); } diff --git a/half-earth/scripts/tile/Wild.cs b/half-earth/scripts/tile/Wild.cs new file mode 100644 index 0000000..5cfef22 --- /dev/null +++ b/half-earth/scripts/tile/Wild.cs @@ -0,0 +1,7 @@ +using Godot; + +public class Wild : TileType, IDamageable +{ + [Export] + public float Threshold { get; private set; } +} \ No newline at end of file -- 2.34.1 From c22827967f160a61937c185591edbe9318876ead Mon Sep 17 00:00:00 2001 From: ktyl Date: Tue, 13 Dec 2022 00:46:19 +0000 Subject: [PATCH 2/8] extract heat system to class #7 --- half-earth/scripts/HeatSystem.cs | 100 +++++++++++++++++++++++++++++++ half-earth/scripts/WorldGrid.cs | 94 ++--------------------------- 2 files changed, 104 insertions(+), 90 deletions(-) create mode 100644 half-earth/scripts/HeatSystem.cs diff --git a/half-earth/scripts/HeatSystem.cs b/half-earth/scripts/HeatSystem.cs new file mode 100644 index 0000000..ebeb79d --- /dev/null +++ b/half-earth/scripts/HeatSystem.cs @@ -0,0 +1,100 @@ +using Godot; + +public class HeatSystem +{ + private readonly TileGrid _tiles; + private readonly float _diffusionCoefficient; + + private float[] _nextTemperatures = null; + + public HeatSystem(TileGrid tiles, float diffusionCoefficient) + { + _tiles = tiles; + _diffusionCoefficient = diffusionCoefficient; + _nextTemperatures = new float[tiles.Count]; + } + + public void Process() + { + GenerateHeat(); + Diffuse(); + } + + + private float TransferHeat(float t0, float alpha, float nx, float ny, float px, float py) + { + float d2tdx2 = nx - 2 * t0 + px; + float d2tdy2 = ny - 2 * t0 + py; + return t0 + alpha * (d2tdx2 + d2tdy2); + } + + private void GetNeighbourTemperatures(int x, int y, out float nx, out float ny, out float px, out float py) + { + // default value + var t = _tiles[x, y].temperature; + + nx = x > 0 ? _tiles[x - 1, y].temperature : t; + px = x < _tiles.Size - 1 ? _tiles[x + 1, y].temperature : t; + + ny = y > 0 ? _tiles[x, y - 1].temperature : t; + py = y < _tiles.Size - 1 ? _tiles[x, y + 1].temperature : t; + } + private void GenerateHeat() + { + for (int i = 0; i < _tiles.Count; i++) + { + var tile = _tiles[i]; + var type = tile.type; + tile.temperature += type.HeatGeneration; + ApplyHeatDamage(ref tile); + _tiles[i] = tile; + } + } + + private void ApplyHeatDamage(ref Tile tile) + { + if (!(tile.type is IDamageable damageable)) + return; + + var surplus = tile.temperature - damageable.Threshold; + if (surplus < 0) + return; + + // TODO: parameterised balancing + tile.currentHealth -= surplus; + tile.currentHealth = Mathf.Clamp(tile.currentHealth, 0, 1); + } + + private void Diffuse() + { + var D = _diffusionCoefficient; + + for (int i = 0; i < _tiles.Count; i++) + { + float t = _tiles[i].temperature; + + _tiles.MapIndex(i, out var x, out var y); + + GetNeighbourTemperatures( + x, y, + out var nx, + out var ny, + out var px, + out var py); + + var temperature = TransferHeat(t, D, nx, ny, px, py); + + // TODO: what if it's really really cold out? + temperature = Mathf.Max(0, temperature); + _nextTemperatures[i] = temperature; + } + + for (int i = 0; i < _tiles.Count; i++) + { + var tile = _tiles[i]; + tile.temperature = _nextTemperatures[i]; + _tiles[i] = tile; + } + } + +} diff --git a/half-earth/scripts/WorldGrid.cs b/half-earth/scripts/WorldGrid.cs index 83c546e..fb78f04 100644 --- a/half-earth/scripts/WorldGrid.cs +++ b/half-earth/scripts/WorldGrid.cs @@ -16,13 +16,12 @@ public class WorldGrid : Node2D [Export] public float DiffusionCoefficient { get; set; } = 0.01f; - private float[] _nextValues = null; - public struct TileView { public ShaderMaterial material; } private TileView[] _tileViews; + private HeatSystem _heat; // Called when the node enters the scene tree for the first time. public override void _Ready() @@ -30,6 +29,8 @@ public class WorldGrid : Node2D _tileGrid = (TileGrid)_tileGridResource; GenerateCanvasItems(_tileGrid); + + _heat = new HeatSystem(_tileGrid, DiffusionCoefficient); } #region Positioning @@ -53,8 +54,6 @@ public class WorldGrid : Node2D var tile = _tileGrid[idx]; tile.type = tileType; _tileGrid[x, y] = tile; - - _tileViews[idx].material.SetShaderParam("lowColor", tileType.Color); } #endregion @@ -76,7 +75,6 @@ public class WorldGrid : Node2D this.Clear(); _tileViews = new TileView[grid.Count]; - _nextValues = new float[grid.Count]; for (int i = 0; i < grid.Count; i++) { @@ -96,95 +94,11 @@ public class WorldGrid : Node2D TileView view = default; view.material = (ShaderMaterial)canvasItem.Material; - //view.material.SetShaderParam("lowColor", _tileGrid.StartTileType.Color); _tileViews[i] = view; } } public ShaderMaterial GetTileMaterial(int idx) => _tileViews[idx].material; - #region Simulation - public void _on_Clock_OnTick(int ticks) - { - GenerateHeat(); - Diffuse(); - } - - private float TransferHeat(float t0, float alpha, float nx, float ny, float px, float py) - { - float d2tdx2 = nx - 2 * t0 + px; - float d2tdy2 = ny - 2 * t0 + py; - return t0 + alpha * (d2tdx2 + d2tdy2); - } - - private void GetNeighbourTemperatures(int x, int y, out float nx, out float ny, out float px, out float py) - { - // default value - var t = _tileGrid[x, y].temperature; - - nx = x > 0 ? _tileGrid[x - 1, y].temperature : t; - px = x < _tileGrid.Size - 1 ? _tileGrid[x + 1, y].temperature : t; - - ny = y > 0 ? _tileGrid[x, y - 1].temperature : t; - py = y < _tileGrid.Size - 1 ? _tileGrid[x, y + 1].temperature : t; - } - - private void ApplyHeatDamage(ref Tile tile) - { - if (!(tile.type is IDamageable damageable)) - return; - - var surplus = tile.temperature - damageable.Threshold; - if (surplus < 0) - return; - - // TODO: parameterised balancing - tile.currentHealth -= surplus; - tile.currentHealth = Mathf.Clamp(tile.currentHealth, 0, 1); - } - - private void GenerateHeat() - { - for (int i = 0; i < _tileGrid.Count; i++) - { - var tile = _tileGrid[i]; - var type = tile.type; - tile.temperature += type.HeatGeneration; - ApplyHeatDamage(ref tile); - _tileGrid[i] = tile; - } - } - - private void Diffuse() - { - var D = DiffusionCoefficient; - - for (int i = 0; i < _tileGrid.Count; i++) - { - float t = _tileGrid[i].temperature; - - _tileGrid.MapIndex(i, out var x, out var y); - - GetNeighbourTemperatures( - x, y, - out var nx, - out var ny, - out var px, - out var py); - - var temperature = TransferHeat(t, D, nx, ny, px, py); - - // TODO: what if it's really really cold out? - temperature = Mathf.Max(0, temperature); - _nextValues[i] = temperature; - } - - for (int i = 0; i < _tileGrid.Count; i++) - { - var tile = _tileGrid[i]; - tile.temperature = _nextValues[i]; - _tileGrid[i] = tile; - } - } - #endregion + public void _on_Clock_OnTick(int ticks) => _heat.Process(); } -- 2.34.1 From 8c55e2131fdba153978097169ce89d568b5134d9 Mon Sep 17 00:00:00 2001 From: ktyl Date: Sat, 17 Dec 2022 23:25:43 +0000 Subject: [PATCH 3/8] spawn buttons for buildable tiles --- .../tile_type_collections/buildable_tiles.tres | 5 +++-- half-earth/scripts/ui/BuildModeUI.cs | 10 +++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/half-earth/resources/tiles/tile_types/tile_type_collections/buildable_tiles.tres b/half-earth/resources/tiles/tile_types/tile_type_collections/buildable_tiles.tres index af140a6..1656e8c 100644 --- a/half-earth/resources/tiles/tile_types/tile_type_collections/buildable_tiles.tres +++ b/half-earth/resources/tiles/tile_types/tile_type_collections/buildable_tiles.tres @@ -1,8 +1,9 @@ -[gd_resource type="Resource" load_steps=3 format=2] +[gd_resource type="Resource" load_steps=4 format=2] [ext_resource path="res://scripts/tile/TileTypeCollection.cs" type="Script" id=1] [ext_resource path="res://resources/tiles/tile_types/developed.tres" type="Resource" id=2] +[ext_resource path="res://resources/tiles/tile_types/wild.tres" type="Resource" id=3] [resource] script = ExtResource( 1 ) -_resources = [ ExtResource( 2 ) ] +_resources = [ ExtResource( 2 ), ExtResource( 3 ) ] diff --git a/half-earth/scripts/ui/BuildModeUI.cs b/half-earth/scripts/ui/BuildModeUI.cs index 92ddfa0..16461c1 100644 --- a/half-earth/scripts/ui/BuildModeUI.cs +++ b/half-earth/scripts/ui/BuildModeUI.cs @@ -20,10 +20,14 @@ public class BuildModeUI : Control _buildMode = GetNode(_buildModePath); var buttonHeight = 40; - var tileType = _buildMode.BuildableTiles[0]; - int x = 50; - SpawnButton(tileType, buttonHeight, ref x); + int x = 50; + int margin = 5; + foreach (var tt in _buildMode.BuildableTiles) + { + SpawnButton(tt, buttonHeight, ref x); + x += margin; + } } private void UpdateButtonToggleState(TileType tileType) -- 2.34.1 From 1bbb11b0426650462dd40e8f61c6491282c9baf8 Mon Sep 17 00:00:00 2001 From: ktyl Date: Sat, 17 Dec 2022 23:27:21 +0000 Subject: [PATCH 4/8] apply spawn effect --- half-earth/scripts/WorldGrid.cs | 1 + half-earth/scripts/tile/TileType.cs | 2 ++ half-earth/scripts/tile/Wild.cs | 6 ++++++ 3 files changed, 9 insertions(+) diff --git a/half-earth/scripts/WorldGrid.cs b/half-earth/scripts/WorldGrid.cs index fb78f04..ec198c7 100644 --- a/half-earth/scripts/WorldGrid.cs +++ b/half-earth/scripts/WorldGrid.cs @@ -53,6 +53,7 @@ public class WorldGrid : Node2D var tile = _tileGrid[idx]; tile.type = tileType; + tile = tileType.ApplySpawneffect(tile); _tileGrid[x, y] = tile; } #endregion diff --git a/half-earth/scripts/tile/TileType.cs b/half-earth/scripts/tile/TileType.cs index c2824a1..f682ed1 100644 --- a/half-earth/scripts/tile/TileType.cs +++ b/half-earth/scripts/tile/TileType.cs @@ -17,4 +17,6 @@ public class TileType : Resource public float HeatGeneration { get; private set; } public override string ToString() => Name; + + public virtual Tile ApplySpawneffect(Tile tile) => tile; } \ No newline at end of file diff --git a/half-earth/scripts/tile/Wild.cs b/half-earth/scripts/tile/Wild.cs index 5cfef22..3697cb3 100644 --- a/half-earth/scripts/tile/Wild.cs +++ b/half-earth/scripts/tile/Wild.cs @@ -4,4 +4,10 @@ public class Wild : TileType, IDamageable { [Export] public float Threshold { get; private set; } + + public override Tile ApplySpawneffect(Tile tile) + { + tile.currentHealth = 0; + return tile; + } } \ No newline at end of file -- 2.34.1 From ece699b68e1171157830089f83d4240be2201735 Mon Sep 17 00:00:00 2001 From: ktyl Date: Sat, 17 Dec 2022 23:27:52 +0000 Subject: [PATCH 5/8] rename script --- half-earth/scripts/{HeatSystem.cs => EnvironmentSystem.cs} | 6 ++---- half-earth/scripts/WorldGrid.cs | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) rename half-earth/scripts/{HeatSystem.cs => EnvironmentSystem.cs} (96%) diff --git a/half-earth/scripts/HeatSystem.cs b/half-earth/scripts/EnvironmentSystem.cs similarity index 96% rename from half-earth/scripts/HeatSystem.cs rename to half-earth/scripts/EnvironmentSystem.cs index ebeb79d..758b231 100644 --- a/half-earth/scripts/HeatSystem.cs +++ b/half-earth/scripts/EnvironmentSystem.cs @@ -1,13 +1,13 @@ using Godot; -public class HeatSystem +public class EnvironmentSystem { private readonly TileGrid _tiles; private readonly float _diffusionCoefficient; private float[] _nextTemperatures = null; - public HeatSystem(TileGrid tiles, float diffusionCoefficient) + public EnvironmentSystem(TileGrid tiles, float diffusionCoefficient) { _tiles = tiles; _diffusionCoefficient = diffusionCoefficient; @@ -20,7 +20,6 @@ public class HeatSystem Diffuse(); } - private float TransferHeat(float t0, float alpha, float nx, float ny, float px, float py) { float d2tdx2 = nx - 2 * t0 + px; @@ -96,5 +95,4 @@ public class HeatSystem _tiles[i] = tile; } } - } diff --git a/half-earth/scripts/WorldGrid.cs b/half-earth/scripts/WorldGrid.cs index ec198c7..10a7250 100644 --- a/half-earth/scripts/WorldGrid.cs +++ b/half-earth/scripts/WorldGrid.cs @@ -21,7 +21,7 @@ public class WorldGrid : Node2D public ShaderMaterial material; } private TileView[] _tileViews; - private HeatSystem _heat; + private EnvironmentSystem _environment; // Called when the node enters the scene tree for the first time. public override void _Ready() @@ -30,7 +30,7 @@ public class WorldGrid : Node2D GenerateCanvasItems(_tileGrid); - _heat = new HeatSystem(_tileGrid, DiffusionCoefficient); + _environment = new EnvironmentSystem(_tileGrid, DiffusionCoefficient); } #region Positioning @@ -101,5 +101,5 @@ public class WorldGrid : Node2D public ShaderMaterial GetTileMaterial(int idx) => _tileViews[idx].material; - public void _on_Clock_OnTick(int ticks) => _heat.Process(); + public void _on_Clock_OnTick(int ticks) => _environment.Process(); } -- 2.34.1 From f13fe1631724e75493151ce76cd1aea147b9fb39 Mon Sep 17 00:00:00 2001 From: ktyl Date: Wed, 21 Dec 2022 22:12:01 +0000 Subject: [PATCH 6/8] wip healing --- half-earth/scripts/EnvironmentSystem.cs | 49 ++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/half-earth/scripts/EnvironmentSystem.cs b/half-earth/scripts/EnvironmentSystem.cs index 758b231..16895ed 100644 --- a/half-earth/scripts/EnvironmentSystem.cs +++ b/half-earth/scripts/EnvironmentSystem.cs @@ -55,13 +55,50 @@ public class EnvironmentSystem if (!(tile.type is IDamageable damageable)) return; - var surplus = tile.temperature - damageable.Threshold; - if (surplus < 0) - return; + var delta = tile.temperature - damageable.Threshold; + if (delta < 0) + { + // we want to heal based on how many wild tiles surround us + float healRate = 0.01f; - // TODO: parameterised balancing - tile.currentHealth -= surplus; - tile.currentHealth = Mathf.Clamp(tile.currentHealth, 0, 1); + // count neighbours + } + else + { + // take damage + // TODO: parameterised balancing + tile.currentHealth -= delta; + tile.currentHealth = Mathf.Clamp(tile.currentHealth, 0, 1); + } + + } + + public int GetNeighbourCount(int x, int y) where T : TileType + { + int count = 0; + + for (int i = -1; i < 1; i += 2) + { + for (int j = -1; j < 1; j += 2) + { + int xi = x + 1; + int yj = y + 1; + + // assume tiles out side of bounds are the same type as this one + if (!_tiles.IsInBounds(xi, yj)) + { + count += 1; + continue; + } + + if (!(_tiles[xi, yj] is T)) + continue; + + count++; + } + } + + return count; } private void Diffuse() -- 2.34.1 From 78e4c6ee9e1cb8940ef77791d2c6bc1997b6c807 Mon Sep 17 00:00:00 2001 From: Cat Flynn Date: Wed, 21 Dec 2022 22:51:51 +0000 Subject: [PATCH 7/8] update docs --- gdd.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gdd.md b/gdd.md index fa2b769..b780dcd 100644 --- a/gdd.md +++ b/gdd.md @@ -11,15 +11,14 @@ ## Clock Ticks can be applied manually or they can be applied over time. -Add a tick counter as a UI element. +There is a tick counter UI debug element. -## Grid +## Diffusion + +### Grid Add a 10x10 grid. Tiles are highlighted a different colour when the player hovers over them with the cursor. - -### Diffusion - Tiles in the grid contain floating point values. These values propogate to neighbouring cells a tick happens. -- 2.34.1 From d431848791adade3ebfce5de89308446fc903e4a Mon Sep 17 00:00:00 2001 From: Cat Flynn Date: Thu, 22 Dec 2022 01:10:30 +0000 Subject: [PATCH 8/8] wild tiles can heal --- .../resources/tiles/tile_types/wild.tres | 1 + half-earth/scripts/EnvironmentSystem.cs | 48 +++++---------- half-earth/scripts/tile/IDamageable.cs | 1 + half-earth/scripts/tile/TileGrid.cs | 59 +++++++++++++++++++ half-earth/scripts/tile/Wild.cs | 3 + 5 files changed, 79 insertions(+), 33 deletions(-) diff --git a/half-earth/resources/tiles/tile_types/wild.tres b/half-earth/resources/tiles/tile_types/wild.tres index 20cc915..ed76163 100644 --- a/half-earth/resources/tiles/tile_types/wild.tres +++ b/half-earth/resources/tiles/tile_types/wild.tres @@ -8,4 +8,5 @@ Name = "Wild" Key = 87 Color = Color( 0.14902, 1, 0, 0 ) HeatGeneration = -0.02 +HealRate = 0.01 Threshold = 0.6 diff --git a/half-earth/scripts/EnvironmentSystem.cs b/half-earth/scripts/EnvironmentSystem.cs index 16895ed..5fabf8b 100644 --- a/half-earth/scripts/EnvironmentSystem.cs +++ b/half-earth/scripts/EnvironmentSystem.cs @@ -45,13 +45,19 @@ public class EnvironmentSystem var tile = _tiles[i]; var type = tile.type; tile.temperature += type.HeatGeneration; - ApplyHeatDamage(ref tile); _tiles[i] = tile; } + + for (int i = 0; i < _tiles.Count; i++) + { + ApplyHeatDamage(i); + } } - private void ApplyHeatDamage(ref Tile tile) + private void ApplyHeatDamage(int i) { + _tiles.MapIndex(i, out var x, out var y); + var tile = _tiles[x, y]; if (!(tile.type is IDamageable damageable)) return; @@ -59,46 +65,22 @@ public class EnvironmentSystem if (delta < 0) { // we want to heal based on how many wild tiles surround us - float healRate = 0.01f; + float wild = _tiles.GetNeighbourProportion(x, y); + float heal = damageable.HealRate * wild; - // count neighbours + tile.currentHealth += heal; } else { - // take damage // TODO: parameterised balancing + + // take damage tile.currentHealth -= delta; - tile.currentHealth = Mathf.Clamp(tile.currentHealth, 0, 1); } - } + tile.currentHealth = Mathf.Clamp(tile.currentHealth, 0, 1); - public int GetNeighbourCount(int x, int y) where T : TileType - { - int count = 0; - - for (int i = -1; i < 1; i += 2) - { - for (int j = -1; j < 1; j += 2) - { - int xi = x + 1; - int yj = y + 1; - - // assume tiles out side of bounds are the same type as this one - if (!_tiles.IsInBounds(xi, yj)) - { - count += 1; - continue; - } - - if (!(_tiles[xi, yj] is T)) - continue; - - count++; - } - } - - return count; + _tiles[x, y] = tile; } private void Diffuse() diff --git a/half-earth/scripts/tile/IDamageable.cs b/half-earth/scripts/tile/IDamageable.cs index 6279a0d..ba606f2 100644 --- a/half-earth/scripts/tile/IDamageable.cs +++ b/half-earth/scripts/tile/IDamageable.cs @@ -1,4 +1,5 @@ public interface IDamageable { + float HealRate { get; } float Threshold { get; } } \ No newline at end of file diff --git a/half-earth/scripts/tile/TileGrid.cs b/half-earth/scripts/tile/TileGrid.cs index ef2c812..7ea685e 100644 --- a/half-earth/scripts/tile/TileGrid.cs +++ b/half-earth/scripts/tile/TileGrid.cs @@ -89,5 +89,64 @@ public class TileGrid : Resource, IReadOnlyList { return x >= 0 && x < Size && y >= 0 && y < Size; } + + private readonly int[] _neighbours = new int[] + { + -1, 0, + 0, 1, + 1, 0, + 0, -1 + }; + + private void GetCoordinate(int dir, out int x, out int y) + { + dir %= 4; + int idx = dir * 2; + x = _neighbours[idx]; + y = _neighbours[idx + 1]; + } + + public float GetNeighbourProportion(int x, int y) + { + int typed = GetNeighbourCount(x, y); + int all = GetNeighbourCount(x, y); + return (float)typed / (float)all; + } + + public int GetNeighbourCount(int x, int y) + { + int count = 0; + for (int i = 0; i < 4; i++) + { + GetCoordinate(i, out var nx, out var ny); + + if (!IsInBounds(x + nx, y + ny)) + continue; + + if (!(this[x + nx, y + ny].type is T)) + continue; + + count++; + } + + return count; + } + + public int GetNeighbourCount(int x, int y) + { + int count = 0; + + for (int i = 0; i < 4; i++) + { + GetCoordinate(i, out var nx, out var ny); + + if (!IsInBounds(x + nx, y + ny)) + continue; + + count++; + } + + return count; + } } diff --git a/half-earth/scripts/tile/Wild.cs b/half-earth/scripts/tile/Wild.cs index 3697cb3..b058b44 100644 --- a/half-earth/scripts/tile/Wild.cs +++ b/half-earth/scripts/tile/Wild.cs @@ -2,6 +2,9 @@ using Godot; public class Wild : TileType, IDamageable { + [Export] + public float HealRate { get; private set; } = 0.01f; + [Export] public float Threshold { get; private set; } -- 2.34.1