Merge pull request #6 from spencershepard/develop

Develop
This commit is contained in:
spencershepard 2022-01-09 01:50:22 -08:00 committed by GitHub
commit 636f871fb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 134 additions and 192 deletions

View File

@ -1,28 +1,33 @@
RotorOps = {} RotorOps = {}
--RotorOps settings that are safe to change dynamically (ideally from the mission editor in DO SCRIPT for ease of use)
RotorOps.voice_overs = true RotorOps.voice_overs = true
RotorOps.ground_speed = 60 --max speed for ground vehicles moving between zones 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.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.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.ai_active_zone = true --allow the script to automatically create waypoints for ground units in the active zone RotorOps.force_offroad = false --affects "move_to_zone" tasks only
RotorOps.zone_states = {not_started = 0, active = 1, cleared = 2, started = 3, most_remain = 4, half_remain = 5, quarter_remain = 6 } --zone level user flags will use these values. _remain flags compare the active red ground units vs their initial numbers --RotorOps settings that are proabably safe to change
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.game_states = {not_started = 0, in_progress = 1, won = 2, lost = 3} --game level user flag will use these values
--RotorOps.game_states = {not_started = 0, alpha = 1, bravo = 2, charlie = 3, delta = 4, game_won = 100} --game level user flag will use these values
RotorOps.transports = {'UH-1H', 'Mi-8MT', 'Mi-24P'} --players flying these will have ctld transport access
--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_state = 0 RotorOps.game_state = 0
RotorOps.zones = {} RotorOps.zones = {}
RotorOps.active_zone = "" --name of the active zone RotorOps.active_zone = "" --name of the active zone
RotorOps.active_zone_index = 1 RotorOps.active_zone_index = 0
RotorOps.game_state_flag = 1 --user flag to store the game state RotorOps.game_state_flag = 1 --user flag to store the game state
RotorOps.staging_zone = "" RotorOps.staging_zone = ""
RotorOps.auto_push = true --leave true for now
RotorOps.ctld_pickup_zones = {} --keep track of ctld zones we've added, mainly for map markup 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_tasks = {}
trigger.action.outText("ROTOR OPS STARTED", 5) trigger.action.outText("ROTOR OPS STARTED", 5)
env.info("ROTOR OPS STARTED") env.info("ROTOR OPS STARTED")
@ -32,11 +37,6 @@ local commandDB = {}
local game_message_buffer = {} local game_message_buffer = {}
local active_zone_initial_enemy_units local active_zone_initial_enemy_units
RotorOps.ai_red_infantry_groups = {}
RotorOps.ai_blue_infantry_groups = {}
RotorOps.ai_red_vehicle_groups = {}
RotorOps.ai_blue_vehicle_groups = {}
RotorOps.ai_tasks = {} --simply use the group ID for schedulefunction id
local gameMsgs = { local gameMsgs = {
push = { push = {
@ -46,12 +46,6 @@ local gameMsgs = {
{'ALL GROUND UNITS, PUSH TO CHARLIE!', 'push_charlie.ogg'}, {'ALL GROUND UNITS, PUSH TO CHARLIE!', 'push_charlie.ogg'},
{'ALL GROUND UNITS, PUSH TO DELTA!', 'push_delta.ogg'}, {'ALL GROUND UNITS, PUSH TO DELTA!', 'push_delta.ogg'},
}, },
fallback = {
{'ALL GROUND UNITS, FALL BACK!', '.wav'},
{'ALL GROUND UNITS, FALL BACK TO ALPHA!', '.wav'},
{'ALL GROUND UNITS, FALL BACK TO BRAVO!', '.wav'},
{'ALL GROUND UNITS, FALL BACK TO CHARLIE!', '.wav'},
},
cleared = { cleared = {
{'ZONE CLEARED!', 'cleared_active.ogg'}, {'ZONE CLEARED!', 'cleared_active.ogg'},
{'ALPHA CLEARED!', 'cleared_alpha.ogg'}, {'ALPHA CLEARED!', 'cleared_alpha.ogg'},
@ -83,7 +77,7 @@ local gameMsgs = {
} }
--[[ UTILITY FUNCTIONS ]]-- ---UTILITY FUNCTIONS---
local function debugMsg(text) local function debugMsg(text)
trigger.action.outText(text, 5) trigger.action.outText(text, 5)
@ -149,17 +143,11 @@ end
function RotorOps.groupsFromUnits(units, table) function RotorOps.groupsFromUnits(units, table)
local groups = {} local groups = {}
--debugTable(units)
--local groupIndex = {}
for i = 1, #units do for i = 1, #units do
if units[i]:isExist() then if units[i]:isExist() then
if hasValue(groups, units[i]:getGroup():getName()) == false then if hasValue(groups, units[i]:getGroup():getName()) == false then
--debugMsg("added: "..units[i]:getGroup():getName())
--groups[units[i]:getGroup():getName()] = true
--groupIndex[#groupIndex + 1] = groups[units[i]:getGroup():getName()]
groups[#groups + 1] = units[i]:getGroup():getName() groups[#groups + 1] = units[i]:getGroup():getName()
else --debugMsg(units[i]:getGroup():getName().." was already in the table") else
end end
end end
end end
@ -204,7 +192,14 @@ function RotorOps.sortOutInfantry(mixed_units)
return {infantry = _infantry, not_infantry = _not_infantry} return {infantry = _infantry, not_infantry = _not_infantry}
end end
function RotorOps.getValidUnitFromGroup(grp) function RotorOps.getValidUnitFromGroup(grp)
local group_obj
if type(grp) == 'string' then
group_obj = Group.getByName(grp)
else
group_obj = grp
end
if grp:isExist() ~= true then return nil end if grp:isExist() ~= true then return nil end
local first_valid_unit local first_valid_unit
for index, unit in pairs(grp:getUnits()) for index, unit in pairs(grp:getUnits())
@ -220,7 +215,9 @@ end
--spawn/clone a group onto the location of the first unit in a group (best to only use this for groups of one unit only for now!) See chargeEnemy for grabing first valid unit ----USEFUL PUBLIC FUNCTIONS FOR THE MISSION EDITOR---
--Spawn/clone a group onto the location of one unit in the group. This is similar to deployTroops, but it does not use CTLD. You must provide a source group to copy.
function RotorOps.spawnInfantryOnGrp(grp, src_grp_name, ai_task) --allow to spawn on other group units function RotorOps.spawnInfantryOnGrp(grp, src_grp_name, ai_task) --allow to spawn on other group units
local valid_unit = RotorOps.getValidUnitFromGroup(grp) local valid_unit = RotorOps.getValidUnitFromGroup(grp)
if not valid_unit then return end if not valid_unit then return end
@ -239,7 +236,15 @@ function RotorOps.spawnInfantryOnGrp(grp, src_grp_name, ai_task) --allow to spaw
end end
end end
function RotorOps.deployTroops(quantity, target_group_obj)
--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)
local target_group_obj
if type(target_group) == 'string' then
target_group_obj = Group.getByName(target_group)
else
target_group_obj = target_group
end
local valid_unit = RotorOps.getValidUnitFromGroup(target_group_obj) local valid_unit = RotorOps.getValidUnitFromGroup(target_group_obj)
if not valid_unit then return end if not valid_unit then return end
local coalition = valid_unit:getCoalition() local coalition = valid_unit:getCoalition()
@ -261,6 +266,37 @@ function RotorOps.deployTroops(quantity, target_group_obj)
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
if type(grp) == 'string' then
group_name = grp
else
group_name = Group.getName(grp)
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
RotorOps.ai_tasks[group_name].zone = zone
else
local vars = {}
vars.group_name = group_name
--vars.last_task = task
if zone then
vars.zone = zone
end
local timer_id = timer.scheduleFunction(RotorOps.aiExecute, vars, timer.getTime() + 5)
RotorOps.ai_tasks[group_name] = {['timer_id'] = timer_id, ['ai_task'] = task, ['zone'] = zone}
end
end
---AI CORE BEHAVIOR--
function RotorOps.chargeEnemy(vars) function RotorOps.chargeEnemy(vars)
--trigger.action.outText("charge enemies: "..mist.utils.tableShow(vars), 5) --trigger.action.outText("charge enemies: "..mist.utils.tableShow(vars), 5)
local grp = vars.grp local grp = vars.grp
@ -288,7 +324,7 @@ function RotorOps.chargeEnemy(vars)
} }
} }
else else
debugMsg("CHARGE ENEMY in radius: "..search_radius) --debugMsg("CHARGE ENEMY in radius: "..search_radius)
volS = { volS = {
id = world.VolumeType.SPHERE, id = world.VolumeType.SPHERE,
params = { params = {
@ -320,7 +356,7 @@ function RotorOps.chargeEnemy(vars)
end end
--default path if no units found --default path if no units found
if false then if false then
debugMsg("group going back to origin") --debugMsg("group going back to origin")
path[1] = mist.ground.buildWP(start_point, '', 5) path[1] = mist.ground.buildWP(start_point, '', 5)
path[2] = mist.ground.buildWP(vars.spawn_point, '', 5) path[2] = mist.ground.buildWP(vars.spawn_point, '', 5)
@ -397,47 +433,19 @@ end
------------------------------------------
local function changeGameState(new_state)
RotorOps.game_state = new_state
trigger.action.setUserFlag(RotorOps.game_state_flag, new_state)
end
function RotorOps.aiTask(group_name, task, zone)
if tableHasKey(RotorOps.ai_tasks, group_name) == true then --if we already have this group id in our list of timers
--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
RotorOps.ai_tasks[group_name].zone = zone
else
--debugMsg("adding timer: "..group_name.." task: "..task)
local vars = {}
vars.group_name = group_name
--vars.last_task = task
if zone then
vars.zone = zone
end
local timer_id = timer.scheduleFunction(RotorOps.aiExecute, vars, timer.getTime() + 5)
RotorOps.ai_tasks[group_name] = {['timer_id'] = timer_id, ['ai_task'] = task, ['zone'] = zone}
end
end
function RotorOps.aiExecute(vars) function RotorOps.aiExecute(vars)
local update_interval = 60 local update_interval = 60
local last_task = vars.last_task local last_task = vars.last_task
local group_name = vars.group_name local group_name = vars.group_name
local task = RotorOps.ai_tasks[group_name].ai_task local task = RotorOps.ai_tasks[group_name].ai_task
local zone = vars.zone local zone = vars.zone
--local zone = ""
if vars.zone then zone = vars.zone end
--debugMsg("aiExecute: "..group_name.." : "..task .." zone:"..zone)
--debugMsg("task:"..RotorOps.ai_tasks[group_name].ai_task)
--we should remove inactive/dead groups and cancel timer here if vars.zone then zone = vars.zone end
--debugMsg("tasking: "..group_name.." : "..task .." zone:"..zone)
if Group.isExist(Group.getByName(group_name)) ~= true or #Group.getByName(group_name):getUnits() < 1 then if Group.isExist(Group.getByName(group_name)) ~= true or #Group.getByName(group_name):getUnits() < 1 then
--debugMsg("group no longer exists") --debugMsg("group no longer exists")
RotorOps.ai_tasks[group_name] = nil
return return
end end
@ -466,55 +474,32 @@ function RotorOps.aiExecute(vars)
local formation = 'cone' local formation = 'cone'
local final_heading = nil local final_heading = nil
local speed = RotorOps.ground_speed local speed = RotorOps.ground_speed
local force_offroad = false local force_offroad = RotorOps.force_offroad
mist.groupToPoint(group_name, zone, formation, final_heading, speed, force_offroad) mist.groupToPoint(group_name, zone, formation, final_heading, speed, force_offroad)
elseif task == "move_to_active_zone" then elseif task == "move_to_active_zone" then
update_interval = math.random(90,120) update_interval = math.random(90,120)
local formation = 'cone' local formation = 'cone'
local final_heading = nil local final_heading = nil
local speed = RotorOps.ground_speed local speed = RotorOps.ground_speed
local force_offroad = false local force_offroad = RotorOps.force_offroad
mist.groupToPoint(group_name, RotorOps.active_zone, formation, final_heading, speed, force_offroad) mist.groupToPoint(group_name, RotorOps.active_zone, formation, final_heading, speed, force_offroad)
end end
--end
vars.last_task = task vars.last_task = task
local timer_id = timer.scheduleFunction(RotorOps.aiExecute, vars, timer.getTime() + update_interval) local timer_id = timer.scheduleFunction(RotorOps.aiExecute, vars, timer.getTime() + update_interval)
end end
function RotorOps.aiActiveZone(var) --[[
if RotorOps.ai_active_zone == false then return end
--debugMsg("aiActiveZone func")
for index, group in pairs(RotorOps.ai_red_infantry_groups) do
if group then
RotorOps.aiTask(group, "patrol")
end
end
for index, group in pairs(RotorOps.ai_blue_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
if group then
RotorOps.aiTask(group, "clear_zone", RotorOps.active_zone)
end
end
local id = timer.scheduleFunction(RotorOps.aiActiveZone, 1, timer.getTime() + 10) ]]--
end
---CONFLICT ZONES GAME FUNCTIONS---
--take stock of the blue/red forces in zone and apply some logic to determine game/zone states
function RotorOps.assessUnitsInZone(var) function RotorOps.assessUnitsInZone(var)
if RotorOps.game_state ~= RotorOps.game_states.in_progress then return end if RotorOps.game_state == RotorOps.game_states.not_started then return end
--find and sort units found in the active zone --find and sort units found in the active zone
local red_ground_units = mist.getUnitsInZones(mist.makeUnitTable({'[red][vehicle]'}), {RotorOps.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_infantry = RotorOps.sortOutInfantry(red_ground_units).infantry
@ -523,14 +508,12 @@ function RotorOps.assessUnitsInZone(var)
local blue_infantry = RotorOps.sortOutInfantry(blue_ground_units).infantry local blue_infantry = RotorOps.sortOutInfantry(blue_ground_units).infantry
local blue_vehicles = RotorOps.sortOutInfantry(blue_ground_units).not_infantry local blue_vehicles = RotorOps.sortOutInfantry(blue_ground_units).not_infantry
------- --ground unit ai stuff
-- --ground unit ai stuff
RotorOps.ai_red_infantry_groups = RotorOps.groupsFromUnits(red_infantry) RotorOps.ai_red_infantry_groups = RotorOps.groupsFromUnits(red_infantry)
RotorOps.ai_blue_infantry_groups = RotorOps.groupsFromUnits(blue_infantry) RotorOps.ai_blue_infantry_groups = RotorOps.groupsFromUnits(blue_infantry)
RotorOps.ai_red_vehicle_groups = RotorOps.groupsFromUnits(red_vehicles) RotorOps.ai_red_vehicle_groups = RotorOps.groupsFromUnits(red_vehicles)
RotorOps.ai_blue_vehicle_groups = RotorOps.groupsFromUnits(blue_vehicles) RotorOps.ai_blue_vehicle_groups = RotorOps.groupsFromUnits(blue_vehicles)
for index, group in pairs(RotorOps.ai_red_infantry_groups) do for index, group in pairs(RotorOps.ai_red_infantry_groups) do
if group then if group then
RotorOps.aiTask(group, "patrol") RotorOps.aiTask(group, "patrol")
@ -549,56 +532,41 @@ function RotorOps.assessUnitsInZone(var)
end end
end end
-----
local active_zone_status_flag = RotorOps.zones[RotorOps.active_zone_index].zone_status_flag
local active_zone_status = trigger.misc.getUserFlag(active_zone_status_flag)
--set user flags based on quantities of enemy units remaining --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_enemy_units then
--debugMsg("taking stock of the active zone") --debugMsg("taking stock of the active zone")
active_zone_initial_enemy_units = red_ground_units active_zone_initial_enemy_units = red_ground_units
trigger.action.setUserFlag(active_zone_status_flag, RotorOps.zone_states.active) --set the zone's flag to active ---patch solution...would this work if there were no enemies in zone??
end
local enemy_remain_status
if #red_ground_units < #active_zone_initial_enemy_units * 0.75 then
enemy_remain_status = RotorOps.zone_states.most_remain
debugMsg("most remain at "..RotorOps.active_zone)
end
if #red_ground_units < #active_zone_initial_enemy_units * 0.5 then
enemy_remain_status = RotorOps.zone_states.half_remain
debugMsg("half remain at "..RotorOps.active_zone)
end
if #red_ground_units < #active_zone_initial_enemy_units * 0.25 then
enemy_remain_status = RotorOps.zone_states.quarter_remain
debugMsg("quarter remain at "..RotorOps.active_zone)
end 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 #red_ground_units <= RotorOps.max_units_left then --if we should declare the zone cleared if #red_ground_units <= RotorOps.max_units_left then --if we should declare the zone cleared
active_zone_initial_enemy_units = nil active_zone_initial_enemy_units = nil
trigger.action.setUserFlag(active_zone_status_flag, RotorOps.zone_states.cleared) --set the zone's flag to cleared 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) gameMsg(gameMsgs.cleared, RotorOps.active_zone_index)
if RotorOps.auto_push then
if RotorOps.auto_push then --push units to the next zone
RotorOps.setActiveZone(RotorOps.active_zone_index + 1) RotorOps.setActiveZone(RotorOps.active_zone_index + 1)
local staged_groups = RotorOps.groupsFromUnits(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
end end
end
elseif enemy_remain_status then else
trigger.action.setUserFlag(active_zone_status_flag, enemy_remain_status) --set the zones flage 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 enemies
end end
--are all zones clear? --are all zones clear?
local all_zones_clear = true local all_zones_clear = true
for key, value in pairs(RotorOps.zones) do for key, value in pairs(RotorOps.zones) do
local zone_status = trigger.misc.getUserFlag(RotorOps.zones[key].zone_status_flag) local defenders_remaining = trigger.misc.getUserFlag(RotorOps.zones[key].defenders_status_flag)
if zone_status ~= RotorOps.zone_states.cleared then if defenders_remaining ~= 0 then
all_zones_clear = false all_zones_clear = false
end end
end end
--is the game finished?
if all_zones_clear then if all_zones_clear then
changeGameState(RotorOps.game_states.won) changeGameState(RotorOps.game_states.won)
gameMsg(gameMsgs.success) gameMsg(gameMsgs.success)
@ -607,20 +575,19 @@ function RotorOps.assessUnitsInZone(var)
--zone status display stuff --zone status display
local message = "" local message = ""
local header = "" local header = ""
local body = "" local body = ""
if active_zone_status == RotorOps.zone_states.cleared then if defenders_remaining_percent == 0 then
header = "["..RotorOps.active_zone .. " CLEARED!] " header = "["..RotorOps.active_zone .. " CLEARED!] "
else else
header = "[BATTLE FOR "..RotorOps.active_zone .. "] " header = "[BATTLE FOR "..RotorOps.active_zone .. "] "
end end
body = "RED: " ..#red_infantry.. " infantry, " .. #red_vehicles .. " vehicles. BLUE: "..#blue_infantry.. " infantry, " .. #blue_vehicles.." vehicles." body = "RED: " ..#red_infantry.. " infantry, " .. #red_vehicles .. " vehicles. BLUE: "..#blue_infantry.. " infantry, " .. #blue_vehicles.." vehicles. ["..defenders_remaining_percent.."%]"
message = header .. body message = header .. body
if RotorOps.zone_status_display then if RotorOps.zone_status_display then
--trigger.action.outText(message , 5, true)
game_message_buffer[#game_message_buffer + 1] = {message, ""} --don't load the buffer faster than it's cleared. game_message_buffer[#game_message_buffer + 1] = {message, ""} --don't load the buffer faster than it's cleared.
end end
local id = timer.scheduleFunction(RotorOps.assessUnitsInZone, 1, timer.getTime() + 10) local id = timer.scheduleFunction(RotorOps.assessUnitsInZone, 1, timer.getTime() + 10)
@ -686,33 +653,13 @@ function RotorOps.drawZones() --this could use a lot of work, we should use tri
end end
--[[
function RotorOps.clearActiveZone()
local active_zone_status_flag = RotorOps.zones[RotorOps.active_zone_index].zone_status_flag
trigger.action.setUserFlag(active_zone_status_flag, RotorOps.zone_states.cleared) --set the zone's flag to cleared
gameMsg(gameMsgs.cleared, RotorOps.active_zone_index)
if RotorOps.auto_push then
RotorOps.setActiveZone(RotorOps.active_zone_index + 1)
local staged_groups = RotorOps.groupsFromUnits(staged_units)
for index, group in pairs(staged_groups) do
RotorOps.aiTask(group,"move_to_active_zone", RotorOps.zones[RotorOps.active_zone_index].name)
end
end
end
]]--
local function changeGameState(new_state)
RotorOps.game_state = new_state
function RotorOps.spawnInfantryAtZone(vars) trigger.action.setUserFlag(RotorOps.game_state_flag, new_state)
local side = vars.side
local inf = vars.inf
local zone = vars.zone
local radius = vars.radius
ctld.spawnGroupAtTrigger(side, inf, zone, radius)
end end
function RotorOps.setActiveZone(new_index) function RotorOps.setActiveZone(new_index)
local old_index = RotorOps.active_zone_index local old_index = RotorOps.active_zone_index
if new_index > #RotorOps.zones then if new_index > #RotorOps.zones then
@ -726,13 +673,18 @@ function RotorOps.setActiveZone(new_index)
RotorOps.active_zone = RotorOps.zones[new_index].name RotorOps.active_zone = RotorOps.zones[new_index].name
if new_index ~= old_index then --the active zone is changing if new_index ~= old_index then --the active zone is changing
trigger.action.setUserFlag(RotorOps.zones[new_index].zone_status_flag, RotorOps.zone_states.active) --set the new zone to active if old_index > 0 then
ctld.activatePickupZone(RotorOps.zones[old_index].name) ctld.activatePickupZone(RotorOps.zones[old_index].name)
end
ctld.deactivatePickupZone(RotorOps.zones[new_index].name) ctld.deactivatePickupZone(RotorOps.zones[new_index].name)
changeGameState(new_index)
if new_index < old_index then gameMsg(gameMsgs.fallback, new_index) end if new_index < old_index then gameMsg(gameMsgs.fallback, new_index) end
--if new_index > old_index then gameMsg(gameMsgs.push, new_index) end
if new_index > old_index then gameMsg(gameMsgs.get_troops_to_zone, new_index) end if new_index > old_index then gameMsg(gameMsgs.get_troops_to_zone, new_index) end
local staged_groups = RotorOps.groupsFromUnits(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
end
end end
@ -742,9 +694,9 @@ function RotorOps.setActiveZone(new_index)
end end
--make some changes to the CTLD script/settings
function RotorOps.setupCTLD() function RotorOps.setupCTLD()
ctld.enableCrates = false ctld.enableCrates = RotorOps.CTLD_crates
ctld.enabledFOBBuilding = false ctld.enabledFOBBuilding = false
ctld.JTAC_lock = "vehicle" ctld.JTAC_lock = "vehicle"
ctld.location_DMS = true ctld.location_DMS = true
@ -763,22 +715,20 @@ function RotorOps.setupCTLD()
} }
ctld.loadableGroups = { ctld.loadableGroups = {
-- {name = "Mortar Squad Red", inf = 2, mortar = 5, side =1 }, --would make a group loadable by RED only {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 = "Standard Group (10)", inf = 6, 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 Air (5)", inf = 2, aa = 3 },
{name = "Anti Tank (8)", inf = 2, at = 6 }, {name = "Anti Tank (8)", inf = 2, at = 6 },
{name = "Mortar Squad (6)", mortar = 6 }, {name = "Mortar Squad (6)", mortar = 6 },
{name = "Small Standard Group (4)", inf = 2, mg = 1, at = 1 }, {name = "Small Standard Group (4)", inf = 2, mg = 1, at = 1 },
{name = "JTAC Group (5)", inf = 4, jtac = 1 }, -- will make a loadable group with 4 infantry and a JTAC soldier for both coalitions {name = "JTAC Group (5)", inf = 4, jtac = 1 },
{name = "Single JTAC (1)", 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 = "Platoon (24)", inf = 12, mg = 4, at = 3, aa = 1 },
} }
end end
function RotorOps.setupRadioMenu() function RotorOps.setupRadioMenu()
commandDB['conflict_zones_menu'] = missionCommands.addSubMenu( "ROTOR OPS") commandDB['conflict_zones_menu'] = missionCommands.addSubMenu( "ROTOR OPS")
local conflict_zones_menu = commandDB['conflict_zones_menu'] local conflict_zones_menu = commandDB['conflict_zones_menu']
@ -788,15 +738,11 @@ end
function RotorOps.addZone(_name, _zone_defenders_flag)
function RotorOps.addZone(_name, _zone_status_flag) table.insert(RotorOps.zones, {name = _name, defenders_status_flag = _zone_defenders_flag})
table.insert(RotorOps.zones, {name = _name, zone_status_flag = _zone_status_flag}) trigger.action.setUserFlag(_zone_defenders_flag, 101)
trigger.action.setUserFlag(_zone_status_flag, RotorOps.zone_states.not_started)
RotorOps.drawZones() RotorOps.drawZones()
--ctld.dropOffZones[#ctld.dropOffZones + 1] = { _name, "green", 0 }
RotorOps.addPickupZone(_name, "blue", -1, "no", 0) RotorOps.addPickupZone(_name, "blue", -1, "no", 0)
--ctld.dropOffZones[#ctld.dropOffZones + 1] = { _name, "none", 1 }
--trigger.action.outText("zones: ".. mist.utils.tableShow(RotorOps.zones), 5)
end end
function RotorOps.stagingZone(_name) function RotorOps.stagingZone(_name)
@ -804,6 +750,7 @@ function RotorOps.stagingZone(_name)
RotorOps.staging_zone = _name RotorOps.staging_zone = _name
end end
--function to automatically add transport craft to ctld, rather than having to define each in the mission editor --function to automatically add transport craft to ctld, rather than having to define each in the mission editor
function RotorOps.addPilots(var) function RotorOps.addPilots(var)
for uName, uData in pairs(mist.DBs.humansByName) do for uName, uData in pairs(mist.DBs.humansByName) do
@ -817,10 +764,11 @@ function RotorOps.addPilots(var)
local id = timer.scheduleFunction(RotorOps.addPilots, 1, timer.getTime() + 15) local id = timer.scheduleFunction(RotorOps.addPilots, 1, timer.getTime() + 15)
end end
function RotorOps.setupConflict(_game_state_flag) function RotorOps.setupConflict(_game_state_flag)
RotorOps.addPilots(1) RotorOps.addPilots(1)
RotorOps.setupCTLD() RotorOps.setupCTLD()
RotorOps.setupRadioMenu() --RotorOps.setupRadioMenu()
RotorOps.game_state_flag = _game_state_flag RotorOps.game_state_flag = _game_state_flag
changeGameState(RotorOps.game_states.not_started) changeGameState(RotorOps.game_states.not_started)
trigger.action.outText("ALL TROOPS GET TO TRANSPORT AND PREPARE FOR DEPLOYMENT!" , 10, false) trigger.action.outText("ALL TROOPS GET TO TRANSPORT AND PREPARE FOR DEPLOYMENT!" , 10, false)
@ -835,26 +783,20 @@ end
function RotorOps.startConflict() function RotorOps.startConflict()
if RotorOps.game_state == RotorOps.game_states.in_progress then return end if RotorOps.game_state ~= RotorOps.game_states.not_started then return end
changeGameState(RotorOps.game_states.in_progress)
--make some changes to the radio menu --make some changes to the radio menu
local conflict_zones_menu = commandDB['conflict_zones_menu'] --local conflict_zones_menu = commandDB['conflict_zones_menu']
missionCommands.removeItem(commandDB['start_conflict']) --missionCommands.removeItem(commandDB['start_conflict'])
--commandDB['clear_zone'] = missionCommands.addCommand( "[CHEAT] Force Clear Zone" , conflict_zones_menu , RotorOps.clearActiveZone) --commandDB['clear_zone'] = missionCommands.addCommand( "[CHEAT] Force Clear Zone" , conflict_zones_menu , RotorOps.clearActiveZone)
RotorOps.setActiveZone(1)
gameMsg(gameMsgs.start) gameMsg(gameMsgs.start)
gameMsg(gameMsgs.push, 1) gameMsg(gameMsgs.push, 1)
processMsgBuffer() processMsgBuffer()
RotorOps.aiActiveZone()
staged_units = mist.getUnitsInZones(mist.makeUnitTable({'[all][vehicle]'}), {RotorOps.staging_zone}) staged_units = mist.getUnitsInZones(mist.makeUnitTable({'[all][vehicle]'}), {RotorOps.staging_zone})
local staged_groups = RotorOps.groupsFromUnits(staged_units) RotorOps.setActiveZone(1)
for index, group in pairs(staged_groups) do
RotorOps.aiTask(group,"move_to_active_zone")
end
local id = timer.scheduleFunction(RotorOps.assessUnitsInZone, 1, timer.getTime() + 5) local id = timer.scheduleFunction(RotorOps.assessUnitsInZone, 1, timer.getTime() + 5)
end end

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB