|
QuakeZone MOD Coding Tutorials
|
|
|
Introduction Pre-requisites Code Notes Exercises |
|
| Introduction |
|
|
Related Links
15 Teamplay Enhancements
| This tutorial demonstrates how to allocate different weapons to different teams. In this example for 2 teams, the host can configure either team to use rocket launchers or railguns, thus giving team rocket arena, rail arena or rocket versus rail. |
| Pre-requisites |
|
|
You will require tutorial 15, team play enhancements, plus any tutorials required for that. |
| Code |
|
|
g_local.h Add the following lines as indicated:
1. Locate the teamplay enhancements cvars:
extern cvar_t *sv_allowswitch; // allow team switching
extern cvar_t *sv_teamrail1; // team rail options <-- insert
extern cvar_t *sv_teamrail2; // <-- insert
2. Locate prototypes for p_client.c:
void AssignSkin(edict_t *ent, char *s); // PJT - team play
void AssignWeapon(edict_t *ent); // PJT - team rail <-- insert
3. Locate struct client_respawn_t:
int team; // PJT - team play
int teamrail; // PJT - rail option <-- insert
4. Locate table team_Table (added for teamplay enhancements):
// PJT - team play
typedef struct
{
char *name; // team name
int score; // team score
int teamrail; // team rail option <-- insert
} team_data;
extern team_data team_table[];
// PJT
p_client.c Make folloiwng changes as indicated:
1. At the top of the code, add the cvars as indicated:
cvar_t *sv_allowswitch; // PJT - teams - allow switching (teamplay enhancements)
cvar_t *sv_teamrail1; // PJT - team rail option <-- insert
cvar_t *sv_teamrail2; // PJT <-- insert
2. Locate the table team_table and totally replace with the following:
// PJT - team play
team_data team_table[] =
{
{"", 0, 0},
{"Blue", 0, 0},
{"Red", 0, 1}
}
;
// PJT
3. Just before procedure AssignTeam (added for teamplay enhancements) add following new procedure:
// PJT - team rocket / rail
void AssignWeapon(edict_t *self)
{
gitem_t *item;
// determine rocket/rail option for team
self->client->resp.teamrail = team_table[self->client->resp.team].teamrail;
// give rockets, no rails
if (self->client->resp.teamrail == 0)
{
item = FindItem("Slugs");
self->client->pers.selected_item = ITEM_INDEX(item);
self->client->pers.inventory[self->client->pers.selected_item] = 0;
item = FindItem("Railgun");
self->client->pers.selected_item = ITEM_INDEX(item);
self->client->pers.inventory[self->client->pers.selected_item] = 0;
item = FindItem("Rockets");
self->client->pers.selected_item = ITEM_INDEX(item);
self->client->pers.inventory[self->client->pers.selected_item] = 5;
item = FindItem("Rocket Launcher");
self->client->pers.selected_item = ITEM_INDEX(item);
self->client->pers.inventory[self->client->pers.selected_item] = 1;
item->use(self, item);
self->client->pers.max_rockets = 50;
self->client->pers.max_slugs = 0;
}
// give rail, no rockets
else
{
item = FindItem("Rockets");
self->client->pers.selected_item = ITEM_INDEX(item);
self->client->pers.inventory[self->client->pers.selected_item] = 0;
item = FindItem("Rocket Launcher");
self->client->pers.selected_item = ITEM_INDEX(item);
self->client->pers.inventory[self->client->pers.selected_item] = 0;
item = FindItem("Slugs");
self->client->pers.selected_item = ITEM_INDEX(item);
self->client->pers.inventory[self->client->pers.selected_item] = 10;
item = FindItem("Railgun");
self->client->pers.selected_item = ITEM_INDEX(item);
self->client->pers.inventory[self->client->pers.selected_item] = 1;
item->use(self, item);
self->client->pers.max_rockets = 0;
self->client->pers.max_slugs = 50;
}
}
// PJT
4. At the end of procedure AssignTeam, add the following line as indicated:
self->client->resp.team = best;
AssignWeapon(self); // PJT - team weapon <-- insert
5. In procedure ClientThink, add the folloiwng lines as indicated:
// PJT - team weapon <-- insert
if (client->resp.teamrail != team_table[client->resp.team].teamrail)
AssignWeapon(ent);
// PJT <-- end of insert
if (level.intermissiontime) // <-- locate this line
g_save.c In procedure InitGame, add following lines near end as indicated (this is code that was added for the teamplay enhancements) :
sv_allowswitch = gi.cvar("sv_allowswitch","0", CVAR_SERVERINFO); // allow team switching <-- locate this line
sv_teamrail1 = gi.cvar("sv_teamrail1","0", CVAR_SERVERINFO); // team rail options <-- start of insert
sv_teamrail2 = gi.cvar("sv_teamrail2","1", CVAR_SERVERINFO); //
team_table[1].teamrail = sv_teamrail1->value; //
team_table[2].teamrail = sv_teamrail2->value; // <-- end of insert
p_weapon.c Add the following lines as indicated: 1. To Weapon_RocketLauncher_Fire: if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) ) // <-- locate this line if (ent->client->pers.inventory[ent->client->ammo_index] > 1) // PJT team rail <-- insert this line ent->client->pers.inventory[ent->client->ammo_index]--; 2. To weapon_railgun_fire: if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) ) // <-- locate this line if (ent->client->pers.inventory[ent->client->ammo_index] > 1) // PJT team rail <-- insert this line ent->client->pers.inventory[ent->client->ammo_index]--; g_cmds.c Add the folloiwng lines to Cmd_Switch_f as indicated: ent->client->resp.team = i; ent->client->resp.teamrail = team_table[ent->client->resp.team].teamrail; // PJT - team rail <-- insert then.... AssignSkin(ent, Info_ValueForKey (ent->client->pers.userinfo, "skin")); AssignWeapon(ent); // PJT - team rail <-- insert g_items.c You may have certain items in your game that you may not want to be picked up, depending on what weapon a player is holding. Locate the touch function for your item, and, as an example, add the following line near the start of your procedure: // don't bother if not active player if (!G_EntExists(other)) return; if (!other->client) return; // only clients can pick up if (other->health < 1) return; // dead people can't pickup if (other->client->resp.teamrail == 1) return; // PJT - not for rail <-- insert g_main.c In procedure G_RunFrame, locate the code previously added for the teamplay enhancements and insert the following lines as indicated:
// PJT - teamplay enhancements
if (level.framenum % 35 == 0)
{
gi.configstring (CS_TR_STRINGS +40, sv_teamname1->string);
gi.configstring (CS_TR_STRINGS +41, sv_teamname2->string);
team_table[1].name = sv_teamname1->string;
team_table[2].name = sv_teamname2->string;
// PJT - team rail options <-- start of insert
sv_teamrail1 = gi.cvar("sv_teamrail1","0", CVAR_SERVERINFO);
sv_teamrail2 = gi.cvar("sv_teamrail2","1", CVAR_SERVERINFO);
if ((team_table[1].teamrail != sv_teamrail1->value) ||
(team_table[2].teamrail != sv_teamrail2->value))
gi.bprintf (PRINT_HIGH, "Host has changed team weapons.\n");
team_table[1].teamrail = sv_teamrail1->value;
team_table[2].teamrail = sv_teamrail2->value;
// PJT <-- end of insert
}
// PJT
cmds.cfg Add the following lines to your Quake config file: set sv_teamrail1 0 set sv_teamrail2 1 |
| Notes |
|
|
g_local.h
p_client.c
g_save.c
p_weapon.c
g_cmds.c
g_items.c
g_main.c
cmds.cfg
|
| Exercises |
|
|