From 1685da832f1cecba215296734aef91b3918f57bb Mon Sep 17 00:00:00 2001 From: Will Robertson Date: Thu, 2 Aug 2007 12:55:14 +0000 Subject: Accept FS#7136: Turn based strategy game - "Superdom" clone git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14144 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/SOURCES | 3 + apps/plugins/bitmaps/mono/SOURCES | 4 + .../bitmaps/mono/superdom_boarditems.160x128x1.bmp | Bin 0 -> 630 bytes apps/plugins/bitmaps/native/SOURCES | 15 + .../native/superdom_boarditems.176x132x16.bmp | Bin 0 -> 630 bytes .../native/superdom_boarditems.220x176x16.bmp | Bin 0 -> 1902 bytes .../native/superdom_boarditems.240x320x16.bmp | Bin 0 -> 3078 bytes .../native/superdom_boarditems.320x240x16.bmp | Bin 0 -> 3654 bytes apps/plugins/superdom.c | 2341 ++++++++++++++++++++ apps/plugins/viewers.config | 1 + 10 files changed, 2364 insertions(+) create mode 100644 apps/plugins/bitmaps/mono/superdom_boarditems.160x128x1.bmp create mode 100644 apps/plugins/bitmaps/native/superdom_boarditems.176x132x16.bmp create mode 100644 apps/plugins/bitmaps/native/superdom_boarditems.220x176x16.bmp create mode 100644 apps/plugins/bitmaps/native/superdom_boarditems.240x320x16.bmp create mode 100644 apps/plugins/bitmaps/native/superdom_boarditems.320x240x16.bmp create mode 100644 apps/plugins/superdom.c (limited to 'apps/plugins') diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index 48d9417e7a..06c4b7ccdc 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES @@ -133,3 +133,6 @@ iriver_flash.c #endif #endif /* iFP7xx */ +#if (LCD_WIDTH == 220) || (LCD_WIDTH == 176) || (LCD_WIDTH == 160) || (LCD_WIDTH == 320) || (LCD_WIDTH == 240) +superdom.c +#endif diff --git a/apps/plugins/bitmaps/mono/SOURCES b/apps/plugins/bitmaps/mono/SOURCES index 626b6ca2d8..d74905fb0d 100644 --- a/apps/plugins/bitmaps/mono/SOURCES +++ b/apps/plugins/bitmaps/mono/SOURCES @@ -46,6 +46,10 @@ flipit_cursor.16x13x1.bmp #endif #endif +#if LCD_WIDTH == 160 && LCD_HEIGHT == 128 && LCD_DEPTH < 16 +superdom_boarditems.160x128x1.bmp +#endif + #endif /* HAVE_LCD_BITMAP */ #if defined(SIMULATOR) && defined(__APPLE__) osx.dummy.bmp diff --git a/apps/plugins/bitmaps/mono/superdom_boarditems.160x128x1.bmp b/apps/plugins/bitmaps/mono/superdom_boarditems.160x128x1.bmp new file mode 100644 index 0000000000..c9196b22db Binary files /dev/null and b/apps/plugins/bitmaps/mono/superdom_boarditems.160x128x1.bmp differ diff --git a/apps/plugins/bitmaps/native/SOURCES b/apps/plugins/bitmaps/native/SOURCES index 50866cb183..05029c430c 100644 --- a/apps/plugins/bitmaps/native/SOURCES +++ b/apps/plugins/bitmaps/native/SOURCES @@ -457,4 +457,19 @@ sudoku_inverse.320x240x16.bmp #endif #endif +/* Superdom */ +#if LCD_DEPTH == 16 +#if ((LCD_WIDTH == 220) && (LCD_HEIGHT == 176)) +superdom_boarditems.220x176x16.bmp +#elif ((LCD_WIDTH == 176) && (LCD_HEIGHT == 132)) || \ + ((LCD_WIDTH == 160) && (LCD_HEIGHT == 128)) || \ + ((LCD_WIDTH == 176) && (LCD_HEIGHT == 220)) +superdom_boarditems.176x132x16.bmp +#elif (LCD_WIDTH == 320 && LCD_HEIGHT == 240) +superdom_boarditems.320x240x16.bmp +#elif (LCD_WIDTH == 240 && LCD_HEIGHT == 320) +superdom_boarditems.240x320x16.bmp +#endif +#endif + #endif /* HAVE_LCD_BITMAP */ diff --git a/apps/plugins/bitmaps/native/superdom_boarditems.176x132x16.bmp b/apps/plugins/bitmaps/native/superdom_boarditems.176x132x16.bmp new file mode 100644 index 0000000000..db95fb5f8d Binary files /dev/null and b/apps/plugins/bitmaps/native/superdom_boarditems.176x132x16.bmp differ diff --git a/apps/plugins/bitmaps/native/superdom_boarditems.220x176x16.bmp b/apps/plugins/bitmaps/native/superdom_boarditems.220x176x16.bmp new file mode 100644 index 0000000000..47b4b90164 Binary files /dev/null and b/apps/plugins/bitmaps/native/superdom_boarditems.220x176x16.bmp differ diff --git a/apps/plugins/bitmaps/native/superdom_boarditems.240x320x16.bmp b/apps/plugins/bitmaps/native/superdom_boarditems.240x320x16.bmp new file mode 100644 index 0000000000..b39c69ba6e Binary files /dev/null and b/apps/plugins/bitmaps/native/superdom_boarditems.240x320x16.bmp differ diff --git a/apps/plugins/bitmaps/native/superdom_boarditems.320x240x16.bmp b/apps/plugins/bitmaps/native/superdom_boarditems.320x240x16.bmp new file mode 100644 index 0000000000..36b53b6bb6 Binary files /dev/null and b/apps/plugins/bitmaps/native/superdom_boarditems.320x240x16.bmp differ diff --git a/apps/plugins/superdom.c b/apps/plugins/superdom.c new file mode 100644 index 0000000000..7c70aa7d96 --- /dev/null +++ b/apps/plugins/superdom.c @@ -0,0 +1,2341 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +#define SUPERDOM_OK BUTTON_SELECT +#define SUPERDOM_CANCEL BUTTON_MENU +#define SUPERDOM_LEFT BUTTON_LEFT +#define SUPERDOM_RIGHT BUTTON_RIGHT + +#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.farmsrand()%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.indsrand()%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) { + /* Yes, I know. Please, if you know how, fix it. */ + int score=0; + if(board[x][y].colour == colour) { + score+=10; + } + if(board[x+1][y].colour == colour) { + score+=10; + } + if(board[x][y+1].colour == colour) { + score+=10; + } + if(board[x-1][y].colour == colour) { + score+=10; + } + if(board[x][y-1].colour == colour) { + score+=10; + } + if((board[x][y].colour == colour) && board[x][y].tank) { + score+=30; + } + if((board[x+1][y].colour == colour) && board[x+1][y].tank) { + score+=30; + } + if((board[x][y+1].colour == colour) && board[x][y+1].tank) { + score+=30; + } + if((board[x-1][y].colour == colour) && board[x-1][y].tank) { + score+=30; + } + if((board[x][y-1].colour == colour) && board[x][y-1].tank) { + score+=30; + } + if((board[x][y].colour == colour) && board[x][y].plane) { + score+=40; + } + if((board[x+1][y].colour == colour) && board[x+1][y].plane) { + score+=40; + } + if((board[x][y+1].colour == colour) && board[x][y+1].plane) { + score+=40; + } + if((board[x-1][y].colour == colour) && board[x-1][y].plane) { + score+=40; + } + if((board[x][y-1].colour == colour) && board[x][y-1].plane) { + score+=40; + } + if((board[x][y].colour == colour) && board[x][y].ind) { + score+=40; + } + if((board[x+1][y].colour == colour) && board[x+1][y].ind) { + score+=40; + } + if((board[x][y+1].colour == colour) && board[x][y+1].ind) { + score+=40; + } + if((board[x-1][y].colour == colour) && board[x-1][y].ind) { + score+=40; + } + if((board[x][y-1].colour == colour) && board[x][y-1].ind) { + score+=40; + } + if((board[x][y].colour == colour) && board[x][y].farm) { + score+=30; + } + if((board[x+1][y].colour == colour) && board[x+1][y].farm) { + score+=30; + } + if((board[x][y+1].colour == colour) && board[x][y+1].farm) { + score+=30; + } + if((board[x-1][y].colour == colour) && board[x-1][y].farm) { + score+=30; + } + if((board[x][y-1].colour == colour) && board[x][y-1].farm) { + score+=30; + } + if((board[x][y].colour == colour) && board[x][y].nuke) { + score+=20; + } + if((board[x+1][y].colour == colour) && board[x+1][y].nuke) { + score+=20; + } + if((board[x][y+1].colour == colour) && board[x][y+1].nuke) { + score+=20; + } + if((board[x-1][y].colour == colour) && board[x-1][y].nuke) { + score+=20; + } + if((board[x][y-1].colour == colour) && board[x][y-1].nuke) { + score+=20; + } + if((board[x][y].colour == colour) && board[x][y].men) { + score+=(board[x][y].men*133/1000); + } + if((board[x+1][y].colour == colour) && board[x+1][y].men) { + score+=(board[x+1][y].men*133/1000); + } + if((board[x][y+1].colour == colour) && board[x][y+1].men) { + score+=(board[x][y+1].men*133/1000); + } + if((board[x-1][y].colour == colour) && board[x-1][y].men) { + score+=(board[x-1][y].men*133/1000); + } + if((board[x][y-1].colour == colour) && board[x][y-1].men) { + score+=(board[x][y-1].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;irand()%200); + } + for(i=0;irand()%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;irand()%200); + } + for(i=0;irand()%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) { +#if CONFIG_KEYPAD == IPOD_4G_PAD + 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) { +#if CONFIG_KEYPAD == IPOD_4G_PAD + 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 +#if CONFIG_KEYPAD != IPOD_4G_PAD + 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 { +#if CONFIG_KEYPAD == IPOD_4G_PAD + 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 { +#if CONFIG_KEYPAD == IPOD_4G_PAD + if(cursor.y<10) + cursor.y++; + else + cursor.y = 1; +#endif + cursor.x = 1; + } + update_score(); + draw_cursor(); + break; +#endif +#if CONFIG_KEYPAD != IPOD_4G_PAD + 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(ksrand(*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 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 compres.cash) { + /* Not enough cash to accomodate all threats using tanks alone - + * use men as a backup */ + for(i=0;i= 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= 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 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; + rb = api; + bool statusbar_setting; + 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; +} diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config index 143b593dc4..0f70dc737d 100644 --- a/apps/plugins/viewers.config +++ b/apps/plugins/viewers.config @@ -35,3 +35,4 @@ tzx,viewers/zxbox,12 z80,viewers/zxbox,12 zzz,viewers/properties,- colours,rocks/text_editor,11 +ssg,rocks/superdom,- -- cgit v1.2.3