New TNG spawning system :)

This commit is contained in:
Richard Allen 2002-06-19 18:13:57 +00:00
parent 500d26beac
commit c114cae764
8 changed files with 328 additions and 12 deletions

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.81 2002/06/19 18:13:57 jbravo
// New TNG spawning system :)
//
// Revision 1.80 2002/06/16 20:06:14 jbravo
// Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap"
//
@ -1319,6 +1322,7 @@ qboolean BG_CanItemBeGrabbed(int gametype, const entityState_t * ent, const play
#define DF_NO_FALLING 8
#define DF_FIXED_FOV 16
#define DF_NO_FOOTSTEPS 32
#define DF_SPAWN_FARTHEST 512
// content masks
#define MASK_ALL (-1)

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.80 2002/06/19 18:13:57 jbravo
// New TNG spawning system :)
//
// Revision 1.79 2002/06/18 06:15:30 niceass
// m4 kick now smooth
//
@ -140,8 +143,6 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
#include "g_local.h"
// JBravo: need TP functions
#include "g_teamplay.h"
#include "zcam.h"
//Elder: moved kick to g_weapon.c where it belongs

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.96 2002/06/19 18:13:57 jbravo
// New TNG spawning system :)
//
// Revision 1.95 2002/06/17 00:23:59 slicer
// Lasersight problem fixed
//
@ -332,7 +335,8 @@ SelectNearestDeathmatchSpawnPoint
Find the spot that we DON'T want to use
================
*/
#define MAX_SPAWN_POINTS 128
// Moved to g_local.h
//#define MAX_SPAWN_POINTS 128
gentity_t *SelectNearestDeathmatchSpawnPoint(vec3_t from)
{
gentity_t *spot;
@ -364,7 +368,8 @@ SelectRandomDeathmatchSpawnPoint
go to a random point that doesn't telefrag
================
*/
#define MAX_SPAWN_POINTS 128
// Moved to g_local.h
//#define MAX_SPAWN_POINTS 128
gentity_t *SelectRandomDeathmatchSpawnPoint(void)
{
gentity_t *spot;
@ -1563,7 +1568,7 @@ void ClientSpawn(gentity_t * ent)
client = ent->client;
// JBravo: Check if team spawnpoints have been located. If not find a spot for each team ala AQ2.
if (g_gametype.integer == GT_TEAMPLAY) {
/* if (g_gametype.integer == GT_TEAMPLAY) {
if (!level.spawnPointsLocated) {
client->pers.initialSpawn = qfalse;
do {
@ -1582,7 +1587,7 @@ void ClientSpawn(gentity_t * ent)
level.team2spawn_angles);
level.spawnPointsLocated = qtrue;
}
}
} */
// End JBravo.
// find a spawn point
@ -1604,16 +1609,21 @@ void ClientSpawn(gentity_t * ent)
client->pers.teamState.state, spawn_origin, spawn_angles);
// JBravo: If we are in Teamplay mode, use the teamspawnpoints.
} else if (g_gametype.integer == GT_TEAMPLAY) {
// Freud: Assign the spawns from the spawning system (g_teamplay.c)
level.team1spawnpoint = level.teamplay_spawns[0];
level.team2spawnpoint = level.teamplay_spawns[1];
if (client->sess.sessionTeam == TEAM_RED) {
client->sess.spawnPoint = level.team1spawnpoint;
spawnPoint = level.team1spawnpoint;
VectorCopy(level.team1spawn_angles, spawn_angles);
VectorCopy(level.team1spawn_origin, spawn_origin);
VectorCopy(level.team1spawnpoint->s.angles, spawn_angles);
VectorCopy(level.team1spawnpoint->s.origin, spawn_origin);
} else {
client->sess.spawnPoint = level.team2spawnpoint;
spawnPoint = level.team2spawnpoint;
VectorCopy(level.team2spawn_angles, spawn_angles);
VectorCopy(level.team2spawn_origin, spawn_origin);
VectorCopy(level.team2spawnpoint->s.angles, spawn_angles);
VectorCopy(level.team2spawnpoint->s.origin, spawn_origin);
}
// End JBravo.
} else {

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.97 2002/06/19 18:13:57 jbravo
// New TNG spawning system :)
//
// Revision 1.96 2002/06/18 09:22:16 niceass
// file exist function
//
@ -213,6 +216,8 @@
// JBravo: Max number of killed enemys to track
#define RQ3_MAXKILLS 5
#define MAX_TEAMS 2
#define MAX_SPAWN_POINTS 128
// Blaze: How long someone bleeds for
// Elder: This doesn't work the same as Q2 because clients and servers can
@ -748,6 +753,16 @@ typedef struct {
//Slicer:
int team1gender;
int team2gender;
// Freud: spawning system
int randteam;
int num_used_farteamplay_spawns[MAX_TEAMS];
int num_potential_spawns[MAX_TEAMS];
gentity_t *teamplay_spawns[MAX_TEAMS];
qboolean teams_assigned[MAX_TEAMS];
gentity_t *potential_spawns[MAX_TEAMS][MAX_SPAWN_POINTS];
gentity_t *used_farteamplay_spawns[MAX_TEAMS][MAX_SPAWN_POINTS];
} level_locals_t;
//

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.91 2002/06/19 18:13:57 jbravo
// New TNG spawning system :)
//
// Revision 1.90 2002/06/19 05:21:43 niceass
// scoreboard stuff
//
@ -981,6 +984,8 @@ void G_InitGame(int levelTime, int randomSeed, int restart)
level.team_game_going = 0;
level.team_round_going = 0;
level.fps = trap_Cvar_VariableIntegerValue("sv_fps");
level.num_potential_spawns[0] = 0;
level.num_potential_spawns[1] = 0;
}
// Slicer: reset matchmode vars
if (g_RQ3_matchmode.integer && g_gametype.integer == GT_TEAMPLAY) {
@ -998,7 +1003,6 @@ void G_InitGame(int levelTime, int randomSeed, int restart)
}
G_RemapTeamShaders();
}
/*

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.13 2002/06/19 18:13:57 jbravo
// New TNG spawning system :)
//
// Revision 1.12 2002/06/18 03:57:38 jbravo
// Committing for aasimon. Callvote nextmap removed and replaced with cyclemap for .ini
//
@ -40,7 +43,6 @@
// this file holds commands that can be executed by the server console, but not remote clients
#include "g_local.h"
#include "g_teamplay.h"
/*
==============================================================================

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.109 2002/06/19 18:13:57 jbravo
// New TNG spawning system :)
//
// Revision 1.108 2002/06/17 03:30:33 jbravo
// More color fixes
//
@ -353,6 +356,8 @@
#include "g_local.h"
#include "zcam.h"
void RQ3_SetupTeamSpawnPoints (void);
gitem_t *BG_FindItemForHoldable(holdable_t pw);
char *ConcatArgs(int start);
int touch[MAX_GENTITIES];
@ -853,6 +858,7 @@ void SpawnPlayers()
int clientNum, i;
level.spawnPointsLocated = qfalse;
RQ3_SetupTeamSpawnPoints ();
for (i = 0; i < level.maxclients; i++) {
player = &g_entities[i];
@ -2286,3 +2292,267 @@ void Cmd_Playerlist_f(gentity_t * ent)
trap_SendServerCommand(ent - g_entities, va("print \"%i - %s^7\n\"", i, other->client->pers.netname));
}
}
// Freud: RQ3_compare_spawn_distances
//
// Sorting mechanism for spawn point distances feeded to qsort
int QDECL RQ3_compare_spawn_distances (const void *sd1, const void *sd2)
{
if (((spawn_distances_t *) sd1)->distance < ((spawn_distances_t *) sd2)->distance)
return -1;
else if (((spawn_distances_t *) sd1)->distance > ((spawn_distances_t *) sd2)->distance)
return 1;
else
return 0;
}
// Freud: SpawnPointDistance
//
// Returns the distance between two spawn points (or any entities, actually...)
float
RQ3_SpawnPointDistance (gentity_t * spot1, gentity_t * spot2)
{
vec3_t v;
VectorSubtract (spot1->s.origin, spot2->s.origin, v);
return VectorLength (v);
}
// RQ3_GetSpawnPoints ()
//
// Called whenever no spawn points are available.
void RQ3_GetSpawnPoints ()
{
gentity_t *spot;
int x, spawns;
spot = NULL;
// The team that is called with SetupRandomTeamplaySpawnPoint
level.randteam = rand() % MAX_TEAMS;
// Reset the spawns for each team
for (x = 0;x < MAX_TEAMS;x++) {
level.num_potential_spawns[x] = 0;
level.num_used_farteamplay_spawns[x] = 0;
}
spawns = 0;
// Read spawn points from the map
while ((spot = G_Find (spot, FOFS (classname), "info_player_deathmatch")) != NULL) {
spawns++;
for (x = 0;x < MAX_TEAMS;x++) {
level.potential_spawns[x][level.num_potential_spawns[x]] = spot;
level.num_potential_spawns[x]++;
}
}
G_Printf("%i spawns read from map\n", spawns);
}
// Freud: RQ3_SelectRandomTeamplaySpawnPoint
//
// Selects a random spawns point from potential team spawns.
qboolean RQ3_SelectRandomTeamplaySpawnPoint (int team)
{
int spawn_point, y, ok, i, z;
float distance;
gentity_t *spot;
spot = NULL;
i = 0;
ok = qfalse;
// Done with potential spawns, re-reading and re-assigning
if (level.num_potential_spawns[team] < 1)
{
RQ3_GetSpawnPoints ();
RQ3_SetupTeamSpawnPoints ();
return qfalse;
}
// Randomizing from potential spawn points
spawn_point = rand() % level.num_potential_spawns[team];
// decrementing potential spawns counter
level.num_potential_spawns[team]--;
while ((ok == qfalse) && (i < MAX_TEAMS))
{
ok = qtrue;
for (y = 0; y < MAX_TEAMS; y++)
{
if (level.teams_assigned[y] == qtrue)
{
distance = RQ3_SpawnPointDistance (level.potential_spawns[team][spawn_point],
level.teamplay_spawns[y]);
if (distance == 0)
{
ok = qfalse;
}
}
}
if (ok == qfalse)
{
spawn_point++;
if (spawn_point == level.num_potential_spawns[team])
{
spawn_point = 0;
}
i++;
}
}
// Assigning the spawn point to the team
level.teamplay_spawns[team] = level.potential_spawns[team][spawn_point];
level.teams_assigned[team] = qtrue;
// Removing used spawn point from potential_spawns
for (z = spawn_point;z < level.num_potential_spawns[team];z++)
{
level.potential_spawns[team][z] = level.potential_spawns[team][z + 1];
}
if (i == MAX_TEAMS)
{
G_Printf("Arrrggh: More teams than potential spawnpoints!\n");
if ((spot = G_Find (spot, FOFS (classname), "info_player_start")) != NULL)
{
G_Printf("Well, guess I'm using info_player_start\n");
level.teamplay_spawns[team] = spot;
}
else
return qfalse;
}
return qtrue;
}
// Freud: RQ3_SelectFarTeamplaySpawnPoint
//
// Selects farthest teamplay spawn point(s) from available spawns.
qboolean RQ3_SelectFarTeamplaySpawnPoint (int team)
{
int u, x, y, z;
int spawn_to_use, preferred_spawn_points, num_already_used;
int total_good_spawn_points, num_usable;
float closest_spawn_distance, distance;
gentity_t *usable_spawns[MAX_SPAWN_POINTS];
qboolean used;
spawn_distances_t spawn_distances[MAX_SPAWN_POINTS];
num_already_used = 0;
// Reset the spawn_distances structure
for (x = 0; x < MAX_SPAWN_POINTS; x++) {
memset(&spawn_distances[x], 0 , sizeof(spawn_distances[x]));
}
//
for (x = 0; x < level.num_potential_spawns[team]; x++)
{
closest_spawn_distance = 2000000000;
for (y = 0; y < MAX_TEAMS; y++)
{
if (level.teams_assigned[y] == qtrue)
{
distance = RQ3_SpawnPointDistance (level.potential_spawns[team][x], level.teamplay_spawns[y]);
if (distance < closest_spawn_distance)
{
closest_spawn_distance = distance;
}
}
}
if (closest_spawn_distance == 0)
num_already_used++;
spawn_distances[x].s = level.potential_spawns[team][x];
spawn_distances[x].distance = closest_spawn_distance;
}
// Sort the farthest spawn points to the end of the array
qsort (spawn_distances, MAX_SPAWN_POINTS,
sizeof (spawn_distances_t), RQ3_compare_spawn_distances);
total_good_spawn_points = level.num_potential_spawns[team] - num_already_used;
// Support Spawn farthest and the old AQ system for spawn possibilities
if (g_dmflags.integer & DF_SPAWN_FARTHEST || total_good_spawn_points <= 4)
preferred_spawn_points = 1;
else if (total_good_spawn_points <= 10)
preferred_spawn_points = 2;
else
preferred_spawn_points = 3;
num_usable = 0;
// Now lets go through the spawn points and see if they have been used up.
for (z = 0;z < preferred_spawn_points;z++)
{
used = qfalse;
for (u = 0; u < level.num_used_farteamplay_spawns[team]; u++)
{
if (level.used_farteamplay_spawns[team][u] == spawn_distances[MAX_SPAWN_POINTS - z - 1].s) {
used = qtrue;
}
}
if (used == qfalse)
{
usable_spawns[num_usable] = spawn_distances[MAX_SPAWN_POINTS-z-1].s;
num_usable++;
}
}
// Can't use any of the far spawn points, let's go through the whole thing again.
if (num_usable < 1)
{
RQ3_SetupTeamSpawnPoints();
return qfalse;
}
// Randomize through the usable spawns.
spawn_to_use = rand() % num_usable;
// Marking the spawn as used.
level.used_farteamplay_spawns[team][level.num_used_farteamplay_spawns[team]] = usable_spawns[spawn_to_use];
level.num_used_farteamplay_spawns[team]++;
// Setting the team to assigned and assigning the spawn point.
level.teams_assigned[team] = qtrue;
level.teamplay_spawns[team] = usable_spawns[spawn_to_use];
if (!level.teamplay_spawns[team]) {
G_Printf("Argh, Invalid Far Spawn\n");
return qfalse;
}
return qtrue;
}
// Freud: RQ3_SetupTeamSpawnPoints
//
// Call this for assigning the spawn points to the teams
void RQ3_SetupTeamSpawnPoints()
{
int i;
for (i = 0; i < MAX_TEAMS; i++) {
level.teamplay_spawns[i] = NULL;
level.teams_assigned[i] = qfalse;
}
if (RQ3_SelectRandomTeamplaySpawnPoint (level.randteam) == qfalse)
return;
// If we ever decide to have more teams then 2.. :)
for (i = 0;i < MAX_TEAMS;i++)
if (i != level.randteam && RQ3_SelectFarTeamplaySpawnPoint (i) == qfalse)
return;
}

View file

@ -5,6 +5,9 @@
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.19 2002/06/19 18:13:57 jbravo
// New TNG spawning system :)
//
// Revision 1.18 2002/06/16 20:06:14 jbravo
// Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap"
//
@ -74,6 +77,12 @@
//Slicer TeamName Size.
#define TEAM_NAME_SIZE 30
typedef struct {
float distance;
gentity_t *s;
} spawn_distances_t;
void CheckTeamRules();
void StartLCA();
void ContinueLCA();
@ -109,3 +118,4 @@ void Cmd_Ignorenum_f(gentity_t * ent);
void Cmd_Ignoreclear_f(gentity_t * ent);
void Cmd_Playerlist_f(gentity_t * ent);
int IsInIgnoreList(gentity_t * source, gentity_t * subject);
void RQ3_GetSpawnPoints (void);