mirror of
https://github.com/spencershepard/RotorOps.git
synced 2025-11-10 15:45:30 +00:00
BHD2 and infantry update (#48)
* BHD2 and infantry update - default to easy comms - modify ctld for better infantry models - cleaner logging - warn user if no resources for fat cow FARPs - condition for fat cow added; not available if enemies too close * Update README.md
This commit is contained in:
parent
be89639e6d
commit
bca47d63d6
@ -593,6 +593,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
"blue_cap": self.scenario.getConfigValue("blue_cap", default=True),
|
"blue_cap": self.scenario.getConfigValue("blue_cap", default=True),
|
||||||
"rotorops_server": self.scenario.getConfigValue("rotorops_server", default=False),
|
"rotorops_server": self.scenario.getConfigValue("rotorops_server", default=False),
|
||||||
"perks": self.perks_checkBox.isChecked(),
|
"perks": self.perks_checkBox.isChecked(),
|
||||||
|
"easy_comms": self.scenario.getConfigValue("easy_comms", default=True)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Generating mission with options:")
|
logger.info("Generating mission with options:")
|
||||||
|
|||||||
@ -401,6 +401,12 @@ class RotorOpsMission:
|
|||||||
self.m.random_daytime(options["time"].lower())
|
self.m.random_daytime(options["time"].lower())
|
||||||
print("Time set to " + options["time"])
|
print("Time set to " + options["time"])
|
||||||
|
|
||||||
|
# set the mission options
|
||||||
|
if options["easy_comms"]:
|
||||||
|
# to simplify rearm/refuel at FARPs
|
||||||
|
self.m.options.difficulty.easyCommunication = True
|
||||||
|
|
||||||
|
|
||||||
# Save the mission file
|
# Save the mission file
|
||||||
window.statusBar().showMessage("Saving mission...", 10000)
|
window.statusBar().showMessage("Saving mission...", 10000)
|
||||||
if window.user_output_dir:
|
if window.user_output_dir:
|
||||||
@ -824,7 +830,7 @@ class RotorOpsMission:
|
|||||||
self.m.triggers.add_triggerzone(f_cap_spawn_point, 30000, hidden=True, name="BLUE_CAP_SPAWN")
|
self.m.triggers.add_triggerzone(f_cap_spawn_point, 30000, hidden=True, name="BLUE_CAP_SPAWN")
|
||||||
|
|
||||||
# Fat Cow
|
# Fat Cow
|
||||||
if True:
|
if options["perks"]:
|
||||||
helo_type = dcs.helicopters.CH_47D
|
helo_type = dcs.helicopters.CH_47D
|
||||||
name = "FAT COW"
|
name = "FAT COW"
|
||||||
|
|
||||||
@ -852,6 +858,24 @@ class RotorOpsMission:
|
|||||||
afg.set_skill(dcs.unit.Skill.Excellent)
|
afg.set_skill(dcs.unit.Skill.Excellent)
|
||||||
afg.late_activation = True
|
afg.late_activation = True
|
||||||
|
|
||||||
|
else:
|
||||||
|
afg = self.m.flight_group_inflight(
|
||||||
|
combinedJointTaskForcesBlue,
|
||||||
|
name,
|
||||||
|
helo_type,
|
||||||
|
position=primary_f_airport.position,
|
||||||
|
altitude=500,
|
||||||
|
speed=50,
|
||||||
|
group_size=1
|
||||||
|
)
|
||||||
|
|
||||||
|
if afg:
|
||||||
|
afg.set_skill(dcs.unit.Skill.Excellent)
|
||||||
|
afg.late_activation = True
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception("Unable to insert Fat Cow CH-47")
|
||||||
|
|
||||||
|
|
||||||
if options["f_awacs"]:
|
if options["f_awacs"]:
|
||||||
awacs_name = "AWACS"
|
awacs_name = "AWACS"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
# ROTOROPS VERSION
|
# ROTOROPS VERSION
|
||||||
maj_version = 1
|
maj_version = 1
|
||||||
minor_version = 4
|
minor_version = 4
|
||||||
patch_version = 3
|
patch_version = 4
|
||||||
|
|
||||||
version_url = 'https://dcs-helicopters.com/app-updates/versioncheck.yaml'
|
version_url = 'https://dcs-helicopters.com/app-updates/versioncheck.yaml'
|
||||||
|
|
||||||
|
|||||||
11
README.md
11
README.md
@ -24,15 +24,24 @@ At the core of the RotorOps script are AI enhancements that provide a dynamic gr
|
|||||||
- Single-player and multiplayer slot creation.
|
- Single-player and multiplayer slot creation.
|
||||||
|
|
||||||
## Demo Missions
|
## Demo Missions
|
||||||
|
|
||||||
|
Newest to oldest:
|
||||||
|
|
||||||
|
Black Hawk Down Pt 1 (UH-1H UH-60L) https://www.digitalcombatsimulator.com/en/files/3328428/
|
||||||
|
|
||||||
|
NightHawks (AH-64D) https://www.digitalcombatsimulator.com/en/files/3322036/
|
||||||
|
|
||||||
RotorOps: Aleppo Under Siege https://www.digitalcombatsimulator.com/en/files/3320079/
|
RotorOps: Aleppo Under Siege https://www.digitalcombatsimulator.com/en/files/3320079/
|
||||||
|
|
||||||
Rota Landing (Mr. Nobody) https://www.digitalcombatsimulator.com/en/files/3320186/
|
Rota Landing (Mr. Nobody) https://www.digitalcombatsimulator.com/en/files/3320186/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# RotorOps: Conflict
|
# RotorOps: Conflict
|
||||||
Conflict is a game type in which attacking forces must clear Conflict Zones of defending ground forces. Once a zone is cleared, the next zone is activated and attacking ground vehicles will move to the next Conflict Zone automatically.
|
Conflict is a game type in which attacking forces must clear Conflict Zones of defending ground forces. Once a zone is cleared, the next zone is activated and attacking ground vehicles will move to the next Conflict Zone automatically.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Dynamic Roles
|
## Dynamic Roles
|
||||||
A RotorOps Conflict mission has opportunities for a variety of roles and tasks. There's no need to artificially select these roles, as the mission is fully dynamic.
|
A RotorOps Conflict mission has opportunities for a variety of roles and tasks. There's no need to artificially select these roles, as the mission is fully dynamic.
|
||||||
|
|||||||
@ -26,7 +26,7 @@ ctld = {} -- DONT REMOVE!
|
|||||||
ctld.Id = "CTLD - "
|
ctld.Id = "CTLD - "
|
||||||
|
|
||||||
--- Version.
|
--- Version.
|
||||||
ctld.Version = "20211113.01"
|
ctld.Version = "20211113.01 GRIMM01"
|
||||||
|
|
||||||
-- debug level, specific to this module
|
-- debug level, specific to this module
|
||||||
ctld.Debug = true
|
ctld.Debug = true
|
||||||
@ -1976,9 +1976,9 @@ function ctld.generateTroopTypes(_side, _countOrTemplate, _country)
|
|||||||
if _countOrTemplate.inf then
|
if _countOrTemplate.inf then
|
||||||
ctld.logTrace(string.format("_countOrTemplate.inf=%s", ctld.p(_countOrTemplate.inf)))
|
ctld.logTrace(string.format("_countOrTemplate.inf=%s", ctld.p(_countOrTemplate.inf)))
|
||||||
if _side == 2 then
|
if _side == 2 then
|
||||||
_troops = ctld.insertIntoTroopsArray("Soldier M4",_countOrTemplate.inf,_troops)
|
_troops = ctld.insertIntoTroopsArray("Soldier M4 GRG",_countOrTemplate.inf,_troops)
|
||||||
else
|
else
|
||||||
_troops = ctld.insertIntoTroopsArray("Soldier AK",_countOrTemplate.inf,_troops)
|
_troops = ctld.insertIntoTroopsArray("Infantry AK",_countOrTemplate.inf,_troops)
|
||||||
end
|
end
|
||||||
_weight = _weight + getSoldiersWeight(_countOrTemplate.inf, ctld.RIFLE_WEIGHT)
|
_weight = _weight + getSoldiersWeight(_countOrTemplate.inf, ctld.RIFLE_WEIGHT)
|
||||||
ctld.logTrace(string.format("_weight=%s", ctld.p(_weight)))
|
ctld.logTrace(string.format("_weight=%s", ctld.p(_weight)))
|
||||||
@ -2012,9 +2012,9 @@ function ctld.generateTroopTypes(_side, _countOrTemplate, _country)
|
|||||||
if _countOrTemplate.jtac then
|
if _countOrTemplate.jtac then
|
||||||
ctld.logTrace(string.format("_countOrTemplate.jtac=%s", ctld.p(_countOrTemplate.jtac)))
|
ctld.logTrace(string.format("_countOrTemplate.jtac=%s", ctld.p(_countOrTemplate.jtac)))
|
||||||
if _side == 2 then
|
if _side == 2 then
|
||||||
_troops = ctld.insertIntoTroopsArray("Soldier M4",_countOrTemplate.jtac,_troops, "JTAC")
|
_troops = ctld.insertIntoTroopsArray("Soldier M4 GRG",_countOrTemplate.jtac,_troops, "JTAC")
|
||||||
else
|
else
|
||||||
_troops = ctld.insertIntoTroopsArray("Soldier AK",_countOrTemplate.jtac,_troops, "JTAC")
|
_troops = ctld.insertIntoTroopsArray("Infantry AK",_countOrTemplate.jtac,_troops, "JTAC")
|
||||||
end
|
end
|
||||||
_hasJTAC = true
|
_hasJTAC = true
|
||||||
_weight = _weight + getSoldiersWeight(_countOrTemplate.jtac, ctld.JTAC_WEIGHT + ctld.RIFLE_WEIGHT)
|
_weight = _weight + getSoldiersWeight(_countOrTemplate.jtac, ctld.JTAC_WEIGHT + ctld.RIFLE_WEIGHT)
|
||||||
@ -2024,7 +2024,7 @@ function ctld.generateTroopTypes(_side, _countOrTemplate, _country)
|
|||||||
else
|
else
|
||||||
for _i = 1, _countOrTemplate do
|
for _i = 1, _countOrTemplate do
|
||||||
|
|
||||||
local _unitType = "Soldier AK"
|
local _unitType = "Infantry AK"
|
||||||
|
|
||||||
if _side == 2 then
|
if _side == 2 then
|
||||||
if _i <=2 then
|
if _i <=2 then
|
||||||
@ -2040,7 +2040,7 @@ function ctld.generateTroopTypes(_side, _countOrTemplate, _country)
|
|||||||
_weight = _weight + getSoldiersWeight(1, ctld.MANPAD_WEIGHT)
|
_weight = _weight + getSoldiersWeight(1, ctld.MANPAD_WEIGHT)
|
||||||
ctld.logTrace(string.format("_unitType=%s, _weight=%s", ctld.p(_unitType), ctld.p(_weight)))
|
ctld.logTrace(string.format("_unitType=%s, _weight=%s", ctld.p(_unitType), ctld.p(_weight)))
|
||||||
else
|
else
|
||||||
_unitType = "Soldier M4"
|
_unitType = "Soldier M4 GRG"
|
||||||
_weight = _weight + getSoldiersWeight(1, ctld.RIFLE_WEIGHT)
|
_weight = _weight + getSoldiersWeight(1, ctld.RIFLE_WEIGHT)
|
||||||
ctld.logTrace(string.format("_unitType=%s, _weight=%s", ctld.p(_unitType), ctld.p(_weight)))
|
ctld.logTrace(string.format("_unitType=%s, _weight=%s", ctld.p(_unitType), ctld.p(_weight)))
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
RotorOps = {}
|
RotorOps = {}
|
||||||
RotorOps.version = "1.3.4"
|
RotorOps.version = "1.3.4"
|
||||||
local debug = true
|
local debug = false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ 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 = 0
|
RotorOps.active_zone_index = 0
|
||||||
RotorOps.game_state_flag = 1 --user flag to store the game state
|
RotorOps.game_state_flag = 100 --user flag to store the game state
|
||||||
RotorOps.staging_zones = {}
|
RotorOps.staging_zones = {}
|
||||||
RotorOps.ai_defending_infantry_groups = {}
|
RotorOps.ai_defending_infantry_groups = {}
|
||||||
RotorOps.ai_attacking_infantry_groups = {}
|
RotorOps.ai_attacking_infantry_groups = {}
|
||||||
@ -1200,6 +1200,7 @@ function RotorOps.assessUnitsInZone(var)
|
|||||||
--RotorOps.inf_spawns_avail = RotorOps.inf_spawns_per_zone * RotorOps.inf_spawn_multiplier[RotorOps.active_zone_index]
|
--RotorOps.inf_spawns_avail = RotorOps.inf_spawns_per_zone * RotorOps.inf_spawn_multiplier[RotorOps.active_zone_index]
|
||||||
if total_spawn_zones > 0 then
|
if total_spawn_zones > 0 then
|
||||||
RotorOps.inf_spawns_avail = (RotorOps.inf_spawns_total / total_spawn_zones) * #inf_spawn_zones
|
RotorOps.inf_spawns_avail = (RotorOps.inf_spawns_total / total_spawn_zones) * #inf_spawn_zones
|
||||||
|
RotorOps.inf_spawns_avail = math.ceil(RotorOps.inf_spawns_avail)
|
||||||
end
|
end
|
||||||
|
|
||||||
env.info("ROTOR OPS: zone activated: "..RotorOps.active_zone..", inf spawns avail:"..RotorOps.inf_spawns_avail..", spawn zones:"..#inf_spawn_zones)
|
env.info("ROTOR OPS: zone activated: "..RotorOps.active_zone..", inf spawns avail:"..RotorOps.inf_spawns_avail..", spawn zones:"..#inf_spawn_zones)
|
||||||
@ -1285,7 +1286,8 @@ function RotorOps.assessUnitsInZone(var)
|
|||||||
|
|
||||||
for index, vehicle in pairs(units_table) do
|
for index, vehicle in pairs(units_table) do
|
||||||
local should_deploy = false
|
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
|
if vehicle:hasAttribute("Infantry carriers") or vehicle:hasAttribute("Trucks") then --if a vehicle is an APC
|
||||||
|
if RotorOps.isUnitInZone(vehicle, RotorOps.active_zone) then --if a vehicle is an APC and in zone
|
||||||
local apc_name = vehicle:getName()
|
local apc_name = vehicle:getName()
|
||||||
|
|
||||||
if tableHasKey(apcs, apc_name) == true then --if we have this apc in our table already
|
if tableHasKey(apcs, apc_name) == true then --if we have this apc in our table already
|
||||||
@ -1303,6 +1305,7 @@ function RotorOps.assessUnitsInZone(var)
|
|||||||
should_deploy = true
|
should_deploy = true
|
||||||
apcs[apc_name] = {['deployed_zones'] = {RotorOps.active_zone,}}
|
apcs[apc_name] = {['deployed_zones'] = {RotorOps.active_zone,}}
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1314,7 +1317,7 @@ function RotorOps.assessUnitsInZone(var)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local id = timer.scheduleFunction(timedDeploy, nil, timer.getTime() + math.random(90, 180))
|
local id = timer.scheduleFunction(timedDeploy, nil, timer.getTime() + math.random(90, 300))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -1332,7 +1335,9 @@ function RotorOps.assessUnitsInZone(var)
|
|||||||
local zone = inf_spawn_zones[rand_index]
|
local zone = inf_spawn_zones[rand_index]
|
||||||
|
|
||||||
ctld.spawnGroupAtTrigger("red", RotorOps.inf_spawn_red, zone, 1000)
|
ctld.spawnGroupAtTrigger("red", RotorOps.inf_spawn_red, zone, 1000)
|
||||||
RotorOps.gameMsg(RotorOps.gameMsgs.infantry_spawned, math.random(1, #RotorOps.gameMsgs.infantry_spawned))
|
if RotorOps.inf_spawn_messages then
|
||||||
|
RotorOps.gameMsg(RotorOps.gameMsgs.infantry_spawned, math.random(1, #RotorOps.gameMsgs.infantry_spawned))
|
||||||
|
end
|
||||||
|
|
||||||
RotorOps.inf_spawns_avail = RotorOps.inf_spawns_avail - 1
|
RotorOps.inf_spawns_avail = RotorOps.inf_spawns_avail - 1
|
||||||
env.info("ROTOR OPS: Attempting to spawn infantry. "..RotorOps.inf_spawns_avail.." spawns remaining in "..zone)
|
env.info("ROTOR OPS: Attempting to spawn infantry. "..RotorOps.inf_spawns_avail.." spawns remaining in "..zone)
|
||||||
@ -2226,3 +2231,4 @@ function RotorOps.predSpawnRedCap()
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -9,13 +9,13 @@
|
|||||||
|
|
||||||
-- Issues:
|
-- Issues:
|
||||||
-- - You will not get points for your troops' kills if you leave your group (ie switch aircraft)
|
-- - You will not get points for your troops' kills if you leave your group (ie switch aircraft)
|
||||||
|
-- - Currently requires a modified version of MIST (see rotorops repo /scripts)
|
||||||
|
|
||||||
--Todo:
|
--Todo:
|
||||||
-- - more testing needed in RotorOpsPerks.monitorFarps() to check for destroyed farp objects.
|
|
||||||
|
|
||||||
|
|
||||||
RotorOpsPerks = {}
|
RotorOpsPerks = {}
|
||||||
RotorOpsPerks.version = "1.5.1"
|
RotorOpsPerks.version = "1.5.2"
|
||||||
env.warning('ROTOROPS PERKS STARTED: '..RotorOpsPerks.version)
|
env.warning('ROTOROPS PERKS STARTED: '..RotorOpsPerks.version)
|
||||||
trigger.action.outText('ROTOROPS PERKS STARTED: '..RotorOpsPerks.version, 10)
|
trigger.action.outText('ROTOROPS PERKS STARTED: '..RotorOpsPerks.version, 10)
|
||||||
RotorOpsPerks.perks = {}
|
RotorOpsPerks.perks = {}
|
||||||
@ -52,11 +52,17 @@ RotorOpsPerks.player_fatcow_types = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
---- END OPTIONS ----
|
---- END OPTIONS ----
|
||||||
|
local function log(msg)
|
||||||
|
env.info("ROTOROPS PERKS: " .. msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local function debugMsg(msg)
|
local function debugMsg(msg)
|
||||||
if RotorOpsPerks.debug then
|
if RotorOpsPerks.debug then
|
||||||
env.info("ROTOROPS PERKS:")
|
log("ROTOROPS PERKS:")
|
||||||
env.info(msg)
|
if msg then
|
||||||
|
log(msg)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -93,6 +99,27 @@ RotorOpsPerks.perks.fatcow["action_condition"] = function(args)
|
|||||||
return {msg="No FARP resources available!", valid=false}
|
return {msg="No FARP resources available!", valid=false}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--rearming/refueling doesn't work if enemies are nearby (within 1.1nm)
|
||||||
|
--this is a DCS feature/limitation so we won't deploy the farp to avoid confusing the players
|
||||||
|
local units_in_proximity = RotorOpsPerks.findUnitsInVolume({
|
||||||
|
volume_type = world.VolumeType.SPHERE,
|
||||||
|
point = args.target_point,
|
||||||
|
radius = 2050
|
||||||
|
})
|
||||||
|
|
||||||
|
log("units_in_proximity: "..#units_in_proximity)
|
||||||
|
|
||||||
|
local enemy_coal = 1
|
||||||
|
if args.player_coalition == 1 then
|
||||||
|
enemy_coal = 2
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, unit in pairs(units_in_proximity) do
|
||||||
|
if unit:getCoalition() == enemy_coal then
|
||||||
|
return {msg="Too close to enemy!", valid=false}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return {valid=true}
|
return {valid=true}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -267,17 +294,42 @@ end
|
|||||||
RotorOpsPerks.perks.player_fatcow["action_condition"] = function(args)
|
RotorOpsPerks.perks.player_fatcow["action_condition"] = function(args)
|
||||||
local player_unit = Group.getByName(args.player_group_name):getUnit(1)
|
local player_unit = Group.getByName(args.player_group_name):getUnit(1)
|
||||||
local agl_altitude = player_unit:getPosition().p.y - land.getHeight(player_unit:getPosition().p)
|
local agl_altitude = player_unit:getPosition().p.y - land.getHeight(player_unit:getPosition().p)
|
||||||
|
|
||||||
if RotorOpsPerks.perks.player_fatcow.active[args.player_group_name] then
|
if RotorOpsPerks.perks.player_fatcow.active[args.player_group_name] then
|
||||||
return {msg="FARP already deployed at your position!", valid=false}
|
return {msg="FARP already deployed at your position!", valid=false}
|
||||||
end
|
end
|
||||||
|
|
||||||
if #RotorOpsPerks.fat_cow_farps < 1 then
|
if #RotorOpsPerks.fat_cow_farps < 1 then
|
||||||
return {msg="No FARP resources available!", valid=false}
|
return {msg="No FARP resources available!", valid=false}
|
||||||
end
|
end
|
||||||
|
|
||||||
if agl_altitude > 100 then
|
if agl_altitude > 100 then
|
||||||
return {msg="You must be on the ground! "..agl_altitude.." AGL", valid=false}
|
return {msg="You must be on the ground! "..agl_altitude.." AGL", valid=false}
|
||||||
else
|
|
||||||
return {msg="Stay on the ground.", valid=true}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--rearming/refueling doesn't work if enemies are nearby (within 1.1nm)
|
||||||
|
--this is a DCS feature/limitation so we won't deploy the farp to avoid confusing the players
|
||||||
|
local units_in_proximity = RotorOpsPerks.findUnitsInVolume({
|
||||||
|
volume_type = world.VolumeType.SPHERE,
|
||||||
|
point = args.target_point,
|
||||||
|
radius = 2050
|
||||||
|
})
|
||||||
|
|
||||||
|
log("units_in_proximity: "..#units_in_proximity)
|
||||||
|
|
||||||
|
local enemy_coal = 1
|
||||||
|
if args.player_coalition == 1 then
|
||||||
|
enemy_coal = 2
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, unit in pairs(units_in_proximity) do
|
||||||
|
if unit:getCoalition() == enemy_coal then
|
||||||
|
return {msg="Too close to enemy!", valid=false}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return {msg="Stay on the ground.", valid=true}
|
||||||
end
|
end
|
||||||
|
|
||||||
RotorOpsPerks.perks.player_fatcow["action_function"] = function(args)
|
RotorOpsPerks.perks.player_fatcow["action_function"] = function(args)
|
||||||
@ -302,10 +354,10 @@ RotorOpsPerks.perks.player_fatcow["monitor_player"] = function(args)
|
|||||||
local agl_altitude = player_unit:getPosition().p.y - land.getHeight(player_unit:getPosition().p)
|
local agl_altitude = player_unit:getPosition().p.y - land.getHeight(player_unit:getPosition().p)
|
||||||
if agl_altitude > 100 or not player_unit:isExist() then
|
if agl_altitude > 100 or not player_unit:isExist() then
|
||||||
despawn_farp = true
|
despawn_farp = true
|
||||||
env.info("Player is no longer on the ground, despawning FARP!")
|
log("Player is no longer on the ground, despawning FARP!")
|
||||||
end
|
end
|
||||||
if math.abs(player_unit:getPosition().p.x - args.target_point.x) > 50 or math.abs(player_unit:getPosition().p.z - args.target_point.z) > 50 then
|
if math.abs(player_unit:getPosition().p.x - args.target_point.x) > 50 or math.abs(player_unit:getPosition().p.z - args.target_point.z) > 50 then
|
||||||
env.info("Player has moved from target position, despawning FARP!")
|
log("Player has moved from target position, despawning FARP!")
|
||||||
despawn_farp = true
|
despawn_farp = true
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -435,8 +487,8 @@ function RotorOpsPerks.checkPoints(player_group_name)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
env.info("Checking points for "..player_group_name.."...")
|
log("Checking points for "..player_group_name.."...")
|
||||||
env.info(mist.utils.tableShow(players, "players"))
|
log(mist.utils.tableShow(players, "players"))
|
||||||
|
|
||||||
--get combined points from all Players
|
--get combined points from all Players
|
||||||
local total_points = 0
|
local total_points = 0
|
||||||
@ -510,7 +562,7 @@ function RotorOpsPerks.updatePlayer(identifier, groupName, name, slot)
|
|||||||
perks_used = {},
|
perks_used = {},
|
||||||
}
|
}
|
||||||
env.warning('ADDED ' .. identifier .. ' TO PLAYERS TABLE')
|
env.warning('ADDED ' .. identifier .. ' TO PLAYERS TABLE')
|
||||||
env.info(mist.utils.tableShow(RotorOpsPerks.players[identifier]))
|
log(mist.utils.tableShow(RotorOpsPerks.players[identifier]))
|
||||||
missionCommands.removeItemForGroup(groupId, {[1] = 'ROTOROPS PERKS'})
|
missionCommands.removeItemForGroup(groupId, {[1] = 'ROTOROPS PERKS'})
|
||||||
RotorOpsPerks.addRadioMenuForGroup(groupName)
|
RotorOpsPerks.addRadioMenuForGroup(groupName)
|
||||||
if RotorOpsPerks.player_update_messages then
|
if RotorOpsPerks.player_update_messages then
|
||||||
@ -520,7 +572,7 @@ function RotorOpsPerks.updatePlayer(identifier, groupName, name, slot)
|
|||||||
--update an existing player
|
--update an existing player
|
||||||
elseif RotorOpsPerks.players[identifier].groupId ~= groupId then
|
elseif RotorOpsPerks.players[identifier].groupId ~= groupId then
|
||||||
env.warning('UPDATING ' .. identifier .. ' TO GROUP NAME: ' .. groupName)
|
env.warning('UPDATING ' .. identifier .. ' TO GROUP NAME: ' .. groupName)
|
||||||
env.info(mist.utils.tableShow(RotorOpsPerks.players[identifier]))
|
log(mist.utils.tableShow(RotorOpsPerks.players[identifier]))
|
||||||
if RotorOpsPerks.player_update_messages then
|
if RotorOpsPerks.player_update_messages then
|
||||||
trigger.action.outText('PERKS: ' .. name .. ' moved to '.. groupName, 10)
|
trigger.action.outText('PERKS: ' .. name .. ' moved to '.. groupName, 10)
|
||||||
end
|
end
|
||||||
@ -590,7 +642,7 @@ end
|
|||||||
---- FATCOW FARP SUPPORTING FUNCTIONS ----
|
---- FATCOW FARP SUPPORTING FUNCTIONS ----
|
||||||
|
|
||||||
function RotorOpsPerks.monitorFarps()
|
function RotorOpsPerks.monitorFarps()
|
||||||
env.info(mist.utils.tableShow(RotorOpsPerks.fat_cow_farps))
|
--log(mist.utils.tableShow(RotorOpsPerks.fat_cow_farps))
|
||||||
|
|
||||||
local function farpExists(i)
|
local function farpExists(i)
|
||||||
local farp = StaticObject.getByName('FAT COW FARP ' .. i)
|
local farp = StaticObject.getByName('FAT COW FARP ' .. i)
|
||||||
@ -627,7 +679,7 @@ function RotorOpsPerks.buildFatCowFarpTable()
|
|||||||
local ammo = StaticObject.getByName('FAT COW AMMO ' .. i)
|
local ammo = StaticObject.getByName('FAT COW AMMO ' .. i)
|
||||||
local fuel = StaticObject.getByName('FAT COW FUEL ' .. i)
|
local fuel = StaticObject.getByName('FAT COW FUEL ' .. i)
|
||||||
if farp and tent and ammo and fuel then
|
if farp and tent and ammo and fuel then
|
||||||
env.info("FAT COW FARP " .. i .. " FOUND")
|
log("FAT COW FARP " .. i .. " FOUND")
|
||||||
RotorOpsPerks.fat_cow_farps[i] = {
|
RotorOpsPerks.fat_cow_farps[i] = {
|
||||||
index = i,
|
index = i,
|
||||||
farp = farp,
|
farp = farp,
|
||||||
@ -655,7 +707,7 @@ function RotorOpsPerks.teleportStatic(source_name, dest_point)
|
|||||||
debugMsg('RotorOpsPerks.teleportStatic: ' .. source_name)
|
debugMsg('RotorOpsPerks.teleportStatic: ' .. source_name)
|
||||||
local source = StaticObject.getByName(source_name)
|
local source = StaticObject.getByName(source_name)
|
||||||
if not source then
|
if not source then
|
||||||
env.info('RotorOpsPerks.teleportStatic: source not found: ' .. source_name)
|
log('RotorOpsPerks.teleportStatic: source not found: ' .. source_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local vars = {}
|
local vars = {}
|
||||||
@ -664,14 +716,14 @@ function RotorOpsPerks.teleportStatic(source_name, dest_point)
|
|||||||
vars.point = mist.utils.makeVec3(dest_point)
|
vars.point = mist.utils.makeVec3(dest_point)
|
||||||
local res = mist.teleportToPoint(vars)
|
local res = mist.teleportToPoint(vars)
|
||||||
if res then
|
if res then
|
||||||
env.info('RotorOpsPerks.teleportStatic: ' .. source_name .. ' success')
|
log('RotorOpsPerks.teleportStatic: ' .. source_name .. ' success')
|
||||||
else
|
else
|
||||||
env.info('RotorOpsPerks.teleportStatic: ' .. source_name .. ' failed')
|
log('RotorOpsPerks.teleportStatic: ' .. source_name .. ' failed')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function RotorOpsPerks.spawnFatCowFarpObjects(pt_x, pt_y, index, delay)
|
function RotorOpsPerks.spawnFatCowFarpObjects(pt_x, pt_y, index, delay)
|
||||||
env.info('spawnFatCowFarpObjects called. Looking for static group names ending in ' .. index)
|
log('spawnFatCowFarpObjects called. Looking for static group names ending in ' .. index)
|
||||||
local dest_point = mist.utils.makeVec3GL({x = pt_x, y = pt_y})
|
local dest_point = mist.utils.makeVec3GL({x = pt_x, y = pt_y})
|
||||||
trigger.action.smoke(dest_point, 2)
|
trigger.action.smoke(dest_point, 2)
|
||||||
|
|
||||||
@ -693,12 +745,12 @@ function RotorOpsPerks.spawnFatCow(dest_point, farp)
|
|||||||
local fatcow_name = 'FAT COW'
|
local fatcow_name = 'FAT COW'
|
||||||
local source_farp_name = 'FAT COW FARP ' .. index
|
local source_farp_name = 'FAT COW FARP ' .. index
|
||||||
|
|
||||||
env.info('spawnFatCow called with ' .. source_farp_name)
|
log('spawnFatCow called with ' .. source_farp_name)
|
||||||
|
|
||||||
--set a timer to return the farp static resources to be reused
|
--set a timer to return the farp static resources to be reused
|
||||||
timer.scheduleFunction(function()
|
timer.scheduleFunction(function()
|
||||||
table.insert(RotorOpsPerks.fat_cow_farps, farp) --put it back at the end of the list
|
table.insert(RotorOpsPerks.fat_cow_farps, farp) --put it back at the end of the list
|
||||||
env.info('FatCow FARP timer expired, making the farp available to be used again.')
|
log('FatCow FARP timer expired, making the farp available to be used again.')
|
||||||
end, nil, timer.getTime() + 1800)
|
end, nil, timer.getTime() + 1800)
|
||||||
|
|
||||||
dest_point = mist.utils.makeVec2(dest_point)
|
dest_point = mist.utils.makeVec2(dest_point)
|
||||||
@ -793,8 +845,8 @@ function RotorOpsPerks.spawnFatCow(dest_point, farp)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function RotorOpsPerks.requestPerk(args)
|
function RotorOpsPerks.requestPerk(args)
|
||||||
env.info('requestPerk called for ' .. args.perk_name)
|
log('requestPerk called for ' .. args.perk_name)
|
||||||
--env.info(mist.utils.tableShow(args, 'args'))
|
--log(mist.utils.tableShow(args, 'args'))
|
||||||
local player_group = Group.getByName(args.player_group_name)
|
local player_group = Group.getByName(args.player_group_name)
|
||||||
local player_unit = player_group:getUnits()[1]
|
local player_unit = player_group:getUnits()[1]
|
||||||
local player_unit_name = player_unit:getName()
|
local player_unit_name = player_unit:getName()
|
||||||
@ -834,7 +886,7 @@ function RotorOpsPerks.requestPerk(args)
|
|||||||
mark_name = mark_name:gsub("\n", "")
|
mark_name = mark_name:gsub("\n", "")
|
||||||
if mark_name == args.perk_name then
|
if mark_name == args.perk_name then
|
||||||
perk_name_matches = true
|
perk_name_matches = true
|
||||||
env.info("mark name matches perk name")
|
log("mark name matches perk name")
|
||||||
end
|
end
|
||||||
|
|
||||||
if perk_name_matches then
|
if perk_name_matches then
|
||||||
@ -866,9 +918,9 @@ function RotorOpsPerks.requestPerk(args)
|
|||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- env.info(mist.utils.tableShow(mist.DBs.markList, 'markList'))
|
-- log(mist.utils.tableShow(mist.DBs.markList, 'markList'))
|
||||||
-- env.info('player group' .. mist.utils.tableShow(player_group, 'player_group'))
|
-- log('player group' .. mist.utils.tableShow(player_group, 'player_group'))
|
||||||
-- env.info('player' .. mist.utils.tableShow(player_unit, 'player_unit'))
|
-- log('player' .. mist.utils.tableShow(player_unit, 'player_unit'))
|
||||||
if temp_mark then
|
if temp_mark then
|
||||||
target_point = temp_mark.pos
|
target_point = temp_mark.pos
|
||||||
end
|
end
|
||||||
@ -923,9 +975,10 @@ function RotorOpsPerks.requestPerk(args)
|
|||||||
args.player_group = player_group
|
args.player_group = player_group
|
||||||
args.player_unit = player_unit
|
args.player_unit = player_unit
|
||||||
args.player_unit_name = player_unit_name
|
args.player_unit_name = player_unit_name
|
||||||
|
args.player_coalition = player_group:getCoalition()
|
||||||
|
|
||||||
--show all variables available to perk actions and conditions
|
--show all variables available to perk actions and conditions
|
||||||
--env.info('args: ' .. mist.utils.tableShow(args, 'args'))
|
--log('args: ' .. mist.utils.tableShow(args, 'args'))
|
||||||
|
|
||||||
|
|
||||||
--check the perk's unique prerequisite conditions
|
--check the perk's unique prerequisite conditions
|
||||||
@ -947,9 +1000,9 @@ function RotorOpsPerks.requestPerk(args)
|
|||||||
|
|
||||||
--check points
|
--check points
|
||||||
if RotorOpsPerks.spendPoints(args.player_group_name, perk.cost, false) then
|
if RotorOpsPerks.spendPoints(args.player_group_name, perk.cost, false) then
|
||||||
env.info(args.player_group_name.. ' has sufficient (' .. perk.cost .. ') points for ' .. args.perk_name)
|
log(args.player_group_name.. ' has sufficient (' .. perk.cost .. ') points for ' .. args.perk_name)
|
||||||
else
|
else
|
||||||
env.info(args.player_group_name.. ' tried to spend ' .. perk.cost .. ' points for ' .. args.perk_name .. ' but did not have enough points')
|
log(args.player_group_name.. ' tried to spend ' .. perk.cost .. ' points for ' .. args.perk_name .. ' but did not have enough points')
|
||||||
if #players == 1 then
|
if #players == 1 then
|
||||||
trigger.action.outTextForGroup(player_group:getID(), 'NEGATIVE. You have ' .. RotorOpsPerks.getPlayerGroupSum(args.player_group_name, "points") .. ' points. (cost '.. perk.cost .. ')', 10)
|
trigger.action.outTextForGroup(player_group:getID(), 'NEGATIVE. You have ' .. RotorOpsPerks.getPlayerGroupSum(args.player_group_name, "points") .. ' points. (cost '.. perk.cost .. ')', 10)
|
||||||
else
|
else
|
||||||
@ -996,7 +1049,7 @@ function RotorOpsPerks.requestPerk(args)
|
|||||||
trigger.action.outTextForGroup(_player.groupId, 'AFFIRM. ' .. RotorOpsPerks.perks[args.perk_name].display_name .. position_string, 10)
|
trigger.action.outTextForGroup(_player.groupId, 'AFFIRM. ' .. RotorOpsPerks.perks[args.perk_name].display_name .. position_string, 10)
|
||||||
else
|
else
|
||||||
-- send messages to all other players
|
-- send messages to all other players
|
||||||
env.info(player_unit:getPlayerName() .. ' requested ' .. RotorOpsPerks.perks[args.perk_name].display_name .. position_string)
|
log(player_unit:getPlayerName() .. ' requested ' .. RotorOpsPerks.perks[args.perk_name].display_name .. position_string)
|
||||||
trigger.action.outTextForGroup(_player.groupId, player_unit:getPlayerName() .. ' requested ' .. RotorOpsPerks.perks[args.perk_name].display_name .. position_string, 10)
|
trigger.action.outTextForGroup(_player.groupId, player_unit:getPlayerName() .. ' requested ' .. RotorOpsPerks.perks[args.perk_name].display_name .. position_string, 10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1157,11 +1210,11 @@ function RotorOpsPerks.registerCtldCallbacks()
|
|||||||
local unit = _args.unit
|
local unit = _args.unit
|
||||||
local picked_troops = _args.onboard
|
local picked_troops = _args.onboard
|
||||||
local dropped_troops = _args.unloaded
|
local dropped_troops = _args.unloaded
|
||||||
--env.info("ctld callback: ".. mist.utils.tableShow(_args))
|
--log("ctld callback: ".. mist.utils.tableShow(_args))
|
||||||
|
|
||||||
if dropped_troops then
|
if dropped_troops then
|
||||||
--env.info('dropped troops: ' .. mist.utils.tableShow(dropped_troops))
|
--log('dropped troops: ' .. mist.utils.tableShow(dropped_troops))
|
||||||
--env.info('dropped troops group name: ' .. dropped_troops:getName())
|
--log('dropped troops group name: ' .. dropped_troops:getName())
|
||||||
RotorOpsPerks.troops[dropped_troops:getName()] = {dropped_troops=dropped_troops:getName(), player_group=unit:getGroup():getName(), player_name=unit:getPlayerName(), player_unit=unit:getName(), side=unit:getGroup():getCoalition() , qty=#dropped_troops:getUnits()}
|
RotorOpsPerks.troops[dropped_troops:getName()] = {dropped_troops=dropped_troops:getName(), player_group=unit:getGroup():getName(), player_name=unit:getPlayerName(), player_unit=unit:getName(), side=unit:getGroup():getCoalition() , qty=#dropped_troops:getUnits()}
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -1253,16 +1306,23 @@ function RotorOpsPerks.monitorPlayers()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if mist.grimm_version then
|
if mist.grimm_version then
|
||||||
env.info("GRIMM's version of MIST is loaded")
|
log("GRIMM's version of MIST is loaded")
|
||||||
else
|
else
|
||||||
env.warning("ROTOROPS PERKS REQUIRES A MODIFIED VERSION OF MIST TO WORK PROPERLY. PLEASE SEE THE SCRIPTS FOLDER IN THE ROTOROPS GITHUB REPO")
|
env.warning("ERROR: ROTOROPS PERKS REQUIRES A MODIFIED VERSION OF MIST TO WORK PROPERLY. PLEASE SEE THE SCRIPTS FOLDER IN THE ROTOROPS GITHUB REPO")
|
||||||
trigger.action.outText("ERROR: ROTOROPS PERKS REQUIRES A MODIFIED VERSION OF MIST TO WORK PROPERLY.", 30)
|
trigger.action.outText("ERROR: ROTOROPS PERKS REQUIRES A MODIFIED VERSION OF MIST TO WORK PROPERLY.", 30)
|
||||||
end
|
end
|
||||||
|
|
||||||
RotorOpsPerks.buildFatCowFarpTable()
|
RotorOpsPerks.buildFatCowFarpTable()
|
||||||
env.info("Found " .. #RotorOpsPerks.fat_cow_farps .. " Fat Cow FARPs")
|
log("Found " .. #RotorOpsPerks.fat_cow_farps .. " Fat Cow FARPs")
|
||||||
if #RotorOpsPerks.fat_cow_farps > 0 then
|
if #RotorOpsPerks.fat_cow_farps > 0 then
|
||||||
RotorOpsPerks.monitorFarps()
|
RotorOpsPerks.monitorFarps()
|
||||||
|
else
|
||||||
|
env.warning("NO FAT COW FARPS FOUND. PLEASE SEE THE ROTOROPS WIKI FOR INSTRUCTIONS ON HOW TO SET UP FAT COW FARPS")
|
||||||
|
trigger.action.outText("WARNING: NO FAT COW FARPS FOUND.", 30)
|
||||||
|
end
|
||||||
|
if not Group.getByName('FAT COW') then
|
||||||
|
env.warning("NO AI FAT COW HELICOPTER FOUND. PLEASE SEE THE ROTOROPS WIKI FOR INSTRUCTIONS ON HOW TO SET UP FAT COW FARPS")
|
||||||
|
trigger.action.outText("WARNING: NO AI FAT COW HELICOPTER FOUND.", 30)
|
||||||
end
|
end
|
||||||
RotorOpsPerks.registerCtldCallbacks()
|
RotorOpsPerks.registerCtldCallbacks()
|
||||||
-- start a 5 second timer to monitor players, to allow other scripts to load
|
-- start a 5 second timer to monitor players, to allow other scripts to load
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user