diff --git a/engine/Makefile b/engine/Makefile index ebddddcd..cdffd62a 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -111,7 +111,7 @@ endif export CROSS_COMPILING ifndef VERSION -VERSION=v0.0.1.5 +VERSION=v0.0.2.1 endif ifndef CLIENTBIN diff --git a/engine/code/cgame/cg_draw.c b/engine/code/cgame/cg_draw.c index 302c6c46..b265e62d 100644 --- a/engine/code/cgame/cg_draw.c +++ b/engine/code/cgame/cg_draw.c @@ -529,6 +529,33 @@ void CG_DrawTeamBackground( int x, int y, int w, int h, float alpha, int team ) trap_R_SetColor( NULL ); } +/* +======================= +CG_DrawSigilHUD +======================= +*/ +void CG_DrawSigilHUD( void ) { + int i, x=480, y=0; + for (i=0; ips.clientNum]; ps = &cg.snap->ps; @@ -3112,6 +3143,93 @@ static void CG_DrawWarmup( void ) { */ // Q3Rally Code END +//======================================= +//CG_DrawSigilLocationInfo +//======================================= +void CG_DrawSigilLocationInfo( vec3_t origin, vec3_t target, qhandle_t shader, vec4_t color ) + { + int x = 320, y = 240; + int w = 320, h = 240; + float angle, distance; + vec3_t temp, angles; + VectorSubtract(origin, target, temp); + distance=VectorLength(temp); + VectorNormalize(temp); + vectoangles(temp,angles); + + angles[YAW]=AngleSubtract(cg.snap->ps.viewangles[YAW],angles[YAW]); + angle=(angles[YAW] + 180.0f)/360.0f; + angle -=0.25; + angle *= (2*M_PI); + w=sqrt((w*w)+(h*h)); + x +=cos(angle)*w; + y +=sin(angle)*w; + + if (x<15) + x=15; + else { + + if (x>605) + x=605; + } + if (y<20) + y=20; + else + { + if (y>440) + y=440; + } + CG_DrawPic( x, y, 20, 20, shader ); + CG_DrawStringExt( x-50, y+20, va("%10.2f",distance/100.0), color, qtrue, qfalse, TINYCHAR_WIDTH, TINYCHAR_HEIGHT, 0 ); + } + +//======================================= +//CG_DrawSigilLocations +//======================================= +static void CG_DrawSigilLocations( void ) { + snapshot_t *snap; + int i; + vec3_t origin, end; + int redSigil, blueSigil, whiteSigil; + + if ( cgs.gametype != GT_DOMINATION) + return; + if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) + return; + + if ( cg.nextSnap && (!cg.nextFrameTeleport && !cg.thisFrameTeleport)) + + snap = cg.nextSnap; + else + snap = cg.snap; + + VectorCopy(cg.snap->ps.origin,origin); + redSigil = ITEM_INDEX( BG_FindItemForPowerup( PW_SIGILRED ) ); + blueSigil = ITEM_INDEX( BG_FindItemForPowerup( PW_SIGILBLUE ) ); + whiteSigil = ITEM_INDEX( BG_FindItemForPowerup( PW_SIGILWHITE ) ); + + for ( i = 0; i < snap->numEntities; i++ ) + { + + centity_t *target = &cg_entities[snap->entities[i].number]; + if (target->currentState.eType != ET_ITEM) + continue; + + if ( target->currentState.modelindex != redSigil && target->currentState.modelindex != blueSigil && target->currentState.modelindex != whiteSigil ) + continue; + + VectorCopy(target->lerpOrigin,end); + + if (target->currentState.modelindex == redSigil) + CG_DrawSigilLocationInfo(origin, end, cgs.media.redFlagShader[0], colorRed); + + else if (target->currentState.modelindex == blueSigil) + CG_DrawSigilLocationInfo(origin, end, cgs.media.blueFlagShader[0], colorBlue); + + else if (target->currentState.modelindex == whiteSigil) + CG_DrawSigilLocationInfo(origin, end, cgs.media.sigilShader, colorWhite); + } + } //================================================================================== #ifdef MISSIONPACK /* @@ -3221,7 +3339,10 @@ static void CG_Draw2D(stereoFrame_t stereoFrame) CG_DrawTeamVote(); CG_DrawLagometer(); - + + if (cg_sigilLocator.integer == 1) + CG_DrawSigilLocations(); + #ifdef MISSIONPACK if (!cg_paused.integer) { CG_DrawUpperRight(stereoFrame); diff --git a/engine/code/cgame/cg_event.c b/engine/code/cgame/cg_event.c index 2489f3f6..5ad7a7b9 100644 --- a/engine/code/cgame/cg_event.c +++ b/engine/code/cgame/cg_event.c @@ -894,7 +894,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { // powerups and team items will have a separate global sound, this one // will be played at prediction time - if ( item->giType == IT_POWERUP || item->giType == IT_TEAM ) { + if ( item->giType == IT_POWERUP || item->giType == IT_TEAM || item->giType == IT_SIGIL ) { trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound ); } else if (item->giType == IT_PERSISTANT_POWERUP) { #ifdef MISSIONPACK diff --git a/engine/code/cgame/cg_info.c b/engine/code/cgame/cg_info.c index 280420bd..50b6363e 100644 --- a/engine/code/cgame/cg_info.c +++ b/engine/code/cgame/cg_info.c @@ -263,6 +263,10 @@ void CG_DrawInformation( void ) { case GT_CTF: s = "Capture The Flag"; break; +// Q3Rally Code Start + case GT_DOMINATION: + s = "Domination"; + break; /* #ifdef MISSIONPACK diff --git a/engine/code/cgame/cg_local.h b/engine/code/cgame/cg_local.h index 76155634..424d94db 100644 --- a/engine/code/cgame/cg_local.h +++ b/engine/code/cgame/cg_local.h @@ -838,7 +838,9 @@ typedef struct { qhandle_t redFlagShader[3]; qhandle_t blueFlagShader[3]; qhandle_t flagShader[4]; - +// Q3Rally Code Start + qhandle_t sigilShader; +// Q3Rally Code END qhandle_t flagPoleModel; qhandle_t flagFlapModel; @@ -1342,7 +1344,7 @@ typedef struct { // Q3Rally Code END int redflag, blueflag; // flag status from configstrings int flagStatus; - + int sigil[MAX_SIGILS]; qboolean newHud; // @@ -1496,6 +1498,7 @@ extern vmCvar_t cg_oldRail; extern vmCvar_t cg_oldRocket; extern vmCvar_t cg_oldPlasma; extern vmCvar_t cg_trueLightning; +extern vmCvar_t cg_sigilLocator; #ifdef MISSIONPACK extern vmCvar_t cg_redTeamName; extern vmCvar_t cg_blueTeamName; @@ -2071,7 +2074,17 @@ void trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin ); // respatialize recalculates the volumes of sound as they should be heard by the // given entityNum and position void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater ); + sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed ); // returns buzz if not found + + +/* Temp Debug Code + +#define trap_S_RegisterSound( sample, compressed ) trap_S_RegisterSoundDebug( sample, compressed, __FILE__, __LINE__ ) +sfxHandle_t trap_S_RegisterSoundDebug( const char *sample, qboolean compressed, const char *file, int line ); + +*/ + void trap_S_StartBackgroundTrack( const char *intro, const char *loop ); // empty name stops music void trap_S_StopBackgroundTrack( void ); diff --git a/engine/code/cgame/cg_main.c b/engine/code/cgame/cg_main.c index a3fabb87..e136f4de 100644 --- a/engine/code/cgame/cg_main.c +++ b/engine/code/cgame/cg_main.c @@ -222,7 +222,7 @@ vmCvar_t cg_oldRail; vmCvar_t cg_oldRocket; vmCvar_t cg_oldPlasma; vmCvar_t cg_trueLightning; - +vmCvar_t cg_sigilLocator; #ifdef MISSIONPACK vmCvar_t cg_redTeamName; vmCvar_t cg_blueTeamName; @@ -430,7 +430,8 @@ static cvarTable_t cvarTable[] = { { &cg_oldRail, "cg_oldRail", "1", CVAR_ARCHIVE}, { &cg_oldRocket, "cg_oldRocket", "1", CVAR_ARCHIVE}, { &cg_oldPlasma, "cg_oldPlasma", "1", CVAR_ARCHIVE}, - { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE} + { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE}, + { &cg_sigilLocator, "cg_sigilLocator", "1", CVAR_ARCHIVE} // { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE } }; @@ -728,7 +729,7 @@ static void CG_RegisterSounds( void ) { cgs.media.takenYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagtaken_yourteam.wav", qtrue ); cgs.media.takenOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagtaken_opponent.wav", qtrue ); - if ( cgs.gametype == GT_CTF || cg_buildScript.integer ) { + if ( cgs.gametype == GT_CTF || cgs.gametype == GT_DOMINATION || cg_buildScript.integer ) { cgs.media.redFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/voc_red_returned.wav", qtrue ); cgs.media.blueFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/voc_blue_returned.wav", qtrue ); cgs.media.enemyTookYourFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_enemy_flag.wav", qtrue ); @@ -1085,7 +1086,7 @@ static void CG_RegisterGraphics( void ) { if ( cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF || cgs.gametype == GT_HARVESTER || cg_buildScript.integer ) { #else - if ( cgs.gametype == GT_CTF || cg_buildScript.integer ) { + if ( cgs.gametype == GT_CTF || cgs.gametype == GT_DOMINATION || cg_buildScript.integer ) { #endif cgs.media.redFlagModel = trap_R_RegisterModel( "models/flags/r_flag.md3" ); cgs.media.blueFlagModel = trap_R_RegisterModel( "models/flags/b_flag.md3" ); @@ -1095,6 +1096,10 @@ static void CG_RegisterGraphics( void ) { cgs.media.blueFlagShader[0] = trap_R_RegisterShaderNoMip( "icons/iconf_blu1" ); cgs.media.blueFlagShader[1] = trap_R_RegisterShaderNoMip( "icons/iconf_blu2" ); cgs.media.blueFlagShader[2] = trap_R_RegisterShaderNoMip( "icons/iconf_blu3" ); +// Q3Rally Code Start + cgs.media.sigilShader = trap_R_RegisterShaderNoMip( "icons/iconf_neutral1" ); +// Q3Rally Code END + #ifdef MISSIONPACK cgs.media.flagPoleModel = trap_R_RegisterModel( "models/flag2/flagpole.md3" ); cgs.media.flagFlapModel = trap_R_RegisterModel( "models/flag2/flagflap3.md3" ); @@ -2156,6 +2161,9 @@ void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum ) { cgs.redflag = cgs.blueflag = -1; // For compatibily, default to unset for cgs.flagStatus = -1; +// Q3Rally Code Start + cgs.sigil[0] = cgs.sigil[1] = cgs.sigil[2] = -1; // Sigil Reset +// Q3Rally Code END // old servers // get the rendering configuration from the client system diff --git a/engine/code/cgame/cg_servercmds.c b/engine/code/cgame/cg_servercmds.c index 6934c9f7..36048c95 100644 --- a/engine/code/cgame/cg_servercmds.c +++ b/engine/code/cgame/cg_servercmds.c @@ -263,6 +263,14 @@ void CG_SetConfigValues( void ) { cgs.redflag = s[0] - '0'; cgs.blueflag = s[1] - '0'; } + + else if ( cgs.gametype == GT_DOMINATION ) { + s = CG_ConfigString( CS_SIGILSTATUS ); + cgs.sigil[0] = s[0] - '0'; + cgs.sigil[1] = s[1] - '0'; + cgs.sigil[2] = s[2] - '0'; + } + #ifdef MISSIONPACK else if( cgs.gametype == GT_1FCTF ) { s = CG_ConfigString( CS_FLAGSTATUS ); @@ -400,7 +408,15 @@ static void CG_ConfigStringModified( void ) { cgs.flagStatus = str[0] - '0'; } #endif - } + } + + else if ( num == CS_SIGILSTATUS ) { + if ( cgs.gametype == GT_DOMINATION ) { + cgs.sigil[0] = str[0] - '0'; + cgs.sigil[1] = str[1] - '1'; + cgs.sigil[2] = str[2] - '2'; + } + } else if ( num == CS_SHADERSTATE ) { CG_ShaderStateChanged(); } diff --git a/engine/code/cgame/cg_syscalls.c b/engine/code/cgame/cg_syscalls.c index 8e9c5740..85b13ad2 100644 --- a/engine/code/cgame/cg_syscalls.c +++ b/engine/code/cgame/cg_syscalls.c @@ -219,10 +219,23 @@ void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], in syscall( CG_S_RESPATIALIZE, entityNum, origin, axis, inwater ); } + sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed ) { return syscall( CG_S_REGISTERSOUND, sample, compressed ); } +/* Temp Debug Code + +sfxHandle_t trap_S_RegisterSoundDebug( const char *sample, qboolean compressed, const char *file, int line ) { + if ( !sample ) { + Com_Printf( "DEBUG: trap_S_RegisterSound: NULL sound name at %s:%d\n", file, line ); + } + + return syscall( CG_S_REGISTERSOUND, sample, compressed ); +} + +*/ + void trap_S_StartBackgroundTrack( const char *intro, const char *loop ) { syscall( CG_S_STARTBACKGROUNDTRACK, intro, loop ); } diff --git a/engine/code/game/bg_misc.c b/engine/code/game/bg_misc.c index 0b27a227..cd67fcf3 100644 --- a/engine/code/game/bg_misc.c +++ b/engine/code/game/bg_misc.c @@ -890,6 +890,61 @@ Only in CTF games /* sounds */ "" }, +// Q3Rally Code Start + +/*QUAKED team_DOMINATION_sigil_red +Only in Domination games +*/ + { + "team_DOMINATION_sigil_red", + NULL, + { "models/flags/r_flag.md3", + 0, 0, 0 }, +/* icon */ "icons/iconf_red1", +/* pickup */ "Flag", + 0, + IT_SIGIL, + PW_SIGILRED, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED team_DOMINATION_sigil_blue +Only in Domination games +*/ + { + "team_DOMINATION_sigil_blue", + NULL, + { "models/flags/b_flag.md3", + 0, 0, 0 }, +/* icon */ "icons/iconf_blu1", +/* pickup */ "Flag", + 0, + IT_SIGIL, + PW_SIGILBLUE, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED team_DOMINATION_sigil +Only in Domination games +*/ + { + "team_DOMINATION_sigil", + NULL, + { "models/flags/n_flag.md3", + 0, 0, 0 }, +/* icon */ "icons/iconf_neutral1", +/* pickup */ "Flag", + 0, + IT_SIGIL, + PW_SIGILWHITE, +/* precache */ "", +/* sounds */ "" + }, + +// Q3Rally Code END + #ifdef MISSIONPACK /*QUAKED holdable_kamikaze (.3 .3 1) (-16 -16 -16) (16 16 16) suspended */ @@ -1170,7 +1225,8 @@ gitem_t *BG_FindItemForPowerup( powerup_t pw ) { for ( i = 0 ; i < bg_numItems ; i++ ) { if ( (bg_itemlist[i].giType == IT_POWERUP || bg_itemlist[i].giType == IT_TEAM || - bg_itemlist[i].giType == IT_PERSISTANT_POWERUP) && + bg_itemlist[i].giType == IT_PERSISTANT_POWERUP || + bg_itemlist[i].giType == IT_SIGIL ) && bg_itemlist[i].giTag == pw ) { return &bg_itemlist[i]; } @@ -1437,6 +1493,18 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play } #endif return qfalse; + + // Q3Rally Code Start + case IT_SIGIL: + // red team cannot touch a red sigil + if (ps->persistant[PERS_TEAM] == TEAM_RED && ent->powerups == PW_SIGILRED) + return qfalse; + // blue team cannot touch a blue sigil + else if (ps->persistant[PERS_TEAM] == TEAM_BLUE && ent->powerups == PW_SIGILBLUE) + return qfalse; + else + return qtrue; +// Q3Rally Code END case IT_HOLDABLE: // can only hold one item at a time @@ -1591,9 +1659,9 @@ char *eventnames[] = { "EV_NOAMMO", "EV_CHANGE_WEAPON", "EV_FIRE_WEAPON", + "EV_ALTFIRE_WEAPON", // STONELANCE "EV_HAZARD", - "EV_ALTFIRE_WEAPON", "EV_FIRE_REARWEAPON", // END diff --git a/engine/code/game/bg_public.h b/engine/code/game/bg_public.h index 1f32c4cb..f79fce6d 100644 --- a/engine/code/game/bg_public.h +++ b/engine/code/game/bg_public.h @@ -106,6 +106,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA //#define CS_MODELS 32 #define CS_MODELS 30 +#define CS_SIGILSTATUS 31 // Q3Rally Code END #define CS_SOUNDS (CS_MODELS+MAX_MODELS) // STONELANCE @@ -148,6 +149,7 @@ typedef enum { GT_TEAM_RACING, // team racing GT_TEAM_RACING_DM, // team racing with weapons GT_CTF, // capture the flag + GT_DOMINATION, // domination // Q3Rally Code END GT_MAX_GAME_TYPE } gametype_t; @@ -425,6 +427,9 @@ typedef enum { PW_AMMOREGEN, PW_INVULNERABILITY, + PW_SIGILWHITE, + PW_SIGILRED, + PW_SIGILBLUE, PW_NUM_POWERUPS @@ -825,6 +830,7 @@ typedef enum { IT_TEAM, // Q3Rally Code Start IT_RFWEAPON, + IT_SIGIL // Q3Rally Code END } itemType_t; diff --git a/engine/code/game/g_items.c b/engine/code/game/g_items.c index b1e706f1..fb4e8767 100644 --- a/engine/code/game/g_items.c +++ b/engine/code/game/g_items.c @@ -516,6 +516,11 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) { case IT_TEAM: respawn = Pickup_Team(ent, other); break; +// Q3Rally Code Start + case IT_SIGIL: + respawn = Sigil_Touch(ent, other); + break; +// Q3Rally Code END case IT_HOLDABLE: respawn = Pickup_Holdable(ent, other); break; @@ -535,7 +540,7 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) { } // powerup pickups are global broadcasts - if ( ent->item->giType == IT_POWERUP || ent->item->giType == IT_TEAM) { + if ( ent->item->giType == IT_POWERUP || ent->item->giType == IT_TEAM || ent->item->giType == IT_SIGIL ) { // if we want the global sound to play if (!ent->speed) { gentity_t *te; @@ -806,6 +811,17 @@ void G_CheckTeamItems( void ) { G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map\n" ); } } +// Q3Rally Code Start + if ( g_gametype.integer == GT_DOMINATION ) + { + gitem_t *item; + + // check for at least one sigil + item = BG_FindItem( "Flag" ); + if ( !item || !itemRegistered[item - bg_itemlist] ) + G_Printf( S_COLOR_YELLOW "WARNING: No team_DOMINATION_sigil in map" ); + } +// Q3Rally Code END #ifdef MISSIONPACK if( g_gametype.integer == GT_1FCTF ) { gitem_t *item; diff --git a/engine/code/game/g_spawn.c b/engine/code/game/g_spawn.c index 838e62d7..645414a5 100644 --- a/engine/code/game/g_spawn.c +++ b/engine/code/game/g_spawn.c @@ -324,6 +324,15 @@ qboolean G_CallSpawn( gentity_t *ent ) { G_Printf ("G_CallSpawn: NULL classname\n"); return qfalse; } + +// Q3Rally Code Start + if (g_gametype.integer == GT_DOMINATION) + { + RegisterItem(BG_FindItemForPowerup(PW_SIGILWHITE)); + RegisterItem(BG_FindItemForPowerup(PW_SIGILRED)); + RegisterItem(BG_FindItemForPowerup(PW_SIGILBLUE)); + } +// Q3Rally Code END // check item spawn functions for ( item=bg_itemlist+1 ; item->classname ; item++ ) { @@ -335,7 +344,12 @@ qboolean G_CallSpawn( gentity_t *ent ) { || item->giTag == PW_HASTE || item->giTag == PW_SHIELD ){ return qfalse; - } + } + } + if ( item->giType == IT_TEAM && g_gametype.integer == GT_DOMINATION ) { + item = BG_FindItemForPowerup(PW_SIGILWHITE); + ent->classname = item->classname; + ent->r.svFlags = SVF_BROADCAST; } G_SpawnItem( ent, item ); @@ -761,6 +775,20 @@ void SP_worldspawn( void ) { } +/* +============================ +G_ValidateSigils +============================ +*/ +void G_ValidateSigils() + { + gentity_t *it_ent; + + it_ent = G_Spawn(); + it_ent->think = ValidateSigilsInMap; + it_ent->nextthink = level.time + 500; + } + /* ============== G_SpawnEntitiesFromString @@ -786,6 +814,10 @@ void G_SpawnEntitiesFromString( void ) { G_SpawnGEntityFromSpawnVars(); } +// make sure Domination maps have a 3rd sigil +if (g_gametype.integer == GT_DOMINATION) + G_ValidateSigils(); + + level.spawning = qfalse; // any future calls to G_Spawn*() will be errors } - diff --git a/engine/code/game/g_team.c b/engine/code/game/g_team.c index b2eac89b..7d5913fb 100644 --- a/engine/code/game/g_team.c +++ b/engine/code/game/g_team.c @@ -24,6 +24,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "g_local.h" +// Q3Rally Code Start + +typedef struct domination_sigil_s +{ + gentity_t *entity; + sigilStatus_t status; +} domination_sigil_t; + +// Q3Rally Code END typedef struct teamgame_s { float last_flag_capture; @@ -35,6 +44,9 @@ typedef struct teamgame_s { int blueTakenTime; int redObeliskAttackedTime; int blueObeliskAttackedTime; +// Q3Rally Code Start + domination_sigil_t sigil[MAX_SIGILS]; +// Q3Rally Code END } teamgame_t; teamgame_t teamgame; @@ -42,6 +54,10 @@ teamgame_t teamgame; gentity_t *neutralObelisk; void Team_SetFlagStatus( int team, flagStatus_t status ); +// Q3Rally Code Start +void Team_SetSigilStatus( int sigilNum, sigilStatus_t status ); +void Init_Sigils( void ); +// Q3Rally Code END void Team_InitGame( void ) { memset(&teamgame, 0, sizeof teamgame); @@ -53,12 +69,28 @@ void Team_InitGame( void ) { teamgame.blueStatus = -1; // Invalid to force update Team_SetFlagStatus( TEAM_BLUE, FLAG_ATBASE ); break; + +// Q3Rally Code Start + + case GT_DOMINATION: + Init_Sigils(); + teamgame.sigil[0].status = teamgame.sigil[1].status = teamgame.sigil[2].status = -1; // Invalid to force update + Team_SetSigilStatus( 0, SIGIL_ISWHITE ); + Team_SetSigilStatus( 1, SIGIL_ISWHITE ); + Team_SetSigilStatus( 2, SIGIL_ISWHITE ); + break; + +// Q3Rally Code END + #ifdef MISSIONPACK case GT_1FCTF: teamgame.flagStatus = -1; // Invalid to force update Team_SetFlagStatus( TEAM_FREE, FLAG_ATBASE ); break; #endif + + + default: break; } @@ -88,6 +120,16 @@ const char *TeamName(int team) { 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) + return "SPECTATOR"; + return "FREE"; +} + const char *TeamColorString(int team) { if (team==TEAM_RED) return S_COLOR_RED; @@ -192,10 +234,152 @@ qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 ) { return qfalse; } - +// Q3Rally Code Start +static char dominationSigilStatusRemap[] = { '0', '1', '2' }; +// Q3Rally Code END static char ctfFlagStatusRemap[] = { '0', '1', '*', '*', '2' }; static char oneFlagStatusRemap[] = { '0', '1', '2', '3', '4' }; + // Q3Rally Code Start +/* +======================== +Init_Sigils +======================== +*/ +void Init_Sigils( void ) { + gentity_t *point = NULL; + int sigilNum = 0; + for (point = g_entities; point < &g_entities[level.num_entities] ; + point++) + { + if (!point->inuse) + continue; + + if (!strcmp(point->classname, "team_Domination_sigil")) { + teamgame.sigil[sigilNum].entity = point; + sigilNum++; + } + + if ( sigilNum == 2 ) + return; + } + } +/* +=============================== +Team_SetSigilStatus +=============================== +*/ +void Team_SetSigilStatus( int sigilNum, sigilStatus_t status ) { + qboolean modified = qfalse; + + // update only the sigil modified + if( teamgame.sigil[sigilNum].status != status ); + teamgame.sigil[sigilNum].status = status; + modified = qtrue; + + + if( modified ) { + char st[4]; + + //send all 3 sigils' status to the configstring + st[0] = dominationSigilStatusRemap[teamgame.sigil[0].status]; + st[1] = dominationSigilStatusRemap[teamgame.sigil[1].status]; + st[2] = dominationSigilStatusRemap[teamgame.sigil[2].status]; + st[3] = 0; + + trap_SetConfigstring( CS_SIGILSTATUS, st ); + + } + } +/* +============================== +ValidateSigilsInMap +============================== +*/ + +#define FRADIUS 800 + +void ValidateSigilsInMap( gentity_t *ent ) +{ + vec3_t start, end, temp, mins, maxs, tvec, offset = {FRADIUS, FRADIUS, FRADIUS}; + int numEnts, i, touch[MAX_GENTITIES], dist = FRADIUS; + gentity_t *tent, *targ; + float vlen; + qboolean foundItem = qfalse, foundPreferredItem = qfalse; + gitem_t *item; + + // if 3rd sigil exists, this function doesn´t need to run + if (teamgame.sigil[2].entity) + return; + + VectorCopy(teamgame.sigil[0].entity->r.currentOrigin, start); + VectorCopy(teamgame.sigil[1].entity->r.currentOrigin, end); + VectorSubtract(start, end, temp); + VectorScale(temp, 0.5, temp); + VectorAdd(end, temp, temp); + + VectorCopy(temp, mins); + VectorCopy(temp, maxs); + VectorAdd(maxs, offset, maxs); + VectorScale(offset, -1, offset); + VectorAdd(mins, offset, mins); + + numEnts = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); + + for ( i=0 ; iitem) + continue; + + if (!(tent->item->giType == IT_HEALTH || tent->item->giType == IT_ARMOR || tent->item->giType == IT_WEAPON)) + continue; + + VectorSubtract(temp, tent->r.currentOrigin, tvec); + vlen = abs(VectorLength(tvec)); + + if (vlen > FRADIUS) + continue; + + if ( (foundItem && !foundPreferredItem) && (tent->item->giType == IT_HEALTH || tent->item->giType == IT_ARMOR) ) { + + foundPreferredItem = qtrue; + dist = abs(VectorLength(tvec)); + targ = tent; + } else { + if ( vlen < dist ) { + if (tent->item->giType == IT_HEALTH || tent->item->giType == IT_ARMOR || (tent->item->giType == IT_WEAPON && !foundPreferredItem ) ) { + foundItem = qtrue; + dist = abs(VectorLength(tvec)); + targ = tent; + + if (tent->item->giType == IT_HEALTH || tent->item->giType == IT_ARMOR) + foundPreferredItem = qtrue; + + } + } + } + } + if (foundItem) + { + + item = BG_FindItemForPowerup(PW_SIGILWHITE); + targ->s.modelindex = item - bg_itemlist; + targ->classname = item->classname; + targ->item = item; + targ->r.svFlags = SVF_BROADCAST; + targ->s.powerups = PW_SIGILWHITE; + teamgame.sigil[2].entity = targ; + } + // kill the entity that does the spawn conversions + G_FreeEntity(ent); + } + + + +// Q3Rally Code END + void Team_SetFlagStatus( int team, flagStatus_t status ) { qboolean modified = qfalse; @@ -899,8 +1083,68 @@ int Pickup_Team( gentity_t *ent, gentity_t *other ) { return Team_TouchOurFlag( ent, other, team ); } return Team_TouchEnemyFlag( ent, other, team ); -} + } +// Q3Rally Code Start + +/* +=================== +Sigil_Think +=================== +*/ +void Sigil_Think( gentity_t *ent ) { + team_t team; + + team = (ent->s.powerups == PW_SIGILRED) ? TEAM_RED : TEAM_BLUE; + ent->count = 0; + level.teamScores[team]++; + ent->nextthink = level.time + 10000; + + // refresh scoreboard + CalculateRanks(); + } + +/* +==================================== +Sigil_Touch +==================================== +*/ +int Sigil_Touch( gentity_t *ent, gentity_t *other ) { + gclient_t *cl = other->client; + int sigilNum = 0; + + if (!cl) + return 0; + + if (ent->count && ent->nextthink < level.time + 1500) // protect against overflows by not counting + return 0; + + // find the index of the sigil reffered by ent + while ( sigilNum < MAX_SIGILS && teamgame.sigil[sigilNum].entity != ent ) + sigilNum++; + + if ( cl->sess.sessionTeam == TEAM_RED && ent->s.powerups != PW_SIGILRED ) + { + Team_SetSigilStatus(sigilNum, SIGIL_ISRED); + ent->nextthink = level.time - (level.time % 4000) + 4000; + ent->think = Sigil_Think; + ent->s.powerups = PW_SIGILRED; + ent->s.modelindex = ITEM_INDEX( BG_FindItemForPowerup( PW_SIGILRED ) ); + ent->count = 1; +} + else if ( cl->sess.sessionTeam == TEAM_BLUE && ent->s.powerups != PW_SIGILBLUE ) + { + Team_SetSigilStatus(sigilNum, SIGIL_ISBLUE); + ent->nextthink = level.time - (level.time % 4000) + 4000; + ent->think = Sigil_Think; + ent->s.powerups = PW_SIGILBLUE; + ent->s.modelindex = ITEM_INDEX( BG_FindItemForPowerup( PW_SIGILBLUE ) ); + ent->count = 1; + } + return 0; + } + +// Q3Rally Code END /* =========== Team_GetLocation diff --git a/engine/code/game/g_team.h b/engine/code/game/g_team.h index bbb7d1f0..5c72d50d 100644 --- a/engine/code/game/g_team.h +++ b/engine/code/game/g_team.h @@ -86,3 +86,8 @@ void TeamplayInfoMessage( gentity_t *ent ); void CheckTeamStatus(void); int Pickup_Team( gentity_t *ent, gentity_t *other ); + +// Q3Rally Code Start +int Sigil_Touch( gentity_t *ent, gentity_t *other ); +void ValidateSigilsInMap( gentity_t *ent ); +// Q3Rally Code END diff --git a/engine/code/q3_ui/ui_rally_servers.c b/engine/code/q3_ui/ui_rally_servers.c index e8443f7b..cbc9d4e5 100644 --- a/engine/code/q3_ui/ui_rally_servers.c +++ b/engine/code/q3_ui/ui_rally_servers.c @@ -131,7 +131,8 @@ MULTIPLAYER MENU (SERVER BROWSER) #define GAMES_TEAM_RACING_DM 6 #define GAMES_TEAMPLAY 7 #define GAMES_CTF 8 -#define GAMES_NUM_GAMES 9 +#define GAMES_DOMINATION 9 +#define GAMES_NUM_GAMES 10 // END static const char *master_items[] = { @@ -163,6 +164,7 @@ static const char *servertype_items[] = { "Team Racing Deathmatch", "Team Deathmatch", "Capture the Flag", + "Domination", // END 0 }; @@ -201,6 +203,7 @@ static char* gamenames[] = { "TRace DM", "Team DM", // team deathmatch "CTF", // capture the flag + "Domination", // domination // END "???", // unknown 0 @@ -520,6 +523,10 @@ int ArenaServers_GametypeForGames(int games) { case GAMES_CTF: gametype = GT_CTF; break; + + case GAMES_DOMINATION: + gametype = GT_DOMINATION; + break; } return gametype; diff --git a/engine/code/q3_ui/ui_rally_startserver.c b/engine/code/q3_ui/ui_rally_startserver.c index e5d2c931..8e931c24 100644 --- a/engine/code/q3_ui/ui_rally_startserver.c +++ b/engine/code/q3_ui/ui_rally_startserver.c @@ -144,13 +144,14 @@ static const char *gametype_items[] = { "Team Racing Deathmatch", // END "Capture the Flag", + "Domination", 0 }; // STONELANCE // gametype_items[gametype_remap2[s_serveroptions.gametype]] -static int gametype_remap[] = {GT_RACING, GT_RACING_DM, GT_DERBY, GT_DEATHMATCH, GT_TEAM, GT_TEAM_RACING, GT_TEAM_RACING_DM, GT_CTF}; -static int gametype_remap2[] = {0, 1, 0, 2, 3, 4, 5, 6, 7}; +static int gametype_remap[] = {GT_RACING, GT_RACING_DM, GT_DERBY, GT_DEATHMATCH, GT_TEAM, GT_TEAM_RACING, GT_TEAM_RACING_DM, GT_CTF, GT_DOMINATION}; +static int gametype_remap2[] = {0, 1, 0, 2, 3, 4, 5, 6, 7, 8}; int allowLength[3]; int reversable; @@ -423,8 +424,11 @@ static int GametypeBits( char *string ) { continue; } - } - + if( Q_stricmp( token, "q3r_dom" ) == 0 ) { + bits |= 1 << GT_DOMINATION; + continue; + } + } return bits; } @@ -1246,6 +1250,8 @@ typedef struct { menufield_s flaglimit; menuradiobutton_s friendlyfire; menufield_s hostname; + menulist_s dominationSpawnStyle; + menuradiobutton_s sigillocator; // STONLANCE menulist_s trackLength; menulist_s reversed; @@ -1335,6 +1341,13 @@ static const char *botSkill_list[] = { 0 }; +// for dominationSpawnStyle +static const char *dtfspawn_list[] = { + "DM Spawns", + "CTF Team Spawns", + 0 +}; + /* ================= BotAlreadySelected @@ -1368,6 +1381,8 @@ ServerOptions_Start static void ServerOptions_Start( void ) { int timelimit; int fraglimit; + int dominationSpawnStyle; + int sigillocator; int maxclients; int dedicated; int friendlyfire; @@ -1389,6 +1404,8 @@ static void ServerOptions_Start( void ) { pure = s_serveroptions.pure.curvalue; // STONELANCE skill = s_serveroptions.botSkill.curvalue + 1; + dominationSpawnStyle = s_serveroptions.dominationSpawnStyle.curvalue; // dtf + sigillocator = s_serveroptions.sigillocator.curvalue; // dtf trackLength = s_serveroptions.trackLength.curvalue; reversed = s_serveroptions.reversed.curvalue; // END @@ -1441,6 +1458,14 @@ static void ServerOptions_Start( void ) { trap_Cvar_SetValue( "ui_ctf_friendlt", friendlyfire ); break; + case GT_DOMINATION: + trap_Cvar_SetValue ("g_dominationSpawnStyle", Com_Clamp( 0, dominationSpawnStyle, dominationSpawnStyle ) ); + trap_Cvar_SetValue ("cg_sigilLocator", Com_Clamp( 1, sigillocator, sigillocator) ); + trap_Cvar_SetValue( "fraglimit", fraglimit ); + trap_Cvar_SetValue( "timelimit", timelimit ); + trap_Cvar_SetValue( "friendlt", friendlyfire ); + break; + } trap_Cvar_SetValue( "sv_maxclients", Com_Clamp( 0, 12, maxclients ) ); @@ -2219,7 +2244,9 @@ static void ServerOptions_MenuInit( qboolean multiplayer ) { s_serveroptions.fraglimit.field.widthInChars = 3; s_serveroptions.fraglimit.field.maxchars = 3; } - if( s_serveroptions.gametype != GT_CTF ) { + else if( s_serveroptions.gametype != GT_CTF && s_serveroptions.gametype != GT_DOMINATION ) { +// if( s_serveroptions.gametype != GT_CTF ) { +// END s_serveroptions.fraglimit.generic.type = MTYPE_FIELD; s_serveroptions.fraglimit.generic.name = "Frag Limit:"; s_serveroptions.fraglimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; @@ -2330,6 +2357,23 @@ static void ServerOptions_MenuInit( qboolean multiplayer ) { s_serveroptions.hostname.field.maxchars = 64; } +if (s_serveroptions.gametype == GT_DOMINATION) { + y += BIGCHAR_HEIGHT+2; + s_serveroptions.dominationSpawnStyle.generic.type = MTYPE_SPINCONTROL; + s_serveroptions.dominationSpawnStyle.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.dominationSpawnStyle.generic.x = OPTIONS_X; + s_serveroptions.dominationSpawnStyle.generic.y = y; + s_serveroptions.dominationSpawnStyle.generic.name = "Spawn Style:"; + s_serveroptions.dominationSpawnStyle.itemnames = dtfspawn_list; + + y += BIGCHAR_HEIGHT+2; + s_serveroptions.sigillocator.generic.type = MTYPE_RADIOBUTTON; + s_serveroptions.sigillocator.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.sigillocator.generic.x = OPTIONS_X; + s_serveroptions.sigillocator.generic.y = y; + s_serveroptions.sigillocator.generic.name = "Flag Locator:"; + } + y = 80; s_serveroptions.botSkill.generic.type = MTYPE_SPINCONTROL; s_serveroptions.botSkill.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; @@ -2459,7 +2503,7 @@ static void ServerOptions_MenuInit( qboolean multiplayer ) { // STONELANCE if( s_serveroptions.gametype != GT_DERBY ) { // END - if( s_serveroptions.gametype != GT_CTF ) { + if( s_serveroptions.gametype != GT_CTF && s_serveroptions.gametype != GT_DOMINATION ) { Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.fraglimit ); } else { @@ -2536,6 +2580,11 @@ static void ServerOptions_MenuInit( qboolean multiplayer ) { Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.hostname ); } +if (s_serveroptions.gametype == GT_DOMINATION) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.dominationSpawnStyle ); + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.sigillocator ); + } + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.back ); Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.go ); diff --git a/engine/code/q3_ui/ui_servers2.c b/engine/code/q3_ui/ui_servers2.c index b68aad46..0a5117e7 100644 --- a/engine/code/q3_ui/ui_servers2.c +++ b/engine/code/q3_ui/ui_servers2.c @@ -116,6 +116,7 @@ MULTIPLAYER MENU (SERVER BROWSER) #define GAMES_TEAM_RACING_DM 6 #define GAMES_TEAMPLAY 7 #define GAMES_CTF 8 +#define GAMES_DOMINATION 9 // END static const char *master_items[] = { @@ -143,6 +144,7 @@ static const char *servertype_items[] = { "Team Racing Deathmatch", "Team Deathmatch", "Capture the Flag", + "Domination", // END 0 }; @@ -180,6 +182,7 @@ static char* gamenames[] = { "TRace DM", "Team DM", // team deathmatch "CTF", // capture the flag + "Domination", // domination // END "???", // unknown 0 @@ -615,6 +618,12 @@ static void ArenaServers_UpdateMenu( void ) { } break; + case GAMES_DOMINATION: + if( servernodeptr->gametype != GT_DOMINATION ) { + continue; + } + break; + } if( servernodeptr->pingtime < servernodeptr->minPing ) { @@ -1182,6 +1191,10 @@ static void ArenaServers_StartRefresh( void ) strcpy( myargs, " ctf" ); break; + case GAMES_DOMINATION: + strcpy( myargs, " domination" ); + break; + } diff --git a/engine/code/qcommon/q_shared.h b/engine/code/qcommon/q_shared.h index 47146b21..c6a52985 100644 --- a/engine/code/qcommon/q_shared.h +++ b/engine/code/qcommon/q_shared.h @@ -67,7 +67,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define BASETA "missionpack" #ifndef PRODUCT_VERSION -#define PRODUCT_VERSION "v0.0.1.5_r253" +#define PRODUCT_VERSION "v0.0.2.1_r253" #endif @@ -1787,7 +1787,18 @@ typedef enum _flag_status { FLAG_TAKEN_BLUE, // One Flag CTF FLAG_DROPPED } flagStatus_t; + +// Q3Rally Code Start +#define MAX_SIGILS 3 + +typedef enum _sigil_status { + SIGIL_ISWHITE = 0, + SIGIL_ISRED, + SIGIL_ISBLUE +} sigilStatus_t; + +// Q3Rally Code END #define MAX_GLOBAL_SERVERS 4096 diff --git a/q3rallycode.ppr b/q3rallycode.ppr index b1945f13..cf18ea74 100644 --- a/q3rallycode.ppr +++ b/q3rallycode.ppr @@ -95,7 +95,7 @@ q3rallycode engine\code\botlib\l_utils.h engine\code\botlib\lcc.mak engine\code\botlib\linux-i386.mak - -cgame + +cgame engine\code\cgame\cg_atmospheric.c engine\code\cgame\cg_consolecmds.c engine\code\cgame\cg_draw.c @@ -427,7 +427,7 @@ q3rallycode engine\code\null\null_main.c engine\code\null\null_net.c engine\code\null\null_snddma.c - -q3_ui + +q3_ui engine\code\q3_ui\ui.def engine\code\q3_ui\ui_addbots.c engine\code\q3_ui\ui_atoms.c @@ -861,23 +861,59 @@ q3rallycode 0=engine\code\qcommon\files.c 1=engine\code\qcommon\q_shared.h 2=engine\Makefile -3=engine\code\q3_ui\ui_menu.c -4=engine\code\q3_ui\ui_rally_credits.c +3=engine\code\game\bg_misc.c +4=engine\code\cgame\cg_draw.c +5=engine\code\game\bg_public.h +6=engine\code\game\g_spawn.c +7=engine\code\game\g_team.c +8=engine\code\cgame\cg_local.h +9=engine\code\cgame\cg_syscalls.c +10=engine\code\cgame\cg_event.c +11=engine\code\cgame\cg_main.c +12=engine\code\game\inv.h +13=engine\code\game\g_items.c [Selected Project Files] Main= -Selected=engine\code\q3_ui\ui_rally_credits.c +Selected=engine\code\cgame\cg_local.h [engine\code\qcommon\files.c] -TopLine=180 -Caret=3,211 +TopLine=161 +Caret=129,192 [engine\code\qcommon\q_shared.h] -TopLine=49 -Caret=40,70 +TopLine=1141 +Caret=1,1156 [engine\Makefile] TopLine=99 Caret=17,114 -[engine\code\q3_ui\ui_menu.c] -TopLine=420 -Caret=63,438 -[engine\code\q3_ui\ui_rally_credits.c] -TopLine=101 -Caret=65,102 +[engine\code\game\bg_misc.c] +TopLine=886 +Caret=1,895 +[engine\code\cgame\cg_draw.c] +TopLine=3192 +Caret=1,3207 +[engine\code\game\bg_public.h] +TopLine=426 +Caret=1,431 +[engine\code\game\g_spawn.c] +TopLine=323 +Caret=1,332 +[engine\code\game\g_team.c] +TopLine=272 +Caret=1,272 +[engine\code\cgame\cg_local.h] +TopLine=2067 +Caret=3,2086 +[engine\code\cgame\cg_syscalls.c] +TopLine=215 +Caret=3,237 +[engine\code\cgame\cg_event.c] +TopLine=873 +Caret=94,897 +[engine\code\cgame\cg_main.c] +TopLine=631 +Caret=39,646 +[engine\code\game\inv.h] +TopLine=81 +Caret=1,95 +[engine\code\game\g_items.c] +TopLine=506 +Caret=66,537