/*--------------------------------------------------------------------------* * ** WolfPaw 3.0 ** * *--------------------------------------------------------------------------* * WolfPaw 3.0 (c) 1997 - 1999 by Dale Corse * *--------------------------------------------------------------------------* * The WolfPaw Coding Team is headed by: Greywolf * * With the Assitance from: Callinon, Dhamon, Sentra, Wyverns, Altrag * * Scryn, Thoric, Justice, Tricops and Brogar. * *--------------------------------------------------------------------------* * Based on SMAUG 1.2a. Copyright 1994 - 1996 by Derek Snider * * SMAUG Coding Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, * * Swordbearer, Gorog, Grishnakh and Tricops. * *--------------------------------------------------------------------------* * Merc 2.1 Diku MUD Improvments (C) 1992 - 1993 by Michael Chastain, * * Michael Quan, and Michael Tse. * * Original Diku MUD (C) 1990 - 1991 by Sebastian Hammer, Michael Seifert, * * Hans Hendrik Strfeldt, Tom Madsen, and Katja Nyboe. * *--------------------------------------------------------------------------* * Arena Handling Functions Module * *--------------------------------------------------------------------------*/ #include <stdio.h> #include <string.h> #include <time.h> #include <unistd.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include "mud.h" ARENA_DATA *find_arena args( ( CHALLENGE_DATA *challenge ) ); CHALLENGE_DATA *find_challenge args( ( CHAR_DATA *ch ) ); ARENA_DATA *find_arena_by_challenge args( ( CHALLENGE_DATA *challenge ) ); void challenge_cancel args( ( CHAR_DATA *ch, CHAR_DATA *victim, char *argument ) ); CHAR_DATA *get_char args( ( char *name ) ); void pk_champ_check( CHAR_DATA *ch, CHAR_DATA *victim ); void give_pk_pin( CHAR_DATA *old_champ, CHAR_DATA *new_champ ); void do_bet2(CHAR_DATA *ch, char *argument ); /*=======================================================================* * function: do_challenge * * purpose: sends initial arena match query * * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96 * * ReVamped by Greywolf, May 1998 * *=======================================================================*/ void do_challenge(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; char buf[MAX_STRING_LENGTH]; char arg[MIL]; CHALLENGE_DATA *challenge=NULL; record_call( "<do_challenge>" ); one_argument( argument, arg ); if(IS_NPC(ch)) return; if ( in_arena(ch) ) { send_to_char("Your Already in the Arena!!\n\r",ch); return; } if ( ch->fighting ) { send_to_char("While Fighting!?! Noooo..!!!\n\r",ch); return; } if ( arg[0] == '\0' ) /* Status */ { if ( ( challenge = find_challenge(ch) )==NULL ) { send_to_char("But you have not been challenged, or challenged anyone!\n\r",ch); return; } if ( IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGER ) ) { send_to_char("Your Challenge Status:\n\r",ch); ch_printf( ch, "You have challenged: %s\n\r", capitalize(challenge->challenged) ); ch_printf( ch, "The Challenge is Currently %s.", challenge->fight_in_progress == FALSE ? "Waiting for Acceptance" : "in Progress" ); return; } if ( IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGED ) ) { send_to_char("Your Challenge Status:\n\r",ch); ch_printf( ch, "You have been challenged by: %s\n\r", capitalize(challenge->challenger ) ); ch_printf( ch, "The Challenge is Currently %s.", challenge->fight_in_progress == FALSE ? "Waiting for Acceptance" : "in Progress" ); return; } } /* The routine above handles this -- Cal if ( IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGER ) ) { send_to_char("You have already challenged someone else!\n\r",ch); return; } if ( IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGED ) ) { send_to_char("You have already been challenged!\n\r",ch); return; } */ if ( !str_cmp( arg, "accept" ) ) /* Accept the Challenge */ { char pk_buf[MAX_STRING_LENGTH]; ARENA_DATA *arena; if ( ( challenge = find_challenge(ch) )==NULL ) { send_to_char("But you have not been challenged, or challenged anyone!\n\r",ch); return; } if ( ( arena = find_arena(challenge) )==NULL) { send_to_char("All arena's are Full, please wait a few moments.\n\r",ch); return; } if((victim = get_char_world(ch,challenge->challenger)) == NULL) { send_to_char("Your Opponent is not logged in!\n\r",ch); return; } if ( !IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGED ) ) { send_to_char("But you have not been challenged!\n\r",ch); return; } send_to_char("You have accepted the challenge!\n\r",ch); act(AT_BLOOD,"$n accepts your challenge!",ch,NULL,victim,TO_VICT); challenge->fight_in_progress = TRUE; arena->in_use = TRUE; /* == announce the upcoming event == */ sprintf(buf,"&r[CHALLENGE]&W %s has accepted %s's challenge!\n\r",ch->name, victim->name); echo_to_all( AT_BLOOD,buf,ECHOTAR_ALL ); /* == now move them both to an arena for the fun == */ act( AT_BLOOD,"$n dissapears suddenly, eyes full of blood lust!",ch,NULL,NULL,TO_ROOM); send_to_char("You make your way into the arena.\n\r",ch); char_from_room(ch); char_to_room(ch,get_room_index(arena->char_room,1)); do_look( ch,"auto"); act( AT_BLOOD,"$n dissapears suddenly, eyes full of blood lust!",victim,NULL,NULL,TO_ROOM); send_to_char("You make your way to the arena.\n\r",victim); char_from_room(victim); char_to_room(victim,get_room_index(arena->vict_room,1)); do_look( victim,"auto"); /* == announce the bets == */ echo_to_all( AT_PLAIN,"&B[GAMBLE]&W To wager on the fight, type bet <amount> <playername> \n\r",ECHOTAR_ALL ); /* Viewing --GW */ echo_to_all( AT_PLAIN,"&B[&GVIEW IT!&B]&W To View the Battle, type view <char name>\n\r",ECHOTAR_ALL); if( IS_PKILL(ch) && IS_PKILL(victim) ) { if ( IS_SET( victim->pcdata->flags, PCFLAG_PKCHAMP) ) { sprintf(pk_buf,"&BYou hear the voice of &r%s &BScream...",capitalize(victim->name)); echo_to_all(AT_PLAIN,pk_buf,ECHOTAR_ALL); echo_to_all(AT_PLAIN,"\n&RTHERE CAN BE ONLY ONE!!!&W\n",ECHOTAR_ALL); } if ( IS_SET( ch->pcdata->flags, PCFLAG_PKCHAMP) ) { sprintf(pk_buf,"&BYou hear the voice of &r%s &BScream...",capitalize(ch->name)); echo_to_all(AT_PLAIN,pk_buf,ECHOTAR_ALL); echo_to_all(AT_PLAIN,"\n&RTHERE CAN BE ONLY ONE!!!&W\n",ECHOTAR_ALL); } } return; } else if ( !str_cmp( arg, "decline" ) ) /* Decline the Challenge */ { if ( ( challenge = find_challenge(ch) )==NULL ) { send_to_char("But you have not been challenged, or challenged anyone!\n\r",ch); return; } if((victim = get_char_world(ch,challenge->challenger)) == NULL) { send_to_char("Your opponent logged in!\n\r",ch); return; } if(victim == ch && IS_SET(ch->pcdata->flags, PCFLAG_CHALLENGER)) { REMOVE_BIT(victim->pcdata->flags, PCFLAG_CHALLENGER); send_to_char("Challenge removed!\n\r",ch); sprintf(buf,"&R[CHALLENGE]&W %s has STEPED DOWN from the challenge! WHAT A WUSS!!\n\r",victim->name); if ( ( victim = get_char_world(ch,challenge->challenged))!=NULL && !IS_NPC(victim) ) { ch_printf(victim,"%s has STEPPED DOWN from the challenge!\n\r",capitalize(ch->name) ); REMOVE_BIT(victim->pcdata->flags, PCFLAG_CHALLENGED); } echo_to_all( AT_BLOOD,buf,ECHOTAR_ALL ); UNLINK(challenge, first_challenge, last_challenge, next, prev ); DISPOSE(challenge); return; } if (victim->desc && IS_SET(victim->pcdata->flags, PCFLAG_CHALLENGER) ) { REMOVE_BIT(victim->pcdata->flags, PCFLAG_CHALLENGER); REMOVE_BIT(ch->pcdata->flags, PCFLAG_CHALLENGED); send_to_char("Challenge declined!\n\r",ch); act(AT_BLOOD,"$n has declined your challenge.",ch,NULL,victim,TO_VICT); sprintf(buf,"&R[CHALLENGE]&W %s has DECLINED %s's challenge! WHAT A WUSS!!\n\r",ch->name, victim->name); echo_to_all( AT_BLOOD,buf,ECHOTAR_ALL ); UNLINK(challenge, first_challenge, last_challenge, next, prev ); DISPOSE(challenge); return; } return; } else /* New Challenge */ { if(IS_SET(ch->pcdata->flags, PCFLAG_CHALLENGED)) { send_to_char("You have already been challenged, either ACCEPT or DECLINE first.\n\r",ch); return; } if(IS_SET(ch->pcdata->flags, PCFLAG_CHALLENGER)) { send_to_char("You have already challenged someone!\n\r", ch ); return; } if (IS_SET(ch->pcdata->flagstwo, MOREPC_HOARDER) ) { send_to_char("Get out of the Hoarder's Void First!\n\r",ch); return; } if ( ch->in_room->vnum == 8 ) { send_to_char("But .... But ... YOUR IN HELL! Hello?\n\r",ch); return; } if((victim = get_char_world(ch,arg)) == NULL) { send_to_char("They are not playing.\n\r",ch); return; } if ( IS_NPC(victim) ) { send_to_char("Not on NPC's!\n\r",ch); return; } if(IS_SET(victim->pcdata->flags, PCFLAG_CHALLENGED)) { send_to_char("That person has already been challenged.\n\r",ch); return; } if(IS_SET(victim->pcdata->flags, PCFLAG_CHALLENGER)) { send_to_char("That person has already challenged someone!\n\r", ch ); return; } if (ch->in_room->sector_type == 15 ) { send_to_char("You cannot challenge well in a rented room\n\r", ch); return; } if (victim->in_room->sector_type == 15 ) { send_to_char("Sorry they are in a rented room at the moment\n\r", ch); return; } if(IS_NPC(victim) || victim == ch ) { send_to_char("You cannot challenge NPC's, or yourself.\n\r",ch); return; } if (IS_SET(victim->pcdata->flagstwo, MOREPC_HOARDER) ) { send_to_char("You cant challenge someone who is in the Hoarder's Void!\n\r",ch); return; } if ( victim->in_room->vnum == 8 ) { send_to_char("That character pissed someone off, and is in Hell. No can do!\n\r",ch); return; } if(IS_SET(victim->pcdata->flags, PCFLAG_CHALLENGER)) { send_to_char("They have already challenged someone else.\n\r",ch); return; } if(victim->fighting != NULL ) { send_to_char("That person is engaged in battle right now.\n\r",ch); return; } if( IS_IMMORTAL(ch) && IS_IMMORTAL(victim) ) { send_to_char("God vs God? yeah ok right... NOT\n\r", ch); return; } /* == Now for the challenge == */ CREATE( challenge, CHALLENGE_DATA, 1 ); SET_BIT(ch->pcdata->flags, PCFLAG_CHALLENGER); SET_BIT(victim->pcdata->flags, PCFLAG_CHALLENGED); send_to_char("Challenge ISSUED!\n\r",ch); act(AT_BLOOD,"$n has challenged you to a death match.",ch,NULL,victim,TO_VICT); send_to_char("type: CHALLENGE ACCEPT to meet the challenge.\n\r",victim); send_to_char("OR:\n\r",victim); send_to_char("type: CHALLENGE DECLINE to chicken out.\n\r",victim); sprintf(buf,"0.%s",ch->name); challenge->challenger = STRALLOC(buf); sprintf(buf,"0.%s",victim->name); challenge->challenged = STRALLOC(buf); challenge->fight_in_progress = FALSE; challenge->arena_number = 1; LINK( challenge, first_challenge, last_challenge, next, prev ); /* == announce the upcoming event == */ sprintf(buf,"&r[CHALLENGE]&W %s has issued a challenge to %s!\n\r", ch->name, victim->name); echo_to_all( AT_PLAIN,buf,ECHOTAR_ALL ); return; } } /*======================================================================* * function: do_bet * * purpose: to allow players to wager on the outcome of arena battles * * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96 * *======================================================================*/ void do_bet(CHAR_DATA *ch, char *argument) { char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; CHAR_DATA *fighter; int wager; record_call( "<do_bet>" ); if ( ch->in_room->vnum == BLACKJACK ) { do_bet2(ch,argument); return; } argument = one_argument(argument, arg); if(argument[0] == '\0' || !is_number(arg)) { send_to_char("Syntax: BET [amount] [player]\n\r",ch); return; } /*== disable the actual fighters from betting ==*/ if(IS_SET(ch->pcdata->flags, PCFLAG_CHALLENGER) || IS_SET(ch->pcdata->flags, PCFLAG_CHALLENGED)) { send_to_char("You can't bet on this battle.\n\r",ch); return; } /*== make sure the choice is valid ==*/ if((fighter = get_char_world(ch,argument)) == NULL) { send_to_char("That player is not in the arena.\n\r",ch); return; } /*== do away with the negative number trickery ==*/ if(!str_prefix("-",arg)) { send_to_char("Error: Invalid argument!\n\r",ch); return; } wager = atoi(arg); if(wager > 5001 || wager < 1) { send_to_char("Wager range is between 1 and 5000\n\r",ch); return; } /*== make sure they have the cash ==*/ if(wager > ch->gold) { send_to_char("You don't have that much gold to wager!\n\r",ch); return; } /*== now set the info ==*/ ch->pcdata->gladiator = fighter->name; ch->pcdata->plr_wager = wager; sprintf(buf,"You have placed a %d gold wager on %s\n\r",wager,fighter->name); send_to_char(buf,ch); return; } /* * Find the right Challenge Array for the char --GW */ CHALLENGE_DATA *find_challenge( CHAR_DATA *ch ) { CHALLENGE_DATA *temp, *temp_next; char buf[MSL]; for ( temp = first_challenge; temp; temp = temp_next ) { temp_next = temp->next; sprintf(buf,"0.%s",ch->name); if ( !str_cmp( buf, temp->challenger ) ) return temp; if ( !str_cmp( buf, temp->challenged ) ) return temp; } return NULL; } /* * Find an Open Arena --GW */ ARENA_DATA *find_arena( CHALLENGE_DATA *challenge ) { ARENA_DATA *temp, *temp_next; for( temp = first_arena; temp; temp = temp_next ) { temp_next = temp->next; if ( !challenge ) { bug( "Null challenge!",0); return NULL; } if ( temp->in_use == FALSE ) { challenge->arena_number = temp->arena_number; return temp; } } return NULL; } ARENA_DATA *find_arena_by_challenge( CHALLENGE_DATA *challenge ) { ARENA_DATA *temp, *next_temp; for ( temp = first_arena; temp; temp = next_temp ) { next_temp = temp->next; if ( !challenge ) return NULL; if ( temp->arena_number == challenge->arena_number ) return temp; } return NULL; } /* * Terminate a Challenge --GW */ void challenge_cancel( CHAR_DATA *ch, CHAR_DATA *victim, char *argument ) { char arg[MSL]; CHAR_DATA *challenger; CHAR_DATA *challenged; CHALLENGE_DATA *temp; CHALLENGE_DATA *temp_next; one_argument( argument, arg ); /* All First */ if ( !str_cmp( arg, "all" ) ) { for ( temp = first_challenge; temp; temp = temp_next ) { temp_next = temp->next; challenger = get_char_world(ch, temp->challenger ); challenged = get_char_world(ch, temp->challenged ); ch = challenger; victim = challenged; if ( challenger && challenged && in_arena( challenger ) ) { send_to_char("\aYour Challenge has been Canceled.\n\r",challenger); send_to_char("\aYour Challenge has been Canceled.\n\r",challenged); ch->hit = ch->max_hit; victim->hit = victim->max_hit; update_pos(ch); update_pos(victim); stop_fighting( challenger, TRUE ); char_from_room( challenger ); char_from_room( challenged ); char_to_room( challenger, get_room_index( 30601,1 ) ); char_to_room( challenged, get_room_index( 30602,1 ) ); REMOVE_BIT( challenger->pcdata->flags, PCFLAG_CHALLENGER ); REMOVE_BIT( challenged->pcdata->flags, PCFLAG_CHALLENGED ); UNLINK(temp, first_challenge, last_challenge, next, prev ); DISPOSE(temp); return; } else { if ( challenger && challenged ) { send_to_char("\aYour Challenge has been Canceled.\n\r",challenger); send_to_char("\aYour Challenge has been Canceled.\n\r",challenged); REMOVE_BIT( challenger->pcdata->flags, PCFLAG_CHALLENGER ); REMOVE_BIT( challenged->pcdata->flags, PCFLAG_CHALLENGED ); UNLINK(temp, first_challenge, last_challenge, next, prev ); DISPOSE(temp); } } } } return; } /* * Get a char from the game, regardless of anything, just do it --GW */ CHAR_DATA *get_char( char *name ) { CHAR_DATA *ch1; char buf[MSL]; char buf2[MSL]; for( ch1 = first_char; ch1; ch1 = ch1->next ) { if ( name[0] != '0' && name[1] != '.' ) sprintf(buf,"0.%s",name); else sprintf(buf,"%s",name); sprintf(buf2,"0.%s",ch1->name); if ( !str_cmp( buf, buf2 ) ) return ch1; } return NULL; } /* * Pass the Pin! --GW * ch is always Winner, Vict Loser */ void pk_champ_check( CHAR_DATA *ch, CHAR_DATA *victim ) { char buf[MSL]; if ( IS_SET( ch->pcdata->flagstwo, MOREPC_ETERNAL_PK ) ) return; /* We beat the Champion! -- Lets Championize! */ if ( IS_SET( victim->pcdata->flags, PCFLAG_PKCHAMP ) ) { echo_to_all(AT_PLAIN,"&RThe Realms Rise up in PRAISE!",ECHOTAR_ALL); echo_to_all(AT_PLAIN,"&WFrom this Match rises a &RNew Champion!&W",ECHOTAR_ALL); sprintf(buf,"&R%s&W is the New &RPlayer Kill Champion&W!",ch->name); echo_to_all(AT_PLAIN,buf,ECHOTAR_ALL); REMOVE_BIT(victim->pcdata->flags, PCFLAG_PKCHAMP); SET_BIT(ch->pcdata->flags, PCFLAG_PKCHAMP); give_pk_pin(victim,ch); ch->pcdata->pkchamps++; sysdata.pkchamp = str_dup(ch->name); save_sysdata(sysdata); return; } return; } void give_pk_pin( CHAR_DATA *old_champ, CHAR_DATA *new_champ ) { OBJ_DATA *obj; if ( ( obj = get_obj_wear( old_champ, "pkchamppin" ) ) == NULL ) { bug("Give_Pk_Pin: Champ not wearing a Pin!",0); } unequip_char( old_champ, obj ); obj_from_char( obj ); obj_to_char( obj, new_champ ); equip_char( new_champ, obj, WEAR_CHAMP ); return; } /* * Allow people to view a match in progress as if they were in the room --GW */ void do_view( CHAR_DATA *ch, char *argument ) { char arg1[MSL]; CHAR_DATA *victim; int gallery_vnum=41; ROOM_INDEX_DATA *gallery; one_argument( argument, arg1 ); if ( IS_NPC(ch) ) return; if ( IS_SET(ch->pcdata->flagstwo, MOREPC_HOARDER) ) { send_to_char("I don't think so, Tim.\n\r",ch); return; } if ( arg1[0] == '\0' ) { send_to_char("Syntax: view <char name>/<all>\n\r",ch); return; } if ( ( victim=get_char_world( ch, arg1 ) )==NULL) { send_to_char("You can't seem to find that person\n\r",ch); return; } if ( !in_arena( victim ) ) { send_to_char("That person is not in the Arena!\n\r",ch); return; } if ( ch->fighting && ch->fighting->who ) { send_to_char("Not while you are fighting! You better watch this match closer!\n\r",ch); return; } if ( ch->in_room && ch->in_room->vnum == 8 ) { send_to_char("Ya right.\n\r",ch); return; } if ( IS_SET(ch->pcdata->flagstwo, MOREPC_ARRESTED ) ) { send_to_char("Uh .. no.\n\r",ch); return; } if ( IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGED ) || IS_SET( ch->pcdata->flags, PCFLAG_CHALLENGER ) ) { send_to_char("And just how do you intend to pull that off?\n\r",ch); return; } if ( str_cmp(ch->pcdata->arena_viewing, "None" ) ) { send_to_char("Sorry, you are already Viewing a Match.\n\r",ch); return; } if ( IS_SET( ch->pcdata->flags, PCFLAG_KOMBAT ) ) { send_to_char("Um....... No.\n\r",ch); return; } if ( ( gallery=get_room_index( gallery_vnum, 1 ) )==NULL ) { send_to_char("Can't seem to find the Viewing Gallery.. talk to a god..\n\r",ch); return; } char_from_room(ch); char_to_room(ch,gallery); ch->pcdata->arena_viewing = STRALLOC( victim->name ); send_to_char("You start viewing the match.\n\r",ch); return; } void stop_viewers( void ) { CHAR_DATA *ch, *ch_next; ROOM_INDEX_DATA *recall; recall=get_room_index( 30601, 1 ); for( ch=first_char; ch; ch = ch_next ) { ch_next = ch->next; if ( str_cmp( ch->pcdata->arena_viewing,"none" ) && ch->in_room && ch->in_room->vnum == 41 ) { send_to_char("The Match is over, you make your way back to Mithras.\n\r",ch); ch->pcdata->arena_viewing = STRALLOC( "None" ); char_from_room( ch ); char_to_room( ch, recall ); do_look( ch, "auto" ); } } return; } /* * Write the Fight stuff to the Gallery --GW */ void write_to_gallery( CHAR_DATA *fighter, char *message ) { DESCRIPTOR_DATA *d, *d_next; CHAR_DATA *ch; if ( !message ) return; for ( d=first_descriptor; d; d = d_next ) { d_next = d->next; if ( !d ) continue; ch = d->character; if ( !ch ) continue; if( d->connected == CON_PLAYING && ch->pcdata->arena_viewing ) { if ( !str_cmp(ch->pcdata->arena_viewing, fighter->name ) ) send_to_char(message,ch); } } return; }