170 lines
5.1 KiB
C#
170 lines
5.1 KiB
C#
using System.Collections.Generic;
|
|
using Godot;
|
|
using Godot.Collections;
|
|
|
|
public partial class SurvivalZombieSpawner : Node
|
|
{
|
|
// Zombie pools
|
|
// Points from pools go in that order: support -> tank -> horde -> bank
|
|
// Horde pool is allowed to shrink during runtime
|
|
[Export] private Array<string> supportPool;
|
|
[Export] private Array<string> tankPool;
|
|
[Export] private Array<string> hordePool;
|
|
|
|
private List<ZombieResource> cachedSupportPool;
|
|
private List<ZombieResource> cachedTankPool;
|
|
private List<ZombieResource> cachedHordePool;
|
|
|
|
private float minSupportPoints;
|
|
private float minTankPoints;
|
|
private float minHordePoints;
|
|
|
|
[Export] private float points = 0;
|
|
[Export] private float huge_wave_points;
|
|
[Export] private Curve velocity_curve;
|
|
private float velocity = 0;
|
|
[Export] private double time = 0.0;
|
|
private float fin_a;
|
|
private RandomNumberGenerator rng = new();
|
|
|
|
|
|
public override void _Ready()
|
|
{
|
|
rng.Randomize();
|
|
|
|
cachedSupportPool = LoadFromRegistry(supportPool);
|
|
cachedTankPool = LoadFromRegistry(tankPool);
|
|
cachedHordePool = LoadFromRegistry(hordePool);
|
|
|
|
cachedTankPool.Sort((x, y) =>
|
|
{
|
|
return (int)(x.Cost - y.Cost);
|
|
});
|
|
cachedHordePool.Sort((x, y) =>
|
|
{
|
|
return (int)(x.Cost - y.Cost);
|
|
});
|
|
|
|
minSupportPoints = cachedSupportPool[0].Cost;
|
|
minTankPoints = cachedTankPool[0].Cost;
|
|
minHordePoints = cachedHordePool[0].Cost;
|
|
|
|
fin_a = (velocity_curve.Sample(velocity_curve.MaxDomain) - velocity_curve.Sample(velocity_curve.MaxDomain - 0.001f)) / 0.001f;
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
points += velocity * (float)delta;
|
|
|
|
if (time > velocity_curve.MaxDomain)
|
|
{
|
|
velocity += fin_a * (float)delta;
|
|
}
|
|
else
|
|
{
|
|
velocity = velocity_curve.Sample((float)time);
|
|
}
|
|
time += delta;
|
|
}
|
|
|
|
public void SummonWave()
|
|
{
|
|
bool big_wave = false;
|
|
if ((int)time % 300 == 0)
|
|
{
|
|
points += velocity/velocity_curve.Sample((float)time)*huge_wave_points;
|
|
big_wave = true;
|
|
}
|
|
|
|
float support_points = points * 0.2f;
|
|
float tank_points = points * 0.5f;
|
|
float horde_points = points * 0.3f;
|
|
points = 0;
|
|
|
|
List<ZombieResource> wave = [];
|
|
var remaining = SummonTank(tank_points, wave);
|
|
support_points += remaining * 0.8f;
|
|
horde_points += remaining * 0.2f;
|
|
horde_points += SummonSupport(support_points, wave);
|
|
points += SummonHorde(horde_points, wave, big_wave);
|
|
|
|
wave.Sort((x, y) => { return rng.RandiRange(-1, 1); });
|
|
|
|
foreach (var zom in wave)
|
|
{
|
|
ZombieSequencer.Instance.Add(zom.internal_id);
|
|
}
|
|
|
|
big_wave = false;
|
|
}
|
|
|
|
private float SummonSupport(float given_points, List<ZombieResource> wave)
|
|
{
|
|
if (cachedSupportPool.Count == 0)
|
|
{
|
|
return given_points;
|
|
}
|
|
while (given_points >= minSupportPoints)
|
|
{
|
|
var chosen_zombie = cachedSupportPool[rng.RandiRange(0, cachedSupportPool.Count - 1)];
|
|
if (given_points - chosen_zombie.Cost >= 0)
|
|
{
|
|
wave.Add(chosen_zombie);
|
|
given_points -= chosen_zombie.Cost;
|
|
}
|
|
}
|
|
return given_points;
|
|
}
|
|
private float SummonTank(float given_points, List<ZombieResource> wave)
|
|
{
|
|
if (cachedTankPool.Count == 0)
|
|
{
|
|
return given_points;
|
|
}
|
|
int zombieIndex = cachedTankPool.Count - 1;
|
|
while (given_points >= minSupportPoints && zombieIndex > -1)
|
|
{
|
|
if (cachedTankPool[zombieIndex].Cost > given_points)
|
|
{
|
|
zombieIndex--;
|
|
continue;
|
|
}
|
|
var chosen_zombie = cachedTankPool[zombieIndex];
|
|
wave.Add(chosen_zombie);
|
|
given_points -= chosen_zombie.Cost;
|
|
}
|
|
return given_points;
|
|
}
|
|
private float SummonHorde(float given_points, List<ZombieResource> wave, bool is_big)
|
|
{
|
|
if (cachedHordePool.Count == 0)
|
|
{
|
|
return given_points;
|
|
}
|
|
while (is_big == false && cachedHordePool.Count > 1 && cachedHordePool[1].Cost * 15 <= given_points)
|
|
{
|
|
cachedHordePool.RemoveAt(0);
|
|
minHordePoints = cachedHordePool[0].Cost;
|
|
}
|
|
while (given_points >= minHordePoints)
|
|
{
|
|
var chosen_zombie = cachedHordePool[rng.RandiRange(0, cachedHordePool.Count - 1)];
|
|
if (given_points - chosen_zombie.Cost >= 0)
|
|
{
|
|
wave.Add(chosen_zombie);
|
|
given_points -= chosen_zombie.Cost;
|
|
}
|
|
}
|
|
return given_points;
|
|
}
|
|
|
|
private List<ZombieResource> LoadFromRegistry(Array<string> pool)
|
|
{
|
|
List<ZombieResource> list = [];
|
|
foreach (var res in pool)
|
|
{
|
|
list.Add(GameRegistry.GetZombieByName(res));
|
|
}
|
|
return list;
|
|
}
|
|
}
|