Files
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

74 lines
4.7 KiB
Plaintext

--- a/addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelDiscoveryFeedback.c
+++ b/addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelDiscoveryFeedback.c
@@ -5,6 +5,7 @@
protected ref map<ERR_LocationComponent, int> m_ERRIntelSeen = new map<ERR_LocationComponent, int>();
protected ref map<ERR_LocationComponent, int> m_ERRIntelPending = new map<ERR_LocationComponent, int>();
protected float m_ERRIntelMessageAt;
+ protected float m_ERRIntelExhaustedAt;
protected bool m_ERRIntelFeedbackStopped;
protected int m_ERRIntelMessageSequence;
protected int m_ERRIntelReceivedSequence;
@@ -63,6 +64,11 @@
void ERR_IntelExhausted(bool duplicate = false)
{
if (!Replication.IsServer() || m_ERRIntelFeedbackStopped || !Active()) return;
+ // Recover scans a whole inventory; surplus folders share one team notice.
+ // Keep useful new discoveries on their independent coalescing schedule.
+ float now = GetWorld().GetWorldTime();
+ if (now < m_ERRIntelExhaustedAt) return;
+ m_ERRIntelExhaustedAt = now + 5000;
string message = "Every known location has already been identified. This intel doesn't help us.";
if (duplicate) message = "This document concerns a location we have already identified.";
m_ERRIntelMessageSequence++;
@@ -75,6 +81,7 @@
m_ERRIntelPending.Clear();
m_ERRIntelSeen.Clear();
m_ERRIntelMessageAt = 0;
+ m_ERRIntelExhaustedAt = 0;
OnLocationDiscovered().Remove(ERR_QueueDiscoveryFeedback);
OnTick().Remove(ERR_FlushDiscoveryFeedback);
}
--- a/tests/test_intel_discovery_feedback.py
+++ b/tests/test_intel_discovery_feedback.py
@@ -1,6 +1,8 @@
"""Execute production feedback queue/delivery bodies with fake engine boundaries."""
from policy_harness import ROOT, body, run
-P=ROOT/'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelDiscoveryFeedback.c'
+from pathlib import Path
+import os
+P=Path(os.environ.get('ERR_INTEL_FEEDBACK_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelDiscoveryFeedback.c'))
source=P.read_text()
def cpp(s):
s=s.replace('protected ', '').replace('static ', '')
@@ -42,7 +44,7 @@
static ERR_GameMode* current;static ERR_GameMode* Get(){return current;}
bool active=true;int phase=ERR_Phase::RADIO_SEARCH;bool Active(){return active;}int Phase(){return phase;}World* GetWorld(){return &world;}
Map<ERR_LocationComponent*,int> m_ERRIntelSeen,m_ERRIntelPending;
- float m_ERRIntelMessageAt=0;bool m_ERRIntelFeedbackStopped=false;int m_ERRIntelMessageSequence=0,m_ERRIntelReceivedSequence=0;
+ float m_ERRIntelMessageAt=0,m_ERRIntelExhaustedAt=0;bool m_ERRIntelFeedbackStopped=false;int m_ERRIntelMessageSequence=0,m_ERRIntelReceivedSequence=0;
Events discovered,tick;Events& OnLocationDiscovered(){return discovered;}Events& OnTick(){return tick;}
int rpcCount=0;void Rpc(int sequence,string message){rpcCount++;ERR_ReceiveDiscoveryFeedback(sequence,message);}
'''+methods+r'''
@@ -79,6 +81,21 @@
assert(ERR_IntelDiscoveryText::Type(ERR_LocationKind::MORTAR,"any")=="mortar site");
ERR_GameMode::current=&m;m.ERR_IntelExhausted();assert(SCR_ChatComponent::messages.back()=="Every known location has already been identified. This intel doesn't help us.");
assert(ERR_IntelDiscoveryText::Message(0,0,"secret").empty());assert(ERR_IntelDiscoveryText::Message(1,0,"")=="Hey! A location was identified in the intel!");
+ // Recovering a stack of spent-topic folders performs one exhaustion broadcast,
+ // not one chat line/RPC per physical document. Both variants share the budget.
+ ERR_GameMode surplus;ERR_GameMode::current=&surplus;world.time=10000;
+ for(int i=0;i<20;i++)surplus.ERR_IntelExhausted(i%2==0);
+ assert(surplus.rpcCount==1&&surplus.m_ERRIntelMessageSequence==1);
+ // Actual new discovery still follows its own coalescing window immediately.
+ world.time=10000;ERR_LocationComponent fresh;surplus.ERR_QueueDiscoveryFeedback(&fresh,0,1);
+ surplus.ERR_FlushDiscoveryFeedback(11500);assert(surplus.rpcCount==2);
+ assert(SCR_ChatComponent::messages.back()=="New location marked. Type unknown.");
+ world.time=14999;surplus.ERR_IntelExhausted();assert(surplus.rpcCount==2);
+ world.time=15000;surplus.ERR_IntelExhausted();assert(surplus.rpcCount==3&&surplus.m_ERRIntelMessageSequence==3);
+ world.time=20000;Replication::server=false;surplus.ERR_IntelExhausted();assert(surplus.rpcCount==3);Replication::server=true;
+ surplus.ERR_StopDiscoveryFeedback();surplus.ERR_IntelExhausted();assert(surplus.rpcCount==3);
+ ERR_GameMode freshRound;ERR_GameMode::current=&freshRound;world.time=0;freshRound.ERR_IntelExhausted();assert(freshRound.rpcCount==1);
+
}
''')
for required in ('OnLocationDiscovered().Insert(ERR_QueueDiscoveryFeedback)', 'OnTick().Insert(ERR_FlushDiscoveryFeedback)', 'OnStop().Insert(ERR_StopDiscoveryFeedback)', '[RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]'):