diff --git a/src/evac.lua b/src/evac.lua index 004fdda..a93be29 100644 --- a/src/evac.lua +++ b/src/evac.lua @@ -466,23 +466,6 @@ Evac.groups = { -- Aircraft Evac._internal.aircraft = { - getZone = function(_unit) - Gremlin.log.trace(Evac.Id, string.format('Grabbing Unit Zone Name : %s', _unit)) - - local _unitObj = Unit.getByName(_unit) - - if _unitObj ~= nil then - local _unitPoint = _unitObj:getPoint() - - for _, _zoneData in pairs(Gremlin.utils.mergeTables(Evac._state.zones.evac, Evac._state.zones.relay, Evac._state.zones.safe)) do - if mist.pointInZone(_unitPoint, _zoneData.name) then - return _zoneData.name - end - end - end - - return nil - end, inZone = function(_unit, _evacMode) Gremlin.log.trace(Evac.Id, string.format('Checking For Unit In Zones : %s, %s', _unit, tostring(_evacMode))) @@ -528,7 +511,7 @@ Evac._internal.aircraft = { loadEvacuees = function(_unit, _number) Gremlin.log.trace(Evac.Id, string.format('Loading Evacuees Onto Unit : %s, %i', _unit, _number)) - local _zone = Evac._internal.aircraft.getZone(_unit) + local _zone = Evac._internal.utils.getUnitZone(_unit) if Evac._state.extractableNow[_zone] == nil or ((Evac._state.zones.evac[_zone] == nil or Evac._state.zones.evac[_zone].active == false) and (Evac._state.zones.relay[_zone] == nil or Evac._state.zones.relay[_zone].active == false)) then Gremlin.log.debug(Evac.Id, string.format('Loading Evacuees : %s is not an active or registered zone\nextractable - %s\nevac zone - %s\nrelay zone - %s', _zone, mist.utils.tableShowSorted(Evac._state.extractableNow[_zone]), mist.utils.tableShowSorted(Evac._state.zones.evac[_zone]), mist.utils.tableShowSorted(Evac._state.zones.relay[_zone]))) @@ -552,14 +535,14 @@ Evac._internal.aircraft = { local _timeout = Evac.loadUnloadPerIndividual * _number local _timeNow = math.floor(timer.getTime()) mist.scheduleFunction(function(_start) - local _left = (_start + _timeout) - timer.getTime() + local _left = math.floor((_start + _timeout) - timer.getTime()) Gremlin.log.debug(Evac.Id, string.format('Loading Evacuees : %i seconds to finish', _left)) - local _displayTime = 1 - local _message + local _message = string.format('%i seconds remaining to load %i evacuees', _left, _number) + local _displayFor = 1 - if math.floor(_left) <= 0 then + if _left <= 0 then local _evacNameList = {} for _evacName, _ in pairs(Evac._state.extractableNow[_zone]) do table.insert(_evacNameList, _evacName) @@ -574,16 +557,28 @@ Evac._internal.aircraft = { Evac._state.extractionUnits[_unit][_randomName] = _evacuee end - Evac._internal.aircraft.adaptWeight(_unit) _message = 'Evacuee loading complete!' - _displayTime = 5 - else - _message = string.format('%i seconds remaining in evacuee loading process', _left) + _displayFor = 5 + elseif math.fmod(_left, Evac.loadUnloadPerIndividual) == 0 then + local _evacNameList = {} + for _evacName, _ in pairs(Evac._state.extractableNow[_zone]) do + table.insert(_evacNameList, _evacName) + end + + local _randomIdx = math.random(#_evacNameList) + local _randomName = _evacNameList[_randomIdx] + local _evacuee = Evac._state.extractableNow[_zone][_randomName] + table.remove(_evacNameList, _randomIdx) + Evac._state.extractableNow[_zone][_randomName] = nil + Evac._state.extractionUnits[_unit][_randomName] = _evacuee + _number = _number - 1 end + Evac._internal.aircraft.adaptWeight(_unit) + Gremlin.log.debug(Evac.Id, string.format('Loading Evacuees : Sending %s to %s', _message, tostring(_unit))) - Gremlin.utils.displayMessageTo(_unit, _message, _displayTime) + Gremlin.utils.displayMessageTo(_unit, _message, _displayFor) end, {_timeNow + 0.01}, _timeNow + 0.01, 1, _timeNow + _timeout + 0.02) end, countEvacuees = function(_unit) @@ -620,8 +615,7 @@ Evac._internal.aircraft = { if _extracted ~= nil then for _i, _evacuee in pairs(_extracted) do if _i ~= 0 then - _calculated = _calculated + - (_evacuee.weight or Evac._internal.utils.randomizeWeight(Evac.spawnWeight)) + _calculated = _calculated + (_evacuee.weight or Evac._internal.utils.randomizeWeight(Evac.spawnWeight)) end end end @@ -637,7 +631,7 @@ Evac._internal.aircraft = { unloadEvacuees = function(_unit) Gremlin.log.trace(Evac.Id, string.format('Unloading Evacuees From Unit : %s', _unit)) - local _zone = Evac._internal.aircraft.getZone(_unit) + local _zone = Evac._internal.utils.getUnitZone(_unit) if (Evac._state.zones.safe[_zone] == nil or Evac._state.zones.safe[_zone].active == false) and (Evac._state.zones.relay[_zone] == nil or Evac._state.zones.relay[_zone].active == false) then Gremlin.log.debug(Evac.Id, string.format('Unloading Evacuees : %s is not an active or registered zone\nrelay zone - %s\nsafe zone - %s', _zone, mist.utils.tableShowSorted(Evac._state.zones.relay[_zone]), mist.utils.tableShowSorted(Evac._state.zones.safe[_zone]))) @@ -661,14 +655,14 @@ Evac._internal.aircraft = { local _timeout = Evac.loadUnloadPerIndividual * _number local _timeNow = math.floor(timer.getTime()) mist.scheduleFunction(function(_start) - local _left = (_start + _timeout) - timer.getTime() + local _left = math.floor((_start + _timeout) - timer.getTime()) Gremlin.log.debug(Evac.Id, string.format('Unloading Evacuees : %f seconds to finish', _left)) - local _displayTime = 1 - local _message + local _displayFor = 1 + local _message = string.format('%i seconds remaining to unload %i evacuees', _left, _number) - if math.floor(_left) <= 0 then + if _left <= 0 then local _groups = {} for _evacueeName, _evacuee in pairs(Evac._state.extractionUnits[_unit]) do if _evacueeName ~= 0 then @@ -686,15 +680,26 @@ Evac._internal.aircraft = { } Evac._internal.aircraft.adaptWeight(_unit) _message = 'Evacuee unloading complete!' - _displayTime = 5 - else - _message = string.format('%i seconds remaining in evacuee unloading process', _left) + _displayFor = 5 + elseif math.fmod(_left, Evac.loadUnloadPerIndividual) == 0 then + for _evacueeName, _evacuee in pairs(Evac._state.extractionUnits[_unit]) do + if _evacueeName ~= 0 then + Evac._state.extractableNow[_zone][_evacueeName] = _evacuee + Evac._state.extractionUnits[_unit][_evacueeName] = nil + break + end + end + + Evac._internal.aircraft.adaptWeight(_unit) + + _number = _number - 1 end Gremlin.log.debug(Evac.Id, string.format('Unloading Evacuees : Sending %s to %s', _message, tostring(_unit))) - Gremlin.utils.displayMessageTo(_unit, _message, _displayTime) - end, {_timeNow + 0.01}, _timeNow + 0.01, 1, _timeNow + _timeout + 0.02) + Gremlin.utils.displayMessageTo(_unit, _message, _displayFor) + Evac._internal.utils.endIfEnoughGotOut() + end, { _timeNow + 0.01 }, _timeNow + 0.01, 1, _timeNow + _timeout + 0.02) end } @@ -1116,7 +1121,7 @@ Evac._internal.zones = { for _unitName, _unit in pairs(Evac._state.extractableNow[_zone]) do if not Evac._internal.aircraft.inZone(_unitName, _zone) then - local _newZone = Evac._internal.aircraft.getZone(_unitName) + local _newZone = Evac._internal.utils.getUnitZone(_unitName) if _newZone ~= nil and Evac._state.extractableNow[_newZone] ~= nil then Evac._state.extractableNow[_newZone][_unitName] = _unit @@ -1202,8 +1207,8 @@ Evac._internal.menu = { text = function(_unit) local _unitObj = Unit.getByName(_unit) if _unitObj ~= nil then - local _zone = Evac._internal.aircraft.getZone(_unit) - return string.format('Load %i Evacuees', math.min((Evac.carryLimits[_unitObj:getTypeName()] or 0), Gremlin.utils.countTableEntries(Evac._state.extractableNow[_zone]))) + local _zone = Evac._internal.utils.getUnitZone(_unit) + return string.format('Load %i Evacuees (%i In Zone)', math.min((Evac.carryLimits[_unitObj:getTypeName()] or 0), Gremlin.utils.countTableEntries(Evac._state.extractableNow[_zone])), Gremlin.utils.countTableEntries(Evac._state.extractableNow[_zone])) end end, func = Evac.units.loadEvacuees, @@ -1213,9 +1218,11 @@ Evac._internal.menu = { if not Evac._internal.aircraft.inAir(_unit) and (Evac.zones.evac.isIn(_unit) or Evac.zones.relay.isIn(_unit)) then local _unitObj = Unit.getByName(_unit) if _unitObj ~= nil then - local _zone = Evac._internal.aircraft.getZone(_unit) - local _seats = math.min((Evac.carryLimits[_unitObj:getTypeName()] or 0), Gremlin.utils.countTableEntries(Evac._state.extractableNow[_zone])) - return _seats > Evac._internal.aircraft.countEvacuees(_unit) + local _zone = Evac._internal.utils.getUnitZone(_unit) + if _zone ~= nil then + local _seats = math.min((Evac.carryLimits[_unitObj:getTypeName()] or 0), Gremlin.utils.countTableEntries(Evac._state.extractableNow[_zone])) + return _seats > Evac._internal.aircraft.countEvacuees(_unit) + end end end @@ -1250,23 +1257,44 @@ Evac._internal.menu = { Evac._internal.utils = { currentGroup = Evac.idStart + 0, currentUnit = Evac.idStart + 0, + endIfEnoughGotOut = function() + Gremlin.log.trace(Evac.Id, string.format('Checking Whether To End The Mission')) + + for _side, _maxExtract in pairs(Evac.maxExtractable) do + local _saved = Evac._internal.utils.tallyEvacueesInZones(Evac._state.zones.safe) + + local _pilot = _saved['Ejected Pilot'] / _maxExtract['Ejected Pilot'] + local _infantry = _saved.Infantry / _maxExtract.Infantry + local _2b11 = _saved['2B11'] / _maxExtract['2B11'] + local _m249 = _saved.M249 / _maxExtract.M249 + local _rpg = _saved.RPG / _maxExtract.RPG + local _stingerIgla = _saved.StingerIgla / _maxExtract.StingerIgla + local _jtac = _saved.JTAC / _maxExtract.JTAC + local _combined = (_pilot + _infantry + _2b11 + _m249 + _rpg + _stingerIgla + _jtac) / 7 + + if (_combined > 0 and _combined >= (Evac.winThresholds[_side] / 100)) or + (_pilot > 0 and _pilot >= (Evac.winThresholds[_side] / 100)) then + trigger.action.setUserFlag(Evac.winFlags[_side], true) + end + end + end, endIfLossesTooHigh = function() Gremlin.log.trace(Evac.Id, string.format('Checking Whether To End The Mission')) for _side, _maxExtract in pairs(Evac.maxExtractable) do local _lost = Evac._state.lostEvacuees[_side] - local _generic = _lost['Ejected Pilot'] / _maxExtract['Ejected Pilot'] + local _pilot = _lost['Ejected Pilot'] / _maxExtract['Ejected Pilot'] local _infantry = _lost.Infantry / _maxExtract.Infantry local _2b11 = _lost['2B11'] / _maxExtract['2B11'] local _m249 = _lost.M249 / _maxExtract.M249 local _rpg = _lost.RPG / _maxExtract.RPG local _stingerIgla = _lost.StingerIgla / _maxExtract.StingerIgla local _jtac = _lost.JTAC / _maxExtract.JTAC - local _combined = (_generic + _infantry + _2b11 + _m249 + _rpg + _stingerIgla + _jtac) / 7 + local _combined = (_pilot + _infantry + _2b11 + _m249 + _rpg + _stingerIgla + _jtac) / 7 if (_combined > 0 and _combined >= (Evac.lossThresholds[_side] / 100)) or - (_generic > 0 and _generic >= (Evac.lossThresholds[_side] / 100)) then + (_pilot > 0 and _pilot >= (Evac.lossThresholds[_side] / 100)) then trigger.action.setUserFlag(Evac.lossFlags[_side], true) end end @@ -1280,6 +1308,20 @@ Evac._internal.utils = { return _menuUnits end, + getUnitZone = function(_unit) + Gremlin.log.trace(Evac.Id, string.format('Getting Unit Zone : %s', _unit)) + + local _zones = Gremlin.utils.getUnitZones(_unit) + local _outZones = {} + + for _, _zone in pairs(_zones) do + if Evac._state.zones.evac[_zone] ~= nil or Evac._state.zones.relay[_zone] ~= nil or Evac._state.zones.safe[_zone] ~= nil then + table.insert(_outZones, _zone) + end + end + + return _outZones[1] + end, getNextGroupId = function() Gremlin.log.trace(Evac.Id, string.format('Getting Next Group ID')) @@ -1309,6 +1351,25 @@ Evac._internal.utils = { return (math.random(90, 120) * (_weight or Evac.spawnWeight)) / 100 end, + tallyEvacueesInZones = function(_zoneList) + local _evacCounter = { + ['Ejected Pilot'] = 0, + Infantry = 0, + ['2B11'] = 0, + M249 = 0, + RPG = 0, + StingerIgla = 0, + JTAC = 0, + } + + for _zone, _ in pairs(_zoneList) do + for _, _evacuee in pairs(Evac._state.extractableNow[_zone]) do + _evacCounter[_evacuee.type] = (_evacCounter[_evacuee.type] or 0) + 1 + end + end + + return _evacCounter + end, unitDataToList = function(_units, _point, _scatterRadius) Gremlin.log.trace(Evac.Id, string.format('Converting Evac Unit Descriptions To DCS Internal Specs')) @@ -1332,7 +1393,7 @@ Evac._internal.utils = { end return _unitsOut - end + end, } -- Auto-spawn @@ -1503,7 +1564,7 @@ Evac._internal.doSpawns = function() ---@diagnostic disable-next-line: redefined-local for _zone, _zoneData in pairs(Evac._state.zones.evac) do if _zoneData.active then - _addedUnits = _addedUnits or _doLoop(_zone, _rates, _lastChecked) + _addedUnits = _doLoop(_zone, _rates, _lastChecked) or _addedUnits end end else @@ -1541,7 +1602,7 @@ Evac._internal.handlers = { if _unit ~= nil then local _name = _unit:getName() - if Evac._state.extractionUnits[_name] ~= nil and Gremlin.utils.countTableEntries(Evac._state.extractionUnits[_name]) > 0 then + if Evac._state.extractionUnits[_name] ~= nil and Evac._internal.aircraft.countEvacuees(_name) > 0 then local _side if Evac._state.extractionUnits[_name][0] ~= nil then @@ -1574,9 +1635,9 @@ Evac._internal.handlers = { end end - Gremlin.log.debug(Evac.Id, string.format('Lost Evacuees! : %s', mist.utils.tableShowSorted(Evac._state.extractionUnits[_name]))) + Gremlin.log.debug(Evac.Id, string.format('Lost Evacuee(s)! : %s', Evac._internal.aircraft.countEvacuees(_name))) - Gremlin.utils.displayMessageTo(Gremlin.SideToText[_side], string.format('We just lost %i evacuees! Step it up, pilots!', Gremlin.utils.countTableEntries(Evac._state.extractionUnits[_name])), 15) + Gremlin.utils.displayMessageTo(Gremlin.SideToText[_side], string.format('We just lost %i evacuee(s)! Step it up, pilots!', Evac._internal.aircraft.countEvacuees(_name)), 15) Evac._state.extractionUnits[_name] = { [0] = Evac._state.extractionUnits[_name][0], @@ -1588,6 +1649,26 @@ Evac._internal.handlers = { end end }, + takeControl = { + event = world.event.S_EVENT_BIRTH, + fn = function(_event) + Gremlin.log.trace(Evac.Id, string.format('Handling Spawn Event')) + + local _unit = _event.initiator + + if _unit ~= nil then + local _name = _unit:getName() + + if Evac._state.extractionUnits[_name] ~= nil then + Evac._state.extractionUnits[_name][0] = _unit + + Gremlin.log.debug(Evac.Id, string.format('Everyone welcome our newest pilot! : Unit %s Spawned by %s', _name, _unit:getPlayerName() or 'Unknown?')) + else + Gremlin.log.debug(Evac.Id, string.format('Not my circus, not my monkeys : Unit %s Spawned', _name)) + end + end + end + }, } --[[ diff --git a/src/gremlin.lua b/src/gremlin.lua index b3a6d49..be07548 100644 --- a/src/gremlin.lua +++ b/src/gremlin.lua @@ -120,7 +120,7 @@ Gremlin = { Gremlin.log.trace(Gremlin.Id, string.format('Updating F10 Menu For %i Units', Gremlin.utils.countTableEntries(forUnits))) - timer.scheduleFunction(Gremlin.menu.updateF10, {toolId, commands, forUnits}, timer.getTime() + 10) + timer.scheduleFunction(Gremlin.menu.updateF10, args, timer.getTime() + 10) for _unitName, _extractor in pairs(forUnits) do local _unit = _extractor or Unit.getByName(_unitName) @@ -193,23 +193,40 @@ Gremlin = { displayMessageTo = function(_name, _text, _time) if _name == 'all' or _name == 'Neutral' or _name == nil then trigger.action.outText(_text, _time) - elseif coalition.side[_name] ~= nil then - trigger.action.outTextForCoalition(coalition.side[_name], _text, _time) - elseif country.by_country[_name] ~= nil then - trigger.action.outTextForCountry(country.by_country[_name].WorldID, _text, _time) + elseif type(_name) == 'string' and coalition.side[string.upper(_name)] ~= nil then + trigger.action.outTextForCoalition(coalition.side[string.upper(_name)], _text, _time) + elseif type(_name) == 'string' and country[string.upper(_name)] ~= nil then + trigger.action.outTextForCountry(country[string.upper(_name)], _text, _time) elseif type(_name) == 'table' and _name.className_ == 'Group' then trigger.action.outTextForGroup(_name:getID(), _text, _time) - elseif Group.getByName(_name) ~= nil then + elseif type(_name) == 'string' and Group.getByName(_name) ~= nil then trigger.action.outTextForGroup(Group.getByName(_name):getID(), _text, _time) elseif type(_name) == 'table' and _name.className_ == 'Unit' then trigger.action.outTextForUnit(_name:getID(), _text, _time) - elseif Unit.getByName(_name) ~= nil then + elseif type(_name) == 'string' and Unit.getByName(_name) ~= nil then trigger.action.outTextForUnit(Unit.getByName(_name):getID(), _text, _time) else - Gremlin.log.error(Gremlin.Id, "Can't find object named " .. tostring(_name) .. - ' to display message to!\nMessage was: ' .. _text) + Gremlin.log.error(Gremlin.Id, string.format("Can't find object named %s to display message to!\nMessage was: %s", tostring(_name), _text)) end end, + getUnitZones = function(_unit) + Gremlin.log.trace(Gremlin.Id, string.format('Grabbing Unit Zone Names : %s', _unit)) + + local _outZones = {} + local _unitObj = Unit.getByName(_unit) + + if _unitObj ~= nil then + local _unitPoint = _unitObj:getPoint() + + for _zoneName, _ in pairs(mist.DBs.zonesByName) do + if mist.pointInZone(_unitPoint, _zoneName) then + table.insert(_outZones, _zoneName) + end + end + end + + return _outZones + end, parseFuncArgs = function(_args, _objs) local _out = {} for _, _arg in pairs(_args) do diff --git a/test/evac.lua b/test/evac.lua index c6aa75f..5042e9e 100644 --- a/test/evac.lua +++ b/test/evac.lua @@ -178,6 +178,7 @@ local tearDown = function() Gremlin.log.debug:reset() Gremlin.log.trace:reset() trigger.action.setUnitInternalCargo:reset() + trigger.action.setUserFlag:reset() trigger.action.outText:reset() trigger.action.outTextForCoalition:reset() trigger.action.outTextForCountry:reset() @@ -185,9 +186,9 @@ local tearDown = function() trigger.action.outTextForUnit:reset() end -Test0ZonesEvac = { +TestEvacZonesEvac = { setUp = setUp, - test0Register = function() + testRegister = function() -- INIT lu.assertEquals(Evac._state.zones.evac, { [_testZone] = { active = false, mode = 1, name = _testZone, side = 2, smoke = 0 } }) @@ -200,7 +201,7 @@ Test0ZonesEvac = { test2 = { active = false, mode = 1, name = 'test2', side = 1, smoke = 3 }, }) end, - test1Activate = function() + testActivate = function() -- INIT lu.assertEquals(Evac._state.zones.evac, { [_testZone] = { active = false, mode = 1, name = _testZone, side = 2, smoke = 0 } }) @@ -210,7 +211,7 @@ Test0ZonesEvac = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.evac, { [_testZone] = { active = true, mode = 1, name = _testZone, side = 2, smoke = 0 } }) end, - test2SetRemainingNumber = function() + testSetRemainingNumber = function() -- INIT Evac.beaconBatteryLife = 30 @@ -255,7 +256,7 @@ Test0ZonesEvac = { Evac.beaconBatteryLife = 0 end, - test3SetRemainingComposition = function() + testSetRemainingComposition = function() -- INIT Evac.beaconBatteryLife = 30 @@ -299,7 +300,7 @@ Test0ZonesEvac = { lu.assertEquals(Evac._state.extractableNow[_testZone], { ['Evacuee: Ejected Pilot #2'] = { unitName = 'Evacuee: Ejected Pilot #2', type = 'Ejected Pilot', unitId = 2, weight = 0 } }) end, - test4Count = function() + testCount = function() -- INIT lu.assertEquals(Evac._state.extractableNow[_testZone], { [_testUnit3.unitName] = _testEvacuee }) @@ -309,7 +310,7 @@ Test0ZonesEvac = { -- SIDE EFFECTS -- N/A? end, - test5IsIn = function() + testIsIn = function() -- INIT lu.assertEquals(Evac.zones.evac.activate(_testZone), nil) lu.assertEquals(Evac._state.extractableNow[_testZone], { [_testUnit3.unitName] = _testEvacuee }) @@ -321,7 +322,7 @@ Test0ZonesEvac = { -- SIDE EFFECTS -- N/A? end, - test6Deactivate = function() + testDeactivate = function() -- INIT lu.assertEquals(Evac.zones.evac.activate(_testZone), nil) lu.assertEquals(Evac._state.zones.evac, { [_testZone] = { active = true, mode = 1, name = _testZone, side = 2, smoke = 0 } }) @@ -332,7 +333,7 @@ Test0ZonesEvac = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.evac, { [_testZone] = { active = false, mode = 1, name = _testZone, side = 2, smoke = 0 } }) end, - test7Unregister = function() + testUnregister = function() -- INIT lu.assertEquals(Evac._state.zones.evac, { [_testZone] = { active = false, mode = 1, name = _testZone, side = 2, smoke = 0 } }) @@ -345,9 +346,9 @@ Test0ZonesEvac = { tearDown = tearDown, } -Test1ZonesRelay = { +TestEvacZonesRelay = { setUp = setUp, - test0Register = function() + testRegister = function() -- INIT lu.assertEquals(Evac._state.zones.relay, {}) @@ -357,7 +358,7 @@ Test1ZonesRelay = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.relay, { [_testZone] = { active = false, mode = 3, name = _testZone, side = 2, smoke = 0 } }) end, - test1Activate = function() + testActivate = function() -- INIT lu.assertEquals(Evac.zones.relay.register(_testZone, trigger.smokeColor.Green, 2), nil) lu.assertEquals(Evac._state.zones.relay, { [_testZone] = { active = false, mode = 3, name = _testZone, side = 2, smoke = 0 } }) @@ -368,7 +369,7 @@ Test1ZonesRelay = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.relay, { [_testZone] = { active = true, mode = 3, name = _testZone, side = 2, smoke = 0 } }) end, - test2SetRemainingNumber = function() + testSetRemainingNumber = function() -- INIT lu.assertEquals(Evac._state.extractableNow[_testZone], { [_testUnit3.unitName] = _testEvacuee }) @@ -379,7 +380,7 @@ Test1ZonesRelay = { lu.assertEquals(Evac._state.extractableNow[_testZone], { ['Evacuee: Ejected Pilot #2'] = { unitName = 'Evacuee: Ejected Pilot #2', type = 'Ejected Pilot', unitId = 2, weight = 0 } }) end, - test3SetRemainingComposition = function() + testSetRemainingComposition = function() -- INIT lu.assertEquals(Evac._state.extractableNow[_testZone], { [_testUnit3.unitName] = _testEvacuee }) @@ -390,7 +391,7 @@ Test1ZonesRelay = { lu.assertEquals(Evac._state.extractableNow[_testZone], { ['Evacuee: Ejected Pilot #2'] = { unitName = 'Evacuee: Ejected Pilot #2', type = 'Ejected Pilot', unitId = 2, weight = 0 } }) end, - test4Count = function() + testCount = function() -- INIT Evac._state.zones.relay[_testZone] = _testZoneData lu.assertEquals(Evac._state.extractableNow[_testZone], { [_testUnit3.unitName] = _testEvacuee }) @@ -401,7 +402,7 @@ Test1ZonesRelay = { -- SIDE EFFECTS -- N/A? end, - test5IsIn = function() + testIsIn = function() -- INIT Evac._state.zones.relay[_testZone] = _testZoneData lu.assertEquals(Evac.zones.relay.register(_testZone, trigger.smokeColor.Green, 2), nil) @@ -415,7 +416,7 @@ Test1ZonesRelay = { -- SIDE EFFECTS -- N/A? end, - test6Deactivate = function() + testDeactivate = function() -- INIT Evac._state.zones.relay[_testZone] = _testZoneData lu.assertEquals(Evac.zones.relay.activate(_testZone), nil) @@ -427,7 +428,7 @@ Test1ZonesRelay = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.relay, { [_testZone] = _testZoneData }) end, - test7Unregister = function() + testUnregister = function() -- INIT Evac._state.zones.relay[_testZone] = _testZoneData lu.assertEquals(Evac._state.zones.relay, { [_testZone] = _testZoneData }) @@ -441,9 +442,9 @@ Test1ZonesRelay = { tearDown = tearDown, } -Test2ZonesSafe = { +TestEvacZonesSafe = { setUp = setUp, - test0Register = function() + testRegister = function() -- INIT lu.assertEquals(Evac._state.zones.safe, {}) @@ -453,7 +454,7 @@ Test2ZonesSafe = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.safe, { [_testZone] = { active = false, mode = 2, name = _testZone, side = 2, smoke = 0 } }) end, - test1Activate = function() + testActivate = function() -- INIT lu.assertEquals(Evac._state.zones.safe, {}) lu.assertEquals(Evac.zones.safe.register(_testZone, trigger.smokeColor.Green, 2), nil) @@ -465,7 +466,7 @@ Test2ZonesSafe = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.safe, { [_testZone] = { active = true, mode = 2, name = _testZone, side = 2, smoke = 0 } }) end, - test2Count = function() + testCount = function() -- INIT Evac._state.zones.safe[_testZone] = _testZoneData lu.assertEquals(Evac._state.extractableNow[_testZone], { [_testUnit3.unitName] = _testEvacuee }) @@ -476,7 +477,7 @@ Test2ZonesSafe = { -- SIDE EFFECTS -- N/A? end, - test3IsIn = function() + testIsIn = function() -- INIT lu.assertEquals(Evac.zones.safe.register(_testZone, trigger.smokeColor.Green, 2), nil) lu.assertEquals(Evac.zones.safe.activate(_testZone), nil) @@ -491,7 +492,7 @@ Test2ZonesSafe = { -- SIDE EFFECTS -- N/A? end, - test4Deactivate = function() + testDeactivate = function() -- INIT lu.assertEquals(Evac.zones.safe.register(_testZone, trigger.smokeColor.Green, 2), nil) lu.assertEquals(Evac.zones.safe.activate(_testZone), nil) @@ -503,7 +504,7 @@ Test2ZonesSafe = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.safe, { [_testZone] = { active = false, mode = 2, name = _testZone, side = 2, smoke = 0 } }) end, - test5Unregister = function() + testUnregister = function() -- INIT Evac._state.zones.safe[_testZone] = _testZoneData lu.assertEquals(Evac._state.zones.safe, { [_testZone] = _testZoneData }) @@ -517,9 +518,9 @@ Test2ZonesSafe = { tearDown = tearDown, } -Test3Units = { +TestEvacUnits = { setUp = setUp, - test0Register = function() + testRegister = function() -- INIT Evac._state.extractionUnits = {} lu.assertEquals(Evac._state.extractionUnits[_testUnit2.unitName], nil) @@ -530,7 +531,7 @@ Test3Units = { -- SIDE EFFECTS lu.assertNotEquals(Evac._state.extractionUnits[_testUnit2.unitName], nil) end, - test1FindEvacuees = function() + testFindEvacuees = function() -- INIT local _args = { _testUnit:getGroup():getID(), 'No Active Evacuation Beacons', 15 } trigger.action.outTextForGroup:whenCalled({ with = _args, thenReturn = nil }) @@ -546,7 +547,7 @@ Test3Units = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(trigger.action.outTextForGroup.spy.calls))) end, - test2LoadEvacuees = function() + testLoadEvacuees = function() -- INIT local _args = {_testUnit:getID(), "Your aircraft isn't rated for evacuees in this mission!", timer.getTime() + 1 } trigger.action.outTextForUnit:whenCalled({ with = _args, thenReturn = nil }) @@ -562,7 +563,7 @@ Test3Units = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(trigger.action.outTextForUnit.spy.calls))) end, - test3UnloadEvacuees = function() + testUnloadEvacuees = function() -- INIT local _args = {_testUnit:getID(), 'Not in an active relay or safe zone! Try looking elsewhere.', 5 } trigger.action.outTextForUnit:whenCalled({ with = _args, thenReturn = nil }) @@ -578,7 +579,7 @@ Test3Units = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(trigger.action.outTextForUnit.spy.calls))) end, - test4CountEvacuees = function() + testCountEvacuees = function() -- INIT local _args = {_testUnit:getID(), 'You are currently carrying 0 evacuees.', timer.getTime() + 1 } trigger.action.outTextForUnit:whenCalled({ with = _args, thenReturn = nil }) @@ -594,7 +595,7 @@ Test3Units = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(trigger.action.outTextForUnit.spy.calls))) end, - test5Count = function() + testCount = function() -- INIT -- N/A? @@ -604,7 +605,7 @@ Test3Units = { -- SIDE EFFECTS -- N/A? end, - test6Unregister = function() + testUnregister = function() -- INIT lu.assertEquals(Evac.units.register(_testUnit2), nil) lu.assertNotEquals(Evac._state.extractionUnits[_testUnit2.unitName], nil) @@ -618,9 +619,9 @@ Test3Units = { tearDown = tearDown, } -Test4Groups = { +TestEvacGroups = { setUp = setUp, - test0SpawnNumber = function() + testSpawnNumber = function() -- INIT Evac.beaconBatteryLife = 30 @@ -692,7 +693,7 @@ Test4Groups = { -- SIDE EFFECTS Evac.beaconBatteryLife = 0 end, - test1SpawnComposition = function() + testSpawnComposition = function() -- INIT Evac.beaconBatteryLife = 30 @@ -754,7 +755,7 @@ Test4Groups = { -- SIDE EFFECTS Evac.beaconBatteryLife = 0 end, - test2List = function() + testList = function() -- INIT lu.assertEquals(Evac._state.extractableNow[_testZone], { [_testUnit3.unitName] = _testEvacuee }) @@ -764,7 +765,7 @@ Test4Groups = { -- SIDE EFFECTS -- N/A? end, - test3Count = function() + testCount = function() -- INIT -- N/A? @@ -777,19 +778,9 @@ Test4Groups = { tearDown = tearDown, } -Test5Internal0Aircraft = { +TestEvacInternalAircraft = { setUp = setUp, - test0GetZone = function() - -- INIT - lu.assertEquals(Evac.zones.evac.activate(_testZone), nil) - - -- TEST - lu.assertEquals(Evac._internal.aircraft.getZone(_testUnit.unitName), _testZone) - - -- SIDE EFFECTS - -- N/A? - end, - test1InZone = function() + testInZone = function() -- INIT lu.assertEquals(Evac.zones.evac.activate(_testZone), nil) @@ -799,7 +790,7 @@ Test5Internal0Aircraft = { -- SIDE EFFECTS -- N/A? end, - test2InAir = function() + testInAir = function() -- INIT -- N/A? @@ -809,7 +800,7 @@ Test5Internal0Aircraft = { -- SIDE EFFECTS -- N/A? end, - test3HeightDifference = function() + testHeightDifference = function() -- INIT -- N/A? @@ -819,7 +810,7 @@ Test5Internal0Aircraft = { -- SIDE EFFECTS -- N/A? end, - test4LoadEvacuees = function() + testLoadEvacuees = function() -- INIT local _args = {_testUnit:getID(), 'Not in an active evac or relay zone! Try looking elsewhere.', 5 } trigger.action.outTextForUnit:whenCalled({ with = _args, thenReturn = nil }) @@ -835,7 +826,7 @@ Test5Internal0Aircraft = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(trigger.action.outTextForUnit.spy.calls))) end, - test5CountEvacuees = function() + testCountEvacuees = function() -- INIT -- N/A? @@ -845,7 +836,7 @@ Test5Internal0Aircraft = { -- SIDE EFFECTS -- N/A? end, - test6CalculateWeight = function() + testCalculateWeight = function() -- INIT -- N/A? @@ -855,7 +846,7 @@ Test5Internal0Aircraft = { -- SIDE EFFECTS -- N/A? end, - test7AdaptWeight = function() + testAdaptWeight = function() -- INIT trigger.action.setUnitInternalCargo:whenCalled({ with = { _testUnit.unitName, 0 }, thenReturn = nil }) @@ -870,7 +861,7 @@ Test5Internal0Aircraft = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(trigger.action.setUnitInternalCargo.spy.calls))) end, - test8UnloadEvacuees = function() + testUnloadEvacuees = function() -- INIT local _args = {_testUnit:getID(), 'Not in an active relay or safe zone! Try looking elsewhere.', 5 } trigger.action.outTextForUnit:whenCalled({ with = _args, thenReturn = nil }) @@ -889,9 +880,9 @@ Test5Internal0Aircraft = { tearDown = tearDown, } -Test5Internal1Beacons = { +TestEvacInternalBeacons = { setUp = setUp, - test0Spawn = function() + testSpawn = function() -- INIT Evac.beaconBatteryLife = 30 @@ -940,7 +931,7 @@ Test5Internal1Beacons = { -- SIDE EFFECTS Evac.beaconBatteryLife = 0 end, - test1GetFreeADFFrequencies = function() + testGetFreeADFFrequencies = function() -- INIT -- N/A? @@ -954,7 +945,7 @@ Test5Internal1Beacons = { -- SIDE EFFECTS -- N/A? end, - test2List = function() + testList = function() -- INIT local _args = {_testUnit:getGroup():getID(), 'Evacuation Beacons:\nGroup #2 - Beacon #1 (840.00 kHz - 277.50 / 32.15 MHz)\n', 15 } @@ -972,7 +963,7 @@ Test5Internal1Beacons = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(trigger.action.outTextForGroup.spy.calls))) end, - test3Update = function() + testUpdate = function() -- INIT local _radioGroup = { battery = 1800, @@ -1025,7 +1016,7 @@ Test5Internal1Beacons = { -- SIDE EFFECTS Evac.beaconBatteryLife = 0 end, - test4KillDead = function() + testKillDead = function() -- INIT -- N/A? @@ -1040,7 +1031,7 @@ Test5Internal1Beacons = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(timer.scheduleFunction.calls))) end, - test5GenerateVHFrequencies = function() + testGenerateVHFrequencies = function() -- INIT -- N/A? @@ -1104,7 +1095,7 @@ Test5Internal1Beacons = { 1250000 }) end, - test6GenerateUHFrequencies = function() + testGenerateUHFrequencies = function() -- INIT -- N/A? @@ -1473,7 +1464,7 @@ Test5Internal1Beacons = { 398500000 }) end, - test7GenerateFMFrequencies = function() + testGenerateFMFrequencies = function() -- INIT -- N/A? @@ -2087,9 +2078,9 @@ Test5Internal1Beacons = { tearDown = tearDown, } -Test5Internal2Smoke = { +TestEvacInternalSmoke = { setUp = setUp, - test0Refresh = function() + testRefresh = function() -- INIT trigger.action.smoke:whenCalled({ with = { nil, trigger.smokeColor.Green }, thenReturn = nil }) lu.assertEquals(Evac._internal.zones.activate(_testZone, Evac.modes.EVAC)) @@ -2115,9 +2106,9 @@ Test5Internal2Smoke = { tearDown = tearDown, } -Test5Internal3Zones = { +TestEvacInternalZones = { setUp = setUp, - test0Register = function() + testRegister = function() -- INIT local _testName = 'register' @@ -2137,7 +2128,7 @@ Test5Internal3Zones = { }) lu.assertEquals(Evac._state.extractableNow[_testName], {}) end, - test1GenerateEvacueesByNumber = function() + testGenerateEvacueesByNumber = function() -- INIT -- N/A? @@ -2154,7 +2145,7 @@ Test5Internal3Zones = { -- SIDE EFFECTS -- N/A? end, - test2GenerateEvacueesByComposition = function() + testGenerateEvacueesByComposition = function() -- INIT -- N/A? @@ -2171,7 +2162,7 @@ Test5Internal3Zones = { -- SIDE EFFECTS -- N/A? end, - test3Activate = function() + testActivate = function() -- INIT lu.assertEquals(Evac._state.zones.evac[_testZone].active, false) @@ -2181,7 +2172,7 @@ Test5Internal3Zones = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.evac[_testZone].active, true) end, - test4SetRemainingNumber = function() + testSetRemainingNumber = function() -- INIT lu.assertEquals(Evac._state.extractableNow[_testZone], { [_testUnit3.unitName] = _testEvacuee }) @@ -2191,7 +2182,7 @@ Test5Internal3Zones = { -- SIDE EFFECTS lu.assertEquals(Evac._state.extractableNow[_testZone], { ['Evacuee: Ejected Pilot #2'] = { type = 'Ejected Pilot', unitId = 2, unitName = 'Evacuee: Ejected Pilot #2', weight = 0 } }) end, - test5SetRemainingComposition = function() + testSetRemainingComposition = function() -- INIT lu.assertEquals(Evac._state.extractableNow[_testZone], { [_testUnit3.unitName] = _testEvacuee }) @@ -2201,7 +2192,7 @@ Test5Internal3Zones = { -- SIDE EFFECTS lu.assertEquals(Evac._state.extractableNow[_testZone], { ['Evacuee: Ejected Pilot #2'] = { type = 'Ejected Pilot', unitId = 2, unitName = 'Evacuee: Ejected Pilot #2', weight = 0 } }) end, - test6Count = function() + testCount = function() -- INIT -- N/A? @@ -2211,7 +2202,7 @@ Test5Internal3Zones = { -- SIDE EFFECTS -- N/A? end, - test7IsIn = function() + testIsIn = function() -- INIT lu.assertEquals(Evac._internal.zones.activate(_testZone, Evac.modes.EVAC), nil) @@ -2221,7 +2212,7 @@ Test5Internal3Zones = { -- SIDE EFFECTS -- N/A? end, - test8Deactivate = function() + testDeactivate = function() -- INIT lu.assertEquals(Evac._state.zones.evac[_testZone].active, false) lu.assertEquals(Evac._internal.zones.activate(_testZone, Evac.modes.EVAC), nil) @@ -2233,7 +2224,7 @@ Test5Internal3Zones = { -- SIDE EFFECTS lu.assertEquals(Evac._state.zones.evac[_testZone].active, false) end, - test9Unregister = function() + testUnregister = function() -- INIT lu.assertEquals(Evac._state.zones.evac[_testZone], { active = false, @@ -2254,9 +2245,9 @@ Test5Internal3Zones = { tearDown = tearDown, } -Test5Internal4Utils = { +TestEvacInternalUtils = { setUp = setUp, - test0EndIfLossesTooHigh = function() + testEndIfLossesTooHigh = function() -- INIT trigger.action.setUserFlag:whenCalled({ with = { 1, true }, thenReturn = nil }) trigger.action.setUserFlag:whenCalled({ with = { 2, true }, thenReturn = nil }) @@ -2301,7 +2292,7 @@ Test5Internal4Utils = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(trigger.action.setUserFlag.spy.calls))) end, - test1GetNextGroupId = function() + testGetNextGroupId = function() -- INIT -- N/A? @@ -2311,7 +2302,7 @@ Test5Internal4Utils = { -- SIDE EFFECTS -- N/A? end, - test2GetNextUnitId = function() + testGetNextUnitId = function() -- INIT -- N/A? @@ -2321,7 +2312,7 @@ Test5Internal4Utils = { -- SIDE EFFECTS -- N/A? end, - test3RandomizeWeight = function() + testRandomizeWeight = function() -- INIT -- N/A? @@ -2337,7 +2328,7 @@ Test5Internal4Utils = { -- SIDE EFFECTS -- N/A? end, - test4UnitDataToList = function() + testUnitDataToList = function() -- INIT -- N/A? @@ -2363,9 +2354,9 @@ Test5Internal4Utils = { tearDown = tearDown, } -Test5Internal5DoSpawns = { +TestEvacInternalDoSpawns = { setUp = setUp, - test0DoSpawnsFirstPass = function() + testDoSpawnsFirstPass = function() -- INIT Evac.zones.evac.activate(_testZone) @@ -2376,7 +2367,7 @@ Test5Internal5DoSpawns = { lu.assertNotEquals(Evac._state.spawns.lastChecked[0], nil) lu.assertEquals(Evac._state.spawns.alreadySpawned, Evac.maxExtractable) end, - test1DoSpawnsSecondPass = function() + testDoSpawnsSecondPass = function() -- INIT Evac.zones.evac.activate(_testZone) @@ -2397,10 +2388,11 @@ Test5Internal5DoSpawns = { tearDown = tearDown, } -Test5Internal6Handlers = { +TestEvacInternalHandlers = { setUp = setUp, - test0FullLoss = function() + testFullLoss = function() -- INIT + trigger.action.outTextForCoalition:whenCalled({ with = { 2, 'We just lost 1 evacuee(s)! Step it up, pilots!', 15 }, thenReturn = nil }) trigger.action.setUserFlag:whenCalled({ with = { 1, true }, thenReturn = nil }) trigger.action.setUserFlag:whenCalled({ with = { 2, true }, thenReturn = nil }) @@ -2453,12 +2445,27 @@ Test5Internal6Handlers = { ) lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(trigger.action.setUserFlag.spy.calls))) end, + testTakeControl = function() + -- INIT + Evac._state.extractionUnits[_testUnit.unitName] = {} + + -- TEST + lu.assertEquals(Evac._internal.handlers.takeControl.fn({ id = world.event.S_EVENT_BIRTH, initiator = _testUnit })) + + -- SIDE EFFECTS + local _status, _result = pcall( + Gremlin.log.debug.assertAnyCallMatches, + Gremlin.log.debug, + { arguments = { Evac.Id, string.format('Everyone welcome our newest pilot! : Unit %s Spawned by %s', _testUnit:getName(), _testUnit:getPlayerName()) } } + ) + lu.assertEquals(_status, true, string.format('%s\n%s', inspect(_result), inspect(Gremlin.log.debug.calls))) + end, tearDown = tearDown, } -Test6TopLevel = { +TestEvacTopLevel = { setUp = setUp, - test0SetupNone = function() + testSetupNone = function() -- INIT trigger.action.setUserFlag:whenCalled({ with = { 'GremlinEvacRedLoss', false }, thenReturn = nil }) trigger.action.setUserFlag:whenCalled({ with = { 'GremlinEvacBlueLoss', false }, thenReturn = nil }) @@ -2509,7 +2516,7 @@ Test6TopLevel = { lu.assertEquals(Evac.spawnRates, { _global = { { per = 0, period = 1, units = 0 }, { per = 0, period = 1, units = 0 } } }) lu.assertEquals(Evac.spawnWeight, 100) end, - test1SetupBlank = function() + testSetupBlank = function() -- INIT trigger.action.setUserFlag:whenCalled({ with = { 'GremlinEvacRedLoss', false }, thenReturn = nil }) trigger.action.setUserFlag:whenCalled({ with = { 'GremlinEvacBlueLoss', false }, thenReturn = nil }) @@ -2560,7 +2567,7 @@ Test6TopLevel = { lu.assertEquals(Evac.spawnRates, { _global = { { per = 0, period = 1, units = 0 }, { per = 0, period = 1, units = 0 } } }) lu.assertEquals(Evac.spawnWeight, 100) end, - test2SetupConfig = function() + testSetupConfig = function() -- INIT trigger.action.setUserFlag:whenCalled({ with = { 'GremlinEvacRedLoss', false }, thenReturn = nil }) trigger.action.setUserFlag:whenCalled({ with = { 'GremlinEvacBlueLoss', false }, thenReturn = nil }) diff --git a/test/gremlin.lua b/test/gremlin.lua index 477ff20..c5c2d77 100644 --- a/test/gremlin.lua +++ b/test/gremlin.lua @@ -101,6 +101,7 @@ local tearDown = function() Gremlin.log.debug:reset() Gremlin.log.trace:reset() trigger.action.setUnitInternalCargo:reset() + trigger.action.setUserFlag:reset() trigger.action.outText:reset() trigger.action.outTextForCoalition:reset() trigger.action.outTextForCountry:reset() @@ -108,9 +109,9 @@ local tearDown = function() trigger.action.outTextForUnit:reset() end -Test0Menu = { +TestGremlinMenu = { setUp = setUp, - test0UpdateF10 = function() + testUpdateF10 = function() -- INIT local _testCommands = { { @@ -193,3 +194,18 @@ Test0Menu = { end, tearDown = tearDown, } + +TestGremlinUtils = { + setUp = setUp, + testGetUnitZones = function() + -- INIT + -- N/A? + + -- TEST + lu.assertEquals(Gremlin.utils.getUnitZones(_testUnit.unitName), { _testZone }) + + -- SIDE EFFECTS + -- N/A? + end, + tearDown = tearDown, +}