Skip to content

Commit

Permalink
fix #6065
Browse files Browse the repository at this point in the history
MoveCtrl.Set*MoveTypeData(..., "useWantedSpeed[0]", false) disables engine wanted-speed changes for individual orders
MoveCtrl.Set*MoveTypeData(..., "useWantedSpeed[1]", false) disables engine wanted-speed changes for formation orders
  • Loading branch information
rt committed Nov 16, 2018
1 parent 16a88b7 commit 39d5e92
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 83 deletions.
25 changes: 14 additions & 11 deletions rts/Game/SelectedUnitsAI.cpp
Expand Up @@ -29,31 +29,34 @@ static const auto ugPairComp = [](const TGroupPair& a, const TGroupPair& b) { re
static const auto idPairComp = [](const std::pair<float, int>& a, const std::pair<float, int>& b) { return (a.first < b.first); };


// Global object
CSelectedUnitsHandlerAI selectedUnitsAI;


inline void CSelectedUnitsHandlerAI::SetUnitWantedMaxSpeedNet(CUnit* unit)
{
AMoveType* mt = unit->moveType;

if (!mt->UseWantedSpeed(false))
return;

// this sets the WANTED maximum speed of <unit>
// equal to its current ACTUAL maximum (not the
// UnitDef maximum, which can be overridden by
// scripts)
if (!unit->commandAI->CanSetMaxSpeed())
return;

unit->moveType->SetWantedMaxSpeed(unit->moveType->GetMaxSpeed());
mt->SetWantedMaxSpeed(mt->GetMaxSpeed());
}

inline void CSelectedUnitsHandlerAI::SetUnitGroupWantedMaxSpeedNet(CUnit* unit)
{
AMoveType* mt = unit->moveType;

if (!mt->UseWantedSpeed(true))
return;

// sets the wanted speed of this unit to that of the
// group's current-slowest member (groupMinMaxSpeed
// is derived from GetMaxSpeed, not GetMaxSpeedDef)
if (!unit->commandAI->CanSetMaxSpeed())
return;

unit->moveType->SetWantedMaxSpeed(groupMinMaxSpeed);
mt->SetWantedMaxSpeed(groupMinMaxSpeed);
}


Expand Down Expand Up @@ -243,7 +246,6 @@ void CSelectedUnitsHandlerAI::GiveCommandNet(Command& c, int player)
// Calculate the outer limits and the center of the group coordinates.
//
void CSelectedUnitsHandlerAI::CalculateGroupData(int player, bool queueing) {
//Finding the highest, lowest and weighted central positional coordinates among the selected units.
float3 sumCoor;
float3 minCoor = OnesVector * 100000.0f;
float3 maxCoor = -OnesVector * 100000.0f;
Expand All @@ -256,6 +258,7 @@ void CSelectedUnitsHandlerAI::CalculateGroupData(int player, bool queueing) {

const std::vector<int>& playerUnitIDs = selectedUnitsHandler.netSelected[player];

// find highest, lowest and weighted central positional coordinates among selected units
for (const int unitID: playerUnitIDs) {
const CUnit* unit = unitHandler.GetUnit(unitID);

Expand All @@ -270,7 +273,7 @@ void CSelectedUnitsHandlerAI::CalculateGroupData(int player, bool queueing) {
maxCoor = float3::max(maxCoor, unitPos);
sumCoor += unitPos;

if (!unit->commandAI->CanSetMaxSpeed())
if (!unit->moveType->UseWantedSpeed(false))
continue;

mobileUnits++;
Expand Down
59 changes: 30 additions & 29 deletions rts/Sim/MoveTypes/HoverAirMoveType.cpp
Expand Up @@ -52,6 +52,32 @@ CR_REG_METADATA(CHoverAirMoveType, (



#define MEMBER_CHARPTR_HASH(memberName) HsiehHash(memberName, strlen(memberName), 0)
#define MEMBER_LITERAL_HASH(memberName) HsiehHash(memberName, sizeof(memberName) - 1, 0)

static const unsigned int BOOL_MEMBER_HASHES[] = {
MEMBER_LITERAL_HASH( "collide"),
MEMBER_LITERAL_HASH( "dontLand"),
MEMBER_LITERAL_HASH( "airStrafe"),
MEMBER_LITERAL_HASH( "useSmoothMesh"),
MEMBER_LITERAL_HASH("bankingAllowed"),
};
static const unsigned int FLOAT_MEMBER_HASHES[] = {
MEMBER_LITERAL_HASH( "wantedHeight"),
MEMBER_LITERAL_HASH( "accRate"),
MEMBER_LITERAL_HASH( "decRate"),
MEMBER_LITERAL_HASH( "turnRate"),
MEMBER_LITERAL_HASH( "altitudeRate"),
MEMBER_LITERAL_HASH( "currentBank"),
MEMBER_LITERAL_HASH( "currentPitch"),
MEMBER_LITERAL_HASH( "maxDrift"),
};

#undef MEMBER_CHARPTR_HASH
#undef MEMBER_LITERAL_HASH



static bool UnitIsBusy(const CCommandAI* cai) {
// queued move-commands (or active build/repair/etc-commands) mean unit has to stay airborne
return (cai->inCommand || cai->HasMoreMoveCommands(false));
Expand Down Expand Up @@ -1128,34 +1154,9 @@ bool CHoverAirMoveType::SetMemberValue(unsigned int memberHash, void* memberValu
if (AMoveType::SetMemberValue(memberHash, memberValue))
return true;

#define MEMBER_CHARPTR_HASH(memberName) HsiehHash(memberName, strlen(memberName), 0)
#define MEMBER_LITERAL_HASH(memberName) HsiehHash(memberName, sizeof(memberName) - 1, 0)

#define DONTLAND_MEMBER_IDX 1
#define WANTEDHEIGHT_MEMBER_IDX 0

static const unsigned int boolMemberHashes[] = {
MEMBER_LITERAL_HASH( "collide"),
MEMBER_LITERAL_HASH( "dontLand"),
MEMBER_LITERAL_HASH( "airStrafe"),
MEMBER_LITERAL_HASH( "useSmoothMesh"),
MEMBER_LITERAL_HASH("bankingAllowed"),
};
static const unsigned int floatMemberHashes[] = {
MEMBER_LITERAL_HASH( "wantedHeight"),
MEMBER_LITERAL_HASH( "accRate"),
MEMBER_LITERAL_HASH( "decRate"),
MEMBER_LITERAL_HASH( "turnRate"),
MEMBER_LITERAL_HASH( "altitudeRate"),
MEMBER_LITERAL_HASH( "currentBank"),
MEMBER_LITERAL_HASH( "currentPitch"),
MEMBER_LITERAL_HASH( "maxDrift"),
};

#undef MEMBER_CHARPTR_HASH
#undef MEMBER_LITERAL_HASH


// unordered_map etc. perform dynallocs, so KISS here
bool* boolMemberPtrs[] = {
&collide,
Expand All @@ -1181,25 +1182,25 @@ bool CHoverAirMoveType::SetMemberValue(unsigned int memberHash, void* memberValu
};

// special cases
if (memberHash == boolMemberHashes[DONTLAND_MEMBER_IDX]) {
if (memberHash == BOOL_MEMBER_HASHES[DONTLAND_MEMBER_IDX]) {
SetAllowLanding(!(*(reinterpret_cast<bool*>(memberValue))));
return true;
}
if (memberHash == floatMemberHashes[WANTEDHEIGHT_MEMBER_IDX]) {
if (memberHash == FLOAT_MEMBER_HASHES[WANTEDHEIGHT_MEMBER_IDX]) {
SetDefaultAltitude(*(reinterpret_cast<float*>(memberValue)));
return true;
}

// note: <memberHash> should be calculated via HsiehHash
for (unsigned int n = 0; n < sizeof(boolMemberPtrs) / sizeof(boolMemberPtrs[0]); n++) {
if (memberHash == boolMemberHashes[n]) {
if (memberHash == BOOL_MEMBER_HASHES[n]) {
*(boolMemberPtrs[n]) = *(reinterpret_cast<bool*>(memberValue));
return true;
}
}

for (unsigned int n = 0; n < sizeof(floatMemberPtrs) / sizeof(floatMemberPtrs[0]); n++) {
if (memberHash == floatMemberHashes[n]) {
if (memberHash == FLOAT_MEMBER_HASHES[n]) {
*(floatMemberPtrs[n]) = *(reinterpret_cast<float*>(memberValue));
return true;
}
Expand Down
59 changes: 41 additions & 18 deletions rts/Sim/MoveTypes/MoveType.cpp
Expand Up @@ -11,23 +11,47 @@
#include "System/myMath.h"
#include "System/Sync/HsiehHash.h"


CR_BIND_DERIVED_INTERFACE(AMoveType, CObject)
CR_REG_METADATA(AMoveType, (
CR_MEMBER(owner),
CR_MEMBER(goalPos),
CR_MEMBER(oldPos),
CR_MEMBER(oldSlowUpdatePos),

CR_MEMBER(progressState),

CR_MEMBER(maxSpeed),
CR_MEMBER(maxSpeedDef),
CR_MEMBER(maxWantedSpeed),
CR_MEMBER(maneuverLeash),
CR_MEMBER(waterline),

CR_MEMBER(useHeading),
CR_MEMBER(progressState)
CR_MEMBER(useWantedSpeed)
))



#define MEMBER_CHARPTR_HASH(memberName) HsiehHash(memberName, strlen(memberName), 0)
#define MEMBER_LITERAL_HASH(memberName) HsiehHash(memberName, sizeof(memberName) - 1, 0)

static const unsigned int BOOL_MEMBER_HASHES[] = {
MEMBER_LITERAL_HASH("useWantedSpeed[0]"), // individual
MEMBER_LITERAL_HASH("useWantedSpeed[1]"), // formation
};
static const unsigned int FLOAT_MEMBER_HASHES[] = {
MEMBER_LITERAL_HASH( "maxSpeed"),
MEMBER_LITERAL_HASH( "maxWantedSpeed"),
MEMBER_LITERAL_HASH( "maneuverLeash"),
MEMBER_LITERAL_HASH( "waterline"),
};

#undef MEMBER_CHARPTR_HASH
#undef MEMBER_LITERAL_HASH



AMoveType::AMoveType(CUnit* owner):
owner(owner),

Expand Down Expand Up @@ -86,46 +110,45 @@ float AMoveType::CalcStaticTurnRadius() const {


bool AMoveType::SetMemberValue(unsigned int memberHash, void* memberValue) {
#define MEMBER_CHARPTR_HASH(memberName) HsiehHash(memberName, strlen(memberName), 0)
#define MEMBER_LITERAL_HASH(memberName) HsiehHash(memberName, sizeof(memberName) - 1, 0)

#define MAXSPEED_MEMBER_IDX 0
#define MAXWANTEDSPEED_MEMBER_IDX 1
#define MANEUVERLEASH_MEMBER_IDX 2
#define WATERLINE_MEMBER_IDX 3

static const unsigned int floatMemberHashes[] = {
MEMBER_LITERAL_HASH( "maxSpeed"),
MEMBER_LITERAL_HASH( "maxWantedSpeed"),
MEMBER_LITERAL_HASH( "maneuverLeash"),
MEMBER_LITERAL_HASH( "waterline"),
bool* boolMemberPtrs[] = {
&useWantedSpeed[false],
&useWantedSpeed[ true],
};

#undef MEMBER_CHARPTR_HASH
#undef MEMBER_LITERAL_HASH

/*
#if 0
// unordered_map etc. perform dynallocs, so KISS here
float* floatMemberPtrs[] = {
&maxSpeed,
&maxWantedSpeed,
};
*/
#endif

for (size_t n = 0; n < sizeof(boolMemberPtrs) / sizeof(boolMemberPtrs[0]); n++) {
if (memberHash == BOOL_MEMBER_HASHES[n]) {
*(boolMemberPtrs[n]) = *(reinterpret_cast<bool*>(memberValue));
return true;
}
}

// special cases
if (memberHash == floatMemberHashes[MAXSPEED_MEMBER_IDX]) {
if (memberHash == FLOAT_MEMBER_HASHES[MAXSPEED_MEMBER_IDX]) {
SetMaxSpeed((*reinterpret_cast<float*>(memberValue)) / GAME_SPEED);
return true;
}
if (memberHash == floatMemberHashes[MAXWANTEDSPEED_MEMBER_IDX]) {
if (memberHash == FLOAT_MEMBER_HASHES[MAXWANTEDSPEED_MEMBER_IDX]) {
SetWantedMaxSpeed((*reinterpret_cast<float*>(memberValue)) / GAME_SPEED);
return true;
}
if (memberHash == floatMemberHashes[MANEUVERLEASH_MEMBER_IDX]) {
if (memberHash == FLOAT_MEMBER_HASHES[MANEUVERLEASH_MEMBER_IDX]) {
SetManeuverLeash(*reinterpret_cast<float*>(memberValue));
return true;
}
if (memberHash == floatMemberHashes[WATERLINE_MEMBER_IDX]) {
if (memberHash == FLOAT_MEMBER_HASHES[WATERLINE_MEMBER_IDX]) {
SetWaterline(*reinterpret_cast<float*>(memberValue));
return true;
}
Expand Down
15 changes: 9 additions & 6 deletions rts/Sim/MoveTypes/MoveType.h
Expand Up @@ -60,6 +60,8 @@ class AMoveType : public CObject
bool UseHeading( ) const { return (useHeading ); }
bool UseHeading(bool b) { return (useHeading = b); }

bool UseWantedSpeed(bool groupOrder) const { return useWantedSpeed[groupOrder]; }

float GetMaxSpeed() const { return maxSpeed; }
float GetMaxSpeedDef() const { return maxSpeedDef; }
float GetMaxWantedSpeed() const { return maxWantedSpeed; }
Expand All @@ -83,8 +85,8 @@ class AMoveType : public CObject
CUnit* owner;

float3 goalPos;
float3 oldPos; // owner position at last Update()
float3 oldSlowUpdatePos; // owner position at last SlowUpdate()
float3 oldPos; // owner position at last Update()
float3 oldSlowUpdatePos; // owner position at last SlowUpdate()

enum ProgressState {
Done = 0,
Expand All @@ -94,14 +96,15 @@ class AMoveType : public CObject
ProgressState progressState = Done;

protected:
float maxSpeed; // current maximum speed owner is allowed to reach (changes with eg. guard orders)
float maxSpeedDef; // default maximum speed owner can reach (as defined by its UnitDef, never changes)
float maxWantedSpeed; // maximum speed (temporarily) set by a CommandAI
float maxSpeed; // current maximum speed owner is allowed to reach (changes with eg. guard orders)
float maxSpeedDef; // default maximum speed owner can reach (as defined by its UnitDef, never changes)
float maxWantedSpeed; // maximum speed (temporarily) set by a CommandAI

float maneuverLeash; // maximum distance away a target can be and still be chased
float maneuverLeash; // maximum distance before target stops being chased
float waterline;

bool useHeading = true;
bool useWantedSpeed[2] = {true, true}; // if false, SelUnitsAI will not (re)set wanted-speed for {[0] := individual, [1] := formation} orders
};

#endif // MOVETYPE_H
5 changes: 4 additions & 1 deletion rts/Sim/MoveTypes/StaticMoveType.h
Expand Up @@ -10,7 +10,10 @@ class CStaticMoveType : public AMoveType
CR_DECLARE_DERIVED(CStaticMoveType)

public:
CStaticMoveType(CUnit* unit) : AMoveType(unit) {}
CStaticMoveType(CUnit* unit) : AMoveType(unit) {
useWantedSpeed[false] = false;
useWantedSpeed[ true] = false;
}

void StartMoving(float3 pos, float goalRadius) override {}
void StartMoving(float3 pos, float goalRadius, float speed) override {}
Expand Down
16 changes: 8 additions & 8 deletions rts/Sim/Units/CommandAI/CommandAI.cpp
Expand Up @@ -1206,23 +1206,22 @@ void CCommandAI::ExecuteRemove(const Command& c)
// the removal may have corrupted the iterator
break;
}
}
while (ci != queue->end());
} while (ci != queue->end());
}

repeatOrders = prevRepeat;
}


bool CCommandAI::WillCancelQueued(const Command& c)
bool CCommandAI::WillCancelQueued(const Command& c) const
{
return (GetCancelQueued(c, commandQue) != commandQue.end());
}


CCommandQueue::iterator CCommandAI::GetCancelQueued(const Command& c, CCommandQueue& q)
CCommandQueue::const_iterator CCommandAI::GetCancelQueued(const Command& c, const CCommandQueue& q) const
{
CCommandQueue::iterator ci = q.end();
CCommandQueue::const_iterator ci = q.end();

while (ci != q.begin()) {
--ci; //iterate from the end and dont check the current order
Expand All @@ -1243,8 +1242,8 @@ CCommandQueue::iterator CCommandAI::GetCancelQueued(const Command& c, CCommandQu
}
else if (c.GetNumParams() >= 3) {
if (cmdID < 0) {
BuildInfo bc1(c);
BuildInfo bc2(c2);
const BuildInfo bc1(c);
const BuildInfo bc2(c2);

if (bc1.def == nullptr) continue;
if (bc2.def == nullptr) continue;
Expand Down Expand Up @@ -1279,7 +1278,8 @@ int CCommandAI::CancelCommands(const Command& c, CCommandQueue& q, bool& first)
int cancelCount = 0;

while (true) {
CCommandQueue::iterator ci = GetCancelQueued(c, q);
CCommandQueue::const_iterator cci = GetCancelQueued(c, q);
CCommandQueue::iterator ci = q.begin() + (cci - q.begin());

if (ci == q.end())
return cancelCount;
Expand Down

0 comments on commit 39d5e92

Please sign in to comment.