Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
310 changes: 309 additions & 1 deletion src/galaxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include <cstring>
#include <cmath>
#include "colony.h"
#include "gamestate.h"
#include "screen.h"
#include "guimisc.h"
#include "mainmenu.h"
Expand Down Expand Up @@ -113,6 +115,28 @@
#define PLANET_LIST_COLONY_X 88
#define PLANET_LIST_OUTPOST_X 18

#define COLONY_ARCHIVE "colsum.lbx"
#define ASSET_COLONYLIST_BG 0
#define ASSET_COLONYLIST_RETURN_BUTTON 1

#define COLONY_LIST_ROWS 10
#define COLONY_LIST_FIRST_ROW 39
#define COLONY_LIST_ROW_HEIGHT 26
#define COLONY_LIST_ROW_DIST 5
#define COLONY_LIST_ROW_LEFT_PADDING 55
#define COLONY_LIST_ROW_BOTTOM_PADDING 5
#define COLONY_LIST_ROW_MARGIN 13
#define COLONY_LIST_DETAILS_LEFT_PADDING 15
#define COLONY_LIST_EMPIRE_DETAILS_LEFT_POSITION 520
#define COLONY_LIST_EMPIRE_DETAILS_RIGHT_POSITION 625
#define COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION 353
#define COLONY_LIST_EMPIRE_DETAILS_RESERVE_SLOT 0
#define COLONY_LIST_EMPIRE_DETAILS_INCOME_SLOT 1
#define COLONY_LIST_EMPIRE_DETAILS_POPULATION_SLOT 2
#define COLONY_LIST_EMPIRE_DETAILS_FREIGHTERS_SLOT 3
#define COLONY_LIST_EMPIRE_DETAILS_FOOD_SLOT 4
#define COLONY_LIST_EMPIRE_DETAILS_RESEARCH_SLOT 5

static const uint8_t starmapHighlightColors[(MAX_PLAYERS + 1) * 3] {
RGB(0xfc0000), RGB(0xd4c418), RGB(0x209c1c), RGB(0xc8c8c8),
RGB(0x305ca0), RGB(0xa47050), RGB(0x8c6098), RGB(0xd0680c),
Expand Down Expand Up @@ -2125,7 +2149,9 @@ void GalaxyView::clickGameMenu(int x, int y, int arg) {
new MainMenuWindow(this, _game);
}

void GalaxyView::clickColoniesButton(int x, int y, int arg) STUB(this)
void GalaxyView::clickColoniesButton(int x, int y, int arg) {
gui_stack->push(new ColoniesListView(_game, _activePlayer));
}

void GalaxyView::clickPlanetsButton(int x, int y, int arg) {
gui_stack->push(new PlanetsListView(_game, _activePlayer));
Expand Down Expand Up @@ -2913,6 +2939,288 @@ void PlanetsListView::clickReturn(int x, int y, int arg) {
exitView();
}

ColoniesListView::ColoniesListView(GameState *game, int activePlayer) :
_game(game), _activePlayer(activePlayer),_scroll(NULL), _selectedSlot(-1) {

_bg = gameAssets->getImage(COLONY_ARCHIVE, ASSET_COLONYLIST_BG);

initWidgets();
}

void ColoniesListView::initWidgets(void) {
unsigned i;
const uint8_t *pal = _bg->palette();
Widget *w = NULL;

for (i = 0; i < COLONY_LIST_ROWS; i++) {
w = createWidget(10,
COLONY_LIST_FIRST_ROW + i * (COLONY_LIST_ROW_HEIGHT + COLONY_LIST_ROW_BOTTOM_PADDING),
398,
COLONY_LIST_ROW_HEIGHT);
w->setMouseOverCallback(GuiMethod(*this,
&ColoniesListView::highlightSlot, i));
w->setMouseMoveCallback(GuiMethod(*this,
&ColoniesListView::highlightSlot, i));
w->setMouseOutCallback(GuiMethod(*this,
&ColoniesListView::highlightSlot, -1));
w->setMouseUpCallback(MBUTTON_LEFT,
GuiMethod(*this, &ColoniesListView::clickSlot, i));
}

w = createWidget(531, 445, 156, 25);
w->setMouseUpCallback(MBUTTON_LEFT,
GuiMethod(*this, &ColoniesListView::clickReturn));
w->setClickSprite(MBUTTON_LEFT, COLONY_ARCHIVE,
ASSET_COLONYLIST_RETURN_BUTTON, pal, 1);
w->setMouseUpCallback(MBUTTON_RIGHT,
GuiMethod(*this, &ColoniesListView::showHelp,
HELP_RETURN_BUTTON));

farmer = new ColonistPickerWidget(0, 0, 100, 90, NULL, FARMER, _game->_players, _game->_playerCount);
worker = new ColonistPickerWidget(0, 0, 100, 90, NULL, WORKER, _game->_players, _game->_playerCount);
scientist = new ColonistPickerWidget(0, 0, 100, 90, NULL, SCIENTIST, _game->_players, _game->_playerCount);
}

void ColoniesListView::highlightSlot(int x, int y, int arg) {
if (arg >= 0 && arg < COLONY_LIST_ROWS && arg < _game->_colonyCount) {
_curslot = arg;
} else {
_curslot = -1;
}
}

void ColoniesListView::clickSlot(int x, int y, int arg) {
_selectedSlot = arg;
}

// FIXME: Render the colonies in alphanumeric order maybe
void ColoniesListView::redraw(unsigned curtick) {
Font *fnt;
// unsigned i, offset = _scroll->position();
unsigned i, j, y, color;
int owner;
StringBuffer buf, num;
const Planet *planet_ptr;
const Star *star_ptr;
const Colony *colony_ptr;

fnt = gameFonts->getFont(FONTSIZE_SMALL);

gameScreen->clear();
_bg->draw(0, 0);

unsigned offset = 0; // FIXME: This should come from the scrollbar
int colony_row = 0;
for (i = 0; i < _game->_colonyCount; i++) {
y = COLONY_LIST_FIRST_ROW + COLONY_LIST_ROW_DIST + colony_row * (COLONY_LIST_ROW_HEIGHT + COLONY_LIST_ROW_BOTTOM_PADDING);
colony_ptr = _game->_colonies + offset + i;
if (colony_ptr->owner != _activePlayer) continue;

planet_ptr = &_game->_planets[colony_ptr->planet];
star_ptr = &_game->_starSystems[planet_ptr->star];
if (_curslot == colony_row) {
color = FONT_COLOR_COLONY_LIST_BRIGHT;
// Fill the lower right box with the info from the selected colony, if any
renderPlanetDetail(planet_ptr, colony_ptr);
} else {
color = FONT_COLOR_COLONY_LIST;
}
num.roman(star_ptr->planetSeq(planet_ptr->orbit) + 1);
buf.printf("%s %s", star_ptr->name, num.c_str());

fnt->centerText(COLONY_LIST_ROW_LEFT_PADDING, y, color, buf.c_str());

drawColonistsJobs(colony_ptr, curtick);
drawEmpireDetails();

colony_row++;
}

redrawWidgets(0, 0, curtick);
redrawWindows(curtick);
}

void ColoniesListView::clickReturn(int x, int y, int arg) {
exitView();
}

void ColoniesListView::showHelp(int x, int y, int arg) {
new MessageBoxWindow(this, arg, _bg->palette());
}

void ColoniesListView::renderPlanetDetail(const Planet *planet_ptr, const Colony *colony_ptr) {
StringBuffer buf;
Font *fnt;

fnt = gameFonts->getFont(FONTSIZE_SMALLER);

switch(planet_ptr->size) {
case TINY_PLANET:
buf.append(gameLang->estrings(ESTR_PLANET_SIZE_TINY));
break;
case SMALL_PLANET:
buf.append(gameLang->estrings(ESTR_PLANET_SIZE_SMALL));
break;
case MEDIUM_PLANET:
buf.append(gameLang->estrings(ESTR_PLANET_SIZE_MEDIUM));
break;
case LARGE_PLANET:
buf.append(gameLang->estrings(ESTR_PLANET_SIZE_LARGE));
break;
default:
buf.append(gameLang->estrings(ESTR_PLANET_SIZE_HUGE));
}

switch(planet_ptr->climate) {
case TOXIC:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_TOXIC));
break;
case RADIATED:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_RADIATED));
break;
case BARREN:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_BARREN));
break;
case DESERT:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_DESERT));
break;
case TUNDRA:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_TUNDRA));
break;
case OCEAN:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_OCEAN));
break;
case SWAMP:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_SWAMP));
break;
case ARID:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_ARID));
break;
case TERRAN:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_TERRAN));
break;
default:
buf.append_printf(" %s", gameLang->estrings(ESTR_CLIMATE_GAIA));
}

fnt->renderText(COLONY_LIST_DETAILS_LEFT_PADDING, 354, FONT_COLOR_COLONY_LIST, buf.c_str());

switch(planet_ptr->gravity) {
case LOW_G:
buf.printf("Low Gravity");
break;
case NORMAL_G:
buf.printf("Normal Gravity");
break;
default:
buf.printf("Heavy Gravity");
}
fnt->renderText(COLONY_LIST_DETAILS_LEFT_PADDING, 365, FONT_COLOR_COLONY_LIST, buf.c_str());

switch(planet_ptr->minerals) {
case ULTRA_POOR:
buf.append_printf("Mineral %s", gameLang->estrings(ESTR_LMINERALS_ULTRA_POOR));
break;
case POOR:
buf.append_printf("Mineral %s", gameLang->estrings(ESTR_LMINERALS_POOR));
break;
case ABUNDANT:
buf.append_printf("Mineral %s", gameLang->estrings(ESTR_LMINERALS_ABUNDANT));
break;
case RICH :
buf.append_printf("Mineral %s", gameLang->estrings(ESTR_LMINERALS_RICH));
break;
default:
buf.append_printf("Mineral %s", gameLang->estrings(ESTR_LMINERALS_ULTRA_RICH));
}
fnt->renderText(COLONY_LIST_DETAILS_LEFT_PADDING, 376, FONT_COLOR_COLONY_LIST, buf.c_str());

// FIXME: Max population always seems to be zero
buf.printf("Population (%d/%d)",
colony_ptr->population,
_game->planetMaxPop(colony_ptr->planet, _activePlayer));
fnt->renderText(COLONY_LIST_DETAILS_LEFT_PADDING, 387, FONT_COLOR_COLONY_LIST, buf.c_str());
}

void ColoniesListView::drawColonistsJobs(const Colony* colony_ptr, int curtick) {
int farmers = 0;
int workers = 0;
int scientists = 0;
int j = 0;

for (j = 0; j < MAX_POPULATION; j++) {
if (colony_ptr->colonists[j].job == FARMER) {
farmers++;
} else if (colony_ptr->colonists[j].job == WORKER) {
workers++;
} else if (colony_ptr->colonists[j].job == SCIENTIST) {
scientists++;
}
}

farmers = colony_ptr->population - workers + scientists;

if (farmers > colony_ptr->population) {
farmers = colony_ptr->population;
}

farmer->setColony(colony_ptr);
farmer->redraw(103, 38, curtick);

// FIXME: This is showing no workers on some colonies...
worker->setColony(colony_ptr);
worker->redraw(237, 38, curtick);

scientist->setColony(colony_ptr);
scientist->redraw(377, 38, curtick);
}

void ColoniesListView::drawEmpireDetails() {
int color;
StringBuffer buf;
Font* fnt = gameFonts->getFont(FONTSIZE_SMALL);

color = FONT_COLOR_COLONY_LIST;
buf.printf("Reserve:");
fnt->renderText(COLONY_LIST_EMPIRE_DETAILS_LEFT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_RESERVE_SLOT, color, buf.c_str());
buf.printf("%d", _game->_players[_activePlayer].BC);
fnt->rightText(COLONY_LIST_EMPIRE_DETAILS_RIGHT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_RESERVE_SLOT, color, buf.c_str());

buf.printf("Income:");
fnt->renderText(COLONY_LIST_EMPIRE_DETAILS_LEFT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_INCOME_SLOT, color, buf.c_str());
if (_game->_players[_activePlayer].BC > 0) {
buf.printf("+%d", _game->_players[_activePlayer].surplusBC);
} else {
buf.printf("-%d", _game->_players[_activePlayer].surplusBC);
}
fnt->rightText(COLONY_LIST_EMPIRE_DETAILS_RIGHT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_INCOME_SLOT, color, buf.c_str());

buf.printf("Population:");
fnt->renderText(COLONY_LIST_EMPIRE_DETAILS_LEFT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_POPULATION_SLOT, color, buf.c_str());
buf.printf("%d", _game->_players[_activePlayer].totalPop);
fnt->rightText(COLONY_LIST_EMPIRE_DETAILS_RIGHT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_POPULATION_SLOT, color, buf.c_str());

buf.printf("Freighters:");
fnt->renderText(COLONY_LIST_EMPIRE_DETAILS_LEFT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_FREIGHTERS_SLOT, color, buf.c_str());
buf.printf("%d", _game->_players[_activePlayer].surplusFreighters);
fnt->rightText(COLONY_LIST_EMPIRE_DETAILS_RIGHT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_FREIGHTERS_SLOT, color, buf.c_str());

buf.printf("Food:");
fnt->renderText(COLONY_LIST_EMPIRE_DETAILS_LEFT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_FOOD_SLOT, color, buf.c_str());
if (_game->_players[_activePlayer].surplusFood >= 0) {
buf.printf("+%d", _game->_players[_activePlayer].surplusFood);
} else {
buf.printf("-%d", _game->_players[_activePlayer].surplusFood);
}
fnt->rightText(COLONY_LIST_EMPIRE_DETAILS_RIGHT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_FOOD_SLOT, color, buf.c_str());

buf.printf("Research:");
fnt->renderText(COLONY_LIST_EMPIRE_DETAILS_LEFT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_RESEARCH_SLOT, color, buf.c_str());
buf.printf("%d", _game->_players[_activePlayer].researchProduced);
fnt->rightText(COLONY_LIST_EMPIRE_DETAILS_RIGHT_POSITION, COLONY_LIST_EMPIRE_DETAILS_TOP_POSITION + COLONY_LIST_ROW_MARGIN * COLONY_LIST_EMPIRE_DETAILS_RESEARCH_SLOT, color, buf.c_str());

}

MainMenuWindow::MainMenuWindow(GuiView *parent, GameState *game) :
GuiWindow(parent, WINDOW_MODAL), _game(game) {

Expand Down
31 changes: 31 additions & 0 deletions src/galaxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "gui.h"
#include "gamestate.h"
#include "colony.h"

#define GALAXY_ARCHIVE "buffer0.lbx"
#define ASSET_GALAXY_GUI 0
Expand Down Expand Up @@ -294,6 +295,36 @@ class PlanetsListView : public GuiView {
void clickReturn(int x, int y, int arg);
};

class ColoniesListView : public GuiView {
private:
GameState *_game;
ScrollBarWidget *_scroll;
ColonistPickerWidget* farmer;
ColonistPickerWidget* worker;
ColonistPickerWidget* scientist;
int _curslot;
int _selectedSlot;
ImageAsset _bg;
unsigned _colonies[MAX_COLONIES];
int _activePlayer;

void initWidgets(void);
void renderPlanetDetail(const Planet *planet_ptr, const Colony *colony_ptr);
void drawColonistsJobs(const Colony* colony_ptr, int curtick);
void drawEmpireDetails();


public:
ColoniesListView(GameState *game, int activePlayer);

void highlightSlot(int x, int y, int arg);
void clickSlot(int x, int y, int arg);
void redraw(unsigned curtick);

void showHelp(int x, int y, int arg);
void clickReturn(int x, int y, int arg);
};

class MainMenuWindow : public GuiWindow {
private:
ImageAsset _bg;
Expand Down
6 changes: 6 additions & 0 deletions src/gfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,12 @@ int Font::centerText(int x, int y, unsigned color, const char *str,
outline, charSpacing);
}

int Font::rightText(int x, int y, unsigned color, const char *str,
unsigned outline, unsigned charSpacing) {
return renderText(x - textWidth(str, charSpacing), y, color, str,
outline, charSpacing);
}

const uint8_t *Font::titlePalette(unsigned color) {
if (color >= TITLE_COLOR_MAX) {
throw std::out_of_range("Invalid title font color ID");
Expand Down
Loading