86 changes: 53 additions & 33 deletions src/hci.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
}
}


Expand Down Expand Up @@ -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*/
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand All @@ -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();
Expand All @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions src/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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__
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,7 @@ static void initMiscVars(void)
radarOnScreen = true;
radarPermitted = true;
allowDesign = true;
includeRedundantDesigns = false;
enableConsoleDisplay(true);

setSelectedGroup(UBYTE_MAX);
Expand Down
53 changes: 0 additions & 53 deletions src/intdisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 0 additions & 2 deletions src/intdisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions src/intfac.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
13 changes: 8 additions & 5 deletions src/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 4 additions & 1 deletion src/template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/template.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
extern DROID_TEMPLATE *apsDroidTemplates[MAX_PLAYERS];

extern bool allowDesign;
extern bool includeRedundantDesigns;


bool initTemplates();
bool shutdownTemplates();
Expand Down