Files
T
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

96 lines
4.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) m_HuntPlan = new ERR_HunterOpeningPlan(ERR_Actors.Ground("6880 0 3500"), 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());
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;
}
}