diff --git a/.gitattributes b/.gitattributes index 894a91c8e..9af92ddc6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,5 @@ -*.[ch] filter=NHtext merge=NHsubst -*.sh filter=NHtext merge=NHsubst +*.[ch] NHSUBST +*.sh NHSUBST * text=auto *.hqx -text *.sln -text diff --git a/.gitignore b/.gitignore index 302497de0..aedf39f50 100644 --- a/.gitignore +++ b/.gitignore @@ -32,8 +32,11 @@ core Makefile # Win32-specific ignores +Debug/ +Release/ binary/ build/ +ipch/ Nethack.sln Nethack.sdf Nethack.opensdf diff --git a/DEVEL/.gitattributes b/DEVEL/.gitattributes index 3e157372b..cc0b542f3 100644 --- a/DEVEL/.gitattributes +++ b/DEVEL/.gitattributes @@ -1,4 +1,4 @@ -Developer.txt filter=NHtext merge=NHsubst -nhgitset.pl filter=NHtext merge=NHsubst -hookdir/* filter=NHtext merge=NHsubst +Developer.txt NHSUBST +nhgitset.pl NHSUBST +hooksdir/* NHSUBST * text=auto diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index 5e9e76356..49cebe12f 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -136,9 +136,9 @@ B. Enabling variable expansion Variable expansion is controlled by the .gitattributes file. To enable variable expansion: - pattern filter=NHtext merge=NHsubst + pattern NHSUBST To disable variable expansion: - pattern -filter + pattern -NHSUBST More information: "git help gitattributes" @@ -147,8 +147,8 @@ C. Oddities instead of "git add" or "git commit." Nothing terrible will happen if you use the wrong one, but the values will not be updated. - Due to the way this abuses git filters, the updated values are not visible - in your working tree. + Variable expansion modifies the files in the work tree - your editor or + IDE may or may not be happy with this. D. Using your own hooks You can use your own hooks - put them in .git/hooks as usual BUT name them diff --git a/DEVEL/code_features.txt b/DEVEL/code_features.txt index 08c42c9d7..414a51dbf 100644 --- a/DEVEL/code_features.txt +++ b/DEVEL/code_features.txt @@ -4,6 +4,34 @@ code_features.txt Developer-useful info about code features, assumptions, purpose, rationale, etc. +============================================== +FEATURE_NOTICE Alerts for a Release + +There is a code mechanism for alterting players to a change in behavior +over prior versions of the game. + +Here's how to do it: + o Where the change in behavior needs to alert the player, + - Add an 'if statement' to invoke the alert behavior + if the condition is met, for example + if (flags.suppress_alert < FEATURE_NOTICE_VER(3.6.0)) + pline("Note: and explain the change here."); + - The example above will alert the users for a new feature + added in 3.6.0 via a one-liner via pline(), but you + could get more elaborate (just make sure it is all done + in the 'if' code block.. + +Once the user finds the alert no longer useful, or becoming +annoying, they can set the "suppress_alert" option. + - The user can only set the suppress_alert to the current + version, not future versions. That restriction is done + so that the feature can be used for new things in new + releases. + - The suppression can be done interactively mid game with + the 'O' command, or via + OPTIONS=suppress_alert:3.6.0 + in the user's config file. + ============================================== PREFIXES_IN_USE and NOCWD_ASSUMPTIONS diff --git a/DEVEL/git_recipes.txt b/DEVEL/git_recipes.txt index 88af7f927..1a2ec0acf 100644 --- a/DEVEL/git_recipes.txt +++ b/DEVEL/git_recipes.txt @@ -32,15 +32,22 @@ you specify: -pretty=one: format output as a single line for each entry (branch): show the commits from (branch) instead of the current one +[*] git log --pretty=one --decorate --graph --all + +(This is best explained by executing and looking at the output.) + [*] git add (filename) [*] git nhadd (filename) Adds the changes you've made in (filename) to the pre-commit staging area. (also referred to as the 'index') + OR +Make a new file be tracked by git. "nhadd" is the preferred syntax and will automatically update the source file -headers with the latest date, branch, and version. +headers with the latest date, branch, and version. See Developer.txt for +details. [*] git commit [-a] [-m "text"] @@ -53,7 +60,8 @@ Including -m will use "text" as the commit message instead of opening an editor window for you to create one. "nhcommit" is the preferred syntax and will automatically update the source file -headers with the latest date, branch, and version. +headers with the latest date, branch, and version. See Developer.txt for +details. [*] git push [--all] [-u origin (branch)] @@ -101,10 +109,10 @@ the prior commit. [/end area-of-concern] -[*] git fetch [-a] +[*] git fetch [--all] Retrieve commits from the remote repository to your machine. -Including -a will get commits for all branches. +Including --all will get commits for all branches. Does NOT merge them into your local repository. diff --git a/DEVEL/hooksdir/NHadd b/DEVEL/hooksdir/NHadd old mode 100755 new mode 100644 index 55a86ee08..55138e738 --- a/DEVEL/hooksdir/NHadd +++ b/DEVEL/hooksdir/NHadd @@ -1,14 +1,19 @@ #!/usr/bin/perl # wrapper for nhadd and nhcommit aliases -# $NHDT-Date$ +# $NHDT-Date: 1427408239 2015/03/26 22:17:19 $ %ok = map { $_ => 1 } ('add', 'commit'); die "Bad subcommand '$ARGV[0]'" unless $ok{$ARGV[0]}; +# we won't fail on a failure, so just system() +$rv = system('.git/hooks/nhsub',"--$ARGV[0]",@ARGV[1..$#ARGV]); +if($rv){ + print "warning: nhsub failed: $rv $!\n"; +} + if(length $ENV{GIT_PREFIX}){ chdir($ENV{GIT_PREFIX}) or die "Can't chdir $ENV{GIT_PREFIX}: $!"; } -$ENV{NHMODE} = 1; exec "git", @ARGV or die "Can't exec git: $!"; diff --git a/DEVEL/hooksdir/NHsubst b/DEVEL/hooksdir/NHsubst index 2c0c3c774..1039c21e6 100755 --- a/DEVEL/hooksdir/NHsubst +++ b/DEVEL/hooksdir/NHsubst @@ -13,7 +13,8 @@ my $rawin = 0; # feed diff to stdin for testing (do NOT set $debug=1) # this first block because it's expensive and dumpfile() hangs with $rawin. my $sink = ($^O eq "MSWin32") ? "NUL" : "/dev/null"; my $dbgfile = ($^O eq "MSWin32") ? "$ENV{TEMP}.$$" : "/tmp/trace.$$"; -open TRACE, ">>", ($debug==0)? $sink : $dbgfile; +open TRACE, ">>", $rawin?"/dev/tty":(($debug==0)? $sink : $dbgfile); +print TRACE "TEST TRACE\n"; if($debug){ print TRACE "START CLIENT ARGV:\n"; print TRACE "[0] $0\n"; @@ -233,7 +234,7 @@ sub merge_one_line_maybe { $theirval = $1; } } - +print TRACE "MID: $ourstype/$oursval $theirtype/$theirval\n"; # are we done? if(pos($ours)==length $ours && pos($theirs) == length $theirs){ $more = 0; @@ -245,6 +246,12 @@ sub merge_one_line_maybe { # now see if ours and their match or can be resolved # text if($ourstype == 3 && $theirtype == 3){ +#mismatch is \s vs \s\s - where is this coming from? + # HACK - hopefully temporary + if($oursval =~ m/^\s+$/ && $theirval =~ m/^\s+$/){ + $out .= $oursval; + next; + } if($oursval eq $theirval){ $out .= $oursval; next; @@ -273,6 +280,7 @@ sub merge_one_line_maybe { # return undef if we can't merge the values; $NAME: VALUE $ or $NAME$ (as appropriate) if we can. sub merge_one_var_maybe { my($varname, $oursval, $theirval) = @_; +print TRACE "MVM: -$varname-$oursval-$theirval-\n"; my $resolvedas; { no strict; @@ -309,12 +317,28 @@ sub Date { sub Branch { my($PREFIX, $varname, $mine, $theirs) = @_; - return "\$$PREFIX-$varname: $mine \$"; + $mine =~ s/^\s+//; $mine =~ s/\s+$//; + $theirs =~ s/^\s+//; $theirs =~ s/\s+$//; + return "\$$PREFIX-$varname: $mine \$" if(length $mine); + return "\$$PREFIX-$varname: $theirs \$" if(length $theirs); + return "\$$PREFIX-$varname\$" if(length $theirs); } sub Revision { my($PREFIX, $varname, $mine, $theirs) = @_; - return "\$$PREFIX-$varname: $mine \$"; + my($m) = ($mine =~ m/1.(\d+)/); + my($t) = ($theirs =~ m/1.(\d+)/); + if($m > 0 && $t > 0){ + my $q = ($m > $t) ? $m : $t; + return "\$$PREFIX-$varname: 1.$q \$"; + } + if($m > 0){ + return "\$$PREFIX-$varname: 1.$m \$"; + } + if($t > 0){ + return "\$$PREFIX-$varname: 1.$t \$"; + } + return "\$$PREFIX-$varname\$"; } __END__ @@ -364,3 +388,10 @@ $TEST-Branch: mine $ === $TEST-Branch: theirs $ >>> d3 + +TEST 8: +<<< d1 +/* NetHack 3.5 objnam.c $TEST-Date$ $TEST-Branch$:$TEST-Revision$ */ +=== +/* NetHack 3.5 objnam.c $TEST-Date: 1426977394 2015/03/21 22:36:34 $ $TEST-Branch: master $:$TEST-Revision: 1.108 $ */ +>>> d3 diff --git a/DEVEL/hooksdir/nhsub b/DEVEL/hooksdir/nhsub new file mode 100644 index 000000000..5238f422a --- /dev/null +++ b/DEVEL/hooksdir/nhsub @@ -0,0 +1,386 @@ +#!/usr/bin/perl +# nhsub +# $NHDT-Date: 1427913635 2015/04/01 18:40:35 $ + +# Note: was originally called nhdate; the rename is not reflected in the code. + +use strict; +my %opt; #cmd v n f F (other single char, but we don't care) +my $mode; # a c d f (add, commit, date, date -f) + +if(length $ENV{GIT_PREFIX}){ + chdir($ENV{GIT_PREFIX}) or die "Can't chdir $ENV{GIT_PREFIX}: $!"; +} + +#SO how do we know if a file has changed? +#(git status: git status --porcelain --ignored -- FILES. +#maybe + -z but it's a question of rename operations - probably doesn't +# matter, but need to experiment. + +# key: [dacf] first character of opt{cmd} (f if nhsub -f or add -f) +# first 2 chars of "git status --porcelain --ignored" +# (see "git help status" for table) +# No default. Undef means something unexpected happened. +my %codes = ( + 'f M'=>1, 'f D'=>1, # [MD] not updated + 'a M'=>0, 'a D'=>0, + 'd M'=>0, 'd D'=>0, + 'c M'=>0, 'c D'=>0, + +# M [ MD] updated in index + + 'dA '=>1, 'dAM'=>1, 'dAD'=>1, + 'aA '=>1, 'aAM'=>1, 'aAD'=>1, + 'cA '=>1, 'cAM'=>1, 'cAD'=>1, + 'fA '=>1, 'fAM'=>1, 'fAD'=>1, + # A [ MD] added to index + + 'dD '=>0, 'dDM'=>0, + 'aD '=>1, 'aDM'=>1, + 'cD '=>0, 'cDM'=>0, + 'fD '=>1, 'fDM'=>1, + # D [ M] deleted from index + +# R [ MD] renamed in index + +# C [ MD] copied in index + + 'aM '=>1, 'aA '=>1, 'aR '=>1, 'aC '=>1, + 'fM '=>1, 'fA '=>1, 'fR '=>1, 'fC '=>1, + # [MARC] index and work tree matches + + 'd M'=>1, 'dMM'=>1, 'dAM'=>1, 'dRM'=>1, 'dCM'=>1, + 'a M'=>1, 'aMM'=>1, 'aAM'=>1, 'aRM'=>1, 'aCM'=>1, + 'c M'=>1, 'cMM'=>1, 'cAM'=>1, 'cRM'=>1, 'cCM'=>1, + 'f M'=>1, 'fMM'=>1, 'fAM'=>1, 'fRM'=>1, 'fCM'=>1, + # [ MARC] M work tree changed since index + + 'd D'=>0, 'dMD'=>0, 'dAD'=>0, 'dRD'=>0, 'dCD'=>0, + 'a D'=>0, 'aMD'=>0, 'aAD'=>0, 'aRD'=>0, 'aCD'=>0, + 'c D'=>0, 'cMD'=>0, 'cAD'=>0, 'cRD'=>0, 'cCD'=>0, + 'f D'=>0, 'fMD'=>0, 'fAD'=>0, 'fRD'=>0, 'fCD'=>0, + # [ MARC] D deleted in work tree + + # ------------------------------------------------- + # DD unmerged, both deleted + # AU unmerged, added by us + # UD unmerged, deleted by them + # UA unmerged, added by them + # DU unmerged, deleted by us + # AA unmerged, both added + # UU unmerged, both modified + # ------------------------------------------------- + 'a??'=>1, 'f??'=>1, # ?? untracked + 'd??'=>0, 'c??'=>0, + + 'f!!'=>1, # !! ignored + 'a!!'=>0, 'd!!'=>0, 'c!!'=>0, + + 'f@@'=>1, # @@ internal ignored + 'a@@'=>0, 'd@@'=>0, 'c@@'=>0 +); + +# OS hackery +my $PDS = '/'; +if ($^O eq "MSWin32") +{ + $PDS = '\\'; +} + +# pick up the prefix for substitutions in this repo +my $PREFIX = &git_config('nethack','substprefix'); +print "PREFIX: '$PREFIX'\n" if($opt{v}); + +my @rawlist = &cmdparse(@ARGV); +push(@rawlist,'.') if($#rawlist == -1); + +while(@rawlist){ + my $raw = shift @rawlist; + if(-f $raw){ + &schedule_work($raw); + next; + } + if(-d $raw){ + if($raw =~ m!$PDS.git$!o){ + print "SKIP $raw\n" if($opt{v}>=2); + next; + } + opendir RDIR,$raw or die "Can't opendir: $raw"; + local($_); # needed until perl 5.11.2 + while($_ = readdir RDIR){ + next if(m/^\.\.?$/); + if(m/^\./ && $opt{f}){ + print " IGNORE-f: $raw$PDS$_\n" if($opt{v}>=2); + next; + } + push(@rawlist, $raw.$PDS.$_); + } + closedir RDIR; + } + # ignore other file types + if(! -e $raw){ + print "warning: missing file $raw\n"; + } +} + +# XXX could batch things up - later + +sub schedule_work { + my($file) = @_; + print "CHECK: '$file'\n" if($opt{v}>=2); + local($_) = `git status --porcelain --ignored -- $file`; + my $key = $mode . join('',(m/^(.)(.)/)); + if(length $key == 1){ + # Hack. An unmodified, tracked file produces no output from + # git status. Treat as another version of 'ignored'. + $key .= '@@'; + } + $key =~ s/-/ /g; # for Keni's locally mod'ed git + if(!exists $codes{$key}){ + die "I'm lost.\nK='$key' F=$file\nST=$_"; + } + if($codes{$key}==0){ + if($opt{v}>=2){ + print " IGNORE: $_" if(length); + print " IGNORE: !! $file\n" if(!length); + } + return; + } + if($opt{F}){ + my $ign = `git check-ignore $file`; + if($ign !~ m/^\s*$/){ + print " IGNORE-F: $ign" if($opt{v}>=2); + return; + } + } +# FALLTHROUGH and continue +#print "ACCEPT TEST\n"; # XXXXXXXXXX TEST +#return; + + my $attr = `git check-attr NHSUBST -- $file`; + if($attr =~ m/NHSUBST:\s+(.*)/){ +# XXX this is a bug in git. What if the value of an attribute is the +# string "unset"? Sigh. + if(! $opt{F}){ + if($1 eq "unset" || $1 eq "unspecified"){ + print " NOATTR: $attr" if($opt{v}>=2); + return; + } + } + &process_file($file); + return; + } + die "Can't parse check-attr return: $attr\n"; +} + +sub process_file { + my($file) = @_; + print "DOFIL: $file\n" if($opt{v}>=1); + + # For speed we read in the entire file then do the substitutions. + local($_) = ''; + my $len; + open INFILE, "<", $file or die "Can't open $file: $!"; + while(1){ + # On at least some systems we only get 64K. + my $len = sysread(INFILE, $_, 999999, length($_)); + last if($len == 0); + die "read failed: $!" unless defined($len); + } + close INFILE; + + local $::current_file = $file; # used under handlevar + # $1 - var and value (including trailing space but not $) + # $2 - var + # $4 - value or undef +#s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\N{DOLLAR SIGN}]+))?)\$/&handlevar($2,$4)/eg; +my $count = s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2,$4)/eg; +# XXX had o modifier, why? + return unless($count>0); + return if($opt{n}); + + my $ofile = $file . ".nht"; + open(TOUT, ">", $ofile) or die "Can't open $ofile"; + die "write failed: $!" unless defined syswrite(TOUT, $_); + close TOUT or die "Can't close $ofile"; + rename $ofile, $file or die "Can't rename $ofile to $file"; +} + +sub cmdparse { + my(@in) = @_; + + # What are we doing? + $opt{cmd} = 'date'; # really nhsub + if($in[0] eq '--add'){ + $opt{cmd} = 'add'; + shift @in; + } + if($in[0] eq '--commit'){ + $opt{cmd} = 'commit'; + shift @in; + } + +# add: -n -v +# commit: --dry-run -v +# nhsub: -n -v + while($in[0] =~ m/^-/){ + local($_) = $in[0]; + if($_ eq '--'){ + shift @in; + last; + } + if(m/^--/){ + if($opt{cmd} eq 'commit' && $_ eq '--dry-run'){ + $opt{'n'} = 1; + } + shift @in; + next; + } + if(m/^-(.*)/){ + foreach my $single ( split(//,$1) ){ + # don't do -v here from add/commit + if($single ne 'v'){ + $opt{$single}++; + } elsif($opt{cmd} eq 'date'){ + $opt{$single}++; + } + } + } + shift @in; + } + + ($mode) = ($opt{cmd} =~ m/^(.)/); + $mode = 'f' if($opt{cmd} eq 'date' && ($opt{f}||$opt{F})); + $mode = 'f' if($opt{cmd} eq 'add' && $opt{f}); + + return @in; # this is our file list +} + +sub git_config { + my($section, $var) = @_; + my $raw = `git config --local --get $section.$var`; + $raw =~ s/[\r\n]*$//g; + return $raw if(length $raw); + die "Missing config var: [$section] $var\n"; +} + +sub handlevar { + my($var, $val) = @_; +# print "HIT '$var' '$val'\n" if($debug2); + + my $subname = "PREFIX::$var"; + if(defined &$subname){ + no strict; + print " SUBIN: $var '$val'\n" if($opt{v}>=3); + $val =~ s/\s+$//; + $val = &$subname($val); + print " SUBOT: $var '$val'\n" if($opt{v}>=3); + } else { + warn "No handler for \$$PREFIX-$var\n"; + } + + if(length $val){ + return "\$$PREFIX-$var: $val \$"; + } else { + return "\$$PREFIX-$var\$"; + } +} + +package PREFIX; +use POSIX qw(strftime); + +# On push, put in the current date because we changed the file. +# On pull, keep the current value so we can see the last change date. +sub Date { + my($val) = @_; + # we add this to make merge easier for now XXX + my $now = time; # not %s below - may not be portable + # YYYY/MM/DD HH:MM:SS + $val = "$now " . strftime("%Y/%m/%d %H:%M:%S", gmtime($now)); + return $val; +} + +#sub Header { +#} +#sub Author { +#} + +# NB: the standard-ish Revision line isn't enough - you need Branch:Revision - +# but we split it into 2 so we can use the standard processing code on Revision +# and just slip Branch in. +sub Branch { + my($val) = @_; + $val = `git symbolic-ref -q --short HEAD`; + $val =~ s/[\n\r]*$//; + $val =~ s/^\*\s*//; + $val = "(unknown)" unless($val =~ m/^[[:print:]]+$/); + return $val; +} + +sub Revision { + my($val) = @_; + my @val = `git log --follow --oneline $::current_file`; + my $ver = 0+$#val; + $ver = 0 if($ver < 0); + $val = "1.$ver"; + return $val; +} +__END__ + +=head1 NAME + +C - NetHack git command for substitution variables + +=head1 SYNOPSIS + +C + +=head1 DESCRIPTION + +C rewrites the specified files by doing variable substitution for +variables starting with the prefix specified in the repository's +C configuration variable. C is also invoked +internally from the implementation of the C and C +commands. + +The program re-writes those files listed on the command line; if the file +is actually a directory, the program recurses into that directory tree. +Not all files found are re-written; some are ignored and those with no +substitution variables are not re-written. Unless changed by the options, +files that have not changed are not affected. + +If no files are listed on the command line, the current directory is +checked as if specified as C<.>. +Files listed directly on the command line are always checked. +The C<.git> directory is never processed. + +The following command line options are available: + +=over + +=item C<-v[v[v]]> + +Verbose output; may be (usefully) specified up to 3 times. Not available +when invoked as part of C or C. + +=item C<-n> + +Do not write any files. + +=item C<-f> + +Force, version 1: +Perform substitution even if the file has not changed, +except no dot files are processed unless listed directly on the command line. +This prevents accidents with editor temprorary files while recursing. Note +that this overloads the C<-f> option of C and C. + +=item C<-F> + +Force, version 2: +Perform substitution even if the file has not changed, +even if the NHSUBST attribute is not set for the +file, and only if the file is not ignored by git. Not available +when invoked as part of C or C. + +=back diff --git a/DEVEL/nhgitset.pl b/DEVEL/nhgitset.pl index 183c73d69..08068484a 100755 --- a/DEVEL/nhgitset.pl +++ b/DEVEL/nhgitset.pl @@ -3,7 +3,7 @@ # value of nethack.setupversion we will end up with when this is done # version 1 is reserved for repos checked out before versioning was added -my $version_new = 2; +my $version_new = 3; my $version_old = 0; # current version, if any (0 is no entry ergo new repo) use Cwd; @@ -100,16 +100,29 @@ print STDERR "Installing aliases\n" if($opt_v); $addpath = catfile(curdir(),'.git','hooks','NHadd'); &add_alias('nhadd', "!$addpath add"); &add_alias('nhcommit', "!$addpath commit"); +my $nhsub = catfile(curdir(),'.git','hooks','nhsub'); +&add_alias('nhsub', "!$nhsub"); print STDERR "Installing filter/merge\n" if($opt_v); -if($^O eq "MSWin32"){ - $cmd = '.git\\\\hooks\\\\NHtext'; -} else { - $cmd = catfile(curdir(),'.git','hooks','NHtext'); +# XXXX need it in NHadd to find nhsub??? +# removed at version 3 +#if($^O eq "MSWin32"){ +# $cmd = '.git\\\\hooks\\\\NHtext'; +#} else { +# $cmd = catfile(curdir(),'.git','hooks','NHtext'); +#} +#&add_config('filter.NHtext.clean', "$cmd --clean %f"); +#&add_config('filter.NHtext.smudge', "$cmd --smudge %f"); +if($version_old == 1 or $version_old == 2){ + print STDERR "Removing filter.NHtext\n" if($opt_v); + system('git','config','--unset','filter.NHtext.clean') unless($opt_n); + system('git','config','--unset','filter.NHtext.smudge') unless($opt_n); + system('git','config','--remove-section','filter.NHtext') unless($opt_n); + + print STDERR "Removing NHtext\n" if($opt_v); + unlink catfile(curdir(),'.git','hooks','NHtext') unless($opt_n); } -&add_config('filter.NHtext.clean', "$cmd --clean %f"); -&add_config('filter.NHtext.smudge', "$cmd --smudge %f"); $cmd = catfile(curdir(),'.git','hooks','NHsubst'); &add_config('merge.NHsubst.name', 'NetHack Keyword Substitution'); diff --git a/dat/.gitattributes b/dat/.gitattributes index 72aa05edd..b59108e49 100644 --- a/dat/.gitattributes +++ b/dat/.gitattributes @@ -1,3 +1,3 @@ -*.def filter=NHtext merge=NHsubst -*.des filter=NHtext merge=NHsubst -*.txt filter=NHtext merge=NHsubst +*.def NHSUBST +*.des NHSUBST +*.txt NHSUBST diff --git a/dat/.gitignore b/dat/.gitignore index 1784229ab..caece5a59 100644 --- a/dat/.gitignore +++ b/dat/.gitignore @@ -20,3 +20,4 @@ nhdat dlb.lst guioptions porthelp +NetHack.ad diff --git a/dat/Arch.des b/dat/Arch.des index 3c1ccfaf0..4ea3a818b 100644 --- a/dat/Arch.des +++ b/dat/Arch.des @@ -70,25 +70,25 @@ DOOR:locked,(24,14) DOOR:closed,(31,14) DOOR:locked,(49,14) # Lord Carnarvon -MONSTER:'@',"Lord Carnarvon",(25,10) +MONSTER:('@',"Lord Carnarvon"),(25,10) # The treasure of Lord Carnarvon -OBJECT:'(',"chest",(25,10) +OBJECT:('(',"chest"),(25,10) # student guards for the audience chamber -MONSTER:'@',"student",(26,09) -MONSTER:'@',"student",(27,09) -MONSTER:'@',"student",(28,09) -MONSTER:'@',"student",(26,10) -MONSTER:'@',"student",(28,10) -MONSTER:'@',"student",(26,11) -MONSTER:'@',"student",(27,11) -MONSTER:'@',"student",(28,11) +MONSTER:('@',"student"),(26,09) +MONSTER:('@',"student"),(27,09) +MONSTER:('@',"student"),(28,09) +MONSTER:('@',"student"),(26,10) +MONSTER:('@',"student"),(28,10) +MONSTER:('@',"student"),(26,11) +MONSTER:('@',"student"),(27,11) +MONSTER:('@',"student"),(28,11) # city watch guards in the antechambers -MONSTER:'@',"watchman",(50,06) -MONSTER:'@',"watchman",(50,14) +MONSTER:('@',"watchman"),(50,06) +MONSTER:('@',"watchman"),(50,14) # Eels in the moat -MONSTER:';',"giant eel",(20,10) -MONSTER:';',"giant eel",(45,04) -MONSTER:';',"giant eel",(33,16) +MONSTER:(';',"giant eel"),(20,10) +MONSTER:(';',"giant eel"),(45,04) +MONSTER:(';',"giant eel"),(33,16) # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Random traps @@ -99,18 +99,18 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Monsters on siege duty. -MONSTER: 'S',random,(60,09) -MONSTER: 'M',random,(60,10) -MONSTER: 'S',random,(60,11) -MONSTER: 'S',random,(60,12) -MONSTER: 'M',random,(60,13) -MONSTER: 'S',random,(61,10) -MONSTER: 'S',random,(61,11) -MONSTER: 'S',random,(61,12) -MONSTER: 'S',random,(30,03) -MONSTER: 'M',random,(20,17) -MONSTER: 'S',random,(67,02) -MONSTER: 'S',random,(10,19) +MONSTER: 'S',(60,09) +MONSTER: 'M',(60,10) +MONSTER: 'S',(60,11) +MONSTER: 'S',(60,12) +MONSTER: 'M',(60,13) +MONSTER: 'S',(61,10) +MONSTER: 'S',(61,11) +MONSTER: 'S',(61,12) +MONSTER: 'S',(30,03) +MONSTER: 'M',(20,17) +MONSTER: 'S',(67,02) +MONSTER: 'S',(10,19) # # The "locate" level for the quest. @@ -151,13 +151,13 @@ REGION:(25,09,28,11),unlit,"temple" REGION:(25,13,28,16),lit,"temple" REGION:(30,04,30,16),lit,"ordinary" REGION:(32,04,32,16),unlit,"ordinary" -REGION:(33,04,53,04),unlit,"ordinary",unfilled,true +REGION:(33,04,53,04),unlit,"ordinary",unfilled,irregular REGION:(36,10,37,10),unlit,"ordinary" REGION:(39,09,39,11),unlit,"ordinary" -REGION:(36,06,42,08),unlit,"ordinary",unfilled,true -REGION:(36,12,42,14),unlit,"ordinary",unfilled,true +REGION:(36,06,42,08),unlit,"ordinary",unfilled,irregular +REGION:(36,12,42,14),unlit,"ordinary",unfilled,irregular REGION:(46,06,51,09),unlit,"ordinary" -REGION:(46,11,49,11),unlit,"ordinary",unfilled,true +REGION:(46,11,49,11),unlit,"ordinary",unfilled,irregular REGION:(48,13,51,14),unlit,"ordinary" # Doors DOOR:closed,(31,04) @@ -186,21 +186,21 @@ ALTAR:(26,15),align[2],altar # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Treasure? ENGRAVING:random,engrave,"X marks the spot." ENGRAVING:random,engrave,"X marks the spot." @@ -231,33 +231,33 @@ TRAP:"dart",random TRAP:"rolling boulder",(32,10) TRAP:"rolling boulder",(40,16) # Random monsters. -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'M',random,random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',random,random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'M',random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:'M',random # # The "goal" level for the quest. @@ -323,21 +323,21 @@ NON_DIGGABLE:(00,00,75,19) # The altar of Huhetotl. Unattended. ALTAR:(50,14),chaos,altar # Objects -OBJECT:'(',"crystal ball",(50,14),blessed,5,"The Orb of Detection" -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('(',"crystal ball"),(50,14),blessed,5,name:"The Orb of Detection" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -347,34 +347,34 @@ TRAP:random,random TRAP:random,random TRAP:"rolling boulder",(46,14) # Random monsters. -MONSTER:'&',"Minion of Huhetotl",(50,14) -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'S',random,random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',"human mummy",random -MONSTER:'M',random,random +MONSTER:('&',"Minion of Huhetotl"),(50,14) +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:'S',random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:('M',"human mummy"),random +MONSTER:'M',random # # The "fill" levels for the quest. @@ -387,76 +387,88 @@ MONSTER:'M',random,random LEVEL: "Arc-fila" # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'S', random, random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: 'S', random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random,random,random -MONSTER: 'S', random, random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random,random + MONSTER: 'S', random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'S', random, random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: 'S', random +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'S', random, random -MONSTER: 'M', "human mummy", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random + MONSTER: 'S', random + MONSTER: ('M', "human mummy"), random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'S', random, random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + MONSTER: 'S', random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'S', random, random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + MONSTER: 'S', random +} RANDOM_CORRIDORS LEVEL: "Arc-filb" # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'M', random, random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: 'M', random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random,random,random -MONSTER: 'M', random, random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random,random + MONSTER: 'M', random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'M', random, random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: 'M', random +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'S', random, random -MONSTER: 'M', "human mummy", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random + MONSTER: 'S', random + MONSTER: ('M', "human mummy"), random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'S', random, random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + MONSTER: 'S', random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'S', random, random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + MONSTER: 'S', random +} RANDOM_CORRIDORS diff --git a/dat/Barb.des b/dat/Barb.des index 29a612015..ea8ab9738 100644 --- a/dat/Barb.des +++ b/dat/Barb.des @@ -60,38 +60,38 @@ DOOR:open,(23,13) DOOR:open,(25,10) DOOR:open,(28,05) # Elder -MONSTER:'@',"Pelias",(10,07) +MONSTER:('@',"Pelias"),(10,07) # The treasure of Pelias -OBJECT:'(',"chest",(09,05) +OBJECT:('(',"chest"),(09,05) # chieftain guards for the audience chamber -MONSTER:'@',"chieftain",(10,05) -MONSTER:'@',"chieftain",(10,09) -MONSTER:'@',"chieftain",(11,05) -MONSTER:'@',"chieftain",(11,09) -MONSTER:'@',"chieftain",(14,05) -MONSTER:'@',"chieftain",(14,09) -MONSTER:'@',"chieftain",(16,05) -MONSTER:'@',"chieftain",(16,09) +MONSTER:('@',"chieftain"),(10,05) +MONSTER:('@',"chieftain"),(10,09) +MONSTER:('@',"chieftain"),(11,05) +MONSTER:('@',"chieftain"),(11,09) +MONSTER:('@',"chieftain"),(14,05) +MONSTER:('@',"chieftain"),(14,09) +MONSTER:('@',"chieftain"),(16,05) +MONSTER:('@',"chieftain"),(16,09) # Non diggable walls NON_DIGGABLE:(00,00,75,19) # One trap to keep the ogres at bay. TRAP:"spiked pit",(37,07) # Eels in the river -MONSTER:';',"giant eel",(36,01) -MONSTER:';',"giant eel",(37,09) -MONSTER:';',"giant eel",(39,15) +MONSTER:(';',"giant eel"),(36,01) +MONSTER:(';',"giant eel"),(37,09) +MONSTER:(';',"giant eel"),(39,15) # Monsters on siege duty. -MONSTER:'O',"ogre",(40,08),hostile -MONSTER:'O',"ogre",(41,06),hostile -MONSTER:'O',"ogre",(41,07),hostile -MONSTER:'O',"ogre",(41,08),hostile -MONSTER:'O',"ogre",(41,09),hostile -MONSTER:'O',"ogre",(41,10),hostile -MONSTER:'O',"ogre",(42,06),hostile -MONSTER:'O',"ogre",(42,07),hostile -MONSTER:'O',"ogre",(42,08),hostile -MONSTER:'O',"ogre",(42,09),hostile -MONSTER:'O',"ogre",(42,10),hostile +MONSTER:('O',"ogre"),(40,08),hostile +MONSTER:('O',"ogre"),(41,06),hostile +MONSTER:('O',"ogre"),(41,07),hostile +MONSTER:('O',"ogre"),(41,08),hostile +MONSTER:('O',"ogre"),(41,09),hostile +MONSTER:('O',"ogre"),(41,10),hostile +MONSTER:('O',"ogre"),(42,06),hostile +MONSTER:('O',"ogre"),(42,07),hostile +MONSTER:('O',"ogre"),(42,08),hostile +MONSTER:('O',"ogre"),(42,09),hostile +MONSTER:('O',"ogre"),(42,10),hostile # # The "locate" level for the quest. @@ -148,21 +148,21 @@ DOOR:locked,(55,06) STAIR:(05,02),up STAIR:(70,13),down # Objects -OBJECT:random,random,(42,03) -OBJECT:random,random,(42,03) -OBJECT:random,random,(42,03) -OBJECT:random,random,(41,03) -OBJECT:random,random,(41,03) -OBJECT:random,random,(41,03) -OBJECT:random,random,(41,03) -OBJECT:random,random,(41,08) -OBJECT:random,random,(41,08) -OBJECT:random,random,(42,08) -OBJECT:random,random,(42,08) -OBJECT:random,random,(42,08) -OBJECT:random,random,(71,13) -OBJECT:random,random,(71,13) -OBJECT:random,random,(71,13) +OBJECT:random,(42,03) +OBJECT:random,(42,03) +OBJECT:random,(42,03) +OBJECT:random,(41,03) +OBJECT:random,(41,03) +OBJECT:random,(41,03) +OBJECT:random,(41,03) +OBJECT:random,(41,08) +OBJECT:random,(41,08) +OBJECT:random,(42,08) +OBJECT:random,(42,08) +OBJECT:random,(42,08) +OBJECT:random,(71,13) +OBJECT:random,(71,13) +OBJECT:random,(71,13) # Random traps TRAP:"spiked pit",(10,13) TRAP:"spiked pit",(21,07) @@ -173,33 +173,33 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'O',"ogre",(12,09),hostile -MONSTER:'O',"ogre",(18,11),hostile -MONSTER:'O',"ogre",(45,05),hostile -MONSTER:'O',"ogre",(45,06),hostile -MONSTER:'O',"ogre",(47,05),hostile -MONSTER:'O',"ogre",(46,05),hostile -MONSTER:'O',"ogre",(56,03),hostile -MONSTER:'O',"ogre",(56,04),hostile -MONSTER:'O',"ogre",(56,05),hostile -MONSTER:'O',"ogre",(56,06),hostile -MONSTER:'O',"ogre",(57,03),hostile -MONSTER:'O',"ogre",(57,04),hostile -MONSTER:'O',"ogre",(57,05),hostile -MONSTER:'O',"ogre",(57,06),hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',random,random,hostile -MONSTER:'T',random,random,hostile -MONSTER:'T',"rock troll",(46,06),hostile -MONSTER:'T',"rock troll",(47,06),hostile -MONSTER:'T',"rock troll",(56,07),hostile -MONSTER:'T',"rock troll",(57,07),hostile -MONSTER:'T',"rock troll",(70,13),hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',random,random,hostile +MONSTER:('O',"ogre"),(12,09),hostile +MONSTER:('O',"ogre"),(18,11),hostile +MONSTER:('O',"ogre"),(45,05),hostile +MONSTER:('O',"ogre"),(45,06),hostile +MONSTER:('O',"ogre"),(47,05),hostile +MONSTER:('O',"ogre"),(46,05),hostile +MONSTER:('O',"ogre"),(56,03),hostile +MONSTER:('O',"ogre"),(56,04),hostile +MONSTER:('O',"ogre"),(56,05),hostile +MONSTER:('O',"ogre"),(56,06),hostile +MONSTER:('O',"ogre"),(57,03),hostile +MONSTER:('O',"ogre"),(57,04),hostile +MONSTER:('O',"ogre"),(57,05),hostile +MONSTER:('O',"ogre"),(57,06),hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:'O',random,hostile +MONSTER:'T',random,hostile +MONSTER:('T',"rock troll"),(46,06),hostile +MONSTER:('T',"rock troll"),(47,06),hostile +MONSTER:('T',"rock troll"),(56,07),hostile +MONSTER:('T',"rock troll"),(57,07),hostile +MONSTER:('T',"rock troll"),(70,13),hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:'T',random,hostile # # The "goal" level for the quest. @@ -244,21 +244,21 @@ STAIR:(36,05),up ALTAR:(63,04),noncoaligned,altar NON_DIGGABLE:(00,00,75,19) # Objects -OBJECT:'*',"luckstone",(63,04),blessed,0,"The Heart of Ahriman" -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('*',"luckstone"),(63,04),blessed,0,name:"The Heart of Ahriman" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -267,34 +267,34 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'@',"Thoth Amon",(63,04),hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',"ogre",random,hostile -MONSTER:'O',random,random,hostile -MONSTER:'O',random,random,hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',"rock troll",random,hostile -MONSTER:'T',random,random,hostile +MONSTER:('@',"Thoth Amon"),(63,04),hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:('O',"ogre"),random,hostile +MONSTER:'O',random,hostile +MONSTER:'O',random,hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:('T',"rock troll"),random,hostile +MONSTER:'T',random,hostile WALLIFY # @@ -307,64 +307,64 @@ WALLIFY # MAZE: "Bar-fila" , ' ' -INIT_MAP: '.' , '.' , true , true , unlit , false +INIT_MAP: mines, '.' , '.' , true , true , unlit , false NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # TRAP: random, random TRAP: random, random TRAP: random, random TRAP: random, random # -MONSTER: 'O', "ogre", random, hostile -MONSTER: 'O', "ogre", random, hostile -MONSTER: 'O', random, random, hostile -MONSTER: 'T', "rock troll", random, hostile +MONSTER: ('O', "ogre"), random, hostile +MONSTER: ('O', "ogre"), random, hostile +MONSTER: 'O', random, hostile +MONSTER: ('T', "rock troll"), random, hostile MAZE: "Bar-filb" , ' ' -INIT_MAP: '.' , ' ' , true , true , unlit , true +INIT_MAP: mines, '.' , ' ' , true , true , unlit , true NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # TRAP: random, random TRAP: random, random TRAP: random, random TRAP: random, random # -MONSTER: 'O', "ogre", random, hostile -MONSTER: 'O', "ogre", random, hostile -MONSTER: 'O', "ogre", random, hostile -MONSTER: 'O', "ogre", random, hostile -MONSTER: 'O', "ogre", random, hostile -MONSTER: 'O', "ogre", random, hostile -MONSTER: 'O', "ogre", random, hostile -MONSTER: 'O', random , random, hostile -MONSTER: 'T', "rock troll", random, hostile -MONSTER: 'T', "rock troll", random, hostile -MONSTER: 'T', "rock troll", random, hostile -MONSTER: 'T', random , random, hostile +MONSTER: ('O', "ogre"), random, hostile +MONSTER: ('O', "ogre"), random, hostile +MONSTER: ('O', "ogre"), random, hostile +MONSTER: ('O', "ogre"), random, hostile +MONSTER: ('O', "ogre"), random, hostile +MONSTER: ('O', "ogre"), random, hostile +MONSTER: ('O', "ogre"), random, hostile +MONSTER: 'O' , random, hostile +MONSTER: ('T', "rock troll"), random, hostile +MONSTER: ('T', "rock troll"), random, hostile +MONSTER: ('T', "rock troll"), random, hostile +MONSTER: 'T' , random, hostile diff --git a/dat/Caveman.des b/dat/Caveman.des index f9617c86f..0a84e6c25 100644 --- a/dat/Caveman.des +++ b/dat/Caveman.des @@ -37,14 +37,14 @@ MAP ENDMAP # Dungeon Description REGION:(00,00,75,19),unlit,"ordinary" -REGION:(13,01,40,05),lit,"temple",unfilled,true +REGION:(13,01,40,05),lit,"temple",unfilled,irregular # The occupied rooms. -REGION:(02,01,08,03),lit,"ordinary",unfilled,true -REGION:(01,11,06,14),lit,"ordinary",unfilled,true -REGION:(13,08,18,10),lit,"ordinary",unfilled,true -REGION:(05,17,14,18),lit,"ordinary",unfilled,true -REGION:(17,16,23,18),lit,"ordinary",unfilled,true -REGION:(35,16,44,18),lit,"ordinary",unfilled,true +REGION:(02,01,08,03),lit,"ordinary",unfilled,irregular +REGION:(01,11,06,14),lit,"ordinary",unfilled,irregular +REGION:(13,08,18,10),lit,"ordinary",unfilled,irregular +REGION:(05,17,14,18),lit,"ordinary",unfilled,irregular +REGION:(17,16,23,18),lit,"ordinary",unfilled,irregular +REGION:(35,16,44,18),lit,"ordinary",unfilled,irregular # Stairs STAIR:(02,03),down # Portal arrival point @@ -54,18 +54,18 @@ DOOR:locked,(19,06) # The temple altar (this will force a priest(ess) to be created) ALTAR:(36,02),coaligned,shrine # Shaman Karnov -MONSTER:'@',"Shaman Karnov",(35,02) +MONSTER:('@',"Shaman Karnov"),(35,02) # The treasure of Shaman Karnov -OBJECT:'(',"chest",(34,02) +OBJECT:('(',"chest"),(34,02) # neanderthal guards for the audience chamber -MONSTER:'@',"neanderthal",(20,03) -MONSTER:'@',"neanderthal",(20,02) -MONSTER:'@',"neanderthal",(20,01) -MONSTER:'@',"neanderthal",(21,03) -MONSTER:'@',"neanderthal",(21,02) -MONSTER:'@',"neanderthal",(21,01) -MONSTER:'@',"neanderthal",(22,01) -MONSTER:'@',"neanderthal",(26,09) +MONSTER:('@',"neanderthal"),(20,03) +MONSTER:('@',"neanderthal"),(20,02) +MONSTER:('@',"neanderthal"),(20,01) +MONSTER:('@',"neanderthal"),(21,03) +MONSTER:('@',"neanderthal"),(21,02) +MONSTER:('@',"neanderthal"),(21,01) +MONSTER:('@',"neanderthal"),(22,01) +MONSTER:('@',"neanderthal"),(26,09) # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Random traps @@ -76,18 +76,18 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Monsters on siege duty (in the outer caves). -MONSTER: 'h',"bugbear",(47,02),hostile -MONSTER: 'h',"bugbear",(48,03),hostile -MONSTER: 'h',"bugbear",(49,04),hostile -MONSTER: 'h',"bugbear",(67,03),hostile -MONSTER: 'h',"bugbear",(69,04),hostile -MONSTER: 'h',"bugbear",(51,13),hostile -MONSTER: 'h',"bugbear",(53,14),hostile -MONSTER: 'h',"bugbear",(55,15),hostile -MONSTER: 'h',"bugbear",(63,10),hostile -MONSTER: 'h',"bugbear",(65,09),hostile -MONSTER: 'h',"bugbear",(67,10),hostile -MONSTER: 'h',"bugbear",(69,11),hostile +MONSTER: ('h',"bugbear"),(47,02),hostile +MONSTER: ('h',"bugbear"),(48,03),hostile +MONSTER: ('h',"bugbear"),(49,04),hostile +MONSTER: ('h',"bugbear"),(67,03),hostile +MONSTER: ('h',"bugbear"),(69,04),hostile +MONSTER: ('h',"bugbear"),(51,13),hostile +MONSTER: ('h',"bugbear"),(53,14),hostile +MONSTER: ('h',"bugbear"),(55,15),hostile +MONSTER: ('h',"bugbear"),(63,10),hostile +MONSTER: ('h',"bugbear"),(65,09),hostile +MONSTER: ('h',"bugbear"),(67,10),hostile +MONSTER: ('h',"bugbear"),(69,11),hostile WALLIFY # @@ -124,7 +124,7 @@ MAP ENDMAP # Dungeon Description REGION:(00,00,75,19),unlit,"ordinary" -REGION:(52,06,73,15),lit,"ordinary",unfilled,true +REGION:(52,06,73,15),lit,"ordinary",unfilled,irregular # Doors DOOR:locked,(28,11) # Stairs @@ -133,21 +133,21 @@ STAIR:(73,10),down # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -156,33 +156,33 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'h',"bugbear",(02,10),hostile -MONSTER:'h',"bugbear",(03,11),hostile -MONSTER:'h',"bugbear",(04,12),hostile -MONSTER:'h',"bugbear",(02,11),hostile -MONSTER:'h',"bugbear",(16,16),hostile -MONSTER:'h',"bugbear",(17,17),hostile -MONSTER:'h',"bugbear",(18,18),hostile -MONSTER:'h',"bugbear",(19,16),hostile -MONSTER:'h',"bugbear",(30,06),hostile -MONSTER:'h',"bugbear",(31,07),hostile -MONSTER:'h',"bugbear",(32,08),hostile -MONSTER:'h',"bugbear",(33,06),hostile -MONSTER:'h',"bugbear",(34,07),hostile -MONSTER:'h',"bugbear",random,hostile -MONSTER:'h',"bugbear",random,hostile -MONSTER:'h',"bugbear",random,hostile -MONSTER:'h',"bugbear",random,hostile -MONSTER:'h',random,random,hostile -MONSTER:'H',random,random,hostile -MONSTER:'H',"hill giant",(03,12),hostile -MONSTER:'H',"hill giant",(20,17),hostile -MONSTER:'H',"hill giant",(35,08),hostile -MONSTER:'H',"hill giant",random,hostile -MONSTER:'H',"hill giant",random,hostile -MONSTER:'H',"hill giant",random,hostile -MONSTER:'H',"hill giant",random,hostile -MONSTER:'H',random,random,hostile +MONSTER:('h',"bugbear"),(02,10),hostile +MONSTER:('h',"bugbear"),(03,11),hostile +MONSTER:('h',"bugbear"),(04,12),hostile +MONSTER:('h',"bugbear"),(02,11),hostile +MONSTER:('h',"bugbear"),(16,16),hostile +MONSTER:('h',"bugbear"),(17,17),hostile +MONSTER:('h',"bugbear"),(18,18),hostile +MONSTER:('h',"bugbear"),(19,16),hostile +MONSTER:('h',"bugbear"),(30,06),hostile +MONSTER:('h',"bugbear"),(31,07),hostile +MONSTER:('h',"bugbear"),(32,08),hostile +MONSTER:('h',"bugbear"),(33,06),hostile +MONSTER:('h',"bugbear"),(34,07),hostile +MONSTER:('h',"bugbear"),random,hostile +MONSTER:('h',"bugbear"),random,hostile +MONSTER:('h',"bugbear"),random,hostile +MONSTER:('h',"bugbear"),random,hostile +MONSTER:'h',random,hostile +MONSTER:'H',random,hostile +MONSTER:('H',"hill giant"),(03,12),hostile +MONSTER:('H',"hill giant"),(20,17),hostile +MONSTER:('H',"hill giant"),(35,08),hostile +MONSTER:('H',"hill giant"),random,hostile +MONSTER:('H',"hill giant"),random,hostile +MONSTER:('H',"hill giant"),random,hostile +MONSTER:('H',"hill giant"),random,hostile +MONSTER:'H',random,hostile WALLIFY # @@ -224,26 +224,26 @@ STAIR:random,up # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Objects -OBJECT:')',"mace",(23,10),blessed,0,"The Sceptre of Might" -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:(')',"mace"),(23,10),blessed,0,name:"The Sceptre of Might" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # monsters. -MONSTER:'D',"Chromatic Dragon",(23,10),asleep -MONSTER:'F',"shrieker",(26,13) -MONSTER:'F',"shrieker",(25,8) -MONSTER:'F',"shrieker",(45,11) +MONSTER:('D',"Chromatic Dragon"),(23,10),asleep +MONSTER:('F',"shrieker"),(26,13) +MONSTER:('F',"shrieker"),(25,8) +MONSTER:('F',"shrieker"),(45,11) WALLIFY # @@ -256,63 +256,63 @@ WALLIFY # MAZE: "Cav-fila" , ' ' -INIT_MAP: '.' , ' ' , true , true , random , true +INIT_MAP: mines, '.' , ' ' , true , true , random , true NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # TRAP: random, random TRAP: random, random TRAP: random, random TRAP: random, random # -MONSTER: 'h', "bugbear", random, hostile -MONSTER: 'h', "bugbear", random, hostile -MONSTER: 'h', "bugbear", random, hostile -MONSTER: 'h', "bugbear", random, hostile -MONSTER: 'h', "bugbear", random, hostile -MONSTER: 'h', random, random, hostile -MONSTER: 'H', "hill giant", random, hostile +MONSTER: ('h', "bugbear"), random, hostile +MONSTER: ('h', "bugbear"), random, hostile +MONSTER: ('h', "bugbear"), random, hostile +MONSTER: ('h', "bugbear"), random, hostile +MONSTER: ('h', "bugbear"), random, hostile +MONSTER: 'h', random, hostile +MONSTER: ('H', "hill giant"), random, hostile MAZE: "Cav-filb" , ' ' -INIT_MAP: '.' , ' ' , true , true , random , true +INIT_MAP: mines, '.' , ' ' , true , true , random , true NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # TRAP: random, random TRAP: random, random TRAP: random, random TRAP: random, random # -MONSTER: 'h', "bugbear", random, hostile -MONSTER: 'h', "bugbear", random, hostile -MONSTER: 'h', "bugbear", random, hostile -MONSTER: 'h', "bugbear", random, hostile -MONSTER: 'h', random, random, hostile -MONSTER: 'h', random, random, hostile -MONSTER: 'H', "hill giant", random, hostile -MONSTER: 'H', "hill giant", random, hostile +MONSTER: ('h', "bugbear"), random, hostile +MONSTER: ('h', "bugbear"), random, hostile +MONSTER: ('h', "bugbear"), random, hostile +MONSTER: ('h', "bugbear"), random, hostile +MONSTER: 'h', random, hostile +MONSTER: 'h', random, hostile +MONSTER: ('H', "hill giant"), random, hostile +MONSTER: ('H', "hill giant"), random, hostile diff --git a/dat/Healer.des b/dat/Healer.des index 3a93adc4f..dcbb01b2a 100644 --- a/dat/Healer.des +++ b/dat/Healer.des @@ -57,18 +57,18 @@ DOOR:closed,(47,08) DOOR:closed,(48,12) DOOR:locked,(50,10) # Hippocrates -MONSTER:'@',"Hippocrates",(37,10) +MONSTER:('@',"Hippocrates"),(37,10) # The treasure of Hippocrates -OBJECT:'(',"chest",(37,10) +OBJECT:('(',"chest"),(37,10) # intern guards for the audience chamber -MONSTER:'@',"attendant",(29,08) -MONSTER:'@',"attendant",(29,09) -MONSTER:'@',"attendant",(29,10) -MONSTER:'@',"attendant",(29,11) -MONSTER:'@',"attendant",(40,09) -MONSTER:'@',"attendant",(40,10) -MONSTER:'@',"attendant",(40,11) -MONSTER:'@',"attendant",(40,13) +MONSTER:('@',"attendant"),(29,08) +MONSTER:('@',"attendant"),(29,09) +MONSTER:('@',"attendant"),(29,10) +MONSTER:('@',"attendant"),(29,11) +MONSTER:('@',"attendant"),(40,09) +MONSTER:('@',"attendant"),(40,10) +MONSTER:('@',"attendant"),(40,11) +MONSTER:('@',"attendant"),(40,13) # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Random traps @@ -79,29 +79,29 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Monsters on siege duty. -MONSTER: 'r',"rabid rat",random -MONSTER: 'r',"rabid rat",random -MONSTER: 'r',"rabid rat",random -MONSTER: 'r',"rabid rat",random -MONSTER: 'r',"rabid rat",random -MONSTER: 'r',"rabid rat",random -MONSTER: 'r',"rabid rat",random -MONSTER: 'r',"rabid rat",random -MONSTER: 'r',"rabid rat",random -MONSTER: 'r',"rabid rat",random -MONSTER: ';',"giant eel",random -MONSTER: ';',"shark",random -MONSTER: ';', random, random -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile +MONSTER: ('r',"rabid rat"),random +MONSTER: ('r',"rabid rat"),random +MONSTER: ('r',"rabid rat"),random +MONSTER: ('r',"rabid rat"),random +MONSTER: ('r',"rabid rat"),random +MONSTER: ('r',"rabid rat"),random +MONSTER: ('r',"rabid rat"),random +MONSTER: ('r',"rabid rat"),random +MONSTER: ('r',"rabid rat"),random +MONSTER: ('r',"rabid rat"),random +MONSTER: (';',"giant eel"),random +MONSTER: (';',"shark"),random +MONSTER: ';', random +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile # # The "locate" level for the quest. # @@ -112,7 +112,7 @@ MONSTER: 'S',random,random,hostile MAZE: "Hea-loca",' ' FLAGS: hardfloor # -INIT_MAP: '.' , 'P', true , true , lit , false +INIT_MAP: mines, '.' , 'P', true , true , lit , false GEOMETRY:center,center MAP PPPPPPPPPPPPP.......PPPPPPPPPPP @@ -142,21 +142,21 @@ NON_DIGGABLE:(11,02,21,07) # Altar in the temple. ALTAR:(13,05), chaos, shrine # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -165,41 +165,41 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'r',"rabid rat",random -MONSTER:'r',"rabid rat",random -MONSTER:'r',"rabid rat",random -MONSTER:'r',"rabid rat",random -MONSTER:'r',"rabid rat",random -MONSTER:'r',"rabid rat",random -MONSTER:'r',"rabid rat",random -MONSTER:'r',"rabid rat",random -MONSTER:'r',random,random,hostile -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"kraken",random -MONSTER:';',"shark",random -MONSTER:';',"shark",random -MONSTER:';',random, random,hostile -MONSTER:';',random, random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile +MONSTER:('r',"rabid rat"),random +MONSTER:('r',"rabid rat"),random +MONSTER:('r',"rabid rat"),random +MONSTER:('r',"rabid rat"),random +MONSTER:('r',"rabid rat"),random +MONSTER:('r',"rabid rat"),random +MONSTER:('r',"rabid rat"),random +MONSTER:('r',"rabid rat"),random +MONSTER:'r',random,hostile +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"shark"),random +MONSTER:(';',"shark"),random +MONSTER:';', random,hostile +MONSTER:';', random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile # # The "goal" level for the quest. @@ -211,7 +211,7 @@ MONSTER: 'S',random,random,hostile MAZE: "Hea-goal", 'P' # -INIT_MAP: '.' , 'P' , false , true , lit , false +INIT_MAP: mines, '.' , 'P' , false , true , lit , false GEOMETRY:center,center MAP .P....................................PP. @@ -234,22 +234,22 @@ STAIR:(39,10),up # Non diggable walls NON_DIGGABLE:(00,00,40,11) # Objects -OBJECT:')',"quarterstaff",(20,06),blessed,0,"The Staff of Aesculapius" -OBJECT:'/',"lightning",(20,06) -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:(')',"quarterstaff"),(20,06),blessed,0,name:"The Staff of Aesculapius" +OBJECT:('/',"lightning"),(20,06) +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -258,38 +258,38 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'H',"Cyclops",(20,06),hostile -MONSTER:'r',"rabid rat",random -MONSTER:'r',"rabid rat",random -MONSTER:'r',"rabid rat",random -MONSTER:'r',random,random,hostile -MONSTER:'r',random,random,hostile -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"shark",random -MONSTER:';',"shark",random -MONSTER:';',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile +MONSTER:('H',"Cyclops"),(20,06),hostile +MONSTER:('r',"rabid rat"),random +MONSTER:('r',"rabid rat"),random +MONSTER:('r',"rabid rat"),random +MONSTER:'r',random,hostile +MONSTER:'r',random,hostile +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"shark"),random +MONSTER:(';',"shark"),random +MONSTER:';',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile # # The "fill" levels for the quest. @@ -301,34 +301,34 @@ MONSTER: 'S',random,random,hostile # MAZE: "Hea-fila" , 'P' -INIT_MAP: '.' , 'P' , false , true , lit , false +INIT_MAP: mines, '.' , 'P' , false , true , lit , false NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # -MONSTER: 'r', "rabid rat", random -MONSTER: 'r', random, random,hostile -MONSTER: 'r', random, random,hostile -MONSTER: ';', "giant eel", random -MONSTER: ';', "giant eel", random -MONSTER: ';', "electric eel", random -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile +MONSTER: ('r', "rabid rat"), random +MONSTER: 'r', random,hostile +MONSTER: 'r', random,hostile +MONSTER: (';', "giant eel"), random +MONSTER: (';', "giant eel"), random +MONSTER: (';', "electric eel"), random +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile # TRAP: random, random TRAP: random, random @@ -336,42 +336,42 @@ TRAP: random, random TRAP: random, random MAZE: "Hea-filb" , 'P' -INIT_MAP: '.' , 'P' , false , true , lit , false +INIT_MAP: mines, '.' , 'P' , false , true , lit , false NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # -MONSTER: 'r', "rabid rat", random -MONSTER: 'r', "rabid rat", random -MONSTER: 'r', random, random,hostile -MONSTER: 'r', random, random,hostile -MONSTER: ';', "giant eel", random -MONSTER: ';', "giant eel", random -MONSTER: ';', "giant eel", random -MONSTER: ';', "giant eel", random -MONSTER: ';', "giant eel", random -MONSTER: ';', "electric eel", random -MONSTER: ';', "electric eel", random -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'D',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile -MONSTER: 'S',random,random,hostile +MONSTER: ('r', "rabid rat"), random +MONSTER: ('r', "rabid rat"), random +MONSTER: 'r', random,hostile +MONSTER: 'r', random,hostile +MONSTER: (';', "giant eel"), random +MONSTER: (';', "giant eel"), random +MONSTER: (';', "giant eel"), random +MONSTER: (';', "giant eel"), random +MONSTER: (';', "giant eel"), random +MONSTER: (';', "electric eel"), random +MONSTER: (';', "electric eel"), random +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'D',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile +MONSTER: 'S',random,hostile # TRAP: random, random TRAP: random, random diff --git a/dat/Knight.des b/dat/Knight.des index 2be72af7d..5e22f43a9 100644 --- a/dat/Knight.des +++ b/dat/Knight.des @@ -13,7 +13,7 @@ MAZE: "Kni-strt",'.' FLAGS: noteleport,hardfloor # This is a kludge to init the level as a lit field. -INIT_MAP: '.' , '.' , false , false , lit , false +INIT_MAP: mines, '.' , '.' , false , false , lit , false GEOMETRY:center,center MAP .................................................. @@ -62,21 +62,21 @@ DOOR:closed,(45,03) DOOR:closed,(04,12) DOOR:closed,(45,12) # King Arthur -MONSTER:'@',"King Arthur",(09,07) +MONSTER:('@',"King Arthur"),(09,07) # The treasure of King Arthur -OBJECT:'(',"chest",(09,07) +OBJECT:('(',"chest"),(09,07) # knight guards for the watchrooms -MONSTER:'@',"knight",(04,02),peaceful -MONSTER:'@',"knight",(04,13),peaceful -MONSTER:'@',"knight",(45,02),peaceful -MONSTER:'@',"knight",(45,13),peaceful +MONSTER:('@',"knight"),(04,02),peaceful +MONSTER:('@',"knight"),(04,13),peaceful +MONSTER:('@',"knight"),(45,02),peaceful +MONSTER:('@',"knight"),(45,13),peaceful # page guards for the audience chamber -MONSTER:'@',"page",(16,06) -MONSTER:'@',"page",(18,06) -MONSTER:'@',"page",(20,06) -MONSTER:'@',"page",(16,09) -MONSTER:'@',"page",(18,09) -MONSTER:'@',"page",(20,09) +MONSTER:('@',"page"),(16,06) +MONSTER:('@',"page"),(18,06) +MONSTER:('@',"page"),(20,06) +MONSTER:('@',"page"),(16,09) +MONSTER:('@',"page"),(18,09) +MONSTER:('@',"page"),(20,09) # Non diggable walls NON_DIGGABLE:(00,00,49,15) # Random traps @@ -87,18 +87,18 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Monsters on siege duty. -MONSTER: 'i',"quasit",(14,00),hostile -MONSTER: 'i',"quasit",(16,00),hostile -MONSTER: 'i',"quasit",(18,00),hostile -MONSTER: 'i',"quasit",(20,00),hostile -MONSTER: 'i',"quasit",(22,00),hostile -MONSTER: 'i',"quasit",(24,00),hostile -MONSTER: 'i',"quasit",(26,00),hostile -MONSTER: 'i',"quasit",(28,00),hostile -MONSTER: 'i',"quasit",(30,00),hostile -MONSTER: 'i',"quasit",(32,00),hostile -MONSTER: 'i',"quasit",(34,00),hostile -MONSTER: 'i',"quasit",(36,00),hostile +MONSTER: ('i',"quasit"),(14,00),hostile +MONSTER: ('i',"quasit"),(16,00),hostile +MONSTER: ('i',"quasit"),(18,00),hostile +MONSTER: ('i',"quasit"),(20,00),hostile +MONSTER: ('i',"quasit"),(22,00),hostile +MONSTER: ('i',"quasit"),(24,00),hostile +MONSTER: ('i',"quasit"),(26,00),hostile +MONSTER: ('i',"quasit"),(28,00),hostile +MONSTER: ('i',"quasit"),(30,00),hostile +MONSTER: ('i',"quasit"),(32,00),hostile +MONSTER: ('i',"quasit"),(34,00),hostile +MONSTER: ('i',"quasit"),(36,00),hostile # # The "locate" level for the quest. @@ -109,7 +109,7 @@ MONSTER: 'i',"quasit",(36,00),hostile MAZE: "Kni-loca",' ' FLAGS: hardfloor -INIT_MAP: '.' , 'P' , false , true , lit , false +INIT_MAP: mines, '.' , 'P' , false , true , lit , false GEOMETRY:center,center MAP ...PPP.........PPPP..............PPPP... @@ -136,21 +136,21 @@ STAIR:(18,05),down # The altar atop the Tor and its attendant (creating altar makes the priest). ALTAR:(17,05),neutral,shrine # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps # All of the avenues are guarded by magic except for the East. # South @@ -210,33 +210,33 @@ TRAP:"anti magic",random TRAP:"anti magic",random TRAP:"anti magic",random # Random monsters. -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'j',random,random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',random,random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:'i',random,hostile +MONSTER:'j',random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:'j',random,hostile # # The "goal" level for the quest. @@ -278,28 +278,28 @@ STAIR:(03,08),up # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Objects -OBJECT:'(',"mirror",(50,06),blessed,0,"The Magic Mirror of Merlin" -OBJECT:random,random,(33,01) -OBJECT:random,random,(33,02) -OBJECT:random,random,(33,03) -OBJECT:random,random,(33,04) -OBJECT:random,random,(33,05) -OBJECT:random,random,(34,01) -OBJECT:random,random,(34,02) -OBJECT:random,random,(34,03) -OBJECT:random,random,(34,04) -OBJECT:random,random,(34,05) -OBJECT:random,random,(35,01) -OBJECT:random,random,(35,02) -OBJECT:random,random,(35,03) -OBJECT:random,random,(35,04) -OBJECT:random,random,(35,05) -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('(',"mirror"),(50,06),blessed,0,name:"The Magic Mirror of Merlin" +OBJECT:random,(33,01) +OBJECT:random,(33,02) +OBJECT:random,(33,03) +OBJECT:random,(33,04) +OBJECT:random,(33,05) +OBJECT:random,(34,01) +OBJECT:random,(34,02) +OBJECT:random,(34,03) +OBJECT:random,(34,04) +OBJECT:random,(34,05) +OBJECT:random,(35,01) +OBJECT:random,(35,02) +OBJECT:random,(35,03) +OBJECT:random,(35,04) +OBJECT:random,(35,05) +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:"spiked pit",(13,07) TRAP:"spiked pit",(12,08) @@ -310,34 +310,34 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'D',"Ixoth",(50,06),hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',"quasit",random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',"ochre jelly",random,hostile -MONSTER:'j',random,random,hostile +MONSTER:('D',"Ixoth"),(50,06),hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:('i',"quasit"),random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:('j',"ochre jelly"),random,hostile +MONSTER:'j',random,hostile # # The "fill" levels for the quest. @@ -349,27 +349,27 @@ MONSTER:'j',random,random,hostile # MAZE: "Kni-fila" , '.' -INIT_MAP: '.' , 'P' , false , true , lit , false +INIT_MAP: mines, '.' , 'P' , false , true , lit , false NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # -MONSTER: 'i', "quasit", random, hostile -MONSTER: 'i', "quasit", random, hostile -MONSTER: 'i', "quasit", random, hostile -MONSTER: 'i', "quasit", random, hostile -MONSTER: 'i', random, random, hostile -MONSTER: 'j', "ochre jelly", random, hostile +MONSTER: ('i', "quasit"), random, hostile +MONSTER: ('i', "quasit"), random, hostile +MONSTER: ('i', "quasit"), random, hostile +MONSTER: ('i', "quasit"), random, hostile +MONSTER: 'i', random, hostile +MONSTER: ('j', "ochre jelly"), random, hostile # TRAP: random, random TRAP: random, random @@ -377,32 +377,32 @@ TRAP: random, random TRAP: random, random MAZE: "Kni-filb" , '.' -INIT_MAP: '.' , 'P' , false , true , lit , false +INIT_MAP: mines, '.' , 'P' , false , true , lit , false NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # -MONSTER: 'i', "quasit", random, hostile -MONSTER: 'i', "quasit", random, hostile -MONSTER: 'i', "quasit", random, hostile -MONSTER: 'i', "quasit", random, hostile -MONSTER: 'i', random, random, hostile -MONSTER: 'j', "ochre jelly", random, hostile -MONSTER: 'j', "ochre jelly", random, hostile -MONSTER: 'j', "ochre jelly", random, hostile +MONSTER: ('i', "quasit"), random, hostile +MONSTER: ('i', "quasit"), random, hostile +MONSTER: ('i', "quasit"), random, hostile +MONSTER: ('i', "quasit"), random, hostile +MONSTER: 'i', random, hostile +MONSTER: ('j', "ochre jelly"), random, hostile +MONSTER: ('j', "ochre jelly"), random, hostile +MONSTER: ('j', "ochre jelly"), random, hostile # TRAP: random, random TRAP: random, random diff --git a/dat/Monk.des b/dat/Monk.des index fe75301d9..155b37040 100644 --- a/dat/Monk.des +++ b/dat/Monk.des @@ -64,17 +64,17 @@ DOOR:closed,(52,14) # Unattended Altar - unaligned due to conflict - player must align it. ALTAR:(28,09),noalign,altar # The Grand Master -MONSTER:'@',"Grand Master",(28,10) +MONSTER:('@',"Grand Master"),(28,10) # No treasure chest! # guards for the audience chamber -MONSTER:'@',"abbot",(32,07) -MONSTER:'@',"abbot",(32,08) -MONSTER:'@',"abbot",(32,11) -MONSTER:'@',"abbot",(32,12) -MONSTER:'@',"abbot",(33,07) -MONSTER:'@',"abbot",(33,08) -MONSTER:'@',"abbot",(33,11) -MONSTER:'@',"abbot",(33,12) +MONSTER:('@',"abbot"),(32,07) +MONSTER:('@',"abbot"),(32,08) +MONSTER:('@',"abbot"),(32,11) +MONSTER:('@',"abbot"),(32,12) +MONSTER:('@',"abbot"),(33,07) +MONSTER:('@',"abbot"),(33,08) +MONSTER:('@',"abbot"),(33,11) +MONSTER:('@',"abbot"),(33,12) # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Random traps @@ -85,18 +85,18 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Monsters on siege duty. -MONSTER: 'E',"earth elemental",(37,01) -MONSTER: 'E',"earth elemental",(37,18) -MONSTER: 'E',"earth elemental",(03,03) -MONSTER: 'E',"earth elemental",(65,04) -MONSTER: 'E',"earth elemental",(12,11) -MONSTER: 'E',"earth elemental",(60,12) -MONSTER: 'E',"earth elemental",(14,08) -MONSTER: 'E',"earth elemental",(55,00) -MONSTER: 'X',"xorn",(18,18) -MONSTER: 'X',"xorn",(59,10) -MONSTER: 'X',"xorn",(13,09) -MONSTER: 'X',"xorn",(01,17) +MONSTER: ('E',"earth elemental"),(37,01) +MONSTER: ('E',"earth elemental"),(37,18) +MONSTER: ('E',"earth elemental"),(03,03) +MONSTER: ('E',"earth elemental"),(65,04) +MONSTER: ('E',"earth elemental"),(12,11) +MONSTER: ('E',"earth elemental"),(60,12) +MONSTER: ('E',"earth elemental"),(14,08) +MONSTER: ('E',"earth elemental"),(55,00) +MONSTER: ('X',"xorn"),(18,18) +MONSTER: ('X',"xorn"),(59,10) +MONSTER: ('X',"xorn"),(13,09) +MONSTER: ('X',"xorn"),(01,17) # # The "locate" level for the quest. @@ -133,7 +133,9 @@ MAP ------------------------------------------ ------ ENDMAP # Random Monsters -RANDOM_MONSTERS: 'E', 'X' +$monster = monster: { 'E', 'X' } +SHUFFLE: $monster + # Dungeon Description REGION:(00,00,75,20),lit,"ordinary" # Stairs @@ -142,21 +144,21 @@ STAIR:random,down # Non diggable walls NON_DIGGABLE:(00,00,75,20) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -165,29 +167,29 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random # # The "goal" level for the quest. @@ -198,7 +200,7 @@ MONSTER: 'X',"xorn",random # MAZE: "Mon-goal", ' ' -INIT_MAP: 'L' , '.' , false , false , unlit , false +INIT_MAP: mines, 'L' , '.' , false , false , unlit , false GEOMETRY:center,center MAP .L......L.LLL.......LL.... @@ -214,26 +216,28 @@ LL........................ .........LLL.........L.... ENDMAP # Dungeon Description -RANDOM_PLACES:(14,04),(13,07) +$place = { (14,04),(13,07) } +SHUFFLE: $place + REGION:(00,00,25,10),unlit,"ordinary" # Stairs STAIR:(20,05),up # Objects -OBJECT:'(',"lenses",place[0],blessed,0,"The Eyes of the Overworld" -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('(',"lenses"),$place[0],blessed,0,name:"The Eyes of the Overworld" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:"fire",random TRAP:"fire",random @@ -242,26 +246,26 @@ TRAP:"fire",random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'@',"Master Kaen",place[0] -ALTAR:place[0],noalign,altar -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'E',"earth elemental",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random -MONSTER: 'X',"xorn",random +MONSTER:('@',"Master Kaen"),$place[0] +ALTAR:$place[0],noalign,altar +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('E',"earth elemental"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random +MONSTER: ('X',"xorn"),random # # The "fill" levels for the quest. @@ -274,82 +278,98 @@ MONSTER: 'X',"xorn",random LEVEL: "Mon-fila" # Random Monsters -RANDOM_MONSTERS: 'E', 'X' +$monster = monster: { 'E', 'X' } +SHUFFLE: $monster + # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'E', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: 'E', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random,random,random -MONSTER: 'E', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random,random + MONSTER: 'E', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'X', "xorn", random -MONSTER: 'E', "earth elemental", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: ('X', "xorn"), random + MONSTER: ('E', "earth elemental"), random +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'E', random, random, hostile -MONSTER: 'E', "earth elemental", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random + MONSTER: 'E', random, hostile + MONSTER: ('E', "earth elemental"), random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'X', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + MONSTER: 'X', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'E', "earth elemental", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + MONSTER: ('E', "earth elemental"), random +} RANDOM_CORRIDORS LEVEL: "Mon-filb" # Random Monsters -RANDOM_MONSTERS: 'E', 'X' +$monster = monster: { 'E', 'X' } +SHUFFLE: $monster + # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'X', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: 'X', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random,random,random -MONSTER: 'X', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random,random + MONSTER: 'X', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'E', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: 'E', random, hostile +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'E', random, random, hostile -MONSTER: 'E', "earth elemental", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random + MONSTER: 'E', random, hostile + MONSTER: ('E', "earth elemental"), random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'X', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + MONSTER: 'X', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'E', "earth elemental", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + MONSTER: ('E', "earth elemental"), random +} RANDOM_CORRIDORS diff --git a/dat/Priest.des b/dat/Priest.des index ea4aef3c5..21fd71600 100644 --- a/dat/Priest.des +++ b/dat/Priest.des @@ -64,18 +64,18 @@ DOOR:closed,(52,14) # Unattended Altar - unaligned due to conflict - player must align it. ALTAR:(28,09),noalign,altar # High Priest -MONSTER:'@',"Arch Priest",(28,10) +MONSTER:('@',"Arch Priest"),(28,10) # The treasure of High Priest -OBJECT:'(',"chest",(27,10) +OBJECT:('(',"chest"),(27,10) # knight guards for the audience chamber -MONSTER:'@',"acolyte",(32,07) -MONSTER:'@',"acolyte",(32,08) -MONSTER:'@',"acolyte",(32,11) -MONSTER:'@',"acolyte",(32,12) -MONSTER:'@',"acolyte",(33,07) -MONSTER:'@',"acolyte",(33,08) -MONSTER:'@',"acolyte",(33,11) -MONSTER:'@',"acolyte",(33,12) +MONSTER:('@',"acolyte"),(32,07) +MONSTER:('@',"acolyte"),(32,08) +MONSTER:('@',"acolyte"),(32,11) +MONSTER:('@',"acolyte"),(32,12) +MONSTER:('@',"acolyte"),(33,07) +MONSTER:('@',"acolyte"),(33,08) +MONSTER:('@',"acolyte"),(33,11) +MONSTER:('@',"acolyte"),(33,12) # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Random traps @@ -86,18 +86,18 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Monsters on siege duty. -MONSTER: 'Z',"human zombie",(37,01) -MONSTER: 'Z',"human zombie",(37,18) -MONSTER: 'Z',"human zombie",(03,03) -MONSTER: 'Z',"human zombie",(65,04) -MONSTER: 'Z',"human zombie",(12,11) -MONSTER: 'Z',"human zombie",(60,12) -MONSTER: 'Z',"human zombie",(14,08) -MONSTER: 'Z',"human zombie",(55,00) -MONSTER: 'Z',"human zombie",(18,18) -MONSTER: 'Z',"human zombie",(59,10) -MONSTER: 'Z',"human zombie",(13,09) -MONSTER: 'Z',"human zombie",(01,17) +MONSTER: ('Z',"human zombie"),(37,01) +MONSTER: ('Z',"human zombie"),(37,18) +MONSTER: ('Z',"human zombie"),(03,03) +MONSTER: ('Z',"human zombie"),(65,04) +MONSTER: ('Z',"human zombie"),(12,11) +MONSTER: ('Z',"human zombie"),(60,12) +MONSTER: ('Z',"human zombie"),(14,08) +MONSTER: ('Z',"human zombie"),(55,00) +MONSTER: ('Z',"human zombie"),(18,18) +MONSTER: ('Z',"human zombie"),(59,10) +MONSTER: ('Z',"human zombie"),(13,09) +MONSTER: ('Z',"human zombie"),(01,17) # # The "locate" level for the quest. @@ -109,7 +109,7 @@ MONSTER: 'Z',"human zombie",(01,17) MAZE: "Pri-loca",' ' FLAGS: hardfloor # This is a kludge to init the level as a lit field. -INIT_MAP: '.' , '.' , false , false , lit , false +INIT_MAP: mines, '.' , '.' , false , false , lit , false GEOMETRY:center,center MAP ........................................ @@ -132,10 +132,10 @@ REGION:(00,00,09,13),unlit,"morgue" REGION:(09,00,30,01),unlit,"morgue" REGION:(09,12,30,13),unlit,"morgue" REGION:(31,00,39,13),unlit,"morgue" -REGION:(11,03,29,10),lit,"temple",filled,true +REGION:(11,03,29,10),lit,"temple",filled,irregular # The altar inside the temple ALTAR:(20,07),noalign,shrine -MONSTER:'@',"aligned priest",(20,07),noalign,hostile +MONSTER:('@',"aligned priest"),(20,07),noalign,hostile # Doors DOOR:locked,(10,06) DOOR:locked,(10,07) @@ -150,21 +150,21 @@ STAIR:(20,06),down # Non diggable walls NON_DIGGABLE:(10,02,30,13) # Objects (inside the antechambers). -OBJECT:random,random,(14,03) -OBJECT:random,random,(15,03) -OBJECT:random,random,(16,03) -OBJECT:random,random,(14,10) -OBJECT:random,random,(15,10) -OBJECT:random,random,(16,10) -OBJECT:random,random,(17,10) -OBJECT:random,random,(24,03) -OBJECT:random,random,(25,03) -OBJECT:random,random,(26,03) -OBJECT:random,random,(27,03) -OBJECT:random,random,(24,10) -OBJECT:random,random,(25,10) -OBJECT:random,random,(26,10) -OBJECT:random,random,(27,10) +OBJECT:random,(14,03) +OBJECT:random,(15,03) +OBJECT:random,(16,03) +OBJECT:random,(14,10) +OBJECT:random,(15,10) +OBJECT:random,(16,10) +OBJECT:random,(17,10) +OBJECT:random,(24,03) +OBJECT:random,(25,03) +OBJECT:random,(26,03) +OBJECT:random,(27,03) +OBJECT:random,(24,10) +OBJECT:random,(25,10) +OBJECT:random,(26,10) +OBJECT:random,(27,10) # Random traps TRAP:random,(15,04) TRAP:random,(25,04) @@ -183,7 +183,7 @@ TRAP:random,random # MAZE: "Pri-goal", ' ' -INIT_MAP: 'L' , '.' , false , false , unlit , false +INIT_MAP: mines, 'L' , '.' , false , false , unlit , false GEOMETRY:center,center MAP .L......L.LLL.......LL.... @@ -199,26 +199,28 @@ LL........................ .........LLL.........L.... ENDMAP # Dungeon Description -RANDOM_PLACES:(14,04),(13,07) +$place = { (14,04),(13,07) } +SHUFFLE: $place + REGION:(00,00,25,10),unlit,"ordinary" # Stairs STAIR:(20,05),up # Objects -OBJECT:'[',"helm of brilliance",place[0],blessed,0,"The Mitre of Holiness" -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('[',"helm of brilliance"),$place[0],blessed,0,name:"The Mitre of Holiness" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:"fire",random TRAP:"fire",random @@ -227,34 +229,34 @@ TRAP:"fire",random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'&',"Nalzok",place[0] -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',random,random -MONSTER:'Z',random,random -MONSTER:'W',"wraith",random -MONSTER:'W',"wraith",random -MONSTER:'W',"wraith",random -MONSTER:'W',"wraith",random -MONSTER:'W',"wraith",random -MONSTER:'W',"wraith",random -MONSTER:'W',"wraith",random -MONSTER:'W',"wraith",random -MONSTER:'W',random,random +MONSTER:('&',"Nalzok"),$place[0] +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:'Z',random +MONSTER:'Z',random +MONSTER:('W',"wraith"),random +MONSTER:('W',"wraith"),random +MONSTER:('W',"wraith"),random +MONSTER:('W',"wraith"),random +MONSTER:('W',"wraith"),random +MONSTER:('W',"wraith"),random +MONSTER:('W',"wraith"),random +MONSTER:('W',"wraith"),random +MONSTER:'W',random # # The "fill" levels for the quest. @@ -267,73 +269,85 @@ MONSTER:'W',random,random LEVEL: "Pri-fila" # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'Z', "human zombie", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: ('Z', "human zombie"), random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random,random,random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random,random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'Z', "human zombie", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: ('Z', "human zombie"), random +} -ROOM: "morgue" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random +ROOM: "morgue" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'W', "wraith", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + MONSTER: ('W', "wraith"), random +} -ROOM: "morgue" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random +ROOM: "morgue" , random, random, random, random { + OBJECT: random, random + TRAP: random, random +} RANDOM_CORRIDORS LEVEL: "Pri-filb" # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'Z', "human zombie", random -MONSTER: 'W', "wraith", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: ('Z', "human zombie"), random + MONSTER: ('W', "wraith"), random +} -ROOM: "morgue" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random,random,random +ROOM: "morgue" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + OBJECT: random,random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'Z', "human zombie", random -MONSTER: 'W', "wraith", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: ('Z', "human zombie"), random + MONSTER: ('W', "wraith"), random +} -ROOM: "morgue" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random +ROOM: "morgue" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + OBJECT: random, random + TRAP: random, random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'Z', "human zombie", random -MONSTER: 'W', "wraith", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + MONSTER: ('Z', "human zombie"), random + MONSTER: ('W', "wraith"), random +} -ROOM: "morgue" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random +ROOM: "morgue" , random, random, random, random { + OBJECT: random, random + TRAP: random, random +} RANDOM_CORRIDORS diff --git a/dat/Ranger.des b/dat/Ranger.des index d36559cb6..f44c28779 100644 --- a/dat/Ranger.des +++ b/dat/Ranger.des @@ -12,7 +12,7 @@ # MAZE: "Ran-strt",'.' FLAGS: noteleport,hardfloor,arboreal -INIT_MAP:'.','.',true,true,lit,false +INIT_MAP:mines,'.','.',true,true,lit,false GEOMETRY:left,center #1234567890123456789012345678901234567890123456789012345678901234567890 MAP @@ -45,18 +45,18 @@ STAIR:(10,10),down # Portal arrival point; just about anywhere on the right hand side of the map BRANCH:levregion(51,2,77,18),(0,0,40,20) # Orion -MONSTER:'@',"Orion",(20,10) +MONSTER:('@',"Orion"),(20,10) # The treasure of Orion -OBJECT:'(',"chest",(20,10) +OBJECT:('(',"chest"),(20,10) # Guards for the audience chamber -MONSTER:'@',"hunter",(19,09) -MONSTER:'@',"hunter",(20,09) -MONSTER:'@',"hunter",(21,09) -MONSTER:'@',"hunter",(19,10) -MONSTER:'@',"hunter",(21,10) -MONSTER:'@',"hunter",(19,11) -MONSTER:'@',"hunter",(20,11) -MONSTER:'@',"hunter",(21,11) +MONSTER:('@',"hunter"),(19,09) +MONSTER:('@',"hunter"),(20,09) +MONSTER:('@',"hunter"),(21,09) +MONSTER:('@',"hunter"),(19,10) +MONSTER:('@',"hunter"),(21,10) +MONSTER:('@',"hunter"),(19,11) +MONSTER:('@',"hunter"),(20,11) +MONSTER:('@',"hunter"),(21,11) # Non diggable walls NON_DIGGABLE:(00,00,40,20) # Traps @@ -67,33 +67,33 @@ TRAP:"spiked pit",random TRAP:"bear",random TRAP:"bear",random # Monsters on siege duty. -MONSTER: 'H',"minotaur",(33,09),hostile,asleep -MONSTER: 'C',"forest centaur",(19,03),hostile -MONSTER: 'C',"forest centaur",(19,04),hostile -MONSTER: 'C',"forest centaur",(19,05),hostile -MONSTER: 'C',"forest centaur",(21,03),hostile -MONSTER: 'C',"forest centaur",(21,04),hostile -MONSTER: 'C',"forest centaur",(21,05),hostile -MONSTER: 'C',"forest centaur",(01,09),hostile -MONSTER: 'C',"forest centaur",(02,09),hostile -MONSTER: 'C',"forest centaur",(03,09),hostile -MONSTER: 'C',"forest centaur",(01,11),hostile -MONSTER: 'C',"forest centaur",(02,11),hostile -MONSTER: 'C',"forest centaur",(03,11),hostile -MONSTER: 'C',"forest centaur",(19,15),hostile -MONSTER: 'C',"forest centaur",(19,16),hostile -MONSTER: 'C',"forest centaur",(19,17),hostile -MONSTER: 'C',"forest centaur",(21,15),hostile -MONSTER: 'C',"forest centaur",(21,16),hostile -MONSTER: 'C',"forest centaur",(21,17),hostile -MONSTER: 'C',"plains centaur",random,hostile -MONSTER: 'C',"plains centaur",random,hostile -MONSTER: 'C',"plains centaur",random,hostile -MONSTER: 'C',"plains centaur",random,hostile -MONSTER: 'C',"plains centaur",random,hostile -MONSTER: 'C',"plains centaur",random,hostile -MONSTER: 's',"scorpion",random,hostile -MONSTER: 's',"scorpion",random,hostile +MONSTER: ('H',"minotaur"),(33,09),hostile,asleep +MONSTER: ('C',"forest centaur"),(19,03),hostile +MONSTER: ('C',"forest centaur"),(19,04),hostile +MONSTER: ('C',"forest centaur"),(19,05),hostile +MONSTER: ('C',"forest centaur"),(21,03),hostile +MONSTER: ('C',"forest centaur"),(21,04),hostile +MONSTER: ('C',"forest centaur"),(21,05),hostile +MONSTER: ('C',"forest centaur"),(01,09),hostile +MONSTER: ('C',"forest centaur"),(02,09),hostile +MONSTER: ('C',"forest centaur"),(03,09),hostile +MONSTER: ('C',"forest centaur"),(01,11),hostile +MONSTER: ('C',"forest centaur"),(02,11),hostile +MONSTER: ('C',"forest centaur"),(03,11),hostile +MONSTER: ('C',"forest centaur"),(19,15),hostile +MONSTER: ('C',"forest centaur"),(19,16),hostile +MONSTER: ('C',"forest centaur"),(19,17),hostile +MONSTER: ('C',"forest centaur"),(21,15),hostile +MONSTER: ('C',"forest centaur"),(21,16),hostile +MONSTER: ('C',"forest centaur"),(21,17),hostile +MONSTER: ('C',"plains centaur"),random,hostile +MONSTER: ('C',"plains centaur"),random,hostile +MONSTER: ('C',"plains centaur"),random,hostile +MONSTER: ('C',"plains centaur"),random,hostile +MONSTER: ('C',"plains centaur"),random,hostile +MONSTER: ('C',"plains centaur"),random,hostile +MONSTER: ('s',"scorpion"),random,hostile +MONSTER: ('s',"scorpion"),random,hostile # @@ -137,14 +137,14 @@ STAIR:(27,18),down # Non diggable walls NON_DIGGABLE:(00,00,54,19) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:"spiked pit",random TRAP:"spiked pit",random @@ -153,29 +153,29 @@ TRAP:"teleport",random TRAP:"arrow",random TRAP:"arrow",random # Random monsters. -MONSTER:'q',"wumpus",(27,18),hostile,asleep -MONSTER:'B',"giant bat",random,hostile -MONSTER:'B',"giant bat",random,hostile -MONSTER:'B',"giant bat",random,hostile -MONSTER:'B',"giant bat",random,hostile -MONSTER:'C',"forest centaur",random,hostile -MONSTER:'C',"forest centaur",random,hostile -MONSTER:'C',"forest centaur",random,hostile -MONSTER:'C',"forest centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'s',"scorpion",random,hostile -MONSTER:'s',"scorpion",random,hostile -MONSTER:'s',"scorpion",random,hostile -MONSTER:'s',"scorpion",random,hostile -MONSTER:'s',random,random,hostile -MONSTER:'s',random,random,hostile +MONSTER:('q',"wumpus"),(27,18),hostile,asleep +MONSTER:('B',"giant bat"),random,hostile +MONSTER:('B',"giant bat"),random,hostile +MONSTER:('B',"giant bat"),random,hostile +MONSTER:('B',"giant bat"),random,hostile +MONSTER:('C',"forest centaur"),random,hostile +MONSTER:('C',"forest centaur"),random,hostile +MONSTER:('C',"forest centaur"),random,hostile +MONSTER:('C',"forest centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:('s',"scorpion"),random,hostile +MONSTER:('s',"scorpion"),random,hostile +MONSTER:('s',"scorpion"),random,hostile +MONSTER:('s',"scorpion"),random,hostile +MONSTER:'s',random,hostile +MONSTER:'s',random,hostile # @@ -217,21 +217,21 @@ STAIR:(19,10),up # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Objects -OBJECT:')',"bow",(37,10),blessed,0,"The Longbow of Diana" -OBJECT:'(',"chest",(37,10) -OBJECT:random,random,(36,09) -OBJECT:random,random,(36,10) -OBJECT:random,random,(36,11) -OBJECT:random,random,(37,09) -OBJECT:random,random,(37,11) -OBJECT:random,random,(38,09) -OBJECT:random,random,(38,10) -OBJECT:random,random,(38,11) -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:(')',"bow"),(37,10),blessed,0,name:"The Longbow of Diana" +OBJECT:('(',"chest"),(37,10) +OBJECT:random,(36,09) +OBJECT:random,(36,10) +OBJECT:random,(36,11) +OBJECT:random,(37,09) +OBJECT:random,(37,11) +OBJECT:random,(38,09) +OBJECT:random,(38,10) +OBJECT:random,(38,11) +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -255,34 +255,34 @@ DOOR:closed,(51,10) DOOR:locked,(53,08) DOOR:closed,(65,05) # Random monsters. -MONSTER:'s',"Scorpius",(37,10),hostile -MONSTER:'C',"forest centaur",(36,09),hostile -MONSTER:'C',"forest centaur",(36,10),hostile -MONSTER:'C',"forest centaur",(36,11),hostile -MONSTER:'C',"forest centaur",(37,09),hostile -MONSTER:'C',"forest centaur",(37,11),hostile -MONSTER:'C',"forest centaur",(38,09),hostile -MONSTER:'C',"mountain centaur",(38,10),hostile -MONSTER:'C',"mountain centaur",(38,11),hostile -MONSTER:'C',"mountain centaur",(02,02),hostile -MONSTER:'C',"mountain centaur",(71,02),hostile -MONSTER:'C',"mountain centaur",(02,16),hostile -MONSTER:'C',"mountain centaur",(71,16),hostile -MONSTER:'C',"forest centaur",random,hostile -MONSTER:'C',"forest centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'C',"mountain centaur",random,hostile -MONSTER:'C',random,random,hostile -MONSTER:'C',random,random,hostile -MONSTER:'s',"scorpion",(03,02),hostile -MONSTER:'s',"scorpion",(72,02),hostile -MONSTER:'s',"scorpion",(03,17),hostile -MONSTER:'s',"scorpion",(72,17),hostile -MONSTER:'s',"scorpion",(41,10),hostile -MONSTER:'s',"scorpion",(33,09),hostile -MONSTER:'s',"scorpion",random,hostile -MONSTER:'s',"scorpion",random,hostile -MONSTER:'s',random,random,hostile +MONSTER:('s',"Scorpius"),(37,10),hostile +MONSTER:('C',"forest centaur"),(36,09),hostile +MONSTER:('C',"forest centaur"),(36,10),hostile +MONSTER:('C',"forest centaur"),(36,11),hostile +MONSTER:('C',"forest centaur"),(37,09),hostile +MONSTER:('C',"forest centaur"),(37,11),hostile +MONSTER:('C',"forest centaur"),(38,09),hostile +MONSTER:('C',"mountain centaur"),(38,10),hostile +MONSTER:('C',"mountain centaur"),(38,11),hostile +MONSTER:('C',"mountain centaur"),(02,02),hostile +MONSTER:('C',"mountain centaur"),(71,02),hostile +MONSTER:('C',"mountain centaur"),(02,16),hostile +MONSTER:('C',"mountain centaur"),(71,16),hostile +MONSTER:('C',"forest centaur"),random,hostile +MONSTER:('C',"forest centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:('C',"mountain centaur"),random,hostile +MONSTER:'C',random,hostile +MONSTER:'C',random,hostile +MONSTER:('s',"scorpion"),(03,02),hostile +MONSTER:('s',"scorpion"),(72,02),hostile +MONSTER:('s',"scorpion"),(03,17),hostile +MONSTER:('s',"scorpion"),(72,17),hostile +MONSTER:('s',"scorpion"),(41,10),hostile +MONSTER:('s',"scorpion"),(33,09),hostile +MONSTER:('s',"scorpion"),random,hostile +MONSTER:('s',"scorpion"),random,hostile +MONSTER:'s',random,hostile WALLIFY @@ -296,62 +296,62 @@ WALLIFY # MAZE: "Ran-fila" , ' ' -INIT_MAP: '.' , 'T', true, true, random, true +INIT_MAP: mines, '.' , 'T', true, true, random, true NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # TRAP: random, random TRAP: random, random TRAP: random, random TRAP: random, random # -MONSTER: 'C', "mountain centaur", random, hostile -MONSTER: 'C', "mountain centaur", random, hostile -MONSTER: 'C', "forest centaur", random, hostile -MONSTER: 'C', "forest centaur", random, hostile -MONSTER: 'C', "forest centaur", random, hostile -MONSTER: 'C', random, random, hostile -MONSTER: 's', "scorpion", random, hostile +MONSTER: ('C', "mountain centaur"), random, hostile +MONSTER: ('C', "mountain centaur"), random, hostile +MONSTER: ('C', "forest centaur"), random, hostile +MONSTER: ('C', "forest centaur"), random, hostile +MONSTER: ('C', "forest centaur"), random, hostile +MONSTER: 'C', random, hostile +MONSTER: ('s', "scorpion"), random, hostile MAZE: "Ran-filb" , ' ' -INIT_MAP: '.' , ' ', true, true, random, true +INIT_MAP: mines, '.' , ' ', true, true, random, true NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # TRAP: random, random TRAP: random, random TRAP: random, random TRAP: random, random # -MONSTER: 'C', "mountain centaur", random, hostile -MONSTER: 'C', "mountain centaur", random, hostile -MONSTER: 'C', "mountain centaur", random, hostile -MONSTER: 'C', "mountain centaur", random, hostile -MONSTER: 'C', random, random, hostile -MONSTER: 's', "scorpion", random, hostile -MONSTER: 's', "scorpion", random, hostile +MONSTER: ('C', "mountain centaur"), random, hostile +MONSTER: ('C', "mountain centaur"), random, hostile +MONSTER: ('C', "mountain centaur"), random, hostile +MONSTER: ('C', "mountain centaur"), random, hostile +MONSTER: 'C', random, hostile +MONSTER: ('s', "scorpion"), random, hostile +MONSTER: ('s', "scorpion"), random, hostile diff --git a/dat/Rogue.des b/dat/Rogue.des index 2d2c6a202..38921c371 100644 --- a/dat/Rogue.des +++ b/dat/Rogue.des @@ -41,11 +41,13 @@ ENDMAP #REGION:(00,00,75,20),lit,"ordinary" # The down stairs is at one of the 4 "exits". The others are mimics, # mimicing stairwells. -RANDOM_PLACES: (33,0), (0,12), (25,20), (75,05) -STAIR:place[0],down -MONSTER:'m',"giant mimic", place[1], m_feature "staircase down" -MONSTER:'m',"large mimic", place[2], m_feature "staircase down" -MONSTER:'m',"small mimic", place[3], m_feature "staircase down" +$place = { (33,0), (0,12), (25,20), (75,05) } +SHUFFLE: $place + +STAIR:$place[0],down +MONSTER:('m',"giant mimic"), $place[1], m_feature "staircase down" +MONSTER:('m',"large mimic"), $place[2], m_feature "staircase down" +MONSTER:('m',"small mimic"), $place[3], m_feature "staircase down" # Portal arrival point BRANCH:(19,09,19,09),(0,0,0,0) # Doors (secret) @@ -98,21 +100,21 @@ DOOR: closed, ( 6,18) DOOR: closed, (65,18) DOOR: closed, (68,18) # Master of Thieves -MONSTER:'@',"Master of Thieves",(36,11) +MONSTER:('@',"Master of Thieves"),(36,11) # The treasure of Master of Thieves -OBJECT:'(',"chest",(36,11) +OBJECT:('(',"chest"),(36,11) # thug guards, room #1 -MONSTER:'@',"thug",(28,10) -MONSTER:'@',"thug",(29,11) -MONSTER:'@',"thug",(30,09) -MONSTER:'@',"thug",(31,07) +MONSTER:('@',"thug"),(28,10) +MONSTER:('@',"thug"),(29,11) +MONSTER:('@',"thug"),(30,09) +MONSTER:('@',"thug"),(31,07) # thug guards, room #2 -MONSTER:'@',"thug",(31,13) -MONSTER:'@',"thug",(33,14) -MONSTER:'@',"thug",(30,15) +MONSTER:('@',"thug"),(31,13) +MONSTER:('@',"thug"),(33,14) +MONSTER:('@',"thug"),(30,15) #thug guards, room #3 -MONSTER:'@',"thug",(35,09) -MONSTER:'@',"thug",(36,13) +MONSTER:('@',"thug"),(35,09) +MONSTER:('@',"thug"),(36,13) # Non diggable walls NON_DIGGABLE:(00,00,75,20) # Random traps @@ -136,37 +138,37 @@ TRAP:random,random # Monsters to get in the way. # # West exit -MONSTER: 'l',"leprechaun",(01,12),hostile -MONSTER: 'n',"water nymph",(02,12),hostile +MONSTER: ('l',"leprechaun"),(01,12),hostile +MONSTER: ('n',"water nymph"),(02,12),hostile # North exit -MONSTER: 'n',"water nymph",(33,01),hostile -MONSTER: 'l',"leprechaun",(33,02),hostile +MONSTER: ('n',"water nymph"),(33,01),hostile +MONSTER: ('l',"leprechaun"),(33,02),hostile # East exit -MONSTER: 'n',"water nymph",(74,05),hostile -MONSTER: 'l',"leprechaun",(74,04),hostile +MONSTER: ('n',"water nymph"),(74,05),hostile +MONSTER: ('l',"leprechaun"),(74,04),hostile # South exit -MONSTER: 'l',"leprechaun",(25,19),hostile -MONSTER: 'n',"water nymph",(25,18),hostile +MONSTER: ('l',"leprechaun"),(25,19),hostile +MONSTER: ('n',"water nymph"),(25,18),hostile # Wandering the streets. What I'd really like for this is a random # location, but make sure we're on a given type, e.g. street (if they # existed, of course). -MONSTER: 'n',"water nymph",(07,05),hostile -MONSTER: 'l',"leprechaun",(28,06),hostile -MONSTER: 'n',"water nymph",(38,07),hostile -MONSTER: 'l',"leprechaun",(45,01),hostile -MONSTER: 'n',"water nymph",(59,07),hostile -MONSTER: 'l',"leprechaun",(62,14),hostile -MONSTER: 'n',"water nymph",(71,14),hostile -MONSTER: 'l',"leprechaun",(39,13),hostile -MONSTER: 'n',"water nymph",(18,14),hostile -MONSTER: ':',"chameleon",(19,08),hostile -MONSTER: ':',"chameleon",(22,08),hostile -MONSTER: ':',"chameleon",(16,08),hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile +MONSTER: ('n',"water nymph"),(07,05),hostile +MONSTER: ('l',"leprechaun"),(28,06),hostile +MONSTER: ('n',"water nymph"),(38,07),hostile +MONSTER: ('l',"leprechaun"),(45,01),hostile +MONSTER: ('n',"water nymph"),(59,07),hostile +MONSTER: ('l',"leprechaun"),(62,14),hostile +MONSTER: ('n',"water nymph"),(71,14),hostile +MONSTER: ('l',"leprechaun"),(39,13),hostile +MONSTER: ('n',"water nymph"),(18,14),hostile +MONSTER: (':',"chameleon"),(19,08),hostile +MONSTER: (':',"chameleon"),(22,08),hostile +MONSTER: (':',"chameleon"),(16,08),hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile # # The "locate" level for the quest. @@ -212,21 +214,21 @@ STAIR:random,down # Non diggable walls NON_DIGGABLE:(00,00,75,20) # Objects -OBJECT:'?',"teleportation",(11,18),cursed,0 -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('?',"teleportation"),(11,18),cursed,0 +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -235,39 +237,39 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',random,random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',random,random,hostile -MONSTER:'N',random,random,hostile -MONSTER:'N',random,random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:'l',random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:'N',random,hostile +MONSTER:'N',random,hostile +MONSTER:'N',random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile # # The "goal" level for the quest. Teleportation and digging are @@ -315,21 +317,21 @@ NON_DIGGABLE:(00,00,75,20) # One trap to keep the gnomes at bay. TRAP:"spiked pit",(37,07) # Objects -OBJECT:'(',"skeleton key",(38,10),blessed,0,"The Master Key of Thievery" -OBJECT:'%',"tin",(26,12),"chameleon",0 -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('(',"skeleton key"),(38,10),blessed,0,name:"The Master Key of Thievery" +OBJECT:('%',"tin"),(26,12),montype:"chameleon" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -343,45 +345,45 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'@',"Master Assassin",(38,10),hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',"leprechaun",random,hostile -MONSTER:'l',random,random,hostile -MONSTER:'l',random,random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',"guardian naga",random,hostile -MONSTER:'N',random,random,hostile -MONSTER:'N',random,random,hostile -MONSTER:'N',random,random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER: ':',"chameleon",random,hostile -MONSTER:';',"shark",(51,14),hostile -MONSTER:';',"shark",(53,09),hostile -MONSTER:';',"shark",(55,15),hostile -MONSTER:';',"shark",(58,10),hostile +MONSTER:('@',"Master Assassin"),(38,10),hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:('l',"leprechaun"),random,hostile +MONSTER:'l',random,hostile +MONSTER:'l',random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:('N',"guardian naga"),random,hostile +MONSTER:'N',random,hostile +MONSTER:'N',random,hostile +MONSTER:'N',random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER: (':',"chameleon"),random,hostile +MONSTER:(';',"shark"),(51,14),hostile +MONSTER:(';',"shark"),(53,09),hostile +MONSTER:(';',"shark"),(55,15),hostile +MONSTER:(';',"shark"),(58,10),hostile # # The "fill" level for the quest. @@ -391,45 +393,51 @@ MONSTER:';',"shark",(58,10),hostile # LEVEL: "Rog-fila" # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'l', "leprechaun", random, hostile +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: ('l', "leprechaun"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random,random,random -MONSTER: 'l', "leprechaun", random, hostile -MONSTER: 'N', "guardian naga", random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random,random + MONSTER: ('l', "leprechaun"), random, hostile + MONSTER: ('N', "guardian naga"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'n', "water nymph", random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: ('n', "water nymph"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random -TRAP: random, random -MONSTER: 'l', random, random, hostile -MONSTER: 'N', "guardian naga", random, hostile +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random + TRAP: random, random + MONSTER: 'l', random, hostile + MONSTER: ('N', "guardian naga"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -TRAP: random, random -MONSTER: 'l', "leprechaun", random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + TRAP: random, random + MONSTER: ('l', "leprechaun"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -TRAP: random, random -MONSTER: 'l', "leprechaun", random, hostile -MONSTER: 'n', "water nymph", random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + TRAP: random, random + MONSTER: ('l', "leprechaun"), random, hostile + MONSTER: ('n', "water nymph"), random, hostile +} RANDOM_CORRIDORS @@ -438,44 +446,50 @@ RANDOM_CORRIDORS # LEVEL: "Rog-filb" # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'l', "leprechaun", random, hostile +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: ('l', "leprechaun"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random,random,random -MONSTER: 'l', "leprechaun", random, hostile -MONSTER: 'N', "guardian naga", random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random,random + MONSTER: ('l', "leprechaun"), random, hostile + MONSTER: ('N', "guardian naga"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'n', "water nymph", random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: ('n', "water nymph"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random -TRAP: random, random -MONSTER: 'l', random, random, hostile -MONSTER: 'N', "guardian naga", random, hostile +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random + TRAP: random, random + MONSTER: 'l', random, hostile + MONSTER: ('N', "guardian naga"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -TRAP: random, random -MONSTER: 'l', "leprechaun", random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + TRAP: random, random + MONSTER: ('l', "leprechaun"), random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -TRAP: random, random -MONSTER: 'l', "leprechaun", random, hostile -MONSTER: 'n', "water nymph", random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + TRAP: random, random + MONSTER: ('l', "leprechaun"), random, hostile + MONSTER: ('n', "water nymph"), random, hostile +} RANDOM_CORRIDORS diff --git a/dat/Samurai.des b/dat/Samurai.des index 565a2ed67..6dd53ac4f 100644 --- a/dat/Samurai.des +++ b/dat/Samurai.des @@ -54,18 +54,18 @@ DOOR:locked,(39,08) DOOR:closed,(50,04) DOOR:closed,(50,06) # Lord Sato -MONSTER:'@',"Lord Sato",(20,04) +MONSTER:('@',"Lord Sato"),(20,04) # The treasure of Lord Sato -OBJECT:'(',"chest",(20,04) +OBJECT:('(',"chest"),(20,04) # roshi guards for the audience chamber -MONSTER:'@',"roshi",(18,04) -MONSTER:'@',"roshi",(18,05) -MONSTER:'@',"roshi",(18,06) -MONSTER:'@',"roshi",(18,07) -MONSTER:'@',"roshi",(26,04) -MONSTER:'@',"roshi",(26,05) -MONSTER:'@',"roshi",(26,06) -MONSTER:'@',"roshi",(26,07) +MONSTER:('@',"roshi"),(18,04) +MONSTER:('@',"roshi"),(18,05) +MONSTER:('@',"roshi"),(18,06) +MONSTER:('@',"roshi"),(18,07) +MONSTER:('@',"roshi"),(26,04) +MONSTER:('@',"roshi"),(26,05) +MONSTER:('@',"roshi"),(26,06) +MONSTER:('@',"roshi"),(26,07) # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Random traps @@ -76,19 +76,19 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Monsters on siege duty. -MONSTER: '@',"ninja",(64,00),hostile -MONSTER: 'd',"wolf",(65,01) -MONSTER: '@',"ninja",(67,02),hostile -MONSTER: '@',"ninja",(69,05),hostile -MONSTER: '@',"ninja",(69,06),hostile -MONSTER: 'd',"wolf",(69,07) -MONSTER: '@',"ninja",(70,06),hostile -MONSTER: '@',"ninja",(70,07),hostile -MONSTER: '@',"ninja",(72,01),hostile -MONSTER: 'd',"wolf",(75,09) -MONSTER: '@',"ninja",(73,05),hostile -MONSTER: '@',"ninja",(68,02),hostile -MONSTER:'E',"stalker",random +MONSTER: ('@',"ninja"),(64,00),hostile +MONSTER: ('d',"wolf"),(65,01) +MONSTER: ('@',"ninja"),(67,02),hostile +MONSTER: ('@',"ninja"),(69,05),hostile +MONSTER: ('@',"ninja"),(69,06),hostile +MONSTER: ('d',"wolf"),(69,07) +MONSTER: ('@',"ninja"),(70,06),hostile +MONSTER: ('@',"ninja"),(70,07),hostile +MONSTER: ('@',"ninja"),(72,01),hostile +MONSTER: ('d',"wolf"),(75,09) +MONSTER: ('@',"ninja"),(73,05),hostile +MONSTER: ('@',"ninja"),(68,02),hostile +MONSTER:('E',"stalker"),random # # The "locate" level for the quest. @@ -155,41 +155,41 @@ STAIR:(25,14),down # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Objects -OBJECT:'*',random,(25,05) -OBJECT:'*',random,(26,05) -OBJECT:'*',random,(27,05) -OBJECT:'*',random,(28,05) -OBJECT:'*',random,(25,06) -OBJECT:'*',random,(26,06) -OBJECT:'*',random,(27,06) -OBJECT:'*',random,(28,06) +OBJECT:'*',(25,05) +OBJECT:'*',(26,05) +OBJECT:'*',(27,05) +OBJECT:'*',(28,05) +OBJECT:'*',(25,06) +OBJECT:'*',(26,06) +OBJECT:'*',(27,06) +OBJECT:'*',(28,06) # -OBJECT:'[',random,(40,05) -OBJECT:'[',random,(41,05) -OBJECT:'[',random,(42,05) -OBJECT:'[',random,(43,05) -OBJECT:'[',random,(40,06) -OBJECT:'[',random,(41,06) -OBJECT:'[',random,(42,06) -OBJECT:'[',random,(43,06) +OBJECT:'[',(40,05) +OBJECT:'[',(41,05) +OBJECT:'[',(42,05) +OBJECT:'[',(43,05) +OBJECT:'[',(40,06) +OBJECT:'[',(41,06) +OBJECT:'[',(42,06) +OBJECT:'[',(43,06) # -OBJECT:')',random,(27,13) -OBJECT:')',random,(28,13) -OBJECT:')',random,(29,13) -OBJECT:')',random,(30,13) -OBJECT:')',random,(27,14) -OBJECT:')',random,(28,14) -OBJECT:')',random,(29,14) -OBJECT:')',random,(30,14) +OBJECT:')',(27,13) +OBJECT:')',(28,13) +OBJECT:')',(29,13) +OBJECT:')',(30,13) +OBJECT:')',(27,14) +OBJECT:')',(28,14) +OBJECT:')',(29,14) +OBJECT:')',(30,14) # -OBJECT:'(',random,(37,13) -OBJECT:'(',random,(38,13) -OBJECT:'(',random,(39,13) -OBJECT:'(',random,(40,13) -OBJECT:'(',random,(37,14) -OBJECT:'(',random,(38,14) -OBJECT:'(',random,(39,14) -OBJECT:'(',random,(40,14) +OBJECT:'(',(37,13) +OBJECT:'(',(38,13) +OBJECT:'(',(39,13) +OBJECT:'(',(40,13) +OBJECT:'(',(37,14) +OBJECT:'(',(38,14) +OBJECT:'(',(39,14) +OBJECT:'(',(40,14) # Random traps TRAP:random,random TRAP:random,random @@ -198,40 +198,40 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'@',"ninja",(15,05),hostile -MONSTER:'@',"ninja",(16,05),hostile -MONSTER:'d',"wolf",(17,05) -MONSTER:'d',"wolf",(18,05) -MONSTER:'@',"ninja",(19,05),hostile -MONSTER:'d',"wolf",(15,14) -MONSTER:'d',"wolf",(16,14) -MONSTER:'@',"ninja",(17,14),hostile -MONSTER:'@',"ninja",(18,14),hostile -MONSTER:'d',"wolf",(56,05) -MONSTER:'@',"ninja",(57,05),hostile -MONSTER:'d',"wolf",(58,05) -MONSTER:'d',"wolf",(59,05) -MONSTER:'@',"ninja",(56,14),hostile -MONSTER:'d',"wolf",(57,14) -MONSTER:'@',"ninja",(58,14),hostile -MONSTER:'d',random,(59,14) -MONSTER:'d',"wolf",(60,14) -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random +MONSTER:('@',"ninja"),(15,05),hostile +MONSTER:('@',"ninja"),(16,05),hostile +MONSTER:('d',"wolf"),(17,05) +MONSTER:('d',"wolf"),(18,05) +MONSTER:('@',"ninja"),(19,05),hostile +MONSTER:('d',"wolf"),(15,14) +MONSTER:('d',"wolf"),(16,14) +MONSTER:('@',"ninja"),(17,14),hostile +MONSTER:('@',"ninja"),(18,14),hostile +MONSTER:('d',"wolf"),(56,05) +MONSTER:('@',"ninja"),(57,05),hostile +MONSTER:('d',"wolf"),(58,05) +MONSTER:('d',"wolf"),(59,05) +MONSTER:('@',"ninja"),(56,14),hostile +MONSTER:('d',"wolf"),(57,14) +MONSTER:('@',"ninja"),(58,14),hostile +MONSTER:'d',(59,14) +MONSTER:('d',"wolf"),(60,14) +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random # "guards" for the central courtyard. -MONSTER:'@',"samurai",(30,05),hostile -MONSTER:'@',"samurai",(31,05),hostile -MONSTER:'@',"samurai",(32,05),hostile -MONSTER:'@',"samurai",(32,14),hostile -MONSTER:'@',"samurai",(33,14),hostile -MONSTER:'@',"samurai",(34,14),hostile +MONSTER:('@',"samurai"),(30,05),hostile +MONSTER:('@',"samurai"),(31,05),hostile +MONSTER:('@',"samurai"),(32,05),hostile +MONSTER:('@',"samurai"),(32,14),hostile +MONSTER:('@',"samurai"),(33,14),hostile +MONSTER:('@',"samurai"),(34,14),hostile # # The "goal" level for the quest. @@ -267,7 +267,9 @@ MAP ....................... ENDMAP # Dungeon Description -RANDOM_PLACES:(02,11),(42,09) +$place = { (02,11),(42,09) } +SHUFFLE: $place + REGION:(00,00,44,19),unlit,"ordinary" # Doors DOOR:closed,(19,10) @@ -275,25 +277,25 @@ DOOR:closed,(22,08) DOOR:closed,(22,12) DOOR:closed,(25,10) # Stairs -STAIR:place[0],up +STAIR:$place[0],up # Non diggable walls NON_DIGGABLE:(00,00,44,19) # Objects -OBJECT:')',"tsurugi",(22,10),blessed,0,"The Tsurugi of Muramasa" -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:(')',"tsurugi"),(22,10),blessed,0,name:"The Tsurugi of Muramasa" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # TRAP:"board",(22,09) TRAP:"board",(24,10) @@ -306,32 +308,32 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'@',"Ashikaga Takauji",(22,10) -MONSTER:'@',"samurai",random,hostile -MONSTER:'@',"samurai",random,hostile -MONSTER:'@',"samurai",random,hostile -MONSTER:'@',"samurai",random,hostile -MONSTER:'@',"samurai",random,hostile -MONSTER:'@',"ninja",random,hostile -MONSTER:'@',"ninja",random,hostile -MONSTER:'@',"ninja",random,hostile -MONSTER:'@',"ninja",random,hostile -MONSTER:'@',"ninja",random,hostile -MONSTER:'d',"wolf",random -MONSTER:'d',"wolf",random -MONSTER:'d',"wolf",random -MONSTER:'d',"wolf",random -MONSTER:'d',random,random -MONSTER:'d',random,random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random -MONSTER:'E',"stalker",random +MONSTER:('@',"Ashikaga Takauji"),(22,10) +MONSTER:('@',"samurai"),random,hostile +MONSTER:('@',"samurai"),random,hostile +MONSTER:('@',"samurai"),random,hostile +MONSTER:('@',"samurai"),random,hostile +MONSTER:('@',"samurai"),random,hostile +MONSTER:('@',"ninja"),random,hostile +MONSTER:('@',"ninja"),random,hostile +MONSTER:('@',"ninja"),random,hostile +MONSTER:('@',"ninja"),random,hostile +MONSTER:('@',"ninja"),random,hostile +MONSTER:('d',"wolf"),random +MONSTER:('d',"wolf"),random +MONSTER:('d',"wolf"),random +MONSTER:('d',"wolf"),random +MONSTER:'d',random +MONSTER:'d',random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random +MONSTER:('E',"stalker"),random # @@ -344,29 +346,29 @@ MONSTER:'E',"stalker",random # MAZE: "Sam-fila", ' ' -INIT_MAP: '.' , 'P', true, true, random, true +INIT_MAP: mines, '.' , 'P', true, true, random, true NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # -MONSTER: 'd', random, random -MONSTER: 'd', "wolf", random -MONSTER: 'd', "wolf", random -MONSTER: 'd', "wolf", random -MONSTER: 'd', "wolf", random -MONSTER: 'd', "wolf", random -MONSTER: 'E', "stalker", random +MONSTER: 'd', random +MONSTER: ('d', "wolf"), random +MONSTER: ('d', "wolf"), random +MONSTER: ('d', "wolf"), random +MONSTER: ('d', "wolf"), random +MONSTER: ('d', "wolf"), random +MONSTER: ('E', "stalker"), random # TRAP: random, random TRAP: random, random @@ -403,24 +405,24 @@ DOOR:closed,(43,08) STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # -MONSTER: 'd', random, random -MONSTER: 'd', "wolf", random -MONSTER: 'd', "wolf", random -MONSTER: 'd', "wolf", random -MONSTER: 'd', "wolf", random -MONSTER: 'E', "stalker", random -MONSTER: 'E', "stalker", random -MONSTER: 'E', "stalker", random +MONSTER: 'd', random +MONSTER: ('d', "wolf"), random +MONSTER: ('d', "wolf"), random +MONSTER: ('d', "wolf"), random +MONSTER: ('d', "wolf"), random +MONSTER: ('E', "stalker"), random +MONSTER: ('E', "stalker"), random +MONSTER: ('E', "stalker"), random # TRAP: random, random TRAP: random, random diff --git a/dat/Tourist.des b/dat/Tourist.des index e9b1658e9..4f814dc34 100644 --- a/dat/Tourist.des +++ b/dat/Tourist.des @@ -72,54 +72,54 @@ DOOR:open,(16,17) DOOR:locked,(35,07) DOOR:locked,(36,07) # Monsters on siege duty. -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',"giant spider",random -MONSTER: 's',random,random -MONSTER: 's',random,random -MONSTER: 'C',"forest centaur",random -MONSTER: 'C',"forest centaur",random -MONSTER: 'C',"forest centaur",random -MONSTER: 'C',"forest centaur",random -MONSTER: 'C',"forest centaur",random -MONSTER: 'C',"forest centaur",random -MONSTER: 'C',"forest centaur",random -MONSTER: 'C',"forest centaur",random -MONSTER: 'C',random,random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: ('s',"giant spider"),random +MONSTER: 's',random +MONSTER: 's',random +MONSTER: ('C',"forest centaur"),random +MONSTER: ('C',"forest centaur"),random +MONSTER: ('C',"forest centaur"),random +MONSTER: ('C',"forest centaur"),random +MONSTER: ('C',"forest centaur"),random +MONSTER: ('C',"forest centaur"),random +MONSTER: ('C',"forest centaur"),random +MONSTER: ('C',"forest centaur"),random +MONSTER: 'C',random # Twoflower -MONSTER:'@',"Twoflower",(64,03) +MONSTER:('@',"Twoflower"),(64,03) # The treasure of Twoflower -OBJECT:'(',"chest",(64,03) +OBJECT:('(',"chest"),(64,03) # guides for the audience chamber -MONSTER:'@',"guide",(29,03) -MONSTER:'@',"guide",(32,04) -MONSTER:'@',"guide",(35,02) -MONSTER:'@',"guide",(38,03) -MONSTER:'@',"guide",(45,03) -MONSTER:'@',"guide",(48,02) -MONSTER:'@',"guide",(49,04) -MONSTER:'@',"guide",(51,03) -MONSTER:'@',"guide",(57,03) -MONSTER:'@',"guide",(62,04) -MONSTER:'@',"guide",(66,04) +MONSTER:('@',"guide"),(29,03) +MONSTER:('@',"guide"),(32,04) +MONSTER:('@',"guide"),(35,02) +MONSTER:('@',"guide"),(38,03) +MONSTER:('@',"guide"),(45,03) +MONSTER:('@',"guide"),(48,02) +MONSTER:('@',"guide"),(49,04) +MONSTER:('@',"guide"),(51,03) +MONSTER:('@',"guide"),(57,03) +MONSTER:('@',"guide"),(62,04) +MONSTER:('@',"guide"),(66,04) # path guards -MONSTER:'@',"watchman",(35,08) -MONSTER:'@',"watchman",(36,08) +MONSTER:('@',"watchman"),(35,08) +MONSTER:('@',"watchman"),(36,08) # river monsters -MONSTER:';',"giant eel",(62,12) -MONSTER:';',"piranha",(47,10) -MONSTER:';',"piranha",(29,11) -MONSTER:';',"kraken",(34,09) -MONSTER:';',"kraken",(37,09) +MONSTER:(';',"giant eel"),(62,12) +MONSTER:(';',"piranha"),(47,10) +MONSTER:(';',"piranha"),(29,11) +MONSTER:(';',"kraken"),(34,09) +MONSTER:(';',"kraken"),(37,09) # Random traps TRAP:random,random TRAP:random,random @@ -244,23 +244,23 @@ DOOR:closed,(60,16) DOOR:closed,(73,16) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Toilet paper -OBJECT:'?',"blank paper",(71,12) -OBJECT:'?',"blank paper",(71,12) +OBJECT:('?',"blank paper"),(71,12) +OBJECT:('?',"blank paper"),(71,12) # Random traps TRAP:random,random TRAP:random,random @@ -272,24 +272,24 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',random,random -MONSTER:'s',random,random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:'s',random +MONSTER:'s',random # # The "goal" level for the quest. @@ -386,21 +386,21 @@ DOOR:random,(51,15) DOOR:open,(59,14) DOOR:open,(59,17) # Objects -OBJECT:'(',"credit card",(04,01),blessed,0,"The Platinum Yendorian Express Card" -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('(',"credit card"),(04,01),blessed,0,name:"The Platinum Yendorian Express Card" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -409,47 +409,47 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'@',"Master of Thieves",(04,01),hostile -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',"giant spider",random -MONSTER:'s',random,random -MONSTER:'s',random,random +MONSTER:('@',"Master of Thieves"),(04,01),hostile +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:('s',"giant spider"),random +MONSTER:'s',random +MONSTER:'s',random # ladies of the evening -MONSTER:'&',"succubus",(02,08) -MONSTER:'&',"succubus",(08,08) -MONSTER:'&',"incubus",(02,14) -MONSTER:'&',"incubus",(08,14) -MONSTER:'&',"incubus",(02,17) -MONSTER:'&',"incubus",(08,17) +MONSTER:('&',"succubus"),(02,08) +MONSTER:('&',"succubus"),(08,08) +MONSTER:('&',"incubus"),(02,14) +MONSTER:('&',"incubus"),(08,14) +MONSTER:('&',"incubus"),(02,17) +MONSTER:('&',"incubus"),(08,17) # Police station (with drunken prisoners) -MONSTER:'K',"Kop Kaptain",(24,09),hostile -MONSTER:'K',"Kop Lieutenant",(20,09),hostile -MONSTER:'K',"Kop Lieutenant",(22,11),hostile -MONSTER:'K',"Kop Lieutenant",(22,07),hostile -MONSTER:'K',"Keystone Kop",(19,07),hostile -MONSTER:'K',"Keystone Kop",(19,08),hostile -MONSTER:'K',"Keystone Kop",(22,09),hostile -MONSTER:'K',"Keystone Kop",(24,11),hostile -MONSTER:'K',"Keystone Kop",(19,11),hostile -MONSTER:'@',"prisoner",(19,13) -MONSTER:'@',"prisoner",(21,13) -MONSTER:'@',"prisoner",(24,13) +MONSTER:('K',"Kop Kaptain"),(24,09),hostile +MONSTER:('K',"Kop Lieutenant"),(20,09),hostile +MONSTER:('K',"Kop Lieutenant"),(22,11),hostile +MONSTER:('K',"Kop Lieutenant"),(22,07),hostile +MONSTER:('K',"Keystone Kop"),(19,07),hostile +MONSTER:('K',"Keystone Kop"),(19,08),hostile +MONSTER:('K',"Keystone Kop"),(22,09),hostile +MONSTER:('K',"Keystone Kop"),(24,11),hostile +MONSTER:('K',"Keystone Kop"),(19,11),hostile +MONSTER:('@',"prisoner"),(19,13) +MONSTER:('@',"prisoner"),(21,13) +MONSTER:('@',"prisoner"),(24,13) # -MONSTER:'@',"watchman",(33,10),hostile +MONSTER:('@',"watchman"),(33,10),hostile WALLIFY @@ -461,61 +461,61 @@ WALLIFY # MAZE: "Tou-fila" , ' ' -INIT_MAP: '.' , ' ', true, true, random, true +INIT_MAP: mines, '.' , ' ', true, true, random, true NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # TRAP: random, random TRAP: random, random TRAP: random, random TRAP: random, random # -MONSTER: '@', "soldier", random, hostile -MONSTER: '@', "soldier", random, hostile -MONSTER: '@', "soldier", random, hostile -MONSTER: '@', "soldier", random, hostile -MONSTER: '@', "soldier", random, hostile -MONSTER: 'H', random, random, hostile -MONSTER: 'C', random, random, hostile +MONSTER: ('@', "soldier"), random, hostile +MONSTER: ('@', "soldier"), random, hostile +MONSTER: ('@', "soldier"), random, hostile +MONSTER: ('@', "soldier"), random, hostile +MONSTER: ('@', "soldier"), random, hostile +MONSTER: 'H', random, hostile +MONSTER: 'C', random, hostile MAZE: "Tou-filb" , ' ' -INIT_MAP: '.' , ' ', true, true, random, true +INIT_MAP: mines, '.' , ' ', true, true, random, true NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # TRAP: random, random TRAP: random, random TRAP: random, random TRAP: random, random # -MONSTER: '@', "soldier", random, hostile -MONSTER: '@', "captain", random, hostile -MONSTER: '@', "captain", random, hostile -MONSTER: 'H', random, random, hostile -MONSTER: 'H', random, random, hostile -MONSTER: 'C', random, random, hostile -MONSTER: 's', random, random +MONSTER: ('@', "soldier"), random, hostile +MONSTER: ('@', "captain"), random, hostile +MONSTER: ('@', "captain"), random, hostile +MONSTER: 'H', random, hostile +MONSTER: 'H', random, hostile +MONSTER: 'C', random, hostile +MONSTER: 's', random diff --git a/dat/Valkyrie.des b/dat/Valkyrie.des index 04c401bde..0dbd3bd05 100644 --- a/dat/Valkyrie.des +++ b/dat/Valkyrie.des @@ -11,8 +11,7 @@ # and receive your quest assignment. # MAZE: "Val-strt",' ' -FLAGS: noteleport,hardfloor -INIT_MAP: '.', 'I', true, true, lit, false, true +FLAGS: noteleport,hardfloor,icedpools GEOMETRY:center,center MAP IIIIIIPPPIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII @@ -48,18 +47,18 @@ FOUNTAIN:(53,02) DOOR:locked,(26,10) DOOR:locked,(43,10) # Norn -MONSTER:'@',"Norn",(35,10) +MONSTER:('@',"Norn"),(35,10) # The treasure of the Norn -OBJECT:'(',"chest",(36,10) +OBJECT:('(',"chest"),(36,10) # valkyrie guards for the audience chamber -MONSTER:'@',"warrior",(27,08) -MONSTER:'@',"warrior",(27,09) -MONSTER:'@',"warrior",(27,11) -MONSTER:'@',"warrior",(27,12) -MONSTER:'@',"warrior",(42,08) -MONSTER:'@',"warrior",(42,09) -MONSTER:'@',"warrior",(42,11) -MONSTER:'@',"warrior",(42,12) +MONSTER:('@',"warrior"),(27,08) +MONSTER:('@',"warrior"),(27,09) +MONSTER:('@',"warrior"),(27,11) +MONSTER:('@',"warrior"),(27,12) +MONSTER:('@',"warrior"),(42,08) +MONSTER:('@',"warrior"),(42,09) +MONSTER:('@',"warrior"),(42,11) +MONSTER:('@',"warrior"),(42,12) # Non diggable walls NON_DIGGABLE:(26,07,43,13) # Random traps @@ -70,18 +69,18 @@ TRAP:"fire",random TRAP:"fire",random TRAP:"fire",random # Monsters on siege duty. -MONSTER: 'a',"fire ant",(04,12) -MONSTER: 'a',"fire ant",(08,08) -MONSTER: 'a',"fire ant",(14,04) -MONSTER: 'a',"fire ant",(17,11) -MONSTER: 'a',"fire ant",(24,10) -MONSTER: 'a',"fire ant",(45,10) -MONSTER: 'a',"fire ant",(54,02) -MONSTER: 'a',"fire ant",(55,07) -MONSTER: 'a',"fire ant",(58,14) -MONSTER: 'a',"fire ant",(63,17) -MONSTER: 'H',"fire giant",(18,01),hostile -MONSTER: 'H',"fire giant",(10,16),hostile +MONSTER: ('a',"fire ant"),(04,12) +MONSTER: ('a',"fire ant"),(08,08) +MONSTER: ('a',"fire ant"),(14,04) +MONSTER: ('a',"fire ant"),(17,11) +MONSTER: ('a',"fire ant"),(24,10) +MONSTER: ('a',"fire ant"),(45,10) +MONSTER: ('a',"fire ant"),(54,02) +MONSTER: ('a',"fire ant"),(55,07) +MONSTER: ('a',"fire ant"),(58,14) +MONSTER: ('a',"fire ant"),(63,17) +MONSTER: ('H',"fire giant"),(18,01),hostile +MONSTER: ('H',"fire giant"),(10,16),hostile # # The "locate" level for the quest. @@ -91,8 +90,8 @@ MONSTER: 'H',"fire giant",(10,16),hostile # MAZE: "Val-loca",' ' -FLAGS: hardfloor -INIT_MAP: '.', 'I', true, true, lit, false, true +FLAGS: hardfloor,icedpools +INIT_MAP: mines, '.', 'I', true, true, lit, false GEOMETRY:center,center MAP PPPP.... ....PPPPP. @@ -117,21 +116,21 @@ STAIR:(20,06),down # Non diggable walls NON_DIGGABLE:(00,00,39,12) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:"fire",random TRAP:"fire",random @@ -140,33 +139,33 @@ TRAP:"fire",random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',random,random -MONSTER:'H',random,random,hostile -MONSTER:'H',"fire giant",random,hostile -MONSTER:'H',"fire giant",random,hostile -MONSTER:'H',"fire giant",random,hostile -MONSTER:'H',"fire giant",random,hostile -MONSTER:'H',"fire giant",random,hostile -MONSTER:'H',"fire giant",random,hostile -MONSTER:'H',"fire giant",random,hostile -MONSTER:'H',random,random,hostile +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:'a',random +MONSTER:'H',random,hostile +MONSTER:('H',"fire giant"),random,hostile +MONSTER:('H',"fire giant"),random,hostile +MONSTER:('H',"fire giant"),random,hostile +MONSTER:('H',"fire giant"),random,hostile +MONSTER:('H',"fire giant"),random,hostile +MONSTER:('H',"fire giant"),random,hostile +MONSTER:('H',"fire giant"),random,hostile +MONSTER:'H',random,hostile # # The "goal" level for the quest. @@ -177,7 +176,8 @@ MONSTER:'H',random,random,hostile # MAZE: "Val-goal", 'L' -INIT_MAP: '.', 'L', true, true, lit, false, true +FLAGS: icedpools +INIT_MAP: mines, '.', 'L', true, true, lit, false GEOMETRY:center,center MAP .L............................LLLLL @@ -209,21 +209,21 @@ NON_DIGGABLE:(00,00,34,16) DRAWBRIDGE:(17,02),south,random DRAWBRIDGE:(17,14),north,open # Objects -OBJECT:'(',"crystal ball",(17,08),blessed,5,"The Orb of Fate" -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('(',"crystal ball"),(17,08),blessed,5,name:"The Orb of Fate" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Traps TRAP:"board",(13,08) TRAP:"board",(21,08) @@ -236,26 +236,26 @@ TRAP:"board",random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'H',"Lord Surtur",(17,08) -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',"fire ant",random -MONSTER:'a',random,random -MONSTER:'a',random,random -MONSTER:'H',"fire giant",(10,06),hostile -MONSTER:'H',"fire giant",(10,07),hostile -MONSTER:'H',"fire giant",(10,08),hostile -MONSTER:'H',"fire giant",(10,09),hostile -MONSTER:'H',"fire giant",(10,10),hostile -MONSTER:'H',"fire giant",(24,06),hostile -MONSTER:'H',"fire giant",(24,07),hostile -MONSTER:'H',"fire giant",(24,08),hostile -MONSTER:'H',"fire giant",(24,09),hostile -MONSTER:'H',"fire giant",(24,10),hostile -MONSTER:'H',"fire giant",random,hostile -MONSTER:'H',"fire giant",random,hostile -MONSTER:'H',random,random,hostile +MONSTER:('H',"Lord Surtur"),(17,08) +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:('a',"fire ant"),random +MONSTER:'a',random +MONSTER:'a',random +MONSTER:('H',"fire giant"),(10,06),hostile +MONSTER:('H',"fire giant"),(10,07),hostile +MONSTER:('H',"fire giant"),(10,08),hostile +MONSTER:('H',"fire giant"),(10,09),hostile +MONSTER:('H',"fire giant"),(10,10),hostile +MONSTER:('H',"fire giant"),(24,06),hostile +MONSTER:('H',"fire giant"),(24,07),hostile +MONSTER:('H',"fire giant"),(24,08),hostile +MONSTER:('H',"fire giant"),(24,09),hostile +MONSTER:('H',"fire giant"),(24,10),hostile +MONSTER:('H',"fire giant"),random,hostile +MONSTER:('H',"fire giant"),random,hostile +MONSTER:'H',random,hostile # # The "fill" levels for the quest. @@ -267,29 +267,30 @@ MONSTER:'H',random,random,hostile # MAZE: "Val-fila" , 'I' -INIT_MAP: '.', 'I', true, true, lit, false, true +FLAGS: icedpools +INIT_MAP: mines, '.', 'I', true, true, lit, false NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # -MONSTER: 'a', "fire ant", random -MONSTER: 'a', "fire ant", random -MONSTER: 'a', "fire ant", random -MONSTER: 'a', "fire ant", random -MONSTER: 'a', "fire ant", random -MONSTER: 'a', random, random -MONSTER: 'H', "fire giant", random, hostile +MONSTER: ('a', "fire ant"), random +MONSTER: ('a', "fire ant"), random +MONSTER: ('a', "fire ant"), random +MONSTER: ('a', "fire ant"), random +MONSTER: ('a', "fire ant"), random +MONSTER: 'a', random +MONSTER: ('H', "fire giant"), random, hostile # TRAP: random, random TRAP: random, random @@ -300,31 +301,32 @@ TRAP: random, random TRAP: random, random MAZE: "Val-filb" , 'L' -INIT_MAP: '.', 'L', true, true, lit, false, true +FLAGS: icedpools +INIT_MAP: mines, '.', 'L', true, true, lit, false NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # -MONSTER: 'a', "fire ant", random -MONSTER: 'a', "fire ant", random -MONSTER: 'a', "fire ant", random -MONSTER: 'a', random, random -MONSTER: 'H', "fire giant", random, hostile -MONSTER: 'H', "fire giant", random, hostile -MONSTER: 'H', "fire giant", random, hostile +MONSTER: ('a', "fire ant"), random +MONSTER: ('a', "fire ant"), random +MONSTER: ('a', "fire ant"), random +MONSTER: 'a', random +MONSTER: ('H', "fire giant"), random, hostile +MONSTER: ('H', "fire giant"), random, hostile +MONSTER: ('H', "fire giant"), random, hostile # TRAP: "fire", random TRAP: "fire", random diff --git a/dat/Wizard.des b/dat/Wizard.des index dae831ed4..d70be72d6 100644 --- a/dat/Wizard.des +++ b/dat/Wizard.des @@ -38,7 +38,7 @@ ENDMAP REGION:(00,00,75,19),lit,"ordinary" REGION:(35,00,49,03),unlit,"ordinary" REGION:(43,12,49,16),unlit,"ordinary" -REGION:(19,11,33,15),unlit,"ordinary",unfilled,true +REGION:(19,11,33,15),unlit,"ordinary",unfilled,irregular REGION:(30,10,31,10),unlit,"ordinary" # Stairs STAIR:(30,10),down @@ -54,22 +54,22 @@ DOOR:closed,(15,10) DOOR:locked,(19,10) DOOR:locked,(20,10) # Neferet the Green, the quest leader -MONSTER:'@',"Neferet the Green",(23,05) +MONSTER:('@',"Neferet the Green"),(23,05) # The treasure of the quest leader -OBJECT:'(',"chest",(24,05) +OBJECT:('(',"chest"),(24,05) # apprentice guards for the audience chamber -MONSTER:'@',"apprentice",(30,07) -MONSTER:'@',"apprentice",(24,06) -MONSTER:'@',"apprentice",(15,06) -MONSTER:'@',"apprentice",(15,12) -MONSTER:'@',"apprentice",(26,11) -MONSTER:'@',"apprentice",(27,11) -MONSTER:'@',"apprentice",(19,09) -MONSTER:'@',"apprentice",(20,09) +MONSTER:('@',"apprentice"),(30,07) +MONSTER:('@',"apprentice"),(24,06) +MONSTER:('@',"apprentice"),(15,06) +MONSTER:('@',"apprentice"),(15,12) +MONSTER:('@',"apprentice"),(26,11) +MONSTER:('@',"apprentice"),(27,11) +MONSTER:('@',"apprentice"),(19,09) +MONSTER:('@',"apprentice"),(20,09) # Eels in the pond -MONSTER:';',"giant eel",(62,14) -MONSTER:';',"giant eel",(69,15) -MONSTER:';',"giant eel",(67,17) +MONSTER:(';',"giant eel"),(62,14) +MONSTER:(';',"giant eel"),(69,15) +MONSTER:(';',"giant eel"),(67,17) # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Random traps @@ -80,21 +80,21 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Monsters on siege duty. -MONSTER: 'B',random,(60,09),hostile -MONSTER: 'W',random,(60,10),hostile -MONSTER: 'B',random,(60,11),hostile -MONSTER: 'B',random,(60,12),hostile -MONSTER: 'i',random,(60,13),hostile -MONSTER: 'B',random,(61,10),hostile -MONSTER: 'B',random,(61,11),hostile -MONSTER: 'B',random,(61,12),hostile -MONSTER: 'B',random,(35,03),hostile -MONSTER: 'i',random,(35,17),hostile -MONSTER: 'B',random,(36,17),hostile -MONSTER: 'B',random,(34,16),hostile -MONSTER: 'i',random,(34,17),hostile -MONSTER: 'W',random,(67,02),hostile -MONSTER: 'B',random,(10,19),hostile +MONSTER: 'B',(60,09),hostile +MONSTER: 'W',(60,10),hostile +MONSTER: 'B',(60,11),hostile +MONSTER: 'B',(60,12),hostile +MONSTER: 'i',(60,13),hostile +MONSTER: 'B',(61,10),hostile +MONSTER: 'B',(61,11),hostile +MONSTER: 'B',(61,12),hostile +MONSTER: 'B',(35,03),hostile +MONSTER: 'i',(35,17),hostile +MONSTER: 'B',(36,17),hostile +MONSTER: 'B',(34,16),hostile +MONSTER: 'i',(34,17),hostile +MONSTER: 'W',(67,02),hostile +MONSTER: 'B',(10,19),hostile # # The "locate" level for the quest. @@ -153,21 +153,21 @@ STAIR:(48,10),down # Non diggable walls NON_DIGGABLE:(00,00,75,20) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:"spiked pit",(24,02) TRAP:"spiked pit",(07,10) @@ -191,33 +191,33 @@ TRAP:"dart",random TRAP:"dart",random TRAP:"dart",random # Random monsters. -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'i',random,random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:'i',random,hostile # # The "goal" level for the quest. @@ -293,21 +293,21 @@ NON_DIGGABLE:(00,00,75,19) # The altar. This is not a shrine. ALTAR:(16,11),noncoaligned,altar # Objects -OBJECT:'"',"amulet of ESP",(16,11),blessed,0,"The Eye of the Aethiopica" -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('"',"amulet of ESP"),(16,11),blessed,0,name:"The Eye of the Aethiopica" +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -316,43 +316,43 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'@',"Dark One",(16,11) -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'B',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'i',random,random,hostile -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'i',random,random,hostile +MONSTER:('@',"Dark One"),(16,11) +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'B',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:'i',random,hostile +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:'i',random,hostile # Captive Monsters in the dungeon -MONSTER:'@',"rogue",(35,06),peaceful,"Pug" -MONSTER:'Y',"owlbear",(47,06),peaceful,asleep -MONSTER:'@',"wizard",(32,11),peaceful,asleep,"Newt" -MONSTER:'@',"Grey-elf",(44,11),peaceful -MONSTER:'H',"hill giant",(47,11),peaceful,asleep -MONSTER:'G',"gnomish wizard",(38,06),peaceful -MONSTER:'@',"prisoner",(35,11),peaceful -MONSTER:'@',"prisoner",(41,11),peaceful,asleep +MONSTER:('@',"rogue"),(35,06),peaceful,"Pug" +MONSTER:('Y',"owlbear"),(47,06),peaceful,asleep +MONSTER:('@',"wizard"),(32,11),peaceful,asleep,"Newt" +MONSTER:('@',"Grey-elf"),(44,11),peaceful +MONSTER:('H',"hill giant"),(47,11),peaceful,asleep +MONSTER:('G',"gnomish wizard"),(38,06),peaceful +MONSTER:('@',"prisoner"),(35,11),peaceful +MONSTER:('@',"prisoner"),(41,11),peaceful,asleep # # The "fill" levels for the quest. @@ -365,77 +365,89 @@ MONSTER:'@',"prisoner",(41,11),peaceful,asleep LEVEL: "Wiz-fila" # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'i', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: 'i', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random,random,random -MONSTER: 'i', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random,random + MONSTER: 'i', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'B', "vampire bat", random -MONSTER: 'B', "vampire bat", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: ('B', "vampire bat"), random + MONSTER: ('B', "vampire bat"), random +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'i', random, random, hostile -MONSTER: 'B', "vampire bat", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random + MONSTER: 'i', random, hostile + MONSTER: ('B', "vampire bat"), random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'i', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + MONSTER: 'i', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'B', "vampire bat", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + MONSTER: ('B', "vampire bat"), random +} RANDOM_CORRIDORS LEVEL: "Wiz-filb" # -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random -MONSTER: 'X', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random + MONSTER: 'X', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random,random,random -MONSTER: 'i', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random,random + MONSTER: 'i', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -OBJECT: random,random,random -MONSTER: 'X', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + OBJECT: random,random + MONSTER: 'X', random, hostile +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'i', random, random, hostile -MONSTER: 'B', "vampire bat", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random + MONSTER: 'i', random, hostile + MONSTER: ('B', "vampire bat"), random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'i', random, random, hostile +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + TRAP: random, random + MONSTER: 'i', random, hostile +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: 'B', "vampire bat", random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + MONSTER: ('B', "vampire bat"), random +} RANDOM_CORRIDORS diff --git a/dat/bigroom.des b/dat/bigroom.des index 00ea47f32..a902cfc3a 100644 --- a/dat/bigroom.des +++ b/dat/bigroom.des @@ -38,21 +38,21 @@ STAIR:random,down # Non diggable walls NON_DIGGABLE:(00,00,74,17) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -61,34 +61,34 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random # Here, just play with the lighting... @@ -130,21 +130,21 @@ STAIR:random,down # Non diggable walls NON_DIGGABLE:(00,00,74,17) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -153,34 +153,34 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random # Now, let's get fancy... @@ -214,21 +214,21 @@ STAIR:random,down # Non diggable walls NON_DIGGABLE:(00,00,74,17) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -237,34 +237,34 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:random,random,(01,01) -MONSTER:random,random,(13,01) -MONSTER:random,random,(25,01) -MONSTER:random,random,(37,01) -MONSTER:random,random,(49,01) -MONSTER:random,random,(61,01) -MONSTER:random,random,(73,01) -MONSTER:random,random,(07,07) -MONSTER:random,random,(13,07) -MONSTER:random,random,(25,07) -MONSTER:random,random,(37,07) -MONSTER:random,random,(49,07) -MONSTER:random,random,(61,07) -MONSTER:random,random,(67,07) -MONSTER:random,random,(07,09) -MONSTER:random,random,(13,09) -MONSTER:random,random,(25,09) -MONSTER:random,random,(37,09) -MONSTER:random,random,(49,09) -MONSTER:random,random,(61,09) -MONSTER:random,random,(67,09) -MONSTER:random,random,(01,16) -MONSTER:random,random,(13,16) -MONSTER:random,random,(25,16) -MONSTER:random,random,(37,16) -MONSTER:random,random,(49,16) -MONSTER:random,random,(61,16) -MONSTER:random,random,(73,16) +MONSTER:random,(01,01) +MONSTER:random,(13,01) +MONSTER:random,(25,01) +MONSTER:random,(37,01) +MONSTER:random,(49,01) +MONSTER:random,(61,01) +MONSTER:random,(73,01) +MONSTER:random,(07,07) +MONSTER:random,(13,07) +MONSTER:random,(25,07) +MONSTER:random,(37,07) +MONSTER:random,(49,07) +MONSTER:random,(61,07) +MONSTER:random,(67,07) +MONSTER:random,(07,09) +MONSTER:random,(13,09) +MONSTER:random,(25,09) +MONSTER:random,(37,09) +MONSTER:random,(49,09) +MONSTER:random,(61,09) +MONSTER:random,(67,09) +MONSTER:random,(01,16) +MONSTER:random,(13,16) +MONSTER:random,(25,16) +MONSTER:random,(37,16) +MONSTER:random,(49,16) +MONSTER:random,(61,16) +MONSTER:random,(73,16) MAZE:"bigrm-4",' ' GEOMETRY:center,center MAP @@ -300,21 +300,21 @@ FOUNTAIN:(05,15) FOUNTAIN:(69,02) FOUNTAIN:(69,15) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -323,34 +323,34 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random # Try an oval room... @@ -385,21 +385,21 @@ STAIR:random,down # Non diggable walls NON_DIGGABLE:(00,00,72,18) # Objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -408,31 +408,31 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random diff --git a/dat/bogusmon.txt b/dat/bogusmon.txt index 2ec3e7fe7..59bfdbe3a 100644 --- a/dat/bogusmon.txt +++ b/dat/bogusmon.txt @@ -245,6 +245,9 @@ flying pig hippocampus hippogriff kelpie +catoblepas +phoenix +amphisbaena # Unusually animate body parts bouncing eye diff --git a/dat/castle.des b/dat/castle.des index 1dd4fda78..17f5e9f5c 100644 --- a/dat/castle.des +++ b/dat/castle.des @@ -42,9 +42,15 @@ MAP ENDMAP # Random registers initialisation -RANDOM_OBJECTS:'[',')','*','%' -RANDOM_PLACES:(04,02),(58,02),(04,14),(58,14) -RANDOM_MONSTERS:'L','N','E','H','M','O','R','T','X','Z' +$object = object: { '[',')','*','%' } +SHUFFLE: $object + +$place = { (04,02),(58,02),(04,14),(58,14) } +SHUFFLE: $place + +$monster = monster: { 'L','N','E','H','M','O','R','T','X','Z' } +SHUFFLE: $monster + TELEPORT_REGION:levregion(01,00,10,20),(1,1,61,15),down TELEPORT_REGION:levregion(69,00,79,20),(1,1,61,15),up @@ -72,72 +78,73 @@ DOOR:closed,(55,13) # The drawbridge DRAWBRIDGE:(05,08),east,closed # Storeroom number 1 -OBJECT:object[0],random,(39,05) -OBJECT:object[0],random,(40,05) -OBJECT:object[0],random,(41,05) -OBJECT:object[0],random,(42,05) -OBJECT:object[0],random,(43,05) -OBJECT:object[0],random,(44,05) -OBJECT:object[0],random,(45,05) -OBJECT:object[0],random,(39,06) -OBJECT:object[0],random,(40,06) -OBJECT:object[0],random,(41,06) -OBJECT:object[0],random,(42,06) -OBJECT:object[0],random,(43,06) -OBJECT:object[0],random,(44,06) -OBJECT:object[0],random,(45,06) +OBJECT:$object[0],(39,05) +OBJECT:$object[0],(40,05) +OBJECT:$object[0],(41,05) +OBJECT:$object[0],(42,05) +OBJECT:$object[0],(43,05) +OBJECT:$object[0],(44,05) +OBJECT:$object[0],(45,05) +OBJECT:$object[0],(39,06) +OBJECT:$object[0],(40,06) +OBJECT:$object[0],(41,06) +OBJECT:$object[0],(42,06) +OBJECT:$object[0],(43,06) +OBJECT:$object[0],(44,06) +OBJECT:$object[0],(45,06) # Storeroom number 2 -OBJECT:object[1],random,(49,05) -OBJECT:object[1],random,(50,05) -OBJECT:object[1],random,(51,05) -OBJECT:object[1],random,(52,05) -OBJECT:object[1],random,(53,05) -OBJECT:object[1],random,(54,05) -OBJECT:object[1],random,(55,05) -OBJECT:object[1],random,(49,06) -OBJECT:object[1],random,(50,06) -OBJECT:object[1],random,(51,06) -OBJECT:object[1],random,(52,06) -OBJECT:object[1],random,(53,06) -OBJECT:object[1],random,(54,06) -OBJECT:object[1],random,(55,06) +OBJECT:$object[1],(49,05) +OBJECT:$object[1],(50,05) +OBJECT:$object[1],(51,05) +OBJECT:$object[1],(52,05) +OBJECT:$object[1],(53,05) +OBJECT:$object[1],(54,05) +OBJECT:$object[1],(55,05) +OBJECT:$object[1],(49,06) +OBJECT:$object[1],(50,06) +OBJECT:$object[1],(51,06) +OBJECT:$object[1],(52,06) +OBJECT:$object[1],(53,06) +OBJECT:$object[1],(54,06) +OBJECT:$object[1],(55,06) # Storeroom number 3 -OBJECT:object[2],random,(39,10) -OBJECT:object[2],random,(40,10) -OBJECT:object[2],random,(41,10) -OBJECT:object[2],random,(42,10) -OBJECT:object[2],random,(43,10) -OBJECT:object[2],random,(44,10) -OBJECT:object[2],random,(45,10) -OBJECT:object[2],random,(39,11) -OBJECT:object[2],random,(40,11) -OBJECT:object[2],random,(41,11) -OBJECT:object[2],random,(42,11) -OBJECT:object[2],random,(43,11) -OBJECT:object[2],random,(44,11) -OBJECT:object[2],random,(45,11) +OBJECT:$object[2],(39,10) +OBJECT:$object[2],(40,10) +OBJECT:$object[2],(41,10) +OBJECT:$object[2],(42,10) +OBJECT:$object[2],(43,10) +OBJECT:$object[2],(44,10) +OBJECT:$object[2],(45,10) +OBJECT:$object[2],(39,11) +OBJECT:$object[2],(40,11) +OBJECT:$object[2],(41,11) +OBJECT:$object[2],(42,11) +OBJECT:$object[2],(43,11) +OBJECT:$object[2],(44,11) +OBJECT:$object[2],(45,11) # Storeroom number 4 -OBJECT:object[3],random,(49,10) -OBJECT:object[3],random,(50,10) -OBJECT:object[3],random,(51,10) -OBJECT:object[3],random,(52,10) -OBJECT:object[3],random,(53,10) -OBJECT:object[3],random,(54,10) -OBJECT:object[3],random,(55,10) -OBJECT:object[3],random,(49,11) -OBJECT:object[3],random,(50,11) -OBJECT:object[3],random,(51,11) -OBJECT:object[3],random,(52,11) -OBJECT:object[3],random,(53,11) -OBJECT:object[3],random,(54,11) -OBJECT:object[3],random,(55,11) +OBJECT:$object[3],(49,10) +OBJECT:$object[3],(50,10) +OBJECT:$object[3],(51,10) +OBJECT:$object[3],(52,10) +OBJECT:$object[3],(53,10) +OBJECT:$object[3],(54,10) +OBJECT:$object[3],(55,10) +OBJECT:$object[3],(49,11) +OBJECT:$object[3],(50,11) +OBJECT:$object[3],(51,11) +OBJECT:$object[3],(52,11) +OBJECT:$object[3],(53,11) +OBJECT:$object[3],(54,11) +OBJECT:$object[3],(55,11) # THE WAND OF WISHING in 1 of the 4 towers -CONTAINER:'(',"chest",place[0] -OBJECT:'/',"wishing",contained +CONTAINER:('(',"chest"),$place[0] { +OBJECT:('/',"wishing") +} # Prevent monsters from eating it. (@'s never eat objects) -ENGRAVING:place[0],burn,"Elbereth" +ENGRAVING:$place[0],burn,"Elbereth" # The treasure of the lord -OBJECT:'(',"chest",(37,08) +OBJECT:('(',"chest"),(37,08) # Traps TRAP:"trap door",(40,08) TRAP:"trap door",(44,08) @@ -145,66 +152,66 @@ TRAP:"trap door",(48,08) TRAP:"trap door",(52,08) TRAP:"trap door",(55,08) # Soldiers guarding the entry hall -MONSTER:'@',"soldier",(08,06) -MONSTER:'@',"soldier",(09,05) -MONSTER:'@',"soldier",(11,05) -MONSTER:'@',"soldier",(12,06) -MONSTER:'@',"soldier",(08,10) -MONSTER:'@',"soldier",(09,11) -MONSTER:'@',"soldier",(11,11) -MONSTER:'@',"soldier",(12,10) -MONSTER:'@',"lieutenant",(09,08) +MONSTER:('@',"soldier"),(08,06) +MONSTER:('@',"soldier"),(09,05) +MONSTER:('@',"soldier"),(11,05) +MONSTER:('@',"soldier"),(12,06) +MONSTER:('@',"soldier"),(08,10) +MONSTER:('@',"soldier"),(09,11) +MONSTER:('@',"soldier"),(11,11) +MONSTER:('@',"soldier"),(12,10) +MONSTER:('@',"lieutenant"),(09,08) # Soldiers guarding the towers -MONSTER:'@',"soldier",(03,02) -MONSTER:'@',"soldier",(05,02) -MONSTER:'@',"soldier",(57,02) -MONSTER:'@',"soldier",(59,02) -MONSTER:'@',"soldier",(03,14) -MONSTER:'@',"soldier",(05,14) -MONSTER:'@',"soldier",(57,14) -MONSTER:'@',"soldier",(59,14) +MONSTER:('@',"soldier"),(03,02) +MONSTER:('@',"soldier"),(05,02) +MONSTER:('@',"soldier"),(57,02) +MONSTER:('@',"soldier"),(59,02) +MONSTER:('@',"soldier"),(03,14) +MONSTER:('@',"soldier"),(05,14) +MONSTER:('@',"soldier"),(57,14) +MONSTER:('@',"soldier"),(59,14) # The four dragons that are guarding the storerooms -MONSTER:'D',random,(47,05) -MONSTER:'D',random,(47,06) -MONSTER:'D',random,(47,10) -MONSTER:'D',random,(47,11) +MONSTER:'D',(47,05) +MONSTER:'D',(47,06) +MONSTER:'D',(47,10) +MONSTER:'D',(47,11) # Sea monsters in the moat -MONSTER:';',"giant eel",(05,07) -MONSTER:';',"giant eel",(05,09) -MONSTER:';',"giant eel",(57,07) -MONSTER:';',"giant eel",(57,09) -MONSTER:';',"shark",(05,00) -MONSTER:';',"shark",(05,16) -MONSTER:';',"shark",(57,00) -MONSTER:';',"shark",(57,16) +MONSTER:(';',"giant eel"),(05,07) +MONSTER:(';',"giant eel"),(05,09) +MONSTER:(';',"giant eel"),(57,07) +MONSTER:(';',"giant eel"),(57,09) +MONSTER:(';',"shark"),(05,00) +MONSTER:(';',"shark"),(05,16) +MONSTER:(';',"shark"),(57,00) +MONSTER:(';',"shark"),(57,16) # The throne room and the court monsters -MONSTER:monster[0],random,(27,05) -MONSTER:monster[1],random,(30,05) -MONSTER:monster[2],random,(33,05) -MONSTER:monster[3],random,(36,05) -MONSTER:monster[4],random,(28,06) -MONSTER:monster[5],random,(31,06) -MONSTER:monster[6],random,(34,06) -MONSTER:monster[7],random,(37,06) -MONSTER:monster[8],random,(27,07) -MONSTER:monster[9],random,(30,07) -MONSTER:monster[0],random,(33,07) -MONSTER:monster[1],random,(36,07) -MONSTER:monster[2],random,(28,08) -MONSTER:monster[3],random,(31,08) -MONSTER:monster[4],random,(34,08) -MONSTER:monster[5],random,(27,09) -MONSTER:monster[6],random,(30,09) -MONSTER:monster[7],random,(33,09) -MONSTER:monster[8],random,(36,09) -MONSTER:monster[9],random,(28,10) -MONSTER:monster[0],random,(31,10) -MONSTER:monster[1],random,(34,10) -MONSTER:monster[2],random,(37,10) -MONSTER:monster[3],random,(27,11) -MONSTER:monster[4],random,(30,11) -MONSTER:monster[5],random,(33,11) -MONSTER:monster[6],random,(36,11) +MONSTER:$monster[0],(27,05) +MONSTER:$monster[1],(30,05) +MONSTER:$monster[2],(33,05) +MONSTER:$monster[3],(36,05) +MONSTER:$monster[4],(28,06) +MONSTER:$monster[5],(31,06) +MONSTER:$monster[6],(34,06) +MONSTER:$monster[7],(37,06) +MONSTER:$monster[8],(27,07) +MONSTER:$monster[9],(30,07) +MONSTER:$monster[0],(33,07) +MONSTER:$monster[1],(36,07) +MONSTER:$monster[2],(28,08) +MONSTER:$monster[3],(31,08) +MONSTER:$monster[4],(34,08) +MONSTER:$monster[5],(27,09) +MONSTER:$monster[6],(30,09) +MONSTER:$monster[7],(33,09) +MONSTER:$monster[8],(36,09) +MONSTER:$monster[9],(28,10) +MONSTER:$monster[0],(31,10) +MONSTER:$monster[1],(34,10) +MONSTER:$monster[2],(37,10) +MONSTER:$monster[3],(27,11) +MONSTER:$monster[4],(30,11) +MONSTER:$monster[5],(33,11) +MONSTER:$monster[6],(36,11) # MazeWalks MAZEWALK:(00,10),west MAZEWALK:(62,06),east diff --git a/dat/data.base b/dat/data.base index 6bca23177..57aea652e 100644 --- a/dat/data.base +++ b/dat/data.base @@ -5321,6 +5321,22 @@ web Oh what a tangled web we weave, When first we practise to deceive! [ Marmion, by Sir Walter Scott ] +whistle + There were legends both on the front and on the back of the + whistle. The one read thus: + + FLA FUR BIS FLE The other: QUIS EST ISTE QUI VENIT + 'I ought to be able to make it out,' he thought; + 'but I suppose I am a little rusty in my Latin. + When I come to think of it, I don't believe I even + know the word for a whistle. The long one does seem + simple enough. It ought to mean, "Who is this who is coming?" + + Well, the best way to find out is evidently to whistle + for him.' + + [Ghost Stories of an Antiquary, by Montague Rhodes James + 'Oh, Whistle, and I'll Come to You My Lad'] # werecritter -- see "lycanthrope" *wight When he came to himself again, for a moment he could recall diff --git a/dat/endgame.des b/dat/endgame.des index 4758ff518..83441e58c 100644 --- a/dat/endgame.des +++ b/dat/endgame.des @@ -51,79 +51,79 @@ PORTAL:(0,0,75,19),(65,13,75,19),"air" # Some helpful monsters. Making sure a # pick axe and at least one wand of digging # are available. -MONSTER:'@',"Elvenking",(67,16) -MONSTER:'H',"minotaur",(67,14) +MONSTER:('@',"Elvenking"),(67,16) +MONSTER:('H',"minotaur"),(67,14) # An assortment of earth-appropriate nasties # in each cavern. -MONSTER:'E',"earth elemental",(52,13),hostile -MONSTER:'E',"earth elemental",(53,13),hostile -MONSTER:'T',"rock troll",(53,12) -MONSTER:'H',"stone giant",(54,12) +MONSTER:('E',"earth elemental"),(52,13),hostile +MONSTER:('E',"earth elemental"),(53,13),hostile +MONSTER:('T',"rock troll"),(53,12) +MONSTER:('H',"stone giant"),(54,12) # -MONSTER:'S',"pit viper",(70,05) -MONSTER:'&',"barbed devil",(69,06) -MONSTER:'H',"stone giant",(69,08) -MONSTER:''',"stone golem",(71,08) -MONSTER:'&',"pit fiend",(70,09) -MONSTER:'E',"earth elemental",(70,08),hostile +MONSTER:('S',"pit viper"),(70,05) +MONSTER:('&',"barbed devil"),(69,06) +MONSTER:('H',"stone giant"),(69,08) +MONSTER:(''',"stone golem"),(71,08) +MONSTER:('&',"pit fiend"),(70,09) +MONSTER:('E',"earth elemental"),(70,08),hostile # -MONSTER:'E',"earth elemental",(60,03),hostile -MONSTER:'H',"stone giant",(61,04) -MONSTER:'E',"earth elemental",(62,04),hostile -MONSTER:'E',"earth elemental",(61,05),hostile -MONSTER:'s',"scorpion",(62,05) -MONSTER:'p',"rock piercer",(63,05) +MONSTER:('E',"earth elemental"),(60,03),hostile +MONSTER:('H',"stone giant"),(61,04) +MONSTER:('E',"earth elemental"),(62,04),hostile +MONSTER:('E',"earth elemental"),(61,05),hostile +MONSTER:('s',"scorpion"),(62,05) +MONSTER:('p',"rock piercer"),(63,05) # -MONSTER:'U',"umber hulk",(40,05) -MONSTER:'v',"dust vortex",(42,05) -MONSTER:'T',"rock troll",(38,06) -MONSTER:'E',"earth elemental",(39,06),hostile -MONSTER:'E',"earth elemental",(41,06),hostile -MONSTER:'E',"earth elemental",(38,07),hostile -MONSTER:'H',"stone giant",(39,07) -MONSTER:'E',"earth elemental",(43,07),hostile -MONSTER:''',"stone golem",(37,08) -MONSTER:'S',"pit viper",(43,08) -MONSTER:'S',"pit viper",(43,09) -MONSTER:'T',"rock troll",(44,10) +MONSTER:('U',"umber hulk"),(40,05) +MONSTER:('v',"dust vortex"),(42,05) +MONSTER:('T',"rock troll"),(38,06) +MONSTER:('E',"earth elemental"),(39,06),hostile +MONSTER:('E',"earth elemental"),(41,06),hostile +MONSTER:('E',"earth elemental"),(38,07),hostile +MONSTER:('H',"stone giant"),(39,07) +MONSTER:('E',"earth elemental"),(43,07),hostile +MONSTER:(''',"stone golem"),(37,08) +MONSTER:('S',"pit viper"),(43,08) +MONSTER:('S',"pit viper"),(43,09) +MONSTER:('T',"rock troll"),(44,10) # -MONSTER:'E',"earth elemental",(02,01),hostile -MONSTER:'E',"earth elemental",(03,01),hostile -MONSTER:''',"stone golem",(01,02) -MONSTER:'E',"earth elemental",(02,02),hostile -MONSTER:'T',"rock troll",(04,03) -MONSTER:'T',"rock troll",(03,03) -MONSTER:'&',"pit fiend",(03,04) -MONSTER:'E',"earth elemental",(04,05),hostile -MONSTER:'S',"pit viper",(05,06) +MONSTER:('E',"earth elemental"),(02,01),hostile +MONSTER:('E',"earth elemental"),(03,01),hostile +MONSTER:(''',"stone golem"),(01,02) +MONSTER:('E',"earth elemental"),(02,02),hostile +MONSTER:('T',"rock troll"),(04,03) +MONSTER:('T',"rock troll"),(03,03) +MONSTER:('&',"pit fiend"),(03,04) +MONSTER:('E',"earth elemental"),(04,05),hostile +MONSTER:('S',"pit viper"),(05,06) # -MONSTER:'E',"earth elemental",(21,02),hostile -MONSTER:'E',"earth elemental",(21,03),hostile -MONSTER:'H',"minotaur",(21,04) -MONSTER:'E',"earth elemental",(21,05),hostile -MONSTER:'T',"rock troll",(22,05) -MONSTER:'E',"earth elemental",(22,06),hostile -MONSTER:'E',"earth elemental",(23,06),hostile +MONSTER:('E',"earth elemental"),(21,02),hostile +MONSTER:('E',"earth elemental"),(21,03),hostile +MONSTER:('H',"minotaur"),(21,04) +MONSTER:('E',"earth elemental"),(21,05),hostile +MONSTER:('T',"rock troll"),(22,05) +MONSTER:('E',"earth elemental"),(22,06),hostile +MONSTER:('E',"earth elemental"),(23,06),hostile # -MONSTER:'S',"pit viper",(14,08) -MONSTER:'&',"barbed devil",(14,09) -MONSTER:'E',"earth elemental",(13,10),hostile -MONSTER:'T',"rock troll",(12,11) -MONSTER:'E',"earth elemental",(14,12),hostile -MONSTER:'E',"earth elemental",(15,13),hostile -MONSTER:'H',"stone giant",(17,13) -MONSTER:''',"stone golem",(18,13) -MONSTER:'&',"pit fiend",(18,12) -MONSTER:'E',"earth elemental",(18,11),hostile -MONSTER:'E',"earth elemental",(18,10),hostile +MONSTER:('S',"pit viper"),(14,08) +MONSTER:('&',"barbed devil"),(14,09) +MONSTER:('E',"earth elemental"),(13,10),hostile +MONSTER:('T',"rock troll"),(12,11) +MONSTER:('E',"earth elemental"),(14,12),hostile +MONSTER:('E',"earth elemental"),(15,13),hostile +MONSTER:('H',"stone giant"),(17,13) +MONSTER:(''',"stone golem"),(18,13) +MONSTER:('&',"pit fiend"),(18,12) +MONSTER:('E',"earth elemental"),(18,11),hostile +MONSTER:('E',"earth elemental"),(18,10),hostile # -MONSTER:'&',"barbed devil",(02,16) -MONSTER:'E',"earth elemental",(03,16),hostile -MONSTER:'T',"rock troll",(02,17) -MONSTER:'E',"earth elemental",(04,17),hostile -MONSTER:'E',"earth elemental",(04,18),hostile +MONSTER:('&',"barbed devil"),(02,16) +MONSTER:('E',"earth elemental"),(03,16),hostile +MONSTER:('T',"rock troll"),(02,17) +MONSTER:('E',"earth elemental"),(04,17),hostile +MONSTER:('E',"earth elemental"),(04,18),hostile -OBJECT:'`',"boulder",random +OBJECT:('`',"boulder"),random MAZE:"air",' ' @@ -139,26 +139,26 @@ GEOMETRY:center,center # This map has no visible outer boundary, and # is all "air". MAP -AAAAAAAAAAAAAAAAAAAAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAACCCCCCAAAAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAACCAACCCCCAAAAAACCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAACCACCCCCCCAAAAACCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAACCCCCCCCCCAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAACCCCAAACCAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAACCCCAAAAAACCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAACCCCCCCAAAACCACCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAACCCCAAAAAAACCACAACCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCAACCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCAAACCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACACACCCCCAAACCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCCCCAAAACCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACACCCCCCCCAAACCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCCCCCCCCAACCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAACACCCCCCCCCCACCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCCCAAACCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAACCAAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ENDMAP # Use up and down regions to partition the level into three parts; # teleportation can't cross from one part into another. @@ -168,63 +168,63 @@ TELEPORT_REGION:levregion(01,00,24,20),levregion(25,00,79,20),up TELEPORT_REGION:levregion(56,00,79,20),levregion(01,00,55,20),down PORTAL:levregion(57,01,78,19),(0,0,0,0),"fire" REGION:(00,00,75,19),lit,"ordinary" -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile -MONSTER:'E',"air elemental",random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile +MONSTER:('E',"air elemental"),random,hostile -MONSTER:'e',"floating eye",random,hostile -MONSTER:'e',"floating eye",random,hostile -MONSTER:'e',"floating eye",random,hostile +MONSTER:('e',"floating eye"),random,hostile +MONSTER:('e',"floating eye"),random,hostile +MONSTER:('e',"floating eye"),random,hostile -MONSTER:'y',"yellow light",random,hostile -MONSTER:'y',"yellow light",random,hostile -MONSTER:'y',"yellow light",random,hostile +MONSTER:('y',"yellow light"),random,hostile +MONSTER:('y',"yellow light"),random,hostile +MONSTER:('y',"yellow light"),random,hostile -MONSTER:'A',"couatl",random +MONSTER:('A',"couatl"),random -MONSTER:'D',random,random -MONSTER:'D',random,random -MONSTER:'D',random,random -MONSTER:'D',random,random -MONSTER:'D',random,random +MONSTER:'D',random +MONSTER:'D',random +MONSTER:'D',random +MONSTER:'D',random +MONSTER:'D',random -MONSTER:'E',random,random -MONSTER:'E',random,random -MONSTER:'E',random,random -MONSTER:'J',random,random -MONSTER:'J',random,random +MONSTER:'E',random +MONSTER:'E',random +MONSTER:'E',random +MONSTER:'J',random +MONSTER:'J',random -MONSTER:'&',"djinni",random,hostile -MONSTER:'&',"djinni",random,hostile -MONSTER:'&',"djinni",random,hostile +MONSTER:('&',"djinni"),random,hostile +MONSTER:('&',"djinni"),random,hostile +MONSTER:('&',"djinni"),random,hostile -MONSTER:'v',"fog cloud",random,hostile -MONSTER:'v',"fog cloud",random,hostile -MONSTER:'v',"fog cloud",random,hostile -MONSTER:'v',"fog cloud",random,hostile -MONSTER:'v',"fog cloud",random,hostile -MONSTER:'v',"fog cloud",random,hostile -MONSTER:'v',"fog cloud",random,hostile -MONSTER:'v',"fog cloud",random,hostile -MONSTER:'v',"fog cloud",random,hostile -MONSTER:'v',"energy vortex",random,hostile -MONSTER:'v',"energy vortex",random,hostile -MONSTER:'v',"energy vortex",random,hostile -MONSTER:'v',"energy vortex",random,hostile -MONSTER:'v',"energy vortex",random,hostile -MONSTER:'v',"steam vortex",random,hostile -MONSTER:'v',"steam vortex",random,hostile -MONSTER:'v',"steam vortex",random,hostile -MONSTER:'v',"steam vortex",random,hostile -MONSTER:'v',"steam vortex",random,hostile +MONSTER:('v',"fog cloud"),random,hostile +MONSTER:('v',"fog cloud"),random,hostile +MONSTER:('v',"fog cloud"),random,hostile +MONSTER:('v',"fog cloud"),random,hostile +MONSTER:('v',"fog cloud"),random,hostile +MONSTER:('v',"fog cloud"),random,hostile +MONSTER:('v',"fog cloud"),random,hostile +MONSTER:('v',"fog cloud"),random,hostile +MONSTER:('v',"fog cloud"),random,hostile +MONSTER:('v',"energy vortex"),random,hostile +MONSTER:('v',"energy vortex"),random,hostile +MONSTER:('v',"energy vortex"),random,hostile +MONSTER:('v',"energy vortex"),random,hostile +MONSTER:('v',"energy vortex"),random,hostile +MONSTER:('v',"steam vortex"),random,hostile +MONSTER:('v',"steam vortex"),random,hostile +MONSTER:('v',"steam vortex"),random,hostile +MONSTER:('v',"steam vortex"),random,hostile +MONSTER:('v',"steam vortex"),random,hostile MAZE:"fire",' ' @@ -301,81 +301,81 @@ TRAP:"fire",random TRAP:"fire",random TRAP:"fire",random # An assortment of fire-appropriate nasties -MONSTER:'D',"red dragon",random -MONSTER:'&',"balrog",random -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'v',"fire vortex",random -MONSTER:'d',"hell hound",random +MONSTER:('D',"red dragon"),random +MONSTER:('&',"balrog"),random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('v',"fire vortex"),random +MONSTER:('d',"hell hound"),random # -MONSTER:'H',"fire giant",random -MONSTER:'&',"barbed devil",random -MONSTER:'d',"hell hound",random -MONSTER:''',"stone golem",random -MONSTER:'&',"pit fiend",random -MONSTER:'E',"fire elemental",random,hostile +MONSTER:('H',"fire giant"),random +MONSTER:('&',"barbed devil"),random +MONSTER:('d',"hell hound"),random +MONSTER:(''',"stone golem"),random +MONSTER:('&',"pit fiend"),random +MONSTER:('E',"fire elemental"),random,hostile # -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'d',"hell hound",random -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'s',"scorpion",random -MONSTER:'H',"fire giant",random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('d',"hell hound"),random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('s',"scorpion"),random +MONSTER:('H',"fire giant"),random # -MONSTER:'d',"hell hound",random -MONSTER:'v',"dust vortex",random -MONSTER:'v',"fire vortex",random -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'d',"hell hound",random -MONSTER:'E',"fire elemental",random,hostile -MONSTER:''',"stone golem",random -MONSTER:'S',"pit viper",random -MONSTER:'S',"pit viper",random -MONSTER:'v',"fire vortex",random +MONSTER:('d',"hell hound"),random +MONSTER:('v',"dust vortex"),random +MONSTER:('v',"fire vortex"),random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('d',"hell hound"),random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:(''',"stone golem"),random +MONSTER:('S',"pit viper"),random +MONSTER:('S',"pit viper"),random +MONSTER:('v',"fire vortex"),random # -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'H',"fire giant",random -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'v',"fire vortex",random -MONSTER:'v',"fire vortex",random -MONSTER:'&',"pit fiend",random -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'S',"pit viper",random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('H',"fire giant"),random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('v',"fire vortex"),random +MONSTER:('v',"fire vortex"),random +MONSTER:('&',"pit fiend"),random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('S',"pit viper"),random # -MONSTER:':',"salamander",random,hostile -MONSTER:':',"salamander",random,hostile -MONSTER:'H',"minotaur",random -MONSTER:':',"salamander",random,hostile -MONSTER:'v',"steam vortex",random -MONSTER:':',"salamander",random,hostile -MONSTER:':',"salamander",random,hostile +MONSTER:(':',"salamander"),random,hostile +MONSTER:(':',"salamander"),random,hostile +MONSTER:('H',"minotaur"),random +MONSTER:(':',"salamander"),random,hostile +MONSTER:('v',"steam vortex"),random +MONSTER:(':',"salamander"),random,hostile +MONSTER:(':',"salamander"),random,hostile # -MONSTER:'H',"fire giant",random -MONSTER:'&',"barbed devil",random -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'v',"fire vortex",random -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'d',"hell hound",random -MONSTER:'H',"fire giant",random -MONSTER:'&',"pit fiend",random -MONSTER:'E',"fire elemental",random,hostile -MONSTER:'E',"fire elemental",random,hostile +MONSTER:('H',"fire giant"),random +MONSTER:('&',"barbed devil"),random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('v',"fire vortex"),random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('d',"hell hound"),random +MONSTER:('H',"fire giant"),random +MONSTER:('&',"pit fiend"),random +MONSTER:('E',"fire elemental"),random,hostile +MONSTER:('E',"fire elemental"),random,hostile # -MONSTER:'&',"barbed devil",random -MONSTER:':',"salamander",random,hostile -MONSTER:'v',"steam vortex",random -MONSTER:':',"salamander",random,hostile -MONSTER:':',"salamander",random,hostile +MONSTER:('&',"barbed devil"),random +MONSTER:(':',"salamander"),random,hostile +MONSTER:('v',"steam vortex"),random +MONSTER:(':',"salamander"),random,hostile +MONSTER:(':',"salamander"),random,hostile -OBJECT:'`',"boulder",random -OBJECT:'`',"boulder",random -OBJECT:'`',"boulder",random -OBJECT:'`',"boulder",random -OBJECT:'`',"boulder",random +OBJECT:('`',"boulder"),random +OBJECT:('`',"boulder"),random +OBJECT:('`',"boulder"),random +OBJECT:('`',"boulder"),random +OBJECT:('`',"boulder"),random MAZE:"water",' ' @@ -412,67 +412,67 @@ ENDMAP TELEPORT_REGION:(0,0,25,19),(0,0,0,0) PORTAL:(51,0,75,19),(0,0,0,0),"astral" # A fisherman's dream... -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"giant eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"electric eel",random -MONSTER:';',"kraken",random -MONSTER:';',"kraken",random -MONSTER:';',"kraken",random -MONSTER:';',"kraken",random -MONSTER:';',"kraken",random -MONSTER:';',"kraken",random -MONSTER:';',"kraken",random -MONSTER:';',"kraken",random -MONSTER:';',"kraken",random -MONSTER:';',"shark",random -MONSTER:';',"shark",random -MONSTER:';',"shark",random -MONSTER:';',"shark",random -MONSTER:';',"piranha",random -MONSTER:';',"piranha",random -MONSTER:';',"piranha",random -MONSTER:';',"piranha",random -MONSTER:';',"jellyfish",random -MONSTER:';',"jellyfish",random -MONSTER:';',"jellyfish",random -MONSTER:';',"jellyfish",random -MONSTER:';',random,random -MONSTER:';',random,random -MONSTER:';',random,random -MONSTER:';',random,random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"giant eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"electric eel"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"kraken"),random +MONSTER:(';',"shark"),random +MONSTER:(';',"shark"),random +MONSTER:(';',"shark"),random +MONSTER:(';',"shark"),random +MONSTER:(';',"piranha"),random +MONSTER:(';',"piranha"),random +MONSTER:(';',"piranha"),random +MONSTER:(';',"piranha"),random +MONSTER:(';',"jellyfish"),random +MONSTER:(';',"jellyfish"),random +MONSTER:(';',"jellyfish"),random +MONSTER:(';',"jellyfish"),random +MONSTER:';',random +MONSTER:';',random +MONSTER:';',random +MONSTER:';',random # These guys feel like home here -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile -MONSTER:'E',"water elemental",random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile +MONSTER:('E',"water elemental"),random,hostile MAZE:"astral",' ' @@ -504,13 +504,15 @@ MAP ----------------- ENDMAP # Rider locations -RANDOM_PLACES:(23,9),(37,14),(51,9) +$place = { (23,9),(37,14),(51,9) } +SHUFFLE: $place + # Where the player will land on arrival TELEPORT_REGION:(29,15,45,15),(30,15,44,15) # Lit courts -REGION:(01,05,16,14),lit,"ordinary",filled,true -REGION:(31,01,44,10),lit,"ordinary",filled,true -REGION:(61,05,74,14),lit,"ordinary",filled,true +REGION:(01,05,16,14),lit,"ordinary",filled,irregular +REGION:(31,01,44,10),lit,"ordinary",filled,irregular +REGION:(61,05,74,14),lit,"ordinary",filled,irregular # A Sanctum for each alignment # The shrines' alignments are shuffled for # each game @@ -535,29 +537,29 @@ NON_DIGGABLE:(00,00,74,19) NON_PASSWALL:(00,00,74,19) # Moloch's horde # West round room -MONSTER:'@',"aligned priest",(18,09),noalign,hostile -MONSTER:'@',"aligned priest",(19,08),noalign,hostile -MONSTER:'@',"aligned priest",(19,09),noalign,hostile -MONSTER:'@',"aligned priest",(19,10),noalign,hostile -MONSTER:'A',"Angel",(20,09),noalign,hostile -MONSTER:'A',"Angel",(20,10),noalign,hostile -MONSTER:'&',"Pestilence",place[0],hostile +MONSTER:('@',"aligned priest"),(18,09),noalign,hostile +MONSTER:('@',"aligned priest"),(19,08),noalign,hostile +MONSTER:('@',"aligned priest"),(19,09),noalign,hostile +MONSTER:('@',"aligned priest"),(19,10),noalign,hostile +MONSTER:('A',"Angel"),(20,09),noalign,hostile +MONSTER:('A',"Angel"),(20,10),noalign,hostile +MONSTER:('&',"Pestilence"),$place[0],hostile # South-central round room -MONSTER:'@',"aligned priest",(36,12),noalign,hostile -MONSTER:'@',"aligned priest",(37,12),noalign,hostile -MONSTER:'@',"aligned priest",(38,12),noalign,hostile -MONSTER:'@',"aligned priest",(36,13),noalign,hostile -MONSTER:'A',"Angel",(38,13),noalign,hostile -MONSTER:'A',"Angel",(37,13),noalign,hostile -MONSTER:'&',"Death",place[1],hostile +MONSTER:('@',"aligned priest"),(36,12),noalign,hostile +MONSTER:('@',"aligned priest"),(37,12),noalign,hostile +MONSTER:('@',"aligned priest"),(38,12),noalign,hostile +MONSTER:('@',"aligned priest"),(36,13),noalign,hostile +MONSTER:('A',"Angel"),(38,13),noalign,hostile +MONSTER:('A',"Angel"),(37,13),noalign,hostile +MONSTER:('&',"Death"),$place[1],hostile # East round room -MONSTER:'@',"aligned priest",(56,09),noalign,hostile -MONSTER:'@',"aligned priest",(55,08),noalign,hostile -MONSTER:'@',"aligned priest",(55,09),noalign,hostile -MONSTER:'@',"aligned priest",(55,10),noalign,hostile -MONSTER:'A',"Angel",(54,09),noalign,hostile -MONSTER:'A',"Angel",(54,10),noalign,hostile -MONSTER:'&',"Famine",place[2],hostile +MONSTER:('@',"aligned priest"),(56,09),noalign,hostile +MONSTER:('@',"aligned priest"),(55,08),noalign,hostile +MONSTER:('@',"aligned priest"),(55,09),noalign,hostile +MONSTER:('@',"aligned priest"),(55,10),noalign,hostile +MONSTER:('A',"Angel"),(54,09),noalign,hostile +MONSTER:('A',"Angel"),(54,10),noalign,hostile +MONSTER:('&',"Famine"),$place[2],hostile # # The aligned horde # @@ -567,52 +569,52 @@ MONSTER:'&',"Famine",place[2],hostile # but a place holder. # # West court -MONSTER:'@',"aligned priest",(12,07),chaos,hostile -MONSTER:'@',"aligned priest",(13,07),chaos,peaceful -MONSTER:'@',"aligned priest",(14,07),law,hostile -MONSTER:'@',"aligned priest",(12,11),law,peaceful -MONSTER:'@',"aligned priest",(13,11),neutral,hostile -MONSTER:'@',"aligned priest",(14,11),neutral,peaceful -MONSTER:'A',"Angel",(11,05),chaos,hostile -MONSTER:'A',"Angel",(12,05),chaos,peaceful -MONSTER:'A',"Angel",(13,05),law,hostile -MONSTER:'A',"Angel",(11,13),law,peaceful -MONSTER:'A',"Angel",(12,13),neutral,hostile -MONSTER:'A',"Angel",(13,13),neutral,peaceful +MONSTER:('@',"aligned priest"),(12,07),chaos,hostile +MONSTER:('@',"aligned priest"),(13,07),chaos,peaceful +MONSTER:('@',"aligned priest"),(14,07),law,hostile +MONSTER:('@',"aligned priest"),(12,11),law,peaceful +MONSTER:('@',"aligned priest"),(13,11),neutral,hostile +MONSTER:('@',"aligned priest"),(14,11),neutral,peaceful +MONSTER:('A',"Angel"),(11,05),chaos,hostile +MONSTER:('A',"Angel"),(12,05),chaos,peaceful +MONSTER:('A',"Angel"),(13,05),law,hostile +MONSTER:('A',"Angel"),(11,13),law,peaceful +MONSTER:('A',"Angel"),(12,13),neutral,hostile +MONSTER:('A',"Angel"),(13,13),neutral,peaceful # Central court -MONSTER:'@',"aligned priest",(32,09),chaos,hostile -MONSTER:'@',"aligned priest",(33,09),chaos,peaceful -MONSTER:'@',"aligned priest",(34,09),law,hostile -MONSTER:'@',"aligned priest",(40,09),law,peaceful -MONSTER:'@',"aligned priest",(41,09),neutral,hostile -MONSTER:'@',"aligned priest",(42,09),neutral,peaceful -MONSTER:'A',"Angel",(31,08),chaos,hostile -MONSTER:'A',"Angel",(32,08),chaos,peaceful -MONSTER:'A',"Angel",(31,09),law,hostile -MONSTER:'A',"Angel",(42,08),law,peaceful -MONSTER:'A',"Angel",(43,08),neutral,hostile -MONSTER:'A',"Angel",(43,09),neutral,peaceful +MONSTER:('@',"aligned priest"),(32,09),chaos,hostile +MONSTER:('@',"aligned priest"),(33,09),chaos,peaceful +MONSTER:('@',"aligned priest"),(34,09),law,hostile +MONSTER:('@',"aligned priest"),(40,09),law,peaceful +MONSTER:('@',"aligned priest"),(41,09),neutral,hostile +MONSTER:('@',"aligned priest"),(42,09),neutral,peaceful +MONSTER:('A',"Angel"),(31,08),chaos,hostile +MONSTER:('A',"Angel"),(32,08),chaos,peaceful +MONSTER:('A',"Angel"),(31,09),law,hostile +MONSTER:('A',"Angel"),(42,08),law,peaceful +MONSTER:('A',"Angel"),(43,08),neutral,hostile +MONSTER:('A',"Angel"),(43,09),neutral,peaceful # East court -MONSTER:'@',"aligned priest",(60,07),chaos,hostile -MONSTER:'@',"aligned priest",(61,07),chaos,peaceful -MONSTER:'@',"aligned priest",(62,07),law,hostile -MONSTER:'@',"aligned priest",(60,11),law,peaceful -MONSTER:'@',"aligned priest",(61,11),neutral,hostile -MONSTER:'@',"aligned priest",(62,11),neutral,peaceful -MONSTER:'A',"Angel",(61,05),chaos,hostile -MONSTER:'A',"Angel",(62,05),chaos,peaceful -MONSTER:'A',"Angel",(63,05),law,hostile -MONSTER:'A',"Angel",(61,13),law,peaceful -MONSTER:'A',"Angel",(62,13),neutral,hostile -MONSTER:'A',"Angel",(63,13),neutral,peaceful +MONSTER:('@',"aligned priest"),(60,07),chaos,hostile +MONSTER:('@',"aligned priest"),(61,07),chaos,peaceful +MONSTER:('@',"aligned priest"),(62,07),law,hostile +MONSTER:('@',"aligned priest"),(60,11),law,peaceful +MONSTER:('@',"aligned priest"),(61,11),neutral,hostile +MONSTER:('@',"aligned priest"),(62,11),neutral,peaceful +MONSTER:('A',"Angel"),(61,05),chaos,hostile +MONSTER:('A',"Angel"),(62,05),chaos,peaceful +MONSTER:('A',"Angel"),(63,05),law,hostile +MONSTER:('A',"Angel"),(61,13),law,peaceful +MONSTER:('A',"Angel"),(62,13),neutral,hostile +MONSTER:('A',"Angel"),(63,13),neutral,peaceful # # Assorted nasties -MONSTER:'L',random,random,hostile -MONSTER:'L',random,random,hostile -MONSTER:'L',random,random,hostile -MONSTER:'V',random,random,hostile -MONSTER:'V',random,random,hostile -MONSTER:'V',random,random,hostile -MONSTER:'D',random,random,hostile -MONSTER:'D',random,random,hostile -MONSTER:'D',random,random,hostile +MONSTER:'L',random,hostile +MONSTER:'L',random,hostile +MONSTER:'L',random,hostile +MONSTER:'V',random,hostile +MONSTER:'V',random,hostile +MONSTER:'V',random,hostile +MONSTER:'D',random,hostile +MONSTER:'D',random,hostile +MONSTER:'D',random,hostile diff --git a/dat/gehennom.des b/dat/gehennom.des index daba7f532..7ae2a9df4 100644 --- a/dat/gehennom.des +++ b/dat/gehennom.des @@ -35,9 +35,9 @@ ENDMAP # The shrine to Moloch. REGION:(01,06,05,14),lit,"temple" # The Morgues -REGION:(19,01,24,08),unlit,"morgue",filled,true -REGION:(09,14,16,18),unlit,"morgue",filled,true -REGION:(37,09,43,14),unlit,"morgue",filled,true +REGION:(19,01,24,08),unlit,"morgue",filled,irregular +REGION:(09,14,16,18),unlit,"morgue",filled,irregular +REGION:(37,09,43,14),unlit,"morgue",filled,irregular # Stairs STAIR:(01,01),down # Branch location @@ -60,60 +60,60 @@ NON_DIGGABLE:(00,00,75,19) # note: no priest(esse)s or monks - maybe Moloch has a *special* # fate reserved for members of *those* classes. # -OBJECT:'%',"corpse",random,"archeologist",0 -OBJECT:'%',"corpse",random,"archeologist",0 -OBJECT:'%',"corpse",random,"barbarian",0 -OBJECT:'%',"corpse",random,"barbarian",0 -OBJECT:'%',"corpse",random,"caveman",0 -OBJECT:'%',"corpse",random,"cavewoman",0 -OBJECT:'%',"corpse",random,"healer",0 -OBJECT:'%',"corpse",random,"healer",0 -OBJECT:'%',"corpse",random,"knight",0 -OBJECT:'%',"corpse",random,"knight",0 -OBJECT:'%',"corpse",random,"ranger",0 -OBJECT:'%',"corpse",random,"ranger",0 -OBJECT:'%',"corpse",random,"rogue",0 -OBJECT:'%',"corpse",random,"rogue",0 -OBJECT:'%',"corpse",random,"samurai",0 -OBJECT:'%',"corpse",random,"samurai",0 -OBJECT:'%',"corpse",random,"tourist",0 -OBJECT:'%',"corpse",random,"tourist",0 -OBJECT:'%',"corpse",random,"valkyrie",0 -OBJECT:'%',"corpse",random,"valkyrie",0 -OBJECT:'%',"corpse",random,"wizard",0 -OBJECT:'%',"corpse",random,"wizard",0 +OBJECT:('%',"corpse"),random,montype:"archeologist" +OBJECT:('%',"corpse"),random,montype:"archeologist" +OBJECT:('%',"corpse"),random,montype:"barbarian" +OBJECT:('%',"corpse"),random,montype:"barbarian" +OBJECT:('%',"corpse"),random,montype:"caveman" +OBJECT:('%',"corpse"),random,montype:"cavewoman" +OBJECT:('%',"corpse"),random,montype:"healer" +OBJECT:('%',"corpse"),random,montype:"healer" +OBJECT:('%',"corpse"),random,montype:"knight" +OBJECT:('%',"corpse"),random,montype:"knight" +OBJECT:('%',"corpse"),random,montype:"ranger" +OBJECT:('%',"corpse"),random,montype:"ranger" +OBJECT:('%',"corpse"),random,montype:"rogue" +OBJECT:('%',"corpse"),random,montype:"rogue" +OBJECT:('%',"corpse"),random,montype:"samurai" +OBJECT:('%',"corpse"),random,montype:"samurai" +OBJECT:('%',"corpse"),random,montype:"tourist" +OBJECT:('%',"corpse"),random,montype:"tourist" +OBJECT:('%',"corpse"),random,montype:"valkyrie" +OBJECT:('%',"corpse"),random,montype:"valkyrie" +OBJECT:('%',"corpse"),random,montype:"wizard" +OBJECT:('%',"corpse"),random,montype:"wizard" # # Some random weapons and armor. # -OBJECT:'[',random,random -OBJECT:'[',random,random -OBJECT:'[',random,random -OBJECT:'[',random,random -OBJECT:')',random,random -OBJECT:')',random,random -OBJECT:')',random,random -OBJECT:')',random,random +OBJECT:'[',random +OBJECT:'[',random +OBJECT:'[',random +OBJECT:'[',random +OBJECT:')',random +OBJECT:')',random +OBJECT:')',random +OBJECT:')',random # # Some random loot. # -OBJECT:'*',"ruby",random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'/',random,random -OBJECT:'/',random,random -OBJECT:'=',random,random -OBJECT:'=',random,random -OBJECT:'+',random,random -OBJECT:'+',random,random -OBJECT:'(',random,random -OBJECT:'(',random,random -OBJECT:'(',random,random +OBJECT:('*',"ruby"),random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'/',random +OBJECT:'/',random +OBJECT:'=',random +OBJECT:'=',random +OBJECT:'+',random +OBJECT:'+',random +OBJECT:'(',random +OBJECT:'(',random +OBJECT:'(',random # (Not so) Random traps. TRAP:"spiked pit", (05,02) @@ -130,36 +130,36 @@ TRAP:"magic", random # Random monsters. # The ghosts. -MONSTER:' ',"ghost",random -MONSTER:' ',"ghost",random -MONSTER:' ',"ghost",random -MONSTER:' ',"ghost",random -MONSTER:' ',"ghost",random -MONSTER:' ',"ghost",random +MONSTER:(' ',"ghost"),random +MONSTER:(' ',"ghost"),random +MONSTER:(' ',"ghost"),random +MONSTER:(' ',"ghost"),random +MONSTER:(' ',"ghost"),random +MONSTER:(' ',"ghost"),random # Add a few bats for atmosphere. -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random -MONSTER:'B',"vampire bat",random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random +MONSTER:('B',"vampire bat"),random # And a lich for good measure. -MONSTER:'L',random,random +MONSTER:'L',random # Some undead nasties for good measure -MONSTER:'V',random,random -MONSTER:'V',random,random -MONSTER:'V',random,random -MONSTER:'Z',random,random -MONSTER:'Z',random,random -MONSTER:'Z',random,random -MONSTER:'Z',random,random -MONSTER:'M',random,random -MONSTER:'M',random,random -MONSTER:'M',random,random -MONSTER:'M',random,random +MONSTER:'V',random +MONSTER:'V',random +MONSTER:'V',random +MONSTER:'Z',random +MONSTER:'Z',random +MONSTER:'Z',random +MONSTER:'Z',random +MONSTER:'M',random +MONSTER:'M',random +MONSTER:'M',random +MONSTER:'M',random # # The Juiblex level # MAZE:"juiblex",' ' FLAGS:noteleport,shortsighted -INIT_MAP:'.','}',true,true,unlit,false +INIT_MAP:mines,'.','}',true,true,unlit,false # guarantee at least one open spot to ensure successful stair placement GEOMETRY:left,bottom MAP @@ -169,7 +169,7 @@ MAP }}}}.}}} }}}}}}}} ENDMAP -OBJECT:'`',"boulder",random +OBJECT:('`',"boulder"),random GEOMETRY:right,top MAP }}}}}}}} @@ -178,7 +178,7 @@ MAP }}...}}} }}}}}}}} ENDMAP -OBJECT:'`',"boulder",random +OBJECT:('`',"boulder"),random # lair GEOMETRY:center,center MAP @@ -202,8 +202,12 @@ MAP ..}}}}}.}}}}}.}}}}}.}}}}}.}}}}}.}}}}}.}}}}}.}}}}}.. ENDMAP # Random registers -RANDOM_MONSTERS:'j','b','P','F' -RANDOM_PLACES:(04,02),(46,02),(04,15),(46,15) +$monster = monster: { 'j','b','P','F' } +SHUFFLE: $monster + +$place = { (04,02),(46,02),(04,15),(46,15) } +SHUFFLE: $place + # Dungeon description REGION:(00,00,50,17),unlit,"swamp" MAZEWALK:(00,09),west @@ -213,57 +217,57 @@ STAIR:levregion(69,00,79,20),(0,0,50,17),up BRANCH:levregion(01,00,11,20),(0,0,50,17) TELEPORT_REGION:levregion(01,00,11,20),(0,0,50,17),up TELEPORT_REGION:levregion(69,00,79,20),(0,0,50,17),down -FOUNTAIN:place[0] -MONSTER:'m',"giant mimic",place[1],m_feature "fountain" -MONSTER:'m',"giant mimic",place[2],m_feature "fountain" -MONSTER:'m',"giant mimic",place[3],m_feature "fountain" +FOUNTAIN:$place[0] +MONSTER:('m',"giant mimic"),$place[1],m_feature "fountain" +MONSTER:('m',"giant mimic"),$place[2],m_feature "fountain" +MONSTER:('m',"giant mimic"),$place[3],m_feature "fountain" # The demon of the swamp -MONSTER:'&',"Juiblex",(25,08) +MONSTER:('&',"Juiblex"),(25,08) # And a couple demons -MONSTER:'i',"lemure",(43,08) -MONSTER:'i',"lemure",(44,08) -MONSTER:'i',"lemure",(45,08) +MONSTER:('i',"lemure"),(43,08) +MONSTER:('i',"lemure"),(44,08) +MONSTER:('i',"lemure"),(45,08) # Some liquids and gems -OBJECT:'*',random,(43,06) -OBJECT:'*',random,(45,06) -OBJECT:'!',random,(43,09) -OBJECT:'!',random,(44,09) -OBJECT:'!',random,(45,09) +OBJECT:'*',(43,06) +OBJECT:'*',(45,06) +OBJECT:'!',(43,09) +OBJECT:'!',(44,09) +OBJECT:'!',(45,09) # And lots of blobby monsters -MONSTER:monster[0],random,(25,06) -MONSTER:monster[1],random,(24,07) -MONSTER:monster[2],random,(26,07) -MONSTER:monster[3],random,(23,08) -MONSTER:monster[3],random,(27,08) -MONSTER:monster[2],random,(24,09) -MONSTER:monster[1],random,(26,09) -MONSTER:monster[0],random,(25,10) -MONSTER:'j',random,random -MONSTER:'j',random,random -MONSTER:'j',random,random -MONSTER:'j',random,random -MONSTER:'P',random,random -MONSTER:'P',random,random -MONSTER:'P',random,random -MONSTER:'P',random,random -MONSTER:'b',random,random -MONSTER:'b',random,random -MONSTER:'b',random,random -MONSTER:'F',random,random -MONSTER:'F',random,random -MONSTER:'F',random,random -MONSTER:'m',random,random -MONSTER:'m',random,random -MONSTER:';',"jellyfish",random -MONSTER:';',"jellyfish",random +MONSTER:$monster[0],(25,06) +MONSTER:$monster[1],(24,07) +MONSTER:$monster[2],(26,07) +MONSTER:$monster[3],(23,08) +MONSTER:$monster[3],(27,08) +MONSTER:$monster[2],(24,09) +MONSTER:$monster[1],(26,09) +MONSTER:$monster[0],(25,10) +MONSTER:'j',random +MONSTER:'j',random +MONSTER:'j',random +MONSTER:'j',random +MONSTER:'P',random +MONSTER:'P',random +MONSTER:'P',random +MONSTER:'P',random +MONSTER:'b',random +MONSTER:'b',random +MONSTER:'b',random +MONSTER:'F',random +MONSTER:'F',random +MONSTER:'F',random +MONSTER:'m',random +MONSTER:'m',random +MONSTER:(';',"jellyfish"),random +MONSTER:(';',"jellyfish"),random # Some random objects -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'`',"boulder",random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:('`',"boulder"),random # Some traps TRAP:"sleep gas",random TRAP:"sleep gas",random @@ -305,30 +309,30 @@ STAIR:levregion(01,00,12,20),levregion(20,01,70,20),up BRANCH:levregion(01,00,12,20),levregion(20,01,70,20) TELEPORT_REGION:levregion(01,00,12,20),levregion(20,01,70,20) # Wall "ruins" -OBJECT:'`',"boulder",(19,02) -OBJECT:'`',"boulder",(20,02) -OBJECT:'`',"boulder",(21,02) -OBJECT:'`',"boulder",(36,02) -OBJECT:'`',"boulder",(36,03) -OBJECT:'`',"boulder",(06,04) -OBJECT:'`',"boulder",(05,05) -OBJECT:'`',"boulder",(06,05) -OBJECT:'`',"boulder",(07,05) -OBJECT:'`',"boulder",(39,05) -OBJECT:'`',"boulder",(08,08) -OBJECT:'`',"boulder",(09,08) -OBJECT:'`',"boulder",(10,08) -OBJECT:'`',"boulder",(11,08) -OBJECT:'`',"boulder",(06,10) -OBJECT:'`',"boulder",(05,11) -OBJECT:'`',"boulder",(06,11) -OBJECT:'`',"boulder",(07,11) -OBJECT:'`',"boulder",(21,11) -OBJECT:'`',"boulder",(21,12) -OBJECT:'`',"boulder",(13,13) -OBJECT:'`',"boulder",(14,13) -OBJECT:'`',"boulder",(15,13) -OBJECT:'`',"boulder",(14,14) +OBJECT:('`',"boulder"),(19,02) +OBJECT:('`',"boulder"),(20,02) +OBJECT:('`',"boulder"),(21,02) +OBJECT:('`',"boulder"),(36,02) +OBJECT:('`',"boulder"),(36,03) +OBJECT:('`',"boulder"),(06,04) +OBJECT:('`',"boulder"),(05,05) +OBJECT:('`',"boulder"),(06,05) +OBJECT:('`',"boulder"),(07,05) +OBJECT:('`',"boulder"),(39,05) +OBJECT:('`',"boulder"),(08,08) +OBJECT:('`',"boulder"),(09,08) +OBJECT:('`',"boulder"),(10,08) +OBJECT:('`',"boulder"),(11,08) +OBJECT:('`',"boulder"),(06,10) +OBJECT:('`',"boulder"),(05,11) +OBJECT:('`',"boulder"),(06,11) +OBJECT:('`',"boulder"),(07,11) +OBJECT:('`',"boulder"),(21,11) +OBJECT:('`',"boulder"),(21,12) +OBJECT:('`',"boulder"),(13,13) +OBJECT:('`',"boulder"),(14,13) +OBJECT:('`',"boulder"),(15,13) +OBJECT:('`',"boulder"),(14,14) # Doors DOOR:closed,(23,02) DOOR:open,(31,03) @@ -361,56 +365,56 @@ TRAP:"fire", random TRAP:"magic", random TRAP:"magic", random # Some random objects -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # The resident nasty -MONSTER:'&',"Orcus",(33,15) +MONSTER:('&',"Orcus"),(33,15) # And its preferred companions -MONSTER:'Z',"human zombie",(32,15) -MONSTER:' ',"shade",(32,14) -MONSTER:' ',"shade",(32,16) -MONSTER:'V',"vampire",(35,16) -MONSTER:'V',"vampire",(35,14) -MONSTER:'V',"vampire lord",(36,14) -MONSTER:'V',"vampire lord",(36,15) +MONSTER:('Z',"human zombie"),(32,15) +MONSTER:(' ',"shade"),(32,14) +MONSTER:(' ',"shade"),(32,16) +MONSTER:('V',"vampire"),(35,16) +MONSTER:('V',"vampire"),(35,14) +MONSTER:('V',"vampire lord"),(36,14) +MONSTER:('V',"vampire lord"),(36,15) # Randomly placed companions -MONSTER:'Z',"skeleton",random -MONSTER:'Z',"skeleton",random -MONSTER:'Z',"skeleton",random -MONSTER:'Z',"skeleton",random -MONSTER:'Z',"skeleton",random -MONSTER:' ',"shade",random -MONSTER:' ',"shade",random -MONSTER:' ',"shade",random -MONSTER:' ',"shade",random -MONSTER:'Z',"giant zombie",random -MONSTER:'Z',"giant zombie",random -MONSTER:'Z',"giant zombie",random -MONSTER:'Z',"ettin zombie",random -MONSTER:'Z',"ettin zombie",random -MONSTER:'Z',"ettin zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'Z',"human zombie",random -MONSTER:'V',"vampire",random -MONSTER:'V',"vampire",random -MONSTER:'V',"vampire",random -MONSTER:'V',"vampire lord",random -MONSTER:'V',"vampire lord",random +MONSTER:('Z',"skeleton"),random +MONSTER:('Z',"skeleton"),random +MONSTER:('Z',"skeleton"),random +MONSTER:('Z',"skeleton"),random +MONSTER:('Z',"skeleton"),random +MONSTER:(' ',"shade"),random +MONSTER:(' ',"shade"),random +MONSTER:(' ',"shade"),random +MONSTER:(' ',"shade"),random +MONSTER:('Z',"giant zombie"),random +MONSTER:('Z',"giant zombie"),random +MONSTER:('Z',"giant zombie"),random +MONSTER:('Z',"ettin zombie"),random +MONSTER:('Z',"ettin zombie"),random +MONSTER:('Z',"ettin zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('Z',"human zombie"),random +MONSTER:('V',"vampire"),random +MONSTER:('V',"vampire"),random +MONSTER:('V',"vampire"),random +MONSTER:('V',"vampire lord"),random +MONSTER:('V',"vampire lord"),random # A few more for the party -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random # # The Asmodeus Level # @@ -447,18 +451,18 @@ NON_DIGGABLE:(00,00,20,11) # Entire main area REGION:(01,01,20,10),unlit,"ordinary" # The fellow in residence -MONSTER:'&',"Asmodeus",(12,07) +MONSTER:('&',"Asmodeus"),(12,07) # Some random weapons and armor. -OBJECT:'[',random,random -OBJECT:'[',random,random -OBJECT:')',random,random -OBJECT:')',random,random -OBJECT:'*',random,random -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random +OBJECT:'[',random +OBJECT:'[',random +OBJECT:')',random +OBJECT:')',random +OBJECT:'*',random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'?',random # Some traps. TRAP:"spiked pit", (05,02) TRAP:"fire", (08,06) @@ -468,13 +472,13 @@ TRAP:"fire", random TRAP:"magic", random TRAP:"magic", random # Random monsters. -MONSTER:' ',"ghost",(11,07) -MONSTER:'&',"horned devil",(10,05) -MONSTER:'L',random,random +MONSTER:(' ',"ghost"),(11,07) +MONSTER:('&',"horned devil"),(10,05) +MONSTER:'L',random # Some Vampires for good measure -MONSTER:'V',random,random -MONSTER:'V',random,random -MONSTER:'V',random,random +MONSTER:'V',random +MONSTER:'V',random +MONSTER:'V',random # Second part GEOMETRY:half-right,center MAP @@ -488,9 +492,9 @@ MAZEWALK:(32,02),east # Non diggable walls NON_DIGGABLE:(00,00,32,04) DOOR:closed,(32,02) -MONSTER:'&',random,random -MONSTER:'&',random,random -MONSTER:'&',random,random +MONSTER:'&',random +MONSTER:'&',random +MONSTER:'&',random TRAP:"anti magic", random TRAP:"fire", random TRAP:"magic", random @@ -523,18 +527,18 @@ NON_DIGGABLE:(00,00,46,12) MAZEWALK:(00,06),west STAIR:(44,06),down # The fellow in residence -MONSTER:'&',"Baalzebub",(35,06) +MONSTER:('&',"Baalzebub"),(35,06) # Some random weapons and armor. -OBJECT:'[',random,random -OBJECT:'[',random,random -OBJECT:')',random,random -OBJECT:')',random,random -OBJECT:'*',random,random -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random +OBJECT:'[',random +OBJECT:'[',random +OBJECT:')',random +OBJECT:')',random +OBJECT:'*',random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'?',random # Some traps. TRAP:"spiked pit", random TRAP:"fire", random @@ -544,14 +548,14 @@ TRAP:"fire", random TRAP:"magic", random TRAP:"magic", random # Random monsters. -MONSTER:' ',"ghost",(37,07) -MONSTER:'&',"horned devil",(32,05) -MONSTER:'&',"barbed devil",(38,07) -MONSTER:'L',random,random +MONSTER:(' ',"ghost"),(37,07) +MONSTER:('&',"horned devil"),(32,05) +MONSTER:('&',"barbed devil"),(38,07) +MONSTER:'L',random # Some Vampires for good measure -MONSTER:'V',random,random -MONSTER:'V',random,random -MONSTER:'V',random,random +MONSTER:'V',random +MONSTER:'V',random +MONSTER:'V',random # # The Sanctum Level # @@ -582,7 +586,7 @@ MAP ENDMAP REGION:(15,07,21,10),lit,"temple" ALTAR:(18,08),noalign,sanctum -REGION:(41,06,48,11),unlit,"morgue",filled,true +REGION:(41,06,48,11),unlit,"morgue",filled,irregular # Non diggable walls NON_DIGGABLE:(00,00,75,19) # Invisible barrier separating the left & right halves of the level @@ -635,44 +639,44 @@ TRAP:"anti magic", random TRAP:"fire", random TRAP:"magic", random # Some random objects -OBJECT:'[',random,random -OBJECT:'[',random,random -OBJECT:'[',random,random -OBJECT:'[',random,random -OBJECT:')',random,random -OBJECT:')',random,random -OBJECT:'*',random,random -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random +OBJECT:'[',random +OBJECT:'[',random +OBJECT:'[',random +OBJECT:'[',random +OBJECT:')',random +OBJECT:')',random +OBJECT:'*',random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'?',random # Some monsters. -MONSTER:'&',"horned devil",(14,12),hostile -MONSTER:'&',"barbed devil",(18,08),hostile -MONSTER:'&',"erinys",(10,04),hostile -MONSTER:'&',"marilith",(07,09),hostile -MONSTER:'&',"nalfeshnee",(27,08),hostile +MONSTER:('&',"horned devil"),(14,12),hostile +MONSTER:('&',"barbed devil"),(18,08),hostile +MONSTER:('&',"erinys"),(10,04),hostile +MONSTER:('&',"marilith"),(07,09),hostile +MONSTER:('&',"nalfeshnee"),(27,08),hostile # Moloch's horde -MONSTER:'@',"aligned priest",(20,03),noalign,hostile -MONSTER:'@',"aligned priest",(15,04),noalign,hostile -MONSTER:'@',"aligned priest",(11,05),noalign,hostile -MONSTER:'@',"aligned priest",(11,07),noalign,hostile -MONSTER:'@',"aligned priest",(11,09),noalign,hostile -MONSTER:'@',"aligned priest",(11,12),noalign,hostile -MONSTER:'@',"aligned priest",(15,13),noalign,hostile -MONSTER:'@',"aligned priest",(17,13),noalign,hostile -MONSTER:'@',"aligned priest",(21,13),noalign,hostile +MONSTER:('@',"aligned priest"),(20,03),noalign,hostile +MONSTER:('@',"aligned priest"),(15,04),noalign,hostile +MONSTER:('@',"aligned priest"),(11,05),noalign,hostile +MONSTER:('@',"aligned priest"),(11,07),noalign,hostile +MONSTER:('@',"aligned priest"),(11,09),noalign,hostile +MONSTER:('@',"aligned priest"),(11,12),noalign,hostile +MONSTER:('@',"aligned priest"),(15,13),noalign,hostile +MONSTER:('@',"aligned priest"),(17,13),noalign,hostile +MONSTER:('@',"aligned priest"),(21,13),noalign,hostile # A few nasties -MONSTER:'L',random,random -MONSTER:'L',random,random -MONSTER:'V',random,random -MONSTER:'V',random,random -MONSTER:'V',random,random +MONSTER:'L',random +MONSTER:'L',random +MONSTER:'V',random +MONSTER:'V',random +MONSTER:'V',random STAIR:(63,15),up # Teleporting to this level is allowed after the invocation creates its # entrance. Force arrival in that case to be on rightmost third of level. diff --git a/dat/history b/dat/history index 0e15a079c..060982446 100644 --- a/dat/history +++ b/dat/history @@ -128,20 +128,20 @@ just before the release of NetHack 3.4.0 in March 2002. As with version 3.3, various people contributed to the game as a whole as well as supporting ports on the different platforms that NetHack runs on: -Pat Rankin maintained 3.5 for VMS. +Pat Rankin maintained 3.4 for VMS. -Michael Allison maintained NetHack 3.5 for the MS-DOS platform. +Michael Allison maintained NetHack 3.4 for the MS-DOS platform. Paul Winner and Yitzhak Sapir provided encouragement. Dean Luick, Mark Modrall, and Kevin Hugo maintained and enhanced the Macintosh port of 3.4. Michael Allison, David Cohrs, Alex Kompel, Dion Nicolaas, and Yitzhak Sapir -maintained and enhanced 3.5 for the Microsoft Windows platform. Alex Kompel +maintained and enhanced 3.4 for the Microsoft Windows platform. Alex Kompel contributed a new graphical interface for the Windows port. Alex Kompel also contributed a Windows CE port for 3.4.1. -Ron Van Iwaarden maintained 3.5 for OS/2. +Ron Van Iwaarden maintained 3.4 for OS/2. Janne Salmijarvi and Teemu Suikki maintained and enhanced the Amiga port of 3.5 after Janne Salmijarvi resurrected it for 3.3.1. @@ -174,7 +174,6 @@ At the beginning of development for what would eventually get released as 3.6.0, the development team consisted of Michael Allison, Warwick Allison, Ken Arromdee, David Cohrs, Jessie Collet, Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and Paul Winner. - Leading up to the release of 3.6.0 in early 2015, new members Sean Hunt, Pasi Kallinen, and Derek S. Ray joined the NetHack development team. @@ -211,7 +210,9 @@ people primarily responsible for the public NetHack servers available for playing the game at nethack.alt.org and devnull.net. In addition to providing a way for the public to play a game of NetHack from almost anywhere, they have hosted annual NetHack tournaments for many, many years. - write up something for Robin, M. Drew Streib, Pasi Kallinen + +On behalf of the NetHack community, thank you very much to +M. Drew Streib, Pasi Kallinen and Robin Bandy. - - - - - - - - - - @@ -220,11 +221,11 @@ particularly intriguing modification to help out with the game. The Gods of the Dungeon sometimes make note of the names of the worst of these miscreants in this, the list of Dungeoneers: - Adam Aronow Izchak Miller Mike Stephenson - Alex Kompel J. Ali Harlow Norm Meluch - Andreas Dorn Janet Walz Olaf Seibert - Andy Church Janne Salmijarvi Pasi Kallinen - Andy Swanson Jean-Christophe Collet Pat Rankin + Adam Aronow J. Ali Harlow Mike Stephenson + Alex Kompel Janet Walz Norm Meluch + Andreas Dorn Janne Salmijarvi Olaf Seibert + Andy Church Jean-Christophe Collet Pasi Kallinen + Andy Swanson Jeff Bailey Pat Rankin Ari Huttunen Jochen Erwied Paul Winner Barton House John Kallen Pierre Martineau Benson I. Margulies John Rupley Ralf Brown @@ -233,29 +234,30 @@ in this, the list of Dungeoneers: Bruce Cox Jon W{tte Richard Beigel Bruce Holloway Jonathan Handler Richard P. Hughey Bruce Mewborne Joshua Delahunty Rob Menke - Carl Schelin Keizo Yamamoto Robin Johnson - Chris Russo Ken Arnold Roderick Schertler - David Cohrs Ken Arromdee Roland McGrath - David Damerell Ken Lorber Ron Van Iwaarden - David Gentzel Ken Washikita Ronnen Miller - David Hairston Kevin Darcy Ross Brown - Dean Luick Kevin Hugo Sascha Wostmann - Del Lamb Kevin Sitze Scott Bigham - Derek S. Ray Kevin Smolkowski Scott R. Turner - Deron Meranda Kevin Sweet Sean Hunt - Dion Nicolaas Lars Huttar Stephen Spackman - Dylan O'Donnell Leon Arnott Stephen White - Eric Backus Malcolm Ryan Steve Creps - Eric Hendrickson Mark Gooderum Steve Linhart - Eric R. Smith Mark Modrall Steve VanDevender - Eric S. Raymond Marvin Bressler Teemu Suikki - Erik Andersen Matthew Day Tim Lennan - Frederick Roeber Merlyn LeRoy Timo Hakulinen - Gil Neiger Michael Allison Tom Almy - Greg Laskin Michael Feir Tom West - Greg Olson Michael Hamel Warren Cheung - Gregg Wonderly Michael Sokolov Warwick Allison - Hao-yang Wang Mike Engber Yitzhak Sapir - Helge Hafting Mike Gallop - Irina Rempt-Drijfhout Mike Passaretti + Carl Schelin Keizo Yamamoto Robin Bandy + Chris Russo Ken Arnold Robin Johnson + David Cohrs Ken Arromdee Roderick Schertler + David Damerell Ken Lorber Roland McGrath + David Gentzel Ken Washikita Ron Van Iwaarden + David Hairston Kevin Darcy Ronnen Miller + Dean Luick Kevin Hugo Ross Brown + Del Lamb Kevin Sitze Sascha Wostmann + Derek S. Ray Kevin Smolkowski Scott Bigham + Deron Meranda Kevin Sweet Scott R. Turner + Dion Nicolaas Lars Huttar Sean Hunt + Dylan O'Donnell Leon Arnott Stephen Spackman + Eric Backus M. Drew Streib Stephen White + Eric Hendrickson Malcolm Ryan Steve Creps + Eric R. Smith Mark Gooderum Steve Linhart + Eric S. Raymond Mark Modrall Steve VanDevender + Erik Andersen Marvin Bressler Teemu Suikki + Frederick Roeber Matthew Day Tim Lennan + Gil Neiger Merlyn LeRoy Timo Hakulinen + Greg Laskin Michael Allison Tom Almy + Greg Olson Michael Feir Tom West + Gregg Wonderly Michael Hamel Warren Cheung + Hao-yang Wang Michael Sokolov Warwick Allison + Helge Hafting Mike Engber Yitzhak Sapir + Irina Rempt-Drijfhout Mike Gallop + Izchak Miller Mike Passaretti diff --git a/dat/knox.des b/dat/knox.des index d9d1a2d4d..f9b9b3809 100644 --- a/dat/knox.des +++ b/dat/knox.des @@ -39,7 +39,7 @@ TELEPORT_REGION:(06,16,09,17),(0,0,0,0),up TELEPORT_REGION:(06,16,09,17),(0,0,0,0),down # Throne room, with Croesus on the throne REGION:(37,08,46,11),lit,"throne" -MONSTER:'@',"Croesus",(43,10),hostile +MONSTER:('@',"Croesus"),(43,10),hostile # The Vault # Using unfilled morgue for # identification in mkmaze.c @@ -50,12 +50,12 @@ REGION:(46,06,48,06),lit,"ordinary" REGION:(19,13,21,13),lit,"ordinary" REGION:(46,13,48,13),lit,"ordinary" # A welcoming committee -REGION:(03,10,07,13),lit,"zoo",filled,true +REGION:(03,10,07,13),lit,"zoo",filled,irregular # arrival chamber; needs to be a real room to control migrating monsters, # and `unfilled' is a kludge to force an ordinary room to remain a room REGION:(06,15,09,16),unlit,"ordinary",unfilled # Barracks -REGION:(62,03,71,04),lit,"barracks",filled,true +REGION:(62,03,71,04),lit,"barracks",filled,irregular # Doors DOOR:closed,(06,14) DOOR:closed,(09,03) @@ -67,43 +67,43 @@ DOOR:open,(68,11) DOOR:closed,(63,14) DOOR:closed,(66,14) # Soldiers guarding the fort -MONSTER:'@',"soldier",(12,14) -MONSTER:'@',"soldier",(12,13) -MONSTER:'@',"soldier",(11,10) -MONSTER:'@',"soldier",(13,02) -MONSTER:'@',"soldier",(14,03) -MONSTER:'@',"soldier",(20,02) -MONSTER:'@',"soldier",(30,02) -MONSTER:'@',"soldier",(40,02) -MONSTER:'@',"soldier",(30,16) -MONSTER:'@',"soldier",(32,16) -MONSTER:'@',"soldier",(40,16) -MONSTER:'@',"soldier",(54,16) -MONSTER:'@',"soldier",(54,14) -MONSTER:'@',"soldier",(54,13) -MONSTER:'@',"soldier",(57,10) -MONSTER:'@',"soldier",(57,09) -MONSTER:'@',"lieutenant",(15,08) +MONSTER:('@',"soldier"),(12,14) +MONSTER:('@',"soldier"),(12,13) +MONSTER:('@',"soldier"),(11,10) +MONSTER:('@',"soldier"),(13,02) +MONSTER:('@',"soldier"),(14,03) +MONSTER:('@',"soldier"),(20,02) +MONSTER:('@',"soldier"),(30,02) +MONSTER:('@',"soldier"),(40,02) +MONSTER:('@',"soldier"),(30,16) +MONSTER:('@',"soldier"),(32,16) +MONSTER:('@',"soldier"),(40,16) +MONSTER:('@',"soldier"),(54,16) +MONSTER:('@',"soldier"),(54,14) +MONSTER:('@',"soldier"),(54,13) +MONSTER:('@',"soldier"),(57,10) +MONSTER:('@',"soldier"),(57,09) +MONSTER:('@',"lieutenant"),(15,08) # Four dragons guarding each side -MONSTER:'D',random,(18,09) -MONSTER:'D',random,(49,10) -MONSTER:'D',random,(33,05) -MONSTER:'D',random,(33,14) +MONSTER:'D',(18,09) +MONSTER:'D',(49,10) +MONSTER:'D',(33,05) +MONSTER:'D',(33,14) # Eels in the moat -MONSTER:';',"giant eel",(17,08) -MONSTER:';',"giant eel",(17,11) -MONSTER:';',"giant eel",(48,08) -MONSTER:';',"giant eel",(48,11) +MONSTER:(';',"giant eel"),(17,08) +MONSTER:(';',"giant eel"),(17,11) +MONSTER:(';',"giant eel"),(48,08) +MONSTER:(';',"giant eel"),(48,11) # The corner rooms treasures -OBJECT:'*',"diamond",(19,06) -OBJECT:'*',"diamond",(20,06) -OBJECT:'*',"diamond",(21,06) -OBJECT:'*',"emerald",(19,13) -OBJECT:'*',"emerald",(20,13) -OBJECT:'*',"emerald",(21,13) -OBJECT:'*',"ruby",(46,06) -OBJECT:'*',"ruby",(47,06) -OBJECT:'*',"ruby",(48,06) -OBJECT:'*',"amethyst",(46,13) -OBJECT:'*',"amethyst",(47,13) -OBJECT:'*',"amethyst",(48,13) +OBJECT:('*',"diamond"),(19,06) +OBJECT:('*',"diamond"),(20,06) +OBJECT:('*',"diamond"),(21,06) +OBJECT:('*',"emerald"),(19,13) +OBJECT:('*',"emerald"),(20,13) +OBJECT:('*',"emerald"),(21,13) +OBJECT:('*',"ruby"),(46,06) +OBJECT:('*',"ruby"),(47,06) +OBJECT:('*',"ruby"),(48,06) +OBJECT:('*',"amethyst"),(46,13) +OBJECT:('*',"amethyst"),(47,13) +OBJECT:('*',"amethyst"),(48,13) diff --git a/dat/medusa.des b/dat/medusa.des index ae65ff6d5..48720d3ba 100644 --- a/dat/medusa.des +++ b/dat/medusa.des @@ -55,28 +55,29 @@ BRANCH:levregion(01,00,79,20),(30,06,46,13) # Non diggable walls NON_DIGGABLE:(30,06,46,13) # Objects -CONTAINER:'`',"statue",(36,10),uncursed,"knight",3,"Perseus" -OBJECT[75%]:'[',"shield of reflection",contained,cursed,+0 -OBJECT[25%]:'[',"levitation boots",contained,random,+0 -OBJECT[50%]:')',"scimitar",contained,blessed,+2 -OBJECT[50%]:'(',"sack",contained +CONTAINER:('`',"statue"),(36,10),uncursed,montype:"knight",3,name:"Perseus" { + [75%]: OBJECT:('[',"shield of reflection"),cursed,+0 + [25%]: OBJECT:('[',"levitation boots"),+0 + [50%]: OBJECT:(')',"scimitar"),blessed,+2 + [50%]: OBJECT:('(',"sack") +} # These aren't really containers, but specifying CONTAINER forces them to be # empty, since CONTAINERs contain only what is explicitly specified. -CONTAINER:'`',"statue",random -CONTAINER:'`',"statue",random -CONTAINER:'`',"statue",random -CONTAINER:'`',"statue",random -CONTAINER:'`',"statue",random -CONTAINER:'`',"statue",random -CONTAINER:'`',"statue",random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +CONTAINER:('`',"statue"),random { } +CONTAINER:('`',"statue"),random { } +CONTAINER:('`',"statue"),random { } +CONTAINER:('`',"statue"),random { } +CONTAINER:('`',"statue"),random { } +CONTAINER:('`',"statue"),random { } +CONTAINER:('`',"statue"),random { } +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -86,27 +87,27 @@ TRAP:random,random TRAP:"board",(38,07) TRAP:"board",(38,12) # Random monsters -MONSTER:'@',"Medusa",(36,10),asleep -MONSTER:';',"giant eel",(11,06) -MONSTER:';',"giant eel",(23,13) -MONSTER:';',"giant eel",(29,02) -MONSTER:';',"jellyfish",(02,02) -MONSTER:';',"jellyfish",(00,08) -MONSTER:';',"jellyfish",(04,18) -MONSTER:'T',"water troll",(51,03) -MONSTER:'T',"water troll",(64,11) -MONSTER:'S',random,(38,07) -MONSTER:'S',random,(38,12) -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random +MONSTER:('@',"Medusa"),(36,10),asleep +MONSTER:(';',"giant eel"),(11,06) +MONSTER:(';',"giant eel"),(23,13) +MONSTER:(';',"giant eel"),(29,02) +MONSTER:(';',"jellyfish"),(02,02) +MONSTER:(';',"jellyfish"),(00,08) +MONSTER:(';',"jellyfish"),(04,18) +MONSTER:('T',"water troll"),(51,03) +MONSTER:('T',"water troll"),(64,11) +MONSTER:'S',(38,07) +MONSTER:'S',(38,12) +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random MAZE:"medusa-2",' ' FLAGS: noteleport @@ -136,7 +137,7 @@ ENDMAP # Dungeon Description REGION:(00,00,74,19),lit,"ordinary" REGION:(02,03,05,16),unlit,"ordinary" -REGION:(61,03,72,16),unlit,"ordinary",unfilled,true +REGION:(61,03,72,16),unlit,"ordinary",unfilled,irregular REGION:(71,08,72,11),unlit,"ordinary" REGION:(67,08,69,11),lit,"ordinary" # Teleport: down to up stairs island, up to Medusa's island @@ -153,28 +154,29 @@ BRANCH:levregion(01,00,79,20),(59,01,73,17) NON_DIGGABLE:(01,02,06,17) NON_DIGGABLE:(60,02,73,17) # Objects -CONTAINER:'`',"statue",(68,10),uncursed,"knight",3,"Perseus" -OBJECT[25%]:'[',"shield of reflection",contained,cursed,+0 -OBJECT[75%]:'[',"levitation boots",contained,random,+0 -OBJECT[50%]:')',"scimitar",contained,blessed,+2 -OBJECT[50%]:'(',"sack",contained -CONTAINER:'`',"statue",(64,08) -CONTAINER:'`',"statue",(65,08) -CONTAINER:'`',"statue",(64,09) -CONTAINER:'`',"statue",(65,09) -CONTAINER:'`',"statue",(64,10) -CONTAINER:'`',"statue",(65,10) -CONTAINER:'`',"statue",(64,11) -CONTAINER:'`',"statue",(65,11) -OBJECT:'`',"boulder",(04,04) -OBJECT:'/',random,(52,09) -OBJECT:'`',"boulder",(52,09) -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +CONTAINER:('`',"statue"),(68,10),uncursed,montype:"knight",3,name:"Perseus" { + [25%]: OBJECT:('[',"shield of reflection"),cursed,+0 + [75%]: OBJECT:('[',"levitation boots"),+0 + [50%]: OBJECT:(')',"scimitar"),blessed,+2 + [50%]: OBJECT:('(',"sack") +} +CONTAINER:('`',"statue"),(64,08) { } +CONTAINER:('`',"statue"),(65,08) { } +CONTAINER:('`',"statue"),(64,09) { } +CONTAINER:('`',"statue"),(65,09) { } +CONTAINER:('`',"statue"),(64,10) { } +CONTAINER:('`',"statue"),(65,10) { } +CONTAINER:('`',"statue"),(64,11) { } +CONTAINER:('`',"statue"),(65,11) { } +OBJECT:('`',"boulder"),(04,04) +OBJECT:'/',(52,09) +OBJECT:('`',"boulder"),(52,09) +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Traps TRAP:"magic",(03,12) TRAP:random,random @@ -182,36 +184,36 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Monsters. -MONSTER:'@',"Medusa",(68,10),asleep -MONSTER:'g',"gremlin",(02,14) -MONSTER:'H',"titan",(02,05) -MONSTER:';',"electric eel",(10,13) -MONSTER:';',"electric eel",(11,13) -MONSTER:';',"electric eel",(10,14) -MONSTER:';',"electric eel",(11,14) -MONSTER:';',"electric eel",(10,15) -MONSTER:';',"electric eel",(11,15) -MONSTER:';',"jellyfish",(01,01) -MONSTER:';',"jellyfish",(00,08) -MONSTER:';',"jellyfish",(04,19) -MONSTER:''',"stone golem",(64,08),asleep -MONSTER:''',"stone golem",(65,08),asleep -MONSTER:''',"stone golem",(64,09),asleep -MONSTER:''',"stone golem",(65,09),asleep -MONSTER:'S',"cobra",(64,10),asleep -MONSTER:'S',"cobra",(65,10),asleep -MONSTER:'A',random,(72,08) -MONSTER:'y',"yellow light",(72,11),asleep -MONSTER:random,random,(17,07) -MONSTER:random,random,(28,11) -MONSTER:random,random,(32,13) -MONSTER:random,random,(49,09) -MONSTER:random,random,(48,07) -MONSTER:random,random,(65,03) -MONSTER:random,random,(70,04) -MONSTER:random,random,(70,15) -MONSTER:random,random,(65,16) -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random +MONSTER:('@',"Medusa"),(68,10),asleep +MONSTER:('g',"gremlin"),(02,14) +MONSTER:('H',"titan"),(02,05) +MONSTER:(';',"electric eel"),(10,13) +MONSTER:(';',"electric eel"),(11,13) +MONSTER:(';',"electric eel"),(10,14) +MONSTER:(';',"electric eel"),(11,14) +MONSTER:(';',"electric eel"),(10,15) +MONSTER:(';',"electric eel"),(11,15) +MONSTER:(';',"jellyfish"),(01,01) +MONSTER:(';',"jellyfish"),(00,08) +MONSTER:(';',"jellyfish"),(04,19) +MONSTER:(''',"stone golem"),(64,08),asleep +MONSTER:(''',"stone golem"),(65,08),asleep +MONSTER:(''',"stone golem"),(64,09),asleep +MONSTER:(''',"stone golem"),(65,09),asleep +MONSTER:('S',"cobra"),(64,10),asleep +MONSTER:('S',"cobra"),(65,10),asleep +MONSTER:'A',(72,08) +MONSTER:('y',"yellow light"),(72,11),asleep +MONSTER:random,(17,07) +MONSTER:random,(28,11) +MONSTER:random,(32,13) +MONSTER:random,(49,09) +MONSTER:random,(48,07) +MONSTER:random,(65,03) +MONSTER:random,(70,04) +MONSTER:random,(70,15) +MONSTER:random,(65,16) +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random diff --git a/dat/mines.des b/dat/mines.des index 8408bbd9d..c8be29d35 100644 --- a/dat/mines.des +++ b/dat/mines.des @@ -12,33 +12,33 @@ # specific levels as defined below. # MAZE: "minefill" , ' ' -INIT_MAP: '.' , ' ' , true , true , random , true +INIT_MAP: mines, '.' , ' ' , true , true , random , true NOMAP # STAIR: random, up STAIR: random, down # -OBJECT: '*', random, random -OBJECT: '*', random, random -OBJECT: '*', random, random -OBJECT: '(', random, random -OBJECT: random, random, random -OBJECT: random, random, random -OBJECT: random, random, random +OBJECT: '*', random +OBJECT: '*', random +OBJECT: '*', random +OBJECT: '(', random +OBJECT: random, random +OBJECT: random, random +OBJECT: random, random # -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome lord", random -MONSTER: 'h', "dwarf", random -MONSTER: 'h', "dwarf", random -MONSTER: 'G', random, random -MONSTER: 'G', random, random -MONSTER: 'h', random, random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome lord"), random +MONSTER: ('h', "dwarf"), random +MONSTER: ('h', "dwarf"), random +MONSTER: 'G', random +MONSTER: 'G', random +MONSTER: 'h', random # TRAP: random, random TRAP: random, random @@ -48,179 +48,254 @@ TRAP: random, random TRAP: random, random +# A tragic accident has occurred in Frontier Town.... +# # Minetown variant 1 -# "Frontier Town" +# Orcish Town - a variant of Frontier Town that has been +# overrun by orcs. Note the barricades (iron bars). # LEVEL: "minetn-1" +FLAGS:mazelevel +INIT_MAP:mines,'.',' ',true,true,random,true +GEOMETRY:center,center +MAP +..................................... +.----------------F------------------. +.|.................................|. +.|.-------------......------------.|. +.|.|...|...|...|......|..|...|...|.|. +.F.|...|...|...|......|..|...|...|.|. +.|.|...|...|...|......|..|...|...|.F. +.|.|...|...|----......------------.|. +.|.---------.......................|. +.|.................................|. +.|.---------.....--...--...........|. +.|.|...|...|----.|.....|.---------.|. +.|.|...|...|...|.|.....|.|..|....|.|. +.|.|...|...|...|.|.....|.|..|....|.|. +.|.|...|...|...|.|.....|.|..|....|.|. +.|.-------------.-------.---------.|. +.|.................................F. +.-----------F------------F----------. +..................................... +ENDMAP -ROOM: "ordinary" , lit, (3,3), (center,center), (31,15) -NAME: "town" -FOUNTAIN: (13, 7) -FOUNTAIN: (20, 7) +# Don't let the player fall into his likely death +TELEPORT_REGION:levregion(01,01,20,19),levregion(20,00,70,19) +REGION:(00,00,36,16),lit,"ordinary" +STAIR:levregion(01,03,20,19),(00,00,36,15),up +STAIR:levregion(61,03,75,19),(00,00,36,15),down -# The Town Watch -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watch captain", random, peaceful +# shame we can't make polluted fountains +FOUNTAIN:(16,09) +FOUNTAIN:(25,09) -SUBROOM: "shop" , lit, (2,2), (3,4), "town" -CHANCE: 90 -DOOR: false, closed, south, random +# the altar's defiled; useful for BUC but never coaligned +ALTAR:(20,13),noalign,shrine -SUBROOM: "tool shop", lit, (2,9), (3,4), "town" -CHANCE: 90 -DOOR: false, closed, north, random +# set up the shop doors; could be broken down +DOOR:random,(5,8) +DOOR:random,(9,8) +DOOR:random,(13,7) +DOOR:random,(22,5) +DOOR:random,(27,7) +DOOR:random,(31,7) +DOOR:random,(5,10) +DOOR:random,(9,10) +DOOR:random,(15,13) +DOOR:random,(25,13) +DOOR:random,(31,11) -SUBROOM: "ordinary", unlit, (6,2), (3,4), "town" -DOOR: false, closed, south, random +# knock a few holes in the shop interior walls +REPLACE_TERRAIN:(07,04,11,06),'|','.',18% +REPLACE_TERRAIN:(25,04,29,06),'|','.',18% +REPLACE_TERRAIN:(07,12,11,14),'|','.',18% +REPLACE_TERRAIN:(28,12,28,14),'|','.',33% -SUBROOM: "ordinary", lit, (6,9), (3,4), "town" -DOOR: false, closed, north, random +# One spot each in most shops... +$place = { (05,04),(09,05),(13,04),(26,04),(31,05),(30,14),(05,14),(10,13),(26,14),(27,13) } +SHUFFLE:$place -SUBROOM: "food shop", lit, (10,2), (2,3), "town" -CHANCE: 90 -DOOR: false, closed, south, random +# scatter some bodies +OBJECT:('%',"corpse"),(20,12),montype:"aligned priest" +OBJECT:('%',"corpse"),$place[0],montype:"shopkeeper" +OBJECT:('%',"corpse"),$place[1],montype:"shopkeeper" +OBJECT:('%',"corpse"),$place[2],montype:"shopkeeper" +OBJECT:('%',"corpse"),$place[3],montype:"shopkeeper" +OBJECT:('%',"corpse"),$place[4],montype:"shopkeeper" +OBJECT:('%',"corpse"),random,montype:"watchman" +OBJECT:('%',"corpse"),random,montype:"watchman" +OBJECT:('%',"corpse"),random,montype:"watchman" +OBJECT:('%',"corpse"),random,montype:"watchman" +OBJECT:('%',"corpse"),random,montype:"watch captain" -SUBROOM: "candle shop", lit, (22,2), (3,3), "town" -DOOR: false, closed, south, random +# Rubble! +LOOP [9 + 2d5] { + [90%]: OBJECT:('`',"boulder"),random + OBJECT:('*',"rock"),random +} -SUBROOM: "ordinary", unlit, (10,10), (2,3), "town" -DOOR: false, locked, east, random -MONSTER: 'G', "gnome", random +# Guarantee 7 candles since we won't have Izchak available +OBJECT:('(',"wax candle"),$place[0],quantity:1d2 +OBJECT:('(',"wax candle"),$place[1],quantity:2d2 +OBJECT:('(',"wax candle"),$place[2],quantity:1d2 +OBJECT:('(',"tallow candle"),$place[3],quantity:1d3 +OBJECT:('(',"tallow candle"),$place[2],quantity:1d2 +OBJECT:('(',"tallow candle"),$place[0],quantity:1d2 -SUBROOM: "ordinary", lit, (19,2), (2,3), "town" -DOOR: false, locked, west, random -MONSTER: 'G', "gnome", random +# go ahead and leave a lamp next to one corpse to be suggestive +# and some empty wands... +OBJECT:('(',"oil lamp"),$place[2] +OBJECT:('/',"striking"),$place[1],uncursed,0 +OBJECT:('/',"striking"),$place[3],uncursed,0 +OBJECT:('/',"striking"),$place[4],uncursed,0 +OBJECT:('/',"magic missile"),$place[4],uncursed,0 +OBJECT:('/',"magic missile"),$place[0],uncursed,0 -SUBROOM: "temple", lit, (15,9), (4,4), "town" -DOOR: false, closed, north, random -ALTAR:(02,02),align[0],shrine -MONSTER: 'G', "gnomish wizard", random -MONSTER: 'G', "gnomish wizard", random +# the Orcish Army -SUBROOM: "ordinary", lit, (22,10), (2,3), "town" -DOOR: false, locked, west, random +$inside = selection: floodfill(18,8) +$near_temple = selection: filter(fillrect(17,8, 23,14), $inside) -SUBROOM: "ordinary", lit, (26,2), (3,3), "town" -DOOR: false, closed, south, random -MONSTER: 'G', "gnome lord", random +LOOP [5 + 1d10] { + IF [50%] { + MONSTER: ('o', "orc-captain"), rndcoord($inside), hostile + } ELSE { + IF [80%] { + MONSTER: ('o', "Uruk-hai"), rndcoord($inside), hostile + } ELSE { + MONSTER: ('o', "Mordor orc"), rndcoord($inside), hostile + } + } +} +# shamans can be hanging out in/near the temple +LOOP [2d3] { + MONSTER: ('o', "orc shaman"), rndcoord($near_temple), hostile +} +# these are not such a big deal +# to run into outside the bars +LOOP [9 + 2d5] { + IF [90%] { + MONSTER: ('o', "hill orc"), random, hostile + } ELSE { + MONSTER: ('o', "goblin"), random, hostile + } +} -SUBROOM: "ordinary", unlit, (25,10), (4,3), "town" -DOOR: false, closed, north, random - -ROOM: "ordinary" , random, random, random, random -STAIR: random, up - -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -TRAP: random, random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random - -ROOM: "ordinary" , random, random, random, random -MONSTER: 'h', "dwarf", random - -ROOM: "ordinary" , random, random, random, random -TRAP: random, random -MONSTER: 'G', "gnome", random - -RANDOM_CORRIDORS +WALLIFY # Minetown variant 2 # "Town Square" # LEVEL: "minetn-2" -ROOM: "ordinary" , lit, (3,3), (center,center), (31,15) -NAME: "town" +ROOM: "ordinary" , lit, (3,3), (center,center), (31,15) { FOUNTAIN: (17, 5) FOUNTAIN: (13, 8) +SUBROOM: "ordinary", random, (2,0), (2,2) { + ROOMDOOR: false, closed, west, random +} + +SUBROOM: "ordinary", unlit, (5,0), (2,2) { + ROOMDOOR: false, closed, south, random +} + +SUBROOM: "ordinary", random, (8,0), (2,2) { + ROOMDOOR: false, closed, east, random +} + +SUBROOM: "ordinary", lit, (16,0), (2,2) { + ROOMDOOR: false, closed, west, random +} + +SUBROOM: "ordinary", unlit, (19,0), (2,2) { + ROOMDOOR: false, closed, south, random +} + +SUBROOM: "ordinary", random, (22,0), (2,2) { + ROOMDOOR: false, locked, south, random + MONSTER: ('G', "gnome"), random +} + +SUBROOM: "ordinary", unlit, (25,0), (2,2) { + ROOMDOOR: false, closed, east, random +} + +SUBROOM: "ordinary", lit, (2,5), (2,2) { + ROOMDOOR: false, closed, north, random +} + +SUBROOM: "ordinary", lit, (5,5), (2,2) { + ROOMDOOR: false, closed, south, random +} + +SUBROOM: "ordinary", random, (8,5), (2,2) { + ROOMDOOR: false, locked, north, random + MONSTER: ('G', "gnome"), random +} + +SUBROOM: "shop" [90%] , lit, (2,10), (4,3) { + ROOMDOOR: false, closed, west, random +} + +SUBROOM: "tool shop" [90%], lit, (23,10), (4,3) { + ROOMDOOR: false, closed, east, random +} + +SUBROOM: "food shop" [90%], lit, (24,5), (3,4) { + ROOMDOOR: false, closed, north, random +} + +SUBROOM: "candle shop", lit, (11,10), (4,3) { + ROOMDOOR: false, closed, east, random +} + +SUBROOM: "ordinary", unlit, (7,10), (3,3) { + ROOMDOOR: false, locked, north, random + MONSTER: ('G', "gnome"), random +} + +SUBROOM: "temple", lit, (19,5), (4,4) { + ROOMDOOR: false, closed, north, random + ALTAR:(02,02),align[0],shrine + MONSTER: ('G', "gnomish wizard"), random + MONSTER: ('G', "gnomish wizard"), random +} + +SUBROOM: "ordinary", lit, (18,10), (4,3) { + ROOMDOOR: false, locked, west, random + MONSTER: ('G', "gnome lord"), random +} + # The Town Watch -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watch captain", random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watch captain"), random, peaceful -SUBROOM: "ordinary", random, (2,0), (2,2), "town" -DOOR: false, closed, west, random +} -SUBROOM: "ordinary", unlit, (5,0), (2,2), "town" -DOOR: false, closed, south, random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up +} -SUBROOM: "ordinary", random, (8,0), (2,2), "town" -DOOR: false, closed, east, random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + TRAP: random, random + MONSTER: ('G', "gnome"), random + MONSTER: ('G', "gnome"), random +} -SUBROOM: "ordinary", lit, (16,0), (2,2), "town" -DOOR: false, closed, west, random +ROOM: "ordinary" , random, random, random, random { + MONSTER: ('h', "dwarf"), random +} -SUBROOM: "ordinary", unlit, (19,0), (2,2), "town" -DOOR: false, closed, south, random - -SUBROOM: "ordinary", random, (22,0), (2,2), "town" -DOOR: false, locked, south, random -MONSTER: 'G', "gnome", random - -SUBROOM: "ordinary", unlit, (25,0), (2,2), "town" -DOOR: false, closed, east, random - -SUBROOM: "ordinary", lit, (2,5), (2,2), "town" -DOOR: false, closed, north, random - -SUBROOM: "ordinary", lit, (5,5), (2,2), "town" -DOOR: false, closed, south, random - -SUBROOM: "ordinary", random, (8,5), (2,2), "town" -DOOR: false, locked, north, random -MONSTER: 'G', "gnome", random - -SUBROOM: "shop" , lit, (2,10), (4,3), "town" -CHANCE: 90 -DOOR: false, closed, west, random - -SUBROOM: "tool shop", lit, (23,10), (4,3), "town" -CHANCE: 90 -DOOR: false, closed, east, random - -SUBROOM: "food shop", lit, (24,5), (3,4), "town" -CHANCE: 90 -DOOR: false, closed, north, random - -SUBROOM: "candle shop", lit, (11,10), (4,3), "town" -DOOR: false, closed, east, random - -SUBROOM: "ordinary", unlit, (7,10), (3,3), "town" -DOOR: false, locked, north, random -MONSTER: 'G', "gnome", random - -SUBROOM: "temple", lit, (19,5), (4,4), "town" -DOOR: false, closed, north, random -ALTAR:(02,02),align[0],shrine -MONSTER: 'G', "gnomish wizard", random -MONSTER: 'G', "gnomish wizard", random - -SUBROOM: "ordinary", lit, (18,10), (4,3), "town" -DOOR: false, locked, west, random -MONSTER: 'G', "gnome lord", random - -ROOM: "ordinary" , random, random, random, random -STAIR: random, up - -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -TRAP: random, random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random - -ROOM: "ordinary" , random, random, random, random -MONSTER: 'h', "dwarf", random - -ROOM: "ordinary" , random, random, random, random -TRAP: random, random -MONSTER: 'G', "gnome", random +ROOM: "ordinary" , random, random, random, random { + TRAP: random, random + MONSTER: ('G', "gnome"), random +} RANDOM_CORRIDORS @@ -229,89 +304,107 @@ RANDOM_CORRIDORS # "Alley Town" # LEVEL: "minetn-3" -ROOM: "ordinary",lit,(3,3),(center,center),(31,15) -NAME: "town" +ROOM: "ordinary",lit,(3,3),(center,center),(31,15) { FOUNTAIN:(01,06) FOUNTAIN:(29,13) -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watch captain", random, peaceful -SUBROOM:"ordinary",random,(2,2),(2,2),"town" -DOOR: false,closed,south,random +SUBROOM:"ordinary",random,(2,2),(2,2) { + ROOMDOOR: false,closed,south,random +} -SUBROOM:"tool shop",lit,(5,3),(2,3),"town" -CHANCE: 30 -DOOR: false,closed,south,random +SUBROOM:"tool shop" [30%], lit,(5,3),(2,3) { + ROOMDOOR: false,closed,south,random +} -SUBROOM:"ordinary",random,(2,10),(2,3),"town" -DOOR: false, locked, north, random -MONSTER: 'G',random,random +SUBROOM:"ordinary",random,(2,10),(2,3) { + ROOMDOOR: false, locked, north, random + MONSTER: 'G',random +} -SUBROOM:"ordinary",random,(5,9),(2,2),"town" -DOOR: false,closed,north,random +SUBROOM:"ordinary",random,(5,9),(2,2) { + ROOMDOOR: false,closed,north,random +} -SUBROOM:"temple",lit,(10,2),(3,4),"town" -DOOR: false,closed,east,random -ALTAR:(1,1),align[0],shrine -MONSTER: 'G', "gnomish wizard", random -MONSTER: 'G', "gnomish wizard", random +SUBROOM:"temple",lit,(10,2),(3,4) { + ROOMDOOR: false,closed,east,random + ALTAR:(1,1),align[0],shrine + MONSTER: ('G', "gnomish wizard"), random + MONSTER: ('G', "gnomish wizard"), random +} -SUBROOM:"ordinary",random,(11,7),(2,2),"town" -DOOR: false,closed,west,random +SUBROOM:"ordinary",random,(11,7),(2,2) { + ROOMDOOR: false,closed,west,random +} -SUBROOM:"shop",lit,(10,10),(3,3),"town" -DOOR:false,closed,west,random +SUBROOM:"shop",lit,(10,10),(3,3) { + ROOMDOOR:false,closed,west,random +} -SUBROOM:"ordinary",random,(14,8),(2,2),"town" -DOOR:false,locked,north,random -MONSTER: 'G',random,random +SUBROOM:"ordinary",random,(14,8),(2,2) { + ROOMDOOR:false,locked,north,random + MONSTER: 'G',random +} -SUBROOM:"ordinary",random,(14,11),(2,2),"town" -DOOR:false,closed,south,random +SUBROOM:"ordinary",random,(14,11),(2,2) { + ROOMDOOR:false,closed,south,random +} -SUBROOM:"tool shop",lit,(17,10),(3,3),"town" -CHANCE:40 -DOOR:false,closed,north,random +SUBROOM:"tool shop" [40%],lit,(17,10),(3,3) { + ROOMDOOR:false,closed,north,random +} -SUBROOM:"ordinary",random,(21,11),(2,2),"town" -DOOR:false,locked,east,random -MONSTER:'G',random,random +SUBROOM:"ordinary",random,(21,11),(2,2) { + ROOMDOOR:false,locked,east,random + MONSTER:'G',random +} -SUBROOM:"food shop",lit,(26,8),(3,2),"town" -CHANCE:90 -DOOR:false,closed,west,random +SUBROOM:"food shop" [90%],lit,(26,8),(3,2) { + ROOMDOOR:false,closed,west,random +} -SUBROOM:"ordinary",random,(16,2),(2,2),"town" -DOOR:false,closed,west,random +SUBROOM:"ordinary",random,(16,2),(2,2) { + ROOMDOOR:false,closed,west,random +} -SUBROOM:"ordinary",random,(19,2),(2,2),"town" -DOOR:false,closed,north,random +SUBROOM:"ordinary",random,(19,2),(2,2) { + ROOMDOOR:false,closed,north,random +} -SUBROOM:"wand shop",lit,(19,5),(3,2),"town" -CHANCE:30 -DOOR:false,closed,west,random +SUBROOM:"wand shop" [30%],lit,(19,5),(3,2) { + ROOMDOOR:false,closed,west,random +} -SUBROOM: "candle shop",lit,(25,2),(3,3),"town" -DOOR:false,closed,south,random +SUBROOM: "candle shop",lit,(25,2),(3,3) { + ROOMDOOR:false,closed,south,random +} -ROOM: "ordinary", random, random, random, random -STAIR: random, up +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watch captain"), random, peaceful -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -TRAP: random, random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random +} -ROOM: "ordinary" , random, random, random, random -MONSTER: 'h', "dwarf", random +ROOM: "ordinary", random, random, random, random { + STAIR: random, up +} -ROOM: "ordinary" , random, random, random, random -TRAP: random, random -MONSTER: 'G', "gnome", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + TRAP: random, random + MONSTER: ('G', "gnome"), random + MONSTER: ('G', "gnome"), random +} + +ROOM: "ordinary" , random, random, random, random { + MONSTER: ('h', "dwarf"), random +} + +ROOM: "ordinary" , random, random, random, random { + TRAP: random, random + MONSTER: ('G', "gnome"), random +} RANDOM_CORRIDORS @@ -320,80 +413,95 @@ RANDOM_CORRIDORS # "College Town" # LEVEL: "minetn-4" -ROOM: "ordinary",lit,(3,3),(center,center),(30,15) -NAME: "town" +ROOM: "ordinary",lit,(3,3),(center,center),(30,15) { FOUNTAIN:(08,07) FOUNTAIN:(18,07) -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watch captain", random, peaceful -SUBROOM:"book shop",lit,(4,2),(3,3),"town" -DOOR: false,closed,south,random +SUBROOM:"book shop",lit,(4,2),(3,3) { + ROOMDOOR: false,closed,south,random +} -SUBROOM:"ordinary",random,(8,2),(2,2),"town" -DOOR: false,closed,south,random +SUBROOM:"ordinary",random,(8,2),(2,2) { + ROOMDOOR: false,closed,south,random +} -SUBROOM:"temple",lit,(11,3),(5,4),"town" -DOOR: false,closed,south,random -ALTAR:(2,1),align[0],shrine -MONSTER: 'G', "gnomish wizard", random -MONSTER: 'G', "gnomish wizard", random +SUBROOM:"temple",lit,(11,3),(5,4) { + ROOMDOOR: false,closed,south,random + ALTAR:(2,1),align[0],shrine + MONSTER: ('G', "gnomish wizard"), random + MONSTER: ('G', "gnomish wizard"), random +} -SUBROOM:"ordinary",random,(19,2),(2,2),"town" -DOOR: false,closed,south,random -MONSTER: 'G', random, random +SUBROOM:"ordinary",random,(19,2),(2,2) { + ROOMDOOR: false,closed,south,random + MONSTER: 'G', random +} -SUBROOM:"candle shop",lit,(22,2),(3,3),"town" -DOOR:false,closed,south,random +SUBROOM:"candle shop",lit,(22,2),(3,3) { + ROOMDOOR:false,closed,south,random +} -SUBROOM:"ordinary",random,(26,2),(2,2),"town" -DOOR:false,locked,east,random -MONSTER: 'G',random,random +SUBROOM:"ordinary",random,(26,2),(2,2) { + ROOMDOOR:false,locked,east,random + MONSTER: 'G',random +} -SUBROOM:"tool shop",lit,(4,10),(3,3),"town" -CHANCE:90 -DOOR:false,closed,north,random +SUBROOM:"tool shop" [90%],lit,(4,10),(3,3) { + ROOMDOOR:false,closed,north,random +} -SUBROOM:"ordinary",random,(8,11),(2,2),"town" -DOOR:false,locked,south,random -MONSTER: 'k',"kobold shaman",random -MONSTER: 'k',"kobold shaman",random -MONSTER: 'f',"kitten",random -MONSTER: 'f',random,random +SUBROOM:"ordinary",random,(8,11),(2,2) { + ROOMDOOR:false,locked,south,random + MONSTER: ('k',"kobold shaman"),random + MONSTER: ('k',"kobold shaman"),random + MONSTER: ('f',"kitten"),random + MONSTER: 'f',random +} -SUBROOM:"food shop",lit,(11,11),(3,2),"town" -CHANCE:90 -DOOR:false,closed,east,random +SUBROOM:"food shop" [90%],lit,(11,11),(3,2) { + ROOMDOOR:false,closed,east,random +} -SUBROOM:"ordinary",random,(17,11),(2,2),"town" -DOOR:false,closed,west,random +SUBROOM:"ordinary",random,(17,11),(2,2) { + ROOMDOOR:false,closed,west,random +} -SUBROOM:"ordinary",random,(20,10),(2,2),"town" -DOOR:false,locked,north,random -MONSTER:'G',random,random +SUBROOM:"ordinary",random,(20,10),(2,2) { + ROOMDOOR:false,locked,north,random + MONSTER:'G',random +} -SUBROOM:"shop",lit,(23,10),(3,3),"town" -CHANCE:90 -DOOR:false,closed,north,random +SUBROOM:"shop" [90%],lit,(23,10),(3,3) { + ROOMDOOR:false,closed,north,random +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, up +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watch captain"), random, peaceful -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -TRAP: random, random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random +} -ROOM: "ordinary" , random, random, random, random -MONSTER: 'h', "dwarf", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up +} -ROOM: "ordinary" , random, random, random, random -TRAP: random, random -MONSTER: 'G', "gnome", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + TRAP: random, random + MONSTER: ('G', "gnome"), random + MONSTER: ('G', "gnome"), random +} + +ROOM: "ordinary" , random, random, random, random { + MONSTER: ('h', "dwarf"), random +} + +ROOM: "ordinary" , random, random, random, random { + TRAP: random, random + MONSTER: ('G', "gnome"), random +} RANDOM_CORRIDORS @@ -442,22 +550,22 @@ REGION:(37,13,39,17),lit,"ordinary" REGION:(36,14,40,17),lit,"ordinary" REGION:(59,02,72,10),lit,"ordinary" -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watch captain", random, peaceful -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome lord", random -MONSTER: 'G', "gnome lord", random -MONSTER: 'h', "dwarf", random -MONSTER: 'h', "dwarf", random -MONSTER: 'h', "dwarf", random +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watch captain"), random, peaceful +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome lord"), random +MONSTER: ('G', "gnome lord"), random +MONSTER: ('h', "dwarf"), random +MONSTER: ('h', "dwarf"), random +MONSTER: ('h', "dwarf"), random # The shops REGION:(25,17,28,19),lit,"candle shop" @@ -471,14 +579,14 @@ DOOR:closed,(07,11) # Gnome homes DOOR:closed,(04,14) DOOR:locked,(01,17) -MONSTER: 'G', "gnomish wizard", (02,19) +MONSTER: ('G', "gnomish wizard"), (02,19) DOOR:locked,(20,16) -MONSTER: 'G', random, (20,18) +MONSTER: 'G', (20,18) DOOR:random,(21,14) DOOR:random,(25,14) DOOR:random,(42,08) DOOR:locked,(40,05) -MONSTER: 'G', random, (38,07) +MONSTER: 'G', (38,07) DOOR:random,(59,03) DOOR:random,(58,06) DOOR:random,(63,03) @@ -487,15 +595,15 @@ DOOR:locked,(71,03) DOOR:locked,(71,06) DOOR:closed,(69,04) DOOR:closed,(67,16) -MONSTER: 'G', "gnomish wizard", (67,14) -OBJECT: '=', random, (70,14) +MONSTER: ('G', "gnomish wizard"), (67,14) +OBJECT: '=', (70,14) DOOR:locked,(69,18) -MONSTER: 'G', "gnome lord", (71,19) +MONSTER: ('G', "gnome lord"), (71,19) DOOR:locked,(73,18) -OBJECT: '(', "chest", (73,19) +OBJECT: ('(', "chest"), (73,19) DOOR:locked,(50,06) -OBJECT: '(', random, (50,03) -OBJECT: '`', "statue", (38,15), "gnome king", 1 +OBJECT: '(', (50,03) +OBJECT: ('`', "statue"), (38,15), montype:"gnome king", 1 # Temple REGION:(29,02,33,04),lit,"temple" DOOR:closed,(31,05) @@ -505,7 +613,7 @@ ALTAR:(31,03),align[0],shrine # "Bustling Town" by Kelly Bailey # MAZE: "minetn-6",' ' -INIT_MAP:'.','-',true,true,lit,true +INIT_MAP:mines,'.','-',true,true,lit,true GEOMETRY:center,top MAP .-----................----------------.- @@ -557,135 +665,153 @@ DOOR:closed,(31,3) DOOR:closed,(35,3) DOOR:closed,(33,7) -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", (14,6) -MONSTER: 'G', "gnome lord", (14,5) -MONSTER: 'G', "gnome", (27,8) -MONSTER: 'G', "gnome lord", random -MONSTER: 'G', "gnome lord", random -MONSTER: 'h', "dwarf", random -MONSTER: 'h', "dwarf", random -MONSTER: 'h', "dwarf", random -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watch captain", random, peaceful -MONSTER: '@', "watch captain", random, peaceful +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), random +MONSTER: ('G', "gnome"), (14,6) +MONSTER: ('G', "gnome lord"), (14,5) +MONSTER: ('G', "gnome"), (27,8) +MONSTER: ('G', "gnome lord"), random +MONSTER: ('G', "gnome lord"), random +MONSTER: ('h', "dwarf"), random +MONSTER: ('h', "dwarf"), random +MONSTER: ('h', "dwarf"), random +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watch captain"), random, peaceful +MONSTER: ('@', "watch captain"), random, peaceful # "Bazaar Town" by Kelly Bailey # LEVEL: "minetn-7" -ROOM: "ordinary" , lit, (3,3), (center,center), (30,15) -NAME: "town" +ROOM: "ordinary" , lit, (3,3), (center,center), (30,15) { FOUNTAIN: (12, 07) FOUNTAIN: (11, 13) -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watchman", random, peaceful -MONSTER: '@', "watch captain", random, peaceful -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome lord",random -MONSTER:'Y',"monkey",random -MONSTER:'Y',"monkey",random +SUBROOM: "ordinary", random, (2,2), (4,2) { + ROOMDOOR: false, closed, south, random +} -SUBROOM: "ordinary", random, (2,2), (4,2), "town" -DOOR: false, closed, south, random +SUBROOM: "ordinary", random, (7,2), (2,2) { + ROOMDOOR: false, closed, north, random +} -SUBROOM: "ordinary", random, (7,2), (2,2), "town" -DOOR: false, closed, north, random +SUBROOM: "ordinary", random, (7,5), (2,2) { + ROOMDOOR: false, closed, south, random +} -SUBROOM: "ordinary", random, (7,5), (2,2), "town" -DOOR: false, closed, south, random +SUBROOM: "ordinary", lit, (10,2), (3,4) { + MONSTER:('G',"gnome"),random + MONSTER:('Y',"monkey"),random + MONSTER:('Y',"monkey"),random + MONSTER:('Y',"monkey"),random + ROOMDOOR: false, closed, south, random +} -SUBROOM: "ordinary", lit, (10,2), (3,4), "town" -MONSTER:'G',"gnome",random -MONSTER:'Y',"monkey",random -MONSTER:'Y',"monkey",random -MONSTER:'Y',"monkey",random -DOOR: false, closed, south, random +SUBROOM: "ordinary", random, (14,2), (4,2) { + ROOMDOOR: false, closed, south, 0 + MONSTER: 'n', random +} -SUBROOM: "ordinary", random, (14,2), (4,2), "town" -DOOR: false, closed, south, 0 -MONSTER: 'n', random, random +SUBROOM: "ordinary", random, (16,5), (2,2) { + ROOMDOOR: false, closed, south, random +} -SUBROOM: "ordinary", random, (16,5), (2,2), "town" -DOOR: false, closed, south, random +SUBROOM: "ordinary", unlit, (19,2), (2,2) { + ROOMDOOR: false, locked, east, random + MONSTER: ('G',"gnome king"),random +} -SUBROOM: "ordinary", unlit, (19,2), (2,2), "town" -DOOR: false, locked, east, random -MONSTER: 'G',"gnome king",random +SUBROOM: "food shop" [50%], lit, (19,5), (2,3) { + ROOMDOOR: false, closed, south, random +} -SUBROOM: "food shop", lit, (19,5), (2,3), "town" -CHANCE: 50 -DOOR: false, closed, south, random +SUBROOM: "ordinary", random, (2,7), (2,2) { + ROOMDOOR: false, closed, east, random +} -SUBROOM: "ordinary", random, (2,7), (2,2), "town" -DOOR: false, closed, east, random +SUBROOM: "tool shop" [50%], lit, (2,10), (2,3) { + ROOMDOOR: false, closed, south, random +} -SUBROOM: "tool shop", lit, (2,10), (2,3), "town" -CHANCE: 50 -DOOR: false, closed, south, random +SUBROOM: "candle shop", lit, (5,10),(3,3) { + ROOMDOOR: false, closed, north, random +} -SUBROOM: "candle shop", lit, (5,10),(3,3), "town" -DOOR: false, closed, north, random +SUBROOM: "ordinary", random, (11,10), (2,2) { + ROOMDOOR: false, locked, west, random + MONSTER: 'G',random +} -SUBROOM: "ordinary", random, (11,10), (2,2), "town" -DOOR: false, locked, west, random -MONSTER: 'G',random,random +SUBROOM: "shop" [60%], lit, (14,10), (2,3) { + ROOMDOOR: false, closed, north, random +} -SUBROOM: "shop", lit, (14,10), (2,3), "town" -CHANCE: 60 -DOOR: false, closed, north, random +SUBROOM: "ordinary", random, (17,11), (4,2) { + ROOMDOOR: false, closed, north, random +} -SUBROOM: "ordinary", random, (17,11), (4,2), "town" -DOOR: false, closed, north, random +SUBROOM: "ordinary", random, (22,11), (2,2) { + ROOMDOOR: false, closed, south, random + SINK: (00,00) +} -SUBROOM: "ordinary", random, (22,11), (2,2), "town" -DOOR: false, closed, south, random -SINK: (00,00) +SUBROOM: "food shop" [50%], lit, (25,11), (3,2) { + ROOMDOOR: false, closed, east, random +} -SUBROOM: "food shop", lit, (25,11), (3,2), "town" -CHANCE: 50 -DOOR: false, closed, east, random +SUBROOM: "tool shop" [30%], lit, (25,2), (3,3) { + ROOMDOOR: false, closed, west, random +} -SUBROOM: "tool shop", lit, (25,2), (3,3), "town" -CHANCE: 30 -DOOR: false, closed, west, random +SUBROOM: "temple", lit, (24,6), (4,4) { + ROOMDOOR: false, closed, west, random + ALTAR:(02,01),align[0],shrine + MONSTER: ('G', "gnomish wizard"), random + MONSTER: ('G', "gnomish wizard"), random +} -SUBROOM: "temple", lit, (24,6), (4,4), "town" -DOOR: false, closed, west, random -ALTAR:(02,01),align[0],shrine -MONSTER: 'G', "gnomish wizard", random -MONSTER: 'G', "gnomish wizard", random +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watchman"), random, peaceful +MONSTER: ('@', "watch captain"), random, peaceful +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome lord"),random +MONSTER:('Y',"monkey"),random +MONSTER:('Y',"monkey"),random -ROOM: "ordinary" , random, random, random, random -STAIR: random, up +} -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -TRAP: random, random -MONSTER: 'G', "gnome", random -MONSTER: 'G', "gnome", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up +} -ROOM: "ordinary" , random, random, random, random -MONSTER: 'h', "dwarf", random - -ROOM: "ordinary" , random, random, random, random -TRAP: random, random -MONSTER: 'G', "gnome", random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + TRAP: random, random + MONSTER: ('G', "gnome"), random + MONSTER: ('G', "gnome"), random +} + +ROOM: "ordinary" , random, random, random, random { + MONSTER: ('h', "dwarf"), random +} + +ROOM: "ordinary" , random, random, random, random { + TRAP: random, random + MONSTER: ('G', "gnome"), random +} RANDOM_CORRIDORS - + # Mine end level variant 1 # "Mimic of the Mines" @@ -715,8 +841,10 @@ MAP ENDMAP # Dungeon Description -RANDOM_PLACES:(08,16),(13,07),(21,08),(41,14),(50,04),(50,16),(66,01) -REGION:(26,01,32,01),unlit,"ordinary",filled,true +$place = { (08,16),(13,07),(21,08),(41,14),(50,04),(50,16),(66,01) } +SHUFFLE: $place + +REGION:(26,01,32,01),unlit,"ordinary",filled,irregular REGION:(20,08,21,08),unlit,"ordinary" REGION:(23,08,25,08),unlit,"ordinary" # Secret doors @@ -732,42 +860,42 @@ STAIR:(36,04),up # Non diggable walls NON_DIGGABLE:(00,00,74,17) # Niches -# Note: place[6] empty -OBJECT:'*',"diamond",place[0] -OBJECT:'*',"emerald",place[0] -OBJECT:'*',"worthless piece of violet glass",place[0] -MONSTER:'m',random,place[0], m_object "luckstone" -OBJECT:'*',"worthless piece of white glass",place[1] -OBJECT:'*',"emerald",place[1] -OBJECT:'*',"amethyst",place[1] -MONSTER:'m',random,place[1], m_object "loadstone" -OBJECT:'*',"diamond",place[2] -OBJECT:'*',"worthless piece of green glass",place[2] -OBJECT:'*',"amethyst",place[2] -MONSTER:'m',random,place[2], m_object "flint" -OBJECT:'*',"worthless piece of white glass",place[3] -OBJECT:'*',"emerald",place[3] -OBJECT:'*',"worthless piece of violet glass",place[3] -MONSTER:'m',random,place[3], m_object "touchstone" -OBJECT:'*',"worthless piece of red glass",place[4] -OBJECT:'*',"ruby",place[4] -OBJECT:'*',"loadstone",place[4] -OBJECT:'*',"ruby",place[5] -OBJECT:'*',"worthless piece of red glass",place[5] -OBJECT:'*',"luckstone",place[5] +# Note: $place[6] empty +OBJECT:('*',"diamond"),$place[0] +OBJECT:('*',"emerald"),$place[0] +OBJECT:('*',"worthless piece of violet glass"),$place[0] +MONSTER:'m',$place[0], m_object "luckstone" +OBJECT:('*',"worthless piece of white glass"),$place[1] +OBJECT:('*',"emerald"),$place[1] +OBJECT:('*',"amethyst"),$place[1] +MONSTER:'m',$place[1], m_object "loadstone" +OBJECT:('*',"diamond"),$place[2] +OBJECT:('*',"worthless piece of green glass"),$place[2] +OBJECT:('*',"amethyst"),$place[2] +MONSTER:'m',$place[2], m_object "flint" +OBJECT:('*',"worthless piece of white glass"),$place[3] +OBJECT:('*',"emerald"),$place[3] +OBJECT:('*',"worthless piece of violet glass"),$place[3] +MONSTER:'m',$place[3], m_object "touchstone" +OBJECT:('*',"worthless piece of red glass"),$place[4] +OBJECT:('*',"ruby"),$place[4] +OBJECT:('*',"loadstone"),$place[4] +OBJECT:('*',"ruby"),$place[5] +OBJECT:('*',"worthless piece of red glass"),$place[5] +OBJECT:('*',"luckstone"),$place[5] # Random objects -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'(',random,random -OBJECT:'(',random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'(',random +OBJECT:'(',random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -776,27 +904,27 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters -MONSTER:'G',"gnome king",random -MONSTER:'G',"gnome lord",random -MONSTER:'G',"gnome lord",random -MONSTER:'G',"gnome lord",random -MONSTER:'G',"gnomish wizard",random -MONSTER:'G',"gnomish wizard",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'h',"hobbit",random -MONSTER:'h',"hobbit",random -MONSTER:'h',"dwarf",random -MONSTER:'h',"dwarf",random -MONSTER:'h',"dwarf",random -MONSTER:'h',random,random +MONSTER:('G',"gnome king"),random +MONSTER:('G',"gnome lord"),random +MONSTER:('G',"gnome lord"),random +MONSTER:('G',"gnome lord"),random +MONSTER:('G',"gnomish wizard"),random +MONSTER:('G',"gnomish wizard"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('h',"hobbit"),random +MONSTER:('h',"hobbit"),random +MONSTER:('h',"dwarf"),random +MONSTER:('h',"dwarf"),random +MONSTER:('h',"dwarf"),random +MONSTER:'h',random # Mine end level variant 2 @@ -849,47 +977,47 @@ NON_DIGGABLE:(53,14,61,14) # the Trespassers sign is a long-running joke ENGRAVING:(12,03),engrave,"You are now entering the Gnome King's wine cellar." ENGRAVING:(12,04),engrave,"Trespassers will be persecuted!" -OBJECT:'!',"booze",(10,07) -OBJECT:'!',"booze",(10,07) -OBJECT:'!',random,(10,07) -OBJECT:'!',"booze",(10,08) -OBJECT:'!',"booze",(10,08) -OBJECT:'!',random,(10,08) -OBJECT:'!',"booze",(10,09) -OBJECT:'!',"booze",(10,09) -OBJECT:'!',"object detection",(10,09) +OBJECT:('!',"booze"),(10,07) +OBJECT:('!',"booze"),(10,07) +OBJECT:'!',(10,07) +OBJECT:('!',"booze"),(10,08) +OBJECT:('!',"booze"),(10,08) +OBJECT:'!',(10,08) +OBJECT:('!',"booze"),(10,09) +OBJECT:('!',"booze"),(10,09) +OBJECT:('!',"object detection"),(10,09) # Objects # The Treasure chamber... -OBJECT:'*',"diamond",(69,04) -OBJECT:'*',random,(69,04) -OBJECT:'*',"diamond",(69,04) -OBJECT:'*',random,(69,04) -OBJECT:'*',"emerald",(70,04) -OBJECT:'*',random,(70,04) -OBJECT:'*',"emerald",(70,04) -OBJECT:'*',random,(70,04) -OBJECT:'*',"emerald",(69,05) -OBJECT:'*',random,(69,05) -OBJECT:'*',"ruby",(69,05) -OBJECT:'*',random,(69,05) -OBJECT:'*',"ruby",(70,05) -OBJECT:'*',"amethyst",(70,05) -OBJECT:'*',random,(70,05) -OBJECT:'*',"amethyst",(70,05) -OBJECT:'*',"luckstone",(70,05) +OBJECT:('*',"diamond"),(69,04) +OBJECT:'*',(69,04) +OBJECT:('*',"diamond"),(69,04) +OBJECT:'*',(69,04) +OBJECT:('*',"emerald"),(70,04) +OBJECT:'*',(70,04) +OBJECT:('*',"emerald"),(70,04) +OBJECT:'*',(70,04) +OBJECT:('*',"emerald"),(69,05) +OBJECT:'*',(69,05) +OBJECT:('*',"ruby"),(69,05) +OBJECT:'*',(69,05) +OBJECT:('*',"ruby"),(70,05) +OBJECT:('*',"amethyst"),(70,05) +OBJECT:'*',(70,05) +OBJECT:('*',"amethyst"),(70,05) +OBJECT:('*',"luckstone"),(70,05) # Scattered gems... -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'*',random,random -OBJECT:'(',random,random -OBJECT:'(',random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'*',random +OBJECT:'(',random +OBJECT:'(',random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random # Random traps TRAP:random,random TRAP:random,random @@ -898,27 +1026,27 @@ TRAP:random,random TRAP:random,random TRAP:random,random # Random monsters. -MONSTER:'G',"gnome king",random -MONSTER:'G',"gnome lord",random -MONSTER:'G',"gnome lord",random -MONSTER:'G',"gnome lord",random -MONSTER:'G',"gnomish wizard",random -MONSTER:'G',"gnomish wizard",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'G',"gnome",random -MONSTER:'h',"hobbit",random -MONSTER:'h',"hobbit",random -MONSTER:'h',"dwarf",random -MONSTER:'h',"dwarf",random -MONSTER:'h',"dwarf",random -MONSTER:'h',random,random +MONSTER:('G',"gnome king"),random +MONSTER:('G',"gnome lord"),random +MONSTER:('G',"gnome lord"),random +MONSTER:('G',"gnome lord"),random +MONSTER:('G',"gnomish wizard"),random +MONSTER:('G',"gnomish wizard"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('G',"gnome"),random +MONSTER:('h',"hobbit"),random +MONSTER:('h',"hobbit"),random +MONSTER:('h',"dwarf"),random +MONSTER:('h',"dwarf"),random +MONSTER:('h',"dwarf"),random +MONSTER:'h',random # "Catacombs" by Kelly Bailey @@ -947,7 +1075,9 @@ MAP --|. - - - - - - - -- - - - -- . - - - --- - - - . . - - - - -- - - - - - - ENDMAP -RANDOM_PLACES:(1,15),(68,6),(1,13) +$place = { (1,15),(68,6),(1,13) } +SHUFFLE: $place + NON_DIGGABLE:(67,3,73,7) NON_DIGGABLE:(0,12,2,16) FOUNTAIN:(12,08) @@ -962,36 +1092,36 @@ MAZEWALK:(36,8),west STAIR:(42,8),up # Objects -OBJECT:'*',"diamond",random -OBJECT:'*',random,random -OBJECT:'*',"diamond",random -OBJECT:'*',random,random -OBJECT:'*',"emerald",random -OBJECT:'*',random,random -OBJECT:'*',"emerald",random -OBJECT:'*',random,random -OBJECT:'*',"emerald",random -OBJECT:'*',random,random -OBJECT:'*',"ruby",random -OBJECT:'*',random,random -OBJECT:'*',"ruby",random -OBJECT:'*',"amethyst",random -OBJECT:'*',random,random -OBJECT:'*',"amethyst",random -OBJECT:'*',"luckstone",place[0] -OBJECT:'*',"flint",place[1] -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'+',random,random -OBJECT:'+',random,random -OBJECT:'+',random,random -OBJECT:'+',random,random -OBJECT:random,random,random -OBJECT:random,random,random -OBJECT:random,random,random +OBJECT:('*',"diamond"),random +OBJECT:'*',random +OBJECT:('*',"diamond"),random +OBJECT:'*',random +OBJECT:('*',"emerald"),random +OBJECT:'*',random +OBJECT:('*',"emerald"),random +OBJECT:'*',random +OBJECT:('*',"emerald"),random +OBJECT:'*',random +OBJECT:('*',"ruby"),random +OBJECT:'*',random +OBJECT:('*',"ruby"),random +OBJECT:('*',"amethyst"),random +OBJECT:'*',random +OBJECT:('*',"amethyst"),random +OBJECT:('*',"luckstone"),$place[0] +OBJECT:('*',"flint"),$place[1] +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'+',random +OBJECT:'+',random +OBJECT:'+',random +OBJECT:'+',random +OBJECT:random,random +OBJECT:random,random +OBJECT:random,random TRAP:random,random TRAP:random,random TRAP:random,random @@ -1000,25 +1130,25 @@ TRAP:random,random TRAP:random,random TRAP:random,random # One-time annoyance factor -TRAP:"level teleport",place[0] -TRAP:"level teleport",place[1] -MONSTER:'M',random,random -MONSTER:'M',random,random -MONSTER:'M',random,random -MONSTER:'M',random,random -MONSTER:'M',random,random -MONSTER:'M',"ettin mummy",random -MONSTER:'V',random,random -MONSTER:'Z',random,random -MONSTER:'Z',random,random -MONSTER:'Z',random,random -MONSTER:'Z',random,random -MONSTER:'Z',random,random -MONSTER:'V',random,random -MONSTER:'e',random,random -MONSTER:'e',random,random -MONSTER:'e',random,random -MONSTER:'e',random,random +TRAP:"level teleport",$place[0] +TRAP:"level teleport",$place[1] +MONSTER:'M',random +MONSTER:'M',random +MONSTER:'M',random +MONSTER:'M',random +MONSTER:'M',random +MONSTER:('M',"ettin mummy"),random +MONSTER:'V',random +MONSTER:'Z',random +MONSTER:'Z',random +MONSTER:'Z',random +MONSTER:'Z',random +MONSTER:'Z',random +MONSTER:'V',random +MONSTER:'e',random +MONSTER:'e',random +MONSTER:'e',random +MONSTER:'e',random # end mines.des diff --git a/dat/opthelp b/dat/opthelp index 836e33d87..ce1d743cc 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -45,6 +45,7 @@ tombstone print tombstone when you die [TRUE] toptenwin print topten in a window rather than stdout [FALSE] travel enable the command to travel to a map location via [TRUE] a shortest-path algorithm, usually invoked by '_'. +use_darkgray use bold black instead of blue for black glyphs. [TRUE] use_inverse display detected monsters in highlighted manner [FALSE] verbose print more commentary during the game [TRUE] diff --git a/dat/oracle.des b/dat/oracle.des index 72da0401f..095b40928 100644 --- a/dat/oracle.des +++ b/dat/oracle.des @@ -8,51 +8,59 @@ LEVEL: "oracle" -ROOM: "ordinary" , lit, (3,3), (center,center), (11,9) -NAME: "central" -OBJECT:'`',"statue",(0,0),"forest centaur",1 -OBJECT:'`',"statue",(0,8),"mountain centaur",1 -OBJECT:'`',"statue",(10,0),"mountain centaur",1 -OBJECT:'`',"statue",(10,8),"forest centaur",1 -OBJECT:'`',"statue",(5,1),"plains centaur",1 -OBJECT:'`',"statue",(5,7),"plains centaur",1 -OBJECT:'`',"statue",(2,4),"plains centaur",1 -OBJECT:'`',"statue",(8,4),"plains centaur",1 -MONSTER: random, random, random -MONSTER: random, random, random +ROOM: "ordinary" , lit, (3,3), (center,center), (11,9) { + OBJECT:('`',"statue"),(0,0),montype:'C',1 + OBJECT:('`',"statue"),(0,8),montype:'C',1 + OBJECT:('`',"statue"),(10,0),montype:'C',1 + OBJECT:('`',"statue"),(10,8),montype:'C',1 + OBJECT:('`',"statue"),(5,1),montype:'C',1 + OBJECT:('`',"statue"),(5,7),montype:'C',1 + OBJECT:('`',"statue"),(2,4),montype:'C',1 + OBJECT:('`',"statue"),(8,4),montype:'C',1 -SUBROOM: "delphi" , lit , (4,3) , (3,3), "central" -FOUNTAIN: (0, 1) -FOUNTAIN: (1, 0) -FOUNTAIN: (1, 2) -FOUNTAIN: (2, 1) -MONSTER: '@', "Oracle", (1,1) -DOOR: false , nodoor , random, random + SUBROOM: "delphi" , lit , (4,3) , (3,3) { + FOUNTAIN: (0, 1) + FOUNTAIN: (1, 0) + FOUNTAIN: (1, 2) + FOUNTAIN: (2, 1) + MONSTER: ('@', "Oracle"), (1,1) + ROOMDOOR: false , nodoor , random, random + } -ROOM: "ordinary" , random, random, random, random -STAIR: random, up -OBJECT: random,random,random + MONSTER: random, random + MONSTER: random, random -ROOM: "ordinary" , random, random, random, random -STAIR: random, down -OBJECT: random, random, random -TRAP: random, random -MONSTER: random, random, random -MONSTER: random, random, random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -OBJECT: random, random, random -MONSTER: random, random, random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, up + OBJECT: random,random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: random, random, random +ROOM: "ordinary" , random, random, random, random { + STAIR: random, down + OBJECT: random, random + TRAP: random, random + MONSTER: random, random + MONSTER: random, random +} -ROOM: "ordinary" , random, random, random, random -OBJECT: random, random, random -TRAP: random, random -MONSTER: random, random, random +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + OBJECT: random, random + MONSTER: random, random +} + +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + MONSTER: random, random +} + +ROOM: "ordinary" , random, random, random, random { + OBJECT: random, random + TRAP: random, random + MONSTER: random, random +} RANDOM_CORRIDORS diff --git a/dat/sokoban.des b/dat/sokoban.des index 21eb63de5..343e895d6 100644 --- a/dat/sokoban.des +++ b/dat/sokoban.des @@ -35,7 +35,7 @@ ### Bottom (first) level of Sokoban ### MAZE:"soko4-1",' ' -FLAGS:noteleport,hardfloor +FLAGS:noteleport,hardfloor,premapped,solidify GEOMETRY:center,center #12345678901234567890123456789012345678901234567890 MAP @@ -60,18 +60,18 @@ NON_DIGGABLE:(00,00,13,12) NON_PASSWALL:(00,00,13,12) # Boulders -OBJECT:'`',"boulder",(02,02) -OBJECT:'`',"boulder",(02,03) +OBJECT:('`',"boulder"),(02,02) +OBJECT:('`',"boulder"),(02,03) # -OBJECT:'`',"boulder",(10,02) -OBJECT:'`',"boulder",(09,03) -OBJECT:'`',"boulder",(10,04) +OBJECT:('`',"boulder"),(10,02) +OBJECT:('`',"boulder"),(09,03) +OBJECT:('`',"boulder"),(10,04) # -OBJECT:'`',"boulder",(08,07) -OBJECT:'`',"boulder",(09,08) -OBJECT:'`',"boulder",(09,09) -OBJECT:'`',"boulder",(08,10) -OBJECT:'`',"boulder",(10,10) +OBJECT:('`',"boulder"),(08,07) +OBJECT:('`',"boulder"),(09,08) +OBJECT:('`',"boulder"),(09,09) +OBJECT:('`',"boulder"),(08,10) +OBJECT:('`',"boulder"),(10,10) # Traps TRAP:"pit",(03,06) @@ -85,20 +85,20 @@ TRAP:"pit",(06,10) TRAP:"pit",(07,10) # A little help -OBJECT:'?',"earth",(02,11) -OBJECT:'?',"earth",(03,11) +OBJECT:('?',"earth"),(02,11) +OBJECT:('?',"earth"),(03,11) # Random objects -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'=',random,random -OBJECT:'/',random,random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'=',random +OBJECT:'/',random MAZE:"soko4-2",' ' -FLAGS:noteleport,hardfloor +FLAGS:noteleport,hardfloor,premapped,solidify GEOMETRY:center,center #12345678901234567890123456789012345678901234567890 MAP @@ -121,20 +121,20 @@ NON_DIGGABLE:(00,00,14,10) NON_PASSWALL:(00,00,14,10) # Boulders -OBJECT:'`',"boulder",(05,02) -OBJECT:'`',"boulder",(06,02) -OBJECT:'`',"boulder",(06,03) -OBJECT:'`',"boulder",(07,03) +OBJECT:('`',"boulder"),(05,02) +OBJECT:('`',"boulder"),(06,02) +OBJECT:('`',"boulder"),(06,03) +OBJECT:('`',"boulder"),(07,03) # -OBJECT:'`',"boulder",(09,05) -OBJECT:'`',"boulder",(10,03) -OBJECT:'`',"boulder",(11,02) -OBJECT:'`',"boulder",(12,03) +OBJECT:('`',"boulder"),(09,05) +OBJECT:('`',"boulder"),(10,03) +OBJECT:('`',"boulder"),(11,02) +OBJECT:('`',"boulder"),(12,03) # -OBJECT:'`',"boulder",(07,08) -OBJECT:'`',"boulder",(08,08) -OBJECT:'`',"boulder",(09,08) -OBJECT:'`',"boulder",(10,08) +OBJECT:('`',"boulder"),(07,08) +OBJECT:('`',"boulder"),(08,08) +OBJECT:('`',"boulder"),(09,08) +OBJECT:('`',"boulder"),(10,08) # Traps TRAP:"pit",(01,02) @@ -149,21 +149,21 @@ TRAP:"pit",(05,08) TRAP:"pit",(06,08) # A little help -OBJECT:'?',"earth",(01,09) -OBJECT:'?',"earth",(02,09) +OBJECT:('?',"earth"),(01,09) +OBJECT:('?',"earth"),(02,09) # Random objects -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'=',random,random -OBJECT:'/',random,random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'=',random +OBJECT:'/',random ### Second level ### MAZE:"soko3-1",' ' -FLAGS:noteleport +FLAGS:noteleport,premapped,solidify GEOMETRY:center,center #12345678901234567890123456789012345678901234567890 MAP @@ -188,29 +188,29 @@ NON_DIGGABLE:(00,00,28,11) NON_PASSWALL:(00,00,28,11) # Boulders -OBJECT:'`',"boulder",(03,02) -OBJECT:'`',"boulder",(04,02) +OBJECT:('`',"boulder"),(03,02) +OBJECT:('`',"boulder"),(04,02) # -OBJECT:'`',"boulder",(06,02) -OBJECT:'`',"boulder",(06,03) -OBJECT:'`',"boulder",(07,02) +OBJECT:('`',"boulder"),(06,02) +OBJECT:('`',"boulder"),(06,03) +OBJECT:('`',"boulder"),(07,02) # -OBJECT:'`',"boulder",(03,06) -OBJECT:'`',"boulder",(02,07) -OBJECT:'`',"boulder",(03,07) -OBJECT:'`',"boulder",(03,08) -OBJECT:'`',"boulder",(02,09) -OBJECT:'`',"boulder",(03,09) -OBJECT:'`',"boulder",(04,09) +OBJECT:('`',"boulder"),(03,06) +OBJECT:('`',"boulder"),(02,07) +OBJECT:('`',"boulder"),(03,07) +OBJECT:('`',"boulder"),(03,08) +OBJECT:('`',"boulder"),(02,09) +OBJECT:('`',"boulder"),(03,09) +OBJECT:('`',"boulder"),(04,09) # -OBJECT:'`',"boulder",(06,07) -OBJECT:'`',"boulder",(06,09) -OBJECT:'`',"boulder",(08,07) -OBJECT:'`',"boulder",(08,10) -OBJECT:'`',"boulder",(09,08) -OBJECT:'`',"boulder",(09,09) -OBJECT:'`',"boulder",(10,07) -OBJECT:'`',"boulder",(10,10) +OBJECT:('`',"boulder"),(06,07) +OBJECT:('`',"boulder"),(06,09) +OBJECT:('`',"boulder"),(08,07) +OBJECT:('`',"boulder"),(08,10) +OBJECT:('`',"boulder"),(09,08) +OBJECT:('`',"boulder"),(09,09) +OBJECT:('`',"boulder"),(10,07) +OBJECT:('`',"boulder"),(10,10) # Traps TRAP:"hole",(12,10) @@ -230,16 +230,16 @@ TRAP:"hole",(25,10) TRAP:"hole",(26,10) # Random objects -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'=',random,random -OBJECT:'/',random,random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'=',random +OBJECT:'/',random MAZE:"soko3-2",' ' -FLAGS:noteleport +FLAGS:noteleport,premapped,solidify GEOMETRY:center,center #12345678901234567890123456789012345678901234567890 MAP @@ -266,22 +266,22 @@ NON_DIGGABLE:(00,00,25,13) NON_PASSWALL:(00,00,25,13) # Boulders -OBJECT:'`',"boulder",(02,03) -OBJECT:'`',"boulder",(08,03) -OBJECT:'`',"boulder",(09,04) -OBJECT:'`',"boulder",(02,05) -OBJECT:'`',"boulder",(04,05) -OBJECT:'`',"boulder",(09,05) -OBJECT:'`',"boulder",(02,06) -OBJECT:'`',"boulder",(05,06) -OBJECT:'`',"boulder",(06,07) -OBJECT:'`',"boulder",(03,08) -OBJECT:'`',"boulder",(07,08) -OBJECT:'`',"boulder",(05,09) -OBJECT:'`',"boulder",(10,09) -OBJECT:'`',"boulder",(07,10) -OBJECT:'`',"boulder",(10,10) -OBJECT:'`',"boulder",(03,11) +OBJECT:('`',"boulder"),(02,03) +OBJECT:('`',"boulder"),(08,03) +OBJECT:('`',"boulder"),(09,04) +OBJECT:('`',"boulder"),(02,05) +OBJECT:('`',"boulder"),(04,05) +OBJECT:('`',"boulder"),(09,05) +OBJECT:('`',"boulder"),(02,06) +OBJECT:('`',"boulder"),(05,06) +OBJECT:('`',"boulder"),(06,07) +OBJECT:('`',"boulder"),(03,08) +OBJECT:('`',"boulder"),(07,08) +OBJECT:('`',"boulder"),(05,09) +OBJECT:('`',"boulder"),(10,09) +OBJECT:('`',"boulder"),(07,10) +OBJECT:('`',"boulder"),(10,10) +OBJECT:('`',"boulder"),(03,11) # Traps TRAP:"hole",(12,10) @@ -298,17 +298,17 @@ TRAP:"hole",(22,10) TRAP:"hole",(23,10) # Random objects -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'=',random,random -OBJECT:'/',random,random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'=',random +OBJECT:'/',random ### Third level ### MAZE:"soko2-1",' ' -FLAGS:noteleport +FLAGS:noteleport,premapped,solidify GEOMETRY:center,center #12345678901234567890123456789012345678901234567890 MAP @@ -333,23 +333,23 @@ NON_DIGGABLE:(00,00,19,11) NON_PASSWALL:(00,00,19,11) # Boulders -OBJECT:'`',"boulder",(02,02) -OBJECT:'`',"boulder",(03,02) +OBJECT:('`',"boulder"),(02,02) +OBJECT:('`',"boulder"),(03,02) # -OBJECT:'`',"boulder",(05,03) -OBJECT:'`',"boulder",(07,03) -OBJECT:'`',"boulder",(07,02) -OBJECT:'`',"boulder",(08,02) +OBJECT:('`',"boulder"),(05,03) +OBJECT:('`',"boulder"),(07,03) +OBJECT:('`',"boulder"),(07,02) +OBJECT:('`',"boulder"),(08,02) # -OBJECT:'`',"boulder",(10,03) -OBJECT:'`',"boulder",(11,03) +OBJECT:('`',"boulder"),(10,03) +OBJECT:('`',"boulder"),(11,03) # -OBJECT:'`',"boulder",(02,07) -OBJECT:'`',"boulder",(02,08) -OBJECT:'`',"boulder",(03,09) +OBJECT:('`',"boulder"),(02,07) +OBJECT:('`',"boulder"),(02,08) +OBJECT:('`',"boulder"),(03,09) # -OBJECT:'`',"boulder",(05,07) -OBJECT:'`',"boulder",(06,06) +OBJECT:('`',"boulder"),(05,07) +OBJECT:('`',"boulder"),(06,06) # Traps TRAP:"hole",(08,09) @@ -364,16 +364,16 @@ TRAP:"hole",(16,09) TRAP:"hole",(17,09) # Random objects -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'=',random,random -OBJECT:'/',random,random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'=',random +OBJECT:'/',random MAZE:"soko2-2",' ' -FLAGS:noteleport +FLAGS:noteleport,premapped,solidify GEOMETRY:center,center #12345678901234567890123456789012345678901234567890 MAP @@ -399,22 +399,22 @@ NON_DIGGABLE:(00,00,19,12) NON_PASSWALL:(00,00,19,12) # Boulders -OBJECT:'`',"boulder",(04,02) -OBJECT:'`',"boulder",(04,03) -OBJECT:'`',"boulder",(05,03) -OBJECT:'`',"boulder",(07,03) -OBJECT:'`',"boulder",(08,03) -OBJECT:'`',"boulder",(02,04) -OBJECT:'`',"boulder",(03,04) -OBJECT:'`',"boulder",(05,05) -OBJECT:'`',"boulder",(06,06) -OBJECT:'`',"boulder",(09,06) -OBJECT:'`',"boulder",(03,07) -OBJECT:'`',"boulder",(04,07) -OBJECT:'`',"boulder",(07,07) -OBJECT:'`',"boulder",(06,09) -OBJECT:'`',"boulder",(05,10) -OBJECT:'`',"boulder",(05,11) +OBJECT:('`',"boulder"),(04,02) +OBJECT:('`',"boulder"),(04,03) +OBJECT:('`',"boulder"),(05,03) +OBJECT:('`',"boulder"),(07,03) +OBJECT:('`',"boulder"),(08,03) +OBJECT:('`',"boulder"),(02,04) +OBJECT:('`',"boulder"),(03,04) +OBJECT:('`',"boulder"),(05,05) +OBJECT:('`',"boulder"),(06,06) +OBJECT:('`',"boulder"),(09,06) +OBJECT:('`',"boulder"),(03,07) +OBJECT:('`',"boulder"),(04,07) +OBJECT:('`',"boulder"),(07,07) +OBJECT:('`',"boulder"),(06,09) +OBJECT:('`',"boulder"),(05,10) +OBJECT:('`',"boulder"),(05,11) # Traps TRAP:"hole",(07,11) @@ -430,17 +430,17 @@ TRAP:"hole",(16,11) TRAP:"hole",(17,11) # Random objects -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'=',random,random -OBJECT:'/',random,random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'=',random +OBJECT:'/',random ### Top (last) level of Sokoban ### MAZE:"soko1-1",' ' -FLAGS:noteleport +FLAGS:noteleport,premapped,solidify GEOMETRY:center,center #12345678901234567890123456789012345678901234567890 MAP @@ -463,34 +463,36 @@ MAP |...|----- --|.....| ----- ------- ENDMAP -RANDOM_PLACES:(16,11),(16,13),(16,15) +$place = { (16,11),(16,13),(16,15) } +SHUFFLE: $place + STAIR:(01,01),down REGION:(00,00,25,17),lit,"ordinary" NON_DIGGABLE:(00,00,25,17) NON_PASSWALL:(00,00,25,17) # Boulders -OBJECT:'`',"boulder",(03,05) -OBJECT:'`',"boulder",(05,05) -OBJECT:'`',"boulder",(07,05) -OBJECT:'`',"boulder",(09,05) -OBJECT:'`',"boulder",(11,05) +OBJECT:('`',"boulder"),(03,05) +OBJECT:('`',"boulder"),(05,05) +OBJECT:('`',"boulder"),(07,05) +OBJECT:('`',"boulder"),(09,05) +OBJECT:('`',"boulder"),(11,05) # -OBJECT:'`',"boulder",(04,07) -OBJECT:'`',"boulder",(04,08) -OBJECT:'`',"boulder",(06,07) -OBJECT:'`',"boulder",(09,07) -OBJECT:'`',"boulder",(11,07) +OBJECT:('`',"boulder"),(04,07) +OBJECT:('`',"boulder"),(04,08) +OBJECT:('`',"boulder"),(06,07) +OBJECT:('`',"boulder"),(09,07) +OBJECT:('`',"boulder"),(11,07) # -OBJECT:'`',"boulder",(03,12) -OBJECT:'`',"boulder",(04,10) -OBJECT:'`',"boulder",(05,12) -OBJECT:'`',"boulder",(06,10) -OBJECT:'`',"boulder",(07,11) -OBJECT:'`',"boulder",(08,10) -OBJECT:'`',"boulder",(09,12) +OBJECT:('`',"boulder"),(03,12) +OBJECT:('`',"boulder"),(04,10) +OBJECT:('`',"boulder"),(05,12) +OBJECT:('`',"boulder"),(06,10) +OBJECT:('`',"boulder"),(07,11) +OBJECT:('`',"boulder"),(08,10) +OBJECT:('`',"boulder"),(09,12) # -OBJECT:'`',"boulder",(03,14) +OBJECT:('`',"boulder"),(03,14) # Traps TRAP:"hole",(08,01) @@ -510,29 +512,33 @@ TRAP:"hole",(21,01) TRAP:"hole",(22,01) TRAP:"hole",(23,01) -MONSTER:'m',"giant mimic", random, m_object "boulder" -MONSTER:'m',"giant mimic", random, m_object "boulder" +MONSTER:('m',"giant mimic"), random, m_object "boulder" +MONSTER:('m',"giant mimic"), random, m_object "boulder" # Random objects -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'=',random,random -OBJECT:'/',random,random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'=',random +OBJECT:'/',random # Rewards DOOR:locked,(23,13) DOOR:closed,(17,11) DOOR:closed,(17,13) DOOR:closed,(17,15) -REGION:(18,10,22,16),lit,"zoo",filled,true -OBJECT:'(',"bag of holding",place[0] -ENGRAVING:place[0],burn,"Elbereth" +REGION:(18,10,22,16),lit,"zoo",filled,irregular +IF [50%] { + OBJECT:('(',"bag of holding"),$place[0] +} ELSE { + OBJECT:('"',"amulet of reflection"),$place[0] +} +ENGRAVING:$place[0],burn,"Elbereth" MAZE:"soko1-2",' ' -FLAGS:noteleport +FLAGS:noteleport,premapped,solidify GEOMETRY:center,center #12345678901234567890123456789012345678901234567890 MAP @@ -554,35 +560,37 @@ MAP |..|..| --|.....| ------- ------- ENDMAP -RANDOM_PLACES:(16,10),(16,12),(16,14) +$place = { (16,10),(16,12),(16,14) } +SHUFFLE: $place + STAIR:(06,15),down REGION:(00,00,25,16),lit,"ordinary" NON_DIGGABLE:(00,00,25,16) NON_PASSWALL:(00,00,25,16) # Boulders -OBJECT:'`',"boulder",(04,04) -OBJECT:'`',"boulder",(02,06) -OBJECT:'`',"boulder",(03,06) -OBJECT:'`',"boulder",(04,07) -OBJECT:'`',"boulder",(05,07) -OBJECT:'`',"boulder",(02,08) -OBJECT:'`',"boulder",(05,08) -OBJECT:'`',"boulder",(03,09) -OBJECT:'`',"boulder",(04,09) -OBJECT:'`',"boulder",(03,10) -OBJECT:'`',"boulder",(05,10) -OBJECT:'`',"boulder",(06,12) +OBJECT:('`',"boulder"),(04,04) +OBJECT:('`',"boulder"),(02,06) +OBJECT:('`',"boulder"),(03,06) +OBJECT:('`',"boulder"),(04,07) +OBJECT:('`',"boulder"),(05,07) +OBJECT:('`',"boulder"),(02,08) +OBJECT:('`',"boulder"),(05,08) +OBJECT:('`',"boulder"),(03,09) +OBJECT:('`',"boulder"),(04,09) +OBJECT:('`',"boulder"),(03,10) +OBJECT:('`',"boulder"),(05,10) +OBJECT:('`',"boulder"),(06,12) # -OBJECT:'`',"boulder",(07,14) +OBJECT:('`',"boulder"),(07,14) # -OBJECT:'`',"boulder",(11,05) -OBJECT:'`',"boulder",(12,06) -OBJECT:'`',"boulder",(10,07) -OBJECT:'`',"boulder",(11,07) -OBJECT:'`',"boulder",(10,08) -OBJECT:'`',"boulder",(12,09) -OBJECT:'`',"boulder",(11,10) +OBJECT:('`',"boulder"),(11,05) +OBJECT:('`',"boulder"),(12,06) +OBJECT:('`',"boulder"),(10,07) +OBJECT:('`',"boulder"),(11,07) +OBJECT:('`',"boulder"),(10,08) +OBJECT:('`',"boulder"),(12,09) +OBJECT:('`',"boulder"),(11,10) # Traps TRAP:"hole",(05,01) @@ -604,22 +612,26 @@ TRAP:"hole",(20,01) TRAP:"hole",(21,01) TRAP:"hole",(22,01) -MONSTER:'m',"giant mimic", random, m_object "boulder" -MONSTER:'m',"giant mimic", random, m_object "boulder" +MONSTER:('m',"giant mimic"), random, m_object "boulder" +MONSTER:('m',"giant mimic"), random, m_object "boulder" # Random objects -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'%',random,random -OBJECT:'=',random,random -OBJECT:'/',random,random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'%',random +OBJECT:'=',random +OBJECT:'/',random # Rewards DOOR:locked,(23,12) DOOR:closed,(17,10) DOOR:closed,(17,12) DOOR:closed,(17,14) -REGION:(18,09,22,15),lit,"zoo",filled,true -OBJECT:'"',"amulet of reflection",place[0] -ENGRAVING:place[0],burn,"Elbereth" +REGION:(18,09,22,15),lit,"zoo",filled,irregular +IF [50%] { + OBJECT:('(',"bag of holding"),$place[0] +} ELSE { + OBJECT:('"',"amulet of reflection"),$place[0] +} +ENGRAVING:$place[0],burn,"Elbereth" diff --git a/dat/tower.des b/dat/tower.des index eb017247d..eeef1f46b 100644 --- a/dat/tower.des +++ b/dat/tower.des @@ -6,7 +6,7 @@ # # Upper stage of Vlad's tower MAZE:"tower1",' ' -FLAGS: noteleport,hardfloor +FLAGS: noteleport,hardfloor,solidify GEOMETRY:half-left,center MAP --- --- --- @@ -23,13 +23,13 @@ MAP ENDMAP LADDER:(11,05),down # The lord and his court -MONSTER:'V',"Vlad the Impaler",(06,05) -MONSTER:'V',random,(03,09) -MONSTER:'V',random,(07,09) -MONSTER:'V',random,(11,09) -MONSTER:'V',random,(03,01) -MONSTER:'V',random,(07,01) -MONSTER:'V',random,(11,01) +MONSTER:('V',"Vlad the Impaler"),(06,05) +MONSTER:'V',(03,09) +MONSTER:'V',(07,09) +MONSTER:'V',(11,09) +MONSTER:'V',(03,01) +MONSTER:'V',(07,01) +MONSTER:'V',(11,01) # The doors DOOR:closed,(08,03) DOOR:closed,(10,03) @@ -39,20 +39,20 @@ DOOR:locked,(08,07) DOOR:locked,(10,07) DOOR:closed,(03,06) # treasures -OBJECT:'(',"chest",(07,05) -OBJECT:'(',"chest",(03,09) -OBJECT:'(',"chest",(07,09) -OBJECT:'(',"chest",(11,09) -OBJECT:'(',"chest",(03,01) -OBJECT:'(',"chest",(07,01) -OBJECT:'(',"chest",(11,01) +OBJECT:('(',"chest"),(07,05) +OBJECT:('(',"chest"),(03,09) +OBJECT:('(',"chest"),(07,09) +OBJECT:('(',"chest"),(11,09) +OBJECT:('(',"chest"),(03,01) +OBJECT:('(',"chest"),(07,01) +OBJECT:('(',"chest"),(11,01) # We have to protect the tower against outside attacks NON_DIGGABLE:(00,00,14,10) # Intermediate stage of Vlad's tower MAZE:"tower2",' ' -FLAGS: noteleport,hardfloor +FLAGS: noteleport,hardfloor,solidify GEOMETRY:half-left,center MAP --- --- --- @@ -68,31 +68,34 @@ MAP --- --- --- ENDMAP # Random places are the 10 niches -RANDOM_PLACES:(03,01),(07,01),(11,01),(01,03),(13,03), - (01,07),(13,07),(03,09),(07,09),(11,09) +$place = { (03,01),(07,01),(11,01),(01,03),(13,03), + (01,07),(13,07),(03,09),(07,09),(11,09) } +SHUFFLE: $place LADDER:(11,05),up LADDER:(03,07),down DOOR:locked,(10,04) DOOR:locked,(09,07) -MONSTER:'&',random,place[0] -MONSTER:'&',random,place[1] -MONSTER:'d',"hell hound pup",place[2] -MONSTER:'d',"hell hound pup",place[3] -MONSTER:'d',"winter wolf",place[4] -CONTAINER:'(',"chest",place[5] -OBJECT:'"',"amulet of life saving",contained -CONTAINER:'(',"chest",place[6] -OBJECT:'"',"amulet of strangulation",contained -OBJECT:'[',"water walking boots",place[7] -OBJECT:'[',"crystal plate mail",place[8] -OBJECT:'+',"invisibility",place[9] +MONSTER:'&',$place[0] +MONSTER:'&',$place[1] +MONSTER:('d',"hell hound pup"),$place[2] +MONSTER:('d',"hell hound pup"),$place[3] +MONSTER:('d',"winter wolf"),$place[4] +CONTAINER:('(',"chest"),$place[5] { + OBJECT:('"',"amulet of life saving") +} +CONTAINER:('(',"chest"),$place[6] { + OBJECT:('"',"amulet of strangulation") +} +OBJECT:('[',"water walking boots"),$place[7] +OBJECT:('[',"crystal plate mail"),$place[8] +OBJECT:('+',"invisibility"),$place[9] # Walls in the tower are non diggable NON_DIGGABLE:(00,00,14,10) # Bottom most stage of Vlad's tower MAZE:"tower3",' ' -FLAGS: noteleport,hardfloor +FLAGS: noteleport,hardfloor,solidify GEOMETRY:half-left,center MAP --- --- --- @@ -110,29 +113,30 @@ MAP --------------- ENDMAP # Random places are the 10 niches -RANDOM_PLACES:(05,01),(09,01),(13,01),(03,03),(15,03), - (03,07),(15,07),(05,09),(09,09),(13,09) +$place = { (05,01),(09,01),(13,01),(03,03),(15,03), + (03,07),(15,07),(05,09),(09,09),(13,09) } +SHUFFLE: $place BRANCH:(02,05,02,05),(00,00,00,00) LADDER:(05,07),up # Entry door is, of course, locked DOOR:locked,(14,05) # Let's put a dragon behind the door, just for the fun... -MONSTER:'D',random,(13,05) -MONSTER:random,random,(12,04) -MONSTER:random,random,(12,06) -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -MONSTER:random,random,random -OBJECT:')',"long sword",place[0] -TRAP:random,place[0] -OBJECT:'(',"lock pick",place[1] -TRAP:random,place[1] -OBJECT:'[',"elven cloak",place[2] -TRAP:random,place[2] -OBJECT:'(',"blindfold",place[3] -TRAP:random,place[3] +MONSTER:'D',(13,05) +MONSTER:random,(12,04) +MONSTER:random,(12,06) +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +MONSTER:random,random +OBJECT:(')',"long sword"),$place[0] +TRAP:random,$place[0] +OBJECT:('(',"lock pick"),$place[1] +TRAP:random,$place[1] +OBJECT:('[',"elven cloak"),$place[2] +TRAP:random,$place[2] +OBJECT:('(',"blindfold"),$place[3] +TRAP:random,$place[3] # Walls in the tower are non diggable NON_DIGGABLE:(00,00,18,12) diff --git a/dat/yendor.des b/dat/yendor.des index 6bef30231..dcb77c986 100644 --- a/dat/yendor.des +++ b/dat/yendor.des @@ -48,29 +48,29 @@ NON_PASSWALL:(11,00,21,00) NON_PASSWALL:(11,10,27,12) NON_PASSWALL:(21,00,27,10) # The wizard and his guards -MONSTER:'@',"Wizard of Yendor",(16,05),asleep -MONSTER:'d',"hell hound",(15,05) -MONSTER:'V',"vampire lord",(17,05) +MONSTER:('@',"Wizard of Yendor"),(16,05),asleep +MONSTER:('d',"hell hound"),(15,05) +MONSTER:('V',"vampire lord"),(17,05) # The local treasure -OBJECT:'+',"Book of the Dead",(16,05) +OBJECT:('+',"Book of the Dead"),(16,05) # Surrounding terror -MONSTER:';',"kraken",(14,02) -MONSTER:';',"giant eel",(17,02) -MONSTER:';',"kraken",(13,04) -MONSTER:';',"giant eel",(13,06) -MONSTER:';',"kraken",(19,04) -MONSTER:';',"giant eel",(19,06) -MONSTER:';',"kraken",(15,08) -MONSTER:';',"giant eel",(17,08) -MONSTER:';',"piranha",(15,02) -MONSTER:';',"piranha",(19,08) +MONSTER:(';',"kraken"),(14,02) +MONSTER:(';',"giant eel"),(17,02) +MONSTER:(';',"kraken"),(13,04) +MONSTER:(';',"giant eel"),(13,06) +MONSTER:(';',"kraken"),(19,04) +MONSTER:(';',"giant eel"),(19,06) +MONSTER:(';',"kraken"),(15,08) +MONSTER:(';',"giant eel"),(17,08) +MONSTER:(';',"piranha"),(15,02) +MONSTER:(';',"piranha"),(19,08) # Random monsters -MONSTER:'D',random,random -MONSTER:'H',random,random -MONSTER:'&',random,random -MONSTER:'&',random,random -MONSTER:'&',random,random -MONSTER:'&',random,random +MONSTER:'D',random +MONSTER:'H',random +MONSTER:'&',random +MONSTER:'&',random +MONSTER:'&',random +MONSTER:'&',random # And to make things a little harder. TRAP:"board",(16,04) TRAP:"board",(16,06) @@ -82,14 +82,14 @@ TRAP:"sleep gas",random TRAP:"anti magic",random TRAP:"magic",random # Some random loot. -OBJECT:'*',"ruby",random -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'+',random,random -OBJECT:'+',random,random -OBJECT:'+',random,random +OBJECT:('*',"ruby"),random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'+',random +OBJECT:'+',random +OBJECT:'+',random # The middle wizard level. @@ -136,13 +136,13 @@ TRAP:"sleep gas",random TRAP:"anti magic",random TRAP:"magic",random # Some random loot. -OBJECT:'!',random,random -OBJECT:'!',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'+',random,random +OBJECT:'!',random +OBJECT:'!',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'+',random # treasures -OBJECT:'"',random,(04,06) +OBJECT:'"',(04,06) # The bottom wizard level. @@ -191,33 +191,33 @@ NON_PASSWALL:(06,00,27,02) NON_PASSWALL:(16,02,27,12) NON_PASSWALL:(06,12,16,12) # -MONSTER:'L',random,(10,07) -MONSTER:'V',"vampire lord",(12,07) +MONSTER:'L',(10,07) +MONSTER:('V',"vampire lord"),(12,07) # Some surrounding horrors -MONSTER:';',"kraken",(08,05) -MONSTER:';',"giant eel",(08,08) -MONSTER:';',"kraken",(14,05) -MONSTER:';',"giant eel",(14,08) +MONSTER:(';',"kraken"),(08,05) +MONSTER:(';',"giant eel"),(08,08) +MONSTER:(';',"kraken"),(14,05) +MONSTER:(';',"giant eel"),(14,08) # Other monsters -MONSTER:'L',random,random -MONSTER:'D',random,random -MONSTER:'D',random,(26,09) -MONSTER:'&',random,random -MONSTER:'&',random,random -MONSTER:'&',random,random +MONSTER:'L',random +MONSTER:'D',random +MONSTER:'D',(26,09) +MONSTER:'&',random +MONSTER:'&',random +MONSTER:'&',random # And to make things a little harder. TRAP:"board",(10,07) TRAP:"board",(12,07) TRAP:"board",(11,06) TRAP:"board",(11,08) # Some loot -OBJECT:')',random,random -OBJECT:'!',random,random -OBJECT:'?',random,random -OBJECT:'?',random,random -OBJECT:'(',random,random +OBJECT:')',random +OBJECT:'!',random +OBJECT:'?',random +OBJECT:'?',random +OBJECT:'(',random # treasures -OBJECT:'"',random,(11,07) +OBJECT:'"',(11,07) # The former decoy wizard levels. @@ -241,10 +241,10 @@ BRANCH:levregion(01,00,79,20),(0,0,8,7) TELEPORT_REGION:levregion(01,00,79,20),(2,2,6,6) PORTAL:(4,4,4,4),(0,0,0,0),"wizard3" MAZEWALK:(08,05),east -REGION:(04,03,06,06),unlit,"ordinary",unfilled,true -MONSTER:'L',random,(04,04) -MONSTER:'V',"vampire lord",(03,04) -MONSTER:';',"kraken",(06,06) +REGION:(04,03,06,06),unlit,"ordinary",unfilled,irregular +MONSTER:'L',(04,04) +MONSTER:('V',"vampire lord"),(03,04) +MONSTER:(';',"kraken"),(06,06) # And to make things a little harder. TRAP:"board",(04,03) TRAP:"board",(04,05) @@ -269,14 +269,14 @@ STAIR:levregion(01,00,79,20),(0,0,8,7),down BRANCH:levregion(01,00,79,20),(0,0,8,7) TELEPORT_REGION:levregion(01,00,79,20),(2,2,6,6) MAZEWALK:(08,05),east -REGION:(04,03,06,06),unlit,"ordinary",unfilled,true -MONSTER:'L',random,(04,04) -MONSTER:'V',"vampire lord",(03,04) -MONSTER:';',"kraken",(06,06) +REGION:(04,03,06,06),unlit,"ordinary",unfilled,irregular +MONSTER:'L',(04,04) +MONSTER:('V',"vampire lord"),(03,04) +MONSTER:(';',"kraken"),(06,06) # And to make things a little harder. TRAP:"board",(04,03) TRAP:"board",(04,05) TRAP:"board",(03,04) TRAP:"board",(05,04) # treasures -OBJECT:'"',random,(04,04) +OBJECT:'"',(04,04) diff --git a/doc/.gitattributes b/doc/.gitattributes index 9ca881076..a9a06f4c8 100644 --- a/doc/.gitattributes +++ b/doc/.gitattributes @@ -1,5 +1,5 @@ -*.mn filter=NHtext merge=NHsubst -*.6 filter=NHtext merge=NHsubst -fixes.* filter=NHtext merge=NHsubst -window.doc filter=NHtext merge=NHsubst +*.mn NHSUBST +*.6 NHSUBST +fixes.* NHSUBST +window.doc NHSUBST diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 0b2e5cf3b..89dee0ae0 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,12 +1,12 @@ .\" $NHDT-Branch$:$NHDT-Revision$ $NHDT-Date$ -.\" $Revision: 1.130 $ $Date: 2012/05/02 00:38:30 $ +.\" $Revision: 1.130 $ $Date: 2015/03/27 00:38:30 $ .ds h0 "NetHack Guidebook .ds h1 .ds h2 % .ds vr "NetHack 3.6 .ds f0 "\*(vr .ds f1 -.ds f2 "March 16, 2015 +.ds f2 "March 27, 2015 .\" labeled paragraph start (should be part of tmac.n, but I don't want to .\" make changes to that file) .\" .PS word @@ -710,12 +710,6 @@ the exchange still takes place. .lp X Toggle two-weapon combat, if your character can do it. Also available via the ``#twoweapon'' extended command -.lp "" -Since using this command by accident would be troublesome, you are asked -to confirm your intent before switching to explore mode. By default -the response 'y' acknowledges that intent. You can set the -.op paraniod_confirmation -option to require a response of "yes" instead. .lp ^X Display basic information about your character. .lp "" @@ -848,7 +842,7 @@ You probably shouldn't start off a new game by praying right away.) Since using this command by accident can cause trouble, there is an option to make you confirm your intent before praying. It is enabled by default, and you can reset the -.op paraniod_confirmation +.op paranoid_confirmation option to disable it. .lp #quit Quit the program without saving your game. @@ -856,7 +850,7 @@ Quit the program without saving your game. Since using this command by accident would throw away the current game, you are asked to confirm your intent before quitting. By default a response of 'y' acknowledges that intent. You can set the -.op paraniod_confirmation +.op paranoid_confirmation option to require a response of "yes" instead. .lp #ride Ride (or stop riding) a monster. @@ -1138,7 +1132,7 @@ In most circumstances, if you attempt to attack a peaceful monster by moving into its location, you'll be asked to confirm your intent. By default an answer of 'y' acknowledges that intent, which can be error prone if you're using 'y' to move. You can set the -.op paraniod_confirmation +.op paranoid_confirmation option to require a response of "yes" instead. .pg If you can't see a monster (if it is invisible, or if you are blinded), @@ -1927,6 +1921,8 @@ quality of the weapon; you are free to manually fill your quiver or quiver sack or make ready with the `Q' command instead. If no weapon is found or the option is false, the `t' (throw) command is executed instead. (default false) +.lp blind +Start the character permanently blind. (default false) .lp bones Allow saving and loading bones files. (default true) .lp boulder @@ -2053,6 +2049,11 @@ Enable mail delivery during the game (default on). .lp "male " An obsolete synonym for ``gender:male''. Cannot be set with the `O' command. +.lp mention_walls +Give feedback when walking against a wall (default off). +.lp menucolors +Enable coloring menu lines (default off). +See ``Configuring Menu Colors'' on how to configure the colors. .lp menustyle Controls the interface used when you need to choose various objects (in response to the Drop command, for instance). The value specified should @@ -2098,6 +2099,9 @@ Default '|'. Menu character accelerator to goto the next menu page. Implemented by the Amiga, Gem and tty ports. Default '>'. +.lp menu_objsyms +Show object symbols in menu headings in menus where +the object symbols act as menu accelerators (default off). .lp menu_previous_page Menu character accelerator to goto the previous menu page. Implemented by the Amiga, Gem and tty ports. @@ -2144,6 +2148,8 @@ Cannot be set with the `O' command. Read the NetHack news file, if present (default on). Since the news is shown at the beginning of the game, there's no point in setting this with the `O' command. +.lp nudist +Start the character with no armor (default false). .lp "null " Send padding nulls to the terminal (default on). .lp number_pad @@ -2170,7 +2176,7 @@ is the same as specifying 0. (Settings 2 and 4 are for compatibility with MSDOS or old PC Hack; in addition to the different behavior for `5', `Alt-5' acts as `G' and `Alt-0' acts as `I'. -Setting -1 is to accomodate some German keyboards which have the +Setting -1 is to accommodate some German keyboards which have the location of the `y' and `z' keys swapped.) When moving by numbers, to enter a count prefix for those commands which accept one (such as ``12s'' to search twelve times), precede it @@ -2454,6 +2460,8 @@ Specify the name of an alternative tile file to override the default. Specify the preferred height of each tile in a tile capable port. .lp tile_width Specify the preferred width of each tile in a tile capable port +.lp use_darkgray +Use bold black instead of blue for black glyphs (TTY only). .lp use_inverse NetHack should display inverse when the game specifies it. .lp vary_msgcount @@ -2599,6 +2607,56 @@ The second example results in the exclusion of any corpse from autopickup. The last example results in the exclusion of items known to be cursed from autopickup. .hn 2 +Configuring Menu Colors +.pg +Some platforms allow you to define colors used in menu lines when the +line matches a user-defined pattern. At this time the tty, win32tty and +win32gui support this. +.pg +In general, the config file entries to configure the menu color mappings +look like this: +.si +.lp MENUCOLOR="pattern"=color&attribute +.ei +.PS "menu color" +.PL pattern +the pattern to match; +.PL color +the color to use for lines matching the pattern; +.PL attribute +the attribute to use for lines matching the pattern. The attribute is +optional, and if left out, you must also leave out the preceding ampersand. +If no attribute is defined, no attribute is used. +.PE +.lp "" +For explanation on pattern format and the matching routines, see +the pattern in the ``Configuring User Sounds'' -section. +.lp "" +Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, +orange, lightgreen, yellow, lightblue, lightmagenta, lightcyan, and white. +.lp "" +Allowed attributes are none, bold, dim, underline, blink, and inverse. +Note that the platform used may interpret the attributes any way it +wants. +.lp "" +Here's an example of menu colors using NetHack's internal +pattern matching facility: +.sd +.si +MENUCOLOR="* blessed *"=green +MENUCOLOR="* cursed *"=red +MENUCOLOR="* cursed *(being worn)"=red&underline +.ei +.ed +specifies that any menu line with " blessed " contained +in it will be shown in green color, lines with " cursed " will be +shown in red, and lines with " cursed " followed by "(being worn)" +on the same line will be shown in red color and underlined. +You can have multiple MENUCOLOR entries in your config file, +and the last MENUCOLOR-line in your config file that matches +a menu line will be used for the line. +.pg +.hn 2 Configuring User Sounds .pg Some platforms allow you to define sound files to be played when a message @@ -2917,6 +2975,10 @@ SHELLERS A list of users who are allowed to use the shell escape command (!). The syntax is the same as WIZARDS. .lp +EXPLORERS +A list of users who are allowed to use the explore mode. The +syntax is the same as WIZARDS. +.lp MAXPLAYERS Limit the maximum number of games that can be running at the same time. .lp @@ -2989,7 +3051,7 @@ command-line switch or with the .op playmode:explore option. The other is to issue the ``#exploremode'' extended command while already playing the game. Starting a new game in explore mode provides your -character with a wand of wishing in initial inventory; switching via `X' +character with a wand of wishing in initial inventory; switching during play does not. The other benefits of explore mode are left for the trepid reader to discover. .pg @@ -3157,7 +3219,7 @@ available web-site listing all the bugs that had been discovered. Despite that constantly growing bug list, 3.3 proved stable enough to last for more than a year and a half. .pg -The 3.5 development team initially consisted of +The 3.4 development team initially consisted of \fBMichael Allison\fP, \fBKen Arromdee\fP, \fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBKevin Hugo\fP, \fBKen Lorber\fP, \fBDean Luick\fP, \fBPat Rankin\fP, \fBMike Stephenson\fP, @@ -3167,16 +3229,16 @@ just before the release of NetHack 3.4.0 in March 2002. As with version 3.3, various people contributed to the game as a whole as well as supporting ports on the different platforms that NetHack runs on: .pg -\fBPat Rankin\fP maintained 3.5 for VMS. +\fBPat Rankin\fP maintained 3.4 for VMS. .pg -\fBMichael Allison\fP maintained NetHack 3.5 for the MS-DOS platform. \fBPaul Winner\fP +\fBMichael Allison\fP maintained NetHack 3.4 for the MS-DOS platform. \fBPaul Winner\fP and \fBYitzhak Sapir\fP provided encouragement. .pg \fBDean Luick\fP, \fBMark Modrall\fP, and \fBKevin Hugo\fP maintained and enhanced the Macintosh port of 3.4. .pg \fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBAlex Kompel\fP, \fBDion Nicolaas\fP, and -\fBYitzhak Sapir\fP maintained and enhanced 3.5 for the Microsoft Windows platform. +\fBYitzhak Sapir\fP maintained and enhanced 3.4 for the Microsoft Windows platform. \fBAlex Kompel\fP contributed a new graphical interface for the Windows port. \fBAlex Kompel\fP also contributed a Windows CE port for 3.4.1. .pg @@ -3186,13 +3248,77 @@ early 2006. A great many thanks to Ron for keeping NetHack alive on OS/2 all these years. .pg \fBJanne Salmijarvi\fP and \fBTeemu Suikki\fP maintained and -enhanced the Amiga port of 3.5 after \fBJanne Salmijarvi\fP resurrected +enhanced the Amiga port of 3.4 after \fBJanne Salmijarvi\fP resurrected it for 3.3.1. .pg -\fBChristian ``Marvin'' Bressler\fP maintained 3.5 for the Atari after he +\fBChristian ``Marvin'' Bressler\fP maintained 3.4 for the Atari after he resurrected it for 3.3.1. .pg +The release of NetHack 3.4.3 in December 2003 marked the beginning of a +long release hiatus. 3.4.3 proved to be a remarkably stable version that +provided continued enjoyment by the community for more than a decade. The +devteam slowly and quietly continued to work on the game behind the scenes +during the tenure of 3.4.3. It was during that same period that several new +variants emerged within the NetHack community. Notably sporkhack by +\fBDerek S. Ray\fP, unnethack by \fBPatric Mueller\fP, nitrohack and its +successors originally by \fBDaniel Thaler\fP and then by \fBAlex Smith\fP, +and Dynahack by \fBTung Nguyen\fP. Some of those variants continue to be +developed, maintained, and enjoyed by the community to this day. +.pg +In September 2014, an interim snapshot of the code under development was +released publicly by other parties. Since that code was a work-in-progress +and had not gone through a period of debugging, it was decided that the +version numbers present on that code snapshot would be retired and never +used in an official NetHack release. An announcement was posted on the +devteam's official nethack.org website to that effect, stating that there +would never be a 3.4.4, 3.5, or 3.5.0 official release version. +.pg +In January 2015, preparation began for the release of NetHack 3.6 +.pg +At the beginning of development for what would eventually get released +as 3.6.0, the development team consisted of \fBWarwick Allison\fP, +\fBMichael Allison\fP, \fBKen Arromdee\fP, +\fBDavid Cohrs\fP, \fBJessie Collet\fP, +\fBKen Lorber\fP, \fBDean Luick\fP, \fBPat Rankin\fP, +\fBMike Stephenson\fP, \fBJanet Walz\fP, and \fBPaul Winner\fP. +Leading up to the release of 3.6.0 in early 2015, new members +\fBSean Hunt\fP, \fBPasi Kallinen\fP, and \fBDerek S. Ray\fP +joined the NetHack development team, +.pg +\fB3.6.0 TODO insert apprpriate description of 3.6.0 here +.pg +\fBThe development team, as well as \fBSteve VanDevender\fP and +\fBKevin Smolkowski\fP ensured that NetHack 3.6.0 continued to operate on +various Unix flavors as well as maintaining the X11 interface. +.pg +\fBKen Lorber\fP, \fBHaoyang Wang\fP, \fBPat Rankin\fP, and \fBDean Luick\fP +maintained the port of NetHack 3.6.0 for Mac. +.pg +\fBMichael Allison\fP, \fBDerek S. Ray\fP, \fBYitzhak Sapir\fP, +\fBAlex Kompel\fP, and \fBDavid Cohrs\fP maintained the port of +NetHack 3.6.0 for Microsoft Windows. +.pg +\fBJeff Bailey\fP created and maintained a port of NetHack 3.6.0 for Chrome. +.pg +TODO \fBAlex Kompel\fP maintained a port of NetHack 3.6.0 to Windows Phone. +.pg +\fBThis version of the game is special in a particular way. Near the end of +the development of 3.6, one of the significant inspirations for many of the +humorous and fun features found in the game, author \fBTerry Pratchett\fP, +passed away. This version of the game is dedicated to him. +.pg The official NetHack web site is maintained by \fBKen Lorber\fP at http://www.nethack.org/. +.pg +SHOUT-OUTS +.pg +The devteam would like to give a special "shout-out" to thank the generous +people primarily responsible for the public NetHack servers available for +playing the game at nethack.alt.org and devnull.net. In addition to providing +a way for the public to play a game of NetHack from almost anywhere, they +have hosted annual NetHack tournaments for many, many years. +.pg +On behalf of the NetHack community, thank you very much to +\fBM. Drew Streib\fP, \fBPasi Kallinen\fP and \fBRobin Bandy\fP. .pg - - - - - - - - - - .pg @@ -3205,11 +3331,11 @@ in this, the list of Dungeoneers: center; c c c. .\"TABLE_START -Adam Aronow Izchak Miller Mike Stephenson -Alex Kompel J. Ali Harlow Norm Meluch -Andreas Dorn Janet Walz Olaf Seibert -Andy Church Janne Salmijarvi Pasi Kallinen -Andy Swanson Jean-Christophe Collet Pat Rankin +Adam Aronow J. Ali Harlow Mike Stephenson +Alex Kompel Janet Walz Norm Meluch +Andreas Dorn Janne Salmijarvi Olaf Seibert +Andy Church Jean-Christophe Collet Pasi Kallinen +Andy Swanson Jeff Bailey Pat Rankin Ari Huttunen Jochen Erwied Paul Winner Barton House John Kallen Pierre Martineau Benson I. Margulies John Rupley Ralf Brown @@ -3218,31 +3344,32 @@ Boudewijn Waijers Johnny Lee Richard Addison Bruce Cox Jon W{tte Richard Beigel Bruce Holloway Jonathan Handler Richard P. Hughey Bruce Mewborne Joshua Delahunty Rob Menke -Carl Schelin Keizo Yamamoto Robin Johnson -Chris Russo Ken Arnold Roderick Schertler -David Cohrs Ken Arromdee Roland McGrath -David Damerell Ken Lorber Ron Van Iwaarden -David Gentzel Ken Washikita Ronnen Miller -David Hairston Kevin Darcy Ross Brown -Dean Luick Kevin Hugo Sascha Wostmann -Del Lamb Kevin Sitze Scott Bigham -Derek S. Ray Kevin Smolkowski Scott R. Turner -Deron Meranda Kevin Sweet Sean Hunt -Dion Nicolaas Lars Huttar Stephen Spackman -Dylan O'Donnell Leon Arnott Stephen White -Eric Backus Malcolm Ryan Steve Creps -Eric Hendrickson Mark Gooderum Steve Linhart -Eric R. Smith Mark Modrall Steve VanDevender -Eric S. Raymond Marvin Bressler Teemu Suikki -Erik Andersen Matthew Day Tim Lennan -Frederick Roeber Merlyn LeRoy Timo Hakulinen -Gil Neiger Michael Allison Tom Almy -Greg Laskin Michael Feir Tom West -Greg Olson Michael Hamel Warren Cheung -Gregg Wonderly Michael Sokolov Warwick Allison -Hao-yang Wang Mike Engber Yitzhak Sapir -Helge Hafting Mike Gallop -Irina Rempt-Drijfhout Mike Passaretti +Carl Schelin Keizo Yamamoto Robin Bandy +Chris Russo Ken Arnold Robin Johnson +David Cohrs Ken Arromdee Roderick Schertler +David Damerell Ken Lorber Roland McGrath +David Gentzel Ken Washikita Ron Van Iwaarden +David Hairston Kevin Darcy Ronnen Miller +Dean Luick Kevin Hugo Ross Brown +Del Lamb Kevin Sitze Sascha Wostmann +Derek S. Ray Kevin Smolkowski Scott Bigham +Deron Meranda Kevin Sweet Scott R. Turner +Dion Nicolaas Lars Huttar Sean Hunt +Dylan O'Donnell Leon Arnott Stephen Spackman +Eric Backus M. Drew Streib Stephen White +Eric Hendrickson Malcolm Ryan Steve Creps +Eric R. Smith Mark Gooderum Steve Linhart +Eric S. Raymond Mark Modrall Steve VanDevender +Erik Andersen Marvin Bressler Teemu Suikki +Frederick Roeber Matthew Day Tim Lennan +Gil Neiger Merlyn LeRoy Timo Hakulinen +Greg Laskin Michael Allison Tom Almy +Greg Olson Michael Feir Tom West +Gregg Wonderly Michael Hamel Warren Cheung +Hao-yang Wang Michael Sokolov Warwick Allison +Helge Hafting Mike Engber Yitzhak Sapir +Irina Rempt-Drijfhout Mike Gallop +Izchak Miller Mike Passaretti .\"TABLE_END Do not delete this line. .TE diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index c1cf2015e..67ca18cc1 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -33,7 +33,7 @@ \begin{document} % % input file: guidebook.mn -% $Revision: 1.122 $ $Date: 2015/03/16 06:00:00 $ +% $Revision: 1.122 $ $Date: 2015/03/27 06:00:00 $ % %.ds h0 " %.ds h1 %.ds h2 \% @@ -46,7 +46,7 @@ %.au \author{Eric S. Raymond\\ (Edited and expanded for 3.6)} -\date{March 16, 2015} +\date{March 27, 2015} \maketitle @@ -862,13 +862,8 @@ two-weapon combat. Note that if one of these slots is empty, the exchange still takes place. %.lp \item[\tb{X}] -Enter explore (discovery) mode, explained in its own section later.\\ -%.lp "" -Since using this command by accident would be troublesome, you are asked -to confirm your intent before switching to explore mode. By default -the response `{\tt y}' acknowledges that intent. You can set the -{\it paranoid\_confirmation\/} -option to require a response of ``yes'' instead. +Toggle two-weapon combat, if your character can do it. Also available +via the ``{\tt \#twoweapon}'' extended command %.lp \item[\tb{\^{}X}] Display basic information about your character.\\ @@ -2224,7 +2219,8 @@ command allows you to view all options and change most of them. You can also set options automatically by placing them in the ``NETHACKOPTIONS'' environment variable or in a configuration file. Some versions of {\it NetHack\/} also have front-end programs that allow -you to set options before starting the game. +you to set options before starting the game or a global configuration +for system administrators. %.hn 2 \subsection*{Using the NETHACKOPTIONS environment variable} @@ -2275,8 +2271,7 @@ each entry. Such a sequence can be continued to multiple lines by putting a `{\tt \verb+\+}' at the end of each line to be continued. %.pg -If your copy of the game included the compile time AUTOPICKUP\_EXCEPTIONS -option, then any line starting with ``{\tt AUTOPICKUP\_EXCEPTION=}'' +Any line starting with ``{\tt AUTOPICKUP\_EXCEPTION=}'' is taken as defining an exception to the ``{\tt pickup\_types}'' option. There is a section of this Guidebook that discusses that. @@ -2327,6 +2322,12 @@ or make ready with the `Q' command instead. If no weapon is found or the option is false, the `t' (throw) command is executed instead. (default false) %.lp +\item[\ib{blind}] +Start the character permanently blind. (default false) +%.lp +\item[\ib{bones}] +Allow saving and loading bones files. (default true) +%.lp \item[\ib{boulder}] Set the character used to display boulders (default is rock class symbol). %.lp @@ -2475,6 +2476,13 @@ Enable mail delivery during the game (default on). An obsolete synonym for ``{\tt gender:male}''. Cannot be set with the `{\tt O}' command. %.lp +\item[\ib{mention\_walls}] +Give feedback when walking against a wall (default off). +%.lp +\item[\ib{menucolors}] +Enable coloring menu lines (default off). +See ``{\it Configuring Menu Colors\/}'' on how to configure the colors. +%.lp \item[\ib{menustyle}] Controls the interface used when you need to choose various objects (in response to the Drop command, for instance). The value specified should @@ -2520,13 +2528,16 @@ Default `\verb+|+'. Menu character accelerator to goto the next menu page. Implemented by the Amiga, Gem and tty ports. Default `\verb+>+'. +\item[\ib{menu\_objsyms}] +Show object symbols in menu headings in menus where +the object symbols act as menu accelerators (default off). \item[\ib{menu\_previous\_page}] Menu character accelerator to goto the previous menu page. Implemented by the Amiga, Gem and tty ports. Default `\verb+<+'. \item[\ib{menu\_search}] Menu character accelerator to search for a menu item. -Implemented by the Amiga, Gem and X11 ports. +Implemented by the Amiga, Gem, X11 and tty ports. Default `:'. \item[\ib{menu\_select\_all}] Menu character accelerator to select all items in a menu. @@ -2572,6 +2583,9 @@ Read the {\it NetHack\/} news file, if present (default on). Since the news is shown at the beginning of the game, there's no point in setting this with the `{\tt O}' command. %.lp +\item[\ib{nudist}] +Start the character with no armor (default false). +%.lp \item[\ib{null}] Send padding nulls to the terminal (default on). %.lp @@ -2600,7 +2614,7 @@ is the same as specifying {\tt 0}. (Settings {\tt 2} and {\tt 4} are for compatibility with MSDOS or old PC Hack; in addition to the different behavior for `{\tt 5}', `{\tt Alt-5}' acts as `{\tt G}' and `{\tt Alt-0}' acts as `{\tt I}'. -Setting {\tt -1} is to accomodate some German keyboards which have the +Setting {\tt -1} is to accommodate some German keyboards which have the location of the `{\tt y}' and `{\tt z}' keys swapped.) When moving by numbers, to enter a count prefix for those commands which accept one (such as ``{\tt 12s}'' to search twelve times), precede it @@ -2678,10 +2692,8 @@ match an autopickup exception. Default is on. %.lp \item[\ib{pickup\_types}] Specify the object types to be picked up when ``{\it autopickup\/}'' -is on. Default is all types. If your copy of the game has the -compile time option AUTOPICKUP\_EXCEPTIONS included, -you may be able to use ``{\it autopickup\_exception\/}'' configuration -file lines to further refine ``{\it autopickup\/}'' behavior. +is on. Default is all types. You can use ``{\it autopickup\_exception\/}'' +configuration file lines to further refine ``{\it autopickup\/}'' behavior. %.lp \item[\ib{pile\_limit}] When walking across a pile of objects on the floor, threshold at which @@ -2962,6 +2974,9 @@ Specify the preferred height of each tile in a tile capable port. \item[\ib{tile\_width}] Specify the preferred width of each tile in a tile capable port %.lp +\item[\ib{use\_darkgray}] +Use bold black instead of blue for black glyphs (TTY only). +%.lp \item[\ib{use\_inverse}] NetHack should display inverse when the game specifies it. %.lp @@ -3074,10 +3089,8 @@ Cannot be set with the `{\tt O}' command. \subsection*{Configuring autopickup exceptions} %.pg -There is a compile time option called AUTOPICKUP_EXCEPTIONS. -If your copy of the game was built with that option defined, you can -further refine the behavior of the ``{\tt autopickup}'' option beyond -what is available through the ``{\tt pickup\_types}'' option. +You can further refine the behavior of the ``{\tt autopickup}'' option +beyond what is available through the ``{\tt pickup\_types}'' option. %.pg By placing ``{\tt autopickup\_exception}'' lines in your configuration @@ -3132,6 +3145,71 @@ The second example results in the exclusion of any corpse from autopickup. The last example results in the exclusion of items known to be cursed from autopickup. +%.lp +%.hn 2 +\subsection*{Configuring Menu Colors} + +%.pg +Some platforms allow you to define colors used in menu lines when the +line matches a user-defined pattern. At this time the tty, win32tty and +win32gui support this. + +%.pg +In general, the config file entries to configure the menu color mappings +look like this: +\begin{verbatim} + MENUCOLOR="pattern"=color&attribute +\end{verbatim} + +\blist{} +%.lp +\item[\ib{pattern}] +the pattern to match; +%.lp +\item[\ib{color}] +the color to use for lines matching the pattern; +%.lp +\item[\ib{attribute}] +the attribute to use for lines matching the pattern. The attribute is +optional, and if left out, you must also leave out the preceding ampersand. +If no attribute is defined, no attribute is used. +\elist + +%.lp "" +For explanation on pattern format and the matching routines, see +the pattern in the {\it Configuring User Sounds} -section. + +%.lp "" +Allowed colors are {\it black}, {\it red}, {\it green}, {\it brown}, +{\it blue}, {\it magenta}, {\it cyan}, {\it gray}, {\it orange}, +{\it lightgreen}, {\it yellow}, {\it lightblue}, {\it lightmagenta}, +{\it lightcyan}, and {\it white}. + +%.lp "" +Allowed attributes are {\it none}, {\it bold}, {\it dim}, {\it underline}, +{\it blink}, and {\it inverse}. +Note that the platform used may interpret the attributes any way it +wants. + +%.lp "" +Here's an example of menu colors using NetHack's internal +pattern matching facility: + +\begin{verbatim} + MENUCOLOR="* blessed *"=green + MENUCOLOR="* cursed *"=red + MENUCOLOR="* cursed *(being worn)"=red&underline +\end{verbatim} + +specifies that any menu line with " blessed " contained +in it will be shown in green color, lines with " cursed " will be +shown in red, and lines with " cursed " followed by "(being worn)" +on the same line will be shown in red color and underlined. +You can have multiple MENUCOLOR entries in your config file, +and the last MENUCOLOR-line in your config file that matches +a menu line will be used for the line. +%.pg + %.lp %.hn 2 \subsection*{Configuring User Sounds} @@ -3459,6 +3537,69 @@ If this is the case, disable the number\_pad option and use the traditional Rogue-like commands. \elist +%.hn2 +\subsection*{Global Configuration for System Administrators} + +%.pg +If NetHack is compiled with the SYSCF option, a system administrator +should set up a global configuration; this is a file in the +same format as the traditional per-user configuration file (see above). + +This file should be named sysconf and placed in the same directory as +the other NetHack support files. +The options recognized in this file are listed below. Any option not +set uses a compiled-in default (which may not be appropriate for your +system). + +%.pg +\blist{} +%.lp +\item[\ib{WIZARDS}] +A space-separated list of user name who are allowed to play in wizard +mode (the debugging mode, not the magic-useing role). A value of a single +asterisk (*) allows anyone to start a game in wizard mode. +%.lp +\item[\ib{SHELLERS}] +A list of users who are allowed to use the shell escape command (!). +The syntax is the same as WIZARDS. +%.lp +\item[\ib{EXPLORERS}] +A list of users who are allowed to use the explore mode. +The syntax is the same as WIZARDS. +%.lp +\item[\ib{MAXPLAYERS}] +Limit the maximum number of games taht can be running at the same time. +%.lp +\item[\ib{SUPPORT}] +A string explainign how to get local support (no default value). +%.lp +\item[\ib{RECOVER}] +A string explaining how to recover a game on this system (no default value). +%.lp +\item[\ib{SEDUCE}] +0 or 1 to disable or enable, respectively, the SEDUCE option (see the source) +for details on this function. +\elist + +%.pg +The following options affect the score file: +\blist {} +%.pg +%.lp +\item[\ib{PERSMAX}] +Maximum number of entries for one person +%.lp +\item[\ib{ENTRYMAX}] +Maximum number of entries in the score file +%.lp +\item[\ib{POINTSMIN}] +Minimum number of points to get an entry in the score file. +%.lp +\item[\ib{PERS_IS_UID}] +0 or 1 to use user names or numeric userids, respectively, to identify +unique people for the score file +\elist + %.hn 1 \section{Scoring} @@ -3505,9 +3646,9 @@ There are two ways of enabling explore mode. One is to start the game with the {\tt -X} command-line switch or with the {\it playmode:explore\/} -option. The other is to issue the `{\tt X}' command while already -playing the game. Starting a new game in explore mode provides your -character with a wand of wishing in initial inventory; switching via `X' +option. The other is to issue the `{\tt \#exploremode}' extended command while +already playing the game. Starting a new game in explore mode provides your +character with a wand of wishing in initial inventory; switching during play does not. The other benefits of explore mode are left for the trepid reader to discover. @@ -3728,7 +3869,7 @@ more than a year and a half. %.pg \medskip -The 3.5 development team initially consisted of +The 3.4 development team initially consisted of {\it Michael Allison}, {\it Ken Arromdee}, {\it David Cohrs}, {\it Jessie Collet}, {\it Kevin Hugo}, {\it Ken Lorber}, {\it Dean Luick}, {\it Pat Rankin}, {\it Mike Stephenson}, @@ -3743,11 +3884,11 @@ runs on: %.pg \medskip -\nd{\it Pat Rankin} maintained 3.5 for VMS. +\nd{\it Pat Rankin} maintained 3.4 for VMS. %.pg \medskip -\nd {\it Michael Allison} maintained NetHack 3.5 for the MS-DOS platform. +\nd {\it Michael Allison} maintained NetHack 3.4 for the MS-DOS platform. {\it Paul Winner} and {\it Yitzhak Sapir} provided encouragement. %.pg @@ -3758,7 +3899,7 @@ enhanced the Macintosh port of 3.4. %.pg \medskip \nd {\it Michael Allison}, {\it David Cohrs}, {\it Alex Kompel}, {\it Dion Nicolaas}, and -{\it Yitzhak Sapir} maintained and enhanced 3.5 for the Microsoft Windows platform. +{\it Yitzhak Sapir} maintained and enhanced 3.4 for the Microsoft Windows platform. {\it Alex Kompel} contributed a new graphical interface for the Windows port. {\it Alex Kompel} also contributed a Windows CE port for 3.4.1. @@ -3772,23 +3913,109 @@ all these years. %.pg \medskip \nd {\it Janne Salmij\"{a}rvi} and {\it Teemu Suikki} maintained -and enhanced the Amiga port of 3.5 after {\it Janne Salmij\"{a}rvi} resurrected +and enhanced the Amiga port of 3.4 after {\it Janne Salmij\"{a}rvi} resurrected it for 3.3.1. %.pg \medskip -\nd {\it Christian ``Marvin'' Bressler} maintained 3.5 for the Atari after he +\nd {\it Christian ``Marvin'' Bressler} maintained 3.4 for the Atari after he resurrected it for 3.3.1. %.pg \medskip -\nd There is a NetHack web site maintained by {\it Ken Lorber} at +The release of NetHack 3.4.3 in December 2003 marked the beginning of a +long release hiatus. 3.4.3 proved to be a remarkably stable version that +provided continued enjoyment by the community for more than a decade. The +devteam slowly and quietly continued to work on the game behind the scenes +during the tenure of 3.4.3. It was during that same period that several new +variants emerged within the NetHack community. Notably sporkhack by +Derek S. Ray, unnethack by Patric Mueller, nitrohack and its successors +originally by Daniel Thaler and then by Alex Smith, and +Dynahack by Tung Nguyen. Some of those variants continue to be developed, +maintained, and enjoyed by the community to this day. + +%.pg +\medskip +In September 2014, an interim snapshot of the code under development was +released publicly by other parties. Since that code was a work-in-progress +and had not gone through a period of debugging, it was decided that the +version numbers present on that code snapshot would be retired and never +used in an official NetHack release. An announcement was posted on the +devteam's official nethack.org website to that effect, stating that there +would never be a 3.4.4, 3.5, or 3.5.0 official release version. + +%.pg +\medskip +In January 2015, preparation began for the release of NetHack 3.6 + +%.pg +\medskip +At the beginning of development for what would eventually get released +as 3.6.0, the development team consisted of {\it Warwick Allison}, +{\it Michael Allison}, {\it Ken Arromdee}, +{\it David Cohrs}, {\it Jessie Collet}, +{\it Ken Lorber}, {\it Dean Luick}, {\it Pat Rankin}, +{\it Mike Stephenson}, {\it Janet Walz}, and {\it Paul Winner}. +Leading up to the release of 3.6.0 in early 2015, new members +{\it Sean Hunt}, {\it Pasi Kallinen}, and {\it Derek S. Ray} +joined the NetHack development team, + +%.pg +\medskip +3.6.0 TODO insert apprpriate description of 3.6.0 here + +%.pg +\medskip +The development team, as well as {\it Steve VanDevender} and +{\it Kevin Smolkowski} ensured that NetHack 3.6.0 continued to operate on +various Unix flavors as well as maintaining the X11 interface. + +{\it Ken Lorber}, {\it Haoyang Wang}, {\it Pat Rankin}, and {\it Dean Luick} +maintained the port of NetHack 3.6.0 for Mac. + +%.pg +\medskip +{\it Michael Allison}, {\it Derek S. Ray}, {\it Yitzhak Sapir}, +{\it Alex Kompel}, and {\it David Cohrs} maintained the port of +NetHack 3.6.0 for Microsoft Windows. + +%.pg +\medskip +{\it Jeff Bailey} created and maintained a port of NetHack 3.6.0 for Chrome. + +%.pg +\medskip +{\it Alex Kompel} maintained a port of NetHack 3.6.0 to Windows Phone. ? + +%.pg +\medskip +This version of the game is special in a particular way. Near the end of +the development of 3.6, one of the significant inspirations for many of the +humorous and fun features found in the game, author {\it Terry Pratchett}, +passed away. This version of the game is dedicated to him. + +%.pg +\medskip +\nd The official NetHack web site is maintained by {\it Ken Lorber} at {\catcode`\#=11 \special{html:}} http:{\tt /}{\tt /}www.nethack.org{\tt /}. {\catcode`\#=11 \special{html:}} +%.pg +%.hn 2 +\subsection*{Shout Outs} +\nd The devteam would like to give a special "shout-out" to thank the generous +people primarily responsible for the public NetHack servers available for +playing the game at nethack.alt.org and devnull.net. In addition to providing +a way for the public to play a game of NetHack from almost anywhere, they +have hosted annual NetHack tournaments for many, many years. +%.pg +\nd On behalf of the NetHack community, thank you very much to +{\it M. Drew Streib}, {\it Pasi Kallinen} and {\it Robin Bandy}. + +%.pg %.hn 3 \subsection*{Dungeoneers} \bigskip @@ -3801,11 +4028,11 @@ in this, the list of Dungeoneers: \begin{center} \begin{tabular}{lll} %TABLE_START -Adam Aronow & Izchak Miller & Mike Stephenson\\ -Alex Kompel & J. Ali Harlow & Norm Meluch\\ -Andreas Dorn & Janet Walz & Olaf Seibert\\ -Andy Church & Janne Salmij\"{a}rvi & Pasi Kallinen\\ -Andy Swanson & Jean-Christophe Collet & Pat Rankin\\ +Adam Aronow & J. Ali Harlow & Mike Stephenson\\ +Alex Kompel & Janet Walz & Norm Meluch\\ +Andreas Dorn & Janne Salmij\"{a}rvi & Olaf Seibert\\ +Andy Church & Jean-Christophe Collet & Pasi Kallinen\\ +Andy Swanson & Jeff Bailey & Pat Rankin\\ Ari Huttunen & Jochen Erwied & Paul Winner\\ Barton House & John Kallen & Pierre Martineau\\ Benson I. Margulies & John Rupley & Ralf Brown\\ @@ -3814,31 +4041,32 @@ Boudewijn Waijers & Johnny Lee & Richard Addison\\ Bruce Cox & Jon W\{tte & Richard Beigel\\ Bruce Holloway & Jonathan Handler & Richard P. Hughey\\ Bruce Mewborne & Joshua Delahunty & Rob Menke\\ -Carl Schelin & Keizo Yamamoto & Robin Johnson\\ -Chris Russo & Ken Arnold & Roderick Schertler\\ -David Cohrs & Ken Arromdee & Roland McGrath\\ -David Damerell & Ken Lorber & Ron Van Iwaarden\\ -David Gentzel & Ken Washikita & Ronnen Miller\\ -David Hairston & Kevin Darcy & Ross Brown\\ -Dean Luick & Kevin Hugo & Sascha Wostmann\\ -Del Lamb & Kevin Sitze & Scott Bigham\\ -Derek S. Ray & Kevin Smolkowski & Scott R. Turner\\ -Deron Meranda & Kevin Sweet & Sean Hunt\\ -Dion Nicolaas & Lars Huttar & Stephen Spackman\\ -Dylan O'Donnell & Leon Arnott & Stephen White\\ -Eric Backus & Malcolm Ryan & Steve Creps\\ -Eric Hendrickson & Mark Gooderum & Steve Linhart\\ -Eric R. Smith & Mark Modrall & Steve VanDevender\\ -Eric S. Raymond & Marvin Bressler & Teemu Suikki\\ -Erik Andersen & Matthew Day & Tim Lennan\\ -Frederick Roeber & Merlyn LeRoy & Timo Hakulinen\\ -Gil Neiger & Michael Allison & Tom Almy\\ -Greg Laskin & Michael Feir & Tom West\\ -Greg Olson & Michael Hamel & Warren Cheung\\ -Gregg Wonderly & Michael Sokolov & Warwick Allison\\ -Hao-yang Wang & Mike Engber & Yitzhak Sapir\\ -Helge Hafting & Mike Gallop\\ -Irina Rempt-Drijfhout & Mike Passaretti +Carl Schelin & Keizo Yamamoto & Robin Bandy\\ +Chris Russo & Ken Arnold & Robin Johnson\\ +David Cohrs & Ken Arromdee & Roderick Schertler\\ +David Damerell & Ken Lorber & Roland McGrath\\ +David Gentzel & Ken Washikita & Ron Van Iwaarden\\ +David Hairston & Kevin Darcy & Ronnen Miller\\ +Dean Luick & Kevin Hugo & Ross Brown\\ +Del Lamb & Kevin Sitze & Sascha Wostmann\\ +Derek S. Ray & Kevin Smolkowski & Scott Bigham\\ +Deron Meranda & Kevin Sweet & Scott R. Turner\\ +Dion Nicolaas & Lars Huttar & Sean Hunt\\ +Dylan O'Donnell & Leon Arnott & Stephen Spackman\\ +Eric Backus & M. Drew Streib & Stephen White\\ +Eric Hendrickson & Malcolm Ryan & Steve Creps\\ +Eric R. Smith & Mark Gooderum & Steve Linhart\\ +Eric S. Raymond & Mark Modrall & Steve VanDevender\\ +Erik Andersen & Marvin Bressler & Teemu Suikki\\ +Frederick Roeber & Matthew Day & Tim Lennan\\ +Gil Neiger & Merlyn LeRoy & Timo Hakulinen\\ +Greg Laskin & Michael Allison & Tom Almy\\ +Greg Olson & Michael Feir & Tom West\\ +Gregg Wonderly & Michael Hamel & Warren Cheung\\ +Hao-yang Wang & Michael Sokolov & Warwick Allison\\ +Helge Hafting & Mike Engber & Yitzhak Sapir\\ +Irina Rempt-Drijfhout & Mike Gallop\\ +Izchak Miller & Mike Passaretti %TABLE_END Do not delete this line. \end{tabular} \end{center} diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 4318b8a5f..84a5395a6 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -13,25 +13,25 @@ Eric S. Raymond - (Extensively edited and expanded for 3.5) + (Edited and expanded for 3.6) 1. Introduction Recently, you have begun to find yourself unfulfilled and distant - in your daily occupation. Strange dreams of prospecting, steal- + in your daily occupation. Strange dreams of prospecting, steal‐ ing, crusading, and combat have haunted you in your sleep for - many months, but you aren't sure of the reason. You wonder + many months, but you aren’t sure of the reason. You wonder whether you have in fact been having those dreams all your life, and somehow managed to forget about them until now. Some nights - you awaken suddenly and cry out, terrified at the vivid recollec- - tion of the strange and powerful creatures that seem to be lurk- + you awaken suddenly and cry out, terrified at the vivid recollec‐ + tion of the strange and powerful creatures that seem to be lurk‐ ing behind every corner of the dungeon in your dream. Could - these details haunting your dreams be real? As each night pass- + these details haunting your dreams be real? As each night pass‐ es, you feel the desire to enter the mysterious caverns near the ruins grow stronger. Each morning, however, you quickly put the - idea out of your head as you recall the tales of those who en- + idea out of your head as you recall the tales of those who en‐ tered the caverns before you and did not return. Eventually you can resist the yearning to seek out the fantastic place in your dreams no longer. After all, when other adventurers came back @@ -49,14 +49,14 @@ deep within the Mazes of Menace. Upon hearing the legends, you immediately realize that there is some profound and undiscovered reason that you are to descend into the caverns and seek out that - amulet of which they spoke. Even if the rumors of the amulet's + amulet of which they spoke. Even if the rumors of the amulet’s powers are untrue, you decide that you should at least be able to sell the tales of your adventures to the local minstrels for a tidy sum, especially if you encounter any of the terrifying and magical creatures of your dreams along the way. You spend one last night fortifying yourself at the local inn, becoming more and more depressed as you watch the odds of your success being - posted on the inn's walls getting lower and lower. + posted on the inn’s walls getting lower and lower. @@ -74,8 +74,8 @@ off for the dungeon. After several days of uneventful travel, you see the ancient ruins that mark the entrance to the Mazes of Menace. It is late at night, so you make camp at the entrance - and spend the night sleeping under the open skies. In the morn- - ing, you gather your gear, eat what may be your last meal out- + and spend the night sleeping under the open skies. In the morn‐ + ing, you gather your gear, eat what may be your last meal out‐ side, and enter the dungeon... @@ -94,15 +94,15 @@ Barbarians are warriors out of the hinterland, hardened to battle. They begin their quests with naught but uncommon - strength, a trusty hauberk, and a great two-handed sword. + strength, a trusty hauberk, and a great two‐handed sword. Cavemen and Cavewomen start with exceptional strength but, unfortunately, with neolithic weapons. Healers are wise in medicine and apothecary. They know the - herbs and simples that can restore vitality, ease pain, anes- + herbs and simples that can restore vitality, ease pain, anes‐ thetize, and neutralize poisons; and with their instruments, they - can divine a being's state of health or sickness. Their medical + can divine a being’s state of health or sickness. Their medical practice earns them quite reasonable amounts of money, with which they enter the dungeon. @@ -115,7 +115,7 @@ without weapons as with. They wear no armor but make up for it with increased mobility. - Priests and Priestesses are clerics militant, crusaders ad- + Priests and Priestesses are clerics militant, crusaders ad‐ vancing the cause of righteousness with arms, armor, and arts thaumaturgic. Their ability to commune with deities via prayer occasionally extricates them from peril, but can also put them in @@ -126,7 +126,7 @@ as well as tracking and stealthy movement. - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -141,26 +141,26 @@ which they employ to great advantage. Samurai are the elite warriors of feudal Nippon. They are - lightly armored and quick, and wear the dai-sho, two swords of + lightly armored and quick, and wear the dai‐sho, two swords of the deadliest keenness. Tourists start out with lots of gold (suitable for shopping with), a credit card, lots of food, some maps, and an expensive - camera. Most monsters don't like being photographed. + camera. Most monsters don’t like being photographed. Valkyries are hardy warrior women. Their upbringing in the harsh Northlands makes them strong, inures them to extremes of cold, and instills in them stealth and cunning. Wizards start out with a knowledge of magic, a selection of - magical items, and a particular affinity for dweomercraft. Al- - though seemingly weak and easy to overcome at first sight, an ex- + magical items, and a particular affinity for dweomercraft. Al‐ + though seemingly weak and easy to overcome at first sight, an ex‐ perienced Wizard is a deadly foe. You may also choose the race of your character: Dwarves are smaller than humans or elves, but are stocky and - solid individuals. Dwarves' most notable trait is their great + solid individuals. Dwarves’ most notable trait is their great expertise in mining and metalwork. Dwarvish armor is said to be second in quality not even to the mithril armor of the Elves. @@ -169,7 +169,7 @@ often gives them an advantage in arms and armor. Gnomes are smaller than but generally similar to dwarves. - Gnomes are known to be expert miners, and it is known that a se- + Gnomes are known to be expert miners, and it is known that a se‐ cret underground mine complex built by this race exists within the Mazes of Menace, filled with both riches and danger. @@ -192,7 +192,7 @@ - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -202,63 +202,63 @@ - When NetHack's ancestor rogue first appeared, its screen + When NetHack’s ancestor rogue first appeared, its screen orientation was almost unique among computer fantasy games. Since then, screen orientation has become the norm rather than the exception; NetHack continues this fine tradition. Unlike - text adventure games that accept commands in pseudo-English sen- + text adventure games that accept commands in pseudo‐English sen‐ tences and explain the results in words, NetHack commands are all one or two keystrokes and the results are displayed graphically on the screen. A minimum screen size of 24 lines by 80 columns is recommended; if the screen is larger, only a 21x80 section will be used for the map. - NetHack can even be played by blind players, with the assis- + NetHack can even be played by blind players, with the assis‐ tance of Braille readers or speech synthesisers. Instructions for configuring NetHack for the blind are included later in this document. NetHack generates a new dungeon every time you play it; even - the authors still find it an entertaining and exciting game de- + the authors still find it an entertaining and exciting game de‐ spite having won several times. NetHack offers a variety of display options. The options available to you will vary from port to port, depending on the capabilities of your hardware and software, and whether various - compile-time options were enabled when your executable was creat- - ed. The three possible display options are: a monochrome charac- - ter interface, a color character interface, and a graphical in- - terface using small pictures called tiles. The two character in- + compile‐time options were enabled when your executable was creat‐ + ed. The three possible display options are: a monochrome charac‐ + ter interface, a color character interface, and a graphical in‐ + terface using small pictures called tiles. The two character in‐ terfaces allow fonts with other characters to be substituted, but - the default assignments use standard ASCII characters to repre- - sent everything. There is no difference between the various dis- - play options with respect to game play. Because we cannot repro- - duce the tiles or colors in the Guidebook, and because it is com- + the default assignments use standard ASCII characters to repre‐ + sent everything. There is no difference between the various dis‐ + play options with respect to game play. Because we cannot repro‐ + duce the tiles or colors in the Guidebook, and because it is com‐ mon to all ports, we will use the default ASCII characters from the monochrome character display when referring to things you might see on the screen during your game. In order to understand what is going on in NetHack, first you must understand what NetHack is doing with the screen. The - NetHack screen replaces the ``You see ...'' descriptions of text + NetHack screen replaces the ‘‘You see ...’’ descriptions of text adventure games. Figure 1 is a sample of what a NetHack screen might look like. The way the screen looks for you depends on your platform. - -------------------------------------------------------------------- + ──────────────────────────────────────────────────────────────────── The bat bites! - ------ - |....| ---------- + ‐‐‐‐‐‐ + |....| ‐‐‐‐‐‐‐‐‐‐ |.<..|####...@...$.| - |....-# |...B....+ + |....‐# |...B....+ |....| |.d......| - ------ -------|-- + ‐‐‐‐‐‐ ‐‐‐‐‐‐‐|‐‐ - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -273,7 +273,7 @@ Player the Rambler St:12 Dx:7 Co:18 In:11 Wi:9 Ch:15 Neutral Dlvl:1 $:0 HP:9(12) Pw:3(3) AC:10 Exp:1/19 T:257 Weak - -------------------------------------------------------------------- + ──────────────────────────────────────────────────────────────────── Figure 1 @@ -282,19 +282,19 @@ The bottom two lines of the screen contain several cryptic pieces of information describing your current status. If either status line becomes longer than the width of the screen, you - might not see all of it. Here are explanations of what the vari- + might not see all of it. Here are explanations of what the vari‐ ous status items mean (though your configuration may not have all the status items listed below): Rank - Your character's name and professional ranking (based on the + Your character’s name and professional ranking (based on the experience level, see below). Strength - A measure of your character's strength; one of your six ba- - sic attributes. A human character's attributes can range - from 3 to 18 inclusive; non-humans may exceed these limits - (occasionally you may get super-strengths of the form 18/xx, + A measure of your character’s strength; one of your six ba‐ + sic attributes. A human character’s attributes can range + from 3 to 18 inclusive; non‐humans may exceed these limits + (occasionally you may get super‐strengths of the form 18/xx, and magic can also cause attributes to exceed the normal limits). The higher your strength, the stronger you are. Strength affects how successfully you perform physical @@ -324,7 +324,7 @@ - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -336,17 +336,17 @@ Alignment Lawful, Neutral, or Chaotic. Often, Lawful is taken as good - and Chaotic as evil, but legal and ethical do not always co- + and Chaotic as evil, but legal and ethical do not always co‐ incide. Your alignment influences how other monsters react toward you. Monsters of a like alignment are more likely to - be non-aggressive, while those of an opposing alignment are + be non‐aggressive, while those of an opposing alignment are more likely to be seriously offended at your presence. Dungeon Level How deep you are in the dungeon. You start at level one and the number increases as you go deeper into the dungeon. Some levels are special, and are identified by a name and - not a number. The Amulet of Yendor is reputed to be some- + not a number. The Amulet of Yendor is reputed to be some‐ where beneath the twentieth level. Gold @@ -367,16 +367,16 @@ regenerate the amount available. Armor Class - A measure of how effectively your armor stops blows from un- - friendly creatures. The lower this number is, the more ef- - fective the armor; it is quite possible to have negative ar- + A measure of how effectively your armor stops blows from un‐ + friendly creatures. The lower this number is, the more ef‐ + fective the armor; it is quite possible to have negative ar‐ mor class. Experience Your current experience level and experience points. As you - adventure, you gain experience points. At certain experi- + adventure, you gain experience points. At certain experi‐ ence point totals, you gain an experience level. The more - experienced you are, the better you fight and withstand mag- + experienced you are, the better you fight and withstand mag‐ ical attacks. Many dungeons show only your experience level here. @@ -386,11 +386,11 @@ Hunger status Your current hunger status, ranging from Satiated down to - Fainting. If your hunger status is normal, it is not dis- + Fainting. If your hunger status is normal, it is not dis‐ played. - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -401,27 +401,27 @@ Additional status flags may appear after the hunger status: - Conf when you're confused, FoodPois or Ill when sick, Blind when - you can't see, Stun when stunned, and Hallu when hallucinating. + Conf when you’re confused, FoodPois or Ill when sick, Blind when + you can’t see, Stun when stunned, and Hallu when hallucinating. 3.2. The message line (top) - The top line of the screen is reserved for messages that de- + The top line of the screen is reserved for messages that de‐ scribe things that are impossible to represent visually. If you - see a ``--More--'' on the top line, this means that NetHack has + see a ‘‘‐‐More‐‐’’ on the top line, this means that NetHack has another message to display on the screen, but it wants to make - certain that you've read the one that is there first. To read + certain that you’ve read the one that is there first. To read the next message, just press the space bar. 3.3. The map (rest of the screen) The rest of the screen is the map of the level as you have - explored it so far. Each symbol on the screen represents some- + explored it so far. Each symbol on the screen represents some‐ thing. You can set various graphics options to change some of the symbols the game uses; otherwise, the game will use default symbols. Here is a list of what the default symbols mean: - - and | + ‐ and | The walls of a room, or an open door. Or a grave (|). . The floor of a room, ice, or a doorless doorway. @@ -456,7 +456,7 @@ - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -468,13 +468,13 @@ ! A potion. - ( A useful item (pick-axe, key, lamp...). + ( A useful item (pick‐axe, key, lamp...). " An amulet or a spider web. * A gem or rock (possibly valuable, possibly worthless). - ` A boulder or statue. + ‘ A boulder or statue. 0 An iron ball. @@ -486,43 +486,43 @@ \ An opulent throne. - a-zA-Z and other symbols - Letters and certain other symbols represent the various in- + a‐zA‐Z and other symbols + Letters and certain other symbols represent the various in‐ habitants of the Mazes of Menace. Watch out, they can be nasty and vicious. Sometimes, however, they can be helpful. - I This marks the last known location of an invisible or other- + I This marks the last known location of an invisible or other‐ wise unseen monster. Note that the monster could have - moved. The 'F' and 'm' commands may be useful here. + moved. The ’F’ and ’m’ commands may be useful here. You need not memorize all these symbols; you can ask the - game what any symbol represents with the `/' command (see the + game what any symbol represents with the ‘/’ command (see the next section for more info). 4. Commands Commands are initiated by typing one or two characters. - Some commands, like ``search'', do not require that any more in- + Some commands, like ‘‘search’’, do not require that any more in‐ formation be collected by NetHack. Other commands might require additional information, for example a direction, or an object to be used. For those commands that require additional information, NetHack will present you with either a menu of choices or with a - command line prompt requesting information. Which you are pre- + command line prompt requesting information. Which you are pre‐ sented with will depend chiefly on how you have set the menustyle option. - For example, a common question, in the form ``What do you - want to use? [a-zA-Z ?*]'', asks you to choose an object you are - carrying. Here, ``a-zA-Z'' are the inventory letters of your - possible choices. Typing `?' gives you an inventory list of + For example, a common question, in the form ‘‘What do you + want to use? [a‐zA‐Z ?*]’’, asks you to choose an object you are + carrying. Here, ‘‘a‐zA‐Z’’ are the inventory letters of your + possible choices. Typing ‘?’ gives you an inventory list of these items, so you can see what each letter refers to. In this - example, there is also a `*' indicating that you may choose an - object not on the list, if you wanted to use something unexpect- - ed. Typing a `*' lists your entire inventory, so you can see the + example, there is also a ‘*’ indicating that you may choose an + object not on the list, if you wanted to use something unexpect‐ + ed. Typing a ‘*’ lists your entire inventory, so you can see the - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -532,39 +532,39 @@ - inventory letters of every object you're carrying. Finally, if - you change your mind and decide you don't want to do this command + inventory letters of every object you’re carrying. Finally, if + you change your mind and decide you don’t want to do this command after all, you can press the ESC key to abort the command. You can put a number before some commands to repeat them - that many times; for example, ``10s'' will search ten times. If - you have the number_pad option set, you must type `n' to prefix a - count, so the example above would be typed ``n10s'' instead. - Commands for which counts make no sense ignore them. In addi- + that many times; for example, ‘‘10s’’ will search ten times. If + you have the number_pad option set, you must type ‘n’ to prefix a + count, so the example above would be typed ‘‘n10s’’ instead. + Commands for which counts make no sense ignore them. In addi‐ tion, movement commands can be prefixed for greater control (see below). To cancel a count or a prefix, press the ESC key. The list of commands is rather long, but it can be read at - any time during the game through the `?' command, which accesses - a menu of helpful texts. Here are the commands for your refer- + any time during the game through the ‘?’ command, which accesses + a menu of helpful texts. Here are the commands for your refer‐ ence: ? Help menu: display one of several help texts available. / Tell what a symbol represents. You may choose to specify a location or type a symbol (or even a whole word) to explain. - Specifying a location is done by moving the cursor to a par- - ticular spot on the map and then pressing one of `.', `,', - `;', or `:'. `.' will explain the symbol at the chosen lo- - cation, conditionally check for ``More info?'' depending up- + Specifying a location is done by moving the cursor to a par‐ + ticular spot on the map and then pressing one of ‘.’, ‘,’, + ‘;’, or ‘:’. ‘.’ will explain the symbol at the chosen lo‐ + cation, conditionally check for ‘‘More info?’’ depending up‐ on whether the help option is on, and then you will be asked - to pick another location; `,' will explain the symbol but - skip any additional information; `;' will skip additional - info and also not bother asking you to choose another loca- - tion to examine; `:' will show additional info, if any, + to pick another location; ‘,’ will explain the symbol but + skip any additional information; ‘;’ will skip additional + info and also not bother asking you to choose another loca‐ + tion to examine; ‘:’ will show additional info, if any, without asking for confirmation. When picking a location, - pressing the ESC key will terminate this command, or press- - ing `?' will give a brief reminder about how it works. + pressing the ESC key will terminate this command, or press‐ + ing ‘?’ will give a brief reminder about how it works. Specifying a name rather than a location always gives any additional information available about that name. @@ -574,21 +574,21 @@ < Go up to the previous level (if you are on a staircase or ladder). - > Go down to the next level (if you are on a staircase or lad- + > Go down to the next level (if you are on a staircase or lad‐ der). [yuhjklbn] Go one step in the direction indicated (see Figure 2). If you sense or remember a monster there, you will fight the - monster instead. Only these one-step movement commands + monster instead. Only these one‐step movement commands cause you to fight monsters; the others (below) are - ``safe.'' + ‘‘safe.’’ - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -600,7 +600,7 @@ y k u 7 8 9 \ | / \ | / - h- . -l 4- . -6 + h‐ . ‐l 4‐ . ‐6 / | \ / | \ b j n 1 2 3 (if number_pad is set) @@ -609,7 +609,7 @@ [YUHJKLBN] - Go in that direction until you hit a wall or run into some- + Go in that direction until you hit a wall or run into some‐ thing. m[yuhjklbn] @@ -626,35 +626,35 @@ g[yuhjklbn] Prefix: move until something interesting is found. - G[yuhjklbn] or [yuhjklbn] - Prefix: same as `g', but forking of corridors is not con- + G[yuhjklbn] or [yuhjklbn] + Prefix: same as ‘g’, but forking of corridors is not con‐ sidered interesting. - _ Travel to a map location via a shortest-path algorithm. The - shortest path is computed over map locations the hero knows - about (e.g. seen or previously traversed). If there is no - known path, a guess is made instead. Stops on most of the - same conditions as the `G' command, but without picking up - objects, similar to the `M' command. For ports with mouse - support, the command is also invoked when a mouse-click - takes place on a location other than the current position. + _ Travel to a map location via a shortest‐path algorithm. + + The shortest path is computed over map locations the hero + knows about (e.g. seen or previously traversed). If there + is no known path, a guess is made instead. Stops on most of + the same conditions as the ‘G’ command, but without picking + up objects, similar to the ‘M’ command. For ports with + mouse support, the command is also invoked when a mouse‐ + click takes place on a location other than the current posi‐ + tion. . Rest, do nothing for one turn. - a Apply (use) a tool (pick-axe, key, lamp...). + a Apply (use) a tool (pick‐axe, key, lamp...). - A Remove one or more worn items, such as armor. Use `T' (take - off) to take off only one piece of armor or `R' (remove) to - take off only one accessory. + A Remove one or more worn items, such as armor. + + Use ‘T’ (take off) to take off only one piece of armor or + ‘R’ (remove) to take off only one accessory. ^A Redo the previous command. - c Close a door. - - - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -664,63 +664,63 @@ - C Call (name) an individual monster. + c Close a door. + + C Call (name) a monster, an individual object, or a type of + object. + + Same as extended command ‘‘#name’’. ^C Panic button. Quit the game. - d Drop something. Ex. ``d7a'' means drop seven items of ob- - ject a. + d Drop something. - D Drop several things. In answer to the question ``What kinds - of things do you want to drop? [!%= BUCXaium]'' you should - type zero or more object symbols possibly followed by `a' - and/or `i' and/or `u' and/or `m'. In addition, one or more - of the blessed/uncursed/cursed groups may be typed. + Ex. ‘‘d7a’’ means drop seven items of object a. - DB - drop all objects known to be blessed. - DU - drop all objects known to be uncursed. - DC - drop all objects known to be cursed. - DX - drop all objects of unknown B/U/C status. - Da - drop all objects, without asking for confirmation. - Di - examine your inventory before dropping anything. - Du - drop only unpaid objects (when in a shop). - Dm - use a menu to pick which object(s) to drop. - D%u - drop only unpaid food. + D Drop several things. + + In answer to the question + + ‘‘What kinds of things do you want to drop? [!%= BUCXaium]’’ + + you should type zero or more object symbols possibly fol‐ + lowed by ‘a’ and/or ‘i’ and/or ‘u’ and/or ‘m’. In addition, + one or more of the blessed/uncursed/cursed groups may be + typed. + + DB ‐ drop all objects known to be blessed. + DU ‐ drop all objects known to be uncursed. + DC ‐ drop all objects known to be cursed. + DX ‐ drop all objects of unknown B/U/C status. + Da ‐ drop all objects, without asking for confirmation. + Di ‐ examine your inventory before dropping anything. + Du ‐ drop only unpaid objects (when in a shop). + Dm ‐ use a menu to pick which object(s) to drop. + D%u ‐ drop only unpaid food. ^D Kick something (usually a door). e Eat food. - E Engrave a message on the floor. Engraving the word - ``Elbereth'' will cause most monsters to not attack you - hand-to-hand (but if you attack, you will rub it out); this - is often useful to give yourself a breather. (This feature - may be compiled out of the game, so your version might not - have it.) + E Engrave a message on the floor. - E- - write in the dust with your fingers. + E‐ ‐ write in the dust with your fingers. - f Fire one of the objects placed in your quiver. You may se- - lect ammunition with a previous `Q' command, or let the com- - puter pick something appropriate if autoquiver is true. + Engraving the word ‘‘Elbereth’’ will cause most monsters to + not attack you hand‐to‐hand (but if you attack, you will rub + it out); this is often useful to give yourself a breather. + (This feature may be compiled out of the game, so your ver‐ + sion might not have it.) - i List your inventory (everything you're carrying). - - I List selected parts of your inventory. - - I* - list all gems in inventory; - Iu - list all unpaid items; - Ix - list all used up items that are on your shopping bill; - I$ - count your money. - - o Open a door. - - O Set options. A menu showing the current option values will - be displayed. You can change most values simply by select- - ing the menu entry for the given option (ie, by typing its + f Fire one of the objects placed in your quiver (or quiver + sack, or that you have at the ready). You may select ammu‐ + nition with a previous ‘Q’ command, or let the computer pick + something appropriate if autoquiver is true. - NetHack 3.5 September 20, 2006 + + + NetHack 3.6 March 27, 2015 @@ -730,63 +730,63 @@ - letter or clicking upon it, depending on your user inter- - face). For the non-boolean choices, a further menu or - prompt will appear once you've closed this menu. The avail- - able options are listed later in this Guidebook. Options - are usually set before the game rather than with the `O' - command; see the section on options below. + i List your inventory (everything you’re carrying). + + I List selected parts of your inventory. + + I* ‐ list all gems in inventory; + Iu ‐ list all unpaid items; + Ix ‐ list all used up items that are on your shopping bill; + I$ ‐ count your money. + + o Open a door. + + O Set options. + + A menu showing the current option values will be displayed. + You can change most values simply by selecting the menu en‐ + try for the given option (ie, by typing its letter or click‐ + ing upon it, depending on your user interface). For the + non‐boolean choices, a further menu or prompt will appear + once you’ve closed this menu. The available options are + listed later in this Guidebook. Options are usually set be‐ + fore the game rather than with the ‘O’ command; see the sec‐ + tion on options below. p Pay your shopping bill. P Put on a ring or other accessory (amulet, blindfold). - ^P Repeat previous message. Subsequent ^P's repeat earlier - messages. The behavior can be varied via the msg_window op- - tion. + Use the ’W’ command to wear armor. + + ^P Repeat previous message. + + Subsequent ^P’s repeat earlier messages. The behavior can + be varied via the msg_window option. q Quaff (drink) something (potion, water, etc). - Q Select an object for your quiver. You can then throw this - using the `f' command. (In versions prior to 3.3 this was - the command to quit the game, which has now been moved to - `#quit'.) + Q Select an object for your quiver, quiver sack, or just gen‐ + erally at the ready (only one of these is available at a + time). You can then throw this (or one of these) using the + ‘f’ command. (In versions prior to 3.3 this was the command + to quit the game, which has now been moved to ‘#quit’.) r Read a scroll or spellbook. R Remove an accessory (ring, amulet, etc). - ^R Redraw the screen. + If you’re wearing more than one, you’ll be prompted for + which one to remove. If you’re only wearing one, then by + default it will be removed without asking, but you can set + the paranoid_confirmation option to require a prompt. - s Search for secret doors and traps around you. It usually - takes several tries to find something. - - S Save (and suspend) the game. The game will be restored au- - tomatically the next time you play. - - t Throw an object or shoot a projectile. - - T Take off armor. - - ^T Teleport, if you have the ability. - - v Display version number. - - V Display the game history. - - w Wield weapon. - - w- - wield nothing, use your bare hands. - - W Wear armor. - - x Exchange your wielded weapon with the item in your alternate - weapon slot. The latter is used as your secondary weapon - when engaging in two-weapon combat. Note that if one of - these slots is empty, the exchange still takes place. + Use the ’T’ command to take off armor. - NetHack 3.5 September 20, 2006 + + + NetHack 3.6 March 27, 2015 @@ -796,16 +796,81 @@ - X Enter explore (discovery) mode, explained in its own section - later. + ^R Redraw the screen. - ^X Display your name, role, race, gender, and alignment as well - as the various deities in your game. + s Search for secret doors and traps around you. It usually + takes several tries to find something. - z Zap a wand. To aim at yourself, use `.' for the direction. + S Save (and suspend) the game. The game will be restored au‐ + tomatically the next time you play. - Z Zap (cast) a spell. To cast at yourself, use `.' for the - direction. + t Throw an object or shoot a projectile. + + T Take off armor. + + If you’re wearing more than one piece, you’ll be prompted + for which one to take off. If you’re only wearing one, then + by default it will be taken off without asking, but you can + set the paranoid_confirmation option to require a prompt. + + Use the ’R’ command to remove accessories. + + ^T Teleport, if you have the ability. + + v Display version number. + + V Display the game history. + + w Wield weapon. + + w‐ ‐ wield nothing, use your bare hands. + + Some characters can wield two weapons and once; use the + ‘‘#twoweapon’’ extended command to do so. + + W Wear armor. + + Use the ’P’ command to put on accessories. + + x Exchange your wielded weapon with the item in your alternate + weapon slot. + + The latter is used as your secondary weapon when engaging in + two‐weapon combat. Note that if one of these slots is emp‐ + ty, the exchange still takes place. + + X Toggle two‐weapon combat, if your character can do it. Also + available via the ‘‘#twoweapon’’ extended command + + ^X Display basic information about your character. + + Displays name, role, race, gender (unless role name makes + that redundant, such as Caveman or Priestess), and align‐ + ment, along with your patron deity and his or her opposi‐ + tion. It also shows most of the various items of informa‐ + tion from the status line(s) in a less terse form, including + several additional things which don’t appear in the normal + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 14 + + + + status display due to space considerations. + + z Zap a wand. + + z. ‐ to aim at yourself, use ‘.’ for the direction. + + Z Zap (cast) a spell. + + Z. ‐ to cast at yourself, use ‘.’ for the direction. ^Z Suspend the game (UNIX(R) versions with job control only). @@ -813,8 +878,9 @@ ; Show what type of thing a visible symbol corresponds to. - , Pick up some things. May be preceded by `m' to force a se- - lection menu. + , Pick up some things from the floor beneath you. + + May be preceded by ‘m’ to force a selection menu. @ Toggle the autopickup option on and off. @@ -830,95 +896,29 @@ ( Tell what tools you are using. - * Tell what equipment you are using; combines the preceding - five type-specific commands into one. + * Tell what equipment you are using. + + Combines the preceding five type‐specific commands into one. $ Count your gold pieces. - + List the spells you know. Using this command, you can also - rearrange the order in which your spells are listed, either - by sorting the entire list or by picking one spell from the - menu then picking another to swap places with it. Swapping - pairs of spells changes their casting letters, so the change - lasts after the current `+' command finishes. Sorting the - whole list is temporary. To make the most recent sort order - persist beyond the current `+' command, choose the sort op- - tion again and then pick "reassign casting letters". (Any - spells learned after that will be added to the end of the - list rather than be inserted into the sorted ordering.) + + List the spells you know. + Using this command, you can also rearrange the order in + which your spells are listed, either by sorting the entire + list or by picking one spell from the menu then picking an‐ + other to swap places with it. Swapping pairs of spells + changes their casting letters, so the change lasts after the + current ‘+’ command finishes. Sorting the whole list is + temporary. To make the most recent sort order persist be‐ + yond the current ‘+’ command, choose the sort option again + and then pick "reassign casting letters". (Any spells __________ (R)UNIX is a registered trademark of AT&T. - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 14 - - - - \ Show what types of objects have been discovered. - - ! Escape to a shell. - - # Perform an extended command. As you can see, the authors of - NetHack used up all the letters, so this is a way to intro- - duce the less frequently used commands. What extended com- - mands are available depends on what features the game was - compiled with. - - #adjust - Adjust inventory letters (most useful when the fixinv option - is ``on''). This command allows you to move an item from - one particular inventory slot to another so that it has a - letter which is more meaningful for you or that it will ap- - pear in a particular location when inventory listings are - displayed. ``#adjust'' can also be used to split a stack of - objects; when choosing the item to adjust, enter a count - prior to its letter. - - #chat - Talk to someone. - - #conduct - List voluntary challenges you have maintained. See the sec- - tion below entitled ``Conduct'' for details. - - #dip Dip an object into something. - - #enhance - Advance or check weapon and spell skills. - - #force - Force a lock. - - #invoke - Invoke an object's special powers. - - #jump - Jump to another location. - - #loot - Loot a box or bag on the floor beneath you, or the saddle - from a horse standing next to you. - - #monster - Use a monster's special ability (when polymorphed into mon- - ster form). - - #name - Name an item or type of object. - - #offer - Offer a sacrifice to the gods. - - - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -928,63 +928,63 @@ - #pray - Pray to the gods for help. + learned after that will be added to the end of the list + rather than be inserted into the sorted ordering.) - #quit - Quit the program without saving your game. + \ Show what types of objects have been discovered. - #ride - Ride (or stop riding) a monster. + ‘ Show discovered types for one class of objects. - #rub Rub a lamp or a stone. + ! Escape to a shell. - #sit Sit down. + # Perform an extended command. - #tip Tip over a container to pour out its contents. + As you can see, the authors of NetHack used up all the let‐ + ters, so this is a way to introduce the less frequently used + commands. What extended commands are available depends on + what features the game was compiled with. - #turn - Turn undead. + #adjust + Adjust inventory letters (most useful when the fixinv option + is ‘‘on’’). - #twoweapon - Toggle two-weapon combat on or off. Note that you must use - suitable weapons for this type of combat, or it will be au- - tomatically turned off. + This command allows you to move an item from one particular + inventory slot to another so that it has a letter which is + more meaningful for you or that it will appear in a particu‐ + lar location when inventory listings are displayed. ‘‘#ad‐ + just’’ can also be used to split a stack of objects; when + choosing the item to adjust, enter a count prior to its let‐ + ter. - #untrap - Untrap something (trap, door, or chest). + #chat + Talk to someone. - #version - Print compile time options for this version of NetHack. + #conduct + List voluntary challenges you have maintained. - #wipe - Wipe off your face. + See the section below entitled ‘‘Conduct’’ for details. - #? Help menu: get the list of available extended commands. + #dip + Dip an object into something. - If your keyboard has a meta key (which, when pressed in com- - bination with another key, modifies it by setting the `meta' - [8th, or `high'] bit), you can invoke many extended commands by - meta-ing the first letter of the command. In NT, OS/2, and PC - NetHack, the `Alt' key can be used in this fashion. + #enhance + Advance or check weapon and spell skills. - M-? #? (not supported by all platforms) + #force + Force a lock. - M-2 #twoweapon (unless the number_pad option is enabled) + #invoke + Invoke an object’s special powers. - M-a #adjust + #jump + Jump to another location. - M-c #chat - - M-d #dip - - M-e #enhance - - M-f #force + #loot + Loot a box or bag on the floor beneath you, or the saddle + from a steed standing next to you. - - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -994,63 +994,63 @@ - M-i #invoke + #monster + Use a monster’s special ability (when polymorphed into mon‐ + ster form). - M-j #jump + #name + Name a monster, an individual object, or a type of object. + Same as ‘C’. - M-l #loot + #offer + Offer a sacrifice to the gods. - M-m #monster + You’ll need to find an altar to have any chance at success. + Corpses of recently killed monsters are the fodder of + choice. - M-n #name + #pray + Pray to the gods for help. - M-o #offer + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having re‐ + ceived help. You probably shouldn’t start off a new game by + praying right away.) Since using this command by accident + can cause trouble, there is an option to make you confirm + your intent before praying. It is enabled by default, and + you can reset the paranoid_confirmation option to disable + it. - M-p #pray + #quit + Quit the program without saving your game. - M-q #quit + Since using this command by accident would throw away the + current game, you are asked to confirm your intent before + quitting. By default a response of ’y’ acknowledges that + intent. You can set the paranoid_confirmation option to re‐ + quire a response of "yes" instead. - M-r #rub + #ride + Ride (or stop riding) a monster. - M-s #sit + #rub + Rub a lamp or a stone. - M-t #turn + #sit + Sit down. - M-u #untrap + #terrain + Show bare map without displaying monsters, objects, or + traps. - M-v #version + #tip + Tip over a container (bag or box) to pour out its contents. - M-w #wipe - - If the number_pad option is on, some additional letter com- - mands are available: - - h Help menu: display one of several help texts available, - like ``?''. - - j Jump to another location. Same as ``#jump'' or ``M-j''. - - k Kick something (usually a door). Same as `^D'. - - l Loot a box or bag on the floor beneath you, or the saddle - from a horse standing next to you. Same as ``#loot'' or - ``M-l''. - - N Name an item or type of object. Same as ``#name'' or ``M- - n''. - - u Untrap a trap, door, or chest. Same as ``#untrap'' or ``M- - u''. + #turn + Turn undead. - 5. Rooms and corridors - - Rooms and corridors in the dungeon are either lit or dark. - Any lit areas within your line of sight will be displayed; dark - areas are only displayed if they are within one space of you. - - - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -1060,63 +1060,63 @@ - Walls and corridors remain on the map as you explore them. + #twoweapon + Toggle two‐weapon combat on or off. - Secret corridors are hidden. You can find them with the `s' - (search) command. + Note that you must use suitable weapons for this type of + combat, or it will be automatically turned off. - 5.1. Doorways + #untrap + Untrap something (trap, door, or chest). - Doorways connect rooms and corridors. Some doorways have no - doors; you can walk right through. Others have doors in them, - which may be open, closed, or locked. To open a closed door, use - the `o' (open) command; to close it again, use the `c' (close) - command. + In some circumstances it can also be used to rescue trapped + monsters. - You can get through a locked door by using a tool to pick - the lock with the `a' (apply) command, or by kicking it open with - the `^D' (kick) command. + #version + Print compile time options for this version of NetHack. - Open doors cannot be entered diagonally; you must approach - them straight on, horizontally or vertically. Doorways without - doors are not restricted in this fashion. + #wipe + Wipe off your face. - Doors can be useful for shutting out monsters. Most mon- - sters cannot open doors, although a few don't need to (ex. ghosts - can walk through doors). + #? + Help menu: get the list of available extended commands. - Secret doors are hidden. You can find them with the `s' - (search) command. Once found they are in all ways equivalent to - normal doors. + If your keyboard has a meta key (which, when pressed in com‐ + bination with another key, modifies it by setting the ‘meta’ + [8th, or ‘high’] bit), you can invoke many extended commands by + meta‐ing the first letter of the command. In NT, OS/2, PC and ST + NetHack, the ‘Alt’ key can be used in this fashion; on the Amiga, + set the altmeta option to get this behavior. On other systems, + if typing ‘Alt’ plus another key transmits a two character se‐ + quence consisting of an Escape followed by the other key, you may + set the altmeta option to have nethack combine them into + meta+key. - 5.2. Traps (`^') + M‐? #? (not supported by all platforms) - There are traps throughout the dungeon to snare the unwary - delver. For example, you may suddenly fall into a pit and be - stuck for a few turns trying to climb out. Traps don't appear on - your map until you see one triggered by moving onto it, see some- - thing fall into it, or you discover it with the `s' (search) com- - mand. Monsters can fall prey to traps, too, which can be a very - useful defensive strategy. + M‐2 #twoweapon (unless the number_pad option is enabled) - There is a special pre-mapped branch of the dungeon based on - the classic computer game ``Sokoban.'' The goal is to push the - boulders into the pits or holes. With careful foresight, it is - possible to complete all of the levels according to the tradi- - tional rules of Sokoban. Some allowances are permitted in case - the player gets stuck; however, they will lower your luck. + M‐a #adjust - 5.3. Stairs (`<', `>') + M‐A #annotate (if supported) - In general, each level in the dungeon will have a staircase - going up (`<') to the previous level and another going down (`>') - to the next level. There are some exceptions though. For in- - stance, fairly early in the dungeon you will find a level with - two down staircases, one continuing into the dungeon and the oth- - er branching into an area known as the Gnomish Mines. Those + M‐c #chat + + M‐C #conduct + + M‐d #dip + + M‐e #enhance + + M‐f #force + + M‐i #invoke + + M‐j #jump - NetHack 3.5 September 20, 2006 + + NetHack 3.6 March 27, 2015 @@ -1126,63 +1126,63 @@ - mines eventually hit a dead end, so after exploring them (if you - choose to do so), you'll need to climb back up to the main dun- - geon. + M‐l #loot - When you traverse a set of stairs, or trigger a trap which - sends you to another level, the level you're leaving will be de- - activated and stored in a file on disk. If you're moving to a - previously visited level, it will be loaded from its file on disk - and reactivated. If you're moving to a level which has not yet - been visited, it will be created (from scratch for most random - levels, from a template for some ``special'' levels, or loaded - from the remains of an earlier game for a ``bones'' level as - briefly described below). Monsters are only active on the cur- - rent level; those on other levels are essentially placed into - stasis. + M‐m #monster - Ordinarily when you climb a set of stairs, you will arrive - on the corresponding staircase at your destination. However, - pets (see below) and some other monsters will follow along if - they're close enough when you travel up or down stairs, and occa- - sionally one of these creatures will displace you during the - climb. When that occurs, the pet or other monster will arrive on - the staircase and you will end up nearby. + M‐n #name - 5.4. Ladders (`<', `>') + M‐o #offer - Ladders serve the same purpose as staircases, and the two - types of inter-level connections are nearly indistinguishable - during game play. + M‐O #overview (if supported) - 5.5. Shops and shopping + M‐p #pray - Occasionally you will run across a room with a shopkeeper - near the door and many items lying on the floor. You can buy - items by picking them up and then using the `p' command. You can - inquire about the price of an item prior to picking it up by us- - ing the ``#chat'' command while standing on it. Using an item - prior to paying for it will incur a charge, and the shopkeeper - won't allow you to leave the shop until you have paid any debt - you owe. + M‐q #quit - You can sell items to a shopkeeper by dropping them to the - floor while inside a shop. You will either be offered an amount - of gold and asked whether you're willing to sell, or you'll be - told that the shopkeeper isn't interested (generally, your item - needs to be compatible with the type of merchandise carried by - the shop). + M‐r #rub - If you drop something in a shop by accident, the shopkeeper - will usually claim ownership without offering any compensation. - You'll have to buy it back if you want to reclaim it. + M‐R #ride (if supported) - Shopkeepers sometimes run out of money. When that happens, - you'll be offered credit instead of gold when you try to sell + M‐s #sit + + M‐t #turn + + M‐T #tip + + M‐u #untrap + + M‐v #version + + M‐w #wipe + + If the number_pad option is on, some additional letter com‐ + mands are available: + + h Help menu: display one of several help texts available, + like ‘‘?’’. + + j Jump to another location. Same as ‘‘#jump’’ or ‘‘M‐j’’. + + k Kick something (usually a door). Same as ‘^D’. + + l Loot a box or bag on the floor beneath you, or the saddle + from a steed standing next to you. Same as ‘‘#loot’’ or + ‘‘M‐l’’. + + N Name a monster, an individual object, or a type of object. + Same as ‘‘#name’’ (or ‘‘M‐n’’) which is the same as the ‘C’ + command. + + u Untrap a trap, door, or chest. Same as ‘‘#untrap’’ or ‘‘M‐ + u’’. - NetHack 3.5 September 20, 2006 + + + + + NetHack 3.6 March 27, 2015 @@ -1192,17 +1192,157 @@ + 5. Rooms and corridors + + Rooms and corridors in the dungeon are either lit or dark. + Any lit areas within your line of sight will be displayed; dark + areas are only displayed if they are within one space of you. + Walls and corridors remain on the map as you explore them. + + Secret corridors are hidden. You can find them with the ‘s’ + (search) command. + + 5.1. Doorways + + Doorways connect rooms and corridors. Some doorways have no + doors; you can walk right through. Others have doors in them, + which may be open, closed, or locked. To open a closed door, use + the ‘o’ (open) command; to close it again, use the ‘c’ (close) + command. + + You can get through a locked door by using a tool to pick + the lock with the ‘a’ (apply) command, or by kicking it open with + the ‘^D’ (kick) command. + + Open doors cannot be entered diagonally; you must approach + them straight on, horizontally or vertically. Doorways without + doors are not restricted in this fashion. + + Doors can be useful for shutting out monsters. Most mon‐ + sters cannot open doors, although a few don’t need to (ex. ghosts + can walk through doors). + + Secret doors are hidden. You can find them with the ‘s’ + (search) command. Once found they are in all ways equivalent to + normal doors. + + 5.2. Traps (‘^’) + + There are traps throughout the dungeon to snare the unwary + delver. For example, you may suddenly fall into a pit and be + stuck for a few turns trying to climb out. Traps don’t appear on + your map until you see one triggered by moving onto it, see some‐ + thing fall into it, or you discover it with the ‘s’ (search) com‐ + mand. Monsters can fall prey to traps, too, which can be a very + useful defensive strategy. + + There is a special pre‐mapped branch of the dungeon based on + the classic computer game ‘‘Sokoban.’’ The goal is to push the + boulders into the pits or holes. With careful foresight, it is + possible to complete all of the levels according to the tradi‐ + tional rules of Sokoban. Some allowances are permitted in case + the player gets stuck; however, they will lower your luck. + + + + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 20 + + + + 5.3. Stairs (‘<’, ‘>’) + + In general, each level in the dungeon will have a staircase + going up (‘<’) to the previous level and another going down (‘>’) + to the next level. There are some exceptions though. For in‐ + stance, fairly early in the dungeon you will find a level with + two down staircases, one continuing into the dungeon and the oth‐ + er branching into an area known as the Gnomish Mines. Those + mines eventually hit a dead end, so after exploring them (if you + choose to do so), you’ll need to climb back up to the main dun‐ + geon. + + When you traverse a set of stairs, or trigger a trap which + sends you to another level, the level you’re leaving will be de‐ + activated and stored in a file on disk. If you’re moving to a + previously visited level, it will be loaded from its file on disk + and reactivated. If you’re moving to a level which has not yet + been visited, it will be created (from scratch for most random + levels, from a template for some ‘‘special’’ levels, or loaded + from the remains of an earlier game for a ‘‘bones’’ level as + briefly described below). Monsters are only active on the cur‐ + rent level; those on other levels are essentially placed into + stasis. + + Ordinarily when you climb a set of stairs, you will arrive + on the corresponding staircase at your destination. However, + pets (see below) and some other monsters will follow along if + they’re close enough when you travel up or down stairs, and occa‐ + sionally one of these creatures will displace you during the + climb. When that occurs, the pet or other monster will arrive on + the staircase and you will end up nearby. + + 5.4. Ladders (‘<’, ‘>’) + + Ladders serve the same purpose as staircases, and the two + types of inter‐level connections are nearly indistinguishable + during game play. + + 5.5. Shops and shopping + + Occasionally you will run across a room with a shopkeeper + near the door and many items lying on the floor. You can buy + items by picking them up and then using the ‘p’ command. You can + inquire about the price of an item prior to picking it up by us‐ + ing the ‘‘#chat’’ command while standing on it. Using an item + prior to paying for it will incur a charge, and the shopkeeper + won’t allow you to leave the shop until you have paid any debt + you owe. + + You can sell items to a shopkeeper by dropping them to the + floor while inside a shop. You will either be offered an amount + of gold and asked whether you’re willing to sell, or you’ll be + told that the shopkeeper isn’t interested (generally, your item + needs to be compatible with the type of merchandise carried by + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 21 + + + + the shop). + + If you drop something in a shop by accident, the shopkeeper + will usually claim ownership without offering any compensation. + You’ll have to buy it back if you want to reclaim it. + + Shopkeepers sometimes run out of money. When that happens, + you’ll be offered credit instead of gold when you try to sell something. Credit can be used to pay for purchases, but it is only good in the shop where it was obtained; other shopkeepers - won't honor it. (If you happen to find a "credit card" in the - dungeon, don't bother trying to use it in shops; shopkeepers will + won’t honor it. (If you happen to find a "credit card" in the + dungeon, don’t bother trying to use it in shops; shopkeepers will not accept it.) - The `$' command, which reports the amount of gold you are + The ‘$’ command, which reports the amount of gold you are carrying (in inventory, not inside bags or boxes), will also show - current shop debt or credit, if any. The `Iu' command lists un- - paid items (those which still belong to the shop) if you are car- - rying any. The `Ix' command shows an inventory-like display of + current shop debt or credit, if any. The ‘Iu’ command lists un‐ + paid items (those which still belong to the shop) if you are car‐ + rying any. The ‘Ix’ command shows an inventory‐like display of any unpaid items which have been used up, along with other shop fees, if any. @@ -1221,7 +1361,7 @@ * If a shop is "closed for inventory", it will not open of its own accord. - * Shops do not get restocked with new items, regardless of inven- + * Shops do not get restocked with new items, regardless of inven‐ tory depletion. @@ -1232,155 +1372,15 @@ magic items can help you locate them before they locate you (which some monsters can do very well). - The commands `/' and `;' may be used to obtain information - about those monsters who are displayed on the screen. The com- - mand `C' allows you to assign a name to a monster, which may be - useful to help distinguish one from another when multiple mon- - sters are present. Assigning a name which is just a space will - remove any prior name. - - The extended command ``#chat'' can be used to interact with - an adjacent monster. There is no actual dialog (in other words, - you don't get to choose what you'll say), but chatting with some - monsters such as a shopkeeper or the Oracle of Delphi can produce - useful results. + The commands ‘/’ and ‘;’ may be used to obtain information + about those monsters who are displayed on the screen. The com‐ + mand ‘‘#name’’, or its synonym ‘C’, allows you to assign a name + to a monster, which may be useful to help distinguish one from + another when multiple monsters are present. Assigning a name + which is just a space will remove any prior name. - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 20 - - - - 6.1. Fighting - - If you see a monster and you wish to fight it, just attempt - to walk into it. Many monsters you find will mind their own - business unless you attack them. Some of them are very dangerous - when angered. Remember: discretion is the better part of valor. - - If you can't see a monster (if it is invisible, or if you - are blinded), the symbol `I' will be shown when you learn of its - presence. If you attempt to walk into it, you will try to fight - it just like a monster that you can see; of course, if the mon- - ster has moved, you will attack empty air. If you guess that the - monster has moved and you don't wish to fight, you can use the - `m' command to move without fighting; likewise, if you don't re- - member a monster but want to try fighting anyway, you can use the - `F' command. - - 6.2. Your pet - - You start the game with a little dog (`d'), cat (`f'), or - pony (`u'), which follows you about the dungeon and fights mon- - sters with you. Like you, your pet needs food to survive. It - usually feeds itself on fresh carrion and other meats. If you're - worried about it or want to train it, you can feed it, too, by - throwing it food. A properly trained pet can be very useful un- - der certain circumstances. - - Your pet also gains experience from killing monsters, and - can grow over time, gaining hit points and doing more damage. - Initially, your pet may even be better at killing things than - you, which makes pets useful for low-level characters. - - Your pet will follow you up and down staircases if it is - next to you when you move. Otherwise your pet will be stranded - and may become wild. Similarly, when you trigger certain types - of traps which alter your location (for instance, a trap door - which drops you to a lower dungeon level), any adjacent pet will - accompany you and any non-adjacent pet will be left behind. Your - pet may trigger such traps itself; you will not be carried along - with it even if adjacent at the time. - - 6.3. Steeds - - Some types of creatures in the dungeon can actually be rid- - den if you have the right equipment and skill. Convincing a wild - beast to let you saddle it up is difficult to say the least. - Many a dungeoneer has had to resort to magic and wizardry in or- - der to forge the alliance. Once you do have the beast under your - control however, you can easily climb in and out of the saddle - with the `#ride' command. Lead the beast around the dungeon when - riding, in the same manner as you would move yourself. It is the - beast that you will see displayed on the map. - - - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 21 - - - - Riding skill is managed by the `#enhance' command. See the - section on Weapon proficiency for more information about that. - - 6.4. Bones levels - - You may encounter the shades and corpses of other adventur- - ers (or even former incarnations of yourself!) and their personal - effects. Ghosts are hard to kill, but easy to avoid, since - they're slow and do little damage. You can plunder the deceased - adventurer's possessions; however, they are likely to be cursed. - Beware of whatever killed the former player; it is probably still - lurking around, gloating over its last victory. - - - 7. Objects - - When you find something in the dungeon, it is common to want - to pick it up. In NetHack, this is accomplished automatically by - walking over the object (unless you turn off the autopickup op- - tion (see below), or move with the `m' prefix (see above)), or - manually by using the `,' command. - - If you're carrying too many items, NetHack will tell you so - and you won't be able to pick up anything more. Otherwise, it - will add the object(s) to your pack and tell you what you just - picked up. - - As you add items to your inventory, you also add the weight - of that object to your load. The amount that you can carry de- - pends on your strength and your constitution. The stronger you - are, the less the additional load will affect you. There comes a - point, though, when the weight of all of that stuff you are car- - rying around with you through the dungeon will encumber you. - Your reactions will get slower and you'll burn calories faster, - requiring food more frequently to cope with it. Eventually, - you'll be so overloaded that you'll either have to discard some - of what you're carrying or collapse under its weight. - - NetHack will tell you how badly you have loaded yourself. - The symbols `Burdened', `Stressed', `Strained', `Overtaxed' and - `Overloaded' are displayed on the bottom line display to indicate - your condition. - - When you pick up an object, it is assigned an inventory let- - ter. Many commands that operate on objects must ask you to find - out which object you want to use. When NetHack asks you to - choose a particular object you are carrying, you are usually pre- - sented with a list of inventory letters to choose from (see Com- - mands, above). - - Some objects, such as weapons, are easily differentiated. - Others, like scrolls and potions, are given descriptions which - vary according to type. During a game, any two objects with the - same description are the same type. However, the descriptions - - - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -1390,63 +1390,63 @@ - will vary from game to game. + The extended command ‘‘#chat’’ can be used to interact with + an adjacent monster. There is no actual dialog (in other words, + you don’t get to choose what you’ll say), but chatting with some + monsters such as a shopkeeper or the Oracle of Delphi can produce + useful results. - When you use one of these objects, if its effect is obvious, - NetHack will remember what it is for you. If its effect isn't - extremely obvious, you will be asked what you want to call this - type of object so you will recognize it later. You can also use - the ``#name'' command for the same purpose at any time, to name - all objects of a particular type or just an individual object. - When you use ``#name'' on an object which has already been named, - specifying a space as the value will remove the prior name in- - stead of assigning a new one. + 6.1. Fighting - 7.1. Curses and Blessings + If you see a monster and you wish to fight it, just attempt + to walk into it. Many monsters you find will mind their own + business unless you attack them. Some of them are very dangerous + when angered. Remember: discretion is the better part of valor. - Any object that you find may be cursed, even if the object - is otherwise helpful. The most common effect of a curse is being - stuck with (and to) the item. Cursed weapons weld themselves to - your hand when wielded, so you cannot unwield them. Any cursed - item you wear is not removable by ordinary means. In addition, - cursed arms and armor usually, but not always, bear negative en- - chantments that make them less effective in combat. Other cursed - objects may act poorly or detrimentally in other ways. + In most circumstances, if you attempt to attack a peaceful + monster by moving into its location, you’ll be asked to confirm + your intent. By default an answer of ’y’ acknowledges that in‐ + tent, which can be error prone if you’re using ’y’ to move. You + can set the paranoid_confirmation option to require a response of + "yes" instead. - Objects can also be blessed. Blessed items usually work - better or more beneficially than normal uncursed items. For ex- - ample, a blessed weapon will do more damage against demons. + If you can’t see a monster (if it is invisible, or if you + are blinded), the symbol ‘I’ will be shown when you learn of its + presence. If you attempt to walk into it, you will try to fight + it just like a monster that you can see; of course, if the mon‐ + ster has moved, you will attack empty air. If you guess that the + monster has moved and you don’t wish to fight, you can use the + ‘m’ command to move without fighting; likewise, if you don’t re‐ + member a monster but want to try fighting anyway, you can use the + ‘F’ command. - There are magical means of bestowing or removing curses upon - objects, so even if you are stuck with one, you can still have - the curse lifted and the item removed. Priests and Priestesses - have an innate sensitivity to this property in any object, so - they can more easily avoid cursed objects than other character - roles. + 6.2. Your pet - An item with unknown status will be reported in your inven- - tory with no prefix. An item which you know the state of will be - distinguished in your inventory by the presence of the word - ``cursed'', ``uncursed'' or ``blessed'' in the description of the - item. + You start the game with a little dog (‘d’), cat (‘f’), or + pony (‘u’), which follows you about the dungeon and fights mon‐ + sters with you. Like you, your pet needs food to survive. It + usually feeds itself on fresh carrion and other meats. If you’re + worried about it or want to train it, you can feed it, too, by + throwing it food. A properly trained pet can be very useful un‐ + der certain circumstances. - 7.2. Weapons (`)') + Your pet also gains experience from killing monsters, and + can grow over time, gaining hit points and doing more damage. + Initially, your pet may even be better at killing things than + you, which makes pets useful for low‐level characters. - Given a chance, most monsters in the Mazes of Menace will - gratuitously try to kill you. You need weapons for self-defense - (killing them first). Without a weapon, you do only 1-2 hit - points of damage (plus bonuses, if any). Monk characters are an - exception; they normally do much more damage with bare hands than - they do with weapons. - - There are wielded weapons, like maces and swords, and thrown - weapons, like arrows and spears. To hit monsters with a weapon, - you must wield it and attack them, or throw it at them. You can - simply elect to throw a spear. To shoot an arrow, you should - first wield a bow, then throw the arrow. Crossbows shoot + Your pet will follow you up and down staircases if it is + next to you when you move. Otherwise your pet will be stranded + and may become wild. Similarly, when you trigger certain types + of traps which alter your location (for instance, a trap door + which drops you to a lower dungeon level), any adjacent pet will + accompany you and any non‐adjacent pet will be left behind. Your + pet may trigger such traps itself; you will not be carried along + with it even if adjacent at the time. - NetHack 3.5 September 20, 2006 + + NetHack 3.6 March 27, 2015 @@ -1456,63 +1456,63 @@ - crossbow bolts. Slings hurl rocks and (other) stones (like - gems). + 6.3. Steeds - Enchanted weapons have a ``plus'' (or ``to hit enhancement'' - which can be either positive or negative) that adds to your - chance to hit and the damage you do to a monster. The only way - to determine a weapon's enchantment is to have it magically iden- - tified somehow. Most weapons are subject to some type of damage - like rust. Such ``erosion'' damage can be repaired. + Some types of creatures in the dungeon can actually be rid‐ + den if you have the right equipment and skill. Convincing a wild + beast to let you saddle it up is difficult to say the least. + Many a dungeoneer has had to resort to magic and wizardry in or‐ + der to forge the alliance. Once you do have the beast under your + control however, you can easily climb in and out of the saddle + with the ‘#ride’ command. Lead the beast around the dungeon when + riding, in the same manner as you would move yourself. It is the + beast that you will see displayed on the map. - The chance that an attack will successfully hit a monster, - and the amount of damage such a hit will do, depends upon many - factors. Among them are: type of weapon, quality of weapon (en- - chantment and/or erosion), experience level, strength, dexterity, - encumbrance, and proficiency (see below). The monster's armor - class - a general defense rating, not necessarily due to wearing - of armor - is a factor too; also, some monsters are particularly - vulnerable to certain types of weapons. + Riding skill is managed by the ‘#enhance’ command. See the + section on Weapon proficiency for more information about that. - Many weapons can be wielded in one hand; some require both - hands. When wielding a two-handed weapon, you can not wear a - shield, and vice versa. When wielding a one-handed weapon, you - can have another weapon ready to use by setting things up with - the `x' command, which exchanges your primary (the one being - wielded) and alternate weapons. And if you have proficiency in - the ``two weapon combat'' skill, you may wield both weapons si- - multaneously as primary and secondary; use the `#twoweapon' ex- - tended command to engage or disengage that. Only some types of - characters (barbarians, for instance) have the necessary skill - available. Even with that skill, using two weapons at once in- - curs a penalty in the chance to hit your target compared to using - just one weapon at a time. + 6.4. Bones levels - There might be times when you'd rather not wield any weapon - at all. To accomplish that, wield `-', or else use the `A' com- - mand which allows you to unwield the current weapon in addition - to taking off other worn items. - - Those of you in the audience who are AD&D players, be aware - that each weapon which existed in AD&D does roughly the same dam- - age to monsters in NetHack. Some of the more obscure weapons - (such as the aklys, lucern hammer, and bec-de-corbin) are defined - in an appendix to Unearthed Arcana, an AD&D supplement. - - The commands to use weapons are `w' (wield), `t' (throw), - `f' (fire, an alternative way of throwing), `Q' (quiver), `x' - (exchange), `#twoweapon', and `#enhance' (see below). - - 7.2.1. Throwing and shooting - - You can throw just about anything via the `t' command. It - will prompt for the item to throw; picking `?' will list things - in your inventory which are considered likely to be thrown, or - picking `*' will list your entire inventory. After you've chosen + You may encounter the shades and corpses of other adventur‐ + ers (or even former incarnations of yourself!) and their personal + effects. Ghosts are hard to kill, but easy to avoid, since + they’re slow and do little damage. You can plunder the deceased + adventurer’s possessions; however, they are likely to be cursed. + Beware of whatever killed the former player; it is probably still + lurking around, gloating over its last victory. - NetHack 3.5 September 20, 2006 + 7. Objects + + When you find something in the dungeon, it is common to want + to pick it up. In NetHack, this is accomplished automatically by + walking over the object (unless you turn off the autopickup op‐ + tion (see below), or move with the ‘m’ prefix (see above)), or + manually by using the ‘,’ command. + + If you’re carrying too many items, NetHack will tell you so + and you won’t be able to pick up anything more. Otherwise, it + will add the object(s) to your pack and tell you what you just + picked up. + + As you add items to your inventory, you also add the weight + of that object to your load. The amount that you can carry de‐ + pends on your strength and your constitution. The stronger you + are, the less the additional load will affect you. There comes a + point, though, when the weight of all of that stuff you are car‐ + rying around with you through the dungeon will encumber you. + Your reactions will get slower and you’ll burn calories faster, + requiring food more frequently to cope with it. Eventually, + you’ll be so overloaded that you’ll either have to discard some + of what you’re carrying or collapse under its weight. + + NetHack will tell you how badly you have loaded yourself. + The symbols ‘Burdened’, ‘Stressed’, ‘Strained’, ‘Overtaxed’ and + ‘Overloaded’ are displayed on the bottom line display to indicate + your condition. + + + NetHack 3.6 March 27, 2015 @@ -1522,63 +1522,63 @@ - what to throw, you will be prompted for a direction rather than - for a specific target. The distance something can be thrown de- - pends mainly on the type of object and your strength. Arrows can - be thrown by hand, but can be thrown much farther and will be - more likely to hit when thrown while you are wielding a bow. + When you pick up an object, it is assigned an inventory let‐ + ter. Many commands that operate on objects must ask you to find + out which object you want to use. When NetHack asks you to + choose a particular object you are carrying, you are usually pre‐ + sented with a list of inventory letters to choose from (see Com‐ + mands, above). - You can simplify the throwing operation by using the `Q' - command to select your preferred ``missile'', then using the `f' - command to throw it. You'll be prompted for a direction as - above, but you don't have to specify which item to throw each - time you use `f'. There is also an option, autoquiver, which has - NetHack choose another item to automatically fill your quiver - when the inventory slot used for `Q' runs out. + Some objects, such as weapons, are easily differentiated. + Others, like scrolls and potions, are given descriptions which + vary according to type. During a game, any two objects with the + same description are the same type. However, the descriptions + will vary from game to game. - Some characters have the ability to fire a volley of multi- - ple items in a single turn. Knowing how to load several rounds - of ammunition at once -- or hold several missiles in your hand -- - and still hit a target is not an easy task. Rangers are among - those who are adept at this task, as are those with a high level - of proficiency in the relevant weapon skill (in bow skill if - you're wielding one to shoot arrows, in crossbow skill if you're - wielding one to shoot bolts, or in sling skill if you're wielding - one to shoot stones). The number of items that the character has - a chance to fire varies from turn to turn. You can explicitly - limit the number of shots by using a numeric prefix before the - `t' or `f' command. For example, ``2f'' (or ``n2f'' if using - number_pad mode) would ensure that at most 2 arrows are shot even - if you could have fired 3. If you specify a larger number than - would have been shot (``4f'' in this example), you'll just end up - shooting the same number (3, here) as if no limit had been speci- - fied. Once the volley is in motion, all of the items will travel - in the same direction; if the first ones kill a monster, the oth- - ers can still continue beyond that spot. + When you use one of these objects, if its effect is obvious, + NetHack will remember what it is for you. If its effect isn’t + extremely obvious, you will be asked what you want to call this + type of object so you will recognize it later. You can also use + the ‘‘#name’’ command, or its synonym ‘C’, for the same purpose + at any time, to name all objects of a particular type or just an + individual object. When you use ‘‘#name’’ on an object which has + already been named, specifying a space as the value will remove + the prior name instead of assigning a new one. - 7.2.2. Weapon proficiency + 7.1. Curses and Blessings - You will have varying degrees of skill in the weapons avail- - able. Weapon proficiency, or weapon skills, affect how well you - can use particular types of weapons, and you'll be able to im- - prove your skills as you progress through a game, depending on - your role, your experience level, and use of the weapons. + Any object that you find may be cursed, even if the object + is otherwise helpful. The most common effect of a curse is being + stuck with (and to) the item. Cursed weapons weld themselves to + your hand when wielded, so you cannot unwield them. Any cursed + item you wear is not removable by ordinary means. In addition, + cursed arms and armor usually, but not always, bear negative en‐ + chantments that make them less effective in combat. Other cursed + objects may act poorly or detrimentally in other ways. - For the purposes of proficiency, weapons have been divided - up into various groups such as daggers, broadswords, and - polearms. Each role has a limit on what level of proficiency a - character can achieve for each group. For instance, wizards can - become highly skilled in daggers or staves but not in swords or - bows. + Objects can also be blessed. Blessed items usually work + better or more beneficially than normal uncursed items. For ex‐ + ample, a blessed weapon will do more damage against demons. - The `#enhance' extended command is used to review current - weapons proficiency (also spell proficiency) and to choose which - skill(s) to improve when you've used one or more skills enough to - become eligible to do so. The skill rankings are ``none'' (some- - times also referred to as ``restricted'', because you won't be + There are magical means of bestowing or removing curses upon + objects, so even if you are stuck with one, you can still have + the curse lifted and the item removed. Priests and Priestesses + have an innate sensitivity to this property in any object, so + they can more easily avoid cursed objects than other character + roles. + + An item with unknown status will be reported in your inven‐ + tory with no prefix. An item which you know the state of will be + distinguished in your inventory by the presence of the word + ‘‘cursed’’, ‘‘uncursed’’ or ‘‘blessed’’ in the description of the + item. - NetHack 3.5 September 20, 2006 + + + + + NetHack 3.6 March 27, 2015 @@ -1588,35 +1588,230 @@ - able to advance), ``unskilled'', ``basic'', ``skilled'', and - ``expert''. Restricted skills simply will not appear in the list - shown by `#enhance'. (Divine intervention might unrestrict a - particular skill, in which case it will start at unskilled and be - limited to basic.) Some characters can enhance their barehanded - combat or martial arts skill beyond expert to ``master'' or - ``grand master''. + 7.2. Weapons (‘)’) - Use of a weapon in which you're restricted or unskilled will + Given a chance, most monsters in the Mazes of Menace will + gratuitously try to kill you. You need weapons for self‐defense + (killing them first). Without a weapon, you do only 1‐2 hit + points of damage (plus bonuses, if any). Monk characters are an + exception; they normally do much more damage with bare hands than + they do with weapons. + + There are wielded weapons, like maces and swords, and thrown + weapons, like arrows and spears. To hit monsters with a weapon, + you must wield it and attack them, or throw it at them. You can + simply elect to throw a spear. To shoot an arrow, you should + first wield a bow, then throw the arrow. Crossbows shoot cross‐ + bow bolts. Slings hurl rocks and (other) stones (like gems). + + Enchanted weapons have a ‘‘plus’’ (or ‘‘to hit enhancement’’ + which can be either positive or negative) that adds to your + chance to hit and the damage you do to a monster. The only way + to determine a weapon’s enchantment is to have it magically iden‐ + tified somehow. Most weapons are subject to some type of damage + like rust. Such ‘‘erosion’’ damage can be repaired. + + The chance that an attack will successfully hit a monster, + and the amount of damage such a hit will do, depends upon many + factors. Among them are: type of weapon, quality of weapon (en‐ + chantment and/or erosion), experience level, strength, dexterity, + encumbrance, and proficiency (see below). The monster’s armor + class ‐ a general defense rating, not necessarily due to wearing + of armor ‐ is a factor too; also, some monsters are particularly + vulnerable to certain types of weapons. + + Many weapons can be wielded in one hand; some require both + hands. When wielding a two‐handed weapon, you can not wear a + shield, and vice versa. When wielding a one‐handed weapon, you + can have another weapon ready to use by setting things up with + the ‘x’ command, which exchanges your primary (the one being + wielded) and alternate weapons. And if you have proficiency in + the ‘‘two weapon combat’’ skill, you may wield both weapons si‐ + multaneously as primary and secondary; use the ‘#twoweapon’ ex‐ + tended command to engage or disengage that. Only some types of + characters (barbarians, for instance) have the necessary skill + available. Even with that skill, using two weapons at once in‐ + curs a penalty in the chance to hit your target compared to using + just one weapon at a time. + + There might be times when you’d rather not wield any weapon + at all. To accomplish that, wield ‘‐’, or else use the ‘A’ com‐ + mand which allows you to unwield the current weapon in addition + to taking off other worn items. + + Those of you in the audience who are AD&D players, be aware + that each weapon which existed in AD&D does roughly the same dam‐ + age to monsters in NetHack. Some of the more obscure weapons + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 26 + + + + (such as the aklys, lucern hammer, and bec‐de‐corbin) are defined + in an appendix to Unearthed Arcana, an AD&D supplement. + + The commands to use weapons are ‘w’ (wield), ‘t’ (throw), + ‘f’ (fire, an alternative way of throwing), ‘Q’ (quiver), ‘x’ + (exchange), ‘#twoweapon’, and ‘#enhance’ (see below). + + 7.2.1. Throwing and shooting + + You can throw just about anything via the ‘t’ command. It + will prompt for the item to throw; picking ‘?’ will list things + in your inventory which are considered likely to be thrown, or + picking ‘*’ will list your entire inventory. After you’ve chosen + what to throw, you will be prompted for a direction rather than + for a specific target. The distance something can be thrown de‐ + pends mainly on the type of object and your strength. Arrows can + be thrown by hand, but can be thrown much farther and will be + more likely to hit when thrown while you are wielding a bow. + + You can simplify the throwing operation by using the ‘Q’ + command to select your preferred ‘‘missile’’, then using the ‘f’ + command to throw it. You’ll be prompted for a direction as + above, but you don’t have to specify which item to throw each + time you use ‘f’. There is also an option, autoquiver, which has + NetHack choose another item to automatically fill your quiver (or + quiver sack, or have at the ready) when the inventory slot used + for ‘Q’ runs out. + + Some characters have the ability to fire a volley of multi‐ + ple items in a single turn. Knowing how to load several rounds + of ammunition at once ‐‐ or hold several missiles in your hand ‐‐ + and still hit a target is not an easy task. Rangers are among + those who are adept at this task, as are those with a high level + of proficiency in the relevant weapon skill (in bow skill if + you’re wielding one to shoot arrows, in crossbow skill if you’re + wielding one to shoot bolts, or in sling skill if you’re wielding + one to shoot stones). The number of items that the character has + a chance to fire varies from turn to turn. You can explicitly + limit the number of shots by using a numeric prefix before the + ‘t’ or ‘f’ command. For example, ‘‘2f’’ (or ‘‘n2f’’ if using + number_pad mode) would ensure that at most 2 arrows are shot even + if you could have fired 3. If you specify a larger number than + would have been shot (‘‘4f’’ in this example), you’ll just end up + shooting the same number (3, here) as if no limit had been speci‐ + fied. Once the volley is in motion, all of the items will travel + in the same direction; if the first ones kill a monster, the oth‐ + ers can still continue beyond that spot. + + 7.2.2. Weapon proficiency + + You will have varying degrees of skill in the weapons avail‐ + able. Weapon proficiency, or weapon skills, affect how well you + can use particular types of weapons, and you’ll be able to im‐ + prove your skills as you progress through a game, depending on + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 27 + + + + your role, your experience level, and use of the weapons. + + For the purposes of proficiency, weapons have been divided + up into various groups such as daggers, broadswords, and + polearms. Each role has a limit on what level of proficiency a + character can achieve for each group. For instance, wizards can + become highly skilled in daggers or staves but not in swords or + bows. + + The ‘#enhance’ extended command is used to review current + weapons proficiency (also spell proficiency) and to choose which + skill(s) to improve when you’ve used one or more skills enough to + become eligible to do so. The skill rankings are ‘‘none’’ (some‐ + times also referred to as ‘‘restricted’’, because you won’t be + able to advance), ‘‘unskilled’’, ‘‘basic’’, ‘‘skilled’’, and + ‘‘expert’’. Restricted skills simply will not appear in the list + shown by ‘#enhance’. (Divine intervention might unrestrict a + particular skill, in which case it will start at unskilled and be + limited to basic.) Some characters can enhance their barehanded + combat or martial arts skill beyond expert to ‘‘master’’ or + ‘‘grand master’’. + + Use of a weapon in which you’re restricted or unskilled will incur a modest penalty in the chance to hit a monster and also in - the amount of damage done when you do hit; at basic level, there - is no penalty or bonus; at skilled level, you receive a modest - bonus in the chance to hit and amount of damage done; at expert - level, the bonus is higher. A successful hit has a chance to - boost your training towards the next skill level (unless you've - already reached the limit for this skill). Once such training - reaches the threshold for that next level, you'll be told that - you feel more confident in your skills. At that point you can - use `#enhance' to increase one or more skills. Such skills are - not increased automatically because there is a limit to your to- - tal overall skills, so you need to actively choose which skills + the amount of damage done when you do hit; at basic level, there + is no penalty or bonus; at skilled level, you receive a modest + bonus in the chance to hit and amount of damage done; at expert + level, the bonus is higher. A successful hit has a chance to + boost your training towards the next skill level (unless you’ve + already reached the limit for this skill). Once such training + reaches the threshold for that next level, you’ll be told that + you feel more confident in your skills. At that point you can + use ‘#enhance’ to increase one or more skills. Such skills are + not increased automatically because there is a limit to your to‐ + tal overall skills, so you need to actively choose which skills to enhance and which to ignore. - 7.3. Armor (`[') + 7.2.3. Two‐Weapon combat - Lots of unfriendly things lurk about; you need armor to pro- + Some characters can use two weapons at once. Setting things + up to do so can seem cumbersome but becomes second nature with + use. To wield two weapons, you need to use the ‘‘#twoweapon’’ + command. But first you need to have a weapon in each hand. + (Note that your two weapons are not fully equal; the one in the + hand you normally wield with is considered primary and the other + one is considered secondary. The most noticeable difference is + after you stop‐‐or before you begin, for that matter‐‐wielding + two weapons at once. The primary is your wielded weapon and the + secondary is just an item in your inventory that’s been designat‐ + ed as alternate weapon.) + + If your primary weapon is wielded but your off hand is empty + or has the wrong weapon, use the sequence ’x’, ’w’, ’x’ to first + swap your primary into your off hand, wield whatever you want as + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 28 + + + + secondary weapon, then swap them both back into the intended + hands. If your secondary or alternate weapon is correct but your + primary one is not, simply use ’w’ to wield the primary. Lastly, + if neither hand holds the correct weapon, use ’w’, ’x’, ’w’ to + first wield the intended secondary, swap it to off hand, and then + wield the primary. + + The whole process can be simplified via use of the push‐ + weapon option. When it is enabled, then using ’w’ to wield some‐ + thing causes the currently wielded weapon to become your alter‐ + nate weapon. So the sequence ’w’, ’w’ can be used to first wield + the weapon you intend to be secondary, and then wield the one you + want as primary which will push the first into secondary posi‐ + tion. + + When in two‐weapon combat mode, using the ‘‘#twoweapon’’ + command toggles back to single‐weapon mode. Throwing or dropping + either of the weapons or having one of them be stolen or de‐ + stroyed will also make you revert to single‐weapon combat. + + 7.3. Armor (‘[’) + + Lots of unfriendly things lurk about; you need armor to pro‐ tect yourself from their blows. Some types of armor offer better protection than others. Your armor class is a measure of this - protection. Armor class (AC) is measured as in AD&D, with 10 be- + protection. Armor class (AC) is measured as in AD&D, with 10 be‐ ing the equivalent of no armor, and lower numbers meaning better armor. Each suit of armor which exists in AD&D gives the same protection in NetHack. Here is an (incomplete) list of the armor @@ -1628,8 +1823,8 @@ bronze plate mail 4 splint mail 4 banded mail 4 - dwarvish mithril-coat 4 - elven mithril-coat 5 + dwarvish mithril‐coat 4 + elven mithril‐coat 5 chain mail 5 orcish chain mail 6 scale mail 6 @@ -1642,103 +1837,103 @@ You can also wear other pieces of armor (ex. helmets, boots, shields, cloaks) to lower your armor class even further, but you - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 26 - - - can only wear one item of each category (one suit of armor, one cloak, one helmet, one shield, and so on) at a time. + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 29 + + + If a piece of armor is enchanted, its armor protection will - be better (or worse) than normal, and its ``plus'' (or minus) + be better (or worse) than normal, and its ‘‘plus’’ (or minus) will subtract from your armor class. For example, a +1 chain mail would give you better protection than normal chain mail, lowering your armor class one unit further to 4. When you put on a piece of armor, you immediately find out the armor class and - any ``plusses'' it provides. Cursed pieces of armor usually have + any ‘‘plusses’’ it provides. Cursed pieces of armor usually have negative enchantments (minuses) in addition to being unremovable. Many types of armor are subject to some kind of damage like - rust. Such damage can be repaired. Some types of armor may in- + rust. Such damage can be repaired. Some types of armor may in‐ hibit spell casting. - The commands to use armor are `W' (wear) and `T' (take off). - The `A' command can also be used to take off armor as well as + The commands to use armor are ‘W’ (wear) and ‘T’ (take off). + The ‘A’ command can also be used to take off armor as well as other worn items. - 7.4. Food (`%') + 7.4. Food (‘%’) Food is necessary to survive. If you go too long without eating you will faint, and eventually die of starvation. Some types of food will spoil, and become unhealthy to eat, if not - protected. Food stored in ice boxes or tins (``cans'') will usu- + protected. Food stored in ice boxes or tins (‘‘cans’’) will usu‐ ally stay fresh, but ice boxes are heavy, and tins take a while to open. When you kill monsters, they usually leave corpses which are - also ``food.'' Many, but not all, of these are edible; some also + also ‘‘food.’’ Many, but not all, of these are edible; some also give you special powers when you eat them. A good rule of thumb - is ``you are what you eat.'' + is ‘‘you are what you eat.’’ - Some character roles and some monsters are vegetarian. Veg- + Some character roles and some monsters are vegetarian. Veg‐ etarian monsters will typically never eat animal corpses, while - vegetarian players can, but with some rather unpleasant side-ef- + vegetarian players can, but with some rather unpleasant side‐ef‐ fects. You can name one food item after something you like to eat with the fruit option. - The command to eat food is `e'. + The command to eat food is ‘e’. - 7.5. Scrolls (`?') + 7.5. Scrolls (‘?’) Scrolls are labeled with various titles, probably chosen by - ancient wizards for their amusement value (ex. ``READ ME,'' or - ``THANX MAUD'' backwards). Scrolls disappear after you read them + ancient wizards for their amusement value (ex. ‘‘READ ME,’’ or + ‘‘THANX MAUD’’ backwards). Scrolls disappear after you read them (except for blank ones, without magic spells on them). One of the most useful of these is the scroll of identify, which can be used to determine what another object is, whether it - is cursed or blessed, and how many uses it has left. Some - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 27 - - - - objects of subtle enchantment are difficult to identify without + is cursed or blessed, and how many uses it has left. Some ob‐ + jects of subtle enchantment are difficult to identify without these. + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 30 + + + A mail daemon may run up and deliver mail to you as a scroll of mail (on versions compiled with this feature). To use this feature on versions where NetHack mail delivery is triggered by electronic mail appearing in your system mailbox, you must let - NetHack know where to look for new mail by setting the ``MAIL'' + NetHack know where to look for new mail by setting the ‘‘MAIL’’ environment variable to the file name of your mailbox. You may - also want to set the ``MAILREADER'' environment variable to the + also want to set the ‘‘MAILREADER’’ environment variable to the file name of your favorite reader, so NetHack can shell to it when you read the scroll. On versions of NetHack where mail is - randomly generated internal to the game, these environment vari- + randomly generated internal to the game, these environment vari‐ ables are ignored. You can disable the mail daemon by turning off the mail option. - The command to read a scroll is `r'. + The command to read a scroll is ‘r’. - 7.6. Potions (`!') + 7.6. Potions (‘!’) Potions are distinguished by the color of the liquid inside the flask. They disappear after you quaff them. @@ -1746,22 +1941,22 @@ Clear potions are potions of water. Sometimes these are blessed or cursed, resulting in holy or unholy water. Holy water is the bane of the undead, so potions of holy water are good - things to throw (`t') at them. It is also sometimes very useful - to dip (``#dip'') an object into a potion. + things to throw (‘t’) at them. It is also sometimes very useful + to dip (‘‘#dip’’) an object into a potion. - The command to drink a potion is `q' (quaff). + The command to drink a potion is ‘q’ (quaff). - 7.7. Wands (`/') + 7.7. Wands (‘/’) Magic wands usually have multiple magical charges. Some - wands are directional--you must give a direction in which to zap - them. You can also zap them at yourself (just give a `.' or `s' + wands are directional—you must give a direction in which to zap + them. You can also zap them at yourself (just give a ‘.’ or ‘s’ for the direction). Be warned, however, for this is often unwise. - Other wands are nondirectional--they don't require a direction. + Other wands are nondirectional—they don’t require a direction. The number of charges in a wand is random and decreases by one whenever you use it. - When the number of charges left in a wand becomes zero, at- + When the number of charges left in a wand becomes zero, at‐ tempts to use the wand will usually result in nothing happening. Occasionally, however, it may be possible to squeeze the last few mana points from an otherwise spent wand, destroying it in the @@ -1772,32 +1967,33 @@ In a truly desperate situation, when your back is up against the wall, you might decide to go for broke and break your wand. - This is not for the faint of heart. Doing so will almost cer- + This is not for the faint of heart. Doing so will almost cer‐ tainly cause a catastrophic release of magical energies. - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 28 - - - When you have fully identified a particular wand, inventory display will include additional information in parentheses: the + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 31 + + + number of times it has been recharged followed by a colon and then by its current number of charges. A current charge count of - -1 is a special case indicating that the wand has been cancelled. + ‐1 is a special case indicating that the wand has been cancelled. - The command to use a wand is `z' (zap). To break one, use - the `a' (apply) command. + The command to use a wand is ‘z’ (zap). To break one, use + the ‘a’ (apply) command. - 7.8. Rings (`=') + 7.8. Rings (‘=’) - Rings are very useful items, since they are relatively per- + Rings are very useful items, since they are relatively per‐ manent magic, unlike the usually fleeting effects of potions, scrolls, and wands. @@ -1807,15 +2003,15 @@ Most rings also cause you to grow hungry more rapidly, the rate varying with the type of ring. - The commands to use rings are `P' (put on) and `R' (remove). + The commands to use rings are ‘P’ (put on) and ‘R’ (remove). - 7.9. Spellbooks (`+') + 7.9. Spellbooks (‘+’) Spellbooks are tomes of mighty magic. When studied with the - `r' (read) command, they transfer to the reader the knowledge of - a spell (and therefore eventually become unreadable) -- unless - the attempt backfires. Reading a cursed spellbook or one with - mystic runes beyond your ken can be harmful to your health! + ‘r’ (read) command, they transfer to the reader the knowledge of + a spell (and therefore eventually become unreadable) — unless the + attempt backfires. Reading a cursed spellbook or one with mystic + runes beyond your ken can be harmful to your health! A spell (even when learned) can also backfire when you cast it. If you attempt to cast a spell well above your experience @@ -1827,98 +2023,100 @@ Casting a spell calls forth magical energies and focuses them with your naked mind. Some of the magical energy released comes from within you, and casting several spells in a row may - tire you. Casting of spells also requires practice. With prac- + tire you. Casting of spells also requires practice. With prac‐ tice, your skill in each category of spell casting will improve. Over time, however, your memory of each spell will dim, and you will need to relearn it. - Some spells are directional--you must give a direction in + Some spells are directional—you must give a direction in which to cast them. You can also cast them at yourself (just - give a `.' or `s' for the direction). Be warned, however, for - this is often unwise. Other spells are nondirectional--they - don't require a direction. + give a ‘.’ or ‘s’ for the direction). Be warned, however, for + this is often unwise. Other spells are nondirectional—they don’t + require a direction. Just as weapons are divided into groups in which a character can become proficient (to varying degrees), spells are similarly - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 29 - - - grouped. Successfully casting a spell exercises its skill group; - using the `#enhance' command to advance a sufficiently exercised + using the ‘#enhance’ command to advance a sufficiently exercised + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 32 + + + skill will affect all spells within the group. Advanced skill may increase the potency of spells, reduce their risk of failure during casting attempts, and improve the accuracy of the estimate for how much longer they will be retained in your memory. Skill slots are shared with weapons skills. (See also the section on - ``Weapon proficiency''.) + ‘‘Weapon proficiency’’.) Casting a spell also requires flexible movement, and wearing various types of armor may interfere with that. The command to read a spellbook is the same as for scrolls, - `r' (read). The `+' command lists each spell you know along with + ‘r’ (read). The ‘+’ command lists each spell you know along with its level, skill category, chance of failure when casting, and an - estimate of how strongly it is remembered. The `Z' (cast) com- + estimate of how strongly it is remembered. The ‘Z’ (cast) com‐ mand casts a spell. - 7.10. Tools (`(') + 7.10. Tools (‘(’) Tools are miscellaneous objects with various purposes. Some tools have a limited number of uses, akin to wand charges. For - example, lamps burn out after a while. Other tools are contain- + example, lamps burn out after a while. Other tools are contain‐ ers, which objects can be placed into or taken out of. - The command to use tools is `a' (apply). + The command to use tools is ‘a’ (apply). 7.10.1. Containers You may encounter bags, boxes, and chests in your travels. - A tool of this sort can be opened with the ``#loot'' extended + A tool of this sort can be opened with the ‘‘#loot’’ extended command when you are standing on top of it (that is, on the same - floor spot), or with the `a' (apply) command when you are carry- + floor spot), or with the ‘a’ (apply) command when you are carry‐ ing it. However, chests are often locked, and are in any case unwieldy objects. You must set one down before unlocking it by - using a key or lock-picking tool with the `a' (apply) command, by - kicking it with the `^D' command, or by using a weapon to force - the lock with the ``#force'' extended command. + using a key or lock‐picking tool with the ‘a’ (apply) command, by + kicking it with the ‘^D’ command, or by using a weapon to force + the lock with the ‘‘#force’’ extended command. Some chests are trapped, causing nasty things to happen when you unlock or open them. You can check for and try to deactivate - traps with the ``#untrap'' extended command. + traps with the ‘‘#untrap’’ extended command. - 7.11. Amulets (`"') + 7.11. Amulets (‘"’) Amulets are very similar to rings, and often more powerful. - Like rings, amulets have various magical properties, some benefi- + Like rings, amulets have various magical properties, some benefi‐ cial, some harmful, which are activated by putting them on. Only one amulet may be worn at a time, around your neck. - The commands to use amulets are the same as for rings, `P' - (put on) and `R' (remove). - - - - NetHack 3.5 September 20, 2006 + The commands to use amulets are the same as for rings, ‘P’ + (put on) and ‘R’ (remove). - NetHack Guidebook 30 + NetHack 3.6 March 27, 2015 - 7.12. Gems (`*') + + + NetHack Guidebook 33 + + + + 7.12. Gems (‘*’) Some gems are valuable, and can be sold for a lot of gold. They are also a far more efficient way of carrying your riches. @@ -1926,11 +2124,11 @@ you exit. Other small rocks are also categorized as gems, but they are - much less valuable. All rocks, however, can be used as projec- + much less valuable. All rocks, however, can be used as projec‐ tile weapons (if you have a sling). In the most desperate of cases, you can still throw them by hand. - 7.13. Large rocks (``') + 7.13. Large rocks (‘`’) Statues and boulders are not particularly useful, and are generally heavy. It is rumored that some statues are not what @@ -1939,7 +2137,7 @@ Very large humanoids (giants and their ilk) have been known to use boulders as weapons. - 7.14. Gold (`$') + 7.14. Gold (‘$’) Gold adds to your score, and you can buy things in shops with it. There are a number of monsters in the dungeon that may @@ -1955,7 +2153,7 @@ of these challenges, which can be checked at any time with the #conduct command or at the end of the game. When you perform an action which breaks a challenge, it will no longer be listed. - This gives players extra ``bragging rights'' for winning the game + This gives players extra ‘‘bragging rights’’ for winning the game with these challenges. Note that it is perfectly acceptable to win the game without resorting to these restrictions and that it is unusual for players to adhere to challenges the first time @@ -1965,37 +2163,37 @@ The most difficult of these is the foodless challenge. Although creatures can survive long periods of time without food, there is a physiological need for water; thus there is no restriction on - drinking beverages, even if they provide some minor food bene- + drinking beverages, even if they provide some minor food bene‐ fits. Calling upon your god for help with starvation does not violate any food challenges either. A strict vegan diet is one which avoids any food derived - from animals. The primary source of nutrition is fruits and veg- - etables. The corpses and tins of blobs (`b'), jellies (`j'), and + from animals. The primary source of nutrition is fruits and veg‐ + etables. The corpses and tins of blobs (‘b’), jellies (‘j’), and - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 - NetHack Guidebook 31 + NetHack Guidebook 34 - fungi (`F') are also considered to be vegetable matter. Certain + fungi (‘F’) are also considered to be vegetable matter. Certain human food is prepared without animal products; namely, lembas - wafers, cram rations, food rations (gunyoki), K-rations, and C- + wafers, cram rations, food rations (gunyoki), K‐rations, and C‐ rations. Metal or another normally indigestible material eaten - while polymorphed into a creature that can digest it is also con- + while polymorphed into a creature that can digest it is also con‐ sidered vegan food. Note however that eating such items still counts against foodless conduct. - Vegetarians do not eat animals; however, they are less se- + Vegetarians do not eat animals; however, they are less se‐ lective about eating animal byproducts than vegans. In addition to the vegan items listed above, they may eat any kind of pudding - (`P') other than the black puddings, eggs and food made from eggs + (‘P’) other than the black puddings, eggs and food made from eggs (fortune cookies and pancakes), food made with milk (cream pies and candy bars), and lumps of royal jelly. Monks are expected to observe a vegetarian diet. @@ -2004,32 +2202,32 @@ foodless conducts. This includes tripe rations, the corpses or tins of any monsters not mentioned above, and the various other chunks of meat found in the dungeon. Swallowing and digesting a - monster while polymorphed is treated as if you ate the creature's - corpse. Eating leather, dragon hide, or bone items while poly- + monster while polymorphed is treated as if you ate the creature’s + corpse. Eating leather, dragon hide, or bone items while poly‐ morphed into a creature that can digest it, or eating monster brains while polymorphed into a mind flayer, is considered eating an animal, although wax is only an animal byproduct. Regardless of conduct, there will be some items which are indigestible, and others which are hazardous to eat. Using a - swallow-and-digest attack against a monster is equivalent to eat- - ing the monster's corpse. Please note that the term ``vegan'' is + swallow‐and‐digest attack against a monster is equivalent to eat‐ + ing the monster’s corpse. Please note that the term ‘‘vegan’’ is used here only in the context of diet. You are still free to choose not to use or wear items derived from animals (e.g. leather, dragon hide, bone, horns, coral), but the game will not - keep track of this for you. Also note that ``milky'' potions may + keep track of this for you. Also note that ‘‘milky’’ potions may be a translucent white, but they do not contain milk, so they are - compatible with a vegan diet. Slime molds or player-defined - ``fruits'', although they could be anything from ``cherries'' to - ``pork chops'', are also assumed to be vegan. + compatible with a vegan diet. Slime molds or player‐defined + ‘‘fruits’’, although they could be anything from ‘‘cherries’’ to + ‘‘pork chops’’, are also assumed to be vegan. An atheist is one who rejects religion. This means that you cannot #pray, #offer sacrifices to any god, #turn undead, or #chat with a priest. Particularly selective readers may argue - that playing Monk or Priest characters should violate this con- + that playing Monk or Priest characters should violate this con‐ duct; that is a choice left to the player. Offering the Amulet of Yendor to your god is necessary to win the game and is not - counted against this conduct. You are also not penalized for be- + counted against this conduct. You are also not penalized for be‐ ing spoken to by an angry god, priest(ess), or other religious figure; a true atheist would hear the words but attach no special meaning to them. @@ -2040,13 +2238,13 @@ throw, fire, and kick weapons; use a wand, spell, or other type - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 - NetHack Guidebook 32 + NetHack Guidebook 35 @@ -2058,30 +2256,30 @@ possible to gain experience by other means. An illiterate character cannot read or write. This includes - reading a scroll, spellbook, fortune cookie message, or t-shirt; + reading a scroll, spellbook, fortune cookie message, or t‐shirt; writing a scroll; or making an engraving of anything other than a - single ``x'' (the traditional signature of an illiterate person). + single ‘‘x’’ (the traditional signature of an illiterate person). Reading an engraving, or any item that is absolutely necessary to win the game, is not counted against this conduct. The identity of scrolls and spellbooks (and knowledge of spells) in your starting inventory is assumed to be learned from your teachers - prior to the start of the game and isn't counted. + prior to the start of the game and isn’t counted. There are several other challenges tracked by the game. It - is possible to eliminate one or more species of monsters by geno- + is possible to eliminate one or more species of monsters by geno‐ cide; playing without this feature is considered a challenge. When the game offers you an opportunity to genocide monsters, you - may respond with the monster type ``none'' if you want to de- + may respond with the monster type ‘‘none’’ if you want to de‐ cline. You can change the form of an item into another item of - the same type (``polypiling'') or the form of your own body into - another creature (``polyself'') by wand, spell, or potion of + the same type (‘‘polypiling’’) or the form of your own body into + another creature (‘‘polyself’’) by wand, spell, or potion of polymorph; avoiding these effects are each considered challenges. Polymorphing monsters, including pets, does not break either of these challenges. Finally, you may sometimes receive wishes; a game without an attempt to wish for any items is a challenge, as is a game without wishing for an artifact (even if the artifact immediately disappears). When the game offers you an opportunity - to make a wish for an item, you may choose ``nothing'' if you + to make a wish for an item, you may choose ‘‘nothing’’ if you want to decline. @@ -2094,217 +2292,19 @@ 9.1. Setting the options Options may be set in a number of ways. Within the game, - the `O' command allows you to view all options and change most of + the ‘O’ command allows you to view all options and change most of them. You can also set options automatically by placing them in the NETHACKOPTIONS environment variable or in a configuration - file. Some versions of NetHack also have front-end programs that - allow you to set options before starting the game. + file. Some versions of NetHack also have front‐end programs that + allow you to set options before starting the game or a global + configuration for system administrators. - 9.2. Using the NETHACKOPTIONS environment variable - The NETHACKOPTIONS variable is a comma-separated list of - initial values for the various options. Some can only be turned - NetHack 3.5 September 20, 2006 - - - - NetHack Guidebook 33 - - - - on or off. You turn one of these on by adding the name of the - option to the list, and turn it off by typing a `!' or ``no'' be- - fore the name. Others take a character string as a value. You - can set string options by typing the option name, a colon or - equals sign, and then the value of the string. The value is ter- - minated by the next comma or the end of string. - - For example, to set up an environment variable so that ``au- - toquiver'' is on, ``autopickup'' is off, the name is set to - ``Blue Meanie'', and the fruit is set to ``papaya'', you would - enter the command - - % setenv NETHACKOPTIONS "autoquiver,\!autopickup,name:Blue Meanie,fruit:papaya" - - in csh (note the need to escape the ! since it's special to the - shell), or - - $ NETHACKOPTIONS="autoquiver,!autopickup,name:Blue Meanie,fruit:papaya" - $ export NETHACKOPTIONS - - in sh or ksh. - - 9.3. Using a configuration file - - Any line in the configuration file starting with `#' is - treated as a comment. Any line in the configuration file start- - ing with ``OPTIONS='' may be filled out with options in the same - syntax as in NETHACKOPTIONS. Any line starting with ``SYMBOLS='' - is taken as defining the corresponding symbol in a different syn- - tax, a sequence of decimal numbers giving the character position - in the current font to be used in displaying each entry. Such a - sequence can be continued to multiple lines by putting a `\' at - the end of each line to be continued. - - If your copy of the game included the compile time AUTOPICK- - UP_EXCEPTIONS option, then any line starting with ``AUTOPICK- - UP_EXCEPTION='' is taken as defining an exception to the pick- - up_types option. There is a section of this Guidebook that dis- - cusses that. - - The default name of the configuration file varies on differ- - ent operating systems, but NETHACKOPTIONS can also be set to the - full name of a file you want to use (possibly preceded by an - `@'). - - 9.4. Customization options - - Here are explanations of what the various options do. Char- - acter strings that are too long may be truncated. Some of the - options listed may be inactive in your dungeon. - - acoustics - Enable messages about what your character hears (default on). - Note that this has nothing to do with your computer's audio - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 34 - - - - capabilities. - - align - Your starting alignment (align:lawful, align:neutral, or - align:chaotic). You may specify just the first letter. The - default is to randomly pick an appropriate alignment. If you - prefix a `!' or ``no'' to the value, you can exclude that - alignment from being picked randomly. Cannot be set with the - `O' command. - - autodig - Automatically dig if you are wielding a digging tool and moving - into a place that can be dug (default false). - - autopickup - Automatically pick up things onto which you move (default on). - See pickup_types to refine the behavior. - - autoquiver - This option controls what happens when you attempt the `f' - (fire) command with an empty quiver. When true, the computer - will fill your quiver with some suitable weapon. Note that it - will not take into account the blessed/cursed status, enchant- - ment, damage, or quality of the weapon; you are free to manual- - ly fill your quiver with the `Q' command instead. If no weapon - is found or the option is false, the `t' (throw) command is ex- - ecuted instead. (default false) - - boulder - Set the character used to display boulders (default is rock - class symbol). - - catname - Name your starting cat (ex. ``catname:Morris''). Cannot be set - with the `O' command. - - character - Pick your type of character (ex. ``character:Monk''); synonym - for ``role''. See ``name'' for an alternate method of specify- - ing your role. Normally only the first letter of the value is - examined; the string ``random'' is an exception. - - checkpoint - Save game state after each level change, for possible recovery - after program crash (default on). - - checkspace - Check free disk space before writing files to disk (default - on). You may have to turn this off if you have more than 2 GB - free space on the partition used for your save and level files. - Only applies when MFLOPPY was defined during compilation. - - clicklook - Allows looking at things on the screen by navigating the mouse - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 35 - - - - over them and clicking the right mouse button (default off). - - cmdassist - Have the game provide some additional command assistance for - new players if it detects some anticipated mistakes (default - on). - - confirm - Have user confirm attacks on pets, shopkeepers, and other - peaceable creatures (default on). - - disclose - Controls options for disclosing various information when the - game ends (defaults to all possibilities being disclosed). The - possibilities are: - - i - disclose your inventory. - a - disclose your attributes. - v - summarize monsters that have been vanquished. - g - list monster species that have been genocided. - c - display your conduct. - - Each disclosure possibility can optionally be preceded by a - prefix which let you refine how it behaves. Here are the valid - prefixes: - - y - prompt you and default to yes on the prompt. - n - prompt you and default to no on the prompt. - + - disclose it without prompting. - - - do not disclose it and do not prompt. - - (ex. ``disclose:yi na +v -g -c'') The example sets inventory to - prompt and default to yes, attributes to prompt and default to - no, vanquished to disclose without prompting, genocided to not - disclose and not to prompt, conduct to not disclose and not to - prompt. Note that the vanquished monsters list includes all - monsters killed by traps and each other as well as by you. - - dogname - Name your starting dog (ex. ``dogname:Fang''). Cannot be set - with the `O' command. - - extmenu - Changes the extended commands interface to pop-up a menu of - available commands. It is keystroke compatible with the tradi- - tional interface except that it does not require that you hit - Enter. It is implemented only by the tty port (default off), - when the game has been compiled to support tty graphics. - - female - An obsolete synonym for ``gender:female''. Cannot be set with - the `O' command. - - - - - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -2314,63 +2314,63 @@ - fixinv - An object's inventory letter sticks to it when it's dropped - (default on). If this is off, dropping an object shifts all - the remaining inventory letters. + 9.2. Using the NETHACKOPTIONS environment variable - fruit - Name a fruit after something you enjoy eating (ex. ``fruit:man- - go'') (default ``slime mold''). Basically a nostalgic whimsy - that NetHack uses from time to time. You should set this to - something you find more appetizing than slime mold. Apples, - oranges, pears, bananas, and melons already exist in NetHack, - so don't use those. + The NETHACKOPTIONS variable is a comma‐separated list of + initial values for the various options. Some can only be turned + on or off. You turn one of these on by adding the name of the + option to the list, and turn it off by typing a ‘!’ or ‘‘no’’ be‐ + fore the name. Others take a character string as a value. You + can set string options by typing the option name, a colon or + equals sign, and then the value of the string. The value is ter‐ + minated by the next comma or the end of string. - gender - Your starting gender (gender:male or gender:female). You may - specify just the first letter. Although you can still denote - your gender using the ``male'' and ``female'' options, the - ``gender'' option will take precedence. The default is to ran- - domly pick an appropriate gender. If you prefix a `!' or - ``no'' to the value, you can exclude that gender from being - picked randomly. Cannot be set with the `O' command. + For example, to set up an environment variable so that ‘‘au‐ + toquiver’’ is on, ‘‘autopickup’’ is off, the name is set to + ‘‘Blue Meanie’’, and the fruit is set to ‘‘papaya’’, you would + enter the command - help - If more information is available for an object looked at with - the `/' command, ask if you want to see it (default on). Turn- - ing help off makes just looking at things faster, since you - aren't interrupted with the ``More info?'' prompt, but it also - means that you might miss some interesting and/or important in- - formation. + % setenv NETHACKOPTIONS "autoquiver,\!autopickup,name:Blue Meanie,fruit:papaya" - horsename - Name your starting horse (ex. ``horsename:Trigger''). Cannot - be set with the `O' command. + in csh (note the need to escape the ! since it’s special to the + shell), or - ignintr - Ignore interrupt signals, including breaks (default off). + $ NETHACKOPTIONS="autoquiver,!autopickup,name:Blue Meanie,fruit:papaya" + $ export NETHACKOPTIONS - legacy - Display an introductory message when starting the game (default - on). + in sh or ksh. - lit_corridor - Show corridor squares seen by night vision or a light source - held by your character as lit (default off). + 9.3. Using a configuration file - lootabc - Use the old `a', `b', and `c' keyboard shortcuts when looting, - rather than the mnemonics `o', `i', and `b' (default off). + Any line in the configuration file starting with ‘#’ is + treated as a comment. Any line in the configuration file start‐ + ing with ‘‘OPTIONS=’’ may be filled out with options in the same + syntax as in NETHACKOPTIONS. Any line starting with ‘‘SYMBOLS=’’ + is taken as defining the corresponding symbol in a different syn‐ + tax, a sequence of decimal numbers giving the character position + in the current font to be used in displaying each entry. Such a + sequence can be continued to multiple lines by putting a ‘\’ at + the end of each line to be continued. - mail - Enable mail delivery during the game (default on). + Any line starting with ‘‘AUTOPICKUP_EXCEPTION=’’ is taken as + defining an exception to the pickup_types option. There is a + section of this Guidebook that discusses that. - male - An obsolete synonym for ``gender:male''. Cannot be set with + The default name of the configuration file varies on differ‐ + ent operating systems, but NETHACKOPTIONS can also be set to the + full name of a file you want to use (possibly preceded by an + ‘@’). + + 9.4. Customization options + + Here are explanations of what the various options do. Char‐ + acter strings that are too long may be truncated. Some of the + options listed may be inactive in your dungeon. - NetHack 3.5 September 20, 2006 + + + NetHack 3.6 March 27, 2015 @@ -2380,63 +2380,63 @@ - the `O' command. + acoustics + Enable messages about what your character hears (default on). + Note that this has nothing to do with your computer’s audio ca‐ + pabilities. - menustyle - Controls the interface used when you need to choose various ob- - jects (in response to the Drop command, for instance). The - value specified should be the first letter of one of the fol- - lowing: traditional, combination, partial, or full. Tradi- - tional was the only interface available for earlier versions; - it consists of a prompt for object class characters, followed - by an object-by-object prompt for all items matching the se- - lected object class(es). Combination starts with a prompt for - object class(es) of interest, but then displays a menu of - matching objects rather than prompting one-by-one. Partial - skips the object class filtering and immediately displays a - menu of all objects. Full displays a menu of object classes - rather than a character prompt, and then a menu of matching ob- - jects for selection. + align + Your starting alignment (align:lawful, align:neutral, or + align:chaotic). You may specify just the first letter. The + default is to randomly pick an appropriate alignment. If you + prefix a ‘!’ or ‘‘no’’ to the value, you can exclude that + alignment from being picked randomly. Cannot be set with the + ‘O’ command. - menu_deselect_all - Menu character accelerator to deselect all items in a menu. - Implemented by the Amiga, Gem, X11 and tty ports. Default '-'. + autodig + Automatically dig if you are wielding a digging tool and moving + into a place that can be dug (default false). - menu_deselect_page - Menu character accelerator to deselect all items on this page - of a menu. Implemented by the Amiga, Gem and tty ports. De- - fault '\'. + autopickup + Automatically pick up things onto which you move (default on). + See pickup_types to refine the behavior. - menu_first_page - Menu character accelerator to jump to the first page in a menu. - Implemented by the Amiga, Gem and tty ports. Default '^'. + autoquiver + This option controls what happens when you attempt the ‘f’ + (fire) command with an empty quiver (or quiver sack or have + nothing at the ready). When true, the computer will fill your + quiver or quiver sack or make ready some suitable weapon. Note + that it will not take into account the blessed/cursed status, + enchantment, damage, or quality of the weapon; you are free to + manually fill your quiver or quiver sack or make ready with the + ‘Q’ command instead. If no weapon is found or the option is + false, the ‘t’ (throw) command is executed instead. (default + false) - menu_headings - Controls how the headings in a menu are highlighted. Values - are 'bold', 'inverse', or 'underline'. Not all ports can actu- - ally display all three types. + bones + Allow saving and loading bones files. (default true) - menu_invert_all - Menu character accelerator to invert all items in a menu. Im- - plemented by the Amiga, Gem, X11 and tty ports. Default '@'. + boulder + Set the character used to display boulders (default is rock + class symbol). - menu_invert_page - Menu character accelerator to invert all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default - '~'. + catname + Name your starting cat (ex. ‘‘catname:Morris’’). Cannot be set + with the ‘O’ command. - menu_last_page - Menu character accelerator to jump to the last page in a menu. - Implemented by the Amiga, Gem and tty ports. Default '|'. + character + Pick your type of character (ex. ‘‘character:Monk’’); synonym + for ‘‘role’’. See ‘‘name’’ for an alternate method of specify‐ + ing your role. Normally only the first letter of the value is + examined; the string ‘‘random’’ is an exception. - menu_next_page - Menu character accelerator to goto the next menu page. Imple- - mented by the Amiga, Gem and tty ports. Default '>'. + checkpoint + Save game state after each level change, for possible recovery + after program crash (default on). - - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -2446,63 +2446,63 @@ - menu_previous_page - Menu character accelerator to goto the previous menu page. Im- - plemented by the Amiga, Gem and tty ports. Default '<'. + checkspace + Check free disk space before writing files to disk (default + on). You may have to turn this off if you have more than 2 GB + free space on the partition used for your save and level files. + Only applies when MFLOPPY was defined during compilation. - menu_search - Menu character accelerator to search for a menu item. Imple- - mented by the Amiga, Gem and X11 ports. Default ':'. + clicklook + Allows looking at things on the screen by navigating the mouse + over them and clicking the right mouse button (default off). - menu_select_all - Menu character accelerator to select all items in a menu. Im- - plemented by the Amiga, Gem, X11 and tty ports. Default '.'. + cmdassist + Have the game provide some additional command assistance for + new players if it detects some anticipated mistakes (default + on). - menu_select_page - Menu character accelerator to select all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default - ','. + confirm + Have user confirm attacks on pets, shopkeepers, and other + peaceable creatures (default on). - msghistory - The number of top line messages to save (and recall with ^P) - (default 20). Cannot be set with the `O' command. + disclose + Controls what information the program reveals when the game + ends. Value is a space separated list of prompting/category + pairs (default is ‘ni na nv ng nc no’, prompt with default re‐ + sponse of ‘n’ for each candidate). The possibilities are: - msg_window - Allows you to change the way recalled messages are displayed. - (It is currently implemented for tty only.) The possible val- - ues are: + i ‐ disclose your inventory; + a ‐ disclose your attributes; + v ‐ summarize monsters that have been vanquished; + g ‐ list monster species that have been genocided; + c ‐ display your conduct; + o ‐ display dungeon overview. - s - single message (default, this was the behavior before 3.4.0). - c - combination, two messages as `single', then as `full'. - f - full window, oldest message first. - r - full window, newest message first. + Each disclosure possibility can optionally be preceded by a + prefix which lets you refine how it behaves. Here are the + valid prefixes: - For backward compatibility, no value needs to be specified - (which defaults to `full'), or it can be negated (which de- - faults to `single'). + y ‐ prompt you and default to yes on the prompt; + n ‐ prompt you and default to no on the prompt; + + ‐ disclose it without prompting; + ‐ ‐ do not disclose it and do not prompt. - name - Set your character's name (defaults to your user name). You - can also set your character's role by appending a dash and one - or more letters of the role (that is, by suffixing one of -A -B - -C -H -K -M -P -Ra -Ro -S -T -V -W). If -@ is used for the - role, then a random one will be automatically chosen. Cannot - be set with the `O' command. + Omitted categories are implicitly added with ‘n’ prefix. Spec‐ + ified categories with omitted prefix implicitly use ‘+’ prefix. + Order of the disclosure categories does not matter, program + display for end‐of‐game disclosure follows a set sequence. - news - Read the NetHack news file, if present (default on). Since the - news is shown at the beginning of the game, there's no point in - setting this with the `O' command. + (ex. ‘‘disclose:yi na +v ‐g o’’) The example sets inventory to + prompt and default to yes, attributes to prompt and default to + no, vanquished to disclose without prompting, genocided to not + disclose and not prompt, conduct to implicitly prompt and de‐ + fault to no, and overview to disclose without prompting. - null - Send padding nulls to the terminal (default on). - - number_pad - Use digit keys instead of letters to move (default 0 or off). - Valid settings are: + Note that the vanquished monsters list includes all monsters + killed by traps and each other as well as by you. And the - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -2512,63 +2512,63 @@ - 0 - move by letters; `yuhjklbn'. - 1 - move by numbers; digit `5' acts as `G' movement prefix. - 2 - like 1 but `5' works as `g' prefix instead of as `G'. - 3 - move by numbers using phone keypad layout; 123 above, 789 below. - 4 - combines 3 with 2; phone layout plus MSDOS compatibility. - -1 - move by letters but use `z' to go northwest and `y' to zap wands. + dungeon overview shows all levels you had visited but does not + reveal things about them that you hadn’t discovered. - For backward compatibility, omitting a value is the same as - specifying 1 and negating number_pad is the same as specifying - 0. (Settings 2 and 4 are for compatibility with MSDOS or old - PC Hack; in addition to the different behavior for `5', `Alt-5' - acts as `G' and `Alt-0' acts as `I'. Setting -1 is to accomo- - date some German keyboards which have the location of the `y' - and `z' keys swapped.) When moving by numbers, to enter a - count prefix for those commands which accept one (such as - ``12s'' to search twelve times), precede it with the letter `n' - (``n12s''). + dogname + Name your starting dog (ex. ‘‘dogname:Fang’’). Cannot be set + with the ‘O’ command. - packorder - Specify the order to list object types in (default - ``")[%?+!=/(*`0_''). The value of this option should be a - string containing the symbols for the various object types. - Any omitted types are filled in at the end from the previous - order. + extmenu + Changes the extended commands interface to pop‐up a menu of + available commands. It is keystroke compatible with the tradi‐ + tional interface except that it does not require that you hit + Enter. It is implemented only by the tty port (default off), + when the game has been compiled to support tty graphics. - perm_invent - If true, always display your current inventory in a window. - This only makes sense for windowing system interfaces that im- - plement this feature. + female + An obsolete synonym for ‘‘gender:female’’. Cannot be set with + the ‘O’ command. - pettype - Specify the type of your initial pet, if you are playing a - character class that uses multiple types of pets; or choose to - have no initial pet at all. Possible values are ``cat'', - ``dog'', ``horse'', and ``none''. If the choice is not allowed - for the role you are currently playing, it will be silently ig- - nored. For example, ``horse'' will only be honored when play- - ing a knight. Cannot be set with the `O' command. + fixinv + An object’s inventory letter sticks to it when it’s dropped + (default on). If this is off, dropping an object shifts all + the remaining inventory letters. - pickup_burden - When you pick up an item that would exceed this encumbrance - level (Unburdened, Burdened, streSsed, straiNed, overTaxed, or - overLoaded), you will be asked if you want to continue. (De- - fault `S'). + fruit + Name a fruit after something you enjoy eating (ex. ‘‘fruit:man‐ + go’’) (default ‘‘slime mold’’). Basically a nostalgic whimsy + that NetHack uses from time to time. You should set this to + something you find more appetizing than slime mold. Apples, + oranges, pears, bananas, and melons already exist in NetHack, + so don’t use those. - pickup_thrown - If this option is on and autopickup is also on, try to pick up - things that you threw, even if they aren't in pickup_types or - match an autopickup exception. Default is on. + gender + Your starting gender (gender:male or gender:female). You may + specify just the first letter. Although you can still denote + your gender using the ‘‘male’’ and ‘‘female’’ options, the + ‘‘gender’’ option will take precedence. The default is to ran‐ + domly pick an appropriate gender. If you prefix a ‘!’ or + ‘‘no’’ to the value, you can exclude that gender from being + picked randomly. Cannot be set with the ‘O’ command. - pickup_types - Specify the object types to be picked up when autopickup is on. - Default is all types. If your copy of the game has the compile - time option AUTOPICKUP_EXCEPTIONS included, you may be able to + help + If more information is available for an object looked at with + the ‘/’ command, ask if you want to see it (default on). Turn‐ + ing help off makes just looking at things faster, since you + aren’t interrupted with the ‘‘More info?’’ prompt, but it also + means that you might miss some interesting and/or important in‐ + formation. + + horsename + Name your starting horse (ex. ‘‘horsename:Trigger’’). Cannot + be set with the ‘O’ command. + + ignintr + Ignore interrupt signals, including breaks (default off). - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -2578,63 +2578,63 @@ - use autopickup_exception configuration file lines to further - refine autopickup behavior. + legacy + Display an introductory message when starting the game (default + on). - prayconfirm - Prompt for confirmation before praying (default on). + lit_corridor + Show corridor squares seen by night vision or a light source + held by your character as lit (default off). - pushweapon - Using the `w' (wield) command when already wielding something - pushes the old item into your alternate weapon slot (default - off). Likewise for the `a' (apply) command if it causes the - applied item to become wielded. + lootabc + Use the old ‘a’, ‘b’, and ‘c’ keyboard shortcuts when looting, + rather than the mnemonics ‘o’, ‘i’, and ‘b’ (default off). - race - Selects your race (for example, ``race:human''). Default is - random. If you prefix a `!' or ``no'' to the value, you can - exclude that race from being picked randomly. Cannot be set - with the `O' command. + mail + Enable mail delivery during the game (default on). - rest_on_space - Make the space bar a synonym for the `.' (rest) command (de- - fault off). + male + An obsolete synonym for ‘‘gender:male’’. Cannot be set with + the ‘O’ command. - role - Pick your type of character (ex. ``role:Samurai''); synonym for - ``character''. See ``name'' for an alternate method of speci- - fying your role. Normally only the first letter of the value - is examined; `r' is an exception with ``Rogue'', ``Ranger'', - and ``random'' values. If you prefix a `!' or ``no'' to the - value, you can exclude that role from being picked randomly. + mention_walls + Give feedback when walking against a wall (default off). - roguesymset - This option may be used to select one of the named symbol sets - found within ``symbols'' to alter the symbols displayed on the - screen on the rogue level. + menustyle + Controls the interface used when you need to choose various ob‐ + jects (in response to the Drop command, for instance). The + value specified should be the first letter of one of the fol‐ + lowing: traditional, combination, partial, or full. Tradi‐ + tional was the only interface available for earlier versions; + it consists of a prompt for object class characters, followed + by an object‐by‐object prompt for all items matching the se‐ + lected object class(es). Combination starts with a prompt for + object class(es) of interest, but then displays a menu of + matching objects rather than prompting one‐by‐one. Partial + skips the object class filtering and immediately displays a + menu of all objects. Full displays a menu of object classes + rather than a character prompt, and then a menu of matching ob‐ + jects for selection. - rlecomp - When writing out a save file, perform run length compression of - the map. Not all ports support run length compression. It has - no effect on reading an existing save file. + menu_deselect_all + Menu character accelerator to deselect all items in a menu. + Implemented by the Amiga, Gem, X11 and tty ports. Default ’‐’. - runmode - Controls the amount of screen updating for the map window when - engaged in multi-turn movement (running via shift+direction or - control+direction and so forth, or via the travel command or - mouse click). The possible values are: + menu_deselect_page + Menu character accelerator to deselect all items on this page + of a menu. Implemented by the Amiga, Gem and tty ports. De‐ + fault ’\’. - teleport - update the map after movement has finished; - run - update the map after every seven or so steps; - walk - update the map after each step; - crawl - like walk, but pause briefly after each step. + menu_first_page + Menu character accelerator to jump to the first page in a menu. + Implemented by the Amiga, Gem and tty ports. Default ’^’. - This option only affects the game's screen display, not the ac- - tual results of moving. The default is `run'; versions prior - to 3.4.1 used `teleport' only. Whether or not the effect is + menu_headings + Controls how the headings in a menu are highlighted. Values + are ’bold’, ’inverse’, or ’underline’. Not all ports can - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 @@ -2644,6 +2644,280 @@ + actually display all three types. + + menu_invert_all + Menu character accelerator to invert all items in a menu. Im‐ + plemented by the Amiga, Gem, X11 and tty ports. Default ’@’. + + menu_invert_page + Menu character accelerator to invert all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default + ’~’. + + menu_last_page + Menu character accelerator to jump to the last page in a menu. + Implemented by the Amiga, Gem and tty ports. Default ’|’. + + menu_next_page + Menu character accelerator to goto the next menu page. Imple‐ + mented by the Amiga, Gem and tty ports. Default ’>’. + + menu_objsyms + Show object symbols in menu headings in menus where the object + symbols act as menu accelerators (default off). + + menu_previous_page + Menu character accelerator to goto the previous menu page. Im‐ + plemented by the Amiga, Gem and tty ports. Default ’<’. + + menu_search + Menu character accelerator to search for a menu item. Imple‐ + mented by the Amiga, Gem, X11 and tty ports. Default ’:’. + + menu_select_all + Menu character accelerator to select all items in a menu. Im‐ + plemented by the Amiga, Gem, X11 and tty ports. Default ’.’. + + menu_select_page + Menu character accelerator to select all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default + ’,’. + + msghistory + The number of top line messages to save (and recall with ^P) + (default 20). Cannot be set with the ‘O’ command. + + msg_window + Allows you to change the way recalled messages are displayed. + (It is currently implemented for tty only.) The possible val‐ + ues are: + + s ‐ single message (default; only choice prior to 3.4.0); + c ‐ combination, two messages as ‘single’, then as ‘full’; + f ‐ full window, oldest message first; + r ‐ full window reversed, newest message first. + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 42 + + + + For backward compatibility, no value needs to be specified + (which defaults to ‘full’), or it can be negated (which de‐ + faults to ‘single’). + + name + Set your character’s name (defaults to your user name). You + can also set your character’s role by appending a dash and one + or more letters of the role (that is, by suffixing one of ‐A ‐B + ‐C ‐H ‐K ‐M ‐P ‐Ra ‐Ro ‐S ‐T ‐V ‐W). If ‐@ is used for the + role, then a random one will be automatically chosen. Cannot + be set with the ‘O’ command. + + news + Read the NetHack news file, if present (default on). Since the + news is shown at the beginning of the game, there’s no point in + setting this with the ‘O’ command. + + null + Send padding nulls to the terminal (default on). + + number_pad + Use digit keys instead of letters to move (default 0 or off). + Valid settings are: + + 0 ‐ move by letters; ‘yuhjklbn’ + 1 ‐ move by numbers; digit ‘5’ acts as ‘G’ movement prefix + 2 ‐ like 1 but ‘5’ works as ‘g’ prefix instead of as ‘G’ + 3 ‐ by numbers using phone key layout; 123 above, 789 below + 4 ‐ combines 3 with 2; phone layout plus MSDOS compatibility + ‐1 ‐ by letters but use ‘z’ to go northwest, ‘y’ to zap wands + + For backward compatibility, omitting a value is the same as + specifying 1 and negating number_pad is the same as specifying + 0. (Settings 2 and 4 are for compatibility with MSDOS or old + PC Hack; in addition to the different behavior for ‘5’, ‘Alt‐5’ + acts as ‘G’ and ‘Alt‐0’ acts as ‘I’. Setting ‐1 is to accommo‐ + date some German keyboards which have the location of the ‘y’ + and ‘z’ keys swapped.) When moving by numbers, to enter a + count prefix for those commands which accept one (such as + ‘‘12s’’ to search twelve times), precede it with the letter ‘n’ + (‘‘n12s’’). + + packorder + Specify the order to list object types in (default + ‘‘")[%?+!=/(*‘0_’’). The value of this option should be a + string containing the symbols for the various object types. + Any omitted types are filled in at the end from the previous + order. + + paranoid_confirmation + A space separated list of specific situations where alternate + prompting is desired. The default is paranoid_confirma‐ + tion:pray. + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 43 + + + + Confirm ‐ for any prompts which are set to require "yes" rather + than ’y’, also require "no" to reject instead of ac‐ + cepting any non‐yes response as no + quit ‐ require "yes" rather than ’y’ to confirm quitting the + game or switching into non‐scoring explore mode; + die ‐ require "yes" rather than ’y’ to confirm dying (not + useful in normal play; applies to explore mode); + bones ‐ require "yes" rather than ’y’ to confirm saving bones + data when dying in debug mode; + attack ‐ require "yes" rather than ’y’ to confirm attacking a + peaceful monster; + pray ‐ require ’y’ to confirm an attempt to pray rather than + immediately praying; on by default; + Remove ‐ require selection from inventory for ’R’ and ’T’ com‐ + mands even when wearing just one applicable item. + + By default, the pray choice is enabled, the others disabled. + To disable it without setting any of the other choices, use + ‘‘paranoid_confirmation:none’’. To keep it enabled while set‐ + ting any of the others, include it in the list, such as ‘‘para‐ + noid_confirmation:attack pray Remove’’. + + perm_invent + If true, always display your current inventory in a window. + This only makes sense for windowing system interfaces that im‐ + plement this feature. + + pettype + Specify the type of your initial pet, if you are playing a + character class that uses multiple types of pets; or choose to + have no initial pet at all. Possible values are ‘‘cat’’, + ‘‘dog’’, ‘‘horse’’, and ‘‘none’’. If the choice is not allowed + for the role you are currently playing, it will be silently ig‐ + nored. For example, ‘‘horse’’ will only be honored when play‐ + ing a knight. Cannot be set with the ‘O’ command. + + pickup_burden + When you pick up an item that would exceed this encumbrance + level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, + or overLoaded), you will be asked if you want to continue. + (Default ‘S’). + + pickup_thrown + If this option is on and autopickup is also on, try to pick up + things that you threw, even if they aren’t in pickup_types or + match an autopickup exception. Default is on. + + pickup_types + Specify the object types to be picked up when autopickup is on. + Default is all types. You can use autopickup_exception config‐ + uration file lines to further refine autopickup behavior. + + pile_limit + When walking across a pile of objects on the floor, threshold + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 44 + + + + at which the message "there are few/several/many objects here" + is given instead of showing a popup list of those objects. A + value of 0 means "no limit" (always list the objects); a value + of 1 effectively means "never show the objects" since the pile + size will always be at least that big; default value is 5. + + playmode + Values are ‘normal’, ‘explore’, or ‘debug’. Allows selection + of explore mode (also known as discovery mode) or debug mode + (also known as wizard mode) instead of normal play. Debug mode + might only be allowed for someone logged in under a particular + user name (on multi‐user systems) or specifying a particular + character name (on single‐user systems) or it might be disabled + entirely. Requesting it when not allowed or not possible re‐ + sults in explore mode instead. Default is normal play. + + pushweapon + Using the ‘w’ (wield) command when already wielding something + pushes the old item into your alternate weapon slot (default + off). Likewise for the ‘a’ (apply) command if it causes the + applied item to become wielded. + + race + Selects your race (for example, ‘‘race:human’’). Default is + random. If you prefix a ‘!’ or ‘‘no’’ to the value, you can + exclude that race from being picked randomly. Cannot be set + with the ‘O’ command. + + rest_on_space + Make the space bar a synonym for the ‘.’ (rest) command (de‐ + fault off). + + role + Pick your type of character (ex. ‘‘role:Samurai’’); synonym for + ‘‘character’’. See ‘‘name’’ for an alternate method of speci‐ + fying your role. Normally only the first letter of the value + is examined; ‘r’ is an exception with ‘‘Rogue’’, ‘‘Ranger’’, + and ‘‘random’’ values. If you prefix a ‘!’ or ‘‘no’’ to the + value, you can exclude that role from being picked randomly. + + roguesymset + This option may be used to select one of the named symbol sets + found within ‘‘symbols’’ to alter the symbols displayed on the + screen on the rogue level. + + rlecomp + When writing out a save file, perform run length compression of + the map. Not all ports support run length compression. It has + no effect on reading an existing save file. + + runmode + Controls the amount of screen updating for the map window when + engaged in multi‐turn movement (running via shift+direction or + control+direction and so forth, or via the travel command or + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 45 + + + + mouse click). The possible values are: + + teleport ‐ update the map after movement has finished; + run ‐ update the map after every seven or so steps; + walk ‐ update the map after each step; + crawl ‐ like walk, but pause briefly after each step. + + This option only affects the game’s screen display, not the ac‐ + tual results of moving. The default is ‘run’; versions prior + to 3.4.1 used ‘teleport’ only. Whether or not the effect is noticeable will depend upon the window port used or on the type of terminal. @@ -2652,8 +2926,8 @@ scores Control what parts of the score list you are shown at the end - (ex. ``scores:5 top scores/4 around my score/own scores''). - Only the first letter of each category (`t', `a', or `o') is + (ex. ‘‘scores:5 top scores/4 around my score/own scores’’). + Only the first letter of each category (‘t’, ‘a’, or ‘o’) is necessary. showexp @@ -2662,7 +2936,7 @@ showrace Display yourself as the glyph for your race, rather than the - glyph for your role (default off). Note that this setting af- + glyph for your role (default off). Note that this setting af‐ fects only the appearance of the display, not the way the game treats you. @@ -2674,7 +2948,7 @@ Suppress terminal beeps (default on). sortpack - Sort the pack contents by type when displaying inventory (de- + Sort the pack contents by type when displaying inventory (de‐ fault on). sparkle @@ -2682,39 +2956,38 @@ hit by an attack to which it is resistant (default on). standout - Boldface monsters and ``--More--'' (default off). + Boldface monsters and ‘‘‐‐More‐‐’’ (default off). suppress_alert This option may be set to a NetHack version level to suppress alert notification messages about feature changes for that and - prior versions (ex. ``suppress_alert:3.3.1''). + prior versions (ex. ‘‘suppress_alert:3.3.1’’). + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 46 + + symset This option may be used to select one of the named symbol sets - found within ``symbols'' to alter the symbols displayed on the + found within ‘‘symbols’’ to alter the symbols displayed on the screen. time Show the elapsed game time in turns on bottom line (default off). - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 42 - - - timed_delay - When pausing momentarily for display effect, such as with ex- + When pausing momentarily for display effect, such as with ex‐ plosions and moving objects, use a timer rather than sending - extra characters to the screen. (Applies to ``tty'' interface - only; ``X11'' interface always uses a timer based delay. The + extra characters to the screen. (Applies to ‘‘tty’’ interface + only; ‘‘X11’’ interface always uses a timer based delay. The default is on if configured into the program.) tombstone @@ -2722,7 +2995,7 @@ toptenwin Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visi- + (default off). Setting this option makes the score list visi‐ ble when a windowing version of NetHack is started without a parent window, but it no longer leaves the score list around after game end on a terminal or emulating window. @@ -2736,13 +3009,13 @@ Provide more commentary during the game (default on). windowtype - Select which windowing system to use, such as ``tty'' or - ``X11'' (default depends on version). Cannot be set with the - `O' command. + Select which windowing system to use, such as ‘‘tty’’ or + ‘‘X11’’ (default depends on version). Cannot be set with the + ‘O’ command. zerocomp - When writing out a save file, perform zero-comp compression of - the contents. Not all ports support zero-comp compression. It + When writing out a save file, perform zero‐comp compression of + the contents. Not all ports support zero‐comp compression. It has no effect on reading an existing save file. 9.5. Window Port Customization options @@ -2753,29 +3026,29 @@ truncated. Not all window ports will adjust for all settings listed here. You can safely add any of these options to your config file, and if the window port is capable of adjusting to - suit your preferences, it will attempt to do so. If it can't it - will silently ignore it. You can find out if an option is sup- - ported by the window port that you are currently using by check- - ing to see if it shows up in the Options list. Some options are - dynamic and can be specified during the game with the `O' com- - mand. + suit your preferences, it will attempt to do so. If it can’t it + will silently ignore it. You can find out if an option is + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 47 + + + + supported by the window port that you are currently using by + checking to see if it shows up in the Options list. Some options + are dynamic and can be specified during the game with the ‘O’ + command. align_message Where to align or place the message window (top, bottom, left, or right) - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 43 - - - align_status Where to align or place the status window (top, bottom, left, or right). @@ -2788,12 +3061,12 @@ objects, and dungeon features eight_bit_tty - NetHack should pass eight-bit character values (for example, - specified with the traps option) straight through to your ter- + NetHack should pass eight‐bit character values (for example, + specified with the traps option) straight through to your ter‐ minal (default off). font_map - NetHack should use a font by the chosen name for the map win- + NetHack should use a font by the chosen name for the map win‐ dow. font_menu @@ -2822,6 +3095,17 @@ font_size_status NetHack should use this size font for the status window. + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 48 + + + font_size_text NetHack should use this size font for text windows. @@ -2829,19 +3113,6 @@ NetHack should try and display on the entire screen rather than in a window. - - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 44 - - - hilite_pet Visually distinguish pets from similar animals (default off). The behavior of this option depends on the type of windowing @@ -2859,7 +3130,7 @@ Allow use of the mouse for input and travel. player_selection - NetHack should pop up dialog boxes, or use prompts for charac- + NetHack should pop up dialog boxes, or use prompts for charac‐ ter selection. popup_dialog @@ -2867,10 +3138,10 @@ preload_tiles NetHack should preload tiles into memory. For example, in the - protected mode MSDOS version, control whether tiles get pre- + protected mode MSDOS version, control whether tiles get pre‐ loaded into RAM at the start of the game. Doing so enhances - performance of the tile graphics, but uses more memory. (de- - fault on). Cannot be set with the `O' command. + performance of the tile graphics, but uses more memory. (de‐ + fault on). Cannot be set with the ‘O’ command. scroll_amount NetHack should scroll the display by this number of cells when @@ -2889,6 +3160,18 @@ Display an onscreen keyboard. Handhelds are most likely to support this option. + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 49 + + + splash_screen NetHack should display an opening splash screen when it starts up (default yes). @@ -2896,18 +3179,6 @@ tiled_map NetHack should display a tiled map if it can. - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 45 - - - tile_file Specify the name of an alternative tile file to override the default. @@ -2927,14 +3198,14 @@ message window. windowcolors - NetHack should display windows with the specified fore- + NetHack should display windows with the specified fore‐ ground/background colors if it can. wraptext - NetHack port should wrap long lines of text if they don't fit + NetHack port should wrap long lines of text if they don’t fit in the visible area of the window. - 9.6. Platform-specific Customization options + 9.6. Platform‐specific Customization options Here are explanations of options that are used by specific platforms or ports to customize and change the port behavior. @@ -2943,15 +3214,43 @@ Select an alternate keystroke handler dll to load (Win32 tty NetHack only). The name of the handler is specified without the .dll extension and without any path information. Cannot be - set with the `O' command. + set with the ‘O’ command. altmeta - (default on, AMIGA NetHack only). + On Amiga, this option controls whether typing ‘Alt’ plus anoth‐ + er key functions as a meta‐shift for that key (default on). + + altmeta + On other (non‐Amiga) systems where this option is available, it + can be set to tell nethack to convert a two character sequence + beginning with ESC into a meta‐shifted version of the second + character (default off). + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 50 + + + + This conversion is only done for commands, not for other input + prompts. Note that typing one or more digits as a count prefix + prior to a command‐‐preceded by n if the number_pad option is + set‐‐is also subject to this conversion, so attempting to abort + the count by typing ESC will leave nethack waiting for another + character to complete the two character sequence. Type a sec‐ + ond ESC to finish cancelling such a count. At other prompts a + single ESC suffices. BIOS Use BIOS calls to update the screen display quickly and to read - the keyboard (allowing the use of arrow keys to move) on ma- - chines with an IBM PC compatible BIOS ROM (default off, OS/2, + the keyboard (allowing the use of arrow keys to move) on ma‐ + chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). flush @@ -2963,177 +3262,180 @@ page_wait (default on, Mac NetHack only). - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 46 - - - rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof input (MS-DOS sometimes treats `^P' as a printer toggle - without it) (default off, OS/2, PC, and ST NetHack only). - Note: DEC Rainbows hang if this is turned on. Cannot be set - with the `O' command. + Force raw (non‐cbreak) mode for faster output and more bullet‐ + proof input (MS‐DOS sometimes treats ‘^P’ as a printer toggle + without it) (default off, OS/2, PC, and ST NetHack only). + Note: DEC Rainbows hang if this is turned on. Cannot be set + with the ‘O’ command. soundcard - (default on, PC NetHack only). Cannot be set with the `O' com- + (default on, PC NetHack only). Cannot be set with the ‘O’ com‐ mand. subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of + (Win32 tty NetHack only). May be used to alter the value of keystrokes that the operating system returns to NetHack to help - compensate for international keyboard issues. OPTIONS=subkey- - value:171/92 will return 92 to NetHack, if 171 was originally - going to be returned. You can use multiple subkeyvalue state- - ments in the config file if needed. Cannot be set with the `O' + compensate for international keyboard issues. OPTIONS=subkey‐ + value:171/92 will return 92 to NetHack, if 171 was originally + going to be returned. You can use multiple subkeyvalue state‐ + ments in the config file if needed. Cannot be set with the ‘O’ command. video - Set the video mode used (PC NetHack only). Values are `autode- - tect', `default', or `vga'. Setting `vga' (or `autodetect' - with vga hardware present) will cause the game to display - tiles. Cannot be set with the `O' command. + Set the video mode used (PC NetHack only). Values are ‘autode‐ + tect’, ‘default’, or ‘vga’. Setting ‘vga’ (or ‘autodetect’ + with vga hardware present) will cause the game to display + tiles. Cannot be set with the ‘O’ command. videocolors - Set the color palette for PC systems using NO_TERMS (default - 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order - of colors is red, green, brown, blue, magenta, cyan, - bright.white, bright.red, bright.green, yellow, bright.blue, - bright.magenta, and bright.cyan. Cannot be set with the `O' + Set the color palette for PC systems using NO_TERMS (default + 4‐2‐6‐1‐5‐3‐15‐12‐10‐14‐9‐13‐11, (PC NetHack only). The order + of colors is red, green, brown, blue, magenta, cyan, + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 51 + + + + bright.white, bright.red, bright.green, yellow, bright.blue, + bright.magenta, and bright.cyan. Cannot be set with the ‘O’ command. videoshades - Set the intensity level of the three gray scales available (de- + Set the intensity level of the three gray scales available (de‐ fault dark normal light, PC NetHack only). If the game display - is difficult to read, try adjusting these scales; if this does - not correct the problem, try !color. Cannot be set with the - `O' command. + is difficult to read, try adjusting these scales; if this does + not correct the problem, try !color. Cannot be set with the + ‘O’ command. 9.7. Configuring autopickup exceptions - There is an experimental compile time option called AU- - TOPICKUP_EXCEPTIONS. If your copy of the game was built with - that option defined, you can further refine the behavior of the - autopickup option beyond what is available through the pick- - up_types option. + You can further refine the behavior of the autopickup option + beyond what is available through the pickup_types option. By placing autopickup_exception lines in your configuration file, you can define patterns to be checked when the game is about to autopickup something. - - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 47 - - - autopickup_exception - Sets an exception to the pickup_types option. The autopick- - up_exception option should be followed by a string of 1-80 - characters to be used as a pattern to match against the singu- + Sets an exception to the pickup_types option. The autopick‐ + up_exception option should be followed by a string of 1‐80 + characters to be used as a pattern to match against the singu‐ lar form of the description of an object at your location. - You may use the following special characters in a pattern: + You may use the following special characters in a pattern: - *--- matches 0 or more characters. - ?--- matches any single character. + * ‐ matches zero or more characters; + ? ‐ matches any single character. - In addition, some characters are treated specially if they - occur as the first character in the string pattern, specifically: + In addition, some characters are treated specially if they oc‐ + cur as the first character in the pattern, specifically: - < - always pickup an object that matches the pattern that follows. - > - never pickup an object that matches the pattern that follows. + < ‐ always pickup an object that matches rest of pattern; + > ‐ never pickup an object that matches rest of pattern. - Can be set with the `O' command, but the setting is not pre- - served across saves and restores. + A ‘never pickup’ rule takes precedence over an ‘always pickup’ + rule if both match. - Here's a couple of examples of autopickup_exceptions: + Exceptions can be set with the ‘O’ command, but ones set that + way will not be preserved across saves and restores. + + Here are some examples: + + autopickup_exception="<*arrow" + autopickup_exception=">*corpse" + autopickup_exception=">* cursed*" + + The first example above will result in autopickup of any + type of arrow. The second example results in the exclusion of + any corpse from autopickup. The last example results in the ex‐ + clusion of items known to be cursed from autopickup. + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 52 - autopickup_exception="<*arrow" - autopickup_exception=">*corpse" - autopickup_exception=">* cursed*" - The first example above will result in autopickup of any type of - arrow. The second example results in the exclusion of any corpse - from autopickup. The last example results in the exclusion of - items known to be cursed from autopickup. A `never pickup' rule - takes precedence over an `always pickup' rule if both match. 9.8. Configuring User Sounds - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered + Some platforms allow you to define sound files to be played + when a message that matches a user‐defined pattern is delivered to the message window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. - The following config file entries are relevant to mapping + The following config file entries are relevant to mapping user sounds to messages: SOUNDDIR The directory that houses the sound files to be played. SOUND - An entry that maps a sound file to a user-specified message - pattern. Each SOUND entry is broken down into the following + An entry that maps a sound file to a user‐specified message + pattern. Each SOUND entry is broken down into the following parts: - MESG - message window mapping (the only one supported in 3.5). - pattern - the pattern to match. - sound file - the sound file to play. - volume - the volume to be set while playing the sound file. + MESG ‐ message window mapping (the only one supported in + 3.5); + pattern ‐ the pattern to match; + sound file ‐ the sound file to play; + volume ‐ the volume to be set while playing the sound file. + The exact format for the pattern depends on whether the plat‐ + form is built to use ‘‘regular expressions’’ or NetHack’s own + internal pattern matching facility. The ‘‘regular expressions’’ + matching can be much more sophisticated than the internal + NetHack pattern matching, but requires 3rd party libraries on + some platforms. There are plenty of references available else‐ + where for explaining ‘‘regular expressions’’. You can verify + which pattern matching is used by your port with the #version + command. - NetHack 3.5 September 20, 2006 + NetHack’s internal pattern matching routine uses the following + special characters in its pattern matching: + * ‐ matches 0 or more characters; + ? ‐ matches any single character. + Here’s an example of a sound mapping using NetHack’s internal + pattern matching facility: + SOUND=MESG "*chime of a cash register*" "gong.wav" 50 - - NetHack Guidebook 48 - - - - The exact format for the pattern depends on whether the - platform is built to use ``regular expressions'' or NetHack's own - internal pattern matching facility. The ``regular expressions'' - matching can be much more sophisticated than the internal NetHack - pattern matching, but requires 3rd party libraries on some plat- - forms. There are plenty of references available elsewhere for - explaining ``regular expressions''. You can verify which pattern - matching is used by your port with the #version command. - - NetHack's internal pattern matching routine uses the follow- - ing special characters in its pattern matching: - - *--- matches 0 or more characters. - ?--- matches any single character. - - Here's an example of a sound mapping using NetHack's inter- - nal pattern matching facility: - - SOUND=MESG "*chime of a cash register*" "gong.wav" 50 - - specifies that any message with "chime of a cash register" con- - tained in it will trigger the playing of "gong.wav". You can - have multiple SOUND entries in your config file. + specifies that any message with "chime of a cash register" con‐ + tained in it will trigger the playing of file gong.wav. You + can have multiple SOUND entries in your config file. 9.9. Modifying NetHack Symbols NetHack can load entire symbol sets from the symbol file. + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 53 + + + The options that are used to select a particular symbol set from the symbol file are: @@ -3141,13 +3443,13 @@ Set the name of the symbol set that you want to load. roguesymset - Set the name of the symbol set that you want to load for dis- + Set the name of the symbol set that you want to load for dis‐ play on the rogue level. You can also override one or more symbols using the SYMBOLS config file option. Symbols are specified as name:value pairs. - Note that NetHack escape-processes the value string in conven- - tional C fashion. This means that \ is a prefix to take the fol- + Note that NetHack escape‐processes the value string in conven‐ + tional C fashion. This means that \ is a prefix to take the fol‐ lowing character literally. Thus \ needs to be represented as \\. The special escape form \m switches on the meta bit in the symbol value, and the \^ prefix causes the following character to be @@ -3155,26 +3457,13 @@ NetHack Symbols Default Symbol Name Description - ------------------------------------------------------------------------ + ──────────────────────────────────────────────────────────────────────── S_air (air) _ S_altar (altar) " S_amulet (amulet) - - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 49 - - - A S_angel (angelic being) a S_ant (ant or other insect) - ^ S_anti_magic_trap (anti-magic field) + ^ S_anti_magic_trap (anti‐magic field) [ S_armor (suit or piece of armor) [ S_armour (suit or piece of armor) ^ S_arrow_trap (arrow trap) @@ -3182,37 +3471,50 @@ # S_bars (iron bars) B S_bat (bat or bird) ^ S_bear_trap (bear trap) - - S_blcorn (bottom left corner) + ‐ S_blcorn (bottom left corner) b S_blob (blob) + S_book (spellbook) ) S_boomleft (boomerang open left) ( S_boomright (boomerang open right) - ` S_boulder (boulder) - - S_brcorn (bottom right corner) + ‘ S_boulder (boulder) + ‐ S_brcorn (bottom right corner) C S_centaur (centaur) _ S_chain (iron chain) # S_cloud (cloud) c S_cockatrice (cockatrice) $ S_coin (pile of coins) # S_corr (corridor) - - S_crwall (wall) + ‐ S_crwall (wall) ^ S_dart_trap (dart trap) & S_demon (major demon) * S_digbeam (dig beam) > S_dnladder (ladder down) + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 54 + + + > S_dnstair (staircase down) d S_dog (dog or other canine) D S_dragon (dragon) ; S_eel (sea monster) E S_elemental (elemental) / S_explode1 (explosion top left) - - S_explode2 (explosion top center) - `\' S_explode3 (explosion top right) + ‐ S_explode2 (explosion top center) + ‘\’ S_explode3 (explosion top right) | S_explode4 (explosion middle left) S_explode5 (explosion middle center) | S_explode6 (explosion middle right) - `\' S_explode7 (explosion bottom left) - - S_explode8 (explosion bottom center) + ‘\’ S_explode7 (explosion bottom left) + ‐ S_explode8 (explosion bottom center) / S_explode9 (explosion bottom right) e S_eye (eye or sphere) ^ S_falling_rock_trap (falling rock trap) @@ -3225,31 +3527,18 @@ * S_gem (gem or rock) S_ghost (ghost) H S_giant (giant humanoid) - - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 50 - - - G S_gnome (gnome) - ' S_golem (golem) + ’ S_golem (golem) | S_grave (grave) g S_gremlin (gremlin) - - S_hbeam (wall) + ‐ S_hbeam (wall) # S_hcdbridge (horizontal raised drawbridge) + S_hcdoor (closed door) | S_hodoor (open door) ^ S_hole (hole) @ S_human (human or elf) h S_humanoid (humanoid) - - S_hwall (horizontal wall) + ‐ S_hwall (horizontal wall) i S_imp (imp or minor demon) J S_jabberwock (jabberwock) j S_jelly (jelly) @@ -3263,9 +3552,22 @@ y S_light (light) # S_litcorr (lit corridor) : S_lizard (lizard) - `\' S_lslant (wall) + ‘\’ S_lslant (wall) ^ S_magic_portal (magic portal) ^ S_magic_trap (magic trap) + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 55 + + + m S_mimic (mimic) ] S_mimic_def (mimic) M S_mummy (mummy) @@ -3282,7 +3584,7 @@ q S_quadruped (quadruped) Q S_quantmech (quantum mechanic) = S_ring (ring) - ` S_rock (boulder or statue) + ‘ S_rock (boulder or statue) r S_rodent (rodent) ^ S_rolling_boulder_trap (rolling boulder trap) / S_rslant (wall) @@ -3291,19 +3593,6 @@ ? S_scroll (scroll) # S_sink (sink) ^ S_sleeping_gas_trap (sleeping gas trap) - - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 51 - - - S S_snake (snake) s S_spider (arachnid or centipede) ^ S_spiked_pit (spiked pit) @@ -3314,27 +3603,40 @@ * S_ss4 (magic shield 4 of 4) ^ S_statue_trap (statue trap) S_stone (dark part of a room) - - S_sw_bc (swallow bottom center) - `\' S_sw_bl (swallow bottom left) + ‐ S_sw_bc (swallow bottom center) + ‘\’ S_sw_bl (swallow bottom left) / S_sw_br (swallow bottom right) | S_sw_ml (swallow middle left) | S_sw_mr (swallow middle right) - - S_sw_tc (swallow top center) + ‐ S_sw_tc (swallow top center) / S_sw_tl (swallow top left) - `\' S_sw_tr (swallow top right) - - S_tdwall (wall) + ‘\’ S_sw_tr (swallow top right) + ‐ S_tdwall (wall) ^ S_teleportation_trap (teleportation trap) S_throne (opulent throne) - - S_tlcorn (top left corner) + ‐ S_tlcorn (top left corner) | S_tlwall (wall) - ( S_tool (useful item (pick-axe key lamp...)) + ( S_tool (useful item (pick‐axe key lamp...)) ^ S_trap_door (trap door) t S_trapper (trapper or lurker above) - - S_trcorn (top right corner) + ‐ S_trcorn (top right corner) # S_tree (tree) + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 56 + + + T S_troll (troll) | S_trwall (wall) - - S_tuwall (wall) + ‐ S_tuwall (wall) U S_umber (umber hulk) u S_unicorn (unicorn or horse) < S_upladder (ladder up) @@ -3343,7 +3645,7 @@ | S_vbeam (wall) # S_vcdbridge (vertical raised drawbridge) + S_vcdoor (closed door) - - S_vodoor (open door) + ‐ S_vodoor (open door) v S_vortex (vortex) | S_vwall (vertical wall) / S_wand (wand) @@ -3357,48 +3659,47 @@ X S_xorn (xorn) Y S_yeti (apelike creature) Z S_zombie (zombie) - - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 52 - - - z S_zruty (zruty) 9.10. Configuring NetHack for Play by the Blind NetHack can be set up to use only standard ASCII characters - for making maps of the dungeons. This makes the MS-DOS versions + for making maps of the dungeons. This makes the MS‐DOS versions of NetHack completely accessible to the blind who use speech and/or Braille access technologies. Players will require a good - working knowledge of their screen-reader's review features, and + working knowledge of their screen‐reader’s review features, and will have to know how to navigate horizontally and vertically - character by character. They will also find the search capabili- - ties of their screen-readers to be quite valuable. Be certain to + character by character. They will also find the search capabili‐ + ties of their screen‐readers to be quite valuable. Be certain to examine this Guidebook before playing so you have an idea what - the screen layout is like. You'll also need to be able to locate + the screen layout is like. You’ll also need to be able to locate the PC cursor. It is always where your character is located. - Merely searching for an @-sign will not always find your charac- + Merely searching for an @‐sign will not always find your charac‐ ter since there are other humanoids represented by the same sign. - Your screen-reader should also have a function which gives you + Your screen‐reader should also have a function which gives you the row and column of your review cursor and the PC cursor. - These co-ordinates are often useful in giving players a better + These co‐ordinates are often useful in giving players a better sense of the overall location of items on the screen. While it is not difficult for experienced users to edit the defaults.nh file to accomplish this, novices may find this task - somewhat daunting. Included within the ``symbols'' file of all + somewhat daunting. Included within the ‘‘symbols’’ file of all official distributions of NetHack is a symset called NHAccess. Selecting that symset in your configuration file will cause the game to run in a manner accessible to the blind. After you have gained some experience with the game and with editing files, you + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 57 + + + may want to alter settings via SYMBOLS= in your configuration file to better suit your preferences. The most crucial settings to make the game accessible are: @@ -3414,28 +3715,74 @@ This will assist in the interface to speech synthesizers. number_pad - A lot of speech access programs use the number-pad to review + A lot of speech access programs use the number‐pad to review the screen. If this is the case, disable the number_pad option - and use the traditional Rogue-like commands. + and use the traditional Rogue‐like commands. + + 9.11. Global Configuration for System Administrators + + If NetHack is compiled with the SYSCF option, a system ad‐ + ministrator should set up a global configuration; this is a file + in the same format as the traditional per‐user configuration file + (see above). This file should be named sysconf and placed in the + same directory as the other NetHack support files. The options + recognized in this file are listed below. Any option not set us‐ + es a compiled‐in default (which may not be appropriate for your + system). + + WIZARDS A space‐separated list of user names who are allowed to + play in wizard mode (the debugging mode, not the magic‐using + role). A value of a single asterisk (*) allows anyone to start + a game in wizard mode. + + SHELLERS A list of users who are allowed to use the shell es‐ + cape command (!). The syntax is the same as WIZARDS. + + MAXPLAYERS Limit the maximum number of games that can be run‐ + ning at the same time. + + SUPPORT A string explaining how to get local support (no de‐ + fault value). + + RECOVER A string explaining how to recover a game on this sys‐ + tem (no default value). + + SEDUCE 0 or 1 to disable or enable, respectively, the SEDUCE + option (see the source for details on this function). + + The following options affect the score file: + + PERSMAX Maximum number of entries for one person. + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 58 + + + + ENTRYMAX Maximum number of entries in the score file. + + POINTSMIN Minimum number of points to get an entry in the score + file. + + PERS_IS_UID 0 or 1 to use user names or numeric userids, re‐ + spectively, to identify unique people for the score file. + + MAX_STATUENAME_RANK Maximum number of score file entries to use + for random statue names (default is 10). 10. Scoring NetHack maintains a list of the top scores or scorers on your machine, depending on how it is set up. In the latter case, - each account on the machine can post only one non-winning score + each account on the machine can post only one non‐winning score on this list. If you score higher than someone else on this - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 53 - - - list, or better your previous score, you will be inserted in the proper place under your current name. How many scores are kept can also be set up when NetHack is compiled. @@ -3446,280 +3793,397 @@ your gold intact. If, however, you get killed in the Mazes of Menace, the guild will only hear about 90% of your gold when your corpse is discovered (adventurers have been known to collect - finder's fees). So, consider whether you want to take one last + finder’s fees). So, consider whether you want to take one last hit at that monster and possibly live, or quit and stop with whatever you have. If you quit, you keep all your gold, but if you swing and live, you might find more. If you just want to see what the current top players/games - list is, you can type nethack -s all on most versions. + list is, you can type nethack ‐s all on most versions. 11. Explore mode NetHack is an intricate and difficult game. Novices might falter in fear, aware of their ignorance of the means to survive. - Well, fear not. Your dungeon may come equipped with an ``ex- - plore'' or ``discovery'' mode that enables you to keep old save - files and cheat death, at the paltry cost of not getting on the - high score list. + Well, fear not. Your dungeon comes equipped with an ‘‘explore’’ + or ‘‘discovery’’ mode that enables you to keep old save files and + cheat death, at the paltry cost of not getting on the high score + list. There are two ways of enabling explore mode. One is to - start the game with the -X switch. The other is to issue the `X' - command while already playing the game. The other benefits of - explore mode are left for the trepid reader to discover. + start the game with the ‐X command‐line switch or with the play‐ + mode:explore option. The other is to issue the ‘‘#exploremode’’ + extended command while already playing the game. Starting a new + game in explore mode provides your character with a wand of wish‐ + ing in initial inventory; switching during play does not. The + other benefits of explore mode are left for the trepid reader to + discover. + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 59 + + + + 11.1. Debug mode + + Debug mode, also known as wizard mode, is undocumented aside + from this brief description. It is intended for tracking down + problems within the program rather than to provide god‐like pow‐ + ers to your character, and players who attempt debugging are ex‐ + pected to figure out how to use it themselves. It is initiated + by starting the game with the ‐D command‐line switch or with the + playmode:debug option. + + For some systems, the player must be logged in under a par‐ + ticular user name to be allowed to use debug mode; for others, + the hero must be given a particular character name (but may be + any role; there’s no connection between ‘‘wizard mode’’ and the + Wizard role). And on any system, the program might have been + configured to omit debug mode entirely. Attempting to start a + game in debug mode when not allowed or not available will result + in falling back to explore mode instead. 12. Credits - The original hack game was modeled on the Berkeley UNIX - rogue game. Large portions of this paper were shamelessly - cribbed from A Guide to the Dungeons of Doom, by Michael C. Toy - and Kenneth C. R. C. Arnold. Small portions were adapted from + The original hack game was modeled on the Berkeley UNIX + rogue game. Large portions of this paper were shamelessly + cribbed from A Guide to the Dungeons of Doom, by Michael C. Toy + and Kenneth C. R. C. Arnold. Small portions were adapted from Further Exploration of the Dungeons of Doom, by Ken Arromdee. - NetHack is the product of literally dozens of people's work. - Main events in the course of the game development are described + NetHack is the product of literally dozens of people’s work. + Main events in the course of the game development are described below: - Jay Fenlason wrote the original Hack, with help from Kenny + Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome and Jon Payne. - Andries Brouwer did a major re-write, transforming Hack into - a very different game, and published (at least) three versions + Andries Brouwer did a major re‐write, transforming Hack into + a very different game, and published (at least) three versions (1.0.1, 1.0.2, and 1.0.3) for UNIX machines to the Usenet. - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 54 - - - - Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, - producing PC HACK 1.01e, added support for DEC Rainbow graphics - in version 1.03g, and went on to produce at least four more ver- + Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS‐DOS, + producing PC HACK 1.01e, added support for DEC Rainbow graphics + in version 1.03g, and went on to produce at least four more ver‐ sions (3.0, 3.2, 3.51, and 3.6). - R. Black ported PC HACK 3.51 to Lattice C and the Atari + R. Black ported PC HACK 3.51 to Lattice C and the Atari 520/1040ST, producing ST Hack 1.03. Mike Stephenson merged these various versions back together, - incorporating many of the added features, and produced NetHack - 1.4. He then coordinated a cast of thousands in enhancing and - debugging NetHack 1.4 and released NetHack versions 2.2 and 2.3. + incorporating many of the added features, and produced NetHack + 1.4. He then coordinated a cast of thousands in enhancing and + debugging NetHack 1.4 and released NetHack versions 2.2 and 2.3. + + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 60 + + Later, Mike coordinated a major rewrite of the game, heading - a team which included Ken Arromdee, Jean-Christophe Collet, Steve - Creps, Eric Hendrickson, Izchak Miller, John Rupley, Mike Threep- + a team which included Ken Arromdee, Jean‐Christophe Collet, Steve + Creps, Eric Hendrickson, Izchak Miller, John Rupley, Mike Threep‐ oint, and Janet Walz, to produce NetHack 3.0c. - NetHack 3.0 was ported to the Atari by Eric R. Smith, to - OS/2 by Timo Hakulinen, and to VMS by David Gentzel. The three + NetHack 3.0 was ported to the Atari by Eric R. Smith, to + OS/2 by Timo Hakulinen, and to VMS by David Gentzel. The three of them and Kevin Darcy later joined the main development team to produce subsequent revisions of 3.0. - Olaf Seibert ported NetHack 2.3 and 3.0 to the Amiga. Norm - Meluch, Stephen Spackman and Pierre Martineau designed overlay - code for PC NetHack 3.0. Johnny Lee ported NetHack 3.0 to the - Macintosh. Along with various other Dungeoneers, they continued - to enhance the PC, Macintosh, and Amiga ports through the later + Olaf Seibert ported NetHack 2.3 and 3.0 to the Amiga. Norm + Meluch, Stephen Spackman and Pierre Martineau designed overlay + code for PC NetHack 3.0. Johnny Lee ported NetHack 3.0 to the + Macintosh. Along with various other Dungeoneers, they continued + to enhance the PC, Macintosh, and Amiga ports through the later revisions of 3.0. - Headed by Mike Stephenson and coordinated by Izchak Miller - and Janet Walz, the development team which now included Ken Ar- - romdee, David Cohrs, Jean-Christophe Collet, Kevin Darcy, Matt - Day, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric - Raymond, and Eric Smith undertook a radical revision of 3.0. - They re-structured the game's design, and re-wrote major parts of - the code. They added multiple dungeons, a new display, special - individual character quests, a new endgame and many other new + Headed by Mike Stephenson and coordinated by Izchak Miller + and Janet Walz, the development team which now included Ken Ar‐ + romdee, David Cohrs, Jean‐Christophe Collet, Kevin Darcy, Matt + Day, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric + Raymond, and Eric Smith undertook a radical revision of 3.0. + They re‐structured the game’s design, and re‐wrote major parts of + the code. They added multiple dungeons, a new display, special + individual character quests, a new endgame and many other new features, and produced NetHack 3.1. - Ken Lorber, Gregg Wonderly and Greg Olson, with help from - Richard Addison, Mike Passaretti, and Olaf Seibert, developed + Ken Lorber, Gregg Wonderly and Greg Olson, with help from + Richard Addison, Mike Passaretti, and Olaf Seibert, developed NetHack 3.1 for the Amiga. - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + Norm Meluch and Kevin Smolkowski, with help from Carl Sche‐ lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC. - Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny - Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack - 3.1 for the Macintosh, porting it for MPW. Building on their de- + Jon W{tte and Hao‐yang Wang, with help from Ross Brown, Mike + Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny + Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack + 3.1 for the Macintosh, porting it for MPW. Building on their de‐ velopment, Barton House added a Think C port. - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 55 - - - - Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port‐ + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + Delahunty, was responsible for the VMS version of NetHack 3.1. Michael Allison ported NetHack 3.1 to Windows NT. - Dean Luick, with help from David Cohrs, developed NetHack - 3.1 for X11. Warwick Allison wrote a tiled version of NetHack - for the Atari; he later contributed the tiles to the DevTeam and + Dean Luick, with help from David Cohrs, developed NetHack + 3.1 for X11. Warwick Allison wrote a tiled version of NetHack + for the Atari; he later contributed the tiles to the DevTeam and tile support was then added to other platforms. - The 3.2 development team, comprised of Michael Allison, Ken - Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, - Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric - Smith, Mike Stephenson, Janet Walz, and Paul Winner, released + The 3.2 development team, comprised of Michael Allison, Ken + Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, + Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 61 + + + + Smith, Mike Stephenson, Janet Walz, and Paul Winner, released version 3.2 in April of 1996. Version 3.2 marked the tenth anniversary of the formation of - the development team. In a testament to their dedication to the - game, all thirteen members of the original development team re- - mained on the team at the start of work on that release. During - the interval between the release of 3.1.3 and 3.2, one of the - founding members of the development team, Dr. Izchak Miller, was - diagnosed with cancer and passed away. That release of the game + the development team. In a testament to their dedication to the + game, all thirteen members of the original development team re‐ + mained on the team at the start of work on that release. During + the interval between the release of 3.1.3 and 3.2, one of the + founding members of the development team, Dr. Izchak Miller, was + diagnosed with cancer and passed away. That release of the game was dedicated to him by the development and porting teams. - During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and - made these ``variants'' publicly available: + During the lifespan of NetHack 3.1 and 3.2, several enthusi‐ + asts of the game added their own modifications to the game and + made these ‘‘variants’’ publicly available: - Tom Proudfoot and Yuval Oren created NetHack++, which was - quickly renamed NetHack--. Working independently, Stephen White - wrote NetHack Plus. Tom Proudfoot later merged NetHack Plus and - his own NetHack-- to produce SLASH. Larry Stewart-Zerba and War- - wick Allison improved the spell casting system with the Wizard - Patch. Warwick Allison also ported NetHack to use the Qt inter- + Tom Proudfoot and Yuval Oren created NetHack++, which was + quickly renamed NetHack‐‐. Working independently, Stephen White + wrote NetHack Plus. Tom Proudfoot later merged NetHack Plus and + his own NetHack‐‐ to produce SLASH. Larry Stewart‐Zerba and War‐ + wick Allison improved the spell casting system with the Wizard + Patch. Warwick Allison also ported NetHack to use the Qt inter‐ face. - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'em, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the DevTeam and incorporated the best + Warren Cheung combined SLASH with the Wizard Patch to pro‐ + duce Slash’em, and with the help of Kevin Hugo, added more fea‐ + tures. Kevin later joined the DevTeam and incorporated the best of these ideas in NetHack 3.3. The final update to 3.2 was the bug fix release 3.2.3, which - was released simultaneously with 3.3.0 in December 1999 just in + was released simultaneously with 3.3.0 in December 1999 just in time for the Year 2000. The 3.3 development team, consisting of Michael Allison, Ken - Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, - Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lorber, Dean - Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet Walz, and - Paul Winner, released 3.3.0 in December 1999 and 3.3.1 in August + Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, + Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lorber, Dean + Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet Walz, and + Paul Winner, released 3.3.0 in December 1999 and 3.3.1 in August of 2000. - - - - NetHack 3.5 September 20, 2006 - - - - - - NetHack Guidebook 56 - - - Version 3.3 offered many firsts. It was the first version to - separate race and profession. The Elf class was removed in pref- + separate race and profession. The Elf class was removed in pref‐ erence to an elf race, and the races of dwarves, gnomes, and orcs - made their first appearance in the game alongside the familiar - human race. Monk and Ranger roles joined Archeologists, Barbar- - ians, Cavemen, Healers, Knights, Priests, Rogues, Samurai, - Tourists, Valkyries and of course, Wizards. It was also the - first version to allow you to ride a steed, and was the first - version to have a publicly available web-site listing all the - bugs that had been discovered. Despite that constantly growing - bug list, 3.3 proved stable enough to last for more than a year + made their first appearance in the game alongside the familiar + human race. Monk and Ranger roles joined Archeologists, Barbar‐ + ians, Cavemen, Healers, Knights, Priests, Rogues, Samurai, + Tourists, Valkyries and of course, Wizards. It was also the + first version to allow you to ride a steed, and was the first + version to have a publicly available web‐site listing all the + bugs that had been discovered. Despite that constantly growing + bug list, 3.3 proved stable enough to last for more than a year and a half. - The 3.5 development team initially consisted of Michael Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Kevin Hugo, Ken - Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and - Paul Winner, with Warwick Allison joining just before the re- + + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 62 + + + + The 3.4 development team initially consisted of Michael Al‐ + lison, Ken Arromdee, David Cohrs, Jessie Collet, Kevin Hugo, Ken + Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and + Paul Winner, with Warwick Allison joining just before the re‐ lease of NetHack 3.4.0 in March 2002. - As with version 3.3, various people contributed to the game + As with version 3.3, various people contributed to the game as a whole as well as supporting ports on the different platforms that NetHack runs on: - Pat Rankin maintained 3.5 for VMS. + Pat Rankin maintained 3.4 for VMS. - Michael Allison maintained NetHack 3.5 for the MS-DOS plat- + Michael Allison maintained NetHack 3.4 for the MS‐DOS plat‐ form. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en‐ hanced the Macintosh port of 3.4. - Michael Allison, David Cohrs, Alex Kompel, Dion Nicolaas, - and Yitzhak Sapir maintained and enhanced 3.5 for the Microsoft - Windows platform. Alex Kompel contributed a new graphical inter- - face for the Windows port. Alex Kompel also contributed a Win- + Michael Allison, David Cohrs, Alex Kompel, Dion Nicolaas, + and Yitzhak Sapir maintained and enhanced 3.4 for the Microsoft + Windows platform. Alex Kompel contributed a new graphical inter‐ + face for the Windows port. Alex Kompel also contributed a Win‐ dows CE port for 3.4.1. Ron Van Iwaarden was the sole maintainer of NetHack for OS/2 - the past several releases. Unfortunately Ron's last OS/2 machine - stopped working in early 2006. A great many thanks to Ron for + the past several releases. Unfortunately Ron’s last OS/2 machine + stopped working in early 2006. A great many thanks to Ron for keeping NetHack alive on OS/2 all these years. - Janne Salmijarvi and Teemu Suikki maintained and enhanced - the Amiga port of 3.5 after Janne Salmijarvi resurrected it for + Janne Salmijarvi and Teemu Suikki maintained and enhanced + the Amiga port of 3.4 after Janne Salmijarvi resurrected it for 3.3.1. - Christian ``Marvin'' Bressler maintained 3.5 for the Atari + Christian ‘‘Marvin’’ Bressler maintained 3.4 for the Atari after he resurrected it for 3.3.1. - There is a NetHack web site maintained by Ken Lorber at + The release of NetHack 3.4.3 in December 2003 marked the be‐ + ginning of a long release hiatus. 3.4.3 proved to be a remarkably + stable version that provided continued enjoyment by the community + for more than a decade. The devteam slowly and quietly continued + to work on the game behind the scenes during the tenure of 3.4.3. + It was during that same period that several new variants emerged + within the NetHack community. Notably sporkhack by Derek S. Ray, + unnethack by Patric Mueller, nitrohack and its successors origi‐ + nally by Daniel Thaler and then by Alex Smith, and Dynahack by + Tung Nguyen. Some of those variants continue to be developed, + maintained, and enjoyed by the community to this day. + + In September 2014, an interim snapshot of the code under de‐ + velopment was released publicly by other parties. Since that code + was a work‐in‐progress and had not gone through a period of de‐ + bugging, it was decided that the version numbers present on that + code snapshot would be retired and never used in an official + NetHack release. An announcement was posted on the devteam’s + + + NetHack 3.6 March 27, 2015 + + + + + + NetHack Guidebook 63 + + + + official nethack.org website to that effect, stating that there + would never be a 3.4.4, 3.5, or 3.5.0 official release version. + + In January 2015, preparation began for the release of + NetHack 3.6 + + At the beginning of development for what would eventually + get released as 3.6.0, the development team consisted of Warwick + Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Col‐ + let, Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet + Walz, and Paul Winner. Leading up to the release of 3.6.0 in + early 2015, new members Sean Hunt, Pasi Kallinen, and Derek S. + Ray joined the NetHack development team, + + 3.6.0 TODO insert apprpriate description of 3.6.0 here + + The development team, as well as Steve VanDevender and Kevin + Smolkowski ensured that NetHack 3.6.0 continued to operate on + various Unix flavors as well as maintaining the X11 interface. + + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main‐ + tained the port of NetHack 3.6.0 for Mac. + + Michael Allison, Derek S. Ray, Yitzhak Sapir, Alex Kompel, + and David Cohrs maintained the port of NetHack 3.6.0 for Mi‐ + crosoft Windows. + + Jeff Bailey created and maintained a port of NetHack 3.6.0 + for Chrome. + + TODO Alex Kompel maintained a port of NetHack 3.6.0 to Win‐ + dows Phone. + + This version of the game is special in a particular way. + Near the end of the development of 3.6, one of the significant + inspirations for many of the humorous and fun features found in + the game, author Terry Pratchett, passed away. This version of + the game is dedicated to him. + + The official NetHack web site is maintained by Ken Lorber at http://www.nethack.org/. - - - - - - - - - - - + SHOUT‐OUTS + + The devteam would like to give a special "shout‐out" to + thank the generous people primarily responsible for the public + NetHack servers available for playing the game at nethack.alt.org + and devnull.net. In addition to providing a way for the public to + play a game of NetHack from almost anywhere, they have hosted an‐ + nual NetHack tournaments for many, many years. + + On behalf of the NetHack community, thank you very much to + M. Drew Streib, Pasi Kallinen and Robin Bandy. - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 - NetHack Guidebook 57 + NetHack Guidebook 64 + ‐ ‐ ‐ ‐ ‐ ‐ ‐ ‐ ‐ ‐ + From time to time, some depraved individual out there in netland sends a particularly intriguing modification to help out with the game. The Gods of the Dungeon sometimes make note of the names of the worst of these miscreants in this, the list of Dungeoneers: - Adam Aronow Izchak Miller Mike Passaretti - Alex Kompel J. Ali Harlow Mike Stephenson - Andreas Dorn Janet Walz Norm Meluch - Andy Church Janne Salmijarvi Olaf Seibert - Andy Swanson Jean-Christophe Collet Pasi Kallinen - Ari Huttunen Jochen Erwied Pat Rankin - Barton House John Kallen Paul Winner - Benson I. Margulies John Rupley Pierre Martineau - Bill Dyer John S. Bien Ralf Brown - Boudewijn Waijers Johnny Lee Ray Chason - Bruce Cox Jon W{tte Richard Addison - Bruce Holloway Jonathan Handler Richard Beigel - Bruce Mewborne Joshua Delahunty Richard P. Hughey - Carl Schelin Keizo Yamamoto Rob Menke + Adam Aronow J. Ali Harlow Mike Stephenson + Alex Kompel Janet Walz Norm Meluch + Andreas Dorn Janne Salmijarvi Olaf Seibert + Andy Church Jean‐Christophe Collet Pasi Kallinen + Andy Swanson Jeff Bailey Pat Rankin + Ari Huttunen Jochen Erwied Paul Winner + Barton House John Kallen Pierre Martineau + Benson I. Margulies John Rupley Ralf Brown + Bill Dyer John S. Bien Ray Chason + Boudewijn Waijers Johnny Lee Richard Addison + Bruce Cox Jon W{tte Richard Beigel + Bruce Holloway Jonathan Handler Richard P. Hughey + Bruce Mewborne Joshua Delahunty Rob Menke + Carl Schelin Keizo Yamamoto Robin Bandy Chris Russo Ken Arnold Robin Johnson David Cohrs Ken Arromdee Roderick Schertler David Damerell Ken Lorber Roland McGrath @@ -3727,10 +4191,11 @@ David Hairston Kevin Darcy Ronnen Miller Dean Luick Kevin Hugo Ross Brown Del Lamb Kevin Sitze Sascha Wostmann - Deron Meranda Kevin Smolkowski Scott Bigham - Dion Nicolaas Kevin Sweet Scott R. Turner - Dylan O'Donnell Lars Huttar Stephen Spackman - Eric Backus Leon Arnott Stephen White + Derek S. Ray Kevin Smolkowski Scott Bigham + Deron Meranda Kevin Sweet Scott R. Turner + Dion Nicolaas Lars Huttar Sean Hunt + Dylan O’Donnell Leon Arnott Stephen Spackman + Eric Backus M. Drew Streib Stephen White Eric Hendrickson Malcolm Ryan Steve Creps Eric R. Smith Mark Gooderum Steve Linhart Eric S. Raymond Mark Modrall Steve VanDevender @@ -3740,9 +4205,10 @@ Greg Laskin Michael Allison Tom Almy Greg Olson Michael Feir Tom West Gregg Wonderly Michael Hamel Warren Cheung - Hao-yang Wang Michael Sokolov Warwick Allison + Hao‐yang Wang Michael Sokolov Warwick Allison Helge Hafting Mike Engber Yitzhak Sapir - Irina Rempt-Drijfhout Mike Gallop + Irina Rempt‐Drijfhout Mike Gallop + Izchak Miller Mike Passaretti Brand and product names are trademarks or registered trademarks of their respective holders. @@ -3752,11 +4218,7 @@ - - - - - NetHack 3.5 September 20, 2006 + NetHack 3.6 March 27, 2015 diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 5d9f4707a..5fa64755d 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -63,7 +63,7 @@ wizard mode: avoid division by 0 crash for level teleport in the endgame if don't #sit on an object in a pit if you're only on the precipice fix message when pushing a boulder into a pool while riding plural of "Nazgul" is "Nazgul" not "Nazguls" -trap messages referring to named steed were ackwardly worded when hallucination +trap messages referring to named steed were awkwardly worded when hallucination overrode use of the name some actions such as eating corpses off the floor didn't check whether hero could reach the bottom of a pit @@ -117,7 +117,7 @@ shopkeeper removal of trap from shop doorway yields an open door instead of a closed one if an intact open door is present guarantee that hostile djinn released from bottles really are hostile handle lava when removing or losing water walking boots -fix incomplete sentence occuring when unique monster's corpse fell down stairs +fix incomplete sentence occurring when unique monster's corpse fell down stairs fractured boulders or statues produced inconsistent object settings on the resulting rocks really fix rolling boulder bug C340-18, the previous "fix" reversed the test @@ -165,7 +165,7 @@ clean up messages when you stop levitation while riding a flying steed monsters evading a kick on noteleport levels would cause a "teleports" message interrupt current activity during certain stages of petrification or vomiting warning about bad food didn't recognize tin of Medusa meat -eating tainted Medusa corpse caused food poisioning instead of petrification +eating tainted Medusa corpse caused food poisoning instead of petrification avoid potential stale pointer use after magic bag explosion nymphs and monkeys can't steal rings worn under gloves monkeys can't steal rings worn under cursed weapon @@ -237,7 +237,7 @@ when there were multiple boulders at a location, moving one of them sometimes resulted in line-of-sight anomalies unicorn can't catch gems if it is asleep or paralyzed fix grammar when choking on gold -prevent lose-level+regain-level cycle from arbritrarily boosting HP and Pw +prevent lose-level+regain-level cycle from arbitrarily boosting HP and Pw prevent polymorphing into "new man" at low level from magnifying HP and Pw some messages which referred to "mirror" ought to have used "looking glass" incubi react to mirrors @@ -360,8 +360,8 @@ code handling a monster's use of potion or food to cure stoning or confusion properly handle destruction of equipment carried by monsters hit by disintegration breath; life-saving retained conferred properties of formerly worn items (loss of steed's saddle caused much confusion) -don't exercize or abuse wisdom when rumors get used for random graffiti -don't exercize wisdom twice for each minor oracle consultation +don't exercise or abuse wisdom when rumors get used for random graffiti +don't exercise wisdom twice for each minor oracle consultation don't welcome the hero to Delphi if the Oracle was angered before first entry create_object() created lizard corpses without timers and troll corpses with their revive timers, then changed the corpsenm field @@ -383,7 +383,7 @@ specifying role and/or race along with an invalid alignment for it/them in temple donation can recover protection previously stolen by attrcurse attack even when protection amount is so big that no increment would be given meditating monsters stop meditating when affected by something which wakes - sleeping mosnters + sleeping monsters monsters capable of hiding can't do so when trapped or while holding you limit recursive calls to spoteffects (poly'd hero fell into water, reverted to human because of it, fell into same water, then crawled out twice) @@ -474,7 +474,7 @@ suppress corpse from bones data if death is due to being dissolved in lava suppress "you rise from the dead" if game ends due to be turned into slime hero poly'd into stone golem and wielding cockatrice corpse casts stone-to- flesh at self to become flesh golem will revert to stone if no gloves -don't give erroneous " disppears" message for hero poly'd into quantum +don't give erroneous " disappears" message for hero poly'd into quantum mechanic who hits engulfer while swallowed and blinded demon lords/princes can't be summoned to the elemental or Astral planes feedback from casting spell of protection was wrong in some situations @@ -496,7 +496,7 @@ can't eat an artifact you're unable to touch attempting to kick beyond map edge performed an out of array bounds memory access; symptom seen was "show_glyph: bad pos" warning when blind attempting to engrave with an empty wand should always use a turn -don't access freed memory after engraving "wrests one last charnge" from wand +don't access freed memory after engraving "wrests one last charge" from wand a magic portal could be rendered inactive for the hero if a successful hangup save took place during level change; leaving the level by any means other than triggering the portal would reactivate it @@ -645,7 +645,7 @@ secret door detection's trap finding is no longer blocked by water or clouds potion thrown by monster which hit a long worm's tail gave feedback about hitting its head implement energy vortex's previously unused energy drain attack -changing alignment type resets alignment record to 0 (nomimally aligned) +changing alignment type resets alignment record to 0 (nominally aligned) jellyfish do not technically have a head while polymorphed, suppress attribute gain/lose earned by pre-poly exercise wizard mode #monpolycontrol prompting asked about "it" when monster was unseen @@ -670,7 +670,7 @@ if polymorph causes a monster to drop items, they won't be used up via monsters who ate green slime corpses weren't turned into green slime "hand slip" while naming an object would never pick 'z' as a substitute letter hero would "gladly take off " for nymph or succubus even while asleep -concealed mimic wasn't revealed if kicking attmpt yielded a clumsy miss +concealed mimic wasn't revealed if kicking attempt yielded a clumsy miss too accurate feedback given to a blinded hero when a monster summons insects if life-saved steed became untame, repeated "placing steed onto map?" warnings would be given as long as the hero remained mounted @@ -730,7 +730,7 @@ shouldn't have been able write scrolls by guessing type name when they're scrolls given names can be written by assigned name as well as by description fix writing feedback "the spellbook warps strangely, then turns parchment" make stone artifacts usually resist stone-to-flesh -when reading an unknown scroll and learning it, discovery of teleporation was +when reading an unknown scroll and learning it, discovery of teleportation was too late if hero happened to land on another scroll of teleportation using an unlocking tool on a closed door which was actually a mimic reported that there was no door to unlock instead of exposing the mimic @@ -760,7 +760,7 @@ for number_pad:2 (MSDOS compatibility), M-5 (Alt+5, or Shift+keypad5 using MSDOS/Windows keystroke hackery) didn't function as G movement prefix if an angry shopkeeper chased the hero to a different level and then got paid off, he'd dismiss kops on that other level but not on his shop level -objects inside the Wizard's Tower can't be teleport to outside and vica versa +objects inside the Wizard's Tower can't be teleport to outside and vice versa dying in lava and being life-saved or leaving bones would destroy ring of fire resistance if it happened to be made of wood, and also burn up scrolls of fire and spellbook of fireball @@ -786,7 +786,7 @@ when shop prices are adjusted, handle roundoff (integer truncation) better for hero poly'd into a monster form that lacks a weapon attack but has a claw attack, use wielded weapon even when claw attack isn't the very first rename the SLEEPING property and Sleeping attribute to SLEEPY and Sleepy, resp. -character escape sequence handling during options processing was vulernable +character escape sequence handling during options processing was vulnerable to malformed escapes and could potentially be abused to clobber the stack and launch a buffer overrun attack give alternate message for " turns to flee" when mon can't move @@ -815,7 +815,7 @@ hangup save made during magic mapping or detection performed while underwater could put hero on top of the water after restore fix bug preventing stone-resistant monsters w/o gloves from wielding cockatrices items conferring life drain resistance were affected by drain life spell -'a'pply command could be used to recogniize undiscovered potions of oil +'a'pply command could be used to recognize undiscovered potions of oil fix replacing an existing bones file in wizard mode [load?y, unlink?n, die?y, save?y, replace?y] for configurations using external file compression theft of worn armor with wear/unwear delay would interfere with completion of @@ -872,13 +872,28 @@ data.base "gelatinous cube" and "jack boot" have their own entries data.base "vampire bat" matched twice; use the bat entry data.base dagger attribution started with spaces instead of tabs remove 'if (Deaf)' guards preceding You_hear which already checks deafness -tse a menu to loot multiple containers +use a menu to loot multiple containers do_look() in post-3.4.3 used glyph prior to setting it in pager.c charge for a boulder that fills a pit in shop abuse wisdom in keeping with Rider eating message message inconsistency: death message "swallowed whole" was preceded by "You bite into" improve the messaging when a monster you can't see is causing an obstruction +add option mention_walls, which gives feedback when bumping against a wall +fix invalid pointer dereference in morguemon if ndemon returns NON_PM +after object loss through polyshudder don't get left hiding under nothing + if you're polymorphed into a hider +show object symbols in menu headings in menus where those object symbols + act as menu accelerators, toggleable via "menu_objsyms" option +show t-shirt text at end of game inventory disclose +hitting with a polearm remembers the position of the last monster you hit +allow showing legal polearm positions when asked for location to hit +add messages for trying to pick up some terrain features +boomerang makes noise when hitting a sink +non-pet rust monsters would eat rust-proofed non-digestibles but ignore + those non-digestibles otherwise +kicking a grave may topple the gravestone +allow showing legal jumping positions when asked for location to jump to Platform- and/or Interface-Specific Fixes @@ -979,7 +994,7 @@ burying a punishment ball no longer ends your punishment add clicklook option to allow looking at things on the display by clicking right mouse button when floating mouse pointer over them Izchak's lighting store is now able to stock oil for your lamp -provide core support for saving of messsage history in save file +provide core support for saving of message history in save file the following actions can now be continued after save/restore: digging, eating, studying, removing armor hero-created and monster-created ice will eventually melt away @@ -1090,6 +1105,13 @@ pressing @ when cursor positioning moves cursor on top of hero pressing # when cursor positioning toggles automatic description of features under the cursor cursor positioning ignores uninteresting dungeon features +allow reading many more items +when you're hiding under something a zap downward should not hit that + something, while a zap upward should +show more explicit reason why player was helpless at death +added new hallucinatory-only gods +options to create the character blind or nudist +moving clouds on the plane of air Platform- and/or Interface-Specific New Features @@ -1110,6 +1132,7 @@ smartphone: added "Type Cmd" command that allows to type arbitrary commands smartphone: added Q(quiver) command to "Attack" layout smartphone: fixed F command to prompt for direction unix,vms: altmeta option to handle terminals which send "ESC c" for Alt+c +tty,win32gui,win32tty: add menucolors NetHack Community Patches (or Variation) Included @@ -1127,6 +1150,7 @@ adopt/adapt/improve the Paranoid_Quit patch; default is paranoid_confirm:pray paranoid_confirm:Remove always pick from inventory for 'R' and 'T' adopt/adapt/improve Dungeon Overview Aardvark Joe's Extended Logfile +Michael Deutschmann's use_darkgray Code Cleanup and Reorganization diff --git a/include/.gitignore b/include/.gitignore index b9bd5d8ab..cb5a92532 100644 --- a/include/.gitignore +++ b/include/.gitignore @@ -5,3 +5,4 @@ pm.h vis_tab.h dgn_comp.h lev_comp.h +tile.h diff --git a/include/color.h b/include/color.h index ab6fe0462..f7bec4a08 100644 --- a/include/color.h +++ b/include/color.h @@ -7,6 +7,10 @@ #ifndef COLOR_H #define COLOR_H +#ifdef MENU_COLOR_REGEX +#include +#endif + /* * The color scheme used is tailored for an IBM PC. It consists of the * standard 8 colors, folowed by their bright counterparts. There are @@ -51,4 +55,18 @@ #define DRAGON_SILVER CLR_BRIGHT_CYAN #define HI_ZAP CLR_BRIGHT_BLUE +struct menucoloring { +# ifdef MENU_COLOR_REGEX +# ifdef MENU_COLOR_REGEX_POSIX + regex_t match; +# else + struct re_pattern_buffer match; +# endif +# else + char *match; +# endif + int color, attr; + struct menucoloring *next; +}; + #endif /* COLOR_H */ diff --git a/include/config.h b/include/config.h index d8c96af14..c5e53abf6 100644 --- a/include/config.h +++ b/include/config.h @@ -437,6 +437,14 @@ typedef unsigned char uchar; * bugs left here. */ +/* Menucolors */ +# define MENU_COLOR_REGEX /* use GNU regex */ +/*# define MENU_COLOR_REGEX_POSIX*/ /* use POSIX regex */ +/* if neither is defined, uses pmatch() + * pmatch() provides basic globbing: '*' and '?' wildcards. + */ + + #define STATUS_VIA_WINDOWPORT /* re-work of the status line updating process */ #define STATUS_HILITES /* support hilites of status fields */ /* #define WINCHAIN*/ /* stacked window systems */ diff --git a/include/context.h b/include/context.h index fad18f827..d25af4371 100644 --- a/include/context.h +++ b/include/context.h @@ -73,6 +73,11 @@ struct warntype_info { short speciesidx; /* index of above in mons[] (for save/restore) */ }; +struct polearm_info { + struct monst *hitmon; /* the monster we tried to hit last */ + unsigned m_id; /* monster id of hitmon, in save file */ +}; + struct tribute_info { size_t tributesz; /* make it possible to skip this in future */ boolean enabled; /* Do we have tributes turned on? */ @@ -111,7 +116,11 @@ struct context_info { struct book_info spbook; struct takeoff_info takeoff; struct warntype_info warntype; +<<<<<<< HEAD struct tribute_info tribute; +======= + struct polearm_info polearm; +>>>>>>> master }; extern NEARDATA struct context_info context; diff --git a/include/decl.h b/include/decl.h index 15191842e..417ca9d62 100644 --- a/include/decl.h +++ b/include/decl.h @@ -28,6 +28,7 @@ E char SAVEP[]; E NEARDATA int bases[MAXOCLASSES]; E NEARDATA int multi; +E const char *multi_reason; E NEARDATA int nroom; E NEARDATA int nsubroom; E NEARDATA int occtime; diff --git a/include/extern.h b/include/extern.h index 95f5844f6..fd44496a1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -276,7 +276,7 @@ E int FDECL(use_pick_axe2, (struct obj *)); E boolean FDECL(mdig_tunnel, (struct monst *)); E void FDECL(watch_dig, (struct monst *,XCHAR_P,XCHAR_P,BOOLEAN_P)); E void NDECL(zap_dig); -E struct obj *FDECL(bury_an_obj, (struct obj *)); +E struct obj *FDECL(bury_an_obj, (struct obj *, boolean *)); E void FDECL(bury_objs, (int,int)); E void FDECL(unearth_objs, (int,int)); E void FDECL(rot_organic, (ANY_P *, long)); @@ -364,6 +364,7 @@ E void NDECL(heal_legs); /* ### do_name.c ### */ E int FDECL(getpos, (coord *,BOOLEAN_P,const char *)); +E void FDECL(getpos_sethilite, (void (*f)(int) )); E void FDECL(new_mname, (struct monst *,int)); E void FDECL(free_mname, (struct monst *)); E void FDECL(new_oname, (struct obj *,int)); @@ -829,6 +830,7 @@ E char *FDECL(sitoa, (int)); E int FDECL(sgn, (int)); E int FDECL(rounddiv, (long,int)); E int FDECL(dist2, (int,int,int,int)); +E int FDECL(isqrt, (int)); E int FDECL(distmin, (int,int,int,int)); E boolean FDECL(online2, (int,int,int,int)); E boolean FDECL(pmatch, (const char *,const char *)); @@ -913,7 +915,7 @@ E int NDECL(dopramulet); E int NDECL(doprtool); E int NDECL(doprinuse); E void FDECL(useupf, (struct obj *,long)); -E char *FDECL(let_to_name, (CHAR_P,BOOLEAN_P)); +E char *FDECL(let_to_name, (CHAR_P,BOOLEAN_P,BOOLEAN_P)); E void NDECL(free_invbuf); E void NDECL(reassign); E int NDECL(doorganize); @@ -1139,6 +1141,7 @@ E void FDECL(dodoor, (int,int,struct mkroom *)); E void FDECL(mktrap, (int,int,struct mkroom *,coord*)); E void FDECL(mkstairs, (XCHAR_P,XCHAR_P,CHAR_P,struct mkroom *)); E void NDECL(mkinvokearea); +E void FDECL(mineralize, (int, int, int, int, BOOLEAN_P)); /* ### mkmap.c ### */ @@ -1148,7 +1151,7 @@ void FDECL(remove_rooms, (int,int,int,int)); /* ### mkmaze.c ### */ E void FDECL(wallification, (int,int,int,int)); -E void FDECL(walkfrom, (int,int)); +E void FDECL(walkfrom, (int,int,SCHAR_P)); E void FDECL(makemaz, (const char *)); E void FDECL(mazexy, (coord *)); E void NDECL(bound_digging); @@ -1582,6 +1585,9 @@ E void FDECL(parsesymbols, (char *)); E struct symparse *FDECL(match_sym, (char *)); E void NDECL(set_playmode); E int FDECL(sym_val, (char *)); +E boolean FDECL(add_menu_coloring, (char *)); +E boolean FDECL(get_menu_coloring, (char *, int *, int *)); +E void NDECL(free_menu_coloring); /* ### pager.c ### */ @@ -1826,6 +1832,7 @@ E long NDECL(random); /* ### read.c ### */ E void FDECL(learnscroll, (struct obj *)); +E char *FDECL(tshirt_text, (struct obj *, char *)); E int NDECL(doread); E boolean FDECL(is_chargeable, (struct obj *)); E void FDECL(recharge, (struct obj *,int)); @@ -2629,7 +2636,7 @@ E boolean FDECL(obj_resists, (struct obj *,int,int)); E boolean FDECL(obj_shudders, (struct obj *)); E void FDECL(do_osshock, (struct obj *)); E int FDECL(bhito, (struct obj *,struct obj *)); -E int FDECL(bhitpile, (struct obj *,int (*)(OBJ_P,OBJ_P),int,int)); +E int FDECL(bhitpile, (struct obj *,int (*)(OBJ_P,OBJ_P),int,int,SCHAR_P)); E int FDECL(zappable, (struct obj *)); E void FDECL(zapnodir, (struct obj *)); E int NDECL(dozap); diff --git a/include/flag.h b/include/flag.h index aaff7431c..072fb4a30 100644 --- a/include/flag.h +++ b/include/flag.h @@ -189,7 +189,9 @@ struct instance_flags { boolean deferred_X; /* deferred entry into explore mode */ boolean num_pad; /* use numbers for movement commands */ boolean news; /* print news */ + boolean mention_walls; /* give feedback when bumping walls */ boolean menu_tab_sep; /* Use tabs to separate option menu fields */ + boolean menu_head_objsym; /* Show obj symbol in menu headings */ boolean menu_requested; /* Flag for overloaded use of 'm' prefix * on some non-move commands */ boolean renameallowed; /* can change hero name during role selection */ @@ -199,6 +201,7 @@ struct instance_flags { boolean rlecomp; /* run-length comp of levels when writing savefile */ uchar num_pad_mode; boolean echo; /* 1 to echo characters */ + boolean use_menu_color; /* use color in menus; only if wc_color */ #if 0 boolean DECgraphics; /* use DEC VT-xxx extended character set */ boolean IBMgraphics; /* use IBM extended character set */ @@ -293,6 +296,7 @@ struct instance_flags { boolean wc2_softkeyboard; /* use software keyboard */ boolean wc2_wraptext; /* wrap text */ boolean wc2_selectsaved; /* display a menu of user's saved games */ + boolean wc2_darkgray; /* try to use dark-gray color for black glyphs */ boolean cmdassist; /* provide detailed assistance for some commands */ boolean clicklook; /* allow right-clicking for look */ boolean obsolete; /* obsolete options can point at this, it isn't used */ diff --git a/include/mkroom.h b/include/mkroom.h index e9952ddfa..45f49305f 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -13,6 +13,8 @@ struct mkroom { schar rtype; /* type of room (zoo, throne, etc...) */ schar orig_rtype; /* same as rtype, but not zeroed later */ schar rlit; /* is the room lit ? */ + schar needfill; /* sp_lev: does the room need filling? */ + schar needjoining; /* sp_lev */ schar doorct; /* door count */ schar fdoor; /* index for the first door of the room */ schar nsubrooms; /* number of subrooms */ diff --git a/include/ntconf.h b/include/ntconf.h index b51459151..3a02905e5 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -127,8 +127,15 @@ extern void FDECL(interject, (int)); #define strncmpi(a,b,c) strnicmp(a,b,c) #endif +/* Visual Studio defines this in their own headers, which we don't use */ +#ifndef snprintf +#define snprintf _snprintf +#pragma warning(disable:4996) /* deprecation warning suggesting snprintf_s */ +#endif + #include #include +#include #ifdef __BORLANDC__ #undef randomize #undef random diff --git a/include/obj.h b/include/obj.h index dea1c9d5e..39f163632 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.5 obj.h $NHDT-Date: 1426949157 2015/03/21 14:45:57 $ $NHDT-Branch: master $:$NHDT-Revision: 1.36 $ */ +/* NetHack 3.5 obj.h $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* NetHack 3.5 obj.h $Date: 2012/01/10 17:47:16 $ $Revision: 1.31 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -304,6 +304,17 @@ struct obj { || (otmp)->otyp == WAX_CANDLE\ || (otmp)->otyp == POT_OIL) +/* things that can be read */ +#define is_readable(otmp) ((otmp)->otyp == FORTUNE_COOKIE\ + || (otmp)->otyp == T_SHIRT\ + || (otmp)->otyp == ALCHEMY_SMOCK\ + || (otmp)->otyp == CREDIT_CARD\ + || (otmp)->otyp == CAN_OF_GREASE\ + || (otmp)->otyp == MAGIC_MARKER\ + || (otmp)->oclass == COIN_CLASS\ + || (otmp)->oartifact == ART_ORB_OF_FATE\ + || (otmp)->otyp == CANDY_BAR) + /* special stones */ #define is_graystone(obj) ((obj)->otyp == LUCKSTONE || \ (obj)->otyp == LOADSTONE || \ diff --git a/include/patchlevel.h b/include/patchlevel.h index eab90e89f..76d514afa 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -1,4 +1,4 @@ -/* NetHack 3.5 patchlevel.h $NHDT-Date: 1426948844 2015/03/21 14:40:44 $ $NHDT-Branch: master $:$NHDT-Revision: 1.95 $ */ +/* NetHack 3.5 patchlevel.h $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* NetHack 3.5 patchlevel.h $Date: 2012/04/14 08:31:03 $ $Revision: 1.93 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -14,7 +14,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 58 +#define EDITLEVEL 60 #define COPYRIGHT_BANNER_A \ "NetHack, Copyright 1985-2015" diff --git a/include/rm.h b/include/rm.h index c007f6a4f..00f0bc4c5 100644 --- a/include/rm.h +++ b/include/rm.h @@ -291,6 +291,7 @@ extern struct symsetentry symset[NUM_GRAPHICS]; /* from drawing.c */ #define D_CLOSED 4 #define D_LOCKED 8 #define D_TRAPPED 16 +#define D_SECRET 32 /* only used by sp_lev.c, NOT in rm-struct */ /* * Some altars are considered as shrines, so we need a flag. @@ -393,6 +394,19 @@ struct rm { Bitfield(candig,1); /* Exception to Can_dig_down; was a trapdoor */ }; + +#define SET_TYPLIT(x,y,ttyp,llit) \ +{ \ + if ((x) >= 0 && (y) >= 0 && (x) < COLNO && (y) < ROWNO) { \ + if ((ttyp) < MAX_TYPE) levl[(x)][(y)].typ = (ttyp); \ + if ((ttyp) == LAVAPOOL) levl[(x)][(y)].lit = 1; \ + else if ((schar)(llit) != -2) { \ + if ((schar)(llit) == -1) levl[(x)][(y)].lit = rn2(2); \ + else levl[(x)][(y)].lit = (llit); \ + } \ + } \ +} + /* * Add wall angle viewing by defining "modes" for each wall type. Each * mode describes which parts of a wall are finished (seen as as wall) diff --git a/include/sp_lev.h b/include/sp_lev.h index 0a1d22173..3d4d961c6 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -19,92 +19,378 @@ #define MAP_Y_LIM 21 /* Per level flags */ -#define NOTELEPORT 1 -#define HARDFLOOR 2 -#define NOMMAP 4 -#define SHORTSIGHTED 8 -#define ARBOREAL 16 +#define NOTELEPORT 0x00000001L +#define HARDFLOOR 0x00000002L +#define NOMMAP 0x00000004L +#define SHORTSIGHTED 0x00000008L +#define ARBOREAL 0x00000010L +#define MAZELEVEL 0x00000020L +#define PREMAPPED 0x00000040L /* premapped level & sokoban rules */ +#define SHROUD 0x00000080L +#define GRAVEYARD 0x00000100L +#define ICEDPOOLS 0x00000200L /* for ice locations: ICED_POOL vs ICED_MOAT */ +#define SOLIDIFY 0x00000400L /* outer areas are nondiggable & nonpasswall */ - /* special level types */ -#define SP_LEV_ROOMS 1 -#define SP_LEV_MAZE 2 +/* different level layout initializers */ +#define LVLINIT_NONE 0 +#define LVLINIT_SOLIDFILL 1 +#define LVLINIT_MAZEGRID 2 +#define LVLINIT_MINES 3 +#define LVLINIT_ROGUE 4 + +/* max. layers of object containment */ +#define MAX_CONTAINMENT 10 + +/* max. # of random registers */ +#define MAX_REGISTERS 10 + +/* max. nested depth of subrooms */ +#define MAX_NESTED_ROOMS 5 + +/* max. # of opcodes per special level */ +#define SPCODER_MAX_RUNTIME 65536 + +/* Opcodes for creating the level + * If you change these, also change opcodestr[] in util/lev_main.c + */ +enum opcode_defs { + SPO_NULL = 0, + SPO_MESSAGE, + SPO_MONSTER, + SPO_OBJECT, + SPO_ENGRAVING, + SPO_ROOM, + SPO_SUBROOM, + SPO_DOOR, + SPO_STAIR, + SPO_LADDER, + SPO_ALTAR, + SPO_FOUNTAIN, + SPO_SINK, + SPO_POOL, + SPO_TRAP, + SPO_GOLD, + SPO_CORRIDOR, + SPO_LEVREGION, + SPO_DRAWBRIDGE, + SPO_MAZEWALK, + SPO_NON_DIGGABLE, + SPO_NON_PASSWALL, + SPO_WALLIFY, + SPO_MAP, + SPO_ROOM_DOOR, + SPO_REGION, + SPO_MINERALIZE, + SPO_CMP, + SPO_JMP, + SPO_JL, + SPO_JLE, + SPO_JG, + SPO_JGE, + SPO_JE, + SPO_JNE, + SPO_TERRAIN, + SPO_REPLACETERRAIN, + SPO_EXIT, + SPO_ENDROOM, + SPO_POP_CONTAINER, + SPO_PUSH, + SPO_POP, + SPO_RN2, + SPO_DEC, + SPO_INC, + SPO_MATH_ADD, + SPO_MATH_SUB, + SPO_MATH_MUL, + SPO_MATH_DIV, + SPO_MATH_MOD, + SPO_MATH_SIGN, + SPO_COPY, + SPO_END_MONINVENT, + SPO_GRAVE, + SPO_FRAME_PUSH, + SPO_FRAME_POP, + SPO_CALL, + SPO_RETURN, + SPO_INITLEVEL, + SPO_LEVEL_FLAGS, + SPO_VAR_INIT, /* variable_name data */ + SPO_SHUFFLE_ARRAY, + SPO_DICE, + + SPO_SEL_ADD, + SPO_SEL_POINT, + SPO_SEL_RECT, + SPO_SEL_FILLRECT, + SPO_SEL_LINE, + SPO_SEL_RNDLINE, + SPO_SEL_GROW, + SPO_SEL_FLOOD, + SPO_SEL_RNDCOORD, + SPO_SEL_ELLIPSE, + SPO_SEL_FILTER, + SPO_SEL_GRADIENT, + SPO_SEL_COMPLEMENT, + + MAX_SP_OPCODES +}; + +/* MONSTER and OBJECT can take a variable number of parameters, + * they also pop different # of values from the stack. So, + * first we pop a value that tells what the _next_ value will + * mean. + */ +/* MONSTER */ +#define SP_M_V_PEACEFUL 0 +#define SP_M_V_ALIGN 1 +#define SP_M_V_ASLEEP 2 +#define SP_M_V_APPEAR 3 +#define SP_M_V_NAME 4 + +#define SP_M_V_FEMALE 5 +#define SP_M_V_INVIS 6 +#define SP_M_V_CANCELLED 7 +#define SP_M_V_REVIVED 8 +#define SP_M_V_AVENGE 9 +#define SP_M_V_FLEEING 10 +#define SP_M_V_BLINDED 11 +#define SP_M_V_PARALYZED 12 +#define SP_M_V_STUNNED 13 +#define SP_M_V_CONFUSED 14 +#define SP_M_V_SEENTRAPS 15 + +#define SP_M_V_END 16 /* end of variable parameters */ + +/* OBJECT */ +#define SP_O_V_SPE 0 +#define SP_O_V_CURSE 1 +#define SP_O_V_CORPSENM 2 +#define SP_O_V_NAME 3 +#define SP_O_V_QUAN 4 +#define SP_O_V_BURIED 5 +#define SP_O_V_LIT 6 +#define SP_O_V_ERODED 7 +#define SP_O_V_LOCKED 8 +#define SP_O_V_TRAPPED 9 +#define SP_O_V_RECHARGED 10 +#define SP_O_V_INVIS 11 +#define SP_O_V_GREASED 12 +#define SP_O_V_BROKEN 13 +#define SP_O_V_COORD 14 +#define SP_O_V_END 15 /* end of variable parameters */ + + +/* When creating objects, we need to know whether + * it's a container and/or contents. + */ +#define SP_OBJ_CONTENT 0x1 +#define SP_OBJ_CONTAINER 0x2 + + +/* SPO_FILTER types */ +#define SPOFILTER_PERCENT 0 +#define SPOFILTER_SELECTION 1 +#define SPOFILTER_MAPCHAR 2 + +/* gradient filter types */ +#define SEL_GRADIENT_RADIAL 0 +#define SEL_GRADIENT_SQUARE 1 + +/* variable types */ +#define SPOVAR_NULL 0x00 +#define SPOVAR_INT 0x01 /* l */ +#define SPOVAR_STRING 0x02 /* str */ +#define SPOVAR_VARIABLE 0x03 /* str (contains the variable name) */ +#define SPOVAR_COORD 0x04 /* coordinate, encoded in l; use SP_COORD_X() and SP_COORD_Y() */ +#define SPOVAR_REGION 0x05 /* region, encoded in l; use SP_REGION_X1() etc */ +#define SPOVAR_MAPCHAR 0x06 /* map char, in l */ +#define SPOVAR_MONST 0x07 /* monster class & specific monster, encoded in l; use SP_MONST_... */ +#define SPOVAR_OBJ 0x08 /* object class & specific object type, encoded in l; use SP_OBJ_... */ +#define SPOVAR_SEL 0x09 /* selection. char[COLNO][ROWNO] in str */ +#define SPOVAR_ARRAY 0x40 /* used in splev_var & lc_vardefs, not in opvar */ + +#define SP_COORD_IS_RANDOM 0x01000000 +/* Humidity flags for get_location() and friends, used with SP_COORD_PACK_RANDOM() */ +#define DRY 0x1 +#define WET 0x2 +#define HOT 0x4 +#define SOLID 0x8 +#define ANY_LOC 0x10 /* even outside the level */ +#define NO_LOC_WARN 0x20 /* no complaints and set x & y to -1, if no loc */ + +#define SP_COORD_X(l) (l & 0xff) +#define SP_COORD_Y(l) ((l >> 16) & 0xff) +#define SP_COORD_PACK(x,y) ((( x ) & 0xff) + ((( y ) & 0xff) << 16)) +#define SP_COORD_PACK_RANDOM(f) (SP_COORD_IS_RANDOM | (f)) + +#define SP_REGION_X1(l) (l & 0xff) +#define SP_REGION_Y1(l) ((l >> 8) & 0xff) +#define SP_REGION_X2(l) ((l >> 16) & 0xff) +#define SP_REGION_Y2(l) ((l >> 24) & 0xff) +#define SP_REGION_PACK(x1,y1,x2,y2) ((( x1 ) & 0xff) + ((( y1 ) & 0xff) << 8) + ((( x2 ) & 0xff) << 16) + ((( y2 ) & 0xff) << 24)) + +#define SP_MONST_CLASS(l) (l & 0xff) +#define SP_MONST_PM(l) ((l >> 8) & 0xffff) +#define SP_MONST_PACK(m,c) ((( m ) << 8) + ((char)( c ))) + +#define SP_OBJ_CLASS(l) (l & 0xff) +#define SP_OBJ_TYP(l) ((l >> 8) & 0xffff) +#define SP_OBJ_PACK(o,c) ((( o ) << 8) + ((char)( c ))) + +#define SP_MAPCHAR_TYP(l) (l & 0xff) +#define SP_MAPCHAR_LIT(l) ((l >> 8) & 0xff) +#define SP_MAPCHAR_PACK(typ,lit) ((( lit ) << 8) + ((char)( typ ))) + + +struct opvar { + xchar spovartyp; /* one of SPOVAR_foo */ + union { + char *str; + long l; + } vardata; +}; + +struct splev_var { + struct splev_var *next; + char *name; + xchar svtyp; /* SPOVAR_foo */ + union { + struct opvar *value; + struct opvar **arrayvalues; + } data; + long array_len; +}; + +struct splevstack { + long depth; + long depth_alloc; + struct opvar **stackdata; +}; + + +struct sp_frame { + struct sp_frame *next; + struct splevstack *stack; + struct splev_var *variables; + long n_opcode; +}; + + +struct sp_coder { + struct splevstack *stack; + struct sp_frame *frame; + int premapped; + boolean solidify; + struct mkroom *croom; + struct mkroom *tmproomlist[MAX_NESTED_ROOMS+1]; + boolean failed_room[MAX_NESTED_ROOMS+1]; + int n_subroom; + boolean exit_script; + int lvl_is_joined; + + int opcode; /* current opcode */ + struct opvar *opdat; /* current push data (req. opcode == SPO_PUSH) */ +}; + +/* special level coder CPU flags */ +#define SP_CPUFLAG_LT 1 +#define SP_CPUFLAG_GT 2 +#define SP_CPUFLAG_EQ 4 +#define SP_CPUFLAG_ZERO 8 /* * Structures manipulated by the special levels loader & compiler */ +#define packed_coord long +typedef struct { + xchar is_random; + long getloc_flags; + int x, y; +} unpacked_coord; + +typedef struct { + int cmp_what; + int cmp_val; +} opcmp; + +typedef struct { + long jmp_target; +} opjmp; + + typedef union str_or_len { char *str; int len; } Str_or_Len; typedef struct { + xchar init_style; /* one of LVLINIT_foo */ + long flags; + schar filling; boolean init_present, padding; char fg, bg; boolean smoothed, joined; xchar lit, walled; - boolean icedpools; /* for ice locations: ICED_POOL vs ICED_MOAT */ + boolean icedpools; } lev_init; -typedef struct { - xchar x, y, mask; -} door; - typedef struct { xchar wall, pos, secret, mask; } room_door; typedef struct { - xchar x, y, chance, type; + packed_coord coord; + xchar x, y, type; } trap; typedef struct { Str_or_Len name, appear_as; short id; aligntyp align; - xchar x, y, chance, class, appear; + packed_coord coord; + xchar x, y, class, appear; schar peaceful, asleep; + short female, invis, cancelled, revived, avenge, fleeing, blinded, paralyzed, stunned, confused; + long seentraps; + short has_invent; } monster; typedef struct { Str_or_Len name; int corpsenm; short id, spe; - xchar x, y, chance, class, containment; + packed_coord coord; + xchar x, y, class, containment; schar curse_state; + int quan; + short buried; + short lit; + short eroded, locked, trapped, recharged, invis, greased, broken; } object; typedef struct { + packed_coord coord; xchar x, y; aligntyp align; xchar shrine; } altar; -typedef struct { - xchar x, y, dir, db_open; -} drawbridge; - -typedef struct { - xchar x, y, dir; -} walk; - -typedef struct { - xchar x1, y1, x2, y2; -} digpos; - -typedef struct { - xchar x, y, up; -} lad; - -typedef struct { - xchar x, y, up; -} stair; - typedef struct { xchar x1, y1, x2, y2; xchar rtype, rlit, rirreg; } region; +typedef struct { + xchar ter, tlit; +} terrain; + +typedef struct { + xchar chance; + xchar x1,y1,x2,y2; + xchar fromter, toter, tolit; +} replaceterrain; + /* values for rtype are defined in dungeon.h */ typedef struct { struct { xchar x1, y1, x2, y2; } inarea; @@ -114,116 +400,6 @@ typedef struct { Str_or_Len rname; } lev_region; -typedef struct { - xchar x, y; - int amount; -} gold; - -typedef struct { - xchar x, y; - Str_or_Len engr; - xchar etype; -} engraving; - -typedef struct { - xchar x, y; -} fountain; - -typedef struct { - xchar x, y; -} sink; - -typedef struct { - xchar x, y; -} pool; - -typedef struct { - char halign, valign; - char xsize, ysize; - char **map; - char nrobjects; - char *robjects; - char nloc; - char *rloc_x; - char *rloc_y; - char nrmonst; - char *rmonst; - char nreg; - region **regions; - char nlreg; - lev_region **lregions; - char ndoor; - door **doors; - char ntrap; - trap **traps; - char nmonster; - monster **monsters; - char nobject; - object **objects; - char ndrawbridge; - drawbridge **drawbridges; - char nwalk; - walk **walks; - char ndig; - digpos **digs; - char npass; - digpos **passs; - char nlad; - lad **lads; - char nstair; - stair **stairs; - char naltar; - altar **altars; - char ngold; - gold **golds; - char nengraving; - engraving **engravings; - char nfountain; - fountain **fountains; -} mazepart; - -typedef struct { - long flags; - lev_init init_lev; - schar filling; - char numpart; - mazepart **parts; -} specialmaze; - -typedef struct _room { - char *name; - char *parent; - xchar x, y, w, h; - xchar xalign, yalign; - xchar rtype, chance, rlit, filled; - char ndoor; - room_door **doors; - char ntrap; - trap **traps; - char nmonster; - monster **monsters; - char nobject; - object **objects; - char naltar; - altar **altars; - char nstair; - stair **stairs; - char ngold; - gold **golds; - char nengraving; - engraving **engravings; - char nfountain; - fountain **fountains; - char nsink; - sink **sinks; - char npool; - pool **pools; - /* These three fields are only used when loading the level... */ - int nsubroom; - struct _room *subrooms[MAX_SUBROOMS]; - struct mkroom *mkr; -} room; - typedef struct { struct { xchar room; @@ -232,18 +408,66 @@ typedef struct { } src, dest; } corridor; -/* used only by lev_comp */ +typedef struct _room { + Str_or_Len name; + Str_or_Len parent; + xchar x, y, w, h; + xchar xalign, yalign; + xchar rtype, chance, rlit, filled, joined; +} room; + typedef struct { - long flags; - lev_init init_lev; - char nrobjects; - char *robjects; - char nrmonst; - char *rmonst; - xchar nroom; - room **rooms; - xchar ncorr; - corridor **corrs; -} splev; + schar zaligntyp; + schar keep_region; + schar halign, valign; + char xsize, ysize; + char **map; +} mazepart; + +typedef struct { + int opcode; + struct opvar *opdat; +} _opcode; + +typedef struct { + _opcode *opcodes; + long n_opcodes; +} sp_lev; + +typedef struct { + xchar x, y, direction, count, lit; + char typ; +} spill; + + +/* only used by lev_comp */ +struct lc_funcdefs_parm { + char *name; + char parmtype; + struct lc_funcdefs_parm *next; +}; + +struct lc_funcdefs { + struct lc_funcdefs *next; + char *name; + long addr; + sp_lev code; + long n_called; + struct lc_funcdefs_parm *params; + long n_params; +}; + +struct lc_vardefs { + struct lc_vardefs *next; + char *name; + long var_type; /* SPOVAR_foo */ + long n_used; +}; + +struct lc_breakdef { + struct lc_breakdef *next; + struct opvar *breakpoint; + int break_depth; +}; #endif /* SP_LEV_H */ diff --git a/include/sys.h b/include/sys.h index b97f7ca80..84d42b5b6 100644 --- a/include/sys.h +++ b/include/sys.h @@ -10,6 +10,7 @@ struct sysopt { char *support; /* local support contact */ char *recover; /* how to run recover - may be overridden by win port */ char *wizards; + char *explorers; char *shellers; /* like wizards, for ! command (-DSHELL) */ char *debugfiles; /* files to show debugplines in. '*' is all. */ int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES") diff --git a/include/winprocs.h b/include/winprocs.h index 72dad2315..398ba9cba 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -219,7 +219,8 @@ NEARDATA struct window_procs windowprocs; #define WC2_WRAPTEXT 0x04L /* 03 wrap long lines of text */ #define WC2_HILITE_STATUS 0x08L /* 04 hilite fields in status */ #define WC2_SELECTSAVED 0x10L /* 05 saved game selection menu */ - /* 27 free bits */ +#define WC2_DARKGRAY 0x20L /* 06 use bold black for black glyphs */ + /* 26 free bits */ #define ALIGN_LEFT 1 #define ALIGN_RIGHT 2 diff --git a/include/you.h b/include/you.h index 0fc5c6073..11ba9079e 100644 --- a/include/you.h +++ b/include/you.h @@ -92,6 +92,12 @@ struct u_conduct { /* number of times... */ /* genocides already listed at end of game */ }; +struct u_roleplay { + boolean blind; /* permanently blind */ + boolean nudist; /* has not worn any armor, ever */ + long numbones; /* # of bones files loaded */ +}; + /*** Unified structure containing role information ***/ struct Role { /*** Strings that name various things ***/ @@ -330,6 +336,7 @@ struct you { struct u_event uevent; /* certain events have happened */ struct u_have uhave; /* you're carrying special objects */ struct u_conduct uconduct; /* KMH, conduct */ + struct u_roleplay uroleplay; struct attribs acurr, /* your current attributes (eg. str)*/ aexe, /* for gain/loss via "exercise" */ abon, /* your bonus attributes (eg. str) */ diff --git a/include/youprop.h b/include/youprop.h index 1dfe3a9e9..cdecb6c82 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -91,7 +91,7 @@ #define Blinded u.uprops[BLINDED].intrinsic #define Blindfolded (ublindf && ublindf->otyp != LENSES) /* ...means blind because of a cover */ -#define Blind ((Blinded || Blindfolded || !haseyes(youmonst.data)) && \ +#define Blind ((u.uroleplay.blind || Blinded || Blindfolded || !haseyes(youmonst.data)) && \ !(ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD)) /* ...the Eyes operate even when you really are blind or don't have any eyes */ diff --git a/src/allmain.c b/src/allmain.c index 4d0574260..5eb1c1de3 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -292,7 +292,7 @@ boolean resuming; } restore_attrib(); /* underwater and waterlevel vision are done here */ - if (Is_waterlevel(&u.uz)) + if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) movebubbles(); else if (Underwater) under_water(0); diff --git a/src/apply.c b/src/apply.c index fd3193fb3..65482c337 100644 --- a/src/apply.c +++ b/src/apply.c @@ -20,6 +20,7 @@ STATIC_DCL void FDECL(use_candelabrum, (struct obj *)); STATIC_DCL void FDECL(use_candle, (struct obj **)); STATIC_DCL void FDECL(use_lamp, (struct obj *)); STATIC_DCL void FDECL(light_cocktail, (struct obj *)); +STATIC_PTR void FDECL(display_jump_positions, (int)); STATIC_DCL void FDECL(use_tinning_kit, (struct obj *)); STATIC_DCL void FDECL(use_figurine, (struct obj **)); STATIC_DCL void FDECL(use_grease, (struct obj *)); @@ -27,6 +28,7 @@ STATIC_DCL void FDECL(use_trap, (struct obj *)); STATIC_DCL void FDECL(use_stone, (struct obj *)); STATIC_PTR int NDECL(set_trap); /* occupation callback */ STATIC_DCL int FDECL(use_whip, (struct obj *)); +STATIC_PTR void FDECL(display_polearm_positions, (int)); STATIC_DCL int FDECL(use_pole, (struct obj *)); STATIC_DCL int FDECL(use_cream_pie, (struct obj *)); STATIC_DCL int FDECL(use_grapple, (struct obj *)); @@ -736,8 +738,10 @@ struct obj *obj; pline("Yow! The %s stares back!", mirror); else pline("Yikes! You've frozen yourself!"); - if (!Hallucination || !rn2(4)) + if (!Hallucination || !rn2(4)) { nomul(-rnd(MAXULEV + 6 - u.ulevel)); + multi_reason = "gazing into a mirror"; + } nomovemsg = 0; /* default, "you can move again" */ } } else if (youmonst.data->mlet == S_VAMPIRE) @@ -915,6 +919,7 @@ struct obj **optr; break; case 2: /* no explanation; it just happens... */ nomovemsg = ""; + multi_reason = NULL; nomul(-rnd(2)); break; } @@ -1357,6 +1362,53 @@ dojump() return jump(0); } +boolean +is_valid_jump_pos(x,y, magic, showmsg) +int x,y, magic; +boolean showmsg; +{ + if (!magic && !(HJumping & ~INTRINSIC) && !EJumping && + distu(x, y) != 5) { + /* The Knight jumping restriction still applies when riding a + * horse. After all, what shape is the knight piece in chess? + */ + if (showmsg) pline("Illegal move!"); + return FALSE; + } else if (distu(x, y) > (magic ? 6+magic*3 : 9)) { + if (showmsg) pline("Too far!"); + return FALSE; + } else if (!cansee(x, y)) { + if (showmsg) You("cannot see where to land!"); + return FALSE; + } else if (!isok(x, y)) { + if (showmsg) You("cannot jump there!"); + return FALSE; + } + return TRUE; +} + +int jumping_is_magic; + +void +display_jump_positions(state) +int state; +{ + if (state == 0) { + tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam)); + } else if (state == 1) { + int x,y, dx, dy; + for (dx = -4; dx <= 4; dx++) + for (dy = -4; dy <= 4; dy++) { + x = dx + (int)u.ux; + y = dy + (int)u.uy; + if (isok(x,y) && is_valid_jump_pos(x,y, jumping_is_magic, FALSE)) + tmp_at(x,y); + } + } else { + tmp_at(DISP_END, 0); + } +} + int jump(magic) int magic; /* 0=Physical, otherwise skill level */ @@ -1436,24 +1488,12 @@ int magic; /* 0=Physical, otherwise skill level */ pline("Where do you want to jump?"); cc.x = u.ux; cc.y = u.uy; + jumping_is_magic = magic; + getpos_sethilite(display_jump_positions); if (getpos(&cc, TRUE, "the desired position") < 0) return 0; /* user pressed ESC */ - if (!magic && !(HJumping & ~INTRINSIC) && !EJumping && - distu(cc.x, cc.y) != 5) { - /* The Knight jumping restriction still applies when riding a - * horse. After all, what shape is the knight piece in chess? - */ - pline("Illegal move!"); - return 0; - } else if (distu(cc.x, cc.y) > (magic ? 6+magic*3 : 9)) { - pline("Too far!"); - return 0; - } else if (!cansee(cc.x, cc.y)) { - You("cannot see where to land!"); - return 0; - } else if (!isok(cc.x, cc.y)) { - You("cannot jump there!"); - return 0; + if (!is_valid_jump_pos(cc.x, cc.y, magic, TRUE)) { + return 0; } else { coord uc; int range, temp; @@ -1508,6 +1548,7 @@ int magic; /* 0=Physical, otherwise skill level */ teleds(cc.x, cc.y, TRUE); sokoban_guilt(); nomul(-1); + multi_reason = "jumping around"; nomovemsg = ""; morehungry(rnd(25)); return 1; @@ -2531,6 +2572,54 @@ static const char cant_see_spot[] = "won't hit anything if you can't see that spot.", cant_reach[] = "can't reach that spot from here."; +/* find pos of monster in range, if only one monster */ +boolean +find_poleable_mon(pos, min_range, max_range) +coord *pos; +int min_range, max_range; +{ + struct monst *mtmp; + struct monst *selmon = NULL; + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) + if (mtmp && !DEADMONSTER(mtmp) && !mtmp->mtame && + cansee(mtmp->mx, mtmp->my) && + distu(mtmp->mx, mtmp->my) <= max_range && + distu(mtmp->mx, mtmp->my) >= min_range) { + if (selmon) return FALSE; + selmon = mtmp; + } + if (!selmon) return FALSE; + pos->x = selmon->mx; + pos->y = selmon->my; + return TRUE; +} + +int polearm_range_min = -1; +int polearm_range_max = -1; + +void +display_polearm_positions(state) +int state; +{ + if (state == 0) { + tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam)); + } else if (state == 1) { + int x,y, dx,dy; + for (dx = -4; dx <= 4; dx++) + for (dy = -4; dy <= 4; dy++) { + x = dx + (int)u.ux; + y = dy + (int)u.uy; + if (isok(x, y) && + distu(x, y) >= polearm_range_min && + distu(x, y) <= polearm_range_max) { + tmp_at(x, y); + } + } + } else { + tmp_at(DISP_END, 0); + } +} + /* Distance attacks by pole-weapons */ STATIC_OVL int use_pole(obj) @@ -2539,6 +2628,7 @@ use_pole(obj) int res = 0, typ, max_range, min_range, glyph; coord cc; struct monst *mtmp; + struct monst *hitm = context.polearm.hitmon; /* Are you allowed to use the pole? */ if (u.uswallow) { @@ -2551,15 +2641,7 @@ use_pole(obj) } /* assert(obj == uwep); */ - /* Prompt for a location */ - pline(where_to_hit); - cc.x = u.ux; - cc.y = u.uy; - if (getpos(&cc, TRUE, "the spot to hit") < 0) - return res; /* ESC; uses turn iff polearm became wielded */ - - glyph = glyph_at(cc.x, cc.y); - /* + /* * Calculate allowable range (pole's reach is always 2 steps): * unskilled and basic: orthogonal direction, 4..4; * skilled: as basic, plus knight's jump position, 4..5; @@ -2579,6 +2661,26 @@ use_pole(obj) if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4; else if (P_SKILL(typ) == P_SKILLED) max_range = 5; else max_range = 8; /* (P_SKILL(typ) >= P_EXPERT) */ + + polearm_range_min = min_range; + polearm_range_max = max_range; + + /* Prompt for a location */ + pline(where_to_hit); + cc.x = u.ux; + cc.y = u.uy; + if (!find_poleable_mon(&cc, min_range, max_range) && + hitm && !DEADMONSTER(hitm) && cansee(hitm->mx, hitm->my) && + distu(hitm->mx,hitm->my) <= max_range && + distu(hitm->mx,hitm->my) >= min_range) { + cc.x = hitm->mx; + cc.y = hitm->my; + } + getpos_sethilite(display_polearm_positions); + if (getpos(&cc, TRUE, "the spot to hit") < 0) + return res; /* ESC; uses turn iff polearm became wielded */ + + glyph = glyph_at(cc.x, cc.y); if (distu(cc.x, cc.y) > max_range) { pline("Too far!"); return (res); @@ -2596,11 +2698,13 @@ use_pole(obj) return res; } + context.polearm.hitmon = NULL; /* Attack the monster there */ bhitpos = cc; if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *)0) { if (attack_checks(mtmp, uwep)) return res; if (overexertion()) return 1; /* burn nutrition; maybe pass out */ + context.polearm.hitmon = mtmp; check_caitiff(mtmp); notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my); (void) thitmonst(mtmp, uwep); @@ -2828,6 +2932,7 @@ do_break_wand(obj) boolean fillmsg = FALSE; int expltype = EXPL_MAGICAL; char confirm[QBUFSZ], buf[BUFSZ]; + boolean is_fragile = (!strcmp(OBJ_DESCR(objects[obj->otyp]), "balsa")); if (yn(safe_qbuf(confirm, "Are you really sure you want to break ", "?", obj, yname, ysimple_name, "the wand")) == 'n') @@ -2836,7 +2941,7 @@ do_break_wand(obj) if (nohands(youmonst.data)) { You_cant("break %s without hands!", yname(obj)); return 0; - } else if (ACURR(A_STR) < 10) { + } else if (ACURR(A_STR) < (is_fragile ? 5 : 10)) { You("don't have the strength to break %s!", yname(obj)); return 0; } @@ -2974,7 +3079,7 @@ do_break_wand(obj) /* if (context.botl) bot(); */ } if (affects_objects && level.objects[x][y]) { - (void) bhitpile(obj, bhito, x, y); + (void) bhitpile(obj, bhito, x, y, 0); if (context.botl) bot(); /* potion effects */ } } else { @@ -2991,7 +3096,7 @@ do_break_wand(obj) * since it's also used by retouch_equipment() for polyself.) */ if (affects_objects && level.objects[x][y]) { - (void) bhitpile(obj, bhito, x, y); + (void) bhitpile(obj, bhito, x, y, 0); if (context.botl) bot(); /* potion effects */ } damage = zapyourself(obj, FALSE); diff --git a/src/artifact.c b/src/artifact.c index c9baaf365..81bfd4cf0 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -983,6 +983,7 @@ char *hittee; /* target's name: "you" or mon_nam(mdef) */ resisted = TRUE; } else { nomul(-3); + multi_reason = "being scared stiff"; nomovemsg = ""; if (magr && magr == u.ustuck && sticks(youmonst.data)) { u.ustuck = (struct monst *)0; diff --git a/src/attrib.c b/src/attrib.c index b9ce67596..f7af4fee8 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -691,6 +691,8 @@ int propidx; /* special cases can have negative values */ Sprintf(buf, because_of, obj->oartifact ? bare_artifactname(obj) : ysimple_name(obj)); + else if (propidx == BLINDED && u.uroleplay.blind) + Sprintf(buf, " from birth"); else if (propidx == BLINDED && Blindfolded_only) Sprintf(buf, because_of, ysimple_name(ublindf)); diff --git a/src/bones.c b/src/bones.c index 9024354a2..f061316b4 100644 --- a/src/bones.c +++ b/src/bones.c @@ -597,6 +597,7 @@ getbones() } (void) close(fd); sanitize_engravings(); + u.uroleplay.numbones++; if(wizard) { if(yn("Unlink bones?") == 'n') { diff --git a/src/cmd.c b/src/cmd.c index 5d9bcfc27..3798a4fb0 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -509,6 +509,16 @@ enter_explore_mode(VOID_ARGS) } else if (discover) { You("are already in explore mode."); } else { +#ifdef SYSCF +# if defined(UNIX) + if (!sysopt.explorers || + !sysopt.explorers[0] || + !check_user_string(sysopt.explorers)) { + You("cannot access explore mode."); + return 0; + } +# endif +#endif pline( "Beware! From explore mode there will be no return to normal game."); if (paranoid_query(ParanoidQuit, @@ -997,11 +1007,8 @@ wiz_levltyp_legend(VOID_ARGS) STATIC_PTR int wiz_smell(VOID_ARGS) { - char out_str[BUFSZ]; - struct permonst *pm = 0; int ans = 0; int mndx; /* monster index */ - int found; /* count of matching mndxs found */ coord cc; /* screen pos of unknown glyph */ int glyph; /* glyph at selected position */ @@ -1015,11 +1022,6 @@ wiz_smell(VOID_ARGS) pline("You can move the cursor to a monster that you want to smell."); do { - /* Reset some variables. */ - pm = (struct permonst *)0; - found = 0; - out_str[0] = '\0'; - pline("Pick a monster to smell."); ans = getpos(&cc, TRUE, "a monster"); if (ans < 0 || cc.x < 0) { @@ -2246,6 +2248,9 @@ int final; en_win = create_nhwindow(NHW_MENU); putstr(en_win, 0, "Voluntary challenges:"); + if (u.uroleplay.blind) you_have_been("blind from birth"); + if (u.uroleplay.nudist) you_have_been("faithfully nudist"); + if (!u.uconduct.food) enl_msg(You_, "have gone", "went", " without food", ""); /* But beverages are okay */ diff --git a/src/decl.c b/src/decl.c index 75203c056..d9429dbcf 100644 --- a/src/decl.c +++ b/src/decl.c @@ -21,6 +21,7 @@ char *catmore = 0; /* default pager */ NEARDATA int bases[MAXOCLASSES] = DUMMY; NEARDATA int multi = 0; +const char *multi_reason = NULL; NEARDATA int nroom = 0; NEARDATA int nsubroom = 0; NEARDATA int occtime = 0; @@ -102,9 +103,9 @@ NEARDATA struct multishot m_shot = { 0, 0, STRANGE_OBJECT, FALSE }; NEARDATA dungeon dungeons[MAXDUNGEON]; /* ini'ed by init_dungeon() */ NEARDATA s_level *sp_levchn; -NEARDATA stairway upstair = { 0, 0 }, dnstair = { 0, 0 }; -NEARDATA stairway upladder = { 0, 0 }, dnladder = { 0, 0 }; -NEARDATA stairway sstairs = { 0, 0 }; +NEARDATA stairway upstair = { 0, 0, { 0,0 }, 0 }, dnstair = { 0, 0, { 0,0 }, 0 }; +NEARDATA stairway upladder = { 0, 0, { 0,0 }, 0 }, dnladder = { 0, 0, { 0,0 }, 0 }; +NEARDATA stairway sstairs = { 0, 0, { 0,0 }, 0 }; NEARDATA dest_area updest = { 0, 0, 0, 0, 0, 0, 0, 0 }; NEARDATA dest_area dndest = { 0, 0, 0, 0, 0, 0, 0, 0 }; NEARDATA coord inv_pos = { 0, 0 }; @@ -218,6 +219,8 @@ NEARDATA struct c_color_names c_color_names = { "white" }; +struct menucoloring *menu_colorings = NULL; + const char *c_obj_colors[] = { "black", /* CLR_BLACK */ "red", /* CLR_RED */ diff --git a/src/detect.c b/src/detect.c index ecc4d3878..2af53021e 100644 --- a/src/detect.c +++ b/src/detect.c @@ -890,6 +890,7 @@ struct obj *obj; } You("peer into %s...", the(xname(obj))); nomul(-rnd(10)); + multi_reason = "gazing into a crystal ball"; nomovemsg = ""; if (obj->spe <= 0) pline_The("vision is unclear."); diff --git a/src/dig.c b/src/dig.c index fa25f76a0..1d7d5dd7a 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1023,6 +1023,7 @@ struct obj *obj; /* you ought to be able to let go; tough luck */ /* (maybe `move_into_trap()' would be better) */ nomul(-d(2,2)); + multi_reason = "stuck in a spider web"; nomovemsg = "You pull free."; } else if (lev->typ == IRONBARS) { pline("Clang!"); @@ -1283,7 +1284,7 @@ zap_dig() struct monst *mtmp; struct obj *otmp; struct trap *trap_with_u = (struct trap *)0; - int zx, zy, diridx, digdepth, flow_x, flow_y; + int zx, zy, diridx = 8, digdepth, flow_x = -1, flow_y = -1; boolean shopdoor, shopwall, maze_dig, pitdig = FALSE, pitflow = FALSE; /* @@ -1461,7 +1462,7 @@ zap_dig() } /* while */ tmp_at(DISP_END,0); /* closing call */ - if (pitflow) { + if (pitflow && isok(flow_x, flow_y)) { struct trap *ttmp = t_at(flow_x, flow_y); if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)) { schar filltyp = fillholetyp(ttmp->tx, ttmp->ty, TRUE); @@ -1683,13 +1684,15 @@ buried_ball_to_freedom() /* move objects from fobj/nexthere lists to buriedobjlist, keeping position */ /* information */ struct obj * -bury_an_obj(otmp) +bury_an_obj(otmp, dealloced) struct obj *otmp; + boolean *dealloced; { struct obj *otmp2; boolean under_ice; debugpline1("bury_an_obj: %s", xname(otmp)); + if (dealloced) *dealloced = FALSE; if (otmp == uball) { unpunish(); u.utrap = rn1(50,20); @@ -1720,6 +1723,7 @@ bury_an_obj(otmp) under_ice = is_ice(otmp->ox, otmp->oy); if (otmp->otyp == ROCK && !under_ice) { /* merges into burying material */ + if (dealloced) *dealloced = TRUE; obfree(otmp, (struct obj *)0); return(otmp2); } @@ -1754,7 +1758,7 @@ int x, y; if(level.objects[x][y] != (struct obj *)0) debugpline2("bury_objs: at <%d,%d>", x, y); for (otmp = level.objects[x][y]; otmp; otmp = otmp2) - otmp2 = bury_an_obj(otmp); + otmp2 = bury_an_obj(otmp, NULL); /* don't expect any engravings here, but just in case */ del_engr_at(x, y); @@ -1814,7 +1818,7 @@ long timeout UNUSED; /* Everything which can be held in a container can also be buried, so bury_an_obj's use of obj_extract_self insures that Has_contents(obj) will eventually become false. */ - (void)bury_an_obj(obj->cobj); + (void)bury_an_obj(obj->cobj, NULL); } obj_extract_self(obj); obfree(obj, (struct obj *) 0); diff --git a/src/do.c b/src/do.c index b387752d6..eae360425 100644 --- a/src/do.c +++ b/src/do.c @@ -1286,7 +1286,7 @@ boolean at_stairs, falling, portal; } /* initial movement of bubbles just before vision_recalc */ - if (Is_waterlevel(&u.uz)) + if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) movebubbles(); if (level_info[new_ledger].flags & FORGOTTEN) { @@ -1402,6 +1402,7 @@ boolean at_stairs, falling, portal; /* assume this will always return TRUE when changing level */ (void) in_out_region(u.ux, u.uy); (void) pickup(1); + context.polearm.hitmon = NULL; } STATIC_OVL void diff --git a/src/do_name.c b/src/do_name.c index 6618b5802..54a1aeb8c 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -25,6 +25,17 @@ nextmbuf() return bufs[bufidx]; } +/* function for getpos() to highlight desired map locations. + * parameter value 0 = initialize, 1 = highlight, 2 = done + */ +void (*getpos_hilitefunc)(int) = NULL; +void +getpos_sethilite(f) +void (*f)(int); +{ + getpos_hilitefunc = f; +} + /* the response for '?' help request in getpos() */ STATIC_OVL void getpos_help(force, goal) @@ -41,6 +52,8 @@ const char *goal; putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time."); putstr(tmpwin, 0, "Or enter a background symbol (ex. <)."); putstr(tmpwin, 0, "Use @ to move the cursor on yourself."); + if (getpos_hilitefunc != NULL) + putstr(tmpwin, 0, "Use $ to display valid locations."); putstr(tmpwin, 0, "Use # to toggle automatic description."); /* disgusting hack; the alternate selection characters work for any getpos call, but they only matter for dowhatis (and doquickwhatis) */ @@ -69,6 +82,7 @@ const char *goal; boolean show_goal_msg = FALSE; static const char pick_chars[] = ".,;:"; const char *cp; + boolean hilite_state = FALSE; if (!goal) goal = "desired location"; if (flags.verbose) { @@ -92,7 +106,7 @@ const char *goal; curs(WIN_MAP, cx, cy); flush_screen(0); show_goal_msg = FALSE; - } else if (auto_msg && !msg_given) { + } else if (auto_msg && !msg_given && !hilite_state) { coord cc; int sym = 0; char tmpbuf[BUFSZ]; @@ -110,6 +124,13 @@ const char *goal; c = nh_poskey(&tx, &ty, &sidx); + if (hilite_state) { + (*getpos_hilitefunc)(2); + hilite_state = FALSE; + curs(WIN_MAP, cx, cy); + flush_screen(0); + } + if (auto_msg) msg_given = FALSE; @@ -174,6 +195,13 @@ const char *goal; /* update message window to reflect that we're still targetting */ show_goal_msg = TRUE; msg_given = TRUE; + } else if ((c == '$') && (getpos_hilitefunc != NULL)) { + if (!hilite_state) { + (*getpos_hilitefunc)(0); + (*getpos_hilitefunc)(1); + hilite_state = TRUE; + } + goto nxtc; } else if (c == '#') { auto_msg = !auto_msg; pline("Automatic description %sis %s.", @@ -269,6 +297,7 @@ const char *goal; if (msg_given) clear_nhwindow(WIN_MESSAGE); ccp->x = cx; ccp->y = cy; + getpos_hilitefunc = NULL; return result; } diff --git a/src/do_wear.c b/src/do_wear.c index 39d3b6c3f..ef04ee360 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1407,6 +1407,7 @@ register struct obj *otmp; if(cursed(otmp)) return(0); if(delay) { nomul(delay); + multi_reason = "disrobing"; if (is_helmet(otmp)) { /* ick... */ nomovemsg = !strcmp(helm_simple_name(otmp), "hat") ? @@ -1664,6 +1665,7 @@ dowear() delay = -objects[otmp->otyp].oc_delay; if(delay){ nomul(delay); + multi_reason = "dressing up"; if(is_boots(otmp)) afternmv = Boots_on; if(is_helmet(otmp)) afternmv = Helmet_on; if(is_gloves(otmp)) afternmv = Gloves_on; diff --git a/src/dog.c b/src/dog.c index d8ab09e4f..10e33677f 100644 --- a/src/dog.c +++ b/src/dog.c @@ -423,7 +423,7 @@ boolean with_you; * probably because the level is full. * Dump the monster's cargo and leave the monster dead. */ - struct obj *obj, *corpse; + struct obj *obj; while ((obj = mtmp->minvent) != 0) { obj_extract_self(obj); obj_no_longer_held(obj); @@ -437,7 +437,7 @@ boolean with_you; impossible("Can't find relocated object."); } } - corpse = mkcorpstat(CORPSE, (struct monst *)0, mtmp->data, + (void) mkcorpstat(CORPSE, (struct monst *)0, mtmp->data, xlocale, ylocale, CORPSTAT_NONE); mongone(mtmp); } @@ -685,6 +685,7 @@ migrate_to_level(mtmp, tolev, xyloc, cc) mtmp->mux = new_lev.dnum; mtmp->muy = new_lev.dlevel; mtmp->mx = mtmp->my = 0; /* this implies migration */ + if (mtmp == context.polearm.hitmon) context.polearm.hitmon = NULL; } /* return quality of food; the lower the better */ diff --git a/src/dokick.c b/src/dokick.c index 645eb5cf2..d558bdd38 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -991,7 +991,28 @@ dokick() exercise(A_DEX, TRUE); return(1); } - if(IS_GRAVE(maploc->typ) || maploc->typ == IRONBARS) + if (IS_GRAVE(maploc->typ)) { + if(Levitation) goto dumb; + if (rn2(4)) goto ouch; + exercise(A_WIS, FALSE); + if (Role_if(PM_ARCHEOLOGIST) || + Role_if(PM_SAMURAI) || + ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10))) { + adjalign(-sgn(u.ualign.type)); + } + maploc->typ = ROOM; + maploc->doormask = 0; + (void) mksobj_at(ROCK, x,y, TRUE, FALSE); + del_engr_at(x,y); + if (Blind) + pline("Crack! %s broke!", Something); + else { + pline_The("headstone topples over and breaks!"); + newsym(x,y); + } + return 1; + } + if(maploc->typ == IRONBARS) goto ouch; if(IS_TREE(maploc->typ)) { struct obj *treefruit; diff --git a/src/dothrow.c b/src/dothrow.c index aedb4fc40..ab4b96497 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -693,6 +693,7 @@ hurtle(dx, dy, range, verbose) if(!range || (!dx && !dy) || u.ustuck) return; /* paranoia */ nomul(-range); + multi_reason = "moving through the air"; nomovemsg = ""; /* it just happens */ if (verbose) You("%s in the opposite direction.", range > 1 ? "hurtle" : "float"); diff --git a/src/eat.c b/src/eat.c index a5b413772..cb92f16c1 100644 --- a/src/eat.c +++ b/src/eat.c @@ -962,6 +962,7 @@ register int pm; /* A pile of gold can't ride. */ if (u.usteed) dismount_steed(DISMOUNT_FELL); nomul(-tmp); + multi_reason = "pretending to be a pile of gold"; Sprintf(buf, Hallucination ? "You suddenly dread being peeled and mimic %s again!" : "You now prefer mimicking %s again.", @@ -1479,6 +1480,7 @@ struct obj *obj; pline_The("world spins and %s %s.", what, where); incr_itimeout(&HDeaf, duration); nomul(-duration); + multi_reason = "unconscious from rotten food"; nomovemsg = "You are conscious again."; afternmv = Hear_again; return(1); @@ -1572,6 +1574,8 @@ eatcorpse(otmp) /* called when a corpse is selected as food */ } else if ((mnum == PM_COCKATRICE || mnum == PM_CHICKATRICE) && (Stone_resistance || Hallucination)) { pline("This tastes just like chicken!"); + } else if (mnum == PM_FLOATING_EYE && u.umonnum == PM_RAVEN) { + You("peck the eyeball with delight."); } else { /* [is this right? omnivores end up always disliking the taste] */ boolean yummy = (vegan(&mons[mnum]) ? @@ -2677,6 +2681,7 @@ boolean incr; if (!Levitation) selftouch("Falling, you"); incr_itimeout(&HDeaf, duration); nomul(-duration); + multi_reason = "fainted from lack of food"; nomovemsg = "You regain consciousness."; afternmv = unfaint; newhs = FAINTED; @@ -2853,6 +2858,7 @@ vomit() /* A good idea from David Neves */ else make_sick(0L, (char *)0, TRUE, SICK_VOMITABLE); nomul(-2); + multi_reason = "vomiting"; nomovemsg = You_can_move_again; } diff --git a/src/end.c b/src/end.c index 7ada39767..35a5393bd 100644 --- a/src/end.c +++ b/src/end.c @@ -465,7 +465,12 @@ int how; Sprintf(eos(buf), " called %s", MNAME(mtmp)); } - if (multi) Strcat(buf, ", while helpless"); + if (multi) { + if (multi_reason) + Sprintf(eos(buf), ", while %s", multi_reason); + else + Strcat(buf, ", while helpless"); + } Strcpy(killer.name, buf); if (mptr->mlet == S_WRAITH) u.ugrave_arise = PM_WRAITH; diff --git a/src/files.c b/src/files.c index 9bc152726..a837e8765 100644 --- a/src/files.c +++ b/src/files.c @@ -2184,6 +2184,9 @@ int src; } else if (src == SET_IN_SYS && match_varname(buf, "SHELLERS", 8)) { if (sysopt.shellers) free(sysopt.shellers); sysopt.shellers = dupstr(bufp); + } else if (src == SET_IN_SYS && match_varname(buf, "EXPLORERS", 7)) { + if (sysopt.explorers) free(sysopt.explorers); + sysopt.explorers = dupstr(bufp); } else if (src == SET_IN_SYS && match_varname(buf, "DEBUGFILES", 5)) { if (sysopt.debugfiles) free(sysopt.debugfiles); /* if showdebug() has already been called (perhaps we've added @@ -2287,6 +2290,8 @@ int src; } else if (match_varname(buf, "BOULDER", 3)) { (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE, 1, "BOULDER"); + } else if (match_varname(buf, "MENUCOLOR", 9)) { + (void) add_menu_coloring(bufp); } else if (match_varname(buf, "WARNINGS", 5)) { (void) get_uchars(fp, buf, bufp, translate, FALSE, WARNCOUNT, "WARNINGS"); diff --git a/src/fountain.c b/src/fountain.c index 88fb6e2a4..405fac4a3 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 fountain.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 fountain.c $NHDT-Date: 1426953330 2015/03/21 15:55:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.40 $ */ /* NetHack 3.5 fountain.c $Date: 2011/08/20 00:22:20 $ $Revision: 1.32 $ */ /* Copyright Scott R. Turner, srt@ucla, 10/27/86 */ /* NetHack may be freely redistributed. See license for details. */ @@ -402,12 +402,14 @@ register struct obj *obj; if(in_town(u.ux, u.uy)) (void) angry_guards(FALSE); return; - } else if (water_damage(obj, NULL, TRUE) != ER_NOTHING) { - if (obj->otyp == POT_ACID) { /* Acid and water don't mix */ - useup(obj); - return; - } else if (!rn2(2)) /* no further effect */ - return; + } else { + int er = water_damage(obj, NULL, TRUE); + if (obj->otyp == POT_ACID && er != ER_DESTROYED) { /* Acid and water don't mix */ + useup(obj); + return; + } else if (er != ER_NOTHING && !rn2(2)) { /* no further effect */ + return; + } } switch (rnd(30)) { diff --git a/src/hack.c b/src/hack.c index 1edfb9f4e..5e14a3fab 100644 --- a/src/hack.c +++ b/src/hack.c @@ -630,8 +630,11 @@ int mode; if (Passes_walls && may_passwall(x,y)) { ; /* do nothing */ } else if (tmpr->typ == IRONBARS) { - if (!(Passes_walls || passes_bars(youmonst.data))) + if (!(Passes_walls || passes_bars(youmonst.data))) { + if (iflags.mention_walls) + You("cannot pass through the bars."); return FALSE; + } } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) { /* Eat the rock. */ if (mode == DO_MOVE && still_chewing(x,y)) return FALSE; @@ -646,8 +649,10 @@ int mode; if (Is_stronghold(&u.uz) && is_db_wall(x,y)) pline_The("drawbridge is up!"); /* sokoban restriction stays even after puzzle is solved */ - if (Passes_walls && !may_passwall(x,y) && In_sokoban(&u.uz)) + else if (Passes_walls && !may_passwall(x,y) && In_sokoban(&u.uz)) pline_The("Sokoban walls resist your ability."); + else if (iflags.mention_walls) + pline("It's a wall."); } return FALSE; } @@ -1099,7 +1104,7 @@ domove() register struct monst *mtmp; register struct rm *tmpr; register xchar x,y; - struct trap *trap; + struct trap *trap = (struct trap *)0; int wtcap; boolean on_ice; xchar chainx, chainy, ballx, bally; /* ball&chain new positions */ @@ -1563,6 +1568,7 @@ domove() /* must come after we finished picking up, in spoteffects() */ if (cause_delay) { nomul(-2); + multi_reason = "dragging an iron ball"; nomovemsg = ""; } @@ -2202,7 +2208,19 @@ dopickup() } } if (!OBJ_AT(u.ux, u.uy)) { - There("is nothing here to pick up."); + register struct rm *lev = &levl[u.ux][u.uy]; + if (IS_THRONE(lev->typ)) + pline("It must weigh%s a ton!", + lev->looted ? " almost" : ""); + else if (IS_SINK(lev->typ)) + pline_The("plumbing connects it to the floor."); + else if (IS_GRAVE(lev->typ)) + You("don't need a gravestone. Yet."); + else if (IS_FOUNTAIN(lev->typ)) + You("could drink the water..."); + else if (IS_DOOR(lev->typ) && (lev->doormask & D_ISOPEN)) + pline("It won't come off the hinges."); + else There("is nothing here to pick up."); return 0; } if (!can_reach_floor(TRUE)) { @@ -2417,6 +2435,7 @@ nomul(nval) u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */ u.usleep = 0; multi = nval; + if (nval == 0) multi_reason = NULL; context.travel = context.travel1 = context.mv = context.run = 0; } @@ -2431,6 +2450,7 @@ const char *msg_override; if (*nomovemsg) pline1(nomovemsg); nomovemsg = 0; u.usleep = 0; + multi_reason = NULL; if (afternmv) (*afternmv)(); afternmv = 0; } diff --git a/src/hacklib.c b/src/hacklib.c index 1c091b8f6..a9c31d42d 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -432,6 +432,28 @@ dist2(x0, y0, x1, y1) /* square of euclidean distance between pair of pts */ return dx * dx + dy * dy; } +/* Integer square root function without using floating point. + * This could be replaced by a faster algorithm, but has not been because: + * + the simple algorithm is easy to read + * + this algorithm does not require 64-bit support + * + in current usage, the values passed to isqrt() are not really that + * large, so the performance difference is negligible + * + isqrt() is used in only few places, which are not bottle-necks + */ +int +isqrt(val) +int val; +{ + int rt = 0; + int odd = 1; + while(val >= odd) { + val = val-odd; + odd = odd+2; + rt = rt + 1; + } + return rt; +} + boolean online2(x0, y0, x1, y1) /* are two points lined up (on a straight line)? */ int x0, y0, x1, y1; diff --git a/src/invent.c b/src/invent.c index 12f0ef1b3..2cc9e9004 100644 --- a/src/invent.c +++ b/src/invent.c @@ -915,8 +915,8 @@ register const char *let,*word; /* "ugly check" for reading fortune cookies, part 2 */ if ((!strcmp(word, "read") - && (otmp->otyp == FORTUNE_COOKIE || otmp->otyp == T_SHIRT))) - allowall = TRUE; + && is_readable(otmp))) + allowall = usegold = TRUE; } } bp[foo] = 0; @@ -1789,7 +1789,7 @@ nextclass: if (!flags.sortpack || otmp->oclass == *invlet) { if (flags.sortpack && !classcount) { add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, - let_to_name(*invlet, FALSE), MENU_UNSELECTED); + let_to_name(*invlet, FALSE, (want_reply && iflags.menu_head_objsym)), MENU_UNSELECTED); classcount++; } any.a_char = ilet; @@ -1863,7 +1863,7 @@ char avoidlet; if (flags.sortpack && !classcount) { any = zeroany; /* zero */ add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, - let_to_name(*invlet, FALSE), MENU_UNSELECTED); + let_to_name(*invlet, FALSE, FALSE), MENU_UNSELECTED); classcount++; } any.a_char = ilet; @@ -1991,7 +1991,7 @@ dounpaid() if (otmp->unpaid) { if (!flags.sortpack || otmp->oclass == *invlet) { if (flags.sortpack && !classcount) { - putstr(win, 0, let_to_name(*invlet, TRUE)); + putstr(win, 0, let_to_name(*invlet, TRUE, FALSE)); classcount++; } @@ -2009,7 +2009,7 @@ dounpaid() if (count > num_so_far) { /* something unpaid is contained */ if (flags.sortpack) - putstr(win, 0, let_to_name(CONTAINED_SYM, TRUE)); + putstr(win, 0, let_to_name(CONTAINED_SYM, TRUE, FALSE)); /* * Search through the container objects in the inventory for * unpaid items. The top level inventory items have already @@ -2701,10 +2701,12 @@ static NEARDATA char *invbuf = (char *)0; static NEARDATA unsigned invbufsiz = 0; char * -let_to_name(let,unpaid) +let_to_name(let,unpaid,showsym) char let; -boolean unpaid; +boolean unpaid,showsym; { + const char *ocsymfmt = " ('%c')"; + const int invbuf_sympadding = 8; /* arbitrary */ const char *class_name; const char *pos; int oclass = (let >= 1 && let < MAXOCLASSES) ? let : 0; @@ -2717,7 +2719,8 @@ boolean unpaid; else class_name = names[0]; - len = strlen(class_name) + (unpaid ? sizeof "unpaid_" : sizeof ""); + len = strlen(class_name) + (unpaid ? sizeof "unpaid_" : sizeof "") + + (oclass ? (strlen(ocsymfmt)+invbuf_sympadding) : 0); if (len > invbufsiz) { if (invbuf) free((genericptr_t)invbuf); invbufsiz = len + 10; /* add slop to reduce incremental realloc */ @@ -2727,6 +2730,15 @@ boolean unpaid; Strcat(strcpy(invbuf, "Unpaid "), class_name); else Strcpy(invbuf, class_name); + if ((oclass != 0) && showsym) { + char *bp = eos(invbuf); + int mlen = invbuf_sympadding - strlen(class_name); + while (--mlen > 0) { + *bp = ' '; bp++; + } + *bp = '\0'; + Sprintf(eos(invbuf), ocsymfmt, def_oc_syms[oclass].sym); + } return invbuf; } diff --git a/src/mail.c b/src/mail.c index cc01b97d3..c4cf8f61c 100644 --- a/src/mail.c +++ b/src/mail.c @@ -437,6 +437,11 @@ struct obj *otmp; "Only Amiga makes it possible.", "CATS have all the answers.", #endif + "This mail complies with the Yendorian Anti-Spam Act (YASA)", + "Please find enclosed a small token to represent your Owlbear", + "**FR33 P0T10N 0F FULL H34L1NG**", + "Please return to sender (Asmodeus)", + "Buy a potion of gain level for only $19.99! Guaranteed to be blessed!", "Invitation: Visit the NetHack web site at http://www.nethack.org!" }; diff --git a/src/makemon.c b/src/makemon.c index 6ce548ea0..799438c2e 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 makemon.c $NHDT-Date: 1426465436 2015/03/16 00:23:56 $ $NHDT-Branch: debug $:$NHDT-Revision: 1.74 $ */ +/* NetHack 3.5 makemon.c $NHDT-Date: 1427440865 2015/03/27 07:21:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.75 $ */ /* NetHack 3.5 makemon.c $Date: 2012/01/29 00:34:33 $ $Revision: 1.69 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1884,10 +1884,6 @@ int *seencount; /* secondary output */ } while (--creatcnt > 0); if (seecount) { if (seencount) *seencount += seecount; - /* don't set contents-known flag if we just used last charge - (such suppression doesn't actually gain us much since - player can now deduce that the bag has become empty) */ - if (bag->spe > 0) bag->cknown = 1; if (bag->dknown) makeknown(BAG_OF_TRICKS); } else if (!tipping) { pline1(!moncount ? nothing_happens : "Nothing seems to happen."); diff --git a/src/mcastu.c b/src/mcastu.c index a677db12e..03c06f2ed 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -634,12 +634,14 @@ int spellnum; if (multi >= 0) You("stiffen briefly."); nomul(-1); + multi_reason = "paralyzed by a monster"; } else { if (multi >= 0) You("are frozen in place!"); dmg = 4 + (int)mtmp->m_lev; if (Half_spell_damage) dmg = (dmg + 1) / 2; nomul(-dmg); + multi_reason = "paralyzed by a monster"; } nomovemsg = 0; dmg = 0; diff --git a/src/mhitu.c b/src/mhitu.c index 6aa4225f7..9ec602895 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1053,6 +1053,7 @@ dopois: else You("are frozen by %s!", mon_nam(mtmp)); nomovemsg = You_can_move_again; nomul(-rnd(10)); + multi_reason = "paralyzed by a monster"; exercise(A_DEX, FALSE); } } diff --git a/src/mklev.c b/src/mklev.c index 4412d68aa..5210d912b 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -17,7 +17,6 @@ STATIC_DCL void FDECL(mkgrave,(struct mkroom *)); STATIC_DCL void NDECL(makevtele); STATIC_DCL void NDECL(clear_level_structures); STATIC_DCL void NDECL(makelevel); -STATIC_DCL void NDECL(mineralize); STATIC_DCL boolean FDECL(bydoor,(XCHAR_P,XCHAR_P)); STATIC_DCL struct mkroom *FDECL(find_branch_room, (coord *)); STATIC_DCL struct mkroom *FDECL(pos_to_room, (XCHAR_P, XCHAR_P)); @@ -538,7 +537,7 @@ STATIC_OVL void clear_level_structures() { static struct rm zerorm = { cmap_to_glyph(S_stone), - 0, 0, 0, 0, 0, 0, 0, 0 }; + 0, 0, 0, 0, 0, 0, 0, 0, 0 }; register int x,y; register struct rm *lev; @@ -814,43 +813,50 @@ skip0: * Place deposits of minerals (gold and misc gems) in the stone * surrounding the rooms on the map. * Also place kelp in water. + * mineralize(-1, -1, -1, -1, FALSE); => "default" behaviour */ -STATIC_OVL void -mineralize() +void +mineralize(kelp_pool, kelp_moat, goldprob, gemprob, skip_lvl_checks) +int kelp_pool, kelp_moat, goldprob, gemprob; +boolean skip_lvl_checks; { s_level *sp; struct obj *otmp; - int goldprob, gemprob, x, y, cnt; + int x, y, cnt; + if (kelp_pool < 0) kelp_pool = 10; + if (kelp_moat < 0) kelp_moat = 30; /* Place kelp, except on the plane of water */ - if (In_endgame(&u.uz)) return; + if (!skip_lvl_checks && In_endgame(&u.uz)) return; for (x = 2; x < (COLNO - 2); x++) for (y = 1; y < (ROWNO - 1); y++) - if ((levl[x][y].typ == POOL && !rn2(10)) || - (levl[x][y].typ == MOAT && !rn2(30))) + if ((kelp_pool && levl[x][y].typ == POOL && !rn2(kelp_pool)) || + (kelp_moat && levl[x][y].typ == MOAT && !rn2(kelp_moat))) (void) mksobj_at(KELP_FROND, x, y, TRUE, FALSE); /* determine if it is even allowed; almost all special levels are excluded */ - if (In_hell(&u.uz) || In_V_tower(&u.uz) || + if (!skip_lvl_checks && (In_hell(&u.uz) || In_V_tower(&u.uz) || Is_rogue_level(&u.uz) || level.flags.arboreal || ((sp = Is_special(&u.uz)) != 0 && !Is_oracle_level(&u.uz) && (!In_mines(&u.uz) || sp->flags.town) - )) return; + ))) return; /* basic level-related probabilities */ - goldprob = 20 + depth(&u.uz) / 3; - gemprob = goldprob / 4; + if (goldprob < 0) goldprob = 20 + depth(&u.uz) / 3; + if (gemprob < 0) gemprob = goldprob / 4; /* mines have ***MORE*** goodies - otherwise why mine? */ - if (In_mines(&u.uz)) { - goldprob *= 2; - gemprob *= 3; - } else if (In_quest(&u.uz)) { - goldprob /= 4; - gemprob /= 6; + if (!skip_lvl_checks) { + if (In_mines(&u.uz)) { + goldprob *= 2; + gemprob *= 3; + } else if (In_quest(&u.uz)) { + goldprob /= 4; + gemprob /= 6; + } } /* @@ -905,7 +911,7 @@ mklev() in_mklev = TRUE; makelevel(); bound_digging(); - mineralize(); + mineralize(-1, -1, -1, -1, FALSE); in_mklev = FALSE; /* has_morgue gets cleared once morgue is entered; graveyard stays set (graveyard might already be set even when has_morgue is clear diff --git a/src/mkmaze.c b/src/mkmaze.c index 87a3a870b..8a5b9b793 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -344,7 +344,8 @@ fixup_special() was_waterlevel = FALSE; u.uinwater = 0; unsetup_waterlevel(); - } else if (Is_waterlevel(&u.uz)) { + } + if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) { level.flags.hero_memory = 0; was_waterlevel = TRUE; /* water level is an odd beast - it has to be set up @@ -406,10 +407,6 @@ fixup_special() place_lregion(0,0,0,0,0,0,0,0,LR_BRANCH,(d_level *)0); } - /* KMH -- Sokoban levels */ - if(In_sokoban(&u.uz)) - sokoban_detect(); - /* Still need to add some stuff to level file */ if (Is_medusa_level(&u.uz)) { struct obj *otmp; @@ -556,7 +553,7 @@ register const char *s; #endif maze0xy(&mm); - walkfrom((int) mm.x, (int) mm.y); + walkfrom((int) mm.x, (int) mm.y, 0); /* put a boulder at the maze center */ (void) mksobj_at(BOULDER, (int) mm.x, (int) mm.y, TRUE, FALSE); @@ -644,14 +641,21 @@ register const char *s; * that is totally safe. */ void -walkfrom(x,y) +walkfrom(x,y,typ) int x,y; +schar typ; { #define CELLS (ROWNO * COLNO) / 4 /* a maze cell is 4 squares */ char mazex[CELLS + 1], mazey[CELLS + 1]; /* char's are OK */ int q, a, dir, pos; int dirs[4]; +#ifndef WALLIFIED_MAZE + if (!typ) typ = CORR; +#else + if (!typ) typ = ROOM; +#endif + pos = 1; mazex[pos] = (char) x; mazey[pos] = (char) y; @@ -660,11 +664,7 @@ int x,y; y = (int) mazey[pos]; if(!IS_DOOR(levl[x][y].typ)) { /* might still be on edge of MAP, so don't overwrite */ -#ifndef WALLIFIED_MAZE - levl[x][y].typ = CORR; -#else - levl[x][y].typ = ROOM; -#endif + levl[x][y].typ = typ; levl[x][y].flags = 0; } q = 0; @@ -675,11 +675,7 @@ int x,y; else { dir = dirs[rn2(q)]; move(&x, &y, dir); -#ifndef WALLIFIED_MAZE - levl[x][y].typ = CORR; -#else - levl[x][y].typ = ROOM; -#endif + levl[x][y].typ = typ; move(&x, &y, dir); pos++; if (pos > CELLS) @@ -692,19 +688,22 @@ int x,y; #else void -walkfrom(x,y) +walkfrom(x,y,typ) int x,y; +schar typ; { register int q,a,dir; int dirs[4]; +#ifndef WALLIFIED_MAZE + if (!typ) typ = CORR; +#else + if (!typ) typ = ROOM; +#endif + if(!IS_DOOR(levl[x][y].typ)) { /* might still be on edge of MAP, so don't overwrite */ -#ifndef WALLIFIED_MAZE - levl[x][y].typ = CORR; -#else - levl[x][y].typ = ROOM; -#endif + levl[x][y].typ = typ; levl[x][y].flags = 0; } @@ -715,13 +714,9 @@ int x,y; if(!q) return; dir = dirs[rn2(q)]; move(&x,&y,dir); -#ifndef WALLIFIED_MAZE - levl[x][y].typ = CORR; -#else - levl[x][y].typ = ROOM; -#endif + levl[x][y].typ = typ; move(&x,&y,dir); - walkfrom(x,y); + walkfrom(x,y,typ); } } #endif /* MICRO */ @@ -921,99 +916,111 @@ movebubbles() register int x, y, i, j; struct trap *btrap; static const struct rm water_pos = - { cmap_to_glyph(S_water), WATER, 0, 0, 0, 0, 0, 0, 0 }; + { cmap_to_glyph(S_water), WATER, 0, 0, 0, 0, 0, 0, 0, 0 }; + static const struct rm air_pos = + { cmap_to_glyph(S_cloud), AIR, 0, 0, 0, 1, 0, 0, 0, 0 }; /* set up the portal the first time bubbles are moved */ if (!wportal) set_wportal(); vision_recalc(2); - /* keep attached ball&chain separate from bubble objects */ - if (Punished) unplacebc(); - /* - * Pick up everything inside of a bubble then fill all bubble - * locations. - */ + if (Is_waterlevel(&u.uz)) { - for (b = up ? bbubbles : ebubbles; b; b = up ? b->next : b->prev) { - if (b->cons) panic("movebubbles: cons != null"); - for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++) - for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++) - if (b->bm[j + 2] & (1 << i)) { - if (!isok(x,y)) { - impossible("movebubbles: bad pos (%d,%d)", x,y); - continue; - } + /* keep attached ball&chain separate from bubble objects */ + if (Punished) unplacebc(); - /* pick up objects, monsters, hero, and traps */ - if (OBJ_AT(x,y)) { - struct obj *olist = (struct obj *) 0, *otmp; - struct container *cons = (struct container *) - alloc(sizeof(struct container)); + /* + * Pick up everything inside of a bubble then fill all bubble + * locations. + */ - while ((otmp = level.objects[x][y]) != 0) { - remove_object(otmp); - otmp->ox = otmp->oy = 0; - otmp->nexthere = olist; - olist = otmp; + for (b = up ? bbubbles : ebubbles; b; b = up ? b->next : b->prev) { + if (b->cons) panic("movebubbles: cons != null"); + for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++) + for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++) + if (b->bm[j + 2] & (1 << i)) { + if (!isok(x,y)) { + impossible("movebubbles: bad pos (%d,%d)", x,y); + continue; } - cons->x = x; - cons->y = y; - cons->what = CONS_OBJ; - cons->list = (genericptr_t) olist; - cons->next = b->cons; - b->cons = cons; + /* pick up objects, monsters, hero, and traps */ + if (OBJ_AT(x,y)) { + struct obj *olist = (struct obj *) 0, *otmp; + struct container *cons = (struct container *) + alloc(sizeof(struct container)); + + while ((otmp = level.objects[x][y]) != 0) { + remove_object(otmp); + otmp->ox = otmp->oy = 0; + otmp->nexthere = olist; + olist = otmp; + } + + cons->x = x; + cons->y = y; + cons->what = CONS_OBJ; + cons->list = (genericptr_t) olist; + cons->next = b->cons; + b->cons = cons; + } + if (MON_AT(x,y)) { + struct monst *mon = m_at(x,y); + struct container *cons = (struct container *) + alloc(sizeof(struct container)); + + cons->x = x; + cons->y = y; + cons->what = CONS_MON; + cons->list = (genericptr_t) mon; + + cons->next = b->cons; + b->cons = cons; + + if(mon->wormno) + remove_worm(mon); + else + remove_monster(x, y); + + newsym(x,y); /* clean up old position */ + mon->mx = mon->my = 0; + } + if (!u.uswallow && x == u.ux && y == u.uy) { + struct container *cons = (struct container *) + alloc(sizeof(struct container)); + + cons->x = x; + cons->y = y; + cons->what = CONS_HERO; + cons->list = (genericptr_t) 0; + + cons->next = b->cons; + b->cons = cons; + } + if ((btrap = t_at(x,y)) != 0) { + struct container *cons = (struct container *) + alloc(sizeof(struct container)); + + cons->x = x; + cons->y = y; + cons->what = CONS_TRAP; + cons->list = (genericptr_t) btrap; + + cons->next = b->cons; + b->cons = cons; + } + + levl[x][y] = water_pos; + block_point(x,y); } - if (MON_AT(x,y)) { - struct monst *mon = m_at(x,y); - struct container *cons = (struct container *) - alloc(sizeof(struct container)); - - cons->x = x; - cons->y = y; - cons->what = CONS_MON; - cons->list = (genericptr_t) mon; - - cons->next = b->cons; - b->cons = cons; - - if(mon->wormno) - remove_worm(mon); - else - remove_monster(x, y); - - newsym(x,y); /* clean up old position */ - mon->mx = mon->my = 0; - } - if (!u.uswallow && x == u.ux && y == u.uy) { - struct container *cons = (struct container *) - alloc(sizeof(struct container)); - - cons->x = x; - cons->y = y; - cons->what = CONS_HERO; - cons->list = (genericptr_t) 0; - - cons->next = b->cons; - b->cons = cons; - } - if ((btrap = t_at(x,y)) != 0) { - struct container *cons = (struct container *) - alloc(sizeof(struct container)); - - cons->x = x; - cons->y = y; - cons->what = CONS_TRAP; - cons->list = (genericptr_t) btrap; - - cons->next = b->cons; - b->cons = cons; - } - - levl[x][y] = water_pos; - block_point(x,y); - } + } + } else if (Is_airlevel(&u.uz)) { + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) { + levl[x][y] = air_pos; + unblock_point(x,y); + } } /* @@ -1032,7 +1039,7 @@ movebubbles() } /* put attached ball&chain back */ - if (Punished) placebc(); + if (Is_waterlevel(&u.uz) && Punished) placebc(); vision_full_recalc = 1; } @@ -1076,7 +1083,7 @@ int fd, mode; { register struct bubble *b; - if (!Is_waterlevel(&u.uz)) return; + if (!Is_waterlevel(&u.uz) && !Is_airlevel(&u.uz)) return; if (perform_bwrite(mode)) { int n = 0; @@ -1101,7 +1108,7 @@ register int fd; register int i; int n; - if (!Is_waterlevel(&u.uz)) return; + if (!Is_waterlevel(&u.uz) && !Is_airlevel(&u.uz)) return; set_wportal(); mread(fd,(genericptr_t)&n,sizeof(int)); @@ -1177,6 +1184,7 @@ setup_waterlevel() register int x, y; register int xskip, yskip; register int water_glyph = cmap_to_glyph(S_water); + register int air_glyph = cmap_to_glyph(S_air); /* ouch, hardcoded... */ @@ -1189,12 +1197,18 @@ setup_waterlevel() for (x = xmin; x <= xmax; x++) for (y = ymin; y <= ymax; y++) - levl[x][y].glyph = water_glyph; + levl[x][y].glyph = Is_waterlevel(&u.uz) ? water_glyph : air_glyph; /* make bubbles */ - xskip = 10 + rn2(10); - yskip = 4 + rn2(4); + if (Is_waterlevel(&u.uz)) { + xskip = 10 + rn2(10); + yskip = 4 + rn2(4); + } else { + xskip = 6 + rn2(4); + yskip = 3 + rn2(3); + } + for (x = bxmin; x <= bxmax; x += xskip) for (y = bymin; y <= bymax; y += yskip) mk_bubble(x,y,rn2(7)); @@ -1280,67 +1294,76 @@ register boolean ini; register int x, y, i, j, colli = 0; struct container *cons, *ctemp; - /* move bubble */ - if (dx < -1 || dx > 1 || dy < -1 || dy > 1) { - /* pline("mv_bubble: dx = %d, dy = %d", dx, dy); */ - dx = sgn(dx); - dy = sgn(dy); + /* clouds move slowly */ + if (!Is_airlevel(&u.uz) || !rn2(6)) { + /* move bubble */ + if (dx < -1 || dx > 1 || dy < -1 || dy > 1) { + /* pline("mv_bubble: dx = %d, dy = %d", dx, dy); */ + dx = sgn(dx); + dy = sgn(dy); + } + + /* + * collision with level borders? + * 1 = horizontal border, 2 = vertical, 3 = corner + */ + if (b->x <= bxmin) colli |= 2; + if (b->y <= bymin) colli |= 1; + if ((int) (b->x + b->bm[0] - 1) >= bxmax) colli |= 2; + if ((int) (b->y + b->bm[1] - 1) >= bymax) colli |= 1; + + if (b->x < bxmin) { + pline("bubble xmin: x = %d, xmin = %d", b->x, bxmin); + b->x = bxmin; + } + if (b->y < bymin) { + pline("bubble ymin: y = %d, ymin = %d", b->y, bymin); + b->y = bymin; + } + if ((int) (b->x + b->bm[0] - 1) > bxmax) { + pline("bubble xmax: x = %d, xmax = %d", + b->x + b->bm[0] - 1, bxmax); + b->x = bxmax - b->bm[0] + 1; + } + if ((int) (b->y + b->bm[1] - 1) > bymax) { + pline("bubble ymax: y = %d, ymax = %d", + b->y + b->bm[1] - 1, bymax); + b->y = bymax - b->bm[1] + 1; + } + + /* bounce if we're trying to move off the border */ + if (b->x == bxmin && dx < 0) dx = -dx; + if (b->x + b->bm[0] - 1 == bxmax && dx > 0) dx = -dx; + if (b->y == bymin && dy < 0) dy = -dy; + if (b->y + b->bm[1] - 1 == bymax && dy > 0) dy = -dy; + + b->x += dx; + b->y += dy; } - /* - * collision with level borders? - * 1 = horizontal border, 2 = vertical, 3 = corner - */ - if (b->x <= bxmin) colli |= 2; - if (b->y <= bymin) colli |= 1; - if ((int) (b->x + b->bm[0] - 1) >= bxmax) colli |= 2; - if ((int) (b->y + b->bm[1] - 1) >= bymax) colli |= 1; - - if (b->x < bxmin) { - pline("bubble xmin: x = %d, xmin = %d", b->x, bxmin); - b->x = bxmin; - } - if (b->y < bymin) { - pline("bubble ymin: y = %d, ymin = %d", b->y, bymin); - b->y = bymin; - } - if ((int) (b->x + b->bm[0] - 1) > bxmax) { - pline("bubble xmax: x = %d, xmax = %d", - b->x + b->bm[0] - 1, bxmax); - b->x = bxmax - b->bm[0] + 1; - } - if ((int) (b->y + b->bm[1] - 1) > bymax) { - pline("bubble ymax: y = %d, ymax = %d", - b->y + b->bm[1] - 1, bymax); - b->y = bymax - b->bm[1] + 1; - } - - /* bounce if we're trying to move off the border */ - if (b->x == bxmin && dx < 0) dx = -dx; - if (b->x + b->bm[0] - 1 == bxmax && dx > 0) dx = -dx; - if (b->y == bymin && dy < 0) dy = -dy; - if (b->y + b->bm[1] - 1 == bymax && dy > 0) dy = -dy; - - b->x += dx; - b->y += dy; - - /* void positions inside bubble */ - + /* draw the bubbles */ for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++) for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++) if (b->bm[j + 2] & (1 << i)) { + if (Is_waterlevel(&u.uz)) { levl[x][y].typ = AIR; levl[x][y].lit = 1; unblock_point(x,y); + } else if (Is_airlevel(&u.uz)) { + levl[x][y].typ = CLOUD; + levl[x][y].lit = 1; + block_point(x,y); + } } - /* replace contents of bubble */ - for (cons = b->cons; cons; cons = ctemp) { - ctemp = cons->next; - cons->x += dx; - cons->y += dy; + if (Is_waterlevel(&u.uz)) { + /* replace contents of bubble */ + for (cons = b->cons; cons; cons = ctemp) { + ctemp = cons->next; + cons->x += dx; + cons->y += dy; - switch(cons->what) { + switch(cons->what) { case CONS_OBJ: { struct obj *olist, *otmp; @@ -1381,13 +1404,13 @@ register boolean ini; default: impossible("mv_bubble: unknown bubble contents"); break; + } + free((genericptr_t)cons); } - free((genericptr_t)cons); + b->cons = 0; } - b->cons = 0; /* boing? */ - switch (colli) { case 1: b->dy = -b->dy; break; case 3: b->dy = -b->dy; /* fall through */ diff --git a/src/mkroom.c b/src/mkroom.c index 7f94076e7..6ef03054a 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 mkroom.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 mkroom.c $NHDT-Date: 1427239202 2015/03/24 23:20:02 $ $NHDT-Branch: master $:$NHDT-Revision: 1.16 $ */ /* NetHack 3.5 mkroom.c $Date: 2012/01/10 17:47:19 $ $Revision: 1.15 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -219,14 +219,10 @@ struct mkroom *sroom; { struct monst *mon; register int sx,sy,i; - int sh, tx, ty, goldlim, type = sroom->rtype; + int sh, tx = 0, ty = 0, goldlim = 0, type = sroom->rtype; int rmno = (int)((sroom - rooms) + ROOMOFFSET); coord mm; -#ifdef GCC_WARN - tx = ty = goldlim = 0; -#endif - sh = sroom->fdoor; switch(type) { case COURT: @@ -408,9 +404,17 @@ morguemon() { register int i = rn2(100), hd = rn2(level_difficulty()); - if(hd > 10 && i < 10) - return((Inhell || In_endgame(&u.uz)) ? mkclass(S_DEMON,0) : - &mons[ndemon(A_NONE)]); + if(hd > 10 && i < 10) { + if (Inhell || In_endgame(&u.uz)) { + return(mkclass(S_DEMON,0)); + } else { + int ndemon_res = ndemon(A_NONE); + if (ndemon_res != NON_PM) + return(&mons[ndemon_res]); + /* else do what? As is, it will drop to ghost/wraith/zombie */ + } + } + if(hd > 8 && i > 85) return(mkclass(S_VAMPIRE,0)); diff --git a/src/mon.c b/src/mon.c index fb0a75a57..5427f8da4 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 mon.c $NHDT-Date: 1426465438 2015/03/16 00:23:58 $ $NHDT-Branch: debug $:$NHDT-Revision: 1.139 $ */ +/* NetHack 3.5 mon.c $NHDT-Date: 1427580482 2015/03/28 22:08:02 $ $NHDT-Branch: master $:$NHDT-Revision: 1.142 $ */ /* NetHack 3.5 mon.c $Date: 2012/05/16 02:15:10 $ $Revision: 1.126 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -278,9 +278,10 @@ unsigned corpseflags; obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0, mdat, x, y, corpstatflags); if (burythem) { - (void) bury_an_obj(obj); + boolean dealloc; + (void) bury_an_obj(obj, &dealloc); newsym(x, y); - return obj; + return (dealloc ? NULL : obj); } } break; @@ -615,7 +616,10 @@ meatmetal(mtmp) /* Eats topmost metal object if it is there */ for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp->nexthere) { - if (mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp)) + /* Don't eat indigestible/choking/inappropriate objects */ + if ((mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp)) || + (otmp->otyp == AMULET_OF_STRANGULATION) || + (otmp->otyp == RIN_SLOW_DIGESTION)) continue; if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) && touch_artifact(otmp,mtmp)) { @@ -632,9 +636,7 @@ meatmetal(mtmp) pline("%s spits %s out in disgust!", Monnam(mtmp), distant_name(otmp,doname)); } - /* KMH -- Don't eat indigestible/choking objects */ - } else if (otmp->otyp != AMULET_OF_STRANGULATION && - otmp->otyp != RIN_SLOW_DIGESTION) { + } else { if (cansee(mtmp->mx,mtmp->my) && flags.verbose) pline("%s eats %s!", Monnam(mtmp), distant_name(otmp,doname)); @@ -1237,6 +1239,8 @@ dmonsfree() for (mtmp = &fmon; *mtmp;) { freetmp = *mtmp; if (freetmp->mhp <= 0 && !freetmp->isgd) { + if (freetmp == context.polearm.hitmon) + context.polearm.hitmon = NULL; *mtmp = freetmp->nmon; dealloc_monst(freetmp); count++; diff --git a/src/o_init.c b/src/o_init.c index 4ae8892e9..3d95a0d6f 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -446,7 +446,7 @@ dodiscovered() /* free after Robert Viduya */ if ((dis = disco[i]) != 0 && interesting_to_discover(dis)) { ct++; if (oclass != prev_class) { - putstr(tmpwin, iflags.menu_headings, let_to_name(oclass, FALSE)); + putstr(tmpwin, iflags.menu_headings, let_to_name(oclass, FALSE, FALSE)); prev_class = oclass; } Sprintf(buf, "%s %s",(objects[dis].oc_pre_discovered ? "*" : " "), @@ -472,7 +472,7 @@ char *buf; { char *s; - Strcpy(buf, let_to_name(oclass, FALSE)); + Strcpy(buf, let_to_name(oclass, FALSE, FALSE)); for (s = buf; *s; ++s) *s = lowc(*s); return buf; } @@ -615,7 +615,7 @@ doclassdisco() break; default: oclass = def_char_to_objclass(c); - Sprintf(buf, "Discovered %s", let_to_name(oclass, FALSE)); + Sprintf(buf, "Discovered %s", let_to_name(oclass, FALSE, FALSE)); putstr(tmpwin, iflags.menu_headings, buf); for (i = bases[(int)oclass]; i < NUM_OBJECTS && objects[i].oc_class == oclass; ++i) { @@ -672,7 +672,7 @@ rename_disco() if (oclass != prev_class) { any.a_int = 0; add_menu(tmpwin, NO_GLYPH, &any, ' ', iflags.menu_headings, - ATR_NONE, let_to_name(oclass, FALSE), MENU_UNSELECTED); + ATR_NONE, let_to_name(oclass, FALSE, FALSE), MENU_UNSELECTED); prev_class = oclass; } any.a_int = dis; diff --git a/src/objnam.c b/src/objnam.c index 993513583..fd23f01ad 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 objnam.c $NHDT-Date: 1426977394 2015/03/21 22:36:34 $ $NHDT-Branch: master $:$NHDT-Revision: 1.108 $ */ +/* NetHack 3.5 objnam.c $NHDT-Date: 1427440866 2015/03/27 07:21:06 $ $NHDT-Branch: master $:$NHDT-Revision: 1.109 $ */ /* NetHack 3.5 objnam.c $Date: 2011/10/27 02:24:54 $ $Revision: 1.101 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -501,6 +501,11 @@ register struct obj *obj; } if (pluralize) Strcpy(buf, makeplural(buf)); + if (obj->otyp == T_SHIRT && program_state.gameover) { + char tmpbuf[BUFSZ]; + Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf)); + } + if (has_oname(obj) && dknown) { Strcat(buf, " named "); nameit: @@ -663,8 +668,9 @@ register struct obj *obj; */ register char *bp = xname(obj); - if (iflags.override_ID) known = cknown = bknown = lknown = TRUE; - else { + if (iflags.override_ID) { + known = cknown = bknown = lknown = TRUE; + } else { known = obj->known; cknown = obj->cknown; bknown = obj->bknown; @@ -697,7 +703,15 @@ register struct obj *obj; /* "empty" goes at the beginning, but item count goes at the end */ if (cknown && - (Is_container(obj) || obj->otyp == STATUE) && !Has_contents(obj)) + /* bag of tricks: include "empty" prefix if it's known to + be empty but its precise number of charges isn't known + (when that is known, suffix of "(n:0)" will be appended, + making the prefix be redundant; note that 'known' flag + isn't set when emptiness gets discovered because then + charging magic would yield known number of new charges) */ + (obj->otyp == BAG_OF_TRICKS ? (obj->spe == 0 && !obj->known) : + /* not bag of tricks: empty if container which has no contents */ + (Is_container(obj) || obj->otyp == STATUE) && !Has_contents(obj))) Strcat(prefix, "empty "); if (bknown && diff --git a/src/options.c b/src/options.c index c21010ab1..54e0471e8 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 options.c $NHDT-Date: 1427035440 2015/03/22 14:44:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.163 $ */ +/* NetHack 3.5 options.c $NHDT-Date: 1427073746 2015/03/23 01:22:26 $ $NHDT-Branch: master $:$NHDT-Revision: 1.164 $ */ /* NetHack 3.5 options.c $Date: 2012/04/09 02:56:30 $ $Revision: 1.153 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -85,6 +85,7 @@ static struct Bool_Opt #else {"BIOS", (boolean *)0, FALSE, SET_IN_FILE}, #endif + {"blind", &u.uroleplay.blind, FALSE, DISP_IN_GAME}, {"bones", &flags.bones, TRUE, SET_IN_FILE}, #ifdef INSURANCE {"checkpoint", &flags.ins_chkpt, TRUE, SET_IN_GAME}, @@ -139,14 +140,18 @@ static struct Bool_Opt #else {"mail", (boolean *)0, TRUE, SET_IN_FILE}, #endif + {"mention_walls", &iflags.mention_walls, FALSE, SET_IN_GAME}, + {"menucolors", &iflags.use_menu_color, FALSE, SET_IN_GAME}, /* for menu debugging only*/ {"menu_tab_sep", &iflags.menu_tab_sep, FALSE, SET_IN_GAME}, + {"menu_objsyms", &iflags.menu_head_objsym, FALSE, SET_IN_GAME}, {"mouse_support", &iflags.wc_mouse_support, TRUE, DISP_IN_GAME}, /*WC*/ #ifdef NEWS {"news", &iflags.news, TRUE, DISP_IN_GAME}, #else {"news", (boolean *)0, FALSE, SET_IN_FILE}, #endif + {"nudist", &u.uroleplay.nudist, FALSE, DISP_IN_GAME}, {"null", &flags.null, TRUE, SET_IN_GAME}, #if defined(SYSFLAGS) && defined(MAC) {"page_wait", &sysflags.page_wait, TRUE, SET_IN_GAME}, @@ -199,6 +204,7 @@ static struct Bool_Opt {"tombstone",&flags.tombstone, TRUE, SET_IN_GAME}, {"toptenwin",&iflags.toptenwin, FALSE, SET_IN_GAME}, {"travel", &flags.travelcmd, TRUE, SET_IN_GAME}, + {"use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE}, #ifdef WIN32CON {"use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME}, /*WC*/ #else @@ -1085,6 +1091,174 @@ STATIC_VAR const struct paranoia_opts { { ~0, "all", 3, 0, 0, 0 }, /* ditto */ }; + +extern struct menucoloring *menu_colorings; + +static const struct { + const char *name; + const int color; +} colornames[] = { + {"black", CLR_BLACK}, + {"red", CLR_RED}, + {"green", CLR_GREEN}, + {"brown", CLR_BROWN}, + {"blue", CLR_BLUE}, + {"magenta", CLR_MAGENTA}, + {"cyan", CLR_CYAN}, + {"gray", CLR_GRAY}, + {"grey", CLR_GRAY}, + {"orange", CLR_ORANGE}, + {"lightgreen", CLR_BRIGHT_GREEN}, + {"yellow", CLR_YELLOW}, + {"lightblue", CLR_BRIGHT_BLUE}, + {"lightmagenta", CLR_BRIGHT_MAGENTA}, + {"lightcyan", CLR_BRIGHT_CYAN}, + {"white", CLR_WHITE} +}; + +static const struct { + const char *name; + const int attr; +} attrnames[] = { + {"none", ATR_NONE}, + {"bold", ATR_BOLD}, + {"dim", ATR_DIM}, + {"underline", ATR_ULINE}, + {"blink", ATR_BLINK}, + {"inverse", ATR_INVERSE} +}; + +/* parse '"regex_string"=color&attr' and add it to menucoloring */ +boolean +add_menu_coloring(str) +char *str; +{ + int i, c = NO_COLOR, a = ATR_NONE; + struct menucoloring *tmp; + char *tmps, *cs = strchr(str, '='); +#ifdef MENU_COLOR_REGEX_POSIX + int errnum; + char errbuf[80]; +#endif + const char *err = (char *)0; + + if (!cs || !str) return FALSE; + + tmps = cs; + tmps++; + while (*tmps && isspace(*tmps)) tmps++; + + for (i = 0; i < SIZE(colornames); i++) + if (strstri(tmps, colornames[i].name) == tmps) { + c = colornames[i].color; + break; + } + if ((i == SIZE(colornames)) && (*tmps >= '0' && *tmps <='9')) + c = atoi(tmps); + + if (c > 15) return FALSE; + + tmps = strchr(str, '&'); + if (tmps) { + tmps++; + while (*tmps && isspace(*tmps)) tmps++; + for (i = 0; i < SIZE(attrnames); i++) + if (strstri(tmps, attrnames[i].name) == tmps) { + a = attrnames[i].attr; + break; + } + if ((i == SIZE(attrnames)) && (*tmps >= '0' && *tmps <='9')) + a = atoi(tmps); + } + + *cs = '\0'; + tmps = str; + if ((*tmps == '"') || (*tmps == '\'')) { + cs--; + while (isspace(*cs)) cs--; + if (*cs == *tmps) { + *cs = '\0'; + tmps++; + } + } + + tmp = (struct menucoloring *)alloc(sizeof(struct menucoloring)); +#ifdef MENU_COLOR_REGEX +#ifdef MENU_COLOR_REGEX_POSIX + errnum = regcomp(&tmp->match, tmps, REG_EXTENDED | REG_NOSUB); + if (errnum != 0) + { + regerror(errnum, &tmp->match, errbuf, sizeof(errbuf)); + err = errbuf; + } +#else + tmp->match.translate = 0; + tmp->match.fastmap = 0; + tmp->match.buffer = 0; + tmp->match.allocated = 0; + tmp->match.regs_allocated = REGS_FIXED; + err = re_compile_pattern(tmps, strlen(tmps), &tmp->match); +#endif +#else + tmp->match = (char *)alloc(strlen(tmps)+1); + (void) memcpy((genericptr_t)tmp->match, (genericptr_t)tmps, strlen(tmps)+1); +#endif + if (err) { + raw_printf("\nMenucolor regex error: %s\n", err); + wait_synch(); + free(tmp); + return FALSE; + } else { + tmp->next = menu_colorings; + tmp->color = c; + tmp->attr = a; + menu_colorings = tmp; + return TRUE; + } +} + +boolean +get_menu_coloring(str, color, attr) +char *str; +int *color, *attr; +{ + struct menucoloring *tmpmc; + if (iflags.use_menu_color) + for (tmpmc = menu_colorings; tmpmc; tmpmc = tmpmc->next) +#ifdef MENU_COLOR_REGEX +# ifdef MENU_COLOR_REGEX_POSIX + if (regexec(&tmpmc->match, str, 0, NULL, 0) == 0) { +# else + if (re_search(&tmpmc->match, str, strlen(str), 0, 9999, 0) >= 0) { +# endif +#else + if (pmatch(tmpmc->match, str)) { +#endif + *color = tmpmc->color; + *attr = tmpmc->attr; + return TRUE; + } + return FALSE; +} + +void +free_menu_coloring() +{ + struct menucoloring *tmp = menu_colorings; + + while (tmp) { + struct menucoloring *tmp2 = tmp->next; +#ifdef MENU_COLOR_REGEX + (void) regfree(&tmp->match); +#else + free(tmp->match); +#endif + free(tmp); + tmp = tmp2; + } +} + + void parseoptions(opts, tinitial, tfrom_file) register char *opts; @@ -1426,6 +1600,16 @@ boolean tinitial, tfrom_file; return; } + /* menucolor:"regex_string"=color */ + fullname = "menucolor"; + if (match_optname(opts, fullname, 9, TRUE)) { + if (negated) bad_negation(fullname, FALSE); + else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) + if (!add_menu_coloring(op)) + badoption(opts); + return; + } + fullname = "msghistory"; if (match_optname(opts, fullname, 3, TRUE)) { if (duplicate) complain_about_duplicate(opts,1); @@ -2484,7 +2668,7 @@ goodfruit: #if defined(BACKWARD_COMPAT) fullname = "DECgraphics"; - if (match_optname(opts, fullname, 10, TRUE)) { + if (match_optname(opts, fullname, 3, TRUE)) { boolean badflag = FALSE; if (duplicate) complain_about_duplicate(opts,1); if (!negated) { @@ -2508,7 +2692,7 @@ goodfruit: return; } fullname = "IBMgraphics"; - if (match_optname(opts, fullname, 10, TRUE)) { + if (match_optname(opts, fullname, 3, TRUE)) { const char *sym_name = fullname; boolean badflag = FALSE; if (duplicate) complain_about_duplicate(opts,1); @@ -2542,7 +2726,7 @@ goodfruit: #endif #ifdef MAC_GRAPHICS_ENV fullname = "MACgraphics"; - if (match_optname(opts, fullname, 11, TRUE)) { + if (match_optname(opts, fullname, 3, TRUE)) { boolean badflag = FALSE; if (duplicate) complain_about_duplicate(opts,1); if (!negated) { @@ -4396,6 +4580,7 @@ struct wc_Opt wc2_options[] = { {"fullscreen", WC2_FULLSCREEN}, {"softkeyboard", WC2_SOFTKEYBOARD}, {"wraptext", WC2_WRAPTEXT}, + {"use_darkgray", WC2_DARKGRAY}, #ifdef STATUS_VIA_WINDOWPORT {"hilite_status", WC2_HILITE_STATUS}, #endif diff --git a/src/pager.c b/src/pager.c index bb1c82e72..4c0f69d17 100644 --- a/src/pager.c +++ b/src/pager.c @@ -447,7 +447,8 @@ const char **firstmatch; { boolean need_to_look = FALSE; int glyph; - char look_buf[BUFSZ], prefix[BUFSZ]; + static char look_buf[BUFSZ]; + char prefix[BUFSZ]; int found = 0; /* count of matching syms found */ int i; int skipped_venom = 0; @@ -678,7 +679,7 @@ do_look(mode, click_cc) char out_str[BUFSZ]; const char *firstmatch = 0; struct permonst *pm = 0; - int i, ans = 0; + int i = '\0', ans = 0; int sym; /* typed symbol or converted glyph */ int found; /* count of matching syms found */ coord cc; /* screen pos of unknown glyph */ @@ -688,25 +689,68 @@ do_look(mode, click_cc) if (!clicklook) { if (quick) { from_screen = TRUE; /* yes, we want to use the cursor */ - } else { - i = ynq("Specify unknown object by cursor?"); - if (i == 'q') return 0; - from_screen = (i == 'y'); + i = 'y'; + } + + if (i != 'y') { + menu_item *pick_list = (menu_item *)0; + winid win; + anything any; + win = create_nhwindow(NHW_MENU); + start_menu(win); + any.a_void = 0; any.a_char ='a'; + /* 'y' and 'n' to keep backwards compat with previous versions */ + add_menu(win, NO_GLYPH, &any, 'a', 'y', ATR_NONE, "something on the map", MENU_UNSELECTED); + any.a_void = 0; any.a_char ='b'; + add_menu(win, NO_GLYPH, &any, 'b', 0, ATR_NONE, "something you're carrying", MENU_UNSELECTED); + any.a_void = 0; any.a_char ='c'; + add_menu(win, NO_GLYPH, &any, 'c', 'n', ATR_NONE, "something else", MENU_UNSELECTED); + end_menu(win, "What do you want to look at:"); + if (select_menu(win, PICK_ONE, &pick_list) > 0) { + i = pick_list->item.a_char; + free((genericptr_t)pick_list); + } + destroy_nhwindow(win); } - if (from_screen) { - cc.x = u.ux; - cc.y = u.uy; - sym = 0; /* gcc -Wall lint */ - } else { - getlin("Specify what? (type the word)", out_str); - if (out_str[0] == '\0' || out_str[0] == '\033') - return 0; - if (out_str[1]) { /* user typed in a complete string */ - checkfile(out_str, pm, TRUE, TRUE); - return 0; - } - sym = out_str[0]; + switch (i) { + default: + case 'q': return 0; + case 'y': + case 'a': + from_screen = TRUE; + sym = 0; + cc.x = u.ux; + cc.y = u.uy; + break; + case 'b': + { + char invlet; + struct obj *invobj; + invlet = display_inventory(NULL, TRUE); + if (!invlet) return 0; + for (invobj = invent; invobj; invobj = invobj->nobj) + if (invobj->invlet == invlet) { + strcpy(out_str, singular(invobj, xname)); + break; + } + if (!out_str[1]) return 0; + checkfile(out_str, pm, TRUE, TRUE); + return 0; + } + break; + case 'c': + from_screen = FALSE; + getlin("Specify what? (type the word)", out_str); + if (out_str[0] == '\0' || out_str[0] == '\033') + return 0; + + if (out_str[1]) { /* user typed in a complete string */ + checkfile(out_str, pm, TRUE, TRUE); + return 0; + } + sym = out_str[0]; + break; } } else { /* clicklook */ cc.x = click_cc->x; diff --git a/src/pickup.c b/src/pickup.c index 1d78dea76..bf5d06129 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -769,7 +769,9 @@ boolean FDECL((*allow), (OBJ_P));/* allow function */ if (sorted && !printed_type_name) { any = zeroany; add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, - let_to_name(*pack, FALSE), MENU_UNSELECTED); + let_to_name(*pack, FALSE, + (how != PICK_NONE) && iflags.menu_head_objsym), + MENU_UNSELECTED); printed_type_name = TRUE; } @@ -928,8 +930,10 @@ int how; /* type of query */ any.a_int = curr->oclass; add_menu(win, NO_GLYPH, &any, invlet++, def_oc_syms[(int)objects[curr->otyp].oc_class].sym, - ATR_NONE, let_to_name(*pack, FALSE), - MENU_UNSELECTED); + ATR_NONE, + let_to_name(*pack, FALSE, + (how != PICK_NONE) && iflags.menu_head_objsym), + MENU_UNSELECTED); collected_type_name = TRUE; } } @@ -1494,6 +1498,7 @@ doloot() /* loot a container on the floor or loot saddle from mon. */ char qbuf[BUFSZ]; int prev_inquiry = 0; boolean prev_loot = FALSE; + int num_conts; if (check_capacity((char *)0)) { /* "Can't do that while carrying so much stuff." */ @@ -1514,15 +1519,11 @@ doloot() /* loot a container on the floor or loot saddle from mon. */ lootcont: - if (container_at(cc.x, cc.y, FALSE)) { + if ((num_conts = container_at(cc.x, cc.y, TRUE)) > 0) { boolean anyfound = FALSE; - int num_conts = 0; if (!able_to_loot(cc.x, cc.y, TRUE)) return 0; - for (cobj = level.objects[cc.x][cc.y]; cobj; cobj = cobj->nexthere) - if (Is_container(cobj)) num_conts++; - if (num_conts > 1) { /* use a menu to loot many containers */ int n, i; @@ -2120,6 +2121,7 @@ int held; /* even if the trap fails, you've used up this turn */ if (multi >= 0) { /* in case we didn't become paralyzed */ nomul(-1); + multi_reason = "opening a container"; nomovemsg = ""; } return 1; @@ -2629,6 +2631,7 @@ struct obj *box; /* or bag */ /* even if the trap fails, you've used up this turn */ if (multi >= 0) { /* in case we didn't become paralyzed */ nomul(-1); + multi_reason = "tipping a container"; nomovemsg = ""; } } else if (box->otyp == BAG_OF_TRICKS || box->otyp == HORN_OF_PLENTY) { diff --git a/src/polyself.c b/src/polyself.c index 3effba8b2..023b1f44a 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1285,6 +1285,7 @@ dogaze() -d((int)mtmp->m_lev+1, (int)mtmp->data->mattk[0].damd) : -200); + multi_reason = "frozen by a monster's gaze"; nomovemsg = 0; return 1; } else diff --git a/src/potion.c b/src/potion.c index 0af019181..86fdcdff8 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 potion.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 potion.c $NHDT-Date: 1426953330 2015/03/21 15:55:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.99 $ */ /* NetHack 3.5 potion.c $Date: 2013/11/05 00:57:55 $ $Revision: 1.91 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -375,6 +375,7 @@ ghost_from_bottle() if(flags.verbose) You("are frightened to death, and unable to move."); nomul(-3); + multi_reason = "being frightened to death"; nomovemsg = "You regain your composure."; } @@ -678,6 +679,7 @@ peffects(otmp) Your("%s are frozen to the %s!", makeplural(body_part(FOOT)), surface(u.ux, u.uy)); nomul(-(rn1(10, 25 - 12*bcsign(otmp)))); + multi_reason = "frozen by a potion"; nomovemsg = You_can_move_again; exercise(A_DEX, FALSE); } @@ -1053,7 +1055,7 @@ boolean useeit; const char *objphrase; /* "Your widget glows" or "Steed's saddle glows" */ { void FDECL((*func), (OBJ_P)) = 0; - const char *how = 0, *glowcolor = 0; + const char *glowcolor = 0; #define COST_alter (-2) #define COST_none (-1) int costchange = COST_none; @@ -1062,7 +1064,6 @@ const char *objphrase; /* "Your widget glows" or "Steed's saddle glows" */ if (!potion || potion->otyp != POT_WATER) return FALSE; if (potion->blessed) { - how = "softly glow"; if (targobj->cursed) { func = uncurse; glowcolor = NH_AMBER; @@ -1074,7 +1075,6 @@ const char *objphrase; /* "Your widget glows" or "Steed's saddle glows" */ altfmt = TRUE; /* "with a aura" */ } } else if (potion->cursed) { - how = "glow"; if (targobj->blessed) { func = unbless; glowcolor = "brown"; @@ -1467,6 +1467,7 @@ register struct obj *obj; if (!Free_action) { pline("%s seems to be holding you.", Something); nomul(-rnd(5)); + multi_reason = "frozen by a potion"; nomovemsg = You_can_move_again; exercise(A_DEX, FALSE); } else You("stiffen momentarily."); @@ -1476,6 +1477,7 @@ register struct obj *obj; if (!Free_action && !Sleep_resistance) { You_feel("rather tired."); nomul(-rnd(5)); + multi_reason = "sleeping off a magical draught"; nomovemsg = You_can_move_again; exercise(A_DEX, FALSE); } else You("yawn."); @@ -1664,8 +1666,8 @@ dodip() rider_cant_reach(); /* not skilled enough to reach */ } else { if (obj->otyp == POT_ACID) obj->in_use = 1; - (void) water_damage(obj, 0, TRUE); - if (obj->in_use) useup(obj); + if (water_damage(obj, 0, TRUE) != ER_DESTROYED && obj->in_use) + useup(obj); } return 1; } diff --git a/src/pray.c b/src/pray.c index ffdee9b49..20e5d348d 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 pray.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 pray.c $NHDT-Date: 1427670643 2015/03/29 23:10:43 $ $NHDT-Branch: master $:$NHDT-Revision: 1.69 $ */ /* NetHack 3.5 pray.c $Date: 2012/05/07 01:44:38 $ $Revision: 1.62 $ */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1269,6 +1269,7 @@ dosacrifice() dmon->mpeaceful = TRUE; You("are terrified, and unable to move."); nomul(-3); + multi_reason = "being terrified of a demon"; nomovemsg = 0; } else pline_The("%s.", demonless_msg); } @@ -1655,6 +1656,7 @@ dopray() } } nomul(-3); + multi_reason = "praying"; nomovemsg = "You finish your prayer."; afternmv = prayer_done; @@ -1817,6 +1819,7 @@ doturn() } } nomul(-5); + multi_reason = "trying to turn the monsters"; nomovemsg = You_can_move_again; return(1); } @@ -1860,26 +1863,70 @@ aligntyp alignment; return gnam; } +static const char *hallu_gods[] = { + "the Flying Spaghetti Monster", /* Church of the FSM */ + "Eris", /* Discordianism */ + "the Martians", /* every science fiction ever */ + "Xom", /* Crawl */ + "AnDoR dRaKoN", /* ADOM */ + "the Central Bank of Yendor", /* economics */ + "Tooth Fairy", /* real world(?) */ + "Om", /* Discworld */ + "Yawgmoth", /* Magic: the Gathering */ + "Morgoth", /* LoTR */ + "Cthulhu", /* Lovecraft */ + "the Ori", /* Stargate */ + "destiny", /* why not? */ + "your Friend the Computer", /* Paranoia */ +}; + /* hallucination handling for priest/minion names: select a random god iff character is hallucinating */ const char * halu_gname(alignment) aligntyp alignment; { - const char *gnam; + const char *gnam = NULL; int which; - if (!Hallucination) return align_gname(alignment); + if (!Hallucination) + return align_gname(alignment); - which = randrole(); - switch (rn2(3)) { - case 0: gnam = roles[which].lgod; break; - case 1: gnam = roles[which].ngod; break; - case 2: gnam = roles[which].cgod; break; - default: gnam = 0; break; /* lint suppression */ + /* The priest may not have initialized god names. If this is the + * case, and we roll priest, we need to try again. */ + do + which = randrole(); + while (!roles[which].lgod); + + switch (rn2(9)) { + case 0: + case 1: + gnam = roles[which].lgod; + break; + case 2: + case 3: + gnam = roles[which].ngod; + break; + case 4: + case 5: + gnam = roles[which].cgod; + break; + case 6: + case 7: + gnam = hallu_gods[rn2(sizeof hallu_gods / sizeof *hallu_gods)]; + break; + case 8: + gnam = Moloch; + break; + default: + impossible("rn2 broken in halu_gname?!?"); } - if (!gnam) gnam = Moloch; - if (*gnam == '_') ++gnam; + if (!gnam) { + impossible("No random god name?"); + gnam = "your Friend the Computer"; /* Paranoia */ + } + if (*gnam == '_') + ++gnam; return gnam; } diff --git a/src/priest.c b/src/priest.c index a28f2b8d4..0b520cfdf 100644 --- a/src/priest.c +++ b/src/priest.c @@ -475,6 +475,7 @@ int roomno; if (flags.verbose) You("are frightened to death, and unable to move."); nomul(-3); + multi_reason = "being terrified of a demon"; nomovemsg = "You regain your composure."; } } diff --git a/src/read.c b/src/read.c index 38f122af1..0aa007928 100644 --- a/src/read.c +++ b/src/read.c @@ -53,6 +53,115 @@ struct obj *sobj; (void) learnscrolltyp(sobj->otyp); } +char * +erode_obj_text(otmp, buf) +struct obj *otmp; +char *buf; +{ + int erosion = greatest_erosion(otmp); + if (erosion) + wipeout_text(buf, + (int)(strlen(buf) * erosion / (2*MAX_ERODE)), + otmp->o_id ^ (unsigned)ubirthday); + return buf; +} + +char * +tshirt_text(tshirt, buf) +struct obj *tshirt; +char *buf; +{ + static const char *shirt_msgs[] = { /* Scott Bigham */ + "I explored the Dungeons of Doom and all I got was this lousy T-shirt!", + "Is that Mjollnir in your pocket or are you just happy to see me?", + "It's not the size of your sword, it's how #enhance'd you are with it.", + "Madame Elvira's House O' Succubi Lifetime Customer", + "Madame Elvira's House O' Succubi Employee of the Month", + "Ludios Vault Guards Do It In Small, Dark Rooms", + "Yendor Military Soldiers Do It In Large Groups", + "I survived Yendor Military Boot Camp", + "Ludios Accounting School Intra-Mural Lacrosse Team", + "Oracle(TM) Fountains 10th Annual Wet T-Shirt Contest", + "Hey, black dragon! Disintegrate THIS!", + "I'm With Stupid -->", + "Don't blame me, I voted for Izchak!", + "Don't Panic", /* HHGTTG */ + "Furinkan High School Athletic Dept.", /* Ranma 1/2 */ + "Hel-LOOO, Nurse!", /* Animaniacs */ + "=^.^=", + "100% goblin hair - do not wash", + "Aberzombie and Fitch", + "cK -- Cockatrice touches the Kop", + "Don't ask me, I only adventure here", + "Down with pants!", + "d, your dog or a killer?", + "FREE PUG AND NEWT!", + "Go team ant!", + "Got newt?", + "Hello, my darlings!", /* Charlie Drake */ + "Hey! Nymphs! Steal This T-Shirt!", + "I <3 Dungeon of Doom", + "I <3 Maud", + "I am a Valkyrie. If you see me running, try to keep up.", + "I am not a pack rat - I am a collector", + "I bounced off a rubber tree", /* Monkey Island */ + "Plunder Island Brimstone Beach Club", /* Monkey Island */ + "If you can read this, I can hit you with my polearm", + "I'm confused!", + "I scored with the princess", + "I want to live forever or die in the attempt.", + "Lichen Park", + "LOST IN THOUGHT - please send search party", + "Meat is Mordor", + "Minetown Better Business Bureau", + "Minetown Watch", + "Ms. Palm's House of Negotiable Affection -- A Very Reputable House Of Disrepute", + "Protection Racketeer", + "Real men love Crom", + "Somebody stole my Mojo!", + "The Hellhound Gang", + "The Werewolves", + "They Might Be Storm Giants", + "Weapons don't kill people, I kill people", + "White Zombie", + "You're killing me!", + "Anhur State University - Home of the Fighting Fire Ants!", + "FREE HUGS", + "Serial Ascender", + "Real men are valkyries", + "Young Men's Cavedigging Association", + "Occupy Fort Ludios", + "I couldn't afford this T-shirt so I stole it!", + "Mind flayers suck", + "I'm not wearing any pants", + "Down with the living!", + "Pudding farmer", + "Vegetarian", + }; + Strcpy(buf, shirt_msgs[tshirt->o_id % SIZE(shirt_msgs)]); + return erode_obj_text(tshirt, buf); +} + +char * +apron_text(apron, buf) +struct obj *apron; +char *buf; +{ + static const char *apron_msgs[] = { + "Kiss the cook", + "I'm making SCIENCE!", + "Don't mess with the chef", + "Don't make me poison you", + "Gehennom's Kitchen", + "Rat: The other white meat", + "If you can't stand the heat, get out of Gehennom!", + "If we weren't meant to eat animals, why are they made out of meat?", + "If you don't like the food, I'll stab you", + }; + Strcpy(buf, apron_msgs[apron->o_id % SIZE(apron_msgs)]); + return erode_obj_text(apron, buf); +} + int doread() { @@ -72,34 +181,15 @@ doread() if (!Blind) u.uconduct.literate++; useup(scroll); return(1); - } else if (scroll->otyp == T_SHIRT) { - static const char *shirt_msgs[] = { /* Scott Bigham */ - "I explored the Dungeons of Doom and all I got was this lousy T-shirt!", - "Is that Mjollnir in your pocket or are you just happy to see me?", - "It's not the size of your sword, it's how #enhance'd you are with it.", - "Madame Elvira's House O' Succubi Lifetime Customer", - "Madame Elvira's House O' Succubi Employee of the Month", - "Ludios Vault Guards Do It In Small, Dark Rooms", - "Yendor Military Soldiers Do It In Large Groups", - "I survived Yendor Military Boot Camp", - "Ludios Accounting School Intra-Mural Lacrosse Team", - "Oracle(TM) Fountains 10th Annual Wet T-Shirt Contest", - "Hey, black dragon! Disintegrate THIS!", - "I'm With Stupid -->", - "Don't blame me, I voted for Izchak!", - "Don't Panic", /* HHGTTG */ - "Furinkan High School Athletic Dept.", /* Ranma 1/2 */ - "Hel-LOOO, Nurse!", /* Animaniacs */ - }; + } else if (scroll->otyp == T_SHIRT || + scroll->otyp == ALCHEMY_SMOCK) { char buf[BUFSZ]; - int erosion; - if (Blind) { You_cant("feel any Braille writing."); return 0; } /* can't read shirt worn under suit (under cloak is ok though) */ - if (uarm && scroll == uarmu) { + if (scroll->otyp == T_SHIRT && uarm && scroll == uarmu) { pline("%s shirt is obscured by %s%s.", scroll->unpaid ? "That" : "Your", shk_your(buf, uarm), suit_simple_name(uarm)); @@ -108,19 +198,96 @@ doread() u.uconduct.literate++; if(flags.verbose) pline("It reads:"); - Strcpy(buf, shirt_msgs[scroll->o_id % SIZE(shirt_msgs)]); - erosion = greatest_erosion(scroll); - if (erosion) - wipeout_text(buf, - (int)(strlen(buf) * erosion / (2*MAX_ERODE)), - scroll->o_id ^ (unsigned)ubirthday); - pline("\"%s\"", buf); + pline("\"%s\"", (scroll->otyp == T_SHIRT) + ? tshirt_text(scroll, buf) + : apron_text(scroll, buf)); + return 1; + } else if (scroll->otyp == CREDIT_CARD) { + static const char *card_msgs[] = { + "Leprechaun Gold Tru$t - Shamrock Card", + "Magic Memory Vault Charge Card", + "Larn National Bank", /* Larn */ + "First Bank of Omega", /* Omega */ + "Bank of Zork - Frobozz Magic Card", /* Zork */ + "Ankh-Morpork Merchant's Guild Barter Card", + "Ankh-Morpork Thieves' Guild Unlimited Transaction Card", + "Ransmannsby Moneylenders Association", + "Bank of Gehennom - 99% Interest Card", + "Yendorian Express - Copper Card", + "Yendorian Express - Silver Card", + "Yendorian Express - Gold Card", + "Yendorian Express - Mithril Card", + "Yendorian Express - Platinum Card", /* must be last */ + }; + if (Blind) { + You("feel the embossed numbers:"); + } else { + if(flags.verbose) + pline("It reads:"); + pline("\"%s\"", scroll->oartifact ? card_msgs[SIZE(card_msgs)-1] + : card_msgs[scroll->o_id % (SIZE(card_msgs)-1)]); + } + /* Make a credit card number */ + pline("\"%d0%d %d%d1 0%d%d0\"", ((scroll->o_id % 89)+10), (scroll->o_id % 4), + (((scroll->o_id * 499) % 899999) + 100000), (scroll->o_id % 10), + (!(scroll->o_id % 3)), ((scroll->o_id * 7) % 10)); + u.uconduct.literate++; + return 1; + } else if (scroll->otyp == CAN_OF_GREASE) { + pline("This %s has no label.", singular(scroll, xname)); + return 0; + } else if (scroll->otyp == MAGIC_MARKER) { + if (Blind) { + You_cant("feel any Braille writing."); + return 0; + } + if (flags.verbose) + pline("It reads:"); + pline("\"Magic Marker(TM) Red Ink Marker Pen. Water Soluble.\""); + u.uconduct.literate++; + return 1; + } else if (scroll->oclass == COIN_CLASS) { + if (Blind) + You("feel the embossed words:"); + else if (flags.verbose) + You("read:"); + pline("\"1 Zorkmid. 857 GUE. In Frobs We Trust.\""); + u.uconduct.literate++; + return 1; + } else if (scroll->oartifact == ART_ORB_OF_FATE) { + if (Blind) + You("feel the engraved signature:"); + else pline("It is signed:"); + pline("\"Odin.\""); + u.uconduct.literate++; + return 1; + } else if (scroll->otyp == CANDY_BAR) { + static const char *wrapper_msgs[] = { + "Apollo", /* Lost */ + "Moon Crunchy", /* South Park */ + "Snacky Cake", + "Chocolate Nuggie", + "The Small Bar", + "Crispy Yum Yum", + "Nilla Crunchie", + "Berry Bar", + "Choco Nummer", + "Om-nom", /* Cat Macro */ + "Fruity Oaty", /* Serenity */ + "Wonka Bar" /* Charlie and the Chocolate Factory */ + }; + if (Blind) { + You_cant("feel any Braille writing."); + return 0; + } + pline("The wrapper reads: \"%s\"", wrapper_msgs[scroll->o_id % SIZE(wrapper_msgs)]); + u.uconduct.literate++; return 1; } else if (scroll->oclass != SCROLL_CLASS && scroll->oclass != SPBOOK_CLASS) { pline(silly_thing_to, "read"); return(0); - } else if (Blind) { + } else if (Blind && (scroll->otyp != SPE_BOOK_OF_THE_DEAD)) { const char *what = 0; if (scroll->oclass == SPBOOK_CLASS) what = "mystic runes"; @@ -2033,7 +2200,7 @@ create_particular() { char buf[BUFSZ], *bufp, monclass; int which, tryct, i, firstchoice = NON_PM; - struct permonst *whichpm; + struct permonst *whichpm = NULL; struct monst *mtmp; boolean madeany = FALSE; boolean maketame, makepeaceful, makehostile; diff --git a/src/restore.c b/src/restore.c index 4e4502b53..4c4b049ce 100644 --- a/src/restore.c +++ b/src/restore.c @@ -446,6 +446,10 @@ boolean ghostly; if (mtmp->isshk) restshk(mtmp, ghostly); if (mtmp->ispriest) restpriest(mtmp, ghostly); + if (!ghostly) { + if (mtmp->m_id == context.polearm.m_id) + context.polearm.hitmon = mtmp; + } mtmp2 = mtmp; } if(first && mtmp2->nmon){ @@ -1140,9 +1144,9 @@ get_plname_from_file(fd, plbuf) int fd; char *plbuf; { - int rlen, pltmpsiz = 0; - rlen = read(fd, (genericptr_t) &pltmpsiz, sizeof(pltmpsiz)); - rlen = read(fd, (genericptr_t) plbuf, pltmpsiz); + int pltmpsiz = 0; + (void) read(fd, (genericptr_t) &pltmpsiz, sizeof(pltmpsiz)); + (void) read(fd, (genericptr_t) plbuf, pltmpsiz); return; } diff --git a/src/save.c b/src/save.c index 807ecd7dc..094f54042 100644 --- a/src/save.c +++ b/src/save.c @@ -1124,8 +1124,13 @@ register struct monst *mtmp; } if (mtmp->minvent) saveobjchn(fd,mtmp->minvent,mode); - if (release_data(mode)) + if (release_data(mode)) { + if (mtmp == context.polearm.hitmon) { + context.polearm.m_id = mtmp->m_id; + context.polearm.hitmon = NULL; + } dealloc_monst(mtmp); + } mtmp = mtmp2; } if (perform_bwrite(mode)) @@ -1291,6 +1296,7 @@ void freedynamicdata() { unload_qtlist(); + free_menu_coloring(); free_invbuf(); /* let_to_name (invent.c) */ free_youbuf(); /* You_buf,&c (pline.c) */ tmp_at(DISP_FREEMEM, 0); /* temporary display effects */ @@ -1316,6 +1322,7 @@ freedynamicdata() /* level-specific data */ free_timers(RANGE_LEVEL); free_light_sources(RANGE_LEVEL); + clear_regions(); freemonchn(fmon); free_worm(); /* release worm segment information */ freetrapchn(ftrap); diff --git a/src/sounds.c b/src/sounds.c index 6204847e8..f1dec986f 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -304,7 +304,11 @@ dosounds() static const char * const h_sounds[] = { "beep", "boing", "sing", "belche", "creak", "cough", "rattle", - "ululate", "pop", "jingle", "sniffle", "tinkle", "eep" + "ululate", "pop", "jingle", "sniffle", "tinkle", "eep", + "clatter", "hum", "sizzle", "twitter", "wheeze", "rustle", + "honk", "lisp", "yodel", "coo", "burp", "moo", "boom", + "murmur", "oink", "quack", "rumble", "twang", "bellow", + "toot", "gargle", "hoot", "warble" }; const char * @@ -706,6 +710,7 @@ register struct monst *mtmp; pline("%s rattles noisily.", Monnam(mtmp)); You("freeze for a moment."); nomul(-2); + multi_reason = "scared by rattling"; nomovemsg = 0; break; case MS_LAUGH: diff --git a/src/sp_lev.c b/src/sp_lev.c index c495d5c99..ed1b782c2 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 sp_lev.c $NHDT-Date: 1426465441 2015/03/16 00:24:01 $ $NHDT-Branch: debug $:$NHDT-Revision: 1.25 $ */ +/* NetHack 3.5 sp_lev.c $NHDT-Date: 1427934549 2015/04/02 00:29:09 $ $NHDT-Branch: master $:$NHDT-Revision: 1.40 $ */ /* NetHack 3.5 sp_lev.c $Date: 2011/01/05 01:28:36 $ $Revision: 1.23 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -18,25 +18,24 @@ extern void FDECL(mkmap, (lev_init *)); STATIC_DCL void FDECL(get_room_loc, (schar *, schar *, struct mkroom *)); -STATIC_DCL void FDECL(get_free_room_loc, (schar *, schar *, struct mkroom *)); +STATIC_DCL void FDECL(get_free_room_loc, (schar *, schar *, struct mkroom *, packed_coord)); STATIC_DCL void FDECL(create_trap, (trap *, struct mkroom *)); STATIC_DCL int FDECL(noncoalignment, (ALIGNTYP_P)); STATIC_DCL boolean FDECL(m_bad_boulder_spot, (int,int)); STATIC_DCL void FDECL(create_monster, (monster *, struct mkroom *)); STATIC_DCL void FDECL(create_object, (object *, struct mkroom *)); -STATIC_DCL void FDECL(create_engraving, (engraving *,struct mkroom *)); -STATIC_DCL void FDECL(create_stairs, (stair *, struct mkroom *)); STATIC_DCL void FDECL(create_altar, (altar *, struct mkroom *)); -STATIC_DCL void FDECL(create_gold, (gold *, struct mkroom *)); -STATIC_DCL void FDECL(create_feature, (int,int,struct mkroom *,int)); STATIC_DCL boolean FDECL(search_door, (struct mkroom *, xchar *, xchar *, XCHAR_P, int)); STATIC_DCL void NDECL(fix_stair_rooms); STATIC_DCL void FDECL(create_corridor, (corridor *)); +STATIC_DCL void NDECL(count_features); STATIC_DCL boolean FDECL(create_subroom, (struct mkroom *, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P)); +long FDECL(opvar_array_length, (struct sp_coder *)); + #define LEFT 1 #define H_LEFT 2 #define CENTER 3 @@ -57,11 +56,13 @@ STATIC_DCL boolean FDECL(create_subroom, (struct mkroom *, XCHAR_P, XCHAR_P, #define NewTab(type, size) (type **) alloc(sizeof(type *) * (unsigned)size) #define Free(ptr) if(ptr) free((genericptr_t) (ptr)) -static NEARDATA walk walklist[50]; +extern struct engr *head_engr; + extern int min_rx, max_rx, min_ry, max_ry; /* from mkmap.c */ -static char Map[COLNO][ROWNO]; -static char robjects[10], rloc_x[10], rloc_y[10], rmonst[10]; +/* positions touched by level elements explicitly defined in the des-file */ +static char SpLev_Map[COLNO][ROWNO]; + static aligntyp ralign[3] = { AM_CHAOTIC, AM_NEUTRAL, AM_LAWFUL }; static NEARDATA xchar xstart, ystart; static NEARDATA char xsize, ysize; @@ -69,24 +70,387 @@ static NEARDATA char xsize, ysize; STATIC_DCL void FDECL(set_wall_property, (XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P,int)); STATIC_DCL int NDECL(rnddoor); STATIC_DCL int NDECL(rndtrap); -STATIC_DCL void FDECL(get_location, (schar *,schar *,int)); -STATIC_DCL void FDECL(sp_lev_shuffle, (char *,char *,int)); +STATIC_DCL void FDECL(get_location, (schar *,schar *,int, struct mkroom *)); STATIC_DCL void FDECL(light_region, (region *)); -STATIC_DCL void FDECL(load_common_data, (dlb *,int)); -STATIC_DCL void FDECL(load_one_monster, (dlb *,monster *)); -STATIC_DCL void FDECL(load_one_object, (dlb *,object *)); -STATIC_DCL void FDECL(load_one_engraving, (dlb *,engraving *)); -STATIC_DCL boolean FDECL(load_rooms, (dlb *)); STATIC_DCL void FDECL(maze1xy, (coord *,int)); -STATIC_DCL boolean FDECL(load_maze, (dlb *)); +STATIC_DCL boolean FDECL(sp_level_loader, (dlb *, sp_lev *)); STATIC_DCL void FDECL(create_door, (room_door *, struct mkroom *)); -STATIC_DCL void FDECL(free_rooms,(room **, int)); -STATIC_DCL void FDECL(build_room, (room *, room*)); +struct mkroom * FDECL(build_room, (room *, struct mkroom *)); char *lev_message = 0; lev_region *lregions = 0; int num_lregions = 0; -lev_init init_lev; +boolean splev_init_present = FALSE; +boolean icedpools = FALSE; + +struct obj *container_obj[MAX_CONTAINMENT]; +int container_idx = 0; + +struct monst *invent_carrying_monster = NULL; + +#define SPLEV_STACK_RESERVE 128 + +void +solidify_map() +{ + xchar x, y; + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) + if (IS_STWALL(levl[x][y].typ) && !SpLev_Map[x][y]) + levl[x][y].wall_info |= (W_NONDIGGABLE|W_NONPASSWALL); +} + +void +splev_stack_init(st) + struct splevstack *st; +{ + if (st) { + st->depth = 0; + st->depth_alloc = SPLEV_STACK_RESERVE; + st->stackdata = (struct opvar **)alloc(st->depth_alloc * sizeof(struct opvar *)); + if (!st->stackdata) panic("stack init alloc"); + } +} + +void +splev_stack_done(st) + struct splevstack *st; +{ + if (st) { + int i; + + if (st->stackdata && st->depth) + for (i = 0; i < st->depth; i++) { + switch (st->stackdata[i]->spovartyp) { + default: + case SPOVAR_NULL: + case SPOVAR_COORD: + case SPOVAR_REGION: + case SPOVAR_MAPCHAR: + case SPOVAR_MONST: + case SPOVAR_OBJ: + case SPOVAR_INT: + break; + case SPOVAR_VARIABLE: + case SPOVAR_STRING: + case SPOVAR_SEL: + if (st->stackdata[i]->vardata.str) Free(st->stackdata[i]->vardata.str); + st->stackdata[i]->vardata.str = NULL; + break; + } + Free(st->stackdata[i]); + st->stackdata[i] = NULL; + } + + Free(st->stackdata); + st->stackdata = NULL; + st->depth = st->depth_alloc = 0; + Free(st); + } +} + +void +splev_stack_push(st, v) + struct splevstack *st; + struct opvar *v; +{ + if (!st || !v) return; + if (!st->stackdata) panic("splev_stack_push: no stackdata allocated?"); + + if (st->depth >= st->depth_alloc) { + struct opvar **tmp = (struct opvar **)alloc((st->depth_alloc + SPLEV_STACK_RESERVE) * sizeof(struct opvar *)); + if (!tmp) panic("stack push alloc"); + (void)memcpy(tmp, st->stackdata, st->depth_alloc * sizeof(struct opvar *)); + Free(st->stackdata); + st->stackdata = tmp; + st->depth_alloc += SPLEV_STACK_RESERVE; + } + + st->stackdata[st->depth] = v; + st->depth++; +} + +struct opvar * +splev_stack_pop(st) + struct splevstack *st; +{ + struct opvar *ret = NULL; + if (!st) return ret; + if (!st->stackdata) panic("splev_stack_pop: no stackdata allocated?"); + + if (st->depth) { + st->depth--; + ret = st->stackdata[st->depth]; + st->stackdata[st->depth] = NULL; + return ret; + } else impossible("splev_stack_pop: empty stack?"); + return ret; +} + +struct splevstack * +splev_stack_reverse(st) + struct splevstack *st; +{ + long i; + struct opvar *tmp; + if (!st) return NULL; + if (!st->stackdata) panic("splev_stack_reverse: no stackdata allocated?"); + for (i = 0; i < (st->depth / 2); i++) { + tmp = st->stackdata[i]; + st->stackdata[i] = st->stackdata[st->depth - i - 1]; + st->stackdata[st->depth - i - 1] = tmp; + } + return st; +} + +#define OV_typ(o) (o->spovartyp) +#define OV_i(o) (o->vardata.l) +#define OV_s(o) (o->vardata.str) + +#define OV_pop_i(x) (x = splev_stack_getdat(coder, SPOVAR_INT)) +#define OV_pop_c(x) (x = splev_stack_getdat(coder, SPOVAR_COORD)) +#define OV_pop_r(x) (x = splev_stack_getdat(coder, SPOVAR_REGION)) +#define OV_pop_s(x) (x = splev_stack_getdat(coder, SPOVAR_STRING)) +#define OV_pop(x) (x = splev_stack_getdat_any(coder)) +#define OV_pop_typ(x,typ) (x = splev_stack_getdat(coder, typ)) + + +struct opvar * +opvar_new_str(s) + char *s; +{ + struct opvar *tmpov = (struct opvar *)alloc(sizeof(struct opvar)); + if (!tmpov) panic("could not alloc opvar struct"); + tmpov->spovartyp = SPOVAR_STRING; + if (s) { + int len = strlen(s); + tmpov->vardata.str = (char *)alloc(len + 1); + if (!tmpov->vardata.str) panic("opvar new str alloc"); + (void)memcpy((genericptr_t)tmpov->vardata.str, + (genericptr_t)s, len); + tmpov->vardata.str[len] = '\0'; + } else + tmpov->vardata.str = NULL; + return tmpov; +} + +struct opvar * +opvar_new_int(i) + long i; +{ + struct opvar *tmpov = (struct opvar *)alloc(sizeof(struct opvar)); + if (!tmpov) panic("could not alloc opvar struct"); + tmpov->spovartyp = SPOVAR_INT; + tmpov->vardata.l = i; + return tmpov; +} + +struct opvar * +opvar_new_coord(x,y) + int x,y; +{ + struct opvar *tmpov = (struct opvar *)alloc(sizeof(struct opvar)); + if (!tmpov) panic("could not alloc opvar struct"); + tmpov->spovartyp = SPOVAR_COORD; + tmpov->vardata.l = SP_COORD_PACK(x,y); + return tmpov; +} + +struct opvar * +opvar_new_region(x1,y1,x2,y2) + int x1,y1,x2,y2; +{ + struct opvar *tmpov = (struct opvar *)alloc(sizeof(struct opvar)); + if (!tmpov) panic("could not alloc opvar struct"); + tmpov->spovartyp = SPOVAR_REGION; + tmpov->vardata.l = SP_REGION_PACK(x1,y1,x2,y2); + return tmpov; +} + +void +opvar_free_x(ov) + struct opvar *ov; +{ + if (!ov) return; + switch (ov->spovartyp) { + case SPOVAR_COORD: + case SPOVAR_REGION: + case SPOVAR_MAPCHAR: + case SPOVAR_MONST: + case SPOVAR_OBJ: + case SPOVAR_INT: + break; + case SPOVAR_VARIABLE: + case SPOVAR_STRING: + case SPOVAR_SEL: + Free(ov->vardata.str); + break; + default: impossible("Unknown opvar value type (%i)!", ov->spovartyp); + } + Free(ov); +} + +#define opvar_free(ov) { if (ov) { opvar_free_x(ov); ov = NULL; } else impossible("opvar_free(), %s", __FUNCTION__); } + +struct opvar * +opvar_clone(ov) + struct opvar *ov; +{ + struct opvar *tmpov; + if (!ov) panic("no opvar to clone"); + tmpov = (struct opvar *)alloc(sizeof(struct opvar)); + if (!tmpov) panic("could not alloc opvar struct"); + tmpov->spovartyp = ov->spovartyp; + switch (ov->spovartyp) { + case SPOVAR_COORD: + case SPOVAR_REGION: + case SPOVAR_MAPCHAR: + case SPOVAR_MONST: + case SPOVAR_OBJ: + case SPOVAR_INT: + tmpov->vardata.l = ov->vardata.l; + break; + case SPOVAR_VARIABLE: + case SPOVAR_STRING: + case SPOVAR_SEL: + tmpov->vardata.str = strdup(ov->vardata.str); + break; + default: impossible("Unknown push value type (%i)!", ov->spovartyp); + } + return tmpov; +} + + +struct opvar * +opvar_var_conversion(coder, ov) + struct sp_coder *coder; + struct opvar *ov; +{ + struct splev_var *tmp; + struct opvar *tmpov; + struct opvar *array_idx = NULL; + if (!coder || !ov) return NULL; + if (ov->spovartyp != SPOVAR_VARIABLE) return ov; + tmp = coder->frame->variables; + while (tmp) { + if (!strcmp(tmp->name, OV_s(ov))) { + if ((tmp->svtyp & SPOVAR_ARRAY)) { + array_idx = opvar_var_conversion(coder, splev_stack_pop(coder->stack)); + if (!array_idx || OV_typ(array_idx) != SPOVAR_INT) + panic("array idx not an int"); + if (tmp->array_len < 1) panic("array len < 1"); + OV_i(array_idx) = (OV_i(array_idx) % tmp->array_len); + tmpov = opvar_clone(tmp->data.arrayvalues[OV_i(array_idx)]); + return tmpov; + } else { + tmpov = opvar_clone(tmp->data.value); + return tmpov; + } + } + tmp = tmp->next; + } + return NULL; +} + +struct splev_var * +opvar_var_defined(coder, name) + struct sp_coder *coder; + char *name; +{ + struct splev_var *tmp; + if (!coder) return NULL; + tmp = coder->frame->variables; + while (tmp) { + if (!strcmp(tmp->name, name)) return tmp; + tmp = tmp->next; + } + return NULL; +} + +struct opvar * +splev_stack_getdat(coder, typ) + struct sp_coder *coder; + xchar typ; +{ + if (coder && coder->stack) { + struct opvar *tmp = splev_stack_pop(coder->stack); + if (!tmp) panic("no value type %i in stack.", typ); + if (tmp->spovartyp == SPOVAR_VARIABLE) + tmp = opvar_var_conversion(coder, tmp); + if (tmp->spovartyp == typ) + return tmp; + } + return NULL; +} + +struct opvar * +splev_stack_getdat_any(coder) + struct sp_coder *coder; +{ + if (coder && coder->stack) { + struct opvar *tmp = splev_stack_pop(coder->stack); + if (tmp && tmp->spovartyp == SPOVAR_VARIABLE) + tmp = opvar_var_conversion(coder, tmp); + return tmp; + } + return NULL; +} + + + +void +variable_list_del(varlist) + struct splev_var *varlist; +{ + struct splev_var *tmp = varlist; + if (!tmp) return; + while (tmp) { + Free(tmp->name); + if ((tmp->svtyp & SPOVAR_ARRAY)) { + long idx = tmp->array_len; + while (idx-- > 0) { + opvar_free(tmp->data.arrayvalues[idx]); + }; + Free(tmp->data.arrayvalues); + } else { + opvar_free(tmp->data.value); + } + tmp = varlist->next; + Free(varlist); + varlist = tmp; + } +} + +void +lvlfill_maze_grid(x1,y1,x2,y2,filling) +int x1,y1,x2,y2; +schar filling; +{ + int x,y; + + for (x = x1; x <= x2; x++) + for (y = y1; y <= y2; y++) { +#ifndef WALLIFIED_MAZE + levl[x][y].typ = STONE; +#else + levl[x][y].typ = + (y < 2 || ((x % 2) && (y % 2))) ? STONE : filling; +#endif + } +} + +void +lvlfill_solid(filling,lit) +schar filling; +schar lit; +{ + int x,y; + for (x = 2; x <= x_maze_max; x++) + for (y = 0; y <= y_maze_max; y++) { + SET_TYPLIT(x,y,filling,lit); + } +} + /* * Make walls of the area (x1, y1, x2, y2) non diggable/non passwall-able @@ -99,12 +463,105 @@ int prop; { register xchar x, y; - for(y = y1; y <= y2; y++) - for(x = x1; x <= x2; x++) - if(IS_STWALL(levl[x][y].typ)) + for(y = max(y1,0); y <= min(y2, ROWNO-1); y++) + for(x = max(x1,0); x <= min(x2,COLNO-1); x++) + if(IS_STWALL(levl[x][y].typ) || IS_TREE(levl[x][y].typ)) levl[x][y].wall_info |= prop; } +STATIC_OVL void +shuffle_alignments() +{ + int i; + aligntyp atmp; + /* shuffle 3 alignments */ + i = rn2(3); atmp=ralign[2]; ralign[2]=ralign[i]; ralign[i]=atmp; + if (rn2(2)) { atmp=ralign[1]; ralign[1]=ralign[0]; ralign[0]=atmp; } +} + +/* + * Count the different features (sinks, fountains) in the level. + */ +STATIC_OVL void +count_features() +{ + xchar x,y; + level.flags.nfountains = level.flags.nsinks = 0; + for (y = 0; y < ROWNO; y++) + for (x = 0; x < COLNO; x++) { + int typ = levl[x][y].typ; + if (typ == FOUNTAIN) + level.flags.nfountains++; + else if (typ == SINK) + level.flags.nsinks++; + } +} + +void +remove_boundary_syms() +{ + /* + * If any CROSSWALLs are found, must change to ROOM after REGION's + * are laid out. CROSSWALLS are used to specify "invisible" + * boundaries where DOOR syms look bad or aren't desirable. + */ + xchar x,y; + boolean has_bounds = FALSE; + for (x = 0; x < COLNO-1; x++) + for (y = 0; y < ROWNO-1; y++) + if (levl[x][y].typ == CROSSWALL) { + has_bounds = TRUE; + break; + } + if (has_bounds) { + for(x = 0; x < x_maze_max; x++) + for(y = 0; y < y_maze_max; y++) + if ((levl[x][y].typ == CROSSWALL) && SpLev_Map[x][y]) + levl[x][y].typ = ROOM; + } +} + + +void +maybe_add_door(x,y, droom) +int x,y; +struct mkroom *droom; +{ + if (droom->hx >= 0 && doorindex < DOORMAX && inside_room(droom, x,y)) + add_door(x, y, droom); +} + +void +link_doors_rooms() +{ + int x,y; + int tmpi, m; + for (y = 0; y < ROWNO; y++) + for (x = 0; x < COLNO; x++) + if (IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR) { + for (tmpi = 0; tmpi < nroom; tmpi++) { + maybe_add_door(x,y, &rooms[tmpi]); + for (m = 0; m < rooms[tmpi].nsubrooms; m++) { + maybe_add_door(x,y, rooms[tmpi].sbrooms[m]); + } + } + } +} + +void +fill_rooms() +{ + int tmpi; + for (tmpi = 0; tmpi < nroom; tmpi++) { + int m; + if (rooms[tmpi].needfill) + fill_room(&rooms[tmpi], (rooms[tmpi].needfill == 2)); + for (m = 0; m < rooms[tmpi].nsubrooms; m++) + if (rooms[tmpi].sbrooms[m]->needfill) + fill_room(rooms[tmpi].sbrooms[m], FALSE); + } +} + /* * Choose randomly the state (nodoor, open, closed or locked) for a door */ @@ -146,55 +603,74 @@ rndtrap() /* * Coordinates in special level files are handled specially: * - * if x or y is -11, we generate a random coordinate. - * if x or y is between -1 and -10, we read one from the corresponding - * register (x0, x1, ... x9). - * if x or y is nonnegative, we convert it from relative to the local map - * to global coordinates. + * if x or y is < 0, we generate a random coordinate. * The "humidity" flag is used to insure that engravings aren't * created underwater, or eels on dry land. */ -#define DRY 0x1 -#define WET 0x2 - STATIC_DCL boolean FDECL(is_ok_location, (SCHAR_P, SCHAR_P, int)); STATIC_OVL void -get_location(x, y, humidity) +get_location(x, y, humidity, croom) schar *x, *y; int humidity; +struct mkroom *croom; { int cpt = 0; + int mx, my, sx, sy; + + if (croom) { + mx = croom->lx; + my = croom->ly; + sx = croom->hx - mx + 1; + sy = croom->hy - my + 1; + } else { + mx = xstart; + my = ystart; + sx = xsize; + sy = ysize; + } if (*x >= 0) { /* normal locations */ - *x += xstart; - *y += ystart; - } else if (*x > -11) { /* special locations */ - *y = ystart + rloc_y[ - *y - 1]; - *x = xstart + rloc_x[ - *x - 1]; + *x += mx; + *y += my; } else { /* random location */ do { - *x = xstart + rn2((int)xsize); - *y = ystart + rn2((int)ysize); + if (croom) { /* handle irregular areas */ + coord tmpc; + somexy(croom, &tmpc); + *x = tmpc.x; + *y = tmpc.y; + } else { + *x = mx + rn2((int)sx); + *y = my + rn2((int)sy); + } if (is_ok_location(*x,*y,humidity)) break; } while (++cpt < 100); if (cpt >= 100) { register int xx, yy; /* last try */ - for (xx = 0; xx < xsize; xx++) - for (yy = 0; yy < ysize; yy++) { - *x = xstart + xx; - *y = ystart + yy; + for (xx = 0; xx < sx; xx++) + for (yy = 0; yy < sy; yy++) { + *x = mx + xx; + *y = my + yy; if (is_ok_location(*x,*y,humidity)) goto found_it; } - panic("get_location: can't find a place!"); + if (!(humidity & NO_LOC_WARN)) { + impossible("get_location: can't find a place!"); + } else { + *x = *y = -1; + } } } found_it:; - if (!isok(*x,*y)) { - impossible("get_location: (%d,%d) out of bounds", *x, *y); - *x = x_maze_max; *y = y_maze_max; + if (!(humidity & ANY_LOC) && !isok(*x,*y)) { + if (!(humidity & NO_LOC_WARN)) { + /*warning("get_location: (%d,%d) out of bounds", *x, *y);*/ + *x = x_maze_max; *y = y_maze_max; + } else { + *x = *y = -1; + } } } @@ -207,42 +683,58 @@ register int humidity; if (Is_waterlevel(&u.uz)) return TRUE; /* accept any spot */ + /* TODO: Should perhaps check if wall is diggable/passwall? */ + if (humidity & ANY_LOC) return TRUE; + + if ((humidity & SOLID) && IS_ROCK(levl[x][y].typ)) return TRUE; + if (humidity & DRY) { typ = levl[x][y].typ; if (typ == ROOM || typ == AIR || typ == CLOUD || typ == ICE || typ == CORR) return TRUE; } - if (humidity & WET) { - if (is_pool(x,y) || ((humidity & DRY) && is_lava(x,y))) - return TRUE; - } + if ((humidity & WET) && is_pool(x,y)) return TRUE; + if ((humidity & HOT) && is_lava(x,y)) return TRUE; return FALSE; } -/* - * Shuffle the registers for locations, objects or monsters - */ + +unpacked_coord +get_unpacked_coord(loc, defhumidity) + long loc; + int defhumidity; +{ + static unpacked_coord c; + + if (loc & SP_COORD_IS_RANDOM) { + c.x = c.y = -1; + c.is_random = 1; + c.getloc_flags = (loc & ~SP_COORD_IS_RANDOM); + if (!c.getloc_flags) c.getloc_flags = defhumidity; + } else { + c.is_random = 0; + c.getloc_flags = defhumidity; + c.x = SP_COORD_X(loc); + c.y = SP_COORD_Y(loc); + } + return c; +} STATIC_OVL void -sp_lev_shuffle(list1, list2, n) -char list1[], list2[]; -int n; +get_location_coord(x, y, humidity, croom, crd) +schar *x, *y; +int humidity; +struct mkroom *croom; +long crd; { - register int i, j; - register char k; - - for (i = n - 1; i > 0; i--) { - if ((j = rn2(i + 1)) == i) continue; - k = list1[j]; - list1[j] = list1[i]; - list1[i] = k; - if (list2) { - k = list2[j]; - list2[j] = list2[i]; - list2[i] = k; - } - } + unpacked_coord c; + c = get_unpacked_coord(crd, humidity); + *x = c.x; + *y = c.y; + get_location(x, y, c.getloc_flags | (c.is_random ? NO_LOC_WARN : 0), croom); + if (*x == -1 && *y == -1 && c.is_random) + get_location(x,y, humidity, croom); } /* @@ -279,20 +771,24 @@ struct mkroom *croom; */ STATIC_OVL void -get_free_room_loc(x,y, croom) +get_free_room_loc(x,y, croom, pos) schar *x, *y; struct mkroom *croom; +packed_coord pos; { schar try_x, try_y; register int trycnt = 0; - do { - try_x = *x, try_y = *y; - get_room_loc(&try_x, &try_y, croom); - } while (levl[try_x][try_y].typ != ROOM && ++trycnt <= 100); + get_location_coord(&try_x, &try_y, DRY, croom, pos); + if (levl[try_x][try_y].typ != ROOM) { + do { + try_x = *x, try_y = *y; + get_room_loc(&try_x, &try_y, croom); + } while (levl[try_x][try_y].typ != ROOM && ++trycnt <= 100); - if (trycnt > 100) - panic("get_free_room_loc: can't find a place!"); + if (trycnt > 100) + panic("get_free_room_loc: can't find a place!"); + } *x = try_x, *y = try_y; } @@ -390,7 +886,7 @@ xchar rtype, rlit; xtmp = x; ytmp = y; xaltmp = xal; yaltmp = yal; - /* First case : a totaly random room */ + /* First case : a totally random room */ if((xtmp < 0 && ytmp <0 && wtmp < 0 && xaltmp < 0 && yaltmp < 0) || vault) { @@ -571,8 +1067,8 @@ create_door(dd, broom) room_door *dd; struct mkroom *broom; { - int x, y; - int trycnt = 0; + int x = 0, y = 0; + int trycnt = 0, wtry = 0; if (dd->secret == -1) dd->secret = rn2(2); @@ -607,43 +1103,48 @@ struct mkroom *broom; dwall = 1 << rn2(4); dpos = dd->pos; - if (dpos == -1) /* The position is RANDOM */ - dpos = rn2((dwall == W_WEST || dwall == W_EAST) ? - (broom->hy - broom->ly + 1) : - (broom->hx - broom->lx + 1)); /* Convert wall and pos into an absolute coordinate! */ - - switch (dwall) { - case W_NORTH: + wtry = rn2(4); + switch (wtry) { + case 0: + if (!(dwall & W_NORTH)) goto redoloop; y = broom->ly - 1; - x = broom->lx + dpos; - break; - case W_SOUTH: + x = broom->lx + ((dpos == -1) ? rn2(1+(broom->hx - broom->lx)) : dpos); + if (IS_ROCK(levl[x][y-1].typ)) goto redoloop; + goto outdirloop; + case 1: + if (!(dwall & W_SOUTH)) goto redoloop; y = broom->hy + 1; - x = broom->lx + dpos; - break; - case W_WEST: + x = broom->lx + ((dpos == -1) ? rn2(1+(broom->hx - broom->lx)) : dpos); + if (IS_ROCK(levl[x][y+1].typ)) goto redoloop; + goto outdirloop; + case 2: + if (!(dwall & W_WEST)) goto redoloop; x = broom->lx - 1; - y = broom->ly + dpos; - break; - case W_EAST: + y = broom->ly + ((dpos == -1) ? rn2(1+(broom->hy - broom->ly)) : dpos); + if (IS_ROCK(levl[x-1][y].typ)) goto redoloop; + goto outdirloop; + case 3: + if (!(dwall & W_EAST)) goto redoloop; x = broom->hx + 1; - y = broom->ly + dpos; - break; + y = broom->ly + ((dpos == -1) ? rn2(1+(broom->hy - broom->ly)) : dpos); + if (IS_ROCK(levl[x+1][y].typ)) goto redoloop; + goto outdirloop; default: x = y = 0; panic("create_door: No wall for door!"); - break; + goto outdirloop; } +outdirloop: if (okdoor(x,y)) break; +redoloop: ; } while (++trycnt <= 100); if (trycnt > 100) { impossible("create_door: Can't find a proper place!"); return; } - add_door(x,y,broom); levl[x][y].typ = (dd->secret ? SDOOR : DOOR); levl[x][y].doormask = dd->mask; } @@ -681,7 +1182,6 @@ create_secret_door(croom, walls) if(okdoor(sx,sy)) { levl[sx][sy].typ = SDOOR; levl[sx][sy].doormask = D_CLOSED; - add_door(sx,sy,croom); return; } } @@ -701,19 +1201,20 @@ struct mkroom *croom; schar x,y; coord tm; - if (rn2(100) < t->chance) { - x = t->x; - y = t->y; - if (croom) - get_free_room_loc(&x, &y, croom); - else - get_location(&x, &y, DRY); + if (croom) + get_free_room_loc(&x, &y, croom, t->coord); + else { + int trycnt = 0; + do { + get_location_coord(&x, &y, DRY, croom, t->coord); + } while ((levl[x][y].typ == STAIRS || levl[x][y].typ == LADDER) && ++trycnt <= 100); + if (trycnt > 100) return; + } tm.x = x; tm.y = y; mktrap(t->type, 1, (struct mkroom*) 0, &tm); - } } /* @@ -765,12 +1266,9 @@ struct mkroom *croom; struct permonst *pm; unsigned g_mvflags; - if (rn2(100) < m->chance) { if (m->class >= 0) class = (char) def_char_to_monclass((char)m->class); - else if (m->class > -11) - class = (char) def_char_to_monclass(rmonst[- m->class - 1]); else class = 0; @@ -781,7 +1279,7 @@ struct mkroom *croom; Align2amask(u.ualignbase[A_ORIGINAL]) : (m->align == AM_SPLEV_NONCO) ? Align2amask(noncoalignment(u.ualignbase[A_ORIGINAL])) : - (m->align <= -11) ? induced_align(80) : + (m->align <= -(MAX_REGISTERS+1)) ? induced_align(80) : (m->align < 0 ? ralign[-m->align-1] : m->align); if (!class) @@ -790,7 +1288,7 @@ struct mkroom *croom; pm = &mons[m->id]; g_mvflags = (unsigned) mvitals[monsndx(pm)].mvflags; if ((pm->geno & G_UNIQ) && (g_mvflags & G_EXTINCT)) - goto m_done; + return; else if (g_mvflags & G_GONE) /* genocided or extinct */ pm = (struct permonst *) 0; /* make random monster */ } else { @@ -802,23 +1300,27 @@ struct mkroom *croom; (Race_if(PM_DWARF) || Race_if(PM_GNOME)) && rn2(3)) pm = (struct permonst *) 0; - x = m->x; - y = m->y; - if (croom) - get_room_loc(&x, &y, croom); - else { - if (!pm || !is_swimmer(pm)) - get_location(&x, &y, DRY); - else if (pm->mlet == S_EEL) - get_location(&x, &y, WET); - else - get_location(&x, &y, DRY|WET); + if (pm) { + int loc = DRY; + if (pm->mlet == S_EEL || amphibious(pm) || is_swimmer(pm)) loc = WET; + if (is_flyer(pm) || is_floater(pm)) loc |= (HOT | WET); + if (passes_walls(pm) || noncorporeal(pm)) loc |= SOLID; + if (flaming(pm)) loc |= HOT; + /* If water-liking monster, first try is without DRY */ + get_location_coord(&x, &y, loc|NO_LOC_WARN, croom, m->coord); + if (x == -1 && y == -1) { + loc |= DRY; + get_location_coord(&x, &y, loc, croom, m->coord); + } + } else { + get_location_coord(&x, &y, DRY, croom, m->coord); } + /* try to find a close place if someone else is already there */ if (MON_AT(x,y) && enexto(&cc, x, y, pm)) x = cc.x, y = cc.y; - if(m->align != -12) + if(m->align != -(MAX_REGISTERS+2)) mtmp = mk_roamer(pm, Amask2align(amask), x, y, m->peaceful); else if(PM_ARCHEOLOGIST <= m->id && m->id <= PM_WIZARD) mtmp = mk_mplayer(pm, x, y, FALSE); @@ -826,6 +1328,7 @@ struct mkroom *croom; if (mtmp) { x = mtmp->mx, y = mtmp->my; /* sanity precaution */ + m->x = x, m->y = y; /* handle specific attributes for some special monsters */ if (m->name.str) mtmp = christen_monst(mtmp, m->name.str); @@ -833,7 +1336,7 @@ struct mkroom *croom; * This is currently hardwired for mimics only. It should * eventually be expanded. */ - if (m->appear_as.str && mtmp->data->mlet == S_MIMIC) { + if (m->appear_as.str && ((mtmp->data->mlet == S_MIMIC) || mtmp->cham)) { int i; switch (m->appear) { @@ -879,10 +1382,7 @@ struct mkroom *croom; do { x = m->x; y = m->y; - if (croom) - get_room_loc(&x, &y, croom); - else - get_location(&x, &y, DRY); + get_location(&x, &y, DRY, croom); if (MON_AT(x,y) && enexto(&cc, x, y, pm)) x = cc.x, y = cc.y; } while (m_bad_boulder_spot(x, y) && @@ -896,8 +1396,38 @@ struct mkroom *croom; break; case M_AP_MONSTER: - /* note: mimics don't appear as monsters! */ - /* (but chameleons can :-) */ + { + int mndx; + if (!strcmpi(m->appear_as.str, "random")) + mndx = select_newcham_form(mtmp); + else + mndx = name_to_mon(m->appear_as.str); + if ((mndx != NON_PM) && (&mons[mndx] != mtmp->data)) { + struct permonst *mdat = &mons[mndx]; + struct permonst *olddata = mtmp->data; + /* this code duplicated from newcham() */ + if(is_male(mdat)) { + if(mtmp->female) mtmp->female = FALSE; + } else if (is_female(mdat)) { + if(!mtmp->female) mtmp->female = TRUE; + } else if (!is_neuter(mdat)) { + if(!rn2(10)) mtmp->female = !mtmp->female; + } + set_mon_data(mtmp, mdat, 0); + if (emits_light(olddata) != emits_light(mtmp->data)) { + /* used to give light, now doesn't, or vice versa, + or light's range has changed */ + if (emits_light(olddata)) + del_light_source(LS_MONSTER, (genericptr_t)mtmp); + if (emits_light(mtmp->data)) + new_light_source(mtmp->mx, mtmp->my, emits_light(mtmp->data), + LS_MONSTER, (genericptr_t)mtmp); + } + if (!mtmp->perminvis || pm_invisible(olddata)) + mtmp->perminvis = pm_invisible(mdat); + } + } + break; default: impossible( "create_monster: unimplemented mon appear type [%d,\"%s\"]", @@ -924,12 +1454,35 @@ struct mkroom *croom; mtmp->msleeping = m->asleep; #endif } + if (m->seentraps) mtmp->mtrapseen = m->seentraps; + if (m->female) mtmp->female = 1; + if (m->cancelled) mtmp->mcan = 1; + if (m->revived) mtmp->mrevived = 1; + if (m->avenge) mtmp->mavenge = 1; + if (m->stunned) mtmp->mstun = 1; + if (m->confused) mtmp->mconf = 1; + if (m->invis) { + mtmp->minvis = mtmp->perminvis = 1; + } + if (m->blinded) { + mtmp->mcansee = 0; + mtmp->mblinded = (m->blinded % 127); + } + if (m->paralyzed) { + mtmp->mcanmove = 0; + mtmp->mfrozen = (m->paralyzed % 127); + } + if (m->fleeing) { + mtmp->mflee = 1; + mtmp->mfleetim = (m->fleeing % 127); + } + + if (m->has_invent) { + discard_minvent(mtmp); + invent_carrying_monster = mtmp; + } } - } /* if (rn2(100) < m->chance) */ - m_done: - Free(m->name.str); - Free(m->appear_as.str); } /* @@ -946,19 +1499,12 @@ struct mkroom *croom; char c; boolean named; /* has a name been supplied in level description? */ - if (rn2(100) < o->chance) { named = o->name.str ? TRUE : FALSE; - x = o->x; y = o->y; - if (croom) - get_room_loc(&x, &y, croom); - else - get_location(&x, &y, DRY); + get_location_coord(&x, &y, DRY, croom, o->coord); if (o->class >= 0) c = o->class; - else if (o->class > -11) - c = robjects[ -(o->class+1)]; else c = 0; @@ -998,34 +1544,89 @@ struct mkroom *croom; if (o->corpsenm != NON_PM) { if (o->corpsenm == NON_PM - 1) set_corpsenm(otmp, rndmonnum()); - else set_corpsenm(otmp, o->corpsenm); + else set_corpsenm(otmp, o->corpsenm); } /* set_corpsenm() took care of egg hatch and corpse timers */ if (named) otmp = oname(otmp, o->name.str); - switch(o->containment) { - static struct obj *container = 0; + if (o->eroded) { + if (o->eroded < 0) otmp->oerodeproof = 1; + else { + otmp->oeroded = (o->eroded % 4); + otmp->oeroded2 = ((o->eroded >> 2) % 4); + } + } + if (o->recharged) otmp->recharged = (o->recharged % 8); + if (o->locked) otmp->olocked = 1; + else if (o->broken) { + otmp->obroken = 1; + otmp->olocked = 0; /* obj generation may set */ + } + if (o->trapped) otmp->otrapped = 1; + if (o->greased) otmp->greased = 1; +#ifdef INVISIBLE_OBJECTS + if (o->invis) otmp->oinvis = 1; +#endif - /* contents */ - case 1: - if (!container) { - impossible("create_object: no container"); - break; + if ((o->quan > 0) && objects[otmp->otyp].oc_merge) { + otmp->quan = o->quan; + otmp->owt = weight(otmp); + } + + /* contents */ + if (o->containment & SP_OBJ_CONTENT) { + if (!container_idx) { + if (!invent_carrying_monster) { + /*impossible("create_object: no container");*/ + /* don't complain, the monster may be gone legally + (eg. unique demon already generated) + TODO: In the case of unique demon lords, they should + get their inventories even when they get generated + outside the des-file. Maybe another data file that + determines what inventories monsters get by default? + */ + } else { + int ci; + struct obj *objcheck = otmp; + int inuse = -1; + + for (ci = 0; ci < container_idx; ci++) + if (container_obj[ci] == objcheck) + inuse = ci; + remove_object(otmp); + if (mpickobj(invent_carrying_monster, otmp)) { + if (inuse > -1) { + impossible( + "container given to monster was merged or deallocated."); + for (ci = inuse; ci < container_idx - 1; ci++) + container_obj[ci] = container_obj[ci + 1]; + container_obj[container_idx] = NULL; + container_idx--; + } + /* we lost track of it. */ + return; + } } + } else { remove_object(otmp); - (void) add_to_container(container, otmp); - goto o_done; /* don't stack, but do other cleanup */ - /* container */ - case 2: - delete_contents(otmp); - container = otmp; - break; - /* nothing */ - case 0: break; - - default: impossible("containment type %d?", (int) o->containment); + if (container_obj[container_idx-1]) + (void) add_to_container(container_obj[container_idx-1], otmp); + else { + obj_extract_self(otmp); + obfree(otmp, NULL); + return; + } + } + } + /* container */ + if (o->containment & SP_OBJ_CONTAINER) { + delete_contents(otmp); + if (container_idx < MAX_CONTAINMENT) { + container_obj[container_idx] = otmp; + container_idx++; + } else impossible("create_object: too deeply nested containers."); } /* Medusa level special case: statues are petrified monsters, so they @@ -1037,29 +1638,35 @@ struct mkroom *croom; struct monst *was; struct obj *obj; int wastyp; + int i = 0; /* prevent endless loop in case makemon always fails */ /* Named random statues are of player types, and aren't stone- * resistant (if they were, we'd have to reset the name as well as * setting corpsenm). */ - for (wastyp = otmp->corpsenm; ; wastyp = rndmonnum()) { + for (wastyp = otmp->corpsenm; i < 1000 ; i++, wastyp = rndmonnum()) { /* makemon without rndmonst() might create a group */ was = makemon(&mons[wastyp], 0, 0, MM_NOCOUNTBIRTH); - if (!resists_ston(was)) { + if (was) { + if (!resists_ston(was)) { (void) propagate(wastyp, TRUE, FALSE); break; + } + mongone(was); + was = NULL; } + } + if (was) { + set_corpsenm(otmp, wastyp); + while(was->minvent) { + obj = was->minvent; + obj->owornmask = 0; + obj_extract_self(obj); + (void) add_to_container(otmp, obj); + } + otmp->owt = weight(otmp); mongone(was); } - set_corpsenm(otmp, wastyp); - while(was->minvent) { - obj = was->minvent; - obj->owornmask = 0; - obj_extract_self(obj); - (void) add_to_container(otmp, obj); - } - otmp->owt = weight(otmp); - mongone(was); } /* Nasty hack here: try to determine if this is the Mines or Sokoban @@ -1076,46 +1683,18 @@ struct mkroom *croom; stackobj(otmp); - } /* if (rn2(100) < o->chance) */ - o_done: - Free(o->name.str); -} + if (o->lit) { + begin_burn(otmp, FALSE); + } -/* - * Randomly place a specific engraving, then release its memory. - */ -STATIC_OVL void -create_engraving(e, croom) -engraving *e; -struct mkroom *croom; -{ - xchar x, y; + if (o->buried) { + boolean dealloced; + (void) bury_an_obj(otmp, &dealloced); + if (dealloced && container_idx) { + container_obj[container_idx-1] = NULL; + } + } - x = e->x, y = e->y; - if (croom) - get_room_loc(&x, &y, croom); - else - get_location(&x, &y, DRY); - - make_engr_at(x, y, e->engr.str, 0L, e->etype); - free((genericptr_t) e->engr.str); -} - -/* - * Create stairs in a room. - * - */ - -STATIC_OVL void -create_stairs(s,croom) -stair *s; -struct mkroom *croom; -{ - schar x,y; - - x = s->x; y = s->y; - get_free_room_loc(&x, &y, croom); - mkstairs(x,y,(char)s->up, croom); } /* @@ -1130,16 +1709,14 @@ create_altar(a, croom) schar sproom,x,y; aligntyp amask; boolean croom_is_temple = TRUE; - int oldtyp; - - x = a->x; y = a->y; + int oldtyp; if (croom) { - get_free_room_loc(&x, &y, croom); + get_free_room_loc(&x, &y, croom, a->coord); if (croom->rtype != TEMPLE) croom_is_temple = FALSE; } else { - get_location(&x, &y, DRY); + get_location_coord(&x, &y, DRY, croom, a->coord); if ((sproom = (schar) *in_rooms(x, y, TEMPLE)) != 0) croom = &rooms[sproom - ROOMOFFSET]; else @@ -1151,9 +1728,6 @@ create_altar(a, croom) if (oldtyp == STAIRS || oldtyp == LADDER) return; - a->x = x; - a->y = y; - /* Is the alignment random ? * If so, it's an 80% chance that the altar will be co-aligned. * @@ -1166,7 +1740,7 @@ create_altar(a, croom) Align2amask(u.ualignbase[A_ORIGINAL]) : (a->align == AM_SPLEV_NONCO) ? Align2amask(noncoalignment(u.ualignbase[A_ORIGINAL])) : - (a->align == -11) ? induced_align(80) : + (a->align == -(MAX_REGISTERS+1)) ? induced_align(80) : (a->align < 0 ? ralign[-a->align-1] : a->align); levl[x][y].typ = ALTAR; @@ -1174,11 +1748,6 @@ create_altar(a, croom) if (a->shrine < 0) a->shrine = rn2(2); /* handle random case */ - if (oldtyp == FOUNTAIN) - level.flags.nfountains--; - else if (oldtyp == SINK) - level.flags.nsinks--; - if (!croom_is_temple || !a->shrine) return; if (a->shrine) { /* Is it a shrine or sanctum? */ @@ -1188,68 +1757,29 @@ create_altar(a, croom) } } -/* - * Create a gold pile in a room. - */ -STATIC_OVL void -create_gold(g,croom) -gold *g; -struct mkroom *croom; +void +replace_terrain(terr, croom) +replaceterrain *terr; +struct mkroom *croom; { - schar x,y; + schar x, y, x1, y1, x2, y2; - x = g->x; y= g->y; - if (croom) - get_room_loc(&x, &y, croom); - else - get_location(&x, &y, DRY); + if (terr->toter >= MAX_TYPE) return; - if (g->amount == -1) - g->amount = rnd(200); - (void) mkgold((long) g->amount, x, y); + x1 = terr->x1; y1 = terr->y1; + get_location(&x1, &y1, ANY_LOC, croom); + + x2 = terr->x2; y2 = terr->y2; + get_location(&x2, &y2, ANY_LOC, croom); + + for (x = max(x1,0); x <= min(x2,COLNO-1); x++) + for (y = max(y1,0); y <= min(y2,ROWNO-1); y++) + if ((levl[x][y].typ == terr->fromter) && (rn2(100) < terr->chance)) { + SET_TYPLIT(x,y, terr->toter, terr->tolit); + } } -/* - * Create a feature (e.g a fountain) in a room. - */ - -STATIC_OVL void -create_feature(fx, fy, croom, typ) -int fx, fy; -struct mkroom *croom; -int typ; -{ - schar x,y; - int trycnt = 0; - - x = fx; y = fy; - if (croom) { - if (x < 0 && y < 0) - do { - x = -1; y = -1; - get_room_loc(&x, &y, croom); - } while (++trycnt <= 200 && occupied(x,y)); - else - get_room_loc(&x, &y, croom); - if(trycnt > 200) - return; - } else { - get_location(&x, &y, DRY); - } - /* Don't cover up an existing feature (particularly randomly - placed stairs). However, if the _same_ feature is already - here, it came from the map drawing and we still need to - update the special counters. */ - if (IS_FURNITURE(levl[x][y].typ) && levl[x][y].typ != typ) - return; - - levl[x][y].typ = typ; - if (typ == FOUNTAIN) - level.flags.nfountains++; - else if (typ == SINK) - level.flags.nsinks++; -} /* * Search for a door in a room on a specified wall. @@ -1463,9 +1993,8 @@ corridor *c; coord org, dest; if (c->src.room == -1) { - sort_rooms(); fix_stair_rooms(); - makecorridors(); + makecorridors(); /*makecorridors(c->src.door);*/ return; } @@ -1559,154 +2088,37 @@ boolean prefilled; } } -STATIC_OVL void -free_rooms(ro, n) -room **ro; -int n; -{ - short j; - room *r; - while(n--) { - r = ro[n]; - Free(r->name); - Free(r->parent); - if ((j = r->ndoor) != 0) { - while(j--) - Free(r->doors[j]); - Free(r->doors); - } - if ((j = r->nstair) != 0) { - while(j--) - Free(r->stairs[j]); - Free(r->stairs); - } - if ((j = r->naltar) != 0) { - while (j--) - Free(r->altars[j]); - Free(r->altars); - } - if ((j = r->nfountain) != 0) { - while(j--) - Free(r->fountains[j]); - Free(r->fountains); - } - if ((j = r->nsink) != 0) { - while(j--) - Free(r->sinks[j]); - Free(r->sinks); - } - if ((j = r->npool) != 0) { - while(j--) - Free(r->pools[j]); - Free(r->pools); - } - if ((j = r->ntrap) != 0) { - while (j--) - Free(r->traps[j]); - Free(r->traps); - } - if ((j = r->nmonster) != 0) { - while (j--) - Free(r->monsters[j]); - Free(r->monsters); - } - if ((j = r->nobject) != 0) { - while (j--) - Free(r->objects[j]); - Free(r->objects); - } - if ((j = r->ngold) != 0) { - while(j--) - Free(r->golds[j]); - Free(r->golds); - } - if ((j = r->nengraving) != 0) { - while (j--) - Free(r->engravings[j]); - Free(r->engravings); - } - Free(r); - } - Free(ro); -} - -STATIC_OVL void -build_room(r, pr) -room *r, *pr; +struct mkroom * +build_room(r, mkr) +room *r; +struct mkroom *mkr; { boolean okroom; struct mkroom *aroom; - short i; xchar rtype = (!r->chance || rn2(100) < r->chance) ? r->rtype : OROOM; - if(pr) { + if(mkr) { aroom = &subrooms[nsubroom]; - okroom = create_subroom(pr->mkr, r->x, r->y, r->w, r->h, + okroom = create_subroom(mkr, r->x, r->y, r->w, r->h, rtype, r->rlit); } else { aroom = &rooms[nroom]; okroom = create_room(r->x, r->y, r->w, r->h, r->xalign, r->yalign, rtype, r->rlit); - r->mkr = aroom; } if (okroom) { - /* Create subrooms if necessary... */ - for(i=0; i < r->nsubroom; i++) - build_room(r->subrooms[i], r); - /* And now we can fill the room! */ - - /* Priority to the stairs */ - - for(i=0; i nstair; i++) - create_stairs(r->stairs[i], aroom); - - /* Then to the various elements (sinks, etc..) */ - for(i = 0; insink; i++) - create_feature(r->sinks[i]->x, r->sinks[i]->y, aroom, SINK); - for(i = 0; inpool; i++) - create_feature(r->pools[i]->x, r->pools[i]->y, aroom, POOL); - for(i = 0; infountain; i++) - create_feature(r->fountains[i]->x, r->fountains[i]->y, - aroom, FOUNTAIN); - for(i = 0; inaltar; i++) - create_altar(r->altars[i], aroom); - for(i = 0; indoor; i++) - create_door(r->doors[i], aroom); - - /* The traps */ - for(i = 0; intrap; i++) - create_trap(r->traps[i], aroom); - - /* The monsters */ - for(i = 0; inmonster; i++) - create_monster(r->monsters[i], aroom); - - /* The objects */ - for(i = 0; inobject; i++) - create_object(r->objects[i], aroom); - - /* The gold piles */ - for(i = 0; ingold; i++) - create_gold(r->golds[i], aroom); - - /* The engravings */ - for (i = 0; i < r->nengraving; i++) - create_engraving(r->engravings[i], aroom); - #ifdef SPECIALIZATION - topologize(aroom,FALSE); /* set roomno */ + topologize(aroom,FALSE); /* set roomno */ #else - topologize(aroom); /* set roomno */ + topologize(aroom); /* set roomno */ #endif - /* MRS - 07/04/91 - This is temporary but should result - * in proper filling of shops, etc. - * DLC - this can fail if corridors are added to this room - * at a later point. Currently no good way to fix this. - */ - if(aroom->rtype != OROOM && r->filled) fill_room(aroom, FALSE); + aroom->needfill = r->filled; + aroom->needjoining = r->joined; + return aroom; } + return (struct mkroom *)0; } /* @@ -1740,328 +2152,29 @@ light_region(tmpregion) } } -/* initialization common to all special levels */ -STATIC_OVL void -load_common_data(fd, typ) -dlb *fd; -int typ; +void +wallify_map(x1,y1,x2,y2) +int x1,y1,x2,y2; { - uchar n; - long lev_flags; - int i; + int x, y, xx, yy, lo_xx, lo_yy, hi_xx, hi_yy; - { - aligntyp atmp; - /* shuffle 3 alignments; can't use sp_lev_shuffle() on aligntyp's */ - i = rn2(3); atmp=ralign[2]; ralign[2]=ralign[i]; ralign[i]=atmp; - if (rn2(2)) { atmp=ralign[1]; ralign[1]=ralign[0]; ralign[0]=atmp; } - } - - level.flags.is_maze_lev = typ == SP_LEV_MAZE; - - /* Read the level initialization data */ - Fread((genericptr_t) &init_lev, 1, sizeof(lev_init), fd); - if(init_lev.init_present) { - if(init_lev.lit < 0) - init_lev.lit = rn2(2); - mkmap(&init_lev); - } - - /* Read the per level flags */ - Fread((genericptr_t) &lev_flags, 1, sizeof(lev_flags), fd); - if (lev_flags & NOTELEPORT) - level.flags.noteleport = 1; - if (lev_flags & HARDFLOOR) - level.flags.hardfloor = 1; - if (lev_flags & NOMMAP) - level.flags.nommap = 1; - if (lev_flags & SHORTSIGHTED) - level.flags.shortsighted = 1; - if (lev_flags & ARBOREAL) - level.flags.arboreal = 1; - - /* Read message */ - Fread((genericptr_t) &n, 1, sizeof(n), fd); - if (n) { - lev_message = (char *) alloc(n + 1); - Fread((genericptr_t) lev_message, 1, (int) n, fd); - lev_message[n] = 0; - } -} - -STATIC_OVL void -load_one_monster(fd, m) -dlb *fd; -monster *m; -{ - int size; - - Fread((genericptr_t) m, 1, sizeof *m, fd); - if ((size = m->name.len) != 0) { - m->name.str = (char *) alloc((unsigned)size + 1); - Fread((genericptr_t) m->name.str, 1, size, fd); - m->name.str[size] = '\0'; - } else - m->name.str = (char *) 0; - if ((size = m->appear_as.len) != 0) { - m->appear_as.str = (char *) alloc((unsigned)size + 1); - Fread((genericptr_t) m->appear_as.str, 1, size, fd); - m->appear_as.str[size] = '\0'; - } else - m->appear_as.str = (char *) 0; -} - -STATIC_OVL void -load_one_object(fd, o) -dlb *fd; -object *o; -{ - int size; - - Fread((genericptr_t) o, 1, sizeof *o, fd); - if ((size = o->name.len) != 0) { - o->name.str = (char *) alloc((unsigned)size + 1); - Fread((genericptr_t) o->name.str, 1, size, fd); - o->name.str[size] = '\0'; - } else - o->name.str = (char *) 0; -} - -STATIC_OVL void -load_one_engraving(fd, e) -dlb *fd; -engraving *e; -{ - int size; - - Fread((genericptr_t) e, 1, sizeof *e, fd); - size = e->engr.len; - e->engr.str = (char *) alloc((unsigned)size+1); - Fread((genericptr_t) e->engr.str, 1, size, fd); - e->engr.str[size] = '\0'; -} - -STATIC_OVL boolean -load_rooms(fd) -dlb *fd; -{ - xchar nrooms, ncorr; - char n; - short size; - corridor tmpcor; - room** tmproom; - int i, j; - - load_common_data(fd, SP_LEV_ROOMS); - - Fread((genericptr_t) &n, 1, sizeof(n), fd); /* nrobjects */ - if (n) { - Fread((genericptr_t)robjects, sizeof(*robjects), n, fd); - sp_lev_shuffle(robjects, (char *)0, (int)n); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); /* nrmonst */ - if (n) { - Fread((genericptr_t)rmonst, sizeof(*rmonst), n, fd); - sp_lev_shuffle(rmonst, (char *)0, (int)n); - } - - Fread((genericptr_t) &nrooms, 1, sizeof(nrooms), fd); - /* Number of rooms to read */ - tmproom = NewTab(room,nrooms); - for (i=0;i 0) { /* Yup, it does! */ - r->name = (char *) alloc((unsigned)size + 1); - Fread((genericptr_t) r->name, 1, size, fd); - r->name[size] = 0; - } else - r->name = (char *) 0; - - /* Let's see if this room has a parent */ - Fread((genericptr_t) &size, 1, sizeof(size), fd); - if (size > 0) { /* Yup, it does! */ - r->parent = (char *) alloc((unsigned)size + 1); - Fread((genericptr_t) r->parent, 1, size, fd); - r->parent[size] = 0; - } else - r->parent = (char *) 0; - - Fread((genericptr_t) &r->x, 1, sizeof(r->x), fd); - /* x pos on the grid (1-5) */ - Fread((genericptr_t) &r->y, 1, sizeof(r->y), fd); - /* y pos on the grid (1-5) */ - Fread((genericptr_t) &r->w, 1, sizeof(r->w), fd); - /* width of the room */ - Fread((genericptr_t) &r->h, 1, sizeof(r->h), fd); - /* height of the room */ - Fread((genericptr_t) &r->xalign, 1, sizeof(r->xalign), fd); - /* horizontal alignment */ - Fread((genericptr_t) &r->yalign, 1, sizeof(r->yalign), fd); - /* vertical alignment */ - Fread((genericptr_t) &r->rtype, 1, sizeof(r->rtype), fd); - /* type of room (zoo, shop, etc.) */ - Fread((genericptr_t) &r->chance, 1, sizeof(r->chance), fd); - /* chance of room being special. */ - Fread((genericptr_t) &r->rlit, 1, sizeof(r->rlit), fd); - /* lit or not ? */ - Fread((genericptr_t) &r->filled, 1, sizeof(r->filled), fd); - /* to be filled? */ - r->nsubroom= 0; - - /* read the doors */ - Fread((genericptr_t) &r->ndoor, 1, sizeof(r->ndoor), fd); - if ((n = r->ndoor) != 0) - r->doors = NewTab(room_door, n); - while(n--) { - r->doors[(int)n] = New(room_door); - Fread((genericptr_t) r->doors[(int)n], 1, - sizeof(room_door), fd); - } - - /* read the stairs */ - Fread((genericptr_t) &r->nstair, 1, sizeof(r->nstair), fd); - if ((n = r->nstair) != 0) - r->stairs = NewTab(stair, n); - while (n--) { - r->stairs[(int)n] = New(stair); - Fread((genericptr_t) r->stairs[(int)n], 1, - sizeof(stair), fd); - } - - /* read the altars */ - Fread((genericptr_t) &r->naltar, 1, sizeof(r->naltar), fd); - if ((n = r->naltar) != 0) - r->altars = NewTab(altar, n); - while (n--) { - r->altars[(int)n] = New(altar); - Fread((genericptr_t) r->altars[(int)n], 1, - sizeof(altar), fd); - } - - /* read the fountains */ - Fread((genericptr_t) &r->nfountain, 1, - sizeof(r->nfountain), fd); - if ((n = r->nfountain) != 0) - r->fountains = NewTab(fountain, n); - while (n--) { - r->fountains[(int)n] = New(fountain); - Fread((genericptr_t) r->fountains[(int)n], 1, - sizeof(fountain), fd); - } - - /* read the sinks */ - Fread((genericptr_t) &r->nsink, 1, sizeof(r->nsink), fd); - if ((n = r->nsink) != 0) - r->sinks = NewTab(sink, n); - while (n--) { - r->sinks[(int)n] = New(sink); - Fread((genericptr_t) r->sinks[(int)n], 1, sizeof(sink), fd); - } - - /* read the pools */ - Fread((genericptr_t) &r->npool, 1, sizeof(r->npool), fd); - if ((n = r->npool) != 0) - r->pools = NewTab(pool,n); - while (n--) { - r->pools[(int)n] = New(pool); - Fread((genericptr_t) r->pools[(int)n], 1, sizeof(pool), fd); - } - - /* read the traps */ - Fread((genericptr_t) &r->ntrap, 1, sizeof(r->ntrap), fd); - if ((n = r->ntrap) != 0) - r->traps = NewTab(trap, n); - while(n--) { - r->traps[(int)n] = New(trap); - Fread((genericptr_t) r->traps[(int)n], 1, sizeof(trap), fd); - } - - /* read the monsters */ - Fread((genericptr_t) &r->nmonster, 1, sizeof(r->nmonster), fd); - if ((n = r->nmonster) != 0) { - r->monsters = NewTab(monster, n); - while(n--) { - r->monsters[(int)n] = New(monster); - load_one_monster(fd, r->monsters[(int)n]); - } - } else - r->monsters = 0; - - /* read the objects, in same order as mazes */ - Fread((genericptr_t) &r->nobject, 1, sizeof(r->nobject), fd); - if ((n = r->nobject) != 0) { - r->objects = NewTab(object, n); - for (j = 0; j < n; ++j) { - r->objects[j] = New(object); - load_one_object(fd, r->objects[j]); - } - } else - r->objects = 0; - - /* read the gold piles */ - Fread((genericptr_t) &r->ngold, 1, sizeof(r->ngold), fd); - if ((n = r->ngold) != 0) - r->golds = NewTab(gold, n); - while (n--) { - r->golds[(int)n] = New(gold); - Fread((genericptr_t) r->golds[(int)n], 1, sizeof(gold), fd); - } - - /* read the engravings */ - Fread((genericptr_t) &r->nengraving, 1, - sizeof(r->nengraving), fd); - if ((n = r->nengraving) != 0) { - r->engravings = NewTab(engraving,n); - while (n--) { - r->engravings[(int)n] = New(engraving); - load_one_engraving(fd, r->engravings[(int)n]); - } - } else - r->engravings = 0; - - } - - /* Now that we have loaded all the rooms, search the - * subrooms and create the links. - */ - - for (i = 0; iparent) { - /* Search the parent room */ - for(j=0; jname && !strcmp(tmproom[j]->name, - tmproom[i]->parent)) { - n = tmproom[j]->nsubroom++; - tmproom[j]->subrooms[(int)n] = tmproom[i]; - break; + for (y = y1; y <= y2; y++) { + lo_yy = (y > 0) ? y - 1 : 0; + hi_yy = (y < y2) ? y + 1 : y2; + for (x = x1; x <= x2; x++) { + if (levl[x][y].typ != STONE) continue; + lo_xx = (x > 0) ? x - 1 : 0; + hi_xx = (x < x2) ? x + 1 : x2; + for (yy = lo_yy; yy <= hi_yy; yy++) + for (xx = lo_xx; xx <= hi_xx; xx++) + if (IS_ROOM(levl[xx][yy].typ) || + levl[xx][yy].typ == CROSSWALL) { + levl[x][y].typ = (yy != y) ? HWALL : VWALL; + yy = hi_yy; /* end `yy' loop */ + break; /* end `xx' loop */ } } - - /* - * Create the rooms now... - */ - - for (i=0; i < nrooms; i++) - if(!tmproom[i]->parent) - build_room(tmproom[i], (room *) 0); - - free_rooms(tmproom, nrooms); - - /* read the corridors */ - - Fread((genericptr_t) &ncorr, sizeof(ncorr), 1, fd); - for (i=0; ix = (xchar)x, m->y = (xchar)y; } /* - * The Big Thing: special maze loader + * If there's a significant portion of maze unused by the special level, + * we don't want it empty. * - * Could be cleaner, but it works. + * Makes the number of traps, monsters, etc. proportional + * to the size of the maze. */ - -STATIC_OVL boolean -load_maze(fd) -dlb *fd; +STATIC_OVL void +fill_empty_maze() { - xchar x, y, typ; - boolean prefilled, room_not_needed; + int mapcountmax, mapcount, mapfact; + xchar x,y; + coord mm; - char n, numpart = 0; - xchar nwalk = 0, nwalk_sav; - schar filling; - char halign, valign; - - int xi, dir, size; - coord mm; - int mapcount, mapcountmax, mapfact; - - lev_region tmplregion; - region tmpregion; - door tmpdoor; - trap tmptrap; - monster tmpmons; - object tmpobj; - drawbridge tmpdb; - walk tmpwalk; - digpos tmpdig; - lad tmplad; - stair tmpstair, prevstair; - altar tmpaltar; - gold tmpgold; - fountain tmpfountain; - engraving tmpengraving; - xchar mustfill[(MAXNROFROOMS+1)*2]; - struct trap *badtrap; - boolean has_bounds; - boolean bounds_nodigpass; - - (void) memset((genericptr_t)&Map[0][0], 0, sizeof Map); - load_common_data(fd, SP_LEV_MAZE); - - /* Initialize map */ - Fread((genericptr_t) &filling, 1, sizeof(filling), fd); - if (!init_lev.init_present) { /* don't init if mkmap() has been called */ - for(x = 2; x <= x_maze_max; x++) - for(y = 0; y <= y_maze_max; y++) - if (filling == -1) { -#ifndef WALLIFIED_MAZE - levl[x][y].typ = STONE; -#else - levl[x][y].typ = - (y < 2 || ((x % 2) && (y % 2))) ? STONE : HWALL; -#endif - } else { - levl[x][y].typ = filling; - } - } - - /* if filling with stone, surrounding stone may all be nondig, nonpass */ - bounds_nodigpass = (filling == STONE); - - /* Start reading the file */ - Fread((genericptr_t) &numpart, 1, sizeof(numpart), fd); - /* Number of parts */ - if (!numpart || numpart > 9) - panic("load_maze error: numpart = %d", (int) numpart); - - while (numpart--) { - Fread((genericptr_t) &halign, 1, sizeof(halign), fd); - /* Horizontal alignment */ - Fread((genericptr_t) &valign, 1, sizeof(valign), fd); - /* Vertical alignment */ - Fread((genericptr_t) &xsize, 1, sizeof(xsize), fd); - /* size in X */ - Fread((genericptr_t) &ysize, 1, sizeof(ysize), fd); - /* size in Y */ - switch((int) halign) { - /* mkmap always creates levels starting at x==1 */ - case LEFT: xstart = init_lev.init_present ? 1 : 3; break; - case H_LEFT: xstart = 2+((x_maze_max-2-xsize)/4); break; - case CENTER: xstart = 2+((x_maze_max-2-xsize)/2); break; - case H_RIGHT: xstart = 2+((x_maze_max-2-xsize)*3/4); break; - case RIGHT: xstart = x_maze_max-xsize-1; break; - } - switch((int) valign) { - case TOP: ystart = 3; break; - case CENTER: ystart = 2+((y_maze_max-2-ysize)/2); break; - case BOTTOM: ystart = y_maze_max-ysize-1; break; - } - if (!(xstart % 2)) xstart++; - if (!(ystart % 2)) ystart++; - if ((ystart < 0) || (ystart + ysize > ROWNO)) { - /* try to move the start a bit */ - ystart += (ystart > 0) ? -2 : 2; - if(ysize == ROWNO) ystart = 0; - if(ystart < 0 || ystart + ysize > ROWNO) - panic("reading special level with ysize too large"); - } - - /* - * If any CROSSWALLs are found, must change to ROOM after REGION's - * are laid out. CROSSWALLS are used to specify "invisible" - * boundaries where DOOR syms look bad or aren't desirable. - */ - has_bounds = FALSE; - - if(init_lev.init_present && xsize <= 1 && ysize <= 1) { - xstart = 1; - ystart = 0; - xsize = COLNO-1; - ysize = ROWNO; - bounds_nodigpass = FALSE; - } else { - /* Load the map */ - for(y = ystart; y < ystart+ysize; y++) - for(x = xstart; x < xstart+xsize; x++) { - levl[x][y].typ = Fgetc(fd); - levl[x][y].lit = FALSE; - /* clear out levl: load_common_data may set them */ - levl[x][y].flags = 0; - levl[x][y].horizontal = 0; - levl[x][y].roomno = 0; - levl[x][y].edge = 0; - /* - * Note: Even though levl[x][y].typ is type schar, - * lev_comp.y saves it as type char. Since schar != char - * all the time we must make this exception or hack - * through lev_comp.y to fix. - */ - - /* - * Set secret doors to closed (why not trapped too?). Set - * the horizontal bit. - */ - if (levl[x][y].typ == SDOOR || IS_DOOR(levl[x][y].typ)) { - if(levl[x][y].typ == SDOOR) - levl[x][y].doormask = D_CLOSED; - /* - * If there is a wall to the left that connects to a - * (secret) door, then it is horizontal. This does - * not allow (secret) doors to be corners of rooms. - */ - if (x != xstart && (IS_WALL(levl[x-1][y].typ) || - levl[x-1][y].horizontal)) - levl[x][y].horizontal = 1; - } else if(levl[x][y].typ == HWALL || - levl[x][y].typ == IRONBARS) - levl[x][y].horizontal = 1; - else if(levl[x][y].typ == LAVAPOOL) - levl[x][y].lit = 1; - else if (init_lev.init_present && levl[x][y].typ == ICE) - levl[x][y].icedpool = init_lev.icedpools ? ICED_POOL : - ICED_MOAT; - else if(levl[x][y].typ == CROSSWALL) - has_bounds = TRUE; - Map[x][y] = 1; - } - if (init_lev.init_present && init_lev.joined) - remove_rooms(xstart, ystart, xstart+xsize, ystart+ysize); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of level regions */ - if(n) { - if(num_lregions) { - /* realloc the lregion space to add the new ones */ - /* don't really free it up until the whole level is done */ - lev_region *newl = (lev_region *) alloc(sizeof(lev_region) * - (unsigned)(n+num_lregions)); - (void) memcpy((genericptr_t)(newl+n), (genericptr_t)lregions, - sizeof(lev_region) * num_lregions); - Free(lregions); - num_lregions += n; - lregions = newl; - } else { - num_lregions = n; - lregions = (lev_region *) - alloc(sizeof(lev_region) * (unsigned)n); - } - } - - while(n--) { - Fread((genericptr_t) &tmplregion, sizeof(tmplregion), 1, fd); - if ((size = tmplregion.rname.len) != 0) { - tmplregion.rname.str = (char *) alloc((unsigned)size + 1); - Fread((genericptr_t) tmplregion.rname.str, size, 1, fd); - tmplregion.rname.str[size] = '\0'; - } else - tmplregion.rname.str = (char *) 0; - if(!tmplregion.in_islev) { - get_location(&tmplregion.inarea.x1, &tmplregion.inarea.y1, - DRY|WET); - get_location(&tmplregion.inarea.x2, &tmplregion.inarea.y2, - DRY|WET); - } - if(!tmplregion.del_islev) { - get_location(&tmplregion.delarea.x1, &tmplregion.delarea.y1, - DRY|WET); - get_location(&tmplregion.delarea.x2, &tmplregion.delarea.y2, - DRY|WET); - } - lregions[(int)n] = tmplregion; - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Random objects */ - if(n) { - Fread((genericptr_t)robjects, sizeof(*robjects), (int) n, fd); - sp_lev_shuffle(robjects, (char *)0, (int)n); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Random locations */ - if(n) { - Fread((genericptr_t)rloc_x, sizeof(*rloc_x), (int) n, fd); - Fread((genericptr_t)rloc_y, sizeof(*rloc_y), (int) n, fd); - sp_lev_shuffle(rloc_x, rloc_y, (int)n); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Random monsters */ - if(n) { - Fread((genericptr_t)rmonst, sizeof(*rmonst), (int) n, fd); - sp_lev_shuffle(rmonst, (char *)0, (int)n); - } - - (void) memset((genericptr_t)mustfill, 0, sizeof(mustfill)); - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of subrooms */ - while(n--) { - register struct mkroom *troom; - - Fread((genericptr_t)&tmpregion, 1, sizeof(tmpregion), fd); - - if(tmpregion.rtype > MAXRTYPE) { - tmpregion.rtype -= MAXRTYPE+1; - prefilled = TRUE; - } else - prefilled = FALSE; - - if(tmpregion.rlit < 0) - tmpregion.rlit = (rnd(1+abs(depth(&u.uz))) < 11 && rn2(77)) - ? TRUE : FALSE; - - get_location(&tmpregion.x1, &tmpregion.y1, DRY|WET); - get_location(&tmpregion.x2, &tmpregion.y2, DRY|WET); - - /* for an ordinary room, `prefilled' is a flag to force - an actual room to be created (such rooms are used to - control placement of migrating monster arrivals) */ - room_not_needed = (tmpregion.rtype == OROOM && - !tmpregion.rirreg && !prefilled); - if (room_not_needed || nroom >= MAXNROFROOMS) { - if (!room_not_needed) - impossible("Too many rooms on new level!"); - light_region(&tmpregion); - continue; - } - - troom = &rooms[nroom]; - - /* mark rooms that must be filled, but do it later */ - if (tmpregion.rtype != OROOM) - mustfill[nroom] = (prefilled ? 2 : 1); - - if(tmpregion.rirreg) { - min_rx = max_rx = tmpregion.x1; - min_ry = max_ry = tmpregion.y1; - flood_fill_rm(tmpregion.x1, tmpregion.y1, - nroom+ROOMOFFSET, tmpregion.rlit, TRUE); - add_room(min_rx, min_ry, max_rx, max_ry, - FALSE, tmpregion.rtype, TRUE); - troom->rlit = tmpregion.rlit; - troom->irregular = TRUE; - } else { - add_room(tmpregion.x1, tmpregion.y1, - tmpregion.x2, tmpregion.y2, - tmpregion.rlit, tmpregion.rtype, TRUE); -#ifdef SPECIALIZATION - topologize(troom,FALSE); /* set roomno */ -#else - topologize(troom); /* set roomno */ -#endif - } - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of doors */ - while(n--) { - struct mkroom *croom = &rooms[0]; - - Fread((genericptr_t)&tmpdoor, 1, sizeof(tmpdoor), fd); - - x = tmpdoor.x; y = tmpdoor.y; - typ = tmpdoor.mask == -1 ? rnddoor() : tmpdoor.mask; - - get_location(&x, &y, DRY); - if(levl[x][y].typ != SDOOR) - levl[x][y].typ = DOOR; - else { - if(typ < D_CLOSED) - typ = D_CLOSED; /* force it to be closed */ - } - levl[x][y].doormask = typ; - - /* Now the complicated part, list it with each subroom */ - /* The dog move and mail daemon routines use this */ - while(croom->hx >= 0 && doorindex < DOORMAX) { - if(croom->hx >= x-1 && croom->lx <= x+1 && - croom->hy >= y-1 && croom->ly <= y+1) { - /* Found it */ - add_door(x, y, croom); - } - croom++; - } - } - - /* now that we have rooms _and_ associated doors, fill the rooms */ - for(n = 0; n < SIZE(mustfill); n++) - if(mustfill[(int)n]) - fill_room(&rooms[(int)n], (mustfill[(int)n] == 2)); - - /* if special boundary syms (CROSSWALL) in map, remove them now */ - if(has_bounds) { - for(x = xstart; x < xstart+xsize; x++) - for(y = ystart; y < ystart+ysize; y++) - if(levl[x][y].typ == CROSSWALL) - levl[x][y].typ = ROOM; - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of drawbridges */ - while(n--) { - Fread((genericptr_t)&tmpdb, 1, sizeof(tmpdb), fd); - - x = tmpdb.x; y = tmpdb.y; - get_location(&x, &y, DRY|WET); - - typ = tmpdb.db_open; - if (typ == 127) typ = rn2(2); /* 0 => closed, 1 => open */ - if (!create_drawbridge(x, y, tmpdb.dir, typ)) - impossible("Cannot create drawbridge."); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of mazewalks */ - while(n--) { - Fread((genericptr_t)&tmpwalk, 1, sizeof(tmpwalk), fd); - - get_location(&tmpwalk.x, &tmpwalk.y, DRY|WET); - - walklist[nwalk++] = tmpwalk; - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of non_diggables */ - while(n--) { - Fread((genericptr_t)&tmpdig, 1, sizeof(tmpdig), fd); - - get_location(&tmpdig.x1, &tmpdig.y1, DRY|WET); - get_location(&tmpdig.x2, &tmpdig.y2, DRY|WET); - - set_wall_property(tmpdig.x1, tmpdig.y1, - tmpdig.x2, tmpdig.y2, W_NONDIGGABLE); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of non_passables */ - while(n--) { - Fread((genericptr_t)&tmpdig, 1, sizeof(tmpdig), fd); - - get_location(&tmpdig.x1, &tmpdig.y1, DRY|WET); - get_location(&tmpdig.x2, &tmpdig.y2, DRY|WET); - - set_wall_property(tmpdig.x1, tmpdig.y1, - tmpdig.x2, tmpdig.y2, W_NONPASSWALL); - } - - /* walk bounds, reset bounds_nodigpass diggable or passable */ - if (bounds_nodigpass) { - for (x = xstart; x < xstart+xsize; x++) { - if (!IS_STWALL(levl[x][ystart].typ) || - (levl[x][ystart].wall_info & - (W_NONDIGGABLE|W_NONPASSWALL)) != - (W_NONDIGGABLE|W_NONPASSWALL) || - !IS_STWALL(levl[x][ystart+ysize-1].typ) || - (levl[x][ystart+ysize-1].wall_info & - (W_NONDIGGABLE|W_NONPASSWALL)) != - (W_NONDIGGABLE|W_NONPASSWALL)) { - bounds_nodigpass = FALSE; - break; - } - } - } - if (bounds_nodigpass) { - for(y = ystart; y < ystart+ysize; y++) { - if (!IS_STWALL(levl[xstart][y].typ) || - (levl[xstart][y].wall_info & - (W_NONDIGGABLE|W_NONPASSWALL)) != - (W_NONDIGGABLE|W_NONPASSWALL) || - !IS_STWALL(levl[xstart+xsize-1][y].typ) || - (levl[xstart+xsize-1][y].wall_info & - (W_NONDIGGABLE|W_NONPASSWALL)) != - (W_NONDIGGABLE|W_NONPASSWALL)) { - bounds_nodigpass = FALSE; - break; - } - } - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of ladders */ - while(n--) { - Fread((genericptr_t)&tmplad, 1, sizeof(tmplad), fd); - - x = tmplad.x; y = tmplad.y; - get_location(&x, &y, DRY); - - levl[x][y].typ = LADDER; - if (tmplad.up == 1) { - xupladder = x; yupladder = y; - levl[x][y].ladder = LA_UP; - } else { - xdnladder = x; ydnladder = y; - levl[x][y].ladder = LA_DOWN; - } - } - - prevstair.x = prevstair.y = 0; - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of stairs */ - while(n--) { - Fread((genericptr_t)&tmpstair, 1, sizeof(tmpstair), fd); - - xi = 0; - do { - x = tmpstair.x; y = tmpstair.y; - get_location(&x, &y, DRY); - } while(prevstair.x && xi++ < 100 && - distmin(x,y,prevstair.x,prevstair.y) <= 8); - if ((badtrap = t_at(x,y)) != 0) deltrap(badtrap); - mkstairs(x, y, (char)tmpstair.up, (struct mkroom *)0); - prevstair.x = x; - prevstair.y = y; - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of altars */ - while(n--) { - Fread((genericptr_t)&tmpaltar, 1, sizeof(tmpaltar), fd); - - create_altar(&tmpaltar, (struct mkroom *)0); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of fountains */ - while (n--) { - Fread((genericptr_t)&tmpfountain, 1, sizeof(tmpfountain), fd); - - create_feature(tmpfountain.x, tmpfountain.y, - (struct mkroom *)0, FOUNTAIN); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of traps */ - while(n--) { - Fread((genericptr_t)&tmptrap, 1, sizeof(tmptrap), fd); - - create_trap(&tmptrap, (struct mkroom *)0); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of monsters */ - while(n--) { - load_one_monster(fd, &tmpmons); - - create_monster(&tmpmons, (struct mkroom *)0); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of objects */ - while(n--) { - load_one_object(fd, &tmpobj); - - create_object(&tmpobj, (struct mkroom *)0); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of gold piles */ - while (n--) { - Fread((genericptr_t)&tmpgold, 1, sizeof(tmpgold), fd); - - create_gold(&tmpgold, (struct mkroom *)0); - } - - Fread((genericptr_t) &n, 1, sizeof(n), fd); - /* Number of engravings */ - while(n--) { - load_one_engraving(fd, &tmpengraving); - - create_engraving(&tmpengraving, (struct mkroom *)0); - } - - } /* numpart loop */ - - nwalk_sav = nwalk; - while(nwalk--) { - x = (xchar) walklist[nwalk].x; - y = (xchar) walklist[nwalk].y; - dir = walklist[nwalk].dir; - - /* don't use move() - it doesn't use W_NORTH, etc. */ - switch (dir) { - case W_NORTH: --y; break; - case W_SOUTH: y++; break; - case W_EAST: x++; break; - case W_WEST: --x; break; - default: panic("load_maze: bad MAZEWALK direction"); - } - - if(!IS_DOOR(levl[x][y].typ)) { -#ifndef WALLIFIED_MAZE - levl[x][y].typ = CORR; -#else - levl[x][y].typ = ROOM; -#endif - levl[x][y].flags = 0; - } - - /* - * We must be sure that the parity of the coordinates for - * walkfrom() is odd. But we must also take into account - * what direction was chosen. - */ - if(!(x % 2)) { - if (dir == W_EAST) - x++; - else - x--; - - /* no need for IS_DOOR check; out of map bounds */ -#ifndef WALLIFIED_MAZE - levl[x][y].typ = CORR; -#else - levl[x][y].typ = ROOM; -#endif - levl[x][y].flags = 0; - } - - if (!(y % 2)) { - if (dir == W_SOUTH) - y++; - else - y--; - } - - walkfrom(x, y); - } - wallification(1, 0, COLNO-1, ROWNO-1); - - /* - * If there's a significant portion of maze unused by the special level, - * we don't want it empty. - * - * Makes the number of traps, monsters, etc. proportional - * to the size of the maze. - */ mapcountmax = mapcount = (x_maze_max - 2) * (y_maze_max - 2); + mapcountmax = mapcountmax / 2; for(x = 2; x < x_maze_max; x++) for(y = 0; y < y_maze_max; y++) - if(Map[x][y]) mapcount--; + if(SpLev_Map[x][y]) mapcount--; - if (nwalk_sav && (mapcount > (int) (mapcountmax / 10))) { + if ((mapcount > (int) (mapcountmax / 10))) { mapfact = (int) ((mapcount * 100L) / mapcountmax); for(x = rnd((int) (20 * mapfact) / 100); x; x--) { maze1xy(&mm, DRY); @@ -2684,7 +2241,7 @@ dlb *fd; (void) makemon(&mons[PM_MINOTAUR], mm.x, mm.y, NO_MM_FLAGS); } for(x = rnd((int) (12 * mapfact) / 100); x; x--) { - maze1xy(&mm, WET|DRY); + maze1xy(&mm, DRY); (void) makemon((struct permonst *) 0, mm.x, mm.y, NO_MM_FLAGS); } for(x = rn2((int) (15 * mapfact) / 100); x; x--) { @@ -2703,17 +2260,2837 @@ dlb *fd; (void) maketrap(mm.x, mm.y, trytrap); } } +} + +/* + * special level loader + */ +STATIC_OVL boolean +sp_level_loader(fd, lvl) +dlb *fd; +sp_lev *lvl; +{ + long n_opcode = 0; + struct opvar *opdat; + int opcode; + + Fread((genericptr_t)&(lvl->n_opcodes), 1, sizeof(lvl->n_opcodes), fd); + + lvl->opcodes = (_opcode *)alloc(sizeof(_opcode) * (lvl->n_opcodes)); + if (!lvl->opcodes) panic("sp lvl load opcodes alloc"); + while (n_opcode < lvl->n_opcodes) { + + Fread((genericptr_t) &lvl->opcodes[n_opcode].opcode, 1, + sizeof(lvl->opcodes[n_opcode].opcode), fd); + opcode = lvl->opcodes[n_opcode].opcode; + + opdat = NULL; + + if (opcode < SPO_NULL || opcode >= MAX_SP_OPCODES) + panic("sp_level_loader: impossible opcode %i.", opcode); + + if (opcode == SPO_PUSH) { + struct opvar *ov = (opdat = (struct opvar *)alloc(sizeof(struct opvar))); + int nsize; + + if (!ov) panic("push ov alloc"); + ov->spovartyp = SPO_NULL; + ov->vardata.l = 0; + Fread((genericptr_t)&(ov->spovartyp), 1, sizeof(ov->spovartyp), fd); + + switch (ov->spovartyp) { + case SPOVAR_NULL: break; + case SPOVAR_COORD: + case SPOVAR_REGION: + case SPOVAR_MAPCHAR: + case SPOVAR_MONST: + case SPOVAR_OBJ: + case SPOVAR_INT: + Fread((genericptr_t)&(ov->vardata.l), 1, sizeof(ov->vardata.l), fd); + break; + case SPOVAR_VARIABLE: + case SPOVAR_STRING: + case SPOVAR_SEL: + { + char *opd; + Fread((genericptr_t) &nsize, 1, sizeof(nsize), fd); + opd = (char *)alloc(nsize + 1); + if (!opd) panic("sp lvl load opd alloc"); + if (nsize) Fread(opd, 1, nsize, fd); + opd[nsize] = 0; + ov->vardata.str = opd; + } + break; + default: + panic("sp_level_loader: unknown opvar type %i", ov->spovartyp); + } + } + + lvl->opcodes[n_opcode].opdat = opdat; + n_opcode++; + } /*while*/ + + return TRUE; +} + + +/* Frees the memory allocated for special level creation structs */ +STATIC_OVL boolean +sp_level_free(lvl) +sp_lev *lvl; +{ + long n_opcode = 0; + + while (n_opcode < lvl->n_opcodes) { + int opcode = lvl->opcodes[n_opcode].opcode; + struct opvar *opdat = lvl->opcodes[n_opcode].opdat; + + if (opcode < SPO_NULL || opcode >= MAX_SP_OPCODES) + panic("sp_level_free: unknown opcode %i", opcode); + + if (opdat) opvar_free(opdat); + n_opcode++; + } + Free(lvl->opcodes); + lvl->opcodes = NULL; + return TRUE; +} + +void +splev_initlev(linit) +lev_init *linit; +{ + switch (linit->init_style) { + default: impossible("Unrecognized level init style."); break; + case LVLINIT_NONE: break; + case LVLINIT_SOLIDFILL: + if (linit->lit == -1) linit->lit = rn2(2); + lvlfill_solid(linit->filling, linit->lit); + break; + case LVLINIT_MAZEGRID: + lvlfill_maze_grid(2,0, x_maze_max,y_maze_max, linit->filling); + break; +#ifdef REINCARNATION + case LVLINIT_ROGUE: + makeroguerooms(); + break; +#endif + case LVLINIT_MINES: + if (linit->lit == -1) linit->lit = rn2(2); + if (linit->filling > -1) lvlfill_solid(linit->filling, 0); + linit->icedpools = icedpools; + mkmap(linit); + break; + } +} + +struct sp_frame * +frame_new(execptr) + long execptr; +{ + struct sp_frame *frame = (struct sp_frame *)alloc(sizeof(struct sp_frame)); + if (!frame) panic("could not create execution frame."); + frame->next = NULL; + frame->variables = NULL; + frame->n_opcode = execptr; + frame->stack = (struct splevstack *)alloc(sizeof(struct splevstack)); + if (!frame->stack) panic("could not create execution frame stack."); + splev_stack_init(frame->stack); + return frame; +} + +void +frame_del(frame) + struct sp_frame *frame; +{ + if (!frame) return; + if (frame->stack) { + splev_stack_done(frame->stack); + frame->stack = NULL; + } + if (frame->variables) { + variable_list_del(frame->variables); + frame->variables = NULL; + } + Free(frame); +} + +void +spo_frame_push(coder) + struct sp_coder *coder; +{ + struct sp_frame *tmpframe = frame_new(coder->frame->n_opcode); + tmpframe->next = coder->frame; + coder->frame = tmpframe; +} + +void +spo_frame_pop(coder) + struct sp_coder *coder; +{ + if (coder->frame && coder->frame->next) { + struct sp_frame *tmpframe = coder->frame->next; + frame_del(coder->frame); + coder->frame = tmpframe; + coder->stack = coder->frame->stack; + } +} + +long +sp_code_jmpaddr(curpos, jmpaddr) + long curpos, jmpaddr; +{ + return (curpos + jmpaddr); +} + +void +spo_call(coder) + struct sp_coder *coder; +{ + struct opvar *addr; + struct opvar *params; + struct sp_frame *tmpframe; + + if (!OV_pop_i(addr) || !OV_pop_i(params)) return; + if (OV_i(params) < 0) return; + + tmpframe = frame_new(sp_code_jmpaddr(coder->frame->n_opcode, OV_i(addr)-1)); + + while (OV_i(params)-- > 0) { + splev_stack_push(tmpframe->stack, splev_stack_getdat_any(coder)); + } + splev_stack_reverse(tmpframe->stack); + + /* push a frame */ + tmpframe->next = coder->frame; + coder->frame = tmpframe; + + opvar_free(addr); + opvar_free(params); +} + +void +spo_return(coder) + struct sp_coder *coder; +{ + struct opvar *params; + if (!coder->frame || !coder->frame->next) panic("return: no frame."); + if (!OV_pop_i(params)) return; + if (OV_i(params) < 0) return; + + while (OV_i(params)-- > 0) { + splev_stack_push(coder->frame->next->stack, splev_stack_pop(coder->stack)); + } + + /* pop the frame */ + if (coder->frame->next) { + struct sp_frame *tmpframe = coder->frame->next; + frame_del(coder->frame); + coder->frame = tmpframe; + coder->stack = coder->frame->stack; + } + + opvar_free(params); +} + +/*ARGUSED*/ +void +spo_end_moninvent(coder) + struct sp_coder *coder; +{ + if (invent_carrying_monster) + m_dowear(invent_carrying_monster, TRUE); + invent_carrying_monster = NULL; +} + +/*ARGUSED*/ +void +spo_pop_container(coder) + struct sp_coder *coder; +{ + if (container_idx > 0) { + container_idx--; + container_obj[container_idx] = NULL; + } +} + + +void +spo_message(coder) + struct sp_coder *coder; +{ + struct opvar *op; + char *msg, *levmsg; + int old_n, n; + if (!OV_pop_s(op)) return; + msg = OV_s(op); + if (!msg) return; + + old_n = lev_message ? (strlen(lev_message)+1) : 0; + n = strlen(msg); + + levmsg = (char *) alloc(old_n+n+1); + if (!levmsg) panic("spo_message alloc"); + if (old_n) levmsg[old_n-1] = '\n'; + if (lev_message) + (void) memcpy((genericptr_t)levmsg, (genericptr_t)lev_message, old_n-1); + (void) memcpy((genericptr_t)&levmsg[old_n], msg, n); + levmsg[old_n+n] = '\0'; + Free(lev_message); + lev_message = levmsg; + opvar_free(op); +} + +void +spo_monster(coder) + struct sp_coder *coder; +{ + int nparams = 0; + + struct opvar *varparam; + struct opvar *id, *mcoord, *has_inv; + monster tmpmons; + + tmpmons.peaceful = -1; + tmpmons.asleep = -1; + tmpmons.name.str = (char *)0; + tmpmons.appear = 0; + tmpmons.appear_as.str = (char *)0; + tmpmons.align = - MAX_REGISTERS - 2; + tmpmons.female = 0; + tmpmons.invis = 0; + tmpmons.cancelled = 0; + tmpmons.revived = 0; + tmpmons.avenge = 0; + tmpmons.fleeing = 0; + tmpmons.blinded = 0; + tmpmons.paralyzed = 0; + tmpmons.stunned = 0; + tmpmons.confused = 0; + tmpmons.seentraps = 0; + tmpmons.has_invent = 0; + + if (!OV_pop_i(has_inv)) return; + + if (!OV_pop_i(varparam)) return; + + while ((nparams++ < (SP_M_V_END+1)) && + (OV_typ(varparam) == SPOVAR_INT) && + (OV_i(varparam) >= 0) && + (OV_i(varparam) < SP_M_V_END)) { + struct opvar *parm = NULL; + OV_pop(parm); + switch (OV_i(varparam)) { + case SP_M_V_NAME: + if ((OV_typ(parm) == SPOVAR_STRING) && + !tmpmons.name.str) + tmpmons.name.str = strdup(OV_s(parm)); + break; + case SP_M_V_APPEAR: + if ((OV_typ(parm) == SPOVAR_INT) && + !tmpmons.appear_as.str) { + tmpmons.appear = OV_i(parm); + opvar_free(parm); + OV_pop(parm); + tmpmons.appear_as.str = strdup(OV_s(parm)); + } + break; + case SP_M_V_ASLEEP: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.asleep = OV_i(parm); + break; + case SP_M_V_ALIGN: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.align = OV_i(parm); + break; + case SP_M_V_PEACEFUL: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.peaceful = OV_i(parm); + break; + case SP_M_V_FEMALE: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.female = OV_i(parm); + break; + case SP_M_V_INVIS: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.invis = OV_i(parm); + break; + case SP_M_V_CANCELLED: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.cancelled = OV_i(parm); + break; + case SP_M_V_REVIVED: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.revived = OV_i(parm); + break; + case SP_M_V_AVENGE: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.avenge = OV_i(parm); + break; + case SP_M_V_FLEEING: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.fleeing = OV_i(parm); + break; + case SP_M_V_BLINDED: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.blinded = OV_i(parm); + break; + case SP_M_V_PARALYZED: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.paralyzed = OV_i(parm); + break; + case SP_M_V_STUNNED: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.stunned = OV_i(parm); + break; + case SP_M_V_CONFUSED: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.confused = OV_i(parm); + break; + case SP_M_V_SEENTRAPS: + if (OV_typ(parm) == SPOVAR_INT) + tmpmons.seentraps = OV_i(parm); + break; + case SP_M_V_END: + nparams = SP_M_V_END+1; + break; + default: + impossible("MONSTER with unknown variable param type!"); + break; + } + opvar_free(parm); + if (OV_i(varparam) != SP_M_V_END) { + opvar_free(varparam); + OV_pop(varparam); + } + } + + if (!OV_pop_c(mcoord)) panic("no monster coord?"); + + if (!OV_pop_typ(id, SPOVAR_MONST)) panic("no mon type"); + + tmpmons.id = SP_MONST_PM(OV_i(id)); + tmpmons.class = SP_MONST_CLASS(OV_i(id)); + tmpmons.coord = OV_i(mcoord); + tmpmons.has_invent = OV_i(has_inv); + + create_monster(&tmpmons, coder->croom); + + Free(tmpmons.name.str); + Free(tmpmons.appear_as.str); + + opvar_free(id); + opvar_free(mcoord); + opvar_free(has_inv); + opvar_free(varparam); +} + +void +spo_object(coder) + struct sp_coder *coder; +{ + int nparams = 0; + long quancnt; + + struct opvar *varparam; + struct opvar *id, *containment; + + object tmpobj; + + tmpobj.spe = -127; + tmpobj.curse_state = -1; + tmpobj.corpsenm = NON_PM; + tmpobj.name.str = (char *)0; + tmpobj.quan = -1; + tmpobj.buried = 0; + tmpobj.lit = 0; + tmpobj.eroded = 0; + tmpobj.locked = 0; + tmpobj.trapped = 0; + tmpobj.recharged = 0; + tmpobj.invis = 0; + tmpobj.greased = 0; + tmpobj.broken = 0; + tmpobj.coord = SP_COORD_PACK_RANDOM(0); + + if (!OV_pop_i(containment)) return; + + if (!OV_pop_i(varparam)) return; + + while ((nparams++ < (SP_O_V_END+1)) && + (OV_typ(varparam) == SPOVAR_INT) && + (OV_i(varparam) >= 0) && + (OV_i(varparam) < SP_O_V_END)) { + struct opvar *parm; + OV_pop(parm); + switch (OV_i(varparam)) { + case SP_O_V_NAME: + if ((OV_typ(parm) == SPOVAR_STRING) && + !tmpobj.name.str) + tmpobj.name.str = strdup(OV_s(parm)); + break; + case SP_O_V_CORPSENM: + if (OV_typ(parm) == SPOVAR_MONST) { + char monclass = SP_MONST_CLASS(OV_i(parm)); + int monid = SP_MONST_PM(OV_i(parm)); + if (monid >= 0 && monid < NUMMONS) { + tmpobj.corpsenm = monid; + break; /* we're done! */ + } else { + struct permonst *pm = (struct permonst *)0; + if (def_char_to_monclass(monclass) != MAXMCLASSES) { + pm = mkclass(def_char_to_monclass(monclass), G_NOGEN); + } else { + pm = rndmonst(); + } + if (pm) + tmpobj.corpsenm = monsndx(pm); + } + } + break; + case SP_O_V_CURSE: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.curse_state = OV_i(parm); + break; + case SP_O_V_SPE: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.spe = OV_i(parm); + break; + case SP_O_V_QUAN: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.quan = OV_i(parm); + break; + case SP_O_V_BURIED: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.buried = OV_i(parm); + break; + case SP_O_V_LIT: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.lit = OV_i(parm); + break; + case SP_O_V_ERODED: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.eroded = OV_i(parm); + break; + case SP_O_V_LOCKED: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.locked = OV_i(parm); + break; + case SP_O_V_TRAPPED: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.trapped = OV_i(parm); + break; + case SP_O_V_RECHARGED: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.recharged = OV_i(parm); + break; + case SP_O_V_INVIS: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.invis = OV_i(parm); + break; + case SP_O_V_GREASED: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.greased = OV_i(parm); + break; + case SP_O_V_BROKEN: + if (OV_typ(parm) == SPOVAR_INT) + tmpobj.broken = OV_i(parm); + break; + case SP_O_V_COORD: + if (OV_typ(parm) != SPOVAR_COORD) + panic("no coord for obj?"); + tmpobj.coord = OV_i(parm); + break; + case SP_O_V_END: + nparams = SP_O_V_END+1; + break; + default: + impossible("OBJECT with unknown variable param type!"); + break; + } + opvar_free(parm); + if (OV_i(varparam) != SP_O_V_END) { + opvar_free(varparam); + OV_pop(varparam); + } + } + + if (!OV_pop_typ(id, SPOVAR_OBJ)) panic("no obj type"); + + tmpobj.id = SP_OBJ_TYP(OV_i(id)); + tmpobj.class = SP_OBJ_CLASS(OV_i(id)); + tmpobj.containment = OV_i(containment); + + quancnt = (tmpobj.id > STRANGE_OBJECT) ? tmpobj.quan : 0; + + do { + create_object(&tmpobj, coder->croom); + quancnt--; + } while ((quancnt > 0) && + ((tmpobj.id > STRANGE_OBJECT) && + !objects[tmpobj.id].oc_merge)); + + Free(tmpobj.name.str); + + opvar_free(varparam); + opvar_free(id); + opvar_free(containment); +} + +void +spo_level_flags(coder) + struct sp_coder *coder; +{ + struct opvar *flagdata; + long lflags; + + if (!OV_pop_i(flagdata)) return; + lflags = OV_i(flagdata); + + if (lflags & NOTELEPORT) level.flags.noteleport = 1; + if (lflags & HARDFLOOR) level.flags.hardfloor = 1; + if (lflags & NOMMAP) level.flags.nommap = 1; + if (lflags & SHORTSIGHTED) level.flags.shortsighted = 1; + if (lflags & ARBOREAL) level.flags.arboreal = 1; + if (lflags & MAZELEVEL) level.flags.is_maze_lev = 1; + if (lflags & PREMAPPED) coder->premapped = TRUE; + if (lflags & SHROUD) level.flags.hero_memory = 0; + if (lflags & GRAVEYARD) level.flags.graveyard = 1; + if (lflags & ICEDPOOLS) icedpools = TRUE; + if (lflags & SOLIDIFY) coder->solidify = TRUE; + + opvar_free(flagdata); +} + +void +spo_initlevel(coder) + struct sp_coder *coder; +{ + lev_init init_lev; + struct opvar *init_style, *fg, *bg, *smoothed, *joined, *lit, *walled, *filling; + + if (!OV_pop_i(fg) || + !OV_pop_i(bg) || + !OV_pop_i(smoothed) || + !OV_pop_i(joined) || + !OV_pop_i(lit) || + !OV_pop_i(walled) || + !OV_pop_i(filling) || + !OV_pop_i(init_style)) return; + + splev_init_present = TRUE; + + init_lev.init_style = OV_i(init_style); + init_lev.fg = OV_i(fg); + init_lev.bg = OV_i(bg); + init_lev.smoothed = OV_i(smoothed); + init_lev.joined = OV_i(joined); + init_lev.lit = OV_i(lit); + init_lev.walled = OV_i(walled); + init_lev.filling = OV_i(filling); + + coder->lvl_is_joined = OV_i(joined); + + splev_initlev(&init_lev); + + opvar_free(init_style); + opvar_free(fg); + opvar_free(bg); + opvar_free(smoothed); + opvar_free(joined); + opvar_free(lit); + opvar_free(walled); + opvar_free(filling); +} + +void +spo_engraving(coder) + struct sp_coder *coder; +{ + struct opvar *etyp, *txt, *ecoord; + xchar x,y; + + if (!OV_pop_i(etyp) || + !OV_pop_s(txt) || + !OV_pop_c(ecoord)) return; + + get_location_coord(&x, &y, DRY, coder->croom, OV_i(ecoord)); + make_engr_at(x, y, OV_s(txt), 0L, OV_i(etyp)); + + opvar_free(etyp); + opvar_free(txt); + opvar_free(ecoord); +} + +void +spo_mineralize(coder) + struct sp_coder *coder; +{ + struct opvar *kelp_pool, *kelp_moat, *gold_prob, *gem_prob; + + if (!OV_pop_i(gem_prob) || + !OV_pop_i(gold_prob) || + !OV_pop_i(kelp_moat) || + !OV_pop_i(kelp_pool)) return; + + mineralize(OV_i(kelp_pool), OV_i(kelp_moat), OV_i(gold_prob), OV_i(gem_prob), TRUE); + + opvar_free(gem_prob); + opvar_free(gold_prob); + opvar_free(kelp_moat); + opvar_free(kelp_pool); +} + +void +spo_room(coder) + struct sp_coder *coder; +{ + if (coder->n_subroom > MAX_NESTED_ROOMS) { + panic("Too deeply nested rooms?!"); + } else { + struct opvar *rflags, *h, *w, *yalign, *xalign, + *y, *x, *rlit, *chance, *rtype; + + room tmproom; + struct mkroom *tmpcr; + + if (!OV_pop_i(h) || + !OV_pop_i(w) || + !OV_pop_i(y) || + !OV_pop_i(x) || + !OV_pop_i(yalign) || + !OV_pop_i(xalign) || + !OV_pop_i(rflags) || + !OV_pop_i(rlit) || + !OV_pop_i(chance) || + !OV_pop_i(rtype)) return; + + + tmproom.x = OV_i(x); + tmproom.y = OV_i(y); + tmproom.w = OV_i(w); + tmproom.h = OV_i(h); + tmproom.xalign = OV_i(xalign); + tmproom.yalign = OV_i(yalign); + tmproom.rtype = OV_i(rtype); + tmproom.chance = OV_i(chance); + tmproom.rlit = OV_i(rlit); + tmproom.filled = (OV_i(rflags) & (1 << 0)); + /*tmproom.irregular = (OV_i(rflags) & (1 << 1));*/ + tmproom.joined = !(OV_i(rflags) & (1 << 2)); + + opvar_free(x); + opvar_free(y); + opvar_free(w); + opvar_free(h); + opvar_free(xalign); + opvar_free(yalign); + opvar_free(rtype); + opvar_free(chance); + opvar_free(rlit); + opvar_free(rflags); + + if (!coder->failed_room[coder->n_subroom-1]) { + tmpcr = build_room(&tmproom, coder->croom); + if (tmpcr) { + coder->tmproomlist[coder->n_subroom] = tmpcr; + coder->failed_room[coder->n_subroom] = FALSE; + coder->n_subroom++; + return; + } + } /* failed to create parent room, so fail this too */ + } + coder->tmproomlist[coder->n_subroom] = (struct mkroom *)0; + coder->failed_room[coder->n_subroom] = TRUE; + coder->n_subroom++; +} + +void +spo_endroom(coder) + struct sp_coder *coder; +{ + if (coder->n_subroom > 1) { + coder->n_subroom--; + coder->tmproomlist[coder->n_subroom] = NULL; + coder->failed_room[coder->n_subroom] = TRUE; + } else { + /* no subroom, get out of top-level room */ + /* Need to ensure xstart/ystart/xsize/ysize have something sensible, + in case there's some stuff to be created outside the outermost room, + and there's no MAP. + */ + if(xsize <= 1 && ysize <= 1) { + xstart = 1; + ystart = 0; + xsize = COLNO-1; + ysize = ROWNO; + } + } +} + +void +spo_stair(coder) + struct sp_coder *coder; +{ + xchar x,y; + struct opvar *up, *scoord; + struct trap *badtrap; + + if (!OV_pop_i(up) || + !OV_pop_c(scoord)) return; + + get_location_coord(&x, &y, DRY, coder->croom, OV_i(scoord)); + if ((badtrap = t_at(x,y)) != 0) deltrap(badtrap); + mkstairs(x, y, (char)OV_i(up), coder->croom); + SpLev_Map[x][y] = 1; + + opvar_free(scoord); + opvar_free(up); +} + +void +spo_ladder(coder) + struct sp_coder *coder; +{ + xchar x,y; + struct opvar *up, *lcoord; + + if (!OV_pop_i(up) || + !OV_pop_c(lcoord)) return; + + get_location_coord(&x, &y, DRY, coder->croom, OV_i(lcoord)); + + levl[x][y].typ = LADDER; + SpLev_Map[x][y] = 1; + if (OV_i(up)) { + xupladder = x; yupladder = y; + levl[x][y].ladder = LA_UP; + } else { + xdnladder = x; ydnladder = y; + levl[x][y].ladder = LA_DOWN; + } + opvar_free(lcoord); + opvar_free(up); +} + +void +spo_grave(coder) + struct sp_coder *coder; +{ + struct opvar *gcoord, *typ, *txt; + schar x,y; + if (!OV_pop_i(typ) || + !OV_pop_s(txt) || + !OV_pop_c(gcoord)) return; + + get_location_coord(&x, &y, DRY, coder->croom, OV_i(gcoord)); + + if (isok(x, y) && !t_at(x, y)) { + levl[x][y].typ = GRAVE; + switch (OV_i(typ)) { + case 2: make_grave(x, y, OV_s(txt)); break; + case 1: make_grave(x, y, NULL); break; + default: del_engr_at(x, y); break; + } + } + + opvar_free(gcoord); + opvar_free(typ); + opvar_free(txt); +} + +void +spo_altar(coder) + struct sp_coder *coder; +{ + struct opvar *al, *shrine, *acoord; + altar tmpaltar; + + if (!OV_pop_i(al) || + !OV_pop_i(shrine) || + !OV_pop_c(acoord)) return; + + tmpaltar.coord = OV_i(acoord); + tmpaltar.align = OV_i(al); + tmpaltar.shrine = OV_i(shrine); + + create_altar(&tmpaltar, coder->croom); + + opvar_free(acoord); + opvar_free(shrine); + opvar_free(al); +} + +void +spo_trap(coder) + struct sp_coder *coder; +{ + struct opvar *type; + struct opvar *tcoord; + trap tmptrap; + + if (!OV_pop_i(type) || + !OV_pop_c(tcoord)) return; + + tmptrap.coord = OV_i(tcoord); + tmptrap.type = OV_i(type); + + create_trap(&tmptrap, coder->croom); + opvar_free(tcoord); + opvar_free(type); +} + +void +spo_gold(coder) + struct sp_coder *coder; +{ + struct opvar *gcoord, *amt; + schar x,y; + long amount; + + if (!OV_pop_c(gcoord) || !OV_pop_i(amt)) return; + amount = OV_i(amt); + get_location_coord(&x, &y, DRY, coder->croom, OV_i(gcoord)); + if (amount == -1) amount = rnd(200); + mkgold(amount, x,y); + opvar_free(gcoord); + opvar_free(amt); +} + +void +spo_corridor(coder) + struct sp_coder *coder; +{ + struct opvar *deswall, *desdoor, *desroom, + *srcwall, *srcdoor, *srcroom; + corridor tc; + + if (!OV_pop_i(deswall) || + !OV_pop_i(desdoor) || + !OV_pop_i(desroom) || + !OV_pop_i(srcwall) || + !OV_pop_i(srcdoor) || + !OV_pop_i(srcroom)) return; + + tc.src.room = OV_i(srcroom); + tc.src.door = OV_i(srcdoor); + tc.src.wall = OV_i(srcwall); + tc.dest.room = OV_i(desroom); + tc.dest.door = OV_i(desdoor); + tc.dest.wall = OV_i(deswall); + + create_corridor(&tc); + + opvar_free(deswall); + opvar_free(desdoor); + opvar_free(desroom); + opvar_free(srcwall); + opvar_free(srcdoor); + opvar_free(srcroom); +} + + +struct opvar * +selection_opvar(nbuf) + char *nbuf; +{ + struct opvar *ov; + char buf[(COLNO*ROWNO)+1]; + + if (!nbuf) { + (void) memset(buf, 1, sizeof(buf)); + buf[(COLNO*ROWNO)] = '\0'; + ov = opvar_new_str(buf); + } else { + ov = opvar_new_str(nbuf); + } + ov->spovartyp = SPOVAR_SEL; + return ov; +} + +char +selection_getpoint(x,y,ov) + int x,y; + struct opvar *ov; +{ + if (!ov || ov->spovartyp != SPOVAR_SEL) return 0; + if (x < 0 || y < 0 || x >= COLNO || y >= ROWNO) return 0; + + return (ov->vardata.str[COLNO*y + x] - 1); +} + +void +selection_setpoint(x,y,ov, c) + int x,y; + struct opvar *ov; + char c; +{ + if (!ov || ov->spovartyp != SPOVAR_SEL) return; + if (x < 0 || y < 0 || x >= COLNO || y >= ROWNO) return; + + ov->vardata.str[COLNO*y + x] = (c + 1); +} + +struct opvar * +selection_not(s) + struct opvar *s; +{ + struct opvar *ov; + int x,y; + ov = selection_opvar(NULL); + if (!ov) return NULL; + + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) + if (!selection_getpoint(x,y,s)) + selection_setpoint(x,y,ov,1); + + return ov; +} + +struct opvar * +selection_logical_oper(s1, s2, oper) + struct opvar *s1, *s2; + char oper; +{ + struct opvar *ov; + int x,y; + + ov = selection_opvar(NULL); + if (!ov) return NULL; + + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) { + switch (oper) { + default: + case '|': + if (selection_getpoint(x,y,s1) || selection_getpoint(x,y,s2)) + selection_setpoint(x,y,ov,1); + break; + case '&': + if (selection_getpoint(x,y,s1) && selection_getpoint(x,y,s2)) + selection_setpoint(x,y,ov,1); + break; + } + } + + return ov; +} + +struct opvar * +selection_filter_mapchar(ov, mc) + struct opvar *ov; + struct opvar *mc; +{ + int x,y; + schar mapc; + xchar lit; + struct opvar *ret = selection_opvar(NULL); + if (!ov || !mc || !ret) return NULL; + mapc = SP_MAPCHAR_TYP(OV_i(mc)); + lit = SP_MAPCHAR_LIT(OV_i(mc)); + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) + if (selection_getpoint(x,y,ov) && (levl[x][y].typ == mapc)) { + switch (lit) { + default: + case -2: selection_setpoint(x,y,ret, 1); break; + case -1: selection_setpoint(x,y,ret, rn2(2)); break; + case 0: + case 1: if (levl[x][y].lit == lit) selection_setpoint(x,y,ret, 1); break; + } + } + return ret; +} + + +void +selection_filter_percent(ov, percent) + struct opvar *ov; + int percent; +{ + int x,y; + if (!ov) return; + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) + if (selection_getpoint(x,y,ov) && (rn2(100) >= percent)) + selection_setpoint(x,y,ov,0); +} + +int +selection_rndcoord(ov, x,y) + struct opvar *ov; + schar *x, *y; +{ + int idx = 0; + int c; + int dx,dy; + + for (dx = 0; dx < COLNO; dx++) + for (dy = 0; dy < ROWNO; dy++) + if (isok(dx,dy) && selection_getpoint(dx,dy,ov)) idx++; + + if (idx) { + c = rn2(idx); + for (dx = 0; dx < COLNO; dx++) + for (dy = 0; dy < ROWNO; dy++) + if (isok(dx,dy) && selection_getpoint(dx,dy, ov)) { + if (!c) { + *x = dx; + *y = dy; + return 1; + } + c--; + } + } + *x = *y = -1; + return 0; +} + +void +selection_do_grow(ov, dir) + struct opvar *ov; + int dir; +{ + int x,y, c; + char tmp[COLNO][ROWNO]; + + if (ov->spovartyp != SPOVAR_SEL) return; + if (!ov) return; + + (void) memset(tmp, 0, sizeof(tmp)); + + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) { + c = 0; + if ((dir & W_WEST) && (x > 0) && (selection_getpoint(x-1,y, ov))) c++; + if ((dir & (W_WEST|W_NORTH)) && (x > 0) && (y > 0) && (selection_getpoint(x-1,y-1, ov))) c++; + if ((dir & W_NORTH) && (y > 0) && (selection_getpoint(x,y-1, ov))) c++; + if ((dir & (W_NORTH|W_EAST)) && (y > 0) && (x < COLNO-1) && (selection_getpoint(x+1,y-1, ov))) c++; + if ((dir & W_EAST) && (x < COLNO-1) && (selection_getpoint(x+1,y, ov))) c++; + if ((dir & (W_EAST|W_SOUTH)) && (x < COLNO-1) && (y < ROWNO-1) && (selection_getpoint(x+1,y+1, ov))) c++; + if ((dir & W_SOUTH) && (y < ROWNO-1) && (selection_getpoint(x,y+1, ov))) c++; + if ((dir & (W_SOUTH|W_WEST)) && (y < ROWNO-1) && (x > 0) && (selection_getpoint(x-1,y+1, ov))) c++; + if (c) tmp[x][y] = 1; + } + + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) + if (tmp[x][y]) selection_setpoint(x,y,ov,1); +} + +void +selection_floodfill(ov, x,y) + struct opvar *ov; + int x,y; +{ + struct opvar *tmp = selection_opvar(NULL); +#define SEL_FLOOD_STACK (COLNO*ROWNO) +#define SEL_FLOOD(nx,ny) {if (idx 0); +#undef SEL_FLOOD +#undef SEL_FLOOD_STACK + opvar_free(tmp); +} + +/* McIlroy's Ellipse Algorithm */ +void +selection_do_ellipse(ov, xc,yc, a,b, filled) + struct opvar *ov; + int xc,yc,a,b,filled; +{ /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */ + int x = 0, y = b; + long a2 = (long)a*a, b2 = (long)b*b; + long crit1 = -(a2/4 + a%2 + b2); + long crit2 = -(b2/4 + b%2 + a2); + long crit3 = -(b2/4 + b%2); + long t = -a2*y; /* e(x+1/2,y-1/2) - (a^2+b^2)/4 */ + long dxt = 2*b2*x, dyt = -2*a2*y; + long d2xt = 2*b2, d2yt = 2*a2; + long width = 1; + long i; + + if (!ov) return; + + filled = !filled; + + if (!filled) { + while (y>=0 && x<=a) { + selection_setpoint(xc+x, yc+y, ov, 1); + if (x!=0 || y!=0) + selection_setpoint(xc-x, yc-y, ov, 1); + if (x!=0 && y!=0) { + selection_setpoint(xc+x, yc-y, ov, 1); + selection_setpoint(xc-x, yc+y, ov, 1); + } + if (t + b2*x <= crit1 || /* e(x+1,y-1/2) <= 0 */ + t + a2*y <= crit3) { /* e(x+1/2,y) <= 0 */ + x++; dxt += d2xt; t += dxt; + } else if (t - a2*y > crit2) { /* e(x+1/2,y-1) > 0 */ + y--; dyt += d2yt; t += dyt; + } else { + x++; dxt += d2xt; t += dxt; + y--; dyt += d2yt; t += dyt; + } + } + } else { + while (y>=0 && x<=a) { + if (t + b2*x <= crit1 || /* e(x+1,y-1/2) <= 0 */ + t + a2*y <= crit3) { /* e(x+1/2,y) <= 0 */ + x++; dxt += d2xt; t += dxt; + width += 2; + } else if (t - a2*y > crit2) { /* e(x+1/2,y-1) > 0 */ + for (i = 0; i < width; i++) selection_setpoint(xc-x+i, yc-y, ov, 1); + if (y!=0) + for (i = 0; i < width; i++) selection_setpoint(xc-x+i, yc+y, ov, 1); + y--; dyt += d2yt; t += dyt; + } else { + for (i = 0; i < width; i++) selection_setpoint(xc-x+i, yc-y, ov, 1); + if (y!=0) + for (i = 0; i < width; i++) selection_setpoint(xc-x+i, yc+y, ov, 1); + x++; dxt += d2xt; t += dxt; + y--; dyt += d2yt; t += dyt; + width += 2; + } + } + } +} + +/* distance from line segment (x1,y1, x2,y2) to point (x3,y3) */ +long +line_dist_coord(x1,y1, x2,y2, x3,y3) + long x1,y1,x2,y2,x3,y3; +{ + long px = x2-x1; + long py = y2-y1; + long s = px*px + py*py; + long x, y, dx, dy, dist = 0; + float u = 0; + + if (x1 == x2 && y1 == y2) return isqrt(dist2(x1,y1, x3,y3)); + + u = ((x3 - x1) * px + (y3 - y1) * py) / (float)s; + if (u > 1) u = 1; + else if (u < 0) u = 0; + + x = x1 + u * px; + y = y1 + u * py; + dx = x - x3; + dy = y - y3; + dist = isqrt(dx*dx + dy*dy); + + return dist; +} + +void +selection_do_gradient(ov, x,y, x2,y2, gtyp, mind, maxd, limit) + struct opvar *ov; + long x, y, x2,y2, gtyp, mind, maxd, limit; +{ + long dx,dy, dofs; + + if (mind > maxd) { + long tmp = mind; + mind = maxd; + maxd = tmp; + } + + dofs = maxd - mind; + if (dofs < 1) dofs = 1; + + switch (gtyp) { + default: + case SEL_GRADIENT_RADIAL: + { + for (dx = 0; dx < COLNO; dx++) + for (dy = 0; dy < ROWNO; dy++) { + long d = line_dist_coord(x,y, x2,y2, dx,dy); + if (d >= mind && (!limit || (d <= maxd))) { + if ((d - mind) > rn2(dofs)) + selection_setpoint(dx,dy, ov, 1); + } + } + } + break; + case SEL_GRADIENT_SQUARE: + { + for (dx = 0; dx < COLNO; dx++) + for (dy = 0; dy < ROWNO; dy++) { + long d1 = line_dist_coord(x,y, x2,y2, x,dy); + long d2 = line_dist_coord(x,y, x2,y2, dx,y); + long d3 = line_dist_coord(x,y, x2,y2, x2,dy); + long d4 = line_dist_coord(x,y, x2,y2, dx,y2); + long d5 = line_dist_coord(x,y, x2,y2, dx,dy); + long d = min(d5, min(max(d1, d2),max(d3,d4))); + + if (d >= mind && (!limit || (d <= maxd))) { + if ((d - mind) > rn2(dofs)) + selection_setpoint(dx,dy, ov, 1); + } + } + } + break; + } +} + +void +selection_do_line(x1,y1,x2,y2, ov) /* bresenham line algo */ + schar x1,y1,x2,y2; + struct opvar *ov; +{ + int d,dx,dy,ai,bi,xi,yi; + + if (x1 < x2) { + xi = 1; + dx = x2 - x1; + } else { + xi = - 1; + dx = x1 - x2; + } + + if (y1 < y2) { + yi = 1; + dy = y2 - y1; + } else { + yi = - 1; + dy = y1 - y2; + } + + selection_setpoint(x1,y1, ov, 1); + + if (dx > dy) { + ai = (dy - dx) * 2; + bi = dy * 2; + d = bi - dx; + do { + if (d >= 0) { + y1 += yi; + d += ai; + } else d += bi; + x1 += xi; + selection_setpoint(x1,y1, ov, 1); + } while (x1 != x2); + } else { + ai = (dx - dy) * 2; + bi = dx * 2; + d = bi - dy; + do { + if (d >= 0) { + x1 += xi; + d += ai; + } else d += bi; + y1 += yi; + selection_setpoint(x1,y1, ov, 1); + } while (y1 != y2); + } +} + +void +selection_do_randline(x1,y1,x2,y2,rough, rec, ov) + schar x1,y1,x2,y2,rough,rec; + struct opvar *ov; +{ + int mx, my; + int dx, dy; + + if (rec < 1) { + return; + } + + if ((x2 == x1) && (y2 == y1)) { + selection_setpoint(x1,y1, ov, 1); + return; + } + + if (rough > max(abs(x2-x1), abs(y2-y1))) + rough = max(abs(x2-x1), abs(y2-y1)); + + if (rough < 2) { + mx = ((x1 + x2) / 2); + my = ((y1 + y2) / 2); + } else { + do { + dx = (rand() % rough) - (rough / 2); + dy = (rand() % rough) - (rough / 2); + mx = ((x1 + x2) / 2) + dx; + my = ((y1 + y2) / 2) + dy; + } while ((mx > COLNO-1 || mx < 0 || my < 0 || my > ROWNO-1)); + } + + selection_setpoint(mx,my, ov, 1); + + rough = (rough * 2) / 3; + + rec--; + + selection_do_randline(x1,y1,mx,my, rough, rec, ov); + selection_do_randline(mx,my,x2,y2, rough, rec, ov); +} + + +void +selection_iterate(ov, func, arg) + struct opvar *ov; + void FDECL((*func), (int,int,genericptr_t)); + genericptr_t arg; +{ + int x,y; + /* yes, this is very naive, but it's not _that_ expensive. */ + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) + if (selection_getpoint(x,y, ov)) (*func)(x,y, arg); +} + +void +sel_set_ter(x,y,arg) + int x,y; + genericptr_t arg; +{ + terrain terr; + terr = (*(terrain *)arg); + SET_TYPLIT(x,y, terr.ter, terr.tlit); + /* handle doors and secret doors */ + if (levl[x][y].typ == SDOOR || IS_DOOR(levl[x][y].typ)) { + if(levl[x][y].typ == SDOOR) + levl[x][y].doormask = D_CLOSED; + if (x && (IS_WALL(levl[x-1][y].typ) || + levl[x-1][y].horizontal)) + levl[x][y].horizontal = 1; + } +} + +void +sel_set_feature(x,y,arg) + int x,y; + genericptr_t arg; +{ + if (IS_FURNITURE(levl[x][y].typ)) return; + levl[x][y].typ = (*(int *)arg); +} + +void +sel_set_door(dx,dy,arg) + int dx,dy; + genericptr_t arg; +{ + xchar typ = (*(xchar *)arg); + xchar x = dx; + xchar y = dy; + if (!IS_DOOR(levl[x][y].typ) && levl[x][y].typ != SDOOR) + levl[x][y].typ = (typ & D_SECRET) ? SDOOR : DOOR; + if (typ & D_SECRET) { + typ &= ~D_SECRET; + if (typ < D_CLOSED) + typ = D_CLOSED; + } + levl[x][y].doormask = typ; + SpLev_Map[x][y] = 1; +} + + + +void +spo_door(coder) + struct sp_coder *coder; +{ + struct opvar *msk, *sel; + xchar typ; + + if (!OV_pop_i(msk) || + !OV_pop_typ(sel, SPOVAR_SEL)) return; + + typ = OV_i(msk) == -1 ? rnddoor() : (xchar)OV_i(msk); + + selection_iterate(sel, sel_set_door, (genericptr_t)&typ); + + opvar_free(sel); + opvar_free(msk); +} + +void +spo_feature(coder) + struct sp_coder *coder; +{ + struct opvar *sel; + int typ; + + if (!OV_pop_typ(sel, SPOVAR_SEL)) return; + + switch (coder->opcode) { + default: impossible("spo_feature called with wrong opcode %i.", coder->opcode); break; + case SPO_FOUNTAIN: typ = FOUNTAIN; break; + case SPO_SINK: typ = SINK; break; + case SPO_POOL: typ = POOL; break; + } + selection_iterate(sel, sel_set_feature, (genericptr_t)&typ); + opvar_free(sel); +} + +void +spo_terrain(coder) + struct sp_coder *coder; +{ + terrain tmpterrain; + struct opvar *ter, *sel; + + if (!OV_pop_typ(ter, SPOVAR_MAPCHAR) || + !OV_pop_typ(sel, SPOVAR_SEL)) return; + + tmpterrain.ter = SP_MAPCHAR_TYP(OV_i(ter)); + tmpterrain.tlit = SP_MAPCHAR_LIT(OV_i(ter)); + selection_iterate(sel, sel_set_ter, (genericptr_t)&tmpterrain); + + opvar_free(ter); + opvar_free(sel); +} + +void +spo_replace_terrain(coder) + struct sp_coder *coder; +{ + replaceterrain rt; + struct opvar *reg,*from_ter,*to_ter,*chance; + + if (!OV_pop_i(chance) || + !OV_pop_typ(to_ter, SPOVAR_MAPCHAR) || + !OV_pop_typ(from_ter, SPOVAR_MAPCHAR) || + !OV_pop_r(reg)) return; + + rt.chance = OV_i(chance); + rt.tolit = SP_MAPCHAR_LIT(OV_i(to_ter)); + rt.toter = SP_MAPCHAR_TYP(OV_i(to_ter)); + rt.fromter = SP_MAPCHAR_TYP(OV_i(from_ter)); + /* TODO: use SP_MAPCHAR_LIT(OV_i(from_ter)) too */ + rt.x1 = SP_REGION_X1(OV_i(reg)); + rt.y1 = SP_REGION_Y1(OV_i(reg)); + rt.x2 = SP_REGION_X2(OV_i(reg)); + rt.y2 = SP_REGION_Y2(OV_i(reg)); + + replace_terrain(&rt, coder->croom); + + opvar_free(reg); + opvar_free(from_ter); + opvar_free(to_ter); + opvar_free(chance); +} + +void +spo_levregion(coder) + struct sp_coder *coder; +{ + struct opvar *rname, *padding, *rtype, + *del_islev, *dy2, *dx2, *dy1, *dx1, + *in_islev, *iy2, *ix2, *iy1, *ix1; + + lev_region *tmplregion; + + if (!OV_pop_s(rname) || + !OV_pop_i(padding) || + !OV_pop_i(rtype) || + !OV_pop_i(del_islev) || + !OV_pop_i(dy2) || + !OV_pop_i(dx2) || + !OV_pop_i(dy1) || + !OV_pop_i(dx1) || + !OV_pop_i(in_islev) || + !OV_pop_i(iy2) || + !OV_pop_i(ix2) || + !OV_pop_i(iy1) || + !OV_pop_i(ix1)) return; + + tmplregion = (lev_region *)alloc(sizeof(lev_region)); + if (!tmplregion) panic("levreg alloc"); + tmplregion->inarea.x1 = OV_i(ix1); + tmplregion->inarea.y1 = OV_i(iy1); + tmplregion->inarea.x2 = OV_i(ix2); + tmplregion->inarea.y2 = OV_i(iy2); + + tmplregion->delarea.x1 = OV_i(dx1); + tmplregion->delarea.y1 = OV_i(dy1); + tmplregion->delarea.x2 = OV_i(dx2); + tmplregion->delarea.y2 = OV_i(dy2); + + tmplregion->in_islev = OV_i(in_islev); + tmplregion->del_islev = OV_i(del_islev); + tmplregion->rtype = OV_i(rtype); + tmplregion->padding = OV_i(padding); + tmplregion->rname.str = strdup(OV_s(rname)); + + if(!tmplregion->in_islev) { + get_location(&tmplregion->inarea.x1, &tmplregion->inarea.y1, + ANY_LOC, (struct mkroom *)0); + get_location(&tmplregion->inarea.x2, &tmplregion->inarea.y2, + ANY_LOC, (struct mkroom *)0); + } + + if(!tmplregion->del_islev) { + get_location(&tmplregion->delarea.x1, &tmplregion->delarea.y1, + ANY_LOC, (struct mkroom *)0); + get_location(&tmplregion->delarea.x2, &tmplregion->delarea.y2, + ANY_LOC, (struct mkroom *)0); + } + if(num_lregions) { + /* realloc the lregion space to add the new one */ + lev_region *newl = (lev_region *) alloc(sizeof(lev_region) * + (unsigned)(1+num_lregions)); + if (!newl) panic("levreg newl alloc"); + (void) memcpy((genericptr_t)(newl), (genericptr_t)lregions, + sizeof(lev_region) * num_lregions); + Free(lregions); + num_lregions++; + lregions = newl; + } else { + num_lregions = 1; + lregions = (lev_region *) alloc(sizeof(lev_region)); + if (!lregions) panic("lregions alloc"); + } + (void) memcpy(&lregions[num_lregions-1], tmplregion, sizeof(lev_region)); + + opvar_free(dx1); + opvar_free(dy1); + opvar_free(dx2); + opvar_free(dy2); + + opvar_free(ix1); + opvar_free(iy1); + opvar_free(ix2); + opvar_free(iy2); + + opvar_free(del_islev); + opvar_free(in_islev); + opvar_free(rname); + opvar_free(rtype); + opvar_free(padding); +} + +void +spo_region(coder) + struct sp_coder *coder; +{ + struct opvar *rtype, *rlit, *rflags, *area; + xchar dx1,dy1,dx2,dy2; + register struct mkroom *troom; + boolean prefilled, room_not_needed, irregular, joined; + + if (!OV_pop_i(rflags) || + !OV_pop_i(rtype) || + !OV_pop_i(rlit) || + !OV_pop_r(area)) return; + + prefilled = !(OV_i(rflags) & (1 << 0)); + irregular = (OV_i(rflags) & (1 << 1)); + joined = !(OV_i(rflags) & (1 << 2)); + + if(OV_i(rtype) > MAXRTYPE) { + OV_i(rtype) -= MAXRTYPE+1; + prefilled = TRUE; + } else + prefilled = FALSE; + + if(OV_i(rlit) < 0) + OV_i(rlit) = (rnd(1+abs(depth(&u.uz))) < 11 && rn2(77)) + ? TRUE : FALSE; + + dx1 = SP_REGION_X1(OV_i(area)); + dy1 = SP_REGION_Y1(OV_i(area)); + dx2 = SP_REGION_X2(OV_i(area)); + dy2 = SP_REGION_Y2(OV_i(area)); + + get_location(&dx1, &dy1, ANY_LOC, (struct mkroom *)0); + get_location(&dx2, &dy2, ANY_LOC, (struct mkroom *)0); + + /* for an ordinary room, `prefilled' is a flag to force + an actual room to be created (such rooms are used to + control placement of migrating monster arrivals) */ + room_not_needed = (OV_i(rtype) == OROOM && + !irregular && !prefilled); + if (room_not_needed || nroom >= MAXNROFROOMS) { + region tmpregion; + if (!room_not_needed) + impossible("Too many rooms on new level!"); + tmpregion.rlit = OV_i(rlit); + tmpregion.x1 = dx1; + tmpregion.y1 = dy1; + tmpregion.x2 = dx2; + tmpregion.y2 = dy2; + light_region(&tmpregion); + + opvar_free(area); + opvar_free(rflags); + opvar_free(rlit); + opvar_free(rtype); + + return; + } + + troom = &rooms[nroom]; + + /* mark rooms that must be filled, but do it later */ + if (OV_i(rtype) != OROOM) + troom->needfill = (prefilled ? 2 : 1); + + troom->needjoining = joined; + + if (irregular) { + min_rx = max_rx = dx1; + min_ry = max_ry = dy1; + smeq[nroom] = nroom; + flood_fill_rm(dx1, dy1, nroom+ROOMOFFSET, + OV_i(rlit), TRUE); + add_room(min_rx, min_ry, max_rx, max_ry, + FALSE, OV_i(rtype), TRUE); + troom->rlit = OV_i(rlit); + troom->irregular = TRUE; + } else { + add_room(dx1, dy1, dx2, dy2, + OV_i(rlit), OV_i(rtype), TRUE); +#ifdef SPECIALIZATION + topologize(troom,FALSE); /* set roomno */ +#else + topologize(troom); /* set roomno */ +#endif + } + + if (!room_not_needed) { + if (coder->n_subroom > 1) + impossible("region as subroom"); + else { + coder->tmproomlist[coder->n_subroom] = troom; + coder->failed_room[coder->n_subroom] = FALSE; + coder->n_subroom++; + } + } + + opvar_free(area); + opvar_free(rflags); + opvar_free(rlit); + opvar_free(rtype); +} + +void +spo_drawbridge(coder) + struct sp_coder *coder; +{ + xchar x,y; + struct opvar *dir, *db_open, *dcoord; + + if (!OV_pop_i(dir) || + !OV_pop_i(db_open) || + !OV_pop_c(dcoord)) return; + + get_location_coord(&x, &y, DRY|WET|HOT, coder->croom, OV_i(dcoord)); + if (!create_drawbridge(x, y, OV_i(dir), OV_i(db_open))) + impossible("Cannot create drawbridge."); + SpLev_Map[x][y] = 1; + + opvar_free(dcoord); + opvar_free(db_open); + opvar_free(dir); +} + +void +spo_mazewalk(coder) + struct sp_coder *coder; +{ + xchar x,y; + struct opvar *ftyp, *fstocked,*fdir, *mcoord; + int dir; + + if (!OV_pop_i(ftyp) || + !OV_pop_i(fstocked) || + !OV_pop_i(fdir) || + !OV_pop_c(mcoord)) return; + + dir = OV_i(fdir); + + get_location_coord(&x, &y, ANY_LOC, coder->croom, OV_i(mcoord)); + if (!isok(x,y)) return; + + if (OV_i(ftyp) < 1) { +#ifndef WALLIFIED_MAZE + OV_i(ftyp) = CORR; +#else + OV_i(ftyp) = ROOM; +#endif + } + + /* don't use move() - it doesn't use W_NORTH, etc. */ + switch (dir) { + case W_NORTH: --y; break; + case W_SOUTH: y++; break; + case W_EAST: x++; break; + case W_WEST: --x; break; + default: + impossible("sp_level_coder: Bad MAZEWALK direction"); + } + + if(!IS_DOOR(levl[x][y].typ)) { + levl[x][y].typ = OV_i(ftyp); + levl[x][y].flags = 0; + } /* - * If bounds_nodigpass, and no mazewalks, mark all locations outside - * the map are mapped as nodig and nopass as well. This avoids passwall - * monsters like Xorns from appearing outside the accessible area. + * We must be sure that the parity of the coordinates for + * walkfrom() is odd. But we must also take into account + * what direction was chosen. */ - if (bounds_nodigpass && !nwalk_sav) { - for(x = 1; x < COLNO; x++) - for(y = 0; y < ROWNO; y++) - if(!Map[x][y]) - levl[x][y].wall_info |= W_NONDIGGABLE|W_NONPASSWALL; + if(!(x % 2)) { + if (dir == W_EAST) + x++; + else + x--; + + /* no need for IS_DOOR check; out of map bounds */ + levl[x][y].typ = OV_i(ftyp); + levl[x][y].flags = 0; + } + + if (!(y % 2)) { + if (dir == W_SOUTH) + y++; + else + y--; + } + + walkfrom(x, y, OV_i(ftyp)); + if (OV_i(fstocked)) fill_empty_maze(); + + opvar_free(mcoord); + opvar_free(fdir); + opvar_free(fstocked); + opvar_free(ftyp); +} + +void +spo_wall_property(coder) + struct sp_coder *coder; +{ + struct opvar *r; + xchar dx1,dy1,dx2,dy2; + int wprop = (coder->opcode == SPO_NON_DIGGABLE) ? W_NONDIGGABLE : W_NONPASSWALL; + + if (!OV_pop_r(r)) return; + + dx1 = SP_REGION_X1(OV_i(r)); + dy1 = SP_REGION_Y1(OV_i(r)); + dx2 = SP_REGION_X2(OV_i(r)); + dy2 = SP_REGION_Y2(OV_i(r)); + + get_location(&dx1, &dy1, ANY_LOC, (struct mkroom *)0); + get_location(&dx2, &dy2, ANY_LOC, (struct mkroom *)0); + + set_wall_property(dx1, dy1, dx2, dy2, wprop); + + opvar_free(r); +} + +void +spo_room_door(coder) + struct sp_coder *coder; +{ + struct opvar *wall, *secret, *mask, *pos; + room_door tmpd; + + if (!OV_pop_i(wall) || + !OV_pop_i(secret) || + !OV_pop_i(mask) || + !OV_pop_i(pos) || + !coder->croom) return; + + tmpd.secret = OV_i(secret); + tmpd.mask = OV_i(mask); + tmpd.pos = OV_i(pos); + tmpd.wall = OV_i(wall); + + create_door(&tmpd, coder->croom); + + opvar_free(wall); + opvar_free(secret); + opvar_free(mask); + opvar_free(pos); +} + +/*ARGSUSED*/ +void +sel_set_wallify(x,y,arg) + int x, y; + genericptr_t arg; +{ + wallify_map(x,y, x,y); +} + +void +spo_wallify(coder) + struct sp_coder *coder; +{ + struct opvar *typ, *r; + int dx1,dy1,dx2,dy2; + if (!OV_pop_i(typ)) return; + switch (OV_i(typ)) { + default: + case 0: + { + if (!OV_pop_r(r)) return; + dx1 = (xchar)SP_REGION_X1(OV_i(r)); + dy1 = (xchar)SP_REGION_Y1(OV_i(r)); + dx2 = (xchar)SP_REGION_X2(OV_i(r)); + dy2 = (xchar)SP_REGION_Y2(OV_i(r)); + wallify_map(dx1 < 0 ? xstart : dx1, + dy1 < 0 ? ystart : dy1, + dx2 < 0 ? xstart+xsize : dx2, + dy2 < 0 ? ystart+ysize : dy2); + } + break; + case 1: + { + if (!OV_pop_typ(r, SPOVAR_SEL)) return; + selection_iterate(r, sel_set_wallify, NULL); + } + break; + } + opvar_free(r); +} + +void +spo_map(coder) + struct sp_coder *coder; +{ + mazepart tmpmazepart; + struct opvar *mpxs, *mpys, *mpmap, *mpa, *mpkeepr, *mpzalign; + xchar halign, valign; + xchar tmpxstart, tmpystart, tmpxsize, tmpysize; + unpacked_coord upc; + + if (!OV_pop_i(mpxs) || + !OV_pop_i(mpys) || + !OV_pop_s(mpmap) || + !OV_pop_i(mpkeepr) || + !OV_pop_i(mpzalign) || + !OV_pop_c(mpa)) return; + + tmpmazepart.xsize = OV_i(mpxs); + tmpmazepart.ysize = OV_i(mpys); + tmpmazepart.zaligntyp = OV_i(mpzalign); + + upc = get_unpacked_coord(OV_i(mpa), ANY_LOC); + tmpmazepart.halign = upc.x; + tmpmazepart.valign = upc.y; + + tmpxsize = xsize; tmpysize = ysize; + tmpxstart = xstart; tmpystart = ystart; + + halign = tmpmazepart.halign; + valign = tmpmazepart.valign; + xsize = tmpmazepart.xsize; + ysize = tmpmazepart.ysize; + switch (tmpmazepart.zaligntyp) { + default: + case 0: + break; + case 1: + switch((int) halign) { + case LEFT: xstart = splev_init_present ? 1 : 3; break; + case H_LEFT: xstart = 2+((x_maze_max-2-xsize)/4); break; + case CENTER: xstart = 2+((x_maze_max-2-xsize)/2); break; + case H_RIGHT: xstart = 2+((x_maze_max-2-xsize)*3/4); break; + case RIGHT: xstart = x_maze_max-xsize-1; break; + } + switch((int) valign) { + case TOP: ystart = 3; break; + case CENTER: ystart = 2+((y_maze_max-2-ysize)/2); break; + case BOTTOM: ystart = y_maze_max-ysize-1; break; + } + if (!(xstart % 2)) xstart++; + if (!(ystart % 2)) ystart++; + break; + case 2: + if (!coder->croom) { + xstart = 1; + ystart = 0; + xsize = COLNO-1-tmpmazepart.xsize; + ysize = ROWNO-tmpmazepart.ysize; + } + get_location_coord(&halign, &valign, ANY_LOC, coder->croom, OV_i(mpa)); + xsize = tmpmazepart.xsize; + ysize = tmpmazepart.ysize; + xstart = halign; + ystart = valign; + break; + } + if ((ystart < 0) || (ystart + ysize > ROWNO)) { + /* try to move the start a bit */ + ystart += (ystart > 0) ? -2 : 2; + if(ysize == ROWNO) ystart = 0; + if(ystart < 0 || ystart + ysize > ROWNO) + panic("reading special level with ysize too large"); + } + if (xsize <= 1 && ysize <= 1) { + xstart = 1; + ystart = 0; + xsize = COLNO-1; + ysize = ROWNO; + } else { + xchar x,y; + /* Load the map */ + for(y = ystart; y < ystart+ysize; y++) + for(x = xstart; x < xstart+xsize; x++) { + xchar mptyp = (mpmap->vardata.str[(y-ystart) * xsize + (x-xstart)] - 1); + if (mptyp >= MAX_TYPE) continue; + levl[x][y].typ = mptyp; + levl[x][y].lit = FALSE; + /* clear out levl: load_common_data may set them */ + levl[x][y].flags = 0; + levl[x][y].horizontal = 0; + levl[x][y].roomno = 0; + levl[x][y].edge = 0; + SpLev_Map[x][y] = 1; + /* + * Set secret doors to closed (why not trapped too?). Set + * the horizontal bit. + */ + if (levl[x][y].typ == SDOOR || IS_DOOR(levl[x][y].typ)) { + if(levl[x][y].typ == SDOOR) + levl[x][y].doormask = D_CLOSED; + /* + * If there is a wall to the left that connects to a + * (secret) door, then it is horizontal. This does + * not allow (secret) doors to be corners of rooms. + */ + if (x != xstart && (IS_WALL(levl[x-1][y].typ) || + levl[x-1][y].horizontal)) + levl[x][y].horizontal = 1; + } else if(levl[x][y].typ == HWALL || + levl[x][y].typ == IRONBARS) + levl[x][y].horizontal = 1; + else if(levl[x][y].typ == LAVAPOOL) + levl[x][y].lit = 1; + else if (splev_init_present && levl[x][y].typ == ICE) + levl[x][y].icedpool = icedpools ? ICED_POOL : ICED_MOAT; + } + if (coder->lvl_is_joined) + remove_rooms(xstart, ystart, xstart+xsize, ystart+ysize); + } + if (!OV_i(mpkeepr)) { + xstart = tmpxstart; ystart = tmpystart; + xsize = tmpxsize; ysize = tmpysize; + } + + opvar_free(mpxs); + opvar_free(mpys); + opvar_free(mpmap); + opvar_free(mpa); + opvar_free(mpkeepr); + opvar_free(mpzalign); +} + +void +spo_jmp(coder, lvl) + struct sp_coder *coder; + sp_lev *lvl; +{ + struct opvar *tmpa; + long a; + if (!OV_pop_i(tmpa)) return; + a = sp_code_jmpaddr(coder->frame->n_opcode, (OV_i(tmpa) - 1)); + if ((a >= 0) && (a < lvl->n_opcodes) && + (a != coder->frame->n_opcode)) + coder->frame->n_opcode = a; + opvar_free(tmpa); +} + +void +spo_conditional_jump(coder,lvl) + struct sp_coder *coder; + sp_lev *lvl; +{ + struct opvar *oa, *oc; + long a,c; + int test = 0; + if (!OV_pop_i(oa) || !OV_pop_i(oc)) return; + + a = sp_code_jmpaddr(coder->frame->n_opcode, (OV_i(oa) - 1)); + c = OV_i(oc); + + switch (coder->opcode) { + default: impossible("spo_conditional_jump: illegal opcode"); break; + case SPO_JL: test = (c & SP_CPUFLAG_LT); break; + case SPO_JLE: test = (c & (SP_CPUFLAG_LT|SP_CPUFLAG_EQ)); break; + case SPO_JG: test = (c & SP_CPUFLAG_GT); break; + case SPO_JGE: test = (c & (SP_CPUFLAG_GT|SP_CPUFLAG_EQ)); break; + case SPO_JE: test = (c & SP_CPUFLAG_EQ); break; + case SPO_JNE: test = (c & ~SP_CPUFLAG_EQ); break; + } + + if ((test) && (a >= 0) && + (a < lvl->n_opcodes) && + (a != coder->frame->n_opcode)) + coder->frame->n_opcode = a; + + opvar_free(oa); + opvar_free(oc); +} + + +void +spo_var_init(coder) + struct sp_coder *coder; +{ + struct opvar *vname; + struct opvar *arraylen; + struct opvar *vvalue; + struct splev_var *tmpvar; + struct splev_var *tmp2; + long idx; + + OV_pop_s(vname); + OV_pop_i(arraylen); + + if (!vname || !arraylen) + panic("no values for SPO_VAR_INIT"); + + tmpvar = opvar_var_defined(coder, OV_s(vname)); + + if (tmpvar) { + /* variable redefinition */ + if (OV_i(arraylen) < 0) { + /* copy variable */ + if (tmpvar->array_len) { + idx = tmpvar->array_len; + while (idx-- > 0) { + opvar_free(tmpvar->data.arrayvalues[idx]); + } + Free(tmpvar->data.arrayvalues); + } else { + opvar_free(tmpvar->data.value); + } + tmpvar->data.arrayvalues = NULL; + goto copy_variable; + } else if (OV_i(arraylen)) { + /* redefined array */ + idx = tmpvar->array_len; + while (idx-- > 0) { + opvar_free(tmpvar->data.arrayvalues[idx]); + } + Free(tmpvar->data.arrayvalues); + tmpvar->data.arrayvalues = NULL; + goto create_new_array; + } else { + /* redefined single value */ + OV_pop(vvalue); + if (tmpvar->svtyp != vvalue->spovartyp) panic("redefining variable as different type"); + opvar_free(tmpvar->data.value); + tmpvar->data.value = vvalue; + tmpvar->array_len = 0; + } + } else { + /* new variable definition */ + tmpvar = (struct splev_var *)malloc(sizeof(struct splev_var)); + if (!tmpvar) panic("newvar tmpvar alloc"); + tmpvar->next = coder->frame->variables; + tmpvar->name = strdup(OV_s(vname)); + coder->frame->variables = tmpvar; + + if (OV_i(arraylen) < 0) { + /* copy variable */ +copy_variable: + OV_pop(vvalue); + tmp2 = opvar_var_defined(coder, OV_s(vvalue)); + if (!tmp2) panic("no copyable var"); + tmpvar->svtyp = tmp2->svtyp; + tmpvar->array_len = tmp2->array_len; + if (tmpvar->array_len) { + idx = tmpvar->array_len; + tmpvar->data.arrayvalues = (struct opvar **)malloc(sizeof(struct opvar *) * idx); + if (!tmpvar->data.arrayvalues) panic("tmpvar->data.arrayvalues alloc"); + while (idx-- > 0) { + tmpvar->data.arrayvalues[idx] = opvar_clone(tmp2->data.arrayvalues[idx]); + } + } else { + tmpvar->data.value = opvar_clone(tmp2->data.value); + } + opvar_free(vvalue); + } else if (OV_i(arraylen)) { + /* new array */ +create_new_array: + idx = OV_i(arraylen); + tmpvar->array_len = idx; + tmpvar->data.arrayvalues = (struct opvar **)malloc(sizeof(struct opvar *) * idx); + if (!tmpvar->data.arrayvalues) panic("malloc tmpvar->data.arrayvalues"); + while (idx-- > 0) { + OV_pop(vvalue); + if (!vvalue) panic("no value for arrayvariable"); + tmpvar->data.arrayvalues[idx] = vvalue; + } + tmpvar->svtyp = SPOVAR_ARRAY; + } else { + /* new single value */ + OV_pop(vvalue); + if (!vvalue) panic("no value for variable"); + tmpvar->svtyp = OV_typ(vvalue); + tmpvar->data.value = vvalue; + tmpvar->array_len = 0; + } + } + + opvar_free(vname); + opvar_free(arraylen); +} + + +long +opvar_array_length(coder) + struct sp_coder *coder; +{ + struct opvar *vname; + struct splev_var *tmp; + long len = 0; + + if (!coder) return 0; + + vname = splev_stack_pop(coder->stack); + if (!vname) return 0; + if (vname->spovartyp != SPOVAR_VARIABLE) goto pass; + + tmp = coder->frame->variables; + while (tmp) { + if (!strcmp(tmp->name, OV_s(vname))) { + if ((tmp->svtyp & SPOVAR_ARRAY)) { + len = tmp->array_len; + if (len < 1) len = 0; + } + goto pass; + } + tmp = tmp->next; + } + +pass: + opvar_free(vname); + return len; +} + + +void +spo_shuffle_array(coder) + struct sp_coder *coder; +{ + struct opvar *vname; + struct splev_var *tmp; + struct opvar *tmp2; + long i,j; + + if (!OV_pop_s(vname)) return; + + tmp = opvar_var_defined(coder, OV_s(vname)); + if (!tmp || (tmp->array_len < 1)) { + opvar_free(vname); + return; + } + for (i = tmp->array_len - 1; i > 0; i--) { + if ((j = rn2(i + 1)) == i) continue; + tmp2 = tmp->data.arrayvalues[j]; + tmp->data.arrayvalues[j] = tmp->data.arrayvalues[i]; + tmp->data.arrayvalues[i] = tmp2; + } + + opvar_free(vname); +} + + + +/* Special level coder, creates the special level from the sp_lev codes. + * Does not free the allocated memory. + */ +STATIC_OVL boolean +sp_level_coder(lvl) +sp_lev *lvl; +{ + unsigned long exec_opcodes = 0; + int tmpi; + long room_stack = 0; + unsigned long max_execution = SPCODER_MAX_RUNTIME; + struct sp_coder *coder = (struct sp_coder *)alloc(sizeof(struct sp_coder)); + if (!coder) panic("coder alloc"); + coder->frame = frame_new(0); + coder->stack = NULL; + coder->premapped = FALSE; + coder->solidify = FALSE; + coder->croom = NULL; + coder->n_subroom = 1; + coder->exit_script = FALSE; + coder->lvl_is_joined = 0; + + splev_init_present = FALSE; + icedpools = FALSE; + + if (wizard) { + char *met = nh_getenv("SPCODER_MAX_RUNTIME"); + if (met && met[0] == '1') max_execution = (1<<30) - 1; + } + + for (tmpi = 0; tmpi <= MAX_NESTED_ROOMS; tmpi++) { + coder->tmproomlist[tmpi] = (struct mkroom *)0; + coder->failed_room[tmpi] = FALSE; + } + + shuffle_alignments(); + + for (tmpi = 0; tmpi < MAX_CONTAINMENT; tmpi++) container_obj[tmpi] = NULL; + container_idx = 0; + + invent_carrying_monster = NULL; + + (void) memset((genericptr_t)&SpLev_Map[0][0], 0, sizeof SpLev_Map); + + level.flags.is_maze_lev = 0; + + xstart = 1; + ystart = 0; + xsize = COLNO-1; + ysize = ROWNO; + + while (coder->frame->n_opcode < lvl->n_opcodes && !coder->exit_script) { + coder->opcode = lvl->opcodes[coder->frame->n_opcode].opcode; + coder->opdat = lvl->opcodes[coder->frame->n_opcode].opdat; + + coder->stack = coder->frame->stack; + + if (exec_opcodes++ > max_execution) { + impossible("Level script is taking too much time, stopping."); + coder->exit_script = TRUE; + } + + if (coder->failed_room[coder->n_subroom-1] && + coder->opcode != SPO_ENDROOM && + coder->opcode != SPO_ROOM && + coder->opcode != SPO_SUBROOM) goto next_opcode; + + coder->croom = coder->tmproomlist[coder->n_subroom-1]; + + switch (coder->opcode) { + case SPO_NULL: break; + case SPO_EXIT: coder->exit_script = TRUE; break; + case SPO_FRAME_PUSH: spo_frame_push(coder); break; + case SPO_FRAME_POP: spo_frame_pop(coder); break; + case SPO_CALL: spo_call(coder); break; + case SPO_RETURN: spo_return(coder); break; + case SPO_END_MONINVENT: spo_end_moninvent(coder); break; + case SPO_POP_CONTAINER: spo_pop_container(coder); break; + case SPO_POP: + { + struct opvar *ov = splev_stack_pop(coder->stack); + opvar_free(ov); + } + break; + case SPO_PUSH: splev_stack_push(coder->stack, opvar_clone(coder->opdat)); break; + case SPO_MESSAGE: spo_message(coder); break; + case SPO_MONSTER: spo_monster(coder); break; + case SPO_OBJECT: spo_object(coder); break; + case SPO_LEVEL_FLAGS: spo_level_flags(coder); break; + case SPO_INITLEVEL: spo_initlevel(coder); break; + case SPO_ENGRAVING: spo_engraving(coder); break; + case SPO_MINERALIZE: spo_mineralize(coder); break; + case SPO_SUBROOM: + case SPO_ROOM: + if (!coder->failed_room[coder->n_subroom-1]) { + spo_room(coder); + } else room_stack++; + break; + case SPO_ENDROOM: + if (coder->failed_room[coder->n_subroom-1]) { + if (!room_stack) + spo_endroom(coder); + else + room_stack--; + } else { + spo_endroom(coder); + } + break; + case SPO_DOOR: spo_door(coder); break; + case SPO_STAIR: spo_stair(coder); break; + case SPO_LADDER: spo_ladder(coder); break; + case SPO_GRAVE: spo_grave(coder); break; + case SPO_ALTAR: spo_altar(coder); break; + case SPO_SINK: + case SPO_POOL: + case SPO_FOUNTAIN: spo_feature(coder); break; + case SPO_TRAP: spo_trap(coder); break; + case SPO_GOLD: spo_gold(coder); break; + case SPO_CORRIDOR: spo_corridor(coder); break; + case SPO_TERRAIN: spo_terrain(coder); break; + case SPO_REPLACETERRAIN: spo_replace_terrain(coder); break; + case SPO_LEVREGION: spo_levregion(coder); break; + case SPO_REGION: spo_region(coder); break; + case SPO_DRAWBRIDGE: spo_drawbridge(coder); break; + case SPO_MAZEWALK: spo_mazewalk(coder); break; + case SPO_NON_PASSWALL: + case SPO_NON_DIGGABLE: spo_wall_property(coder); break; + case SPO_ROOM_DOOR: spo_room_door(coder); break; + case SPO_WALLIFY: spo_wallify(coder); break; + case SPO_COPY: + { + struct opvar *a = splev_stack_pop(coder->stack); + splev_stack_push(coder->stack, opvar_clone(a)); + splev_stack_push(coder->stack, opvar_clone(a)); + opvar_free(a); + } + break; + case SPO_DEC: + { + struct opvar *a; + if (!OV_pop_i(a)) break; + OV_i(a)--; + splev_stack_push(coder->stack, a); + } + break; + case SPO_INC: + { + struct opvar *a; + if (!OV_pop_i(a)) break; + OV_i(a)++; + splev_stack_push(coder->stack, a); + } + break; + case SPO_MATH_SIGN: + { + struct opvar *a; + if (!OV_pop_i(a)) break; + OV_i(a) = ((OV_i(a) < 0) ? -1 : ((OV_i(a) > 0) ? 1 : 0)); + splev_stack_push(coder->stack, a); + } + break; + case SPO_MATH_ADD: + { + struct opvar *a, *b; + if (!OV_pop(b) || !OV_pop(a)) break; + if (OV_typ(b) == OV_typ(a)) { + if (OV_typ(a) == SPOVAR_INT) { + OV_i(a) = OV_i(a) + OV_i(b); + splev_stack_push(coder->stack, a); + opvar_free(b); + } else if (OV_typ(a) == SPOVAR_STRING) { + char *tmpbuf = (char *)alloc(strlen(OV_s(a)) + strlen(OV_s(b)) + 1); + if (tmpbuf) { + struct opvar *c; + (void) sprintf(tmpbuf, "%s%s", OV_s(a), OV_s(b)); + c = opvar_new_str(tmpbuf); + splev_stack_push(coder->stack, c); + opvar_free(a); + opvar_free(b); + Free(tmpbuf); + } else { + splev_stack_push(coder->stack, a); + opvar_free(b); + impossible("malloc at str concat"); + } + } else { + splev_stack_push(coder->stack, a); + opvar_free(b); + impossible("adding weird types"); + } + } else { + splev_stack_push(coder->stack, a); + opvar_free(b); + impossible("adding different types"); + } + } + break; + case SPO_MATH_SUB: + { + struct opvar *a, *b; + if (!OV_pop_i(b) || !OV_pop_i(a)) break; + OV_i(a) = OV_i(a) - OV_i(b); + splev_stack_push(coder->stack, a); + opvar_free(b); + } + break; + case SPO_MATH_MUL: + { + struct opvar *a, *b; + if (!OV_pop_i(b) || !OV_pop_i(a)) break; + OV_i(a) = OV_i(a) * OV_i(b); + splev_stack_push(coder->stack, a); + opvar_free(b); + } + break; + case SPO_MATH_DIV: + { + struct opvar *a, *b; + if (!OV_pop_i(b) || !OV_pop_i(a)) break; + if (OV_i(b) >= 1) { + OV_i(a) = OV_i(a) / OV_i(b); + } else { + OV_i(a) = 0; + } + splev_stack_push(coder->stack, a); + opvar_free(b); + } + break; + case SPO_MATH_MOD: + { + struct opvar *a, *b; + if (!OV_pop_i(b) || !OV_pop_i(a)) break; + if (OV_i(b) > 0) { + OV_i(a) = OV_i(a) % OV_i(b); + } else { + OV_i(a) = 0; + } + splev_stack_push(coder->stack, a); + opvar_free(b); + } + break; + case SPO_CMP: + { + struct opvar *a; + struct opvar *b; + struct opvar *c; + long val = 0; + + OV_pop(b); + OV_pop(a); + + if (!a || !b) { + impossible("spo_cmp: no values in stack"); + break; + } + + if (OV_typ(a) != OV_typ(b)) { + impossible("spo_cmp: trying to compare differing datatypes"); + break; + } + + switch (OV_typ(a)) { + case SPOVAR_COORD: + case SPOVAR_REGION: + case SPOVAR_MAPCHAR: + case SPOVAR_MONST: + case SPOVAR_OBJ: + case SPOVAR_INT: + if (OV_i(b) > OV_i(a)) val |= SP_CPUFLAG_LT; + if (OV_i(b) < OV_i(a)) val |= SP_CPUFLAG_GT; + if (OV_i(b) == OV_i(a)) val |= SP_CPUFLAG_EQ; + c = opvar_new_int(val); + break; + case SPOVAR_STRING: + c = opvar_new_int(((!strcmp(OV_s(b), OV_s(a))) ? SP_CPUFLAG_EQ : 0)); + break; + default: + c = opvar_new_int(0); + break; + } + splev_stack_push(coder->stack, c); + opvar_free(a); + opvar_free(b); + } + break; + case SPO_JMP: + spo_jmp(coder, lvl); break; + case SPO_JL: + case SPO_JLE: + case SPO_JG: + case SPO_JGE: + case SPO_JE: + case SPO_JNE: + spo_conditional_jump(coder, lvl); break; + case SPO_RN2: + { + struct opvar *tmpv; + struct opvar *t; + if (!OV_pop_i(tmpv)) break; + t = opvar_new_int((OV_i(tmpv) > 1) ? rn2(OV_i(tmpv)) : 0); + splev_stack_push(coder->stack, t); + opvar_free(tmpv); + } + break; + case SPO_DICE: + { + struct opvar *a, *b, *t; + if (!OV_pop_i(b) || !OV_pop_i(a)) break; + if (OV_i(b) < 1) OV_i(b) = 1; + if (OV_i(a) < 1) OV_i(a) = 1; + t = opvar_new_int(d(OV_i(a), OV_i(b))); + splev_stack_push(coder->stack, t); + opvar_free(a); + opvar_free(b); + } + break; + case SPO_MAP: + spo_map(coder); break; + case SPO_VAR_INIT: + spo_var_init(coder); break; + case SPO_SHUFFLE_ARRAY: + spo_shuffle_array(coder); break; + case SPO_SEL_ADD: /* actually, logical or */ + { + struct opvar *sel1, *sel2, *pt; + if (!OV_pop_typ(sel1, SPOVAR_SEL)) panic("no sel1 for add"); + if (!OV_pop_typ(sel2, SPOVAR_SEL)) panic("no sel2 for add"); + pt = selection_logical_oper(sel1, sel2, '|'); + opvar_free(sel1); + opvar_free(sel2); + splev_stack_push(coder->stack, pt); + } + break; + case SPO_SEL_COMPLEMENT: + { + struct opvar *sel, *pt; + if (!OV_pop_typ(sel, SPOVAR_SEL)) panic("no sel for not"); + pt = selection_not(sel); + opvar_free(sel); + splev_stack_push(coder->stack, pt); + } + break; + case SPO_SEL_FILTER: /* sorta like logical and */ + { + struct opvar *filtertype; + if (!OV_pop_i(filtertype)) panic("no sel filter type"); + switch (OV_i(filtertype)) { + case SPOFILTER_PERCENT: + { + struct opvar *tmp1, *sel; + if (!OV_pop_i(tmp1)) panic("no sel filter percent"); + if (!OV_pop_typ(sel, SPOVAR_SEL)) panic("no sel filter"); + selection_filter_percent(sel, OV_i(tmp1)); + splev_stack_push(coder->stack, sel); + opvar_free(tmp1); + } + break; + case SPOFILTER_SELECTION: /* logical and */ + { + struct opvar *pt, *sel1, *sel2; + if (!OV_pop_typ(sel1, SPOVAR_SEL)) panic("no sel filter sel1"); + if (!OV_pop_typ(sel2, SPOVAR_SEL)) panic("no sel filter sel2"); + pt = selection_logical_oper(sel1, sel2, '&'); + splev_stack_push(coder->stack, pt); + opvar_free(sel1); + opvar_free(sel2); + } + break; + case SPOFILTER_MAPCHAR: + { + struct opvar *pt, *tmp1, *sel; + if (!OV_pop_typ(sel, SPOVAR_SEL)) panic("no sel filter"); + if (!OV_pop_typ(tmp1, SPOVAR_MAPCHAR)) panic("no sel filter mapchar"); + pt = selection_filter_mapchar(sel, tmp1); + splev_stack_push(coder->stack, pt); + opvar_free(tmp1); + opvar_free(sel); + } + break; + default: panic("unknown sel filter type"); + } + opvar_free(filtertype); + } + break; + case SPO_SEL_POINT: + { + struct opvar *tmp; + struct opvar *pt = selection_opvar(NULL); + schar x,y; + if (!OV_pop_c(tmp)) panic("no ter sel coord"); + get_location_coord(&x, &y, ANY_LOC, coder->croom, OV_i(tmp)); + selection_setpoint(x,y, pt, 1); + splev_stack_push(coder->stack, pt); + opvar_free(tmp); + } + break; + case SPO_SEL_RECT: + case SPO_SEL_FILLRECT: + { + struct opvar *tmp, *pt = selection_opvar(NULL); + schar x,y,x1,y1,x2,y2; + if (!OV_pop_r(tmp)) panic("no ter sel region"); + x1 = min(SP_REGION_X1(OV_i(tmp)), SP_REGION_X2(OV_i(tmp))); + y1 = min(SP_REGION_Y1(OV_i(tmp)), SP_REGION_Y2(OV_i(tmp))); + x2 = max(SP_REGION_X1(OV_i(tmp)), SP_REGION_X2(OV_i(tmp))); + y2 = max(SP_REGION_Y1(OV_i(tmp)), SP_REGION_Y2(OV_i(tmp))); + get_location(&x1, &y1, ANY_LOC, coder->croom); + get_location(&x2, &y2, ANY_LOC, coder->croom); + x1 = (x1 < 0) ? 0 : x1; + y1 = (y1 < 0) ? 0 : y1; + x2 = (x2 >= COLNO) ? COLNO-1 : x2; + y2 = (y2 >= ROWNO) ? ROWNO-1 : y2; + if (coder->opcode == SPO_SEL_RECT) { + for (x = x1; x <= x2; x++) { + selection_setpoint(x,y1, pt, 1); + selection_setpoint(x,y2, pt, 1); + } + for (y = y1; y <= y2; y++) { + selection_setpoint(x1,y, pt, 1); + selection_setpoint(x2,y, pt, 1); + } + } else { + for (x = x1; x <= x2; x++) + for (y = y1; y <= y2; y++) + selection_setpoint(x,y, pt, 1); + } + splev_stack_push(coder->stack, pt); + opvar_free(tmp); + } + break; + case SPO_SEL_LINE: + { + struct opvar *tmp, *tmp2, *pt = selection_opvar(NULL); + schar x1,y1,x2,y2; + if (!OV_pop_c(tmp)) panic("no ter sel linecoord1"); + if (!OV_pop_c(tmp2)) panic("no ter sel linecoord2"); + get_location_coord(&x1, &y1, ANY_LOC, coder->croom, OV_i(tmp)); + get_location_coord(&x2, &y2, ANY_LOC, coder->croom, OV_i(tmp2)); + x1 = (x1 < 0) ? 0 : x1; + y1 = (y1 < 0) ? 0 : y1; + x2 = (x2 >= COLNO) ? COLNO-1 : x2; + y2 = (y2 >= ROWNO) ? ROWNO-1 : y2; + selection_do_line(x1,y1,x2,y2, pt); + splev_stack_push(coder->stack, pt); + opvar_free(tmp); + opvar_free(tmp2); + } + break; + case SPO_SEL_RNDLINE: + { + struct opvar *tmp, *tmp2, *tmp3, *pt = selection_opvar(NULL); + schar x1,y1,x2,y2; + if (!OV_pop_i(tmp3)) panic("no ter sel randline1"); + if (!OV_pop_c(tmp)) panic("no ter sel randline2"); + if (!OV_pop_c(tmp2)) panic("no ter sel randline3"); + get_location_coord(&x1, &y1, ANY_LOC, coder->croom, OV_i(tmp)); + get_location_coord(&x2, &y2, ANY_LOC, coder->croom, OV_i(tmp2)); + x1 = (x1 < 0) ? 0 : x1; + y1 = (y1 < 0) ? 0 : y1; + x2 = (x2 >= COLNO) ? COLNO-1 : x2; + y2 = (y2 >= ROWNO) ? ROWNO-1 : y2; + selection_do_randline(x1,y1,x2,y2, OV_i(tmp3), 12, pt); + splev_stack_push(coder->stack, pt); + opvar_free(tmp); + opvar_free(tmp2); + opvar_free(tmp3); + } + break; + case SPO_SEL_GROW: + { + struct opvar *dirs, *pt; + if (!OV_pop_i(dirs)) panic("no dirs for grow"); + if (!OV_pop_typ(pt, SPOVAR_SEL)) panic("no selection for grow"); + selection_do_grow(pt, OV_i(dirs)); + splev_stack_push(coder->stack, pt); + opvar_free(dirs); + } + break; + case SPO_SEL_FLOOD: + { + struct opvar *tmp; + schar x,y; + if (!OV_pop_c(tmp)) panic("no ter sel flood coord"); + get_location_coord(&x, &y, ANY_LOC, coder->croom, OV_i(tmp)); + if (isok(x,y)) { + struct opvar *pt = selection_opvar(NULL); + selection_floodfill(pt, x,y); + splev_stack_push(coder->stack, pt); + } + opvar_free(tmp); + } + break; + case SPO_SEL_RNDCOORD: + { + struct opvar *pt; + schar x,y; + if (!OV_pop_typ(pt, SPOVAR_SEL)) panic("no selection for rndcoord"); + if (selection_rndcoord(pt, &x, &y)) { + x -= xstart; + y -= ystart; + } + splev_stack_push(coder->stack, opvar_new_coord(x,y)); + opvar_free(pt); + } + break; + case SPO_SEL_ELLIPSE: + { + struct opvar *filled, *xaxis, *yaxis, *pt; + struct opvar *sel = selection_opvar(NULL); + schar x,y; + if (!OV_pop_i(filled)) panic("no filled for ellipse"); + if (!OV_pop_i(yaxis)) panic("no yaxis for ellipse"); + if (!OV_pop_i(xaxis)) panic("no xaxis for ellipse"); + if (!OV_pop_c(pt)) panic("no pt for ellipse"); + get_location_coord(&x, &y, ANY_LOC, coder->croom, OV_i(pt)); + selection_do_ellipse(sel, x,y, OV_i(xaxis), OV_i(yaxis), OV_i(filled)); + splev_stack_push(coder->stack, sel); + opvar_free(filled); + opvar_free(yaxis); + opvar_free(xaxis); + opvar_free(pt); + } + break; + case SPO_SEL_GRADIENT: + { + struct opvar *gtyp, *glim, *mind, *maxd, *gcoord, *coord2; + struct opvar *sel; + schar x,y, x2,y2; + if (!OV_pop_i(gtyp)) panic("no gtyp for grad"); + if (!OV_pop_i(glim)) panic("no glim for grad"); + if (!OV_pop_c(coord2)) panic("no coord2 for grad"); + if (!OV_pop_c(gcoord)) panic("no coord for grad"); + if (!OV_pop_i(maxd)) panic("no maxd for grad"); + if (!OV_pop_i(mind)) panic("no mind for grad"); + get_location_coord(&x, &y, ANY_LOC, coder->croom, + OV_i(gcoord)); + get_location_coord(&x2, &y2, ANY_LOC, coder->croom, + OV_i(coord2)); + + sel = selection_opvar(NULL); + selection_do_gradient(sel, x,y, x2,y2, OV_i(gtyp), + OV_i(mind), OV_i(maxd), OV_i(glim)); + splev_stack_push(coder->stack, sel); + + opvar_free(gtyp); + opvar_free(glim); + opvar_free(gcoord); + opvar_free(coord2); + opvar_free(maxd); + opvar_free(mind); + } + break; + default: + panic("sp_level_coder: Unknown opcode %i", coder->opcode); + } + +next_opcode: + coder->frame->n_opcode++; + } /*while*/ + + link_doors_rooms(); + fill_rooms(); + remove_boundary_syms(); + wallification(1, 0, COLNO-1, ROWNO-1); + + count_features(); + + if (coder->premapped) sokoban_detect(); + if (coder->solidify) solidify_map(); + + if (coder->frame) { + struct sp_frame *tmpframe; + do { + tmpframe = coder->frame->next; + frame_del(coder->frame); + coder->frame = tmpframe; + } while (coder->frame); } return TRUE; @@ -2728,32 +5105,28 @@ load_special(name) const char *name; { dlb *fd; + sp_lev *lvl = NULL; boolean result = FALSE; - char c; struct version_info vers_info; fd = dlb_fopen(name, RDBMODE); if (!fd) return FALSE; - Fread((genericptr_t) &vers_info, sizeof vers_info, 1, fd); - if (!check_version(&vers_info, name, TRUE)) + if (!check_version(&vers_info, name, TRUE)) { + (void)dlb_fclose(fd); goto give_up; - - Fread((genericptr_t) &c, sizeof c, 1, fd); /* c Header */ - - switch (c) { - case SP_LEV_ROOMS: - result = load_rooms(fd); - break; - case SP_LEV_MAZE: - result = load_maze(fd); - break; - default: /* ??? */ - result = FALSE; } - give_up: + lvl = (sp_lev *)alloc(sizeof(sp_lev)); + if (!lvl) panic("alloc sp_lev"); + result = sp_level_loader(fd, lvl); (void)dlb_fclose(fd); + if (result) result = sp_level_coder(lvl); + sp_level_free(lvl); + Free(lvl); + + give_up: return result; } + /*sp_lev.c*/ diff --git a/src/spell.c b/src/spell.c index e5e208046..a9a9d7fb4 100644 --- a/src/spell.c +++ b/src/spell.c @@ -42,7 +42,6 @@ STATIC_DCL int NDECL(throwspell); STATIC_DCL void NDECL(cast_protection); STATIC_DCL void FDECL(spell_backfire, (int)); STATIC_DCL const char *FDECL(spelltypemnemonic, (int)); -STATIC_DCL int FDECL(isqrt, (int)); /* The roles[] table lists the role-specific values for tuning * percent_success(). @@ -329,6 +328,7 @@ learn(VOID_ARGS) context.spbook.book = 0; /* no longer studying */ context.spbook.o_id = 0; nomul(context.spbook.delay); /* remaining delay is uninterrupted */ + multi_reason = "reading a book"; nomovemsg = 0; context.spbook.delay = 0; return(0); @@ -517,6 +517,7 @@ register struct obj *spellbook; boolean gone = cursed_book(spellbook); nomul(context.spbook.delay); /* study time */ + multi_reason = "reading a book"; nomovemsg = 0; context.spbook.delay = 0; if(gone || !rn2(3)) { @@ -533,6 +534,7 @@ register struct obj *spellbook; spellbook->in_use = FALSE; } nomul(context.spbook.delay); + multi_reason = "reading a book"; nomovemsg = 0; context.spbook.delay = 0; return(1); @@ -1441,29 +1443,6 @@ int *spell_no; return FALSE; } -/* Integer square root function without using floating point. - * This could be replaced by a faster algorithm, but has not been because: - * + the simple algorithm is easy to read - * + this algorithm does not require 64-bit support - * + in current usage, the values passed to isqrt() are not really that - * large, so the performance difference is negligible - * + isqrt() is used in only one place - * + that one place is not a bottle-neck - */ -STATIC_OVL int -isqrt(val) -int val; -{ - int rt = 0; - int odd = 1; - while(val >= odd) { - val = val-odd; - odd = odd+2; - rt = rt + 1; - } - return rt; -} - STATIC_OVL int percent_success(spell) int spell; diff --git a/src/steal.c b/src/steal.c index c73878310..f803ae4da 100644 --- a/src/steal.c +++ b/src/steal.c @@ -361,6 +361,7 @@ gotobj: named++; /* the following is to set multi for later on */ nomul(-armordelay); + multi_reason = "taking off clothes"; nomovemsg = 0; remove_worn_item(otmp, TRUE); otmp->cursed = curssv; diff --git a/src/sys.c b/src/sys.c index 35e46b7c8..6ca0017f7 100644 --- a/src/sys.c +++ b/src/sys.c @@ -33,6 +33,7 @@ sys_early_init() #endif sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */ sysopt.shellers = NULL; + sysopt.explorers = NULL; sysopt.maxplayers = 0; /* XXX eventually replace MAX_NR_OF_PLAYERS */ /* record file */ diff --git a/src/timeout.c b/src/timeout.c index e47d863fb..e1ccaf96e 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -51,6 +51,7 @@ stoned_dialogue() case 3: /* limbs turned to stone */ stop_occupation(); nomul(-3); /* can't move anymore */ + multi_reason = "getting stoned"; nomovemsg = You_can_move_again; /* not unconscious */ break; default: @@ -377,6 +378,7 @@ nh_timeout() if (u.umoved && !Levitation) { slip_or_trip(); nomul(-2); + multi_reason = "fumbling"; nomovemsg = ""; /* The more you are carrying the more likely you * are to make noise when you fumble. Adjustments @@ -409,6 +411,7 @@ boolean wakeup_msg; { stop_occupation(); nomul(how_long); + multi_reason = "sleeping"; /* generally don't notice sounds while sleeping */ if (wakeup_msg && multi == how_long) { /* caller can follow with a direct call to Hear_again() if @@ -1271,6 +1274,7 @@ do_storms() if(!u.uinvulnerable) { stop_occupation(); nomul(-3); + multi_reason = "hiding from thunderstorm"; nomovemsg = 0; } } else diff --git a/src/topten.c b/src/topten.c index b68ad1bce..c803aac39 100644 --- a/src/topten.c +++ b/src/topten.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 topten.c $NHDT-Date: 1426731079 2015/03/19 02:11:19 $ $NHDT-Branch: harder_d8 $:$NHDT-Revision: 1.25 $ */ +/* NetHack 3.5 topten.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* NetHack 3.5 topten.c $Date: 2012/01/24 04:26:15 $ $Revision: 1.23 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -66,6 +66,7 @@ STATIC_DCL void FDECL(discardexcess, (FILE *)); STATIC_DCL void FDECL(readentry, (FILE *,struct toptenentry *)); STATIC_DCL void FDECL(writeentry, (FILE *,struct toptenentry *)); STATIC_DCL void FDECL(writexlentry, (FILE*, struct toptenentry *)); +STATIC_DCL long NDECL(encodexlogflags); STATIC_DCL long NDECL(encodeconduct); STATIC_DCL long NDECL(encodeachieve); STATIC_DCL void FDECL(free_ttlist, (struct toptenentry *)); @@ -341,10 +342,24 @@ struct toptenentry *tt; Fprintf(rfile, "%cgender0=%s%calign0=%s", XLOG_SEP, genders[flags.initgend].filecode, XLOG_SEP, aligns[1 - u.ualignbase[A_ORIGINAL]].filecode); + Fprintf(rfile, "%cflags=0x%lx", + XLOG_SEP, encodexlogflags()); Fprintf(rfile, "\n"); #undef XLOG_SEP } +STATIC_OVL long +encodexlogflags() +{ + long e = 0L; + + if (wizard) e |= 1L << 0; + if (discover) e |= 1L << 1; + if (!u.uroleplay.numbones) e |= 1L << 2; + + return e; +} + STATIC_OVL long encodeconduct() { @@ -383,6 +398,8 @@ encodeachieve() if(u.uachieve.mines_luckstone) r |= 1L << 9; if(u.uachieve.finish_sokoban) r |= 1L << 10; if(u.uachieve.killed_medusa) r |= 1L << 11; + if(u.uroleplay.blind) r |= 1L << 12; + if(u.uroleplay.nudist) r |= 1L << 13; return r; } diff --git a/src/trap.c b/src/trap.c index a0c6fa1b1..c826fb851 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 trap.c $NHDT-Date: 1426805491 2015/03/19 22:51:31 $ $NHDT-Branch: water_damage $:$NHDT-Revision: 1.198 $ */ +/* NetHack 3.5 trap.c $NHDT-Date: 1427934551 2015/04/02 00:29:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.223 $ */ /* NetHack 3.5 trap.c $Date: 2013/03/14 01:58:21 $ $Revision: 1.179 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -946,6 +946,7 @@ unsigned trflags; } else { pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u], body_part(FOOT)); + set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10,10)); if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) You("howl in anger!"); losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN); @@ -1406,13 +1407,12 @@ struct obj *otmp; { struct monst *steed = u.usteed; int tt; - boolean in_sight, trapkilled, steedhit; + boolean trapkilled, steedhit; if (!steed || !trap) return 0; tt = trap->ttyp; steed->mx = u.ux; steed->my = u.uy; - in_sight = !Blind; trapkilled = steedhit = FALSE; switch (tt) { @@ -3118,13 +3118,17 @@ acid_damage(obj) struct obj *obj; { /* Scrolls but not spellbooks can be erased by acid. */ - struct monst *victim = - carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL; - boolean vismon = victim && (victim != &youmonst) && canseemon(victim); + struct monst *victim; + boolean vismon; - if (obj->greased) + if (!obj) return; + + victim = carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL; + vismon = victim && (victim != &youmonst) && canseemon(victim); + + if (obj->greased) { grease_protect(obj, NULL, victim); - else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) { + } else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) { if (obj->otyp != SCR_BLANK_PAPER #ifdef MAIL && obj->otyp != SCR_MAIL @@ -3571,7 +3575,7 @@ boolean bury_it; place_object(otmp, ttmp->tx, ttmp->ty); if (bury_it) { /* magical digging first disarms this trap, then will unearth it */ - (void) bury_an_obj(otmp); + (void) bury_an_obj(otmp, NULL); } else { /* Sell your own traps only... */ if (ttmp->madeby_u) sellobj(otmp, ttmp->tx, ttmp->ty); @@ -4443,6 +4447,7 @@ boolean disarm; if (!Free_action) { pline("Suddenly you are frozen in place!"); nomul(-d(5, 6)); + multi_reason = "frozen by a trap"; exercise(A_DEX, FALSE); nomovemsg = You_can_move_again; } else You("momentarily stiffen."); diff --git a/src/u_init.c b/src/u_init.c index 79954841c..3c32637dd 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -491,6 +491,7 @@ void u_init() { register int i; + struct u_roleplay tmpuroleplay = u.uroleplay; /* these set by rcfile options */ flags.female = flags.initgend; flags.beginner = 1; @@ -502,6 +503,8 @@ u_init() (void) memset((genericptr_t)&ubirthday, 0, sizeof(ubirthday)); (void) memset((genericptr_t)&urealtime, 0, sizeof(urealtime)); + u.uroleplay = tmpuroleplay; /* restore options set via rcfile */ + #if 0 /* documentation of more zero values as desirable */ u.usick_cause[0] = 0; u.uluck = u.moreluck = 0; @@ -922,6 +925,13 @@ register struct trobj *trop; nocreate4 = otyp; } + /* nudist gets no armor */ + if (u.uroleplay.nudist && obj->oclass == ARMOR_CLASS) { + dealloc_obj(obj); + trop++; + continue; + } + if (trop->trclass == COIN_CLASS) { /* no "blessed" or "identified" money */ obj->quan = u.umoney0; diff --git a/src/uhitm.c b/src/uhitm.c index 80f38addf..2bf963c94 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1871,6 +1871,7 @@ register struct attack *mattk; You("digest %s.", mon_nam(mdef)); if (Slow_digestion) tmp *= 2; nomul(-tmp); + multi_reason = "digesting something"; nomovemsg = msgbuf; } else pline1(msgbuf); if (pd == &mons[PM_GREEN_SLIME]) { @@ -2353,6 +2354,7 @@ boolean wep_was_destroyed; You("are frozen by %s gaze!", s_suffix(mon_nam(mon))); nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127); + multi_reason = "frozen by a monster's gaze"; nomovemsg = 0; } } else { @@ -2366,6 +2368,7 @@ boolean wep_was_destroyed; You("are frozen by %s!", mon_nam(mon)); nomovemsg = You_can_move_again; nomul(-tmp); + multi_reason = "frozen by a monster"; exercise(A_DEX, FALSE); } break; diff --git a/src/vision.c b/src/vision.c index a6585de14..8abf63c79 100644 --- a/src/vision.c +++ b/src/vision.c @@ -2198,9 +2198,9 @@ right_side(row, left, right_mark, limits) int deeper; /* if TRUE, call self as needed */ int result; /* set by q?_path() */ register int i; /* loop counter */ - register char *rowp; /* row optimization */ - char *row_min; /* left most [used by macro set_min()] */ - char *row_max; /* right most [used by macro set_max()] */ + register char *rowp = NULL; /* row optimization */ + char *row_min = NULL; /* left most [used by macro set_min()] */ + char *row_max = NULL; /* right most [used by macro set_max()] */ int lim_max; /* right most limit of circle */ #ifdef GCC_WARN @@ -2374,8 +2374,8 @@ left_side(row, left_mark, right, limits) { int left, left_edge, nrow, deeper, result; register int i; - register char *rowp; - char *row_min, *row_max; + register char *rowp = NULL; + char *row_min = NULL, *row_max = NULL; int lim_min; #ifdef GCC_WARN diff --git a/src/wield.c b/src/wield.c index 9e1447bff..c70bec601 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 wield.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 wield.c $NHDT-Date: 1427062304 2015/03/22 22:11:44 $ $NHDT-Branch: master $:$NHDT-Revision: 1.34 $ */ /* NetHack 3.5 wield.c $Date: 2009/05/06 10:48:14 $ $Revision: 1.31 $ */ /* SCCS Id: @(#)wield.c 3.5 2009/01/20 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ @@ -349,10 +349,6 @@ dowieldquiver() /* will_weld(), touch_petrifies(), etc. */ multi = 0; - /* Because 'Q' used to be quit... */ - if (flags.suppress_alert < FEATURE_NOTICE_VER(3,3,0)) - pline("Note: Please use #quit if you wish to exit the game."); - /* Prompt for a new quiver */ if (!(newquiver = getobj(quivee_types, "ready"))) /* Cancelled */ diff --git a/src/worn.c b/src/worn.c index a542f3be4..b810332ea 100644 --- a/src/worn.c +++ b/src/worn.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 worn.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 worn.c $NHDT-Date: 1427580338 2015/03/28 22:05:38 $ $NHDT-Branch: master $:$NHDT-Revision: 1.35 $ */ /* NetHack 3.5 worn.c $Date: 2013/11/05 00:57:56 $ $Revision: 1.32 $ */ /* SCCS Id: @(#)worn.c 3.5 2009/02/28 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ @@ -57,6 +57,7 @@ long mask; uskin = obj; /* assert( !uarm ); */ } else { + if ((mask & W_ARMOR)) u.uroleplay.nudist = FALSE; for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) { oobj = *(wp->w_obj); if(oobj && !(oobj->owornmask & wp->w_mask)) @@ -591,9 +592,7 @@ long flag; case W_ARMS: return uarms; case W_ARMG: return uarmg; case W_ARMF: return uarmf; -#ifdef TOURIST case W_ARMU: return uarmu; -#endif default: impossible("bad flag in which_armor"); return 0; diff --git a/src/zap.c b/src/zap.c index 3134c8b88..2852cf995 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 zap.c $NHDT-Date: 1426465444 2015/03/16 00:24:04 $ $NHDT-Branch: debug $:$NHDT-Revision: 1.195 $ */ +/* NetHack 3.5 zap.c $NHDT-Date: 1427782839 2015/03/31 06:20:39 $ $NHDT-Branch: master $:$NHDT-Revision: 1.200 $ */ /* NetHack 3.5 zap.c $Date: 2013/11/05 00:57:56 $ $Revision: 1.183 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1750,8 +1750,14 @@ struct obj *obj, *otmp; if (Is_box(obj)) (void) boxlock(obj, otmp); if (obj_shudders(obj)) { + boolean cover = ((obj == level.objects[u.ux][u.uy]) && + u.uundetected && + hides_under(youmonst.data)); + if (cansee(obj->ox, obj->oy)) learn_it = TRUE; do_osshock(obj); + /* eek - your cover might have been blown */ + if (cover) (void) hideunder(&youmonst); break; } obj = poly_obj(obj, STRANGE_OBJECT); @@ -1886,10 +1892,11 @@ struct obj *obj, *otmp; /* returns nonzero if something was hit */ int -bhitpile(obj,fhito,tx,ty) +bhitpile(obj, fhito, tx, ty, zz) struct obj *obj; int FDECL((*fhito), (OBJ_P,OBJ_P)); int tx, ty; + schar zz; { int hitanything = 0; register struct obj *otmp, *next_obj; @@ -1909,8 +1916,11 @@ bhitpile(obj,fhito,tx,ty) poly_zapped = -1; for(otmp = level.objects[tx][ty]; otmp; otmp = next_obj) { - /* Fix for polymorph bug, Tim Wright */ next_obj = otmp->nexthere; + /* for zap downwards, don't hit object poly'd hero is hiding under */ + if (zz > 0 && u.uundetected && otmp == level.objects[u.ux][u.uy] + && hides_under(youmonst.data)) continue; + hitanything += (*fhito)(otmp, obj); } if(poly_zapped >= 0) @@ -2562,7 +2572,7 @@ struct obj *obj; /* wand or spell */ if (u.dz < 0) { You("probe towards the %s.", ceiling(x,y)); } else { - ptmp += bhitpile(obj, bhito, x, y); + ptmp += bhitpile(obj, bhito, x, y, u.dz); You("probe beneath the %s.", surface(x,y)); ptmp += display_binventory(x, y, TRUE); } @@ -2682,7 +2692,7 @@ struct obj *obj; /* wand or spell */ if (u.dz > 0) { /* zapping downward */ - (void) bhitpile(obj, bhito, x, y); + (void) bhitpile(obj, bhito, x, y, u.dz); /* subset of engraving effects; none sets `disclose' */ if ((e = engr_at(x, y)) != 0 && e->engr_type != HEADSTONE) { @@ -2718,6 +2728,22 @@ struct obj *obj; /* wand or spell */ break; } } + } else if (u.dz < 0) { + /* zapping upward */ + + /* game flavor: if you're hiding under "something" + * a zap upward should hit that "something". + */ + if (u.uundetected && hides_under(youmonst.data)) { + int hitit = 0; + otmp = level.objects[u.ux][u.uy]; + + if (otmp) hitit = bhito(otmp, obj); + if (hitit) { + (void) hideunder(&youmonst); + disclose = TRUE; + } + } } return disclose; @@ -3089,7 +3115,7 @@ struct obj **pobj; /* object tossed/used, set to NULL } } if(fhito) { - if(bhitpile(obj,fhito,bhitpos.x,bhitpos.y)) + if(bhitpile(obj,fhito,bhitpos.x,bhitpos.y,0)) range--; } else { if(weapon == KICKED_WEAPON && @@ -3253,8 +3279,10 @@ int dx, dy; } tmp_at(bhitpos.x, bhitpos.y); delay_output(); - if(IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) + if(IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) { + if (!Deaf) pline("Klonk!"); break; /* boomerang falls on sink */ + } /* ct==0, initial position, we want next delta to be same; ct==5, opposite position, repeat delta undoes first one */ if (ct % 5 != 0) i += (counterclockwise ? -1 : 1); diff --git a/sys/amiga/.gitattributes b/sys/amiga/.gitattributes index 7a28030a9..7735c64ea 100644 --- a/sys/amiga/.gitattributes +++ b/sys/amiga/.gitattributes @@ -1 +1 @@ -*.p filter=NHtext merge=NHsubst +*.p NHSUBST diff --git a/sys/mac/.gitattributes b/sys/mac/.gitattributes index 62b9832d7..8f8defc69 100644 --- a/sys/mac/.gitattributes +++ b/sys/mac/.gitattributes @@ -1 +1 @@ -NHDeflts filter=NHtext merge=NHsubst +NHDeflts NHSUBST diff --git a/sys/msdos/.gitattributes b/sys/msdos/.gitattributes index baef52e46..7e8941f2d 100644 --- a/sys/msdos/.gitattributes +++ b/sys/msdos/.gitattributes @@ -1,4 +1,4 @@ -*.BC filter=NHtext merge=NHsubst -*.bat filter=NHtext merge=NHsubst -Makefile.* filter=NHtext merge=NHsubst -Install.* filter=NHtext merge=NHsubst +*.BC NHSUBST +*.bat NHSUBST +Makefile.* NHSUBST +Install.* NHSUBST diff --git a/sys/os2/.gitattributes b/sys/os2/.gitattributes index 8cffb77ae..31e18fe84 100644 --- a/sys/os2/.gitattributes +++ b/sys/os2/.gitattributes @@ -1 +1 @@ -Makefile.* filter=NHtext merge=NHsubst +Makefile.* NHSUBST diff --git a/sys/share/.gitattributes b/sys/share/.gitattributes index 8cffb77ae..31e18fe84 100644 --- a/sys/share/.gitattributes +++ b/sys/share/.gitattributes @@ -1 +1 @@ -Makefile.* filter=NHtext merge=NHsubst +Makefile.* NHSUBST diff --git a/sys/share/NetHack.cnf b/sys/share/NetHack.cnf index 29d8ce910..2b16dfcc7 100644 --- a/sys/share/NetHack.cnf +++ b/sys/share/NetHack.cnf @@ -121,3 +121,14 @@ OPTIONS=time,noshowexp,number_pad:2,lit_corridor # DEC Rainbows will hang if rawio is set, so they should instead use: #OPTIONS=BIOS,DECgraphics +# Colored menus. +#OPTIONS=menucolors +# Syntax is: MENUCOLOR="string_to_match"=color&attribute +# Colors: black, red, green, brown, blue, magenta, cyan, gray, orange, +# lightgreen, yellow, lightblue, lightmagenta, lightcyan, white. +# Attributes: none, bold, dim, underline, blink, inverse. +#MENUCOLOR=" blessed "=green +#MENUCOLOR=" holy "=green +#MENUCOLOR=" cursed "=red +#MENUCOLOR=" unholy "=red +#MENUCOLOR=" cursed .* (being worn)"=orange&underline diff --git a/sys/share/lev_comp.h b/sys/share/lev_comp.h index 8152d608a..bdfa23854 100644 --- a/sys/share/lev_comp.h +++ b/sys/share/lev_comp.h @@ -1,79 +1,453 @@ -#define CHAR 257 -#define INTEGER 258 -#define BOOLEAN 259 -#define PERCENT 260 -#define MESSAGE_ID 261 -#define MAZE_ID 262 -#define LEVEL_ID 263 -#define LEV_INIT_ID 264 -#define GEOMETRY_ID 265 -#define NOMAP_ID 266 -#define OBJECT_ID 267 -#define COBJECT_ID 268 -#define MONSTER_ID 269 -#define TRAP_ID 270 -#define DOOR_ID 271 -#define DRAWBRIDGE_ID 272 -#define MAZEWALK_ID 273 -#define WALLIFY_ID 274 -#define REGION_ID 275 -#define FILLING 276 -#define RANDOM_OBJECTS_ID 277 -#define RANDOM_MONSTERS_ID 278 -#define RANDOM_PLACES_ID 279 -#define ALTAR_ID 280 -#define LADDER_ID 281 -#define STAIR_ID 282 -#define NON_DIGGABLE_ID 283 -#define NON_PASSWALL_ID 284 -#define ROOM_ID 285 -#define PORTAL_ID 286 -#define TELEPRT_ID 287 -#define BRANCH_ID 288 -#define LEV 289 -#define CHANCE_ID 290 -#define CORRIDOR_ID 291 -#define GOLD_ID 292 -#define ENGRAVING_ID 293 -#define FOUNTAIN_ID 294 -#define POOL_ID 295 -#define SINK_ID 296 -#define NONE 297 -#define RAND_CORRIDOR_ID 298 -#define DOOR_STATE 299 -#define LIGHT_STATE 300 -#define CURSE_TYPE 301 -#define ENGRAVING_TYPE 302 -#define DIRECTION 303 -#define RANDOM_TYPE 304 -#define O_REGISTER 305 -#define M_REGISTER 306 -#define P_REGISTER 307 -#define A_REGISTER 308 -#define ALIGNMENT 309 -#define LEFT_OR_RIGHT 310 -#define CENTER 311 -#define TOP_OR_BOT 312 -#define ALTAR_TYPE 313 -#define UP_OR_DOWN 314 -#define SUBROOM_ID 315 -#define NAME_ID 316 -#define FLAGS_ID 317 -#define FLAG_TYPE 318 -#define MON_ATTITUDE 319 -#define MON_ALERTNESS 320 -#define MON_APPEARANCE 321 -#define CONTAINED 322 -#define STRING 323 -#define MAP_ID 324 -typedef union +/* A Bison parser, made by GNU Bison 3.0.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef YY_YY_Y_TAB_H_INCLUDED +# define YY_YY_Y_TAB_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + CHAR = 258, + INTEGER = 259, + BOOLEAN = 260, + PERCENT = 261, + SPERCENT = 262, + MINUS_INTEGER = 263, + PLUS_INTEGER = 264, + MAZE_GRID_ID = 265, + SOLID_FILL_ID = 266, + MINES_ID = 267, + ROGUELEV_ID = 268, + MESSAGE_ID = 269, + MAZE_ID = 270, + LEVEL_ID = 271, + LEV_INIT_ID = 272, + GEOMETRY_ID = 273, + NOMAP_ID = 274, + OBJECT_ID = 275, + COBJECT_ID = 276, + MONSTER_ID = 277, + TRAP_ID = 278, + DOOR_ID = 279, + DRAWBRIDGE_ID = 280, + object_ID = 281, + monster_ID = 282, + terrain_ID = 283, + MAZEWALK_ID = 284, + WALLIFY_ID = 285, + REGION_ID = 286, + FILLING = 287, + IRREGULAR = 288, + JOINED = 289, + ALTAR_ID = 290, + LADDER_ID = 291, + STAIR_ID = 292, + NON_DIGGABLE_ID = 293, + NON_PASSWALL_ID = 294, + ROOM_ID = 295, + PORTAL_ID = 296, + TELEPRT_ID = 297, + BRANCH_ID = 298, + LEV = 299, + MINERALIZE_ID = 300, + CORRIDOR_ID = 301, + GOLD_ID = 302, + ENGRAVING_ID = 303, + FOUNTAIN_ID = 304, + POOL_ID = 305, + SINK_ID = 306, + NONE = 307, + RAND_CORRIDOR_ID = 308, + DOOR_STATE = 309, + LIGHT_STATE = 310, + CURSE_TYPE = 311, + ENGRAVING_TYPE = 312, + DIRECTION = 313, + RANDOM_TYPE = 314, + RANDOM_TYPE_BRACKET = 315, + A_REGISTER = 316, + ALIGNMENT = 317, + LEFT_OR_RIGHT = 318, + CENTER = 319, + TOP_OR_BOT = 320, + ALTAR_TYPE = 321, + UP_OR_DOWN = 322, + SUBROOM_ID = 323, + NAME_ID = 324, + FLAGS_ID = 325, + FLAG_TYPE = 326, + MON_ATTITUDE = 327, + MON_ALERTNESS = 328, + MON_APPEARANCE = 329, + ROOMDOOR_ID = 330, + IF_ID = 331, + ELSE_ID = 332, + TERRAIN_ID = 333, + HORIZ_OR_VERT = 334, + REPLACE_TERRAIN_ID = 335, + EXIT_ID = 336, + SHUFFLE_ID = 337, + QUANTITY_ID = 338, + BURIED_ID = 339, + LOOP_ID = 340, + FOR_ID = 341, + TO_ID = 342, + SWITCH_ID = 343, + CASE_ID = 344, + BREAK_ID = 345, + DEFAULT_ID = 346, + ERODED_ID = 347, + TRAPPED_ID = 348, + RECHARGED_ID = 349, + INVIS_ID = 350, + GREASED_ID = 351, + FEMALE_ID = 352, + CANCELLED_ID = 353, + REVIVED_ID = 354, + AVENGE_ID = 355, + FLEEING_ID = 356, + BLINDED_ID = 357, + PARALYZED_ID = 358, + STUNNED_ID = 359, + CONFUSED_ID = 360, + SEENTRAPS_ID = 361, + ALL_ID = 362, + MONTYPE_ID = 363, + GRAVE_ID = 364, + ERODEPROOF_ID = 365, + FUNCTION_ID = 366, + MSG_OUTPUT_TYPE = 367, + COMPARE_TYPE = 368, + UNKNOWN_TYPE = 369, + rect_ID = 370, + fillrect_ID = 371, + line_ID = 372, + randline_ID = 373, + grow_ID = 374, + selection_ID = 375, + flood_ID = 376, + rndcoord_ID = 377, + circle_ID = 378, + ellipse_ID = 379, + filter_ID = 380, + complement_ID = 381, + gradient_ID = 382, + GRADIENT_TYPE = 383, + LIMITED = 384, + HUMIDITY_TYPE = 385, + STRING = 386, + MAP_ID = 387, + NQSTRING = 388, + VARSTRING = 389, + CFUNC = 390, + CFUNC_INT = 391, + CFUNC_STR = 392, + CFUNC_COORD = 393, + CFUNC_REGION = 394, + VARSTRING_INT = 395, + VARSTRING_INT_ARRAY = 396, + VARSTRING_STRING = 397, + VARSTRING_STRING_ARRAY = 398, + VARSTRING_VAR = 399, + VARSTRING_VAR_ARRAY = 400, + VARSTRING_COORD = 401, + VARSTRING_COORD_ARRAY = 402, + VARSTRING_REGION = 403, + VARSTRING_REGION_ARRAY = 404, + VARSTRING_MAPCHAR = 405, + VARSTRING_MAPCHAR_ARRAY = 406, + VARSTRING_MONST = 407, + VARSTRING_MONST_ARRAY = 408, + VARSTRING_OBJ = 409, + VARSTRING_OBJ_ARRAY = 410, + VARSTRING_SEL = 411, + VARSTRING_SEL_ARRAY = 412, + METHOD_INT = 413, + METHOD_INT_ARRAY = 414, + METHOD_STRING = 415, + METHOD_STRING_ARRAY = 416, + METHOD_VAR = 417, + METHOD_VAR_ARRAY = 418, + METHOD_COORD = 419, + METHOD_COORD_ARRAY = 420, + METHOD_REGION = 421, + METHOD_REGION_ARRAY = 422, + METHOD_MAPCHAR = 423, + METHOD_MAPCHAR_ARRAY = 424, + METHOD_MONST = 425, + METHOD_MONST_ARRAY = 426, + METHOD_OBJ = 427, + METHOD_OBJ_ARRAY = 428, + METHOD_SEL = 429, + METHOD_SEL_ARRAY = 430, + DICE = 431 + }; +#endif +/* Tokens. */ +#define CHAR 258 +#define INTEGER 259 +#define BOOLEAN 260 +#define PERCENT 261 +#define SPERCENT 262 +#define MINUS_INTEGER 263 +#define PLUS_INTEGER 264 +#define MAZE_GRID_ID 265 +#define SOLID_FILL_ID 266 +#define MINES_ID 267 +#define ROGUELEV_ID 268 +#define MESSAGE_ID 269 +#define MAZE_ID 270 +#define LEVEL_ID 271 +#define LEV_INIT_ID 272 +#define GEOMETRY_ID 273 +#define NOMAP_ID 274 +#define OBJECT_ID 275 +#define COBJECT_ID 276 +#define MONSTER_ID 277 +#define TRAP_ID 278 +#define DOOR_ID 279 +#define DRAWBRIDGE_ID 280 +#define object_ID 281 +#define monster_ID 282 +#define terrain_ID 283 +#define MAZEWALK_ID 284 +#define WALLIFY_ID 285 +#define REGION_ID 286 +#define FILLING 287 +#define IRREGULAR 288 +#define JOINED 289 +#define ALTAR_ID 290 +#define LADDER_ID 291 +#define STAIR_ID 292 +#define NON_DIGGABLE_ID 293 +#define NON_PASSWALL_ID 294 +#define ROOM_ID 295 +#define PORTAL_ID 296 +#define TELEPRT_ID 297 +#define BRANCH_ID 298 +#define LEV 299 +#define MINERALIZE_ID 300 +#define CORRIDOR_ID 301 +#define GOLD_ID 302 +#define ENGRAVING_ID 303 +#define FOUNTAIN_ID 304 +#define POOL_ID 305 +#define SINK_ID 306 +#define NONE 307 +#define RAND_CORRIDOR_ID 308 +#define DOOR_STATE 309 +#define LIGHT_STATE 310 +#define CURSE_TYPE 311 +#define ENGRAVING_TYPE 312 +#define DIRECTION 313 +#define RANDOM_TYPE 314 +#define RANDOM_TYPE_BRACKET 315 +#define A_REGISTER 316 +#define ALIGNMENT 317 +#define LEFT_OR_RIGHT 318 +#define CENTER 319 +#define TOP_OR_BOT 320 +#define ALTAR_TYPE 321 +#define UP_OR_DOWN 322 +#define SUBROOM_ID 323 +#define NAME_ID 324 +#define FLAGS_ID 325 +#define FLAG_TYPE 326 +#define MON_ATTITUDE 327 +#define MON_ALERTNESS 328 +#define MON_APPEARANCE 329 +#define ROOMDOOR_ID 330 +#define IF_ID 331 +#define ELSE_ID 332 +#define TERRAIN_ID 333 +#define HORIZ_OR_VERT 334 +#define REPLACE_TERRAIN_ID 335 +#define EXIT_ID 336 +#define SHUFFLE_ID 337 +#define QUANTITY_ID 338 +#define BURIED_ID 339 +#define LOOP_ID 340 +#define FOR_ID 341 +#define TO_ID 342 +#define SWITCH_ID 343 +#define CASE_ID 344 +#define BREAK_ID 345 +#define DEFAULT_ID 346 +#define ERODED_ID 347 +#define TRAPPED_ID 348 +#define RECHARGED_ID 349 +#define INVIS_ID 350 +#define GREASED_ID 351 +#define FEMALE_ID 352 +#define CANCELLED_ID 353 +#define REVIVED_ID 354 +#define AVENGE_ID 355 +#define FLEEING_ID 356 +#define BLINDED_ID 357 +#define PARALYZED_ID 358 +#define STUNNED_ID 359 +#define CONFUSED_ID 360 +#define SEENTRAPS_ID 361 +#define ALL_ID 362 +#define MONTYPE_ID 363 +#define GRAVE_ID 364 +#define ERODEPROOF_ID 365 +#define FUNCTION_ID 366 +#define MSG_OUTPUT_TYPE 367 +#define COMPARE_TYPE 368 +#define UNKNOWN_TYPE 369 +#define rect_ID 370 +#define fillrect_ID 371 +#define line_ID 372 +#define randline_ID 373 +#define grow_ID 374 +#define selection_ID 375 +#define flood_ID 376 +#define rndcoord_ID 377 +#define circle_ID 378 +#define ellipse_ID 379 +#define filter_ID 380 +#define complement_ID 381 +#define gradient_ID 382 +#define GRADIENT_TYPE 383 +#define LIMITED 384 +#define HUMIDITY_TYPE 385 +#define STRING 386 +#define MAP_ID 387 +#define NQSTRING 388 +#define VARSTRING 389 +#define CFUNC 390 +#define CFUNC_INT 391 +#define CFUNC_STR 392 +#define CFUNC_COORD 393 +#define CFUNC_REGION 394 +#define VARSTRING_INT 395 +#define VARSTRING_INT_ARRAY 396 +#define VARSTRING_STRING 397 +#define VARSTRING_STRING_ARRAY 398 +#define VARSTRING_VAR 399 +#define VARSTRING_VAR_ARRAY 400 +#define VARSTRING_COORD 401 +#define VARSTRING_COORD_ARRAY 402 +#define VARSTRING_REGION 403 +#define VARSTRING_REGION_ARRAY 404 +#define VARSTRING_MAPCHAR 405 +#define VARSTRING_MAPCHAR_ARRAY 406 +#define VARSTRING_MONST 407 +#define VARSTRING_MONST_ARRAY 408 +#define VARSTRING_OBJ 409 +#define VARSTRING_OBJ_ARRAY 410 +#define VARSTRING_SEL 411 +#define VARSTRING_SEL_ARRAY 412 +#define METHOD_INT 413 +#define METHOD_INT_ARRAY 414 +#define METHOD_STRING 415 +#define METHOD_STRING_ARRAY 416 +#define METHOD_VAR 417 +#define METHOD_VAR_ARRAY 418 +#define METHOD_COORD 419 +#define METHOD_COORD_ARRAY 420 +#define METHOD_REGION 421 +#define METHOD_REGION_ARRAY 422 +#define METHOD_MAPCHAR 423 +#define METHOD_MAPCHAR_ARRAY 424 +#define METHOD_MONST 425 +#define METHOD_MONST_ARRAY 426 +#define METHOD_OBJ 427 +#define METHOD_OBJ_ARRAY 428 +#define METHOD_SEL 429 +#define METHOD_SEL_ARRAY 430 +#define DICE 431 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE YYSTYPE; +union YYSTYPE { - int i; +#line 148 "lev_comp.y" /* yacc.c:1909 */ + + long i; char* map; struct { - xchar room; - xchar wall; - xchar door; + long room; + long wall; + long door; } corpos; -} YYSTYPE; + struct { + long area; + long x1; + long y1; + long x2; + long y2; + } lregn; + struct { + long x; + long y; + } crd; + struct { + long ter; + long lit; + } terr; + struct { + long height; + long width; + } sze; + struct { + long die; + long num; + } dice; + struct { + long cfunc; + char *varstr; + } meth; + +#line 443 "y.tab.h" /* yacc.c:1909 */ +}; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + extern YYSTYPE yylval; + +int yyparse (void); + +#endif /* !YY_YY_Y_TAB_H_INCLUDED */ diff --git a/sys/share/lev_lex.c b/sys/share/lev_lex.c index 929d3b3b7..91f13e8f8 100644 --- a/sys/share/lev_lex.c +++ b/sys/share/lev_lex.c @@ -1,14 +1,112 @@ -/* A lexical scanner for NetHack generated by flex */ -/* Scanner skeleton version: - * flexhack.skl 3.3.0 (from .../flex/RCS/flex.skl,v 2.85 95/04/24 10:48:47) - */ -#define FLEXHACK_SCANNER +#line 3 "lex.yy.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 39 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif -#include "config.h" -#define yyconst const /* some code inserted by flex will refer to yyconst */ +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif /* Returned upon end-of-file. */ #define YY_NULL 0 @@ -24,55 +122,79 @@ * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ -#define BEGIN yy_start = 1 + 2 * +#define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ -#define YY_START ((yy_start - 1) / 2) +#define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) +#define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else #define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t yyleng; -extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 -/* Return all but the first 'n' matched characters back to the input stream. */ + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - +#define unput(c) yyunput( c, (yytext_ptr) ) +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; @@ -88,7 +210,7 @@ struct yy_buffer_state /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - int yy_n_chars; + yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -109,12 +231,16 @@ struct yy_buffer_state */ int yy_at_bol; + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; + #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process @@ -128,26 +254,38 @@ struct yy_buffer_state * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 - }; -static YY_BUFFER_STATE yy_current_buffer = 0; + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". + * + * Returns the top of the stack, or NULL. */ -#define YY_CURRENT_BUFFER yy_current_buffer +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - -int yyleng; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ +static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches @@ -155,152 +293,226 @@ static int yy_start = 0; /* start state number */ */ static int yy_did_buffer_switch_on_eof; -void FDECL(yyrestart, (FILE *)); +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); -void FDECL(yy_switch_to_buffer, (YY_BUFFER_STATE)); -void NDECL(yy_load_buffer_state); -YY_BUFFER_STATE FDECL(yy_create_buffer, (FILE *,int)); -void FDECL(yy_delete_buffer, (YY_BUFFER_STATE)); -void FDECL(yy_init_buffer, (YY_BUFFER_STATE,FILE *)); -void FDECL(yy_flush_buffer, (YY_BUFFER_STATE)); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); -static genericptr_t FDECL(yy_flex_alloc, (yy_size_t)); -static genericptr_t FDECL(yy_flex_realloc2, (genericptr_t,yy_size_t,int)); -static void FDECL(yy_flex_free, (genericptr_t)); +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ typedef unsigned char YY_CHAR; + FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + extern char *yytext; #define yytext_ptr yytext -static yy_state_type NDECL(yy_get_previous_state); -static yy_state_type FDECL(yy_try_NUL_trans, (yy_state_type)); -static int NDECL(yy_get_next_buffer); -static void FDECL(yy_fatal_error, (const char *)); +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; + (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 113 -#define YY_END_OF_BUFFER 114 -static yyconst short int yy_accept[643] = +#define YY_NUM_RULES 197 +#define YY_END_OF_BUFFER 198 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[1049] = { 0, - 0, 0, 0, 0, 114, 112, 109, 108, 112, 112, - 112, 112, 106, 4, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 2, 112, 109, 112, 112, 106, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 109, - 108, 0, 107, 0, 0, 106, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 196, 192, 191, 196, 196, + 196, 196, 196, 196, 195, 181, 189, 196, 190, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 196, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 192, 196, 195, 2, 196, 192, 196, 196, 195, 181, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 192, 196, 195, 192, 191, 185, + 0, 182, 183, 0, 0, 179, 195, 178, 180, 181, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 87, 0, 0, 3, 0, 2, 2, 0, 109, 0, - 106, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 111, 0, 111, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 195, 187, 186, 184, 188, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 39, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 55, 195, 195, 0, 0, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 72, 0, 0, 67, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 110, 0, 0, 0, 0, 0, - 17, 0, 0, 0, 0, 0, 40, 0, 0, 0, - 6, 0, 0, 42, 0, 0, 0, 33, 0, 0, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 153, 195, 195, 192, 0, + 0, 3, 195, 2, 2, 0, 192, 0, 179, 195, + 178, 181, 195, 195, 195, 195, 195, 39, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 192, 0, 2, + 0, 0, 195, 194, 0, 194, 176, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 54, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 0, 36, 32, 0, 0, 0, 16, 0, 0, 105, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, - 0, 0, 0, 0, 0, 0, 88, 91, 51, 0, - 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, - 0, 94, 0, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 90, 0, 0, 0, 53, 12, 0, 0, 0, - 0, 0, 25, 0, 0, 0, 0, 0, 0, 10, - 0, 0, 0, 0, 8, 0, 0, 0, 7, 0, - 0, 0, 0, 0, 0, 27, 0, 0, 0, 59, + 195, 195, 195, 0, 195, 103, 195, 83, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 79, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 81, 195, 195, 195, + 195, 138, 195, 195, 195, 195, 127, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 16, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 125, 195, - 86, 0, 0, 80, 0, 95, 0, 0, 0, 74, - 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 0, 0, 0, 58, 0, 64, 0, 0, - 0, 52, 0, 0, 68, 0, 0, 30, 43, 0, - 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, - 0, 0, 13, 28, 0, 21, 0, 0, 0, 0, - 79, 0, 66, 49, 62, 46, 0, 0, 98, 0, - 69, 0, 0, 0, 0, 0, 47, 0, 0, 0, - 0, 0, 0, 48, 102, 0, 0, 56, 0, 54, + 195, 195, 195, 195, 195, 195, 195, 80, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 193, + 195, 195, 195, 58, 195, 195, 195, 22, 195, 40, + 195, 41, 195, 195, 195, 195, 49, 195, 195, 195, + 195, 56, 6, 195, 195, 195, 53, 195, 195, 195, + 36, 195, 195, 195, 195, 42, 195, 35, 195, 195, + 195, 195, 195, 21, 195, 0, 177, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 159, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 154, + 157, 113, 195, 195, 195, 195, 195, 195, 195, 195, - 0, 0, 85, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 15, 0, 0, 0, - 37, 0, 20, 0, 96, 0, 0, 92, 0, 0, - 0, 78, 0, 0, 0, 0, 57, 73, 71, 0, - 0, 0, 84, 0, 0, 0, 0, 39, 0, 0, - 31, 11, 9, 19, 0, 0, 0, 0, 0, 0, - 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, - 83, 0, 0, 77, 0, 97, 70, 14, 0, 41, - 0, 0, 0, 0, 0, 0, 0, 75, 99, 61, - 0, 101, 44, 81, 82, 0, 0, 0, 18, 0, + 195, 195, 195, 195, 69, 195, 195, 195, 195, 195, + 195, 195, 195, 120, 195, 195, 67, 195, 195, 195, + 195, 160, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 118, 195, 195, 195, 106, 195, 195, 195, 195, + 195, 195, 195, 65, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 156, 195, 195, 195, 195, 195, 115, 15, + 0, 195, 195, 195, 195, 195, 195, 2, 0, 28, + 195, 59, 195, 195, 195, 195, 195, 13, 195, 195, + 195, 50, 195, 195, 7, 195, 195, 195, 195, 5, - 0, 0, 0, 0, 0, 0, 63, 0, 100, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, - 35, 0, 0, 0, 0, 0, 76, 104, 0, 0, - 0, 24, 0, 0, 0, 22, 0, 0, 23, 29, - 38, 0 + 195, 195, 195, 195, 195, 195, 195, 195, 195, 30, + 195, 195, 195, 195, 195, 119, 152, 195, 195, 195, + 146, 195, 195, 161, 195, 195, 195, 195, 195, 140, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 155, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 11, 195, 195, 195, 195, + 195, 195, 195, 112, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 124, 195, 12, 195, + 195, 195, 195, 195, 195, 195, 82, 114, 195, 195, + + 195, 195, 195, 195, 195, 195, 128, 195, 195, 195, + 195, 195, 33, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 29, 195, 195, 195, 195, 195, 195, 17, + 31, 195, 27, 195, 195, 195, 195, 57, 195, 195, + 195, 195, 145, 96, 195, 195, 126, 110, 86, 195, + 122, 72, 107, 195, 195, 195, 164, 195, 195, 87, + 195, 93, 129, 195, 74, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 134, 195, + 195, 108, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 109, 167, 195, 195, 16, 195, 195, 195, 195, + + 77, 195, 116, 195, 195, 195, 195, 195, 111, 195, + 195, 195, 151, 172, 195, 195, 78, 195, 195, 195, + 195, 195, 195, 195, 195, 1, 195, 57, 195, 195, + 195, 60, 195, 195, 195, 195, 195, 195, 195, 4, + 195, 19, 195, 195, 195, 195, 195, 62, 43, 195, + 46, 26, 195, 162, 98, 195, 195, 195, 195, 73, + 158, 195, 195, 97, 195, 195, 195, 92, 195, 195, + 195, 195, 144, 195, 195, 195, 195, 135, 195, 195, + 195, 195, 195, 20, 63, 139, 137, 195, 195, 195, + 195, 195, 195, 195, 117, 195, 131, 95, 195, 150, + + 195, 195, 195, 195, 195, 100, 47, 89, 195, 195, + 195, 195, 195, 26, 195, 45, 195, 195, 34, 61, + 14, 8, 25, 195, 195, 195, 195, 195, 23, 195, + 168, 195, 195, 195, 101, 195, 66, 195, 75, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 149, 9, 195, 195, 195, 195, 143, 195, 85, 68, + 195, 71, 195, 195, 195, 195, 175, 163, 130, 133, + 195, 105, 18, 195, 51, 195, 195, 195, 195, 195, + 195, 94, 141, 195, 195, 70, 173, 121, 195, 166, + 195, 174, 91, 132, 84, 147, 148, 170, 195, 195, + + 99, 171, 90, 195, 64, 195, 10, 136, 24, 52, + 195, 195, 195, 195, 195, 76, 88, 123, 104, 195, + 165, 102, 195, 195, 195, 195, 195, 195, 195, 195, + 37, 38, 195, 195, 195, 142, 169, 195, 195, 195, + 195, 195, 195, 195, 48, 32, 44, 0 } ; -static yyconst int yy_ec[256] = +static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 5, 1, 6, 7, 1, 8, 1, 9, 1, - 1, 1, 10, 1, 11, 12, 1, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 14, 1, 1, - 1, 1, 1, 1, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 1, 31, 32, 33, 34, 35, 36, 1, 37, 38, - 39, 40, 41, 1, 42, 1, 43, 44, 45, 46, + 1, 5, 6, 7, 8, 9, 10, 1, 11, 1, + 1, 1, 12, 1, 13, 14, 1, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 1, 1, 16, + 17, 18, 1, 1, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 1, 48, 1, 49, 50, 51, 52, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 1, 59, 60, 61, 62, 63, 64, 1, - 1, 1, 12, 12, 12, 1, 1, 1, 1, 1, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -317,267 +529,413 @@ static yyconst int yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst int yy_meta[65] = +static yyconst flex_int32_t yy_meta[75] = { 0, - 1, 2, 3, 2, 2, 1, 2, 1, 1, 2, - 2, 2, 2, 1, 2, 2, 2, 1, 1, 2, - 1, 2, 2, 1, 2, 2, 1, 1, 1, 2, - 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1 + 1, 2, 3, 2, 2, 1, 1, 2, 1, 1, + 1, 2, 4, 2, 4, 1, 1, 1, 5, 5, + 5, 6, 6, 5, 6, 5, 5, 6, 5, 5, + 5, 6, 6, 5, 6, 6, 5, 5, 5, 6, + 5, 6, 5, 6, 1, 2, 1, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, + 6, 5, 6, 6 } ; -static yyconst short int yy_base[648] = +static yyconst flex_int16_t yy_base[1056] = { 0, - 0, 58, 83, 62, 799, 800, 65, 800, 795, 791, - 756, 782, 781, 800, 767, 761, 44, 43, 763, 42, - 62, 762, 60, 63, 68, 773, 759, 92, 91, 91, - 772, 71, 72, 76, 87, 55, 84, 77, 61, 96, - 103, 95, 104, 103, 108, 111, 99, 107, 739, 782, - 151, 800, 781, 169, 173, 179, 182, 185, 194, 197, - 755, 180, 185, 193, 181, 194, 202, 214, 241, 75, - 800, 776, 800, 772, 771, 766, 745, 762, 761, 136, - 746, 759, 752, 757, 737, 741, 743, 745, 749, 731, - 727, 732, 735, 735, 151, 737, 162, 732, 738, 729, + 0, 73, 102, 77, 1287, 1288, 75, 1288, 1283, 1268, + 1277, 0, 1237, 1267, 1266, 78, 66, 1263, 1262, 1248, + 1241, 57, 63, 59, 64, 101, 0, 63, 79, 119, + 94, 1256, 1242, 128, 127, 126, 1255, 104, 109, 118, + 133, 94, 139, 151, 1207, 95, 132, 1209, 157, 164, + 154, 100, 166, 1202, 173, 175, 176, 56, 1217, 1216, + 239, 1265, 226, 1288, 1264, 252, 248, 258, 271, 157, + 162, 120, 248, 216, 274, 1251, 201, 249, 296, 140, + 306, 301, 176, 265, 346, 352, 369, 232, 1288, 1288, + 1258, 1288, 0, 1253, 1252, 1247, 0, 1246, 1288, 278, - 729, 741, 739, 728, 738, 726, 225, 224, 143, 707, - 696, 706, 192, 687, 690, 687, 689, 701, 686, 162, - 683, 677, 680, 679, 689, 683, 682, 181, 675, 670, - 199, 672, 687, 221, 672, 674, 667, 229, 676, 680, - 683, 682, 668, 674, 666, 211, 659, 662, 657, 235, - 800, 658, 714, 800, 204, 800, 800, 713, 277, 264, - 274, 269, 279, 274, 282, 287, 285, 295, 293, 800, - 712, 0, 800, 705, 704, 697, 683, 682, 676, 677, - 676, 670, 674, 683, 675, 675, 683, 667, 681, 679, - 678, 664, 663, 675, 678, 650, 672, 664, 656, 670, + 1245, 1288, 1288, 1288, 1288, 1221, 246, 1221, 234, 1233, + 1223, 1236, 1217, 1228, 1225, 1232, 260, 1218, 1216, 1218, + 1228, 0, 1219, 1223, 1204, 1210, 1198, 1204, 1208, 1207, + 1207, 246, 1209, 270, 1204, 301, 1202, 1195, 1201, 1213, + 1211, 1203, 306, 0, 1210, 1198, 347, 208, 301, 1154, + 1176, 1165, 1171, 1174, 317, 1154, 1158, 1154, 1157, 1156, + 1168, 1150, 1152, 338, 1148, 1142, 1139, 1144, 1143, 1149, + 1153, 1144, 1146, 1144, 1144, 300, 348, 280, 337, 1150, + 1132, 1135, 1143, 1128, 217, 345, 1147, 314, 26, 1135, + 1134, 1134, 1125, 360, 1135, 1139, 1125, 1141, 1136, 1139, - 664, 659, 660, 661, 652, 663, 651, 654, 295, 630, - 635, 620, 629, 622, 614, 616, 611, 618, 614, 608, - 611, 607, 612, 604, 604, 607, 601, 600, 601, 599, - 604, 609, 610, 594, 800, 593, 594, 800, 599, 604, - 593, 605, 595, 587, 585, 591, 587, 588, 273, 581, - 594, 593, 583, 593, 592, 590, 585, 589, 574, 581, - 570, 800, 583, 567, 577, 576, 565, 256, 306, 301, - 598, 304, 309, 315, 800, 593, 606, 605, 606, 597, - 800, 603, 603, 585, 583, 596, 800, 572, 594, 586, - 575, 595, 576, 800, 578, 309, 590, 800, 591, 576, + 356, 359, 1132, 1134, 1130, 1122, 372, 259, 325, 1114, + 1113, 1115, 1116, 366, 376, 0, 1113, 349, 435, 1175, + 1174, 1288, 397, 1288, 1288, 1173, 442, 446, 449, 1160, + 0, 423, 404, 424, 316, 439, 440, 1159, 305, 441, + 442, 444, 445, 447, 448, 170, 450, 484, 0, 1288, + 1170, 0, 456, 1288, 1161, 1160, 1155, 1150, 1136, 1148, + 1143, 1127, 1128, 1144, 1126, 1120, 1137, 1123, 1120, 1132, + 0, 1124, 1134, 1123, 1131, 1112, 1113, 1128, 1126, 1114, + 1124, 1109, 1122, 1107, 1120, 1123, 1093, 1117, 1109, 1100, + 1115, 1109, 1105, 1103, 1109, 1103, 1104, 1094, 1091, 1105, - 575, 800, 800, 572, 573, 571, 800, 577, 307, 800, - 543, 539, 538, 549, 548, 534, 547, 535, 544, 800, - 543, 529, 541, 536, 543, 538, 800, 800, 800, 541, - 536, 535, 570, 532, 528, 800, 531, 530, 533, 519, - 522, 800, 512, 513, 520, 513, 526, 511, 800, 517, - 512, 520, 800, 517, 516, 505, 500, 499, 498, 502, - 507, 800, 497, 501, 493, 800, 800, 550, 318, 537, - 321, 331, 800, 529, 531, 526, 530, 516, 511, 800, - 530, 511, 516, 511, 800, 526, 519, 520, 800, 515, - 522, 503, 509, 507, 505, 800, 503, 502, 510, 800, + 1091, 1092, 1095, 462, 1069, 0, 1074, 0, 1059, 1068, + 1058, 1060, 1051, 1055, 1053, 1047, 1055, 416, 1062, 1044, + 1048, 1059, 1042, 1048, 1043, 1052, 1038, 1042, 0, 1035, + 1034, 1044, 1034, 1047, 1031, 1048, 416, 1043, 1032, 427, + 1045, 1022, 1038, 1039, 1033, 1021, 0, 1036, 1030, 1033, + 1023, 0, 1016, 1017, 1025, 1028, 0, 1021, 1026, 1015, + 1027, 1017, 1022, 1021, 402, 1020, 1004, 1011, 1007, 1008, + 440, 1000, 1014, 1013, 1003, 1015, 1012, 1001, 999, 1003, + 1007, 426, 989, 1000, 1000, 1004, 985, 1002, 986, 989, + 997, 983, 438, 991, 979, 997, 983, 978, 0, 979, - 800, 482, 470, 800, 480, 800, 471, 469, 465, 800, - 477, 473, 470, 474, 456, 800, 472, 196, 463, 462, - 466, 468, 452, 452, 464, 463, 466, 459, 448, 448, - 462, 800, 457, 442, 454, 800, 446, 800, 438, 439, - 451, 800, 437, 442, 800, 465, 335, 800, 800, 466, - 464, 469, 468, 467, 458, 473, 800, 461, 467, 454, - 463, 451, 800, 800, 440, 800, 454, 449, 442, 435, - 800, 431, 800, 800, 800, 800, 420, 419, 800, 427, - 800, 426, 421, 414, 423, 418, 800, 406, 406, 421, - 406, 410, 407, 800, 800, 408, 403, 800, 398, 800, + 989, 972, 983, 976, 981, 969, 968, 0, 495, 487, + 481, 1004, 488, 490, 492, 493, 495, 496, 512, 1288, + 998, 1012, 1003, 0, 1012, 1003, 990, 0, 1008, 0, + 1008, 0, 989, 987, 986, 1000, 0, 999, 973, 997, + 989, 0, 977, 998, 980, 977, 0, 980, 490, 992, + 0, 993, 978, 977, 990, 986, 983, 0, 970, 972, + 983, 969, 983, 0, 974, 476, 1288, 938, 933, 932, + 944, 941, 942, 927, 941, 940, 928, 937, 936, 0, + 935, 934, 919, 925, 931, 926, 922, 912, 927, 0, + 0, 0, 915, 929, 924, 923, 915, 464, 921, 916, - 404, 407, 800, 410, 409, 800, 329, 436, 423, 435, - 424, 423, 413, 419, 423, 800, 800, 426, 414, 342, - 800, 412, 800, 390, 800, 396, 395, 800, 393, 391, - 382, 800, 381, 378, 389, 374, 800, 800, 800, 383, - 376, 378, 800, 382, 384, 383, 397, 800, 406, 405, - 800, 800, 800, 800, 410, 388, 394, 393, 405, 394, - 377, 800, 372, 371, 355, 365, 355, 357, 365, 352, - 800, 361, 350, 800, 358, 800, 800, 800, 388, 800, - 390, 390, 373, 375, 378, 386, 369, 800, 800, 800, - 338, 800, 800, 800, 800, 342, 336, 335, 800, 369, + 920, 914, 917, 902, 0, 955, 913, 892, 908, 900, + 896, 907, 908, 0, 907, 891, 0, 905, 908, 894, + 897, 0, 465, 887, 885, 879, 885, 893, 886, 899, + 884, 0, 890, 885, 893, 0, 883, 889, 892, 872, + 890, 458, 889, 0, 877, 866, 867, 871, 880, 864, + 878, 882, 878, 860, 865, 857, 873, 868, 857, 860, + 872, 856, 0, 853, 858, 860, 467, 859, 0, 1288, + 912, 507, 895, 516, 517, 521, 519, 1288, 910, 0, + 886, 0, 884, 888, 879, 872, 867, 0, 887, 878, + 866, 0, 872, 866, 0, 882, 875, 880, 875, 0, - 368, 362, 360, 372, 373, 370, 800, 341, 800, 340, - 367, 359, 347, 335, 350, 346, 342, 316, 315, 800, - 800, 338, 327, 312, 310, 311, 800, 800, 236, 210, - 188, 800, 161, 138, 123, 800, 101, 69, 800, 800, - 800, 800, 372, 375, 377, 379, 382 + 870, 877, 857, 864, 862, 860, 870, 857, 859, 0, + 855, 861, 853, 858, 860, 0, 0, 830, 818, 828, + 0, 827, 826, 0, 817, 815, 824, 815, 808, 0, + 820, 820, 816, 817, 802, 816, 800, 796, 485, 0, + 812, 812, 810, 796, 799, 806, 806, 785, 804, 478, + 796, 792, 794, 790, 795, 782, 798, 794, 795, 795, + 778, 778, 791, 777, 789, 0, 788, 776, 790, 783, + 771, 772, 786, 0, 781, 765, 759, 777, 766, 772, + 768, 770, 765, 759, 775, 770, 0, 759, 0, 752, + 752, 751, 750, 750, 763, 763, 491, 0, 761, 760, + + 755, 758, 743, 749, 746, 750, 0, 755, 771, 524, + 526, 532, 0, 772, 770, 764, 774, 773, 772, 765, + 761, 777, 0, 765, 771, 763, 756, 766, 750, 0, + 0, 720, 0, 88, 261, 336, 519, 0, 515, 523, + 514, 509, 0, 0, 507, 508, 0, 0, 0, 501, + 0, 0, 0, 500, 502, 511, 0, 512, 513, 0, + 501, 0, 0, 517, 0, 514, 513, 509, 523, 521, + 521, 518, 513, 515, 525, 516, 530, 521, 0, 525, + 531, 0, 515, 517, 535, 530, 518, 523, 537, 531, + 530, 0, 0, 533, 530, 0, 521, 527, 533, 530, + + 0, 537, 555, 546, 536, 551, 538, 544, 0, 540, + 550, 551, 0, 0, 552, 556, 0, 559, 550, 561, + 561, 562, 563, 549, 569, 0, 604, 605, 606, 599, + 587, 0, 602, 593, 594, 596, 586, 596, 602, 0, + 605, 0, 608, 597, 614, 588, 601, 0, 0, 600, + 0, 0, 579, 0, 0, 587, 588, 589, 591, 0, + 0, 581, 577, 0, 586, 579, 582, 0, 596, 596, + 589, 585, 0, 594, 595, 607, 594, 0, 592, 606, + 592, 609, 609, 0, 0, 0, 0, 606, 601, 612, + 606, 614, 595, 616, 1288, 617, 0, 0, 619, 0, + + 623, 610, 619, 615, 603, 0, 0, 0, 625, 626, + 627, 627, 621, 667, 647, 0, 659, 660, 0, 0, + 0, 0, 0, 642, 668, 647, 656, 652, 0, 643, + 0, 640, 641, 632, 0, 632, 0, 636, 0, 645, + 630, 643, 634, 652, 635, 650, 638, 643, 653, 641, + 0, 0, 648, 654, 644, 659, 0, 660, 0, 0, + 661, 0, 650, 653, 660, 657, 0, 0, 0, 0, + 666, 0, 0, 696, 0, 697, 701, 703, 687, 701, + 689, 0, 0, 658, 673, 0, 0, 0, 660, 0, + 669, 0, 0, 0, 0, 0, 0, 0, 668, 663, + + 0, 0, 0, 665, 0, 665, 0, 0, 0, 0, + 704, 705, 700, 701, 715, 0, 0, 0, 0, 686, + 0, 0, 687, 718, 712, 716, 708, 720, 694, 695, + 0, 0, 726, 730, 723, 0, 0, 718, 725, 720, + 718, 723, 724, 720, 0, 0, 0, 1288, 757, 759, + 765, 768, 774, 779, 784 } ; -static yyconst short int yy_def[648] = +static yyconst flex_int16_t yy_def[1056] = { 0, - 642, 1, 1, 3, 642, 642, 642, 642, 642, 643, - 644, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 645, - 642, 642, 642, 646, 646, 646, 646, 646, 646, 646, - 642, 60, 60, 60, 60, 60, 60, 60, 645, 642, - 642, 643, 642, 642, 647, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, + 1048, 1, 1, 3, 1048, 1048, 1048, 1048, 1048, 1048, + 1049, 1050, 1051, 1048, 1052, 1052, 1048, 1048, 1048, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1048, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1048, 1053, 1052, 1048, 1048, 1054, 1054, 1054, 1052, 69, + 69, 69, 69, 1052, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 1054, 1053, 69, 1048, 1048, 1048, + 1049, 1048, 1050, 1048, 1055, 1048, 1052, 1052, 1048, 1052, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 645, 642, 642, 642, 642, 642, 60, 60, - 60, 60, 60, 642, 60, 60, 60, 60, 60, 642, - 645, 69, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, + 1052, 1048, 1048, 1048, 1048, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1048, 1048, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 60, 60, - 642, 60, 60, 60, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1048, 1053, + 1053, 1048, 1052, 1048, 1048, 1048, 1054, 1054, 1054, 69, + 69, 69, 69, 69, 1052, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 1054, 86, 1048, + 1053, 86, 69, 1048, 1048, 1048, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 60, 642, - 60, 60, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, + 1052, 1052, 1052, 1048, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 60, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 69, + 69, 1052, 69, 69, 69, 69, 69, 69, 69, 1048, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1048, 1048, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, - 642, 642, 642, 642, 642, 642, 60, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1048, + 1048, 69, 1052, 69, 69, 69, 69, 1048, 1048, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 0, 642, 642, 642, 642, 642 + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 69, + 69, 69, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 69, 69, 69, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1048, 1052, 1052, 1052, 1052, 1052, + + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 69, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1052, + 1052, 1052, 1052, 1052, 1052, 1052, 1052, 0, 1048, 1048, + 1048, 1048, 1048, 1048, 1048 } ; -static yyconst short int yy_nxt[865] = +static yyconst flex_int16_t yy_nxt[1363] = { 0, - 6, 7, 8, 9, 7, 10, 6, 6, 11, 12, - 12, 6, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 6, 22, 6, 6, 23, 24, 25, 26, 27, - 28, 29, 30, 6, 6, 31, 6, 6, 32, 6, - 6, 6, 33, 34, 35, 36, 37, 38, 6, 39, - 6, 6, 6, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 6, 49, 50, 79, 70, 84, 69, 70, - 85, 81, 80, 82, 89, 107, 70, 91, 90, 70, - 86, 92, 94, 108, 51, 52, 53, 54, 51, 55, - 87, 93, 56, 56, 55, 57, 95, 58, 59, 60, + 6, 7, 8, 9, 7, 10, 11, 6, 12, 6, + 13, 14, 15, 6, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 27, 27, 29, + 30, 31, 32, 33, 27, 34, 35, 36, 27, 27, + 37, 27, 27, 27, 38, 6, 6, 27, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 27, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 27, 27, 27, 61, 108, 88, 61, 61, 88, + 62, 85, 102, 103, 86, 110, 122, 99, 113, 109, + 114, 362, 100, 116, 123, 111, 117, 124, 112, 363, - 641, 61, 62, 128, 55, 63, 98, 55, 64, 104, - 99, 122, 65, 101, 66, 67, 123, 129, 68, 126, - 100, 105, 55, 102, 103, 109, 124, 127, 640, 113, - 110, 111, 114, 117, 115, 112, 118, 116, 130, 125, - 119, 137, 131, 120, 134, 135, 132, 139, 121, 141, - 143, 138, 133, 145, 639, 148, 142, 149, 144, 136, - 146, 140, 150, 179, 151, 155, 180, 147, 638, 92, - 70, 157, 158, 159, 642, 157, 158, 195, 196, 93, - 642, 157, 158, 642, 157, 158, 642, 157, 158, 637, - 198, 161, 199, 210, 161, 642, 157, 158, 642, 157, + 115, 125, 118, 63, 64, 65, 66, 87, 147, 67, + 846, 126, 131, 68, 69, 67, 70, 215, 148, 216, + 71, 72, 73, 119, 74, 75, 132, 76, 77, 101, + 76, 78, 79, 120, 230, 80, 121, 127, 81, 82, + 76, 128, 83, 178, 76, 129, 135, 67, 143, 195, + 136, 130, 138, 139, 230, 107, 166, 179, 144, 167, + 137, 145, 168, 196, 140, 141, 99, 142, 149, 84, + 150, 232, 134, 76, 151, 152, 230, 155, 153, 154, + 156, 159, 180, 157, 230, 160, 158, 169, 161, 162, + 230, 233, 163, 181, 247, 164, 417, 182, 170, 173, - 158, 160, 160, 211, 223, 165, 160, 166, 85, 97, - 162, 90, 88, 642, 160, 160, 167, 224, 163, 636, - 104, 642, 642, 160, 78, 80, 168, 103, 169, 107, - 642, 209, 105, 268, 232, 160, 108, 108, 215, 233, - 635, 191, 642, 170, 171, 172, 236, 172, 216, 482, - 172, 172, 172, 172, 483, 172, 172, 172, 367, 368, - 172, 237, 172, 172, 634, 172, 172, 259, 240, 260, - 172, 246, 172, 172, 247, 241, 172, 242, 70, 264, - 172, 159, 265, 248, 249, 160, 161, 250, 266, 251, - 160, 271, 642, 270, 183, 160, 272, 642, 160, 309, + 171, 165, 192, 174, 172, 184, 193, 175, 101, 185, + 176, 188, 189, 186, 197, 230, 194, 304, 198, 187, + 190, 201, 148, 206, 238, 202, 191, 207, 212, 203, + 208, 199, 123, 88, 204, 205, 88, 209, 213, 210, + 219, 214, 211, 219, 223, 113, 220, 235, 128, 1048, + 225, 226, 129, 88, 225, 226, 227, 115, 130, 1048, + 225, 226, 230, 230, 259, 262, 234, 239, 260, 263, + 353, 125, 229, 225, 226, 228, 286, 287, 228, 230, + 109, 126, 228, 230, 228, 231, 354, 99, 230, 230, + 230, 230, 100, 847, 230, 271, 230, 230, 272, 230, + + 230, 230, 289, 236, 230, 290, 117, 230, 230, 230, + 230, 230, 237, 230, 240, 230, 228, 212, 128, 230, + 230, 392, 241, 143, 393, 292, 278, 213, 130, 101, + 214, 242, 243, 144, 293, 300, 145, 412, 230, 343, + 268, 301, 230, 244, 245, 344, 246, 219, 225, 226, + 248, 147, 338, 249, 250, 251, 252, 305, 848, 252, + 306, 148, 339, 252, 252, 252, 252, 359, 307, 313, + 252, 252, 252, 314, 360, 252, 361, 252, 252, 315, + 252, 252, 252, 230, 394, 252, 324, 253, 252, 252, + 252, 128, 252, 395, 252, 241, 340, 252, 325, 326, + + 341, 130, 345, 346, 347, 355, 356, 380, 368, 382, + 342, 369, 357, 383, 400, 407, 408, 381, 230, 252, + 370, 371, 389, 252, 390, 372, 402, 373, 384, 403, + 409, 391, 99, 404, 401, 405, 219, 232, 230, 219, + 281, 410, 220, 88, 225, 226, 227, 1048, 225, 226, + 1048, 225, 226, 230, 230, 230, 230, 413, 230, 230, + 411, 230, 230, 229, 230, 415, 466, 416, 525, 526, + 230, 273, 479, 283, 101, 498, 296, 480, 502, 418, + 466, 543, 414, 499, 281, 219, 225, 226, 248, 419, + 531, 249, 532, 544, 555, 230, 503, 570, 571, 281, + + 556, 230, 230, 424, 230, 572, 230, 230, 467, 230, + 230, 601, 433, 574, 578, 579, 642, 682, 575, 664, + 683, 230, 467, 602, 665, 577, 230, 706, 460, 643, + 230, 230, 576, 230, 707, 230, 760, 771, 230, 710, + 230, 711, 580, 772, 815, 712, 230, 816, 761, 849, + 850, 828, 610, 827, 851, 829, 852, 853, 854, 855, + 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, + 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, + 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, + 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, + + 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, + 906, 907, 908, 909, 910, 911, 912, 913, 230, 230, + 230, 915, 916, 917, 918, 919, 848, 920, 921, 922, + 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, + 933, 934, 935, 936, 937, 938, 939, 940, 914, 941, + 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, + 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, + 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, + 972, 230, 973, 974, 975, 976, 977, 978, 979, 980, + 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, + + 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, + 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, + 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, + 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, + 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, + 1041, 1042, 1043, 1044, 1045, 1046, 1047, 91, 91, 91, + 91, 91, 91, 93, 93, 94, 94, 845, 94, 94, + 94, 97, 97, 97, 221, 221, 221, 221, 221, 221, + 228, 228, 228, 228, 255, 255, 844, 255, 255, 255, + 843, 842, 841, 840, 839, 838, 837, 836, 835, 834, + + 833, 832, 831, 830, 826, 825, 824, 823, 822, 821, + 820, 819, 818, 817, 814, 813, 812, 811, 810, 809, + 808, 807, 806, 805, 804, 803, 802, 801, 800, 799, + 798, 797, 796, 795, 794, 793, 792, 791, 790, 789, + 788, 787, 786, 785, 784, 783, 782, 781, 780, 779, + 778, 777, 776, 775, 774, 773, 770, 769, 768, 767, + 766, 765, 764, 763, 762, 759, 758, 757, 756, 755, + 754, 753, 752, 751, 750, 749, 748, 747, 746, 745, + 744, 743, 742, 741, 740, 739, 738, 737, 736, 735, + 734, 733, 732, 731, 730, 729, 728, 727, 726, 725, + + 724, 723, 722, 721, 720, 719, 718, 717, 716, 715, + 714, 713, 578, 709, 570, 708, 705, 704, 703, 702, + 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, + 691, 690, 689, 688, 687, 686, 685, 684, 681, 680, + 679, 678, 677, 676, 675, 674, 673, 672, 671, 670, + 669, 668, 667, 666, 663, 662, 661, 660, 659, 658, + 657, 656, 655, 654, 653, 652, 651, 650, 649, 648, + 647, 646, 645, 644, 641, 640, 639, 638, 637, 636, + 635, 634, 633, 632, 631, 630, 629, 628, 627, 626, + 625, 624, 623, 622, 621, 620, 619, 618, 617, 616, - 160, 269, 642, 160, 189, 642, 160, 642, 160, 273, - 642, 309, 203, 642, 160, 642, 160, 348, 274, 349, - 369, 642, 160, 642, 284, 160, 390, 160, 278, 642, - 160, 371, 642, 633, 642, 310, 160, 642, 391, 160, - 372, 632, 160, 642, 631, 630, 642, 310, 373, 642, - 160, 396, 160, 447, 507, 629, 160, 642, 557, 642, - 628, 627, 626, 642, 625, 523, 624, 623, 558, 622, - 559, 560, 72, 72, 72, 74, 74, 153, 153, 153, - 160, 160, 174, 174, 621, 620, 619, 618, 617, 616, 615, 614, 613, 612, 611, 610, 609, 608, 607, 606, + 605, 604, 603, 600, 599, 598, 597, 596, 595, 594, + 593, 592, 591, 590, 589, 588, 587, 586, 585, 584, + 583, 582, 581, 580, 573, 569, 568, 567, 566, 565, + 564, 563, 562, 561, 560, 559, 558, 557, 554, 553, + 552, 551, 550, 549, 548, 547, 546, 545, 542, 541, + 540, 539, 538, 537, 536, 535, 534, 533, 530, 529, + 528, 527, 447, 524, 523, 522, 521, 520, 519, 518, + 517, 516, 515, 514, 513, 512, 511, 510, 509, 508, + 507, 506, 505, 504, 501, 500, 497, 496, 495, 494, - 605, 604, 603, 602, 601, 600, 599, 598, 597, 596, - 595, 594, 593, 592, 591, 590, 589, 588, 587, 586, - 585, 584, 583, 582, 581, 580, 579, 578, 577, 576, - 575, 574, 573, 572, 571, 570, 569, 568, 567, 566, - 565, 564, 563, 562, 561, 556, 555, 554, 553, 552, - 551, 550, 549, 548, 547, 546, 545, 544, 543, 542, - 541, 540, 539, 538, 537, 536, 535, 534, 533, 532, - 531, 530, 529, 528, 527, 526, 525, 524, 523, 522, - 521, 520, 519, 518, 517, 516, 515, 514, 513, 512, - 511, 510, 509, 508, 506, 505, 504, 503, 502, 501, + 493, 492, 491, 490, 489, 488, 487, 486, 485, 484, + 483, 482, 481, 478, 477, 476, 475, 474, 473, 472, + 471, 470, 469, 468, 465, 464, 463, 462, 461, 460, + 459, 458, 457, 456, 455, 454, 453, 452, 451, 450, + 449, 448, 447, 446, 445, 444, 443, 442, 441, 440, + 439, 438, 437, 436, 435, 434, 433, 432, 431, 430, + 429, 428, 427, 426, 425, 424, 423, 422, 421, 257, + 420, 420, 250, 230, 230, 225, 222, 222, 406, 399, + 398, 397, 396, 388, 387, 386, 385, 379, 378, 377, + 376, 375, 374, 367, 366, 365, 364, 358, 352, 351, - 500, 499, 498, 497, 496, 495, 494, 493, 492, 491, - 490, 489, 488, 487, 486, 485, 484, 481, 480, 479, - 478, 477, 476, 475, 474, 473, 472, 471, 470, 469, - 468, 467, 466, 465, 464, 463, 462, 461, 460, 459, - 458, 457, 456, 455, 454, 453, 452, 451, 450, 449, - 448, 446, 367, 445, 444, 443, 442, 441, 440, 439, - 438, 437, 436, 435, 434, 433, 432, 431, 430, 429, - 428, 427, 426, 425, 424, 423, 422, 421, 420, 419, - 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, - 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, + 350, 349, 348, 337, 336, 335, 334, 333, 332, 331, + 330, 329, 328, 327, 323, 322, 321, 320, 319, 318, + 317, 316, 312, 311, 310, 309, 308, 303, 302, 299, + 298, 297, 296, 295, 294, 291, 288, 285, 284, 283, + 282, 281, 280, 279, 278, 277, 276, 275, 274, 273, + 270, 269, 268, 267, 266, 265, 264, 261, 258, 257, + 98, 96, 256, 254, 92, 230, 224, 222, 218, 217, + 200, 183, 177, 146, 134, 133, 107, 106, 105, 104, + 98, 96, 95, 92, 90, 89, 1048, 5, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, - 398, 397, 396, 395, 394, 393, 392, 389, 388, 387, - 386, 385, 384, 383, 382, 381, 380, 379, 378, 377, - 376, 375, 374, 373, 370, 366, 365, 364, 363, 362, - 361, 360, 359, 358, 357, 356, 355, 354, 353, 352, - 351, 350, 347, 346, 345, 344, 343, 342, 341, 340, - 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, - 329, 328, 327, 326, 325, 324, 323, 322, 321, 320, - 319, 318, 317, 316, 315, 314, 313, 312, 311, 308, - 307, 306, 305, 304, 303, 302, 301, 300, 299, 298, - 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, - - 287, 286, 285, 284, 283, 282, 281, 280, 279, 278, - 277, 276, 275, 275, 170, 157, 154, 267, 263, 262, - 261, 258, 257, 256, 255, 254, 253, 252, 245, 244, - 243, 239, 238, 235, 234, 231, 230, 229, 228, 227, - 226, 225, 222, 221, 220, 219, 218, 217, 214, 213, - 212, 208, 207, 206, 205, 204, 203, 202, 201, 200, - 197, 194, 193, 192, 191, 190, 189, 188, 187, 186, - 185, 184, 183, 182, 181, 178, 177, 176, 76, 175, - 173, 73, 164, 156, 154, 152, 106, 97, 96, 88, - 83, 78, 77, 76, 76, 75, 73, 71, 642, 5, - - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642 + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048 } ; -static yyconst short int yy_chk[865] = +static yyconst flex_int16_t yy_chk[1363] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -585,109 +943,170 @@ static yyconst short int yy_chk[865] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 17, 7, 20, 4, 7, - 20, 18, 17, 18, 23, 32, 70, 24, 23, 70, - 21, 24, 25, 32, 2, 3, 3, 3, 4, 3, - 21, 24, 3, 3, 3, 3, 25, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 22, 7, 2, 4, 7, + 2, 4, 17, 17, 4, 23, 28, 16, 24, 22, + 24, 189, 16, 25, 28, 23, 25, 29, 23, 189, - 638, 3, 3, 39, 3, 3, 28, 3, 3, 30, - 28, 36, 3, 29, 3, 3, 36, 39, 3, 38, - 28, 30, 3, 29, 29, 33, 37, 38, 637, 34, - 33, 33, 34, 35, 34, 33, 35, 34, 40, 37, - 35, 42, 40, 35, 41, 41, 40, 43, 35, 44, - 45, 42, 40, 46, 635, 47, 44, 47, 45, 41, - 46, 43, 48, 80, 48, 51, 80, 46, 634, 51, - 54, 54, 54, 54, 55, 55, 55, 95, 95, 51, - 56, 56, 56, 57, 57, 57, 58, 58, 58, 633, - 97, 56, 97, 109, 57, 59, 59, 59, 60, 60, + 24, 29, 25, 2, 3, 3, 3, 4, 38, 3, + 734, 29, 31, 3, 3, 3, 3, 58, 38, 58, + 3, 3, 3, 26, 3, 3, 31, 3, 3, 16, + 3, 3, 3, 26, 72, 3, 26, 30, 3, 3, + 3, 30, 3, 46, 3, 30, 34, 3, 36, 52, + 34, 30, 35, 35, 80, 72, 42, 46, 36, 42, + 34, 36, 42, 52, 35, 35, 70, 35, 39, 3, + 39, 70, 80, 3, 39, 39, 71, 40, 39, 39, + 40, 41, 47, 40, 246, 41, 40, 43, 41, 41, + 83, 71, 41, 47, 83, 41, 246, 47, 43, 44, - 60, 62, 65, 109, 120, 62, 63, 64, 62, 65, - 58, 64, 63, 63, 64, 66, 66, 120, 60, 631, - 67, 64, 66, 67, 59, 60, 66, 66, 68, 107, - 67, 108, 67, 155, 128, 68, 108, 107, 113, 128, - 630, 155, 68, 69, 69, 69, 131, 69, 113, 418, - 69, 69, 69, 69, 418, 69, 69, 69, 268, 268, - 69, 131, 69, 69, 629, 69, 69, 146, 134, 146, - 69, 138, 69, 69, 138, 134, 69, 134, 159, 150, - 69, 159, 150, 138, 138, 160, 161, 138, 150, 138, - 162, 164, 160, 163, 164, 161, 165, 162, 159, 209, + 43, 41, 51, 44, 43, 49, 51, 44, 70, 49, + 44, 50, 50, 49, 53, 77, 51, 148, 53, 49, + 50, 55, 148, 56, 77, 55, 50, 56, 57, 55, + 56, 53, 77, 88, 55, 55, 88, 56, 57, 56, + 61, 57, 56, 61, 63, 74, 61, 74, 63, 67, + 67, 67, 63, 66, 66, 66, 66, 74, 63, 68, + 68, 68, 73, 78, 107, 109, 73, 78, 107, 109, + 185, 78, 68, 69, 69, 69, 132, 132, 69, 84, + 73, 78, 69, 69, 69, 69, 185, 100, 75, 69, + 69, 69, 100, 735, 69, 117, 69, 69, 117, 69, - 163, 162, 161, 165, 166, 159, 167, 163, 166, 168, - 165, 309, 167, 167, 169, 166, 168, 249, 169, 249, - 269, 169, 270, 168, 272, 272, 296, 269, 270, 270, - 273, 273, 272, 626, 269, 209, 274, 273, 296, 369, - 274, 625, 371, 274, 624, 623, 369, 309, 369, 371, - 507, 371, 372, 372, 447, 622, 447, 507, 520, 372, - 619, 618, 617, 447, 616, 507, 615, 614, 520, 613, - 520, 520, 643, 643, 643, 644, 644, 645, 645, 645, - 646, 646, 647, 647, 612, 611, 610, 608, 606, 605, - 604, 603, 602, 601, 600, 598, 597, 596, 591, 587, + 69, 69, 134, 75, 69, 134, 75, 69, 69, 69, + 79, 69, 75, 69, 79, 82, 69, 84, 79, 239, + 81, 208, 79, 82, 208, 136, 239, 84, 79, 100, + 84, 81, 81, 82, 136, 143, 82, 235, 69, 178, + 235, 143, 69, 81, 81, 178, 81, 85, 85, 85, + 85, 147, 176, 85, 86, 86, 86, 149, 736, 86, + 149, 147, 176, 86, 86, 86, 86, 188, 149, 155, + 86, 86, 86, 155, 188, 86, 188, 86, 86, 155, + 86, 86, 86, 87, 209, 86, 164, 87, 86, 86, + 86, 87, 86, 209, 86, 87, 177, 86, 164, 164, - 586, 585, 584, 583, 582, 581, 579, 575, 573, 572, - 570, 569, 568, 567, 566, 565, 564, 563, 561, 560, - 559, 558, 557, 556, 555, 550, 549, 547, 546, 545, - 544, 542, 541, 540, 536, 535, 534, 533, 531, 530, - 529, 527, 526, 524, 522, 519, 518, 515, 514, 513, - 512, 511, 510, 509, 508, 505, 504, 502, 501, 499, - 497, 496, 493, 492, 491, 490, 489, 488, 486, 485, - 484, 483, 482, 480, 478, 477, 472, 470, 469, 468, - 467, 465, 462, 461, 460, 459, 458, 456, 455, 454, - 453, 452, 451, 450, 446, 444, 443, 441, 440, 439, + 177, 87, 179, 179, 179, 186, 186, 201, 194, 202, + 177, 194, 186, 202, 214, 218, 218, 201, 233, 86, + 194, 194, 207, 86, 207, 194, 215, 194, 202, 215, + 223, 207, 232, 215, 214, 215, 219, 232, 234, 219, + 223, 233, 219, 227, 227, 227, 227, 228, 228, 228, + 229, 229, 229, 236, 237, 240, 241, 236, 242, 243, + 234, 244, 245, 229, 247, 244, 304, 245, 365, 365, + 253, 237, 318, 241, 232, 337, 243, 318, 340, 247, + 466, 382, 242, 337, 240, 248, 248, 248, 248, 253, + 371, 248, 371, 382, 393, 411, 340, 409, 409, 253, - 437, 435, 434, 433, 431, 430, 429, 428, 427, 426, - 425, 424, 423, 422, 421, 420, 419, 417, 415, 414, - 413, 412, 411, 409, 408, 407, 405, 403, 402, 399, - 398, 397, 395, 394, 393, 392, 391, 390, 388, 387, - 386, 384, 383, 382, 381, 379, 378, 377, 376, 375, - 374, 370, 368, 365, 364, 363, 361, 360, 359, 358, - 357, 356, 355, 354, 352, 351, 350, 348, 347, 346, - 345, 344, 343, 341, 340, 339, 338, 337, 335, 334, - 333, 332, 331, 330, 326, 325, 324, 323, 322, 321, - 319, 318, 317, 316, 315, 314, 313, 312, 311, 308, + 393, 410, 413, 411, 414, 410, 415, 416, 304, 417, + 418, 449, 413, 414, 419, 419, 498, 542, 415, 523, + 542, 572, 466, 449, 523, 418, 419, 567, 416, 498, + 574, 575, 417, 577, 567, 576, 639, 650, 710, 574, + 711, 576, 572, 650, 697, 577, 712, 697, 639, 737, + 739, 711, 575, 710, 740, 712, 741, 742, 745, 746, + 750, 754, 755, 756, 758, 759, 761, 764, 766, 767, + 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, + 778, 780, 781, 783, 784, 785, 786, 787, 788, 789, + 790, 791, 794, 795, 797, 798, 799, 800, 802, 803, - 306, 305, 304, 301, 300, 299, 297, 295, 293, 292, - 291, 290, 289, 288, 286, 285, 284, 283, 282, 280, - 279, 278, 277, 276, 271, 267, 266, 265, 264, 263, - 261, 260, 259, 258, 257, 256, 255, 254, 253, 252, - 251, 250, 248, 247, 246, 245, 244, 243, 242, 241, - 240, 239, 237, 236, 234, 233, 232, 231, 230, 229, - 228, 227, 226, 225, 224, 223, 222, 221, 220, 219, - 218, 217, 216, 215, 214, 213, 212, 211, 210, 208, - 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, - 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, + 804, 805, 806, 807, 808, 810, 811, 812, 815, 816, + 818, 819, 820, 821, 822, 823, 824, 825, 827, 828, + 829, 830, 831, 833, 834, 835, 827, 836, 837, 838, + 839, 841, 843, 844, 845, 846, 847, 850, 853, 856, + 857, 858, 859, 862, 863, 865, 866, 867, 829, 869, + 870, 871, 872, 874, 875, 876, 877, 879, 880, 881, + 882, 883, 888, 889, 890, 891, 892, 893, 894, 896, + 899, 901, 902, 903, 904, 905, 909, 910, 911, 912, + 913, 914, 915, 917, 918, 924, 925, 926, 927, 928, + 930, 932, 933, 934, 936, 938, 940, 941, 942, 943, - 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, - 177, 176, 175, 174, 171, 158, 153, 152, 149, 148, - 147, 145, 144, 143, 142, 141, 140, 139, 137, 136, - 135, 133, 132, 130, 129, 127, 126, 125, 124, 123, - 122, 121, 119, 118, 117, 116, 115, 114, 112, 111, - 110, 106, 105, 104, 103, 102, 101, 100, 99, 98, - 96, 94, 93, 92, 91, 90, 89, 88, 87, 86, - 85, 84, 83, 82, 81, 79, 78, 77, 76, 75, - 74, 72, 61, 53, 50, 49, 31, 27, 26, 22, - 19, 16, 15, 13, 12, 11, 10, 9, 5, 642, + 944, 945, 946, 947, 948, 949, 950, 953, 954, 955, + 956, 958, 961, 963, 964, 965, 966, 971, 974, 976, + 977, 978, 979, 980, 981, 984, 985, 989, 991, 999, + 1000, 1004, 1006, 1011, 1012, 1013, 1014, 1015, 1020, 1023, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1033, 1034, 1035, + 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1049, 1049, 1049, + 1049, 1049, 1049, 1050, 1050, 1051, 1051, 732, 1051, 1051, + 1051, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1053, 1053, + 1054, 1054, 1054, 1054, 1055, 1055, 729, 1055, 1055, 1055, + 728, 727, 726, 725, 724, 722, 721, 720, 719, 718, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - 642, 642, 642, 642 + 717, 716, 715, 714, 709, 708, 706, 705, 704, 703, + 702, 701, 700, 699, 696, 695, 694, 693, 692, 691, + 690, 688, 686, 685, 684, 683, 682, 681, 680, 679, + 678, 677, 676, 675, 673, 672, 671, 670, 669, 668, + 667, 665, 664, 663, 662, 661, 660, 659, 658, 657, + 656, 655, 654, 653, 652, 651, 649, 648, 647, 646, + 645, 644, 643, 642, 641, 638, 637, 636, 635, 634, + 633, 632, 631, 629, 628, 627, 626, 625, 623, 622, + 620, 619, 618, 615, 614, 613, 612, 611, 609, 608, + 607, 606, 605, 604, 603, 602, 601, 599, 598, 597, + + 596, 594, 593, 591, 590, 589, 587, 586, 585, 584, + 583, 581, 579, 573, 571, 568, 566, 565, 564, 562, + 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, + 551, 550, 549, 548, 547, 546, 545, 543, 541, 540, + 539, 538, 537, 535, 534, 533, 531, 530, 529, 528, + 527, 526, 525, 524, 521, 520, 519, 518, 516, 515, + 513, 512, 511, 510, 509, 508, 507, 506, 504, 503, + 502, 501, 500, 499, 497, 496, 495, 494, 493, 489, + 488, 487, 486, 485, 484, 483, 482, 481, 479, 478, + 477, 476, 475, 474, 473, 472, 471, 470, 469, 468, + + 465, 463, 462, 461, 460, 459, 457, 456, 455, 454, + 453, 452, 450, 448, 446, 445, 444, 443, 441, 440, + 439, 438, 436, 435, 434, 433, 431, 429, 427, 426, + 425, 423, 422, 421, 412, 407, 406, 405, 404, 403, + 402, 401, 400, 398, 397, 396, 395, 394, 392, 391, + 390, 389, 388, 387, 386, 385, 384, 383, 381, 380, + 379, 378, 377, 376, 375, 374, 373, 372, 370, 369, + 368, 367, 366, 364, 363, 362, 361, 360, 359, 358, + 356, 355, 354, 353, 351, 350, 349, 348, 346, 345, + 344, 343, 342, 341, 339, 338, 336, 335, 334, 333, + + 332, 331, 330, 328, 327, 326, 325, 324, 323, 322, + 321, 320, 319, 317, 316, 315, 314, 313, 312, 311, + 310, 309, 307, 305, 303, 302, 301, 300, 299, 298, + 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, + 287, 286, 285, 284, 283, 282, 281, 280, 279, 278, + 277, 276, 275, 274, 273, 272, 270, 269, 268, 267, + 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, + 256, 255, 251, 238, 230, 226, 221, 220, 217, 213, + 212, 211, 210, 206, 205, 204, 203, 200, 199, 198, + 197, 196, 195, 193, 192, 191, 190, 187, 184, 183, + + 182, 181, 180, 175, 174, 173, 172, 171, 170, 169, + 168, 167, 166, 165, 163, 162, 161, 160, 159, 158, + 157, 156, 154, 153, 152, 151, 150, 146, 145, 142, + 141, 140, 139, 138, 137, 135, 133, 131, 130, 129, + 128, 127, 126, 125, 124, 123, 121, 120, 119, 118, + 116, 115, 114, 113, 112, 111, 110, 108, 106, 101, + 98, 96, 95, 94, 91, 76, 65, 62, 60, 59, + 54, 48, 45, 37, 33, 32, 21, 20, 19, 18, + 15, 14, 13, 11, 10, 9, 5, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, + 1048, 1048 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; +extern int yy_flex_debug; +int yy_flex_debug = 0; + /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#define INITIAL 0 -/* NetHack 3.5 lev_comp.l $Date: 2009/05/11 22:53:51 $ $Revision: 1.12 $ */ +#line 1 "lev_comp.l" +#line 2 "lev_comp.l" +/* NetHack 3.5 lev_comp.l $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 lev_comp.l $Date: 2009/05/06 10:54:31 $ $Revision: 1.9 $ */ /* SCCS Id: @(#)lev_lex.c 3.5 2002/03/27 */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -753,51 +1172,133 @@ int FDECL(yyoutput, (int)); void FDECL(init_yyin, (FILE *)); void FDECL(init_yyout, (FILE *)); +long NDECL(handle_varstring_check); +long FDECL(corefunc_str_check, (char *, long)); + +extern struct lc_vardefs *FDECL(vardef_defined,(struct lc_vardefs *,char *, int)); + +extern struct lc_vardefs *variable_definitions; + +extern long FDECL(method_defined, (char *, long, long *)); + +void FDECL(savetoken, (char *)); +void NDECL(newline); +void FDECL(advancepos, (char *)); + /* * This doesn't always get put in lev_comp.h * (esp. when using older versions of bison). */ extern YYSTYPE yylval; -int nh_line_number = 1, colon_line_number = 1; +int nh_line_number = 1; +int token_start_pos = 0; +char curr_token[512]; static char map[4096]; static int map_cnt = 0; +FILE *orig_yyin = NULL; + +#define ST_RET(x) do { savetoken(yytext); return x; } while (0); +#define ST_RETF(y, x) do { savetoken(yytext); y; return x; } while (0); + + +#line 1207 "lex.yy.c" + +#define INITIAL 0 #define MAPC 1 +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (void ); + +int yyget_debug (void ); + +void yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE yyget_extra (void ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in (void ); + +void yyset_in (FILE * in_str ); + +FILE *yyget_out (void ); + +void yyset_out (FILE * out_str ); + +yy_size_t yyget_leng (void ); + +char *yyget_text (void ); + +int yyget_lineno (void ); + +void yyset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP -extern int NDECL(yywrap); -#endif - -#ifndef YY_NO_UNPUT -static void FDECL(yyunput, (int,char *)); +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif #endif + static void yyunput (int c,char *buf_ptr ); + #ifndef yytext_ptr -static void FDECL(yy_flex_strncpy, (char *,const char *,int)); +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT -static int NDECL(input); + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else #define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ - #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -805,9 +1306,10 @@ static int NDECL(input); */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ - int c = '*', n; \ + int c = '*'; \ + size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -817,9 +1319,22 @@ static int NDECL(input); YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - @@ -840,6 +1355,19 @@ static int NDECL(input); #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ @@ -854,29 +1382,28 @@ static int NDECL(input); #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ - yy_current_buffer->yy_at_bol = \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION -int NDECL(yylex); -int yylex() - { +/** The main scanner function which does all the work. + */ +YY_DECL +{ register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; - - - - if ( yy_init ) + + if ( !(yy_init) ) { - yy_init = 0; + (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif - if ( ! yy_start ) - yy_start = 1; /* first start state */ + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; @@ -884,74 +1411,81 @@ int yylex() if ( ! yyout ) yyout = stdout; - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); } + yy_load_buffer_state( ); + } + + { +#line 104 "lev_comp.l" + +#line 1427 "lex.yy.c" + while ( 1 ) /* loops until end-of-file is reached */ { - yy_cp = yy_c_buf_p; + yy_cp = (yy_c_buf_p); /* Support of yytext. */ - *yy_cp = yy_hold_char; + *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; - yy_current_state = yy_start; + yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 643 ) + if ( yy_current_state >= 1049 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 800 ); + while ( yy_base[yy_current_state] != 1288 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; - do_action: /* This label is used only to access EOF actions. */ - switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP +#line 105 "lev_comp.l" { + savetoken(yytext); BEGIN(INITIAL); yylval.map = (char *) alloc(map_cnt + 1); (void) strncpy(yylval.map, map, map_cnt); @@ -961,465 +1495,1020 @@ YY_RULE_SETUP } YY_BREAK case 2: +/* rule 2 can match eol */ YY_RULE_SETUP +#line 114 "lev_comp.l" { int len = yyleng; + savetoken(yytext); /* convert \r\n to \n */ if (len >= 2 && yytext[len - 2] == '\r') len -= 1; - nh_line_number++; (void) strncpy(map + map_cnt, yytext, len); map_cnt += len; map[map_cnt - 1] = '\n'; map[map_cnt] = '\0'; + newline(); } YY_BREAK case 3: +/* rule 3 can match eol */ YY_RULE_SETUP -{ nh_line_number++; } +#line 125 "lev_comp.l" +{ savetoken(yytext); newline(); } YY_BREAK case 4: YY_RULE_SETUP -{ colon_line_number = nh_line_number; return ':'; } +#line 126 "lev_comp.l" +ST_RET(MESSAGE_ID); YY_BREAK case 5: YY_RULE_SETUP -return MESSAGE_ID; +#line 127 "lev_comp.l" +ST_RET(NOMAP_ID); YY_BREAK case 6: YY_RULE_SETUP -return MAZE_ID; +#line 128 "lev_comp.l" +ST_RET(MAZE_ID); YY_BREAK case 7: YY_RULE_SETUP -return NOMAP_ID; +#line 129 "lev_comp.l" +ST_RET(LEVEL_ID); YY_BREAK case 8: YY_RULE_SETUP -return LEVEL_ID; +#line 130 "lev_comp.l" +ST_RET(LEV_INIT_ID); YY_BREAK case 9: YY_RULE_SETUP -return LEV_INIT_ID; +#line 131 "lev_comp.l" +ST_RET(MAZE_GRID_ID); YY_BREAK case 10: YY_RULE_SETUP -return FLAGS_ID; +#line 132 "lev_comp.l" +ST_RET(SOLID_FILL_ID); YY_BREAK case 11: YY_RULE_SETUP -return GEOMETRY_ID; +#line 133 "lev_comp.l" +ST_RET(MINES_ID); YY_BREAK case 12: YY_RULE_SETUP -{ BEGIN(MAPC); nh_line_number++; } +#line 134 "lev_comp.l" +ST_RET(ROGUELEV_ID); YY_BREAK case 13: YY_RULE_SETUP -return OBJECT_ID; +#line 135 "lev_comp.l" +ST_RET(FLAGS_ID); YY_BREAK case 14: YY_RULE_SETUP -return COBJECT_ID; +#line 136 "lev_comp.l" +ST_RET(GEOMETRY_ID); YY_BREAK case 15: +/* rule 15 can match eol */ YY_RULE_SETUP -return MONSTER_ID; +#line 137 "lev_comp.l" +{ savetoken(yytext); BEGIN(MAPC); newline(); } YY_BREAK case 16: YY_RULE_SETUP -return TRAP_ID; +#line 138 "lev_comp.l" +ST_RET(object_ID); YY_BREAK case 17: YY_RULE_SETUP -return DOOR_ID; +#line 139 "lev_comp.l" +ST_RET(OBJECT_ID); YY_BREAK case 18: YY_RULE_SETUP -return DRAWBRIDGE_ID; +#line 140 "lev_comp.l" +ST_RET(COBJECT_ID); YY_BREAK case 19: YY_RULE_SETUP -return MAZEWALK_ID; +#line 141 "lev_comp.l" +ST_RET(MONSTER_ID); YY_BREAK case 20: YY_RULE_SETUP -return WALLIFY_ID; +#line 142 "lev_comp.l" +ST_RET(monster_ID); YY_BREAK case 21: YY_RULE_SETUP -return REGION_ID; +#line 143 "lev_comp.l" +ST_RET(TRAP_ID); YY_BREAK case 22: YY_RULE_SETUP -return RANDOM_OBJECTS_ID; +#line 144 "lev_comp.l" +ST_RET(DOOR_ID); YY_BREAK case 23: YY_RULE_SETUP -return RANDOM_MONSTERS_ID; +#line 145 "lev_comp.l" +ST_RET(ROOMDOOR_ID); YY_BREAK case 24: YY_RULE_SETUP -return RANDOM_PLACES_ID; +#line 146 "lev_comp.l" +ST_RET(DRAWBRIDGE_ID); YY_BREAK case 25: YY_RULE_SETUP -return ALTAR_ID; +#line 147 "lev_comp.l" +ST_RET(MAZEWALK_ID); YY_BREAK case 26: YY_RULE_SETUP -return LADDER_ID; +#line 148 "lev_comp.l" +ST_RET(WALLIFY_ID); YY_BREAK case 27: YY_RULE_SETUP -return STAIR_ID; +#line 149 "lev_comp.l" +ST_RET(REGION_ID); YY_BREAK case 28: YY_RULE_SETUP -return PORTAL_ID; +#line 150 "lev_comp.l" +ST_RET(ALTAR_ID); YY_BREAK case 29: YY_RULE_SETUP -return TELEPRT_ID; +#line 151 "lev_comp.l" +ST_RET(LADDER_ID); YY_BREAK case 30: YY_RULE_SETUP -return BRANCH_ID; +#line 152 "lev_comp.l" +ST_RET(STAIR_ID); YY_BREAK case 31: YY_RULE_SETUP -return FOUNTAIN_ID; +#line 153 "lev_comp.l" +ST_RET(PORTAL_ID); YY_BREAK case 32: YY_RULE_SETUP -return SINK_ID; +#line 154 "lev_comp.l" +ST_RET(TELEPRT_ID); YY_BREAK case 33: YY_RULE_SETUP -return POOL_ID; +#line 155 "lev_comp.l" +ST_RET(BRANCH_ID); YY_BREAK case 34: YY_RULE_SETUP -return NON_DIGGABLE_ID; +#line 156 "lev_comp.l" +ST_RET(FOUNTAIN_ID); YY_BREAK case 35: YY_RULE_SETUP -return NON_PASSWALL_ID; +#line 157 "lev_comp.l" +ST_RET(SINK_ID); YY_BREAK case 36: YY_RULE_SETUP -return ROOM_ID; +#line 158 "lev_comp.l" +ST_RET(POOL_ID); YY_BREAK case 37: YY_RULE_SETUP -return SUBROOM_ID; +#line 159 "lev_comp.l" +ST_RET(NON_DIGGABLE_ID); YY_BREAK case 38: YY_RULE_SETUP -return RAND_CORRIDOR_ID; +#line 160 "lev_comp.l" +ST_RET(NON_PASSWALL_ID); YY_BREAK case 39: YY_RULE_SETUP -return CORRIDOR_ID; +#line 161 "lev_comp.l" +ST_RET(IF_ID); YY_BREAK case 40: YY_RULE_SETUP -return GOLD_ID; +#line 162 "lev_comp.l" +ST_RET(ELSE_ID); YY_BREAK case 41: YY_RULE_SETUP -return ENGRAVING_ID; +#line 163 "lev_comp.l" +ST_RET(EXIT_ID); YY_BREAK case 42: YY_RULE_SETUP -return NAME_ID; +#line 164 "lev_comp.l" +ST_RET(ROOM_ID); YY_BREAK case 43: YY_RULE_SETUP -return CHANCE_ID; +#line 165 "lev_comp.l" +ST_RET(SUBROOM_ID); YY_BREAK case 44: YY_RULE_SETUP -return LEV; +#line 166 "lev_comp.l" +ST_RET(RAND_CORRIDOR_ID); YY_BREAK case 45: YY_RULE_SETUP -{ yylval.i=D_ISOPEN; return DOOR_STATE; } +#line 167 "lev_comp.l" +ST_RET(CORRIDOR_ID); YY_BREAK case 46: YY_RULE_SETUP -{ yylval.i=D_CLOSED; return DOOR_STATE; } +#line 168 "lev_comp.l" +ST_RET(TERRAIN_ID); YY_BREAK case 47: YY_RULE_SETUP -{ yylval.i=D_LOCKED; return DOOR_STATE; } +#line 169 "lev_comp.l" +ST_RET(terrain_ID); YY_BREAK case 48: YY_RULE_SETUP -{ yylval.i=D_NODOOR; return DOOR_STATE; } +#line 170 "lev_comp.l" +ST_RET(REPLACE_TERRAIN_ID); YY_BREAK case 49: YY_RULE_SETUP -{ yylval.i=D_BROKEN; return DOOR_STATE; } +#line 171 "lev_comp.l" +ST_RET(GOLD_ID); YY_BREAK case 50: YY_RULE_SETUP -{ yylval.i=W_NORTH; return DIRECTION; } +#line 172 "lev_comp.l" +ST_RET(GRAVE_ID); YY_BREAK case 51: YY_RULE_SETUP -{ yylval.i=W_EAST; return DIRECTION; } +#line 173 "lev_comp.l" +ST_RET(ENGRAVING_ID); YY_BREAK case 52: YY_RULE_SETUP -{ yylval.i=W_SOUTH; return DIRECTION; } +#line 174 "lev_comp.l" +ST_RET(MINERALIZE_ID); YY_BREAK case 53: YY_RULE_SETUP -{ yylval.i=W_WEST; return DIRECTION; } +#line 175 "lev_comp.l" +ST_RET(NAME_ID); YY_BREAK case 54: YY_RULE_SETUP -{ yylval.i = -1; return RANDOM_TYPE; } +#line 176 "lev_comp.l" +ST_RET(FOR_ID); YY_BREAK case 55: YY_RULE_SETUP -{ yylval.i = -2; return NONE; } +#line 177 "lev_comp.l" +ST_RET(TO_ID); YY_BREAK case 56: YY_RULE_SETUP -return O_REGISTER; +#line 178 "lev_comp.l" +ST_RET(LOOP_ID); YY_BREAK case 57: YY_RULE_SETUP -return M_REGISTER; +#line 179 "lev_comp.l" +ST_RET(SWITCH_ID); YY_BREAK case 58: YY_RULE_SETUP -return P_REGISTER; +#line 180 "lev_comp.l" +ST_RET(CASE_ID); YY_BREAK case 59: YY_RULE_SETUP -return A_REGISTER; +#line 181 "lev_comp.l" +ST_RET(BREAK_ID); YY_BREAK case 60: YY_RULE_SETUP -{ yylval.i=1; return LEFT_OR_RIGHT; } +#line 182 "lev_comp.l" +ST_RET(DEFAULT_ID); YY_BREAK case 61: YY_RULE_SETUP -{ yylval.i=2; return LEFT_OR_RIGHT; } +#line 183 "lev_comp.l" +ST_RET(FUNCTION_ID); YY_BREAK case 62: YY_RULE_SETUP -{ yylval.i=3; return CENTER; } +#line 184 "lev_comp.l" +ST_RET(SHUFFLE_ID); YY_BREAK case 63: YY_RULE_SETUP -{ yylval.i=4; return LEFT_OR_RIGHT; } +#line 185 "lev_comp.l" +ST_RET(MONTYPE_ID); YY_BREAK case 64: YY_RULE_SETUP -{ yylval.i=5; return LEFT_OR_RIGHT; } +#line 186 "lev_comp.l" +ST_RET(selection_ID); YY_BREAK case 65: YY_RULE_SETUP -{ yylval.i=1; return TOP_OR_BOT; } +#line 187 "lev_comp.l" +ST_RET(rect_ID); YY_BREAK case 66: YY_RULE_SETUP -{ yylval.i=5; return TOP_OR_BOT; } +#line 188 "lev_comp.l" +ST_RET(fillrect_ID); YY_BREAK case 67: YY_RULE_SETUP -{ yylval.i=1; return LIGHT_STATE; } +#line 189 "lev_comp.l" +ST_RET(line_ID); YY_BREAK case 68: YY_RULE_SETUP -{ yylval.i=0; return LIGHT_STATE; } +#line 190 "lev_comp.l" +ST_RET(randline_ID); YY_BREAK case 69: YY_RULE_SETUP -{ yylval.i=0; return FILLING; } +#line 191 "lev_comp.l" +ST_RET(grow_ID); YY_BREAK case 70: YY_RULE_SETUP -{ yylval.i=1; return FILLING; } +#line 192 "lev_comp.l" +ST_RET(flood_ID); YY_BREAK case 71: YY_RULE_SETUP -{ yylval.i= AM_NONE; return ALIGNMENT; } +#line 193 "lev_comp.l" +ST_RET(rndcoord_ID); YY_BREAK case 72: YY_RULE_SETUP -{ yylval.i= AM_LAWFUL; return ALIGNMENT; } +#line 194 "lev_comp.l" +ST_RET(circle_ID); YY_BREAK case 73: YY_RULE_SETUP -{ yylval.i= AM_NEUTRAL; return ALIGNMENT; } +#line 195 "lev_comp.l" +ST_RET(ellipse_ID); YY_BREAK case 74: YY_RULE_SETUP -{ yylval.i= AM_CHAOTIC; return ALIGNMENT; } +#line 196 "lev_comp.l" +ST_RET(filter_ID); YY_BREAK case 75: YY_RULE_SETUP -{ yylval.i= AM_SPLEV_CO; return ALIGNMENT; } +#line 197 "lev_comp.l" +ST_RET(gradient_ID); YY_BREAK case 76: YY_RULE_SETUP -{ yylval.i= AM_SPLEV_NONCO; return ALIGNMENT; } +#line 198 "lev_comp.l" +ST_RET(complement_ID); YY_BREAK case 77: YY_RULE_SETUP -{ yylval.i=1; return MON_ATTITUDE; } +#line 199 "lev_comp.l" +{ savetoken(yytext); yylval.i=SEL_GRADIENT_RADIAL; return GRADIENT_TYPE; } YY_BREAK case 78: YY_RULE_SETUP -{ yylval.i=0; return MON_ATTITUDE; } +#line 200 "lev_comp.l" +{ savetoken(yytext); yylval.i=SEL_GRADIENT_SQUARE; return GRADIENT_TYPE; } YY_BREAK case 79: YY_RULE_SETUP -{ yylval.i=1; return MON_ALERTNESS; } +#line 201 "lev_comp.l" +{ savetoken(yytext); yylval.i=DRY; return HUMIDITY_TYPE; } YY_BREAK case 80: YY_RULE_SETUP -{ yylval.i=0; return MON_ALERTNESS; } +#line 202 "lev_comp.l" +{ savetoken(yytext); yylval.i=WET; return HUMIDITY_TYPE; } YY_BREAK case 81: YY_RULE_SETUP -{ yylval.i= M_AP_FURNITURE; return MON_APPEARANCE; } +#line 203 "lev_comp.l" +{ savetoken(yytext); yylval.i=HOT; return HUMIDITY_TYPE; } YY_BREAK case 82: YY_RULE_SETUP -{ yylval.i= M_AP_MONSTER; return MON_APPEARANCE; } +#line 204 "lev_comp.l" +{ savetoken(yytext); yylval.i=SOLID; return HUMIDITY_TYPE; } YY_BREAK case 83: YY_RULE_SETUP -{ yylval.i= M_AP_OBJECT; return MON_APPEARANCE; } +#line 205 "lev_comp.l" +{ savetoken(yytext); yylval.i=ANY_LOC; return HUMIDITY_TYPE; } YY_BREAK case 84: YY_RULE_SETUP -{ yylval.i=2; return ALTAR_TYPE; } +#line 206 "lev_comp.l" +ST_RET(LEV); YY_BREAK case 85: YY_RULE_SETUP -{ yylval.i=1; return ALTAR_TYPE; } +#line 207 "lev_comp.l" +ST_RET(QUANTITY_ID); YY_BREAK case 86: YY_RULE_SETUP -{ yylval.i=0; return ALTAR_TYPE; } +#line 208 "lev_comp.l" +ST_RET(BURIED_ID); YY_BREAK case 87: YY_RULE_SETUP -{ yylval.i=1; return UP_OR_DOWN; } +#line 209 "lev_comp.l" +ST_RET(ERODED_ID); YY_BREAK case 88: YY_RULE_SETUP -{ yylval.i=0; return UP_OR_DOWN; } +#line 210 "lev_comp.l" +ST_RET(ERODEPROOF_ID); YY_BREAK case 89: YY_RULE_SETUP -{ yylval.i=0; return BOOLEAN; } +#line 211 "lev_comp.l" +ST_RET(TRAPPED_ID); YY_BREAK case 90: YY_RULE_SETUP -{ yylval.i=1; return BOOLEAN; } +#line 212 "lev_comp.l" +ST_RET(RECHARGED_ID); YY_BREAK case 91: YY_RULE_SETUP -{ yylval.i=DUST; return ENGRAVING_TYPE; } +#line 213 "lev_comp.l" +ST_RET(INVIS_ID); YY_BREAK case 92: YY_RULE_SETUP -{ yylval.i=ENGRAVE; return ENGRAVING_TYPE; } +#line 214 "lev_comp.l" +ST_RET(GREASED_ID); YY_BREAK case 93: YY_RULE_SETUP -{ yylval.i=BURN; return ENGRAVING_TYPE; } +#line 215 "lev_comp.l" +ST_RET(FEMALE_ID); YY_BREAK case 94: YY_RULE_SETUP -{ yylval.i=MARK; return ENGRAVING_TYPE; } +#line 216 "lev_comp.l" +ST_RET(CANCELLED_ID); YY_BREAK case 95: YY_RULE_SETUP -{ yylval.i=ENGR_BLOOD; return ENGRAVING_TYPE; } +#line 217 "lev_comp.l" +ST_RET(REVIVED_ID); YY_BREAK case 96: YY_RULE_SETUP -{ yylval.i=1; return CURSE_TYPE; } +#line 218 "lev_comp.l" +ST_RET(AVENGE_ID); YY_BREAK case 97: YY_RULE_SETUP -{ yylval.i=2; return CURSE_TYPE; } +#line 219 "lev_comp.l" +ST_RET(FLEEING_ID); YY_BREAK case 98: YY_RULE_SETUP -{ yylval.i=3; return CURSE_TYPE; } +#line 220 "lev_comp.l" +ST_RET(BLINDED_ID); YY_BREAK case 99: YY_RULE_SETUP -{ return CONTAINED; } +#line 221 "lev_comp.l" +ST_RET(PARALYZED_ID); YY_BREAK case 100: YY_RULE_SETUP -{ yylval.i=NOTELEPORT; return FLAG_TYPE; } +#line 222 "lev_comp.l" +ST_RET(STUNNED_ID); YY_BREAK case 101: YY_RULE_SETUP -{ yylval.i=HARDFLOOR; return FLAG_TYPE; } +#line 223 "lev_comp.l" +ST_RET(CONFUSED_ID); YY_BREAK case 102: YY_RULE_SETUP -{ yylval.i=NOMMAP; return FLAG_TYPE; } +#line 224 "lev_comp.l" +ST_RET(SEENTRAPS_ID); YY_BREAK case 103: YY_RULE_SETUP -{ yylval.i=ARBOREAL; return FLAG_TYPE; } /* KMH */ +#line 225 "lev_comp.l" +ST_RET(ALL_ID); YY_BREAK case 104: YY_RULE_SETUP -{ yylval.i=SHORTSIGHTED; return FLAG_TYPE; } +#line 226 "lev_comp.l" +ST_RETF((yylval.i=1), HORIZ_OR_VERT); YY_BREAK case 105: YY_RULE_SETUP -{ yylval.i = atoi(yytext + 1); return PERCENT; } +#line 227 "lev_comp.l" +{ savetoken(yytext); yylval.i=2; return HORIZ_OR_VERT; } YY_BREAK case 106: YY_RULE_SETUP -{ yylval.i=atoi(yytext); return INTEGER; } +#line 228 "lev_comp.l" +{ savetoken(yytext); yylval.i=D_ISOPEN; return DOOR_STATE; } YY_BREAK case 107: YY_RULE_SETUP -{ yytext[yyleng-1] = 0; /* Discard the trailing \" */ +#line 229 "lev_comp.l" +{ savetoken(yytext); yylval.i=D_CLOSED; return DOOR_STATE; } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 230 "lev_comp.l" +{ savetoken(yytext); yylval.i=D_LOCKED; return DOOR_STATE; } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 231 "lev_comp.l" +{ savetoken(yytext); yylval.i=D_NODOOR; return DOOR_STATE; } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 232 "lev_comp.l" +{ savetoken(yytext); yylval.i=D_BROKEN; return DOOR_STATE; } + YY_BREAK +case 111: +YY_RULE_SETUP +#line 233 "lev_comp.l" +{ savetoken(yytext); yylval.i=D_SECRET; return DOOR_STATE; } + YY_BREAK +case 112: +YY_RULE_SETUP +#line 234 "lev_comp.l" +{ savetoken(yytext); yylval.i=W_NORTH; return DIRECTION; } + YY_BREAK +case 113: +YY_RULE_SETUP +#line 235 "lev_comp.l" +{ savetoken(yytext); yylval.i=W_EAST; return DIRECTION; } + YY_BREAK +case 114: +YY_RULE_SETUP +#line 236 "lev_comp.l" +{ savetoken(yytext); yylval.i=W_SOUTH; return DIRECTION; } + YY_BREAK +case 115: +YY_RULE_SETUP +#line 237 "lev_comp.l" +{ savetoken(yytext); yylval.i=W_WEST; return DIRECTION; } + YY_BREAK +case 116: +YY_RULE_SETUP +#line 238 "lev_comp.l" +{ savetoken(yytext); yylval.i = -1; return RANDOM_TYPE; } + YY_BREAK +case 117: +YY_RULE_SETUP +#line 239 "lev_comp.l" +{ savetoken(yytext); yylval.i = -1; return RANDOM_TYPE_BRACKET; } + YY_BREAK +case 118: +YY_RULE_SETUP +#line 240 "lev_comp.l" +{ savetoken(yytext); yylval.i = -2; return NONE; } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 241 "lev_comp.l" +ST_RET(A_REGISTER); + YY_BREAK +case 120: +YY_RULE_SETUP +#line 242 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return LEFT_OR_RIGHT; } + YY_BREAK +case 121: +YY_RULE_SETUP +#line 243 "lev_comp.l" +{ savetoken(yytext); yylval.i=2; return LEFT_OR_RIGHT; } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 244 "lev_comp.l" +{ savetoken(yytext); yylval.i=3; return CENTER; } + YY_BREAK +case 123: +YY_RULE_SETUP +#line 245 "lev_comp.l" +{ savetoken(yytext); yylval.i=4; return LEFT_OR_RIGHT; } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 246 "lev_comp.l" +{ savetoken(yytext); yylval.i=5; return LEFT_OR_RIGHT; } + YY_BREAK +case 125: +YY_RULE_SETUP +#line 247 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return TOP_OR_BOT; } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 248 "lev_comp.l" +{ savetoken(yytext); yylval.i=5; return TOP_OR_BOT; } + YY_BREAK +case 127: +YY_RULE_SETUP +#line 249 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return LIGHT_STATE; } + YY_BREAK +case 128: +YY_RULE_SETUP +#line 250 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return LIGHT_STATE; } + YY_BREAK +case 129: +YY_RULE_SETUP +#line 251 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return FILLING; } + YY_BREAK +case 130: +YY_RULE_SETUP +#line 252 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return FILLING; } + YY_BREAK +case 131: +YY_RULE_SETUP +#line 253 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return IRREGULAR; } + YY_BREAK +case 132: +YY_RULE_SETUP +#line 254 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return IRREGULAR; } + YY_BREAK +case 133: +YY_RULE_SETUP +#line 255 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return JOINED; } + YY_BREAK +case 134: +YY_RULE_SETUP +#line 256 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return JOINED; } + YY_BREAK +case 135: +YY_RULE_SETUP +#line 257 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return LIMITED; } + YY_BREAK +case 136: +YY_RULE_SETUP +#line 258 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return LIMITED; } + YY_BREAK +case 137: +YY_RULE_SETUP +#line 259 "lev_comp.l" +{ savetoken(yytext); yylval.i= AM_NONE; return ALIGNMENT; } + YY_BREAK +case 138: +YY_RULE_SETUP +#line 260 "lev_comp.l" +{ savetoken(yytext); yylval.i= AM_LAWFUL; return ALIGNMENT; } + YY_BREAK +case 139: +YY_RULE_SETUP +#line 261 "lev_comp.l" +{ savetoken(yytext); yylval.i= AM_NEUTRAL; return ALIGNMENT; } + YY_BREAK +case 140: +YY_RULE_SETUP +#line 262 "lev_comp.l" +{ savetoken(yytext); yylval.i= AM_CHAOTIC; return ALIGNMENT; } + YY_BREAK +case 141: +YY_RULE_SETUP +#line 263 "lev_comp.l" +{ savetoken(yytext); yylval.i= AM_SPLEV_CO; return ALIGNMENT; } + YY_BREAK +case 142: +YY_RULE_SETUP +#line 264 "lev_comp.l" +{ savetoken(yytext); yylval.i= AM_SPLEV_NONCO; return ALIGNMENT; } + YY_BREAK +case 143: +YY_RULE_SETUP +#line 265 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return MON_ATTITUDE; } + YY_BREAK +case 144: +YY_RULE_SETUP +#line 266 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return MON_ATTITUDE; } + YY_BREAK +case 145: +YY_RULE_SETUP +#line 267 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return MON_ALERTNESS; } + YY_BREAK +case 146: +YY_RULE_SETUP +#line 268 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return MON_ALERTNESS; } + YY_BREAK +case 147: +YY_RULE_SETUP +#line 269 "lev_comp.l" +{ savetoken(yytext); yylval.i= M_AP_FURNITURE; return MON_APPEARANCE; } + YY_BREAK +case 148: +YY_RULE_SETUP +#line 270 "lev_comp.l" +{ savetoken(yytext); yylval.i= M_AP_MONSTER; return MON_APPEARANCE; } + YY_BREAK +case 149: +YY_RULE_SETUP +#line 271 "lev_comp.l" +{ savetoken(yytext); yylval.i= M_AP_OBJECT; return MON_APPEARANCE; } + YY_BREAK +case 150: +YY_RULE_SETUP +#line 272 "lev_comp.l" +{ savetoken(yytext); yylval.i=2; return ALTAR_TYPE; } + YY_BREAK +case 151: +YY_RULE_SETUP +#line 273 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return ALTAR_TYPE; } + YY_BREAK +case 152: +YY_RULE_SETUP +#line 274 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return ALTAR_TYPE; } + YY_BREAK +case 153: +YY_RULE_SETUP +#line 275 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return UP_OR_DOWN; } + YY_BREAK +case 154: +YY_RULE_SETUP +#line 276 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return UP_OR_DOWN; } + YY_BREAK +case 155: +YY_RULE_SETUP +#line 277 "lev_comp.l" +{ savetoken(yytext); yylval.i=0; return BOOLEAN; } + YY_BREAK +case 156: +YY_RULE_SETUP +#line 278 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return BOOLEAN; } + YY_BREAK +case 157: +YY_RULE_SETUP +#line 279 "lev_comp.l" +{ savetoken(yytext); yylval.i=DUST; return ENGRAVING_TYPE; } + YY_BREAK +case 158: +YY_RULE_SETUP +#line 280 "lev_comp.l" +{ savetoken(yytext); yylval.i=ENGRAVE; return ENGRAVING_TYPE; } + YY_BREAK +case 159: +YY_RULE_SETUP +#line 281 "lev_comp.l" +{ savetoken(yytext); yylval.i=BURN; return ENGRAVING_TYPE; } + YY_BREAK +case 160: +YY_RULE_SETUP +#line 282 "lev_comp.l" +{ savetoken(yytext); yylval.i=MARK; return ENGRAVING_TYPE; } + YY_BREAK +case 161: +YY_RULE_SETUP +#line 283 "lev_comp.l" +{ savetoken(yytext); yylval.i=ENGR_BLOOD; return ENGRAVING_TYPE; } + YY_BREAK +case 162: +YY_RULE_SETUP +#line 284 "lev_comp.l" +{ savetoken(yytext); yylval.i=1; return CURSE_TYPE; } + YY_BREAK +case 163: +YY_RULE_SETUP +#line 285 "lev_comp.l" +{ savetoken(yytext); yylval.i=2; return CURSE_TYPE; } + YY_BREAK +case 164: +YY_RULE_SETUP +#line 286 "lev_comp.l" +{ savetoken(yytext); yylval.i=3; return CURSE_TYPE; } + YY_BREAK +case 165: +YY_RULE_SETUP +#line 287 "lev_comp.l" +{ savetoken(yytext); yylval.i=NOTELEPORT; return FLAG_TYPE; } + YY_BREAK +case 166: +YY_RULE_SETUP +#line 288 "lev_comp.l" +{ savetoken(yytext); yylval.i=HARDFLOOR; return FLAG_TYPE; } + YY_BREAK +case 167: +YY_RULE_SETUP +#line 289 "lev_comp.l" +{ savetoken(yytext); yylval.i=NOMMAP; return FLAG_TYPE; } + YY_BREAK +case 168: +YY_RULE_SETUP +#line 290 "lev_comp.l" +{ savetoken(yytext); yylval.i=ARBOREAL; return FLAG_TYPE; } /* KMH */ + YY_BREAK +case 169: +YY_RULE_SETUP +#line 291 "lev_comp.l" +{ savetoken(yytext); yylval.i=SHORTSIGHTED; return FLAG_TYPE; } + YY_BREAK +case 170: +YY_RULE_SETUP +#line 292 "lev_comp.l" +{ savetoken(yytext); yylval.i=MAZELEVEL; return FLAG_TYPE; } + YY_BREAK +case 171: +YY_RULE_SETUP +#line 293 "lev_comp.l" +{ savetoken(yytext); yylval.i=PREMAPPED; return FLAG_TYPE; } + YY_BREAK +case 172: +YY_RULE_SETUP +#line 294 "lev_comp.l" +{ savetoken(yytext); yylval.i=SHROUD; return FLAG_TYPE; } + YY_BREAK +case 173: +YY_RULE_SETUP +#line 295 "lev_comp.l" +{ savetoken(yytext); yylval.i=GRAVEYARD; return FLAG_TYPE; } + YY_BREAK +case 174: +YY_RULE_SETUP +#line 296 "lev_comp.l" +{ savetoken(yytext); yylval.i=ICEDPOOLS; return FLAG_TYPE; } + YY_BREAK +case 175: +YY_RULE_SETUP +#line 297 "lev_comp.l" +{ savetoken(yytext); yylval.i=SOLIDIFY; return FLAG_TYPE; } + YY_BREAK +case 176: +YY_RULE_SETUP +#line 298 "lev_comp.l" +{ char *p = strchr(yytext, 'd'); + savetoken(yytext); + if (p) { + *p = '\0'; + p++; + yylval.dice.num=atoi(yytext); + yylval.dice.die=atoi(p); + } else { yylval.dice.num = yylval.dice.die = 1; } + return DICE; + } + YY_BREAK +case 177: +YY_RULE_SETUP +#line 308 "lev_comp.l" +{ savetoken(yytext); yylval.i = atoi(yytext + 1); + if (yylval.i < 0 || yylval.i > 100) + lc_error("Unexpected percentile '%li%%'", yylval.i); + return PERCENT; } + YY_BREAK +case 178: +YY_RULE_SETUP +#line 312 "lev_comp.l" +{ savetoken(yytext); yylval.i=atoi(yytext); return MINUS_INTEGER; } + YY_BREAK +case 179: +YY_RULE_SETUP +#line 313 "lev_comp.l" +{ savetoken(yytext); yylval.i=atoi(yytext); return PLUS_INTEGER; } + YY_BREAK +case 180: +YY_RULE_SETUP +#line 314 "lev_comp.l" +{ savetoken(yytext); yylval.i = atoi(yytext); + if (yylval.i < 0 || yylval.i > 100) + lc_error("Unexpected percentile '%li%%'", yylval.i); + return SPERCENT; } + YY_BREAK +case 181: +YY_RULE_SETUP +#line 318 "lev_comp.l" +{ savetoken(yytext); yylval.i=atoi(yytext); return INTEGER; } + YY_BREAK +case 182: +/* rule 182 can match eol */ +YY_RULE_SETUP +#line 319 "lev_comp.l" +{ savetoken(yytext); + yytext[yyleng-1] = 0; /* Discard the trailing \" */ yylval.map = (char *) alloc(strlen(yytext+1)+1); Strcpy(yylval.map, yytext+1); /* Discard the first \" */ return STRING; } YY_BREAK -case 108: +case 183: YY_RULE_SETUP -{ nh_line_number++; } +#line 324 "lev_comp.l" +{ savetoken(yytext); return handle_varstring_check(); } YY_BREAK -case 109: +case 184: YY_RULE_SETUP -; +#line 325 "lev_comp.l" +{ savetoken(yytext); yylval.i = SPO_JE; return COMPARE_TYPE; } YY_BREAK -case 110: +case 185: YY_RULE_SETUP -{ yylval.i = yytext[2]; return CHAR; } +#line 326 "lev_comp.l" +{ savetoken(yytext); yylval.i = SPO_JNE; return COMPARE_TYPE; } YY_BREAK -case 111: +case 186: YY_RULE_SETUP -{ yylval.i = yytext[1]; return CHAR; } +#line 327 "lev_comp.l" +{ savetoken(yytext); yylval.i = SPO_JNE; return COMPARE_TYPE; } YY_BREAK -case 112: +case 187: YY_RULE_SETUP -{ return yytext[0]; } +#line 328 "lev_comp.l" +{ savetoken(yytext); yylval.i = SPO_JLE; return COMPARE_TYPE; } YY_BREAK -case 113: +case 188: YY_RULE_SETUP +#line 329 "lev_comp.l" +{ savetoken(yytext); yylval.i = SPO_JGE; return COMPARE_TYPE; } + YY_BREAK +case 189: +YY_RULE_SETUP +#line 330 "lev_comp.l" +{ savetoken(yytext); yylval.i = SPO_JL; return COMPARE_TYPE; } + YY_BREAK +case 190: +YY_RULE_SETUP +#line 331 "lev_comp.l" +{ savetoken(yytext); yylval.i = SPO_JG; return COMPARE_TYPE; } + YY_BREAK +case 191: +/* rule 191 can match eol */ +YY_RULE_SETUP +#line 332 "lev_comp.l" +{ newline(); } + YY_BREAK +case 192: +YY_RULE_SETUP +#line 333 "lev_comp.l" +{ advancepos(yytext); } + YY_BREAK +case 193: +YY_RULE_SETUP +#line 334 "lev_comp.l" +{ savetoken(yytext); yylval.i = yytext[2]; return CHAR; } + YY_BREAK +case 194: +YY_RULE_SETUP +#line 335 "lev_comp.l" +{ savetoken(yytext); yylval.i = yytext[1]; return CHAR; } + YY_BREAK +case 195: +YY_RULE_SETUP +#line 336 "lev_comp.l" +ST_RET(UNKNOWN_TYPE); + YY_BREAK +case 196: +YY_RULE_SETUP +#line 337 "lev_comp.l" +{ savetoken(yytext); return yytext[0]; } + YY_BREAK +case 197: +YY_RULE_SETUP +#line 338 "lev_comp.l" ECHO; YY_BREAK +#line 2512 "lex.yy.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(MAPC): yyterminate(); @@ -1427,25 +2516,26 @@ case YY_STATE_EOF(MAPC): case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our + * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position @@ -1455,13 +2545,13 @@ case YY_STATE_EOF(MAPC): * end-of-buffer state). Contrast this with the test * in input(). */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have @@ -1474,30 +2564,30 @@ case YY_STATE_EOF(MAPC): yy_next_state = yy_try_NUL_trans( yy_current_state ); - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; + yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { - yy_cp = yy_c_buf_p; + yy_cp = (yy_c_buf_p); goto yy_find_action; } } - else switch ( yy_get_next_buffer() ) + else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { - yy_did_buffer_switch_on_eof = 0; + (yy_did_buffer_switch_on_eof) = 0; - if ( yywrap() ) + if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up @@ -1508,7 +2598,7 @@ case YY_STATE_EOF(MAPC): * YY_NULL, it'll still work - another * YY_NULL will get returned. */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; @@ -1516,30 +2606,30 @@ case YY_STATE_EOF(MAPC): else { - if ( ! yy_did_buffer_switch_on_eof ) + if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state( ); - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state( ); - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; @@ -1550,8 +2640,8 @@ case YY_STATE_EOF(MAPC): "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ - } /* end of yylex */ - + } /* end of user's declarations */ +} /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * @@ -1560,23 +2650,22 @@ case YY_STATE_EOF(MAPC): * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); - if ( yy_current_buffer->yy_fill_buffer == 0 ) + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { - /* We matched a singled characater, the EOB, so + /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; @@ -1594,39 +2683,34 @@ static int yy_get_next_buffer() /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ - yy_n_chars = 0; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); + (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { - int old_size = b->yy_buf_size + 2; - int new_size = b->yy_buf_size * 2; + yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -1635,8 +2719,7 @@ static int yy_get_next_buffer() b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ - yy_flex_realloc2( (genericptr_t) b->yy_ch_buf, - b->yy_buf_size + 2, old_size ); + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ @@ -1646,33 +2729,35 @@ static int yy_get_next_buffer() YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = yy_current_buffer->yy_buf_size - + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; -#endif + } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } - if ( yy_n_chars == 0 ) + if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); + yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } @@ -1680,229 +2765,266 @@ static int yy_get_next_buffer() else ret_val = EOB_ACT_CONTINUE_SCAN; - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} /* yy_get_previous_state - get the state just before the EOB char was reached */ -static yy_state_type yy_get_previous_state() - { + static yy_state_type yy_get_previous_state (void) +{ register yy_state_type yy_current_state; register char *yy_cp; - - yy_current_state = yy_start; + + yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 643 ) + if ( yy_current_state >= 1049 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; - } - +} /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ - -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; - { + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; + register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 643 ) + if ( yy_current_state >= 1049 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 642); + yy_is_jam = (yy_current_state == 1048); - return yy_is_jam ? 0 : yy_current_state; - } + return yy_is_jam ? 0 : yy_current_state; +} - -#ifndef YY_NO_UNPUT -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; - { - register char *yy_cp = yy_c_buf_p; + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; + *yy_cp = (yy_hold_char); - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; + register yy_size_t number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - while ( source > yy_current_buffer->yy_ch_buf ) + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); - yy_n_chars = yy_current_buffer->yy_buf_size; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif - -static int input() - { +{ int c; + + *(yy_c_buf_p) = (yy_hold_char); - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ - *yy_c_buf_p = '\0'; + *(yy_c_buf_p) = '\0'; else { /* need more input */ - yytext_ptr = yy_c_buf_p; - ++yy_c_buf_p; + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); - switch ( yy_get_next_buffer() ) + switch ( yy_get_next_buffer( ) ) { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + case EOB_ACT_END_OF_FILE: { - if ( yywrap() ) - { - yy_c_buf_p = - yytext_ptr + YY_MORE_ADJ; + if ( yywrap( ) ) return EOF; - } - if ( ! yy_did_buffer_switch_on_eof ) + if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else return input(); +#endif } case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + (yy_c_buf_p) = (yytext_ptr) + offset; break; - - case EOB_ACT_LAST_MATCH: - YY_FATAL_ERROR( - "unexpected last match in input()" ); } } } - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); - yy_current_buffer->yy_at_bol = (c == '\n'); + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); } + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} -void yyrestart( input_file ) -FILE *input_file; - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; - { - if ( yy_current_buffer == new_buffer ) +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) return; - if ( yy_current_buffer ) + if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } - yy_current_buffer = new_buffer; - yy_load_buffer_state(); + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ - yy_did_buffer_switch_on_eof = 1; - } + (yy_did_buffer_switch_on_eof) = 1; +} +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} -void yy_load_buffer_state() - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; - { +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); @@ -1911,64 +3033,73 @@ int size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; - yy_init_buffer( b, file ); + yy_init_buffer(b,file ); return b; - } +} - -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; - { +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) return; - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) - yy_flex_free( (genericptr_t) b->yy_ch_buf ); + yyfree((void *) b->yy_ch_buf ); - yy_flex_free( (genericptr_t) b ); - } + yyfree((void *) b ); +} +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -extern int FDECL(isatty, (int)); -#endif -#endif - -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; - { - yy_flush_buffer( b ); +{ + int oerrno = errno; + + yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; -#ifdef YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#ifdef YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; - { b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes @@ -1983,24 +3114,203 @@ YY_BUFFER_STATE b; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; - if ( b == yy_current_buffer ) - yy_load_buffer_state(); + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; } + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + yy_size_t i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif -static void yy_fatal_error( msg ) -const char msg[]; - { - (void) fprintf( stderr, "%s\n", msg ); +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); - } - - +} /* Redefine yyless() so it works in section 3 code. */ @@ -2009,61 +3319,196 @@ const char msg[]; do \ { \ /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n - YY_MORE_ADJ; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ } \ while ( 0 ) +/* Accessor methods (get/set functions) to struct members. */ -/* Internal utility routines. */ +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +yy_size_t yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ #ifndef yytext_ptr -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -const char *s2; -int n; - { +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; - } +} #endif +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; -static genericptr_t yy_flex_alloc( size ) -yy_size_t size; - { - return (genericptr_t) alloc((unsigned)size); - } + return n; +} +#endif -/* we want to avoid use of realloc(), so we require that caller supply the - size of the old block of memory */ -static genericptr_t yy_flex_realloc2( ptr, size, old_size ) -genericptr_t ptr; -yy_size_t size; -int old_size; - { - genericptr_t outptr = yy_flex_alloc(size); +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} - if (ptr) { - char *p = (char *) outptr, *q = (char *) ptr; +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} - while (--old_size >= 0) *p++ = *q++; - yy_flex_free(ptr); - } - return outptr; - } +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} -static void yy_flex_free( ptr ) -genericptr_t ptr; - { - free( ptr ); - } +#define YYTABLES_NAME "yytables" + +#line 337 "lev_comp.l" -/*flexhack.skl*/ #ifdef AMIGA long *alloc(n) @@ -2083,6 +3528,7 @@ FILE *input_f; else #endif yyin = input_f; + if (!orig_yyin) orig_yyin = yyin; } /* analogous routine (for completeness) */ void init_yyout( output_f ) @@ -2091,4 +3537,52 @@ FILE *output_f; yyout = output_f; } +long +handle_varstring_check() +{ + struct lc_vardefs *vd; + yylval.map = (char *) alloc(strlen(yytext)+1); + Strcpy(yylval.map, yytext); + if ((vd = vardef_defined(variable_definitions, yytext, 1))) { + long l = vd->var_type; + long a = ((l & SPOVAR_ARRAY) == SPOVAR_ARRAY); + l = (l & ~SPOVAR_ARRAY); + if (l == SPOVAR_INT) return (a ? VARSTRING_INT_ARRAY : VARSTRING_INT); + if (l == SPOVAR_STRING) return (a ? VARSTRING_STRING_ARRAY : VARSTRING_STRING); + if (l == SPOVAR_VARIABLE) return (a ? VARSTRING_VAR_ARRAY : VARSTRING_VAR); + if (l == SPOVAR_COORD) return (a ? VARSTRING_COORD_ARRAY : VARSTRING_COORD); + if (l == SPOVAR_REGION) return (a ? VARSTRING_REGION_ARRAY : VARSTRING_REGION); + if (l == SPOVAR_MAPCHAR) return (a ? VARSTRING_MAPCHAR_ARRAY : VARSTRING_MAPCHAR); + if (l == SPOVAR_MONST) return (a ? VARSTRING_MONST_ARRAY : VARSTRING_MONST); + if (l == SPOVAR_OBJ) return (a ? VARSTRING_OBJ_ARRAY : VARSTRING_OBJ); + if (l == SPOVAR_SEL) return (a ? VARSTRING_SEL_ARRAY : VARSTRING_SEL); + } + return VARSTRING; +} + + +void +newline() +{ + nh_line_number++; + token_start_pos = 0; + memset(curr_token, 0, 512); +} + +void +savetoken(s) +char *s; +{ + sprintf(curr_token, "%s", s); + advancepos(s); +} + +void +advancepos(s) +char *s; +{ + token_start_pos += strlen(s); +} + /*lev_comp.l*/ + diff --git a/sys/share/lev_yacc.c b/sys/share/lev_yacc.c index 02aaf1938..376c48759 100644 --- a/sys/share/lev_yacc.c +++ b/sys/share/lev_yacc.c @@ -1,14 +1,71 @@ -#ifndef lint -static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; -#endif -#define YYBYACC 1 -#define YYMAJOR 1 -#define YYMINOR 9 -#define yyclearin (yychar=(-1)) -#define yyerrok (yyerrflag=0) -#define YYRECOVERING (yyerrflag!=0) -#define YYPREFIX "yy" -/* NetHack 3.5 lev_comp.y $Date: 2009/05/11 22:53:51 $ $Revision: 1.10 $ */ +/* A Bison parser, made by GNU Bison 3.0.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.0.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* Copy the first part of user declarations. */ +#line 1 "lev_comp.y" /* yacc.c:339 */ + +/* NetHack 3.5 lev_comp.y $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 lev_comp.y $Date: 2009/05/06 10:54:31 $ $Revision: 1.8 $ */ /* SCCS Id: @(#)lev_yacc.c 3.5 2007/08/01 */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -34,7 +91,6 @@ static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; #include "hack.h" #include "sp_lev.h" -#define MAX_REGISTERS 10 #define ERR (-1) /* many types of things are put in chars for transference to NetHack. * since some systems will use signed chars, limit everybody to the @@ -42,11 +98,16 @@ static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; */ #define MAX_OF_TYPE 128 +#define MAX_NESTED_IFS 20 +#define MAX_SWITCH_CASES 20 + #define New(type) \ (type *) memset((genericptr_t)alloc(sizeof(type)), 0, sizeof(type)) #define NewTab(type, size) (type **) alloc(sizeof(type *) * size) #define Free(ptr) free((genericptr_t)ptr) +extern void VDECL(lc_error, (const char *, ...)); +extern void VDECL(lc_warning, (const char *, ...)); extern void FDECL(yyerror, (const char *)); extern void FDECL(yywarning, (const char *)); extern int NDECL(yylex); @@ -60,2392 +121,5567 @@ extern int FDECL(get_object_id, (char *,CHAR_P)); extern boolean FDECL(check_monster_char, (CHAR_P)); extern boolean FDECL(check_object_char, (CHAR_P)); extern char FDECL(what_map_char, (CHAR_P)); -extern void FDECL(scan_map, (char *)); -extern void NDECL(wallify_map); -extern boolean NDECL(check_subrooms); -extern void FDECL(check_coord, (int,int,const char *)); -extern void NDECL(store_part); -extern void NDECL(store_room); -extern boolean FDECL(write_level_file, (char *,splev *,specialmaze *)); -extern void FDECL(free_rooms, (splev *)); +extern void FDECL(scan_map, (char *, sp_lev *)); +extern void FDECL(add_opcode, (sp_lev *, int, genericptr_t)); +extern genericptr_t FDECL(get_last_opcode_data1, (sp_lev *, int)); +extern genericptr_t FDECL(get_last_opcode_data2, (sp_lev *, int,int)); +extern boolean FDECL(check_subrooms, (sp_lev *)); +extern boolean FDECL(write_level_file, (char *,sp_lev *)); +extern struct opvar *FDECL(set_opvar_int, (struct opvar *, long)); +extern void VDECL(add_opvars, (sp_lev *, const char *, ...)); +extern void FDECL(start_level_def, (sp_lev * *, char *)); -static struct reg { - int x1, y1; - int x2, y2; -} current_region; +extern struct lc_funcdefs *FDECL(funcdef_new,(long,char *)); +extern void FDECL(funcdef_free_all,(struct lc_funcdefs *)); +extern struct lc_funcdefs *FDECL(funcdef_defined,(struct lc_funcdefs *,char *, int)); +extern char *FDECL(funcdef_paramtypes, (struct lc_funcdefs *)); +extern char *FDECL(decode_parm_str, (char *)); -static struct coord { - int x; - int y; -} current_coord, current_align; +extern struct lc_vardefs *FDECL(vardef_new,(long,char *)); +extern void FDECL(vardef_free_all,(struct lc_vardefs *)); +extern struct lc_vardefs *FDECL(vardef_defined,(struct lc_vardefs *,char *, int)); -static struct size { - int height; - int width; -} current_size; +extern void NDECL(break_stmt_start); +extern void FDECL(break_stmt_end, (sp_lev *)); +extern void FDECL(break_stmt_new, (sp_lev *, long)); -char tmpmessage[256]; -digpos *tmppass[32]; -char *tmpmap[ROWNO]; +extern void FDECL(splev_add_from, (sp_lev *, sp_lev *)); -digpos *tmpdig[MAX_OF_TYPE]; -region *tmpreg[MAX_OF_TYPE]; -lev_region *tmplreg[MAX_OF_TYPE]; -door *tmpdoor[MAX_OF_TYPE]; -drawbridge *tmpdb[MAX_OF_TYPE]; -walk *tmpwalk[MAX_OF_TYPE]; +extern void FDECL(check_vardef_type, (struct lc_vardefs *, char *, long)); +extern void FDECL(vardef_used, (struct lc_vardefs *, char *)); +extern struct lc_vardefs *FDECL(add_vardef_type, (struct lc_vardefs *, char *, long)); -room_door *tmprdoor[MAX_OF_TYPE]; -trap *tmptrap[MAX_OF_TYPE]; -monster *tmpmonst[MAX_OF_TYPE]; -object *tmpobj[MAX_OF_TYPE]; -altar *tmpaltar[MAX_OF_TYPE]; -lad *tmplad[MAX_OF_TYPE]; -stair *tmpstair[MAX_OF_TYPE]; -gold *tmpgold[MAX_OF_TYPE]; -engraving *tmpengraving[MAX_OF_TYPE]; -fountain *tmpfountain[MAX_OF_TYPE]; -sink *tmpsink[MAX_OF_TYPE]; -pool *tmppool[MAX_OF_TYPE]; +extern int FDECL(reverse_jmp_opcode, (int)); -mazepart *tmppart[10]; -room *tmproom[MAXNROFROOMS*2]; -corridor *tmpcor[MAX_OF_TYPE]; +struct coord { + long x; + long y; +}; -static specialmaze maze; -static splev special_lev; -static lev_init init_lev; +struct forloopdef { + char *varname; + long jmp_point; +}; +static struct forloopdef forloop_list[MAX_NESTED_IFS]; +static short n_forloops = 0; -static char olist[MAX_REGISTERS], mlist[MAX_REGISTERS]; -static struct coord plist[MAX_REGISTERS]; -int n_olist = 0, n_mlist = 0, n_plist = 0; +sp_lev *splev = NULL; -unsigned int nlreg = 0, nreg = 0, ndoor = 0, ntrap = 0, nmons = 0, nobj = 0; -unsigned int ndb = 0, nwalk = 0, npart = 0, ndig = 0, nlad = 0, nstair = 0; -unsigned int naltar = 0, ncorridor = 0, nrooms = 0, ngold = 0, nengraving = 0; -unsigned int nfountain = 0, npool = 0, nsink = 0, npass = 0; +static struct opvar *if_list[MAX_NESTED_IFS]; -static int lev_flags = 0; +static short n_if_list = 0; unsigned int max_x_map, max_y_map; +int obj_containment = 0; -static xchar in_room; +int in_container_obj = 0; + +/* integer value is possibly an inconstant value (eg. dice notation or a variable) */ +int is_inconstant_number = 0; + +int in_switch_statement = 0; +static struct opvar *switch_check_jump = NULL; +static struct opvar *switch_default_case = NULL; +static struct opvar *switch_case_list[MAX_SWITCH_CASES]; +static long switch_case_value[MAX_SWITCH_CASES]; +int n_switch_case_list = 0; + +int allow_break_statements = 0; +struct lc_breakdef *break_list = NULL; + +extern struct lc_vardefs *variable_definitions; + + +struct lc_vardefs *function_tmp_var_defs = NULL; +extern struct lc_funcdefs *function_definitions; +struct lc_funcdefs *curr_function = NULL; +struct lc_funcdefs_parm * curr_function_param = NULL; +int in_function_definition = 0; +sp_lev *function_splev_backup = NULL; extern int fatal_error; -extern int want_warnings; +extern int got_errors; +extern int line_number; extern const char *fname; -typedef union +extern char curr_token[512]; + + +#line 212 "y.tab.c" /* yacc.c:339 */ + +# ifndef YY_NULLPTR +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef YY_YY_Y_TAB_H_INCLUDED +# define YY_YY_Y_TAB_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + CHAR = 258, + INTEGER = 259, + BOOLEAN = 260, + PERCENT = 261, + SPERCENT = 262, + MINUS_INTEGER = 263, + PLUS_INTEGER = 264, + MAZE_GRID_ID = 265, + SOLID_FILL_ID = 266, + MINES_ID = 267, + ROGUELEV_ID = 268, + MESSAGE_ID = 269, + MAZE_ID = 270, + LEVEL_ID = 271, + LEV_INIT_ID = 272, + GEOMETRY_ID = 273, + NOMAP_ID = 274, + OBJECT_ID = 275, + COBJECT_ID = 276, + MONSTER_ID = 277, + TRAP_ID = 278, + DOOR_ID = 279, + DRAWBRIDGE_ID = 280, + object_ID = 281, + monster_ID = 282, + terrain_ID = 283, + MAZEWALK_ID = 284, + WALLIFY_ID = 285, + REGION_ID = 286, + FILLING = 287, + IRREGULAR = 288, + JOINED = 289, + ALTAR_ID = 290, + LADDER_ID = 291, + STAIR_ID = 292, + NON_DIGGABLE_ID = 293, + NON_PASSWALL_ID = 294, + ROOM_ID = 295, + PORTAL_ID = 296, + TELEPRT_ID = 297, + BRANCH_ID = 298, + LEV = 299, + MINERALIZE_ID = 300, + CORRIDOR_ID = 301, + GOLD_ID = 302, + ENGRAVING_ID = 303, + FOUNTAIN_ID = 304, + POOL_ID = 305, + SINK_ID = 306, + NONE = 307, + RAND_CORRIDOR_ID = 308, + DOOR_STATE = 309, + LIGHT_STATE = 310, + CURSE_TYPE = 311, + ENGRAVING_TYPE = 312, + DIRECTION = 313, + RANDOM_TYPE = 314, + RANDOM_TYPE_BRACKET = 315, + A_REGISTER = 316, + ALIGNMENT = 317, + LEFT_OR_RIGHT = 318, + CENTER = 319, + TOP_OR_BOT = 320, + ALTAR_TYPE = 321, + UP_OR_DOWN = 322, + SUBROOM_ID = 323, + NAME_ID = 324, + FLAGS_ID = 325, + FLAG_TYPE = 326, + MON_ATTITUDE = 327, + MON_ALERTNESS = 328, + MON_APPEARANCE = 329, + ROOMDOOR_ID = 330, + IF_ID = 331, + ELSE_ID = 332, + TERRAIN_ID = 333, + HORIZ_OR_VERT = 334, + REPLACE_TERRAIN_ID = 335, + EXIT_ID = 336, + SHUFFLE_ID = 337, + QUANTITY_ID = 338, + BURIED_ID = 339, + LOOP_ID = 340, + FOR_ID = 341, + TO_ID = 342, + SWITCH_ID = 343, + CASE_ID = 344, + BREAK_ID = 345, + DEFAULT_ID = 346, + ERODED_ID = 347, + TRAPPED_ID = 348, + RECHARGED_ID = 349, + INVIS_ID = 350, + GREASED_ID = 351, + FEMALE_ID = 352, + CANCELLED_ID = 353, + REVIVED_ID = 354, + AVENGE_ID = 355, + FLEEING_ID = 356, + BLINDED_ID = 357, + PARALYZED_ID = 358, + STUNNED_ID = 359, + CONFUSED_ID = 360, + SEENTRAPS_ID = 361, + ALL_ID = 362, + MONTYPE_ID = 363, + GRAVE_ID = 364, + ERODEPROOF_ID = 365, + FUNCTION_ID = 366, + MSG_OUTPUT_TYPE = 367, + COMPARE_TYPE = 368, + UNKNOWN_TYPE = 369, + rect_ID = 370, + fillrect_ID = 371, + line_ID = 372, + randline_ID = 373, + grow_ID = 374, + selection_ID = 375, + flood_ID = 376, + rndcoord_ID = 377, + circle_ID = 378, + ellipse_ID = 379, + filter_ID = 380, + complement_ID = 381, + gradient_ID = 382, + GRADIENT_TYPE = 383, + LIMITED = 384, + HUMIDITY_TYPE = 385, + STRING = 386, + MAP_ID = 387, + NQSTRING = 388, + VARSTRING = 389, + CFUNC = 390, + CFUNC_INT = 391, + CFUNC_STR = 392, + CFUNC_COORD = 393, + CFUNC_REGION = 394, + VARSTRING_INT = 395, + VARSTRING_INT_ARRAY = 396, + VARSTRING_STRING = 397, + VARSTRING_STRING_ARRAY = 398, + VARSTRING_VAR = 399, + VARSTRING_VAR_ARRAY = 400, + VARSTRING_COORD = 401, + VARSTRING_COORD_ARRAY = 402, + VARSTRING_REGION = 403, + VARSTRING_REGION_ARRAY = 404, + VARSTRING_MAPCHAR = 405, + VARSTRING_MAPCHAR_ARRAY = 406, + VARSTRING_MONST = 407, + VARSTRING_MONST_ARRAY = 408, + VARSTRING_OBJ = 409, + VARSTRING_OBJ_ARRAY = 410, + VARSTRING_SEL = 411, + VARSTRING_SEL_ARRAY = 412, + METHOD_INT = 413, + METHOD_INT_ARRAY = 414, + METHOD_STRING = 415, + METHOD_STRING_ARRAY = 416, + METHOD_VAR = 417, + METHOD_VAR_ARRAY = 418, + METHOD_COORD = 419, + METHOD_COORD_ARRAY = 420, + METHOD_REGION = 421, + METHOD_REGION_ARRAY = 422, + METHOD_MAPCHAR = 423, + METHOD_MAPCHAR_ARRAY = 424, + METHOD_MONST = 425, + METHOD_MONST_ARRAY = 426, + METHOD_OBJ = 427, + METHOD_OBJ_ARRAY = 428, + METHOD_SEL = 429, + METHOD_SEL_ARRAY = 430, + DICE = 431 + }; +#endif +/* Tokens. */ +#define CHAR 258 +#define INTEGER 259 +#define BOOLEAN 260 +#define PERCENT 261 +#define SPERCENT 262 +#define MINUS_INTEGER 263 +#define PLUS_INTEGER 264 +#define MAZE_GRID_ID 265 +#define SOLID_FILL_ID 266 +#define MINES_ID 267 +#define ROGUELEV_ID 268 +#define MESSAGE_ID 269 +#define MAZE_ID 270 +#define LEVEL_ID 271 +#define LEV_INIT_ID 272 +#define GEOMETRY_ID 273 +#define NOMAP_ID 274 +#define OBJECT_ID 275 +#define COBJECT_ID 276 +#define MONSTER_ID 277 +#define TRAP_ID 278 +#define DOOR_ID 279 +#define DRAWBRIDGE_ID 280 +#define object_ID 281 +#define monster_ID 282 +#define terrain_ID 283 +#define MAZEWALK_ID 284 +#define WALLIFY_ID 285 +#define REGION_ID 286 +#define FILLING 287 +#define IRREGULAR 288 +#define JOINED 289 +#define ALTAR_ID 290 +#define LADDER_ID 291 +#define STAIR_ID 292 +#define NON_DIGGABLE_ID 293 +#define NON_PASSWALL_ID 294 +#define ROOM_ID 295 +#define PORTAL_ID 296 +#define TELEPRT_ID 297 +#define BRANCH_ID 298 +#define LEV 299 +#define MINERALIZE_ID 300 +#define CORRIDOR_ID 301 +#define GOLD_ID 302 +#define ENGRAVING_ID 303 +#define FOUNTAIN_ID 304 +#define POOL_ID 305 +#define SINK_ID 306 +#define NONE 307 +#define RAND_CORRIDOR_ID 308 +#define DOOR_STATE 309 +#define LIGHT_STATE 310 +#define CURSE_TYPE 311 +#define ENGRAVING_TYPE 312 +#define DIRECTION 313 +#define RANDOM_TYPE 314 +#define RANDOM_TYPE_BRACKET 315 +#define A_REGISTER 316 +#define ALIGNMENT 317 +#define LEFT_OR_RIGHT 318 +#define CENTER 319 +#define TOP_OR_BOT 320 +#define ALTAR_TYPE 321 +#define UP_OR_DOWN 322 +#define SUBROOM_ID 323 +#define NAME_ID 324 +#define FLAGS_ID 325 +#define FLAG_TYPE 326 +#define MON_ATTITUDE 327 +#define MON_ALERTNESS 328 +#define MON_APPEARANCE 329 +#define ROOMDOOR_ID 330 +#define IF_ID 331 +#define ELSE_ID 332 +#define TERRAIN_ID 333 +#define HORIZ_OR_VERT 334 +#define REPLACE_TERRAIN_ID 335 +#define EXIT_ID 336 +#define SHUFFLE_ID 337 +#define QUANTITY_ID 338 +#define BURIED_ID 339 +#define LOOP_ID 340 +#define FOR_ID 341 +#define TO_ID 342 +#define SWITCH_ID 343 +#define CASE_ID 344 +#define BREAK_ID 345 +#define DEFAULT_ID 346 +#define ERODED_ID 347 +#define TRAPPED_ID 348 +#define RECHARGED_ID 349 +#define INVIS_ID 350 +#define GREASED_ID 351 +#define FEMALE_ID 352 +#define CANCELLED_ID 353 +#define REVIVED_ID 354 +#define AVENGE_ID 355 +#define FLEEING_ID 356 +#define BLINDED_ID 357 +#define PARALYZED_ID 358 +#define STUNNED_ID 359 +#define CONFUSED_ID 360 +#define SEENTRAPS_ID 361 +#define ALL_ID 362 +#define MONTYPE_ID 363 +#define GRAVE_ID 364 +#define ERODEPROOF_ID 365 +#define FUNCTION_ID 366 +#define MSG_OUTPUT_TYPE 367 +#define COMPARE_TYPE 368 +#define UNKNOWN_TYPE 369 +#define rect_ID 370 +#define fillrect_ID 371 +#define line_ID 372 +#define randline_ID 373 +#define grow_ID 374 +#define selection_ID 375 +#define flood_ID 376 +#define rndcoord_ID 377 +#define circle_ID 378 +#define ellipse_ID 379 +#define filter_ID 380 +#define complement_ID 381 +#define gradient_ID 382 +#define GRADIENT_TYPE 383 +#define LIMITED 384 +#define HUMIDITY_TYPE 385 +#define STRING 386 +#define MAP_ID 387 +#define NQSTRING 388 +#define VARSTRING 389 +#define CFUNC 390 +#define CFUNC_INT 391 +#define CFUNC_STR 392 +#define CFUNC_COORD 393 +#define CFUNC_REGION 394 +#define VARSTRING_INT 395 +#define VARSTRING_INT_ARRAY 396 +#define VARSTRING_STRING 397 +#define VARSTRING_STRING_ARRAY 398 +#define VARSTRING_VAR 399 +#define VARSTRING_VAR_ARRAY 400 +#define VARSTRING_COORD 401 +#define VARSTRING_COORD_ARRAY 402 +#define VARSTRING_REGION 403 +#define VARSTRING_REGION_ARRAY 404 +#define VARSTRING_MAPCHAR 405 +#define VARSTRING_MAPCHAR_ARRAY 406 +#define VARSTRING_MONST 407 +#define VARSTRING_MONST_ARRAY 408 +#define VARSTRING_OBJ 409 +#define VARSTRING_OBJ_ARRAY 410 +#define VARSTRING_SEL 411 +#define VARSTRING_SEL_ARRAY 412 +#define METHOD_INT 413 +#define METHOD_INT_ARRAY 414 +#define METHOD_STRING 415 +#define METHOD_STRING_ARRAY 416 +#define METHOD_VAR 417 +#define METHOD_VAR_ARRAY 418 +#define METHOD_COORD 419 +#define METHOD_COORD_ARRAY 420 +#define METHOD_REGION 421 +#define METHOD_REGION_ARRAY 422 +#define METHOD_MAPCHAR 423 +#define METHOD_MAPCHAR_ARRAY 424 +#define METHOD_MONST 425 +#define METHOD_MONST_ARRAY 426 +#define METHOD_OBJ 427 +#define METHOD_OBJ_ARRAY 428 +#define METHOD_SEL 429 +#define METHOD_SEL_ARRAY 430 +#define DICE 431 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE YYSTYPE; +union YYSTYPE { - int i; +#line 148 "lev_comp.y" /* yacc.c:355 */ + + long i; char* map; struct { - xchar room; - xchar wall; - xchar door; + long room; + long wall; + long door; } corpos; -} YYSTYPE; -#define CHAR 257 -#define INTEGER 258 -#define BOOLEAN 259 -#define PERCENT 260 -#define MESSAGE_ID 261 -#define MAZE_ID 262 -#define LEVEL_ID 263 -#define LEV_INIT_ID 264 -#define GEOMETRY_ID 265 -#define NOMAP_ID 266 -#define OBJECT_ID 267 -#define COBJECT_ID 268 -#define MONSTER_ID 269 -#define TRAP_ID 270 -#define DOOR_ID 271 -#define DRAWBRIDGE_ID 272 -#define MAZEWALK_ID 273 -#define WALLIFY_ID 274 -#define REGION_ID 275 -#define FILLING 276 -#define RANDOM_OBJECTS_ID 277 -#define RANDOM_MONSTERS_ID 278 -#define RANDOM_PLACES_ID 279 -#define ALTAR_ID 280 -#define LADDER_ID 281 -#define STAIR_ID 282 -#define NON_DIGGABLE_ID 283 -#define NON_PASSWALL_ID 284 -#define ROOM_ID 285 -#define PORTAL_ID 286 -#define TELEPRT_ID 287 -#define BRANCH_ID 288 -#define LEV 289 -#define CHANCE_ID 290 -#define CORRIDOR_ID 291 -#define GOLD_ID 292 -#define ENGRAVING_ID 293 -#define FOUNTAIN_ID 294 -#define POOL_ID 295 -#define SINK_ID 296 -#define NONE 297 -#define RAND_CORRIDOR_ID 298 -#define DOOR_STATE 299 -#define LIGHT_STATE 300 -#define CURSE_TYPE 301 -#define ENGRAVING_TYPE 302 -#define DIRECTION 303 -#define RANDOM_TYPE 304 -#define O_REGISTER 305 -#define M_REGISTER 306 -#define P_REGISTER 307 -#define A_REGISTER 308 -#define ALIGNMENT 309 -#define LEFT_OR_RIGHT 310 -#define CENTER 311 -#define TOP_OR_BOT 312 -#define ALTAR_TYPE 313 -#define UP_OR_DOWN 314 -#define SUBROOM_ID 315 -#define NAME_ID 316 -#define FLAGS_ID 317 -#define FLAG_TYPE 318 -#define MON_ATTITUDE 319 -#define MON_ALERTNESS 320 -#define MON_APPEARANCE 321 -#define CONTAINED 322 -#define STRING 323 -#define MAP_ID 324 -#define YYERRCODE 256 -short yylhs[] = { -1, - 0, 0, 36, 36, 37, 37, 38, 39, 32, 23, - 23, 23, 14, 14, 19, 19, 20, 20, 40, 40, - 45, 42, 42, 46, 46, 43, 43, 49, 49, 44, - 44, 51, 52, 52, 53, 53, 35, 50, 50, 56, - 54, 10, 10, 59, 59, 57, 57, 60, 60, 58, - 58, 55, 55, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 62, 63, 64, 15, - 15, 13, 13, 12, 12, 31, 11, 11, 41, 41, - 75, 76, 76, 79, 1, 1, 2, 2, 77, 77, - 80, 80, 80, 47, 47, 48, 48, 81, 83, 81, - 78, 78, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 99, 65, 98, 98, 100, 100, 100, 100, - 100, 66, 66, 102, 101, 103, 103, 104, 104, 104, - 104, 105, 105, 106, 107, 107, 108, 108, 108, 85, - 67, 86, 92, 93, 94, 74, 109, 88, 110, 89, - 111, 113, 90, 114, 91, 112, 112, 22, 22, 69, - 70, 71, 95, 96, 87, 68, 72, 73, 25, 25, - 25, 28, 28, 28, 33, 33, 34, 34, 3, 3, - 4, 4, 21, 21, 21, 97, 97, 97, 5, 5, - 6, 6, 7, 7, 7, 8, 8, 117, 29, 26, - 9, 82, 24, 27, 30, 16, 16, 17, 17, 18, - 18, 116, 115, + struct { + long area; + long x1; + long y1; + long x2; + long y2; + } lregn; + struct { + long x; + long y; + } crd; + struct { + long ter; + long lit; + } terr; + struct { + long height; + long width; + } sze; + struct { + long die; + long num; + } dice; + struct { + long cfunc; + char *varstr; + } meth; + +#line 641 "y.tab.c" /* yacc.c:355 */ }; -short yylen[] = { 2, - 0, 1, 1, 2, 1, 1, 5, 7, 3, 0, - 13, 15, 1, 1, 0, 3, 3, 1, 0, 2, - 3, 0, 2, 3, 3, 0, 1, 1, 2, 1, - 1, 1, 0, 2, 5, 5, 7, 2, 2, 12, - 12, 0, 2, 5, 1, 5, 1, 5, 1, 5, - 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 3, 9, 1, - 1, 1, 1, 1, 1, 5, 1, 1, 1, 2, - 3, 1, 2, 5, 1, 1, 1, 1, 0, 2, - 3, 3, 3, 1, 3, 1, 3, 1, 0, 4, - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 10, 0, 2, 2, 2, 2, 2, - 3, 2, 2, 0, 9, 1, 1, 0, 7, 5, - 5, 1, 1, 1, 1, 1, 0, 2, 2, 5, - 6, 7, 5, 1, 5, 5, 0, 8, 0, 8, - 0, 0, 8, 0, 6, 0, 2, 1, 10, 3, - 3, 3, 3, 3, 8, 7, 5, 7, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 2, 4, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, - 4, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 1, 5, 9, -}; -short yydefred[] = { 0, - 0, 0, 0, 0, 0, 2, 0, 5, 6, 0, - 0, 0, 0, 0, 4, 215, 0, 9, 0, 0, - 0, 0, 0, 0, 16, 0, 0, 0, 0, 22, - 77, 78, 76, 0, 0, 0, 0, 82, 7, 0, - 89, 0, 20, 0, 17, 0, 21, 0, 80, 0, - 83, 0, 0, 0, 0, 0, 23, 27, 0, 52, - 52, 0, 85, 86, 0, 0, 0, 0, 0, 90, - 0, 0, 0, 0, 32, 8, 30, 0, 29, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 103, 104, 106, 113, - 114, 119, 120, 118, 102, 105, 107, 108, 109, 110, - 111, 112, 115, 116, 117, 121, 122, 214, 0, 24, - 213, 0, 25, 192, 0, 191, 0, 0, 34, 0, - 0, 0, 0, 0, 0, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 0, - 88, 87, 84, 91, 93, 0, 92, 0, 212, 219, - 0, 132, 133, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 199, 200, 0, - 198, 0, 0, 196, 197, 0, 0, 0, 0, 0, - 0, 0, 157, 0, 168, 173, 174, 159, 161, 164, - 216, 217, 0, 0, 170, 95, 97, 201, 202, 0, - 0, 0, 0, 70, 71, 0, 68, 172, 171, 67, - 0, 0, 0, 183, 0, 182, 0, 184, 180, 0, - 179, 0, 181, 190, 0, 189, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 100, 0, 0, 0, 0, 0, 150, 0, 0, 153, - 0, 0, 205, 0, 203, 0, 204, 155, 0, 0, - 0, 156, 0, 0, 0, 177, 220, 221, 0, 45, - 0, 0, 47, 0, 0, 0, 36, 35, 0, 0, - 222, 0, 188, 187, 134, 0, 186, 185, 0, 151, - 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 162, 165, 0, 0, 0, 0, 0, 0, 0, 0, - 209, 0, 210, 0, 152, 0, 0, 0, 207, 206, - 176, 0, 0, 0, 0, 178, 0, 49, 0, 0, - 0, 51, 0, 0, 0, 72, 73, 0, 13, 14, - 0, 0, 123, 0, 0, 175, 211, 0, 158, 160, - 0, 163, 0, 0, 0, 0, 0, 0, 74, 75, - 0, 0, 0, 137, 136, 0, 125, 0, 0, 0, - 167, 44, 0, 0, 46, 0, 0, 37, 69, 12, - 0, 135, 0, 0, 0, 0, 0, 0, 41, 0, - 40, 143, 142, 144, 0, 0, 0, 126, 223, 195, - 0, 48, 43, 50, 0, 0, 128, 129, 0, 130, - 127, 169, 146, 145, 0, 0, 0, 131, 0, 0, - 140, 141, 0, 148, 149, 139, -}; -short yydgoto[] = { 3, - 65, 163, 265, 135, 210, 240, 306, 371, 307, 439, - 33, 411, 388, 391, 246, 233, 171, 319, 13, 25, - 396, 223, 21, 132, 262, 263, 129, 257, 258, 136, - 4, 5, 339, 335, 243, 6, 7, 8, 9, 28, - 39, 44, 56, 76, 29, 57, 130, 133, 58, 59, - 77, 78, 139, 60, 80, 61, 325, 384, 322, 380, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 40, 41, 50, 69, 42, 70, - 167, 168, 204, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 224, 433, 417, 448, - 172, 362, 416, 432, 445, 446, 466, 471, 277, 279, - 280, 402, 375, 281, 225, 214, 215, -}; -short yysindex[] = { -149, - -5, 1, 0, -269, -269, 0, -149, 0, 0, -242, - -242, 12, -154, -154, 0, 0, 50, 0, -200, 41, - -137, -137, -232, 103, 0, -103, 99, -132, -137, 0, - 0, 0, 0, -200, 126, -141, 128, 0, 0, -132, - 0, -136, 0, -251, 0, -68, 0, -158, 0, -139, - 0, 129, 132, 134, 135, -100, 0, 0, -253, 0, - 0, 151, 0, 0, 155, 144, 146, 147, -109, 0, - -51, -50, -260, -260, 0, 0, 0, -83, 0, -165, - -165, -49, -162, -51, -50, 174, -44, -44, -44, -44, - 159, 160, 161, 0, 162, 163, 166, 167, 168, 170, - 171, 172, 173, 175, 176, 177, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, - 0, 183, 0, 0, 188, 0, 192, 179, 0, 180, - 181, 182, 185, 186, 187, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, - 0, 0, 0, 0, 0, -12, 0, 0, 0, 0, - 189, 0, 0, 190, 191, -212, 46, 46, 210, 46, - 46, 58, 210, 210, -37, -37, -37, -230, 46, 46, - -51, -50, -193, -193, 211, -237, 46, -4, 46, 46, - -242, -6, 212, 213, -221, -233, -258, 0, 0, 214, - 0, 164, 215, 0, 0, 216, 3, 218, 219, 226, - 267, 96, 0, 312, 0, 0, 0, 0, 0, 0, - 0, 0, 313, 317, 0, 0, 0, 0, 0, 319, - 322, 110, 325, 0, 0, 326, 0, 0, 0, 0, - 329, 130, 174, 0, 296, 0, 365, 0, 0, 321, - 0, 369, 0, 0, 376, 0, 46, 178, 119, 120, - 383, -193, -208, 115, 193, 403, 404, 136, 409, 410, - 411, 46, -161, -1, 28, 412, -35, -212, -193, 416, - 0, 194, -257, 200, -228, 46, 0, 366, 417, 0, - 202, 418, 0, 388, 0, 423, 0, 0, 448, 235, - -37, 0, -37, -37, -37, 0, 0, 0, 454, 0, - 241, 456, 0, 244, 459, 228, 0, 0, 488, 493, - 0, 449, 0, 0, 0, 458, 0, 0, 494, 0, - 0, -212, 497, -260, 291, -259, 294, 49, 509, 510, - 0, 0, -242, 511, 40, 512, 42, 514, -148, -219, - 0, 517, 0, 46, 0, 304, 519, 471, 0, 0, - 0, 521, 252, -242, 524, 0, 311, 0, -158, 526, - 316, 0, 318, 527, -227, 0, 0, 531, 0, 0, - 533, 38, 0, 534, 303, 0, 0, 323, 0, 0, - 268, 0, 542, 540, 42, 544, 543, -242, 0, 0, - 545, -227, 330, 0, 0, 546, 0, 333, 548, 549, - 0, 0, -162, 550, 0, 337, 550, 0, 0, 0, - -263, 0, 552, 547, 339, 341, 559, 345, 0, 567, - 0, 0, 0, 0, 565, 570, -108, 0, 0, 0, - 574, 0, 0, 0, -235, -225, 0, 0, -242, 0, - 0, 0, 0, 0, 575, 576, 576, 0, -225, -262, - 0, 0, 576, 0, 0, 0, -}; -short yyrindex[] = { 616, - 0, 0, 0, -129, 349, 0, 621, 0, 0, 0, - 0, 0, -210, 406, 0, 0, 0, 0, 0, 0, - -98, 408, 0, 282, 0, 0, 0, 0, 367, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 57, 0, 0, 0, 0, 0, 539, - 0, 0, 0, 0, 0, 4, 0, 0, 123, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 169, 0, - 0, 0, 0, 0, 0, 0, 0, 89, 0, 426, - 445, 0, 0, 0, 0, 0, 564, 564, 564, 564, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, - 0, 242, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 506, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 572, 0, 0, 0, - 0, 0, 0, 0, 607, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 0, 0, 641, 0, - 0, 0, 0, 148, 0, 0, 148, 0, 0, 0, - 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 109, 0, 0, 0, - 0, 0, 109, 0, 0, 0, -}; -short yygindex[] = { 0, - 245, 205, 0, -60, -267, -181, 195, 0, 0, 196, - 0, 223, 0, 0, 0, 0, 91, 0, 631, 603, - 0, -169, 625, 437, 0, 0, 441, 0, 0, -10, - 0, 0, 0, 0, 361, 642, 0, 0, 0, 20, - 610, 0, 0, 0, 0, 0, -72, -70, 592, 0, - 0, 0, 0, 0, 593, 0, 0, 248, 0, 0, - 0, 0, 0, 0, 587, 588, 590, 591, 594, 0, - 0, 597, 604, 605, 0, 0, 0, 0, 0, 0, - 419, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -170, 0, 0, 0, - 573, 0, 0, 0, 0, 207, -419, -415, 0, 0, - 0, 0, 0, 0, -63, -77, 0, -}; -#define YYTABLESIZE 935 -short yytable[] = { 17, - 18, 79, 217, 33, 242, 138, 213, 216, 169, 219, - 220, 164, 241, 137, 165, 228, 229, 230, 234, 235, - 329, 244, 463, 131, 31, 52, 53, 231, 248, 249, - 409, 54, 463, 54, 474, 128, 467, 442, 321, 389, - 443, 30, 124, 134, 369, 264, 333, 12, 43, 473, - 10, 472, 10, 370, 10, 10, 26, 476, 11, 444, - 475, 55, 16, 55, 16, 16, 245, 324, 464, 19, - 259, 32, 260, 232, 365, 337, 410, 166, 464, 379, - 16, 383, 254, 255, 390, 166, 208, 444, 31, 331, - 302, 209, 366, 23, 16, 303, 297, 222, 26, 304, - 305, 87, 88, 89, 90, 140, 238, 330, 147, 20, - 239, 316, 1, 2, 96, 218, 141, 24, 236, 226, - 227, 237, 28, 27, 142, 340, 104, 105, 106, 143, - 144, 15, 37, 38, 15, 15, 15, 66, 67, 68, - 317, 349, 318, 350, 351, 352, 34, 42, 161, 162, - 145, 63, 64, 35, 386, 387, 36, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 19, 19, 81, 46, - 96, 97, 98, 99, 100, 169, 101, 102, 103, 174, - 175, 47, 104, 105, 106, 48, 71, 51, 62, 72, - 250, 73, 74, 393, 82, 303, 266, 75, 83, 304, - 305, 84, 94, 85, 86, 128, 131, 138, 191, 160, - 457, 458, 459, 166, 16, 170, 176, 177, 178, 179, - 180, 415, 327, 181, 182, 183, 192, 184, 185, 186, - 187, 193, 188, 189, 190, 194, 195, 196, 197, 198, - 202, 96, 199, 200, 201, 203, 205, 206, 207, 217, - 242, 221, 251, 247, 268, 252, 253, 267, 269, 270, - 271, 272, 273, 79, 79, 33, 33, 138, 138, 274, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 18, 334, 367, 338, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 33, 138, 138, 138, 138, 138, - 138, 138, 320, 138, 124, 124, 275, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 26, 26, - 138, 138, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 323, 124, 124, 124, 124, 124, 124, 124, 11, - 124, 211, 376, 378, 212, 382, 221, 26, 15, 211, - 31, 31, 212, 276, 26, 278, 282, 124, 124, 414, - 283, 211, 284, 400, 212, 285, 19, 286, 287, 288, - 147, 147, 289, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 28, 28, 292, 290, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 427, 147, 147, - 147, 147, 147, 147, 147, 10, 147, 19, 293, 42, - 42, 294, 295, 28, 42, 42, 42, 42, 42, 296, - 28, 299, 300, 147, 147, 38, 301, 42, 308, 42, - 81, 81, 42, 81, 81, 298, 461, 42, 42, 42, - 42, 42, 42, 42, 39, 42, 310, 311, 468, 312, - 309, 332, 313, 314, 315, 326, 331, 336, 341, 343, - 342, 344, 42, 42, 94, 94, 346, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 345, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 347, 348, 94, 94, 94, 94, 353, 354, 355, - 94, 356, 357, 96, 96, 98, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 94, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 358, 359, 96, 96, 96, 96, 360, 364, 101, 96, - 366, 361, 18, 18, 18, 18, 18, 18, 368, 99, - 363, 372, 373, 374, 377, 381, 96, 385, 18, 18, - 392, 394, 395, 397, 398, 399, 18, 401, 403, 405, - 408, 193, 18, 406, 412, 407, 413, 418, 419, 18, - 420, 421, 422, 423, 425, 428, 426, 449, 430, 431, - 434, 435, 436, 438, 440, 447, 18, 450, 451, 452, - 11, 11, 11, 453, 11, 11, 166, 454, 455, 15, - 15, 15, 15, 456, 462, 1, 11, 11, 469, 470, - 3, 218, 441, 404, 11, 15, 15, 437, 19, 19, - 11, 19, 19, 15, 429, 14, 45, 11, 22, 15, - 194, 460, 261, 19, 19, 256, 15, 328, 15, 49, - 79, 19, 424, 81, 11, 107, 108, 19, 109, 110, - 173, 465, 111, 15, 19, 112, 10, 10, 10, 19, - 19, 291, 113, 114, 0, 0, 0, 0, 0, 0, - 0, 19, 10, 10, 19, 19, 0, 38, 38, 0, - 10, 0, 19, 0, 0, 0, 10, 0, 19, 0, - 0, 0, 0, 10, 0, 19, 39, 39, 0, 0, - 38, 0, 0, 0, 0, 0, 38, 0, 0, 0, - 10, 0, 19, 38, 0, 0, 0, 0, 0, 39, - 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, - 38, 0, 39, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, - 0, 0, 0, 0, 0, 0, 0, 98, 98, 0, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 0, 98, 98, 98, 98, 98, 98, 98, 98, - 0, 98, 98, 98, 0, 0, 0, 98, 98, 98, - 101, 101, 0, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 0, 0, 0, 0, 101, 101, - 101, 101, 101, 0, 101, 101, 101, 0, 0, 0, - 101, 101, 101, 193, 193, 0, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 0, 0, 0, - 0, 193, 193, 193, 193, 193, 0, 193, 193, 193, - 0, 0, 0, 193, 193, 193, 0, 0, 166, 166, - 0, 166, 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 0, 0, 0, 0, 166, 166, 166, 166, - 166, 0, 166, 166, 166, 0, 0, 0, 166, 166, - 166, 0, 194, 194, 0, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 0, 0, 0, 0, - 194, 194, 194, 194, 194, 0, 194, 194, 194, 0, - 0, 0, 194, 194, 194, -}; -short yycheck[] = { 10, - 11, 0, 40, 0, 40, 0, 177, 178, 86, 180, - 181, 84, 194, 74, 85, 185, 186, 187, 189, 190, - 288, 259, 258, 257, 257, 277, 278, 258, 199, 200, - 258, 285, 258, 285, 297, 257, 456, 301, 40, 259, - 304, 22, 0, 304, 304, 304, 304, 317, 29, 469, - 261, 467, 58, 313, 265, 266, 0, 473, 58, 323, - 323, 315, 323, 315, 323, 323, 304, 40, 304, 58, - 304, 304, 306, 304, 342, 304, 304, 40, 304, 40, - 323, 40, 304, 305, 304, 40, 299, 323, 0, 41, - 272, 304, 44, 44, 323, 304, 267, 40, 58, 308, - 309, 267, 268, 269, 270, 271, 300, 289, 0, 264, - 304, 282, 262, 263, 280, 179, 282, 318, 191, 183, - 184, 192, 0, 261, 290, 296, 292, 293, 294, 295, - 296, 261, 265, 266, 264, 265, 266, 277, 278, 279, - 302, 311, 304, 313, 314, 315, 44, 0, 311, 312, - 316, 310, 311, 257, 303, 304, 58, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 265, 266, 0, 44, - 280, 281, 282, 283, 284, 253, 286, 287, 288, 89, - 90, 323, 292, 293, 294, 58, 58, 324, 257, 58, - 201, 58, 58, 364, 44, 304, 207, 298, 44, 308, - 309, 58, 0, 58, 58, 257, 257, 291, 44, 259, - 319, 320, 321, 40, 323, 260, 58, 58, 58, 58, - 58, 392, 258, 58, 58, 58, 44, 58, 58, 58, - 58, 44, 58, 58, 58, 44, 58, 58, 58, 58, - 44, 0, 58, 58, 58, 258, 58, 58, 58, 40, - 40, 289, 259, 258, 91, 44, 44, 44, 44, 44, - 258, 44, 44, 262, 263, 262, 263, 262, 263, 44, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 0, 293, 344, 295, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 291, 290, 291, 292, 293, 294, - 295, 296, 304, 298, 262, 263, 40, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 262, 263, - 315, 316, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 304, 290, 291, 292, 293, 294, 295, 296, 0, - 298, 304, 353, 304, 307, 304, 289, 291, 0, 304, - 262, 263, 307, 258, 298, 44, 44, 315, 316, 322, - 44, 304, 44, 374, 307, 44, 0, 258, 44, 44, - 262, 263, 44, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 262, 263, 91, 258, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 408, 290, 291, - 292, 293, 294, 295, 296, 0, 298, 0, 44, 262, - 263, 91, 44, 291, 267, 268, 269, 270, 271, 44, - 298, 303, 303, 315, 316, 0, 44, 280, 314, 282, - 262, 263, 285, 265, 266, 258, 447, 290, 291, 292, - 293, 294, 295, 296, 0, 298, 44, 44, 459, 314, - 258, 258, 44, 44, 44, 44, 41, 258, 93, 258, - 44, 44, 315, 316, 262, 263, 44, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 91, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 44, 258, 291, 292, 293, 294, 44, 258, 44, - 298, 258, 44, 262, 263, 0, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 315, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 303, 44, 291, 292, 293, 294, 44, 44, 0, 298, - 44, 93, 261, 262, 263, 264, 265, 266, 258, 44, - 93, 258, 44, 44, 44, 44, 315, 44, 277, 278, - 44, 258, 44, 93, 44, 314, 285, 44, 258, 44, - 44, 0, 291, 258, 44, 258, 44, 44, 276, 298, - 258, 314, 41, 44, 41, 41, 44, 41, 259, 44, - 258, 44, 44, 44, 258, 44, 315, 259, 258, 41, - 261, 262, 263, 259, 265, 266, 0, 41, 44, 261, - 262, 263, 264, 44, 41, 0, 277, 278, 44, 44, - 0, 58, 427, 379, 285, 277, 278, 423, 262, 263, - 291, 265, 266, 285, 412, 5, 34, 298, 14, 291, - 0, 447, 206, 277, 278, 205, 298, 287, 7, 40, - 59, 285, 405, 61, 315, 69, 69, 291, 69, 69, - 88, 455, 69, 315, 298, 69, 261, 262, 263, 262, - 263, 253, 69, 69, -1, -1, -1, -1, -1, -1, - -1, 315, 277, 278, 277, 278, -1, 262, 263, -1, - 285, -1, 285, -1, -1, -1, 291, -1, 291, -1, - -1, -1, -1, 298, -1, 298, 262, 263, -1, -1, - 285, -1, -1, -1, -1, -1, 291, -1, -1, -1, - 315, -1, 315, 298, -1, -1, -1, -1, -1, 285, - -1, -1, -1, -1, -1, 291, -1, -1, -1, -1, - 315, -1, 298, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 315, - -1, -1, -1, -1, -1, -1, -1, 262, 263, -1, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, -1, 277, 278, 279, 280, 281, 282, 283, 284, - -1, 286, 287, 288, -1, -1, -1, 292, 293, 294, - 262, 263, -1, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, -1, -1, -1, -1, 280, 281, - 282, 283, 284, -1, 286, 287, 288, -1, -1, -1, - 292, 293, 294, 262, 263, -1, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, -1, -1, -1, - -1, 280, 281, 282, 283, 284, -1, 286, 287, 288, - -1, -1, -1, 292, 293, 294, -1, -1, 262, 263, - -1, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, -1, -1, -1, -1, 280, 281, 282, 283, - 284, -1, 286, 287, 288, -1, -1, -1, 292, 293, - 294, -1, 262, 263, -1, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, -1, -1, -1, -1, - 280, 281, 282, 283, 284, -1, 286, 287, 288, -1, - -1, -1, 292, 293, 294, -}; -#define YYFINAL 3 -#ifndef YYDEBUG -#define YYDEBUG 0 +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 #endif -#define YYMAXTOKEN 324 + + +extern YYSTYPE yylval; + +int yyparse (void); + +#endif /* !YY_YY_Y_TAB_H_INCLUDED */ + +/* Copy the second part of user declarations. */ + +#line 656 "y.tab.c" /* yacc.c:358 */ + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ + && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 9 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 1031 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 194 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 160 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 406 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 866 + +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 431 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 189, 193, 2, + 133, 134, 187, 185, 131, 186, 191, 188, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 132, 2, + 2, 190, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 135, 2, 136, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 137, 192, 138, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184 +}; + #if YYDEBUG -char *yyname[] = { -"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,"'('","')'",0,0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,"':'",0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'['",0,"']'",0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"CHAR", -"INTEGER","BOOLEAN","PERCENT","MESSAGE_ID","MAZE_ID","LEVEL_ID","LEV_INIT_ID", -"GEOMETRY_ID","NOMAP_ID","OBJECT_ID","COBJECT_ID","MONSTER_ID","TRAP_ID", -"DOOR_ID","DRAWBRIDGE_ID","MAZEWALK_ID","WALLIFY_ID","REGION_ID","FILLING", -"RANDOM_OBJECTS_ID","RANDOM_MONSTERS_ID","RANDOM_PLACES_ID","ALTAR_ID", -"LADDER_ID","STAIR_ID","NON_DIGGABLE_ID","NON_PASSWALL_ID","ROOM_ID", -"PORTAL_ID","TELEPRT_ID","BRANCH_ID","LEV","CHANCE_ID","CORRIDOR_ID","GOLD_ID", -"ENGRAVING_ID","FOUNTAIN_ID","POOL_ID","SINK_ID","NONE","RAND_CORRIDOR_ID", -"DOOR_STATE","LIGHT_STATE","CURSE_TYPE","ENGRAVING_TYPE","DIRECTION", -"RANDOM_TYPE","O_REGISTER","M_REGISTER","P_REGISTER","A_REGISTER","ALIGNMENT", -"LEFT_OR_RIGHT","CENTER","TOP_OR_BOT","ALTAR_TYPE","UP_OR_DOWN","SUBROOM_ID", -"NAME_ID","FLAGS_ID","FLAG_TYPE","MON_ATTITUDE","MON_ALERTNESS", -"MON_APPEARANCE","CONTAINED","STRING","MAP_ID", -}; -char *yyrule[] = { -"$accept : file", -"file :", -"file : levels", -"levels : level", -"levels : level levels", -"level : maze_level", -"level : room_level", -"maze_level : maze_def flags lev_init messages regions", -"room_level : level_def flags lev_init messages rreg_init rooms corridors_def", -"level_def : LEVEL_ID ':' string", -"lev_init :", -"lev_init : LEV_INIT_ID ':' CHAR ',' CHAR ',' BOOLEAN ',' BOOLEAN ',' light_state ',' walled", -"lev_init : LEV_INIT_ID ':' CHAR ',' CHAR ',' BOOLEAN ',' BOOLEAN ',' light_state ',' walled ',' BOOLEAN", -"walled : BOOLEAN", -"walled : RANDOM_TYPE", -"flags :", -"flags : FLAGS_ID ':' flag_list", -"flag_list : FLAG_TYPE ',' flag_list", -"flag_list : FLAG_TYPE", -"messages :", -"messages : message messages", -"message : MESSAGE_ID ':' STRING", -"rreg_init :", -"rreg_init : rreg_init init_rreg", -"init_rreg : RANDOM_OBJECTS_ID ':' object_list", -"init_rreg : RANDOM_MONSTERS_ID ':' monster_list", -"rooms :", -"rooms : roomlist", -"roomlist : aroom", -"roomlist : aroom roomlist", -"corridors_def : random_corridors", -"corridors_def : corridors", -"random_corridors : RAND_CORRIDOR_ID", -"corridors :", -"corridors : corridors corridor", -"corridor : CORRIDOR_ID ':' corr_spec ',' corr_spec", -"corridor : CORRIDOR_ID ':' corr_spec ',' INTEGER", -"corr_spec : '(' INTEGER ',' DIRECTION ',' door_pos ')'", -"aroom : room_def room_details", -"aroom : subroom_def room_details", -"subroom_def : SUBROOM_ID ':' room_type ',' light_state ',' subroom_pos ',' room_size ',' string roomfill", -"room_def : ROOM_ID ':' room_type ',' light_state ',' room_pos ',' room_align ',' room_size roomfill", -"roomfill :", -"roomfill : ',' BOOLEAN", -"room_pos : '(' INTEGER ',' INTEGER ')'", -"room_pos : RANDOM_TYPE", -"subroom_pos : '(' INTEGER ',' INTEGER ')'", -"subroom_pos : RANDOM_TYPE", -"room_align : '(' h_justif ',' v_justif ')'", -"room_align : RANDOM_TYPE", -"room_size : '(' INTEGER ',' INTEGER ')'", -"room_size : RANDOM_TYPE", -"room_details :", -"room_details : room_details room_detail", -"room_detail : room_name", -"room_detail : room_chance", -"room_detail : room_door", -"room_detail : monster_detail", -"room_detail : object_detail", -"room_detail : trap_detail", -"room_detail : altar_detail", -"room_detail : fountain_detail", -"room_detail : sink_detail", -"room_detail : pool_detail", -"room_detail : gold_detail", -"room_detail : engraving_detail", -"room_detail : stair_detail", -"room_name : NAME_ID ':' string", -"room_chance : CHANCE_ID ':' INTEGER", -"room_door : DOOR_ID ':' secret ',' door_state ',' door_wall ',' door_pos", -"secret : BOOLEAN", -"secret : RANDOM_TYPE", -"door_wall : DIRECTION", -"door_wall : RANDOM_TYPE", -"door_pos : INTEGER", -"door_pos : RANDOM_TYPE", -"maze_def : MAZE_ID ':' string ',' filling", -"filling : CHAR", -"filling : RANDOM_TYPE", -"regions : aregion", -"regions : aregion regions", -"aregion : map_definition reg_init map_details", -"map_definition : NOMAP_ID", -"map_definition : map_geometry MAP_ID", -"map_geometry : GEOMETRY_ID ':' h_justif ',' v_justif", -"h_justif : LEFT_OR_RIGHT", -"h_justif : CENTER", -"v_justif : TOP_OR_BOT", -"v_justif : CENTER", -"reg_init :", -"reg_init : reg_init init_reg", -"init_reg : RANDOM_OBJECTS_ID ':' object_list", -"init_reg : RANDOM_PLACES_ID ':' place_list", -"init_reg : RANDOM_MONSTERS_ID ':' monster_list", -"object_list : object", -"object_list : object ',' object_list", -"monster_list : monster", -"monster_list : monster ',' monster_list", -"place_list : place", -"$$1 :", -"place_list : place $$1 ',' place_list", -"map_details :", -"map_details : map_details map_detail", -"map_detail : monster_detail", -"map_detail : object_detail", -"map_detail : door_detail", -"map_detail : trap_detail", -"map_detail : drawbridge_detail", -"map_detail : region_detail", -"map_detail : stair_region", -"map_detail : portal_region", -"map_detail : teleprt_region", -"map_detail : branch_region", -"map_detail : altar_detail", -"map_detail : fountain_detail", -"map_detail : mazewalk_detail", -"map_detail : wallify_detail", -"map_detail : ladder_detail", -"map_detail : stair_detail", -"map_detail : gold_detail", -"map_detail : engraving_detail", -"map_detail : diggable_detail", -"map_detail : passwall_detail", -"$$2 :", -"monster_detail : MONSTER_ID chance ':' monster_c ',' m_name ',' coordinate $$2 monster_infos", -"monster_infos :", -"monster_infos : monster_infos monster_info", -"monster_info : ',' string", -"monster_info : ',' MON_ATTITUDE", -"monster_info : ',' MON_ALERTNESS", -"monster_info : ',' alignment", -"monster_info : ',' MON_APPEARANCE string", -"object_detail : OBJECT_ID object_desc", -"object_detail : COBJECT_ID object_desc", -"$$3 :", -"object_desc : chance ':' object_c ',' o_name $$3 ',' object_where object_infos", -"object_where : coordinate", -"object_where : CONTAINED", -"object_infos :", -"object_infos : ',' curse_state ',' monster_id ',' enchantment optional_name", -"object_infos : ',' curse_state ',' enchantment optional_name", -"object_infos : ',' monster_id ',' enchantment optional_name", -"curse_state : RANDOM_TYPE", -"curse_state : CURSE_TYPE", -"monster_id : STRING", -"enchantment : RANDOM_TYPE", -"enchantment : INTEGER", -"optional_name :", -"optional_name : ',' NONE", -"optional_name : ',' STRING", -"door_detail : DOOR_ID ':' door_state ',' coordinate", -"trap_detail : TRAP_ID chance ':' trap_name ',' coordinate", -"drawbridge_detail : DRAWBRIDGE_ID ':' coordinate ',' DIRECTION ',' door_state", -"mazewalk_detail : MAZEWALK_ID ':' coordinate ',' DIRECTION", -"wallify_detail : WALLIFY_ID", -"ladder_detail : LADDER_ID ':' coordinate ',' UP_OR_DOWN", -"stair_detail : STAIR_ID ':' coordinate ',' UP_OR_DOWN", -"$$4 :", -"stair_region : STAIR_ID ':' lev_region $$4 ',' lev_region ',' UP_OR_DOWN", -"$$5 :", -"portal_region : PORTAL_ID ':' lev_region $$5 ',' lev_region ',' string", -"$$6 :", -"$$7 :", -"teleprt_region : TELEPRT_ID ':' lev_region $$6 ',' lev_region $$7 teleprt_detail", -"$$8 :", -"branch_region : BRANCH_ID ':' lev_region $$8 ',' lev_region", -"teleprt_detail :", -"teleprt_detail : ',' UP_OR_DOWN", -"lev_region : region", -"lev_region : LEV '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'", -"fountain_detail : FOUNTAIN_ID ':' coordinate", -"sink_detail : SINK_ID ':' coordinate", -"pool_detail : POOL_ID ':' coordinate", -"diggable_detail : NON_DIGGABLE_ID ':' region", -"passwall_detail : NON_PASSWALL_ID ':' region", -"region_detail : REGION_ID ':' region ',' light_state ',' room_type prefilled", -"altar_detail : ALTAR_ID ':' coordinate ',' alignment ',' altar_type", -"gold_detail : GOLD_ID ':' amount ',' coordinate", -"engraving_detail : ENGRAVING_ID ':' coordinate ',' engraving_type ',' string", -"monster_c : monster", -"monster_c : RANDOM_TYPE", -"monster_c : m_register", -"object_c : object", -"object_c : RANDOM_TYPE", -"object_c : o_register", -"m_name : string", -"m_name : RANDOM_TYPE", -"o_name : string", -"o_name : RANDOM_TYPE", -"trap_name : string", -"trap_name : RANDOM_TYPE", -"room_type : string", -"room_type : RANDOM_TYPE", -"prefilled :", -"prefilled : ',' FILLING", -"prefilled : ',' FILLING ',' BOOLEAN", -"coordinate : coord", -"coordinate : p_register", -"coordinate : RANDOM_TYPE", -"door_state : DOOR_STATE", -"door_state : RANDOM_TYPE", -"light_state : LIGHT_STATE", -"light_state : RANDOM_TYPE", -"alignment : ALIGNMENT", -"alignment : a_register", -"alignment : RANDOM_TYPE", -"altar_type : ALTAR_TYPE", -"altar_type : RANDOM_TYPE", -"p_register : P_REGISTER '[' INTEGER ']'", -"o_register : O_REGISTER '[' INTEGER ']'", -"m_register : M_REGISTER '[' INTEGER ']'", -"a_register : A_REGISTER '[' INTEGER ']'", -"place : coord", -"monster : CHAR", -"object : CHAR", -"string : STRING", -"amount : INTEGER", -"amount : RANDOM_TYPE", -"chance :", -"chance : PERCENT", -"engraving_type : ENGRAVING_TYPE", -"engraving_type : RANDOM_TYPE", -"coord : '(' INTEGER ',' INTEGER ')'", -"region : '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'", + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 275, 275, 276, 279, 280, 283, 305, 310, 326, + 330, 336, 345, 354, 358, 384, 387, 394, 398, 405, + 408, 415, 416, 420, 423, 429, 433, 440, 443, 449, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 497, 498, 501, 502, 503, 504, 505, 506, + 507, 508, 509, 512, 513, 514, 515, 516, 517, 518, + 519, 520, 523, 524, 525, 528, 529, 532, 544, 550, + 556, 562, 568, 574, 580, 586, 592, 599, 606, 613, + 620, 627, 634, 643, 648, 655, 660, 667, 672, 679, + 683, 689, 694, 701, 705, 711, 715, 722, 744, 721, + 758, 803, 810, 813, 819, 825, 829, 838, 842, 837, + 899, 900, 904, 903, 916, 915, 930, 940, 941, 944, + 977, 976, 1002, 1001, 1031, 1030, 1061, 1060, 1086, 1095, + 1094, 1121, 1127, 1131, 1135, 1141, 1148, 1157, 1165, 1176, + 1175, 1191, 1190, 1207, 1210, 1216, 1226, 1232, 1241, 1247, + 1252, 1258, 1263, 1269, 1278, 1284, 1285, 1288, 1289, 1292, + 1296, 1302, 1303, 1306, 1312, 1318, 1326, 1327, 1330, 1331, + 1334, 1339, 1338, 1352, 1359, 1365, 1373, 1378, 1383, 1388, + 1393, 1398, 1403, 1408, 1413, 1418, 1423, 1428, 1433, 1438, + 1443, 1448, 1455, 1462, 1466, 1479, 1486, 1485, 1501, 1509, + 1515, 1523, 1528, 1533, 1538, 1543, 1548, 1553, 1558, 1563, + 1568, 1579, 1584, 1589, 1594, 1599, 1606, 1612, 1639, 1644, + 1651, 1655, 1661, 1667, 1673, 1683, 1693, 1708, 1718, 1721, + 1727, 1733, 1739, 1745, 1750, 1757, 1763, 1769, 1775, 1782, + 1781, 1805, 1808, 1814, 1820, 1824, 1829, 1836, 1842, 1849, + 1853, 1859, 1867, 1870, 1880, 1884, 1887, 1893, 1897, 1904, + 1908, 1912, 1918, 1919, 1922, 1923, 1926, 1927, 1928, 1934, + 1935, 1936, 1942, 1943, 1946, 1955, 1960, 1967, 1977, 1983, + 1987, 1991, 1998, 2007, 2013, 2017, 2023, 2027, 2035, 2039, + 2046, 2055, 2066, 2070, 2077, 2086, 2095, 2106, 2110, 2117, + 2126, 2135, 2144, 2153, 2159, 2163, 2170, 2179, 2189, 2198, + 2207, 2214, 2215, 2221, 2222, 2223, 2224, 2232, 2240, 2241, + 2242, 2243, 2244, 2245, 2248, 2254, 2262, 2291, 2292, 2295, + 2296, 2299, 2303, 2310, 2317, 2328, 2331, 2339, 2343, 2347, + 2351, 2355, 2360, 2364, 2368, 2372, 2376, 2380, 2384, 2388, + 2392, 2396, 2400, 2404, 2408, 2415, 2421, 2425, 2431, 2437, + 2438, 2439, 2442, 2446, 2450, 2454, 2460, 2461, 2464, 2465, + 2468, 2469, 2472, 2473, 2476, 2480, 2498 }; #endif -#ifdef YYSTACKSIZE -#undef YYMAXDEPTH -#define YYMAXDEPTH YYSTACKSIZE -#else -#ifdef YYMAXDEPTH -#define YYSTACKSIZE YYMAXDEPTH -#else -#define YYSTACKSIZE 500 -#define YYMAXDEPTH 500 + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "CHAR", "INTEGER", "BOOLEAN", "PERCENT", + "SPERCENT", "MINUS_INTEGER", "PLUS_INTEGER", "MAZE_GRID_ID", + "SOLID_FILL_ID", "MINES_ID", "ROGUELEV_ID", "MESSAGE_ID", "MAZE_ID", + "LEVEL_ID", "LEV_INIT_ID", "GEOMETRY_ID", "NOMAP_ID", "OBJECT_ID", + "COBJECT_ID", "MONSTER_ID", "TRAP_ID", "DOOR_ID", "DRAWBRIDGE_ID", + "object_ID", "monster_ID", "terrain_ID", "MAZEWALK_ID", "WALLIFY_ID", + "REGION_ID", "FILLING", "IRREGULAR", "JOINED", "ALTAR_ID", "LADDER_ID", + "STAIR_ID", "NON_DIGGABLE_ID", "NON_PASSWALL_ID", "ROOM_ID", "PORTAL_ID", + "TELEPRT_ID", "BRANCH_ID", "LEV", "MINERALIZE_ID", "CORRIDOR_ID", + "GOLD_ID", "ENGRAVING_ID", "FOUNTAIN_ID", "POOL_ID", "SINK_ID", "NONE", + "RAND_CORRIDOR_ID", "DOOR_STATE", "LIGHT_STATE", "CURSE_TYPE", + "ENGRAVING_TYPE", "DIRECTION", "RANDOM_TYPE", "RANDOM_TYPE_BRACKET", + "A_REGISTER", "ALIGNMENT", "LEFT_OR_RIGHT", "CENTER", "TOP_OR_BOT", + "ALTAR_TYPE", "UP_OR_DOWN", "SUBROOM_ID", "NAME_ID", "FLAGS_ID", + "FLAG_TYPE", "MON_ATTITUDE", "MON_ALERTNESS", "MON_APPEARANCE", + "ROOMDOOR_ID", "IF_ID", "ELSE_ID", "TERRAIN_ID", "HORIZ_OR_VERT", + "REPLACE_TERRAIN_ID", "EXIT_ID", "SHUFFLE_ID", "QUANTITY_ID", + "BURIED_ID", "LOOP_ID", "FOR_ID", "TO_ID", "SWITCH_ID", "CASE_ID", + "BREAK_ID", "DEFAULT_ID", "ERODED_ID", "TRAPPED_ID", "RECHARGED_ID", + "INVIS_ID", "GREASED_ID", "FEMALE_ID", "CANCELLED_ID", "REVIVED_ID", + "AVENGE_ID", "FLEEING_ID", "BLINDED_ID", "PARALYZED_ID", "STUNNED_ID", + "CONFUSED_ID", "SEENTRAPS_ID", "ALL_ID", "MONTYPE_ID", "GRAVE_ID", + "ERODEPROOF_ID", "FUNCTION_ID", "MSG_OUTPUT_TYPE", "COMPARE_TYPE", + "UNKNOWN_TYPE", "rect_ID", "fillrect_ID", "line_ID", "randline_ID", + "grow_ID", "selection_ID", "flood_ID", "rndcoord_ID", "circle_ID", + "ellipse_ID", "filter_ID", "complement_ID", "gradient_ID", + "GRADIENT_TYPE", "LIMITED", "HUMIDITY_TYPE", "','", "':'", "'('", "')'", + "'['", "']'", "'{'", "'}'", "STRING", "MAP_ID", "NQSTRING", "VARSTRING", + "CFUNC", "CFUNC_INT", "CFUNC_STR", "CFUNC_COORD", "CFUNC_REGION", + "VARSTRING_INT", "VARSTRING_INT_ARRAY", "VARSTRING_STRING", + "VARSTRING_STRING_ARRAY", "VARSTRING_VAR", "VARSTRING_VAR_ARRAY", + "VARSTRING_COORD", "VARSTRING_COORD_ARRAY", "VARSTRING_REGION", + "VARSTRING_REGION_ARRAY", "VARSTRING_MAPCHAR", "VARSTRING_MAPCHAR_ARRAY", + "VARSTRING_MONST", "VARSTRING_MONST_ARRAY", "VARSTRING_OBJ", + "VARSTRING_OBJ_ARRAY", "VARSTRING_SEL", "VARSTRING_SEL_ARRAY", + "METHOD_INT", "METHOD_INT_ARRAY", "METHOD_STRING", "METHOD_STRING_ARRAY", + "METHOD_VAR", "METHOD_VAR_ARRAY", "METHOD_COORD", "METHOD_COORD_ARRAY", + "METHOD_REGION", "METHOD_REGION_ARRAY", "METHOD_MAPCHAR", + "METHOD_MAPCHAR_ARRAY", "METHOD_MONST", "METHOD_MONST_ARRAY", + "METHOD_OBJ", "METHOD_OBJ_ARRAY", "METHOD_SEL", "METHOD_SEL_ARRAY", + "DICE", "'+'", "'-'", "'*'", "'/'", "'%'", "'='", "'.'", "'|'", "'&'", + "$accept", "file", "levels", "level", "level_def", "mazefiller", + "lev_init", "opt_limited", "opt_coord_or_var", "opt_fillchar", "walled", + "flags", "flag_list", "levstatements", "stmt_block", "levstatement", + "any_var_array", "any_var", "any_var_or_arr", "any_var_or_unk", + "shuffle_detail", "variable_define", "encodeobj_list", + "encodemonster_list", "mapchar_list", "encoderegion_list", + "encodecoord_list", "integer_list", "string_list", "function_define", + "$@1", "$@2", "function_call", "exitstatement", "opt_percent", + "comparestmt", "switchstatement", "$@3", "$@4", "switchcases", + "switchcase", "$@5", "$@6", "breakstatement", "for_to_span", + "forstmt_start", "forstatement", "$@7", "loopstatement", "$@8", + "chancestatement", "$@9", "ifstatement", "$@10", "if_ending", "$@11", + "message", "random_corridors", "corridor", "corr_spec", "room_begin", + "subroom_def", "$@12", "room_def", "$@13", "roomfill", "room_pos", + "subroom_pos", "room_align", "room_size", "door_detail", "secret", + "door_wall", "dir_list", "door_pos", "map_definition", "h_justif", + "v_justif", "monster_detail", "$@14", "monster_desc", "monster_infos", + "monster_info", "seen_trap_mask", "object_detail", "$@15", "object_desc", + "object_infos", "object_info", "trap_detail", "drawbridge_detail", + "mazewalk_detail", "wallify_detail", "ladder_detail", "stair_detail", + "stair_region", "portal_region", "teleprt_region", "branch_region", + "teleprt_detail", "fountain_detail", "sink_detail", "pool_detail", + "terrain_type", "replace_terrain_detail", "terrain_detail", + "diggable_detail", "passwall_detail", "region_detail", "@16", + "region_detail_end", "altar_detail", "grave_detail", "gold_detail", + "engraving_detail", "mineralize", "trap_name", "room_type", + "optroomregionflags", "roomregionflags", "roomregionflag", "door_state", + "light_state", "alignment", "alignment_prfx", "altar_type", "a_register", + "string_or_var", "integer_or_var", "coord_or_var", "encodecoord", + "humidity_flags", "region_or_var", "encoderegion", "mapchar_or_var", + "mapchar", "monster_or_var", "encodemonster", "object_or_var", + "encodeobj", "string_expr", "math_expr_var", "func_param_type", + "func_param_part", "func_param_list", "func_params_list", + "func_call_param_part", "func_call_param_list", "func_call_params_list", + "ter_selection_x", "ter_selection", "dice", "all_integers", + "all_ints_push", "objectid", "monsterid", "terrainid", "engraving_type", + "lev_region", "region", YY_NULLPTR +}; #endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 44, 58, 40, 41, 91, 93, 123, 125, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, 428, 429, 430, 431, 43, 45, 42, 47, 37, + 61, 46, 124, 38 +}; +# endif + +#define YYPACT_NINF -654 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-654))) + +#define YYTABLE_NINF -202 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 137, 7, 27, 83, -654, 137, 24, -15, 37, -654, + -654, 91, 733, -10, -654, 113, -654, 99, 131, 133, + -654, 161, 164, 166, 174, 183, 199, 214, 231, 233, + 239, 241, 243, 245, 247, 250, 268, 269, 275, 276, + 281, 295, 305, 317, 322, 323, 325, 326, 327, 28, + 340, 343, -654, 345, 205, 757, -654, -654, 346, 49, + 66, 265, -654, -654, -654, -654, -654, -654, -654, -654, + -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, + -654, -654, -654, 733, -654, -654, 190, -654, -654, -654, + -654, -654, 353, -654, -654, -654, -654, -654, -654, -654, + -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, + -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, + -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, + -654, -654, 59, 308, -654, -31, 406, 351, 58, 58, + 144, -11, 57, -18, -18, 672, -57, -18, -18, 248, + -57, -57, -6, -1, -1, -1, 66, 303, 66, -18, + 672, 672, 672, 319, -6, 51, -654, 672, -57, 751, + 66, -654, -654, 279, 339, -18, 355, -654, 29, -654, + 344, -654, 198, -654, 56, -654, 18, -654, 359, -654, + -654, -654, 113, -654, -654, 360, -654, 309, 368, 371, + 372, -654, -654, 374, -654, -654, 375, 503, -654, 378, + 379, 383, -654, -654, -654, 506, -654, -654, 402, -654, + -654, -654, -654, -654, -654, 537, -654, -654, 413, 404, + 418, -654, -654, -654, 420, -654, -654, 427, 439, 446, + -57, -57, -18, -18, 417, -18, 436, 445, 449, 672, + 450, 508, -654, -654, 391, -654, 582, -654, 453, 458, + -654, 459, 460, 466, 599, 473, 474, -654, -654, -654, + -654, -654, 475, 601, 608, 482, 483, 489, 490, 387, + 618, 526, 208, 529, -654, -654, -654, -654, -654, -654, + -654, -654, 530, -654, -654, 534, 359, 538, 539, -654, + 523, 66, 66, 540, -654, 548, 342, 66, 66, -654, + 66, 66, 66, 66, 66, 309, 387, -654, 542, 549, + -654, -654, -654, -654, -654, -654, 554, 60, 32, -654, + -654, 309, 387, 555, 556, 558, 733, 733, -654, -654, + 66, -31, 671, 46, 698, 571, 567, 672, 573, 66, + 215, 700, 566, 581, 66, 587, 359, 589, 66, 359, + -18, -18, 672, 663, 664, -654, -654, 541, 544, 521, + -654, -18, -18, 307, -654, 595, 590, 672, 597, 66, + 67, 186, 659, 730, 604, 669, -1, 8, -654, 606, + 607, -1, -1, -1, 66, 609, 89, -18, 141, 12, + 57, 665, -654, 52, 52, -654, 156, 605, -38, 697, + -654, -654, 331, 347, 168, 168, -654, -654, -654, 56, + -654, 672, 612, -52, -50, 4, 140, -654, -654, 309, + 387, 55, 127, 158, -654, 611, 358, -654, -654, -654, + 743, -654, 628, 374, -654, 626, 761, 430, -654, -654, + 383, -654, -654, 627, 464, 266, -654, 638, 492, -654, + -654, -654, -654, 636, 654, -18, -18, 600, 673, 666, + 675, 676, -654, 679, 438, -654, 667, 681, -654, 685, + 686, -654, -654, 799, 522, -654, -654, 689, -654, 687, + -654, 693, -654, -654, 694, 824, -654, 699, -654, 825, + 701, 67, 827, 702, 703, -654, 704, 779, -654, -654, + -654, -654, -654, 707, -654, 836, 710, 712, 786, 861, + -654, 734, 359, -654, 678, 66, -654, -654, 309, 735, + -654, 739, 732, -654, -654, -654, -654, 867, 740, -654, + -8, -654, 66, -654, -31, -654, 21, -654, 25, -654, + 54, -654, -654, -654, 741, 873, -654, -654, 744, -654, + 737, 745, -654, -654, -654, -654, -654, -654, -654, 748, + 769, -654, 771, -654, 788, -654, -654, 790, -654, -654, + -654, -654, -654, 784, -654, 792, 57, 919, -654, 794, + 868, 672, -654, 66, 66, 672, 796, 66, 672, 672, + 795, 798, -654, -6, 926, 90, 927, -49, 865, 802, + 13, -654, 803, 797, 870, -654, 66, 804, -31, 807, + 15, 254, 359, 52, -654, -654, 387, 805, 224, 697, + -654, -29, -654, -654, 387, 309, 151, -654, 159, -654, + 171, -654, 67, 808, -654, -654, -654, -31, 66, 66, + 66, 144, -654, 594, -654, 809, 66, -654, 810, 258, + 337, 811, 67, 528, 812, 813, 66, 937, 817, 814, + -654, -654, -654, 818, 939, -654, 947, -654, 289, 821, + -654, -654, 822, 85, 309, 950, -654, 951, 817, -654, + 826, -654, -654, 828, 160, -654, -654, -654, -654, 359, + 21, -654, 25, -654, 54, -654, 829, 953, 309, -654, + -654, -654, -654, 149, -654, -654, -654, -31, -654, -654, + -654, -654, -654, 830, 832, 833, -654, -654, 834, -654, + -654, -654, 309, 957, -654, 387, -654, 924, -654, 66, + -654, 835, -654, -654, -654, 409, 837, 419, -654, -654, + 963, 839, 838, 840, 15, 66, -654, -654, 841, 842, + 843, -654, 85, 954, 329, 845, 844, 160, -654, -654, + -654, -654, -654, 847, 914, 309, 66, 66, 66, -44, + -654, 846, 304, -654, 66, 975, -654, -654, -654, -654, + 850, 359, 852, 980, -654, 215, 817, -654, -654, -654, + 981, 359, -654, -654, 854, -654, -654, -654, 982, -654, + -654, -654, -654, -654, 800, -654, -654, 956, -654, 217, + 855, 419, -654, -654, 986, 857, 859, -654, 860, -654, + -654, 733, 864, -44, 862, 869, 863, -654, -654, 866, + -654, -654, 359, -654, 733, -654, 67, -654, -654, -654, + 871, -654, -654, -654, 872, -18, 68, 874, -654, -654, + 809, -18, 875, -654, -654, -654 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 2, 0, 0, 0, 3, 4, 23, 0, 0, 1, + 5, 0, 27, 0, 7, 0, 134, 0, 0, 0, + 193, 0, 0, 0, 0, 0, 0, 0, 250, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, + 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, + 0, 0, 131, 0, 0, 0, 137, 146, 0, 0, + 0, 0, 94, 83, 74, 84, 75, 85, 76, 86, + 77, 87, 78, 88, 79, 89, 80, 90, 81, 91, + 82, 31, 6, 27, 92, 93, 0, 37, 36, 52, + 53, 50, 0, 45, 51, 150, 46, 47, 49, 48, + 30, 62, 35, 65, 64, 39, 55, 57, 58, 72, + 40, 56, 73, 54, 69, 70, 61, 71, 34, 43, + 66, 60, 68, 67, 38, 59, 63, 32, 33, 44, + 41, 42, 0, 26, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, + 0, 95, 96, 0, 0, 0, 0, 343, 0, 346, + 0, 388, 0, 344, 365, 28, 0, 154, 0, 10, + 9, 8, 0, 305, 306, 0, 341, 161, 0, 0, + 0, 13, 314, 0, 196, 197, 0, 0, 311, 0, + 0, 173, 309, 338, 340, 0, 337, 335, 0, 225, + 229, 334, 226, 331, 333, 0, 330, 328, 0, 200, + 0, 327, 282, 281, 0, 292, 293, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 384, 367, 386, 251, 0, 319, 0, 0, + 318, 0, 0, 0, 0, 0, 0, 404, 267, 268, + 284, 283, 0, 132, 0, 0, 0, 0, 0, 308, + 0, 0, 0, 0, 260, 262, 261, 391, 389, 390, + 164, 163, 0, 185, 186, 0, 0, 0, 0, 97, + 0, 0, 0, 276, 127, 0, 0, 0, 0, 136, + 0, 0, 0, 0, 0, 362, 361, 363, 366, 0, + 397, 399, 396, 398, 400, 401, 0, 0, 0, 104, + 105, 100, 98, 0, 0, 0, 0, 27, 151, 25, + 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 368, 369, 0, 0, 0, + 377, 0, 0, 0, 383, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 158, 157, 0, 0, 152, 0, 0, 0, 359, + 345, 353, 0, 0, 348, 349, 350, 351, 352, 0, + 130, 0, 343, 0, 0, 0, 0, 121, 119, 125, + 123, 0, 0, 0, 155, 0, 0, 342, 12, 263, + 0, 11, 0, 0, 315, 0, 0, 0, 199, 198, + 173, 174, 195, 0, 0, 0, 227, 0, 0, 202, + 204, 246, 184, 0, 248, 0, 0, 189, 0, 0, + 0, 0, 325, 0, 0, 323, 0, 0, 322, 0, + 0, 385, 387, 0, 0, 294, 295, 0, 298, 0, + 296, 0, 297, 252, 0, 0, 253, 0, 176, 0, + 0, 0, 0, 0, 258, 257, 0, 0, 165, 166, + 277, 402, 403, 0, 178, 0, 0, 0, 0, 0, + 266, 0, 0, 148, 0, 0, 138, 275, 274, 0, + 357, 360, 0, 347, 135, 364, 99, 0, 0, 108, + 0, 107, 0, 106, 0, 112, 0, 103, 0, 102, + 0, 101, 29, 307, 0, 0, 317, 310, 0, 312, + 0, 0, 336, 394, 392, 393, 240, 237, 231, 0, + 0, 236, 0, 241, 0, 243, 244, 0, 239, 230, + 245, 395, 233, 0, 329, 203, 0, 0, 370, 0, + 0, 0, 372, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 320, 0, 0, 0, 0, 0, 0, 0, + 0, 168, 0, 0, 0, 256, 0, 0, 0, 0, + 0, 0, 0, 0, 153, 147, 149, 0, 0, 0, + 128, 0, 120, 122, 124, 126, 0, 113, 0, 115, + 0, 117, 0, 0, 313, 194, 339, 0, 0, 0, + 0, 0, 332, 0, 247, 19, 0, 190, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 285, 0, + 303, 302, 273, 0, 0, 254, 0, 180, 0, 0, + 255, 259, 0, 0, 278, 0, 182, 0, 285, 188, + 0, 187, 160, 0, 140, 354, 355, 356, 358, 0, + 0, 111, 0, 110, 0, 109, 0, 0, 234, 235, + 238, 242, 232, 0, 299, 207, 208, 0, 212, 211, + 213, 214, 215, 0, 0, 0, 219, 220, 0, 205, + 209, 300, 206, 0, 249, 371, 373, 0, 378, 0, + 374, 0, 324, 376, 375, 0, 0, 0, 269, 304, + 0, 0, 0, 0, 0, 0, 191, 192, 0, 0, + 0, 169, 0, 0, 0, 0, 0, 140, 129, 114, + 116, 118, 264, 0, 0, 210, 0, 0, 0, 0, + 20, 0, 0, 326, 0, 0, 289, 290, 291, 286, + 287, 271, 0, 0, 175, 0, 285, 279, 167, 177, + 0, 0, 183, 265, 0, 144, 139, 141, 0, 301, + 216, 217, 218, 223, 222, 221, 379, 0, 380, 349, + 0, 0, 272, 270, 0, 0, 0, 171, 0, 170, + 142, 27, 0, 0, 0, 0, 0, 321, 288, 0, + 406, 179, 0, 181, 27, 145, 0, 224, 381, 16, + 0, 405, 172, 143, 0, 0, 0, 17, 21, 22, + 19, 0, 0, 14, 18, 382 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -654, -654, 994, -654, -654, -654, -654, -654, -654, 146, + -654, -654, 815, -83, -290, 668, 848, 946, -390, -654, + -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, + -654, -654, -654, -654, -654, 959, -654, -654, -654, 244, + -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, + -654, -654, -654, -654, -654, -654, -654, -654, -654, 614, + 849, -654, -654, -654, -654, 562, -654, -654, -654, 260, + -654, -654, -654, -531, 253, -654, 338, 223, -654, -654, + -654, -654, -654, 187, -654, -654, 880, -654, -654, -654, + -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, + -654, -654, -654, -654, -654, -654, -654, -654, -654, -654, + -654, -654, -654, -654, -654, -654, -654, 421, -653, 200, + -654, -385, -492, -654, -654, -654, 369, 682, -168, -136, + -312, 583, 150, -308, -386, -485, -418, -473, 596, -459, + -132, -55, -654, 396, -654, -654, 610, -654, -654, 781, + -135, 576, -392, -654, -654, -654, -654, -654, -124, -654 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 3, 4, 5, 6, 191, 81, 836, 862, 734, + 860, 12, 134, 82, 338, 83, 84, 85, 86, 173, + 87, 88, 636, 638, 640, 423, 424, 425, 426, 89, + 409, 699, 90, 91, 389, 92, 93, 174, 627, 766, + 767, 844, 831, 94, 525, 95, 96, 188, 97, 522, + 98, 336, 99, 296, 402, 518, 100, 101, 102, 281, + 272, 103, 801, 104, 842, 352, 500, 516, 679, 688, + 105, 295, 690, 468, 758, 106, 210, 450, 107, 359, + 229, 585, 729, 815, 108, 356, 219, 355, 579, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 615, + 119, 120, 121, 441, 122, 123, 124, 125, 126, 791, + 823, 127, 128, 129, 130, 131, 234, 273, 748, 789, + 790, 237, 487, 491, 730, 672, 492, 196, 278, 253, + 212, 346, 259, 260, 477, 478, 230, 231, 220, 221, + 315, 279, 697, 530, 531, 532, 317, 318, 319, 254, + 376, 183, 291, 582, 333, 334, 335, 513, 266, 267 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 185, 211, 300, 197, 509, 182, 401, 238, 239, 611, + 255, 261, 262, 265, 549, 517, 427, 520, 521, 529, + 428, 527, 177, 283, 213, 284, 285, 286, 223, 275, + 276, 277, 297, 177, 16, 761, 177, 305, 320, 303, + 321, 202, 203, 263, 322, 323, 324, 551, 232, 439, + 329, 202, 203, 270, 331, 472, 293, 472, 213, 657, + 177, 213, 189, 813, 422, 641, 456, 498, 305, 459, + 177, 514, 677, 858, 686, 639, 256, 202, 203, 538, + 214, 540, 674, 9, 224, 644, 539, 637, 541, 756, + 691, 202, 203, 287, 11, 814, 325, 288, 289, 257, + 258, 193, 667, 282, 206, 644, 367, 368, 193, 370, + 294, 235, 194, 195, 214, 207, 236, 214, 190, 194, + 195, 132, 485, 306, 13, 207, 486, 859, 233, 316, + 223, 332, 274, 271, 407, 542, 208, 209, 326, 7, + 206, 499, 543, 827, 757, 515, 678, 223, 687, 670, + 706, 327, 1, 2, 215, 328, 671, 193, 225, 8, + 216, 472, 178, 60, 226, 327, 179, 180, 194, 195, + 741, 193, 208, 209, 257, 258, 14, 179, 180, 440, + 179, 180, 194, 195, 133, 519, 224, 519, 215, 178, + 176, 215, 546, 178, 216, 193, 429, 216, 511, 178, + 512, 654, 181, 224, 179, 180, 194, 195, 179, 180, + 475, 476, 445, 181, 179, 180, 181, 217, 218, 771, + 217, 218, 280, 15, 460, 461, 506, 462, 633, 770, + 632, 135, 624, 712, 469, 470, 471, 693, 479, 529, + 181, 769, 482, 523, 181, 488, 406, 489, 490, 764, + 181, 765, 412, 413, 435, 414, 415, 416, 417, 418, + 225, 510, 497, 136, 548, 137, 226, 503, 504, 505, + 563, 544, 306, 430, 564, 565, 528, 225, 545, 448, + 449, 774, 700, 226, 604, 436, 536, 227, 228, 701, + 702, 519, 263, 138, 447, 550, 139, 703, 140, 454, + 268, 269, 704, 458, 227, 228, 141, 202, 203, 705, + 472, 308, 467, 689, 473, 142, 475, 476, 298, 580, + 566, 567, 568, 287, 484, 202, 203, 288, 289, 588, + 589, 143, 692, 287, 309, 569, 330, 288, 289, 397, + 170, 310, 311, 312, 313, 314, 144, 524, 835, 570, + 571, -15, 204, 205, 854, 312, 313, 314, 572, 573, + 574, 575, 576, 145, 316, 146, 202, 203, 695, 696, + 206, 147, 804, 148, 577, 149, 578, 150, 290, 151, + 186, 264, 152, 310, 311, 312, 313, 314, 206, 737, + 365, 366, 738, 310, 311, 312, 313, 314, 184, 207, + 153, 154, 208, 209, 312, 313, 314, 155, 156, 768, + 202, 203, 635, 157, 204, 205, 198, 199, 200, 201, + 208, 209, 240, 241, 242, 243, 244, 158, 245, 206, + 246, 247, 248, 249, 250, 817, 280, 159, 818, 192, + 474, 596, 348, 310, 311, 312, 313, 314, 682, 160, + 181, 786, 787, 788, 161, 162, 658, 163, 164, 165, + 661, 208, 209, 664, 665, 475, 476, 533, 739, 301, + 626, 252, 167, 206, 302, 168, 411, 169, 175, 307, + 709, 710, 711, 534, 207, 187, 684, 634, 304, 310, + 311, 312, 313, 314, 553, 340, 337, 202, 203, 342, + 341, 822, 343, 344, 345, 208, 209, 348, 347, 353, + 350, 829, 348, 349, 351, 708, 310, 311, 312, 313, + 314, 732, 310, 311, 312, 313, 314, 310, 311, 312, + 313, 314, 310, 311, 312, 313, 314, 354, 659, 660, + 357, -201, 663, 310, 311, 312, 313, 314, 358, 360, + 369, 361, 852, 240, 241, 242, 243, 244, 362, 245, + 206, 246, 247, 248, 249, 250, 559, 202, 203, 371, + 363, 251, 310, 311, 312, 313, 314, 364, 372, 467, + 202, 203, 373, 375, 377, 775, 378, 797, 379, 380, + 381, 382, 208, 209, 310, 784, 312, 313, 314, 383, + 562, 735, 252, 384, 385, 386, 387, 388, 810, 811, + 812, 745, 390, 391, 392, 310, 311, 312, 313, 314, + 393, 394, 395, 240, 241, 242, 243, 244, 584, 245, + 206, 246, 247, 248, 249, 250, 240, 241, 242, 243, + 244, 251, 245, 206, 246, 247, 248, 249, 250, 310, + 311, 312, 313, 314, 251, 713, 714, 396, 602, 405, + 398, 399, 208, 209, 742, 400, 715, 716, 717, 403, + 404, 408, 252, 419, 438, 208, 209, 310, 311, 312, + 313, 314, 410, 420, 782, 252, 421, 431, 432, 718, + 433, 719, 720, 721, 722, 723, 724, 725, 726, 727, + 728, 442, 443, 444, 446, 451, 452, 310, 311, 312, + 313, 314, 453, 310, 311, 312, 313, 314, 455, 857, + 457, 463, 464, 480, 481, 864, 493, 465, 483, 819, + 466, 202, 203, 193, 494, 495, 496, 501, 502, 16, + 507, 526, -159, 537, 194, 195, 554, 17, 845, 552, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 555, + 557, 853, 27, 28, 29, 558, 561, 586, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 583, 39, 40, + 41, 42, 43, 44, 45, 587, 46, 240, 241, 242, + 243, 244, 590, 245, 206, 246, 247, 248, 249, 250, + 592, 47, 597, 601, 591, 251, 593, 594, 48, 49, + 595, 50, 598, 51, 52, 53, 599, 600, 54, 55, + 603, 56, 604, 57, 605, 606, 208, 209, 607, 609, + 608, 612, 610, 613, 614, 616, 252, 617, 618, 62, + 619, 620, 58, 621, 59, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 622, 596, 623, 630, 628, 60, 625, + 629, 631, 642, 256, 61, 62, 643, 645, 644, 646, + 647, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 171, + 64, 648, 66, 649, 68, 63, 70, 65, 72, 67, + 74, 69, 76, 71, 78, 73, 80, 75, 652, 77, + 650, 79, 651, 653, 655, 656, 467, 662, 666, 667, + 669, 673, 675, 676, 674, 683, 680, 681, 685, 707, + 733, 746, 694, 751, 736, 740, 743, 744, 747, 750, + 749, 752, 754, 755, 759, 760, 781, 762, 773, 763, + 780, 803, 776, 772, 777, 778, 779, 792, 785, 783, + 793, 795, 794, 809, 800, 798, 799, 805, 808, 820, + 816, 821, 806, 824, 825, 828, 830, 832, 834, 837, + 839, 840, 833, 841, 843, 846, 848, 850, 849, 10, + 851, 172, 855, 856, 434, 861, 863, 339, 166, 865, + 508, 807, 560, 292, 796, 802, 753, 299, 826, 222, + 847, 838, 731, 437, 668, 698, 556, 547, 0, 535, + 374, 581 +}; + +static const yytype_int16 yycheck[] = +{ + 83, 137, 170, 135, 396, 60, 296, 143, 144, 501, + 145, 147, 148, 149, 432, 400, 328, 403, 404, 409, + 328, 59, 4, 159, 3, 160, 161, 162, 3, 153, + 154, 155, 167, 4, 6, 688, 4, 8, 20, 175, + 22, 59, 60, 44, 26, 27, 28, 433, 59, 3, + 186, 59, 60, 59, 186, 3, 5, 3, 3, 590, + 4, 3, 3, 107, 4, 550, 356, 59, 8, 359, + 4, 59, 59, 5, 59, 548, 133, 59, 60, 131, + 59, 131, 131, 0, 59, 134, 138, 546, 138, 4, + 621, 59, 60, 4, 70, 139, 78, 8, 9, 156, + 157, 139, 131, 158, 122, 134, 242, 243, 139, 245, + 59, 54, 150, 151, 59, 133, 59, 59, 59, 150, + 151, 131, 55, 178, 139, 133, 59, 59, 139, 184, + 3, 186, 133, 139, 302, 131, 154, 155, 120, 132, + 122, 133, 138, 796, 59, 133, 133, 3, 133, 59, + 642, 133, 15, 16, 133, 137, 66, 139, 133, 132, + 139, 3, 133, 135, 139, 133, 148, 149, 150, 151, + 662, 139, 154, 155, 156, 157, 139, 148, 149, 133, + 148, 149, 150, 151, 71, 133, 59, 133, 133, 133, + 141, 133, 137, 133, 139, 139, 328, 139, 57, 133, + 59, 586, 184, 59, 148, 149, 150, 151, 148, 149, + 158, 159, 347, 184, 148, 149, 184, 162, 163, 704, + 162, 163, 133, 132, 360, 361, 394, 362, 540, 702, + 538, 132, 522, 651, 369, 371, 372, 623, 373, 629, + 184, 700, 377, 87, 184, 59, 301, 61, 62, 89, + 184, 91, 307, 308, 337, 310, 311, 312, 313, 314, + 133, 397, 386, 132, 137, 132, 139, 391, 392, 393, + 4, 131, 327, 328, 8, 9, 408, 133, 138, 64, + 65, 132, 131, 139, 135, 340, 421, 160, 161, 138, + 131, 133, 44, 132, 349, 137, 132, 138, 132, 354, + 150, 151, 131, 358, 160, 161, 132, 59, 60, 138, + 3, 113, 58, 59, 7, 132, 158, 159, 168, 455, + 54, 55, 56, 4, 379, 59, 60, 8, 9, 465, + 466, 132, 622, 4, 136, 69, 186, 8, 9, 131, + 135, 185, 186, 187, 188, 189, 132, 191, 131, 83, + 84, 134, 63, 64, 846, 187, 188, 189, 92, 93, + 94, 95, 96, 132, 419, 132, 59, 60, 144, 145, + 122, 132, 764, 132, 108, 132, 110, 132, 59, 132, + 190, 133, 132, 185, 186, 187, 188, 189, 122, 131, + 240, 241, 134, 185, 186, 187, 188, 189, 133, 133, + 132, 132, 154, 155, 187, 188, 189, 132, 132, 699, + 59, 60, 544, 132, 63, 64, 10, 11, 12, 13, + 154, 155, 115, 116, 117, 118, 119, 132, 121, 122, + 123, 124, 125, 126, 127, 131, 133, 132, 134, 131, + 133, 3, 4, 185, 186, 187, 188, 189, 616, 132, + 184, 32, 33, 34, 132, 132, 591, 132, 132, 132, + 595, 154, 155, 598, 599, 158, 159, 136, 131, 190, + 525, 164, 132, 122, 135, 132, 134, 132, 132, 135, + 648, 649, 650, 136, 133, 132, 618, 542, 133, 185, + 186, 187, 188, 189, 136, 135, 137, 59, 60, 131, + 191, 791, 131, 131, 130, 154, 155, 4, 133, 3, + 131, 801, 4, 135, 131, 647, 185, 186, 187, 188, + 189, 653, 185, 186, 187, 188, 189, 185, 186, 187, + 188, 189, 185, 186, 187, 188, 189, 135, 593, 594, + 3, 137, 597, 185, 186, 187, 188, 189, 135, 131, + 133, 131, 842, 115, 116, 117, 118, 119, 131, 121, + 122, 123, 124, 125, 126, 127, 136, 59, 60, 133, + 131, 133, 185, 186, 187, 188, 189, 131, 133, 58, + 59, 60, 133, 133, 193, 717, 4, 755, 135, 131, + 131, 131, 154, 155, 185, 186, 187, 188, 189, 133, + 136, 656, 164, 4, 131, 131, 131, 6, 776, 777, + 778, 666, 4, 131, 131, 185, 186, 187, 188, 189, + 131, 131, 4, 115, 116, 117, 118, 119, 136, 121, + 122, 123, 124, 125, 126, 127, 115, 116, 117, 118, + 119, 133, 121, 122, 123, 124, 125, 126, 127, 185, + 186, 187, 188, 189, 133, 61, 62, 131, 136, 136, + 131, 131, 154, 155, 136, 131, 72, 73, 74, 131, + 131, 131, 164, 131, 3, 154, 155, 185, 186, 187, + 188, 189, 134, 134, 739, 164, 132, 132, 132, 95, + 132, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 3, 131, 136, 131, 5, 140, 185, 186, 187, + 188, 189, 131, 185, 186, 187, 188, 189, 131, 855, + 131, 58, 58, 128, 134, 861, 67, 186, 131, 784, + 186, 59, 60, 139, 4, 131, 67, 131, 131, 6, + 131, 136, 77, 131, 150, 151, 3, 14, 831, 138, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 131, + 134, 844, 29, 30, 31, 4, 139, 131, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 139, 45, 46, + 47, 48, 49, 50, 51, 131, 53, 115, 116, 117, + 118, 119, 192, 121, 122, 123, 124, 125, 126, 127, + 134, 68, 135, 4, 131, 133, 131, 131, 75, 76, + 131, 78, 131, 80, 81, 82, 131, 131, 85, 86, + 131, 88, 135, 90, 131, 131, 154, 155, 4, 4, + 131, 4, 131, 131, 131, 131, 164, 58, 131, 142, + 4, 131, 109, 131, 111, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 77, 3, 131, 134, 132, 135, 191, + 131, 4, 131, 133, 141, 142, 3, 140, 134, 134, + 132, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 142, + 149, 132, 151, 132, 153, 148, 155, 150, 157, 152, + 159, 154, 161, 156, 163, 158, 165, 160, 134, 162, + 132, 164, 132, 131, 5, 131, 58, 131, 133, 131, + 4, 4, 67, 131, 131, 131, 139, 67, 131, 131, + 131, 4, 137, 4, 134, 134, 134, 134, 131, 131, + 136, 4, 131, 131, 4, 4, 32, 131, 5, 131, + 3, 7, 132, 134, 132, 132, 132, 4, 131, 134, + 131, 131, 134, 59, 131, 134, 134, 132, 131, 4, + 134, 131, 138, 131, 4, 4, 132, 5, 32, 134, + 4, 134, 192, 134, 134, 131, 134, 134, 129, 5, + 134, 55, 131, 131, 336, 131, 860, 192, 49, 134, + 396, 767, 450, 164, 754, 762, 678, 169, 795, 139, + 833, 821, 653, 341, 603, 629, 443, 431, -1, 419, + 249, 455 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint16 yystos[] = +{ + 0, 15, 16, 195, 196, 197, 198, 132, 132, 0, + 196, 70, 205, 139, 139, 132, 6, 14, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 29, 30, 31, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, + 46, 47, 48, 49, 50, 51, 53, 68, 75, 76, + 78, 80, 81, 82, 85, 86, 88, 90, 109, 111, + 135, 141, 142, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 200, 207, 209, 210, 211, 212, 214, 215, 223, + 226, 227, 229, 230, 237, 239, 240, 242, 244, 246, + 250, 251, 252, 255, 257, 264, 269, 272, 278, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 294, + 295, 296, 298, 299, 300, 301, 302, 305, 306, 307, + 308, 309, 131, 71, 206, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 229, 132, 132, 132, + 135, 142, 211, 213, 231, 132, 141, 4, 133, 148, + 149, 184, 335, 345, 133, 207, 190, 132, 241, 3, + 59, 199, 131, 139, 150, 151, 321, 334, 10, 11, + 12, 13, 59, 60, 63, 64, 122, 133, 154, 155, + 270, 323, 324, 3, 59, 133, 139, 162, 163, 280, + 332, 333, 280, 3, 59, 133, 139, 160, 161, 274, + 330, 331, 59, 139, 310, 54, 59, 315, 323, 323, + 115, 116, 117, 118, 119, 121, 123, 124, 125, 126, + 127, 133, 164, 323, 343, 344, 133, 156, 157, 326, + 327, 323, 323, 44, 133, 323, 352, 353, 326, 326, + 59, 139, 254, 311, 133, 352, 352, 352, 322, 335, + 133, 253, 335, 323, 344, 344, 344, 4, 8, 9, + 59, 346, 254, 5, 59, 265, 247, 344, 326, 210, + 322, 190, 135, 323, 133, 8, 335, 135, 113, 136, + 185, 186, 187, 188, 189, 334, 335, 340, 341, 342, + 20, 22, 26, 27, 28, 78, 120, 133, 137, 323, + 326, 334, 335, 348, 349, 350, 245, 137, 208, 206, + 135, 191, 131, 131, 131, 130, 325, 133, 4, 135, + 131, 131, 259, 3, 135, 281, 279, 3, 135, 273, + 131, 131, 131, 131, 131, 326, 326, 323, 323, 133, + 323, 133, 133, 133, 343, 133, 344, 193, 4, 135, + 131, 131, 131, 133, 4, 131, 131, 131, 6, 228, + 4, 131, 131, 131, 131, 4, 131, 131, 131, 131, + 131, 208, 248, 131, 131, 136, 335, 322, 131, 224, + 134, 134, 335, 335, 335, 335, 335, 335, 335, 131, + 134, 132, 4, 219, 220, 221, 222, 324, 327, 334, + 335, 132, 132, 132, 209, 207, 335, 321, 3, 3, + 133, 297, 3, 131, 136, 344, 131, 335, 64, 65, + 271, 5, 140, 131, 335, 131, 208, 131, 335, 208, + 323, 323, 344, 58, 58, 186, 186, 58, 267, 344, + 323, 323, 3, 7, 133, 158, 159, 328, 329, 344, + 128, 134, 344, 131, 335, 55, 59, 316, 59, 61, + 62, 317, 320, 67, 4, 131, 67, 352, 59, 133, + 260, 131, 131, 352, 352, 352, 322, 131, 253, 346, + 323, 57, 59, 351, 59, 133, 261, 315, 249, 133, + 328, 328, 243, 87, 191, 238, 136, 59, 334, 212, + 337, 338, 339, 136, 136, 340, 344, 131, 131, 138, + 131, 138, 131, 138, 131, 138, 137, 332, 137, 330, + 137, 328, 138, 136, 3, 131, 325, 134, 4, 136, + 259, 139, 136, 4, 8, 9, 54, 55, 56, 69, + 83, 84, 92, 93, 94, 95, 96, 108, 110, 282, + 323, 345, 347, 139, 136, 275, 131, 131, 323, 323, + 192, 131, 134, 131, 131, 131, 3, 135, 131, 131, + 131, 4, 136, 131, 135, 131, 131, 4, 131, 4, + 131, 316, 4, 131, 131, 293, 131, 58, 131, 4, + 131, 131, 77, 131, 208, 191, 335, 232, 132, 131, + 134, 4, 327, 324, 335, 334, 216, 333, 217, 331, + 218, 329, 131, 3, 134, 140, 134, 132, 132, 132, + 132, 132, 134, 131, 315, 5, 131, 267, 344, 335, + 335, 344, 131, 335, 344, 344, 133, 131, 311, 4, + 59, 66, 319, 4, 131, 67, 131, 59, 133, 262, + 139, 67, 322, 131, 334, 131, 59, 133, 263, 59, + 266, 267, 208, 328, 137, 144, 145, 336, 337, 225, + 131, 138, 131, 138, 131, 138, 316, 131, 334, 322, + 322, 322, 330, 61, 62, 72, 73, 74, 95, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 276, + 318, 320, 334, 131, 203, 335, 134, 131, 134, 131, + 134, 316, 136, 134, 134, 335, 4, 131, 312, 136, + 131, 4, 4, 270, 131, 131, 4, 59, 268, 4, + 4, 312, 131, 131, 89, 91, 233, 234, 208, 333, + 331, 329, 134, 5, 132, 334, 132, 132, 132, 132, + 3, 32, 335, 134, 186, 131, 32, 33, 34, 313, + 314, 303, 4, 131, 134, 131, 263, 322, 134, 134, + 131, 256, 268, 7, 346, 132, 138, 233, 131, 59, + 322, 322, 322, 107, 139, 277, 134, 131, 134, 335, + 4, 131, 208, 304, 131, 4, 271, 312, 4, 208, + 132, 236, 5, 192, 32, 131, 201, 134, 313, 4, + 134, 134, 258, 134, 235, 207, 131, 277, 134, 129, + 134, 134, 208, 207, 316, 131, 131, 323, 5, 59, + 204, 131, 202, 203, 323, 134 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 194, 195, 195, 196, 196, 197, 198, 198, 199, + 199, 200, 200, 200, 200, 201, 201, 202, 202, 203, + 203, 204, 204, 205, 205, 206, 206, 207, 207, 208, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 210, 210, 210, 210, 210, 210, + 210, 210, 210, 211, 211, 211, 211, 211, 211, 211, + 211, 211, 212, 212, 212, 213, 213, 214, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 216, 216, 217, 217, 218, 218, 219, + 219, 220, 220, 221, 221, 222, 222, 224, 225, 223, + 226, 227, 228, 228, 229, 229, 229, 231, 232, 230, + 233, 233, 235, 234, 236, 234, 237, 238, 238, 239, + 241, 240, 243, 242, 245, 244, 247, 246, 248, 249, + 248, 250, 251, 251, 251, 252, 252, 253, 254, 256, + 255, 258, 257, 259, 259, 260, 260, 261, 261, 262, + 262, 263, 263, 264, 264, 265, 265, 266, 266, 267, + 267, 268, 268, 269, 269, 269, 270, 270, 271, 271, + 272, 273, 272, 274, 275, 275, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 277, 277, 277, 278, 279, 278, 280, 281, + 281, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 283, 284, 285, 285, + 286, 286, 287, 288, 289, 290, 291, 292, 293, 293, + 294, 295, 296, 297, 297, 298, 299, 300, 301, 303, + 302, 304, 304, 305, 306, 306, 306, 307, 308, 309, + 309, 310, 310, 311, 311, 312, 312, 313, 313, 314, + 314, 314, 315, 315, 316, 316, 317, 317, 317, 318, + 318, 318, 319, 319, 320, 321, 321, 321, 322, 323, + 323, 323, 323, 324, 324, 324, 325, 325, 326, 326, + 326, 327, 328, 328, 328, 329, 329, 330, 330, 330, + 331, 331, 331, 331, 332, 332, 332, 333, 333, 333, + 333, 334, 334, 335, 335, 335, 335, 335, 335, 335, + 335, 335, 335, 335, 336, 336, 337, 338, 338, 339, + 339, 340, 340, 341, 341, 342, 342, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 344, 344, 345, 346, + 346, 346, 347, 347, 347, 347, 348, 348, 349, 349, + 350, 350, 351, 351, 352, 352, 353 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 1, 1, 2, 3, 3, 5, 1, + 1, 5, 5, 3, 16, 0, 2, 0, 2, 0, + 2, 1, 1, 0, 3, 3, 1, 0, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 3, 5, + 3, 5, 5, 5, 3, 3, 5, 5, 5, 7, + 7, 7, 5, 1, 3, 1, 3, 1, 3, 1, + 3, 1, 3, 1, 3, 1, 3, 0, 0, 8, + 4, 1, 0, 1, 1, 5, 3, 0, 0, 9, + 0, 2, 0, 5, 0, 4, 1, 2, 1, 6, + 0, 3, 0, 6, 0, 4, 0, 4, 1, 0, + 4, 3, 1, 3, 3, 5, 5, 7, 4, 0, + 10, 0, 12, 0, 2, 5, 1, 5, 1, 5, + 1, 5, 1, 9, 5, 1, 1, 1, 1, 1, + 3, 1, 1, 1, 7, 5, 1, 1, 1, 1, + 3, 0, 5, 4, 0, 3, 1, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 3, 3, 3, 1, + 1, 3, 1, 1, 3, 3, 0, 5, 2, 0, + 3, 1, 3, 1, 3, 3, 1, 1, 3, 1, + 1, 1, 3, 1, 1, 1, 5, 7, 5, 8, + 1, 3, 5, 5, 7, 7, 6, 5, 0, 2, + 3, 3, 3, 1, 5, 9, 5, 3, 3, 0, + 10, 0, 1, 7, 5, 5, 3, 5, 7, 9, + 1, 1, 1, 1, 1, 0, 2, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 1, 4, 1, 1, 4, 1, 1, + 4, 1, 4, 5, 1, 3, 1, 3, 1, 1, + 4, 9, 1, 1, 4, 1, 5, 1, 1, 4, + 1, 1, 5, 1, 1, 1, 4, 1, 1, 5, + 1, 1, 3, 1, 1, 3, 1, 4, 3, 3, + 3, 3, 3, 3, 1, 1, 3, 1, 3, 0, + 1, 1, 1, 1, 3, 0, 1, 1, 2, 2, + 4, 6, 4, 6, 6, 6, 6, 2, 6, 8, + 8, 10, 14, 2, 1, 3, 1, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 10, 9 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +{ + unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ int yydebug; -int yynerrs; -int yyerrflag; -int yychar; -short *yyssp; -YYSTYPE *yyvsp; -YYSTYPE yyval; -YYSTYPE yylval; -short yyss[YYSTACKSIZE]; -YYSTYPE yyvs[YYSTACKSIZE]; -#define yystacksize YYSTACKSIZE +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ -/*lev_comp.y*/ -#define YYABORT goto yyabort -#define YYREJECT goto yyabort -#define YYACCEPT goto yyaccept -#define YYERROR goto yyerrlab -int -yyparse() + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) { - register int yym, yyn, yystate; -#if YYDEBUG - register char *yys; - extern char *getenv(); + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif - if ((yys = getenv("YYDEBUG")) != 0) +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') { - yyn = *yys; - if (yyn >= '0' && yyn <= '9') - yydebug = yyn - '0'; + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; } -#endif - yynerrs = 0; - yyerrflag = 0; - yychar = (-1); + if (! yyres) + return yystrlen (yystr); - yyssp = yyss; - yyvsp = yyvs; - *yyssp = yystate = 0; + return yystpcpy (yyres, yystr) - yyres; +} +# endif -yyloop: - if ((yyn = yydefred[yystate]) != 0) goto yyreduce; - if (yychar < 0) +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) { - if ((yychar = yylex()) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - } - if ((yyn = yysindex[yystate]) != 0 && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, shifting to state %d\n", - YYPREFIX, yystate, yytable[yyn]); -#endif - if (yyssp >= yyss + yystacksize - 1) - { - goto yyoverflow; - } - *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; - yychar = (-1); - if (yyerrflag > 0) --yyerrflag; - goto yyloop; - } - if ((yyn = yyrindex[yystate]) != 0 && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { - yyn = yytable[yyn]; - goto yyreduce; - } - if (yyerrflag) goto yyinrecovery; -#ifdef lint - goto yynewerror; -#endif -yynewerror: - yyerror("syntax error"); -#ifdef lint - goto yyerrlab; -#endif -yyerrlab: - ++yynerrs; -yyinrecovery: - if (yyerrflag < 3) - { - yyerrflag = 3; - for (;;) - { - if ((yyn = yysindex[*yyssp]) != 0 && (yyn += YYERRCODE) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, error recovery shifting\ - to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); -#endif - if (yyssp >= yyss + yystacksize - 1) + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; { - goto yyoverflow; + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; } - *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; - goto yyloop; - } - else - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: error recovery discarding state %d\n", - YYPREFIX, *yyssp); -#endif - if (yyssp <= yyss) goto yyabort; - --yyssp; - --yyvsp; - } + } } } - else - { - if (yychar == 0) goto yyabort; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, error recovery discards token %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - yychar = (-1); - goto yyloop; - } -yyreduce: -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, reducing by rule %d (%s)\n", - YYPREFIX, yystate, yyn, yyrule[yyn]); -#endif - yym = yylen[yyn]; - yyval = yyvsp[1-yym]; - switch (yyn) - { -case 7: -{ - unsigned i; + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ + YYUSE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 6: +#line 284 "lev_comp.y" /* yacc.c:1646 */ + { if (fatal_error > 0) { (void) fprintf(stderr, - "%s : %d errors detected. No output created!\n", - fname, fatal_error); - } else { - maze.flags = yyvsp[-3].i; - (void) memcpy((genericptr_t)&(maze.init_lev), - (genericptr_t)&(init_lev), - sizeof(lev_init)); - maze.numpart = npart; - maze.parts = NewTab(mazepart, npart); - for(i=0;i 0) { - (void) fprintf(stderr, - "%s : %d errors detected. No output created!\n", - fname, fatal_error); - } else { - special_lev.flags = (long) yyvsp[-5].i; - (void) memcpy( - (genericptr_t)&(special_lev.init_lev), - (genericptr_t)&(init_lev), - sizeof(lev_init)); - special_lev.nroom = nrooms; - special_lev.rooms = NewTab(room, nrooms); - for(i=0; i 8) - yyerror("Level names limited to 8 characters."); - yyval.map = yyvsp[0].map; - special_lev.nrmonst = special_lev.nrobjects = 0; - n_mlist = n_olist = 0; - } -break; -case 10: -{ - /* in case we're processing multiple files, - explicitly clear any stale settings */ - (void) memset((genericptr_t) &init_lev, 0, - sizeof init_lev); - init_lev.init_present = FALSE; - yyval.i = 0; - } -break; -case 11: -{ - init_lev.init_present = TRUE; - init_lev.fg = what_map_char((char) yyvsp[-10].i); - if (init_lev.fg == INVALID_TYPE) - yyerror("Invalid foreground type."); - init_lev.bg = what_map_char((char) yyvsp[-8].i); - if (init_lev.bg == INVALID_TYPE) - yyerror("Invalid background type."); - init_lev.smoothed = yyvsp[-6].i; - init_lev.joined = yyvsp[-4].i; - if (init_lev.joined && - init_lev.fg != CORR && init_lev.fg != ROOM) - yyerror("Invalid foreground type for joined map."); - init_lev.lit = yyvsp[-2].i; - init_lev.walled = yyvsp[0].i; - init_lev.icedpools = FALSE; - yyval.i = 1; - } -break; -case 12: -{ - init_lev.init_present = TRUE; - init_lev.fg = what_map_char((char) yyvsp[-12].i); - if (init_lev.fg == INVALID_TYPE) - yyerror("Invalid foreground type."); - init_lev.bg = what_map_char((char) yyvsp[-10].i); - if (init_lev.bg == INVALID_TYPE) - yyerror("Invalid background type."); - init_lev.smoothed = yyvsp[-8].i; - init_lev.joined = yyvsp[-6].i; - if (init_lev.joined && - init_lev.fg != CORR && init_lev.fg != ROOM) - yyerror("Invalid foreground type for joined map."); - init_lev.lit = yyvsp[-4].i; - init_lev.walled = yyvsp[-2].i; - init_lev.icedpools = yyvsp[0].i; - yyval.i = 1; - } -break; -case 15: -{ - yyval.i = 0; - } -break; -case 16: -{ - yyval.i = lev_flags; - lev_flags = 0; /* clear for next user */ - } -break; -case 17: -{ - lev_flags |= yyvsp[-2].i; - } -break; -case 18: -{ - lev_flags |= yyvsp[0].i; - } -break; -case 21: -{ - int i, j; +#line 2475 "y.tab.c" /* yacc.c:1646 */ + break; - i = (int) strlen(yyvsp[0].map) + 1; - j = (int) strlen(tmpmessage); - if (i + j > 255) { - yyerror("Message string too long (>256 characters)"); - } else { - if (j) tmpmessage[j++] = '\n'; - (void) strncpy(tmpmessage+j, yyvsp[0].map, i - 1); - tmpmessage[j + i - 1] = 0; - } - Free(yyvsp[0].map); + case 8: +#line 311 "lev_comp.y" /* yacc.c:1646 */ + { + start_level_def(&splev, (yyvsp[-2].map)); + if ((yyvsp[0].i) == -1) { + add_opvars(splev, "iiiiiiiio", LVLINIT_MAZEGRID,HWALL,0,0, 0,0,0,0, SPO_INITLEVEL); + } else { + long bg = what_map_char((char) (yyvsp[0].i)); + add_opvars(splev, "iiiiiiiio", LVLINIT_SOLIDFILL, bg, 0,0, 0,0,0,0, SPO_INITLEVEL); + } + add_opvars(splev, "io", MAZELEVEL, SPO_LEVEL_FLAGS); + max_x_map = COLNO-1; + max_y_map = ROWNO; + (yyval.map) = (yyvsp[-2].map); } -break; -case 24: -{ - if(special_lev.nrobjects) { - yyerror("Object registers already initialized!"); - } else { - special_lev.nrobjects = n_olist; - special_lev.robjects = (char *) alloc(n_olist); - (void) memcpy((genericptr_t)special_lev.robjects, - (genericptr_t)olist, n_olist); - } +#line 2493 "y.tab.c" /* yacc.c:1646 */ + break; + + case 9: +#line 327 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = -1; } -break; -case 25: -{ - if(special_lev.nrmonst) { - yyerror("Monster registers already initialized!"); - } else { - special_lev.nrmonst = n_mlist; - special_lev.rmonst = (char *) alloc(n_mlist); - (void) memcpy((genericptr_t)special_lev.rmonst, - (genericptr_t)mlist, n_mlist); - } +#line 2501 "y.tab.c" /* yacc.c:1646 */ + break; + + case 10: +#line 331 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = what_map_char((char) (yyvsp[0].i)); } -break; -case 26: -{ - tmproom[nrooms] = New(room); - tmproom[nrooms]->name = (char *) 0; - tmproom[nrooms]->parent = (char *) 0; - tmproom[nrooms]->rtype = 0; - tmproom[nrooms]->rlit = 0; - tmproom[nrooms]->xalign = ERR; - tmproom[nrooms]->yalign = ERR; - tmproom[nrooms]->x = 0; - tmproom[nrooms]->y = 0; - tmproom[nrooms]->w = 2; - tmproom[nrooms]->h = 2; - in_room = 1; +#line 2509 "y.tab.c" /* yacc.c:1646 */ + break; + + case 11: +#line 337 "lev_comp.y" /* yacc.c:1646 */ + { + long filling = (yyvsp[0].terr).ter; + if (filling == INVALID_TYPE || filling >= MAX_TYPE) + lc_error("INIT_MAP: Invalid fill char type."); + add_opvars(splev, "iiiiiiiio", LVLINIT_SOLIDFILL,filling,0,(long)(yyvsp[0].terr).lit, 0,0,0,0, SPO_INITLEVEL); + max_x_map = COLNO-1; + max_y_map = ROWNO; } -break; -case 32: -{ - tmpcor[0] = New(corridor); - tmpcor[0]->src.room = -1; - ncorridor = 1; +#line 2522 "y.tab.c" /* yacc.c:1646 */ + break; + + case 12: +#line 346 "lev_comp.y" /* yacc.c:1646 */ + { + long filling = what_map_char((char) (yyvsp[0].i)); + if (filling == INVALID_TYPE || filling >= MAX_TYPE) + lc_error("INIT_MAP: Invalid fill char type."); + add_opvars(splev, "iiiiiiiio", LVLINIT_MAZEGRID,filling,0,0, 0,0,0,0, SPO_INITLEVEL); + max_x_map = COLNO-1; + max_y_map = ROWNO; } -break; -case 35: -{ - tmpcor[ncorridor] = New(corridor); - tmpcor[ncorridor]->src.room = yyvsp[-2].corpos.room; - tmpcor[ncorridor]->src.wall = yyvsp[-2].corpos.wall; - tmpcor[ncorridor]->src.door = yyvsp[-2].corpos.door; - tmpcor[ncorridor]->dest.room = yyvsp[0].corpos.room; - tmpcor[ncorridor]->dest.wall = yyvsp[0].corpos.wall; - tmpcor[ncorridor]->dest.door = yyvsp[0].corpos.door; - ncorridor++; - if (ncorridor >= MAX_OF_TYPE) { - yyerror("Too many corridors in level!"); - ncorridor--; - } +#line 2535 "y.tab.c" /* yacc.c:1646 */ + break; + + case 13: +#line 355 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiiiiiio", LVLINIT_ROGUE,0,0,0,0,0,0,0, SPO_INITLEVEL); } -break; -case 36: -{ - tmpcor[ncorridor] = New(corridor); - tmpcor[ncorridor]->src.room = yyvsp[-2].corpos.room; - tmpcor[ncorridor]->src.wall = yyvsp[-2].corpos.wall; - tmpcor[ncorridor]->src.door = yyvsp[-2].corpos.door; - tmpcor[ncorridor]->dest.room = -1; - tmpcor[ncorridor]->dest.wall = yyvsp[0].i; - ncorridor++; - if (ncorridor >= MAX_OF_TYPE) { - yyerror("Too many corridors in level!"); - ncorridor--; - } - } -break; -case 37: -{ - if ((unsigned) yyvsp[-5].i >= nrooms) - yyerror("Wrong room number!"); - yyval.corpos.room = yyvsp[-5].i; - yyval.corpos.wall = yyvsp[-3].i; - yyval.corpos.door = yyvsp[-1].i; - } -break; -case 38: -{ - store_room(); - } -break; -case 39: -{ - store_room(); - } -break; -case 40: -{ - tmproom[nrooms] = New(room); - tmproom[nrooms]->parent = yyvsp[-1].map; - tmproom[nrooms]->name = (char *) 0; - tmproom[nrooms]->rtype = yyvsp[-9].i; - tmproom[nrooms]->rlit = yyvsp[-7].i; - tmproom[nrooms]->filled = yyvsp[0].i; - tmproom[nrooms]->xalign = ERR; - tmproom[nrooms]->yalign = ERR; - tmproom[nrooms]->x = current_coord.x; - tmproom[nrooms]->y = current_coord.y; - tmproom[nrooms]->w = current_size.width; - tmproom[nrooms]->h = current_size.height; - in_room = 1; - } -break; -case 41: -{ - tmproom[nrooms] = New(room); - tmproom[nrooms]->name = (char *) 0; - tmproom[nrooms]->parent = (char *) 0; - tmproom[nrooms]->rtype = yyvsp[-9].i; - tmproom[nrooms]->rlit = yyvsp[-7].i; - tmproom[nrooms]->filled = yyvsp[0].i; - tmproom[nrooms]->xalign = current_align.x; - tmproom[nrooms]->yalign = current_align.y; - tmproom[nrooms]->x = current_coord.x; - tmproom[nrooms]->y = current_coord.y; - tmproom[nrooms]->w = current_size.width; - tmproom[nrooms]->h = current_size.height; - in_room = 1; - } -break; -case 42: -{ - yyval.i = 1; - } -break; -case 43: -{ - yyval.i = yyvsp[0].i; - } -break; -case 44: -{ - if ( yyvsp[-3].i < 1 || yyvsp[-3].i > 5 || - yyvsp[-1].i < 1 || yyvsp[-1].i > 5 ) { - yyerror("Room position should be between 1 & 5!"); - } else { - current_coord.x = yyvsp[-3].i; - current_coord.y = yyvsp[-1].i; - } - } -break; -case 45: -{ - current_coord.x = current_coord.y = ERR; - } -break; -case 46: -{ - if ( yyvsp[-3].i < 0 || yyvsp[-1].i < 0) { - yyerror("Invalid subroom position !"); - } else { - current_coord.x = yyvsp[-3].i; - current_coord.y = yyvsp[-1].i; - } - } -break; -case 47: -{ - current_coord.x = current_coord.y = ERR; - } -break; -case 48: -{ - current_align.x = yyvsp[-3].i; - current_align.y = yyvsp[-1].i; - } -break; -case 49: -{ - current_align.x = current_align.y = ERR; - } -break; -case 50: -{ - current_size.width = yyvsp[-3].i; - current_size.height = yyvsp[-1].i; - } -break; -case 51: -{ - current_size.height = current_size.width = ERR; - } -break; -case 67: -{ - if (tmproom[nrooms]->name) - yyerror("This room already has a name!"); - else - tmproom[nrooms]->name = yyvsp[0].map; - } -break; -case 68: -{ - if (tmproom[nrooms]->chance) - yyerror("This room already assigned a chance!"); - else if (tmproom[nrooms]->rtype == OROOM) - yyerror("Only typed rooms can have a chance!"); - else if (yyvsp[0].i < 1 || yyvsp[0].i > 99) - yyerror("The chance is supposed to be percentile."); - else - tmproom[nrooms]->chance = yyvsp[0].i; - } -break; -case 69: -{ - /* ERR means random here */ - if (yyvsp[-2].i == ERR && yyvsp[0].i != ERR) { - yyerror("If the door wall is random, so must be its pos!"); - } else { - tmprdoor[ndoor] = New(room_door); - tmprdoor[ndoor]->secret = yyvsp[-6].i; - tmprdoor[ndoor]->mask = yyvsp[-4].i; - tmprdoor[ndoor]->wall = yyvsp[-2].i; - tmprdoor[ndoor]->pos = yyvsp[0].i; - ndoor++; - if (ndoor >= MAX_OF_TYPE) { - yyerror("Too many doors in room!"); - ndoor--; - } - } - } -break; -case 76: -{ - maze.filling = (schar) yyvsp[0].i; - if (index(yyvsp[-2].map, '.')) - yyerror("Invalid dot ('.') in level name."); - if ((int) strlen(yyvsp[-2].map) > 8) - yyerror("Level names limited to 8 characters."); - yyval.map = yyvsp[-2].map; - in_room = 0; - n_plist = n_mlist = n_olist = 0; - } -break; -case 77: -{ - yyval.i = get_floor_type((char)yyvsp[0].i); - } -break; -case 78: -{ - yyval.i = -1; - } -break; -case 81: -{ - store_part(); - } -break; -case 82: -{ - tmppart[npart] = New(mazepart); - tmppart[npart]->halign = 1; - tmppart[npart]->valign = 1; - tmppart[npart]->nrobjects = 0; - tmppart[npart]->nloc = 0; - tmppart[npart]->nrmonst = 0; - tmppart[npart]->xsize = 1; - tmppart[npart]->ysize = 1; - tmppart[npart]->map = (char **) alloc(sizeof(char *)); - tmppart[npart]->map[0] = (char *) alloc(1); - tmppart[npart]->map[0][0] = STONE; +#line 2543 "y.tab.c" /* yacc.c:1646 */ + break; + + case 14: +#line 359 "lev_comp.y" /* yacc.c:1646 */ + { + long fg = what_map_char((char) (yyvsp[-11].i)); + long bg = what_map_char((char) (yyvsp[-9].i)); + long smoothed = (yyvsp[-7].i); + long joined = (yyvsp[-5].i); + long lit = (yyvsp[-3].i); + long walled = (yyvsp[-1].i); + long filling = (yyvsp[0].i); + if (fg == INVALID_TYPE || fg >= MAX_TYPE) + lc_error("INIT_MAP: Invalid foreground type."); + if (bg == INVALID_TYPE || bg >= MAX_TYPE) + lc_error("INIT_MAP: Invalid background type."); + if (joined && fg != CORR && fg != ROOM) + lc_error("INIT_MAP: Invalid foreground type for joined map."); + + if (filling == INVALID_TYPE) + lc_error("INIT_MAP: Invalid fill char type."); + + add_opvars(splev, "iiiiiiiio", LVLINIT_MINES,filling,walled,lit, joined,smoothed,bg,fg, SPO_INITLEVEL); max_x_map = COLNO-1; max_y_map = ROWNO; } -break; -case 83: -{ - tmppart[npart] = New(mazepart); - tmppart[npart]->halign = yyvsp[-1].i % 10; - tmppart[npart]->valign = yyvsp[-1].i / 10; - tmppart[npart]->nrobjects = 0; - tmppart[npart]->nloc = 0; - tmppart[npart]->nrmonst = 0; - scan_map(yyvsp[0].map); - Free(yyvsp[0].map); - } -break; -case 84: -{ - yyval.i = yyvsp[-2].i + (yyvsp[0].i * 10); - } -break; -case 91: -{ - if (tmppart[npart]->nrobjects) { - yyerror("Object registers already initialized!"); - } else { - tmppart[npart]->robjects = (char *)alloc(n_olist); - (void) memcpy((genericptr_t)tmppart[npart]->robjects, - (genericptr_t)olist, n_olist); - tmppart[npart]->nrobjects = n_olist; - } - } -break; -case 92: -{ - if (tmppart[npart]->nloc) { - yyerror("Location registers already initialized!"); - } else { - register int i; - tmppart[npart]->rloc_x = (char *) alloc(n_plist); - tmppart[npart]->rloc_y = (char *) alloc(n_plist); - for(i=0;irloc_x[i] = plist[i].x; - tmppart[npart]->rloc_y[i] = plist[i].y; - } - tmppart[npart]->nloc = n_plist; - } - } -break; -case 93: -{ - if (tmppart[npart]->nrmonst) { - yyerror("Monster registers already initialized!"); - } else { - tmppart[npart]->rmonst = (char *) alloc(n_mlist); - (void) memcpy((genericptr_t)tmppart[npart]->rmonst, - (genericptr_t)mlist, n_mlist); - tmppart[npart]->nrmonst = n_mlist; - } - } -break; -case 94: -{ - if (n_olist < MAX_REGISTERS) - olist[n_olist++] = yyvsp[0].i; - else - yyerror("Object list too long!"); - } -break; -case 95: -{ - if (n_olist < MAX_REGISTERS) - olist[n_olist++] = yyvsp[-2].i; - else - yyerror("Object list too long!"); - } -break; -case 96: -{ - if (n_mlist < MAX_REGISTERS) - mlist[n_mlist++] = yyvsp[0].i; - else - yyerror("Monster list too long!"); - } -break; -case 97: -{ - if (n_mlist < MAX_REGISTERS) - mlist[n_mlist++] = yyvsp[-2].i; - else - yyerror("Monster list too long!"); - } -break; -case 98: -{ - if (n_plist < MAX_REGISTERS) - plist[n_plist++] = current_coord; - else - yyerror("Location list too long!"); - } -break; -case 99: -{ - if (n_plist < MAX_REGISTERS) - plist[n_plist++] = current_coord; - else - yyerror("Location list too long!"); - } -break; -case 123: -{ - tmpmonst[nmons] = New(monster); - tmpmonst[nmons]->x = current_coord.x; - tmpmonst[nmons]->y = current_coord.y; - tmpmonst[nmons]->class = yyvsp[-4].i; - tmpmonst[nmons]->peaceful = -1; /* no override */ - tmpmonst[nmons]->asleep = -1; - tmpmonst[nmons]->align = - MAX_REGISTERS - 2; - tmpmonst[nmons]->name.str = 0; - tmpmonst[nmons]->appear = 0; - tmpmonst[nmons]->appear_as.str = 0; - tmpmonst[nmons]->chance = yyvsp[-6].i; - tmpmonst[nmons]->id = NON_PM; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Monster"); - if (yyvsp[-2].map) { - int token = get_monster_id(yyvsp[-2].map, (char) yyvsp[-4].i); - if (token == ERR) - yywarning( - "Invalid monster name! Making random monster."); - else - tmpmonst[nmons]->id = token; - Free(yyvsp[-2].map); - } - } -break; -case 124: -{ - if (++nmons >= MAX_OF_TYPE) { - yyerror("Too many monsters in room or mazepart!"); - nmons--; - } - } -break; -case 127: -{ - tmpmonst[nmons]->name.str = yyvsp[0].map; - } -break; -case 128: -{ - tmpmonst[nmons]->peaceful = yyvsp[0].i; - } -break; -case 129: -{ - tmpmonst[nmons]->asleep = yyvsp[0].i; - } -break; -case 130: -{ - tmpmonst[nmons]->align = yyvsp[0].i; - } -break; -case 131: -{ - tmpmonst[nmons]->appear = yyvsp[-1].i; - tmpmonst[nmons]->appear_as.str = yyvsp[0].map; - } -break; -case 132: -{ - } -break; -case 133: -{ - /* 1: is contents of preceeding object with 2 */ - /* 2: is a container */ - /* 0: neither */ - tmpobj[nobj-1]->containment = 2; - } -break; -case 134: -{ - tmpobj[nobj] = New(object); - tmpobj[nobj]->class = yyvsp[-2].i; - tmpobj[nobj]->corpsenm = NON_PM; - tmpobj[nobj]->curse_state = -1; - tmpobj[nobj]->name.str = 0; - tmpobj[nobj]->chance = yyvsp[-4].i; - tmpobj[nobj]->id = -1; - if (yyvsp[0].map) { - int token = get_object_id(yyvsp[0].map, yyvsp[-2].i); - if (token == ERR) - yywarning( - "Illegal object name! Making random object."); - else - tmpobj[nobj]->id = token; - Free(yyvsp[0].map); - } - } -break; -case 135: -{ - if (++nobj >= MAX_OF_TYPE) { - yyerror("Too many objects in room or mazepart!"); - nobj--; - } - } -break; -case 136: -{ - tmpobj[nobj]->containment = 0; - tmpobj[nobj]->x = current_coord.x; - tmpobj[nobj]->y = current_coord.y; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Object"); - } -break; -case 137: -{ - tmpobj[nobj]->containment = 1; - /* random coordinate, will be overridden anyway */ - tmpobj[nobj]->x = -MAX_REGISTERS-1; - tmpobj[nobj]->y = -MAX_REGISTERS-1; - } -break; -case 138: -{ - tmpobj[nobj]->spe = -127; - /* Note below: we're trying to make as many of these optional as - * possible. We clearly can't make curse_state, enchantment, and - * monster_id _all_ optional, since ",random" would be ambiguous. - * We can't even just make enchantment mandatory, since if we do that - * alone, ",random" requires too much lookahead to parse. - */ - } -break; -case 139: -{ - } -break; -case 140: -{ - } -break; -case 141: -{ - } -break; -case 142: -{ - tmpobj[nobj]->curse_state = -1; - } -break; -case 143: -{ - tmpobj[nobj]->curse_state = yyvsp[0].i; - } -break; -case 144: -{ - int token = get_monster_id(yyvsp[0].map, (char)0); - if (token == ERR) /* "random" */ - tmpobj[nobj]->corpsenm = NON_PM - 1; - else - tmpobj[nobj]->corpsenm = token; - Free(yyvsp[0].map); - } -break; -case 145: -{ - tmpobj[nobj]->spe = -127; - } -break; -case 146: -{ - tmpobj[nobj]->spe = yyvsp[0].i; - } -break; -case 148: -{ - } -break; -case 149: -{ - tmpobj[nobj]->name.str = yyvsp[0].map; - } -break; -case 150: -{ - tmpdoor[ndoor] = New(door); - tmpdoor[ndoor]->x = current_coord.x; - tmpdoor[ndoor]->y = current_coord.y; - tmpdoor[ndoor]->mask = yyvsp[-2].i; - if(current_coord.x >= 0 && current_coord.y >= 0 && - tmpmap[current_coord.y][current_coord.x] != DOOR && - tmpmap[current_coord.y][current_coord.x] != SDOOR) - yyerror("Door decl doesn't match the map"); - ndoor++; - if (ndoor >= MAX_OF_TYPE) { - yyerror("Too many doors in mazepart!"); - ndoor--; - } - } -break; -case 151: -{ - tmptrap[ntrap] = New(trap); - tmptrap[ntrap]->x = current_coord.x; - tmptrap[ntrap]->y = current_coord.y; - tmptrap[ntrap]->type = yyvsp[-2].i; - tmptrap[ntrap]->chance = yyvsp[-4].i; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Trap"); - if (++ntrap >= MAX_OF_TYPE) { - yyerror("Too many traps in room or mazepart!"); - ntrap--; - } - } -break; -case 152: -{ - int x, y, dir; +#line 2570 "y.tab.c" /* yacc.c:1646 */ + break; - tmpdb[ndb] = New(drawbridge); - x = tmpdb[ndb]->x = current_coord.x; - y = tmpdb[ndb]->y = current_coord.y; - /* convert dir from a DIRECTION to a DB_DIR */ - dir = yyvsp[-2].i; - switch(dir) { - case W_NORTH: dir = DB_NORTH; y--; break; - case W_SOUTH: dir = DB_SOUTH; y++; break; - case W_EAST: dir = DB_EAST; x++; break; - case W_WEST: dir = DB_WEST; x--; break; - default: - yyerror("Invalid drawbridge direction"); - break; - } - tmpdb[ndb]->dir = dir; - if (current_coord.x >= 0 && current_coord.y >= 0 && - !IS_WALL(tmpmap[y][x])) { - char ebuf[60]; - Sprintf(ebuf, - "Wall needed for drawbridge (%02d, %02d)", - current_coord.x, current_coord.y); - yyerror(ebuf); - } + case 15: +#line 384 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 0; + } +#line 2578 "y.tab.c" /* yacc.c:1646 */ + break; - if ( yyvsp[0].i == D_ISOPEN ) - tmpdb[ndb]->db_open = 1; - else if ( yyvsp[0].i == D_CLOSED ) - tmpdb[ndb]->db_open = 0; - else if (yyvsp[0].i == -1) /* RANDOM_TYPE */ - tmpdb[ndb]->db_open = 127; /* random */ - else - yyerror("A drawbridge can only be open, closed, or random!"); - ndb++; - if (ndb >= MAX_OF_TYPE) { - yyerror("Too many drawbridges in mazepart!"); - ndb--; + case 16: +#line 388 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); + } +#line 2586 "y.tab.c" /* yacc.c:1646 */ + break; + + case 17: +#line 394 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_COPY); + (yyval.i) = 0; + } +#line 2595 "y.tab.c" /* yacc.c:1646 */ + break; + + case 18: +#line 399 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 1; + } +#line 2603 "y.tab.c" /* yacc.c:1646 */ + break; + + case 19: +#line 405 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = -1; + } +#line 2611 "y.tab.c" /* yacc.c:1646 */ + break; + + case 20: +#line 409 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = what_map_char((char) (yyvsp[0].i)); + } +#line 2619 "y.tab.c" /* yacc.c:1646 */ + break; + + case 23: +#line 420 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", 0, SPO_LEVEL_FLAGS); + } +#line 2627 "y.tab.c" /* yacc.c:1646 */ + break; + + case 24: +#line 424 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", (yyvsp[0].i), SPO_LEVEL_FLAGS); + } +#line 2635 "y.tab.c" /* yacc.c:1646 */ + break; + + case 25: +#line 430 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = ((yyvsp[-2].i) | (yyvsp[0].i)); + } +#line 2643 "y.tab.c" /* yacc.c:1646 */ + break; + + case 26: +#line 434 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); + } +#line 2651 "y.tab.c" /* yacc.c:1646 */ + break; + + case 27: +#line 440 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 0; + } +#line 2659 "y.tab.c" /* yacc.c:1646 */ + break; + + case 28: +#line 444 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 1 + (yyvsp[0].i); + } +#line 2667 "y.tab.c" /* yacc.c:1646 */ + break; + + case 29: +#line 450 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[-1].i); + } +#line 2675 "y.tab.c" /* yacc.c:1646 */ + break; + + case 97: +#line 533 "lev_comp.y" /* yacc.c:1646 */ + { + struct lc_vardefs *vd; + if ((vd = vardef_defined(variable_definitions, (yyvsp[0].map), 1))) { + if (!(vd->var_type & SPOVAR_ARRAY)) + lc_error("Trying to shuffle non-array variable '%s'", (yyvsp[0].map)); + } else lc_error("Trying to shuffle undefined variable '%s'", (yyvsp[0].map)); + add_opvars(splev, "so", (yyvsp[0].map), SPO_SHUFFLE_ARRAY); + Free((yyvsp[0].map)); + } +#line 2689 "y.tab.c" /* yacc.c:1646 */ + break; + + case 98: +#line 545 "lev_comp.y" /* yacc.c:1646 */ + { + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-2].map), SPOVAR_INT); + add_opvars(splev, "iso", 0, (yyvsp[-2].map), SPO_VAR_INIT); + Free((yyvsp[-2].map)); + } +#line 2699 "y.tab.c" /* yacc.c:1646 */ + break; + + case 99: +#line 551 "lev_comp.y" /* yacc.c:1646 */ + { + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-4].map), SPOVAR_SEL); + add_opvars(splev, "iso", 0, (yyvsp[-4].map), SPO_VAR_INIT); + Free((yyvsp[-4].map)); + } +#line 2709 "y.tab.c" /* yacc.c:1646 */ + break; + + case 100: +#line 557 "lev_comp.y" /* yacc.c:1646 */ + { + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-2].map), SPOVAR_STRING); + add_opvars(splev, "iso", 0, (yyvsp[-2].map), SPO_VAR_INIT); + Free((yyvsp[-2].map)); + } +#line 2719 "y.tab.c" /* yacc.c:1646 */ + break; + + case 101: +#line 563 "lev_comp.y" /* yacc.c:1646 */ + { + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-4].map), SPOVAR_MAPCHAR); + add_opvars(splev, "iso", 0, (yyvsp[-4].map), SPO_VAR_INIT); + Free((yyvsp[-4].map)); + } +#line 2729 "y.tab.c" /* yacc.c:1646 */ + break; + + case 102: +#line 569 "lev_comp.y" /* yacc.c:1646 */ + { + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-4].map), SPOVAR_MONST); + add_opvars(splev, "iso", 0, (yyvsp[-4].map), SPO_VAR_INIT); + Free((yyvsp[-4].map)); + } +#line 2739 "y.tab.c" /* yacc.c:1646 */ + break; + + case 103: +#line 575 "lev_comp.y" /* yacc.c:1646 */ + { + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-4].map), SPOVAR_OBJ); + add_opvars(splev, "iso", 0, (yyvsp[-4].map), SPO_VAR_INIT); + Free((yyvsp[-4].map)); + } +#line 2749 "y.tab.c" /* yacc.c:1646 */ + break; + + case 104: +#line 581 "lev_comp.y" /* yacc.c:1646 */ + { + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-2].map), SPOVAR_COORD); + add_opvars(splev, "iso", 0, (yyvsp[-2].map), SPO_VAR_INIT); + Free((yyvsp[-2].map)); + } +#line 2759 "y.tab.c" /* yacc.c:1646 */ + break; + + case 105: +#line 587 "lev_comp.y" /* yacc.c:1646 */ + { + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-2].map), SPOVAR_REGION); + add_opvars(splev, "iso", 0, (yyvsp[-2].map), SPO_VAR_INIT); + Free((yyvsp[-2].map)); + } +#line 2769 "y.tab.c" /* yacc.c:1646 */ + break; + + case 106: +#line 593 "lev_comp.y" /* yacc.c:1646 */ + { + long n_items = (yyvsp[-1].i); + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-4].map), SPOVAR_INT|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, (yyvsp[-4].map), SPO_VAR_INIT); + Free((yyvsp[-4].map)); + } +#line 2780 "y.tab.c" /* yacc.c:1646 */ + break; + + case 107: +#line 600 "lev_comp.y" /* yacc.c:1646 */ + { + long n_items = (yyvsp[-1].i); + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-4].map), SPOVAR_COORD|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, (yyvsp[-4].map), SPO_VAR_INIT); + Free((yyvsp[-4].map)); + } +#line 2791 "y.tab.c" /* yacc.c:1646 */ + break; + + case 108: +#line 607 "lev_comp.y" /* yacc.c:1646 */ + { + long n_items = (yyvsp[-1].i); + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-4].map), SPOVAR_REGION|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, (yyvsp[-4].map), SPO_VAR_INIT); + Free((yyvsp[-4].map)); + } +#line 2802 "y.tab.c" /* yacc.c:1646 */ + break; + + case 109: +#line 614 "lev_comp.y" /* yacc.c:1646 */ + { + long n_items = (yyvsp[-1].i); + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-6].map), SPOVAR_MAPCHAR|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, (yyvsp[-6].map), SPO_VAR_INIT); + Free((yyvsp[-6].map)); + } +#line 2813 "y.tab.c" /* yacc.c:1646 */ + break; + + case 110: +#line 621 "lev_comp.y" /* yacc.c:1646 */ + { + long n_items = (yyvsp[-1].i); + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-6].map), SPOVAR_MONST|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, (yyvsp[-6].map), SPO_VAR_INIT); + Free((yyvsp[-6].map)); + } +#line 2824 "y.tab.c" /* yacc.c:1646 */ + break; + + case 111: +#line 628 "lev_comp.y" /* yacc.c:1646 */ + { + long n_items = (yyvsp[-1].i); + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-6].map), SPOVAR_OBJ|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, (yyvsp[-6].map), SPO_VAR_INIT); + Free((yyvsp[-6].map)); + } +#line 2835 "y.tab.c" /* yacc.c:1646 */ + break; + + case 112: +#line 635 "lev_comp.y" /* yacc.c:1646 */ + { + long n_items = (yyvsp[-1].i); + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-4].map), SPOVAR_STRING|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, (yyvsp[-4].map), SPO_VAR_INIT); + Free((yyvsp[-4].map)); + } +#line 2846 "y.tab.c" /* yacc.c:1646 */ + break; + + case 113: +#line 644 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "O", (yyvsp[0].i)); + (yyval.i) = 1; + } +#line 2855 "y.tab.c" /* yacc.c:1646 */ + break; + + case 114: +#line 649 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "O", (yyvsp[0].i)); + (yyval.i) = 1 + (yyvsp[-2].i); + } +#line 2864 "y.tab.c" /* yacc.c:1646 */ + break; + + case 115: +#line 656 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "M", (yyvsp[0].i)); + (yyval.i) = 1; + } +#line 2873 "y.tab.c" /* yacc.c:1646 */ + break; + + case 116: +#line 661 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "M", (yyvsp[0].i)); + (yyval.i) = 1 + (yyvsp[-2].i); + } +#line 2882 "y.tab.c" /* yacc.c:1646 */ + break; + + case 117: +#line 668 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "m", (yyvsp[0].i)); + (yyval.i) = 1; + } +#line 2891 "y.tab.c" /* yacc.c:1646 */ + break; + + case 118: +#line 673 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "m", (yyvsp[0].i)); + (yyval.i) = 1 + (yyvsp[-2].i); + } +#line 2900 "y.tab.c" /* yacc.c:1646 */ + break; + + case 119: +#line 680 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 1; + } +#line 2908 "y.tab.c" /* yacc.c:1646 */ + break; + + case 120: +#line 684 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 1 + (yyvsp[-2].i); + } +#line 2916 "y.tab.c" /* yacc.c:1646 */ + break; + + case 121: +#line 690 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "c", (yyvsp[0].i)); + (yyval.i) = 1; + } +#line 2925 "y.tab.c" /* yacc.c:1646 */ + break; + + case 122: +#line 695 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "c", (yyvsp[0].i)); + (yyval.i) = 1 + (yyvsp[-2].i); + } +#line 2934 "y.tab.c" /* yacc.c:1646 */ + break; + + case 123: +#line 702 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 1; + } +#line 2942 "y.tab.c" /* yacc.c:1646 */ + break; + + case 124: +#line 706 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 1 + (yyvsp[-2].i); + } +#line 2950 "y.tab.c" /* yacc.c:1646 */ + break; + + case 125: +#line 712 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 1; + } +#line 2958 "y.tab.c" /* yacc.c:1646 */ + break; + + case 126: +#line 716 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 1 + (yyvsp[-2].i); + } +#line 2966 "y.tab.c" /* yacc.c:1646 */ + break; + + case 127: +#line 722 "lev_comp.y" /* yacc.c:1646 */ + { + struct lc_funcdefs *funcdef; + + if (in_function_definition) + lc_error("Recursively defined functions not allowed (function %s).", (yyvsp[-1].map)); + + in_function_definition++; + + if (funcdef_defined(function_definitions, (yyvsp[-1].map), 1)) + lc_error("Function '%s' already defined once.", (yyvsp[-1].map)); + + funcdef = funcdef_new(-1, (yyvsp[-1].map)); + funcdef->next = function_definitions; + function_definitions = funcdef; + function_splev_backup = splev; + splev = &(funcdef->code); + Free((yyvsp[-1].map)); + curr_function = funcdef; + function_tmp_var_defs = variable_definitions; + variable_definitions = NULL; + } +#line 2992 "y.tab.c" /* yacc.c:1646 */ + break; + + case 128: +#line 744 "lev_comp.y" /* yacc.c:1646 */ + { + /* nothing */ + } +#line 3000 "y.tab.c" /* yacc.c:1646 */ + break; + + case 129: +#line 748 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", 0, SPO_RETURN); + splev = function_splev_backup; + in_function_definition--; + curr_function = NULL; + vardef_free_all(variable_definitions); + variable_definitions = function_tmp_var_defs; + } +#line 3013 "y.tab.c" /* yacc.c:1646 */ + break; + + case 130: +#line 759 "lev_comp.y" /* yacc.c:1646 */ + { + struct lc_funcdefs *tmpfunc; + tmpfunc = funcdef_defined(function_definitions, (yyvsp[-3].map), 1); + if (tmpfunc) { + long l; + long nparams = strlen( (yyvsp[-1].map) ); + char *fparamstr = funcdef_paramtypes(tmpfunc); + if (strcmp((yyvsp[-1].map), fparamstr)) { + char *tmps = strdup(decode_parm_str(fparamstr)); + lc_error("Function '%s' requires params '%s', got '%s' instead.", (yyvsp[-3].map), tmps, decode_parm_str((yyvsp[-1].map))); + Free(tmps); + } + Free(fparamstr); + Free((yyvsp[-1].map)); + if (!(tmpfunc->n_called)) { + /* we haven't called the function yet, so insert it in the code */ + struct opvar *jmp = New(struct opvar); + set_opvar_int(jmp, splev->n_opcodes+1); + add_opcode(splev, SPO_PUSH, jmp); + add_opcode(splev, SPO_JMP, NULL); /* we must jump past it first, then CALL it, due to RETURN. */ + + tmpfunc->addr = splev->n_opcodes; + + { /* init function parameter variables */ + struct lc_funcdefs_parm *tfp = tmpfunc->params; + while (tfp) { + add_opvars(splev, "iso", 0, tfp->name, SPO_VAR_INIT); + tfp = tfp->next; + } + } + + splev_add_from(splev, &(tmpfunc->code)); + set_opvar_int(jmp, splev->n_opcodes - jmp->vardata.l); + } + l = tmpfunc->addr - splev->n_opcodes - 2; + add_opvars(splev, "iio", nparams, l, SPO_CALL); + tmpfunc->n_called++; + } else { + lc_error("Function '%s' not defined.", (yyvsp[-3].map)); + } + Free((yyvsp[-3].map)); + } +#line 3060 "y.tab.c" /* yacc.c:1646 */ + break; + + case 131: +#line 804 "lev_comp.y" /* yacc.c:1646 */ + { + add_opcode(splev, SPO_EXIT, NULL); + } +#line 3068 "y.tab.c" /* yacc.c:1646 */ + break; + + case 132: +#line 810 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 100; + } +#line 3076 "y.tab.c" /* yacc.c:1646 */ + break; + + case 133: +#line 814 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); + } +#line 3084 "y.tab.c" /* yacc.c:1646 */ + break; + + case 134: +#line 820 "lev_comp.y" /* yacc.c:1646 */ + { + /* val > rn2(100) */ + add_opvars(splev, "iio", (long)(yyvsp[0].i), 100, SPO_RN2); + (yyval.i) = SPO_JG; + } +#line 3094 "y.tab.c" /* yacc.c:1646 */ + break; + + case 135: +#line 826 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[-2].i); + } +#line 3102 "y.tab.c" /* yacc.c:1646 */ + break; + + case 136: +#line 830 "lev_comp.y" /* yacc.c:1646 */ + { + /* boolean, explicit foo != 0 */ + add_opvars(splev, "i", 0); + (yyval.i) = SPO_JNE; + } +#line 3112 "y.tab.c" /* yacc.c:1646 */ + break; + + case 137: +#line 838 "lev_comp.y" /* yacc.c:1646 */ + { + is_inconstant_number = 0; + } +#line 3120 "y.tab.c" /* yacc.c:1646 */ + break; + + case 138: +#line 842 "lev_comp.y" /* yacc.c:1646 */ + { + struct opvar *chkjmp; + if (in_switch_statement > 0) + lc_error("Cannot nest switch-statements."); + + in_switch_statement++; + + n_switch_case_list = 0; + switch_default_case = NULL; + + if (!is_inconstant_number) + add_opvars(splev, "o", SPO_RN2); + is_inconstant_number = 0; + + chkjmp = New(struct opvar); + set_opvar_int(chkjmp, splev->n_opcodes+1); + switch_check_jump = chkjmp; + add_opcode(splev, SPO_PUSH, chkjmp); + add_opcode(splev, SPO_JMP, NULL); + break_stmt_start(); + } +#line 3146 "y.tab.c" /* yacc.c:1646 */ + break; + + case 139: +#line 864 "lev_comp.y" /* yacc.c:1646 */ + { + struct opvar *endjump = New(struct opvar); + int i; + + set_opvar_int(endjump, splev->n_opcodes+1); + + add_opcode(splev, SPO_PUSH, endjump); + add_opcode(splev, SPO_JMP, NULL); + + set_opvar_int(switch_check_jump, splev->n_opcodes - switch_check_jump->vardata.l); + + for (i = 0; i < n_switch_case_list; i++) { + add_opvars(splev, "oio", SPO_COPY, switch_case_value[i], SPO_CMP); + set_opvar_int(switch_case_list[i], switch_case_list[i]->vardata.l - splev->n_opcodes-1); + add_opcode(splev, SPO_PUSH, switch_case_list[i]); + add_opcode(splev, SPO_JE, NULL); + } + + if (switch_default_case) { + set_opvar_int(switch_default_case, switch_default_case->vardata.l - splev->n_opcodes-1); + add_opcode(splev, SPO_PUSH, switch_default_case); + add_opcode(splev, SPO_JMP, NULL); + } + + set_opvar_int(endjump, splev->n_opcodes - endjump->vardata.l); + + break_stmt_end(splev); + + add_opcode(splev, SPO_POP, NULL); /* get rid of the value in stack */ + in_switch_statement--; + + + } +#line 3184 "y.tab.c" /* yacc.c:1646 */ + break; + + case 142: +#line 904 "lev_comp.y" /* yacc.c:1646 */ + { + if (n_switch_case_list < MAX_SWITCH_CASES) { + struct opvar *tmppush = New(struct opvar); + set_opvar_int(tmppush, splev->n_opcodes); + switch_case_value[n_switch_case_list] = (yyvsp[-1].i); + switch_case_list[n_switch_case_list++] = tmppush; + } else lc_error("Too many cases in a switch."); + } +#line 3197 "y.tab.c" /* yacc.c:1646 */ + break; + + case 143: +#line 913 "lev_comp.y" /* yacc.c:1646 */ + { + } +#line 3204 "y.tab.c" /* yacc.c:1646 */ + break; + + case 144: +#line 916 "lev_comp.y" /* yacc.c:1646 */ + { + struct opvar *tmppush = New(struct opvar); + + if (switch_default_case) + lc_error("Switch default case already used."); + + set_opvar_int(tmppush, splev->n_opcodes); + switch_default_case = tmppush; + } +#line 3218 "y.tab.c" /* yacc.c:1646 */ + break; + + case 145: +#line 926 "lev_comp.y" /* yacc.c:1646 */ + { + } +#line 3225 "y.tab.c" /* yacc.c:1646 */ + break; + + case 146: +#line 931 "lev_comp.y" /* yacc.c:1646 */ + { + if (!allow_break_statements) + lc_error("Cannot use BREAK outside a statement block."); + else { + break_stmt_new(splev, splev->n_opcodes); + } + } +#line 3237 "y.tab.c" /* yacc.c:1646 */ + break; + + case 149: +#line 945 "lev_comp.y" /* yacc.c:1646 */ + { + char buf[256], buf2[256]; + + if (n_forloops >= MAX_NESTED_IFS) { + lc_error("FOR: Too deeply nested loops."); + n_forloops = MAX_NESTED_IFS - 1; + } + + /* first, define a variable for the for-loop end value */ + snprintf(buf, 255, "%s end", (yyvsp[-4].map)); + /* the value of which is already in stack (the 2nd math_expr) */ + add_opvars(splev, "iso", 0, buf, SPO_VAR_INIT); + + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-4].map), SPOVAR_INT); + /* define the for-loop variable. value is in stack (1st math_expr) */ + add_opvars(splev, "iso", 0, (yyvsp[-4].map), SPO_VAR_INIT); + + /* calculate value for the loop "step" variable */ + snprintf(buf2, 255, "%s step", (yyvsp[-4].map)); + add_opvars(splev, "vvo", buf, (yyvsp[-4].map), SPO_MATH_SUB); /* end - start */ + add_opvars(splev, "o", SPO_MATH_SIGN); /* sign of that */ + add_opvars(splev, "iso", 0, buf2, SPO_VAR_INIT); /* save the sign into the step var */ + + forloop_list[n_forloops].varname = strdup((yyvsp[-4].map)); + forloop_list[n_forloops].jmp_point = splev->n_opcodes; + + n_forloops++; + Free((yyvsp[-4].map)); + } +#line 3271 "y.tab.c" /* yacc.c:1646 */ + break; + + case 150: +#line 977 "lev_comp.y" /* yacc.c:1646 */ + { + /* nothing */ + break_stmt_start(); + } +#line 3280 "y.tab.c" /* yacc.c:1646 */ + break; + + case 151: +#line 982 "lev_comp.y" /* yacc.c:1646 */ + { + char buf[256], buf2[256]; + n_forloops--; + snprintf(buf, 255, "%s step", forloop_list[n_forloops].varname); + snprintf(buf2, 255, "%s end", forloop_list[n_forloops].varname); + /* compare for-loop var to end value */ + add_opvars(splev, "vvo", forloop_list[n_forloops].varname, buf2, SPO_CMP); + /* var + step */ + add_opvars(splev, "vvo", buf, + forloop_list[n_forloops].varname, SPO_MATH_ADD); + /* for-loop var = (for-loop var + step) */ + add_opvars(splev, "iso", 0, forloop_list[n_forloops].varname, SPO_VAR_INIT); + /* jump back if compared values were not equal */ + add_opvars(splev, "io", forloop_list[n_forloops].jmp_point - splev->n_opcodes - 1, SPO_JNE); + Free(forloop_list[n_forloops].varname); + break_stmt_end(splev); + } +#line 3302 "y.tab.c" /* yacc.c:1646 */ + break; + + case 152: +#line 1002 "lev_comp.y" /* yacc.c:1646 */ + { + struct opvar *tmppush = New(struct opvar); + + if (n_if_list >= MAX_NESTED_IFS) { + lc_error("LOOP: Too deeply nested conditionals."); + n_if_list = MAX_NESTED_IFS - 1; + } + set_opvar_int(tmppush, splev->n_opcodes); + if_list[n_if_list++] = tmppush; + + add_opvars(splev, "o", SPO_DEC); + break_stmt_start(); + } +#line 3320 "y.tab.c" /* yacc.c:1646 */ + break; + + case 153: +#line 1016 "lev_comp.y" /* yacc.c:1646 */ + { + struct opvar *tmppush; + + add_opvars(splev, "oio", SPO_COPY, 0, SPO_CMP); + + tmppush = (struct opvar *) if_list[--n_if_list]; + set_opvar_int(tmppush, tmppush->vardata.l - splev->n_opcodes-1); + add_opcode(splev, SPO_PUSH, tmppush); + add_opcode(splev, SPO_JG, NULL); + add_opcode(splev, SPO_POP, NULL); /* get rid of the count value in stack */ + break_stmt_end(splev); + } +#line 3337 "y.tab.c" /* yacc.c:1646 */ + break; + + case 154: +#line 1031 "lev_comp.y" /* yacc.c:1646 */ + { + struct opvar *tmppush2 = New(struct opvar); + + if (n_if_list >= MAX_NESTED_IFS) { + lc_error("IF: Too deeply nested conditionals."); + n_if_list = MAX_NESTED_IFS - 1; + } + + add_opcode(splev, SPO_CMP, NULL); + + set_opvar_int(tmppush2, splev->n_opcodes+1); + + if_list[n_if_list++] = tmppush2; + + add_opcode(splev, SPO_PUSH, tmppush2); + + add_opcode(splev, reverse_jmp_opcode( (yyvsp[-1].i) ), NULL); + + } +#line 3361 "y.tab.c" /* yacc.c:1646 */ + break; + + case 155: +#line 1051 "lev_comp.y" /* yacc.c:1646 */ + { + if (n_if_list > 0) { + struct opvar *tmppush; + tmppush = (struct opvar *) if_list[--n_if_list]; + set_opvar_int(tmppush, splev->n_opcodes - tmppush->vardata.l); + } else lc_error("IF: Huh?! No start address?"); + } +#line 3373 "y.tab.c" /* yacc.c:1646 */ + break; + + case 156: +#line 1061 "lev_comp.y" /* yacc.c:1646 */ + { + struct opvar *tmppush2 = New(struct opvar); + + if (n_if_list >= MAX_NESTED_IFS) { + lc_error("IF: Too deeply nested conditionals."); + n_if_list = MAX_NESTED_IFS - 1; + } + + add_opcode(splev, SPO_CMP, NULL); + + set_opvar_int(tmppush2, splev->n_opcodes+1); + + if_list[n_if_list++] = tmppush2; + + add_opcode(splev, SPO_PUSH, tmppush2); + + add_opcode(splev, reverse_jmp_opcode( (yyvsp[0].i) ), NULL); + + } +#line 3397 "y.tab.c" /* yacc.c:1646 */ + break; + + case 157: +#line 1081 "lev_comp.y" /* yacc.c:1646 */ + { + /* do nothing */ + } +#line 3405 "y.tab.c" /* yacc.c:1646 */ + break; + + case 158: +#line 1087 "lev_comp.y" /* yacc.c:1646 */ + { + if (n_if_list > 0) { + struct opvar *tmppush; + tmppush = (struct opvar *) if_list[--n_if_list]; + set_opvar_int(tmppush, splev->n_opcodes - tmppush->vardata.l); + } else lc_error("IF: Huh?! No start address?"); + } +#line 3417 "y.tab.c" /* yacc.c:1646 */ + break; + + case 159: +#line 1095 "lev_comp.y" /* yacc.c:1646 */ + { + if (n_if_list > 0) { + struct opvar *tmppush = New(struct opvar); + struct opvar *tmppush2; + + set_opvar_int(tmppush, splev->n_opcodes+1); + add_opcode(splev, SPO_PUSH, tmppush); + + add_opcode(splev, SPO_JMP, NULL); + + tmppush2 = (struct opvar *) if_list[--n_if_list]; + + set_opvar_int(tmppush2, splev->n_opcodes - tmppush2->vardata.l); + if_list[n_if_list++] = tmppush; + } else lc_error("IF: Huh?! No else-part address?"); + } +#line 3438 "y.tab.c" /* yacc.c:1646 */ + break; + + case 160: +#line 1112 "lev_comp.y" /* yacc.c:1646 */ + { + if (n_if_list > 0) { + struct opvar *tmppush; + tmppush = (struct opvar *) if_list[--n_if_list]; + set_opvar_int(tmppush, splev->n_opcodes - tmppush->vardata.l); + } else lc_error("IF: Huh?! No end address?"); + } +#line 3450 "y.tab.c" /* yacc.c:1646 */ + break; + + case 161: +#line 1122 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_MESSAGE); + } +#line 3458 "y.tab.c" /* yacc.c:1646 */ + break; + + case 162: +#line 1128 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiiiio", -1, 0, -1, -1, -1, -1, SPO_CORRIDOR); + } +#line 3466 "y.tab.c" /* yacc.c:1646 */ + break; + + case 163: +#line 1132 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiiiio", -1, (yyvsp[0].i), -1, -1, -1, -1, SPO_CORRIDOR); + } +#line 3474 "y.tab.c" /* yacc.c:1646 */ + break; + + case 164: +#line 1136 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiiiio", -1, -1, -1, -1, -1, -1, SPO_CORRIDOR); + } +#line 3482 "y.tab.c" /* yacc.c:1646 */ + break; + + case 165: +#line 1142 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiiiio", + (yyvsp[-2].corpos).room, (yyvsp[-2].corpos).door, (yyvsp[-2].corpos).wall, + (yyvsp[0].corpos).room, (yyvsp[0].corpos).door, (yyvsp[0].corpos).wall, + SPO_CORRIDOR); + } +#line 3493 "y.tab.c" /* yacc.c:1646 */ + break; + + case 166: +#line 1149 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiiiio", + (yyvsp[-2].corpos).room, (yyvsp[-2].corpos).door, (yyvsp[-2].corpos).wall, + -1, -1, (long)(yyvsp[0].i), + SPO_CORRIDOR); + } +#line 3504 "y.tab.c" /* yacc.c:1646 */ + break; + + case 167: +#line 1158 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.corpos).room = (yyvsp[-5].i); + (yyval.corpos).wall = (yyvsp[-3].i); + (yyval.corpos).door = (yyvsp[-1].i); + } +#line 3514 "y.tab.c" /* yacc.c:1646 */ + break; + + case 168: +#line 1166 "lev_comp.y" /* yacc.c:1646 */ + { + if (((yyvsp[-2].i) < 100) && ((yyvsp[-3].i) == OROOM)) + lc_error("Only typed rooms can have a chance."); + else { + add_opvars(splev, "iii", (long)(yyvsp[-3].i), (long)(yyvsp[-2].i), (long)(yyvsp[0].i)); + } + } +#line 3526 "y.tab.c" /* yacc.c:1646 */ + break; + + case 169: +#line 1176 "lev_comp.y" /* yacc.c:1646 */ + { + long flags = (yyvsp[0].i); + if (flags == -1) flags = (1 << 0); + add_opvars(splev, "iiiiiiio", flags, ERR, ERR, + (yyvsp[-3].crd).x, (yyvsp[-3].crd).y, (yyvsp[-1].sze).width, (yyvsp[-1].sze).height, SPO_SUBROOM); + break_stmt_start(); + } +#line 3538 "y.tab.c" /* yacc.c:1646 */ + break; + + case 170: +#line 1184 "lev_comp.y" /* yacc.c:1646 */ + { + break_stmt_end(splev); + add_opcode(splev, SPO_ENDROOM, NULL); + } +#line 3547 "y.tab.c" /* yacc.c:1646 */ + break; + + case 171: +#line 1191 "lev_comp.y" /* yacc.c:1646 */ + { + long flags = (yyvsp[-2].i); + if (flags == -1) flags = (1 << 0); + add_opvars(splev, "iiiiiiio", flags, + (yyvsp[-3].crd).x, (yyvsp[-3].crd).y, (yyvsp[-5].crd).x, (yyvsp[-5].crd).y, + (yyvsp[-1].sze).width, (yyvsp[-1].sze).height, SPO_ROOM); + break_stmt_start(); + } +#line 3560 "y.tab.c" /* yacc.c:1646 */ + break; + + case 172: +#line 1200 "lev_comp.y" /* yacc.c:1646 */ + { + break_stmt_end(splev); + add_opcode(splev, SPO_ENDROOM, NULL); + } +#line 3569 "y.tab.c" /* yacc.c:1646 */ + break; + + case 173: +#line 1207 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 1; + } +#line 3577 "y.tab.c" /* yacc.c:1646 */ + break; + + case 174: +#line 1211 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); + } +#line 3585 "y.tab.c" /* yacc.c:1646 */ + break; + + case 175: +#line 1217 "lev_comp.y" /* yacc.c:1646 */ + { + if ( (yyvsp[-3].i) < 1 || (yyvsp[-3].i) > 5 || + (yyvsp[-1].i) < 1 || (yyvsp[-1].i) > 5 ) { + lc_error("Room positions should be between 1-5: (%li,%li)!", (yyvsp[-3].i), (yyvsp[-1].i)); + } else { + (yyval.crd).x = (yyvsp[-3].i); + (yyval.crd).y = (yyvsp[-1].i); } + } +#line 3599 "y.tab.c" /* yacc.c:1646 */ + break; + + case 176: +#line 1227 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.crd).x = (yyval.crd).y = ERR; + } +#line 3607 "y.tab.c" /* yacc.c:1646 */ + break; + + case 177: +#line 1233 "lev_comp.y" /* yacc.c:1646 */ + { + if ( (yyvsp[-3].i) < 0 || (yyvsp[-1].i) < 0) { + lc_error("Invalid subroom position (%li,%li)!", (yyvsp[-3].i), (yyvsp[-1].i)); + } else { + (yyval.crd).x = (yyvsp[-3].i); + (yyval.crd).y = (yyvsp[-1].i); + } + } +#line 3620 "y.tab.c" /* yacc.c:1646 */ + break; + + case 178: +#line 1242 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.crd).x = (yyval.crd).y = ERR; + } +#line 3628 "y.tab.c" /* yacc.c:1646 */ + break; + + case 179: +#line 1248 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.crd).x = (yyvsp[-3].i); + (yyval.crd).y = (yyvsp[-1].i); + } +#line 3637 "y.tab.c" /* yacc.c:1646 */ + break; + + case 180: +#line 1253 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.crd).x = (yyval.crd).y = ERR; + } +#line 3645 "y.tab.c" /* yacc.c:1646 */ + break; + + case 181: +#line 1259 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.sze).width = (yyvsp[-3].i); + (yyval.sze).height = (yyvsp[-1].i); + } +#line 3654 "y.tab.c" /* yacc.c:1646 */ + break; + + case 182: +#line 1264 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.sze).height = (yyval.sze).width = ERR; + } +#line 3662 "y.tab.c" /* yacc.c:1646 */ + break; + + case 183: +#line 1270 "lev_comp.y" /* yacc.c:1646 */ + { + /* ERR means random here */ + if ((yyvsp[-2].i) == ERR && (yyvsp[0].i) != ERR) { + lc_error("If the door wall is random, so must be its pos!"); + } else { + add_opvars(splev, "iiiio", (long)(yyvsp[0].i), (long)(yyvsp[-4].i), (long)(yyvsp[-6].i), (long)(yyvsp[-2].i), SPO_ROOM_DOOR); + } + } +#line 3675 "y.tab.c" /* yacc.c:1646 */ + break; + + case 184: +#line 1279 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", (long)(yyvsp[-2].i), SPO_DOOR); + } +#line 3683 "y.tab.c" /* yacc.c:1646 */ + break; + + case 189: +#line 1293 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); + } +#line 3691 "y.tab.c" /* yacc.c:1646 */ + break; + + case 190: +#line 1297 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = ((yyvsp[-2].i) | (yyvsp[0].i)); + } +#line 3699 "y.tab.c" /* yacc.c:1646 */ + break; + + case 193: +#line 1307 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ciisiio", 0, 0, 1, (char *)0, 0, 0, SPO_MAP); + max_x_map = COLNO-1; + max_y_map = ROWNO; + } +#line 3709 "y.tab.c" /* yacc.c:1646 */ + break; + + case 194: +#line 1313 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "cii", SP_COORD_PACK(((yyvsp[-4].i)),((yyvsp[-2].i))), 1, (long)(yyvsp[-1].i)); + scan_map((yyvsp[0].map), splev); + Free((yyvsp[0].map)); + } +#line 3719 "y.tab.c" /* yacc.c:1646 */ + break; + + case 195: +#line 1319 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 2, (long)(yyvsp[-1].i)); + scan_map((yyvsp[0].map), splev); + Free((yyvsp[0].map)); + } +#line 3729 "y.tab.c" /* yacc.c:1646 */ + break; + + case 200: +#line 1335 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", 0, SPO_MONSTER); + } +#line 3737 "y.tab.c" /* yacc.c:1646 */ + break; + + case 201: +#line 1339 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", 1, SPO_MONSTER); + in_container_obj++; + break_stmt_start(); + } +#line 3747 "y.tab.c" /* yacc.c:1646 */ + break; + + case 202: +#line 1345 "lev_comp.y" /* yacc.c:1646 */ + { + break_stmt_end(splev); + in_container_obj--; + add_opvars(splev, "o", SPO_END_MONINVENT); + } +#line 3757 "y.tab.c" /* yacc.c:1646 */ + break; + + case 203: +#line 1353 "lev_comp.y" /* yacc.c:1646 */ + { + /* nothing */ + } +#line 3765 "y.tab.c" /* yacc.c:1646 */ + break; + + case 204: +#line 1359 "lev_comp.y" /* yacc.c:1646 */ + { + struct opvar *stopit = New(struct opvar); + set_opvar_int(stopit, SP_M_V_END); + add_opcode(splev, SPO_PUSH, stopit); + (yyval.i) = 0x0000; + } +#line 3776 "y.tab.c" /* yacc.c:1646 */ + break; + + case 205: +#line 1366 "lev_comp.y" /* yacc.c:1646 */ + { + if (( (yyvsp[-2].i) & (yyvsp[0].i) )) + lc_error("MONSTER extra info defined twice."); + (yyval.i) = ( (yyvsp[-2].i) | (yyvsp[0].i) ); + } +#line 3786 "y.tab.c" /* yacc.c:1646 */ + break; + + case 206: +#line 1374 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_M_V_NAME); + (yyval.i) = 0x0001; + } +#line 3795 "y.tab.c" /* yacc.c:1646 */ + break; + + case 207: +#line 1379 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", (long)(yyvsp[0].i), SP_M_V_PEACEFUL); + (yyval.i) = 0x0002; + } +#line 3804 "y.tab.c" /* yacc.c:1646 */ + break; + + case 208: +#line 1384 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", (long)(yyvsp[0].i), SP_M_V_ASLEEP); + (yyval.i) = 0x0004; + } +#line 3813 "y.tab.c" /* yacc.c:1646 */ + break; + + case 209: +#line 1389 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", (long)(yyvsp[0].i), SP_M_V_ALIGN); + (yyval.i) = 0x0008; + } +#line 3822 "y.tab.c" /* yacc.c:1646 */ + break; + + case 210: +#line 1394 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", (long)(yyvsp[-1].i), SP_M_V_APPEAR); + (yyval.i) = 0x0010; + } +#line 3831 "y.tab.c" /* yacc.c:1646 */ + break; + + case 211: +#line 1399 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_M_V_FEMALE); + (yyval.i) = 0x0020; + } +#line 3840 "y.tab.c" /* yacc.c:1646 */ + break; + + case 212: +#line 1404 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_M_V_INVIS); + (yyval.i) = 0x0040; + } +#line 3849 "y.tab.c" /* yacc.c:1646 */ + break; + + case 213: +#line 1409 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_M_V_CANCELLED); + (yyval.i) = 0x0080; + } +#line 3858 "y.tab.c" /* yacc.c:1646 */ + break; + + case 214: +#line 1414 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_M_V_REVIVED); + (yyval.i) = 0x0100; + } +#line 3867 "y.tab.c" /* yacc.c:1646 */ + break; + + case 215: +#line 1419 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_M_V_AVENGE); + (yyval.i) = 0x0200; + } +#line 3876 "y.tab.c" /* yacc.c:1646 */ + break; + + case 216: +#line 1424 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_M_V_FLEEING); + (yyval.i) = 0x0400; + } +#line 3885 "y.tab.c" /* yacc.c:1646 */ + break; + + case 217: +#line 1429 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_M_V_BLINDED); + (yyval.i) = 0x0800; + } +#line 3894 "y.tab.c" /* yacc.c:1646 */ + break; + + case 218: +#line 1434 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_M_V_PARALYZED); + (yyval.i) = 0x1000; + } +#line 3903 "y.tab.c" /* yacc.c:1646 */ + break; + + case 219: +#line 1439 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_M_V_STUNNED); + (yyval.i) = 0x2000; + } +#line 3912 "y.tab.c" /* yacc.c:1646 */ + break; + + case 220: +#line 1444 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_M_V_CONFUSED); + (yyval.i) = 0x4000; + } +#line 3921 "y.tab.c" /* yacc.c:1646 */ + break; + + case 221: +#line 1449 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", (long)(yyvsp[0].i), SP_M_V_SEENTRAPS); + (yyval.i) = 0x8000; + } +#line 3930 "y.tab.c" /* yacc.c:1646 */ + break; + + case 222: +#line 1456 "lev_comp.y" /* yacc.c:1646 */ + { + int token = get_trap_type((yyvsp[0].map)); + if (token == ERR || token == 0) + lc_error("Unknown trap type '%s'!", (yyvsp[0].map)); + (yyval.i) = (1L << (token - 1)); + } +#line 3941 "y.tab.c" /* yacc.c:1646 */ + break; + + case 223: +#line 1463 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (long) ~0; + } +#line 3949 "y.tab.c" /* yacc.c:1646 */ + break; + + case 224: +#line 1467 "lev_comp.y" /* yacc.c:1646 */ + { + int token = get_trap_type((yyvsp[-2].map)); + if (token == ERR || token == 0) + lc_error("Unknown trap type '%s'!", (yyvsp[-2].map)); + + if ((1L << (token - 1)) & (yyvsp[0].i)) + lc_error("Monster seen_traps, trap '%s' listed twice.", (yyvsp[-2].map)); + + (yyval.i) = ((1L << (token - 1)) | (yyvsp[0].i)); + } +#line 3964 "y.tab.c" /* yacc.c:1646 */ + break; + + case 225: +#line 1480 "lev_comp.y" /* yacc.c:1646 */ + { + long cnt = 0; + if (in_container_obj) cnt |= SP_OBJ_CONTENT; + add_opvars(splev, "io", cnt, SPO_OBJECT); + } +#line 3974 "y.tab.c" /* yacc.c:1646 */ + break; + + case 226: +#line 1486 "lev_comp.y" /* yacc.c:1646 */ + { + long cnt = SP_OBJ_CONTAINER; + if (in_container_obj) cnt |= SP_OBJ_CONTENT; + add_opvars(splev, "io", cnt, SPO_OBJECT); + in_container_obj++; + break_stmt_start(); + } +#line 3986 "y.tab.c" /* yacc.c:1646 */ + break; + + case 227: +#line 1494 "lev_comp.y" /* yacc.c:1646 */ + { + break_stmt_end(splev); + in_container_obj--; + add_opcode(splev, SPO_POP_CONTAINER, NULL); + } +#line 3996 "y.tab.c" /* yacc.c:1646 */ + break; + + case 228: +#line 1502 "lev_comp.y" /* yacc.c:1646 */ + { + if (( (yyvsp[0].i) & 0x4000) && in_container_obj) lc_error("Object cannot have a coord when contained."); + else if (!( (yyvsp[0].i) & 0x4000) && !in_container_obj) lc_error("Object needs a coord when not contained."); + } +#line 4005 "y.tab.c" /* yacc.c:1646 */ + break; + + case 229: +#line 1509 "lev_comp.y" /* yacc.c:1646 */ + { + struct opvar *stopit = New(struct opvar); + set_opvar_int(stopit, SP_O_V_END); + add_opcode(splev, SPO_PUSH, stopit); + (yyval.i) = 0x00; + } +#line 4016 "y.tab.c" /* yacc.c:1646 */ + break; + + case 230: +#line 1516 "lev_comp.y" /* yacc.c:1646 */ + { + if (( (yyvsp[-2].i) & (yyvsp[0].i) )) + lc_error("OBJECT extra info '%s' defined twice.", curr_token); + (yyval.i) = ( (yyvsp[-2].i) | (yyvsp[0].i) ); + } +#line 4026 "y.tab.c" /* yacc.c:1646 */ + break; + + case 231: +#line 1524 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", (long)(yyvsp[0].i), SP_O_V_CURSE); + (yyval.i) = 0x0001; + } +#line 4035 "y.tab.c" /* yacc.c:1646 */ + break; + + case 232: +#line 1529 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_O_V_CORPSENM); + (yyval.i) = 0x0002; + } +#line 4044 "y.tab.c" /* yacc.c:1646 */ + break; + + case 233: +#line 1534 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_O_V_SPE); + (yyval.i) = 0x0004; + } +#line 4053 "y.tab.c" /* yacc.c:1646 */ + break; + + case 234: +#line 1539 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_O_V_NAME); + (yyval.i) = 0x0008; + } +#line 4062 "y.tab.c" /* yacc.c:1646 */ + break; + + case 235: +#line 1544 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_O_V_QUAN); + (yyval.i) = 0x0010; + } +#line 4071 "y.tab.c" /* yacc.c:1646 */ + break; + + case 236: +#line 1549 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_O_V_BURIED); + (yyval.i) = 0x0020; + } +#line 4080 "y.tab.c" /* yacc.c:1646 */ + break; + + case 237: +#line 1554 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", (long)(yyvsp[0].i), SP_O_V_LIT); + (yyval.i) = 0x0040; + } +#line 4089 "y.tab.c" /* yacc.c:1646 */ + break; + + case 238: +#line 1559 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_O_V_ERODED); + (yyval.i) = 0x0080; + } +#line 4098 "y.tab.c" /* yacc.c:1646 */ + break; + + case 239: +#line 1564 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", -1, SP_O_V_ERODED); + (yyval.i) = 0x0080; + } +#line 4107 "y.tab.c" /* yacc.c:1646 */ + break; + + case 240: +#line 1569 "lev_comp.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].i) == D_LOCKED) { + add_opvars(splev, "ii", 1, SP_O_V_LOCKED); + (yyval.i) = 0x0100; + } else if ((yyvsp[0].i) == D_BROKEN) { + add_opvars(splev, "ii", 1, SP_O_V_BROKEN); + (yyval.i) = 0x0200; + } else + lc_error("OBJECT state can only be locked or broken."); + } +#line 4122 "y.tab.c" /* yacc.c:1646 */ + break; + + case 241: +#line 1580 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_O_V_TRAPPED); + (yyval.i) = 0x0400; + } +#line 4131 "y.tab.c" /* yacc.c:1646 */ + break; + + case 242: +#line 1585 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_O_V_RECHARGED); + (yyval.i) = 0x0800; + } +#line 4140 "y.tab.c" /* yacc.c:1646 */ + break; + + case 243: +#line 1590 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_O_V_INVIS); + (yyval.i) = 0x1000; + } +#line 4149 "y.tab.c" /* yacc.c:1646 */ + break; + + case 244: +#line 1595 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "ii", 1, SP_O_V_GREASED); + (yyval.i) = 0x2000; + } +#line 4158 "y.tab.c" /* yacc.c:1646 */ + break; + + case 245: +#line 1600 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", SP_O_V_COORD); + (yyval.i) = 0x4000; + } +#line 4167 "y.tab.c" /* yacc.c:1646 */ + break; + + case 246: +#line 1607 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", (long)(yyvsp[-2].i), SPO_TRAP); + } +#line 4175 "y.tab.c" /* yacc.c:1646 */ + break; + + case 247: +#line 1613 "lev_comp.y" /* yacc.c:1646 */ + { + long d, state = 0; + /* convert dir from a DIRECTION to a DB_DIR */ + d = (yyvsp[-2].i); + switch(d) { + case W_NORTH: d = DB_NORTH; break; + case W_SOUTH: d = DB_SOUTH; break; + case W_EAST: d = DB_EAST; break; + case W_WEST: d = DB_WEST; break; + default: + lc_error("Invalid drawbridge direction."); + break; + } + + if ( (yyvsp[0].i) == D_ISOPEN ) + state = 1; + else if ( (yyvsp[0].i) == D_CLOSED ) + state = 0; + else if ( (yyvsp[0].i) == -1 ) + state = -1; + else + lc_error("A drawbridge can only be open, closed or random!"); + add_opvars(splev, "iio", state, d, SPO_DRAWBRIDGE); } -break; -case 153: -{ - tmpwalk[nwalk] = New(walk); - tmpwalk[nwalk]->x = current_coord.x; - tmpwalk[nwalk]->y = current_coord.y; - tmpwalk[nwalk]->dir = yyvsp[0].i; - nwalk++; - if (nwalk >= MAX_OF_TYPE) { - yyerror("Too many mazewalks in mazepart!"); - nwalk--; - } - } -break; -case 154: -{ - wallify_map(); - } -break; -case 155: -{ - tmplad[nlad] = New(lad); - tmplad[nlad]->x = current_coord.x; - tmplad[nlad]->y = current_coord.y; - tmplad[nlad]->up = yyvsp[0].i; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Ladder"); - nlad++; - if (nlad >= MAX_OF_TYPE) { - yyerror("Too many ladders in mazepart!"); - nlad--; - } - } -break; -case 156: -{ - tmpstair[nstair] = New(stair); - tmpstair[nstair]->x = current_coord.x; - tmpstair[nstair]->y = current_coord.y; - tmpstair[nstair]->up = yyvsp[0].i; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Stairway"); - nstair++; - if (nstair >= MAX_OF_TYPE) { - yyerror("Too many stairs in room or mazepart!"); - nstair--; - } - } -break; -case 157: -{ - tmplreg[nlreg] = New(lev_region); - tmplreg[nlreg]->in_islev = yyvsp[0].i; - tmplreg[nlreg]->inarea.x1 = current_region.x1; - tmplreg[nlreg]->inarea.y1 = current_region.y1; - tmplreg[nlreg]->inarea.x2 = current_region.x2; - tmplreg[nlreg]->inarea.y2 = current_region.y2; - } -break; -case 158: -{ - tmplreg[nlreg]->del_islev = yyvsp[-2].i; - tmplreg[nlreg]->delarea.x1 = current_region.x1; - tmplreg[nlreg]->delarea.y1 = current_region.y1; - tmplreg[nlreg]->delarea.x2 = current_region.x2; - tmplreg[nlreg]->delarea.y2 = current_region.y2; - if(yyvsp[0].i) - tmplreg[nlreg]->rtype = LR_UPSTAIR; - else - tmplreg[nlreg]->rtype = LR_DOWNSTAIR; - tmplreg[nlreg]->rname.str = 0; - nlreg++; - if (nlreg >= MAX_OF_TYPE) { - yyerror("Too many levregions in mazepart!"); - nlreg--; - } - } -break; -case 159: -{ - tmplreg[nlreg] = New(lev_region); - tmplreg[nlreg]->in_islev = yyvsp[0].i; - tmplreg[nlreg]->inarea.x1 = current_region.x1; - tmplreg[nlreg]->inarea.y1 = current_region.y1; - tmplreg[nlreg]->inarea.x2 = current_region.x2; - tmplreg[nlreg]->inarea.y2 = current_region.y2; - } -break; -case 160: -{ - tmplreg[nlreg]->del_islev = yyvsp[-2].i; - tmplreg[nlreg]->delarea.x1 = current_region.x1; - tmplreg[nlreg]->delarea.y1 = current_region.y1; - tmplreg[nlreg]->delarea.x2 = current_region.x2; - tmplreg[nlreg]->delarea.y2 = current_region.y2; - tmplreg[nlreg]->rtype = LR_PORTAL; - tmplreg[nlreg]->rname.str = yyvsp[0].map; - nlreg++; - if (nlreg >= MAX_OF_TYPE) { - yyerror("Too many levregions in mazepart!"); - nlreg--; - } - } -break; -case 161: -{ - tmplreg[nlreg] = New(lev_region); - tmplreg[nlreg]->in_islev = yyvsp[0].i; - tmplreg[nlreg]->inarea.x1 = current_region.x1; - tmplreg[nlreg]->inarea.y1 = current_region.y1; - tmplreg[nlreg]->inarea.x2 = current_region.x2; - tmplreg[nlreg]->inarea.y2 = current_region.y2; - } -break; -case 162: -{ - tmplreg[nlreg]->del_islev = yyvsp[0].i; - tmplreg[nlreg]->delarea.x1 = current_region.x1; - tmplreg[nlreg]->delarea.y1 = current_region.y1; - tmplreg[nlreg]->delarea.x2 = current_region.x2; - tmplreg[nlreg]->delarea.y2 = current_region.y2; - } -break; -case 163: -{ - switch(yyvsp[0].i) { - case -1: tmplreg[nlreg]->rtype = LR_TELE; break; - case 0: tmplreg[nlreg]->rtype = LR_DOWNTELE; break; - case 1: tmplreg[nlreg]->rtype = LR_UPTELE; break; - } - tmplreg[nlreg]->rname.str = 0; - nlreg++; - if (nlreg >= MAX_OF_TYPE) { - yyerror("Too many levregions in mazepart!"); - nlreg--; - } - } -break; -case 164: -{ - tmplreg[nlreg] = New(lev_region); - tmplreg[nlreg]->in_islev = yyvsp[0].i; - tmplreg[nlreg]->inarea.x1 = current_region.x1; - tmplreg[nlreg]->inarea.y1 = current_region.y1; - tmplreg[nlreg]->inarea.x2 = current_region.x2; - tmplreg[nlreg]->inarea.y2 = current_region.y2; - } -break; -case 165: -{ - tmplreg[nlreg]->del_islev = yyvsp[0].i; - tmplreg[nlreg]->delarea.x1 = current_region.x1; - tmplreg[nlreg]->delarea.y1 = current_region.y1; - tmplreg[nlreg]->delarea.x2 = current_region.x2; - tmplreg[nlreg]->delarea.y2 = current_region.y2; - tmplreg[nlreg]->rtype = LR_BRANCH; - tmplreg[nlreg]->rname.str = 0; - nlreg++; - if (nlreg >= MAX_OF_TYPE) { - yyerror("Too many levregions in mazepart!"); - nlreg--; - } - } -break; -case 166: -{ - yyval.i = -1; - } -break; -case 167: -{ - yyval.i = yyvsp[0].i; - } -break; -case 168: -{ - yyval.i = 0; - } -break; -case 169: -{ -/* This series of if statements is a hack for MSC 5.1. It seems that its - tiny little brain cannot compile if these are all one big if statement. */ - if (yyvsp[-7].i <= 0 || yyvsp[-7].i >= COLNO) - yyerror("Region out of level range!"); - else if (yyvsp[-5].i < 0 || yyvsp[-5].i >= ROWNO) - yyerror("Region out of level range!"); - else if (yyvsp[-3].i <= 0 || yyvsp[-3].i >= COLNO) - yyerror("Region out of level range!"); - else if (yyvsp[-1].i < 0 || yyvsp[-1].i >= ROWNO) - yyerror("Region out of level range!"); - current_region.x1 = yyvsp[-7].i; - current_region.y1 = yyvsp[-5].i; - current_region.x2 = yyvsp[-3].i; - current_region.y2 = yyvsp[-1].i; - yyval.i = 1; - } -break; -case 170: -{ - tmpfountain[nfountain] = New(fountain); - tmpfountain[nfountain]->x = current_coord.x; - tmpfountain[nfountain]->y = current_coord.y; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Fountain"); - nfountain++; - if (nfountain >= MAX_OF_TYPE) { - yyerror("Too many fountains in room or mazepart!"); - nfountain--; - } - } -break; -case 171: -{ - tmpsink[nsink] = New(sink); - tmpsink[nsink]->x = current_coord.x; - tmpsink[nsink]->y = current_coord.y; - nsink++; - if (nsink >= MAX_OF_TYPE) { - yyerror("Too many sinks in room!"); - nsink--; - } - } -break; -case 172: -{ - tmppool[npool] = New(pool); - tmppool[npool]->x = current_coord.x; - tmppool[npool]->y = current_coord.y; - npool++; - if (npool >= MAX_OF_TYPE) { - yyerror("Too many pools in room!"); - npool--; - } - } -break; -case 173: -{ - tmpdig[ndig] = New(digpos); - tmpdig[ndig]->x1 = current_region.x1; - tmpdig[ndig]->y1 = current_region.y1; - tmpdig[ndig]->x2 = current_region.x2; - tmpdig[ndig]->y2 = current_region.y2; - ndig++; - if (ndig >= MAX_OF_TYPE) { - yyerror("Too many diggables in mazepart!"); - ndig--; - } - } -break; -case 174: -{ - tmppass[npass] = New(digpos); - tmppass[npass]->x1 = current_region.x1; - tmppass[npass]->y1 = current_region.y1; - tmppass[npass]->x2 = current_region.x2; - tmppass[npass]->y2 = current_region.y2; - npass++; - if (npass >= 32) { - yyerror("Too many passwalls in mazepart!"); - npass--; - } - } -break; -case 175: -{ - tmpreg[nreg] = New(region); - tmpreg[nreg]->x1 = current_region.x1; - tmpreg[nreg]->y1 = current_region.y1; - tmpreg[nreg]->x2 = current_region.x2; - tmpreg[nreg]->y2 = current_region.y2; - tmpreg[nreg]->rlit = yyvsp[-3].i; - tmpreg[nreg]->rtype = yyvsp[-1].i; - if(yyvsp[0].i & 1) tmpreg[nreg]->rtype += MAXRTYPE+1; - tmpreg[nreg]->rirreg = ((yyvsp[0].i & 2) != 0); - if(current_region.x1 > current_region.x2 || - current_region.y1 > current_region.y2) - yyerror("Region start > end!"); - if(tmpreg[nreg]->rtype == VAULT && - (tmpreg[nreg]->rirreg || - (tmpreg[nreg]->x2 - tmpreg[nreg]->x1 != 1) || - (tmpreg[nreg]->y2 - tmpreg[nreg]->y1 != 1))) - yyerror("Vaults must be exactly 2x2!"); - if(want_warnings && !tmpreg[nreg]->rirreg && - current_region.x1 > 0 && current_region.y1 > 0 && - current_region.x2 < (int)max_x_map && - current_region.y2 < (int)max_y_map) { - /* check for walls in the room */ - char ebuf[60]; - register int x, y, nrock = 0; +#line 4204 "y.tab.c" /* yacc.c:1646 */ + break; - for(y=current_region.y1; y<=current_region.y2; y++) - for(x=current_region.x1; - x<=current_region.x2; x++) - if(IS_ROCK(tmpmap[y][x]) || - IS_DOOR(tmpmap[y][x])) nrock++; - if(nrock) { - Sprintf(ebuf, - "Rock in room (%02d,%02d,%02d,%02d)?!", - current_region.x1, current_region.y1, - current_region.x2, current_region.y2); - yywarning(ebuf); - } - if ( - !IS_ROCK(tmpmap[current_region.y1-1][current_region.x1-1]) || - !IS_ROCK(tmpmap[current_region.y2+1][current_region.x1-1]) || - !IS_ROCK(tmpmap[current_region.y1-1][current_region.x2+1]) || - !IS_ROCK(tmpmap[current_region.y2+1][current_region.x2+1])) { - Sprintf(ebuf, - "NonRock edge in room (%02d,%02d,%02d,%02d)?!", - current_region.x1, current_region.y1, - current_region.x2, current_region.y2); - yywarning(ebuf); - } - } else if(tmpreg[nreg]->rirreg && - !IS_ROOM(tmpmap[current_region.y1][current_region.x1])) { - char ebuf[60]; - Sprintf(ebuf, - "Rock in irregular room (%02d,%02d)?!", - current_region.x1, current_region.y1); - yyerror(ebuf); - } - nreg++; - if (nreg >= MAX_OF_TYPE) { - yyerror("Too many regions in mazepart!"); - nreg--; - } + case 248: +#line 1640 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiio", + (long)(yyvsp[0].i), 1, 0, SPO_MAZEWALK); } -break; -case 176: -{ - tmpaltar[naltar] = New(altar); - tmpaltar[naltar]->x = current_coord.x; - tmpaltar[naltar]->y = current_coord.y; - tmpaltar[naltar]->align = yyvsp[-2].i; - tmpaltar[naltar]->shrine = yyvsp[0].i; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Altar"); - naltar++; - if (naltar >= MAX_OF_TYPE) { - yyerror("Too many altars in room or mazepart!"); - naltar--; - } +#line 4213 "y.tab.c" /* yacc.c:1646 */ + break; + + case 249: +#line 1645 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiio", + (long)(yyvsp[-3].i), (long)(yyvsp[-1].i), (long)(yyvsp[0].i), SPO_MAZEWALK); } -break; -case 177: -{ - tmpgold[ngold] = New(gold); - tmpgold[ngold]->x = current_coord.x; - tmpgold[ngold]->y = current_coord.y; - tmpgold[ngold]->amount = yyvsp[-2].i; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Gold"); - ngold++; - if (ngold >= MAX_OF_TYPE) { - yyerror("Too many golds in room or mazepart!"); - ngold--; - } +#line 4222 "y.tab.c" /* yacc.c:1646 */ + break; + + case 250: +#line 1652 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "rio", SP_REGION_PACK(-1,-1,-1,-1), 0, SPO_WALLIFY); } -break; -case 178: -{ - tmpengraving[nengraving] = New(engraving); - tmpengraving[nengraving]->x = current_coord.x; - tmpengraving[nengraving]->y = current_coord.y; - tmpengraving[nengraving]->engr.str = yyvsp[0].map; - tmpengraving[nengraving]->etype = yyvsp[-2].i; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Engraving"); - nengraving++; - if (nengraving >= MAX_OF_TYPE) { - yyerror("Too many engravings in room or mazepart!"); - nengraving--; - } +#line 4230 "y.tab.c" /* yacc.c:1646 */ + break; + + case 251: +#line 1656 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", 1, SPO_WALLIFY); } -break; -case 180: -{ - yyval.i = - MAX_REGISTERS - 1; +#line 4238 "y.tab.c" /* yacc.c:1646 */ + break; + + case 252: +#line 1662 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", (long)(yyvsp[0].i), SPO_LADDER); } -break; -case 183: -{ - yyval.i = - MAX_REGISTERS - 1; +#line 4246 "y.tab.c" /* yacc.c:1646 */ + break; + + case 253: +#line 1668 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", (long)(yyvsp[0].i), SPO_STAIR); } -break; -case 186: -{ - yyval.map = (char *) 0; +#line 4254 "y.tab.c" /* yacc.c:1646 */ + break; + + case 254: +#line 1674 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiii iiiii iiso", + (yyvsp[-4].lregn).x1, (yyvsp[-4].lregn).y1, (yyvsp[-4].lregn).x2, (yyvsp[-4].lregn).y2, (yyvsp[-4].lregn).area, + (yyvsp[-2].lregn).x1, (yyvsp[-2].lregn).y1, (yyvsp[-2].lregn).x2, (yyvsp[-2].lregn).y2, (yyvsp[-2].lregn).area, + (long)(((yyvsp[0].i)) ? LR_UPSTAIR : LR_DOWNSTAIR), + 0, (char *)0, SPO_LEVREGION); } -break; -case 188: -{ - yyval.map = (char *) 0; +#line 4266 "y.tab.c" /* yacc.c:1646 */ + break; + + case 255: +#line 1684 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiii iiiii iiso", + (yyvsp[-4].lregn).x1, (yyvsp[-4].lregn).y1, (yyvsp[-4].lregn).x2, (yyvsp[-4].lregn).y2, (yyvsp[-4].lregn).area, + (yyvsp[-2].lregn).x1, (yyvsp[-2].lregn).y1, (yyvsp[-2].lregn).x2, (yyvsp[-2].lregn).y2, (yyvsp[-2].lregn).area, + LR_PORTAL, 0, (yyvsp[0].map), SPO_LEVREGION); + Free((yyvsp[0].map)); } -break; -case 189: -{ - int token = get_trap_type(yyvsp[0].map); +#line 4278 "y.tab.c" /* yacc.c:1646 */ + break; + + case 256: +#line 1694 "lev_comp.y" /* yacc.c:1646 */ + { + long rtype = 0; + switch((yyvsp[0].i)) { + case -1: rtype = LR_TELE; break; + case 0: rtype = LR_DOWNTELE; break; + case 1: rtype = LR_UPTELE; break; + } + add_opvars(splev, "iiiii iiiii iiso", + (yyvsp[-3].lregn).x1, (yyvsp[-3].lregn).y1, (yyvsp[-3].lregn).x2, (yyvsp[-3].lregn).y2, (yyvsp[-3].lregn).area, + (yyvsp[-1].lregn).x1, (yyvsp[-1].lregn).y1, (yyvsp[-1].lregn).x2, (yyvsp[-1].lregn).y2, (yyvsp[-1].lregn).area, + rtype, 0, (char *)0, SPO_LEVREGION); + } +#line 4295 "y.tab.c" /* yacc.c:1646 */ + break; + + case 257: +#line 1709 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiii iiiii iiso", + (yyvsp[-2].lregn).x1, (yyvsp[-2].lregn).y1, (yyvsp[-2].lregn).x2, (yyvsp[-2].lregn).y2, (yyvsp[-2].lregn).area, + (yyvsp[0].lregn).x1, (yyvsp[0].lregn).y1, (yyvsp[0].lregn).x2, (yyvsp[0].lregn).y2, (yyvsp[0].lregn).area, + (long)LR_BRANCH, 0, (char *)0, SPO_LEVREGION); + } +#line 4306 "y.tab.c" /* yacc.c:1646 */ + break; + + case 258: +#line 1718 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = -1; + } +#line 4314 "y.tab.c" /* yacc.c:1646 */ + break; + + case 259: +#line 1722 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); + } +#line 4322 "y.tab.c" /* yacc.c:1646 */ + break; + + case 260: +#line 1728 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_FOUNTAIN); + } +#line 4330 "y.tab.c" /* yacc.c:1646 */ + break; + + case 261: +#line 1734 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_SINK); + } +#line 4338 "y.tab.c" /* yacc.c:1646 */ + break; + + case 262: +#line 1740 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_POOL); + } +#line 4346 "y.tab.c" /* yacc.c:1646 */ + break; + + case 263: +#line 1746 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.terr).lit = -2; + (yyval.terr).ter = what_map_char((char) (yyvsp[0].i)); + } +#line 4355 "y.tab.c" /* yacc.c:1646 */ + break; + + case 264: +#line 1751 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.terr).lit = (yyvsp[-1].i); + (yyval.terr).ter = what_map_char((char) (yyvsp[-3].i)); + } +#line 4364 "y.tab.c" /* yacc.c:1646 */ + break; + + case 265: +#line 1758 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", (yyvsp[0].i), SPO_REPLACETERRAIN); + } +#line 4372 "y.tab.c" /* yacc.c:1646 */ + break; + + case 266: +#line 1764 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_TERRAIN); + } +#line 4380 "y.tab.c" /* yacc.c:1646 */ + break; + + case 267: +#line 1770 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_NON_DIGGABLE); + } +#line 4388 "y.tab.c" /* yacc.c:1646 */ + break; + + case 268: +#line 1776 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_NON_PASSWALL); + } +#line 4396 "y.tab.c" /* yacc.c:1646 */ + break; + + case 269: +#line 1782 "lev_comp.y" /* yacc.c:1646 */ + { + long irr; + long rt = (yyvsp[-1].i); + long flags = (yyvsp[0].i); + if (flags == -1) flags = (1 << 0); + if (!(( flags ) & 1)) rt += MAXRTYPE+1; + irr = ((( flags ) & 2) != 0); + add_opvars(splev, "iiio", + (long)(yyvsp[-3].i), rt, flags, SPO_REGION); + (yyval.i) = (irr || (flags & 1) || rt != OROOM); + break_stmt_start(); + } +#line 4413 "y.tab.c" /* yacc.c:1646 */ + break; + + case 270: +#line 1795 "lev_comp.y" /* yacc.c:1646 */ + { + break_stmt_end(splev); + if ( (yyvsp[-1].i) ) { + add_opcode(splev, SPO_ENDROOM, NULL); + } else if ( (yyvsp[0].i) ) + lc_error("Cannot use lev statements in non-permanent REGION"); + } +#line 4425 "y.tab.c" /* yacc.c:1646 */ + break; + + case 271: +#line 1805 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = 0; + } +#line 4433 "y.tab.c" /* yacc.c:1646 */ + break; + + case 272: +#line 1809 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); + } +#line 4441 "y.tab.c" /* yacc.c:1646 */ + break; + + case 273: +#line 1815 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iio", (long)(yyvsp[0].i), (long)(yyvsp[-2].i), SPO_ALTAR); + } +#line 4449 "y.tab.c" /* yacc.c:1646 */ + break; + + case 274: +#line 1821 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", 2, SPO_GRAVE); + } +#line 4457 "y.tab.c" /* yacc.c:1646 */ + break; + + case 275: +#line 1825 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "sio", + (char *)0, 1, SPO_GRAVE); + } +#line 4466 "y.tab.c" /* yacc.c:1646 */ + break; + + case 276: +#line 1830 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "sio", + (char *)0, 0, SPO_GRAVE); + } +#line 4475 "y.tab.c" /* yacc.c:1646 */ + break; + + case 277: +#line 1837 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_GOLD); + } +#line 4483 "y.tab.c" /* yacc.c:1646 */ + break; + + case 278: +#line 1843 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", + (long)(yyvsp[-2].i), SPO_ENGRAVING); + } +#line 4492 "y.tab.c" /* yacc.c:1646 */ + break; + + case 279: +#line 1850 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_MINERALIZE); + } +#line 4500 "y.tab.c" /* yacc.c:1646 */ + break; + + case 280: +#line 1854 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iiiio", -1L, -1L, -1L, -1L, SPO_MINERALIZE); + } +#line 4508 "y.tab.c" /* yacc.c:1646 */ + break; + + case 281: +#line 1860 "lev_comp.y" /* yacc.c:1646 */ + { + int token = get_trap_type((yyvsp[0].map)); if (token == ERR) - yyerror("Unknown trap type!"); - yyval.i = token; - Free(yyvsp[0].map); + lc_error("Unknown trap type '%s'!", (yyvsp[0].map)); + (yyval.i) = token; + Free((yyvsp[0].map)); } -break; -case 191: -{ - int token = get_room_type(yyvsp[0].map); +#line 4520 "y.tab.c" /* yacc.c:1646 */ + break; + + case 283: +#line 1871 "lev_comp.y" /* yacc.c:1646 */ + { + int token = get_room_type((yyvsp[0].map)); if (token == ERR) { - yywarning("Unknown room type! Making ordinary room..."); - yyval.i = OROOM; + lc_warning("Unknown room type \"%s\"! Making ordinary room...", (yyvsp[0].map)); + (yyval.i) = OROOM; } else - yyval.i = token; - Free(yyvsp[0].map); + (yyval.i) = token; + Free((yyvsp[0].map)); } -break; -case 193: -{ - yyval.i = 0; +#line 4534 "y.tab.c" /* yacc.c:1646 */ + break; + + case 285: +#line 1884 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = -1; } -break; -case 194: -{ - yyval.i = yyvsp[0].i; +#line 4542 "y.tab.c" /* yacc.c:1646 */ + break; + + case 286: +#line 1888 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); } -break; -case 195: -{ - yyval.i = yyvsp[-2].i + (yyvsp[0].i << 1); +#line 4550 "y.tab.c" /* yacc.c:1646 */ + break; + + case 287: +#line 1894 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); } -break; -case 198: -{ - current_coord.x = current_coord.y = -MAX_REGISTERS-1; +#line 4558 "y.tab.c" /* yacc.c:1646 */ + break; + + case 288: +#line 1898 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[-2].i) | (yyvsp[0].i); } -break; -case 205: -{ - yyval.i = - MAX_REGISTERS - 1; +#line 4566 "y.tab.c" /* yacc.c:1646 */ + break; + + case 289: +#line 1905 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = ((yyvsp[0].i) << 0); } -break; -case 208: -{ - if ( yyvsp[-1].i >= MAX_REGISTERS ) - yyerror("Register Index overflow!"); +#line 4574 "y.tab.c" /* yacc.c:1646 */ + break; + + case 290: +#line 1909 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = ((yyvsp[0].i) << 1); + } +#line 4582 "y.tab.c" /* yacc.c:1646 */ + break; + + case 291: +#line 1913 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = ((yyvsp[0].i) << 2); + } +#line 4590 "y.tab.c" /* yacc.c:1646 */ + break; + + case 298: +#line 1929 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = - MAX_REGISTERS - 1; + } +#line 4598 "y.tab.c" /* yacc.c:1646 */ + break; + + case 301: +#line 1937 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = - MAX_REGISTERS - 1; + } +#line 4606 "y.tab.c" /* yacc.c:1646 */ + break; + + case 304: +#line 1947 "lev_comp.y" /* yacc.c:1646 */ + { + if ( (yyvsp[-1].i) >= 3 ) + lc_error("Register Index overflow!"); else - current_coord.x = current_coord.y = - yyvsp[-1].i - 1; + (yyval.i) = - (yyvsp[-1].i) - 1; } -break; -case 209: -{ - if ( yyvsp[-1].i >= MAX_REGISTERS ) - yyerror("Register Index overflow!"); - else - yyval.i = - yyvsp[-1].i - 1; +#line 4617 "y.tab.c" /* yacc.c:1646 */ + break; + + case 305: +#line 1956 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "s", (yyvsp[0].map)); + Free((yyvsp[0].map)); } -break; -case 210: -{ - if ( yyvsp[-1].i >= MAX_REGISTERS ) - yyerror("Register Index overflow!"); - else - yyval.i = - yyvsp[-1].i - 1; +#line 4626 "y.tab.c" /* yacc.c:1646 */ + break; + + case 306: +#line 1961 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[0].map), SPOVAR_STRING); + vardef_used(variable_definitions, (yyvsp[0].map)); + add_opvars(splev, "v", (yyvsp[0].map)); + Free((yyvsp[0].map)); } -break; -case 211: -{ - if ( yyvsp[-1].i >= 3 ) - yyerror("Register Index overflow!"); - else - yyval.i = - yyvsp[-1].i - 1; +#line 4637 "y.tab.c" /* yacc.c:1646 */ + break; + + case 307: +#line 1968 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[-3].map), SPOVAR_STRING|SPOVAR_ARRAY); + vardef_used(variable_definitions, (yyvsp[-3].map)); + add_opvars(splev, "v", (yyvsp[-3].map)); + Free((yyvsp[-3].map)); } -break; -case 213: -{ - if (check_monster_char((char) yyvsp[0].i)) - yyval.i = yyvsp[0].i ; +#line 4648 "y.tab.c" /* yacc.c:1646 */ + break; + + case 308: +#line 1978 "lev_comp.y" /* yacc.c:1646 */ + { + /* nothing */ + } +#line 4656 "y.tab.c" /* yacc.c:1646 */ + break; + + case 309: +#line 1984 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "c", (yyvsp[0].i)); + } +#line 4664 "y.tab.c" /* yacc.c:1646 */ + break; + + case 310: +#line 1988 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_SEL_RNDCOORD); + } +#line 4672 "y.tab.c" /* yacc.c:1646 */ + break; + + case 311: +#line 1992 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[0].map), SPOVAR_COORD); + vardef_used(variable_definitions, (yyvsp[0].map)); + add_opvars(splev, "v", (yyvsp[0].map)); + Free((yyvsp[0].map)); + } +#line 4683 "y.tab.c" /* yacc.c:1646 */ + break; + + case 312: +#line 1999 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[-3].map), SPOVAR_COORD|SPOVAR_ARRAY); + vardef_used(variable_definitions, (yyvsp[-3].map)); + add_opvars(splev, "v", (yyvsp[-3].map)); + Free((yyvsp[-3].map)); + } +#line 4694 "y.tab.c" /* yacc.c:1646 */ + break; + + case 313: +#line 2008 "lev_comp.y" /* yacc.c:1646 */ + { + if ((yyvsp[-3].i) < 0 || (yyvsp[-1].i) < 0 || (yyvsp[-3].i) >= COLNO || (yyvsp[-1].i) >= ROWNO) + lc_error("Coordinates (%li,%li) out of map range!", (yyvsp[-3].i), (yyvsp[-1].i)); + (yyval.i) = SP_COORD_PACK((yyvsp[-3].i), (yyvsp[-1].i)); + } +#line 4704 "y.tab.c" /* yacc.c:1646 */ + break; + + case 314: +#line 2014 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = SP_COORD_PACK_RANDOM(0); + } +#line 4712 "y.tab.c" /* yacc.c:1646 */ + break; + + case 315: +#line 2018 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = SP_COORD_PACK_RANDOM( (yyvsp[-1].i) ); + } +#line 4720 "y.tab.c" /* yacc.c:1646 */ + break; + + case 316: +#line 2024 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (yyvsp[0].i); + } +#line 4728 "y.tab.c" /* yacc.c:1646 */ + break; + + case 317: +#line 2028 "lev_comp.y" /* yacc.c:1646 */ + { + if (((yyvsp[-2].i) & (yyvsp[0].i))) + lc_warning("Humidity flag used twice."); + (yyval.i) = ((yyvsp[-2].i) | (yyvsp[0].i)); + } +#line 4738 "y.tab.c" /* yacc.c:1646 */ + break; + + case 318: +#line 2036 "lev_comp.y" /* yacc.c:1646 */ + { + /* nothing */ + } +#line 4746 "y.tab.c" /* yacc.c:1646 */ + break; + + case 319: +#line 2040 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[0].map), SPOVAR_REGION); + vardef_used(variable_definitions, (yyvsp[0].map)); + add_opvars(splev, "v", (yyvsp[0].map)); + Free((yyvsp[0].map)); + } +#line 4757 "y.tab.c" /* yacc.c:1646 */ + break; + + case 320: +#line 2047 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[-3].map), SPOVAR_REGION|SPOVAR_ARRAY); + vardef_used(variable_definitions, (yyvsp[-3].map)); + add_opvars(splev, "v", (yyvsp[-3].map)); + Free((yyvsp[-3].map)); + } +#line 4768 "y.tab.c" /* yacc.c:1646 */ + break; + + case 321: +#line 2056 "lev_comp.y" /* yacc.c:1646 */ + { + long r = SP_REGION_PACK((yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + if ( (yyvsp[-7].i) > (yyvsp[-3].i) || (yyvsp[-5].i) > (yyvsp[-1].i) ) + lc_error("Region start > end: (%li,%li,%li,%li)!", (yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + + add_opvars(splev, "r", r); + (yyval.i) = r; + } +#line 4781 "y.tab.c" /* yacc.c:1646 */ + break; + + case 322: +#line 2067 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "m", (yyvsp[0].i)); + } +#line 4789 "y.tab.c" /* yacc.c:1646 */ + break; + + case 323: +#line 2071 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[0].map), SPOVAR_MAPCHAR); + vardef_used(variable_definitions, (yyvsp[0].map)); + add_opvars(splev, "v", (yyvsp[0].map)); + Free((yyvsp[0].map)); + } +#line 4800 "y.tab.c" /* yacc.c:1646 */ + break; + + case 324: +#line 2078 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[-3].map), SPOVAR_MAPCHAR|SPOVAR_ARRAY); + vardef_used(variable_definitions, (yyvsp[-3].map)); + add_opvars(splev, "v", (yyvsp[-3].map)); + Free((yyvsp[-3].map)); + } +#line 4811 "y.tab.c" /* yacc.c:1646 */ + break; + + case 325: +#line 2087 "lev_comp.y" /* yacc.c:1646 */ + { + if (what_map_char((char) (yyvsp[0].i)) != INVALID_TYPE) + (yyval.i) = SP_MAPCHAR_PACK(what_map_char((char) (yyvsp[0].i)), -2); + else { + lc_error("Unknown map char type '%c'!", (yyvsp[0].i)); + (yyval.i) = SP_MAPCHAR_PACK(STONE, -2); + } + } +#line 4824 "y.tab.c" /* yacc.c:1646 */ + break; + + case 326: +#line 2096 "lev_comp.y" /* yacc.c:1646 */ + { + if (what_map_char((char) (yyvsp[-3].i)) != INVALID_TYPE) + (yyval.i) = SP_MAPCHAR_PACK(what_map_char((char) (yyvsp[-3].i)), (yyvsp[-1].i)); + else { + lc_error("Unknown map char type '%c'!", (yyvsp[-3].i)); + (yyval.i) = SP_MAPCHAR_PACK(STONE, (yyvsp[-1].i)); + } + } +#line 4837 "y.tab.c" /* yacc.c:1646 */ + break; + + case 327: +#line 2107 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "M", (yyvsp[0].i)); + } +#line 4845 "y.tab.c" /* yacc.c:1646 */ + break; + + case 328: +#line 2111 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[0].map), SPOVAR_MONST); + vardef_used(variable_definitions, (yyvsp[0].map)); + add_opvars(splev, "v", (yyvsp[0].map)); + Free((yyvsp[0].map)); + } +#line 4856 "y.tab.c" /* yacc.c:1646 */ + break; + + case 329: +#line 2118 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[-3].map), SPOVAR_MONST|SPOVAR_ARRAY); + vardef_used(variable_definitions, (yyvsp[-3].map)); + add_opvars(splev, "v", (yyvsp[-3].map)); + Free((yyvsp[-3].map)); + } +#line 4867 "y.tab.c" /* yacc.c:1646 */ + break; + + case 330: +#line 2127 "lev_comp.y" /* yacc.c:1646 */ + { + long m = get_monster_id((yyvsp[0].map), (char)0); + if (m == ERR) { + lc_error("Unknown monster \"%s\"!", (yyvsp[0].map)); + (yyval.i) = -1; + } else + (yyval.i) = SP_MONST_PACK(m, def_monsyms[(int)mons[m].mlet].sym); + } +#line 4880 "y.tab.c" /* yacc.c:1646 */ + break; + + case 331: +#line 2136 "lev_comp.y" /* yacc.c:1646 */ + { + if (check_monster_char((char) (yyvsp[0].i))) + (yyval.i) = SP_MONST_PACK(-1, (yyvsp[0].i)); + else { + lc_error("Unknown monster class '%c'!", (yyvsp[0].i)); + (yyval.i) = -1; + } + } +#line 4893 "y.tab.c" /* yacc.c:1646 */ + break; + + case 332: +#line 2145 "lev_comp.y" /* yacc.c:1646 */ + { + long m = get_monster_id((yyvsp[-1].map), (char) (yyvsp[-3].i)); + if (m == ERR) { + lc_error("Unknown monster ('%c', \"%s\")!", (yyvsp[-3].i), (yyvsp[-1].map)); + (yyval.i) = -1; + } else + (yyval.i) = SP_MONST_PACK(m, (yyvsp[-3].i)); + } +#line 4906 "y.tab.c" /* yacc.c:1646 */ + break; + + case 333: +#line 2154 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = -1; + } +#line 4914 "y.tab.c" /* yacc.c:1646 */ + break; + + case 334: +#line 2160 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "O", (yyvsp[0].i)); + } +#line 4922 "y.tab.c" /* yacc.c:1646 */ + break; + + case 335: +#line 2164 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[0].map), SPOVAR_OBJ); + vardef_used(variable_definitions, (yyvsp[0].map)); + add_opvars(splev, "v", (yyvsp[0].map)); + Free((yyvsp[0].map)); + } +#line 4933 "y.tab.c" /* yacc.c:1646 */ + break; + + case 336: +#line 2171 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[-3].map), SPOVAR_OBJ|SPOVAR_ARRAY); + vardef_used(variable_definitions, (yyvsp[-3].map)); + add_opvars(splev, "v", (yyvsp[-3].map)); + Free((yyvsp[-3].map)); + } +#line 4944 "y.tab.c" /* yacc.c:1646 */ + break; + + case 337: +#line 2180 "lev_comp.y" /* yacc.c:1646 */ + { + long m = get_object_id((yyvsp[0].map), (char)0); + if (m == ERR) { + lc_error("Unknown object \"%s\"!", (yyvsp[0].map)); + (yyval.i) = -1; + } else + (yyval.i) = SP_OBJ_PACK(m, 1); /* obj class != 0 to force generation of a specific item */ + + } +#line 4958 "y.tab.c" /* yacc.c:1646 */ + break; + + case 338: +#line 2190 "lev_comp.y" /* yacc.c:1646 */ + { + if (check_object_char((char) (yyvsp[0].i))) + (yyval.i) = SP_OBJ_PACK(-1, (yyvsp[0].i)); else { - yyerror("Unknown monster class!"); - yyval.i = ERR; + lc_error("Unknown object class '%c'!", (yyvsp[0].i)); + (yyval.i) = -1; } } -break; -case 214: -{ - char c = yyvsp[0].i; - if (check_object_char(c)) - yyval.i = c; - else { - yyerror("Unknown char class!"); - yyval.i = ERR; - } +#line 4971 "y.tab.c" /* yacc.c:1646 */ + break; + + case 339: +#line 2199 "lev_comp.y" /* yacc.c:1646 */ + { + long m = get_object_id((yyvsp[-1].map), (char) (yyvsp[-3].i)); + if (m == ERR) { + lc_error("Unknown object ('%c', \"%s\")!", (yyvsp[-3].i), (yyvsp[-1].map)); + (yyval.i) = -1; + } else + (yyval.i) = SP_OBJ_PACK(m, (yyvsp[-3].i)); } -break; -case 218: -{ - yyval.i = 100; /* default is 100% */ +#line 4984 "y.tab.c" /* yacc.c:1646 */ + break; + + case 340: +#line 2208 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = -1; } -break; -case 219: -{ - if (yyvsp[0].i <= 0 || yyvsp[0].i > 100) - yyerror("Expected percentile chance."); - yyval.i = yyvsp[0].i; +#line 4992 "y.tab.c" /* yacc.c:1646 */ + break; + + case 341: +#line 2214 "lev_comp.y" /* yacc.c:1646 */ + { } +#line 4998 "y.tab.c" /* yacc.c:1646 */ + break; + + case 342: +#line 2216 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_MATH_ADD); } -break; -case 222: -{ - if (!in_room && !init_lev.init_present && - (yyvsp[-3].i < 0 || yyvsp[-3].i > (int)max_x_map || - yyvsp[-1].i < 0 || yyvsp[-1].i > (int)max_y_map)) - yyerror("Coordinates out of map range!"); - current_coord.x = yyvsp[-3].i; - current_coord.y = yyvsp[-1].i; +#line 5006 "y.tab.c" /* yacc.c:1646 */ + break; + + case 343: +#line 2221 "lev_comp.y" /* yacc.c:1646 */ + { add_opvars(splev, "i", (yyvsp[0].i) ); } +#line 5012 "y.tab.c" /* yacc.c:1646 */ + break; + + case 344: +#line 2222 "lev_comp.y" /* yacc.c:1646 */ + { is_inconstant_number = 1; } +#line 5018 "y.tab.c" /* yacc.c:1646 */ + break; + + case 345: +#line 2223 "lev_comp.y" /* yacc.c:1646 */ + { add_opvars(splev, "i", (yyvsp[-1].i) ); } +#line 5024 "y.tab.c" /* yacc.c:1646 */ + break; + + case 346: +#line 2225 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[0].map), SPOVAR_INT); + vardef_used(variable_definitions, (yyvsp[0].map)); + add_opvars(splev, "v", (yyvsp[0].map)); + Free((yyvsp[0].map)); + is_inconstant_number = 1; } -break; -case 223: -{ +#line 5036 "y.tab.c" /* yacc.c:1646 */ + break; + + case 347: +#line 2233 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[-3].map), SPOVAR_INT|SPOVAR_ARRAY); + vardef_used(variable_definitions, (yyvsp[-3].map)); + add_opvars(splev, "v", (yyvsp[-3].map)); + Free((yyvsp[-3].map)); + is_inconstant_number = 1; + } +#line 5048 "y.tab.c" /* yacc.c:1646 */ + break; + + case 348: +#line 2240 "lev_comp.y" /* yacc.c:1646 */ + { add_opvars(splev, "o", SPO_MATH_ADD); } +#line 5054 "y.tab.c" /* yacc.c:1646 */ + break; + + case 349: +#line 2241 "lev_comp.y" /* yacc.c:1646 */ + { add_opvars(splev, "o", SPO_MATH_SUB); } +#line 5060 "y.tab.c" /* yacc.c:1646 */ + break; + + case 350: +#line 2242 "lev_comp.y" /* yacc.c:1646 */ + { add_opvars(splev, "o", SPO_MATH_MUL); } +#line 5066 "y.tab.c" /* yacc.c:1646 */ + break; + + case 351: +#line 2243 "lev_comp.y" /* yacc.c:1646 */ + { add_opvars(splev, "o", SPO_MATH_DIV); } +#line 5072 "y.tab.c" /* yacc.c:1646 */ + break; + + case 352: +#line 2244 "lev_comp.y" /* yacc.c:1646 */ + { add_opvars(splev, "o", SPO_MATH_MOD); } +#line 5078 "y.tab.c" /* yacc.c:1646 */ + break; + + case 353: +#line 2245 "lev_comp.y" /* yacc.c:1646 */ + { } +#line 5084 "y.tab.c" /* yacc.c:1646 */ + break; + + case 354: +#line 2249 "lev_comp.y" /* yacc.c:1646 */ + { + if (!strcmp("int", (yyvsp[0].map)) || !strcmp("integer", (yyvsp[0].map))) { + (yyval.i) = (int)'i'; + } else lc_error("Unknown function parameter type '%s'", (yyvsp[0].map)); + } +#line 5094 "y.tab.c" /* yacc.c:1646 */ + break; + + case 355: +#line 2255 "lev_comp.y" /* yacc.c:1646 */ + { + if (!strcmp("str", (yyvsp[0].map)) || !strcmp("string", (yyvsp[0].map))) { + (yyval.i) = (int)'s'; + } else lc_error("Unknown function parameter type '%s'", (yyvsp[0].map)); + } +#line 5104 "y.tab.c" /* yacc.c:1646 */ + break; + + case 356: +#line 2263 "lev_comp.y" /* yacc.c:1646 */ + { + struct lc_funcdefs_parm *tmp = New(struct lc_funcdefs_parm); + + if (!curr_function) + lc_error("Function parameters outside function definition."); + else if (!tmp) + lc_error("Could not alloc function params."); + else { + tmp->name = strdup((yyvsp[-2].map)); + tmp->parmtype = (char) (yyvsp[0].i); + tmp->next = curr_function->params; + curr_function->params = tmp; + curr_function->n_params++; + { + long vt; + switch (tmp->parmtype) { + case 'i': vt = SPOVAR_INT; break; + case 's': vt = SPOVAR_STRING; break; + default: lc_error("Unknown func param conversion."); break; + } + variable_definitions = add_vardef_type(variable_definitions, (yyvsp[-2].map), vt); + } + } + Free((yyvsp[-2].map)); + } +#line 5134 "y.tab.c" /* yacc.c:1646 */ + break; + + case 361: +#line 2300 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (int)'i'; + } +#line 5142 "y.tab.c" /* yacc.c:1646 */ + break; + + case 362: +#line 2304 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.i) = (int)'s'; + } +#line 5150 "y.tab.c" /* yacc.c:1646 */ + break; + + case 363: +#line 2311 "lev_comp.y" /* yacc.c:1646 */ + { + char tmpbuf[2]; + tmpbuf[0] = (char) (yyvsp[0].i); + tmpbuf[1] = '\0'; + (yyval.map) = strdup(tmpbuf); + } +#line 5161 "y.tab.c" /* yacc.c:1646 */ + break; + + case 364: +#line 2318 "lev_comp.y" /* yacc.c:1646 */ + { + long len = strlen( (yyvsp[-2].map) ); + char *tmp = (char *)alloc(len + 2); + sprintf(tmp, "%c%s", (char) (yyvsp[0].i), (yyvsp[-2].map) ); + Free( (yyvsp[-2].map) ); + (yyval.map) = tmp; + } +#line 5173 "y.tab.c" /* yacc.c:1646 */ + break; + + case 365: +#line 2328 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.map) = strdup(""); + } +#line 5181 "y.tab.c" /* yacc.c:1646 */ + break; + + case 366: +#line 2332 "lev_comp.y" /* yacc.c:1646 */ + { + char *tmp = strdup( (yyvsp[0].map) ); + Free( (yyvsp[0].map) ); + (yyval.map) = tmp; + } +#line 5191 "y.tab.c" /* yacc.c:1646 */ + break; + + case 367: +#line 2340 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_SEL_POINT); + } +#line 5199 "y.tab.c" /* yacc.c:1646 */ + break; + + case 368: +#line 2344 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_SEL_RECT); + } +#line 5207 "y.tab.c" /* yacc.c:1646 */ + break; + + case 369: +#line 2348 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_SEL_FILLRECT); + } +#line 5215 "y.tab.c" /* yacc.c:1646 */ + break; + + case 370: +#line 2352 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_SEL_LINE); + } +#line 5223 "y.tab.c" /* yacc.c:1646 */ + break; + + case 371: +#line 2356 "lev_comp.y" /* yacc.c:1646 */ + { + /* randline (x1,y1),(x2,y2), roughness */ + add_opvars(splev, "o", SPO_SEL_RNDLINE); + } +#line 5232 "y.tab.c" /* yacc.c:1646 */ + break; + + case 372: +#line 2361 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", W_ANY, SPO_SEL_GROW); + } +#line 5240 "y.tab.c" /* yacc.c:1646 */ + break; + + case 373: +#line 2365 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", (yyvsp[-3].i), SPO_SEL_GROW); + } +#line 5248 "y.tab.c" /* yacc.c:1646 */ + break; + + case 374: +#line 2369 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iio", (yyvsp[-3].i), SPOFILTER_PERCENT, SPO_SEL_FILTER); + } +#line 5256 "y.tab.c" /* yacc.c:1646 */ + break; + + case 375: +#line 2373 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", SPOFILTER_SELECTION, SPO_SEL_FILTER); + } +#line 5264 "y.tab.c" /* yacc.c:1646 */ + break; + + case 376: +#line 2377 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", SPOFILTER_MAPCHAR, SPO_SEL_FILTER); + } +#line 5272 "y.tab.c" /* yacc.c:1646 */ + break; + + case 377: +#line 2381 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_SEL_FLOOD); + } +#line 5280 "y.tab.c" /* yacc.c:1646 */ + break; + + case 378: +#line 2385 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "oio", SPO_COPY, 1, SPO_SEL_ELLIPSE); + } +#line 5288 "y.tab.c" /* yacc.c:1646 */ + break; + + case 379: +#line 2389 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "oio", SPO_COPY, (yyvsp[-1].i), SPO_SEL_ELLIPSE); + } +#line 5296 "y.tab.c" /* yacc.c:1646 */ + break; + + case 380: +#line 2393 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", 1, SPO_SEL_ELLIPSE); + } +#line 5304 "y.tab.c" /* yacc.c:1646 */ + break; + + case 381: +#line 2397 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "io", (yyvsp[-1].i), SPO_SEL_ELLIPSE); + } +#line 5312 "y.tab.c" /* yacc.c:1646 */ + break; + + case 382: +#line 2401 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iio", (yyvsp[-5].i), (yyvsp[-11].i), SPO_SEL_GRADIENT); + } +#line 5320 "y.tab.c" /* yacc.c:1646 */ + break; + + case 383: +#line 2405 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_SEL_COMPLEMENT); + } +#line 5328 "y.tab.c" /* yacc.c:1646 */ + break; + + case 384: +#line 2409 "lev_comp.y" /* yacc.c:1646 */ + { + check_vardef_type(variable_definitions, (yyvsp[0].map), SPOVAR_SEL); + vardef_used(variable_definitions, (yyvsp[0].map)); + add_opvars(splev, "v", (yyvsp[0].map)); + Free((yyvsp[0].map)); + } +#line 5339 "y.tab.c" /* yacc.c:1646 */ + break; + + case 385: +#line 2416 "lev_comp.y" /* yacc.c:1646 */ + { + /* nothing */ + } +#line 5347 "y.tab.c" /* yacc.c:1646 */ + break; + + case 386: +#line 2422 "lev_comp.y" /* yacc.c:1646 */ + { + /* nothing */ + } +#line 5355 "y.tab.c" /* yacc.c:1646 */ + break; + + case 387: +#line 2426 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "o", SPO_SEL_ADD); + } +#line 5363 "y.tab.c" /* yacc.c:1646 */ + break; + + case 388: +#line 2432 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "iio", (yyvsp[0].dice).num, (yyvsp[0].dice).die, SPO_DICE); + } +#line 5371 "y.tab.c" /* yacc.c:1646 */ + break; + + case 392: +#line 2443 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", (yyvsp[0].i) ); + } +#line 5379 "y.tab.c" /* yacc.c:1646 */ + break; + + case 393: +#line 2447 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", (yyvsp[0].i) ); + } +#line 5387 "y.tab.c" /* yacc.c:1646 */ + break; + + case 394: +#line 2451 "lev_comp.y" /* yacc.c:1646 */ + { + add_opvars(splev, "i", (yyvsp[0].i) ); + } +#line 5395 "y.tab.c" /* yacc.c:1646 */ + break; + + case 395: +#line 2455 "lev_comp.y" /* yacc.c:1646 */ + { + /* nothing */ + } +#line 5403 "y.tab.c" /* yacc.c:1646 */ + break; + + case 404: +#line 2477 "lev_comp.y" /* yacc.c:1646 */ + { + (yyval.lregn) = (yyvsp[0].lregn); + } +#line 5411 "y.tab.c" /* yacc.c:1646 */ + break; + + case 405: +#line 2481 "lev_comp.y" /* yacc.c:1646 */ + { + if ((yyvsp[-7].i) <= 0 || (yyvsp[-7].i) >= COLNO) + lc_error("Region (%li,%li,%li,%li) out of level range (x1)!", (yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + else if ((yyvsp[-5].i) < 0 || (yyvsp[-5].i) >= ROWNO) + lc_error("Region (%li,%li,%li,%li) out of level range (y1)!", (yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + else if ((yyvsp[-3].i) <= 0 || (yyvsp[-3].i) >= COLNO) + lc_error("Region (%li,%li,%li,%li) out of level range (x2)!", (yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + else if ((yyvsp[-1].i) < 0 || (yyvsp[-1].i) >= ROWNO) + lc_error("Region (%li,%li,%li,%li) out of level range (y2)!", (yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + (yyval.lregn).x1 = (yyvsp[-7].i); + (yyval.lregn).y1 = (yyvsp[-5].i); + (yyval.lregn).x2 = (yyvsp[-3].i); + (yyval.lregn).y2 = (yyvsp[-1].i); + (yyval.lregn).area = 1; + } +#line 5431 "y.tab.c" /* yacc.c:1646 */ + break; + + case 406: +#line 2499 "lev_comp.y" /* yacc.c:1646 */ + { /* This series of if statements is a hack for MSC 5.1. It seems that its tiny little brain cannot compile if these are all one big if statement. */ - if (yyvsp[-7].i < 0 || yyvsp[-7].i > (int)max_x_map) - yyerror("Region out of map range!"); - else if (yyvsp[-5].i < 0 || yyvsp[-5].i > (int)max_y_map) - yyerror("Region out of map range!"); - else if (yyvsp[-3].i < 0 || yyvsp[-3].i > (int)max_x_map) - yyerror("Region out of map range!"); - else if (yyvsp[-1].i < 0 || yyvsp[-1].i > (int)max_y_map) - yyerror("Region out of map range!"); - current_region.x1 = yyvsp[-7].i; - current_region.y1 = yyvsp[-5].i; - current_region.x2 = yyvsp[-3].i; - current_region.y2 = yyvsp[-1].i; + if ((yyvsp[-7].i) < 0 || (yyvsp[-7].i) > (int)max_x_map) + lc_error("Region (%li,%li,%li,%li) out of map range (x1)!", (yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + else if ((yyvsp[-5].i) < 0 || (yyvsp[-5].i) > (int)max_y_map) + lc_error("Region (%li,%li,%li,%li) out of map range (y1)!", (yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + else if ((yyvsp[-3].i) < 0 || (yyvsp[-3].i) > (int)max_x_map) + lc_error("Region (%li,%li,%li,%li) out of map range (x2)!", (yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + else if ((yyvsp[-1].i) < 0 || (yyvsp[-1].i) > (int)max_y_map) + lc_error("Region (%li,%li,%li,%li) out of map range (y2)!", (yyvsp[-7].i), (yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].i)); + (yyval.lregn).area = 0; + (yyval.lregn).x1 = (yyvsp[-7].i); + (yyval.lregn).y1 = (yyvsp[-5].i); + (yyval.lregn).x2 = (yyvsp[-3].i); + (yyval.lregn).y2 = (yyvsp[-1].i); } -break; +#line 5453 "y.tab.c" /* yacc.c:1646 */ + break; + + +#line 5457 "y.tab.c" /* yacc.c:1646 */ + default: break; } - yyssp -= yym; - yystate = *yyssp; - yyvsp -= yym; - yym = yylhs[yyn]; - if (yystate == 0 && yym == 0) + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) { -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state 0 to\ - state %d\n", YYPREFIX, YYFINAL); + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR #endif - yystate = YYFINAL; - *++yyssp = YYFINAL; - *++yyvsp = yyval; - if (yychar < 0) + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) { - if ((yychar = yylex()) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, YYFINAL, yychar, yys); - } -#endif + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; } - if (yychar == 0) goto yyaccept; - goto yyloop; } - if ((yyn = yygindex[yym]) != 0 && (yyn += yystate) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yystate) - yystate = yytable[yyn]; - else - yystate = yydgoto[yym]; -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state %d \ -to state %d\n", YYPREFIX, *yyssp, yystate); -#endif - if (yyssp >= yyss + yystacksize - 1) + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) { - goto yyoverflow; + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); } - *++yyssp = yystate; - *++yyvsp = yyval; - goto yyloop; -yyoverflow: - yyerror("yacc stack overflow"); -yyabort: - return (1); -yyaccept: - return (0); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; } +#line 2519 "lev_comp.y" /* yacc.c:1906 */ + + +/*lev_comp.y*/ diff --git a/sys/unix/.gitattributes b/sys/unix/.gitattributes index 8cffb77ae..31e18fe84 100644 --- a/sys/unix/.gitattributes +++ b/sys/unix/.gitattributes @@ -1 +1 @@ -Makefile.* filter=NHtext merge=NHsubst +Makefile.* NHSUBST diff --git a/sys/unix/hints/.gitattributes b/sys/unix/hints/.gitattributes index a079959f1..db77844f7 100644 --- a/sys/unix/hints/.gitattributes +++ b/sys/unix/hints/.gitattributes @@ -1 +1 @@ -* filter=NHtext merge=NHsubst +* NHSUBST diff --git a/sys/unix/hints/linux-x11 b/sys/unix/hints/linux-x11 index e0d98badd..cf5dfb6f3 100644 --- a/sys/unix/hints/linux-x11 +++ b/sys/unix/hints/linux-x11 @@ -16,6 +16,7 @@ HACKDIR=$(PREFIX)/games/lib/$(GAME)dir SHELLDIR = $(PREFIX)/games CFLAGS=-O -I../include -DNOTPARMDECL $(CFLAGS1) $(CFLAGS3) +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" CFLAGS1=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" CFLAGS3=-DX11_GRAPHICS -DDEFAULT_WINDOW_SYS=\"X11\" -DNOTTYGRAPHICS diff --git a/sys/unix/sysconf b/sys/unix/sysconf index cff28b04f..50fa74085 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -14,6 +14,9 @@ WIZARDS=root games # Uses the same syntax as the WIZARDS option above. #SHELLERS= +# Users allowed to use #exploremode. Same syntax as WIZARDS above. +EXPLORERS=* + # Show debugging information originating from these source files. # Use '*' for all, or list source files separated by spaces. # Only available if game has been compiled with DEBUG. diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index f7f1ac87e..b31032efb 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 unixmain.c $NHDT-Date: 1426966705 2015/03/21 19:38:25 $ $NHDT-Branch: master $:$NHDT-Revision: 1.44 $ */ +/* NetHack 3.5 unixmain.c $NHDT-Date: 1427074144 2015/03/23 01:29:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.45 $ */ /* NetHack 3.5 unixmain.c $Date: 2012/01/27 20:15:31 $ $Revision: 1.42 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -324,7 +324,7 @@ process_options(argc, argv) int argc; char *argv[]; { - int i; + int i, l; /* * Process options. @@ -332,11 +332,25 @@ char *argv[]; while(argc > 1 && argv[1][0] == '-'){ argv++; argc--; + l = (int)strlen(*argv); + /* must supply at least 4 chars to match "-XXXgraphics" */ + if (l < 4) l = 4; + switch(argv[0][1]){ case 'D': - wizard = TRUE, discover = FALSE; + case 'd': + if ((argv[0][1] == 'D' && !argv[0][2]) + || !strcmpi(*argv, "-debug")) { + wizard = TRUE, discover = FALSE; + } else if (!strncmpi(*argv, "-DECgraphics", l)) { + load_symset("DECGraphics", PRIMARY); + switch_symbols(TRUE); + } else { + raw_printf("Unknown option: %s", *argv); + } break; case 'X': + discover = TRUE, wizard = FALSE; break; #ifdef NEWS @@ -356,17 +370,12 @@ char *argv[]; break; case 'I': case 'i': - if (!strncmpi(argv[0]+1, "IBM", 3)) { + if (!strncmpi(*argv, "-IBMgraphics", l)) { load_symset("IBMGraphics", PRIMARY); load_symset("RogueIBM", ROGUESET); switch_symbols(TRUE); - } - break; - /* case 'D': */ - case 'd': - if (!strncmpi(argv[0]+1, "DEC", 3)) { - load_symset("DECGraphics", PRIMARY); - switch_symbols(TRUE); + } else { + raw_printf("Unknown option: %s", *argv); } break; case 'p': /* profession (role) */ diff --git a/sys/vms/.gitattributes b/sys/vms/.gitattributes index 8cffb77ae..31e18fe84 100644 --- a/sys/vms/.gitattributes +++ b/sys/vms/.gitattributes @@ -1 +1 @@ -Makefile.* filter=NHtext merge=NHsubst +Makefile.* NHSUBST diff --git a/sys/wince/.gitattributes b/sys/wince/.gitattributes index e034edc5e..fbe75bcd4 100644 --- a/sys/wince/.gitattributes +++ b/sys/wince/.gitattributes @@ -1,3 +1,3 @@ -*.ce filter=NHtext merge=NHsubst -*.mak filter=NHtext merge=NHsubst -*.bat filter=NHtext merge=NHsubst +*.ce NHSUBST +*.mak NHSUBST +*.bat NHSUBST diff --git a/sys/winnt/.gitattributes b/sys/winnt/.gitattributes index 2a38b029c..88f970c96 100644 --- a/sys/winnt/.gitattributes +++ b/sys/winnt/.gitattributes @@ -1,4 +1,4 @@ -Install.nt filter=NHtext merge=NHsubst -Makefile.* filter=NHtext merge=NHsubst -*.rc filter=NHtext merge=NHsubst -*.bat filter=NHtext merge=NHsubst +Install.nt NHSUBST +Makefile.* NHSUBST +*.rc NHSUBST +*.bat NHSUBST diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 301dc279c..c808440ed 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -151,7 +151,7 @@ TARGET_CPU=x86 # -Zd - generate only public symbols and line numbers for debugging # -GS - enable security checks # -ccommon=-c $(CDBFLAG) -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -c +ccommon=-c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -c lflags=/INCREMENTAL:NO /NOLOGO !IF "$(TARGET_CPU)" == "x86" @@ -195,10 +195,6 @@ guilibs = $(winlibs) # Exe File Info. #========================================== -# -# For the level compiler bits, -# we just defer to win\win32\dgnstuff.mak -# and win\win32\levstuff.mak # # # Optional high-quality BSD random number generation routines @@ -271,44 +267,90 @@ DLBFLG = #========================================== #========================================== -INCLDIR= /I..\include +!IF "$(TARGET_CPU)" == "" +TARGET_CPU=x86 +!ENDIF + +!IF "$(_NMAKE_VER)" == "10.00.40219.01" +CL2013= +!ELSE +! IF ($(VSVER) > 2010) +CL2013=-sdl +! ENDIF +!ENDIF + +ccommon= -c -nologo -D"_CONSOLE" -D"_CRT_NONSTDC_NO_DEPRECATE" -D"_CRT_SECURE_NO_DEPRECATE" \ + -D"_LIB" -D"_SCL_SECURE_NO_DEPRECATE" -D"_VC80_UPGRADE=0x0600" -D"DLB" -D"_MBCS" \ + -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -D"NDEBUG" -D"YY_NO_UNISTD_H" -EHsc -fp:precise -Gd -GF -GS -Gy \ + $(CL2013) -WX- -Zc:forScope -Zc:wchar_t -Zi +cdebug= -analyze- -D"_DEBUG" -Gm -MTd -RTC1 -Od +crelease= -analyze- -D"_MBCS" -errorReport:prompt -GL -Gm- -MT -O2 -Ot -Ox -Oy + +lcommon= /NOLOGO /INCREMENTAL:NO !IF "$(DEBUGINFO)" == "Y" -CDBGFLAG=-Zi -LDBGFLAG=/debug -cdebug = -Zi -Od ldebug = /DEBUG +cflags1=$(ccommon) $(cdebug) +lflags1=$(lcommon) $(ldebug) !ELSE -CDBGFLAG= -LDBGFLAG= -ldebug = -cdebug = +ldebug= +cflags1=$(ccomon) $(crelease) +lflags1=$(lcommon) $(ldebug) !ENDIF -!IF ("$(ldebug)" != "") -!IF ("$(ldebug)" != "/RELEASE") -ldebug = /DEBUG -!ENDIF +lflags= $(lflags1) + +!IF "$(TARGET_CPU)" == "x86" +cflags = $(cflags1) -D_X86_=1 -DWIN32 -D_WIN32 -W3 +scall = -Gz + +!ELSEIF "$(TARGET_CPU)" == "x64" +cflags = $(cflags1) -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 +scall = !ENDIF -!IF ("$(cdebug)" != "") -!IF ("$(cdebug)" != "-Ox -DNDEBUG") -cdebug = -Zi -Od -!ENDIF +!IF "$(_NMAKE_VER)" == "10.00.40219.01" +cflags = $(cflags:-W4=-W3) !ENDIF -cflags2 = $(cflags:-W4=-W3) -#More verbose below -#cflags2 = $(cflags) -wd4131 -#cflags2 = $(cflags:-W4=-Wall) +#More verbose warning output options below +#cflags = $(cflags:-W4=-wd4131 +#cflags = $(cflags:-W4=-Wall) +#cflags = $(cflags:-W3=-wd4131 +#cflags = $(cflags:-W3=-Wall) + +# declarations for use on Intel x86 systems +!IF "$(TARGET_CPU)" == "x86" +DLLENTRY = @12 +!ENDIF + +# declarations for use on AMD64 systems +!IF "$(TARGET_CPU)" == "x64" +DLLENTRY = +!ENDIF + +# for Windows applications +conlflags = $(lflags) -subsystem:console,$(EXEVER) +guilflags = $(lflags) -subsystem:windows,$(EXEVER) +dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll + +# basic subsystem specific libraries, less the C Run-Time +baselibs = kernel32.lib $(optlibs) $(winsocklibs) advapi32.lib +winlibs = $(baselibs) user32.lib gdi32.lib comdlg32.lib winspool.lib + +# for Windows applications that use the C Run-Time libraries +conlibs = $(baselibs) +guilibs = $(winlibs) +# + +INCLDIR= /I..\include #========================================== # Util builds #========================================== -cflagsUtil = $(cdebug) $(cflags2) $(INCLDIR) \ - $(WINPFLAG) $(DLBFLG) -lflagsUtil = $(ldebug) $(lflags) $(conlibs) +cflagsUtil = $(cflags) $(INCLDIR) $(WINPFLAG) $(DLBFLG) +lflagsUtil = $(lflags) $(conlibs) #========================================== # - Game build @@ -320,15 +362,13 @@ LIBS= user32.lib winmm.lib $(ZLIB) !IF ("$(GRAPHICAL)"=="Y") -cflagsGame = $(cdebug) $(cflags2) $(guiflags) $(INCLDIR) \ - $(WINPFLAG) $(DLBFLG) -lflagsGame = $(ldebug) $(lflags) $(guilibs) $(GAMEPDBFILE) $(GAMEMAPFILE) +cflagsGame = $(cflags) $(guiflags) $(INCLDIR) $(WINPFLAG) $(DLBFLG) +lflagsGame = $(lflags) $(guilibs) $(GAMEPDBFILE) $(GAMEMAPFILE) !ELSE -cflagsGame = $(cdebug) $(cflags2) $(conflags) $(INCLDIR) \ - $(WINPFLAG) $(DLBFLG) -lflagsGame = $(ldebug) $(lflags) $(conlibs) $(GAMEPDBFILE) $(GAMEMAPFILE) +cflagsGame = $(cflags) $(conflags) $(INCLDIR) $(WINPFLAG) $(DLBFLG) +lflagsGame = $(lflags) $(conlibs) $(GAMEPDBFILE) $(GAMEMAPFILE) !ENDIF @@ -429,21 +469,15 @@ U = $(UTIL)^\ # Utility Objects. # -MAKESRC = $(U)makedefs.c +MAKESRC = $(U)makedefs.c -MAKEOBJS = $(O)makedefs.o $(O)monst.o $(O)objects.o +MAKEOBJS = $(O)makedefs.o $(O)monst.o $(O)objects.o -#SPLEVOBJS = $(O)lev_yacc.o $(O)lev_lex.o $(O)lev_main.o \ -# $(O)alloc.o $(O)decl.o $(O)drawing.o \ -# $(O)monst.o $(O)objects.o $(O)panic.o - -SPLEVOBJS = $(O)lev_yacc.o $(O)lev_lex.o $(O)lev_main.o \ - $(O)alloc.o $(O)decl.o $(O)drawing.o \ - $(O)monst.o $(O)objects.o $(O)panic.o - -DGNCOMPOBJS = $(O)dgn_yacc.o $(O)dgn_lex.o $(O)dgn_main.o \ - $(O)alloc.o $(O)panic.o +LEVCOMPOBJS = $(O)lev_yacc.o $(O)lev_lex.o $(O)lev_main.o \ + $(O)alloc.o $(O)decl.o $(O)drawing.o $(O)monst.o $(O)objects.o $(O)panic.o +DGNCOMPOBJS = $(O)dgn_yacc.o $(O)dgn_lex.o $(O)dgn_main.o \ + $(O)alloc.o $(O)panic.o RECOVOBJS = $(O)recover.o @@ -704,7 +738,7 @@ $(NHRES): $(MSWSYS)\console.rc $(MSWSYS)\NetHack.ico $(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag $(WINDLLS) @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR) - @echo Linking.... + @echo Linking $@ $(link) $(lflagsGame) /STACK:2048 $(LIBS) $(COMCTRL) -out:$@ @<<$(GAME).lnk $(ALLOBJ:^ =^ ) $(NHRES) @@ -782,12 +816,14 @@ $(GAMEDIR)\nhraykey.dll : $(O)$(@B).o $(O)gamedir.tag $(O)$(@B).def # Makedefs Stuff #========================================== $(U)nhsizes.exe: $(O)nhsizes.o + @echo Linking $@ $(link) $(lflagsUtil) -out:$@ $(O)nhsizes.o $(O)panic.o $(O)alloc.o $(O)nhsizes.o: $(CONFIG_H) nhsizes.c @$(CC) $(cflagsUtil) -Fo$@ nhsizes.c $(U)makedefs.exe: $(MAKEOBJS) + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ $(MAKEOBJS) $(O)makedefs.o: $(CONFIG_H) $(INCL)\monattk.h $(INCL)\monflag.h $(INCL)\objclass.h \ @@ -795,7 +831,7 @@ $(O)makedefs.o: $(CONFIG_H) $(INCL)\monattk.h $(INCL)\monflag.h $(INCL)\objcla $(U)makedefs.c @if not exist $(OBJ)\*.* echo creating directory $(OBJ) @if not exist $(OBJ)\*.* mkdir $(OBJ) - $(CC) $(cflagsUtil) -Fo$@ $(U)makedefs.c + @$(CC) $(cflagsUtil) -Fo$@ $(U)makedefs.c # # date.h should be remade every time any of the source or include @@ -836,6 +872,7 @@ $(DAT)\bogusmon: $(DAT)\bogusmon.txt $(U)makedefs.exe #========================================== $(U)uudecode.exe: $(O)uudecode.o + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ $(O)uudecode.o $(O)uudecode.o: $(SSYS)\uudecode.c @@ -891,24 +928,20 @@ $(WIN32)\splash.bmp: $(U)uudecode.exe $(WIN32)\splash.uu $(U)lev_yacc.c $(INCL)\lev_comp.h: $(U)lev_comp.y nmake -nologo -f ..\win\win32\levstuff.mak default -LEVCFLAGS=-c -nologo -DWIN32 -D_WIN32 -I$(INCL) -nologo -Z7 -Od -DDLB - $(O)lev_yacc.o: $(HACK_H) $(SP_LEV_H) $(INCL)\lev_comp.h $(U)lev_yacc.c - $(CC) $(LEVCFLAGS) -W0 -Fo$@ $(U)lev_yacc.c + @$(CC) $(cflagsUtil) -Fo$@ $(U)lev_yacc.c -$(O)lev_lex.o: $(HACK_H) $(INCL)\lev_comp.h $(SP_LEV_H) \ +$(O)lev_lex.o: $(HACK_H) $(INCL)\lev_comp.h $(SP_LEV_H) \ $(U)lev_lex.c - $(CC) $(LEVCFLAGS) -W0 -Fo$@ $(U)lev_lex.c + @$(CC) $(cflagsUtil) -Fo$@ $(U)lev_lex.c -$(O)lev_main.o: $(U)lev_main.c $(HACK_H) $(SP_LEV_H) - $(CC) $(LEVCFLAGS) -W0 -Fo$@ $(U)lev_main.c +$(O)lev_main.o: $(U)lev_main.c $(HACK_H) $(SP_LEV_H) + @$(CC) $(cflagsUtil) -Fo$@ $(U)lev_main.c -$(U)levcomp.exe: $(SPLEVOBJS) - @echo Linking $@... - echo $(link) - echo $(lflagsUtil) - $(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk - $(SPLEVOBJS:^ =^ +$(U)levcomp.exe: $(LEVCOMPOBJS) + @echo Linking $@ + @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk + $(LEVCOMPOBJS:^ =^ ) << @@ -922,17 +955,17 @@ $(U)dgn_yacc.c $(INCL)\dgn_comp.h : $(U)dgn_comp.y nmake -nologo -f ..\win\win32\dgnstuff.mak default $(O)dgn_yacc.o: $(HACK_H) $(DGN_FILE_H) $(INCL)\dgn_comp.h $(U)dgn_yacc.c - @$(CC) $(LEVCFLAGS) -W0 -Fo$@ $(U)dgn_yacc.c + @$(CC) $(cflagsUtil) -Fo$@ $(U)dgn_yacc.c $(O)dgn_lex.o: $(HACK_H) $(DGN_FILE_H) $(INCL)\dgn_comp.h \ $(U)dgn_lex.c - @$(CC) $(LEVCFLAGS) -W0 -Fo$@ $(U)dgn_lex.c + @$(CC) $(cflagsUtil) -Fo$@ $(U)dgn_lex.c $(O)dgn_main.o: $(HACK_H) $(U)dgn_main.c - @$(CC) $(LEVCFLAGS) -W0 -Fo$@ $(U)dgn_main.c + @$(CC) $(cflagsUtil) -Fo$@ $(U)dgn_main.c $(U)dgncomp.exe: $(DGNCOMPOBJS) - @echo Linking $@... + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk $(DGNCOMPOBJS:^ =^ ) @@ -990,6 +1023,7 @@ $(INCL)\win32api.h: $(MSWSYS)\win32api.h #========================================== $(U)dlb_main.exe: $(DLBOBJ) $(O)dlb.o + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk $(O)dlb_main.o $(O)dlb.o @@ -1040,10 +1074,11 @@ nhdat: $(U)dlb_main.exe $(DAT)\data $(DAT)\oracles $(OPTIONS_FILE) \ #========================================== $(U)recover.exe: $(RECOVOBJS) + @echo Linking $@ $(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ $(RECOVOBJS) $(O)recover.o: $(CONFIG_H) $(U)recover.c $(INCL)\win32api.h - $(CC) $(cflagsUtil) -Fo$@ $(U)recover.c + @$(CC) $(cflagsUtil) -Fo$@ $(U)recover.c #========================================== # Tile Mapping @@ -1054,6 +1089,7 @@ $(SRC)\tile.c: $(U)tilemap.exe @$(U)tilemap $(U)tilemap.exe: $(O)tilemap.o + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ $(O)tilemap.o $(O)tilemap.o: $(WSHR)\tilemap.c $(HACK_H) @@ -1085,7 +1121,7 @@ $(O)tilete32.o: $(WSHR)\tiletext.c $(CONFIG_H) $(TILE_H) #========================================== $(U)gif2txt.exe: $(GIFREADERS) $(TEXT_IO) - @echo Linking $@... + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk $(GIFREADERS:^ =^ ) @@ -1094,7 +1130,7 @@ $(U)gif2txt.exe: $(GIFREADERS) $(TEXT_IO) << $(U)gif2tx32.exe: $(GIFREADERS32) $(TEXT_IO32) - @echo Linking $@... + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk $(GIFREADERS32:^ =^ ) @@ -1103,7 +1139,7 @@ $(U)gif2tx32.exe: $(GIFREADERS32) $(TEXT_IO32) << $(U)txt2ppm.exe: $(PPMWRITERS) $(TEXT_IO) - @echo Linking $@... + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk $(PPMWRITERS:^ =^ ) @@ -1125,7 +1161,7 @@ $(TILEBMP32): !ENDIF $(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXT_IO) - @echo Linking $@... + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk $(O)tile2bmp.o $(TEXT_IO:^ =^ @@ -1133,7 +1169,7 @@ $(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXT_IO) << $(U)til2bm32.exe: $(O)til2bm32.o $(TEXT_IO32) - @echo Linking $@... + @echo Linking $@ @$(link) $(lflagsUtil) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk $(O)til2bm32.o $(TEXT_IO32:^ =^ diff --git a/util/.gitattributes b/util/.gitattributes index 15e23d268..8b2657e61 100644 --- a/util/.gitattributes +++ b/util/.gitattributes @@ -1,2 +1,2 @@ -*.pl filter=NHtext merge=NHsubst -*.[ly] filter=NHtext merge=NHsubst +*.pl NHSUBST +*.[ly] NHSUBST diff --git a/util/lev_comp.l b/util/lev_comp.l index 2b0ad5188..bba52c270 100644 --- a/util/lev_comp.l +++ b/util/lev_comp.l @@ -66,16 +66,36 @@ int FDECL(yyoutput, (int)); void FDECL(init_yyin, (FILE *)); void FDECL(init_yyout, (FILE *)); +long NDECL(handle_varstring_check); +long FDECL(corefunc_str_check, (char *, long)); + +extern struct lc_vardefs *FDECL(vardef_defined,(struct lc_vardefs *,char *, int)); + +extern struct lc_vardefs *variable_definitions; + +extern long FDECL(method_defined, (char *, long, long *)); + +void FDECL(savetoken, (char *)); +void NDECL(newline); +void FDECL(advancepos, (char *)); + /* * This doesn't always get put in lev_comp.h * (esp. when using older versions of bison). */ extern YYSTYPE yylval; -int nh_line_number = 1, colon_line_number = 1; +int nh_line_number = 1; +int token_start_pos = 0; +char curr_token[512]; static char map[4096]; static int map_cnt = 0; +FILE *orig_yyin = NULL; + +#define ST_RET(x) do { savetoken(yytext); return x; } while (0); +#define ST_RETF(y, x) do { savetoken(yytext); y; return x; } while (0); + %} %e 1500 %p 5000 @@ -83,6 +103,7 @@ static int map_cnt = 0; %s MAPC %% ENDMAP { + savetoken(yytext); BEGIN(INITIAL); yylval.map = (char *) alloc(map_cnt + 1); (void) strncpy(yylval.map, map, map_cnt); @@ -90,129 +111,230 @@ static int map_cnt = 0; map_cnt = 0; return MAP_ID; } -[-|}{+ABCISHKPLWTF\\#. 0123456789]*\r?\n { +[-|}{+xABCISHKMPLWTtFYU\\#. 0123456789]*\r?\n { int len = yyleng; + savetoken(yytext); /* convert \r\n to \n */ if (len >= 2 && yytext[len - 2] == '\r') len -= 1; - nh_line_number++; (void) strncpy(map + map_cnt, yytext, len); map_cnt += len; map[map_cnt - 1] = '\n'; map[map_cnt] = '\0'; + newline(); } -^#.*\n { nh_line_number++; } -: { colon_line_number = nh_line_number; return ':'; } -MESSAGE return MESSAGE_ID; -MAZE return MAZE_ID; -NOMAP return NOMAP_ID; -LEVEL return LEVEL_ID; -INIT_MAP return LEV_INIT_ID; -FLAGS return FLAGS_ID; -GEOMETRY return GEOMETRY_ID; -^MAP\r?\n { BEGIN(MAPC); nh_line_number++; } -OBJECT return OBJECT_ID; -CONTAINER return COBJECT_ID; -MONSTER return MONSTER_ID; -TRAP return TRAP_ID; -DOOR return DOOR_ID; -DRAWBRIDGE return DRAWBRIDGE_ID; -MAZEWALK return MAZEWALK_ID; -WALLIFY return WALLIFY_ID; -REGION return REGION_ID; -RANDOM_OBJECTS return RANDOM_OBJECTS_ID; -RANDOM_MONSTERS return RANDOM_MONSTERS_ID; -RANDOM_PLACES return RANDOM_PLACES_ID; -ALTAR return ALTAR_ID; -LADDER return LADDER_ID; -STAIR return STAIR_ID; -PORTAL return PORTAL_ID; -TELEPORT_REGION return TELEPRT_ID; -BRANCH return BRANCH_ID; -FOUNTAIN return FOUNTAIN_ID; -SINK return SINK_ID; -POOL return POOL_ID; -NON_DIGGABLE return NON_DIGGABLE_ID; -NON_PASSWALL return NON_PASSWALL_ID; -ROOM return ROOM_ID; -SUBROOM return SUBROOM_ID; -RANDOM_CORRIDORS return RAND_CORRIDOR_ID; -CORRIDOR return CORRIDOR_ID; -GOLD return GOLD_ID; -ENGRAVING return ENGRAVING_ID; -NAME return NAME_ID; -CHANCE return CHANCE_ID; -levregion return LEV; -open { yylval.i=D_ISOPEN; return DOOR_STATE; } -closed { yylval.i=D_CLOSED; return DOOR_STATE; } -locked { yylval.i=D_LOCKED; return DOOR_STATE; } -nodoor { yylval.i=D_NODOOR; return DOOR_STATE; } -broken { yylval.i=D_BROKEN; return DOOR_STATE; } -north { yylval.i=W_NORTH; return DIRECTION; } -east { yylval.i=W_EAST; return DIRECTION; } -south { yylval.i=W_SOUTH; return DIRECTION; } -west { yylval.i=W_WEST; return DIRECTION; } -random { yylval.i = -1; return RANDOM_TYPE; } -none { yylval.i = -2; return NONE; } -object return O_REGISTER; -monster return M_REGISTER; -place return P_REGISTER; -align return A_REGISTER; -left { yylval.i=1; return LEFT_OR_RIGHT; } -half-left { yylval.i=2; return LEFT_OR_RIGHT; } -center { yylval.i=3; return CENTER; } -half-right { yylval.i=4; return LEFT_OR_RIGHT; } -right { yylval.i=5; return LEFT_OR_RIGHT; } -top { yylval.i=1; return TOP_OR_BOT; } -bottom { yylval.i=5; return TOP_OR_BOT; } -lit { yylval.i=1; return LIGHT_STATE; } -unlit { yylval.i=0; return LIGHT_STATE; } -filled { yylval.i=0; return FILLING; } -unfilled { yylval.i=1; return FILLING; } -noalign { yylval.i= AM_NONE; return ALIGNMENT; } -law { yylval.i= AM_LAWFUL; return ALIGNMENT; } -neutral { yylval.i= AM_NEUTRAL; return ALIGNMENT; } -chaos { yylval.i= AM_CHAOTIC; return ALIGNMENT; } -coaligned { yylval.i= AM_SPLEV_CO; return ALIGNMENT; } -noncoaligned { yylval.i= AM_SPLEV_NONCO; return ALIGNMENT; } -peaceful { yylval.i=1; return MON_ATTITUDE; } -hostile { yylval.i=0; return MON_ATTITUDE; } -asleep { yylval.i=1; return MON_ALERTNESS; } -awake { yylval.i=0; return MON_ALERTNESS; } -m_feature { yylval.i= M_AP_FURNITURE; return MON_APPEARANCE; } -m_monster { yylval.i= M_AP_MONSTER; return MON_APPEARANCE; } -m_object { yylval.i= M_AP_OBJECT; return MON_APPEARANCE; } -sanctum { yylval.i=2; return ALTAR_TYPE; } -shrine { yylval.i=1; return ALTAR_TYPE; } -altar { yylval.i=0; return ALTAR_TYPE; } -up { yylval.i=1; return UP_OR_DOWN; } -down { yylval.i=0; return UP_OR_DOWN; } -false { yylval.i=0; return BOOLEAN; } -true { yylval.i=1; return BOOLEAN; } -dust { yylval.i=DUST; return ENGRAVING_TYPE; } -engrave { yylval.i=ENGRAVE; return ENGRAVING_TYPE; } -burn { yylval.i=BURN; return ENGRAVING_TYPE; } -mark { yylval.i=MARK; return ENGRAVING_TYPE; } -blood { yylval.i=ENGR_BLOOD; return ENGRAVING_TYPE; } -blessed { yylval.i=1; return CURSE_TYPE; } -uncursed { yylval.i=2; return CURSE_TYPE; } -cursed { yylval.i=3; return CURSE_TYPE; } -contained { return CONTAINED; } -noteleport { yylval.i=NOTELEPORT; return FLAG_TYPE; } -hardfloor { yylval.i=HARDFLOOR; return FLAG_TYPE; } -nommap { yylval.i=NOMMAP; return FLAG_TYPE; } -arboreal { yylval.i=ARBOREAL; return FLAG_TYPE; } /* KMH */ -shortsighted { yylval.i=SHORTSIGHTED; return FLAG_TYPE; } -\[\ *[0-9]+\%\ *\] { yylval.i = atoi(yytext + 1); return PERCENT; } -[+\-]?[0-9]+ { yylval.i=atoi(yytext); return INTEGER; } -\"[^"]*\" { yytext[yyleng-1] = 0; /* Discard the trailing \" */ +^[ \t]*#.*\n { savetoken(yytext); newline(); } +MESSAGE ST_RET(MESSAGE_ID); +NOMAP ST_RET(NOMAP_ID); +MAZE ST_RET(MAZE_ID); +LEVEL ST_RET(LEVEL_ID); +INIT_MAP ST_RET(LEV_INIT_ID); +mazegrid ST_RET(MAZE_GRID_ID); +solidfill ST_RET(SOLID_FILL_ID); +mines ST_RET(MINES_ID); +rogue ST_RET(ROGUELEV_ID); +FLAGS ST_RET(FLAGS_ID); +GEOMETRY ST_RET(GEOMETRY_ID); +^MAP\r?\n { savetoken(yytext); BEGIN(MAPC); newline(); } +obj(ect)? ST_RET(object_ID); +OBJECT ST_RET(OBJECT_ID); +CONTAINER ST_RET(COBJECT_ID); +MONSTER ST_RET(MONSTER_ID); +monster ST_RET(monster_ID); +TRAP ST_RET(TRAP_ID); +DOOR ST_RET(DOOR_ID); +ROOMDOOR ST_RET(ROOMDOOR_ID); +DRAWBRIDGE ST_RET(DRAWBRIDGE_ID); +MAZEWALK ST_RET(MAZEWALK_ID); +WALLIFY ST_RET(WALLIFY_ID); +REGION ST_RET(REGION_ID); +ALTAR ST_RET(ALTAR_ID); +LADDER ST_RET(LADDER_ID); +STAIR ST_RET(STAIR_ID); +PORTAL ST_RET(PORTAL_ID); +TELEPORT_REGION ST_RET(TELEPRT_ID); +BRANCH ST_RET(BRANCH_ID); +FOUNTAIN ST_RET(FOUNTAIN_ID); +SINK ST_RET(SINK_ID); +POOL ST_RET(POOL_ID); +NON_DIGGABLE ST_RET(NON_DIGGABLE_ID); +NON_PASSWALL ST_RET(NON_PASSWALL_ID); +IF ST_RET(IF_ID); +ELSE ST_RET(ELSE_ID); +EXIT ST_RET(EXIT_ID); +ROOM ST_RET(ROOM_ID); +SUBROOM ST_RET(SUBROOM_ID); +RANDOM_CORRIDORS ST_RET(RAND_CORRIDOR_ID); +CORRIDOR ST_RET(CORRIDOR_ID); +TERRAIN ST_RET(TERRAIN_ID); +terrain ST_RET(terrain_ID); +REPLACE_TERRAIN ST_RET(REPLACE_TERRAIN_ID); +GOLD ST_RET(GOLD_ID); +GRAVE ST_RET(GRAVE_ID); +ENGRAVING ST_RET(ENGRAVING_ID); +MINERALIZE ST_RET(MINERALIZE_ID); +(NAME|name) ST_RET(NAME_ID); +FOR ST_RET(FOR_ID); +TO ST_RET(TO_ID); +LOOP ST_RET(LOOP_ID); +SWITCH ST_RET(SWITCH_ID); +CASE ST_RET(CASE_ID); +BREAK ST_RET(BREAK_ID); +DEFAULT ST_RET(DEFAULT_ID); +FUNCTION ST_RET(FUNCTION_ID); +SHUFFLE ST_RET(SHUFFLE_ID); +montype ST_RET(MONTYPE_ID); +selection ST_RET(selection_ID); +rect ST_RET(rect_ID); +fillrect ST_RET(fillrect_ID); +line ST_RET(line_ID); +randline ST_RET(randline_ID); +grow ST_RET(grow_ID); +floodfill ST_RET(flood_ID); +rndcoord ST_RET(rndcoord_ID); +circle ST_RET(circle_ID); +ellipse ST_RET(ellipse_ID); +filter ST_RET(filter_ID); +gradient ST_RET(gradient_ID); +complement ST_RET(complement_ID); +radial { savetoken(yytext); yylval.i=SEL_GRADIENT_RADIAL; return GRADIENT_TYPE; } +square { savetoken(yytext); yylval.i=SEL_GRADIENT_SQUARE; return GRADIENT_TYPE; } +dry { savetoken(yytext); yylval.i=DRY; return HUMIDITY_TYPE; } +wet { savetoken(yytext); yylval.i=WET; return HUMIDITY_TYPE; } +hot { savetoken(yytext); yylval.i=HOT; return HUMIDITY_TYPE; } +solid { savetoken(yytext); yylval.i=SOLID; return HUMIDITY_TYPE; } +any { savetoken(yytext); yylval.i=ANY_LOC; return HUMIDITY_TYPE; } +levregion ST_RET(LEV); +quantity ST_RET(QUANTITY_ID); +buried ST_RET(BURIED_ID); +eroded ST_RET(ERODED_ID); +erodeproof ST_RET(ERODEPROOF_ID); +trapped ST_RET(TRAPPED_ID); +recharged ST_RET(RECHARGED_ID); +invisible ST_RET(INVIS_ID); +greased ST_RET(GREASED_ID); +female ST_RET(FEMALE_ID); +cancelled ST_RET(CANCELLED_ID); +revived ST_RET(REVIVED_ID); +avenge ST_RET(AVENGE_ID); +fleeing ST_RET(FLEEING_ID); +blinded ST_RET(BLINDED_ID); +paralyzed ST_RET(PARALYZED_ID); +stunned ST_RET(STUNNED_ID); +confused ST_RET(CONFUSED_ID); +seen_traps ST_RET(SEENTRAPS_ID); +all ST_RET(ALL_ID); +horizontal ST_RETF((yylval.i=1), HORIZ_OR_VERT); +vertical { savetoken(yytext); yylval.i=2; return HORIZ_OR_VERT; } +open { savetoken(yytext); yylval.i=D_ISOPEN; return DOOR_STATE; } +closed { savetoken(yytext); yylval.i=D_CLOSED; return DOOR_STATE; } +locked { savetoken(yytext); yylval.i=D_LOCKED; return DOOR_STATE; } +nodoor { savetoken(yytext); yylval.i=D_NODOOR; return DOOR_STATE; } +broken { savetoken(yytext); yylval.i=D_BROKEN; return DOOR_STATE; } +secret { savetoken(yytext); yylval.i=D_SECRET; return DOOR_STATE; } +north { savetoken(yytext); yylval.i=W_NORTH; return DIRECTION; } +east { savetoken(yytext); yylval.i=W_EAST; return DIRECTION; } +south { savetoken(yytext); yylval.i=W_SOUTH; return DIRECTION; } +west { savetoken(yytext); yylval.i=W_WEST; return DIRECTION; } +random { savetoken(yytext); yylval.i = -1; return RANDOM_TYPE; } +random\[ { savetoken(yytext); yylval.i = -1; return RANDOM_TYPE_BRACKET; } +none { savetoken(yytext); yylval.i = -2; return NONE; } +align ST_RET(A_REGISTER); +left { savetoken(yytext); yylval.i=1; return LEFT_OR_RIGHT; } +half-left { savetoken(yytext); yylval.i=2; return LEFT_OR_RIGHT; } +center { savetoken(yytext); yylval.i=3; return CENTER; } +half-right { savetoken(yytext); yylval.i=4; return LEFT_OR_RIGHT; } +right { savetoken(yytext); yylval.i=5; return LEFT_OR_RIGHT; } +top { savetoken(yytext); yylval.i=1; return TOP_OR_BOT; } +bottom { savetoken(yytext); yylval.i=5; return TOP_OR_BOT; } +lit { savetoken(yytext); yylval.i=1; return LIGHT_STATE; } +unlit { savetoken(yytext); yylval.i=0; return LIGHT_STATE; } +filled { savetoken(yytext); yylval.i=1; return FILLING; } +unfilled { savetoken(yytext); yylval.i=0; return FILLING; } +regular { savetoken(yytext); yylval.i=0; return IRREGULAR; } +irregular { savetoken(yytext); yylval.i=1; return IRREGULAR; } +unjoined { savetoken(yytext); yylval.i=1; return JOINED; } +joined { savetoken(yytext); yylval.i=0; return JOINED; } +limited { savetoken(yytext); yylval.i=1; return LIMITED; } +unlimited { savetoken(yytext); yylval.i=0; return LIMITED; } +noalign { savetoken(yytext); yylval.i= AM_NONE; return ALIGNMENT; } +law { savetoken(yytext); yylval.i= AM_LAWFUL; return ALIGNMENT; } +neutral { savetoken(yytext); yylval.i= AM_NEUTRAL; return ALIGNMENT; } +chaos { savetoken(yytext); yylval.i= AM_CHAOTIC; return ALIGNMENT; } +coaligned { savetoken(yytext); yylval.i= AM_SPLEV_CO; return ALIGNMENT; } +noncoaligned { savetoken(yytext); yylval.i= AM_SPLEV_NONCO; return ALIGNMENT; } +peaceful { savetoken(yytext); yylval.i=1; return MON_ATTITUDE; } +hostile { savetoken(yytext); yylval.i=0; return MON_ATTITUDE; } +asleep { savetoken(yytext); yylval.i=1; return MON_ALERTNESS; } +awake { savetoken(yytext); yylval.i=0; return MON_ALERTNESS; } +m_feature { savetoken(yytext); yylval.i= M_AP_FURNITURE; return MON_APPEARANCE; } +m_monster { savetoken(yytext); yylval.i= M_AP_MONSTER; return MON_APPEARANCE; } +m_object { savetoken(yytext); yylval.i= M_AP_OBJECT; return MON_APPEARANCE; } +sanctum { savetoken(yytext); yylval.i=2; return ALTAR_TYPE; } +shrine { savetoken(yytext); yylval.i=1; return ALTAR_TYPE; } +altar { savetoken(yytext); yylval.i=0; return ALTAR_TYPE; } +up { savetoken(yytext); yylval.i=1; return UP_OR_DOWN; } +down { savetoken(yytext); yylval.i=0; return UP_OR_DOWN; } +false { savetoken(yytext); yylval.i=0; return BOOLEAN; } +true { savetoken(yytext); yylval.i=1; return BOOLEAN; } +dust { savetoken(yytext); yylval.i=DUST; return ENGRAVING_TYPE; } +engrave { savetoken(yytext); yylval.i=ENGRAVE; return ENGRAVING_TYPE; } +burn { savetoken(yytext); yylval.i=BURN; return ENGRAVING_TYPE; } +mark { savetoken(yytext); yylval.i=MARK; return ENGRAVING_TYPE; } +blood { savetoken(yytext); yylval.i=ENGR_BLOOD; return ENGRAVING_TYPE; } +blessed { savetoken(yytext); yylval.i=1; return CURSE_TYPE; } +uncursed { savetoken(yytext); yylval.i=2; return CURSE_TYPE; } +cursed { savetoken(yytext); yylval.i=3; return CURSE_TYPE; } +noteleport { savetoken(yytext); yylval.i=NOTELEPORT; return FLAG_TYPE; } +hardfloor { savetoken(yytext); yylval.i=HARDFLOOR; return FLAG_TYPE; } +nommap { savetoken(yytext); yylval.i=NOMMAP; return FLAG_TYPE; } +arboreal { savetoken(yytext); yylval.i=ARBOREAL; return FLAG_TYPE; } /* KMH */ +shortsighted { savetoken(yytext); yylval.i=SHORTSIGHTED; return FLAG_TYPE; } +mazelevel { savetoken(yytext); yylval.i=MAZELEVEL; return FLAG_TYPE; } +premapped { savetoken(yytext); yylval.i=PREMAPPED; return FLAG_TYPE; } +shroud { savetoken(yytext); yylval.i=SHROUD; return FLAG_TYPE; } +graveyard { savetoken(yytext); yylval.i=GRAVEYARD; return FLAG_TYPE; } +icedpools { savetoken(yytext); yylval.i=ICEDPOOLS; return FLAG_TYPE; } +solidify { savetoken(yytext); yylval.i=SOLIDIFY; return FLAG_TYPE; } +[0-9]+d[0-9]+ { char *p = strchr(yytext, 'd'); + savetoken(yytext); + if (p) { + *p = '\0'; + p++; + yylval.dice.num=atoi(yytext); + yylval.dice.die=atoi(p); + } else { yylval.dice.num = yylval.dice.die = 1; } + return DICE; + } +\[\ *[0-9]+\%\ *\] { savetoken(yytext); yylval.i = atoi(yytext + 1); + if (yylval.i < 0 || yylval.i > 100) + lc_error("Unexpected percentile '%li%%'", yylval.i); + return PERCENT; } +-[0-9]+ { savetoken(yytext); yylval.i=atoi(yytext); return MINUS_INTEGER; } +\+[0-9]+ { savetoken(yytext); yylval.i=atoi(yytext); return PLUS_INTEGER; } +[0-9]+\% { savetoken(yytext); yylval.i = atoi(yytext); + if (yylval.i < 0 || yylval.i > 100) + lc_error("Unexpected percentile '%li%%'", yylval.i); + return SPERCENT; } +[0-9]+ { savetoken(yytext); yylval.i=atoi(yytext); return INTEGER; } +\"[^"]*\" { savetoken(yytext); + yytext[yyleng-1] = 0; /* Discard the trailing \" */ yylval.map = (char *) alloc(strlen(yytext+1)+1); Strcpy(yylval.map, yytext+1); /* Discard the first \" */ return STRING; } -\r?\n { nh_line_number++; } -[ \t]+ ; -'\\.' { yylval.i = yytext[2]; return CHAR; } -'.' { yylval.i = yytext[1]; return CHAR; } -. { return yytext[0]; } +\$[a-zA-Z_]+ { savetoken(yytext); return handle_varstring_check(); } +"==" { savetoken(yytext); yylval.i = SPO_JE; return COMPARE_TYPE; } +"!=" { savetoken(yytext); yylval.i = SPO_JNE; return COMPARE_TYPE; } +"<>" { savetoken(yytext); yylval.i = SPO_JNE; return COMPARE_TYPE; } +"<=" { savetoken(yytext); yylval.i = SPO_JLE; return COMPARE_TYPE; } +">=" { savetoken(yytext); yylval.i = SPO_JGE; return COMPARE_TYPE; } +"<" { savetoken(yytext); yylval.i = SPO_JL; return COMPARE_TYPE; } +">" { savetoken(yytext); yylval.i = SPO_JG; return COMPARE_TYPE; } +\r?\n { newline(); } +[ \t]+ { advancepos(yytext); } +'\\.' { savetoken(yytext); yylval.i = yytext[2]; return CHAR; } +'.' { savetoken(yytext); yylval.i = yytext[1]; return CHAR; } +[-_a-zA-Z0-9]+ ST_RET(UNKNOWN_TYPE); +. { savetoken(yytext); return yytext[0]; } %% #ifdef AMIGA long *alloc(n) @@ -232,6 +354,7 @@ FILE *input_f; else #endif yyin = input_f; + if (!orig_yyin) orig_yyin = yyin; } /* analogous routine (for completeness) */ void init_yyout( output_f ) @@ -240,4 +363,51 @@ FILE *output_f; yyout = output_f; } +long +handle_varstring_check() +{ + struct lc_vardefs *vd; + yylval.map = (char *) alloc(strlen(yytext)+1); + Strcpy(yylval.map, yytext); + if ((vd = vardef_defined(variable_definitions, yytext, 1))) { + long l = vd->var_type; + long a = ((l & SPOVAR_ARRAY) == SPOVAR_ARRAY); + l = (l & ~SPOVAR_ARRAY); + if (l == SPOVAR_INT) return (a ? VARSTRING_INT_ARRAY : VARSTRING_INT); + if (l == SPOVAR_STRING) return (a ? VARSTRING_STRING_ARRAY : VARSTRING_STRING); + if (l == SPOVAR_VARIABLE) return (a ? VARSTRING_VAR_ARRAY : VARSTRING_VAR); + if (l == SPOVAR_COORD) return (a ? VARSTRING_COORD_ARRAY : VARSTRING_COORD); + if (l == SPOVAR_REGION) return (a ? VARSTRING_REGION_ARRAY : VARSTRING_REGION); + if (l == SPOVAR_MAPCHAR) return (a ? VARSTRING_MAPCHAR_ARRAY : VARSTRING_MAPCHAR); + if (l == SPOVAR_MONST) return (a ? VARSTRING_MONST_ARRAY : VARSTRING_MONST); + if (l == SPOVAR_OBJ) return (a ? VARSTRING_OBJ_ARRAY : VARSTRING_OBJ); + if (l == SPOVAR_SEL) return (a ? VARSTRING_SEL_ARRAY : VARSTRING_SEL); + } + return VARSTRING; +} + + +void +newline() +{ + nh_line_number++; + token_start_pos = 0; + memset(curr_token, 0, 512); +} + +void +savetoken(s) +char *s; +{ + sprintf(curr_token, "%s", s); + advancepos(s); +} + +void +advancepos(s) +char *s; +{ + token_start_pos += strlen(s); +} + /*lev_comp.l*/ diff --git a/util/lev_comp.y b/util/lev_comp.y index c2fe15fb6..fab3a9450 100644 --- a/util/lev_comp.y +++ b/util/lev_comp.y @@ -26,7 +26,6 @@ #include "hack.h" #include "sp_lev.h" -#define MAX_REGISTERS 10 #define ERR (-1) /* many types of things are put in chars for transference to NetHack. * since some systems will use signed chars, limit everybody to the @@ -34,11 +33,16 @@ */ #define MAX_OF_TYPE 128 +#define MAX_NESTED_IFS 20 +#define MAX_SWITCH_CASES 20 + #define New(type) \ (type *) memset((genericptr_t)alloc(sizeof(type)), 0, sizeof(type)) #define NewTab(type, size) (type **) alloc(sizeof(type *) * size) #define Free(ptr) free((genericptr_t)ptr) +extern void VDECL(lc_error, (const char *, ...)); +extern void VDECL(lc_warning, (const char *, ...)); extern void FDECL(yyerror, (const char *)); extern void FDECL(yywarning, (const char *)); extern int NDECL(yylex); @@ -52,119 +56,219 @@ extern int FDECL(get_object_id, (char *,CHAR_P)); extern boolean FDECL(check_monster_char, (CHAR_P)); extern boolean FDECL(check_object_char, (CHAR_P)); extern char FDECL(what_map_char, (CHAR_P)); -extern void FDECL(scan_map, (char *)); -extern void NDECL(wallify_map); -extern boolean NDECL(check_subrooms); -extern void FDECL(check_coord, (int,int,const char *)); -extern void NDECL(store_part); -extern void NDECL(store_room); -extern boolean FDECL(write_level_file, (char *,splev *,specialmaze *)); -extern void FDECL(free_rooms, (splev *)); +extern void FDECL(scan_map, (char *, sp_lev *)); +extern void FDECL(add_opcode, (sp_lev *, int, genericptr_t)); +extern genericptr_t FDECL(get_last_opcode_data1, (sp_lev *, int)); +extern genericptr_t FDECL(get_last_opcode_data2, (sp_lev *, int,int)); +extern boolean FDECL(check_subrooms, (sp_lev *)); +extern boolean FDECL(write_level_file, (char *,sp_lev *)); +extern struct opvar *FDECL(set_opvar_int, (struct opvar *, long)); +extern void VDECL(add_opvars, (sp_lev *, const char *, ...)); +extern void FDECL(start_level_def, (sp_lev * *, char *)); -static struct reg { - int x1, y1; - int x2, y2; -} current_region; +extern struct lc_funcdefs *FDECL(funcdef_new,(long,char *)); +extern void FDECL(funcdef_free_all,(struct lc_funcdefs *)); +extern struct lc_funcdefs *FDECL(funcdef_defined,(struct lc_funcdefs *,char *, int)); +extern char *FDECL(funcdef_paramtypes, (struct lc_funcdefs *)); +extern char *FDECL(decode_parm_str, (char *)); -static struct coord { - int x; - int y; -} current_coord, current_align; +extern struct lc_vardefs *FDECL(vardef_new,(long,char *)); +extern void FDECL(vardef_free_all,(struct lc_vardefs *)); +extern struct lc_vardefs *FDECL(vardef_defined,(struct lc_vardefs *,char *, int)); -static struct size { - int height; - int width; -} current_size; +extern void NDECL(break_stmt_start); +extern void FDECL(break_stmt_end, (sp_lev *)); +extern void FDECL(break_stmt_new, (sp_lev *, long)); -char tmpmessage[256]; -digpos *tmppass[32]; -char *tmpmap[ROWNO]; +extern void FDECL(splev_add_from, (sp_lev *, sp_lev *)); -digpos *tmpdig[MAX_OF_TYPE]; -region *tmpreg[MAX_OF_TYPE]; -lev_region *tmplreg[MAX_OF_TYPE]; -door *tmpdoor[MAX_OF_TYPE]; -drawbridge *tmpdb[MAX_OF_TYPE]; -walk *tmpwalk[MAX_OF_TYPE]; +extern void FDECL(check_vardef_type, (struct lc_vardefs *, char *, long)); +extern void FDECL(vardef_used, (struct lc_vardefs *, char *)); +extern struct lc_vardefs *FDECL(add_vardef_type, (struct lc_vardefs *, char *, long)); -room_door *tmprdoor[MAX_OF_TYPE]; -trap *tmptrap[MAX_OF_TYPE]; -monster *tmpmonst[MAX_OF_TYPE]; -object *tmpobj[MAX_OF_TYPE]; -altar *tmpaltar[MAX_OF_TYPE]; -lad *tmplad[MAX_OF_TYPE]; -stair *tmpstair[MAX_OF_TYPE]; -gold *tmpgold[MAX_OF_TYPE]; -engraving *tmpengraving[MAX_OF_TYPE]; -fountain *tmpfountain[MAX_OF_TYPE]; -sink *tmpsink[MAX_OF_TYPE]; -pool *tmppool[MAX_OF_TYPE]; +extern int FDECL(reverse_jmp_opcode, (int)); -mazepart *tmppart[10]; -room *tmproom[MAXNROFROOMS*2]; -corridor *tmpcor[MAX_OF_TYPE]; +struct coord { + long x; + long y; +}; -static specialmaze maze; -static splev special_lev; -static lev_init init_lev; +struct forloopdef { + char *varname; + long jmp_point; +}; +static struct forloopdef forloop_list[MAX_NESTED_IFS]; +static short n_forloops = 0; -static char olist[MAX_REGISTERS], mlist[MAX_REGISTERS]; -static struct coord plist[MAX_REGISTERS]; -int n_olist = 0, n_mlist = 0, n_plist = 0; +sp_lev *splev = NULL; -unsigned int nlreg = 0, nreg = 0, ndoor = 0, ntrap = 0, nmons = 0, nobj = 0; -unsigned int ndb = 0, nwalk = 0, npart = 0, ndig = 0, nlad = 0, nstair = 0; -unsigned int naltar = 0, ncorridor = 0, nrooms = 0, ngold = 0, nengraving = 0; -unsigned int nfountain = 0, npool = 0, nsink = 0, npass = 0; +static struct opvar *if_list[MAX_NESTED_IFS]; -static int lev_flags = 0; +static short n_if_list = 0; unsigned int max_x_map, max_y_map; +int obj_containment = 0; -static xchar in_room; +int in_container_obj = 0; + +/* integer value is possibly an inconstant value (eg. dice notation or a variable) */ +int is_inconstant_number = 0; + +int in_switch_statement = 0; +static struct opvar *switch_check_jump = NULL; +static struct opvar *switch_default_case = NULL; +static struct opvar *switch_case_list[MAX_SWITCH_CASES]; +static long switch_case_value[MAX_SWITCH_CASES]; +int n_switch_case_list = 0; + +int allow_break_statements = 0; +struct lc_breakdef *break_list = NULL; + +extern struct lc_vardefs *variable_definitions; + + +struct lc_vardefs *function_tmp_var_defs = NULL; +extern struct lc_funcdefs *function_definitions; +struct lc_funcdefs *curr_function = NULL; +struct lc_funcdefs_parm * curr_function_param = NULL; +int in_function_definition = 0; +sp_lev *function_splev_backup = NULL; extern int fatal_error; -extern int want_warnings; +extern int got_errors; +extern int line_number; extern const char *fname; +extern char curr_token[512]; + %} %union { - int i; + long i; char* map; struct { - xchar room; - xchar wall; - xchar door; + long room; + long wall; + long door; } corpos; + struct { + long area; + long x1; + long y1; + long x2; + long y2; + } lregn; + struct { + long x; + long y; + } crd; + struct { + long ter; + long lit; + } terr; + struct { + long height; + long width; + } sze; + struct { + long die; + long num; + } dice; + struct { + long cfunc; + char *varstr; + } meth; } -%token CHAR INTEGER BOOLEAN PERCENT +%token CHAR INTEGER BOOLEAN PERCENT SPERCENT +%token MINUS_INTEGER PLUS_INTEGER +%token MAZE_GRID_ID SOLID_FILL_ID MINES_ID ROGUELEV_ID %token MESSAGE_ID MAZE_ID LEVEL_ID LEV_INIT_ID GEOMETRY_ID NOMAP_ID %token OBJECT_ID COBJECT_ID MONSTER_ID TRAP_ID DOOR_ID DRAWBRIDGE_ID -%token MAZEWALK_ID WALLIFY_ID REGION_ID FILLING -%token RANDOM_OBJECTS_ID RANDOM_MONSTERS_ID RANDOM_PLACES_ID +%token object_ID monster_ID terrain_ID +%token MAZEWALK_ID WALLIFY_ID REGION_ID FILLING IRREGULAR JOINED %token ALTAR_ID LADDER_ID STAIR_ID NON_DIGGABLE_ID NON_PASSWALL_ID ROOM_ID -%token PORTAL_ID TELEPRT_ID BRANCH_ID LEV CHANCE_ID +%token PORTAL_ID TELEPRT_ID BRANCH_ID LEV MINERALIZE_ID %token CORRIDOR_ID GOLD_ID ENGRAVING_ID FOUNTAIN_ID POOL_ID SINK_ID NONE %token RAND_CORRIDOR_ID DOOR_STATE LIGHT_STATE CURSE_TYPE ENGRAVING_TYPE -%token DIRECTION RANDOM_TYPE O_REGISTER M_REGISTER P_REGISTER A_REGISTER +%token DIRECTION RANDOM_TYPE RANDOM_TYPE_BRACKET A_REGISTER %token ALIGNMENT LEFT_OR_RIGHT CENTER TOP_OR_BOT ALTAR_TYPE UP_OR_DOWN %token SUBROOM_ID NAME_ID FLAGS_ID FLAG_TYPE MON_ATTITUDE MON_ALERTNESS -%token MON_APPEARANCE -%token CONTAINED -%token ',' ':' '(' ')' '[' ']' +%token MON_APPEARANCE ROOMDOOR_ID IF_ID ELSE_ID +%token TERRAIN_ID HORIZ_OR_VERT REPLACE_TERRAIN_ID +%token EXIT_ID SHUFFLE_ID +%token QUANTITY_ID BURIED_ID LOOP_ID +%token FOR_ID TO_ID +%token SWITCH_ID CASE_ID BREAK_ID DEFAULT_ID +%token ERODED_ID TRAPPED_ID RECHARGED_ID INVIS_ID GREASED_ID +%token FEMALE_ID CANCELLED_ID REVIVED_ID AVENGE_ID FLEEING_ID BLINDED_ID +%token PARALYZED_ID STUNNED_ID CONFUSED_ID SEENTRAPS_ID ALL_ID +%token MONTYPE_ID +%token GRAVE_ID ERODEPROOF_ID +%token FUNCTION_ID +%token MSG_OUTPUT_TYPE +%token COMPARE_TYPE +%token UNKNOWN_TYPE +%token rect_ID fillrect_ID line_ID randline_ID grow_ID selection_ID flood_ID +%token rndcoord_ID circle_ID ellipse_ID filter_ID complement_ID +%token gradient_ID GRADIENT_TYPE LIMITED HUMIDITY_TYPE +%token ',' ':' '(' ')' '[' ']' '{' '}' %token STRING MAP_ID +%token NQSTRING VARSTRING +%token CFUNC CFUNC_INT CFUNC_STR CFUNC_COORD CFUNC_REGION +%token VARSTRING_INT VARSTRING_INT_ARRAY +%token VARSTRING_STRING VARSTRING_STRING_ARRAY +%token VARSTRING_VAR VARSTRING_VAR_ARRAY +%token VARSTRING_COORD VARSTRING_COORD_ARRAY +%token VARSTRING_REGION VARSTRING_REGION_ARRAY +%token VARSTRING_MAPCHAR VARSTRING_MAPCHAR_ARRAY +%token VARSTRING_MONST VARSTRING_MONST_ARRAY +%token VARSTRING_OBJ VARSTRING_OBJ_ARRAY +%token VARSTRING_SEL VARSTRING_SEL_ARRAY +%token METHOD_INT METHOD_INT_ARRAY +%token METHOD_STRING METHOD_STRING_ARRAY +%token METHOD_VAR METHOD_VAR_ARRAY +%token METHOD_COORD METHOD_COORD_ARRAY +%token METHOD_REGION METHOD_REGION_ARRAY +%token METHOD_MAPCHAR METHOD_MAPCHAR_ARRAY +%token METHOD_MONST METHOD_MONST_ARRAY +%token METHOD_OBJ METHOD_OBJ_ARRAY +%token METHOD_SEL METHOD_SEL_ARRAY +%token DICE %type h_justif v_justif trap_name room_type door_state light_state -%type alignment altar_type a_register roomfill filling door_pos -%type door_wall walled secret amount chance -%type engraving_type flags flag_list prefilled lev_region lev_init -%type monster monster_c m_register object object_c o_register -%type string maze_def level_def m_name o_name +%type alignment altar_type a_register roomfill door_pos +%type alignment_prfx +%type door_wall walled secret +%type dir_list teleprt_detail +%type object_infos object_info monster_infos monster_info +%type levstatements stmt_block region_detail_end +%type engraving_type flag_list roomregionflag roomregionflags optroomregionflags +%type humidity_flags +%type comparestmt encodecoord encoderegion mapchar +%type seen_trap_mask +%type encodemonster encodeobj encodeobj_list +%type integer_list string_list encodecoord_list encoderegion_list mapchar_list encodemonster_list +%type opt_percent opt_fillchar +%type all_integers +%type ter_selection ter_selection_x +%type func_param_type +%type objectid monsterid terrainid +%type opt_coord_or_var opt_limited +%type mazefiller +%type level_def +%type any_var any_var_array any_var_or_arr any_var_or_unk +%type func_call_params_list func_call_param_list +%type func_call_param_part %type corr_spec +%type region lev_region +%type room_pos subroom_pos room_align +%type room_size +%type terrain_type +%left '+' '-' +%left '*' '/' '%' %start file %% @@ -176,331 +280,926 @@ levels : level | level levels ; -level : maze_level - | room_level - ; - -maze_level : maze_def flags lev_init messages regions +level : level_def flags levstatements { - unsigned i; - if (fatal_error > 0) { (void) fprintf(stderr, - "%s : %d errors detected. No output created!\n", - fname, fatal_error); - } else { - maze.flags = $2; - (void) memcpy((genericptr_t)&(maze.init_lev), - (genericptr_t)&(init_lev), - sizeof(lev_init)); - maze.numpart = npart; - maze.parts = NewTab(mazepart, npart); - for(i=0;i 0) { - (void) fprintf(stderr, - "%s : %d errors detected. No output created!\n", - fname, fatal_error); - } else { - special_lev.flags = (long) $2; - (void) memcpy( - (genericptr_t)&(special_lev.init_lev), - (genericptr_t)&(init_lev), - sizeof(lev_init)); - special_lev.nroom = nrooms; - special_lev.rooms = NewTab(room, nrooms); - for(i=0; i 8) - yyerror("Level names limited to 8 characters."); - $$ = $3; - special_lev.nrmonst = special_lev.nrobjects = 0; - n_mlist = n_olist = 0; + $$ = -1; + } + | CHAR + { + $$ = what_map_char((char) $1); } ; -lev_init : /* nothing */ +lev_init : LEV_INIT_ID ':' SOLID_FILL_ID ',' terrain_type { - /* in case we're processing multiple files, - explicitly clear any stale settings */ - (void) memset((genericptr_t) &init_lev, 0, - sizeof init_lev); - init_lev.init_present = FALSE; - $$ = 0; + long filling = $5.ter; + if (filling == INVALID_TYPE || filling >= MAX_TYPE) + lc_error("INIT_MAP: Invalid fill char type."); + add_opvars(splev, "iiiiiiiio", LVLINIT_SOLIDFILL,filling,0,(long)$5.lit, 0,0,0,0, SPO_INITLEVEL); + max_x_map = COLNO-1; + max_y_map = ROWNO; } - | LEV_INIT_ID ':' CHAR ',' CHAR ',' BOOLEAN ',' BOOLEAN ',' light_state ',' walled + | LEV_INIT_ID ':' MAZE_GRID_ID ',' CHAR { - init_lev.init_present = TRUE; - init_lev.fg = what_map_char((char) $3); - if (init_lev.fg == INVALID_TYPE) - yyerror("Invalid foreground type."); - init_lev.bg = what_map_char((char) $5); - if (init_lev.bg == INVALID_TYPE) - yyerror("Invalid background type."); - init_lev.smoothed = $7; - init_lev.joined = $9; - if (init_lev.joined && - init_lev.fg != CORR && init_lev.fg != ROOM) - yyerror("Invalid foreground type for joined map."); - init_lev.lit = $11; - init_lev.walled = $13; - init_lev.icedpools = FALSE; - $$ = 1; + long filling = what_map_char((char) $5); + if (filling == INVALID_TYPE || filling >= MAX_TYPE) + lc_error("INIT_MAP: Invalid fill char type."); + add_opvars(splev, "iiiiiiiio", LVLINIT_MAZEGRID,filling,0,0, 0,0,0,0, SPO_INITLEVEL); + max_x_map = COLNO-1; + max_y_map = ROWNO; } - | LEV_INIT_ID ':' CHAR ',' CHAR ',' BOOLEAN ',' BOOLEAN ',' light_state ',' walled ',' BOOLEAN + | LEV_INIT_ID ':' ROGUELEV_ID { - init_lev.init_present = TRUE; - init_lev.fg = what_map_char((char) $3); - if (init_lev.fg == INVALID_TYPE) - yyerror("Invalid foreground type."); - init_lev.bg = what_map_char((char) $5); - if (init_lev.bg == INVALID_TYPE) - yyerror("Invalid background type."); - init_lev.smoothed = $7; - init_lev.joined = $9; - if (init_lev.joined && - init_lev.fg != CORR && init_lev.fg != ROOM) - yyerror("Invalid foreground type for joined map."); - init_lev.lit = $11; - init_lev.walled = $13; - init_lev.icedpools = $15; - $$ = 1; + add_opvars(splev, "iiiiiiiio", LVLINIT_ROGUE,0,0,0,0,0,0,0, SPO_INITLEVEL); + } + | LEV_INIT_ID ':' MINES_ID ',' CHAR ',' CHAR ',' BOOLEAN ',' BOOLEAN ',' light_state ',' walled opt_fillchar + { + long fg = what_map_char((char) $5); + long bg = what_map_char((char) $7); + long smoothed = $9; + long joined = $11; + long lit = $13; + long walled = $15; + long filling = $16; + if (fg == INVALID_TYPE || fg >= MAX_TYPE) + lc_error("INIT_MAP: Invalid foreground type."); + if (bg == INVALID_TYPE || bg >= MAX_TYPE) + lc_error("INIT_MAP: Invalid background type."); + if (joined && fg != CORR && fg != ROOM) + lc_error("INIT_MAP: Invalid foreground type for joined map."); + + if (filling == INVALID_TYPE) + lc_error("INIT_MAP: Invalid fill char type."); + + add_opvars(splev, "iiiiiiiio", LVLINIT_MINES,filling,walled,lit, joined,smoothed,bg,fg, SPO_INITLEVEL); + max_x_map = COLNO-1; + max_y_map = ROWNO; } ; +opt_limited : /* nothing */ + { + $$ = 0; + } + | ',' LIMITED + { + $$ = $2; + } + ; + +opt_coord_or_var : /* nothing */ + { + add_opvars(splev, "o", SPO_COPY); + $$ = 0; + } + | ',' coord_or_var + { + $$ = 1; + } + ; + +opt_fillchar : /* nothing */ + { + $$ = -1; + } + | ',' CHAR + { + $$ = what_map_char((char) $2); + } + ; + + walled : BOOLEAN | RANDOM_TYPE ; flags : /* nothing */ { - $$ = 0; + add_opvars(splev, "io", 0, SPO_LEVEL_FLAGS); } | FLAGS_ID ':' flag_list { - $$ = lev_flags; - lev_flags = 0; /* clear for next user */ + add_opvars(splev, "io", $3, SPO_LEVEL_FLAGS); } ; flag_list : FLAG_TYPE ',' flag_list { - lev_flags |= $1; + $$ = ($1 | $3); } | FLAG_TYPE { - lev_flags |= $1; + $$ = $1; } ; -messages : /* nothing */ - | message messages - ; - -message : MESSAGE_ID ':' STRING +levstatements : /* nothing */ { - int i, j; - - i = (int) strlen($3) + 1; - j = (int) strlen(tmpmessage); - if (i + j > 255) { - yyerror("Message string too long (>256 characters)"); - } else { - if (j) tmpmessage[j++] = '\n'; - (void) strncpy(tmpmessage+j, $3, i - 1); - tmpmessage[j + i - 1] = 0; - } - Free($3); + $$ = 0; + } + | levstatement levstatements + { + $$ = 1 + $2; } ; -rreg_init : /* nothing */ - | rreg_init init_rreg +stmt_block : '{' levstatements '}' + { + $$ = $2; + } ; -init_rreg : RANDOM_OBJECTS_ID ':' object_list +levstatement : message + | lev_init + | altar_detail + | grave_detail + | branch_region + | corridor + | variable_define + | shuffle_detail + | diggable_detail + | door_detail + | drawbridge_detail + | engraving_detail + | mineralize + | fountain_detail + | gold_detail + | switchstatement + | forstatement + | loopstatement + | ifstatement + | chancestatement + | exitstatement + | breakstatement + | function_define + | function_call + | ladder_detail + | map_definition + | mazewalk_detail + | monster_detail + | object_detail + | passwall_detail + | pool_detail + | portal_region + | random_corridors + | region_detail + | room_def + | subroom_def + | sink_detail + | terrain_detail + | replace_terrain_detail + | stair_detail + | stair_region + | teleprt_region + | trap_detail + | wallify_detail + ; + +any_var_array : VARSTRING_INT_ARRAY + | VARSTRING_STRING_ARRAY + | VARSTRING_VAR_ARRAY + | VARSTRING_COORD_ARRAY + | VARSTRING_REGION_ARRAY + | VARSTRING_MAPCHAR_ARRAY + | VARSTRING_MONST_ARRAY + | VARSTRING_OBJ_ARRAY + | VARSTRING_SEL_ARRAY + ; + +any_var : VARSTRING_INT + | VARSTRING_STRING + | VARSTRING_VAR + | VARSTRING_COORD + | VARSTRING_REGION + | VARSTRING_MAPCHAR + | VARSTRING_MONST + | VARSTRING_OBJ + | VARSTRING_SEL + ; + +any_var_or_arr : any_var_array + | any_var + | VARSTRING + ; + +any_var_or_unk : VARSTRING + | any_var + ; + +shuffle_detail : SHUFFLE_ID ':' any_var_array { - if(special_lev.nrobjects) { - yyerror("Object registers already initialized!"); - } else { - special_lev.nrobjects = n_olist; - special_lev.robjects = (char *) alloc(n_olist); - (void) memcpy((genericptr_t)special_lev.robjects, - (genericptr_t)olist, n_olist); - } + struct lc_vardefs *vd; + if ((vd = vardef_defined(variable_definitions, $3, 1))) { + if (!(vd->var_type & SPOVAR_ARRAY)) + lc_error("Trying to shuffle non-array variable '%s'", $3); + } else lc_error("Trying to shuffle undefined variable '%s'", $3); + add_opvars(splev, "so", $3, SPO_SHUFFLE_ARRAY); + Free($3); } - | RANDOM_MONSTERS_ID ':' monster_list + ; + +variable_define : any_var_or_arr '=' math_expr_var { - if(special_lev.nrmonst) { - yyerror("Monster registers already initialized!"); - } else { - special_lev.nrmonst = n_mlist; - special_lev.rmonst = (char *) alloc(n_mlist); - (void) memcpy((genericptr_t)special_lev.rmonst, - (genericptr_t)mlist, n_mlist); + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_INT); + add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' selection_ID ':' ter_selection + { + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_SEL); + add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' string_expr + { + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_STRING); + add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' terrainid ':' mapchar_or_var + { + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_MAPCHAR); + add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' monsterid ':' monster_or_var + { + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_MONST); + add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' objectid ':' object_or_var + { + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_OBJ); + add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' coord_or_var + { + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_COORD); + add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' region_or_var + { + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_REGION); + add_opvars(splev, "iso", 0, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' '{' integer_list '}' + { + long n_items = $4; + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_INT|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' '{' encodecoord_list '}' + { + long n_items = $4; + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_COORD|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' '{' encoderegion_list '}' + { + long n_items = $4; + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_REGION|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' terrainid ':' '{' mapchar_list '}' + { + long n_items = $6; + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_MAPCHAR|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' monsterid ':' '{' encodemonster_list '}' + { + long n_items = $6; + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_MONST|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' objectid ':' '{' encodeobj_list '}' + { + long n_items = $6; + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_OBJ|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT); + Free($1); + } + | any_var_or_arr '=' '{' string_list '}' + { + long n_items = $4; + variable_definitions = add_vardef_type(variable_definitions, $1, SPOVAR_STRING|SPOVAR_ARRAY); + add_opvars(splev, "iso", n_items, $1, SPO_VAR_INIT); + Free($1); + } + ; + +encodeobj_list : encodeobj + { + add_opvars(splev, "O", $1); + $$ = 1; + } + | encodeobj_list ',' encodeobj + { + add_opvars(splev, "O", $3); + $$ = 1 + $1; + } + ; + +encodemonster_list : encodemonster + { + add_opvars(splev, "M", $1); + $$ = 1; + } + | encodemonster_list ',' encodemonster + { + add_opvars(splev, "M", $3); + $$ = 1 + $1; + } + ; + +mapchar_list : mapchar + { + add_opvars(splev, "m", $1); + $$ = 1; + } + | mapchar_list ',' mapchar + { + add_opvars(splev, "m", $3); + $$ = 1 + $1; + } + ; + +encoderegion_list : encoderegion + { + $$ = 1; + } + | encoderegion_list ',' encoderegion + { + $$ = 1 + $1; + } + ; + +encodecoord_list : encodecoord + { + add_opvars(splev, "c", $1); + $$ = 1; + } + | encodecoord_list ',' encodecoord + { + add_opvars(splev, "c", $3); + $$ = 1 + $1; + } + ; + +integer_list : math_expr_var + { + $$ = 1; + } + | integer_list ',' math_expr_var + { + $$ = 1 + $1; + } + ; + +string_list : string_expr + { + $$ = 1; + } + | string_list ',' string_expr + { + $$ = 1 + $1; + } + ; + +function_define : FUNCTION_ID NQSTRING '(' + { + struct lc_funcdefs *funcdef; + + if (in_function_definition) + lc_error("Recursively defined functions not allowed (function %s).", $2); + + in_function_definition++; + + if (funcdef_defined(function_definitions, $2, 1)) + lc_error("Function '%s' already defined once.", $2); + + funcdef = funcdef_new(-1, $2); + funcdef->next = function_definitions; + function_definitions = funcdef; + function_splev_backup = splev; + splev = &(funcdef->code); + Free($2); + curr_function = funcdef; + function_tmp_var_defs = variable_definitions; + variable_definitions = NULL; + } + func_params_list ')' + { + /* nothing */ + } + stmt_block + { + add_opvars(splev, "io", 0, SPO_RETURN); + splev = function_splev_backup; + in_function_definition--; + curr_function = NULL; + vardef_free_all(variable_definitions); + variable_definitions = function_tmp_var_defs; + } + ; + +function_call : NQSTRING '(' func_call_params_list ')' + { + struct lc_funcdefs *tmpfunc; + tmpfunc = funcdef_defined(function_definitions, $1, 1); + if (tmpfunc) { + long l; + long nparams = strlen( $3 ); + char *fparamstr = funcdef_paramtypes(tmpfunc); + if (strcmp($3, fparamstr)) { + char *tmps = strdup(decode_parm_str(fparamstr)); + lc_error("Function '%s' requires params '%s', got '%s' instead.", $1, tmps, decode_parm_str($3)); + Free(tmps); } + Free(fparamstr); + Free($3); + if (!(tmpfunc->n_called)) { + /* we haven't called the function yet, so insert it in the code */ + struct opvar *jmp = New(struct opvar); + set_opvar_int(jmp, splev->n_opcodes+1); + add_opcode(splev, SPO_PUSH, jmp); + add_opcode(splev, SPO_JMP, NULL); /* we must jump past it first, then CALL it, due to RETURN. */ + + tmpfunc->addr = splev->n_opcodes; + + { /* init function parameter variables */ + struct lc_funcdefs_parm *tfp = tmpfunc->params; + while (tfp) { + add_opvars(splev, "iso", 0, tfp->name, SPO_VAR_INIT); + tfp = tfp->next; + } + } + + splev_add_from(splev, &(tmpfunc->code)); + set_opvar_int(jmp, splev->n_opcodes - jmp->vardata.l); + } + l = tmpfunc->addr - splev->n_opcodes - 2; + add_opvars(splev, "iio", nparams, l, SPO_CALL); + tmpfunc->n_called++; + } else { + lc_error("Function '%s' not defined.", $1); + } + Free($1); } ; -rooms : /* Nothing - dummy room for use with INIT_MAP */ +exitstatement : EXIT_ID { - tmproom[nrooms] = New(room); - tmproom[nrooms]->name = (char *) 0; - tmproom[nrooms]->parent = (char *) 0; - tmproom[nrooms]->rtype = 0; - tmproom[nrooms]->rlit = 0; - tmproom[nrooms]->xalign = ERR; - tmproom[nrooms]->yalign = ERR; - tmproom[nrooms]->x = 0; - tmproom[nrooms]->y = 0; - tmproom[nrooms]->w = 2; - tmproom[nrooms]->h = 2; - in_room = 1; + add_opcode(splev, SPO_EXIT, NULL); } - | roomlist ; -roomlist : aroom - | aroom roomlist +opt_percent : /* nothing */ + { + $$ = 100; + } + | PERCENT + { + $$ = $1; + } ; -corridors_def : random_corridors - | corridors +comparestmt : PERCENT + { + /* val > rn2(100) */ + add_opvars(splev, "iio", (long)$1, 100, SPO_RN2); + $$ = SPO_JG; + } + | '[' math_expr_var COMPARE_TYPE math_expr_var ']' + { + $$ = $3; + } + | '[' math_expr_var ']' + { + /* boolean, explicit foo != 0 */ + add_opvars(splev, "i", 0); + $$ = SPO_JNE; + } + ; + +switchstatement : SWITCH_ID + { + is_inconstant_number = 0; + } + '[' integer_or_var ']' + { + struct opvar *chkjmp; + if (in_switch_statement > 0) + lc_error("Cannot nest switch-statements."); + + in_switch_statement++; + + n_switch_case_list = 0; + switch_default_case = NULL; + + if (!is_inconstant_number) + add_opvars(splev, "o", SPO_RN2); + is_inconstant_number = 0; + + chkjmp = New(struct opvar); + set_opvar_int(chkjmp, splev->n_opcodes+1); + switch_check_jump = chkjmp; + add_opcode(splev, SPO_PUSH, chkjmp); + add_opcode(splev, SPO_JMP, NULL); + break_stmt_start(); + } + '{' switchcases '}' + { + struct opvar *endjump = New(struct opvar); + int i; + + set_opvar_int(endjump, splev->n_opcodes+1); + + add_opcode(splev, SPO_PUSH, endjump); + add_opcode(splev, SPO_JMP, NULL); + + set_opvar_int(switch_check_jump, splev->n_opcodes - switch_check_jump->vardata.l); + + for (i = 0; i < n_switch_case_list; i++) { + add_opvars(splev, "oio", SPO_COPY, switch_case_value[i], SPO_CMP); + set_opvar_int(switch_case_list[i], switch_case_list[i]->vardata.l - splev->n_opcodes-1); + add_opcode(splev, SPO_PUSH, switch_case_list[i]); + add_opcode(splev, SPO_JE, NULL); + } + + if (switch_default_case) { + set_opvar_int(switch_default_case, switch_default_case->vardata.l - splev->n_opcodes-1); + add_opcode(splev, SPO_PUSH, switch_default_case); + add_opcode(splev, SPO_JMP, NULL); + } + + set_opvar_int(endjump, splev->n_opcodes - endjump->vardata.l); + + break_stmt_end(splev); + + add_opcode(splev, SPO_POP, NULL); /* get rid of the value in stack */ + in_switch_statement--; + + + } + ; + +switchcases : /* nothing */ + | switchcase switchcases + ; + +switchcase : CASE_ID all_integers ':' + { + if (n_switch_case_list < MAX_SWITCH_CASES) { + struct opvar *tmppush = New(struct opvar); + set_opvar_int(tmppush, splev->n_opcodes); + switch_case_value[n_switch_case_list] = $2; + switch_case_list[n_switch_case_list++] = tmppush; + } else lc_error("Too many cases in a switch."); + } + levstatements + { + } + | DEFAULT_ID ':' + { + struct opvar *tmppush = New(struct opvar); + + if (switch_default_case) + lc_error("Switch default case already used."); + + set_opvar_int(tmppush, splev->n_opcodes); + switch_default_case = tmppush; + } + levstatements + { + } + ; + +breakstatement : BREAK_ID + { + if (!allow_break_statements) + lc_error("Cannot use BREAK outside a statement block."); + else { + break_stmt_new(splev, splev->n_opcodes); + } + } + ; + +for_to_span : '.' '.' + | TO_ID + ; + +forstmt_start : FOR_ID any_var_or_unk '=' math_expr_var for_to_span math_expr_var + { + char buf[256], buf2[256]; + + if (n_forloops >= MAX_NESTED_IFS) { + lc_error("FOR: Too deeply nested loops."); + n_forloops = MAX_NESTED_IFS - 1; + } + + /* first, define a variable for the for-loop end value */ + snprintf(buf, 255, "%s end", $2); + /* the value of which is already in stack (the 2nd math_expr) */ + add_opvars(splev, "iso", 0, buf, SPO_VAR_INIT); + + variable_definitions = add_vardef_type(variable_definitions, $2, SPOVAR_INT); + /* define the for-loop variable. value is in stack (1st math_expr) */ + add_opvars(splev, "iso", 0, $2, SPO_VAR_INIT); + + /* calculate value for the loop "step" variable */ + snprintf(buf2, 255, "%s step", $2); + add_opvars(splev, "vvo", buf, $2, SPO_MATH_SUB); /* end - start */ + add_opvars(splev, "o", SPO_MATH_SIGN); /* sign of that */ + add_opvars(splev, "iso", 0, buf2, SPO_VAR_INIT); /* save the sign into the step var */ + + forloop_list[n_forloops].varname = strdup($2); + forloop_list[n_forloops].jmp_point = splev->n_opcodes; + + n_forloops++; + Free($2); + } + ; + +forstatement : forstmt_start + { + /* nothing */ + break_stmt_start(); + } + stmt_block + { + char buf[256], buf2[256]; + n_forloops--; + snprintf(buf, 255, "%s step", forloop_list[n_forloops].varname); + snprintf(buf2, 255, "%s end", forloop_list[n_forloops].varname); + /* compare for-loop var to end value */ + add_opvars(splev, "vvo", forloop_list[n_forloops].varname, buf2, SPO_CMP); + /* var + step */ + add_opvars(splev, "vvo", buf, + forloop_list[n_forloops].varname, SPO_MATH_ADD); + /* for-loop var = (for-loop var + step) */ + add_opvars(splev, "iso", 0, forloop_list[n_forloops].varname, SPO_VAR_INIT); + /* jump back if compared values were not equal */ + add_opvars(splev, "io", forloop_list[n_forloops].jmp_point - splev->n_opcodes - 1, SPO_JNE); + Free(forloop_list[n_forloops].varname); + break_stmt_end(splev); + } + ; + +loopstatement : LOOP_ID '[' integer_or_var ']' + { + struct opvar *tmppush = New(struct opvar); + + if (n_if_list >= MAX_NESTED_IFS) { + lc_error("LOOP: Too deeply nested conditionals."); + n_if_list = MAX_NESTED_IFS - 1; + } + set_opvar_int(tmppush, splev->n_opcodes); + if_list[n_if_list++] = tmppush; + + add_opvars(splev, "o", SPO_DEC); + break_stmt_start(); + } + stmt_block + { + struct opvar *tmppush; + + add_opvars(splev, "oio", SPO_COPY, 0, SPO_CMP); + + tmppush = (struct opvar *) if_list[--n_if_list]; + set_opvar_int(tmppush, tmppush->vardata.l - splev->n_opcodes-1); + add_opcode(splev, SPO_PUSH, tmppush); + add_opcode(splev, SPO_JG, NULL); + add_opcode(splev, SPO_POP, NULL); /* get rid of the count value in stack */ + break_stmt_end(splev); + } + ; + +chancestatement : comparestmt ':' + { + struct opvar *tmppush2 = New(struct opvar); + + if (n_if_list >= MAX_NESTED_IFS) { + lc_error("IF: Too deeply nested conditionals."); + n_if_list = MAX_NESTED_IFS - 1; + } + + add_opcode(splev, SPO_CMP, NULL); + + set_opvar_int(tmppush2, splev->n_opcodes+1); + + if_list[n_if_list++] = tmppush2; + + add_opcode(splev, SPO_PUSH, tmppush2); + + add_opcode(splev, reverse_jmp_opcode( $1 ), NULL); + + } + levstatement + { + if (n_if_list > 0) { + struct opvar *tmppush; + tmppush = (struct opvar *) if_list[--n_if_list]; + set_opvar_int(tmppush, splev->n_opcodes - tmppush->vardata.l); + } else lc_error("IF: Huh?! No start address?"); + } + ; + +ifstatement : IF_ID comparestmt + { + struct opvar *tmppush2 = New(struct opvar); + + if (n_if_list >= MAX_NESTED_IFS) { + lc_error("IF: Too deeply nested conditionals."); + n_if_list = MAX_NESTED_IFS - 1; + } + + add_opcode(splev, SPO_CMP, NULL); + + set_opvar_int(tmppush2, splev->n_opcodes+1); + + if_list[n_if_list++] = tmppush2; + + add_opcode(splev, SPO_PUSH, tmppush2); + + add_opcode(splev, reverse_jmp_opcode( $2 ), NULL); + + } + if_ending + { + /* do nothing */ + } + ; + +if_ending : stmt_block + { + if (n_if_list > 0) { + struct opvar *tmppush; + tmppush = (struct opvar *) if_list[--n_if_list]; + set_opvar_int(tmppush, splev->n_opcodes - tmppush->vardata.l); + } else lc_error("IF: Huh?! No start address?"); + } + | stmt_block + { + if (n_if_list > 0) { + struct opvar *tmppush = New(struct opvar); + struct opvar *tmppush2; + + set_opvar_int(tmppush, splev->n_opcodes+1); + add_opcode(splev, SPO_PUSH, tmppush); + + add_opcode(splev, SPO_JMP, NULL); + + tmppush2 = (struct opvar *) if_list[--n_if_list]; + + set_opvar_int(tmppush2, splev->n_opcodes - tmppush2->vardata.l); + if_list[n_if_list++] = tmppush; + } else lc_error("IF: Huh?! No else-part address?"); + } + ELSE_ID stmt_block + { + if (n_if_list > 0) { + struct opvar *tmppush; + tmppush = (struct opvar *) if_list[--n_if_list]; + set_opvar_int(tmppush, splev->n_opcodes - tmppush->vardata.l); + } else lc_error("IF: Huh?! No end address?"); + } + ; + +message : MESSAGE_ID ':' string_expr + { + add_opvars(splev, "o", SPO_MESSAGE); + } ; random_corridors: RAND_CORRIDOR_ID { - tmpcor[0] = New(corridor); - tmpcor[0]->src.room = -1; - ncorridor = 1; + add_opvars(splev, "iiiiiio", -1, 0, -1, -1, -1, -1, SPO_CORRIDOR); + } + | RAND_CORRIDOR_ID ':' all_integers + { + add_opvars(splev, "iiiiiio", -1, $3, -1, -1, -1, -1, SPO_CORRIDOR); + } + | RAND_CORRIDOR_ID ':' RANDOM_TYPE + { + add_opvars(splev, "iiiiiio", -1, -1, -1, -1, -1, -1, SPO_CORRIDOR); } - ; - -corridors : /* nothing */ - | corridors corridor ; corridor : CORRIDOR_ID ':' corr_spec ',' corr_spec { - tmpcor[ncorridor] = New(corridor); - tmpcor[ncorridor]->src.room = $3.room; - tmpcor[ncorridor]->src.wall = $3.wall; - tmpcor[ncorridor]->src.door = $3.door; - tmpcor[ncorridor]->dest.room = $5.room; - tmpcor[ncorridor]->dest.wall = $5.wall; - tmpcor[ncorridor]->dest.door = $5.door; - ncorridor++; - if (ncorridor >= MAX_OF_TYPE) { - yyerror("Too many corridors in level!"); - ncorridor--; - } + add_opvars(splev, "iiiiiio", + $3.room, $3.door, $3.wall, + $5.room, $5.door, $5.wall, + SPO_CORRIDOR); } - | CORRIDOR_ID ':' corr_spec ',' INTEGER + | CORRIDOR_ID ':' corr_spec ',' all_integers { - tmpcor[ncorridor] = New(corridor); - tmpcor[ncorridor]->src.room = $3.room; - tmpcor[ncorridor]->src.wall = $3.wall; - tmpcor[ncorridor]->src.door = $3.door; - tmpcor[ncorridor]->dest.room = -1; - tmpcor[ncorridor]->dest.wall = $5; - ncorridor++; - if (ncorridor >= MAX_OF_TYPE) { - yyerror("Too many corridors in level!"); - ncorridor--; - } + add_opvars(splev, "iiiiiio", + $3.room, $3.door, $3.wall, + -1, -1, (long)$5, + SPO_CORRIDOR); } ; corr_spec : '(' INTEGER ',' DIRECTION ',' door_pos ')' { - if ((unsigned) $2 >= nrooms) - yyerror("Wrong room number!"); $$.room = $2; $$.wall = $4; $$.door = $6; } ; -aroom : room_def room_details +room_begin : room_type opt_percent ',' light_state + { + if (($2 < 100) && ($1 == OROOM)) + lc_error("Only typed rooms can have a chance."); + else { + add_opvars(splev, "iii", (long)$1, (long)$2, (long)$4); + } + } + ; + +subroom_def : SUBROOM_ID ':' room_begin ',' subroom_pos ',' room_size optroomregionflags { - store_room(); + long flags = $8; + if (flags == -1) flags = (1 << 0); + add_opvars(splev, "iiiiiiio", flags, ERR, ERR, + $5.x, $5.y, $7.width, $7.height, SPO_SUBROOM); + break_stmt_start(); } - | subroom_def room_details + stmt_block { - store_room(); + break_stmt_end(splev); + add_opcode(splev, SPO_ENDROOM, NULL); } ; -subroom_def : SUBROOM_ID ':' room_type ',' light_state ',' subroom_pos ',' room_size ',' string roomfill +room_def : ROOM_ID ':' room_begin ',' room_pos ',' room_align ',' room_size optroomregionflags { - tmproom[nrooms] = New(room); - tmproom[nrooms]->parent = $11; - tmproom[nrooms]->name = (char *) 0; - tmproom[nrooms]->rtype = $3; - tmproom[nrooms]->rlit = $5; - tmproom[nrooms]->filled = $12; - tmproom[nrooms]->xalign = ERR; - tmproom[nrooms]->yalign = ERR; - tmproom[nrooms]->x = current_coord.x; - tmproom[nrooms]->y = current_coord.y; - tmproom[nrooms]->w = current_size.width; - tmproom[nrooms]->h = current_size.height; - in_room = 1; + long flags = $8; + if (flags == -1) flags = (1 << 0); + add_opvars(splev, "iiiiiiio", flags, + $7.x, $7.y, $5.x, $5.y, + $9.width, $9.height, SPO_ROOM); + break_stmt_start(); } - ; - -room_def : ROOM_ID ':' room_type ',' light_state ',' room_pos ',' room_align ',' room_size roomfill + stmt_block { - tmproom[nrooms] = New(room); - tmproom[nrooms]->name = (char *) 0; - tmproom[nrooms]->parent = (char *) 0; - tmproom[nrooms]->rtype = $3; - tmproom[nrooms]->rlit = $5; - tmproom[nrooms]->filled = $12; - tmproom[nrooms]->xalign = current_align.x; - tmproom[nrooms]->yalign = current_align.y; - tmproom[nrooms]->x = current_coord.x; - tmproom[nrooms]->y = current_coord.y; - tmproom[nrooms]->w = current_size.width; - tmproom[nrooms]->h = current_size.height; - in_room = 1; + break_stmt_end(splev); + add_opcode(splev, SPO_ENDROOM, NULL); } ; @@ -518,193 +1217,109 @@ room_pos : '(' INTEGER ',' INTEGER ')' { if ( $2 < 1 || $2 > 5 || $4 < 1 || $4 > 5 ) { - yyerror("Room position should be between 1 & 5!"); + lc_error("Room positions should be between 1-5: (%li,%li)!", $2, $4); } else { - current_coord.x = $2; - current_coord.y = $4; + $$.x = $2; + $$.y = $4; } } | RANDOM_TYPE { - current_coord.x = current_coord.y = ERR; + $$.x = $$.y = ERR; } ; subroom_pos : '(' INTEGER ',' INTEGER ')' { if ( $2 < 0 || $4 < 0) { - yyerror("Invalid subroom position !"); + lc_error("Invalid subroom position (%li,%li)!", $2, $4); } else { - current_coord.x = $2; - current_coord.y = $4; + $$.x = $2; + $$.y = $4; } } | RANDOM_TYPE { - current_coord.x = current_coord.y = ERR; + $$.x = $$.y = ERR; } ; room_align : '(' h_justif ',' v_justif ')' { - current_align.x = $2; - current_align.y = $4; + $$.x = $2; + $$.y = $4; } | RANDOM_TYPE { - current_align.x = current_align.y = ERR; + $$.x = $$.y = ERR; } ; room_size : '(' INTEGER ',' INTEGER ')' { - current_size.width = $2; - current_size.height = $4; + $$.width = $2; + $$.height = $4; } | RANDOM_TYPE { - current_size.height = current_size.width = ERR; + $$.height = $$.width = ERR; } ; -room_details : /* nothing */ - | room_details room_detail - ; - -room_detail : room_name - | room_chance - | room_door - | monster_detail - | object_detail - | trap_detail - | altar_detail - | fountain_detail - | sink_detail - | pool_detail - | gold_detail - | engraving_detail - | stair_detail - ; - -room_name : NAME_ID ':' string - { - if (tmproom[nrooms]->name) - yyerror("This room already has a name!"); - else - tmproom[nrooms]->name = $3; - } - ; - -room_chance : CHANCE_ID ':' INTEGER - { - if (tmproom[nrooms]->chance) - yyerror("This room already assigned a chance!"); - else if (tmproom[nrooms]->rtype == OROOM) - yyerror("Only typed rooms can have a chance!"); - else if ($3 < 1 || $3 > 99) - yyerror("The chance is supposed to be percentile."); - else - tmproom[nrooms]->chance = $3; - } - ; - -room_door : DOOR_ID ':' secret ',' door_state ',' door_wall ',' door_pos +door_detail : ROOMDOOR_ID ':' secret ',' door_state ',' door_wall ',' door_pos { /* ERR means random here */ if ($7 == ERR && $9 != ERR) { - yyerror("If the door wall is random, so must be its pos!"); + lc_error("If the door wall is random, so must be its pos!"); } else { - tmprdoor[ndoor] = New(room_door); - tmprdoor[ndoor]->secret = $3; - tmprdoor[ndoor]->mask = $5; - tmprdoor[ndoor]->wall = $7; - tmprdoor[ndoor]->pos = $9; - ndoor++; - if (ndoor >= MAX_OF_TYPE) { - yyerror("Too many doors in room!"); - ndoor--; - } + add_opvars(splev, "iiiio", (long)$9, (long)$5, (long)$3, (long)$7, SPO_ROOM_DOOR); } } + | DOOR_ID ':' door_state ',' ter_selection + { + add_opvars(splev, "io", (long)$3, SPO_DOOR); + } ; secret : BOOLEAN | RANDOM_TYPE ; -door_wall : DIRECTION +door_wall : dir_list | RANDOM_TYPE ; +dir_list : DIRECTION + { + $$ = $1; + } + | DIRECTION '|' dir_list + { + $$ = ($1 | $3); + } + ; + door_pos : INTEGER | RANDOM_TYPE ; -maze_def : MAZE_ID ':' string ',' filling - { - maze.filling = (schar) $5; - if (index($3, '.')) - yyerror("Invalid dot ('.') in level name."); - if ((int) strlen($3) > 8) - yyerror("Level names limited to 8 characters."); - $$ = $3; - in_room = 0; - n_plist = n_mlist = n_olist = 0; - } - ; - -filling : CHAR - { - $$ = get_floor_type((char)$1); - } - | RANDOM_TYPE - { - $$ = -1; - } - ; - -regions : aregion - | aregion regions - ; - -aregion : map_definition reg_init map_details - { - store_part(); - } - ; - map_definition : NOMAP_ID { - tmppart[npart] = New(mazepart); - tmppart[npart]->halign = 1; - tmppart[npart]->valign = 1; - tmppart[npart]->nrobjects = 0; - tmppart[npart]->nloc = 0; - tmppart[npart]->nrmonst = 0; - tmppart[npart]->xsize = 1; - tmppart[npart]->ysize = 1; - tmppart[npart]->map = (char **) alloc(sizeof(char *)); - tmppart[npart]->map[0] = (char *) alloc(1); - tmppart[npart]->map[0][0] = STONE; - max_x_map = COLNO-1; - max_y_map = ROWNO; + add_opvars(splev, "ciisiio", 0, 0, 1, (char *)0, 0, 0, SPO_MAP); + max_x_map = COLNO-1; + max_y_map = ROWNO; } - | map_geometry MAP_ID + | GEOMETRY_ID ':' h_justif ',' v_justif roomfill MAP_ID { - tmppart[npart] = New(mazepart); - tmppart[npart]->halign = $1 % 10; - tmppart[npart]->valign = $1 / 10; - tmppart[npart]->nrobjects = 0; - tmppart[npart]->nloc = 0; - tmppart[npart]->nrmonst = 0; - scan_map($2); - Free($2); + add_opvars(splev, "cii", SP_COORD_PACK(($3),($5)), 1, (long)$6); + scan_map($7, splev); + Free($7); } - ; - -map_geometry : GEOMETRY_ID ':' h_justif ',' v_justif + | GEOMETRY_ID ':' coord_or_var roomfill MAP_ID { - $$ = $3 + ($5 * 10); + add_opvars(splev, "ii", 2, (long)$4); + scan_map($5, splev); + Free($5); } ; @@ -716,852 +1331,587 @@ v_justif : TOP_OR_BOT | CENTER ; -reg_init : /* nothing */ - | reg_init init_reg +monster_detail : MONSTER_ID ':' monster_desc + { + add_opvars(splev, "io", 0, SPO_MONSTER); + } + | MONSTER_ID ':' monster_desc + { + add_opvars(splev, "io", 1, SPO_MONSTER); + in_container_obj++; + break_stmt_start(); + } + stmt_block + { + break_stmt_end(splev); + in_container_obj--; + add_opvars(splev, "o", SPO_END_MONINVENT); + } ; -init_reg : RANDOM_OBJECTS_ID ':' object_list +monster_desc : monster_or_var ',' coord_or_var monster_infos { - if (tmppart[npart]->nrobjects) { - yyerror("Object registers already initialized!"); - } else { - tmppart[npart]->robjects = (char *)alloc(n_olist); - (void) memcpy((genericptr_t)tmppart[npart]->robjects, - (genericptr_t)olist, n_olist); - tmppart[npart]->nrobjects = n_olist; - } - } - | RANDOM_PLACES_ID ':' place_list - { - if (tmppart[npart]->nloc) { - yyerror("Location registers already initialized!"); - } else { - register int i; - tmppart[npart]->rloc_x = (char *) alloc(n_plist); - tmppart[npart]->rloc_y = (char *) alloc(n_plist); - for(i=0;irloc_x[i] = plist[i].x; - tmppart[npart]->rloc_y[i] = plist[i].y; - } - tmppart[npart]->nloc = n_plist; - } - } - | RANDOM_MONSTERS_ID ':' monster_list - { - if (tmppart[npart]->nrmonst) { - yyerror("Monster registers already initialized!"); - } else { - tmppart[npart]->rmonst = (char *) alloc(n_mlist); - (void) memcpy((genericptr_t)tmppart[npart]->rmonst, - (genericptr_t)mlist, n_mlist); - tmppart[npart]->nrmonst = n_mlist; - } - } - ; - -object_list : object - { - if (n_olist < MAX_REGISTERS) - olist[n_olist++] = $1; - else - yyerror("Object list too long!"); - } - | object ',' object_list - { - if (n_olist < MAX_REGISTERS) - olist[n_olist++] = $1; - else - yyerror("Object list too long!"); - } - ; - -monster_list : monster - { - if (n_mlist < MAX_REGISTERS) - mlist[n_mlist++] = $1; - else - yyerror("Monster list too long!"); - } - | monster ',' monster_list - { - if (n_mlist < MAX_REGISTERS) - mlist[n_mlist++] = $1; - else - yyerror("Monster list too long!"); - } - ; - -place_list : place - { - if (n_plist < MAX_REGISTERS) - plist[n_plist++] = current_coord; - else - yyerror("Location list too long!"); - } - | place - { - if (n_plist < MAX_REGISTERS) - plist[n_plist++] = current_coord; - else - yyerror("Location list too long!"); - } - ',' place_list - ; - -map_details : /* nothing */ - | map_details map_detail - ; - -map_detail : monster_detail - | object_detail - | door_detail - | trap_detail - | drawbridge_detail - | region_detail - | stair_region - | portal_region - | teleprt_region - | branch_region - | altar_detail - | fountain_detail - | mazewalk_detail - | wallify_detail - | ladder_detail - | stair_detail - | gold_detail - | engraving_detail - | diggable_detail - | passwall_detail - ; - -monster_detail : MONSTER_ID chance ':' monster_c ',' m_name ',' coordinate - { - tmpmonst[nmons] = New(monster); - tmpmonst[nmons]->x = current_coord.x; - tmpmonst[nmons]->y = current_coord.y; - tmpmonst[nmons]->class = $4; - tmpmonst[nmons]->peaceful = -1; /* no override */ - tmpmonst[nmons]->asleep = -1; - tmpmonst[nmons]->align = - MAX_REGISTERS - 2; - tmpmonst[nmons]->name.str = 0; - tmpmonst[nmons]->appear = 0; - tmpmonst[nmons]->appear_as.str = 0; - tmpmonst[nmons]->chance = $2; - tmpmonst[nmons]->id = NON_PM; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Monster"); - if ($6) { - int token = get_monster_id($6, (char) $4); - if (token == ERR) - yywarning( - "Invalid monster name! Making random monster."); - else - tmpmonst[nmons]->id = token; - Free($6); - } - } - monster_infos - { - if (++nmons >= MAX_OF_TYPE) { - yyerror("Too many monsters in room or mazepart!"); - nmons--; - } + /* nothing */ } ; monster_infos : /* nothing */ - | monster_infos monster_info - ; - -monster_info : ',' string { - tmpmonst[nmons]->name.str = $2; + struct opvar *stopit = New(struct opvar); + set_opvar_int(stopit, SP_M_V_END); + add_opcode(splev, SPO_PUSH, stopit); + $$ = 0x0000; } - | ',' MON_ATTITUDE + | monster_infos ',' monster_info { - tmpmonst[nmons]->peaceful = $2; - } - | ',' MON_ALERTNESS - { - tmpmonst[nmons]->asleep = $2; - } - | ',' alignment - { - tmpmonst[nmons]->align = $2; - } - | ',' MON_APPEARANCE string - { - tmpmonst[nmons]->appear = $2; - tmpmonst[nmons]->appear_as.str = $3; + if (( $1 & $3 )) + lc_error("MONSTER extra info defined twice."); + $$ = ( $1 | $3 ); } ; -object_detail : OBJECT_ID object_desc +monster_info : string_expr { + add_opvars(splev, "i", SP_M_V_NAME); + $$ = 0x0001; } - | COBJECT_ID object_desc + | MON_ATTITUDE { - /* 1: is contents of preceeding object with 2 */ - /* 2: is a container */ - /* 0: neither */ - tmpobj[nobj-1]->containment = 2; + add_opvars(splev, "ii", (long)$1, SP_M_V_PEACEFUL); + $$ = 0x0002; + } + | MON_ALERTNESS + { + add_opvars(splev, "ii", (long)$1, SP_M_V_ASLEEP); + $$ = 0x0004; + } + | alignment_prfx + { + add_opvars(splev, "ii", (long)$1, SP_M_V_ALIGN); + $$ = 0x0008; + } + | MON_APPEARANCE string_expr + { + add_opvars(splev, "ii", (long)$1, SP_M_V_APPEAR); + $$ = 0x0010; + } + | FEMALE_ID + { + add_opvars(splev, "ii", 1, SP_M_V_FEMALE); + $$ = 0x0020; + } + | INVIS_ID + { + add_opvars(splev, "ii", 1, SP_M_V_INVIS); + $$ = 0x0040; + } + | CANCELLED_ID + { + add_opvars(splev, "ii", 1, SP_M_V_CANCELLED); + $$ = 0x0080; + } + | REVIVED_ID + { + add_opvars(splev, "ii", 1, SP_M_V_REVIVED); + $$ = 0x0100; + } + | AVENGE_ID + { + add_opvars(splev, "ii", 1, SP_M_V_AVENGE); + $$ = 0x0200; + } + | FLEEING_ID ':' integer_or_var + { + add_opvars(splev, "i", SP_M_V_FLEEING); + $$ = 0x0400; + } + | BLINDED_ID ':' integer_or_var + { + add_opvars(splev, "i", SP_M_V_BLINDED); + $$ = 0x0800; + } + | PARALYZED_ID ':' integer_or_var + { + add_opvars(splev, "i", SP_M_V_PARALYZED); + $$ = 0x1000; + } + | STUNNED_ID + { + add_opvars(splev, "ii", 1, SP_M_V_STUNNED); + $$ = 0x2000; + } + | CONFUSED_ID + { + add_opvars(splev, "ii", 1, SP_M_V_CONFUSED); + $$ = 0x4000; + } + | SEENTRAPS_ID ':' seen_trap_mask + { + add_opvars(splev, "ii", (long)$3, SP_M_V_SEENTRAPS); + $$ = 0x8000; } ; -object_desc : chance ':' object_c ',' o_name +seen_trap_mask : STRING { - tmpobj[nobj] = New(object); - tmpobj[nobj]->class = $3; - tmpobj[nobj]->corpsenm = NON_PM; - tmpobj[nobj]->curse_state = -1; - tmpobj[nobj]->name.str = 0; - tmpobj[nobj]->chance = $1; - tmpobj[nobj]->id = -1; - if ($5) { - int token = get_object_id($5, $3); - if (token == ERR) - yywarning( - "Illegal object name! Making random object."); - else - tmpobj[nobj]->id = token; - Free($5); - } + int token = get_trap_type($1); + if (token == ERR || token == 0) + lc_error("Unknown trap type '%s'!", $1); + $$ = (1L << (token - 1)); } - ',' object_where object_infos + | ALL_ID { - if (++nobj >= MAX_OF_TYPE) { - yyerror("Too many objects in room or mazepart!"); - nobj--; - } + $$ = (long) ~0; + } + | STRING '|' seen_trap_mask + { + int token = get_trap_type($1); + if (token == ERR || token == 0) + lc_error("Unknown trap type '%s'!", $1); + + if ((1L << (token - 1)) & $3) + lc_error("Monster seen_traps, trap '%s' listed twice.", $1); + + $$ = ((1L << (token - 1)) | $3); } ; -object_where : coordinate +object_detail : OBJECT_ID ':' object_desc { - tmpobj[nobj]->containment = 0; - tmpobj[nobj]->x = current_coord.x; - tmpobj[nobj]->y = current_coord.y; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Object"); + long cnt = 0; + if (in_container_obj) cnt |= SP_OBJ_CONTENT; + add_opvars(splev, "io", cnt, SPO_OBJECT); } - | CONTAINED + | COBJECT_ID ':' object_desc { - tmpobj[nobj]->containment = 1; - /* random coordinate, will be overridden anyway */ - tmpobj[nobj]->x = -MAX_REGISTERS-1; - tmpobj[nobj]->y = -MAX_REGISTERS-1; + long cnt = SP_OBJ_CONTAINER; + if (in_container_obj) cnt |= SP_OBJ_CONTENT; + add_opvars(splev, "io", cnt, SPO_OBJECT); + in_container_obj++; + break_stmt_start(); + } + stmt_block + { + break_stmt_end(splev); + in_container_obj--; + add_opcode(splev, SPO_POP_CONTAINER, NULL); + } + ; + +object_desc : object_or_var object_infos + { + if (( $2 & 0x4000) && in_container_obj) lc_error("Object cannot have a coord when contained."); + else if (!( $2 & 0x4000) && !in_container_obj) lc_error("Object needs a coord when not contained."); } ; object_infos : /* nothing */ { - tmpobj[nobj]->spe = -127; - /* Note below: we're trying to make as many of these optional as - * possible. We clearly can't make curse_state, enchantment, and - * monster_id _all_ optional, since ",random" would be ambiguous. - * We can't even just make enchantment mandatory, since if we do that - * alone, ",random" requires too much lookahead to parse. - */ + struct opvar *stopit = New(struct opvar); + set_opvar_int(stopit, SP_O_V_END); + add_opcode(splev, SPO_PUSH, stopit); + $$ = 0x00; } - | ',' curse_state ',' monster_id ',' enchantment optional_name - { - } - | ',' curse_state ',' enchantment optional_name - { - } - | ',' monster_id ',' enchantment optional_name + | object_infos ',' object_info { + if (( $1 & $3 )) + lc_error("OBJECT extra info '%s' defined twice.", curr_token); + $$ = ( $1 | $3 ); } ; -curse_state : RANDOM_TYPE +object_info : CURSE_TYPE { - tmpobj[nobj]->curse_state = -1; + add_opvars(splev, "ii", (long)$1, SP_O_V_CURSE); + $$ = 0x0001; } - | CURSE_TYPE + | MONTYPE_ID ':' monster_or_var { - tmpobj[nobj]->curse_state = $1; + add_opvars(splev, "i", SP_O_V_CORPSENM); + $$ = 0x0002; + } + | all_ints_push + { + add_opvars(splev, "i", SP_O_V_SPE); + $$ = 0x0004; + } + | NAME_ID ':' string_expr + { + add_opvars(splev, "i", SP_O_V_NAME); + $$ = 0x0008; + } + | QUANTITY_ID ':' integer_or_var + { + add_opvars(splev, "i", SP_O_V_QUAN); + $$ = 0x0010; + } + | BURIED_ID + { + add_opvars(splev, "ii", 1, SP_O_V_BURIED); + $$ = 0x0020; + } + | LIGHT_STATE + { + add_opvars(splev, "ii", (long)$1, SP_O_V_LIT); + $$ = 0x0040; + } + | ERODED_ID ':' integer_or_var + { + add_opvars(splev, "i", SP_O_V_ERODED); + $$ = 0x0080; + } + | ERODEPROOF_ID + { + add_opvars(splev, "ii", -1, SP_O_V_ERODED); + $$ = 0x0080; + } + | DOOR_STATE + { + if ($1 == D_LOCKED) { + add_opvars(splev, "ii", 1, SP_O_V_LOCKED); + $$ = 0x0100; + } else if ($1 == D_BROKEN) { + add_opvars(splev, "ii", 1, SP_O_V_BROKEN); + $$ = 0x0200; + } else + lc_error("OBJECT state can only be locked or broken."); + } + | TRAPPED_ID + { + add_opvars(splev, "ii", 1, SP_O_V_TRAPPED); + $$ = 0x0400; + } + | RECHARGED_ID ':' integer_or_var + { + add_opvars(splev, "i", SP_O_V_RECHARGED); + $$ = 0x0800; + } + | INVIS_ID + { + add_opvars(splev, "ii", 1, SP_O_V_INVIS); + $$ = 0x1000; + } + | GREASED_ID + { + add_opvars(splev, "ii", 1, SP_O_V_GREASED); + $$ = 0x2000; + } + | coord_or_var + { + add_opvars(splev, "i", SP_O_V_COORD); + $$ = 0x4000; } ; -monster_id : STRING +trap_detail : TRAP_ID ':' trap_name ',' coord_or_var { - int token = get_monster_id($1, (char)0); - if (token == ERR) /* "random" */ - tmpobj[nobj]->corpsenm = NON_PM - 1; - else - tmpobj[nobj]->corpsenm = token; - Free($1); + add_opvars(splev, "io", (long)$3, SPO_TRAP); } ; -enchantment : RANDOM_TYPE - { - tmpobj[nobj]->spe = -127; - } - | INTEGER - { - tmpobj[nobj]->spe = $1; - } - ; - -optional_name : /* nothing */ - | ',' NONE - { - } - | ',' STRING - { - tmpobj[nobj]->name.str = $2; - } - ; - -door_detail : DOOR_ID ':' door_state ',' coordinate - { - tmpdoor[ndoor] = New(door); - tmpdoor[ndoor]->x = current_coord.x; - tmpdoor[ndoor]->y = current_coord.y; - tmpdoor[ndoor]->mask = $3; - if(current_coord.x >= 0 && current_coord.y >= 0 && - tmpmap[current_coord.y][current_coord.x] != DOOR && - tmpmap[current_coord.y][current_coord.x] != SDOOR) - yyerror("Door decl doesn't match the map"); - ndoor++; - if (ndoor >= MAX_OF_TYPE) { - yyerror("Too many doors in mazepart!"); - ndoor--; - } - } - ; - -trap_detail : TRAP_ID chance ':' trap_name ',' coordinate - { - tmptrap[ntrap] = New(trap); - tmptrap[ntrap]->x = current_coord.x; - tmptrap[ntrap]->y = current_coord.y; - tmptrap[ntrap]->type = $4; - tmptrap[ntrap]->chance = $2; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Trap"); - if (++ntrap >= MAX_OF_TYPE) { - yyerror("Too many traps in room or mazepart!"); - ntrap--; - } - } - ; - -drawbridge_detail: DRAWBRIDGE_ID ':' coordinate ',' DIRECTION ',' door_state +drawbridge_detail: DRAWBRIDGE_ID ':' coord_or_var ',' DIRECTION ',' door_state { - int x, y, dir; + long d, state = 0; + /* convert dir from a DIRECTION to a DB_DIR */ + d = $5; + switch(d) { + case W_NORTH: d = DB_NORTH; break; + case W_SOUTH: d = DB_SOUTH; break; + case W_EAST: d = DB_EAST; break; + case W_WEST: d = DB_WEST; break; + default: + lc_error("Invalid drawbridge direction."); + break; + } - tmpdb[ndb] = New(drawbridge); - x = tmpdb[ndb]->x = current_coord.x; - y = tmpdb[ndb]->y = current_coord.y; - /* convert dir from a DIRECTION to a DB_DIR */ - dir = $5; - switch(dir) { - case W_NORTH: dir = DB_NORTH; y--; break; - case W_SOUTH: dir = DB_SOUTH; y++; break; - case W_EAST: dir = DB_EAST; x++; break; - case W_WEST: dir = DB_WEST; x--; break; - default: - yyerror("Invalid drawbridge direction"); - break; - } - tmpdb[ndb]->dir = dir; - if (current_coord.x >= 0 && current_coord.y >= 0 && - !IS_WALL(tmpmap[y][x])) { - char ebuf[60]; - Sprintf(ebuf, - "Wall needed for drawbridge (%02d, %02d)", - current_coord.x, current_coord.y); - yyerror(ebuf); - } - - if ( $7 == D_ISOPEN ) - tmpdb[ndb]->db_open = 1; - else if ( $7 == D_CLOSED ) - tmpdb[ndb]->db_open = 0; - else if ($7 == -1) /* RANDOM_TYPE */ - tmpdb[ndb]->db_open = 127; /* random */ - else - yyerror("A drawbridge can only be open, closed, or random!"); - ndb++; - if (ndb >= MAX_OF_TYPE) { - yyerror("Too many drawbridges in mazepart!"); - ndb--; - } + if ( $7 == D_ISOPEN ) + state = 1; + else if ( $7 == D_CLOSED ) + state = 0; + else if ( $7 == -1 ) + state = -1; + else + lc_error("A drawbridge can only be open, closed or random!"); + add_opvars(splev, "iio", state, d, SPO_DRAWBRIDGE); } ; -mazewalk_detail : MAZEWALK_ID ':' coordinate ',' DIRECTION +mazewalk_detail : MAZEWALK_ID ':' coord_or_var ',' DIRECTION { - tmpwalk[nwalk] = New(walk); - tmpwalk[nwalk]->x = current_coord.x; - tmpwalk[nwalk]->y = current_coord.y; - tmpwalk[nwalk]->dir = $5; - nwalk++; - if (nwalk >= MAX_OF_TYPE) { - yyerror("Too many mazewalks in mazepart!"); - nwalk--; - } + add_opvars(splev, "iiio", + (long)$5, 1, 0, SPO_MAZEWALK); + } + | MAZEWALK_ID ':' coord_or_var ',' DIRECTION ',' BOOLEAN opt_fillchar + { + add_opvars(splev, "iiio", + (long)$5, (long)$7, (long)$8, SPO_MAZEWALK); } ; wallify_detail : WALLIFY_ID { - wallify_map(); + add_opvars(splev, "rio", SP_REGION_PACK(-1,-1,-1,-1), 0, SPO_WALLIFY); + } + | WALLIFY_ID ':' ter_selection + { + add_opvars(splev, "io", 1, SPO_WALLIFY); } ; -ladder_detail : LADDER_ID ':' coordinate ',' UP_OR_DOWN +ladder_detail : LADDER_ID ':' coord_or_var ',' UP_OR_DOWN { - tmplad[nlad] = New(lad); - tmplad[nlad]->x = current_coord.x; - tmplad[nlad]->y = current_coord.y; - tmplad[nlad]->up = $5; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Ladder"); - nlad++; - if (nlad >= MAX_OF_TYPE) { - yyerror("Too many ladders in mazepart!"); - nlad--; - } + add_opvars(splev, "io", (long)$5, SPO_LADDER); } ; -stair_detail : STAIR_ID ':' coordinate ',' UP_OR_DOWN +stair_detail : STAIR_ID ':' coord_or_var ',' UP_OR_DOWN { - tmpstair[nstair] = New(stair); - tmpstair[nstair]->x = current_coord.x; - tmpstair[nstair]->y = current_coord.y; - tmpstair[nstair]->up = $5; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Stairway"); - nstair++; - if (nstair >= MAX_OF_TYPE) { - yyerror("Too many stairs in room or mazepart!"); - nstair--; - } + add_opvars(splev, "io", (long)$5, SPO_STAIR); } ; -stair_region : STAIR_ID ':' lev_region +stair_region : STAIR_ID ':' lev_region ',' lev_region ',' UP_OR_DOWN { - tmplreg[nlreg] = New(lev_region); - tmplreg[nlreg]->in_islev = $3; - tmplreg[nlreg]->inarea.x1 = current_region.x1; - tmplreg[nlreg]->inarea.y1 = current_region.y1; - tmplreg[nlreg]->inarea.x2 = current_region.x2; - tmplreg[nlreg]->inarea.y2 = current_region.y2; - } - ',' lev_region ',' UP_OR_DOWN - { - tmplreg[nlreg]->del_islev = $6; - tmplreg[nlreg]->delarea.x1 = current_region.x1; - tmplreg[nlreg]->delarea.y1 = current_region.y1; - tmplreg[nlreg]->delarea.x2 = current_region.x2; - tmplreg[nlreg]->delarea.y2 = current_region.y2; - if($8) - tmplreg[nlreg]->rtype = LR_UPSTAIR; - else - tmplreg[nlreg]->rtype = LR_DOWNSTAIR; - tmplreg[nlreg]->rname.str = 0; - nlreg++; - if (nlreg >= MAX_OF_TYPE) { - yyerror("Too many levregions in mazepart!"); - nlreg--; - } + add_opvars(splev, "iiiii iiiii iiso", + $3.x1, $3.y1, $3.x2, $3.y2, $3.area, + $5.x1, $5.y1, $5.x2, $5.y2, $5.area, + (long)(($7) ? LR_UPSTAIR : LR_DOWNSTAIR), + 0, (char *)0, SPO_LEVREGION); } ; -portal_region : PORTAL_ID ':' lev_region +portal_region : PORTAL_ID ':' lev_region ',' lev_region ',' STRING { - tmplreg[nlreg] = New(lev_region); - tmplreg[nlreg]->in_islev = $3; - tmplreg[nlreg]->inarea.x1 = current_region.x1; - tmplreg[nlreg]->inarea.y1 = current_region.y1; - tmplreg[nlreg]->inarea.x2 = current_region.x2; - tmplreg[nlreg]->inarea.y2 = current_region.y2; - } - ',' lev_region ',' string - { - tmplreg[nlreg]->del_islev = $6; - tmplreg[nlreg]->delarea.x1 = current_region.x1; - tmplreg[nlreg]->delarea.y1 = current_region.y1; - tmplreg[nlreg]->delarea.x2 = current_region.x2; - tmplreg[nlreg]->delarea.y2 = current_region.y2; - tmplreg[nlreg]->rtype = LR_PORTAL; - tmplreg[nlreg]->rname.str = $8; - nlreg++; - if (nlreg >= MAX_OF_TYPE) { - yyerror("Too many levregions in mazepart!"); - nlreg--; - } + add_opvars(splev, "iiiii iiiii iiso", + $3.x1, $3.y1, $3.x2, $3.y2, $3.area, + $5.x1, $5.y1, $5.x2, $5.y2, $5.area, + LR_PORTAL, 0, $7, SPO_LEVREGION); + Free($7); } ; -teleprt_region : TELEPRT_ID ':' lev_region +teleprt_region : TELEPRT_ID ':' lev_region ',' lev_region teleprt_detail { - tmplreg[nlreg] = New(lev_region); - tmplreg[nlreg]->in_islev = $3; - tmplreg[nlreg]->inarea.x1 = current_region.x1; - tmplreg[nlreg]->inarea.y1 = current_region.y1; - tmplreg[nlreg]->inarea.x2 = current_region.x2; - tmplreg[nlreg]->inarea.y2 = current_region.y2; - } - ',' lev_region - { - tmplreg[nlreg]->del_islev = $6; - tmplreg[nlreg]->delarea.x1 = current_region.x1; - tmplreg[nlreg]->delarea.y1 = current_region.y1; - tmplreg[nlreg]->delarea.x2 = current_region.x2; - tmplreg[nlreg]->delarea.y2 = current_region.y2; - } - teleprt_detail - { - switch($8) { - case -1: tmplreg[nlreg]->rtype = LR_TELE; break; - case 0: tmplreg[nlreg]->rtype = LR_DOWNTELE; break; - case 1: tmplreg[nlreg]->rtype = LR_UPTELE; break; - } - tmplreg[nlreg]->rname.str = 0; - nlreg++; - if (nlreg >= MAX_OF_TYPE) { - yyerror("Too many levregions in mazepart!"); - nlreg--; - } + long rtype = 0; + switch($6) { + case -1: rtype = LR_TELE; break; + case 0: rtype = LR_DOWNTELE; break; + case 1: rtype = LR_UPTELE; break; + } + add_opvars(splev, "iiiii iiiii iiso", + $3.x1, $3.y1, $3.x2, $3.y2, $3.area, + $5.x1, $5.y1, $5.x2, $5.y2, $5.area, + rtype, 0, (char *)0, SPO_LEVREGION); } ; -branch_region : BRANCH_ID ':' lev_region +branch_region : BRANCH_ID ':' lev_region ',' lev_region { - tmplreg[nlreg] = New(lev_region); - tmplreg[nlreg]->in_islev = $3; - tmplreg[nlreg]->inarea.x1 = current_region.x1; - tmplreg[nlreg]->inarea.y1 = current_region.y1; - tmplreg[nlreg]->inarea.x2 = current_region.x2; - tmplreg[nlreg]->inarea.y2 = current_region.y2; - } - ',' lev_region - { - tmplreg[nlreg]->del_islev = $6; - tmplreg[nlreg]->delarea.x1 = current_region.x1; - tmplreg[nlreg]->delarea.y1 = current_region.y1; - tmplreg[nlreg]->delarea.x2 = current_region.x2; - tmplreg[nlreg]->delarea.y2 = current_region.y2; - tmplreg[nlreg]->rtype = LR_BRANCH; - tmplreg[nlreg]->rname.str = 0; - nlreg++; - if (nlreg >= MAX_OF_TYPE) { - yyerror("Too many levregions in mazepart!"); - nlreg--; - } + add_opvars(splev, "iiiii iiiii iiso", + $3.x1, $3.y1, $3.x2, $3.y2, $3.area, + $5.x1, $5.y1, $5.x2, $5.y2, $5.area, + (long)LR_BRANCH, 0, (char *)0, SPO_LEVREGION); } ; teleprt_detail : /* empty */ { - $$ = -1; + $$ = -1; } | ',' UP_OR_DOWN { - $$ = $2; + $$ = $2; } ; -lev_region : region +fountain_detail : FOUNTAIN_ID ':' ter_selection { - $$ = 0; - } - | LEV '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')' - { -/* This series of if statements is a hack for MSC 5.1. It seems that its - tiny little brain cannot compile if these are all one big if statement. */ - if ($3 <= 0 || $3 >= COLNO) - yyerror("Region out of level range!"); - else if ($5 < 0 || $5 >= ROWNO) - yyerror("Region out of level range!"); - else if ($7 <= 0 || $7 >= COLNO) - yyerror("Region out of level range!"); - else if ($9 < 0 || $9 >= ROWNO) - yyerror("Region out of level range!"); - current_region.x1 = $3; - current_region.y1 = $5; - current_region.x2 = $7; - current_region.y2 = $9; - $$ = 1; + add_opvars(splev, "o", SPO_FOUNTAIN); } ; -fountain_detail : FOUNTAIN_ID ':' coordinate +sink_detail : SINK_ID ':' ter_selection { - tmpfountain[nfountain] = New(fountain); - tmpfountain[nfountain]->x = current_coord.x; - tmpfountain[nfountain]->y = current_coord.y; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Fountain"); - nfountain++; - if (nfountain >= MAX_OF_TYPE) { - yyerror("Too many fountains in room or mazepart!"); - nfountain--; - } + add_opvars(splev, "o", SPO_SINK); } ; -sink_detail : SINK_ID ':' coordinate +pool_detail : POOL_ID ':' ter_selection { - tmpsink[nsink] = New(sink); - tmpsink[nsink]->x = current_coord.x; - tmpsink[nsink]->y = current_coord.y; - nsink++; - if (nsink >= MAX_OF_TYPE) { - yyerror("Too many sinks in room!"); - nsink--; - } + add_opvars(splev, "o", SPO_POOL); } ; -pool_detail : POOL_ID ':' coordinate +terrain_type : CHAR { - tmppool[npool] = New(pool); - tmppool[npool]->x = current_coord.x; - tmppool[npool]->y = current_coord.y; - npool++; - if (npool >= MAX_OF_TYPE) { - yyerror("Too many pools in room!"); - npool--; - } + $$.lit = -2; + $$.ter = what_map_char((char) $1); + } + | '(' CHAR ',' light_state ')' + { + $$.lit = $4; + $$.ter = what_map_char((char) $2); } ; -diggable_detail : NON_DIGGABLE_ID ':' region +replace_terrain_detail : REPLACE_TERRAIN_ID ':' region_or_var ',' mapchar_or_var ',' mapchar_or_var ',' SPERCENT { - tmpdig[ndig] = New(digpos); - tmpdig[ndig]->x1 = current_region.x1; - tmpdig[ndig]->y1 = current_region.y1; - tmpdig[ndig]->x2 = current_region.x2; - tmpdig[ndig]->y2 = current_region.y2; - ndig++; - if (ndig >= MAX_OF_TYPE) { - yyerror("Too many diggables in mazepart!"); - ndig--; - } + add_opvars(splev, "io", $9, SPO_REPLACETERRAIN); } ; -passwall_detail : NON_PASSWALL_ID ':' region +terrain_detail : TERRAIN_ID ':' ter_selection ',' mapchar_or_var + { + add_opvars(splev, "o", SPO_TERRAIN); + } + ; + +diggable_detail : NON_DIGGABLE_ID ':' region_or_var { - tmppass[npass] = New(digpos); - tmppass[npass]->x1 = current_region.x1; - tmppass[npass]->y1 = current_region.y1; - tmppass[npass]->x2 = current_region.x2; - tmppass[npass]->y2 = current_region.y2; - npass++; - if (npass >= 32) { - yyerror("Too many passwalls in mazepart!"); - npass--; - } + add_opvars(splev, "o", SPO_NON_DIGGABLE); } ; -region_detail : REGION_ID ':' region ',' light_state ',' room_type prefilled +passwall_detail : NON_PASSWALL_ID ':' region_or_var { - tmpreg[nreg] = New(region); - tmpreg[nreg]->x1 = current_region.x1; - tmpreg[nreg]->y1 = current_region.y1; - tmpreg[nreg]->x2 = current_region.x2; - tmpreg[nreg]->y2 = current_region.y2; - tmpreg[nreg]->rlit = $5; - tmpreg[nreg]->rtype = $7; - if($8 & 1) tmpreg[nreg]->rtype += MAXRTYPE+1; - tmpreg[nreg]->rirreg = (($8 & 2) != 0); - if(current_region.x1 > current_region.x2 || - current_region.y1 > current_region.y2) - yyerror("Region start > end!"); - if(tmpreg[nreg]->rtype == VAULT && - (tmpreg[nreg]->rirreg || - (tmpreg[nreg]->x2 - tmpreg[nreg]->x1 != 1) || - (tmpreg[nreg]->y2 - tmpreg[nreg]->y1 != 1))) - yyerror("Vaults must be exactly 2x2!"); - if(want_warnings && !tmpreg[nreg]->rirreg && - current_region.x1 > 0 && current_region.y1 > 0 && - current_region.x2 < (int)max_x_map && - current_region.y2 < (int)max_y_map) { - /* check for walls in the room */ - char ebuf[60]; - register int x, y, nrock = 0; - - for(y=current_region.y1; y<=current_region.y2; y++) - for(x=current_region.x1; - x<=current_region.x2; x++) - if(IS_ROCK(tmpmap[y][x]) || - IS_DOOR(tmpmap[y][x])) nrock++; - if(nrock) { - Sprintf(ebuf, - "Rock in room (%02d,%02d,%02d,%02d)?!", - current_region.x1, current_region.y1, - current_region.x2, current_region.y2); - yywarning(ebuf); - } - if ( - !IS_ROCK(tmpmap[current_region.y1-1][current_region.x1-1]) || - !IS_ROCK(tmpmap[current_region.y2+1][current_region.x1-1]) || - !IS_ROCK(tmpmap[current_region.y1-1][current_region.x2+1]) || - !IS_ROCK(tmpmap[current_region.y2+1][current_region.x2+1])) { - Sprintf(ebuf, - "NonRock edge in room (%02d,%02d,%02d,%02d)?!", - current_region.x1, current_region.y1, - current_region.x2, current_region.y2); - yywarning(ebuf); - } - } else if(tmpreg[nreg]->rirreg && - !IS_ROOM(tmpmap[current_region.y1][current_region.x1])) { - char ebuf[60]; - Sprintf(ebuf, - "Rock in irregular room (%02d,%02d)?!", - current_region.x1, current_region.y1); - yyerror(ebuf); - } - nreg++; - if (nreg >= MAX_OF_TYPE) { - yyerror("Too many regions in mazepart!"); - nreg--; - } + add_opvars(splev, "o", SPO_NON_PASSWALL); } ; -altar_detail : ALTAR_ID ':' coordinate ',' alignment ',' altar_type +region_detail : REGION_ID ':' region_or_var ',' light_state ',' room_type optroomregionflags { - tmpaltar[naltar] = New(altar); - tmpaltar[naltar]->x = current_coord.x; - tmpaltar[naltar]->y = current_coord.y; - tmpaltar[naltar]->align = $5; - tmpaltar[naltar]->shrine = $7; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Altar"); - naltar++; - if (naltar >= MAX_OF_TYPE) { - yyerror("Too many altars in room or mazepart!"); - naltar--; - } + long irr; + long rt = $7; + long flags = $8; + if (flags == -1) flags = (1 << 0); + if (!(( flags ) & 1)) rt += MAXRTYPE+1; + irr = ((( flags ) & 2) != 0); + add_opvars(splev, "iiio", + (long)$5, rt, flags, SPO_REGION); + $$ = (irr || (flags & 1) || rt != OROOM); + break_stmt_start(); + } + region_detail_end + { + break_stmt_end(splev); + if ( $9 ) { + add_opcode(splev, SPO_ENDROOM, NULL); + } else if ( $10 ) + lc_error("Cannot use lev statements in non-permanent REGION"); } ; -gold_detail : GOLD_ID ':' amount ',' coordinate +region_detail_end : /* nothing */ { - tmpgold[ngold] = New(gold); - tmpgold[ngold]->x = current_coord.x; - tmpgold[ngold]->y = current_coord.y; - tmpgold[ngold]->amount = $3; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Gold"); - ngold++; - if (ngold >= MAX_OF_TYPE) { - yyerror("Too many golds in room or mazepart!"); - ngold--; - } + $$ = 0; + } + | stmt_block + { + $$ = $1; } ; -engraving_detail: ENGRAVING_ID ':' coordinate ',' engraving_type ',' string +altar_detail : ALTAR_ID ':' coord_or_var ',' alignment ',' altar_type { - tmpengraving[nengraving] = New(engraving); - tmpengraving[nengraving]->x = current_coord.x; - tmpengraving[nengraving]->y = current_coord.y; - tmpengraving[nengraving]->engr.str = $7; - tmpengraving[nengraving]->etype = $5; - if (!in_room) - check_coord(current_coord.x, current_coord.y, - "Engraving"); - nengraving++; - if (nengraving >= MAX_OF_TYPE) { - yyerror("Too many engravings in room or mazepart!"); - nengraving--; - } + add_opvars(splev, "iio", (long)$7, (long)$5, SPO_ALTAR); } ; -monster_c : monster - | RANDOM_TYPE +grave_detail : GRAVE_ID ':' coord_or_var ',' string_expr { - $$ = - MAX_REGISTERS - 1; + add_opvars(splev, "io", 2, SPO_GRAVE); } - | m_register - ; - -object_c : object - | RANDOM_TYPE + | GRAVE_ID ':' coord_or_var ',' RANDOM_TYPE { - $$ = - MAX_REGISTERS - 1; + add_opvars(splev, "sio", + (char *)0, 1, SPO_GRAVE); } - | o_register - ; - -m_name : string - | RANDOM_TYPE + | GRAVE_ID ':' coord_or_var { - $$ = (char *) 0; + add_opvars(splev, "sio", + (char *)0, 0, SPO_GRAVE); } ; -o_name : string - | RANDOM_TYPE +gold_detail : GOLD_ID ':' math_expr_var ',' coord_or_var { - $$ = (char *) 0; + add_opvars(splev, "o", SPO_GOLD); } ; -trap_name : string +engraving_detail: ENGRAVING_ID ':' coord_or_var ',' engraving_type ',' string_expr + { + add_opvars(splev, "io", + (long)$5, SPO_ENGRAVING); + } + ; + +mineralize : MINERALIZE_ID ':' integer_or_var ',' integer_or_var ',' integer_or_var ',' integer_or_var + { + add_opvars(splev, "o", SPO_MINERALIZE); + } + | MINERALIZE_ID + { + add_opvars(splev, "iiiio", -1L, -1L, -1L, -1L, SPO_MINERALIZE); + } + ; + +trap_name : STRING { int token = get_trap_type($1); if (token == ERR) - yyerror("Unknown trap type!"); - $$ = token; + lc_error("Unknown trap type '%s'!", $1); + $$ = token; Free($1); } | RANDOM_TYPE ; -room_type : string +room_type : STRING { int token = get_room_type($1); if (token == ERR) { - yywarning("Unknown room type! Making ordinary room..."); - $$ = OROOM; + lc_warning("Unknown room type \"%s\"! Making ordinary room...", $1); + $$ = OROOM; } else - $$ = token; + $$ = token; Free($1); } | RANDOM_TYPE ; -prefilled : /* empty */ +optroomregionflags : /* empty */ { - $$ = 0; + $$ = -1; } - | ',' FILLING + | ',' roomregionflags { - $$ = $2; - } - | ',' FILLING ',' BOOLEAN - { - $$ = $2 + ($4 << 1); + $$ = $2; } ; -coordinate : coord - | p_register - | RANDOM_TYPE +roomregionflags : roomregionflag { - current_coord.x = current_coord.y = -MAX_REGISTERS-1; + $$ = $1; + } + | roomregionflag ',' roomregionflags + { + $$ = $1 | $3; + } + ; + +/* 0 is the "default" here */ +roomregionflag : FILLING + { + $$ = ($1 << 0); + } + | IRREGULAR + { + $$ = ($1 << 1); + } + | JOINED + { + $$ = ($1 << 2); } ; @@ -1577,7 +1927,15 @@ alignment : ALIGNMENT | a_register | RANDOM_TYPE { - $$ = - MAX_REGISTERS - 1; + $$ = - MAX_REGISTERS - 1; + } + ; + +alignment_prfx : ALIGNMENT + | a_register + | A_REGISTER ':' RANDOM_TYPE + { + $$ = - MAX_REGISTERS - 1; } ; @@ -1585,99 +1943,555 @@ altar_type : ALTAR_TYPE | RANDOM_TYPE ; -p_register : P_REGISTER '[' INTEGER ']' - { - if ( $3 >= MAX_REGISTERS ) - yyerror("Register Index overflow!"); - else - current_coord.x = current_coord.y = - $3 - 1; - } - ; - -o_register : O_REGISTER '[' INTEGER ']' - { - if ( $3 >= MAX_REGISTERS ) - yyerror("Register Index overflow!"); - else - $$ = - $3 - 1; - } - ; - -m_register : M_REGISTER '[' INTEGER ']' - { - if ( $3 >= MAX_REGISTERS ) - yyerror("Register Index overflow!"); - else - $$ = - $3 - 1; - } - ; - a_register : A_REGISTER '[' INTEGER ']' { if ( $3 >= 3 ) - yyerror("Register Index overflow!"); + lc_error("Register Index overflow!"); else - $$ = - $3 - 1; + $$ = - $3 - 1; } ; -place : coord - ; - -monster : CHAR +string_or_var : STRING { - if (check_monster_char((char) $1)) - $$ = $1 ; - else { - yyerror("Unknown monster class!"); - $$ = ERR; - } + add_opvars(splev, "s", $1); + Free($1); } - ; - -object : CHAR + | VARSTRING_STRING { - char c = $1; - if (check_object_char(c)) - $$ = c; - else { - yyerror("Unknown char class!"); - $$ = ERR; - } + check_vardef_type(variable_definitions, $1, SPOVAR_STRING); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + | VARSTRING_STRING_ARRAY '[' math_expr_var ']' + { + check_vardef_type(variable_definitions, $1, SPOVAR_STRING|SPOVAR_ARRAY); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); } ; -string : STRING + +integer_or_var : math_expr_var + { + /* nothing */ + } ; -amount : INTEGER +coord_or_var : encodecoord + { + add_opvars(splev, "c", $1); + } + | rndcoord_ID '(' ter_selection ')' + { + add_opvars(splev, "o", SPO_SEL_RNDCOORD); + } + | VARSTRING_COORD + { + check_vardef_type(variable_definitions, $1, SPOVAR_COORD); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + | VARSTRING_COORD_ARRAY '[' math_expr_var ']' + { + check_vardef_type(variable_definitions, $1, SPOVAR_COORD|SPOVAR_ARRAY); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + ; + +encodecoord : '(' INTEGER ',' INTEGER ')' + { + if ($2 < 0 || $4 < 0 || $2 >= COLNO || $4 >= ROWNO) + lc_error("Coordinates (%li,%li) out of map range!", $2, $4); + $$ = SP_COORD_PACK($2, $4); + } | RANDOM_TYPE + { + $$ = SP_COORD_PACK_RANDOM(0); + } + | RANDOM_TYPE_BRACKET humidity_flags ']' + { + $$ = SP_COORD_PACK_RANDOM( $2 ); + } ; -chance : /* empty */ +humidity_flags : HUMIDITY_TYPE { - $$ = 100; /* default is 100% */ + $$ = $1; } - | PERCENT + | HUMIDITY_TYPE ',' humidity_flags { - if ($1 <= 0 || $1 > 100) - yyerror("Expected percentile chance."); - $$ = $1; + if (($1 & $3)) + lc_warning("Humidity flag used twice."); + $$ = ($1 | $3); } ; +region_or_var : encoderegion + { + /* nothing */ + } + | VARSTRING_REGION + { + check_vardef_type(variable_definitions, $1, SPOVAR_REGION); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + | VARSTRING_REGION_ARRAY '[' math_expr_var ']' + { + check_vardef_type(variable_definitions, $1, SPOVAR_REGION|SPOVAR_ARRAY); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + ; + +encoderegion : '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')' + { + long r = SP_REGION_PACK($2, $4, $6, $8); + if ( $2 > $6 || $4 > $8 ) + lc_error("Region start > end: (%li,%li,%li,%li)!", $2, $4, $6, $8); + + add_opvars(splev, "r", r); + $$ = r; + } + ; + +mapchar_or_var : mapchar + { + add_opvars(splev, "m", $1); + } + | VARSTRING_MAPCHAR + { + check_vardef_type(variable_definitions, $1, SPOVAR_MAPCHAR); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + | VARSTRING_MAPCHAR_ARRAY '[' math_expr_var ']' + { + check_vardef_type(variable_definitions, $1, SPOVAR_MAPCHAR|SPOVAR_ARRAY); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + ; + +mapchar : CHAR + { + if (what_map_char((char) $1) != INVALID_TYPE) + $$ = SP_MAPCHAR_PACK(what_map_char((char) $1), -2); + else { + lc_error("Unknown map char type '%c'!", $1); + $$ = SP_MAPCHAR_PACK(STONE, -2); + } + } + | '(' CHAR ',' light_state ')' + { + if (what_map_char((char) $2) != INVALID_TYPE) + $$ = SP_MAPCHAR_PACK(what_map_char((char) $2), $4); + else { + lc_error("Unknown map char type '%c'!", $2); + $$ = SP_MAPCHAR_PACK(STONE, $4); + } + } + ; + +monster_or_var : encodemonster + { + add_opvars(splev, "M", $1); + } + | VARSTRING_MONST + { + check_vardef_type(variable_definitions, $1, SPOVAR_MONST); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + | VARSTRING_MONST_ARRAY '[' math_expr_var ']' + { + check_vardef_type(variable_definitions, $1, SPOVAR_MONST|SPOVAR_ARRAY); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + ; + +encodemonster : STRING + { + long m = get_monster_id($1, (char)0); + if (m == ERR) { + lc_error("Unknown monster \"%s\"!", $1); + $$ = -1; + } else + $$ = SP_MONST_PACK(m, def_monsyms[(int)mons[m].mlet].sym); + } + | CHAR + { + if (check_monster_char((char) $1)) + $$ = SP_MONST_PACK(-1, $1); + else { + lc_error("Unknown monster class '%c'!", $1); + $$ = -1; + } + } + | '(' CHAR ',' STRING ')' + { + long m = get_monster_id($4, (char) $2); + if (m == ERR) { + lc_error("Unknown monster ('%c', \"%s\")!", $2, $4); + $$ = -1; + } else + $$ = SP_MONST_PACK(m, $2); + } + | RANDOM_TYPE + { + $$ = -1; + } + ; + +object_or_var : encodeobj + { + add_opvars(splev, "O", $1); + } + | VARSTRING_OBJ + { + check_vardef_type(variable_definitions, $1, SPOVAR_OBJ); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + | VARSTRING_OBJ_ARRAY '[' math_expr_var ']' + { + check_vardef_type(variable_definitions, $1, SPOVAR_OBJ|SPOVAR_ARRAY); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + ; + +encodeobj : STRING + { + long m = get_object_id($1, (char)0); + if (m == ERR) { + lc_error("Unknown object \"%s\"!", $1); + $$ = -1; + } else + $$ = SP_OBJ_PACK(m, 1); /* obj class != 0 to force generation of a specific item */ + + } + | CHAR + { + if (check_object_char((char) $1)) + $$ = SP_OBJ_PACK(-1, $1); + else { + lc_error("Unknown object class '%c'!", $1); + $$ = -1; + } + } + | '(' CHAR ',' STRING ')' + { + long m = get_object_id($4, (char) $2); + if (m == ERR) { + lc_error("Unknown object ('%c', \"%s\")!", $2, $4); + $$ = -1; + } else + $$ = SP_OBJ_PACK(m, $2); + } + | RANDOM_TYPE + { + $$ = -1; + } + ; + + +string_expr : string_or_var { } + | string_expr '.' string_or_var + { + add_opvars(splev, "o", SPO_MATH_ADD); + } + ; + +math_expr_var : INTEGER { add_opvars(splev, "i", $1 ); } + | dice { is_inconstant_number = 1; } + | '(' MINUS_INTEGER ')' { add_opvars(splev, "i", $2 ); } + | VARSTRING_INT + { + check_vardef_type(variable_definitions, $1, SPOVAR_INT); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + is_inconstant_number = 1; + } + | VARSTRING_INT_ARRAY '[' math_expr_var ']' + { + check_vardef_type(variable_definitions, $1, SPOVAR_INT|SPOVAR_ARRAY); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + is_inconstant_number = 1; + } + | math_expr_var '+' math_expr_var { add_opvars(splev, "o", SPO_MATH_ADD); } + | math_expr_var '-' math_expr_var { add_opvars(splev, "o", SPO_MATH_SUB); } + | math_expr_var '*' math_expr_var { add_opvars(splev, "o", SPO_MATH_MUL); } + | math_expr_var '/' math_expr_var { add_opvars(splev, "o", SPO_MATH_DIV); } + | math_expr_var '%' math_expr_var { add_opvars(splev, "o", SPO_MATH_MOD); } + | '(' math_expr_var ')' { } + ; + +func_param_type : CFUNC_INT + { + if (!strcmp("int", $1) || !strcmp("integer", $1)) { + $$ = (int)'i'; + } else lc_error("Unknown function parameter type '%s'", $1); + } + | CFUNC_STR + { + if (!strcmp("str", $1) || !strcmp("string", $1)) { + $$ = (int)'s'; + } else lc_error("Unknown function parameter type '%s'", $1); + } + ; + +func_param_part : any_var_or_arr ':' func_param_type + { + struct lc_funcdefs_parm *tmp = New(struct lc_funcdefs_parm); + + if (!curr_function) + lc_error("Function parameters outside function definition."); + else if (!tmp) + lc_error("Could not alloc function params."); + else { + tmp->name = strdup($1); + tmp->parmtype = (char) $3; + tmp->next = curr_function->params; + curr_function->params = tmp; + curr_function->n_params++; + { + long vt; + switch (tmp->parmtype) { + case 'i': vt = SPOVAR_INT; break; + case 's': vt = SPOVAR_STRING; break; + default: lc_error("Unknown func param conversion."); break; + } + variable_definitions = add_vardef_type(variable_definitions, $1, vt); + } + } + Free($1); + } + ; + + +func_param_list : func_param_part + | func_param_list ',' func_param_part + ; + +func_params_list : /* nothing */ + | func_param_list + ; + +func_call_param_part : math_expr_var + { + $$ = (int)'i'; + } + | string_expr + { + $$ = (int)'s'; + } + ; + + +func_call_param_list : func_call_param_part + { + char tmpbuf[2]; + tmpbuf[0] = (char) $1; + tmpbuf[1] = '\0'; + $$ = strdup(tmpbuf); + } + | func_call_param_list ',' func_call_param_part + { + long len = strlen( $1 ); + char *tmp = (char *)alloc(len + 2); + sprintf(tmp, "%c%s", (char) $3, $1 ); + Free( $1 ); + $$ = tmp; + } + ; + +func_call_params_list : /* nothing */ + { + $$ = strdup(""); + } + | func_call_param_list + { + char *tmp = strdup( $1 ); + Free( $1 ); + $$ = tmp; + } + ; + +ter_selection_x : coord_or_var + { + add_opvars(splev, "o", SPO_SEL_POINT); + } + | rect_ID region_or_var + { + add_opvars(splev, "o", SPO_SEL_RECT); + } + | fillrect_ID region_or_var + { + add_opvars(splev, "o", SPO_SEL_FILLRECT); + } + | line_ID coord_or_var '-' coord_or_var + { + add_opvars(splev, "o", SPO_SEL_LINE); + } + | randline_ID coord_or_var '-' coord_or_var ',' math_expr_var + { + /* randline (x1,y1),(x2,y2), roughness */ + add_opvars(splev, "o", SPO_SEL_RNDLINE); + } + | grow_ID '(' ter_selection ')' + { + add_opvars(splev, "io", W_ANY, SPO_SEL_GROW); + } + | grow_ID '(' dir_list ',' ter_selection ')' + { + add_opvars(splev, "io", $3, SPO_SEL_GROW); + } + | filter_ID '(' SPERCENT ',' ter_selection ')' + { + add_opvars(splev, "iio", $3, SPOFILTER_PERCENT, SPO_SEL_FILTER); + } + | filter_ID '(' ter_selection ',' ter_selection ')' + { + add_opvars(splev, "io", SPOFILTER_SELECTION, SPO_SEL_FILTER); + } + | filter_ID '(' mapchar_or_var ',' ter_selection ')' + { + add_opvars(splev, "io", SPOFILTER_MAPCHAR, SPO_SEL_FILTER); + } + | flood_ID coord_or_var + { + add_opvars(splev, "o", SPO_SEL_FLOOD); + } + | circle_ID '(' coord_or_var ',' math_expr_var ')' + { + add_opvars(splev, "oio", SPO_COPY, 1, SPO_SEL_ELLIPSE); + } + | circle_ID '(' coord_or_var ',' math_expr_var ',' FILLING ')' + { + add_opvars(splev, "oio", SPO_COPY, $7, SPO_SEL_ELLIPSE); + } + | ellipse_ID '(' coord_or_var ',' math_expr_var ',' math_expr_var ')' + { + add_opvars(splev, "io", 1, SPO_SEL_ELLIPSE); + } + | ellipse_ID '(' coord_or_var ',' math_expr_var ',' math_expr_var ',' FILLING ')' + { + add_opvars(splev, "io", $9, SPO_SEL_ELLIPSE); + } + | gradient_ID '(' GRADIENT_TYPE ',' '(' math_expr_var '-' math_expr_var opt_limited ')' ',' coord_or_var opt_coord_or_var ')' + { + add_opvars(splev, "iio", $9, $3, SPO_SEL_GRADIENT); + } + | complement_ID ter_selection_x + { + add_opvars(splev, "o", SPO_SEL_COMPLEMENT); + } + | VARSTRING_SEL + { + check_vardef_type(variable_definitions, $1, SPOVAR_SEL); + vardef_used(variable_definitions, $1); + add_opvars(splev, "v", $1); + Free($1); + } + | '(' ter_selection ')' + { + /* nothing */ + } + ; + +ter_selection : ter_selection_x + { + /* nothing */ + } + | ter_selection_x '&' ter_selection + { + add_opvars(splev, "o", SPO_SEL_ADD); + } + ; + +dice : DICE + { + add_opvars(splev, "iio", $1.num, $1.die, SPO_DICE); + } + ; + +all_integers : MINUS_INTEGER + | PLUS_INTEGER + | INTEGER + ; + +all_ints_push : MINUS_INTEGER + { + add_opvars(splev, "i", $1 ); + } + | PLUS_INTEGER + { + add_opvars(splev, "i", $1 ); + } + | INTEGER + { + add_opvars(splev, "i", $1 ); + } + | dice + { + /* nothing */ + } + ; + +objectid : object_ID + | OBJECT_ID + ; + +monsterid : monster_ID + | MONSTER_ID + ; + +terrainid : terrain_ID + | TERRAIN_ID + ; + engraving_type : ENGRAVING_TYPE | RANDOM_TYPE ; -coord : '(' INTEGER ',' INTEGER ')' +lev_region : region { - if (!in_room && !init_lev.init_present && - ($2 < 0 || $2 > (int)max_x_map || - $4 < 0 || $4 > (int)max_y_map)) - yyerror("Coordinates out of map range!"); - current_coord.x = $2; - current_coord.y = $4; + $$ = $1; + } + | LEV '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')' + { + if ($3 <= 0 || $3 >= COLNO) + lc_error("Region (%li,%li,%li,%li) out of level range (x1)!", $3, $5, $7, $9); + else if ($5 < 0 || $5 >= ROWNO) + lc_error("Region (%li,%li,%li,%li) out of level range (y1)!", $3, $5, $7, $9); + else if ($7 <= 0 || $7 >= COLNO) + lc_error("Region (%li,%li,%li,%li) out of level range (x2)!", $3, $5, $7, $9); + else if ($9 < 0 || $9 >= ROWNO) + lc_error("Region (%li,%li,%li,%li) out of level range (y2)!", $3, $5, $7, $9); + $$.x1 = $3; + $$.y1 = $5; + $$.x2 = $7; + $$.y2 = $9; + $$.area = 1; } ; @@ -1686,20 +2500,22 @@ region : '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')' /* This series of if statements is a hack for MSC 5.1. It seems that its tiny little brain cannot compile if these are all one big if statement. */ if ($2 < 0 || $2 > (int)max_x_map) - yyerror("Region out of map range!"); + lc_error("Region (%li,%li,%li,%li) out of map range (x1)!", $2, $4, $6, $8); else if ($4 < 0 || $4 > (int)max_y_map) - yyerror("Region out of map range!"); + lc_error("Region (%li,%li,%li,%li) out of map range (y1)!", $2, $4, $6, $8); else if ($6 < 0 || $6 > (int)max_x_map) - yyerror("Region out of map range!"); + lc_error("Region (%li,%li,%li,%li) out of map range (x2)!", $2, $4, $6, $8); else if ($8 < 0 || $8 > (int)max_y_map) - yyerror("Region out of map range!"); - current_region.x1 = $2; - current_region.y1 = $4; - current_region.x2 = $6; - current_region.y2 = $8; + lc_error("Region (%li,%li,%li,%li) out of map range (y2)!", $2, $4, $6, $8); + $$.area = 0; + $$.x1 = $2; + $$.y1 = $4; + $$.x2 = $6; + $$.y2 = $8; } ; + %% /*lev_comp.y*/ diff --git a/util/lev_main.c b/util/lev_main.c index fa539f5e2..2268c9fc3 100644 --- a/util/lev_main.c +++ b/util/lev_main.c @@ -11,12 +11,15 @@ #define SPEC_LEV /* for MPW */ /* although, why don't we move those special defines here.. and in dgn_main? */ +#include + #include "hack.h" #include "date.h" #include "sp_lev.h" #ifdef STRICT_REF_DEF #include "tcap.h" #endif +#include #ifdef MAC # if defined(__SC__) || defined(__MRC__) @@ -90,26 +93,34 @@ int FDECL(get_object_id, (char *,CHAR_P)); boolean FDECL(check_monster_char, (CHAR_P)); boolean FDECL(check_object_char, (CHAR_P)); char FDECL(what_map_char, (CHAR_P)); -void FDECL(scan_map, (char *)); -void NDECL(wallify_map); +void FDECL(scan_map, (char *, sp_lev *)); boolean NDECL(check_subrooms); -void FDECL(check_coord, (int,int,const char *)); -void NDECL(store_part); -void NDECL(store_room); -boolean FDECL(write_level_file, (char *,splev *,specialmaze *)); -void FDECL(free_rooms, (splev *)); +boolean FDECL(write_level_file, (char *,sp_lev *)); + +struct lc_funcdefs *FDECL(funcdef_new,(long,char *)); +void FDECL(funcdef_free_all,(struct lc_funcdefs *)); +struct lc_funcdefs *FDECL(funcdef_defined,(struct lc_funcdefs *,char *, int)); + +struct lc_vardefs *FDECL(vardef_new,(long,char *)); +void FDECL(vardef_free_all,(struct lc_vardefs *)); +struct lc_vardefs *FDECL(vardef_defined,(struct lc_vardefs *,char *, int)); + +void FDECL(splev_add_from, (sp_lev *, sp_lev *)); extern void NDECL(monst_init); extern void NDECL(objects_init); extern void NDECL(decl_init); -static boolean FDECL(write_common_data, (int,int,lev_init *,long)); -static boolean FDECL(write_monsters, (int,char *,monster ***)); -static boolean FDECL(write_objects, (int,char *,object ***)); -static boolean FDECL(write_engravings, (int,char *,engraving ***)); -static boolean FDECL(write_maze, (int,specialmaze *)); -static boolean FDECL(write_rooms, (int,splev *)); +void FDECL(add_opcode, (sp_lev *, int, genericptr_t)); + +static boolean FDECL(write_common_data, (int,sp_lev *)); +static boolean FDECL(write_maze, (int,sp_lev *)); static void NDECL(init_obj_classes); +static int FDECL(case_insensitive_comp, (const char *, const char *)); + +void VDECL(lc_error, (const char *, ...)); +void VDECL(add_opvars, (sp_lev *, const char *, ...)); + static struct { const char *name; @@ -176,47 +187,27 @@ static struct { const char *fname = "(stdin)"; int fatal_error = 0; -int want_warnings = 0; +int got_errors = 0; +int be_verbose = 0; +int fname_counter = 1; #ifdef FLEX23_BUG /* Flex 2.3 bug work around; not needed for 2.3.6 or later */ int yy_more_len = 0; #endif -extern char tmpmessage[]; -extern altar *tmpaltar[]; -extern lad *tmplad[]; -extern stair *tmpstair[]; -extern digpos *tmpdig[]; -extern digpos *tmppass[]; -extern char *tmpmap[]; -extern region *tmpreg[]; -extern lev_region *tmplreg[]; -extern door *tmpdoor[]; -extern room_door *tmprdoor[]; -extern trap *tmptrap[]; -extern monster *tmpmonst[]; -extern object *tmpobj[]; -extern drawbridge *tmpdb[]; -extern walk *tmpwalk[]; -extern gold *tmpgold[]; -extern fountain *tmpfountain[]; -extern sink *tmpsink[]; -extern pool *tmppool[]; -extern engraving *tmpengraving[]; -extern mazepart *tmppart[]; -extern room *tmproom[]; - -extern int n_olist, n_mlist, n_plist; - -extern unsigned int nlreg, nreg, ndoor, ntrap, nmons, nobj; -extern unsigned int ndb, nwalk, npart, ndig, npass, nlad, nstair; -extern unsigned int naltar, ncorridor, nrooms, ngold, nengraving; -extern unsigned int nfountain, npool, nsink; - extern unsigned int max_x_map, max_y_map; -extern int nh_line_number, colon_line_number; +extern int nh_line_number; + +extern int token_start_pos; +extern char curr_token[512]; + +struct lc_vardefs *variable_definitions = NULL; +struct lc_funcdefs *function_definitions = NULL; + +extern int allow_break_statements; +extern struct lc_breakdef *break_list; int main(argc, argv) @@ -276,8 +267,8 @@ char **argv; } else { /* Otherwise every argument is a filename */ for(i=1; i 0) { + if (fatal_error > 0 || got_errors > 0) { errors_encountered = TRUE; fatal_error = 0; } @@ -314,8 +306,14 @@ void yyerror(s) const char *s; { - (void) fprintf(stderr, "%s: line %d : %s\n", fname, - (*s >= 'A' && *s <= 'Z') ? colon_line_number : nh_line_number, s); + char *e = ((char *)s + strlen(s) - 1); + (void) fprintf(stderr, "%s: line %d, pos %d: %s", + fname, nh_line_number, + token_start_pos-strlen(curr_token), s); + if (*e != '.' && *e != '!') + (void) fprintf(stderr, " at \"%s\"", curr_token); + (void) fprintf(stderr, "\n"); + if (++fatal_error > MAX_ERRORS) { (void) fprintf(stderr,"Too many errors, good bye!\n"); exit(EXIT_FAILURE); @@ -330,7 +328,7 @@ yywarning(s) const char *s; { (void) fprintf(stderr, "%s: line %d : WARNING : %s\n", - fname, colon_line_number, s); + fname, nh_line_number, s); } /* @@ -342,6 +340,586 @@ yywrap() return 1; } +void +lc_error(const char *fmt, ...) +{ + char buf[512]; + va_list argp; + + va_start(argp, fmt); + (void) vsnprintf(buf, 511, fmt, argp); + va_end(argp); + + yyerror(buf); +} + +void +lc_warning(const char *fmt, ...) +{ + char buf[512]; + va_list argp; + + va_start(argp, fmt); + (void) vsnprintf(buf, 511, fmt, argp); + va_end(argp); + + yywarning(buf); +} + + +char * +decode_parm_chr(chr) +char chr; +{ + static char buf[32]; + switch (chr) { + default: sprintf(buf, "unknown"); break; + case 'i': sprintf(buf, "int"); break; + case 'r': sprintf(buf, "region"); break; + case 's': sprintf(buf, "str"); break; + case 'O': sprintf(buf, "obj"); break; + case 'c': sprintf(buf, "coord"); break; + case ' ': sprintf(buf, "nothing"); break; + case 'm': sprintf(buf, "mapchar"); break; + case 'M': sprintf(buf, "monster"); break; + } + return buf; +} + +char * +decode_parm_str(str) +char *str; +{ + static char tmpbuf[1024]; + char *p = str; + tmpbuf[0] = '\0'; + if (str) { + for ( ; *p; p++) { + Strcat(tmpbuf, decode_parm_chr(*p)); + if (*(p + 1)) Strcat(tmpbuf, ", "); + } + } + return tmpbuf; +} + + +struct opvar * +set_opvar_int(ov, val) +struct opvar *ov; +long val; +{ + if (ov) { + ov->spovartyp = SPOVAR_INT; + ov->vardata.l = val; + } + return ov; +} + +struct opvar * +set_opvar_coord(ov, val) +struct opvar *ov; +long val; +{ + if (ov) { + ov->spovartyp = SPOVAR_COORD; + ov->vardata.l = val; + } + return ov; +} + +struct opvar * +set_opvar_region(ov, val) +struct opvar *ov; +long val; +{ + if (ov) { + ov->spovartyp = SPOVAR_REGION; + ov->vardata.l = val; + } + return ov; +} + +struct opvar * +set_opvar_mapchar(ov, val) +struct opvar *ov; +long val; +{ + if (ov) { + ov->spovartyp = SPOVAR_MAPCHAR; + ov->vardata.l = val; + } + return ov; +} + +struct opvar * +set_opvar_monst(ov, val) +struct opvar *ov; +long val; +{ + if (ov) { + ov->spovartyp = SPOVAR_MONST; + ov->vardata.l = val; + } + return ov; +} + +struct opvar * +set_opvar_obj(ov, val) +struct opvar *ov; +long val; +{ + if (ov) { + ov->spovartyp = SPOVAR_OBJ; + ov->vardata.l = val; + } + return ov; +} + +struct opvar * +set_opvar_str(ov, val) +struct opvar *ov; +char *val; +{ + if (ov) { + ov->spovartyp = SPOVAR_STRING; + ov->vardata.str = (val) ? strdup(val) : NULL; + } + return ov; +} + +struct opvar * +set_opvar_var(ov, val) +struct opvar *ov; +char *val; +{ + if (ov) { + ov->spovartyp = SPOVAR_VARIABLE; + ov->vardata.str = (val) ? strdup(val) : NULL; + } + return ov; +} + +#define New(type) \ + (type *) memset((genericptr_t)alloc(sizeof(type)), 0, sizeof(type)) + +void +add_opvars(sp_lev *sp, const char *fmt, ...) +{ + const char *p; + va_list argp; + + va_start(argp, fmt); + + for(p = fmt; *p != '\0'; p++) { + switch(*p) { + case ' ': break; + case 'i': /* integer */ + { + struct opvar *ov = New(struct opvar); + set_opvar_int(ov, va_arg(argp, long)); + add_opcode(sp, SPO_PUSH, ov); + break; + } + case 'c': /* coordinate */ + { + struct opvar *ov = New(struct opvar); + set_opvar_coord(ov, va_arg(argp, long)); + add_opcode(sp, SPO_PUSH, ov); + break; + } + case 'r': /* region */ + { + struct opvar *ov = New(struct opvar); + set_opvar_region(ov, va_arg(argp, long)); + add_opcode(sp, SPO_PUSH, ov); + break; + } + case 'm': /* mapchar */ + { + struct opvar *ov = New(struct opvar); + set_opvar_mapchar(ov, va_arg(argp, long)); + add_opcode(sp, SPO_PUSH, ov); + break; + } + case 'M': /* monster */ + { + struct opvar *ov = New(struct opvar); + set_opvar_monst(ov, va_arg(argp, long)); + add_opcode(sp, SPO_PUSH, ov); + break; + } + case 'O': /* object */ + { + struct opvar *ov = New(struct opvar); + set_opvar_obj(ov, va_arg(argp, long)); + add_opcode(sp, SPO_PUSH, ov); + break; + } + case 's': /* string */ + { + struct opvar *ov = New(struct opvar); + set_opvar_str(ov, va_arg(argp, char *)); + add_opcode(sp, SPO_PUSH, ov); + break; + } + case 'v': /* variable */ + { + struct opvar *ov = New(struct opvar); + set_opvar_var(ov, va_arg(argp, char *)); + add_opcode(sp, SPO_PUSH, ov); + break; + } + case 'o': /* opcode */ + { + long i = va_arg(argp, int); + if (i < 0 || i >= MAX_SP_OPCODES) + fprintf(stderr, "add_opvars: unknown opcode '%li'.\n", i); + add_opcode(sp, i, NULL); + break; + } + default: + fprintf(stderr, "add_opvars: illegal format character '%c'.\n", *p); + break; + } + } + + va_end(argp); +} + +void +break_stmt_start() +{ + allow_break_statements++; +} + +void +break_stmt_end(splev) + sp_lev *splev; +{ + struct lc_breakdef *tmp = break_list; + struct lc_breakdef *prv = NULL; + while (tmp) { + if (tmp->break_depth == allow_break_statements) { + struct lc_breakdef *nxt = tmp->next; + set_opvar_int(tmp->breakpoint, splev->n_opcodes - tmp->breakpoint->vardata.l-1); + tmp->next = NULL; + Free(tmp); + if (!prv) break_list = NULL; + else prv->next = nxt; + tmp = nxt; + } else { + prv = tmp; + tmp = tmp->next; + } + } + allow_break_statements--; +} + +void +break_stmt_new(splev,i) + sp_lev *splev; + long i; +{ + struct lc_breakdef *tmp = New(struct lc_breakdef); + tmp->breakpoint = New(struct opvar); + tmp->break_depth = allow_break_statements; + tmp->next = break_list; + break_list = tmp; + set_opvar_int(tmp->breakpoint, i); + add_opcode(splev, SPO_PUSH, tmp->breakpoint); + add_opcode(splev, SPO_JMP, NULL); +} + +struct lc_funcdefs * +funcdef_new(addr, name) + long addr; + char *name; +{ + struct lc_funcdefs *f = New(struct lc_funcdefs); + if (!f) { + lc_error("Could not alloc function definition for '%s'.", name); + return NULL; + } + f->next = NULL; + f->addr = addr; + f->name = strdup(name); + f->n_called = 0; + f->n_params = 0; + f->params = NULL; + f->code.opcodes = NULL; + f->code.n_opcodes = 0; + return f; +} + +void +funcdef_free_all(fchain) + struct lc_funcdefs *fchain; +{ + struct lc_funcdefs *tmp = fchain; + struct lc_funcdefs *nxt; + struct lc_funcdefs_parm *tmpparam; + while (tmp) { + nxt = tmp->next; + Free(tmp->name); + while (tmp->params) { + tmpparam = tmp->params->next; + Free(tmp->params->name); + tmp->params = tmpparam; + } + /* FIXME: free tmp->code */ + Free(tmp); + tmp = nxt; + } +} + + +char * +funcdef_paramtypes(f) + struct lc_funcdefs *f; +{ + int i = 0; + struct lc_funcdefs_parm *fp = f->params; + char *tmp = (char *)alloc((f->n_params) + 1); + if (!tmp) return NULL; + while (fp) { + tmp[i++] = fp->parmtype; + fp = fp->next; + } + tmp[i] = '\0'; + return tmp; +} + +struct lc_funcdefs * +funcdef_defined(f, name, casesense) + struct lc_funcdefs *f; + char *name; + int casesense; +{ + while (f) { + if (casesense) { + if (!strcmp(name, f->name)) return f; + } else { + if (!case_insensitive_comp(name, f->name)) return f; + } + f = f->next; + } + return NULL; +} + + +struct lc_vardefs * +vardef_new(typ, name) + long typ; + char *name; +{ + struct lc_vardefs *f = New(struct lc_vardefs); + if (!f) { + lc_error("Could not alloc variable definition for '%s'.", name); + return NULL; + } + f->next = NULL; + f->var_type = typ; + f->name = strdup(name); + f->n_used = 0; + return f; +} + +void +vardef_free_all(fchain) + struct lc_vardefs *fchain; +{ + struct lc_vardefs *tmp = fchain; + struct lc_vardefs *nxt; + while (tmp) { + if (be_verbose && (tmp->n_used == 0)) + lc_warning("Unused variable '%s'", tmp->name); + nxt = tmp->next; + Free(tmp->name); + Free(tmp); + tmp = nxt; + } +} + +struct lc_vardefs * +vardef_defined(f, name, casesense) + struct lc_vardefs *f; + char *name; + int casesense; +{ + while (f) { + if (casesense) { + if (!strcmp(name, f->name)) return f; + } else { + if (!case_insensitive_comp(name, f->name)) return f; + } + f = f->next; + } + return NULL; +} + +const char * +spovar2str(spovar) + long spovar; +{ + static int togl = 0; + static char buf[2][128]; + char *n = NULL; + int is_array = (spovar & SPOVAR_ARRAY); + spovar &= ~SPOVAR_ARRAY; + + switch (spovar) { + default: lc_error("spovar2str(%li)", spovar); break; + case SPOVAR_INT: n = "integer"; break; + case SPOVAR_STRING: n = "string"; break; + case SPOVAR_VARIABLE: n = "variable"; break; + case SPOVAR_COORD: n = "coordinate"; break; + case SPOVAR_REGION: n = "region"; break; + case SPOVAR_MAPCHAR: n = "mapchar"; break; + case SPOVAR_MONST: n = "monster"; break; + case SPOVAR_OBJ: n = "object"; break; + } + + togl = ((togl + 1) % 2); + + snprintf(buf[togl], 127, "%s%s", n, (is_array ? " array" : "")); + return buf[togl]; +} + +void +vardef_used(vd, varname) + struct lc_vardefs *vd; + char *varname; +{ + struct lc_vardefs *tmp; + if ((tmp = vardef_defined(vd, varname, 1))) tmp->n_used++; +} + +void +check_vardef_type(vd, varname, vartype) + struct lc_vardefs *vd; + char *varname; + long vartype; +{ + struct lc_vardefs *tmp; + if ((tmp = vardef_defined(vd, varname, 1))) { + if (tmp->var_type != vartype) + lc_error("Trying to use variable '%s' as %s, when it is %s.", + varname, spovar2str(vartype), spovar2str(tmp->var_type)); + } else lc_error("Variable '%s' not defined.", varname); +} + +struct lc_vardefs * +add_vardef_type(vd, varname, vartype) + struct lc_vardefs *vd; + char *varname; + long vartype; +{ + struct lc_vardefs *tmp; + if ((tmp = vardef_defined(vd, varname, 1))) { + if (tmp->var_type != vartype) + lc_error("Trying to redefine variable '%s' as %s, when it is %s.", + varname, spovar2str(vartype), spovar2str(tmp->var_type)); + } else { + tmp = vardef_new(vartype, varname); + tmp->next = vd; + return tmp; + } + return vd; +} + +int +reverse_jmp_opcode(opcode) + int opcode; +{ + switch (opcode) { + case SPO_JE: return SPO_JNE; + case SPO_JNE: return SPO_JE; + case SPO_JL: return SPO_JGE; + case SPO_JG: return SPO_JLE; + case SPO_JLE: return SPO_JG; + case SPO_JGE: return SPO_JL; + default: lc_error("Cannot reverse comparison jmp opcode %i.", opcode); return SPO_NULL; + } +} + +/* basically copied from src/sp_lev.c */ +struct opvar * +opvar_clone(ov) + struct opvar *ov; +{ + if (ov) { + struct opvar *tmpov = (struct opvar *)alloc(sizeof(struct opvar)); + if (!tmpov) panic("could not alloc opvar struct"); + switch (ov->spovartyp) { + case SPOVAR_COORD: + case SPOVAR_REGION: + case SPOVAR_MAPCHAR: + case SPOVAR_MONST: + case SPOVAR_OBJ: + case SPOVAR_INT: + { + tmpov->spovartyp = ov->spovartyp; + tmpov->vardata.l = ov->vardata.l; + } + break; + case SPOVAR_VARIABLE: + case SPOVAR_STRING: + { + int len = strlen(ov->vardata.str); + tmpov->spovartyp = ov->spovartyp; + tmpov->vardata.str = (char *)alloc(len+1); + (void)memcpy((genericptr_t)tmpov->vardata.str, + (genericptr_t)ov->vardata.str, len); + tmpov->vardata.str[len] = '\0'; + } + break; + default: + { + lc_error("Unknown opvar_clone value type (%i)!", ov->spovartyp); + } + } + return tmpov; + } + return NULL; +} + + +void +splev_add_from(splev, from_splev) + sp_lev *splev; + sp_lev *from_splev; +{ + int i; + if (splev && from_splev) + for (i = 0; i < from_splev->n_opcodes; i++) + add_opcode(splev, from_splev->opcodes[i].opcode, opvar_clone(from_splev->opcodes[i].opdat)); +} + + +void +start_level_def(splev, fname) +sp_lev **splev; +char *fname; +{ + struct lc_funcdefs *f; + if (index(fname, '.')) + lc_error("Invalid dot ('.') in level name '%s'.", fname); + if ((int) strlen(fname) > 14) + lc_error("Level names limited to 14 characters ('%s').", fname); + f = function_definitions; + while (f) { + f->n_called = 0; + f = f->next; + } + *splev = (sp_lev *)alloc(sizeof(sp_lev)); + (*splev)->n_opcodes = 0; + (*splev)->opcodes = NULL; + + vardef_free_all(variable_definitions); + variable_definitions = NULL; +} + + /* * Find the type of floor, knowing its char representation. */ @@ -409,6 +987,14 @@ char c; for (i = LOW_PM; i < NUMMONS; i++) if (!class || class == mons[i].mlet) if (!strcmp(s, mons[i].mname)) return i; + /* didn't find it; lets try case insensitive search */ + for (i = LOW_PM; i < NUMMONS; i++) + if (!class || class == mons[i].mlet) + if (!case_insensitive_comp(s, mons[i].mname)) { + if (be_verbose) + lc_warning("Monster type \"%s\" matches \"%s\".", s, mons[i].mname); + return i; + } return ERR; } @@ -433,6 +1019,15 @@ char c; /* class */ if (objname && !strcmp(s, objname)) return i; } + for (i = class ? bases[class] : 0; i < NUM_OBJECTS; i++) { + if (class && objects[i].oc_class != class) break; + objname = obj_descr[i].oc_name; + if (objname && !case_insensitive_comp(s, objname)) { + if (be_verbose) + lc_warning("Object type \"%s\" matches \"%s\".", s, objname); + return i; + } + } return ERR; } @@ -506,19 +1101,50 @@ char c; return(INVALID_TYPE); } +void +add_opcode(sp, opc, dat) +sp_lev *sp; +int opc; +genericptr_t dat; +{ + long nop = sp->n_opcodes; + _opcode *tmp; + + if ((opc < 0) || (opc >= MAX_SP_OPCODES)) + lc_error("Unknown opcode '%i'", opc); + + tmp = (_opcode *)alloc(sizeof(_opcode)*(nop+1)); + if (sp->opcodes && nop) { + (void) memcpy(tmp, sp->opcodes, sizeof(_opcode)*nop); + free(sp->opcodes); + } else if (!tmp) + lc_error("Could not alloc opcode space"); + + sp->opcodes = tmp; + + sp->opcodes[nop].opcode = opc; + sp->opcodes[nop].opdat = dat; + + sp->n_opcodes++; +} + + /* * Yep! LEX gives us the map in a raw mode. * Just analyze it here. */ void -scan_map(map) +scan_map(map, sp) char *map; +sp_lev *sp; { register int i, len; register char *s1, *s2; int max_len = 0; int max_hig = 0; - char msg[256]; + char *tmpmap[ROWNO]; + int dx,dy; + char *mbuf; /* First, strip out digits 0-9 (line numbering) */ for (s1 = s2 = map; *s1; s1++) @@ -553,10 +1179,7 @@ char *map; } for(i=0; i MAP_X_LIM || max_hig > MAP_Y_LIM) { - Sprintf(msg, "Map too large! (max %d x %d)", MAP_X_LIM, MAP_Y_LIM); - yyerror(msg); + lc_error("Map too large at (%d x %d), max is (%d x %d)", max_len, max_hig, MAP_X_LIM, MAP_Y_LIM); } - tmppart[npart]->xsize = max_len; - tmppart[npart]->ysize = max_hig; - tmppart[npart]->map = (char **) alloc(max_hig*sizeof(char *)); - for(i = 0; i< max_hig; i++) - tmppart[npart]->map[i] = tmpmap[i]; + mbuf = (char *) alloc(((max_hig-1) * max_len) + (max_len-1) + 2); + for (dy = 0; dy < max_hig; dy++) + for (dx = 0; dx < max_len; dx++) + mbuf[(dy * max_len) + dx] = (tmpmap[dy][dx] + 1); + + mbuf[((max_hig-1) * max_len) + (max_len-1) + 1] = '\0'; + + add_opvars(sp, "siio", mbuf, max_hig, max_len, SPO_MAP); + + for (dy = 0; dy < max_hig; dy++) + Free(tmpmap[dy]); + Free(mbuf); } -/* - * If we have drawn a map without walls, this allows us to - * auto-magically wallify it. - */ -#define Map_point(x,y) *(tmppart[npart]->map[y] + x) -void -wallify_map() -{ - unsigned int x, y, xx, yy, lo_xx, lo_yy, hi_xx, hi_yy; - for (y = 0; y <= max_y_map; y++) { - SpinCursor(3); - lo_yy = (y > 0) ? y - 1 : 0; - hi_yy = (y < max_y_map) ? y + 1 : max_y_map; - for (x = 0; x <= max_x_map; x++) { - if (Map_point(x,y) != STONE) continue; - lo_xx = (x > 0) ? x - 1 : 0; - hi_xx = (x < max_x_map) ? x + 1 : max_x_map; - for (yy = lo_yy; yy <= hi_yy; yy++) - for (xx = lo_xx; xx <= hi_xx; xx++) - if (IS_ROOM(Map_point(xx,yy)) || - Map_point(xx,yy) == CROSSWALL) { - Map_point(x,y) = (yy != y) ? HWALL : VWALL; - yy = hi_yy; /* end `yy' loop */ - break; /* end `xx' loop */ - } - } - } -} - -/* - * We need to check the subrooms apartenance to an existing room. - */ -boolean -check_subrooms() -{ - unsigned i, j, n_subrooms; - boolean found, ok = TRUE; - char *last_parent, msg[256]; - - for (i = 0; i < nrooms; i++) - if (tmproom[i]->parent) { - found = FALSE; - for(j = 0; j < nrooms; j++) - if (tmproom[j]->name && - !strcmp(tmproom[i]->parent, tmproom[j]->name)) { - found = TRUE; - break; - } - if (!found) { - Sprintf(msg, - "Subroom error : parent room '%s' not found!", - tmproom[i]->parent); - yyerror(msg); - ok = FALSE; - } - } - - msg[0] = '\0'; - last_parent = msg; - for (i = 0; i < nrooms; i++) - if (tmproom[i]->parent) { - n_subrooms = 0; - for(j = i; j < nrooms; j++) { -/* - * This is by no means perfect, but should cut down the duplicate error - * messages by over 90%. The only problem will be when either subrooms - * are mixed in the level definition (not likely but possible) or rooms - * have subrooms that have subrooms. - */ - if (!strcmp(tmproom[i]->parent, last_parent)) continue; - if (tmproom[j]->parent && - !strcmp(tmproom[i]->parent, tmproom[j]->parent)) { - n_subrooms++; - if(n_subrooms > MAX_SUBROOMS) { - - Sprintf(msg, - "Subroom error: too many subrooms attached to parent room '%s'!", - tmproom[i]->parent); - yyerror(msg); - last_parent = tmproom[i]->parent; - ok = FALSE; - break; - } - } - } - } - return ok; -} - -/* - * Check that coordinates (x,y) are roomlike locations. - * Print warning "str" if they aren't. - */ -void -check_coord(x, y, str) -int x, y; -const char *str; -{ - char ebuf[60]; - - if (x >= 0 && y >= 0 && x <= (int)max_x_map && y <= (int)max_y_map && - (IS_ROCK(tmpmap[y][x]) || IS_DOOR(tmpmap[y][x]))) { - Sprintf(ebuf, "%s placed in wall at (%02d,%02d)?!", str, x, y); - yywarning(ebuf); - } -} - -/* - * Here we want to store the maze part we just got. - */ -void -store_part() -{ - register unsigned i; - - /* Ok, We got the whole part, now we store it. */ - - /* The Regions */ - - if ((tmppart[npart]->nreg = nreg) != 0) { - tmppart[npart]->regions = NewTab(region, nreg); - for(i=0;iregions[i] = tmpreg[i]; - } - nreg = 0; - - /* The Level Regions */ - - if ((tmppart[npart]->nlreg = nlreg) != 0) { - tmppart[npart]->lregions = NewTab(lev_region, nlreg); - for(i=0;ilregions[i] = tmplreg[i]; - } - nlreg = 0; - - /* the doors */ - - if ((tmppart[npart]->ndoor = ndoor) != 0) { - tmppart[npart]->doors = NewTab(door, ndoor); - for(i=0;idoors[i] = tmpdoor[i]; - } - ndoor = 0; - - /* the drawbridges */ - - if ((tmppart[npart]->ndrawbridge = ndb) != 0) { - tmppart[npart]->drawbridges = NewTab(drawbridge, ndb); - for(i=0;idrawbridges[i] = tmpdb[i]; - } - ndb = 0; - - /* The walkmaze directives */ - - if ((tmppart[npart]->nwalk = nwalk) != 0) { - tmppart[npart]->walks = NewTab(walk, nwalk); - for(i=0;iwalks[i] = tmpwalk[i]; - } - nwalk = 0; - - /* The non_diggable directives */ - - if ((tmppart[npart]->ndig = ndig) != 0) { - tmppart[npart]->digs = NewTab(digpos, ndig); - for(i=0;idigs[i] = tmpdig[i]; - } - ndig = 0; - - /* The non_passwall directives */ - - if ((tmppart[npart]->npass = npass) != 0) { - tmppart[npart]->passs = NewTab(digpos, npass); - for(i=0;ipasss[i] = tmppass[i]; - } - npass = 0; - - /* The ladders */ - - if ((tmppart[npart]->nlad = nlad) != 0) { - tmppart[npart]->lads = NewTab(lad, nlad); - for(i=0;ilads[i] = tmplad[i]; - } - nlad = 0; - - /* The stairs */ - - if ((tmppart[npart]->nstair = nstair) != 0) { - tmppart[npart]->stairs = NewTab(stair, nstair); - for(i=0;istairs[i] = tmpstair[i]; - } - nstair = 0; - - /* The altars */ - if ((tmppart[npart]->naltar = naltar) != 0) { - tmppart[npart]->altars = NewTab(altar, naltar); - for(i=0;ialtars[i] = tmpaltar[i]; - } - naltar = 0; - - /* The fountains */ - - if ((tmppart[npart]->nfountain = nfountain) != 0) { - tmppart[npart]->fountains = NewTab(fountain, nfountain); - for(i=0;ifountains[i] = tmpfountain[i]; - } - nfountain = 0; - - /* the traps */ - - if ((tmppart[npart]->ntrap = ntrap) != 0) { - tmppart[npart]->traps = NewTab(trap, ntrap); - for(i=0;itraps[i] = tmptrap[i]; - } - ntrap = 0; - - /* the monsters */ - - if ((tmppart[npart]->nmonster = nmons) != 0) { - tmppart[npart]->monsters = NewTab(monster, nmons); - for(i=0;imonsters[i] = tmpmonst[i]; - } else - tmppart[npart]->monsters = 0; - nmons = 0; - - /* the objects */ - - if ((tmppart[npart]->nobject = nobj) != 0) { - tmppart[npart]->objects = NewTab(object, nobj); - for(i=0;iobjects[i] = tmpobj[i]; - } else - tmppart[npart]->objects = 0; - nobj = 0; - - /* The gold piles */ - - if ((tmppart[npart]->ngold = ngold) != 0) { - tmppart[npart]->golds = NewTab(gold, ngold); - for(i=0;igolds[i] = tmpgold[i]; - } - ngold = 0; - - /* The engravings */ - - if ((tmppart[npart]->nengraving = nengraving) != 0) { - tmppart[npart]->engravings = NewTab(engraving, nengraving); - for(i=0;iengravings[i] = tmpengraving[i]; - } else - tmppart[npart]->engravings = 0; - nengraving = 0; - - npart++; - n_plist = n_mlist = n_olist = 0; -} - -/* - * Here we want to store the room part we just got. - */ -void -store_room() -{ - register unsigned i; - - /* Ok, We got the whole room, now we store it. */ - - /* the doors */ - - if ((tmproom[nrooms]->ndoor = ndoor) != 0) { - tmproom[nrooms]->doors = NewTab(room_door, ndoor); - for(i=0;idoors[i] = tmprdoor[i]; - } - ndoor = 0; - - /* The stairs */ - - if ((tmproom[nrooms]->nstair = nstair) != 0) { - tmproom[nrooms]->stairs = NewTab(stair, nstair); - for(i=0;istairs[i] = tmpstair[i]; - } - nstair = 0; - - /* The altars */ - if ((tmproom[nrooms]->naltar = naltar) != 0) { - tmproom[nrooms]->altars = NewTab(altar, naltar); - for(i=0;ialtars[i] = tmpaltar[i]; - } - naltar = 0; - - /* The fountains */ - - if ((tmproom[nrooms]->nfountain = nfountain) != 0) { - tmproom[nrooms]->fountains = NewTab(fountain, nfountain); - for(i=0;ifountains[i] = tmpfountain[i]; - } - nfountain = 0; - - /* The sinks */ - - if ((tmproom[nrooms]->nsink = nsink) != 0) { - tmproom[nrooms]->sinks = NewTab(sink, nsink); - for(i=0;isinks[i] = tmpsink[i]; - } - nsink = 0; - - /* The pools */ - - if ((tmproom[nrooms]->npool = npool) != 0) { - tmproom[nrooms]->pools = NewTab(pool, npool); - for(i=0;ipools[i] = tmppool[i]; - } - npool = 0; - - /* the traps */ - - if ((tmproom[nrooms]->ntrap = ntrap) != 0) { - tmproom[nrooms]->traps = NewTab(trap, ntrap); - for(i=0;itraps[i] = tmptrap[i]; - } - ntrap = 0; - - /* the monsters */ - - if ((tmproom[nrooms]->nmonster = nmons) != 0) { - tmproom[nrooms]->monsters = NewTab(monster, nmons); - for(i=0;imonsters[i] = tmpmonst[i]; - } else - tmproom[nrooms]->monsters = 0; - nmons = 0; - - /* the objects */ - - if ((tmproom[nrooms]->nobject = nobj) != 0) { - tmproom[nrooms]->objects = NewTab(object, nobj); - for(i=0;iobjects[i] = tmpobj[i]; - } else - tmproom[nrooms]->objects = 0; - nobj = 0; - - /* The gold piles */ - - if ((tmproom[nrooms]->ngold = ngold) != 0) { - tmproom[nrooms]->golds = NewTab(gold, ngold); - for(i=0;igolds[i] = tmpgold[i]; - } - ngold = 0; - - /* The engravings */ - - if ((tmproom[nrooms]->nengraving = nengraving) != 0) { - tmproom[nrooms]->engravings = NewTab(engraving, nengraving); - for(i=0;iengravings[i] = tmpengraving[i]; - } else - tmproom[nrooms]->engravings = 0; - nengraving = 0; - - nrooms++; -} /* * Output some info common to all special levels. */ static boolean -write_common_data(fd, typ, init, flgs) -int fd, typ; -lev_init *init; -long flgs; +write_common_data(fd, lvl) +int fd; +sp_lev *lvl; { - char c; - uchar len; static struct version_info version_data = { VERSION_NUMBER, VERSION_FEATURES, VERSION_SANITY1, VERSION_SANITY2, VERSION_SANITY3 }; Write(fd, &version_data, sizeof version_data); - c = typ; - Write(fd, &c, sizeof(c)); /* 1 byte header */ - Write(fd, init, sizeof(lev_init)); - Write(fd, &flgs, sizeof flgs); - - len = (uchar) strlen(tmpmessage); - Write(fd, &len, sizeof len); - if (len) Write(fd, tmpmessage, (int) len); - tmpmessage[0] = '\0'; return TRUE; } /* - * Output monster info, which needs string fixups, then release memory. + * Here we write the sp_lev structure in the specified file (fd). + * Also, we have to free the memory allocated via alloc(). */ static boolean -write_monsters(fd, nmonster_p, monsters_p) +write_maze(fd, maze) int fd; -char *nmonster_p; -monster ***monsters_p; +sp_lev *maze; { - monster *m; - char *name, *appr; - int j, n = (int)*nmonster_p; + int i; + + if (!write_common_data(fd, maze)) + return FALSE; + + Write(fd, &(maze->n_opcodes), sizeof(maze->n_opcodes)); + + for (i = 0; i < maze->n_opcodes; i++) { + _opcode tmpo = maze->opcodes[i]; + + Write(fd, &(tmpo.opcode), sizeof(tmpo.opcode)); + + if (tmpo.opcode < SPO_NULL || tmpo.opcode >= MAX_SP_OPCODES) + panic("write_maze: unknown opcode (%i).", tmpo.opcode); + + if (tmpo.opcode == SPO_PUSH) { + genericptr_t opdat = tmpo.opdat; + if (opdat) { + struct opvar *ov = (struct opvar *)opdat; + int size; + Write(fd, &(ov->spovartyp), sizeof(ov->spovartyp)); + switch (ov->spovartyp) { + case SPOVAR_NULL: break; + case SPOVAR_COORD: + case SPOVAR_REGION: + case SPOVAR_MAPCHAR: + case SPOVAR_MONST: + case SPOVAR_OBJ: + case SPOVAR_INT: + Write(fd, &(ov->vardata.l), sizeof(ov->vardata.l)); + break; + case SPOVAR_VARIABLE: + case SPOVAR_STRING: + if (ov->vardata.str) + size = strlen(ov->vardata.str); + else size = 0; + Write(fd, &size, sizeof(size)); + if (size) { + Write(fd, ov->vardata.str, size); + Free(ov->vardata.str); + } + break; + default: panic("write_maze: unknown data type (%i).", ov->spovartyp); + } + } else panic("write_maze: PUSH with no data."); + } else { + /* sanity check */ + genericptr_t opdat = tmpo.opdat; + if (opdat) + panic("write_maze: opcode (%i) has data.", tmpo.opcode); + } + + Free(tmpo.opdat); - Write(fd, nmonster_p, sizeof *nmonster_p); - for (j = 0; j < n; j++) { - m = (*monsters_p)[j]; - name = m->name.str; - appr = m->appear_as.str; - m->name.str = m->appear_as.str = 0; - m->name.len = name ? strlen(name) : 0; - m->appear_as.len = appr ? strlen(appr) : 0; - Write(fd, m, sizeof *m); - if (name) { - Write(fd, name, m->name.len); - Free(name); - } - if (appr) { - Write(fd, appr, m->appear_as.len); - Free(appr); - } - Free(m); } - if (*monsters_p) { - Free(*monsters_p); - *monsters_p = 0; - } - *nmonster_p = 0; + /* clear the struct for next user */ + Free(maze->opcodes); + maze->opcodes = NULL; + /*(void) memset((genericptr_t) &maze->init_lev, 0, sizeof maze->init_lev);*/ + return TRUE; } -/* - * Output object info, which needs string fixup, then release memory. - */ -static boolean -write_objects(fd, nobject_p, objects_p) -int fd; -char *nobject_p; -object ***objects_p; -{ - object *o; - char *name; - int j, n = (int)*nobject_p; - Write(fd, nobject_p, sizeof *nobject_p); - for (j = 0; j < n; j++) { - o = (*objects_p)[j]; - name = o->name.str; - o->name.str = 0; /* reset in case `len' is narrower */ - o->name.len = name ? strlen(name) : 0; - Write(fd, o, sizeof *o); - if (name) { - Write(fd, name, o->name.len); - Free(name); - } - Free(o); - } - if (*objects_p) { - Free(*objects_p); - *objects_p = 0; - } - *nobject_p = 0; - return TRUE; -} -/* - * Output engraving info, which needs string fixup, then release memory. - */ -static boolean -write_engravings(fd, nengraving_p, engravings_p) -int fd; -char *nengraving_p; -engraving ***engravings_p; -{ - engraving *e; - char *engr; - int j, n = (int)*nengraving_p; - - Write(fd, nengraving_p, sizeof *nengraving_p); - for (j = 0; j < n; j++) { - e = (*engravings_p)[j]; - engr = e->engr.str; - e->engr.str = 0; /* reset in case `len' is narrower */ - e->engr.len = strlen(engr); - Write(fd, e, sizeof *e); - Write(fd, engr, e->engr.len); - Free(engr); - Free(e); - } - if (*engravings_p) { - Free(*engravings_p); - *engravings_p = 0; - } - *nengraving_p = 0; - return TRUE; -} /* * Open and write maze or rooms file, based on which pointer is non-null. * Return TRUE on success, FALSE on failure. */ boolean -write_level_file(filename, room_level, maze_level) +write_level_file(filename, lvl) char *filename; -splev *room_level; -specialmaze *maze_level; +sp_lev *lvl; { int fout; char lbuf[60]; @@ -1129,410 +1332,36 @@ specialmaze *maze_level; #endif if (fout < 0) return FALSE; - if (room_level) { - if (!write_rooms(fout, room_level)) - return FALSE; - } else if (maze_level) { - if (!write_maze(fout, maze_level)) - return FALSE; - } else - panic("write_level_file"); + if (!lvl) panic("write_level_file"); + + if (be_verbose) + fprintf(stdout, "File: '%s', opcodes: %li\n", lbuf, lvl->n_opcodes); + + if (!write_maze(fout, lvl)) + return FALSE; (void) close(fout); + return TRUE; } -/* - * Here we write the structure of the maze in the specified file (fd). - * Also, we have to free the memory allocated via alloc(). - */ -static boolean -write_maze(fd, maze) -int fd; -specialmaze *maze; +static int +case_insensitive_comp(s1, s2) +const char *s1; +const char *s2; { - short i,j; - mazepart *pt; + unsigned char u1, u2; - if (!write_common_data(fd, SP_LEV_MAZE, &(maze->init_lev), maze->flags)) - return FALSE; - - Write(fd, &(maze->filling), sizeof(maze->filling)); - Write(fd, &(maze->numpart), sizeof(maze->numpart)); - /* Number of parts */ - for(i=0;inumpart;i++) { - pt = maze->parts[i]; - - /* First, write the map */ - - Write(fd, &(pt->halign), sizeof(pt->halign)); - Write(fd, &(pt->valign), sizeof(pt->valign)); - Write(fd, &(pt->xsize), sizeof(pt->xsize)); - Write(fd, &(pt->ysize), sizeof(pt->ysize)); - for(j=0;jysize;j++) { - if(!maze->init_lev.init_present || - pt->xsize > 1 || pt->ysize > 1) { - Write(fd, pt->map[j], pt->xsize * sizeof *pt->map[j]); - } - Free(pt->map[j]); - } - Free(pt->map); - - /* level region stuff */ - Write(fd, &pt->nlreg, sizeof pt->nlreg); - for (j = 0; j < pt->nlreg; j++) { - lev_region *l = pt->lregions[j]; - char *rname = l->rname.str; - l->rname.str = 0; /* reset in case `len' is narrower */ - l->rname.len = rname ? strlen(rname) : 0; - Write(fd, l, sizeof *l); - if (rname) { - Write(fd, rname, l->rname.len); - Free(rname); - } - Free(l); - } - if (pt->nlreg > 0) - Free(pt->lregions); - - /* The random registers */ - Write(fd, &(pt->nrobjects), sizeof(pt->nrobjects)); - if(pt->nrobjects) { - Write(fd, pt->robjects, pt->nrobjects); - Free(pt->robjects); - } - Write(fd, &(pt->nloc), sizeof(pt->nloc)); - if(pt->nloc) { - Write(fd, pt->rloc_x, pt->nloc); - Write(fd, pt->rloc_y, pt->nloc); - Free(pt->rloc_x); - Free(pt->rloc_y); - } - Write(fd, &(pt->nrmonst), sizeof(pt->nrmonst)); - if(pt->nrmonst) { - Write(fd, pt->rmonst, pt->nrmonst); - Free(pt->rmonst); - } - - /* subrooms */ - Write(fd, &(pt->nreg), sizeof(pt->nreg)); - for(j=0;jnreg;j++) { - Write(fd, pt->regions[j], sizeof(region)); - Free(pt->regions[j]); - } - if(pt->nreg > 0) - Free(pt->regions); - - /* the doors */ - Write(fd, &(pt->ndoor), sizeof(pt->ndoor)); - for(j=0;jndoor;j++) { - Write(fd, pt->doors[j], sizeof(door)); - Free(pt->doors[j]); - } - if (pt->ndoor > 0) - Free(pt->doors); - - /* The drawbridges */ - Write(fd, &(pt->ndrawbridge), sizeof(pt->ndrawbridge)); - for(j=0;jndrawbridge;j++) { - Write(fd, pt->drawbridges[j], sizeof(drawbridge)); - Free(pt->drawbridges[j]); - } - if(pt->ndrawbridge > 0) - Free(pt->drawbridges); - - /* The mazewalk directives */ - Write(fd, &(pt->nwalk), sizeof(pt->nwalk)); - for(j=0; jnwalk; j++) { - Write(fd, pt->walks[j], sizeof(walk)); - Free(pt->walks[j]); - } - if (pt->nwalk > 0) - Free(pt->walks); - - /* The non_diggable directives */ - Write(fd, &(pt->ndig), sizeof(pt->ndig)); - for(j=0;jndig;j++) { - Write(fd, pt->digs[j], sizeof(digpos)); - Free(pt->digs[j]); - } - if (pt->ndig > 0) - Free(pt->digs); - - /* The non_passwall directives */ - Write(fd, &(pt->npass), sizeof(pt->npass)); - for(j=0;jnpass;j++) { - Write(fd, pt->passs[j], sizeof(digpos)); - Free(pt->passs[j]); - } - if (pt->npass > 0) - Free(pt->passs); - - /* The ladders */ - Write(fd, &(pt->nlad), sizeof(pt->nlad)); - for(j=0;jnlad;j++) { - Write(fd, pt->lads[j], sizeof(lad)); - Free(pt->lads[j]); - } - if (pt->nlad > 0) - Free(pt->lads); - - /* The stairs */ - Write(fd, &(pt->nstair), sizeof(pt->nstair)); - for(j=0;jnstair;j++) { - Write(fd, pt->stairs[j], sizeof(stair)); - Free(pt->stairs[j]); - } - if (pt->nstair > 0) - Free(pt->stairs); - - /* The altars */ - Write(fd, &(pt->naltar), sizeof(pt->naltar)); - for(j=0;jnaltar;j++) { - Write(fd, pt->altars[j], sizeof(altar)); - Free(pt->altars[j]); - } - if (pt->naltar > 0) - Free(pt->altars); - - /* The fountains */ - Write(fd, &(pt->nfountain), sizeof(pt->nfountain)); - for(j=0;jnfountain;j++) { - Write(fd, pt->fountains[j], sizeof(fountain)); - Free(pt->fountains[j]); - } - if (pt->nfountain > 0) - Free(pt->fountains); - - /* The traps */ - Write(fd, &(pt->ntrap), sizeof(pt->ntrap)); - for(j=0;jntrap;j++) { - Write(fd, pt->traps[j], sizeof(trap)); - Free(pt->traps[j]); - } - if (pt->ntrap) - Free(pt->traps); - - /* The monsters */ - if (!write_monsters(fd, &pt->nmonster, &pt->monsters)) - return FALSE; - - /* The objects */ - if (!write_objects(fd, &pt->nobject, &pt->objects)) - return FALSE; - - /* The gold piles */ - Write(fd, &(pt->ngold), sizeof(pt->ngold)); - for(j=0;jngold;j++) { - Write(fd, pt->golds[j], sizeof(gold)); - Free(pt->golds[j]); - } - if (pt->ngold > 0) - Free(pt->golds); - - /* The engravings */ - if (!write_engravings(fd, &pt->nengraving, &pt->engravings)) - return FALSE; - - Free(pt); + for ( ; ; s1++, s2++) { + u1 = tolower((unsigned char) *s1); + u2 = tolower((unsigned char) *s2); + if ((u1 == '\0') || (u1 != u2)) { + break; } - - Free(maze->parts); - maze->parts = (mazepart **)0; - maze->numpart = 0; - return TRUE; + } + return u1-u2; } -/* - * Here we write the structure of the room level in the specified file (fd). - */ -static boolean -write_rooms(fd, lev) -int fd; -splev *lev; -{ - short i,j, size; - room *pt; - - if (!write_common_data(fd, SP_LEV_ROOMS, &(lev->init_lev), lev->flags)) - return FALSE; - - /* Random registers */ - - Write(fd, &lev->nrobjects, sizeof(lev->nrobjects)); - if (lev->nrobjects) - Write(fd, lev->robjects, lev->nrobjects); - Write(fd, &lev->nrmonst, sizeof(lev->nrmonst)); - if (lev->nrmonst) - Write(fd, lev->rmonst, lev->nrmonst); - - Write(fd, &(lev->nroom), sizeof(lev->nroom)); - /* Number of rooms */ - for(i=0;inroom;i++) { - pt = lev->rooms[i]; - - /* Room characteristics */ - - size = (short) (pt->name ? strlen(pt->name) : 0); - Write(fd, &size, sizeof(size)); - if (size) - Write(fd, pt->name, size); - - size = (short) (pt->parent ? strlen(pt->parent) : 0); - Write(fd, &size, sizeof(size)); - if (size) - Write(fd, pt->parent, size); - - Write(fd, &(pt->x), sizeof(pt->x)); - Write(fd, &(pt->y), sizeof(pt->y)); - Write(fd, &(pt->w), sizeof(pt->w)); - Write(fd, &(pt->h), sizeof(pt->h)); - Write(fd, &(pt->xalign), sizeof(pt->xalign)); - Write(fd, &(pt->yalign), sizeof(pt->yalign)); - Write(fd, &(pt->rtype), sizeof(pt->rtype)); - Write(fd, &(pt->chance), sizeof(pt->chance)); - Write(fd, &(pt->rlit), sizeof(pt->rlit)); - Write(fd, &(pt->filled), sizeof(pt->filled)); - - /* the doors */ - Write(fd, &(pt->ndoor), sizeof(pt->ndoor)); - for(j=0;jndoor;j++) - Write(fd, pt->doors[j], sizeof(room_door)); - - /* The stairs */ - Write(fd, &(pt->nstair), sizeof(pt->nstair)); - for(j=0;jnstair;j++) - Write(fd, pt->stairs[j], sizeof(stair)); - - /* The altars */ - Write(fd, &(pt->naltar), sizeof(pt->naltar)); - for(j=0;jnaltar;j++) - Write(fd, pt->altars[j], sizeof(altar)); - - /* The fountains */ - Write(fd, &(pt->nfountain), sizeof(pt->nfountain)); - for(j=0;jnfountain;j++) - Write(fd, pt->fountains[j], sizeof(fountain)); - - /* The sinks */ - Write(fd, &(pt->nsink), sizeof(pt->nsink)); - for(j=0;jnsink;j++) - Write(fd, pt->sinks[j], sizeof(sink)); - - /* The pools */ - Write(fd, &(pt->npool), sizeof(pt->npool)); - for(j=0;jnpool;j++) - Write(fd, pt->pools[j], sizeof(pool)); - - /* The traps */ - Write(fd, &(pt->ntrap), sizeof(pt->ntrap)); - for(j=0;jntrap;j++) - Write(fd, pt->traps[j], sizeof(trap)); - - /* The monsters */ - if (!write_monsters(fd, &pt->nmonster, &pt->monsters)) - return FALSE; - - /* The objects */ - if (!write_objects(fd, &pt->nobject, &pt->objects)) - return FALSE; - - /* The gold piles */ - Write(fd, &(pt->ngold), sizeof(pt->ngold)); - for(j=0;jngold;j++) - Write(fd, pt->golds[j], sizeof(gold)); - - /* The engravings */ - if (!write_engravings(fd, &pt->nengraving, &pt->engravings)) - return FALSE; - - } - - /* The corridors */ - Write(fd, &lev->ncorr, sizeof(lev->ncorr)); - for (i=0; i < lev->ncorr; i++) - Write(fd, lev->corrs[i], sizeof(corridor)); - return TRUE; -} - -/* - * Release memory allocated to a rooms-style special level; maze-style - * levels have the fields freed as they're written; monsters, objects, and - * engravings are freed as written for both styles, so not handled here. - */ -void -free_rooms(lev) -splev *lev; -{ - room *r; - int j, n = lev->nroom; - - while(n--) { - r = lev->rooms[n]; - Free(r->name); - Free(r->parent); - if ((j = r->ndoor) != 0) { - while(j--) - Free(r->doors[j]); - Free(r->doors); - } - if ((j = r->nstair) != 0) { - while(j--) - Free(r->stairs[j]); - Free(r->stairs); - } - if ((j = r->naltar) != 0) { - while (j--) - Free(r->altars[j]); - Free(r->altars); - } - if ((j = r->nfountain) != 0) { - while(j--) - Free(r->fountains[j]); - Free(r->fountains); - } - if ((j = r->nsink) != 0) { - while(j--) - Free(r->sinks[j]); - Free(r->sinks); - } - if ((j = r->npool) != 0) { - while(j--) - Free(r->pools[j]); - Free(r->pools); - } - if ((j = r->ntrap) != 0) { - while (j--) - Free(r->traps[j]); - Free(r->traps); - } - if ((j = r->ngold) != 0) { - while(j--) - Free(r->golds[j]); - Free(r->golds); - } - Free(r); - lev->rooms[n] = (room *)0; - } - Free(lev->rooms); - lev->rooms = (room **)0; - lev->nroom = 0; - - for (j = 0; j < lev->ncorr; j++) { - Free(lev->corrs[j]); - lev->corrs[j] = (corridor *)0; - } - Free(lev->corrs); - lev->corrs = (corridor **)0; - lev->ncorr = 0; - - Free(lev->robjects); - lev->robjects = (char *)0; - lev->nrobjects = 0; - Free(lev->rmonst); - lev->rmonst = (char *)0; - lev->nrmonst = 0; -} #ifdef STRICT_REF_DEF /* @@ -1571,6 +1400,31 @@ struct window_procs windowprocs; # ifdef DEFINE_OSPEED short ospeed; # endif +# ifndef STRNCMPI +char +lowc(c) /* force 'c' into lowercase */ + char c; +{ + return((char)(('A' <= c && c <= 'Z') ? (c | 040) : c)); +} + +int +strncmpi(s1, s2, n) /* case insensitive counted string comparison */ + register const char *s1, *s2; + register int n; /*(should probably be size_t, which is usually unsigned)*/ +{ /*{ aka strncasecmp }*/ + register char t1, t2; + + while (n--) { + if (!*s2) return (*s1 != 0); /* s1 >= s2 */ + else if (!*s1) return -1; /* s1 < s2 */ + t1 = lowc(*s1++); + t2 = lowc(*s2++); + if (t1 != t2) return (t1 > t2) ? 1 : -1; + } + return 0; /* s1 == s2 */ +} +# endif /* STRNCMPI */ #endif /* STRICT_REF_DEF */ /*lev_main.c*/ diff --git a/util/makedefs.c b/util/makedefs.c index 8555178e1..7bb689bef 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1294,6 +1294,11 @@ static const char *build_opts[] = { #ifdef NEWS "news file", #endif +#ifdef MENU_COLOR_REGEX + "menu colors via regular expressions", +#else + "menu colors via pmatch", +#endif #ifdef OVERLAY # ifdef MOVERLAY "MOVE overlays", diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index b28dc3361..6ab51fae9 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 winmenu.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 winmenu.c $NHDT-Date: 1427881480 2015/04/01 09:44:40 $ $NHDT-Branch: master $:$NHDT-Revision: 1.5 $ */ /* NetHack 3.5 winmenu.c $Date: 2009/05/06 10:55:53 $ $Revision: 1.5 $ */ /* SCCS Id: @(#)winmenu.c 3.5 1996/08/15 */ /* Copyright (c) Dean Luick, 1992 */ @@ -206,6 +206,7 @@ menu_key(w, event, params, num_params) struct xwindow *wp; char ch; int count; + boolean selected_something; wp = find_widget(w); menu_info = wp->menu_information; @@ -218,6 +219,13 @@ menu_key(w, event, params, num_params) } if (menu_info->is_active) { /* waiting for input */ + /* first check for an explicit selector match, so that it won't be + overridden if it happens to duplicate a mapped menu command (':' + to look inside a container vs ':' to select via search string) */ + for (curr = menu_info->curr_menu.base; curr; curr = curr->next) + if (curr->identifier.a_void != 0 && curr->selector == ch) + goto make_selection; + ch = map_menu_cmd(ch); if (ch == '\033') { /* quit */ if (menu_info->counting) { @@ -294,7 +302,8 @@ menu_key(w, event, params, num_params) X11_nhbell(); return; } else { - boolean selected_something = FALSE; + make_selection: + selected_something = FALSE; for (count = 0, curr = menu_info->curr_menu.base; curr; curr = curr->next, count++) if (curr->identifier.a_void != 0 && curr->selector == ch) break; diff --git a/win/tty/termcap.c b/win/tty/termcap.c index b06a9abfe..5329417d5 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 termcap.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 3.5 termcap.c $NHDT-Date: 1427756993 2015/03/30 23:09:53 $ $NHDT-Branch: master $:$NHDT-Revision: 1.15 $ */ /* NetHack 3.5 termcap.c $Date: 2009/05/06 10:59:19 $ $Revision: 1.13 $ */ /* SCCS Id: @(#)termcap.c 3.5 2007/12/12 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ @@ -809,10 +809,9 @@ cl_eos() /* free after Robert Viduya */ extern char *tparm(); #endif -# ifdef COLOR_BLACK /* trust include file */ -#undef COLOR_BLACK -# else +# ifndef COLOR_BLACK /* trust include file */ # ifndef _M_UNIX /* guess BGR */ +#define COLOR_BLACK 0 #define COLOR_BLUE 1 #define COLOR_GREEN 2 #define COLOR_CYAN 3 @@ -821,6 +820,7 @@ extern char *tparm(); #define COLOR_YELLOW 6 #define COLOR_WHITE 7 # else /* guess RGB */ +#define COLOR_BLACK 0 #define COLOR_RED 1 #define COLOR_GREEN 2 #define COLOR_YELLOW 3 @@ -830,43 +830,126 @@ extern char *tparm(); #define COLOR_WHITE 7 # endif # endif -#define COLOR_BLACK COLOR_BLUE -const int ti_map[8] = { - COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, - COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; +/* Mapping data for the six terminfo colors that resolve to pairs of nethack + * colors. Black and white are handled specially. + */ +const struct {int ti_color, nh_color, nh_bright_color;} ti_map[6] = +{ + {COLOR_RED,CLR_RED,CLR_ORANGE}, + {COLOR_GREEN,CLR_GREEN,CLR_BRIGHT_GREEN}, + {COLOR_YELLOW,CLR_BROWN,CLR_YELLOW}, + {COLOR_BLUE,CLR_BLUE,CLR_BRIGHT_BLUE}, + {COLOR_MAGENTA,CLR_MAGENTA,CLR_BRIGHT_MAGENTA}, + {COLOR_CYAN,CLR_CYAN,CLR_BRIGHT_CYAN} +}; + +static char nilstring[] = ""; static void init_hilite() { register int c; char *setf, *scratch; - - for (c = 0; c < SIZE(hilites); c++) - hilites[c] = nh_HI; - hilites[CLR_GRAY] = hilites[NO_COLOR] = (char *)0; + int md_len; if (tgetnum("Co") < 8 || (MD == NULL) || (strlen(MD) == 0) || ((setf = tgetstr("AF", (char **)0)) == (char *)0 && (setf = tgetstr("Sf", (char **)0)) == (char *)0)) + { + /* Fallback when colors not available + * It's arbitrary to collapse all colors except gray + * together, but that's what the previous code did. + */ + hilites[CLR_BLACK] = nh_HI; + hilites[CLR_RED] = nh_HI; + hilites[CLR_GREEN] = nh_HI; + hilites[CLR_BROWN] = nh_HI; + hilites[CLR_BLUE] = nh_HI; + hilites[CLR_MAGENTA] = nh_HI; + hilites[CLR_CYAN] = nh_HI; + hilites[CLR_GRAY] = nilstring; + hilites[NO_COLOR] = nilstring; + hilites[CLR_ORANGE] = nh_HI; + hilites[CLR_BRIGHT_GREEN] = nh_HI; + hilites[CLR_YELLOW] = nh_HI; + hilites[CLR_BRIGHT_BLUE] = nh_HI; + hilites[CLR_BRIGHT_MAGENTA] = nh_HI; + hilites[CLR_BRIGHT_CYAN] = nh_HI; + hilites[CLR_WHITE] = nh_HI; return; - - for (c = 0; c < CLR_MAX / 2; c++) { - scratch = tparm(setf, ti_map[c]); - if (c != CLR_GRAY) { - hilites[c] = (char *) alloc(strlen(scratch) + 1); - Strcpy(hilites[c], scratch); - } - if (c != CLR_BLACK) { - hilites[c|BRIGHT] = (char*) alloc(strlen(scratch)+strlen(MD)+1); - Strcpy(hilites[c|BRIGHT], MD); - Strcat(hilites[c|BRIGHT], scratch); } + md_len = strlen(MD); + + c = 6; + while (c--) { + char *work; + scratch = tparm(setf,ti_map[c].ti_color); + work = (char *) alloc(strlen(scratch) + md_len + 1); + Strcpy(work,MD); + hilites[ti_map[c].nh_bright_color] = work; + work += md_len; + Strcpy(work,scratch); + hilites[ti_map[c].nh_color] = work; + } + + scratch = tparm(setf,COLOR_WHITE); + hilites[CLR_WHITE] = (char *) alloc(strlen(scratch) + md_len + 1); + Strcpy(hilites[CLR_WHITE],MD); + Strcat(hilites[CLR_WHITE],scratch); + + hilites[CLR_GRAY] = nilstring; + hilites[NO_COLOR] = nilstring; + + if (iflags.wc2_darkgray) { + /* On many terminals, esp. those using classic PC CGA/EGA/VGA + * textmode, specifying "hilight" and "black" simultaneously + * produces a dark shade of gray that is visible against a + * black background. We can use it to represent black objects. + */ + scratch = tparm(setf,COLOR_BLACK); + hilites[CLR_BLACK] = (char *) alloc(strlen(scratch) + md_len + 1); + Strcpy(hilites[CLR_BLACK],MD); + Strcat(hilites[CLR_BLACK],scratch); + } else { + /* But it's concievable that hilighted black-on-black could + * still be invisible on many others. We substitute blue for + * black. + */ + hilites[CLR_BLACK] = hilites[CLR_BLUE]; } } +static void +kill_hilite() +{ + /* if colors weren't available, no freeing needed */ + if (hilites[CLR_BLACK] == nh_HI) + return; + + if (hilites[CLR_BLACK] != hilites[CLR_BLUE]) + free(hilites[CLR_BLACK]); + + /* CLR_BLUE overlaps CLR_BRIGHT_BLUE, do not free */ + /* CLR_GREEN overlaps CLR_BRIGHT_GREEN, do not free */ + /* CLR_CYAN overlaps CLR_BRIGHT_CYAN, do not free */ + /* CLR_RED overlaps CLR_ORANGE, do not free */ + /* CLR_MAGENTA overlaps CLR_BRIGHT_MAGENTA, do not free */ + /* CLR_BROWN overlaps CLR_YELLOW, do not free */ + /* CLR_GRAY is static 'nilstring', do not free */ + /* NO_COLOR is static 'nilstring', do not free */ + free(hilites[CLR_BRIGHT_BLUE]); + free(hilites[CLR_BRIGHT_GREEN]); + free(hilites[CLR_BRIGHT_CYAN]); + free(hilites[CLR_YELLOW]); + free(hilites[CLR_ORANGE]); + free(hilites[CLR_BRIGHT_MAGENTA]); + free(hilites[CLR_WHITE]); +} + + # else /* UNIX && TERMINFO */ # ifndef TOS @@ -1011,7 +1094,6 @@ init_hilite() # endif # endif /* TOS */ } -# endif /* UNIX */ static void kill_hilite() @@ -1029,6 +1111,7 @@ kill_hilite() # endif return; } +# endif /* UNIX */ #endif /* TEXTCOLOR */ diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 553553744..0aaf9e92d 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ -/* NetHack 3.5 wintty.c $NHDT-Date: 1426465444 2015/03/16 00:24:04 $ $NHDT-Branch: debug $:$NHDT-Revision: 1.71 $ */ +/* NetHack 3.5 wintty.c $NHDT-Date: 1427667623 2015/03/29 22:20:23 $ $NHDT-Branch: master $:$NHDT-Revision: 1.75 $ */ /* NetHack 3.5 wintty.c $Date: 2012/01/22 06:27:09 $ $Revision: 1.66 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -56,7 +56,7 @@ struct window_procs tty_procs = { #if defined(SELECTSAVED) WC2_SELECTSAVED| #endif - 0L, + WC2_DARKGRAY, tty_init_nhwindows, tty_player_selection, tty_askname, @@ -1391,10 +1391,11 @@ struct WinDesc *cw; { tty_menu_item *page_start, *page_end, *curr; long count; - int n, curr_page, page_lines; + int n, curr_page, page_lines, resp_len; boolean finished, counting, reset_count; char *cp, *rp, resp[QBUFSZ], gacc[QBUFSZ], - *msave, *morestr; + *msave, *morestr, really_morc; +#define MENU_EXPLICIT_CHOICE 0x7f /* pseudo menu manipulation char */ curr_page = page_lines = 0; page_start = page_end = 0; @@ -1461,6 +1462,8 @@ struct WinDesc *cw; for (page_lines = 0, curr = page_start; curr != page_end; page_lines++, curr = curr->next) { + int color = NO_COLOR, attr = ATR_NONE; + boolean menucolr = FALSE; if (curr->selector) *rp++ = curr->selector; @@ -1476,6 +1479,11 @@ struct WinDesc *cw; * actually output the character. We're faster doing * this. */ + if (iflags.use_menu_color && + (menucolr = get_menu_coloring(curr->str, &color,&attr))) { + term_start_attr(attr); + if (color != NO_COLOR) term_start_color(color); + } else term_start_attr(curr->attr); for (n = 0, cp = curr->str; #ifndef WIN32CON @@ -1493,6 +1501,10 @@ struct WinDesc *cw; (void) putchar('#'); /* count selected */ } else (void) putchar(*cp); + if (iflags.use_menu_color && menucolr) { + if (color != NO_COLOR) term_end_color(); + term_end_attr(attr); + } else term_end_attr(curr->attr); } } else { @@ -1501,6 +1513,8 @@ struct WinDesc *cw; page_lines = 0; } *rp = 0; + /* remember how many explicit menu choices there are */ + resp_len = (int)strlen(resp); /* corner window - clear extra lines from last page */ if (cw->offx) { @@ -1533,7 +1547,15 @@ struct WinDesc *cw; xwaitforspace(resp); } - morc = map_menu_cmd(morc); + really_morc = morc; /* (only used with MENU_EXPLICIT_CHOICE */ + if ((rp = index(resp, morc)) != 0 && rp < resp + resp_len) + /* explicit menu selection; don't override it if it also + happens to match a mapped menu command (such as ':' to + look inside a container vs ':' to search) */ + morc = MENU_EXPLICIT_CHOICE; + else + morc = map_menu_cmd(morc); + switch (morc) { case '0': /* special case: '0' is also the default ball class */ @@ -1646,7 +1668,7 @@ struct WinDesc *cw; boolean on_curr_page = FALSE; int lineno = 0; tty_getlin("Search for:", tmpbuf); - if (!tmpbuf || tmpbuf[0] == '\033') break; + if (!tmpbuf[0] || tmpbuf[0] == '\033') break; Sprintf(searchbuf, "*%s*", tmpbuf); for (curr = cw->mlist; curr; curr = curr->next) { if (on_curr_page) lineno++; @@ -1664,6 +1686,9 @@ struct WinDesc *cw; } } break; + case MENU_EXPLICIT_CHOICE: + morc = really_morc; + /*FALLTHRU*/ default: if (cw->how == PICK_NONE || !index(resp, morc)) { /* unacceptable input received */ @@ -1809,6 +1834,7 @@ tty_display_nhwindow(window, blocking) cw->offx = (uchar) (int) max((int) 10, (int) (ttyDisplay->cols - cw->maxcol - 1)); #endif + if(cw->offx < 0) cw->offx = 0; if(cw->type == NHW_MENU) cw->offy = 0; if(ttyDisplay->toplin == 1) diff --git a/win/win32/levstuff.mak b/win/win32/levstuff.mak index cf749c6ce..2597e5eb7 100644 --- a/win/win32/levstuff.mak +++ b/win/win32/levstuff.mak @@ -17,10 +17,14 @@ @echo LEXYYC set to $(LEXYYC) !ENDIF +# these won't have an impact unless YACC/LEX are defined +YTABC = y.tab.c +YTABH = y.tab.h +LEXYYC = lex.yy.c default: all -all: ..\util\lev_yacc.c ..\util\lev_lex.c +all: tools ..\util\lev_yacc.c ..\util\lev_lex.c rebuild: clean all @@ -29,15 +33,29 @@ clean: -del ..\util\lev_yacc.c -del ..\include\lev_comp.h +tools: +!IFDEF YACC + @echo Yacc-alike set to $(YACC) + @echo YTABC set to $(YTABC) + @echo YTABH set to $(YTABH) +!ENDIF + +!IFDEF LEX + @echo Lex-alike set to $(LEX) + @echo LEXYYC set to $(LEXYYC) +!ENDIF + #========================================== # Level Compiler Stuff #========================================== + ..\util\lev_yacc.c ..\include\lev_comp.h: ..\util\lev_comp.y -!IF "$(YACC)"=="" +!IFNDEF YACC @echo Using pre-built lev_yacc.c and lev_comp.h @copy ..\sys\share\lev_yacc.c ..\util\lev_yacc.c @copy ..\sys\share\lev_comp.h ..\include\lev_comp.h !ELSE + @echo Generating lev_yacc.c and lev_comp.h chdir ..\util $(YACC) -d lev_comp.y copy $(YTABC) $@ @@ -48,10 +66,11 @@ clean: !ENDIF ..\util\lev_lex.c: ..\util\lev_comp.l -!IF "$(LEX)"=="" +!IFNDEF LEX @echo Using pre-built lev_lex.c @copy ..\sys\share\lev_lex.c $@ !ELSE + @echo Generating lev_lex.c chdir ..\util $(LEX) lev_comp.l copy $(LEXYYC) $@ diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index bd3c60a17..d07af75c5 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -45,7 +45,6 @@ static void nhcoord2display(PNHMapWindow data, int x, int y, LPRECT lpOut); #if (VERSION_MAJOR < 4) && (VERSION_MINOR < 4) && (PATCHLEVEL < 2) static void nhglyph2charcolor(short glyph, uchar* ch, int* color); #endif -static COLORREF nhcolor_to_RGB(int c); HWND mswin_init_map_window () { static int run_once = 0; diff --git a/win/win32/mhmap.h b/win/win32/mhmap.h index 54a614730..e33f64ec3 100644 --- a/win/win32/mhmap.h +++ b/win/win32/mhmap.h @@ -12,6 +12,7 @@ #include "global.h" +COLORREF nhcolor_to_RGB (int c); HWND mswin_init_map_window (void); void mswin_map_stretch(HWND hWnd, LPSIZE lpsz, BOOL redraw); int mswin_map_mode(HWND hWnd, int mode); diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index e39470dc1..6f32931e3 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -917,6 +917,9 @@ BOOL onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) int column; int spacing = 0; + int color = NO_COLOR, attr; + boolean menucolr = FALSE; + lpdis = (LPDRAWITEMSTRUCT) lParam; /* If there are no list box items, skip this message. */ @@ -967,6 +970,13 @@ BOOL onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) buf[0] = item->accelerator; buf[1] = '\x0'; + if (iflags.use_menu_color && + (menucolr = get_menu_coloring(item->str, &color,&attr))) { + /* TODO: use attr too */ + if (color != NO_COLOR) + SetTextColor(lpdis->hDC, nhcolor_to_RGB(color)); + } + SetRect( &drawRect, x, lpdis->rcItem.top, lpdis->rcItem.right, lpdis->rcItem.bottom ); DrawText(lpdis->hDC, NH_A2W(buf, wbuf, 2), 1, &drawRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX); }