void mech_move_event(EVENT * e) { MECH *mech = (MECH *) e->data; if (MechType(mech) == CLASS_VTOL) if (Landed(mech) || FuelCheck(mech)) return; UpdateHeading(mech); if ((IsMechLegLess(mech)) || Jumping(mech) || OODing(mech)) { if (MechDesiredFacing(mech) != MechFacing(mech)) MECHEVENT(mech, EVENT_MOVE, mech_move_event, MOVE_TICK, 0); return; } UpdateSpeed(mech); move_mech(mech); if (mech->mapindex < 0) return; if (MechType(mech) == CLASS_VEH_NAVAL && MechRTerrain(mech) != BRIDGE && MechRTerrain(mech) != ICE && MechRTerrain(mech) != WATER) return; if (MechSpeed(mech) || MechDesiredSpeed(mech) || MechDesiredFacing(mech) != MechFacing(mech) || ((MechType(mech) == CLASS_VTOL || MechMove(mech) == MOVE_SUB) && MechVerticalSpeed(mech))) MECHEVENT(mech, EVENT_MOVE, mech_move_event, MOVE_TICK, 0); }
void aero_move_event(EVENT * e) { MECH *mech = (MECH *) e->data; if (!Landed(mech)) { /* Returns 1 only if we 1) Ran out of fuel, and 2) Were VTOL, and 3) Crashed */ if (FuelCheck(mech)) return; /* Genuine CHEAT :-) */ if (Started(mech)) { aero_UpdateHeading(mech); aero_UpdateSpeed(mech); } if (Fallen(mech)) MechStartFZ(mech) = MechStartFZ(mech) - 1; move_mech(mech); if (IsDS(mech) && MechZ(mech) <= (MechElevation(mech) + 5) && ((event_tick / WEAPON_TICK) % 10) == 0) DS_BlastNearbyMechsAndTrees(mech, "You are hit by the DropShip's plasma exhaust!", "is hit directly by DropShip's exhaust!", "You are hit by the DropShip's plasma exhaust!", "is hit by DropShip's exhaust!", "light up and burn.", 8); MECHEVENT(mech, EVENT_MOVE, aero_move_event, MOVE_TICK, 0); } else if (Landed(mech) && !Fallen(mech) && RollingT(mech)) { UpdateHeading(mech); UpdateSpeed(mech); move_mech(mech); if (fabs(MechSpeed(mech)) > 0.0 || fabs(MechDesiredSpeed(mech)) > 0.0 || MechDesiredFacing(mech) != MechFacing(mech)) if (!FuelCheck(mech)) MECHEVENT(mech, EVENT_MOVE, aero_move_event, MOVE_TICK, 0); } }
bool CTAAirMoveType::Update() { float3& pos = owner->pos; float3& speed = owner->speed; // This is only set to false after the plane has finished constructing if (useHeading) { useHeading = false; SetState(AIRCRAFT_TAKEOFF); } 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) { CUnit* unit = reservedPad->GetUnit(); const float3 relPos = unit->script->GetPiecePos(reservedPad->GetPiece()); const 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.SqDistance2D(owner->pos) < 400*400) { padStatus = 1; } } else if (padStatus == 1) { if (aircraftState != AIRCRAFT_FLYING) { SetState(AIRCRAFT_FLYING); } flyState = FLY_LANDING; goalPos = pos; reservedLandingPos = pos; wantedHeight = pos.y - ground->GetHeightAboveWater(pos.x, pos.z); if (owner->pos.SqDistance(pos) < 9 || aircraftState == AIRCRAFT_LANDED) { padStatus = 2; } } else { if (aircraftState != AIRCRAFT_LANDED) SetState(AIRCRAFT_LANDED); owner->pos = pos; owner->AddBuildPower(unit->unitDef->buildSpeed / 30, unit); owner->currentFuel = std::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 = NULL; padStatus = 0; goalPos = oldGoalPos; SetState(AIRCRAFT_TAKEOFF); } } } // 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); owner->UpdateMidPos(); return (HandleCollisions()); }
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(); UpdateBanking(aircraftState == AIRCRAFT_HOVERING); return (HandleCollisions(collide && !owner->beingBuilt && (padStatus == PAD_STATUS_FLYING) && (aircraftState != AIRCRAFT_TAKEOFF))); }
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()); }
void CTAAirMoveType::Update() { float3& pos = owner->pos; 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 { 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); float3 nextPos = pos + speed; 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; if (!nextPos.CheckInBounds()) { speed = ZeroVector; } UpdateAirPhysics(); wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z); } else { if (reservedPad) { CUnit* unit = reservedPad->GetUnit(); float3 relPos = unit->script->GetPiecePos(reservedPad->GetPiece()); 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.SqDistance2D(owner->pos) < 400*400) { padStatus = 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.SqDistance(pos) < 9 || aircraftState == AIRCRAFT_LANDED) { padStatus = 2; } } else { if (aircraftState != AIRCRAFT_LANDED) SetState(AIRCRAFT_LANDED); owner->pos = pos; owner->AddBuildPower(unit->unitDef->buildSpeed / 30, unit); owner->currentFuel = std::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); } } } // 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; // Turn and bank and move UpdateHeading(); UpdateBanking(aircraftState == AIRCRAFT_HOVERING); // updates dirs owner->UpdateMidPos(); // Push other units out of the way if (pos != oldpos && aircraftState != AIRCRAFT_TAKEOFF && padStatus == 0) { oldpos = pos; if (!dontCheckCol && collide) { vector<CUnit*> nearUnits = qf->GetUnitsExact(pos, owner->radius + 6); vector<CUnit*>::iterator ui; for (ui = nearUnits.begin(); ui != nearUnits.end(); ++ui) { if ((*ui)->transporter) continue; float sqDist = (pos-(*ui)->pos).SqLength(); float totRad = owner->radius + (*ui)->radius; if (sqDist < totRad * totRad && sqDist != 0) { float dist = sqrt(sqDist); float3 dif = pos - (*ui)->pos; if (dist > 0.0f) { dif /= dist; } if ((*ui)->mass >= 100000 || (*ui)->immobile) { pos -= dif * (dist - totRad); owner->UpdateMidPos(); owner->speed *= 0.99f; } else { float part = owner->mass / (owner->mass + (*ui)->mass); pos -= dif * (dist - totRad) * (1 - part); owner->UpdateMidPos(); CUnit* u = (CUnit*) (*ui); u->pos += dif * (dist - totRad) * (part); u->UpdateMidPos(); float colSpeed = -owner->speed.dot(dif) + u->speed.dot(dif); owner->speed += dif * colSpeed * (1 - part); u->speed -= dif * colSpeed * (part); } } } } if (pos.x < 0) { pos.x += 0.6f; owner->midPos.x += 0.6f; } else if (pos.x > float3::maxxpos) { pos.x -= 0.6f; owner->midPos.x -= 0.6f; } if (pos.z < 0) { pos.z += 0.6f; owner->midPos.z += 0.6f; } else if (pos.z > float3::maxzpos) { pos.z -= 0.6f; owner->midPos.z -= 0.6f; } } }
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); } } } //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; } } } deltaSpeed = speed - lastSpeed; deltaSpeed.y = 0; //Banking requires this //Turn and bank and move UpdateHeading(); UpdateBanking(aircraftState == AIRCRAFT_HOVERING); //updates dirs owner->midPos=pos+frontdir*owner->relMidPos.z + updir*owner->relMidPos.y + rightdir*owner->relMidPos.x; //Push other units out of the way if(pos!=oldpos && aircraftState!=AIRCRAFT_TAKEOFF && padStatus==0){ oldpos=pos; if(!dontCheckCol){ vector<CUnit*> nearUnits=qf->GetUnitsExact(pos,owner->radius+6); vector<CUnit*>::iterator ui; for(ui=nearUnits.begin();ui!=nearUnits.end();++ui){ if((*ui)->transporter) continue; float sqDist=(pos-(*ui)->pos).SqLength(); float totRad=owner->radius+(*ui)->radius; if(sqDist<totRad*totRad && sqDist!=0){ float dist=sqrt(sqDist); float3 dif=pos-(*ui)->pos; dif/=dist; if((*ui)->mass>=100000 || (*ui)->immobile){ pos-=dif*(dist-totRad); owner->midPos=pos+owner->frontdir*owner->relMidPos.z + owner->updir*owner->relMidPos.y + owner->rightdir*owner->relMidPos.x; owner->speed*=0.99f; // float damage=((*ui)->speed-owner->speed).SqLength(); //dont think they should take damage when they dont try to avoid it // owner->DoDamage(DamageArray()*damage,0,ZeroVector); // (*ui)->DoDamage(DamageArray()*damage,0,ZeroVector); } else { float part=owner->mass/(owner->mass+(*ui)->mass); pos-=dif*(dist-totRad)*(1-part); owner->midPos=pos+owner->frontdir*owner->relMidPos.z + owner->updir*owner->relMidPos.y + owner->rightdir*owner->relMidPos.x; CUnit* u=(CUnit*)(*ui); u->pos+=dif*(dist-totRad)*(part); u->midPos=u->pos+u->frontdir*u->relMidPos.z + u->updir*u->relMidPos.y + u->rightdir*u->relMidPos.x; float colSpeed=-owner->speed.dot(dif)+u->speed.dot(dif); owner->speed+=dif*colSpeed*(1-part); u->speed-=dif*colSpeed*(part); // float damage=(((*ui)->speed-owner->speed)*0.1f).SqLength(); // owner->DoDamage(DamageArray()*damage,0,ZeroVector); // (*ui)->DoDamage(DamageArray()*damage,0,ZeroVector); // owner->speed*=0.99f; } } } } if(pos.x<0){ pos.x+=0.6f; owner->midPos.x+=0.6f; } else if(pos.x>float3::maxxpos){ pos.x-=0.6f; owner->midPos.x-=0.6f; } if(pos.z<0){ pos.z+=0.6f; owner->midPos.z+=0.6f; }else if(pos.z>float3::maxzpos){ pos.z-=0.6f; owner->midPos.z-=0.6f; } } }