├── BUGS ├── GDB_commands ├── GDB_di ├── GDB_run ├── Makefile ├── NetBSD ├── README ├── ben_wong.netbsd_config └── ben_wong.netbsd_install ├── PROGRESS ├── README ├── README.md ├── bank.c ├── bj.c ├── bj.h ├── blackmarket.c ├── blow.c ├── casino.c ├── casino.h ├── config.h ├── configure.h ├── constants.h ├── create.c ├── creature.c ├── death.c ├── debug.c ├── debug.h ├── desc.c ├── dungeon.c ├── dungeon.h ├── eat.c ├── encrypt.c ├── files.c ├── generate.c ├── generate.h ├── help.c ├── horse.c ├── horse.h ├── imoria.h ├── insurance.c ├── inven.c ├── io.c ├── item_guide.txt ├── magic.c ├── master.c ├── master.h ├── mhelp.pl ├── misc.c ├── monk.c ├── monsters.c ├── monsters.dat ├── monsters.info ├── moria.c ├── mtwist ├── COPYING ├── Makefile ├── mt-optimized-cokus.c └── mtwist.h ├── netopen.c ├── pascal.c ├── pascal.h ├── patchlevel.h ├── play.c ├── player.c ├── port.c ├── potions.c ├── prayer.c ├── quest.c ├── random.c ├── river.c ├── rooms.c ├── routines.h ├── run_gdb.pl ├── save.c ├── screen.c ├── scrolls.c ├── sing.c ├── slots.c ├── slots.h ├── spells.c ├── staffs.c ├── store.c ├── term.c ├── term.h ├── termdef.c ├── trade.c ├── trade.h ├── traps.c ├── treasure.c ├── types.h ├── unix.c ├── values.h ├── variables.h ├── wands.c └── wizard.c /BUGS: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | prerelease alpha 3 | 4 | July 12 1998 errors in saving file don't always abort save (write errors) 5 | 6 | ------------------------------------------------------------------------------- 7 | 8 | July 14 1998 should allow move w/o pickup 9 | 10 | ------------------------------------------------------------------------------- 11 | 12 | July 18 1998 is it possible to have identical claim_check numbers? 13 | is it possible that creation_time will move if no save? 14 | ummmm, create trade file if missing... 15 | 16 | July 25 post should check master file before letting ppl in 17 | 18 | july 28 light off, walk up dark hall to panel change, @ is at top 19 | of screen [ used_line is not set in term.c ] (fixed) 20 | 21 | 22 | aug 15 combat with a siren teleported me on top of her, messed stuff 23 | up. light on did not draw me, only w/ light off did @ show up 24 | 25 | poisonus berries showed up with a * in the ident list 26 | 27 | oct 11 put/take for bags is not written, nor is 'I' (fixed) 28 | staff of darkness messes up screen (fixed) 29 | 30 | oct 12 ^M is not working, getch returns a 10 31 | exits w/o error if ncurses dislikes term type? 32 | move file paths to Makefile? 33 | 34 | 35 | THIS FILE IS WAY OUT OF DATE. I'm tracking bugs on scraps of paper next 36 | to my mouse. Lots of them are logged in the PROGRESS file as they are 37 | fixed. 38 | 39 | /* end bugs */ 40 | -------------------------------------------------------------------------------- /GDB_commands: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | define rerun 3 | run -f ss 4 | end 5 | document rerun 6 | do this: run -f ss 7 | end 8 | ############################################################## 9 | define wizon 10 | set wizard2 = 1 11 | set wizard1 = 1 12 | end 13 | 14 | document wizon 15 | turn wizard2 and wizard1 on 16 | end 17 | ############################################################## 18 | define wizoff 19 | set wizard2 = 0 20 | set wizard1 = 0 21 | end 22 | 23 | document wizoff 24 | turn wizard2 and wizard1 off 25 | end 26 | ############################################################## 27 | define curloc 28 | printf "player location: [%d][%d]\n", char_row, char_col 29 | end 30 | 31 | define ploc 32 | curloc 33 | end 34 | 35 | document curloc 36 | print char_row and char_col 37 | end 38 | 39 | document ploc 40 | print char_row and char_col 41 | end 42 | 43 | ############################################################## 44 | define curpos 45 | pcave char_row char_col 46 | end 47 | 48 | define ppos 49 | curpos 50 | end 51 | 52 | document curpos 53 | print information about players current position using pcave 54 | end 55 | 56 | document ppos 57 | print information about players current position using pcave 58 | end 59 | ############################################################## 60 | define pcave 61 | 62 | printf "cave[%d][%d] = \n", $arg0, $arg1 63 | print cave[$arg0][$arg1] 64 | 65 | if cave[$arg0][$arg1].tptr != 0 66 | printf "\nt_list[%d] = \n", cave[$arg0][$arg1].tptr 67 | print t_list[cave[$arg0][$arg1].tptr] 68 | else 69 | printf "\n No treasure.\n" 70 | end 71 | 72 | if cave[$arg0][$arg1].cptr != 0 73 | if cave[$arg0][$arg1].cptr != 1 74 | printf "\nm_list[%d] = \n", cave[$arg0][$arg1].cptr 75 | print m_list[cave[$arg0][$arg1].cptr] 76 | printf "\nc_list[%d] = \n", m_list[cave[$arg0][$arg1].cptr].mptr 77 | print c_list[m_list[cave[$arg0][$arg1].cptr].mptr] 78 | else 79 | printf "\n Player is here.\n" 80 | end 81 | else 82 | printf "\n No monster.\n" 83 | end 84 | 85 | end 86 | 87 | ############################## 88 | document pcave 89 | print information about what is at cave[arg0][arg1] 90 | end 91 | ############################################################## 92 | define l100 93 | set py.misc.lev = 100 94 | end 95 | ############################## 96 | document l100 97 | set py.misc.lev = 100 98 | end 99 | ############################################################## 100 | 101 | define pt 102 | print t_list[$arg0] 103 | end 104 | document pt 105 | print t_list[arg0] 106 | end 107 | 108 | ############################################################## 109 | define ppas1 110 | print (unsigned char)password1[0] 111 | print (unsigned char)password1[1] 112 | print (unsigned char)password1[2] 113 | print (unsigned char)password1[3] 114 | print (unsigned char)password1[4] 115 | print (unsigned char)password1[5] 116 | print (unsigned char)password1[6] 117 | print (unsigned char)password1[7] 118 | print (unsigned char)password1[8] 119 | print (unsigned char)password1[9] 120 | print (unsigned char)password1[10] 121 | print (unsigned char)password1[11] 122 | print (unsigned char)password1[12] 123 | end 124 | ############################## 125 | document ppas1 126 | Helps figure out how to set wdata. Set wdata[0][0] to a seed 127 | and set the rest of the array to 0. Start the game, and then 128 | run ppas1. It will show what to xor the password against to 129 | fill in wdata correctly. 130 | end 131 | ############################################################## 132 | define ppas2 133 | print (unsigned char)password2[0] 134 | print (unsigned char)password2[1] 135 | print (unsigned char)password2[2] 136 | print (unsigned char)password2[3] 137 | print (unsigned char)password2[4] 138 | print (unsigned char)password2[5] 139 | print (unsigned char)password2[6] 140 | print (unsigned char)password2[7] 141 | print (unsigned char)password2[8] 142 | print (unsigned char)password2[9] 143 | print (unsigned char)password2[10] 144 | print (unsigned char)password2[11] 145 | print (unsigned char)password2[12] 146 | end 147 | ############################## 148 | document ppas2 149 | Helps figure out how to set wdata. Set wdata[1][0] to a seed 150 | and set the rest of the array to 0. Start the game, and then 151 | run ppas2. It will show what to xor the password against to 152 | fill in wdata correctly. 153 | end 154 | ############################################################## 155 | 156 | ############################## 157 | 158 | ############################################################## 159 | 160 | ############################## 161 | 162 | ############################################################## 163 | ############################################################## 164 | -------------------------------------------------------------------------------- /GDB_di: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | 3 | source GDB_commands 4 | 5 | printf "\nCommands loaded, continuing...\n\n" 6 | 7 | continue 8 | 9 | ############################################################## 10 | -------------------------------------------------------------------------------- /GDB_run: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | 3 | source GDB_commands 4 | 5 | run -f ss 6 | 7 | ############################################################## 8 | -------------------------------------------------------------------------------- /NetBSD/README: -------------------------------------------------------------------------------- 1 | In May 2002 Ben Wong sent me some patches to help build imoria on NetBSD. 2 | Changes that were easy to include in the main codeline have already been 3 | applied. Makefile and configure.h changes have been left out. 4 | 5 | This directory has the original email he sent me for those two files, 6 | I don't have NetBSD installed anyplace so I haven't tested them. 7 | 8 | Enjoy, 9 | 10 | -steve 11 | -------------------------------------------------------------------------------- /NetBSD/ben_wong.netbsd_config: -------------------------------------------------------------------------------- 1 | From benjamin.wong@cc.gatech.edu Tue May 28 01:08:30 2002 2 | Date: Sat, 25 May 2002 18:54:20 -0400 (EDT) 3 | From: Ben Wong 4 | To: kertes@amazon.com 5 | Subject: imoria patch: NetBSD configuration 6 | 7 | You won't want to apply this patch. It changes configure.h to install 8 | the files in the /usr/pkg hierarchy, and to disable the Mersenne 9 | twister. It also turns off the "USE_CURSES_ATTRS" since it wasn't 10 | compiling nicely with the standard BSD curses. (I don't know if using 11 | ncurses would have made it work, but I poked at it a bit and it didn't 12 | seem to help). 13 | 14 | What do I lose by not having USE_CURSES_ATTRS? Is it worth fixing? 15 | 16 | [ kertes: Various status indicators like blind/hungry/confused get drawn 17 | in bold or blinking if they are important. The game plays the same 18 | without USE_CURSES_ATTRS, I just like to make sure I see that I'm about 19 | to die of hunger. ] 20 | 21 | --- configure.h.orig Tue Jul 28 01:24:44 1998 22 | +++ configure.h 23 | @@ -13,7 +13,8 @@ 24 | If USE_MTWIST is 0 then rand() will be used rather than the 25 | Mersenne Twister library. 26 | */ 27 | -#define USE_MTWIST 1 28 | +/*#define USE_MTWIST 1*/ 29 | +#define USE_MTWIST 0 30 | 31 | /* 32 | Keep the path under 60 characters or it will overflow some variables. 33 | @@ -26,7 +27,7 @@ 34 | it is run. 35 | 36 | */ 37 | -#define DATA_FILE_PATH "/home/kertes/icmoria" 38 | +#define DATA_FILE_PATH "/usr/pkg/share/imoria" 39 | 40 | /* 41 | Keep this one under 80 characters, it points to the help program... 42 | @@ -46,6 +47,7 @@ 43 | This is only used in put_buffer_attr (term.c). If you get it working 44 | with a curses that it does not currently work with please let me know! 45 | */ 46 | -#define USE_CURSES_ATTRS 1 47 | +/*#define USE_CURSES_ATTRS 1*/ 48 | +#define USE_CURSES_ATTRS 0 49 | 50 | /* END FILE configure.h */ 51 | -------------------------------------------------------------------------------- /NetBSD/ben_wong.netbsd_install: -------------------------------------------------------------------------------- 1 | From benjamin.wong@cc.gatech.edu Tue May 28 01:08:21 2002 2 | Date: Sat, 25 May 2002 18:51:15 -0400 (EDT) 3 | From: Ben Wong 4 | To: kertes@amazon.com 5 | Subject: imoria patch: NetBSD installation 6 | 7 | You won't want to apply this patch. It changes the Makefile to install 8 | the files in the /usr/pkg hierarchy that NetBSD uses for package 9 | management. You may want to look, though, at some of the choices I've 10 | made: 11 | 12 | * I disabled the Mersenne Twister because it was not compiling 13 | correctly. I think MT may be overkill. If rand(3) isn't good enough, 14 | it'd make more sense to use random(3), which is available under most 15 | Unixes these days. 16 | 17 | * I chose to link with the default BSD curses library instead of 18 | requiring ncurses. (I'm not sure how much benefit ncurses gives, so 19 | I didn't bother getting it to work). 20 | 21 | * I added an "install:" target which copies over the basic files plus 22 | monsters.info, runs imoria to install the "first time" files, and 23 | then sets the proper privileges. 24 | 25 | Note the ugly kludge of giving the -q flag to imoria. I'm not sure 26 | why, but imoria just quits when given any flag. This prevents imoria 27 | from actually starting a game if the "first time" files are already 28 | installed. 29 | 30 | 31 | --- Makefile.orig Fri Feb 18 02:42:28 2000 32 | +++ Makefile 33 | @@ -13,13 +13,13 @@ 34 | # make privs 35 | # 36 | ############################################################################### 37 | -DESTDIR = /usr/local 38 | +DESTDIR = /usr/pkg 39 | 40 | BINDEST = $(DESTDIR)/bin 41 | MANDEST = $(DESTDIR)/man 42 | 43 | -#LIBDEST = $(DESTDIR)/lib 44 | -LIBDEST = /usr/lib 45 | +LIBDEST = $(DESTDIR)/lib 46 | +#LIBDEST = /usr/lib 47 | INCDEST = $(DESTDIR)/include 48 | 49 | MANEXT = 1 50 | @@ -29,10 +29,10 @@ 51 | HARDLINK = ln -f 52 | 53 | # For BSD Systems 54 | -CURSES = -lncurses -ltermcap 55 | +CURSES = -lcurses -ltermcap 56 | 57 | CC = gcc 58 | -#INCLUDES = -I/usr/include/tcl 59 | +INCLUDES = -I/usr/pkg/include 60 | #INCLUDES = -I. 61 | 62 | DEFINES = -DDO_DEBUG=0 63 | @@ -44,12 +44,12 @@ 64 | COPTS = -Wall -g3 65 | 66 | CFLAGS = $(COPTS) $(INCLUDES) $(DEFINES) 67 | -LDFLAGS = 68 | +LDFLAGS = -L/usr/pkg/lib -Wl,-rpath,/usr/pkg/lib 69 | 70 | # 71 | # the owner and group for the game and data files 72 | # 73 | -OWNER = games 74 | +OWNER = root 75 | GROUP = games 76 | 77 | # 78 | @@ -59,7 +59,7 @@ 79 | WRITEFILES = death.log moriamas.dat moriatop.dat moriatrd.dat 80 | DATAFILES = $(READFILES) $(WRITEFILES) 81 | 82 | -all: mtwist imoria 83 | +all: imoria 84 | 85 | ############################################################################# 86 | # 87 | @@ -104,7 +104,7 @@ 88 | 89 | 90 | imoria: $(IMORIAOBJS) 91 | - $(CC) $(LDFLAGS) $(IMORIAOBJS) $(LIBS) $(MTWIST) -o $@ 92 | + $(CC) $(LDFLAGS) $(IMORIAOBJS) $(LIBS) -o $@ 93 | chown $(OWNER):$(GROUP) imoria 94 | chmod 2711 imoria 95 | echo 96 | @@ -258,3 +258,21 @@ 97 | wizard.o: wizard.c imoria.h mtwist/mtwist.h patchlevel.h configure.h \ 98 | constants.h types.h pascal.h routines.h term.h debug.h variables.h \ 99 | dungeon.h 100 | + 101 | +install: all 102 | + mkdir -p /usr/pkg/share/imoria 103 | + chgrp games /usr/pkg/share/imoria 104 | + chmod 2775 /usr/pkg/share/imoria 105 | + cp -p monsters.dat /usr/pkg/share/imoria/ 106 | + cp -p monsters.info /usr/pkg/share/imoria/ 107 | + cp -p mhelp.pl /usr/pkg/share/imoria/ 108 | + cp -p imoria /usr/pkg/bin/ 109 | + ./imoria -q >/dev/null 110 | + chown $(OWNER):$(GROUP) /usr/pkg/bin/imoria 111 | + chown $(OWNER):$(GROUP) /usr/pkg/share/imoria/* 112 | + chmod 2711 /usr/pkg/bin/imoria 113 | + (cd /usr/pkg/share/imoria; \ 114 | + chmod 640 $(READFILES); \ 115 | + chmod 660 $(WRITEFILES); \ 116 | + chmod 755 mhelp.pl) 117 | + 118 | 119 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | I finally wrote a README file. 2 | 3 | Making imoria: 4 | 5 | Edit configure.h to set the paths you want the data files to go and 6 | were the help file (mhelp.pl) will be. 7 | 8 | Put a copy of monsters.dat into the DATA_FILE_PATH, and move mhelp.pl 9 | to the propper place as well. 10 | 11 | In the Makefile edit the owner and group to use for the game and data files. 12 | Also pick how the mtwist library will be linked to imoria, the default is 13 | as a shared library. The Makefile has a lot more imormation about this. 14 | 15 | run "make mtwist" 16 | run "make imoria" 17 | 18 | the first time you run imoria it should make a bunch of data files and 19 | then quit. I run "make privs" to fixup the file ownership and privileges, 20 | since the Makefile does not know where the data files are at this may 21 | not work correctly for you (I do intend to make this better). 22 | 23 | 24 | Common problems: 25 | 26 | Several people are having a problem running the game where it quits 27 | right after starting, without any error messages. Two problems have 28 | been found that cause this. The first is not having copied monsters.dat 29 | to the data files directory that is set in configure.h. The second 30 | is if ncurses does not like the default terminal type. 31 | 32 | 33 | /* end readme */ 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ICMoria 4.85.22 2 | 3 | This repository contains the source code for the ICMoria roguelike game, developed by Stephen Kertes between 1997 and 2003. 4 | 5 | ICMoria was ported from [Imoria](https://github.com/dungeons-of-moria/imoria), which itself was based on [Moria](https://github.com/dungeons-of-moria/vms-moria), and is a part of the Rogue and Nethack family of dungeon games with character graphics. 6 | 7 | Kertes noted that most of the development work was done on Slackware. Around 2002 he got it running under Red Hat 5.1 - although a lot of the encryption code had to be rewritten because of missing libraries on RH. In Aug 2003 he found out that it also works on a custom RedHat 6.2. 8 | 9 | It's unkown what other systems ICMoria will compile and run on. 10 | -------------------------------------------------------------------------------- /bj.h: -------------------------------------------------------------------------------- 1 | /* bj.h */ 2 | /* declarations for the blackjack module in the casino */ 3 | 4 | typedef vtype drawcard[16]; 5 | typedef integer hand[16]; 6 | 7 | extern void bj__game_blackjack(); 8 | 9 | /* END FILE bj.h */ 10 | -------------------------------------------------------------------------------- /casino.c: -------------------------------------------------------------------------------- 1 | /* casino.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "casino.h" 6 | #include "slots.h" 7 | #include "horse.h" 8 | #include "bj.h" 9 | 10 | integer bet; 11 | integer gld; 12 | integer tics; 13 | boolean c_closed; 14 | 15 | void c__display_gold() 16 | { 17 | vtype out_val; 18 | 19 | sprintf(out_val, "gold remaining : %ld ",gld); 20 | prt( out_val, 19, 22); 21 | }; 22 | 23 | 24 | boolean c__get_response(vtype comment, integer *num) 25 | { 26 | integer i1, clen; 27 | vtype out_val; 28 | boolean flag; 29 | 30 | flag = true; 31 | i1 = 0; 32 | clen = strlen(comment) + 2; 33 | 34 | do { 35 | prt(comment,1,1); 36 | msg_flag = false; 37 | if (!(get_string(out_val,1,clen,40))) { 38 | flag = false; 39 | erase_line(msg_line,msg_line); 40 | } 41 | sscanf(out_val,"%ld", &i1); 42 | } while (!((i1 != 0) || !(flag))); 43 | 44 | if (flag) { 45 | *num = i1; 46 | } 47 | 48 | return flag; 49 | }; 50 | 51 | void c__change_money() 52 | { 53 | int amount; 54 | 55 | amount = abs(py.misc.money[TOTAL_] - gld)*GOLD_VALUE; 56 | if (gld > py.misc.money[TOTAL_]) { 57 | add_money(amount); 58 | } else { 59 | subtract_money(amount,true); 60 | } 61 | }; 62 | 63 | void c__check_casino_kickout() 64 | { 65 | if ((tics % 2) == 1) { 66 | if (check_kickout()) { 67 | msg_print("A new version of Imoria is being installed."); 68 | msg_print("After your character is saved, wait a few minutes,"); 69 | msg_print("And then try to run the game."); 70 | msg_print(""); 71 | c__change_money(); 72 | do { 73 | py.flags.dead = false; 74 | save_char(true); 75 | } while (!false); 76 | } 77 | } 78 | tics++; 79 | }; 80 | 81 | void c__display_casino() 82 | { 83 | vtype shop_owner; 84 | 85 | clear_screen(); 86 | strcpy(shop_owner, "Darkon (Master-Hacker) Casino"); 87 | prt(shop_owner, 4, 10); 88 | prt("Game: Max Bet",6,4); 89 | prt("a) slots 10000", 7,1); 90 | prt("b) blackjack 1000", 8,1); 91 | prt("c) horse racing 1000", 9,1); 92 | c__display_gold(); 93 | prt("You may:",21,1); 94 | prt(" p) Play a game. h) Help on game rules.",22,2); 95 | prt("^R) Redraw the screen. Esc) Exit from building.",23,2); 96 | }; 97 | 98 | void c__play_game(char game) 99 | { 100 | boolean exit_flag = false; 101 | 102 | do { 103 | if (game == 0) { 104 | msg_print("Which game do you want to play? "); 105 | exit_flag = !get_com("", &game); 106 | } 107 | 108 | if (!exit_flag) { 109 | switch (game) { 110 | case 97 : 111 | sm__game_slots(); 112 | exit_flag = true; 113 | c__display_casino(); 114 | break; 115 | 116 | case 98 : 117 | bj__game_blackjack(); 118 | exit_flag = true; 119 | c__display_casino(); 120 | break; 121 | 122 | case 99 : 123 | hr__game_horse(); 124 | exit_flag = true; 125 | c__display_casino(); 126 | break; 127 | 128 | default: 129 | prt("That game does not exist, try again.",1,1); 130 | break; 131 | } 132 | } else { 133 | exit_flag = true; 134 | } 135 | } while (!exit_flag); 136 | }; 137 | 138 | 139 | void c__parse_command() 140 | { 141 | char command; 142 | boolean exit_flag = false; 143 | 144 | do { 145 | if (get_com( "", &command)) { 146 | switch (command) { 147 | case 97 : 148 | case 98 : 149 | case 99 : 150 | c__play_game(command); 151 | break; 152 | 153 | case 112 : c__play_game(0); break; 154 | case 18 : c__display_casino(); break; 155 | default : prt("Invalid Command.",1,1); break; 156 | } 157 | } else { 158 | exit_flag = true; 159 | } 160 | } while (!(exit_flag || c_closed)); 161 | }; 162 | 163 | void c__exit_messages() 164 | { 165 | if (gld > 2*py.misc.money[TOTAL_] + 1000) { 166 | switch (randint(3)) { 167 | case 1 : msg_print("Quitting while you're ahead, huh?");break; 168 | case 2 : msg_print("Lady luck must be on you side.");break; 169 | case 3 : msg_print("A pair of heavily armed thugs show you to the door."); 170 | break; 171 | } 172 | } else if (gld < py.misc.money[TOTAL_] - 1000) { 173 | switch (randint(4)) { 174 | case 1 : msg_print("KC thanks you for your patronage.");break; 175 | case 2 : msg_print("KC personally escorts you to the door.");break; 176 | case 3 : msg_print("Better luck next time.");break; 177 | case 4 : msg_print("You leave a sadder and wiser man.");break; 178 | } 179 | } else { 180 | msg_print("Bye."); 181 | } 182 | //msg_print(""); 183 | }; 184 | 185 | 186 | void enter_casino() 187 | { 188 | c_closed = false; 189 | tics = 1; 190 | seed = get_seed(); 191 | set_seed(seed); 192 | gld = py.misc.money[TOTAL_]; 193 | msg_line = 1; 194 | c__display_casino(); 195 | c__parse_command(); 196 | c__exit_messages(); 197 | c__change_money(); 198 | draw_cave(); 199 | }; 200 | 201 | /* END FILE casino.c */ 202 | -------------------------------------------------------------------------------- /casino.h: -------------------------------------------------------------------------------- 1 | /* casino.h */ 2 | /* common declarations for the casino modules */ 3 | 4 | extern integer bet; 5 | extern integer gld; 6 | extern integer tics; 7 | extern boolean c_closed; 8 | 9 | extern void c__display_gold(); 10 | extern boolean c__get_response(vtype comment, integer *num); 11 | extern void c__change_money(); 12 | extern void c__check_casino_kickout(); 13 | 14 | 15 | /* END FILE casino.h */ 16 | -------------------------------------------------------------------------------- /configure.h: -------------------------------------------------------------------------------- 1 | /* configure.h*/ 2 | /* include file for fun configurable stuff */ 3 | 4 | /* 5 | My system has des_crypt.h, some do not. Set to 0 to disable des encryption 6 | in favor of xor against random numbers. It turns out that it was happier 7 | to xor everything against the random numbers even when DES was going to be 8 | used, so turning on des is probably major overkill but I do not mind. 9 | */ 10 | #define ENABLE_DES 0 11 | 12 | /* 13 | If USE_MTWIST is 0 then rand() will be used rather than the 14 | Mersenne Twister library. 15 | */ 16 | #define USE_MTWIST 1 17 | 18 | /* 19 | Keep the path under 60 characters or it will overflow some variables. 20 | 21 | This is where hours.dat, moria.dat, monsters.dat, moria_gcustom.mst, 22 | moriamas.dat, moriatop.dat, moriatrd.dat, death.log 23 | 24 | WARNING: Be sure to copy monsters.dat to this directory! The game 25 | will attempt to create the other files the first time that 26 | it is run. 27 | 28 | */ 29 | #define DATA_FILE_PATH "/home/kertes/icmoria" 30 | 31 | /* 32 | Keep this one under 160 characters, it points to the help program... 33 | You may have to edit mhelp.pl to set the path to perl. 34 | */ 35 | #define HELP_FILE_PATH DATA_FILE_PATH "/mhelp.pl" 36 | 37 | /* 38 | The curses I have on my system defines attr_get() and attrset(attr) 39 | differently than the one that a lot of people using Red Hat have. 40 | 41 | I don't know what to use to get and set the attributes with the 42 | newer library so change this to 1 if you want to try the nifty 43 | attr changes I added. Otherwise you can leave it set to 0 and 44 | always wonder what the game could be like... 45 | 46 | This is only used in put_buffer_attr (term.c). If you get it working 47 | with a curses that it does not currently work with please let me know! 48 | */ 49 | #define USE_CURSES_ATTRS 1 50 | 51 | /* END FILE configure.h */ 52 | -------------------------------------------------------------------------------- /debug.c: -------------------------------------------------------------------------------- 1 | /* debug.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | 6 | #if DO_DEBUG 7 | FILE *debug_file = NULL; 8 | int call_depth = 0; 9 | 10 | ////////////////////////////////////////////////////////////////////// 11 | ////////////////////////////////////////////////////////////////////// 12 | ////////////////////////////////////////////////////////////////////// 13 | void enter(char *routine_name,char *marker) 14 | { 15 | if (debug_file == NULL) { 16 | debug_file = (FILE *)fopen("Debug.out","w"); 17 | } 18 | 19 | call_depth++; 20 | 21 | if (debug_file != NULL) { 22 | fprintf(debug_file, ":::%4d: ENTER %s | %s |\n", 23 | call_depth,routine_name,marker); 24 | 25 | // fprintf(debug_file,": In %ld %ld\n",panel_row_min,panel_row_max); 26 | 27 | fflush(debug_file); 28 | } 29 | } 30 | ////////////////////////////////////////////////////////////////////// 31 | ////////////////////////////////////////////////////////////////////// 32 | ////////////////////////////////////////////////////////////////////// 33 | void leave(char *routine_name,char *marker) 34 | { 35 | if ( debug_file == NULL ) { 36 | return; 37 | } 38 | 39 | // fprintf(debug_file,": Out %ld %ld\n",panel_row_min,panel_row_max); 40 | 41 | fprintf(debug_file, ":::%4d: LEAVE %s | %s |\n", 42 | call_depth,routine_name,marker); 43 | 44 | fflush(debug_file); 45 | 46 | 47 | call_depth--; 48 | } 49 | ////////////////////////////////////////////////////////////////////// 50 | ////////////////////////////////////////////////////////////////////// 51 | ////////////////////////////////////////////////////////////////////// 52 | void return_dbg(char *routine_name,char *marker, 53 | char typestr, char *descript, void *valptr) 54 | { 55 | 56 | if ( debug_file == NULL ) { 57 | return; 58 | } 59 | 60 | // fprintf(debug_file,": Ret %ld %ld\n",panel_row_min,panel_row_max); 61 | 62 | switch (typestr) { 63 | 64 | case 'b': 65 | fprintf(debug_file, ":::%4d: RETUR %s | %s | %s = %s\n", 66 | call_depth,routine_name,marker,descript, 67 | (*((boolean *)valptr)) == 0 ? "false" : "true"); 68 | break; 69 | 70 | case 'd': 71 | fprintf(debug_file, ":::%4d: RETUR %s | %s | %s = %ld\n", 72 | call_depth,routine_name,marker,descript,*((integer *)valptr)); 73 | break; 74 | 75 | case 'u': 76 | fprintf(debug_file, ":::%4d: RETUR %s | %s | %s = %lu\n",call_depth, 77 | routine_name,marker,descript,*((unsigned long *)valptr)); 78 | break; 79 | 80 | case 's': 81 | fprintf(debug_file, ":::%4d: RETUR %s | %s | %s = %s\n", 82 | call_depth,routine_name,marker,descript,(char *)valptr); 83 | break; 84 | 85 | case 'y': 86 | fprintf(debug_file, ":::%4d: RETUR %s | %s | %s = %ld\n", 87 | call_depth,routine_name,marker,descript,(integer)(*((bytlint *)valptr))); 88 | 89 | default: 90 | fprintf(debug_file, ":::%4d: RETUR %s | %s | %s = (unknown type %c)\n", 91 | call_depth,routine_name,marker,descript,typestr); 92 | break; 93 | 94 | } 95 | 96 | 97 | fflush(debug_file); 98 | 99 | call_depth--; 100 | } 101 | ////////////////////////////////////////////////////////////////////// 102 | ////////////////////////////////////////////////////////////////////// 103 | ////////////////////////////////////////////////////////////////////// 104 | void log_msg(char *str) 105 | { 106 | if ( debug_file == NULL ) { 107 | return; 108 | } 109 | 110 | fprintf(debug_file, "> %s\n", str); 111 | fflush(debug_file); 112 | }; 113 | ////////////////////////////////////////////////////////////////////// 114 | ////////////////////////////////////////////////////////////////////// 115 | ////////////////////////////////////////////////////////////////////// 116 | #endif 117 | /* END FILE debug.c */ 118 | -------------------------------------------------------------------------------- /debug.h: -------------------------------------------------------------------------------- 1 | /* debug.h */ 2 | /**/ 3 | 4 | #if DO_DEBUG 5 | 6 | #define ENTER(rname,mark) enter((rname), (mark)); 7 | #define LEAVE(rname,mark) leave((rname), (mark)); 8 | #define RETURN(rname,mark,typestr,desc,valptr) return_dbg((rname),(mark),(typestr),(desc),(valptr)); 9 | #define MSG(str) log_msg(str); 10 | 11 | extern FILE *debug_file; 12 | extern int call_depth; 13 | 14 | #else 15 | 16 | #define ENTER(rname,mark) 17 | #define LEAVE(rname,mark) 18 | #define RETURN(rname,mark,typestr,desc,valptr) 19 | #define MSG(str) 20 | 21 | #endif 22 | 23 | extern void enter(char *routine_name,char *marker); 24 | extern void leave(char *routine_name,char *marker); 25 | extern void return_dbg(char *routine_name,char *marker,char typestr, char *descript, void *valptr); 26 | extern void log_msg(char *str); 27 | 28 | 29 | /* END FILE debug.h */ 30 | -------------------------------------------------------------------------------- /dungeon.h: -------------------------------------------------------------------------------- 1 | /* dungeon.h */ 2 | /* there were not enough globals in variables.h */ 3 | 4 | #define DRAW_BOLT_DELAY 50 5 | #define DRAW_BALL_DELAY 30 6 | 7 | typedef integer mm_type[6]; //array [1..5] of integer; 8 | 9 | extern integer dir_val; // { For movement } 10 | //extern integer y,x,moves; // { For movement } 11 | //extern integer i1,i2,tmp1; // { Temporaries } 12 | extern integer old_chp,old_cmana; // { Detect change } 13 | extern real regen_amount; // { Regenerate hp and mana} 14 | extern char command; // { Last command } 15 | //extern vtype out_val,out2; // { For messages } 16 | //extern vtype tmp_str; // { Temporary } 17 | extern boolean moria_flag; // { Next level when true } 18 | extern boolean reset_flag; // { Do not move creatures } 19 | extern boolean search_flag; // { Player is searching } 20 | extern boolean teleport_flag; // { Handle telport traps } 21 | extern boolean player_light; // { Player carrying light } 22 | extern boolean save_msg_flag; // { Msg flag after INKEY } 23 | extern ttype s1,s2,s3,s4; // { Summon item strings } 24 | extern integer i_summ_count; // { Summon item count } 25 | //extern char trash_char; 26 | //extern FILE * f1; 27 | //extern stat_set tstat; 28 | //extern treas_ptr trash_ptr; 29 | 30 | #define DISPLAY_SIZE 20 31 | #define MOO_DISPLAY_SIZE 18 32 | 33 | /* index stuff for door_list */ 34 | #define DL_OPEN 0 35 | #define DL_CLOSED 1 36 | #define DL_SECRET 2 37 | 38 | #define ML(mmm) (m_list[(mmm)]) 39 | #define MY(mmm) (m_list[(mmm)].fy) 40 | #define MX(mmm) (m_list[(mmm)].fx) 41 | 42 | extern boolean do_stun(byteint a_cptr, integer save_bonus, integer time); 43 | extern void desc_remain(treas_ptr item_ptr); 44 | extern void add_food(integer num); 45 | extern void desc_charges(treas_ptr item_ptr); 46 | extern boolean move_to_creature(integer dir, integer *y, integer *x); 47 | extern boolean bolt_to_creature(integer dir, integer *y, integer *x, 48 | integer *dist, integer max_dist, 49 | boolean visable); 50 | extern boolean cast_spell(vtype prompt, treas_ptr item_ptr, integer *sn, 51 | integer *sc, boolean *redraw); 52 | extern boolean d__get_dir(vtype prompt, integer *dir, integer *com_val, 53 | integer *y, integer *x); 54 | extern boolean explode(integer typ,integer y,integer x, 55 | integer dam_hp,ctype descrip); 56 | extern void teleport(integer dis); 57 | extern boolean create_water(integer y, integer x); 58 | extern boolean destroy_water(integer y, integer x); 59 | extern boolean item_petrify(); 60 | extern boolean xor(integer thing1, integer thing2); 61 | extern void blow(); 62 | 63 | /* END FILE dungeon.h */ 64 | -------------------------------------------------------------------------------- /eat.c: -------------------------------------------------------------------------------- 1 | /* eat.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "dungeon.h" 6 | ////////////////////////////////////////////////////////////////////// 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | void e__eyeball_of_drong(treas_ptr item_ptr, boolean *ident) 10 | { 11 | integer i1; 12 | 13 | i1 = damroll("10d8")+100; 14 | take_hit(i1, "the Wrath of Ned"); 15 | 16 | cure_me(&PF.afraid); 17 | bless(randint(100)+100); 18 | PF.hero += randint(100) + 100; 19 | PF.shero += randint(50) + 75; 20 | PF.invuln += randint(15) + 10; 21 | 22 | PF.image += randint(500) + randint(500) + randint(1000) + 5000; 23 | PF.poisoned += randint(100) + 150; 24 | PF.confused += randint(30) + 50; 25 | PF.blind += randint(3) + 10; 26 | PF.paralysis = 4; 27 | 28 | msg_print("You hear a distant rumble of laughter..."); 29 | msg_print("You throw back your head and laugh back!"); 30 | aggravate_monster(30); 31 | 32 | i1 = randint(5); 33 | if (i1 == 1) { 34 | gain_stat(STR,"Ned smiles upon you."); 35 | gain_stat(INT,""); 36 | gain_stat(WIS,""); 37 | gain_stat(DEX,""); 38 | gain_stat(CON,""); 39 | gain_stat(CHR,""); 40 | } 41 | 42 | msg_print("Your head begins to spin. Spots swirl before you."); 43 | msg_print("A veil of darkness clings to your eyes."); 44 | msg_print("You are unable to move!"); 45 | 46 | *ident = true; 47 | }; 48 | ////////////////////////////////////////////////////////////////////// 49 | void eat() 50 | { 51 | /* { Eat some food... -RAK- }*/ 52 | 53 | unsigned long i1; 54 | integer i3,i4,i5; 55 | treas_ptr i2,item_ptr; 56 | char trash_char; 57 | boolean redraw,ident; 58 | integer dam_pts = 0; 59 | 60 | obj_set things_to_eat = {Food, Junk_food, 0}; 61 | 62 | reset_flag = true; 63 | 64 | if (inven_ctr > 0) { 65 | if (find_range(things_to_eat,false,&i2,&i3)) { 66 | redraw = false; 67 | if (get_item(&item_ptr,"Eat what?",&redraw,i3,&trash_char,false,false)) { 68 | 69 | //with item_ptr->data. do; 70 | 71 | if (redraw) { 72 | draw_cave(); 73 | } 74 | 75 | reset_flag = false; 76 | ident = false; 77 | 78 | if ((item_ptr->data.tval == junk_food) && 79 | (item_ptr->data.subval == 270)) { /* eyeball of drong */ 80 | e__eyeball_of_drong(item_ptr, &ident); 81 | } else { 82 | 83 | i1 = item_ptr->data.flags; 84 | 85 | for (;i1 > 0;) { 86 | i4 = bit_pos(&i1) + 1; 87 | 88 | /*{ Foods }*/ 89 | 90 | switch (i4) { 91 | case 1 : 92 | //with py.flags do; 93 | PF.poisoned += randint(10) + item_ptr->data.level; 94 | ident = true; 95 | break; 96 | 97 | case 2 : 98 | //with py.flags do; 99 | PF.blind += randint(250) + 10*item_ptr->data.level + 100; 100 | draw_cave(); 101 | msg_print("A veil of darkness surrounds you."); 102 | ident = true; 103 | break; 104 | 105 | case 3 : 106 | //with py.flags do; 107 | PF.afraid += randint(10) + item_ptr->data.level; 108 | msg_print("You feel terrified!"); 109 | ident = true; 110 | break; 111 | 112 | case 4 : 113 | //with py.flags do; 114 | PF.confused += randint(10) + item_ptr->data.level; 115 | msg_print("You feel drugged."); 116 | break; 117 | 118 | case 5 : 119 | //with py.flags do; 120 | PF.image += randint(200) + 25*item_ptr->data.level + 200; 121 | break; 122 | 123 | case 6 : 124 | ident = cure_me(&py.flags.poisoned); 125 | break; 126 | 127 | case 7 : 128 | ident = cure_me(&py.flags.blind); 129 | break; 130 | 131 | case 8 : 132 | //with py.flags do; 133 | if (PF.afraid > 1) { 134 | PF.afraid = 1; 135 | ident = true; 136 | } 137 | break; 138 | 139 | case 9 : 140 | ident = cure_me(&py.flags.confused); 141 | break; 142 | 143 | case 10 : 144 | ident = lose_stat(STR,"X","X"); 145 | break; 146 | 147 | case 11 : 148 | ident = lose_stat(CON,"X","X"); 149 | break; 150 | 151 | case 12 : 152 | ident = lose_stat(INT,"X","X"); 153 | break; 154 | 155 | case 13 : 156 | ident = lose_stat(WIS,"X","X"); 157 | break; 158 | 159 | case 14 : 160 | ident = lose_stat(DEX,"X","X"); 161 | break; 162 | 163 | case 15 : 164 | ident = lose_stat(CHR,"X","X"); 165 | break; 166 | 167 | case 16 : 168 | ident = restore_stat(STR,"You feel your strength returning."); 169 | break; 170 | 171 | case 17 : 172 | ident = restore_stat(CON,"X"); 173 | break; 174 | 175 | case 18 : 176 | ident = restore_stat(INT,"Your head spins for a moment."); 177 | break; 178 | 179 | case 19 : 180 | ident = restore_stat(WIS,"X"); 181 | break; 182 | 183 | case 20 : 184 | ident = restore_stat(DEX,"You feel more agile."); 185 | break; 186 | 187 | case 21 : 188 | ident = restore_stat(CHR,"X"); 189 | break; 190 | 191 | case 22 : 192 | dam_pts += randint(3); 193 | break; 194 | 195 | case 23 : 196 | dam_pts += randint(6); 197 | break; 198 | 199 | case 24 : 200 | dam_pts += randint(12); 201 | break; 202 | 203 | case 25 : 204 | dam_pts += damroll("2d12"); 205 | break; 206 | 207 | case 26 : 208 | dam_pts += damroll("4d12"); 209 | break; 210 | 211 | case 27 : 212 | dam_pts -= randint(4); 213 | break; 214 | 215 | case 28 : 216 | dam_pts -= randint(8); 217 | break; 218 | 219 | case 29 : 220 | ident = cure_me(&py.flags.hoarse); 221 | break; 222 | 223 | /*{ fill player to full, then adds food value }*/ 224 | case 30 : 225 | py.flags.foodc = PLAYER_FOOD_FULL; 226 | msg_print("Yum!"); 227 | break; 228 | 229 | case 31 : 230 | i5 = bit_pos(&item_ptr->data.flags2) + 1; 231 | switch (i5) { 232 | case 1 : /*{crunchy}*/ 233 | switch (randint(4)) { 234 | case 1 : msg_print("*munch* *munch*"); break; 235 | case 2 : msg_print("*crunch* *crunch*"); break; 236 | case 3 : msg_print("*munch* *crunch*"); break; 237 | case 4 : msg_print("*crunch* *munch*"); break; 238 | } 239 | break; 240 | 241 | case 2 : /*{liquid}*/ 242 | switch (randint(3)) { 243 | case 1 : msg_print("*guzzle* *guzzle*"); break; 244 | case 2 : msg_print("*glug* *glug* *glug*"); break; 245 | case 3 : msg_print("*slurp*"); break; 246 | } 247 | 248 | if (randint(3) == 1) { 249 | msg_print("*Burp*"); 250 | msg_print("('scuse me....)"); 251 | } /*{Belch}*/ 252 | break; 253 | 254 | default: 255 | break; 256 | } /* end switch i5 */ 257 | 258 | break; /* end case 31 */ 259 | 260 | default: 261 | break; 262 | } /* end switch i4 */ 263 | 264 | if (dam_pts != 0) { 265 | ident = hp_player(dam_pts,"poisonous food."); 266 | } 267 | 268 | } /* end for */ 269 | } /* end else not eyeball of drong */ 270 | /*{ End of food actions... }*/ 271 | 272 | if (ident) { 273 | identify(&(item_ptr->data)); 274 | } 275 | 276 | if (item_ptr->data.flags != 0) { 277 | //with py.misc do; 278 | if (item_ptr->data.level > 0) { 279 | PM.exp += (((real)item_ptr->data.level/(real)PM.lev) + .5); 280 | prt_experience(); 281 | } 282 | } 283 | 284 | add_food(item_ptr->data.p1); 285 | py.flags.status &= ~(IS_HUNGERY | IS_WEAK); 286 | prt_hunger(); 287 | desc_remain(item_ptr); 288 | inven_destroy(item_ptr); 289 | prt_weight(); 290 | 291 | } else { 292 | if (redraw) { 293 | draw_cave(); 294 | } 295 | } 296 | } else { 297 | msg_print("You are not carrying any food."); 298 | } 299 | } else { 300 | msg_print("But you are not carrying anything."); 301 | } 302 | }; 303 | ////////////////////////////////////////////////////////////////////// 304 | ////////////////////////////////////////////////////////////////////// 305 | ////////////////////////////////////////////////////////////////////// 306 | /* END FILE eat.c */ 307 | -------------------------------------------------------------------------------- /encrypt.c: -------------------------------------------------------------------------------- 1 | /* encrypt.c */ 2 | /* routines to handle encrypting and decrypting save files */ 3 | 4 | #include "imoria.h" 5 | 6 | #if ENABLE_DES 7 | #include 8 | #endif 9 | ////////////////////////////////////////////////////////////////////// 10 | ////////////////////////////////////////////////////////////////////// 11 | ////////////////////////////////////////////////////////////////////// 12 | void encrypt_init(encrypt_state *state, byteint key[], boolean doit) 13 | { 14 | /* called by before using encrypt_write or read_decrypt */ 15 | 16 | #if ENABLE_DES 17 | int i1; 18 | 19 | memcpy(state->des_key, key, 8); 20 | des_setparity(state->des_key); 21 | 22 | for (i1 = 0 ; i1 < 8 ; i1++) { 23 | state->des_ivec[i1] = 0; 24 | } 25 | 26 | state->doit = doit; 27 | #else 28 | state->doit = doit; 29 | #endif 30 | 31 | state->got_eof = false; 32 | state->buf_pos = 0; 33 | state->buf_size = 0; 34 | }; 35 | ////////////////////////////////////////////////////////////////////// 36 | ////////////////////////////////////////////////////////////////////// 37 | ////////////////////////////////////////////////////////////////////// 38 | #if ENABLE_DES 39 | void des_encrypt_write(FILE *f1, encrypt_state *state) 40 | { 41 | /* called by encrypt_write to encode a block of plaintext and write it */ 42 | 43 | int result; 44 | 45 | if (state->buf_pos != 0) { 46 | /* round up to 8 bytes */ 47 | state->buf_pos += 7; 48 | state->buf_pos &= 0xfffffff8; 49 | 50 | result = cbc_crypt(state->des_key, state->data_buf, state->buf_pos, 51 | DES_ENCRYPT | DES_SW, state->des_ivec); 52 | 53 | if (result != DESERR_NONE) { 54 | prt("Error calling cbc_crypt to encrypt.", 1, 1); 55 | put_qio(); 56 | } 57 | 58 | if (write((int)fileno(f1), state->data_buf, state->buf_pos) 59 | != state->buf_pos) { 60 | prt("Error writing line to file.", 1, 1); 61 | put_qio(); 62 | } 63 | 64 | state->buf_pos = 0; 65 | } 66 | }; 67 | #else 68 | void rand_encrypt_write(FILE *f1, encrypt_state *state) 69 | { 70 | /* called by encrypt_write to encode a block of plaintext and write it */ 71 | 72 | if (state->buf_pos != 0) { 73 | 74 | if (write((int)fileno(f1), state->data_buf, state->buf_pos) 75 | != state->buf_pos) { 76 | prt("Error writing line to file.", 1, 1); 77 | put_qio(); 78 | } 79 | 80 | state->buf_pos = 0; 81 | } 82 | }; 83 | #endif 84 | ////////////////////////////////////////////////////////////////////// 85 | ////////////////////////////////////////////////////////////////////// 86 | ////////////////////////////////////////////////////////////////////// 87 | #if ENABLE_DES 88 | void des_read_decrypt(FILE *f1, encrypt_state *state) 89 | { 90 | /* called by read_decrypt to get next block of plaintext */ 91 | 92 | int result; 93 | 94 | state->buf_pos = 0; 95 | state->buf_size = 0; 96 | state->data_buf[0] = 0; 97 | 98 | if (feof(f1)) { 99 | state->got_eof = true; 100 | } else { 101 | 102 | state->buf_size = read((int)fileno(f1), state->data_buf, 103 | ENCRYPT_STAT_BUF_SIZE); 104 | if (state->buf_size == -1) { 105 | prt("Error reading line from file.", 1, 1); 106 | state->got_eof = true; 107 | } else { 108 | 109 | if (state->buf_size == 0) { 110 | state->got_eof = true; 111 | } else if (state->buf_size & 0x07) { 112 | prt("Error read not a multiple of 8 bytes.", 1, 1); 113 | put_qio(); 114 | state->got_eof = true; 115 | state->buf_size = 0; 116 | } else { 117 | result = cbc_crypt(state->des_key, state->data_buf, state->buf_size, 118 | DES_DECRYPT | DES_SW, state->des_ivec); 119 | 120 | if (result != DESERR_NONE) { 121 | prt("Error calling cbc_crypt to decrypt.", 1, 1); 122 | put_qio(); 123 | } 124 | } 125 | } 126 | } 127 | }; 128 | #else 129 | void rand_read_decrypt(FILE *f1, encrypt_state *state) 130 | { 131 | /* called by read_decrypt to get next block of plaintext */ 132 | 133 | state->buf_pos = 0; 134 | state->buf_size = 0; 135 | state->data_buf[0] = 0; 136 | 137 | if (feof(f1)) { 138 | state->got_eof = true; 139 | } else { 140 | 141 | state->buf_size = read((int)fileno(f1), state->data_buf, 142 | ENCRYPT_STAT_BUF_SIZE); 143 | if (state->buf_size == -1) { 144 | prt("Error reading line from file.", 1, 1); 145 | state->got_eof = true; 146 | } else { 147 | 148 | if (state->buf_size == 0) { 149 | state->got_eof = true; 150 | } 151 | } 152 | } 153 | }; 154 | #endif 155 | ////////////////////////////////////////////////////////////////////// 156 | ////////////////////////////////////////////////////////////////////// 157 | ////////////////////////////////////////////////////////////////////// 158 | void encrypt_flush(FILE *f1, encrypt_state *state) 159 | { 160 | /* file is about to close, flush out the rest of the bytes */ 161 | /* this will add a null and pad out to a multiple of 8 bytes */ 162 | 163 | /* we do not care about overflow because the buffer is 8 bytes too big */ 164 | 165 | if (state->doit) { 166 | state->data_buf[state->buf_pos++] = 0; 167 | #if ENABLE_DES 168 | state->data_buf[state->buf_pos++] = randint(256)-1; 169 | des_encrypt_write(f1, state); 170 | #else 171 | rand_encrypt_write(f1, state); 172 | #endif 173 | } 174 | }; 175 | ////////////////////////////////////////////////////////////////////// 176 | ////////////////////////////////////////////////////////////////////// 177 | ////////////////////////////////////////////////////////////////////// 178 | void encrypt_write (FILE *f1, encrypt_state *state, ntype line) 179 | { 180 | /* this is ment to encrypt ascii, when decrypting a null in the 181 | plaintext marks the end of the file. so, you can use it with 182 | binary data as long as there are no nulls! also, newlines are 183 | bad since decrypt breaks things into lines */ 184 | 185 | int i1; 186 | 187 | // printf("writeline: ***%s***\n", line); fflush(stdout); 188 | 189 | if (!(state->doit)) { 190 | fprintf(f1,"%s\n",line); 191 | } else { 192 | 193 | for (i1 = 0 ; line[i1] ; i1++) { 194 | state->data_buf[state->buf_pos++] = line[i1] ^ (randint(256)-1); 195 | 196 | if (state->buf_pos == ENCRYPT_STAT_BUF_SIZE) { 197 | #if ENABLE_DES 198 | des_encrypt_write(f1, state); 199 | #else 200 | rand_encrypt_write(f1, state); 201 | #endif 202 | } 203 | } 204 | 205 | state->data_buf[state->buf_pos++] = '\n' ^ (randint(256)-1); 206 | 207 | if (state->buf_pos == ENCRYPT_STAT_BUF_SIZE) { 208 | #if ENABLE_DES 209 | des_encrypt_write(f1, state); 210 | #else 211 | rand_encrypt_write(f1, state); 212 | #endif 213 | } 214 | } 215 | }; 216 | ////////////////////////////////////////////////////////////////////// 217 | ////////////////////////////////////////////////////////////////////// 218 | ////////////////////////////////////////////////////////////////////// 219 | void read_decrypt (FILE *f1, encrypt_state *state, ntype line,boolean *got_eof) 220 | { 221 | /* this is ment to decrypt ascii, a null in the plaintext marks the 222 | end of the file. so, you can use it with binary data as long as there 223 | are no nulls! (or newlines, since we break things into lines) */ 224 | 225 | int i1; 226 | byteint i2; 227 | boolean exit; 228 | 229 | line[0] = 0; 230 | 231 | if (!(state->doit)) { 232 | /* file is not encrypted */ 233 | 234 | if ((fgets(line, sizeof(ntype), f1)) == NULL) { 235 | *got_eof = true; 236 | //printf("Yikes! EOF on f1: %p\n",f1); fflush(stdout); 237 | } else { 238 | line[strlen(line)-1] = 0; /* strip newline */ 239 | } 240 | 241 | } else { 242 | 243 | if ((state->buf_size != 0) || (!state->got_eof)) { 244 | 245 | for (i1 = 0, exit = false ; (i1 < 1000) && !exit ; ) { 246 | if (state->buf_pos >= state->buf_size) { 247 | #if ENABLE_DES 248 | des_read_decrypt(f1, state); 249 | #else 250 | rand_read_decrypt(f1, state); 251 | #endif 252 | } 253 | 254 | if (state->buf_size == 0) { 255 | exit = true; 256 | i2 = 0; 257 | } else { 258 | i2 = state->data_buf[state->buf_pos++] ^ (randint(256)-1); 259 | 260 | if (i2 == 0) { 261 | /* end of file */ 262 | state->buf_size = 0; 263 | exit = true; 264 | } else if (i2 == '\n') { 265 | /* end of line */ 266 | exit = true; 267 | } else { 268 | line[i1++] = i2; 269 | } 270 | } 271 | 272 | } 273 | line[i1] = 0; 274 | 275 | if (state->buf_size == 0) { 276 | state->got_eof = true; 277 | *got_eof = true; 278 | } 279 | 280 | } 281 | } 282 | //printf("readline: ***%s***\n", line); fflush(stdout); 283 | }; 284 | ////////////////////////////////////////////////////////////////////// 285 | ////////////////////////////////////////////////////////////////////// 286 | ////////////////////////////////////////////////////////////////////// 287 | /* END FILE encrypt.c */ 288 | -------------------------------------------------------------------------------- /generate.h: -------------------------------------------------------------------------------- 1 | typedef struct coords 2 | { 3 | integer y; 4 | integer x; 5 | } coords; 6 | 7 | typedef struct river_deal 8 | { 9 | integer in1,in2,out; /*{ (keypad) directions; in is upstream }*/ 10 | integer flow; /*{ water flow out of this river spot }*/ 11 | integer pos; /*{ in array of s_l_type; if > num_left then }*/ 12 | /*{ spot is no longer available }*/ 13 | } river_deal; 14 | 15 | typedef struct s_l_type 16 | { 17 | coords loc; /*{ cross-ref back to river_deal }*/ 18 | boolean is_active; /*{ is still an unresolved river source}*/ 19 | } s_l_type; 20 | 21 | #define RIVER_SIZE_Y 10 22 | #define RIVER_SIZE_X 31 23 | #define RIVER_TOTAL_SIZE 310 24 | #define RIVER_SEGMENT_SIZE 6 25 | 26 | typedef struct river_args 27 | { 28 | river_deal gup[RIVER_SIZE_Y+1][RIVER_SIZE_X+1]; 29 | /*: array [1..RIVER_SIZE_Y] of array [1..RIVER_SIZE_X] of river_deal;*/ 30 | 31 | s_l_type s_list[RIVER_TOTAL_SIZE+1]; 32 | /*: array [1..RIVER_TOTAL_SIZE] of s_l_type;*/ 33 | 34 | integer max_wet; /*{ # of river or next-to-river }*/ 35 | integer num_left,s_l_top; 36 | coords river_mouth; 37 | 38 | } river_args; 39 | 40 | #define Gup a->gup 41 | #define S_list a->s_list 42 | #define Max_wet a->max_wet 43 | #define Num_left a->num_left 44 | #define S_l_top a->s_l_top 45 | #define River_mouth a->river_mouth 46 | 47 | /* end generate.h */ 48 | -------------------------------------------------------------------------------- /horse.h: -------------------------------------------------------------------------------- 1 | /* horse.h */ 2 | /* declarations for the horse racing module in the casino */ 3 | 4 | #define RACES_PER_DAY 10 5 | #define MAX_HORSE_NAMES 55 6 | 7 | typedef integer h_stat[MAX_HORSE_NAMES+1]; 8 | typedef vtype h_name[MAX_HORSE_NAMES+1]; 9 | typedef boolean h_bool[MAX_HORSE_NAMES+1]; 10 | typedef real statr[11]; 11 | 12 | extern void hr__game_horse(); 13 | 14 | /* END FILE horse.h */ 15 | -------------------------------------------------------------------------------- /imoria.h: -------------------------------------------------------------------------------- 1 | /* imoria.h */ 2 | /* include flies for all the modlues */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include /* for ftruncate, usleep */ 11 | 12 | /*#include */ 13 | #include "mtwist/mtwist.h" /* random number generation */ 14 | #include "patchlevel.h" 15 | #include "configure.h" 16 | #include "constants.h" 17 | #include "types.h" 18 | #include "pascal.h" 19 | #include "routines.h" 20 | #include "term.h" 21 | 22 | #include "debug.h" 23 | 24 | // moria.c includes the actual declarations of all the variables, 25 | // everything else just includes the extern stuff 26 | 27 | #ifdef __MORIA_C__ 28 | #include "values.h" 29 | #else 30 | #include "variables.h" 31 | #endif 32 | 33 | #define PSPELL(xx) (magic_spell[py.misc.pclass][(xx)]) 34 | #define PCLASS (class[py.misc.pclass]) 35 | #define PM (py.misc) 36 | #define PS (py.stat) 37 | #define PF (py.flags) 38 | 39 | /* END FILE imoria.h */ 40 | -------------------------------------------------------------------------------- /insurance.c: -------------------------------------------------------------------------------- 1 | /* insurance.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | ////////////////////////////////////////////////////////////////////// 6 | ////////////////////////////////////////////////////////////////////// 7 | ////////////////////////////////////////////////////////////////////// 8 | void bi__display_gold() 9 | { 10 | vtype out_val; 11 | 12 | sprintf(out_val,"Gold remaining : %ld",py.misc.money[TOTAL_]); 13 | prt(out_val,19,18); 14 | 15 | }; 16 | ////////////////////////////////////////////////////////////////////// 17 | void bi__display_commands() 18 | { 19 | prt("You may:",21,1); 20 | prt(" i) Insure an item. a) Insure all items.",22,1); 21 | prt(" e) Insure all equipment. p) Insure person.",23,1); 22 | prt("^R) Redraw the screen. Esc) Exit from building.",24,1); 23 | }; 24 | ////////////////////////////////////////////////////////////////////// 25 | void bi__display_store(vtype shop_owner) 26 | { 27 | clear_screen(); 28 | prt(shop_owner,4,10); 29 | prt("(Protects character against most system failures.)",7,15); 30 | bi__display_commands(); 31 | bi__display_gold(); 32 | }; 33 | ////////////////////////////////////////////////////////////////////// 34 | void bi__insure_all_items() 35 | { 36 | integer tot_cost,temp; 37 | treas_ptr ptr; 38 | boolean flag; 39 | string out, out2; 40 | 41 | tot_cost = 0; 42 | 43 | for(ptr = inventory_list ; (ptr != nil) ; ptr = ptr->next ) { 44 | if ((Insured_bit & ptr->data.flags2) == 0) { 45 | temp = abs(ptr->data.cost * ptr->data.number) / 40; 46 | if (temp < (MITHRIL_VALUE / 10)) { 47 | temp = (MITHRIL_VALUE / 10); 48 | } 49 | tot_cost += temp; 50 | } 51 | } 52 | 53 | if (tot_cost > 0) { 54 | 55 | flag = false; 56 | sprintf(out,"Do you wish to pay %s?",cost_str(tot_cost,out2)); 57 | 58 | if (get_yes_no(out)) { 59 | if ((py.misc.money[TOTAL_] * GOLD_VALUE) >= tot_cost) { 60 | subtract_money(tot_cost,true); 61 | flag = true; 62 | } else { 63 | msg_print("Get some more cash, you fool!"); 64 | } 65 | } 66 | 67 | if (flag) { 68 | for (ptr = inventory_list ; ptr != nil ; ptr = ptr->next) { 69 | ptr->data.flags2 |= Insured_bit; 70 | } 71 | bi__display_gold(); 72 | msg_print("Your inventory is now insured"); 73 | } 74 | } else { 75 | msg_print("You have no inventory that needs to be insured."); 76 | } 77 | }; 78 | ////////////////////////////////////////////////////////////////////// 79 | void bi__insure_item(vtype shop_owner) 80 | { 81 | treas_ptr ptr; 82 | integer count,temp; 83 | boolean redraw,flag; 84 | string out, out2; 85 | vtype out_val; 86 | char trash_char; 87 | 88 | count = 0; 89 | change_all_ok_stats(false,false); 90 | ptr = inventory_list; 91 | 92 | for ( ; ptr != nil ; ptr = ptr->next) { 93 | if ((ptr->data.flags2 & Insured_bit) == 0) { 94 | ptr->ok = true; 95 | count++; 96 | } 97 | } 98 | 99 | if (count > 0) { 100 | if (get_item(&ptr,"Insure which item?",&redraw,count,&trash_char,false,false)) { 101 | temp = (int)(abs(ptr->data.cost * ptr->data.number) / 40); 102 | if (temp < (MITHRIL_VALUE div 10)) { 103 | temp = (MITHRIL_VALUE div 10); 104 | } 105 | 106 | flag = false; 107 | sprintf(out,"Do you wish to pay %s?",cost_str(temp,out2)); 108 | if (get_yes_no(out)) { 109 | if ((py.misc.money[TOTAL_] * GOLD_VALUE) >= temp) { 110 | subtract_money(temp,true); 111 | flag = true; 112 | } else { 113 | msg_print("Why don't you try again when you have more cash?"); 114 | } 115 | } 116 | 117 | if (flag) { 118 | ptr->data.flags2 |= Insured_bit; 119 | bi__display_store(shop_owner); 120 | objdes(out_val,ptr,true); 121 | if (ptr->data.number > 1) { 122 | sprintf(out,"Your %s are now insured", out_val); 123 | msg_print(out); 124 | } else { 125 | sprintf(out,"Your %s is now insured", out_val); 126 | msg_print(out); 127 | } 128 | } 129 | } else { 130 | bi__display_store(shop_owner); 131 | } 132 | } else { 133 | msg_print("None of your items need insurance"); 134 | } 135 | }; 136 | ////////////////////////////////////////////////////////////////////// 137 | real bi__death_adj() 138 | { 139 | /* Returns the rate to rape the character at for insurance, 140 | based on the number of times they have been restored in the past. 141 | Change this after seeing how bad ppl get screwed -DMF- */ 142 | 143 | real temp; 144 | 145 | //with py.misc do; 146 | PM.premium = PM.exp; 147 | if (PM.premium < 100) { 148 | PM.premium = 100; 149 | } 150 | temp = 100 * sqrt(PM.premium) + PM.premium * PM.deaths; 151 | PM.premium = (int)(temp); 152 | 153 | return temp; 154 | }; 155 | ////////////////////////////////////////////////////////////////////// 156 | void bi__insure_person() 157 | { 158 | integer tot_cost; 159 | boolean flag; 160 | string out, out2; 161 | 162 | if (py.flags.insured) { 163 | msg_print("Your person is already insured."); 164 | } else if (py.misc.deaths > 7) { 165 | msg_print("You are deemed a security risk. We will not insure you."); 166 | } else { 167 | tot_cost = (int)(bi__death_adj()); 168 | if (tot_cost < (2*MITHRIL_VALUE)) { 169 | tot_cost = (2*MITHRIL_VALUE); 170 | } 171 | 172 | flag = false; 173 | sprintf(out,"Do you wish to pay %s?",cost_str(tot_cost,out2)); 174 | if (get_yes_no(out)) { 175 | if ((py.misc.money[TOTAL_] * GOLD_VALUE) >= tot_cost) { 176 | subtract_money(tot_cost,true); 177 | flag = true; 178 | } else { 179 | msg_print("Nope, not enough cash with you."); 180 | } 181 | } 182 | 183 | if (flag) { 184 | bi__display_gold(); 185 | py.flags.insured = true; 186 | msg_print("Your person is now insured"); 187 | } 188 | } 189 | }; 190 | ////////////////////////////////////////////////////////////////////// 191 | void bi__insure_all_equip() 192 | { 193 | integer i1,tot_cost,temp; 194 | boolean flag; 195 | string out, out2; 196 | 197 | tot_cost = 0; 198 | for (i1 = Equipment_min; i1 < EQUIP_MAX; i1++) { 199 | //with equipment[i1]. do; 200 | if (equipment[i1].tval > 0) { 201 | if ((Insured_bit & equipment[i1].flags2) == 0) { 202 | temp = (int)(abs(equipment[i1].cost * equipment[i1].number) / 40); 203 | if (temp < (MITHRIL_VALUE div 10)) { 204 | temp = (MITHRIL_VALUE div 10); 205 | } 206 | tot_cost += temp; 207 | } 208 | } 209 | } 210 | 211 | 212 | if (tot_cost > 0) { 213 | flag = false; 214 | sprintf(out,"Do you wish to pay %s?",cost_str(tot_cost,out2)); 215 | 216 | if (get_yes_no(out)) { 217 | if ((py.misc.money[TOTAL_] * GOLD_VALUE) >= tot_cost) { 218 | subtract_money(tot_cost,true); 219 | flag = true; 220 | } else { 221 | msg_print("You don't have enough money with you. Maybe you should make a withdrawal."); 222 | } 223 | } 224 | 225 | if (flag) { 226 | for (i1 = Equipment_min; i1 < EQUIP_MAX; i1++) { 227 | //with equipment[i1]. do; 228 | if (equipment[i1].tval > 0) { 229 | equipment[i1].flags2 |= Insured_bit; 230 | } 231 | } 232 | bi__display_gold(); 233 | msg_print("Your equipment is now insured"); 234 | } 235 | } else { 236 | msg_print("You have no equipment that needs to be insured."); 237 | } 238 | }; 239 | ////////////////////////////////////////////////////////////////////// 240 | void bi__parse_command(boolean *exit_flag, vtype shop_owner) 241 | { 242 | char command; 243 | 244 | if (get_com("", &command)) { 245 | switch (command) { 246 | case 18 : 247 | bi__display_store(shop_owner); 248 | break; 249 | 250 | case 112 : 251 | bi__insure_person(); 252 | break; 253 | 254 | case 97 : 255 | if (py.flags.insured) { 256 | bi__insure_all_items(); 257 | } else { 258 | prt("Insure your body first.",1,1); 259 | } 260 | break; 261 | 262 | case 105 : 263 | if (py.flags.insured) { 264 | bi__insure_item(shop_owner); 265 | } else { 266 | prt("Insure your body first.",1,1); 267 | } 268 | break; 269 | 270 | case 101 : 271 | if (py.flags.insured) { 272 | bi__insure_all_equip(); 273 | } else { 274 | prt("Insure your body first.",1,1); 275 | } 276 | break; 277 | 278 | default : 279 | prt("Invalid Command.",1,1); break; 280 | } 281 | } else { 282 | *exit_flag = true; 283 | } 284 | }; 285 | ////////////////////////////////////////////////////////////////////// 286 | void buy_insurance() 287 | { 288 | boolean exit_flag = false; 289 | vtype shop_owner; 290 | integer tics = 1; 291 | integer starting_money; 292 | 293 | starting_money = PM.money[TOTAL_]; 294 | 295 | if (py.misc.max_exp > 30+randint(30)) { 296 | 297 | strcpy(shop_owner,"Mangy Dragon Flye (Scum) Insurance"); 298 | bi__display_store(shop_owner); 299 | 300 | do { 301 | bi__parse_command(&exit_flag, shop_owner); 302 | adv_time(false); 303 | tics++; 304 | check_kickout_time(tics,2); 305 | } while (!exit_flag); 306 | 307 | clear_screen(); 308 | draw_cave(); 309 | if (PM.money[TOTAL_] != starting_money) { 310 | msg_print("Be sure to save your character for your insurance to begin."); 311 | } 312 | 313 | } else { 314 | msg_print("Hmmmm... come back when you are a bit older."); 315 | } 316 | 317 | }; 318 | ////////////////////////////////////////////////////////////////////// 319 | ////////////////////////////////////////////////////////////////////// 320 | ////////////////////////////////////////////////////////////////////// 321 | 322 | 323 | /* END FILE insurance.c */ 324 | -------------------------------------------------------------------------------- /magic.c: -------------------------------------------------------------------------------- 1 | /* magic.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "dungeon.h" 6 | 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | ////////////////////////////////////////////////////////////////////// 10 | void c__mage_spell_effects(integer effect) 11 | { 12 | /*{ Spells... }*/ 13 | 14 | integer i2,dir; 15 | integer dumy,y_dumy,x_dumy; 16 | 17 | y_dumy = char_row; 18 | x_dumy = char_col; 19 | 20 | switch (effect+1) { 21 | 22 | case 1 : /*{ Magic Missile }*/ 23 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 24 | fire_bolt(0,dir,char_row,char_col, 25 | damroll("2d6")+1,"Magic Missile"); 26 | } 27 | break; 28 | 29 | case 2 : /*{ Detect Monster }*/ 30 | detect_creatures(c_monster); 31 | break; 32 | 33 | case 3 : /*{ Phase Door }*/ 34 | teleport(10); 35 | break; 36 | 37 | case 4 : /*{ Light }*/ 38 | light_area(char_row,char_col); 39 | break; 40 | 41 | case 5 : /*{ Cure Light }*/ 42 | hp_player(damroll("4d4"),"a magic spell."); 43 | break; 44 | 45 | case 6 : /*{ Find Hidden Traps/Door }*/ 46 | detect_sdoor(); 47 | detect_trap(); 48 | break; 49 | 50 | case 7 : /*{ Stinking Cloud }*/ 51 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 52 | fire_ball(c_gas,dir,char_row,char_col,9,"Stinking Cloud"); 53 | } 54 | break; 55 | 56 | case 8 : /*{ Confuse Monster }*/ 57 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 58 | zap_monster(dir,char_row,char_col,0,c_confuse); 59 | } 60 | break; 61 | 62 | case 9 : /*{ Lightning Bolt }*/ 63 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 64 | fire_bolt(c_lightning,dir,char_row,char_col, 65 | damroll("3d8")+1,"Lightning Bolt"); 66 | } 67 | break; 68 | 69 | case 10 : /*{ Trap/Door Destruction }*/ 70 | td_destroy(); 71 | break; 72 | 73 | case 11 : /*{ Sleep I }*/ 74 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 75 | zap_monster(dir,char_row,char_col,0,c_sleep); 76 | } 77 | break; 78 | 79 | case 12 : /*{ Cure Poison }*/ 80 | cure_me(&(py.flags.poisoned)); 81 | break; 82 | 83 | case 13 : /*{ Shadow Door }*/ 84 | teleport(py.misc.lev*5); 85 | break; 86 | 87 | case 14 : /*{ Remove Curse }*/ 88 | for (i2 = Equipment_min ; i2 <= EQUIP_MAX-1 ; i2++) { 89 | //with equipment[i2] do; 90 | equipment[i2].flags &= 0x7FFFFFFF; 91 | } 92 | break; 93 | 94 | case 15 : /*{ Frost Bolt }*/ 95 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 96 | fire_bolt(c_cold,dir,char_row,char_col, 97 | damroll("4d8")+1,"Frost Bolt"); 98 | } 99 | break; 100 | 101 | case 16 : /*{ Create Food }*/ 102 | create_food(7,7,0,0,0); 103 | break; 104 | 105 | case 17 : /*{ Infravision }*/ 106 | py.flags.tim_infra += 50 + randint(50); 107 | break; 108 | 109 | case 18 : /*{ Invisibility }*/ 110 | py.flags.temp_stealth += randint(15)+10; 111 | break; 112 | 113 | case 19 : /*{ Turn Stone to Mud }*/ 114 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 115 | wall_to_mud(dir,char_row,char_col); 116 | } 117 | break; 118 | 119 | case 20 : /*{ Recharge Item I }*/ 120 | recharge(20); 121 | break; 122 | 123 | case 21 : /*{ Sleep II }*/ 124 | sleep_monsters1(char_row,char_col); 125 | break; 126 | 127 | case 22 : /*{ Phantasmal Force }*/ 128 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 129 | fire_bolt(c_illusion,dir,char_row,char_col,damroll("8d4"), 130 | "phantasmal force"); 131 | } 132 | break; 133 | 134 | case 23 : /*{ Polymorph Other }*/ 135 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 136 | poly_monster(dir,char_row,char_col); 137 | } 138 | break; 139 | 140 | case 24 : /*{ Identify }*/ 141 | ident_spell(); 142 | break; 143 | 144 | case 25 : /*{ Ring of Frost }*/ 145 | py.flags.ring_ice += 3 + randint(3); 146 | break; 147 | 148 | case 26 : /*{ Sleep III }*/ 149 | zap_area(0,0,c_sleep); 150 | break; 151 | 152 | case 27 : /*{ Hold Monster }*/ 153 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 154 | zap_monster(dir,char_row,char_col,4+randint(4),c_hold); 155 | } 156 | break; 157 | 158 | case 28 : /*{ Fire Bolt }*/ 159 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 160 | fire_bolt(c_fire,dir,char_row,char_col, 161 | damroll("6d8")+1,"Fire Bolt"); 162 | } 163 | break; 164 | 165 | case 29 : /*{ Slow Creature }*/ 166 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 167 | zap_monster(dir,char_row,char_col,-1,c_speed); 168 | } 169 | break; 170 | 171 | case 30 : /*{ Protection From Magic }*/ 172 | py.flags.magic_prot += 20 + randint(20); 173 | break; 174 | 175 | case 31 : /*{ Frost Ball }*/ 176 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 177 | fire_ball(c_cold,dir,char_row,char_col,40,"Frost Ball"); 178 | } 179 | break; 180 | 181 | case 32 : /*{ Death Spell }*/ 182 | zap_area(0,py.misc.lev div 2+damroll("4d8"),c_drain); 183 | break; 184 | 185 | case 33 : /*{ Ring of Fire }*/ 186 | py.flags.ring_fire += 3 + randint(3); 187 | break; 188 | 189 | case 34 : /*{ Recharge Item II }*/ 190 | recharge(50); 191 | break; 192 | 193 | case 35 : /*{ Teleport Other }*/ 194 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 195 | teleport_monster(dir,char_row,char_col); 196 | } 197 | break; 198 | 199 | case 36 : /*{ Haste Self }*/ 200 | PF.fast += randint(20) + py.misc.lev; 201 | break; 202 | 203 | case 37 : /*{ Fire Ball }*/ 204 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 205 | fire_ball(c_fire,dir,char_row,char_col,59,"Fire Ball"); 206 | } 207 | break; 208 | 209 | case 38 : /*{ Power Word: Destruction }*/ 210 | destroy_area(char_row,char_col); 211 | break; 212 | 213 | case 39 : /*{ Power Word: Kill }*/ 214 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 215 | fire_bolt(0,dir,char_row,char_col, 216 | damroll("24d8"),"Black Bolt"); 217 | } 218 | break; 219 | 220 | case 40 : /*{ Genocide }*/ 221 | genocide(); 222 | break; 223 | 224 | default: 225 | break; 226 | } 227 | /*{ End of spells... }*/ 228 | 229 | }; 230 | ////////////////////////////////////////////////////////////////////// 231 | 232 | 233 | void cast() 234 | { 235 | /*{ Throw a magic spell -RAK- }*/ 236 | 237 | treas_ptr i1,item_ptr; 238 | integer choice,chance,i2; 239 | char trash_char; 240 | boolean redraw; 241 | obj_set magic_books = {Magic_Book, 0}; 242 | 243 | reset_flag = true; 244 | if (py.flags.blind > 0) { 245 | msg_print("You can't see to read your spell book!"); 246 | } else if (no_light()) { 247 | msg_print("You have no light to read by."); 248 | } else if (py.flags.confused > 0) { 249 | msg_print("You are too confused..."); 250 | } else if (class[py.misc.pclass].mspell) { 251 | if (inven_ctr > 0) { 252 | if (find_range(magic_books,false,&i1,&i2)) { 253 | redraw = false; 254 | if (get_item(&item_ptr,"Use which spell-book?",&redraw, 255 | i2,&trash_char,false,false)) { 256 | 257 | if (cast_spell("Cast which spell?",item_ptr, 258 | &choice,&chance,&redraw)) { 259 | 260 | //with magic_spell[py.misc.pclass,choice] do; 261 | reset_flag = false; 262 | if (randint(100) < chance) { 263 | msg_print("You failed to get the spell off!"); 264 | } else { 265 | c__mage_spell_effects(choice); 266 | if (!(reset_flag)) { 267 | //with py.misc do; 268 | PM.exp += magic_spell[PM.pclass][choice].sexp; 269 | prt_experience(); 270 | magic_spell[PM.pclass][choice].sexp = 0; 271 | } 272 | } 273 | 274 | //with py.misc do; 275 | if (!(reset_flag)) { 276 | if (magic_spell[PM.pclass][choice].smana > PM.cmana) { 277 | msg_print("You faint from the effort!"); 278 | py.flags.paralysis = 279 | randint(5*trunc(magic_spell[PM.pclass][choice].smana-PM.cmana)); 280 | PM.cmana = 0; 281 | if (randint(3) == 1) { 282 | /*{lower_stat == no sustain}*/ 283 | lower_stat(CON,"You have damaged your health!"); 284 | } 285 | } else { 286 | PM.cmana -= magic_spell[PM.pclass][choice].smana; 287 | } 288 | prt_mana(); 289 | } 290 | } /* end if which spell */ 291 | 292 | } else { 293 | if (redraw) { 294 | draw_cave(); 295 | } 296 | } 297 | } else { 298 | msg_print("But you are not carrying any spell-books!"); 299 | } 300 | } else { 301 | msg_print("But you are not carrying any spell-books!"); 302 | } 303 | } else { 304 | msg_print("You can't cast spells!"); 305 | } 306 | }; 307 | 308 | /* END FILE magic.c */ 309 | ////////////////////////////////////////////////////////////////////// 310 | ////////////////////////////////////////////////////////////////////// 311 | ////////////////////////////////////////////////////////////////////// 312 | -------------------------------------------------------------------------------- /master.c: -------------------------------------------------------------------------------- 1 | /* master.c */ 2 | /* routines to handle the master file, which keeps track of save files */ 3 | 4 | #include "imoria.h" 5 | #include "master.h" 6 | 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | ////////////////////////////////////////////////////////////////////// 10 | boolean master_file_open(GDBM_FILE *mf) 11 | { 12 | /* open the master file db, returns true on success */ 13 | 14 | int trys; 15 | 16 | *mf = NULL; 17 | for (trys = 0 ; (trys < 10) && (*mf == NULL) ; trys++) { 18 | priv_switch(1); 19 | *mf = gdbm_open(MORIA_MAS, 1024, GDBM_WRCREAT, 0, 0); 20 | priv_switch(0); 21 | if ((*mf == NULL)) { 22 | sleep(1); 23 | } 24 | } 25 | 26 | return (*mf != NULL); 27 | }; 28 | ////////////////////////////////////////////////////////////////////// 29 | ////////////////////////////////////////////////////////////////////// 30 | ////////////////////////////////////////////////////////////////////// 31 | void master_file_close(GDBM_FILE *mf) 32 | { 33 | /* save changes and close the master file db */ 34 | 35 | if (*mf != NULL) { 36 | gdbm_close(*mf); 37 | *mf = NULL; 38 | } 39 | }; 40 | ////////////////////////////////////////////////////////////////////// 41 | ////////////////////////////////////////////////////////////////////// 42 | ////////////////////////////////////////////////////////////////////// 43 | boolean master_file_read(GDBM_FILE mf, master_key *mkey, master_entry *mentry) 44 | { 45 | /* fetch a db entry, returns true if the entry was found */ 46 | 47 | boolean return_value = false; 48 | datum key, data; 49 | 50 | key.dptr = (char *)mkey; 51 | key.dsize = sizeof(master_key); 52 | 53 | if (mf != NULL) { 54 | data = gdbm_fetch(mf, key); 55 | 56 | if (data.dptr != NULL) { 57 | /* Will read from data that is bigger than expected, but not smaller. */ 58 | /* If more data is added to entries without fixing the database then */ 59 | /* handle that case here! */ 60 | if (data.dsize >= sizeof(master_entry)) { 61 | memcpy(mentry, data.dptr, sizeof(master_entry)); 62 | return_value = true; 63 | } 64 | free(data.dptr); 65 | } 66 | } else { 67 | /* no open db file, that isn't good */ 68 | } 69 | return return_value; 70 | }; 71 | ////////////////////////////////////////////////////////////////////// 72 | ////////////////////////////////////////////////////////////////////// 73 | ////////////////////////////////////////////////////////////////////// 74 | boolean master_file_write(GDBM_FILE mf, master_key *mkey, master_entry *mentry) 75 | { 76 | datum key, data; 77 | int result; 78 | 79 | key.dptr = (char *)mkey; 80 | key.dsize = sizeof(master_key); 81 | data.dptr = (char *)mentry; 82 | data.dsize = sizeof(master_entry); 83 | 84 | if (mf != NULL) { 85 | mentry->updated = time(0); 86 | result = gdbm_store(mf, key, data, GDBM_REPLACE); 87 | } 88 | 89 | return true; 90 | }; 91 | ////////////////////////////////////////////////////////////////////// 92 | ////////////////////////////////////////////////////////////////////// 93 | ////////////////////////////////////////////////////////////////////// 94 | boolean master_file_delete(GDBM_FILE mf, master_key *mkey) 95 | { 96 | datum key; 97 | int result = -1; 98 | 99 | key.dptr = (char *)mkey; 100 | key.dsize = sizeof(master_key); 101 | 102 | if (mf != NULL) { 103 | result = gdbm_delete(mf, key); /* 0 if deleted, -1 if not found */ 104 | } 105 | 106 | return (result == 0) ? true : false; 107 | }; 108 | ////////////////////////////////////////////////////////////////////// 109 | ////////////////////////////////////////////////////////////////////// 110 | ////////////////////////////////////////////////////////////////////// 111 | int master_file_verify(GDBM_FILE mf, master_key *mkey) 112 | { 113 | boolean foundit; 114 | master_entry mentry; 115 | int return_value = MF_CHAR_NOT_FOUND; 116 | 117 | if (mf != NULL) { 118 | foundit = master_file_read(mf, mkey, &mentry); 119 | 120 | if (foundit) { 121 | if (py.misc.save_count == mentry.save_count) { 122 | return_value = MF_CHAR_OK; 123 | } else { 124 | return_value = MF_CHAR_MISMATCH; 125 | } 126 | } 127 | } 128 | 129 | // if (return_value != MF_CHAR_OK) { 130 | // msg_print("Verify mismatch."); 131 | // msg_print(" "); 132 | // } 133 | 134 | return return_value; 135 | }; 136 | ////////////////////////////////////////////////////////////////////// 137 | ////////////////////////////////////////////////////////////////////// 138 | ////////////////////////////////////////////////////////////////////// 139 | boolean master_file_write_new(GDBM_FILE mf, master_key *mkey, 140 | master_entry *mentry) 141 | { 142 | /* insert a new key, if key already exists then try new keys for a while */ 143 | 144 | int trys; 145 | datum key; 146 | boolean return_value = false; 147 | 148 | key.dptr = (char *)mkey; 149 | key.dsize = sizeof(master_key); 150 | 151 | if (mf != NULL) { 152 | for (trys = 0 ; (trys < 500) && !return_value ; trys++) { 153 | if (!gdbm_exists(mf, key)) { 154 | master_file_write(mf, mkey, mentry); 155 | return_value = true; 156 | } else { 157 | mkey->creation_time += randint(40); 158 | } 159 | } 160 | } 161 | 162 | return return_value; 163 | }; 164 | ////////////////////////////////////////////////////////////////////// 165 | ////////////////////////////////////////////////////////////////////// 166 | ////////////////////////////////////////////////////////////////////// 167 | /* END FILE master.c */ 168 | -------------------------------------------------------------------------------- /master.h: -------------------------------------------------------------------------------- 1 | /* master.h */ 2 | /* routines to handle the master file, which keeps track of save files */ 3 | ////////////////////////////////////////////////////////////////////// 4 | ////////////////////////////////////////////////////////////////////// 5 | ////////////////////////////////////////////////////////////////////// 6 | 7 | #include 8 | 9 | extern boolean master_file_open(GDBM_FILE *mf); 10 | extern void master_file_close(GDBM_FILE *mf); 11 | extern boolean master_file_read(GDBM_FILE mf, master_key *mkey, 12 | master_entry *mentry); 13 | extern boolean master_file_write(GDBM_FILE mf, master_key *mkey, 14 | master_entry *mentry); 15 | extern boolean master_file_write_new(GDBM_FILE mf, master_key *mkey, 16 | master_entry *mentry); 17 | extern boolean master_file_delete(GDBM_FILE mf, master_key *mkey); 18 | extern int master_file_verify(GDBM_FILE mf, master_key *mkey); 19 | 20 | ////////////////////////////////////////////////////////////////////// 21 | ////////////////////////////////////////////////////////////////////// 22 | ////////////////////////////////////////////////////////////////////// 23 | /* END FILE master.h */ 24 | -------------------------------------------------------------------------------- /monk.c: -------------------------------------------------------------------------------- 1 | /* monk.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "dungeon.h" 6 | ////////////////////////////////////////////////////////////////////// 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | 10 | void d__monk_effects(integer effect) 11 | { 12 | /*{ Disciplines....}*/ 13 | switch (effect+1) { 14 | 15 | case 1 : /*{ Self-Healing }*/ 16 | hp_player(damroll("4d4"),"a magic spell."); 17 | break; 18 | 19 | 20 | case 2 : /*{ Courage } */ 21 | cure_me(&py.flags.afraid); 22 | break; 23 | 24 | 25 | case 3 : /*{ Slow Poison } */ 26 | slow_poison(); 27 | break; 28 | 29 | 30 | case 4 : /*{ Negate Hunger } */ 31 | py.flags.foodc = PLAYER_FOOD_FULL + 4000; 32 | py.flags.status &= ~(IS_HUNGERY | IS_WEAK); 33 | prt_hunger(); 34 | msg_print("You are full."); 35 | break; 36 | 37 | 38 | case 5 : /*{ Sense Enemies }*/ 39 | detect_creatures(c_creature); 40 | break; 41 | 42 | 43 | case 6 : /*{ Self-Healing II } */ 44 | hp_player(damroll("8d4"),"a prayer."); 45 | break; 46 | 47 | 48 | case 7 : /*{ Night Vision }*/ 49 | py.flags.tim_infra += randint(25) + 25; 50 | break; 51 | 52 | 53 | case 8 : /*{ Poison Immunity }*/ 54 | cure_me(&(py.flags.poisoned)); 55 | break; 56 | 57 | 58 | case 9 : /*{ See Invisible } */ 59 | detect_inv2(randint(24)+24); 60 | break; 61 | 62 | 63 | case 10 : /*{ Advanced Self-Healing } */ 64 | hp_player(damroll("16d4"),"a prayer."); 65 | break; 66 | 67 | 68 | case 11 : /*{ Resist Petrification }*/ 69 | py.flags.resist_petri += randint(15) + 10; 70 | break; 71 | 72 | 73 | case 12 : /*{ Stealth }*/ 74 | py.flags.temp_stealth += randint(15)+10; 75 | break; 76 | 77 | 78 | case 13 : /*{ Free Action } */ 79 | py.flags.free_time += (randint(10) + py.misc.lev); 80 | break; 81 | 82 | 83 | case 14 : /*{ Improved Speed }*/ 84 | PF.fast += randint(20) + py.misc.lev; 85 | break; 86 | 87 | default: 88 | break; 89 | } 90 | /*{ End of Disciplines...}*/ 91 | }; 92 | ////////////////////////////////////////////////////////////////////// 93 | 94 | void discipline() 95 | { 96 | /*{ Use a monk's mental discipline. . . . -RAD- }*/ 97 | integer i2; 98 | integer choice,chance; 99 | integer y_dumy,x_dumy; 100 | boolean redraw; 101 | boolean flag; 102 | 103 | redraw = false; 104 | reset_flag = true; 105 | if (py.flags.confused > 0) { 106 | msg_print("You are too confused to concentrate...."); 107 | } else if (py.flags.image > 0) { 108 | msg_print("Colors and images run through your head, distracting you."); 109 | } else { 110 | flag = false; 111 | for (i2=0 ; (i2 < 40) && !flag ; i2++) { 112 | if (magic_spell[py.misc.pclass][i2].learned) { 113 | flag = true; 114 | } 115 | } 116 | 117 | if (flag) { 118 | inven_temp->data = monk_book; 119 | if (cast_spell("Use which discipline?",inven_temp, 120 | &choice,&chance,&redraw)) { 121 | //with magic_spell[py.misc.pclass][choice]. do; 122 | reset_flag = false; 123 | if (randint(100) < chance) { 124 | msg_print("You lost your concentration!"); 125 | } else { 126 | 127 | y_dumy = char_row; 128 | x_dumy = char_col; 129 | d__monk_effects(choice); 130 | if (!reset_flag) { 131 | //with py.misc do; 132 | PM.exp += magic_spell[py.misc.pclass][choice].sexp; 133 | prt_experience(); 134 | magic_spell[py.misc.pclass][choice].sexp = 0; 135 | } 136 | } 137 | //with py.misc do; 138 | if (!reset_flag) { 139 | if (magic_spell[py.misc.pclass][choice].smana > PM.cmana) { 140 | msg_print("You are distracted by the effort!"); 141 | py.flags.paralysis = 142 | randint(5*trunc(magic_spell[py.misc.pclass][choice].smana-PM.cmana)); 143 | PM.cmana = 0; 144 | } else { 145 | PM.cmana -= magic_spell[py.misc.pclass][choice].smana; 146 | } 147 | prt_mana(); 148 | } 149 | 150 | } else { 151 | erase_line(1,1); 152 | } 153 | } else { 154 | msg_print("You don't know any disciplines!"); 155 | } 156 | } 157 | } 158 | /* END FILE monk.c */ 159 | ////////////////////////////////////////////////////////////////////// 160 | ////////////////////////////////////////////////////////////////////// 161 | ////////////////////////////////////////////////////////////////////// 162 | -------------------------------------------------------------------------------- /monsters.c: -------------------------------------------------------------------------------- 1 | /* monsters.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | 6 | ////////////////////////////////////////////////////////////////////// 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | void place_monster(integer y,integer x,integer z, boolean slp) 10 | { 11 | /*{ Places a monster at given location -RAK- }*/ 12 | 13 | integer cur_pos; 14 | 15 | // printf ("\n Enter place_monster: %d (%d,%d)",z,x,y); fflush(stdout); 16 | 17 | popm(&cur_pos); 18 | 19 | // printf ("\n got cur_pos: %d",cur_pos); fflush(stdout); 20 | 21 | //with m_list[cur_pos] do; 22 | m_list[cur_pos].fy = y; 23 | m_list[cur_pos].fx = x; 24 | m_list[cur_pos].mptr = z; 25 | m_list[cur_pos].nptr = muptr; 26 | muptr = cur_pos; 27 | 28 | if ((c_list[z].cdefense & 0x4000) != 0) { 29 | m_list[cur_pos].hp = max_hp(c_list[z].hd); 30 | } else { 31 | m_list[cur_pos].hp = damroll(c_list[z].hd); 32 | } 33 | // printf ("\n hp: %d)",m_list[cur_pos].hp); fflush(stdout); 34 | 35 | m_list[cur_pos].cdis = distance(char_row,char_col,y,x); 36 | // printf ("\n cdis: %d)",m_list[cur_pos].cdis); fflush(stdout); 37 | m_list[cur_pos].cspeed = c_list[z].speed + py.flags.speed; 38 | m_list[cur_pos].stunned = 0; 39 | 40 | if (slp) { 41 | // printf ("\n set sleep: %d",c_list[z].sleep); fflush(stdout); 42 | m_list[cur_pos].csleep = (c_list[z].sleep/5.0)+randint(c_list[z].sleep); 43 | // printf ("\n sleep: %d",m_list[cur_pos].csleep); fflush(stdout); 44 | } else { 45 | // printf ("\n set no sleep:"); fflush(stdout); 46 | m_list[cur_pos].csleep = 0; 47 | } 48 | 49 | cave[y][x].cptr = cur_pos; 50 | 51 | // printf ("\n Exit place_monster: %d (%d,%d)",z,x,y); fflush(stdout); 52 | }; 53 | ////////////////////////////////////////////////////////////////////// 54 | ////////////////////////////////////////////////////////////////////// 55 | ////////////////////////////////////////////////////////////////////// 56 | void alloc_land_monster(obj_set alloc_set, integer num, integer dis, 57 | boolean slp, boolean water) 58 | { 59 | /*{ Allocates a random land monster -RAK- }*/ 60 | 61 | integer y,x,i1,i2,i3,count; 62 | integer count2; 63 | boolean flag; 64 | 65 | // printf ("\n Enter alloc land monster\n"); fflush(stdout); 66 | 67 | for (i1 = 0; i1 < num; i1++) { 68 | // printf ("\n Doing a monster"); fflush(stdout); 69 | flag = false; 70 | count = 0; 71 | count2 = 0; 72 | do { 73 | y = randint(cur_height-2)+1; 74 | x = randint(cur_width-2)+1; 75 | count2++; 76 | } while (!(((is_in(cave[y][x].fval, alloc_set)) && 77 | (cave[y][x].cptr == 0) && 78 | (cave[y][x].fopen) && 79 | (distance(y,x,char_row,char_col) > dis)) 80 | || (count2 > 7500))); 81 | 82 | // printf ("\n got me coords (%d, %d)",x,y); fflush(stdout); 83 | 84 | do { 85 | if (dun_level == 0) { 86 | //printf ("\n doing dun_level: %d",m_level[0]); fflush(stdout); 87 | i2 = randint(m_level[0]); 88 | } else if (dun_level > MAX_MONS_LEVEL) { 89 | i2 = randint(m_level[MAX_MONS_LEVEL]) + m_level[0]; 90 | } else if (randint(mon_nasty) == 1) { 91 | i2 = dun_level + abs(randnor(0,4)) + 1; 92 | if (i2 > MAX_MONS_LEVEL) { 93 | i2 = MAX_MONS_LEVEL; 94 | } 95 | i3 = m_level[i2] - m_level[i2-1]; 96 | i2 = randint(i3) + m_level[i2-1]; 97 | } else { 98 | i2 = randint(m_level[dun_level]) + m_level[0]; 99 | } 100 | 101 | // printf ("\n got me i2 (%d)",i2); fflush(stdout); 102 | 103 | if (!water) { 104 | flag = (((c_list[i2].cmove & 0x00008000) == 0) && 105 | (((c_list[i2].cmove & 0x00000010) == 0) || 106 | ((c_list[i2].cmove & 0x00000040) == 0) || 107 | ((c_list[i2].cmove & 0x00800000) != 0))) ; 108 | } else { 109 | flag = (((c_list[i2].cmove & 0x00008000) == 0) && 110 | ((c_list[i2].cmove & 0x00000010) != 0)); 111 | } 112 | 113 | // printf ("\n got me flag (%d)",flag); fflush(stdout); 114 | 115 | if (flag) { 116 | if (count2 < 7500) { 117 | // printf ("\n placing monster"); fflush(stdout); 118 | place_monster(y,x,i2,slp); 119 | flag = true; 120 | // printf ("\n placed monster"); fflush(stdout); 121 | } 122 | } 123 | 124 | 125 | count++; 126 | } while (!((flag) || (count > 10))); 127 | } /* end for */ 128 | 129 | // printf ("\n Exit alloc land monster\n"); fflush(stdout); 130 | }; 131 | ////////////////////////////////////////////////////////////////////// 132 | ////////////////////////////////////////////////////////////////////// 133 | ////////////////////////////////////////////////////////////////////// 134 | 135 | ////////////////////////////////////////////////////////////////////// 136 | ////////////////////////////////////////////////////////////////////// 137 | ////////////////////////////////////////////////////////////////////// 138 | 139 | /* END FILE monsters.c */ 140 | -------------------------------------------------------------------------------- /monsters.info: -------------------------------------------------------------------------------- 1 | /* 2 | { Creatures must be defined here } 3 | { See TYPES.INC under creature_type for a complete list 4 | of all variables for creatures. Some of the less obvious 5 | are explained below. 6 | 7 | Area of affect (aaf) : Max range that creature is able to "notice" 8 | the player. 9 | 10 | Armor Class (AC): difficulty to hit. 11 | 12 | CMOVE flags: 13 | Movement. 00000001 Move only to attack 14 | . 00000002 20% random movement 15 | . 00000004 40% random movement 16 | . 00000008 75% random movement 17 | . 00000010 On = Water-based; Off = Land-based 18 | . 00000040 Drowns/Suffocates in wrong element 19 | . 00000300 monster rate in wrong elm't (0=stop,3=full) 20 | Special + 00004000 Is a 'good' monster (reputation) 21 | + 00008000 Is a monster that will not normally appear 22 | (such as Town Guards) 23 | These can only be summoned by summon 24 | monster by name. 25 | + 00010000 Invisible movement 26 | + 00020000 Move through door 27 | + 00040000 Move through wall 28 | + 00080000 Move through creatures 29 | + 00100000 Picks up objects 30 | + 00200000 Multiply monster 31 | + 00400000 Can anchor in water 32 | + 00800000 Flying creature 33 | Carries = 01000000 Carries objects. 34 | = 02000000 Carries gold. 35 | = 04000000 Has 60% of time. 36 | = 08000000 Has 90% of time. 37 | = 10000000 1d2 objects/gold. 38 | = 20000000 2d2 objects/gold. 39 | = 40000000 4d2 objects/gold. 40 | Special ~ 80000000 Win-the-Game creature. 41 | 42 | SPELL Flags: 43 | Frequency 00000001 1 These add up to x. Then 44 | (1 in x). 00000002 2 if RANDINT(X) = 1 the 45 | . 00000004 4 creature casts a spell. 46 | . 00000008 8 47 | Spells = 00000010 Teleport short (blink) 48 | = 00000020 Teleport long 49 | = 00000040 Teleport player to monster 50 | = 00000080 Cause light wound 51 | = 00000100 Cause serious wound 52 | = 00000200 Hold person (Paralysis) 53 | = 00000400 Cause blindness 54 | = 00000800 Cause confusion 55 | = 00001000 Cause fear 56 | = 00002000 Summon monster 57 | = 00004000 Summon undead 58 | = 00008000 Slow Person 59 | = 00010000 Drain Mana 60 | = 00020000 Shadow Breath/Orb of Draining 61 | = 00040000 Not Used 62 | Breaths + 00080000 Breath Lightning 63 | + 00100000 Breath Gas 64 | + 00200000 Breath Acid 65 | + 00400000 Breath Frost 66 | + 00800000 Breath Fire 67 | = 01000000 Casts Illusion 68 | = 02000000 Summon Demon 69 | = 04000000 Summon Multiplying Monster (heh heh) 70 | = 08000000 Gaze from distance for petrification 71 | . 80000000 makes no casting 1 in x (instead of casting 1 in x) 72 | 73 | CDEFENSE flags: 74 | 0001 Hurt by Slay Dragon. 75 | 0002 Hurt by Slay Monster. 76 | 0004 Hurt by Slay Evil. 77 | 0008 Hurt by Slay Undead. 78 | 0010 Hurt by Frost. 79 | 0020 Hurt by Fire. 80 | 0040 Hurt by Poison. 81 | 0080 Hurt by Acid. 82 | 0100 Hurt by Light-Wand. 83 | 0200 Hurt by Stone-to-Mud. 84 | 0400 Hurt by Slay Demon. 85 | 0800 Not used. 86 | 1000 Cannot be charmed or slept. 87 | 2000 Can be seen with infra-vision. 88 | 4000 Max Hit points. 89 | 8000 Regenerates. 90 | 91 | Sleep (sleep) : A measure in turns of how fast creature 92 | will notice player (on the average). 93 | 94 | Experience : Base Experience for slaying the creature. 95 | 96 | Speed : Base Monster Speed. 97 | 98 | Character Rep. : The character used on the map. 99 | 100 | Hit points: '#1d#2' where #2 is the range of each roll and 101 | #1 is the number of added up rolls to make. 102 | Example: a creature with 5 eight-sided hit die 103 | is given '5d8'. 104 | 105 | Attack types: 106 | 1 Normal attack 107 | 2 Lose Strength 108 | 3 Confusion attack 109 | 4 Fear attack 110 | 5 Fire attack 111 | 6 Acid attack 112 | 7 Cold attack 113 | 8 Lightning attack 114 | 9 Corrosion attack 115 | 10 Blindness attack 116 | 11 Paralysis attack 117 | 12 Steal Money 118 | 13 Steal Object 119 | 14 Poison 120 | 15 Lose dexterity 121 | 16 Lose constitution 122 | 17 Lose intelligence 123 | 18 Lose wisdom 124 | 19 Lose experience 125 | 20 Aggravation 126 | 21 Disenchants 127 | 22 Eats food 128 | 23 Eats light 129 | 24 Eats charges 130 | 25 Lose charisma 131 | 26 Petrification 132 | 27 POISON poison 133 | 99 Blank 134 | 135 | Attack descriptions: 136 | 1 hits you. 137 | 2 bites you. 138 | 3 claws you. 139 | 4 stings you. 140 | 5 touches you. 141 | 6 kicks you. 142 | 7 gazes at you. 143 | 8 breathes on you. 144 | 9 spits on you. 145 | 10 makes a horrible wail. 146 | 11 embraces you. 147 | 12 crawls on you. 148 | 13 releases a cloud of spores. 149 | 14 begs you for money. 150 | 15 You've been slimed. 151 | 16 crushes you. 152 | 17 tramples you. 153 | 18 drools on you. 154 | 19 insults you. 155 | 23 plays a song. 156 | 24 kisses you. 157 | 25 gores you. 158 | 26 "bovine"s you. 159 | 27 electrocutes you. 160 | 28 inks you. 161 | 29 entangles you. 162 | 30 blood sucks you. 163 | 31 goes for your throat. 164 | 32 blows bubbles at you. 165 | 33 squawks at you. 166 | 34 pecks at you. 167 | 35 barks at you. 168 | 36 rubs against your leg. 169 | 99 is repelled. 170 | 171 | 172 | Example: For a creature which claws twice for 1d6, then stings for 173 | 2d4 and loss of dex you would use: 174 | '1 3 2-1d6|15 4 2d4' 175 | 176 | Level : Base level the creature is found on. 177 | 178 | moo.monst in dua2:[sa65] has bovine monsters } 179 | */ -------------------------------------------------------------------------------- /moria.c: -------------------------------------------------------------------------------- 1 | /* moria.c 2 | 3 | Port of imoria from VMS in pascal to linux in C. Joy. Here is the 4 | copyright notice from the sources I started with (although trying to 5 | maintain a copyright on something you put into the public domain seems 6 | wrong somehow): 7 | 8 | 9 | { Moria Version 4.8 COPYRIGHT (c) Robert Alan Koeneke } 10 | { Public Domain } 11 | { } 12 | { I lovingly dedicate this game to hackers and adventurers } 13 | { everywhere... } 14 | { } 15 | { } 16 | { Designer and Programmer : Robert Alan Koeneke } 17 | { University of Oklahoma } 18 | { } 19 | { Assitant Programmers : Jimmey Wayne Todd } 20 | { University of Oklahoma } 21 | { } 22 | { Gary D. McAdoo } 23 | { University of Oklahoma } 24 | { } 25 | { Moria may be copied and modified freely as long as the above } 26 | { credits are retained. No one who-so-ever may sell or market } 27 | { this software in any form without the expressed written consent } 28 | { of the author Robert Alan Koeneke. } 29 | { } 30 | */ 31 | 32 | #define __MORIA_C__ 33 | #include "imoria.h" 34 | 35 | /***********************************************************************/ 36 | 37 | int main(int argc, char *argv[], char *envp[]) 38 | { 39 | /*// { SYSPRV stays off except when needed... }*/ 40 | game_state = GS_LOADING; 41 | init_priv_switch(); 42 | priv_switch(0); 43 | 44 | ENTER("main", "") 45 | 46 | //init_signals(); 47 | 48 | // { Get the time player entered game } 49 | start_time = time(NULL); 50 | 51 | // { Get the directory location of the image } 52 | get_paths(); 53 | 54 | // { Here comes the monsters.... } 55 | load_monsters(); 56 | 57 | // { Check to see if an update is in progress -DMF- } 58 | if (check_kickout()) { 59 | writeln("Imoria is locked . . . Try playing conquest."); 60 | writeln("Who knows *how* long this might take?"); 61 | exit_game(); 62 | } 63 | 64 | // { Some necessary initializations } 65 | msg_line = 1; 66 | quart_height = trunc(SCREEN_HEIGHT/4); 67 | quart_width = trunc(SCREEN_WIDTH /4); 68 | dun_level = 0; 69 | inven_temp = (treas_ptr)safe_malloc(sizeof(treas_rec),"inven_temp"); 70 | inven_temp->data = blank_treasure; 71 | inven_temp->ok = false; 72 | inven_temp->insides = 0; 73 | inven_temp->next = nil; 74 | inven_temp->is_in = false; 75 | caught_message = nil; 76 | old_message = nil; 77 | old_mess_count = 0; 78 | turn_counter = 100000; 79 | 80 | // { Grab a random seed from the clock } 81 | seed = get_seed(); 82 | 83 | // { Sort the objects by level } 84 | sort_objects(); 85 | 86 | // { Init monster and treasure levels for allocate } 87 | init_m_level(); 88 | init_t_level(); 89 | 90 | // { Init the store inventories } 91 | store_init(); 92 | if (COST_ADJ != 1.00) price_adjust(); 93 | if (WEIGHT_ADJ != 1) item_weight_adjust(); 94 | bank_init(); 95 | 96 | // { Build the secret wizard and god passwords } 97 | bpswd(); 98 | 99 | // { Check operating hours } 100 | // { If not wizard then No_Control_Y } 101 | // { Check or create hours.dat, print message } 102 | intro(finam, argc, argv); 103 | 104 | // { Init an IO channel for QIO } 105 | /* init_channel(); */ 106 | 107 | clear_screen(); 108 | 109 | // { Generate a character, or retrieve old one... } 110 | if (strlen(finam) > 0) { 111 | // { Retrieve character } 112 | game_state = GS_IGNORE_CTRL_C; 113 | generate = get_char(finam,true); 114 | py.flags.dead = true; 115 | is_from_file = true; 116 | save_char(false); 117 | change_name(); 118 | magic_init(randes_seed); 119 | } else { 120 | // { Create character } 121 | is_from_file = false; 122 | strncpy(finam,"moriachar.sav",sizeof(vtype)); 123 | create_character(); 124 | 125 | char_inven_init(); 126 | 127 | if (class[py.misc.pclass].mspell) { 128 | // { Magic realm } 129 | learn_spell(&msg_flag); 130 | gain_mana(spell_adj(INT)); 131 | } else if (class[py.misc.pclass].pspell) { 132 | // { Clerical realm} 133 | learn_prayer(); 134 | gain_mana(spell_adj(WIS)); 135 | } else if (class[py.misc.pclass].dspell) { 136 | // { Druidical realm } 137 | learn_druid(); 138 | gain_mana(druid_adj()); 139 | } else if (class[py.misc.pclass].bspell) { 140 | // { Bardic realm } 141 | learn_song(&msg_flag); 142 | gain_mana(bard_adj()); 143 | } 144 | py.misc.cmana = py.misc.mana; 145 | randes_seed = seed; // { Description seed } 146 | town_seed = seed; // { Town generation seed } 147 | magic_init(randes_seed); 148 | generate = true; 149 | 150 | } /* end if (load/create character) */ 151 | 152 | if (py.misc.pclass == C_MONK) { 153 | strcpy(bare_hands, "2d2"); 154 | } 155 | 156 | if (class[py.misc.pclass].mspell || class[py.misc.pclass].pspell || 157 | class[py.misc.pclass].dspell || class[py.misc.pclass].bspell || 158 | class[py.misc.pclass].mental ) 159 | { 160 | is_magii = true; 161 | } else { 162 | is_magii = false; 163 | } 164 | 165 | // { Begin the game } 166 | replace_name(); 167 | set_gem_values(); 168 | 169 | set_difficulty(py.misc.diffic); // { Set difficulty of game } 170 | player_max_exp = (integer)(player_exp[MAX_PLAYER_LEVEL-1] 171 | * py.misc.expfact); 172 | clear_from(1); 173 | prt_stat_block(); 174 | 175 | // { Turn on message trapping, if requested } 176 | // if (want_trap) set_the_trap(); 177 | 178 | set_seed(get_seed()); 179 | 180 | // { Loop till dead, or exit } 181 | do { 182 | //generate = true; 183 | if (generate) generate_cave(); // { New level } 184 | dungeon(); // { Dungeon logic } 185 | generate = true; 186 | } while (!death); 187 | 188 | upon_death(); // { Character gets buried } 189 | 190 | LEAVE("main", "") 191 | return 0; 192 | } /* end main */ 193 | 194 | /***********************************************************************/ 195 | -------------------------------------------------------------------------------- /mtwist/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for ``Mersenne Twister'' 3 | # This was written for linux, it works on my system and may not do you any good 4 | # 5 | # redhat 5.0 likes this to be /usr/lib 6 | # my slackware wants it in /usr/local/lib 7 | # 8 | LIBDEST = /usr/local/lib 9 | #LIBDEST = /usr/lib 10 | CC = gcc 11 | 12 | # 13 | # version numbers, this becomes part of the library name: 14 | # libmtwist.so.. 15 | # 16 | MAJOR = 1 17 | MINOR = 0 18 | 19 | #COPTS = -Wall -O3 -g3 20 | COPTS = -Wall -O3 21 | #COPTS = -Wall 22 | #COPTS = -Wall -g3 23 | 24 | CFLAGS = $(COPTS) $(INCLUDES) $(DEFINES) 25 | LDFLAGS = 26 | 27 | all: obj lib 28 | 29 | # 30 | # Non shared library version 31 | # 32 | obj :: 33 | $(CC) $(CFLAGS) -c mt-optimized-cokus.c -o mtwist.o 34 | 35 | # 36 | # Library version 37 | # 38 | lib :: 39 | $(CC) $(CFLAGS) -fPIC -c mt-optimized-cokus.c -o mtwist-lib.o 40 | $(CC) -shared -Wl,-soname,libmtwist.so.$(MAJOR) -o libmtwist.so.$(MAJOR).$(MINOR) mtwist-lib.o 41 | 42 | install :: 43 | cp libmtwist.so.$(MAJOR).$(MINOR) $(LIBDEST)/libmtwist.so.$(MAJOR).$(MINOR) 44 | rm -f $(LIBDEST)/libmtwist.so.$(MAJOR) $(LIBDEST)/libmtwist.so 45 | /sbin/ldconfig 46 | ( cd $(LIBDEST) ; ln -s libmtwist.so.$(MAJOR) libmtwist.so ) 47 | 48 | clean :: 49 | rm -f *.o *~ libmtwist.so* 50 | 51 | #### end of makefile #### 52 | -------------------------------------------------------------------------------- /mtwist/mt-optimized-cokus.c: -------------------------------------------------------------------------------- 1 | /* 2 | // ``Mersenne Twister'' 3 | // 4 | // api to save/restore state added by Stephen Kertes, kertes@geoworks.com 5 | // Also added the .h and Makefile. july 25 1998. 6 | // 7 | // This is the ``Mersenne Twister'' random number generator MT19937, which 8 | // generates pseudorandom integers uniformly distributed in 0..(2^32 - 1) 9 | // starting from any odd seed in 0..(2^32 - 1). This version is a recode 10 | // by Shawn Cokus (Cokus@math.washington.edu) on March 8, 1998 of a version by 11 | // Takuji Nishimura (who had suggestions from Topher Cooper and Marc Rieffel in 12 | // July-August 1997). 13 | // 14 | // Effectiveness of the recoding (on Goedel2.math.washington.edu, a DEC Alpha 15 | // running OSF/1) using GCC -O3 as a compiler: before recoding: 51.6 sec. to 16 | // generate 300 million random numbers; after recoding: 24.0 sec. for the same 17 | // (i.e., 46.5% of original time), so speed is now about 12.5 million random 18 | // number generations per second on this machine. 19 | // 20 | // According to the URL 21 | // (and paraphrasing a bit in places), the Mersenne Twister is ``designed 22 | // with consideration of the flaws of various existing generators,'' has 23 | // a period of 2^19937 - 1, gives a sequence that is 623-dimensionally 24 | // equidistributed, and ``has passed many stringent tests, including the 25 | // die-hard test of G. Marsaglia and the load test of P. Hellekalek and 26 | // S. Wegenkittl.'' It is efficient in memory usage (typically using 2506 27 | // to 5012 bytes of static data, depending on data type sizes, and the code 28 | // is quite short as well). It generates random numbers in batches of 624 29 | // at a time, so the caching and pipelining of modern systems is exploited. 30 | // It is also divide- and mod-free. 31 | // 32 | // This library is free software; you can redistribute it and/or modify it 33 | // under the terms of the GNU Library General Public License as published by 34 | // the Free Software Foundation (either version 2 of the License or, at your 35 | // option, any later version). This library is distributed in the hope that 36 | // it will be useful, but WITHOUT ANY WARRANTY, without even the implied 37 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 38 | // the GNU Library General Public License for more details. You should have 39 | // received a copy of the GNU Library General Public License along with this 40 | // library; if not, write to the Free Software Foundation, Inc., 59 Temple 41 | // Place, Suite 330, Boston, MA 02111-1307, USA. 42 | // 43 | // The code as Shawn received it included the following notice: 44 | // 45 | // Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When 46 | // you use this, send an e-mail to with 47 | // an appropriate reference to your work. 48 | // 49 | // It would be nice to CC: when you write. 50 | // 51 | */ 52 | #include 53 | #include 54 | #include "mtwist.h" 55 | 56 | /* 57 | // 58 | // uint32 must be an unsigned integer type capable of holding at least 32 59 | // bits; exactly 32 should be fastest, but 64 is better on an Alpha with 60 | // GCC at -O3 optimization so try your options and see what's best for you 61 | // 62 | typedef unsigned long uint32; 63 | */ 64 | 65 | #define N (624) // length of state vector 66 | #define M (397) // a period parameter 67 | #define K (0x9908B0DFU) // a magic constant 68 | #define hiBit(u) ((u) & 0x80000000U) // mask all but highest bit of u 69 | #define loBit(u) ((u) & 0x00000001U) // mask all but lowest bit of u 70 | #define loBits(u) ((u) & 0x7FFFFFFFU) // mask the highest bit of u 71 | #define mixBits(u, v) (hiBit(u)|loBits(v)) // move hi bit of u to hi bit of v 72 | 73 | static uint32 state[N+1]; // state vector + 1 extra to not violate ANSI C 74 | static uint32 *next; // next random value is computed from here 75 | static int left = -1; // can *next++ this many times before reloading 76 | 77 | 78 | void seedMT(uint32 seed) 79 | { 80 | /* 81 | // 82 | // We initialize state[0..(N-1)] via the generator 83 | // 84 | // x_new = (69069 * x_old) mod 2^32 85 | // 86 | // from Line 15 of Table 1, p. 106, Sec. 3.3.4 of Knuth's 87 | // _The Art of Computer Programming_, Volume 2, 3rd ed. 88 | // 89 | // Notes (SJC): I do not know what the initial state requirements 90 | // of the Mersenne Twister are, but it seems this seeding generator 91 | // could be better. It achieves the maximum period for its modulus 92 | // (2^30) iff x_initial is odd (p. 20-21, Sec. 3.2.1.2, Knuth); if 93 | // x_initial can be even, you have sequences like 0, 0, 0, ...; 94 | // 2^31, 2^31, 2^31, ...; 2^30, 2^30, 2^30, ...; 2^29, 2^29 + 2^31, 95 | // 2^29, 2^29 + 2^31, ..., etc. so I force seed to be odd below. 96 | // 97 | // Even if x_initial is odd, if x_initial is 1 mod 4 then 98 | // 99 | // the lowest bit of x is always 1, 100 | // the next-to-lowest bit of x is always 0, 101 | // the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... , 102 | // the 3rd-from-lowest bit of x 4-cycles ... 0 1 1 0 0 1 1 0 ... , 103 | // the 4th-from-lowest bit of x has the 8-cycle ... 0 0 0 1 1 1 1 0 ... , 104 | // ... 105 | // 106 | // and if x_initial is 3 mod 4 then 107 | // 108 | // the lowest bit of x is always 1, 109 | // the next-to-lowest bit of x is always 1, 110 | // the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... , 111 | // the 3rd-from-lowest bit of x 4-cycles ... 0 0 1 1 0 0 1 1 ... , 112 | // the 4th-from-lowest bit of x has the 8-cycle ... 0 0 1 1 1 1 0 0 ... , 113 | // ... 114 | // 115 | // The generator's potency (min. s>=0 with (69069-1)^s = 0 mod 2^32) is 116 | // 16, which seems to be alright by p. 25, Sec. 3.2.1.3 of Knuth. It 117 | // also does well in the dimension 2..5 spectral tests, but it could be 118 | // better in dimension 6 (Line 15, Table 1, p. 106, Sec. 3.3.4, Knuth). 119 | // 120 | // Note that the random number user does not see the values generated 121 | // here directly since reloadMT() will always munge them first, so maybe 122 | // none of all of this matters. In fact, the seed values made here could 123 | // even be extra-special desirable if the Mersenne Twister theory says 124 | // so-- that's why the only change I made is to restrict to odd seeds. 125 | // 126 | */ 127 | register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state; 128 | register int j; 129 | 130 | for(left=0, *s++=x, j=N; --j; 131 | *s++ = (x*=69069U) & 0xFFFFFFFFU); 132 | } 133 | 134 | 135 | uint32 reloadMT(void) 136 | { 137 | register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1; 138 | register int j; 139 | 140 | if(left < -1) 141 | seedMT(4357U); 142 | 143 | left=N-1, next=state+1; 144 | 145 | for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++) 146 | *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); 147 | 148 | for(pM=state, j=M; --j; s0=s1, s1=*p2++) 149 | *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); 150 | 151 | s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); 152 | s1 ^= (s1 >> 11); 153 | s1 ^= (s1 << 7) & 0x9D2C5680U; 154 | s1 ^= (s1 << 15) & 0xEFC60000U; 155 | return(s1 ^ (s1 >> 18)); 156 | } 157 | 158 | 159 | /*inline uint32 randomMT(void)*/ 160 | uint32 randomMT(void) 161 | { 162 | uint32 y; 163 | 164 | if(--left < 0) 165 | return(reloadMT()); 166 | 167 | y = *next++; 168 | y ^= (y >> 11); 169 | y ^= (y << 7) & 0x9D2C5680U; 170 | y ^= (y << 15) & 0xEFC60000U; 171 | return(y ^ (y >> 18)); 172 | } 173 | 174 | void * saveMTstate(void *mtState) 175 | { 176 | /* if mtState is NULL then a block will be malloced and the ptr returned */ 177 | void *curpos; 178 | 179 | if (mtState == NULL) { 180 | mtState = malloc(sizeof(state) + sizeof(next) + sizeof(left)); 181 | } 182 | 183 | curpos = mtState; 184 | 185 | if (mtState != NULL) { 186 | *(((uint32 **)curpos)++) = next; 187 | *(((int *)curpos)++) = left; 188 | memcpy(curpos, state, sizeof(state)); 189 | } 190 | 191 | return mtState; 192 | }; 193 | 194 | void * restoreMTstate(void *mtState) 195 | { 196 | /* will NOT free the space */ 197 | 198 | void *curpos = mtState; 199 | 200 | if (curpos != NULL) { 201 | next = *(((uint32 **)curpos)++); 202 | left = *(((int *)curpos)++); 203 | memcpy(state, curpos, sizeof(state)); 204 | } 205 | 206 | return mtState; 207 | }; 208 | 209 | 210 | /* 211 | int main(void) 212 | { 213 | int j; 214 | 215 | // you can seed with any uint32, but the best are odds in 0..(2^32 - 1) 216 | 217 | seedMT(4357U); 218 | 219 | // print the first 2,002 random numbers seven to a line as an example 220 | for(j=0; j<2002; j++) { 221 | printf(" %10lu%s", (unsigned long) randomMT(), (j%7)==6 ? "\n" : ""); 222 | } 223 | 224 | return(EXIT_SUCCESS); 225 | } 226 | */ 227 | /* END FILE mt-optimized-cokus.c */ 228 | -------------------------------------------------------------------------------- /mtwist/mtwist.h: -------------------------------------------------------------------------------- 1 | /* mt.h include file Mersenne Twister random number library */ 2 | 3 | /* 4 | // 5 | // uint32 must be an unsigned integer type capable of holding at least 32 6 | // bits; exactly 32 should be fastest, but 64 is better on an Alpha with 7 | // GCC at -O3 optimization so try your options and see what's best for you 8 | // 9 | */ 10 | #ifndef uint32 11 | typedef unsigned long uint32; 12 | #endif 13 | 14 | extern void seedMT(uint32 seed); 15 | /* you can seed with any uint32, but the best are odds in 0..(2^32 - 1) */ 16 | 17 | extern uint32 randomMT(void); 18 | /* lots of lovely numbers come out of this */ 19 | 20 | extern void * saveMTstate(void *mtState); 21 | /* if mtState is NULL then a block will be malloced and the ptr returned */ 22 | 23 | extern void * restoreMTstate(void *mtState); 24 | /* will NOT free the space */ 25 | 26 | /* end file mt.h */ 27 | -------------------------------------------------------------------------------- /netopen.c: -------------------------------------------------------------------------------- 1 | /* xxx.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | 6 | 7 | /* END FILE xxx.c */ 8 | -------------------------------------------------------------------------------- /pascal.c: -------------------------------------------------------------------------------- 1 | /* pascal.c */ 2 | /* code to help port pascal */ 3 | 4 | #include "imoria.h" 5 | 6 | ////////////////////////////////////////////////////////////////////// 7 | 8 | void writeln(char *out_line) 9 | { 10 | printf("%s\n\r",out_line); 11 | }; 12 | 13 | ////////////////////////////////////////////////////////////////////// 14 | 15 | integer pindex(char *s1, char c1) 16 | { 17 | /* 18 | pascal index function, return position of c1 in s1 19 | 20 | returns i if (s1[i-1] == c1), returns 0 if c1 not found 21 | */ 22 | 23 | char *c2; 24 | 25 | c2 = strchr(s1, c1); 26 | 27 | if (c2 == NULL) { 28 | return 0; 29 | } 30 | 31 | return (c2 - s1 + 1); 32 | }; 33 | ////////////////////////////////////////////////////////////////////// 34 | boolean is_in(integer obj, obj_set oset) 35 | { 36 | integer i1, tmp; 37 | boolean return_value = false; 38 | 39 | // ENTER("is_in","m"); 40 | 41 | #if DO_DEBUG 42 | tmp = 0; 43 | for (i1=0; i1 < MAX_OBJ_SET; i1++) { 44 | if ((tmp > oset[i1]) && (oset[i1] > 0)) { 45 | printf("bad obj_set i1 = %ld\n\r", i1); 46 | fprintf(debug_file,"bad obj_set: %d",oset[i1]); 47 | for (i1=0; i1 < MAX_OBJ_SET; i1++) { 48 | fprintf(debug_file,"%d ",oset[i1]); 49 | } 50 | fprintf(debug_file,"\n"); 51 | exit (0); 52 | } 53 | tmp = oset[i1]; 54 | } 55 | #endif 56 | 57 | tmp = 0; 58 | for (i1=0;(i1 0) { 255 | msg_print("You are too hoarse to sing!"); 256 | } else if (py.flags.afraid > 0) { 257 | msg_print("You are too scared to play music!"); 258 | } else if (py.flags.confused > 0) { 259 | msg_print("You are too confused..."); 260 | } else if (class[py.misc.pclass].dspell) { 261 | if (inven_ctr > 0) { 262 | if (find_range(playable_things,false,&i1,&i2)) { 263 | 264 | redraw = false; 265 | if (get_item(&item_ptr,"Use which Instrument?", 266 | &redraw,i2,&trash_char,false,false)) { 267 | if (cast_spell("Play which song?",item_ptr, 268 | &choice,&chance,&redraw)) { 269 | //with magic_spell[py.misc.pclass][choice]. do; 270 | reset_flag = false; 271 | if (randint(100) < chance) { 272 | switch (randint(5)) { 273 | case 1 : msg_print("*Twang!*"); break; 274 | case 2 : msg_print("*Boink!*"); break; 275 | case 3 : msg_print("*Ding!*"); break; 276 | case 4 : msg_print("*Plunk!*"); break; 277 | case 5 : msg_print("*Clang!*"); break; 278 | }; /*{ of the bad notes }*/ 279 | switch (randint(2)) { 280 | case 1 : msg_print("You play a sour note!"); break; 281 | case 2 : msg_print("You play an awful note!"); break; 282 | } 283 | } else { 284 | p__druid_effects(choice); 285 | if (!(reset_flag)) { 286 | //with py.misc do; 287 | PM.exp += magic_spell[py.misc.pclass][choice].sexp; 288 | prt_experience(); 289 | magic_spell[py.misc.pclass][choice].sexp = 0; 290 | } 291 | } 292 | 293 | //with py.misc do; 294 | if (!reset_flag) { 295 | if (magic_spell[py.misc.pclass][choice].smana > PM.cmana) { 296 | msg_print("You lose your voice attempting the song!"); 297 | py.flags.hoarse = 298 | randint(5*(magic_spell[PM.pclass][choice].smana-PM.cmana)); 299 | PM.cmana = 0; 300 | if (randint(3) == 1) { 301 | lower_stat(CHR,"Your self-esteem is lowered!"); 302 | } 303 | } else { 304 | PM.cmana -= magic_spell[py.misc.pclass][choice].smana; 305 | } 306 | prt_mana(); 307 | } 308 | } else { 309 | if (redraw) { 310 | draw_cave(); 311 | } 312 | } 313 | } 314 | } else { 315 | msg_print("But you are not carrying any Instruments!"); 316 | } 317 | } else { 318 | msg_print("But you are not carrying any Instruments!"); 319 | } 320 | } else { 321 | switch (bard_adj()) { 322 | case 0 : msg_print("You utter a gutteral cry."); break; 323 | case 1 : msg_print("You utter a gutteral cry."); break; 324 | case 2 : msg_print("You attempt to sing."); break; 325 | case 3 : msg_print("You attempt to sing."); break; 326 | case 4 : msg_print("You sing a song."); break; 327 | case 5 : msg_print("You sing a song."); break; 328 | case 6 : msg_print("You sing a nice song."); break; 329 | case 7 : msg_print("You sing a very nice song."); break; 330 | } 331 | } 332 | }; 333 | /* END FILE play.c */ 334 | ////////////////////////////////////////////////////////////////////// 335 | ////////////////////////////////////////////////////////////////////// 336 | ////////////////////////////////////////////////////////////////////// 337 | -------------------------------------------------------------------------------- /player.c: -------------------------------------------------------------------------------- 1 | /* player.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "dungeon.h" 6 | 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | ////////////////////////////////////////////////////////////////////// 10 | void search_off() 11 | { 12 | search_flag = false; 13 | find_flag = false; 14 | move_char(5); 15 | change_speed(-1); 16 | py.flags.status &= ~IS_SEARCHING; 17 | prt_search(); 18 | }; 19 | ////////////////////////////////////////////////////////////////////// 20 | ////////////////////////////////////////////////////////////////////// 21 | ////////////////////////////////////////////////////////////////////// 22 | void search_on() 23 | { 24 | /*{ Search Mode enhancement -RAK- }*/ 25 | 26 | search_flag = true; 27 | change_speed(+1); 28 | py.flags.status |= IS_SEARCHING; 29 | prt_search(); 30 | //with py.flags do; 31 | }; 32 | ////////////////////////////////////////////////////////////////////// 33 | ////////////////////////////////////////////////////////////////////// 34 | ////////////////////////////////////////////////////////////////////// 35 | void rest_off() 36 | { 37 | py.flags.rest = 0; 38 | py.flags.status &= ~IS_RESTING; 39 | py.flags.resting_till_full = false; 40 | if (msg_flag) { 41 | erase_line(1,1); 42 | } 43 | prt_rest(); 44 | }; 45 | ////////////////////////////////////////////////////////////////////// 46 | ////////////////////////////////////////////////////////////////////// 47 | ////////////////////////////////////////////////////////////////////// 48 | void move_char(integer dir) 49 | { 50 | /*{ Moves player from one space to another... -RAK- }*/ 51 | 52 | integer test_row,test_col; 53 | integer i1,i2; 54 | 55 | ENTER("move_char","m"); 56 | 57 | test_row = char_row; 58 | test_col = char_col; 59 | 60 | if (dir==5) { 61 | find_flag = false; 62 | } 63 | 64 | if (py.flags.confused > 0) { /*{ Confused? }*/ 65 | if (randint(4) > 1) { /*{ 75% random movement }*/ 66 | if (dir != 5) { /*{ Never random if sitting}*/ 67 | dir = randint(9); 68 | find_flag = false; 69 | } 70 | } 71 | } 72 | 73 | if (move_dir(dir,&test_row,&test_col)) { /*{ Legal move? }*/ 74 | //with cave[test_row][test_col] do; 75 | if (cave[test_row][test_col].cptr < 2) { /*{ No creature? }*/ 76 | if (cave[test_row][test_col].fopen) { /*{ Open floor spot }*/ 77 | if ((find_flag) && 78 | ((is_in(cave[char_row][char_col].fval,earth_set)) == 79 | (is_in(cave[test_row][test_col].fval,water_set)))) { 80 | find_flag = false; 81 | move_char(5); 82 | } else { 83 | 84 | /*{ Move character record (-1) }*/ 85 | move_rec(char_row,char_col,test_row,test_col); 86 | /*{ Check for new panel }*/ 87 | if (get_panel(test_row,test_col,false)) { 88 | prt_map(); 89 | } 90 | /*{ Check to see if he should stop }*/ 91 | if (find_flag) { 92 | area_affect(dir,test_row,test_col); 93 | } 94 | /*{ Check to see if he notices something }*/ 95 | if (py.flags.blind < 1) { 96 | if ((randint(py.misc.fos) == 1) || (search_flag)) { 97 | search(test_row,test_col,py.misc.srh); 98 | } 99 | } 100 | /*{ An object is beneath him... }*/ 101 | 102 | if (cave[test_row][test_col].tptr > 0) { 103 | carry(test_row,test_col); 104 | } 105 | 106 | /*{ Move the light source }*/ 107 | move_light(char_row,char_col,test_row,test_col); 108 | 109 | /*{ A room of light should be lit... }*/ 110 | if (cave[test_row][test_col].fval == lopen_floor.ftval) { 111 | if (py.flags.blind < 1) { 112 | if (!(cave[test_row][test_col].pl)) { 113 | light_room(test_row,test_col); 114 | } 115 | } 116 | /*{ In doorway of light-room? }*/ 117 | } else if ((cave[test_row][test_col].fval == corr_floor2.ftval) || 118 | (cave[test_row][test_col].fval == corr_floor3.ftval)) { 119 | if (py.flags.blind < 1) { 120 | for (i1=(test_row-1); i1<=(test_row+1); i1++) { 121 | for (i2=(test_col-1); i2<=(test_col+1); i2++) { 122 | if (in_bounds(i1,i2)) { 123 | //with cave[i1][i2] do; 124 | if (cave[i1][i2].fval == lopen_floor.ftval) { 125 | if (!(cave[i1][i2].pl)) { 126 | light_room(i1,i2); 127 | } 128 | } 129 | } 130 | } 131 | } 132 | } 133 | } 134 | /*{ Make final assignments of char co-ords}*/ 135 | char_row = test_row; 136 | char_col = test_col; 137 | } 138 | } else { 139 | /*{ Can't move onto floor space }*/ 140 | /*{ Try a new direction if in find mode }*/ 141 | if (!(pick_dir(dir))) { 142 | if (find_flag) { 143 | find_flag = false; 144 | move_char(5); 145 | } else if (cave[test_row][test_col].tptr > 0) { 146 | reset_flag = true; 147 | if (t_list[cave[test_row][test_col].tptr].tval == Rubble) { 148 | msg_print("There is rubble blocking your way."); 149 | }else if (t_list[cave[test_row][test_col].tptr].tval==Closed_door){ 150 | msg_print("There is a closed door blocking your way."); 151 | } 152 | } else { 153 | reset_flag = true; 154 | } 155 | } /* end if pick_dir */ 156 | } 157 | 158 | } else { /*{ Attacking a creature! }*/ 159 | 160 | if (find_flag) { 161 | find_flag = false; 162 | move_light(char_row,char_col,char_row,char_col); 163 | } 164 | 165 | if (py.flags.afraid < 1) { /*{ Coward? }*/ 166 | py_attack(test_row,test_col); 167 | } else { /*{ Coward! }*/ 168 | msg_print("You are too afraid!"); 169 | } 170 | 171 | } /* end if attacing */ 172 | } /* end if legal move */ 173 | 174 | LEAVE("move_char","m"); 175 | }; 176 | ////////////////////////////////////////////////////////////////////// 177 | ////////////////////////////////////////////////////////////////////// 178 | ////////////////////////////////////////////////////////////////////// 179 | void regenhp(real percent) 180 | { 181 | /*{ Regenerate hit points -RAK- }*/ 182 | 183 | PM.chp += PM.mhp*percent + PLAYER_REGEN_HPBASE; 184 | 185 | }; 186 | 187 | void regenmana(real percent) 188 | { 189 | /*{ Regenerate mana points -RAK- }*/ 190 | 191 | PM.cmana += PM.mana*percent + PLAYER_REGEN_MNBASE; 192 | 193 | }; 194 | ////////////////////////////////////////////////////////////////////// 195 | ////////////////////////////////////////////////////////////////////// 196 | ////////////////////////////////////////////////////////////////////// 197 | void take_hit(integer damage, vtype hit_from) 198 | { 199 | /*{ Decreases players hit points and sets death flag if neccessary}*/ 200 | 201 | ENTER("take_hit", ""); 202 | 203 | if (py.flags.invuln > 0) { 204 | damage = 0; 205 | } 206 | 207 | py.misc.chp -= damage; 208 | 209 | if (search_flag) { 210 | search_off(); 211 | } 212 | 213 | if (py.flags.rest > 0) { 214 | rest_off(); 215 | } 216 | 217 | flush(); 218 | 219 | if (py.misc.chp <= -1) { 220 | if (!death) { 221 | /*{ Hee, hee... Ain't I mean? }*/ 222 | death = true; 223 | strcpy(died_from, hit_from); 224 | total_winner = false; 225 | } 226 | moria_flag = true; 227 | } else { 228 | prt_hp(); 229 | } 230 | 231 | LEAVE("take_hit", ""); 232 | }; 233 | ////////////////////////////////////////////////////////////////////// 234 | ////////////////////////////////////////////////////////////////////// 235 | ////////////////////////////////////////////////////////////////////// 236 | 237 | ////////////////////////////////////////////////////////////////////// 238 | ////////////////////////////////////////////////////////////////////// 239 | ////////////////////////////////////////////////////////////////////// 240 | 241 | /* END FILE player.c */ 242 | -------------------------------------------------------------------------------- /port.c: -------------------------------------------------------------------------------- 1 | /* port.c */ 2 | /* code to help port the vax pascal into linux c */ 3 | 4 | #include "imoria.h" 5 | 6 | ////////////////////////////////////////////////////////////////////// 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | 10 | void * safe_malloc(int blocksize, char *message) 11 | { 12 | void * new_pointer; 13 | 14 | if((new_pointer = (void *)malloc(blocksize)) == NULL) { 15 | printf("\n\r\n\rMemory error (%d bytes)! Ref: %s.\n\r\n\r",blocksize,message); 16 | printf("malloc calls: %ld\tmalloc bytes: %ld\n\r",malloc_calls,malloc_bytes); 17 | printf("free calls: %ld\tfree bytes: %ld\n\r",free_calls,free_bytes); 18 | printf("\n\rdelta calls: %ld\ndelta bytes: %ld\n\r", 19 | malloc_calls-free_calls,malloc_bytes-free_bytes); 20 | printf("\n\r\n\r"); 21 | exit_game(); 22 | } 23 | 24 | malloc_calls++; 25 | malloc_bytes += blocksize; 26 | 27 | return new_pointer; 28 | }; 29 | ////////////////////////////////////////////////////////////////////// 30 | ////////////////////////////////////////////////////////////////////// 31 | ////////////////////////////////////////////////////////////////////// 32 | void dispose(void *ptr, int size, char *message) 33 | { 34 | free_calls++; 35 | free_bytes += size; 36 | 37 | free(ptr); 38 | }; 39 | ////////////////////////////////////////////////////////////////////// 40 | ////////////////////////////////////////////////////////////////////// 41 | ////////////////////////////////////////////////////////////////////// 42 | 43 | char * chomp(char *input_line) 44 | { 45 | /* remove \n from the end of a string if there is one */ 46 | integer x; 47 | 48 | x = strlen(input_line); 49 | if (x && (input_line[x-1] == '\n')) 50 | { 51 | input_line[x-1] = 0; 52 | } 53 | 54 | return input_line; 55 | 56 | }; /* end chomp */ 57 | 58 | ////////////////////////////////////////////////////////////////////// 59 | ////////////////////////////////////////////////////////////////////// 60 | ////////////////////////////////////////////////////////////////////// 61 | 62 | integer min3(integer i1, integer i2, integer i3) 63 | { 64 | if (i1 < i2) { 65 | return (i1 < i3) ? i1 : i3; 66 | } else { 67 | return (i2 < i3) ? i2 : i3; 68 | } 69 | }; 70 | 71 | ////////////////////////////////////////////////////////////////////// 72 | 73 | void ignore_signals() 74 | { 75 | }; 76 | void restore_signals() 77 | { 78 | }; 79 | void default_signals() 80 | { 81 | }; 82 | 83 | /* Something happens to disturb the player. -CJS- 84 | The first arg indicates a major disturbance, which affects search. 85 | The second arg indicates a light change. */ 86 | /* see moria1.c from umoria */ 87 | void disturb(s, l) 88 | int s, l; 89 | { 90 | #if 0 91 | command_count = 0; 92 | if (s && search_flag) 93 | search_off(); 94 | if (py.flags.rest > 0) 95 | rest_off(); 96 | if (l || find_flag) 97 | { 98 | find_flag = FALSE; 99 | check_view(); 100 | } 101 | #endif 102 | } 103 | 104 | ////////////////////////////////////////////////////////////////////// 105 | ////////////////////////////////////////////////////////////////////// 106 | ////////////////////////////////////////////////////////////////////// 107 | 108 | /* END FILE port.c */ 109 | -------------------------------------------------------------------------------- /potions.c: -------------------------------------------------------------------------------- 1 | /* potions.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "dungeon.h" 6 | ////////////////////////////////////////////////////////////////////// 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | void q__potion_effect(integer effect, boolean *idented) 10 | { 11 | integer i4,i5; 12 | boolean redraw = false; 13 | boolean ident = false; 14 | 15 | /*{ Potions }*/ 16 | switch (effect) { 17 | 18 | case 1 : /*{ Gain Str }*/ 19 | ident = gain_stat(STR,"X"); 20 | break; 21 | 22 | case 2 : /*{ Lose Str }*/ 23 | ident = lose_stat(STR,"X","X"); 24 | break; 25 | 26 | case 3 : /*{ Restore Str }*/ 27 | ident = restore_stat(STR,"X"); 28 | break; 29 | 30 | case 4 : /*{ Gain Int }*/ 31 | ident = gain_stat(INT,"X"); 32 | break; 33 | 34 | case 5 : /*{ Lose Int }*/ 35 | msg_print("This potion tastes very dull."); 36 | ident = lose_stat(INT,"X","X"); 37 | break; 38 | 39 | case 6 : /*{ Restore Int }*/ 40 | ident = restore_stat(INT,"X"); 41 | break; 42 | 43 | case 7 : /*{ Gain Wis }*/ 44 | ident = gain_stat(WIS,"X"); 45 | break; 46 | 47 | case 8 : /*{ Lose Wis }*/ 48 | ident = lose_stat(WIS,"X","X"); 49 | break; 50 | 51 | case 9 : /*{ Restore Wis }*/ 52 | ident = restore_stat(WIS,"X"); 53 | break; 54 | 55 | case 10 : /*{ Gain Chr }*/ 56 | ident = gain_stat(CHR,"X"); 57 | break; 58 | 59 | case 11 : /*{ Lose Chr }*/ 60 | ident = lose_stat(CHR,"X","X"); 61 | break; 62 | 63 | case 12 : /*{ Restore Chr }*/ 64 | ident = restore_stat(CHR,"X"); 65 | break; 66 | 67 | /*{ Cures and healing }*/ 68 | case 13 : 69 | ident = hp_player(damroll("2d7"),"a potion."); 70 | break; 71 | 72 | case 14 : 73 | ident = hp_player(damroll("4d7"),"a potion."); 74 | break; 75 | 76 | case 15 : 77 | ident = hp_player(damroll("6d7"),"a potion."); 78 | break; 79 | 80 | case 16 : 81 | ident = hp_player(1000,"a potion."); 82 | break; 83 | 84 | case 17 : /*{ Gain Con }*/ 85 | py.misc.mhp++; 86 | py.misc.chp += py.misc.mhp; 87 | ident = gain_stat(CON,"X"); 88 | prt_hp(); 89 | break; 90 | 91 | case 18 : /*{ Gain Experience }*/ 92 | //with py.misc do; 93 | i5 = (PM.exp div 2) + 10; 94 | if (i5 > 100000) { 95 | i5 = 100000; 96 | } 97 | PM.exp += i5; 98 | msg_print("You feel more experienced."); 99 | prt_experience(); 100 | ident = true; 101 | break; 102 | 103 | case 19 : /*{ Sleep }*/ 104 | if (! (py.flags.free_act)) { 105 | msg_print("You fall asleep."); 106 | py.flags.paralysis += randint(4) + 4; 107 | ident = true; 108 | } 109 | break; 110 | 111 | case 20 : /*{ Darkness }*/ 112 | msg_print("You are covered by a veil of darkness."); 113 | PF.blind += randint(100) + 100; 114 | ident = true; 115 | break; 116 | 117 | case 21 : /*{ Confusion }*/ 118 | msg_print("Hey! This is good stuff! * Hick! *"); 119 | PF.confused += randint(20) + 12; 120 | ident = true; 121 | break; 122 | 123 | case 22 : /*{ Poison }*/ 124 | msg_print("You feel very sick."); 125 | PF.poisoned += randint(15) + 10; 126 | ident = true; 127 | break; 128 | 129 | case 23 : /*{ Haste Self }*/ 130 | py.flags.fast += randint(25) + 15; 131 | ident = true; 132 | break; 133 | 134 | case 24 : /*{ Slowness }*/ 135 | py.flags.slow += randint(25) + 15; 136 | ident = true; 137 | break; 138 | 139 | case 25 : 140 | ident = detect_creatures(c_monster); 141 | break; 142 | 143 | case 26 : /*{ Increase Dex }*/ 144 | ident = gain_stat(DEX,"X"); 145 | break; 146 | 147 | case 27 : /*{ Restore Dex }*/ 148 | ident = restore_stat(DEX,"X"); 149 | break; 150 | 151 | case 28 : /*{ Restore Con }*/ 152 | ident = restore_stat(CON,"X"); 153 | break; 154 | 155 | case 29 : /*{ Cure Blindness }*/ 156 | cure_me(&py.flags.blind); 157 | break; 158 | 159 | case 30 : /*{ Cure Confusion }*/ 160 | cure_me(&py.flags.confused); 161 | break; 162 | 163 | case 31 : /*{ Cure Poison }*/ 164 | cure_me(&py.flags.poisoned); 165 | break; 166 | 167 | case 32 : /*{ Learning }*/ /* 32 is the Cursed_worn_bit value */ 168 | case 48 : /*{ Learning }*/ 169 | //with py.misc do; 170 | //with class[pclass] do; 171 | if (class[PM.pclass].mspell) { 172 | ident = learn_spell(&redraw); 173 | if (redraw) { 174 | draw_cave(); 175 | } 176 | } else if (class[PM.pclass].bspell) { 177 | ident = learn_song(&redraw); 178 | if (redraw) { 179 | draw_cave(); 180 | } 181 | } else if (class[PM.pclass].pspell) { 182 | ident = learn_prayer(); 183 | } else if (class[PM.pclass].dspell) { 184 | ident = learn_druid(); 185 | } 186 | break; 187 | 188 | case 33 : /*{ Lose Memories }*/ 189 | msg_print("You feel your memories fade..."); 190 | msg_print(""); 191 | i4 = trunc(py.misc.exp/5.0); 192 | lose_exp(randint(i4)+i4); 193 | ident = true; 194 | break; 195 | 196 | case 34 : /*{ Salt Water }*/ 197 | //with py.flags do; 198 | PF.poisoned = 0; 199 | py.flags.status &= ~IS_POISONED; 200 | prt_poisoned(); 201 | if (PF.foodc > 150) { 202 | PF.foodc = 150; 203 | } 204 | PF.paralysis = 4; 205 | msg_print("The potion makes you vomit!"); 206 | ident = true; 207 | break; 208 | 209 | case 35 : /*{ Invulnerability }*/ 210 | py.flags.invuln += randint(10) + 10; 211 | ident = true; 212 | break; 213 | 214 | case 36 : /*{ Heroism }*/ 215 | py.flags.hero += randint(25) + 25; 216 | ident = true; 217 | break; 218 | 219 | case 37 : /*{ Super-Heroism }*/ 220 | py.flags.shero += randint(25) + 25; 221 | ident = true; 222 | break; 223 | 224 | case 38 : /*{ Remove Fear }*/ 225 | ident = cure_me(&py.flags.afraid); 226 | break; 227 | 228 | case 39 : /*{ Restore Level }*/ 229 | ident = restore_level(); 230 | add_food(5000); 231 | py.flags.status &= ~(IS_WEAK | IS_HUNGERY); 232 | prt_hunger(); 233 | break; 234 | 235 | case 40 : /*{ Resist Heat }*/ 236 | PF.resist_heat += randint(10) + 10; 237 | break; 238 | 239 | case 41 : /*{ Resist Cold }*/ 240 | PF.resist_cold += randint(10) + 10; 241 | break; 242 | 243 | case 42 : 244 | detect_inv2(randint(12)+12); 245 | break; 246 | 247 | case 43 : /*{ Slow Poison }*/ 248 | ident = slow_poison(); 249 | break; 250 | 251 | case 44 : /*{ Cure Poison }*/ 252 | ident = cure_me(&py.flags.poisoned); 253 | break; 254 | 255 | case 45 : /*{ Restore Mana }*/ 256 | //with py.misc do; 257 | if (PM.cmana < PM.mana) { 258 | PM.cmana = PM.mana; 259 | } 260 | ident = true; 261 | msg_print("Your feel your head clear..."); 262 | break; 263 | 264 | case 46 : /*{ Infra-Vision }*/ 265 | PF.tim_infra += 100 + randint(100); 266 | ident = true; 267 | msg_print("Your eyes begin to tingle."); 268 | break; 269 | 270 | case 47 : /* cure hallucination */ 271 | msg_print("Pretty colors!"); 272 | PF.confused += randint(5) + 5; 273 | ident = cure_me(&py.flags.image); 274 | break; 275 | 276 | /* case 48 moved up to 32 */ 277 | 278 | case 49 : /* reduce petrification */ 279 | if ( PF.petrification > 0 ) { 280 | ident = true; 281 | PF.petrification -= 100; 282 | if ( PF.petrification < 0 ) { 283 | PF.petrification = 0; 284 | } 285 | } 286 | break; 287 | 288 | case 50 : ; 289 | case 51 : ; 290 | case 52 : ; 291 | case 53 : ; 292 | case 54 : ; 293 | case 55 : ; 294 | case 56 : ; 295 | case 57 : ; 296 | case 58 : ; 297 | case 59 : ; 298 | case 60 : ; 299 | case 61 : ; 300 | case 62 : ; 301 | default: 302 | break; 303 | } /* end switch */ 304 | /*{ End of Potions... }*/ 305 | 306 | *idented = ident; 307 | }; 308 | ////////////////////////////////////////////////////////////////////// 309 | void quaff() 310 | { 311 | /*{ Potions for the quaffing -RAK- }*/ 312 | 313 | unsigned long q1,q2; 314 | integer i3,i6; 315 | treas_ptr i2,item_ptr; 316 | char trash_char; 317 | boolean redraw,ident; 318 | obj_set stuff_to_drink = {potion1, potion2, 0}; 319 | 320 | reset_flag = true; 321 | 322 | if (inven_ctr > 0) { 323 | if (find_range(stuff_to_drink,false,&i2,&i3)) { 324 | redraw = false; 325 | if (get_item(&item_ptr,"Quaff which potion?", 326 | &redraw,i3,&trash_char,false,false)) { 327 | //with item_ptr->data. do; 328 | if (redraw) { 329 | draw_cave(); 330 | } 331 | reset_flag = false; 332 | q1 = item_ptr->data.flags; 333 | q2 = item_ptr->data.flags2; 334 | ident = false; 335 | 336 | for (;q1 > 0 || q2 > 0;) { 337 | i6 = bit_pos64(&q2,&q1)+1; 338 | 339 | /* 340 | * It looks like potion2 was created before flags2 was 341 | * added to the treasure type, now we can fit all the 342 | * potion effects into the pair of flags. 343 | * 344 | * The += 31 should be 64 now, I am leaving it at 31 so 345 | * that old characters do not get confused. 346 | */ 347 | if (item_ptr->data.tval == potion2) { 348 | i6 += 31; 349 | } 350 | 351 | q__potion_effect(i6, &ident); 352 | } /* end for */ 353 | 354 | if (ident) { 355 | identify(&(item_ptr->data)); 356 | } 357 | 358 | if (item_ptr->data.flags != 0) { 359 | PM.exp += (item_ptr->data.level / (real)PM.lev) + .5; 360 | prt_experience(); 361 | } 362 | 363 | add_food(item_ptr->data.p1); 364 | desc_remain(item_ptr); 365 | inven_destroy(item_ptr); 366 | prt_weight(); 367 | 368 | } else { 369 | if (redraw) { 370 | draw_cave(); 371 | } 372 | } 373 | } else { 374 | msg_print("You are not carrying any potions."); 375 | } 376 | } else { 377 | msg_print("But you are not carrying anything."); 378 | } 379 | }; 380 | 381 | /* END FILE potions.c */ 382 | ////////////////////////////////////////////////////////////////////// 383 | ////////////////////////////////////////////////////////////////////// 384 | ////////////////////////////////////////////////////////////////////// 385 | -------------------------------------------------------------------------------- /prayer.c: -------------------------------------------------------------------------------- 1 | /* prayer.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "dungeon.h" 6 | ////////////////////////////////////////////////////////////////////// 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | void p__prayer_effects(integer effect) 10 | { 11 | 12 | /*{ Prayers... }*/ 13 | integer i2,dir; 14 | integer dumy,y_dumy,x_dumy; 15 | 16 | y_dumy = char_row; 17 | x_dumy = char_col; 18 | 19 | switch (effect+1) { 20 | 21 | case 1 : /*{ Detect Evil }*/ 22 | detect_creatures(c_evil); 23 | break; 24 | 25 | case 2 : /*{ Cure Light Wounds }*/ 26 | hp_player(damroll("3d3"),"a prayer."); 27 | break; 28 | 29 | case 3 : /*{ Bless }*/ 30 | bless(randint(12)+12); 31 | break; 32 | 33 | case 4 : /*{ Remove Fear }*/ 34 | cure_me(&py.flags.afraid); 35 | break; 36 | 37 | case 5 : /*{ Call Light }*/ 38 | light_area(char_row,char_col); 39 | break; 40 | 41 | case 6 : /*{ Find Traps }*/ 42 | detect_trap(); 43 | break; 44 | 45 | case 7 : /*{ Detect Doors/Stairs }*/ 46 | detect_sdoor(); 47 | break; 48 | 49 | case 8 : /*{ Slow Poison }*/ 50 | slow_poison(); 51 | break; 52 | 53 | case 9 : /*{ Blind Creature }*/ 54 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 55 | zap_monster(dir,char_row,char_col,0,c_confuse); 56 | } 57 | break; 58 | 59 | case 10 : /*{ Portal }*/ 60 | teleport(py.misc.lev*3); 61 | break; 62 | 63 | case 11 : /*{ Cure Medium Wounds }*/ 64 | hp_player(damroll("4d4"),"a prayer."); 65 | break; 66 | 67 | case 12 : /*{ Ray of Sanctification }*/ 68 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 69 | fire_bolt(c_good,dir,char_row,char_col,damroll("2d6"),"Purple Ray"); 70 | } 71 | break; 72 | 73 | case 13 : /*{ Heroism }*/ 74 | py.flags.hero += randint(24) + 48; 75 | break; 76 | 77 | case 14 : /*{ Sanctuary }*/ 78 | sleep_monsters1(char_row,char_col); 79 | break; 80 | 81 | case 15 : /*{ Remove Curse }*/ 82 | for (i2 = Equipment_min; i2 <= EQUIP_MAX-1; i2++) { 83 | //with equipment[i2]. do; 84 | equipment[i2].flags &= 0x7FFFFFFF; 85 | } 86 | break; 87 | 88 | case 16 : /*{ Resist Heat and Cold }*/ 89 | //with py.flags do; 90 | PF.resist_heat += randint(10) + 10; 91 | PF.resist_cold += randint(10) + 10; 92 | break; 93 | 94 | case 17 : /*{ Silence }*/ 95 | PF.temp_stealth += (randint(20) + 15); 96 | break; 97 | 98 | case 18 : /*{ Resist Petrification }*/ 99 | PF.resist_petri += (randint(15) + 10); 100 | break; 101 | 102 | case 19 : /*{ Neutralize Poison }*/ 103 | cure_me(&py.flags.poisoned); 104 | break; 105 | 106 | case 20 : /*{ Cure Serious Wounds }*/ 107 | hp_player(damroll("9d4"),"a prayer."); 108 | break; 109 | 110 | case 21 : /*{ Chant }*/ 111 | bless(24+randint(48)); 112 | break; 113 | 114 | case 22 : /*{ Sense Invisible }*/ 115 | detect_inv2(randint(24)+24); 116 | break; 117 | 118 | case 23 : /*{ Protection from Evil }*/ 119 | protect_evil(); 120 | break; 121 | 122 | case 24 : /*{ Earthquake }*/ 123 | earthquake(); 124 | break; 125 | 126 | case 25 : /*{ Create food }*/ 127 | create_food(3,2,1,0,0); 128 | break; 129 | 130 | case 26 : /*{ Sense Surroundings }*/ 131 | map_area(); 132 | break; 133 | 134 | case 27 : /*{ Orb of Draining }*/ 135 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 136 | fire_ball(c_good,dir,char_row,char_col, 137 | damroll("3d6")+py.misc.lev,"Black Sphere"); 138 | } 139 | break; 140 | 141 | case 28 : /*{ Cure Critical Wounds }*/ 142 | hp_player(damroll("20d4"),"a prayer."); 143 | break; 144 | 145 | case 29 : /*{ Turn Undead }*/ 146 | zap_area(0,0,c_turn); 147 | break; 148 | 149 | case 30 : /*{ Prayer }*/ 150 | py.flags.shero = 24 + randint(48); /* XXXX not cumulitive */ 151 | break; 152 | 153 | case 31 : /*{ Dispell Undead }*/ 154 | zap_area(0x0008,3*py.misc.lev,c_hp); 155 | break; 156 | 157 | case 32 : /*{ Resist Paralysis }*/ 158 | py.flags.free_time += (randint(20) + 15); 159 | break; 160 | 161 | case 33 : /*{ Blade Barrier }*/ 162 | py.flags.blade_ring += 3+randint(3); 163 | break; 164 | 165 | case 34 : /*{ Dispell Evil }*/ 166 | zap_area(0x0004,3*py.misc.lev,c_hp); 167 | break; 168 | 169 | case 35 : /*{ Heal }*/ 170 | hp_player(200,"a prayer."); 171 | break; 172 | 173 | case 36 : /*{ Resist Magic }*/ 174 | py.flags.magic_prot += 40 + randint(40); 175 | break; 176 | 177 | case 37 : /*{ Holy Thunder }*/ 178 | msg_print("KABOOM!"); 179 | zap_area(0x0004,4+randint(4),c_thunder); 180 | break; 181 | 182 | case 38 : /*{ Glyph of Warding }*/ 183 | warding_glyph(); 184 | break; 185 | 186 | case 39 : /*{ Hero's Feast }*/ 187 | msg_print("You have a marvelous meal!"); 188 | py.flags.foodc = PLAYER_FOOD_FULL+4000; 189 | prt_hunger(); 190 | hp_player(200,"a prayer."); 191 | create_food(6,4,3,2,1); 192 | py.flags.status &= ~(IS_WEAK | IS_HUNGERY); 193 | prt_hunger(); 194 | msg_print("You are full."); 195 | break; 196 | 197 | case 40 : /*{ Holy Word }*/ 198 | zap_area(0x0004,6*py.misc.lev,c_holy_word); 199 | cure_me(&py.flags.afraid); 200 | cure_me(&py.flags.poisoned); 201 | hp_player(1000,"a prayer."); 202 | break; 203 | 204 | default: 205 | break; 206 | } 207 | /*{ End of prayers... }*/ 208 | 209 | }; 210 | ////////////////////////////////////////////////////////////////////// 211 | void pray() 212 | { 213 | /*{ Pray like HELL... -RAK- }*/ 214 | 215 | treas_ptr i1,item_ptr; 216 | integer choice,chance,i2; 217 | char trash_char; 218 | boolean redraw; 219 | obj_set good_book = {Prayer_Book, 0}; 220 | 221 | reset_flag = true; 222 | if (py.flags.blind > 0) { 223 | msg_print("You can't see to read your prayer!"); 224 | } else if (no_light()) { 225 | msg_print("You have no light to read by."); 226 | } else if (py.flags.confused > 0) { 227 | msg_print("You are too confused..."); 228 | } else if (class[py.misc.pclass].pspell) { 229 | if (inven_ctr > 0) { 230 | if (find_range(good_book,false,&i1,&i2)) { 231 | redraw = false; 232 | if (get_item(&item_ptr,"Use which Holy Book?", 233 | &redraw,i2,&trash_char,false,false)) { 234 | if (cast_spell("Recite which prayer?",item_ptr, 235 | &choice,&chance,&redraw)) { 236 | 237 | //with magic_spell[PM.pclass][choice]. do 238 | reset_flag = false; 239 | if (randint(100) < chance) { 240 | msg_print("You lost your concentration!"); 241 | } else { 242 | p__prayer_effects(choice); 243 | if (!reset_flag) { 244 | //with py.misc do; 245 | PM.exp += magic_spell[PM.pclass][choice].sexp; 246 | prt_experience(); 247 | magic_spell[PM.pclass][choice].sexp = 0; 248 | } 249 | } 250 | 251 | //with py.misc do; 252 | if (!reset_flag) { 253 | if (magic_spell[PM.pclass][choice].smana > PM.cmana) { 254 | msg_print("You faint from fatigue!"); 255 | py.flags.paralysis = 256 | randint(5*(magic_spell[PM.pclass][choice].smana-PM.cmana)); 257 | PM.cmana = 0; 258 | if (randint(3) == 1) { 259 | /*{XXXX does not check for sustain}*/ 260 | lower_stat(CON,"You have damaged your health!"); 261 | } 262 | } else { 263 | PM.cmana -= magic_spell[PM.pclass][choice].smana; 264 | } 265 | prt_mana(); 266 | } else { 267 | if (redraw) { 268 | draw_cave(); 269 | } 270 | } 271 | } 272 | } 273 | } else { 274 | msg_print("But you are not carrying any Holy Books!"); 275 | } 276 | } else { 277 | msg_print("But you are not carrying any Holy Books!"); 278 | } 279 | } else { 280 | msg_print("Pray hard enough and your prayers may be answered."); 281 | } 282 | }; 283 | /* END FILE prayer.c */ 284 | ////////////////////////////////////////////////////////////////////// 285 | ////////////////////////////////////////////////////////////////////// 286 | ////////////////////////////////////////////////////////////////////// 287 | -------------------------------------------------------------------------------- /random.c: -------------------------------------------------------------------------------- 1 | /* random.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include 6 | 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | ////////////////////////////////////////////////////////////////////// 10 | unsigned long get_seed() 11 | { 12 | // { Use date and time to produce a random seed -RAK- } 13 | struct timeval tv; 14 | unsigned long the_seed; 15 | 16 | ENTER("get_seed",""); 17 | 18 | gettimeofday(&tv, NULL); 19 | 20 | the_seed = tv.tv_usec ^ tv.tv_sec; 21 | 22 | // the_seed = 883993667; 23 | 24 | RETURN("get_seed","",'u',"rand seed",&the_seed); 25 | return the_seed; 26 | }; /* end get_seed */ 27 | ////////////////////////////////////////////////////////////////////// 28 | ////////////////////////////////////////////////////////////////////// 29 | ////////////////////////////////////////////////////////////////////// 30 | void set_seed(unsigned long the_seed) 31 | { 32 | /* use the_seed to seed the generator */ 33 | 34 | #if DO_DEBUG 35 | fprintf(debug_file,"set_seed: s= %ld\n",the_seed); 36 | fflush(debug_file); 37 | #endif 38 | 39 | #if USE_MTWIST 40 | seedMT(the_seed); 41 | #else 42 | srand(the_seed); 43 | #endif 44 | }; /* end get_seed */ 45 | ////////////////////////////////////////////////////////////////////// 46 | ////////////////////////////////////////////////////////////////////// 47 | ////////////////////////////////////////////////////////////////////// 48 | integer randnor(integer mean,integer stand) 49 | { 50 | /*{ Generates a random integer number of NORMAL distribution -RAK-}*/ 51 | 52 | return (integer)(sqrt(-2.0*log(randint(9999999)/10000000.0))* 53 | cos(6.283*(randint(9999999)/10000000.0))*stand) + mean; 54 | }; 55 | ////////////////////////////////////////////////////////////////////// 56 | ////////////////////////////////////////////////////////////////////// 57 | ////////////////////////////////////////////////////////////////////// 58 | integer rand_rep(integer num, integer die) 59 | { 60 | integer i1, sum=0; 61 | 62 | for (i1 = 0; i1 < num; i1++) { 63 | sum += randint(die); 64 | } 65 | 66 | return sum; 67 | }; 68 | ////////////////////////////////////////////////////////////////////// 69 | ////////////////////////////////////////////////////////////////////// 70 | ////////////////////////////////////////////////////////////////////// 71 | integer randint(integer maxval) 72 | { 73 | /* Generates a random integer x where 1<=X<=MAXVAL -RAK- */ 74 | 75 | integer r = 0; 76 | 77 | if (maxval) { 78 | #if USE_MTWIST 79 | r = ((randomMT() % maxval) + 1); 80 | #else 81 | r = ((rand() % maxval) + 1); 82 | #endif 83 | } 84 | 85 | /* 86 | #if DO_DEBUG 87 | fprintf(debug_file, " rand: %ld\t(%ld)\n", r, maxval); 88 | fflush(debug_file); 89 | #endif 90 | */ 91 | 92 | return r; 93 | }; 94 | ////////////////////////////////////////////////////////////////////// 95 | ////////////////////////////////////////////////////////////////////// 96 | ////////////////////////////////////////////////////////////////////// 97 | void *save_rand_state(void *randState) 98 | { 99 | #if USE_MTWIST 100 | return saveMTstate(randState); 101 | #else 102 | return NULL; 103 | #endif 104 | }; 105 | ////////////////////////////////////////////////////////////////////// 106 | ////////////////////////////////////////////////////////////////////// 107 | ////////////////////////////////////////////////////////////////////// 108 | void restore_rand_state(void *randState) 109 | { 110 | #if USE_MTWIST 111 | if (randState != NULL) { 112 | restoreMTstate(randState); 113 | free(randState); 114 | } 115 | #endif 116 | }; 117 | ////////////////////////////////////////////////////////////////////// 118 | ////////////////////////////////////////////////////////////////////// 119 | ////////////////////////////////////////////////////////////////////// 120 | 121 | /* END FILE random.c */ 122 | -------------------------------------------------------------------------------- /run_gdb.pl: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | 3 | $prog_name = shift; 4 | $prog_name = "i2" if $prog_name eq ""; 5 | 6 | open (PROCESSES, "ps -ax |") || die "unable to open pipe from ps\n"; 7 | 8 | while () { 9 | next if /grep/; 10 | next if /perl/; 11 | if ( /$prog_name/ ) { 12 | #print "looking in $_"; 13 | if ( /^\s*(\d+)\s+/ ) { 14 | #print "$1\n"; 15 | #exit 0; 16 | close(PROCESSES); 17 | exec "/usr/bin/gdb $prog_name $1 -x GDB_di"; 18 | } 19 | } 20 | } 21 | close(PROCESSES); 22 | 23 | print "Unable to find $prog_name running.\n"; 24 | 25 | __END__ 26 | -------------------------------------------------------------------------------- /sing.c: -------------------------------------------------------------------------------- 1 | /* sing.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "dungeon.h" 6 | ////////////////////////////////////////////////////////////////////// 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | void s__bard_effects(integer effect) 10 | { 11 | /*{ Songs.... }*/ 12 | integer i2,i3,dir; 13 | integer dumy,y_dumy,x_dumy; 14 | 15 | y_dumy = char_row; 16 | x_dumy = char_col; 17 | 18 | switch (effect+1) { 19 | 20 | case 1 : /*{ Detect Monster }*/ 21 | detect_creatures(c_monster); 22 | break; 23 | 24 | case 2 : /*{ Battle Song }*/ 25 | bless(randint(12)+12); 26 | break; 27 | 28 | case 3 : /*{ Blink }*/ 29 | teleport(10); 30 | break; 31 | 32 | case 4 : /*{ Light }*/ 33 | light_area(char_row,char_col); 34 | break; 35 | 36 | case 5 : /*{ Detect Doors }*/ 37 | detect_sdoor(); 38 | detect_trap(); 39 | break; 40 | 41 | case 6 : /*{ Magical Jig }*/ 42 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 43 | zap_monster(dir,char_row,char_col,0,c_confuse); 44 | } 45 | break; 46 | 47 | case 7 : /*{ Detect Magic }*/ 48 | detect_magic(); 49 | break; 50 | 51 | case 8 : /*{ Minor Cure }*/ 52 | hp_player(damroll("5d3"),"a magic spell."); 53 | break; 54 | 55 | case 9 : /*{ Battle Dance }*/ 56 | py.flags.hero += (randint(10) +5); 57 | bless(randint(20)+20); 58 | break; 59 | 60 | case 10 : /*{ Charm Monsters }*/ 61 | sleep_monsters1(char_row,char_col); 62 | break; 63 | 64 | case 11 : /*{ Detect Curse }*/ 65 | detect_curse(); 66 | break; 67 | 68 | case 12 : /*{ Detect Invisible }*/ 69 | detect_creatures(c_invisible); 70 | break; 71 | 72 | case 13 : /*{ Cure Poison }*/ 73 | cure_me(&(py.flags.poisoned)); 74 | break; 75 | 76 | case 14 : /*{ Invisibility }*/ 77 | py.flags.temp_stealth += randint(15)+10; 78 | break; 79 | 80 | case 15 : /*{ Teleport Self }*/ 81 | teleport(py.misc.lev*6); 82 | break; 83 | 84 | case 16 : /*{ Infravision }*/ 85 | py.flags.tim_infra += randint(50) + 50; 86 | break; 87 | 88 | case 17 : /*{ Physical Humor }*/ 89 | if (d__get_dir("Which diretion?",&dir,&dumy,&y_dumy,&x_dumy)) { 90 | fire_bolt(c_joke,dir,char_row,char_col,damroll("3d8"), 91 | "punch line"); 92 | } 93 | break; 94 | 95 | case 18 : /*{ Recharge Item }*/ 96 | recharge(20); 97 | break; 98 | 99 | case 19 : /*{ Remove Curse }*/ 100 | for (i2 = Equipment_min ; i2 <= EQUIP_MAX-1 ; i2++) { 101 | //with equipment[i2] do; 102 | equipment[i2].flags &= 0x7FFFFFFF; 103 | } 104 | break; 105 | 106 | case 20 : /*{ Legend Lore }*/ 107 | ident_spell(); 108 | break; 109 | 110 | case 21 : /*{ Mass Charm }*/ 111 | zap_area(0,0,c_sleep); 112 | break; 113 | 114 | case 22 : /*{ Detect Treasure }*/ 115 | detect_item(c_treasure); 116 | break; 117 | 118 | case 23 : /*{ Detect Object }*/ 119 | detect_item(c_object); 120 | break; 121 | 122 | case 24 : /*{ Resist Petrification }*/ 123 | py.flags.resist_petri += randint(15) + 10; 124 | break; 125 | 126 | case 25 : /*{ Create Food and Drink }*/ 127 | create_food(3,9,1,0,0); 128 | break; 129 | 130 | case 26 : /*{ Panic }*/ 131 | msg_print("You scare the creatures!"); 132 | zap_area(0,0,c_confuse); 133 | break; 134 | 135 | case 27 : /*{ Word of Recall }*/ 136 | py.flags.word_recall = randint(20) + 20; 137 | break; 138 | 139 | case 28 : /*{ Protection from Nature }*/ 140 | //with py.flags do; 141 | PF.resist_heat += randint(15) +10; 142 | PF.resist_cold += randint(15) +10; 143 | PF.resist_lght += randint(15) +10; 144 | break; 145 | 146 | case 29 : /*{ See Invisible }*/ 147 | detect_inv2(randint(24)+24); 148 | break; 149 | 150 | case 30 : /*{ Magic Mapping }*/ 151 | map_area(); 152 | break; 153 | 154 | case 31 : /*{ Joke of Death }*/ 155 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 156 | fire_ball(c_joke,dir,char_row,char_col,30,"terrible joke"); 157 | } 158 | break; 159 | 160 | case 32 : /*{ Battle Frenzy }*/ 161 | bless(randint(30)+30); 162 | py.flags.hero = randint(30)+30; 163 | py.flags.shero = randint(30)+30; 164 | break; 165 | 166 | case 33 : /*{ Slow Creature }*/ 167 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 168 | zap_monster(dir,char_row,char_col,-1,c_speed); 169 | } 170 | break; 171 | 172 | case 34 : /*{ Resist Charm }*/ 173 | //with py.flags do; 174 | PF.free_time += randint(10) + py.misc.lev; 175 | PF.magic_prot += randint(10) + py.misc.lev; 176 | break; 177 | 178 | case 35 : /*{ Item Lore }*/ 179 | lore_spell(); 180 | break; 181 | 182 | case 36 : /*{ Song of Protection }*/ 183 | py.flags.protmon = (randint(20)+py.misc.lev ); 184 | protect_evil(); 185 | bless(randint(24)+24); 186 | break; 187 | 188 | case 37 : /*{ Last Laugh }*/ 189 | zap_area(0,50,c_joke); 190 | break; 191 | 192 | case 38 : /*{ Teleport Level }*/ 193 | dun_level += 2*randint(2) - 3; 194 | if (dun_level < 1) { 195 | dun_level = 1; 196 | } 197 | moria_flag = true; 198 | break; 199 | 200 | case 39 : /*{ Clairvoyance }*/ 201 | redraw = true; 202 | wizard_light(); 203 | for (i2 = (char_col + 1); i2 <= (char_col - 1); i2++) { 204 | for (i3 = (char_row + 1); i3 <= (char_row - 1); i3++) { 205 | if (test_light(i3,i2)) { 206 | redraw = false; 207 | } 208 | } 209 | } 210 | if (redraw) { 211 | wizard_light(); 212 | } 213 | break; 214 | 215 | case 40 : /*{ Song of Power }*/ 216 | zap_area(0x0006,4*py.misc.lev,c_hp); 217 | cure_me(&(py.flags.poisoned)); 218 | hp_player(300, "a spell"); 219 | cure_me(&py.flags.blind); 220 | break; 221 | 222 | default: 223 | break; 224 | } 225 | /*{ End of songs... }*/ 226 | }; 227 | ////////////////////////////////////////////////////////////////////// 228 | void sing() 229 | { 230 | /*{ Sing a Bard song -CAPN/DMF- }*/ 231 | 232 | integer i2; 233 | treas_ptr i1,item_ptr; 234 | integer choice,chance; 235 | char trash_char; 236 | boolean redraw; 237 | obj_set song_books = {Song_Book, 0}; 238 | 239 | reset_flag = true; 240 | if (py.flags.hoarse > 0) { 241 | msg_print("You are too hoarse to sing!"); 242 | } else if (py.flags.afraid > 0) { 243 | msg_print("You are too scared to play music!"); 244 | } else if (py.flags.confused > 0) { 245 | msg_print("You are too confused..."); 246 | } else if (class[py.misc.pclass].bspell) { 247 | if (inven_ctr > 0) { 248 | if (find_range(song_books,false,&i1,&i2)) { 249 | redraw = false; 250 | if (get_item(&item_ptr,"Use which Instrument?", 251 | &redraw,i2,&trash_char,false,false)) { 252 | if (cast_spell("Play which song?",item_ptr, 253 | &choice,&chance,&redraw)) { 254 | //with magic_spell[py.misc.pclass][choice]. do; 255 | reset_flag = false; 256 | if (randint(100) < chance) { 257 | switch (randint(5)) { 258 | case 1 : msg_print("*Squak*"); break; 259 | case 2 : msg_print("*Gag!*"); break; 260 | case 3 : msg_print("*Aaugh!*"); break; 261 | case 4 : msg_print("*Yargh!*"); break; 262 | case 5 : msg_print("*Cough!*"); break; 263 | } ; /*{ of the bad notes }*/ 264 | switch (randint(2)) { 265 | case 1 : msg_print("You sing a sour note!");break; 266 | case 2 : msg_print("You sing an awful note!");break; 267 | } 268 | } else { 269 | s__bard_effects(choice); 270 | if (!reset_flag) { 271 | //with py.misc do; 272 | PM.exp += magic_spell[py.misc.pclass][choice].sexp; 273 | prt_experience(); 274 | magic_spell[py.misc.pclass][choice].sexp = 0; 275 | } 276 | } 277 | //with py.misc do; 278 | if (!reset_flag) { 279 | if (magic_spell[py.misc.pclass][choice].smana > PM.cmana) { 280 | msg_print("You lose your voice attempting the song!"); 281 | py.flags.hoarse = 282 | randint(5*trunc(magic_spell[py.misc.pclass][choice].smana-PM.cmana)); 283 | PM.cmana = 0; 284 | if (randint(3) == 1) { 285 | lower_stat(CHR,"Your self-esteem is lowered!"); 286 | } 287 | } else { 288 | PM.cmana -= magic_spell[py.misc.pclass][choice].smana; 289 | } 290 | prt_mana(); 291 | } 292 | } 293 | } else { 294 | if (redraw) { 295 | draw_cave(); 296 | } 297 | } 298 | } else { 299 | msg_print("But you are not carrying any Instruments!"); 300 | } 301 | } else { 302 | msg_print("But you are not carrying any Instruments!"); 303 | } 304 | } else { 305 | switch (bard_adj()+randint(4)) { 306 | case 1: case 2 : msg_print("You utter a gutteral cry."); break; 307 | case 3: case 4 : msg_print("You mumble a simple tune."); break; 308 | case 5: case 6 : msg_print("You sing a fair song."); break; 309 | case 7: case 8 : msg_print("You sing a very nice song."); break; 310 | case 9: case 10: case 11 :msg_print("You sing quite beautifully.");break; 311 | } 312 | } 313 | 314 | }; 315 | /* END FILE sing.c */ 316 | ////////////////////////////////////////////////////////////////////// 317 | ////////////////////////////////////////////////////////////////////// 318 | ////////////////////////////////////////////////////////////////////// 319 | -------------------------------------------------------------------------------- /slots.c: -------------------------------------------------------------------------------- 1 | /* slots.c */ 2 | /* slot machine code for the casino */ 3 | 4 | #include "imoria.h" 5 | #include "casino.h" 6 | #include "slots.h" 7 | 8 | char *s_name[6] = {"jackpot", "cherry", "orange", "bell", "bar"}; 9 | slot slotpos; 10 | 11 | 12 | void sm__display_slot_options() 13 | { 14 | prt(" ------------------------------------------- ",2,11); 15 | prt("| | _-_ ", 3,11); 16 | prt("| | / \\ ",4,11); 17 | prt("| XXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXX | ( ) ",5,11); 18 | prt("| X X X X X X | \\ _ / ",6,11); 19 | prt("| X X X X X X | | | ",7,11); 20 | prt("| X X X X X X | | | ",8,11); 21 | prt("| XXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXX | | | ",9,11); 22 | prt("| | | | ",10,11); 23 | prt("| X X X | | | ",11,11); 24 | prt("| XXX XXX XXX |__/ | ",12,11); 25 | prt("| X X X | | ",13,11); 26 | prt("| |____/ ",14,11); 27 | prt("| | ",15,11); 28 | prt("| | ",16,11); 29 | prt("| | ",17,11); 30 | prt(" -------------------------------------------",18,11); 31 | 32 | prt("You may:",21,1); 33 | prt(" p) pull lever. d) display prizes.",22,2); 34 | prt("^R) Redraw the screen. Esc) Return to main menu.",23,2); 35 | }; 36 | 37 | 38 | void sm__position_adjust(integer *c1, integer *c2, integer *c3) 39 | { 40 | /* Centers slots in middle of box */ 41 | 42 | *c1 = 15; 43 | *c2 = 29; 44 | *c3 = 43; 45 | 46 | // if (slotpos[1] > 1) { *c1 = 14; } 47 | // if (slotpos[2] > 1) { *c2 = 28; } 48 | // if (slotpos[3] > 1) { *c3 = 42; } 49 | }; 50 | 51 | 52 | 53 | void sm__display_slots() 54 | { 55 | vtype out_val; 56 | integer c1,c2,c3; 57 | 58 | clear_screen(); 59 | sm__display_slot_options(); 60 | sm__position_adjust(&c1,&c2,&c3); 61 | sprintf(out_val,"%s",s_name[slotpos[1]]); 62 | put_buffer(out_val,7,c1); 63 | sprintf(out_val,"%s",s_name[slotpos[2]]); 64 | put_buffer(out_val,7,c2); 65 | sprintf(out_val,"%s",s_name[slotpos[3]]); 66 | put_buffer(out_val,7,c3); 67 | c__display_gold(); 68 | }; 69 | 70 | 71 | 72 | void sm__display_prizes() 73 | { 74 | char command; 75 | boolean exit; 76 | 77 | clear_screen(); 78 | prt(" 1 2 5 10 25 50 ",4,1); 79 | prt("jackpot jackpot jackpot 1000 2000 5000 1000 25000 50000",6,1); 80 | prt(" bar bar bar 30 60 150 300 750 1500",7,1); 81 | prt(" bell bell bell 15 30 75 150 375 750",8,1); 82 | prt(" orange orange orange 8 16 40 80 200 400",9,1); 83 | prt(" cherry cherry cherry 4 8 20 40 100 200",10,1); 84 | prt(" bell --- bell 4 8 20 40 100 200",11,1); 85 | prt(" --- bar bar 4 8 20 40 100 200",12,1); 86 | prt(" --- orange orange 2 4 10 20 50 100",13,1); 87 | prt(" jackpot --- --- 2 4 10 20 50 100",14,1); 88 | prt(" cherry cherry --- 1 2 5 10 25 50",15,1); 89 | prt("[hit any key to continue]",22,27); 90 | exit = get_com("",&command); 91 | sm__display_slots(); 92 | }; 93 | 94 | 95 | 96 | 97 | void sm__get_slots() 98 | { 99 | integer c; 100 | 101 | /* Wheel one */ 102 | c = randint(20); 103 | if (c >= 20) { 104 | slotpos[1] = S_JACKPOT; 105 | } else if (c >= 17) { 106 | slotpos[1] = S_BAR; 107 | } else if (c >= 13) { 108 | slotpos[1] = S_BELL; 109 | } else if (c >= 8) { 110 | slotpos[1] = S_ORANGE; 111 | } else if (c >= 1) { 112 | slotpos[1] = S_CHERRY; 113 | } 114 | 115 | 116 | /* Wheel two */ 117 | c = randint(20); 118 | if (c >= 20) { 119 | slotpos[2] = S_JACKPOT; 120 | } else if (c >= 17) { 121 | slotpos[2] = S_BAR; 122 | } else if (c >= 11) { 123 | slotpos[2] = S_BELL; 124 | } else if (c >= 7) { 125 | slotpos[2] = S_ORANGE; 126 | } else if (c >= 1) { 127 | slotpos[2] = S_CHERRY; 128 | } 129 | 130 | /* Wheel three */ 131 | c = randint(20); 132 | if (c >= 20) { 133 | slotpos[3] = S_JACKPOT; 134 | } else if (c >= 16) { 135 | slotpos[3] = S_BAR; 136 | } else if (c >= 13) { 137 | slotpos[3] = S_BELL; 138 | } else if (c >= 7) { 139 | slotpos[3] = S_ORANGE; 140 | } else if (c >= 1) { 141 | slotpos[3] = S_CHERRY; 142 | } 143 | }; 144 | 145 | 146 | void sm__clearslots(integer line) 147 | { 148 | /* clears a line of slots */ 149 | 150 | vtype killpos; 151 | 152 | strcpy(killpos, " "); 153 | put_buffer(killpos,line,15); 154 | put_buffer(killpos,line,29); 155 | put_buffer(killpos,line,43); 156 | }; 157 | 158 | 159 | void sm__print_slots() 160 | { 161 | /* Simulates wheel spinning */ 162 | 163 | integer i; 164 | integer c1,c2,c3; 165 | vtype out_val; 166 | 167 | sm__get_slots(); /* {get new slots} */ 168 | 169 | for (i = 1; i <= 9; i++) { 170 | sm__clearslots(7); /* {clear middle row} */ 171 | sm__position_adjust(&c1,&c2,&c3); /* {center bar and bell} */ 172 | 173 | sprintf(out_val,"%s",s_name[slotpos[1]]); 174 | put_buffer(out_val,8,c1); 175 | sprintf(out_val,"%s",s_name[slotpos[2]]); /*{print bottom}*/ 176 | put_buffer(out_val,8,c2); 177 | sprintf(out_val,"%s",s_name[slotpos[3]]); 178 | put_buffer(out_val,8,c3); 179 | 180 | sm__get_slots(); /*{get new slots}*/ 181 | sm__position_adjust(&c1,&c2,&c3); 182 | 183 | sprintf(out_val,"%s",s_name[slotpos[1]]); 184 | put_buffer(out_val,6,c1); 185 | sprintf(out_val,"%s",s_name[slotpos[2]]); /*{print top row}*/ 186 | put_buffer(out_val,6,c2); 187 | sprintf(out_val,"%s",s_name[slotpos[3]]); 188 | put_buffer(out_val,6,c3); 189 | 190 | put_qio(); 191 | usleep(50); 192 | sm__clearslots(6); /*{clear top row}*/ 193 | put_qio(); 194 | usleep(50); 195 | sm__clearslots(8); /*{clear bottom row}*/ 196 | 197 | sprintf(out_val,"%s",s_name[slotpos[1]]); 198 | put_buffer(out_val,7,c1); 199 | sprintf(out_val,"%s",s_name[slotpos[2]]); /*{print middle row}*/ 200 | put_buffer(out_val,7,c2); 201 | sprintf(out_val,"%s",s_name[slotpos[3]]); 202 | put_buffer(out_val,7,c3); 203 | 204 | put_qio(); 205 | usleep(100); 206 | } 207 | }; 208 | 209 | void sm__winnings() 210 | { 211 | /* calculates the amount won */ /* Currently, odds slightly favor */ 212 | /* the user. Return of 101% */ 213 | 214 | vtype out_val; 215 | vtype comment,comment1; 216 | integer winning; 217 | 218 | strcpy(comment, "You have won "); 219 | strcpy(comment1, " gold pieces!"); 220 | 221 | winning = 0; 222 | if ((slotpos[1]==slotpos[2]) && (slotpos[1]==S_CHERRY)) { winning = bet; } 223 | if ((slotpos[1]==S_JACKPOT)) { winning = bet*2; } 224 | if ((slotpos[2]==slotpos[3]) && (slotpos[2]==S_ORANGE)) { winning = 2*bet; } 225 | if ((slotpos[1]==slotpos[3]) && (slotpos[1]==S_BELL)) { winning = 4*bet; } 226 | if ((slotpos[2]==slotpos[3]) && (slotpos[2]==S_BAR)) { winning = 4*bet; } 227 | 228 | if ((slotpos[1]==slotpos[2]) && (slotpos[1]==slotpos[3])) { 229 | switch (slotpos[1]) { 230 | case S_JACKPOT : winning = 1000*bet; break; 231 | case S_CHERRY : winning = 4*bet; break; 232 | case S_ORANGE : winning = 8*bet; break; 233 | case S_BELL : winning = 15*bet; break; 234 | case S_BAR : winning = 30*bet; break; 235 | } 236 | } 237 | 238 | if (winning == 0) { 239 | switch (randint(5)) { 240 | case 1 : msg_print("You lose. "); break; 241 | case 2 : msg_print("Your money pouch feels a little lighter."); break; 242 | case 3 : msg_print("Rats! Lost again! "); break; 243 | case 4 : msg_print("The casino owner becomes richer. "); break; 244 | case 5 : msg_print("Apparently you don't know the secret to winning at slots."); break; 245 | } 246 | } else { 247 | if (winning > bet) { 248 | switch (randint(5)) { 249 | case 1 : msg_print("Hmmm...Maybe this system really works...");break; 250 | case 2 : msg_print("Maybe you should quit while you''re ahead.");break; 251 | case 3 : msg_print("Coins begin to pour out of the machine.");break; 252 | case 4 : msg_print("You're not cheating, are you?");break; 253 | case 5 : msg_print("Be sure to report your winnings!");break; 254 | } 255 | sprintf(out_val, "%s%ld%s", comment, winning, comment1); 256 | msg_print(out_val); 257 | } else { 258 | msg_print("You break even."); 259 | } 260 | gld += winning; 261 | } 262 | }; 263 | 264 | 265 | 266 | void sm__get_slots_bet() 267 | { 268 | vtype comment; 269 | integer num; 270 | boolean exit_flag = false; 271 | 272 | strcpy(comment, "Which machine (1 to 10000 gp)? "); 273 | 274 | do { 275 | if (c__get_response(comment, &num)) { 276 | bet = num; 277 | if ((bet>0) && (bet<10001)) { 278 | exit_flag = true; 279 | } else { 280 | prt("Improper value.",1,1); 281 | } 282 | } else { 283 | exit_flag = true; 284 | bet = 0; 285 | } 286 | } while (!exit_flag); 287 | 288 | if (bet > gld) { 289 | prt("You have not the gold!",1,1); 290 | bet = 0; 291 | } 292 | }; 293 | 294 | 295 | void sm__slot_commands() 296 | { 297 | char command; 298 | boolean exit_flag = false; 299 | 300 | bet = 0; 301 | 302 | do { 303 | if (get_com("", &command)) { 304 | switch (command) { 305 | case 112 : sm__get_slots_bet(); break; 306 | case 18 : sm__display_slots(); break; 307 | case 100 : sm__display_prizes(); break; 308 | default : prt("Invalid Command.",1,1); break; 309 | } 310 | } else { 311 | exit_flag = true; 312 | } 313 | 314 | if (bet > 0) { 315 | gld -= bet; 316 | sm__print_slots(); 317 | sm__winnings(); 318 | bet = 0; 319 | c__display_gold(); 320 | } 321 | c__check_casino_kickout(); 322 | } while (!exit_flag); 323 | }; 324 | 325 | 326 | 327 | void sm__game_slots() 328 | { 329 | clear_screen(); 330 | slotpos[1] = S_JACKPOT; 331 | slotpos[2] = S_JACKPOT; 332 | slotpos[3] = S_JACKPOT; 333 | sm__display_slots(); 334 | prt("You are standing in front of a row of odd looking machines.",1,1); 335 | sm__slot_commands(); 336 | } 337 | 338 | 339 | /* END FILE slots.c */ 340 | -------------------------------------------------------------------------------- /slots.h: -------------------------------------------------------------------------------- 1 | /* slots.h */ 2 | /* declarations for the slot machine module in the casino */ 3 | 4 | #define xS_JACKPOT 1 5 | #define xS_CHERRY 2 6 | #define xS_ORANGE 3 7 | #define xS_BELL 4 8 | #define xS_BAR 5 9 | 10 | #define S_JACKPOT 0 11 | #define S_CHERRY 1 12 | #define S_ORANGE 2 13 | #define S_BELL 3 14 | #define S_BAR 4 15 | 16 | typedef integer stype; /* stype = (jackpot,cherry,orange,bell,bar);*/ 17 | typedef stype slot[4]; /* slot = array[1..3] of stype;*/ 18 | 19 | extern void sm__game_slots(); 20 | 21 | /* END FILE slots.h */ 22 | -------------------------------------------------------------------------------- /staffs.c: -------------------------------------------------------------------------------- 1 | /* staffs.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "dungeon.h" 6 | 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | ////////////////////////////////////////////////////////////////////// 10 | void us__staff_effect(integer effect, boolean *idented) 11 | { 12 | integer i3,randnum; 13 | integer y,x; 14 | boolean ident; 15 | 16 | 17 | ident = *idented; 18 | 19 | /*{ Staffs... }*/ 20 | 21 | switch (effect) { 22 | 23 | case 1 : 24 | ident = light_area(char_row,char_col); 25 | break; 26 | 27 | case 2 : 28 | ident = detect_sdoor(); 29 | break; 30 | 31 | case 3 : 32 | ident = detect_trap(); 33 | break; 34 | 35 | case 4 : 36 | ident = detect_item(c_treasure); 37 | break; 38 | 39 | case 5 : 40 | ident = detect_item(c_object); 41 | break; 42 | 43 | case 6 : 44 | teleport(100); 45 | ident = true; 46 | break; 47 | 48 | case 7 : 49 | ident = earthquake(); 50 | break; 51 | 52 | case 8 : 53 | for (randnum=randint(4),i3 = 0; i3 < randnum; i3++) { 54 | y = char_row; 55 | x = char_col; 56 | if (is_in(cave[y][x].fval, water_set)) { 57 | summon_water_monster(&y,&x,false); 58 | } else { 59 | summon_land_monster(&y,&x,false); 60 | } 61 | } 62 | ident = true; 63 | break; 64 | 65 | case 9 : 66 | ident = genocide(); 67 | break; 68 | 69 | case 10 : 70 | ident = destroy_area(char_row,char_col); 71 | break; 72 | 73 | case 11 : 74 | msg_print("The end of the staff bursts into a blue shimmering light."); 75 | ident = starlite(char_row,char_col); 76 | break; 77 | 78 | case 12 : 79 | ident = zap_area(0,1,c_speed); /*{haste}*/ 80 | break; 81 | 82 | case 13 : 83 | ident = zap_area(0,-1,c_speed); /*{slow}*/ 84 | break; 85 | 86 | case 14 : 87 | ident = zap_area(0,0,c_sleep); 88 | break; 89 | 90 | case 15 : 91 | ident = hp_player(randint(8),"a staff."); 92 | break; 93 | 94 | case 16 : 95 | ident = detect_creatures(c_invisible); 96 | break; 97 | 98 | case 17 : 99 | py.flags.fast += randint(30) + 15; 100 | ident = true; 101 | break; 102 | 103 | case 18 : 104 | py.flags.slow += randint(30) + 15; 105 | ident = true; 106 | break; 107 | 108 | case 19 : 109 | ident = mass_poly(); 110 | break; 111 | 112 | case 20 : 113 | if (remove_curse()) { 114 | msg_print("The staff glows blue for a moment..."); 115 | ident = true; 116 | } 117 | break; 118 | 119 | case 21 : 120 | ident = detect_creatures(c_evil); 121 | break; 122 | 123 | case 22 : 124 | //with py.flags do; 125 | ident = cure_me(&(PF.blind)); 126 | ident |= cure_me(&(PF.poisoned)); 127 | ident |= cure_me(&(PF.confused)); 128 | break; 129 | 130 | case 23 : 131 | ident = zap_area(0x0004,60,c_hp); 132 | break; 133 | 134 | case 24 : 135 | ident = mass_genocide(); 136 | break; 137 | 138 | case 25 : 139 | ident = unlight_area(char_row,char_col); 140 | break; 141 | 142 | case 26 : 143 | ident = ident_spell(); 144 | break; 145 | 146 | default: 147 | break; 148 | 149 | } 150 | /*{ End of staff actions... }*/ 151 | 152 | *idented = ident; 153 | }; 154 | ////////////////////////////////////////////////////////////////////// 155 | void use_staff() 156 | { 157 | /*{ Use a staff... -RAK- }*/ 158 | 159 | unsigned long i1; 160 | integer i3,chance,i4; 161 | treas_ptr i2,item_ptr; 162 | char trash_char; 163 | boolean redraw,ident; 164 | obj_set this_be_a_staff = {staff, 0}; 165 | 166 | 167 | reset_flag = true; 168 | 169 | if (inven_ctr > 0) { 170 | if (find_range(this_be_a_staff,false,&i2,&i3)) { 171 | 172 | redraw = false; 173 | if (get_item(&item_ptr,"Use which staff?", 174 | &redraw,i3,&trash_char,false,false)) { 175 | //with item_ptr^.data do; 176 | 177 | if (redraw) { 178 | draw_cave(); 179 | } 180 | reset_flag = false; 181 | 182 | //with py.misc do; 183 | chance = PM.save + PM.lev + spell_adj(INT) - item_ptr->data.level - 5; 184 | 185 | if (py.flags.confused > 0) { 186 | chance /= 2; 187 | } 188 | if (chance < 0) { 189 | chance = 0; 190 | } 191 | 192 | if (randint(chance) < USE_DEVICE) { 193 | msg_print("You failed to use the staff properly."); 194 | } else if (item_ptr->data.p1 > 0) { 195 | i1 = item_ptr->data.flags; 196 | ident = false; 197 | item_ptr->data.p1--; 198 | for ( ; i1 > 0 ; ) { 199 | i4 = bit_pos(&i1) + 1; 200 | 201 | 202 | us__staff_effect(i4, &ident); 203 | } 204 | identify(&(item_ptr->data)); 205 | if (ident) { 206 | if (item_ptr->data.flags != 0) { 207 | //with py.misc do; 208 | PM.exp += (item_ptr->data.level / (real)PM.lev) + .5; 209 | prt_experience(); 210 | } 211 | } 212 | desc_charges(item_ptr); 213 | } 214 | 215 | } else { 216 | if (redraw) { 217 | draw_cave(); 218 | } 219 | } 220 | } else { 221 | msg_print("You are not carrying any staffs."); 222 | } 223 | } else { 224 | msg_print("But you are not carrying anything."); 225 | } 226 | }; 227 | ////////////////////////////////////////////////////////////////////// 228 | ////////////////////////////////////////////////////////////////////// 229 | ////////////////////////////////////////////////////////////////////// 230 | 231 | /* END FILE staffs.c */ 232 | ////////////////////////////////////////////////////////////////////// 233 | ////////////////////////////////////////////////////////////////////// 234 | ////////////////////////////////////////////////////////////////////// 235 | -------------------------------------------------------------------------------- /term.h: -------------------------------------------------------------------------------- 1 | /* term.h */ 2 | 3 | typedef unsigned char int8u; 4 | 5 | void moriaterm(); 6 | void clear_screen(); 7 | void save_screen(); 8 | void restore_screen(); 9 | void restore_term(); 10 | void bell(); 11 | 12 | /* Dungeon size parameters */ 13 | #define MAX_HEIGHT 66 /* Multiple of 11; >= 22 */ 14 | #define MAX_WIDTH 198 /* Multiple of 33; >= 66 */ 15 | 16 | #undef CTRL_ 17 | #define CTRL_(x) (x & 0x1F) 18 | #define DELETE 0x7f 19 | #define ESCAPE '\033' /* ESCAPE character -CJS- */ 20 | 21 | /* message line location */ 22 | #define MSG_LINE -1 23 | 24 | #define CNIL (char *)0 25 | 26 | /* number of messages to save in a buffer */ 27 | #define MAX_SAVE_MSG 22 /* How many messages to save -CJS- */ 28 | 29 | int screen_change; 30 | int command_count; 31 | int eof_flag; 32 | int character_generated, character_saved; 33 | int sound_beep_flag; 34 | int panic_save; 35 | FILE *highscore_fp; 36 | 37 | 38 | 39 | /* end file term.h */ 40 | -------------------------------------------------------------------------------- /termdef.c: -------------------------------------------------------------------------------- 1 | /* termdef.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | 6 | 7 | void termdef() 8 | { 9 | 10 | }; 11 | 12 | /* END FILE termdef.c */ 13 | -------------------------------------------------------------------------------- /trade.h: -------------------------------------------------------------------------------- 1 | /* trade.h */ 2 | /* routines to handle the trading post */ 3 | 4 | ////////////////////////////////////////////////////////////////////// 5 | ////////////////////////////////////////////////////////////////////// 6 | ////////////////////////////////////////////////////////////////////// 7 | 8 | #define T_DISPLAY_SIZE 12 9 | #define T_ACCEPTABLE_ITEM_PRICE 50 10 | #define T_PROFIT_FROM_BID 0.05 11 | #define T_PROFIT_FROM_SALE 0.25 12 | #define T_REFUND_ON_BID (1.00 - T_PROFIT_FROM_BID) 13 | #define T_REFUND_ON_SALE (1.00 - T_PROFIT_FROM_SALE) 14 | #define T_BID_INCREMENT_FACTOR 1.05 15 | #define T_TAKE_THE_MONEY_AND_RUN 0.90 16 | #define T_BID_WAIT_DAYS 0 17 | #define T_BID_WAIT_HOURS 6 18 | #define T_EXPIRE_TIME_DAYS 4 19 | #define T_EXPIRE_TIME_HOURS 0 20 | 21 | #define TT_PROFIT 0 22 | #define TT_FOR_SALE 1 23 | #define TT_CASH 2 24 | 25 | typedef struct trade_account_type 26 | { 27 | uid_t uid; 28 | char username[13]; 29 | integer master_id; 30 | integer claim_check; 31 | } trade_account_type; 32 | 33 | typedef struct profit_record 34 | { 35 | integer trade_type; 36 | integer time; 37 | integer money; 38 | } profit_record; 39 | 40 | typedef struct for_sale_record 41 | { 42 | integer trade_type; 43 | integer time; 44 | treasure_type object; 45 | trade_account_type seller; 46 | integer bid_time; 47 | integer best_bid; 48 | trade_account_type best_bidder; 49 | } for_sale_record; 50 | 51 | typedef struct cash_record 52 | { 53 | integer trade_type; 54 | integer time; 55 | integer amount; 56 | trade_account_type owner; 57 | } cash_record; 58 | 59 | typedef union trade_record_type 60 | { 61 | struct profit_record pr; 62 | struct for_sale_record fsr; 63 | struct cash_record cr; 64 | } trade_record_type; 65 | 66 | typedef struct pinven_record 67 | { 68 | struct pinven_record *prev; 69 | struct pinven_record *next; 70 | trade_record_type data; 71 | } pinven_record; 72 | 73 | typedef pinven_record *pinven_ptr; 74 | 75 | #define ROUND(x) ((integer)((x)+.5)) 76 | 77 | extern boolean trade_file_open(FILE **tf, boolean *busy, boolean create); 78 | extern void trade_file_close(FILE **tf); 79 | extern void enter_trading_post(); 80 | 81 | ////////////////////////////////////////////////////////////////////// 82 | ////////////////////////////////////////////////////////////////////// 83 | ////////////////////////////////////////////////////////////////////// 84 | /* END FILE trade.h */ 85 | -------------------------------------------------------------------------------- /unix.c: -------------------------------------------------------------------------------- 1 | /* unix/unix.c: UNIX dependent code. -CJS- 2 | 3 | Copyright (c) 1989-91 James E. Wilson, Christopher J. Stuart 4 | 5 | This software may be copied and distributed for educational, research, and 6 | not for profit purposes provided that this copyright and statement are 7 | included in all such copies. */ 8 | 9 | 10 | /* defines NULL */ 11 | #include 12 | /* defines CTRL */ 13 | #include 14 | /* defines TRUE and FALSE */ 15 | #include 16 | #include 17 | 18 | #if 0 19 | #include "config.h" 20 | #include "constant.h" 21 | #include "types.h" 22 | #endif 23 | 24 | #include "term.h" 25 | 26 | #if defined(unix) || defined(__NetBSD__) 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | 34 | #if defined(SYS_V) && defined(lint) 35 | /* for AIX, prevent hundreds of unnecessary lint errors, must define before 36 | signal.h is included */ 37 | #define _h_IEEETRAP 38 | typedef struct { int stuff; } fpvmach; 39 | #endif 40 | 41 | #include 42 | 43 | #ifdef M_XENIX 44 | #include 45 | #include 46 | /* For various selects from TCP/IP. */ 47 | #define bzero(addr,n) memset((char *)addr, 0, n) 48 | #endif 49 | 50 | #ifndef USG 51 | #include 52 | #include 53 | #include 54 | #include 55 | #endif 56 | 57 | #ifdef __linux__ 58 | #include 59 | #include 60 | #include 61 | #endif 62 | 63 | #ifdef USG 64 | #include 65 | #if 0 66 | /* Used to include termio.h here, but this is unnecessary because it is 67 | included in curses.h, and some systems fail when it gets included 68 | twice. */ 69 | #include 70 | #endif 71 | #include 72 | #else 73 | #include 74 | #if defined(atarist) && defined(__GNUC__) 75 | /* doesn't have */ 76 | #else 77 | #include 78 | #endif 79 | #endif 80 | 81 | /* This must be included after fcntl.h, which has a prototype for `open' 82 | on some systems. Otherwise, the `open' prototype conflicts with the 83 | `topen' declaration. */ 84 | #if 0 85 | #include "externs.h" 86 | #endif 87 | 88 | #include 89 | #include 90 | 91 | #ifdef USG 92 | struct passwd *getpwuid(); 93 | struct passwd *getpwnam(); 94 | #endif 95 | 96 | #if defined(SYS_V) && defined(lint) 97 | struct screen { int dumb; }; 98 | #endif 99 | 100 | /* Fooling lint. Unfortunately, c defines all the TIO constants to be long, 101 | and lint expects them to be int. Also, ioctl is sometimes called with just 102 | two arguments. The following definition keeps lint happy. It may need to be 103 | reset for different systems. */ 104 | #ifdef lint 105 | #ifdef Pyramid 106 | /* Pyramid makes constants greater than 65535 into long! Gakk! -CJS- */ 107 | /*ARGSUSED*/ 108 | /*VARARGS2*/ 109 | static Ioctl(i, l, p) long l; char *p; { return 0; } 110 | #else 111 | /*ARGSUSED*/ 112 | /*VARARGS2*/ 113 | static Ioctl(i, l, p) char *p; { return 0; } 114 | #endif 115 | #define ioctl Ioctl 116 | #endif 117 | 118 | /* Provides for a timeout on input. Does a non-blocking read, consuming the 119 | data if any, and then returns 1 if data was read, zero otherwise. 120 | 121 | Porting: 122 | 123 | In systems without the select call, but with a sleep for 124 | fractional numbers of seconds, one could sleep for the time 125 | and then check for input. 126 | 127 | In systems which can only sleep for whole number of seconds, 128 | you might sleep by writing a lot of nulls to the terminal, and 129 | waiting for them to drain, or you might hack a static 130 | accumulation of times to wait. When the accumulation reaches a 131 | certain point, sleep for a second. There would need to be a 132 | way of resetting the count, with a call made for commands like 133 | run or rest. */ 134 | int check_input(microsec) 135 | int microsec; 136 | { 137 | #if defined(USG) && !defined(M_XENIX) && !defined(__linux__) 138 | int arg, result; 139 | #else 140 | struct timeval tbuf; 141 | int ch; 142 | #if defined(BSD4_3) || defined(M_XENIX) || defined(__linux__) 143 | fd_set smask; 144 | #else 145 | int smask; 146 | #endif 147 | #endif 148 | 149 | /* Return true if a read on descriptor 1 will not block. */ 150 | #if !defined(USG) || defined(M_XENIX) || defined(__linux__) 151 | tbuf.tv_sec = 0; 152 | tbuf.tv_usec = microsec; 153 | #if defined(BSD4_3) || defined(M_XENIX) || defined(__linux__) 154 | FD_ZERO(&smask); 155 | FD_SET(fileno(stdin), &smask); 156 | if (select(1, &smask, (fd_set *)0, (fd_set *)0, &tbuf) == 1) 157 | #else 158 | smask = 1; /* i.e. (1 << 0) */ 159 | if (select(1, &smask, (int *)0, (int *)0, &tbuf) == 1) 160 | #endif 161 | { 162 | ch = getch(); 163 | /* check for EOF errors here, select sometimes works even when EOF */ 164 | if (ch == -1) 165 | { 166 | eof_flag++; 167 | return 0; 168 | } 169 | return 1; 170 | } 171 | else 172 | return 0; 173 | #else /* SYS V code follows */ 174 | if (microsec != 0 && (turn & 0x7F) == 0) 175 | (void) sleep (1); /* mod 128, sleep one sec every 128 turns */ 176 | /* Can't check for input, but can do non-blocking read, so... */ 177 | /* Ugh! */ 178 | arg = 0; 179 | arg = fcntl(0, F_GETFL, arg); 180 | arg |= O_NDELAY; 181 | (void) fcntl(0, F_SETFL, arg); 182 | 183 | result = getch(); 184 | 185 | arg = 0; 186 | arg = fcntl(0, F_GETFL, arg); 187 | arg &= ~O_NDELAY; 188 | (void) fcntl(0, F_SETFL, arg); 189 | if (result == -1) 190 | return 0; 191 | else 192 | return 1; 193 | #endif 194 | } 195 | 196 | #if 0 197 | /* This is not used, however, this should be compared against shell_out 198 | in io.c */ 199 | 200 | /* A command for the operating system. Standard library function 201 | 'system' is unsafe, as it leaves various file descriptors 202 | open. This also is very careful with signals and interrupts, 203 | and does rudimentary job control, and puts the terminal back 204 | in a standard mode. */ 205 | int system_cmd(p) 206 | char *p; 207 | { 208 | int pgrp, pid, i, mask; 209 | union wait w; 210 | extern char *getenv(); 211 | 212 | mask = sigsetmask(~0); /* No interrupts. */ 213 | restore_term(); /* Terminal in original state. */ 214 | /* Are we in the control terminal group? */ 215 | if (ioctl(0, TIOCGPGRP, (char *)&pgrp) < 0 || pgrp != getpgrp(0)) 216 | pgrp = -1; 217 | pid = fork(); 218 | if (pid < 0) 219 | { 220 | (void) sigsetmask(mask); 221 | moriaterm(); 222 | return -1; 223 | } 224 | if (pid == 0) 225 | { 226 | (void) sigsetmask(0); /* Interrupts on. */ 227 | /* Transfer control terminal. */ 228 | if (pgrp >= 0) 229 | { 230 | i = getpid(); 231 | (void) ioctl(0, TIOCSPGRP, (char *)&i); 232 | (void) setpgrp(i, i); 233 | } 234 | for(i = 2; i < 30; i++) 235 | (void) close(i); /* Close all but standard in and out.*/ 236 | (void) dup2(1, 2); /* Make standard error as standard out. */ 237 | if (p == 0 || *p == 0) 238 | { 239 | p = getenv("SHELL"); 240 | if (p) 241 | execl(p, p, 0); 242 | execl("/bin/sh", "sh", 0); 243 | } 244 | else 245 | execl("/bin/sh", "sh", "-c", p, 0); 246 | _exit(1); 247 | } 248 | /* Wait for child termination. */ 249 | for(;;) 250 | { 251 | i = wait3(&w, WUNTRACED, (struct rusage *)0); 252 | if (i == pid) 253 | { 254 | if (WIFSTOPPED(w)) 255 | { 256 | /* Stop outselves, if child stops. */ 257 | (void) kill(getpid(), SIGSTOP); 258 | /* Restore the control terminal, and restart subprocess. */ 259 | if (pgrp >= 0) 260 | (void) ioctl(0, TIOCSPGRP, (char *)&pid); 261 | (void) killpg(pid, SIGCONT); 262 | } 263 | else 264 | break; 265 | } 266 | } 267 | /* Get the control terminal back. */ 268 | if (pgrp >= 0) 269 | (void) ioctl(0, TIOCSPGRP, (char *)&pgrp); 270 | (void) sigsetmask(mask); /* Interrupts on. */ 271 | moriaterm(); /* Terminal in moria mode. */ 272 | return 0; 273 | } 274 | #endif 275 | 276 | #if 0 277 | 278 | #ifdef USG 279 | unsigned short getuid(); 280 | #else 281 | #ifndef SECURE 282 | #if defined(BSD4_3) || defined(__NetBSD__) 283 | uid_t getuid(); 284 | #else /* other BSD versions */ 285 | int getuid(); 286 | #endif 287 | #endif 288 | #endif 289 | 290 | #endif 291 | /* Find a default user name from the system. */ 292 | void user_name(buf) 293 | char *buf; 294 | { 295 | extern char *getlogin(); 296 | struct passwd *pwline; 297 | register char *p; 298 | 299 | p = getlogin(); 300 | if (p && p[0]) 301 | (void) strcpy(buf, p); 302 | else 303 | { 304 | pwline = getpwuid((int)getuid()); 305 | if (pwline) 306 | (void) strcpy(buf, pwline->pw_name); 307 | } 308 | if (!buf[0]) 309 | (void) strcpy(buf, "X"); /* Gotta have some name */ 310 | } 311 | 312 | /* expands a tilde at the beginning of a file name to a users home 313 | directory */ 314 | int tilde(file, exp) 315 | char *file, *exp; 316 | { 317 | *exp = '\0'; 318 | if (file) 319 | { 320 | if (*file == '~') 321 | { 322 | char user[128]; 323 | struct passwd *pw = NULL; 324 | int i = 0; 325 | 326 | user[0] = '\0'; 327 | file++; 328 | while (*file != '/' && i < sizeof(user)) 329 | user[i++] = *file++; 330 | user[i] = '\0'; 331 | if (i == 0) 332 | { 333 | char *login = (char *) getlogin(); 334 | 335 | if (login != NULL) 336 | (void) strcpy (user, login); 337 | else if ((pw = getpwuid(getuid())) == NULL) 338 | return 0; 339 | } 340 | if (pw == NULL && (pw = getpwnam(user)) == NULL) 341 | return 0; 342 | (void) strcpy (exp, pw->pw_dir); 343 | } 344 | (void) strcat(exp, file); 345 | return 1; 346 | } 347 | return 0; 348 | } 349 | 350 | /* undefine these so that tfopen and topen will work */ 351 | #undef fopen 352 | #undef open 353 | 354 | /* open a file just as does fopen, but allow a leading ~ to specify a home 355 | directory */ 356 | FILE *tfopen(file, mode) 357 | char *file; 358 | char *mode; 359 | { 360 | char buf[1024]; 361 | extern int errno; 362 | 363 | if (tilde(file, buf)) 364 | return (fopen(buf, mode)); 365 | errno = ENOENT; 366 | return NULL; 367 | } 368 | 369 | /* open a file just as does open, but expand a leading ~ into a home directory 370 | name */ 371 | /* 372 | int topen(file, flags, mode) 373 | char *file; 374 | int flags, mode; 375 | { 376 | char buf[1024]; 377 | extern int errno; 378 | 379 | if (tilde(file, buf)) 380 | return (open(buf, flags, mode)); 381 | errno = ENOENT; 382 | return -1; 383 | } 384 | */ 385 | #endif 386 | -------------------------------------------------------------------------------- /variables.h: -------------------------------------------------------------------------------- 1 | /* variables.h */ 2 | /* Ever feel the need for more global vars? */ 3 | 4 | extern treas_ptr cur_inven; // { Current inven page } 5 | extern boolean is_magii; // { True if has mana } 6 | extern time_t start_time; // { Time started playing} 7 | extern boolean is_from_file; // { True if restored } 8 | extern money_type bank; // { Bank's money } 9 | extern money_type coin_value; // { Copy of money values} 10 | extern integer player_max_exp; // { Max exp possible } 11 | extern unsigned long seed; // { Contains seed # } 12 | extern unsigned long randes_seed; // { For encoding colors } 13 | extern unsigned long town_seed; // { Seed for town genera} 14 | extern integer channel; // { I/O channel # } 15 | extern unsigned long pasteb; // { Pasteboard id } 16 | extern quad_type io_bin_pause; // { I/O pause time } 17 | extern integer cur_height; // { Cur dungeon size } 18 | extern integer cur_width; 19 | extern integer dun_level; // { Cur dungeon level } 20 | extern integer missle_ctr; // { Counter for missles } 21 | extern integer msg_line; // { Contains message txt} 22 | extern boolean msg_flag; // { Set with first msg } 23 | extern vtype msg_prev[MAX_MESSAGES+1]; 24 | extern integer quest[NUM_QUESTS+1]; // {quest data} 25 | extern vtype old_msg; // { Last message } 26 | extern boolean want_trap; // { True = trap messages} 27 | extern boolean want_warn; // { True = water warning} 28 | extern message_ptr caught_message; // { Message from other } 29 | extern message_ptr old_message; // { Past messages } 30 | extern integer old_mess_count; // { Count of old mess's } 31 | extern integer max_mess_keep; // { Max old to keep } 32 | extern message_ptr cur_message; // { Pointer to add mess } 33 | extern message_ptr message_cursor; // { Pointer to read mess} 34 | extern integer caught_count; // { # of mesgs waiting } 35 | extern integer max_score; // { # of scores to list } 36 | extern boolean generate; // { Generate next level } 37 | extern boolean death; // { True if died } 38 | extern vtype died_from; // { What killed him } 39 | extern integer turn_counter; // { Turns ellapsed } 40 | extern boolean find_flag; // { Used in MORIA } 41 | extern boolean cave_flag; // { Used in GET_PANEL } 42 | extern boolean light_flag; // { Used in MOVE_LIGHT } 43 | extern boolean redraw; // { For redraw screen } 44 | extern unsigned long print_stat; // { Flag for stats } 45 | extern integer turn; // { Cur trun of game } 46 | extern boolean wizard1; // { Wizard flag } 47 | extern boolean wizard2; // { Wizard flag } 48 | extern boolean used_line[24]; // array [2..23] of boolean; 49 | extern char password1[13]; 50 | extern char password2[13]; 51 | extern boolean became_wizard; 52 | extern unsigned long wdata[2][13]; // array [1..2,0..12] of unsigned; 53 | extern char days[7][30]; 54 | extern integer closing_flag; // { Used for closing } 55 | extern boolean uw_id; // { Is this a UW node? } 56 | //{neatness arrays} 57 | extern byteint key_of[9]; // array [0..8] of byteint; 58 | extern byteint oct_of[10]; // array [1..9] of byteint; 59 | extern bytlint dx_of[10]; // array [1..9] of bytlint; 60 | extern bytlint dy_of[10]; // array [1..9] of bytlint; 61 | 62 | // { Bit testing array } 63 | extern unsigned long bit_array[33]; // array [1..32] of unsigned; 64 | 65 | // { External file names; are all located in directory with image } 66 | extern mtype MORIA_HOU; 67 | extern mtype MORIA_MOR; 68 | extern mtype MORIA_MAS; 69 | extern mtype MORIA_TOP; 70 | extern mtype MORIA_TRD; 71 | extern mtype MORIA_HLP; 72 | extern mtype MORIA_LCK; 73 | extern mtype MORIA_DTH; 74 | extern mtype MORIA_MON; 75 | extern mtype MORIA_CST; 76 | extern mtype MORIA_GCST; 77 | 78 | // { following are calculated from max dungeon sizes } 79 | extern integer max_panel_rows, max_panel_cols; 80 | extern integer quart_height, quart_width; 81 | extern integer panel_row, panel_col; 82 | extern integer panel_row_min, panel_row_max; 83 | extern integer panel_col_min, panel_col_max; 84 | extern integer panel_col_prt, panel_row_prt; 85 | 86 | // { Following are all floor definitions } 87 | extern row_floor cave[MAX_HEIGHT+1]; 88 | extern cave_type blank_floor; 89 | extern floor_type dopen_floor; 90 | extern floor_type lopen_floor; 91 | extern floor_type corr_floor1; 92 | extern floor_type corr_floor2; 93 | extern floor_type corr_floor3; 94 | extern floor_type corr_floor4; 95 | extern floor_type rock_wall1; 96 | extern floor_type rock_wall2; 97 | extern floor_type rock_wall3; 98 | extern floor_type water1; 99 | extern floor_type water2; 100 | extern floor_type water3; 101 | extern floor_type boundry_wall; 102 | 103 | // { Following are set definitions } 104 | extern obj_set floor_set; 105 | extern obj_set open_dry_floors; 106 | extern obj_set wall_set; 107 | extern obj_set pwall_set; 108 | extern obj_set corr_set; 109 | extern obj_set trap_set; 110 | extern obj_set light_set; 111 | extern obj_set water_set; 112 | extern obj_set earth_set; 113 | extern obj_set float_set; 114 | extern obj_set slow_set; 115 | extern obj_set stable_set; 116 | 117 | // { Following are player variables } 118 | extern player_type py; 119 | 120 | // { Class titles for different levels } 121 | 122 | extern btype player_title[MAX_CLASS][MAX_PLAYER_LEVEL+1]; 123 | // array [1..max_class] of 124 | // array [1..max_player_level] of btype; 125 | 126 | extern integer player_exp[MAX_PLAYER_LEVEL+1]; 127 | extern real acc_exp; //{ Accumulator for fractional exp} 128 | extern dtype bare_hands; 129 | extern boolean msg_terse; 130 | extern byteint record_ctr; 131 | extern integer char_row; 132 | extern integer char_col; 133 | extern integer com_val; 134 | extern integer pclass; 135 | extern vtype sex_type; 136 | extern race_type race[MAX_RACES]; 137 | extern background_type background[MAX_BACKGROUND]; 138 | extern real rgold_adj[MAX_RACES][MAX_RACES]; 139 | extern class_type class[MAX_CLASS]; 140 | extern spell_type magic_spell[MAX_CLASS][MAX_SPELLS]; 141 | extern treasure_type yums[NUM_YUM+1]; 142 | extern treasure_type monk_book; 143 | extern byteint player_init[MAX_CLASS][5]; 144 | extern boolean total_winner; 145 | 146 | // { Following are store definitions } 147 | extern owner_type owners[MAX_OWNERS]; 148 | extern store_type stores[MAX_STORES+1]; 149 | extern treasure_type store_door[MAX_STORES+MAX_UNNAMED+5+1]; 150 | extern integer store_choice[MAX_STORES][STORE_CHOICES]; 151 | extern obj_set store_buy[MAX_STORES]; 152 | // array [1..max_stores] of obj_set; 153 | extern htype store_hours[MAX_STORES+MAX_UNNAMED][7]; 154 | extern integer store_bribe[MAX_STORES+MAX_UNNAMED]; 155 | extern integer mugging_chance; // { Chance page gets mugged} 156 | 157 | // { Following are treasure arrays and variables } 158 | extern treasure_type object_list[MAX_OBJECTS+1]; 159 | extern boolean object_ident[MAX_OBJECTS+1]; 160 | extern integer t_level[MAX_OBJ_LEVEL+1]; 161 | extern treasure_type gold_list[MAX_GOLD]; 162 | extern treasure_type t_list[MAX_TALLOC+1]; 163 | extern treasure_type equipment[EQUIP_MAX]; 164 | extern treas_ptr inventory_list; 165 | extern treas_ptr inven_temp; 166 | extern treasure_type inventory_init[INVEN_INIT_MAX+1]; 167 | extern treasure_type blank_treasure; 168 | extern integer inven_ctr; // { Total different obj's } 169 | extern integer inven_weight; // { Cur carried weight } 170 | extern integer equip_ctr; // { Cur equipment ctr } 171 | extern integer tcptr; // { Cur treasure heap ptr } 172 | 173 | // { Following are variables that change with level of difficulty } 174 | // { 1/x chance of treasure per magma } 175 | extern integer dun_str_mc; 176 | // { 1/x chance of treasure per quartz } 177 | extern integer dun_str_qc; 178 | // { Level/x chance of unusual room } 179 | extern integer dun_unusual; 180 | // { Amount of objects for rooms } 181 | extern integer treas_room_alloc; 182 | // { Amount of objects for corridors } 183 | extern integer treas_any_alloc; 184 | // { Amount of gold (and gems) } 185 | extern integer treas_gold_alloc; 186 | // { 1/n Chance of item being a Great Item } 187 | extern integer obj_great; 188 | // { Adjust STD per level } 189 | extern real obj_std_adj; 190 | // { Minimum STD } 191 | extern integer obj_std_min; 192 | // { Town object generation level } 193 | extern integer obj_town_level; 194 | // { Base amount of magic } 195 | extern integer obj_base_magic; 196 | // { Max amount of magic } 197 | extern integer obj_base_max; 198 | // { magic_chance/# = special magic } 199 | extern integer obj_div_special; 200 | // { magic_chance/# = cursed items } 201 | extern real obj_div_cursed; 202 | // { High value slows multiplication } 203 | extern integer mon_mult_adj; 204 | // { Dun_level/x chance of high level creature } 205 | extern integer mon_nasty; 206 | 207 | // { Following are feature objects defined for dungeon } 208 | extern treasure_type trap_lista[MAX_TRAPA+1]; 209 | extern treasure_type trap_listb[MAX_TRAPB+1]; 210 | extern treasure_type scare_monster; // { Special trap } 211 | extern treasure_type some_rubble; 212 | extern treasure_type door_list[3]; 213 | extern treasure_type up_stair; 214 | extern treasure_type down_stair; 215 | extern treasure_type up_steep; 216 | extern treasure_type down_steep; 217 | 218 | // { Following are creature arrays and variables } 219 | extern creature_type c_list[MAX_CREATURES+1]; 220 | extern monster_type m_list[MAX_MALLOC+1]; 221 | extern integer m_level[MAX_MONS_LEVEL+1]; 222 | extern monster_type blank_monster; // { Blank monster values } 223 | extern integer muptr; // { Cur used monster ptr } 224 | extern integer mfptr; // { Cur free monster ptr } 225 | extern integer mon_tot_mult; // { # of repro's of creature } 226 | 227 | // { Following are arrays for descriptive pieces } 228 | extern atype colors[MAX_COLORS]; 229 | extern atype mushrooms[MAX_MUSH]; 230 | extern atype woods[MAX_WOODS]; 231 | extern atype metals[MAX_METALS]; 232 | extern atype horns[MAX_HORNS]; 233 | extern atype rocks[MAX_ROCKS]; 234 | extern atype amulets[MAX_AMULETS]; 235 | extern atype cloths[MAX_CLOTHS]; 236 | extern atype syllables[MAX_SYLLABLES]; 237 | // vowel_set : 238 | // char_set; 239 | 240 | // { Following are variables for the Save Character Routines } 241 | extern vtype finam; 242 | // key_type key_rec; 243 | 244 | // { Cursor variables, used for cursor positioning } 245 | extern char cursor_r[25][11]; //array [1..24] of varying[10] of 246 | extern integer curlen_r; 247 | extern char cursor_c[81][11]; //array [1..80] of varying[10] of 248 | extern integer curlen_c; 249 | extern integer cursor_l; 250 | extern boolean row_first; 251 | extern char cursor_erl[11]; // : varying[10] of char; 252 | extern char cursor_erp[11]; // : varying[10] of char; 253 | 254 | // new stuff 255 | extern integer malloc_calls; 256 | extern integer malloc_bytes; 257 | extern integer free_calls; 258 | extern integer free_bytes; 259 | extern vtype coin_name[MITHRIL+1]; 260 | extern obj_set blank_floor_set; 261 | 262 | extern obj_set null_obj_set; 263 | extern obj_set destroyed_by_lightning; 264 | extern obj_set destroyed_by_acid; 265 | extern obj_set destroyed_by_cold; 266 | extern obj_set destroyed_by_fire; 267 | extern obj_set destroyed_by_petrify; 268 | extern obj_set destroyed_by_sunray; 269 | 270 | extern gid_t games_gid; 271 | extern boolean scoresAreEncrypted; 272 | extern boolean saveFilesAreEncrypted; 273 | 274 | extern byteint highScoreKey[8]; 275 | extern byteint saveFileKey[8]; 276 | 277 | extern int game_state; 278 | extern boolean curses_is_running; 279 | 280 | /* END FILE variables.h */ 281 | -------------------------------------------------------------------------------- /wands.c: -------------------------------------------------------------------------------- 1 | /* wands.c */ 2 | /**/ 3 | 4 | #include "imoria.h" 5 | #include "dungeon.h" 6 | ////////////////////////////////////////////////////////////////////// 7 | ////////////////////////////////////////////////////////////////////// 8 | ////////////////////////////////////////////////////////////////////// 9 | void aw__wand_effects(integer effect, boolean *idented, integer dir, 10 | integer i3, integer i4) 11 | { 12 | boolean ident; 13 | 14 | 15 | ident = *idented; 16 | 17 | /*{ Wands }*/ 18 | 19 | /* handle wand of wonder */ 20 | if (effect == 24) { 21 | effect = randint(23); 22 | } 23 | 24 | switch (effect) { 25 | case 1 : 26 | msg_print("A line of blue shimmering light appears."); 27 | light_line(dir,char_row,char_col,1); 28 | ident = true; 29 | break; 30 | 31 | case 2 : 32 | fire_bolt(c_lightning,dir,i3,i4,damroll("3d8"), 33 | "Lightning Bolt"); 34 | ident = true; 35 | break; 36 | 37 | case 3 : 38 | fire_bolt(c_cold,dir,i3,i4,damroll("4d8"),"Frost Bolt"); 39 | ident = true; 40 | break; 41 | 42 | case 4 : 43 | fire_bolt(c_fire,dir,i3,i4,damroll("6d8"),"Fire Bolt"); 44 | ident = true; 45 | break; 46 | 47 | case 5 : 48 | ident = wall_to_mud(dir,i3,i4); 49 | break; 50 | 51 | case 6 : 52 | ident = poly_monster(dir,i3,i4); 53 | break; 54 | 55 | case 7 : 56 | ident = zap_monster(dir,i3,i4,-damroll("4d6"),c_hp); 57 | break; 58 | 59 | case 8 : 60 | ident = zap_monster(dir,i3,i4,1,c_speed); 61 | break; 62 | 63 | case 9 : 64 | ident = zap_monster(dir,i3,i4,-1,c_speed); 65 | break; 66 | 67 | case 10 : 68 | ident = zap_monster(dir,i3,i4,0,c_confuse); 69 | break; 70 | 71 | case 11 : 72 | ident = zap_monster(dir,i3,i4,0,c_sleep); 73 | break; 74 | 75 | case 12 : 76 | ident = zap_monster(dir,i3,i4,50,c_drain); 77 | break; 78 | 79 | case 13 : 80 | ident = td_destroy2(dir,i3,i4); 81 | break; 82 | 83 | case 14 : 84 | fire_bolt(0,dir,i3,i4,damroll("2d6"),"Magic Missile"); 85 | ident = true; 86 | break; 87 | 88 | case 15 : 89 | ident = build_wall(dir,i3,i4); 90 | break; 91 | 92 | case 16 : 93 | ident = clone_monster(dir,i3,i4); 94 | break; 95 | 96 | case 17 : 97 | ident = teleport_monster(dir,i3,i4); 98 | break; 99 | 100 | case 18 : 101 | ident = disarm_all(dir,i3,i4); 102 | break; 103 | 104 | case 19 : 105 | fire_ball(c_lightning,dir,i3,i4,24,"Lightning Ball"); 106 | ident = true; 107 | break; 108 | 109 | case 20 : 110 | fire_ball(c_cold,dir,i3,i4,32,"Cold Ball"); 111 | ident = true; 112 | break; 113 | 114 | case 21 : 115 | fire_ball(c_fire,dir,i3,i4,48,"Fire Ball"); 116 | ident = true; 117 | break; 118 | 119 | case 22 : 120 | fire_ball(c_gas,dir,i3,i4,8,"Stinking Cloud"); 121 | ident = true; 122 | break; 123 | 124 | case 23 : 125 | fire_ball(c_acid,dir,i3,i4,40,"Acid Ball"); 126 | ident = true; 127 | break; 128 | 129 | case 24 : 130 | /* wand of wonder */ 131 | break; 132 | 133 | case 25 : 134 | ident = zap_monster(dir,i3,i4,0,c_probe); 135 | break; 136 | 137 | default: 138 | break; 139 | } 140 | /*{ End of Wands... }*/ 141 | 142 | 143 | *idented = ident; 144 | }; 145 | ////////////////////////////////////////////////////////////////////// 146 | void aim_wand() 147 | { 148 | /*{ Wands for the aiming... }*/ 149 | 150 | unsigned long i1; 151 | integer i3,i4,chance,i5; 152 | integer dir; 153 | treas_ptr i2,item_ptr; 154 | integer dumy,y_dumy,x_dumy; 155 | char trash_char; 156 | boolean redraw,ident; 157 | obj_set give_me_a_wand = {wand, 0}; 158 | 159 | redraw = false; 160 | reset_flag = true; 161 | 162 | if (inven_ctr > 0) { 163 | if (find_range(give_me_a_wand,false,&i2,&i3)) { 164 | if (get_item(&item_ptr,"Aim which wand?", 165 | &redraw,i3,&trash_char,false,false)) { 166 | //with item_ptr^.data do; 167 | if (redraw) { 168 | draw_cave(); 169 | } 170 | reset_flag = false; 171 | redraw = false; 172 | y_dumy = char_row; 173 | x_dumy = char_col; 174 | if (d__get_dir("Which direction?",&dir,&dumy,&y_dumy,&x_dumy)) { 175 | if (py.flags.confused > 0) { 176 | msg_print("You are confused..."); 177 | do { 178 | dir = randint(9); 179 | } while (dir == 5); 180 | } 181 | i1 = item_ptr->data.flags; 182 | ident = false; 183 | 184 | //with py.misc do; 185 | chance = PM.save + PM.lev + spell_adj(INT) - item_ptr->data.level; 186 | 187 | if (py.flags.confused > 0) { 188 | chance /= 2; 189 | } 190 | if (chance < 0) { 191 | chance = 0; 192 | } 193 | 194 | if (randint(chance) < USE_DEVICE) { 195 | msg_print("You failed to use the wand properly."); 196 | } else if (item_ptr->data.p1 > 0) { 197 | item_ptr->data.p1--; 198 | for ( ; i1 > 0 ; ) { 199 | i5 = bit_pos(&i1)+1; 200 | i3 = char_row; 201 | i4 = char_col; 202 | aw__wand_effects(i5,&ident,dir,i3,i4); 203 | } 204 | if (ident) { 205 | identify(&(item_ptr->data)); 206 | } 207 | if (item_ptr->data.flags != 0) { 208 | //with py.misc do; 209 | PM.exp += (item_ptr->data.level / (real)PM.lev) + .5; 210 | prt_experience(); 211 | } 212 | 213 | desc_charges(item_ptr); 214 | 215 | } /* end if have charges */ 216 | } /* end if get_dir */ 217 | } /* end if get_item */ 218 | 219 | } else { 220 | msg_print("You are not carrying any wands."); 221 | } 222 | } else { 223 | msg_print("But you are not carrying anything."); 224 | } 225 | if (redraw) { 226 | draw_cave(); 227 | } 228 | }; 229 | ////////////////////////////////////////////////////////////////////// 230 | ////////////////////////////////////////////////////////////////////// 231 | ////////////////////////////////////////////////////////////////////// 232 | 233 | /* END FILE wands.c */ 234 | ////////////////////////////////////////////////////////////////////// 235 | ////////////////////////////////////////////////////////////////////// 236 | ////////////////////////////////////////////////////////////////////// 237 | --------------------------------------------------------------------------------