Skip to content

Commit

Permalink
Rearrange things and add GHA automation, README
Browse files Browse the repository at this point in the history
  • Loading branch information
danhunsaker committed Mar 10, 2024
1 parent 1fe638e commit 54b0e10
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 16 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/evac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: "Gremlin Evac"

on:
push:

jobs:
test:
name: Test
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: ilammy/msvc-dev-cmd@v1
- uses: leafo/gh-actions-lua@v10
with:
luaVersion: "5.1"
- run: .\lib\DCS_World_web.exe
- run: .\runtests.bat
106 changes: 106 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Gremlin Scripts

This is the Gremlin Scripts repo! Everything you need to succeed with DCS mission scripting can be found within.

## Installation

Simply copy the contents of the `src` directory to your `Missions` folder in `Saved Games`. If you like, you can also grab MiST from this project's `lib` folder, though it's usually best to grab the latest version [directly from GitHub](https://github.com/mrSkortch/MissionScriptingTools).

Once you have the files in place, add a trigger to load MiST (follow its documentation for the best ways to do this), a second to load Gremlin Script Tools, and then a third to load the exact script you wish to use, such as Gremlin Evac. Once all three are loaded, the final step is to fully set up the script(s) to do their thing - see the relevant Configuration section, below, for more on this.

And that's it! The scripts are installed and working from this point on.

## Components

### gremlin.lua

The Gremlin Script Tools file provides common features that all Gremlin Scripts use to do their thing. It must be loaded after MiST, and before any other Gremlin Scripts components.

### evac.lua

The Gremlin Evac script sets up your missions to include evacuation scenarios. Simply call `Evac:setup({})` to get sane defualts, or customize everything by filling out the available options you wish to override.

#### Configuration

```lua
Evac:setup({
beaconBatteryLife = 2,
beaconSound = "test.ogg",
carryLimits = {
["Test"] = 15,
},
idStart = 5,
loadUnloadPerIndividual = 2,
maxExtractable = {
Refugees = 12,
Infantry = 12,
M249 = 12,
RPG = 12,
StingerIgla = 12,
["2B11"] = 12,
JTAC = 3,
},
spawnWeight = 50,
spawnRates = {
test = {
units = 12,
per = 5,
period = Gremlin.Periods.Minute,
},
},
startingZones = {
{ mode = Evac.modes.EVAC, name = "Test 1", smoke = trigger.smokeColors.Green, side = coalition.side.BLUE },
{ mode = Evac.modes.RELAY, name = "Test 2", smoke = trigger.smokeColors.Orange, side = coalition.side.BLUE },
{ mode = Evac.modes.SAFE, name = "Test 3", smoke = trigger.smokeColors.White, side = coalition.side.BLUE },
},
})
```

- `beaconBatteryLife`: How long beacons should broadcast once spawned, in minutes
- Default: `30`

- `beaconSound`: The audio file name to play for radio beacons
- Default: `beacon.ogg`

- `carryLimits`: Specifies the maximum capacity loadout per aircraft designator
- Default: `{ ["C-130"] = 90, ["CH-47D"] = 44, ["CH-43E"] = 55, ["Mi-8MT"] = 24, ["Mi-24P"] = 5, ["Mi-24V"] = 5, ["Mi-26"] = 70, ["SH-60B"] = 5, ["UH-1H"] = 8, ["UH-60A"] = 11 }`

- `idStart`: The lowest ID number that Gremlin Evac will use to create units and groups
- Default: `500`

- `loadUnloadPerIndividual`: The amount of time it takes to load/unload a single evacuee onto/from an aircraft, in seconds
- Default: `30`

- `maxExtractable`: Provides a cap for automatically generated evacuees, by type; the script won't create more than allowed here
- Default: `0` for everything

- `spawnWeight`: The average weight of an evacuee - the exact weight used will vary between 90% and 120% of this value
- Default: `100`

- `spawnRates`: Describes how and when to spawn evacuee units/groups
- Default: `{ _global = { units = 0, per = 0, period = Gremlin.Periods.Second } }` (everything at mission start)
- Spec
- key: Zone name
- value: table
- `units`: Number or composition of units to spawn
- `per`: Number of periods to wait between spawns
- `0`: At setup time, no repeat
- `< 0`: After `math.abs(per)` periods, no repeat
- `> 0`: Every `per` periods, until `maxExtractable` is reached
- `period`: One of the `Gremlin.Periods` constants indicating how long a single period lasts

- `startingZones`: Registers zones for evacuation purposes during setup
- Default: `{}`
- Spec
- key: ignored
- value: table
- `mode`: One of the `Evac.modes` constants, indicating what evacuation mode the zone should be registered using
- `name`: Zone name - MUST MATCH THE MISSION EDITOR'S NAME FOR THE ZONE EXACTLY!
- `smoke`: Smoke color, taken from `trigger.smokeColors`
- `side`: Coalition, taken from `coalition.side`

## Development and Testing

Gremlin Scripts are fully tested before release. You can run these tests yourself by simply running `runtests.bat` at the top level of this project. It will run _all_ defined tests, at the moment, but that's fine since only Gremlin Evac is available today.

Development follows standard project rules for Git - create a fork, make your changes on a new branch, submit a PR on GitHub, and we'll review and do our best to merge. If none of these words make any sense to you, let us know and we'll help you figure something out.
Binary file added lib/DCS_World_web.exe
Binary file not shown.
4 changes: 2 additions & 2 deletions test/mock/Mock.lua → lib/mock/Mock.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
-- See @{Spy} and @{ProgrammableFn} for details.


local ProgrammableFn = require 'test.mock.ProgrammableFn'
local Spy = require 'test.mock.Spy'
local ProgrammableFn = require 'lib.mock.ProgrammableFn'
local Spy = require 'lib.mock.Spy'


local Mock = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
-- return values.


local ValueMatcher = require 'test.mock.ValueMatcher'
local ValueMatcher = require 'lib.mock.ValueMatcher'


local ProgrammableFn = {}
Expand Down
2 changes: 1 addition & 1 deletion test/mock/Spy.lua → lib/mock/Spy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
-- For each call the arguments and return values are saved.


local ValueMatcher = require 'test.mock.ValueMatcher'
local ValueMatcher = require 'lib.mock.ValueMatcher'


local Spy = {}
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions mocks/DCS.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
local Mock = require("test.mock.Mock")
local Spy = require("test.mock.Spy")
local Mock = require("lib.mock.Mock")
local Spy = require("lib.mock.Spy")
require("Scripts.Common.LuaClass")

Object = {
Expand Down
8 changes: 6 additions & 2 deletions src/evac.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,11 @@ function Evac:setup(config)
return
end

if config ~= nil then
do -- configuration
if config == nil then
config = {}
end

Evac.beaconBatteryLife = config.beaconBatteryLife or 30
Evac.beaconSound = config.beaconSound or "beacon.ogg"
Evac.carryLimits = config.carryLimits or {
Expand Down Expand Up @@ -1163,7 +1167,7 @@ function Evac:setup(config)
end
end
end
end
end -- configuration

Evac._internal.beacons.generateVHFrequencies()
Evac._internal.beacons.generateUHFrequencies()
Expand Down
27 changes: 19 additions & 8 deletions test/evac.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local lu = require("luaunit_3_4")
local inspect = require("inspect")
local Spy = require("test.mock.Spy")
local Spy = require("lib.mock.Spy")

table.unpack = table.unpack or unpack
unpack = table.unpack
Expand Down Expand Up @@ -1749,11 +1749,22 @@ Test6TopLevel = {
test1SetupNone = function()
lu.assertEquals(Evac:setup(), nil)

lu.assertEquals(Evac.beaconBatteryLife, 0)
lu.assertEquals(Evac.beaconSound, "")
lu.assertEquals(Evac.carryLimits, {})
lu.assertEquals(Evac.idStart, 0)
lu.assertEquals(Evac.loadUnloadPerIndividual, 0)
lu.assertEquals(Evac.beaconBatteryLife, 30)
lu.assertEquals(Evac.beaconSound, "beacon.ogg")
lu.assertEquals(Evac.carryLimits, {
["C-130"] = 90,
["CH-47D"] = 44,
["CH-43E"] = 55,
["Mi-8MT"] = 24,
["Mi-24P"] = 5,
["Mi-24V"] = 5,
["Mi-26"] = 70,
["SH-60B"] = 5,
["UH-1H"] = 8,
["UH-60A"] = 11,
})
lu.assertEquals(Evac.idStart, 500)
lu.assertEquals(Evac.loadUnloadPerIndividual, 30)
lu.assertEquals(Evac.maxExtractable, {
Refugees = 0,
Infantry = 0,
Expand All @@ -1763,8 +1774,8 @@ Test6TopLevel = {
["2B11"] = 0,
JTAC = 0,
})
lu.assertEquals(Evac.spawnRates, {})
lu.assertEquals(Evac.spawnWeight, 0)
lu.assertEquals(Evac.spawnRates, { _global = { per = 0, period = 1, units = 0 } })
lu.assertEquals(Evac.spawnWeight, 100)
end,
test2SetupBlank = function()
lu.assertEquals(Evac:setup({}), nil)
Expand Down

0 comments on commit 54b0e10

Please sign in to comment.