#!/usr/bin/perl -w ## ## This port of the original 350 point game "advent" by Willie Crowther / ## Don wood is in the public domain. Use it as you please, but I provide ## absolutely no warranty, yada yada. ## ## If there's any reason why this should not be public domain, please ## contact me (ross.crawford@gmail.com) and I'll remove it. ## use strict; my(@lines, @travel, @ktab,@atab, @ltext,@stext,@key,@cond,@abb, @atloc, @plac,@place,@fixd,@fixed,@link, @ptext,@prop, @actspk, @rtext, @ctext,@cval, @hintlc,@hinted,@hints, @mtext, @tk,@dseen,@dloc,@odloc); my($loc, $keys, $lamp, $grate, $cage, $rod, $rod2, $steps, $bird, $door, $pillow, $snake, $fissur, $tablet, $clam, $oyster, $magzin, $dwarf, $knife, $food, $bottle, $water, $oil, $plant, $plant2, $axe, $mirror, $dragon, $chasm, $troll, $troll2, $bear, $messag, $vend, $batter, $nugget, $coins, $chest, $eggs, $tridnt, $vase, $emrald, $pyram, $pearl, $rug, $chain, # # Added this (not in original source???) # $spices, $back, $look, $cave, $null, $entrnc, $dprssn, $say, $lock, $throw, $find, $invent, $chloc, $chloc2); my($dflag, $daltlc, $turns, $lmwarn, $iwest, $knfloc, $detail, $abbnum, $maxdie, $numdie, $holdng, $dkill, $foobar, $bonus, $clock1, $clock2, $saved, $savet, $closng, $panic, $closed, $gaveup, $continued); my($wkday, $wkend, $holid, $hbegin, $hend, $hname, $short, $magic, $magnm, $latncy); my($demo, $spk, $verb, $obj, $newloc, $showitems, $showloc, $limit, $alive, $maxtrs, $tally, $tally2, $score, $mxscor, $oldloc, $oldlc2, $wzdark, $wd1,$wd2, $i, $idondx); my($linuse, $clsses, $hntmax, $trvs, $tabndx); my($msg, $msgday); sub toting {my($obj) = @_; return $place[$obj] == -1} sub here {my($obj) = @_; return $place[$obj] == $loc || toting($obj)} sub at {my($obj) = @_; return $place[$obj] == $loc || $fixed[$obj] == $loc} sub liq2 {my($pbotl) = @_; return (1-$pbotl)*$water + int($pbotl/2)*($water+$oil)} sub liq {return liq2(max($prop[$bottle],-1 - $prop[$bottle]))} sub liqloc {my($loc) = @_; return liq2( (((int($cond[$loc]/2)*2) % 8)-5) * (int( $cond[$loc]/4) % 2)+1)} sub bittest {my($l,$n) = @_; return (($l & (1 << $n)) > 0)} sub bitset {my($l,$n) = @_; return (bittest($cond[$l],$n))} sub forced {my($loc) = @_; return $cond[$loc] == 2} sub dark {return (!bitset($loc,0) && ($prop[$lamp] == 0 || !here($lamp)))} sub pct {my($n) = @_; return (ran(100) < $n)} # a couple of useful funcs sub min {my($m1,$m2) = @_; return $m1 if ($m1<$m2); return $m2} sub max {my($m1,$m2) = @_; return $m1 if ($m1>$m2); return $m2} # # Extra init stuff as required # my($false) = 0; my($true) = !$false; my($r); # Random seed - initialised from clock first time my($gamefile) = "$ENV{HOME}/.advent.sav"; my($wizfile) = "/usr/local/share/advent/advent.wiz"; # open keyboard open(STDIN,"-") or die "Cant open stdin"; # my($linsiz,$trvsiz,$tabsiz,$locsiz,$vrbsiz,$rtxsiz,$clsmax,$hntsiz,$magsiz) = (650, 750, 300, 150, 35, 205, 12, 20, 35); my($blklin) = $true; print "Initialising...\n"; loaddat(); initwiz(); # Does what poof() used to do initgame(); print "Init done.\n"; loadwiz(); if (!loadgame()) { getusage(); # L:1 $demo = start(); motd($false); $i = ran(1); $hinted[3] = yes(65,1,0); $loc = 1; $newloc = 1; $limit = 330; $limit = 1000 if ($hinted[3]); # New variable allows us to immediately jump to "death" code $alive = $true; } while ($alive) { # L:2 if ($newloc < 9 && $newloc != 0 && $closng) { rspeak(130); $newloc = $loc; $clock2 = 15 if (!$panic); $panic = $true; } # L:71 if ($newloc != $loc && !forced($loc) && !bitset($loc,3)) { for ($i = 1; $i <= 5; ++$i) { if ($odloc[$i] == $newloc && $dseen[$i]) { $newloc = $loc; rspeak(2); last; } # L:73 } } # L:74 $loc = $newloc; if ($loc != 0 && !forced($loc) && !bitset($loc,3)) { movedwarves(); } showlocandgetcommand(); if (!$alive) { # L:99 if ($closng) { # L:95 rspeak(131); $numdie++; exitgame(); } my $yea = yes(81+$numdie*2,82+$numdie*2,54); $numdie++; next if ($numdie == $maxdie || !$yea); $place[$water] = 0; $place[$oil] = 0; $prop[$lamp] = 0 if (toting($lamp)); for ($i = 100; $i >= 1; --$i) { my($k); if (toting($i)) { $k = $oldlc2; $k = 1 if ($i == $lamp); drop($i,$k); } # L:98 } $loc = 3; $oldloc = $loc; $alive = $true; showlocandgetcommand(); } } # while ($alive) 2 loop exitgame(); ###################################################### # Initialising etc ###################################################### sub loaddat { my($i,$k,@tk); # L:1000 for ($i = 1; $i <= 300; ++$i) { $ptext[$i] = 0 if $i <= 100; $rtext[$i] = 0 if $i <= $rtxsiz; $ctext[$i] = 0 if $i <= $clsmax; $mtext[$i] = 0 if $i <= $magsiz; $stext[$i] = $ltext[$i] = $cond[$i] = 0 if $i <= $locsiz; # L:1001 } # # Extra initialisation required # for ($i = 1; $i <= 100; ++$i) { $fixd[$i] = $fixed[$i] = $plac[$i] = 0; } for ($i = 1; $i <= $locsiz; ++$i) { $key[$i] = 0; } for ($i = 1; $i <= 5; ++$i) { $odloc[$i] = 0; } for ($i = 1; $i <= 150; ++$i) { $atloc[$i] = 0; } open(DATFILE,"advent.dat") or die "Can't open advent.dat: $!"; $linuse = 0; $clsses = 1; $hntmax = 0; $trvs = 1; $tabndx = 1; my($sect) = -1; my($loc) = -1; my($filcnt) = 0; my($line); while($line = ) { chomp($line); $filcnt++; my(@line1) = split(/\t/, $line); if ($sect == -1) { $sect = $line1[0]; last if ($sect == 0); print "Processing section " . $sect . ".\n"; $loc = -3; $oldloc = -2; bug(9) if ($sect < 0 || $sect > 12); next; } else { $loc = $line1[0]; if ($loc == -1) { $sect = -1; } } # # Change: $lines array is a bit different - Full text is stored in a # single element with embedded newlines, and the element number # is stored in *text arrays. # # This to get around problem of having TAB embedded in text. # my($rest) = join("\t",@line1[1..$#line1]); $rest .= "\n"; # if ($sect == 1) { if ($loc == $oldloc) { $lines[$linuse] .= $rest; } else { $ltext[$loc] = ++$linuse; $lines[$linuse] = $rest; } } elsif ($sect == 2) { if ($loc == $oldloc) { $lines[$linuse] .= $rest; } else { $stext[$loc] = ++$linuse; $lines[$linuse] = $rest; } } elsif ($sect == 3) { my($newloc) = $line1[1]; my(@tk) = @line1[2..$#line1]; if ($key[$loc] == 0) { $key[$loc] = $trvs; } else { $travel[$trvs-1] *= -1; } my($l); for ($l = 0; $l <= $#tk; ++$l) { $travel[$trvs] = $newloc * 1000 + $tk[$l]; $trvs++; die "Too many travels." if ($trvs > $trvsiz); } # L:1039 $travel[$trvs-1] *= -1; } elsif ($sect == 4) { $ktab[$tabndx] = $line1[0]; # # Make sure there's a -1 at the end # $ktab[$tabndx+1] = -1; $atab[$tabndx] = $line1[1]; $tabndx++; bug(4) if ($tabndx > $tabsiz); } elsif ($sect == 5) { if ($loc == $oldloc) { $lines[$linuse] .= $rest; } else { $linuse++; $ptext[$loc] = $linuse if ($loc>0 && $loc<=100); $lines[$linuse] = $rest; } } elsif ($sect == 6) { bug(6) if ($loc > $rtxsiz); if ($loc == $oldloc) { $lines[$linuse] .= $rest; } else { $rtext[$loc] = ++$linuse; $lines[$linuse] = $rest; } } elsif ($sect == 7) { my($obj, @j) = @line1; $plac[$obj] = $j[0]; $fixd[$obj] = $j[1] if ($#j > 0); } elsif ($sect == 8) { my($verb,$j) = @line1[0..1]; $actspk[$verb] = $j; } elsif ($sect == 9) { ($k, @tk) = @line1; for ($i = 0; $i <= $#tk; ++$i) { $loc = $tk[$i]; bug(8) if (bitset($loc,$k)); $cond[$loc] |= (1 << $k); } } elsif ($sect == 10) { if ($loc == $oldloc) { $lines[$linuse] .= $rest; } else { $ctext[$loc] = ++$linuse; $lines[$linuse] = $rest; $cval[$clsses++] = $loc; } } elsif ($sect == 11) { ($k, @tk) = @line1; bug(7) if ($k < 0 || $k > $hntsiz); for ($i = 0; $i < 4; ++$i){ $hints[$k*4+$i+1] = $tk[$i]; } $hntmax = $k if ($k > $hntmax); } elsif ($sect == 12) { bug(6) if ($loc > $magsiz); if ($loc == $oldloc) { $lines[$linuse] .= $rest; } else { $mtext[$loc] = ++$linuse; $lines[$linuse] = $rest; } } $oldloc = $loc; bug(2) if ($linuse > $linsiz); } close(DATFILE); # # This converts all text in the DAT file. Begin each sentence with # upper case, the rest lower case except for lone "I"s. Note that # this doesn't do a perfect job - certain things which should be # upper case (Willie Crowther) are missed, but it's about as good # as I can do without actually editing the file. # Update: # Also capitalise first letter after a " and occurrences of "y2" # print "Converting text...\n"; for ($i = 1; $i <= $linuse; ++$i) { # all to lower case, first letter upper case $lines[$i] = ucfirst(lc($lines[$i])); # capitalise first word of each sentence $lines[$i] =~ s/([\.\!]\W*)(\w)/$1\u$2/sg; # capitalise lone "i"s $lines[$i] =~ s/(.*\W)i(\W)/$1I$2/sg; # capitalise first letter after " $lines[$i] =~ s/(.* \")(\w)/$1\u$2/sg; # capitalise "y2" $lines[$i] =~ s/(.*\W)y2(\W)/$1Y2$2/sg; } } sub initgame { my($i,$k); # L:1100 for ($i = 1; $i <= 100; ++$i) { $place[$i] = $prop[$i] = $link[$i] = $link[$i+100] = 0; } for ($i = 1; $i <= $locsiz; ++$i) { $abb[$i] = 0; if ($ltext[$i] ne "" && $key[$i] != 0) { $k = $key[$i]; $cond[$i] = 2 if (abs($travel[$k]) % 1000 == 1); } # L:1102 $atloc[$i] = 0; } # # Not sure why its done with 2 loops, but I'm trying to stick close as # possible to the original, so... # for ($k = 100; $k >= 1; --$k) { if ($fixd[$k] > 0) { drop($k+100, $fixd[$k]); drop($k, $plac[$k]); } # L:1106 } for ($k = 100; $k >= 1; --$k) { $fixed[$k] = $fixd[$k]; # L:1107 drop($k, $plac[$k]) if ($plac[$k] != 0 && $fixd[$k] <= 0); } $maxtrs = 79; $tally = $tally2 = 0; for ($i = 50; $i <= $maxtrs; ++$i) { $prop[$i] = -1 if ($ptext[$i] != 0); $tally -= $prop[$i]; } for ($i = 1; $i <= $hntmax; ++$i) { $hinted[$i] = $false; $hintlc[$i] = 0; } # # Some constants... # $keys = vocab("KEYS",1); $lamp = vocab("LAMP",1); $grate = vocab("GRATE",1); $cage = vocab("CAGE",1); $rod = vocab("ROD",1); $rod2 = $rod+1; $steps = vocab("STEPS",1); $bird = vocab("BIRD",1); $door = vocab("DOOR",1); $pillow = vocab("PILLO",1); $snake = vocab("SNAKE",1); $fissur = vocab("FISSU",1); $tablet = vocab("TABLE",1); $clam = vocab("CLAM",1); $oyster = vocab("OYSTE",1); $magzin = vocab("MAGAZ",1); $dwarf = vocab("DWARF",1); $knife = vocab("KNIFE",1); $food = vocab("FOOD",1); $bottle = vocab("BOTTL",1); $water = vocab("WATER",1); $oil = vocab("OIL",1); $plant = vocab("PLANT",1); $plant2 = $plant+1; $axe = vocab("AXE",1); $mirror = vocab("MIRRO",1); $dragon = vocab("DRAGO",1); $chasm = vocab("CHASM",1); $troll = vocab("TROLL",1); $troll2 = $troll+1; $bear = vocab("BEAR",1); $messag = vocab("MESSA",1); $vend = vocab("VENDI",1); $batter = vocab("BATTE",1); $nugget = vocab("GOLD",1); $coins = vocab("COINS",1); $chest = vocab("CHEST",1); $eggs = vocab("EGGS",1); $tridnt = vocab("TRIDE",1); $vase = vocab("VASE",1); $emrald = vocab("EMERA",1); $pyram = vocab("PYRAM",1); $pearl = vocab("PEARL",1); $rug = vocab("RUG",1); $chain = vocab("CHAIN",1); # # Added this - seems to be omitted in my original source version ???? # $spices = vocab("SPICE",1); $back = vocab("BACK",0); $look = vocab("LOOK",0); $cave = vocab("CAVE",0); $null = vocab("NULL",0); $entrnc = vocab("ENTRA",0); $dprssn = vocab("DEPRE",0); $say = vocab("SAY",2); $lock = vocab("LOCK",2); $throw = vocab("THROW",2); $find = vocab("FIND",2); $invent = vocab("INVENT",2); $chloc = 114; $chloc2 = 140; # # Variables that change... # for ($i = 1; $i <= 6; ++$i) { $dseen[$i] = $false; } $dflag = 0; $dloc[1] = 19; $dloc[2] = 27; $dloc[3] = 33; $dloc[4] = 44; $dloc[5] = 64; $dloc[6] = $chloc; $daltlc = 18; $turns = 0; $lmwarn = $false; $iwest = 0; $knfloc = 0; $detail = 0; $abbnum = 5; for ($i = 0; $i <= 4; ++$i) { $maxdie = $i+1 if ($rtext[2*$i+81] != 0); } $numdie = 0; $holdng = 0; $dkill = 0; $foobar = 0; $bonus = 0; $clock1 = 30; $clock2 = 50; $saved = 0; $closng = $false; $panic = $false; $closed = $false; $gaveup = $false; $continued = $false; } sub getusage { my($i,$j,$k,$kk); for ($kk = $locsiz; $kk >= 1; --$kk) { last if ($ltext[$kk] != 0); # L:1998 } # L:1997 $obj = 0; for ($k = 1; $k <= 100; ++$k) { $obj++ if ($ptext[$k] != 0); # L:1996 } for ($k = 1; $k <= $tabndx; ++$k) { $verb = $ktab[$k]-2000 if (int($ktab[$k]/1000) == 2); # L:1995 } for ($j = $rtxsiz; $j >= 1; --$j) { last if ($rtext[$j] != 0); # L:1994 } # L:1993 for ($i = $magsiz; $i >= 1; --$i) { last if ($mtext[$i] != 0); # L:1992 } # L:1991 $k = 100; # L:1992 printf "Table space used:\n" ."%d of %d words of messages\n" ."%d of %d travel options\n" ."%d of %d vocabulary words\n" ."%d of %d locations\n" ."%d of %d objects\n" ."%d of %d action verbs\n" ."%d of %d RTEXT messages\n" ."%d of %d CLASS messages\n" ."%d of %d hints\n" ."%d of %d MAGIC messages\n", $linuse,$linsiz,$trvs,$trvsiz,$tabndx,$tabsiz,$kk, $locsiz,$obj,$k,$verb,$vrbsiz,$j,$rtxsiz,$clsses,$clsmax, $hntmax,$hntsiz,$i,$magsiz; } ###################################################### # Saving & loading.... ###################################################### sub savegame { if (!open(SAVEFILE,">$gamefile")) { printf "Can't open %s to save game.\n",$gamefile; return $false; } print SAVEFILE "$r\n"; # so we dont have to re-seed... print SAVEFILE "$saved\n"; print SAVEFILE "$savet\n"; print SAVEFILE "$limit\n"; print SAVEFILE "$loc\n"; print SAVEFILE "$newloc\n"; print SAVEFILE "$maxtrs\n"; print SAVEFILE "$tally\n"; print SAVEFILE "$tally2\n"; print SAVEFILE "$dflag\n"; for ($i = 1; $i <= 6; ++$i) { print SAVEFILE "$dseen[$i]\n"; print SAVEFILE "$dloc[$i]\n"; } print SAVEFILE "$turns\n"; print SAVEFILE "$lmwarn\n"; print SAVEFILE "$iwest\n"; print SAVEFILE "$knfloc\n"; print SAVEFILE "$detail\n"; print SAVEFILE "$abbnum\n"; print SAVEFILE "$maxdie\n"; print SAVEFILE "$numdie\n"; print SAVEFILE "$holdng\n"; print SAVEFILE "$dkill\n"; print SAVEFILE "$foobar\n"; print SAVEFILE "$bonus\n"; print SAVEFILE "$clock1\n"; print SAVEFILE "$clock2\n"; print SAVEFILE "$saved\n"; print SAVEFILE "$closng\n"; print SAVEFILE "$panic\n"; print SAVEFILE "$closed\n"; print SAVEFILE "$gaveup\n"; for ($i = 1; $i <= 100; ++$i) { print SAVEFILE "$place[$i]\n"; print SAVEFILE "$fixed[$i]\n"; print SAVEFILE "$prop[$i]\n"; print SAVEFILE "$link[$i]\n"; print SAVEFILE "$link[$i+100]\n"; } print SAVEFILE "$locsiz\n"; for ($i = 1; $i <= $locsiz; ++$i) { print SAVEFILE "$abb[$i]\n"; print SAVEFILE "$cond[$i]\n"; print SAVEFILE "$atloc[$i]\n"; } print SAVEFILE "$hntmax\n"; for ($i = 1; $i <= $hntmax; ++$i) { print SAVEFILE "$hinted[$i]\n"; print SAVEFILE "$hintlc[$i]\n"; } close(SAVEFILE); return $true; } sub loadgame { if (!open(LOADFILE,"$gamefile")) { return $false; } print "\nLoading saved game...\n"; $r = ; chomp $r; $saved = ; chomp $saved; $savet = ; chomp $savet; $limit = ; chomp $limit; $loc = ; chomp $loc; $newloc = ; chomp $newloc; $maxtrs = ; chomp $maxtrs; $tally = ; chomp $tally; $tally2 = ; chomp $tally2; $dflag = ; chomp $dflag; for ($i = 1; $i <= 6; ++$i) { $dseen[$i] = ; chomp $dseen[$i]; $dloc[$i] = ; chomp $dloc[$i]; } $turns = ; chomp $turns; $lmwarn = ; chomp $lmwarn; $iwest = ; chomp $iwest; $knfloc = ; chomp $knfloc; $detail = ; chomp $detail; $abbnum = ; chomp $abbnum; $maxdie = ; chomp $maxdie; $numdie = ; chomp $numdie; $holdng = ; chomp $holdng; $dkill = ; chomp $dkill; $foobar = ; chomp $foobar; $bonus = ; chomp $bonus; $clock1 = ; chomp $clock1; $clock2 = ; chomp $clock2; $saved = ; chomp $saved; $closng = ; chomp $closng; $panic = ; chomp $panic; $closed = ; chomp $closed; $gaveup = ; chomp $gaveup; for ($i = 1; $i <= 100; ++$i) { $place[$i] = ; chomp $place[$i]; $fixed[$i] = ; chomp $fixed[$i]; $prop[$i] = ; chomp $prop[$i]; $link[$i] = ; chomp $link[$i]; $link[$i+100] = ; chomp $link[$i+100]; } $locsiz = ; chomp $locsiz; for ($i = 1; $i <= $locsiz; ++$i) { $abb[$i] = ; chomp $abb[$i]; $cond[$i] = ; chomp $cond[$i]; $atloc[$i] = ; chomp $atloc[$i]; } $hntmax = ; chomp $hntmax; for ($i = 1; $i <= $hntmax; ++$i) { $hinted[$i] = ; chomp $hinted[$i]; $hintlc[$i] = ; chomp $hintlc[$i]; } close(LOADFILE); $continued = $true; # # Do this first, so save file isn't deleted if game can't go ahead # # L:8305 my $yea = start(); unlink $gamefile; # Dont let them re-start here again... return $true; } sub savewiz { if (!open(SAVEFILE,">$wizfile")) { printf "Can't open %s to save game.\n",$wizfile; return $false; } print SAVEFILE "$wkday\n"; print SAVEFILE "$wkend\n"; print SAVEFILE "$holid\n"; print SAVEFILE "$hbegin\n"; print SAVEFILE "$hend\n"; print SAVEFILE "$short\n"; print SAVEFILE "$magic\n"; print SAVEFILE "$magnm\n"; print SAVEFILE "$latncy\n"; print SAVEFILE "$msgday\n"; print SAVEFILE "$msg"; close(SAVEFILE); return $true; } sub loadwiz { my($m); if (!open(LOADFILE,"$wizfile")) { return $false; } $wkday = ; chomp $wkday; $wkend = ; chomp $wkend; $holid = ; chomp $holid; $hbegin = ; chomp $hbegin; $hend = ; chomp $hend; $short = ; chomp $short; $magic = ; chomp $magic; $magnm = ; chomp $magnm; $latncy = ; chomp $latncy; $msgday = ; chomp $msgday; while($m = ) { $msg .= $m; } close(LOADFILE); return $true; } ######################################################################## # # Following are some new functions - mostly to get around the liberal # use of "GOTO" in the original # sub showlocandgetcommand { # L:2000 $alive = $false if ($loc == 0); return if (!$alive); do { showlocation(); return if (!$alive); # L:2001 if (forced($loc)) { getnewloc(1); return; } do { rspeak(8) if ($loc == 33 && pct(25) && !$closng); showwhatshere() if (!dark()); do { # L:2012 $verb = 0; $obj = 0; # L:2600 checkhints(); if ($closed) { pspeak($oyster,1) if ($prop[$oyster] < 0 && toting($oyster)); for ($i = 1; $i <= 100; ++$i) { # L:2604 $prop[$i] = -1 - $prop[$i] if (toting($i) && $prop[$i] < 0); } } # L:2605 $wzdark = dark(); $knfloc = 0 if ($knfloc > 0 && $knfloc != $loc); $i = ran(1); # just generates initial seed getin(\$wd1,\$wd2); $newloc = $loc; $showitems = $false; $showloc = $false; processentry(); $showloc = $true if ($newloc != $loc); } until ($showitems || $showloc); } until ($showloc); } while ($newloc == $loc && $alive); } sub sayok { # L:2009 rspeak(54); } sub processentry { my($k); # L:2608 $foobar = min(0,-$foobar); maint() if ($turns == 0 && uc($wd1) eq "MAGIC" && uc($wd2) eq "MODE"); $turns++; if ($demo && $turns >= $short) { # L:13000 mspeak(1); exitgame(); } $verb = 0 if ($verb == $say && $wd2 ne ""); if ($verb == $say) { dotransitive(); return; } $clock1-- if ($tally == 0 && $loc >= 15 && $loc != 33); if ($clock1 == 0) { closewarning(); } else { $clock2-- if ($clock1 < 0); if ($clock2 == 0) { lastroom(); $showloc = $true; return; } $limit-- if ($prop[$lamp] == 1); if ($limit <= 30 && here($batter) && $prop[$batter] == 0 && here($lamp)) { replacebatteries(); } else { if ($limit == 0) { # L:12400 $limit = -1; $prop[$lamp] = 0; rspeak(184) if (here($lamp)); } else { if ($limit < 0 && $loc <= 8) { # L:12600 rspeak(185); $gaveup = $true; exitgame(); } if ($limit <= 30) { # L:12200 if (!$lmwarn && here($lamp)) { $lmwarn = $true; $spk = 187; $spk = 183 if ($place[$batter] == 0); $spk = 189 if ($prop[$batter] == 1); rspeak($spk); } } } } } # L:19999 $k = 43; $k = 70 if (liqloc($loc) == $water); if (uc($wd1) eq "ENTER" && (uc($wd2) eq "STREA" || uc($wd2) eq "WATER")) { rspeak($k); return; } if (uc($wd1) eq "ENTER" && $wd2 ne "") { getsecond(); } else { if ((uc($wd1) eq "WATER" || uc($wd1) eq "OIL") && (uc($wd2) eq "PLANT" || uc($wd2) eq "DOOR")) { $wd2 = "pour" if (at(vocab($wd2,1))); } } # L:2610 if (uc($wd1) eq "WEST") { $iwest++; rspeak(17) if ($iwest == 10); } processwd1(); } sub processwd1 { my($i,$k,$kq); # L:2630 $i = vocab($wd1,-1); if ($i == -1) { # L:3000 $spk = 60; $spk = 61 if (pct(20)); $spk = 13 if (pct(20)); rspeak($spk); } else { $k = $i % 1000; $kq = int($i/1000)+1; if ($kq == 1) { getnewloc($k); } elsif ($kq == 2) { analysewords($k); } elsif ($kq == 3) { analyseverb($k); } elsif ($kq == 4) { rspeak($k); } } } sub replacebatteries { # L:12000 rspeak(188); $prop[$batter] = 1; drop($batter,$loc) if (toting($batter)); $limit += 2500; $lmwarn = $false; } sub closewarning { # L:10000 $prop[$grate] = 0; $prop[$fissur] = 0; for ($i = 1; $i <= 6; ++$i) { $dseen[$i] = $false; # L:10010 $dloc[$i] = 0; } move($troll,0); move($troll+100,0); move($troll2,$plac[$troll]); move($troll2+100,$fixd[$troll]); juggle($chasm); dstroy($bear) if ($prop[$bear] != 3); $prop[$chain] = 0; $fixed[$chain] = 0; $prop[$axe] = 0; $fixed[$axe] = 0; rspeak(129); $clock1 = -1; $closng = $true; } sub lastroom { my($i); # L:11000 $prop[$bottle] = put($bottle,115,1); $prop[$plant] = put($plant,115,0); $prop[$oyster] = put($oyster,115,0); $prop[$lamp] = put($lamp,115,0); $prop[$rod] = put($rod,115,0); $prop[$dwarf] = put($dwarf,115,0); $loc = 115; $oldloc = 115; $newloc = 115; # # Changed this to $i to avoid "only used once" warning # $i = put($grate,116,0); $prop[$snake] = put($snake,116,1); $prop[$bird] = put($bird,116,1); $prop[$cage] = put($cage,116,0); $prop[$rod2] = put($rod2,116,0); $prop[$pillow] = put($pillow,116,0); $prop[$mirror] = put($mirror,115,0); $fixed[$mirror] = 116; for ($i = 1; $i <= 100; ++$i) { # L:11010 dstroy($i) if (toting($i)); } rspeak(132); $closed = $true; } sub showlocation { my($kk) = $stext[$loc]; $kk = $ltext[$loc] if (($abb[$loc] % $abbnum) == 0 || $kk == 0); if (!forced($loc) && dark()) { if ($wzdark && pct(35)) { $alive = $false; # L:90 rspeak(23); $oldlc2 = $loc; return; } $kk = $rtext[16]; } rspeak(141) if (toting($bear)); speak($kk); } # # Do all the dwarf movement. If player is killed, set $alive to $false # sub movedwarves { my($k); if ($dflag == 0) { $dflag = 1 if ($loc >= 15); } else { # L:6000 if ($dflag == 1) { if ($loc >= 15 && pct(5)) { $dflag = 2; for ($i = 1; $i <= 2; ++$i) { my($j) = 1+ran(5); $dloc[$j] = 0 if (pct(50) && $saved == -1); # L:6001 } for ($i = 1; $i <= 5; ++$i) { $dloc[$i] = $daltlc if ($dloc[$i] == $loc); # L:6002 $odloc[$i] = $dloc[$i]; } $odloc[$i] = 0; # Need extra init - fortran assumes 0. rspeak(3); drop($axe,$loc); } } else { # L:6010 my($dtotal) = 0; my($attack) = 0; my($stick) = 0; for ($i = 1; $i <= 6; ++$i) { if ($dloc[$i] != 0) { my($j) = 1; my($kk) = $dloc[$i]; $kk = $key[$kk]; if ($kk != 0) { do { # L:6012 $newloc = int(abs($travel[$kk])/1000) % 1000; if ($newloc>300 || $newloc<15 || $newloc==$odloc[$i] || ($j>1 && $newloc==$tk[$j-1]) || $j>=20 || $newloc == $dloc[$i] || forced($newloc) || int(abs($travel[$kk]/1000000)) == 100) { } else { $tk[$j] = $newloc; ++$j; } # L:6014 ++$kk; } while ($travel[$kk-1] >= 0); } # L:6016 $tk[$j] = $odloc[$i]; --$j if ($j >= 2); $j = 1+ran($j); $odloc[$i] = $dloc[$i]; $dloc[$i] = $tk[$j]; $dseen[$i] = ($dseen[$i] && $loc > 15) || ($dloc[$i] == $loc || $odloc[$i] == $loc); if ($dseen[$i]) { $dloc[$i] = $loc; if ($i == 6) { checkpirate(); # Fall thru to 6030 } else { # L:6027 $dtotal++; if ($odloc[$i] == $dloc[$i]) { $attack++; $knfloc = $loc if ($knfloc >= 0); $stick++ if (ran(1000) < 95*($dflag-2)); } } } # dseen[i] } # dloc[i] != 0 # L:6030 } # i=1..6 if ($dtotal != 0) { if ($dtotal != 1) { # L:67 printf "There are %d threatening little swarves in the" ." room with you.\n", $dtotal; } else { # L:75 rspeak(4); } # L:77 if ($attack != 0) { $dflag = 3 if ($dflag == 2); $dflag = 20 if ($saved != -1); if ($attack == 1) { # L:79 rspeak(5); $k = 52; } else { # L:78 printf "%d of them throw knives at you!\n", $attack; $k = 6; } # L:82 if ($stick <= 1) { rspeak($k+$stick); } else { # L:83 printf "%d of them get you!\n", $stick; } if ($stick != 0) { $alive = $false; } # L:84 if (!$alive) { $oldlc2 = $loc; } # L:79 } } } # dflag != 1 } # dflag == 0 } sub checkpirate { my($i,$j,$k); if ($loc != $chloc && $prop[$chest] < 0) { $k = 0; for ($i = 50; $i <= $maxtrs; ++$i) { if ($i == $pyram && ($loc == $plac[$pyram] || $loc == $plac[$emrald])) { } else { $idondx = $i; if (toting($idondx)) { # L:6022 rspeak(128); move($chest,$chloc) if ($place[$messag]==0); move($messag,$chloc); for ($j = 50; $j <= $maxtrs; ++$j) { if ($j == $pyram && ($loc == $plac[$pyram] || $loc == $plac[$emrald])) { } else { $idondx = $j; if (at($idondx) && $fixed[$idondx] == 0) { carry($idondx,$loc); } drop($idondx,$chloc) if (toting($idondx)); } # L:6023 } last; } } # L:6020 $k = 1 if (here($idondx)); if($tally==$tally2+1 && $k==0 && $place[$chest]==0 && here($lamp) && $prop[$lamp]==1) { # L:6025 rspeak(186); move($chest,$chloc); move($messag,$chloc2); last; # Fall thru to 6024 } } # L:6024 $dloc[6] = $chloc; $odloc[6] = $chloc; $dseen[6] = $false; } } # # Show them all the objects that are in this location # sub showwhatshere { $abb[$loc]++; my($i) = $atloc[$loc]; while ($i != 0) { my($obj) = $i; $obj -= 100 if ($obj>100); if ($obj != $steps || !toting($nugget)) { if ($prop[$obj] < 0) { if (!$closed) { $prop[$obj] = 0; $prop[$obj] = 1 if ($obj == $rug || $obj == $chain); $tally--; $limit = min(35,$limit) if ($tally == $tally2 && $tally != 0); } } if ($prop[$obj] >= 0) { my($kk) = $prop[$obj]; $kk = 1 if ($obj == $steps && $loc == $fixed[$steps]); pspeak($obj,$kk); } } $i = $link[$i]; } # while i != 0 } # # analyseverb inplements the 4000 bits # sub analyseverb { # L:4000 ($verb) = @_; $spk = $actspk[$verb]; if ($wd2 ne "" && $verb ne $say) { getsecond(); return; } # Force transitive for "say" $obj = -1 if ($verb == $say); if ($obj == 0) { # L:4080 dointransitive(); } else { # L:4090 dotransitive(); } return; } # # analysewords implements the 5000 bits # sub analysewords { # L:5000 ($obj) = @_; if ($fixed[$obj] == $loc || here($obj)) { # L:5010 whattodo(); return; } # L:5100 if ($obj == $grate) { $obj = $dprssn if ($loc == 1 || $loc == 4 || $loc == 7); $obj = $entrnc if ($loc > 9 && $loc < 15); if ($obj != $grate) { getnewloc(1); return; } } # L:5110 if ($obj == $dwarf) { for ($i = 1; $i <= 5; ++$i) { if ($dloc[$i] == $loc && $dflag >= 2) { whattodo(); return; } # L:5112 } } # L:5120 if ((liq() == $obj && here($bottle)) || $obj == liqloc($loc)) { whattodo(); return; } if ($obj != $plant || !at($plant2) || $prop[$plant2] == 0) { } else { $obj = $plant2; whattodo(); return; } # L:5130 if ($obj != $knife || $knfloc != $loc) { } else { $knfloc = -1; $spk = 116; rspeak($spk); return; } # L:5140 if ($obj != $rod || !here($rod2)) { } else { $obj = $rod2; whattodo(); return; } # L:5190 if (($verb == $find || $verb == $invent) && $wd2 eq "") { whattodo(); return; } cantsee(); } sub dointransitive { bug(23) if ($verb < 1 || $verb > 31); if ($verb == 1) { # TAKE takenoobj(); } elsif ($verb == 2) { # DROP what(); } elsif ($verb == 3) { # SAY what(); } elsif ($verb == 4) { # OPEN locknoobj(); } elsif ($verb == 5) { # NOTH sayok(); } elsif ($verb == 6) { # LOCK locknoobj(); } elsif ($verb == 7) { # ON lampon(); } elsif ($verb == 8) { # OFF lampoff(); } elsif ($verb == 9) { # WAVE what(); } elsif ($verb == 10) { # CALM what(); } elsif ($verb == 11) { # WALK rspeak($spk); } elsif ($verb == 12) { # KILL attack(); } elsif ($verb == 13) { # POUR pour(); } elsif ($verb == 14) { # EAT eatnoobj(); } elsif ($verb == 15) { # DRINK drink(); } elsif ($verb == 16) { # RUB what(); } elsif ($verb == 17) { # TOSS what(); } elsif ($verb == 18) { # QUIT quit(); } elsif ($verb == 19) { # FIND what(); } elsif ($verb == 20) { # INVENTORY inventory(); } elsif ($verb == 21) { # FEED what(); } elsif ($verb == 22) { # FILL fill(); } elsif ($verb == 23) { # BLAST blast(); } elsif ($verb == 24) { # SCORE score(); } elsif ($verb == 25) { # FOO foo(); } elsif ($verb == 26) { # BRIEF brief(); } elsif ($verb == 27) { # READ readnoobj(); } elsif ($verb == 28) { # BREAK what(); } elsif ($verb == 29) { # WAKE what(); } elsif ($verb == 30) { # SUSPEND suspend(); } elsif ($verb == 31) { # HOUR mspeak(6); hours(); } } sub dotransitive { bug(24) if ($verb < 1 || $verb > 31); if ($verb == 1) { # TAKE take(); } elsif ($verb == 2) { # DROP discard(); } elsif ($verb == 3) { # SAY say(); } elsif ($verb == 4) { # OPEN lockit(); } elsif ($verb == 5) { # NOTH sayok(); } elsif ($verb == 6) { # LOCK lockit(); } elsif ($verb == 7) { # ON lampon(); } elsif ($verb == 8) { # OFF lampoff(); } elsif ($verb == 9) { # WAVE wave(); } elsif ($verb == 10) { # CALM rspeak($spk); } elsif ($verb == 11) { # WALK rspeak($spk); } elsif ($verb == 12) { # KILL attack(); } elsif ($verb == 13) { # POUR pour(); } elsif ($verb == 14) { # EAT eat(); } elsif ($verb == 15) { # DRINK drink(); } elsif ($verb == 16) { # RUB rub(); } elsif ($verb == 17) { # TOSS throw(); } elsif ($verb == 18) { # QUIT rspeak($spk); } elsif ($verb == 19) { # FIND find(); } elsif ($verb == 20) { # INVENTORY inventory(); } elsif ($verb == 21) { # FEED feed(); } elsif ($verb == 22) { # FILL fill(); } elsif ($verb == 23) { # BLAST blast(); } elsif ($verb == 24) { # SCORE rspeak($spk); } elsif ($verb == 25) { # FOO rspeak($spk); } elsif ($verb == 26) { # BRIEF rspeak($spk); } elsif ($verb == 27) { # READ readit(); } elsif ($verb == 28) { # BREAK break(); } elsif ($verb == 29) { # WAKE wake(); } elsif ($verb == 30) { # SUSPEND rspeak($spk); } elsif ($verb == 31) { # HOUR rspeak($spk); } } sub whattodo { # L:5010 if ($wd2 ne "") { getsecond(); return; # will go to 2610 } if ($verb != 0) { dotransitive(); return; } # L:5015 printf "What do you want to do with the %s ?\n",$wd1; } sub what { # L:8000 # L:8002 printf "%s What?\n",$wd1; $obj = 0; } sub takenoobj { # L:8010 if ($atloc[$loc] == 0 || $link[$atloc[$loc]] != 0) { what(); return; } for ($i = 1; $i <= 5; ++$i) { if ($dloc[$i] == $loc && $dflag >= 2) { what(); return; } # L:8012 } $obj = $atloc[$loc]; take(); } sub take { # L:9010 if (toting($obj)) { rspeak($spk); return; } $spk = 25; $spk = 115 if ($obj == $plant && $prop[$plant] <= 0); $spk = 169 if ($obj == $bear && $prop[$bear] == 1); $spk = 170 if ($obj == $chain && $prop[$bear] != 0); if ($fixed[$obj] != 0) { rspeak($spk); return; } if ($obj == $water || $obj == $oil) { if (here($bottle) && liq() == $obj) { } else { $obj = $bottle; if (toting($bottle) && $prop[$bottle] == 1) { fill(); return; } $spk = 105 if ($prop[$bottle] != 1); $spk = 104 if (!toting($bottle)); rspeak($spk); return; } # L:9018 $obj = $bottle; } # L:9017 if ($holdng >= 7) { rspeak(92); return; } # L:9016 if ($obj != $bird || $prop[$bird] != 0) { } else { if (toting($rod)) { rspeak(26); return; } # L:9013 if (!toting($cage)) { rspeak(27); return; } } # L:9014 if (($obj == $bird || $obj == $cage) && $prop[$bird] != 0) { carry($bird+$cage-$obj,$loc); } carry($obj,$loc); my($k) = liq(); $place[$k] = -1 if ($obj == $bottle && $k != 0); sayok(); } sub discard { # L:9020 $obj = $rod2 if (toting($rod2) && $obj == $rod && !toting($rod)); if (!toting($obj)) { rspeak($spk); return; } if ($obj != $bird || !here($snake)) { # L:9024 if ($obj == $coins && here($vend)) { dstroy($coins); drop($batter,$loc); pspeak($batter,0); return; } else { # L:9025 if ($obj == $bird && at($dragon) && $prop[$dragon] == 0) { rspeak(154); dstroy($bird); $prop[$bird] = 0; $tally2++ if ($place[$snake] == $plac[$snake]); return; } else { # L:9026 if ($obj == $bear && at($troll)) { rspeak(163); move($troll,0); move($troll+100,0); move($troll2,$plac[$troll]); move($troll2+100,$fixd[$troll]); juggle($chasm); $prop[$troll] = 2; } else { # L:9027 if ($obj == $vase && $loc != $plac[$pillow]) { # L:9028 $prop[$vase] = 2; $prop[$vase] = 0 if (at($pillow)); pspeak($vase,$prop[$vase]+1); $fixed[$vase] = -1 if ($prop[$vase] != 0); } else { rspeak(54); } } } } } else { rspeak(30); wakendwarves() if ($closed); dstroy($snake); $prop[$snake] = 1; } # L:9021 my($k) = liq(); $obj = $bottle if ($k == $obj); $place[$k] = 0 if ($obj == $bottle && $k != 0); $prop[$bird] = 0 if ($obj == $bird); drop($obj,$loc); } sub say { my($tk,$i); # L:9030 $tk = $wd2; $tk = $wd1 if ($wd2 eq ""); if ($wd2 ne "") { $wd1 = $wd2; } $i = vocab($wd1,-1); if ($i == 62 || $i == 65 || $i == 71 || $i == 2025) { # L:9035 $wd2 = ""; $obj = 0; processwd1(); return; } else { # L:9032 printf "Okay, \"%s\".\n",$tk; return; } } sub locknoobj { # L:8040 $spk = 28; $obj = $clam if (here($clam)); $obj = $oyster if (here($oyster)); $obj = $door if (at($door)); $obj = $grate if (at($grate)); if ($obj != 0 && here($chain)) { what(); return; } $obj = $chain if (here($chain)); if ($obj == 0) { rspeak($spk); return; } lockit(); } sub lockit { my($k); # L:9040 if ($obj == $clam || $obj == $oyster) { # L:9046 $k = 0; $k = 1 if ($obj == $oyster); $spk = 124+$k; $spk = 120+$k if (toting($obj)); $spk = 122+$k if (!toting($tridnt)); $spk = 61 if ($verb == $lock); if ($spk != 124) { rspeak($spk); return; } dstroy($clam); drop($oyster,$loc); drop($pearl,105); rspeak($spk); return; } else { $spk = 111 if ($obj == $door); $spk = 54 if ($obj == $door && $prop[$door] == 1); $spk = 32 if ($obj == $cage); $spk = 55 if ($obj == $keys); $spk = 31 if ($obj == $grate || $obj == $chain); if ($spk != 31 || !here($keys)) { rspeak($spk); return; } if ($obj != $chain) { if (!$closng) { # L:9043 $k = 34+$prop[$grate]; $prop[$grate] = 1; $prop[$grate] = 0 if ($verb == $lock); $k += 2*$prop[$grate]; rspeak($k); return; } $clock2 = 15 if (!$panic); $panic = $true; rspeak($k); return; } else { # L:9048 if ($verb != $lock) { $spk = 171; $spk = 41 if ($prop[$bear] == 0); $spk = 37 if ($prop[$chain] == 0); if ($spk != 171) { rspeak($spk); return; } $prop[$chain] = 0; $fixed[$chain] = 0; $prop[$bear] = 2 if ($prop[$bear] != 3); $fixed[$bear] = 2 - $prop[$bear]; } else { # L:9049 $spk = 172; $spk = 34 if ($prop[$chain] != 0); $spk = 173 if ($loc != $plac[$chain]); if ($spk != 172) { rspeak($spk); return; } $prop[$chain] = 2; drop($chain,$loc) if (toting($chain)); $fixed[$chain] = -1; } rspeak($spk); return; } } } sub lampon { # L:9070 if (!here($lamp)) { rspeak($spk); return; } $spk = 184; if ($limit < 0) { rspeak($spk); return; } $prop[$lamp] = 1; rspeak(39); if ($wzdark) { showlocandgetcommand(); return; } } sub lampoff { # L:9080 if (!here($lamp)) { rspeak($spk); return; } $prop[$lamp] = 0; rspeak(40); rspeak(16) if (dark()); } sub wave { # L:9090 $spk = 29 if ((!toting($obj)) && ($obj != $rod || !toting($rod2))); if ($obj != $rod || !at($fissur) || !toting($obj) || $closng) { rspeak($spk); return; } $prop[$fissur] = 1 - $prop[$fissur]; pspeak($fissur,2-$prop[$fissur]); } sub attack { # L:9120 for ($i = 1; $i <= 5; ++$i) { last if ($dloc[$i] == $loc && $dflag >= 2); # L:9121 } $i = 0 if ($i > 5); # L:9122 if ($obj == 0) { $obj = $dwarf if ($i != 0); $obj = $obj*100 + $snake if (here($snake)); $obj = $obj*100 + $dragon if (at($dragon) && $prop[$dragon] == 0); $obj = $obj*100 + $troll if (at($troll)); $obj = $obj*100 + $bear if (here($bear) && $prop[$bear] == 0); if ($obj > 100) { what(); return; } if ($obj == 0) { $obj = $bird if (here($bird) && $verb != $throw); $obj = $obj*100 + $clam if (here($clam) || here($oyster)); if ($obj > 100) { what(); return; } } } # L:9124 if ($obj == $bird) { $spk = 137; if ($closed) { rspeak($spk); return; } dstroy($bird); $prop[$bird] = 0; $tally2++ if ($place[$snake] == $plac[$snake]); $spk = 45; } # L:9125 $spk = 44 if ($obj == 0); $spk = 150 if ($obj == $clam || $obj == $oyster); $spk = 46 if ($obj == $snake); $spk = 49 if ($obj == $dwarf); wakendwarves() if ($obj == $dwarf && $closed); $spk = 167 if ($obj == $dragon); $spk = 157 if ($obj == $troll); $spk = 165+int(($prop[$bear]+1)/2) if ($obj == $bear); if ($obj != $dragon || $prop[$dragon] != 0) { rspeak($spk); return; } rspeak(49); $verb = 0; $obj = 0; getin(\$wd1,\$wd2); if (uc($wd1) ne "Y" && uc($wd1) ne "YES") { processentry(); return; } pspeak($dragon,1); $prop[$dragon] = 2; $prop[$rug] = 0; my($k) = int(($plac[$dragon] + $fixd[$dragon]) / 2); move($dragon+100,-1); move($rug+100,0); move($dragon,$k); move($rug,$k); for ($obj = 1; $obj <= 100; ++$obj) { move($obj,$k) if ($place[$obj] == $plac[$dragon] || $place[$obj] == $fixd[$dragon]); # L:9126 } $loc = $k; getnewloc($null); $showitems = $true; } sub pour { # L:9130 $obj = liq() if ($obj == $bottle || $obj == 0); if ($obj == 0) { what(); return; } if (!toting($obj)) { rspeak($spk); return; } $spk = 78; if ($obj != $oil && $obj != $water) { rspeak($spk); return; } $prop[$bottle] = 1; $place[$obj] = 0; $spk = 77; if (!(at($plant) || at($door))) { rspeak($spk); return; } if (!at($door)) { $spk = 112; if ($obj != $water) { rspeak($spk); return; } pspeak($plant,$prop[$plant]+1); $prop[$plant] = ($prop[$plant]+2) % 6; $prop[$plant2] = int($prop[$plant]/2); getnewloc($null); $showitems = $true; return; } # L:9132 $prop[$door] = 0; $prop[$door] = 1 if ($obj == $oil); $spk = 113+$prop[$door]; rspeak($spk); } sub eatnoobj { # L:8140 if (!here($food)) { what(); return; } # # Slightly different, but should be OK.... # $obj = $food; eat(); } sub eat { # L:9140 if ($obj == $food) { dstroy($food); $spk = 72; rspeak($spk); return; } $spk = 71 if ($obj == $bird || $obj == $snake || $obj == $clam || $obj == $oyster || $obj == $dwarf || $obj == $dragon || $obj == $troll || $obj == $bear); rspeak($spk); } sub drink { # L:9150 if ($obj == 0 && liqloc($loc) != $water && (liq() != $water || !here($bottle))) { what(); return; } $spk = 110 if ($obj != 0 && $obj != $water); if ($spk == 110 || liq() != $water || !here($bottle)) { rspeak($spk); return; } $prop[$bottle] = 1; $place[$water] = 0; $spk = 74; rspeak($spk); } sub rub { # L:9160 $spk = 76 if ($obj != $lamp); rspeak($spk); } sub throw { # L:9170 $obj = $rod2 if (toting($rod2) && $obj == $rod && !toting($rod)); if (!toting($obj)) { rspeak($spk); return; } if ($obj >= 50 && $obj <= $maxtrs && at($troll)) { # L:9178 $spk = 159; drop($obj,0); move($troll,0); move($troll+100,0); drop($troll2,$plac[$troll]); drop($troll2+100,$fixd[$troll]); juggle($chasm); rspeak($spk); return; } else { if ($obj == $food && here($bear)) { # L:9177 $obj = $bear; feed(); } else { discard() if ($obj != $axe); my($founddwarf) = $false; for ($i = 1; $i <= 5; ++$i) { if ($dloc[$i] == $loc) { $founddwarf = $true; last; } # L:9171 } if (!$founddwarf) { $spk = 152; if (at($dragon) && $prop[$dragon] == 0) { } else { $spk = 158; if (!at($troll)) { if (here($bear) && $prop[$bear] == 0) { # L:9176 $spk = 164; drop($axe,$loc); $fixed[$axe] = -1; $prop[$axe] = 1; juggle($bear); rspeak($spk); return; } $obj = 0; attack(); return; } } } else { # L:9172 $spk = 48; if (ran(3) == 0 || $saved != -1) { } else { $dseen[$i] = $false; $dloc[$i] = 0; $spk = 47; $dkill++; $spk = 149 if ($dkill == 1); } } # L:9175 rspeak($spk); drop($axe,$loc); getnewloc($null); $showitems = $true; return; } } } sub quit { # L:8180 $gaveup = yes(22,54,54); exitgame() if ($gaveup); } sub find { # L:9190 $spk = 94 if (at($obj) || (liq() == $obj && at($bottle)) || $obj == liqloc($loc)); for ($i = 1; $i <= 5; ++$i) { $spk = 94 if ($dloc[$i] == $loc && $dflag >= 2 && $obj == $dwarf); # L:9192 } $spk = 138 if ($closed); $spk = 24 if (toting($obj)); rspeak($spk); } sub inventory { # L:9190 $spk = 98; for ($i = 1; $i <= 100; ++$i) { if ($i == $bear || !toting($i)) { } else { rspeak(99) if ($spk == 98); $blklin = $false; pspeak($i,-1); $blklin = $true; $spk = 0; } # L:8201 } $spk = 141 if (toting($bear)); rspeak($spk); } sub feed { # L:9210 if ($obj == $bird) { $spk = 100; rspeak($spk); return; } # L:9212 if ($obj == $snake || $obj == $dragon || $obj == $troll) { $spk = 102; $spk = 110 if ($obj == $dragon && $prop[$dragon] != 0); $spk = 182 if ($obj == $troll); if ($obj != $snake || $closed || !here($bird)) { rspeak($spk); return; } $spk = 101; dstroy($bird); $prop[$bird] = 0; $tally2++; rspeak($spk); return; } # L:9213 if ($obj == $dwarf) { rspeak($spk); return if (!here($food)); $spk = 103; $dflag++; return; } # L:9214 if ($obj == $bear) { $spk = 102 if ($prop[$bear] == 0); $spk = 110 if ($prop[$bear] == 3); if (!here($food)) { rspeak($spk); return; } dstroy($food); $prop[$bear] = 1; $fixed[$axe] = 0; $prop[$axe] = 0; $spk = 168; rspeak($spk); return; } # L:9215 $spk = 14; rspeak($spk); } sub fill { # L:9220 if ($obj == $vase) { # L:9222 $spk = 29; $spk = 144 if (liqloc($loc) == 0); if (liqloc($loc) == 0 || !toting($vase)) { rspeak($spk); return; } rspeak(145); $prop[$vase] = 2; $fixed[$vase] = -1; # # This is not quite the same as goto 9024, but I think it # has the same result. # discard(); } else { if ($obj != 0 && $obj != $bottle) { rspeak($spk); return; } if ($obj == 0 && !here($bottle)) { what(); return; } $spk = 107; $spk = 106 if(liqloc($loc) == 0); $spk = 105 if(liq() != 0); if ($spk != 107) { rspeak($spk); return; } $prop[$bottle] = int(($cond[$loc] % 4) / 2) * 2; my($k) = liq(); $place[$k] = -1 if (toting($bottle)); $spk = 108 if ($k == $oil); rspeak($spk); } } sub blast { # L:9230 if ($prop[$rod2] < 0 || !$closed) { rspeak($spk); return; } $bonus = 133; $bonus = 134 if ($loc == 115); $bonus = 135 if (here($rod2)); rspeak($bonus); exitgame(); } sub score { # L:8240 getscore($true); # L:8243 printf "If you were to quit now, you would score %d out of a possible %d.\n", $score,$mxscor; $gaveup = yes(143,54,54); exitgame() if ($gaveup); } sub foo { # L:8250 my($k) = vocab($wd1,3); $spk = 42; if ($foobar != (1-$k)) { $spk = 151 if ($foobar != 0); rspeak($spk); return; } # L:8252 $foobar = $k; if ($k != 4) { sayok(); return; } $foobar = 0; if ($place[$eggs] == $plac[$eggs] || (toting($eggs) && $loc == $plac[$eggs])) { rspeak($spk); return; } $prop[$troll] = 1 if ($place[$eggs] == 0 && $place[$troll] == 0 && $prop[$troll] == 0); $k = 2; $k = 1 if (here($eggs)); $k = 0 if ($loc == $plac[$eggs]); move($eggs,$plac[$eggs]); pspeak($eggs,$k); } sub brief { # L:8260 $abbnum = 10000; $detail = 3; rspeak(156); } sub readnoobj { # L:8270 $obj = $magzin if (here($magzin)); $obj = $obj*100 + $tablet if (here($tablet)); $obj = $obj*100 + $messag if (here($messag)); $obj = $oyster if ($closed && toting($oyster)); if ($obj > 100 || $obj == 0 || dark()) { what(); return; } readit(); } # # Had to use readit to avoid clash with Perl's read command. # sub readit { # L:9270 if (dark()) { cantsee(); return; } $spk = 190 if ($obj == $magzin); $spk = 196 if ($obj == $tablet); $spk = 191 if ($obj == $messag); $spk = 194 if ($obj == $oyster && $hinted[2] && toting($oyster)); # # Should following be ...|| !$hinted[2] || ...???? # May as well duplicate bugs as well. # if ($obj != $oyster || $hinted[2] || !toting($oyster) || !$closed) { rspeak($spk); return; } $hinted[2] = yes(192,193,54); } sub break { # L:9280 $spk = 148 if ($obj == $mirror); if ($obj == $vase && $prop[$vase] == 0) { } else { if ($obj != $mirror || !$closed) { rspeak($spk); return; } rspeak(197); wakendwarves(); } # L:9282 $spk = 198; drop($vase,$loc) if (toting($vase)); $prop[$vase] = 2; $fixed[$vase] = -1; rspeak($spk); } sub wake { # L:9290 if ($obj != $dwarf || !$closed) { rspeak($spk); return; } rspeak(199); wakendwarves(); } sub suspend { my($d,$t); # L:8300 $spk = 201; if ($demo) { rspeak($spk); return; } # L:8302 printf "I can suspend your adventure for you so that you can " ."resume later, but\nyou will have to wait at least " ."%d minutes before continuing.\n", $latncy; if (!yes(200,54,54)) { return; } datime(\$saved,\$savet); if (!savegame()) { return; } ciao(); } # # Pretty obvious really.... only added this cos of the goto 5190 # in readit (9270) # sub cantsee { printf "I see no %s here.\n",$wd1; } # # getsecond moves the second word to the first for analysis # Analogous to L:2800 in original # sub getsecond { # L:2800 $wd1 = $wd2; $wd2 = ""; processwd1(); } # # getnewloc works out new location from current location "loc" and # verb "k". Note that $alive may be changed by this routine. # sub getnewloc { my($k) = @_; my($ll,$kk); $kk = $key[$loc]; $newloc = $loc; bug(26) if ($kk == 0); return if ($k == $null); if ($k == $back) { # L:20 $k = $oldloc; $k = $oldlc2 if (forced($k)); $oldlc2 = $oldloc; $oldloc = $loc; my($k2) = 0; if ($k == $loc) { rspeak(91); return; } # L:21 while ($true) { $ll = int(abs($travel[$kk])/1000) % 1000; if ($ll != $k) { if ($ll <= 300) { my($j) = $key[$ll]; $k2 = $kk if (forced($ll) && int(abs($travel[$j])/1000) % 1000 == $k); } # L:22 if ($travel[$kk] < 0) { # L:23 $kk = $k2; if ($kk == 0) { rspeak(140); return; } else { last; } } else { $kk++; } } } # L:25 $k = abs($travel[$kk]) % 1000; $kk = $key[$loc]; $oldlc2 = $oldloc; $oldloc = $loc; # L:23 } elsif ($k == $look) { # L:30 rspeak(15) if ($detail < 3); $detail++; $wzdark = $false; $abb[$loc] = 0; $showloc = $true; return; } elsif ($k == $cave) { # L:40 rspeak(57) if ($loc < 8); rspeak(58) if ($loc >= 8); return; } # L:9 do { $ll = abs($travel[$kk]); if ($ll % 1000 == 1 || $ll % 1000 == $k) { } else { if ($travel[$kk] < 0) { # L:50 $spk = 12; $spk = 9 if ($k >= 43 && $k <= 50); $spk = 9 if ($k == 29 || $k == 30); $spk = 10 if ($k == 7 || $k == 36 || $k == 37); $spk = 11 if ($k == 11 || $k == 19); $spk = 59 if ($verb == $find || $verb == $invent); $spk = 42 if ($k == 62 || $k == 65); $spk = 80 if ($k == 17); rspeak($spk); return; } $kk++; } } until ($ll % 1000 == 1 || $ll % 1000 == $k); # # OK. This takes some thinkin, but I'm pretty sure it's the same # logic as the original. As usual, tell me if I'm wrong. # # L:10 $ll = int($ll/1000); # # Need an additional "do" loop and variable to simulate "goto 12" # my($foundloc) = $false; # L:11 while ($true) { $newloc = int($ll/1000); $k = $newloc % 100; if ($newloc <= 300) { # L:13 if ($newloc <= 100) { # L:14 $foundloc = ($newloc == 0 || pct($newloc)); } else { $foundloc = (toting($k) || ($newloc > 200 && at($k))); } } else { $foundloc = ($prop[$k] != int($newloc/100)-3); } # L:16 if ($foundloc) { $newloc = $ll % 1000; return if ($newloc <= 300); if ($newloc > 500) { rspeak($newloc-500); $newloc = $loc; return; } # L:30000 $newloc -= 300; if ($newloc == 1) { # L:30100 $newloc = 99+100-$loc; return if ($holdng == 0 || ($holdng == 1 && toting($emrald))); $newloc = $loc; rspeak(117); return; } elsif ($newloc == 2) { # L:30200 drop ($emrald,$loc); # and continue loop to find new location. } elsif ($newloc == 3) { # L:30300 if ($prop[$troll] == 1) { pspeak($troll,1); $prop[$troll] = 0; move($troll2,0); move($troll2+100,0); move($troll,$plac[$troll]); move($troll+100,$fixd[$troll]); juggle($chasm); $newloc = $loc; return; } else { # L:30310 $newloc = $plac[$troll] + $fixd[$troll] - $loc; $prop[$troll] = 1 if ($prop[$troll] == 0); return if (!toting($bear)); rspeak(162); $prop[$chasm] = 1; $prop[$troll] = 2; drop($bear,$newloc); $fixed[$bear] = -1; $prop[$bear] = 3; # # spices wasnt initialised in the original .. see above # $tally2++ if ($prop[$spices] < 0); $oldlc2 = $newloc; $alive = $false; return; } } else {bug(20)} } # L:12 do { bug(25) if ($travel[$kk] < 0); $kk++; $newloc = int(abs($travel[$kk])/1000); } while ($newloc == $ll); $ll = $newloc; } # while true } sub wakendwarves { rspeak(136); exitgame(); } sub stop { die "Goodbye.\n"; } # # This used to be done in exitgame(), but it's neater(TM) this way. # Note that we still need the scorng variable here - 4 points are # added if you're exiting due to ill-health. # sub getscore { my($i,$k); my($scorng) = @_; # L:20000 $score = 0; $mxscor = 0; for ($i = 50; $i <= $maxtrs; ++$i) { if ($ptext[$i] != 0) { $k = 12; $k = 14 if ($i == $chest); $k = 16 if ($i > $chest); $score += 2 if ($prop[$i] >= 0); $score += ($k-2) if ($place[$i] == 3 && $prop[$i] == 0); $mxscor += $k; } # L:20010 } $score += (($maxdie-$numdie)*10); $mxscor += ($maxdie*10); $score += 4 if (!($scorng || $gaveup)); $mxscor += 4; $score += 25 if ($dflag != 0); $mxscor += 25; $score += 25 if ($closng); $mxscor += 25; if ($closed) { $score += 10 if ($bonus == 0); $score += 25 if ($bonus == 135); $score += 30 if ($bonus == 134); $score += 45 if ($bonus == 133); } # L:20020 $mxscor += 45; $score++ if ($place[$magzin] == 108); $mxscor++; $mxscor += 2; for ($i = 1; $i <= $hntmax; ++$i) { $score -= $hints[$i*4+2] if ($hinted[$i]); # L:20030 } } # # exitgame does the scoring / exit stuff. # sub exitgame { my($i,$k); getscore(); printf "You scored %d out of a possible %d using %d turns.\n", $score, $mxscor, $turns; for ($i = 1; $i <= $clsses; ++$i) { last if ($cval[$i] >= $score); # L:20200 } if ($cval[$i] >= $score) { # L:20210 speak($ctext[$cval[$i]]); if ($i != $clsses-1) { $k = $cval[$i]+1-$score; my($kk) = "s."; $kk = "." if ($k == 1); printf "To achieve the next higher rating, you need %d more point%s\n", $k,$kk; } else { # L:20220 print "To achieve the next higher rating would be a neat trick!\n"; print "Congratulations!!\n"; } } else { # L:20202 print "You just went off my scale!!\n"; } stop(); } # # The hint stuff was all nicely contained, so I put it all in # a separate sub. # sub checkhints { my($hint); for ($hint = 4; $hint <= $hntmax; ++$hint) { if (!$hinted[$hint]) { $hintlc[$hint] = -1 if (!bitset($loc,$hint)); $hintlc[$hint]++; if ($hintlc[$hint] >= $hints[$hint*4+1]) { showhint($hint-3); } } # L:2602 } } sub showhint { my($hint) = @_; my($zerohint); my($askhint); $zerohint = $true; # L:40000 if ($hint == 1) {$askhint = ($prop[$grate]==0 && !here($keys))} elsif ($hint == 2) { $askhint = (here($bird) && toting($bird) && $obj==$bird); $zerohint = $false; } elsif ($hint == 3) {$askhint = (here($grate) && !here($bird))} elsif ($hint == 4) {$askhint = ($atloc[$loc]==0 && $atloc[$oldloc]==0 && $atloc[$oldlc2]==0 && $holdng > 1)} elsif ($hint == 5) {$askhint = ($prop[$emrald]!=-1 && $prop[$pyram]==-1)} elsif ($hint == 6) {$askhint = $true} else {bug(27)} if ($askhint) { #L:40010 $hintlc[$hint] = 0; return if (!yes($hints[$hint*4+3],0,54)); #L:40012 printf "I am prepared to give you a hint, but it will cost you" ." %d points.\n", $hints[$hint*4+2]; $hinted[$hint] = yes(175,$hints[$hint*4+4],54); $limit = $limit+30*$hints[$hint*4+2] if ($hinted[$hint] && $limit>30); } $hintlc[$hint] = 0 if ($zerohint); } sub getnum { my $inp; while ($true) { $inp = ; chomp $inp; $inp = 0 if ($inp eq ""); last if ($inp =~ /[0-9]*/); printf "Please enter a number.\n"; } return $inp; } # # This converts between A5 format and integer # sub a5toi { my($str) = @_; my($num) = 0; return $num; } sub itoa5 { my($num) = @_; my($str) = ""; return $str; } ################################################################## # Original subroutines ################################################################## sub speak { my($n) = @_; return if ($n == 0); return if ($lines[$n] =~ /^>\$<.*/); # Original only checked 1st 5 chars print "\n" if ($blklin); print $lines[$n]; } sub pspeak { my($msg,$skip) = @_; my $m = $ptext[$msg]; if ($skip >= 0) { $m += ($skip + 1); } speak($m); } sub rspeak { my($i) = @_; speak($rtext[$i]) if ($i != 0); } sub mspeak { my($i) = @_; speak($mtext[$i]) if ($i != 0); } sub getin { my($word1,$word2) = @_; print "\n" if ($blklin); my $line; do { $line = ; chomp $line; } while ($line eq ""); if ($line =~ /\s*(.*)/) { $line = $1; } if ($line =~ /(\w*)\s(\w*).*/) { $$word1 = $1; $$word2 = $2; } else { $$word1 = $line; $$word2 = ""; } } sub yes { my($x,$y,$z) = @_; return yesx($x,$y,$z,\&rspeak); } sub yesm { my($x,$y,$z) = @_; return yesx($x,$y,$z,\&mspeak); } sub yesx { my($x,$y,$z,$spk) = @_; my($reply,$junk); &$spk($x); while ($true) { getin(\$reply,\$junk); $reply = uc($reply); if ($reply eq 'YES' || $reply eq 'Y') { &$spk($y); return $true; } if ($reply eq 'NO' || $reply eq 'N') { &$spk($z); return $false; } print "Please answer the question.\n"; } } sub vocab { my($id, $init) = @_; my($i); $id = substr(uc($id),0,5); for ($i = 1; $i <= $tabsiz && $ktab[$i] != -1; ++$i) { if ($init < 0 || int($ktab[$i]/1000) == $init) { last if ($atab[$i] eq $id); } } if ($i > $#ktab) { if ($init < 0) {return -1} bug(5); } my $voc = $ktab[$i]; $voc = ($voc % 1000) if ($init >= 0); return $voc; } sub dstroy { my($object) = @_; move($object,0); } sub juggle { my($object) = @_; my($i,$j); $i=$place[$object]; $j=$fixed[$object]; move($object,$i); move($object+100,$j); } sub move { my($object,$where) = @_; my($from); if ($object <= 100) { $from = $place[$object]; } else { # L:1 $from = $fixed[$object-100]; } # L:2 if ($from > 0 && $from <= 300) {carry($object,$from);} drop ($object,$where); } sub put { my($object,$where,$pval) = @_; move($object,$where); return (-1 - $pval); } sub carry { my($object,$where) = @_; my($temp); if ($object <= 100) { return if ($place[$object] == -1); $place[$object] = -1; $holdng++; } # L:5 if ($atloc[$where] == $object) { $atloc[$where] = $link[$object]; return; } # L:6 $temp = $atloc[$where]; until ($link[$temp] == $object) { # L:7 $temp = $link[$temp]; } # L:8 $link[$temp] = $link[$object]; } sub drop { my($object,$where) = @_; if ($object > 100) { # L:1 $fixed[$object-100] = $where; } else { $holdng-- if ($place[$object] == -1); $place[$object] = $where; } # L:2 return if ($where <= 0); $link[$object] = $atloc[$where]; $atloc[$where] = $object; } sub start { my($d,$t); my($primtm,$ptime,$hour); datime(\$d,\$t); $primtm = $wkday; # # Our day 0 was a Thursday... # $primtm = $wkend if ((($d+5) % 7) <= 1); $primtm = $holid if ($d >= $hbegin && $d <= $hend); $hour = int($t/60); $ptime = (bittest($primtm,$hour)); my($soon) = $false; if ($continued) { my($delay) = ($d - $saved) * 1440 + ($t - $savet); if ($delay < $latncy) { # L:10 printf "This adventure was suspended a mere %d minutes ago.\n",$delay; $soon = $true; if ($delay < int($latncy/3)) { mspeak(2); stop(); } } } # L:20 if (!$soon) { if (!$ptime) { # L:22 $saved = -1; return $false; } # L:25 mspeak(3); hours(); mspeak(4); if (wizard()) { # L:22 COPY $saved = -1; return $false; } if ($continued) { # L:33 COPY mspeak(9); stop(); } if (yesm(5,7,7)) { # L:22 COPY $saved = -1; return $true; } stop(); } # L:30 mspeak(8); if (wizard()) { $saved = -1; return $false; } # L:33 mspeak(9); stop(); } sub maint { my($d,$t); my($x); return if (!wizard()); $blklin = $false; hours() if (yesm(10,0,0)); newhrs() if (yesm(11,0,0)); if (yesm(26,0,0)) { mspeak(27); $hbegin = getnum(); mspeak(28); $hend = getnum(); datime(\$d,\$t); $hbegin += $d; $hend += ($hbegin-1); mspeak(29); $hname = ; chomp $hname; } # L:10 # L:12 printf "Length of short game (null to leave at %d):",$short; $x = getnum(); $short = $x if ($x > 0); mspeak(12); $x = ; chomp $x; $magic = $x if ($x ne ""); mspeak(13); $x = getnum(); $magnm = $x if ($x > 0); # L:16 printf "Latency for restart (null to leave at %d):",$latncy; $x = getnum(); mspeak(30) if ($x > 0 && $x < 45); $latncy = max(45,$x) if ($x > 0); motd($true) if (yesm(14,0,0)); $saved = 0; $abb[1] = 0; mspeak(15); $blklin = $true; savewiz(); ciao(); } sub wizard { my($wiz,$word,$d,$t,@val); my($x,$y,$z); $wiz = yesm(16,0,7); return ($wiz) if (!$wiz); mspeak(17); $word = ; chomp $word; if ($word eq $magic) { datime(\$d,\$t); $t = $t*2+1; $word = a5toi("@@@@@"); for ($y = 1; $y <= 5; ++$y) { $x = 79 + ($d % 5); $d = int($d/5); for ($z = 1; $z <= $x; ++$z) { # L:12 $t = ($t * 1027) % 1048576; } $val[$y] = int(($t*26)/1048576)+1; # L:15 $word += ($val[$y] << 36-7*$y); } if (!yesm(18,0,0)) { printf "%s\n",itoa5($word); $word = ; chomp $word; $word = a5toi($word); datime(\$d,\$t); $t = int($t/60)*40+int($t/10)*10; $d = $magnm; for ($y = 1; $y <= 5; ++$y) { $z = ($y % 5) + 1; $x = (abs($val[$y] - $val[$z]) * ($d % 10) + ($t % 10)) % 26 + 1; $t = int($t/10); $d = int($d/10); # L:19 $word -= ($x << 36-7*$y); } if ($word == a5toi("@@@@@") || $true) { mspeak(19); return $true; } } } # L:99 mspeak(20); return $false; } sub hours { my($d,$t); print "\n"; hoursx($wkday,"Mon - Fri:"); hoursx($wkend,"Sat - Sun:"); hoursx($holid,"Holidays: "); datime(\$d,\$t); return if ($hend < $d || $hend < $hbegin); if ($hbegin <= $d) { # L:5 printf "Today is a holiday, namely %s\n",$hname; return; } # L:10 $d = $hbegin - $d; $t = "Days,"; $t = "Day," if ($d == 1); # L:15 printf " The next holiday will be in %d %s namely %s\n",$d,$t,$hname; } sub hoursx { my($h,$day) = @_; my($first,$from,$till); $first = $true; $from = -1; if ($h == 0) { # L:2 printf " %s Open all day\n",$day; return; } # L:10 while ($true) { do { $from++; } while (bittest($h,$from)); if ($from > 24) { # L:20 printf " %s Closed all day\n",$day if ($first); return; } $till = $from; do { $till++; } while (!bittest($h,$till) && $till != 24); if ($first) { # L:16 printf " %10.10s %02d:00 to %02d:00\n",$day,$from,$till; } else { # L:18 printf " %02d:00 to %02d:00\n",$from,$till; } $first = $false; $from = $till; } } sub newhrs { mspeak(21); $wkday = newhrx("Weekdays:"); $wkend = newhrx("Weekends:"); $holid = newhrx("Holidays:"); mspeak(22); hours(); } sub newhrx { my($day) = @_; my($newh) = 0; my($from,$till); # L:1 printf "Prime time on %s\n",$day; while ($true) { # L:10 print "from: "; $from = getnum(); return ($newh) if ($from < 0 || $from >= 24); # L:4 print "till: "; $till = getnum(); $till--; return ($newh) if ($till < $from || $till >= 24); for ($i = $from; $i <= $till; ++$i) { $newh += (1 << $i); # L:5 } } } sub motd { my($alter) = @_; my($d,$t); if (!$alter) { datime(\$d,\$t); if ($d == $msgday) { print $msg; } return; } # L:50 my($m) = 1; my($line); mspeak(23); do { $line = ; chomp $line; if ($line ne "") { if (length($line) > 70) { mspeak(24); next; } $msg .= "$line\n"; $m++; } } until ($line eq "" || $m > 15); if ($m > 15) { mspeak(25); } } sub initwiz { $wkday = 00777400; # Hour mask - if bit set, that hour is prime-time. $wkend = 0; $holid = 0; $hbegin = 0; $hend = -1; $short = 30; $magic = "DWARF"; $magnm = 11111; $latncy = 90; $msgday = -1; $msg = ""; } sub ran { my($range) = @_; my($d,$t); $d = 1; if (!(defined $r)) { datime(\$d,\$t); $r = 18*$t+5; $d = 1000 + ($d % 1000); } for ($t=1; $t <= $d; ++$t) { $r = ($r * 1021) % 1048576; } return int(($range * $r) / 1048576); } # # In the original, d was days since 1-1-77. It was easier just to # use days since 1-1-70, cos thats what most unices return in time(). # NOTE: This is in GMT!! The horrendous code is there to convert from # GMT to local time. Is there no easy way to do this? # sub datime { my($d,$t) = @_; my($sec1,$min1,$hour1,$mday1,$mon1,$year1,$wday1,$yday1,$isdst1) = gmtime(); my($sec2,$min2,$hour2,$mday2,$mon2,$year2,$wday2,$yday2,$isdst2) = localtime(); my $hdiff = 0; $hour2 -= 24 if ($yday2 == $yday1-1 || $year2 < $year1); $hour2 += 24 if ($yday2 == $yday1+1 || $year2 > $year1); $hdiff = $hour2 - $hour1; my $now = time() + $hdiff * 3600; $$d=int($now / 86400); $$t=int(($now % 86400) / 60); } sub ciao { my($k) = 32; my($a,$b); mspeak($k); if ($k == 31) { getin(\$a,\$b); } stop(); } sub bug { my($num) = @_; die "Fatal error, see source code for interpretation.\n" ."Probable cause: erroneous info in database.\n" ."Error code = $num.\n"; }