Integrate owned Intel rerolls, discovery feedback and fair HQ reports
This commit is contained in:
@@ -1,5 +1,19 @@
|
||||
// Native completion is separate from inventory contents: an unrelated transferred
|
||||
// folder must never acknowledge a pending spawn and permit a duplicate request.
|
||||
class ERR_IntelInsertCallback : ScriptedInventoryOperationCallback
|
||||
{
|
||||
bool Finished;
|
||||
bool Succeeded;
|
||||
protected void Finish(bool success) { if (!Finished) { Finished = true; Succeeded = success; } }
|
||||
protected override void OnComplete() { Finish(true); }
|
||||
protected override void OnFailed() { Finish(false); }
|
||||
protected override void OnAllComplete() { Finish(true); }
|
||||
protected override void OnAllFailed() { Finish(false); }
|
||||
}
|
||||
|
||||
class ERR_IntelRequest
|
||||
{
|
||||
ref ERR_IntelInsertCallback Operation;
|
||||
IEntity Actor;
|
||||
int Attempts;
|
||||
bool Accepted;
|
||||
@@ -11,11 +25,14 @@ class ERR_IntelService
|
||||
protected ERR_GameMode m_Mode;
|
||||
protected ref array<ref ERR_IntelRequest> m_Requests = {};
|
||||
protected ref set<IEntity> m_Rolled = new set<IEntity>();
|
||||
protected ref set<IEntity> m_Unsettled = new set<IEntity>();
|
||||
protected ref ERR_IntelReroll m_Reroll;
|
||||
protected bool m_Stopped;
|
||||
|
||||
void ERR_IntelService(ERR_GameMode mode) { m_Mode = mode; }
|
||||
void RegisterGroup(SCR_AIGroup group)
|
||||
{
|
||||
if (!Replication.IsServer() || !group) return;
|
||||
if (!Replication.IsServer() || m_Stopped || !group) return;
|
||||
array<AIAgent> members = {};
|
||||
group.GetAgents(members);
|
||||
foreach (AIAgent member : members)
|
||||
@@ -35,28 +52,85 @@ class ERR_IntelService
|
||||
|
||||
void Tick(float now)
|
||||
{
|
||||
if (!Replication.IsServer()) return;
|
||||
if (!Replication.IsServer() || m_Stopped) return;
|
||||
int budget = 8;
|
||||
for (int i = m_Requests.Count() - 1; i >= 0 && budget > 0; i--)
|
||||
{
|
||||
budget--;
|
||||
ERR_IntelRequest request = m_Requests[i];
|
||||
if (!ERR_Actors.Alive(request.Actor) || ERR_Actors.Player(request.Actor)) { m_Requests.Remove(i); continue; }
|
||||
if (!ERR_Actors.Alive(request.Actor) || ERR_Actors.Player(request.Actor))
|
||||
{
|
||||
if (request.Accepted) Unsettled(request.Actor);
|
||||
m_Requests.Remove(i); continue;
|
||||
}
|
||||
SCR_InventoryStorageManagerComponent inventory = SCR_InventoryStorageManagerComponent.Cast(request.Actor.FindComponent(SCR_InventoryStorageManagerComponent));
|
||||
array<IEntity> folders = {};
|
||||
if (inventory) ERR_DiscoveryService.Folders(inventory, folders);
|
||||
if (!folders.IsEmpty()) { m_Requests.Remove(i); continue; }
|
||||
if (request.Accepted && request.Operation && request.Operation.Finished)
|
||||
{
|
||||
m_Requests.Remove(i); continue;
|
||||
}
|
||||
if (!request.Accepted && !folders.IsEmpty()) { m_Requests.Remove(i); continue; }
|
||||
request.Attempts++;
|
||||
if (request.Attempts > 30)
|
||||
{
|
||||
Print("Rereintroduced [intel]: bounded assignment failed", LogLevel.WARNING);
|
||||
if (request.Accepted) Unsettled(request.Actor);
|
||||
m_Requests.Remove(i); continue;
|
||||
}
|
||||
if (inventory && !request.Accepted)
|
||||
request.Accepted = inventory.TrySpawnPrefabToStorage(ERR_Resources.IntelFolder(), purpose: EStoragePurpose.PURPOSE_ANY);
|
||||
{
|
||||
request.Operation = new ERR_IntelInsertCallback();
|
||||
request.Accepted = inventory.TrySpawnPrefabToStorage(ERR_Resources.IntelFolder(), purpose: EStoragePurpose.PURPOSE_ANY, cb: request.Operation);
|
||||
}
|
||||
}
|
||||
if (m_Reroll) m_Reroll.Tick();
|
||||
}
|
||||
|
||||
// Only the successor's registered enemy cohort is rerolled. Other AI, newly
|
||||
// registered groups and documents already carried away are outside this batch.
|
||||
bool BeginReroll()
|
||||
{
|
||||
if (!Replication.IsServer() || m_Stopped || !m_Mode || !m_Mode.Active() || !m_Mode.Discovery() || (m_Reroll && m_Reroll.Running())) return false;
|
||||
m_Reroll = new ERR_IntelReroll(m_Mode, this, m_Mode.Settings().Get("aiIntelChancePercent"));
|
||||
set<IEntity> cohort = new set<IEntity>();
|
||||
foreach (IEntity actor : m_Rolled)
|
||||
{
|
||||
if (!ERR_Actors.Alive(actor) || ERR_Actors.Player(actor)) continue;
|
||||
cohort.Insert(actor);
|
||||
m_Reroll.Add(actor);
|
||||
}
|
||||
for (int i = m_Requests.Count() - 1; i >= 0; i--)
|
||||
{
|
||||
ERR_IntelRequest request = m_Requests[i];
|
||||
// Native accepted spawns cannot be cancelled; retain their observation.
|
||||
if (cohort.Contains(request.Actor) && !request.Accepted) m_Requests.Remove(i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasPendingInsertion(IEntity actor)
|
||||
{
|
||||
foreach (ERR_IntelRequest request : m_Requests)
|
||||
if (request.Actor == actor && request.Accepted) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Unsettled(IEntity actor) { if (actor) m_Unsettled.Insert(actor); }
|
||||
bool Settled(IEntity actor)
|
||||
{
|
||||
// Unknown native completion remains quarantined until round teardown.
|
||||
// Seeing some folder is not proof that this particular spawn completed.
|
||||
return !m_Unsettled.Contains(actor);
|
||||
}
|
||||
|
||||
bool RerollRunning() { return m_Reroll && m_Reroll.Running(); }
|
||||
|
||||
string RerollStatus()
|
||||
{
|
||||
if (!m_Reroll) return "No intel reroll has been started this mission.";
|
||||
return m_Reroll.Status();
|
||||
}
|
||||
|
||||
#ifdef WORKBENCH
|
||||
// Observation only: a negative carrying decision still counts as its one roll.
|
||||
@@ -66,12 +140,20 @@ class ERR_IntelService
|
||||
}
|
||||
#endif
|
||||
|
||||
void Stop() { m_Requests.Clear(); m_Rolled.Clear(); }
|
||||
void Stop()
|
||||
{
|
||||
m_Stopped = true;
|
||||
if (m_Reroll) m_Reroll.Stop();
|
||||
m_Requests.Clear();
|
||||
m_Rolled.Clear();
|
||||
m_Unsettled.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
modded class ERR_GameMode
|
||||
{
|
||||
protected ref ERR_IntelService m_Intel;
|
||||
ERR_IntelService Intel() { return m_Intel; }
|
||||
protected override void EOnInit(IEntity owner)
|
||||
{
|
||||
super.EOnInit(owner);
|
||||
|
||||
Reference in New Issue
Block a user