From 1407a08c1751f6c2e36d5ced6decf56c7d17911e Mon Sep 17 00:00:00 2001 From: Kashif Shah Date: Sun, 21 May 2023 03:23:56 +0000 Subject: [PATCH] added pristine code from debian 0.90-pa9 package --- CVS/Entries | 69 ++ CVS/Entries.Log | 3 + CVS/Repository | 1 + CVS/Root | 1 + Makefile | 110 ++ Makefile.ami | 46 + abyss.c | 212 ++++ aux1.c | 972 +++++++++++++++ aux2.c | 1215 +++++++++++++++++++ aux3.c | 1285 ++++++++++++++++++++ bank.c | 1165 ++++++++++++++++++ buglist.txt | 2 + char.c | 841 +++++++++++++ city.c | 708 +++++++++++ command1.c | 334 ++++++ command2.c | 1219 +++++++++++++++++++ command3.c | 1121 ++++++++++++++++++ compress.c | 1444 ++++++++++++++++++++++ country.c | 647 ++++++++++ defs.h | 1930 ++++++++++++++++++++++++++++++ docs/CVS/Entries | 11 + docs/CVS/Repository | 1 + docs/CVS/Root | 1 + docs/compile.all | 58 + docs/compile.ami | 14 + docs/compile.dj | 38 + docs/compile.dos | 77 ++ docs/omega.6 | 63 + docs/omega.txt | 132 +++ docs/readme.1st | 19 + docs/readme.dos | 88 ++ docs/readme3 | 189 +++ docs/readme4 | 48 + effect1.c | 804 +++++++++++++ effect2.c | 660 +++++++++++ effect3.c | 1195 +++++++++++++++++++ env.c | 330 ++++++ etc.c | 322 +++++ extern.h | 1143 ++++++++++++++++++ file.c | 672 +++++++++++ fixstr.c | 142 +++ gen1.c | 625 ++++++++++ gen2.c | 495 ++++++++ genclr.c | 365 ++++++ glob.h | 298 +++++ guild1.c | 615 ++++++++++ guild2.c | 1103 +++++++++++++++++ house.c | 224 ++++ iinit.h | 484 ++++++++ init.c | 10 + inv.c | 1773 +++++++++++++++++++++++++++ item.c | 712 +++++++++++ itemf1.c | 990 ++++++++++++++++ itemf2.c | 522 ++++++++ itemf3.c | 900 ++++++++++++++ lev.c | 514 ++++++++ lib/CVS/Entries | 31 + lib/CVS/Repository | 1 + lib/CVS/Root | 1 + lib/Makefile | 12 + lib/abyss.txt | Bin 0 -> 1314 bytes lib/help1.txt | 55 + lib/help10.txt | 23 + lib/help11.txt | 18 + lib/help12.txt | 68 ++ lib/help13.txt | 25 + lib/help2.txt | 69 ++ lib/help3.txt | 108 ++ lib/help4.txt | 14 + lib/help5.txt | 90 ++ lib/help6.txt | 13 + lib/help7.txt | 13 + lib/help8.txt | 44 + lib/help9.txt | 77 ++ lib/intro.txt | Bin 0 -> 1802 bytes lib/lgpl.txt | 482 ++++++++ lib/license.txt | 61 + lib/motd.txt | 19 + lib/omega.hi | 35 + lib/omega.hi.backup | 35 + lib/omega.log | 4 + lib/omega.log.backup | 4 + lib/omegatiles.xpm | 893 ++++++++++++++ lib/scroll1.txt | Bin 0 -> 2337 bytes lib/scroll2.txt | Bin 0 -> 1650 bytes lib/scroll3.txt | Bin 0 -> 1913 bytes lib/scroll4.txt | Bin 0 -> 1354 bytes lib/thanks.txt | 32 + lib/update.txt | 80 ++ map.c | 210 ++++ minit.h | 328 +++++ mmelee.c | 304 +++++ mmove.c | 267 +++++ mon.c | 1179 ++++++++++++++++++ move.c | 1165 ++++++++++++++++++ movef.c | 362 ++++++ mspec.c | 746 ++++++++++++ mstrike.c | 73 ++ mtalk.c | 794 +++++++++++++ newrand.c | 95 ++ oldsave.h | 107 ++ omega.ad | 50 + omega.bug | 625 ++++++++++ omega.bug2 | 56 + omega.c | 520 ++++++++ pdump.c | 1223 +++++++++++++++++++ priest.c | 523 ++++++++ save.c | 1293 ++++++++++++++++++++ scr.c | 2238 +++++++++++++++++++++++++++++++++++ site1.c | 1093 +++++++++++++++++ site2.c | 1147 ++++++++++++++++++ spell.c | 875 ++++++++++++++ stats.c | 119 ++ test.c | 37 + time.c | 103 ++ tools/CVS/Entries | 7 + tools/CVS/Entries.Log | 1 + tools/CVS/Repository | 1 + tools/CVS/Root | 1 + tools/bwt.c | 208 ++++ tools/bwt.h | 24 + tools/crypt.c | 241 ++++ tools/decrypt.c | 180 +++ tools/libsrc/CVS/Entries | 22 + tools/libsrc/CVS/Repository | 1 + tools/libsrc/CVS/Root | 1 + tools/libsrc/Makefile | 11 + tools/makedate.c | 21 + tools/makefile | 25 + trap.c | 302 +++++ util.c | 1154 ++++++++++++++++++ village.c | 294 +++++ 132 files changed, 49295 insertions(+) create mode 100644 CVS/Entries create mode 100644 CVS/Entries.Log create mode 100644 CVS/Repository create mode 100644 CVS/Root create mode 100644 Makefile create mode 100644 Makefile.ami create mode 100644 abyss.c create mode 100644 aux1.c create mode 100644 aux2.c create mode 100644 aux3.c create mode 100644 bank.c create mode 100644 buglist.txt create mode 100644 char.c create mode 100644 city.c create mode 100644 command1.c create mode 100644 command2.c create mode 100644 command3.c create mode 100644 compress.c create mode 100644 country.c create mode 100644 defs.h create mode 100644 docs/CVS/Entries create mode 100644 docs/CVS/Repository create mode 100644 docs/CVS/Root create mode 100644 docs/compile.all create mode 100644 docs/compile.ami create mode 100644 docs/compile.dj create mode 100644 docs/compile.dos create mode 100644 docs/omega.6 create mode 100644 docs/omega.txt create mode 100644 docs/readme.1st create mode 100644 docs/readme.dos create mode 100644 docs/readme3 create mode 100644 docs/readme4 create mode 100644 effect1.c create mode 100644 effect2.c create mode 100644 effect3.c create mode 100644 env.c create mode 100644 etc.c create mode 100644 extern.h create mode 100644 file.c create mode 100644 fixstr.c create mode 100644 gen1.c create mode 100644 gen2.c create mode 100644 genclr.c create mode 100644 glob.h create mode 100644 guild1.c create mode 100644 guild2.c create mode 100644 house.c create mode 100644 iinit.h create mode 100644 init.c create mode 100644 inv.c create mode 100644 item.c create mode 100644 itemf1.c create mode 100644 itemf2.c create mode 100644 itemf3.c create mode 100644 lev.c create mode 100644 lib/CVS/Entries create mode 100644 lib/CVS/Repository create mode 100644 lib/CVS/Root create mode 100644 lib/Makefile create mode 100644 lib/abyss.txt create mode 100644 lib/help1.txt create mode 100644 lib/help10.txt create mode 100644 lib/help11.txt create mode 100644 lib/help12.txt create mode 100644 lib/help13.txt create mode 100644 lib/help2.txt create mode 100644 lib/help3.txt create mode 100644 lib/help4.txt create mode 100644 lib/help5.txt create mode 100644 lib/help6.txt create mode 100644 lib/help7.txt create mode 100644 lib/help8.txt create mode 100644 lib/help9.txt create mode 100644 lib/intro.txt create mode 100644 lib/lgpl.txt create mode 100644 lib/license.txt create mode 100644 lib/motd.txt create mode 100644 lib/omega.hi create mode 100644 lib/omega.hi.backup create mode 100644 lib/omega.log create mode 100644 lib/omega.log.backup create mode 100644 lib/omegatiles.xpm create mode 100644 lib/scroll1.txt create mode 100644 lib/scroll2.txt create mode 100644 lib/scroll3.txt create mode 100644 lib/scroll4.txt create mode 100644 lib/thanks.txt create mode 100644 lib/update.txt create mode 100644 map.c create mode 100644 minit.h create mode 100644 mmelee.c create mode 100644 mmove.c create mode 100644 mon.c create mode 100644 move.c create mode 100644 movef.c create mode 100644 mspec.c create mode 100644 mstrike.c create mode 100644 mtalk.c create mode 100644 newrand.c create mode 100644 oldsave.h create mode 100644 omega.ad create mode 100644 omega.bug create mode 100644 omega.bug2 create mode 100644 omega.c create mode 100644 pdump.c create mode 100644 priest.c create mode 100644 save.c create mode 100644 scr.c create mode 100644 site1.c create mode 100644 site2.c create mode 100644 spell.c create mode 100644 stats.c create mode 100644 test.c create mode 100644 time.c create mode 100644 tools/CVS/Entries create mode 100644 tools/CVS/Entries.Log create mode 100644 tools/CVS/Repository create mode 100644 tools/CVS/Root create mode 100644 tools/bwt.c create mode 100644 tools/bwt.h create mode 100644 tools/crypt.c create mode 100644 tools/decrypt.c create mode 100644 tools/libsrc/CVS/Entries create mode 100644 tools/libsrc/CVS/Repository create mode 100644 tools/libsrc/CVS/Root create mode 100644 tools/libsrc/Makefile create mode 100644 tools/makedate.c create mode 100644 tools/makefile create mode 100644 trap.c create mode 100644 util.c create mode 100644 village.c diff --git a/CVS/Entries b/CVS/Entries new file mode 100644 index 0000000..e7ad55e --- /dev/null +++ b/CVS/Entries @@ -0,0 +1,69 @@ +/Makefile/1.9/Mon Aug 27 09:21:25 2001// +/Makefile.ami/1.1.1.1/Fri Jun 1 11:59:09 2001// +/abyss.c/1.1.1.1/Fri Jun 1 11:59:09 2001// +/aux1.c/1.2/Fri Jun 1 16:19:23 2001// +/aux2.c/1.2/Mon Aug 27 09:22:37 2001// +/aux3.c/1.3/Tue Jun 5 09:58:19 2001// +/bank.c/1.2/Tue Jun 5 09:56:14 2001// +/buglist.txt/1.3/Mon Aug 27 09:22:56 2001// +/char.c/1.2/Mon Jun 4 11:14:28 2001// +/city.c/1.1.1.1/Fri Jun 1 11:59:10 2001// +/command1.c/1.1.1.1/Fri Jun 1 11:59:10 2001// +/command2.c/1.2/Mon Aug 27 09:29:35 2001// +/command3.c/1.2/Mon Aug 27 09:25:08 2001// +/compress.c/1.2/Mon Aug 27 09:47:44 2001// +/country.c/1.2/Mon Aug 27 09:22:06 2001// +/defs.h/1.6/Thu Aug 23 11:41:11 2001// +/effect1.c/1.4/Mon Aug 27 09:29:35 2001// +/effect2.c/1.1.1.1/Fri Jun 1 11:59:13 2001// +/effect3.c/1.2/Mon Aug 27 09:29:35 2001// +/env.c/1.1.1.1/Fri Jun 1 11:59:13 2001// +/etc.c/1.1.1.1/Fri Jun 1 11:59:13 2001// +/extern.h/1.5/Tue Jun 12 13:32:37 2001// +/file.c/1.5/Mon Aug 27 09:29:35 2001// +/fixstr.c/1.1.1.1/Fri Jun 1 11:59:14 2001// +/gen1.c/1.2/Mon Aug 27 09:30:52 2001// +/gen2.c/1.2/Mon Aug 27 09:29:35 2001// +/genclr.c/1.4/Mon Aug 27 09:29:35 2001// +/glob.h/1.3/Mon Aug 27 09:24:27 2001// +/guild1.c/1.2/Tue Jun 5 09:57:38 2001// +/guild2.c/1.1.1.1/Fri Jun 1 11:59:15 2001// +/house.c/1.1.1.1/Fri Jun 1 11:59:15 2001// +/iinit.h/1.2/Mon Jun 4 11:11:36 2001// +/init.c/1.1.1.1/Fri Jun 1 11:59:15 2001// +/inv.c/1.5/Mon Aug 27 09:29:35 2001// +/item.c/1.2/Mon Jun 4 11:13:49 2001// +/itemf1.c/1.2/Mon Aug 27 09:29:35 2001// +/itemf2.c/1.1.1.1/Fri Jun 1 11:59:16 2001// +/itemf3.c/1.1.1.1/Fri Jun 1 11:59:16 2001// +/lev.c/1.2/Mon Aug 27 09:29:35 2001// +/map.c/1.1.1.1/Fri Jun 1 11:59:17 2001// +/minit.h/1.1.1.1/Fri Jun 1 11:59:17 2001// +/mmelee.c/1.1.1.1/Fri Jun 1 11:59:17 2001// +/mmove.c/1.1.1.1/Fri Jun 1 11:59:17 2001// +/mon.c/1.1.1.1/Fri Jun 1 11:59:18 2001// +/move.c/1.1.1.1/Fri Jun 1 11:59:18 2001// +/movef.c/1.1.1.1/Fri Jun 1 11:59:18 2001// +/mspec.c/1.3/Mon Aug 27 09:29:35 2001// +/mstrike.c/1.1.1.1/Fri Jun 1 11:59:18 2001// +/mtalk.c/1.1.1.1/Fri Jun 1 11:59:19 2001// +/newrand.c/1.1.1.1/Fri Jun 1 11:59:19 2001// +/oldsave.h/1.1.1.1/Fri Jun 1 11:59:19 2001// +/omega.ad/1.1.1.1/Fri Jun 1 11:59:19 2001// +/omega.bug/1.1.1.1/Fri Jun 1 11:59:19 2001// +/omega.bug2/1.1.1.1/Fri Jun 1 11:59:19 2001// +/omega.c/1.2/Tue Jun 5 09:57:38 2001// +/pdump.c/1.3/Mon Jun 4 11:09:52 2001// +/priest.c/1.1.1.1/Fri Jun 1 11:59:20 2001// +/save.c/1.4/Mon Aug 27 09:29:35 2001// +/scr.c/1.10/Mon Aug 27 09:29:35 2001// +/site1.c/1.2/Mon Jun 4 11:13:09 2001// +/site2.c/1.1.1.1/Fri Jun 1 11:59:21 2001// +/spell.c/1.1.1.1/Fri Jun 1 11:59:22 2001// +/stats.c/1.1.1.1/Fri Jun 1 11:59:22 2001// +/test.c/1.1.1.1/Fri Jun 1 11:59:22 2001// +/time.c/1.2/Tue Jun 5 09:57:38 2001// +/trap.c/1.1.1.1/Fri Jun 1 11:59:22 2001// +/util.c/1.2/Mon Aug 27 09:23:58 2001// +/village.c/1.2/Mon Aug 27 09:29:35 2001// +D diff --git a/CVS/Entries.Log b/CVS/Entries.Log new file mode 100644 index 0000000..f8e792c --- /dev/null +++ b/CVS/Entries.Log @@ -0,0 +1,3 @@ +A D/docs//// +A D/lib//// +A D/tools//// diff --git a/CVS/Repository b/CVS/Repository new file mode 100644 index 0000000..17ba91c --- /dev/null +++ b/CVS/Repository @@ -0,0 +1 @@ +omega-roguelike/omega diff --git a/CVS/Root b/CVS/Root new file mode 100644 index 0000000..f722675 --- /dev/null +++ b/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.omega-roguelike.sourceforge.net:/cvsroot/omega-roguelike diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f59da18 --- /dev/null +++ b/Makefile @@ -0,0 +1,110 @@ +### These two definitions are used if you 'make install' +### the value of LIBDIR should be the same as OMEGALIB in defs.h +BINDIR = ./omega/ +LIBDIR = ./lib/ + +### choose your optimization level +OFLAGS = -O2 + +### One of these should be uncommented, as appropriate, unless your compiler +### does it for you. You can test this by simply trying to 'make' omega - +### it will fail if none of them are defined. If you do uncomment +### one, make sure you comment out the other definition of CFLAGS lower down + +CFLAGS = -ggdb -Wall $(OFLAGS) -DBSD # -ansi +#CFLAGS = -DSYSV $(OFLAGS) +#CFLAGS = -DMSDOS $(OFLAGS) +#CFLAGS = -DAMIGA $(OFLAGS) + +### CPP should contain the command to run the C preprocessor. +#CPP = cc -E +#CPP = /lib/cpp +CPP = gcc -E + +### define a compiler +CC = gcc + +### Select one of the following that is appropriate for your curses... +### Comment ALL of them out if you are using opcurses +#LIBS = -lncurses -ltermcap +#LIBS = -lcurses -ltermlib +#LIBS = -lpdcurses +#Linux links in term?? automatically. +#LIBS = -lncurses + +### uncomment to use "op-curses" package +OPDEF = -DUSE_OPCURSES +CUROBJ = ../opcurses/curses.o ../opcurses/curgtk.o + +### uncomment to compile using opcurses GTK+ driver +CPPFLAGS = `gtk-config --cflags` -DUSE_OPCURSES +LDFLAGS = `gtk-config --libs` + +#################### that's it for changing the Makefile #################### + +OLIBSTUFF = tools/libsrc/maps.dat lib/maps.dat + +TOOLS = tools/crypt tools/decrypt tools/makedate + +CLROBJ = clrgen.o + +OBJ = omega.o abyss.o aux1.o aux2.o aux3.o bank.o char.o city.o\ + command1.o command2.o command3.o country.o date.o effect1.o\ + effect2.o effect3.o etc.o env.o file.o gen1.o gen2.o guild1.o guild2.o\ + house.o init.o inv.o item.o itemf1.o itemf2.o itemf3.o lev.o map.o\ + mmelee.o mmove.o mon.o move.o movef.o mspec.o mstrike.o mtalk.o\ + newrand.o priest.o pdump.o save.o scr.o site1.o site2.o spell.o\ + stats.o time.o trap.o util.o village.o + +all: maps.dat omega + +omega: $(CUROBJ) $(CLROBJ) $(OBJ) + $(CC) $(LDFLAGS) $(OFLAGS) $(CUROBJ) $(CLROBJ) $(OBJ) $(LIBS) -o omega + rm date.c date.o + +date.c: + tools/makedate > date.c + +maps.dat: + cd tools; make + cd tools/libsrc; make maps.dat + +install: omega maps.dat $(BINDIR) $(LIBDIR) + cp omega $(BINDIR) + chmod 4711 $(BINDIR)/omega + - cp lib/* $(LIBDIR) + cp maps.dat $(LIBDIR) + chmod 0644 $(LIBDIR)/help*.txt $(LIBDIR)/license.txt $(LIBDIR)/motd.txt $(LIBDIR)/thanks.txt $(LIBDIR)/update.txt + chmod 0600 $(LIBDIR)/abyss.txt $(LIBDIR)/scroll[1234].txt $(LIBDIR)/maps.dat + chmod 0600 $(LIBDIR)/omega.hi $(LIBDIR)/omega.log $(LIBDIR)/omegahi.bak + +install_not_suid: omega maps.dat $(BINDIR) $(LIBDIR) + cp omega $(BINDIR) + chmod 0711 $(BINDIR)/omega + - cp lib/* $(LIBDIR) + cp maps.dat $(LIBDIR) + chmod 0644 $(LIBDIR)/help*.txt $(LIBDIR)/license.txt $(LIBDIR)/motd.txt $(LIBDIR)/thanks.txt $(LIBDIR)/update.txt + chmod 0644 $(LIBDIR)/abyss.txt $(LIBDIR)/scroll[1234].txt $(LIBDIR)/*.dat + chmod 0666 $(LIBDIR)/omega.hi $(LIBDIR)/omega.log + chmod 0600 $(LIBDIR)/omegahi.bak + +clean: + rm -f $(OBJ) clrgen.h clrgen.c genclr.o genclr omega + +distclean: + rm -f $(OBJ) $(CUROBJ) $(TOOLS) $(OLIBSTUFF) clrgen.h clrgen.c genclr.o genclr omega + cp lib/omega.hi.backup lib/omega.hi + cp lib/omega.log.backup lib/omega.log + +$(CUROBJ): ../opcurses/curses.h ../opcurses/cmacros.h ../opcurses/xcurses.h + +$(CLROBJ): clrgen.h + +$(OBJ): defs.h extern.h glob.h iinit.h minit.h clrgen.h + +clrgen.h clrgen.c: genclr.c minit.h defs.h + $(MAKE) genclr + $(CPP) $(OPDEF) -DOMEGA_CLRGEN *.[ch] | ./genclr clrgen.c clrgen.h + +genclr: genclr.o + $(CC) $(LDFLAGS) genclr.o -o genclr diff --git a/Makefile.ami b/Makefile.ami new file mode 100644 index 0000000..15186e6 --- /dev/null +++ b/Makefile.ami @@ -0,0 +1,46 @@ +# If you have gcc and don't intend to hack around with the game, +# I recommend setting CC to gcc and using -O (as the CFLAGS). + +CFLAGS = -O +LDFLAGS = -s +CC = gcc + +LIBS = -lc -lcurses -lamiga + +#################### that's it for changing the Makefile #################### + +OBJ = omega.o abyss.o aux1.o aux2.o aux3.o char.o city.o\ + command1.o command2.o command3.o compress.o\ + country.o effect1.o effect2.o effect3.o\ + etc.o env.o file.o gen1.o gen2.o guild1.o guild2.o house.o\ + init.o inv.o item.o itemf1.o itemf2.o itemf3.o lev.o\ + mmelee.o mmove.o mon.o move.o movef.o mspec.o\ + mstrike.o mtalk.o priest.o\ + save.o scr.o site1.o site2.o\ + spell.o time.o trap.o util.o village.o + +omega: $(OBJ) + $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o omega + +install: omega $(BINDIR) $(LIBDIR) + cp omega $(BINDIR) + chmod 4711 $(BINDIR)/omega + - cp ../omegalib/* $(LIBDIR) + chmod 0644 $(LIBDIR)/help*.txt $(LIBDIR)/license.txt $(LIBDIR)/motd.txt $(LIBDIR)/thanks.txt $(LIBDIR)/update.txt + chmod 0600 $(LIBDIR)/abyss.txt $(LIBDIR)/scroll[1234].txt $(LIBDIR)/*.dat + chmod 0600 $(LIBDIR)/omega.hi $(LIBDIR)/omega.log $(LIBDIR)/omegahi.bak + +install_not_suid: omega $(BINDIR) $(LIBDIR) + cp omega $(BINDIR) + chmod 0711 $(BINDIR)/omega + - cp ../omegalib/* $(LIBDIR) + chmod 0644 $(LIBDIR)/help*.txt $(LIBDIR)/license.txt $(LIBDIR)/motd.txt $(LIBDIR)/thanks.txt $(LIBDIR)/update.txt + chmod 0644 $(LIBDIR)/abyss.txt $(LIBDIR)/scroll[1234].txt $(LIBDIR)/*.dat + chmod 0666 $(LIBDIR)/omega.hi $(LIBDIR)/omega.log + chmod 0600 $(LIBDIR)/omegahi.bak + +clean: + rm -f $(OBJ) + rm -i omega + +$(OBJ): defs.h extern.h glob.h diff --git a/abyss.c b/abyss.c new file mode 100644 index 0000000..5206b06 --- /dev/null +++ b/abyss.c @@ -0,0 +1,212 @@ +/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */ +/* abyss.c */ +/* some functions to make the abyss level and run the final challenge */ + +#ifdef MSDOS_SUPPORTED_ANTIQUE +#include +#include +#ifdef SAVE_LEVELS +#include +#include +#endif +#endif + +#include "glob.h" + +/* loads the abyss level into Level*/ +void load_abyss(void) +{ + int i,j; + char site; + map *abyss; + + TempLevel = Level; + if (ok_to_free(TempLevel)) { +#ifndef SAVE_LEVELS + free_level(TempLevel); +#endif + TempLevel = NULL; + } +#ifndef SAVE_LEVELS + Level = ((plv) checkmalloc(sizeof(levtype))); +#else + msdos_changelevel(TempLevel,0,-1); + Level = &TheLevel; +#endif + + clear_level(Level); + + abyss = map_open(MAP_abyss); + map_setLevel(abyss,0); + Level->level_width = map_getWidth(abyss); + Level->level_length = map_getLength(abyss); + + for(j=0;jlevel_length;j++) { + for(i=0;ilevel_width;i++) { + site = map_getSiteChar(abyss,i,j); + Level->site[i][j].roomnumber = RS_ADEPT; + switch(site) { + case '0': + Level->site[i][j].locchar = VOID_CHAR; + Level->site[i][j].p_locf = L_VOID; + break; + case 'V': + Level->site[i][j].locchar = VOID_CHAR; + Level->site[i][j].p_locf = L_VOID_STATION; + break; + case '1': + Level->site[i][j].locchar = FLOOR; + Level->site[i][j].p_locf = L_VOICE1; + break; + case '2': + Level->site[i][j].locchar = FLOOR; + Level->site[i][j].p_locf = L_VOICE2; + break; + case '3': + Level->site[i][j].locchar = FLOOR; + Level->site[i][j].p_locf = L_VOICE3; + break; + case '~': + Level->site[i][j].locchar = WATER; + Level->site[i][j].p_locf = L_WATER_STATION; + break; + case ';': + Level->site[i][j].locchar = FIRE; + Level->site[i][j].p_locf = L_FIRE_STATION; + break; + case '"': + Level->site[i][j].locchar = HEDGE; + Level->site[i][j].p_locf = L_EARTH_STATION; + break; + case '6': + Level->site[i][j].locchar = WHIRLWIND; + Level->site[i][j].p_locf = L_AIR_STATION; + break; + case '#': + Level->site[i][j].locchar = WALL; + break; + case '.': + Level->site[i][j].locchar = FLOOR; + break; + } + } + } + map_close(abyss); +} + + +#ifdef SAVE_LEVELS +/* This stuff is in this file because the file was really small. */ + +void msdos_init(void) +{ + int i; + + /* Allocate the inner level of pointers for TheLevel */ + for (i = 0; i < MAXWIDTH; i++) + TheLevel.site[i] = (plc)checkmalloc(MAXLENGTH * sizeof(loctype)); + + /* Remove old level files */ + kill_all_levels(); +} + +void kill_all_levels(void) +{ + kill_levels("om*.lev"); +} + +void kill_levels(char *str) +{ + int i; + struct find_t buf; + + /* Remove old level files laying around */ + sprintf(Str1,"%s%s",Omegalib,str); + for (i = _dos_findfirst(Str1,_A_NORMAL,&buf); !i; i = _dos_findnext(&buf)) + { + sprintf(Str2,"%s%s",Omegalib,buf.name); + remove(Str2); + } +} + +#define MEM_CHECK_AMOUNT 0xf000 +void check_memory(void) +{ + char *mems[50]; + long amount = 0; + int num_mems = 0; + unsigned try; + + sprintf(Str1,"Heapchk returned %d.",_heapchk()); + mprint(Str1); + + try = MEM_CHECK_AMOUNT; + while (try > 10000) + { + while (try > 0 && (mems[num_mems] = checkmalloc(try)) == NULL) + try -= 0x400; + amount += try; + num_mems++; + } + while (--num_mems >= 0) + if (mems[num_mems] != NULL) + free(mems[num_mems]); + + sprintf(Str1,"Free mem approx %dK",(int)(amount / 0x400)); + mprint(Str1); +} + +static FILE *open_levfile(int env, int depth, int rw) +{ + sprintf(Str1,"%som%03d%03d.lev",Omegalib,env,depth); + return(fopen(Str1,(rw) ? "wb" : "rb")); +} + +/* Saves oldlevel (unless NULL), and reads in the new level, + unless depth is < 0. */ +plv msdos_changelevel(plv oldlevel, int newenv, int newdepth) +{ + FILE *fp; + + if (oldlevel != NULL) + { + if (oldlevel->environment == newenv && + oldlevel->depth == newdepth) + return(oldlevel); + if ((fp = open_levfile(oldlevel->environment,oldlevel->depth,1)) != NULL) + { + save_level(fp,oldlevel); + fclose(fp); + } + else + mprint("Cannot save level!!!"); + /* Free up monsters and items */ + free_level(oldlevel); + } + if (newdepth >= 0) + { + if ((fp = open_levfile(newenv,newdepth,0)) == NULL) + return(NULL); + restore_level(fp); + fclose(fp); + return(Level); + } + return(NULL); +} + +#endif + +#ifdef DJGPP + +void check_memory(void) +{ + clear_screen(); + print1("There should be over 300 K free on the drive."); + print2("Save _before_ the free space gets below 300 K."); + morewait(); + system("dir"); + morewait(); + clear_screen(); + xredraw(); +} +#endif diff --git a/aux1.c b/aux1.c new file mode 100644 index 0000000..25d3262 --- /dev/null +++ b/aux1.c @@ -0,0 +1,972 @@ +/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */ +/* aux1.c */ +/* auxiliary functions for those in com.c, also see aux2.c and aux3.c */ + +#include "glob.h" + + + +/* check to see if too much tunneling has been done in this level */ +void tunnelcheck(void) +{ + if ((Level->depth == 0 && Current_Environment != E_DLAIR) || + Current_Environment == E_ASTRAL) + return; + Level->tunnelled++; + if ((Level->tunnelled) > (Level->level_length)/4) + mprint("Dust and stone fragments fall on you from overhead."); + if ((Level->tunnelled) >(Level->level_length)/2) + mprint("You hear groaning and creaking noises."); + if ((Level->tunnelled) > (3*(Level->level_length))/4) + mprint("The floor trembles and you hear a loud grinding screech."); + if ((Level->tunnelled) > Level->level_length) { + mprint("With a scream of tortured stone, the entire dungeon caves in!!!"); + gain_experience(5000); + if (Player.status[SHADOWFORM]) { + change_environment(E_COUNTRYSIDE); + switch (Country[Player.x][Player.y].base_terrain_type) + { + case CASTLE: + case STARPEAK: + case CAVES: + case VOLCANO: + Country[Player.x][Player.y].current_terrain_type = MOUNTAINS; + break; + case DRAGONLAIR: + Country[Player.x][Player.y].current_terrain_type = DESERT; + break; + case MAGIC_ISLE: + Country[Player.x][Player.y].current_terrain_type = CHAOS_SEA; + break; + case PALACE: + Country[Player.x][Player.y].current_terrain_type = JUNGLE; + break; + } + Country[Player.x][Player.y].base_terrain_type = + Country[Player.x][Player.y].current_terrain_type; + c_set(Player.x, Player.y, CHANGED); + print1("In your shadowy state, you float back up to the surface."); + return; + } + mprint("You are flattened into an unpleasant jellylike substance."); + p_death("dungeon cave-in"); + } +} + +/* displays a room's name */ +void showroom(int i) +{ + strcpy(Str1,""); + strcpy(Str2,""); + switch(Current_Environment) { + case E_MANSION: + strcpy(Str2,"A luxurious mansion: "); + break; + case E_HOUSE: + strcpy(Str2,"A house: "); + break; + case E_HOVEL: + strcpy(Str2,"A hovel: "); + break; + case E_CITY: + strcpy(Str2,"The City of Rampart"); + break; + case E_VILLAGE: + switch(Villagenum) { + case 1: strcpy(Str2,"The Village of Star View"); break; + case 2: strcpy(Str2,"The Village of Woodmere"); break; + case 3: strcpy(Str2,"The Village of Stormwatch"); break; + case 4: strcpy(Str2,"The Village of Thaumaris"); break; + case 5: strcpy(Str2,"The Village of Skorch"); break; + case 6: strcpy(Str2,"The Village of Whorfen"); break; + } + break; + case E_CAVES: + strcpy(Str2,"The Goblin Caves: "); + break; + case E_CASTLE: + strcpy(Str2,"The Archmage's Castle: "); + break; + case E_ASTRAL: + strcpy(Str2,"The Astral Plane: "); + break; + case E_VOLCANO: + strcpy(Str2,"The Volcano: "); + break; + case E_PALACE: + strcpy(Str2,"The Palace Dungeons: "); + break; + case E_SEWERS: + strcpy(Str2,"The Sewers: "); + break; + case E_TACTICAL_MAP: + strcpy(Str2,"The Tactical Map "); + break; + default: + strcpy(Str2,""); + break; + } + if (Current_Environment == Current_Dungeon) { + strcpy(Str1,"Level "); + if (Level->depth < 10) { + Str1[6] = Level->depth + '0'; + Str1[7] = 0; + } + else { + Str1[6] = (Level->depth / 10) + '0'; + Str1[7] = (Level->depth % 10) + '0'; + Str1[8] = 0; + } + strcat(Str1," ("); + strcat(Str1,roomname(i)); + strcat(Str1,")"); + } + else if (strlen(Str2) == 0 || Current_Environment == E_MANSION || + Current_Environment == E_HOUSE || Current_Environment == E_HOVEL) + strcpy(Str1,roomname(i)); + strcat(Str2,Str1); + locprint(Str2); +} + + +int player_on_sanctuary(void) +{ + if ((Player.x==Player.sx) && + (Player.y==Player.sy)) + return(TRUE); + else { + if (Player.patron) { + if ((Level->site[Player.x][Player.y].locchar == ALTAR) && + (Level->site[Player.x][Player.y].aux == Player.patron)) + return(TRUE); + else return(FALSE); + } + else return(FALSE); + } +} + + +/* check a move attempt, maybe attack something, return TRUE if ok to move. */ +/* x y is the proposed place to move to */ +int p_moveable(int x, int y) +{ + setgamestatus(SKIP_MONSTERS); + if (! inbounds(x,y)) return (FALSE); + else if (Player.status[SHADOWFORM]) { + switch(Level->site[x][y].p_locf) { + case L_CHAOS: case L_ABYSS: case L_VOID: + return cinema_confirm("That looks dangerous.") == 'y'; + default: + resetgamestatus(SKIP_MONSTERS); + return(TRUE); + } + } + else if (loc_statusp(x,y,SECRET)) { + if (!gamestatusp(FAST_MOVE)) print3("Ouch!"); + return(FALSE); + } + else if (Level->site[x][y].creature != NULL) { + if (! gamestatusp(FAST_MOVE)) { + fight_monster(Level->site[x][y].creature); + resetgamestatus(SKIP_MONSTERS); + return(FALSE); + } + else return(FALSE); + } + else if ((Level->site[x][y].locchar == WALL) || + (Level->site[x][y].locchar == STATUE) || + (Level->site[x][y].locchar == PORTCULLIS) || + (Level->site[x][y].locchar == CLOSED_DOOR) || + (gamestatusp(FAST_MOVE) && + ((Level->site[x][y].locchar == HEDGE) || + (Level->site[x][y].locchar == LAVA) || + (Level->site[x][y].locchar == ABYSS) || + (Level->site[x][y].locchar == VOID_CHAR) || + (Level->site[x][y].locchar == FIRE) || + (Level->site[x][y].locchar == WHIRLWIND) || + (Level->site[x][y].locchar == WATER) || + (Level->site[x][y].locchar == LIFT) || + (Level->site[x][y].locchar == TRAP)))) { + if (! gamestatusp(FAST_MOVE)) print3("Ouch!"); + return(FALSE); + } + else if (optionp(CONFIRM)) { + if ((Level->site[x][y].locchar == HEDGE) || + (Level->site[x][y].locchar == LAVA) || + (Level->site[x][y].locchar == FIRE) || + (Level->site[x][y].locchar == WHIRLWIND) || + (Level->site[x][y].locchar == ABYSS) || + (Level->site[x][y].locchar == VOID_CHAR) || + (Level->site[x][y].locchar == WATER) || + (Level->site[x][y].locchar == RUBBLE) || + (Level->site[x][y].locchar == LIFT) || + (Level->site[x][y].locchar == TRAP)) { + /* horses WILL go into water... */ + if (gamestatusp(MOUNTED)) { + if (Level->site[x][y].locchar != WATER || + Level->site[x][y].p_locf != L_WATER) { + print1("You can't convince your steed to continue."); + setgamestatus(SKIP_MONSTERS); + return(FALSE); + } + else return(TRUE); + } + else if (cinema_confirm("Look where you're about to step!") == 'y') resetgamestatus(SKIP_MONSTERS); + else setgamestatus(SKIP_MONSTERS); + return(!gamestatusp(SKIP_MONSTERS)); + } + else { + resetgamestatus(SKIP_MONSTERS); + return(TRUE); + } + } + else { + resetgamestatus(SKIP_MONSTERS); + return(TRUE); + } +} + + + +/* check a move attempt in the countryside */ +int p_country_moveable(int x, int y) +{ + if (! inbounds(x,y)) return (FALSE); + else if (optionp(CONFIRM)) { + if ((Country[x][y].current_terrain_type == CHAOS_SEA) || + (Country[x][y].current_terrain_type == MOUNTAINS)) + return(cinema_confirm("That's dangerous terrain, and slow going.")=='y'); + else return(TRUE); + } + else return(TRUE); +} + + + + + +/* search once particular spot */ +void searchat(int x, int y) +{ + int i; + if (inbounds(x,y) && (random_range(3) || Player.status[ALERT])) { + if (loc_statusp(x,y,SECRET)) { + lreset(x,y,SECRET); + lset(x, y, CHANGED); + if ((Level->site[x][y].locchar==OPEN_DOOR) || + (Level->site[x][y].locchar==CLOSED_DOOR)) { + mprint("You find a secret door!"); + for(i=0;i<=8;i++) { /* FIXED! 12/25/98 */ + lset(x+Dirs[0][i],y+Dirs[1][i],STOPS); + lset(x+Dirs[0][i], y+Dirs[1][i], CHANGED); + } + } + else mprint("You find a secret passage!"); + drawvision(Player.x,Player.y); + } + if ((Level->site[x][y].p_locf >= TRAP_BASE) && + (Level->site[x][y].locchar != TRAP) && + (Level->site[x][y].p_locf <= TRAP_BASE+NUMTRAPS)) { + Level->site[x][y].locchar = TRAP; + lset(x, y, CHANGED); + mprint("You find a trap!"); + drawvision(Player.x,Player.y); + resetgamestatus(FAST_MOVE); + } + } +} + + + +/* This is to be called whenever anything might change player performance in + melee, such as changing weapon, statistics, etc. */ +void calc_melee(void) +{ + calc_weight(); + + Player.maxweight = (Player.str * Player.agi * 10); + Player.absorption = Player.status[PROTECTION]; + Player.defense = 2 * statmod(Player.agi)+(Player.level/2); + Player.hit = Player.level + statmod(Player.dex)+1; + Player.dmg = statmod(Player.str)+3; + Player.speed = 5 - min(4,(statmod(Player.agi)/2)); + if (Player.status[HASTED] > 0) Player.speed = Player.speed / 2; + if (Player.status[SLOWED] > 0) Player.speed = Player.speed * 2; + if (Player.itemweight > 0) + switch(Player.maxweight / Player.itemweight) { + case 0: Player.speed+=6; break; + case 1: Player.speed+=3; break; + case 2: Player.speed+=2; break; + case 3: Player.speed+=1; break; + } + + if (Player.status[ACCURATE]) Player.hit+=20; + if (Player.status[HERO]) Player.hit+=Player.dex; + if (Player.status[HERO]) Player.dmg+=Player.str; + if (Player.status[HERO]) Player.defense+=Player.agi; + if (Player.status[HERO]) Player.speed=Player.speed / 2; + + Player.speed = max(1,min(25,Player.speed)); + + if (gamestatusp(MOUNTED)) { + Player.speed = 3; + Player.hit += 10; + Player.dmg += 10; + } +#ifdef INCLUDE_MONKS + else if (Player.rank[MONKS] > 0) + { + /* monks are faster when not in armor or on horseback */ + if (Player.possessions[O_ARMOR] == NULL) { + Player.speed += (min(0,(Player.rank[MONKS] -1))); + } + } +#endif + /* weapon */ + /* have to check for used since it could be a 2h weapon just carried + in one hand */ + if (Player.possessions[O_WEAPON_HAND] != NULL) + if (Player.possessions[O_WEAPON_HAND]->used && + ((Player.possessions[O_WEAPON_HAND]->objchar==WEAPON)|| + (Player.possessions[O_WEAPON_HAND]->objchar==MISSILEWEAPON))) { + Player.hit += + Player.possessions[O_WEAPON_HAND]->hit + + Player.possessions[O_WEAPON_HAND]->plus; + Player.dmg += + Player.possessions[O_WEAPON_HAND]->dmg + + Player.possessions[O_WEAPON_HAND]->plus; + } + +#ifdef INCLUDE_MONKS + if (Player.rank[MONKS] > 0) + { + /* monks */ + /* aren't monks just obscene? PGM */ + if (Player.possessions[O_WEAPON_HAND] == NULL) /*barehanded*/ + { + /* all monks get a bonus in unarmed combat */ + Player.hit += ( Player.rank[MONKS] * Player.level ); + Player.dmg += ( Player.rank[MONKS] * Player.level ); + Player.defense += ( Player.rank[MONKS] * Player.level ); + + if (Player.rank[MONKS] == MONK_GRANDMASTER) + { + /* Grandmaster does 3x damage in unarmed combat. */ + Player.dmg *= 3; + } + } + } +#endif + + /* shield or defensive weapon */ + if (Player.possessions[O_SHIELD] != NULL) { + Player.defense += + Player.possessions[O_SHIELD]->aux + + Player.possessions[O_SHIELD]->plus; + } + + /* armor */ + if (Player.possessions[O_ARMOR] != NULL) { + Player.absorption += Player.possessions[O_ARMOR]->dmg; + Player.defense += + Player.possessions[O_ARMOR]->plus - + Player.possessions[O_ARMOR]->aux; + } + + if (strlen(Player.meleestr) > 2*maneuvers()) + default_maneuvers(); + comwinprint(); + showflags(); + dataprint(); +} + + +/* player attacks monster m */ +void fight_monster(struct monster *m) +{ + int hitmod = 0; + int reallyfight = TRUE; + + if (Player.status[AFRAID]) { + print3("You are much too afraid to fight!"); + reallyfight = FALSE; + } + else if (player_on_sanctuary()) { + print3("You restrain yourself from desecrating this holy place."); + reallyfight = FALSE; + } + else if (Player.status[SHADOWFORM]) { + print3("Your attack has no effect in your shadowy state."); + reallyfight = FALSE; + } + else if ((Player.status[BERSERK]<1) && (! m_statusp(m,HOSTILE))) { + if (optionp(BELLICOSE)) reallyfight = TRUE; + else reallyfight = 'y'==cinema_confirm("You're attacking without provokation."); + } + else reallyfight = TRUE; + + if (reallyfight) { + + if (Lunarity == 1) hitmod += Player.level; + else if (Lunarity == -1) hitmod -= (Player.level / 2); + + if (! m->attacked) Player.alignment -= 2; /* chaotic action */ + m_status_set(m,AWAKE); + m_status_set(m,HOSTILE); + m->attacked = TRUE; + Player.hit += hitmod; + tacplayer(m); + Player.hit -= hitmod; + } +} + + + + +/* Attempt to break an object o */ +int damage_item(pob o) +{ + /* special case -- break star gem */ + if (o->id == OB_STARGEM) { + print1("The Star Gem shatters into a million glistening shards...."); + if (Current_Environment == E_STARPEAK) { + if (! gamestatusp(KILLED_LAWBRINGER)) + print2("You hear an agonizing scream of anguish and despair."); + morewait(); + print1("A raging torrent of energy escapes in an explosion of magic!"); + print2("The energy flows to the apex of Star Peak where there is"); + morewait(); + clearmsg(); + print1("an enormous explosion!"); + morewait(); + annihilate(1); + print3("You seem to gain strength in the chaotic glare of magic!"); + Player.str = max(Player.str, Player.maxstr + 5); /* FIXED! 12/25/98 */ + Player.pow = max(Player.pow, Player.maxpow + 5); /* ditto */ + Player.alignment -= 200; + dispose_lost_objects(1,o); + } + else { + morewait(); + print1("The shards coalesce back together again, and vanish"); + print2("with a muted giggle."); + dispose_lost_objects(1,o); + Objects[o->id].uniqueness = UNIQUE_UNMADE; /* FIXED! 12/30/98 */ + } + return 1; + } + else { + if (o->fragility < random_range(30)) { + if (o->objchar == STICK && o->charge > 0) { + strcpy(Str1,"Your "); + strcat(Str1,(o->blessing >= 0 ? o->truename : o->cursestr)); + strcat(Str1," explodes!"); + print1(Str1); + morewait(); + nprint1(" Ka-Blamm!!!"); + /* general case. Some sticks will eventually do special things */ + morewait(); + manastorm(Player.x, Player.y, o->charge*o->level*10); + dispose_lost_objects(1,o); + return 1; + } + else if ((o->blessing > 0) && (o->level > random_range(10))) { + strcpy(Str1,"Your "); + strcat(Str1,itemid(o)); + strcat(Str1," glows strongly."); + print1(Str1); + return 0; + } + else if ((o->blessing < -1) && (o->level > random_range(10))) { + strcpy(Str1,"You hear an evil giggle from your "); + strcat(Str1,itemid(o)); + print1(Str1); + return 0; + } + else if (o->plus > 0) { + strcpy(Str1,"Your "); + strcat(Str1,itemid(o)); + strcat(Str1," glows and then fades."); + print1(Str1); + o->plus--; + return 0; + } + else { + if (o->blessing > 0) print1("You hear a faint despairing cry!"); + else if (o->blessing < 0) print1("You hear an agonized scream!"); + strcpy(Str1,"Your "); + strcat(Str1,itemid(o)); + strcat(Str1," shatters in a thousand lost fragments!"); + print2(Str1); + morewait(); + dispose_lost_objects(1,o); + return 1; + } + } + return 0; + } +} + +/* do dmg points of damage of type dtype, from source fromstring */ +void p_damage(int dmg, int dtype, char *fromstring) +{ + if (gamestatusp(FAST_MOVE)) { + drawvision(Player.x,Player.y); + resetgamestatus(FAST_MOVE); + } + if (! p_immune(dtype)) { + if (dtype == NORMAL_DAMAGE) Player.hp -= max(1,(dmg-Player.absorption)); + else Player.hp -= dmg; + if (Player.hp < 1) p_death(fromstring); + } + else mprint("You resist the effects!"); + dataprint(); +} + +/* game over, you lose! */ +void p_death(char *fromstring) +{ + Player.hp = -1; + print3("You died!"); + morewait(); + display_death(fromstring); + player_dump(); +#ifdef SAVE_LEVELS + kill_all_levels(); +#endif + endgraf(); + exit(0); +} + + +/* move the cursor around, like for firing a wand, sets x and y to target */ +void setspot(int *x, int *y) +{ + char c = ' '; + mprint("Targeting.... ? for help"); + omshowcursor(*x,*y); + while ((c != '.') && (c != ESCAPE)) { + c = lgetc(); + switch(c) { + case 'h':case '4': movecursor(x,y,-1,0); break; + case 'j':case '2': movecursor(x,y,0,1); break; + case 'k':case '8': movecursor(x,y,0,-1); break; + case 'l':case '6': movecursor(x,y,1,0); break; + case 'b':case '1': movecursor(x,y,-1,1); break; + case 'n':case '3': movecursor(x,y,1,1); break; + case 'y':case '7': movecursor(x,y,-1,-1); break; + case 'u':case '9': movecursor(x,y,1,-1); break; + case '?': + clearmsg(); + mprint("Use vi keys or numeric keypad to move cursor to target."); + mprint("Hit the '.' key when done, or ESCAPE to abort."); + break; + } + } + if (c==ESCAPE) *x = *y= ABORT; + screencheck(Player.x,Player.y); +} + + +/* get a direction: return index into Dirs array corresponding to direction */ +int getdir(void) +{ + while (1) { + mprint("Select direction [hjklyubn, ESCAPE to quit]: "); + switch (mgetc()) { + case '4': + case 'h': + case 'H': return(5); + case '2': + case 'j': + case 'J': return(6); + case '8': + case 'k': + case 'K': return(7); + case '6': + case 'l': + case 'L': return(4); + case '7': + case 'y': + case 'Y': return(3); + case '9': + case 'u': + case 'U': return(1); + case '1': + case 'b': + case 'B': return(2); + case '3': + case 'n': + case 'N': return(0); + case ESCAPE: return(ABORT); + default: print3("That's not a direction! "); + } + } +} + + + +/* functions describes monster m's state for examine function */ +char *mstatus_string(struct monster *m) +{ + if (m_statusp(m, M_INVISIBLE) && !Player.status[TRUESIGHT]) + strcpy(Str2, "Some invisible creature"); + else if (m->uniqueness == COMMON) { + if (m->hp < Monsters[m->id].hp / 3) + strcpy(Str2,"a grievously injured "); + else if (m->hp < Monsters[m->id].hp / 2) + strcpy(Str2,"a severely injured "); + else if (m->hp < Monsters[m->id].hp) + strcpy(Str2,"an injured "); + else strcpy(Str2,getarticle(m->monstring)); + if (m->level > Monsters[m->id].level) { + strcat(Str2," (level "); + strcat(Str2,wordnum(m->level+1-Monsters[m->id].level)); + strcat(Str2,") "); + } + strcat(Str2,m->monstring); + } + else { + strcpy(Str2,m->monstring); + if (m->hp < Monsters[m->id].hp / 3) + strcat(Str2," who is grievously injured "); + else if (m->hp < Monsters[m->id].hp / 2) + strcat(Str2," who is severely injured "); + else if (m->hp < Monsters[m->id].hp) + strcat(Str2," who is injured "); + } + return(Str2); +} + + + + +/* for the examine function */ +void describe_player(void) +{ + if (Player.hp < (Player.maxhp /5)) + print1("A grievously injured "); + else if (Player.hp < (Player.maxhp /2)) + print1("A seriously wounded "); + else if (Player.hp < Player.maxhp) + print1("A somewhat bruised "); + else print1("A fit "); + + if (Player.status[SHADOWFORM]) + nprint1("shadow"); + else + nprint1(levelname(Player.level)); + nprint1(" named "); + nprint1(Player.name); + if (gamestatusp(MOUNTED)) + nprint1(" (riding a horse.)"); +} + + +/* access to player experience... */ +/* share out experience among guild memberships */ +void gain_experience(int amount) +{ + int i,count=0,share; + Player.xp += (long) amount; + gain_level(); /* actually, check to see if should gain level */ + for(i=0;i 0) count++; + share = amount/(max(count,1)); + for(i=0;i 0) Player.guildxp[i]+=share; +} + +/* try to hit a monster in an adjacent space. If there are none + return FALSE. Note if you're berserk you get to attack ALL + adjacent monsters! */ +int goberserk(void) +{ + int wentberserk=FALSE,i; + char meleestr[80]; + strcpy(meleestr,Player.meleestr); + strcpy(Player.meleestr,"lLlClH"); + for(i=0;i<8;i++) + if (Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].creature + != NULL) { + wentberserk=TRUE; + fight_monster(Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].creature); + morewait(); + } + strcpy(Player.meleestr,meleestr); + return(wentberserk); +} + +/* identifies a trap for examine() by its aux value */ +char *trapid(int trapno) +{ + switch (trapno) { + case L_TRAP_SIREN:return("A siren trap"); + case L_TRAP_DART:return("A dart trap"); + case L_TRAP_PIT:return("A pit"); + case L_TRAP_SNARE:return("A snare"); + case L_TRAP_BLADE:return("A blade trap"); + case L_TRAP_FIRE:return("A fire trap"); + case L_TRAP_TELEPORT:return("A teleport trap"); + case L_TRAP_DISINTEGRATE:return("A disintegration trap"); + case L_TRAP_DOOR:return("A trap door"); + case L_TRAP_MANADRAIN:return("A manadrain trap"); + case L_TRAP_ACID:return("An acid shower trap"); + case L_TRAP_SLEEP_GAS:return("A sleep gas trap"); + case L_TRAP_ABYSS:return("A concealed entrance to the abyss"); + default: return("A completely inoperative trap."); + } +} + + +/* checks current food status of player, every hour, and when food is eaten */ +void foodcheck(void) +{ + if (Player.food > 48) { + print3("You vomit up your huge meal."); + Player.food = 12; + } + else if (Player.food == 30) + print3("Time for a smackerel of something."); + else if (Player.food == 20) + print3("You feel hungry."); + else if (Player.food == 12) + print3("You are ravenously hungry."); + else if (Player.food == 3) { + print3("You feel weak."); + if (gamestatusp(FAST_MOVE)) { + drawvision(Player.x,Player.y); + resetgamestatus(FAST_MOVE); + } + } + else if (Player.food < 0) { + if (gamestatusp(FAST_MOVE)) { + drawvision(Player.x,Player.y); + resetgamestatus(FAST_MOVE); + } + print3("You're starving!"); + p_damage(-5*Player.food,UNSTOPPABLE,"starvation"); + } + showflags(); +} + + + + +/* see whether room should be illuminated */ +void roomcheck(void) +{ + static int oldroomno = -1; +#ifdef MSDOS_SUPPORTED_ANTIQUE + static int oldlevel = -1; +#else + static plv oldlevel = NULL; +#endif + int roomno = Level->site[Player.x][Player.y].roomnumber; + + if ((roomno == RS_CAVERN) || + (roomno == RS_SEWER_DUCT) || + (roomno == RS_KITCHEN) || + (roomno == RS_BATHROOM) || + (roomno == RS_BEDROOM) || + (roomno == RS_DININGROOM) || + (roomno == RS_CLOSET) || + (roomno > ROOMBASE)) + if ((! loc_statusp(Player.x,Player.y,LIT)) && + (! Player.status[BLINDED]) && + (Player.status[ILLUMINATION] || (difficulty() < 6))) { + showroom(Level->site[Player.x][Player.y].roomnumber); + spreadroomlight(Player.x,Player.y,roomno); + levelrefresh(); + } + if ((oldroomno != roomno) || +#ifdef MSDOS_SUPPORTED_ANTIQUE + (oldlevel != Level->depth)) { +#else + (oldlevel != Level)) { +#endif + showroom(roomno); + oldroomno = roomno; +#ifdef MSDOS_SUPPORTED_ANTIQUE + oldlevel = Level->depth; +#else + oldlevel = Level; +#endif + } +} + + +/* ask for mercy */ +void surrender(struct monster *m) +{ + int i; + long bestitem,bestvalue; + + switch(random_range(4)) { + case 0: print1("You grovel at the monster's feet..."); break; + case 1: print1("You cry 'uncle'!"); break; + case 2: print1("You beg for mercy."); break; + case 3: print1("You yield to the monster."); break; + } + if (m->id == GUARD) { + if (m_statusp(m,HOSTILE)) + monster_talk(m); + else { + print2("The guard (bored): Have you broken a law? [yn] "); + if (ynq2() == 'y') { + print2("The guard grabs you, and drags you to court."); + morewait(); + send_to_jail(); + } + else print2("Then don't bother me. Scat!"); + } + } + else if ((m->talkf==M_NO_OP) || + (m->talkf==M_TALK_STUPID)) + print3("Your plea is ignored."); + else { + morewait(); + print1("Your surrender is accepted."); + if (Player.cash > 0) nprint1(" All your gold is taken...."); + Player.cash = 0; + bestvalue = 0; + bestitem = ABORT; + for (i=1;ixpv); + nprint2("The monster seems more experienced!"); + m->level = (min(10,m->level+1)); + m->hp += m->level*20; + m->hit += m->level; + m->dmg += m->level; + m->ac += m->level; + m->xpv += m->level*10; + morewait(); + clearmsg(); + if ((m->talkf == M_TALK_EVIL) && random_range(10)) { + print1("It continues to attack you, laughing evilly!"); + m_status_set(m,HOSTILE); + m_status_reset(m,GREEDY); + } + else if (m->id == HORNET || m->id == GUARD) + print1("It continues to attack you. "); + else { + print1("The monster leaves, chuckling to itself...."); + m_teleport(m); + } + } + dataprint(); +} + + +/* threaten a monster */ +void threaten(struct monster *m) +{ + char response; + switch(random_range(4)) { + case 0:mprint("You demand that your opponent surrender!"); break; + case 1:mprint("You threaten to do bodily harm to it."); break; + case 2:mprint("You attempt to bluster it into submission."); break; + case 3:mprint("You try to cow it with your awesome presence."); break; + } + morewait(); /* FIXED! 12/25/98 */ + if (! m_statusp(m,HOSTILE)) { + print3("You only annoy it with your futile demand."); + m_status_set(m,HOSTILE); + } + else if (((m->level*2 > Player.level) && (m->hp > Player.dmg)) || + (m->uniqueness != COMMON)) + print1("It sneers contemptuously at you."); + else if ((m->talkf != M_TALK_GREEDY) && + (m->talkf != M_TALK_HUNGRY) && + (m->talkf != M_TALK_EVIL) && + (m->talkf != M_TALK_MAN) && + (m->talkf != M_TALK_BEG) && + (m->talkf != M_TALK_THIEF) && + (m->talkf != M_TALK_MERCHANT) && + (m->talkf != M_TALK_IM)) + print1("Your demand is ignored"); + else { + print1("It yields to your mercy."); + Player.alignment+=3; + print2("Kill it, rob it, or free it? [krf] "); + do response = (char) mcigetc(); + while ((response != 'k')&&(response != 'r')&&(response !='f')); + if (response == 'k') { + m_death(m); + print2("You treacherous rogue!"); + Player.alignment -= 13; + } + else if (response == 'r') { + Player.alignment-=2; + print2("It drops its treasure and flees."); + m_dropstuff(m); + m_remove( m ); + } + else { + Player.alignment+=2; + print2("'If you love something set it free ... '"); + if (random_range(100)==13) { + morewait(); + print2("'...If it doesn't come back, hunt it down and kill it.'"); + } + print3("It departs with a renewed sense of its own mortality."); + m_remove( m ); + } + } +} + +/* name of the player's experience level */ +char *levelname(int level) +{ + switch(level) { + case 0:strcpy(Str3,"neophyte");break; + case 1:strcpy(Str3,"beginner");break; + case 2:strcpy(Str3,"tourist");break; + case 3:strcpy(Str3,"traveller");break; + case 4:strcpy(Str3,"wayfarer");break; + case 5:strcpy(Str3,"peregrinator");break; + case 6:strcpy(Str3,"wanderer");break; + case 7:strcpy(Str3,"hunter");break; + case 8:strcpy(Str3,"scout");break; + case 9:strcpy(Str3,"trailblazer");break; + case 10:strcpy(Str3,"discoverer");break; + case 11:strcpy(Str3,"explorer");break; + case 12:strcpy(Str3,"senior explorer");break; + case 13:strcpy(Str3,"ranger");break; + case 14:strcpy(Str3,"ranger captain");break; + case 15:strcpy(Str3,"ranger knight");break; + case 16:strcpy(Str3,"adventurer");break; + case 17:strcpy(Str3,"experienced adventurer");break; + case 18:strcpy(Str3,"skilled adventurer");break; + case 19:strcpy(Str3,"master adventurer");break; + case 20:strcpy(Str3,"hero");break; + case 21:strcpy(Str3,"superhero");break; + case 22:strcpy(Str3,"demigod");break; + default: + if (level < 100) { + strcpy(Str3,"Order "); + Str3[6] = ((level/10)-2) + '0'; + Str3[7] = 0; + strcat(Str3," Master of Omega"); + } + else strcpy(Str3,"Ultimate Master of Omega"); + break; + } + return(Str3); +} diff --git a/aux2.c b/aux2.c new file mode 100644 index 0000000..2f7e5ae --- /dev/null +++ b/aux2.c @@ -0,0 +1,1215 @@ +/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */ +/* aux2.c */ +/* some functions called by ocom.c, also see aux1.c and aux3.c*/ +/* This is a real grab bag file. It contains functions used by + aux1.c and omega.c, as well as elsewhere. It is mainly here so aux1.c + and aux3.c are not huge */ + +#include "glob.h" + +/* Player stats like str, agi, etc give modifications to various abilities + chances to do things, etc. Positive is good, negative bad. */ +int statmod(int stat) +{ + return((stat-10)/2); +} + + +/* effects of hitting */ +void p_hit (struct monster *m,int dmg,int dtype) +{ + int dmult = 0; + + /* chance for critical hit..., 3/10 */ + switch (random_range(10)) { + case 0: + if (random_range(100) < (Player.level +#ifdef INCLUDE_MONKS + + Player.rank[MONKS] +#endif + )) { + strcpy(Str3,"You annihilate "); + dmult = 1000; + } + else { + strcpy(Str3,"You blast "); + dmult=5; + } + break; + case 1: + case 2: + strcpy(Str3,"You smash "); + dmult=2; break; + + default: + dmult=1; + if (random_range(10)) strcpy(Str3,"You hit "); +#ifdef NEW_QUOTES + else switch(random_range(12)) { +#else + else switch(random_range(4)) { +#endif + case 0: strcpy(Str3,"You damage "); break; + case 1: strcpy(Str3,"You inflict bodily harm on "); break; + case 2: strcpy(Str3,"You injure "); break; + case 3: strcpy(Str3,"You molest "); break; + case 4: strcpy(Str3,"You tweak "); break; + case 5: strcpy(Str3,"You smush "); break; + case 6: strcpy(Str3,"You smurf "); break; + case 7: strcpy(Str3,"You grind "); break; + case 8: strcpy(Str3,"You hurt "); break; + case 9: strcpy(Str3,"You bring pain to "); break; + case 10: strcpy(Str3,"You recite nasty poetry at "); break; + case 11: strcpy(Str3,"You smack "); break; + } + break; + } + + if (Lunarity == 1) dmult = dmult * 2; + else if (Lunarity == -1) dmult = dmult / 2; + if (m->uniqueness == COMMON) strcat(Str3,"the "); + strcat(Str3,m->monstring); + strcat(Str3,". "); + if (Verbosity != TERSE) mprint(Str3); + else mprint("You hit it."); + +#ifdef INCLUDE_MONKS + if (Player.possessions[O_WEAPON_HAND] == NULL) { /*barehanded*/ + if (Player.rank[MONKS] > MONK_MASTER_SIGHS) { + /* high level monks do unstoppable hand damage */ + dtype = UNSTOPPABLE; + } + } +#endif + m_damage(m,dmult * random_range(dmg),dtype); + if ((Verbosity != TERSE) && (random_range(10)==3) && (m->hp > 0)) + mprint("It laughs at the injury and fights on!"); +} + +/* and effects of missing */ +void player_miss(struct monster *m,int dtype) +{ + if (random_range(30)==1) /* fumble 1 in 30 */ + p_fumble(dtype); + else { + if (Verbosity != TERSE) { + if (random_range(10)) + strcpy(Str3,"You miss "); + else switch(random_range(4)) { + case 0: strcpy(Str3,"You flail lamely at "); break; + case 1: strcpy(Str3,"You only amuse "); break; + case 2: strcpy(Str3,"You fail to even come close to "); break; + case 3: strcpy(Str3,"You totally avoid contact with "); break; + } + if (m->uniqueness == COMMON) strcat(Str3,"the "); + strcat(Str3,m->monstring); + strcat(Str3,". "); + mprint(Str3); + } + else mprint("You missed it."); + } +} + +/* oh nooooo, a fumble.... */ +void p_fumble(int dtype) +{ + mprint("Ooops! You fumbled...."); + switch(random_range(10)) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: drop_weapon(); break; + case 6: + case 7: + case 8: break_weapon(); break; + case 9: mprint("Oh No! You hit yourself!"); + p_damage(Player.dmg,dtype,"stupidity"); + break; + } +} + +/* try to drop a weapon (from fumbling) */ +void drop_weapon(void) +{ + if (Player.possessions[O_WEAPON_HAND] != NULL) { + strcpy(Str1,"You dropped your "); + strcat(Str1,Player.possessions[O_WEAPON_HAND]->objstr); + mprint(Str1); + morewait(); + p_drop_at(Player.x,Player.y,1,Player.possessions[O_WEAPON_HAND]); + conform_lost_objects(1,Player.possessions[O_WEAPON_HAND]); + } + else mprint("You feel fortunate."); +} + + +/* try to break a weapon (from fumbling) */ +void break_weapon(void) +{ + if (Player.possessions[O_WEAPON_HAND] != NULL) { + strcpy(Str1,"Your "); + strcat(Str1,itemid(Player.possessions[O_WEAPON_HAND])); + strcat(Str1," vibrates in your hand...."); + mprint(Str1); + (void) damage_item(Player.possessions[O_WEAPON_HAND]); + morewait(); + } +} + + +/* hooray */ +void p_win(void) +{ + morewait(); + clearmsg(); + print1("You won!"); + morewait(); + display_win(); + endgraf(); + exit(0); +} + + +/* handle a h,j,k,l, etc., to change x and y by dx and dy */ +/* for targeting in dungeon */ +void movecursor(int *x, int *y, int dx, int dy) +{ + if (inbounds(*x+dx,*y+dy)) { + *x += dx; + *y += dy; + screencheck(*x,*y); + } + omshowcursor(*x,*y); +} + + +/* is Player immune to damage type dtype */ +int p_immune(int dtype) +{ + return(Player.immunity[dtype]>0); +} + + +/* deal with each possible stati -- values are per move */ +/* this function is executed every move */ +/* A value over 1000 indicates a permanent effect */ +void minute_status_check(void) +{ + int i; + + if (Player.status[HASTED]>0) { + if (Player.status[HASTED] < 1000) { + Player.status[HASTED]--; + if (Player.status[HASTED]==0) { + mprint("The world speeds up."); + calc_melee(); + } + } + } + + + if (Player.status[POISONED]>0) { + Player.status[POISONED]--; + p_damage(3,POISON,"poison"); + if (Player.status[POISONED] == 0) { + showflags(); + mprint("You feel better now."); + } + } + + + if (Player.immunity[UNSTOPPABLE]>0) { + for(i=0;i0) { + Player.status[IMMOBILE]--; + if (Player.status[IMMOBILE] == 0) + mprint("You can move again."); + } + + + if (Player.status[SLEPT]>0) { + Player.status[SLEPT]--; + if (Player.status[SLEPT] == 0) { + mprint("You woke up."); + } + } + + if (Player.status[REGENERATING]>0) { + if ((Player.hp < Player.maxhp) && (Player.mana > 0)){ + Player.hp++; + Player.mana--; + dataprint(); + } + if (Player.status[REGENERATING] < 1000) { + Player.status[REGENERATING]--; + if (Player.status[REGENERATING] == 0) { + mprint("You feel less homeostatic."); + } + } + } + + if (Player.status[SLOWED]>0) { + if (Player.status[SLOWED] < 1000) { + Player.status[SLOWED]--; + if (Player.status[SLOWED] == 0) { + mprint("You feel quicker now."); + calc_melee(); + } + } + } + + if (Player.status[RETURNING]>0) { + Player.status[RETURNING]--; + if (Player.status[RETURNING] == 10) + mprint("Your return spell slowly hums towards activation..."); + else if (Player.status[RETURNING] == 8) + mprint("There is an electric tension in the air!"); + else if (Player.status[RETURNING] == 5) + mprint("A vortex of mana begins to form around you!"); + else if (Player.status[RETURNING] == 1) + mprint("Your surroundings start to warp and fade!"); + if (Player.status[RETURNING] == 0) + level_return(); + } + + if (Player.status[AFRAID]>0) { + if (Player.status[AFRAID] < 1000) { + Player.status[AFRAID]--; + if (Player.status[AFRAID] == 0) { + mprint("You feel bolder now."); + } + } + } + +} + + + +/* effect of gamma ray radiation... */ +void moon_check(void) +{ + /* 24 day lunar cycle */ + Phase = (Phase+1)%24; + phaseprint(); + Lunarity = 0; + if (((Player.patron == DRUID) && ((Phase/2 == 3) || (Phase/2 == 9))) || + ((Player.alignment > 10) && (Phase/2 == 6)) || + ((Player.alignment < -10) && (Phase/2 == 0))) { + mprint("As the moon rises you feel unusually vital!"); + Lunarity = 1; + } + else + if (((Player.patron == DRUID) && ((Phase/2 == 0) || (Phase/2 == 6))) || + ((Player.alignment > 10) && (Phase/2 == 0)) || + ((Player.alignment < -10) && (Phase/2 == 6))) { + mprint("The rise of the moon tokens a strange enervation!"); + Lunarity = -1; + } + +} + + + +/* check 1/hour for torch to burn out if used */ +void torch_check(void) +{ + int i; + for(i=O_READY_HAND;i<=O_WEAPON_HAND;i++) { + if (Player.possessions[i]!=NULL) + if ((Player.possessions[i]->id == OB_TORCH) && /*torch */ + (Player.possessions[i]->aux > 0)) { + Player.possessions[i]->aux--; + if (Player.possessions[i]->aux==0) { + mprint("Your torch goes out!!!"); + conform_unused_object(Player.possessions[i]); + if (Player.possessions[i]->number > 1) { + Player.possessions[i]->number--; + Player.possessions[i]->aux = 6; + } + else { + Player.possessions[i]->usef = I_NO_OP; + Player.possessions[i]->cursestr = + Player.possessions[i]->truename = + Player.possessions[i]->objstr = "burnt-out torch"; + } + } + } + } +} + + + +/* values are in multiples of ten minutes */ +/* values over 1000 indicate a permanent effect */ +void tenminute_status_check(void) +{ + if ((Player.status[SHADOWFORM]>0) && (Player.status[SHADOWFORM]<1000)) { + Player.status[SHADOWFORM]--; + if (Player.status[SHADOWFORM] == 0) { + Player.immunity[NORMAL_DAMAGE]--; + Player.immunity[ACID]--; + Player.immunity[THEFT]--; + Player.immunity[INFECTION]--; + mprint("You feel less shadowy now."); + } + } + + if ((Player.status[ILLUMINATION]>0) && (Player.status[ILLUMINATION]<1000)) { + Player.status[ILLUMINATION]--; + if (Player.status[ILLUMINATION] == 0) { + mprint("Your light goes out!"); + } + } + + + if ((Player.status[VULNERABLE]>0) && (Player.status[VULNERABLE]<1000)){ + Player.status[VULNERABLE]--; + if (Player.status[VULNERABLE] == 0) + mprint("You feel less endangered."); + } + + + if ((Player.status[DEFLECTION]>0) && (Player.status[DEFLECTION]<1000)){ + Player.status[DEFLECTION]--; + if (Player.status[DEFLECTION] == 0) + mprint("You feel less well defended."); + } + + if ((Player.status[ACCURATE]>0) && (Player.status[ACCURACY]<1000)){ + Player.status[ACCURATE]--; + if (Player.status[ACCURATE] == 0) { + calc_melee(); + mprint("The bulls' eyes go away."); + } + } + if ((Player.status[HERO]>0) && (Player.status[HERO]<1000)){ + Player.status[HERO]--; + if (Player.status[HERO] == 0) { + calc_melee(); + mprint("You feel less than super."); + } + } + + if ((Player.status[LEVITATING]>0) && (Player.status[LEVITATING]<1000)){ + Player.status[LEVITATING]--; + if (Player.status[LEVITATING] == 0) + mprint("You're no longer walking on air."); + } + + if (Player.status[DISEASED]>0) { + Player.status[DISEASED]--; + if (Player.status[DISEASED] == 0) { + showflags(); + mprint("You feel better now."); + } + } + + + if ((Player.status[INVISIBLE] > 0) && (Player.status[INVISIBLE]<1000)){ + Player.status[INVISIBLE]--; + if (Player.status[INVISIBLE] == 0) + mprint("You feel more opaque now."); + } + + if ((Player.status[BLINDED]>0) && (Player.status[BLINDED]<1000)) { + Player.status[BLINDED]--; + if (Player.status[BLINDED] == 0) + mprint("You can see again."); + } + + if ((Player.status[TRUESIGHT]>0) && (Player.status[TRUESIGHT]<1000)) { + Player.status[TRUESIGHT]--; + if (Player.status[TRUESIGHT] == 0) + mprint("You feel less keen now."); + } + + if ((Player.status[BERSERK]>0) && (Player.status[BERSERK]<1000)) { + Player.status[BERSERK]--; + if (Player.status[BERSERK] == 0) + mprint("You stop foaming at the mouth."); + } + + if ((Player.status[ALERT]>0) && (Player.status[ALERT] < 1000)) { + Player.status[ALERT]--; + if (Player.status[ALERT] == 0) + mprint("You feel less alert now."); + } + + if ((Player.status[BREATHING]>0) && (Player.status[BREATHING] < 1000)) { + Player.status[BREATHING]--; + if (Player.status[BREATHING] == 0) + mprint("You feel somewhat congested."); + } + + if ((Player.status[DISPLACED]>0) && (Player.status[DISPLACED] < 1000)) { + Player.status[DISPLACED]--; + if (Player.status[DISPLACED]==0) + mprint("You feel a sense of position."); + } + timeprint(); + dataprint(); +} + + + +/* Increase in level at appropriate experience gain */ +void gain_level(void) +{ + int gained=FALSE; + int hp_gain; /* FIXED! 12/30/98 */ + + if (gamestatusp(SUPPRESS_PRINTING)) + return; + while (expval(Player.level+1) <= Player.xp) { + if (!gained) + morewait(); + gained = TRUE; + Player.level++; + print1("You have attained a new experience level!"); + print2("You are now "); + nprint2(getarticle(levelname(Player.level))); + nprint2(levelname(Player.level)); + hp_gain = random_range(Player.con)+1; /* start fix 12/30/98 */ + if (Player.hp < Player.maxhp ) + Player.hp += hp_gain*Player.hp/Player.maxhp; + else if (Player.hp < Player.maxhp + hp_gain) + Player.hp = Player.maxhp + hp_gain; + /* else leave current hp alone */ + Player.maxhp += hp_gain; + Player.maxmana = calcmana(); + /* If the character was given a bonus, let him keep it. Otherwise + * recharge him. */ + Player.mana = max(Player.mana, Player.maxmana); /* end fix 12/30/98 */ + morewait(); + } + if (gained) clearmsg(); + calc_melee(); +} + +/* experience requirements */ +long expval(plevel) +int plevel; +{ + switch(plevel) { + case 0:return(0L); + case 1:return(20L); + case 2:return(50L); + case 3:return(200L); + case 4:return(500L); + case 5:return(1000L); + case 6:return(2000L); + case 7:return(3000L); + case 8:return(5000L); + case 9:return(7000L); + case 10:return(10000L); + default: + if (plevel < 20) + return((plevel-9) * 10000L); + else + return((plevel-9) * 10000L + + (plevel-19)*(plevel-19)*500); + } +} + +/* If an item is unidentified, it isn't worth much to those who would buy it */ +long item_value(pob item) +{ + if (item->known == 0) { + if (item->objchar == THING) return(1); + else return(true_item_value(item) / 10); + } + else if (item->known == 1) { + if (item->objchar == THING) return(item->basevalue); + else return(item->basevalue / 2); + } + else return(true_item_value(item)); +} + + +/* figures value based on item base-value, charge, plus, and blessing */ +long true_item_value(pob item) +{ + long value = item->basevalue; + + if (item->objchar == THING) return(item->basevalue); + else { + if (item->objchar == STICK) value += value*item->charge/20; + if (item->plus > -1) value += value*item->plus/4; + else value /= -item->plus; + if (item->blessing > 0) value *= 2; + return((long) value); + } +} + +/* kill off player if he isn't got the "breathing" status */ +void p_drown(void) +{ + int attempts = 3, i; + + if (Player.status[BREATHING] > 0) + mprint("Your breathing is unaffected!"); + else while (Player.possessions[O_ARMOR] || + Player.itemweight > ((int) (Player.maxweight / 2))) { + menuclear(); + switch (attempts--) { + case 3: print3("You try to hold your breath..."); break; + case 2: print3("You try to hold your breath... You choke..."); break; + case 1: print3("You try to hold your breath... You choke... Your lungs fill..."); break; + case 0: p_death("drowning"); + } + morewait(); + menuprint("a: Drop an item.\n"); + menuprint("b: Bash an item.\n"); + menuprint("c: Drop your whole pack.\n"); + showmenu(); + switch(menugetc()) { + case 'a': + drop(); + if (Level->site[Player.x][Player.y].p_locf == L_WATER && Level->site[Player.x][Player.y].things) + { + mprint("It sinks without a trace."); + free_objlist(Level->site[Player.x][Player.y].things); + Level->site[Player.x][Player.y].things = NULL; + } + break; + case 'b': + bash_item(); + break; + case 'c': + setgamestatus(SUPPRESS_PRINTING); + for(i=0;isite[Player.x][Player.y].p_locf != L_WATER) + { + p_drop_at(Player.x,Player.y,Player.pack[i]->number,Player.pack[i]); + free_obj( Player.pack[i], TRUE ); + } else + free_obj( Player.pack[i], TRUE ); + } + Player.pack[i] = NULL; + } + if (Level->site[Player.x][Player.y].p_locf == L_WATER) + mprint("It sinks without a trace."); + Player.packptr = 0; + resetgamestatus(SUPPRESS_PRINTING); + calc_melee(); + break; + } + } + show_screen(); + return; +} + + +/* the effect of some weapon on monster m, with dmgmod a bonus to damage */ +void weapon_use(int dmgmod, pob weapon, struct monster *m) +{ + int aux = (weapon==NULL ? -2 : weapon->aux); /* bare hands */ + switch(aux) { + case -2: weapon_bare_hands(dmgmod,m); break; + default: + case I_NO_OP: weapon_normal_hit(dmgmod,weapon,m); break; + case I_ACIDWHIP: weapon_acidwhip(dmgmod,weapon,m); break; + case I_TANGLE: weapon_tangle(dmgmod,weapon,m); break; + case I_ARROW: weapon_arrow(dmgmod,weapon,m); break; + case I_BOLT: weapon_bolt(dmgmod,weapon,m); break; + case I_DEMONBLADE: weapon_demonblade(dmgmod,weapon,m); break; + case I_LIGHTSABRE: weapon_lightsabre(dmgmod,weapon,m); break; + case I_MACE_DISRUPT: weapon_mace_disrupt(dmgmod,weapon,m); break; + case I_VORPAL: weapon_vorpal(dmgmod,weapon,m); break; + case I_DESECRATE: weapon_desecrate(dmgmod,weapon,m); break; + case I_FIRESTAR: weapon_firestar(dmgmod,weapon,m); break; + case I_DEFEND: weapon_defend(dmgmod,weapon,m); break; + case I_VICTRIX: weapon_victrix(dmgmod,weapon,m); break; + case I_SCYTHE: weapon_scythe(dmgmod,weapon,m); break; + } +} + + +/* for printing actions in printactions above */ +char *actionlocstr(char dir) +{ + switch(dir) { + case 'L': strcpy(Str3,"low."); break; + case 'C': strcpy(Str3,"center."); break; + case 'H': strcpy(Str3,"high."); break; + default: strcpy(Str3,"wildly."); break; + } + return(Str3); +} + + +/* execute player combat actions versus monster m */ +void tacplayer(struct monster *m) +{ + int i=0; + + while (i < strlen(Player.meleestr)) { + if (m->hp > 0) { + switch(Player.meleestr[i]) { + case 't': case 'T': + if (Player.possessions[O_WEAPON_HAND] == NULL) + strcpy(Str1,"You punch "); + else strcpy(Str1,"You thrust "); + strcat(Str1,actionlocstr(Player.meleestr[i+1])); + if (Verbosity == VERBOSE) mprint(Str1); + if (player_hit(2*statmod(Player.dex),Player.meleestr[i+1],m)) + weapon_use(0,Player.possessions[O_WEAPON_HAND],m); + else player_miss(m,NORMAL_DAMAGE); + break; + case 'c': case 'C': + if (Player.possessions[O_WEAPON_HAND] == NULL) + strcpy(Str1,"You punch "); + else if (Player.possessions[O_WEAPON_HAND]->type == CUTTING) + strcpy(Str1,"You cut "); + else if (Player.possessions[O_WEAPON_HAND]->type == STRIKING) + strcpy(Str1,"You strike "); + else strcpy(Str1,"You attack "); + strcat(Str1,actionlocstr(Player.meleestr[i+1])); + if (Verbosity == VERBOSE) mprint(Str1); + if (player_hit(0,Player.meleestr[i+1],m)) + weapon_use(2*statmod(Player.str), + Player.possessions[O_WEAPON_HAND], + m); + else player_miss(m,NORMAL_DAMAGE); + break; + case 'l': case 'L': + strcpy(Str1,"You lunge "); + strcat(Str1,actionlocstr(Player.meleestr[i+1])); + if (Verbosity == VERBOSE) mprint(Str1); + if (player_hit(Player.level+Player.dex,Player.meleestr[i+1],m)) + weapon_use(Player.level,Player.possessions[O_WEAPON_HAND],m); + else player_miss(m,NORMAL_DAMAGE); + break; + } + } + i+=2; + } +} + + + + +/* checks to see if player hits with hitmod vs. monster m at location hitloc */ +int player_hit(int hitmod, char hitloc, struct monster *m) +{ + int i=0,blocks=FALSE,goodblocks=0,hit; + if (m->hp < 1) { + mprint("Unfortunately, your opponent is already dead!"); + return(FALSE); + } + else { + if (hitloc == 'X') hitloc = random_loc(); + + transcribe_monster_actions(m); + + while (imeleestr)) { + if ((m->meleestr[i] == 'B') || (m->meleestr[i] == 'R')) { + blocks = TRUE; + if (hitloc == m->meleestr[i+1]) + goodblocks++; + } + i+=2; + } + + if (! blocks) goodblocks = -1; + hit = hitp(Player.hit+hitmod,m->ac+goodblocks*10); + if ((! hit) && (goodblocks > 0)) { + if (m->uniqueness == COMMON) { + strcpy(Str1,"The "); + strcat(Str1,m->monstring); + } + else strcpy(Str1,m->monstring); + strcat(Str1," blocks it!"); + if (Verbosity == VERBOSE) mprint(Str1); + } + return(hit); + } +} + + +/* This function is used to undo all items temporarily, should +always be used in pairs with on being TRUE and FALSE, and may cause +anomalous stats and item-usage if used indiscriminately */ + +void toggle_item_use(int on) +{ + static int used[MAXITEMS]; + int i; + setgamestatus(SUPPRESS_PRINTING); + if (on) + for(i=0;iused) == TRUE) { + Player.possessions[i]->used = FALSE; + item_use(Player.possessions[i]); + } + } + } + else { + for(i=1;iused = TRUE; + item_use(Player.possessions[i]); + } + calc_melee(); + showflags(); + dataprint(); + timeprint(); + } + resetgamestatus(SUPPRESS_PRINTING); +} + + +void enter_site(Symbol site) +{ + switch(site) { + case CITY: change_environment(E_CITY); break; + case VILLAGE: change_environment(E_VILLAGE); break; + case CAVES: change_environment(E_CAVES); break; + case CASTLE: change_environment(E_CASTLE); break; + case VOLCANO: change_environment(E_VOLCANO); break; + case TEMPLE: change_environment(E_TEMPLE); break; + case DRAGONLAIR: change_environment(E_DLAIR); break; + case STARPEAK: change_environment(E_STARPEAK); break; + case MAGIC_ISLE: change_environment(E_MAGIC_ISLE); break; + case PALACE: change_environment(E_PALACE); break; + default:print3("There's nothing to enter here!"); break; + } +} + + + +/* Switches context dungeon/countryside/city, etc */ +void change_environment(char new_environment) +{ + int i, emerging = FALSE; + + Player.sx = -1; + Player.sy = -1; /* reset sanctuary if there was one */ + + /* missing message if gets lost on site... */ + if (gamestatusp(LOST)) + { + resetgamestatus(LOST); /* in case the player gets lost _on_ a site */ + mprint("You know where you are now."); /* but didn't inform player... DAG */ + } + + resetgamestatus(FAST_MOVE); + + Last_Environment = Current_Environment; + if (Last_Environment == E_COUNTRYSIDE) + { + LastCountryLocX = Player.x; + LastCountryLocY = Player.y; + } + + if (((Last_Environment == E_CITY) || + (Last_Environment == E_VILLAGE)) && + ((new_environment == E_MANSION) || + (new_environment == E_HOUSE) || + (new_environment == E_HOVEL) || + (new_environment == E_SEWERS) || + (new_environment == E_ARENA))) + { + LastTownLocX = Player.x; + LastTownLocY = Player.y; + } + + else if (((Last_Environment == E_MANSION) || + (Last_Environment == E_HOUSE) || + (Last_Environment == E_HOVEL) || + (Last_Environment == E_SEWERS) || + (Last_Environment == E_ARENA)) && + ((new_environment == E_CITY) || + (new_environment == E_VILLAGE))) + { + setPlayerXY( LastTownLocX, LastTownLocY); + emerging = TRUE; + } + + Current_Environment = new_environment; + switch (new_environment) + { + case E_ARENA: + setPlayerXY(5, 7); + setgamestatus(ARENA_MODE); + load_arena(); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_ABYSS: + setPlayerXY(32, 15); + load_abyss(); + abyss_file(); + lose_all_items(); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_CIRCLE: + setPlayerXY(32, 14); + load_circle(TRUE); + if (Objects[OB_STARGEM].uniqueness == UNIQUE_TAKEN) + { + print1("A bemused voice says:"); + print2("'Why are you here? You already have the Star Gem!'"); + morewait(); + } + else if (Player.rank[CIRCLE] > 0) + { + print1("You hear the voice of the Prime Sorceror:"); + print2("'Congratulations on your attainment of the Circle's Demesne.'"); + morewait(); + print1("For the honor of the Circle, you may take the Star Gem"); + print2("and destroy it on the acme of Star Peak."); + morewait(); + print1("Beware the foul LawBringer who resides there..."); + print2("By the way, some of the members of the Circle seem to"); + morewait(); + print1("have become a bit jealous of your success --"); + print2("I'd watch out for them too if I were you."); + morewait(); + } + else if (Player.alignment > 0) + { + print1("A mysterious ghostly image materializes in front of you."); + print2("It speaks: 'Greetings, fellow abider in Law. I am called"); + morewait(); + print1("The LawBringer. If you wish to advance our cause, obtain"); + print2("the mystic Star Gem and return it to me on Star Peak."); + morewait(); + print1("Beware the power of the evil Circle of Sorcerors and the"); + print2("forces of Chaos which guard the gem.'"); + morewait(); + print1("The strange form fades slowly."); + morewait(); + } + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_COURT: + setPlayerXY(32, 2); + LastCountryLocX = 6; + LastCountryLocY = 1; + load_court(TRUE); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_MANSION: + load_house(E_MANSION, TRUE); + setPlayerXY(2, 8); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_HOUSE: + load_house(E_HOUSE, TRUE); + setPlayerXY(2, 13); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_HOVEL: + load_house(E_HOVEL, TRUE); + setPlayerXY(2, 9); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_DLAIR: + setPlayerXY(0, 8); + load_dlair(gamestatusp(KILLED_DRAGONLORD), TRUE); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_STARPEAK: + setPlayerXY(2, 9); + load_speak(gamestatusp(KILLED_LAWBRINGER), TRUE); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_MAGIC_ISLE: + setPlayerXY(62, 14); + load_misle(gamestatusp(KILLED_EATER), TRUE); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_TEMPLE: + load_temple(Country[Player.x][Player.y].aux, TRUE); + setPlayerXY(32, 15); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + + case E_CITY: + if (emerging) { + print1("You emerge onto the street."); + emerging = FALSE; + } + else { + print1("You pass through the massive gates of Rampart, the city."); + setPlayerXY(62, 20); + } + if (City == NULL) load_city(TRUE); +#ifdef SAVE_LEVELS + else + msdos_changelevel(Level,new_environment,0); +#endif + Level = City; + ScreenOffset = Player.y - (ScreenLength/2); + ScreenXOffset =Player.x - (ScreenWidth/2); + screencheck(Player.x, Player.y); + show_screen(); + break; + case E_VILLAGE: + if (!emerging) { + /* different villages per different locations */ + switch(Country[Player.x][Player.y].aux) { + case VIL_STARVIEW: + setPlayerXY( 0, 6 ); + Villagenum = VIL_STARVIEW; + break; + default: + print3("Very strange, a nonexistent village."); + case VIL_WOODMERE: + setPlayerXY( 39, 15 ); + Villagenum = VIL_WOODMERE; + break; + case VIL_STORMWAT: + setPlayerXY( 63, 8 ); + Villagenum = VIL_STORMWAT; + break; + case VIL_THAUMARI: + setPlayerXY( 32, 15 ); + Villagenum = VIL_THAUMARI; + break; + case VIL_SKORCH: + setPlayerXY( 2, 8 ); + Villagenum = VIL_SKORCH; + break; + case VIL_WHORFEN: + setPlayerXY( 2, 2 ); + Villagenum = VIL_WHORFEN; + break; + } + } + if ((! emerging) || (TempLevel == NULL)) load_village(Villagenum, TRUE); + else if (TempLevel->environment != E_VILLAGE) load_village(Villagenum, TRUE); +#ifndef SAVE_LEVELS + else Level = TempLevel; +#else + else { + msdos_changelevel(Level,new_environment,0); + Level = TempLevel; + } +#endif + if (emerging) { + print1("You emerge onto the street."); + emerging = FALSE; + } + else + print1("You enter a small rural village."); + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + case E_CAVES: + print1("You enter a dark cleft in a hillside;"); + print2("You note signs of recent passage in the dirt nearby."); + if (gamestatusp(MOUNTED)) { + morewait(); + print1("Seeing as you might not be coming back, you feel compelled"); + print2("to let your horse go, rather than keep him hobbled outside."); + resetgamestatus(MOUNTED); + calc_melee(); + } + MaxDungeonLevels = CAVELEVELS; + if (Current_Dungeon != E_CAVES) { +#ifdef SAVE_LEVELS + msdos_changelevel(Level,0,-1); +#endif + free_dungeon(); + Dungeon = NULL; + Level = NULL; + Current_Dungeon = E_CAVES; + } + change_level(0,1,FALSE); + break; + case E_VOLCANO: + print1("You pass down through the glowing crater."); + if (gamestatusp(MOUNTED)) { + morewait(); + print1("Seeing as you might not be coming back, you feel compelled"); + print2("to let your horse go, rather than keep him hobbled outside."); + resetgamestatus(MOUNTED); + calc_melee(); + } + MaxDungeonLevels = VOLCANOLEVELS; + if (Current_Dungeon != E_VOLCANO) { +#ifdef SAVE_LEVELS + msdos_changelevel(Level,0,-1); +#endif + free_dungeon(); + Dungeon = NULL; + Level = NULL; + Current_Dungeon = E_VOLCANO; + } + change_level(0,1,FALSE); + break; + case E_ASTRAL: + print1("You are in a weird flickery maze."); + if (gamestatusp(MOUNTED)) { + print2("Your horse doesn't seem to have made it...."); + resetgamestatus(MOUNTED); + calc_melee(); + } + MaxDungeonLevels = ASTRALLEVELS; + if (Current_Dungeon != E_ASTRAL) { +#ifdef SAVE_LEVELS + msdos_changelevel(Level,0,-1); +#endif + free_dungeon(); + Dungeon = NULL; + Level = NULL; + Current_Dungeon = E_ASTRAL; + } + change_level(0,1,FALSE); + break; + case E_CASTLE: + print1("You cross the drawbridge. Strange forms move beneath the water."); + if (gamestatusp(MOUNTED)) { + morewait(); + print1("Seeing as you might not be coming back, you feel compelled"); + print2("to let your horse go, rather than keep him hobbled outside."); + resetgamestatus(MOUNTED); + } + MaxDungeonLevels = CASTLELEVELS; + if (Current_Dungeon != E_CASTLE) { +#ifdef SAVE_LEVELS + msdos_changelevel(Level,0,-1); +#endif + free_dungeon(); + Dungeon = NULL; + Level = NULL; + Current_Dungeon = E_CASTLE; + } + change_level(0,1,FALSE); + break; + case E_SEWERS: + print1("You pry open a manhole and descend into the sewers below."); + if (gamestatusp(MOUNTED)) { + print2("You horse waits patiently outside the sewer entrance...."); + dismount_steed(); + } + MaxDungeonLevels = SEWERLEVELS; + if (Current_Dungeon != E_SEWERS) { +#ifdef SAVE_LEVELS + msdos_changelevel(Level,0,-1); +#endif + free_dungeon(); + Dungeon = NULL; + Level = NULL; + Current_Dungeon = E_SEWERS; + } + change_level(0,1,FALSE); + break; + case E_COUNTRYSIDE: + print1("You return to the fresh air of the open countryside."); + if (Last_Environment == E_CITY) { + setPlayerXY(27,19); + } + else { + setPlayerXY(LastCountryLocX,LastCountryLocY); + } + for(i=0;i<9;i++) + c_set(Player.x+Dirs[0][i], Player.y+Dirs[1][i], SEEN); + ScreenOffset = Player.y - (ScreenLength/2); + /* ScreenXOffset = Player.x - (ScreenWidth/2); PGM*/ + show_screen(); + break; + case E_TACTICAL_MAP: + print1("You are now on the tactical screen; exit off any side to leave"); + make_country_screen(Country[Player.x][Player.y].current_terrain_type); + make_country_monsters(Country[Player.x][Player.y].current_terrain_type); + setPlayerXY( Level->level_width/2, Level->level_length/2 ); + + /* This should be altered to use setPlayerXY(x,y) PGM */ + + while (Level->site[Player.x][Player.y].locchar == WATER) { + if (Player.y < Level->level_length/2 + 5) + Player.y++; + else if (Player.x > Level->level_width/2 - 10) { + Player.x--; + Player.y = Level->level_length/2 - 5; + } + else { + Level->site[Player.x][Player.y].locchar = + Level->site[Player.x][Player.y].showchar = FLOOR; + Level->site[Player.x][Player.y].p_locf = L_NO_OP; + } + } + ScreenOffset = 0; + ScreenXOffset = 0; + show_screen(); + break; + case E_PALACE: + print1("You enter the dungeons of the ruined palace."); + if (gamestatusp(MOUNTED)) { + morewait(); + print1("Seeing as you might not be coming back, you feel compelled"); + print2("to let your horse go, rather than keep him hobbled outside."); + resetgamestatus(MOUNTED); + } + MaxDungeonLevels = PALACELEVELS; + if (Current_Dungeon != E_PALACE) { +#ifdef SAVE_LEVELS + msdos_changelevel(Level,0,-1); +#endif + free_dungeon(); + Dungeon = NULL; + Level = NULL; + Current_Dungeon = E_PALACE; + } + change_level(0,1,FALSE); + break; + case E_NEVER_NEVER_LAND: default: + print1("There must be some mistake. You don't look like Peter Pan."); + print2("(But here you are in Never-Never Land)"); + ScreenOffset = Player.y - (ScreenLength/2); + ScreenXOffset = Player.x - (ScreenWidth/2); + show_screen(); + break; + } + setlastxy(Player.x, Player.y); + if (Current_Environment != E_COUNTRYSIDE) + showroom(Level->site[Player.x][Player.y].roomnumber); + else + terrain_check(FALSE); +} diff --git a/aux3.c b/aux3.c new file mode 100644 index 0000000..e8e8498 --- /dev/null +++ b/aux3.c @@ -0,0 +1,1285 @@ +/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */ +/* aux3.c */ +/* some functions called by com.c, also see aux1.c, aux2.c */ +/* This is a real grab bag file. It contains functions used by + aux1.c and omega.c, as well as elsewhere. It is mainly here so aux1.c + and aux2.c are not huge */ + +#include "glob.h" + +/* check every ten minutes */ +void tenminute_check(void) +{ + if (Time % 60 == 0) hourly_check(); + else { + if (Current_Environment == Current_Dungeon) wandercheck(); + minute_status_check(); + tenminute_status_check(); + if ((Player.status[DISEASED] < 1) && (Player.hp < Player.maxhp)) + Player.hp = min(Player.maxhp,Player.hp+Player.level+1); + if (Current_Environment != E_COUNTRYSIDE && Current_Environment != E_ABYSS) + indoors_random_event(); + } +} + + + +/* hourly check is same as ten_minutely check except food is also + checked, and since time moves in hours out of doors, also + outdoors_random_event is possible */ + +void hourly_check(void) +{ + Player.food--; + foodcheck(); + if (hour()==0) { /* midnight, a new day */ + moon_check(); + Date++; + } + torch_check(); + if (Current_Environment == Current_Dungeon) wandercheck(); + minute_status_check(); + tenminute_status_check(); + if ((Player.status[DISEASED] == 0) && (Player.hp < Player.maxhp)) + Player.hp = min(Player.maxhp,Player.hp+Player.level+1); + if (Current_Environment != E_COUNTRYSIDE && Current_Environment != E_ABYSS) + indoors_random_event(); +} + + + + +void indoors_random_event(void) +{ + pml ml; + pol ol; + + switch(random_range(1000)) { + case 0: + print3("You feel an unexplainable elation."); + morewait(); + break; + case 1: + print3("You hear a distant rumbling."); + morewait(); + break; + case 2: + print3("You realize your fly is open."); + morewait(); + break; + case 3: + print3("You have a sudden craving for a pecan twirl."); + morewait(); + break; + case 4: + print3("A mysterious healing flux settles over the level."); + morewait(); + for (ml=Level->mlist;ml!=NULL;ml=ml->next) + if (ml->m->hp > 0) ml->m->hp = Monsters[ml->m->id].hp; + Player.hp = max(Player.hp,Player.maxhp); + break; + case 5: + print3("You discover an itch just where you can't scratch it."); + morewait(); + break; + case 6: + print3("A cosmic ray strikes!"); + p_damage(10,UNSTOPPABLE,"a cosmic ray"); + morewait(); + break; + case 7: + print3("You catch your second wind...."); + Player.maxhp++; + Player.hp = max(Player.hp, Player.maxhp); + Player.mana = max(Player.mana, calcmana()); + morewait(); + break; + case 8: + print3("You find some spare change in a hidden pocket."); + morewait(); + Player.cash += Player.level*Player.level+1; + break; + case 9: + print3("You feel strangely lucky."); + morewait(); + break; + case 10: + print3("You trip over something hidden in a shadow..."); + morewait(); + ol = ((pol) checkmalloc(sizeof(oltype))); + ol->thing = create_object(difficulty()); /* FIXED! 12/30/98 */ + assert(ol->thing); /* WDT I want to make sure... */ + ol->next = Level->site[Player.x][Player.y].things; + Level->site[Player.x][Player.y].things = ol; + pickup(); + break; + case 11: + print3("A mysterious voice echoes all around you...."); + morewait(); + hint(); + morewait(); + break; + +#if 0 +#ifdef NEW_BANK + case 12: + { + int num_accounts; + bank_account *account; + + num_accounts = 0; + for(account = bank; account; account = account->next_account) + { + if (account->player && account->balance > 0) + { + ++num_accounts; + account->balance = 0; + } + } + + if (num_accounts) + print3( "You feel unlucky." ); + else + print3( "You feel lucky." ); + } + break; + + case 13: + { + int num_accounts; + bank_account *account; + + num_accounts = 0; + for(account = bank; account; account = account->next_account) + if (account->player && account->balance > 0) ++num_accounts; + + if (num_accounts) + { + num_accounts = random_range(num_accounts); + for(account = bank; account; account = account->next_account) + { + if (account->player) + { + if (0 == num_accounts) + { + account->balance += random_range( 4000 ) + 1000; + break; + } + + --num_accounts; + } + } + + print3( "You feel lucky." ); + } + else + { + print3( "You feel unlucky." ); + } + } + break; +#else /* !NEW_BANK */ + case 12: + if (Balance > 0) + { + print3("You get word of the failure of your bank!"); + Balance = 0; + } + else + { + print3("You feel lucky."); + } + break; + + case 13: + if (Balance > 0) + { + print3("You get word of a bank error in your favor!"); + Balance += 5000; + } + else + { + print3("You feel unlucky."); + } + break; +#endif /* !NEW_BANK */ +#endif /* 0 */ + } + dataprint(); + showflags(); +} + + + +void outdoors_random_event(void) +{ + int num,i,j; + pob ob; + + switch(random_range(300)) { + case 0: + switch(Country[Player.x][Player.y].current_terrain_type) { + case TUNDRA: + mprint("It begins to snow. Heavily."); + break; + case DESERT: + mprint("A sandstorm swirls around you."); + break; + default: + if ((Date > 75) && (Date < 330)) + mprint("You are drenched by a sudden downpour!"); + else mprint("It begins to snow. Heavily."); + } + morewait(); + mprint("Due to the inclement weather conditions, you have become lost."); + morewait(); + Precipitation+=random_range(12)+1; + setgamestatus(LOST); + break; + case 1: + mprint("You enter a field of brightly colored flowers..."); + mprint("Wow, man! These are some pretty poppies..."); + morewait(); + mprint("poppies..."); + morewait(); + mprint("poppies..."); + morewait(); + print3("You become somewhat disoriented..."); + setgamestatus(LOST); + break; + case 2: + mprint("You discover a sprig of athelas growing lonely in the wild."); + morewait(); + mprint("Using your herbalist lore you cook a cake of lembas...."); + morewait(); + ob = ((pob) checkmalloc(sizeof(objtype))); + *ob = Objects[OB_LEMBAS]; + gain_item(ob); + break; + case 3: + if (Precipitation > 0) { + mprint("You are struck by a bolt of lightning!"); + p_damage(random_range(25),ELECTRICITY,"a lightning strike"); + morewait(); + } + else mprint("You feel static cling"); + break; + case 4: + mprint("You find a fast-food establishment."); + morewait(); + l_commandant(); + break; + case 5: + mprint("A weird howling tornado hits from out of the West!"); + morewait(); + mprint("You've been caught in a chaos storm!"); + morewait(); + num = random_range(300); + if (num <10) { + mprint("Your cell-structure was disrupted!"); + p_damage(random_range(100),UNSTOPPABLE,"a chaos storm"); + morewait(); + } + else if (num < 20) { + mprint("The chaos storm warps your frame!"); + morewait(); + mprint("Your statistical entropy has been maximized."); + morewait(); + mprint("You feel average..."); + morewait(); + toggle_item_use(TRUE); /* FIXED! 12/30/98 */ + Player.str = Player.maxstr = Player.con = Player.maxcon = + Player.dex = Player.maxdex = Player.agi = Player.maxagi = + Player.iq = Player.maxiq = Player.pow = Player.maxpow = + ((Player.maxstr+Player.maxcon+Player.maxdex+Player.maxagi+ + Player.maxiq+Player.maxpow+12)/6); + toggle_item_use(FALSE); /* FIXED! 12/30/98 */ + } + else if (num < 30) { + mprint("Your entire body glows with an eerie flickering light."); + morewait(); + toggle_item_use(TRUE); /* FIXED! 12/30/98 */ + for(i=1;iplus++; + if (Player.possessions[i]->objchar == STICK) + Player.possessions[i]->charge+=10; + Player.possessions[i]->blessing+=10; + } + toggle_item_use(FALSE); /* FIXED! 12/30/98 */ + cleanse(1); + mprint("You feel filled with energy!"); + morewait(); + Player.maxpow += 5; + Player.pow += 5; + Player.mana = Player.maxmana = calcmana() * 5; + mprint("You also feel weaker. Paradoxical, no?"); + morewait(); + Player.con -= 5; + Player.maxcon -= 5; + if (Player.con < 3) + p_death("congestive heart failure"); + } + else if (num < 40) { + mprint("Your entire body glows black."); + morewait(); + dispel(-1); + dispel(-1); + Player.pow-=10; + Player.mana=0; + } + else if (num < 60) { + mprint("The storm deposits you in a strange place...."); + morewait(); + setPlayerXY( random_range(COUNTRY_WIDTH), random_range(COUNTRY_LENGTH)); + screencheck(Player.x,Player.y); + } + else if (num < 70) { + mprint("A tendril of the storm condenses and falls into your hands."); + morewait(); + ob = ((pob) checkmalloc(sizeof(objtype))); + make_artifact(ob,-1); + gain_item(ob); + } + else if (num < 80) { + if (gamestatusp(MOUNTED)) { + mprint("Your horse screams as he is transformed into an"); + morewait(); + mprint("imaginary unseen dead tortoise."); + morewait(); + mprint("You are now on foot."); + morewait(); + resetgamestatus(MOUNTED); + } + else { + mprint("You notice you are riding a horse. Odd. Very odd...."); + morewait(); + mprint("Now that's a horse of a different color!"); + morewait(); + setgamestatus(MOUNTED); + } + } + else if (num < 90) { + mprint("You feel imbued with godlike power...."); + morewait(); + wish(1); + } + else if (num < 100) { + mprint("The chaos storm has wiped your memory!"); + morewait(); + mprint("You feel extraordinarily naive...."); + morewait(); + mprint("You can't remember a thing! Not even your name."); + morewait(); + Player.xp = 0; + Player.level = 0; + for (i=0;i 0) && + (Player.level/2 + random_range(20) > + hostile_magic + random_range(20))) { + if (Player.mana > hostile_magic * hostile_magic) { + mprint("Thinking fast, you defend youself with a counterspell!"); + Player.mana -= hostile_magic * hostile_magic; + dataprint(); + return(TRUE); + } + } + if (Player.level/4 + Player.status[PROTECTION] + random_range(20) > + hostile_magic + random_range(30)) { + mprint("You resist the spell!"); + return(TRUE); + } + else return(FALSE); +} + + +void terrain_check(int takestime) +{ + int faster = 0; + + if (Player.patron == DRUID) { + faster = 1; + switch(random_range(32)) { + case 0:print2("Along the many paths of nature..."); break; + case 1:print2("You move swiftly through the wilderness."); break; + } + } + else if (gamestatusp(MOUNTED)) { + faster = 1; + switch(random_range(32)) { + case 0: + case 1:print2("Clippity Clop.");break; + case 2:print2("....my spurs go jingle jangle jingle....");break; + case 3:print2("....as I go riding merrily along....");break; + } + } + else if (Player.possessions[O_BOOTS] && + Player.possessions[O_BOOTS]->usef == I_BOOTS_7LEAGUE) { + takestime = 0; + switch(random_range(32)) { + case 0:print2("Boingg!"); break; + case 1:print2("Whooosh!"); break; + case 2:print2("Over hill, over dale...."); break; + case 3:print2("...able to leap over 7 leagues in a single bound...."); + break; + } + } + else if (Player.status[SHADOWFORM]) { + faster = 1; + switch(random_range(32)) { + case 0:print2("As swift as a shadow."); break; + case 1:print2("\"I walk through the trees...\""); break; + } + } + else switch(random_range(32)) { + case 0:print2("Trudge. Trudge."); break; + case 1:print2("The road goes ever onward...."); break; + } + switch(Country[Player.x][Player.y].current_terrain_type) { + case RIVER: + if ((Player.y < 6) && (Player.x > 20)) locprint("Star Lake."); + else if (Player.y < 41) { + if (Player.x < 10) locprint("Aerie River."); + else locprint("The Great Flood."); + } + else if (Player.x < 42) locprint("The Swamp Runs."); + else locprint("River Greenshriek."); + if (takestime) { + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + } + break; + case ROAD: + locprint("A well-maintained road."); + if (takestime) { + Time += 60; + hourly_check(); + } + break; + case PLAINS: + locprint("A rippling sea of grass."); + if (takestime) { + Time += 60; + hourly_check(); + if (! faster) { + Time += 60; + hourly_check(); + } + } + break; + case TUNDRA: + locprint("The Great Northern Wastes."); + if (takestime) { + Time += 60; + hourly_check(); + if (! faster) { + Time += 60; + hourly_check(); + } + } + break; + case FOREST: + if (Player.y < 10) locprint("The Deepwood."); + else if (Player.y < 18) locprint("The Forest of Erelon."); + else if (Player.y < 46) locprint("The Great Forest."); + if (takestime) { + Time += 60; + hourly_check(); + if (Player.rank[PRIESTHOOD] == 0 || Player.patron != DRUID) { + Time += 60; + hourly_check(); + if (! faster) { + Time += 60; + hourly_check(); + } + } + } + break; + case JUNGLE: + locprint("Greenshriek Jungle."); + if (takestime) { + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + if (! faster) { + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + } + } + break; + case DESERT: + locprint("The Waste of Time."); + if (takestime) { + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + if (! faster) { + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + } + } + break; + case MOUNTAINS: + if ((Player.y < 9) && (Player.x < 12)) + locprint("The Magic Mountains"); + else if ((Player.y < 9) && (Player.y > 2) && (Player.x < 40)) + locprint("The Peaks of the Fist."); + else if (Player.x < 52) + locprint("The Rift Mountains."); + else locprint("Borderland Mountains."); + if (takestime) { + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + if (! faster) { + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + } + } + break; + case PASS: + locprint("A hidden pass."); + if (takestime) { + Time += 60; + hourly_check(); + } + break; + case CHAOS_SEA: + locprint("The Sea of Chaos."); + if (takestime) { + Time += 60; + hourly_check(); + } + mprint("You have entered the sea of chaos..."); + morewait(); + l_chaos(); + break; + case SWAMP: + locprint("The Loathly Swamp."); + if (takestime) { + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + if (! faster) { + Time += 60; + hourly_check(); + Time += 60; + hourly_check(); + } + } + break; + case CITY: + if (gamestatusp(LOST)) { + resetgamestatus(LOST); + mprint("Well, I guess you know where you are now...."); + } + locprint("Outside Rampart, the city."); + break; + case VILLAGE: + if (gamestatusp(LOST)) { + resetgamestatus(LOST); + mprint("The village guards let you know where you are...."); + } + locprint("Outside a small village."); + break; + case CAVES: + locprint("A deserted hillside."); + if (takestime) { + Time += 60; + hourly_check(); + } + mprint("You notice a concealed entrance into the hill."); + break; + case CASTLE: + locprint("Near a fortified castle."); + if (takestime) { + Time += 60; + hourly_check(); + } + mprint("The castle is hewn from solid granite. The drawbridge is down."); + break; + case TEMPLE: + switch(Country[Player.x][Player.y].aux) { + case ODIN: locprint("A rough-hewn granite temple."); break; + case SET: locprint("A black pyramidal temple made of sandstone."); break; + case ATHENA: locprint("A classical marble-columned temple."); break; + case HECATE: locprint("A temple of ebony adorned with ivory."); break; + case DRUID: locprint("A temple formed of living trees."); break; + case DESTINY: locprint("A temple of some mysterious blue crystal."); break; + } + if (takestime) { + Time += 60; + hourly_check(); + } + mprint("You notice an entrance conveniently at hand."); + break; + case MAGIC_ISLE: + locprint("A strange island in the midst of the Sea of Chaos."); + if (takestime) { + Time += 60; + hourly_check(); + } + mprint("There is a narrow causeway to the island from here."); + break; + case STARPEAK: + locprint("Star Peak."); + if (takestime) { + Time += 60; + hourly_check(); + } + mprint("The top of the mountain seems to glow with a allochroous aura."); + break; + case DRAGONLAIR: + locprint("A rocky chasm."); + if (takestime) { + Time += 60; + hourly_check(); + } + mprint("You are at a cave entrance from which you see the glint of gold."); + break; + case PALACE: + locprint("The ruins of a once expansive palace."); + if (takestime) { + Time += 60; + hourly_check(); + } + mprint("The palace dungeons are still intact..."); + break; + case VOLCANO: + locprint("HellWell Volcano."); + if (takestime) { + Time += 60; + hourly_check(); + } + mprint("A shimmer of heat lightning plays about the crater rim."); + break; + default: + locprint("I haven't any idea where you are!!!"); + break; + } + outdoors_random_event(); +} + + + +void countrysearch(void) +{ + int x,y; + Time+=60; + hourly_check(); + for (x=Player.x-1;x