/************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements 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 * * benefiting. We hope that you share your changes too. What goes * * around, comes around. * *************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * 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 * *************************************************************************** * 1stMUD ROM Derivative (c) 2001-2002 by Ryan Jennings * * http://1stmud.dlmud.com/ <r-jenn@shaw.ca> * ***************************************************************************/ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #include "merc.h" #include "tables.h" #include "recycle.h" #include "interp.h" void death_cry args((CHAR_DATA * ch)); CH_CMD(do_arena_challenge) { CHAR_DATA *victim; if (IS_NPC(ch)) return; if (!str_cmp(argument, "self") || !str_cmp(argument, "drop")) { extract_arena(ch); chprintln(ch, "You retract your challenge."); return; } if (arena == FIGHT_START) { chprintln (ch, "Sorry, some one else has already started a challenge, please try later."); return; } if (arena == FIGHT_BUSY) { chprintln (ch, "Sorry, there is a fight in progress, please wait a few moments."); return; } if (arena == FIGHT_LOCK) { chprintln(ch, "Sorry, the arena is currently locked from use."); return; } if (IS_SET(ch->act, PLR_CHALLENGED)) { chprintlnf (ch, "You have already been challenged, either ACCEPT or DECLINE %s first.", ch->pcdata->challenger ? ch->pcdata->challenger->name : ch-> pcdata->challenged ? ch->pcdata->challenged->name : "!BUG!"); return; } if (ch->hit < ch->max_hit) { chprintln(ch, "You must be fully healed to fight in the arena."); return; } if (argument[0] == '\0') { chprintln(ch, "You must specify whom you wish to challenge."); return; } if ((victim = get_char_world(ch, argument)) == NULL) { chprintln(ch, "They are not playing."); return; } if (IS_NPC(victim) || IS_IMMORTAL(victim) || victim == ch) { chprintln(ch, "You cannot challenge NPC's or yourself."); return; } if (!can_see(victim, ch)) { chprintln(ch, "They can't see you."); return; } if (IS_SET(victim->act, PLR_CHALLENGER)) { chprintln(ch, "They have already challenged someone else."); return; } if (victim->fighting != NULL) { chprintln(ch, "That person is engaged in battle right now."); return; } if (victim->hit < victim->max_hit) { chprintln(ch, "That player is not healthy enough to fight right now."); return; } if (victim->desc == NULL) { chprintln(ch, "That player is linkdead at the moment, try them later."); return; } ch->pcdata->challenged = victim; SET_BIT(ch->act, PLR_CHALLENGER); victim->pcdata->challenger = ch; SET_BIT(victim->act, PLR_CHALLENGED); arena = FIGHT_START; chprintln (ch, "Challenge has been sent. Type 'arena challenge drop' to cancel the challenge."); act("{R$n has challenged you to a death match.", ch, NULL, victim, TO_VICT); announce(victim, INFO_ARENA, "%s has challenged $n to a duel.", ch->name); chprintlnf(victim, "Type: ARENA ACCEPT %s to meet the challenge.", ch->name); chprintlnf(victim, "Type: ARENA DECLINE %s to chicken out.{x", ch->name); return; } CH_CMD(do_arena_accept) { float odd1, odd2; float lvl1, lvl2; CHAR_DATA *victim; ROOM_INDEX_DATA *random1; ROOM_INDEX_DATA *random2; random1 = get_room_index( (number_range (ROOM_VNUM_DUEL_START, ROOM_VNUM_DUEL_END))); random2 = get_room_index( (number_range (ROOM_VNUM_DUEL_START, ROOM_VNUM_DUEL_END))); if (IS_NPC(ch)) return; if (!IS_SET(ch->act, PLR_CHALLENGED)) { chprintln(ch, "You have not been challenged."); return; } if (arena == FIGHT_BUSY) { chprintln (ch, "Sorry, there is a fight in progress, please wait a few moments."); return; } if (arena == FIGHT_LOCK) { chprintln(ch, "Sorry, the arena is currently locked from use."); return; } if (argument[0] == '\0') { chprintln(ch, "You must specify whose challenge you wish to accept."); return; } if ((victim = get_char_world(ch, argument)) == NULL) { chprintln(ch, "They aren't logged in!"); return; } if (victim == ch) { chprintln(ch, "You haven't challenged yourself!"); return; } if (!IS_SET(victim->act, PLR_CHALLENGER) || victim != ch->pcdata->challenger) { chprintln(ch, "That player hasn't challenged you!"); return; } chprintln(ch, "You have accepted the challenge!"); act("$n accepts your challenge!", ch, NULL, victim, TO_VICT); lvl1 = ch->hit + 1; lvl2 = victim->hit + 1; odd1 = (lvl1 / lvl2); odd2 = (lvl2 / lvl1); announce(NULL, INFO_ARENA, "%s (%d wins) (%d losses) Payoff odds %.2f", victim->name, victim->pcdata->awins, victim->pcdata->alosses, odd1); announce(NULL, INFO_ARENA, "%s (%d wins) (%d losses) Payoff odds %.2f", ch->name, ch->pcdata->awins, ch->pcdata->alosses, odd2); announce(NULL, INFO_ARENA, "To wager on the fight, type: arena bet (amount) (player name)"); chprintln(ch, "You make your way into the arena."); char_from_room(ch); char_to_room(ch, random1); do_function(ch, &do_look, "auto"); chprintln(victim, "You make your way to the arena."); char_from_room(victim); char_to_room(victim, random2); do_function(victim, &do_look, "auto"); arena = FIGHT_BUSY; return; } CH_CMD(do_arena_decline) { CHAR_DATA *victim; if (IS_NPC(ch)) return; if (!IS_SET(ch->act, PLR_CHALLENGED)) { chprintln(ch, "You have not been challenged."); return; } if (argument[0] == '\0') { chprintln(ch, "You must specify whose challenge you wish to decline."); return; } if ((victim = get_char_world(ch, argument)) == NULL) { chprintln(ch, "They aren't logged in!"); return; } if (!IS_SET(victim->act, PLR_CHALLENGER) || victim != ch->pcdata->challenger) { chprintln(ch, "That player hasn't challenged you."); return; } if (victim == ch) return; victim->pcdata->challenged = NULL; REMOVE_BIT(victim->act, PLR_CHALLENGER); ch->pcdata->challenger = NULL; REMOVE_BIT(ch->act, PLR_CHALLENGED); arena = FIGHT_OPEN; chprintln(ch, "Challenge declined!"); act("$n has declined your challenge.", ch, NULL, victim, TO_VICT); announce(ch, INFO_ARENA, "$n has declined %s's challenge.", victim->name); return; } CH_CMD(do_arena_bet) { char arg[MIL]; CHAR_DATA *fighter; unsigned int wager; if (IS_NPC(ch)) return; argument = one_argument(argument, arg); if (argument[0] == '\0' || !is_number(arg)) { chprintln(ch, "Syntax: BET [amount] [player]"); return; } if (ch->pcdata->gladiator != NULL) { chprintln(ch, "You have already placed a bet on this fight."); return; } if (IS_SET(ch->act, PLR_CHALLENGER) || IS_SET(ch->act, PLR_CHALLENGED)) { chprintln(ch, "You can't bet on this battle."); return; } fighter = get_char_world(ch, argument); if (fighter == NULL) { chprintln(ch, "That player is not logged in."); return; } if (IS_NPC(fighter)) { chprintln(ch, "Why bet on a mob? They aren't fighting..."); return; } if (!IS_SET(fighter->in_room->room_flags, ROOM_ARENA)) { chprintln(ch, "That player is not in the arena."); return; } if (!str_prefix("-", arg)) { chprintln(ch, "Error: Invalid argument!"); return; } wager = atoi(arg); if (wager > 5000 || wager < 1) { chprintln(ch, "Wager range is between 1 and 5,000"); return; } if (wager > (unsigned int) ch->gold) { chprintln(ch, "You don't have that much gold to wager!"); return; } ch->pcdata->gladiator = fighter; ch->pcdata->plr_wager = wager; chprintlnf(ch, "You have placed a %d gold wager on %s", wager, fighter->name); return; } void check_arena(CHAR_DATA * ch, CHAR_DATA * victim) { CHAR_DATA *wch; float odds; float lvl1, lvl2; long payoff = 0; if (IS_NPC(ch) || IS_NPC(victim)) return; announce(victim, INFO_ARENA, "%s has defeated $n!\n\r", ch->name); ch->pcdata->awins += 1; victim->pcdata->alosses += 1; lvl1 = ch->hit + 1; lvl2 = victim->hit + 1; odds = (lvl2 / lvl1); for (wch = player_first; wch; wch = wch->next_player) { if (wch->pcdata->gladiator == ch) { payoff = wch->pcdata->plr_wager * (UMAX((long) odds + 1, 2)); chprintlnf(wch, "You won! Your wager: %d, payoff: %ld", wch->pcdata->plr_wager, payoff); wch->gold += UMAX(0, payoff); wch->pcdata->gladiator = NULL; wch->pcdata->plr_wager = 0; payoff = 0; } if (wch->pcdata->gladiator != ch && wch->pcdata->plr_wager >= 1) { chprintlnf(wch, "You lost! Your wager: %d", wch->pcdata->plr_wager); wch->gold -= wch->pcdata->plr_wager; if (wch->gold < 0) wch->gold = 0; wch->pcdata->gladiator = NULL; wch->pcdata->plr_wager = 0; } } stop_fighting(victim, TRUE); death_cry(victim); char_from_room(victim); char_to_room(victim, get_room_index(ROOM_VNUM_DUEL_LOSER)); victim->hit = victim->max_hit; victim->mana = victim->max_mana; victim->move = victim->max_move; update_pos(victim); do_function(victim, &do_look, "auto"); stop_fighting(ch, TRUE); char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_DUEL_WINNER)); ch->hit = ch->max_hit; ch->mana = ch->max_mana; ch->move = ch->max_move; update_pos(ch); do_function(ch, &do_look, "auto"); if (IS_SET(ch->act, PLR_CHALLENGER)) REMOVE_BIT(ch->act, PLR_CHALLENGER); if (IS_SET(victim->act, PLR_CHALLENGER)) REMOVE_BIT(victim->act, PLR_CHALLENGER); if (IS_SET(victim->act, PLR_CHALLENGED)) REMOVE_BIT(victim->act, PLR_CHALLENGED); if (IS_SET(ch->act, PLR_CHALLENGED)) REMOVE_BIT(ch->act, PLR_CHALLENGED); ch->pcdata->challenger = NULL; ch->pcdata->challenged = NULL; victim->pcdata->challenger = NULL; victim->pcdata->challenged = NULL; arena = FIGHT_OPEN; return; } void extract_arena(CHAR_DATA * ch) { if (IS_SET(ch->act, PLR_CHALLENGED) && arena == FIGHT_START && ch->pcdata->challenger != NULL) do_function(ch, &do_arena_decline, ch->pcdata->challenger->name); if (IS_SET(ch->act, PLR_CHALLENGER) && arena == FIGHT_START && ch->pcdata->challenged != NULL) { REMOVE_BIT(ch->act, PLR_CHALLENGER); REMOVE_BIT(ch->pcdata->challenged->act, PLR_CHALLENGED); ch->pcdata->challenged->pcdata->challenger = NULL; ch->pcdata->challenged = NULL; arena = FIGHT_OPEN; } } bool IS_IN_ARENA(CHAR_DATA * ch) { if (!ch) return FALSE; if (IS_NPC(ch)) return FALSE; if (!IS_SET(ch->act, PLR_CHALLENGED) && !IS_SET(ch->act, PLR_CHALLENGER)) return FALSE; if (!ch->in_room) return FALSE; if (!IS_SET(ch->in_room->room_flags, ROOM_ARENA)) return FALSE; return TRUE; } CH_CMD(do_arena_help) { chprintln(ch, "Syntax: arena challenge <name>|drop"); chprintln(ch, " : arena accept <name>"); chprintln(ch, " : arena decline <name>"); chprintln(ch, " : arena bet <name>"); if (IS_IMMORTAL(ch)) { chprintln(ch, "Imm Only: arena <clear|lock|busy>"); switch (arena) { case FIGHT_OPEN: chprintln(ch, "Arena is [CLEAR]"); break; case FIGHT_START: chprintln(ch, "A challenge has been started."); break; case FIGHT_BUSY: chprintln(ch, "Arena is [BUSY]"); break; case FIGHT_LOCK: chprintln(ch, "Arena is [LOCKED]"); } } return; } CH_CMD(do_arena_clear) { DESCRIPTOR_DATA *d; if (!IS_IMMORTAL(ch)) { do_arena_help(ch, ""); return; } arena = FIGHT_OPEN; chprintln(ch, "Arena now set [CLEARED]"); announce(NULL, INFO_ARENA, "The arena has been opened."); for (d = descriptor_first; d != NULL; d = d->next) { if (d->connected == CON_PLAYING && d->character) { if (IS_SET(d->character->act, PLR_CHALLENGER)) REMOVE_BIT(d->character->act, PLR_CHALLENGER); if (IS_SET(d->character->act, PLR_CHALLENGED)) REMOVE_BIT(d->character->act, PLR_CHALLENGED); if (IS_SET(d->character->in_room->room_flags, ROOM_ARENA)) { char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE)); chprintln(d->character, "You re-appear in the Temple of Midgaard."); } } } return; } CH_CMD(do_arena_busy) { if (!IS_IMMORTAL(ch)) { do_arena_help(ch, ""); return; } arena = FIGHT_BUSY; chprintln(ch, "Arena now set [BUSY]"); announce(NULL, INFO_ARENA, "The arena is now busy."); return; } CH_CMD(do_arena_lock) { if (!IS_IMMORTAL(ch)) { do_arena_help(ch, ""); return; } arena = FIGHT_LOCK; chprintln(ch, "Arena now set [LOCKED]"); announce(NULL, INFO_ARENA, "The arena has been locked."); return; } CH_CMD(do_arena) { vinterpret(ch, argument, "challenge", do_arena_challenge, "decline", do_arena_decline, "accept", do_arena_accept, "bet", do_arena_bet, "clear", do_arena_clear, "busy", do_arena_busy, "lock", do_arena_lock, NULL, do_arena_help); }