Skip to content

Commit

Permalink
fix #6009 #6010
Browse files Browse the repository at this point in the history
  • Loading branch information
rt committed Jul 16, 2018
1 parent 9587be7 commit 65e10e8
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 88 deletions.
40 changes: 28 additions & 12 deletions rts/Sim/MoveTypes/AAirMoveType.cpp
Expand Up @@ -7,6 +7,7 @@
#include "Map/MapInfo.h"
#include "Sim/Misc/GlobalSynced.h"
#include "Sim/Misc/QuadField.h"
#include "Sim/Misc/SmoothHeightMesh.h"
#include "Sim/Units/Unit.h"
#include "Sim/Units/UnitDef.h"
#include "Sim/Units/CommandAI/CommandAI.h"
Expand Down Expand Up @@ -37,6 +38,26 @@ CR_REG_METADATA(AAirMoveType, (
CR_MEMBER(lastColWarningType)
))



static inline float AAMTGetGroundHeightAW(float x, float z) { return CGround::GetHeightAboveWater(x, z); }
static inline float AAMTGetGroundHeight (float x, float z) { return CGround::GetHeightReal (x, z); }
static inline float AAMTGetSmoothGroundHeightAW(float x, float z) { return smoothGround.GetHeightAboveWater(x, z); }
static inline float AAMTGetSmoothGroundHeight (float x, float z) { return smoothGround.GetHeight (x, z); }
static inline float HAMTGetMaxGroundHeight(float x, float z) { return std::max(smoothGround.GetHeight(x, z), CGround::GetApproximateHeight(x, z)); }
static inline float SAMTGetMaxGroundHeight(float x, float z) { return std::max(smoothGround.GetHeight(x, z), CGround::GetHeightAboveWater(x, z)); }

AAirMoveType::GetGroundHeightFunc amtGetGroundHeightFuncs[6] = {
AAMTGetGroundHeightAW, // canSubmerge=0 useSmoothMesh=0
AAMTGetGroundHeight , // canSubmerge=1 useSmoothMesh=0
AAMTGetSmoothGroundHeightAW, // canSubmerge=0 useSmoothMesh=1
AAMTGetSmoothGroundHeight, // canSubmerge=1 useSmoothMesh=1
HAMTGetMaxGroundHeight, // HoverAirMoveType::UpdateFlying
SAMTGetMaxGroundHeight, // StrafeAirMoveType::UpdateFlying
};



AAirMoveType::AAirMoveType(CUnit* unit):
AMoveType(unit),
aircraftState(AIRCRAFT_LANDED),
Expand Down Expand Up @@ -86,7 +107,7 @@ bool AAirMoveType::UseSmoothMesh() const {

const bool closeGoalPos = (goalPos.SqDistance2D(owner->pos) < Square(landRadiusSq * 2.0f));
const bool transportCmd = ((fc.GetID() == CMD_LOAD_UNITS) || (fc.GetID() == CMD_UNLOAD_UNIT));
const bool forceDisable = ((transportCmd && closeGoalPos) || (aircraftState != AIRCRAFT_FLYING));
const bool forceDisable = ((transportCmd && closeGoalPos) || (aircraftState != AIRCRAFT_FLYING && aircraftState != AIRCRAFT_HOVERING));

return !forceDisable;
}
Expand Down Expand Up @@ -121,9 +142,7 @@ void AAirMoveType::UpdateLanded()
// lowered) later and we do not want to end up hovering
// in mid-air or sink below it
// let gravity do the job instead of teleporting
const float minHeight = owner->unitDef->canSubmerge?
CGround::GetHeightReal(owner->pos.x, owner->pos.z):
CGround::GetHeightAboveWater(owner->pos.x, owner->pos.z);
const float minHeight = amtGetGroundHeightFuncs[owner->unitDef->canSubmerge](owner->pos.x, owner->pos.z);
const float curHeight = owner->pos.y;

if (curHeight > minHeight) {
Expand Down Expand Up @@ -159,15 +178,14 @@ void AAirMoveType::LandAt(float3 pos, float distanceSq)
owner->Block();
owner->Move(originalPos, false);

const float gh = CGround::GetHeightReal(reservedLandingPos.x, reservedLandingPos.z);
wantedHeight = reservedLandingPos.y - (owner->unitDef->canSubmerge ? gh : std::max(0.0f, gh));
wantedHeight = reservedLandingPos.y - amtGetGroundHeightFuncs[owner->unitDef->canSubmerge](reservedLandingPos.x, reservedLandingPos.z);
}


void AAirMoveType::UpdateLandingHeight()
void AAirMoveType::UpdateLandingHeight(float newWantedHeight)
{
const float gh = CGround::GetHeightReal(reservedLandingPos.x, reservedLandingPos.z);
reservedLandingPos.y = wantedHeight + (owner->unitDef->canSubmerge ? gh : std::max(0.0f, gh));
wantedHeight = newWantedHeight;
reservedLandingPos.y = wantedHeight + amtGetGroundHeightFuncs[owner->unitDef->canSubmerge](reservedLandingPos.x, reservedLandingPos.z);
}


Expand All @@ -180,9 +198,7 @@ void AAirMoveType::UpdateLanding()
const float distSq = reservedLandingPos.SqDistance(pos);


const float localAltitude = pos.y - (owner->unitDef->canSubmerge ?
CGround::GetHeightReal(owner->pos.x, owner->pos.z):
CGround::GetHeightAboveWater(owner->pos.x, owner->pos.z));
const float localAltitude = pos.y - amtGetGroundHeightFuncs[owner->unitDef->canSubmerge](owner->pos.x, owner->pos.z);

if (distSq <= radiusSq || (distSq < landRadiusSq && localAltitude < wantedHeight + radius)) {
SetState(AIRCRAFT_LANDED);
Expand Down
3 changes: 2 additions & 1 deletion rts/Sim/MoveTypes/AAirMoveType.h
Expand Up @@ -14,6 +14,7 @@ class AAirMoveType : public AMoveType
{
CR_DECLARE(AAirMoveType)
public:
typedef float(*GetGroundHeightFunc)(float, float);

enum AircraftState {
AIRCRAFT_LANDED,
Expand Down Expand Up @@ -42,7 +43,7 @@ class AAirMoveType : public AMoveType

void LandAt(float3 pos, float distanceSq);
void ClearLandingPos() { reservedLandingPos = -OnesVector; }
void UpdateLandingHeight();
void UpdateLandingHeight(float newWantedHeight);
void UpdateLanding();

bool CanApplyImpulse(const float3&) { return true; }
Expand Down
51 changes: 23 additions & 28 deletions rts/Sim/MoveTypes/HoverAirMoveType.cpp
Expand Up @@ -5,13 +5,13 @@
#include "Game/Players/Player.h"
#include "Game/GlobalUnsynced.h"
#include "Map/Ground.h"
#include "Map/MapInfo.h"
#include "Rendering/Env/Particles/Classes/SmokeProjectile.h"
#include "Sim/Misc/GeometricObjects.h"
#include "Sim/Misc/GlobalSynced.h"
#include "Sim/Misc/GroundBlockingObjectMap.h"
#include "Sim/Misc/QuadField.h"
#include "Sim/Misc/ModInfo.h"
#include "Sim/Misc/SmoothHeightMesh.h"
#include "Sim/Projectiles/ProjectileMemPool.h"
#include "Sim/Units/Scripts/UnitScript.h"
#include "Sim/Units/Unit.h"
Expand Down Expand Up @@ -75,6 +75,9 @@ static bool UnitIsBusy(const CUnit* u) { return (UnitIsBusy(u->commandAI)); }
static bool UnitHasLoadCmd(const CUnit* u) { return (UnitHasLoadCmd(u->commandAI)); }


extern AAirMoveType::GetGroundHeightFunc amtGetGroundHeightFuncs[6];



CHoverAirMoveType::CHoverAirMoveType(CUnit* owner) :
AAirMoveType(owner),
Expand Down Expand Up @@ -367,13 +370,13 @@ void CHoverAirMoveType::UpdateTakeoff()

UpdateAirPhysics();

const float altitude = owner->unitDef->canSubmerge?
(pos.y - CGround::GetHeightReal(pos.x, pos.z)):
(pos.y - CGround::GetHeightAboveWater(pos.x, pos.z));
const float curAltitude = amtGetGroundHeightFuncs[owner->unitDef->canSubmerge](pos.x, pos.z);
const float minAltitude = orgWantedHeight * 0.8f;

if (altitude > orgWantedHeight * 0.8f) {
SetState(AIRCRAFT_FLYING);
}
if (curAltitude <= minAltitude)
return;

SetState(AIRCRAFT_FLYING);
}


Expand Down Expand Up @@ -440,24 +443,21 @@ void CHoverAirMoveType::UpdateFlying()

// Direction to where we would like to be
float3 goalVec = goalPos - pos;
float3 goalDir = goalVec;

// don't change direction for waypoints we just flew over and missed slightly
if (flyState != FLY_LANDING && owner->commandAI->HasMoreMoveCommands()) {
float3 goalDir = goalVec;

if ((goalDir != ZeroVector) && (goalVec.dot(goalDir.UnsafeANormalize()) < 1.0f)) {
if ((goalDir != ZeroVector) && (goalVec.dot(goalDir.UnsafeANormalize()) < 1.0f))
goalVec = owner->frontdir;
}

}

const float goalDistSq2D = goalVec.SqLength2D();
const float gHeight = UseSmoothMesh()?
std::max(smoothGround.GetHeight(pos.x, pos.z), CGround::GetApproximateHeight(pos.x, pos.z)):
CGround::GetHeightAboveWater(pos.x, pos.z);
const float groundHeight = amtGetGroundHeightFuncs[4 * UseSmoothMesh()](pos.x, pos.z);

const bool closeToGoal = (flyState == FLY_ATTACKING)?
(goalDistSq2D < ( 400.0f)):
(goalDistSq2D < (maxDrift * maxDrift)) && (math::fabs(gHeight + wantedHeight - pos.y) < maxDrift);
(goalDistSq2D < (maxDrift * maxDrift)) && (math::fabs(groundHeight + wantedHeight - pos.y) < maxDrift);

if (closeToGoal) {
switch (flyState) {
Expand Down Expand Up @@ -606,8 +606,8 @@ void CHoverAirMoveType::UpdateLanding()
// found a landing spot
reservedLandingPos = pos;
goalPos = pos;
wantedHeight = 0;
UpdateLandingHeight();

UpdateLandingHeight(0.0f);

const float3 originalPos = pos;

Expand Down Expand Up @@ -836,9 +836,7 @@ void CHoverAirMoveType::UpdateAirPhysics()
// if this aircraft uses the smoothmesh, these values are
// calculated with respect to that (for changing vertical
// speed, but not for ground collision)
float curAbsHeight = owner->unitDef->canSubmerge?
CGround::GetHeightReal(pos.x, pos.z):
CGround::GetHeightAboveWater(pos.x, pos.z);
float curAbsHeight = amtGetGroundHeightFuncs[owner->unitDef->canSubmerge](pos.x, pos.z);

// always stay above the actual terrain (therefore either the value of
// <midPos.y - radius> or pos.y must never become smaller than the real
Expand All @@ -853,11 +851,7 @@ void CHoverAirMoveType::UpdateAirPhysics()
owner->Move(UpVector * (curAbsHeight - (owner->midPos.y - owner->radius) + 0.01f), true);
}

if (UseSmoothMesh()) {
curAbsHeight = owner->unitDef->canSubmerge?
smoothGround.GetHeight(pos.x, pos.z):
smoothGround.GetHeightAboveWater(pos.x, pos.z);
}
curAbsHeight = amtGetGroundHeightFuncs[UseSmoothMesh() * 2 + owner->unitDef->canSubmerge](pos.x, pos.z);

// restore original vertical speed, then compute new
UpdateVerticalSpeed(spd, pos.y - curAbsHeight, yspeed);
Expand Down Expand Up @@ -1001,13 +995,14 @@ bool CHoverAirMoveType::CanLandAt(const float3& pos) const

const UnitDef* ud = owner->unitDef;

if ((CGround::GetApproximateHeight(pos.x, pos.z) < 0.0f) && !(ud->floatOnWater || ud->canSubmerge))
if ((CGround::GetApproximateHeight(pos) < 0.0f) && ((mapInfo->water.damage > 0.0f) || !(ud->floatOnWater || ud->canSubmerge)))
return false;

const int2 os = {owner->xsize, owner->zsize};
const int2 mp = owner->GetMapPos(pos);

for (int z = mp.y; z < mp.y + owner->zsize; z++) {
for (int x = mp.x; x < mp.x + owner->xsize; x++) {
for (int z = mp.y; z < (mp.y + os.y); z++) {
for (int x = mp.x; x < (mp.x + os.x); x++) {
if (groundBlockingObjectMap.GroundBlocked(x, z, owner))
return false;
}
Expand Down

0 comments on commit 65e10e8

Please sign in to comment.