summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cgame/cg_buildable.c164
-rw-r--r--src/cgame/cg_consolecmds.c1
-rw-r--r--src/cgame/cg_draw.c13
-rw-r--r--src/cgame/cg_local.h35
-rw-r--r--src/cgame/cg_main.c45
-rw-r--r--src/cgame/cg_players.c28
-rw-r--r--src/cgame/cg_scanner.c72
-rw-r--r--src/cgame/cg_servercmds.c35
-rw-r--r--src/cgame/cg_tutorial.c91
-rw-r--r--src/cgame/cg_view.c12
-rw-r--r--src/cgame/cg_weapons.c12
-rw-r--r--src/game/bg_misc.c13
-rw-r--r--src/game/bg_pmove.c42
-rw-r--r--src/game/bg_public.h8
-rw-r--r--src/game/g_active.c32
-rw-r--r--src/game/g_admin.c6
-rw-r--r--src/game/g_buildable.c78
-rw-r--r--src/game/g_client.c9
-rw-r--r--src/game/g_cmds.c138
-rw-r--r--src/game/g_combat.c27
-rw-r--r--src/game/g_local.h2
-rw-r--r--src/game/g_main.c8
-rw-r--r--src/game/g_weapon.c9
-rw-r--r--src/game/tremulous.h2
24 files changed, 561 insertions, 321 deletions
diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c
index b1d40b0..0c851b0 100644
--- a/src/cgame/cg_buildable.c
+++ b/src/cgame/cg_buildable.c
@@ -683,7 +683,7 @@ void CG_InitBuildables( void )
}
}
- cg.buildablesFraction = (float)i / (float)( BA_NUM_BUILDABLES - 1 );
+ cg.buildablesFraction = (float)i / (float)( CUBOID_FIRST - 1 );
trap_UpdateScreen( );
}
@@ -1024,19 +1024,20 @@ void CG_GhostBuildable( buildable_t buildable, vec3_t dims )
if(BG_Buildable(buildable, NULL)->cuboid)
{
- qhandle_t shader, ashader;
-
- CG_Cuboid_Send(); //NOTE: CG_Cuboid_Send has its own timer so we don't spam server with commands every frame
-
- if(cg.forbidCuboids)
- shader=cgs.media.cuboidYellowBuildShader;
- else if(ps->stats[STAT_BUILDABLE]&SB_VALID_TOGGLEBIT)
- shader=cgs.media.cuboidGreenBuildShader;
- else
- shader=cgs.media.cuboidRedBuildShader;
- CG_DrawCuboid(entity_origin,dims,shader,0);
- CG_DrawCuboidAxis(entity_origin,dims,cg_cuboidResizeAxis.integer,cgs.media.cuboidAxis);
- return;
+ qhandle_t shader, ashader;
+
+ CG_Cuboid_Send( ); //NOTE: CG_Cuboid_Send has its own timer so we don't spam server with commands every frame
+
+ if( cg.waitForCB )
+ shader = cgs.media.cuboidYellowBuildShader;
+ else if( cg.cuboidValid && ps->stats[ STAT_BUILDABLE ] & SB_VALID_TOGGLEBIT )
+ shader = cgs.media.cuboidGreenBuildShader;
+ else
+ shader = cgs.media.cuboidRedBuildShader;
+
+ CG_DrawCuboid( entity_origin, dims, shader, 0 );
+ CG_DrawCuboidAxis( entity_origin, dims, cg_cuboidResizeAxis.integer, cgs.media.cuboidAxis );
+ return;
}
VectorCopy(ps->viewangles,viewangles);
@@ -1896,7 +1897,16 @@ void CG_Buildable( centity_t *cent )
CG_PositionEntityOnTag( &turretBarrel, &ent, ent.hModel, "tag_turret" );
VectorCopy( cent->lerpOrigin, turretBarrel.lightingOrigin );
- AnglesToAxis( es->angles2, flatAxis );
+
+ {
+ vec3_t interpolated;
+ int i;
+
+ for( i = 0; i < 3 ; i++ )
+ interpolated[ i ] = LerpAngle( es->angles2[ i ], cent->nextState.angles2[ i ], cg.frameInterpolation );
+
+ AnglesToAxis( interpolated, flatAxis );
+ }
RotatePointAroundVector( turretBarrel.axis[ 0 ], xNormal, flatAxis[ 0 ], -rotAngle );
RotatePointAroundVector( turretBarrel.axis[ 1 ], xNormal, flatAxis[ 1 ], -rotAngle );
@@ -2090,32 +2100,36 @@ Send the cuboid selection via commands.
*/
void CG_Cuboid_Send(void)
{
- static qboolean init=qfalse;
+ static qboolean init = qfalse;
static int lastupdate;
static vec3_t lastcuboid;
- if(!BG_Buildable(cg.predictedPlayerState.stats[STAT_BUILDABLE]&~SB_VALID_TOGGLEBIT,NULL)->cuboid)
- return;
+ if( !BG_Buildable( cg.predictedPlayerState.stats[ STAT_BUILDABLE ] &~ SB_VALID_TOGGLEBIT, NULL)->cuboid)
+ return;
- if(!init)
+ if( !init )
{
- lastupdate=cg.time;
- VectorCopy(cg.cuboidSelection,lastcuboid);
- init=qtrue;
+ lastupdate = cg.time;
+ VectorCopy( cg.cuboidSelection, lastcuboid );
+ init = qtrue;
}
- if(lastupdate+100>cg.time)
- return;
+ if( lastupdate + 100 > cg.time )
+ return;
- if(!VectorCompareEpsilon(lastcuboid,cg.cuboidSelection,1e-3))
+ if( !VectorCompareEpsilon( lastcuboid, cg.cuboidSelection, 1e-3 ) )
{
- cg.latestCBNumber++;
- cg.latestCBNumber%=100;
- trap_SendClientCommand(va("cb %i %f %f %f\n",cg.latestCBNumber,cg.cuboidSelection[0],cg.cuboidSelection[1],cg.cuboidSelection[2]));
- cg.forbidCuboids=qtrue; //wait for response
+ cg.latestCBNumber++;
+ cg.latestCBNumber %= 100;
+ trap_SendClientCommand( va("cb %i %f %f %f\n",
+ cg.latestCBNumber,
+ cg.cuboidSelection[ 0 ],
+ cg.cuboidSelection[ 1 ],
+ cg.cuboidSelection[ 2 ] ) );
+ cg.waitForCB = qtrue; //wait for response
}
- lastupdate=cg.time;
- VectorCopy(cg.cuboidSelection,lastcuboid);
+ lastupdate = cg.time;
+ VectorCopy( cg.cuboidSelection, lastcuboid );
}
/*
@@ -2127,47 +2141,55 @@ Server responded to our cb with either cb2 or cb3.
*/
void CG_Cuboid_Response(void)
{
- // cb2 <a> <b> <c> : server sets client-side cuboid
- // cb3 <echo> : server agrees on player's cuboid
- // cb3 <echo> <a> <b> <c> : server doesnt agree on player's cuboid and corrects it
- static qboolean init = qfalse;
+ // cb2 <a> <b> <c> : server sets client-side cuboid
+ // cb3 <echo> : server agrees on player's cuboid
+ // cb4 <echo> : server disagrees on player's cuboid
+ int offs;
if( !BG_Buildable( cg.predictedPlayerState.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT, NULL )->cuboid )
return;
if( !Q_stricmp( CG_Argv( 0 ), "cb2" ) && trap_Argc( ) == 4 )
{
- cg.cuboidSelection[ 0 ] = atof( CG_Argv( 1 ) );
- cg.cuboidSelection[ 1 ] = atof( CG_Argv( 2 ) );
- cg.cuboidSelection[ 2 ] = atof( CG_Argv( 3 ) );
- return;
+ if( trap_Argc( ) == 4 ||
+ ( offs = 1, trap_Argc() == 5 && atoi( CG_Argv( 1 ) ) == cg.latestCBNumber ) )
+ {
+ cg.cuboidValid = qtrue;
+ cg.cuboidSelection[ 0 ] = atof( CG_Argv( 1 + offs ) );
+ cg.cuboidSelection[ 1 ] = atof( CG_Argv( 2 + offs ) );
+ cg.cuboidSelection[ 2 ] = atof( CG_Argv( 3 + offs ) );
+ return;
+ }
}
else if( !Q_stricmp( CG_Argv( 0 ), "cb3" ) )
{
if( trap_Argc( ) == 2 )
{
if( atoi( CG_Argv( 1 ) ) == cg.latestCBNumber )
- cg.forbidCuboids = qfalse;
+ cg.waitForCB = qfalse;
+ cg.cuboidValid = qtrue;
return;
}
- else if( trap_Argc() == 5)
+ }
+ else if( !Q_stricmp( CG_Argv( 0 ), "cb4" ) )
+ {
+ if( trap_Argc() == 2 )
{
- cg.cuboidSelection[ 0 ] = atof( CG_Argv( 2 ) );
- cg.cuboidSelection[ 1 ] = atof( CG_Argv( 3 ) );
- cg.cuboidSelection[ 2 ] = atof( CG_Argv( 4 ) );
if( atoi( CG_Argv( 1 ) ) == cg.latestCBNumber )
- {
- cg.forbidCuboids = qfalse;
+ {
+ cg.waitForCB = qfalse;
+ cg.cuboidValid = qfalse;
+
if( cg.lastCuboidError + 250 < cg.time )
{
trap_S_StartLocalSound( cgs.media.cuboidErrorSound, CHAN_LOCAL_SOUND );
cg.lastCuboidError = cg.time;
- }
+ }
}
- return;
+ return;
}
}
- Com_Printf( "^3warning: wrong cb2/cb3 from server\n" );
+ Com_Printf( "^3warning: wrong cb from server\n" );
}
/*
@@ -2237,7 +2259,6 @@ void CG_CuboidRotate_f(void)
break;
}
trap_S_StartLocalSound( cgs.media.cuboidRotateSound, CHAN_LOCAL_SOUND );
- CG_Cuboid_Send( );
}
/*
@@ -2257,7 +2278,7 @@ void CG_CuboidAxis_f(void)
axis = cg_cuboidResizeAxis.integer;
if( !BG_Buildable( cg.predictedPlayerState.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT, NULL )->cuboid)
return;
- if( !CG_Argv( 1 ) )
+ if( trap_Argc( ) < 2 )
{
Com_Printf( "cuboidAxis next|0|1|2 : set axis on which you want to resize your cuboid selection (0 - X, 1 - Y, 2 - Z)\n" );
return;
@@ -2272,20 +2293,51 @@ void CG_CuboidAxis_f(void)
/*
======================
+CG_CuboidSize_f
+
+Set the cuboid selection
+Syntax:
+ cuboidAxis x y z
+======================
+*/
+void CG_CuboidSize_f(void)
+{
+ int axis;
+
+ if( trap_Argc( ) < 4 )
+ {
+ Com_Printf( "cuboidAxis x y z : set the cuboid selection\n" );
+ return;
+ }
+
+ VectorSet( cg.cuboidSelection,
+ atof( CG_Argv( 1 ) ),
+ atof( CG_Argv( 2 ) ),
+ atof( CG_Argv( 3 ) ) );
+
+ trap_S_StartLocalSound( cgs.media.cuboidResizeSoundA, CHAN_LOCAL_SOUND );
+}
+
+/*
+======================
CG_CuboidAttack_f
Replaces +attack/-attack.
If building a cuboid and the selection is somehow invalid, play an error sound.
-Otherwise send the normal +attack / -attack;
+Otherwise send the normal +attack / -attack.
======================
*/
void CG_CuboidAttack_f(void)
{
- if( BG_Buildable( cg.predictedPlayerState.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT, NULL )->cuboid &&
- cg.forbidCuboids )
+ if( BG_Buildable( cg.predictedPlayerState.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT, NULL )->cuboid )
{
- trap_S_StartLocalSound( cgs.media.cuboidErrorSound, CHAN_LOCAL_SOUND );
- return;
+ if( cg.waitForCB )
+ return;
+ else if( !cg.cuboidValid )
+ {
+ trap_S_StartLocalSound( cgs.media.cuboidErrorSound, CHAN_LOCAL_SOUND );
+ return;
+ }
}
trap_SendClientCommand( va( "%s", CG_Argv(0) ) );
}
diff --git a/src/cgame/cg_consolecmds.c b/src/cgame/cg_consolecmds.c
index 0f1a3cf..cf3996d 100644
--- a/src/cgame/cg_consolecmds.c
+++ b/src/cgame/cg_consolecmds.c
@@ -195,6 +195,7 @@ static consoleCommand_t commands[ ] =
{ "clientlist", CG_ClientList_f },
{ "cuboidAxis", CG_CuboidAxis_f },
{ "cuboidRotate", CG_CuboidRotate_f },
+ { "cuboidSize", CG_CuboidSize_f },
{ "destroyTestPS", CG_DestroyTestPS_f },
{ "destroyTestTS", CG_DestroyTestTS_f },
{ "nextframe", CG_TestModelNextFrame_f },
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index 84c49a5..aa6df3d 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -2468,7 +2468,7 @@ CG_DrawTutorial
static void CG_DrawTutorial( rectDef_t *rect, float text_x, float text_y, vec4_t color,
float scale, int textalign, int textvalign, int textStyle )
{
- if( !cg_tutorial.integer && !cg_modTutorial.integer )
+ if( !cg_tutorial.integer )
return;
UI_DrawTextBlock( rect, text_x, text_y, color, scale, textalign, textvalign, textStyle, CG_TutorialText( ) );
@@ -2630,6 +2630,8 @@ static void CG_ScanForCrosshairEntity( void )
CG_Trace( &trace, start, vec3_origin, vec3_origin, end,
cg.snap->ps.clientNum, CONTENTS_SOLID|CONTENTS_BODY );
+ cg.crosshairDistance = Distance( start, trace.endpos );
+
// if the player is in fog, don't show it
content = trap_CM_PointContents( trace.endpos, 0 );
if( content & CONTENTS_FOG )
@@ -3108,6 +3110,9 @@ static void CG_DrawLighting( void )
CG_DrawPic( 0, 0, 640, 480, cgs.media.whiteShader );
trap_R_SetColor( NULL );
}
+
+ if( BG_UpgradeIsActive( UP_NIGHTVISION, cg.predictedPlayerState.stats ) )
+ CG_DrawPic( 0, 0, 640, 480, cgs.media.basivisionShader );
}
/*
@@ -3525,9 +3530,9 @@ void CG_DrawSplash( void )
trap_R_SetColor( color );
ts = 0.33f;
- tw = UI_Text_Width( MODVER_TITLE, ts );
- th = UI_Text_Height( MODVER_TITLE, ts );
- UI_Text_Paint( x + w/2 - tw/2, y + h + th, ts, color, MODVER_TITLE, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE );
+ tw = UI_Text_Width( SPLASH_VERSION, ts );
+ th = UI_Text_Height( SPLASH_VERSION, ts );
+ UI_Text_Paint( x + w/2 - tw/2, y + h + th, ts, color, SPLASH_VERSION, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE );
}
color[ 3 ] = ( t > 3.0f ) ? 4.0f - t : 1.0f;
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index a8316c5..4893060 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -809,6 +809,7 @@ typedef struct weaponInfoMode_s
qhandle_t impactParticleSystem;
qhandle_t impactMark;
qhandle_t impactMarkSize;
+ qboolean impactMarkAlphaFade;
sfxHandle_t impactSound[ 4 ]; //random impact sound
sfxHandle_t impactFleshSound[ 4 ]; //random impact sound
} weaponInfoMode_t;
@@ -1056,6 +1057,7 @@ typedef struct
int lastKillTime;
// crosshair client ID
+ float crosshairDistance;
int crosshairBuildable;
int crosshairClientNum;
int crosshairClientTime;
@@ -1184,9 +1186,10 @@ typedef struct
int nextWeaponClickTime;
vec3_t cuboidSelection;
- qboolean forbidCuboids; //if true then dont let player build a cuboid
- int latestCBNumber; //wait for this number from server before building a cuboid
- int lastCuboidError; //last time error sound was played
+ qboolean waitForCB;
+ qboolean cuboidValid;
+ int latestCBNumber; // for syncing with the server
+ int lastCuboidError; // last time an error sound was played
qhandle_t announcerStack[ MAX_ANNOUNCER_STACK ];
int announcerStackPos;
@@ -1371,6 +1374,10 @@ typedef struct
qhandle_t alienHatchPS;
sfxHandle_t alienHatchSound;
sfxHandle_t alienFailedHatchSound;
+
+ qhandle_t basivisionShader;
+ qhandle_t basivisionBlipShader;
+ qhandle_t basivisionFlareShader;
} cgMedia_t;
typedef struct
@@ -1582,10 +1589,6 @@ extern vmCvar_t cg_disableCommandDialogs;
extern vmCvar_t cg_disableScannerPlane;
extern vmCvar_t cg_tutorial;
-extern vmCvar_t cg_modTutorial;
-extern vmCvar_t cg_modTutorialReference;
-extern vmCvar_t cg_lastModVersion;
-
extern vmCvar_t cg_painBlendUpRate;
extern vmCvar_t cg_painBlendDownRate;
extern vmCvar_t cg_painBlendMax;
@@ -1627,6 +1630,10 @@ extern vmCvar_t cg_fuelInfoX;
extern vmCvar_t cg_fuelInfoY;
extern vmCvar_t cg_fuelInfoScale;
+extern vmCvar_t cg_announcer;
+
+extern vmCvar_t cg_cameraShakeMagnitude;
+
//
// cg_main.c
//
@@ -1748,6 +1755,7 @@ void CG_HumanBuildableExplosion( vec3_t origin, vec3_t dir );
void CG_AlienBuildableExplosion( vec3_t origin, vec3_t dir );
void CG_CuboidAxis_f(void);
void CG_CuboidRotate_f(void);
+void CG_CuboidSize_f(void);
void CG_Cuboid_Send(void);
void CG_Cuboid_Response(void);
void CG_CuboidResize( qboolean enlarge );
@@ -2185,15 +2193,4 @@ typedef enum
// mod version data
-#define MODVER_CURRENT 6
-#define MODVER_C2_0_1_5 6
-#define MODVER_C2_0_1_4 5
-#define MODVER_C2_0_1_3 4
-#define MODVER_C2_0_1_2 3
-#define MODVER_C2_0_1_1 2
-#define MODVER_C2_0_1_0 1
-#define MODVER_TITLE "0.1.5 (Sep 12)"
-
-
-
-
+#define SPLASH_VERSION "0.1.6 (Jan 14)"
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index c1c7a0d..ff3d567 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -192,10 +192,6 @@ vmCvar_t cg_disableCommandDialogs;
vmCvar_t cg_disableScannerPlane;
vmCvar_t cg_tutorial;
-vmCvar_t cg_modTutorial;
-vmCvar_t cg_modTutorialReference;
-vmCvar_t cg_lastModVersion;
-
vmCvar_t cg_painBlendUpRate;
vmCvar_t cg_painBlendDownRate;
vmCvar_t cg_painBlendMax;
@@ -237,6 +233,10 @@ vmCvar_t cg_fuelInfoX;
vmCvar_t cg_fuelInfoY;
vmCvar_t cg_fuelInfoScale;
+vmCvar_t cg_announcer;
+
+vmCvar_t cg_cameraShakeMagnitude;
+
typedef struct
{
vmCvar_t *vmCvar;
@@ -366,27 +366,26 @@ static cvarTable_t cvarTable[ ] =
{ &pmove_fixed, "pmove_fixed", "0", 0},
{ &pmove_msec, "pmove_msec", "8", 0},
{ &cg_noTaunt, "cg_noTaunt", "0", CVAR_ARCHIVE},
-
+
{ &cg_voice, "voice", "default", CVAR_USERINFO|CVAR_ARCHIVE},
{ &cg_emoticons, "cg_emoticons", "1", CVAR_LATCH|CVAR_ARCHIVE},
{ &cg_chatTeamPrefix, "cg_chatTeamPrefix", "1", CVAR_ARCHIVE },
-
+
{ &cg_cuboidResizeAxis, "cg_cuboidResizeAxis", "2", 0 },
{ &cg_cuboidResizeRate, "cg_cuboidResizeRate", "5", CVAR_ARCHIVE },
{ &cg_cuboidPSQuality, "cg_cuboidPSQuality", "3", CVAR_ARCHIVE },
-
+
{ &cg_cuboidInfoX, "cg_cuboidInfoX" ,"0", CVAR_ARCHIVE },
{ &cg_cuboidInfoY, "cg_cuboidInfoY" ,"150", CVAR_ARCHIVE },
-
- { &cg_modTutorial, "cg_modTutorial", "1", CVAR_ARCHIVE },
- { &cg_modTutorialReference, "cg_modTutorialReference", "0", CVAR_ARCHIVE },
- { &cg_lastModVersion, "cg_lastModVersion", "0", CVAR_ARCHIVE },
-
+
{ &cg_fuelInfoX, "cg_fuelInfoX" ,"0", CVAR_ARCHIVE },
{ &cg_fuelInfoY, "cg_fuelInfoY" ,"150", CVAR_ARCHIVE },
- { &cg_fuelInfoScale, "cg_fuelInfoScale" ,"0.5", CVAR_ARCHIVE }
+ { &cg_fuelInfoScale, "cg_fuelInfoScale" ,"0.5", CVAR_ARCHIVE },
+ { &cg_announcer, "cg_announcer", "1", CVAR_ARCHIVE },
+
+ { &cg_cameraShakeMagnitude, "cg_cameraShakeMagnitude", "1", CVAR_ARCHIVE }
};
static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
@@ -819,26 +818,30 @@ static void CG_RegisterGraphics( void )
cgs.media.greenBuildShader = trap_R_RegisterShader("gfx/misc/greenbuild" );
cgs.media.redBuildShader = trap_R_RegisterShader("gfx/misc/redbuild" );
cgs.media.humanSpawningShader = trap_R_RegisterShader("models/buildables/telenode/rep_cyl" );
-
+
for( i = 0; i < CUBOID_CRACK_TEXTURES - 1; i++ )
cgs.media.cuboidCracks[ i ] = trap_R_RegisterShader( va( "models/cuboid/cracks_%i", i ) );
-
+
cgs.media.cuboidModel = trap_R_RegisterModel( "models/cuboid/cuboid.md3" );
cgs.media.cuboidRedBuildShader = trap_R_RegisterShader( "gfx/cuboid/build_red" );
cgs.media.cuboidYellowBuildShader = trap_R_RegisterShader( "gfx/cuboid/build_yellow" );
cgs.media.cuboidGreenBuildShader = trap_R_RegisterShader( "gfx/cuboid/build_green" );
cgs.media.cuboidAxis = trap_R_RegisterShader( "gfx/cuboid/build_axis" );
cgs.media.cuboidAlienPrebuild = trap_R_RegisterShader( "gfx/cuboid/prebuild_alien" );
-
- cg.forbidCuboids=qfalse;
- cg.latestCBNumber=0;
-
+
+ cg.waitForCB = qfalse;
+ cg.cuboidValid = qfalse;
+ cg.latestCBNumber = 0;
+
for( i = 0; i < 15; i++ )
cgs.media.splashLogo[ i ] = trap_R_RegisterShader( va( "cuboid/logo_%i.tga", i ) );
cgs.media.splashLeft = trap_R_RegisterShader( "cuboid/logo_left.tga" );
cgs.media.splashRight = trap_R_RegisterShader( "cuboid/logo_right.tga" );
-
-
+
+ cgs.media.basivisionShader = trap_R_RegisterShader( "gfx/2d/basivision" );
+ cgs.media.basivisionBlipShader = trap_R_RegisterShader( "gfx/2d/basivisionBlip" );
+ cgs.media.basivisionFlareShader = trap_R_RegisterShader( "gfx/2d/basivisionFlare" );
+
for( i = 0; i < 8; i++ )
cgs.media.buildWeaponTimerPie[ i ] = trap_R_RegisterShader( buildWeaponTimerPieShaders[ i ] );
diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c
index 99f9f9e..63464e1 100644
--- a/src/cgame/cg_players.c
+++ b/src/cgame/cg_players.c
@@ -1428,9 +1428,35 @@ static void CG_PlayerUpgrades( centity_t *cent, refEntity_t *torso )
held = es->modelindex;
active = es->modelindex2;
-
+
jetjump = ( cent->jetPackJumpTime + 100 > cg.time && !( active & ( 1 << UP_JETPACK ) ) );
+ if( es->number == cg.snap->ps.clientNum )
+ {
+ static int lastTime=0;
+ static float last=0.0f;
+
+ if( active & ( 1 << UP_NIGHTVISION ) )
+ {
+ float dt, cur, target;
+ dt = 0.001f * ( cg.time - lastTime );
+ target = sqrt( cg.crosshairDistance * 3.0f );
+ cur = last + ( target - last ) * dt * 15.0f;
+
+ last = cur;
+ lastTime = cg.time;
+
+ cur = pow( cur, 2 );
+ trap_R_AddAdditiveLightToScene( cent->lerpOrigin, cur, 1, 1, 1 );
+ }
+ else
+ {
+ lastTime = cg.time;
+ last = 0.0f;
+ }
+ }
+
+
if( held & ( 1 << UP_JETPACK ) )
{
memset( &jetpack, 0, sizeof( jetpack ) );
diff --git a/src/cgame/cg_scanner.c b/src/cgame/cg_scanner.c
index 3941956..821c8bf 100644
--- a/src/cgame/cg_scanner.c
+++ b/src/cgame/cg_scanner.c
@@ -62,9 +62,9 @@ void CG_UpdateEntityPositions( void )
!( cent->currentState.eFlags & EF_DEAD ) )
{
if( BG_Buildable(cent->currentState.modelindex,NULL)->cuboid )
- if( !BG_CuboidAttributes(cent->currentState.modelindex)->detectable )
- continue; //forget about undetectable cuboids
-
+ if( !BG_CuboidAttributes(cent->currentState.modelindex)->detectable )
+ continue; //forget about undetectable cuboids
+
// add to list of item positions (for creep)
if( cent->currentState.modelindex2 == TEAM_ALIENS )
{
@@ -218,6 +218,29 @@ static void CG_DrawDir( rectDef_t *rect, vec3_t origin, vec4_t colour )
/*
=============
+CG_BasivisionBlip
+=============
+*/
+void CG_BasivisionBlip( vec3_t origin, float size, qhandle_t shader, float flareSize, qhandle_t flare )
+{
+ float x, y, s;
+
+ if( !CG_WorldToScreen( origin, &x, &y ) )
+ return;
+
+ size = size * 1000 / Distance( origin, entityPositions.origin );
+
+ if( shader )
+ CG_DrawPic( x - ( size * cgDC.aspectScale ) / 2, y - size / 2, size * cgDC.aspectScale, size,
+ cgs.media.basivisionBlipShader );
+
+ if( flare )
+ CG_DrawPic( x - ( flareSize * cgDC.aspectScale ) / 2, y - flareSize / 2, flareSize * cgDC.aspectScale, flareSize,
+ cgs.media.basivisionFlareShader );
+}
+
+/*
+=============
CG_AlienSense
=============
*/
@@ -231,24 +254,39 @@ void CG_AlienSense( rectDef_t *rect )
VectorCopy( entityPositions.origin, origin );
- //draw human buildables
- for( i = 0; i < entityPositions.numHumanBuildables; i++ )
+ if( BG_UpgradeIsActive( UP_NIGHTVISION, cg.predictedPlayerState.stats ) )
{
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin );
-
- if( VectorLength( relOrigin ) < ALIENSENSE_RANGE )
- CG_DrawDir( rect, relOrigin, buildable );
+ for( i = 0; i < entityPositions.numHumanBuildables; i++ )
+ CG_BasivisionBlip( entityPositions.humanBuildablePos[ i ],
+ 0, 0,
+ 150, cgs.media.basivisionBlipShader );
+
+ for( i = 0; i < entityPositions.numHumanClients; i++ )
+ CG_BasivisionBlip( entityPositions.humanClientPos[ i ],
+ 60, cgs.media.basivisionBlipShader,
+ 80, cgs.media.basivisionFlareShader );
}
-
- //draw human clients
- for( i = 0; i < entityPositions.numHumanClients; i++ )
+ else
{
- VectorClear( relOrigin );
- VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin );
+ //draw human buildables
+ for( i = 0; i < entityPositions.numHumanBuildables; i++ )
+ {
+ VectorClear( relOrigin );
+ VectorSubtract( entityPositions.humanBuildablePos[ i ], origin, relOrigin );
+
+ if( VectorLength( relOrigin ) < ALIENSENSE_RANGE )
+ CG_DrawDir( rect, relOrigin, buildable );
+ }
- if( VectorLength( relOrigin ) < ALIENSENSE_RANGE )
- CG_DrawDir( rect, relOrigin, client );
+ //draw human clients
+ for( i = 0; i < entityPositions.numHumanClients; i++ )
+ {
+ VectorClear( relOrigin );
+ VectorSubtract( entityPositions.humanClientPos[ i ], origin, relOrigin );
+
+ if( VectorLength( relOrigin ) < ALIENSENSE_RANGE )
+ CG_DrawDir( rect, relOrigin, client );
+ }
}
}
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index 2a71b62..cf820c0 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -634,8 +634,8 @@ void CG_Menu( int menu, int arg )
case MN_B_CUBOID_MODE1:
longMsg = "On this map noone is allowed to build a cuboid before reaching "
- "stage 2 to prevent players from cheating.";
- shortMsg = "Cuboids are disabled on stage 1";
+ "Stage 2 to prevent players from cheating.";
+ shortMsg = "Cuboids are disabled on Stage 1";
break;
case MN_B_CUBOID_MODE2:
@@ -650,6 +650,14 @@ void CG_Menu( int menu, int arg )
shortMsg = "Buildable density is too high here";
break;
+ case MN_B_INVALIDSIZE:
+ longMsg = "You cannot build a cuboid of the selected size."
+ "Most likely the size is too big, too small or "
+ "invalid. Keep changing it until the preview "
+ "turns green.";
+ shortMsg = "Invalid cuboid size";
+ break;
+
//===============================
case MN_H_NOBP:
@@ -1274,12 +1282,13 @@ void CG_ProcessAnnouncer( void )
if( last + ANNOUNCER_DELAY > cg.time )
return;
-
+
cg.announcerStackPos++;
cg.announcerStackPos %= MAX_ANNOUNCER_STACK;
-
- trap_S_StartLocalSound( cg.announcerStack[ cg.announcerStackPos ], CHAN_VOICE );
-
+
+ if( cg_announcer.integer )
+ trap_S_StartLocalSound( cg.announcerStack[ cg.announcerStackPos ], CHAN_VOICE );
+
last = cg.time;
}
@@ -1293,12 +1302,15 @@ Play an announcer sound
static void CG_Announce( void )
{
const char *event, *soundName;
-
+
+ if( !cg_announcer.integer )
+ return;
+
if( trap_Argc( ) != 2 )
return;
-
+
event = CG_Argv( 1 );
-
+
if( !Q_stricmp( event, "votenow" ) ||
!Q_stricmp( event, "votecancelled" ) ||
!Q_stricmp( event, "votefailed" ) ||
@@ -1347,8 +1359,9 @@ static void CG_GameCmds_f( void )
static consoleCommand_t svcommands[ ] =
{
{ "announce", CG_Announce },
- { "cb2", CG_Cuboid_Response }, // set local cuboid
- { "cb3", CG_Cuboid_Response }, // set local cuboid and print a "limit exceeded" warning
+ { "cb2", CG_Cuboid_Response },
+ { "cb3", CG_Cuboid_Response },
+ { "cb4", CG_Cuboid_Response },
{ "chat", CG_Chat_f },
{ "clientLevelShot", CG_ClientLevelShot_f },
{ "cmds", CG_GameCmds_f },
diff --git a/src/cgame/cg_tutorial.c b/src/cgame/cg_tutorial.c
index f68d070..212db33 100644
--- a/src/cgame/cg_tutorial.c
+++ b/src/cgame/cg_tutorial.c
@@ -639,21 +639,6 @@ const char *CG_TutorialText( void )
playerState_t *ps;
static char text[ MAX_TUTORIAL_TEXT ];
static int refreshBindings = 0;
- static qboolean checkedUpdate = qfalse;
-
- // force mod tutorial if new version
- if( !checkedUpdate )
- {
- trap_Cvar_Update( &cg_lastModVersion );
-
- if( cg_lastModVersion.integer < MODVER_CURRENT )
- {
- trap_Cvar_Set( "cg_modTutorial", "1" );
- trap_Cvar_Set( "cg_modTutorialReference", va( "%i", cg_lastModVersion.integer ) );
- trap_Cvar_Set( "cg_lastModVersion", va( "%i", MODVER_CURRENT ) );
- }
- checkedUpdate = qtrue;
- }
if( refreshBindings == 0 )
CG_GetBindings( );
@@ -663,14 +648,11 @@ const char *CG_TutorialText( void )
text[ 0 ] = '\0';
ps = &cg.snap->ps;
- if( cg_modTutorial.integer )
- {
- CG_NewText( text, ps );
-
- if( !cg_tutorial.integer )
- return text;
- }
-
+ CG_NewText( text, ps );
+
+ if( !cg_tutorial.integer )
+ return text;
+
if( !cg.intermissionStarted && !cg.demoPlayback )
{
if( ps->persistant[ PERS_SPECSTATE ] != SPECTATOR_NOT ||
@@ -800,38 +782,31 @@ static void CG_CuboidText( char *text, playerState_t *ps )
static void CG_NewText( char *text, playerState_t *ps )
{
- int reference;
-
- reference = cg_modTutorialReference.integer;
-
if( !cg.intermissionStarted && !cg.demoPlayback )
{
if( ps->persistant[ PERS_SPECSTATE ] == SPECTATOR_NOT &&
!( ps->pm_flags & PMF_FOLLOW ) &&
ps->stats[ STAT_HEALTH ] > 0 )
{
- if( reference >= MODVER_C2_0_1_0 )
+ if( BG_InventoryContainsUpgrade( UP_JETPACK, ps->stats ) )
{
- if( BG_InventoryContainsUpgrade( UP_JETPACK, ps->stats ) )
+ if( ps->stats[ STAT_FUEL ] > JETPACK_FUEL_JUMP )
{
- if( ps->stats[ STAT_FUEL ] > JETPACK_FUEL_JUMP )
- {
- Q_strcat( text, MAX_TUTORIAL_TEXT,
- va( "Press %s to perform a jetpack-aided jump. It uses fuel instead of stamina\n",
- CG_KeyNameForCommand( "+moveup" ) ) );
- }
- if( ps->stats[ STAT_FUEL ] <= JETPACK_FUEL_LOW )
- {
- Q_strcat( text, MAX_TUTORIAL_TEXT,
- va( "You are running low on jet fuel. Find an Armoury and press %s to refuel\n",
- CG_KeyNameForCommand( "buy ammo" ) ) );
- }
- else if( ps->stats[ STAT_FUEL ] <= 0 )
- {
- Q_strcat( text, MAX_TUTORIAL_TEXT,
- va( "You are out of jet fuel. You can no longer fly. Find an Armoury and press %s to refuel\n",
- CG_KeyNameForCommand( "buy ammo" ) ) );
- }
+ Q_strcat( text, MAX_TUTORIAL_TEXT,
+ va( "Press %s to perform a jetpack-aided jump. It uses fuel instead of stamina\n",
+ CG_KeyNameForCommand( "+moveup" ) ) );
+ }
+ if( ps->stats[ STAT_FUEL ] <= JETPACK_FUEL_LOW )
+ {
+ Q_strcat( text, MAX_TUTORIAL_TEXT,
+ va( "You are running low on jet fuel. Find an Armoury and press %s to refuel\n",
+ CG_KeyNameForCommand( "buy ammo" ) ) );
+ }
+ else if( ps->stats[ STAT_FUEL ] <= 0 )
+ {
+ Q_strcat( text, MAX_TUTORIAL_TEXT,
+ va( "You are out of jet fuel. You can no longer fly. Find an Armoury and press %s to refuel\n",
+ CG_KeyNameForCommand( "buy ammo" ) ) );
}
}
@@ -840,22 +815,18 @@ static void CG_NewText( char *text, playerState_t *ps )
case WP_ABUILD:
case WP_ABUILD2:
case WP_HBUILD:
- if( reference >= MODVER_C2_0_1_0 )
- {
- CG_CuboidText( text, ps );
- if( ps->weapon == WP_ABUILD2 )
- Q_strcat( text, MAX_TUTORIAL_TEXT,
- "Spitting at a human has a chance of impregnating him\n"
- "with an alien egg. After a certain amount of time,\n"
- "the egg can be spawned from by aliens, killing the human.\n" );
- }
+ CG_CuboidText( text, ps );
+ if( ps->weapon == WP_ABUILD2 )
+ Q_strcat( text, MAX_TUTORIAL_TEXT,
+ "Spitting at a human has a chance of impregnating him\n"
+ "with an alien egg. After a certain amount of time,\n"
+ "the egg can be spawned from by aliens, killing the human.\n" );
break;
case WP_ALEVEL4:
- if( reference >= MODVER_C2_0_1_0 )
- Q_strcat( text, MAX_TUTORIAL_TEXT,
- va( "Press %s to drop a Tyrant Bomb. It can be regerated by touching a Booster.\n",
- CG_KeyNameForCommand( "+button2" ) ) );
+ Q_strcat( text, MAX_TUTORIAL_TEXT,
+ va( "Press %s to drop a Tyrant Bomb. It can be regerated by touching a Booster.\n",
+ CG_KeyNameForCommand( "+button2" ) ) );
break;
}
}
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
index 4b2b254..97b7582 100644
--- a/src/cgame/cg_view.c
+++ b/src/cgame/cg_view.c
@@ -578,6 +578,18 @@ void CG_OffsetFirstPersonView( void )
origin[ 2 ] += cg.predictedPlayerState.viewheight;
return;
}
+ // camera shake effect
+ else if( cg.snap->ps.stats[ STAT_SHAKE ] > 0 )
+ {
+ float fac, mag;
+
+ fac = (float) cg.snap->ps.stats[ STAT_SHAKE ] *
+ cg_cameraShakeMagnitude.value * 0.15f;
+
+ angles[ 0 ] += crandom() * fac;
+ angles[ 1 ] += crandom() * fac;
+ angles[ 2 ] += crandom() * fac;
+ }
// add angles based on damage kick
if( cg.damageTime )
diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c
index f844f81..7e22baf 100644
--- a/src/cgame/cg_weapons.c
+++ b/src/cgame/cg_weapons.c
@@ -414,6 +414,11 @@ static qboolean CG_ParseWeaponModeSection( weaponInfoMode_t *wim, char **text_p
continue;
}
+ else if( !Q_stricmp( token, "impactMarkAlphaFade" ) )
+ {
+ wim->impactMarkAlphaFade = qtrue;
+ continue;
+ }
else if( !Q_stricmp( token, "}" ) )
return qtrue; //reached the end of this weapon section
else
@@ -1253,6 +1258,10 @@ static qboolean CG_WeaponSelectable( weapon_t weapon )
if( !BG_InventoryContainsWeapon( weapon, cg.snap->ps.stats ) )
return qfalse;
+ // needed for basilisk nightvision
+ if( BG_Weapon( weapon )->team != TEAM_HUMANS )
+ return qfalse;
+
return qtrue;
}
@@ -1742,7 +1751,8 @@ void CG_MissileHitWall( weapon_t weaponNum, weaponMode_t weaponMode, int clientN
// impact mark
//
if( radius > 0.0f )
- CG_ImpactMark( mark, origin, dir, random( ) * 360, 1, 1, 1, 1, qfalse, radius, qfalse );
+ CG_ImpactMark( mark, origin, dir, random( ) * 360, 1, 1, 1, 1,
+ weapon->wim[ weaponMode ].impactMarkAlphaFade, radius, qfalse );
}
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index b96c8a9..a416ecb 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -2804,6 +2804,19 @@ static const upgradeAttributes_t bg_upgrades[ ] =
qtrue, //qboolean purchasable
qfalse, //qboolean usable
TEAM_HUMANS //team_t team;
+ },
+ {
+ UP_NIGHTVISION, //int upgradeNum;
+ 0, //int price;
+ 0, //int stages
+ SLOT_NONE, //int slots;
+ "nightvision", //char *upgradeName;
+ "", //char *humanName;
+ "",
+ 0,
+ qfalse, //qboolean purchasable
+ qtrue, //qboolean usable
+ TEAM_ALIENS //team_t team;
}
};
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 3b53dc9..d5719a5 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -672,6 +672,9 @@ static qboolean PM_CheckWallJump( void )
float upFraction = 1.5f;
trace_t trace;
+ if( pm->waterlevel )
+ return qfalse;
+
if( !( BG_Class( pm->ps->stats[ STAT_CLASS ] )->abilities & SCA_WALLJUMPER ) )
return qfalse;
@@ -935,27 +938,45 @@ static qboolean PM_CheckWaterJump( void )
vec3_t spot;
int cont;
vec3_t flatforward;
+ vec3_t mins, maxs;
+ float a, r;
if( pm->ps->pm_time )
return qfalse;
- // check for water jump
- if( pm->waterlevel != 2 )
+ if( pm->cmd.upmove < 10 )
+ // not holding jump
return qfalse;
+ // check for water jump
+ //if( pm->waterlevel != 2 )
+ // return qfalse;
+
flatforward[ 0 ] = pml.forward[ 0 ];
flatforward[ 1 ] = pml.forward[ 1 ];
flatforward[ 2 ] = 0;
VectorNormalize( flatforward );
- VectorMA( pm->ps->origin, 30, flatforward, spot );
- spot[ 2 ] += 4;
+ BG_ClassBoundingBox( pm->ps->stats[ STAT_CLASS ], mins, maxs, NULL, NULL, NULL );
+
+ // bbox bottom
+ spot[ 0 ] = pm->ps->origin[ 0 ];
+ spot[ 1 ] = pm->ps->origin[ 1 ];
+ spot[ 2 ] = pm->ps->origin[ 2 ] + mins[ 2 ];
+
+ // project the flatforward vector onto the bbox (just a bit longer, so we'll actually hit a wall)
+ // then add it to spot
+ #define fmod(a,n) ((a)-(n)*floor((a)/(n)))
+ a = pm->ps->viewangles[ YAW ] / ( 180.0f / M_PI );
+ r = ( maxs[ 0 ] + 1 ) * 1.0f / cos( fmod( a+0.25f*M_PI, 0.5f*M_PI ) - 0.25f*M_PI );
+ VectorMA( spot, r, flatforward, spot );
+
cont = pm->pointcontents( spot, pm->ps->clientNum );
if( !( cont & CONTENTS_SOLID ) )
return qfalse;
- spot[ 2 ] += 16;
+ spot[ 2 ] = pm->ps->origin[ 2 ] + maxs[ 2 ];
cont = pm->pointcontents( spot, pm->ps->clientNum );
if( cont )
@@ -2409,32 +2430,35 @@ static void PM_SetWaterLevel( void )
int cont;
int sample1;
int sample2;
+ vec3_t mins;
//
// get waterlevel, accounting for ducking
//
pm->waterlevel = 0;
pm->watertype = 0;
+
+ BG_ClassBoundingBox( pm->ps->stats[ STAT_CLASS ], mins, NULL, NULL, NULL, NULL );
point[ 0 ] = pm->ps->origin[ 0 ];
point[ 1 ] = pm->ps->origin[ 1 ];
- point[ 2 ] = pm->ps->origin[ 2 ] + MINS_Z + 1;
+ point[ 2 ] = pm->ps->origin[ 2 ] + mins[2] + 1;
cont = pm->pointcontents( point, pm->ps->clientNum );
if( cont & MASK_WATER )
{
- sample2 = pm->ps->viewheight - MINS_Z;
+ sample2 = pm->ps->viewheight - mins[2];
sample1 = sample2 / 2;
pm->watertype = cont;
pm->waterlevel = 1;
- point[ 2 ] = pm->ps->origin[ 2 ] + MINS_Z + sample1;
+ point[ 2 ] = pm->ps->origin[ 2 ] + mins[2] + sample1;
cont = pm->pointcontents( point, pm->ps->clientNum );
if( cont & MASK_WATER )
{
pm->waterlevel = 2;
- point[ 2 ] = pm->ps->origin[ 2 ] + MINS_Z + sample2;
+ point[ 2 ] = pm->ps->origin[ 2 ] + mins[2] + sample2;
cont = pm->pointcontents( point, pm->ps->clientNum );
if( cont & MASK_WATER )
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 64ce615..e06015d 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -233,8 +233,9 @@ typedef enum
STAT_BUILDABLE, // which ghost model to display for building
STAT_FALLDIST, // the distance the player fell
STAT_VIEWLOCK, // direction to lock the view in
- STAT_FUEL // jetpacks
- // netcode has space for 2 more
+ STAT_FUEL, // jetpacks
+ STAT_SHAKE // camera shake
+ // netcode has space for 1 more
} statIndex_t;
#define SCA_WALLCLIMBER 0x00000001
@@ -397,6 +398,8 @@ typedef enum
UP_BIORES,
UP_AMMO,
+
+ UP_NIGHTVISION, // aliens
UP_NUM_UPGRADES
} upgrade_t;
@@ -630,6 +633,7 @@ typedef enum
MN_B_CUBOID_MODE1,
MN_B_CUBOID_MODE2,
MN_B_TOODENSE,
+ MN_B_INVALIDSIZE,
//alien build
MN_A_ONEOVERMIND,
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 05bda16..1fa0caa 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -168,6 +168,19 @@ void P_WorldEffects( gentity_t *ent )
ent->client->airOutTime = level.time + 12000;
ent->damage = 2;
}
+}
+
+void P_WorldEffects_Fast( gentity_t *ent )
+{
+ int waterlevel;
+
+ if( ent->client->noclip )
+ {
+ ent->client->airOutTime = level.time + 12000; // don't need air
+ return;
+ }
+
+ waterlevel = ent->waterlevel;
//
// check for sizzle damage (move to pmove?)
@@ -175,26 +188,24 @@ 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 )
{
if( ent->watertype & CONTENTS_LAVA )
{
G_Damage( ent, NULL, NULL, NULL, NULL,
- 30 * waterlevel, 0, MOD_LAVA );
+ 3 * waterlevel, 0, MOD_LAVA );
}
if( ent->watertype & CONTENTS_SLIME )
{
G_Damage( ent, NULL, NULL, NULL, NULL,
- 10 * waterlevel, 0, MOD_SLIME );
+ 1 * waterlevel, 0, MOD_SLIME );
}
}
}
}
-
/*
===============
G_SetClientSound
@@ -629,6 +640,8 @@ void ClientTimerActions( gentity_t *ent, int msec )
weapon_t weapon = BG_GetPlayerWeapon( &client->ps );
client->time100 -= 100;
+
+ P_WorldEffects_Fast( ent );
// Restore or subtract stamina
if( stopped || client->ps.pm_type == PM_JETPACK )
@@ -757,13 +770,16 @@ void ClientTimerActions( gentity_t *ent, int msec )
if( ent->client->bioresHealTimer >= 100 )
{
int delta;
-
+
delta = ent->client->bioresHealTimer / 100;
ent->health = MAX( MIN( ent->health+delta, ent->client->ps.stats[ STAT_MAX_HEALTH ] ), 1 );
-
+
ent->client->bioresHealTimer %= 100;
}
-
+
+ ent->client->ps.stats[ STAT_SHAKE ] *= 0.77f;
+ if( ent->client->ps.stats[ STAT_SHAKE ] < 0 )
+ ent->client->ps.stats[ STAT_SHAKE ] = 0;
}
while( client->time1000 >= 1000 )
diff --git a/src/game/g_admin.c b/src/game/g_admin.c
index 25e3e9b..90f42c8 100644
--- a/src/game/g_admin.c
+++ b/src/game/g_admin.c
@@ -641,7 +641,7 @@ static void admin_default_levels( void )
l->level = level++;
Q_strncpyz( l->name, "^4Unknown Player", sizeof( l->name ) );
Q_strncpyz( l->flags,
- "listplayers admintest adminhelp time",
+ "listplayers admintest adminhelp time register",
sizeof( l->flags ) );
l = l->next = BG_Alloc( sizeof( g_admin_level_t ) );
@@ -3498,6 +3498,8 @@ qboolean G_admin_register( gentity_t *ent )
Q_strncpyz( ent->client->pers.admin->name,
ent->client->pers.netname,
sizeof( ent->client->pers.admin->name ) );
-
+
+ admin_writeconfig( );
+
return qtrue;
}
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index b13c54a..0039ccd 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -2524,39 +2524,46 @@ void Cuboid_Think(gentity_t *self)
}
//Cuboids need a new die function because of the cuboid explosion effects.
-void Cuboid_Die(gentity_t *self,gentity_t *inflictor,gentity_t *attacker,int damage,int mod)
+void Cuboid_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod )
{
vec3_t dir;
- qboolean event=qfalse;
+ qboolean event = qfalse;
const cuboidAttributes_t *cuboid;
- cuboid=BG_CuboidAttributes(self->s.modelindex);
- G_SetBuildableAnim(self,BANIM_DESTROY1,qtrue); // just for sound
- self->die=nullDieFunction;
- self->killedBy=attacker-g_entities;
- self->powered=qfalse;
- self->s.eFlags&=~EF_FIRING;
- G_LogDestruction(self,attacker,mod);
- dir[0]=dir[1]=0;
- dir[2]=1;
+ cuboid = BG_CuboidAttributes( self->s.modelindex );
+ G_SetBuildableAnim( self, BANIM_DESTROY1, qtrue ); // just for sound
+ self->die = nullDieFunction;
+ self->killedBy = attacker - g_entities;
+ self->powered = qfalse;
+ self->s.eFlags &= ~EF_FIRING;
+ G_LogDestruction( self, attacker, mod );
+ dir[ 0 ] =
+ dir[ 1 ] = 0;
+ dir[ 2 ] = 1;
self->timestamp = level.time;
- G_QueueBuildPoints(self);
- if(mod!=MOD_DECONSTRUCT&&self->spawned)
+ G_QueueBuildPoints( self );
+
+ if( mod != MOD_DECONSTRUCT && self->spawned )
{
- G_RewardAttackers(self);
- G_RadiusDamage(self->s.pos.trBase,g_entities+self->killedBy,self->splashDamage,self->splashRadius,self,self->splashMethodOfDeath);
+ G_RewardAttackers( self );
+ G_RadiusDamage( self->s.pos.trBase,
+ g_entities + self->killedBy,
+ self->splashDamage,
+ self->splashRadius,
+ self,
+ self->splashMethodOfDeath );
//NOTE: all cuboid info is already packed
- self->s.eType=ET_EVENTS+EV_CUBOID_EXPLOSION;
+ self->s.eType = ET_EVENTS + EV_CUBOID_EXPLOSION;
self->freeAfterEvent = qtrue;
- G_AddEvent(self,EV_HUMAN_BUILDABLE_EXPLOSION,DirToByte(dir));
- event=qtrue;
- self->r.contents=0;
- trap_LinkEntity(self);
+ G_AddEvent( self, EV_HUMAN_BUILDABLE_EXPLOSION, DirToByte( dir ) );
+ event = qtrue;
+ self->r.contents = 0;
+ trap_LinkEntity( self );
}
else
{
- self->s.eType=0;
- G_FreeEntity(self);
+ self->s.eType = 0;
+ G_FreeEntity( self );
}
}
@@ -3440,12 +3447,18 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance
int contents;
playerState_t *ps = &ent->client->ps;
- if( BG_Buildable(buildable,NULL)->cuboid )
- BG_CuboidBBox(cuboidSize,mins,maxs);
+ if( BG_Buildable( buildable, NULL )->cuboid )
+ {
+ if( !G_CheckCuboidSize( cuboidSize, buildable ) )
+ return IBE_INVALIDSIZE;
+ BG_CuboidBBox( cuboidSize, mins, maxs );
+ }
else
BG_BuildableBoundingBox( buildable, mins, maxs );
-
- if(!BG_PositionBuildableRelativeToPlayer( ps, BG_Buildable(buildable,NULL)->cuboid, mins, maxs, trap_Trace, entity_origin, angles, &tr1 ))
+
+ if( !BG_PositionBuildableRelativeToPlayer(
+ ps, BG_Buildable( buildable, NULL )->cuboid,
+ mins, maxs, trap_Trace, entity_origin, angles, &tr1 ) )
return IBE_NOSURF;
trap_Trace( &tr2, entity_origin, mins, maxs, entity_origin, -1, MASK_PLAYERSOLID );
trap_Trace( &tr3, ps->origin, NULL, NULL, entity_origin, ent->s.number, MASK_PLAYERSOLID );
@@ -3964,15 +3977,19 @@ qboolean G_BuildIfValid( gentity_t *ent, buildable_t buildable, vec3_t cuboidSiz
case IBE_LASTSPAWN:
G_TriggerMenu( ent->client->ps.clientNum, MN_B_LASTSPAWN );
return qfalse;
-
+
case IBE_NOSURF:
G_TriggerMenu( ent->client->ps.clientNum, MN_B_NOSURF );
return qfalse;
-
+
case IBE_TOODENSE:
G_TriggerMenu( ent->client->ps.clientNum, MN_B_TOODENSE );
return qfalse;
+ case IBE_INVALIDSIZE:
+ G_TriggerMenu( ent->client->ps.clientNum, MN_B_INVALIDSIZE );
+ return qfalse;
+
default:
break;
}
@@ -4577,7 +4594,10 @@ void G_RemoveUnbuiltBuildables( gentity_t *self )
if( ent->builtBy != self->client->ps.clientNum )
continue;
-
+
+ if( ent->s.modelindex < CUBOID_FIRST )
+ continue;
+
G_Damage( ent, self, NULL, dir, dir, ent->health, 0, MOD_DECONSTRUCT );
}
}
diff --git a/src/game/g_client.c b/src/game/g_client.c
index c8421f0..7596ea1 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1397,7 +1397,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
// try to unblock the player
if( tr.startsolid )
{
- Com_Printf("DEBUG: player is stuck!\n");
+ //Com_Printf("DEBUG: player is stuck!\n");
for( i = 0; i < 16*2; i++ )
{
float a, r;
@@ -1414,7 +1414,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
if( !tr.startsolid )
{
- Com_Printf("DEBUG: player position fixed at iteration %i\n",i);
+ //Com_Printf("DEBUG: player position fixed at iteration %i\n",i);
VectorCopy( neworigin, spawn_origin );
break;
}
@@ -1547,6 +1547,11 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
else
weapon = WP_NONE;
+ // give nightvision to basilisks
+ if( ent->client->pers.classSelection == PCL_ALIEN_LEVEL1 ||
+ ent->client->pers.classSelection == PCL_ALIEN_LEVEL1_UPG )
+ BG_AddUpgradeToInventory( UP_NIGHTVISION, client->ps.stats );
+
maxAmmo = BG_Weapon( weapon )->maxAmmo;
maxClips = BG_Weapon( weapon )->maxClips;
client->ps.stats[ STAT_WEAPON ] = weapon;
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 468dde0..2c15638 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -2527,21 +2527,30 @@ void Cmd_Sell_f( gentity_t *ent )
/*
=================
-Cmd_CheckCuboidSize
+G_CheckCuboidSize
Check if the specified dimensions are valid.
=================
*/
-qboolean Cmd_CheckCuboidSize(vec3_t dims)
+qboolean G_CheckCuboidSize( vec3_t dims, buildable_t type )
{
- if(g_cuboidSizeLimit.integer)
- if(dims[0]>g_cuboidSizeLimit.integer||dims[1]>g_cuboidSizeLimit.integer||dims[2]>g_cuboidSizeLimit.integer)
- return qfalse;
- if(dims[0]*dims[1]*dims[2]<CUBOID_MINVOLUME)
- return qfalse;
- if(dims[0]<1||dims[1]<1||dims[2]<1)
- return qfalse;
- return qtrue;
+ if( g_cuboidSizeLimit.integer )
+ if( dims[ 0 ] > g_cuboidSizeLimit.integer ||
+ dims[ 1 ] > g_cuboidSizeLimit.integer ||
+ dims[ 2 ] > g_cuboidSizeLimit.integer )
+ return qfalse;
+
+ if( dims[ 0 ] * dims[ 1 ] * dims[ 2 ] < CUBOID_MINVOLUME)
+ return qfalse;
+
+ if( dims[ 0 ] < 1 || dims[ 1 ] < 1 || dims[ 2 ] < 1 )
+ return qfalse;
+
+ if( g_cuboidHealthLimit.integer )
+ if( BG_Buildable( type, dims )->health > g_cuboidHealthLimit.integer )
+ return qfalse;
+
+ return qtrue;
}
/*
@@ -2554,33 +2563,32 @@ Update player's cuboid selection (after validation) with data sent over network.
*/
void Cmd_Cb_f(gentity_t *ent)
{
- char s[MAX_TOKEN_CHARS];
- int echo;
- vec3_t dims;
+ char s[MAX_TOKEN_CHARS];
+ int echo;
+ vec3_t dims;
- if(trap_Argc()!=5)
- return;
- trap_Argv(1,s,sizeof(s));
- echo=atoi(s);
- trap_Argv(2,s,sizeof(s));
- dims[0]=atof(s);
- trap_Argv(3,s,sizeof(s));
- dims[1]=atof(s);
- trap_Argv(4,s,sizeof(s));
- dims[2]=atof(s);
- if(Cmd_CheckCuboidSize(dims))
- {
- VectorCopy(dims,ent->client->cuboidSelection);
- trap_SendServerCommand(ent->client-level.clients,va("cb3 %i\n",echo));
- G_RelayCuboidToSpectators(ent->client);
- }
- else
- {
- if(Cmd_CheckCuboidSize(ent->client->cuboidSelection))
- trap_SendServerCommand(ent->client-level.clients,va("cb3 %i %f %f %f\n",echo,ent->client->cuboidSelection[0],ent->client->cuboidSelection[1],ent->client->cuboidSelection[2]));
+ if( trap_Argc( ) != 5 )
+ return;
+
+ trap_Argv( 1, s, sizeof( s ) );
+ echo = atoi( s );
+ trap_Argv( 2, s, sizeof( s ) );
+ dims[ 0 ] = atof( s );
+ trap_Argv( 3, s, sizeof( s ) );
+ dims[ 1 ] = atof( s );
+ trap_Argv( 4, s, sizeof( s ) );
+ dims[ 2 ] = atof( s );
+
+ VectorCopy( dims, ent->client->cuboidSelection );
+ G_RelayCuboidToSpectators( ent->client );
+
+ if( G_CheckCuboidSize( dims, ent->client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) )
+ trap_SendServerCommand( ent->client - level.clients, va( "cb3 %i\n", echo ) );
else
- trap_SendServerCommand(ent->client-level.clients,va("cb3 %i %f %f %f\n",echo,g_cuboidSizeLimit.integer,g_cuboidSizeLimit.integer,g_cuboidSizeLimit.integer));
- }
+ {
+ trap_SendServerCommand( ent->client - level.clients, va( "cb4 %i\n", echo ) );
+ ent->client->ps.stats[ STAT_BUILDABLE ] &= ~SB_VALID_TOGGLEBIT;
+ }
}
@@ -2627,37 +2635,35 @@ void Cmd_Build_f( gentity_t *ent )
{
if( trap_Argc() >= 5 )
{
- trap_Argv(2,s,sizeof(s));
- dims[0]=MAX(1,atof(s));
- trap_Argv(3,s,sizeof(s));
- dims[1]=MAX(1,atof(s));
- trap_Argv(4,s,sizeof(s));
- dims[2]=MAX(1,atof(s));
- if(!Cmd_CheckCuboidSize(dims))
+ trap_Argv( 2, s, sizeof( s ) );
+ dims[ 0 ] = MAX( 1, atof( s ) );
+ trap_Argv( 3, s, sizeof( s ) );
+ dims[ 1 ] = MAX( 1, atof( s ) );
+ trap_Argv( 4, s, sizeof( s ) );
+ dims[ 2 ] = MAX( 1, atof( s ) );
+ if( !G_CheckCuboidSize( dims, buildable ) )
{
- Com_sprintf(buf,sizeof(buf),"print \"^1error: invalid cuboid size (min volume: %i, max size: %s)\n\"",
- CUBOID_MINVOLUME,(g_cuboidSizeLimit.integer?va("%ix%ix%i",g_cuboidSizeLimit.integer,g_cuboidSizeLimit.integer, g_cuboidSizeLimit.integer):"no limit"));
- trap_SendServerCommand(ent->client-level.clients,buf);
+ G_TriggerMenu( ent->client->ps.clientNum, MN_B_INVALIDSIZE );
return;
}
- VectorCopy(dims,ent->client->cuboidSelection);
+ VectorCopy( dims, ent->client->cuboidSelection );
}
// client is building a cuboid for the first time so reset the selection to default
- if(!Cmd_CheckCuboidSize(ent->client->cuboidSelection))
+ if( !G_CheckCuboidSize(ent->client->cuboidSelection, buildable) )
{
- ent->client->cuboidSelection[0]=32;
- ent->client->cuboidSelection[1]=32;
- ent->client->cuboidSelection[2]=32;
- trap_SendServerCommand(ent->client-level.clients,"cb2 32 32 32");
- G_RelayCuboidToSpectators(ent->client);
+ ent->client->cuboidSelection[ 0 ] = 30;
+ ent->client->cuboidSelection[ 1 ] = 30;
+ ent->client->cuboidSelection[ 2 ] = 30;
+ trap_SendServerCommand( ent->client-level.clients, "cb2 30 30 30" );
+ G_RelayCuboidToSpectators( ent->client );
}
- if(!BG_CuboidAllowed((team==TEAM_ALIENS?g_alienStage.integer:g_humanStage.integer)))
+ if( !BG_CuboidAllowed( ( team == TEAM_ALIENS ? g_alienStage.integer : g_humanStage.integer ) ) )
{
- if(BG_CuboidMode()==1)
- G_TriggerMenu(ent->client->ps.clientNum,MN_B_CUBOID_MODE1);
+ if( BG_CuboidMode() == 1 )
+ G_TriggerMenu(ent->client->ps.clientNum, MN_B_CUBOID_MODE1 );
else
- G_TriggerMenu(ent->client->ps.clientNum,MN_B_CUBOID_MODE2);
+ G_TriggerMenu(ent->client->ps.clientNum, MN_B_CUBOID_MODE2 );
return;
}
}
@@ -2751,12 +2757,13 @@ void Cmd_Build_f( gentity_t *ent )
if( err == MN_NONE || ent->client->pers.disableBlueprintErrors )
{
- trap_SendServerCommand(ent->client-level.clients,va("cb2 %f %f %f\n",
- ent->client->cuboidSelection[0],
- ent->client->cuboidSelection[1],
- ent->client->cuboidSelection[2]));
- G_RelayCuboidToSpectators(ent->client);
- ent->client->ps.stats[ STAT_BUILDABLE ] |= buildable;
+ trap_SendServerCommand( ent->client - level.clients,
+ va( "cb2 %f %f %f\n",
+ ent->client->cuboidSelection[ 0 ],
+ ent->client->cuboidSelection[ 1 ],
+ ent->client->cuboidSelection[ 2 ] ) );
+ G_RelayCuboidToSpectators( ent->client );
+ ent->client->ps.stats[ STAT_BUILDABLE ] |= buildable;
}
else
G_TriggerMenu( ent->client->ps.clientNum, err );
@@ -3298,12 +3305,7 @@ Cmd_Debug1_f
*/
void Cmd_Debug1_f( gentity_t *other )
{
- other->client->isImpregnated = qtrue;
- other->client->isImplantMature = qfalse;
- other->client->impregnationTime = level.time;
- other->client->impregnatedBy = -1;
- other->client->isImplantMature = qtrue;
- other->client->ps.stats[ STAT_STATE ] |= SS_IMPLANTED;
+ other->client->ps.stats[ STAT_SHAKE ] += 70;
}
/*
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index 1b6708f..fe5d607 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -1329,7 +1329,7 @@ G_RadiusDamage
qboolean G_RadiusDamage( vec3_t origin, gentity_t *attacker, float damage,
float radius, gentity_t *ignore, int mod )
{
- float points, dist;
+ float points, dist, shake;
gentity_t *ent;
int entityList[ MAX_GENTITIES ];
int numListedEntities;
@@ -1389,6 +1389,31 @@ qboolean G_RadiusDamage( vec3_t origin, gentity_t *attacker, float damage,
}
}
+ for( i = 0; i < 3; i++ )
+ {
+ mins[ i ] = origin[ i ] - radius * 2;
+ maxs[ i ] = origin[ i ] + radius * 2;
+ }
+
+ numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
+
+ for( e = 0; e < numListedEntities; e++ )
+ {
+ ent = g_entities + entityList[ e ];
+
+ if( ent == ignore )
+ continue;
+
+ if( !ent->client )
+ continue;
+
+ if( !ent->takedamage )
+ continue;
+
+ shake = damage * 10 / Distance( origin, ent->r.currentOrigin );
+ ent->client->ps.stats[ STAT_SHAKE ] += (int) shake;
+ }
+
return hitClient;
}
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 3bd8642..001c7d9 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -790,6 +790,7 @@ typedef enum
IBE_LASTSPAWN,
IBE_NOSURF,
IBE_TOODENSE,
+ IBE_INVALIDSIZE,
IBE_MAXERRORS
} itemBuildError_t;
@@ -1221,6 +1222,7 @@ extern vmCvar_t g_censorship;
extern vmCvar_t g_unlimited;
extern vmCvar_t g_instantBuild;
extern vmCvar_t g_cuboidSizeLimit;
+extern vmCvar_t g_cuboidHealthLimit;
extern vmCvar_t g_buildableDensityLimit;
extern vmCvar_t g_buildableDensityLimitRange;
diff --git a/src/game/g_main.c b/src/game/g_main.c
index 8f43d81..0f9c31c 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -152,6 +152,7 @@ vmCvar_t g_tag;
vmCvar_t g_unlimited;
vmCvar_t g_instantBuild;
vmCvar_t g_cuboidSizeLimit;
+vmCvar_t g_cuboidHealthLimit;
vmCvar_t g_cuboidMode;
vmCvar_t g_buildableDensityLimit;
@@ -295,11 +296,12 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_unlimited, "g_unlimited", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
{ &g_instantBuild, "g_instantBuild", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
- { &g_cuboidSizeLimit, "g_cuboidSizeLimit", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_cuboidSizeLimit, "g_cuboidSizeLimit", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
+ { &g_cuboidHealthLimit, "g_cuboidHealthLimit", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
{ &g_cuboidMode, "g_cuboidMode", "0", CVAR_ARCHIVE, 0, qfalse },
- { &g_buildableDensityLimit, "g_buildableDensityLimit", "0", CVAR_ARCHIVE, 0, qfalse },
- { &g_buildableDensityLimitRange, "g_buildableDensityLimitRange", "0", CVAR_ARCHIVE, 0, qfalse }
+ { &g_buildableDensityLimit, "g_buildableDensityLimit", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
+ { &g_buildableDensityLimitRange, "g_buildableDensityLimitRange", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse }
};
static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] );
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index 11d4892..4a28083 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -1136,9 +1136,7 @@ static void G_CreateNewZap( gentity_t *creator, gentity_t *target )
if( target->health > 0 )
{
G_Damage( target, creator, creator, forward,
- target->s.origin, LEVEL2_AREAZAP_DMG *
- ( ( target->s.eType == ET_BUILDABLE )
- ? LEVEL2_AREAZAP_DMG_MOD : 1.0f ),
+ target->s.origin, LEVEL2_AREAZAP_DMG,
DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE,
MOD_LEVEL2_ZAP );
@@ -1147,9 +1145,8 @@ static void G_CreateNewZap( gentity_t *creator, gentity_t *target )
for( i = 1; i < zap->numTargets; i++ )
{
G_Damage( zap->targets[ i ], target, zap->creator, forward, target->s.origin,
- ( LEVEL2_AREAZAP_DMG * ( 1 - pow( (zap->distances[ i ] /
- LEVEL2_AREAZAP_CHAIN_RANGE ) , LEVEL2_AREAZAP_CHAIN_FALLOFF ) ) + 1 )
- * ( ( zap->targets[ i ]->s.eType == ET_BUILDABLE ) ? LEVEL2_AREAZAP_DMG_MOD : 1.0f ),
+ LEVEL2_AREAZAP_DMG * ( 1 - pow( (zap->distances[ i ] /
+ LEVEL2_AREAZAP_CHAIN_RANGE ) , LEVEL2_AREAZAP_CHAIN_FALLOFF ) ) + 1,
DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE,
MOD_LEVEL2_ZAP );
}
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index a44a306..bf60cd0 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -82,7 +82,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define LEVEL2_CLAW_K_SCALE 1.0f
#define LEVEL2_CLAW_U_REPEAT 400
#define LEVEL2_CLAW_U_K_SCALE 1.0f
-#define LEVEL2_AREAZAP_DMG 6 //ADM(60)
+#define LEVEL2_AREAZAP_DMG ADM(60)
#define LEVEL2_AREAZAP_RANGE 200.0f
#define LEVEL2_AREAZAP_CHAIN_RANGE 150.0f
#define LEVEL2_AREAZAP_CHAIN_FALLOFF 8.0f