Enable finite automatic convoy startup and scoped gunner skill
This commit is contained in:
@@ -17,7 +17,7 @@ for cls in ('ERR_GameMode','SCR_AIGroup','SCR_AIGroupUtilityComponent','IEntity'
|
||||
code=re.sub(r'\b'+cls+r' ([a-zA-Z_]\w*)',cls+r'* \1',code)
|
||||
for obj in ('mode','group','utility','Actor','Group','Combat','Optics','Operation','item','weapons','inventory'):
|
||||
code=code.replace(obj+'.',obj+'->')
|
||||
for cls in ('Replication','SCR_Global','ERR_GameMode','ERR_Actors','ERR_EnemyEquipmentRules','EAISkill','ERR_HQ','Math','EStoragePurpose'):
|
||||
for cls in ('Replication','SCR_Global','ERR_GameMode','ERR_Actors','ERR_EnemyEquipmentRules','ERR_EnemyGunnerSkill','EAISkill','ERR_HQ','Math','EStoragePurpose'):
|
||||
code=code.replace(cls+'.',cls+'::')
|
||||
code=code.replace('GetPrefabData().','GetPrefabData()->').replace('Settings().','Settings()->').replace('foreach (','for (').replace('null','nullptr').replace('super.','NativeCombat::')
|
||||
code=code.replace('new ERR_EnemyEquipmentCallback()','NewOperation()')
|
||||
@@ -67,6 +67,11 @@ struct NativeCombat {
|
||||
IEntity* GetOwner(){return owner;}EAISkill GetAISkill(){return skill;}
|
||||
virtual void SetAISkill(EAISkill value){skill=value;}virtual void ResetAISkill(){skill=EAISkill::ROOKIE;}
|
||||
};
|
||||
namespace ERR_EnemyGunnerSkill {
|
||||
bool CapturedGroup(ERR_GameMode*,SCR_AIGroup*){return false;}
|
||||
bool OriginalGunner(ERR_GameMode*,SCR_AIGroup*,IEntity*){return false;}
|
||||
EAISkill Profile(EAISkill requested,bool){return requested<EAISkill::EXPERT?EAISkill::EXPERT:requested;}
|
||||
}
|
||||
struct ERR_EnemyOptics{int stops=0;void Stop(){stops++;}};
|
||||
''' + code + r'''
|
||||
std::vector<std::unique_ptr<ERR_EnemyEquipmentCallback>> operations;
|
||||
@@ -151,7 +156,7 @@ namespace Replication {bool IsServer(){return true;}}
|
||||
template<typename T> struct Array:std::vector<T>{int Count(){return this->size();}void Insert(T value){this->push_back(value);}void Clear(){this->clear();}};
|
||||
struct SCR_AIGroup;
|
||||
struct ERR_GameMode{static inline ERR_GameMode* current=nullptr;bool active=true;bool Active(){return active;}static ERR_GameMode* Get(){return current;}};
|
||||
struct SCR_AICombatComponent{int binds=0;void ERR_BindEnemySkill(ERR_GameMode*,SCR_AIGroup*){binds++;}};
|
||||
struct SCR_AICombatComponent{int binds=0,refreshes=0;void ERR_BindEnemySkill(ERR_GameMode*,SCR_AIGroup*){binds++;}void ERR_RefreshEnemySkill(){refreshes++;}};
|
||||
struct IEntity{SCR_AICombatComponent* combat=nullptr;bool eligible=true;};
|
||||
struct AIAgent{IEntity* actor=nullptr;IEntity* GetControlledEntity(){return actor;}};
|
||||
struct SCR_AIGroup{Array<AIAgent*> agents;void GetAgents(Array<AIAgent*>& out){out=agents;}};
|
||||
@@ -172,13 +177,13 @@ int main(){
|
||||
ERR_GameMode mode;ERR_GameMode::current=&mode;ERR_EnemyEquipment service(&mode);
|
||||
SCR_AIGroup group;IEntity soldier;SCR_AICombatComponent combat;soldier.combat=&combat;AIAgent agent;agent.actor=&soldier;group.agents.Insert(&agent);
|
||||
service.RegisterGroup(&group);service.RegisterGroup(&group);assert(service.m_Groups.Count()==1);
|
||||
service.Tick(0);assert(service.m_Entries.Count()==0);service.Tick(3000);assert(service.m_Entries.Count()==1&&combat.binds==1);
|
||||
service.Tick(0);assert(service.m_Entries.Count()==0);service.Tick(3000);assert(service.m_Entries.Count()==1&&combat.binds==1&&combat.refreshes==1);
|
||||
auto entry=service.m_Entries[0];assert(entry->Optics&&entry->Optics->actor==&soldier&&entry->Optics->group==&group);
|
||||
assert(entry->Complete&&entry->Optics->checks==1); // Stinger is already complete; optics has its own startup completion.
|
||||
service.Tick(3001);assert(entry->checks==1&&entry->Optics->checks==1);
|
||||
service.Tick(6000);assert(entry->checks==2&&entry->Optics->checks==2&&combat.binds==1);
|
||||
assert(entry->Complete&&entry->Optics->checks==1&&combat.refreshes==1); // Stinger is already complete; optics has its own startup completion.
|
||||
service.Tick(3001);assert(entry->checks==1&&entry->Optics->checks==1&&combat.refreshes==1);
|
||||
service.Tick(6000);assert(entry->checks==2&&entry->Optics->checks==2&&combat.binds==1&&combat.refreshes==2);
|
||||
service.UnregisterGroup(&group);service.Tick(9000);assert(service.m_Entries[0]->Released&&service.m_Entries[0]->checks==2&&entry->Optics->checks==2&&entry->Optics->stops==1);
|
||||
service.RegisterGroup(&group);service.Tick(12000);assert(service.m_Entries.Count()==1&&combat.binds==1);
|
||||
service.RegisterGroup(&group);service.Tick(12000);assert(service.m_Entries.Count()==1&&combat.binds==1&&combat.refreshes==2);
|
||||
service.Stop();service.RegisterGroup(&group);service.Tick(50000);assert(service.m_Groups.Count()==0&&service.m_Stopped);
|
||||
ERR_EnemyEquipment delayed(&mode);SCR_AIGroup late;delayed.RegisterGroup(&late);delayed.Tick(3000);late.agents.Insert(&agent);delayed.Tick(6000);assert(delayed.m_Entries.Count()==1);
|
||||
ERR_EnemyEquipment expired(&mode);SCR_AIGroup empty;expired.RegisterGroup(&empty);for(int i=1;i<=6;i++){expired.Tick(i*3000);}empty.agents.Insert(&agent);expired.Tick(21000);assert(expired.m_Entries.Count()==0);
|
||||
|
||||
Reference in New Issue
Block a user