Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
110 lines
5.8 KiB
C
110 lines
5.8 KiB
C
modded class SCR_ChimeraAIAgent
|
|
{
|
|
void ProbeHuntRelease() { ERR_PrisonPhaseChanged(ERR_Phase.PRISON, ERR_Phase.RADIO_SEARCH); SetPermanentLOD(0); ActivateAI(); }
|
|
}
|
|
modded class ERR_HunterService
|
|
{
|
|
ERR_HunterVehicle ProbeHuntUnit(vector position, vector angles, int ordinal)
|
|
{
|
|
ERR_HunterVehicle unit = new ERR_HunterVehicle(); unit.Source = "hunt-probe-" + ordinal.ToString();
|
|
unit.TroopTransport = ordinal == 2;
|
|
unit.Entity = Vehicle.Cast(ERR_Actors.Spawn(ERR_HunterFleetRules.VehiclePrefab(ordinal), position, angles));
|
|
unit.Group = SCR_AIGroup.Cast(ERR_Actors.Spawn(ERR_ConvoyResources.GroupPrefab(), position));
|
|
if (!unit.Entity || !unit.Group || !FillCrew(unit)) return null;
|
|
unit.Group.SetPermanentLOD(0); unit.Group.ActivateAI();
|
|
return unit;
|
|
}
|
|
}
|
|
modded class ERR_HunterTactics
|
|
{
|
|
bool ProbeHuntBegin(float now)
|
|
{
|
|
foreach (IEntity member : Unit.Members)
|
|
{
|
|
AIControlComponent control = AIControlComponent.Cast(member.FindComponent(AIControlComponent));
|
|
SCR_ChimeraAIAgent agent = SCR_ChimeraAIAgent.Cast(control.GetControlAIAgent()); if (agent) agent.ProbeHuntRelease();
|
|
}
|
|
SCR_AIGroupUtilityComponent utility = Unit.Group.GetGroupUtilityComponent();
|
|
SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(Unit.Entity.FindComponent(SCR_AIVehicleUsageComponent));
|
|
if (utility && usage) utility.AddUsableVehicle(usage);
|
|
if (!Move(Stage, 35)) return false;
|
|
Delivered = true; State = 1; Deadline = now + ERR_HunterAttackRules.ManeuverBudget(m_TravelDistance);
|
|
m_ApproachStarted = now; m_ApproachProgress = now; m_ApproachPosition = Unit.Entity.GetOrigin();
|
|
if (Role == 0) foreach (IEntity crew : Unit.Members) ERR_ConvoyMountedCrew.Hold(crew, Unit.Entity);
|
|
return true;
|
|
}
|
|
}
|
|
modded class ArmaReforgerScripted
|
|
{
|
|
protected ref ERR_HunterOpeningPlan m_HuntPlan;
|
|
protected ref ERR_HunterService m_HuntService;
|
|
protected ref ERR_HunterAttack m_HuntAttack;
|
|
protected ref array<ref ERR_HunterVehicle> m_HuntUnits = {};
|
|
protected ref array<vector> m_HuntStarts = {};
|
|
protected int m_HuntPhase;
|
|
protected float m_HuntNext;
|
|
protected float m_HuntStarted;
|
|
override void OnUpdate(BaseWorld world, float timeslice)
|
|
{
|
|
super.OnUpdate(world, timeslice);
|
|
ERR_GameMode mode = ERR_GameMode.Get();
|
|
if (!mode || mode.Phase() < ERR_Phase.PRISON || m_HuntPhase == 3) return;
|
|
float now = world.GetWorldTime(); if (now < m_HuntNext) return; m_HuntNext = now + 1000;
|
|
if (m_HuntPhase == 0)
|
|
{
|
|
if (!m_HuntPlan)
|
|
{
|
|
vector center, angles;
|
|
if (!ERR_SupplyConvoySystem.ApproachDirected("6880 0 3500", center, angles, 500))
|
|
{ Print("ERR HUNT FAILED test contact road"); m_HuntPhase = 3; return; }
|
|
PrintFormat("ERR HUNT CONTACT: point=%1 water=%2", center, ChimeraWorldUtils.TryGetWaterSurfaceSimple(world, center));
|
|
m_HuntPlan = new ERR_HunterOpeningPlan(center, 1000);
|
|
}
|
|
array<IEntity> players = {}; m_HuntPlan.Step(players); if (!m_HuntPlan.Done()) return;
|
|
if (!m_HuntPlan.Ready()) { Print("ERR HUNT FAILED opening"); m_HuntPhase = 3; return; }
|
|
m_HuntService = new ERR_HunterService(mode, null);
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
ERR_HunterVehicle unit = m_HuntService.ProbeHuntUnit(m_HuntPlan.Positions[i], m_HuntPlan.Angles[i], i);
|
|
if (!unit) { Print("ERR HUNT FAILED crew"); m_HuntPhase = 3; return; }
|
|
m_HuntUnits.Insert(unit); m_HuntStarts.Insert(unit.Entity.GetOrigin());
|
|
}
|
|
m_HuntPhase = 1; m_HuntNext = now + 10000; return;
|
|
}
|
|
if (m_HuntPhase == 1)
|
|
{
|
|
m_HuntAttack = new ERR_HunterAttack(); m_HuntAttack.ReportPosition = m_HuntPlan.Center; m_HuntAttack.Started = now;
|
|
m_HuntAttack.Forward = ERR_MountedCover.Approach(m_HuntUnits[0].Entity.GetOrigin(), m_HuntAttack.ReportPosition, "0 0 1");
|
|
array<vector> occupied = {};
|
|
for (int n = 0; n < m_HuntUnits.Count(); n++)
|
|
{
|
|
ERR_HunterTactics team = new ERR_HunterTactics(mode, m_HuntUnits[n], m_HuntAttack, n);
|
|
PrintFormat("ERR HUNT READY: role=%1 living=%2 crewValid=%3 members=%4", n, team.Living(), m_HuntUnits[n].CrewValid(mode), m_HuntUnits[n].Members.Count());
|
|
vector forward = ERR_MountedCover.Approach(m_HuntStarts[n], m_HuntAttack.ReportPosition, m_HuntAttack.Forward);
|
|
vector seed = ERR_Actors.Ground(m_HuntAttack.ReportPosition - forward * 260);
|
|
ERR_ConvoyPlacement placement = new ERR_ConvoyPlacement();
|
|
bool spawnFlat = placement.Clear(seed, ERR_ForceRules.Heading(seed, m_HuntAttack.ReportPosition, 0));
|
|
string spawnReason = placement.Diagnostic();
|
|
bool stageClear = placement.Clear(seed, ERR_ForceRules.Heading(seed, m_HuntAttack.ReportPosition, 0), 2.5);
|
|
PrintFormat("ERR HUNT SURFACE: role=%1 spawnFlat=%2 stageClear=%3 previous=%4 staging=%5", n, spawnFlat, stageClear, spawnReason, placement.Diagnostic());
|
|
bool planned = team.Plan(occupied);
|
|
bool ownSide = vector.Dot(team.Stage - m_HuntAttack.ReportPosition, m_HuntStarts[n] - m_HuntAttack.ReportPosition) > 0;
|
|
bool lane = ERR_MountedCover.ClearLane(m_HuntUnits[n].Entity, team.Stage, m_HuntAttack.ReportPosition);
|
|
PrintFormat("ERR HUNT PLAN: role=%1 planned=%2 ownSide=%3 lane=%4 start=%5 stage=%6", n, planned, ownSide, lane, m_HuntStarts[n], team.Stage);
|
|
if (!planned) continue;
|
|
occupied.Insert(team.Stage); m_HuntAttack.Teams.Insert(team);
|
|
bool began = team.ProbeHuntBegin(now); PrintFormat("ERR HUNT BEGIN: role=%1 began=%2", n, began);
|
|
}
|
|
m_HuntStarted = now; m_HuntPhase = 2; return;
|
|
}
|
|
foreach (ERR_HunterTactics active : m_HuntAttack.Teams) active.Tick(ERR_HQ.Cast(mode.Command()), now);
|
|
if (now - m_HuntStarted < 120000) return;
|
|
foreach (ERR_HunterTactics finalTeam : m_HuntAttack.Teams)
|
|
{
|
|
PrintFormat("ERR HUNT MOVEMENT: role=%1 moved=%2 state=%3 stopped=%4", finalTeam.Role, vector.DistanceXZ(finalTeam.Unit.Entity.GetOrigin(), m_HuntStarts[finalTeam.Role]), finalTeam.State, finalTeam.Stopped);
|
|
finalTeam.Stop();
|
|
}
|
|
Print("ERR HUNT COMPLETE"); m_HuntPhase = 3;
|
|
}
|
|
}
|