A lot of stuff!

-replaced target_safezone with target_sone (backwardscompability is in place)
--It now servers for more purposes than just escapepods. Also included in the MSD-System

-Removed list-iteration for safezones.
--They gave me such a hard time and put unneeded limits in place (like one time shots)
--now we loop trough all entities instead and find those with the right criteria and go from there

-For safezones clients are now tagged in the backend (new gclients_t-field)
--only those that aren't taggesd this way will be killed
--Closed FS#30

-First version of shiphealth HUD (FS#8, needs testing)
--There were som modifications made to the full UI as well

-Both Selfdestruct and Shiphealth communication to the client go via command now, the events got removed
-new Version Notation: RPG-X V 2.3 CB 4

Signed-off-by: Harry Young <hendrik.gerritzen@googlemail.com>
This commit is contained in:
Harry Young 2013-02-10 00:31:04 +01:00
parent 3797e35c61
commit 3164fdfa33
14 changed files with 265 additions and 306 deletions

View file

@ -934,6 +934,28 @@ static int CG_DrawHealth(centity_t *cent)
}
}
static float CG_DrawShipHealth( void )
{
CG_FillRect( 3, 400, 102, 31, colorTable[CT_BLACK]);
//shield
CG_FillRect( 4, 401, 100, 14, colorTable[CT_VDKBLUE1]);
if(cg.shieldState == 1){
CG_FillRect( 4, 401, floor(cg.relativeHullStrength), 14, colorTable[CT_DKBLUE1]);
UI_DrawProportionalString(5, 403, va("Shields: %i Pct.", cg.relativeHullStrength), UI_TINYFONT, colorTable[CT_MDGREY]);
} else if(cg.shieldState == 0){
UI_DrawProportionalString(5, 403, "Shields: standby", UI_TINYFONT, colorTable[CT_MDGREY]);
} else if(cg.shieldState == -2){
UI_DrawProportionalString(5, 403, "Shields: offline", UI_TINYFONT, colorTable[CT_MDGREY]);
} else if(cg.shieldState == -1){
UI_DrawProportionalString(5, 403, "Shields: inoperable", UI_TINYFONT, colorTable[CT_MDGREY]);
}
//hull
CG_FillRect( 4, 416, 100, 14, colorTable[CT_VDKRED1]);
CG_FillRect( 4, 416, floor(cg.relativeHullStrength), 14, colorTable[CT_DKRED1]);
UI_DrawProportionalString(5, 418, va("Structural: %i Pct.", cg.relativeHullStrength), UI_TINYFONT, colorTable[CT_MDGREY]);
return 0;
}
/*
================
CG_DrawStatusBar
@ -988,6 +1010,10 @@ static void CG_DrawStatusBar( void )
// Added return of the width for the cloak etc messages
healthBarWidth = CG_DrawHealth(cent);
//shiphealth
if(cg.relativeHullStrength > 0)
CG_DrawShipHealth();
// RPG-X
// Print RPG Flags

View file

@ -451,7 +451,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
int clientNum;
clientInfo_t *ci;
vec3_t normal = { 0, 0, 1 };
int a, b, temp;
int a, b;
refEntity_t legs;
refEntity_t torso;
@ -1824,33 +1824,6 @@ 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");
temp = cent->currentState.eventParm * 60000 + cent->currentState.powerups;
if(temp == -1)
cg.selfdestructTime = -1;
else
cg.selfdestructTime = temp + cg.time;
break;
case EV_HULLHEALTH_SETTER:
DEBUGNAME("EV_HULLHEALTH_SETTER");
if(cent->currentState.eventParm == -1)
cg.relativeHullStrength = -1;
else
cg.relativeHullStrength = cent->currentState.eventParm;
break;
case EV_SHIELDHEALTH_SETTER:
DEBUGNAME("EV_SHIELDHEALTH_SETTER");
if(cent->currentState.eventParm == -1)
cg.relativeShieldStrength = -1;
else
cg.relativeShieldStrength = cent->currentState.eventParm;
break;
// Default
default:

View file

@ -1016,6 +1016,7 @@ typedef struct {
// shiphealth
int relativeHullStrength;
int relativeShieldStrength;
int shieldState;
} cg_t;

View file

@ -916,6 +916,21 @@ static void CG_ServerCommand( void ) {
return;
}
if(!strcmp(cmd, "selfdestructupdate")) {
if(atoi(CG_Argv(1)) == -1)
cg.selfdestructTime = -1;
else
cg.selfdestructTime = atoi(CG_Argv(1)) + cg.time;
return;
}
if(!strcmp(cmd, "shiphealthupdate")) {
cg.relativeShieldStrength = atoi(CG_Argv(1));
cg.relativeHullStrength = atoi(CG_Argv(2));
cg.shieldState = atoi(CG_Argv(3));
return;
}
CG_Printf( "Unknown client game command: %s\n", cmd );
}

View file

@ -8,7 +8,7 @@
// because games can change separately from the main system version, we need a
// second version that must match between game and cgame
#define RPGX_VERSION "RPG-X v2.2 wc18072012"
#define RPGX_VERSION "RPG-X V 2.3 CB 4"
#define RPGX_COMPILEDATE "20/05/11"
#define RPGX_COMPILEDBY "GSIO01"
#define GAME_VERSION "RPG-X v" RPGX_VERSION

View file

@ -1593,6 +1593,7 @@ void G_Client_Begin( int clientNum, qboolean careAboutWarmup, qboolean isBot, qb
gentity_t *ent;
gclient_t *client;
gentity_t *tent;
gentity_t *selfdestruct;
int flags;
qboolean alreadyIn = qfalse;
int score;
@ -1798,6 +1799,12 @@ void G_Client_Begin( int clientNum, qboolean careAboutWarmup, qboolean isBot, qb
}
}
//we may currently be selfdestructing, so send stuff for that case
selfdestruct = G_Find(NULL, FOFS(classname), "target_selfdestruct");
if(selfdestruct && selfdestruct->spawnflags & 1)
trap_SendServerCommand(ent->s.number, va("selfdestructupdate %i", selfdestruct->damage - level.time));
else
trap_SendServerCommand(ent->s.number, va("selfdestructupdate %i", -1));
}
// WEAPONS - PHENIX1

View file

@ -5714,12 +5714,14 @@ static void Cmd_alert_f(gentity_t *ent) {
/*
=================
Cmd_safezonelist_f
Cmd_zonelist_f
Harry Young | 02/11/2012
=================
*/
static void Cmd_safezonelist_f(gentity_t *ent) {
gentity_t *safezone=NULL;
static void Cmd_zonelist_f(gentity_t *ent) {
gentity_t *zone=NULL;
char arg[16];
int type;
#ifndef SQL
if ( !IsAdmin( ent ) ) {
@ -5733,17 +5735,32 @@ static void Cmd_safezonelist_f(gentity_t *ent) {
}
#endif
trap_SendServerCommand( ent-g_entities, va("print \"\nList of safezones on this map: \n\n\""));
while((safezone = G_Find(safezone, FOFS(classname), "target_safezone")) != NULL){
trap_SendServerCommand( ent-g_entities, va("print \"Name of safezone: %s \n\"", safezone->targetname ));
if(safezone->count == 1)
trap_SendServerCommand( ent-g_entities, va("print \"Status of safezone: ^2safe \n\""));
else
trap_SendServerCommand( ent-g_entities, va("print \"Status of safezone: ^1unsafe \n\""));
if(safezone->spawnflags & 2)
trap_SendServerCommand( ent-g_entities, va("print \"Flagges as ship: yes \n\n\""));
else
trap_SendServerCommand( ent-g_entities, va("print \"Flagged as ship: no \n\n\""));
trap_Argv(1, arg, sizeof(arg));
type = atoi(arg);
if(type == 0 || type > 2){
trap_SendServerCommand( ent-g_entities, va("print \"Usage: zonelist <type> where type is one of the following types of zones:\n--1 = safezones for Selfdestruct\n--2 = MSD-HUD zones\n\" ") );
return;
}
if(type == 1)
trap_SendServerCommand( ent-g_entities, va("print \"\nList of safezones on this map: \n\n\""));
if(type == 2)
trap_SendServerCommand( ent-g_entities, va("print \"\nList of MSD-HUD-zones on this map: \n\n\""));
while((zone = G_Find(zone, FOFS(classname), "target_zone")) != NULL){
if(zone->count == type){
trap_SendServerCommand( ent-g_entities, va("print \"Name of zone: %s \n\"", zone->targetname ));
if(zone->n00bCount == 1)
trap_SendServerCommand( ent-g_entities, va("print \"Status of safezone: ^2safe \n\""));
else
trap_SendServerCommand( ent-g_entities, va("print \"Status of safezone: ^1unsafe \n\""));
if(zone->spawnflags & 2)
trap_SendServerCommand( ent-g_entities, va("print \"Flagges as ship: yes \n\n\""));
else
trap_SendServerCommand( ent-g_entities, va("print \"Flagged as ship: no \n\n\""));
}
}
trap_SendServerCommand( ent-g_entities, va("print \"End of list \n\n\""));
}
@ -5803,9 +5820,9 @@ static void Cmd_selfdestruct_f(gentity_t *ent) {
if ( destructEnt->wait <= 0 )
G_PrintfClient(ent, "^1ERROR: duration must not be 0. Removing entity.");
while((safezone = G_Find(safezone, FOFS(classname), "target_safezone")) != NULL){
if(!destructEnt->bluename && safezone->spawnflags & 2){
G_PrintfClient(ent, "^1ERROR: safezone must be given for maps consisting of multiple ships/stations (like rpg_runabout). For a list of safezonesuse the safezonelist command. Removing entity.");
while((safezone = G_Find(safezone, FOFS(classname), "target_zone")) != NULL){
if(!destructEnt->bluename && safezone->count == 1 && safezone->spawnflags & 2){
G_PrintfClient(ent, "^1ERROR: safezone must be given for maps consisting of multiple ships/stations (like rpg_runabout). For a list of safezones use this command: zonelist 1 . Removing entity.");
destructEnt->wait = 0; //we'll use this next to free the ent
break;
}
@ -5847,8 +5864,9 @@ static void Cmd_selfdestruct_f(gentity_t *ent) {
G_PrintfClient(ent, "^3Usage: selfdestruct start duration audio [safezone] [target]");
G_PrintfClient(ent, "duration: total countdown-duration in seconds. Must not be 0.");
G_PrintfClient(ent, "audio: set this 0 if you do not want to display the countdown-clock in the top center of your screen, else set this 1.");
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 clients outside an active target_safezone.");
G_PrintfClient(ent, "safezone: Only for maps with multiple ships (like rpg_runabout). it will not be used for processing. Set NULL to skip.");
G_PrintfClient(ent, "target: Optional Argument for Effects to fire once the countdown hist 0.");
G_PrintfClient(ent, "The entity will automatically shake everyones screen and kill all clients outside an active target_zone configured as safezone.");
G_PrintfClient(ent, "\n^3Usage: selfdestruct remaining");
G_PrintfClient(ent, "This will give out the remaining countdown-time to all clients if the count is muted.");
G_PrintfClient(ent, "\n^3Usage: selfdestruct abort");
@ -7719,8 +7737,8 @@ void G_Client_Command( int clientNum )
Cmd_changeFreq(ent);
else if (Q_stricmp(cmd, "alert") == 0)
Cmd_alert_f(ent);
else if (Q_stricmp(cmd, "safezonelist") == 0)
Cmd_safezonelist_f(ent);
else if (Q_stricmp(cmd, "zonelist") == 0)
Cmd_zonelist_f(ent);
else if (Q_stricmp(cmd, "selfdestruct") == 0)
Cmd_selfdestruct_f(ent);
else if (Q_stricmp(cmd, "shipdamage") == 0)

View file

@ -599,6 +599,10 @@ struct gclient_s {
vec3_t origViewAngles;
vec3_t origOrigin;
gentity_t *cam;
// for selfdestruct and shiphealth
int nokilli; //!< if 1 this player won't be killed if the ship is killed
int myship; //!< entnum of the shiphealth entity this client currently holds info from
};
@ -694,7 +698,6 @@ typedef struct {
int numBrushEnts; //!< number of entities in the level that use brushmodels
// selft destruct safezones
list_p selfdestructSafeZones;
list_p locations;
list_p timedMessages;
@ -2084,15 +2087,6 @@ struct luaAlertState_s {
luaAlertState_t *luaAlertState;
// self destruct
typedef struct safeZone_s safeZone_t;
struct safeZone_s {
char* name;
qboolean active;
vec3_t maxs;
vec3_t mins;
} safeZone_s;
// timed messages
typedef struct timedMessage_s timedMessage_t;
struct timedMessage_s {

View file

@ -2017,11 +2017,6 @@ void G_ShutdownGame( int restart ) {
BotAIShutdown( restart );
}
// free self destruct safe zones
if(level.selfdestructSafeZones != NULL) {
destroy_list(level.selfdestructSafeZones);
}
if(level.timedMessages != NULL) {
destroy_list(level.timedMessages);
}

View file

@ -179,7 +179,7 @@ void SP_target_serverchange(gentity_t *ent);
void SP_target_levelchange(gentity_t *ent);
void SP_target_shaderremap(gentity_t *ent);
void SP_target_selfdestruct(gentity_t *ent);
void SP_target_safezone(gentity_t *ent);
void SP_target_zone(gentity_t *ent);
void SP_target_shiphealth(gentity_t *ent);
void SP_light (gentity_t *self);
@ -366,7 +366,8 @@ spawn_t spawns[] = {
{"target_levelchange", SP_target_levelchange},
{"target_shaderremap", SP_target_shaderremap},
{"target_selfdestruct", SP_target_selfdestruct},
{"target_safezone", SP_target_safezone},
{"target_safezone", SP_target_zone},
{"target_zone", SP_target_zone},
{"target_shiphealth", SP_target_shiphealth},
{"light", SP_light},

View file

@ -2660,13 +2660,13 @@ void SP_target_shaderremap(gentity_t *ent) {
}
//RPG-X | Harry Young | 15/10/2011 | MOD END
//RPG-X | Harry Young | 25/07/2012 | MOD START AUDIO_ON
/*QUAKED target_selfdestruct (1 0 0) (-8 -8 -8) (8 8 8)
//RPG-X | Harry Young | 25/07/2012 | MOD START
/*QUAKED target_selfdestruct (1 0 0) (-8 -8 -8) (8 8 8) AUDIO_ON
-----DESCRIPTION-----
DO NOT USE! This just sits here purely for documantation.
This entity manages the self destruct.
For now this should only be used via the selfdestruct console command, however it might be usable from within the radiant at a later date.
Should this thing hit 0 the killing part for everyone outside a target_safezone will be done automatically.
Should this thing hit 0 the killing part for everyone outside a target_zone configured as safezone will be done automatically.
-----SPAWNFLAGS-----
1: AUDIO_ON - tells the script to display the countdown
@ -2674,58 +2674,14 @@ Should this thing hit 0 the killing part for everyone outside a target_safezone
-----KEYS-----
"wait" - total Countdown-Time in secs
"flags" - are audio warnings 1 or 0?
"bluename" - target_safezone this thing affects (multi-ship-maps only) will switch it unsafe at T-50ms
"bluename" - target_zone this thing affects (multi-ship-maps only) will switch it unsafe at T-50ms
"target" - Things like fx to fire once the countdown hits 0
"damage" - leveltime of countdowns end
*/
static int target_selfdestruct_get_unsafe_players(gentity_t *ents[MAX_GENTITIES]) {
int i, n, num, cur = 0, cur2 = 0;
list_iter_p iter = NULL;
safeZone_t* sz;
int entlist[MAX_GENTITIES];
gentity_t *safePlayers[MAX_GENTITIES];
qboolean add = qtrue;
if(level.selfdestructSafeZones != NULL && level.selfdestructSafeZones->length > 0) {
// go through all safe zones and compose a list of sade players
iter = list_iterator(level.selfdestructSafeZones, FRONT);
for(sz = (safeZone_t *)list_next(iter); sz != NULL; sz = (safeZone_t *)list_next(iter)) {
if(!sz->active) {
continue;
}
num = trap_EntitiesInBox(sz->mins, sz->maxs, entlist, MAX_GENTITIES);
for(n = 0; n < num; n++) {
if(entlist[n] < g_maxclients.integer && g_entities[entlist[n]].client) {
safePlayers[cur] = &g_entities[entlist[n]];
cur++;
}
}
}
}
// now use that information to determines all unsafe players
for(i = 0; i < MAX_CLIENTS; i++) {
for(n = 0; n < cur; n++) {
if(&g_entities[i] == safePlayers[n]) {
add = qfalse;
break;
}
}
if(add) {
if(&g_entities[i].client) {
ents[cur2] = &g_entities[i];
cur2++;
}
}
}
destroy_iterator(iter);
return cur2;
}
void target_selfdestruct_use(gentity_t *ent, gentity_t *other, gentity_t *activator) {
if( ent->damage - level.time > 50 ){//if we listed the safezones we're committed
if( ent->damage - level.time > 50 ){//I'm still sceptical about a few things here, so I'll leave this in place
//with the use-function we're going to init aborts in a fairly simple manner: Fire warning notes...
trap_SendServerCommand( -1, va("servermsg \"Self Destruct sequence aborted.\""));
G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/abort.mp3"));
@ -2740,65 +2696,45 @@ void target_selfdestruct_use(gentity_t *ent, gentity_t *other, gentity_t *activa
}
void target_selfdestruct_think(gentity_t *ent) {
gentity_t* client;
gentity_t *client = NULL;
gentity_t *healthEnt, *safezone=NULL;
int i = 0, mins = 0;
int entlist[MAX_GENTITIES];
int n = 0, num;
//this is for calling the safezones to list. It needs to stand here to not screw up the remainder of the think.
if (ent->wait == 50) {
while ((safezone = G_Find( safezone, FOFS( classname ), "target_safezone" )) != NULL ){
if(!Q_stricmp(safezone->targetname, ent->bluename))//free shipwide safezone if it exists
G_FreeEntity(safezone);
else
safezone->use(safezone, ent, ent);
}
ent->wait = 0;
ent->nextthink = level.time + 50;
return;
}
if (ent->wait > 0 && ent->spawnflags == 1 ){
//Send a sync/signal to all clients
ent->s.powerups = ent->damage - level.time;
if(ent->s.powerups > 60000){
mins = ent->s.powerups / 60000;
ent->s.powerups = ent->s.powerups - (60000 * mins);
G_AddEvent( ent, EV_SELFDESTRUCT_SETTER, mins );
}
else
G_AddEvent( ent, EV_SELFDESTRUCT_SETTER, mins );
ent->nextthink = level.time + 10000;
//fail horribly if we overshoot bang-time
if (ent->nextthink > ent->damage){
ent->nextthink = ent->damage;
ent->wait = 0;
}
if (ent->nextthink == ent->damage){
//we need to get the safezones operational and it is highly unlikely that it'll happen in the last .05 secs of the count
ent->nextthink = ent->nextthink - 50;
ent->wait = 50;
}
return;
} else if (ent->wait == 0) { //bang time ^^
if (ent->wait == 0) { //bang time ^^
//I've reconsidered. Selfdestruct will fire it's death mode no matter what. Targets are for FX-Stuff.
healthEnt = G_Find(NULL, FOFS(classname), "target_shiphealth");
if(healthEnt && G_Find(healthEnt, FOFS(classname), "target_shiphealth") == NULL ){
healthEnt->damage = healthEnt->health + healthEnt->splashRadius; //let's use the healthent killfunc if we have just one. makes a lot of stuff easier.
healthEnt->use(healthEnt, NULL, NULL);
}else{
int num;
gentity_t *ents[MAX_GENTITIES];
while ((safezone = G_Find( safezone, FOFS( classname ), "target_zone" )) != NULL ){
// go through all safe zones and tag all safe players
if(safezone->count == 1 && safezone->n00bCount == 1 && Q_stricmp(safezone->targetname, ent->bluename)) {
num = trap_EntitiesInBox(safezone->r.mins, safezone->r.maxs, entlist, MAX_GENTITIES);
for(n = 0; n < num; n++) {
if(entlist[n] < g_maxclients.integer && g_entities[entlist[n]].client) {
while((client = G_Find( client, FOFS( classname ), "player" ))!= NULL){
if(client->s.number == entlist[n])
client->client->nokilli = 1;
trap_SendServerCommand( -1, va("print \"SETTING: %i = %i\n\" ", client->s.number, client->client->nokilli) );
}
}
}
}
}
num = target_selfdestruct_get_unsafe_players(ents);
client = NULL;
//Loop trough all clients on the server.
for(i = 0; i < num; i++) {
client = ents[i];
G_Damage (client, ent, ent, 0, 0, 999999, 0, MOD_TRIGGER_HURT); //maybe a new message ala "[Charname] did not abandon ship."
while((client = G_Find( client, FOFS( classname ), "player" ))!= NULL){
if (client->client->nokilli != 1)
G_Damage (client, ent, ent, 0, 0, 999999, 0, MOD_TRIGGER_HURT); //maybe a new message ala "[Charname] did not abandon ship."
}
//we may go this way once more so clear clients back.
client = NULL;
while((client = G_Find( client, FOFS( classname ), "player" ))){
client->client->nokilli = 0;
}
//let's hear it
G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/weapons/explosions/explode2.wav"));
@ -2816,7 +2752,7 @@ void target_selfdestruct_think(gentity_t *ent) {
//we have aborted and the note should be out or ended and everyone should be dead so let's reset
ent->nextthink = level.time + 50;//give the event time to be conducted
G_AddEvent( ent, EV_SELFDESTRUCT_SETTER, 0 );
trap_SendServerCommand(-1, va("selfdestructupdate %i", -1));
ent->wait = -2;
return;
} else if (ent->wait == -2) {
@ -2898,40 +2834,35 @@ void SP_target_selfdestruct(gentity_t *ent) {
ent->use = target_selfdestruct_use;
ent->think = target_selfdestruct_think;
ent->nextthink = ent->damage;
if(ent->spawnflags == 1)
ent->nextthink = level.time + 50; // init clock over there... somehow doesn't work in spawnfunc...
else
ent->nextthink = ent->damage;
trap_SendServerCommand(-1, va("selfdestructupdate %.0f", ent->wait));
//fail horribly if an intervall overshoots bang-time
if (ent->nextthink > ent->damage){
ent->nextthink = ent->damage;
ent->wait = 0;
}
if (ent->nextthink == ent->damage){
//we need to get the safezones operational and it is highly unlikely that it'll happen in the last .05 secs of the count
ent->nextthink = ent->nextthink - 50;
ent->wait = 50;
}
ent->wait = 0;
trap_LinkEntity(ent);
}
/*QUAKED target_safezone (1 0 0) ? SPAWN_SAFE SHIP
/*QUAKED target_zone (1 0 0) ? SPAWN_SAFE SHIP
-----DESCRIPTION-----
This is a safezone for when the ship/station is destroyed via shiphelath or selfdestruct.
It is used like a trigger and requires a targetname or else it will be removed at spawn.
A generic zone used for entities that need a generic pointer in the world. It needs to be specialized by the team-value.
-----SPAWNFLAGS-----
1: SPAWN_SAFE - Entity is spawned in it's Safe configurartion
2: SHIP - iwill mark this safezone as a ship safezone
Note: Spawnflags will only work with the system they are attached to
1: SPAWN_SAFE - For safezone only: Entity is spawned in it's safe configurartion
2: SHIP - For safezone only: will mark this safezone as a ship safezone
-----KEYS-----
"targetname" - when used will toggle safe/unsafe
"targetname" - used to link with, some types require this for toggling
"count" - specifies this zone's type:
0 - none, will free entity
1 - safezone for target_selfdestruct and target_shiphealth
2 - display zone for target_shiphealth (HUD overlay)
-----USAGE-----
As safezone:
Usage for Escape Pods and similar:
Fill your escape pod Interior with this trigger and have it targeted by a func_usable/target_relay/target_delay to toggle it between safe and unsafe states.
@ -2943,62 +2874,46 @@ To get the correct one use the /safezonelist-command
*/
void target_safezone_use(gentity_t *ent, gentity_t *other, gentity_t *activator){
safeZone_t* sz = (safeZone_t *)malloc(sizeof(safeZone_s));
if(!Q_stricmp(activator->classname, "target_selfdestruct") || !Q_stricmp(activator->classname, "target_shiphealth")){
//our ship is about to die so compose the list of safezones
VectorCopy(ent->r.maxs, sz->maxs);
VectorCopy(ent->r.mins, sz->mins);
VectorAdd(ent->s.origin, ent->r.mins, sz->mins);
VectorAdd(ent->s.origin, ent->r.maxs, sz->maxs);
sz->name = (char *)malloc(strlen(ent->targetname)+1);
strcpy(sz->name, ent->targetname);
sz->active = (qboolean)(ent->count == 1);
list_add(level.selfdestructSafeZones, sz, sizeof(safeZone_s));
G_FreeEntity(ent);
} else {
//a client used this, so let's set this thing to active
if(ent->count == 1)
ent->count = 0;
else
ent->count = 1;
}
//a client used this, so let's set this thing to active
if(ent->n00bCount == 1)
ent->n00bCount = 0;
else
ent->n00bCount = 1;
}
void target_safezone_destructor(void *p) {
safeZone_t *sz = (safeZone_t *)p;
if(p == NULL) {
return;
}
if(sz->name != NULL) {
free(sz->name);
}
free(sz);
}
void SP_target_safezone(gentity_t *ent) {
void SP_target_zone(gentity_t *ent) {
if(!ent->targetname || !ent->targetname[0]) {
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] Safezone without targetname at %s, removing entity.\n", vtos(ent->s.origin)););
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] target_zone without targetname at %s, removing entity.\n", vtos(ent->s.origin)););
G_FreeEntity(ent);
return;
}
if(level.selfdestructSafeZones == NULL) {
level.selfdestructSafeZones = create_list();
level.selfdestructSafeZones->destructor = target_safezone_destructor;
if(strcmp(ent->classname, "target_zone")){
ent->count = 1;
ent->classname = G_NewString("target_zone");
//strcpy(ent->classname, "target_zone");
}
if(ent->count == 0) {
DEVELOPER(G_Printf(S_COLOR_YELLOW "[Entity-Error] target_zone without specified class by it's count-value at %s, removing entity.\n", vtos(ent->s.origin)););
G_FreeEntity(ent);
return;
}
if(strcmp(ent->classname, "target_zone")){
ent->count = 1;
//ent->classname = G_NewString("target_zone");
strcpy(ent->classname, "target_zone");
}
if(!ent->luaEntity) {
trap_SetBrushModel(ent, ent->model);
}
if(ent->spawnflags & 1)
ent->count = 1;
ent->use = target_safezone_use;
if(ent->count == 1)
ent->use = target_safezone_use;
if(ent->count == 1 && ent->spawnflags & 1)
ent->n00bCount = 1;
ent->r.contents = CONTENTS_NONE;
ent->r.svFlags |= SVF_NOCLIENT;
trap_LinkEntity(ent);
@ -3029,6 +2944,8 @@ bluename: swapname for target_turbolift
bluesound: swapname for ui_transporter
falsename: falsename/redname for target_alert
paintarget: target_zones configured as MSD-Display-Zones this thing shoud communicate with
"model" - path to a shader with a MSD-Display (ship) to show. Default will be the Daedalus Class
We're sponsoring a varayity, which were created by Alexander Richardson.
@ -3104,65 +3021,39 @@ textures/msd/akira //this will be the image you will use for texturing
For distribution put both files (including their relative paths) in a *.pk3 file.
*/
static int target_shiphealth_get_unsafe_players(gentity_t *ents[MAX_GENTITIES]) {
int i, n, num, cur = 0, cur2 = 0;
list_iter_p iter = NULL;
safeZone_t* sz;
int entlist[MAX_GENTITIES];
gentity_t *safePlayers[MAX_GENTITIES];
qboolean add = qtrue;
if(level.selfdestructSafeZones != NULL && level.selfdestructSafeZones->length > 0) {
// go through all safe zones and compose a list of sade players
iter = list_iterator(level.selfdestructSafeZones, FRONT);
for(sz = (safeZone_t *)list_next(iter); sz != NULL; sz = (safeZone_t *)list_next(iter)) {
if(!sz->active) {
continue;
}
num = trap_EntitiesInBox(sz->mins, sz->maxs, entlist, MAX_GENTITIES);
void target_shiphealth_die(gentity_t *ent){
//we're dying
int n = 0, num;
int entlist[MAX_GENTITIES];
gentity_t *client = NULL, *safezone=NULL;
while ((safezone = G_Find( safezone, FOFS( classname ), "target_zone" )) != NULL ){
// go through all safe zones and tag all safe players
if(safezone->count == 1 && safezone->n00bCount == 1 && Q_stricmp(safezone->targetname, ent->bluename)) {
num = trap_EntitiesInBox(safezone->r.mins, safezone->r.maxs, entlist, MAX_GENTITIES);
for(n = 0; n < num; n++) {
if(entlist[n] < g_maxclients.integer && g_entities[entlist[n]].client) {
safePlayers[cur] = &g_entities[entlist[n]];
cur++;
while((client = G_Find( client, FOFS( classname ), "player" ))!= NULL){
if(client->s.number == entlist[n])
client->client->nokilli = 1;
}
}
}
}
}
// now use that information to determines all unsafe players
for(i = 0; i < MAX_CLIENTS; i++) {
for(n = 0; n < cur; n++) {
if(&g_entities[i] == safePlayers[n]) {
add = qfalse;
break;
}
}
if(add) {
if(&g_entities[i].client) {
ents[cur2] = &g_entities[i];
cur2++;
}
}
}
if(iter != NULL) {
free(iter);
}
return cur2;
}
void target_shiphealth_die(gentity_t *ent){
//we're dying
int i, num;
gentity_t *ents[MAX_GENTITIES], *client;
num = target_shiphealth_get_unsafe_players(ents);
client = NULL;
//Loop trough all clients on the server.
for(i = 0; i < num; i++) {
client = ents[i];
G_Damage (client, ent, ent, 0, 0, 999999, 0, MOD_TRIGGER_HURT); //maybe a new message ala "[Charname] did not abandon ship."
while((client = G_Find( client, FOFS( classname ), "player" ))!= NULL){
if (client->client->nokilli != 1)
G_Damage (client, ent, ent, 0, 0, 999999, 0, MOD_TRIGGER_HURT); //maybe a new message ala "[Charname] did not abandon ship."
}
//we may go this way once more so clear clients back.
client = NULL;
while((client = G_Find( client, FOFS( classname ), "player" ))){
client->client->nokilli = 0;
}
//let's hear it
G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/weapons/explosions/explode2.wav"));
@ -3174,7 +3065,9 @@ void target_shiphealth_die(gentity_t *ent){
void target_shiphealth_use(gentity_t *ent, gentity_t *other, gentity_t *activator) {
double NSS, NHS, SD, HD, BT;
gentity_t *alertEnt, *warpEnt, *turboEnt, *transEnt, *safezone=NULL;
int n = 0, num;
int entlist[MAX_GENTITIES];
gentity_t *alertEnt, *warpEnt, *turboEnt, *transEnt, *msdzone=NULL, *client=NULL;
if(ent->damage <= 0){ //failsave
return;
@ -3261,15 +3154,35 @@ void target_shiphealth_use(gentity_t *ent, gentity_t *other, gentity_t *activato
//let's reset the repair-timer
ent->nextthink = level.time + 60000;
//if we hit 0 use all the safezones and blow in 50 ms
if(ent->count <= 0){
//refresh clients HUD Display
//first zero out all clients that are connected to this one
while((client = G_Find(client, FOFS(classname), "player")) != NULL){
if(client->client->myship == ent->s.number)
trap_SendServerCommand( client->s.number, va("shiphealthupdate 0 0 0 "));
}
while ((safezone = G_Find( safezone, FOFS( classname ), "target_safezone" )) != NULL ){
if(!Q_stricmp(safezone->targetname, ent->targetname))//free shipwide safezone if it exists
G_FreeEntity(safezone);
else
safezone->use(safezone, ent, ent);
client = NULL;
//now let's loop trough our zones and find the clients to send the info to
while ((msdzone = G_Find( msdzone, FOFS( classname ), "target_zone" )) != NULL ){
// go through all safe zones and tag all safe players
if(msdzone->count == 2 && Q_stricmp(msdzone->targetname, ent->paintarget)) {
num = trap_EntitiesInBox(msdzone->r.mins, msdzone->r.maxs, entlist, MAX_GENTITIES);
for(n = 0; n < num; n++) {
if(entlist[n] < g_maxclients.integer && g_entities[entlist[n]].client) {
while((client = G_Find( client, FOFS( classname ), "player" ))!= NULL){
if(client->s.number == entlist[n]){
trap_SendServerCommand( client->s.number, va("shiphealthupdate %.0f %.0f %i ", floor(ent->count / ent->health), floor(ent->n00bCount / ent->splashRadius), ent->splashDamage));
client->client->myship = ent->s.number;
}
}
}
}
}
}
//if we hit 0 blow in 50 ms
if(ent->count <= 0){
ent->think = target_shiphealth_die;
ent->nextthink = level.time + 50;
}
@ -3280,7 +3193,10 @@ void target_shiphealth_use(gentity_t *ent, gentity_t *other, gentity_t *activato
void target_shiphealth_think(gentity_t *ent) {
//this will do the healing each minute
int NSS, NHS;
int n = 0, num;
int entlist[MAX_GENTITIES];
gentity_t* alertEnt;
gentity_t *msdzone=NULL, *client=NULL;
//We have interconnectivity with target_alert here in that at condition green we regenerate twice as fast
//so let's find the entity
@ -3343,6 +3259,33 @@ void target_shiphealth_think(gentity_t *ent) {
}
ent->nextthink = level.time + 60000;
//refresh clients HUD Display
//first zero out all clients that are connected to this one
while((client = G_Find(client, FOFS(classname), "player")) != NULL){
if(client->client->myship == ent->s.number)
trap_SendServerCommand( client->s.number, va("shiphealthupdate 0 0 0 "));
}
client = NULL;
//now let's loop trough our zones and find the clients to send the info to
while ((msdzone = G_Find( msdzone, FOFS( classname ), "target_zone" )) != NULL ){
// go through all safe zones and tag all safe players
if(msdzone->count == 2 && Q_stricmp(msdzone->targetname, ent->paintarget)) {
num = trap_EntitiesInBox(msdzone->r.mins, msdzone->r.maxs, entlist, MAX_GENTITIES);
for(n = 0; n < num; n++) {
if(entlist[n] < g_maxclients.integer && g_entities[entlist[n]].client) {
while((client = G_Find( client, FOFS( classname ), "player" ))!= NULL){
if(client->s.number == entlist[n]){
trap_SendServerCommand( client->s.number, va("shiphealthupdate %.0f %.0f %i ", floor(ent->count / ent->health), floor(ent->n00bCount / ent->splashRadius), ent->splashDamage));
client->client->myship = ent->s.number;
}
}
}
}
}
}
return;
}

View file

@ -339,8 +339,6 @@ gentity_t *G_PickTarget (char *targetname)
*/
void G_UseTargets2( gentity_t *ent, gentity_t *activator, char *target ) {
gentity_t *t;
list_iter_p szIter = NULL;
safeZone_t *sz;
if ( !ent ) {
return;
@ -507,18 +505,6 @@ void G_UseTargets2( gentity_t *ent, gentity_t *activator, char *target ) {
return;
}
}
/* self destruct safe zones */
if(level.selfdestructSafeZones != NULL && level.selfdestructSafeZones->length > 0) {
szIter = list_iterator(level.selfdestructSafeZones, FRONT);
for(sz = (safeZone_t *)list_next(szIter); sz != NULL; sz = (safeZone_t *)list_next(szIter)) {
if(!strcmp(sz->name, target)) {
sz->active = (qboolean)!sz->active;
}
}
}
destroy_iterator(szIter);
}
/**

View file

@ -1,5 +1,5 @@
// Current version of holomatch game
#define Q3_VERSION "RPG-X v2.2 wc18072012"
#define Q3_VERSION "RPG-X V 2.3 CB 4"
// end

View file

@ -163,18 +163,18 @@ static void M_msdMenu_Graphics (void)
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] );
UI_DrawHandlePic( 100, 320, 500, 49, uis.whiteShader); //background
trap_R_SetColor( colorTable[CT_VDKBLUE1] );
//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_VDKRED1] );
//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] );
trap_R_SetColor( colorTable[CT_DKBLUE1] );
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){
@ -184,9 +184,9 @@ static void M_msdMenu_Graphics (void)
} else if(s_msd.shieldstate == -1){
UI_DrawProportionalString(103, 323, "Shields are inoperable", UI_TINYFONT, colorTable[CT_MDGREY]);
}
trap_R_SetColor( colorTable[CT_YELLOW] );
trap_R_SetColor( colorTable[CT_DKRED1] );
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]);
UI_DrawProportionalString(103, 347, va("Structural Integity at %.1f Percent", (lengthhull / 4.98)), UI_TINYFONT, colorTable[CT_MDGREY]);
//Sub System indicators
//Shields