// Main2.cpp : Third of 3 mainline functions
//
// Public functions:
//    main2
//    hintLogic
//    mistProc
//
// Private functions:

#include "stdafx.h"

#include "AdvIO.h"
#include "AdvMain.h"
#include "AdvUtil.h"
#include "DoVerb.h"
#include "Magician.h"
#include "Retort.h"
#include "Travel.h"
#include "Utilitarian.h"

/////////////////////
// Forward references

///////////////////
// Public functions

void hintLogic
  (AdvGlobalContext& gc)   // global context
//
//  Decides whether to offer a hint.
//
{
long  nHint;    // hint message

  gc.m_nHintTime = 0;
  nHint = 0;

  // Determine hint that will be offered
  if (at (depression) && (gc.m_nState [grate] == 0) && !carrying (keys))
     nHint = lookingcave;
  if (at (birdchamber) && near (bird) && (gc.m_nState [bird] == 0) && carrying (rod))
     nHint = birdhint;
  if (at (mtking) && near (snake) && !near (bird))
     nHint = getpastsnake;
  if (at (wittsend))
     nHint = hint_witts;
  if ((at (plover) || at (alcove) || at (dark)) && !gc.m_visited [dark])
     nHint = hint_plover;
  if (at (plain_2))
     nHint = plain_hint;
  if (gc.m_inMaze [gc.m_nHere])
     nHint = hint_maze;
  if ((gc.m_nHere >= slide) && (gc.m_nHere <= icecave_30))
     nHint = ice_hint;
  if (at (nearstove))
     nHint = stove_hint;
  if (at (mirrorroom))
     nHint = mirror_hint;

  // If a hint can be offered ...
  if (nHint != 0)
     {
       if (gc.m_nArg1 != hint)
          sayMessage (gc, blank);

       // If he wants the offered hint ...
       if (yes (gc, nHint))
          {
            // And is willing to lose points for it ...
            sayMessageValue (gc, ill_give_hint, HINTCOST);
            if (yes (gc, want_hint))
               {
                 // Display the hint
                 sayMessage (gc, nHint + 1);

                 // Reduce his score
                 gc.m_nPenalties += HINTCOST;
                 gc.m_hintable [gc.m_nHere] = false;

                 // Reset hintable states so we don't repeat the offer
                 if (at(plover) || at(alcove) || at(dark))
                    {
                      gc.m_hintable [plover] = false;
                      gc.m_hintable [alcove] = false;
                      gc.m_hintable [dark] = false;
                    }

                 if (gc.m_inMaze [gc.m_nHere])
                    for (long nLocation = ylem; (nLocation < limbo); nLocation++)
                        if (gc.m_inMaze [nLocation])
                           gc.m_hintable [nLocation] = false;
               }
            else
               sayMessage (gc, ok);
          }
       else
          sayMessage (gc, ok);
     }
}

void main2
  (AdvGlobalContext& gc)   // global context
//
//  Third of 3 mainline functions.
//
{
  // Does he need any help?
  if (gc.m_hintable [gc.m_nHere])
     {
       gc.m_nHintTime++;
       if (((gc.m_nHintTime > 20) && !gc.m_inMaze [gc.m_nHere]) || (gc.m_nHintTime > 30))
          hintLogic (gc);
     }
  else
     gc.m_nHintTime = 0;

  // Tally inventory
  gc.m_nInventory = 0;
	for (long nObject=MINOBJECTS; (nObject <= MAXOBJECTS); nObject++)
      if (carrying (nObject))
         if (!gc.m_weightless [nObject])
            gc.m_nInventory++;

  // Get player's input
  getCommand (gc);
  gc.m_bOk2Describe = true;
  gc.m_nTurns++;

  // If null input, repeat brief description and return.  Special case for fog/glow.
  if (gc.m_nCmdWords == 0)
     {
       if (gc.m_nWhereIs [glow] == gc.m_nHere)
          describeObject (gc, glow, gc.m_nState [glow]);
       else
          if ((gc.m_nWhereIs [fog] == gc.m_nHere) && (gc.m_nState [fog] < 8))
             describeObject (gc, fog, gc.m_nState [fog]);
          else
             if (gc.m_lit [gc.m_nHere] || (near (lamp) && (gc.m_nState [lamp]==1)))
                describePlace (gc, gc.m_nHere, false);
             else
                sayMessage (gc, itisnowdark);
       return;
     }

  // Handle "mist"
  if ((gc.m_nArg1 == mist) || (gc.m_nArg2 == mist))
     {
       mistProc (gc);
       return;
     }

  // Invoke an appropriate handler, which is one of these:
  //
  //    magician() or magician2() for magic words
  //    retort() for obscenities
  //    travel() for movement
  //    doVerb() for general actions
  //    utilitarian() for utility commands

  if (isMagic (gc.m_nArg1))
     if (gc.m_nClosure < 3)
        magician (gc);
     else
        magician2 (gc);
  else
     {
       gc.m_nEscape = 0;
	     if ((gc.m_nArg1 == errword) || ((gc.m_nArg2 == errword) && (gc.m_nArg2 != say)))
          {
            gc.m_bOk2Describe = false;
            if (chance (50))
               sayMessage (gc, huh);
            else
               sayMessageText (gc, nocomprende, (gc.m_nArg1 == errword ? gc.m_szArg1 : gc.m_szArg2));
          }
       else
          if ((gc.m_nArg1 == obscenity) || (gc.m_nArg2 == obscenity))
             retort (gc);
          else
             if (isDirection (gc.m_nArg1) || (gc.m_nArg1 == move) || isPlace (gc.m_nArg1))
                travel (gc);
             else
                if (isVerb (gc.m_nArg1))
	                 if (gc.m_nArg2 != treasure)
	                    doVerb (gc);
	                 else
	                    if ((gc.m_nArg1 == obtain) || (gc.m_nArg1 == drop))
                         doVerb (gc);
	                    else
	                       sayMessage (gc, what);
                else
                   if (isUtil (gc.m_nArg1))
                      utilitarian (gc);
                   else
                      if (isObject (gc.m_nArg1))
	                       if (gc.m_nArg1 == all)
	                          printf ("Please be more specific.\n");
	                       else
	                          if (gc.m_nArg2 == null)
	                             if (gc.m_nArg1 == treasure)
	                                sayMessage (gc, what);
	                             else
                                  if (!gc.m_invisible [gc.m_nArg1] && near (gc.m_nArg1))
                                     {
                                       sayMessageWord (gc, whatdo, gc.m_nArg1);
                                       gc.m_nContext = gc.m_nArg1;
                                     }
                                  else
                                     sayMessageWord (gc, idontsee, gc.m_nArg1);
	                          else
	                             sayMessage (gc, huh);
                      else
	                       {
	                         printf ("<GLITCH!> No action performed for arg1=%d, arg2=%d, context=%d\n",
	                                 gc.m_nArg1, gc.m_nArg2, gc.m_nContext);
	                         printf ("Please report this bug to ravib@ravib.com.  Thanks!\n");
	                       }
     }
}

////////////////////
// Private functions

