void CAirMoveType::UpdateLanding(void) { float3 &pos = owner->pos; float3 &rightdir = owner->rightdir; float3 &frontdir = owner->frontdir; float3 &updir = owner->updir; float3 &speed = owner->speed; float speedf=speed.Length(); //find a landing spot if we dont have one if(reservedLandingPos.x<0){ reservedLandingPos=FindLandingPos(); if(reservedLandingPos.x>0){ reservedLandingPos.y+=wantedHeight; float3 tp=pos; pos=reservedLandingPos; owner->physicalState = CSolidObject::OnGround; owner->Block(); owner->physicalState = CSolidObject::Flying; pos=tp; owner->Deactivate(); owner->cob->Call(COBFN_StopMoving); } else { goalPos.CheckInBounds(); UpdateFlying(wantedHeight,1); return; } } else { //see if landing spot is still empty /* float3 tpos=owner->pos; owner->pos=reservedLandingPos; int2 mp=owner->GetMapPos(); owner->pos=tpos; for(int z=mp.y; z<mp.y+owner->ysize; z++){ for(int x=mp.x; x<mp.x+owner->xsize; x++){ if(readmap->groundBlockingObjectMap[z*gs->mapx+x]!=owner){ owner->UnBlock(); reservedLandingPos.x=-1; UpdateFlying(wantedHeight,1); return; } } }*/ } //update our speed float3 dif=reservedLandingPos-pos; float dist=dif.Length(); dif/=dist; float wsf=min(owner->unitDef->speed,dist/speedf*1.8f*maxAcc); float3 wantedSpeed=dif*wsf; float3 delta = wantedSpeed - speed; float dl=delta.Length(); if(dl<maxAcc*3) speed=wantedSpeed; else speed+=delta/dl*maxAcc*3; pos+=speed; //make the aircraft right itself up and turn toward goal if(rightdir.y<-0.01) updir-=rightdir*0.02; else if(rightdir.y>0.01) updir+=rightdir*0.02; if(frontdir.y<-0.01) frontdir+=updir*0.02; else if(frontdir.y>0.01) frontdir-=updir*0.02; if(rightdir.dot(dif)>0.01) frontdir+=rightdir*0.02; else if(rightdir.dot(dif)<-0.01) frontdir-=rightdir*0.02; frontdir.Normalize(); rightdir=frontdir.cross(updir); rightdir.Normalize(); updir=rightdir.cross(frontdir); owner->midPos=pos+frontdir*owner->relMidPos.z + updir*owner->relMidPos.y + rightdir*owner->relMidPos.x; //see if we are at the landing spot if(dist<1){ float h=ground->GetHeight(pos.x,pos.z); if(fabs(reservedLandingPos.y-h)>1) reservedLandingPos.y=h; else{ SetState(AIRCRAFT_LANDED); } } }
void CAirMoveType::UpdateLanding(void) { float3& pos = owner->pos; SyncedFloat3& rightdir = owner->rightdir; SyncedFloat3& frontdir = owner->frontdir; SyncedFloat3& updir = owner->updir; float3& speed = owner->speed; float speedf = speed.Length(); // find a landing spot if we dont have one if (reservedLandingPos.x < 0.0f) { reservedLandingPos = FindLandingPos(); if (reservedLandingPos.x > 0.0f) { reservedLandingPos.y += wantedHeight; float3 tp = pos; pos = reservedLandingPos; owner->physicalState = CSolidObject::OnGround; owner->Block(); owner->physicalState = CSolidObject::Flying; pos = tp; owner->Deactivate(); owner->script->StopMoving(); } else { goalPos.CheckInBounds(); UpdateFlying(wantedHeight, 1); return; } } else { // see if landing spot is still empty /* int2 mp = owner->GetMapPos(reservedLandingPos); for (int z = mp.y; z < mp.y + owner->ysize; z++) { for (int x = mp.x; x < mp.x + owner->xsize; x++) { if (readmap->groundBlockingObjectMap[z * gs->mapx + x] != owner) { owner->UnBlock(); reservedLandingPos.x = -1; UpdateFlying(wantedHeight, 1); return; } } } */ } // update our speed float3 dif = reservedLandingPos - pos; float dist = dif.Length(); float landingSpeed = (speedf > 0.0f && maxAcc > 0.0f)? (dist / speedf * 1.8f * maxAcc): 0.0f; float wsf = std::min(owner->maxSpeed, landingSpeed); if (dist > 0.0f) { dif /= dist; } float3 wantedSpeed = dif * wsf; float3 delta = wantedSpeed - speed; float dl = delta.Length(); if (dl < maxAcc * 3.0f) { speed = wantedSpeed; } else { if (dl > 0.0f && maxAcc > 0.0f) { speed += delta / dl * maxAcc * 3.0f; } } pos += speed; // make the aircraft right itself up and turn toward goal if (rightdir.y < -0.01f) updir -= rightdir * 0.02f; else if (rightdir.y > 0.01f) updir += rightdir * 0.02f; if (frontdir.y < -0.01f) frontdir += updir * 0.02f; else if (frontdir.y > 0.01f) frontdir -= updir * 0.02f; if (rightdir.dot(dif) > 0.01f) frontdir += rightdir * 0.02f; else if (rightdir.dot(dif) < -0.01f) frontdir -= rightdir * 0.02f; frontdir.Normalize(); rightdir = frontdir.cross(updir); rightdir.Normalize(); updir = rightdir.cross(frontdir); owner->UpdateMidPos(); // see if we are at the reserved (not user-clicked) landing spot if (dist < 1.0f) { float gh = ground->GetHeight(pos.x, pos.z); float gah = ground->GetHeight2(pos.x, pos.z); float alt = 0.0f; // can we submerge and are we still above water? if ((owner->unitDef->canSubmerge) && (gah < 0)) { alt = pos.y - gah; reservedLandingPos.y = gah; } else { alt = pos.y - gh; reservedLandingPos.y = gh; } if (alt <= 1.0f) { SetState(AIRCRAFT_LANDED); } } }