From c3ddd5c8b9986b49d4d011e125a2292734aa4c73 Mon Sep 17 00:00:00 2001 From: Hennik Hunsaker Date: Sun, 5 May 2024 19:36:36 -0600 Subject: [PATCH 1/3] Refactor to start supporting improved spawn distributions --- src/evac.lua | 3 +-- src/gremlin.lua | 19 ++++++++++++++++++- src/waves.lua | 3 +-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/evac.lua b/src/evac.lua index dac99a9..984d1ec 100644 --- a/src/evac.lua +++ b/src/evac.lua @@ -1645,8 +1645,7 @@ Evac._internal.utils = { local _angle = math.atan2(_point.z, _point.x) for _i, _unit in pairs(_units) do - local _xOffset = math.cos(_angle) * math.random(_scatterRadius) - local _yOffset = math.sin(_angle) * math.random(_scatterRadius) + local _xOffset, _yOffset = Gremlin.utils.spawnPoints(_angle, _scatterRadius) _unitsOut[_i] = { type = typeTranslation[_side][_unit.type], diff --git a/src/gremlin.lua b/src/gremlin.lua index 27a9afa..57528e8 100644 --- a/src/gremlin.lua +++ b/src/gremlin.lua @@ -521,7 +521,24 @@ Gremlin = { end return tbl1 - end + end, + spawnPoints = function(_angle, _scatterRadius, _counter) + local _xOffset, _yOffset + + if _counter < 1 then + _counter = 0 + end + + if type(_scatterRadius) == 'table' then + _xOffset = math.cos(_angle) * math.random(_scatterRadius.min, _scatterRadius.max) * _counter + _yOffset = math.sin(_angle) * math.random(_scatterRadius.min, _scatterRadius.max) * _counter + else + _xOffset = math.cos(_angle) * math.random(_scatterRadius) * _counter + _yOffset = math.sin(_angle) * math.random(_scatterRadius) * _counter + end + + return _xOffset, _yOffset + end, }, -- Internal State diff --git a/src/waves.lua b/src/waves.lua index 3f1e3be..936f1fb 100644 --- a/src/waves.lua +++ b/src/waves.lua @@ -71,8 +71,7 @@ Waves._internal.spawnWave = function(_name, _wave) local _units = {} for _unitType, _unitCount in pairs(_groupData.units) do for i = 1, _unitCount do - local _xOffset = math.cos(_angle) * math.random(_groupData.scatter.min, _groupData.scatter.max) * #_units - local _yOffset = math.sin(_angle) * math.random(_groupData.scatter.min, _groupData.scatter.max) * #_units + local _xOffset, _yOffset = Gremlin.utils.spawnPoints(_angle, _groupData.scatter, #_units) table.insert(_units, { type = _unitType, From e98d38ac6e7e5440ca875e9d26a11aab8e9e5175 Mon Sep 17 00:00:00 2001 From: Hennik Hunsaker Date: Sun, 5 May 2024 19:39:26 -0600 Subject: [PATCH 2/3] Fixes after testing --- src/gremlin.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gremlin.lua b/src/gremlin.lua index 57528e8..f6c89df 100644 --- a/src/gremlin.lua +++ b/src/gremlin.lua @@ -525,7 +525,7 @@ Gremlin = { spawnPoints = function(_angle, _scatterRadius, _counter) local _xOffset, _yOffset - if _counter < 1 then + if _counter == nil or _counter < 1 then _counter = 0 end From ac8b22768e0d62bc1706fc1ea55dcbe342ad2dc8 Mon Sep 17 00:00:00 2001 From: Hennik Hunsaker Date: Sun, 12 May 2024 21:01:49 -0600 Subject: [PATCH 3/3] More tests and a slight refactor to improve the algorithm --- src/gremlin.lua | 23 ++++++++++++++--------- src/waves.lua | 2 +- test/gremlin.lua | 20 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/gremlin.lua b/src/gremlin.lua index f6c89df..06a5729 100644 --- a/src/gremlin.lua +++ b/src/gremlin.lua @@ -522,19 +522,24 @@ Gremlin = { return tbl1 end, - spawnPoints = function(_angle, _scatterRadius, _counter) + --- Calculate the positions of units to spawn. + -- + -- @function Gremlin.utlis.spawnPoints + -- @tparam number _angle + -- @tparam number|table _scatterRadius + -- @tparam number _counter + -- @treturn number, number + spawnPoints = function(_angle, _scatterRadius) local _xOffset, _yOffset - if _counter == nil or _counter < 1 then - _counter = 0 - end - if type(_scatterRadius) == 'table' then - _xOffset = math.cos(_angle) * math.random(_scatterRadius.min, _scatterRadius.max) * _counter - _yOffset = math.sin(_angle) * math.random(_scatterRadius.min, _scatterRadius.max) * _counter + local _realRadius = math.min(math.max(_scatterRadius.max * math.sqrt(math.random()), _scatterRadius.min), _scatterRadius.max) + _xOffset = math.cos(_angle) * _realRadius + _yOffset = math.sin(_angle) * _realRadius else - _xOffset = math.cos(_angle) * math.random(_scatterRadius) * _counter - _yOffset = math.sin(_angle) * math.random(_scatterRadius) * _counter + local _realRadius = _scatterRadius * math.sqrt(math.random()) + _xOffset = math.cos(_angle) * _realRadius + _yOffset = math.sin(_angle) * _realRadius end return _xOffset, _yOffset diff --git a/src/waves.lua b/src/waves.lua index 936f1fb..4a9a16a 100644 --- a/src/waves.lua +++ b/src/waves.lua @@ -71,7 +71,7 @@ Waves._internal.spawnWave = function(_name, _wave) local _units = {} for _unitType, _unitCount in pairs(_groupData.units) do for i = 1, _unitCount do - local _xOffset, _yOffset = Gremlin.utils.spawnPoints(_angle, _groupData.scatter, #_units) + local _xOffset, _yOffset = Gremlin.utils.spawnPoints(_angle, _groupData.scatter) table.insert(_units, { type = _unitType, diff --git a/test/gremlin.lua b/test/gremlin.lua index df785bd..ed672d8 100644 --- a/test/gremlin.lua +++ b/test/gremlin.lua @@ -653,5 +653,25 @@ TestGremlinUtils = { -- SIDE EFFECTS -- N/A? end, + testSpawnPointsNumber = function() + -- INIT + -- N/A? + + -- TEST + lu.assertAlmostEquals({ Gremlin.utils.spawnPoints(0.25 * math.pi, 50) }, { 0, 0 }, 50) + + -- SIDE EFFECTS + -- N/A? + end, + testSpawnPointsTable = function() + -- INIT + -- N/A? + + -- TEST + lu.assertAlmostEquals({ Gremlin.utils.spawnPoints(0.25 * math.pi, { min = 25, max = 50 }) }, { 0, 0 }, 50) + + -- SIDE EFFECTS + -- N/A? + end, tearDown = tearDown, }