00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00024
00075
00076
00077 #include "crogue.h"
00078 #include "substdio.h"
00079 #include "export.h"
00080
00081 #ifdef REGISTERVAR
00082 world *w_non_reg;
00083
00084 #else
00085 world *w;
00086 #endif
00087
00088 static void cb_main_menu_choice(int n, char *buf);
00089 static void main_menu(void);
00090
00091
00092 void initialize(void)
00093 {
00094 int loadedfromfile = 0;
00095
00096 sys_init();
00097
00098
00099 #ifdef REGISTERVAR
00100 w_non_reg = NULL;
00101 #endif
00102 w = (world*)debug_calloc(1, sizeof(world));
00103 #ifdef REGISTERVAR
00104 w_non_reg = w;
00105 #endif
00106
00107 lsrand(get_entropy());
00108
00109
00110 loadedfromfile = restore_game();
00111
00112
00113
00114 if(!loadedfromfile) {
00115 sys_init_data_file();
00116 init_options();
00117 load_options();
00118 # ifdef IS_CALCULATOR
00119 if(w->options[OPTION_GRAYSCALE] == OPTION_GRAY_ON)
00120 GrayOnThrow();
00121 # endif
00122 display_title_screen();
00123
00124 init_shuffle_tab();
00125
00126 w->messagevis=0;
00127 w->time=0;
00128 #ifdef ALLOWDEBUG
00129 w->debug_mode = 0;
00130 #endif
00131
00132 init_spells();
00133 init_discoveries();
00134 }
00135 else
00136 {
00137 UI_TF_Init( COORD(MAPSIZE_X,MAPSIZE_Y) );
00138 #ifdef IS_CALCULATOR
00139 if(w->options[OPTION_GRAYSCALE] == OPTION_GRAY_ON)
00140 GrayOnThrow();
00141 #endif
00142 }
00143
00144 init_layout();
00145
00146 if(!loadedfromfile)
00147 main_menu();
00148
00149 UI_MF_clear();
00150 enter_map();
00151 }
00152
00153
00154 void resize_map_store(int size_x, int size_y)
00155 {
00156 tile *alloc_pos;
00157 int i;
00158
00159 if(w->t && w->mapsize_x == size_x && w->mapsize_y == size_y)
00160 return;
00161
00162 if(w->t) debug_free(w->t);
00163 w->mapsize_x = size_x;
00164 w->mapsize_y = size_y;
00165 w->t = debug_malloc( size_y*sizeof(tile*)
00166 + size_x*size_y*sizeof(tile) );
00167 alloc_pos = (tile*)((tile**)w->t + size_y);
00168 for(i=0; i<size_y; i++) {
00169 w->t[i] = alloc_pos;
00170 alloc_pos += size_x;
00171 }
00172
00173 UI_TF_Init( COORD(size_x, size_y) );
00174 }
00175
00176
00177
00178 static const char *main_menu_choices[] = {
00179 gettext("New game"),
00180 gettext("Help"),
00181 gettext("Tutorial"),
00182 gettext("High scores"),
00183 gettext("Options"),
00184 gettext("Quit")
00185 };
00186 static const int num_main_menu_choices = 6;
00187
00188
00189 static void cb_main_menu_choice(int n, char *buf)
00190 {
00191 strcpy(buf, main_menu_choices[n]);
00192 }
00193
00194
00195 static void main_menu(void)
00196 {
00197 int choice;
00198
00199 restart:
00200
00201 display_title_screen();
00202
00203 do {
00204 choice = UI_Menu_Pick( main_menu_rect, num_main_menu_choices, &cb_main_menu_choice, 0);
00205 } while(choice == -1);
00206
00207 switch(choice)
00208 {
00209 case 0:
00210 init_player(0);
00211 w->current_map_link = w->desc.mainmap;
00212 w->current_map = (mapdesc*)deref_file_ptr(w->current_map_link);
00213 w->maxlevel = w->level = w->current_map->mapindex;
00214 gen_map(0, COORD(0,0));
00215 break;
00216 case 1:
00217 help();
00218 goto restart;
00219 case 2:
00220 init_player(1);
00221 w->current_map_link = w->desc.tutorialmap;
00222 w->current_map = (mapdesc*)deref_file_ptr(w->current_map_link);
00223 w->maxlevel = w->level = w->current_map->mapindex;
00224 gen_map(0, COORD(0,0));
00225 break;
00226 case 3:
00227 display_scores(-1);
00228 goto restart;
00229 case 4:
00230 options_menu();
00231 goto restart;
00232 case 5:
00233 quit();
00234 }
00235 }
00236
00237
00238
00239 void eventloop(void)
00240 {
00241 while(1)
00242 {
00243 plr_move();
00244 draw();
00245 }
00246 }
00247
00248
00249
00250 void die(const char *cause_of_death)
00251 {
00252 message(gettext("You die..."));
00253 draw();
00254 while(read_char() != KEY_ACKNOWLEDGE);
00255
00256 end_game(cause_of_death);
00257 }
00258
00259
00260 void end_game(const char *cause_of_death)
00261 {
00262 award_item_points();
00263
00264 #ifdef ALLOWDEBUG
00265 if(w->debug_mode)
00266 {
00267 message( gettext(
00268 "Since you used debug features, your game will not be scored."));
00269 read_char();
00270 } else
00271 #endif
00272 {
00273 award_high_score(w->plr.score, cause_of_death);
00274 display_scores(w->plr.score);
00275 }
00276
00277 cleanup_save();
00278 quit();
00279 }
00280
00281
00282
00283 void quit(void)
00284 {
00285 #ifdef IS_CALCULATOR
00286 ER_success();
00287 #endif
00288 cleanup();
00289 exit(0);
00290 }
00291
00292
00293 void cleanup(void)
00294 {
00295 sys_cleanup();
00296
00297 if(w) {
00298 if(w->t) debug_free(w->t);
00299 if(w->plr.spellknowledge) debug_free(w->plr.spellknowledge);
00300 if(w->shuffletranslation) debug_free(w->shuffletranslation);
00301 if(w->itemids) debug_free(w->itemids);
00302 cleanup_items();
00303 debug_free(w);
00304 }
00305 UI_TF_Deinit();
00306
00307 exit(0);
00308 }
00309
00310
00311 void timepass(ushort amt)
00312 {
00313 uint partialhpsperhp;
00314 uint partialppsperpp;
00315 uint i;
00316
00317
00318
00319 if(w->plr.extrinsic[STAT_FLAGS] & STAT_FLAG_DRAIN)
00320 {
00321 if(w->plr.pps > 0)
00322 {
00323 message(gettext("You feel the Amulet sucking your energy away."));
00324 w->plr.pps--;
00325 }
00326 else
00327 {
00328 message(gettext("You feel the Amulet sucking your life away."));
00329 plr_takedamage(1, gettext("Killed by the Amulet of Yendor"));
00330 }
00331 } else {
00332
00333 partialhpsperhp = 150+10*w->plr.level;
00334 w->plr.partialhps += (w->plr.hps_max+10) * amt;
00335 w->plr.hps += w->plr.partialhps / partialhpsperhp;
00336 w->plr.hps += w->plr.extrinsic[STAT_REGEN];
00337 w->plr.partialhps -= (w->plr.partialhps/partialhpsperhp)*partialhpsperhp;
00338 if( w->plr.hps > w->plr.hps_max )
00339 w->plr.hps = w->plr.hps_max;
00340
00341
00342 partialppsperpp = 155+10*w->plr.level;
00343 w->plr.partialpps += (w->plr.pps_max+w->plr.extrinsic[STAT_MANA]) * amt;
00344 w->plr.pps += w->plr.partialpps / partialppsperpp;
00345 w->plr.partialpps -= (w->plr.partialpps/partialppsperpp)*partialppsperpp;
00346 if( w->plr.pps > w->plr.pps_max )
00347 w->plr.pps = w->plr.pps_max;
00348 }
00349
00350
00351 if(w->plr.extrinsic[STAT_FLAGS] & STAT_FLAG_TIMER)
00352 {
00353 for(i=0; i<PLRINVSIZE; i++)
00354 {
00355 if(ITEMDESC(INVENTORY(i)).flags)
00356 {
00357 if(get_item_property(&INVENTORY(i), PROPERTY_BURN))
00358 {
00359 call_usefunc(get_item_property(&INVENTORY(i),
00360 PROPERTY_BURN)->function, i );
00361 }
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 }
00374 }
00375
00376 if(remove_expired_timers())
00377 update_player();
00378
00379 w->plr.satiation -= w->plr.extrinsic[STAT_DIGESTION] * amt;
00380 if(w->plr.satiation <= -600) {
00381 message(gettext("You are starving!"));
00382 plr_takedamage(w->plr.satiation/-600, gettext("Starved to death."));
00383
00384 }
00385
00386
00387 for(i=0; i<MONSTERS_MAX; i++)
00388 {
00389 if(!isNull(w->m[i].type))
00390 {
00391 w->m[i].energy += MDESC(i)->speed * amt;
00392
00393 while(w->m[i].energy >= w->plr.extrinsic[STAT_SPEED] && !isNull(w->m[i].type))
00394 {
00395 monstmove(i);
00396 w->m[i].energy -= w->plr.extrinsic[STAT_SPEED];
00397 }
00398 }
00399 }
00400
00401
00402
00403 for(i=0; i<amt; i++)
00404 if( !(MAPDESC_CURRENT.flags & MAPFLAG_NORANDMONST) && lrand()%70 == 0 )
00405 {
00406 #ifdef DEBUG_BALANCE
00407 if(w->debug_mode)
00408 message(gettext("Added random monster."));
00409 #endif
00410 addrandommonst();
00411 }
00412
00413
00414 w->plr.facing_forced = -1;
00415 if(w->plr.velocity > 0) w->plr.velocity --;
00416
00417 w->time++;
00418 }
00419
00420
00421