175 lines
7.0 KiB
C
175 lines
7.0 KiB
C
#ifdef WORKBENCH
|
|
class ERR_CrashProbeSites : ERR_CrashSites
|
|
{
|
|
protected int m_Captured;
|
|
protected int m_ExpectedStock;
|
|
protected bool m_DestroyedGrant;
|
|
bool WaitingCorrectly() { return !m_Stopped && m_Attempts==0 && Count()==0; }
|
|
protected override void Fill()
|
|
{
|
|
if(false)
|
|
{
|
|
m_DestroyedGrant=true;ERR_Actors.DeleteSpawned(m_Item);
|
|
Print("ERR CRASH: removed first issued rifle before insertion to test spent-grant handling");
|
|
}
|
|
super.Fill();
|
|
}
|
|
void ProofCamera()
|
|
{
|
|
vector point=At(0).Position;
|
|
vector camera[4];vector eye=point+"10 12 -16";
|
|
Math3D.DirectionAndUpMatrix(vector.Direction(eye,point+"0 2 0"),"0 1 0",camera);camera[3]=eye;
|
|
GetGame().GetCameraManager().SetCamera(m_Camera);
|
|
m_Camera.SetWorldTransform(camera);m_Camera.SetFOVDegree(65);m_Camera.SetDirty(true);m_Camera.ApplyTransform(0);
|
|
}
|
|
void ReportCamera() { Print("ERR CONTENT STAGE: 2");System.MakeScreenshot("$logs:crash-helicopter"); }
|
|
|
|
protected SCR_ManualCamera m_Camera;
|
|
void ERR_CrashProbeSites(ERR_GameMode mode) { m_Mode = mode; }
|
|
protected override bool Ready() { return true; }
|
|
protected override bool Survey(out vector point, out float heading)
|
|
{
|
|
if(Count()==0 && m_Attempts==1)
|
|
{
|
|
point="11180.619 0 11534.291";heading=0;float floor;
|
|
if(Separated(point) && m_Terrain.Clear(point,heading,11,0.6,floor,5)) {point=ERR_Actors.Ground(point);return true;}
|
|
}
|
|
return super.Survey(point,heading);
|
|
}
|
|
protected override bool Create(vector point, float heading)
|
|
{
|
|
m_HeliChance = 100;
|
|
|
|
bool created=super.Create(point, heading);
|
|
m_ExpectedStock=m_Loot.Count();
|
|
return created;
|
|
}
|
|
void Begin()
|
|
{
|
|
if(m_Mode.Settings().Get("crashLootMode")!=1){Fail("random mode not default");return;}
|
|
array<ResourceName> planned={};
|
|
foreach(int quality:{0,29,30,64,65,89,90,99})
|
|
{
|
|
ERR_CrashLoot.QualityPlan(quality,planned);
|
|
int count=planned.Count();
|
|
bool valid=count>=20 && count<=58;
|
|
if(quality<30)valid=count>=1 && count<=4;
|
|
else if(quality<65)valid=count>=2 && count<=4;
|
|
else if(quality<90)valid=count>=6 && count<=22;
|
|
if(!valid){Fail("quality plan boundaries");return;}
|
|
}
|
|
int selected;
|
|
if(!ERR_CommandArguments.Selection("crashLootMode","random",selected) || selected!=1){Fail("random command");return;}
|
|
if(!ERR_CommandArguments.Selection("crashLootMode","custom",selected) || selected!=0){Fail("custom command");return;}
|
|
m_Mode.Settings().Set("crashLootMode",1);
|
|
Print("ERR SMOKE PASS: default random, native poor-to-rich plans and mode command aliases");
|
|
m_Mode.Settings().Set("crashSiteCount",1);
|
|
m_Mode.Settings().Set("crashRifleCount",3); m_Mode.Settings().Set("crashMagazineCount",4);
|
|
m_Mode.Settings().Set("crashAntiAirChancePercent",100); m_Mode.Settings().Set("crashRocketChancePercent",100);
|
|
Start();
|
|
GetGame().GetCallqueue().CallLater(Check,1000,true);
|
|
}
|
|
void Fail(string text)
|
|
{
|
|
Print("ERR SMOKE FAIL: crash sites " + text,LogLevel.ERROR);
|
|
GetGame().GetCallqueue().Remove(Check); Stop();
|
|
}
|
|
void Check()
|
|
{
|
|
PrintFormat("ERR CRASH PROGRESS: count=%1 captured=%2 stopped=%3 consumed=%4 attempts=%5 item=%6",Count(),m_Captured,m_Stopped,m_Consumed,m_Attempts,m_ItemIndex);
|
|
Print("ERR CRASH TERRAIN: " + m_Terrain.Rejection());
|
|
if(m_Skipped>0){Fail("unexpected skipped slot");return;}
|
|
if(Count()<=m_Captured || !At(m_Captured).Ready)return;
|
|
ERR_CrashSite site=At(m_Captured);
|
|
if(!site.Wreck || Vehicle.Cast(site.Wreck) || site.Wreck.FindComponent(VehicleControllerComponent)){Fail("repairable vehicle");return;}
|
|
vector low, high;site.Wreck.GetBounds(low,high);
|
|
float bottom=site.Wreck.GetOrigin()[1]+low[1];
|
|
if(Math.AbsFloat(bottom-site.Position[1])>0.02){Fail("helicopter ground contact");return;}
|
|
ParticleEffectEntity smoke=ParticleEffectEntity.Cast(site.Smoke);
|
|
if(!smoke || !smoke.HasActiveParticles()){Fail("inactive smoke");return;}
|
|
if(site.Stock.Count()!=m_ExpectedStock){Fail("maximum crate stock count="+site.Stock.Count().ToString());return;}
|
|
int rifles, mags, rockets, aa;
|
|
foreach(IEntity item:site.Stock)
|
|
{
|
|
string path=item.GetPrefabData().GetPrefabName();
|
|
if(path.Contains("Rifle_"))rifles++;
|
|
if(path.Contains("Magazine_"))mags++;
|
|
if(path.Contains("Ammo_Rocket"))rockets++;
|
|
if(path.Contains("FIM92_Stinger.et"))
|
|
{
|
|
aa++;if(!ERR_EnemyLoadoutCatalog.Loaded(item)){Fail("unloaded AA");return;}
|
|
}
|
|
}
|
|
if(m_LootMode!=1 || m_ExpectedStock<1 || m_ExpectedStock>58){Fail("random loot dispatch");return;}
|
|
PrintFormat("ERR SMOKE PASS: crash %1 random crate: rifles=%2 magazines=%3 rockets=%4 AA=%5 static wreck and active smoke",m_Captured,rifles,mags,rockets,aa);
|
|
if(!m_Camera)
|
|
{
|
|
EntitySpawnParams params=new EntitySpawnParams();
|
|
m_Camera=SCR_ManualCamera.Cast(GetGame().SpawnEntity(SCR_ManualCamera,GetGame().GetWorld(),params));
|
|
GetGame().GetCameraManager().SetCamera(m_Camera);
|
|
}
|
|
vector camera[4];vector eye=site.Position+"18 10 22";
|
|
Math3D.DirectionAndUpMatrix(vector.Direction(eye,site.Position+"0 2 0"),"0 1 0",camera);camera[3]=eye;m_Camera.SetWorldTransform(camera);m_Camera.SetVerticalFOV(65);
|
|
GetGame().GetCallqueue().CallLater(ProofCamera,100,true);
|
|
GetGame().GetCallqueue().CallLater(ReportCamera,2000,false);
|
|
m_Captured++;
|
|
if(m_Captured==1)GetGame().GetCallqueue().CallLater(Done,5000,false);
|
|
}
|
|
void Done()
|
|
{
|
|
GetGame().GetCallqueue().Remove(Check);
|
|
GetGame().GetCallqueue().Remove(ProofCamera);
|
|
if(Count()!=1 || !m_Stopped){Fail("finite completion");return;}
|
|
ERR_AdminMenu.Open();
|
|
GetGame().GetCallqueue().CallLater(MenuDone,5000,false);
|
|
}
|
|
void MenuDone()
|
|
{
|
|
Print("ERR SMOKE COMPLETE: random crash-site loot");
|
|
}
|
|
}
|
|
modded class SCR_RespawnSystemComponent
|
|
{
|
|
override void UpdateLoadingPlaceholder(float dt)
|
|
{
|
|
super.UpdateLoadingPlaceholder(dt);
|
|
if(m_wLoadingPlaceholder)m_wLoadingPlaceholder.SetVisible(false);
|
|
}
|
|
}
|
|
modded class ERR_AdminMenu
|
|
{
|
|
override void OnMenuOpen()
|
|
{
|
|
super.OnMenuOpen(); ShowPage(ERR_AdminPage.CRASH_SITES);
|
|
if(!ERR_ProbeNavigation(ERR_AdminPage.CRASH_SITES))Print("ERR SMOKE FAIL: crash menu bounds",LogLevel.ERROR);
|
|
Print("ERR CONTENT STAGE: 4");
|
|
}
|
|
}
|
|
modded class ERR_GameMode
|
|
{
|
|
protected ref ERR_CrashProbeSites m_CrashProbe;
|
|
protected bool m_CrashActive;
|
|
protected override void StartScenario() {}
|
|
override bool Active() { return m_CrashActive; }
|
|
protected override void EOnInit(IEntity owner)
|
|
{
|
|
super.EOnInit(owner);
|
|
if(SCR_Global.IsEditMode() || !Replication.IsServer())return;
|
|
GetGame().GetCallqueue().CallLater(CrashBegin,7000,false);
|
|
}
|
|
void ActivateCrash()
|
|
{
|
|
if(!m_CrashProbe.WaitingCorrectly()) {Print("ERR SMOKE FAIL: preparation waiting",LogLevel.ERROR);return;}
|
|
ERR_Settings loaded=new ERR_Settings();
|
|
if(loaded.Get("crashLootMode")!=1 || loaded.Get("crashSiteCount")!=1 || loaded.Get("crashRifleCount")!=3 || loaded.Get("crashMagazineCount")!=4) {Print("ERR SMOKE FAIL: persisted crash settings",LogLevel.ERROR);return;}
|
|
Print("ERR SMOKE PASS: preparation waits, settings saved and reloaded");m_CrashActive=true;
|
|
}
|
|
void CrashBegin()
|
|
{
|
|
|
|
m_CrashProbe=new ERR_CrashProbeSites(this);m_CrashProbe.Begin();OnStop().Insert(m_CrashProbe.Stop);
|
|
GetGame().GetCallqueue().CallLater(ActivateCrash,3000,false);
|
|
}
|
|
}
|
|
#endif
|