Skip to content

Commit

Permalink
Allow adding/removing builder/factory build options dynamically. It m…
Browse files Browse the repository at this point in the history
…ight not take into account some corner cases related to the use case. Should be harmless otherwise.
  • Loading branch information
lhog committed Jun 10, 2023
1 parent 175932f commit 5bb1f00
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
64 changes: 61 additions & 3 deletions rts/Sim/Units/CommandAI/CommandAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ void CCommandAI::UpdateCommandDescription(unsigned int cmdDescIdx, SCommandDescr
if (!curCmdDesc->queueing)
nonQueingCommands.erase(curCmdDesc->id);

const bool boUpdate = (curCmdDesc->id != modCmdDesc.id);

if (boUpdate)
HandleBuildOptionRemoval(curCmdDesc->id);

// re-insert otherwise (possibly with a different cmdID!)
if (!modCmdDesc.queueing)
nonQueingCommands.insert(modCmdDesc.id);
Expand All @@ -402,6 +407,9 @@ void CCommandAI::UpdateCommandDescription(unsigned int cmdDescIdx, SCommandDescr
// update
possibleCommands[cmdDescIdx] = commandDescriptionCache.GetPtr(std::move(modCmdDesc));

if (boUpdate)
HandleBuildOptionInsertion(possibleCommands[cmdDescIdx]->id);

selectedUnitsHandler.PossibleCommandChange(owner);
}

Expand All @@ -416,6 +424,8 @@ void CCommandAI::InsertCommandDescription(unsigned int cmdDescIdx, SCommandDescr
possibleCommands.insert(possibleCommands.begin() + cmdDescIdx, cmdDescPtr);
}

HandleBuildOptionInsertion(cmdDescPtr->id < 0);

// NB: cmdDesc is moved into cache, but id remains valid
if (!cmdDesc.queueing)
nonQueingCommands.insert(cmdDesc.id);
Expand All @@ -428,10 +438,14 @@ bool CCommandAI::RemoveCommandDescription(unsigned int cmdDescIdx)
if (cmdDescIdx >= possibleCommands.size())
return false;

if (!possibleCommands[cmdDescIdx]->queueing)
nonQueingCommands.erase(possibleCommands[cmdDescIdx]->id);
const auto* cmdDescPtr = possibleCommands[cmdDescIdx];

commandDescriptionCache.DecRef(*possibleCommands[cmdDescIdx]);
HandleBuildOptionRemoval(cmdDescPtr->id);

if (!cmdDescPtr->queueing)
nonQueingCommands.erase(cmdDescPtr->id);

commandDescriptionCache.DecRef(*cmdDescPtr);
// preserve order
possibleCommands.erase(possibleCommands.begin() + cmdDescIdx);
selectedUnitsHandler.PossibleCommandChange(owner);
Expand Down Expand Up @@ -476,6 +490,50 @@ void CCommandAI::AddCommandDependency(const Command& c) {
}


bool CCommandAI::HandleBuildOptionInsertion(int cmdId)
{
if (cmdId >= 0)
return false;

if (auto* bcai = dynamic_cast<CBuilderCAI*>(this); bcai != nullptr)
bcai->buildOptions.insert(cmdId);
else if (auto* fcai = dynamic_cast<CFactoryCAI*>(this); fcai != nullptr)
fcai->buildOptions.insert(cmdId, 0);

return true;
}

bool CCommandAI::HandleBuildOptionRemoval(int cmdId)
{
if (cmdId >= 0)
return false;

if (cmdId < 0) {
if (auto* bcai = dynamic_cast<CBuilderCAI*>(this); bcai != nullptr) {
// clear the removed unitDef from the construction queue
for (size_t i = 0; i < bcai->commandQue.size(); /*NOOP*/) {
if (const auto& q = bcai->commandQue[i]; q.GetID() == cmdId)
bcai->commandQue.erase(commandQue.begin() + i);
else
++i;
}
bcai->buildOptions.erase(cmdId);
}
else if (auto* fcai = dynamic_cast<CFactoryCAI*>(this); fcai != nullptr) {
// clear the removed unitDef from the construction queue
for (size_t i = 0; i < fcai->commandQue.size(); /*NOOP*/) {
if (const auto& q = fcai->commandQue[i]; q.GetID() == cmdId)
fcai->commandQue.erase(commandQue.begin() + i);
else
++i;
}
fcai->buildOptions.erase(cmdId);
}
}

return true;
}

bool CCommandAI::IsAttackCapable() const
{
return (owner->unitDef->CanAttack());
Expand Down
2 changes: 2 additions & 0 deletions rts/Sim/Units/CommandAI/CommandAI.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class CCommandAI : public CObject
int lastSelectedCommandPage;

protected:
bool HandleBuildOptionInsertion(int cmdId);
bool HandleBuildOptionRemoval(int cmdId);
// return true by default so non-AirCAI's trigger FinishCommand
virtual bool SelectNewAreaAttackTargetOrPos(const Command& ac) { return true; }

Expand Down

0 comments on commit 5bb1f00

Please sign in to comment.