RA2 Bot HOWTO
by David 'crt' Wright (wrightd@stanford.edu)
4-25-98
http://www.planetquake.com/arena
-------------

The info in this file, along with the included source files,
are everything you need to add basic RA2 support to your bot.
You may find a copy of the RA2 map specs (available from the
Rocket Arena 2 page) useful as well.

There are some functions in the arena.c file that are not
used in this example. You can use them to add better RA2
support to your bot.

The instructions in this file are based on my own experiences
modifying the Eraser bot to work with RA2. The Eraser simulates
a client, and so for the most part no bot-specific code had to
be added. If you bot does not simulate a client (and calls the 
appropriate client functions) you may need to make other changes.

This tutorial implements only the most basic bot support.
You might want to consider some of the following ways to 
enhance RA2 support

1. Remove the teleporter and deathmatch spawn pads.
These are turned off in RA2, and some of the RA2 maps may look funny
with them in. Just set ent->svflags|=SVF_NOCLIENT; in their spawn function.

2. Remove weapon dropping. This isn't a big deal since weapons are reset
every match, but it is a cosmetic issue.

3. Add telefrag avoidance. Right now if more people spawn than there are
destinations, players may telefrag.

4. Add better team support. This may be easy or hard depending on how your
bot team support is setup (or it may just "work" anyways).

5. Add a countdown.

6. Add menus / menu options for moving around arenas or adding bots.

7. Provide a set of default bindings for "toarena" and "mstart"
Perhaps bind F1-F10 to "toarena 1" - "toarena 10" and bind mstart to F11.

8. Actually have teams / check when match is over.

I will be available (time permitting) to answer questions regarding this
tutorial from bot authors. I'm afraid I don't have time to answer questions
from everyone who has public bot source that they are trying to add RA2
support to. The full RA2 source is not available for bot authors yet, but
may be in the future. Since RA2 departs pretty drastically from normal
deathmatch, you would probably find it difficult to integrate into your
bot anyways (and still keep normal DM play).



-----------------START--------------------

Eraser Specific Step
--------------------
In the 0.92 source there is a bug in 
PlayersRangeFromSpot.

In P_CLIENT.C (PlayersRangeFromSpot def):
	bestplayerdistance = 9999999;

--	for (n = 1; n < num_players; n++)
++	for (n = 0; n < num_players; n++)
	{


Step 1
------
Add the "arena.c" file to your project, and include the header file.
Add the arena_init call.

In G_LOCAL.H:
void FetchClientEntData (edict_t *ent);
++//arena
++#define ARENA
++#include "arena.h"

In G_SPAWN.C (SpawnEntities def):
	gi.dprintf ("%i entities inhibited\n", inhibit);
++	// arena
++	arena_init(g_edicts);



Step 2
------
Add the "arena" field to entities.

In G_SAVE.C (fields[] delc):
	{"map", FOFS(map), F_LSTRING},
++		//arena
++	{"arena", FOFS(arena),F_INT},

	// temp spawn vars -- only valid when the spawn function is called
	{"lip", STOFS(lip), F_INT, FFL_SPAWNTEMP},

In G_LOCAL.H (edict_t def):
++	//arena
++	int	arena; //for teleporters, spawnpoints, etc
}; //end of edict_t def

Step 3
------
Add field to client_respawn_t, and init it on connect.
Send player to correct waiting area.

In G_LOCAL.H (client_respawn_t def):
		int			helpchanged;
++//arena
++        int context;            // the arena # this person belongs to

In G_CLIENT.C (InitClientResp def):
	client->resp.coop_respawn = client->pers;
++		//arena
++	client->resp.context = 0;

In G_CLIENT.C (PutClientInServer def):
	if (!KillBox (ent))
	{	// could't spawn in?
	}
	gi.linkentity (ent);
++  //arena
++	move_to_arena(ent, ent->client->resp.context, true );

Step 4
------
Add the client command to move to different arenas.

In G_CMDS.C (ClientCommand def):
	else if (Q_stricmp (cmd, "wave") == 0)
		Cmd_Wave_f (ent);
++	//arena
++	else if (Q_stricmp (cmd, "toarena") == 0)
++		Cmd_toarena_f (ent,0);


Step 5
------
Create a method to spawn bots in an arena.
This will vary depending on your bot code.
For the Eraser source I simply added a new console
command (arena_bot <name> <arena>) to spawn a bot
in a specific arena.
You will need to modify the Cmd_add_arena_bot_f function
in arena.c to fit your specific bot.

In G_CMDS.C (ClientCommand def):
	else if (Q_stricmp (cmd, "wave") == 0)
		Cmd_Wave_f (ent);
++	//arena
++	else if (Q_stricmp (cmd, "arena_bot") == 0)
++		Cmd_add_arena_bot_f (ent,gi.argv(1),atoi(gi.argv(2)));

Step 6
------
Create commands to start/stop a match.
In Cmd_start_match_f it gives ammo to the players/bots.
You will need to modify it to put your own bot's pickbestweapon
function in there.

In G_CMDS.C (ClientCommand def):
	else if (Q_stricmp (cmd, "wave") == 0)
		Cmd_Wave_f (ent);
++		//arena
++	else if (Q_stricmp (cmd, "mstart") == 0)
++		Cmd_start_match_f(ent->client->resp.context);
++	else if (Q_stricmp (cmd, "mstop") == 0)
++		Cmd_stop_match_f(ent->client->resp.context);

---------------END---------------------------

At this point basic bot support will be complete
(you may need to make other bot-specific changes if some parts
do not function correctly).

To play a bot a player must:
1. Connect to the server
2. Enter an arena with "toarena <number>"
3. Spawn a bot with "arena_bot <name> <arena>"
4. Start the match with "mstart"

When the player or the bot is dead, the match can be restarted with
the "mstart" command. The "mstop" command should not be needed for 
most stuff.

Players can toggle weapons with console variables (bfg is off by default):
set shotgun 0
set supershotgun 0
set machinegun 0
set chaingun 0
set grenadelauncher 0
set hyperblaster 0
set railgun 0
set bfg 1
.. would only allow blaster, rockets, and bfg
Health, armor, and ammo amounts can also be set with console vars
(see get_arena_settings in arena.c for more info).