/***************************************************************************
 * 		Original Source Code by John Booth (EoD) 		   *
 * 	   Ported to Rom2.4b4 by Yago Diaz <yago@cerberus.uab.es>	   *
 *	       Bugfixes by Bogardan <jordi@cerberus.uab.es>		   *
 *		     (C) Last Modification February 1998		   *
 ***************************************************************************/

/***************************************************************************
 *  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.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  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.                                                  *
 **************************************************************************/

/***************************************************************************
*       ROM 2.4 is copyright 1993-1996 Russ Taylor                         *
*       ROM has been brought to you by the ROM consortium                  *
*           Russ Taylor (rtaylor@efn.org)                                  *
*           Gabrielle Taylor                                               *
*           Brian Moore (zump@rom.org)                                     *
*       By using this code, you have agreed to follow the terms of the     *
*       ROM license, in the file Rom24/doc/rom.license                     *
***************************************************************************/

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"


int
mount_success (CHAR_DATA * ch, CHAR_DATA * mount, int canattack)
{
  int percent;
  int success;

  percent = number_percent () + (ch->level < mount->level ?
				 (mount->level - ch->level) * 3 :
				 (mount->level - ch->level) * 2);

  if (!ch->fighting)
    percent -= 25;

  if (!IS_NPC (ch) && IS_DRUNK (ch))
    {
      percent += ch->pcdata->learned[gsn_riding] / 2;
      send_to_char
	("Due to your being under the influence, riding seems a bit harder...\n\r",
	 ch);
    }

  success = percent - ch->pcdata->learned[gsn_riding];

  if (success <= 0)
    {
      check_improve (ch, gsn_riding, TRUE, 1);
      return (1);
    }
  else
    {
      check_improve (ch, gsn_riding, FALSE, 1);

      if (success >= 10 && MOUNTED (ch) == mount)
	{
	  act ("You lose control and fall off of $N.", ch, NULL, mount,
	       TO_CHAR);
	  act ("$n loses control and falls off of $N.", ch, NULL, mount,
	       TO_ROOM);
	  act ("$n loses control and falls off of you.", ch, NULL, mount,
	       TO_VICT);

	  ch->riding = FALSE;
	  mount->riding = FALSE;

	  if (ch->position > POS_STUNNED)
	    ch->position = POS_SITTING;

	  ch->hit -= 5;
	  update_pos (ch);
	}

      if (success >= 40 && canattack)
	{
	  act ("$N doesn't like the way you've been treating $M.", ch, NULL,
	       mount, TO_CHAR);
	  act ("$N doesn't like the way $n has been treating $M.", ch, NULL,
	       mount, TO_ROOM);
	  act ("You don't like the way $n has been treating you.", ch, NULL,
	       mount, TO_VICT);

	  act ("$N snarls and attacks you!", ch, NULL, mount, TO_CHAR);
	  act ("$N snarls and attacks $n!", ch, NULL, mount, TO_ROOM);
	  act ("You snarl and attack $n!", ch, NULL, mount, TO_VICT);

	  damage (mount, ch, number_range (1, mount->level), gsn_kick,
		  DAM_BASH, FALSE);

	}
    }

  return (0);
}

void
do_mount (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  char buf[MAX_INPUT_LENGTH];
  CHAR_DATA *mount;

  argument = one_argument (argument, arg);

  if (IS_NPC (ch))
    return;

  if (arg[0] == '\0' && ch->mount && ch->mount->in_room == ch->in_room)
    {
      mount = ch->mount;
    }
  else if (!(mount = get_char_room (ch, NULL, arg)))
    {
      send_to_char ("Mount what?\n\r", ch);
      return;
    }

  if (!IS_NPC (ch) && !ch->pcdata->learned[gsn_riding])
    {
      send_to_char ("You don't know how to ride!\n\r", ch);
      return;
    }

  if (!IS_NPC (mount) && !IS_SET (mount->act, ACT_MOUNT))
    {
      sprintf (buf, "You can't ride that.\n\r");
      send_to_char (buf, ch);
      return;
    }

  if (mount->level - 5 > ch->level)
    {
      send_to_char ("That beast is too powerful for you to ride.", ch);
      return;
    }

  if ((mount->mount) && (!mount->riding) && (mount->mount != ch))
    {
      sprintf (buf, "%s belongs to %s, not you.\n\r",
	       mount->short_descr, mount->mount->name);
      send_to_char (buf, ch);
      return;
    }

  if (mount->position < POS_STANDING)
    {
      send_to_char ("Your mount must be standing.\n\r", ch);
      return;
    }

  if (RIDDEN (mount))
    {
      send_to_char ("This beast is already ridden.\n\r", ch);
      return;
    }
  else if (MOUNTED (ch))
    {
      send_to_char ("You are already riding.\n\r", ch);
      return;
    }

  if (!mount_success (ch, mount, TRUE))
    {
      send_to_char ("You fail to mount the beast.\n\r", ch);
      return;
    }

  act ("You hop on $N's back.", ch, NULL, mount, TO_CHAR);
  act ("$n hops on $N's back.", ch, NULL, mount, TO_NOTVICT);
  act ("$n hops on your back!", ch, NULL, mount, TO_VICT);

  ch->mount = mount;
  ch->riding = TRUE;
  mount->mount = ch;
  mount->riding = TRUE;

  affect_strip (ch, gsn_sneak);
  REMOVE_BIT (ch->affected_by, AFF_SNEAK);
  affect_strip (ch, gsn_hide);
  REMOVE_BIT (ch->affected_by, AFF_HIDE);
}

void
do_dismount (CHAR_DATA * ch, char *argument)
{
  CHAR_DATA *mount;

  if (MOUNTED (ch))
    {
      mount = MOUNTED (ch);

      act ("You dismount from $N.", ch, NULL, mount, TO_CHAR);
      act ("$n dismounts from $N.", ch, NULL, mount, TO_NOTVICT);
      act ("$n dismounts from you.", ch, NULL, mount, TO_VICT);

      ch->riding = FALSE;
      mount->riding = FALSE;
    }
  else
    {
      send_to_char ("You aren't mounted.\n\r", ch);
      return;
    }
}


void
do_buy_mount (CHAR_DATA * ch, char *argument)
{
  int cost, roll;
  char arg[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  char color[80], name[30], size[30];
  CHAR_DATA *mount;
  ROOM_INDEX_DATA *pRoomIndexNext;
  ROOM_INDEX_DATA *in_room;

  name[0] = '\0';
  size[0] = '\0';
  color[0] = '\0';

  if (IS_NPC (ch))
    return;

  if (!IS_NPC (ch) && !ch->pcdata->learned[gsn_riding])
    {
      send_to_char
	("How do you expect to buy a horse when you can't even ride?\n\r",
	 ch);
      return;
    }

  argument = one_argument (argument, arg);

  pRoomIndexNext = get_room_index (ch->in_room->vnum + 1);

  if (pRoomIndexNext == NULL)
    {
      bug ("Do_buy: bad mount shop at vnum %d.", ch->in_room->vnum);
      send_to_char
	("I'm afraid the stalls where I keep my mounts don't exist.\n\r", ch);
      return;
    }

  in_room = ch->in_room;
  ch->in_room = pRoomIndexNext;
  mount = get_char_room (ch, NULL, arg);
  ch->in_room = in_room;

  if (mount == NULL)
    {
      send_to_char ("Sorry, we don't sell any of those here.\n\r", ch);
      return;
    }

  if (!IS_SET (mount->act, ACT_MOUNT))
    {
      send_to_char ("Sorry, we don't sell any of those here.\n\r", ch);
      return;
    }

  if (MOUNTED (ch) || ch->mount != NULL)
    {
      send_to_char ("You already have a mount.\n\r", ch);
      return;
    }

  cost = 100 * ch->level;

  if (ch->gold < cost)
    {
      send_to_char ("You can't afford it.\n\r", ch);
      return;
    }

  roll = number_percent ();

  if (!IS_NPC (ch) && roll < ch->pcdata->learned[gsn_haggle])
    {
      cost -= cost / 2 * roll / 100;
      sprintf (buf, "You haggle the price down to %d coins.\n\r", cost);
      send_to_char (buf, ch);
      check_improve (ch, gsn_haggle, TRUE, 4);
    }

  ch->gold -= cost;
  mount = create_mobile (mount->pIndexData);

  mount->comm = COMM_NOTELL | COMM_NOSHOUT | COMM_NOCHANNELS;
  mount->max_hit = mount->hit = (ch->level * 4) - (25 + number_range (1, 50));
  if (mount->max_hit < 25)
    mount->max_hit = mount->hit = 25;
  mount->max_mana = mount->mana = 50;
  mount->max_move = mount->move = 200 + ch->level * 10;
  mount->level = ch->level / 1.25;
  mount->sex = ch->sex;

  switch (number_range (1, 11))
    {
    case 1:
      strcpy (color, "dappled grey");
      break;
    case 2:
      strcpy (color, "charcoal grey");
      break;
    case 3:
      strcpy (color, "midnight black");
      break;
    case 4:
      strcpy (color, "dark burgundy");
      break;
    case 5:
      strcpy (color, "cream yellow");
      break;
    case 6:
      strcpy (color, "pure white");
      break;
    case 7:
      strcpy (color, "dark brown");
      break;
    case 8:
      strcpy (color, "light brown");
      break;
    case 9:
      strcpy (color, "white and brown spotted");
      break;
    case 10:
      strcpy (color, "black and white spotted");
      break;
    case 11:
      strcpy (color, "purple and green striped");
      strcpy (size, "mutant ");
      mount->hit += 100;
      mount->max_hit += 100;
      break;
    }

  if (ch->level >= 41)
    {
      strcpy (name, "pegasus");
      SET_BIT (mount->affected_by, AFF_FLYING);
    }
  else if (ch->level >= 30)
    {
      if (ch->sex == 1)
	strcpy (name, "gelding");
      else
	{
	  strcpy (name, "mare");
	  strcat (size, "majestic ");
	}
    }
  else if (ch->level >= 20)
    {
      if (ch->sex == 1)
	strcpy (name, "stallion");
      else
	strcpy (name, "mare");
    }
  else if (ch->level >= 15)
    {
      strcpy (name, "horse");
    }
  else if (ch->level >= 10)
    {
      strcpy (name, "horse");
      strcat (size, "small ");
    }
  else
    {
      strcpy (name, "pony");
    }

  argument = one_argument (argument, arg);

  if (arg[0] != '\0')
    sprintf (buf, "%s %s", name, arg);
  else
    sprintf (buf, "%s", name);
  free_string (mount->name);
  mount->name = str_dup (buf);

  sprintf (buf, "a %s%s %s", size, color, name);
  free_string (mount->short_descr);
  mount->short_descr = str_dup (buf);

  sprintf (buf, "A %s%s %s is standing here.\n\r", size, color, name);
  free_string (mount->long_descr);
  mount->long_descr = str_dup (buf);

  sprintf (buf, "%sThe name %s is branded on its hind leg.\n\r",
	   mount->description, ch->name);
  free_string (mount->description);
  mount->description = str_dup (buf);

  char_to_room (mount, ch->in_room);
  add_follower (mount, ch);

  act ("$n bought $N as a mount.", ch, NULL, mount, TO_ROOM);

  sprintf (buf, "Enjoy your %s.\n\r", name);
  send_to_char (buf, ch);

  do_mount (ch, name);

  return;
}


char *
get_mount_owner (CHAR_DATA * pet)
{
  static char owner_name[20];
  char *temp;
  int len = 0, i = 0;

  if (!IS_NPC (pet))
    return NULL;

  if (pet->description)
    len = strlen (pet->description);
  else
    return NULL;

  temp = pet->description;

  while (*temp && i < 15 && len < 1024)
    {
      if (*temp == ' ')
	i++;
      temp++;
      len++;
    }

  if (len == 1024)
    {
      log_string ("BUG: description overflow for get_mount_owner.");
      return NULL;
    }

  len = 0;
  owner_name[0] = 0;
  while (*temp && *temp != ' ' && len < 16)
    {
      owner_name[len++] = *temp;
      temp++;
    }

  owner_name[len] = 0;
  return (owner_name);
}