From: Josh Brittenham <Josh.Brittenham@netins.net>

Hello all,

I've just finished with some arena code.  It's not completely
bug tested, so use this at your own risk, but what I have tested 
seems to work pretty well.  I'm not too picky.  I don't care if
you use it, I don't care if you give me any recognition, I don't
care if you print it out, tear it up, and piss on it.  All I ask
is that if you like it to send me some e-mail with some comments,
or suggestions, etc,.  Also any bugs you find I would appreciate
being sent to me so I can change this accordingly.  As of right
now it only supports one kind of war, which is a single war. Every
man/woman for themselves.  I'm currently in the process of a team
war which divides the people up into red and blue teams, and
they have a massive rumble.  So, when you use this, simply use
the syntax:  startwar 1 <min_level> <max_level>.

Here goes nothing:

/* Act.Comm.C */
In the do_channels function, add:

    send_to_char("war            ",ch);
    if (!IS_SET(ch->comm,COMM_NOWAR))
      send_to_char("ON\n\r", ch);
    else
      send_to_char("OFF\n\r", ch);

Add this anywhere:

void do_wartalk(const char *txt)
{
  DESCRIPTOR_DATA *d;
  char buf[MAX_STRING_LENGTH];

  for (d = descriptor_list; d != NULL; d = d->next)
  {
    CHAR_DATA *victim;

    victim = d->original ? d->original : d->character;

    if (d->connected == CON_PLAYING &&
        !IS_SET(victim->comm,COMM_NOWAR) &&
        !IS_SET(victim->comm,COMM_QUIET))
    {
      sprintf(buf, "&c[&RWAR&c] &R%s&w\n\r", txt);
      send_to_char(buf, victim);
    }
  }
}

Also anywhere, add:

void do_nowar(CHAR_DATA *ch, char *argument)
{
  if (IS_SET(ch->comm, COMM_NOWAR))
  {
    REMOVE_BIT(ch->comm, COMM_NOWAR));
    send_to_char("War channel ON.\n\r", ch);
  }
  else
  {
    SET_BIT(ch->comm, COMM_NOWAR));
    send_to_char("War channel OFF.\n\r", ch);
  }
}

/* Fight.C */
At the top, add:

#include "arena.h"

Find the lines:

if ( victim->position == POS_DEAD )
{
  group_gain( ch, victim );

Right under this, there is a line that says:

if (!IS_NPC(victim)) - Change it to:

if (!IS_NPC(victim) && 
!IS_SET(victim->in_room->room_flags, ROOM_ARENA));


Before the lines:

sprintf( log_buf, "%s got toasted by %s at %s [room %d]",
            (IS_NPC(victim) ? victim->short_descr : victim->name),
            (IS_NPC(ch) ? ch->short_descr : ch->name),
            ch->in_room->name, ch->in_room->vnum);

Add:

if (!IS_SET(victim->in_room->room_flags, ROOM_ARENA))

After them, add:

else
{
  REMOVE_BIT(victim->act, PLR_ARENA);
  inwar--;
  if (inwar == 1)
  {
    sprintf(buf, "&c%s &Ris victorious in the arena!", ch->name);
    do_wartalk(buf); 
    wartype = 0;
    min_level = 0;
    max_level = 0;
    iswar = FALSE;
    inwar = 0;
    wartimer = 0;
    wartimeleft = 0;
    REMOVE_BIT(ch->act, PLR_ARENA);
    char_from_room(ch);
    char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE));
  }
}

Find the comment:
/* dump the flags */

Add to the line that say:

if (ch != victim && !IS_NPC ... 

&& !IS_SET(victim->in_room->room_flags, ROOM_ARENA);

Find the comment:
/* Player doing the killing */
After the:

else
{

Add:

if (IS_SET(victim->in_room->room_flags, ROOM_ARENA))
  return FALSE;

There is another exact same comment further down, do the same to it.

Find the comment:
/*
 * Charm-o-Rama.
 */

Add before it:

if (IS_SET(victim->in_room->room_flags, ROOM_ARENA))
  return;

In the function: Void raw_kill: Before the line:

make_corpse(victim)

Add:

if (!IS_SET(victim->in_room->room_flags, ROOM_ARENA))

Find the line:

send_to_char("Kill stealing is not permitted...")

Add to to the if statement:

|| !IS_SET(victim->in_room->room_flags, ROOM_ARENA);

/* Interp.C */
Declare this line somewhere:

"{ "war",            do_war,         POS_STANDING,    0, 
LOG_NORMAL, 1},"

And:

"{ "nowar",      do_nowar,    POS_DEAD,    0,    LOG_NORMAL,  1),"

As well as: (This one should be in imm defines)

    "{ "startwar",       do_startwar,    POS_DEAD,       IM, 
    LOG_NORMAL, 0 },"

/* Interp.H */
Of course, add:
DECLARE_DO_FUN( do_war	);
DECLARE_DO_FUN( do_startwar	);
DECLARE_DO_FUN( do_nowar  );

/* Merc.H */
#define ROOM_ARENA		(XX) <-- Whatever your next open variable is.
#define PLR_ARENA		(XX)
#define COMM_NOWAR		(XX)
#define SINGLE_WAR_WAITING_ROOM (Vnum,whichever you want on your mud)

/* Tables.C */
After the line:

{"nowhere",		ROOM_NOWHERE ....

Add:

{   "arena",                ROOM_ARENA,             TRUE    },

Ok, I hope that should be about it.  There is an arena.h, and arena.c 
file included.  You have to add arena.o to your objfiles.  Also, in 
the arena.c file, you'll notice a line that goes:

random = get_room_index(12004)

You'll have to edit some rooms on your mud, and give them the "arena" 
flag, then simply change this line to:

random = get_room_index((number_range(vnum, vnum))) - Whatever they 
are on your mud.

Sorry for the length of this note, I hope it helps some people out.
If you have any comments, or suggestions, bugs, etc., e-mail me at 
ruiner@mail.org.  I'll also be glad to help you get it up and running 
on your own mud.

// RuineR
// The Mad Coder


  [ Part 2: "Attachment information." ]

Shortly after I posted the code, I found a couple things that need to 
be changed.  First of all, at the

"dump the flags" comment part.
Take out the part that says:

&& !IS_SET(victim->in_room->room_flags, ROOM_ARENA)
replace it with
&& !IS_SET(victim->act, PLR_ARENA)

If you don't, you got "crash-o-rama" :)

Also, there are a hell of alot more "kill stealing not permitted"
areas you have to add the !IS_SET(victim->in_room->room_flags, 
ROOM_ARENA), to.. unless of course you to make it so when people are 
fighting in the arena, they can't attack people that are already 
fighting, which takes out the fun of every man for himself.

// RuineR
// The Mad Coder

Ok, I've included another arena.c file, replace the old one with 
this, there are a few fixes in it.  And here is a listing of just 
SOME of the changes that need to take place in FIGHT.C.  (I'm going 
over this one again, cause it's the only one that needs changed)
The rest of the changes to get this code running were in my first 
post, and shouldn't need changed.  Once again, sorry for the mutiple 
posts, and I hope somebody makes good use of this code. :)

/* fight.c */

Find the following:
 
/*
 * Payoff for killing things.
 */
 if ( victim->position == POS_DEAD )
 {
   group_gain( ch, victim );

   if ( !IS_NPC(victim))

Change the last line to:
  
   if (!IS_NPC(victim) && !IS_SET(victim->in_room->room_flags, 
       ROOM_ARENA)

Find the following:

sprintf(log_buf, "%s got toasted by %s at %s [room %d]",
       (IS_NPC(victim) ? victim->short_descr : victim->name),
       (IS_NPC(ch) ? ch->short_descr : ch->name),
        ch->in_room->name, ch->in_room->vnum);

Add immediately after:

if (IS_SET(victim->act, PLR_ARENA))
{
  REMOVE_BIT(victim->act, PLR_ARENA);
  inwar--;
  if (inwar == 1)
  {
    sprintf(buf, "&c%s &Ris victorious in the arena!", ch->name); 
    do_wartalk(buf);
    wartype = 0;
    min_level = 0;           
    max_level = 0;
    iswar = FALSE;
    inwar = 0;
    wartimer = 0;
    wartimeleft = 0;
    REMOVE_BIT(ch->act, PLR_ARENA);
    char_from_room(ch);
    char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE));
    do_look(ch, "auto");
  }
}

Find the following:

/* dump the flags */
if (ch != victim && !IS_NPC(ch) && !is_same_clan(ch,victim))

Change the last line to:

if (ch!= victim && !IS_NPC(ch) && !is_same_clan(ch,victim) &&
    !IS_SET(victim->in_room->room_flags, ROOM_ARENA))

Find the following (2 occurances):

/* player doing the killing */

Add in the "else" statement:

if (IS_SET(victim->in_room->room_flags, ROOM_ARENA))
return FALSE;

Find the following:

/*
 * Charm-o-rama
 */

Before it, add:

if (IS_SET(victim->in_room->room_flags, ROOM_ARENA))
  return;

In the raw_kill function - Find:

make_corpse(victim);

Add before it:

if (!IS_SET(victim->in_room->room_flags, ROOM_ARENA))

Also in the raw_kill function - Find:

extract_char(victim, FALSE);

Before it, add:

if (!IS_SET(victim->in_room->room_flags, ROOM_ARENA))

After it, add:

else
{
  char_from_room(victim);
  char_to_room(victim, (get_room_index(ROOM_VNUM_TEMPLE)));
  do_look(victim, "auto");
}

Finally, find all occurances of the line:

send_to_char("Kill stealing is not permitted.\n\r", ch);

Add to the check:

&& !IS_SET(victim->in_room->room_flags, ROOM_ARENA);

---------arena.c

/***************************************************************************
 *  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			   *
***************************************************************************/

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "arena.h"

void do_startwar(CHAR_DATA *ch, char *argument)
{
  char buf[MAX_STRING_LENGTH];
  char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
  char arg3[MAX_INPUT_LENGTH];
  DESCRIPTOR_DATA *d;

  argument = one_argument(argument, arg1);
  argument = one_argument(argument, arg2);
  argument = one_argument(argument, arg3);
  if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
  {
    send_to_char("Syntax: startwar <type> <min_level> <max_level>\n\r", ch);
    return;
  }

  if (atoi(arg1) < 1 || atoi(arg1) > 2)
  {
    send_to_char("The type either has to be 1, or 2.\n\r", ch);
    return;
  }

  if (atoi(arg2) <= 0 || atoi(arg2) > 250)
  {
    send_to_char("Level must be between 1 and 250.\n\r", ch);
    return;
  }

  if (atoi(arg3) <= 0 || atoi(arg3) > 250)
  {
    send_to_char("Level must be between 1 and 250.\n\r", ch);
    return;
  }

  if (atoi(arg3) < atoi(arg2))
  {
    send_to_char("Max level must be greater than the min level.\n\r", ch);
    return;
  }

  if (iswar == TRUE)
  {
    send_to_char("There is already a war going!\n\r", ch);
    return;
  }

  iswar = TRUE;
  wartype = atoi(arg1);
  min_level = atoi(arg2);
  max_level = atoi(arg3);
  sprintf(buf, "&c%s &Rwar started for levels &Y%d &Rto &Y%d&R.  Type 'WAR' to kill or be killed", wartype == 1 ? "Single" : "Team", min_level, max_level);
  do_wartalk(buf);
  wartimeleft = 3;
  for (d = descriptor_list; d != NULL; d = d->next)
  {
    if (!IS_NPC(d->character))
    {
      if (IS_SET(d->character->act, PLR_ARENA))
        REMOVE_BIT(d->character->act, PLR_ARENA);
    }
  }
}

void do_war(CHAR_DATA *ch)
{
  char buf[MAX_STRING_LENGTH];
  ROOM_INDEX_DATA *location;

  if (iswar != TRUE) 
  {
    send_to_char("There is no war going!\n\r", ch);
    return;
  }

  if (ch->level < min_level || ch->level > max_level)
  {
    send_to_char("Sorry, you can't join this war.\n\r", ch);
    return;
  }

  if (IS_SET(ch->act, PLR_ARENA))
  {
    send_to_char("I don't think so.\n\r", ch);
    return;
  }

  if (wartype == 1)
  {
    if ((location = get_room_index(SINGLE_WAR_WAITING_ROOM)) == NULL)
    {
      send_to_char("Arena is not yet completed, sorry.\n\r", ch);
      return;
    }
    else
    {
      act("$n goes to get $s &Rass&w whipped in war!", ch, NULL, NULL, TO_ROOM); 
      char_from_room(ch);
      char_to_room(ch, location);
      SET_BIT(ch->act, PLR_ARENA);
      sprintf(buf, "&c%s &R(&cLevel &Y%d&R) joins the war!", ch->name, ch->level);
      do_wartalk(buf);
      act("$n arrives to get $s &Rass&w whipped!", ch, NULL, NULL, TO_ROOM);
      inwar++;
      do_look(ch, "auto");
      return;
    }
  }
}

void war_update(void)
{
  char buf[MAX_STRING_LENGTH];
  CHAR_DATA *ch;
  DESCRIPTOR_DATA *d;
  ROOM_INDEX_DATA *random;
  int x;
  
  if (wartimeleft > 0)
  {
    sprintf(buf, "%d tick%s left to join the war.", wartimeleft, wartimeleft == 1 ? "" : "s");
    do_wartalk(buf);
    sprintf(buf, "%d %s %s fighting in the war, so far.", inwar, inwar == 1 ? "person" : "people", inwar == 1 ? "is" : "are");
    do_wartalk(buf);
    sprintf(buf, "Type of war: &Y%d &R- &Y%d&R, &C%s war&R.&w", min_level, max_level, wartype == 1 ? "Single" : "Team");
    do_wartalk(buf);
    wartimeleft--;
    return;
  }

  if (wartimeleft == 0 && iswar == TRUE && wartimer == 0)
  {  
    if (inwar == 0 || inwar == 1)
    {
      sprintf(buf, "Not enough people for war.  War reset.");
      do_wartalk(buf);
      iswar = FALSE;
      wartimeleft = 0;
      wartimer = 0;
      min_level = 0;
      max_level = 0;
      wartype = 0;
      for(d = descriptor_list; d != NULL; d = d->next)
      {
        if (IS_SET(d->character->act, PLR_ARENA))
        {
          char_from_room(d->character);
          char_to_room(d->character, (get_room_index(ROOM_VNUM_TEMPLE)));
          do_look(d->character, "auto");
        }
      }
    }
    else
    {
      sprintf(buf, "The battle begins! %d players are fighting!", inwar);
      do_wartalk(buf);
      wartimer = 20;
      for(d = descriptor_list; d != NULL; d = d->next)
      {
        if (IS_SET(d->character->act, PLR_ARENA))
        {
          random = get_room_index(12004);
          char_from_room(d->character);
          char_to_room(d->character, random);
          do_look(d->character, "auto");
        }
      }
    }
  }
  return;
}


================UPDATED 27-DEC-2000===========================
There were undefined functions left, this was posted to the rom mailing
list, this is an untested fix:

In merc.h near your other PULSES
------------------------------------
#define PULSE_WAR               (30 * PULSE_PER_SECOND)

In update.c at top of file declare prototype
----------------------------------------
void war_update     args( ( void ) );           /* Arena.c */

in top call of updated_handler():

    static  int     pulse_war;

place in update handler();

    if ( --pulse_war <= 0)
    {
        pulse_war = PULSE_WAR;
        war_update ( );
    }