Improve AI garrisons, player recovery and mission administration
This commit is contained in:
@@ -9,9 +9,9 @@ def adapt(s):
|
||||
s=s.replace('protected ','').replace('out vector position','vector& position').replace('null','nullptr')
|
||||
s=re.sub(r'array<IEntity> (\w+) = \{\};',r'Array<IEntity> \1;',s)
|
||||
s=s.replace('foreach (IEntity survivor : survivors)','for (IEntity survivor : survivors)')
|
||||
for n in ('ERR_Phase','ERR_Actors','SCR_FactionManager','Replication','ERR_GameMode','ERR_ObserverReason','RplComponent','CompartmentAccessComponent'):
|
||||
for n in ('ERR_Phase','ERR_Actors','SCR_FactionManager','Replication','ERR_GameMode','ERR_ObserverReason','RplComponent','CompartmentAccessComponent','ERR_ObserverRules'):
|
||||
s=s.replace(n+'.',n+'::')
|
||||
for n in ('mode','manager','life','component','target'):
|
||||
for n in ('mode','manager','life','component','target','body'):
|
||||
s=s.replace(n+'.',n+'->')
|
||||
s=s.replace('ERR_GameMode mode','ERR_GameMode* mode').replace('PlayerManager manager','PlayerManager* manager').replace('RplComponent component','RplComponent* component')
|
||||
s=s.replace('GetGame().','GetGame()->').replace('Players().','Players()->')
|
||||
@@ -35,8 +35,11 @@ struct PlayerManager{std::map<int,IEntity> controlled;int GetPlayerIdFromControl
|
||||
struct Game{PlayerManager* manager;PlayerManager* GetPlayerManager(){return manager;}};Game* game_;Game* GetGame(){return game_;}
|
||||
namespace Replication{bool server=true;int bumps=0;bool IsServer(){return server;}void BumpMe(){bumps++;}}
|
||||
namespace ERR_Phase{const int PRISON=1;}
|
||||
namespace ERR_ObserverReason{const int NONE=0;}
|
||||
namespace ERR_Actors{bool Alive(IEntity a){return a&&a->alive;}void Players(Array<IEntity>& out,bool conscious=false){out.clear();for(auto& p:GetGame()->manager->controlled){IEntity a=p.second;if(Alive(a)&&(!conscious||a->conscious))out.push_back(a);}}}
|
||||
namespace ERR_ObserverReason{const int NONE=0,UNCONSCIOUS=4;}
|
||||
namespace ERR_ObserverRules{
|
||||
'''+adapt(body(core/'ERR_Observer.c','static bool Casualty('))+r'''
|
||||
}
|
||||
namespace ERR_Actors{bool Alive(IEntity a){return a&&a->alive;}bool CanFight(IEntity a){return Alive(a)&&a->conscious;}void Players(Array<IEntity>& out,bool conscious=false){out.clear();for(auto& p:GetGame()->manager->controlled){IEntity a=p.second;if(Alive(a)&&(!conscious||a->conscious))out.push_back(a);}}}
|
||||
namespace SCR_FactionManager{int SGetFaction(IEntity a){return a?a->faction:0;}}
|
||||
namespace CompartmentAccessComponent{IEntity GetVehicleIn(IEntity a){return a?a->vehicle:nullptr;}}
|
||||
struct Roster{std::map<int,ERR_PlayerLife> lives;ERR_PlayerLife Get(int id){auto p=lives.find(id);return p==lives.end()?nullptr:p->second;}
|
||||
@@ -77,6 +80,16 @@ int main(){
|
||||
Spawn mixed;assert(mixed.SpawnPosition(&mode,p)&&p==other.origin&&mixed.m_Placement.last==&other);
|
||||
Observer mixedFollow;mixedFollow.m_ERRServerObserved=&replacement;mixedFollow.ERR_UpdateObserverServer();assert(mixedFollow.m_ERRServerObserved==&other&&mixedFollow.releases==1);
|
||||
manager.controlled[1]=&original;Observer cycling;cycling.ERR_UpdateObserverServer();assert(cycling.m_ERRServerObserved==&original);cycling.ERR_UpdateObserverServer(1);assert(cycling.m_ERRServerObserved==&other);cycling.ERR_UpdateObserverServer(1);assert(cycling.m_ERRServerObserved==&original);cycling.ERR_UpdateObserverServer(-1);assert(cycling.m_ERRServerObserved==&other);
|
||||
// Unconscious player keeps possession and follows only conscious canonical teammates.
|
||||
Observer casualty;casualty.own=&original;casualty.m_ERRObserverReason=0;original.conscious=false;
|
||||
casualty.ERR_UpdateObserverServer();assert(casualty.m_ERRObserverReason==4&&casualty.m_ERRServerObserved==&other&&casualty.own==&original);
|
||||
other.conscious=false;casualty.ERR_UpdateObserverServer();assert(!casualty.m_ERRServerObserved&&casualty.m_ERRObserverAnchor==original.origin);
|
||||
other.conscious=true;casualty.ERR_UpdateObserverServer();assert(casualty.m_ERRServerObserved==&other);
|
||||
original.conscious=true;casualty.ERR_UpdateObserverServer();assert(casualty.m_ERRObserverReason==0&&!casualty.m_ERRServerObserved&&casualty.own==&original);
|
||||
original.conscious=false;life.Connected=false;casualty.ERR_UpdateObserverServer();assert(casualty.m_ERRObserverReason==0);
|
||||
life.Connected=true;casualty.ERR_UpdateObserverServer();assert(casualty.m_ERRObserverReason==4);
|
||||
mode.active=false;casualty.ERR_UpdateObserverServer();assert(casualty.m_ERRObserverReason==0&&!casualty.m_ERRServerObserved);
|
||||
mode.active=true;original.conscious=true;
|
||||
// Existing terrain rejection and prison-phase placement stay delegated.
|
||||
Spawn blocked;blocked.m_Placement.clear=false;assert(blocked.SpawnPosition(&mode,p)&&p==0&&blocked.m_Placement.nearCalls==2);
|
||||
mode.phase=ERR_Phase::PRISON;Spawn prison;assert(prison.SpawnPosition(&mode,p)&&p==0&&prison.m_Placement.nearCalls==0);
|
||||
|
||||
Reference in New Issue
Block a user