Allow designing and building obsolete tanks.

Since you sometimes might want to a bunch of cheap MG tanks as a decoy, even if you have twin AG researched.

Also, remove an unrelated uselessly-duplicated test in action.cpp.
master
Cyp 2013-05-21 20:48:17 +02:00
parent 5625def655
commit 714727e241
22 changed files with 218 additions and 151 deletions

View File

@ -344,6 +344,12 @@
0,0,image_vdp_down.png
0,0,image_vdp_up.png
-1,-1,image_vdp_hi.png
0,0,image_obsolete_hide_up.png
0,0,image_obsolete_hide_down.png
-1,-1,image_obsolete_hide_hi.png
0,0,image_obsolete_show_up.png
0,0,image_obsolete_show_down.png
-1,-1,image_obsolete_show_hi.png
0,0,image_gn_star.png
0,0,image_gn_15.png
0,0,image_gn_14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

View File

@ -192,20 +192,20 @@ void W_BUTTON::display(int xOffset, int yOffset)
bool isHighlight = (state & WBUT_HIGHLIGHT) != 0;
// Display the button.
if (!image.isNull())
if (!images.normal.isNull())
{
iV_DrawImage(image, x0, y0);
if (isDown && !imageDown.isNull())
iV_DrawImage(images.normal, x0, y0);
if (isDown && !images.down.isNull())
{
iV_DrawImage(imageDown, x0, y0);
iV_DrawImage(images.down, x0, y0);
}
if (isDisabled && !imageDisabled.isNull())
if (isDisabled && !images.disabled.isNull())
{
iV_DrawImage(imageDisabled, x0, y0);
iV_DrawImage(images.disabled, x0, y0);
}
if (isHighlight && !imageHighlight.isNull())
if (isHighlight && !images.highlighted.isNull())
{
iV_DrawImage(imageHighlight, x0, y0);
iV_DrawImage(images.highlighted, x0, y0);
}
}
else
@ -238,21 +238,66 @@ void W_BUTTON::display(int xOffset, int yOffset)
iV_DrawText(textBytes.constData(), fx, fy);
}
if (isDisabled && !image.isNull() && imageDisabled.isNull())
if (isDisabled && !images.normal.isNull() && images.disabled.isNull())
{
// disabled, render something over it!
iV_TransBoxFill(x0, y0, x0 + width(), y0 + height());
}
}
void W_BUTTON::setImages(Image image_, Image imageDown_, Image imageHighlight_, Image imageDisabled_)
void W_BUTTON::setImages(Images const &images_)
{
image = image_;
imageDown = imageDown_;
imageDisabled = imageDisabled_;
imageHighlight = imageHighlight_;
if (!image.isNull())
images = images_;
if (!images.normal.isNull())
{
setGeometry(x(), y(), image.width(), image.height());
setGeometry(x(), y(), images.normal.width(), images.normal.height());
}
}
void W_BUTTON::setImages(Image image, Image imageDown, Image imageHighlight, Image imageDisabled)
{
setImages(Images(image, imageDown, imageHighlight, imageDisabled));
}
void StateButton::setState(int state)
{
if (currentState == state)
{
return;
}
currentState = state;
std::map<int, Images>::const_iterator image = imageSets.find(state);
if (image != imageSets.end())
{
W_BUTTON::setImages(image->second);
}
std::map<int, QString>::const_iterator tip = tips.find(state);
if (tip != tips.end())
{
W_BUTTON::setTip(tip->second);
}
}
void StateButton::setTip(int state, QString string)
{
tips[state] = string;
if (currentState == state)
{
W_BUTTON::setTip(string);
}
}
void StateButton::setTip(int state, char const *stringUtf8)
{
setTip(state, QString::fromUtf8(stringUtf8));
}
void StateButton::setImages(int state, Images const &images)
{
imageSets[state] = images;
if (currentState == state)
{
W_BUTTON::setImages(images);
}
}

View File

@ -26,13 +26,25 @@
#include "widget.h"
#include "widgbase.h"
#include "lib/ivis_opengl/textdraw.h"
#include <map>
class W_BUTTON : public WIDGET
{
Q_OBJECT
public:
struct Images
{
Images() {}
Images(Image normal, Image down, Image highlighted, Image disabled = Image()) : normal(normal), down(down), highlighted(highlighted), disabled(disabled) {}
Image normal; ///< The image for the button.
Image down; ///< The image for the button, when down. Is overlaid over image.
Image highlighted; ///< The image for the button, when highlighted. Is overlaid over image.
Image disabled; ///< The image for the button, when disabled. Is overlaid over image.
};
public:
W_BUTTON(W_BUTINIT const *init);
W_BUTTON(WIDGET *parent);
@ -50,6 +62,7 @@ public:
void setString(QString string);
void setTip(QString string);
void setImages(Images const &images);
void setImages(Image image, Image imageDown, Image imageHighlight, Image imageDisabled = Image());
void setString(char const *stringUtf8) { WIDGET::setString(stringUtf8); } // Unhide the WIDGET::setString(char const *) function...
@ -61,10 +74,7 @@ signals:
public:
UDWORD state; // The current button state
QString pText; // The text for the button
Image image; ///< The image for the button.
Image imageDown; ///< The image for the button, when down. Is overlaid over image.
Image imageDisabled; ///< The image for the button, when disabled. Is overlaid over image.
Image imageHighlight; ///< The image for the button, when highlighted. Is overlaid over image.
Images images; ///< The images for the button.
QString pTip; // The tool tip for the button
SWORD HilightAudioID; // Audio ID for form clicked sound
SWORD ClickedAudioID; // Audio ID for form hilighted sound
@ -72,4 +82,21 @@ public:
iV_fonts FontID;
};
class StateButton : public W_BUTTON
{
Q_OBJECT
public:
StateButton(WIDGET *parent) : W_BUTTON(parent) {}
void setState(int state);
void setTip(int state, QString string);
void setTip(int state, char const *stringUtf8);
void setImages(int state, Images const &images);
private:
int currentState;
std::map<int, QString> tips;
std::map<int, Images> imageSets;
};
#endif // __INCLUDED_LIB_WIDGET_BUTTON_H__

View File

@ -42,6 +42,8 @@ class W_BARGRAPH;
class W_BUTTON;
class W_LABEL;
class W_SLIDER;
class StateButton;
class ListWidget;
/* The display function prototype */
typedef void (*WIDGET_DISPLAY)(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset);

View File

@ -671,7 +671,7 @@ static bool actionRemoveDroidsFromBuildPos(unsigned player, Vector2i pos, uint16
void actionSanity(DROID *psDroid)
{
// Don't waste ammo unless given a direct attack order.
bool avoidOverkill = psDroid->order.type != DORDER_ATTACK && psDroid->order.type != DORDER_ATTACK &&
bool avoidOverkill = psDroid->order.type != DORDER_ATTACK &&
(psDroid->action == DACTION_ATTACK || psDroid->action == DACTION_MOVEFIRE || psDroid->action == DACTION_MOVETOATTACK ||
psDroid->action == DACTION_ROTATETOATTACK || psDroid->action == DACTION_VTOLATTACK);

View File

@ -150,7 +150,7 @@ char StringBuffer[STRING_BUFFER_SIZE];
#define DES_LEFTFORMX RET_X
#define DES_LEFTFORMY DESIGN_Y
#define DES_LEFTFORMWIDTH RET_FORMWIDTH
#define DES_LEFTFORMHEIGHT 258
#define DES_LEFTFORMHEIGHT 273
#define DES_LEFTFORMBUTX 2
#define DES_LEFTFORMBUTY 2
@ -245,7 +245,7 @@ static bool intAddTemplateButtons(ListTabWidget *templList, DROID_TEMPLATE *psSe
static void intDisplayDesignForm(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset);
/* Set the current mode of the design screen, and display the appropriate component lists */
static void intSetDesignMode(DES_COMPMODE newCompMode);
static void intSetDesignMode(DES_COMPMODE newCompMode, bool forceRefresh = false);
/* Set all the design bar graphs from a design template */
static void intSetDesignStats(DROID_TEMPLATE *psTemplate);
/* Set up the system clickable form of the design screen given a set of stats */
@ -351,7 +351,7 @@ extern bool bRender3DOnly;
/* Add the design widgets to the widget screen */
static bool _intAddDesign(bool bShowCentreScreen)
bool intAddDesign(bool bShowCentreScreen)
{
W_FORMINIT sFormInit;
W_LABINIT sLabInit;
@ -777,7 +777,7 @@ void desSetupDesignTemplates(void)
psTempl->droidType != DROID_CYBORG_CONSTRUCT &&
psTempl->droidType != DROID_CYBORG_REPAIR &&
psTempl->droidType != DROID_PERSON &&
researchedTemplate(psTempl, selectedPlayer))
researchedTemplate(psTempl, selectedPlayer, includeRedundantDesigns))
{
apsTemplateList.push_back(psTempl);
}
@ -785,21 +785,24 @@ void desSetupDesignTemplates(void)
}
/* Add the design template form */
static bool _intAddTemplateForm(DROID_TEMPLATE *psSelected)
static bool intAddTemplateForm(DROID_TEMPLATE *psSelected)
{
WIDGET *parent = psWScreen->psForm;
/* add a form to place the tabbed form on */
IntFormAnimated *templbaseForm = new IntFormAnimated(parent, false);
templbaseForm->id = IDDES_TEMPLBASE;
templbaseForm->setGeometry(RET_X, DESIGN_Y, RET_FORMWIDTH, DES_LEFTFORMHEIGHT + 4);
templbaseForm->setGeometry(RET_X, DESIGN_Y, RET_FORMWIDTH, DES_LEFTFORMHEIGHT);
// Add the obsolete items button.
makeObsoleteButton(templbaseForm);
/* Add the design templates form */
IntListTabWidget *templList = new IntListTabWidget(templbaseForm);
templList->setChildSize(DES_TABBUTWIDTH, DES_TABBUTHEIGHT);
templList->setChildSpacing(DES_TABBUTGAP, DES_TABBUTGAP);
int templListWidth = OBJ_BUTWIDTH*2 + DES_TABBUTGAP;
templList->setGeometry((RET_FORMWIDTH - templListWidth)/2, 2, templListWidth, templbaseForm->height() - 2);
templList->setGeometry((RET_FORMWIDTH - templListWidth)/2, 18, templListWidth, templbaseForm->height() - 18);
/* Put the buttons on it */
return intAddTemplateButtons(templList, psSelected);
@ -878,11 +881,11 @@ static bool intAddTemplateButtons(ListTabWidget *templList, DROID_TEMPLATE *psSe
* component lists
* added case IDES_TURRET_A,IDES_TURRET_B
*/
static void intSetDesignMode(DES_COMPMODE newCompMode)
static void intSetDesignMode(DES_COMPMODE newCompMode, bool forceRefresh)
{
UDWORD weaponIndex;
if (newCompMode == desCompMode)
if (newCompMode == desCompMode && !forceRefresh)
{
return;
}
@ -1141,7 +1144,7 @@ static void intSetDesignStats(DROID_TEMPLATE *psTemplate)
}
/* Set up the system clickable form of the design screen given a set of stats */
static bool _intSetSystemForm(COMPONENT_STATS *psStats)
static bool intSetSystemForm(COMPONENT_STATS *psStats)
{
DES_SYSMODE newSysMode = (DES_SYSMODE)0;
@ -1709,7 +1712,7 @@ static ListTabWidget *intAddComponentForm()
/* add a form to place the tabbed form on */
IntFormAnimated *rightBase = new IntFormAnimated(parent, false);
rightBase->id = IDDES_RIGHTBASE;
rightBase->setGeometry(RADTLX - 2, DESIGN_Y, RET_FORMWIDTH, DES_RIGHTFORMHEIGHT + 4);
rightBase->setGeometry(RADTLX - 2, DESIGN_Y, RET_FORMWIDTH, DES_RIGHTFORMHEIGHT);
//now a single form
IntListTabWidget *compList = new IntListTabWidget(rightBase);
@ -1849,7 +1852,7 @@ static bool intAddComponentButtons(ListTabWidget *compList, COMPONENT_STATS *psS
}
/* Skip unavailable entries and non-design ones*/
if (!(aAvailable[i] & AVAILABLE) || !psCurrStats->designable)
if (!(aAvailable[i] == AVAILABLE || (includeRedundantDesigns && aAvailable[i] == REDUNDANT)) || !psCurrStats->designable)
{
/* Update the stats pointer for the next button */
psCurrStats = (COMPONENT_STATS *)(((UBYTE *)psCurrStats) + size);
@ -1980,8 +1983,7 @@ static bool intAddExtraSystemButtons(ListTabWidget *compList, unsigned sensorInd
}
// Skip unavailable entries or non-design ones
if (!(aAvailable[i] & AVAILABLE)
|| !psCurrStats->designable)
if (!(aAvailable[i] == AVAILABLE || (includeRedundantDesigns && aAvailable[i] == REDUNDANT)) || !psCurrStats->designable)
{
// Update the stats pointer for the next button
psCurrStats = (COMPONENT_STATS *)(((UBYTE *)psCurrStats) + size);
@ -3687,6 +3689,26 @@ void intProcessDesign(UDWORD id)
widgHide(psWScreen, IDDES_BODYFORM);
widgReveal(psWScreen, IDDES_PROPFORM);
break;
case IDSTAT_OBSOLETE_BUTTON:
includeRedundantDesigns = !includeRedundantDesigns;
StateButton *obsoleteButton = (StateButton *)widgGetFromID(psWScreen, IDSTAT_OBSOLETE_BUTTON);
obsoleteButton->setState(includeRedundantDesigns);
// Refresh lists.
if (droidTemplID != IDDES_TEMPLSTART)
{
intRemoveDesign();
intAddDesign(false);
}
else
{
desSetupDesignTemplates();
widgDelete(psWScreen, IDDES_TEMPLBASE);
intAddTemplateForm(templateFromButtonId(droidTemplID));
intSetDesignMode(desCompMode, true);
droidTemplID = IDDES_TEMPLSTART;
widgSetButtonState(psWScreen, droidTemplID, WBUT_LOCK);
}
break;
}
}
@ -4134,24 +4156,6 @@ static bool intCheckValidWeaponForProp(void)
return checkValidWeaponForProp(&sCurrDesign);
}
bool intAddDesign(bool bShowCentreScreen)
{
return _intAddDesign(bShowCentreScreen);
}
/* Set up the system clickable form of the design screen given a set of stats */
static bool intSetSystemForm(COMPONENT_STATS *psStats)
{
return _intSetSystemForm(psStats);
}
static bool intAddTemplateForm(DROID_TEMPLATE *psSelected)
{
return _intAddTemplateForm(psSelected);
}
//checks if the template has PROPULSION_TYPE_LIFT propulsion attached - returns true if it does
bool checkTemplateIsVtol(DROID_TEMPLATE *psTemplate)
{

View File

@ -48,6 +48,7 @@
#include "lib/sound/audio.h"
#include "lib/widget/label.h"
#include "lib/widget/bar.h"
#include "lib/widget/button.h"
#include "console.h"
#include "design.h"
#include "display.h"
@ -2235,6 +2236,13 @@ static void intProcessStats(UDWORD id)
}
}
}
else if (id == IDSTAT_OBSOLETE_BUTTON)
{
includeRedundantDesigns = !includeRedundantDesigns;
StateButton *obsoleteButton = (StateButton *)widgGetFromID(psWScreen, IDSTAT_OBSOLETE_BUTTON);
obsoleteButton->setState(includeRedundantDesigns);
intRefreshScreen();
}
}
@ -3624,6 +3632,20 @@ static void intSetStats(UDWORD id, BASE_STATS *psStats)
}
}
StateButton *makeObsoleteButton(WIDGET *parent)
{
StateButton *obsoleteButton = new StateButton(parent);
obsoleteButton->id = IDSTAT_OBSOLETE_BUTTON;
obsoleteButton->style |= WBUT_SECONDARY;
obsoleteButton->setState(includeRedundantDesigns);
obsoleteButton->setImages(false, StateButton::Images(Image(IntImages, IMAGE_OBSOLETE_HIDE_UP), Image(IntImages, IMAGE_OBSOLETE_HIDE_DOWN), Image(IntImages, IMAGE_OBSOLETE_HIDE_HI)));
obsoleteButton->setTip(false, _("Hiding Obsolete Tech"));
obsoleteButton->setImages(true, StateButton::Images(Image(IntImages, IMAGE_OBSOLETE_SHOW_UP), Image(IntImages, IMAGE_OBSOLETE_SHOW_DOWN), Image(IntImages, IMAGE_OBSOLETE_SHOW_HI)));
obsoleteButton->setTip(true, _("Showing Obsolete Tech"));
obsoleteButton->move(4 + Image(IntImages, IMAGE_FDP_UP).width() + 4, STAT_SLDY);
return obsoleteButton;
}
/* Add the stats widgets to the widget screen */
/* If psSelected != NULL it specifies which stat should be hilited
psOwner specifies which object is hilighted on the object bar for this stat*/
@ -3670,43 +3692,32 @@ static bool intAddStats(BASE_STATS **ppsStatsList, UDWORD numStats,
W_LABINIT sLabInit;
// Add the quantity slider ( if it's a factory ).
if (objMode == IOBJ_MANUFACTURE)
if (objMode == IOBJ_MANUFACTURE && psOwner != nullptr)
{
//add the Factory DP button
W_BUTINIT sButInit;
sButInit.formID = IDSTAT_FORM;
sButInit.id = IDSTAT_DP_BUTTON;
sButInit.style = WBUT_SECONDARY;
sButInit.x = 4;
sButInit.y = STAT_SLDY;
sButInit.width = iV_GetImageWidth(IntImages, IMAGE_FDP_DOWN);
sButInit.height = iV_GetImageHeight(IntImages, IMAGE_FDP_DOWN);
sButInit.pTip = _("Factory Delivery Point");
sButInit.pDisplay = intDisplayDPButton;
sButInit.pUserData = psOwner;
STRUCTURE_TYPE factoryType = ((STRUCTURE *)psOwner)->pStructureType->type;
if (!widgAddButton(psWScreen, &sButInit))
//add the Factory DP button
W_BUTTON *deliveryPointButton = new W_BUTTON(statForm);
deliveryPointButton->id = IDSTAT_DP_BUTTON;
deliveryPointButton->style |= WBUT_SECONDARY;
switch (factoryType)
{
return false;
default:
case REF_FACTORY: deliveryPointButton->setImages(Image(IntImages, IMAGE_FDP_UP), Image(IntImages, IMAGE_FDP_DOWN), Image(IntImages, IMAGE_FDP_HI)); break;
case REF_CYBORG_FACTORY: deliveryPointButton->setImages(Image(IntImages, IMAGE_CDP_UP), Image(IntImages, IMAGE_CDP_DOWN), Image(IntImages, IMAGE_CDP_HI)); break;
case REF_VTOL_FACTORY: deliveryPointButton->setImages(Image(IntImages, IMAGE_VDP_UP), Image(IntImages, IMAGE_VDP_DOWN), Image(IntImages, IMAGE_VDP_HI)); break;
}
deliveryPointButton->move(4, STAT_SLDY);
deliveryPointButton->setTip(_("Factory Delivery Point"));
deliveryPointButton->pUserData = psOwner;
//add the Factory Loop button!
sButInit = W_BUTINIT();
sButInit.formID = IDSTAT_FORM;
sButInit.id = IDSTAT_LOOP_BUTTON;
sButInit.style = WBUT_SECONDARY;
sButInit.x = STAT_SLDX + STAT_SLDWIDTH + 2;
sButInit.y = STAT_SLDY;
sButInit.width = iV_GetImageWidth(IntImages, IMAGE_LOOP_DOWN);
sButInit.height = iV_GetImageHeight(IntImages, IMAGE_LOOP_DOWN);
sButInit.pTip = _("Loop Production");
sButInit.pDisplay = intDisplayButtonPressed;
sButInit.UserData = PACKDWORD_TRI(IMAGE_LOOP_DOWN, IMAGE_LOOP_HI, IMAGE_LOOP_UP);
if (!widgAddButton(psWScreen, &sButInit))
{
return false;
}
W_BUTTON *loopButton = new W_BUTTON(statForm);
loopButton->id = IDSTAT_LOOP_BUTTON;
loopButton->style |= WBUT_SECONDARY;
loopButton->setImages(Image(IntImages, IMAGE_LOOP_UP), Image(IntImages, IMAGE_LOOP_DOWN), Image(IntImages, IMAGE_LOOP_HI));
loopButton->move(STAT_SLDX + STAT_SLDWIDTH + 2, STAT_SLDY);
loopButton->setTip(_("Loop Production"));
if (psOwner != NULL)
{
@ -3721,8 +3732,8 @@ static bool intAddStats(BASE_STATS **ppsStatsList, UDWORD numStats,
sLabInit.formID = IDSTAT_FORM;
sLabInit.id = IDSTAT_LOOP_LABEL;
sLabInit.style = WIDG_HIDDEN;
sLabInit.x = (UWORD)(sButInit.x - 15);
sLabInit.y = sButInit.y;
sLabInit.x = loopButton->x() - 15;
sLabInit.y = loopButton->y();
sLabInit.width = 12;
sLabInit.height = 15;
sLabInit.pUserData = psOwner;
@ -3731,7 +3742,10 @@ static bool intAddStats(BASE_STATS **ppsStatsList, UDWORD numStats,
{
return false;
}
}
if (objMode == IOBJ_MANUFACTURE)
{
/* store the common values for the text labels for the quantity
to produce (on each button).*/
sLabInit = W_LABINIT();
@ -3746,6 +3760,12 @@ static bool intAddStats(BASE_STATS **ppsStatsList, UDWORD numStats,
sLabInit.pCallback = intAddProdQuantity;
}
if ((objMode == IOBJ_MANUFACTURE || objMode == IOBJ_BUILD) && psOwner != nullptr)
{
// Add the obsolete items button.
makeObsoleteButton(statForm);
}
/* Add the close button */
W_BUTINIT sButInit;
sButInit.formID = IDSTAT_FORM;

View File

@ -86,12 +86,13 @@
#define IDSTAT_TABFORM 14004 // The tab form with the stats buttons
#define IDSTAT_START 14100 // The first stats ID
#define IDSTAT_END 14999 // The last stats ID enough for 899 things
#define IDSTAT_TIMEBARSTART 4300
#define IDSTAT_TIMEBAREND 4399
#define IDSTAT_TIMEBARSTART 16205000
#define IDSTAT_TIMEBAREND 16205999
#define IDSTAT_SLIDER 4400
#define IDSTAT_LOOP_BUTTON 4403
#define IDSTAT_LOOP_LABEL 4404
#define IDSTAT_DP_BUTTON 4405
#define IDSTAT_OBSOLETE_BUTTON 4406
#define IDSTAT_RESICONSTART 4500
#define IDSTAT_RESICONEND 4599
#define IDSTAT_PRODSTART 4600
@ -378,4 +379,6 @@ extern bool intIsRefreshing(void);
extern void intDemolishCancel(void);
StateButton *makeObsoleteButton(WIDGET *parent); ///< Makes a button to toggle showing obsolete items.
#endif // __INCLUDED_SRC_HCI_H__

View File

@ -1340,6 +1340,7 @@ static void initMiscVars(void)
radarOnScreen = true;
radarPermitted = true;
allowDesign = true;
includeRedundantDesigns = false;
enableConsoleDisplay(true);
setSelectedGroup(UBYTE_MAX);

View File

@ -1259,59 +1259,6 @@ void intDisplayButtonPressed(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset)
}
}
// Display DP images depending on factory and if the widget is currently depressed
void intDisplayDPButton(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset)
{
W_BUTTON *psButton = (W_BUTTON *)psWidget;
STRUCTURE *psStruct = (STRUCTURE *)psButton->pUserData;
UDWORD x = xOffset + psButton->x();
UDWORD y = yOffset + psButton->y();
UBYTE hilight = 0, down = 0;
UWORD imageID;
if (psStruct)
{
ASSERT(StructIsFactory(psStruct), "Structure is not a factory");
if (psButton->state & (WBUT_DOWN | WBUT_LOCK | WBUT_CLICKLOCK))
{
down = true;
}
hilight = (UBYTE)buttonIsHilite(psButton);
switch (psStruct->pStructureType->type)
{
case REF_FACTORY:
imageID = IMAGE_FDP_UP;
break;
case REF_CYBORG_FACTORY:
imageID = IMAGE_CDP_UP;
break;
case REF_VTOL_FACTORY:
imageID = IMAGE_VDP_UP;
break;
default:
return;
}
iV_DrawImage(IntImages, imageID, x, y);
if (hilight)
{
imageID++;
iV_DrawImage(IntImages, (UWORD)imageID, x, y);
}
else if (down)
{
imageID--;
iV_DrawImage(IntImages, (UWORD)imageID, x, y);
}
}
}
void intDisplaySlider(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset)
{
W_SLIDER *Slider = (W_SLIDER *)psWidget;

View File

@ -242,8 +242,6 @@ extern void drawRadarBlips(int radarX, int radarY, float pixSizeH, float pixSize
extern void intUpdateQuantitySlider(WIDGET *psWidget, W_CONTEXT *psContext);
void intDisplayDPButton(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset);
void intDisplayResSubGroup(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset);
void intDisplayMissionClock(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset);

View File

@ -375,6 +375,12 @@ enum INTFAC_TYPE
IMAGE_VDP_DOWN,
IMAGE_VDP_UP,
IMAGE_VDP_HI,
IMAGE_OBSOLETE_HIDE_UP,
IMAGE_OBSOLETE_HIDE_DOWN,
IMAGE_OBSOLETE_HIDE_HI,
IMAGE_OBSOLETE_SHOW_UP,
IMAGE_OBSOLETE_SHOW_DOWN,
IMAGE_OBSOLETE_SHOW_HI,
IMAGE_GN_STAR,
IMAGE_GN_15,
IMAGE_GN_14,

View File

@ -83,11 +83,14 @@ extern UBYTE *apCompLists[MAX_PLAYERS][COMP_NUMCOMPONENTS];
//store for each players Structure states
extern UBYTE *apStructTypeLists[MAX_PLAYERS];
//flags to fill apCompLists and apStructTypeLists
#define AVAILABLE 0x01 //this item can be used to design droids
#define UNAVAILABLE 0x02 //the player does not know about this item
#define FOUND 0x04 //this item has been found, but is unresearched
#define REDUNDANT 0x0A //the player no longer needs this item
//Values to fill apCompLists and apStructTypeLists. Not a bitfield, values are in case that helps with savegame compatibility.
enum ItemAvailability
{
AVAILABLE = 1, // This item can be used to design droids.
UNAVAILABLE = 2, // The player does not know about this item.
FOUND = 4, // This item has been found, but is unresearched.
REDUNDANT = 10, // The player no longer needs this item.
};
/*******************************************************************************
* Allocate stats functions

View File

@ -3786,7 +3786,7 @@ UDWORD fillStructureList(STRUCTURE_STATS **ppList, UDWORD selectedPlayer, UDWORD
for (inc=0; inc < numStructureStats; inc++)
{
//if the structure is flagged as available, add it to the list
if (apStructTypeLists[selectedPlayer][inc] & AVAILABLE)
if (apStructTypeLists[selectedPlayer][inc] == AVAILABLE || (includeRedundantDesigns && apStructTypeLists[selectedPlayer][inc] == REDUNDANT))
{
//check not built the maximum allowed already
if (asStructLimits[selectedPlayer][inc].currentQuantity < asStructLimits[selectedPlayer][inc].limit)

View File

@ -43,7 +43,10 @@
// Template storage
DROID_TEMPLATE *apsDroidTemplates[MAX_PLAYERS];
bool allowDesign = true;
bool includeRedundantDesigns = false;
static bool researchedItem(DROID_TEMPLATE *psCurr, int player, COMPONENT_TYPE partIndex, int part, bool allowZero, bool allowRedundant)
{
@ -503,7 +506,7 @@ void fillTemplateList(std::vector<DROID_TEMPLATE *> &pList, STRUCTURE *psFactory
}
if (!psCurr->enabled || !validTemplateForFactory(psCurr, psFactory, false)
|| !researchedTemplate(psCurr, player))
|| !researchedTemplate(psCurr, player, includeRedundantDesigns))
{
continue;
}

View File

@ -7,6 +7,8 @@
extern DROID_TEMPLATE *apsDroidTemplates[MAX_PLAYERS];
extern bool allowDesign;
extern bool includeRedundantDesigns;
bool initTemplates();
bool shutdownTemplates();