Debug zombie spawner

This commit is contained in:
Rendo 2025-06-24 18:44:49 +05:00
commit 0fff33d196
69 changed files with 564 additions and 100 deletions

View file

@ -0,0 +1,69 @@
using Godot;
using System.Linq;
using System.Collections.Generic;
public partial class DebugZombieSpawner : PopupPanel
{
private List<string> variants;
[Export] private Label label;
[Export] private LineEdit line;
[Export] private SpinBox spin;
public void OnTextChanged(string text)
{
variants = GameRegistry.GetZombieNames();
variants.Sort(Comparer);
if (variants.Count > 3)
{
label.Text = $"{variants[0]}\n{variants[1]}\n{variants[2]}";
}
else
{
label.Text = "";
for (int i = 0; i < variants.Count; i++)
{
label.Text += variants[i] + "\n";
}
}
}
public void OnTextSubmitted(string text)
{
spin.GrabFocus();
}
public void OnPopupHide()
{
if (variants == null || variants.Count == 0)
{
return;
}
for(int i = 0; i < spin.Value; i++)
{
ZombieSequencer.Instance.Add(variants[0]);
}
QueueFree();
}
private int Comparer(string x, string y)
{
return LevensteinDistance(x,line.Text) - LevensteinDistance(y,line.Text);
}
private static int LevensteinDistance(string a, string b)
{
if (b.Length == 0)
{
return a.Length;
}
else if (a.Length == 0)
{
return b.Length;
}
else if (a[0] == b[0])
{
return LevensteinDistance(a[1..], b[1..]);
}
List<int> x = [LevensteinDistance(a[1..], b[1..]), LevensteinDistance(a[1..], b), LevensteinDistance(a, b[1..])];
return 1 + x.Min();
}
}

View file

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

View file

@ -12,19 +12,13 @@ public partial class GridLoader : GridContainer
{
_plantCard = ResourceLoader.Load<PackedScene>("res://scenes/gui/seedpacket.tscn");
string[] files = DirAccess.GetFilesAt(PLANT_RESOURCE_PATH);
foreach(var file in files)
foreach(var resource in GameRegistry.GetPlants())
{
if(ResourceLoader.Exists(PLANT_RESOURCE_PATH+file))
{
Seedpacket slot = _plantCard.Instantiate<Seedpacket>();
AddChild(slot);
slot.SetPlantResource(ResourceLoader.Load<PlantResource>(PLANT_RESOURCE_PATH+file));
slot.SetHandler(new ChoosableHandler(slot));
}
Seedpacket slot = _plantCard.Instantiate<Seedpacket>();
AddChild(slot);
slot.SetPlantResource(resource);
slot.SetHandler(new ChoosableHandler(slot));
}
}
}

View file

@ -8,7 +8,7 @@ namespace Newlon.Components.Level;
// Is not pool in traditional sense, but named like that to prevent repetition
//
public partial class PoolContainer : Node
public partial class PoolContainer : Node2D
{
[Export]
public Node2D Zombies { get; private set; }

View file

@ -0,0 +1,63 @@
using System.Collections.Generic;
using Godot;
using Newlon;
using Newlon.Components.Level;
using Newlon.Components.Zombies;
public partial class ZombieSequencer : Node2D
{
public static ZombieSequencer Instance { get; private set; }
private Queue<string> queue = [];
private RandomNumberGenerator rng = new();
public override void _Ready()
{
rng.Randomize();
Instance = this;
}
private void FormSquad()
{
if (queue.Count == 0) return;
int count = rng.RandiRange(1, queue.Count > 5 ? 5 : queue.Count);
if (count == 5)
{
Spawn(queue.Dequeue(), 1);
Spawn(queue.Dequeue(), 2);
Spawn(queue.Dequeue(), 3);
Spawn(queue.Dequeue(), 4);
Spawn(queue.Dequeue(), 5);
}
List<int> list = [];
while (list.Count < count)
{
int lane = rng.RandiRange(1, 5);
if (list.Contains(lane) == true)
{
continue;
}
list.Add(lane);
}
foreach (int lane in list)
{
Spawn(queue.Dequeue(), lane);
}
}
private void Spawn(string id, int lane)
{
RuntimeZombieData zombie = GameRegistry.GetZombieByName(id).scene.Instantiate<RuntimeZombieData>();
PoolContainer.Instance.Zombies.AddChild(zombie);
zombie.GlobalPosition = new Vector2(GlobalPosition.X, Utility.RightFieldBoundary.Y - (lane-1) * Utility.TileHeight);
}
public void Add(string id)
{
queue.Enqueue(id);
}
}

View file

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

View file

@ -4,7 +4,7 @@ namespace Newlon.Components.Plants;
public partial class PlantEyesightLimiter : CollisionShape2D
{
public override void _Ready()
public override void _Process(double delta)
{
if (Shape is SegmentShape2D segment)
{

View file

@ -37,7 +37,6 @@ public partial class AloeBehaviour : BaseBehaviour
if (PoolContainer.Instance.TryGetEntity(checkPos, out RuntimePlantData plantData))
{
plantData.Heal(3000 + 25 * plantData.MaxHp, GetParent());
GD.Print("IM TRYING");
}
}

View file

@ -25,7 +25,6 @@ public partial class EatBox : Area2D
public void OnAreaEntered(Area2D area)
{
var parent = area.GetParent();
GD.Print(parent.Name);
if (parent != null && parent is RuntimePlantData plantData)
{

View file

@ -21,7 +21,6 @@ public partial class ZombieMover : Node
* Utility.TileWidth
* GetParent<RuntimeZombieData>().LocalTimescale
* _speed.GetValue();
GD.Print(_speed.GetMult());
}
public void SetSpeedFlat(float speed)

View file

@ -12,5 +12,11 @@ public partial class Cheats : Node
{
RuntimeLevelData.Instance.AddSun(50);
}
if (@event.IsActionPressed("cheat_zombie_spawn"))
{
var spawner = GD.Load<PackedScene>("res://scenes/debug_zombie_spawner.tscn").Instantiate<DebugZombieSpawner>();
GetTree().CurrentScene.AddChild(spawner);
}
}
}

View file

@ -0,0 +1,8 @@
using Godot;
[GlobalClass]
public partial class ZombieResource : Resource
{
[Export] public int cost;
[Export] public PackedScene scene;
}

View file

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

View file

@ -0,0 +1,91 @@
using Godot;
using Newlon;
using System.Collections.Generic;
public partial class GameRegistry : Node
{
private const string PLANT_RESOURCE_PATH = "res://resources/plants/";
private const string ZOMBIE_RESOURCE_PATH = "res://resources/zombies/";
public static GameRegistry Instance { get; private set; }
private Dictionary<string, PlantResource> PlantDictionary = [];
private Dictionary<string, ZombieResource> ZombieDictionary = [];
public override void _Ready()
{
Instance = this;
//Plant init
string[] plantFiles = DirAccess.GetFilesAt(PLANT_RESOURCE_PATH);
foreach (var file in plantFiles)
{
if (ResourceLoader.Exists(PLANT_RESOURCE_PATH + file))
{
var plant = ResourceLoader.Load<PlantResource>(PLANT_RESOURCE_PATH + file);
PlantDictionary.Add(file.ToLower().Split('.')[0], plant);
}
}
//Zombie init
string[] zombieFiles = DirAccess.GetFilesAt(ZOMBIE_RESOURCE_PATH);
foreach (var file in zombieFiles)
{
if (ResourceLoader.Exists(ZOMBIE_RESOURCE_PATH + file))
{
var zombie = ResourceLoader.Load<ZombieResource>(ZOMBIE_RESOURCE_PATH + file);
ZombieDictionary.Add(file.ToLower().Split('.')[0], zombie);
}
}
}
public static PlantResource GetPlantByName(string name)
{
if (Instance.PlantDictionary.ContainsKey(name) == false) return null;
return Instance.PlantDictionary[name];
}
public static List<string> GetPlantNames()
{
List<string> result = [];
foreach (var key in Instance.PlantDictionary.Keys)
{
result.Add(key);
}
return result;
}
public static List<PlantResource> GetPlants()
{
List<PlantResource> result = [];
foreach (var value in Instance.PlantDictionary.Values)
{
result.Add(value);
}
return result;
}
public static ZombieResource GetZombieByName(string name)
{
if (Instance.ZombieDictionary.ContainsKey(name) == false) return null;
return Instance.ZombieDictionary[name];
}
public static List<string> GetZombieNames()
{
List<string> result = [];
foreach (var key in Instance.ZombieDictionary.Keys)
{
result.Add(key);
}
return result;
}
public static List<ZombieResource> GetZombies()
{
List<ZombieResource> result = [];
foreach (var value in Instance.ZombieDictionary.Values)
{
result.Add(value);
}
return result;
}
}

View file

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