Files
Viano-Core/tests/clientless/test_elevated_flight.py
T

68 lines
3.9 KiB
Python

"""Exercise elevated landings with production geometry and solid overhangs."""
from pathlib import Path
import subprocess,tempfile
root=Path(__file__).resolve().parents[2]
harness=r'''
#include "ClientlessFlightPath.h"
#include <cassert>
#include <iostream>
using namespace ClientlessFlightPath;
// Tower platform at z=200: collision surface is thin, open air beneath its lip.
auto terrain=[](float x,float y){return Surface{std::hypot(x,y)<20?200.f:0.f,500,true,0.f};};
auto rays=[](Point const&a,Point const&b){
for(int i=0;i<=200;++i){auto p=Mix(a,b,i/200.f);
if(std::hypot(p.X,p.Y)<20 && p.Z>=199.8f && p.Z<=200.2f)return false;
if(std::hypot(p.X,p.Y)<5 && p.Z<200)return false;
}return true;
};
void run(Point p,bool escapeExpected){
Settings cfg;Memory m;m.Departed=true;Point goal{12,0,200};
bool climbed=false,escaped=false,crossed=false,descended=false;unsigned steps=0;
SharedTrail trail;trail.LandingReady=true;trail.Landing=goal;
for(;steps<100 && Distance(p,goal)>.1f;++steps){
auto n=Next(p,goal,cfg,m,terrain,rays);assert(n.Valid);
assert(Corridor(p,n.Next,goal,cfg,terrain,rays,false,n.UnderOverhang));
if(m.Elevated==Memory::ElevatedPhase::Climb){assert(Horizontal(p,n.Next)<.01f);climbed=true;}
if(n.UnderOverhang){assert(std::fabs(p.Z-n.Next.Z)<.01f);escaped=true;}
if(m.Elevated==Memory::ElevatedPhase::Cross){assert(n.Next.Z>=209.9f);crossed=true;}
if(m.Elevated==Memory::ElevatedPhase::Descend){assert(Horizontal(p,n.Next)<.01f);descended=true;}
trail.Points.push_back(n.Next);trail.UnderOverhang.push_back(n.UnderOverhang);
std::size_t index=trail.Points.size()-1;
auto shared=FollowTrail(p,goal,cfg,trail,index,terrain,rays);
assert(shared.Step.Valid && shared.Step.UnderOverhang==n.UnderOverhang);
p=n.Next;
}
assert(Distance(p,goal)<.1f && steps<100 && climbed && crossed && descended);
assert(!escapeExpected || escaped);
}
int main(){
run({90,0,80},false); // high target: climb before approaching the wall
run({12,0,100},true); // directly UNDER platform: move out before rising
run({25,0,190},false); // only 10 yards high, slope budget is 7.8: no fixed threshold
// Reachable diagonal approach intersects platform underside. The collision
// query, rather than a height threshold, must trigger the elevated manoeuvre.
Memory m;m.Departed=true;Settings cfg;
auto n=Next({40,0,190},{12,0,200},cfg,m,terrain,rays);
assert(n.Valid && m.Elevated!=Memory::ElevatedPhase::None);
// A blocked ascent/crossing must fail, never tunnel through a platform.
auto blocked=[](Point const&,Point const&){return false;};
Memory b;b.Departed=true;assert(!Next({12,0,100},{12,0,200},cfg,b,terrain,blocked).Valid);
// The escape exception must not tunnel through bare terrain or water.
auto hill=[](float,float){return Surface{200.f,500,true,200.f};};
assert(!Corridor({12,0,100},{80,0,100},{12,0,200},cfg,hill,rays,false,true));
// A low flight ceiling cannot be ignored by the vertical exception.
auto low=[](float x,float y){return Surface{std::hypot(x,y)<20?200.f:0.f,213,true,0.f};};
Memory c;c.Departed=true;assert(!Next({90,0,80},{12,0,200},cfg,c,low,rays).Valid);
// Ordinary small height changes still use the normal slope.
auto gentle=[](float x,float){return Surface{x>99?5.f:0.f,500,true};};
auto clear=[](Point const&,Point const&){return true;};
Memory d;d.Departed=true;auto normal=Next({0,0,10},{100,0,5},cfg,d,gentle,clear);
assert(normal.Valid && d.Elevated==Memory::ElevatedPhase::None);
std::cout<<"Elevated flight: slope budget, open column, solid overhang escape, above-platform crossing, touchdown, shared trail, blocked/ceiling checks PASS\n";
}
'''
with tempfile.TemporaryDirectory(prefix='vcore-elevated-flight-') as folder:
cpp=Path(folder)/'test.cpp';binary=Path(folder)/'test';cpp.write_text(harness)
subprocess.run(['c++','-std=c++17','-I',str(root/'src/server/game/World'),str(cpp),'-o',str(binary)],check=True)
subprocess.run([str(binary)],check=True)