85 lines
2.6 KiB
C
85 lines
2.6 KiB
C
class ERR_IntelRequest
|
|
{
|
|
IEntity Actor;
|
|
int Attempts;
|
|
bool Accepted;
|
|
}
|
|
|
|
// Optional enemy inventory distribution. Core owns recovery and discovery.
|
|
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>();
|
|
|
|
void ERR_IntelService(ERR_GameMode mode) { m_Mode = mode; }
|
|
void RegisterGroup(SCR_AIGroup group)
|
|
{
|
|
if (!Replication.IsServer() || !group) return;
|
|
array<AIAgent> members = {};
|
|
group.GetAgents(members);
|
|
foreach (AIAgent member : members)
|
|
{
|
|
if (!member) continue;
|
|
IEntity actor = member.GetControlledEntity();
|
|
if (!ERR_Actors.Alive(actor) || ERR_Actors.Player(actor) || m_Rolled.Contains(actor)) continue;
|
|
m_Rolled.Insert(actor);
|
|
if (Math.RandomInt(0, 100) >= m_Mode.Settings().Get("aiIntelChancePercent")) continue;
|
|
if (m_Requests.Count() >= 256) continue;
|
|
ERR_IntelRequest request = new ERR_IntelRequest();
|
|
request.Actor = actor;
|
|
m_Requests.Insert(request);
|
|
}
|
|
}
|
|
|
|
|
|
void Tick(float now)
|
|
{
|
|
if (!Replication.IsServer()) 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; }
|
|
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; }
|
|
request.Attempts++;
|
|
if (request.Attempts > 30)
|
|
{
|
|
Print("Rereintroduced [intel]: bounded assignment failed", LogLevel.WARNING);
|
|
m_Requests.Remove(i); continue;
|
|
}
|
|
if (inventory && !request.Accepted)
|
|
request.Accepted = inventory.TrySpawnPrefabToStorage(ERR_Resources.IntelFolder(), purpose: EStoragePurpose.PURPOSE_ANY);
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef WORKBENCH
|
|
// Observation only: a negative carrying decision still counts as its one roll.
|
|
bool ERR_ProbeWasRolled(IEntity actor)
|
|
{
|
|
return Replication.IsServer() && actor && m_Rolled.Contains(actor);
|
|
}
|
|
#endif
|
|
|
|
void Stop() { m_Requests.Clear(); m_Rolled.Clear(); }
|
|
}
|
|
|
|
modded class ERR_GameMode
|
|
{
|
|
protected ref ERR_IntelService m_Intel;
|
|
protected override void EOnInit(IEntity owner)
|
|
{
|
|
super.EOnInit(owner);
|
|
if (SCR_Global.IsEditMode() || !Replication.IsServer()) return;
|
|
m_Intel = new ERR_IntelService(this);
|
|
OnGroup().Insert(m_Intel.RegisterGroup);
|
|
OnTick().Insert(m_Intel.Tick);
|
|
OnStop().Insert(m_Intel.Stop);
|
|
}
|
|
}
|