RotorOps/RotaryOps.lua
spencer-ki 7dd12d09fc ..
2021-12-28 23:06:00 -08:00

340 lines
11 KiB
Lua

RotaryOps = {}
trigger.action.outText("ROTARY OPS STARTED", 5)
local function tableHasKey(table,key)
return table[key] ~= nil
end
local function dispMsg(text)
trigger.action.outText(text, 5)
return text
end
local function tableHasKey(table,key)
return table[key] ~= nil
end
local function getObjectVolume(obj)
local length = (obj:getDesc().box.max.x + math.abs(obj:getDesc().box.min.x))
local height = (obj:getDesc().box.max.y + math.abs(obj:getDesc().box.min.y))
local depth = (obj:getDesc().box.max.z + math.abs(obj:getDesc().box.min.z))
return length * height * depth
end
function RotaryOps.spawnInfantryOnGrp(grp, src_grp_name, behavior) --allow to spawn on other group units
trigger.action.outText("attempting to spawn at "..grp:getUnit(1):getTypeName(), 5)
local vars = {}
vars.gpName = src_grp_name
vars.action = 'clone'
vars.point = grp:getUnit(1):getPoint()
vars.radius = 5
vars.disperse = 'disp'
vars.maxDisp = 5
local new_grp_table = mist.teleportToPoint(vars)
if new_grp_table then
local new_grp = Group.getByName(new_grp_table.name)
local PATROL = 1
local AGGRESSIVE = 2
if behavior == PATROL then
--trigger.action.outText("new group: "..mist.utils.tableShow(new_grp_table), 5)
--local id = timer.scheduleFunction(RotaryOps.seekCover, new_grp, timer.getTime() + 1)
RotaryOps.patrolRadius({grp = new_grp})
end
if behavior == AGGRESSIVE then
RotaryOps.chargeEnemy({grp = new_grp})
end
else trigger.action.outText("Infantry failed to spawn. ", 5)
end
end
function RotaryOps.chargeEnemy(vars)
--trigger.action.outText("charge enemies: "..mist.utils.tableShow(vars), 5)
local grp = vars.grp
local search_radius = vars.radius or 5000
----
local first_valid_unit
if grp:isExist() ~= true then return end
for index, unit in pairs(grp:getUnits())
do
if unit:isExist() == true then
first_valid_unit = unit
break
else --trigger.action.outText("a unit no longer exists", 15)
end
end
----
if first_valid_unit == nil then return end
local start_point = first_valid_unit:getPoint()
if not vars.spawn_point then vars.spawn_point = start_point end
local enemy_coal
if grp:getCoalition() == 1 then enemy_coal = 2 end
if grp:getCoalition() == 2 then enemy_coal = 1 end
--local sphere = trigger.misc.getZone('town')
local volS = {
id = world.VolumeType.SPHERE,
params = {
point = grp:getUnit(1):getPoint(), --check if exists, maybe itterate through grp
radius = search_radius
}
}
local enemy_unit
local path = {}
local ifFound = function(foundItem, val)
--trigger.action.outText("found item: "..foundItem:getTypeName(), 5)
if foundItem:hasAttribute("Infantry") == true and foundItem:getCoalition() == enemy_coal then
enemy_unit = foundItem
--trigger.action.outText("found enemy! "..foundItem:getTypeName(), 5)
path[1] = mist.ground.buildWP(start_point, '', 5)
path[2] = mist.ground.buildWP(enemy_unit:getPoint(), '', 5)
--path[3] = mist.ground.buildWP(vars.spawn_point, '', 5)
else
--trigger.action.outText("object found is not enemy inf in "..search_radius, 5)
end
return true
end
--default path if no units found
if false then
trigger.action.outText("group going back to origin", 5)
path[1] = mist.ground.buildWP(start_point, '', 5)
path[2] = mist.ground.buildWP(vars.spawn_point, '', 5)
end
world.searchObjects(Object.Category.UNIT, volS, ifFound)
mist.goRoute(grp, path)
local id = timer.scheduleFunction(RotaryOps.chargeEnemy, vars, timer.getTime() + math.random(50,70))
end
function RotaryOps.patrolRadius(vars)
trigger.action.outText("patrol radius: "..mist.utils.tableShow(vars), 5)
local grp = vars.grp
local search_radius = vars.radius or 100
local first_valid_unit
if grp:isExist() ~= true then return end
for index, unit in pairs(grp:getUnits())
do
if unit:isExist() == true then
first_valid_unit = unit
break
else --trigger.action.outText("a unit no longer exists", 15)
end
end
if first_valid_unit == nil then return end
local start_point = first_valid_unit:getPoint()
local object_vol_thresh = 0
local max_waypoints = 5
local foundUnits = {}
--local sphere = trigger.misc.getZone('town')
local volS = {
id = world.VolumeType.SPHERE,
params = {
point = grp:getUnit(1):getPoint(), --check if exists, maybe itterate through grp
radius = search_radius
}
}
local ifFound = function(foundItem, val)
--trigger.action.outText("found item: "..foundItem:getTypeName(), 5)
if foundItem:hasAttribute("Infantry") ~= true then --disregard infantry...we only want objects that might provide cover
if getObjectVolume(foundItem) > object_vol_thresh then
foundUnits[#foundUnits + 1] = foundItem
--trigger.action.outText("valid cover item: "..foundItem:getTypeName(), 5)
else trigger.action.outText("object not large enough: "..foundItem:getTypeName(), 5)
end
else --trigger.action.outText("object not the right type", 5)
end
return true
end
world.searchObjects(1, volS, ifFound)
world.searchObjects(3, volS, ifFound)
world.searchObjects(5, volS, ifFound)
--world.searchObjects(Object.Category.BASE, volS, ifFound)
local path = {}
path[1] = mist.ground.buildWP(start_point, '', 5)
local m = math.min(#foundUnits, max_waypoints)
for i = 1, m, 1
do
local rand_index = math.random(1,#foundUnits)
path[i + 1] = mist.ground.buildWP(foundUnits[rand_index]:getPoint(), '', 5)
--trigger.action.outText("waypoint to: "..foundUnits[rand_index]:getTypeName(), 5)
end
if #path <= 3 then
for i = #path, max_waypoints, 1
do
path[#path + 1] = mist.ground.buildWP(mist.getRandPointInCircle(start_point, search_radius), '', 5)
end
end
--trigger.action.outText("new waypoints created: "..(#path - 1), 5)
mist.goRoute(grp, path)
--local timing = mist.getPathLength(path) / 5
local id = timer.scheduleFunction(RotaryOps.patrolRadius, vars, timer.getTime() + math.random(50,70))
end
function RotaryOps.knowEnemy(vars)
--trigger.action.outText("charge enemies: "..mist.utils.tableShow(vars), 5)
local grp = vars.grp
local search_radius = vars.radius or 5000
----
local first_valid_unit
if grp:isExist() ~= true then return end
for index, unit in pairs(grp:getUnits())
do
if unit:isExist() == true then
first_valid_unit = unit
break
else --trigger.action.outText("a unit no longer exists", 15)
end
end
----
if first_valid_unit == nil then return end
local start_point = first_valid_unit:getPoint()
if not vars.spawn_point then vars.spawn_point = start_point end
local enemy_coal
if grp:getCoalition() == 1 then enemy_coal = 2 end
if grp:getCoalition() == 2 then enemy_coal = 1 end
--local sphere = trigger.misc.getZone('town')
local volS = {
id = world.VolumeType.SPHERE,
params = {
point = grp:getUnit(1):getPoint(), --check if exists, maybe itterate through grp
radius = search_radius
}
}
local enemy_unit
local path = {}
local ifFound = function(foundItem, val)
--trigger.action.outText("found item: "..foundItem:getTypeName(), 5)
if foundItem:getCoalition() == enemy_coal then
enemy_unit = foundItem
trigger.action.outText("found enemy! "..foundItem:getTypeName(), 5)
path[1] = mist.ground.buildWP(start_point, '', 5)
path[2] = mist.ground.buildWP(enemy_unit:getPoint(), '', 5)
--path[3] = mist.ground.buildWP(vars.spawn_point, '', 5)
grp:getUnit(1):getController():knowTarget(enemy_unit, true, true)
else
--trigger.action.outText("object found is not enemy inf in "..search_radius, 5)
end
return true
end
--default path if no units found
if false then
trigger.action.outText("group going back to origin", 5)
path[1] = mist.ground.buildWP(start_point, '', 5)
path[2] = mist.ground.buildWP(vars.spawn_point, '', 5)
end
world.searchObjects(Object.Category.UNIT, volS, ifFound)
--mist.goRoute(grp, path)
local id = timer.scheduleFunction(RotaryOps.knowEnemy, vars, timer.getTime() + 15)
end
------------------------------------------
RotaryOps.zones = {}
RotaryOps.active_zone = 'ALPHA'
function RotaryOps.sortOutInfantry(mixed_units)
local _infantry = {}
local _not_infantry = {}
for index, unit in pairs(mixed_units)
do
if unit:hasAttribute("Infantry") then
_infantry[#_infantry + 1] = unit
else _not_infantry[#_not_infantry + 1] = unit
end
end
return {infantry = _infantry, not_infantry = _not_infantry}
end
function RotaryOps.assessUnitsInZone(var)
--consider adding other unit types
local red_ground_units = mist.getUnitsInZones(mist.makeUnitTable({'[red][vehicle]'}), {RotaryOps.active_zone}) --consider adding other unit types
local red_infantry = RotaryOps.sortOutInfantry(red_ground_units).infantry
local red_vehicles = RotaryOps.sortOutInfantry(red_ground_units).not_infantry
local blue_ground_units = mist.getUnitsInZones(mist.makeUnitTable({'[blue][vehicle]'}), {RotaryOps.active_zone}) --consider adding other unit types
local blue_infantry = RotaryOps.sortOutInfantry(blue_ground_units).infantry
local blue_vehicles = RotaryOps.sortOutInfantry(blue_ground_units).not_infantry
trigger.action.outText("["..RotaryOps.active_zone .. "] RED: " ..#red_infantry.. " infantry, " .. #red_vehicles .. " vehicles. BLUE: "..#blue_infantry.. " infantry, " .. #blue_vehicles.." vehicles.", 5, true)
local id = timer.scheduleFunction(RotaryOps.assessUnitsInZone, 1, timer.getTime() + 5)
end
local id = timer.scheduleFunction(RotaryOps.assessUnitsInZone, 1, timer.getTime() + 5)
function RotaryOps.drawZones(zones) --should be drawZones and itterate through all zones, getting the active zone, and incrementing id
local previous_point
for index, zone in pairs(zones)
do
local point = trigger.misc.getZone(zone.outter_zone_name).point
local radius = trigger.misc.getZone(zone.outter_zone_name).radius
local coalition = -1
local id = index --this must be UNIQUE!
local color = {1, 1, 1, 0.5}
local fill_color = {1, 1, 1, 0.1}
local text_fill_color = {0, 0, 0, 0}
local line_type = 5 --1 Solid 2 Dashed 3 Dotted 4 Dot Dash 5 Long Dash 6 Two Dash
local font_size = 20
local read_only = false
local text = zone.outter_zone_name
if zone.outter_zone_name == RotaryOps.active_zone then
color = {1, 1, 1, 0.5}
fill_color = {1, 0, 1, 0.1}
end
if previous_point ~= nill then
trigger.action.lineToAll(coalition, id + 200, point, previous_point, color, line_type)
end
previous_point = point
trigger.action.outText("drawing map circle", 5)
trigger.action.circleToAll(coalition, id, point, radius, color, fill_color, line_type)
trigger.action.textToAll(coalition, id + 100, point, color, text_fill_color, font_size, read_only, text)
end
end
function RotaryOps.addZone(_outter_zone_name, _vars, group_id) --todo: implement zone group ids
group_id = group_id or 1
table.insert(RotaryOps.zones, {outter_zone_name = _outter_zone_name, vars = _vars})
RotaryOps.drawZones(RotaryOps.zones)
ctld.dropOffZones[#ctld.dropOffZones + 1] = { _outter_zone_name, "green", 0 }
--trigger.action.outText("zones: ".. mist.utils.tableShow(RotaryOps.zones), 5)
end
--[[
vars = {
inner_zone = '',
infantry_spawn = 10,
infantry_respawn = 50,
infantry_spawn_zone = ''
defender_coal = 'red'
}
]]