/***************************************************************************
* 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);
}