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);
		}
	}
}
Example #2
0
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);
		}
	}
}