本文整理汇总了C++中GetHeadingFromVector函数的典型用法代码示例。如果您正苦于以下问题:C++ GetHeadingFromVector函数的具体用法?C++ GetHeadingFromVector怎么用?C++ GetHeadingFromVector使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了GetHeadingFromVector函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: tempTargetPos
bool CWeapon::TryTargetRotate(CUnit* unit, bool userTarget){
float3 tempTargetPos(helper->GetUnitErrorPos(unit,owner->allyteam));
tempTargetPos+=errorVector*(weaponDef->targetMoveError*30*unit->speed.Length()*(1.0f-owner->limExperience));
float appHeight=ground->GetApproximateHeight(tempTargetPos.x,tempTargetPos.z)+2;
if(tempTargetPos.y < appHeight){
tempTargetPos.y=appHeight;
}
short weaponHeadding = GetHeadingFromVector(mainDir.x, mainDir.z);
short enemyHeadding = GetHeadingFromVector(
tempTargetPos.x - weaponPos.x, tempTargetPos.z - weaponPos.z);
return TryTargetHeading(enemyHeadding - weaponHeadding, tempTargetPos,userTarget, unit);
}
示例2: GetHeadingFromVector
void CFarTextureHandler::DrawFarTexture(const CSolidObject* obj, CVertexArray* va)
{
const int farTextureNum = cache[obj->team][obj->model->id];
// not found in the atlas
if (farTextureNum <= 0)
return;
const float3 interPos = obj->drawPos + UpVector * obj->model->height * 0.5f;
// indicates the orientation to draw
static const int USHRT_MAX_ = (1 << 16);
const int orient_step = USHRT_MAX_ / numOrientations;
int orient = GetHeadingFromVector(-camera->forward.x, -camera->forward.z) - obj->heading;
orient += USHRT_MAX_; // make it positive only
orient += (orient_step >> 1); // we want that frontdir is from -orient_step/2 upto orient_step/2
orient %= USHRT_MAX_; // we have an angle so it's periodical
orient /= orient_step; // get the final direction index
const float iconSizeX = float(this->iconSizeX) / texSizeX;
const float iconSizeY = float(this->iconSizeY) / texSizeY;
const float2 texcoords = GetTextureCoords(farTextureNum - 1, orient);
const float3 curad = camera->up * obj->model->radius;
const float3 crrad = camera->right * obj->model->radius;
va->AddVertexQT(interPos - curad + crrad, texcoords.x, texcoords.y );
va->AddVertexQT(interPos + curad + crrad, texcoords.x, texcoords.y + iconSizeY);
va->AddVertexQT(interPos + curad - crrad, texcoords.x + iconSizeX, texcoords.y + iconSizeY);
va->AddVertexQT(interPos - curad - crrad, texcoords.x + iconSizeX, texcoords.y );
}
示例3: glDisable
void HUDDrawer::DrawCameraDirectionArrow(const CUnit* unit)
{
glDisable(GL_TEXTURE_2D);
if (unit->moveType->useHeading) {
glPushMatrix();
glTranslatef(-0.8f, -0.4f, 0.0f);
glScalef(0.33f, 0.33f * globalRendering->aspectRatio, 0.33f);
glRotatef(
GetHeadingFromVector(camera->forward.x, camera->forward.z) * 180.0f / 32768 + 180,
0.0f, 0.0f, 1.0f
);
glScalef(0.4f, 0.4f, 0.3f);
glColor4f(0.4f, 0.4f, 1.0f, 0.6f);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(-0.2f, -0.3f);
glVertex2f(-0.2f, 0.3f);
glVertex2f( 0.0f, 0.5f);
glVertex2f( 0.2f, 0.3f);
glVertex2f( 0.2f, -0.3f);
glVertex2f(-0.2f, -0.3f);
glEnd();
glPopMatrix();
}
}
示例4: DeleteDeathDependence
void CUnit::FinishedBuilding(void)
{
beingBuilt = false;
buildProgress = 1.0f;
if (soloBuilder) {
DeleteDeathDependence(soloBuilder);
soloBuilder = NULL;
}
if (!(immobile && (mass == 100000))) {
mass = unitDef->mass; //set this now so that the unit is harder to move during build
}
ChangeLos(realLosRadius,realAirLosRadius);
if (unitDef->startCloaked) {
wantCloak = true;
isCloaked = true;
}
if (unitDef->windGenerator>0) {
if (wind.curStrength > unitDef->windGenerator) {
cob->Call(COBFN_SetSpeed, (int)(unitDef->windGenerator * 3000.0f));
} else {
cob->Call(COBFN_SetSpeed, (int)(wind.curStrength * 3000.0f));
}
cob->Call(COBFN_SetDirection, (int)GetHeadingFromVector(-wind.curDir.x, -wind.curDir.z));
}
if (unitDef->activateWhenBuilt) {
Activate();
}
gs->Team(team)->metalStorage += unitDef->metalStorage;
gs->Team(team)->energyStorage += unitDef->energyStorage;
//Sets the frontdir in sync with heading.
frontdir = GetVectorFromHeading(heading) + float3(0,frontdir.y,0);
if (unitDef->isAirBase) {
airBaseHandler->RegisterAirBase(this);
}
luaCallIns.UnitFinished(this);
globalAI->UnitFinished(this);
if (unitDef->isFeature) {
UnBlock();
CFeature* f =
featureHandler->CreateWreckage(pos, wreckName, heading, buildFacing,
0, team, false, "");
if (f) {
f->blockHeightChanges = true;
}
KillUnit(false, true, 0);
}
}
示例5: PushWind
void CUnit::PushWind(float x, float z, float strength)
{
if(strength > unitDef->windGenerator)
{
cob->Call(COBFN_SetSpeed, (int)(unitDef->windGenerator*3000.0f));
}
else
{
cob->Call(COBFN_SetSpeed, (int)(strength*3000.0f));
}
cob->Call(COBFN_SetDirection, (int)GetHeadingFromVector(-x, -z));
}
示例6: GetVectorFromHeading
void CFeature::ForcedSpin(const float3& newDir)
{
float3 updir = UpVector;
if (updir == newDir) {
//FIXME perhaps save the old right,up,front directions, so we can
// reconstruct the old upvector and generate a better assumption for updir
updir -= GetVectorFromHeading(heading);
}
float3 rightdir = newDir.cross(updir).Normalize();
updir = rightdir.cross(newDir);
transMatrix = CMatrix44f(pos, -rightdir, updir, newDir);
heading = GetHeadingFromVector(newDir.x, newDir.z);
}
示例7: assert
void CAirMoveType::SetState(AAirMoveType::AircraftState state)
{
// this state is only used by CTAAirMoveType
assert(state != AIRCRAFT_HOVERING);
if (aircraftState == AIRCRAFT_CRASHING || state == aircraftState)
return;
/*
if (state == AIRCRAFT_LANDING)
owner->cob->Call(COBFN_Deactivate);
else if (state == aircraft_flying)
// cob->Call(COBFN_Activate);
*/
if (state == AIRCRAFT_FLYING) {
owner->Activate();
owner->script->StartMoving();
}
if (state == AIRCRAFT_LANDED) {
owner->heading = GetHeadingFromVector(owner->frontdir.x, owner->frontdir.z);
owner->physicalState = CSolidObject::OnGround;
owner->useAirLos = false;
} else {
owner->physicalState = CSolidObject::Flying;
owner->useAirLos = true;
if (state != AIRCRAFT_LANDING) {
reservedLandingPos.x = -1;
owner->UnBlock();
}
}
if (aircraftState == AIRCRAFT_LANDED && reservedLandingPos.x > 0) {
reservedLandingPos.x = -1;
}
subState = 0;
// make sure we only go into takeoff if actually landed
if (state != AIRCRAFT_TAKEOFF || aircraftState == AIRCRAFT_LANDED) {
aircraftState = state;
} else {
aircraftState = AIRCRAFT_TAKEOFF;
}
}
示例8: GetHeadingFromVector
void CFeature::ForcedSpin(const float3& newDir)
{
/*
heading = GetHeadingFromVector(newDir.x, newDir.z);
CalculateTransform();
if (def->drawType >= DRAWTYPE_TREE) {
treeDrawer->DeleteTree(pos);
treeDrawer->AddTree(def->drawType - 1, pos, 1.0f);
}
*/
float3 updir = UpVector;
if (updir == newDir) {
//FIXME perhaps save the old right,up,front directions, so we can
// reconstruct the old upvector and generate a better assumption for updir
updir -= GetVectorFromHeading(heading);
}
float3 rightdir = newDir.cross(updir).Normalize();
updir = rightdir.cross(newDir);
transMatrix = CMatrix44f(pos, -rightdir, updir, newDir);
heading = GetHeadingFromVector(newDir.x, newDir.z);
}
示例9: if
void CAirMoveType::SetState(CAirMoveType::AircraftState state)
{
if(aircraftState==AIRCRAFT_CRASHING || state==aircraftState)
return;
/* if (state == AIRCRAFT_LANDING)
owner->animator->AnimAction(ANIMFN_Deactivate);
else if (state == aircraft_flying)
//animator->AnimAction(ANIMFN_Activate); */
if (state == AIRCRAFT_FLYING) {
owner->Activate();
owner->animator->AnimAction(ANIMFN_StartMoving);
}
if(state==AIRCRAFT_LANDED){
owner->heading=GetHeadingFromVector(owner->frontdir.x, owner->frontdir.z);
owner->physicalState = CSolidObject::OnGround;
owner->useAirLos=false;
}else{
owner->physicalState = CSolidObject::Flying;
owner->useAirLos=true;
if(state!=AIRCRAFT_LANDING){
reservedLandingPos.x=-1;
owner->UnBlock();
}
}
if(aircraftState==AIRCRAFT_LANDED && reservedLandingPos.x>0){
reservedLandingPos.x=-1;
}
subState=0;
if(state!=AIRCRAFT_TAKEOFF || aircraftState==AIRCRAFT_LANDED) //make sure we only go into takeoff if actually landed
aircraftState=state;
else
aircraftState=AIRCRAFT_TAKEOFF;
}
示例10: GetBuildPiece
void CFactory::UpdateBuild(CUnit* buildee) {
if (stunned)
return;
// factory not under construction and
// nanolathing unit: continue building
lastBuildUpdateFrame = gs->frameNum;
// buildPiece is the rotating platform
const int buildPiece = GetBuildPiece();
const float3& buildPos = CalcBuildPos(buildPiece);
const CMatrix44f& mat = script->GetPieceMatrix(buildPiece);
const int h = GetHeadingFromVector(mat[2], mat[10]); //! x.z, z.z
float3 buildeePos = buildPos;
// rotate unit nanoframe with platform
buildee->heading = (-h + GetHeadingFromFacing(buildFacing)) & (SPRING_CIRCLE_DIVS - 1);
if (buildee->unitDef->floatOnWater && (buildeePos.y <= 0.0f))
buildeePos.y = -buildee->unitDef->waterline;
buildee->Move3D(buildeePos, false);
buildee->UpdateDirVectors(false);
buildee->UpdateMidAndAimPos();
const CCommandQueue& queue = commandAI->commandQue;
if (!queue.empty() && (queue.front().GetID() == CMD_WAIT)) {
buildee->AddBuildPower(0, this);
} else {
if (buildee->AddBuildPower(buildSpeed, this)) {
CreateNanoParticle();
}
}
}
示例11: UpdateAirPhysics
bool CHoverAirMoveType::Update()
{
const float3 lastPos = owner->pos;
const float4 lastSpd = owner->speed;
AAirMoveType::Update();
if ((owner->IsStunned() && !owner->IsCrashing()) || owner->beingBuilt) {
wantedSpeed = ZeroVector;
UpdateAirPhysics();
return (HandleCollisions(collide && !owner->beingBuilt && (padStatus == PAD_STATUS_FLYING) && (aircraftState != AIRCRAFT_TAKEOFF)));
}
// allow us to stop if wanted (changes aircraft state)
if (wantToStop)
ExecuteStop();
if (aircraftState != AIRCRAFT_CRASHING) {
if (owner->UnderFirstPersonControl()) {
SetState(AIRCRAFT_FLYING);
const FPSUnitController& con = owner->fpsControlPlayer->fpsController;
const float3 forward = con.viewDir;
const float3 right = forward.cross(UpVector);
const float3 nextPos = lastPos + owner->speed;
float3 flatForward = forward;
flatForward.Normalize2D();
wantedSpeed = ZeroVector;
if (con.forward) wantedSpeed += flatForward;
if (con.back ) wantedSpeed -= flatForward;
if (con.right ) wantedSpeed += right;
if (con.left ) wantedSpeed -= right;
wantedSpeed.Normalize();
wantedSpeed *= maxSpeed;
if (!nextPos.IsInBounds()) {
owner->SetVelocityAndSpeed(ZeroVector);
}
UpdateAirPhysics();
wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z);
}
if (reservedPad != NULL) {
MoveToRepairPad();
if (padStatus >= PAD_STATUS_LANDING) {
flyState = FLY_LANDING;
}
}
}
switch (aircraftState) {
case AIRCRAFT_LANDED:
UpdateLanded();
break;
case AIRCRAFT_TAKEOFF:
UpdateTakeoff();
break;
case AIRCRAFT_FLYING:
UpdateFlying();
break;
case AIRCRAFT_LANDING:
UpdateLanding();
break;
case AIRCRAFT_HOVERING:
UpdateHovering();
break;
case AIRCRAFT_CRASHING: {
UpdateAirPhysics();
if ((CGround::GetHeightAboveWater(owner->pos.x, owner->pos.z) + 5.0f + owner->radius) > owner->pos.y) {
owner->ClearPhysicalStateBit(CSolidObject::PSTATE_BIT_CRASHING);
owner->KillUnit(NULL, true, false);
} else {
#define SPIN_DIR(o) ((o->id & 1) * 2 - 1)
wantedHeading = GetHeadingFromVector(owner->rightdir.x * SPIN_DIR(owner), owner->rightdir.z * SPIN_DIR(owner));
wantedHeight = 0.0f;
#undef SPIN_DIR
}
new CSmokeProjectile(owner, owner->midPos, gs->randVector() * 0.08f, 100 + gs->randFloat() * 50, 5, 0.2f, 0.4f);
} break;
}
if (lastSpd == ZeroVector && owner->speed != ZeroVector) { owner->script->StartMoving(false); }
if (lastSpd != ZeroVector && owner->speed == ZeroVector) { owner->script->StopMoving(); }
// Banking requires deltaSpeed.y = 0
deltaSpeed = owner->speed - lastSpd;
deltaSpeed.y = 0.0f;
// Turn and bank and move; update dirs
UpdateHeading();
//.........这里部分代码省略.........
示例12: UseSmoothMesh
//.........这里部分代码省略.........
case FLY_CIRCLING: {
if ((++waitCounter) > ((GAME_SPEED * 3) + 10)) {
if (airStrafe) {
float3 relPos = pos - circlingPos;
if (relPos.x < 0.0001f && relPos.x > -0.0001f) {
relPos.x = 0.0001f;
}
static CMatrix44f rot(0.0f, fastmath::PI / 4.0f, 0.0f);
// make sure the point is on the circle, go there in a straight line
goalPos = circlingPos + (rot.Mul(relPos.Normalize2D()) * goalDistance);
}
waitCounter = 0;
}
} break;
case FLY_ATTACKING: {
if (airStrafe) {
float3 relPos = pos - circlingPos;
if (relPos.x < 0.0001f && relPos.x > -0.0001f) {
relPos.x = 0.0001f;
}
CMatrix44f rot;
if (gs->randFloat() > 0.5f) {
rot.RotateY(0.6f + gs->randFloat() * 0.6f);
} else {
rot.RotateY(-(0.6f + gs->randFloat() * 0.6f));
}
// Go there in a straight line
goalPos = circlingPos + (rot.Mul(relPos.Normalize2D()) * goalDistance);
}
} break;
case FLY_LANDING: {
} break;
}
}
// not "close" to goal yet, so keep going
// use 2D math since goal is on the ground
// but we are not
goalVec.y = 0.0f;
// if we are close to our goal, we should
// adjust speed st. we never overshoot it
// (by respecting current brake-distance)
const float curSpeed = owner->speed.Length2D();
const float brakeDist = (0.5f * curSpeed * curSpeed) / decRate;
const float goalDist = goalVec.Length() + 0.1f;
const float goalSpeed =
(maxSpeed ) * (goalDist > brakeDist) +
(curSpeed - decRate) * (goalDist <= brakeDist);
if (goalDist > goalSpeed) {
// update our velocity and heading so long as goal is still
// further away than the distance we can cover in one frame
// we must use a variable-size "dead zone" to avoid freezing
// in mid-air or oscillation behavior at very close distances
// NOTE:
// wantedSpeed is a vector, so even aircraft with turnRate=0
// are coincidentally able to reach any goal by side-strafing
wantedHeading = GetHeadingFromVector(goalVec.x, goalVec.z);
wantedSpeed = (goalVec / goalDist) * goalSpeed;
} else {
// switch to hovering (if !CanLand()))
if (flyState != FLY_ATTACKING) {
ExecuteStop();
}
}
// redundant, done in Update()
// UpdateHeading();
UpdateAirPhysics();
// Point toward goal or forward - unless we just passed it to get to another goal
if ((flyState == FLY_ATTACKING) || (flyState == FLY_CIRCLING)) {
goalVec = circlingPos - pos;
} else {
const bool b0 = (flyState != FLY_LANDING && (owner->commandAI->HasMoreMoveCommands()));
const bool b1 = (goalDist < brakeDist && goalDist > 1.0f);
if (b0 && b1) {
goalVec = owner->frontdir;
} else {
goalVec = goalPos - pos;
}
}
if (goalVec.SqLength2D() > 1.0f) {
// update heading again in case goalVec changed
wantedHeading = GetHeadingFromVector(goalVec.x, goalVec.z);
}
}
示例13: fabs
//.........这里部分代码省略.........
case FLY_CIRCLING:
waitCounter++;
if (waitCounter > 100) {
//logOutput.Print("moving circlepos");
float3 relPos = pos - circlingPos;
if(relPos.x<0.0001f && relPos.x>-0.0001f)
relPos.x=0.0001f;
relPos.y = 0;
relPos.Normalize();
CMatrix44f rot;
rot.RotateY(1.0f);
float3 newPos = rot.Mul(relPos);
//Make sure the point is on the circle
newPos = newPos.Normalize() * goalDistance;
//Go there in a straight line
goalPos = circlingPos + newPos;
waitCounter = 0;
}
break;
case FLY_ATTACKING:{
//logOutput.Print("wait is %d", waitCounter);
float3 relPos = pos - circlingPos;
if(relPos.x<0.0001f && relPos.x>-0.0001f)
relPos.x=0.0001f;
relPos.y = 0;
relPos.Normalize();
CMatrix44f rot;
if (gs->randFloat()>0.5f)
rot.RotateY(0.6f+gs->randFloat()*0.6f);
else
rot.RotateY(-(0.6f+gs->randFloat()*0.6f));
float3 newPos = rot.Mul(relPos);
newPos = newPos.Normalize() * goalDistance;
//Go there in a straight line
goalPos = circlingPos + newPos;
// logOutput.Print("Changed circle pos");
break;}
case FLY_LANDING:{
/* //First check if we can land around here somewhere
if (!CanLandAt(pos)) {
//Check the surrounding area for a suitable position
float3 newPos;
bool found = FindLandingSpot(pos, newPos);
if (found) {
SetState(AIRCRAFT_FLYING);
logOutput.Print("Found a landingspot when cruising around");
goalPos = newPos;
return;
}
}
else {
SetState(AIRCRAFT_LANDING);
return;
}
float3 relPos = pos - circlingPos;
relPos.y = 0;
CMatrix44f rot;
rot.RotateY(2.0f);
float3 newPos = rot.Mul(relPos);
//Make sure the point is on the circle
newPos = newPos.Normalize() * goalDistance;
//Go there in a straight line
goalPos = circlingPos + newPos;
waitCounter = 0;
*/ break;}
}
}
//no, so go there!
dir.y = 0;
float realMax = maxSpeed;
float dist=dir.Length2D();
//If we are close to our goal, we should go slow enough to be able to break in time
//if in attack mode dont slow down
if (flyState!=FLY_ATTACKING && dist < breakDistance) {
realMax = dist/(speed.Length2D()+0.01f) * decRate;
//logOutput.Print("Break! %f %f %f", maxSpeed, dir.Length2D(), realMax);
}
wantedSpeed = dir.Normalize() * realMax;
UpdateAirPhysics();
//Point toward goal or forward
if ((flyState == FLY_ATTACKING) || (flyState == FLY_CIRCLING)) {
dir = circlingPos - pos;
} else {
dir = goalPos - pos;
}
if(dir.SqLength2D()>1)
wantedHeading = GetHeadingFromVector(dir.x, dir.z);
}
示例14: SetState
void CTAAirMoveType::Update()
{
//Handy stuff. Wonder if there is a better way?
float3 &pos=owner->pos;
SyncedFloat3 &rightdir = owner->rightdir;
SyncedFloat3 &frontdir = owner->frontdir;
SyncedFloat3 &updir = owner->updir;
float3 &speed = owner->speed;
//This is only set to false after the plane has finished constructing
if (useHeading){
useHeading = false;
SetState(AIRCRAFT_TAKEOFF);
}
//Allow us to stop if wanted
if (wantToStop)
ExecuteStop();
float3 lastSpeed = speed;
if(owner->stunned){
wantedSpeed=ZeroVector;
UpdateAirPhysics();
} else {
#ifdef DIRECT_CONTROL_ALLOWED
if(owner->directControl){
DirectControlStruct* dc=owner->directControl;
SetState(AIRCRAFT_FLYING);
float3 forward=dc->viewDir;
float3 flatForward=forward;
flatForward.y=0;
flatForward.Normalize();
float3 right=forward.cross(UpVector);
wantedSpeed=ZeroVector;
if(dc->forward)
wantedSpeed+=flatForward;
if(dc->back)
wantedSpeed-=flatForward;
if(dc->right)
wantedSpeed+=right;
if(dc->left)
wantedSpeed-=right;
wantedSpeed.Normalize();
wantedSpeed*=maxSpeed;
UpdateAirPhysics();
wantedHeading=GetHeadingFromVector(flatForward.x,flatForward.z);
} else
#endif
{
if(reservedPad){
CUnit* unit=reservedPad->unit;
float3 relPos=unit->localmodel->GetPiecePos(reservedPad->piece);
float3 pos=unit->pos + unit->frontdir*relPos.z + unit->updir*relPos.y + unit->rightdir*relPos.x;
if(padStatus==0){
if(aircraftState!=AIRCRAFT_FLYING && aircraftState!=AIRCRAFT_TAKEOFF)
SetState(AIRCRAFT_FLYING);
goalPos=pos;
if(pos.distance(owner->pos)<400){
padStatus=1;
}
//geometricObjects->AddLine(owner->pos,pos,1,0,1);
} else if(padStatus==1){
if(aircraftState!=AIRCRAFT_FLYING)
SetState(AIRCRAFT_FLYING);
flyState=FLY_LANDING;
goalPos=pos;
reservedLandingPos=pos;
wantedHeight=pos.y-ground->GetHeight(pos.x,pos.z);
if(owner->pos.distance(pos)<3 || aircraftState==AIRCRAFT_LANDED){
padStatus=2;
}
//geometricObjects->AddLine(owner->pos,pos,10,0,1);
} else {
if(aircraftState!=AIRCRAFT_LANDED)
SetState(AIRCRAFT_LANDED);
owner->pos=pos;
owner->AddBuildPower(unit->unitDef->buildSpeed/30,unit);
owner->currentFuel = min (owner->unitDef->maxFuel, owner->currentFuel + (owner->unitDef->maxFuel / (GAME_SPEED * owner->unitDef->refuelTime)));
if(owner->health>=owner->maxHealth-1 && owner->currentFuel >= owner->unitDef->maxFuel){
airBaseHandler->LeaveLandingPad(reservedPad);
reservedPad=0;
padStatus=0;
goalPos=oldGoalPos;
SetState(AIRCRAFT_TAKEOFF);
}
}
}
//.........这里部分代码省略.........
示例15: ExecuteStop
bool CHoverAirMoveType::Update()
{
float3& pos = owner->pos;
float3& speed = owner->speed;
AAirMoveType::Update();
if (owner->stunned || owner->beingBuilt) {
wantedSpeed = ZeroVector;
wantToStop = true;
}
// Allow us to stop if wanted
if (wantToStop) {
ExecuteStop();
}
const float3 lastSpeed = speed;
if (owner->fpsControlPlayer != NULL) {
SetState(AIRCRAFT_FLYING);
const FPSUnitController& con = owner->fpsControlPlayer->fpsController;
const float3 forward = con.viewDir;
const float3 right = forward.cross(UpVector);
const float3 nextPos = pos + speed;
float3 flatForward = forward;
flatForward.y = 0.0f;
flatForward.Normalize();
wantedSpeed = ZeroVector;
if (con.forward) wantedSpeed += flatForward;
if (con.back ) wantedSpeed -= flatForward;
if (con.right ) wantedSpeed += right;
if (con.left ) wantedSpeed -= right;
wantedSpeed.Normalize();
wantedSpeed *= maxSpeed;
if (!nextPos.IsInBounds()) {
speed = ZeroVector;
}
UpdateAirPhysics();
wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z);
} else {
if (reservedPad != NULL) {
MoveToRepairPad();
if (padStatus >= 1) {
flyState = FLY_LANDING;
}
}
// Main state handling
switch (aircraftState) {
case AIRCRAFT_LANDED:
UpdateLanded();
break;
case AIRCRAFT_TAKEOFF:
UpdateTakeoff();
break;
case AIRCRAFT_FLYING:
UpdateFlying();
break;
case AIRCRAFT_LANDING:
UpdateLanding();
break;
case AIRCRAFT_HOVERING:
UpdateHovering();
break;
case AIRCRAFT_CRASHING:
break;
}
}
// Banking requires deltaSpeed.y = 0
deltaSpeed = speed - lastSpeed;
deltaSpeed.y = 0.0f;
// Turn and bank and move; update dirs
UpdateHeading();
UpdateBanking(aircraftState == AIRCRAFT_HOVERING);
return (HandleCollisions());
}