diff --git a/RotorOps.lua b/RotorOps.lua index 46e8b48..dacafb2 100644 --- a/RotorOps.lua +++ b/RotorOps.lua @@ -1,22 +1,33 @@ RotorOps = {} -RotorOps.version = "1.0.11" +RotorOps.version = "1.0.12" ---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.ctld_sound_effects = false --sound effects for troop pickup/dropoffs +RotorOps.apcs_spawn_infantry = true --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.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 + + +---[[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,11 +35,12 @@ 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) @@ -36,10 +48,11 @@ env.info("ROTOR OPS STARTED: "..RotorOps.version) local staged_units --table of ground units that started in the staging zone 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 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,6 +87,45 @@ 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'}, + }, } @@ -88,16 +140,22 @@ local sound_effects = { function RotorOps.registerCtldCallbacks(var) ctld.addCallback(function(_args) - --trigger.action.outText("dbg: ".. mist.utils.tableShow(_args), 5) + trigger.action.outText("dbg: ".. mist.utils.tableShow(_args), 5) 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) + 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.troops.pickup[math.random(1, #sound_effects.troops.pickup)]) + --trigger.action.outSoundForGroup(unit:getGroup():getID() , sound_effects.troops.pickup[math.random(1, #sound_effects.troops.pickup)]) elseif action == "unload_troops_zone" or action == "dropped_troops" then - trigger.action.outSoundForGroup(unit:getGroup():getID() , sound_effects.troops.dropoff[math.random(1, #sound_effects.troops.pickup)]) + --trigger.action.outSoundForGroup(unit:getGroup():getID() , sound_effects.troops.dropoff[math.random(1, #sound_effects.troops.pickup)]) + if RotorOps.isUnitInZone(unit, RotorOps.active_zone) then + RotorOps.gameMsg(RotorOps.gameMsgs.friendly_troops_dropped) + end + if dropped_troops.jtac == true then + RotorOps.gameMsg(RotorOps.gameMsgs.jtac) + end end end) @@ -123,7 +181,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 @@ -156,7 +219,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 @@ -181,14 +244,18 @@ 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 entry for "..event) end end @@ -264,7 +331,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) @@ -282,11 +349,11 @@ 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 @@ -480,9 +547,9 @@ 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) @@ -526,61 +593,85 @@ end function RotorOps.assessUnitsInZone(var) if RotorOps.game_state == RotorOps.game_states.not_started then return end - --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 + + local defending_ground_units + local defending_infantry + local defending_vehicles + local attacking_ground_units + local attacking_infantry + local attacking_vehicles ---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) + + + --find and sort units found in the active zone + 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 - for index, group in pairs(RotorOps.ai_red_infantry_groups) do + + --ground unit ai stuff + 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_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 + --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 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? @@ -594,24 +685,66 @@ function RotorOps.assessUnitsInZone(var) --is the game finished? if all_zones_clear then - RotorOps.game_state = RotorOps.game_states.won - trigger.action.setUserFlag(RotorOps.game_state_flag, 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 - + + --APCs unload + local function unloadAPCs(units_table) + for index, vehicle in pairs(units_table) do + if vehicle:hasAttribute("Infantry carriers") then + local apc_name = vehicle:getName() + trigger.action.outText("found apc: "..apc_name, 5) + + if tableHasKey(apcs, apc_name) == true then + trigger.action.outText("table has key", 5) + + for key, apc_details in pairs(apcs[apc_name]) do + if hasValue(apc_details, RotorOps.active_zone) then + trigger.action.outText("we've already dropped troops in this zone", 5) + else + apcs[apc_name].deployed_zones = {RotorOps.active_zone,} + trigger.action.outText("dropping troops", 5) + RotorOps.deployTroops(4, vehicle:getGroup(), false) + end + end + + else + trigger.action.outText("we've never dropped troops, drop some", 5) + RotorOps.deployTroops(4, vehicle:getGroup()) + apcs[apc_name] = {['deployed_zones'] = {RotorOps.active_zone,}} + end + + end + end + end + + if RotorOps.apcs_spawn_infantry then + local id = timer.scheduleFunction(unloadAPCs, attacking_vehicles, timer.getTime() + 30) + end + + --zone status display local message = "" local header = "" local body = "" - if defenders_remaining_percent == 0 then - header = "["..RotorOps.active_zone .. " CLEARED!] " - else - header = "[BATTLE FOR "..RotorOps.active_zone .. "] " + 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 = "[ATTACK "..RotorOps.active_zone .. "] " + body = "RED: " ..#defending_infantry.. " infantry, " .. #defending_vehicles .. " vehicles. BLUE: "..#defending_infantry.. " infantry, " .. #defending_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 @@ -700,13 +833,21 @@ function RotorOps.setActiveZone(new_index) ctld.deactivatePickupZone(RotorOps.zones[new_index].name) RotorOps.game_state = new_index trigger.action.setUserFlag(RotorOps.game_state_flag, 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 + 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(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 @@ -737,15 +878,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 @@ -793,9 +933,10 @@ function RotorOps.setupConflict(_game_state_flag) --RotorOps.setupRadioMenu() RotorOps.game_state_flag = _game_state_flag 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 + if RotorOps.CTLD_sound_effects == true then local timer_id = timer.scheduleFunction(RotorOps.registerCtldCallbacks, 1, timer.getTime() + 5) end end @@ -814,13 +955,16 @@ function RotorOps.startConflict() --local conflict_zones_menu = commandDB['conflict_zones_menu'] --missionCommands.removeItem(commandDB['start_conflict']) --commandDB['clear_zone'] = missionCommands.addCommand( "[CHEAT] Force Clear Zone" , conflict_zones_menu , RotorOps.clearActiveZone) - - - gameMsg(gameMsgs.start) - gameMsg(gameMsgs.push, 1) - processMsgBuffer() - + staged_units = mist.getUnitsInZones(mist.makeUnitTable({'[all][vehicle]'}), {RotorOps.staging_zone}) + + if 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) + else + RotorOps.gameMsg(RotorOps.gameMsgs.start) + end + RotorOps.setActiveZone(1) local id = timer.scheduleFunction(RotorOps.assessUnitsInZone, 1, timer.getTime() + 5) diff --git a/sound/embedded/almost_cleared.ogg b/sound/embedded/almost_cleared.ogg new file mode 100644 index 0000000..54578b7 Binary files /dev/null and b/sound/embedded/almost_cleared.ogg differ diff --git a/sound/embedded/enemy_almost_cleared.ogg b/sound/embedded/enemy_almost_cleared.ogg new file mode 100644 index 0000000..c437f93 Binary files /dev/null and b/sound/embedded/enemy_almost_cleared.ogg differ diff --git a/sound/embedded/enemy_decimating_forces.ogg b/sound/embedded/enemy_decimating_forces.ogg new file mode 100644 index 0000000..b264a98 Binary files /dev/null and b/sound/embedded/enemy_decimating_forces.ogg differ diff --git a/sound/embedded/enemy_destroying_ground.ogg b/sound/embedded/enemy_destroying_ground.ogg new file mode 100644 index 0000000..2e06af3 Binary files /dev/null and b/sound/embedded/enemy_destroying_ground.ogg differ diff --git a/sound/enemy_destroying_us.ogg b/sound/embedded/enemy_destroying_us.ogg similarity index 100% rename from sound/enemy_destroying_us.ogg rename to sound/embedded/enemy_destroying_us.ogg diff --git a/sound/embedded/enemy_pushing_alpha.ogg b/sound/embedded/enemy_pushing_alpha.ogg new file mode 100644 index 0000000..a0c144d Binary files /dev/null and b/sound/embedded/enemy_pushing_alpha.ogg differ diff --git a/sound/embedded/enemy_pushing_bravo.ogg b/sound/embedded/enemy_pushing_bravo.ogg new file mode 100644 index 0000000..91e6cfe Binary files /dev/null and b/sound/embedded/enemy_pushing_bravo.ogg differ diff --git a/sound/embedded/enemy_pushing_charlie.ogg b/sound/embedded/enemy_pushing_charlie.ogg new file mode 100644 index 0000000..c35159e Binary files /dev/null and b/sound/embedded/enemy_pushing_charlie.ogg differ diff --git a/sound/embedded/enemy_pushing_delta.ogg b/sound/embedded/enemy_pushing_delta.ogg new file mode 100644 index 0000000..7305fc1 Binary files /dev/null and b/sound/embedded/enemy_pushing_delta.ogg differ diff --git a/sound/embedded/enemy_pushing_zone.ogg b/sound/embedded/enemy_pushing_zone.ogg new file mode 100644 index 0000000..bc57d2c Binary files /dev/null and b/sound/embedded/enemy_pushing_zone.ogg differ diff --git a/sound/embedded/enemy_reinforcements_inbound.ogg b/sound/embedded/enemy_reinforcements_inbound.ogg new file mode 100644 index 0000000..70d7301 Binary files /dev/null and b/sound/embedded/enemy_reinforcements_inbound.ogg differ diff --git a/sound/embedded/friendly_troops_dropped_active.ogg b/sound/embedded/friendly_troops_dropped_active.ogg new file mode 100644 index 0000000..2d414f4 Binary files /dev/null and b/sound/embedded/friendly_troops_dropped_active.ogg differ diff --git a/sound/embedded/hold_our_ground.ogg b/sound/embedded/hold_our_ground.ogg new file mode 100644 index 0000000..7308634 Binary files /dev/null and b/sound/embedded/hold_our_ground.ogg differ diff --git a/sound/jtac_dropped.ogg b/sound/embedded/jtac_dropped.ogg similarity index 100% rename from sound/jtac_dropped.ogg rename to sound/embedded/jtac_dropped.ogg diff --git a/sound/embedded/mission_failure.ogg b/sound/embedded/mission_failure.ogg new file mode 100644 index 0000000..267280e Binary files /dev/null and b/sound/embedded/mission_failure.ogg differ diff --git a/sound/embedded/push_back.ogg b/sound/embedded/push_back.ogg new file mode 100644 index 0000000..3e49ccc Binary files /dev/null and b/sound/embedded/push_back.ogg differ diff --git a/sound/tearing_them_up.ogg b/sound/embedded/tearing_them_up.ogg similarity index 100% rename from sound/tearing_them_up.ogg rename to sound/embedded/tearing_them_up.ogg diff --git a/sound/theyre_weak.ogg b/sound/embedded/theyre_weak.ogg similarity index 100% rename from sound/theyre_weak.ogg rename to sound/embedded/theyre_weak.ogg diff --git a/sound/enemy_reinforcements_inbound.ogg b/sound/enemy_reinforcements_inbound.ogg new file mode 100644 index 0000000..70d7301 Binary files /dev/null and b/sound/enemy_reinforcements_inbound.ogg differ diff --git a/sound/enemy_strike_inbound.ogg b/sound/enemy_strike_inbound.ogg new file mode 100644 index 0000000..1d465df Binary files /dev/null and b/sound/enemy_strike_inbound.ogg differ diff --git a/sound/enemy_units_destroyed.ogg b/sound/enemy_units_destroyed.ogg new file mode 100644 index 0000000..2f9233e Binary files /dev/null and b/sound/enemy_units_destroyed.ogg differ diff --git a/sound/friendly_chopper_inbound.ogg b/sound/friendly_chopper_inbound.ogg new file mode 100644 index 0000000..a1990f7 Binary files /dev/null and b/sound/friendly_chopper_inbound.ogg differ diff --git a/sound/friendly_convoy_under_attack.ogg b/sound/friendly_convoy_under_attack.ogg new file mode 100644 index 0000000..dfc2a96 Binary files /dev/null and b/sound/friendly_convoy_under_attack.ogg differ diff --git a/sound/friendly_reinforcements_inbound.ogg b/sound/friendly_reinforcements_inbound.ogg new file mode 100644 index 0000000..1685e91 Binary files /dev/null and b/sound/friendly_reinforcements_inbound.ogg differ diff --git a/sound/friendly_strike_inbound.ogg b/sound/friendly_strike_inbound.ogg new file mode 100644 index 0000000..7790405 Binary files /dev/null and b/sound/friendly_strike_inbound.ogg differ diff --git a/sound/friendly_units_under_attack.ogg b/sound/friendly_units_under_attack.ogg new file mode 100644 index 0000000..842b7dd Binary files /dev/null and b/sound/friendly_units_under_attack.ogg differ diff --git a/sound/hostile_target_destroyed.ogg b/sound/hostile_target_destroyed.ogg new file mode 100644 index 0000000..f5cb692 Binary files /dev/null and b/sound/hostile_target_destroyed.ogg differ diff --git a/sound/losing_battle.ogg b/sound/losing_battle.ogg new file mode 100644 index 0000000..78685f5 Binary files /dev/null and b/sound/losing_battle.ogg differ diff --git a/sound/primary_target_destroyed.ogg b/sound/primary_target_destroyed.ogg new file mode 100644 index 0000000..0717eb6 Binary files /dev/null and b/sound/primary_target_destroyed.ogg differ diff --git a/sound/target_destroyed.ogg b/sound/target_destroyed.ogg new file mode 100644 index 0000000..c9d124a Binary files /dev/null and b/sound/target_destroyed.ogg differ