97c4694bc2
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14188 a1c6a512-1295-4272-9138-f99709370657
2272 lines
83 KiB
C
2272 lines
83 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2006 Will Robertson
|
|
*
|
|
* All files in this archive are subject to the GNU General Public License.
|
|
* See the file COPYING in the source tree root for full license agreement.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
#include "plugin.h"
|
|
PLUGIN_HEADER
|
|
static struct plugin_api* rb;
|
|
|
|
extern const fb_data superdom_boarditems[];
|
|
char buf[255];
|
|
|
|
#define COLOUR_DARK 0
|
|
#define COLOUR_LIGHT 1
|
|
|
|
#define MARGIN 5
|
|
|
|
#if LCD_WIDTH > LCD_HEIGHT
|
|
#define BOX_WIDTH ((LCD_WIDTH-(MARGIN*2))/10)
|
|
#define BOX_HEIGHT ((BOX_WIDTH*2)/3)
|
|
|
|
#else
|
|
#define BOX_HEIGHT ((LCD_HEIGHT-(MARGIN*2)-15)/10)
|
|
#define BOX_WIDTH ((BOX_HEIGHT*2)/3)
|
|
|
|
#endif
|
|
|
|
#if LCD_WIDTH == 220 && LCD_HEIGHT == 176
|
|
#define NUM_BOX_HEIGHT 25
|
|
#define NUM_BOX_WIDTH 30
|
|
#define STRIDE 14
|
|
#define ICON_HEIGHT 7
|
|
#define ICON_WIDTH 7
|
|
|
|
#elif (LCD_WIDTH == 160 && LCD_HEIGHT == 128) || \
|
|
(LCD_WIDTH == 176 && LCD_HEIGHT == 132) || \
|
|
(LCD_WIDTH == 176 && LCD_HEIGHT == 220)
|
|
#define NUM_BOX_HEIGHT 20
|
|
#define NUM_BOX_WIDTH 24
|
|
#define STRIDE 8
|
|
#define ICON_HEIGHT 4
|
|
#define ICON_WIDTH 4
|
|
|
|
#elif (LCD_WIDTH == 320 && LCD_HEIGHT == 240)
|
|
#define NUM_BOX_HEIGHT 25
|
|
#define NUM_BOX_WIDTH 30
|
|
#define STRIDE 20
|
|
#define ICON_HEIGHT 10
|
|
#define ICON_WIDTH 10
|
|
|
|
#elif (LCD_WIDTH == 240 && LCD_HEIGHT == 320)
|
|
#define NUM_BOX_HEIGHT 25
|
|
#define NUM_BOX_WIDTH 30
|
|
#define STRIDE 18
|
|
#define ICON_HEIGHT 9
|
|
#define ICON_WIDTH 9
|
|
|
|
#endif
|
|
|
|
#define NUM_MARGIN_X (LCD_WIDTH-3*NUM_BOX_WIDTH)/2
|
|
#define NUM_MARGIN_Y (LCD_HEIGHT-4*NUM_BOX_HEIGHT)/2
|
|
|
|
#if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
|
|
(CONFIG_KEYPAD == IPOD_1G2G_PAD)
|
|
#define SUPERDOM_OK BUTTON_SELECT
|
|
#define SUPERDOM_CANCEL BUTTON_MENU
|
|
#define SUPERDOM_LEFT BUTTON_LEFT
|
|
#define SUPERDOM_RIGHT BUTTON_RIGHT
|
|
#define IPOD_STYLE
|
|
|
|
#elif CONFIG_KEYPAD == IRIVER_H300_PAD || CONFIG_KEYPAD == IRIVER_H100_PAD
|
|
#define SUPERDOM_OK BUTTON_SELECT
|
|
#define SUPERDOM_LEFT BUTTON_LEFT
|
|
#define SUPERDOM_RIGHT BUTTON_RIGHT
|
|
#define SUPERDOM_UP BUTTON_UP
|
|
#define SUPERDOM_DOWN BUTTON_DOWN
|
|
#define SUPERDOM_CANCEL BUTTON_OFF
|
|
|
|
#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
|
|
#define SUPERDOM_OK BUTTON_SELECT
|
|
#define SUPERDOM_LEFT BUTTON_LEFT
|
|
#define SUPERDOM_RIGHT BUTTON_RIGHT
|
|
#define SUPERDOM_UP BUTTON_UP
|
|
#define SUPERDOM_DOWN BUTTON_DOWN
|
|
#define SUPERDOM_CANCEL BUTTON_REC
|
|
|
|
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
|
|
#define SUPERDOM_OK BUTTON_RIGHT
|
|
#define SUPERDOM_UP BUTTON_SCROLL_UP
|
|
#define SUPERDOM_DOWN BUTTON_SCROLL_DOWN
|
|
#define SUPERDOM_CANCEL BUTTON_LEFT
|
|
|
|
#elif CONFIG_KEYPAD == GIGABEAT_PAD
|
|
#define SUPERDOM_OK BUTTON_SELECT
|
|
#define SUPERDOM_UP BUTTON_UP
|
|
#define SUPERDOM_DOWN BUTTON_DOWN
|
|
#define SUPERDOM_LEFT BUTTON_LEFT
|
|
#define SUPERDOM_RIGHT BUTTON_RIGHT
|
|
#define SUPERDOM_CANCEL BUTTON_POWER
|
|
|
|
#elif CONFIG_KEYPAD == SANSA_E200_PAD
|
|
#define SUPERDOM_OK BUTTON_SELECT
|
|
#define SUPERDOM_UP BUTTON_SCROLL_UP
|
|
#define SUPERDOM_DOWN BUTTON_SCROLL_DOWN
|
|
#define SUPERDOM_LEFT BUTTON_LEFT
|
|
#define SUPERDOM_RIGHT BUTTON_RIGHT
|
|
#define SUPERDOM_CANCEL BUTTON_POWER
|
|
|
|
#endif
|
|
|
|
#define SUPERDOM_QUIT 23
|
|
|
|
void gen_interest(void);
|
|
int production_menu(void);
|
|
void init_resources(void);
|
|
int select_square(void);
|
|
void update_score(void);
|
|
void gen_resources(void);
|
|
void draw_cursor(void);
|
|
int calc_strength(bool colour, int x, int y);
|
|
void draw_board(void);
|
|
|
|
struct tile{
|
|
signed int colour; /* -1 = Unset */
|
|
bool tank;
|
|
bool plane;
|
|
bool nuke;
|
|
bool ind;
|
|
bool farm;
|
|
int men;
|
|
};
|
|
|
|
struct resources {
|
|
int cash;
|
|
int food;
|
|
int farms;
|
|
int inds;
|
|
int men;
|
|
int tanks;
|
|
int planes;
|
|
int nukes;
|
|
int bank;
|
|
int moves;
|
|
};
|
|
|
|
struct settings {
|
|
int compstartfarms;
|
|
int compstartinds;
|
|
int humanstartfarms;
|
|
int humanstartinds;
|
|
int startcash;
|
|
int startfood;
|
|
int movesperturn;
|
|
} superdom_settings;
|
|
|
|
struct resources humanres;
|
|
struct resources compres;
|
|
|
|
struct cursor{
|
|
int x;
|
|
int y;
|
|
} cursor;
|
|
|
|
struct tile board[12][12];
|
|
|
|
void init_board(void) {
|
|
rb->srand(*rb->current_tick);
|
|
int i,j;
|
|
for(i=0;i<12;i++) { /* Hopefully about 50% each colour */
|
|
for(j=0;j<12;j++) {
|
|
if((i<1)||(j<1)||(i>10)||(j>10))
|
|
board[i][j].colour = -1; /* Unset */
|
|
else
|
|
board[i][j].colour = rb->rand()%2;
|
|
board[i][j].tank = false;
|
|
board[i][j].plane = false;
|
|
board[i][j].nuke = false;
|
|
board[i][j].ind = false;
|
|
board[i][j].farm = false;
|
|
board[i][j].men = 0;
|
|
}
|
|
}
|
|
|
|
while(compres.farms < superdom_settings.compstartfarms) {
|
|
i = rb->rand()%10 + 1;
|
|
j = rb->rand()%10 + 1;
|
|
if((board[i][j].colour == COLOUR_DARK) && (board[i][j].farm == false)) {
|
|
board[i][j].farm = true;
|
|
compres.farms++;
|
|
break;
|
|
}
|
|
}
|
|
while(compres.inds < superdom_settings.compstartinds) {
|
|
i = rb->rand()%10 + 1;
|
|
j = rb->rand()%10 + 1;
|
|
if((board[i][j].colour == COLOUR_DARK) && (board[i][j].ind == false)) {
|
|
board[i][j].ind = true;
|
|
compres.inds++;
|
|
break;
|
|
}
|
|
}
|
|
while(humanres.farms<superdom_settings.humanstartfarms) {
|
|
i = rb->rand()%10 + 1;
|
|
j = rb->rand()%10 + 1;
|
|
if((board[i][j].colour == COLOUR_LIGHT)&&(board[i][j].farm == false)) {
|
|
board[i][j].farm = true;
|
|
humanres.farms++;
|
|
}
|
|
}
|
|
while(humanres.inds<superdom_settings.humanstartfarms) {
|
|
i = rb->rand()%10 + 1;
|
|
j = rb->rand()%10 + 1;
|
|
if((board[i][j].colour == COLOUR_LIGHT) && (board[i][j].ind == false)) {
|
|
board[i][j].ind = true;
|
|
humanres.inds++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void draw_board(void) {
|
|
rb->lcd_clear_display();
|
|
int i,j;
|
|
for(i=1;i<11;i++) {
|
|
for(j=1;j<11;j++) {
|
|
if(board[i][j].colour == COLOUR_DARK) {
|
|
rb->lcd_set_foreground(LCD_DARKGRAY);
|
|
} else {
|
|
rb->lcd_set_foreground(LCD_LIGHTGRAY);
|
|
}
|
|
rb->lcd_fillrect(MARGIN+(BOX_WIDTH*(i-1)),
|
|
MARGIN+(BOX_HEIGHT*(j-1)), BOX_WIDTH,
|
|
BOX_HEIGHT);
|
|
#if LCD_DEPTH != 16
|
|
rb->lcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
|
|
#endif
|
|
if(board[i][j].ind) {
|
|
#if (LCD_DEPTH == 16)
|
|
rb->lcd_bitmap_transparent_part(superdom_boarditems,
|
|
#else
|
|
rb->lcd_mono_bitmap_part(superdom_boarditems,
|
|
#endif
|
|
board[i][j].colour?ICON_WIDTH:0, 0, STRIDE,
|
|
#if LCD_WIDTH > LCD_HEIGHT
|
|
MARGIN+(BOX_WIDTH*(i-1))+1,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
|
|
#else
|
|
MARGIN+(BOX_WIDTH*(i-1))+1+ICON_WIDTH,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+1,
|
|
#endif
|
|
ICON_WIDTH, ICON_HEIGHT);
|
|
}
|
|
if(board[i][j].farm) {
|
|
#if (LCD_DEPTH == 16)
|
|
rb->lcd_bitmap_transparent_part(superdom_boarditems,
|
|
#else
|
|
rb->lcd_mono_bitmap_part(superdom_boarditems,
|
|
#endif
|
|
board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT,
|
|
STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+1,
|
|
ICON_WIDTH, ICON_HEIGHT);
|
|
}
|
|
if(board[i][j].tank) {
|
|
#if (LCD_DEPTH == 16)
|
|
rb->lcd_bitmap_transparent_part(superdom_boarditems,
|
|
#else
|
|
rb->lcd_mono_bitmap_part(superdom_boarditems,
|
|
#endif
|
|
board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*2,
|
|
STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
|
|
ICON_WIDTH, ICON_HEIGHT);
|
|
}
|
|
if(board[i][j].men) {
|
|
#if (LCD_DEPTH == 16)
|
|
rb->lcd_bitmap_transparent_part(superdom_boarditems,
|
|
#else
|
|
rb->lcd_mono_bitmap_part(superdom_boarditems,
|
|
#endif
|
|
board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*3,
|
|
#if LCD_WIDTH > LCD_HEIGHT
|
|
STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+1,
|
|
#else
|
|
STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+1+ICON_HEIGHT,
|
|
#endif
|
|
ICON_WIDTH, ICON_HEIGHT);
|
|
}
|
|
if(board[i][j].plane) {
|
|
#if (LCD_DEPTH == 16)
|
|
rb->lcd_bitmap_transparent_part(superdom_boarditems,
|
|
#else
|
|
rb->lcd_mono_bitmap_part(superdom_boarditems,
|
|
#endif
|
|
board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*4,
|
|
#if LCD_WIDTH > LCD_HEIGHT
|
|
STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
|
|
#else
|
|
STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
|
|
#endif
|
|
ICON_WIDTH, ICON_HEIGHT);
|
|
}
|
|
if(board[i][j].nuke) {
|
|
#if (LCD_DEPTH == 16)
|
|
rb->lcd_bitmap_transparent_part(superdom_boarditems,
|
|
#else
|
|
rb->lcd_mono_bitmap_part(superdom_boarditems,
|
|
#endif
|
|
board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*5,
|
|
#if LCD_WIDTH > LCD_HEIGHT
|
|
STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+1,
|
|
#else
|
|
STRIDE,MARGIN+(BOX_WIDTH*(i-1))+1,
|
|
MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
|
|
#endif
|
|
ICON_WIDTH, ICON_HEIGHT);
|
|
}
|
|
#if LCD_DEPTH != 16
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
#endif
|
|
}
|
|
}
|
|
rb->lcd_set_foreground(LCD_BLACK);
|
|
for(i=0;i<=10;i++) { /* Draw Horizontal lines */
|
|
rb->lcd_drawline(MARGIN, MARGIN+(BOX_HEIGHT*i), MARGIN+(BOX_WIDTH*10),
|
|
MARGIN+(BOX_HEIGHT*i));
|
|
}
|
|
for(i=0;i<=10;i++) { /* Draw Vertical lines */
|
|
rb->lcd_drawline(MARGIN+(BOX_WIDTH*i),MARGIN, MARGIN+(BOX_WIDTH*i),
|
|
MARGIN+(BOX_HEIGHT*10));
|
|
}
|
|
rb->lcd_update();
|
|
}
|
|
|
|
int calc_strength(bool colour, int x, int y) {
|
|
int a, b, score=0;
|
|
for (a = -1; a < 2; a++){
|
|
for (b = -1; b < 2; b++){
|
|
if (b == 0){
|
|
if(board[x + a][y].colour == colour)
|
|
score+=10;
|
|
if(((board[x + a][y].colour == colour) && board[x + a][y].tank) || ((board[x + a][y].colour == colour) && board[x + a][y].farm))
|
|
score+=30;
|
|
if(((board[x + a][y].colour == colour) && board[x + a][y].plane) || ((board[x + a][y].colour == colour) && board[x + a][y].ind))
|
|
score+=40;
|
|
if((board[x + a][y].colour == colour) && board[x + a][y].nuke)
|
|
score+=20;
|
|
if((board[x + a][y].colour == colour) && board[x + a][y].men)
|
|
score+=(board[x + a][y].men*133/1000);
|
|
} else if (a == 0){
|
|
if(board[x][y + b].colour == colour)
|
|
score+=10;
|
|
if(((board[x][y + b].colour == colour) && board[x][y + b].tank) || ((board[x][y + b].colour == colour) && board[x][y + b].farm))
|
|
score+=30;
|
|
if(((board[x][y + b].colour == colour) && board[x][y + b].plane) || ((board[x][y + b].colour == colour) && board[x][y + b].ind))
|
|
score+=40;
|
|
if((board[x][y + b].colour == colour) && board[x][y + b].nuke)
|
|
score+=20;
|
|
if((board[x][y + b].colour == colour) && board[x][y + b].men)
|
|
score+=(board[x][y + b].men*133/1000);
|
|
}
|
|
}
|
|
}
|
|
return score;
|
|
}
|
|
|
|
void gen_interest(void) {
|
|
/* Interest should be around 10% */
|
|
rb->srand(*rb->current_tick);
|
|
int interest = 7+rb->rand()%6;
|
|
humanres.bank = humanres.bank+(interest*humanres.bank/100);
|
|
}
|
|
|
|
void draw_cursor(void) {
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(MARGIN+((cursor.x-1)*BOX_WIDTH),
|
|
MARGIN+((cursor.y-1)*BOX_HEIGHT), BOX_WIDTH+1, BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
rb->lcd_update();
|
|
}
|
|
|
|
void gen_resources(void) {
|
|
gen_interest();
|
|
int inccash = 0;
|
|
int incfood = 0;
|
|
int i;
|
|
rb->srand(*rb->current_tick);
|
|
/* Generate Human's resources */
|
|
for(i=0;i<humanres.inds;i++) {
|
|
inccash += (300+rb->rand()%200);
|
|
}
|
|
for(i=0;i<humanres.farms;i++) {
|
|
incfood += (200+rb->rand()%200);
|
|
}
|
|
if(inccash/humanres.inds > 450) {
|
|
if(incfood/humanres.farms > 350) {
|
|
rb->splash(HZ*2, "Patriotism sweeps the land, all production"
|
|
" is up this year!");
|
|
} else {
|
|
rb->splash(HZ*2, "Factories working at maximum efficiency,"
|
|
" cash production up this year!");
|
|
}
|
|
} else if((inccash/humanres.inds>350)&&(inccash/humanres.inds<=450)) {
|
|
if(incfood/humanres.farms > 350) {
|
|
rb->splash(HZ*2, "Record crop harvest this year!");
|
|
} else if((incfood/humanres.farms > 250) &&
|
|
(incfood/humanres.farms <= 350)) {
|
|
rb->splash(HZ*2, "Production continues as normal");
|
|
} else {
|
|
rb->splash(HZ*2, "Spoilage of crops leads to reduced farm"
|
|
" output this year");
|
|
}
|
|
} else {
|
|
if(incfood/humanres.farms > 350) {
|
|
rb->splash(HZ*2, "Record crop harvest this year!");
|
|
} else if((incfood/humanres.farms > 250) &&
|
|
(incfood/humanres.farms <= 350)) {
|
|
rb->splash(HZ*2, "Factory unions introduced. Industrial"
|
|
" production is down this year.");
|
|
} else {
|
|
rb->splash(HZ*2, "Internet created. All production is down"
|
|
" due to time wasted.");
|
|
}
|
|
}
|
|
humanres.cash += inccash;
|
|
humanres.food += incfood;
|
|
|
|
/* Generate Computer's resources */
|
|
inccash = 0;
|
|
incfood = 0;
|
|
for(i=0;i<compres.inds;i++) {
|
|
inccash += (300+rb->rand()%200);
|
|
}
|
|
for(i=0;i<compres.farms;i++) {
|
|
incfood += (200+rb->rand()%200);
|
|
}
|
|
compres.cash += inccash;
|
|
compres.food += incfood;
|
|
}
|
|
|
|
void update_score(void) {
|
|
rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
|
|
rb->lcd_fillrect(5,LCD_HEIGHT-20,105,20);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
rb->snprintf(buf, sizeof(buf), "Your power: %d.%d",
|
|
calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)/10,
|
|
calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)%10);
|
|
rb->lcd_putsxy(5,LCD_HEIGHT-20, buf);
|
|
rb->snprintf(buf, sizeof(buf), "Comp power: %d.%d",
|
|
calc_strength(COLOUR_DARK, cursor.x, cursor.y)/10,
|
|
calc_strength(COLOUR_DARK, cursor.x, cursor.y)%10);
|
|
rb->lcd_putsxy(5,LCD_HEIGHT-10, buf);
|
|
}
|
|
|
|
int settings_menu_function(void) {
|
|
int selection = 0;
|
|
|
|
MENUITEM_STRINGLIST(settings_menu,"Super Domination Settings",NULL,
|
|
"Computer starting farms","Computer starting factories",
|
|
"Human starting farms","Human starting factories",
|
|
"Starting cash","Starting food","Moves per turn");
|
|
settings_menu:
|
|
selection=rb->do_menu(&settings_menu,&selection);
|
|
switch(selection) {
|
|
case 0:
|
|
rb->set_int("Computer starting farms", "", UNIT_INT,
|
|
&superdom_settings.compstartfarms, NULL,
|
|
1, 0, 5, NULL);
|
|
goto settings_menu;
|
|
break;
|
|
case 1:
|
|
rb->set_int("Computer starting factories", "", UNIT_INT,
|
|
&superdom_settings.compstartinds, NULL,
|
|
1, 0, 5, NULL);
|
|
goto settings_menu;
|
|
break;
|
|
case 2:
|
|
rb->set_int("Human starting farms", "", UNIT_INT,
|
|
&superdom_settings.humanstartfarms, NULL,
|
|
1, 0, 5, NULL);
|
|
goto settings_menu;
|
|
break;
|
|
case 3:
|
|
superdom_settings.humanstartinds =
|
|
rb->set_int("Human starting factories", "", UNIT_INT,
|
|
&superdom_settings.humanstartinds, NULL,
|
|
1, 0, 5, NULL);
|
|
goto settings_menu;
|
|
break;
|
|
case 4:
|
|
rb->set_int("Starting cash", "", UNIT_INT,
|
|
&superdom_settings.startcash, NULL,
|
|
250, 0, 5000, NULL);
|
|
goto settings_menu;
|
|
break;
|
|
case 5:
|
|
rb->set_int("Starting food", "", UNIT_INT,
|
|
&superdom_settings.startfood, NULL,
|
|
250, 0, 5000, NULL);
|
|
goto settings_menu;
|
|
break;
|
|
case 6:
|
|
rb->set_int("Moves per turn", "", UNIT_INT,
|
|
&superdom_settings.movesperturn, NULL,
|
|
1, 1, 5, NULL);
|
|
goto settings_menu;
|
|
break;
|
|
case MENU_ATTACHED_USB:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int do_help(void) {
|
|
int selection = 0;
|
|
|
|
MENUITEM_STRINGLIST(help_menu,"Help",NULL,"Super domination is a turn",
|
|
"based strategy game, where the aim is to overpower the",
|
|
"computer player by taking their territory.",
|
|
"Each year you are allocated an amount of cash and food,",
|
|
"depending on how many farms and factories you control."
|
|
"Use this cash and food to buy and feed your army.",
|
|
"Each tile has a strength, calculated by the ownership",
|
|
"of adjacent tiles, and the type and number of troops",
|
|
"on them.");
|
|
rb->do_menu(&help_menu,&selection);
|
|
switch(selection) {
|
|
case MENU_ATTACHED_USB:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int menu(void) {
|
|
int selection = 0;
|
|
|
|
MENUITEM_STRINGLIST(main_menu,"Super Domination Menu",NULL,
|
|
"Play Super Domination","Settings","Help","Quit");
|
|
|
|
while(1) {
|
|
selection=rb->do_menu(&main_menu,&selection);
|
|
switch(selection) {
|
|
case 0:
|
|
return 0; /* start playing */
|
|
break;
|
|
case 1:
|
|
if(settings_menu_function()==PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case 2:
|
|
if(do_help()==PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
default:
|
|
return 2; /* quit program */
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 3;
|
|
}
|
|
|
|
int save_game(void) {
|
|
int fd;
|
|
char savepath[MAX_PATH];
|
|
|
|
rb->snprintf(savepath, sizeof(savepath), "/Savegame.ssg");
|
|
if(rb->kbd_input(savepath, MAX_PATH)) {
|
|
DEBUGF("Keyboard input failed\n");
|
|
return -1;
|
|
}
|
|
|
|
fd = rb->open(savepath, O_WRONLY|O_CREAT);
|
|
DEBUGF("savepath: %s\n", savepath);
|
|
if(fd < 0) {
|
|
DEBUGF("Couldn't create/open file\n");
|
|
return -1;
|
|
}
|
|
|
|
rb->write(fd, "SSGv2", 5);
|
|
rb->write(fd, &humanres.cash, sizeof(humanres.cash));
|
|
rb->write(fd, &humanres.food, sizeof(humanres.food));
|
|
rb->write(fd, &humanres.bank, sizeof(humanres.bank));
|
|
rb->write(fd, &humanres.planes, sizeof(humanres.planes));
|
|
rb->write(fd, &humanres.tanks, sizeof(humanres.tanks));
|
|
rb->write(fd, &humanres.men, sizeof(humanres.men));
|
|
rb->write(fd, &humanres.nukes, sizeof(humanres.nukes));
|
|
rb->write(fd, &humanres.inds, sizeof(humanres.inds));
|
|
rb->write(fd, &humanres.farms, sizeof(humanres.farms));
|
|
rb->write(fd, &humanres.moves, sizeof(humanres.moves));
|
|
rb->write(fd, &compres.cash, sizeof(compres.cash));
|
|
rb->write(fd, &compres.food, sizeof(compres.food));
|
|
rb->write(fd, &compres.bank, sizeof(compres.bank));
|
|
rb->write(fd, &compres.planes, sizeof(compres.planes));
|
|
rb->write(fd, &compres.tanks, sizeof(compres.tanks));
|
|
rb->write(fd, &compres.men, sizeof(compres.men));
|
|
rb->write(fd, &compres.nukes, sizeof(compres.nukes));
|
|
rb->write(fd, &compres.inds, sizeof(compres.inds));
|
|
rb->write(fd, &compres.farms, sizeof(compres.farms));
|
|
rb->write(fd, &compres.moves, sizeof(compres.moves));
|
|
rb->write(fd, board, sizeof(board));
|
|
rb->write(fd, &superdom_settings.compstartfarms, sizeof(int));
|
|
rb->write(fd, &superdom_settings.compstartinds, sizeof(int));
|
|
rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
|
|
rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
|
|
rb->write(fd, &superdom_settings.startcash, sizeof(int));
|
|
rb->write(fd, &superdom_settings.startfood, sizeof(int));
|
|
rb->write(fd, &superdom_settings.movesperturn, sizeof(int));
|
|
rb->close(fd);
|
|
return 0;
|
|
}
|
|
|
|
int ingame_menu(void) {
|
|
int selection = 0;
|
|
|
|
MENUITEM_STRINGLIST(ingame_menu,"Super Domination Menu",NULL,
|
|
"Return to game","Save Game", "Quit");
|
|
|
|
selection=rb->do_menu(&ingame_menu,&selection);
|
|
switch(selection) {
|
|
case 0:
|
|
return 0;
|
|
break;
|
|
case 1:
|
|
if(!save_game())
|
|
rb->splash(HZ, "Game saved");
|
|
else
|
|
rb->splash(HZ, "Error in save");
|
|
break;
|
|
case 2:
|
|
return SUPERDOM_QUIT;
|
|
break;
|
|
case MENU_ATTACHED_USB:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int get_number(char* param, int* value) {
|
|
//int numbers[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
|
|
int numbers[3][3];
|
|
numbers[0][0] = 1;
|
|
numbers[0][1] = 2;
|
|
numbers[0][2] = 3;
|
|
numbers[1][0] = 4;
|
|
numbers[1][1] = 5;
|
|
numbers[1][2] = 6;
|
|
numbers[2][0] = 7;
|
|
numbers[2][1] = 8;
|
|
numbers[2][2] = 9;
|
|
rb->lcd_clear_display();
|
|
/* Draw a 3x4 grid */
|
|
int i,j,x=0,y=0;
|
|
for(i=0;i<=3;i++) { /* Vertical lines */
|
|
rb->lcd_drawline(NUM_MARGIN_X+(NUM_BOX_WIDTH*i), NUM_MARGIN_Y,
|
|
NUM_MARGIN_X+(NUM_BOX_WIDTH*i),
|
|
NUM_MARGIN_Y+(4*NUM_BOX_HEIGHT));
|
|
}
|
|
for(i=0;i<=4;i++) { /* Horizontal lines */
|
|
rb->lcd_drawline(NUM_MARGIN_X, NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT),
|
|
NUM_MARGIN_X+(3*NUM_BOX_WIDTH),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*i));
|
|
}
|
|
int temp = 1;
|
|
for(i=0;i<3;i++) {
|
|
for(j=0;j<3;j++) {
|
|
rb->snprintf(buf, sizeof(buf), "%d", temp);
|
|
rb->lcd_putsxy(NUM_MARGIN_X+(j*NUM_BOX_WIDTH)+10,
|
|
NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT)+8, buf);
|
|
temp++;
|
|
}
|
|
}
|
|
rb->lcd_putsxy(NUM_MARGIN_X+5, NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "CLR");
|
|
rb->lcd_putsxy(NUM_MARGIN_X+NUM_BOX_WIDTH+10,
|
|
NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "0");
|
|
rb->lcd_putsxy(NUM_MARGIN_X+2*NUM_BOX_WIDTH+8,
|
|
NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "OK");
|
|
rb->snprintf(buf,sizeof(buf), "%d", *value);
|
|
rb->lcd_putsxy(NUM_MARGIN_X+10, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
|
|
int height, width;
|
|
rb->lcd_getstringsize(param, &width, &height);
|
|
rb->lcd_putsxy((LCD_WIDTH-width)/2, (NUM_MARGIN_Y-height)/2, param);
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y), NUM_BOX_WIDTH+1,
|
|
NUM_BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
int button = 0;
|
|
rb->lcd_update();
|
|
while(1) {
|
|
button = rb->button_get(true);
|
|
switch(button) {
|
|
case SUPERDOM_OK:
|
|
*value *= 10;
|
|
if(y!=3) {
|
|
*value += numbers[y][x];
|
|
} else if(y==3 && x==0) {
|
|
*value /= 100;
|
|
} else if(y==3 && x==2) {
|
|
*value /= 10;
|
|
return 0;
|
|
}
|
|
rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
|
|
rb->lcd_fillrect(0, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10,
|
|
LCD_WIDTH, 30);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
rb->snprintf(buf,sizeof(buf), "%d", *value);
|
|
rb->lcd_putsxy(NUM_MARGIN_X+10,
|
|
NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
|
|
break;
|
|
case SUPERDOM_CANCEL:
|
|
return 0;
|
|
break;
|
|
#if CONFIG_KEYPAD != IRIVER_H10_PAD
|
|
case SUPERDOM_LEFT:
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
|
|
NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
if(x==0) {
|
|
#ifdef IPOD_STYLE
|
|
if(y>0)
|
|
y--;
|
|
else
|
|
y=3;
|
|
#endif
|
|
x=2;
|
|
} else {
|
|
x--;
|
|
}
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
|
|
NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
break;
|
|
case SUPERDOM_RIGHT:
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
|
|
NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
if(x==2) {
|
|
#ifdef IPOD_STYLE
|
|
if(y==3)
|
|
y=0;
|
|
else
|
|
y++;
|
|
#endif
|
|
x=0;
|
|
} else {
|
|
x++;
|
|
}
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
|
|
NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
break;
|
|
#endif
|
|
#ifndef IPOD_STYLE
|
|
case SUPERDOM_UP:
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
|
|
NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
if(y==0) {
|
|
#if CONFIG_KEYPAD == IRIVER_H10_PAD
|
|
if(x > 0)
|
|
x--;
|
|
else
|
|
x=2;
|
|
#endif
|
|
y=3;
|
|
} else {
|
|
y--;
|
|
}
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
|
|
NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
break;
|
|
case SUPERDOM_DOWN:
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
|
|
NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
if(y==3) {
|
|
#if CONFIG_KEYPAD == IRIVER_H10_PAD
|
|
if(x < 2)
|
|
x++;
|
|
else
|
|
x=0;
|
|
#endif
|
|
y=0;
|
|
} else {
|
|
y++;
|
|
}
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
|
|
rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
|
|
NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
|
|
NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
break;
|
|
#endif
|
|
default:
|
|
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
|
|
{
|
|
return PLUGIN_USB_CONNECTED;
|
|
}
|
|
break;
|
|
}
|
|
rb->lcd_update();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int buy_resources_menu(void) {
|
|
int selection,tempmenu,nummen;
|
|
|
|
MENUITEM_STRINGLIST(res_menu, "Buy Resources", NULL, "Buy men ($1)",
|
|
"Buy tank ($300)", "Buy plane ($600)", "Buy Farm ($1150)",
|
|
"Buy Factory ($1300)", "Buy Nuke ($2000)",
|
|
"Finish buying", "Game menu");
|
|
|
|
resources_menu:
|
|
selection=rb->do_menu(&res_menu,&selection);
|
|
switch(selection) {
|
|
case 0:
|
|
nummen = 0;
|
|
if(get_number("How many men would you like?", &nummen)
|
|
== PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if(humanres.cash>=nummen) {
|
|
rb->splash(HZ, "Where do you want to place them?");
|
|
tempmenu = select_square();
|
|
switch(tempmenu) {
|
|
case 0:
|
|
rb->splash(HZ, "Cancelled");
|
|
break;
|
|
case 2:
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
humanres.men += nummen;
|
|
board[cursor.x][cursor.y].men += nummen;
|
|
humanres.cash -= nummen;
|
|
} else {
|
|
rb->splash(HZ,"Can't place men on enemy territory");
|
|
}
|
|
break;
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Not enough money!");
|
|
}
|
|
goto resources_menu;
|
|
break;
|
|
case 1:
|
|
if(humanres.cash>=300) {
|
|
rb->splash(HZ, "Where do you want to place the tank?");
|
|
tempmenu = select_square();
|
|
switch(tempmenu) {
|
|
case 0:
|
|
rb->splash(HZ, "Cancelled");
|
|
goto resources_menu;
|
|
break;
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
if(board[cursor.x][cursor.y].tank) {
|
|
rb->splash(HZ, "There is already a tank there");
|
|
} else {
|
|
board[cursor.x][cursor.y].tank = true;
|
|
humanres.cash -= 300;
|
|
humanres.tanks++;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Can't place men on enemy territory");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Not enough money!");
|
|
}
|
|
goto resources_menu;
|
|
break;
|
|
case 2:
|
|
if(humanres.cash>=600) {
|
|
rb->splash(HZ, "Where do you want to place the plane?");
|
|
tempmenu = select_square();
|
|
switch(tempmenu) {
|
|
case 0:
|
|
rb->splash(HZ, "Cancelled");
|
|
goto resources_menu;
|
|
break;
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
if(board[cursor.x][cursor.y].plane) {
|
|
rb->splash(HZ, "There is already a plane there");
|
|
} else {
|
|
board[cursor.x][cursor.y].plane = true;
|
|
humanres.cash -= 600;
|
|
humanres.planes++;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Can't place men on enemy territory");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Not enough money!");
|
|
}
|
|
goto resources_menu;
|
|
break;
|
|
case 3:
|
|
if(humanres.cash>=1150) {
|
|
rb->splash(HZ, "Where do you want to place the farm?");
|
|
tempmenu = select_square();
|
|
switch(tempmenu) {
|
|
case 0:
|
|
rb->splash(HZ, "Cancelled");
|
|
goto resources_menu;
|
|
break;
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
if(board[cursor.x][cursor.y].farm) {
|
|
rb->splash(HZ, "There is already a farm there");
|
|
} else {
|
|
board[cursor.x][cursor.y].farm = true;
|
|
humanres.cash -= 1150;
|
|
humanres.farms++;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Can't build on enemy territory");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Not enough money!");
|
|
}
|
|
goto resources_menu;
|
|
break;
|
|
case 4:
|
|
if(humanres.cash>=1300) {
|
|
rb->splash(HZ, "Where do you want to place the industrial"
|
|
" plant?");
|
|
tempmenu = select_square();
|
|
switch(tempmenu) {
|
|
case 0:
|
|
rb->splash(HZ, "Cancelled");
|
|
goto resources_menu;
|
|
break;
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
if(board[cursor.x][cursor.y].ind) {
|
|
rb->splash(HZ, "There is already an industrial"
|
|
" plant there");
|
|
} else {
|
|
board[cursor.x][cursor.y].ind = true;
|
|
humanres.cash -= 1300;
|
|
humanres.inds++;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Can't build on enemy territory");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Not enough money!");
|
|
}
|
|
goto resources_menu;
|
|
break;
|
|
case 5:
|
|
if(humanres.cash>=2000) {
|
|
rb->splash(HZ, "Where do you want to place the nuke?");
|
|
tempmenu = select_square();
|
|
switch(tempmenu) {
|
|
case 0:
|
|
rb->splash(HZ, "Cancelled");
|
|
goto resources_menu;
|
|
break;
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
if(board[cursor.x][cursor.y].nuke) {
|
|
rb->splash(HZ, "There is already a nuke there");
|
|
} else {
|
|
board[cursor.x][cursor.y].nuke = true;
|
|
humanres.cash -= 2000;
|
|
humanres.nukes++;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Can't place a nuke on enemy territory");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Not enough money!");
|
|
}
|
|
goto resources_menu;
|
|
break;
|
|
case 6:
|
|
return 0;
|
|
break;
|
|
case MENU_ATTACHED_USB:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int move_unit(void) {
|
|
int selection, nummen;
|
|
struct cursor from;
|
|
|
|
MENUITEM_STRINGLIST(move_unit_menu, "Move unit", NULL, "Move men",
|
|
"Move tank", "Move plane");
|
|
selection=rb->do_menu(&move_unit_menu,&selection);
|
|
switch(selection) {
|
|
case 0:
|
|
rb->splash(HZ, "Select where to move troops from");
|
|
if(select_square() == PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
if(board[cursor.x][cursor.y].men) {
|
|
from.x = cursor.x;
|
|
from.y = cursor.y;
|
|
nummen = board[from.x][from.y].men;
|
|
if(get_number("How many men do you want to move?",
|
|
&nummen) == PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if(nummen > board[from.x][from.y].men) {
|
|
rb->splash(HZ, "You don't have that many troops.");
|
|
} else {
|
|
rb->splash(HZ,"Select where to move the troops to");
|
|
if(select_square() == PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if((board[cursor.x][cursor.y].colour == COLOUR_LIGHT) &&
|
|
(abs(cursor.x - from.x) <= 1) &&
|
|
abs(cursor.y - from.y) <= 1) {
|
|
board[from.x][from.y].men -= nummen;
|
|
board[cursor.x][cursor.y].men += nummen;
|
|
humanres.moves--;
|
|
return 0;
|
|
}
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "You don't have any troops there");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Can't move enemy troops");
|
|
}
|
|
break;
|
|
case 1:
|
|
rb->splash(HZ, "Select where you want to move the tank from");
|
|
if(select_square() == PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
if(board[cursor.x][cursor.y].tank) {
|
|
from.x = cursor.x;
|
|
from.y = cursor.y;
|
|
rb->splash(HZ, "Select where you want"
|
|
" to move the tank to");
|
|
if(select_square() == PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if((board[cursor.x][cursor.y].colour == COLOUR_LIGHT)&&
|
|
(abs(cursor.x-from.x) <= 1) &&
|
|
(abs(cursor.y-from.y) <= 1)) {
|
|
if(board[cursor.x][cursor.y].tank) {
|
|
rb->splash(HZ, "There is already a tank there");
|
|
} else {
|
|
board[from.x][from.y].tank = false;
|
|
board[cursor.x][cursor.y].tank = true;
|
|
humanres.moves--;
|
|
return 0;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Invalid move");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "You don't have a tank there");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "That isn't your territory");
|
|
}
|
|
break;
|
|
case 2:
|
|
rb->splash(HZ, "Select where you want"
|
|
" to move the plane from");
|
|
if(select_square() == PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
if(board[cursor.x][cursor.y].plane) {
|
|
from.x = cursor.x;
|
|
from.y = cursor.y;
|
|
rb->splash(HZ, "Select where you want"
|
|
" to move the plane to");
|
|
if(select_square() == PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
|
|
if(board[cursor.x][cursor.y].plane) {
|
|
rb->splash(HZ,"There is already a plane there");
|
|
} else {
|
|
board[from.x][from.y].plane = false;
|
|
board[cursor.x][cursor.y].plane = true;
|
|
humanres.moves--;
|
|
return 0;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Invalid move");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "You don't have a plane there");
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "That isn't your territory");
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int movement_menu(void) {
|
|
int selection, tempmenu;
|
|
bool menu_quit = false;
|
|
|
|
MENUITEM_STRINGLIST(move_menu, "Movement", NULL, "Move unit",
|
|
"Buy additional moves ($100)", "Launch nuclear missile",
|
|
"Check map", "Finish moving", "Game menu");
|
|
|
|
while(!menu_quit) {
|
|
selection=rb->do_menu(&move_menu,&selection);
|
|
switch(selection) {
|
|
case 0:
|
|
if(humanres.moves) {
|
|
if(move_unit()==PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
} else {
|
|
rb->splash(HZ, "You have no more moves left."
|
|
" You can buy more for $100 each.");
|
|
}
|
|
break;
|
|
case 1:
|
|
if(humanres.cash > 100) {
|
|
humanres.moves++;
|
|
humanres.cash -= 100;
|
|
rb->snprintf(buf, sizeof(buf), "You now have %d moves",
|
|
humanres.moves);
|
|
rb->splash(HZ, buf);
|
|
}
|
|
break;
|
|
case 2:
|
|
if(humanres.nukes==0) {
|
|
rb->splash(HZ, "You do not have any nukes to launch");
|
|
} else {
|
|
rb->splash(HZ, "Select place to launch nuke from");
|
|
if(select_square() == PLUGIN_USB_CONNECTED) {
|
|
return PLUGIN_USB_CONNECTED;
|
|
}
|
|
if(board[cursor.x][cursor.y].nuke) {
|
|
rb->splash(HZ, "Select place to target with nuke");
|
|
if(select_square() == PLUGIN_USB_CONNECTED) {
|
|
return PLUGIN_USB_CONNECTED;
|
|
}
|
|
board[cursor.x][cursor.y].men = 0;
|
|
board[cursor.x][cursor.y].tank = 0;
|
|
board[cursor.x][cursor.y].plane = 0;
|
|
board[cursor.x][cursor.y].ind = 0;
|
|
board[cursor.x][cursor.y].nuke = 0;
|
|
board[cursor.x][cursor.y].farm = 0;
|
|
/* TODO: Fallout carried by wind */
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
if(select_square() == PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case 4:
|
|
return 0;
|
|
break;
|
|
case 5:
|
|
tempmenu = ingame_menu();
|
|
switch(tempmenu) {
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case SUPERDOM_QUIT:
|
|
return SUPERDOM_QUIT;
|
|
break;
|
|
}
|
|
break;
|
|
case MENU_ATTACHED_USB:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int show_inventory(void) {
|
|
rb->lcd_clear_display();
|
|
rb->lcd_puts(1, 0, "Inventory");
|
|
char men[20], tanks[20], planes[20], inds[20], farms[20], nukes[20],
|
|
cash[20], food[20], bank[20];
|
|
rb->snprintf(men, sizeof(men), "Men: %d", humanres.men);
|
|
rb->snprintf(tanks, sizeof(tanks), "Tanks: %d", humanres.tanks);
|
|
rb->snprintf(planes, sizeof(planes), "Planes: %d", humanres.planes);
|
|
rb->snprintf(inds, sizeof(inds), "Factories: %d", humanres.inds);
|
|
rb->snprintf(farms, sizeof(farms), "Farms: %d", humanres.farms);
|
|
rb->snprintf(nukes, sizeof(nukes), "Nukes: %d", humanres.nukes);
|
|
rb->snprintf(cash, sizeof(cash), "Cash: %d", humanres.cash);
|
|
rb->snprintf(food, sizeof(food), "Food: %d", humanres.food);
|
|
rb->snprintf(bank, sizeof(bank), "Bank: %d", humanres.bank);
|
|
rb->lcd_puts(2, 1, men);
|
|
rb->lcd_puts(2, 2, tanks);
|
|
rb->lcd_puts(2, 3, planes);
|
|
rb->lcd_puts(2, 4, inds);
|
|
rb->lcd_puts(2, 5, farms);
|
|
rb->lcd_puts(2, 6, nukes);
|
|
rb->lcd_puts(2, 7, cash);
|
|
rb->lcd_puts(2, 8, food);
|
|
rb->lcd_puts(2, 9, bank);
|
|
rb->lcd_update();
|
|
if(rb->default_event_handler(rb->button_get(true)) == SYS_USB_CONNECTED) {
|
|
return PLUGIN_USB_CONNECTED;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int production_menu(void) {
|
|
int selection, tempbank, tempmenu;
|
|
|
|
MENUITEM_STRINGLIST(prod_menu, "Production", NULL, "Buy resources",
|
|
"Show inventory", "Check map", "Invest money",
|
|
"Withdraw money", "Finish turn", "Game menu");
|
|
|
|
while(1) {
|
|
selection=rb->do_menu(&prod_menu,&selection);
|
|
switch(selection) {
|
|
case 0:
|
|
tempmenu = buy_resources_menu();
|
|
switch(tempmenu) {
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case SUPERDOM_QUIT:
|
|
return SUPERDOM_QUIT;
|
|
break;
|
|
}
|
|
break;
|
|
case 1:
|
|
tempmenu = show_inventory();
|
|
switch(tempmenu) {
|
|
case 0:
|
|
break;
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
break;
|
|
case 2:
|
|
tempmenu = select_square();
|
|
switch(tempmenu) {
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case SUPERDOM_QUIT:
|
|
return SUPERDOM_QUIT;
|
|
break;
|
|
case 0:
|
|
break;
|
|
}
|
|
break;
|
|
case 3:
|
|
tempbank = humanres.cash;
|
|
if(get_number("How much do you want to invest?", &tempbank)
|
|
== PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if(tempbank>humanres.cash) {
|
|
rb->splash(HZ, "You don't have that much cash to invest");
|
|
} else {
|
|
humanres.cash -= tempbank;
|
|
humanres.bank += tempbank;
|
|
}
|
|
break;
|
|
case 4:
|
|
tempbank = 0;
|
|
if(get_number("How much do you want to withdraw?", &tempbank)
|
|
== PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if(tempbank>humanres.bank) {
|
|
rb->splash(HZ, "You don't have that much cash to withdraw");
|
|
} else {
|
|
humanres.cash += tempbank;
|
|
humanres.bank -= tempbank;
|
|
}
|
|
break;
|
|
case 5:
|
|
return 0;
|
|
break;
|
|
case 6:
|
|
tempmenu = ingame_menu();
|
|
switch(tempmenu) {
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case SUPERDOM_QUIT:
|
|
return SUPERDOM_QUIT;
|
|
break;
|
|
}
|
|
break;
|
|
case MENU_ATTACHED_USB:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void init_resources(void) {
|
|
humanres.cash = superdom_settings.startcash;
|
|
humanres.food = superdom_settings.startfood;
|
|
humanres.tanks = 0;
|
|
humanres.planes = 0;
|
|
humanres.nukes = 0;
|
|
humanres.inds = 0;
|
|
humanres.farms = 0;
|
|
humanres.men = 0;
|
|
humanres.bank = 0;
|
|
humanres.moves = 0;
|
|
compres.cash = superdom_settings.startcash;
|
|
compres.food = superdom_settings.startfood;
|
|
compres.tanks = 0;
|
|
compres.planes = 0;
|
|
compres.nukes = 0;
|
|
compres.inds = 0;
|
|
compres.farms = 0;
|
|
compres.men = 0;
|
|
compres.bank = 0;
|
|
compres.moves = 0;
|
|
}
|
|
|
|
int select_square(void) {
|
|
draw_board();
|
|
draw_cursor();
|
|
update_score();
|
|
#if LCD_WIDTH >= 220
|
|
rb->snprintf(buf, sizeof(buf), "Cash: %d", humanres.cash);
|
|
rb->lcd_putsxy(125, LCD_HEIGHT-20, buf);
|
|
rb->snprintf(buf, sizeof(buf), "Food: %d", humanres.food);
|
|
rb->lcd_putsxy(125, LCD_HEIGHT-10, buf);
|
|
#endif
|
|
rb->lcd_update();
|
|
int button = 0;
|
|
while(1) {
|
|
button = rb->button_get(true);
|
|
switch(button) {
|
|
case SUPERDOM_CANCEL:
|
|
return 0;
|
|
break;
|
|
case SUPERDOM_OK:
|
|
return 2;
|
|
break;
|
|
#if CONFIG_KEYPAD != IRIVER_H10_PAD
|
|
case SUPERDOM_LEFT:
|
|
case (SUPERDOM_LEFT|BUTTON_REPEAT):
|
|
draw_cursor(); /* Deselect the current tile */
|
|
if(cursor.x>1) {
|
|
cursor.x--;
|
|
} else {
|
|
#ifdef IPOD_STYLE
|
|
if(cursor.y>1)
|
|
cursor.y--;
|
|
else
|
|
cursor.y = 10;
|
|
#endif
|
|
cursor.x = 10;
|
|
}
|
|
update_score();
|
|
draw_cursor();
|
|
break;
|
|
case SUPERDOM_RIGHT:
|
|
case (SUPERDOM_RIGHT|BUTTON_REPEAT):
|
|
draw_cursor(); /* Deselect the current tile */
|
|
if(cursor.x<10) {
|
|
cursor.x++;
|
|
} else {
|
|
#ifdef IPOD_STYLE
|
|
if(cursor.y<10)
|
|
cursor.y++;
|
|
else
|
|
cursor.y = 1;
|
|
#endif
|
|
cursor.x = 1;
|
|
}
|
|
update_score();
|
|
draw_cursor();
|
|
break;
|
|
#endif
|
|
#ifndef IPOD_STYLE
|
|
case SUPERDOM_UP:
|
|
case (SUPERDOM_UP|BUTTON_REPEAT):
|
|
draw_cursor(); /* Deselect the current tile */
|
|
if(cursor.y>1) {
|
|
cursor.y--;
|
|
} else {
|
|
#if CONFIG_KEYPAD == IRIVER_H10_PAD
|
|
if(cursor.x > 1)
|
|
cursor.x--;
|
|
else
|
|
cursor.x = 10;
|
|
#endif
|
|
cursor.y = 10;
|
|
}
|
|
update_score();
|
|
draw_cursor();
|
|
break;
|
|
case SUPERDOM_DOWN:
|
|
case (SUPERDOM_DOWN|BUTTON_REPEAT):
|
|
draw_cursor(); /* Deselect the current tile */
|
|
if(cursor.y<10) {
|
|
cursor.y++;
|
|
} else {
|
|
#if CONFIG_KEYPAD == IRIVER_H10_PAD
|
|
if(cursor.x < 10)
|
|
cursor.x++;
|
|
else
|
|
cursor.x = 1;
|
|
#endif
|
|
cursor.y = 1;
|
|
}
|
|
update_score();
|
|
draw_cursor();
|
|
break;
|
|
#endif
|
|
default:
|
|
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
|
|
{
|
|
return PLUGIN_USB_CONNECTED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int killmen(bool human) {
|
|
int menkilled,i,j;
|
|
int percent;
|
|
if(human) {
|
|
percent = (humanres.food*1000)/humanres.men;
|
|
humanres.food = 0;
|
|
} else {
|
|
percent = (compres.food*1000)/compres.men;
|
|
compres.food = 0;
|
|
}
|
|
menkilled = 0;
|
|
for(i=1;i<12;i++) {
|
|
for(j=1;j<12;j++) {
|
|
if(board[i][j].colour == human) {
|
|
menkilled += ((board[i][j].men * percent)/1000);
|
|
board[i][j].men = (board[i][j].men * percent)/1000;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(human)
|
|
humanres.men -= menkilled;
|
|
else
|
|
compres.men -= menkilled;
|
|
return menkilled;
|
|
}
|
|
|
|
int war_menu(void) {
|
|
int selection, tempmenu;
|
|
|
|
MENUITEM_STRINGLIST(wartime_menu, "War!", NULL,
|
|
"Select territory to attack", "Finish turn", "Game menu");
|
|
|
|
humanres.moves = superdom_settings.movesperturn;
|
|
while(humanres.moves) {
|
|
selection=rb->do_menu(&wartime_menu,&selection);
|
|
switch(selection) {
|
|
case 0:
|
|
if(select_square() == PLUGIN_USB_CONNECTED)
|
|
return PLUGIN_USB_CONNECTED;
|
|
if(board[cursor.x][cursor.y].colour == COLOUR_DARK) {
|
|
if(calc_strength(COLOUR_LIGHT, cursor.x,
|
|
cursor.y) > calc_strength(COLOUR_DARK,
|
|
cursor.x, cursor.y)) {
|
|
board[cursor.x][cursor.y].colour = COLOUR_LIGHT;
|
|
board[cursor.x][cursor.y].tank = 0;
|
|
board[cursor.x][cursor.y].men = 0;
|
|
board[cursor.x][cursor.y].plane = 0;
|
|
board[cursor.x][cursor.y].nuke = 0;
|
|
draw_board();
|
|
rb->sleep(HZ*2);
|
|
humanres.moves--;
|
|
} else if(calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)==
|
|
calc_strength(COLOUR_DARK, cursor.x, cursor.y)) {
|
|
if(rb->rand()%2) {
|
|
board[cursor.x][cursor.y].colour = COLOUR_LIGHT;
|
|
board[cursor.x][cursor.y].tank = 0;
|
|
board[cursor.x][cursor.y].men = 0;
|
|
board[cursor.x][cursor.y].plane = 0;
|
|
board[cursor.x][cursor.y].nuke = 0;
|
|
draw_board();
|
|
rb->sleep(HZ*2);
|
|
humanres.moves--;
|
|
} else {
|
|
rb->splash(HZ, "Your troops were unable to"
|
|
" overcome the enemy troops");
|
|
humanres.moves--;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "Your troops were unable to overcome"
|
|
" the enemy troops");
|
|
humanres.moves--;
|
|
}
|
|
} else {
|
|
rb->splash(HZ, "You can't attack your own territory");
|
|
}
|
|
break;
|
|
case 1:
|
|
return 0;
|
|
break;
|
|
case 2:
|
|
tempmenu = ingame_menu();
|
|
switch(tempmenu) {
|
|
case PLUGIN_USB_CONNECTED:
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case SUPERDOM_QUIT:
|
|
return SUPERDOM_QUIT;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct threat {
|
|
int x;
|
|
int y;
|
|
int str_diff;
|
|
};
|
|
|
|
bool place_adjacent(bool tank, int x, int y) {
|
|
if(tank) {
|
|
if(!board[x-1][y].tank && (board[x][y].colour==board[x-1][y].colour)) {
|
|
compres.cash -= 300;
|
|
board[x-1][y].tank = true;
|
|
compres.tanks++;
|
|
return 0;
|
|
}
|
|
if(!board[x+1][y].tank && (board[x][y].colour==board[x+1][y].colour)) {
|
|
compres.cash -= 300;
|
|
board[x+1][y].tank = true;
|
|
compres.tanks++;
|
|
return 0;
|
|
}
|
|
if(!board[x][y-1].tank && (board[x][y].colour==board[x][y-1].colour)) {
|
|
compres.cash -= 300;
|
|
board[x][y-1].tank = true;
|
|
compres.tanks++;
|
|
return 0;
|
|
}
|
|
if(!board[x][y+1].tank && (board[x][y].colour==board[x][y+1].colour)) {
|
|
compres.cash -= 300;
|
|
board[x][y+1].tank = true;
|
|
compres.tanks++;
|
|
return 0;
|
|
}
|
|
} else {
|
|
if(!board[x-1][y].plane && (board[x][y].colour==board[x-1][y].colour)) {
|
|
compres.cash -= 600;
|
|
board[x-1][y].plane = true;
|
|
compres.planes++;
|
|
return 0;
|
|
}
|
|
if(!board[x+1][y].plane && (board[x][y].colour==board[x+1][y].colour)) {
|
|
compres.cash -= 600;
|
|
board[x+1][y].plane = true;
|
|
compres.planes++;
|
|
return 0;
|
|
}
|
|
if(!board[x][y-1].plane && (board[x][y].colour==board[x][y-1].colour)) {
|
|
compres.cash -= 600;
|
|
board[x][y-1].plane = true;
|
|
compres.planes++;
|
|
return 0;
|
|
}
|
|
if(!board[x][y+1].plane && (board[x][y].colour==board[x][y+1].colour)) {
|
|
compres.cash -= 600;
|
|
board[x][y+1].plane = true;
|
|
compres.planes++;
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
bool has_adjacent(int x, int y) {
|
|
if((board[x][y].colour == COLOUR_LIGHT) &&
|
|
((board[x-1][y].colour == COLOUR_DARK) ||
|
|
(board[x+1][y].colour == COLOUR_DARK) ||
|
|
(board[x][y+1].colour == COLOUR_DARK) ||
|
|
(board[x][y-1].colour == COLOUR_DARK)))
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void find_adjacent(int x, int y, int* adj_x, int* adj_y, bool* full) {
|
|
/* Finds adjacent squares, returning squares without tanks on them
|
|
* in preference to those with them */
|
|
if(((board[x-1][y].tank && (board[x-1][y].colour == COLOUR_DARK)) ||
|
|
board[x-1][y].colour != COLOUR_DARK) &&
|
|
((board[x+1][y].tank && (board[x+1][y].colour == COLOUR_DARK)) ||
|
|
board[x+1][y].colour != COLOUR_DARK) &&
|
|
((board[x][y-1].tank && (board[x][y-1].colour == COLOUR_DARK)) ||
|
|
board[x][y-1].colour != COLOUR_DARK) &&
|
|
((board[x][y+1].tank && (board[x][y+1].colour == COLOUR_DARK)) ||
|
|
board[x][y+1].colour != COLOUR_DARK)) {
|
|
*full = true;
|
|
} else {
|
|
*full = false;
|
|
}
|
|
|
|
if(board[x-1][y].colour == COLOUR_DARK) {
|
|
*adj_x = x-1;
|
|
*adj_y = y;
|
|
if(board[x-1][y].tank) {
|
|
if(*full)
|
|
return;
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
if(board[x+1][y].colour == COLOUR_DARK) {
|
|
*adj_x = x+1;
|
|
*adj_y = y;
|
|
if(board[x+1][y].tank) {
|
|
if(*full)
|
|
return;
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
if(board[x][y-1].colour == COLOUR_DARK) {
|
|
*adj_x = x;
|
|
*adj_y = y-1;
|
|
if(board[x][y-1].tank) {
|
|
if(*full)
|
|
return;
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
if(board[x][y+1].colour == COLOUR_DARK) {
|
|
*adj_x = x;
|
|
*adj_y = y+1;
|
|
if(board[x][y+1].tank) {
|
|
if(*full)
|
|
return;
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void computer_allocate(void) {
|
|
/* Firstly, decide whether to go offensive or defensive.
|
|
* This is primarily decided by the human player posing a threat to either
|
|
* the computer's farms or factories */
|
|
int i, j, k;
|
|
bool offensive = true;
|
|
struct threat threats[4];
|
|
int numthreats = 0;
|
|
int total_str_diff = 0;
|
|
int men_needed;
|
|
struct threat targets[2];
|
|
int numtargets;
|
|
struct cursor adj;
|
|
bool full = false;
|
|
for(i=1;i<12;i++) {
|
|
for(j=1;j<12;j++) {
|
|
if((board[i][j].colour == COLOUR_DARK) &&
|
|
(calc_strength(COLOUR_DARK,i,j) <
|
|
calc_strength(COLOUR_LIGHT,i,j))) {
|
|
if(board[i][j].ind || board[i][j].farm) {
|
|
if(numthreats < 3) {
|
|
offensive = false;
|
|
threats[numthreats].x = i;
|
|
threats[numthreats].y = j;
|
|
threats[numthreats].str_diff =
|
|
calc_strength(COLOUR_LIGHT,i,j) -
|
|
calc_strength(COLOUR_DARK,i,j);
|
|
numthreats++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(offensive) {
|
|
/* The AI is going to go straight for the throat here and attack
|
|
* the player's farms and factories. The amount of cash
|
|
* the AI has to spend will determine how many targets there are */
|
|
if(compres.cash > 1200) {
|
|
/* 1200 is a figure I pulled out of nowhere. Adjust as needed */
|
|
numtargets = 2;
|
|
} else {
|
|
numtargets = 1;
|
|
}
|
|
/* Work out which target(s) to attack. They must have adjacent squares
|
|
* owned by the computer. If none are found just place troops in
|
|
* random places around the map until we run out of money */
|
|
k = 0;
|
|
while(k<numtargets) {
|
|
for(i=1;i<12;i++) {
|
|
for(j=1;j<12;j++) {
|
|
if((board[i][j].colour == COLOUR_LIGHT) &&
|
|
(board[i][j].ind || board[i][j].farm) &&
|
|
has_adjacent(i,j)) {
|
|
targets[k].x = i;
|
|
targets[k].y = j;
|
|
targets[k].str_diff = abs(calc_strength(COLOUR_LIGHT,
|
|
i, j) - calc_strength(COLOUR_DARK,
|
|
i, j));
|
|
k++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(k == 0) {
|
|
/* No targets found! Randomly pick squares and if they're owned
|
|
* by the computer then stick a tank on it. */
|
|
rb->srand(*rb->current_tick);
|
|
while(compres.cash >= 300) {
|
|
i = rb->rand()%11 + 1;
|
|
j = rb->rand()%11 + 1;
|
|
if(board[i][j].colour == COLOUR_DARK) {
|
|
if(compres.cash >= 300) {
|
|
if(!board[i][j].tank) {
|
|
board[i][j].tank = true;
|
|
compres.tanks++;
|
|
compres.cash -= 300;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
compres.bank += compres.cash;
|
|
compres.cash = 0;
|
|
} else {
|
|
for(i=0;i<k;i++) {
|
|
men_needed = targets[i].str_diff + 20;
|
|
find_adjacent(targets[i].x,targets[i].y, &adj.x, &adj.y, &full);
|
|
while(((calc_strength(COLOUR_LIGHT, targets[i].x, targets[i].y)
|
|
+ 20) > calc_strength(COLOUR_DARK, targets[i].x,
|
|
targets[i].y)) && compres.cash > 0) {
|
|
/* While we still need them keep placing men */
|
|
if(compres.cash >= 300 && !full) {
|
|
if(board[adj.x][adj.y].tank) {
|
|
find_adjacent(targets[i].x, targets[i].y,
|
|
&adj.x, &adj.y, &full);
|
|
} else {
|
|
board[adj.x][adj.y].tank = true;
|
|
compres.tanks++;
|
|
compres.cash -= 300;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
}
|
|
} else {
|
|
men_needed = (calc_strength(COLOUR_LIGHT, targets[i].x,
|
|
targets[i].y) + 20 -
|
|
calc_strength(COLOUR_DARK, targets[i].x,
|
|
targets[i].y))*1000/133;
|
|
if(compres.cash >= men_needed) {
|
|
board[adj.x][adj.y].men += men_needed;
|
|
compres.men += men_needed;
|
|
compres.cash -= men_needed;
|
|
compres.bank += compres.cash;
|
|
compres.cash = 0;
|
|
} else {
|
|
board[adj.x][adj.y].men += compres.cash;
|
|
compres.men += compres.cash;
|
|
compres.cash = 0;
|
|
}
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
}
|
|
}
|
|
}
|
|
compres.bank += compres.cash;
|
|
compres.cash = 0;
|
|
}
|
|
} else {
|
|
/* Work out what to place on each square to defend it.
|
|
* Tanks are preferential because they do not require food,
|
|
* but if the budget is tight then we fall back onto troops.
|
|
* Conversely if cash is not an issue and there are already tanks in
|
|
* place planes will be deployed. We would like a margin of at least
|
|
* 20 points to be safe. */
|
|
|
|
for(i=0;i<numthreats;i++) {
|
|
total_str_diff += threats[i].str_diff;
|
|
}
|
|
if((total_str_diff+20)*10 > compres.cash) {
|
|
/* Not enough cash to accomodate all threats using tanks alone -
|
|
* use men as a backup */
|
|
for(i=0;i<numthreats;i++) {
|
|
men_needed = ((threats[i].str_diff + 20)*1000)/133;
|
|
if(compres.cash >= men_needed) {
|
|
board[threats[i].x][threats[i].y].men += men_needed;
|
|
compres.cash -= men_needed;
|
|
compres.men += men_needed;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
} else {
|
|
board[threats[i].x][threats[i].y].men += compres.cash;
|
|
compres.men += compres.cash;
|
|
compres.cash = 0;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
}
|
|
}
|
|
} else if((total_str_diff+20)*15 < compres.cash) {
|
|
/* Enough money to pay their way by planes */
|
|
for(i=0;i<numthreats;i++) {
|
|
while(calc_strength(COLOUR_DARK,threats[i].x, threats[i].y) <
|
|
(calc_strength(COLOUR_LIGHT,threats[i].x, threats[i].y) +
|
|
20)) {
|
|
if(board[threats[i].x][threats[i].y].plane) {
|
|
if(place_adjacent(0, threats[i].x, threats[i].y)) {
|
|
/* No room for any more planes, revert to men */
|
|
men_needed = (calc_strength(COLOUR_LIGHT,
|
|
threats[i].x, threats[i].y) + 20 -
|
|
calc_strength(COLOUR_DARK,
|
|
threats[i].x, threats[i].y)*1000/133);
|
|
if(compres.cash >= men_needed) {
|
|
compres.cash -= men_needed;
|
|
compres.men += men_needed;
|
|
board[threats[i].x][threats[i].y].men +=
|
|
men_needed;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
}
|
|
}
|
|
} else {
|
|
if(compres.cash >= 600) {
|
|
board[threats[i].x][threats[i].y].plane = true;
|
|
compres.cash -= 600;
|
|
compres.planes++;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
/* Tanks it is */
|
|
for(i=0;i<numthreats;i++) {
|
|
while(calc_strength(COLOUR_DARK,threats[i].x, threats[i].y) <
|
|
(calc_strength(COLOUR_LIGHT,threats[i].x, threats[i].y) +
|
|
20) && compres.cash > 0) {
|
|
if(board[threats[i].x][threats[i].y].tank) {
|
|
if(place_adjacent(1, threats[i].x, threats[i].y)) {
|
|
/* No room for any more tanks, revert to men */
|
|
men_needed = (calc_strength(COLOUR_LIGHT,
|
|
threats[i].x, threats[i].y) + 20 -
|
|
calc_strength(COLOUR_DARK,
|
|
threats[i].x, threats[i].y)*1000/133);
|
|
if(compres.cash >= men_needed) {
|
|
compres.cash -= men_needed;
|
|
compres.men += men_needed;
|
|
board[threats[i].x][threats[i].y].men +=
|
|
men_needed;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
}
|
|
}
|
|
} else {
|
|
if(compres.cash >= 300) {
|
|
board[threats[i].x][threats[i].y].tank = true;
|
|
compres.tanks++;
|
|
compres.cash -= 300;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
compres.bank += compres.cash;
|
|
compres.cash = 0;
|
|
}
|
|
}
|
|
|
|
int find_adj_target(int x, int y, struct cursor* adj) {
|
|
/* Find a square next to a computer's farm or factory owned by the player
|
|
* that is vulnerable. Return 1 on success, 0 otherwise */
|
|
if(board[x+1][y].colour == COLOUR_LIGHT &&
|
|
calc_strength(COLOUR_LIGHT,x+1,y)<=calc_strength(COLOUR_DARK,x+1,y)) {
|
|
adj->x = x+1;
|
|
adj->y = y;
|
|
return 1;
|
|
}
|
|
if(board[x-1][y].colour == COLOUR_LIGHT &&
|
|
calc_strength(COLOUR_LIGHT,x-1,y)<=calc_strength(COLOUR_DARK,x-1,y)) {
|
|
adj->x = x-1;
|
|
adj->y = y;
|
|
return 1;
|
|
}
|
|
if(board[x][y+1].colour == COLOUR_LIGHT &&
|
|
calc_strength(COLOUR_LIGHT,x,y+1)<=calc_strength(COLOUR_DARK,x,y+1)) {
|
|
adj->x = x;
|
|
adj->y = y+1;
|
|
return 1;
|
|
}
|
|
if(board[x][y-1].colour == COLOUR_LIGHT &&
|
|
calc_strength(COLOUR_LIGHT,x,y-1)<=calc_strength(COLOUR_DARK,x,y-1)) {
|
|
adj->x = x;
|
|
adj->y = y-1;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void computer_war(void) {
|
|
/* Work out where to attack - prioritise the defence of buildings */
|
|
int i, j;
|
|
struct cursor adj;
|
|
|
|
while(compres.moves) {
|
|
for(i=1;i<12;i++) {
|
|
for(j=1;j<12;j++) {
|
|
if((board[i][j].colour == COLOUR_DARK) &&
|
|
(board[i][j].farm || board[i][j].ind)) {
|
|
if(find_adj_target(i, j, &adj) && compres.moves) {
|
|
if(calc_strength(COLOUR_LIGHT, adj.x, adj.y) ==
|
|
calc_strength(COLOUR_DARK, adj.x, adj.y)) {
|
|
rb->srand(*rb->current_tick);
|
|
if(rb->rand()%2) {
|
|
board[adj.x][adj.y].colour = COLOUR_DARK;
|
|
board[adj.x][adj.y].tank = false;
|
|
board[adj.x][adj.y].plane = false;
|
|
board[adj.x][adj.y].nuke = false;
|
|
humanres.men -= board[adj.x][adj.y].men;
|
|
board[adj.x][adj.y].men = 0;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
compres.moves--;
|
|
} else {
|
|
rb->splash(HZ*2, "The computer attempted"
|
|
" to attack, but the"
|
|
" invasion was pushed"
|
|
" back");
|
|
compres.moves--;
|
|
}
|
|
} else {
|
|
if(compres.moves) {
|
|
board[adj.x][adj.y].colour = COLOUR_DARK;
|
|
board[adj.x][adj.y].tank = false;
|
|
board[adj.x][adj.y].plane = false;
|
|
board[adj.x][adj.y].nuke = false;
|
|
humanres.men -= board[adj.x][adj.y].men;
|
|
board[adj.x][adj.y].men = 0;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
compres.moves--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(compres.moves) {
|
|
/* Defence stage done, move on to OFFENCE */
|
|
for(i=1;i<12;i++) {
|
|
for(j=1;j<12;j++) {
|
|
if(board[i][j].colour == COLOUR_LIGHT && compres.moves &&
|
|
(board[i][j].ind || board[i][j].farm) &&
|
|
(calc_strength(COLOUR_DARK, i, j) >=
|
|
calc_strength(COLOUR_LIGHT, i, j))) {
|
|
if(calc_strength(COLOUR_DARK, i, j) ==
|
|
calc_strength(COLOUR_LIGHT, i, j)) {
|
|
if(rb->rand()%2) {
|
|
board[i][j].colour = COLOUR_DARK;
|
|
board[i][j].tank = false;
|
|
board[i][j].plane = false;
|
|
board[i][j].nuke = false;
|
|
board[i][j].men = 0;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
compres.moves--;
|
|
} else {
|
|
rb->splash(HZ*2, "The computer attempted to "
|
|
"attack, but the invasion was"
|
|
" pushed back");
|
|
compres.moves--;
|
|
}
|
|
} else {
|
|
board[i][j].colour = COLOUR_DARK;
|
|
board[i][j].tank = false;
|
|
board[i][j].plane = false;
|
|
board[i][j].nuke = false;
|
|
board[i][j].men = 0;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
compres.moves--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
while(compres.moves > 0) {
|
|
/* Spend leftover moves wherever attacking randomly */
|
|
rb->srand(*rb->current_tick);
|
|
i = (rb->rand()%10)+1;
|
|
j = (rb->rand()%10)+1;
|
|
if(board[i][j].colour == COLOUR_LIGHT &&
|
|
(calc_strength(COLOUR_DARK, i, j) >=
|
|
calc_strength(COLOUR_LIGHT, i, j))) {
|
|
if(calc_strength(COLOUR_DARK, i, j) ==
|
|
calc_strength(COLOUR_LIGHT, i, j)) {
|
|
if(rb->rand()%2) {
|
|
board[i][j].colour = COLOUR_DARK;
|
|
board[i][j].tank = false;
|
|
board[i][j].plane = false;
|
|
board[i][j].nuke = false;
|
|
board[i][j].men = 0;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
compres.moves--;
|
|
} else {
|
|
rb->splash(HZ*2, "The computer attempted to"
|
|
" attack, but the invasion was"
|
|
" pushed back");
|
|
compres.moves--;
|
|
}
|
|
} else {
|
|
board[i][j].colour = COLOUR_DARK;
|
|
board[i][j].tank = false;
|
|
board[i][j].plane = false;
|
|
board[i][j].nuke = false;
|
|
board[i][j].men = 0;
|
|
draw_board();
|
|
rb->sleep(HZ);
|
|
compres.moves--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int load_game(char* file) {
|
|
int fd;
|
|
|
|
fd = rb->open(file, O_RDONLY);
|
|
if(fd == 0) {
|
|
DEBUGF("Couldn't open savegame\n");
|
|
return -1;
|
|
}
|
|
rb->read(fd, buf, 5);
|
|
if(rb->strcmp(buf, "SSGv2")) {
|
|
rb->splash(HZ, "Invalid/incompatible savegame\n");
|
|
return -1;
|
|
}
|
|
rb->read(fd, &humanres.cash, sizeof(humanres.cash));
|
|
rb->read(fd, &humanres.food, sizeof(humanres.food));
|
|
rb->read(fd, &humanres.bank, sizeof(humanres.bank));
|
|
rb->read(fd, &humanres.planes, sizeof(humanres.planes));
|
|
rb->read(fd, &humanres.tanks, sizeof(humanres.tanks));
|
|
rb->read(fd, &humanres.men, sizeof(humanres.men));
|
|
rb->read(fd, &humanres.nukes, sizeof(humanres.nukes));
|
|
rb->read(fd, &humanres.inds, sizeof(humanres.inds));
|
|
rb->read(fd, &humanres.farms, sizeof(humanres.farms));
|
|
rb->read(fd, &humanres.moves, sizeof(humanres.moves));
|
|
rb->read(fd, &compres.cash, sizeof(humanres.cash));
|
|
rb->read(fd, &compres.food, sizeof(humanres.food));
|
|
rb->read(fd, &compres.bank, sizeof(humanres.bank));
|
|
rb->read(fd, &compres.planes, sizeof(humanres.planes));
|
|
rb->read(fd, &compres.tanks, sizeof(humanres.tanks));
|
|
rb->read(fd, &compres.men, sizeof(humanres.men));
|
|
rb->read(fd, &compres.nukes, sizeof(humanres.nukes));
|
|
rb->read(fd, &compres.inds, sizeof(humanres.inds));
|
|
rb->read(fd, &compres.farms, sizeof(humanres.farms));
|
|
rb->read(fd, &compres.moves, sizeof(humanres.moves));
|
|
rb->read(fd, board, sizeof(board));
|
|
rb->read(fd, &superdom_settings.compstartfarms, sizeof(int));
|
|
rb->read(fd, &superdom_settings.compstartinds, sizeof(int));
|
|
rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
|
|
rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
|
|
rb->read(fd, &superdom_settings.startcash, sizeof(int));
|
|
rb->read(fd, &superdom_settings.startfood, sizeof(int));
|
|
rb->read(fd, &superdom_settings.movesperturn, sizeof(int));
|
|
return 0;
|
|
}
|
|
|
|
void default_settings(void) {
|
|
superdom_settings.compstartfarms = 1;
|
|
superdom_settings.compstartinds = 1;
|
|
superdom_settings.humanstartfarms = 2;
|
|
superdom_settings.humanstartinds = 2;
|
|
superdom_settings.startcash = 0;
|
|
superdom_settings.startfood = 0;
|
|
superdom_settings.movesperturn = 2;
|
|
}
|
|
|
|
int average_strength(bool colour) {
|
|
/* This function calculates the average strength of the given player,
|
|
* used to determine when the computer wins or loses. */
|
|
int i,j;
|
|
int totalpower = 0;
|
|
for(i=0;i<12;i++) {
|
|
for(j=0;j<12;j++) {
|
|
if(board[i][j].colour != -1) {
|
|
totalpower += calc_strength(colour, i, j);
|
|
}
|
|
}
|
|
}
|
|
return totalpower/100;
|
|
}
|
|
|
|
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
|
{
|
|
int tempmenu;
|
|
bool statusbar_setting;
|
|
|
|
rb = api;
|
|
|
|
#if LCD_DEPTH > 1
|
|
rb->lcd_set_backdrop(NULL);
|
|
rb->lcd_set_foreground(LCD_BLACK);
|
|
rb->lcd_set_background(LCD_WHITE);
|
|
#endif
|
|
|
|
statusbar_setting = rb->global_settings->statusbar;
|
|
rb->global_settings->statusbar = false;
|
|
cursor.x = 1;
|
|
cursor.y = 1;
|
|
default_settings();
|
|
if(parameter) {
|
|
if(load_game(parameter) != 0) {
|
|
DEBUGF("Loading failed, generating new game\n");
|
|
init_resources();
|
|
init_board();
|
|
} else {
|
|
goto startyear;
|
|
}
|
|
} else {
|
|
init_resources();
|
|
init_board();
|
|
}
|
|
|
|
bool play = false;
|
|
while(!play) {
|
|
switch(menu()) {
|
|
case 0:
|
|
play = true;
|
|
break;
|
|
case 2:
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_OK;
|
|
break;
|
|
}
|
|
}
|
|
gen_resources();
|
|
startyear:
|
|
if((average_strength(COLOUR_LIGHT) - average_strength(COLOUR_DARK)) > 15) {
|
|
rb->splash(HZ*4, "The computer has surrendered. You win.");
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_OK;
|
|
}
|
|
if((average_strength(COLOUR_DARK) - average_strength(COLOUR_LIGHT)) > 15) {
|
|
rb->splash(HZ*4, "Your army have suffered terrible morale from the bleak prospects of winning. You lose");
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_OK;
|
|
}
|
|
tempmenu = production_menu();
|
|
switch(tempmenu) {
|
|
case PLUGIN_USB_CONNECTED:
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case SUPERDOM_QUIT:
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_OK;
|
|
break;
|
|
}
|
|
computer_allocate();
|
|
humanres.moves += superdom_settings.movesperturn;
|
|
tempmenu = movement_menu();
|
|
switch(tempmenu) {
|
|
case PLUGIN_USB_CONNECTED:
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case SUPERDOM_QUIT:
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_OK;
|
|
break;
|
|
}
|
|
if(humanres.men) {
|
|
if(humanres.food > humanres.men) {
|
|
rb->snprintf(buf, sizeof(buf), "Your men ate %d units of food",
|
|
humanres.men);
|
|
humanres.food -= humanres.men;
|
|
} else {
|
|
rb->snprintf(buf, sizeof(buf), "There was not enough food to feed"
|
|
" all your men, %d men have died of starvation",
|
|
killmen(COLOUR_LIGHT));
|
|
}
|
|
rb->splash(HZ*2, buf);
|
|
}
|
|
if(compres.men) {
|
|
if(compres.food < compres.men) {
|
|
rb->snprintf(buf, sizeof(buf), "The computer does not have enough"
|
|
" food to feed its men. %d have ided of starvation",
|
|
killmen(COLOUR_DARK));
|
|
rb->splash(HZ, buf);
|
|
}
|
|
}
|
|
tempmenu = war_menu();
|
|
switch(tempmenu) {
|
|
case PLUGIN_USB_CONNECTED:
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_USB_CONNECTED;
|
|
break;
|
|
case SUPERDOM_QUIT:
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_OK;
|
|
break;
|
|
}
|
|
compres.moves += superdom_settings.movesperturn;
|
|
computer_war();
|
|
gen_resources();
|
|
goto startyear;
|
|
rb->global_settings->statusbar = statusbar_setting;
|
|
return PLUGIN_OK;
|
|
}
|