legend/
legend/area/
legend/player/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, David   *
 *  Love, Guilherme 'Willie' Arnold, and Mitchell Tse.                     *
 *                                                                         *
 *  EnvyMud 2.0 improvements copyright (C) 1995 by Michael Quan and        *
 *  Mitchell Tse.                                                          *
 *                                                                         *
 *  In order to use any part of this Envy Diku Mud, you must comply with   *
 *  the original Diku license in 'license.doc', the Merc license in        *
 *  'license.txt', as well as the Envy license in 'license.nvy'.           *
 *  In particular, you may not remove either of these copyright notices.   *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/
/*  The dicegames HIGHDICE and SEVEN are copyright (C) 1996 Mark Janssen   *
 *  You may do everything to this peace of code as long as you leave the   *
 *  Diku/Merc/Envy license and this text in the code...     --Maniac--     *
 ***************************************************************************/
/***************************************************************************
 *  God Wars Mud copyright (C) 1994, 1995, 1996 by Richard Woolcock        *
 *  									   *
 *  Legend of Chrystancia copyright (C) 1999, 2000, 2001 by Matthew Little *
 *  This mud is NOT to be copied in whole or in part, or to be run without *
 *  the permission of Matthew Little. Nobody else has permission to        *
 *  authorise the use of this code.                                        *
 ***************************************************************************/

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <unistd.h>
#include <stdarg.h>
#include <limits.h>

#include "merc.h"

/*
 *  Menu for all game functions.
 *  Thelonius (Monk)  5/94
 */
void do_bet (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *croupier;


   /*
    *  The following searches for a valid croupier.  It allows existing
    *  ACT_GAMBLE mobs to attempt to gamble with other croupiers, but
    *  will not allow them to gamble with themselves (i.e., switched
    *  imms).  This takes care of ch == croupier in later act()'s
    */
   for (croupier = ch->in_room->people;
	croupier; croupier = croupier->next_in_room)
   {
      if (IS_NPC (croupier)
	  && IS_SET (croupier->act, ACT_GAMBLE) && croupier != ch)
	 break;
   }

   if (!croupier)
   {
      send_to_char ("You can't gamble here.\n\r", ch);
      return;
   }

   if (IS_NPC (ch))
      return;

   switch (croupier->pIndexData->vnum)
   {
   default:
      bug ("ACT_GAMBLE set on undefined game; vnum = %d",
	   croupier->pIndexData->vnum);
      break;
   case MOB_GAME_VNUM_ULT:
      game_u_l_t (ch, croupier, argument);
      break;
   case MOB_GAME_VNUM_HIGHDICE:
      game_high_dice (ch, croupier, argument);
      break;
   case MOB_GAME_VNUM_SEVEN:
      game_seven (ch, croupier, argument);
      break;
   }

   return;
}

/*
 * Upper-Lower-Triple
 * Game idea by Partan
 * Coded by Thelonius
 */
void game_u_l_t (CHAR_DATA * ch, CHAR_DATA * croupier, char *argument)
{
   char msg[MAX_STRING_LENGTH];
   char buf[MAX_STRING_LENGTH];
   char limit[MAX_STRING_LENGTH] = "5000";
   char wager[MAX_INPUT_LENGTH];
   char choice[MAX_INPUT_LENGTH];
   int ichoice;
   int amount;
   int die1;
   int die2;
   int die3;
   int total;

   argument = one_argument (argument, wager);
   one_argument (argument, choice);

   if (wager[0] == '\0' || !is_number (wager))
   {
      send_to_char ("How much would you like to bet?\n\r", ch);
      return;
   }

   amount = atoi (wager);

   if (amount > ch->pcdata->quest)
   {
      send_to_char ("You don't have enough quest points\n\r", ch);
      return;
   }

   if (amount < 1)
   {
      stc ("Invalid amount!\n\r", ch);
      return;
   }
   if (amount > atoi (limit))
   {
      act ("$n tells you, 'Sorry, the house limit is $t.'",
	   croupier, limit, ch, TO_VICT);
      ch->reply = croupier;
      return;
   }
/*
 *  At the moment, the winnings (and losses) do not actually go through
 *  the croupier.  They could do so, if each croupier is loaded with a
 *  certain bankroll.  Unfortunately, they would probably be popular
 *  (and rich) targets.
 */

   if (!str_cmp (choice, "lower"))
      ichoice = 1;
   else if (!str_cmp (choice, "upper"))
      ichoice = 2;
   else if (!str_cmp (choice, "triple"))
      ichoice = 3;
   else
   {
      send_to_char ("What do you wish to bet: Upper, Lower, or Triple?\n\r",
		    ch);
      return;
   }
/*
 *  Now we have a wagering amount, and a choice.
 *  Let's place the bets and roll the dice, shall we?
 */
   act ("You place $t quest points on the table, and bet '$T'.",
	ch, wager, choice, TO_CHAR);
   act ("$n places a bet with you.", ch, NULL, croupier, TO_VICT);
   act ("$n plays a dice game.", ch, NULL, croupier, TO_NOTVICT);
   ch->pcdata->quest -= amount;

   die1 = number_range (1, 6);
   die2 = number_range (1, 6);
   die3 = number_range (1, 6);
   total = die1 + die2 + die3;

   sprintf (msg, "$n rolls the dice: they come up %d, %d, and %d",
	    die1, die2, die3);

   if (die1 == die2 && die2 == die3)
   {
      strcat (msg, ".");
      act (msg, croupier, NULL, ch, TO_VICT);

      if (ichoice == 3)
      {
	 char haul[MAX_STRING_LENGTH];

	 amount *= 37;
	 sprintf (haul, "%d", amount);
	 act ("It's a TRIPLE!  You win $t quest points!",
	      ch, haul, NULL, TO_CHAR);
	 ch->pcdata->quest += amount;
      }
      else
	 send_to_char ("It's a TRIPLE!  You lose!\n\r", ch);

      return;
   }

   sprintf (buf, ", totalling %d.", total);
   strcat (msg, buf);
   act (msg, croupier, NULL, ch, TO_VICT);

   if (((total <= 10) && (ichoice == 1)) || ((total >= 11) && (ichoice == 2)))
   {
      char haul[MAX_STRING_LENGTH];

      amount *= 2;
      sprintf (haul, "%d", amount);
      act ("You win $t quest points!", ch, haul, NULL, TO_CHAR);
      ch->pcdata->quest += amount;
   }
   else
      send_to_char ("Sorry, better luck next time!\n\r", ch);

   return;
}

/*
 * High-Dice
 * Game idea by The Maniac!
 * Coded by The Maniac (based on code from Thelonius for u_l_t)
 *
 * The croupier roll's 2 dice for the player, then he roll's 2 dice
 * for himself. If the player's total is higher he wins his money*2
 * if the player's total is equal to or lower than the croupier's total
 * the bank wins... and the player loses his money
 */
void game_high_dice (CHAR_DATA * ch, CHAR_DATA * croupier, char *argument)
{
   char msg[MAX_STRING_LENGTH];
   char buf[MAX_STRING_LENGTH];
   char limit[MAX_STRING_LENGTH] = "5000";
   char wager[MAX_INPUT_LENGTH];
   int amount;
   int die1;
   int die2;
   int die3;
   int die4;
   int total1;
   int total2;

   argument = one_argument (argument, wager);

   if (wager[0] == '\0' || !is_number (wager))
   {
      send_to_char ("How much would you like to bet?\n\r", ch);
      return;
   }

   amount = atoi (wager);

   if (amount < 1)
   {
      stc ("Invalid amount!\n\r", ch);
      return;
   }				/* Does char have enough qp to play the game */
   if (amount > ch->pcdata->quest)
   {
      send_to_char ("You don't have enough quest points!\n\r", ch);
      return;
   }

   /* Doesn't the char bet too much */
   if (amount > atoi (limit))
   {
      act ("$n tells you, 'Sorry, the house limit is $t.'",
	   croupier, limit, ch, TO_VICT);
      ch->reply = croupier;
      return;
   }

/*
 *  At the moment, the winnings (and losses) do not actually go through
 *  the croupier.  They could do so, if each croupier is loaded with a
 *  certain bankroll.  Unfortunately, they would probably be popular
 *  (and rich) targets.
 */

/*
 *  Now we have a wagering amount...
 *  Let's place the bets and roll the dice, shall we?
 */
   sprintf (msg, "Roll some dice");	/* Because act wants it this way */
   act ("You place $t quest points on the table, and say '$T'.",
	ch, wager, msg, TO_CHAR);
   act ("$n places a bet with you.", ch, NULL, croupier, TO_VICT);
   act ("$n plays a dice game.", ch, NULL, croupier, TO_NOTVICT);
   ch->pcdata->quest -= amount;

   die1 = number_range (1, 6);
   die2 = number_range (1, 6);
   die3 = number_range (1, 6);
   die4 = number_range (1, 6);
   total1 = die1 + die2;
   total2 = die3 + die4;

   sprintf (msg, "$n rolls your dice: they come up %d, and %d", die1, die2);

   sprintf (buf, ", totalling %d.", total1);
   strcat (msg, buf);
   act (msg, croupier, NULL, ch, TO_VICT);

   sprintf (msg, "$n rolls his dice: they come up %d, and %d", die3, die4);

   sprintf (buf, ", totalling %d.", total2);
   strcat (msg, buf);
   act (msg, croupier, NULL, ch, TO_VICT);

   if (total1 > total2)
   {
      char haul[MAX_STRING_LENGTH];

      amount *= 2;
      sprintf (haul, "%d", amount);
      act ("You win $t quest points!", ch, haul, NULL, TO_CHAR);
      ch->pcdata->quest += amount;
   }
   else
      send_to_char ("Sorry, better luck next time!\n\r", ch);
   return;
}

/*
 * Under and Over Seven
 * Game idea by Maniac
 * Coded by Maniac (with bits from Thelonius)
 *
 * This is a very simple and easy dice game... and the nice thing is...
 * the operator never goes broke (he practically always wins)
 * (better not tell the players...)
 * The player can choose to bet on: Under 7, Seven or Over 7
 * The croupier rolls 2d6 and pays double if the player chose under or
 * over 7 and was correct and the croupier pay's 5x the amount if the player
 * chose SEVEN and was right.
 */

void game_seven (CHAR_DATA * ch, CHAR_DATA * croupier, char *argument)
{
   char msg[MAX_STRING_LENGTH];
   char buf[MAX_STRING_LENGTH];
   char limit[MAX_STRING_LENGTH] = "5000";
   char wager[MAX_INPUT_LENGTH];
   char choice[MAX_INPUT_LENGTH];
   int ichoice;
   int amount;
   int die1;
   int die2;
   int total;

   argument = one_argument (argument, wager);
   one_argument (argument, choice);

   if (wager[0] == '\0' || !is_number (wager))
   {
      send_to_char ("How much would you like to bet?\n\r", ch);
      return;
   }

   amount = atoi (wager);

   if (amount < 1)
   {
      stc ("Invalid amount!\n\r", ch);
      return;
   }
   if (amount > ch->pcdata->quest)
   {
      send_to_char ("You don't have enough quest points!\n\r", ch);
      return;
   }

   if (amount > atoi (limit))
   {
      act ("$n tells you, 'Sorry, the house limit is $t.'",
	   croupier, limit, ch, TO_VICT);
      ch->reply = croupier;
      return;
   }
/*
 *  At the moment, the winnings (and losses) do not actually go through
 *  the croupier.  They could do so, if each croupier is loaded with a
 *  certain bankroll.  Unfortunately, they would probably be popular
 *  (and rich) targets.
 */

   if (!str_cmp (choice, "under"))
      ichoice = 1;
   else if (!str_cmp (choice, "over"))
      ichoice = 2;
   else if (!str_cmp (choice, "seven"))
      ichoice = 3;
   else
   {
      send_to_char ("What do you wish to bet: Under, Over, or Seven?\n\r",
		    ch);
      return;
   }
/*
 *  Now we have a wagering amount, and a choice.
 *  Let's place the bets and roll the dice, shall we?
 */
   act ("You place $t quest points on the table, and bet '$T'.",
	ch, wager, choice, TO_CHAR);
   act ("$n places a bet with you.", ch, NULL, croupier, TO_VICT);
   act ("$n plays a dice game.", ch, NULL, croupier, TO_NOTVICT);
   ch->pcdata->quest -= amount;

   die1 = number_range (1, 6);
   die2 = number_range (1, 6);
   total = die1 + die2;

   sprintf (msg, "$n rolls the dice: they come up %d, and %d", die1, die2);

   if (total == 7)
   {
      strcat (msg, ".");
      act (msg, croupier, NULL, ch, TO_VICT);

      if (ichoice == 3)
      {
	 char haul[MAX_STRING_LENGTH];

	 amount *= 5;
	 sprintf (haul, "%d", amount);
	 act ("It's a SEVEN!  You win $t quest points!",
	      ch, haul, NULL, TO_CHAR);
	 ch->pcdata->quest += amount;
      }
      else
	 send_to_char ("It's a SEVEN!  You lose!\n\r", ch);

      return;
   }

   sprintf (buf, ", totalling %d.", total);
   strcat (msg, buf);
   act (msg, croupier, NULL, ch, TO_VICT);

   if (((total < 7) && (ichoice == 1)) || ((total > 7) && (ichoice == 2)))
   {
      char haul[MAX_STRING_LENGTH];

      amount *= 2;
      sprintf (haul, "%d", amount);
      act ("You win $t quest points!", ch, haul, NULL, TO_CHAR);
      ch->pcdata->quest += amount;
   }
   else
      send_to_char ("Sorry, better luck next time!\n\r", ch);

   return;
}

/* Slotr machines */

void do_slot (CHAR_DATA * ch, char *argument)
{
   int num1;
   int num2;
   int num3;
   int slotwin;

   if (IS_NPC (ch))
      return;

   if (ch->in_room == NULL || ch->in_room->vnum != 3165)
   {
      stc ("There is no slot machine here!\n\r", ch);
      return;
   }
   if (ch->pcdata->quest < 50)
   {
      send_to_char ("You need 50 quest points to play the slots.\n\r", ch);
      return;
   }

   ch->pcdata->quest -= 50;

   act ("$n inserts a token into the machine.", ch, NULL, NULL, TO_ROOM);
   send_to_char ("Spinning the slots! Cost - 50 quest points.\n\r", ch);
   pull_slot (ch);
   num1 = slotland;
   pull_slot (ch);
   num2 = slotland;
   pull_slot (ch);
   num3 = slotland;
   send_to_char ("\n\r\n\r", ch);


   if ((num1 == num2 || num2 == num3) && (num1 != num3))
   {
      if (num1 == 9 || num2 == 9 || num3 == 9)
      {
	 send_to_char ("You pulled a loser! No winnings given!\n\r", ch);
	 return;
      }
      send_to_char ("#wBING #yBING#g BING#p BING#c BING#w!\n\r", ch);
      send_to_char ("You win #w175#n quest points!\n\r", ch);
      act ("$n has just won qp playing slots!", ch, NULL, NULL, TO_ROOM);
      ch->pcdata->quest += 175;
      return;
   }

   if (num1 == num2 && num2 == num3)
   {
      switch (num1)
      {
      case 0:
	 slotwin = 400;
	 break;			/* Apple */
      case 1:
	 slotwin = 500;
	 break;			/* Lime */
      case 2:
	 slotwin = 1250;
	 break;			/* Lucky Seven */
      case 3:
	 slotwin = 375;
	 break;			/* Cherry */
      case 4:
	 slotwin = 2500;
	 break;			/* Gold Bar */
      case 5:
	 slotwin = 125;
	 break;			/* Lemon */
      case 6:
	 slotwin = 150;
	 break;			/* Rasberry */
      case 7:
	 slotwin = 250;
	 break;			/* Kiwi */
      case 8:
	 slotwin = 250;
	 break;			/* Banana */
      case 9:
	 if (ch->pcdata->quest > 5000)
	 {
	    slotwin = -5000;
	 }
	 else
	 {
	    slotwin = -ch->pcdata->quest;
	 }
	 break;			/* Loser */
      default:
	 slotwin = 0;
	 send_to_char ("Machine is broken. Please contact an IMM.\n\r", ch);
	 break;
      }

      ch->pcdata->quest += slotwin;
      send_to_char ("#wBING#y BING#g BING#p BING#c BING#w!\n\r", ch);
      stcprintf (ch, "You win #w%d#n quest points playing slots!\n\r",
		 slotwin);
      WAIT_STATE (ch, 9);

      act ("$n has just won qp playing slots!", ch, NULL, NULL, TO_ROOM);
      return;
   }

   send_to_char ("You didn't win. Sorry.\n\r", ch);
   WAIT_STATE (ch, 9);
   return;
}

/* Roll the slots for do_slot - Talon */
void pull_slot (CHAR_DATA * ch)
{
   slotland = (number_range (0, 9));
   switch (slotland)
   {
   case 0:
      send_to_char ("#rApple ", ch);
      break;
   case 1:
      send_to_char ("#gLime ", ch);
      break;
   case 2:
      send_to_char ("#cLucky-Seven ", ch);
      break;
   case 3:
      send_to_char ("#RCherry ", ch);
      break;
   case 4:
      send_to_char ("#oGold-Bar ", ch);
      break;
   case 5:
      send_to_char ("#yLemon ", ch);
      break;
   case 6:
      send_to_char ("#pRasberry ", ch);
      break;
   case 7:
      send_to_char ("#GKiwi ", ch);
      break;
   case 8:
      send_to_char ("#yBanana ", ch);
      break;
   case 9:
      send_to_char ("LOSER ", ch);
      break;
   default:
      send_to_char ("Broken Machine ", ch);
      break;
      break;
   }

   return;
}