<?php
/*	program DATABASE.C					*\
\*	WARNING: "advent.c" allocates GLOBAL storage space by	*\
\*		including "advdef.h".				*\
\*		All other modules use "advdec.h".		*/


//#include	"stdio.h"	/* drv = 1.1st file 2.def 3.A	*/
//#include	"advent.h"
//#include	"advdec.h"

//extern	long	atoi();
//extern	int	fgetc();
//extern	char	*fgets();
//extern	int	fputc();
//extern	long	fseek();
//extern	char	*rindex();
//extern	char	*strcpy();
//extern	int	tolower();


/*
	Routine to fill travel array for a given location
*/
function gettrav($loc)
{

global $cave,$MAXTRAV,$MAXLOC,$traveltcond,$traveltverb,$traveltdest,$dbugflg;

  $atrv="";
  $trav=array();
  $i=$j=$k=$t=0;
  
  $atrav=$cave[$loc-1];
  $trav=explode(",",$atrav);

  foreach ($trav as $dir) {
      $traveltcond[$i]=($dir % 1000);
      $dir/=1000;
      $traveltverb[$i]=($dir % 1000);
      $dir/=1000;
      $traveltdest[$i]=($dir % 1000);
      $i+=1;
      $j=$i;
  }
  $traveltdest[$i] = -1; /* end of array */
  if ($dbugflg)
    for ($j=0;$j<=$MAXTRAV;$j++)
      printf("cave[%d] = %d %d %d (dest,verb,cond)<br>", 
       $loc, $traveltdest[$j], 
       $traveltverb[$j], $traveltcond[$j]);
}

/*
	Function to scan a file up to a specified
	point and either print or return a string.
*/
function rdupto($fdi, $uptoc, $print, $string)
{
	$c=0;$string="";

	while (($c = fgetc($fdi)) != $uptoc) {
		if ($c=='\r')
			continue;
		elseif (feof($fdi))
		        continue;
		$string.= $c;
	}
	if (!$print) return($string);
	else buffprint($string); buffprint("\n");
}

/*
	Function to read a file skipping
	a given character a specified number
	of times, with or without repositioning
	the file.
*/
function rdskip($fdi, $skipc, $n, $rewind)
{
global $dbugflg;
	$c=0;$on=$n;

	if ($rewind)
		if (fseek($fdi, 0, SEEK_SET) == -1)
			bug(31);
	while ($n--)
		while (($c = fgetc($fdi)) != $skipc)
			if (feof($fdi)) {
			        print "rdskip(fdi,skipc,n,rewind)= $fdi,$skipc,$on,$rewind)<br>";
				bug(32);
				}
}

/*
	Routine to request a yes or no answer to a question.
*/
function yes($msg1, $msg2, $msg3)
{
global	$yesno,$PHP_SELF,$words;

// $yesno is input from a form - if its not defined then we're asking the question rather
// than processing the answer

if (!$yesno) {
  if ($msg1)
    rspeak($msg1);
  // print a HTML form to get a yes/ no answer. We include the current user input so this is past
  // to the next session which should cause the engine to ask the same yes/no question again and
  // get the answer
  print "<body onload=\"document.ynform.yesno.focus()\">".
        "<form name=ynform method=post action=$PHP_SELF>Yes or No? <input name=yesno length=80><input type=hidden name=words value=\"$words\"></form></body>";
  return array(0,0);
}
  buffprint ("Yes or No? $yesno\n");
	if (substr(strtolower($yesno),0,1) == 'n') {
		if ($msg3)
			rspeak($msg3);
		return array(1,0);
	}
	if ($msg2)
		rspeak($msg2);
	return array(1,1);
}

/*
	Print a location description from "advent4.txt"
*/
function rspeak($msg)
{
global $fd4,$idx4,$dbugflg;
	if ($msg == 54) {
		buffprint("ok.");buffprint("\n");
	}
	else {  
		if ($dbugflg)
		    buffprint(sprintf("rspeak: Seek loc msg #%d @ %ld<br>", $msg, $idx4[$msg]));
		fseek($fd4, $idx4[$msg], SEEK_SET);
		rdupto($fd4, '#', 1, 0);
	}
	return;
}

/*
	Print an item message for a given state from "advent3.txt"
*/
function pspeak($item, $state)
{
global $fd3,$idx3,$dbugflg;

        if ($dbugflg)
		    buffprint(sprintf("pspeak: Seek loc msg #%d @ %ld<br>", ($state+2), $idx3[$item]));
    	fseek($fd3, $idx3[$item], SEEK_SET);
	rdskip($fd3, '/', $state+2, 0);
	rdupto($fd3, '/', 1, 0);
}

/*
	Print a long location description from "advent1.txt"
*/
function desclg($loc)
{
global $fd1,$idx1;

	fseek($fd1, $idx1[$loc], SEEK_SET);
	rdupto($fd1, '#', 1, 0);
}

/*
	Print a short location description from "advent2.txt"
*/
function descsh($loc)
{
global $fd2,$idx2;
	fseek($fd2, $idx2[$loc], SEEK_SET);
	rdupto($fd2, '#', 1, 0);
}

/*
	look-up vocabulary word in lex-ordered table.  words may have
	two entries with different codes. if minimum acceptable value
	= 0, then return minimum of different codes.  last word CANNOT
	have two entries(due to binary sort).
	word is the word to look up.
	val  is the minimum acceptable value,
		if != 0 return %1000
*/
function vocab($word,$val) {
global $wc,$MAXWC;

        $v1=$v2=0;

	if (($v1 = binary($word, $wc, $MAXWC)) >= 0) {
		$v2 = binary($word, $wc, $MAXWC-1);
		list($v1word,$v1acode)=explode("#",$wc[$v1]);
		list($v2word,$v2acode)=explode("#",$wc[$v2]);
		if ($v2 < 0)
			$v2 = $v1;
		if (!$val)
			return($v1acode < $v2acode? $v1acode : $v2acode);
		if ($val <= $v1acode)
			return($v1acode % 1000);
		else if ($val <= $v2acode)
			return($v2acode % 1000);
		else
			return(-1);
	}
	else
		return(-1);
}


function binary($w, $wctable, $max)
{
	$lo= $mid= $hi= $check=0;

	$lo = 0;
	$hi = $max - 1;
	while ($lo <= $hi) {
		$mid = round(($lo + $hi) / 2);
		list($word,$acode)=explode("#",$wctable[$mid]);
		if (($check = strcmp($w, $word)) < 0)
			$hi = $mid - 1;
		else if ($check > 0)
			$lo = $mid + 1;
		else
			return($mid);
	}
	return(-1);
}


/*
	Utility Routines
*/

/*
	Routine to test for darkness
*/
function dark()
{
global $cond,$LIGHT,$prop,$LAMP,$dbugflg,$loc,$place;
  if ($dbugflg) print "cond[$loc]&LIGHT=".($cond[$loc]&$LIGHT).", prop[LAMP]=".($prop[$LAMP]).",here(LAMP)=".(here($LAMP)).",place[LAMP]=".($place[$LAMP])."<br>";
	return(!($cond[$loc] & $LIGHT) &&
		(!$prop[$LAMP] ||
		!here($LAMP)));
}

/*
	Routine to tell if an item is present.
*/
function here($item)
{
global $place,$loc;
global $dbugflg;
	if ($dbugflg) print "place[$item]=".($place[$item])."<br>";
	return($place[$item] == $loc || toting($item));
}

/*
	Routine to tell if an item is being carried.
*/
function toting($item)
{
global $place;
	return($place[$item] == -1);
}

/*
	Routine to tell if a location causes
	a forced move.
*/
function forced($atloc)
{
global $cond;
	return($cond[$atloc] == 2);
}

/*
	Routine true x% of the time.
*/
function pct($x)
{
	return(rand(0,100) < $x);
}

/*
	Routine to tell if player is on
	either side of a two sided object.
*/
function at($item)
{
global $place,$fixed,$loc;
	return($place[$item] == $loc || $fixed[$item] == $loc);
}

/*
	Routine to destroy an object
*/
function dstroy($obj)
{
	move($obj, 0);
}

/*
	Routine to move an object
*/
function move($obj, $where)
{
global $MAXOBJ,$place,$fixed;
	$from=0;

	$from = ($obj<$MAXOBJ) ? $place[$obj] : $fixed[$obj];
	if ($from>0 && $from<=300)
		carry($obj, $from);
	drop($obj, $where);
}

/*
	Juggle an object
*/
function juggle($object)
{
//  JUGGLE AN OBJECT BY PICKING IT UP AND PUTTING IT DOWN AGAIN, THE PURPOSE
//  BEING TO GET THE OBJECT TO THE FRONT OF THE CHAIN OF THINGS AT ITS LOC.
      $i=$place[$object];
      $j=$fixed[$object];
      move($object,$i);
      move($object+100,$j);
 }

/*
	Routine to carry an object
*/
function carry($obj, $where)
{
global $MAXOBJ,$place,$holding,$dbugflg;
	if ($obj<$MAXOBJ){
		if ($place[$obj] == -1)
			return;
		$place[$obj]=-1;
		++$holding;
	        if ($dbugflg) print "carry(obj,where)=($obj,$where),place[obj]=".($place[$obj])."<br>";
	}
}

/*
	Routine to drop an object
*/
function drop($obj, $where)
{
global $MAXOBJ,$holding,$place,$fixed,$WATER,$OIL;
	if ($obj<$MAXOBJ) {
		if ($place[$obj] == -1 
		    && ($obj != $WATER && $obj != $OIL)) // bug fix Matt Cox: don't decrement count for Oil/ water
			--$holding;
		$place[$obj]=$where;
	}
	else
		$fixed[$obj-$MAXOBJ]=$where;
}

/*
	routine to move an object and return a
	value used to set the negated prop values
	for the repository.
*/
function put($obj, $where, $pval)
{
	move($obj, $where);
	return((-1)-$pval);
}
/*
	Routine to check for presence
	of dwarves..
*/
function dcheck()
{
global $DWARFMAX,$dloc,$loc;
	$i=0;
	for ($i =1; $i < ($DWARFMAX-1); ++$i)
		if ($dloc[$i] == $loc)
			return($i);
	return(0);
}

/*
	Determine liquid in the bottle
*/
function liq()
{
global $prop,$BOTTLE;
	$i= $j=0;
	$i=$prop[$BOTTLE];
	$j=-1-$i;
	$result=(liq2($i>$j ? $i : $j));
	return $result;
}

/*
	Determine liquid at a location
*/
function liqloc($loc)
{
global $cond,$loc,$LIQUID,$WATOIL;
	if ($cond[$loc]&$LIQUID)
		return(liq2($cond[$loc]&$WATOIL));
	else
		return(liq2(1));
}

/*
	Convert  0 to WATER
		 1 to nothing
		 2 to OIL
*/
function liq2($pbottle)
{
global $WATER,$OIL;
	return((1-$pbottle)*$WATER+($pbottle>>1)*($WATER+$OIL));
}

/*
	Fatal error routine
*/
function bug($n)
{
	die("Fatal error number $n");
}


	
function buffprint($s) {
global $screen,$MAXSCREEN,$caveid;
 $line=$screen[$MAXSCREEN];
 $line.=$s;
 $screen[$MAXSCREEN]=$line;
 
 if ($s=="\n") {
   for ($i=2;$i<=$MAXSCREEN;$i++)
     $screen[$i-1]=$screen[$i];
   print nl2br($screen[$MAXSCREEN-1]);
   $screen[$MAXSCREEN]="";
 }
 $arrscreen=implode("¬",$screen);
 str_replace(",","~",$arrscreen);
 $arrscreen=addslashes($arrscreen);    
 $query="UPDATE cave SET screen='$arrscreen' WHERE id=$caveid";
 $result=MYSQL_QUERY($query); print MYSQL_ERROR();

}
function dumpscreen() {
global $screen;
 foreach($screen as $line) print nl2br($line);
}
?>
