/*
 *      ADVACT2.C - Collosal Cave Adventure action routines, module #2
 *      (C) 1986 Ravi Bhavnani
 *      All rights reserved
 *
 *      jump_proc()             jumper          :   refer to travel()
 *      climb_proc()            climber         :   when coding these
 *      swim_proc()             Mark Spitz      :   3 routines
 *
 *	plunge()		called by jump_proc()
 *      kill_proc()             kill a mortal
 *      fill_proc()             fill a container
 *      peruse_proc()           read something
 *      break_proc()            break an object
 *      ride_proc()             ride Darwin
 *      scream_proc()           holler
 *      mist_proc()             misty stuff
 *      fix_proc()              repair an object
 *      wizard_proc()           is he a wizard?
 *      blast_proc()            tnt
 *	push_proc()		push/pull
 */

#include "adv.h"


plunge()
/*
 *	CALLED BY jump_proc() EVERYTIME THE ADVENTURER JUMPS INTO A BOTTOMLESS PIT.
 */
{
	dbg ("plunge()\n");

	here = ylem;
	if (val[lamp]==1)
	   {
	     lamplife = 0;
	     msay (carrying(lamp) ? fallandstarve : fallandstarved);
	   }
	else
	   msay (fallandstarved);

	finis();
	exit();
}


push_proc()
{
	dbg ("push_proc()\n");

	if (inword == 1 || !isobj(arg2))
	   msay (what);
	else
	   if (mortal[arg2])
	      msay (chance(50) ? hah : beserious);
	   else
	      if (arg2 != stove)
	         msay (what);
	      else
	         if (val[mushroom]==2 || val[food]==1)	/* eaten */
	            {
	              if (!val[stove])	/* covering trapdoor */
	                 {
	                   osay (stove, 1);
	                   val[stove] = 2;
	                 }
	              else
	                 {
	                   osay (stove, 3);
	                   val[stove] = 0;
	                 }
	              invisible[trapdoor] = !invisible[trapdoor];
	            }
	         else
	            msay (stove_rocks);
	RETURN;
}


jump_proc()
{
int	derf,
	bar;

	dbg ("jump_proc()\n");

	prevloc = here;
	switch (here)
	{
	  case nslope:
	    here = pathway;
	    moved = 1;
	    break;

	  case westoffissur:
	    ok2desc = 0;
	    if (val[fissure]==1)
	       msay (trythebridge);
	    else
	       {
	         here = cavern;
	         splatter();
	         coroner();	/* Bug fix - see note 270.0 */
		 RETURN;	/* Bug fix - see note 270.0 */
	       }
	    break;

	  case window:
	  case window2:
	    msay (brokenneck);
	    here = mirrorcnyn;
	    coroner();
	    RETURN;

	  case cavern:
	    ok2desc = 0;
	    if (query(whirlpool))
	       {
	         for (bar=0,derf=MINOBJECTS; (derf<=MAXOBJECTS); derf++)
	             if (carrying(derf) && derf!=lamp)
	                {
	                  apport (derf, limbo);
	                  bar++;
	                }
	         invct = 0;
	         if (carrying(lamp))
	            {
	              invct = 1;
	              msay (bar ? flow_rip : flow_down);
	            }
	         else
	            msay (bar ? flow_d_rip : flow_dark);
	         here = reservoir_n;
	         msay (whirl_land);
	       }
	    break;

	  case misty:
	    here = cavern;
	    splatter();
	    coroner();
	    break;

	  case stalact:
	    here = mazea_12;
	    break;

	  case balcony:
	  case breathtaker:
	    here = ylem;
	    splatter();
	    coroner();
	    RETURN;

	  case swofchasm:
	  case neofchasm:
	    ok2desc = 0;
	    if (val[chasm]==0)
	       msay (trythebridge);
	    else
	       {
	         here = ylem;
	         splatter();
	         coroner();
	         RETURN;
	       }
	    break;

	  case brink_1:
	  case brink_2:
	  case brink_3:
	    plunge();
	    break;

	  case platform:
	    msay (sizzle);
	    here = ylem;
	    coroner();
	    RETURN;

	  default:
	    if (chance(50))
	       silly_proc();
	    else
	       msay (chance(50) ? cantapply : nojumping);
	    ok2desc = 0;
	    break;
	}

	RETURN;
}


climb_proc()
{
	dbg ("climb_proc()\n");

	prevloc = here;
	switch (here)
	{
	  case nslope:
	    here = pathway;
	    break;

	  case westpit:
	    if (val[plant]==0)
	       msay (noclimbup);
	    else
	       {
	         msay (val[plant]==2 ? shortplant : longplant);
	         ok2desc = 0;
	         here = (val[plant]==2 ? wend2pit : narrowcorrid);
	       }
	    break;

	  case narrowcorrid:
	    here = westpit;
	    break;

	  case brink:
	    here = streampit;
	    break;

	  case streampit:
	    here = brink;
	    break;

	  case wendmists:
	    here = mazea_1;
	    break;

	  case mazea_16_pit:
	    here = birdchamber;
	    break;

	  case complex:
	    here = dusty;
	    break;

	  case slab:
	    here = secretnscyn;
	    break;

	  case incline:
	    msay (oof);
	    here = low;
	    ok2desc = 0;
	    break;

	  case stalact:
	    here = mazea_12;
	    break;

	  case breathtaker:
	    here = ylem;
	    splatter();
	    coroner();
	    RETURN;

	  case slide:
	    msay (slide_slippery);
	    ok2desc = 0;
	    break;

	  case shelf:
	    here = beach;
	    break;

	  case beach:
	    here = shelf;
	    val[dinghy] = 1;
	    break;

	  case chimney:
	    here = tube;
	    break;

	  case tube:
	    here = chimney;
	    break;

	  case basque_fork:
	    here = on_steps;
	    break;

	  case platform:
	    msay (sizzle);
	    here = ylem;
	    coroner();
	    RETURN;

	  case forest:
	  case forest2:
	    msay (inforest);
	    break;

	  default:
	    ok2desc = 0;
	    msay (cantapply);
	    break;
	}

	moved = (here != prevloc);
	RETURN;
}


swim_proc()
{
	dbg ("swim_proc()\n");
        msay (iamgame);
	RETURN;
}


kill_proc()
{
int     derf;

	dbg ("kill_proc()\n");

        if (inword == 1)
           {
             derf = -1;
             for (thing=MINOBJECTS; (thing <= MAXOBJECTS); thing++)
                 if (mortal[thing] && near(thing))
                    if (derf == -1)
                       derf = thing;
                    else
                       if (derf < 0)
                          derf = -2;

             if (derf == -1)
                {
                  msay (pacifist);
                  RETURN;
                }
             if (derf == -2)
                {
                  mword (clarify, kill);
                  RETURN;
                }
             arg2 = derf;
           }

        if (!near(arg2))
           mword (idontsee, arg2);
        else
           if (!mortal[arg2])
              msay (hah);
           else
              switch (arg2)
              {
                case troll:
                  msay (troll_data);
                  break;

                case dwarf:
                  if (query(withwhat))
                     {
                       derf = (strength - invct + 2) * 10;

/* KILLING A DWARF WITH YOUR BARE HANDS MADE THE GAME TOO EASY.
 *
 *	               if (chance (derf))
 *                        {
 *	                    msay (killeddwarf);
 *	                    dwarfcount--;
 *	                    if (--dwarrows == 0)
 *	                       apport (dwarf, limbo);
 *	                  }
 *	               else
 */
                          if (chance(derf))
                             msay (dwarfdodges);
                          else
                             {
                               msay (dwarfstabs);
                               coroner();
	                       RETURN;
                             }
                     }
                  else
                     msay (ok);
                  break;

                case dragon:
                  if (val[dragon] > 0)
                     msay (it_is_dead);
                  else
                     if (query(withwhat))
                        {
                          val[dragon] = 1;              /* dying dragon's */
                          osay (dragon, 1);             /* teeth fall out */
                          val[dragon] = 2;              /* dead dragon */
                          val[rug]=1;			/* rug can be taken */
                          apport (teeth, here);		/* so can teeth */
                        }
                     else
                        msay (ok);
                  break;

                case snake:
                  msay (cantkillsnake);
                  break;

                case blob:
                  msay (bounce_blob);                  
                  break;

                case bear:
                  if (!val[bear])
                     msay (kill_bear);
                  else
                     msay (bear_puzzled);
                  break;

                case clam:
                case oyster:
                  msay (kill_oyster);
                  break;

                case ogre:
                  if (query(withwhat))
                     if (chance(50))
                        msay (ogre_too_tough);
                     else
                        {
                          msay (ogre_rips_head_off);
                          coroner();
	                  RETURN;
                        }
                  else
                     msay (ok);
                  break;

                case bird:
                  if (closure < 3)
                     {
                       apport (bird, limbo);
                       msay (birdisdead);
                     }
                  else
                     msay (leave_bird);
                  break;

                case djinn:
                  msay (tough_djinn);
                  break;

                case goblins:
                  msay (kill_goblins);
                  coroner();
	          RETURN;
                  break;

                case basilisk:
                  if (val[basilisk] < 2)
                     {
                       msay (hit_basilisk);
                       coroner();
	               RETURN;
                     }
                  else
                     msay (it_is_dead);
                  break;

                case gong:
                  if (near(turtle))
                     msay (gong_rings);
                  else
                     {
                       msay (gong_fetch);
                       apport (turtle, here);
                     }
                  break;

                case turtle:
                  msay (beserious);
                  break;

                default:
                  printf ("GLITCH!  kill_proc() called with mortal %d\n", arg2);
                  break;
              }
	RETURN;
}


fill_proc()
{
	dbg ("fill_proc()\n");

        if (inword == 1)
           {
	     context = fill;
             mword (clarify, fill);
             RETURN;
           }
        if (!isobj(arg2))
           msay (what);
        else
           if (!near(arg2))
              mword (idontsee, arg2);
           else
              if (mortal[arg2])
                 msay (repulsive);
              else
                 switch (arg2)
                 {
                   case bottle:
                     if (val[bottle] == 1)
                        if (h2ohere[here])
                           {
                             msay (bottle_h2o);
                             val[bottle] = 0;
                             if (carrying(bottle))
                                getit (water);
                           }
                        else
                           if (at(eastpit))
                              {
                                msay (bottle_oil);
                                val[bottle] = 2;
                                if (carrying(bottle))
                                   getit (oil);
                              }
                           else
                              msay (nothing2fill);
                     else
                        msay (bottlewasfull);
                     break;

                   case vase:
                     if (h2ohere[here] || at(eastpit))
                        {
                          msay (shatter_vase);
                          apport (vase, limbo);
                          apport (shards, here);
                        }
                     else
                        msay (nothing_vase);
                     break;

                   default:
                     msay (cantfillthat);
                     break;
                 }
	RETURN;
}


peruse_proc()
{
	dbg ("peruse_proc()\n");

        if (inword == 1)
           {
	     context = peruse;
             mword (clarify, peruse);
             RETURN;
           }

        if (!isobj(arg2))
           msay (what);
        else
           if (!near(arg2) || invisible[arg2])
              mword (idontsee, arg2);
           else
	      if (mortal[arg2])
	         msay (hah);
	      else
                 switch (arg2)
                 {
	           case scroll:
		     if (val[scroll] == 1)
		        msay (cant_read_scroll);
		     else
		        msay (read_scroll);
	             break;

                   case magazines:
                     msay (mag_dwarvish);
                     break;

                   case message:
                     msay (chest_elsewhere);
                     break;

                   case tablet:
                     msay (dark_room);
                     break;

                   case machine:
                     msay (machine_sign);
                     break;

                   default:
                     mword (dunno_hao, peruse);
                     break;
                 }
	RETURN;
}


break_proc()
{
	dbg ("break_proc()\n");

        if (inword == 1)
           {
             context = breakit;
             mword (clarify, breakit);
           }
        else
           if (!isobj(arg2))
              msay (what);
           else
              if (!near(arg2) && (arg2!=mirror))
                 mword (idontsee, arg2);
              else
                 if (mortal[arg2] || arg2==shards)
                    if (chance(75))
                       msay (beserious);
                    else
                       msay (iamgame);
                 else
                    switch (arg2)
                    {
	              case mirror:
	                if (near(mirror))
	                   osay (mirror, val[mirror]);
	                else
	                   if (near(mirror2))
	                      if (carrying(axe) || carrying(shovel) || carrying(sword))
	                         if (val[mirror2])
	                            msay (nothing);
	                         else
	                            {
	                              osay (mirror2, val[mirror2]);
	                              val[mirror2] = 1 + random(2);
	                              osay (mirror2, val[mirror2]);
	                              nodesc [mirror2] = 0;
	                            }
	                      else
	                         msay (iamgame);
	                   else
	                      mword (idontsee, mirror);
	                break;

                      case vase:
                        msay (throw_vase);
                        apport (vase, limbo);
                        apport (shards, here);
                        break;
                      case vial:
                        break_vial();
                        break;
                      default:
                        msay (no_can_fix);
                        break;
                    }
	RETURN;
}



ride_proc()
{
	dbg ("ride_proc()\n");

        if (inword==1)
           if (near(turtle))
              arg2 = turtle;
           else
              {
                msay (nothing2ride);
                RETURN;
              }

        if (!isobj(arg2))
           msay (what);
        else
           if (!near(arg2))
              mword (idontsee, arg2);
           else
              if (arg2 == turtle)
                 {
                   msay (turtle_back);
                   here = reservoir;
                   apport (turtle, limbo);
                   moved = 1;
                 }
              else
                 if (arg2==dwarf || arg2==troll || arg2==pirate ||
                     arg2==ogre  || arg2==goblins || arg2==djinn)
                    msay (repulsive);
                 else
                    msay (iamgame);
	RETURN;
}


scream_proc()
{
	dbg ("scream_proc()\n");

        if (inword == 2)
           {
             strupr (word2);
             say_proc();
             RETURN;
           }
        if (chance(30))
           printf ("Aaaaaaaaaaaaaargh!  (I hope you're enjoying yourself)\n");
        else
           if (chance(50))
              printf ("Aiiiiiieeeeeeeeeeee!  (My, aren't we having fun)\n");
           else
              printf ("Eeeeeeeeeeeeeeeek!  (Oh boy, we have a live one here)\n");
	RETURN;
}


mist_proc()
{
	dbg ("mist_proc()\n");

	if (at(pit) || at(mists) || at(eastoffissur) || at(westoffissur) ||
	    at(window) || at(window2) || at(wendmists) || at(misty) ||
	    at(mirrorcnyn) || at(reservoir) || at(reservoir_n) || at(warm) ||
	    at(swofchasm) || at(neofchasm))
	   msay (thisismist);
	else
	   mword (idontsee, mist);
	RETURN;
}


fix_proc()
{
	dbg ("fix_proc()\n");

        if (inword == 1)
           {
             mword (clarify, fix);
             RETURN;
           }

        if (!isobj(arg2))
           msay (what);
        else
           if (arg2!=vase && !near(arg2))
              mword (idontsee, arg2);
           else
              if (mortal[arg2])
                 msay (beserious);
              else
                 if (arg2==vase || arg2==shards)
                    if (near(vase) || near(shards))
                       msay (no_can_fix);
                    else
                       mword (idontsee, arg2);
                 else
                    mword (dunno_hao, fix);
	RETURN;
}


wizard_proc()
{
char    wizardpwd[64];
int     derf;

	dbg ("wizard_proc()\n");

        if (olorin)
           {
             olorin = 0;
             msay (ok);
             RETURN;
           }
        else
           if (inword!=1 || nturns>5)
              {
                msay (magickword);
                RETURN;
              }

        if (query(r_u_a_wizard))
           {
             msay (prove_it);
             printf ("> ");
	     gets (wizardpwd);

/*
             if (!strcmp(wizardpwd, realthing))
                {
                  msay (so_you_are);
                  olorin = 1;
                  demo = 0;
                }
             else
*/

                {
                  msay (oh_pooh);
                  penalties += 10;
                }
           }
        else
           msay (ok);
	RETURN;
}


blast_proc()
{
	dbg ("blast_proc()\n");

        if (inword != 1)
           msay (what);
        else
           msay (needdynamite);
	RETURN;
}
