Merge pull request #12 from spencershepard/develop

Develop
This commit is contained in:
spencershepard 2022-01-19 22:41:18 -08:00 committed by GitHub
commit a30d251ebd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 334 additions and 85 deletions

View File

@ -1,22 +1,34 @@
RotorOps = {}
RotorOps.version = "1.0.11"
RotorOps.version = "1.2.1"
--RotorOps settings that are safe to change dynamically (ideally from the mission editor in DO SCRIPT for ease of use)
---[[ROTOROPS OPTIONS]]---
--- Protip: change these options from the mission editor rather than changing the script file itself. See documentation on github for details.
--RotorOps settings that are safe to change dynamically (ideally from the mission editor in DO SCRIPT for portability). You can change these while the script is running, at any time.
RotorOps.voice_overs = true
RotorOps.ground_speed = 60 --max speed for ground vehicles moving between zones
RotorOps.zone_status_display = true --constantly show units remaining and zone status on screen
RotorOps.max_units_left = 0 --allow clearing the zone when a few units are left to prevent frustration with units getting stuck in buildings etc
RotorOps.force_offroad = false --affects "move_to_zone" tasks only
RotorOps.apcs_spawn_infantry = false --apcs will unload troops when arriving to a new zone
--RotorOps settings that are proabably safe to change
--RotorOps settings that are safe to change only before calling setupConflict()
RotorOps.transports = {'UH-1H', 'Mi-8MT', 'Mi-24P', 'SA342M', 'SA342L', 'SA342Mistral'} --players flying these will have ctld transport access
RotorOps.auto_push = true --should attacking ground units move to the next zone after clearing?
RotorOps.CTLD_crates = false
RotorOps.CTLD_sound_effects = true --sound effects for troop pickup/dropoffs
RotorOps.exclude_ai_group_name = "noai" --include this somewhere in a group name to exclude the group from being tasked in the active zone
---[[END OF OPTIONS]]---
--RotorOps variables that are safe to read only
RotorOps.game_states = {not_started = 0, alpha_active = 1, bravo_active = 2, charlie_active = 3, delta_active = 4, won = 99} --game level user flag will use these values
RotorOps.game_states = {not_started = 0, alpha_active = 1, bravo_active = 2, charlie_active = 3, delta_active = 4, lost = 98, won = 99} --game level user flag will use these values
RotorOps.game_state = 0
RotorOps.zones = {}
RotorOps.active_zone = "" --name of the active zone
@ -24,22 +36,27 @@ RotorOps.active_zone_index = 0
RotorOps.game_state_flag = 1 --user flag to store the game state
RotorOps.staging_zone = ""
RotorOps.ctld_pickup_zones = {} --keep track of ctld zones we've added, mainly for map markup
RotorOps.ai_red_infantry_groups = {}
RotorOps.ai_blue_infantry_groups = {}
RotorOps.ai_red_vehicle_groups = {}
RotorOps.ai_blue_vehicle_groups = {}
RotorOps.ai_defending_infantry_groups = {}
RotorOps.ai_attacking_infantry_groups = {}
RotorOps.ai_defending_vehicle_groups = {}
RotorOps.ai_attacking_vehicle_groups = {}
RotorOps.ai_tasks = {}
RotorOps.defending = false
trigger.action.outText("ROTOR OPS STARTED: "..RotorOps.version, 5)
env.info("ROTOR OPS STARTED: "..RotorOps.version)
local staged_units --table of ground units that started in the staging zone
RotorOps.staged_units = {} --table of ground units that started in the staging zone
RotorOps.eventHandler = {}
local commandDB = {}
local game_message_buffer = {}
local active_zone_initial_enemy_units
local active_zone_initial_defenders
local apcs = {} --table to keep track of infantry vehicles
local low_units_message_fired = false
local gameMsgs = {
RotorOps.gameMsgs = {
push = {
{'ALL GROUND UNITS, PUSH TO THE ACTIVE ZONE!', 'push_next_zone.ogg'},
{'ALL GROUND UNITS, PUSH TO ALPHA!', 'push_alpha.ogg'},
@ -74,10 +91,89 @@ local gameMsgs = {
{'GET OUR TROOPS TO CHARLIE!', 'get_troops_charlie.ogg'},
{'GET OUR TROOPS TO DELTA!', 'get_troops_delta.ogg'},
},
jtac = {
{'JTAC DROPPED!', 'jtac_dropped.ogg'},
},
enemy_almost_cleared = {
{'ENEMY HAS NEARLY CAPTURED THE ZONE!', 'enemy_almost_cleared.ogg'},
{'ENEMY HAS NEARLY CAPTURED THE ZONE!', 'enemy_decimating_forces.ogg'},
{'ENEMY HAS NEARLY CAPTURED THE ZONE!', 'enemy_destroying_ground.ogg'},
},
almost_cleared = {
{'WE HAVE NEARLY CLEARED THE ZONE!', 'almost_cleared.ogg'},
{'WE HAVE NEARLY CLEARED THE ZONE!', 'theyre_weak.ogg'},
{'WE HAVE NEARLY CLEARED THE ZONE!', 'tearing_them_up.ogg'},
},
enemy_pushing = {
{'ENEMY PUSHING TO THE NEXT ZONE!', 'enemy_pushing_zone.ogg'},
{'ENEMY PUSHING TO ALPHA!', 'enemy_pushing_alpha.ogg'},
{'ENEMY PUSHING TO BRAVO!', 'enemy_pushing_bravo.ogg'},
{'ENEMY PUSHING TO CHARLIE!', 'enemy_pushing_charlie.ogg'},
{'ENEMY PUSHING TO DELTA!', 'enemy_pushing_delta.ogg'},
},
start_defense = {
{'SUPPORT THE WAR ON THE GROUND! PUSH BACK AGAINST THE ENEMY!', 'push_back.ogg'},
},
failure = {
{'GROUND MISSION FAILED!', 'mission_failure.ogg'},
},
friendly_troops_dropped = {
{'FRIENDLY TROOPS DROPPED INTO ZONE!', 'friendly_troops_dropped_active.ogg'},
},
hold_ground = {
{'HOLD GROUND TO WIN!', 'hold_our_ground.ogg'},
},
enemy_cleared_zone = {
{'ENEMY TOOK THE ACTIVE ZONE!', 'enemy_destroying_us.ogg'},
{'ENEMY TOOK ALPHA!', 'enemy_destroying_us.ogg'},
{'ENEMY TOOK BRAVO!', 'enemy_destroying_us.ogg'},
{'ENEMY TOOK CHARLIE!', 'enemy_destroying_us.ogg'},
{'ENEMY TOOK DELTA!', 'enemy_destroying_us.ogg'},
},
}
local sound_effects = {
["troop_pickup"] = {'troops_load_ao.ogg', 'troops_load_ready.ogg', 'troops_load_to_action.ogg',force_offroad = true},
["troop_dropoff"] = {'troops_unload_thanks.ogg', 'troops_unload_everybody_off.ogg', 'troops_unload_get_off.ogg', 'troops_unload_here_we_go.ogg', 'troops_unload_moving_out.ogg',},
}
function RotorOps.eventHandler:onEvent(event)
if (world.event.S_EVENT_ENGINE_STARTUP == event.id) then --play some sound files when a player starts engines
local initaitor = event.initiator:getGroup():getID()
if RotorOps.defending then
trigger.action.outSoundForGroup(initaitor , RotorOps.gameMsgs.enemy_pushing[RotorOps.active_zone_index + 1][2])
else
trigger.action.outSoundForGroup(initaitor , RotorOps.gameMsgs.push[RotorOps.active_zone_index + 1][2])
end
end
end
function RotorOps.registerCtldCallbacks(var)
ctld.addCallback(function(_args)
local action = _args.action
local unit = _args.unit
local picked_troops = _args.onboard
local dropped_troops = _args.unloaded
--trigger.action.outText("dbg: ".. mist.utils.tableShow(_args), 5)
if action == "load_troops" or action == "extract_troops" then
trigger.action.outSoundForGroup(unit:getGroup():getID() , sound_effects.troop_pickup[math.random(1, #sound_effects.troop_pickup)])
elseif action == "unload_troops_zone" or action == "dropped_troops" then
trigger.action.outSoundForGroup(unit:getGroup():getID() , sound_effects.troop_dropoff[math.random(1, #sound_effects.troop_dropoff)])
if RotorOps.isUnitInZone(unit, RotorOps.active_zone) then
local id = timer.scheduleFunction(RotorOps.gameMsgHandler, RotorOps.gameMsgs.friendly_troops_dropped, timer.getTime() + 6) --allow some extra time so we don't step on the player's troop/unload sound effects
end
if dropped_troops.jtac == true then
local id = timer.scheduleFunction(RotorOps.gameMsgHandler, RotorOps.gameMsgs.jtac, timer.getTime() + 6) --allow some extra time so we don't step on the player's troop/unload sound effects
end
end
end)
end
---UTILITY FUNCTIONS---
local function debugMsg(text)
@ -98,7 +194,12 @@ end
local function tableHasKey(table,key)
if table then
return table[key] ~= nil
else
env.warning("table parameter not provided")
return nil
end
end
@ -131,7 +232,7 @@ local function getDistance(point1, point2)
return distance
end
local function isUnitInZone(unit, zone_name)
function RotorOps.isUnitInZone(unit, zone_name)
local zone = trigger.misc.getZone(zone_name)
local distance = getDistance(unit:getPoint(), zone.point)
if distance <= zone.radius then
@ -156,17 +257,26 @@ function RotorOps.groupsFromUnits(units, table)
end
local function gameMsg(event, _index)
function RotorOps.gameMsg(event, _index)
if not event then
env.warning("event parameter is nil")
return
end
local index = 1
if _index ~= nill then
if _index ~= nil then
index = _index + 1
end
if tableHasKey(event, index) then
game_message_buffer[#game_message_buffer + 1] = {event[index][1], event[index][2]}
else env.info("ROTOR OPS could not find entry for "..key)
else env.warning("ROTOR OPS could not find sound file entry")
end
end
function RotorOps.gameMsgHandler(event) --for use with scheduled functions
RotorOps.gameMsg(event)
end
local function processMsgBuffer(vars)
if #game_message_buffer > 0 then
@ -239,7 +349,7 @@ end
--Easy way to deploy troops from a vehicle with waypoint action. Spawns from the first valid unit found in a group
function RotorOps.deployTroops(quantity, target_group)
function RotorOps.deployTroops(quantity, target_group, announce)
local target_group_obj
if type(target_group) == 'string' then
target_group_obj = Group.getByName(target_group)
@ -257,17 +367,18 @@ function RotorOps.deployTroops(quantity, target_group)
-- voiceover trigger stuff
for index, zone in pairs(RotorOps.zones)
do
if isUnitInZone(valid_unit, zone.name) then
if RotorOps.isUnitInZone(valid_unit, zone.name) and announce == true then
if side == "red" then
gameMsg(gameMsgs.troops_dropped, index)
RotorOps.gameMsg(RotorOps.gameMsgs.troops_dropped, index)
else
gameMsg(gameMsgs.friendly_troops_dropped, index)
RotorOps.gameMsg(RotorOps.gameMsgs.friendly_troops_dropped)
end
end
end
end
--see list of tasks in aiExecute. Zone is optional for many tasks
function RotorOps.aiTask(grp, task, zone)
local group_name
@ -276,6 +387,9 @@ function RotorOps.aiTask(grp, task, zone)
else
group_name = Group.getName(grp)
end
if string.find(group_name:lower(), RotorOps.exclude_ai_group_name:lower()) then --exclude groups that the user specifies with a special group name
return
end
if tableHasKey(RotorOps.ai_tasks, group_name) == true then --if we already have this group in our list to manage
--debugMsg("timer already exists, updating task for "..group_name.." : ".. RotorOps.ai_tasks[group_name].ai_task.." to "..task)
RotorOps.ai_tasks[group_name].ai_task = task
@ -455,14 +569,14 @@ function RotorOps.aiExecute(vars)
if task == "patrol" then
local vars = {}
vars.grp = Group.getByName(group_name)
vars.radius = 500
vars.radius = 300
RotorOps.patrolRadius(vars) --takes a group object, not name
update_interval = math.random(40,70)
update_interval = math.random(150,200)
elseif task == "aggressive" then
local vars = {}
vars.grp = Group.getByName(group_name)
vars.radius = 5000
update_interval = math.random(20,40)
update_interval = math.random(60,90)
RotorOps.chargeEnemy(vars) --takes a group object, not name
elseif task == "clear_zone" then
local vars = {}
@ -501,61 +615,88 @@ end
function RotorOps.assessUnitsInZone(var)
if RotorOps.game_state == RotorOps.game_states.not_started then return end
local defending_ground_units
local defending_infantry
local defending_vehicles
local attacking_ground_units
local attacking_infantry
local attacking_vehicles
--find and sort units found in the active zone
local red_ground_units = mist.getUnitsInZones(mist.makeUnitTable({'[red][vehicle]'}), {RotorOps.active_zone})
local red_infantry = RotorOps.sortOutInfantry(red_ground_units).infantry
local red_vehicles = RotorOps.sortOutInfantry(red_ground_units).not_infantry
local blue_ground_units = mist.getUnitsInZones(mist.makeUnitTable({'[blue][vehicle]'}), {RotorOps.active_zone})
local blue_infantry = RotorOps.sortOutInfantry(blue_ground_units).infantry
local blue_vehicles = RotorOps.sortOutInfantry(blue_ground_units).not_infantry
if RotorOps.defending then
defending_ground_units = mist.getUnitsInZones(mist.makeUnitTable({'[blue][vehicle]'}), {RotorOps.active_zone})
defending_infantry = RotorOps.sortOutInfantry(defending_ground_units).infantry
defending_vehicles = RotorOps.sortOutInfantry(defending_ground_units).not_infantry
attacking_ground_units = mist.getUnitsInZones(mist.makeUnitTable({'[red][vehicle]'}), {RotorOps.active_zone})
attacking_infantry = RotorOps.sortOutInfantry(attacking_ground_units).infantry
attacking_vehicles = RotorOps.sortOutInfantry(attacking_ground_units).not_infantry
else --attacking
defending_ground_units = mist.getUnitsInZones(mist.makeUnitTable({'[red][vehicle]'}), {RotorOps.active_zone})
defending_infantry = RotorOps.sortOutInfantry(defending_ground_units).infantry
defending_vehicles = RotorOps.sortOutInfantry(defending_ground_units).not_infantry
attacking_ground_units = mist.getUnitsInZones(mist.makeUnitTable({'[blue][vehicle]'}), {RotorOps.active_zone})
attacking_infantry = RotorOps.sortOutInfantry(attacking_ground_units).infantry
attacking_vehicles = RotorOps.sortOutInfantry(attacking_ground_units).not_infantry
end
--ground unit ai stuff
RotorOps.ai_red_infantry_groups = RotorOps.groupsFromUnits(red_infantry)
RotorOps.ai_blue_infantry_groups = RotorOps.groupsFromUnits(blue_infantry)
RotorOps.ai_red_vehicle_groups = RotorOps.groupsFromUnits(red_vehicles)
RotorOps.ai_blue_vehicle_groups = RotorOps.groupsFromUnits(blue_vehicles)
RotorOps.ai_defending_infantry_groups = RotorOps.groupsFromUnits(defending_infantry)
RotorOps.ai_defending_vehicle_groups = RotorOps.groupsFromUnits(defending_vehicles)
RotorOps.ai_attacking_infantry_groups = RotorOps.groupsFromUnits(attacking_infantry)
RotorOps.ai_attacking_vehicle_groups = RotorOps.groupsFromUnits(attacking_vehicles)
for index, group in pairs(RotorOps.ai_red_infantry_groups) do
for index, group in pairs(RotorOps.ai_defending_infantry_groups) do
if group then
RotorOps.aiTask(group, "patrol")
end
end
for index, group in pairs(RotorOps.ai_blue_infantry_groups) do
for index, group in pairs(RotorOps.ai_attacking_infantry_groups) do
if group then
RotorOps.aiTask(group, "clear_zone", RotorOps.active_zone)
end
end
for index, group in pairs(RotorOps.ai_blue_vehicle_groups) do
for index, group in pairs(RotorOps.ai_attacking_vehicle_groups) do
if group then
RotorOps.aiTask(group, "clear_zone", RotorOps.active_zone)
end
end
--FIRES ONCE PER ZONE ACTIVATION
--let's compare the defending units in zone vs their initial numbers and set a game flag
if not active_zone_initial_enemy_units then
if not active_zone_initial_defenders then
--debugMsg("taking stock of the active zone")
active_zone_initial_enemy_units = red_ground_units
active_zone_initial_defenders = defending_ground_units
low_units_message_fired = false
env.info("ROTOR OPS: zone activated: "..RotorOps.active_zone)
end
local defenders_status_flag = RotorOps.zones[RotorOps.active_zone_index].defenders_status_flag
if #active_zone_initial_enemy_units == 0 then active_zone_initial_enemy_units = 1 end --prevent divide by zero
local defenders_remaining_percent = math.floor((#red_ground_units / #active_zone_initial_enemy_units) * 100)
--if #active_zone_initial_defenders == 0 then active_zone_initial_defenders = 1 end --prevent divide by zero
local defenders_remaining_percent = math.floor((#defending_ground_units / #active_zone_initial_defenders) * 100)
if #red_ground_units <= RotorOps.max_units_left then --if we should declare the zone cleared
active_zone_initial_enemy_units = nil
if #defending_ground_units <= RotorOps.max_units_left then --if we should declare the zone cleared
active_zone_initial_defenders = nil
defenders_remaining_percent = 0
trigger.action.setUserFlag(defenders_status_flag, 0) --set the zone's flag to cleared
gameMsg(gameMsgs.cleared, RotorOps.active_zone_index)
if RotorOps.defending == true then
RotorOps.gameMsg(RotorOps.gameMsgs.enemy_cleared_zone, RotorOps.active_zone_index)
else
RotorOps.gameMsg(RotorOps.gameMsgs.cleared, RotorOps.active_zone_index)
end
if RotorOps.auto_push then --push units to the next zone
RotorOps.setActiveZone(RotorOps.active_zone_index + 1)
end
else
trigger.action.setUserFlag(defenders_status_flag, defenders_remaining_percent) --set the zones flag to indicate the status of remaining enemies
trigger.action.setUserFlag(defenders_status_flag, defenders_remaining_percent) --set the zones flag to indicate the status of remaining defenders
end
--are all zones clear?
@ -569,23 +710,104 @@ function RotorOps.assessUnitsInZone(var)
--is the game finished?
if all_zones_clear then
RotorOps.changeGameState(RotorOps.game_states.won)
gameMsg(gameMsgs.success)
if RotorOps.defending == true then
RotorOps.game_state = RotorOps.game_states.lost
trigger.action.setUserFlag(RotorOps.game_state_flag, RotorOps.game_states.lost)
RotorOps.gameMsg(RotorOps.gameMsgs.failure)
else
RotorOps.game_state = RotorOps.game_states.won
trigger.action.setUserFlag(RotorOps.game_state_flag, RotorOps.game_states.won)
RotorOps.gameMsg(RotorOps.gameMsgs.success)
end
return --we won't reset our timer to fire this function again
end
--is the defending game finished?
local defending_game_won = true
for key, staged_unit in pairs(RotorOps.staged_units) do
if staged_unit:isExist() then --check if the enemy has staged units left
defending_game_won = false
end
end
if RotorOps.defending and defending_game_won then
RotorOps.game_state = RotorOps.game_states.won
trigger.action.setUserFlag(RotorOps.game_state_flag, RotorOps.game_states.won)
RotorOps.gameMsg(RotorOps.gameMsgs.success)
return --we won't reset our timer to fire this function again
end
--APCs unload
local function unloadAPCs()
local units_table = attacking_vehicles
for index, vehicle in pairs(units_table) do
local should_deploy = false
if vehicle:hasAttribute("Infantry carriers") and RotorOps.isUnitInZone(vehicle, RotorOps.active_zone) then --if a vehicle is an APC and in zone
local apc_name = vehicle:getName()
if tableHasKey(apcs, apc_name) == true then --if we have this apc in our table already
for key, apc_details in pairs(apcs[apc_name]) do
if hasValue(apc_details, RotorOps.active_zone) then --if our apc table has the current zone
else --our apc table does not have the current zone
apcs[apc_name].deployed_zones = {RotorOps.active_zone,}
should_deploy = true
end
end
else --we don't have the apc in our table
should_deploy = true
apcs[apc_name] = {['deployed_zones'] = {RotorOps.active_zone,}}
end
end
if should_deploy then
local function timedDeploy()
if vehicle:isExist() then
RotorOps.deployTroops(4, vehicle:getGroup(), false)
end
end
local id = timer.scheduleFunction(timedDeploy, nil, timer.getTime() + math.random(90, 180))
end
end
end
if RotorOps.apcs_spawn_infantry then
unloadAPCs() --this should really be an aitask
end
--voiceovers based on remaining defenders
if not low_units_message_fired then
if defenders_remaining_percent <= 40 then
low_units_message_fired = true
env.info("ROTOR OPS: low units remaining in zone")
if RotorOps.defending then
RotorOps.gameMsg(RotorOps.gameMsgs.enemy_almost_cleared, math.random(1, #RotorOps.gameMsgs.enemy_almost_cleared))
else
RotorOps.gameMsg(RotorOps.gameMsgs.almost_cleared, math.random(1, #RotorOps.gameMsgs.almost_cleared))
end
end
end
--zone status display
local message = ""
local header = ""
local body = ""
if defenders_remaining_percent == 0 then
header = "["..RotorOps.active_zone .. " CLEARED!] "
if RotorOps.defending == true then
header = "[DEFEND "..RotorOps.active_zone .. "] "
body = "RED: " ..#attacking_infantry.. " infantry, " .. #attacking_vehicles .. " vehicles. BLUE: "..#defending_infantry.. " infantry, " .. #defending_vehicles.." vehicles. ["..defenders_remaining_percent.."%]"
else
header = "[BATTLE FOR "..RotorOps.active_zone .. "] "
header = "[ATTACK "..RotorOps.active_zone .. "] "
body = "RED: " ..#defending_infantry.. " infantry, " .. #defending_vehicles .. " vehicles. BLUE: "..#attacking_infantry.. " infantry, " .. #attacking_vehicles.." vehicles. ["..defenders_remaining_percent.."%]"
end
body = "RED: " ..#red_infantry.. " infantry, " .. #red_vehicles .. " vehicles. BLUE: "..#blue_infantry.. " infantry, " .. #blue_vehicles.." vehicles. ["..defenders_remaining_percent.."%]"
message = header .. body
if RotorOps.zone_status_display then
@ -655,12 +877,6 @@ end
function RotorOps.changeGameState(new_state)
RotorOps.game_state = new_state
trigger.action.setUserFlag(RotorOps.game_state_flag, new_state)
end
function RotorOps.setActiveZone(new_index)
local old_index = RotorOps.active_zone_index
if new_index > #RotorOps.zones then
@ -674,18 +890,33 @@ function RotorOps.setActiveZone(new_index)
RotorOps.active_zone = RotorOps.zones[new_index].name
if new_index ~= old_index then --the active zone is changing
if not RotorOps.defending then
if old_index > 0 then
ctld.activatePickupZone(RotorOps.zones[old_index].name)
ctld.activatePickupZone(RotorOps.zones[old_index].name) --make the captured zone a pickup zone
end
ctld.deactivatePickupZone(RotorOps.zones[new_index].name)
RotorOps.changeGameState(new_index)
if new_index < old_index then gameMsg(gameMsgs.fallback, new_index) end
if new_index > old_index then gameMsg(gameMsgs.get_troops_to_zone, new_index) end
end
local staged_groups = RotorOps.groupsFromUnits(staged_units)
RotorOps.game_state = new_index
trigger.action.setUserFlag(RotorOps.game_state_flag, new_index)
if new_index > old_index then
if RotorOps.defending == true then
RotorOps.gameMsg(RotorOps.gameMsgs.enemy_pushing, new_index)
else
RotorOps.gameMsg(RotorOps.gameMsgs.push, new_index)
RotorOps.gameMsg(RotorOps.gameMsgs.get_troops_to_zone, new_index)
end
end
local staged_groups = RotorOps.groupsFromUnits(RotorOps.staged_units)
for index, group in pairs(staged_groups) do
RotorOps.aiTask(group,"move_to_active_zone", RotorOps.zones[RotorOps.active_zone_index].name) --send vehicles to next zone; use move_to_active_zone so units don't get stuck if the active zone moves before they arrive
end
end
@ -697,6 +928,11 @@ end
--make some changes to the CTLD script/settings
function RotorOps.setupCTLD()
if type(ctld.pickupZones[1][2]) == "number" then --ctld converts its string table to integer on load, so we'll see if that's happened already
trigger.action.outText("ERROR: CTLD Loaded Too Soon!!", 90)
return
end
ctld.enableCrates = RotorOps.CTLD_crates
ctld.enabledFOBBuilding = false
ctld.JTAC_lock = "vehicle"
@ -716,15 +952,14 @@ function RotorOps.setupCTLD()
}
ctld.loadableGroups = {
{name = "Small Standard Group (4)", inf = 2, mg = 1, at = 1 },
{name = "Standard Group (8)", inf = 4, mg = 2, at = 2 }, -- will make a loadable group with 6 infantry, 2 MGs and 2 anti-tank for both coalitions
{name = "Anti Air (5)", inf = 2, aa = 3 },
{name = "Anti Tank (8)", inf = 2, at = 6 },
{name = "Mortar Squad (6)", mortar = 6 },
{name = "Small Standard Group (4)", inf = 2, mg = 1, at = 1 },
{name = "JTAC Group (5)", inf = 4, jtac = 1 },
{name = "Single JTAC (1)", jtac = 1 },
{name = "Small Platoon (16)", inf = 10, mg = 3, at = 3 },
{name = "Platoon (24)", inf = 12, mg = 4, at = 3, aa = 1 },
{name = "JTAC Group (4)", inf = 3, jtac = 1 },
{name = "Small Platoon (16)", inf = 9, mg = 3, at = 3, aa = 1 },
{name = "Platoon (24)", inf = 10, mg = 5, at = 6, aa = 3 },
}
end
@ -747,7 +982,7 @@ function RotorOps.addZone(_name, _zone_defenders_flag)
end
function RotorOps.stagingZone(_name)
RotorOps.addPickupZone(_name, "blue", -1, "yes", 0)
RotorOps.addPickupZone(_name, "blue", -1, "no", 0)
RotorOps.staging_zone = _name
end
@ -771,9 +1006,13 @@ function RotorOps.setupConflict(_game_state_flag)
RotorOps.setupCTLD()
--RotorOps.setupRadioMenu()
RotorOps.game_state_flag = _game_state_flag
RotorOps.changeGameState(RotorOps.game_states.not_started)
RotorOps.game_state = RotorOps.game_states.not_started
processMsgBuffer()
trigger.action.setUserFlag(RotorOps.game_state_flag, RotorOps.game_states.not_started)
trigger.action.outText("ALL TROOPS GET TO TRANSPORT AND PREPARE FOR DEPLOYMENT!" , 10, false)
if RotorOps.CTLD_sound_effects == true then
local timer_id = timer.scheduleFunction(RotorOps.registerCtldCallbacks, 1, timer.getTime() + 5)
end
end
@ -791,16 +1030,26 @@ function RotorOps.startConflict()
--missionCommands.removeItem(commandDB['start_conflict'])
--commandDB['clear_zone'] = missionCommands.addCommand( "[CHEAT] Force Clear Zone" , conflict_zones_menu , RotorOps.clearActiveZone)
RotorOps.staged_units = mist.getUnitsInZones(mist.makeUnitTable({'[all][vehicle]'}), {RotorOps.staging_zone})
gameMsg(gameMsgs.start)
gameMsg(gameMsgs.push, 1)
processMsgBuffer()
if RotorOps.staged_units[1]:getCoalition() == 1 then --check the coalition in the staging zone to see if we're defending
RotorOps.defending = true
RotorOps.gameMsg(RotorOps.gameMsgs.start_defense)
ctld.activatePickupZone(RotorOps.zones[#RotorOps.zones].name) --make the last zone a pickup zone for defenders
ctld.deactivatePickupZone(RotorOps.staging_zone)
else
RotorOps.gameMsg(RotorOps.gameMsgs.start)
ctld.activatePickupZone(RotorOps.staging_zone)
end
staged_units = mist.getUnitsInZones(mist.makeUnitTable({'[all][vehicle]'}), {RotorOps.staging_zone})
RotorOps.setActiveZone(1)
local id = timer.scheduleFunction(RotorOps.assessUnitsInZone, 1, timer.getTime() + 5)
world.addEventHandler(RotorOps.eventHandler)
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sound/friendly_cap.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sound/friendly_convoy.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sound/friendly_sead.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sound/losing_battle.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
sound/target_destroyed.ogg Normal file

Binary file not shown.