Build magma pump on right-click
If the player selects an engineer and right-clicks on a hot spot, order the engineer to build a magma pump there. More generally, try to build something on top of the clicked unit.
This commit is contained in:
parent
8989c431f5
commit
81dd5ca909
4 changed files with 77 additions and 3 deletions
|
@ -134,8 +134,6 @@ static std::vector<CUnitType *> getReparableUnits()
|
|||
*/
|
||||
static void InitAiHelper(AiHelper &aiHelper)
|
||||
{
|
||||
extern std::vector<ButtonAction *> UnitButtonTable;
|
||||
|
||||
std::vector<CUnitType *> reparableUnits = getReparableUnits();
|
||||
|
||||
for (int i = 0; i < (int)UnitButtonTable.size(); ++i)
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
-- Declarations
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "icons.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
@ -221,6 +222,9 @@ extern int DoubleClickDelay;
|
|||
/// Time to detect hold clicks
|
||||
extern int HoldClickDelay;
|
||||
|
||||
/// All buttons for units
|
||||
extern std::vector<ButtonAction *> UnitButtonTable;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
@ -347,6 +351,8 @@ extern void DrawTimer(void);
|
|||
extern void UpdateTimer(void);
|
||||
/// Update the status line with hints from the button
|
||||
extern void UpdateStatusLineForButton(const ButtonAction *button);
|
||||
/// Check if the button is allowed for the unit.
|
||||
extern bool IsButtonAllowed(const CUnit *, const ButtonAction *);
|
||||
/// Draw the Pie Menu
|
||||
extern void DrawPieMenu(void);
|
||||
|
||||
|
|
|
@ -508,7 +508,7 @@ void UpdateStatusLineForButton(const ButtonAction *button)
|
|||
**
|
||||
** @todo FIXME: better check. (dependancy, resource, ...)
|
||||
*/
|
||||
static bool IsButtonAllowed(const CUnit *unit, const ButtonAction *buttonaction)
|
||||
bool IsButtonAllowed(const CUnit *unit, const ButtonAction *buttonaction)
|
||||
{
|
||||
bool res;
|
||||
|
||||
|
|
70
ui/mouse.cpp
70
ui/mouse.cpp
|
@ -94,6 +94,70 @@ void CancelBuildingMode(void)
|
|||
UI.ButtonPanel.Update();
|
||||
}
|
||||
|
||||
/**
|
||||
** Check whether ButtonAction::UnitMask includes the specified unit
|
||||
** type. If not, the user cannot click that button to give an order
|
||||
** to units of that type.
|
||||
**
|
||||
** Even if this function returns true, the button may still be
|
||||
** disabled for other reasons; call ::IsButtonAllowed to check those.
|
||||
*/
|
||||
static bool IsButtonAllowedForUnitType(const CUnitType *type, const ButtonAction *button)
|
||||
{
|
||||
return button->UnitMask == "*"
|
||||
|| button->UnitMask.find(',' + type->Ident + ',') != std::string::npos;
|
||||
}
|
||||
|
||||
/**
|
||||
** Find the unit type that @a builder could build on top of @a base.
|
||||
**
|
||||
** @param builder The unit who would like to build something.
|
||||
** @param base The building would go on top of this unit.
|
||||
**
|
||||
** If nothing can be built there, or is not clear which type of unit
|
||||
** should be built, this function returns NULL.
|
||||
*/
|
||||
static CUnitType *CanBuildSomethingOnTop(const CUnit *builder, const CUnit *base)
|
||||
{
|
||||
// This check should in principle be in DoRightButton,
|
||||
// but doing it here is easier.
|
||||
if (base == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CUnitType *foundType = NULL;
|
||||
for (std::vector<ButtonAction *>::const_iterator
|
||||
iterator = UnitButtonTable.begin();
|
||||
iterator != UnitButtonTable.end(); ++iterator) {
|
||||
const ButtonAction *const button = *iterator;
|
||||
if (button->Action == ButtonBuild
|
||||
&& IsButtonAllowedForUnitType(builder->Type, button)
|
||||
&& IsButtonAllowed(builder, button))
|
||||
{
|
||||
// Which type of unit the player could build
|
||||
// by clicking this button.
|
||||
CUnitType *const buildingType = UnitTypes.at(button->Value);
|
||||
if (CanBuildHere(builder, buildingType, base->X, base->Y) == base)
|
||||
{
|
||||
// buildingType can be built on top of base.
|
||||
// But is it unambiguous?
|
||||
if (foundType != NULL && buildingType != foundType)
|
||||
{
|
||||
// Oops, we already found a different
|
||||
// type that could be built here.
|
||||
// Better return neither.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
foundType = buildingType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return foundType;
|
||||
}
|
||||
|
||||
/**
|
||||
** Called when right button is pressed
|
||||
**
|
||||
|
@ -263,6 +327,12 @@ void DoRightButton(int sx, int sy)
|
|||
SendCommandFollow(unit, dest, flush);
|
||||
continue;
|
||||
}
|
||||
// Build on top of the clicked unit
|
||||
CUnitType *buildingType = CanBuildSomethingOnTop(unit, dest);
|
||||
if (buildingType != NULL) {
|
||||
SendCommandBuildBuilding(unit, dest->X, dest->Y, buildingType, flush);
|
||||
continue;
|
||||
}
|
||||
// Move
|
||||
SendCommandMove(unit, x, y, flush);
|
||||
continue;
|
||||
|
|
Loading…
Add table
Reference in a new issue