Bundle mission speech with an admin mute option and fix live audio downloads

This commit is contained in:
2026-10-15 16:53:39 +02:00
parent 07c4d70de5
commit 009b2fb591
181 changed files with 19248 additions and 103 deletions
+8 -1
View File
@@ -6,6 +6,7 @@ rules=body(p,'static string Text(')+body(p,'static bool Near(')
names=re.findall(r'case ECommunicationType\.(\w+)',rules)
rules=rules.replace('ECommunicationType.','ECommunicationType::')
s='\n'.join(body(p,x) for x in ['bool Current()', 'void Prepared(', 'bool Speak(', 'bool ReadyClip(', 'bool Clip('])
s=s.replace('ERR_BakedSpeech.', 'ERR_BakedSpeech::')
s=s.replace('out string url','string& url').replace('array<SCR_PlayerController> listeners,','Array<SCR_PlayerController*> listeners,')
s=s.replace('protected ','').replace('null','nullptr').replace('ref ','')
for typ in ['IEntity','SCR_AITalkRequest','VoNComponent','RplComponent','SCR_PlayerController','ERR_SpeechService']:
@@ -34,6 +35,7 @@ namespace ECommunicationType{enum{'''+','.join(names)+r''',REPORT_CONTACT=100,RE
struct ERR_SoldierSpeechRules{
'''+rules+r'''
};
bool baked=false;struct ERR_BakedSpeech{static string Soldier(int kind){return baked&&!ERR_SoldierSpeechRules::Text(kind).IsEmpty()?"baked:line":"";}};
namespace ECommMethod{enum{DIRECT,RADIO};}
struct VoNComponent{int method=ECommMethod::DIRECT;int GetCommMethod(){return method;}};
struct SCR_AITalkRequest{int m_eCommType=ECommunicationType::REPORT_MOVING;};
@@ -43,7 +45,7 @@ namespace ERR_Actors{bool CanFight(IEntity*a){return a&&a->fit;}bool Player(IEnt
float Distance(float a,float b){return std::abs(a-b);}
struct ERR_SoldierSpeechPreparation{void*Server=nullptr;int Kind=0;};
struct ERR_SpeechService{bool ready=true,idle=true,accept=true;int requests=0;string endpoint="bridge",text;bool Ready(){return ready;}string CacheNamespace(){return endpoint;}bool IdleFor(float n){assert(n==65000);return idle;}bool Request(string t,ERR_SoldierSpeechPreparation*){requests++;text=t;return accept;}};
struct ERR_GameMode{static ERR_GameMode*live;bool active=true;ERR_SpeechService voice;bool Active(){return active;}auto ERR_Speech(){return &voice;}static auto Get(){return live;}};ERR_GameMode*ERR_GameMode::live=nullptr;
struct ERR_GameMode{static ERR_GameMode*live;bool active=true,recordings=true;bool ERR_RecordingsEnabled(){return recordings;}ERR_SpeechService voice;bool Active(){return active;}auto ERR_Speech(){return &voice;}static auto Get(){return live;}};ERR_GameMode*ERR_GameMode::live=nullptr;
struct SCR_PlayerController{IEntity*body=nullptr;bool ready=false;int preparations=0,delivered=0;IEntity*GetControlledEntity(){return body;}bool ERR_SoldierClipReady(ERR_GameMode*,int,string){return ready;}void ERR_PrepareSoldierClip(int,string){preparations++;}void ERR_DeliverSoldierLine(int,string,int){delivered++;}};
struct Manager{Array<SCR_PlayerController*>controllers;void GetPlayers(Array<int>&ids){for(int i=0;i<controllers.Count();i++)ids.Insert(i);}auto GetPlayerController(int i){return controllers[i];}};
struct Game{Manager players;auto GetPlayerManager(){return &players;}}game;auto GetGame(){return &game;}
@@ -55,6 +57,11 @@ struct Fixture{ERR_GameMode mode;Server server;IEntity actor,one,two;SCR_PlayerC
bool Speak(){return server.Speak(&actor,&request,&von);}void Prepared(){server.Prepared(request.m_eCommType,"clip");}
};
int main(){
{Fixture f;f.mode.recordings=false;assert(!f.Speak()&&f.mode.voice.requests==0&&f.c1.preparations==0&&f.c1.delivered==0);}
{Fixture f;baked=true;f.server.m_Endpoint="baked:speech-v1";f.mode.voice.ready=false;
assert(!f.Speak()&&f.mode.voice.requests==0&&f.c1.preparations==1);
f.c1.ready=true;f.c2.ready=true;assert(f.Speak()&&f.c1.delivered==1&&f.mode.voice.requests==0);baked=false;
}
assert(!ERR_SoldierSpeechRules::Near(-1)&&ERR_SoldierSpeechRules::Near(80)&&!ERR_SoldierSpeechRules::Near(80.1f)&&!ERR_SoldierSpeechRules::Near(std::numeric_limits<float>::quiet_NaN()));
assert(ERR_SoldierSpeechRules::Text(100).IsEmpty());
{Fixture f;assert(!f.Speak()&&f.mode.voice.requests==1);assert(!f.Speak()&&f.mode.voice.requests==1);f.Prepared();assert(!f.Speak()&&f.c1.preparations==1&&f.c2.preparations==1);f.c1.ready=true;assert(!f.Speak()&&!f.c1.delivered&&!f.c2.delivered);f.c2.ready=true;assert(f.Speak()&&f.c1.delivered==1&&f.c2.delivered==1);assert(f.server.Clip(f.request.m_eCommType,"clip")&&!f.server.Clip(f.request.m_eCommType,"other"));}