1 /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
2
3 /* this file includes main() and some top-level functions */
4 /* omega.c */
5
6 #if !defined(MSDOS_SUPPORTED_ANTIQUE)
7 #include <signal.h>
8 #include <fcntl.h>
9 #include <time.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 /* Note: in order to avoid a memory bug I've been told about, I'm
13 explicitly initializing every global to something. */
14 #endif
15
16 #include "glob.h"
17
18 /* most globals originate in omega.c */
19
20 char *Omegalib; /* contains the path to the library files */
21
22 #ifdef DEBUG
23 FILE *DG_debug_log; /* debug log file pointer */
24 int DG_debug_flag = 0; /* debug flag -- set by -d commandline option */
25 #endif
26
27 /* Objects and Monsters are allocated and initialized in init.c */
28
29 /* one of each spell */
30 #ifndef MSDOS_SUPPORTED_ANTIQUE
31 struct spell Spells[NUMSPELLS+1];
32 #else
33 struct spell Spells[NUMSPELLS+1] = {0};
34 #endif
35
36 /* locations of city sites [0] - found, [1] - x, [2] - y */
37 #ifndef MSDOS_SUPPORTED_ANTIQUE
38 int CitySiteList[NUMCITYSITES][3];
39 #else
40 int CitySiteList[NUMCITYSITES][3] = {0};
41 #endif
42
43 /* Currently defined in caps since it is now a variable, was a constant */
44 int LENGTH=MAXLENGTH;
45 int WIDTH=MAXWIDTH;
46
47 long GameStatus=0L; /* Game Status bit vector */
48 int ScreenLength = 0; /* How large is level window */
49 #ifndef MSDOS_SUPPORTED_ANTIQUE
50 struct player Player; /* the player */
51 #else
52 struct player Player = {0}; /* the player */
53 #endif
54 #ifndef MSDOS_SUPPORTED_ANTIQUE
55 struct terrain Country[MAXWIDTH][MAXLENGTH];/* The countryside */
56 #else
57 struct terrain Country[MAXWIDTH][MAXLENGTH] = {0};/* The countryside */
58 #endif
59 #ifdef SAVE_LEVELS
60 struct level TheLevel;
61 #endif
62 struct level *City=NULL; /* The city of Rampart */
63 struct level *TempLevel=NULL; /* Place holder */
64 struct level *Level=NULL; /* Pointer to current Level */
65 struct level *Dungeon=NULL; /* Pointer to current Dungeon */
66 int Villagenum = 0; /* Current Village number */
67 int ScreenOffset = 0; /* Offset of displayed screen to level */
68 int MaxDungeonLevels = 0; /* Deepest level allowed in dungeon */
69 int Current_Dungeon= -1; /* What is Dungeon now */
70 int Current_Environment= E_CITY; /* Which environment are we in */
71 int Last_Environment= E_COUNTRYSIDE; /* Which environment were we in */
72 #ifndef MSDOS_SUPPORTED_ANTIQUE
73 int Dirs[2][9]; /* 9 xy directions */
74 #else
75 int Dirs[2][9]= /* 9 xy directions */
76 { { 1,1,-1,-1,1,-1,0,0,0} , { 1,-1,1,-1,0,0,1,-1,0 } };
77 #endif
78 char Cmd='s'; /* last player command */
79 int Command_Duration = 0; /* how long does current command take */
80 struct monster *Arena_Monster=NULL; /* Opponent in arena */
81 int Arena_Opponent=0; /* case label of opponent in l_arena()*/
82 int Arena_Victory = 0; /* did player win in arena? */
83 int Imprisonment=0; /* amount of time spent in jail */
84 int Precipitation=0; /* Hours of rain, snow, etc */
85 int Lunarity=0; /* Effect of the moon on character */
86 int Phase = 0; /* Phase of the moon */
87 int Date = 0; /* Starting date */
88 int Pawndate = 0; /* Pawn Shop item generation date */
89 pob Pawnitems[PAWNITEMS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
90 /* items in pawn shop */
91 int SymbolUseHour= -1; /* holy symbol use marker */
92 int ViewHour= -1; /* crystal ball use marker */
93 int ZapHour= -1; /* staff of enchantment use marker */
94 int HelmHour= -1; /* helm of teleportation use marker*/
95 int Constriction=0; /* Dragonlord Attack State */
96 int Blessing=FALSE; /* Altar Blessing State */
97 int LastDay= -1; /* DPW date of dole */
98 int RitualHour= -1; /* last use of ritual magic */
99 int RitualRoom= -1; /* last room of ritual magic */
100 int Lawstone=0; /* magic stone counter */
101 int Chaostone=0; /* magic stone counter */
102 int Mindstone=0; /* magic stone counter */
103 int Searchnum = 1; /* number of times to search on 's' */
104 int Behavior; /* Player NPC behavior */
105 int Verbosity = VERBOSE; /* verbosity level */
106 long Time = 0; /* turn number */
107 int Tick = 0; /* 10 a turn; action coordinator */
108 char Stringbuffer[STRING_BUFFER_SIZE][80]; /* last strings printed */
109 long Gymcredit = 0; /* credit at rampart gym */
110 int Spellsleft = 0; /* research allowance at college */
111 int StarGemUse = 0; /* last date of star gem use */
112 int HiMagicUse = 0; /* last date of high magic use */
113 int HiMagic = 0; /* current level for l_throne */
114 long Balance = 0; /* bank account */
115 long FixedPoints = 0; /* points are frozen after adepthood*/
116 int LastTownLocX=0; /* previous position in village or city */
117 int LastTownLocY=0; /* previous position in village or city */
118 int LastCountryLocX=0; /* previous position in countryside */
119 int LastCountryLocY=0; /* previous position in countryside */
120 #ifndef MSDOS_SUPPORTED_ANTIQUE
121 char Password[64]; /* autoteller password */
122 #else
123 char Password[64] = {0}; /* autoteller password */
124 #endif
125 #ifndef MSDOS_SUPPORTED_ANTIQUE
126 char Str1[STRING_LEN],Str2[STRING_LEN],Str3[STRING_LEN],Str4[STRING_LEN];
127 #else
128 char Str1[STRING_LEN] = {0},Str2[STRING_LEN] = {0},Str3[STRING_LEN] = {0},Str4[STRING_LEN] = {0};
129 #endif
130 /* Some string space, random uses */
131
132 pol Condoitems=NULL; /* Items in condo */
133
134 /* high score names, levels, behavior */
135 #ifndef MSDOS_SUPPORTED_ANTIQUE
136 int Shadowlordbehavior,Archmagebehavior,Primebehavior,Commandantbehavior;
137 int Championbehavior,Priestbehavior[7],Hibehavior,Dukebehavior;
138 int Chaoslordbehavior,Lawlordbehavior,Justiciarbehavior;
139 char Shadowlord[80],Archmage[80],Prime[80],Commandant[80],Duke[80];
140 char Champion[80],Priest[7][80],Hiscorer[80],Hidescrip[80];
141 char Chaoslord[80],Lawlord[80],Justiciar[80];
142 int Shadowlordlevel,Archmagelevel,Primelevel,Commandantlevel,Dukelevel;
143 #else
144 int Shadowlordbehavior = 0,Archmagebehavior = 0,Primebehavior = 0,Commandantbehavior = 0;
145 int Championbehavior = 0,Priestbehavior[7] = {0},Hibehavior = 0,Dukebehavior = 0;
146 int Chaoslordbehavior = 0,Lawlordbehavior = 0,Justiciarbehavior = 0;
147 char Shadowlord[80] = {0},Archmage[80] = {0},Prime[80] = {0},Commandant[80] = {0},Duke[80] = {0};
148 char Champion[80] = {0},Priest[7][80] = {0},Hiscorer[80] = {0},Hidescrip[80] = {0};
149 char Chaoslord[80] = {0},Lawlord[80] = {0},Justiciar[80] = {0};
150 int Shadowlordlevel = 0,Archmagelevel = 0,Primelevel = 0,Commandantlevel = 0,Dukelevel = 0;
151 #endif
152 #ifndef MSDOS_SUPPORTED_ANTIQUE
153 int Championlevel,Priestlevel[7],Hilevel,Justiciarlevel;
154 #else
155 int Championlevel = 0,Priestlevel[7] = {0},Hilevel = 0,Justiciarlevel = 0;
156 #endif
157 long Hiscore = 0L;
158 int Chaoslordlevel = 0,Lawlordlevel = 0,Chaos = 0,Law = 0;
159
160 /* New globals which used to be statics */
161 int twiddle = FALSE;
162 int saved=FALSE;
163 int onewithchaos=FALSE;
164 int club_hinthour = 0;
165 int winnings = 0;
166 int tavern_hinthour;
167 int scroll_ids[30];
168 int potion_ids[30];
169 int stick_ids[30];
170 int ring_ids[30];
171 int cloak_ids[30];
172 int boot_ids[30];
173
174 int deepest[E_MAX + 1];
175 int level_seed[E_MAX + 1]; /* random number seed that generated level */
176
177 /* This may be implementation dependent */
178 /* SRANDFUNCTION is defined in odefs.h */
179 /* environment is the environment about to be generated, or -1 for the first */
180 /* time, or -2 if we want to restore the random number point */
initrand(int environment,int level)181 void initrand(int environment, int level)
182 {
183 static int store;
184 int seed;
185
186 if (environment >= 0)
187 store = RANDFUNCTION();
188 /* Pseudo Random Seed */
189 if (environment == E_RANDOM)
190 seed = (int) time((long *)NULL);
191 else if (environment == E_RESTORE)
192 seed = store;
193 else
194 seed = level_seed[environment] + 1000*level;
195 SRANDFUNCTION(seed);
196 }
197
198
game_restore(argc,argv)199 int game_restore(argc,argv)
200 int argc;
201 char *argv[];
202 {
203 char savestr[80];
204 int ok;
205 #ifdef DEBUG
206 if (argc == 3) {
207 if( (argv[2][0] == '-') && (argv[2][1] == 'g') )
208 {
209 DG_debug_flag++;
210 argc--;
211 }
212 }
213 #endif
214 if (argc==2) {
215 strcpy(savestr,argv[1]);
216 ok = restore_game(savestr);
217 if (! ok) {
218 endgraf();
219 printf("Try again with the right save file, luser!\n");
220 exit(0);
221 }
222 change_to_user_perms();
223 unlink(savestr);
224 change_to_game_perms();
225 return(TRUE);
226 }
227 else return(FALSE);
228 }
229
230
main(argc,argv)231 int main(argc,argv)
232 int argc;
233 char *argv[];
234 {
235 int continuing;
236 int count;
237
238
239 /* always catch ^c and hang-up signals */
240
241 #ifdef SIGINT
242 signal(SIGINT,(void *)quit);
243 #endif
244 #ifdef SIGHUP
245 signal(SIGHUP,(void *)signalsave);
246 #endif
247
248 #ifndef MSDOS
249 if (CATCH_SIGNALS) {
250 signal(SIGQUIT,(void *)signalexit);
251 signal(SIGILL,(void *)signalexit);
252 #ifdef DEBUG
253 if( DG_debug_flag ) {
254 #endif
255 signal(SIGTRAP,(void *)signalexit);
256 signal(SIGFPE,(void *)signalexit);
257 signal(SIGSEGV,(void *)signalexit);
258 #ifdef DEBUG
259 }
260 #endif
261 #ifdef SIGIOT
262 signal(SIGIOT,(void *)signalexit);
263 #endif
264 #ifdef SIGABRT
265 signal(SIGABRT,(void *)signalexit);
266 #endif
267 #ifdef SIGEMT
268 signal(SIGEMT,(void *)signalexit);
269 #endif
270 #ifdef SIGBUS
271 signal(SIGBUS,(void *)signalexit);
272 #endif
273 #ifdef SIGSYS
274 signal(SIGSYS,(void *)signalexit);
275 #endif
276 }
277 #endif
278
279 #ifndef FIXED_OMEGALIB
280 if (!(Omegalib = getenv("OMEGALIB")))
281 #endif
282 Omegalib = OMEGALIB;
283
284 /* if filecheck is 0, some necessary data files are missing */
285 if (filecheck() == 0) exit(0);
286
287 /* all kinds of initialization */
288 init_perms();
289 initgraf();
290 #ifndef MSDOS_SUPPORTED_ANTIQUE
291 initdirs();
292 #endif
293 initrand(E_RANDOM, 0);
294 initspells();
295
296 #ifdef DEBUG
297 /* initialize debug log file */
298 DG_debug_log = fopen( "/tmp/omega_dbg_log", "a" );
299 assert( DG_debug_log ); /* WDT :) */
300 setvbuf( DG_debug_log, NULL, _IOLBF, 0);
301 fprintf(DG_debug_log, "############## new game started ##############\n");
302 #endif
303
304 for (count = 0; count < STRING_BUFFER_SIZE; count++)
305 strcpy(Stringbuffer[count],"<nothing>");
306
307 #ifdef SAVE_LEVELS
308 msdos_init();
309 #endif
310
311 omega_title();
312 showscores();
313
314 /* game restore attempts to restore game if there is an argument */
315 continuing = game_restore(argc,argv);
316
317 /* monsters initialized in game_restore if game is being restored */
318 /* items initialized in game_restore if game is being restored */
319 if (! continuing) {
320 inititem(TRUE);
321 Date = random_range(360);
322 Phase = random_range(24);
323 strcpy(Password,"");
324 initplayer();
325 init_world();
326 mprint("'?' for help or commandlist, 'Q' to quit.");
327 }
328 else mprint("Your adventure continues....");
329
330 timeprint();
331 calc_melee();
332 if (Current_Environment != E_COUNTRYSIDE)
333 showroom(Level->site[Player.x][Player.y].roomnumber);
334 else
335 terrain_check(FALSE);
336
337 if (optionp(SHOW_COLOUR))
338 colour_on();
339 else
340 colour_off();
341
342 screencheck(Player.y);
343
344 /* game cycle */
345 if (!continuing)
346 time_clock(TRUE);
347 while (TRUE) {
348 if (Current_Environment == E_COUNTRYSIDE)
349 p_country_process();
350 else time_clock(FALSE);
351 }
352 }
353
354 #ifndef MSDOS
signalexit()355 void signalexit()
356 {
357 int reply;
358 clearmsg();
359 mprint("Yikes!");
360 morewait();
361 mprint("Sorry, caught a core-dump signal.");
362 mprint("Want to try and save the game?");
363 reply = ynq();
364 if (reply=='y')
365 save(FALSE, TRUE); /* don't compress, force save */
366 else if (reply == EOF)
367 signalsave();
368 mprint("Bye!");
369 endgraf();
370 exit(0);
371 }
372 #endif
373
374
375
376
377 /* Start up game with new dungeons; start with player in city */
init_world()378 void init_world()
379 {
380 int env, i;
381
382 City = Level = TempLevel = Dungeon = NULL;
383 for (env = 0; env <= E_MAX; env++)
384 level_seed[env] = RANDFUNCTION();
385 load_country();
386 for(i=0;i<NUMCITYSITES;i++)
387 CitySiteList[i][0] = FALSE;
388 load_city(TRUE);
389 WIDTH = 64;
390 LENGTH = 64;
391 Player.x = 62;
392 Player.y = 21;
393 Level = City;
394 Current_Environment = E_CITY;
395 print1("You pass through the massive gates of Rampart, the city.");
396 }
397
398 /* set variable item names */
inititem(reset)399 void inititem(reset)
400 int reset;
401 {
402 int i;
403
404 if (reset) {
405 shuffle(scroll_ids, 30);
406 shuffle(potion_ids, 20);
407 shuffle(stick_ids, 20);
408 shuffle(boot_ids, 20);
409 shuffle(cloak_ids, 20);
410 shuffle(ring_ids, 20);
411 }
412 for(i=0;i<NUMSCROLLS;i++)
413 Objects[SCROLLID+i].objstr = scrollname(i);
414 for(i=0;i<NUMPOTIONS;i++)
415 Objects[POTIONID+i].objstr = potionname(i);
416 Objects[ARTIFACTID + 10].objstr = potionname(18);
417 Objects[ARTIFACTID + 13].objstr = potionname(19);
418 for(i=0;i<NUMSTICKS;i++)
419 Objects[STICKID+i].objstr = stickname(i);
420 for(i=0;i<NUMBOOTS;i++)
421 Objects[BOOTID+i].objstr = bootname(i);
422 for(i=0;i<NUMCLOAKS;i++)
423 Objects[CLOAKID+i].objstr = cloakname(i);
424 for(i=0;i<NUMRINGS;i++)
425 Objects[RINGID+i].objstr = ringname(i);
426 }
427