Permalink
Browse files

fix #6065

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
rt committed Nov 16, 2018
1 parent 4d798fb commit f2746effb4a091054aa2f1797376f37ff3451bcc
@@ -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);
}
@@ -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;
@@ -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);
@@ -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++;
@@ -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));
@@ -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,
@@ -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;
}
@@ -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),
@@ -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;
}
@@ -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; }
@@ -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,
@@ -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
@@ -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 {}
@@ -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
@@ -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;
@@ -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;
Oops, something went wrong.

0 comments on commit f2746ef

Please sign in to comment.