mirror of
https://github.com/UberGames/RPG-X2-rpgxEF.git
synced 2025-03-25 10:10:59 +00:00
Sync with rpgxef-repo
This commit is contained in:
parent
860a3fdc67
commit
91bdb0db87
52 changed files with 3994 additions and 2381 deletions
|
@ -913,7 +913,6 @@ void CG_InitConsoleCommands( void ) {
|
|||
|
||||
trap_AddCommand("safezonelist");
|
||||
trap_AddCommand("selfdestruct");
|
||||
trap_AddCommand("selfdestructcountdown");
|
||||
trap_AddCommand("shipdamage");
|
||||
trap_AddCommand("shiphealth");
|
||||
}
|
||||
|
|
|
@ -1830,6 +1830,38 @@ CENTER PRINTING
|
|||
===============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_DrawSelfdestructTimer
|
||||
=================
|
||||
*/
|
||||
static float CG_DrawSelfdestructTimer( void ) {
|
||||
char *s;
|
||||
int w;
|
||||
int mins, tens, seconds, remainder;
|
||||
int msec;
|
||||
|
||||
//cgs.selfdestructTime = 60000; test value just to see if it works as intended
|
||||
msec = cgs.selfdestructTime - cg.time;
|
||||
|
||||
if (msec < 0)
|
||||
return 0;
|
||||
|
||||
mins = msec / 60000;
|
||||
tens = (msec - (mins * 60000)) / 10000;
|
||||
seconds = (msec - (mins * 60000) - (tens * 10000)) / 1000;
|
||||
remainder = msec - (mins * 60000) - (tens * 10000) - (seconds * 1000);
|
||||
|
||||
s = va( "%i:%i%i.%i", mins, tens, seconds, remainder );
|
||||
|
||||
w = UI_ProportionalStringWidth("SELF-DESTRTUCT IN",UI_SMALLFONT);
|
||||
UI_DrawProportionalString(320 - (w / 2), 10, "SELF-DESTRTUCT IN", UI_SMALLFONT, colorTable[CT_RED]);
|
||||
|
||||
w = UI_ProportionalStringWidth(s,UI_SMALLFONT);
|
||||
UI_DrawProportionalString(320 - (w / 2), 30, s, UI_SMALLFONT, colorTable[CT_RED]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
|
@ -3360,6 +3392,8 @@ static void CG_Draw2D( void ) {
|
|||
|
||||
CG_DrawLowerLeft();
|
||||
|
||||
CG_DrawSelfdestructTimer();
|
||||
|
||||
//RPG-X | Phenix | 08/06/2005
|
||||
cgs.widescreen.state = WIDESCREEN_CENTER;
|
||||
CG_DrawAdminMsg();
|
||||
|
|
|
@ -1824,6 +1824,37 @@ case EV_SHAKE_SOUND:
|
|||
FX_AddLine(cent->currentState.origin, cent->currentState.origin2, 0.5, 0.5, 0.5, 1.0, 1.0, 1000, cgs.media.laserShader);
|
||||
break;
|
||||
|
||||
// selfdestruct and shiphealth setter
|
||||
|
||||
case EV_SELFDESTRUCT_SETTER:
|
||||
DEBUGNAME("EV_SELFDESTRUCT_SETTER");
|
||||
trap_Print(va("cgs.selfdestructTime preset is %i", cgs.selfdestructTime));
|
||||
if(cent->currentState.eventParm == -1)
|
||||
cgs.selfdestructTime = -1;
|
||||
else
|
||||
cgs.selfdestructTime = cent->currentState.eventParm + cg.time;
|
||||
trap_Print(va("cgs.selfdestructTime postset is %i", cgs.selfdestructTime));
|
||||
|
||||
break;
|
||||
|
||||
case EV_HULLHEALTH_SETTER:
|
||||
DEBUGNAME("EV_HULLHEALTH_SETTER");
|
||||
if(cent->currentState.eventParm == -1)
|
||||
cgs.relativeHullStrength = -1;
|
||||
else
|
||||
cgs.relativeHullStrength = cent->currentState.eventParm;
|
||||
|
||||
break;
|
||||
|
||||
case EV_SHIELDHEALTH_SETTER:
|
||||
DEBUGNAME("EV_SHIELDHEALTH_SETTER");
|
||||
if(cent->currentState.eventParm == -1)
|
||||
cgs.relativeShieldStrength = -1;
|
||||
else
|
||||
cgs.relativeShieldStrength = cent->currentState.eventParm;
|
||||
|
||||
break;
|
||||
|
||||
// Default
|
||||
|
||||
default:
|
||||
|
|
|
@ -1493,6 +1493,13 @@ typedef struct {
|
|||
char scannableStrings[MAX_SCANNABLES][36];
|
||||
|
||||
qboolean scannablePanels;
|
||||
|
||||
// selfdestruct
|
||||
int selfdestructTime;
|
||||
|
||||
// shiphealth
|
||||
int relativeHullStrength;
|
||||
int relativeShieldStrength;
|
||||
} cgs_t;
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
@ -638,7 +638,7 @@ qboolean CG_DrawScoreboard( void )
|
|||
y += (n2 * lineHeight);
|
||||
maxClients -= n2;
|
||||
|
||||
localClient = qfalse;
|
||||
localClient = qtrue;
|
||||
|
||||
i=0;
|
||||
while (!localClient && i<cg.numScores)
|
||||
|
|
|
@ -880,6 +880,22 @@ static void CG_ServerCommand( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
if(!strcmp(cmd, "ui_msd")) {
|
||||
static char ui_msd1[MAX_STRING_CHARS], ui_msd2[MAX_STRING_CHARS], ui_msd3[MAX_STRING_CHARS], ui_msd4[MAX_STRING_CHARS], ui_msd5[MAX_STRING_CHARS], ui_msd6[MAX_STRING_CHARS], ui_msd7[MAX_STRING_CHARS], ui_msd8[MAX_STRING_CHARS], ui_msd9[MAX_STRING_CHARS], ui_msd10[MAX_STRING_CHARS];
|
||||
trap_Argv( 1, ui_msd1, sizeof( ui_msd1 ) );
|
||||
trap_Argv( 2, ui_msd2, sizeof( ui_msd2 ) );
|
||||
trap_Argv( 3, ui_msd3, sizeof( ui_msd3 ) );
|
||||
trap_Argv( 4, ui_msd4, sizeof( ui_msd4 ) );
|
||||
trap_Argv( 5, ui_msd5, sizeof( ui_msd5 ) );
|
||||
trap_Argv( 6, ui_msd6, sizeof( ui_msd6 ) );
|
||||
trap_Argv( 7, ui_msd7, sizeof( ui_msd7 ) );
|
||||
trap_Argv( 8, ui_msd8, sizeof( ui_msd8 ) );
|
||||
trap_Argv( 9, ui_msd9, sizeof( ui_msd9 ) );
|
||||
trap_Argv( 10, ui_msd10, sizeof( ui_msd10 ) );
|
||||
trap_SendConsoleCommand(va("ui_msd %s %s %s %s %s %s %s %s %s %s", ui_msd1, ui_msd2, ui_msd3, ui_msd4, ui_msd5, ui_msd6, ui_msd7, ui_msd8, ui_msd9, ui_msd10));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcmp(cmd, "ui_transporter")) {
|
||||
trap_SendConsoleCommand(va("ui_transporter %s", CG_Argv(1)));
|
||||
return;
|
||||
|
|
|
@ -799,7 +799,11 @@ typedef enum {
|
|||
EV_STASIS_DOOR_OPENING,
|
||||
EV_STASIS_DOOR_CLOSING,
|
||||
|
||||
EV_DEBUG_TRACE
|
||||
EV_DEBUG_TRACE,
|
||||
|
||||
EV_SELFDESTRUCT_SETTER,
|
||||
EV_HULLHEALTH_SETTER,
|
||||
EV_SHIELDHEALTH_SETTER
|
||||
} entity_event_t;
|
||||
|
||||
//RPG-X: J2J - Moved animation enum list so that the string list can see it, Note special case for cg_players.c.
|
||||
|
|
24
game/entityDefParser/LICENSE
Normal file
24
game/entityDefParser/LICENSE
Normal file
|
@ -0,0 +1,24 @@
|
|||
Copyright (c) 2012 Walter Julius Hennecke, Ubergames
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to
|
||||
whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
|
||||
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
28
game/entityDefParser/README
Normal file
28
game/entityDefParser/README
Normal file
|
@ -0,0 +1,28 @@
|
|||
Entity Definitions Parser
|
||||
|
||||
Required tools:
|
||||
Linux:
|
||||
* flex
|
||||
Windows:
|
||||
* mingw
|
||||
|
||||
Building:
|
||||
Linux:
|
||||
flex quake.l
|
||||
gcc lex.yy.c -o entityDefParser -lfl
|
||||
Mac:
|
||||
flex quake.l
|
||||
gcc lex.yy.c -o entityDefParser -lfl
|
||||
Windows:
|
||||
flex quake.l
|
||||
gcc lex.yy.c -o entityDefParser /lib/libfl.a
|
||||
|
||||
Usage:
|
||||
./entityDefParser <code file> <output file>
|
||||
|
||||
Example:
|
||||
./entityDefParser game/g_mover.c hm_entities.def
|
||||
./entityDefParser game/g_fx.c
|
||||
|
||||
Will produce a def file including all entity definitions from
|
||||
g_mover.c and g_fx.c.
|
88
game/entityDefParser/quaked.l
Normal file
88
game/entityDefParser/quaked.l
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright (c) 2012 Walter Julius Hennecke, Ubergames
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to
|
||||
whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
|
||||
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
%{
|
||||
#include <stdio.h>
|
||||
|
||||
FILE *in, *out;
|
||||
|
||||
#define YY_DECL int yylex()
|
||||
%}
|
||||
|
||||
%x C_QUAKED
|
||||
%%
|
||||
"/*QUAKED" { BEGIN(C_QUAKED); fprintf(out, "/*QUAKED"); }
|
||||
<C_QUAKED>"*/" { BEGIN(INITIAL); fprintf(out, "*/\n\n"); }
|
||||
<C_QUAKED>"\t" { fprintf(out, "\t"); }
|
||||
<C_QUAKED>"\n" { fprintf(out, "\n"); }
|
||||
<C_QUAKED>. { fprintf(out, "%s", yytext); }
|
||||
[\n] ;
|
||||
. ;
|
||||
%%
|
||||
|
||||
main(int argc, char *argv[]) {
|
||||
char *buf;
|
||||
long len;
|
||||
|
||||
if(argc < 2) {
|
||||
printf("Usage: %s <cfiles> <output file>\n", argv[0]);
|
||||
}
|
||||
|
||||
in = fopen(argv[1], "r");
|
||||
if(!in) {
|
||||
return;
|
||||
}
|
||||
|
||||
out = fopen(argv[2], "r");
|
||||
if(out) {
|
||||
fseek(out, 0, SEEK_END);
|
||||
len = ftell(out);
|
||||
fseek(out, 0, SEEK_SET);
|
||||
|
||||
buf = (char *)malloc(len+1);
|
||||
if(!buf) {
|
||||
fclose(out);
|
||||
return;
|
||||
}
|
||||
fgets(buf, len, out);
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
out = fopen(argv[2], "a");
|
||||
if(!out) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(buf != NULL) {
|
||||
fprintf(out, "%s", buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
yyin = in;
|
||||
|
||||
yylex();
|
||||
}
|
211
game/g_active.c
211
game/g_active.c
|
@ -22,7 +22,7 @@ static void TryUse( gentity_t *ent )
|
|||
trace_t trace;
|
||||
vec3_t src, dest, vf;
|
||||
clientSession_t *sess;
|
||||
|
||||
|
||||
if(!ent || !ent->client) return;
|
||||
|
||||
sess = &ent->client->sess;
|
||||
|
@ -60,10 +60,10 @@ static void TryUse( gentity_t *ent )
|
|||
}
|
||||
//FIXME: play sound?
|
||||
target->use( target, ent, ent );
|
||||
#ifdef G_LUA
|
||||
#ifdef G_LUA
|
||||
if(target->luaUse)
|
||||
LuaHook_G_EntityUse(target->luaUse, target-g_entities, ent-g_entities, ent-g_entities);
|
||||
#endif
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
else if ( target && target->use && Q_stricmp("misc_ammo_station", target->classname) == 0 )
|
||||
|
@ -80,10 +80,10 @@ static void TryUse( gentity_t *ent )
|
|||
}
|
||||
}
|
||||
target->use( target, ent, ent );
|
||||
#ifdef G_LUA
|
||||
#ifdef G_LUA
|
||||
if(target->luaUse)
|
||||
LuaHook_G_EntityUse(target->luaUse, target-g_entities, ent-g_entities, ent-g_entities);
|
||||
#endif
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
else if ( (target && target->s.number == ENTITYNUM_WORLD) || (target->s.pos.trType == TR_STATIONARY && !(trace.surfaceFlags & SURF_NOIMPACT) && !target->takedamage) )
|
||||
|
@ -233,19 +233,19 @@ static void P_WorldEffects( gentity_t *ent ) {
|
|||
//
|
||||
if (waterlevel &&
|
||||
(ent->watertype&(CONTENTS_LAVA|CONTENTS_SLIME)) ) {
|
||||
if (ent->health > 0
|
||||
&& ent->pain_debounce_time < level.time ) {
|
||||
if (ent->health > 0
|
||||
&& ent->pain_debounce_time < level.time ) {
|
||||
|
||||
if (ent->watertype & CONTENTS_LAVA) {
|
||||
G_Damage (ent, NULL, NULL, NULL, NULL,
|
||||
30*waterlevel, 0, MOD_LAVA);
|
||||
}
|
||||
if (ent->watertype & CONTENTS_LAVA) {
|
||||
G_Damage (ent, NULL, NULL, NULL, NULL,
|
||||
30*waterlevel, 0, MOD_LAVA);
|
||||
}
|
||||
|
||||
if (ent->watertype & CONTENTS_SLIME) {
|
||||
G_Damage (ent, NULL, NULL, NULL, NULL,
|
||||
10*waterlevel, 0, MOD_SLIME);
|
||||
if (ent->watertype & CONTENTS_SLIME) {
|
||||
G_Damage (ent, NULL, NULL, NULL, NULL,
|
||||
10*waterlevel, 0, MOD_SLIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,12 +344,12 @@ void G_TouchTriggers( gentity_t *ent ) {
|
|||
for ( i=0 ; i<num ; i++ ) {
|
||||
hit = &g_entities[touch[i]];
|
||||
|
||||
#ifdef G_LUA
|
||||
#ifdef G_LUA
|
||||
if(hit->luaTouch)
|
||||
{
|
||||
LuaHook_G_EntityTouch(hit->luaTouch, hit->s.number, ent->s.number);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( !hit->touch && !ent->touch ) {
|
||||
continue;
|
||||
|
@ -363,7 +363,7 @@ void G_TouchTriggers( gentity_t *ent ) {
|
|||
{
|
||||
// this is ugly but adding a new ET_? type will
|
||||
// most likely cause network incompatibilities
|
||||
if ( hit->s.eType != ET_TELEPORT_TRIGGER && hit->touch != Touch_DoorTrigger)
|
||||
if ( hit->s.eType != ET_TELEPORT_TRIGGER && hit->touch != G_Mover_TouchDoorTrigger)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -463,10 +463,10 @@ static qboolean ClientInactivityTimer( gclient_t *client )
|
|||
client->inactivityWarning = qfalse;
|
||||
}
|
||||
else if ( cmd->forwardmove ||
|
||||
cmd->rightmove ||
|
||||
cmd->upmove ||
|
||||
(cmd->buttons & BUTTON_ATTACK) ||
|
||||
(cmd->buttons & BUTTON_ALT_ATTACK) )
|
||||
cmd->rightmove ||
|
||||
cmd->upmove ||
|
||||
(cmd->buttons & BUTTON_ATTACK) ||
|
||||
(cmd->buttons & BUTTON_ALT_ATTACK) )
|
||||
{
|
||||
client->inactivityTime = level.time + g_inactivity.integer * 1000;
|
||||
client->inactivityWarning = qfalse;
|
||||
|
@ -512,6 +512,7 @@ list_iter_p iterTimedMessages;
|
|||
*/
|
||||
static char *TimedMessage( void ){
|
||||
char* message;
|
||||
timedMessage_t *msg;
|
||||
|
||||
if(!level.timedMessages->length) {
|
||||
return "^1RPG-X ERROR: No messages to display";
|
||||
|
@ -524,7 +525,8 @@ static char *TimedMessage( void ){
|
|||
}
|
||||
}
|
||||
|
||||
message = (char *)list_cycl_next(iterTimedMessages);
|
||||
msg = (timedMessage_t *)list_cycl_next(iterTimedMessages);
|
||||
message = msg->message;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
@ -548,7 +550,7 @@ static void ClientTimerActions( gentity_t *ent, int msec ) {
|
|||
|
||||
if( rpg_timedmessagetime.value ){
|
||||
//Make sure its not less then one //TiM: Well... we can have under 1, just not toooo far under 1
|
||||
|
||||
|
||||
if(rpg_timedmessagetime.value < 0.2) { //1
|
||||
messageTime = 0.2;
|
||||
}else{
|
||||
|
@ -557,7 +559,7 @@ static void ClientTimerActions( gentity_t *ent, int msec ) {
|
|||
|
||||
if (level.time > (level.message + (messageTime * 60000)) ) {
|
||||
level.message = level.time;
|
||||
|
||||
|
||||
//TiM - There. So with this working in conjunction with that reset
|
||||
//code above, this should be more efficient. :)
|
||||
message = TimedMessage(); //Since we're working with a gloabl scope variable, there's no need for this thing to have parameters:)
|
||||
|
@ -618,27 +620,6 @@ static void ClientIntermissionThink( gclient_t *client ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Cmd_Ready_f
|
||||
====================
|
||||
*/
|
||||
/**
|
||||
* This function is called from the ui_sp_postgame.c as a result of clicking on the
|
||||
* "next" button in non GT_TOURNAMENT games. This replaces the old system of waiting
|
||||
* for the user to click an ATTACK or USE button to signal ready
|
||||
* (see ClientIntermissionThink())
|
||||
*
|
||||
* when all clients have signaled ready, the game continues to the next match.
|
||||
*/
|
||||
void Cmd_Ready_f (gentity_t *ent)
|
||||
{
|
||||
gclient_t *client;
|
||||
client = ent->client;
|
||||
|
||||
client->readyToExit = qtrue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct detHit_s
|
||||
|
@ -954,7 +935,7 @@ static qhandle_t shieldDeactivateSound=0;
|
|||
/**
|
||||
* Remove a forcefield
|
||||
*/
|
||||
void ShieldRemove(gentity_t *self)
|
||||
void G_Active_ShieldRemove(gentity_t *self)
|
||||
{
|
||||
self->think = G_FreeEntity;
|
||||
self->nextthink = level.time + 300;
|
||||
|
@ -989,7 +970,7 @@ void ShieldDie(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int d
|
|||
// Play damaging sound...
|
||||
G_AddEvent(self, EV_GENERAL_SOUND, shieldDamageSound);
|
||||
|
||||
ShieldRemove(self);
|
||||
G_Active_ShieldRemove(self);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1019,7 +1000,7 @@ void ShieldGoSolid(gentity_t *self)
|
|||
|
||||
if (self->health <= 0)
|
||||
{
|
||||
ShieldRemove(self);
|
||||
G_Active_ShieldRemove(self);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1037,7 +1018,7 @@ void ShieldGoSolid(gentity_t *self)
|
|||
self->nextthink = level.time + 1000;
|
||||
self->think = ShieldThink;
|
||||
self->takedamage = qtrue;//RPG-X: - RedTechie use to be qtrue //TiM - made true again. should be okay so long as the health isn't decremented
|
||||
|
||||
|
||||
trap_LinkEntity(self);
|
||||
}
|
||||
|
||||
|
@ -1128,19 +1109,19 @@ void ShieldTouch(gentity_t *self, gentity_t *other, trace_t *trace)
|
|||
rpg_forcefielddamage.integer = 999;
|
||||
}
|
||||
other->health -= rpg_forcefielddamage.integer;
|
||||
|
||||
|
||||
//RPG-X: RedTechie - Fixed free ent if medic revive on
|
||||
if(rpg_medicsrevive.integer == 1){
|
||||
if(other->health <= 1){
|
||||
other->client->ps.stats[STAT_WEAPONS] = ( 1 << WP_0 );
|
||||
other->client->ps.stats[STAT_HOLDABLE_ITEM] = HI_NONE;
|
||||
other->client->ps.stats[STAT_HEALTH] = other->health = 1;
|
||||
player_die (other, other, other, 1, MOD_FORCEFIELD);
|
||||
G_Client_Die (other, other, other, 1, MOD_FORCEFIELD);
|
||||
}
|
||||
}else{
|
||||
if(other->health <= 1){
|
||||
other->client->ps.stats[STAT_HEALTH] = other->health = 0;
|
||||
player_die (other, other, other, 100000, MOD_FORCEFIELD);
|
||||
G_Client_Die (other, other, other, 100000, MOD_FORCEFIELD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1225,10 +1206,10 @@ void CreateShield(gentity_t *ent)
|
|||
}
|
||||
ent->clipmask = MASK_SHOT;
|
||||
|
||||
// xaxis - 1 bit
|
||||
// height - 0-254 8 bits //10
|
||||
// posWidth - 0-255 8 bits //10
|
||||
// negWidth - 0 - 255 8 bits
|
||||
// xaxis - 1 bit
|
||||
// height - 0-254 8 bits //10
|
||||
// posWidth - 0-255 8 bits //10
|
||||
// negWidth - 0 - 255 8 bits
|
||||
|
||||
paramData = (xaxis << 30) | ((height&1023) << 20) | ((posWidth&1023) << 10) | (negWidth&1023); //24 16 8
|
||||
ent->s.time2 = paramData;
|
||||
|
@ -1241,14 +1222,14 @@ void CreateShield(gentity_t *ent)
|
|||
{
|
||||
ent->team = "2";
|
||||
}
|
||||
|
||||
|
||||
ent->health = ceil(SHIELD_HEALTH*g_dmgmult.value);
|
||||
|
||||
|
||||
ent->s.time = ent->health;//???
|
||||
ent->pain = ShieldPain;
|
||||
ent->die = ShieldDie;
|
||||
ent->touch = ShieldTouch;
|
||||
|
||||
|
||||
ent->r.svFlags |= SVF_SHIELD_BBOX;
|
||||
|
||||
// see if we're valid
|
||||
|
@ -1409,18 +1390,18 @@ void flushDecoys( gentity_t *ent ) {
|
|||
while ( (decoy = G_Find( decoy, FOFS(classname), "decoy" )) != NULL )
|
||||
{
|
||||
if ( decoy->parent != ent )
|
||||
//if ( decoy->s.clientNum != ent->client->ps.clientNum )
|
||||
//if ( decoy->s.clientNum != ent->client->ps.clientNum )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
foundDecoys[decoyCount++] = decoy->s.clientNum;
|
||||
}
|
||||
|
||||
|
||||
//now remove first ones we find until there are only 9 left
|
||||
decoy = NULL;
|
||||
orgCount = decoyCount;
|
||||
lowestTimeStamp = level.time;
|
||||
|
||||
|
||||
//RPG-X: TiM - Let's limit it to say... 64 decoys per player
|
||||
while ( decoyCount > 64 ) //9
|
||||
{
|
||||
|
@ -1432,7 +1413,7 @@ void flushDecoys( gentity_t *ent ) {
|
|||
continue;
|
||||
}
|
||||
decoy = &g_entities[foundDecoys[i]];
|
||||
|
||||
|
||||
if ( decoy && decoy->timestamp < lowestTimeStamp )
|
||||
{
|
||||
removeMe = i;
|
||||
|
@ -1460,7 +1441,7 @@ void flushDecoys( gentity_t *ent ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* entities spawn non solid and through this function,
|
||||
* they'll become solid once nothing's detected in their boundaries. :)
|
||||
|
@ -1534,7 +1515,7 @@ qboolean PlaceDecoy(gentity_t *ent)
|
|||
gentity_t *oldDecoy;
|
||||
|
||||
for ( i = 0; i<level.num_entities; i++ ) {
|
||||
oldDecoy = &g_entities[i];
|
||||
oldDecoy = &g_entities[i];
|
||||
|
||||
if ( !Q_stricmp( oldDecoy->classname, "decoy" ) && oldDecoy->s.eventParm == level.decoyIndex ) {
|
||||
G_FreeEntity( oldDecoy );
|
||||
|
@ -1609,7 +1590,7 @@ qboolean PlaceDecoy(gentity_t *ent)
|
|||
char height[9];
|
||||
char weight[9];
|
||||
char offset[6];
|
||||
|
||||
|
||||
//TiM - ensure that we encapsulate this data better or else it sometimes
|
||||
//becomes null
|
||||
Q_strncpyz( model, Info_ValueForKey( userinfo, "model" ), sizeof( model ) );
|
||||
|
@ -1618,11 +1599,11 @@ qboolean PlaceDecoy(gentity_t *ent)
|
|||
Q_strncpyz( offset, Info_ValueForKey( userinfo, "modelOffset" ), sizeof( offset ) );
|
||||
|
||||
Com_sprintf( buffer, sizeof( buffer ), "model\\%s\\height\\%s\\weight\\%s\\moOf\\%s\\c\\%i",
|
||||
model,
|
||||
height,
|
||||
weight,
|
||||
offset,
|
||||
ent->client->sess.sessionClass );
|
||||
model,
|
||||
height,
|
||||
weight,
|
||||
offset,
|
||||
ent->client->sess.sessionClass );
|
||||
|
||||
trap_SetConfigstring( CS_DECOYS + level.decoyIndex, buffer );
|
||||
}
|
||||
|
@ -1727,7 +1708,7 @@ static void ClientEvents( gentity_t *ent, int oldEventSequence ) {
|
|||
//TiM: Since we purge the vectors each cycle. I'll save us some memory by using the vectors themselves as a check.
|
||||
if ( TransDat[ps->clientNum].beamTime == 0 &&
|
||||
VectorCompare( vec3_origin, TransDat[ps->clientNum].storedCoord[TPT_PORTABLE].origin ) &&
|
||||
VectorCompare( vec3_origin, TransDat[ps->clientNum].storedCoord[TPT_PORTABLE].angles ) )
|
||||
VectorCompare( vec3_origin, TransDat[ps->clientNum].storedCoord[TPT_PORTABLE].angles ) )
|
||||
{
|
||||
VectorCopy( ps->origin, TransDat[ps->clientNum].storedCoord[TPT_PORTABLE].origin );
|
||||
VectorCopy( ps->viewangles, TransDat[ps->clientNum].storedCoord[TPT_PORTABLE].angles );
|
||||
|
@ -1739,7 +1720,7 @@ static void ClientEvents( gentity_t *ent, int oldEventSequence ) {
|
|||
|
||||
if ( TransDat[ps->clientNum].beamTime == 0 && level.time > ps->powerups[PW_QUAD] ) {
|
||||
G_InitTransport( ps->clientNum, TransDat[ps->clientNum].storedCoord[TPT_PORTABLE].origin,
|
||||
TransDat[ps->clientNum].storedCoord[TPT_PORTABLE].angles );
|
||||
TransDat[ps->clientNum].storedCoord[TPT_PORTABLE].angles );
|
||||
|
||||
memset( &TransDat[ps->clientNum].storedCoord[TPT_PORTABLE], 0, sizeof( TransDat[ps->clientNum].storedCoord[TPT_PORTABLE]) );
|
||||
}
|
||||
|
@ -1748,7 +1729,7 @@ static void ClientEvents( gentity_t *ent, int oldEventSequence ) {
|
|||
}
|
||||
|
||||
ps->stats[STAT_USEABLE_PLACED] = 0;
|
||||
|
||||
|
||||
if (g_classData[client->sess.sessionClass].isMarine)
|
||||
{
|
||||
client->teleportTime = level.time + ( 3 * 1000 ); // 15 * 1000
|
||||
|
@ -1853,25 +1834,25 @@ void ThrowWeapon( gentity_t *ent, char *txt )
|
|||
ucmd = &ent->client->pers.cmd;
|
||||
ps = &client->ps;
|
||||
|
||||
if ( rpg_allowWeaponDrop.integer == 0) {
|
||||
return;
|
||||
}
|
||||
if ( rpg_allowWeaponDrop.integer == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( numTotalDropped >= MAX_DROPPED ) {
|
||||
WARNING(("RPG-X Warning: maximum of dropped items of %i reached.\n", MAX_DROPPED));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ps->weapon == WP_1 || ( ucmd->buttons & BUTTON_ATTACK )) {
|
||||
if ( ps->weapon == WP_1 || ( ucmd->buttons & BUTTON_ATTACK )) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
numTotalDropped++;
|
||||
|
||||
item = BG_FindItemForWeapon( ps->weapon );
|
||||
|
||||
// admins don't lose weapon when thrown
|
||||
if ( IsAdmin( ent ) == qfalse ) {
|
||||
// admins don't lose weapon when thrown
|
||||
if ( IsAdmin( ent ) == qfalse ) {
|
||||
ps->ammo[ ps->weapon ] -= 1;
|
||||
if (ps->ammo[ ps->weapon ] <= 0) {
|
||||
ps->stats[STAT_WEAPONS] &= ~( 1 << ps->weapon );
|
||||
|
@ -1883,10 +1864,10 @@ void ThrowWeapon( gentity_t *ent, char *txt )
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drop = DropWeapon( ent, item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM, txt );
|
||||
drop->parent = ent;
|
||||
drop->parent = ent;
|
||||
drop->count = 1;
|
||||
}
|
||||
|
||||
|
@ -1925,7 +1906,7 @@ static void SendPendingPredictableEvents( playerState_t *ps ) {
|
|||
static void ClientCamThink(gentity_t *client) {
|
||||
if(!client->client->cam) return;
|
||||
G_SetOrigin(client, client->client->cam->s.origin);
|
||||
SetClientViewAngle(client, client->client->cam->s.angles);
|
||||
G_Client_SetViewAngle(client, client->client->cam->s.angles);
|
||||
trap_LinkEntity(client);
|
||||
}
|
||||
|
||||
|
@ -1935,17 +1916,17 @@ ClientThink
|
|||
==============
|
||||
*/
|
||||
/**
|
||||
* This will be called once for each client frame, which will
|
||||
* usually be a couple times for each server frame on fast clients.
|
||||
* This will be called once for each client frame, which will
|
||||
* usually be a couple times for each server frame on fast clients.
|
||||
*
|
||||
* If "g_synchronousClients 1" is set, this will be called exactly
|
||||
* once for each server frame, which makes for smooth demo recording.
|
||||
* If "g_synchronousClients 1" is set, this will be called exactly
|
||||
* once for each server frame, which makes for smooth demo recording.
|
||||
*/
|
||||
static void ClientThink_real( gentity_t *ent ) {
|
||||
gclient_t *client;
|
||||
pmove_t pm;
|
||||
int oldEventSequence;
|
||||
int msec;
|
||||
pmove_t pm;
|
||||
int oldEventSequence;
|
||||
int msec;
|
||||
usercmd_t *ucmd;
|
||||
playerState_t *ps;
|
||||
|
||||
|
@ -2013,7 +1994,7 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
ent->r.contents = CONTENTS_CORPSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//RPG-X: Checked to see if medics revive is on if so do as following
|
||||
if(rpg_medicsrevive.integer == 1){
|
||||
if ( client->noclip ) {
|
||||
|
@ -2032,7 +2013,7 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
ps->pm_type = PM_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//RPG-X: J2J & Phenix - For the gravity ent
|
||||
if(client->SpecialGrav != qtrue)
|
||||
{
|
||||
|
@ -2053,15 +2034,15 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
else if ( ps->stats[STAT_HEALTH] <= 20 ) {
|
||||
ps->speed *= 0.55;
|
||||
}
|
||||
|
||||
|
||||
if (( ps->powerups[PW_EVOSUIT] ) && ( ps->gravity == 0 ))
|
||||
{//Evosuit time.. RPG-X | Phenix | 8/8/2004
|
||||
ps->speed *= 1.3;
|
||||
}
|
||||
|
||||
|
||||
//RPG-X: Redtechie - n00bie stay.....good boy!
|
||||
if ( g_classData[client->sess.sessionClass].isn00b ){
|
||||
ps->speed = 0;
|
||||
ps->speed = 0;
|
||||
}
|
||||
|
||||
//TiM : SP Style Transporter. :)
|
||||
|
@ -2072,9 +2053,9 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
//so bullets and other players will pass thru the transportee. :)
|
||||
if ( (level.time > TransDat[ps->clientNum].beamTime - 6000) &&
|
||||
( level.time < TransDat[ps->clientNum].beamTime - 2000 ) ) {
|
||||
if ( ps->stats[STAT_HEALTH] > 1 ) {
|
||||
ent->r.contents = CONTENTS_NONE;
|
||||
}
|
||||
if ( ps->stats[STAT_HEALTH] > 1 ) {
|
||||
ent->r.contents = CONTENTS_NONE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( ps->stats[STAT_HEALTH] > 1 ) {
|
||||
|
@ -2083,13 +2064,13 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
//If we're half-way thru the cycle, teleport the player now
|
||||
if ( level.time > TransDat[ps->clientNum].beamTime - 4000 &&
|
||||
!TransDat[ps->clientNum].beamed ) {
|
||||
TeleportPlayer( ent, TransDat[ps->clientNum].currentCoord.origin,
|
||||
TransDat[ps->clientNum].currentCoord.angles,
|
||||
TP_TRI_TP );
|
||||
if ( level.time > TransDat[ps->clientNum].beamTime - 4000 &&
|
||||
!TransDat[ps->clientNum].beamed ) {
|
||||
TeleportPlayer( ent, TransDat[ps->clientNum].currentCoord.origin,
|
||||
TransDat[ps->clientNum].currentCoord.angles,
|
||||
TP_TRI_TP );
|
||||
|
||||
TransDat[ps->clientNum].beamed = qtrue;
|
||||
TransDat[ps->clientNum].beamed = qtrue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -2100,8 +2081,8 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
ps->powerups[PW_QUAD] = 0;
|
||||
TransDat[ps->clientNum].beamed = qfalse;
|
||||
|
||||
memset( &TransDat[ps->clientNum].currentCoord, 0,
|
||||
sizeof( TransDat[ps->clientNum].currentCoord.origin ) );
|
||||
memset( &TransDat[ps->clientNum].currentCoord, 0,
|
||||
sizeof( TransDat[ps->clientNum].currentCoord.origin ) );
|
||||
|
||||
if(g_entities[ps->clientNum].flags & FL_CLAMPED) {
|
||||
//reset everything if player was beamed by trigger_transporter
|
||||
|
@ -2111,13 +2092,13 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
//TiM : Freeze their movement if they're halfway through a transport cycle
|
||||
if ( level.time < TransDat[ps->clientNum].beamTime &&
|
||||
if ( level.time < TransDat[ps->clientNum].beamTime &&
|
||||
level.time > TransDat[ps->clientNum].beamTime - 4000 )
|
||||
{
|
||||
vec3_t endPoint;
|
||||
trace_t tr;
|
||||
VectorSet( endPoint, ps->origin[0], ps->origin[1], ps->origin[2] - 48 );
|
||||
//Do a trace down. If we're near ground, just re-enable gravity. Else we we get weird animations O_o
|
||||
//Do a trace down. If we're near ground, just re-enable gravity. Else we we get weird animations O_o
|
||||
trap_Trace( &tr, ps->origin, NULL, NULL, endPoint, ps->clientNum, CONTENTS_SOLID );
|
||||
|
||||
if ( tr.fraction == 1.0 ) {
|
||||
|
@ -2126,7 +2107,7 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
ps->speed = 0;
|
||||
|
||||
|
||||
ps->velocity[0] = ps->velocity[1] = 0.0;
|
||||
}
|
||||
|
||||
|
@ -2155,7 +2136,7 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
pm.admin = (qboolean)(g_classData[client->sess.sessionClass].isAdmin || client->LoggedAsAdmin);
|
||||
//pm.admin = g_classData[client->sess.sessionClass].isAdmin;
|
||||
pm.medic = (qboolean)g_classData[client->sess.sessionClass].isMedical;
|
||||
pm.borg = (qboolean)g_classData[client->sess.sessionClass].isBorg;
|
||||
pm.borg = (qboolean)g_classData[client->sess.sessionClass].isBorg;
|
||||
|
||||
// perform a pmove
|
||||
Pmove (&pm);
|
||||
|
@ -2181,7 +2162,7 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
ClientEvents( ent, oldEventSequence );
|
||||
|
||||
if ( pm.useEvent )
|
||||
{ //TODO: Use
|
||||
{ //TODO: Use
|
||||
TryUse( ent );
|
||||
}
|
||||
|
||||
|
@ -2214,7 +2195,7 @@ static void ClientThink_real( gentity_t *ent ) {
|
|||
if ( level.time > client->respawnTime ) {
|
||||
// pressing attack or use is the normal respawn method
|
||||
if ( ucmd->buttons & ( BUTTON_ATTACK | BUTTON_USE_HOLDABLE ) ) {
|
||||
respawn( ent );
|
||||
G_Client_Respawn( ent );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2309,7 +2290,7 @@ static void SpectatorClientEndFrame( gentity_t *ent ) {
|
|||
// drop them to free spectators unless they are dedicated camera followers
|
||||
if ( sess->spectatorClient >= 0 ) {
|
||||
sess->spectatorState = SPECTATOR_FREE;
|
||||
ClientBegin( ent->client - level.clients, qfalse, qfalse, qfalse );
|
||||
G_Client_Begin( ent->client - level.clients, qfalse, qfalse, qfalse );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ void UpdateTournamentInfo( void ) {
|
|||
}
|
||||
playerClientNum = i;
|
||||
|
||||
CalculateRanks( qfalse );
|
||||
G_Client_CalculateRanks( qfalse );
|
||||
// put info for the top three players into the msg
|
||||
Com_sprintf(msg, AWARDS_MSG_LENGTH, "awards %d", level.numNonSpectatorClients);
|
||||
for( j = 0; j < level.numNonSpectatorClients; j++ )
|
||||
|
|
14
game/g_bot.c
14
game/g_bot.c
|
@ -470,7 +470,7 @@ void G_CheckBotSpawn( void ) {
|
|||
if ( botSpawnQueue[n].spawnTime > level.time ) {
|
||||
continue;
|
||||
}
|
||||
ClientBegin( botSpawnQueue[n].clientNum, qfalse, qtrue, qfalse );
|
||||
G_Client_Begin( botSpawnQueue[n].clientNum, qfalse, qtrue, qfalse );
|
||||
botSpawnQueue[n].spawnTime = 0;
|
||||
|
||||
if( g_gametype.integer == GT_SINGLE_PLAYER ) {
|
||||
|
@ -498,7 +498,7 @@ static void AddBotToSpawnQueue( int clientNum, int delay ) {
|
|||
}
|
||||
|
||||
G_Printf( S_COLOR_YELLOW "Unable to delay spawn\n" );
|
||||
ClientBegin( clientNum, qfalse, qtrue, qfalse );
|
||||
G_Client_Begin( clientNum, qfalse, qtrue, qfalse );
|
||||
}
|
||||
|
||||
|
||||
|
@ -632,7 +632,7 @@ static void G_AddBot( const char *name, float skill, const char *team, const cha
|
|||
// initialize the bot settings
|
||||
if( !team || !*team ) {
|
||||
if( g_gametype.integer >= GT_TEAM ) {
|
||||
if( PickTeam(clientNum) == TEAM_RED) {
|
||||
if( G_Client_PickTeam(clientNum) == TEAM_RED) {
|
||||
team = "red";
|
||||
}
|
||||
else {
|
||||
|
@ -666,14 +666,14 @@ static void G_AddBot( const char *name, float skill, const char *team, const cha
|
|||
}
|
||||
else
|
||||
{
|
||||
bot->client->sess.sessionTeam = PickTeam( -1 );
|
||||
bot->client->sess.sessionTeam = G_Client_PickTeam( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
preTeam = bot->client->sess.sessionTeam;
|
||||
|
||||
// have it connect to the game as a normal client
|
||||
if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
|
||||
if ( G_Client_Connect( clientNum, qtrue, qtrue ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -702,11 +702,11 @@ static void G_AddBot( const char *name, float skill, const char *team, const cha
|
|||
bot->client->ps.persistant[ PERS_TEAM ] = bot->client->sess.sessionTeam;
|
||||
|
||||
G_ReadSessionData( bot->client );
|
||||
ClientUserinfoChanged( clientNum );
|
||||
G_Client_UserinfoChanged( clientNum );
|
||||
}
|
||||
|
||||
if( delay == 0 ) {
|
||||
ClientBegin( clientNum, qfalse, qfalse, qfalse );
|
||||
G_Client_Begin( clientNum, qfalse, qfalse, qfalse );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,20 +245,34 @@ void breakable_spawn_trigger(gentity_t *ent) {
|
|||
|
||||
//RPG-X | GSIO01 | 09/05/2009 EOE
|
||||
|
||||
/*QUAKED func_breakable (0 .8 .5) ? x x x x INVINCIBLE x x x REPAIRABLE
|
||||
INVINCIBLE - can only be broken by being used
|
||||
REPAIRABLE - con be repaired with hyperspanner
|
||||
|
||||
/*QUAKED func_breakable (0 .8 .5) ? x x x x INVINCIBLE x x x REPAIRABLE NOORIGIN
|
||||
-----DESCRIPTION-----
|
||||
When destroyed, fires it's trigger and explodes
|
||||
When repaired just fires it's targets so things like forcefields get turned back on
|
||||
|
||||
"targetname" entities with matching target will fire it
|
||||
"paintarget" target to fire when hit (but not destroyed)
|
||||
"wait" how long minimum to wait between firing paintarget each time hit
|
||||
"model2" .md3 model to also draw
|
||||
"target" all entities with a matching targetname will be used when this is destoryed
|
||||
"health" default is 10
|
||||
-----SPAWNFLAGS-----
|
||||
1: DO NOT USE! This may come in conflict with shared functions from misc_model_breakable.
|
||||
2: DO NOT USE! This may come in conflict with shared functions from misc_model_breakable.
|
||||
4: DO NOT USE! This may come in conflict with shared functions from misc_model_breakable.
|
||||
8: DO NOT USE! This may come in conflict with shared functions from misc_model_breakable.
|
||||
16: INVINCIBLE - can only be broken by being used
|
||||
32: DO NOT USE! This may come in conflict with shared functions from misc_model_breakable.
|
||||
64: DO NOT USE! This may come in conflict with shared functions from misc_model_breakable.
|
||||
128: DO NOT USE! This may come in conflict with shared functions from misc_model_breakable.
|
||||
256: REPAIRABLE - can be repaired with hyperspanner, requires an origin brush
|
||||
512: NOORIGIN - used for retrofitting repairability on func_breakables with no origin brush, do not use for new maps
|
||||
|
||||
"team" - This cannot take damage from members of this team (2 = blue, 1 = red)
|
||||
-----KEYS-----
|
||||
"targetname" - entities with matching target will fire it
|
||||
"paintarget" - target to fire when hit (but not destroyed)
|
||||
"wait" - how long minimum to wait between firing paintarget each time hit
|
||||
"model2" - .md3 model to also draw
|
||||
"target" - all entities with a matching targetname will be used when this is destoryed
|
||||
"health" - default is 10
|
||||
|
||||
"luaDie" - Lua-Hook for when the breakable dies
|
||||
|
||||
"team" - This cannot take damage from members of this team (2 = blue, 1 = red) 2 will exclude players/clients in RPG-X
|
||||
|
||||
Damage: default is none
|
||||
"splashDamage" - damage to do (will make it explode on death
|
||||
|
@ -273,9 +287,34 @@ Damage: default is none
|
|||
5 - stone
|
||||
|
||||
Don't know if these work:
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
|
||||
q3map2:
|
||||
"_clone" _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" see _clone
|
||||
"_castShadows" OR "_cs" sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" sets whether the entity receives shadows
|
||||
|
||||
-----LUA-----
|
||||
Retrofitting repairability using lua:
|
||||
Retrofitting repairability is possible, however it is not easy as we likely have to come by the fact taht we do not have an origin brush.
|
||||
To start here is the code with no origin brush present:
|
||||
|
||||
ent = entity.FindBModel(bmodel);
|
||||
ent:SetSpawnflags(ent:GetSpawnflags() + 768);
|
||||
--Do not use entity.CallSpawn(ent); after this point for this entity!
|
||||
mover.SetAngles2(ent, posX, posY, posZ);
|
||||
ent:SetN00bCount(radius);
|
||||
|
||||
The bmodel-number can be retrieved ingame as an admin/developer by pointing at the entity and using the /getentinfo command
|
||||
posX, Y andf Z are the origin (usually the center of brush) of the entity and need too be retrieved manually from within the radiant
|
||||
radius is a spherical distance around origin/angles2 that the hyperspanner will respond to. It should barely cover the entire facing side of the entity.
|
||||
|
||||
In the unlikely event that we do have an origin brush this is the code:
|
||||
|
||||
ent = entity.FindBModel(bmodel);
|
||||
ent:SetSpawnflags(ent:GetSpawnflags() + 256);
|
||||
*/
|
||||
/**
|
||||
* Spawnfunction for func_breakable entity.
|
||||
|
@ -317,25 +356,38 @@ void SP_func_breakable( gentity_t *self )
|
|||
level.numBrushEnts++;
|
||||
}
|
||||
|
||||
/*QUAKED misc_model_breakable (1 0 0) (-16 -16 -16) (16 16 16) SOLID AUTOANIMATE DEADSOLID NO_DMODEL INVINCIBLE x x x REPAIRABLE
|
||||
SOLID - Movement is blocked by it, if not set, can still be broken by explosions and shots if it has health
|
||||
AUTOANIMATE - Will cycle it's anim
|
||||
DEADSOLID - Stay solid even when destroyed (in case damage model is rather large).
|
||||
NO_DMODEL - Makes it NOT display a damage model when destroyed, even if one exists
|
||||
INVINCIBLE - Can only be broken by being used
|
||||
/*QUAKED misc_model_breakable (1 0 0) (-16 -16 -16) (16 16 16) SOLID AUTOANIMATE DEADSOLID NO_DMODEL INVINCIBLE X X X REPAIRABLE X
|
||||
-----DESCRIPTION-----
|
||||
Destroyable *.md3-model. If it dies it will display it's damge model if one exists and fire it's targets.
|
||||
If repaired by either target_repair (not yet implemented) or hyperspanner (not yet fully implemented) it will fire it's targets
|
||||
|
||||
"model" arbitrary .md3 file to display
|
||||
"health" how much health to have - default is zero (not breakable) If you don't set the SOLID flag, but give it health, it can be shot but will not block NPCs or players from moving
|
||||
"targetname" when used, dies and displays damagemodel, if any (if not, removes itself)
|
||||
"target" What to use when it dies
|
||||
"paintarget" target to fire when hit (but not destroyed)
|
||||
"wait" how long minimum to wait between firing paintarget each time hit
|
||||
-----SPAWNFLAGS-----
|
||||
1: SOLID - Movement is blocked by it, if not set, can still be broken by explosions and shots if it has health
|
||||
2: AUTOANIMATE - Will cycle it's anim
|
||||
4: DEADSOLID - Stay solid even when destroyed (in case damage model is rather large).
|
||||
8: NO_DMODEL - Makes it NOT display a damage model when destroyed, even if one exists. Needs to be set if none exist.
|
||||
16: INVINCIBLE - Can only be broken by being used
|
||||
32: X - DO NOT USE! This may come in conflict with shared functions from func_breakable.
|
||||
64: X - DO NOT USE! This may come in conflict with shared functions from func_breakable.
|
||||
128: X - DO NOT USE! This may come in conflict with shared functions from func_breakable.
|
||||
256: REPAIRABLE - can be repaired with hyperspanner
|
||||
512: X - DO NOT USE! This may come in conflict with shared functions from func_breakable.
|
||||
|
||||
-----KEYS-----
|
||||
"model" - path to the arbitrary .md3 file to display
|
||||
"health" - how much health to have - default is zero (not breakable) If you don't set the SOLID flag, but give it health, it can be shot but will not block NPCs or players from moving
|
||||
"targetname" - when used, dies and displays damagemodel, if any (if not, removes itself)
|
||||
"target" - What to use when it dies
|
||||
"paintarget" - target to fire when hit (but not destroyed)
|
||||
"wait" - how long minimum to wait between firing paintarget each time hit
|
||||
|
||||
"luaDie" - Lua-Hook for when the breakable dies
|
||||
|
||||
Damage: default is none
|
||||
"splashDamage" - damage to do (will make it explode on death)
|
||||
"splashRadius" - radius for above damage
|
||||
|
||||
"team" - This cannot take damage from members of this team (2 = blue, 1 = red)
|
||||
"team" - This cannot take damage from members of this team (2 = blue, 1 = red) 2 will exclude players/clients in RPG-X
|
||||
|
||||
"material" - sets the chunk type:
|
||||
0 - none (default)
|
||||
|
@ -345,11 +397,34 @@ Damage: default is none
|
|||
4 - wood
|
||||
5 - stone
|
||||
|
||||
FIXME/TODO:
|
||||
-----LUA-----
|
||||
Finding an MMB for post-spawn manipulation:
|
||||
For this purpose we have created a function that will return the first of these that has a matching s.origin.
|
||||
You can get the s.origin ingame as an admin/developer by pointing at the MMB ingame and using the /getorigin-command.
|
||||
This is how it should look:
|
||||
|
||||
vec = vector.Construct(s.origin[X], s.origin[Y], s.origin[Z]);
|
||||
ent = entity.FindMMB(vec);
|
||||
|
||||
Refitting repairablility using lua:
|
||||
This is a fairly simple addition, here's the code:
|
||||
|
||||
vec = vector.Construct(s.origin[X], s.origin[Y], s.origin[Z]);
|
||||
MMB = entity.FindMMB(vec);
|
||||
MMB:SetSpawnflags(MMB:
|
||||
GetSpawnflags() + 256);
|
||||
if MMB:GetHealth() == 0 then --we do require health to be present for repairability
|
||||
MMB:SetHealth (1);
|
||||
entity.CallSpawn(MMB);
|
||||
end
|
||||
*/
|
||||
/*
|
||||
FIXME/TODO on misc_model_breakable:
|
||||
set size better?
|
||||
multiple damage models?
|
||||
don't throw chunks on pain, or throw level 1 chunks only on pains?
|
||||
custom explosion effect/sound?
|
||||
custom dmodel using model2?
|
||||
*/
|
||||
/**
|
||||
* Spawnfunction for misc_model_breakable entity.
|
||||
|
@ -422,6 +497,8 @@ void SP_misc_model_breakable( gentity_t *ent )
|
|||
//
|
||||
// AMMO plugin functions
|
||||
//
|
||||
// Remove this? No purpose in RPG-X other than displaying something fixed...
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
void ammo_use( gentity_t *self, gentity_t *other, gentity_t *activator);
|
||||
|
||||
|
@ -594,13 +671,20 @@ void ammo_station_finish_spawning ( gentity_t *self )
|
|||
}
|
||||
//------------------------------------------------------------
|
||||
/*QUAKED misc_ammo_station (1 0 0) (-16 -16 -16) (16 16 16)
|
||||
-----DESCRIPTION-----
|
||||
Grants ammo to client until depleted.
|
||||
This useless in RPG-X unless you'd like to spawn a DN-ammo-console.
|
||||
|
||||
-----Spawnflags-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"health" - how much health the model has - default 60 (zero makes non-breakable)
|
||||
"target" - what to use when it dies
|
||||
"paintarget" - target to fire when hit (but not destroyed)
|
||||
"count" - the amount of health given when used (default 1000)
|
||||
|
||||
"team" - This cannot take damage from members of this team and only members of this team can use it (2 = blue, 1 = red)
|
||||
"team" - This cannot take damage from members of this team and only members of this team can use it (2 = blue, 1 = red) 2 will exclude players/clients in RPG-X
|
||||
*/
|
||||
//------------------------------------------------------------
|
||||
/**
|
||||
|
@ -652,10 +736,18 @@ void SP_misc_ammo_station( gentity_t *ent )
|
|||
|
||||
//RPG-X | GSIO01 | 09/05/2009 SOE
|
||||
/*QUAKED target_repair (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
Repairs a func_breakable.
|
||||
-----DESCRIPTION-----
|
||||
Repairs a func_breakable..
|
||||
|
||||
"target" breakable to repair (targetname2)
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" breakable to repair (targetname or targetname2)
|
||||
*/
|
||||
|
||||
//We need to think about how to implement MMB's into this. Also maybe write a target_repair_multiple that skims both classes via while-loop --Harry
|
||||
|
||||
/**
|
||||
* Use function of target_repair entity.
|
||||
* Repairs it's target entity (stored in ent->lastEnemy)
|
||||
|
|
|
@ -4,7 +4,17 @@
|
|||
extern void InitMover( gentity_t *ent );
|
||||
|
||||
/*QUAKED cinematic_camera (0 0.5 0) (-4 -4 -4) (4 4 4)
|
||||
-----DESCRIPTION-----
|
||||
Camera for cinematic. Normally spawn by Lua script.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
none
|
||||
|
||||
-----LUA-----
|
||||
To be written later.
|
||||
*/
|
||||
void SP_cinematic_camera(gentity_t *ent) {
|
||||
trap_LinkEntity(ent);
|
||||
|
@ -22,7 +32,7 @@ void Cinematic_ActivateCameraMode(gentity_t *ent, gentity_t *target) {
|
|||
client->cam = target;
|
||||
VectorCopy(client->ps.viewangles, client->origViewAngles);
|
||||
VectorCopy(ent->r.currentOrigin, client->origOrigin);
|
||||
SetClientViewAngle(ent, target->s.angles);
|
||||
G_Client_SetViewAngle(ent, target->s.angles);
|
||||
G_SetOrigin(ent, target->r.currentOrigin);
|
||||
VectorCopy(target->r.currentOrigin, ent->client->ps.origin);
|
||||
trap_LinkEntity(ent);
|
||||
|
@ -36,7 +46,7 @@ void Cinematic_DeactivateCameraMode(gentity_t *ent) {
|
|||
|
||||
ent->flags ^= FL_CCAM;
|
||||
G_SetOrigin(ent, client->origOrigin);
|
||||
SetClientViewAngle(ent, client->origViewAngles);
|
||||
G_Client_SetViewAngle(ent, client->origViewAngles);
|
||||
trap_LinkEntity(ent);
|
||||
}
|
||||
|
||||
|
|
401
game/g_client.c
401
game/g_client.c
|
@ -18,7 +18,7 @@ extern pclass_t ValueNameForClass ( /*gentity_t *ent,*/ char* s );
|
|||
extern qboolean levelExiting;
|
||||
// g_client.c -- client functions that don't happen every frame
|
||||
|
||||
void G_StoreClientInitialStatus( gentity_t *ent );
|
||||
void G_Client_StoreClientInitialStatus( gentity_t *ent );
|
||||
|
||||
//! players mins
|
||||
static vec3_t playerMins = {-12, -12, -24}; //RPG-X : TiM - {-15, -15, -24}
|
||||
|
@ -26,7 +26,6 @@ static vec3_t playerMins = {-12, -12, -24}; //RPG-X : TiM - {-15, -15, -24}
|
|||
static vec3_t playerMaxs = {12, 12, 32}; // {15, 15, 32}
|
||||
|
||||
clInitStatus_t clientInitialStatus[MAX_CLIENTS];
|
||||
team_t borgTeam = TEAM_FREE;
|
||||
|
||||
//TiM: For easier transport setup
|
||||
/**
|
||||
|
@ -49,12 +48,17 @@ void G_InitTransport( int clientNum, vec3_t origin, vec3_t angles ) {
|
|||
tent->s.clientNum = clientNum;
|
||||
}
|
||||
|
||||
/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 32) initial
|
||||
/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 32) INITIAL
|
||||
-----DESCRIPTION-----
|
||||
potential spawning position for deathmatch games.
|
||||
The first time a player enters the game, they will be at an 'initial' spot.
|
||||
Targets will be fired when someone spawns in on them.
|
||||
"nobots" will prevent bots from using this spot.
|
||||
"nohumans" will prevent non-bots from using this spot.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: INITIAL - Preferred spawn for the first spawn of a client when entering a match.
|
||||
|
||||
-----KEYS-----
|
||||
"target" - entities with matching targetname will be fired if someone spawns here.
|
||||
"nobots" - if 1 will prevent bots from using this spot.
|
||||
"nohumans" - if 1 will prevent non-bots from using this spot.
|
||||
*/
|
||||
/**
|
||||
* Spawn function for deathmatch spawnpoint
|
||||
|
@ -62,6 +66,10 @@ Targets will be fired when someone spawns in on them.
|
|||
void SP_info_player_deathmatch( gentity_t *ent ) {
|
||||
int i;
|
||||
|
||||
if(strcmp(ent->classname, "info_player_deathmatch")) {
|
||||
ent->classname = G_NewString("info_player_deathmatch");
|
||||
}
|
||||
|
||||
G_SpawnInt( "nobots", "0", &i);
|
||||
if ( i ) {
|
||||
ent->flags |= FL_NO_BOTS;
|
||||
|
@ -74,19 +82,17 @@ void SP_info_player_deathmatch( gentity_t *ent ) {
|
|||
trap_LinkEntity(ent);
|
||||
}
|
||||
|
||||
/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 32)
|
||||
equivelant to info_player_deathmatch
|
||||
*/
|
||||
/**
|
||||
* Spawn function for player start spawnpoint which actually the same as deatchmatch spawnpoint
|
||||
*/
|
||||
void SP_info_player_start(gentity_t *ent) {
|
||||
ent->classname = "info_player_deathmatch";
|
||||
SP_info_player_deathmatch( ent );
|
||||
}
|
||||
|
||||
/*QUAKED info_player_intermission (1 0 1) (-16 -16 -24) (16 16 32)
|
||||
The intermission will be viewed from this point. Target an info_notnull for the view direction.
|
||||
-----DESCRIPTION-----
|
||||
The intermission will be viewed from this point.
|
||||
It is also used to spawn spectators.
|
||||
Target an info_notnull or similar for the view direction.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
none
|
||||
*/
|
||||
/**
|
||||
* Spawn function for intermission entity.
|
||||
|
@ -100,21 +106,21 @@ void SP_info_player_intermission( gentity_t *ent ) {
|
|||
/*
|
||||
=======================================================================
|
||||
|
||||
SelectSpawnPoint
|
||||
G_Client_SelectSpawnPoint
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
================
|
||||
SpotWouldTelefrag
|
||||
G_Client_SpotWouldTelefrag
|
||||
|
||||
================
|
||||
*/
|
||||
/**
|
||||
* Check if beaming to a point will result in a teleporter frag.
|
||||
*/
|
||||
qboolean SpotWouldTelefrag( gentity_t *spot ) {
|
||||
qboolean G_Client_SpotWouldTelefrag( gentity_t *spot ) {
|
||||
int i, num;
|
||||
int touch[MAX_GENTITIES];
|
||||
gentity_t *hit;
|
||||
|
@ -195,7 +201,7 @@ static gentity_t *SelectRandomDeathmatchSpawnPoint( void ) {
|
|||
spot = NULL;
|
||||
|
||||
while ((spot = G_Find (spot, FOFS(classname), "info_player_deathmatch")) != NULL) {
|
||||
if ( SpotWouldTelefrag( spot ) ) {
|
||||
if ( G_Client_SpotWouldTelefrag( spot ) ) {
|
||||
continue;
|
||||
}
|
||||
spots[ count ] = spot;
|
||||
|
@ -213,7 +219,7 @@ static gentity_t *SelectRandomDeathmatchSpawnPoint( void ) {
|
|||
|
||||
/*
|
||||
===========
|
||||
SelectSpawnPoint
|
||||
G_Client_SelectSpawnPoint
|
||||
|
||||
Chooses a player start, deathmatch start, etc
|
||||
============
|
||||
|
@ -221,7 +227,7 @@ Chooses a player start, deathmatch start, etc
|
|||
/**
|
||||
* Chooses a player start, deathmatch start, etc
|
||||
*/
|
||||
gentity_t *SelectSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles ) {
|
||||
gentity_t *G_Client_SelectSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles ) {
|
||||
gentity_t *spot;
|
||||
gentity_t *nearestSpot;
|
||||
|
||||
|
@ -272,8 +278,8 @@ static gentity_t *SelectInitialSpawnPoint( vec3_t origin, vec3_t angles ) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( !spot || SpotWouldTelefrag( spot ) ) {
|
||||
return SelectSpawnPoint( vec3_origin, origin, angles );
|
||||
if ( !spot || G_Client_SpotWouldTelefrag( spot ) ) {
|
||||
return G_Client_SelectSpawnPoint( vec3_origin, origin, angles );
|
||||
}
|
||||
|
||||
VectorCopy (spot->s.origin, origin);
|
||||
|
@ -311,10 +317,10 @@ static int bodyFadeSound=0;
|
|||
|
||||
/*
|
||||
===============
|
||||
InitBodyQue
|
||||
G_Client_InitBodyQue
|
||||
===============
|
||||
*/
|
||||
void InitBodyQue (void) {
|
||||
void G_Client_InitBodyQue (void) {
|
||||
int i;
|
||||
gentity_t *ent;
|
||||
|
||||
|
@ -466,11 +472,11 @@ static void CopyToBodyQue( gentity_t *ent ) {
|
|||
|
||||
/*
|
||||
==================
|
||||
SetClientViewAngle
|
||||
G_Client_SetViewAngle
|
||||
|
||||
==================
|
||||
*/
|
||||
void SetClientViewAngle( gentity_t *ent, vec3_t angle ) {
|
||||
void G_Client_SetViewAngle( gentity_t *ent, vec3_t angle ) {
|
||||
int i;
|
||||
|
||||
// set the delta angle
|
||||
|
@ -486,18 +492,18 @@ void SetClientViewAngle( gentity_t *ent, vec3_t angle ) {
|
|||
|
||||
/*
|
||||
================
|
||||
respawn
|
||||
G_Client_Respawn
|
||||
================
|
||||
*/
|
||||
extern char *ClassNameForValue( pclass_t pClass );
|
||||
void respawn( gentity_t *ent ) {
|
||||
void G_Client_Respawn( gentity_t *ent ) {
|
||||
qboolean borg = qfalse;
|
||||
gentity_t *tent;
|
||||
playerState_t *ps;
|
||||
|
||||
CopyToBodyQue (ent);
|
||||
|
||||
ClientSpawn(ent, 0, qfalse);//RPG-X: RedTechie - Modifyed
|
||||
G_Client_Spawn(ent, 0, qfalse);//RPG-X: RedTechie - Modifyed
|
||||
|
||||
ps = &ent->client->ps;
|
||||
|
||||
|
@ -515,7 +521,7 @@ void respawn( gentity_t *ent ) {
|
|||
|
||||
/*
|
||||
================
|
||||
TeamCount
|
||||
G_Client_TeamCount
|
||||
|
||||
Returns number of players on a team
|
||||
================
|
||||
|
@ -523,7 +529,7 @@ Returns number of players on a team
|
|||
/**
|
||||
* Returns number of players on a team
|
||||
*/
|
||||
team_t TeamCount( int ignoreClientNum, int team ) {
|
||||
team_t G_Client_TeamCount( int ignoreClientNum, int team ) {
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
|
@ -545,15 +551,15 @@ team_t TeamCount( int ignoreClientNum, int team ) {
|
|||
|
||||
/*
|
||||
================
|
||||
PickTeam
|
||||
G_Client_PickTeam
|
||||
|
||||
================
|
||||
*/
|
||||
team_t PickTeam( int ignoreClientNum ) {
|
||||
team_t G_Client_PickTeam( int ignoreClientNum ) {
|
||||
int counts[TEAM_NUM_TEAMS];
|
||||
|
||||
counts[TEAM_BLUE] = TeamCount( ignoreClientNum, TEAM_BLUE );
|
||||
counts[TEAM_RED] = TeamCount( ignoreClientNum, TEAM_RED );
|
||||
counts[TEAM_BLUE] = G_Client_TeamCount( ignoreClientNum, TEAM_BLUE );
|
||||
counts[TEAM_RED] = G_Client_TeamCount( ignoreClientNum, TEAM_RED );
|
||||
|
||||
if ( counts[TEAM_BLUE] > counts[TEAM_RED] ) {
|
||||
return TEAM_RED;
|
||||
|
@ -938,17 +944,17 @@ void SetCSTeam( team_t team, char *teamname )
|
|||
}
|
||||
/*
|
||||
===========
|
||||
ClientUserInfoChanged
|
||||
G_Client_UserinfoChanged
|
||||
============
|
||||
*/
|
||||
/**
|
||||
* Called from ClientConnect when the player first connects and
|
||||
* Called from G_Client_Connect when the player first connects and
|
||||
* directly by the server system when the player updates a userinfo variable.
|
||||
*
|
||||
* The game can override any of the settings and call trap_SetUserinfo
|
||||
* if desired.
|
||||
*/
|
||||
void ClientUserinfoChanged( int clientNum ) {
|
||||
void G_Client_UserinfoChanged( int clientNum ) {
|
||||
gentity_t *ent;
|
||||
int i;
|
||||
char *s;
|
||||
|
@ -1253,7 +1259,7 @@ void ClientUserinfoChanged( int clientNum ) {
|
|||
|
||||
/*
|
||||
===========
|
||||
ClientConnect
|
||||
G_Client_Connect
|
||||
============
|
||||
*/
|
||||
/**
|
||||
|
@ -1266,13 +1272,13 @@ ClientConnect
|
|||
* a string with the reason for denial.
|
||||
*
|
||||
* Otherwise, the client will be sent the current gamestate
|
||||
* and will eventually get to ClientBegin.
|
||||
* and will eventually get to G_Client_Begin.
|
||||
*
|
||||
* firstTime will be qtrue the very first time a client connects
|
||||
* to the server machine, but qfalse on map changes and tournement
|
||||
* restarts.
|
||||
*/
|
||||
char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) {
|
||||
char *G_Client_Connect( int clientNum, qboolean firstTime, qboolean isBot ) {
|
||||
char *value;
|
||||
gclient_t *client;
|
||||
char userinfo[MAX_INFO_STRING];
|
||||
|
@ -1417,7 +1423,7 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) {
|
|||
|
||||
//========================================================
|
||||
}
|
||||
ClientUserinfoChanged( clientNum );
|
||||
G_Client_UserinfoChanged( clientNum );
|
||||
|
||||
//RPG-X: Save the ip for later - has to be down here, since it gets flushed in the above function
|
||||
Q_strncpyz( ent->client->pers.ip, ip, sizeof( ent->client->pers.ip ) );
|
||||
|
@ -1464,7 +1470,7 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) {
|
|||
}
|
||||
|
||||
// count current clients and rank for scoreboard
|
||||
//CalculateRanks( qfalse );
|
||||
//G_Client_CalculateRanks( qfalse );
|
||||
|
||||
//RPG-X: J2J - Reset Variables
|
||||
DragDat[clientNum].AdminId = -1;
|
||||
|
@ -1575,7 +1581,7 @@ static void G_SendTransData(int clientNum) {
|
|||
|
||||
/*
|
||||
===========
|
||||
ClientBegin
|
||||
G_Client_Begin
|
||||
============
|
||||
*/
|
||||
/**
|
||||
|
@ -1583,7 +1589,7 @@ ClientBegin
|
|||
* to be placed into the level. This will happen every level load,
|
||||
* and on transition between teams, but doesn't happen on respawns
|
||||
*/
|
||||
void ClientBegin( int clientNum, qboolean careAboutWarmup, qboolean isBot, qboolean first ) {
|
||||
void G_Client_Begin( int clientNum, qboolean careAboutWarmup, qboolean isBot, qboolean first ) {
|
||||
gentity_t *ent;
|
||||
gclient_t *client;
|
||||
gentity_t *tent;
|
||||
|
@ -1634,7 +1640,7 @@ void ClientBegin( int clientNum, qboolean careAboutWarmup, qboolean isBot, qbool
|
|||
SetScore( ent, score );
|
||||
|
||||
// locate ent at a spawn point
|
||||
ClientSpawn( ent, 0, qfalse );//RPG-X: RedTechie - Modifyed
|
||||
G_Client_Spawn( ent, 0, qfalse );//RPG-X: RedTechie - Modifyed
|
||||
|
||||
if ( client->sess.sessionTeam != TEAM_SPECTATOR /*&& g_holoIntro.integer==0 */ )
|
||||
{ // Don't use transporter FX for spectators or those watching the holodoors.
|
||||
|
@ -1647,7 +1653,7 @@ void ClientBegin( int clientNum, qboolean careAboutWarmup, qboolean isBot, qbool
|
|||
G_LogPrintf( "ClientBegin: %i (%s)\n", clientNum, g_entities[clientNum].client->pers.ip );
|
||||
|
||||
// count current clients and rank for scoreboard
|
||||
CalculateRanks( qfalse );
|
||||
G_Client_CalculateRanks( qfalse );
|
||||
|
||||
//TiM - This appears to be a flaw in Raven's design
|
||||
//When a client connects, or if they enter admin or medics class
|
||||
|
@ -1795,7 +1801,7 @@ void ClientBegin( int clientNum, qboolean careAboutWarmup, qboolean isBot, qbool
|
|||
}
|
||||
|
||||
// WEAPONS - PHENIX1
|
||||
void ClientWeaponsForClass ( gclient_t *client, pclass_t pclass )
|
||||
void G_Client_WeaponsForClass ( gclient_t *client, pclass_t pclass )
|
||||
{
|
||||
int i;
|
||||
int Bits;
|
||||
|
@ -1818,7 +1824,7 @@ void ClientWeaponsForClass ( gclient_t *client, pclass_t pclass )
|
|||
}
|
||||
}
|
||||
|
||||
void ClientHoldablesForClass ( gclient_t *client, pclass_t pclass )
|
||||
void G_Client_HoldablesForClass ( gclient_t *client, pclass_t pclass )
|
||||
{
|
||||
if ( g_classData[pclass].isMarine )
|
||||
client->ps.stats[STAT_HOLDABLE_ITEM] = BG_FindItemForHoldable( HI_TRANSPORTER ) - bg_itemlist;
|
||||
|
@ -1827,7 +1833,7 @@ void ClientHoldablesForClass ( gclient_t *client, pclass_t pclass )
|
|||
client->ps.stats[STAT_HOLDABLE_ITEM] = BG_FindItemForHoldable( HI_SHIELD ) - bg_itemlist;
|
||||
}
|
||||
|
||||
void G_StoreClientInitialStatus( gentity_t *ent )
|
||||
void G_Client_StoreClientInitialStatus( gentity_t *ent )
|
||||
{
|
||||
char userinfo[MAX_INFO_STRING];
|
||||
|
||||
|
@ -1888,17 +1894,17 @@ void G_RestoreClientInitialStatus( gentity_t *ent )
|
|||
|
||||
/*
|
||||
===========
|
||||
ClientSpawn
|
||||
G_Client_Spawn
|
||||
|
||||
Called every time a client is placed fresh in the world:
|
||||
after the first ClientBegin, and after each respawn
|
||||
after the first G_Client_Begin, and after each respawn
|
||||
Initializes all non-persistant parts of playerState
|
||||
------------------------------------
|
||||
Modifyed By: RedTechie
|
||||
And also by Marcin - 30/12/2008
|
||||
============
|
||||
*/
|
||||
void ClientSpawn(gentity_t *ent, int rpgx_spawn, qboolean fromDeath ) {
|
||||
void G_Client_Spawn(gentity_t *ent, int rpgx_spawn, qboolean fromDeath ) {
|
||||
int index=0;
|
||||
vec3_t spawn_origin, spawn_angles;
|
||||
gclient_t *client=NULL;
|
||||
|
@ -1924,12 +1930,6 @@ void ClientSpawn(gentity_t *ent, int rpgx_spawn, qboolean fromDeath ) {
|
|||
if ( client->sess.sessionTeam == TEAM_SPECTATOR ) {
|
||||
spawnPoint = SelectSpectatorSpawnPoint (
|
||||
spawn_origin, spawn_angles);
|
||||
} else if (g_gametype.integer >= GT_TEAM) {
|
||||
spawnPoint = SelectCTFSpawnPoint (
|
||||
ent,
|
||||
client->sess.sessionTeam,
|
||||
client->pers.teamState.state,
|
||||
spawn_origin, spawn_angles);
|
||||
} else {
|
||||
do {
|
||||
// the first spawn should be at a good looking spot
|
||||
|
@ -1938,7 +1938,7 @@ void ClientSpawn(gentity_t *ent, int rpgx_spawn, qboolean fromDeath ) {
|
|||
spawnPoint = SelectInitialSpawnPoint( spawn_origin, spawn_angles );
|
||||
} else {
|
||||
// don't spawn near existing origin if possible
|
||||
spawnPoint = SelectSpawnPoint (
|
||||
spawnPoint = G_Client_SelectSpawnPoint (
|
||||
client->ps.origin,
|
||||
spawn_origin, spawn_angles);
|
||||
}
|
||||
|
@ -2018,7 +2018,7 @@ void ClientSpawn(gentity_t *ent, int rpgx_spawn, qboolean fromDeath ) {
|
|||
ent->r.contents = CONTENTS_BODY;
|
||||
|
||||
ent->clipmask = MASK_PLAYERSOLID;
|
||||
ent->die = player_die;
|
||||
ent->die = G_Client_Die;
|
||||
ent->waterlevel = 0;
|
||||
ent->watertype = 0;
|
||||
ent->flags = 0;
|
||||
|
@ -2037,7 +2037,7 @@ void ClientSpawn(gentity_t *ent, int rpgx_spawn, qboolean fromDeath ) {
|
|||
|
||||
if ( oClass != client->sess.sessionClass )
|
||||
{//need to send the class change
|
||||
ClientUserinfoChanged( client->ps.clientNum );
|
||||
G_Client_UserinfoChanged( client->ps.clientNum );
|
||||
}
|
||||
|
||||
client->ps.persistant[PERS_CLASS] = client->sess.sessionClass;
|
||||
|
@ -2049,11 +2049,11 @@ void ClientSpawn(gentity_t *ent, int rpgx_spawn, qboolean fromDeath ) {
|
|||
}
|
||||
|
||||
if ( !fromDeath || !rpg_dropOnDeath.integer || !rpg_allowWeaponDrop.integer ) {
|
||||
ClientWeaponsForClass( client, pClass );
|
||||
G_Client_WeaponsForClass( client, pClass );
|
||||
} else { // Marcin: just a hand
|
||||
ClientWeaponsForClass( client, 0 );
|
||||
G_Client_WeaponsForClass( client, 0 );
|
||||
}
|
||||
ClientHoldablesForClass( client, pClass );
|
||||
G_Client_HoldablesForClass( client, pClass );
|
||||
|
||||
if(rpgx_spawn != 1){
|
||||
G_SetOrigin( ent, spawn_origin );
|
||||
|
@ -2067,7 +2067,7 @@ void ClientSpawn(gentity_t *ent, int rpgx_spawn, qboolean fromDeath ) {
|
|||
|
||||
trap_GetUsercmd( client - level.clients, &ent->client->pers.cmd );
|
||||
if(rpgx_spawn != 1){
|
||||
SetClientViewAngle( ent, spawn_angles );
|
||||
G_Client_SetViewAngle( ent, spawn_angles );
|
||||
}
|
||||
|
||||
if(rpgx_spawn != 1){
|
||||
|
@ -2230,7 +2230,7 @@ void ClientSpawn(gentity_t *ent, int rpgx_spawn, qboolean fromDeath ) {
|
|||
//store intial client values
|
||||
//FIXME: when purposely change teams, this gets confused?
|
||||
|
||||
G_StoreClientInitialStatus( ent );
|
||||
G_Client_StoreClientInitialStatus( ent );
|
||||
|
||||
//RPG-X: Marcin: stuff was here previously - 22/12/2008
|
||||
}
|
||||
|
@ -2270,7 +2270,7 @@ gentity_t *SpawnBeamOutPlayer( gentity_t *ent ) {
|
|||
|
||||
/*
|
||||
===========
|
||||
ClientDisconnect
|
||||
G_Client_Disconnect
|
||||
|
||||
Called when a player drops from the server.
|
||||
Will not be called between levels.
|
||||
|
@ -2280,7 +2280,7 @@ call trap_DropClient(), which will call this and do
|
|||
server system housekeeping.
|
||||
============
|
||||
*/
|
||||
void ClientDisconnect( int clientNum ) {
|
||||
void G_Client_Disconnect( int clientNum ) {
|
||||
gentity_t *ent;
|
||||
gentity_t *tent;
|
||||
int i;
|
||||
|
@ -2368,7 +2368,7 @@ void ClientDisconnect( int clientNum ) {
|
|||
if ( g_gametype.integer == GT_TOURNAMENT && !level.intermissiontime
|
||||
&& !level.warmupTime && level.sortedClients[1] == clientNum ) {
|
||||
level.clients[ level.sortedClients[0] ].sess.wins++;
|
||||
ClientUserinfoChanged( level.sortedClients[0] );
|
||||
G_Client_UserinfoChanged( level.sortedClients[0] );
|
||||
}
|
||||
|
||||
if ( g_gametype.integer == GT_TOURNAMENT && ent->client->sess.sessionTeam == TEAM_FREE && level.intermissiontime )
|
||||
|
@ -2392,7 +2392,7 @@ void ClientDisconnect( int clientNum ) {
|
|||
|
||||
trap_SetConfigstring( CS_PLAYERS + clientNum, "");
|
||||
|
||||
CalculateRanks( qfalse );
|
||||
G_Client_CalculateRanks( qfalse );
|
||||
|
||||
if ( ent->r.svFlags & SVF_BOT ) {
|
||||
BotAIShutdownClient( clientNum );
|
||||
|
@ -2436,4 +2436,253 @@ qboolean IsAdmin( gentity_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
G_Client_GetLocation
|
||||
|
||||
Report a location for the player. Uses placed nearby target_location entities
|
||||
============
|
||||
*/
|
||||
gentity_t *G_Client_GetLocation(gentity_t *ent)
|
||||
{
|
||||
gentity_t *eloc, *best;
|
||||
float bestlen, len;
|
||||
vec3_t origin;
|
||||
|
||||
best = NULL;
|
||||
bestlen = 3*8192.0*8192.0;
|
||||
|
||||
VectorCopy( ent->r.currentOrigin, origin );
|
||||
|
||||
for (eloc = level.locationHead; eloc; eloc = eloc->nextTrain) {
|
||||
len = ( origin[0] - eloc->r.currentOrigin[0] ) * ( origin[0] - eloc->r.currentOrigin[0] )
|
||||
+ ( origin[1] - eloc->r.currentOrigin[1] ) * ( origin[1] - eloc->r.currentOrigin[1] )
|
||||
+ ( origin[2] - eloc->r.currentOrigin[2] ) * ( origin[2] - eloc->r.currentOrigin[2] );
|
||||
|
||||
if ( len > bestlen ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !trap_InPVS( origin, eloc->r.currentOrigin ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bestlen = len;
|
||||
best = eloc;
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
G_Client_GetLocationMsg
|
||||
|
||||
Report a location for the player. Uses placed nearby target_location entities
|
||||
============
|
||||
*/
|
||||
qboolean G_Client_GetLocationMsg(gentity_t *ent, char *loc, int loclen)
|
||||
{
|
||||
gentity_t *best;
|
||||
|
||||
best = G_Client_GetLocation( ent );
|
||||
|
||||
if (!best)
|
||||
return qfalse;
|
||||
|
||||
if (best->count) {
|
||||
if (best->count < 0)
|
||||
best->count = 0;
|
||||
if (best->count > 7)
|
||||
best->count = 7;
|
||||
Com_sprintf(loc, loclen, "%c%c%s" S_COLOR_WHITE, Q_COLOR_ESCAPE, best->count + '0', best->message );
|
||||
} else
|
||||
Com_sprintf(loc, loclen, "%s", best->message);
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
G_Client_CheckHealthInfoMessage
|
||||
|
||||
Sends Health Changes to proper clients
|
||||
|
||||
Format:
|
||||
clientNum health
|
||||
|
||||
==================
|
||||
*/
|
||||
void G_Client_CheckHealthInfoMessage( void )
|
||||
{
|
||||
char entry[1024];
|
||||
char string[1400];
|
||||
int stringlength;
|
||||
int i, j, t;
|
||||
gentity_t *player, *ent;
|
||||
int sendToCnt, cnt, sentCnt;
|
||||
int h;
|
||||
int clients[MAX_CLIENTS];
|
||||
int sendToClients[MAX_CLIENTS];
|
||||
|
||||
//only send this to medics or spectators or adminz
|
||||
for (i = 0, sendToCnt = 0; i < g_maxclients.integer; i++)
|
||||
{
|
||||
|
||||
if ( level.clients[i].pers.connected == CON_CONNECTED && level.clients[i].ps.stats[STAT_HEALTH] > 0 &&//make sure they've actually spawned in already
|
||||
(level.clients[i].sess.sessionTeam == TEAM_SPECTATOR || g_classData[level.clients[i].sess.sessionClass].isMedical || g_classData[level.clients[i].sess.sessionClass].isAdmin ) )
|
||||
{
|
||||
sendToClients[sendToCnt++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !sendToCnt )
|
||||
{//no-one to send to
|
||||
return;
|
||||
}
|
||||
|
||||
//only send those clients whose health has changed this cycle
|
||||
//NB: there's a prob with client 0 in here....
|
||||
for (i = 0, cnt = 0; i < g_maxclients.integer; i++)
|
||||
{
|
||||
player = g_entities + i;
|
||||
if ( player->inuse && player->old_health != player->health && ( player->health > 0 || player->old_health > 0 ))
|
||||
{
|
||||
clients[cnt++] = i;
|
||||
player->old_health = player->health;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !cnt )
|
||||
{//no-one relevant changed health
|
||||
return;
|
||||
}
|
||||
|
||||
for ( t = 0; t < sendToCnt; t++ )
|
||||
{
|
||||
ent = g_entities + sendToClients[t];
|
||||
sentCnt = 0;
|
||||
|
||||
// send the latest information on all clients
|
||||
string[0] = 0;
|
||||
stringlength = 0;
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
player = g_entities + clients[i];
|
||||
|
||||
if ( ent == player )
|
||||
{//don't send the ent his own health
|
||||
continue;
|
||||
}
|
||||
|
||||
//send this one
|
||||
sentCnt++;
|
||||
|
||||
h = player->health;
|
||||
if (h < 0) h = 0;
|
||||
|
||||
Com_sprintf (entry, sizeof(entry), " %i %i", clients[i], h);
|
||||
j = strlen(entry);
|
||||
if (stringlength + j > sizeof(string))
|
||||
break;
|
||||
strcpy (string + stringlength, entry);
|
||||
stringlength += j;
|
||||
}
|
||||
|
||||
if ( sentCnt )
|
||||
{
|
||||
trap_SendServerCommand( sendToClients[t], va("hinfo %i%s", sentCnt, string) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TiM - Modified to work with RPG-X
|
||||
void G_Client_CheckClientStatus(void)
|
||||
{
|
||||
int i;
|
||||
gentity_t *loc, *ent;
|
||||
|
||||
if (level.time - level.lastTeamLocationTime > TEAM_LOCATION_UPDATE_TIME) {
|
||||
|
||||
level.lastTeamLocationTime = level.time;
|
||||
|
||||
for (i = 0; i < g_maxclients.integer; i++) {
|
||||
ent = g_entities + i;
|
||||
if (ent->inuse) {
|
||||
loc = G_Client_GetLocation( ent );
|
||||
if (loc)
|
||||
ent->client->pers.teamState.location = loc->health;
|
||||
else
|
||||
ent->client->pers.teamState.location = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < g_maxclients.integer; i++) {
|
||||
ent = g_entities + i;
|
||||
if (ent->inuse) {
|
||||
G_Client_LocationsMessage( ent );
|
||||
}
|
||||
}
|
||||
|
||||
G_Client_CheckHealthInfoMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
G_Client_LocationsMessage
|
||||
|
||||
Format:
|
||||
clientNum location health armor weapon powerups
|
||||
|
||||
==================
|
||||
*/
|
||||
void G_Client_LocationsMessage( gentity_t *ent ) {
|
||||
char entry[1024];
|
||||
char string[1400];
|
||||
int stringlength;
|
||||
int i, j;
|
||||
gentity_t *player;
|
||||
int cnt;
|
||||
|
||||
//don't bother sending during intermission?
|
||||
if ( level.intermissiontime )
|
||||
return;
|
||||
|
||||
// figure out what client should be on the display
|
||||
// we are limited to 8, but we want to use the top eight players
|
||||
// but in client order (so they don't keep changing position on the overlay)
|
||||
for (i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++) {
|
||||
player = g_entities + level.sortedClients[i];
|
||||
if (player->inuse && player->client->sess.sessionTeam ==
|
||||
ent->client->sess.sessionTeam ) {
|
||||
}
|
||||
}
|
||||
|
||||
// send the latest information on all clients
|
||||
string[0] = 0;
|
||||
stringlength = 0;
|
||||
|
||||
for (i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++) {
|
||||
player = g_entities + i;
|
||||
//RPG-X | Phenix | 05/03/2005
|
||||
if (player->inuse) {
|
||||
//to counter for the fact we could pwn the server doing this, remove all superfluous data
|
||||
|
||||
Com_sprintf (entry, sizeof(entry), " %i %i ", i, player->client->pers.teamState.location);
|
||||
j = strlen(entry);
|
||||
if (stringlength + j > sizeof(string))
|
||||
break;
|
||||
strcpy (string + stringlength, entry);
|
||||
stringlength += j;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
trap_SendServerCommand( ent-g_entities, va("tinfo %i%s", cnt, string) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
219
game/g_cmds.c
219
game/g_cmds.c
|
@ -539,7 +539,7 @@ static void Cmd_LevelShot_f( gentity_t *ent ) {
|
|||
level.intermissiontime = -1;
|
||||
// Special 'level shot' setting -- Terrible ABUSE!!! HORRIBLE NASTY HOBBITTESSSES
|
||||
|
||||
BeginIntermission();
|
||||
G_Client_BeginIntermission();
|
||||
trap_SendServerCommand( ent-g_entities, "clientLevelShot" );
|
||||
}
|
||||
|
||||
|
@ -608,10 +608,10 @@ static void Cmd_Kill_f( gentity_t *ent )
|
|||
ps->stats[STAT_WEAPONS] = ( 1 << WP_0 );
|
||||
ps->stats[STAT_HOLDABLE_ITEM] = HI_NONE;
|
||||
ps->stats[STAT_HEALTH] = ent->health = 1;
|
||||
player_die (ent, ent, ent, 1, meansOfDeath ); //MOD_SUICIDE
|
||||
G_Client_Die (ent, ent, ent, 1, meansOfDeath ); //MOD_SUICIDE
|
||||
}else{
|
||||
ps->stats[STAT_HEALTH] = ent->health = 0;
|
||||
player_die (ent, ent, ent, 100000, meansOfDeath ); //MOD_SUICIDE
|
||||
G_Client_Die (ent, ent, ent, 100000, meansOfDeath ); //MOD_SUICIDE
|
||||
}
|
||||
|
||||
if ( rpg_kicksuiciders.integer > 0 )
|
||||
|
@ -733,7 +733,7 @@ qboolean SetTeam( gentity_t *ent, char *s ) {
|
|||
// pick the team with the least number of players
|
||||
if ( isBot )
|
||||
{
|
||||
team = PickTeam( clientNum );
|
||||
team = G_Client_PickTeam( clientNum );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -746,8 +746,8 @@ qboolean SetTeam( gentity_t *ent, char *s ) {
|
|||
{
|
||||
int counts[TEAM_NUM_TEAMS];
|
||||
|
||||
counts[TEAM_BLUE] = TeamCount( clNum, TEAM_BLUE );
|
||||
counts[TEAM_RED] = TeamCount( clNum, TEAM_RED );
|
||||
counts[TEAM_BLUE] = G_Client_TeamCount( clNum, TEAM_BLUE );
|
||||
counts[TEAM_RED] = G_Client_TeamCount( clNum, TEAM_RED );
|
||||
|
||||
// We allow a spread of two
|
||||
if ( team == TEAM_RED && counts[TEAM_RED] - counts[TEAM_BLUE] > 1 )
|
||||
|
@ -800,7 +800,7 @@ qboolean SetTeam( gentity_t *ent, char *s ) {
|
|||
// Kill him (makes sure he loses flags, etc)
|
||||
ent->flags &= ~FL_GODMODE;
|
||||
ent->client->ps.stats[STAT_HEALTH] = ent->health = 0;
|
||||
player_die (ent, NULL, NULL, 100000, MOD_RESPAWN);
|
||||
G_Client_Die (ent, NULL, NULL, 100000, MOD_RESPAWN);
|
||||
|
||||
}
|
||||
// they go to the end of the line for tournements
|
||||
|
@ -815,9 +815,9 @@ qboolean SetTeam( gentity_t *ent, char *s ) {
|
|||
BroadcastTeamChange( client, oldTeam );
|
||||
|
||||
// get and distribute relevent paramters
|
||||
ClientUserinfoChanged( clientNum );
|
||||
G_Client_UserinfoChanged( clientNum );
|
||||
|
||||
ClientBegin( clientNum, qfalse, qfalse, qfalse );
|
||||
G_Client_Begin( clientNum, qfalse, qfalse, qfalse );
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
@ -953,7 +953,7 @@ qboolean SetClass( gentity_t *ent, char *s, char *teamName, qboolean SaveToCvar
|
|||
else
|
||||
{//not changing teams or couldn't change teams
|
||||
// get and distribute relevent paramters
|
||||
ClientUserinfoChanged( clientNum );
|
||||
G_Client_UserinfoChanged( clientNum );
|
||||
|
||||
//if in the game already, kill and respawn him, else just wait to join
|
||||
if ( sess->sessionTeam == TEAM_SPECTATOR )
|
||||
|
@ -965,7 +965,7 @@ qboolean SetClass( gentity_t *ent, char *s, char *teamName, qboolean SaveToCvar
|
|||
//RPG-X: RedTechie - No respawn for n00bs set all info and frap that a n00b needs HERE this eliminates respawns for n00bs
|
||||
if(g_classData[pclass].isn00b/*pclass == PC_N00B*/){
|
||||
|
||||
ClientSpawn(ent, 1, qfalse);
|
||||
G_Client_Spawn(ent, 1, qfalse);
|
||||
ps->stats[STAT_WEAPONS] = ( 1 << WP_0 );
|
||||
ps->stats[STAT_HOLDABLE_ITEM] = HI_NONE;
|
||||
|
||||
|
@ -990,8 +990,8 @@ qboolean SetClass( gentity_t *ent, char *s, char *teamName, qboolean SaveToCvar
|
|||
ent->flags &= ~FL_GODMODE;
|
||||
ps->stats[STAT_HEALTH] = ent->health = 0;
|
||||
|
||||
player_die (ent, NULL, NULL, 100000, MOD_RESPAWN);
|
||||
ClientBegin( clientNum, qfalse, qfalse, qfalse );
|
||||
G_Client_Die (ent, NULL, NULL, 100000, MOD_RESPAWN);
|
||||
G_Client_Begin( clientNum, qfalse, qfalse, qfalse );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1023,8 +1023,6 @@ void StopFollowing( gentity_t *ent ) {
|
|||
ps->stats[STAT_HEALTH] = ps->stats[STAT_MAX_HEALTH];
|
||||
}
|
||||
|
||||
extern team_t borgTeam;
|
||||
|
||||
/*
|
||||
=================
|
||||
Cmd_Team_f
|
||||
|
@ -1088,6 +1086,26 @@ static void Cmd_Team_f( gentity_t *ent ) {
|
|||
ent->client->switchTeamTime = level.time + 2000;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Cmd_Ready_f
|
||||
====================
|
||||
*/
|
||||
/**
|
||||
* This function is called from the ui_sp_postgame.c as a result of clicking on the
|
||||
* "next" button in non GT_TOURNAMENT games. This replaces the old system of waiting
|
||||
* for the user to click an ATTACK or USE button to signal ready
|
||||
* (see ClientIntermissionThink())
|
||||
*
|
||||
* when all clients have signaled ready, the game continues to the next match.
|
||||
*/
|
||||
void Cmd_Ready_f (gentity_t *ent)
|
||||
{
|
||||
gclient_t *client;
|
||||
client = ent->client;
|
||||
|
||||
client->readyToExit = qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -1471,12 +1489,10 @@ static void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chat
|
|||
clientPersistant_t *entPers = &entClient->pers;
|
||||
clientPersistant_t *tarPers = NULL;
|
||||
clientSession_t *entSess = &entClient->sess;
|
||||
clientSession_t *tarSess =NULL;
|
||||
|
||||
if(target && target->client) {
|
||||
tarClient = target->client;
|
||||
tarPers = &tarClient->pers;
|
||||
tarSess =&tarClient->sess;
|
||||
}
|
||||
|
||||
if ( g_gametype.integer < GT_TEAM && mode == SAY_TEAM ) {
|
||||
|
@ -1530,21 +1546,13 @@ static void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chat
|
|||
color = COLOR_WHITE;
|
||||
break;
|
||||
case SAY_TELL:
|
||||
if (target && g_gametype.integer >= GT_TEAM && tarSess &&
|
||||
tarSess->sessionTeam == entSess->sessionTeam && tarPers &&
|
||||
Team_GetLocationMsg(ent, location, sizeof(location)))
|
||||
Com_sprintf (name, sizeof(name), "^7%s ^7from %s%c%c (%s): ", tarPers->netname, entPers->netname, Q_COLOR_ESCAPE, COLOR_WHITE, location );
|
||||
else if(tarPers)
|
||||
if(tarPers)
|
||||
Com_sprintf (name, sizeof(name), "^7%s ^7from %s%c%c: ", tarPers->netname, entPers->netname, Q_COLOR_ESCAPE, COLOR_WHITE );
|
||||
else return;
|
||||
color = COLOR_MAGENTA;
|
||||
break;
|
||||
case SAY_TELL2:
|
||||
if (target && g_gametype.integer >= GT_TEAM && tarSess &&
|
||||
tarSess->sessionTeam == entSess->sessionTeam && tarPers &&
|
||||
Team_GetLocationMsg(ent, location, sizeof(location)))
|
||||
Com_sprintf (name, sizeof(name), "^7%s ^7from %s%c%c (%s): ", tarPers->netname, entPers->netname, Q_COLOR_ESCAPE, COLOR_WHITE, location );
|
||||
else if(tarPers)
|
||||
if(tarPers)
|
||||
Com_sprintf (name, sizeof(name), "^7%s ^7from %s%c%c: ", tarPers->netname, entPers->netname, Q_COLOR_ESCAPE, COLOR_WHITE );
|
||||
else return;
|
||||
color = COLOR_MAGENTA;
|
||||
|
@ -1560,7 +1568,7 @@ static void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chat
|
|||
color = COLOR_YELLOW;
|
||||
break;
|
||||
case SAY_ADMIN:
|
||||
if (Team_GetLocationMsg(ent, location, sizeof(location)) && tarPers)
|
||||
if (G_Client_GetLocationMsg(ent, location, sizeof(location)) && tarPers)
|
||||
Com_sprintf (name, sizeof(name), "[%s%c%c] [%s] (%s): ", entPers->netname, Q_COLOR_ESCAPE, COLOR_WHITE, tarPers->netname, location );
|
||||
else if(tarPers)
|
||||
Com_sprintf (name, sizeof(name), "[%s%c%c ^7To %s^7]: ", entPers->netname, Q_COLOR_ESCAPE, COLOR_WHITE, tarPers->netname );
|
||||
|
@ -2274,10 +2282,10 @@ static void Cmd_ForceKill_f( gentity_t *ent ) {
|
|||
ps->stats[STAT_WEAPONS] = ( 1 << WP_0 );
|
||||
ps->stats[STAT_HOLDABLE_ITEM] = HI_NONE;
|
||||
ps->stats[STAT_HEALTH] = target->health = 1;
|
||||
player_die (target, target, target, 100000, MOD_FORCEDSUICIDE);
|
||||
G_Client_Die (target, target, target, 100000, MOD_FORCEDSUICIDE);
|
||||
}else{
|
||||
ps->stats[STAT_HEALTH] = target->health = 0;
|
||||
player_die (target, target, target, 100000, MOD_FORCEDSUICIDE);
|
||||
G_Client_Die (target, target, target, 100000, MOD_FORCEDSUICIDE);
|
||||
}
|
||||
} // end iterations
|
||||
|
||||
|
@ -2311,10 +2319,10 @@ static void Cmd_ForceKill_f( gentity_t *ent ) {
|
|||
ps->stats[STAT_WEAPONS] = ( 1 << WP_0 );
|
||||
ps->stats[STAT_HOLDABLE_ITEM] = HI_NONE;
|
||||
ps->stats[STAT_HEALTH] = target->health = 1;
|
||||
player_die (target, target, target, 100000, MOD_FORCEDSUICIDE);
|
||||
G_Client_Die (target, target, target, 100000, MOD_FORCEDSUICIDE);
|
||||
}else{
|
||||
ps->stats[STAT_HEALTH] = target->health = 0;
|
||||
player_die (target, target, target, 100000, MOD_FORCEDSUICIDE);
|
||||
G_Client_Die (target, target, target, 100000, MOD_FORCEDSUICIDE);
|
||||
}
|
||||
|
||||
Com_sprintf (send, sizeof(send), "%s ^7forced %s^7's death", ent->client->pers.netname, target->client->pers.netname);
|
||||
|
@ -2445,10 +2453,10 @@ static void Cmd_ForceKillRadius_f( gentity_t *ent)
|
|||
oPs->stats[STAT_WEAPONS] = ( 1 << WP_0 );
|
||||
oPs->stats[STAT_HOLDABLE_ITEM] = HI_NONE;
|
||||
oPs->stats[STAT_HEALTH] = OtherPlayer->health = 1;
|
||||
player_die(OtherPlayer,OtherPlayer,OtherPlayer,100000, MOD_FORCEDSUICIDE);
|
||||
G_Client_Die(OtherPlayer,OtherPlayer,OtherPlayer,100000, MOD_FORCEDSUICIDE);
|
||||
}else{
|
||||
oPs->stats[STAT_HEALTH] = OtherPlayer->health = 0;
|
||||
player_die(OtherPlayer,OtherPlayer,OtherPlayer,100000, MOD_FORCEDSUICIDE);
|
||||
G_Client_Die(OtherPlayer,OtherPlayer,OtherPlayer,100000, MOD_FORCEDSUICIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2465,10 +2473,10 @@ static void Cmd_ForceKillRadius_f( gentity_t *ent)
|
|||
ePs->stats[STAT_WEAPONS] = ( 1 << WP_0 );
|
||||
ePs->stats[STAT_HOLDABLE_ITEM] = HI_NONE;
|
||||
ePs->stats[STAT_HEALTH] = ent->health = 1;
|
||||
player_die(ent,ent,ent,100000, MOD_FORCEDSUICIDE);
|
||||
G_Client_Die(ent,ent,ent,100000, MOD_FORCEDSUICIDE);
|
||||
}else{
|
||||
ePs->stats[STAT_HEALTH] = ent->health = 0;
|
||||
player_die(ent,ent,ent,100000, MOD_FORCEDSUICIDE);
|
||||
G_Client_Die(ent,ent,ent,100000, MOD_FORCEDSUICIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3134,7 +3142,7 @@ static void Cmd_AdminLogin_f( gentity_t *ent)
|
|||
if(!arg[0] && ent->client->LoggedAsAdmin) {
|
||||
ent->client->LoggedAsAdmin = qfalse;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"You are now logged out.\n\"") );
|
||||
ClientUserinfoChanged( ent-g_entities );
|
||||
G_Client_UserinfoChanged( ent-g_entities );
|
||||
return;
|
||||
}
|
||||
else if ( !arg[0] ) { //if user added no args (ie wanted the parameters)
|
||||
|
@ -3152,7 +3160,7 @@ static void Cmd_AdminLogin_f( gentity_t *ent)
|
|||
if ( IsAdmin( ent ) == qfalse ) {
|
||||
ent->client->LoggedAsAdmin = qtrue;
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"You are logged in as an admin.\n\"") );
|
||||
ClientUserinfoChanged( ent-g_entities );
|
||||
G_Client_UserinfoChanged( ent-g_entities );
|
||||
return;
|
||||
} else {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"You are already logged in as an admin or in the admin class.\n\"") );
|
||||
|
@ -3245,7 +3253,7 @@ static void Cmd_Revive_f( gentity_t *ent)
|
|||
{
|
||||
if( (g_entities[i].client) && (g_entities[i].health == 1) && (g_entities[i].client->ps.pm_type == PM_DEAD))
|
||||
{
|
||||
ClientSpawn(&g_entities[i], 1, qtrue);
|
||||
G_Client_Spawn(&g_entities[i], 1, qtrue);
|
||||
|
||||
ps = &g_entities[i].client->ps;
|
||||
|
||||
|
@ -3281,7 +3289,7 @@ static void Cmd_Revive_f( gentity_t *ent)
|
|||
//Just me
|
||||
if( (ent && ent->client) && (ent->health <= 1) && (ent->client->ps.pm_type == PM_DEAD))
|
||||
{
|
||||
ClientSpawn(ent, 1, qtrue);
|
||||
G_Client_Spawn(ent, 1, qtrue);
|
||||
|
||||
ps = &ent->client->ps;
|
||||
|
||||
|
@ -3316,7 +3324,7 @@ static void Cmd_Revive_f( gentity_t *ent)
|
|||
|
||||
if( (other && other->client) && (other->health == 1) && (other->client->ps.pm_type == PM_DEAD))
|
||||
{
|
||||
ClientSpawn(other, 1, qtrue);
|
||||
G_Client_Spawn(other, 1, qtrue);
|
||||
|
||||
ps = &other->client->ps;
|
||||
|
||||
|
@ -5561,7 +5569,7 @@ static void Cmd_Respawn_f(gentity_t *ent) {
|
|||
if(!ent->client)
|
||||
return;
|
||||
|
||||
ClientSpawn(ent, 0, qfalse);
|
||||
G_Client_Spawn(ent, 0, qfalse);
|
||||
if(ent->client->sess.sessionTeam != TEAM_SPECTATOR) {
|
||||
ent->client->ps.powerups[PW_QUAD] = level.time + 4000;
|
||||
tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TRANSPORT_IN );
|
||||
|
@ -5899,85 +5907,6 @@ static void Cmd_selfdestruct_f(gentity_t *ent) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Cmd_selfdestructcountdown_f
|
||||
Harry Young | 06/11/2012
|
||||
like selfdestruct but forced to think every .1 sec
|
||||
does output via quiet cp
|
||||
don't ask me what I was thinking ^^
|
||||
=================
|
||||
*/
|
||||
static void Cmd_selfdestructcountdown_f(gentity_t *ent) {
|
||||
gentity_t *destructEnt, *safezone=NULL;
|
||||
char arg[16], arg2[16], arg3[16];
|
||||
if(!ent || !ent->client)
|
||||
return;
|
||||
|
||||
//Trapping all potential args here.
|
||||
trap_Argv(1, arg, sizeof(arg));
|
||||
trap_Argv(2, arg2, sizeof(arg2));
|
||||
trap_Argv(3, arg3, sizeof(arg3));
|
||||
|
||||
#ifndef SQL
|
||||
if ( !IsAdmin( ent ) ) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"ERROR: You are not logged in as an admin.\n\" ") );
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if ( !IsAdmin( ent ) || !G_Sql_UserDB_CheckRight(ent->client->uid, SQLF_SMS ) ) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"ERROR: You are not logged in as a user with the appropiate rights.\n\" ") );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(trap_Argc() < 1) {
|
||||
G_PrintfClient(ent, "^3Usage: selfdestructcountdown duration [safezone] [target]");
|
||||
G_PrintfClient(ent, "^1WARNING: This makes the entity think every 0.1 seconds and forces a lot off traffic. You may want to use selfdestruct start.");
|
||||
G_PrintfClient(ent, "duration: total countdown-duration in seconds. Must not be 0.");
|
||||
G_PrintfClient(ent, "safezone: safezone to toggle unsafe at T-50ms. Only for maps with multiple ships (like rpg_runabout). Set NULL to skip.");
|
||||
G_PrintfClient(ent, "target: Optional Argument for Effects to fire once the countdown hist 0. The entity will automatically shake everyones screen and kill all clienst outside an active target_safezone.");
|
||||
G_PrintfClient(ent, "To abort call selfdestruct abort");
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup command-Execution
|
||||
|
||||
//Is there sth running alrerady?
|
||||
destructEnt = G_Find(NULL, FOFS(classname), "target_selfdestruct");
|
||||
if(destructEnt) {
|
||||
G_PrintfClient(ent, "^1ERROR: There's already a self destruct in progress, aborting setup.");
|
||||
return;
|
||||
}
|
||||
|
||||
//There is not so let's set this up.
|
||||
destructEnt = G_Spawn();
|
||||
destructEnt->classname = "target_selfdestruct";
|
||||
destructEnt->wait = atoi(arg);
|
||||
destructEnt->bluename = G_NewString(arg2);
|
||||
destructEnt->target = G_NewString(arg3);
|
||||
|
||||
destructEnt->spawnflags = 3; //tells ent to free once aborted and think extreme.
|
||||
|
||||
//we need to check a few things here to make sure the entity works properly. Else we free it.
|
||||
if ( destructEnt->wait > 0 || destructEnt->count > 0 || destructEnt->n00bCount > 0 || destructEnt->health > 0 ){
|
||||
G_CallSpawn(destructEnt); //Spawn-Function will also manage init, so we need to call that.
|
||||
} else { //sth's wrong so lets tell them what is.
|
||||
G_PrintfClient(ent, "^1ERROR: The following arguments are missing:");
|
||||
if ( destructEnt->wait == 0 )
|
||||
G_PrintfClient(ent, "^1-duration must not be 0.");
|
||||
while((safezone = G_Find(safezone, FOFS(classname), "target_safezone")) != NULL){
|
||||
if(!destructEnt->bluename && safezone->spawnflags & 2){
|
||||
G_PrintfClient(ent, "^1-safezone must be given for maps consisting of multiple ships/stations (like rpg_runabout). For a list of safezonesuse the safezonelist command.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
G_PrintfClient(ent, "^1Removing entity.");
|
||||
G_FreeEntity(destructEnt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Cmd_shipdamage_f
|
||||
|
@ -6313,7 +6242,11 @@ static void Cmd_getOrigin_f(gentity_t *ent) {
|
|||
if( i > MAX_GENTITIES - 1)
|
||||
return;
|
||||
|
||||
G_PrintfClient(ent, "s.origin = %s, r.currentOrigin = %s, pos1 = %s, pos2 = %s\n\"", vtos(g_entities[i].s.origin), vtos(g_entities[i].r.currentOrigin), vtos(g_entities[i].pos1), vtos(g_entities[i].pos2));
|
||||
G_PrintfClient(ent, "ent->s.origin = %s", vtos(g_entities[i].s.origin));
|
||||
G_PrintfClient(ent, "ent->r.currentOrigin = %s", vtos(g_entities[i].r.currentOrigin));
|
||||
G_PrintfClient(ent, "ent->pos1 = %s", vtos(g_entities[i].pos1));
|
||||
G_PrintfClient(ent, "ent->pos2 = %s", vtos(g_entities[i].pos2));
|
||||
G_PrintfClient(ent, "ent->s.pos.trBase = %s", vtos(g_entities[i].s.pos.trBase));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -7123,18 +7056,6 @@ static void Cmd_UiTransporterLoc_f(gentity_t *ent) {
|
|||
gentity_t *trTrigger;
|
||||
char arg[MAX_QPATH];
|
||||
|
||||
#ifndef SQL
|
||||
if ( !IsAdmin( ent ) ) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"ERROR: You are not logged in as an admin.\n\" ") );
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if ( !IsAdmin( ent ) || !G_Sql_UserDB_CheckRight(ent->client->uid, SQLF_UITRANS ) ) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"ERROR: You are not logged in as a user with the appropiate rights.\n\" ") );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(trap_Argc() < 2) return;
|
||||
|
||||
trap_Argv(1, arg, sizeof(arg));
|
||||
|
@ -7162,10 +7083,17 @@ static void Cmd_UiTransporterLoc_f(gentity_t *ent) {
|
|||
|
||||
if(locTarget) {
|
||||
if(locTarget->sound1to2) {
|
||||
if(!IsAdmin(ent)) {
|
||||
#ifndef SQL
|
||||
if ( !IsAdmin( ent ) ) {
|
||||
G_PrintfClient(ent, "Destination is a restricted location.\n");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if ( !IsAdmin( ent ) || !G_Sql_UserDB_CheckRight(ent->client->uid, SQLF_BEAM) ) {
|
||||
G_PrintfClient(ent, "Destination is a restricted location.\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
trTrigger->target_ent = locTarget;
|
||||
trTrigger->count = 0;
|
||||
|
@ -7195,18 +7123,6 @@ static void Cmd_UiTransporterExt_f(gentity_t *ent) {
|
|||
gentity_t *trTrigger;
|
||||
char arg[MAX_QPATH];
|
||||
|
||||
#ifndef SQL
|
||||
if ( !IsAdmin( ent ) ) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"ERROR: You are not logged in as an admin.\n\" ") );
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if ( !IsAdmin( ent ) || !G_Sql_UserDB_CheckRight(ent->client->uid, SQLF_UITRANS ) ) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"ERROR: You are not logged in as a user with the appropiate rights.\n\" ") );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!rpg_serverchange.integer) {
|
||||
trap_SendServerCommand(ent-g_entities, "print \"Serverchange is disabled.\n\"");
|
||||
return;
|
||||
|
@ -7444,16 +7360,17 @@ static void Cmd_Camtest_f(gentity_t *ent) {
|
|||
}
|
||||
|
||||
void Cmd_CamtestEnd_f(gentity_t *ent) {
|
||||
Cinematic_DeactivateCameraMode(ent);
|
||||
//Cinematic_DeactivateCameraMode(ent);
|
||||
G_LuaNumThreads();
|
||||
}
|
||||
// END CCAM
|
||||
|
||||
/*
|
||||
=================
|
||||
ClientCommand
|
||||
G_Client_Command
|
||||
=================
|
||||
*/
|
||||
void ClientCommand( int clientNum )
|
||||
void G_Client_Command( int clientNum )
|
||||
{
|
||||
gentity_t *ent;
|
||||
char cmd[MAX_TOKEN_CHARS];
|
||||
|
@ -7648,8 +7565,6 @@ void ClientCommand( int clientNum )
|
|||
Cmd_safezonelist_f(ent);
|
||||
else if (Q_stricmp(cmd, "selfdestruct") == 0)
|
||||
Cmd_selfdestruct_f(ent);
|
||||
else if (Q_stricmp(cmd, "selfdestructcountdown") == 0)
|
||||
Cmd_selfdestructcountdown_f(ent);
|
||||
else if (Q_stricmp(cmd, "shipdamage") == 0)
|
||||
Cmd_shipdamage_f(ent);
|
||||
else if (Q_stricmp(cmd, "shiphealth") == 0)
|
||||
|
|
|
@ -11,12 +11,12 @@ extern void SetClass( gentity_t *ent, char *s, char *teamName, qboolean SaveToCv
|
|||
|
||||
/*
|
||||
============
|
||||
AddScore
|
||||
G_Client_AddScore
|
||||
|
||||
Adds score to both the client and his team
|
||||
============
|
||||
*/
|
||||
void AddScore( gentity_t *ent, int score ) {
|
||||
void G_Client_AddScore( gentity_t *ent, int score ) {
|
||||
if ( !ent )
|
||||
{
|
||||
return;
|
||||
|
@ -36,7 +36,7 @@ void AddScore( gentity_t *ent, int score ) {
|
|||
{//this isn't capture score
|
||||
level.teamScores[ ent->client->ps.persistant[PERS_TEAM] ] += score;
|
||||
}
|
||||
CalculateRanks( qfalse );
|
||||
G_Client_CalculateRanks( qfalse );
|
||||
|
||||
//RPG-X: RedTechie - Lets enable score updating without this scores will not be updated
|
||||
ent->client->UpdateScore = qfalse;
|
||||
|
@ -64,7 +64,7 @@ void SetScore( gentity_t *ent, int score ) {
|
|||
}
|
||||
|
||||
ent->client->ps.persistant[PERS_SCORE] = score;
|
||||
CalculateRanks( qfalse );
|
||||
G_Client_CalculateRanks( qfalse );
|
||||
|
||||
// TiM: send the current scoring to all clients
|
||||
SendScoreboardMessageToAllClients();
|
||||
|
@ -251,14 +251,14 @@ extern void DetonateDetpack(gentity_t *ent);
|
|||
|
||||
/*
|
||||
==================
|
||||
player_die
|
||||
G_Client_Die
|
||||
Heavly Modifyed By: RedTechie
|
||||
RPG-X: Marcin: a little bit modified - 30/12/2008
|
||||
==================
|
||||
*/
|
||||
extern char *ClassNameForValue( pclass_t pClass );
|
||||
extern qboolean IsAdmin( gentity_t *ent);
|
||||
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
|
||||
void G_Client_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
|
||||
//---------------------
|
||||
//RPG-X: RedTechie - Check to see if medics revive people and not respawn if true use my fake death insead :)
|
||||
//---------------------
|
||||
|
@ -479,11 +479,11 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
|||
|
||||
BG_PlayerStateToEntityState( &self->client->ps, &self->s, qtrue );
|
||||
|
||||
ClientUserinfoChanged( self->s.clientNum );
|
||||
G_Client_UserinfoChanged( self->s.clientNum );
|
||||
|
||||
ClientEndFrame( self );
|
||||
|
||||
G_StoreClientInitialStatus( self );
|
||||
G_Client_StoreClientInitialStatus( self );
|
||||
//---------------------
|
||||
//RPG-X: RedTechie - If it dose equal 0 use regular die
|
||||
//---------------------
|
||||
|
@ -601,17 +601,17 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
if (attacker && attacker->client)
|
||||
{
|
||||
if ( attacker == self || OnSameTeam (self, attacker ) )
|
||||
if ( attacker == self )
|
||||
{
|
||||
if ( meansOfDeath != MOD_RESPAWN )
|
||||
{//just changing class
|
||||
AddScore( attacker, -1 );
|
||||
G_Client_AddScore( attacker, -1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attacker->client->pers.teamState.frags++;
|
||||
AddScore( attacker, 1 );
|
||||
G_Client_AddScore( attacker, 1 );
|
||||
|
||||
// Check to see if the player is on a streak.
|
||||
attacker->client->streakCount++;
|
||||
|
@ -623,7 +623,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
|||
{
|
||||
if ( meansOfDeath != MOD_RESPAWN )
|
||||
{//not just changing class
|
||||
AddScore( self, -1 );
|
||||
G_Client_AddScore( self, -1 );
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1079,7 +1079,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
gclient_t *client;
|
||||
int take=0;
|
||||
int knockback;
|
||||
qboolean bFriend = (targ && attacker) ? OnSameTeam( targ, attacker ) : qfalse;
|
||||
qboolean bFriend = qfalse;
|
||||
|
||||
if(!targ) return;
|
||||
|
||||
|
@ -1176,7 +1176,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
if ( knockback && targ->client )
|
||||
{
|
||||
//if it's non-radius damage knockback from a teammate, don't do it if the damage won't be taken
|
||||
if ( (dflags&DAMAGE_ALL_TEAMS) || (dflags&DAMAGE_RADIUS) || g_friendlyFire.integer || !attacker->client || !OnSameTeam (targ, attacker) )
|
||||
if ( (dflags&DAMAGE_ALL_TEAMS) || (dflags&DAMAGE_RADIUS) || g_friendlyFire.integer || !attacker->client )
|
||||
{
|
||||
vec3_t kvel;
|
||||
float mass;
|
||||
|
@ -1215,7 +1215,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
// if the attacker was on the same team
|
||||
// check for completely getting out of the damage
|
||||
if ( !(dflags & DAMAGE_NO_PROTECTION) ) {
|
||||
if ( !(dflags&DAMAGE_ALL_TEAMS) && mod != MOD_TELEFRAG && mod != MOD_DETPACK && targ != attacker && OnSameTeam (targ, attacker) )
|
||||
if ( !(dflags&DAMAGE_ALL_TEAMS) && mod != MOD_TELEFRAG && mod != MOD_DETPACK && targ != attacker )
|
||||
{
|
||||
if ( attacker->client && targ->client )
|
||||
{//this only matters between clients
|
||||
|
@ -1294,9 +1294,6 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
}
|
||||
}
|
||||
|
||||
// See if it's the player hurting the emeny flag carrier
|
||||
Team_CheckHurtCarrier(targ, attacker);
|
||||
|
||||
if (targ->client) {
|
||||
// set the last client who damaged the target
|
||||
targ->client->lasthurt_client = attacker->s.number;
|
||||
|
@ -1352,7 +1349,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
client->ps.stats[STAT_WEAPONS] = ( 1 << WP_0 ); //?!!!!!
|
||||
client->ps.stats[STAT_HOLDABLE_ITEM] = HI_NONE;
|
||||
targ->health = 1;
|
||||
player_die( targ, inflictor, attacker, take, mod );
|
||||
G_Client_Die( targ, inflictor, attacker, take, mod );
|
||||
}
|
||||
}else{
|
||||
if ( targ->health <= 0 ) {
|
||||
|
@ -1515,7 +1512,7 @@ qboolean G_RadiusDamage ( vec3_t origin, gentity_t *attacker, float damage, floa
|
|||
}
|
||||
}
|
||||
|
||||
if( LogAccuracyHit( ent, attacker ) ) {
|
||||
if( G_Weapon_LogAccuracyHit( ent, attacker ) ) {
|
||||
hitClient = qtrue;
|
||||
}
|
||||
VectorSubtract (ent->r.currentOrigin, origin, dir);
|
||||
|
@ -1576,13 +1573,18 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
|||
}
|
||||
|
||||
// check if player is near the breakable
|
||||
VectorSubtract(tr_ent->s.origin, ent->r.currentOrigin, help);
|
||||
distance = VectorLength(help);
|
||||
for(i = 0; i < 3; i++) {
|
||||
if(tr_ent->r.maxs[i] > max) {
|
||||
max = tr_ent->r.maxs[i];
|
||||
if(tr_ent->spawnflags & 512) {
|
||||
VectorSubtract(tr_ent->s.angles2, ent->r.currentOrigin, help);
|
||||
max = tr_ent->n00bCount;
|
||||
} else {
|
||||
VectorSubtract(tr_ent->s.origin, ent->r.currentOrigin, help);
|
||||
for(i = 0; i < 3; i++) {
|
||||
if(tr_ent->r.maxs[i] > max) {
|
||||
max = tr_ent->r.maxs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
distance = VectorLength(help);
|
||||
|
||||
//G_Printf("goodDst=%f, curDst=%f\n", 80 + max, distance);
|
||||
if(distance > 80 + max) {
|
||||
|
@ -1591,7 +1593,6 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate) {
|
|||
|
||||
// check if the player is facing it
|
||||
AngleVectors(ent->client->ps.viewangles, forward, NULL, NULL);
|
||||
VectorSubtract(tr_ent->s.origin, ent->client->ps.origin, help);
|
||||
if(DotProduct(help, forward) < 0.4) {
|
||||
return;
|
||||
}
|
||||
|
|
357
game/g_fx.c
357
game/g_fx.c
|
@ -5,17 +5,29 @@
|
|||
#define SPARK_STARTOFF 1
|
||||
|
||||
/*QUAKED fx_spark (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
Emits sparks at the specified point in the specified direction
|
||||
-----DESCRIPTION-----
|
||||
Emits sparks at the specified point in the specified direction.
|
||||
|
||||
"target" - ( optional ) direction to aim the sparks in, otherwise, uses the angles set in the editor.
|
||||
"wait(2000)" - interval between events (randomly twice as long)
|
||||
Can be toggled by being used, but use with caution as updates every second instead of every 10 seconds,
|
||||
which means it sends 10 times the information that an untoggleable steam will send.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect will be off at spawn.
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - toggles on/off whenever used
|
||||
"target" - ( optional ) direction to aim the sparks in, otherwise, uses the angles set in the editor.
|
||||
"wait" - interval between events, default 2000 ms (randomly twice as long)
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
void spark_think( gentity_t *ent )
|
||||
{
|
||||
G_AddEvent( ent, EV_FX_SPARK, 0 );
|
||||
ent->nextthink = level.time + 10000.0; // send a refresh message every 10 seconds
|
||||
if(ent->targetname) //toggleable effect needs to be updated more often
|
||||
ent->nextthink = level.time + 1000;
|
||||
else
|
||||
ent->nextthink = level.time + 10000.0; // send a refresh message every 10 seconds
|
||||
}
|
||||
|
||||
//T3h TiM-zor was here
|
||||
|
@ -104,13 +116,16 @@ void SP_fx_spark( gentity_t *ent )
|
|||
|
||||
|
||||
/*QUAKED fx_steam (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
Emits steam at the specified point in the specified direction. will point at a target if one is specified.
|
||||
-----DESCRIPTION-----
|
||||
Emits steam at the specified point in the specified direction. Will point at a target if one is specified.
|
||||
|
||||
Use toggleable steam with caution as updates every second instead of every 10 seconds,
|
||||
Can be toggled but use with caution as updates every second instead of every 10 seconds,
|
||||
which means it sends 10 times the information that an untoggleable steam will send.
|
||||
|
||||
STARTOFF steam is of at spawn
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - steam is of at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - toggles on/off whenever used
|
||||
"damage" - damage to apply when caught in steam vent, default - zero damage (no damage). Don't add this unless you really have to.
|
||||
*/
|
||||
|
@ -123,11 +138,11 @@ STARTOFF steam is of at spawn
|
|||
void steam_think( gentity_t *ent )
|
||||
{
|
||||
G_AddEvent( ent, EV_FX_STEAM, 0 );
|
||||
if(ent->targetname) { //toggleable steam needs to be updated more often
|
||||
if(ent->targetname) //toggleable effect needs to be updated more often
|
||||
ent->nextthink = level.time + 1000;
|
||||
} else {
|
||||
else
|
||||
ent->nextthink = level.time + 10000.0; // send a refresh message every 10 seconds
|
||||
}
|
||||
|
||||
|
||||
// FIXME: This may be a bit weird for steam bursts*/
|
||||
// If a fool gets in the bolt path, zap 'em
|
||||
|
@ -247,14 +262,23 @@ void SP_fx_steam( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_bolt (0 0 1) (-8 -8 -8) (8 8 8) SPARKS BORG TAPER SMOOTH
|
||||
-----DESCRIPTION-----
|
||||
Emits blue ( or borg green ) electric bolts from the specified point to the specified point
|
||||
|
||||
SPARKS - create impact sparks, probably best used for time delayed bolts
|
||||
BORG - Make the bolts green
|
||||
Can be toggled by being used, but use with caution as updates every second instead of every 10 seconds,
|
||||
which means it sends 10 times the information that an untoggleable steam will send.
|
||||
|
||||
"wait" - seconds between bolts (0 is always on, default is 2.0, -1 for random number between 0 and 5), bolts are always on for 0.2 seconds
|
||||
"damage" - damage per server frame (default 0)
|
||||
"random" - bolt chaos (0.1 = too calm, 0.5 = default, 1.0 or higher = pretty wicked)
|
||||
-----SPAWNFLAGS-----
|
||||
1: SPARKS - create impact sparks, probably best used for time delayed bolts
|
||||
2: BORG - Make the bolts green
|
||||
4: TAPER
|
||||
8: SMOOTH
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - toggles on/off whenever used
|
||||
"wait" - seconds between bolts (0 is always on, default is 2.0, -1 for random number between 0 and 5), bolts are always on for 0.2 seconds
|
||||
"damage" - damage per server frame (default 0)
|
||||
"random" - bolt chaos (0.1 = too calm, 0.5 = default, 1.0 or higher = pretty wicked)
|
||||
*/
|
||||
|
||||
|
||||
|
@ -269,7 +293,11 @@ void bolt_think( gentity_t *ent )
|
|||
|
||||
G_AddEvent( ent, EV_FX_BOLT, ent->spawnflags );
|
||||
ent->s.time2 = ent->wait;
|
||||
ent->nextthink = level.time + 10000;
|
||||
if(ent->targetname) //toggleable effect needs to be updated more often
|
||||
ent->nextthink = level.time + 1000;
|
||||
else
|
||||
ent->nextthink = level.time + 10000.0; // send a refresh message every 10 seconds
|
||||
|
||||
|
||||
// If a fool gets in the bolt path, zap 'em
|
||||
if ( ent->damage )
|
||||
|
@ -382,8 +410,15 @@ void SP_fx_bolt( gentity_t *ent )
|
|||
|
||||
//--------------------------------------------------
|
||||
/*QUAKED fx_transporter (0 0 1) (-8 -8 -8) (8 8 8)
|
||||
-----DESCRIPTION-----
|
||||
Emits transporter pad effect at the specified point. just rest it flush on top of the pad.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
none
|
||||
|
||||
*/
|
||||
|
||||
void transporter_link( gentity_t *ent )
|
||||
|
@ -406,9 +441,19 @@ void SP_fx_transporter(gentity_t *ent)
|
|||
|
||||
|
||||
/*QUAKED fx_drip (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
Drips of a fluid that fall down from this point.
|
||||
|
||||
"damage" -- type of drips. 0 = water, 1 = oil, 2 = green
|
||||
"random" -- (0...1) degree of drippiness. 0 = one drip, 1 = Niagara Falls
|
||||
Can be toggled by being used, but use with caution as updates every second instead of every 10 seconds,
|
||||
which means it sends 10 times the information that an untoggleable steam will send.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - effect is off at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - toggles on/off whenever used
|
||||
"damage" - type of drips. 0 = water, 1 = oil, 2 = green
|
||||
"random" - (0...1) degree of drippiness. 0 = one drip, 1 = Niagara Falls
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -442,11 +487,18 @@ void SP_fx_drip( gentity_t *ent )
|
|||
//***********************************************************************************
|
||||
|
||||
/*QUAKED fx_fountain (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
Fountain-Effect as seen iin the Garden of Scilence holodeck Programm.
|
||||
This is just one single strain of the original effect (which had all four strains hardcoded)
|
||||
|
||||
STARTOFF - Effect spawns in an off state
|
||||
Use with caution as this refreshes 10 times a second.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect spawns in an off state
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - name of entity when used turns this ent on/off
|
||||
"target" - link to a notnull entity to position where the end point of this FX is
|
||||
"target" - link to an info_notnull entity or similar to position where the end point of this FX is
|
||||
*/
|
||||
|
||||
void fountain_think( gentity_t *ent )
|
||||
|
@ -510,16 +562,20 @@ void SP_fx_fountain ( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
/*QUAKED fx_surface_explosion (0 0 1) (-8 -8 -8) (8 8 8) NO_SMOKE LOUDER NODAMAGE
|
||||
-----DESCRIPTION-----
|
||||
Creates a triggerable explosion aimed at a specific point. Always oriented towards viewer.
|
||||
|
||||
LOUDER - Cheap hack to make the explosion sound louder.
|
||||
NODAMAGE - Does no damage
|
||||
-----SPAWNFLAGS-----
|
||||
1: NO_SMOKE - Does not create smoke after explosion
|
||||
2: LOUDER - Cheap hack to make the explosion sound louder.
|
||||
4: NODAMAGE - Does no damage
|
||||
|
||||
"target" (optional) If no target is specified, the explosion is oriented up
|
||||
"damage" - Damage per blast, default is 50. Damage falls off based on proximity.
|
||||
"radius" - blast radius (default 20)
|
||||
"speed" - camera shake speed (default 12). Set to zero to turn camera shakes off
|
||||
"targetname" - triggers explosion when used
|
||||
-----KEYS-----
|
||||
"target" (optional) If no target is specified, the explosion is oriented up
|
||||
"damage" - Damage per blast, default is 50. Damage falls off based on proximity.
|
||||
"radius" - blast radius (default 20)
|
||||
"speed" - camera shake speed (default 12). Set to zero to turn camera shakes off
|
||||
"targetname" - triggers explosion when used
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -528,9 +584,7 @@ void surface_explosion_use( gentity_t *self, gentity_t *other, gentity_t *activa
|
|||
|
||||
G_AddEvent( self, EV_FX_SURFACE_EXPLOSION, 0 );
|
||||
if ( self->splashDamage )
|
||||
{
|
||||
G_RadiusDamage( self->r.currentOrigin, self, self->splashDamage, self->splashRadius, self, DAMAGE_RADIUS|DAMAGE_ALL_TEAMS, MOD_EXPLOSION );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -563,8 +617,7 @@ void surface_explosion_link( gentity_t *ent )
|
|||
//------------------------------------------
|
||||
void SP_fx_surface_explosion( gentity_t *ent )
|
||||
{
|
||||
if ( !(ent->spawnflags&4) )
|
||||
{
|
||||
if ( !(ent->spawnflags&4) ){
|
||||
G_SpawnInt( "damage", "50", &ent->splashDamage );
|
||||
G_SpawnFloat( "radius", "20", &ent->distance ); // was: ent->radius
|
||||
ent->splashRadius = 160;
|
||||
|
@ -589,21 +642,23 @@ void SP_fx_surface_explosion( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_blow_chunks (0 0 1) (-8 -8 -8) (8 8 8)
|
||||
-----DESCRIPTION-----
|
||||
Creates a triggerable chunk spewer that can be aimed at a specific point.
|
||||
|
||||
"target" - (required) Target to spew chunks at
|
||||
"targetname" - triggers chunks when used
|
||||
"radius" - Average size of a chunk (default 65)
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - (required) Target to spew chunks at
|
||||
"targetname" - triggers chunks when used
|
||||
"radius" - Average size of a chunk (default 65)
|
||||
|
||||
"material" - default is "metal" - choose from this list:
|
||||
None = 0,
|
||||
Metal = 1
|
||||
Glass = 2
|
||||
Glass Metal = 3
|
||||
Wood = 4
|
||||
Stone = 5
|
||||
(there will be more eventually lol.. I hope)
|
||||
|
||||
*/
|
||||
|
||||
//"count" - Number of chunks to spew (default 5)
|
||||
|
@ -658,12 +713,16 @@ void SP_fx_blow_chunks( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_smoke (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
Emits cloud of thick black smoke from specified point.
|
||||
|
||||
"target" (option) If no target is specified, the smoke drifts up
|
||||
"targetname" - fires only when used
|
||||
"radius" - size of the smoke puffs (default 16.0)
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect will be off at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"target" - optional, if no target is specified, the smoke drifts up
|
||||
"targetname" - fires only when used
|
||||
"radius" - size of the smoke puffs (default 16.0)
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -754,14 +813,17 @@ void SP_fx_smoke( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_electrical_explosion (0 0 1) (-8 -8 -8) (8 8 8) x x NODAMAGE
|
||||
-----DESCRIPTION-----
|
||||
Creates a triggerable explosion aimed at a specific point
|
||||
NODAMAGE - does no damage
|
||||
|
||||
"target" (optional) If no target is specified, the explosion is oriented up
|
||||
"damage" - Damage per blast, default is 20. Damage falls off based on proximity.
|
||||
"radius" - blast radius (default 50)
|
||||
"targetname" - explodes each time it's used
|
||||
-----SPAWNFLAGS-----
|
||||
1: NODAMAGE - does no damage
|
||||
|
||||
-----KEYS-----
|
||||
"target" - optional, if no target is specified, the explosion is oriented up
|
||||
"damage" - Damage per blast, default is 20. Damage falls off based on proximity.
|
||||
"radius" - blast radius (default 50)
|
||||
"targetname" - explodes each time it's used
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -823,14 +885,20 @@ void SP_fx_electrical_explosion( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_phaser (0 0 1) (-8 -8 -8) (8 8 8) NO_SOUND DISRUPTOR
|
||||
A phaser effect.
|
||||
-----DESCRIPTION-----
|
||||
A phaser effect for use as a ship's weapon.
|
||||
|
||||
"target" endpoint
|
||||
"wait" how long the phaser fires
|
||||
"scale" adjust the effects scale, default: 20
|
||||
"customSnd" use a custom sound
|
||||
"delay" delay the effect, but not the sound. Can be used to adhust the timing between effect and customSnd
|
||||
"impact" set to 1 if you want an impact to be drawn
|
||||
-----SPAWNFLAGS-----
|
||||
1: NO_SOUND - will not play it's sound
|
||||
2: DISRUPTOR - will display a green disruptor beam
|
||||
|
||||
-----KEYS-----
|
||||
"target" - endpoint
|
||||
"wait" - how long the phaser fires
|
||||
"scale" - adjust the effects scale, default: 20
|
||||
"customSnd" - use a custom sound
|
||||
"delay" - delay the effect, but not the sound. Can be used to adjust the timing between effect and customSnd
|
||||
"impact" - set to 1 if you want an impact to be drawn
|
||||
*/
|
||||
#define PHASER_FX_UNLINKED 999
|
||||
|
||||
|
@ -893,16 +961,20 @@ void SP_fx_phaser(gentity_t *ent) {
|
|||
}
|
||||
|
||||
/*QUAKED fx_torpedo (0 0 1) (-8 -8 -8) (8 8 8) QUANTUM NO_SOUND
|
||||
A torpedo effect.
|
||||
-----DESCRIPTION-----
|
||||
A torpedo effect for use as a ship's weapon.
|
||||
|
||||
QUANTUM set this flag if you whant an quantum fx instead of an photon fx
|
||||
-----SPAWNFLAGS-----
|
||||
1: QUANTUM - set this flag if you whant an quantum fx instead of an photon fx
|
||||
2: NO_SOUND - Will not play it's sound
|
||||
|
||||
"target" used for the calculation of the direction
|
||||
"wait" time in seconds till fx can be used again
|
||||
"noise" sound to play
|
||||
"soundNoAmmo" sound to play if ammo is depleted
|
||||
"count" ammount of torpedos that can be fired (defaults to -1 = infinite)
|
||||
"speed" a speed modifier (default: 2.5)
|
||||
-----KEYS-----
|
||||
"target" - used for the calculation of the direction
|
||||
"wait" - time in seconds till fx can be used again
|
||||
"noise" - sound to play
|
||||
"soundNoAmmo" - sound to play if ammo is depleted
|
||||
"count" - ammount of torpedos that can be fired (defaults to -1 = infinite)
|
||||
"speed" - a speed modifier (default: 2.5)
|
||||
*/
|
||||
void fx_torpedo_use(gentity_t* ent, gentity_t*other, gentity_t *activator);
|
||||
|
||||
|
@ -978,11 +1050,16 @@ void SP_fx_torpedo(gentity_t *ent) {
|
|||
}
|
||||
|
||||
/*QUAKED fx_particle_fire (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
A particle based fire effect. Use this sparingly as it is an fps killer.
|
||||
If you want to use a bunch of fires use fx_fire.
|
||||
|
||||
"targetname" - toggles effect on/off whenver used, requires 10x mor thinks
|
||||
"size" how big the fire shoud be (default: 10)
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect will be off at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - toggles effect on/off whenver used, requires 10x more thinks
|
||||
"size" - how big the fire shoud be (default: 10)
|
||||
*/
|
||||
void particleFire_think(gentity_t *ent) {
|
||||
G_AddEvent(ent, EV_FX_PARTICLEFIRE, ent->count);
|
||||
|
@ -1045,11 +1122,16 @@ void SP_fx_particleFire(gentity_t *ent) {
|
|||
}
|
||||
|
||||
/*QUAKED fx_fire (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
A fire affect based on the adminguns fire effect.
|
||||
|
||||
"targetname" - toggles effect on/off whenver used, requires 10x mor thinks
|
||||
"size" how big the fire shoud be (default: 64)
|
||||
"angles" fires angles (default: 0 0 0 = UP)
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect will be off at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - toggles effect on/off whenver used, requires 10x more thinks
|
||||
"size" - how big the fire shoud be (default: 64)
|
||||
"angles" - fires angles (default: 0 0 0 = UP)
|
||||
*/
|
||||
void fire_think(gentity_t *ent) {
|
||||
G_AddEvent(ent, EV_FX_FIRE, 1);
|
||||
|
@ -1114,10 +1196,15 @@ void SP_fx_fire(gentity_t *ent) {
|
|||
// Additional ports from SP by Harry Young
|
||||
|
||||
/*QUAKED fx_cooking_steam (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
Emits slowly moving steam puffs that rise up from the specified point
|
||||
|
||||
"targetname" - toggles effect on/off whenver used
|
||||
"distance" - smoke puff size ( default 3.0 )
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect will be off at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - toggles effect on/off whenver used
|
||||
"distance" - smoke puff size ( default 3.0 )
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1175,10 +1262,15 @@ void SP_fx_cooking_steam( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_elecfire (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
Emits sparks at the specified point in the specified direction
|
||||
Spawns smoke puffs.
|
||||
|
||||
"targetname" - toggles effect on/off whenver used
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect will be off at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - toggles effect on/off whenver used
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1240,20 +1332,24 @@ void SP_fx_electricfire( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_forge_bolt (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF DELAYED SPARKS PULSE TAPER SMOOTH
|
||||
-----DESCRIPTION-----
|
||||
CURRENTLY DISABLED
|
||||
Emits freaky orange bolts, sending pulses down the length of the beam if desired
|
||||
|
||||
STARTOFF - effect is initially off
|
||||
DELAYED - bolts are time delayed, otherwise effect continuously fires
|
||||
SPARKS - create impact sparks, probably best used for time delayed bolts
|
||||
PULSE - sends a pulse down the length of the beam.
|
||||
TAPER - Bolt will taper on one end
|
||||
SMOOTH - Bolt texture stretches across whole length, makes short bolts look much better.
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - effect is initially off
|
||||
2: DELAYED - bolts are time delayed, otherwise effect continuously fires
|
||||
4: SPARKS - create impact sparks, probably best used for time delayed bolts
|
||||
8: PULSE - sends a pulse down the length of the beam.
|
||||
16: TAPER - Bolt will taper on one end
|
||||
32: SMOOTH - Bolt texture stretches across whole length, makes short bolts look much better.
|
||||
|
||||
"wait" - seconds between bolts, only valid when DELAYED is checked (default 2)
|
||||
"damage" - damage per server frame (default 0)
|
||||
"targetname" - toggles effect on/off each time it's used
|
||||
"random" - bolt chaos (0.1 = too calm, 0.4 = default, 1.0 or higher = pretty wicked)
|
||||
"radius" - radius of the bolt (3.0 = default)
|
||||
-----KEYS-----
|
||||
"wait" - seconds between bolts, only valid when DELAYED is checked (default 2)
|
||||
"damage" - damage per server frame (default 0)
|
||||
"targetname" - toggles effect on/off each time it's used
|
||||
"random" - bolt chaos (0.1 = too calm, 0.4 = default, 1.0 or higher = pretty wicked)
|
||||
"radius" - radius of the bolt (3.0 = default)
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1382,17 +1478,22 @@ void SP_fx_forge_bolt( gentity_t *ent )
|
|||
trap_LinkEntity( ent );
|
||||
}
|
||||
|
||||
/*QUAKED fx_plasma (0 0 1) (-8 -8 -8) (8 8 8) START_OFF
|
||||
/*QUAKED fx_plasma (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
CURRENTLY DISABLED
|
||||
Emits plasma jet directed from the specified point to the specified point. Jet size scales based on length.
|
||||
|
||||
"target" (required)
|
||||
"targetname" - fires only when used
|
||||
"startRGBA" - starting cone color, Red Green Blue Alpha
|
||||
(default 100 180 255 255) Light-Blue
|
||||
"finalRGBA" - final cone color, Red Green Blue Alpha
|
||||
(default 0 0 180 0) Blue
|
||||
"damage" - damage PER FRAME, default zero
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect will be off at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"target" - (required) Direction of jet
|
||||
"targetname" - fires only when used
|
||||
"startRGBA" - starting cone color, Red Green Blue Alpha
|
||||
(default 100 180 255 255) Light-Blue
|
||||
"finalRGBA" - final cone color, Red Green Blue Alpha
|
||||
(default 0 0 180 0) Blue
|
||||
"damage" - damage PER FRAME, default zero
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1521,11 +1622,17 @@ void SP_fx_plasma( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_energy_stream (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
CURRENTLY DISABLED
|
||||
Creates streaming particles that travel between two points--for Stasis level. ONLY orients vertically.
|
||||
|
||||
"damage" - amount of damage to player when standing in the stream (default 0)
|
||||
"target" (required) End point for particle stream.
|
||||
"targetname" - toggle effect on/off each time used.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect will be off at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"damage" - amount of damage to player when standing in the stream (default 0)
|
||||
"target" - (required) End point for particle stream.
|
||||
"targetname" - toggle effect on/off each time used.
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1629,11 +1736,16 @@ void SP_fx_stream( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_transporter_stream (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF
|
||||
-----DESCRIPTION-----
|
||||
CURRENTLY DISABLED
|
||||
Creates streaming particles that travel between two points--for forge level.
|
||||
|
||||
"target" (required) End point for particle stream.
|
||||
"targetname" - fires only when used
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect will be off at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"target" - (required) End point for particle stream.
|
||||
"targetname" - fires only when used
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1713,12 +1825,18 @@ void SP_fx_transporter_stream( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_explosion_trail (0 0 1) (-8 -8 -8) (8 8 8)
|
||||
-----DESCRIPTION-----
|
||||
CURRENTLY DISABLED
|
||||
Creates a triggerable explosion aimed at a specific point. Always oriented towards viewer.
|
||||
|
||||
"target" (required) - end point for the explosion
|
||||
"damage" - Damage per blast, default is 150. Damage falls off based on proximity.
|
||||
"radius" - blast radius/explosion size (default 80)
|
||||
"targetname" - triggers explosion when used
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - (required) end point for the explosion
|
||||
"damage" - Damage per blast, default is 150. Damage falls off based on proximity.
|
||||
"radius" - blast radius/explosion size (default 80)
|
||||
"targetname" - triggers explosion when used
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1767,17 +1885,20 @@ void SP_fx_explosion_trail( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_borg_energy_beam (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF CONE
|
||||
-----DESCRIPTION-----
|
||||
CURRENTLY DISABLED
|
||||
A borg tracing beam that either carves out a cone or swings like a pendulum, sweeping across an area.
|
||||
|
||||
STARTOFF - The trace beam will start when used.
|
||||
CONE - Beam traces a cone, default trace shape is a pendulum, sweeping across an area.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - The trace beam will start when used.
|
||||
2: CONE - Beam traces a cone, default trace shape is a pendulum, sweeping across an area.
|
||||
|
||||
-----KEYS-----
|
||||
"radius" - Radius of the area to trace (default 30)
|
||||
"speed" - How fast the tracer beam moves (default 100)
|
||||
"startRGBA" - Effect color specified in RED GREEN BLUE ALPHA (default 0 255 0 128)
|
||||
"target" (required) End point for trace beam, should be placed at the very center of the trace area.
|
||||
"target" - (required) End point for trace beam, should be placed at the very center of the trace area.
|
||||
"targetname" - fires only when used
|
||||
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1874,16 +1995,18 @@ void SP_fx_borg_energy_beam( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_shimmery_thing (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF TAPER
|
||||
-----DESCRIPTION-----
|
||||
Creates a shimmering cone or cylinder of colored light that stretches between two points. Looks like a teleporter type thing.
|
||||
|
||||
STARTOFF - Effect turns on when used.
|
||||
TAPER - Cylinder tapers toward the top, creating a conical effect
|
||||
|
||||
"radius" - radius of the cylinder or of the base of the cone. (default 10)
|
||||
"target" (required) End point for stream.
|
||||
"targetname" - fires only when used
|
||||
"wait" - how long in ms to stay on before turning itself off ( default 2 seconds (200 ms), -1 to disable auto shut off )
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Effect turns on when used.
|
||||
2: TAPER - Cylinder tapers toward the top, creating a conical effect
|
||||
|
||||
-----KEYS-----
|
||||
"radius" - radius of the cylinder or of the base of the cone. (default 10)
|
||||
"target" - (required) End point for stream.
|
||||
"targetname" - fires only when used
|
||||
"wait" - how long in ms to stay on before turning itself off ( default 2 seconds (2000 ms), -1 to disable auto shut off )
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1974,16 +2097,20 @@ void SP_fx_shimmery_thing( gentity_t *ent )
|
|||
}
|
||||
|
||||
/*QUAKED fx_borg_bolt (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF NO_PROXIMITY_FX
|
||||
-----DESCRIPTION-----
|
||||
CURRENTLY DISABLED
|
||||
Emits yellow electric bolts from the specified point to the specified point.
|
||||
Emits showers of sparks if the endpoints are sufficiently close.
|
||||
Has an Ugly FT-Think, so don't use unless needed
|
||||
|
||||
STARTOFF - effect is initially off
|
||||
NO_PROXIMITY_FX - Will deactivate proximity-fx associated with this. Check it if you don't use movers as else the entity thinks EVERY frame (like on borg2)
|
||||
-----SPAWNFLAGS-----
|
||||
STARTOFF - effect is initially off
|
||||
NO_PROXIMITY_FX - Will deactivate proximity-fx associated with this. Check it if you don't use movers as else the entity thinks EVERY frame (like on borg2)
|
||||
|
||||
"target" (required) end point of the beam. Can be a func_train, info_notnull, etc.
|
||||
"message" - moves start point of the beam to this ent's origin. Only useful if the beam connects 2 movers.
|
||||
"targetname" - toggles effect on/off each time it's used
|
||||
-----KEYS-----
|
||||
"target" - (required) end point of the beam. Can be a func_train, info_notnull, etc.
|
||||
"message" - moves start point of the beam to this ent's origin. Only useful if the beam connects 2 movers.
|
||||
"targetname" - toggles effect on/off each time it's used
|
||||
*/
|
||||
|
||||
//------------------------------------------
|
||||
|
|
|
@ -215,11 +215,6 @@ void Padd_Remove( gentity_t *key )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED item_botroam (.5 .3 .7) (-16 -16 -24) (16 16 0)
|
||||
Bots in MP will go to these spots when there's nothing else to get- helps them patrol.
|
||||
*/
|
||||
|
||||
// For more than four players, adjust the respawn times, up to 1/4.
|
||||
int adjustRespawnTime(float respawnTime)
|
||||
{
|
||||
|
@ -559,7 +554,7 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
respawn = Pickup_Powerup(ent, other);
|
||||
break;
|
||||
case IT_TEAM:
|
||||
respawn = Pickup_Team(ent, other);
|
||||
respawn = 0; // TODO remove?
|
||||
break;
|
||||
case IT_HOLDABLE:
|
||||
respawn = Pickup_Holdable(ent, other);
|
||||
|
@ -702,24 +697,8 @@ gentity_t *LaunchItem( gitem_t *item, gentity_t *who, vec3_t origin, vec3_t velo
|
|||
Padd_Add(dropped, who, txt);
|
||||
}
|
||||
|
||||
if (item->giType == IT_TEAM) { // Special case for CTF flags
|
||||
gentity_t *te;
|
||||
|
||||
VectorSet (dropped->r.mins, -23, -23, -15);
|
||||
VectorSet (dropped->r.maxs, 23, 23, 31);
|
||||
dropped->think = Team_DroppedFlagThink;
|
||||
dropped->nextthink = level.time + 30000;
|
||||
Team_CheckDroppedItem( dropped );
|
||||
|
||||
// make the sound call for a dropped flag
|
||||
te = G_TempEntity( dropped->s.pos.trBase, EV_TEAM_SOUND );
|
||||
te->s.eventParm = DROPPED_FLAG_SOUND;
|
||||
te->r.svFlags |= SVF_BROADCAST;
|
||||
|
||||
} else { // auto-remove after 30 seconds
|
||||
dropped->think = G_FreeEntity;
|
||||
dropped->nextthink = level.time + 6000000; //30000; // RPG-X: Marcin: increased - 03/12/2008
|
||||
}
|
||||
dropped->think = G_FreeEntity;
|
||||
dropped->nextthink = level.time + 6000000; //30000; // RPG-X: Marcin: increased - 03/12/2008
|
||||
|
||||
dropped->flags = flags; // FL_DROPPED_ITEM; // RPG-X: Marcin: for ThrowWeapon - 03/12/2008
|
||||
|
||||
|
@ -983,31 +962,6 @@ qboolean FinishSpawningDecoy( gentity_t *ent, int itemIndex )
|
|||
|
||||
qboolean itemRegistered[MAX_ITEMS];
|
||||
|
||||
/*
|
||||
==================
|
||||
G_CheckTeamItems
|
||||
==================
|
||||
*/
|
||||
void G_CheckTeamItems( void ) {
|
||||
|
||||
// Set up team stuff
|
||||
Team_InitGame();
|
||||
|
||||
if ( g_gametype.integer == GT_CTF ) {
|
||||
gitem_t *item;
|
||||
|
||||
// make sure we actually have two flags...
|
||||
item = BG_FindItem( "team_CTF_redflag" );
|
||||
if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
|
||||
G_Printf( "^1WARNING: No team_CTF_redflag in map" );
|
||||
}
|
||||
item = BG_FindItem( "team_CTF_blueflag" );
|
||||
if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
|
||||
G_Printf( "^1WARNING: No team_CTF_blueflag in map" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
ClearRegisteredItems
|
||||
|
@ -1240,11 +1194,7 @@ void G_RunItem( gentity_t *ent ) {
|
|||
// if it is in a nodrop volume, remove it
|
||||
contents = trap_PointContents( ent->r.currentOrigin, -1 );
|
||||
if ( contents & CONTENTS_NODROP ) {
|
||||
if (ent->item && ent->item->giType == IT_TEAM) {
|
||||
Team_FreeEntity(ent);
|
||||
} else {
|
||||
G_FreeEntity( ent );
|
||||
}
|
||||
G_FreeEntity( ent );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
212
game/g_local.h
212
game/g_local.h
|
@ -480,7 +480,7 @@ void SetScore( gentity_t *ent, int score );
|
|||
/**
|
||||
* \brief client data that stays across multiple respawns,
|
||||
*
|
||||
* but is cleared on each level change or team change at ClientBegin()
|
||||
* but is cleared on each level change or team change at G_Client_Begin()
|
||||
*/
|
||||
typedef struct {
|
||||
clientConnected_t connected;
|
||||
|
@ -502,7 +502,7 @@ typedef struct {
|
|||
|
||||
/** \struct gclient_s
|
||||
*
|
||||
* this structure is cleared on each ClientSpawn(),
|
||||
* this structure is cleared on each G_Client_Spawn(),
|
||||
* except for 'client->pers' and 'client->sess'
|
||||
*/
|
||||
struct gclient_s {
|
||||
|
@ -727,6 +727,7 @@ void StopFollowing( gentity_t *ent );
|
|||
void BroadcastTeamChange( gclient_t *client, int oldTeam );
|
||||
qboolean SetTeam( gentity_t *ent, char *s );
|
||||
void Cmd_FollowCycle_f( gentity_t *ent, int dir );
|
||||
void Cmd_Ready_f (gentity_t *ent);
|
||||
|
||||
//
|
||||
// g_roff.c
|
||||
|
@ -762,8 +763,6 @@ void Padd_Add( gentity_t *key, gentity_t *who, char *txt);
|
|||
char *Padd_Get( gentity_t *key, gentity_t *who );
|
||||
void Padd_Remove( gentity_t *key );
|
||||
|
||||
|
||||
void G_CheckTeamItems( void );
|
||||
void G_RunItem( gentity_t *ent );
|
||||
void RespawnItem( gentity_t *ent );
|
||||
|
||||
|
@ -855,8 +854,7 @@ void G_Repair(gentity_t *ent, gentity_t *tr_ent, float rate); //RPG-X | GSIO01 |
|
|||
//
|
||||
// g_missile.c
|
||||
//
|
||||
void G_RunMissile( gentity_t *ent );
|
||||
|
||||
void G_Missile_Run( gentity_t *ent );
|
||||
gentity_t *fire_blaster (gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
gentity_t *fire_plasma (gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
gentity_t *fire_quantum (gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
|
@ -864,16 +862,15 @@ gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t aimdir);
|
|||
gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir);
|
||||
gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir);
|
||||
gentity_t *fire_comprifle (gentity_t *self, vec3_t start, vec3_t dir);
|
||||
//RPG-X: - RedTechie Added this for curiosity
|
||||
void ShieldRemove(gentity_t *self);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// g_mover.c
|
||||
//
|
||||
void G_RunMover( gentity_t *ent );
|
||||
void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace );
|
||||
void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator );
|
||||
void G_Mover_Run( gentity_t *ent );
|
||||
void G_Mover_TouchDoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace );
|
||||
void G_Mover_UseBinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator );
|
||||
|
||||
//
|
||||
// g_trigger.c
|
||||
|
@ -893,35 +890,105 @@ void target_turbolift_start( gentity_t *ent );
|
|||
//
|
||||
// g_weapon.c
|
||||
//
|
||||
qboolean LogAccuracyHit( gentity_t *target, gentity_t *attacker );
|
||||
void CalcMuzzlePoint ( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint, float projsize);
|
||||
void SnapVectorTowards( vec3_t v, vec3_t to );
|
||||
//qboolean SeekerAcquiresTarget ( gentity_t *ent, vec3_t pos );
|
||||
//void FireSeeker( gentity_t *owner, gentity_t *target, vec3_t origin);
|
||||
qboolean G_Weapon_LogAccuracyHit( gentity_t *target, gentity_t *attacker );
|
||||
void G_Weapon_CalcMuzzlePoint ( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint, float projsize);
|
||||
void G_Weapon_SnapVectorTowards( vec3_t v, vec3_t to );
|
||||
|
||||
//
|
||||
// g_client.c
|
||||
//
|
||||
team_t TeamCount( int ignoreClientNum, int team );
|
||||
team_t PickTeam( int ignoreClientNum );
|
||||
void SetClientViewAngle( gentity_t *ent, vec3_t angle );
|
||||
gentity_t *SelectSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles );
|
||||
void respawn (gentity_t *ent);
|
||||
void BeginIntermission (void);
|
||||
void InitClientPersistant (gclient_t *client);
|
||||
void InitClientResp (gclient_t *client);
|
||||
void InitBodyQue (void);
|
||||
void ClientSpawn( gentity_t *ent, int rpgx_spawn, qboolean fromDeath );
|
||||
void player_die (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod);
|
||||
void AddScore( gentity_t *ent, int score );
|
||||
void CalculateRanks( qboolean fromExit );
|
||||
qboolean SpotWouldTelefrag( gentity_t *spot );
|
||||
//RPG-X: RedTechie - Class info
|
||||
//void ClientMaxHealthForClass ( gclient_t *client, pclass_t pclass );
|
||||
//void ClientPowerupsForClass ( gentity_t *ent, pclass_t pclass );
|
||||
void ClientWeaponsForClass ( gclient_t *client, pclass_t pclass );
|
||||
void ClientHoldablesForClass ( gclient_t *client, pclass_t pclass );
|
||||
void G_StoreClientInitialStatus( gentity_t *ent );
|
||||
/**
|
||||
* Get number of clients in team.
|
||||
*/
|
||||
team_t G_Client_TeamCount( int ignoreClientNum, int team );
|
||||
/**
|
||||
* Pick a random team.
|
||||
*/
|
||||
team_t G_Client_PickTeam( int ignoreClientNum );
|
||||
/**
|
||||
* Set the clients view angle.
|
||||
*/
|
||||
void G_Client_SetViewAngle( gentity_t *ent, vec3_t angle );
|
||||
/**
|
||||
* Select a spawnpoint.
|
||||
*/
|
||||
gentity_t* G_Client_SelectSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles );
|
||||
/**
|
||||
* Respawn client.
|
||||
*/
|
||||
void G_Client_Respawn(gentity_t *ent);
|
||||
/**
|
||||
* Begin intermission.
|
||||
*/
|
||||
void G_Client_BeginIntermission(void);
|
||||
/**
|
||||
* Init the body que.
|
||||
*/
|
||||
void G_Client_InitBodyQue(void);
|
||||
/**
|
||||
* Spawn client.
|
||||
*/
|
||||
void G_Client_Spawn( gentity_t *ent, int rpgx_spawn, qboolean fromDeath );
|
||||
/**
|
||||
* Let the client die.
|
||||
*/
|
||||
void G_Client_Die (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod);
|
||||
/**
|
||||
* Add score for the client.
|
||||
*/
|
||||
void G_Client_AddScore( gentity_t *ent, int score );
|
||||
/**
|
||||
* Calculate clients ranks.
|
||||
*/
|
||||
void G_Client_CalculateRanks( qboolean fromExit );
|
||||
/**
|
||||
* Determine whether spot would telefrag.
|
||||
*/
|
||||
qboolean G_Client_SpotWouldTelefrag( gentity_t *spot );
|
||||
/**
|
||||
* Get weapons for a class.
|
||||
*/
|
||||
void G_Client_WeaponsForClass( gclient_t *client, pclass_t pclass );
|
||||
/**
|
||||
* Get holdable items for a class.
|
||||
*/
|
||||
void G_Client_HoldablesForClass( gclient_t *client, pclass_t pclass );
|
||||
/**
|
||||
* Store the clients initial status.
|
||||
*/
|
||||
void G_Client_StoreClientInitialStatus( gentity_t *ent );
|
||||
/**
|
||||
* Get location message for a client.
|
||||
*/
|
||||
qboolean G_Client_GetLocationMsg(gentity_t *ent, char *loc, int loclen);
|
||||
/**
|
||||
* Check client statuses.
|
||||
*/
|
||||
void G_Client_CheckClientStatus(void);
|
||||
/**
|
||||
* Send client location information.
|
||||
*/
|
||||
void G_Client_LocationsMessage( gentity_t *ent );
|
||||
/**
|
||||
* Client connect.
|
||||
*/
|
||||
char* G_Client_Connect( int clientNum, qboolean firstTime, qboolean isBot );
|
||||
/**
|
||||
* Clients user info changed.
|
||||
*/
|
||||
void G_Client_UserinfoChanged( int clientNum );
|
||||
/**
|
||||
* Disconnect client.
|
||||
*/
|
||||
void G_Client_Disconnect( int clientNum );
|
||||
/**
|
||||
* Initialize client.
|
||||
*/
|
||||
void G_Client_Begin( int clientNum, qboolean careAboutWarmup, qboolean isBot, qboolean first );
|
||||
/**
|
||||
* Client command.
|
||||
*/
|
||||
void G_Client_Command( int clientNum );
|
||||
|
||||
//
|
||||
// g_svcmds.c
|
||||
|
@ -1130,18 +1197,57 @@ typedef enum
|
|||
|
||||
#define AWARDS_MSG_LENGTH 256
|
||||
|
||||
/**
|
||||
* Print message to log.
|
||||
*/
|
||||
void QDECL G_LogPrintf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
|
||||
/**
|
||||
* Log weapon pickup.
|
||||
*/
|
||||
void QDECL G_LogWeaponPickup(int client, int weaponid);
|
||||
/**
|
||||
* Log weapon fire.
|
||||
*/
|
||||
void QDECL G_LogWeaponFire(int client, int weaponid);
|
||||
/**
|
||||
* Log weapon damage.
|
||||
*/
|
||||
void QDECL G_LogWeaponDamage(int client, int mod, int amount);
|
||||
/**
|
||||
* Log weapon kill.
|
||||
*/
|
||||
void QDECL G_LogWeaponKill(int client, int mod);
|
||||
/**
|
||||
* Log weapon death.
|
||||
*/
|
||||
void QDECL G_LogWeaponDeath(int client, int weaponid);
|
||||
/**
|
||||
* Log weapon frag.
|
||||
*/
|
||||
void QDECL G_LogWeaponFrag(int attacker, int deadguy);
|
||||
/**
|
||||
* Log weapon powerup.
|
||||
*/
|
||||
void QDECL G_LogWeaponPowerup(int client, int powerupid);
|
||||
/**
|
||||
* Log weapon item.
|
||||
*/
|
||||
void QDECL G_LogWeaponItem(int client, int itemid);
|
||||
/**
|
||||
* Log weapon init.
|
||||
*/
|
||||
void QDECL G_LogWeaponInit(void);
|
||||
/**
|
||||
* Log weapon output.
|
||||
*/
|
||||
void QDECL G_LogWeaponOutput(void);
|
||||
/**
|
||||
* Log exit.
|
||||
*/
|
||||
void QDECL G_LogExit( const char *string );
|
||||
/**
|
||||
* Clear client log.
|
||||
*/
|
||||
void QDECL G_ClearClientLog(int client);
|
||||
|
||||
void CalculateAwards(gentity_t *ent, char *msg);
|
||||
|
@ -1152,17 +1258,7 @@ int GetFavoriteTargetForClient(int nClient);
|
|||
int GetWorstEnemyForClient(int nClient);
|
||||
int GetFavoriteWeaponForClient(int nClient);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// g_client.c
|
||||
//
|
||||
char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot );
|
||||
//TiM - changed to allow override of 'clampinfo'
|
||||
void ClientUserinfoChanged( int clientNum );
|
||||
void ClientDisconnect( int clientNum );
|
||||
void ClientBegin( int clientNum, qboolean careAboutWarmup, qboolean isBot, qboolean first );
|
||||
void ClientCommand( int clientNum );
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
|
||||
//TiM - Delayed Transport Beam
|
||||
void G_InitTransport( int clientNum, vec3_t origin, vec3_t angles );
|
||||
|
@ -1182,22 +1278,15 @@ typedef struct
|
|||
// g_active.c
|
||||
//
|
||||
|
||||
void ClientThink( int clientNum );
|
||||
void ClientEndFrame( gentity_t *ent );
|
||||
void G_RunClient( gentity_t *ent );
|
||||
void Cmd_Ready_f (gentity_t *ent);
|
||||
void ClientThink( int clientNum ); // TODO move me to g_client.c
|
||||
void ClientEndFrame( gentity_t *ent ); // TODO move me to g_client.c
|
||||
void G_RunClient( gentity_t *ent ); // TODO move me to g_client.c
|
||||
void G_Active_ShieldRemove(gentity_t *self);
|
||||
|
||||
//RPG-X | Marcin | 03/12/2008
|
||||
void ThrowWeapon( gentity_t *ent, char *txt );
|
||||
gentity_t *DropWeapon( gentity_t *ent, gitem_t *item, float angle, int flags, char *txt );
|
||||
|
||||
//
|
||||
// g_team.c
|
||||
//
|
||||
qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 );
|
||||
void Team_CheckDroppedItem( gentity_t *dropped );
|
||||
|
||||
|
||||
//
|
||||
// g_mem.c
|
||||
//
|
||||
|
@ -1279,6 +1368,8 @@ qboolean LuaHook_G_EntityTrigger(char *function, int entnum, int othernum);
|
|||
qboolean LuaHook_G_EntitySpawn(char *function, int entnum);
|
||||
qboolean LuaHook_G_EntityReached(char *function, int entnum);
|
||||
qboolean LuaHook_G_EntityReachedAngular(char *function, int entnum);
|
||||
void G_LuaNumThreads(void);
|
||||
void G_LuaCollectGarbage(void);
|
||||
|
||||
void G_LuaStatus(gentity_t * ent);
|
||||
qboolean G_LuaInit(void);
|
||||
|
@ -2010,5 +2101,10 @@ struct safeZone_s {
|
|||
vec3_t mins;
|
||||
} safeZone_s;
|
||||
|
||||
// timed messages
|
||||
typedef struct timedMessage_s timedMessage_t;
|
||||
struct timedMessage_s {
|
||||
char* message;
|
||||
} timedMessage_s;
|
||||
|
||||
#endif //_G_LOCAL_H_
|
||||
|
|
81
game/g_lua.c
81
game/g_lua.c
|
@ -172,7 +172,24 @@ qboolean G_LuaResume(lvm_t *vm, lua_State *T, char *func, int nargs) {
|
|||
G_Printf(S_COLOR_YELLOW "Lua: traceback error ( %s )\n", vm->filename);
|
||||
vm->error++;
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
if(vm->L != T) { // this is a thread
|
||||
int n = lua_gettop(vm->L);
|
||||
int i;
|
||||
lua_State *p;
|
||||
|
||||
for(i = 0; i <= n; i++) {
|
||||
if(lua_isthread(vm->L, i)) {
|
||||
p = lua_tothread(vm->L, i);
|
||||
|
||||
if(p == T) {
|
||||
lua_remove(vm->L, i);
|
||||
G_LuaCollectGarbage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
@ -264,22 +281,22 @@ qboolean G_LuaStartVM(lvm_t * vm)
|
|||
if(lua_istable(vm->L, -1))
|
||||
{
|
||||
lua_pushstring(vm->L, va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
||||
lua_setfield(vm->L, -2, "path");
|
||||
lua_pushstring(vm->L, va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
lua_setfield(vm->L, -2, "cpath");
|
||||
}
|
||||
lua_pop(vm->L, 1);
|
||||
|
||||
Lua_RegisterGlobal(vm->L, "LUA_PATH", va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
||||
Lua_RegisterGlobal(vm->L, "LUA_CPATH", va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
Lua_RegisterGlobal(vm->L, "LUA_DIRSEP", LUA_DIRSEP);
|
||||
|
||||
lua_newtable(vm->L);
|
||||
|
@ -588,6 +605,7 @@ qboolean LuaHook_G_EntityThink(char *function, int entnum)
|
|||
continue;
|
||||
}
|
||||
} else {
|
||||
t = vm->L;
|
||||
if(!G_LuaGetFunctionT(t, function))
|
||||
continue;
|
||||
ent = &g_entities[entnum];
|
||||
|
@ -1071,4 +1089,49 @@ qboolean LuaHook_G_EntitySpawn(char *function, int entnum)
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
void G_LuaNumThreads(void) {
|
||||
lvm_t* vm = lVM[0];
|
||||
|
||||
if(vm) {
|
||||
lua_State *p;
|
||||
int n = lua_gettop(vm->L);
|
||||
int i, cnt = 0;
|
||||
|
||||
for(i = 0; i <= n; i++) {
|
||||
if(lua_isthread(vm->L, i)) {
|
||||
cnt++;
|
||||
p = lua_tothread(vm->L, i);
|
||||
if(lua_status(p) == LUA_YIELD) {
|
||||
G_Printf("lua thread %d is YIELDED\n", i);
|
||||
} else if(lua_status(vm->L) == 0) {
|
||||
G_Printf("lua thread %d is RUNNING\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
G_Printf("Total lua thread count: %d\n", cnt);
|
||||
}
|
||||
}
|
||||
|
||||
void G_LuaCollectGarbage(void) {
|
||||
lvm_t *vm;
|
||||
lua_State *p;
|
||||
int i, n, m;
|
||||
|
||||
for(i = 0; i < NUM_VMS; i++) {
|
||||
vm = lVM[i];
|
||||
|
||||
if(vm) {
|
||||
n = lua_gettop(vm->L);
|
||||
|
||||
for(m = n; m > 0; m--) {
|
||||
if(lua_isthread(vm->L, m)) {
|
||||
p = lua_tothread(vm->L, m);
|
||||
lua_gc(p, LUA_GCCOLLECT, 0);
|
||||
}
|
||||
}
|
||||
lua_gc(vm->L, LUA_GCCOLLECT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
105
game/g_main.c
105
game/g_main.c
|
@ -514,21 +514,21 @@ intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4,
|
|||
G_ShutdownGame( arg0 );
|
||||
return 0;
|
||||
case GAME_CLIENT_CONNECT:
|
||||
return (size_t)ClientConnect( arg0, (qboolean)arg1, (qboolean)arg2 );
|
||||
return (size_t)G_Client_Connect( arg0, (qboolean)arg1, (qboolean)arg2 );
|
||||
case GAME_CLIENT_THINK:
|
||||
ClientThink( arg0 );
|
||||
return 0;
|
||||
case GAME_CLIENT_USERINFO_CHANGED:
|
||||
ClientUserinfoChanged( arg0 ); //TiM - this means a user just tried to change it
|
||||
G_Client_UserinfoChanged( arg0 ); //TiM - this means a user just tried to change it
|
||||
return 0;
|
||||
case GAME_CLIENT_DISCONNECT:
|
||||
ClientDisconnect( arg0 );
|
||||
G_Client_Disconnect( arg0 );
|
||||
return 0;
|
||||
case GAME_CLIENT_BEGIN:
|
||||
ClientBegin( arg0, qtrue, qfalse, qtrue );
|
||||
G_Client_Begin( arg0, qtrue, qfalse, qtrue );
|
||||
return 0;
|
||||
case GAME_CLIENT_COMMAND:
|
||||
ClientCommand( arg0 );
|
||||
G_Client_Command( arg0 );
|
||||
return 0;
|
||||
case GAME_RUN_FRAME:
|
||||
G_RunFrame( arg0 );
|
||||
|
@ -906,10 +906,11 @@ void SP_target_location (gentity_t *ent);
|
|||
static void G_LoadTimedMessages(void) {
|
||||
fileHandle_t f;
|
||||
char* buffer;
|
||||
char* ptr;
|
||||
char* message;
|
||||
char* textPtr;
|
||||
char* token;
|
||||
int len;
|
||||
int i, n;
|
||||
int i;
|
||||
timedMessage_t *msg;
|
||||
|
||||
len = trap_FS_FOpenFile("timedmessages.cfg", &f, FS_READ);
|
||||
if(!len) return;
|
||||
|
@ -930,26 +931,49 @@ static void G_LoadTimedMessages(void) {
|
|||
}
|
||||
|
||||
trap_FS_Read(buffer, len, f);
|
||||
ptr = buffer;
|
||||
|
||||
textPtr = buffer;
|
||||
COM_BeginParseSession();
|
||||
token = COM_Parse(&textPtr);
|
||||
if(token[0] != '{') {
|
||||
G_Printf("G_LoadTimedMessages - timedmessages.cfg not beginning with '{'\n");
|
||||
trap_FS_FCloseFile(f);
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < 10; i++) {
|
||||
for(n = 0; ptr[n] != ';' && ptr[n] != 0; n++);
|
||||
if(ptr[n] == 0) break;
|
||||
message = (char *)malloc(sizeof(char)*(n+1));
|
||||
if(!message) {
|
||||
G_Printf(S_COLOR_RED "ERROR: Was unable to allocate %i byte.\n", (n+1) * sizeof(char) );
|
||||
trap_FS_FCloseFile(f);
|
||||
free(buffer);
|
||||
if(level.timedMessages != NULL) {
|
||||
destroy_list(level.timedMessages);
|
||||
}
|
||||
return;
|
||||
token = COM_Parse(&textPtr);
|
||||
|
||||
if(!token[0]) {
|
||||
break;
|
||||
}
|
||||
|
||||
memset(message, 0, sizeof(message));
|
||||
strncpy(message, ptr, n);
|
||||
list_add(level.timedMessages, message, strlen(message));
|
||||
if(!strcmp(token, "message")) {
|
||||
if(COM_ParseString(&textPtr, &token)) {
|
||||
G_Printf("G_LoadTimedMessages - invalid value '%s'\n", token);
|
||||
SkipRestOfLine(&textPtr);
|
||||
continue;
|
||||
}
|
||||
|
||||
ptr += strlen(message)+1;
|
||||
msg = (timedMessage_t *)malloc(sizeof(timedMessage_s));
|
||||
if(msg == NULL) {
|
||||
G_Printf("G_LoadTimedMessages - was unable to allocate timed message storage\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
msg->message = strdup(token);
|
||||
G_Printf("------------------------------------------------>'%s'\n", token);
|
||||
list_add(level.timedMessages, msg, sizeof(timedMessage_s));
|
||||
} else {
|
||||
G_Printf("G_LoadTimedMessages - invalid token '%s'\n", token);
|
||||
SkipRestOfLine(&textPtr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(token[0] == '}') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
trap_FS_FCloseFile(f);
|
||||
|
@ -1665,8 +1689,6 @@ static void G_UpdateCvars( void )
|
|||
}
|
||||
|
||||
extern int altAmmoUsage[];
|
||||
extern team_t borgTeam;
|
||||
extern team_t initialBorgTeam;
|
||||
static void G_InitModRules( void )
|
||||
{
|
||||
numKilled = 0;
|
||||
|
@ -1827,7 +1849,7 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) {
|
|||
&level.clients[0].ps, sizeof( level.clients[0] ) );
|
||||
|
||||
// reserve some spots for dead player bodies
|
||||
InitBodyQue();
|
||||
G_Client_InitBodyQue();
|
||||
|
||||
ClearRegisteredItems();
|
||||
|
||||
|
@ -1855,9 +1877,6 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) {
|
|||
// general initialization
|
||||
G_FindTeams();
|
||||
|
||||
// make sure we have flags for CTF, etc
|
||||
G_CheckTeamItems();
|
||||
|
||||
SaveRegisteredItems();
|
||||
|
||||
G_Printf ("-----------------------------------\n");
|
||||
|
@ -2084,13 +2103,13 @@ static void AdjustTournamentScores( void ) {
|
|||
clientNum = level.sortedClients[0];
|
||||
if ( level.clients[ clientNum ].pers.connected == CON_CONNECTED ) {
|
||||
level.clients[ clientNum ].sess.wins++;
|
||||
ClientUserinfoChanged( clientNum );
|
||||
G_Client_UserinfoChanged( clientNum );
|
||||
}
|
||||
|
||||
clientNum = level.sortedClients[1];
|
||||
if ( level.clients[ clientNum ].pers.connected == CON_CONNECTED ) {
|
||||
level.clients[ clientNum ].sess.losses++;
|
||||
ClientUserinfoChanged( clientNum );
|
||||
G_Client_UserinfoChanged( clientNum );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2165,7 +2184,7 @@ int QDECL SortRanks( const void *a, const void *b ) {
|
|||
|
||||
/*
|
||||
============
|
||||
CalculateRanks
|
||||
G_Client_CalculateRanks
|
||||
|
||||
Recalculates the score ranks of all players
|
||||
This will be called on every client connect, begin, disconnect, death,
|
||||
|
@ -2174,7 +2193,7 @@ and team change.
|
|||
FIXME: for elimination, the last man standing must be ranked first
|
||||
============
|
||||
*/
|
||||
void CalculateRanks( qboolean fromExit ) {
|
||||
void G_Client_CalculateRanks( qboolean fromExit ) {
|
||||
int i;
|
||||
int rank;
|
||||
int score;
|
||||
|
@ -2291,7 +2310,7 @@ MAP CHANGING
|
|||
========================
|
||||
SendScoreboardMessageToAllClients
|
||||
|
||||
Do this at BeginIntermission time and whenever ranks are recalculated
|
||||
Do this at G_Client_BeginIntermission time and whenever ranks are recalculated
|
||||
due to enters/exits/forced team changes
|
||||
========================
|
||||
*/
|
||||
|
@ -2356,7 +2375,7 @@ void FindIntermissionPoint( void ) {
|
|||
// find the intermission spot
|
||||
ent = G_Find (NULL, FOFS(classname), "info_player_intermission");
|
||||
if ( !ent ) { // the map creator forgot to put in an intermission point...
|
||||
SelectSpawnPoint ( vec3_origin, level.intermission_origin, level.intermission_angle );
|
||||
G_Client_SelectSpawnPoint ( vec3_origin, level.intermission_origin, level.intermission_angle );
|
||||
} else {
|
||||
VectorCopy (ent->s.origin, level.intermission_origin);
|
||||
VectorCopy (ent->s.angles, level.intermission_angle);
|
||||
|
@ -2397,10 +2416,10 @@ static void ClearFiringFlags(void)
|
|||
|
||||
/*
|
||||
==================
|
||||
BeginIntermission
|
||||
G_Client_BeginIntermission
|
||||
==================
|
||||
*/
|
||||
void BeginIntermission( void ) {
|
||||
void G_Client_BeginIntermission( void ) {
|
||||
int i;
|
||||
gentity_t *client;
|
||||
qboolean doingLevelshot;
|
||||
|
@ -2439,7 +2458,7 @@ void BeginIntermission( void ) {
|
|||
if (!client->inuse)
|
||||
continue;
|
||||
if (client->health <= 0) {
|
||||
respawn(client);
|
||||
G_Client_Respawn(client);
|
||||
}
|
||||
MoveClientToIntermission( client );
|
||||
|
||||
|
@ -2722,7 +2741,7 @@ void G_RunFrame( int levelTime ) {
|
|||
}
|
||||
|
||||
if ( (es->eType == ET_MISSILE) || (es->eType == ET_ALT_MISSILE) ) {
|
||||
G_RunMissile( ent );
|
||||
G_Missile_Run( ent );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2732,7 +2751,7 @@ void G_RunFrame( int levelTime ) {
|
|||
}
|
||||
|
||||
if ( es->eType == ET_MOVER || es->eType == ET_MOVER_STR ) { //RPG-X | GSIO01 | 13/05/2009
|
||||
G_RunMover( ent );
|
||||
G_Mover_Run( ent );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2758,8 +2777,8 @@ void G_RunFrame( int levelTime ) {
|
|||
// see if it is time to end the level
|
||||
CheckExitRules();
|
||||
|
||||
// update to team status?
|
||||
CheckTeamStatus();
|
||||
// update to client status?
|
||||
G_Client_CheckClientStatus();
|
||||
|
||||
// cancel vote if timed out
|
||||
CheckVote();
|
||||
|
|
308
game/g_misc.c
308
game/g_misc.c
|
@ -6,20 +6,43 @@
|
|||
|
||||
|
||||
/*QUAKED func_group (0 0 0) ?
|
||||
-----DESCRIPTION-----
|
||||
Used to group brushes together just for editor convenience. They are turned into normal brushes by the utilities.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
q3map2:
|
||||
"_lightmapscale" - set a diffrent lightmapscale for this func group only
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED info_camp (0 0.5 0) (-4 -4 -4) (4 4 4)
|
||||
Used as a positional target for calculations in the utilities (spotlights, etc), but removed during gameplay.
|
||||
-----DESCRIPTION-----
|
||||
Used as a positional target for calculations in the compiler/utilities (spotlights, etc), but removed during gameplay.
|
||||
|
||||
-----SAPWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - have whatever is required point at this.
|
||||
*/
|
||||
// Lol, this is contradictory, should free but instead sets origin... Description sais removed so maybe merge with info_null.
|
||||
void SP_info_camp( gentity_t *self ) {
|
||||
G_SetOrigin( self, self->s.origin );
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
|
||||
Used as a positional target for calculations in the utilities (spotlights, etc), but removed during gameplay.
|
||||
-----DESCRIPTION-----
|
||||
Used as a positional target for calculations in the compiler/utilities (spotlights, etc), but removed during gameplay.
|
||||
|
||||
-----SAPWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - have whatever is required point at this.
|
||||
*/
|
||||
void SP_info_null( gentity_t *self ) {
|
||||
G_FreeEntity( self );
|
||||
|
@ -27,23 +50,83 @@ void SP_info_null( gentity_t *self ) {
|
|||
|
||||
|
||||
/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
|
||||
-----DESCRIPTION-----
|
||||
Used as a positional target for in-game calculation, like jumppad targets.
|
||||
target_position does the same thing
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - have whatever is required point at this.
|
||||
*/
|
||||
|
||||
//these share the spawnfunction with info_notnull
|
||||
|
||||
/*QUAKED misc_teleporter_dest (1 0 0) (-32 -32 -24) (32 32 -16)
|
||||
-----DESCRIPTION-----
|
||||
Merely a fancy name for info_notnull.
|
||||
was originally used for teleporters but became redundant.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - have whatever is required point at this.
|
||||
*/
|
||||
/*QUAKED target_position (0 0.5 0) (-4 -4 -4) (4 4 4)
|
||||
-----DESCRIPTION-----
|
||||
Merely a fancy name for info_notnull.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - have whatever is required point at this.
|
||||
*/
|
||||
void SP_info_notnull( gentity_t *self ){
|
||||
if(!Q_stricmp(self->classname, "ref_tag") && !rpg_allowspmaps.integer)
|
||||
G_FreeEntity(self);
|
||||
|
||||
if(strcmp(self->classname, "info_notnull")) {
|
||||
self->classname = G_NewString("info_notnull");
|
||||
}
|
||||
G_SetOrigin( self, self->s.origin );
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) linear noIncidence
|
||||
Non-displayed light.
|
||||
"light" overrides the default 300 intensity.
|
||||
'Linear' checkbox gives linear falloff instead of inverse square
|
||||
'noIncidence' checkbox makes lighting smoother
|
||||
Lights pointed at a target will be spotlights.
|
||||
"radius" overrides the default 64 unit radius of a spotlight at the target point.
|
||||
/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) LINEAR NO_INCIDENCE X X NO_GRID NORMALIZED_COLOR FORCE_DISTANCE_ATTENUATION
|
||||
-----DESCRIPTION-----
|
||||
Light source for the compiler. Will be removed ingame.
|
||||
Lights pointed at a target (info_null) will be spotlights.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: LINEAR - checkbox gives linear falloff instead of inverse square
|
||||
2: NO_INCIDENCE - checkbox makes lighting smoother
|
||||
4: X - Unknown. Usage not recomended.
|
||||
8: X - Unknown. Usage not recomended.
|
||||
|
||||
q3map2:
|
||||
16: NO_GRID - light does not affect the grid
|
||||
32: NORMALIZED_COLOR - light color gets normalized by the compiler
|
||||
64: FORCE_DISTANCE_ATTENUATION - distance attenuation is enforced
|
||||
|
||||
-----KEYS-----
|
||||
"light" - overrides the default 300 intensity.
|
||||
"radius" - overrides the default 64 unit radius of a spotlight at the target point.
|
||||
"_color" - light color
|
||||
|
||||
q3map2:
|
||||
"_style" - light style number
|
||||
"fade" - Fade factor of light attenuation of linear lights. (Linear lights vanish at light/(fade * 8000).
|
||||
"_anglescale" - scales angle attenuation
|
||||
"scale" - intensity multiplier
|
||||
"_samples" - number of samples to use to get soft shadows from a light
|
||||
"_deviance" - position deviance of the samples of a regular light
|
||||
"_filterradius" - filter radius for this light
|
||||
"_sun" - if 1, this light is an infinite sun light
|
||||
"_flareshader" - shader for a flare surface generated by this light
|
||||
"_flare" - when set, this light is a flare without a specified shader
|
||||
*/
|
||||
void SP_light( gentity_t *self ) {
|
||||
G_FreeEntity( self );
|
||||
|
@ -96,7 +179,7 @@ void TransportPlayer( gentity_t *player, vec3_t origin, vec3_t angles, int speed
|
|||
ps->eFlags ^= EF_TELEPORT_BIT;
|
||||
|
||||
// set angles
|
||||
SetClientViewAngle( player, angles );
|
||||
G_Client_SetViewAngle( player, angles );
|
||||
|
||||
// kill anything at the destination
|
||||
if ( sess->sessionTeam != TEAM_SPECTATOR /*&& !(ps->eFlags&EF_ELIMINATED)*/) {
|
||||
|
@ -204,7 +287,7 @@ void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles, tpType_t t
|
|||
ps->eFlags ^= EF_TELEPORT_BIT;
|
||||
|
||||
// set angles
|
||||
SetClientViewAngle( player, angles );
|
||||
G_Client_SetViewAngle( player, angles );
|
||||
|
||||
// kill anything at the destination
|
||||
if ( sess->sessionTeam != TEAM_SPECTATOR ) {
|
||||
|
@ -223,22 +306,31 @@ void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles, tpType_t t
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED misc_teleporter_dest (1 0 0) (-32 -32 -24) (32 32 -16)
|
||||
Point teleporters at these.
|
||||
Now that we don't have teleport destination pads, this is just
|
||||
an info_notnull
|
||||
*/
|
||||
void SP_misc_teleporter_dest( gentity_t *ent ) {
|
||||
}
|
||||
|
||||
|
||||
//===========================================================
|
||||
|
||||
/*QUAKED misc_model (1 0 0) (-16 -16 -16) (16 16 16) CAST_SHADOWS CLIP_MODEL FORCE_META
|
||||
"model" arbitrary .md3 file to display
|
||||
-----DESCRIPTION-----
|
||||
Will just spawn and display it's model.
|
||||
Can be hooked up with a brushmodel-entity to move relative to.
|
||||
|
||||
spawnflags only work when compiled with q3map2
|
||||
-----SPAWNFLAGS-----
|
||||
q3map2:
|
||||
1: CAST_SHADOWS - Model will cast shadows.
|
||||
2: CLIP_MODEL - Model will be clipped so noone can pass trough.
|
||||
4: FORCE_META - will enforce a meta-compile for .bsp-build even if the compiler wasn't told to do so.
|
||||
|
||||
-----KEYS-----
|
||||
"model" - arbitrary .md3 file to display
|
||||
"target" - brushmodel-entity to attach to
|
||||
|
||||
q3map2:
|
||||
"_castShadows" OR "_cs" sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" sets whether the entity receives shadows
|
||||
"modelscale" scaling factor for the model to include
|
||||
"modelscale_vec" non-uniform scaling vector for the model to include
|
||||
"model2" path name of second model to load
|
||||
"_frame" frame of model to load
|
||||
"_frame2" frame of second model to load
|
||||
*/
|
||||
void SP_misc_model( gentity_t *ent ) {
|
||||
|
||||
|
@ -304,12 +396,6 @@ void cycleCamera( gentity_t *self )
|
|||
//Uh oh! Not targeted at any ents! Or reached end of list? Which is it?
|
||||
//for now assume reached end of list and are cycling
|
||||
owner = G_Find( owner, FOFS(targetname), self->target );
|
||||
if ( owner == NULL )
|
||||
{//still didn't find one
|
||||
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] Couldn't find target for misc_portal_surface\n" ););
|
||||
G_FreeEntity( self );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setCamera( self, owner->s.number );
|
||||
|
@ -317,82 +403,131 @@ void cycleCamera( gentity_t *self )
|
|||
if ( self->think == cycleCamera )
|
||||
{
|
||||
if ( owner->wait > 0 )
|
||||
{
|
||||
self->nextthink = level.time + owner->wait;
|
||||
}
|
||||
else
|
||||
{
|
||||
else if ( self->wait > 0 )
|
||||
self->nextthink = level.time + self->wait;
|
||||
}
|
||||
else
|
||||
self->nextthink = -1; //no auto cycle
|
||||
}
|
||||
}
|
||||
|
||||
void misc_portal_use( gentity_t *self, gentity_t *other, gentity_t *activator )
|
||||
{
|
||||
cycleCamera( self );
|
||||
if(!Q_stricmp(self->swapname, activator->target) && self->wait > 0) { //failsafe in case something slipped up, I'm too tired to be sure ^^
|
||||
if(self->nextthink)
|
||||
self->nextthink = -1;
|
||||
else
|
||||
self->nextthink = level.time + self->wait;
|
||||
}else{
|
||||
cycleCamera( self );
|
||||
}
|
||||
}
|
||||
|
||||
void locateCamera( gentity_t *ent ) {
|
||||
|
||||
gentity_t *owner = NULL;
|
||||
owner = G_Find( NULL, FOFS(targetname), ent->target );
|
||||
if ( owner == NULL )
|
||||
{
|
||||
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] Couldn't find target for misc_partal_surface\n" ););
|
||||
|
||||
if(!owner){
|
||||
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] Couldn't find target for misc_partal_surface, removing surface so you'll note.\n" ););
|
||||
G_FreeEntity( ent );
|
||||
return;
|
||||
}
|
||||
|
||||
setCamera( ent, owner->s.number );
|
||||
|
||||
if ( G_Find( owner, FOFS(targetname), ent->target) != NULL )
|
||||
{//targeted at more than one thing
|
||||
ent->think = cycleCamera;
|
||||
if ( owner->wait > 0 )
|
||||
{
|
||||
ent->nextthink = level.time + owner->wait;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->nextthink = level.time + ent->wait;
|
||||
//let's see if we need cyceling of some sort. Basic requirement: Do we have another camera connected?
|
||||
if( G_Find( owner, FOFS(targetname), ent->target)){
|
||||
//we do, so do we need to set up for manual cycle or pause?
|
||||
if( ent->targetname || (ent->swapname && ent->wait > 0))
|
||||
ent->use = misc_portal_use; //there's one of either. Which one will be determined in usefunction.
|
||||
|
||||
//to set up the autocycle we need wait set on either surface or camera.
|
||||
if(ent->wait > 0 || owner->wait > 0){
|
||||
if(ent->wait == -1 && owner->wait > 0){ //we need to make sure every camera has an individual wait
|
||||
while((owner = G_Find( owner, FOFS(targetname), ent->target)) != NULL){
|
||||
if(owner->wait == -1){
|
||||
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] One of the tragetet misc_portal_cameras does not have an individual wait. Adapting wait of the first camera found as a default.\n" ););
|
||||
owner = G_Find( NULL, FOFS(targetname), ent->target);
|
||||
ent->wait = owner->wait; //a camera failed so make sure to have the wait of the first camera ported over to the surface as failsafe
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//make sure we got the right camera at this point
|
||||
owner = G_Find( NULL, FOFS(targetname), ent->target);
|
||||
|
||||
ent->think = cycleCamera;
|
||||
if ( owner->wait > 0 )
|
||||
ent->nextthink = level.time + owner->wait;
|
||||
else if ( ent->wait > 0 )
|
||||
ent->nextthink = level.time + ent->wait;
|
||||
else
|
||||
ent->nextthink = -1; //no auto cycle
|
||||
}
|
||||
}
|
||||
setCamera( ent, owner->s.number );
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED misc_portal_surface (0 0 1) (-8 -8 -8) (8 8 8)
|
||||
-----DESCRIPTION-----
|
||||
The portal surface nearest this entity will show a view from the targeted misc_portal_camera, or a mirror view if untargeted.
|
||||
This must be within 64 world units of the surface!
|
||||
|
||||
targetname - When used, cycles to the next misc_portal_camera it's targeted
|
||||
wait - makes it auto-cycle between all cameras it's pointed at at intevervals of specified number of seconds.
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
cameras will be cycled through in the order they were created on the map.
|
||||
-----KEYS-----
|
||||
"target" - misc_portal_camera's to target
|
||||
"targetname" - When used, cycles to the next misc_portal_camera it's targeted
|
||||
"wait" - makes it auto-cycle between all cameras it's pointed at at intevervals of specified number of seconds. Default = -1 = don't autocycle
|
||||
cameras will be cycled through in the order they were created on the map.
|
||||
if this and the first camera are -1 there will be no autocycle.
|
||||
if this is -1 but the first camera is positive the wait will be adapted as a faulsafe measure should one of the later cameras lack an individual wait.
|
||||
"swapname" - will pause/unpause the autocycle. The next cycle will happen aufer "wait" seconds, so wait is required for this.
|
||||
requires SELF/NO_ACRIVATOR
|
||||
|
||||
-----USAGE-----
|
||||
Autocycle or manual Cycle usually only makes sence for a survaliance-station or security.
|
||||
For a viewscreen or a communications channel make the brush having the portal-texture a func_usable and treat is as described on that entity for VFX-Entities.
|
||||
*/
|
||||
void SP_misc_portal_surface(gentity_t *ent) {
|
||||
|
||||
VectorClear( ent->r.mins );
|
||||
VectorClear( ent->r.maxs );
|
||||
trap_LinkEntity (ent);
|
||||
|
||||
ent->r.svFlags = SVF_PORTAL;
|
||||
ent->s.eType = ET_PORTAL;
|
||||
ent->wait *= 1000;
|
||||
if(ent->wait > 0)
|
||||
ent->wait *= 1000;
|
||||
else
|
||||
ent->wait = -1;
|
||||
|
||||
if ( !ent->target ) {
|
||||
VectorCopy( ent->s.origin, ent->s.origin2 );
|
||||
VectorCopy( ent->s.origin, ent->s.origin2 ); //mirror
|
||||
} else {
|
||||
ent->think = locateCamera;
|
||||
ent->nextthink = level.time + 100;
|
||||
if ( ent->targetname )
|
||||
{
|
||||
ent->use = misc_portal_use;
|
||||
ent->nextthink = level.time + 500; //give cameras time to spawn
|
||||
if(ent->targetname && ent->swapname && ent->wait == -1){
|
||||
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] Both swapname and wait need to be present on a misc_model_surface to potentionally turn it's autocycle off. NULLing swapname.\n" ););
|
||||
ent->swapname = G_NewString("NULL"); //Failsafe: We'll have the usefunction, however we can not use it for pausing as we did not have wait on ent. Set swapname to NULL so we can use wait as a potential failsafe should one of the cameras lack an individual wait.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate
|
||||
The target for a misc_portal_surface. You can set either angles or target another entity (NOT an info_null) to determine the direction of view.
|
||||
"roll" an angle modifier to orient the camera around the target vector;
|
||||
/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) SLOWROTATE FASTROTATE
|
||||
-----DESCRIPTION-----
|
||||
The target for a misc_portal_surface.
|
||||
You can set either angles or target another entity (NOT an info_null or similar) to determine the direction of view.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: SLOWROTATE - slowly rotates around it's axis of view
|
||||
2: FASTROTATE - quickly rotates around it's axis of view
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - have misc_portal_surface target this
|
||||
"roll" - an angle modifier to orient the camera around the target vector. Default is 0.
|
||||
"wait" - delay for autocycle misc_portal_surface. Will overwrite theirs. Default is -1 = use surface-value.
|
||||
*/
|
||||
void SP_misc_portal_camera(gentity_t *ent) {
|
||||
float roll;
|
||||
|
@ -404,7 +539,10 @@ void SP_misc_portal_camera(gentity_t *ent) {
|
|||
G_SpawnFloat( "roll", "0", &roll );
|
||||
|
||||
ent->s.clientNum = roll/360.0 * 256;
|
||||
ent->wait *= 1000;
|
||||
if(ent->wait > 0)
|
||||
ent->wait *= 1000;
|
||||
else
|
||||
ent->wait = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -487,32 +625,60 @@ void InitShooter( gentity_t *ent, int weapon ) {
|
|||
}
|
||||
|
||||
/*QUAKED shooter_rocket (1 0 0) (-16 -16 -16) (16 16 16)
|
||||
Fires at either the target or the current direction.
|
||||
"random" the number of degrees of deviance from the taget. (1.0 default)
|
||||
-----DESCRIPTION-----
|
||||
When used fires a rocket at either the target or the current direction.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - direction to fire to
|
||||
"random" - the number of degrees of deviance from the taget. (1.0 default)
|
||||
*/
|
||||
void SP_shooter_rocket( gentity_t *ent ) {
|
||||
InitShooter( ent, WP_10 );
|
||||
}
|
||||
|
||||
/*QUAKED shooter_plasma (1 0 0) (-16 -16 -16) (16 16 16)
|
||||
Fires at either the target or the current direction.
|
||||
"random" is the number of degrees of deviance from the taget. (1.0 default)
|
||||
-----DESCRIPTION-----
|
||||
When used fires a plasma-burst at either the target or the current direction.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - direction to fire to
|
||||
"random" - the number of degrees of deviance from the taget. (1.0 default)
|
||||
*/
|
||||
void SP_shooter_plasma( gentity_t *ent ) {
|
||||
InitShooter( ent, WP_6 ); //TiM : WP_4
|
||||
}
|
||||
|
||||
/*QUAKED shooter_grenade (1 0 0) (-16 -16 -16) (16 16 16)
|
||||
Fires at either the target or the current direction.
|
||||
"random" is the number of degrees of deviance from the taget. (1.0 default)
|
||||
-----DESCRIPTION-----
|
||||
When used fires a grenade at either the target or the current direction.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - direction to fire to
|
||||
"random" - the number of degrees of deviance from the taget. (1.0 default)
|
||||
*/
|
||||
void SP_shooter_grenade( gentity_t *ent ) {
|
||||
InitShooter( ent, WP_8);
|
||||
}
|
||||
|
||||
/*QUAKED shooter_torpedo (1 0 0) (-16 -16 -16) (16 16 16)
|
||||
Fires at either the target or the current direction.
|
||||
"random" is the number of degrees of deviance from the taget. (1.0 default)
|
||||
-----DESCRIPTION-----
|
||||
When used fires a torpedo at either the target or the current direction.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - direction to fire to
|
||||
"random" - the number of degrees of deviance from the taget. (1.0 default)
|
||||
*/
|
||||
void SP_shooter_torpedo( gentity_t *ent ) {
|
||||
InitShooter( ent, WP_9 );
|
||||
|
|
|
@ -237,10 +237,10 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
|||
if(other && ((other->classname && !Q_stricmp(other->classname, "holdable_shield")))){
|
||||
if(IsAdmin(ent->parent)){
|
||||
G_FreeEntity(ent);
|
||||
ShieldRemove(other);
|
||||
G_Active_ShieldRemove(other);
|
||||
return;
|
||||
}else{
|
||||
// can't call grenadeSpewShrapnel right here or G_RunMissile will puke
|
||||
// can't call grenadeSpewShrapnel right here or G_Missile_Run will puke
|
||||
ent->think = grenadeSpewShrapnel;
|
||||
// set our next think to right now. our think fn will get called this frame.
|
||||
ent->nextthink = level.time;
|
||||
|
@ -248,7 +248,7 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
|||
return;
|
||||
}
|
||||
}else{
|
||||
// can't call grenadeSpewShrapnel right here or G_RunMissile will puke
|
||||
// can't call grenadeSpewShrapnel right here or G_Missile_Run will puke
|
||||
ent->think = grenadeSpewShrapnel;
|
||||
// set our next think to right now. our think fn will get called this frame.
|
||||
ent->nextthink = level.time;
|
||||
|
@ -301,7 +301,7 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
|
|||
// change over to a normal entity right at the point of impact
|
||||
ent->s.eType = ET_GENERAL;
|
||||
|
||||
SnapVectorTowards( trace->endpos, ent->s.pos.trBase ); // save net bandwidth
|
||||
G_Weapon_SnapVectorTowards( trace->endpos, ent->s.pos.trBase ); // save net bandwidth
|
||||
|
||||
G_SetOrigin( ent, trace->endpos );
|
||||
|
||||
|
@ -367,11 +367,11 @@ static void G_RunStuckMissile( gentity_t *ent )
|
|||
|
||||
/*
|
||||
================
|
||||
G_RunMissile
|
||||
G_Missile_Run
|
||||
|
||||
================
|
||||
*/
|
||||
void G_RunMissile( gentity_t *ent ) {
|
||||
void G_Missile_Run( gentity_t *ent ) {
|
||||
vec3_t origin;
|
||||
trace_t tr;
|
||||
|
||||
|
|
502
game/g_mover.c
502
game/g_mover.c
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "g_local.h"
|
||||
|
||||
extern qboolean G_CallSpawn(gentity_t *ent);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -359,11 +360,11 @@ static void G_MoverTeam( gentity_t *ent ) {
|
|||
|
||||
/*
|
||||
================
|
||||
G_RunMover
|
||||
G_Mover_Run
|
||||
|
||||
================
|
||||
*/
|
||||
void G_RunMover( gentity_t *ent ) {
|
||||
void G_Mover_Run( gentity_t *ent ) {
|
||||
// if not a team captain, don't do anything, because
|
||||
// the captain will handle everything
|
||||
if ( ent->flags & FL_TEAMSLAVE ) {
|
||||
|
@ -703,7 +704,7 @@ void Reached_BinaryMover( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
if ( ent->wait < 0 )
|
||||
ent->use = Use_BinaryMover;
|
||||
ent->use = G_Mover_UseBinaryMover;
|
||||
|
||||
// close areaportals
|
||||
if ( ent->teammaster == ent || !ent->teammaster ) {
|
||||
|
@ -745,7 +746,7 @@ void Reached_BinaryMover( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
if(ent->wait < 0)
|
||||
ent->use = Use_BinaryMover;
|
||||
ent->use = G_Mover_UseBinaryMover;
|
||||
|
||||
// close areaportals
|
||||
if ( ent->teammaster == ent || !ent->teammaster ) {
|
||||
|
@ -777,10 +778,10 @@ void Reached_BinaryMover( gentity_t *ent ) {
|
|||
|
||||
/*
|
||||
================
|
||||
Use_BinaryMover
|
||||
G_Mover_UseBinaryMover
|
||||
================
|
||||
*/
|
||||
void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
|
||||
void G_Mover_UseBinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
|
||||
int total;
|
||||
int partial;
|
||||
|
||||
|
@ -825,7 +826,7 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
|
|||
|
||||
// only the master should be used
|
||||
if ( ent->flags & FL_TEAMSLAVE ) {
|
||||
Use_BinaryMover( ent->teammaster, other, activator );
|
||||
G_Mover_UseBinaryMover( ent->teammaster, other, activator );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1017,7 +1018,7 @@ void InitMover( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
|
||||
ent->use = Use_BinaryMover;
|
||||
ent->use = G_Mover_UseBinaryMover;
|
||||
if(Q_stricmp(ent->classname, "func_mover"))
|
||||
ent->reached = Reached_BinaryMover;
|
||||
else
|
||||
|
@ -1126,7 +1127,7 @@ void InitRotator( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
|
||||
ent->use = Use_BinaryMover;
|
||||
ent->use = G_Mover_UseBinaryMover;
|
||||
ent->reached = Reached_BinaryMover;
|
||||
|
||||
ent->moverState = ROTATOR_POS1;
|
||||
|
@ -1171,11 +1172,6 @@ Blocked_Door
|
|||
void Blocked_Door( gentity_t *ent, gentity_t *other ) {
|
||||
// remove anything other than a client
|
||||
if ( !other->client ) {
|
||||
// except CTF flags!!!!
|
||||
if( other->s.eType == ET_ITEM && other->item->giType == IT_TEAM ) {
|
||||
Team_DroppedFlagThink( other );
|
||||
return;
|
||||
}
|
||||
G_TempEntity( other->s.origin, EV_ITEM_POP );
|
||||
G_FreeEntity( other );
|
||||
return;
|
||||
|
@ -1189,7 +1185,7 @@ void Blocked_Door( gentity_t *ent, gentity_t *other ) {
|
|||
}
|
||||
|
||||
// reverse direction
|
||||
Use_BinaryMover( ent, ent, other );
|
||||
G_Mover_UseBinaryMover( ent, ent, other );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1224,10 +1220,10 @@ void DoorTriggerReactivate(gentity_t *ent);
|
|||
|
||||
/*
|
||||
================
|
||||
Touch_DoorTrigger
|
||||
G_Mover_TouchDoorTrigger
|
||||
================
|
||||
*/
|
||||
void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace ) {
|
||||
void G_Mover_TouchDoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace ) {
|
||||
#if 0
|
||||
vec3_t vec, doorcenter, movedir;
|
||||
float dot, dist ;
|
||||
|
@ -1275,7 +1271,7 @@ void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace ) {
|
|||
else if ( ent->parent->moverState != MOVER_1TO2 &&
|
||||
ent->parent->moverState != ROTATOR_1TO2 )
|
||||
{
|
||||
Use_BinaryMover( ent->parent, ent, other );
|
||||
G_Mover_UseBinaryMover( ent->parent, ent, other );
|
||||
}
|
||||
if(ent->parent->flags & FL_LOCKED) {
|
||||
ent->touch = 0;
|
||||
|
@ -1284,7 +1280,7 @@ void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace ) {
|
|||
}
|
||||
|
||||
void DoorTriggerReactivate(gentity_t *ent) {
|
||||
ent->touch = Touch_DoorTrigger;
|
||||
ent->touch = G_Mover_TouchDoorTrigger;
|
||||
ent->nextthink = -1;
|
||||
}
|
||||
|
||||
|
@ -1353,7 +1349,7 @@ void Think_SpawnNewDoorTrigger( gentity_t *ent ) {
|
|||
VectorCopy (maxs, other->r.maxs);
|
||||
other->parent = ent;
|
||||
other->r.contents = CONTENTS_TRIGGER;
|
||||
other->touch = Touch_DoorTrigger;
|
||||
other->touch = G_Mover_TouchDoorTrigger;
|
||||
// remember the thinnest axis
|
||||
other->count = best;
|
||||
//RPG-X | GSIO01 | 08/05/2009 | SOE = START OF EDIT ... lol
|
||||
|
@ -1462,31 +1458,46 @@ void DoorGetMessage(gentity_t *ent) {
|
|||
}
|
||||
|
||||
|
||||
/*QUAKED func_door (0 .5 .8) ? START_OPEN x CRUSHER TREK_DOOR FACE OVERRIDE LOCKED ADMIN_ONLY CORRIDOR
|
||||
START_OPEN the door to moves to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).
|
||||
x
|
||||
CRUSHER door will crush
|
||||
TREK_DOOR if set this door will have a reduced auto trigger volume
|
||||
FACE if set, this door requires you to be facing it before the trigger will fire
|
||||
OVERRIDE if set, targetted doors won't wait until they're clear before closing
|
||||
LOCKED if set, door is locked at spawn
|
||||
ADMIN_ONLY if set, door only opens for admins
|
||||
CORRIDOR if set, door will have en even more reduced auto trigger volume
|
||||
/*QUAKED func_door (0 .5 .8) ? START_OPEN X CRUSHER TREK_DOOR FACE OVERRIDE LOCKED ADMIN_ONLY CORRIDOR
|
||||
-----DESCRIPTION-----
|
||||
A door that moves between its two positions. Can only translate around one axis at a time.
|
||||
Can be teamed with multiple doors to trigger simultaniously.
|
||||
|
||||
"model2" .md3 model to also draw
|
||||
"angle" determines the opening direction
|
||||
"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
|
||||
"targetname2" for target_doorlock
|
||||
"speed" movement speed (100 default)
|
||||
"wait" wait before returning (3 default, -1 = never return)
|
||||
"lip" lip remaining at end of move (8 default)
|
||||
"dmg" damage to inflict when blocked (2 default)
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
"health" if set, the door must be shot open
|
||||
"soundstart" sound to play at start of moving
|
||||
"soundstop" sound to play at stop of moving
|
||||
"soundlocked" sound to play when locked
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_OPEN : the door to moves to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).
|
||||
2: X : Unknown, do not use.
|
||||
4: CRUSHER : door will be stuck on it's open position
|
||||
8: TREK_DOOR : if set this door will have a reduced auto trigger volume
|
||||
16: FACE : if set, this door requires you to be facing it before the trigger will fire
|
||||
32: OVERRIDE : if set, targetted doors won't wait until they're clear before closing
|
||||
64: LOCKED : if set, door is locked at spawn
|
||||
128: ADMIN_ONLY : if set, door only opens for admins
|
||||
256: CORRIDOR : if set, door will have en even more reduced auto trigger volume
|
||||
|
||||
-----KEYS-----
|
||||
"model2" - .md3 model to also draw
|
||||
"angle" - determines the opening direction
|
||||
"speed" - movement speed (100 default)
|
||||
"lip" - lip remaining at end of move (8 default)
|
||||
"dmg" - damage to inflict when blocked (2 default)
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
"health" - if set, the door must be shot open
|
||||
"soundstart" - sound to play at start of moving
|
||||
"soundstop" - sound to play at stop of moving
|
||||
"soundlocked" - sound to play when locked
|
||||
"team" - all doors that have the same team will move simultaniously
|
||||
|
||||
Ther following keys are only required on one in a team of doors (master door)
|
||||
"targetname" - if set, no touch field will be spawned and a remote button or trigger field activates the door.
|
||||
"targetname2" - for target_doorlock.
|
||||
"wait" - wait before returning (3 default, -1 = never return)
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void SP_func_door (gentity_t *ent) {
|
||||
vec3_t abs_movedir;
|
||||
|
@ -1625,13 +1636,13 @@ void Touch_PlatCenterTrigger(gentity_t *ent, gentity_t *other, trace_t *trace )
|
|||
#endif
|
||||
|
||||
if ( ent->parent->moverState == MOVER_POS1 ) {
|
||||
Use_BinaryMover( ent->parent, ent, other );
|
||||
G_Mover_UseBinaryMover( ent->parent, ent, other );
|
||||
}
|
||||
}
|
||||
|
||||
void func_plat_use(gentity_t *ent, gentity_t *other, gentity_t *activator) {
|
||||
if (ent->parent->moverState == MOVER_POS1 ) {
|
||||
Use_BinaryMover(ent->parent, other, activator);
|
||||
G_Mover_UseBinaryMover(ent->parent, other, activator);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1681,18 +1692,29 @@ void SpawnPlatTrigger( gentity_t *ent ) {
|
|||
|
||||
|
||||
/*QUAKED func_plat (0 .5 .8) NO_TOUCH
|
||||
-----DESCRIPTION-----
|
||||
Binary mover...I don't know much more until I have tested it...
|
||||
Plats are always drawn in the extended position so they will light correctly.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
NO_TOUCH - instead of staying up as long as someone touches it, it will wait "wait" seconds and return
|
||||
|
||||
"targetname" if targeted will only move when used
|
||||
"lip" default 8, protrusion above rest position
|
||||
"height" total height of movement, defaults to model height
|
||||
"speed" overrides default 200.
|
||||
"dmg" overrides default 2
|
||||
"model2" .md3 model to also draw
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
"wait" how many seconds to wait before returning
|
||||
-----KEYS-----
|
||||
"targetname" - if targeted will only move when used
|
||||
"lip" - default 8, protrusion above rest position
|
||||
"height" - total height of movement, defaults to model height
|
||||
"speed" - overrides default 200.
|
||||
"dmg" - overrides default 2
|
||||
"model2" - .md3 model to also draw
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
"wait" - how many seconds to wait before returning
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void SP_func_plat (gentity_t *ent) {
|
||||
float lip, height;
|
||||
|
@ -1775,23 +1797,34 @@ void Touch_Button(gentity_t *ent, gentity_t *other, trace_t *trace ) {
|
|||
#endif
|
||||
|
||||
if ( ent->moverState == MOVER_POS1 ) {
|
||||
Use_BinaryMover( ent, other, other );
|
||||
G_Mover_UseBinaryMover( ent, other, other );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED func_button (0 .5 .8) ?
|
||||
-----DESCRIPTION-----
|
||||
When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
|
||||
|
||||
"model2" .md3 model to also draw
|
||||
"angle" determines the opening direction
|
||||
"target" all entities with a matching targetname will be used
|
||||
"speed" override the default 40 speed
|
||||
"wait" override the default 1 second wait (-1 = never return)
|
||||
"lip" override the default 4 pixel lip remaining at end of move
|
||||
"health" if set, the button must be killed instead of touched
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"model2" - .md3 model to also draw
|
||||
"angle" - determines the opening direction
|
||||
"target" - all entities with a matching targetname will be used
|
||||
"speed" - override the default 40 speed
|
||||
"wait" - override the default 1 second wait (-1 = never return)
|
||||
"lip" - override the default 4 pixel lip remaining at end of move
|
||||
"health" - if set, the button must be killed instead of touched
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void SP_func_button( gentity_t *ent ) {
|
||||
vec3_t abs_movedir;
|
||||
|
@ -1994,10 +2027,16 @@ void Think_SetupTrainTargets( gentity_t *ent ) {
|
|||
|
||||
|
||||
/*QUAKED path_corner (.5 .3 0) (-8 -8 -8) (8 8 8)
|
||||
Train path corners.
|
||||
Target: next path corner and other targets to fire
|
||||
"speed" speed to move to the next corner
|
||||
"wait" seconds to wait before behining move to next corner
|
||||
-----DESCRIPTION-----
|
||||
func_train path corners.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - next path corner and other targets to fire
|
||||
"speed" - speed to move to the next corner
|
||||
"wait" - seconds to wait before behining move to next corner
|
||||
*/
|
||||
void SP_path_corner( gentity_t *self ) {
|
||||
if ( !self->targetname ) {
|
||||
|
@ -2011,17 +2050,33 @@ void SP_path_corner( gentity_t *self ) {
|
|||
|
||||
|
||||
/*QUAKED func_train (0 .5 .8) ? START_ON TOGGLE BLOCK_STOPS START_INVISIBLE
|
||||
-----DESCRIPTION-----
|
||||
A train is a mover that moves between path_corner target points.
|
||||
Can be turned invisible.
|
||||
Trains MUST HAVE AN ORIGIN BRUSH.
|
||||
The train spawns at the first target it is pointing at.
|
||||
"model2" .md3 model to also draw
|
||||
"speed" default 100
|
||||
"dmg" default 2
|
||||
"noise" looping sound to play when the train is in motion
|
||||
"target" next path corner
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
"swapname" targetname for visiblility change
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_ON - the train will begin to move after spawn
|
||||
2: TOGGLE - the train can be toggled
|
||||
4: BLOCK_STOPS - the train will stop if blocked
|
||||
8: START_INVISIBLE - the train will be invisible at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"model2" - .md3 model to also draw
|
||||
"speed" - default 100
|
||||
"dmg" - default 2
|
||||
"noise" - looping sound to play when the train is in motion
|
||||
"target" - next path corner
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
"swapname" - targetname for visiblility change
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void SP_func_train (gentity_t *self) {
|
||||
VectorClear (self->s.angles);
|
||||
|
@ -2077,10 +2132,24 @@ STATIC
|
|||
|
||||
|
||||
/*QUAKED func_static (0 .5 .8) ?
|
||||
A bmodel that just sits there, doing nothing. Can be used for conditional walls and models.
|
||||
"model2" .md3 model to also draw
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
-----DESCRIPTION-----
|
||||
A bmodel that just sits there, doing nothing.
|
||||
Can be used for conditional walls and models.
|
||||
If it has an origin-Brush it can be moved using Lua.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"model2" - .md3 model to also draw
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void SP_func_static( gentity_t *ent ) {
|
||||
trap_SetBrushModel( ent, ent->model );
|
||||
|
@ -2296,30 +2365,43 @@ static void forcefield_touch( gentity_t *ent, gentity_t *other, trace_t *trace )
|
|||
|
||||
#define SF_USEABLE (1<<0)
|
||||
|
||||
/*QUAKED func_forcefield (0 .5 .8) ? STARTOFF DONTTOGGLE ADMINS AUTOANIM x x x x NO_BORG
|
||||
/*QUAKED func_forcefield (0 .5 .8) ? STARTOFF DONTTOGGLE ADMINS AUTOANIM X X X X NO_BORG
|
||||
-----DESCRIPTION-----
|
||||
A brush that remains invisible until it is contacted by a player, where it temporarily
|
||||
becomes visible
|
||||
becomes visible.
|
||||
|
||||
STARTOFF - Spawns in an off state, and must be used to be activated
|
||||
DONTTOGGLE - This entity cannot be used to be switched on and off (ie always on)
|
||||
ADMINS - Players in admin classes can move through the field
|
||||
AUTOANIM - If a model is spawned with it, it will animate at 10FPS repeatedly
|
||||
NO_BORG - If set, borg can't move through
|
||||
-----SPAWNFLAGS-----
|
||||
1: STARTOFF - Spawns in an off state, and must be used to be activated
|
||||
2: DONTTOGGLE - This entity cannot be used to be switched on and off (ie always on)
|
||||
4: ADMINS - Players in admin classes can move through the field
|
||||
8: AUTOANIM - If a model is spawned with it, it will animate at 10FPS repeatedly
|
||||
16: X - Unknown, do not use
|
||||
32: X - Unknown, do not use
|
||||
64: X - Unknown, do not use
|
||||
128: X - Unknown, do not use
|
||||
256: NO_BORG - If set, borg can't move through
|
||||
|
||||
"flareWait" How long the forcefield remains visible after the player contacts it (milliseconds)(default 150)
|
||||
"activateWait" How long the forcefield remains visible after activation/deactivation(default 500)
|
||||
"damageWait" How long the forecefield remains visible after it has been shot (default 400)
|
||||
"kickback" How far the player gets pushed back when they touch the forcefield (default 50)
|
||||
"damage" Damage sustained when the player touches the field (default 0 )
|
||||
"target" Will fire this target every time it is toggled
|
||||
"model2" .md3 model to also draw
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
"activateSnd" sound file to play when the field is activated
|
||||
"damageSnd" sound to play when the field is shot
|
||||
"touchSnd" sound to play if the field is contacted by a player.
|
||||
"deactivateSnd" sound to play when the field is turned off
|
||||
"hittarget" target to fire when hit
|
||||
-----KEYS-----
|
||||
"flareWait" - How long the forcefield remains visible after the player contacts it (milliseconds)(default 150)
|
||||
"activateWait" - How long the forcefield remains visible after activation/deactivation(default 500)
|
||||
"damageWait" - How long the forecefield remains visible after it has been shot (default 400)
|
||||
"kickback" - How far the player gets pushed back when they touch the forcefield (default 50)
|
||||
"damage" - Damage sustained when the player touches the field (default 0 )
|
||||
"target" - Will fire this target every time it is toggled
|
||||
"model2" - .md3 model to also draw
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
"activateSnd" - sound file to play when the field is activated
|
||||
"damageSnd" - sound to play when the field is shot
|
||||
"touchSnd" - sound to play if the field is contacted by a player.
|
||||
"deactivateSnd" - sound to play when the field is turned off
|
||||
"hittarget" - target to fire when hit
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void SP_func_forcefield( gentity_t *ent )
|
||||
{
|
||||
|
@ -2399,11 +2481,22 @@ ROTATING
|
|||
*/
|
||||
|
||||
|
||||
/*QUAKED func_rotating (0 .5 .8) ? START_ON x X_AXIS Y_AXIS x INVISIBLE IGNORE
|
||||
You need to have an origin brush as part of this entity. The center of that brush will be
|
||||
/*QUAKED func_rotating (0 .5 .8) ? START_ON X X_AXIS Y_AXIS x INVISIBLE NO_TOGGLE
|
||||
-----DESCRIPTION-----
|
||||
You need to have an origin brush as part of this entity. The center of that brush will be
|
||||
the point around which it is rotated. It will rotate around the Z axis by default. You can
|
||||
check either the X_AXIS or Y_AXIS box to change that.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_ON - entity will move at spawn
|
||||
2: X - Unknown, do not use
|
||||
4: X-AXIS - rotate around the X-Axis
|
||||
8: Y-AXIS - rotate around the Y-Axis
|
||||
16: X - Unknown, do not use
|
||||
32: INVISIBLE - will be invisible at spawn
|
||||
64: NO_TOGGLE - will not be toggable
|
||||
|
||||
-----KEYS-----
|
||||
"model2" .md3 model to also draw
|
||||
"speed" determines how fast it moves; default value is 100.
|
||||
"dmg" damage to inflict when blocked (2 default)
|
||||
|
@ -2412,6 +2505,12 @@ check either the X_AXIS or Y_AXIS box to change that.
|
|||
"swapname" visibility swap (activator needs NO_ACTIVATOR/SELF)
|
||||
|
||||
"pos1" Angles to end up at in addition to current angles- pitch yaw and roll. Eg: 0 90 45
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
|
||||
//RPG-X Use Function
|
||||
|
@ -2451,7 +2550,7 @@ void SP_func_rotating (gentity_t *ent) {
|
|||
ent->distance = 0;
|
||||
}
|
||||
|
||||
//ent->use = func_rotating_use; //RPG-X | GSIO01 --- weren't you aware that InitMover sets the use func to Use_BinaryMover Phenix??
|
||||
//ent->use = func_rotating_use; //RPG-X | GSIO01 --- weren't you aware that InitMover sets the use func to G_Mover_UseBinaryMover Phenix??
|
||||
|
||||
if (!ent->booleanstate)
|
||||
{
|
||||
|
@ -2548,27 +2647,41 @@ void SP_func_rotating (gentity_t *ent) {
|
|||
|
||||
|
||||
/*QUAKED func_door_rotating (0 .5 .8) ? START_OPEN CRUSHER REVERSE X_AXIS Y_AXIS LOCKED ADMIN_ONLY CORRIDOR
|
||||
This is the rotating door... just as the name suggests it's a door that rotates
|
||||
START_OPEN the door to moves to its destination when spawned, and operate in reverse.
|
||||
REVERSE if you want the door to open in the other direction, use this switch.
|
||||
TOGGLE wait in both the start and end states for a trigger event.
|
||||
X_AXIS open on the X-axis instead of the Z-axis
|
||||
Y_AXIS open on the Y-axis instead of the Z-axis
|
||||
-----DESCRIPTION-----
|
||||
This is the rotating door... just as the name suggests it's a door that rotates around it's origin Brush.
|
||||
The Axis to rotate around is determined by spawnflag.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_OPEN - the door to moves to its destination when spawned, and operate in reverse.
|
||||
2: CRUSHER - The door will stick in it's end position
|
||||
4: REVERSE - if you want the door to open in the other direction, use this switch.
|
||||
8: X_AXIS - rotate around the X-axis instead of the Z-axis
|
||||
16: Y_AXIS - rotate around the Y-axis instead of the Z-axis
|
||||
32: LOCKED - Door is locked at spawn
|
||||
64: ADMIN_ONLY - only admins can use this door
|
||||
128: CORRIDOR - will have a reduced autotrigger volume.
|
||||
|
||||
You need to have an origin brush as part of this entity. The center of that brush will be
|
||||
the point around which it is rotated. It will rotate around the Z axis by default. You can
|
||||
check either the X_AXIS or Y_AXIS box to change that.
|
||||
|
||||
"model2" .md3 model to also draw
|
||||
"distance" how many degrees the door will open
|
||||
"speed" how fast the door will open (degrees/second)
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
"targetname" door can only open/close when used by anonther entity
|
||||
"targetname2" for target_doorlock
|
||||
"soundstart" sound played when start moving
|
||||
"soundstop" sound played when stop moving
|
||||
"soundlocked" sound played when locked
|
||||
"model2" - .md3 model to also draw
|
||||
"distance" - how many degrees the door will open
|
||||
"speed" - how fast the door will open (degrees/second)
|
||||
"wait" - time to wait before returning, default = 2, -1 = move on toggle
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
"targetname" - door can only open/close when used by anonther entity
|
||||
"targetname2" - for target_doorlock
|
||||
"soundstart" - sound played when start moving
|
||||
"soundstop" - sound played when stop moving
|
||||
"soundlocked" - sound played when locked
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
|
||||
void SP_func_door_rotating ( gentity_t *ent ) {
|
||||
|
@ -2678,14 +2791,28 @@ BOBBING
|
|||
|
||||
|
||||
/*QUAKED func_bobbing (0 .5 .8) ? X_AXIS Y_AXIS
|
||||
-----DESCRIPTION-----
|
||||
Don't now what this looks like.
|
||||
Normally bobs on the Z axis
|
||||
"model2" .md3 model to also draw
|
||||
"height" amplitude of bob (32 default)
|
||||
"speed" seconds to complete a bob cycle (4 default)
|
||||
"phase" the 0.0 to 1.0 offset in the cycle to start at
|
||||
"dmg" damage to inflict when blocked (2 default)
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: X-AXIS - bobs on the X-Axis
|
||||
2: Y-AXIS - bobs on the Y-Axis
|
||||
|
||||
-----KEYS-----
|
||||
"model2" - .md3 model to also draw
|
||||
"height" - amplitude of bob (32 default)
|
||||
"speed" - seconds to complete a bob cycle (4 default)
|
||||
"phase" - the 0.0 to 1.0 offset in the cycle to start at
|
||||
"dmg" - damage to inflict when blocked (2 default)
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void SP_func_bobbing (gentity_t *ent) {
|
||||
float height;
|
||||
|
@ -2733,15 +2860,27 @@ PENDULUM
|
|||
|
||||
|
||||
/*QUAKED func_pendulum (0 .5 .8) ?
|
||||
-----DESCRIPTION-----
|
||||
You need to have an origin brush as part of this entity.
|
||||
Pendulums always swing north / south on unrotated models. Add an angles field to the model to allow rotation in other directions.
|
||||
Pendulum frequency is a physical constant based on the length of the beam and gravity.
|
||||
"model2" .md3 model to also draw
|
||||
"speed" the number of degrees each way the pendulum swings, (30 default)
|
||||
"phase" the 0.0 to 1.0 offset in the cycle to start at
|
||||
"dmg" damage to inflict when blocked (2 default)
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"model2" - .md3 model to also draw
|
||||
"speed" - the number of degrees each way the pendulum swings, (30 default)
|
||||
"phase" - the 0.0 to 1.0 offset in the cycle to start at
|
||||
"dmg" - damage to inflict when blocked (2 default)
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void SP_func_pendulum(gentity_t *ent) {
|
||||
float freq;
|
||||
|
@ -2789,9 +2928,22 @@ LIGHTING CHANGE --- sort of :D
|
|||
*/
|
||||
|
||||
/*QUAKED func_brushmodel (0 .5 .8) ?
|
||||
-----DESCRIPTION-----
|
||||
A brushmodel.
|
||||
For use with func_lightchange.
|
||||
Must have an origin brush.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - have this be the target of a func_lightchange
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void SP_func_brushmodel(gentity_t *ent) {
|
||||
trap_SetBrushModel(ent, ent->model);
|
||||
|
@ -2803,9 +2955,22 @@ void SP_func_brushmodel(gentity_t *ent) {
|
|||
}
|
||||
|
||||
/*QUAKED func_lightchange (0 .5 .8) ?
|
||||
-----DESCRIPTION-----
|
||||
Can be used for "toggling" light on/off.
|
||||
Must target a func_brushmodel.
|
||||
Must have an origin brush.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - func_brushmodel to swap positions with
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void func_lightchange_use(gentity_t *ent, gentity_t *other, gentity_t *activator) {
|
||||
char *oldModel;
|
||||
|
@ -2871,12 +3036,23 @@ TARGET MOVER
|
|||
*/
|
||||
|
||||
/*QUAKED func_targetmover (0 .5 .8) ? START_OPEN
|
||||
This work similar to an func_door but will move between the entities origin and an target origin.
|
||||
-----DESCRIPTION-----
|
||||
This work similar to an func_door but will move between the entities origin (requires origin brush) and an target origin.
|
||||
Added for enhanced SP level support, that's why it is a quite basic entity.
|
||||
|
||||
"target" info_notnull, where to move
|
||||
"wait" time beforce returning, -1 = toggle
|
||||
"speed" speed to move with (default: 200)
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_OPEN - will spawn at target position
|
||||
|
||||
-----KEYS-----
|
||||
"target" - info_notnull, where to move
|
||||
"wait" - time beforce returning, -1 = toggle
|
||||
"speed" - speed to move with (default: 200)
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
void func_targetmover_link(gentity_t *ent) {
|
||||
gentity_t *target;
|
||||
|
@ -2968,7 +3144,7 @@ ADVANCED MOVER
|
|||
*/
|
||||
|
||||
void Move_AdvancedMover(gentity_t *ent) {
|
||||
Use_BinaryMover(ent, NULL, ent->activator);
|
||||
G_Mover_UseBinaryMover(ent, NULL, ent->activator);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3005,7 +3181,7 @@ void Reached_AdvancedMover(gentity_t *ent) {
|
|||
|
||||
if( touched->wait < 0) {
|
||||
ent->nextthink = -1; // wait here until used again
|
||||
ent->use = Use_BinaryMover;
|
||||
ent->use = G_Mover_UseBinaryMover;
|
||||
if(ent->damage) {
|
||||
temp = G_Find(NULL, FOFS(targetname), touched->target);
|
||||
if(!temp) {
|
||||
|
@ -3117,12 +3293,17 @@ void Reached_AdvancedMover(gentity_t *ent) {
|
|||
}
|
||||
|
||||
/*QUAKED path_point (.5 .3 0) (-8 8 8) (8 8 8) START_POINT
|
||||
START_POINT this is the first path_point for the train
|
||||
-----DESCRIPTION-----
|
||||
Target position for the discontinued func_mover
|
||||
|
||||
"target" next path_point
|
||||
"wait" time beforce moving on, -1 wait until used
|
||||
"damage" used to tell the func_mover it should fire it's targets here
|
||||
"angles" to rotate to
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_POINT - this is the first path_point for the train
|
||||
|
||||
-----KEYS-----
|
||||
"target" - next path_point
|
||||
"wait" - time beforce moving on, -1 wait until used
|
||||
"damage" - used to tell the func_mover it should fire it's targets here
|
||||
"angles" - to rotate to
|
||||
*/
|
||||
void SP_path_point(gentity_t *ent) {
|
||||
// check if angles are set
|
||||
|
@ -3133,10 +3314,23 @@ void SP_path_point(gentity_t *ent) {
|
|||
}
|
||||
|
||||
/*QUAKED func_mover (0 .5 .8) ?
|
||||
-----DESCRIPTION-----
|
||||
Discontinued enhanced mover requiring an origin brush.
|
||||
Use Lua for this now.
|
||||
|
||||
"target" path_point to start at
|
||||
"speed" speed to move with (default: 10)
|
||||
"aspeed" angular speed to rotate with (default: 10)
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - path_point to start at
|
||||
"speed" - speed to move with (default: 10)
|
||||
"aspeed" - angular speed to rotate with (default: 10)
|
||||
|
||||
q3map2:
|
||||
"_clone" - _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" - see _clone
|
||||
"_castShadows" OR "_cs" - sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" - sets whether the entity receives shadows
|
||||
*/
|
||||
|
||||
void SP_func_mover(gentity_t *ent) {
|
||||
|
@ -3360,14 +3554,16 @@ void spawn_trigger_stasis_door( gentity_t *ent ) {
|
|||
|
||||
//-------------------------------------------
|
||||
/*QUAKED func_stasis_door (0 .5 .8) START_LOCKED
|
||||
-----DESCRIPTION-----
|
||||
A bmodel that just sits there and opens when a player gets close to it.
|
||||
|
||||
START_LOCKED: door is locked at spawn
|
||||
|
||||
"targetname" will open the door
|
||||
"swapname" will lock the door (SELF/NO_ACTIVATOR needed)
|
||||
"wait" time to wait before closing, -1 for manual trigger, default is 5 seconds
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_LOCKED - door is locked at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"targetname" - will open the door
|
||||
"swapname" - will lock the door (SELF/NO_ACTIVATOR needed)
|
||||
"wait" - time to wait before closing, -1 for manual trigger, default is 5 seconds
|
||||
*/
|
||||
void SP_func_stasis_door( gentity_t *ent )
|
||||
{
|
||||
|
|
156
game/g_spawn.c
156
game/g_spawn.c
|
@ -118,7 +118,6 @@ typedef struct {
|
|||
void (*spawn)(gentity_t *ent);
|
||||
} spawn_t;
|
||||
|
||||
void SP_info_player_start (gentity_t *ent);
|
||||
void SP_info_player_deathmatch (gentity_t *ent);
|
||||
void SP_info_player_intermission (gentity_t *ent);
|
||||
void SP_info_firstplace(gentity_t *ent);
|
||||
|
@ -159,11 +158,9 @@ void SP_target_speaker (gentity_t *ent);
|
|||
void SP_target_print (gentity_t *ent);
|
||||
void SP_target_laser (gentity_t *self);
|
||||
void SP_target_character (gentity_t *ent);
|
||||
void SP_target_score( gentity_t *ent );
|
||||
void SP_target_teleporter( gentity_t *ent );
|
||||
void SP_target_relay (gentity_t *ent);
|
||||
void SP_target_kill (gentity_t *ent);
|
||||
void SP_target_position (gentity_t *ent);
|
||||
void SP_target_location (gentity_t *ent);
|
||||
void SP_target_push (gentity_t *ent);
|
||||
void SP_target_counter (gentity_t *self);
|
||||
|
@ -191,7 +188,6 @@ void SP_info_notnull (gentity_t *self);
|
|||
void SP_info_camp (gentity_t *self);
|
||||
void SP_path_corner (gentity_t *self);
|
||||
|
||||
void SP_misc_teleporter_dest (gentity_t *self);
|
||||
void SP_misc_model(gentity_t *ent);
|
||||
void SP_misc_model_breakable(gentity_t *ent);
|
||||
void SP_misc_portal_camera(gentity_t *ent);
|
||||
|
@ -205,12 +201,6 @@ void SP_shooter_plasma( gentity_t *ent );
|
|||
void SP_shooter_grenade( gentity_t *ent );
|
||||
void SP_shooter_torpedo( gentity_t *ent );
|
||||
|
||||
void SP_team_CTF_redplayer( gentity_t *ent );
|
||||
void SP_team_CTF_blueplayer( gentity_t *ent );
|
||||
|
||||
void SP_team_CTF_redspawn( gentity_t *ent );
|
||||
void SP_team_CTF_bluespawn( gentity_t *ent );
|
||||
|
||||
// extra Trek stuff
|
||||
void SP_fx_spark ( gentity_t *ent );
|
||||
void SP_fx_steam ( gentity_t *ent );
|
||||
|
@ -251,6 +241,7 @@ void SP_path_point(gentity_t *ent);
|
|||
|
||||
// ui entities
|
||||
void SP_ui_transporter(gentity_t *ent);
|
||||
void SP_ui_msd(gentity_t *ent);
|
||||
void SP_ui_holodeck(gentity_t *ent);
|
||||
|
||||
// cinematic entities
|
||||
|
@ -260,57 +251,57 @@ void SP_cinematic_camera(gentity_t *ent);
|
|||
spawn_t spawns[] = {
|
||||
// info entities don't do anything at all, but provide positional
|
||||
// information for things controlled by other processes
|
||||
{"info_player_start", SP_info_player_start},
|
||||
{"info_player_start", SP_info_player_deathmatch},
|
||||
|
||||
{"NPC_BioHulk", SP_info_player_start},
|
||||
{"NPC_starfleet", SP_info_player_start},
|
||||
{"NPC_starfleet_random", SP_info_player_start},
|
||||
{"NPC_Tuvok", SP_info_player_start},
|
||||
{"NPC_Kim", SP_info_player_start},
|
||||
{"NPC_Doctor", SP_info_player_start},
|
||||
{"NPC_Paris", SP_info_player_start},
|
||||
{"NPC_Torres", SP_info_player_start},
|
||||
{"NPC_Janeway", SP_info_player_start},
|
||||
{"NPC_Seven", SP_info_player_start},
|
||||
{"NPC_Chakotay", SP_info_player_start},
|
||||
{"NPC_Neelix", SP_info_player_start},
|
||||
{"NPC_Vorik", SP_info_player_start},
|
||||
{"NPC_Foster", SP_info_player_start},
|
||||
{"NPC_Munro", SP_info_player_start},
|
||||
{"NPC_MunroScav", SP_info_player_start},
|
||||
{"NPC_Telsia", SP_info_player_start},
|
||||
{"NPC_Biessman", SP_info_player_start},
|
||||
{"NPC_Chang", SP_info_player_start},
|
||||
{"NPC_Chell", SP_info_player_start},
|
||||
{"NPC_Jurot", SP_info_player_start},
|
||||
{"NPC_borg", SP_info_player_start},
|
||||
{"NPC_klingon", SP_info_player_start},
|
||||
{"NPC_Malon", SP_info_player_start},
|
||||
{"NPC_Hirogen", SP_info_player_start},
|
||||
{"NPC_Hirogen_Alpha", SP_info_player_start},
|
||||
{"NPC_Imperial", SP_info_player_start},
|
||||
{"NPC_Imperial_Blue", SP_info_player_start},
|
||||
{"NPC_Imperial_Gold", SP_info_player_start},
|
||||
{"NPC_Imperial_Raider", SP_info_player_start},
|
||||
{"NPC_Stasis", SP_info_player_start},
|
||||
{"NPC_Species8472", SP_info_player_start},
|
||||
{"NPC_Reaver", SP_info_player_start},
|
||||
{"NPC_ReaverGuard", SP_info_player_start},
|
||||
{"NPC_Avatar", SP_info_player_start},
|
||||
{"NPC_Vohrsoth", SP_info_player_start},
|
||||
{"NPC_Desperado", SP_info_player_start},
|
||||
{"NPC_Paladin", SP_info_player_start},
|
||||
{"NPC_ChaoticaGuard", SP_info_player_start},
|
||||
{"NPC_Chaotica", SP_info_player_start},
|
||||
{"NPC_CaptainProton", SP_info_player_start},
|
||||
{"NPC_SatansRobot", SP_info_player_start},
|
||||
{"NPC_Buster", SP_info_player_start},
|
||||
{"NPC_Goodheart", SP_info_player_start},
|
||||
{"NPC_BioHulk", SP_info_player_deathmatch},
|
||||
{"NPC_starfleet", SP_info_player_deathmatch},
|
||||
{"NPC_starfleet_random", SP_info_player_deathmatch},
|
||||
{"NPC_Tuvok", SP_info_player_deathmatch},
|
||||
{"NPC_Kim", SP_info_player_deathmatch},
|
||||
{"NPC_Doctor", SP_info_player_deathmatch},
|
||||
{"NPC_Paris", SP_info_player_deathmatch},
|
||||
{"NPC_Torres", SP_info_player_deathmatch},
|
||||
{"NPC_Janeway", SP_info_player_deathmatch},
|
||||
{"NPC_Seven", SP_info_player_deathmatch},
|
||||
{"NPC_Chakotay", SP_info_player_deathmatch},
|
||||
{"NPC_Neelix", SP_info_player_deathmatch},
|
||||
{"NPC_Vorik", SP_info_player_deathmatch},
|
||||
{"NPC_Foster", SP_info_player_deathmatch},
|
||||
{"NPC_Munro", SP_info_player_deathmatch},
|
||||
{"NPC_MunroScav", SP_info_player_deathmatch},
|
||||
{"NPC_Telsia", SP_info_player_deathmatch},
|
||||
{"NPC_Biessman", SP_info_player_deathmatch},
|
||||
{"NPC_Chang", SP_info_player_deathmatch},
|
||||
{"NPC_Chell", SP_info_player_deathmatch},
|
||||
{"NPC_Jurot", SP_info_player_deathmatch},
|
||||
{"NPC_borg", SP_info_player_deathmatch},
|
||||
{"NPC_klingon", SP_info_player_deathmatch},
|
||||
{"NPC_Malon", SP_info_player_deathmatch},
|
||||
{"NPC_Hirogen", SP_info_player_deathmatch},
|
||||
{"NPC_Hirogen_Alpha", SP_info_player_deathmatch},
|
||||
{"NPC_Imperial", SP_info_player_deathmatch},
|
||||
{"NPC_Imperial_Blue", SP_info_player_deathmatch},
|
||||
{"NPC_Imperial_Gold", SP_info_player_deathmatch},
|
||||
{"NPC_Imperial_Raider", SP_info_player_deathmatch},
|
||||
{"NPC_Stasis", SP_info_player_deathmatch},
|
||||
{"NPC_Species8472", SP_info_player_deathmatch},
|
||||
{"NPC_Reaver", SP_info_player_deathmatch},
|
||||
{"NPC_ReaverGuard", SP_info_player_deathmatch},
|
||||
{"NPC_Avatar", SP_info_player_deathmatch},
|
||||
{"NPC_Vohrsoth", SP_info_player_deathmatch},
|
||||
{"NPC_Desperado", SP_info_player_deathmatch},
|
||||
{"NPC_Paladin", SP_info_player_deathmatch},
|
||||
{"NPC_ChaoticaGuard", SP_info_player_deathmatch},
|
||||
{"NPC_Chaotica", SP_info_player_deathmatch},
|
||||
{"NPC_CaptainProton", SP_info_player_deathmatch},
|
||||
{"NPC_SatansRobot", SP_info_player_deathmatch},
|
||||
{"NPC_Buster", SP_info_player_deathmatch},
|
||||
{"NPC_Goodheart", SP_info_player_deathmatch},
|
||||
|
||||
{"info_player_deathmatch", SP_info_player_deathmatch},
|
||||
{"info_player_intermission", SP_info_player_intermission},
|
||||
{"info_null", SP_info_null},
|
||||
{"info_notnull", SP_info_notnull}, // use target_position instead
|
||||
{"info_notnull", SP_info_notnull},
|
||||
{"info_camp", SP_info_camp},
|
||||
|
||||
{"func_plat", SP_func_plat},
|
||||
|
@ -353,11 +344,10 @@ spawn_t spawns[] = {
|
|||
{"target_speaker", SP_target_speaker},
|
||||
{"target_print", SP_target_print},
|
||||
{"target_laser", SP_target_laser},
|
||||
{"target_score", SP_target_score},
|
||||
{"target_teleporter", SP_target_teleporter},
|
||||
{"target_relay", SP_target_relay},
|
||||
{"target_kill", SP_target_kill},
|
||||
{"target_position", SP_target_position},
|
||||
{"target_position", SP_info_notnull},
|
||||
{"target_location", SP_target_location},
|
||||
{"target_push", SP_target_push},
|
||||
{"target_counter", SP_target_counter},
|
||||
|
@ -382,7 +372,7 @@ spawn_t spawns[] = {
|
|||
{"light", SP_light},
|
||||
{"path_corner", SP_path_corner},
|
||||
|
||||
{"misc_teleporter_dest", SP_misc_teleporter_dest},
|
||||
{"misc_teleporter_dest", SP_info_notnull},
|
||||
{"misc_model", SP_misc_model},
|
||||
{"misc_model_breakable", SP_misc_model_breakable},
|
||||
{"misc_portal_surface", SP_misc_portal_surface},
|
||||
|
@ -396,11 +386,11 @@ spawn_t spawns[] = {
|
|||
{"shooter_plasma", SP_shooter_plasma},
|
||||
{"shooter_torpedo", SP_shooter_torpedo},
|
||||
|
||||
{"team_CTF_redplayer", SP_team_CTF_redplayer},
|
||||
{"team_CTF_blueplayer", SP_team_CTF_blueplayer},
|
||||
{"team_CTF_redplayer", SP_info_player_deathmatch},
|
||||
{"team_CTF_blueplayer", SP_info_player_deathmatch},
|
||||
|
||||
{"team_CTF_redspawn", SP_team_CTF_redspawn},
|
||||
{"team_CTF_bluespawn", SP_team_CTF_bluespawn},
|
||||
{"team_CTF_redspawn", SP_info_player_deathmatch},
|
||||
{"team_CTF_bluespawn", SP_info_player_deathmatch},
|
||||
|
||||
// extra Trek stuff
|
||||
{"fx_spark", SP_fx_spark},
|
||||
|
@ -435,6 +425,7 @@ spawn_t spawns[] = {
|
|||
|
||||
// ui entities
|
||||
{"ui_transporter", SP_ui_transporter},
|
||||
{"ui_msd", SP_ui_msd},
|
||||
{"ui_holodeck", SP_ui_holodeck},
|
||||
|
||||
{"ref_tag", SP_info_notnull},
|
||||
|
@ -772,16 +763,39 @@ qboolean G_ParseSpawnVars( void ) {
|
|||
|
||||
|
||||
/*QUAKED worldspawn (0 0 0) ?
|
||||
|
||||
-----DESCRIPTION-----
|
||||
Every map should have exactly one worldspawn.
|
||||
"music" path to WAV or MP3 files (e.g. "music\intro.mp3 music\loopfile.mp3")
|
||||
"gravity" 800 is default gravity
|
||||
"message" Text to print during connection process
|
||||
It holds some general information on the map.
|
||||
|
||||
fraglimit - overrides server's limit
|
||||
capturelimit - overrides server's capturelimit (use with team AddScores)
|
||||
timelimit - overrides server's timelimit
|
||||
timelimitWinningTeam - "red" or "blue" - this team will win when the timelimit runs out
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"music" - path to WAV or MP3 files (e.g. "music\intro.mp3 music\loopfile.mp3")
|
||||
"gravity" - 800 is default gravity
|
||||
"message" - Text to print during connection process
|
||||
|
||||
Keys irrelevant for RPG-X
|
||||
"fraglimit" - overrides server's limit
|
||||
"capturelimit" - overrides server's capturelimit (use with team AddScores)
|
||||
"timelimit" - overrides server's timelimit
|
||||
"timelimitWinningTeam" - "red" or "blue" - this team will win when the timelimit runs out
|
||||
|
||||
q3map2:
|
||||
"_blocksize" block size for unconditional BSP subdivisions
|
||||
"_celshader" use the specified cel shader for the world
|
||||
"_lightmapscale" set the lightmapscale for the world
|
||||
"_ignoreleaks" when set, no leak test is performed
|
||||
"_foghull" must be set to a sky shader when _fog is used
|
||||
"_fog" if set, the whole map is fogged using the given shader name
|
||||
"gridsize" resolution of the light grid
|
||||
"_ambient" amount of ambient light
|
||||
"_minvertexlight" amount of minimum vertex light
|
||||
"_mingridlight" amount of minimum grid light
|
||||
"_minlight" amount of minimum light
|
||||
"_keepLights" if set, light entities are not stripped from the BSP file when compiling
|
||||
"_style42rgbgen" |rgbGen|-like shader definition string for light style 42 (works the same way for all style numbers)
|
||||
"_style42alphagen" |alphaGen|-like shader definition string for light style 42 (works the same way for all style numbers)
|
||||
*/
|
||||
void SP_worldspawn( void ) {
|
||||
char *s;
|
||||
|
|
|
@ -84,7 +84,7 @@ typedef enum {
|
|||
SQLF_MESSAGE = 16384,
|
||||
SQLF_DEBUG = 32768, //Debugging Tools
|
||||
SQLF_MUSIC = 65536,
|
||||
SQLF_UITRANS = 131072,
|
||||
//unused = 131072,
|
||||
SQLF_USEENT = 262144,
|
||||
SQLF_BEAM = 524288,
|
||||
//unused = 1048576,
|
||||
|
|
784
game/g_target.c
784
game/g_target.c
File diff suppressed because it is too large
Load diff
906
game/g_team.c
906
game/g_team.c
|
@ -3,928 +3,28 @@
|
|||
|
||||
#include "g_local.h"
|
||||
|
||||
team_t initialBorgTeam = TEAM_FREE;
|
||||
int borgQueenStartPoint = ENTITYNUM_NONE;
|
||||
|
||||
typedef enum _flag_status {
|
||||
FLAG_ATBASE = 0,
|
||||
FLAG_TAKEN,
|
||||
FLAG_DROPPED
|
||||
} flagStatus_t;
|
||||
|
||||
typedef struct teamgame_s
|
||||
{
|
||||
float last_flag_capture;
|
||||
int last_capture_team;
|
||||
flagStatus_t redStatus;
|
||||
flagStatus_t blueStatus;
|
||||
} teamgame_t;
|
||||
|
||||
teamgame_t teamgame;
|
||||
|
||||
void Team_SetFlagStatus( int team, flagStatus_t status );
|
||||
|
||||
void Team_InitGame(void)
|
||||
{
|
||||
memset(&teamgame, 0, sizeof teamgame);
|
||||
teamgame.redStatus = teamgame.blueStatus = -1; // Invalid to force update
|
||||
|
||||
Team_SetFlagStatus( TEAM_RED, FLAG_ATBASE );
|
||||
Team_SetFlagStatus( TEAM_BLUE, FLAG_ATBASE );
|
||||
|
||||
// set config strings for what the two teams are for use in the cgame that renders the CTF flags
|
||||
trap_SetConfigstring( CS_RED_GROUP, g_team_group_red.string);
|
||||
trap_SetConfigstring( CS_BLUE_GROUP, g_team_group_blue.string);
|
||||
|
||||
}
|
||||
|
||||
int OtherTeam(int team) {
|
||||
if (team==TEAM_RED)
|
||||
return TEAM_BLUE;
|
||||
else if (team==TEAM_BLUE)
|
||||
return TEAM_RED;
|
||||
return team;
|
||||
}
|
||||
|
||||
const char *TeamName(int team) {
|
||||
if (team==TEAM_RED)
|
||||
return "RED";
|
||||
else if (team==TEAM_BLUE)
|
||||
return "BLUE";
|
||||
else if (team==TEAM_SPECTATOR)
|
||||
if (team==TEAM_SPECTATOR)
|
||||
return "SPECTATOR";
|
||||
return "FREE";
|
||||
}
|
||||
|
||||
const char *OtherTeamName(int team) {
|
||||
if (team==TEAM_RED)
|
||||
return "BLUE";
|
||||
else if (team==TEAM_BLUE)
|
||||
return "RED";
|
||||
else if (team==TEAM_SPECTATOR)
|
||||
if (team==TEAM_SPECTATOR)
|
||||
return "SPECTATOR";
|
||||
return "FREE";
|
||||
}
|
||||
|
||||
const char *TeamColorString(int team) {
|
||||
if (team==TEAM_RED)
|
||||
return S_COLOR_RED;
|
||||
else if (team==TEAM_BLUE)
|
||||
return S_COLOR_BLUE;
|
||||
else if (team==TEAM_SPECTATOR)
|
||||
if (team==TEAM_SPECTATOR)
|
||||
return S_COLOR_YELLOW;
|
||||
return S_COLOR_WHITE;
|
||||
}
|
||||
|
||||
// NULL for everyone
|
||||
void QDECL PrintMsg( gentity_t *ent, const char *fmt, ... ) __attribute__ ((format (printf, 2, 3)));
|
||||
void QDECL PrintMsg( gentity_t *ent, const char *fmt, ... ) {
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
char *p;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
if (vsprintf (msg, fmt, argptr) > sizeof(msg)) {
|
||||
G_Error ( "%s", "PrintMsg overrun" );
|
||||
}
|
||||
va_end (argptr);
|
||||
|
||||
// double quotes are bad
|
||||
while ((p = strchr(msg, '"')) != NULL)
|
||||
*p = '\'';
|
||||
|
||||
trap_SendServerCommand ( ( (ent == NULL) ? -1 : ent-g_entities ), va("print \"%s\"", msg ));
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
OnSameTeam
|
||||
==============
|
||||
*/
|
||||
qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 ) {
|
||||
if (( g_gametype.integer == GT_FFA ) || (g_gametype.integer == GT_TOURNAMENT) || (g_gametype.integer == GT_SINGLE_PLAYER))
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( !ent1->client || !ent2->client ) {
|
||||
if ( !ent1->client && !ent2->client )
|
||||
{
|
||||
if ( ent1->team && ent2->team && atoi( ent1->team ) == atoi( ent2->team ) )
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
else if ( !ent1->client )
|
||||
{
|
||||
if ( ent1->team && atoi( ent1->team ) == ent2->client->sess.sessionTeam )
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
else// if ( !ent2->client )
|
||||
{
|
||||
if ( ent2->team && ent1->client->sess.sessionTeam == atoi( ent2->team ) )
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( ent1->client->sess.sessionTeam == ent2->client->sess.sessionTeam ) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void Team_SetFlagStatus( int team, flagStatus_t status )
|
||||
{
|
||||
qboolean modified = qfalse;
|
||||
|
||||
switch (team) {
|
||||
case TEAM_RED :
|
||||
if ( teamgame.redStatus != status ) {
|
||||
teamgame.redStatus = status;
|
||||
modified = qtrue;
|
||||
}
|
||||
break;
|
||||
case TEAM_BLUE :
|
||||
if ( teamgame.blueStatus != status ) {
|
||||
teamgame.blueStatus = status;
|
||||
modified = qtrue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
char st[4];
|
||||
|
||||
st[0] = '0' + (int)teamgame.redStatus;
|
||||
st[1] = '0' + (int)teamgame.blueStatus;
|
||||
st[2] = 0;
|
||||
|
||||
trap_SetConfigstring( CS_FLAGSTATUS, st );
|
||||
}
|
||||
}
|
||||
|
||||
void Team_CheckDroppedItem( gentity_t *dropped )
|
||||
{
|
||||
/*if (dropped->item->giTag == PW_REDFLAG)
|
||||
Team_SetFlagStatus( TEAM_RED, FLAG_DROPPED );
|
||||
else if (dropped->item->giTag == PW_BORG_ADAPT)
|
||||
Team_SetFlagStatus( TEAM_BLUE, FLAG_DROPPED );*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Team_FragBonuses
|
||||
|
||||
Calculate the bonuses for flag defense, flag carrier defense, etc.
|
||||
Note that bonuses are not cumlative. You get one, they are in importance
|
||||
order.
|
||||
================
|
||||
*/
|
||||
void Team_FragBonuses(gentity_t *targ, gentity_t *inflictor, gentity_t *attacker)
|
||||
{
|
||||
//int i;
|
||||
//gentity_t *ent;
|
||||
//int flag_pw, enemy_flag_pw;
|
||||
int otherteam;
|
||||
gentity_t *flag, *carrier = NULL;
|
||||
char *c;
|
||||
vec3_t v1, v2;
|
||||
int team;
|
||||
|
||||
// no bonus for fragging yourself
|
||||
if (!targ->client || attacker == NULL || !attacker->client || targ == attacker)
|
||||
return;
|
||||
|
||||
team = targ->client->sess.sessionTeam;
|
||||
otherteam = OtherTeam(targ->client->sess.sessionTeam);
|
||||
if (otherteam < 0)
|
||||
return; // whoever died isn't on a team
|
||||
|
||||
// same team, if the flag at base, check to he has the enemy flag
|
||||
/*if (team == TEAM_RED) {
|
||||
flag_pw = PW_REDFLAG;
|
||||
enemy_flag_pw = PW_REDFLAG;
|
||||
} else {
|
||||
flag_pw = PW_REDFLAG;
|
||||
enemy_flag_pw = PW_REDFLAG;
|
||||
}*/
|
||||
|
||||
// did the attacker frag the flag carrier?
|
||||
/*if (targ->client->ps.powerups[enemy_flag_pw]) {
|
||||
attacker->client->pers.teamState.lastfraggedcarrier = level.time;
|
||||
AddScore(attacker, CTF_FRAG_CARRIER_BONUS);
|
||||
attacker->client->pers.teamState.fragcarrier++;
|
||||
PrintMsg(NULL, "%s" S_COLOR_WHITE " eliminated %s's flag carrier!\n",
|
||||
attacker->client->pers.netname, TeamName(team));
|
||||
|
||||
// the target had the flag, clear the hurt carrier
|
||||
// field on the other team
|
||||
for (i = 0; i < g_maxclients.integer; i++) {
|
||||
ent = g_entities + i;
|
||||
if (ent->inuse && ent->client->sess.sessionTeam == otherteam)
|
||||
ent->client->pers.teamState.lasthurtcarrier = 0;
|
||||
}
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (targ->client->pers.teamState.lasthurtcarrier &&
|
||||
level.time - targ->client->pers.teamState.lasthurtcarrier < CTF_CARRIER_DANGER_PROTECT_TIMEOUT /*&&
|
||||
!attacker->client->ps.powerups[flag_pw]*/) {
|
||||
// attacker is on the same team as the flag carrier and
|
||||
// fragged a guy who hurt our flag carrier
|
||||
AddScore(attacker, CTF_CARRIER_DANGER_PROTECT_BONUS);
|
||||
|
||||
attacker->client->pers.teamState.carrierdefense++;
|
||||
targ->client->pers.teamState.lasthurtcarrier = 0;
|
||||
|
||||
team = attacker->client->sess.sessionTeam;
|
||||
PrintMsg(NULL, "%s" S_COLOR_WHITE " defends %s's flag carrier against an aggressive enemy\n",
|
||||
attacker->client->pers.netname, TeamName(team));
|
||||
return;
|
||||
}
|
||||
|
||||
// flag and flag carrier area defense bonuses
|
||||
|
||||
// we have to find the flag and carrier entities
|
||||
|
||||
// find the flag
|
||||
switch (attacker->client->sess.sessionTeam) {
|
||||
case TEAM_RED:
|
||||
c = "team_CTF_redflag";
|
||||
break;
|
||||
case TEAM_BLUE:
|
||||
c = "team_CTF_blueflag";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
flag = NULL;
|
||||
while ((flag = G_Find (flag, FOFS(classname), c)) != NULL) {
|
||||
if (!(flag->flags & FL_DROPPED_ITEM))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
return; // can't find attacker's flag
|
||||
|
||||
// find attacker's team's flag carrier
|
||||
/*for (i = 0; i < g_maxclients.integer; i++) {
|
||||
carrier = g_entities + i;
|
||||
if (carrier->inuse && carrier->client->ps.powerups[flag_pw])
|
||||
break;
|
||||
carrier = NULL;
|
||||
}*/
|
||||
|
||||
// ok we have the attackers flag and a pointer to the carrier
|
||||
|
||||
// check to see if we are defending the base's flag
|
||||
VectorSubtract(targ->r.currentOrigin, flag->r.currentOrigin, v1);
|
||||
VectorSubtract(attacker->r.currentOrigin, flag->r.currentOrigin, v2);
|
||||
|
||||
if ( ( ( VectorLength(v1) < CTF_TARGET_PROTECT_RADIUS &&
|
||||
trap_InPVS(flag->r.currentOrigin, targ->r.currentOrigin ) ) ||
|
||||
( VectorLength(v2) < CTF_TARGET_PROTECT_RADIUS &&
|
||||
trap_InPVS(flag->r.currentOrigin, attacker->r.currentOrigin ) ) ) &&
|
||||
attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam) {
|
||||
|
||||
// we defended the base flag
|
||||
AddScore(attacker, CTF_FLAG_DEFENSE_BONUS);
|
||||
attacker->client->pers.teamState.basedefense++;
|
||||
if (flag->r.svFlags & SVF_NOCLIENT) {
|
||||
PrintMsg(NULL, "%s" S_COLOR_WHITE " defends the %s base.\n",
|
||||
attacker->client->pers.netname,
|
||||
TeamName(attacker->client->sess.sessionTeam));
|
||||
} else {
|
||||
PrintMsg(NULL, "%s" S_COLOR_WHITE " defends the %s flag.\n",
|
||||
attacker->client->pers.netname,
|
||||
TeamName(attacker->client->sess.sessionTeam));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (carrier && carrier != attacker) {
|
||||
VectorSubtract(targ->r.currentOrigin, carrier->r.currentOrigin, v1);
|
||||
VectorSubtract(attacker->r.currentOrigin, carrier->r.currentOrigin, v1);
|
||||
|
||||
if ( ( ( VectorLength(v1) < CTF_ATTACKER_PROTECT_RADIUS &&
|
||||
trap_InPVS(carrier->r.currentOrigin, targ->r.currentOrigin ) ) ||
|
||||
( VectorLength(v2) < CTF_ATTACKER_PROTECT_RADIUS &&
|
||||
trap_InPVS(carrier->r.currentOrigin, attacker->r.currentOrigin ) ) ) &&
|
||||
attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam) {
|
||||
AddScore(attacker, CTF_CARRIER_PROTECT_BONUS);
|
||||
attacker->client->pers.teamState.carrierdefense++;
|
||||
PrintMsg(NULL, "%s" S_COLOR_WHITE " defends the %s's flag carrier.\n",
|
||||
attacker->client->pers.netname,
|
||||
TeamName(attacker->client->sess.sessionTeam));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Team_CheckHurtCarrier
|
||||
|
||||
Check to see if attacker hurt the flag carrier. Needed when handing out bonuses for assistance to flag
|
||||
carrier defense.
|
||||
================
|
||||
*/
|
||||
void Team_CheckHurtCarrier(gentity_t *targ, gentity_t *attacker)
|
||||
{
|
||||
//int flag_pw;
|
||||
|
||||
if (!targ->client || !attacker->client)
|
||||
return;
|
||||
|
||||
/*if (targ->client->sess.sessionTeam == TEAM_RED)
|
||||
flag_pw = PW_REDFLAG;
|
||||
else
|
||||
flag_pw = PW_REDFLAG;*/
|
||||
|
||||
/*if (targ->client->ps.powerups[flag_pw] &&
|
||||
targ->client->sess.sessionTeam != attacker->client->sess.sessionTeam)
|
||||
attacker->client->pers.teamState.lasthurtcarrier = level.time;*/
|
||||
}
|
||||
|
||||
|
||||
gentity_t *Team_ResetFlag(int team)
|
||||
{
|
||||
char *c;
|
||||
gentity_t *ent, *rent = NULL;
|
||||
|
||||
switch (team) {
|
||||
case TEAM_RED:
|
||||
c = "team_CTF_redflag";
|
||||
break;
|
||||
case TEAM_BLUE:
|
||||
c = "team_CTF_blueflag";
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ent = NULL;
|
||||
while ((ent = G_Find (ent, FOFS(classname), c)) != NULL) {
|
||||
if (ent->flags & FL_DROPPED_ITEM)
|
||||
G_FreeEntity(ent);
|
||||
else {
|
||||
rent = ent;
|
||||
RespawnItem(ent);
|
||||
}
|
||||
}
|
||||
|
||||
Team_SetFlagStatus( team, FLAG_ATBASE );
|
||||
|
||||
return rent;
|
||||
}
|
||||
|
||||
void Team_ResetFlags(void)
|
||||
{
|
||||
Team_ResetFlag(TEAM_RED);
|
||||
Team_ResetFlag(TEAM_BLUE);
|
||||
}
|
||||
|
||||
void Team_ReturnFlagSound(gentity_t *ent, int team)
|
||||
{
|
||||
// play powerup spawn sound to all clients
|
||||
gentity_t *te;
|
||||
|
||||
if (ent == NULL) {
|
||||
G_Printf ("Warning: NULL passed to Team_ReturnFlagSound\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
te = G_TempEntity( ent->s.pos.trBase, EV_TEAM_SOUND );
|
||||
te->s.eventParm = RETURN_FLAG_SOUND;
|
||||
te->s.otherEntityNum = team;
|
||||
|
||||
te->r.svFlags |= SVF_BROADCAST;
|
||||
}
|
||||
|
||||
void Team_ReturnFlag(int team)
|
||||
{
|
||||
Team_ReturnFlagSound(Team_ResetFlag(team), team);
|
||||
PrintMsg(NULL, "The %s flag has returned!\n", TeamName(team));
|
||||
}
|
||||
|
||||
void Team_FreeEntity(gentity_t *ent)
|
||||
{
|
||||
/*if (ent->item->giTag == PW_REDFLAG)
|
||||
Team_ReturnFlag(TEAM_RED);
|
||||
else if (ent->item->giTag == PW_BORG_ADAPT)
|
||||
Team_ReturnFlag(TEAM_BLUE);*/
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Team_DroppedFlagThink
|
||||
|
||||
Automatically set in Launch_Item if the item is one of the flags
|
||||
|
||||
Flags are unique in that if they are dropped, the base flag must be respawned when they time out
|
||||
==============
|
||||
*/
|
||||
void Team_DroppedFlagThink(gentity_t *ent)
|
||||
{
|
||||
/*if (ent->item->giTag == PW_REDFLAG)
|
||||
Team_ReturnFlagSound(Team_ResetFlag(TEAM_RED), TEAM_RED);
|
||||
else if (ent->item->giTag == PW_BORG_ADAPT)
|
||||
Team_ReturnFlagSound(Team_ResetFlag(TEAM_BLUE), TEAM_BLUE);*/
|
||||
// Reset Flag will delete this entity
|
||||
}
|
||||
|
||||
void Team_AddScore( int team, int points )
|
||||
{
|
||||
teamgame.last_flag_capture = level.time;
|
||||
teamgame.last_capture_team = team;
|
||||
|
||||
// Increase the team's score
|
||||
level.teamScores[team] += points;
|
||||
}
|
||||
|
||||
/* TODO: unused! remove me? */
|
||||
int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) {
|
||||
gclient_t *cl = other->client;
|
||||
|
||||
// hey, its not our flag, pick it up
|
||||
PrintMsg (NULL, "%s" S_COLOR_WHITE " got the %s flag!\n",
|
||||
other->client->pers.netname, TeamName(team));
|
||||
AddScore(other, CTF_FLAG_BONUS);
|
||||
|
||||
//if (team == TEAM_RED)
|
||||
//cl->ps.powerups[PW_REDFLAG] = INT_MAX; // flags never expire
|
||||
//else
|
||||
//cl->ps.powerups[PW_BORG_ADAPT] = INT_MAX; // flags never expire
|
||||
|
||||
cl->pers.teamState.flagsince = level.time;
|
||||
|
||||
Team_SetFlagStatus( team, FLAG_TAKEN );
|
||||
|
||||
return -1; // Do not respawn this automatically, but do delete it if it was FL_DROPPED
|
||||
}
|
||||
|
||||
int Pickup_Team( gentity_t *ent, gentity_t *other ) {
|
||||
int team;
|
||||
gclient_t *cl = other->client;
|
||||
|
||||
// figure out what team this flag is
|
||||
if (strcmp(ent->classname, "team_CTF_redflag") == 0)
|
||||
team = TEAM_RED;
|
||||
else if (strcmp(ent->classname, "team_CTF_blueflag") == 0)
|
||||
team = TEAM_BLUE;
|
||||
else {
|
||||
PrintMsg ( other, "Don't know what team the flag is on.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((team == cl->sess.sessionTeam) ?
|
||||
Team_TouchOurFlag : Team_TouchEnemyFlag)
|
||||
(ent, other, team);
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
Team_GetLocation
|
||||
|
||||
Report a location for the player. Uses placed nearby target_location entities
|
||||
============
|
||||
*/
|
||||
gentity_t *Team_GetLocation(gentity_t *ent)
|
||||
{
|
||||
gentity_t *eloc, *best;
|
||||
float bestlen, len;
|
||||
vec3_t origin;
|
||||
|
||||
best = NULL;
|
||||
bestlen = 3*8192.0*8192.0;
|
||||
|
||||
VectorCopy( ent->r.currentOrigin, origin );
|
||||
|
||||
for (eloc = level.locationHead; eloc; eloc = eloc->nextTrain) {
|
||||
len = ( origin[0] - eloc->r.currentOrigin[0] ) * ( origin[0] - eloc->r.currentOrigin[0] )
|
||||
+ ( origin[1] - eloc->r.currentOrigin[1] ) * ( origin[1] - eloc->r.currentOrigin[1] )
|
||||
+ ( origin[2] - eloc->r.currentOrigin[2] ) * ( origin[2] - eloc->r.currentOrigin[2] );
|
||||
|
||||
if ( len > bestlen ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !trap_InPVS( origin, eloc->r.currentOrigin ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bestlen = len;
|
||||
best = eloc;
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
Team_GetLocation
|
||||
|
||||
Report a location for the player. Uses placed nearby target_location entities
|
||||
============
|
||||
*/
|
||||
qboolean Team_GetLocationMsg(gentity_t *ent, char *loc, int loclen)
|
||||
{
|
||||
gentity_t *best;
|
||||
|
||||
best = Team_GetLocation( ent );
|
||||
|
||||
if (!best)
|
||||
return qfalse;
|
||||
|
||||
if (best->count) {
|
||||
if (best->count < 0)
|
||||
best->count = 0;
|
||||
if (best->count > 7)
|
||||
best->count = 7;
|
||||
Com_sprintf(loc, loclen, "%c%c%s" S_COLOR_WHITE, Q_COLOR_ESCAPE, best->count + '0', best->message );
|
||||
} else
|
||||
Com_sprintf(loc, loclen, "%s", best->message);
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
================
|
||||
SelectRandomDeathmatchSpawnPoint
|
||||
|
||||
go to a random point that doesn't telefrag
|
||||
================
|
||||
*/
|
||||
#define MAX_TEAM_SPAWN_POINTS 32
|
||||
gentity_t *SelectRandomTeamSpawnPoint( gentity_t *ent, int teamstate, team_t team ) {
|
||||
gentity_t *spot;
|
||||
int count;
|
||||
int selection;
|
||||
gentity_t *spots[MAX_TEAM_SPAWN_POINTS];
|
||||
char *classname;
|
||||
|
||||
if (teamstate == TEAM_BEGIN) {
|
||||
if (team == TEAM_RED)
|
||||
classname = "team_CTF_redplayer";
|
||||
else if (team == TEAM_BLUE)
|
||||
classname = "team_CTF_blueplayer";
|
||||
else
|
||||
return NULL;
|
||||
} else {
|
||||
if (team == TEAM_RED)
|
||||
classname = "team_CTF_redspawn";
|
||||
else if (team == TEAM_BLUE)
|
||||
classname = "team_CTF_bluespawn";
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
count = 0;
|
||||
|
||||
spot = NULL;
|
||||
|
||||
while ((spot = G_Find (spot, FOFS(classname), classname)) != NULL) {
|
||||
if ( teamstate != TEAM_BEGIN) {
|
||||
if ( spot->spawnflags & 1 ) {
|
||||
//not an active spawn point
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( SpotWouldTelefrag( spot ) ) {
|
||||
continue;
|
||||
}
|
||||
spots[ count ] = spot;
|
||||
if (++count == MAX_TEAM_SPAWN_POINTS)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !count ) { // no spots that won't telefrag
|
||||
return G_Find( NULL, FOFS(classname), classname);
|
||||
}
|
||||
|
||||
selection = rand() % count;
|
||||
return spots[ selection ];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
SelectCTFSpawnPoint
|
||||
|
||||
============
|
||||
*/
|
||||
gentity_t *SelectCTFSpawnPoint ( gentity_t *ent, team_t team, int teamstate, vec3_t origin, vec3_t angles ) {
|
||||
gentity_t *spot;
|
||||
|
||||
spot = SelectRandomTeamSpawnPoint ( ent, teamstate, team );
|
||||
|
||||
if (!spot) {
|
||||
return SelectSpawnPoint( vec3_origin, origin, angles );
|
||||
}
|
||||
|
||||
VectorCopy (spot->s.origin, origin);
|
||||
origin[2] += 9;
|
||||
VectorCopy (spot->s.angles, angles);
|
||||
|
||||
return spot;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*static int QDECL SortClients( const void *a, const void *b ) {
|
||||
return *(int *)a - *(int *)b;
|
||||
}*/
|
||||
|
||||
/*
|
||||
==================
|
||||
CheckHealthInfoMessage
|
||||
|
||||
Sends Health Changes to proper clients
|
||||
|
||||
Format:
|
||||
clientNum health
|
||||
|
||||
==================
|
||||
*/
|
||||
void CheckHealthInfoMessage( void )
|
||||
{
|
||||
char entry[1024];
|
||||
char string[1400];
|
||||
int stringlength;
|
||||
int i, j, t;
|
||||
gentity_t *player, *ent;
|
||||
int sendToCnt, cnt, sentCnt;
|
||||
int h;
|
||||
int clients[MAX_CLIENTS];
|
||||
int sendToClients[MAX_CLIENTS];
|
||||
|
||||
//only send this to medics or spectators or adminz
|
||||
for (i = 0, sendToCnt = 0; i < g_maxclients.integer; i++)
|
||||
{
|
||||
|
||||
if ( level.clients[i].pers.connected == CON_CONNECTED && level.clients[i].ps.stats[STAT_HEALTH] > 0 &&//make sure they've actually spawned in already
|
||||
(level.clients[i].sess.sessionTeam == TEAM_SPECTATOR || g_classData[level.clients[i].sess.sessionClass].isMedical || g_classData[level.clients[i].sess.sessionClass].isAdmin ) )
|
||||
{
|
||||
sendToClients[sendToCnt++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !sendToCnt )
|
||||
{//no-one to send to
|
||||
return;
|
||||
}
|
||||
|
||||
//only send those clients whose health has changed this cycle
|
||||
//NB: there's a prob with client 0 in here....
|
||||
for (i = 0, cnt = 0; i < g_maxclients.integer; i++)
|
||||
{
|
||||
player = g_entities + i;
|
||||
if ( player->inuse && player->old_health != player->health && ( player->health > 0 || player->old_health > 0 ))
|
||||
{
|
||||
clients[cnt++] = i;
|
||||
player->old_health = player->health;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !cnt )
|
||||
{//no-one relevant changed health
|
||||
return;
|
||||
}
|
||||
|
||||
for ( t = 0; t < sendToCnt; t++ )
|
||||
{
|
||||
ent = g_entities + sendToClients[t];
|
||||
sentCnt = 0;
|
||||
|
||||
// send the latest information on all clients
|
||||
string[0] = 0;
|
||||
stringlength = 0;
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
player = g_entities + clients[i];
|
||||
//RPG-X | Phenix | 05/03/2005
|
||||
/*if ( ent->client->sess.sessionTeam == player->client->sess.sessionTeam && ent->client->pers.teamInfo )
|
||||
{//already sent this player's health to this client because teaminfo is on
|
||||
continue;
|
||||
}*/
|
||||
|
||||
if ( ent == player )
|
||||
{//don't send the ent his own health
|
||||
continue;
|
||||
}
|
||||
|
||||
//send this one
|
||||
sentCnt++;
|
||||
|
||||
h = player->health;
|
||||
if (h < 0) h = 0;
|
||||
|
||||
Com_sprintf (entry, sizeof(entry), " %i %i", clients[i], h);
|
||||
j = strlen(entry);
|
||||
if (stringlength + j > sizeof(string))
|
||||
break;
|
||||
strcpy (string + stringlength, entry);
|
||||
stringlength += j;
|
||||
}
|
||||
|
||||
if ( sentCnt )
|
||||
{
|
||||
trap_SendServerCommand( sendToClients[t], va("hinfo %i%s", sentCnt, string) );
|
||||
//trap_SendServerCommand( -1, va( "print \"^1hinfo %i%s\n\"", sentCnt, string ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
TeamplayLocationsMessage
|
||||
|
||||
Format:
|
||||
clientNum location health armor weapon powerups
|
||||
|
||||
==================
|
||||
*/
|
||||
void TeamplayInfoMessage( gentity_t *ent ) {
|
||||
char entry[1024];
|
||||
char string[1400];
|
||||
int stringlength;
|
||||
int i, j;
|
||||
gentity_t *player;
|
||||
int cnt;
|
||||
//int h, a;
|
||||
|
||||
//TiM : Send data regardless
|
||||
/*if ( ! ent->client->pers.teamInfo )
|
||||
return;*/
|
||||
|
||||
//don't bother sending during intermission?
|
||||
if ( level.intermissiontime )
|
||||
return;
|
||||
|
||||
// figure out what client should be on the display
|
||||
// we are limited to 8, but we want to use the top eight players
|
||||
// but in client order (so they don't keep changing position on the overlay)
|
||||
for (i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++) {
|
||||
player = g_entities + level.sortedClients[i];
|
||||
if (player->inuse && player->client->sess.sessionTeam ==
|
||||
ent->client->sess.sessionTeam ) {
|
||||
}
|
||||
}
|
||||
|
||||
// We have the top eight players, sort them by clientNum
|
||||
//TiM
|
||||
//qsort( clients, cnt, sizeof( clients[0] ), SortClients );
|
||||
|
||||
// send the latest information on all clients
|
||||
string[0] = 0;
|
||||
stringlength = 0;
|
||||
|
||||
for (i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++) {
|
||||
player = g_entities + i;
|
||||
//RPG-X | Phenix | 05/03/2005
|
||||
if (player->inuse /*&& player->client->sess.sessionTeam ==
|
||||
ent->client->sess.sessionTeam*/ ) {
|
||||
|
||||
/*h = player->client->ps.stats[STAT_HEALTH];
|
||||
a = player->client->ps.stats[STAT_ARMOR];
|
||||
if (h < 0) h = 0;
|
||||
if (a < 0) a = 0;*/
|
||||
|
||||
//to counter for the fact we could pwn the server doing this, remove all superfluous data
|
||||
|
||||
Com_sprintf (entry, sizeof(entry),
|
||||
" %i %i ", //%i %i %i %i
|
||||
// level.sortedClients[i], player->client->pers.teamState.location, h, a,
|
||||
i, player->client->pers.teamState.location/*, h, a,
|
||||
player->client->ps.weapon, player->s.powerups*/);
|
||||
j = strlen(entry);
|
||||
if (stringlength + j > sizeof(string))
|
||||
break;
|
||||
strcpy (string + stringlength, entry);
|
||||
stringlength += j;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
trap_SendServerCommand( ent-g_entities, va("tinfo %i%s", cnt, string) );
|
||||
}
|
||||
|
||||
//TiM - Modified to work with RPG-X
|
||||
void CheckTeamStatus(void)
|
||||
{
|
||||
int i;
|
||||
gentity_t *loc, *ent;
|
||||
|
||||
if (level.time - level.lastTeamLocationTime > TEAM_LOCATION_UPDATE_TIME) {
|
||||
|
||||
level.lastTeamLocationTime = level.time;
|
||||
|
||||
for (i = 0; i < g_maxclients.integer; i++) {
|
||||
ent = g_entities + i;
|
||||
if (ent->inuse /*&&
|
||||
(ent->client->sess.sessionTeam == TEAM_RED ||
|
||||
ent->client->sess.sessionTeam == TEAM_BLUE)*/ ) {
|
||||
loc = Team_GetLocation( ent );
|
||||
if (loc)
|
||||
ent->client->pers.teamState.location = loc->health;
|
||||
else
|
||||
ent->client->pers.teamState.location = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < g_maxclients.integer; i++) {
|
||||
ent = g_entities + i;
|
||||
if (ent->inuse /*&&
|
||||
(ent->client->sess.sessionTeam == TEAM_RED ||
|
||||
ent->client->sess.sessionTeam == TEAM_BLUE)*/) {
|
||||
TeamplayInfoMessage( ent );
|
||||
}
|
||||
}
|
||||
|
||||
CheckHealthInfoMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
|
||||
/*QUAKED team_CTF_redplayer (1 0 0) (-16 -16 -16) (16 16 32) BORGQUEEN
|
||||
Only in CTF games. Red players spawn here at game start.
|
||||
|
||||
BORGQUEEN - The player that is the Borg Queen will spawn here
|
||||
*/
|
||||
void SP_team_CTF_redplayer( gentity_t *ent ) {
|
||||
if ( ent->spawnflags & 1 )
|
||||
{
|
||||
initialBorgTeam = TEAM_RED;
|
||||
borgQueenStartPoint = ent->s.number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*QUAKED team_CTF_blueplayer (0 0 1) (-16 -16 -16) (16 16 32) BORGQUEEN
|
||||
Only in CTF games. Blue players spawn here at game start.
|
||||
|
||||
BORGQUEEN - The player that is the Borg Queen will spawn here
|
||||
*/
|
||||
void SP_team_CTF_blueplayer( gentity_t *ent ) {
|
||||
if ( ent->spawnflags & 1 )
|
||||
{
|
||||
initialBorgTeam = TEAM_BLUE;
|
||||
borgQueenStartPoint = ent->s.number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void spawnpoint_toggle_active( gentity_t *ent, gentity_t *other, gentity_t *activator )
|
||||
{
|
||||
ent->spawnflags ^= 1;
|
||||
}
|
||||
/*QUAKED team_CTF_redspawn (1 0 0) (-16 -16 -24) (16 16 32) STARTOFF
|
||||
potential spawning position for red team in CTF games, AFTER game start
|
||||
Targets will be fired when someone spawns in on them.
|
||||
|
||||
STARTOFF - won't be considered as a spawn point until used
|
||||
|
||||
targetname - when used, toggles between active and incative spawn point
|
||||
*/
|
||||
void SP_team_CTF_redspawn(gentity_t *ent) {
|
||||
if ( ent->targetname )
|
||||
{
|
||||
ent->use = spawnpoint_toggle_active;
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED team_CTF_bluespawn (0 0 1) (-16 -16 -24) (16 16 32) STARTOFF
|
||||
potential spawning position for blue team in CTF games, AFTER game start
|
||||
Targets will be fired when someone spawns in on them.
|
||||
|
||||
STARTOFF - won't be considered as a spawn point until used
|
||||
|
||||
targetname - when used, toggles between active and incative spawn point
|
||||
*/
|
||||
void SP_team_CTF_bluespawn(gentity_t *ent) {
|
||||
if ( ent->targetname )
|
||||
{
|
||||
ent->use = spawnpoint_toggle_active;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,47 +1,8 @@
|
|||
// Copyright (C) 1999-2000 Id Software, Inc.
|
||||
//
|
||||
|
||||
#define CTF_CAPTURE_BONUS 100 // what you get for capture
|
||||
#define CTF_TEAM_BONUS 0 // what your team gets for capture
|
||||
#define CTF_RECOVERY_BONUS 10 // what you get for recovery
|
||||
#define CTF_FLAG_BONUS 10 // what you get for picking up enemy flag
|
||||
#define CTF_FRAG_CARRIER_BONUS 20 // what you get for fragging enemy flag carrier
|
||||
#define CTF_FLAG_RETURN_TIME 40000 // seconds until auto return
|
||||
|
||||
#define CTF_CARRIER_DANGER_PROTECT_BONUS 5 // bonus for fraggin someone who has recently hurt your flag carrier
|
||||
#define CTF_CARRIER_PROTECT_BONUS 2 // bonus for fraggin someone while either you or your target are near your flag carrier
|
||||
#define CTF_FLAG_DEFENSE_BONUS 10 // bonus for fraggin someone while either you or your target are near your flag
|
||||
#define CTF_RETURN_FLAG_ASSIST_BONUS 10 // awarded for returning a flag that causes a capture to happen almost immediately
|
||||
#define CTF_FRAG_CARRIER_ASSIST_BONUS 10 // award for fragging a flag carrier if a capture happens almost immediately
|
||||
|
||||
#define CTF_TARGET_PROTECT_RADIUS 1000 // the radius around an object being defended where a target will be worth extra frags
|
||||
#define CTF_ATTACKER_PROTECT_RADIUS 1000 // the radius around an object being defended where an attacker will get extra frags when making kills
|
||||
|
||||
#define CTF_CARRIER_DANGER_PROTECT_TIMEOUT 8000
|
||||
#define CTF_FRAG_CARRIER_ASSIST_TIMEOUT 10000
|
||||
#define CTF_RETURN_FLAG_ASSIST_TIMEOUT 10000
|
||||
|
||||
#define CTF_GRAPPLE_SPEED 750 // speed of grapple in flight
|
||||
#define CTF_GRAPPLE_PULL_SPEED 750 // speed player is pulled at
|
||||
|
||||
// Prototypes
|
||||
|
||||
int OtherTeam(int team);
|
||||
const char *TeamName(int team);
|
||||
const char *OtherTeamName(int team);
|
||||
const char *TeamColorString(int team);
|
||||
//void AddTeamScore(vec3_t origin, int team, int score);
|
||||
|
||||
void Team_DroppedFlagThink(gentity_t *ent);
|
||||
void Team_FragBonuses(gentity_t *targ, gentity_t *inflictor, gentity_t *attacker);
|
||||
void Team_CheckHurtCarrier(gentity_t *targ, gentity_t *attacker);
|
||||
void Team_InitGame(void);
|
||||
void Team_ReturnFlag(int team);
|
||||
void Team_FreeEntity(gentity_t *ent);
|
||||
gentity_t *SelectCTFSpawnPoint ( gentity_t *ent, team_t team, int teamstate, vec3_t origin, vec3_t angles );
|
||||
gentity_t *Team_GetLocation(gentity_t *ent);
|
||||
qboolean Team_GetLocationMsg(gentity_t *ent, char *loc, int loclen);
|
||||
void TeamplayInfoMessage( gentity_t *ent );
|
||||
void CheckTeamStatus(void);
|
||||
|
||||
int Pickup_Team( gentity_t *ent, gentity_t *other );
|
||||
|
|
169
game/g_trigger.c
169
game/g_trigger.c
|
@ -4,8 +4,9 @@
|
|||
|
||||
#include "g_local.h"
|
||||
|
||||
/*these look weired... I'd rather replace them with streight numbers.
|
||||
#define SF_SPECTATOR (1<<0)
|
||||
#define SF_RANDOM (1<<1)
|
||||
#define SF_RANDOM (1<<1)*/
|
||||
|
||||
/**
|
||||
* \brief Inits a trigger entity.
|
||||
|
@ -134,13 +135,17 @@ void Touch_Multi( gentity_t *self, gentity_t *other, trace_t *trace ) {
|
|||
}
|
||||
|
||||
/*QUAKED trigger_multiple (.5 .5 .5) ? RED_OK BLUE_OK TEAM_ONLY
|
||||
RED_OK - People on the red team can fire this trigger
|
||||
BLUE_OK - People on the blue team can fire this trigger
|
||||
TEAM_ONLY - Only people on red or blue can fire this trigger (not TEAM_FREE like in straight holomatch or spectators)
|
||||
|
||||
"wait" : Seconds between triggerings, 0.5 default, -1 = one time only.
|
||||
"random" wait variance, default is 0
|
||||
-----DESCRIPTION-----
|
||||
Variable sized repeatable trigger. Must be targeted at one or more entities.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: RED_OK - People on the red team can fire this trigger
|
||||
2: BLUE_OK - People on the blue team can fire this trigger
|
||||
4: TEAM_ONLY - Only people on red or blue can fire this trigger (not TEAM_FREE like in straight holomatch or spectators)
|
||||
|
||||
-----KEYS-----
|
||||
"wait" - Seconds between triggerings, 0.5 default, -1 = one time only.
|
||||
"random" - wait variance, default is 0
|
||||
so, the basic time between firing is a random time between
|
||||
(wait - random) and (wait + random)
|
||||
*/
|
||||
|
@ -206,7 +211,15 @@ void trigger_always_think( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
/*QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
-----DESCRIPTION-----
|
||||
This trigger will always fire. It is activated by the world.
|
||||
Actually this is going to fire once 0.3 secs after spawn, so it's more a trigger_init.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"target" - targets to fire
|
||||
*/
|
||||
/**
|
||||
* \brief Spawn function of trigger_multiple.
|
||||
|
@ -302,8 +315,14 @@ void AimAtTarget( gentity_t *self ) {
|
|||
|
||||
|
||||
/*QUAKED trigger_push (.5 .5 .5) ?
|
||||
Must point at a target_position, which will be the apex of the leap.
|
||||
This will be client side predicted, unlike target_push
|
||||
-----DESCRIPTION-----
|
||||
Jumpfield/Booster Effect predicted on client side. This is activated by touch function.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
None
|
||||
|
||||
-----KEYS-----
|
||||
"target" - apex of the leap. Must be a target_position or info_notnull.
|
||||
*/
|
||||
/**
|
||||
* \brief Spawn function of trigger_push.
|
||||
|
@ -363,9 +382,16 @@ void Use_target_push( gentity_t *self, gentity_t *other, gentity_t *activator )
|
|||
}
|
||||
|
||||
/*QUAKED target_push (.5 .5 .5) (-8 -8 -8) (8 8 8) ENERGYNOISE
|
||||
Pushes the activator in the direction.of angle, or towards a target apex.
|
||||
"speed" defaults to 1000
|
||||
if "ENERGYNOISE", play energy noise instead of windfly
|
||||
-----DESCRIPTION-----
|
||||
Pushes the activator in the direction of angle, or towards a target apex.
|
||||
This is predicted on the serverside and is triggered by use-function.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: ENERGYNOISE - play energy noise instead of windfly
|
||||
|
||||
-----KEYS-----
|
||||
"speed" - defaults to 1000
|
||||
"target" - apex of the leap. Must be a target_position or info_notnull.
|
||||
*/
|
||||
/**
|
||||
* \brief Spawn function of target_push.
|
||||
|
@ -469,7 +495,7 @@ void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace
|
|||
return;
|
||||
}
|
||||
/* Spectators only? */
|
||||
if ( ( self->spawnflags & SF_SPECTATOR ) &&
|
||||
if ( ( self->spawnflags & 1 ) &&
|
||||
other->client->sess.sessionTeam != TEAM_SPECTATOR )
|
||||
{
|
||||
return;
|
||||
|
@ -478,7 +504,7 @@ void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace
|
|||
clientNum = other->client->ps.clientNum;
|
||||
|
||||
/* BOOKMARK J2J */
|
||||
if (self->spawnflags & SF_RANDOM)
|
||||
if (self->spawnflags & 2)
|
||||
{
|
||||
/* find a random spawn point */
|
||||
dest = SelectRandomSpawnPoint();
|
||||
|
@ -585,28 +611,26 @@ void trigger_teleport_use(gentity_t *ent, gentity_t *other, gentity_t *activator
|
|||
}
|
||||
|
||||
|
||||
/*QUAKED trigger_teleport (.5 .5 .5) ? SPECTATOR RANDOM VISUAL_FX SUSPENDED DEACTIVATED SND_ONCE
|
||||
/*QUAKED trigger_teleport (.5 .5 .5) ? SPECTATOR RANDOM VISUAL_FX SUSPENDED DEACTIVATED
|
||||
-----DESCRIPTION-----
|
||||
Allows client side prediction of teleportation events.
|
||||
Must point at a target_position, which will be the teleport destination.
|
||||
Must point at a target_position or info_notnull, which will be the teleport destination.
|
||||
|
||||
--------- spawnflags --------
|
||||
-----SPAWNFLAGS-----
|
||||
1: SPECTATOR: If set, only spectators can use this teleport.
|
||||
Spectator teleporters are not normally placed in the editor, but are created
|
||||
automatically near doors to allow spectators to move through them.
|
||||
2: RANDOM: send player to random info_player_deathmatch spawn point
|
||||
4: VISUAL_FX: plays the Star Trek transporter FX and beams the player out slowly
|
||||
8: SUSPENDED: player appears with the bounding box aligned to the bottom of the target
|
||||
If this isn't set, the player materializes at the first solid surface under it
|
||||
16: DEACTIVATED: Spawns deactivated
|
||||
|
||||
If spectator is set, only spectators can use this teleport
|
||||
Spectator teleporters are not normally placed in the editor, but are created
|
||||
automatically near doors to allow spectators to move through them
|
||||
|
||||
RANDOM -- send player to random info_player_deathmatch spawn point
|
||||
VISUAL_FX -- plays the Star Trek transporter FX and beams the player out slowly
|
||||
SUSPENDED -- player appears with the bounding box aligned to the bottom of the target
|
||||
If this isn't set, the player materializes at the first solid surface under it
|
||||
|
||||
----------- keys ------------
|
||||
|
||||
"swapname" - ACTIVATE/DEACTIVATE (Using entity needs SELF/NOACTIVATOR)
|
||||
"wait" - time before trigger deactivates itself automatically
|
||||
"soundstart" - sound to play if triggered
|
||||
|
||||
health -- default is original behavior (speed of 400), any other value will be the
|
||||
-----KEYS-----
|
||||
"swapname" - ACTIVATE/DEACTIVATE (Using entity needs SELF/NOACTIVATOR)
|
||||
"wait" - time before trigger deactivates itself automatically
|
||||
"soundstart" - sound to play if triggered
|
||||
"health" - default is original behavior (speed of 400), any other value will be the
|
||||
speed at which the player is spewed forth from the tranpsorter destination. -1
|
||||
if you want no speed. The transporter VISUAL_FX flag will only work if the health
|
||||
is set to 0 or -1 as it cannot support 'spewing'.
|
||||
|
@ -628,7 +652,7 @@ void SP_trigger_teleport( gentity_t *self )
|
|||
* unlike other triggers, we need to send this one to the client
|
||||
* unless is a spectator trigger
|
||||
*/
|
||||
if ( self->spawnflags & SF_SPECTATOR )
|
||||
if ( self->spawnflags & 1)
|
||||
{
|
||||
self->r.svFlags |= SVF_NOCLIENT;
|
||||
}
|
||||
|
@ -671,19 +695,22 @@ trigger_hurt
|
|||
*/
|
||||
|
||||
/*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF TOGGLE SILENT NO_PROTECTION SLOW EVO_PROTECT NO_ADMIN
|
||||
-----DESCRIPTION-----
|
||||
Any entity that touches this will be hurt.
|
||||
It does dmg points of damage each server frame
|
||||
Targeting the trigger will toggle its on / off state.
|
||||
|
||||
SILENT supresses playing the sound
|
||||
TOGGLE can be toggled
|
||||
SLOW changes the damage rate to once per second
|
||||
NO_PROTECTION *nothing* stops the damage
|
||||
EVO_PROTECT Evosuit protects the client
|
||||
NO_ADMIN admins don't get hurt
|
||||
|
||||
"dmg" default 5 (whole numbers only)
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_OFF - trigger will not be doing damage until toggled on
|
||||
2: TOGGLE - can be toggled
|
||||
4: SILENT - supresses playing the sound
|
||||
8: NO_PROTECTION - *nothing* stops the damage
|
||||
16: SLOW - changes the damage rate to once per second
|
||||
32: EVO_PROTECT - Evosuit protects the client, even if NO_PROTECTION is set
|
||||
64: NO_ADMIN - admins don't get hurt, even if NO_PROTECTION is set
|
||||
|
||||
-----KEYS-----
|
||||
"dmg" - default 5 (whole numbers only)
|
||||
*/
|
||||
/**
|
||||
* \brief Use function of trigger_hurt.
|
||||
|
@ -799,21 +826,25 @@ void SP_trigger_hurt( gentity_t *self ) {
|
|||
==============================================================================
|
||||
|
||||
timer
|
||||
This should be renamed trigger_timer...
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON
|
||||
This should be renamed trigger_timer...
|
||||
Repeatedly fires its targets.
|
||||
-----DESCRIPTION-----
|
||||
Fires its targets every "wait" seconds.
|
||||
Can be turned on or off by using.
|
||||
|
||||
"wait" base time between triggering all targets, default is 1
|
||||
"random" wait variance, default is 0
|
||||
so, the basic time between firing is a random time between
|
||||
(wait - random) and (wait + random)
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_ON - will be on at spawn and setting up for it's first intervall
|
||||
|
||||
-----KEYS-----
|
||||
"wait" - base time between triggering all targets, default is 1
|
||||
"random" - wait variance, default is 0
|
||||
so, the basic time between firing is a random time between
|
||||
(wait - random) and (wait + random)
|
||||
*/
|
||||
/**
|
||||
* \brief Think function of func_timer.
|
||||
|
@ -878,8 +909,14 @@ void SP_func_timer( gentity_t *self ) {
|
|||
}
|
||||
|
||||
/*QUAKED trigger_transporter (0.5 0.5 0.5) ?
|
||||
-----DESCRIPTION-----
|
||||
This is used in combination with ui_transporter.
|
||||
Have this be targeted by ui_transporter.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
"wait" time to wait before trigger gets deactivated again(in seconds, default 5)
|
||||
"soundstart" transport sound;
|
||||
*/
|
||||
|
@ -1023,15 +1060,18 @@ void SP_trigger_transporter(gentity_t *ent) {
|
|||
}
|
||||
|
||||
/*QUAKED trigger_radiation (0.5 0.5 0.5) ? START_OFF MAP_WIDE
|
||||
-----DESCRIPTION-----
|
||||
This can be used in three ways:
|
||||
- as radiation volume trigger
|
||||
- as mapwide radiation
|
||||
|
||||
START_OFF ent is off at spawn
|
||||
MAP_WIDE mapwide radiation
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_OFF - ent is off at spawn
|
||||
2: MAP_WIDE - mapwide radiation
|
||||
|
||||
-----KEYS-----
|
||||
The damage the radiation does is calculated from these two values:
|
||||
"dmg" damage(default 1)
|
||||
"damage" damage(default 1)
|
||||
"wait" wait(seconds, default 10)
|
||||
|
||||
Forumla is: dps = dmg / wait
|
||||
|
@ -1124,3 +1164,30 @@ void SP_trigger_radiation(gentity_t *ent) {
|
|||
level.numBrushEnts++;
|
||||
}
|
||||
|
||||
/*QUAKED trigger_airlock (0.5 0.5 0.5) ?
|
||||
-----DESCRIPTION-----
|
||||
This is an entity that manages airlocks.
|
||||
It can be used for Maintenance-Locks (Space Walks) internal Airlocks (for example to a quarantene zone)
|
||||
or... as a way to abandon ship the hard way ^^ In that last case even an EVA-Suit won't protect you.
|
||||
|
||||
It is controlled by User Interface.
|
||||
|
||||
The Entity automatically features door management in a cycle, a check for an EVA-Suit (trigger_hurt)
|
||||
and a push to get overboard (trigger_push).
|
||||
|
||||
It is hardcoded to expect func_doors for entrance on either side and a func_forcefiled for ejecting
|
||||
(the forcefield is best placed within the outer door).
|
||||
|
||||
For Setup please set both sets of doors to wait = -1 and have the inner (if you select spawnflag no. 1
|
||||
the outer) door spawn in it's open state.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_OUTSIDE - assumes that the outside door is open and set's itself up approopriately to cycle in at first use
|
||||
2: NO_VENT - Will not check for push-target and forcefield that are required to vent the airlock.
|
||||
4: QUARTANTENE_LOCK - airlock will be considered as an internal airlock to a quarantene zone or similar.
|
||||
this will not kill and will not check for ejection-stuff, so NO_VENT is included in this spawnflag.
|
||||
|
||||
-----KEYS-----
|
||||
"wait" time to wait before trigger gets deactivated again(in seconds, default 5)
|
||||
"soundstart" transport sound;
|
||||
*/
|
|
@ -674,24 +674,27 @@ void turret_base_use (gentity_t *self, gentity_t *other, gentity_t *activator)
|
|||
}
|
||||
|
||||
/*QUAKED misc_turret (1 0 0) (-8 -8 -8) (8 8 8) START_OFF
|
||||
-----DESCRIPTION-----
|
||||
Will aim and shoot at enemies
|
||||
|
||||
START_OFF - Starts off
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_OFF - Starts off
|
||||
|
||||
random - How far away an enemy can be for it to pick it up (default 512)
|
||||
speed - How fast it turns (degrees per second, default 30)
|
||||
wait - How fast it shoots (shots per second, default 4, can't be less)
|
||||
dmg - How much damage each shot does (default 5)
|
||||
health - How much damage it can take before exploding (default 100)
|
||||
-----KEYS-----
|
||||
random - How far away an enemy can be for it to pick it up (default 512)
|
||||
speed - How fast it turns (degrees per second, default 30)
|
||||
wait - How fast it shoots (shots per second, default 4, can't be less)
|
||||
dmg - How much damage each shot does (default 5)
|
||||
health - How much damage it can take before exploding (default 100)
|
||||
|
||||
splashDamage - How much damage the explosion does
|
||||
splashRadius - The random of the explosion
|
||||
NOTE: If either of the above two are 0, it will not make an explosion
|
||||
splashDamage - How much damage the explosion does
|
||||
splashRadius - The random of the explosion
|
||||
NOTE: If either of the above two are 0, it will not make an explosion
|
||||
|
||||
targetname - Toggles it on/off
|
||||
target - What to use when destroyed
|
||||
targetname - Toggles it on/off
|
||||
target - What to use when destroyed
|
||||
|
||||
"team" - This cannot take damage from members of this team and will not target members of this team (2 = blue, 1 = red)
|
||||
"team" - This cannot take damage from members of this team and will not target members of this team (2 = blue, 1 = red) 2 will exclude players in RPG-X
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -1043,8 +1046,13 @@ void laser_arm_use (gentity_t *self, gentity_t *other, gentity_t *activator)
|
|||
}
|
||||
|
||||
/*QUAKED misc_laser_arm (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
-----DESCRIPTION-----
|
||||
What it does when used depends on it's "count" (can be set by a lua-script)
|
||||
|
||||
What it does when used depends on it's "count" (can be set by a script)
|
||||
-----SPAWNFLAGS-----
|
||||
none
|
||||
|
||||
-----KEYS-----
|
||||
count:
|
||||
0 (default) - Fire in direction facing
|
||||
1 turn left
|
||||
|
|
169
game/g_ui.c
169
game/g_ui.c
|
@ -8,14 +8,16 @@
|
|||
|
||||
extern void InitTrigger(gentity_t *self);
|
||||
|
||||
/*
|
||||
QUAKED ui_transporter (.5 .5 .5) ? DISABLED
|
||||
/*QUAKED ui_transporter (.5 .5 .5) ? DISABLED
|
||||
-----DESCRIPTION-----
|
||||
Opens the transporter UI.
|
||||
|
||||
DISABLED Entity is disabled
|
||||
-----SPAWNFLAGS-----
|
||||
1: DISABLED - Entity is disabled at spawn
|
||||
|
||||
"swapname" enables/disables entity(NO_ACTIVATOR/SELF flag must be checked for any entity using this)
|
||||
"target" trigger_transporter to use with this ui_transporter
|
||||
-----KEYS-----
|
||||
"swapname" - enables/disables entity(NO_ACTIVATOR/SELF flag must be checked for any entity using this)
|
||||
"target" - trigger_transporter to use with this ui_transporter
|
||||
*/
|
||||
/**
|
||||
* \brief Think function for ui_transporter entity.
|
||||
|
@ -107,14 +109,159 @@ void SP_ui_transporter(gentity_t *ent) {
|
|||
trap_LinkEntity(ent);
|
||||
}
|
||||
|
||||
/*
|
||||
QUAKED ui_holodeck (.5 .5 .5) ? DISABLED
|
||||
Opens the holodeck UI.
|
||||
/*QUAKED ui_msd (.5 .5 .5) ? DISABLED
|
||||
-----DESCRIPTION-----
|
||||
Opens a Master Systems Display. It will display data grabbed from a target_shiphealth.
|
||||
|
||||
DISABLED Entity is disabled
|
||||
-----SPAWNFLAGS-----
|
||||
1: DISABLED - Entity is disabled at spawn
|
||||
|
||||
"swapname" enables/disables entity(NO_ACTIVATOR/SELF flag must be checked for any entity using this)
|
||||
"target" trigger_holodeck to use with this ui_holodeck
|
||||
-----KEYS-----
|
||||
"swapname" - enables/disables entity(NO_ACTIVATOR/SELF flag must be checked for any entity using this)
|
||||
"target" - target_shiphealth to draw info from
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Use function for ui_msd entity.
|
||||
*
|
||||
* Either either (de)activates entity or opens up the MSD.
|
||||
*
|
||||
* \param ent the ui_msd entity
|
||||
* \param activator the entity that has used the ui_msd entity
|
||||
* \param other other entity
|
||||
*
|
||||
* \author Ubergames - Harry Young
|
||||
*/
|
||||
void ui_msd_use(gentity_t *ent, gentity_t *other, gentity_t *activator) {
|
||||
gentity_t *target, *temp = NULL;
|
||||
int maxhull, currhull, maxshield, currshield, shieldstate, warpstate= -2, turbostate= -2, transstate= -2, alertstate= -2;
|
||||
const char *model;
|
||||
|
||||
if(!Q_stricmp(ent->swapname, activator->target)) {
|
||||
ent->flags ^= FL_LOCKED;
|
||||
} else {
|
||||
if(ent->flags & FL_LOCKED) return;
|
||||
target = ent->target_ent;
|
||||
|
||||
maxhull = target->health;
|
||||
currhull = target->count;
|
||||
maxshield = target->splashRadius;
|
||||
currshield = target->n00bCount;
|
||||
shieldstate = target->splashDamage;
|
||||
if(target->falsetarget){
|
||||
while((temp = G_Find(temp, FOFS(truename), target->falsetarget)) != NULL){
|
||||
if(!Q_stricmp(temp->classname, "target_warp")) break;
|
||||
}
|
||||
if(temp){
|
||||
if(temp->sound2to1)//core ejected, we don't really care if it is online
|
||||
warpstate = 2;
|
||||
if(!temp->sound2to1 && temp->sound1to2)//not ejected and not deactivated -> core active
|
||||
warpstate = 1;
|
||||
if(!temp->sound2to1 && !temp->sound1to2)//not ejected and deactivated -> core inactive
|
||||
warpstate = 0;
|
||||
temp = NULL;
|
||||
}
|
||||
}
|
||||
if(target->bluename){
|
||||
while((temp = G_Find(temp, FOFS(swapname), target->bluename)) != NULL){
|
||||
if(!Q_stricmp(temp->classname, "target_turbolift")) break;
|
||||
}
|
||||
if(temp){
|
||||
if (temp->flags & FL_LOCKED)
|
||||
turbostate = 0;
|
||||
else
|
||||
turbostate = 1;
|
||||
temp = NULL;
|
||||
}
|
||||
}
|
||||
if(target->bluesound){
|
||||
while((temp = G_Find(temp, FOFS(swapname), target->bluesound)) != NULL){
|
||||
if(!Q_stricmp(temp->classname, "ui_transporter")) break;
|
||||
}
|
||||
if(temp){
|
||||
if (temp->flags & FL_LOCKED)
|
||||
transstate = 0;
|
||||
else
|
||||
transstate = 1;
|
||||
temp = NULL;
|
||||
}
|
||||
}
|
||||
if(target->falsename){
|
||||
while((temp = G_Find(temp, FOFS(falsename), target->falsename)) != NULL){
|
||||
if(!Q_stricmp(temp->classname, "target_alert")) break;
|
||||
}
|
||||
if(temp){
|
||||
alertstate = temp->damage;
|
||||
temp = NULL;
|
||||
}
|
||||
}
|
||||
model = target->model;
|
||||
trap_SendServerCommand(activator-g_entities, va("ui_msd %i %i %i %i %i %i %i %i %i %s", maxhull, currhull, maxshield, currshield, shieldstate, warpstate, turbostate, transstate, alertstate, model));
|
||||
//Debugging G_Printf(S_COLOR_YELLOW "ui_msd G %i %i %i %i %i %i %i %i %i\n", maxhull, currhull, maxshield, currshield, shieldstate, warpstate, turbostate, transstate, alertstate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Continues setupt of ui_msd entity after all other entites had time to spawn.
|
||||
*
|
||||
* \param ent the ui_msd entity
|
||||
*
|
||||
* \author Ubergames - GSIO01
|
||||
*/
|
||||
void ui_msd_setup(gentity_t *ent) {
|
||||
gentity_t *target = NULL;
|
||||
|
||||
while((target = G_Find(target, FOFS(targetname), ent->target)) != NULL){
|
||||
if(!Q_stricmp(target->classname, "target_shiphealth")) break;
|
||||
}
|
||||
|
||||
if(!target) {
|
||||
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] ui_msd without target_shiphealth as target at %s! Removing Entity.\n", vtos(ent->s.origin)););
|
||||
G_FreeEntity(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->target_ent = target;
|
||||
ent->target_ent->target_ent = ent;
|
||||
|
||||
ent->nextthink = -1;
|
||||
ent->think = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Spawn function of ui_msd entity.
|
||||
*
|
||||
* \param ent the ui_msd entity
|
||||
*
|
||||
* \author GSIO01
|
||||
*/
|
||||
void SP_ui_msd(gentity_t *ent) {
|
||||
|
||||
if(!ent->target) {
|
||||
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] ui_msd without target at %s! Removing Entity.\n", vtos(ent->s.origin)););
|
||||
G_FreeEntity(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
if(ent->spawnflags & 1)
|
||||
ent->flags ^= FL_LOCKED;
|
||||
ent->use = ui_msd_use;
|
||||
ent->think = ui_msd_setup;
|
||||
ent->nextthink = level.time + 500;
|
||||
ent->count = 0;
|
||||
trap_LinkEntity(ent);
|
||||
}
|
||||
|
||||
/*QUAKED ui_holodeck (.5 .5 .5) ? DISABLED
|
||||
-----Description-----
|
||||
Will open the holodeck UI once this is implemented. For now this will not spawn.
|
||||
|
||||
-----SPAWNFLAGS-----
|
||||
1: DISABLED Entity is disabled at spawn
|
||||
|
||||
-----KEYS-----
|
||||
"swapname" - enables/disables entity(NO_ACTIVATOR/SELF flag must be checked for any entity using this)
|
||||
"target" - trigger_holodeck to use with this ui_holodeck
|
||||
*/
|
||||
void ui_holodeck_think(gentity_t *ent) {
|
||||
if(!ent->activator || ent->sound1to2 >= 10000) { /* player disconnect or was idle more than 10 seconds */
|
||||
|
|
|
@ -176,27 +176,87 @@ void func_usable_die(gentity_t *self, gentity_t *inflictor, gentity_t *attacker,
|
|||
}
|
||||
|
||||
/*QUAKED func_usable (0 .5 .8) ? STARTOFF AUTOANIM x ALWAYS_ON NOBLOCKCHECK x x x ADMIN_ONLY NO_ACTIVATOR NO_AREAPORTAL DEACTIVATED
|
||||
START_OFF - the wall will not be there
|
||||
AUTOANIM - If useing an md3, it will animate
|
||||
ALWAYS_ON - Doesn't toggle on and off when used, just fires target
|
||||
NOBLOCKCHECK - Will NOT turn on while something is inside it unless this is checked
|
||||
ADMIN_ONLY - can only be used by admins
|
||||
NO_ACTIVATOR - use the ent itself instead the player as activator
|
||||
NO_AREAPORTAL - don't affect areaportals
|
||||
DEACTIVATED - start deactivated
|
||||
-----DESCRIPTION-----
|
||||
A bmodel that can be used directly by the player's "activate" button.
|
||||
Can be used for visual FX (like alert lights) or as a button.
|
||||
|
||||
A bmodel that can be used directly by the player's "activate" button
|
||||
-----SPAWNFLAGS-----
|
||||
1: START_OFF - the wall will not be there
|
||||
2: AUTOANIM - If useing an md3, it will animate
|
||||
4: X -Not in Use. Holds ANIM_ONCE for models
|
||||
8: ALWAYS_ON - Doesn't toggle on and off when used, just fires target
|
||||
16: NOBLOCKCHECK - Will NOT turn on while something is inside it unless this is checked
|
||||
32: X - Not in Use.
|
||||
64: X - Not in Use.
|
||||
128: X - Not in Use.
|
||||
256: ADMIN_ONLY - can only be used by admins
|
||||
512: NO_ACTIVATOR - use the ent itself instead the player as activator
|
||||
1024: NO_AREAPORTAL - don't affect areaportals
|
||||
2048: DEACTIVATED - start deactivated
|
||||
|
||||
"targetname" When used, will toggle on and off
|
||||
"target" Will fire this target every time it is toggled OFF
|
||||
"model2" .md3 model to also draw
|
||||
"color" constantLight color
|
||||
"light" constantLight radius
|
||||
"wait" amount of time before the object is usable again (only valid with ALWAYS_ON flag)
|
||||
"health" if it has health, it will be used whenever shot at/killed - if you want it to only be used once this way, set health to 1
|
||||
"messageNum" the number relating to the message string that will display when the player scans this usable with a tricorder
|
||||
-----KEYS-----
|
||||
"targetname" - When used, will toggle on and off
|
||||
"target" - Will fire this target every time it is toggled OFF
|
||||
"model2" - .md3 model to also draw
|
||||
"color" - constantLight color
|
||||
"light" - constantLight radius
|
||||
"wait" - amount of time before the object is usable again (only valid with ALWAYS_ON flag)
|
||||
"health" - if it has health, it will be used whenever shot at/killed - if you want it to only be used once this way, set health to 1
|
||||
|
||||
"team" - This can only be used by this team (2 = blue, 1 = red)
|
||||
"luaUse" - lua-function to call from scripts/lua/<mapname>/<mapname>.lua when this entity is used
|
||||
|
||||
"message" - message string that will display when the player scans this usable with a tricorder
|
||||
"messageNum" - the number relating to the message string in the /maps/<mapname>.usables-file that will display when the player scans this usable with a tricorder
|
||||
NOTE: only use one of the above ways on a map at a time
|
||||
|
||||
"team" - This can only be used by this team (2 = blue, 1 = red) 2 will exclude players in RPG-X
|
||||
|
||||
q3map2:
|
||||
"_clone" _clonename of entity to clone brushes from. Note: this entity still needs at least one brush which gets replaced.
|
||||
"_clonename" see _clone
|
||||
"_castShadows" OR "_cs" sets whether the entity casts shadows
|
||||
"_receiveShadows" OR "_rs" sets whether the entity receives shadows
|
||||
|
||||
-----USAGE-----
|
||||
As stated in the description there are 2 ways to use this kind of entity: As a trigger/activator or as Visual effect.
|
||||
It is possible to do both, however giving an entity only one of the functions usually gives the mapper less of a headace.
|
||||
Instead use the usable as VFx only and forward any command trough a target_relay.
|
||||
|
||||
For trigger-usables you need the following keys:
|
||||
"target" - what stuff to fire
|
||||
"wait" - how long to wait before fire again
|
||||
"spawnflags" - ALWAYS_ON (8) is required. You may also be interested in ADMIN_ONLY (256) NO_ACTIATOR (512) and DEACTIVATED (2048)
|
||||
"message" or "messageNum" - display a string if scanned by a tricorder
|
||||
|
||||
For VFX-usables these keys might be interesting:
|
||||
"targetname" - turns visible/invisible when fired
|
||||
"team" - set 2 as this will disallow clients from accidently using this
|
||||
"spawnflags" - Interesting here are START_OFF (1), NOBLOCKCHECK (16) and NO_AREAPORTAL (1024)
|
||||
|
||||
-----LUA-----
|
||||
Sounds for consoles:
|
||||
One of the advantages with luaUse-functions is that you can play sounds on the usable you're using this comes in very handy if you'd like to for example play a sound on the turbolift-usable:
|
||||
|
||||
function turbocontrol(ent, other, activator) --set luaUse to turbocontrol for this to trigger
|
||||
if ent.GetCount(entity.Find("info_turbolift")) == 1 then --for a trubolift in particular you need an external information provider as lua can't deal with bit-flags. In this case turbolift would be offline.
|
||||
sound.PlaySound(ent, "sound/movers/switches/voyneg.mp3", 0);
|
||||
game.MessagePrint(ent.GetNumber(activator), "=C= Unable to comply: The Turbolift is offline.");
|
||||
else
|
||||
sound.PlaySound(ent, "sound/voice/computer/tour/trblftmenu.mp3", 0);
|
||||
end
|
||||
end
|
||||
|
||||
Also if you have a (morer or less) generic console that you want to fire generic console sounds off of you can extend this script for any number of sounds of which one will be picked randomly:
|
||||
|
||||
function consolesounds(ent, other, activator)
|
||||
i = qmath.irandom(1, <insert number of sounds here>);
|
||||
if i == 1 then
|
||||
sound.PlaySound(ent, <insert soundpath here>, 0);
|
||||
end
|
||||
if i == n then
|
||||
sound.PlaySound(ent, <insert soundpath here>, 0);
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -991,6 +991,9 @@ void G_Sound( gentity_t *ent, int soundIndex ) {
|
|||
* @param origin the new origin
|
||||
*/
|
||||
void G_SetOrigin( gentity_t *ent, vec3_t origin ) {
|
||||
// lets try this to fix setting origins for brush ents without origin brush
|
||||
VectorCopy(origin, ent->pos1); // needs testing
|
||||
|
||||
VectorCopy( origin, ent->s.pos.trBase );
|
||||
ent->s.pos.trType = TR_STATIONARY;
|
||||
ent->s.pos.trTime = 0;
|
||||
|
|
|
@ -70,7 +70,7 @@ into a wall.
|
|||
@param v vector to round
|
||||
@param to rounded vector
|
||||
*/
|
||||
void SnapVectorTowards( vec3_t v, vec3_t to ) {
|
||||
void G_Weapon_SnapVectorTowards( vec3_t v, vec3_t to ) {
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
|
@ -116,7 +116,7 @@ static void WP_FireHyperspanner(gentity_t *ent, qboolean alt_fire) {
|
|||
int i, nearest = -1;
|
||||
float nearestd = 65000;
|
||||
vec3_t dVec, end;
|
||||
vec3_t mins = { -40, -40, -40 }, maxs = { 40, 40, 40 };
|
||||
vec3_t mins = { -40, -40, 0 }, maxs = { 40, 40, 0 };
|
||||
char* classnames[] = { "func_breakable", "misc_model_breakable" };
|
||||
|
||||
/* find all vlaid entities in range */
|
||||
|
@ -126,15 +126,25 @@ static void WP_FireHyperspanner(gentity_t *ent, qboolean alt_fire) {
|
|||
trace_t tr;
|
||||
for(i = 0; i < count; i++) {
|
||||
// TODO: fix problems with small distance
|
||||
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.origin, dVec);
|
||||
VectorMA(validEnts[i]->s.origin, 1024, dVec, end);
|
||||
if(validEnts[i]->spawnflags & 512) {
|
||||
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.angles2, dVec);
|
||||
VectorMA(validEnts[i]->s.angles2, 1024, dVec, end);
|
||||
trap_Trace(&tr, validEnts[i]->s.angles2, mins, maxs, end, validEnts[i]->s.number, MASK_SHOT);
|
||||
} else {
|
||||
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.origin, dVec);
|
||||
VectorMA(validEnts[i]->s.origin, 1024, dVec, end);
|
||||
trap_Trace(&tr, validEnts[i]->s.origin, mins, maxs, end, validEnts[i]->s.number, MASK_SHOT);
|
||||
}
|
||||
//G_Printf("Checking entity: %d\n", i);
|
||||
trap_Trace(&tr, validEnts[i]->s.origin, mins, maxs, end, validEnts[i]->s.number, MASK_SHOT);
|
||||
if(tr.entityNum != ent->s.number) {
|
||||
continue;
|
||||
}
|
||||
//G_Printf("Nothing is blocking view ...\n");
|
||||
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.origin, dVec);
|
||||
if(validEnts[i]->spawnflags & 512) {
|
||||
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.angles2, dVec);
|
||||
} else {
|
||||
VectorSubtract(ent->r.currentOrigin, validEnts[i]->s.origin, dVec);
|
||||
}
|
||||
if(VectorLength(dVec) < nearestd) {
|
||||
nearest = validEnts[i]->s.number;
|
||||
nearestd = VectorLength(dVec);
|
||||
|
@ -1100,7 +1110,7 @@ static qboolean SearchTarget(gentity_t *ent, vec3_t start, vec3_t end)
|
|||
trap_Trace (&tr, start, NULL, NULL, end, ent->s.number, MASK_SHOT );
|
||||
traceEnt = &g_entities[ tr.entityNum ];
|
||||
|
||||
if (traceEnt->takedamage && traceEnt->client && !OnSameTeam(traceEnt, &g_entities[ent->r.ownerNum]))
|
||||
if (traceEnt->takedamage && traceEnt->client)
|
||||
{
|
||||
ent->target_ent = traceEnt;
|
||||
VectorSubtract(ent->target_ent->r.currentOrigin, ent->r.currentOrigin, fwd);
|
||||
|
@ -1308,7 +1318,7 @@ static void WP_FireQuantumBurst( gentity_t *ent, qboolean alt_fire )
|
|||
* @param target the target entity
|
||||
* @param attacker the attacker entity
|
||||
*/
|
||||
qboolean LogAccuracyHit( gentity_t *target, gentity_t *attacker ) {
|
||||
qboolean G_Weapon_LogAccuracyHit( gentity_t *target, gentity_t *attacker ) {
|
||||
if( !target->takedamage ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
@ -1329,10 +1339,6 @@ qboolean LogAccuracyHit( gentity_t *target, gentity_t *attacker ) {
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
if ( OnSameTeam( target, attacker ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
@ -1388,7 +1394,7 @@ static void CorrectForwardVector(gentity_t *ent, vec3_t fwd, vec3_t muzzlePoint,
|
|||
|
||||
/*
|
||||
===============
|
||||
CalcMuzzlePoint
|
||||
G_Weapon_CalcMuzzlePoint
|
||||
|
||||
set muzzle location relative to pivoting eye
|
||||
===============
|
||||
|
@ -1487,7 +1493,7 @@ static float WP_ShotAltSize[WP_NUM_WEAPONS] =
|
|||
* @param muzzlePoint the muzzle point
|
||||
* @param projsize projsize
|
||||
*/
|
||||
void CalcMuzzlePoint ( gentity_t *ent, vec3_t fwd, vec3_t rt, vec3_t vup, vec3_t muzzlePoint, float projsize)
|
||||
void G_Weapon_CalcMuzzlePoint ( gentity_t *ent, vec3_t fwd, vec3_t rt, vec3_t vup, vec3_t muzzlePoint, float projsize)
|
||||
{
|
||||
int weapontype;
|
||||
|
||||
|
@ -1660,9 +1666,10 @@ static void WP_SprayVoyagerHypo( gentity_t *ent, qboolean alt_fire )
|
|||
|
||||
tr_ent = &g_entities[tr.entityNum];
|
||||
/* RPG-X: RedTechie - Medics can revive dead people */
|
||||
if( (tr_ent && tr_ent->client) && (tr_ent->health == 1) && (tr_ent->client->ps.pm_type == PM_DEAD)){ tr_entPs = &tr_ent->client->ps;
|
||||
if( (tr_ent && tr_ent->client) && (tr_ent->health == 1) && (tr_ent->client->ps.pm_type == PM_DEAD)){
|
||||
tr_entPs = &tr_ent->client->ps;
|
||||
if(rpg_medicsrevive.integer == 1){
|
||||
ClientSpawn(tr_ent, 1, qtrue);
|
||||
G_Client_Spawn(tr_ent, 1, qtrue);
|
||||
|
||||
/* TiM : Hard coded emote. Makes the player play a 'get up' animation :) */
|
||||
/* G_MoveBox( tr_ent ); */
|
||||
|
@ -1681,30 +1688,16 @@ static void WP_SprayVoyagerHypo( gentity_t *ent, qboolean alt_fire )
|
|||
/*tr_entPs->stats[STAT_HOLDABLE_ITEM] = HI_NONE;*/
|
||||
}
|
||||
/* RPG-X: RedTechie - Regular functions still work */
|
||||
}else if ( tr_ent && tr_ent->client && tr_ent->health > 0 )
|
||||
{
|
||||
} else if ( tr_ent && tr_ent->client && tr_ent->health > 0 ) {
|
||||
tr_entPs = &tr_ent->client->ps;
|
||||
if ( rpg_rpg.integer > 0 && g_gametype.integer < GT_TEAM )
|
||||
{
|
||||
if(alt_fire && rpg_hypoMelee.integer) { /* alt fire and hypo melee enabled */
|
||||
tr_ent->health = 0;
|
||||
G_Client_Die( tr_ent, ent, ent, 100, MOD_KNOCKOUT );
|
||||
G_LogWeaponFire( ent->s.number, WP_12 );
|
||||
} else { /* else just heal */
|
||||
if ( tr_ent->health < tr_entPs->stats[STAT_MAX_HEALTH] )
|
||||
{
|
||||
tr_ent->health = tr_entPs->stats[STAT_MAX_HEALTH]; /*+20*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !OnSameTeam(tr_ent, ent) || g_gametype.integer < GT_TEAM )
|
||||
{
|
||||
tr_ent->health = 0;
|
||||
player_die( tr_ent, ent, ent, 100, MOD_KNOCKOUT );
|
||||
G_LogWeaponFire( ent->s.number, WP_12 );
|
||||
}
|
||||
else if ( OnSameTeam(tr_ent, ent) )
|
||||
{
|
||||
if ( tr_ent->health < tr_entPs->stats[STAT_MAX_HEALTH] )
|
||||
{
|
||||
tr_ent->health = tr_ent->health + 20;
|
||||
}
|
||||
tr_ent->health = tr_entPs->stats[STAT_MAX_HEALTH];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1749,7 +1742,7 @@ void FireWeapon( gentity_t *ent, qboolean alt_fire )
|
|||
{
|
||||
projsize = WP_ShotSize[ent->s.weapon];
|
||||
}
|
||||
CalcMuzzlePoint ( ent, forward, right, up, muzzle, projsize);
|
||||
G_Weapon_CalcMuzzlePoint ( ent, forward, right, up, muzzle, projsize);
|
||||
|
||||
/* fire the specific weapon */
|
||||
switch( ent->s.weapon )
|
||||
|
|
24
game/luaDefParser/LICENSE
Normal file
24
game/luaDefParser/LICENSE
Normal file
|
@ -0,0 +1,24 @@
|
|||
Copyright (c) 2012 Walter Julius Hennecke, Ubergames
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to
|
||||
whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
|
||||
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
24
game/luaDefParser/README
Normal file
24
game/luaDefParser/README
Normal file
|
@ -0,0 +1,24 @@
|
|||
Lua Definitions Parser (WIP)
|
||||
|
||||
Required tools:
|
||||
Linux:
|
||||
* flex
|
||||
Windows:
|
||||
* mingw
|
||||
|
||||
Building:
|
||||
Linux:
|
||||
flex quake.l
|
||||
gcc lex.yy.c -o luaDefParser -lfl
|
||||
Mac:
|
||||
flex quake.l
|
||||
gcc lex.yy.c -o luaDefParser -lfl
|
||||
Windows:
|
||||
flex quake.l
|
||||
gcc lex.yy.c -o luaDefParser /lib/libfl.a
|
||||
|
||||
Usage:
|
||||
./luaDefParser <code file> <output file>
|
||||
|
||||
Example:
|
||||
./luaDefParser game/lua_game.c module_game.lyx
|
171
game/luaDefParser/export_lyx.c
Normal file
171
game/luaDefParser/export_lyx.c
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
Copyright (c) 2012 Walter Julius Hennecke, Ubergames
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to
|
||||
whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
|
||||
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "export_lyx.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
function_p create_function(void) {
|
||||
function_p n = (function_p)malloc(sizeof(function_s));
|
||||
|
||||
if(n == NULL) return NULL;
|
||||
|
||||
n->desc = create_list();
|
||||
if(n->desc == NULL) {
|
||||
free(n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n->params = create_list();
|
||||
if(n->params == NULL) {
|
||||
destroy_list(n->desc);
|
||||
free(n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void destroy_function(function_p f) {
|
||||
if(f != NULL) {
|
||||
if(f->desc != NULL) {
|
||||
destroy_list(f->desc);
|
||||
}
|
||||
if(f->params != NULL) {
|
||||
destroy_list(f->params);
|
||||
}
|
||||
free(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
desc_p create_desc(void) {
|
||||
desc_p n = (desc_p)malloc(sizeof(desc_s));
|
||||
|
||||
if(n == NULL) return NULL;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void destroy_desc(desc_p d) {
|
||||
if(d != NULL) {
|
||||
if(d->text != NULL) {
|
||||
free(d->text);
|
||||
}
|
||||
|
||||
free(d);
|
||||
}
|
||||
}
|
||||
|
||||
param_p create_param(void) {
|
||||
param_p n = (param_p)malloc(sizeof(param_s));
|
||||
|
||||
if(n == NULL) return NULL;
|
||||
|
||||
n->desc = create_list();
|
||||
if(n->desc == NULL) {
|
||||
free(n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void destroy_param(param_p p) {
|
||||
if (p != NULL) {
|
||||
if(p->name != NULL) {
|
||||
free(p->name);
|
||||
}
|
||||
if(p->desc != NULL) {
|
||||
destroy_list(p->desc);
|
||||
}
|
||||
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
void write_desc(list_p d, FILE* f) {
|
||||
list_iter_p iter;
|
||||
desc_p d;
|
||||
|
||||
if(d == NULL || f == NULL) return;
|
||||
|
||||
fprintf(f, "%s", BEGIN_STANDART);
|
||||
|
||||
for(d = list_next(iter); d != NULL; d = list_next(iter)) {
|
||||
fprintf(f, "%s", d->text);
|
||||
}
|
||||
|
||||
fprintf(f, "%s", END_LAYOUT);
|
||||
}
|
||||
|
||||
void write_params(list_p p, FILE* f) {
|
||||
list_iter_p iter;
|
||||
param_p d;
|
||||
|
||||
if(p == NULL || f == NULL) return;
|
||||
|
||||
fprintf(f, "%s", BEGIN_TABULAR);
|
||||
iter = list_iterator(p);
|
||||
for(d = list_next(iter); d != NULL; d = list_next(iter)) {
|
||||
write_param(d, f);
|
||||
}
|
||||
fprintf(f, "%s", END_TABULAR);
|
||||
}
|
||||
|
||||
void write_param(param_p p, FILE* f) {
|
||||
list_iter_p iter;
|
||||
desc_p d;
|
||||
|
||||
if(p == NULL || f == NULL) return;
|
||||
|
||||
fprintf(f, "%s%s", BEGIN_TABULAR_ROW, BEGIN_TABULAR_CELL);
|
||||
switch(p->type) {
|
||||
case FLOAT:
|
||||
fprintf(f, "float\n");
|
||||
break;
|
||||
case ENTITY:
|
||||
fprintf(f, "entity\n");
|
||||
break;
|
||||
case VECTOR:
|
||||
fprintf(f, "vector\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "write_param - Uknown param type %d\n", p->type);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(f, "%s%s", END_TABULAR_CELL, BEGIN_TABULAR_CELL);
|
||||
fprintf(f, "%s\n", p->name);
|
||||
fprintf(f, "%s%s", END_TABULAR_CELL, BEGIN_TABULAR_CELL);
|
||||
iter = list_iterator(p->desc, FRONT);
|
||||
for(d = list_next(iter); d != NULL; d = list_next(iter)) {
|
||||
fprintf(f, "%s", d->desc);
|
||||
}
|
||||
fprintf(f, "%s%s%s", END_TABULAR_CELL, END_TABULAR_ROW, END_TABULAR);
|
||||
}
|
||||
|
78
game/luaDefParser/export_lyx.h
Normal file
78
game/luaDefParser/export_lyx.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright (c) 2012 Walter Julius Hennecke, Ubergames
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to
|
||||
whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
|
||||
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef EXPORT_LYX_H_
|
||||
#define EXPORT_LYX_H_
|
||||
|
||||
#include "../../game/list.h"
|
||||
|
||||
typedef struct function_s* function_p;
|
||||
struct function_s {
|
||||
char* name;
|
||||
list_p desc;
|
||||
list_p params;
|
||||
} function_s;
|
||||
function_p create_function(void);
|
||||
void destroy_function(function_p f);
|
||||
|
||||
typedef struct desc_s* desc_p;
|
||||
struct desc_s {
|
||||
char* text;
|
||||
} desc_s;
|
||||
desc_p create_desc(void);
|
||||
void destroy_desc(desc_p d);
|
||||
|
||||
typedef enum { FLOAT, ENTITY, VECTOR } pType;
|
||||
|
||||
typedef struct param_s* param_p;
|
||||
struct param_s {
|
||||
pType type;
|
||||
char* name;
|
||||
list_p desc;
|
||||
} param_s;
|
||||
param_p create_param(void);
|
||||
void destroy_param(param_p p);
|
||||
|
||||
void write_function(function_p f, FILE* f);
|
||||
void write_desc(list_p d, FILE* f);
|
||||
void wrtie_params(list_p p, FILE* f);
|
||||
void write_param(param_p p, FILE* f);
|
||||
|
||||
#define BEGIN_SECTION "\\begin_layout Section"
|
||||
#define BEGIN_SUBSECTION "\\begin_layout Subsection"
|
||||
#define BEGIN_STANDART "\\begin_layout Standart"
|
||||
#define END_LAYOUT "\\ent_layout
|
||||
|
||||
#define BEGIN_TABULAR "\\begin_layout Standard\n\\begin_inset Tabular\n<lyxtabular version=\"3\" rows=\"2\" columns=\"3\">\n<features tabularvalignment=\"middle\">\n<column alignment=\"center\" valignment=\"top\" width=\"0\">\n<column alignment=\"center\" valignment=\"top\" width=\"0\">\n<column alignment=\"center\" valignment=\"top\" width=\"0\">\n"
|
||||
#define BEGIN_TABULAR_ROW "<row>\n"
|
||||
#define END_TABULAR_ROW "</row>\n"
|
||||
#define BEGIN_TABULAR_CELL "<cell allignment=\"center\" valignment=\"top\" usebox=\"none\">\n\\begin_inset Text\n\\begin_layout Plain Layout\n"
|
||||
#define END_TABULAR_CELL "\\end_layout\n\\end_inset\n</cell>\n"
|
||||
#define END_TABULAR "</lyxtabular>\n\\end_inset\n\\end_layout\n"
|
||||
|
||||
|
||||
#endif
|
119
game/luaDefParser/luadef.l
Normal file
119
game/luaDefParser/luadef.l
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright (c) 2012 Walter Julius Hennecke, Ubergames
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to
|
||||
whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
|
||||
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
FILE* out;
|
||||
|
||||
int lastState = 0;
|
||||
|
||||
#define YY_DECL int yylex()
|
||||
%}
|
||||
|
||||
%x C_COMMENT
|
||||
%x C_FUNCTION
|
||||
%x C_DESC
|
||||
%x C_PARAM
|
||||
%x C_STRING
|
||||
%x C_MODULE
|
||||
FUNCTEXT [a-zA-z0-9.(), \t]+
|
||||
STRING [a-zA-z0-9.(), \t\n!?<>/\\\[\]\{\}]+
|
||||
VAR [a-zA-Z0-9]+
|
||||
%%
|
||||
"/*" { BEGIN(C_COMMENT); puts("Found a comment"); }
|
||||
<C_COMMENT>"*/" { BEGIN(INITIAL); puts("End of comment"); }
|
||||
<C_COMMENT>[ \t\n*] ;
|
||||
<C_COMMENT>"luamodule" { BEGIN(C_MODULE); puts("Found a luamodule"); }
|
||||
<C_COMMENT>"\\function" { BEGIN(C_FUNCTION); puts("Found a \\function"); }
|
||||
<C_COMMENT>"\\desc" { BEGIN(C_DESC); puts("Found a \\desc"); }
|
||||
<C_COMMENT>"\\param" { BEGIN(C_PARAM); puts("Found a \\param"); }
|
||||
<C_COMMENT>[ \t\n]* ;
|
||||
<C_COMMENT>. ;
|
||||
|
||||
<C_MODULE>[ \t\n] ;
|
||||
<C_MODULE>{VAR} { BEGIN(C_COMMENT); printf("module name: %s\n", yytext); }
|
||||
<C_MODULE>. ;
|
||||
|
||||
<C_FUNCTION>";" { BEGIN(C_COMMENT); puts("End of function"); }
|
||||
<C_FUNCTION>{FUNCTEXT} { printf("function text: %s\n", yytext); }
|
||||
<C_FUNCTION>. ;
|
||||
|
||||
<C_DESC>";" { BEGIN(C_COMMENT); puts("End of desc"); }
|
||||
<C_DESC>"\"" { BEGIN(C_STRING); lastState = C_DESC; puts("Found a String"); }
|
||||
<C_DESC>[.\n]+ { printf("desc text: %s\n", yytext); }
|
||||
<C_DESC>. ;
|
||||
|
||||
<C_PARAM>";" { BEGIN(C_COMMENT); puts("End of param"); }
|
||||
<C_PARAM>"\"" { BEGIN(C_STRING); lastState = C_PARAM; puts("Found a string"); }
|
||||
<C_PARAM>[ \t] ;
|
||||
<C_PARAM>"float" { printf("foud type: %s\n", yytext); }
|
||||
<C_PARAM>"vec" { printf("foud type: %s\n", yytext); }
|
||||
<C_PARAM>"vector" { printf("foud type: %s\n", yytext); }
|
||||
<C_PARAM>"ent" { printf("foud type: %s\n", yytext); }
|
||||
<C_PARAM>"entity" { printf("foud type: %s\n", yytext); }
|
||||
<C_PARAM>{VAR} { printf("foud name: %s\n", yytext); }
|
||||
<C_PARAM>. ;
|
||||
|
||||
<C_STRING>"\"" { BEGIN(lastState); puts("End of String"); }
|
||||
<C_STRING>{STRING} { printf("string text: %s\n", yytext); }
|
||||
<C_STRING>. ;
|
||||
|
||||
"\n" ;
|
||||
. ;
|
||||
%%
|
||||
|
||||
main(int argc, char *argv[]) {
|
||||
FILE *in;
|
||||
|
||||
if(argc < 3) {
|
||||
printf("Usage: %s <input file> <output file>\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
in = fopen(argv[1], "r");
|
||||
if(!in) {
|
||||
printf("Could not open \'%s\'.\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
out = fopen(argv[2], "a");
|
||||
if(!out) {
|
||||
fclose(in);
|
||||
printf("Could not open \'%s\'.\n", argv[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
yyin = in;
|
||||
|
||||
yylex();
|
||||
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
}
|
16
game/luaDefParser/test.c
Normal file
16
game/luaDefParser/test.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* luamodule test */
|
||||
|
||||
int a;
|
||||
|
||||
/* test */
|
||||
void test() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* \function test.func(float a, entity b);
|
||||
* \param float a "this is a";
|
||||
* \desc test 123;
|
||||
* \desc "test
|
||||
* test2";
|
||||
*/
|
|
@ -40,24 +40,32 @@ static int Entity_MMBRefit(lua_State * L)
|
|||
if( !Q_stricmp( MMB->model, "models/mapobjects/borg/blite.md3" )){ //alcove light
|
||||
MMB->splashDamage = 75;
|
||||
MMB->splashRadius = 75;
|
||||
MMB->s.powerups = 3;//glass and metal, may reduce this to glass only toh
|
||||
MMB->s.powerups = 3;//glass and metal, may reduce this to glass only
|
||||
MMB->spawnflags = 258;
|
||||
G_CallSpawn(MMB);
|
||||
}else if( !Q_stricmp( MMB->model, "models/mapobjects/borg/circuit_1.md3" )){ //those things that look like a handle
|
||||
MMB->splashDamage = 75;
|
||||
MMB->splashRadius = 75;
|
||||
MMB->s.powerups = 1;//metal
|
||||
MMB->s.powerups = 1;//
|
||||
MMB->spawnflags = 263;
|
||||
G_CallSpawn(MMB);
|
||||
}else if( !Q_stricmp( MMB->model, "models/mapobjects/borg/circuit_2.md3" )){ //the isosceles triangle looking box
|
||||
MMB->splashDamage = 75;
|
||||
MMB->splashRadius = 75;
|
||||
MMB->s.powerups = 1;//metal
|
||||
MMB->s.powerups = 1;//
|
||||
MMB->spawnflags = 263;
|
||||
G_CallSpawn(MMB);
|
||||
}else if( !Q_stricmp( MMB->model, "models/mapobjects/borg/circuit_3.md3" )){ //the other triangle looking box
|
||||
MMB->splashDamage = 75;
|
||||
MMB->splashRadius = 75;
|
||||
MMB->s.powerups = 1;//metal
|
||||
MMB->spawnflags = 263;
|
||||
G_CallSpawn(MMB);
|
||||
}else if( !Q_stricmp( MMB->model, "models/mapobjects/borg/vynclumn.md3" )){ //no description needed ^^
|
||||
MMB->splashDamage = 9999;
|
||||
MMB->splashRadius = 9999;
|
||||
MMB->s.powerups = 1;//metal
|
||||
MMB->spawnflags = 2;
|
||||
MMB->spawnflags = 263;
|
||||
G_CallSpawn(MMB);
|
||||
}else continue;//we are not looking for this kind of MMB
|
||||
}
|
||||
|
@ -134,6 +142,34 @@ static int Entity_Find(lua_State * L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// entity.FindMMB(vector origin)
|
||||
// Returns the misc_model_breakable entity that has a matching MMB->s.origin.
|
||||
// Requires vector as input.
|
||||
// You can get the s.origin ingame as an admin/developer by pointing at the MMB ingame and using the /getorigin-command.
|
||||
static int Entity_FindMMB(lua_State * L)
|
||||
{
|
||||
gentity_t *t = NULL, *MMB = NULL;
|
||||
vec_t *vec, *origin;
|
||||
|
||||
vec = Lua_GetVector(L, 2);
|
||||
|
||||
while((MMB = G_Find(MMB, FOFS(classname), "misc_model_breakable")) != NULL){
|
||||
origin = MMB->s.origin;
|
||||
if(vec[0] == origin[0] && vec[1] == origin[1] && vec[2] == origin[2]){
|
||||
t = MMB;
|
||||
break;
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(!t)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
Lua_PushEntity(L, t);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// entity.Use(entity ent)
|
||||
// Uses ent.
|
||||
static int Entity_Use(lua_State * L)
|
||||
|
@ -469,6 +505,9 @@ static int Entity_DelayedCallSpawn(lua_State *L) {
|
|||
if(!lent || !lent->e)
|
||||
return 1;
|
||||
|
||||
if(!Q_stricmp(lent->e->classname, "target_selfdestruct"))
|
||||
return 1; //we will not selfdestruct this way
|
||||
|
||||
delay = luaL_checkint(L, 2);
|
||||
|
||||
if(!delay)
|
||||
|
@ -494,6 +533,9 @@ static int Entity_CallSpawn(lua_State *L) {
|
|||
if(lent)
|
||||
e = lent->e;
|
||||
|
||||
if(!Q_stricmp(lent->e->classname, "target_selfdestruct"))
|
||||
return 1; //we will not selfdestruct this way
|
||||
|
||||
if(e) {
|
||||
LUA_DEBUG("Entity_CallSpawn - G_CallSpawn");
|
||||
trap_UnlinkEntity(e);
|
||||
|
@ -2813,6 +2855,7 @@ static int Entity_SetTeammaster(lua_State *L) {
|
|||
static const luaL_Reg Entity_ctor[] = {
|
||||
{"Spawn", Entity_Spawn},
|
||||
{"Find", Entity_Find},
|
||||
{"FindMMB", Entity_FindMMB},
|
||||
{"FindNumber", Entity_FindNumber},
|
||||
{"FindBModel", Entity_FindBModel},
|
||||
{"GetTarget", Entity_GetTarget},
|
||||
|
|
|
@ -69,6 +69,14 @@ extern void Reached_Train(gentity_t *ent);
|
|||
extern void Think_SetupTrainTargets(gentity_t *ent);
|
||||
extern void SetMoverState(gentity_t *ent, moverState_t moverState, int time);
|
||||
|
||||
/* This is an example for a parseable comment that describes a lua function. */
|
||||
/*
|
||||
* \function mover.AsTrain(entity mover, entity target, float speed)
|
||||
* \param entity mover entity to move.
|
||||
* \param entity target path_corner entity to move to.
|
||||
* \param float speed Speed to move with to the first path_corner.
|
||||
* \desc Moves an entity like a func_train entity. Targets have to be path_corner entities.
|
||||
*/
|
||||
// mover.AsTrain(entity mover, entity target, float speed)
|
||||
// Moves an entity like a func_train entity. Targets have to be path_corner entities.
|
||||
// * ent the entity to move
|
||||
|
@ -203,6 +211,51 @@ static int Mover_SetAngles(lua_State * L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// mover.SetAngles2(entity ent, vector angles) or
|
||||
// mover.SetAngles2(entity ent, float y, float z, float x)
|
||||
// Sets the angles of ent to the specified value(s).
|
||||
// Values are sorted Pitch (around Y-Axis), Yaw (around Z-Axis) and
|
||||
// Roll (around X-Axis). These can also be stowed in a vector angles.
|
||||
static int Mover_SetAngles2(lua_State * L)
|
||||
{
|
||||
vec3_t newAngles;
|
||||
lent_t *lent;
|
||||
gentity_t *ent = NULL;
|
||||
vec_t *target;
|
||||
int id = 0;
|
||||
|
||||
if(lua_isnumber(L, 1)) {
|
||||
id = luaL_checkint(L, 1);
|
||||
if(id < 0 || id > MAX_GENTITIES - 1) return 1;
|
||||
ent = &g_entities[id];
|
||||
if(!ent) return 1;
|
||||
} else {
|
||||
lent = Lua_GetEntity(L, 1);
|
||||
if(!lent || !lent->e) return 1;
|
||||
ent = lent->e;
|
||||
}
|
||||
|
||||
if(Lua_IsVector(L, 2))
|
||||
{
|
||||
target = Lua_GetVector(L, 2);
|
||||
VectorCopy(target, newAngles);
|
||||
}
|
||||
else
|
||||
{
|
||||
newAngles[0] = luaL_checkint(L, 2);
|
||||
newAngles[1] = luaL_checkint(L, 3);
|
||||
newAngles[2] = luaL_checkint(L, 4);
|
||||
}
|
||||
LUA_DEBUG("Mover_SetAngles2 - start: ent=%d angles=%s", ent->s.number, vtos(newAngles));
|
||||
if(ent)
|
||||
{
|
||||
VectorCopy(newAngles, ent->s.angles2);
|
||||
trap_LinkEntity(ent);
|
||||
LUA_DEBUG("Mover_SetAngles2 - return: moved");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// mover.SetPosition(entity ent, vector pos) or
|
||||
// mover.SetPosition(entity ent, float x, float y, float z)
|
||||
// Set the position of ent to the specified value(s). Can also be stowed in a vector pos.
|
||||
|
@ -369,6 +422,7 @@ static const luaL_Reg lib_mover[] = {
|
|||
{"SetOrigin", Mover_SetPosition},
|
||||
{"ToPosition", Mover_ToPosition},
|
||||
{"SetAngles", Mover_SetAngles},
|
||||
{"SetAngles2", Mover_SetAngles2},
|
||||
{"ToAngles", Mover_ToAngles},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
|
|
@ -242,6 +242,22 @@ static int Qmath_Crandom(lua_State * L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// qmath.irandom(int i, int j)
|
||||
// Returns a random integer from the range of integers defined by and including i and j.
|
||||
static int Qmath_Irandom(lua_State * L)
|
||||
{
|
||||
lua_pushnumber(L, irandom(luaL_checkint(L, 1), luaL_checkint(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// qmath.flrandom(float i, float j)
|
||||
// Returns a random float from the range of floats defined by and including i and j.
|
||||
static int Qmath_FLrandom(lua_State * L)
|
||||
{
|
||||
lua_pushnumber(L, flrandom(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg lib_qmath[] = {
|
||||
{"abs", Qmath_Abs},
|
||||
{"sin", Qmath_Sin},
|
||||
|
@ -267,8 +283,10 @@ static const luaL_Reg lib_qmath[] = {
|
|||
{"pow", Qmath_Pow},
|
||||
{"rad", Qmath_Rad},
|
||||
{"rand", Qmath_Rand},
|
||||
{"candom", Qmath_Crandom},
|
||||
{"random", Qmath_Random},
|
||||
{"crandom", Qmath_Crandom},
|
||||
{"irandom", Qmath_Irandom},
|
||||
{"flrandom", Qmath_FLrandom},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -738,6 +738,35 @@ char* Q_strrchr( const char* string, int c )
|
|||
return sp;
|
||||
}
|
||||
|
||||
char* Q_strtok(char* str, const char *tok, int size) {
|
||||
char *ptr;
|
||||
char *result;
|
||||
int i, l;
|
||||
|
||||
if(str == NULL || tok == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = (char *)str;
|
||||
|
||||
for(i = 0; i < strlen(str); i++) {
|
||||
for(l = 0; l < size; l++) {
|
||||
if(ptr[i] == tok[l]) {
|
||||
result = (char *)malloc(sizeof(char)+(i+1));
|
||||
if(result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(result, str, i);
|
||||
result[i] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Q_strncpyz
|
||||
|
|
|
@ -688,9 +688,17 @@ int Q_isalpha( int c );
|
|||
int Q_stricmp (const char *s1, const char *s2);
|
||||
int Q_strncmp (const char *s1, const char *s2, int n);
|
||||
int Q_stricmpn (const char *s1, const char *s2, int n);
|
||||
char *Q_strlwr( char *s1 );
|
||||
char *Q_strupr( char *s1 );
|
||||
char *Q_strrchr( const char* string, int c );
|
||||
char* Q_strlwr( char *s1 );
|
||||
char* Q_strupr( char *s1 );
|
||||
char* Q_strrchr( const char* string, int c );
|
||||
/**
|
||||
* Goes through a given str searching for one of the given tokens.
|
||||
* If it finds one it returns a new string containing everything
|
||||
* from str until the found token (Note: remember to free the result
|
||||
* if no longer needed). Returns NULL if no token is found. Make sure
|
||||
* to adjust str for the next call yourself as this function won't do that.
|
||||
*/
|
||||
char* Q_strtok(char* str, const char *tok, int size);
|
||||
|
||||
// buffer size safe library replacements
|
||||
void Q_strncpyz( char *dest, const char *src, int destsize );
|
||||
|
|
|
@ -1298,6 +1298,22 @@ qboolean UI_ConsoleCommand( void ) {
|
|||
return qtrue;
|
||||
}
|
||||
|
||||
if ( Q_stricmp( cmd, "ui_msd" ) == 0 ) {
|
||||
static char ui_msd1[MAX_STRING_CHARS], ui_msd2[MAX_STRING_CHARS], ui_msd3[MAX_STRING_CHARS], ui_msd4[MAX_STRING_CHARS], ui_msd5[MAX_STRING_CHARS], ui_msd6[MAX_STRING_CHARS], ui_msd7[MAX_STRING_CHARS], ui_msd8[MAX_STRING_CHARS], ui_msd9[MAX_STRING_CHARS], ui_msd10[MAX_STRING_CHARS];
|
||||
trap_Argv( 1, ui_msd1, sizeof( ui_msd1 ) );
|
||||
trap_Argv( 2, ui_msd2, sizeof( ui_msd2 ) );
|
||||
trap_Argv( 3, ui_msd3, sizeof( ui_msd3 ) );
|
||||
trap_Argv( 4, ui_msd4, sizeof( ui_msd4 ) );
|
||||
trap_Argv( 5, ui_msd5, sizeof( ui_msd5 ) );
|
||||
trap_Argv( 6, ui_msd6, sizeof( ui_msd6 ) );
|
||||
trap_Argv( 7, ui_msd7, sizeof( ui_msd7 ) );
|
||||
trap_Argv( 8, ui_msd8, sizeof( ui_msd8 ) );
|
||||
trap_Argv( 9, ui_msd9, sizeof( ui_msd9 ) );
|
||||
trap_Argv( 10, ui_msd10, sizeof( ui_msd10 ) );
|
||||
UI_msdMenu( atoi(ui_msd1), atoi(ui_msd2), atoi(ui_msd3), atoi(ui_msd4), atoi(ui_msd5), atoi(ui_msd6), atoi(ui_msd7), atoi(ui_msd8), atoi(ui_msd9), ui_msd10);
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if ( Q_stricmp( cmd, "ui_transporter" ) == 0 ) {
|
||||
UI_TransporterMenu( atoi(UI_Argv( 1 )) );
|
||||
return qtrue;
|
||||
|
|
|
@ -214,6 +214,7 @@ static creditsInfo_t creditsInfo[MAX_MENUS] =
|
|||
{ NAME_SIMMO, TITLE_LCARS },
|
||||
{ NAME_TIM, TITLE_AD2D },
|
||||
{ NAME_SCOOTER, TITLE_AD2D },
|
||||
{ "Alexander Richardson", "Master System Display's" },
|
||||
{ NAME_KURO, TITLE_RANKS },
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1850,6 +1850,11 @@ extern void HoloDataReceived(const char *data);
|
|||
extern void UI_AdminMenu( qboolean fromConsole );
|
||||
extern void UI_AdminMenu_Cache( void );
|
||||
|
||||
//
|
||||
// ui_msd.c
|
||||
//
|
||||
extern void UI_msdMenu(int maxhull, int currhull, int maxshield, int currshield, int shieldstate, int warpstate, int turbostate, int transstate, int alertstate, char *model);
|
||||
|
||||
//
|
||||
// ui_transporter.c
|
||||
//
|
||||
|
|
388
ui/ui_msd.c
Normal file
388
ui/ui_msd.c
Normal file
|
@ -0,0 +1,388 @@
|
|||
/**********************************************************************
|
||||
UI_msd.C
|
||||
|
||||
User interface trigger from within game
|
||||
**********************************************************************/
|
||||
#include "ui_local.h"
|
||||
|
||||
typedef struct //static
|
||||
{
|
||||
menuframework_s menu;
|
||||
menubitmap_s quitmenu;
|
||||
|
||||
int maxhull;
|
||||
int currhull;
|
||||
int maxshield;
|
||||
int currshield;
|
||||
int shieldstate;
|
||||
int warpstate;
|
||||
int turbostate;
|
||||
int transstate;
|
||||
int alertstate;
|
||||
const char *model;
|
||||
} msd_t;
|
||||
|
||||
msd_t s_msd;
|
||||
|
||||
//s_msd.maxhull
|
||||
|
||||
#define ID_QUIT 10
|
||||
|
||||
void UI_msdMenu_Cache (void);
|
||||
|
||||
/*
|
||||
=================
|
||||
M_msd_Event
|
||||
=================
|
||||
*/
|
||||
static void M_msd_Event (void* ptr, int notification)
|
||||
{
|
||||
int id;
|
||||
//menubitmap_s *holdLocation;
|
||||
//menubitmap_s *holdServer;
|
||||
|
||||
id = ((menucommon_s*)ptr)->id;
|
||||
|
||||
/*if ( notification != QM_ACTIVATED )
|
||||
{
|
||||
return;
|
||||
}*/
|
||||
|
||||
if ((id == ID_QUIT) && (notification == QM_ACTIVATED))
|
||||
UI_PopMenu();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
msdMenu_Key
|
||||
=================
|
||||
*/
|
||||
sfxHandle_t msdMenu_Key (int key)
|
||||
{
|
||||
return ( Menu_DefaultKey( &s_msd.menu, key ) );
|
||||
}
|
||||
|
||||
extern qhandle_t leftRound;
|
||||
extern qhandle_t corner_ul_24_60;
|
||||
extern qhandle_t corner_ll_12_60;
|
||||
qhandle_t loading1;
|
||||
qhandle_t loading2;
|
||||
qhandle_t loading3;
|
||||
qhandle_t loading4;
|
||||
qhandle_t loading5;
|
||||
qhandle_t redalert;
|
||||
qhandle_t yellowalert;
|
||||
qhandle_t bluealert;
|
||||
qhandle_t model;
|
||||
|
||||
/*
|
||||
=================
|
||||
M_msdMenu_Graphics
|
||||
=================
|
||||
*/
|
||||
static void M_msdMenu_Graphics (void)
|
||||
{
|
||||
/*Notes:
|
||||
Color-Types in Frame:
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE3]);
|
||||
Blue Alert:
|
||||
trap_R_SetColor( colorTable[CT_BLUE] );
|
||||
Yellow Alert:
|
||||
trap_R_SetColor( colorTable[CT_YELLOW] );
|
||||
Red Alert:
|
||||
trap_R_SetColor( colorTable[CT_RED] );
|
||||
|
||||
*/
|
||||
//menubitmap_s *holdDeck;
|
||||
//int i;
|
||||
int length,xTurboStart, lengthshield, lengthhull;
|
||||
//int numColor, roundColor;
|
||||
|
||||
// Draw the basic screen frame
|
||||
|
||||
// Upper corners
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE1]);
|
||||
UI_DrawHandlePic( 20, 24, 64, 32, corner_ul_24_60); // Upper corner
|
||||
|
||||
// Lower corners
|
||||
//colorTable[CT_VDKPURPLE2]
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE3]);
|
||||
UI_DrawHandlePic( 20, 440, 64, 16, corner_ll_12_60); //
|
||||
|
||||
xTurboStart = 604;
|
||||
length = UI_ProportionalStringWidth( "MASTER SYSTEMS DISPLAY",UI_BIGFONT);
|
||||
length += 4;
|
||||
|
||||
// Upper half
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE1]); //DKGOLD1
|
||||
UI_DrawHandlePic( 79, 24, xTurboStart - (79 + length), PROP_BIG_HEIGHT, uis.whiteShader); // Top left line
|
||||
UI_DrawHandlePic( 20, 60, 60, 40, uis.whiteShader); //
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE3]);
|
||||
UI_DrawHandlePic( 20, 106, 60, 11, uis.whiteShader); //
|
||||
if(s_msd.alertstate == 2){
|
||||
UI_DrawHandlePic( 20, 123, 60, 250, redalert); // Alert Fade Red
|
||||
}else if(s_msd.alertstate == 1){
|
||||
UI_DrawHandlePic( 20, 123, 60, 250, yellowalert); // Alert Fade Yellow
|
||||
}else if(s_msd.alertstate == 3){
|
||||
UI_DrawHandlePic( 20, 123, 60, 250, bluealert); // Alert Fade Blue
|
||||
}else{
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE1]); //DKGOLD1
|
||||
UI_DrawHandlePic( 20, 123, 60, 250, uis.whiteShader); // Left hand column
|
||||
}
|
||||
|
||||
// Lower half
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE3] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 20, 380, 60, 70, uis.whiteShader); // Left Column
|
||||
|
||||
// Bottom line
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE3] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 69, 443, 287, 12, uis.whiteShader); //
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE1]); //colorTable[CT_DKGOLD1]
|
||||
UI_DrawHandlePic(364, 443, 260, 12, uis.whiteShader); // Bottom line
|
||||
|
||||
if(s_msd.alertstate == 2)
|
||||
UI_DrawProportionalString( xTurboStart, 24,
|
||||
"MASTER SYSTEMS DISPLAY", UI_BIGFONT | UI_RIGHT, colorTable[CT_RED]);
|
||||
else if(s_msd.alertstate == 1)
|
||||
UI_DrawProportionalString( xTurboStart, 24,
|
||||
"MASTER SYSTEMS DISPLAY", UI_BIGFONT | UI_RIGHT, colorTable[CT_YELLOW]);
|
||||
else if(s_msd.alertstate == 3)
|
||||
UI_DrawProportionalString( xTurboStart, 24,
|
||||
"MASTER SYSTEMS DISPLAY", UI_BIGFONT | UI_RIGHT, colorTable[CT_BLUE]);
|
||||
else
|
||||
UI_DrawProportionalString( xTurboStart, 24,
|
||||
"MASTER SYSTEMS DISPLAY", UI_BIGFONT | UI_RIGHT, colorTable[CT_WHITE]);
|
||||
|
||||
trap_R_SetColor( colorTable[CT_DKPURPLE1]); //DKGOLD1
|
||||
UI_DrawHandlePic( 607, 24, -16, 32, leftRound);
|
||||
|
||||
// MSD Model
|
||||
UI_DrawHandlePic( 100, 60, 500, 250, model);
|
||||
|
||||
// health Bars
|
||||
lengthshield = (int)(498 * s_msd.currshield / s_msd.maxshield);
|
||||
lengthhull = (int)(498 * s_msd.currhull / s_msd.maxhull);
|
||||
|
||||
trap_R_SetColor( colorTable[CT_WHITE] );
|
||||
UI_DrawHandlePic( 100, 320, 500, 49, uis.whiteShader); //background
|
||||
trap_R_SetColor( colorTable[CT_BLACK] );
|
||||
//trap_R_SetColor( colorTable[CT_VDKPURPLE2] );
|
||||
UI_DrawHandlePic( 101, 321, 498, 23, uis.whiteShader); //Shield Bar BG
|
||||
trap_R_SetColor( colorTable[CT_BLACK] );
|
||||
//trap_R_SetColor( colorTable[CT_VDKORANGE] );
|
||||
UI_DrawHandlePic( 101, 345, 498, 23, uis.whiteShader); //Health Bar BG
|
||||
|
||||
//Shield Bar
|
||||
if(s_msd.shieldstate == 1){
|
||||
trap_R_SetColor( colorTable[CT_BLUE] );
|
||||
UI_DrawHandlePic( 101, 321, lengthshield, 23, uis.whiteShader);
|
||||
UI_DrawProportionalString(103, 323, va("Shields at %.1f Percent", (lengthshield / 4.98)), UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.shieldstate == 0){
|
||||
UI_DrawProportionalString(103, 323, "Shields are on standby", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.shieldstate == -2){
|
||||
UI_DrawProportionalString(103, 323, "Shields are offline", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.shieldstate == -1){
|
||||
UI_DrawProportionalString(103, 323, "Shields are inoperable", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
}
|
||||
trap_R_SetColor( colorTable[CT_YELLOW] );
|
||||
UI_DrawHandlePic( 101, 345, lengthhull, 23, uis.whiteShader); //Health Bar
|
||||
UI_DrawProportionalString(103, 347, va("Structual Integity at %.1f Percent", (lengthhull / 4.98)), UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
|
||||
//Sub System indicators
|
||||
//Shields
|
||||
trap_R_SetColor( colorTable[CT_WHITE] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 100, 380, 90, 45, uis.whiteShader);
|
||||
if(s_msd.shieldstate == 1){
|
||||
trap_R_SetColor( colorTable[CT_GREEN] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 101, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(101, 382, "Shields are", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(101, 397, "online", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.shieldstate == 0){
|
||||
trap_R_SetColor( colorTable[CT_YELLOW] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 101, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(101, 382, "Shields are", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(101, 397, "on standby", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.shieldstate == -2){
|
||||
trap_R_SetColor( colorTable[CT_RED] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 101, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(101, 382, "Shields are", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(101, 397, "offline", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.shieldstate == -1){
|
||||
trap_R_SetColor( colorTable[CT_RED] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 101, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(101, 382, "Shields are", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(101, 397, "inoperable", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
}
|
||||
|
||||
//Warp Drive
|
||||
trap_R_SetColor( colorTable[CT_WHITE] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 195, 380, 90, 45, uis.whiteShader);
|
||||
if(s_msd.warpstate == 1){
|
||||
trap_R_SetColor( colorTable[CT_GREEN] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 196, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(197, 382, "Warp Drive is", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(197, 397, "online", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.warpstate == 0){
|
||||
trap_R_SetColor( colorTable[CT_RED] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 196, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(197, 382, "Warp Drive is", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(197, 397, "offline", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.warpstate == 2){
|
||||
trap_R_SetColor( colorTable[CT_RED] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 196, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(197, 382, "Warp Core is", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(197, 397, "ejected", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.warpstate == -2){//-2, no info available
|
||||
trap_R_SetColor( colorTable[CT_YELLOW] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 196, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(197, 382, "Warp-Core-ODN-", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(197, 397, "Update required", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
}
|
||||
|
||||
//Turbolift
|
||||
trap_R_SetColor( colorTable[CT_WHITE] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 290, 380, 90, 45, uis.whiteShader);
|
||||
if(s_msd.turbostate == 1){
|
||||
trap_R_SetColor( colorTable[CT_GREEN] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 291, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(292, 382, "Turbolifts are", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(292, 397, "online", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.turbostate == 0){
|
||||
trap_R_SetColor( colorTable[CT_RED] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 291, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(292, 382, "Turbolifts are", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(292, 397, "offline", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.turbostate == -2){//-2, no info available
|
||||
trap_R_SetColor( colorTable[CT_YELLOW] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 291, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(292, 382, "Turbolift-ODN-", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(292, 397, "Update required", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
}
|
||||
|
||||
//Transporter
|
||||
trap_R_SetColor( colorTable[CT_WHITE] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 385, 380, 90, 45, uis.whiteShader);
|
||||
if(s_msd.transstate == 1){
|
||||
trap_R_SetColor( colorTable[CT_GREEN] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 386, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(387, 382, "Transporters are", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(387, 397, "online", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.transstate == 0){
|
||||
trap_R_SetColor( colorTable[CT_RED] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 386, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(387, 382, "Transporters are", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(387, 397, "offline", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
} else if(s_msd.transstate == -2){//-2, no info available
|
||||
trap_R_SetColor( colorTable[CT_YELLOW] ); //colorTable[CT_VDKPURPLE2]
|
||||
UI_DrawHandlePic( 386, 381, 88, 43, uis.whiteShader);
|
||||
UI_DrawProportionalString(386, 382, "Transporter-ODN-", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
UI_DrawProportionalString(387, 397, "Update required", UI_TINYFONT, colorTable[CT_MDGREY]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
msdMenu_Draw
|
||||
===============
|
||||
*/
|
||||
static void msdMenu_Draw(void)
|
||||
{
|
||||
// Draw graphics particular to Main Menu
|
||||
M_msdMenu_Graphics();
|
||||
|
||||
Menu_Draw( &s_msd.menu );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
UI_msdMenu_Cache
|
||||
===============
|
||||
*/
|
||||
void UI_msdMenu_Cache (void)
|
||||
{
|
||||
leftRound = trap_R_RegisterShaderNoMip("menu/common/halfroundl_24.tga");
|
||||
corner_ul_24_60 = trap_R_RegisterShaderNoMip("menu/common/corner_ul_24_60.tga");
|
||||
corner_ll_12_60 = trap_R_RegisterShaderNoMip("menu/common/corner_ll_12_60.tga");
|
||||
loading1 = trap_R_RegisterShaderNoMip("menu/new/nav_y.tga");
|
||||
loading2 = trap_R_RegisterShaderNoMip("menu/new/nav_mb.tga");
|
||||
loading3 = trap_R_RegisterShaderNoMip("menu/new/nav_lb.tga");
|
||||
loading4 = trap_R_RegisterShaderNoMip("menu/new/nav_db.tga");
|
||||
loading5 = trap_R_RegisterShaderNoMip("menu/new/nab_o.tga");
|
||||
redalert = trap_R_RegisterShaderNoMip("menu/alert/red");
|
||||
yellowalert = trap_R_RegisterShaderNoMip("menu/alert/yellow");
|
||||
bluealert = trap_R_RegisterShaderNoMip("menu/alert/blue");
|
||||
model = trap_R_RegisterShaderNoMip(s_msd.model);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
msdMenu_Init
|
||||
===============
|
||||
*/
|
||||
void msdMenu_Init(void)
|
||||
{
|
||||
s_msd.menu.nitems = 0;
|
||||
s_msd.menu.draw = msdMenu_Draw;
|
||||
s_msd.menu.key = msdMenu_Key;
|
||||
s_msd.menu.wrapAround = qtrue;
|
||||
s_msd.menu.descX = MENU_DESC_X;
|
||||
s_msd.menu.descY = MENU_DESC_Y;
|
||||
s_msd.menu.titleX = MENU_TITLE_X;
|
||||
s_msd.menu.titleY = MENU_TITLE_Y;
|
||||
|
||||
s_msd.quitmenu.generic.type = MTYPE_BITMAP;
|
||||
s_msd.quitmenu.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
||||
s_msd.quitmenu.generic.x = 490;
|
||||
s_msd.quitmenu.generic.y = 380;
|
||||
s_msd.quitmenu.generic.name = GRAPHIC_BUTTONLEFT;
|
||||
s_msd.quitmenu.generic.id = ID_QUIT;
|
||||
s_msd.quitmenu.generic.callback = M_msd_Event;
|
||||
s_msd.quitmenu.width = MENU_BUTTON_MED_WIDTH-20;
|
||||
s_msd.quitmenu.height = PROP_BIG_HEIGHT;
|
||||
s_msd.quitmenu.color = CT_DKPURPLE1;
|
||||
s_msd.quitmenu.color2 = CT_LTPURPLE1;
|
||||
s_msd.quitmenu.textX = MENU_BUTTON_TEXT_X;
|
||||
s_msd.quitmenu.textY = 12;
|
||||
s_msd.quitmenu.textEnum = MBT_RETURNMENU;
|
||||
s_msd.quitmenu.textcolor = CT_BLACK;
|
||||
s_msd.quitmenu.textcolor2 = CT_WHITE;
|
||||
s_msd.quitmenu.textStyle = UI_TINYFONT;
|
||||
|
||||
Menu_AddItem( &s_msd.menu, &s_msd.quitmenu );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
UI_msdMenu
|
||||
===============
|
||||
*/
|
||||
void UI_msdMenu(int maxhull, int currhull, int maxshield, int currshield, int shieldstate, int warpstate, int turbostate, int transstate, int alertstate, char *model)
|
||||
{
|
||||
memset( &s_msd, 0, sizeof( s_msd ) );
|
||||
|
||||
s_msd.maxhull = maxhull;
|
||||
s_msd.currhull = currhull;
|
||||
s_msd.maxshield = maxshield;
|
||||
s_msd.currshield = currshield;
|
||||
s_msd.shieldstate = shieldstate;
|
||||
s_msd.warpstate = warpstate;
|
||||
s_msd.turbostate = turbostate;
|
||||
s_msd.transstate = transstate;
|
||||
s_msd.alertstate = alertstate;
|
||||
s_msd.model = model;
|
||||
|
||||
uis.menusp = 0;
|
||||
|
||||
ingameFlag = qtrue; // true when in game menu is in use
|
||||
|
||||
Mouse_Show();
|
||||
|
||||
UI_msdMenu_Cache();
|
||||
|
||||
msdMenu_Init();
|
||||
|
||||
UI_PushMenu( &s_msd.menu );
|
||||
|
||||
Menu_AdjustCursor( &s_msd.menu, 1 );
|
||||
}
|
Loading…
Reference in a new issue