mirror of
https://github.com/id-Software/quake2-rerelease-dll.git
synced 2025-03-14 12:20:45 +00:00
Added xgame.cpp fr this time
This commit is contained in:
parent
49a147c18a
commit
1f40e6a6c6
2 changed files with 532 additions and 0 deletions
511
actionlite/action/a_xgame.cpp
Normal file
511
actionlite/action/a_xgame.cpp
Normal file
|
@ -0,0 +1,511 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// PG BUND
|
||||
// a_xgame.c
|
||||
//
|
||||
// this module contains all new and changed functions from a_game.c
|
||||
//
|
||||
// REMARKS:
|
||||
// --------
|
||||
// 1. You have to comment the original ParseSayText in
|
||||
// a_game.c completly out.
|
||||
// 2. Look for the DELETEIT comment. All comments
|
||||
// regarding DELETEIT are *not* really neccesary.
|
||||
// They were done because of my compiler (caused
|
||||
// compiling errors), and not because of functionality!
|
||||
// Try first to de-comment the DELETEIT sections, if
|
||||
// you get compiler errors too, comment them out like
|
||||
// I'd done.
|
||||
//
|
||||
// $Id: a_xgame.c,v 1.19 2004/04/08 23:19:51 slicerdw Exp $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: a_xgame.c,v $
|
||||
// Revision 1.19 2004/04/08 23:19:51 slicerdw
|
||||
// Optimized some code, added a couple of features and fixed minor bugs
|
||||
//
|
||||
// Revision 1.18 2003/12/09 20:54:16 igor_rock
|
||||
// Say: added %M for teammate in line of sight (as %E does for enemies)
|
||||
//
|
||||
// Revision 1.17 2002/02/19 10:28:43 freud
|
||||
// Added to %D hit in the kevlar vest and kevlar helmet, also body for handcannon
|
||||
// and shotgun.
|
||||
//
|
||||
// Revision 1.16 2002/02/18 13:55:35 freud
|
||||
// Added last damaged players %P
|
||||
//
|
||||
// Revision 1.15 2001/12/24 18:06:05 slicerdw
|
||||
// changed dynamic check for darkmatch only
|
||||
//
|
||||
// Revision 1.13 2001/12/09 14:02:11 slicerdw
|
||||
// Added gl_clear check -> video_check_glclear cvar
|
||||
//
|
||||
// Revision 1.12 2001/09/28 13:48:34 ra
|
||||
// I ran indent over the sources. All .c and .h files reindented.
|
||||
//
|
||||
// Revision 1.11 2001/07/16 19:02:06 ra
|
||||
// Fixed compilerwarnings (-g -Wall). Only one remains.
|
||||
//
|
||||
// Revision 1.10 2001/06/25 11:44:47 slicerdw
|
||||
// New Video Check System - video_check and video_check_lockpvs no longer latched
|
||||
//
|
||||
// Revision 1.9 2001/06/21 00:05:30 slicerdw
|
||||
// New Video Check System done - might need some revision but works..
|
||||
//
|
||||
// Revision 1.6 2001/06/19 18:56:38 deathwatch
|
||||
// New Last killed target system
|
||||
//
|
||||
// Revision 1.5 2001/05/20 15:00:19 slicerdw
|
||||
// Some minor fixes and changings on Video Checking system
|
||||
//
|
||||
// Revision 1.4 2001/05/11 12:21:18 slicerdw
|
||||
// Commented old Location support ( ADF ) With the ML/ETE Compatible one
|
||||
//
|
||||
// Revision 1.2 2001/05/07 21:18:34 slicerdw
|
||||
// Added Video Checking System
|
||||
//
|
||||
// Revision 1.1.1.1 2001/05/06 17:25:24 igor_rock
|
||||
// This is the PG Bund Edition V1.25 with all stuff laying around here...
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "../g_local.h"
|
||||
|
||||
// DetermineViewedPlayer: determine the current player you're viewing (only looks for live Enemy/Teammate)
|
||||
edict_t *DetermineViewedPlayer(edict_t *ent, bool teammate)
|
||||
{
|
||||
vec3_t forward, dir;
|
||||
trace_t tr;
|
||||
edict_t *who, *best;
|
||||
float bd = 0, d;
|
||||
int i;
|
||||
|
||||
AngleVectors(ent->client->v_angle, forward, nullptr, nullptr);
|
||||
VectorScale(forward, 8192, forward);
|
||||
VectorAdd(ent->s.origin, forward, forward);
|
||||
PRETRACE();
|
||||
tr = gi.trace(ent->s.origin, ent->mins, ent->maxs, forward, ent, MASK_SOLID|MASK_WATER);
|
||||
POSTTRACE();
|
||||
if (tr.fraction < 1 && tr.ent && tr.ent->client) {
|
||||
return nullptr;
|
||||
}
|
||||
AngleVectors(ent->client->v_angle, forward, nullptr, nullptr);
|
||||
best = nullptr;
|
||||
for (i = 1; i <= game.maxclients; i++)
|
||||
{
|
||||
who = g_edicts + i;
|
||||
if (!who->inuse || who == ent)
|
||||
continue;
|
||||
|
||||
if (!IS_ALIVE(who) || teammate != OnSameTeam(who, ent))
|
||||
continue;
|
||||
|
||||
VectorSubtract(who->s.origin, ent->s.origin, dir);
|
||||
VectorNormalize(dir);
|
||||
d = DotProduct(forward, dir);
|
||||
if (d > bd && visible(ent, who, MASK_SOLID|MASK_WATER)) {
|
||||
bd = d;
|
||||
best = who;
|
||||
}
|
||||
}
|
||||
|
||||
if (bd > 0.90)
|
||||
return best;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void GetViewedEnemyName(edict_t *self, char *buf)
|
||||
{
|
||||
edict_t *the_enemy;
|
||||
|
||||
the_enemy = DetermineViewedPlayer(self, false);
|
||||
if (the_enemy && the_enemy->client)
|
||||
strcpy(buf, the_enemy->client->pers.netname);
|
||||
else
|
||||
strcpy(buf, "no enemy");
|
||||
}
|
||||
|
||||
static void GetViewedTeammateName(edict_t *self, char *buf)
|
||||
{
|
||||
edict_t *the_teammate;
|
||||
|
||||
the_teammate = DetermineViewedPlayer(self, true);
|
||||
if (the_teammate && the_teammate->client)
|
||||
strcpy(buf, the_teammate->client->pers.netname);
|
||||
else
|
||||
strcpy(buf, "no teammate");
|
||||
}
|
||||
|
||||
static void GetViewedEnemyWeapon(edict_t *self, char *buf)
|
||||
{
|
||||
edict_t *the_enemy;
|
||||
|
||||
the_enemy = DetermineViewedPlayer(self, false);
|
||||
if (the_enemy && the_enemy->client && the_enemy->client->pers.weapon)
|
||||
strcpy(buf, the_enemy->client->pers.weapon->pickup_name);
|
||||
else
|
||||
strcpy(buf, "no weapon");
|
||||
}
|
||||
|
||||
//AQ2:TNG - Slicer : Last Damage Location
|
||||
static void GetLastDamagedPart(edict_t *self, char *buf)
|
||||
{
|
||||
switch(self->client->last_damaged_part) {
|
||||
case LOC_HDAM:
|
||||
strcpy(buf, "head");
|
||||
break;
|
||||
case LOC_CDAM:
|
||||
strcpy(buf, "chest");
|
||||
break;
|
||||
case LOC_SDAM:
|
||||
strcpy(buf, "stomach");
|
||||
break;
|
||||
case LOC_LDAM:
|
||||
strcpy(buf, "legs");
|
||||
break;
|
||||
case LOC_KVLR_HELMET:
|
||||
strcpy(buf, "kevlar helmet");
|
||||
break;
|
||||
case LOC_KVLR_VEST:
|
||||
strcpy(buf, "kevlar vest");
|
||||
break;
|
||||
case LOC_NO:
|
||||
strcpy(buf, "body");
|
||||
break;
|
||||
default:
|
||||
strcpy(buf, "nothing");
|
||||
break;
|
||||
}
|
||||
self->client->last_damaged_part = 0;
|
||||
}
|
||||
|
||||
//AQ2:TNG add last damaged players - Freud
|
||||
static void GetLastDamagedPlayers(edict_t *self, char *buf)
|
||||
{
|
||||
if (self->client->last_damaged_players[0] == '\0')
|
||||
strcpy(buf, "nobody");
|
||||
else
|
||||
Q_strlcpy(buf, self->client->last_damaged_players, PARSE_BUFSIZE);
|
||||
|
||||
self->client->last_damaged_players[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
// Gets the location string of a location (xo,yo,zo)
|
||||
// Modifies the the location areas by value of "mod"
|
||||
// in the coord-inside-area tests
|
||||
//
|
||||
static bool GetLocation(int xo, int yo, int zo, int mod, char *buf)
|
||||
{
|
||||
int count;
|
||||
int lx, ly, lz, rlx, rly, rlz;
|
||||
|
||||
count = ml_count;
|
||||
while (count--)
|
||||
{
|
||||
// get next location from location base
|
||||
lx = locationbase[count].x;
|
||||
ly = locationbase[count].y;
|
||||
lz = locationbase[count].z;
|
||||
rlx = locationbase[count].rx;
|
||||
rly = locationbase[count].ry;
|
||||
rlz = locationbase[count].rz;
|
||||
|
||||
// Default X-range 1500
|
||||
if (!rlx)
|
||||
rlx = 1500;
|
||||
|
||||
// Default Y-range 1500
|
||||
if (!rly)
|
||||
rly = 1500;
|
||||
|
||||
// Test if the (xo,yo,zo) is inside the location
|
||||
if (xo >= lx - rlx - mod && xo <= lx + rlx - mod &&
|
||||
yo >= ly - rly - mod && yo <= ly + rly - mod)
|
||||
{
|
||||
if (rlz && (zo < lz - rlz - mod || zo > lz + rlz + mod))
|
||||
continue;
|
||||
|
||||
strcpy(buf, locationbase[count].desc);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(buf, "around");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the player location
|
||||
//
|
||||
bool GetPlayerLocation(edict_t *self, char *buf)
|
||||
{
|
||||
if (GetLocation((int)self->s.origin[0], (int)self->s.origin[1], (int)self->s.origin[2], 0, buf))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the sighted location
|
||||
//
|
||||
static void GetSightedLocation(edict_t *self, char *buf)
|
||||
{
|
||||
vec3_t start, forward, right, end, up, offset;
|
||||
trace_t tr;
|
||||
|
||||
AngleVectors (self->client->v_angle, forward, right, up);
|
||||
|
||||
VectorSet(offset, 24, 8, self->viewheight);
|
||||
P_ProjectSource(self, self->s.origin, offset, forward, start);
|
||||
VectorMA(start, 8192, forward, end);
|
||||
|
||||
PRETRACE();
|
||||
tr = gi.trace(start, self->mins, self->maxs, end, self, CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_DEADMONSTER);
|
||||
POSTTRACE();
|
||||
|
||||
GetLocation((int)tr.endpos[0], (int)tr.endpos[1], (int)tr.endpos[2], 10, buf);
|
||||
}
|
||||
|
||||
static void GetEnemyPosition(edict_t *self, char *buf)
|
||||
{
|
||||
edict_t *the_enemy;
|
||||
vec3_t rel_pos;
|
||||
int rel_xy_pos;
|
||||
|
||||
the_enemy = DetermineViewedPlayer(self, false);
|
||||
if (the_enemy && the_enemy->client)
|
||||
{
|
||||
if (GetPlayerLocation(the_enemy, buf))
|
||||
return;
|
||||
|
||||
//creating relative vector from origin to destination
|
||||
VectorSubtract(self->s.origin, the_enemy->s.origin, rel_pos);
|
||||
|
||||
rel_xy_pos = 0;
|
||||
|
||||
//checking bounds, if one direction is less than half the other, it may
|
||||
//be ignored...
|
||||
if (fabs (rel_pos[0]) > (fabs (rel_pos[1]) * 2))
|
||||
//x width (EAST, WEST) is twice greater than y width (NORTH, SOUTH)
|
||||
rel_pos[1] = 0.0;
|
||||
if (fabs (rel_pos[1]) > (fabs (rel_pos[0]) * 2))
|
||||
//y width (NORTH, SOUTH) is twice greater than x width (EAST, WEST)
|
||||
rel_pos[0] = 0.0;
|
||||
|
||||
if (rel_pos[1] > 0.0)
|
||||
rel_xy_pos |= RP_NORTH;
|
||||
else if (rel_pos[1] < 0.0)
|
||||
rel_xy_pos |= RP_SOUTH;
|
||||
if (rel_pos[0] > 0.0)
|
||||
rel_xy_pos |= RP_EAST;
|
||||
else if (rel_pos[0] < 0.0)
|
||||
rel_xy_pos |= RP_WEST;
|
||||
|
||||
//creating the text message, regarding to rel_xy_pos
|
||||
strcpy (buf, "in the ");
|
||||
if (rel_xy_pos & RP_NORTH)
|
||||
strcat (buf, "north");
|
||||
if (rel_xy_pos & RP_SOUTH)
|
||||
strcat (buf, "south");
|
||||
if (rel_xy_pos & RP_EAST)
|
||||
strcat (buf, "east");
|
||||
if (rel_xy_pos & RP_WEST)
|
||||
strcat (buf, "west");
|
||||
//gi.dprintf ("rel_xy_pos: %i\n", rel_xy_pos);
|
||||
//last but not least, the height of enemy, limit for up/down: 64
|
||||
if (fabs(rel_pos[2]) > 64.0)
|
||||
{
|
||||
if (rel_pos[2] < 0.0)
|
||||
strcat(buf, ", above me");
|
||||
else
|
||||
strcat(buf, ", under me");
|
||||
}
|
||||
else
|
||||
strcat(buf, ", on the same level");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(buf, "somewhere");
|
||||
}
|
||||
}
|
||||
|
||||
//AQ2:TNG Slicer - New last killed target functions
|
||||
static int ReadKilledPlayers(edict_t *ent)
|
||||
{
|
||||
int i, results = 0, j = 0;
|
||||
edict_t *targ;
|
||||
|
||||
for (i = 0; i < MAX_LAST_KILLED; i++)
|
||||
{
|
||||
targ = ent->client->last_killed_target[i];
|
||||
if (!targ)
|
||||
break;
|
||||
|
||||
if (!targ->inuse || !targ->client) //Remove disconnected players from list
|
||||
{
|
||||
for (j = i + 1; j < MAX_LAST_KILLED; j++)
|
||||
ent->client->last_killed_target[j - 1] = ent->client->last_killed_target[j];
|
||||
|
||||
ent->client->last_killed_target[MAX_LAST_KILLED - 1] = NULL;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
results++;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void AddKilledPlayer(edict_t *self, edict_t *ent)
|
||||
{
|
||||
int kills;
|
||||
|
||||
kills = ReadKilledPlayers(self);
|
||||
self->client->last_killed_target[kills % MAX_LAST_KILLED] = ent;
|
||||
}
|
||||
|
||||
static void GetLastKilledTarget(edict_t *self, char *buf)
|
||||
{
|
||||
int kills, i;
|
||||
|
||||
kills = ReadKilledPlayers(self);
|
||||
if (!kills) {
|
||||
strcpy(buf, "nobody");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(buf, self->client->last_killed_target[0]->client->pers.netname);
|
||||
|
||||
for (i = 1; i < kills; i++)
|
||||
{
|
||||
if (i == kills - 1)
|
||||
Q_strlcat(buf, " and ", PARSE_BUFSIZE);
|
||||
else
|
||||
Q_strlcat(buf, ", ", PARSE_BUFSIZE);
|
||||
|
||||
Q_strlcat(buf, self->client->last_killed_target[i]->client->
|
||||
pers.netname, PARSE_BUFSIZE);
|
||||
}
|
||||
|
||||
self->client->last_killed_target[0] = NULL;
|
||||
}
|
||||
|
||||
|
||||
static char *SeekBufEnd(char *buf)
|
||||
{
|
||||
while (*buf != 0)
|
||||
buf++;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
void ParseSayText(edict_t *ent, char *text, size_t size)
|
||||
{
|
||||
char buf[PARSE_BUFSIZE + 256] = "\0"; //Parsebuf + chatpuf size
|
||||
char *p, *pbuf;
|
||||
|
||||
p = text;
|
||||
pbuf = buf;
|
||||
|
||||
while (*p != 0)
|
||||
{
|
||||
if (*p == '%')
|
||||
{
|
||||
switch (*(p + 1))
|
||||
{
|
||||
case 'H':
|
||||
GetHealth(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'A':
|
||||
GetAmmo(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'W':
|
||||
GetWeaponName(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'I':
|
||||
GetItemName(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'T':
|
||||
GetNearbyTeammates(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'M':
|
||||
GetViewedTeammateName(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'E':
|
||||
GetViewedEnemyName(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'F':
|
||||
GetViewedEnemyWeapon(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'G':
|
||||
GetEnemyPosition(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'K':
|
||||
GetLastKilledTarget(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'S':
|
||||
GetSightedLocation(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
case 'L':
|
||||
GetPlayerLocation(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
//AQ2:TNG Slicer Last Damage Location
|
||||
case 'D':
|
||||
GetLastDamagedPart(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
//AQ2:TNG END
|
||||
//AQ2:TNG Freud Last Player Damaged
|
||||
case 'P':
|
||||
GetLastDamagedPlayers(ent, pbuf);
|
||||
pbuf = SeekBufEnd(pbuf);
|
||||
p += 2;
|
||||
break;
|
||||
//AQ2:TNG END
|
||||
default:
|
||||
*pbuf++ = *p++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pbuf++ = *p++;
|
||||
}
|
||||
|
||||
if (buf[size - 1])
|
||||
{
|
||||
buf[size - 1] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*pbuf = 0;
|
||||
strcpy(text, buf);
|
||||
}
|
21
actionlite/action/a_xgame.h
Normal file
21
actionlite/action/a_xgame.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
//relative position directions
|
||||
#define RP_NORTH 1
|
||||
#define RP_SOUTH 2
|
||||
#define RP_EAST 4
|
||||
#define RP_WEST 8
|
||||
|
||||
//TempFile punch delay
|
||||
#define PUNCH_DELAY HZ/2 // 5 frames, that's .5 seconds
|
||||
|
||||
//maximum size for location description
|
||||
#define LOC_STR_LEN 128
|
||||
//maximum amount of location points on a map
|
||||
#define LOC_MAX_POINTS 300
|
||||
|
||||
bool GetPlayerLocation( edict_t *self, char *buf );
|
||||
|
||||
void ParseSayText(edict_t *ent, char *text, size_t size);
|
||||
|
||||
void Cmd_SetFlag1_f(edict_t *self);
|
||||
void Cmd_SetFlag2_f(edict_t *self);
|
||||
void Cmd_SaveFlags_f(edict_t *self);
|
Loading…
Reference in a new issue