/******************************************************************************
 Copyright (c) 2000-2001 Richard Woolcock

 Permission is hereby granted, free of charge, to any person obtaining a copy 
 of this software and associated documentation files (the "Software"), to deal 
 in the Software without restriction, including without limitation the rights 
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 copies of the Software, and to permit persons to whom the Software is 
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all 
 copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 SOFTWARE.
 ******************************************************************************/

/******************************************************************************
 File Name        : combat_eyes.c
 ******************************************************************************
 Description      : The "eyes" combat table and associated commands.
 ******************************************************************************/

/******************************************************************************
 Required library files.
 ******************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "sockets.h"
#include "combat.h"
#include "combat_eyes.h"
#include "glad.h"

/******************************************************************************
 Required local variables.
 ******************************************************************************/

/* Create the combat table */
const cmbt_table_t kstCmbtTableEyes[] =
{ /* Requirements Function        AP   ATT  DEF  DAM  Block message */
   { " ",         CmbtNull,       1,   +0,  +0,  +0,  "misses" },
   { "aaaaa",     CmbtAim,        5,   +25, +0,  +0,  "misses" },
   { "aaaa",      CmbtAim,        4,   +20, +0,  +0,  "misses" },
   { "aaa",       CmbtAim,        3,   +15, +0,  +0,  "misses" },
   { "aa",        CmbtAim,        2,   +10, +0,  +0,  "misses" },
   { "a",         CmbtAim,        1,   +5,  +0,  +0,  "misses" },
   { "ddddd",     CmbtDefend,     5,   +0,  +25, +0,  "misses" },
   { "dddd",      CmbtDefend,     4,   +0,  +20, +0,  "misses" },
   { "ddd",       CmbtDefend,     3,   +0,  +15, +0,  "misses" },
   { "dd",        CmbtDefend,     2,   +0,  +10, +0,  "misses" },
   { "d",         CmbtDefend,     1,   +0,  +5,  +0,  "misses" },
   { "fffff",     CmbtFocus,      5,   +10, +10, +5,  "misses" },
   { "ffff",      CmbtFocus,      4,   +8,  +8,  +4,  "misses" },
   { "fff",       CmbtFocus,      3,   +6,  +6,  +3,  "misses" },
   { "ff",        CmbtFocus,      2,   +4,  +4,  +2,  "misses" },
   { "f",         CmbtFocus,      1,   +2,  +2,  +1,  "misses" },
   { "mmmmm",     CmbtMeditate,   5,   +0,  +0,  +0,  "misses" },
   { "mmmm",      CmbtMeditate,   4,   +0,  +0,  +0,  "misses" },
   { "mmm",       CmbtMeditate,   3,   +0,  +0,  +0,  "misses" },
   { "mm",        CmbtMeditate,   2,   +0,  +0,  +0,  "misses" },
   { "m",         CmbtMeditate,   1,   +0,  +0,  +0,  "misses" },
   { "ppppp",     CmbtPower,      5,   +0,  +0,  +15, "misses" },
   { "pppp",      CmbtPower,      4,   +0,  +0,  +12, "misses" },
   { "ppp",       CmbtPower,      3,   +0,  +0,  +9,  "misses" },
   { "pp",        CmbtPower,      2,   +0,  +0,  +6,  "misses" },
   { "p",         CmbtPower,      1,   +0,  +0,  +3,  "misses" },
   { "sssss",     CmbtSpeed,      5,   +0,  +0,  +0,  "misses" },
   { "ssss",      CmbtSpeed,      4,   +0,  +0,  +0,  "misses" },
   { "sss",       CmbtSpeed,      3,   +0,  +0,  +0,  "misses" },
   { "ss",        CmbtSpeed,      2,   +0,  +0,  +0,  "misses" },
   { "s",         CmbtSpeed,      1,   +0,  +0,  +0,  "misses" },

   /* Commands (an '@' followed by one letter) */
   { "@a",        CmbtCmdAim,     0,   +0,  +0,  +0,  "misses" },
   { "@d",        CmbtCmdDefend,  0,   +0,  +0,  +0,  "misses" },
   { "@f",        CmbtCmdFocus,   0,   +0,  +0,  +0,  "misses" },
   { "@m",        CmbtCmdMeditate,0,   +0,  +0,  +0,  "misses" },
   { "@p",        CmbtCmdPower,   0,   +0,  +0,  +0,  "misses" },
   { "@s",        CmbtCmdSpeed,   0,   +0,  +0,  +0,  "misses" },

   { NULL }
};

/******************************************************************************
 Commands specific to this table.
 ******************************************************************************/

CMBT(CmdAim)
{
   const int kiCost = 100; /* The cost of this particular fighting move */

   if ( pstBody->bBusy[AP_EYES] )
   {
      SendToBody( pstBody, TO_USER, "You're already concentrating on something else!\n\r" );
   }
   else if ( pstBody->iActions[AP_EYES] < kiCost )
   {
      /* Inform the player that they don't have enough action points */
      SendToBody( pstBody, TO_USER, "You need %d action points to improve your aim, you have %d.\n\r", 
         kiCost, pstBody->iActions[AP_EYES] );
   }
   else /* The character is able to make the attack */
   {
      /* Inform the user that the move is taking place */
      SendToBody( pstBody, TO_USER, "Ok.\n\r" );

      pstBody->iActions[AP_EYES] -= kiCost;        /* Subtract the action points */
      pstBody->bBusy[AP_EYES] = TRUE;              /* Set legs to "busy"         */
      Combat( pstBody, AP_EYES, 'a', TABLE_EYES ); /* Call the combat function   */
   }
}

CMBT(CmdDefend)
{
   const int kiCost = 100; /* The cost of this particular fighting move */

   if ( pstBody->bBusy[AP_EYES] )
   {
      SendToBody( pstBody, TO_USER, "You're already concentrating on something else!\n\r" );
   }
   else if ( pstBody->iActions[AP_EYES] < kiCost )
   {
      /* Inform the player that they don't have enough action points */
      SendToBody( pstBody, TO_USER, "You need %d action points to defend, you have %d.\n\r", 
         kiCost, pstBody->iActions[AP_EYES] );
   }
   else /* The character is able to make the attack */
   {
      /* Inform the user that the move is taking place */
      SendToBody( pstBody, TO_USER, "Ok.\n\r" );

      pstBody->iActions[AP_EYES] -= kiCost;        /* Subtract the action points */
      pstBody->bBusy[AP_EYES] = TRUE;              /* Set legs to "busy"         */
      Combat( pstBody, AP_EYES, 'd', TABLE_EYES ); /* Call the combat function   */
   }
}

CMBT(CmdFocus)
{
   const int kiCost = 100; /* The cost of this particular fighting move */

   if ( pstBody->bBusy[AP_EYES] )
   {
      SendToBody( pstBody, TO_USER, "You're already concentrating on something else!\n\r" );
   }
   else if ( pstBody->iActions[AP_EYES] < kiCost )
   {
      /* Inform the player that they don't have enough action points */
      SendToBody( pstBody, TO_USER, "You need %d action points to focus your fighting techniques, you have %d.\n\r", 
         kiCost, pstBody->iActions[AP_EYES] );
   }
   else /* The character is able to make the attack */
   {
      /* Inform the user that the move is taking place */
      SendToBody( pstBody, TO_USER, "Ok.\n\r" );

      pstBody->iActions[AP_EYES] -= kiCost;        /* Subtract the action points */
      pstBody->bBusy[AP_EYES] = TRUE;              /* Set legs to "busy"         */
      Combat( pstBody, AP_EYES, 'f', TABLE_EYES ); /* Call the combat function   */
   }
}

CMBT(CmdMeditate)
{
   const int kiCost = 100; /* The cost of this particular fighting move */

   if ( pstBody->bBusy[AP_EYES] )
   {
      SendToBody( pstBody, TO_USER, "You're already concentrating on something else!\n\r" );
   }
   else if ( pstBody->iActions[AP_EYES] < kiCost )
   {
      /* Inform the player that they don't have enough action points */
      SendToBody( pstBody, TO_USER, "You need %d action points to meditate, you have %d.\n\r", 
         kiCost, pstBody->iActions[AP_EYES] );
   }
   else /* The character is able to make the attack */
   {
      /* Inform the user that the move is taking place */
      SendToBody( pstBody, TO_USER, "Ok.\n\r" );

      pstBody->iActions[AP_EYES] -= kiCost;        /* Subtract the action points */
      pstBody->bBusy[AP_EYES] = TRUE;              /* Set legs to "busy"         */
      Combat( pstBody, AP_EYES, 'm', TABLE_EYES ); /* Call the combat function   */
   }
}

CMBT(CmdPower)
{
   const int kiCost = 100; /* The cost of this particular fighting move */

   if ( pstBody->bBusy[AP_EYES] )
   {
      SendToBody( pstBody, TO_USER, "You're already concentrating on something else!\n\r" );
   }
   else if ( pstBody->iActions[AP_EYES] < kiCost )
   {
      /* Inform the player that they don't have enough action points */
      SendToBody( pstBody, TO_USER, "You need %d action points to power up your attacks, you have %d.\n\r", 
         kiCost, pstBody->iActions[AP_EYES] );
   }
   else /* The character is able to make the attack */
   {
      /* Inform the user that the move is taking place */
      SendToBody( pstBody, TO_USER, "Ok.\n\r" );

      pstBody->iActions[AP_EYES] -= kiCost;        /* Subtract the action points */
      pstBody->bBusy[AP_EYES] = TRUE;              /* Set legs to "busy"         */
      Combat( pstBody, AP_EYES, 'p', TABLE_EYES ); /* Call the combat function   */
   }
}

CMBT(CmdSpeed)
{
   const int kiCost = 100; /* The cost of this particular fighting move */

   if ( pstBody->bBusy[AP_EYES] )
   {
      SendToBody( pstBody, TO_USER, "You're already concentrating on something else!\n\r" );
   }
   else if ( pstBody->iActions[AP_EYES] < kiCost )
   {
      /* Inform the player that they don't have enough action points */
      SendToBody( pstBody, TO_USER, "You need %d action points to accelerate your attacks, you have %d.\n\r", 
         kiCost, pstBody->iActions[AP_EYES] );
   }
   else /* The character is able to make the attack */
   {
      /* Inform the user that the move is taking place */
      SendToBody( pstBody, TO_USER, "Ok.\n\r" );

      pstBody->iActions[AP_EYES] -= kiCost;        /* Subtract the action points */
      pstBody->bBusy[AP_EYES] = TRUE;              /* Set legs to "busy"         */
      Combat( pstBody, AP_EYES, 's', TABLE_EYES ); /* Call the combat function   */
   }
}

/******************************************************************************
 Combat techniques.
 ******************************************************************************/

CMBT(Aim)
{
   SendToBody( pstBody, TO_USER, "You concentrate on aiming your attacks.\n\r" );
   SendToBody( pstBody, TO_ROOM, "{name} concentrates on aiming {his/her} attacks.\n\r" );
}

CMBT(Defend)
{
   SendToBody( pstBody, TO_USER, "You concentrate on your defence.\n\r" );
   SendToBody( pstBody, TO_ROOM, "{name} concentrates on {his/her} defence.\n\r" );
}

CMBT(Focus)
{
   SendToBody( pstBody, TO_USER, "You concentrate on your overall fighting technique.\n\r" );
   SendToBody( pstBody, TO_ROOM, "{name} concentrates on {his/her} overall fighting technique.\n\r" );
}

CMBT(Meditate)
{
   SendToBody( pstBody, TO_USER, "You meditate.\n\r" );
   SendToBody( pstBody, TO_ROOM, "{name} meditates.\n\r" );

   /* Number of HEALTH healed equals the speed of the movement */
   pstBody->iDam -= kstCmbtTable[pstBody->eTable[AP_EYES]][pstBody->iCmbtIndex[AP_EYES]].iSpeed;

   /* Make sure they don't heal themselves beyond full health! */
   if ( pstBody->iDam < 0 )
   {
      pstBody->iDam = 0;
   }
}

CMBT(Power)
{
   SendToBody( pstBody, TO_USER, "You concentrate on improving the power of your attacks.\n\r" );
   SendToBody( pstBody, TO_ROOM, "{name} concentrates on improving the power of {his/her} attacks.\n\r" );
}

CMBT(Speed)
{
   int iSpeed = kstCmbtTable[pstBody->eTable[AP_EYES]][pstBody->iCmbtIndex[AP_EYES]].iSpeed;

   SendToBody( pstBody, TO_USER, "You concentrate on improving the speed of your attacks.\n\r" );
   SendToBody( pstBody, TO_ROOM, "{name} concentrates on improving the speed of {his/her} attacks.\n\r" );

   /* You get 1x, 2x, 3x, 4x then 5x normal action points to each hand */
   pstBody->iActions[AP_LEFT_HAND] += (iSpeed*GetSpeed(pstBody));
   pstBody->iActions[AP_RIGHT_HAND] += (iSpeed*GetSpeed(pstBody));
}