Jedi Outcast MP Patch v1.04
This commit is contained in:
parent
6af9b594e1
commit
c8563e028a
100 changed files with 3123 additions and 1723 deletions
BIN
CODE-mp/Debug/JK2cgame/vc60.idb
Normal file
BIN
CODE-mp/Debug/JK2cgame/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/JK2game/vc60.idb
Normal file
BIN
CODE-mp/Debug/JK2game/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/botlib.lib
Normal file
BIN
CODE-mp/Debug/botlib.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/botlib/vc60.idb
Normal file
BIN
CODE-mp/Debug/botlib/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/cgamex86.dll
Normal file
BIN
CODE-mp/Debug/cgamex86.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/cgamex86.lib
Normal file
BIN
CODE-mp/Debug/cgamex86.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/jk2/vc60.idb
Normal file
BIN
CODE-mp/Debug/jk2/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/jk2mp.exe
Normal file
BIN
CODE-mp/Debug/jk2mp.exe
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/jk2mpgamex86.dll
Normal file
BIN
CODE-mp/Debug/jk2mpgamex86.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/jk2mpgamex86.lib
Normal file
BIN
CODE-mp/Debug/jk2mpgamex86.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/ui/vc60.idb
Normal file
BIN
CODE-mp/Debug/ui/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/uix86.dll
Normal file
BIN
CODE-mp/Debug/uix86.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Debug/uix86.lib
Normal file
BIN
CODE-mp/Debug/uix86.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Final/JK2cgame/vc60.idb
Normal file
BIN
CODE-mp/Final/JK2cgame/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Final/JK2game/vc60.idb
Normal file
BIN
CODE-mp/Final/JK2game/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Final/OpenAL32.dll
Normal file
BIN
CODE-mp/Final/OpenAL32.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Final/botlib.lib
Normal file
BIN
CODE-mp/Final/botlib.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Final/botlib/vc60.idb
Normal file
BIN
CODE-mp/Final/botlib/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Final/cgamex86.dll
Normal file
BIN
CODE-mp/Final/cgamex86.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Final/cgamex86.lib
Normal file
BIN
CODE-mp/Final/cgamex86.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Final/jk2/vc60.idb
Normal file
BIN
CODE-mp/Final/jk2/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Final/jk2/winquake.res
Normal file
BIN
CODE-mp/Final/jk2/winquake.res
Normal file
Binary file not shown.
BIN
CODE-mp/Final/jk2mp.exe
Normal file
BIN
CODE-mp/Final/jk2mp.exe
Normal file
Binary file not shown.
BIN
CODE-mp/Final/jk2mpgamex86.dll
Normal file
BIN
CODE-mp/Final/jk2mpgamex86.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Final/jk2mpgamex86.lib
Normal file
BIN
CODE-mp/Final/jk2mpgamex86.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Final/ui/vc60.idb
Normal file
BIN
CODE-mp/Final/ui/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Final/uix86.dll
Normal file
BIN
CODE-mp/Final/uix86.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Final/uix86.lib
Normal file
BIN
CODE-mp/Final/uix86.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Release/Dedicated/vc60.idb
Normal file
BIN
CODE-mp/Release/Dedicated/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Release/JK2cgame/vc60.idb
Normal file
BIN
CODE-mp/Release/JK2cgame/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Release/JK2game/vc60.idb
Normal file
BIN
CODE-mp/Release/JK2game/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Release/botlib.lib
Normal file
BIN
CODE-mp/Release/botlib.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Release/botlib/vc60.idb
Normal file
BIN
CODE-mp/Release/botlib/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Release/cgamex86.dll
Normal file
BIN
CODE-mp/Release/cgamex86.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Release/cgamex86.lib
Normal file
BIN
CODE-mp/Release/cgamex86.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Release/jk2/vc60.idb
Normal file
BIN
CODE-mp/Release/jk2/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Release/jk2/winquake.res
Normal file
BIN
CODE-mp/Release/jk2/winquake.res
Normal file
Binary file not shown.
BIN
CODE-mp/Release/jk2Ded.exe
Normal file
BIN
CODE-mp/Release/jk2Ded.exe
Normal file
Binary file not shown.
BIN
CODE-mp/Release/jk2mp.exe
Normal file
BIN
CODE-mp/Release/jk2mp.exe
Normal file
Binary file not shown.
BIN
CODE-mp/Release/jk2mpgamex86.dll
Normal file
BIN
CODE-mp/Release/jk2mpgamex86.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Release/jk2mpgamex86.lib
Normal file
BIN
CODE-mp/Release/jk2mpgamex86.lib
Normal file
Binary file not shown.
BIN
CODE-mp/Release/ui/vc60.idb
Normal file
BIN
CODE-mp/Release/ui/vc60.idb
Normal file
Binary file not shown.
BIN
CODE-mp/Release/uix86.dll
Normal file
BIN
CODE-mp/Release/uix86.dll
Normal file
Binary file not shown.
BIN
CODE-mp/Release/uix86.lib
Normal file
BIN
CODE-mp/Release/uix86.lib
Normal file
Binary file not shown.
BIN
CODE-mp/base/vm/cgame.qvm
Normal file
BIN
CODE-mp/base/vm/cgame.qvm
Normal file
Binary file not shown.
BIN
CODE-mp/base/vm/jk2mpgame.qvm
Normal file
BIN
CODE-mp/base/vm/jk2mpgame.qvm
Normal file
Binary file not shown.
Binary file not shown.
|
@ -208,50 +208,69 @@ to a fixed color.
|
|||
Coordinates are at 640 by 480 virtual resolution
|
||||
==================
|
||||
*/
|
||||
#include "../../ui/menudef.h" // for "ITEM_TEXTSTYLE_SHADOWED"
|
||||
void CG_DrawStringExt( int x, int y, const char *string, const float *setColor,
|
||||
qboolean forceColor, qboolean shadow, int charWidth, int charHeight, int maxChars )
|
||||
{
|
||||
vec4_t color;
|
||||
const char *s;
|
||||
int xx;
|
||||
if (trap_Language_IsAsian())
|
||||
{
|
||||
// hack-a-doodle-do (post-release quick fix code)...
|
||||
//
|
||||
vec4_t color;
|
||||
memcpy(color,setColor, sizeof(color)); // de-const it
|
||||
CG_Text_Paint(x, y, 1.0f, // float scale,
|
||||
color, // vec4_t color,
|
||||
string, // const char *text,
|
||||
0.0f, // float adjust,
|
||||
0, // int limit,
|
||||
shadow ? ITEM_TEXTSTYLE_SHADOWED : 0, // int style,
|
||||
FONT_MEDIUM // iMenuFont
|
||||
) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4_t color;
|
||||
const char *s;
|
||||
int xx;
|
||||
|
||||
// draw the drop shadow
|
||||
if (shadow) {
|
||||
color[0] = color[1] = color[2] = 0;
|
||||
color[3] = setColor[3];
|
||||
trap_R_SetColor( color );
|
||||
// draw the drop shadow
|
||||
if (shadow) {
|
||||
color[0] = color[1] = color[2] = 0;
|
||||
color[3] = setColor[3];
|
||||
trap_R_SetColor( color );
|
||||
s = string;
|
||||
xx = x;
|
||||
while ( *s ) {
|
||||
if ( Q_IsColorString( s ) ) {
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
CG_DrawChar( xx + 2, y + 2, charWidth, charHeight, *s );
|
||||
xx += charWidth;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
// draw the colored text
|
||||
s = string;
|
||||
xx = x;
|
||||
trap_R_SetColor( setColor );
|
||||
while ( *s ) {
|
||||
if ( Q_IsColorString( s ) ) {
|
||||
if ( !forceColor ) {
|
||||
memcpy( color, g_color_table[ColorIndex(*(s+1))], sizeof( color ) );
|
||||
color[3] = setColor[3];
|
||||
trap_R_SetColor( color );
|
||||
}
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
CG_DrawChar( xx + 2, y + 2, charWidth, charHeight, *s );
|
||||
CG_DrawChar( xx, y, charWidth, charHeight, *s );
|
||||
xx += charWidth;
|
||||
s++;
|
||||
}
|
||||
trap_R_SetColor( NULL );
|
||||
}
|
||||
|
||||
// draw the colored text
|
||||
s = string;
|
||||
xx = x;
|
||||
trap_R_SetColor( setColor );
|
||||
while ( *s ) {
|
||||
if ( Q_IsColorString( s ) ) {
|
||||
if ( !forceColor ) {
|
||||
memcpy( color, g_color_table[ColorIndex(*(s+1))], sizeof( color ) );
|
||||
color[3] = setColor[3];
|
||||
trap_R_SetColor( color );
|
||||
}
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
CG_DrawChar( xx, y, charWidth, charHeight, *s );
|
||||
xx += charWidth;
|
||||
s++;
|
||||
}
|
||||
trap_R_SetColor( NULL );
|
||||
}
|
||||
|
||||
void CG_DrawBigString( int x, int y, const char *s, float alpha ) {
|
||||
|
|
|
@ -524,7 +524,7 @@ static void CG_General( centity_t *cent ) {
|
|||
}
|
||||
else
|
||||
{
|
||||
clEnt = &cg_entities[cent->currentState.modelindex2];
|
||||
clEnt = &cg_entities[cent->currentState.otherEntityNum2];
|
||||
}
|
||||
|
||||
if (!dismember_settings)
|
||||
|
@ -793,6 +793,10 @@ static void CG_General( centity_t *cent ) {
|
|||
trap_G2API_GiveMeVectorFromMatrix(&matrix, ORIGIN, boltOrg);
|
||||
trap_G2API_GiveMeVectorFromMatrix(&matrix, NEGATIVE_Y, boltAng);
|
||||
|
||||
if (!boltAng[0] && !boltAng[1] && !boltAng[2])
|
||||
{
|
||||
boltAng[1] = 1;
|
||||
}
|
||||
trap_FX_PlayEffectID(trap_FX_RegisterEffect("blaster/smoke_bolton"), boltOrg, boltAng);
|
||||
|
||||
cent->trailTime = cg.time + 400;
|
||||
|
|
|
@ -2236,7 +2236,9 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
// local player sounds are triggered in CG_CheckLocalSounds,
|
||||
// so ignore events on the player
|
||||
DEBUGNAME("EV_PAIN");
|
||||
if ( cent->currentState.number != cg.snap->ps.clientNum ) {
|
||||
|
||||
if ( !cg_oldPainSounds.integer || (cent->currentState.number != cg.snap->ps.clientNum) )
|
||||
{
|
||||
CG_PainEvent( cent, es->eventParm );
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -167,6 +167,17 @@ void CG_DrawInformation( void ) {
|
|||
y += iPropHeight;
|
||||
}
|
||||
|
||||
{ // display global MOTD at bottom (mirrors ui_main UI_DrawConnectScreen
|
||||
char motdString[1024];
|
||||
trap_Cvar_VariableStringBuffer( "cl_motdString", motdString, sizeof( motdString ) );
|
||||
|
||||
if (motdString[0])
|
||||
{
|
||||
UI_DrawProportionalString( 320, 425, motdString,
|
||||
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
|
||||
}
|
||||
}
|
||||
|
||||
// some extra space after hostname and motd
|
||||
y += 10;
|
||||
}
|
||||
|
|
|
@ -1313,6 +1313,11 @@ typedef struct {
|
|||
int capturelimit;
|
||||
int timelimit;
|
||||
int maxclients;
|
||||
qboolean needpass;
|
||||
qboolean jediVmerc;
|
||||
int wDisable;
|
||||
int fDisable;
|
||||
|
||||
char mapname[MAX_QPATH];
|
||||
char redTeam[MAX_QPATH];
|
||||
char blueTeam[MAX_QPATH];
|
||||
|
@ -1456,10 +1461,17 @@ extern vmCvar_t cg_zoomFov;
|
|||
|
||||
extern vmCvar_t cg_swingAngles;
|
||||
|
||||
extern vmCvar_t cg_oldPainSounds;
|
||||
|
||||
#ifdef G2_COLLISION_ENABLED
|
||||
extern vmCvar_t cg_saberModelTraceEffect;
|
||||
#endif
|
||||
|
||||
extern vmCvar_t cg_fpls;
|
||||
|
||||
extern vmCvar_t cg_saberDynamicMarks;
|
||||
extern vmCvar_t cg_saberDynamicMarkTime;
|
||||
|
||||
extern vmCvar_t cg_saberContact;
|
||||
extern vmCvar_t cg_saberTrail;
|
||||
|
||||
|
|
|
@ -410,10 +410,17 @@ vmCvar_t cg_zoomFov;
|
|||
|
||||
vmCvar_t cg_swingAngles;
|
||||
|
||||
vmCvar_t cg_oldPainSounds;
|
||||
|
||||
#ifdef G2_COLLISION_ENABLED
|
||||
vmCvar_t cg_saberModelTraceEffect;
|
||||
#endif
|
||||
|
||||
vmCvar_t cg_fpls;
|
||||
|
||||
vmCvar_t cg_saberDynamicMarks;
|
||||
vmCvar_t cg_saberDynamicMarkTime;
|
||||
|
||||
vmCvar_t cg_saberContact;
|
||||
vmCvar_t cg_saberTrail;
|
||||
|
||||
|
@ -557,10 +564,17 @@ static cvarTable_t cvarTable[] = { // bk001129
|
|||
|
||||
{ &cg_swingAngles, "cg_swingAngles", "1", 0 },
|
||||
|
||||
{ &cg_oldPainSounds, "cg_oldPainSounds", "0", 0 },
|
||||
|
||||
#ifdef G2_COLLISION_ENABLED
|
||||
{ &cg_saberModelTraceEffect, "cg_saberModelTraceEffect", "0", 0 },
|
||||
#endif
|
||||
|
||||
{ &cg_fpls, "cg_fpls", "0", 0 },
|
||||
|
||||
{ &cg_saberDynamicMarks, "cg_saberDynamicMarks", "0", 0 },
|
||||
{ &cg_saberDynamicMarkTime, "cg_saberDynamicMarkTime", "60000", 0 },
|
||||
|
||||
{ &cg_saberContact, "cg_saberContact", "1", 0 },
|
||||
{ &cg_saberTrail, "cg_saberTrail", "1", 0 },
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ retryModel:
|
|||
trap_G2API_CleanGhoul2Models(&(ci->ghoul2Model));
|
||||
}
|
||||
|
||||
if (cgs.gametype >= GT_TEAM)
|
||||
if ( cgs.gametype >= GT_TEAM && !cgs.jediVmerc )
|
||||
{
|
||||
if (ci->team == TEAM_RED)
|
||||
{
|
||||
|
@ -662,7 +662,22 @@ void CG_LoadClientInfo( clientInfo_t *ci ) {
|
|||
dir = ci->modelName;
|
||||
fallback = DEFAULT_MALE_SOUNDPATH; //(cgs.gametype >= GT_TEAM) ? DEFAULT_TEAM_MODEL : DEFAULT_MODEL;
|
||||
|
||||
fLen = trap_FS_FOpenFile(va("models/players/%s/sounds.cfg", dir), &f, FS_READ);
|
||||
if ( !ci->skinName || !Q_stricmp( "default", ci->skinName ) )
|
||||
{//try default sounds.cfg first
|
||||
fLen = trap_FS_FOpenFile(va("models/players/%s/sounds.cfg", dir), &f, FS_READ);
|
||||
if ( !f )
|
||||
{//no? Look for _default sounds.cfg
|
||||
fLen = trap_FS_FOpenFile(va("models/players/%s/sounds_default.cfg", dir), &f, FS_READ);
|
||||
}
|
||||
}
|
||||
else
|
||||
{//use the .skin associated with this skin
|
||||
fLen = trap_FS_FOpenFile(va("models/players/%s/sounds_%s.cfg", dir, ci->skinName), &f, FS_READ);
|
||||
if ( !f )
|
||||
{//fall back to default sounds
|
||||
fLen = trap_FS_FOpenFile(va("models/players/%s/sounds.cfg", dir), &f, FS_READ);
|
||||
}
|
||||
}
|
||||
|
||||
soundpath[0] = 0;
|
||||
|
||||
|
@ -1129,7 +1144,7 @@ void CG_NewClientInfo( int clientNum, qboolean entitiesInitialized ) {
|
|||
|
||||
newInfo.ATST = wasATST;
|
||||
|
||||
if (cgs.gametype >= GT_TEAM)
|
||||
if (cgs.gametype >= GT_TEAM && !cgs.jediVmerc )
|
||||
{
|
||||
if (newInfo.team == TEAM_RED)
|
||||
{
|
||||
|
@ -1190,23 +1205,29 @@ void CG_NewClientInfo( int clientNum, qboolean entitiesInitialized ) {
|
|||
if (entitiesInitialized && ci->ghoul2Model && (oldGhoul2 != ci->ghoul2Model))
|
||||
{ // Copy the new ghoul2 model to the centity.
|
||||
animation_t *anim;
|
||||
// First check if we have a ghoul2 model on the client entity.
|
||||
centity_t *cent = &cg_entities[clientNum];
|
||||
|
||||
anim = &bgGlobalAnimations[ (cg_entities[clientNum].currentState.legsAnim & ~ANIM_TOGGLEBIT) ];
|
||||
|
||||
if (anim)
|
||||
{
|
||||
int flags = BONE_ANIM_OVERRIDE_FREEZE;
|
||||
int firstFrame = anim->firstFrame + anim->numFrames-1;
|
||||
int firstFrame = anim->firstFrame;
|
||||
int setFrame = -1;
|
||||
float animSpeed = 50.0f / anim->frameLerp;
|
||||
|
||||
if (anim->loopFrames != -1)
|
||||
{
|
||||
flags = BONE_ANIM_OVERRIDE_LOOP;
|
||||
firstFrame = anim->firstFrame;
|
||||
flags |= BONE_ANIM_OVERRIDE_LOOP;
|
||||
}
|
||||
|
||||
if (cent->pe.legs.frame >= anim->firstFrame && cent->pe.legs.frame <= (anim->firstFrame + anim->numFrames))
|
||||
{
|
||||
setFrame = cent->pe.legs.frame;
|
||||
}
|
||||
|
||||
//rww - Set the animation again because it just got reset due to the model change
|
||||
trap_G2API_SetBoneAnim(ci->ghoul2Model, 0, "model_root", firstFrame, anim->firstFrame + anim->numFrames, flags, 1.0f, cg.time, -1, 150);
|
||||
trap_G2API_SetBoneAnim(ci->ghoul2Model, 0, "model_root", firstFrame, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, setFrame, 150);
|
||||
|
||||
cg_entities[clientNum].currentState.legsAnim = 0;
|
||||
}
|
||||
|
@ -1216,16 +1237,22 @@ void CG_NewClientInfo( int clientNum, qboolean entitiesInitialized ) {
|
|||
if (anim)
|
||||
{
|
||||
int flags = BONE_ANIM_OVERRIDE_FREEZE;
|
||||
int firstFrame = anim->firstFrame + anim->numFrames-1;
|
||||
int firstFrame = anim->firstFrame;
|
||||
int setFrame = -1;
|
||||
float animSpeed = 50.0f / anim->frameLerp;
|
||||
|
||||
if (anim->loopFrames != -1)
|
||||
{
|
||||
flags = BONE_ANIM_OVERRIDE_LOOP;
|
||||
firstFrame = anim->firstFrame;
|
||||
flags |= BONE_ANIM_OVERRIDE_LOOP;
|
||||
}
|
||||
|
||||
if (cent->pe.torso.frame >= anim->firstFrame && cent->pe.torso.frame <= (anim->firstFrame + anim->numFrames))
|
||||
{
|
||||
setFrame = cent->pe.torso.frame;
|
||||
}
|
||||
|
||||
//rww - Set the animation again because it just got reset due to the model change
|
||||
trap_G2API_SetBoneAnim(ci->ghoul2Model, 0, "lower_lumbar", anim->firstFrame + anim->numFrames-1, anim->firstFrame + anim->numFrames, flags, 1.0f, cg.time, -1, 150);
|
||||
trap_G2API_SetBoneAnim(ci->ghoul2Model, 0, "lower_lumbar", firstFrame, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, setFrame, 150);
|
||||
|
||||
cg_entities[clientNum].currentState.torsoAnim = 0;
|
||||
}
|
||||
|
@ -1235,26 +1262,7 @@ void CG_NewClientInfo( int clientNum, qboolean entitiesInitialized ) {
|
|||
trap_G2API_CleanGhoul2Models(&cg_entities[clientNum].ghoul2);
|
||||
}
|
||||
trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2);
|
||||
|
||||
/*
|
||||
if (cg_entities[clientNum].currentState.weapon > WP_NONE)
|
||||
{
|
||||
CG_CopyG2WeaponInstance(cg_entities[clientNum].currentState.weapon, cg_entities[clientNum].ghoul2);
|
||||
}
|
||||
*/
|
||||
//It should catch this next update anyway. We just set all ghoul2weapon's to NULL above.
|
||||
}
|
||||
/*
|
||||
else if (ci->team == TEAM_SPECTATOR && cg_entities[clientNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[clientNum].ghoul2))
|
||||
{ //this shouldn't actually happen now because we are not trying to register models for spectators. But just in case.
|
||||
trap_G2API_CleanGhoul2Models(&cg_entities[clientNum].ghoul2);
|
||||
if (ci->ghoul2Model && trap_G2_HaveWeGhoul2Models(ci->ghoul2Model))
|
||||
{
|
||||
trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, &cg_entities[clientNum].ghoul2);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2295,6 +2303,35 @@ void CG_G2SetBoneAngles(void *ghoul2, int modelIndex, const char *boneName, cons
|
|||
blendTime, currentTime);
|
||||
}
|
||||
|
||||
qboolean CG_InKnockDown( int anim )
|
||||
{
|
||||
switch ( (anim&~ANIM_TOGGLEBIT) )
|
||||
{
|
||||
case BOTH_KNOCKDOWN1:
|
||||
case BOTH_KNOCKDOWN2:
|
||||
case BOTH_KNOCKDOWN3:
|
||||
case BOTH_KNOCKDOWN4:
|
||||
case BOTH_KNOCKDOWN5:
|
||||
return qtrue;
|
||||
break;
|
||||
case BOTH_GETUP1:
|
||||
case BOTH_GETUP2:
|
||||
case BOTH_GETUP3:
|
||||
case BOTH_GETUP4:
|
||||
case BOTH_GETUP5:
|
||||
case BOTH_FORCE_GETUP_F1:
|
||||
case BOTH_FORCE_GETUP_F2:
|
||||
case BOTH_FORCE_GETUP_B1:
|
||||
case BOTH_FORCE_GETUP_B2:
|
||||
case BOTH_FORCE_GETUP_B3:
|
||||
case BOTH_FORCE_GETUP_B4:
|
||||
case BOTH_FORCE_GETUP_B5:
|
||||
return qtrue;
|
||||
break;
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void CG_G2ClientSpineAngles( centity_t *cent, vec3_t viewAngles, const vec3_t angles, vec3_t thoracicAngles, vec3_t ulAngles, vec3_t llAngles )
|
||||
{
|
||||
float legDif = 0;
|
||||
|
@ -2323,6 +2360,11 @@ void CG_G2ClientSpineAngles( centity_t *cent, vec3_t viewAngles, const vec3_t an
|
|||
!BG_SaberInSpecialAttack(cent->currentState.torsoAnim&~ANIM_TOGGLEBIT) &&
|
||||
!BG_SaberInSpecialAttack(cent->currentState.legsAnim&~ANIM_TOGGLEBIT) &&
|
||||
|
||||
!CG_InKnockDown(cent->currentState.torsoAnim) &&
|
||||
!CG_InKnockDown(cent->currentState.legsAnim) &&
|
||||
!CG_InKnockDown(cgs.clientinfo[cent->currentState.number].torsoAnim) &&
|
||||
!CG_InKnockDown(cgs.clientinfo[cent->currentState.number].legsAnim) &&
|
||||
|
||||
!BG_FlippingAnim( cgs.clientinfo[cent->currentState.number].legsAnim&~ANIM_TOGGLEBIT ) &&
|
||||
!BG_SpinningSaberAnim( cgs.clientinfo[cent->currentState.number].legsAnim&~ANIM_TOGGLEBIT ) &&
|
||||
!BG_SpinningSaberAnim( cgs.clientinfo[cent->currentState.number].torsoAnim&~ANIM_TOGGLEBIT ) &&
|
||||
|
@ -3801,7 +3843,6 @@ void CG_CreateSaberMarks( vec3_t start, vec3_t end, vec3_t normal )
|
|||
numFragments = trap_CM_MarkFragments( 4, (const float (*)[3])originalPoints,
|
||||
projection, MAX_MARK_POINTS, markPoints[0], MAX_MARK_FRAGMENTS, markFragments );
|
||||
|
||||
|
||||
for ( i = 0, mf = markFragments ; i < numFragments ; i++, mf++ )
|
||||
{
|
||||
// we have an upper limit on the complexity of polygons that we store persistantly
|
||||
|
@ -3824,26 +3865,111 @@ void CG_CreateSaberMarks( vec3_t start, vec3_t end, vec3_t normal )
|
|||
v->st[1] = 0.5 + DotProduct( delta, axis[2] ) * (0.15f + random() * 0.05f);
|
||||
}
|
||||
|
||||
// save it persistantly, do burn first
|
||||
mark = CG_AllocMark();
|
||||
mark->time = cg.time;
|
||||
mark->alphaFade = qtrue;
|
||||
mark->markShader = cgs.media.rivetMarkShader;
|
||||
mark->poly.numVerts = mf->numPoints;
|
||||
mark->color[0] = mark->color[1] = mark->color[2] = mark->color[3] = 255;
|
||||
memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) );
|
||||
if (cg_saberDynamicMarks.integer)
|
||||
{
|
||||
int i = 0;
|
||||
int i_2 = 0;
|
||||
addpolyArgStruct_t apArgs;
|
||||
vec3_t x;
|
||||
|
||||
// And now do a glow pass
|
||||
// by moving the start time back, we can hack it to fade out way before the burn does
|
||||
mark = CG_AllocMark();
|
||||
mark->time = cg.time - 8500;
|
||||
mark->alphaFade = qfalse;
|
||||
mark->markShader = trap_R_RegisterShader("gfx/effects/saberDamageGlow" );
|
||||
mark->poly.numVerts = mf->numPoints;
|
||||
mark->color[0] = 215 + random() * 40.0f;
|
||||
mark->color[1] = 96 + random() * 32.0f;
|
||||
mark->color[2] = mark->color[3] = random()*15.0f;
|
||||
memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) );
|
||||
memset (&apArgs, 0, sizeof(apArgs));
|
||||
|
||||
while (i < 4)
|
||||
{
|
||||
while (i_2 < 3)
|
||||
{
|
||||
apArgs.p[i][i_2] = verts[i].xyz[i_2];
|
||||
|
||||
i_2++;
|
||||
}
|
||||
|
||||
i_2 = 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
i_2 = 0;
|
||||
|
||||
while (i < 4)
|
||||
{
|
||||
while (i_2 < 2)
|
||||
{
|
||||
apArgs.ev[i][i_2] = verts[i].st[i_2];
|
||||
|
||||
i_2++;
|
||||
}
|
||||
|
||||
i_2 = 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
//When using addpoly, having a situation like this tends to cause bad results.
|
||||
//(I assume it doesn't like trying to draw a polygon over two planes and extends
|
||||
//the vertex out to some odd value)
|
||||
VectorSubtract(apArgs.p[0], apArgs.p[3], x);
|
||||
if (VectorLength(x) > 3.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
apArgs.numVerts = mf->numPoints;
|
||||
VectorCopy(vec3_origin, apArgs.vel);
|
||||
VectorCopy(vec3_origin, apArgs.accel);
|
||||
|
||||
apArgs.alpha1 = 1.0f;
|
||||
apArgs.alpha2 = 0.0f;
|
||||
apArgs.alphaParm = 255.0f;
|
||||
|
||||
VectorSet(apArgs.rgb1, 0.0f, 0.0f, 0.0f);
|
||||
VectorSet(apArgs.rgb2, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
apArgs.rgbParm = 0.0f;
|
||||
|
||||
apArgs.bounce = 0;
|
||||
apArgs.motionDelay = 0;
|
||||
apArgs.killTime = cg_saberDynamicMarkTime.integer;
|
||||
apArgs.shader = cgs.media.rivetMarkShader;
|
||||
apArgs.flags = 0x08000000|0x00000004;
|
||||
|
||||
trap_FX_AddPoly(&apArgs);
|
||||
|
||||
apArgs.shader = trap_R_RegisterShader("gfx/effects/saberDamageGlow");
|
||||
apArgs.rgb1[0] = 215 + random() * 40.0f;
|
||||
apArgs.rgb1[1] = 96 + random() * 32.0f;
|
||||
apArgs.rgb1[2] = apArgs.alphaParm = random()*15.0f;
|
||||
|
||||
apArgs.rgb1[0] /= 255;
|
||||
apArgs.rgb1[1] /= 255;
|
||||
apArgs.rgb1[2] /= 255;
|
||||
VectorCopy(apArgs.rgb1, apArgs.rgb2);
|
||||
|
||||
apArgs.killTime = 100;
|
||||
|
||||
trap_FX_AddPoly(&apArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
// save it persistantly, do burn first
|
||||
mark = CG_AllocMark();
|
||||
mark->time = cg.time;
|
||||
mark->alphaFade = qtrue;
|
||||
mark->markShader = cgs.media.rivetMarkShader;
|
||||
mark->poly.numVerts = mf->numPoints;
|
||||
mark->color[0] = mark->color[1] = mark->color[2] = mark->color[3] = 255;
|
||||
memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) );
|
||||
|
||||
// And now do a glow pass
|
||||
// by moving the start time back, we can hack it to fade out way before the burn does
|
||||
mark = CG_AllocMark();
|
||||
mark->time = cg.time - 8500;
|
||||
mark->alphaFade = qfalse;
|
||||
mark->markShader = trap_R_RegisterShader("gfx/effects/saberDamageGlow");
|
||||
mark->poly.numVerts = mf->numPoints;
|
||||
mark->color[0] = 215 + random() * 40.0f;
|
||||
mark->color[1] = 96 + random() * 32.0f;
|
||||
mark->color[2] = mark->color[3] = random()*15.0f;
|
||||
memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4060,7 +4186,7 @@ Ghoul2 Insert Start
|
|||
|
||||
scolor = cgs.clientinfo[cent->currentState.number].icolor1;
|
||||
|
||||
if (cgs.gametype >= GT_TEAM)
|
||||
if (cgs.gametype >= GT_TEAM && !cgs.jediVmerc )
|
||||
{
|
||||
if (cgs.clientinfo[cent->currentState.number].team == TEAM_RED)
|
||||
{
|
||||
|
@ -5521,6 +5647,95 @@ void CG_G2Animated( centity_t *cent )
|
|||
}
|
||||
//rww - here ends the majority of my g2animent stuff.
|
||||
|
||||
int cgFPLSState = 0;
|
||||
|
||||
void CG_ForceFPLSPlayerModel(centity_t *cent, clientInfo_t *ci)
|
||||
{
|
||||
int clientNum = cent->currentState.number;
|
||||
animation_t *anim;
|
||||
|
||||
if (cg_fpls.integer && !cg.renderingThirdPerson)
|
||||
{
|
||||
int skinHandle;
|
||||
|
||||
skinHandle = trap_R_RegisterSkin("models/players/kyle/model_fpls2.skin");
|
||||
|
||||
trap_G2API_CleanGhoul2Models(&(ci->ghoul2Model));
|
||||
|
||||
ci->torsoSkin = skinHandle;
|
||||
trap_G2API_InitGhoul2Model(&ci->ghoul2Model, "models/players/kyle/model.glm", 0, ci->torsoSkin, 0, 0, 0);
|
||||
|
||||
ci->bolt_rhand = trap_G2API_AddBolt(ci->ghoul2Model, 0, "*r_hand");
|
||||
|
||||
trap_G2API_SetBoneAnim(ci->ghoul2Model, 0, "model_root", 0, 12, BONE_ANIM_OVERRIDE_LOOP, 1.0f, cg.time, -1, -1);
|
||||
trap_G2API_SetBoneAngles(ci->ghoul2Model, 0, "upper_lumbar", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, NULL, 0, cg.time);
|
||||
trap_G2API_SetBoneAngles(ci->ghoul2Model, 0, "cranium", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Z, NEGATIVE_Y, POSITIVE_X, NULL, 0, cg.time);
|
||||
|
||||
ci->bolt_lhand = trap_G2API_AddBolt(ci->ghoul2Model, 0, "*l_hand");
|
||||
ci->bolt_head = trap_G2API_AddBolt(ci->ghoul2Model, 0, "*head_top");
|
||||
|
||||
ci->bolt_motion = trap_G2API_AddBolt(ci->ghoul2Model, 0, "Motion");
|
||||
|
||||
//We need a lower lumbar bolt for footsteps
|
||||
ci->bolt_llumbar = trap_G2API_AddBolt(ci->ghoul2Model, 0, "lower_lumbar");
|
||||
}
|
||||
else
|
||||
{
|
||||
CG_RegisterClientModelname(ci, ci->modelName, ci->skinName, ci->teamName, cent->currentState.number);
|
||||
}
|
||||
|
||||
anim = &bgGlobalAnimations[ (cg_entities[clientNum].currentState.legsAnim & ~ANIM_TOGGLEBIT) ];
|
||||
|
||||
if (anim)
|
||||
{
|
||||
int flags = BONE_ANIM_OVERRIDE_FREEZE;
|
||||
int firstFrame = anim->firstFrame;
|
||||
int setFrame = -1;
|
||||
float animSpeed = 50.0f / anim->frameLerp;
|
||||
|
||||
if (anim->loopFrames != -1)
|
||||
{
|
||||
flags |= BONE_ANIM_OVERRIDE_LOOP;
|
||||
}
|
||||
|
||||
if (cent->pe.legs.frame >= anim->firstFrame && cent->pe.legs.frame <= (anim->firstFrame + anim->numFrames))
|
||||
{
|
||||
setFrame = cent->pe.legs.frame;
|
||||
}
|
||||
|
||||
trap_G2API_SetBoneAnim(ci->ghoul2Model, 0, "model_root", firstFrame, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, setFrame, 150);
|
||||
|
||||
cg_entities[clientNum].currentState.legsAnim = 0;
|
||||
}
|
||||
|
||||
anim = &bgGlobalAnimations[ (cg_entities[clientNum].currentState.torsoAnim & ~ANIM_TOGGLEBIT) ];
|
||||
|
||||
if (anim)
|
||||
{
|
||||
int flags = BONE_ANIM_OVERRIDE_FREEZE;
|
||||
int firstFrame = anim->firstFrame;
|
||||
int setFrame = -1;
|
||||
float animSpeed = 50.0f / anim->frameLerp;
|
||||
|
||||
if (anim->loopFrames != -1)
|
||||
{
|
||||
flags |= BONE_ANIM_OVERRIDE_LOOP;
|
||||
}
|
||||
|
||||
if (cent->pe.torso.frame >= anim->firstFrame && cent->pe.torso.frame <= (anim->firstFrame + anim->numFrames))
|
||||
{
|
||||
setFrame = cent->pe.torso.frame;
|
||||
}
|
||||
|
||||
trap_G2API_SetBoneAnim(ci->ghoul2Model, 0, "lower_lumbar", firstFrame, anim->firstFrame + anim->numFrames, flags, animSpeed, cg.time, setFrame, 150);
|
||||
|
||||
cg_entities[clientNum].currentState.torsoAnim = 0;
|
||||
}
|
||||
|
||||
trap_G2API_CleanGhoul2Models(&(cent->ghoul2));
|
||||
trap_G2API_DuplicateGhoul2Instance(ci->ghoul2Model, ¢->ghoul2);
|
||||
cg_entities[clientNum].ghoul2 = cent->ghoul2;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -5709,7 +5924,10 @@ void CG_Player( centity_t *cent ) {
|
|||
renderfx = 0;
|
||||
if ( cent->currentState.number == cg.snap->ps.clientNum) {
|
||||
if (!cg.renderingThirdPerson) {
|
||||
renderfx = RF_THIRD_PERSON; // only draw in mirrors
|
||||
if (!cg_fpls.integer || cent->currentState.weapon != WP_SABER)
|
||||
{
|
||||
renderfx = RF_THIRD_PERSON; // only draw in mirrors
|
||||
}
|
||||
} else {
|
||||
if (cg_cameraMode.integer) {
|
||||
iwantout = 1;
|
||||
|
@ -5922,6 +6140,61 @@ doEssentialOne:
|
|||
trap_G2API_GetBoltMatrix(cent->ghoul2, 0, cgs.clientinfo[cent->currentState.number].bolt_lhand, &lHandMatrix, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
|
||||
gotLHandMatrix = qtrue;
|
||||
|
||||
if (cg.renderingThirdPerson)
|
||||
{
|
||||
if (cgFPLSState != 0)
|
||||
{
|
||||
CG_ForceFPLSPlayerModel(cent, ci);
|
||||
cgFPLSState = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ci->team == TEAM_SPECTATOR || (cg.snap && (cg.snap->ps.pm_flags & PMF_FOLLOW)))
|
||||
{ //don't allow this when spectating
|
||||
if (cgFPLSState != 0)
|
||||
{
|
||||
trap_Cvar_Set("cg_fpls", "0");
|
||||
cg_fpls.integer = 0;
|
||||
|
||||
CG_ForceFPLSPlayerModel(cent, ci);
|
||||
cgFPLSState = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cg_fpls.integer)
|
||||
{
|
||||
trap_Cvar_Set("cg_fpls", "0");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cg_fpls.integer && cent->currentState.weapon == WP_SABER && cg.snap && cent->currentState.number == cg.snap->ps.clientNum)
|
||||
{
|
||||
|
||||
if (cgFPLSState != cg_fpls.integer)
|
||||
{
|
||||
CG_ForceFPLSPlayerModel(cent, ci);
|
||||
cgFPLSState = cg_fpls.integer;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
mdxaBone_t headMatrix;
|
||||
trap_G2API_GetBoltMatrix(cent->ghoul2, 0, cgs.clientinfo[cent->currentState.number].bolt_head, &headMatrix, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
|
||||
trap_G2API_GiveMeVectorFromMatrix(&headMatrix, ORIGIN, cg.refdef.vieworg);
|
||||
*/
|
||||
}
|
||||
else if (!cg_fpls.integer && cgFPLSState)
|
||||
{
|
||||
if (cgFPLSState != cg_fpls.integer)
|
||||
{
|
||||
CG_ForceFPLSPlayerModel(cent, ci);
|
||||
cgFPLSState = cg_fpls.integer;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cent->currentState.eFlags & EF_DEAD)
|
||||
{
|
||||
dead = qtrue;
|
||||
|
@ -6002,6 +6275,10 @@ doEssentialTwo:
|
|||
CG_PlayerAnimation( cent, &legs.oldframe, &legs.frame, &legs.backlerp,
|
||||
&torso.oldframe, &torso.frame, &torso.backlerp );
|
||||
|
||||
//Need these set because we use them in other functions (cent pointer differs from cg_entities values)
|
||||
cg_entities[cent->currentState.number].pe.torso.frame = cent->pe.torso.frame;
|
||||
cg_entities[cent->currentState.number].pe.legs.frame = cent->pe.legs.frame;
|
||||
|
||||
// add the talk baloon or disconnect icon
|
||||
CG_PlayerSprites( cent );
|
||||
|
||||
|
@ -6010,13 +6287,6 @@ doEssentialTwo:
|
|||
cgs.clientinfo[cent->currentState.number].frame = cent->pe.torso.frame;
|
||||
}
|
||||
|
||||
/* if ( cent->gent->s.number == 0 && cg_thirdPersonAlpha.value < 1.0f )
|
||||
{
|
||||
ent.renderfx |= RF_ALPHA_FADE;
|
||||
ent.shaderRGBA[3] = (unsigned char)(cg_thirdPersonAlpha.value * 255.0f);
|
||||
}
|
||||
*/
|
||||
|
||||
if (cent->isATST)
|
||||
{
|
||||
goto doEssentialThree;
|
||||
|
|
|
@ -332,9 +332,14 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
|
|||
}
|
||||
|
||||
// health changes of more than -3 should make pain sounds
|
||||
if ( ps->stats[STAT_HEALTH] < (ops->stats[STAT_HEALTH] - 3)) {
|
||||
if ( ps->stats[STAT_HEALTH] > 0 ) {
|
||||
CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[STAT_HEALTH] );
|
||||
if (cg_oldPainSounds.integer)
|
||||
{
|
||||
if ( ps->stats[STAT_HEALTH] < (ops->stats[STAT_HEALTH] - 3))
|
||||
{
|
||||
if ( ps->stats[STAT_HEALTH] > 0 )
|
||||
{
|
||||
CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[STAT_HEALTH] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -363,7 +363,12 @@ qboolean CG_DrawOldScoreboard( void ) {
|
|||
|
||||
CG_DrawPic ( SB_SCORELINE_X - 40, y - 5, SB_SCORELINE_WIDTH + 80, 40, trap_R_RegisterShaderNoMip ( "gfx/menus/menu_buttonback.tga" ) );
|
||||
|
||||
CG_Text_Paint ( SB_NAME_X, y, 1.0f, colorWhite, "Name", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
|
||||
// "NAME", "SCORE", "PING", "TIME" weren't localised, GODDAMMIT!!!!!!!!
|
||||
//
|
||||
// Unfortunately, since it's so sodding late now and post release I can't enable the localisation code (REM'd) since some of
|
||||
// the localised strings don't fit - since no-one's ever seen them to notice this. Smegging brilliant. Thanks people.
|
||||
//
|
||||
CG_Text_Paint ( SB_NAME_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS3", "NAME")*/"Name",0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
|
||||
if (cgs.gametype == GT_TOURNAMENT)
|
||||
{
|
||||
char sWL[100];
|
||||
|
@ -373,10 +378,10 @@ qboolean CG_DrawOldScoreboard( void ) {
|
|||
}
|
||||
else
|
||||
{
|
||||
CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, "Score", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
|
||||
CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS3", "SCORE")*/"Score", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
|
||||
}
|
||||
CG_Text_Paint ( SB_PING_X, y, 1.0f, colorWhite, "Ping", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
|
||||
CG_Text_Paint ( SB_TIME_X, y, 1.0f, colorWhite, "Time", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
|
||||
CG_Text_Paint ( SB_PING_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS0", "PING")*/"Ping", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
|
||||
CG_Text_Paint ( SB_TIME_X, y, 1.0f, colorWhite, /*CG_GetStripEdString("MENUS3", "TIME")*/"Time", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
|
||||
|
||||
y = SB_TOP;
|
||||
|
||||
|
|
|
@ -136,6 +136,10 @@ void CG_ParseServerinfo( void ) {
|
|||
info = CG_ConfigString( CS_SERVERINFO );
|
||||
cgs.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) );
|
||||
trap_Cvar_Set("g_gametype", va("%i", cgs.gametype));
|
||||
cgs.needpass = atoi( Info_ValueForKey( info, "needpass" ) );
|
||||
cgs.jediVmerc = atoi( Info_ValueForKey( info, "g_jediVmerc" ) );
|
||||
cgs.wDisable = atoi( Info_ValueForKey( info, "wdisable" ) );
|
||||
cgs.fDisable = atoi( Info_ValueForKey( info, "fdisable" ) );
|
||||
cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
|
||||
cgs.teamflags = atoi( Info_ValueForKey( info, "teamflags" ) );
|
||||
cgs.fraglimit = atoi( Info_ValueForKey( info, "fraglimit" ) );
|
||||
|
@ -145,6 +149,7 @@ void CG_ParseServerinfo( void ) {
|
|||
cgs.maxclients = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
|
||||
mapname = Info_ValueForKey( info, "mapname" );
|
||||
|
||||
|
||||
//rww - You must do this one here, Info_ValueForKey always uses the same memory pointer.
|
||||
trap_Cvar_Set ( "ui_about_mapname", mapname );
|
||||
|
||||
|
|
|
@ -1559,7 +1559,14 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
|
|||
if (cg.snap->ps.stats[STAT_HEALTH] > 0 && (cg.predictedPlayerState.weapon == WP_SABER || cg.predictedPlayerState.usingATST ||
|
||||
cg.predictedPlayerState.forceHandExtend == HANDEXTEND_KNOCKDOWN || cg.predictedPlayerState.fallingToDeath))
|
||||
{
|
||||
cg.renderingThirdPerson = 1;
|
||||
if (cg_fpls.integer && cg.predictedPlayerState.weapon == WP_SABER)
|
||||
{ //force to first person for fpls
|
||||
cg.renderingThirdPerson = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cg.renderingThirdPerson = 1;
|
||||
}
|
||||
}
|
||||
else if (cg.snap->ps.zoomMode)
|
||||
{ //always force first person when zoomed
|
||||
|
|
|
@ -349,8 +349,8 @@ void CL_ConsolePrint( char *txt ) {
|
|||
|
||||
color = ColorIndex(COLOR_WHITE);
|
||||
|
||||
while ( (c = *txt) != 0 ) {
|
||||
if ( Q_IsColorString( txt ) ) {
|
||||
while ( (c = (unsigned char) *txt) != 0 ) {
|
||||
if ( Q_IsColorString( (unsigned char*) txt ) ) {
|
||||
color = ColorIndex( *(txt+1) );
|
||||
txt += 2;
|
||||
continue;
|
||||
|
|
|
@ -477,7 +477,7 @@ void CL_ParseDownload ( msg_t *msg ) {
|
|||
int block;
|
||||
|
||||
// read the data
|
||||
block = MSG_ReadShort ( msg );
|
||||
block = (unsigned short)MSG_ReadShort ( msg );
|
||||
|
||||
if ( !block )
|
||||
{
|
||||
|
@ -493,7 +493,7 @@ void CL_ParseDownload ( msg_t *msg ) {
|
|||
}
|
||||
}
|
||||
|
||||
size = MSG_ReadShort ( msg );
|
||||
size = (unsigned short)MSG_ReadShort ( msg );
|
||||
if (size > 0)
|
||||
MSG_ReadData( msg, data, size );
|
||||
|
||||
|
|
|
@ -2198,6 +2198,11 @@ int BotIsAChickenWuss(bot_state_t *bs)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (g_gametype.integer == GT_SINGLE_PLAYER)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_gametype.integer == GT_JEDIMASTER && !bs->cur_ps.isJediMaster)
|
||||
{ //Then you may know no fear.
|
||||
//Well, unless he's strong.
|
||||
|
@ -3724,7 +3729,15 @@ void GetIdealDestination(bot_state_t *bs)
|
|||
if (tempInt != -1 && TotalTrailDistance(bs->wpCurrent->index, tempInt, bs) != -1)
|
||||
{
|
||||
bs->wpDestination = gWPArray[tempInt];
|
||||
bs->wpDestSwitchTime = level.time + Q_irand(1000, 5000);
|
||||
|
||||
if (g_gametype.integer == GT_SINGLE_PLAYER)
|
||||
{ //be more aggressive
|
||||
bs->wpDestSwitchTime = level.time + Q_irand(300, 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs->wpDestSwitchTime = level.time + Q_irand(1000, 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6439,6 +6452,8 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
|
|||
{
|
||||
if (BotGetWeaponRange(bs) == BWEAPONRANGE_SABER)
|
||||
{
|
||||
int saberRange = SABER_ATTACK_RANGE;
|
||||
|
||||
VectorSubtract(bs->currentEnemy->client->ps.origin, bs->eye, a_fo);
|
||||
vectoangles(a_fo, a_fo);
|
||||
|
||||
|
@ -6478,7 +6493,12 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
|
|||
}
|
||||
}
|
||||
|
||||
if (bs->frame_Enemy_Len <= SABER_ATTACK_RANGE)
|
||||
if (g_gametype.integer == GT_SINGLE_PLAYER)
|
||||
{
|
||||
saberRange *= 3;
|
||||
}
|
||||
|
||||
if (bs->frame_Enemy_Len <= saberRange)
|
||||
{
|
||||
SaberCombatHandling(bs);
|
||||
|
||||
|
|
|
@ -101,3 +101,4 @@ void PM_SetAnim(int setAnimParts,int anim,int setAnimFlags, int blendTime);
|
|||
void PM_WeaponLightsaber(void);
|
||||
void PM_SetSaberMove(short newMove);
|
||||
|
||||
void PM_SetForceJumpZStart(float value);
|
||||
|
|
|
@ -161,12 +161,18 @@ int WeaponAttackAnim[WP_NUM_WEAPONS] =
|
|||
};
|
||||
|
||||
|
||||
//The magical function to end all functions.
|
||||
//This will take the force power string in powerOut and parse through it, then legalize
|
||||
//it based on the supposed rank and spit it into powerOut, returning true if it was legal
|
||||
//to begin with and false if not.
|
||||
//fpDisabled is actually only expected (needed) from the server, because the ui disables
|
||||
//force power selection anyway when force powers are disabled on the server.
|
||||
/*
|
||||
================
|
||||
BG_LegalizedForcePowers
|
||||
|
||||
The magical function to end all functions.
|
||||
This will take the force power string in powerOut and parse through it, then legalize
|
||||
it based on the supposed rank and spit it into powerOut, returning true if it was legal
|
||||
to begin with and false if not.
|
||||
fpDisabled is actually only expected (needed) from the server, because the ui disables
|
||||
force power selection anyway when force powers are disabled on the server.
|
||||
================
|
||||
*/
|
||||
qboolean BG_LegalizedForcePowers(char *powerOut, int maxRank, qboolean freeSaber, int teamForce, int gametype, int fpDisabled)
|
||||
{
|
||||
char powerBuf[128];
|
||||
|
@ -254,7 +260,6 @@ qboolean BG_LegalizedForcePowers(char *powerOut, int maxRank, qboolean freeSaber
|
|||
{
|
||||
final_Powers[i] = 0;
|
||||
//This is only likely to happen with g_forceBasedTeams. Let it slide.
|
||||
//maintainsValidity = 0;
|
||||
}
|
||||
|
||||
if ( final_Powers[i] &&
|
||||
|
@ -410,16 +415,16 @@ qboolean BG_LegalizedForcePowers(char *powerOut, int maxRank, qboolean freeSaber
|
|||
final_Powers[FP_LEVITATION] = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
if (fpDisabled)
|
||||
i = 0;
|
||||
while (i < NUM_FORCE_POWERS)
|
||||
{
|
||||
final_Powers[FP_LEVITATION] = 1;
|
||||
final_Powers[FP_SABERATTACK] = 3;
|
||||
final_Powers[FP_SABERDEFEND] = 3;
|
||||
final_Powers[FP_SABERTHROW] = 0;
|
||||
if (final_Powers[i] > FORCE_LEVEL_3)
|
||||
{
|
||||
final_Powers[i] = FORCE_LEVEL_3;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
*/
|
||||
//Ahh. I have no idea why I did this, but I would say that it makes me a very bad man.
|
||||
|
||||
if (fpDisabled)
|
||||
{ //If we specifically have attack or def disabled, force them up to level 3. It's the way
|
||||
//things work for the case of all powers disabled.
|
||||
|
@ -1303,7 +1308,7 @@ qboolean BG_CanUseFPNow(int gametype, playerState_t *ps, int time, forcePowers_t
|
|||
|
||||
if (ps->duelInProgress)
|
||||
{
|
||||
if (power != FP_SABERATTACK && power != FP_SABERDEFEND && power != FP_SABERTHROW &&
|
||||
if (power != FP_SABERATTACK && power != FP_SABERDEFEND && /*power != FP_SABERTHROW &&*/
|
||||
power != FP_LEVITATION)
|
||||
{
|
||||
if (!ps->saberLockFrame || power != FP_PUSH)
|
||||
|
@ -1466,68 +1471,68 @@ void BG_CycleForce(playerState_t *ps, int direction)
|
|||
presel = x;
|
||||
|
||||
if (direction == 1)
|
||||
{
|
||||
{ //get the next power
|
||||
x++;
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //get the previous power
|
||||
x--;
|
||||
}
|
||||
|
||||
if (x >= NUM_FORCE_POWERS)
|
||||
{
|
||||
{ //cycled off the end.. cycle around to the first
|
||||
x = 0;
|
||||
}
|
||||
if (x < 0)
|
||||
{
|
||||
{ //cycled off the beginning.. cycle around to the last
|
||||
x = NUM_FORCE_POWERS-1;
|
||||
}
|
||||
|
||||
i = forcePowerSorted[x];
|
||||
i = forcePowerSorted[x]; //the "sorted" value of this power
|
||||
|
||||
while (x != presel)
|
||||
{
|
||||
{ //loop around to the current force power
|
||||
if (ps->fd.forcePowersKnown & (1 << i) && i != ps->fd.forcePowerSelected)
|
||||
{
|
||||
{ //we have the force power
|
||||
if (i != FP_LEVITATION &&
|
||||
i != FP_SABERATTACK &&
|
||||
i != FP_SABERDEFEND &&
|
||||
i != FP_SABERTHROW)
|
||||
{
|
||||
{ //it's selectable
|
||||
foundnext = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (direction == 1)
|
||||
{
|
||||
{ //next
|
||||
x++;
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //previous
|
||||
x--;
|
||||
}
|
||||
|
||||
if (x >= NUM_FORCE_POWERS)
|
||||
{
|
||||
{ //loop around
|
||||
x = 0;
|
||||
}
|
||||
if (x < 0)
|
||||
{
|
||||
{ //loop around
|
||||
x = NUM_FORCE_POWERS-1;
|
||||
}
|
||||
|
||||
i = forcePowerSorted[x];
|
||||
i = forcePowerSorted[x]; //set to the sorted value again
|
||||
}
|
||||
|
||||
if (foundnext != -1)
|
||||
{
|
||||
{ //found one, select it
|
||||
ps->fd.forcePowerSelected = foundnext;
|
||||
}
|
||||
}
|
||||
|
||||
int BG_GetItemIndexByTag(int tag, int type)
|
||||
{
|
||||
{ //Get the itemlist index from the tag and type
|
||||
int i = 0;
|
||||
|
||||
while (i < bg_numItems)
|
||||
|
@ -1553,37 +1558,37 @@ void BG_CycleInven(playerState_t *ps, int direction)
|
|||
original = i;
|
||||
|
||||
if (direction == 1)
|
||||
{
|
||||
{ //next
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //previous
|
||||
i--;
|
||||
}
|
||||
|
||||
while (i != original)
|
||||
{ //go in a full loop until hitting something, if hit nothing then select nothing
|
||||
if (ps->stats[STAT_HOLDABLE_ITEMS] & (1 << i))
|
||||
{
|
||||
{ //we have it, select it.
|
||||
ps->stats[STAT_HOLDABLE_ITEM] = BG_GetItemIndexByTag(i, IT_HOLDABLE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (direction == 1)
|
||||
{
|
||||
{ //next
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //previous
|
||||
i--;
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
{ //wrap around to the last
|
||||
i = HI_NUM_HOLDABLE;
|
||||
}
|
||||
else if (i >= HI_NUM_HOLDABLE)
|
||||
{
|
||||
{ //wrap around to the first
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
@ -2039,7 +2044,6 @@ void BG_TouchJumpPad( playerState_t *ps, entityState_t *jumppad ) {
|
|||
} else {
|
||||
effectNum = 1;
|
||||
}
|
||||
//BG_AddPredictableEventToPlayerstate( EV_JUMP_PAD, effectNum, ps );
|
||||
}
|
||||
// remember hitting this jumppad this frame
|
||||
ps->jumppad_ent = jumppad->number;
|
||||
|
@ -2333,179 +2337,6 @@ PLAYER ANGLES
|
|||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
==================
|
||||
BG_SwingAngles
|
||||
==================
|
||||
*/
|
||||
static void BG_SwingAngles( float destination, float swingTolerance, float clampTolerance,
|
||||
float speed, float *angle, qboolean *swinging, int frameTime ) {
|
||||
float swing;
|
||||
float move;
|
||||
float scale;
|
||||
|
||||
if ( !*swinging ) {
|
||||
// see if a swing should be started
|
||||
swing = AngleSubtract( *angle, destination );
|
||||
if ( swing > swingTolerance || swing < -swingTolerance ) {
|
||||
*swinging = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !*swinging ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// modify the speed depending on the delta
|
||||
// so it doesn't seem so linear
|
||||
swing = AngleSubtract( destination, *angle );
|
||||
scale = fabs( swing );
|
||||
if ( scale < swingTolerance * 0.5 ) {
|
||||
scale = 0.5;
|
||||
} else if ( scale < swingTolerance ) {
|
||||
scale = 1.0;
|
||||
} else {
|
||||
scale = 2.0;
|
||||
}
|
||||
|
||||
// swing towards the destination angle
|
||||
if ( swing >= 0 ) {
|
||||
move = frameTime * scale * speed;
|
||||
if ( move >= swing ) {
|
||||
move = swing;
|
||||
*swinging = qfalse;
|
||||
}
|
||||
*angle = AngleMod( *angle + move );
|
||||
} else if ( swing < 0 ) {
|
||||
move = frameTime * scale * -speed;
|
||||
if ( move <= swing ) {
|
||||
move = swing;
|
||||
*swinging = qfalse;
|
||||
}
|
||||
*angle = AngleMod( *angle + move );
|
||||
}
|
||||
|
||||
// clamp to no more than tolerance
|
||||
swing = AngleSubtract( destination, *angle );
|
||||
if ( swing > clampTolerance ) {
|
||||
*angle = AngleMod( destination - (clampTolerance - 1) );
|
||||
} else if ( swing < -clampTolerance ) {
|
||||
*angle = AngleMod( destination + (clampTolerance - 1) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_AddPainTwitch
|
||||
=================
|
||||
*/
|
||||
#define PAIN_TWITCH_TIME 200
|
||||
static void BG_AddPainTwitch( int painTime, int painDirection, int currentTime, vec3_t torsoAngles ) {
|
||||
int t;
|
||||
float f;
|
||||
|
||||
t = currentTime - painTime;
|
||||
if ( t >= PAIN_TWITCH_TIME ) {
|
||||
return;
|
||||
}
|
||||
|
||||
f = 1.0 - (float)t / PAIN_TWITCH_TIME;
|
||||
|
||||
if ( painDirection ) {
|
||||
torsoAngles[ROLL] += 20 * f;
|
||||
} else {
|
||||
torsoAngles[ROLL] -= 20 * f;
|
||||
}
|
||||
}
|
||||
|
||||
void BG_G2PlayerAngles( vec3_t startAngles, vec3_t legs[3], vec3_t legsAngles, int painTime, int painDirection, int currentTime,
|
||||
qboolean *torso_yawing, float *torso_yawAngle, qboolean *torso_pitching, float *torso_pitchAngle, qboolean *legs_yawing, float *legs_yawAngle,
|
||||
int frameTime, vec3_t velocity, int legsAnim, int torsoAnim, qboolean dead, float movementDir, void *ghoul2, qhandle_t *modelList, int weapon){
|
||||
vec3_t torsoAngles, headAngles;
|
||||
float dest;
|
||||
static int movementOffsets[8] = { 0, 22, 45, -22, 0, 22, -45, -22 };
|
||||
float speed;
|
||||
int dir;
|
||||
|
||||
VectorCopy( startAngles, headAngles );
|
||||
headAngles[YAW] = AngleMod( headAngles[YAW] );
|
||||
VectorClear( legsAngles );
|
||||
VectorClear( torsoAngles );
|
||||
|
||||
// --------- yaw -------------
|
||||
|
||||
// allow yaw to drift a bit
|
||||
if ( ( legsAnim & ~ANIM_TOGGLEBIT ) != WeaponReadyAnim[weapon]
|
||||
|| ( torsoAnim & ~ANIM_TOGGLEBIT ) != WeaponReadyAnim[weapon] ) {
|
||||
// if not standing still, always point all in the same direction
|
||||
*torso_yawing = qtrue; // always center
|
||||
*torso_pitching = qtrue; // always center
|
||||
*legs_yawing = qtrue; // always center
|
||||
}
|
||||
|
||||
// adjust legs for movement dir
|
||||
if (dead ) {
|
||||
// don't let dead bodies twitch
|
||||
dir = 0;
|
||||
} else {
|
||||
dir = movementDir;
|
||||
// if ( dir < 0 || dir > 7 ) {
|
||||
// CG_Error( "Bad player movement angle" );
|
||||
// }
|
||||
}
|
||||
legsAngles[YAW] = headAngles[YAW] + movementOffsets[ dir ];
|
||||
torsoAngles[YAW] = headAngles[YAW] + 0.25 * movementOffsets[ dir ];
|
||||
|
||||
// torso
|
||||
BG_SwingAngles( torsoAngles[YAW], 25, 90, /*cg_swingSpeed.value*/ 0.3, torso_yawAngle, torso_yawing, frameTime );
|
||||
BG_SwingAngles( legsAngles[YAW], 40, 90, /*cg_swingSpeed.value*/ 0.3, legs_yawAngle, legs_yawing, frameTime );
|
||||
|
||||
torsoAngles[YAW] = *torso_yawAngle;
|
||||
legsAngles[YAW] = *legs_yawAngle;
|
||||
|
||||
// --------- pitch -------------
|
||||
|
||||
// only show a fraction of the pitch angle in the torso
|
||||
if ( headAngles[PITCH] > 180 ) {
|
||||
dest = (-360 + headAngles[PITCH]) * 0.75;
|
||||
} else {
|
||||
dest = headAngles[PITCH] * 0.75;
|
||||
}
|
||||
BG_SwingAngles( dest, 15, 30, 0.1, torso_pitchAngle, torso_pitching, frameTime );
|
||||
torsoAngles[PITCH] = *torso_pitchAngle;
|
||||
|
||||
// --------- roll -------------
|
||||
|
||||
// lean towards the direction of travel
|
||||
speed = VectorNormalize( velocity );
|
||||
if ( speed ) {
|
||||
vec3_t axis[3];
|
||||
float side;
|
||||
|
||||
speed *= 0.05;
|
||||
|
||||
AnglesToAxis( legsAngles, axis );
|
||||
side = speed * DotProduct( velocity, axis[1] );
|
||||
legsAngles[ROLL] -= side;
|
||||
|
||||
side = speed * DotProduct( velocity, axis[0] );
|
||||
legsAngles[PITCH] += side;
|
||||
}
|
||||
|
||||
// pain twitch
|
||||
BG_AddPainTwitch( painTime, painDirection, currentTime, torsoAngles );
|
||||
|
||||
// pull the angles back out of the hierarchial chain
|
||||
AnglesSubtract( headAngles, torsoAngles, headAngles );
|
||||
AnglesSubtract( torsoAngles, legsAngles, torsoAngles );
|
||||
AnglesToAxis( legsAngles, legs );
|
||||
// we assume that model 0 is the player model.
|
||||
//g2r trap_G2API_SetBoneAngles(ghoul2, 0, "upper_lumbar", torsoAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, modelList, 0, currentTime);
|
||||
//g2r trap_G2API_SetBoneAngles(ghoul2, 0, "cranium", headAngles, BONE_ANGLES_POSTMULT, POSITIVE_Z, NEGATIVE_Y, POSITIVE_X, modelList,0, currentTime);
|
||||
|
||||
}
|
||||
|
||||
#define MAX_POOL_SIZE 2048000 //1024000
|
||||
|
||||
static char bg_pool[MAX_POOL_SIZE];
|
||||
|
|
|
@ -1077,15 +1077,13 @@ void PM_SetAnimFinal(int setAnimParts,int anim,int setAnimFlags,
|
|||
PM_StartTorsoAnim( anim );
|
||||
|
||||
if (setAnimFlags & SETANIM_FLAG_HOLD)
|
||||
{//FIXME: allow to set a specific time?
|
||||
{
|
||||
if (setAnimFlags & SETANIM_FLAG_HOLDLESS)
|
||||
{ // Make sure to only wait in full 1/20 sec server frame intervals.
|
||||
int dur;
|
||||
int speedDif;
|
||||
|
||||
dur = (animations[anim].numFrames-1) * fabs(animations[anim].frameLerp);
|
||||
//dur = ((int)(dur/50.0)) * 50 / timeScaleMod;
|
||||
//dur -= blendTime+fabs(animations[anim].frameLerp)*2;
|
||||
speedDif = dur - (dur * editAnimSpeed);
|
||||
dur += speedDif;
|
||||
if (dur > 1)
|
||||
|
@ -1127,15 +1125,13 @@ setAnimLegs:
|
|||
PM_StartLegsAnim(anim);
|
||||
|
||||
if (setAnimFlags & SETANIM_FLAG_HOLD)
|
||||
{//FIXME: allow to set a specific time?
|
||||
{
|
||||
if (setAnimFlags & SETANIM_FLAG_HOLDLESS)
|
||||
{ // Make sure to only wait in full 1/20 sec server frame intervals.
|
||||
int dur;
|
||||
int speedDif;
|
||||
|
||||
dur = (animations[anim].numFrames-1) * fabs(animations[anim].frameLerp);
|
||||
//dur = ((int)(dur/50.0)) * 50 / timeScaleMod;
|
||||
//dur -= blendTime+fabs(animations[anim].frameLerp)*2;
|
||||
speedDif = dur - (dur * editAnimSpeed);
|
||||
dur += speedDif;
|
||||
if (dur > 1)
|
||||
|
@ -1152,11 +1148,6 @@ setAnimLegs:
|
|||
pm->ps->legsTimer = ((animations[anim].numFrames ) * fabs(animations[anim].frameLerp));
|
||||
}
|
||||
|
||||
/*
|
||||
PM_DebugLegsAnim(anim);
|
||||
Com_Printf("%i\n", pm->ps->legsTimer);
|
||||
*/
|
||||
|
||||
if (pm->ps->fd.forcePowersActive & (1 << FP_RAGE))
|
||||
{
|
||||
pm->ps->legsTimer /= 1.3;
|
||||
|
@ -1186,8 +1177,7 @@ void PM_SetAnim(int setAnimParts,int anim,int setAnimFlags, int blendTime)
|
|||
}
|
||||
|
||||
if (BG_InRoll(pm->ps, pm->ps->legsAnim))
|
||||
{
|
||||
//setAnimFlags |= SETANIM_FLAG_RESTART;
|
||||
{ //never interrupt a roll
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -467,7 +467,7 @@ qboolean PM_ForceJumpingUp(void)
|
|||
}
|
||||
|
||||
if ( pm->ps->groundEntityNum == ENTITYNUM_NONE && //in air
|
||||
(pm->ps->pm_flags & PMF_JUMP_HELD) &&//forceJumpZStart && //jumped
|
||||
(pm->ps->pm_flags & PMF_JUMP_HELD) && //jumped
|
||||
pm->ps->fd.forcePowerLevel[FP_LEVITATION] > FORCE_LEVEL_0 && //force-jump capable
|
||||
pm->ps->velocity[2] > 0 )//going up
|
||||
{
|
||||
|
@ -506,7 +506,7 @@ static void PM_JumpForDir( void )
|
|||
}
|
||||
if(!BG_InDeathAnim(pm->ps->legsAnim))
|
||||
{
|
||||
PM_SetAnim(SETANIM_LEGS,anim,SETANIM_FLAG_OVERRIDE, 100); // Only blend over 100ms
|
||||
PM_SetAnim(SETANIM_LEGS,anim,SETANIM_FLAG_OVERRIDE, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,14 +514,13 @@ void PM_SetPMViewAngle(playerState_t *ps, vec3_t angle, usercmd_t *ucmd)
|
|||
{
|
||||
int i;
|
||||
|
||||
// set the delta angle
|
||||
for (i=0 ; i<3 ; i++) {
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{ // set the delta angle
|
||||
int cmdAngle;
|
||||
|
||||
cmdAngle = ANGLE2SHORT(angle[i]);
|
||||
ps->delta_angles[i] = cmdAngle - ucmd->angles[i];
|
||||
}
|
||||
//VectorCopy( angle, ent->s.angles );
|
||||
VectorCopy (angle, ps->viewangles);
|
||||
}
|
||||
|
||||
|
@ -555,8 +554,6 @@ qboolean PM_AdjustAngleForWallRun( playerState_t *ps, usercmd_t *ucmd, qboolean
|
|||
|
||||
if ( trace.fraction < 1.0f )
|
||||
{//still a wall there
|
||||
//FIXME: don't pull around 90 turns
|
||||
//FIXME: simulate stepping up steps here, somehow?
|
||||
if ( (ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_RIGHT )
|
||||
{
|
||||
ucmd->rightmove = 127;
|
||||
|
@ -572,7 +569,6 @@ qboolean PM_AdjustAngleForWallRun( playerState_t *ps, usercmd_t *ucmd, qboolean
|
|||
//make me face perpendicular to the wall
|
||||
ps->viewangles[YAW] = vectoyaw( trace.plane.normal )+yawAdjust;
|
||||
|
||||
//SetClientViewAngle( ent, ent->client->ps.viewangles );
|
||||
PM_SetPMViewAngle(ps, ps->viewangles, ucmd);
|
||||
|
||||
ucmd->angles[YAW] = ANGLE2SHORT( ps->viewangles[YAW] ) - ps->delta_angles[YAW];
|
||||
|
@ -587,7 +583,7 @@ qboolean PM_AdjustAngleForWallRun( playerState_t *ps, usercmd_t *ucmd, qboolean
|
|||
|
||||
fwdAngles[YAW] = ps->viewangles[YAW];
|
||||
AngleVectors( fwdAngles, fwd, NULL, NULL );
|
||||
//FIXME: or MA?
|
||||
|
||||
if ( ucmd->forwardmove < 0 )
|
||||
{//slower
|
||||
speed = 100;
|
||||
|
@ -621,12 +617,21 @@ qboolean PM_AdjustAngleForWallRun( playerState_t *ps, usercmd_t *ucmd, qboolean
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
//Set the height for when a force jump was started. If it's 0, nuge it up (slight hack to prevent holding jump over slopes)
|
||||
void PM_SetForceJumpZStart(float value)
|
||||
{
|
||||
pm->ps->fd.forceJumpZStart = value;
|
||||
if (!pm->ps->fd.forceJumpZStart)
|
||||
{
|
||||
pm->ps->fd.forceJumpZStart -= 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
PM_CheckJump
|
||||
=============
|
||||
*/
|
||||
|
||||
static qboolean PM_CheckJump( void )
|
||||
{
|
||||
if (pm->ps->usingATST)
|
||||
|
@ -653,15 +658,9 @@ static qboolean PM_CheckJump( void )
|
|||
{
|
||||
pm->ps->fd.forcePowersActive &= ~(1<<FP_LEVITATION);
|
||||
}
|
||||
/*
|
||||
if ( pm->cmd.buttons & BUTTON_FORCEJUMP )
|
||||
{
|
||||
pm->ps->pm_flags |= PMF_JUMP_HELD;
|
||||
}
|
||||
*/
|
||||
|
||||
if (pm->ps->fd.forcePowersActive & (1 << FP_LEVITATION))
|
||||
{
|
||||
{ //Force jump is already active.. continue draining power appropriately until we land.
|
||||
if (pm->ps->fd.forcePowerDebounce[FP_LEVITATION] < pm->cmd.serverTime)
|
||||
{
|
||||
BG_ForcePowerDrain( pm->ps, FP_LEVITATION, 5 );
|
||||
|
@ -677,7 +676,7 @@ static qboolean PM_CheckJump( void )
|
|||
}
|
||||
|
||||
if (pm->ps->forceJumpFlip)
|
||||
{
|
||||
{ //Forced jump anim
|
||||
int anim = BOTH_FORCEINAIR1;
|
||||
int parts = SETANIM_BOTH;
|
||||
|
||||
|
@ -711,18 +710,15 @@ static qboolean PM_CheckJump( void )
|
|||
{
|
||||
if ( pm->ps->gravity > 0 )
|
||||
{//can't do this in zero-G
|
||||
//FIXME: still able to pogo-jump...
|
||||
if ( PM_ForceJumpingUp() )
|
||||
{//holding jump in air
|
||||
float curHeight = pm->ps->origin[2] - pm->ps->fd.forceJumpZStart;
|
||||
//check for max force jump level and cap off & cut z vel
|
||||
if ( ( curHeight<=forceJumpHeight[0] ||//still below minimum jump height
|
||||
(pm->ps->fd.forcePower&&pm->cmd.upmove>=10) ) &&////still have force power available and still trying to jump up
|
||||
curHeight < forceJumpHeight[pm->ps->fd.forcePowerLevel[FP_LEVITATION]] )//still below maximum jump height
|
||||
curHeight < forceJumpHeight[pm->ps->fd.forcePowerLevel[FP_LEVITATION]] &&
|
||||
pm->ps->fd.forceJumpZStart)//still below maximum jump height
|
||||
{//can still go up
|
||||
//FIXME: after a certain amount of time of held jump, play force jump sound and flip if a dir is being held
|
||||
//FIXME: if hit a wall... should we cut velocity or allow them to slide up it?
|
||||
//FIXME: constantly drain force power at a rate by which the usage for maximum height would use up the full cost of force jump
|
||||
if ( curHeight > forceJumpHeight[0] )
|
||||
{//passed normal jump height *2?
|
||||
if ( !(pm->ps->fd.forcePowersActive&(1<<FP_LEVITATION)) )//haven't started forcejump yet
|
||||
|
@ -731,13 +727,12 @@ static qboolean PM_CheckJump( void )
|
|||
pm->ps->fd.forcePowersActive |= (1<<FP_LEVITATION);
|
||||
pm->ps->fd.forceJumpSound = 1;
|
||||
//play flip
|
||||
//FIXME: do this only when they stop the jump (below) or when they're just about to hit the peak of the jump
|
||||
if ((pm->cmd.forwardmove || pm->cmd.rightmove) && //pushing in a dir
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) != BOTH_FLIP_F &&//not already flipping
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) != BOTH_FLIP_B &&
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) != BOTH_FLIP_R &&
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) != BOTH_FLIP_L )
|
||||
{//FIXME: this could end up playing twice if the jump is very long...
|
||||
{
|
||||
int anim = BOTH_FORCEINAIR1;
|
||||
int parts = SETANIM_BOTH;
|
||||
|
||||
|
@ -758,15 +753,15 @@ static qboolean PM_CheckJump( void )
|
|||
anim = BOTH_FLIP_L;
|
||||
}
|
||||
if ( pm->ps->weaponTime )
|
||||
{//FIXME: really only care if we're in a saber attack anim...
|
||||
{
|
||||
parts = SETANIM_LEGS;
|
||||
}
|
||||
|
||||
PM_SetAnim( parts, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 150 );
|
||||
}
|
||||
else if ( pm->ps->fd.forcePowerLevel[FP_LEVITATION] > FORCE_LEVEL_1 )
|
||||
{//FIXME: really want to know how far off ground we are, probably...
|
||||
vec3_t facingFwd, facingRight, facingAngles;// = {0, pm->ps->viewangles[YAW], 0};
|
||||
{
|
||||
vec3_t facingFwd, facingRight, facingAngles;
|
||||
int anim = -1;
|
||||
float dotR, dotF;
|
||||
|
||||
|
@ -811,7 +806,7 @@ static qboolean PM_CheckJump( void )
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //jump is already active (the anim has started)
|
||||
if ( pm->ps->legsTimer < 1 )
|
||||
{//not in the middle of a legsAnim
|
||||
int anim = (pm->ps->legsAnim&~ANIM_TOGGLEBIT);
|
||||
|
@ -835,7 +830,7 @@ static qboolean PM_CheckJump( void )
|
|||
{
|
||||
int parts = SETANIM_BOTH;
|
||||
if ( pm->ps->weaponTime )
|
||||
{//FIXME: really only care if we're in a saber attack anim...
|
||||
{
|
||||
parts = SETANIM_LEGS;
|
||||
}
|
||||
|
||||
|
@ -871,16 +866,6 @@ static qboolean PM_CheckJump( void )
|
|||
pm->cmd.upmove = 0;
|
||||
return qfalse;
|
||||
}
|
||||
/*
|
||||
else if ( pm->ps->groundEntityNum == ENTITYNUM_NONE )
|
||||
{
|
||||
int legsAnim = (pm->ps->legsAnim&~ANIM_TOGGLEBIT);
|
||||
if ( legsAnim != BOTH_WALL_RUN_LEFT && legsAnim != BOTH_WALL_RUN_RIGHT )
|
||||
{//special case.. these let you jump off a wall
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -911,19 +896,16 @@ static qboolean PM_CheckJump( void )
|
|||
if ( trace.fraction <= 1.0f )
|
||||
{
|
||||
VectorMA( pm->ps->velocity, JUMP_VELOCITY*2, forward, pm->ps->velocity );
|
||||
//FIXME: kicking off wall anim? At least check what anim we're in?
|
||||
PM_SetAnim(SETANIM_LEGS,BOTH_FORCEJUMP1,SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART, 150);
|
||||
}//else no surf close enough to push off of
|
||||
pm->cmd.upmove = 0;
|
||||
}
|
||||
else if ( pm->cmd.upmove > 0 && pm->waterlevel < 2 &&
|
||||
pm->ps->fd.forcePowerLevel[FP_LEVITATION] > FORCE_LEVEL_0 &&
|
||||
!(pm->ps->pm_flags&PMF_JUMP_HELD) /*&&
|
||||
WP_ForcePowerAvailable( pm->gent, FP_LEVITATION, 0 ) */ &&
|
||||
!(pm->ps->pm_flags&PMF_JUMP_HELD) &&
|
||||
pm->ps->weapon == WP_SABER &&
|
||||
!BG_HasYsalamiri(pm->gametype, pm->ps) &&
|
||||
BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_LEVITATION)
|
||||
)
|
||||
BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_LEVITATION) )
|
||||
{
|
||||
if ( pm->ps->groundEntityNum != ENTITYNUM_NONE )
|
||||
{//on the ground
|
||||
|
@ -956,39 +938,21 @@ static qboolean PM_CheckJump( void )
|
|||
anim = BOTH_WALL_FLIP_LEFT;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if ( pm->cmd.forwardmove > 0 && pm->ps->fd.forcePowerLevel[FP_LEVITATION] > FORCE_LEVEL_1 )
|
||||
{//run up wall, flip backwards
|
||||
vertPush = forceJumpStrength[FORCE_LEVEL_2]/2.25f;
|
||||
anim = BOTH_WALL_FLIP_BACK1;
|
||||
}
|
||||
*/
|
||||
else if ( pm->cmd.forwardmove < 0 && !(pm->cmd.buttons&BUTTON_ATTACK) )
|
||||
{//backflip
|
||||
vertPush = JUMP_VELOCITY;
|
||||
anim = BOTH_FLIP_BACK1;//PM_PickAnim( BOTH_FLIP_BACK1, BOTH_FLIP_BACK3 );
|
||||
}
|
||||
/*
|
||||
else if ( VectorLengthSquared( pm->ps->velocity ) < 256 )
|
||||
{//not moving
|
||||
if ( pm->ps->weapon == WP_SABER && (pm->cmd.buttons & BUTTON_ATTACK) && pm->ps->fd.saberAnimLevel == FORCE_LEVEL_2 )
|
||||
{//butterfly... FIXME: does direction matter?
|
||||
vertPush = JUMP_VELOCITY;
|
||||
anim = BOTH_BUTTERFLY_LEFT;
|
||||
}
|
||||
}
|
||||
*/
|
||||
//FIXME: Do we want special moves in MP?
|
||||
|
||||
vertPush += 128; //is gravity different in SP or something?
|
||||
vertPush += 128; //give them an extra shove
|
||||
|
||||
if ( anim != -1 /*&& PM_HasAnimation( pm->gent, anim )*/ )
|
||||
if ( anim != -1 )
|
||||
{
|
||||
vec3_t fwd, right, traceto, mins, maxs, fwdAngles;
|
||||
vec3_t idealNormal;
|
||||
trace_t trace;
|
||||
qboolean doTrace = qfalse;
|
||||
int contents = /*CONTENTS_SOLID*/MASK_PLAYERSOLID;
|
||||
int contents = MASK_PLAYERSOLID;
|
||||
|
||||
VectorSet(mins, pm->mins[0],pm->mins[1],0);
|
||||
VectorSet(maxs, pm->maxs[0],pm->maxs[1],24);
|
||||
|
@ -1002,7 +966,6 @@ static qboolean PM_CheckJump( void )
|
|||
switch ( anim )
|
||||
{
|
||||
case BOTH_WALL_FLIP_LEFT:
|
||||
//contents |= CONTENTS_BODY;
|
||||
//NOTE: purposely falls through to next case!
|
||||
case BOTH_WALL_RUN_LEFT:
|
||||
doTrace = qtrue;
|
||||
|
@ -1010,7 +973,6 @@ static qboolean PM_CheckJump( void )
|
|||
break;
|
||||
|
||||
case BOTH_WALL_FLIP_RIGHT:
|
||||
//contents |= CONTENTS_BODY;
|
||||
//NOTE: purposely falls through to next case!
|
||||
case BOTH_WALL_RUN_RIGHT:
|
||||
doTrace = qtrue;
|
||||
|
@ -1018,7 +980,6 @@ static qboolean PM_CheckJump( void )
|
|||
break;
|
||||
|
||||
case BOTH_WALL_FLIP_BACK1:
|
||||
//contents |= CONTENTS_BODY;
|
||||
doTrace = qtrue;
|
||||
VectorMA( pm->ps->origin, 16, fwd, traceto );
|
||||
break;
|
||||
|
@ -1030,11 +991,9 @@ static qboolean PM_CheckJump( void )
|
|||
VectorSubtract( pm->ps->origin, traceto, idealNormal );
|
||||
VectorNormalize( idealNormal );
|
||||
}
|
||||
// gentity_t *traceEnt = &g_entities[trace.entityNum];
|
||||
|
||||
//if ( !doTrace || (trace.fraction < 1.0f&&((trace.entityNum<ENTITYNUM_WORLD&&traceEnt&&traceEnt->s.solid!=SOLID_BMODEL)||DotProduct(trace.plane.normal,idealNormal)>0.7)) )
|
||||
|
||||
if ( !doTrace || (trace.fraction < 1.0f && (trace.entityNum < MAX_CLIENTS || DotProduct(trace.plane.normal,idealNormal) > 0.7)) )
|
||||
{//there is a wall there
|
||||
{//there is a wall there.. or hit a client
|
||||
int parts;
|
||||
//move me to side
|
||||
if ( anim == BOTH_WALL_FLIP_LEFT )
|
||||
|
@ -1055,26 +1014,7 @@ static qboolean PM_CheckJump( void )
|
|||
pm->ps->velocity[0] = pm->ps->velocity[1] = 0;
|
||||
VectorMA( pm->ps->velocity, -150, fwd, pm->ps->velocity );
|
||||
}
|
||||
//kick if jumping off an ent
|
||||
/*
|
||||
if ( doTrace && anim != BOTH_WALL_RUN_LEFT && anim != BOTH_WALL_RUN_RIGHT )
|
||||
{
|
||||
if ( pm->gent && trace.entityNum < ENTITYNUM_WORLD )
|
||||
{
|
||||
if ( traceEnt && traceEnt->client && traceEnt->health && traceEnt->takedamage )
|
||||
{//push them away and do pain
|
||||
vec3_t oppDir;
|
||||
float strength = VectorNormalize2( pm->ps->velocity, oppDir );
|
||||
VectorScale( oppDir, -1, oppDir );
|
||||
//FIXME: need knockdown anim
|
||||
G_Damage( traceEnt, pm->gent, pm->gent, oppDir, traceEnt->currentOrigin, 10, DAMAGE_NO_ARMOR|DAMAGE_NO_HIT_LOC|DAMAGE_NO_KNOCKBACK, MOD_MELEE );
|
||||
NPC_SetAnim( traceEnt, SETANIM_BOTH, BOTH_KNOCKDOWN1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
|
||||
G_Throw( traceEnt, oppDir, strength );
|
||||
G_Sound( traceEnt, G_SoundIndex( va("sound/weapons/melee/punch%d", Q_irand(1, 4)) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if ( doTrace && anim != BOTH_WALL_RUN_LEFT && anim != BOTH_WALL_RUN_RIGHT )
|
||||
{
|
||||
if (trace.entityNum < MAX_CLIENTS)
|
||||
|
@ -1083,8 +1023,6 @@ static qboolean PM_CheckJump( void )
|
|||
}
|
||||
}
|
||||
|
||||
//FIXMEFIXME
|
||||
|
||||
//up
|
||||
if ( vertPush )
|
||||
{
|
||||
|
@ -1108,10 +1046,9 @@ static qboolean PM_CheckJump( void )
|
|||
{
|
||||
pm->ps->weaponTime = pm->ps->torsoTimer;
|
||||
}
|
||||
pm->ps->fd.forceJumpZStart = pm->ps->origin[2];//so we don't take damage if we land at same height
|
||||
pm->ps->pm_flags |= PMF_JUMP_HELD;//PMF_JUMPING|PMF_SLOW_MO_FALL;
|
||||
PM_SetForceJumpZStart(pm->ps->origin[2]);//so we don't take damage if we land at same height
|
||||
pm->ps->pm_flags |= PMF_JUMP_HELD;
|
||||
pm->cmd.upmove = 0;
|
||||
//WP_ForcePowerDrain( pm->gent, FP_LEVITATION, 0 );
|
||||
pm->ps->fd.forceJumpSound = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1180,8 +1117,6 @@ static qboolean PM_CheckJump( void )
|
|||
parts = SETANIM_BOTH;
|
||||
}
|
||||
PM_SetAnim( parts, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 );
|
||||
//FIXME: do damage to traceEnt, like above?
|
||||
//pm->ps->pm_flags |= PMF_JUMPING|PMF_SLOW_MO_FALL;
|
||||
pm->cmd.upmove = 0;
|
||||
}
|
||||
}
|
||||
|
@ -1193,10 +1128,9 @@ static qboolean PM_CheckJump( void )
|
|||
else if ( pm->cmd.forwardmove > 0 //pushing forward
|
||||
&& pm->ps->fd.forcePowerLevel[FP_LEVITATION] > FORCE_LEVEL_1
|
||||
&& pm->ps->velocity[2] > 200
|
||||
&& /*(level.time - pm->ps->lastOnGround) <= 500*/ PM_GroundDistance() <= 80 //unfortunately we do not have a happy ground timer.
|
||||
&& PM_GroundDistance() <= 80 //unfortunately we do not have a happy ground timer like SP (this would use up more bandwidth if we wanted prediction workign right), so we'll just use the actual ground distance.
|
||||
&& !BG_InSpecialJump(pm->ps->legsAnim))
|
||||
{//run up wall, flip backwards
|
||||
//FIXME: have to be moving... make sure it's opposite the wall... or at least forward?
|
||||
vec3_t fwd, traceto, mins, maxs, fwdAngles;
|
||||
trace_t trace;
|
||||
vec3_t idealNormal;
|
||||
|
@ -1229,10 +1163,8 @@ static qboolean PM_CheckJump( void )
|
|||
pm->ps->legsTimer -= 600; //I force this anim to play to the end to prevent landing on your head and suddenly flipping over.
|
||||
//It is a bit too long at the end though, so I'll just shorten it.
|
||||
|
||||
pm->ps->fd.forceJumpZStart = pm->ps->origin[2];//so we don't take damage if we land at same height
|
||||
//pm->ps->pm_flags |= PMF_JUMPING|PMF_SLOW_MO_FALL;
|
||||
PM_SetForceJumpZStart(pm->ps->origin[2]);//so we don't take damage if we land at same height
|
||||
pm->cmd.upmove = 0;
|
||||
//G_SoundOnEnt( pm->gent, CHAN_BODY, "sound/weapons/force/jump.wav" );
|
||||
pm->ps->fd.forceJumpSound = 1;
|
||||
BG_ForcePowerDrain( pm->ps, FP_LEVITATION, 5 );
|
||||
|
||||
|
@ -1242,10 +1174,6 @@ static qboolean PM_CheckJump( void )
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//FIXME: if in a butterfly, kick people away?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1259,8 +1187,7 @@ static qboolean PM_CheckJump( void )
|
|||
&& !BG_FlippingAnim( pm->ps->legsAnim )
|
||||
&& !PM_SpinningAnim( pm->ps->legsAnim )
|
||||
&& !BG_SaberInSpecialAttack( pm->ps->torsoAnim )
|
||||
&& ( BG_SaberInAttack( pm->ps->saberMove ) )
|
||||
/*&& PM_InAnimForSaberMove( pm->ps->torsoAnim, pm->ps->saberMove )*/ )
|
||||
&& ( BG_SaberInAttack( pm->ps->saberMove ) ) )
|
||||
{//not in an anim we shouldn't interrupt
|
||||
//see if it's not too late to start a special jump-attack
|
||||
float animLength = PM_AnimLength( 0, (animNumber_t)pm->ps->torsoAnim );
|
||||
|
@ -1269,8 +1196,7 @@ static qboolean PM_CheckJump( void )
|
|||
//check for special-case jump attacks
|
||||
if ( pm->ps->fd.saberAnimLevel == FORCE_LEVEL_2 )
|
||||
{//using medium attacks
|
||||
if (/*pm->ps->velocity[2] > 100 &&*/
|
||||
PM_GroundDistance() < 32 &&
|
||||
if (PM_GroundDistance() < 32 &&
|
||||
!BG_InSpecialJump(pm->ps->legsAnim))
|
||||
{ //FLIP AND DOWNWARD ATTACK
|
||||
trace_t tr;
|
||||
|
@ -1314,17 +1240,9 @@ static qboolean PM_CheckJump( void )
|
|||
}
|
||||
if ( pm->cmd.upmove > 0 )
|
||||
{//no special jumps
|
||||
/*
|
||||
gentity_t *groundEnt = &g_entities[pm->ps->groundEntityNum];
|
||||
if ( groundEnt && groundEnt->NPC )
|
||||
{//Can't jump off of someone's head
|
||||
return qfalse;
|
||||
}
|
||||
*/
|
||||
|
||||
pm->ps->velocity[2] = JUMP_VELOCITY;
|
||||
pm->ps->fd.forceJumpZStart = pm->ps->origin[2];//so we don't take damage if we land at same height
|
||||
pm->ps->pm_flags |= PMF_JUMP_HELD;//PMF_JUMPING;
|
||||
PM_SetForceJumpZStart(pm->ps->origin[2]);//so we don't take damage if we land at same height
|
||||
pm->ps->pm_flags |= PMF_JUMP_HELD;
|
||||
}
|
||||
|
||||
//Jumping
|
||||
|
@ -1332,7 +1250,7 @@ static qboolean PM_CheckJump( void )
|
|||
pml.walking = qfalse;
|
||||
pm->ps->pm_flags |= PMF_JUMP_HELD;
|
||||
pm->ps->groundEntityNum = ENTITYNUM_NONE;
|
||||
pm->ps->fd.forceJumpZStart = pm->ps->origin[2];
|
||||
PM_SetForceJumpZStart(pm->ps->origin[2]);
|
||||
|
||||
PM_AddEvent( EV_JUMP );
|
||||
|
||||
|
@ -1696,7 +1614,6 @@ static void PM_WalkMove( void ) {
|
|||
wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove;
|
||||
}
|
||||
// when going up or down slopes the wish velocity should Not be zero
|
||||
// wishvel[2] = 0;
|
||||
|
||||
VectorCopy (wishvel, wishdir);
|
||||
wishspeed = VectorNormalize(wishdir);
|
||||
|
@ -1740,11 +1657,9 @@ static void PM_WalkMove( void ) {
|
|||
//Com_Printf("velocity = %1.1f %1.1f %1.1f\n", pm->ps->velocity[0], pm->ps->velocity[1], pm->ps->velocity[2]);
|
||||
//Com_Printf("velocity1 = %1.1f\n", VectorLength(pm->ps->velocity));
|
||||
|
||||
if ( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) {
|
||||
if ( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK )
|
||||
{
|
||||
pm->ps->velocity[2] -= pm->ps->gravity * pml.frametime;
|
||||
} else {
|
||||
// don't reset the z velocity for slopes
|
||||
// pm->ps->velocity[2] = 0;
|
||||
}
|
||||
|
||||
vel = VectorLength(pm->ps->velocity);
|
||||
|
@ -1766,7 +1681,6 @@ static void PM_WalkMove( void ) {
|
|||
PM_StepSlideMove( qfalse );
|
||||
|
||||
//Com_Printf("velocity2 = %1.1f\n", VectorLength(pm->ps->velocity));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1870,11 +1784,14 @@ PM_FootstepForSurface
|
|||
Returns an event number apropriate for the groundsurface
|
||||
================
|
||||
*/
|
||||
static int PM_FootstepForSurface( void ) {
|
||||
if ( pml.groundTrace.surfaceFlags & SURF_NOSTEPS ) {
|
||||
static int PM_FootstepForSurface( void )
|
||||
{
|
||||
if ( pml.groundTrace.surfaceFlags & SURF_NOSTEPS )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( pml.groundTrace.surfaceFlags & SURF_METALSTEPS ) {
|
||||
if ( pml.groundTrace.surfaceFlags & SURF_METALSTEPS )
|
||||
{
|
||||
return EV_FOOTSTEP_METAL;
|
||||
}
|
||||
return EV_FOOTSTEP;
|
||||
|
@ -1895,22 +1812,19 @@ static int PM_TryRoll( void )
|
|||
|
||||
if (pm->ps->weapon != WP_SABER || BG_HasYsalamiri(pm->gametype, pm->ps) ||
|
||||
!BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_LEVITATION))
|
||||
{
|
||||
{ //Not using saber, or can't use jump
|
||||
return 0;
|
||||
}
|
||||
|
||||
//VectorSet(mins, pm->mins[0],pm->mins[1],pm->mins[2]+STEPSIZE);
|
||||
//VectorSet(maxs, pm->maxs[0],pm->maxs[1],pm->gent->client->crouchheight);
|
||||
|
||||
VectorSet(mins, pm->mins[0],pm->mins[1],pm->mins[2]+STEPSIZE);
|
||||
VectorSet(maxs, pm->maxs[0],pm->maxs[1],CROUCH_MAXS_2);
|
||||
|
||||
VectorSet(fwdAngles, 0, pm->ps->viewangles[YAW], 0);
|
||||
|
||||
AngleVectors( fwdAngles, fwd, right, NULL );
|
||||
//FIXME: trace ahead for clearance to roll
|
||||
|
||||
if ( pm->cmd.forwardmove )
|
||||
{
|
||||
{ //check forward/backward rolls
|
||||
if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN )
|
||||
{
|
||||
anim = BOTH_ROLL_B;
|
||||
|
@ -1923,25 +1837,21 @@ static int PM_TryRoll( void )
|
|||
}
|
||||
}
|
||||
else if ( pm->cmd.rightmove > 0 )
|
||||
{
|
||||
{ //right
|
||||
anim = BOTH_ROLL_R;
|
||||
VectorMA( pm->ps->origin, 64, right, traceto );
|
||||
}
|
||||
else if ( pm->cmd.rightmove < 0 )
|
||||
{
|
||||
{ //left
|
||||
anim = BOTH_ROLL_L;
|
||||
VectorMA( pm->ps->origin, -64, right, traceto );
|
||||
}
|
||||
else
|
||||
{//???
|
||||
}
|
||||
|
||||
if ( anim != -1 )
|
||||
{
|
||||
{ //We want to roll. Perform a trace to see if we can, and if so, send us into one.
|
||||
pm->trace( &trace, pm->ps->origin, mins, maxs, traceto, pm->ps->clientNum, CONTENTS_SOLID );
|
||||
if ( trace.fraction >= 1.0f )
|
||||
{
|
||||
//PM_AddEvent( EV_ROLL );
|
||||
//Done later..
|
||||
pm->ps->saberMove = LS_NONE;
|
||||
return anim;
|
||||
}
|
||||
|
@ -2001,14 +1911,9 @@ static void PM_CrashLand( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (pm->ps->forceHandExtend == HANDEXTEND_NONE)
|
||||
{
|
||||
pm->ps->forceHandExtend = HANDEXTEND_WEAPONREADY;
|
||||
}
|
||||
*/
|
||||
if (pm->ps->weapon != WP_SABER)
|
||||
{ //saber handles its own anims
|
||||
//This will push us back into our weaponready stance from the land anim.
|
||||
if (pm->ps->weapon == WP_DISRUPTOR && pm->ps->zoomMode == 1)
|
||||
{
|
||||
PM_StartTorsoAnim( TORSO_WEAPONREADY4 );
|
||||
|
@ -2025,13 +1930,12 @@ static void PM_CrashLand( void ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
//just a stupid hack to push us back into our "idle" stance
|
||||
|
||||
if (!BG_InSpecialJump(pm->ps->legsAnim) ||
|
||||
pm->ps->legsTimer < 1 ||
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_LEFT ||
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_RIGHT)
|
||||
{
|
||||
{ //Only set the timer if we're in an anim that can be interrupted (this would not be, say, a flip)
|
||||
if (!BG_InRoll(pm->ps, pm->ps->legsAnim) && pm->ps->inAirAnim)
|
||||
{
|
||||
if (!BG_SaberInSpecial(pm->ps->saberMove) || pm->ps->weapon != WP_SABER)
|
||||
|
@ -2062,7 +1966,8 @@ static void PM_CrashLand( void ) {
|
|||
|
||||
if ( pm->ps->pm_flags & PMF_DUCKED )
|
||||
{
|
||||
if( delta >= 2 && !PM_InOnGroundAnim( pm->ps->legsAnim ) && !PM_InKnockDown( pm->ps ) && !BG_InRoll(pm->ps, pm->ps->legsAnim) )
|
||||
if( delta >= 2 && !PM_InOnGroundAnim( pm->ps->legsAnim ) && !PM_InKnockDown( pm->ps ) && !BG_InRoll(pm->ps, pm->ps->legsAnim) &&
|
||||
pm->ps->forceHandExtend == HANDEXTEND_NONE )
|
||||
{//roll!
|
||||
int anim = PM_TryRoll();
|
||||
|
||||
|
@ -2078,7 +1983,6 @@ static void PM_CrashLand( void ) {
|
|||
if ( anim )
|
||||
{//absorb some impact
|
||||
pm->ps->legsTimer = 0;
|
||||
//delta /= 2;
|
||||
delta /= 3; // /= 2 just cancels out the above delta *= 2 when landing while crouched, the roll itself should absorb a little damage
|
||||
pm->ps->legsAnim = 0;
|
||||
PM_SetAnim(SETANIM_BOTH,anim,SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 150);
|
||||
|
@ -2087,8 +1991,6 @@ static void PM_CrashLand( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
// create a local entity event to play the sound
|
||||
|
||||
// SURF_NODAMAGE is used for bounce pads where you don't ever
|
||||
// want to take damage or play a crunch sound
|
||||
if ( !(pml.groundTrace.surfaceFlags & SURF_NODAMAGE) ) {
|
||||
|
@ -2135,7 +2037,7 @@ static void PM_CrashLand( void ) {
|
|||
}
|
||||
|
||||
if (didRoll)
|
||||
{
|
||||
{ //Add the appropriate event..
|
||||
PM_AddEventWithParm( EV_ROLL, delta_send );
|
||||
}
|
||||
else
|
||||
|
@ -2163,22 +2065,6 @@ static void PM_CrashLand( void ) {
|
|||
pm->ps->bobCycle = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
PM_CheckStuck
|
||||
=============
|
||||
*/
|
||||
/*
|
||||
void PM_CheckStuck(void) {
|
||||
trace_t trace;
|
||||
|
||||
pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, pm->ps->origin, pm->ps->clientNum, pm->tracemask);
|
||||
if (trace.allsolid) {
|
||||
//int shit = qtrue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
=============
|
||||
PM_CorrectAllSolid
|
||||
|
@ -2234,23 +2120,18 @@ static void PM_GroundTraceMissed( void ) {
|
|||
|
||||
//rww - don't want to do this when handextend_choke, because you can be standing on the ground
|
||||
//while still holding your throat.
|
||||
if ( pm->ps->pm_type == PM_FLOAT ) {
|
||||
if ( pm->ps->pm_type == PM_FLOAT )
|
||||
{
|
||||
//we're assuming this is because you're being choked
|
||||
int parts = SETANIM_LEGS;
|
||||
/*
|
||||
if ( !pm->ps->weaponTime && pm->ps->forceHandExtend >= HANDEXTEND_CHOKE )
|
||||
{//still on ground, only set anim on torso
|
||||
parts = SETANIM_BOTH;
|
||||
}
|
||||
*/
|
||||
|
||||
//rww - also don't use SETANIM_FLAG_HOLD, it will cause the legs to float around a bit before going into
|
||||
//a proper anim even when on the ground.
|
||||
PM_SetAnim(parts, BOTH_CHOKE3, SETANIM_FLAG_OVERRIDE, 100);
|
||||
//pm->ps->torsoTimer = 1;
|
||||
//pm->ps->legsTimer = 1;
|
||||
}
|
||||
//If the anim is choke3, act like we just went into the air because we aren't in a float
|
||||
else if ( pm->ps->groundEntityNum != ENTITYNUM_NONE || (pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_CHOKE3 ) {
|
||||
else if ( pm->ps->groundEntityNum != ENTITYNUM_NONE || (pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_CHOKE3 )
|
||||
{
|
||||
// we just transitioned into freefall
|
||||
if ( pm->debugLevel ) {
|
||||
Com_Printf("%i:lift\n", c_pmove);
|
||||
|
@ -2264,18 +2145,18 @@ static void PM_GroundTraceMissed( void ) {
|
|||
pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
||||
if ( trace.fraction == 1.0 || pm->ps->pm_type == PM_FLOAT ) {
|
||||
if ( pm->ps->velocity[2] <= 0 && !(pm->ps->pm_flags&PMF_JUMP_HELD))
|
||||
{//FIXME: if velocity[2] < 0 and didn't jump, use some falling anim
|
||||
PM_SetAnim(SETANIM_LEGS,BOTH_INAIR1,SETANIM_FLAG_OVERRIDE, 100); // Only blend over 100ms
|
||||
{
|
||||
PM_SetAnim(SETANIM_LEGS,BOTH_INAIR1,SETANIM_FLAG_OVERRIDE, 100);
|
||||
pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP;
|
||||
}
|
||||
else if ( pm->cmd.forwardmove >= 0 )
|
||||
{
|
||||
PM_SetAnim(SETANIM_LEGS,BOTH_JUMP1,SETANIM_FLAG_OVERRIDE, 100); // Only blend over 100ms
|
||||
PM_SetAnim(SETANIM_LEGS,BOTH_JUMP1,SETANIM_FLAG_OVERRIDE, 100);
|
||||
pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP;
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_SetAnim(SETANIM_LEGS,BOTH_JUMPBACK1,SETANIM_FLAG_OVERRIDE, 100); // Only blend over 100ms
|
||||
PM_SetAnim(SETANIM_LEGS,BOTH_JUMPBACK1,SETANIM_FLAG_OVERRIDE, 100);
|
||||
pm->ps->pm_flags |= PMF_BACKWARDS_JUMP;
|
||||
}
|
||||
|
||||
|
@ -2297,8 +2178,8 @@ static void PM_GroundTraceMissed( void ) {
|
|||
}
|
||||
|
||||
if (PM_InRollComplete(pm->ps, pm->ps->legsAnim))
|
||||
{ //HACK -_- (filthy client won't catch an animation restart because it only checks frame against incoming frame, so if you roll when you land after rolling
|
||||
//off of something it won't replay the roll anim unless we switch it off in the air)
|
||||
{ //Client won't catch an animation restart because it only checks frame against incoming frame, so if you roll when you land after rolling
|
||||
//off of something it won't replay the roll anim unless we switch it off in the air. This fixes that.
|
||||
PM_SetAnim(SETANIM_BOTH,BOTH_INAIR1,SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 150);
|
||||
pm->ps->inAirAnim = qtrue;
|
||||
}
|
||||
|
@ -2372,8 +2253,6 @@ static void PM_GroundTrace( void ) {
|
|||
if ( pm->debugLevel ) {
|
||||
Com_Printf("%i:steep\n", c_pmove);
|
||||
}
|
||||
// FIXME: if they can't slide down the slope, let them
|
||||
// walk (sharp crevices)
|
||||
pm->ps->groundEntityNum = ENTITYNUM_NONE;
|
||||
pml.groundPlane = qtrue;
|
||||
pml.walking = qfalse;
|
||||
|
@ -2409,16 +2288,13 @@ static void PM_GroundTrace( void ) {
|
|||
pm->ps->groundEntityNum = trace.entityNum;
|
||||
pm->ps->lastOnGround = pm->cmd.serverTime;
|
||||
|
||||
// don't reset the z velocity for slopes
|
||||
// pm->ps->velocity[2] = 0;
|
||||
|
||||
PM_AddTouchEnt( trace.entityNum );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
PM_SetWaterLevel FIXME: avoid this twice? certainly if not moving
|
||||
PM_SetWaterLevel
|
||||
=============
|
||||
*/
|
||||
static void PM_SetWaterLevel( void ) {
|
||||
|
@ -2690,7 +2566,8 @@ static void PM_Footsteps( void ) {
|
|||
|
||||
footstep = qfalse;
|
||||
|
||||
if ( pm->ps->pm_flags & PMF_DUCKED ) {
|
||||
if ( pm->ps->pm_flags & PMF_DUCKED )
|
||||
{
|
||||
int rolled = 0;
|
||||
|
||||
bobmove = 0.5; // ducked characters bob much faster
|
||||
|
@ -2700,7 +2577,7 @@ static void PM_Footsteps( void ) {
|
|||
rolled = PM_TryRoll();
|
||||
}
|
||||
if ( !rolled )
|
||||
{
|
||||
{ //if the roll failed or didn't attempt, do standard crouching anim stuff.
|
||||
if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) {
|
||||
if ((pm->ps->legsAnim&~ANIM_TOGGLEBIT) != BOTH_CROUCH1WALKBACK)
|
||||
{
|
||||
|
@ -2723,7 +2600,7 @@ static void PM_Footsteps( void ) {
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //otherwise send us into the roll
|
||||
pm->ps->legsTimer = 0;
|
||||
pm->ps->legsAnim = 0;
|
||||
PM_SetAnim(SETANIM_BOTH,rolled,SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 150);
|
||||
|
@ -2733,17 +2610,6 @@ static void PM_Footsteps( void ) {
|
|||
pm->ps->pm_flags &= ~PMF_DUCKED;
|
||||
pm->ps->pm_flags |= PMF_ROLLING;
|
||||
}
|
||||
// ducked characters never play footsteps
|
||||
/*
|
||||
} else if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) {
|
||||
if ( !( pm->cmd.buttons & BUTTON_WALKING ) ) {
|
||||
bobmove = 0.4; // faster speeds bob faster
|
||||
footstep = qtrue;
|
||||
} else {
|
||||
bobmove = 0.3;
|
||||
}
|
||||
PM_ContinueLegsAnim( LEGS_BACK );
|
||||
*/
|
||||
}
|
||||
else if ((pm->ps->pm_flags & PMF_ROLLING) && !BG_InRoll(pm->ps, pm->ps->legsAnim) &&
|
||||
!PM_InRollComplete(pm->ps, pm->ps->legsAnim))
|
||||
|
@ -2830,14 +2696,6 @@ static void PM_Footsteps( void ) {
|
|||
// if we just crossed a cycle boundary, play an apropriate footstep event
|
||||
if ( ( ( old + 64 ) ^ ( pm->ps->bobCycle + 64 ) ) & 128 )
|
||||
{
|
||||
/*
|
||||
if ( pm->waterlevel == 0 ) {
|
||||
// on ground will only play sounds if running
|
||||
if ( footstep && !pm->noFootsteps ) {
|
||||
PM_AddEvent( PM_FootstepForSurface() );
|
||||
}
|
||||
} else
|
||||
*/
|
||||
pm->ps->footstepTime = pm->cmd.serverTime + 300;
|
||||
if ( pm->waterlevel == 1 ) {
|
||||
// splashing
|
||||
|
@ -3217,6 +3075,11 @@ int PM_ItemUsable(playerState_t *ps, int forcedUse)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (ps->duelInProgress)
|
||||
{ //not allowed to use holdables while in a private duel.
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!forcedUse)
|
||||
{
|
||||
forcedUse = bg_itemlist[ps->stats[STAT_HOLDABLE_ITEM]].giTag;
|
||||
|
@ -3314,7 +3177,8 @@ PM_Weapon
|
|||
Generates weapon events and modifes the weapon counter
|
||||
==============
|
||||
*/
|
||||
static void PM_Weapon( void ) {
|
||||
static void PM_Weapon( void )
|
||||
{
|
||||
int addTime;
|
||||
int amount;
|
||||
int killAfterItem = 0;
|
||||
|
@ -3401,6 +3265,8 @@ static void PM_Weapon( void ) {
|
|||
else if (pm->ps->forceHandExtend != HANDEXTEND_NONE)
|
||||
{ //nothing else should be allowed to happen during this time, including weapon fire
|
||||
int desiredAnim = 0;
|
||||
qboolean seperateOnTorso = qfalse;
|
||||
int desiredOnTorso = 0;
|
||||
|
||||
switch(pm->ps->forceHandExtend)
|
||||
{
|
||||
|
@ -3418,12 +3284,6 @@ static void PM_Weapon( void ) {
|
|||
break;
|
||||
case HANDEXTEND_CHOKE:
|
||||
desiredAnim = BOTH_CHOKE3; //left-handed choke
|
||||
/*
|
||||
if ( pm->ps->weapon == WP_NONE || pm->ps->weapon == WP_MELEE )
|
||||
{
|
||||
desiredAnim = BOTH_CHOKE1; //two-handed choke
|
||||
}
|
||||
*/
|
||||
break;
|
||||
case HANDEXTEND_DODGE:
|
||||
desiredAnim = pm->ps->forceDodgeAnim;
|
||||
|
@ -3431,7 +3291,27 @@ static void PM_Weapon( void ) {
|
|||
case HANDEXTEND_KNOCKDOWN:
|
||||
if (pm->ps->forceDodgeAnim)
|
||||
{
|
||||
if (pm->ps->forceDodgeAnim == 2)
|
||||
if (pm->ps->forceDodgeAnim > 4)
|
||||
{ //this means that we want to play a sepereate anim on the torso
|
||||
int originalDAnim = pm->ps->forceDodgeAnim-8; //-8 is the original legs anim
|
||||
if (originalDAnim == 2)
|
||||
{
|
||||
desiredAnim = BOTH_FORCE_GETUP_B1;
|
||||
}
|
||||
else if (originalDAnim == 3)
|
||||
{
|
||||
desiredAnim = BOTH_FORCE_GETUP_B3;
|
||||
}
|
||||
else
|
||||
{
|
||||
desiredAnim = BOTH_GETUP1;
|
||||
}
|
||||
|
||||
//now specify the torso anim
|
||||
seperateOnTorso = qtrue;
|
||||
desiredOnTorso = BOTH_FORCEPUSH;
|
||||
}
|
||||
else if (pm->ps->forceDodgeAnim == 2)
|
||||
{
|
||||
desiredAnim = BOTH_FORCE_GETUP_B1;
|
||||
}
|
||||
|
@ -3471,14 +3351,28 @@ static void PM_Weapon( void ) {
|
|||
break;
|
||||
}
|
||||
|
||||
PM_SetAnim(SETANIM_TORSO, desiredAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100);
|
||||
pm->ps->torsoTimer = 1;
|
||||
if (!seperateOnTorso)
|
||||
{ //of seperateOnTorso, handle it after setting the legs
|
||||
PM_SetAnim(SETANIM_TORSO, desiredAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100);
|
||||
pm->ps->torsoTimer = 1;
|
||||
}
|
||||
|
||||
if (pm->ps->forceHandExtend == HANDEXTEND_DODGE || pm->ps->forceHandExtend == HANDEXTEND_KNOCKDOWN ||
|
||||
(pm->ps->forceHandExtend == HANDEXTEND_CHOKE && pm->ps->groundEntityNum == ENTITYNUM_NONE) )
|
||||
{ //special case, play dodge anim on whole body, choke anim too if off ground
|
||||
PM_SetAnim(SETANIM_LEGS, desiredAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100);
|
||||
pm->ps->legsTimer = 1;
|
||||
if (seperateOnTorso)
|
||||
{
|
||||
PM_SetAnim(SETANIM_LEGS, desiredAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100);
|
||||
pm->ps->legsTimer = 1;
|
||||
|
||||
PM_SetAnim(SETANIM_TORSO, desiredOnTorso, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100);
|
||||
pm->ps->torsoTimer = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_SetAnim(SETANIM_LEGS, desiredAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100);
|
||||
pm->ps->legsTimer = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -3876,10 +3770,6 @@ static void PM_Animate( void ) {
|
|||
if ( pm->cmd.buttons & BUTTON_GESTURE ) {
|
||||
if ( pm->ps->torsoTimer < 1 && pm->ps->forceHandExtend == HANDEXTEND_NONE &&
|
||||
pm->ps->legsTimer < 1 && pm->ps->weaponTime < 1 && pm->ps->saberLockTime < pm->cmd.serverTime) {
|
||||
/*
|
||||
PM_StartTorsoAnim( BOTH_TALKGESTURE3 );
|
||||
pm->ps->torsoTimer = TIMER_GESTURE;
|
||||
*/
|
||||
|
||||
pm->ps->forceHandExtend = HANDEXTEND_TAUNT;
|
||||
|
||||
|
@ -4114,34 +4004,6 @@ void PM_AdjustAttackStates( pmove_t *pm )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// set the firing flag for continuous beam weapons
|
||||
if ( !(pm->ps->pm_flags & PMF_RESPAWNED) && pm->ps->pm_type != PM_INTERMISSION
|
||||
&& ( pm->cmd.buttons & (BUTTON_ATTACK|BUTTON_ALT_ATTACK)) && pm->ps->ammo[ weaponData[pm->ps->weapon].ammoIndex ] )
|
||||
{
|
||||
// Check more in depth here.
|
||||
if ((pm->cmd.buttons & BUTTON_ATTACK) &&
|
||||
pm->ps->ammo[weaponData[pm->ps->weapon].ammoIndex] >= weaponData[pm->ps->weapon].energyPerShot)
|
||||
{
|
||||
pm->ps->eFlags |= EF_FIRING;
|
||||
pm->ps->eFlags &= ~EF_ALT_FIRING;
|
||||
}
|
||||
else if ((pm->cmd.buttons & BUTTON_ALT_ATTACK) &&
|
||||
pm->ps->ammo[weaponData[pm->ps->weapon].ammoIndex] >= weaponData[pm->ps->weapon].altEnergyPerShot)
|
||||
{
|
||||
pm->ps->eFlags |= (EF_FIRING|EF_ALT_FIRING); // Both are set in the event of an alt fire
|
||||
}
|
||||
else
|
||||
{
|
||||
pm->ps->eFlags &= ~(EF_FIRING|EF_ALT_FIRING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pm->ps->eFlags &= ~(EF_FIRING|EF_ALT_FIRING);
|
||||
}
|
||||
*/
|
||||
|
||||
// set the firing flag for continuous beam weapons, saber will fire even if out of ammo
|
||||
if ( !(pm->ps->pm_flags & PMF_RESPAWNED) &&
|
||||
pm->ps->pm_type != PM_INTERMISSION &&
|
||||
|
@ -4288,6 +4150,10 @@ void BG_AdjustClientSpeed(playerState_t *ps, usercmd_t *cmd, int svTime)
|
|||
| BOTH_RUN1;
|
||||
}
|
||||
}
|
||||
else if ( cmd->forwardmove < 0 && !(cmd->buttons&BUTTON_WALKING) && pm->ps->groundEntityNum != ENTITYNUM_NONE )
|
||||
{//running backwards is slower than running forwards (like SP)
|
||||
ps->speed *= 0.75;
|
||||
}
|
||||
|
||||
if (ps->fd.forcePowersActive & (1 << FP_GRIP))
|
||||
{
|
||||
|
@ -4369,7 +4235,6 @@ void BG_AdjustClientSpeed(playerState_t *ps, usercmd_t *cmd, int svTime)
|
|||
ps->speed *= 0.85f;
|
||||
break;
|
||||
case FORCE_LEVEL_3:
|
||||
//ps->speed *= 0.70f;
|
||||
ps->speed *= 0.55f;
|
||||
break;
|
||||
default:
|
||||
|
@ -4479,7 +4344,6 @@ void PmoveSingle (pmove_t *pmove) {
|
|||
if ((pm->ps->legsAnim&~ANIM_TOGGLEBIT) == (BOTH_A2_STABBACK1) ||
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == (BOTH_ATTACK_BACK) ||
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == (BOTH_CROUCHATTACKBACK1) ||
|
||||
//(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == (BOTH_LUNGE2_B__T_) ||
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == (BOTH_FORCELEAP2_T__B_) ||
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == (BOTH_JUMPFLIPSTABDOWN) ||
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == (BOTH_JUMPFLIPSLASHDOWN1))
|
||||
|
@ -4489,6 +4353,14 @@ void PmoveSingle (pmove_t *pmove) {
|
|||
pm->cmd.upmove = 0;
|
||||
}
|
||||
|
||||
if ((pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_KISSER1LOOP ||
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_KISSEE1LOOP)
|
||||
{
|
||||
pm->cmd.forwardmove = 0;
|
||||
pm->cmd.rightmove = 0;
|
||||
pm->cmd.upmove = 0;
|
||||
}
|
||||
|
||||
if (pm->ps->emplacedIndex)
|
||||
{
|
||||
if (pm->cmd.forwardmove < 0)
|
||||
|
@ -4576,25 +4448,17 @@ void PmoveSingle (pmove_t *pmove) {
|
|||
|
||||
PM_AdjustAngleForWallRun(pm->ps, &pm->cmd, qtrue);
|
||||
|
||||
if (pm->ps->saberMove == LS_A_JUMP_T__B_ || pm->ps->saberMove == LS_A_LUNGE)
|
||||
if (pm->ps->saberMove == LS_A_JUMP_T__B_ || pm->ps->saberMove == LS_A_LUNGE ||
|
||||
pm->ps->saberMove == LS_A_BACK_CR || pm->ps->saberMove == LS_A_BACK ||
|
||||
pm->ps->saberMove == LS_A_BACKSTAB)
|
||||
{
|
||||
/*
|
||||
if (pm->ps->velocity[0] ||
|
||||
pm->ps->velocity[1] ||
|
||||
pm->ps->velocity[2])
|
||||
{ //if we're doing a lunge and we have a velocity, force us to look in the direction we are
|
||||
//flying with the lunge
|
||||
vec3_t velAngles;
|
||||
PM_SetPMViewAngle(pm->ps, pm->ps->viewangles, &pm->cmd);
|
||||
}
|
||||
|
||||
vectoangles(pm->ps->velocity, velAngles);
|
||||
PM_SetPMViewAngle(pm->ps, velAngles, &pm->cmd);
|
||||
}
|
||||
else
|
||||
{ //otherwise, if there is no valid velocity, just don't let us readjust the angles.
|
||||
PM_SetPMViewAngle(pm->ps, pm->ps->viewangles, &pm->cmd);
|
||||
}
|
||||
*/
|
||||
//FIXME: Use the above method, and don't let the angles mess up when you hit something.
|
||||
if ((pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_KISSER1LOOP ||
|
||||
(pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_KISSEE1LOOP)
|
||||
{
|
||||
pm->ps->viewangles[PITCH] = 0;
|
||||
PM_SetPMViewAngle(pm->ps, pm->ps->viewangles, &pm->cmd);
|
||||
}
|
||||
|
||||
|
@ -4715,11 +4579,6 @@ void PmoveSingle (pmove_t *pmove) {
|
|||
|
||||
PM_Use();
|
||||
|
||||
if (pm->ps->pm_flags & PMF_UPDATE_ANIM)
|
||||
{
|
||||
// PM_UpdateGhoul2AnimFromState();
|
||||
}
|
||||
|
||||
// footstep events / legs animations
|
||||
PM_Footsteps();
|
||||
|
||||
|
@ -4790,8 +4649,5 @@ void Pmove (pmove_t *pmove) {
|
|||
pmove->cmd.upmove = 20;
|
||||
}
|
||||
}
|
||||
|
||||
//PM_CheckStuck();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1032,9 +1032,6 @@ void BG_TouchJumpPad( playerState_t *ps, entityState_t *jumppad );
|
|||
|
||||
void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap );
|
||||
void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s, int time, qboolean snap );
|
||||
void BG_G2PlayerAngles( vec3_t startAngles, vec3_t legs[3], vec3_t legsAngles, int painTime, int painDirection, int currentTime,
|
||||
qboolean *torso_yawing, float *torso_yawAngle, qboolean *torso_pitching, float *torso_pitchAngle, qboolean *legs_yawing, float *legs_yawAngle,
|
||||
int frameTime, vec3_t velocity, int legsAnim, int torsoAnim, qboolean dead, float movementDir, void *ghoul2, qhandle_t *modelList, int weapon);
|
||||
|
||||
qboolean BG_PlayerTouchesItem( playerState_t *ps, entityState_t *item, int atTime );
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ void BG_ForcePowerDrain( playerState_t *ps, forcePowers_t forcePower, int overri
|
|||
return;
|
||||
}
|
||||
*/
|
||||
//No longer grant infinite force with boon.
|
||||
|
||||
if ( !drain )
|
||||
{
|
||||
|
@ -353,7 +354,6 @@ qboolean PM_SaberKataDone(int curmove, int newmove);
|
|||
|
||||
int PM_SaberAnimTransitionAnim( int curmove, int newmove )
|
||||
{
|
||||
//FIXME: take FP_SABER_OFFENSE into account here somehow?
|
||||
int retmove = newmove;
|
||||
if ( curmove == LS_READY )
|
||||
{//just standing there
|
||||
|
@ -401,10 +401,8 @@ int PM_SaberAnimTransitionAnim( int curmove, int newmove )
|
|||
case LS_A_TR2BL:
|
||||
case LS_A_T2B:
|
||||
if ( newmove == curmove )
|
||||
{//FIXME: need a spin or something or go to next level, but for now, just play the return
|
||||
//going into another attack...
|
||||
//allow endless chaining in level 1 attacks, several in level 2 and only one or a few in level 3
|
||||
//FIXME: don't let strong attacks chain to an attack in the opposite direction ( > 45 degrees?)
|
||||
{
|
||||
//going into an attack
|
||||
if ( PM_SaberKataDone( curmove, newmove ) )
|
||||
{//done with this kata, must return to ready before attack again
|
||||
retmove = LS_R_TL2BR + (newmove-LS_A_TL2BR);
|
||||
|
@ -555,12 +553,11 @@ int PM_SaberMoveQuadrantForMovement( usercmd_t *ucmd )
|
|||
{//backward= T2B slash //or B2T uppercut?
|
||||
return Q_T;
|
||||
}
|
||||
else //if ( curmove == LS_READY )//???
|
||||
else
|
||||
{//Not moving at all
|
||||
return Q_R;
|
||||
}
|
||||
}
|
||||
//return Q_R;//????
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
@ -702,7 +699,7 @@ qboolean PM_SaberKataDone(int curmove, int newmove)
|
|||
}
|
||||
}
|
||||
else
|
||||
{//FIXME: have chainAngle influence fast and medium chains as well?
|
||||
{//Perhaps have chainAngle influence fast and medium chains as well? For now, just do level 3.
|
||||
if (newmove == LS_A_TL2BR ||
|
||||
newmove == LS_A_L2R ||
|
||||
newmove == LS_A_BL2TR ||
|
||||
|
@ -756,7 +753,6 @@ void PM_SaberLockBreak( playerState_t *genemy, qboolean victory )
|
|||
}
|
||||
else
|
||||
{
|
||||
//loseAnim = BOTH_KNOCKDOWN4;
|
||||
punishLoser = qtrue;
|
||||
}
|
||||
break;
|
||||
|
@ -770,7 +766,6 @@ void PM_SaberLockBreak( playerState_t *genemy, qboolean victory )
|
|||
}
|
||||
else
|
||||
{
|
||||
//loseAnim = BOTH_BF1BREAK;
|
||||
punishLoser = qtrue;
|
||||
}
|
||||
break;
|
||||
|
@ -782,9 +777,8 @@ void PM_SaberLockBreak( playerState_t *genemy, qboolean victory )
|
|||
}
|
||||
else
|
||||
{
|
||||
genemy->saberMove = /*genemy->saberBounceMove =*/ LS_H1_BL;
|
||||
genemy->saberMove = LS_H1_BL;
|
||||
genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
|
||||
//loseAnim = BOTH_H1_S1_BR;
|
||||
punishLoser = qtrue;
|
||||
}
|
||||
break;
|
||||
|
@ -796,9 +790,8 @@ void PM_SaberLockBreak( playerState_t *genemy, qboolean victory )
|
|||
}
|
||||
else
|
||||
{
|
||||
genemy->saberMove = /*genemy->saberBounceMove =*/ LS_H1_BR;
|
||||
genemy->saberMove = LS_H1_BR;
|
||||
genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
|
||||
//loseAnim = BOTH_H1_S1_BL;
|
||||
punishLoser = qtrue;
|
||||
}
|
||||
break;
|
||||
|
@ -806,7 +799,7 @@ void PM_SaberLockBreak( playerState_t *genemy, qboolean victory )
|
|||
PM_SetAnim( SETANIM_BOTH, winAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, -1 );
|
||||
|
||||
if (punishLoser)
|
||||
{
|
||||
{ //someone lost the lock, so punish them by knocking them down
|
||||
vec3_t oppDir;
|
||||
|
||||
int strength = 8;
|
||||
|
@ -829,7 +822,7 @@ void PM_SaberLockBreak( playerState_t *genemy, qboolean victory )
|
|||
pm->checkDuelLoss = genemy->clientNum+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
{ //If no one lost, then shove each player away from the other
|
||||
vec3_t oppDir;
|
||||
|
||||
int strength = 4;
|
||||
|
@ -849,8 +842,7 @@ void PM_SaberLockBreak( playerState_t *genemy, qboolean victory )
|
|||
genemy->forceHandExtend = HANDEXTEND_WEAPONREADY;
|
||||
}
|
||||
|
||||
pm->ps->weaponTime = 0;//pm->ps->torsoTimer;
|
||||
//The enemy unfortunately has no valid torso animation time at this point, so just use ours
|
||||
pm->ps->weaponTime = 0;
|
||||
genemy->weaponTime = 0;
|
||||
|
||||
pm->ps->saberLockTime = genemy->saberLockTime = 0;
|
||||
|
@ -877,12 +869,7 @@ extern qboolean ValidAnimFileIndex ( int index );
|
|||
void PM_SaberLocked( void )
|
||||
{
|
||||
int remaining = 0;
|
||||
/*
|
||||
if ( pm->ps->weaponTime )
|
||||
{//can't attack yet
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
playerState_t *genemy = pm->bgClients[pm->ps->saberLockEnemy];
|
||||
if ( !genemy )
|
||||
{
|
||||
|
@ -906,13 +893,15 @@ void PM_SaberLocked( void )
|
|||
genemy->weaponTime = 0;
|
||||
|
||||
dist = DistanceSquared(pm->ps->origin,genemy->origin);
|
||||
if ( dist < 64 || dist > 6400 )//( dist < 128 || dist > 2304 )
|
||||
{//between 8 and 80 from each other//was 16 and 48
|
||||
if ( dist < 64 || dist > 6400 )
|
||||
{//between 8 and 80 from each other
|
||||
PM_SaberLockBreak( genemy, qfalse );
|
||||
return;
|
||||
}
|
||||
if ( (pm->cmd.buttons & BUTTON_ATTACK) || pm->ps->saberLockAdvance )
|
||||
{//holding attack
|
||||
animation_t *anim;
|
||||
|
||||
if (pm->ps->saberLockAdvance)
|
||||
{//tapping
|
||||
animation_t *anim;
|
||||
|
@ -968,24 +957,21 @@ void PM_SaberLocked( void )
|
|||
{
|
||||
return;
|
||||
}
|
||||
if( 1/*ValidAnimFileIndex( genemy->client->clientInfo.animFileIndex )*/ )
|
||||
{
|
||||
animation_t *anim;
|
||||
anim = &pm->animations[(genemy->torsoAnim&~ANIM_TOGGLEBIT)];
|
||||
|
||||
if ( (genemy->torsoAnim&~ANIM_TOGGLEBIT) == BOTH_CWCIRCLELOCK ||
|
||||
(genemy->torsoAnim&~ANIM_TOGGLEBIT) == BOTH_BF1LOCK )
|
||||
anim = &pm->animations[(genemy->torsoAnim&~ANIM_TOGGLEBIT)];
|
||||
|
||||
if ( (genemy->torsoAnim&~ANIM_TOGGLEBIT) == BOTH_CWCIRCLELOCK ||
|
||||
(genemy->torsoAnim&~ANIM_TOGGLEBIT) == BOTH_BF1LOCK )
|
||||
{
|
||||
if ( !PM_irand_timesync( 0, 2 ) )
|
||||
{
|
||||
if ( !PM_irand_timesync( 0, 2 ) )
|
||||
{
|
||||
BG_AddPredictableEventToPlayerstate(EV_PAIN, floor((float)80/100*100.0f), genemy);
|
||||
}
|
||||
PM_SetAnimFrame( genemy, anim->firstFrame+remaining, qtrue, qtrue );
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_SetAnimFrame( genemy, anim->firstFrame+anim->numFrames-remaining, qtrue, qtrue );
|
||||
BG_AddPredictableEventToPlayerstate(EV_PAIN, floor((float)80/100*100.0f), genemy);
|
||||
}
|
||||
PM_SetAnimFrame( genemy, anim->firstFrame+remaining, qtrue, qtrue );
|
||||
}
|
||||
else
|
||||
{
|
||||
PM_SetAnimFrame( genemy, anim->firstFrame+anim->numFrames-remaining, qtrue, qtrue );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1011,8 +997,6 @@ qboolean PM_SaberInBrokenParry( int move )
|
|||
|
||||
int PM_BrokenParryForParry( int move )
|
||||
{
|
||||
//FIXME: need actual anims for this
|
||||
//FIXME: need to know which side of the saber was hit! For now, we presume the saber gets knocked away from the center
|
||||
switch ( move )
|
||||
{
|
||||
case LS_PARRY_UP:
|
||||
|
@ -1031,13 +1015,13 @@ int PM_BrokenParryForParry( int move )
|
|||
return LS_H1_BR;
|
||||
break;
|
||||
case LS_READY:
|
||||
return LS_H1_B_;//???
|
||||
return LS_H1_B_;
|
||||
break;
|
||||
}
|
||||
return LS_NONE;
|
||||
}
|
||||
|
||||
#define BACK_STAB_DISTANCE 128//64
|
||||
#define BACK_STAB_DISTANCE 128
|
||||
|
||||
qboolean PM_CanBackstab(void)
|
||||
{
|
||||
|
@ -1068,7 +1052,6 @@ qboolean PM_CanBackstab(void)
|
|||
|
||||
saberMoveName_t PM_SaberFlipOverAttackMove(trace_t *tr)
|
||||
{
|
||||
//FIXME: check above for room enough to jump!
|
||||
vec3_t fwdAngles, jumpFwd;
|
||||
float zDiff = 0;
|
||||
playerState_t *psData;
|
||||
|
@ -1076,13 +1059,11 @@ saberMoveName_t PM_SaberFlipOverAttackMove(trace_t *tr)
|
|||
VectorCopy( pm->ps->viewangles, fwdAngles );
|
||||
fwdAngles[PITCH] = fwdAngles[ROLL] = 0;
|
||||
AngleVectors( fwdAngles, jumpFwd, NULL, NULL );
|
||||
VectorScale( jumpFwd, /*100*/50, pm->ps->velocity );
|
||||
VectorScale( jumpFwd, 50, pm->ps->velocity );
|
||||
pm->ps->velocity[2] = 400;
|
||||
|
||||
psData = pm->bgClients[tr->entityNum];
|
||||
|
||||
pm->ps->velocity[2] *= 1;//(pm->gent->enemy->maxs[2]-pm->gent->enemy->mins[2])/64.0f;
|
||||
|
||||
//go higher for enemies higher than you, lower for those lower than you
|
||||
if (psData)
|
||||
{
|
||||
|
@ -1108,7 +1089,7 @@ saberMoveName_t PM_SaberFlipOverAttackMove(trace_t *tr)
|
|||
pm->ps->velocity[2] = 400;
|
||||
}
|
||||
|
||||
pm->ps->fd.forceJumpZStart = pm->ps->origin[2];//so we don't take damage if we land at same height
|
||||
PM_SetForceJumpZStart(pm->ps->origin[2]);//so we don't take damage if we land at same height
|
||||
|
||||
PM_AddEvent( EV_JUMP );
|
||||
pm->ps->fd.forceJumpSound = 1;
|
||||
|
@ -1161,7 +1142,6 @@ saberMoveName_t PM_SaberLungeAttackMove( void )
|
|||
//do the lunge
|
||||
AngleVectors( fwdAngles, jumpFwd, NULL, NULL );
|
||||
VectorScale( jumpFwd, 150, pm->ps->velocity );
|
||||
//pm->ps->velocity[2] = 50;
|
||||
PM_AddEvent( EV_JUMP );
|
||||
|
||||
return LS_A_LUNGE;
|
||||
|
@ -1174,9 +1154,9 @@ saberMoveName_t PM_SaberJumpAttackMove( void )
|
|||
VectorCopy( pm->ps->viewangles, fwdAngles );
|
||||
fwdAngles[PITCH] = fwdAngles[ROLL] = 0;
|
||||
AngleVectors( fwdAngles, jumpFwd, NULL, NULL );
|
||||
VectorScale( jumpFwd, /*200*/300, pm->ps->velocity );
|
||||
pm->ps->velocity[2] = 280;//180;
|
||||
pm->ps->fd.forceJumpZStart = pm->ps->origin[2];//so we don't take damage if we land at same height
|
||||
VectorScale( jumpFwd, 300, pm->ps->velocity );
|
||||
pm->ps->velocity[2] = 280;
|
||||
PM_SetForceJumpZStart(pm->ps->origin[2]);//so we don't take damage if we land at same height
|
||||
|
||||
PM_AddEvent( EV_JUMP );
|
||||
pm->ps->fd.forceJumpSound = 1;
|
||||
|
@ -1240,10 +1220,10 @@ saberMoveName_t PM_SaberAttackForMovement(saberMoveName_t curmove)
|
|||
if ( pm->cmd.forwardmove > 0 )
|
||||
{//forward= T2B slash
|
||||
if (pm->ps->fd.saberAnimLevel == FORCE_LEVEL_2 &&
|
||||
/*pm->ps->groundEntityNum != ENTITYNUM_NONE &&*/
|
||||
pm->ps->velocity[2] > 100 &&
|
||||
PM_GroundDistance() < 32 &&
|
||||
!BG_InSpecialJump(pm->ps->legsAnim))
|
||||
!BG_InSpecialJump(pm->ps->legsAnim) &&
|
||||
!BG_SaberInSpecialAttack(pm->ps->torsoAnim))
|
||||
{ //FLIP AND DOWNWARD ATTACK
|
||||
trace_t tr;
|
||||
|
||||
|
@ -1253,8 +1233,10 @@ saberMoveName_t PM_SaberAttackForMovement(saberMoveName_t curmove)
|
|||
}
|
||||
}
|
||||
else if (pm->ps->fd.saberAnimLevel == FORCE_LEVEL_1 &&
|
||||
pm->ps->groundEntityNum != ENTITYNUM_NONE &&
|
||||
(pm->ps->pm_flags & PMF_DUCKED) &&
|
||||
pm->ps->weaponTime <= 0)
|
||||
pm->ps->weaponTime <= 0 &&
|
||||
!BG_SaberInSpecialAttack(pm->ps->torsoAnim))
|
||||
{ //LUNGE (weak)
|
||||
newmove = PM_SaberLungeAttackMove();
|
||||
}
|
||||
|
@ -1265,7 +1247,7 @@ saberMoveName_t PM_SaberAttackForMovement(saberMoveName_t curmove)
|
|||
}
|
||||
else if ( pm->cmd.forwardmove < 0 )
|
||||
{//backward= T2B slash//B2T uppercut?
|
||||
if (PM_CanBackstab())
|
||||
if (PM_CanBackstab() && !BG_SaberInSpecialAttack(pm->ps->torsoAnim))
|
||||
{ //BACKSTAB (attack varies by level)
|
||||
if (pm->ps->fd.saberAnimLevel >= FORCE_LEVEL_2)
|
||||
{//medium and higher attacks
|
||||
|
@ -1309,7 +1291,6 @@ saberMoveName_t PM_SaberAttackForMovement(saberMoveName_t curmove)
|
|||
//prediction values. Under laggy conditions this will cause the appearance of rapid swing
|
||||
//sequence changes.
|
||||
|
||||
//newmove = PM_irand_timesync(LS_A_TL2BR, LS_A_T2B);
|
||||
newmove = LS_A_T2B; //decided we don't like random attacks when idle, use an overhead instead.
|
||||
}
|
||||
}
|
||||
|
@ -1532,7 +1513,7 @@ void PM_WeaponLightsaber(void)
|
|||
case BLOCKED_ATK_BOUNCE:
|
||||
// If there is absolutely no blocked move in the chart, don't even mess with the animation.
|
||||
// OR if we are already in a block or parry.
|
||||
if (pm->ps->saberMove >= LS_T1_BR__R/*LS_BOUNCE_TOP*/ )//|| saberMoveData[pm->ps->saberMove].bounceMove == LS_NONE )
|
||||
if (pm->ps->saberMove >= LS_T1_BR__R)
|
||||
{//an actual bounce? Other bounces before this are actually transitions?
|
||||
pm->ps->saberBlocked = BLOCKED_NONE;
|
||||
}
|
||||
|
@ -1690,8 +1671,6 @@ weapChecks:
|
|||
// Check for WEAPON ATTACK
|
||||
// *********************************************************
|
||||
|
||||
// NOTENOTE This is simply a client-side struct. Anything that is needed client and server should be moved to bg_weapon.
|
||||
|
||||
if(!delayed_fire)
|
||||
{
|
||||
// Start with the current move, and cross index it with the current control states.
|
||||
|
@ -1704,7 +1683,7 @@ weapChecks:
|
|||
curmove = LS_READY;
|
||||
}
|
||||
// check for fire
|
||||
if ( !(pm->cmd.buttons & (BUTTON_ATTACK/*|BUTTON_ALT_ATTACK*/)) )
|
||||
if ( !(pm->cmd.buttons & (BUTTON_ATTACK)) )
|
||||
{
|
||||
if (pm->ps->weaponTime != 0)
|
||||
{//Still firing
|
||||
|
@ -1798,12 +1777,6 @@ weapChecks:
|
|||
}
|
||||
else//if ( pm->cmd.buttons&BUTTON_ATTACK && !(pm->ps->pm_flags&PMF_ATTACK_HELD) )//only do this if just pressed attack button?
|
||||
{//get attack move from movement command
|
||||
/*
|
||||
if ( PM_SaberKataDone() )
|
||||
{//we came from a bounce and cannot chain to another attack because our kata is done
|
||||
newmove = saberMoveData[curmove].chain_idle;
|
||||
}
|
||||
else */
|
||||
saberMoveName_t checkMove = PM_SaberAttackForMovement(curmove);
|
||||
if (checkMove != -1)
|
||||
{
|
||||
|
@ -1820,39 +1793,17 @@ weapChecks:
|
|||
{//we came from a bounce and cannot chain to another attack because our kata is done
|
||||
newmove = saberMoveData[curmove].chain_idle;
|
||||
}
|
||||
/*else
|
||||
{
|
||||
saberMoveName_t checkMove = PM_SaberAttackForMovement(curmove);
|
||||
if (checkMove != -1)
|
||||
{
|
||||
newmove = checkMove;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
/*
|
||||
if ( newmove == LS_NONE )
|
||||
{//FIXME: should we allow this? Are there some anims that you should never be able to chain into an attack?
|
||||
//only curmove that might get in here is LS_NONE, LS_DRAW, LS_PUTAWAY and the LS_R_ returns... all of which are in Q_R
|
||||
newmove = PM_AttackMoveForQuad( saberMoveData[curmove].endQuad );
|
||||
}
|
||||
*/
|
||||
|
||||
if ( newmove != LS_NONE )
|
||||
{
|
||||
//Now get the proper transition move
|
||||
newmove = PM_SaberAnimTransitionAnim( curmove, newmove );
|
||||
// NOTENOTE Had to remove this concept since there is no gent in pmove.
|
||||
/*
|
||||
if ( PM_HasAnimation( pm->gent, saberMoveData[newmove].animToUse ) )
|
||||
*/
|
||||
|
||||
assert( bgGlobalAnimations[saberMoveData[newmove].animToUse].firstFrame != 0 ||
|
||||
bgGlobalAnimations[saberMoveData[newmove].animToUse].numFrames != 0);
|
||||
|
||||
if (1)
|
||||
{
|
||||
anim = saberMoveData[newmove].animToUse;
|
||||
}
|
||||
anim = saberMoveData[newmove].animToUse;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1890,7 +1841,7 @@ weapChecks:
|
|||
}
|
||||
|
||||
if (anim == BOTH_RUN2 && !pm->cmd.forwardmove && !pm->cmd.rightmove)
|
||||
{ //semi-hacky
|
||||
{ //semi-hacky (if not moving on x-y and still playing the running anim, force the player out of it)
|
||||
anim = PM_GetSaberStance();
|
||||
}
|
||||
newmove = LS_READY;
|
||||
|
@ -2021,8 +1972,6 @@ void PM_SetSaberMove(short newMove)
|
|||
!PM_JumpingAnim( pm->ps->legsAnim ) &&
|
||||
!BG_InSpecialJump( pm->ps->legsAnim ) &&
|
||||
anim != PM_GetSaberStance() &&
|
||||
//!PM_CrouchAnim( pm->ps->legsAnim ) &&
|
||||
//pm->cmd.upmove >= 0 &&
|
||||
pm->ps->groundEntityNum != ENTITYNUM_NONE &&
|
||||
!(pm->ps->pm_flags & PMF_DUCKED))
|
||||
{
|
||||
|
@ -2047,7 +1996,7 @@ void PM_SetSaberMove(short newMove)
|
|||
pm->ps->saberMove = newMove;
|
||||
pm->ps->saberBlocking = saberMoveData[newMove].blocking;
|
||||
|
||||
pm->ps->torsoAnim = anim;//saberMoveData[newMove].animToUse;
|
||||
pm->ps->torsoAnim = anim;
|
||||
|
||||
if (pm->ps->weaponTime <= 0)
|
||||
{
|
||||
|
|
|
@ -153,7 +153,7 @@ weaponData_t weaponData[WP_NUM_WEAPONS] =
|
|||
1, // int energyPerShot; // Amount of energy used per shot
|
||||
100, // int fireTime; // Amount of time between firings
|
||||
8192, // int range; // Range of weapon
|
||||
25, // int altEnergyPerShot; // Amount of energy used for alt-fire
|
||||
15, // int altEnergyPerShot; // Amount of energy used for alt-fire
|
||||
800, // int altFireTime; // Amount of time between alt-firings
|
||||
8192, // int altRange; // Range of alt-fire
|
||||
0, // int chargeSubTime; // ms interval for subtracting ammo during charge
|
||||
|
@ -187,7 +187,7 @@ weaponData_t weaponData[WP_NUM_WEAPONS] =
|
|||
10, // int energyPerShot; // Amount of energy used per shot
|
||||
700, // int fireTime; // Amount of time between firings
|
||||
8192, // int range; // Range of weapon
|
||||
25, // int altEnergyPerShot; // Amount of energy used for alt-fire
|
||||
15, // int altEnergyPerShot; // Amount of energy used for alt-fire
|
||||
800, // int altFireTime; // Amount of time between alt-firings
|
||||
8192, // int altRange; // Range of alt-fire
|
||||
0, // int chargeSubTime; // ms interval for subtracting ammo during charge
|
||||
|
|
|
@ -1295,7 +1295,7 @@ void ClientThink_real( gentity_t *ent ) {
|
|||
pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
|
||||
}
|
||||
else if ( ent->r.svFlags & SVF_BOT ) {
|
||||
pm.tracemask = MASK_PLAYERSOLID | CONTENTS_BOTCLIP;
|
||||
pm.tracemask = MASK_PLAYERSOLID | CONTENTS_MONSTERCLIP;
|
||||
}
|
||||
else {
|
||||
pm.tracemask = MASK_PLAYERSOLID;
|
||||
|
@ -1643,7 +1643,7 @@ void ClientThink_real( gentity_t *ent ) {
|
|||
// check for respawning
|
||||
if ( client->ps.stats[STAT_HEALTH] <= 0 ) {
|
||||
// wait for the attack button to be pressed
|
||||
if ( level.time > client->respawnTime ) {
|
||||
if ( level.time > client->respawnTime && !gDoSlowMoDuel ) {
|
||||
// forcerespawn is to prevent users from waiting out powerups
|
||||
if ( g_forcerespawn.integer > 0 &&
|
||||
( level.time - client->respawnTime ) > g_forcerespawn.integer * 1000 ) {
|
||||
|
@ -1656,6 +1656,10 @@ void ClientThink_real( gentity_t *ent ) {
|
|||
respawn( ent );
|
||||
}
|
||||
}
|
||||
else if (gDoSlowMoDuel)
|
||||
{
|
||||
client->respawnTime = level.time + 1000;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1277,7 +1277,10 @@ void ClientUserinfoChanged( int clientNum ) {
|
|||
|
||||
trap_SetConfigstring( CS_PLAYERS+clientNum, s );
|
||||
|
||||
//G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, s );
|
||||
if (g_logClientInfo.integer)
|
||||
{
|
||||
G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, s );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1742,6 +1745,46 @@ void ClientSpawn(gentity_t *ent) {
|
|||
&& !AllForceDisabled( g_forcePowerDisable.integer )
|
||||
&& g_trueJedi.integer )
|
||||
{
|
||||
if ( g_gametype.integer >= GT_TEAM && (client->sess.sessionTeam == TEAM_BLUE || client->sess.sessionTeam == TEAM_RED) )
|
||||
{//In Team games, force one side to be merc and other to be jedi
|
||||
if ( level.numPlayingClients > 0 )
|
||||
{//already someone in the game
|
||||
int i, forceTeam = TEAM_SPECTATOR;
|
||||
for ( i = 0 ; i < level.maxclients ; i++ )
|
||||
{
|
||||
if ( level.clients[i].pers.connected == CON_DISCONNECTED ) {
|
||||
continue;
|
||||
}
|
||||
if ( level.clients[i].sess.sessionTeam == TEAM_BLUE || level.clients[i].sess.sessionTeam == TEAM_RED )
|
||||
{//in-game
|
||||
if ( WP_HasForcePowers( &level.clients[i].ps ) )
|
||||
{//this side is using force
|
||||
forceTeam = level.clients[i].sess.sessionTeam;
|
||||
}
|
||||
else
|
||||
{//other team is using force
|
||||
if ( level.clients[i].sess.sessionTeam == TEAM_BLUE )
|
||||
{
|
||||
forceTeam = TEAM_RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
forceTeam = TEAM_BLUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( WP_HasForcePowers( &client->ps ) && client->sess.sessionTeam != forceTeam )
|
||||
{//using force but not on right team, switch him over
|
||||
const char *teamName = TeamName( forceTeam );
|
||||
//client->sess.sessionTeam = forceTeam;
|
||||
SetTeam( ent, (char *)teamName );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( WP_HasForcePowers( &client->ps ) )
|
||||
{
|
||||
client->ps.trueNonJedi = qfalse;
|
||||
|
@ -1758,13 +1801,23 @@ void ClientSpawn(gentity_t *ent) {
|
|||
{
|
||||
client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BRYAR_PISTOL );
|
||||
}
|
||||
if (!wDisable || !(wDisable & (1 << WP_BLASTER)))
|
||||
{
|
||||
client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BLASTER );
|
||||
}
|
||||
if (!wDisable || !(wDisable & (1 << WP_BOWCASTER)))
|
||||
{
|
||||
client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BOWCASTER );
|
||||
}
|
||||
client->ps.stats[STAT_WEAPONS] &= ~(1 << WP_SABER);
|
||||
client->ps.stats[STAT_WEAPONS] |= (1 << WP_STUN_BATON);
|
||||
client->ps.ammo[AMMO_POWERCELL] = ammoData[AMMO_POWERCELL].max;
|
||||
client->ps.weapon = WP_BRYAR_PISTOL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{//jediVmerc is incompatible with this gametype, turn it off!
|
||||
trap_Cvar_Set( "g_jediVmerc", "0" );
|
||||
if (g_gametype.integer == GT_HOLOCRON)
|
||||
{
|
||||
//always get free saber level 1 in holocron
|
||||
|
|
|
@ -503,8 +503,11 @@ void Cmd_Kill_f( gentity_t *ent ) {
|
|||
|
||||
if (g_gametype.integer == GT_TOURNAMENT && level.numPlayingClients > 1 && !level.warmupTime)
|
||||
{
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "ATTEMPTDUELKILL")) );
|
||||
return;
|
||||
if (!g_allowDuelSuicide.integer)
|
||||
{
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "ATTEMPTDUELKILL")) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ent->flags &= ~FL_GODMODE;
|
||||
|
@ -646,7 +649,7 @@ void SetTeam( gentity_t *ent, char *s ) {
|
|||
//}
|
||||
}
|
||||
|
||||
if ( g_teamForceBalance.integer ) {
|
||||
if ( g_teamForceBalance.integer && !g_trueJedi.integer ) {
|
||||
int counts[TEAM_NUM_TEAMS];
|
||||
|
||||
counts[TEAM_BLUE] = TeamCount( ent->client->ps.clientNum, TEAM_BLUE );
|
||||
|
@ -1407,6 +1410,109 @@ static const char *gameNames[] = {
|
|||
"Capture the Ysalamiri"
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
G_ClientNumberFromName
|
||||
|
||||
Finds the client number of the client with the given name
|
||||
==================
|
||||
*/
|
||||
int G_ClientNumberFromName ( const char* name )
|
||||
{
|
||||
char s2[MAX_STRING_CHARS];
|
||||
char n2[MAX_STRING_CHARS];
|
||||
int i;
|
||||
gclient_t* cl;
|
||||
|
||||
// check for a name match
|
||||
SanitizeString( (char*)name, s2 );
|
||||
for ( i=0, cl=level.clients ; i < level.numConnectedClients ; i++, cl++ )
|
||||
{
|
||||
SanitizeString( cl->pers.netname, n2 );
|
||||
if ( !strcmp( n2, s2 ) )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SanitizeString2
|
||||
|
||||
Rich's revised version of SanitizeString
|
||||
==================
|
||||
*/
|
||||
void SanitizeString2( char *in, char *out )
|
||||
{
|
||||
int i = 0;
|
||||
int r = 0;
|
||||
|
||||
while (in[i])
|
||||
{
|
||||
if (i >= MAX_NAME_LENGTH-1)
|
||||
{ //the ui truncates the name here..
|
||||
break;
|
||||
}
|
||||
|
||||
if (in[i] == '^')
|
||||
{
|
||||
if (in[i+1] >= 48 && //'0'
|
||||
in[i+1] <= 57) //'9'
|
||||
{ //only skip it if there's a number after it for the color
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{ //just skip the ^
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (in[i] < 32)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
out[r] = in[i];
|
||||
r++;
|
||||
i++;
|
||||
}
|
||||
out[r] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
G_ClientNumberFromStrippedName
|
||||
|
||||
Same as above, but strips special characters out of the names before comparing.
|
||||
==================
|
||||
*/
|
||||
int G_ClientNumberFromStrippedName ( const char* name )
|
||||
{
|
||||
char s2[MAX_STRING_CHARS];
|
||||
char n2[MAX_STRING_CHARS];
|
||||
int i;
|
||||
gclient_t* cl;
|
||||
|
||||
// check for a name match
|
||||
SanitizeString2( (char*)name, s2 );
|
||||
for ( i=0, cl=level.clients ; i < level.numConnectedClients ; i++, cl++ )
|
||||
{
|
||||
SanitizeString2( cl->pers.netname, n2 );
|
||||
if ( !strcmp( n2, s2 ) )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Cmd_CallVote_f
|
||||
|
@ -1466,7 +1572,8 @@ void Cmd_CallVote_f( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
// special case for g_gametype, check for bad values
|
||||
if ( !Q_stricmp( arg1, "g_gametype" ) ) {
|
||||
if ( !Q_stricmp( arg1, "g_gametype" ) )
|
||||
{
|
||||
i = atoi( arg2 );
|
||||
if( i == GT_SINGLE_PLAYER || i < GT_FFA || i >= GT_MAX_GAME_TYPE) {
|
||||
trap_SendServerCommand( ent-g_entities, "print \"Invalid gametype.\n\"" );
|
||||
|
@ -1478,7 +1585,9 @@ void Cmd_CallVote_f( gentity_t *ent ) {
|
|||
|
||||
Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i );
|
||||
Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s %s", arg1, gameNames[i] );
|
||||
} else if ( !Q_stricmp( arg1, "map" ) ) {
|
||||
}
|
||||
else if ( !Q_stricmp( arg1, "map" ) )
|
||||
{
|
||||
// special case for map changes, we want to reset the nextmap setting
|
||||
// this allows a player to change maps, but not upset the map rotation
|
||||
char s[MAX_STRING_CHARS];
|
||||
|
@ -1497,7 +1606,46 @@ void Cmd_CallVote_f( gentity_t *ent ) {
|
|||
Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 );
|
||||
}
|
||||
Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
|
||||
} else if ( !Q_stricmp( arg1, "nextmap" ) ) {
|
||||
}
|
||||
else if ( !Q_stricmp ( arg1, "clientkick" ) )
|
||||
{
|
||||
int n = atoi ( arg2 );
|
||||
|
||||
if ( n < 0 || n >= MAX_CLIENTS )
|
||||
{
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"invalid client number %d.\n\"", n ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( g_entities[n].client->pers.connected == CON_DISCONNECTED )
|
||||
{
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"there is no client with the client number %d.\n\"", n ) );
|
||||
return;
|
||||
}
|
||||
|
||||
Com_sprintf ( level.voteString, sizeof(level.voteString ), "%s %s", arg1, arg2 );
|
||||
Com_sprintf ( level.voteDisplayString, sizeof(level.voteDisplayString), "kick %s", g_entities[n].client->pers.netname );
|
||||
}
|
||||
else if ( !Q_stricmp ( arg1, "kick" ) )
|
||||
{
|
||||
int clientid = G_ClientNumberFromName ( arg2 );
|
||||
|
||||
if ( clientid == -1 )
|
||||
{
|
||||
clientid = G_ClientNumberFromStrippedName(arg2);
|
||||
|
||||
if (clientid == -1)
|
||||
{
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"there is no client named '%s' currently on the server.\n\"", arg2 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Com_sprintf ( level.voteString, sizeof(level.voteString ), "clientkick %d", clientid );
|
||||
Com_sprintf ( level.voteDisplayString, sizeof(level.voteDisplayString), "kick %s", g_entities[clientid].client->pers.netname );
|
||||
}
|
||||
else if ( !Q_stricmp( arg1, "nextmap" ) )
|
||||
{
|
||||
char s[MAX_STRING_CHARS];
|
||||
|
||||
trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof(s) );
|
||||
|
@ -1507,7 +1655,9 @@ void Cmd_CallVote_f( gentity_t *ent ) {
|
|||
}
|
||||
Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr nextmap");
|
||||
Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_sprintf( level.voteString, sizeof( level.voteString ), "%s \"%s\"", arg1, arg2 );
|
||||
Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
|
||||
}
|
||||
|
@ -2174,9 +2324,10 @@ void Cmd_EngageDuel_f(gentity_t *ent)
|
|||
}
|
||||
}
|
||||
|
||||
void PM_SetAnim(int setAnimParts,int anim,int setAnimFlags, int blendTime);
|
||||
|
||||
#ifdef _DEBUG
|
||||
extern stringID_table_t animTable[MAX_ANIMATIONS+1];
|
||||
void PM_SetAnim(int setAnimParts,int anim,int setAnimFlags, int blendTime);
|
||||
|
||||
void Cmd_DebugSetSaberMove_f(gentity_t *self)
|
||||
{
|
||||
|
@ -2206,7 +2357,7 @@ void Cmd_DebugSetSaberMove_f(gentity_t *self)
|
|||
Com_Printf("Anim for move: %s\n", animTable[saberMoveData[self->client->ps.saberMove].animToUse].name);
|
||||
}
|
||||
|
||||
void Cmd_DebugSetBodyAnim_f(gentity_t *self)
|
||||
void Cmd_DebugSetBodyAnim_f(gentity_t *self, int flags)
|
||||
{
|
||||
int argNum = trap_Argc();
|
||||
char arg[MAX_STRING_CHARS];
|
||||
|
@ -2249,12 +2400,28 @@ void Cmd_DebugSetBodyAnim_f(gentity_t *self)
|
|||
pmv.gametype = g_gametype.integer;
|
||||
|
||||
pm = &pmv;
|
||||
PM_SetAnim(SETANIM_BOTH, i, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
|
||||
PM_SetAnim(SETANIM_BOTH, i, flags, 0);
|
||||
|
||||
Com_Printf("Set body anim to %s\n", arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
void StandardSetBodyAnim(gentity_t *self, int anim, int flags)
|
||||
{
|
||||
pmove_t pmv;
|
||||
|
||||
memset (&pmv, 0, sizeof(pmv));
|
||||
pmv.ps = &self->client->ps;
|
||||
pmv.animations = bgGlobalAnimations;
|
||||
pmv.cmd = self->client->pers.cmd;
|
||||
pmv.trace = trap_Trace;
|
||||
pmv.pointcontents = trap_PointContents;
|
||||
pmv.gametype = g_gametype.integer;
|
||||
|
||||
pm = &pmv;
|
||||
PM_SetAnim(SETANIM_BOTH, anim, flags, 0);
|
||||
}
|
||||
|
||||
void DismembermentTest(gentity_t *self);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
@ -2478,6 +2645,7 @@ void ClientCommand( int clientNum ) {
|
|||
*/
|
||||
//I broke the ATST when I restructured it to use a single global anim set for all client animation.
|
||||
//You can fix it, but you'll have to implement unique animations (per character) again.
|
||||
#ifdef _DEBUG //sigh..
|
||||
else if (Q_stricmp(cmd, "headexplodey") == 0 && CheatsOk( ent ))
|
||||
{
|
||||
Cmd_Kill_f (ent);
|
||||
|
@ -2493,6 +2661,67 @@ void ClientCommand( int clientNum ) {
|
|||
{
|
||||
G_CreateExampleAnimEnt(ent);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "loveandpeace") == 0 && CheatsOk( ent ))
|
||||
{
|
||||
trace_t tr;
|
||||
vec3_t fPos;
|
||||
|
||||
AngleVectors(ent->client->ps.viewangles, fPos, 0, 0);
|
||||
|
||||
fPos[0] = ent->client->ps.origin[0] + fPos[0]*40;
|
||||
fPos[1] = ent->client->ps.origin[1] + fPos[1]*40;
|
||||
fPos[2] = ent->client->ps.origin[2] + fPos[2]*40;
|
||||
|
||||
trap_Trace(&tr, ent->client->ps.origin, 0, 0, fPos, ent->s.number, ent->clipmask);
|
||||
|
||||
if (tr.entityNum < MAX_CLIENTS && tr.entityNum != ent->s.number)
|
||||
{
|
||||
gentity_t *other = &g_entities[tr.entityNum];
|
||||
|
||||
if (other && other->inuse && other->client)
|
||||
{
|
||||
vec3_t entDir;
|
||||
vec3_t otherDir;
|
||||
vec3_t entAngles;
|
||||
vec3_t otherAngles;
|
||||
|
||||
if (ent->client->ps.weapon == WP_SABER && !ent->client->ps.saberHolstered)
|
||||
{
|
||||
Cmd_ToggleSaber_f(ent);
|
||||
}
|
||||
|
||||
if (other->client->ps.weapon == WP_SABER && !other->client->ps.saberHolstered)
|
||||
{
|
||||
Cmd_ToggleSaber_f(other);
|
||||
}
|
||||
|
||||
if ((ent->client->ps.weapon != WP_SABER || ent->client->ps.saberHolstered) &&
|
||||
(other->client->ps.weapon != WP_SABER || other->client->ps.saberHolstered))
|
||||
{
|
||||
VectorSubtract( other->client->ps.origin, ent->client->ps.origin, otherDir );
|
||||
VectorCopy( ent->client->ps.viewangles, entAngles );
|
||||
entAngles[YAW] = vectoyaw( otherDir );
|
||||
SetClientViewAngle( ent, entAngles );
|
||||
|
||||
StandardSetBodyAnim(ent, BOTH_KISSER1LOOP, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_HOLDLESS);
|
||||
ent->client->ps.saberMove = LS_NONE;
|
||||
ent->client->ps.saberBlocked = 0;
|
||||
ent->client->ps.saberBlocking = 0;
|
||||
|
||||
VectorSubtract( ent->client->ps.origin, other->client->ps.origin, entDir );
|
||||
VectorCopy( other->client->ps.viewangles, otherAngles );
|
||||
otherAngles[YAW] = vectoyaw( entDir );
|
||||
SetClientViewAngle( other, otherAngles );
|
||||
|
||||
StandardSetBodyAnim(other, BOTH_KISSEE1LOOP, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_HOLDLESS);
|
||||
other->client->ps.saberMove = LS_NONE;
|
||||
other->client->ps.saberBlocked = 0;
|
||||
other->client->ps.saberBlocking = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (Q_stricmp(cmd, "thedestroyer") == 0 && CheatsOk( ent ) && ent && ent->client && ent->client->ps.saberHolstered && ent->client->ps.weapon == WP_SABER)
|
||||
{
|
||||
Cmd_ToggleSaber_f(ent);
|
||||
|
@ -2521,7 +2750,7 @@ void ClientCommand( int clientNum ) {
|
|||
}
|
||||
else if (Q_stricmp(cmd, "debugSetBodyAnim") == 0)
|
||||
{
|
||||
Cmd_DebugSetBodyAnim_f(ent);
|
||||
Cmd_DebugSetBodyAnim_f(ent, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD);
|
||||
}
|
||||
else if (Q_stricmp(cmd, "debugDismemberment") == 0)
|
||||
{
|
||||
|
@ -2544,6 +2773,21 @@ void ClientCommand( int clientNum ) {
|
|||
DismembermentByNum(ent, iArg);
|
||||
}
|
||||
}
|
||||
else if (Q_stricmp(cmd, "debugKnockMeDown") == 0)
|
||||
{
|
||||
ent->client->ps.forceHandExtend = HANDEXTEND_KNOCKDOWN;
|
||||
ent->client->ps.forceDodgeAnim = 0;
|
||||
if (trap_Argc() > 1)
|
||||
{
|
||||
ent->client->ps.forceHandExtendTime = level.time + 1100;
|
||||
ent->client->ps.quickerGetup = qfalse;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->client->ps.forceHandExtendTime = level.time + 700;
|
||||
ent->client->ps.quickerGetup = qtrue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
else
|
||||
|
|
|
@ -890,6 +890,527 @@ void CheckAlmostCapture( gentity_t *self, gentity_t *attacker ) {
|
|||
#endif
|
||||
}
|
||||
|
||||
qboolean G_InKnockDown( playerState_t *ps )
|
||||
{
|
||||
switch ( (ps->legsAnim&~ANIM_TOGGLEBIT) )
|
||||
{
|
||||
case BOTH_KNOCKDOWN1:
|
||||
case BOTH_KNOCKDOWN2:
|
||||
case BOTH_KNOCKDOWN3:
|
||||
case BOTH_KNOCKDOWN4:
|
||||
case BOTH_KNOCKDOWN5:
|
||||
return qtrue;
|
||||
break;
|
||||
case BOTH_GETUP1:
|
||||
case BOTH_GETUP2:
|
||||
case BOTH_GETUP3:
|
||||
case BOTH_GETUP4:
|
||||
case BOTH_GETUP5:
|
||||
case BOTH_FORCE_GETUP_F1:
|
||||
case BOTH_FORCE_GETUP_F2:
|
||||
case BOTH_FORCE_GETUP_B1:
|
||||
case BOTH_FORCE_GETUP_B2:
|
||||
case BOTH_FORCE_GETUP_B3:
|
||||
case BOTH_FORCE_GETUP_B4:
|
||||
case BOTH_FORCE_GETUP_B5:
|
||||
return qtrue;
|
||||
break;
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static int G_CheckSpecialDeathAnim( gentity_t *self, vec3_t point, int damage, int mod, int hitLoc )
|
||||
{
|
||||
int deathAnim = -1;
|
||||
|
||||
if ( BG_InRoll( &self->client->ps, self->client->ps.legsAnim ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH_ROLL; //# Death anim from a roll
|
||||
}
|
||||
else if ( BG_FlippingAnim( self->client->ps.legsAnim ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH_FLIP; //# Death anim from a flip
|
||||
}
|
||||
else if ( G_InKnockDown( &self->client->ps ) )
|
||||
{//since these happen a lot, let's handle them case by case
|
||||
int animLength = bgGlobalAnimations[self->client->ps.legsAnim&~ANIM_TOGGLEBIT].numFrames * fabs(bgGlobalAnimations[self->client->ps.legsAnim&~ANIM_TOGGLEBIT].frameLerp);
|
||||
switch ( self->client->ps.legsAnim&~ANIM_TOGGLEBIT )
|
||||
{
|
||||
case BOTH_KNOCKDOWN1:
|
||||
if ( animLength - self->client->ps.legsTimer > 100 )
|
||||
{//on our way down
|
||||
if ( self->client->ps.legsTimer > 600 )
|
||||
{//still partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_KNOCKDOWN2:
|
||||
if ( animLength - self->client->ps.legsTimer > 700 )
|
||||
{//on our way down
|
||||
if ( self->client->ps.legsTimer > 600 )
|
||||
{//still partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_KNOCKDOWN3:
|
||||
if ( animLength - self->client->ps.legsTimer > 100 )
|
||||
{//on our way down
|
||||
if ( self->client->ps.legsTimer > 1300 )
|
||||
{//still partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_DN;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_DN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_KNOCKDOWN4:
|
||||
if ( animLength - self->client->ps.legsTimer > 300 )
|
||||
{//on our way down
|
||||
if ( self->client->ps.legsTimer > 350 )
|
||||
{//still partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{//crouch death
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_KNOCKDOWN5:
|
||||
if ( self->client->ps.legsTimer < 750 )
|
||||
{//flat
|
||||
deathAnim = BOTH_DEATH_LYING_DN;
|
||||
}
|
||||
break;
|
||||
case BOTH_GETUP1:
|
||||
if ( self->client->ps.legsTimer < 350 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 800 )
|
||||
{//crouching
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 450 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_GETUP2:
|
||||
if ( self->client->ps.legsTimer < 150 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 850 )
|
||||
{//crouching
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 500 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_GETUP3:
|
||||
if ( self->client->ps.legsTimer < 250 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 600 )
|
||||
{//crouching
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 150 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_DN;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_DN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_GETUP4:
|
||||
if ( self->client->ps.legsTimer < 250 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 600 )
|
||||
{//crouching
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 850 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_DN;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_GETUP5:
|
||||
if ( self->client->ps.legsTimer > 850 )
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 1500 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_DN;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_DN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_GETUP_CROUCH_B1:
|
||||
if ( self->client->ps.legsTimer < 800 )
|
||||
{//crouching
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 400 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_GETUP_CROUCH_F1:
|
||||
if ( self->client->ps.legsTimer < 800 )
|
||||
{//crouching
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 150 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_DN;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_DN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_FORCE_GETUP_B1:
|
||||
if ( self->client->ps.legsTimer < 325 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 725 )
|
||||
{//spinning up
|
||||
deathAnim = BOTH_DEATH_SPIN_180; //# Death anim when facing backwards
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 900 )
|
||||
{//crouching
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 50 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_FORCE_GETUP_B2:
|
||||
if ( self->client->ps.legsTimer < 575 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 875 )
|
||||
{//spinning up
|
||||
deathAnim = BOTH_DEATH_SPIN_180; //# Death anim when facing backwards
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 900 )
|
||||
{//crouching
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
break;
|
||||
case BOTH_FORCE_GETUP_B3:
|
||||
if ( self->client->ps.legsTimer < 150 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 775 )
|
||||
{//flipping
|
||||
deathAnim = BOTH_DEATHBACKWARD2; //backflip
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
break;
|
||||
case BOTH_FORCE_GETUP_B4:
|
||||
if ( self->client->ps.legsTimer < 325 )
|
||||
{//standing up
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 150 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_FORCE_GETUP_B5:
|
||||
if ( self->client->ps.legsTimer < 550 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 1025 )
|
||||
{//kicking up
|
||||
deathAnim = BOTH_DEATHBACKWARD2; //backflip
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 50 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_FORCE_GETUP_B6:
|
||||
if ( self->client->ps.legsTimer < 225 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 425 )
|
||||
{//crouching up
|
||||
vec3_t fwd;
|
||||
float thrown = 0;
|
||||
|
||||
AngleVectors( self->client->ps.viewangles, fwd, NULL, NULL );
|
||||
thrown = DotProduct( fwd, self->client->ps.velocity );
|
||||
|
||||
if ( thrown < -150 )
|
||||
{
|
||||
deathAnim = BOTH_DEATHBACKWARD1; //# Death anim when crouched and thrown back
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH_CROUCHED; //# Death anim when crouched
|
||||
}
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 825 )
|
||||
{//flipping up
|
||||
deathAnim = BOTH_DEATHFORWARD3; //backflip
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 225 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_UP;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_UP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_FORCE_GETUP_F1:
|
||||
if ( self->client->ps.legsTimer < 275 )
|
||||
{//standing up
|
||||
}
|
||||
else if ( self->client->ps.legsTimer < 750 )
|
||||
{//flipping
|
||||
deathAnim = BOTH_DEATH14;
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 100 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_DN;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_DN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOTH_FORCE_GETUP_F2:
|
||||
if ( self->client->ps.legsTimer < 1200 )
|
||||
{//standing
|
||||
}
|
||||
else
|
||||
{//lying down
|
||||
if ( animLength - self->client->ps.legsTimer > 225 )
|
||||
{//partially up
|
||||
deathAnim = BOTH_DEATH_FALLING_DN;
|
||||
}
|
||||
else
|
||||
{//down
|
||||
deathAnim = BOTH_DEATH_LYING_DN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return deathAnim;
|
||||
}
|
||||
|
||||
int G_PickDeathAnim( gentity_t *self, vec3_t point, int damage, int mod, int hitLoc )
|
||||
{//FIXME: play dead flop anims on body if in an appropriate _DEAD anim when this func is called
|
||||
int deathAnim = -1;
|
||||
|
@ -1036,63 +1557,36 @@ int G_PickDeathAnim( gentity_t *self, vec3_t point, int damage, int mod, int hit
|
|||
}
|
||||
if ( deathAnim == -1 )
|
||||
{
|
||||
//death anims
|
||||
switch( hitLoc )
|
||||
if (self->client)
|
||||
{
|
||||
case HL_FOOT_RT:
|
||||
case HL_FOOT_LT:
|
||||
if ( mod == MOD_SABER && !Q_irand( 0, 2 ) )
|
||||
{
|
||||
return BOTH_DEATH10;//chest: back flip
|
||||
}
|
||||
else if ( !Q_irand( 0, 2 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH4;//back: forward
|
||||
}
|
||||
else if ( !Q_irand( 0, 1 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH5;//same as 4
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH15;//back: forward
|
||||
}
|
||||
break;
|
||||
case HL_LEG_RT:
|
||||
if ( !Q_irand( 0, 2 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH4;//back: forward
|
||||
}
|
||||
else if ( !Q_irand( 0, 1 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH5;//same as 4
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH15;//back: forward
|
||||
}
|
||||
break;
|
||||
case HL_LEG_LT:
|
||||
if ( !Q_irand( 0, 2 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH4;//back: forward
|
||||
}
|
||||
else if ( !Q_irand( 0, 1 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH5;//same as 4
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH15;//back: forward
|
||||
}
|
||||
break;
|
||||
case HL_BACK:
|
||||
if ( !VectorLengthSquared( objVelocity ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH17;//head/back: croak
|
||||
}
|
||||
else
|
||||
deathAnim = G_CheckSpecialDeathAnim( self, point, damage, mod, hitLoc );
|
||||
}
|
||||
|
||||
if (deathAnim == -1)
|
||||
{
|
||||
//death anims
|
||||
switch( hitLoc )
|
||||
{
|
||||
case HL_FOOT_RT:
|
||||
case HL_FOOT_LT:
|
||||
if ( mod == MOD_SABER && !Q_irand( 0, 2 ) )
|
||||
{
|
||||
return BOTH_DEATH10;//chest: back flip
|
||||
}
|
||||
else if ( !Q_irand( 0, 2 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH4;//back: forward
|
||||
}
|
||||
else if ( !Q_irand( 0, 1 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH5;//same as 4
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH15;//back: forward
|
||||
}
|
||||
break;
|
||||
case HL_LEG_RT:
|
||||
if ( !Q_irand( 0, 2 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH4;//back: forward
|
||||
|
@ -1105,135 +1599,170 @@ int G_PickDeathAnim( gentity_t *self, vec3_t point, int damage, int mod, int hit
|
|||
{
|
||||
deathAnim = BOTH_DEATH15;//back: forward
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HL_CHEST_RT:
|
||||
case HL_ARM_RT:
|
||||
case HL_HAND_RT:
|
||||
case HL_BACK_RT:
|
||||
if ( damage <= max_health*0.25 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH9;//chest right: snap, fall forward
|
||||
}
|
||||
else if ( damage <= max_health*0.5 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH3;//chest right: back
|
||||
}
|
||||
else if ( damage <= max_health*0.75 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH6;//chest right: spin
|
||||
}
|
||||
else
|
||||
{
|
||||
//TEMP HACK: play spinny deaths less often
|
||||
if ( Q_irand( 0, 1 ) )
|
||||
break;
|
||||
case HL_LEG_LT:
|
||||
if ( !Q_irand( 0, 2 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH8;//chest right: spin high
|
||||
deathAnim = BOTH_DEATH4;//back: forward
|
||||
}
|
||||
else if ( !Q_irand( 0, 1 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH5;//same as 4
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( Q_irand( 0, 2 ) )
|
||||
deathAnim = BOTH_DEATH15;//back: forward
|
||||
}
|
||||
break;
|
||||
case HL_BACK:
|
||||
if ( !VectorLengthSquared( objVelocity ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH17;//head/back: croak
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !Q_irand( 0, 2 ) )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
deathAnim = BOTH_DEATH9;//chest right: snap, fall forward
|
||||
break;
|
||||
case 1:
|
||||
deathAnim = BOTH_DEATH3;//chest right: back
|
||||
break;
|
||||
case 2:
|
||||
deathAnim = BOTH_DEATH6;//chest right: spin
|
||||
break;
|
||||
deathAnim = BOTH_DEATH4;//back: forward
|
||||
}
|
||||
else if ( !Q_irand( 0, 1 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH5;//same as 4
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH15;//back: forward
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HL_CHEST_LT:
|
||||
case HL_ARM_LT:
|
||||
case HL_HAND_LT:
|
||||
case HL_BACK_LT:
|
||||
if ( damage <= max_health*0.25 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH11;//chest left: snap, fall forward
|
||||
}
|
||||
else if ( damage <= max_health*0.5 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH7;//chest left: back
|
||||
}
|
||||
else if ( damage <= max_health*0.75 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH12;//chest left: spin
|
||||
}
|
||||
else
|
||||
{
|
||||
//TEMP HACK: play spinny deaths less often
|
||||
if ( Q_irand( 0, 1 ) )
|
||||
break;
|
||||
case HL_CHEST_RT:
|
||||
case HL_ARM_RT:
|
||||
case HL_HAND_RT:
|
||||
case HL_BACK_RT:
|
||||
if ( damage <= max_health*0.25 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH14;//chest left: spin high
|
||||
deathAnim = BOTH_DEATH9;//chest right: snap, fall forward
|
||||
}
|
||||
else
|
||||
else if ( damage <= max_health*0.5 )
|
||||
{
|
||||
switch ( Q_irand( 0, 2 ) )
|
||||
deathAnim = BOTH_DEATH3;//chest right: back
|
||||
}
|
||||
else if ( damage <= max_health*0.75 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH6;//chest right: spin
|
||||
}
|
||||
else
|
||||
{
|
||||
//TEMP HACK: play spinny deaths less often
|
||||
if ( Q_irand( 0, 1 ) )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
deathAnim = BOTH_DEATH11;//chest left: snap, fall forward
|
||||
break;
|
||||
case 1:
|
||||
deathAnim = BOTH_DEATH7;//chest left: back
|
||||
break;
|
||||
case 2:
|
||||
deathAnim = BOTH_DEATH12;//chest left: spin
|
||||
break;
|
||||
deathAnim = BOTH_DEATH8;//chest right: spin high
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( Q_irand( 0, 2 ) )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
deathAnim = BOTH_DEATH9;//chest right: snap, fall forward
|
||||
break;
|
||||
case 1:
|
||||
deathAnim = BOTH_DEATH3;//chest right: back
|
||||
break;
|
||||
case 2:
|
||||
deathAnim = BOTH_DEATH6;//chest right: spin
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HL_CHEST:
|
||||
case HL_WAIST:
|
||||
if ( damage <= max_health*0.25 || !VectorLengthSquared( objVelocity ) )
|
||||
{
|
||||
if ( !Q_irand( 0, 1 ) )
|
||||
break;
|
||||
case HL_CHEST_LT:
|
||||
case HL_ARM_LT:
|
||||
case HL_HAND_LT:
|
||||
case HL_BACK_LT:
|
||||
if ( damage <= max_health*0.25 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH18;//gut: fall right
|
||||
deathAnim = BOTH_DEATH11;//chest left: snap, fall forward
|
||||
}
|
||||
else if ( damage <= max_health*0.5 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH7;//chest left: back
|
||||
}
|
||||
else if ( damage <= max_health*0.75 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH12;//chest left: spin
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH19;//gut: fall left
|
||||
//TEMP HACK: play spinny deaths less often
|
||||
if ( Q_irand( 0, 1 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH14;//chest left: spin high
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( Q_irand( 0, 2 ) )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
deathAnim = BOTH_DEATH11;//chest left: snap, fall forward
|
||||
break;
|
||||
case 1:
|
||||
deathAnim = BOTH_DEATH7;//chest left: back
|
||||
break;
|
||||
case 2:
|
||||
deathAnim = BOTH_DEATH12;//chest left: spin
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( damage <= max_health*0.5 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH2;//chest: backward short
|
||||
}
|
||||
else if ( damage <= max_health*0.75 )
|
||||
{
|
||||
if ( !Q_irand( 0, 1 ) )
|
||||
break;
|
||||
case HL_CHEST:
|
||||
case HL_WAIST:
|
||||
if ( damage <= max_health*0.25 || !VectorLengthSquared( objVelocity ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH1;//chest: backward med
|
||||
if ( !Q_irand( 0, 1 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH18;//gut: fall right
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH19;//gut: fall left
|
||||
}
|
||||
}
|
||||
else if ( damage <= max_health*0.5 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH2;//chest: backward short
|
||||
}
|
||||
else if ( damage <= max_health*0.75 )
|
||||
{
|
||||
if ( !Q_irand( 0, 1 ) )
|
||||
{
|
||||
deathAnim = BOTH_DEATH1;//chest: backward med
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH16;//same as 1
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH16;//same as 1
|
||||
deathAnim = BOTH_DEATH10;//chest: back flip
|
||||
}
|
||||
break;
|
||||
case HL_HEAD:
|
||||
if ( damage <= max_health*0.5 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH17;//head/back: croak
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH13;//head: stumble, fall back
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH10;//chest: back flip
|
||||
}
|
||||
break;
|
||||
case HL_HEAD:
|
||||
if ( damage <= max_health*0.5 )
|
||||
{
|
||||
deathAnim = BOTH_DEATH17;//head/back: croak
|
||||
}
|
||||
else
|
||||
{
|
||||
deathAnim = BOTH_DEATH13;//head: stumble, fall back
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return deathAnim;
|
||||
|
@ -1282,6 +1811,15 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
|||
return;
|
||||
}
|
||||
|
||||
if (g_slowmoDuelEnd.integer && g_gametype.integer == GT_TOURNAMENT && attacker && attacker->inuse && attacker->client)
|
||||
{
|
||||
if (!gDoSlowMoDuel)
|
||||
{
|
||||
gDoSlowMoDuel = qtrue;
|
||||
gSlowMoDuelTime = level.time;
|
||||
}
|
||||
}
|
||||
|
||||
if (inflictor && inflictor->activator && !inflictor->client && !attacker->client &&
|
||||
inflictor->activator->client && inflictor->activator->inuse &&
|
||||
inflictor->s.weapon == WP_TURRET)
|
||||
|
@ -2180,7 +2718,7 @@ void G_Dismember( gentity_t *ent, vec3_t point, int limbType, float limbRollBase
|
|||
else
|
||||
{
|
||||
limb->s.modelindex = -1;
|
||||
limb->s.modelindex2 = ent->s.number;
|
||||
limb->s.otherEntityNum2 = ent->s.number;
|
||||
}
|
||||
|
||||
trap_LinkEntity( limb );
|
||||
|
@ -2610,7 +3148,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
}
|
||||
|
||||
|
||||
if ( g_trueJedi.integer )
|
||||
if ( g_trueJedi.integer && client )
|
||||
{//less explosive damage for jedi, more saber damage for non-jedi
|
||||
if ( client->ps.trueJedi )
|
||||
{//if the target is a trueJedi, reduce splash and explosive damage to 1/2
|
||||
|
@ -2629,7 +3167,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
case MOD_TRIP_MINE_SPLASH:
|
||||
case MOD_TIMED_MINE_SPLASH:
|
||||
case MOD_DET_PACK_SPLASH:
|
||||
damage *= 0.5;
|
||||
damage *= 0.75;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -792,6 +792,8 @@ void DeathmatchScoreboardMessage (gentity_t *client);
|
|||
// g_main.c
|
||||
//
|
||||
extern vmCvar_t g_ff_objectives;
|
||||
extern qboolean gDoSlowMoDuel;
|
||||
extern int gSlowMoDuelTime;
|
||||
|
||||
void FindIntermissionPoint( void );
|
||||
void SetLeader(int team, int client);
|
||||
|
@ -964,10 +966,22 @@ extern vmCvar_t g_saberGhoul2Collision;
|
|||
extern vmCvar_t g_saberAlwaysBoxTrace;
|
||||
extern vmCvar_t g_saberBoxTraceSize;
|
||||
|
||||
extern vmCvar_t g_logClientInfo;
|
||||
|
||||
extern vmCvar_t g_slowmoDuelEnd;
|
||||
|
||||
extern vmCvar_t g_saberDamageScale;
|
||||
|
||||
extern vmCvar_t g_useWhileThrowing;
|
||||
|
||||
extern vmCvar_t g_forceRegenTime;
|
||||
extern vmCvar_t g_spawnInvulnerability;
|
||||
extern vmCvar_t g_forcePowerDisable;
|
||||
extern vmCvar_t g_weaponDisable;
|
||||
|
||||
extern vmCvar_t g_allowDuelSuicide;
|
||||
extern vmCvar_t g_fraglimitVoteCorrection;
|
||||
|
||||
extern vmCvar_t g_duelWeaponDisable;
|
||||
extern vmCvar_t g_fraglimit;
|
||||
extern vmCvar_t g_duel_fraglimit;
|
||||
|
|
|
@ -40,11 +40,21 @@ vmCvar_t g_saberGhoul2Collision;
|
|||
vmCvar_t g_saberAlwaysBoxTrace;
|
||||
vmCvar_t g_saberBoxTraceSize;
|
||||
|
||||
vmCvar_t g_logClientInfo;
|
||||
|
||||
vmCvar_t g_slowmoDuelEnd;
|
||||
|
||||
vmCvar_t g_saberDamageScale;
|
||||
|
||||
vmCvar_t g_useWhileThrowing;
|
||||
|
||||
vmCvar_t g_forceRegenTime;
|
||||
vmCvar_t g_spawnInvulnerability;
|
||||
vmCvar_t g_forcePowerDisable;
|
||||
vmCvar_t g_weaponDisable;
|
||||
vmCvar_t g_duelWeaponDisable;
|
||||
vmCvar_t g_allowDuelSuicide;
|
||||
vmCvar_t g_fraglimitVoteCorrection;
|
||||
vmCvar_t g_fraglimit;
|
||||
vmCvar_t g_duel_fraglimit;
|
||||
vmCvar_t g_timelimit;
|
||||
|
@ -136,7 +146,7 @@ static cvarTable_t gameCvarTable[] = {
|
|||
// change anytime vars
|
||||
{ &g_ff_objectives, "g_ff_objectives", "0", /*CVAR_SERVERINFO |*/ CVAR_NORESTART, 0, qtrue },
|
||||
|
||||
{ &g_trueJedi, "g_jediVmerc", "0", CVAR_INTERNAL |CVAR_SERVERINFO | CVAR_LATCH, 0, qtrue },
|
||||
{ &g_trueJedi, "g_jediVmerc", "0", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qtrue },
|
||||
|
||||
{ &g_autoMapCycle, "g_autoMapCycle", "0", CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
|
||||
{ &g_dmflags, "dmflags", "0", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue },
|
||||
|
@ -154,6 +164,14 @@ static cvarTable_t gameCvarTable[] = {
|
|||
{ &g_saberAlwaysBoxTrace, "g_saberAlwaysBoxTrace", "0", 0, 0, qtrue },
|
||||
{ &g_saberBoxTraceSize, "g_saberBoxTraceSize", "2", 0, 0, qtrue },
|
||||
|
||||
{ &g_logClientInfo, "g_logClientInfo", "0", CVAR_ARCHIVE, 0, qtrue },
|
||||
|
||||
{ &g_slowmoDuelEnd, "g_slowmoDuelEnd", "0", CVAR_ARCHIVE, 0, qtrue },
|
||||
|
||||
{ &g_saberDamageScale, "g_saberDamageScale", "1", CVAR_ARCHIVE, 0, qtrue },
|
||||
|
||||
{ &g_useWhileThrowing, "g_useWhileThrowing", "1", 0, 0, qtrue },
|
||||
|
||||
{ &g_forceRegenTime, "g_forceRegenTime", "200", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue },
|
||||
|
||||
{ &g_spawnInvulnerability, "g_spawnInvulnerability", "3000", CVAR_ARCHIVE, 0, qtrue },
|
||||
|
@ -162,6 +180,10 @@ static cvarTable_t gameCvarTable[] = {
|
|||
{ &g_weaponDisable, "g_weaponDisable", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH, 0, qtrue },
|
||||
{ &g_duelWeaponDisable, "g_duelWeaponDisable", "1", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH, 0, qtrue },
|
||||
|
||||
{ &g_allowDuelSuicide, "g_allowDuelSuicide", "0", CVAR_ARCHIVE, 0, qtrue },
|
||||
|
||||
{ &g_fraglimitVoteCorrection, "g_fraglimitVoteCorrection", "1", CVAR_ARCHIVE, 0, qtrue },
|
||||
|
||||
{ &g_fraglimit, "fraglimit", "20", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
|
||||
{ &g_duel_fraglimit, "duel_fraglimit", "10", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
|
||||
{ &g_timelimit, "timelimit", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
|
||||
|
@ -1685,6 +1707,11 @@ void CheckExitRules( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (gDoSlowMoDuel)
|
||||
{ //don't go to intermission while in slow motion
|
||||
return;
|
||||
}
|
||||
|
||||
if (gEscaping)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -2001,6 +2028,28 @@ void CheckVote( void ) {
|
|||
{ //otherwise, just leave the map until a restart
|
||||
G_RefreshNextMap(level.votingGametypeTo, qfalse);
|
||||
}
|
||||
|
||||
if (g_fraglimitVoteCorrection.integer)
|
||||
{ //This means to auto-correct fraglimit when voting to and from duel.
|
||||
int currentGT = trap_Cvar_VariableIntegerValue("g_gametype");
|
||||
int currentFL = trap_Cvar_VariableIntegerValue("fraglimit");
|
||||
|
||||
if (level.votingGametypeTo == GT_TOURNAMENT && currentGT != GT_TOURNAMENT)
|
||||
{
|
||||
if (currentFL > 3 || !currentFL)
|
||||
{ //if voting to duel, and fraglimit is more than 3 (or unlimited), then set it down to 3
|
||||
trap_SendConsoleCommand(EXEC_APPEND, "fraglimit 3\n");
|
||||
}
|
||||
}
|
||||
else if (level.votingGametypeTo != GT_TOURNAMENT && currentGT == GT_TOURNAMENT)
|
||||
{
|
||||
if (currentFL && currentFL < 20)
|
||||
{ //if voting from duel, an fraglimit is less than 20, then set it up to 20
|
||||
trap_SendConsoleCommand(EXEC_APPEND, "fraglimit 20\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level.votingGametype = qfalse;
|
||||
level.votingGametypeTo = 0;
|
||||
}
|
||||
|
@ -2196,6 +2245,9 @@ void G_RunThink (gentity_t *ent) {
|
|||
int g_LastFrameTime = 0;
|
||||
int g_TimeSinceLastFrame = 0;
|
||||
|
||||
qboolean gDoSlowMoDuel = qfalse;
|
||||
int gSlowMoDuelTime = 0;
|
||||
|
||||
/*
|
||||
================
|
||||
G_RunFrame
|
||||
|
@ -2208,7 +2260,64 @@ void G_RunFrame( int levelTime ) {
|
|||
int i;
|
||||
gentity_t *ent;
|
||||
int msec;
|
||||
int start, end;
|
||||
int start, end;
|
||||
|
||||
if (gDoSlowMoDuel)
|
||||
{
|
||||
if (level.restarted)
|
||||
{
|
||||
char buf[128];
|
||||
float tFVal = 0;
|
||||
|
||||
trap_Cvar_VariableStringBuffer("timescale", buf, sizeof(buf));
|
||||
|
||||
tFVal = atof(buf);
|
||||
|
||||
trap_Cvar_Set("timescale", "1");
|
||||
if (tFVal == 1.0f)
|
||||
{
|
||||
gDoSlowMoDuel = qfalse;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float timeDif = (level.time - gSlowMoDuelTime); //difference in time between when the slow motion was initiated and now
|
||||
float useDif = 0; //the difference to use when actually setting the timescale
|
||||
|
||||
if (timeDif < 150)
|
||||
{
|
||||
trap_Cvar_Set("timescale", "0.1f");
|
||||
}
|
||||
else if (timeDif < 1150)
|
||||
{
|
||||
useDif = (timeDif/1000); //scale from 0.1 up to 1
|
||||
if (useDif < 0.1)
|
||||
{
|
||||
useDif = 0.1;
|
||||
}
|
||||
if (useDif > 1.0)
|
||||
{
|
||||
useDif = 1.0;
|
||||
}
|
||||
trap_Cvar_Set("timescale", va("%f", useDif));
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[128];
|
||||
float tFVal = 0;
|
||||
|
||||
trap_Cvar_VariableStringBuffer("timescale", buf, sizeof(buf));
|
||||
|
||||
tFVal = atof(buf);
|
||||
|
||||
trap_Cvar_Set("timescale", "1");
|
||||
if (timeDif > 1500 && tFVal == 1.0f)
|
||||
{
|
||||
gDoSlowMoDuel = qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we are waiting for the level to restart, do nothing
|
||||
if ( level.restarted ) {
|
||||
|
@ -2295,7 +2404,7 @@ int start, end;
|
|||
{
|
||||
G_CheckClientTimeouts ( ent );
|
||||
|
||||
if((!level.intermissiontime)&&!(ent->client->ps.pm_flags&PMF_FOLLOW))
|
||||
if((!level.intermissiontime)&&!(ent->client->ps.pm_flags&PMF_FOLLOW) && ent->client->sess.sessionTeam != TEAM_SPECTATOR)
|
||||
{
|
||||
WP_ForcePowersUpdate(ent, &ent->client->pers.cmd );
|
||||
WP_SaberPositionUpdate(ent, &ent->client->pers.cmd);
|
||||
|
|
|
@ -1552,6 +1552,9 @@ void SP_fx_runner( gentity_t *ent )
|
|||
//rww - here starts the main example g2animent stuff
|
||||
#define ANIMENT_TYPE_STORMTROOPER 0
|
||||
#define ANIMENT_TYPE_RODIAN 1
|
||||
#define ANIMENT_TYPE_JAN 2
|
||||
#define ANIMENT_TYPE_CUSTOM 3
|
||||
#define MAX_ANIMENTS 4
|
||||
|
||||
#define TROOPER_PAIN_SOUNDS 4
|
||||
#define TROOPER_DEATH_SOUNDS 3
|
||||
|
@ -1567,12 +1570,245 @@ int gRodianSound_Pain[RODIAN_PAIN_SOUNDS];
|
|||
int gRodianSound_Death[RODIAN_DEATH_SOUNDS];
|
||||
int gRodianSound_Alert[RODIAN_ALERT_SOUNDS];
|
||||
|
||||
#define JAN_PAIN_SOUNDS 4
|
||||
#define JAN_DEATH_SOUNDS 3
|
||||
#define JAN_ALERT_SOUNDS 5
|
||||
int gJanSound_Pain[JAN_PAIN_SOUNDS];
|
||||
int gJanSound_Death[JAN_DEATH_SOUNDS];
|
||||
int gJanSound_Alert[JAN_ALERT_SOUNDS];
|
||||
|
||||
int G_PickDeathAnim( gentity_t *self, vec3_t point, int damage, int mod, int hitLoc );
|
||||
void AnimEntFireWeapon( gentity_t *ent, qboolean altFire );
|
||||
int GetNearestVisibleWP(vec3_t org, int ignore);
|
||||
int InFieldOfVision(vec3_t viewangles, float fov, vec3_t angles);
|
||||
extern float gBotEdit;
|
||||
|
||||
#define ANIMENT_ALIGNED_UNKNOWN 0
|
||||
#define ANIMENT_ALIGNED_BAD 1
|
||||
#define ANIMENT_ALIGNED_GOOD 2
|
||||
|
||||
#define ANIMENT_CUSTOMSOUND_PAIN 0
|
||||
#define ANIMENT_CUSTOMSOUND_DEATH 1
|
||||
#define ANIMENT_CUSTOMSOUND_ALERT 2
|
||||
|
||||
int gAnimEntTypes = 0;
|
||||
|
||||
typedef struct animentCustomInfo_s
|
||||
{
|
||||
int aeAlignment;
|
||||
int aeIndex;
|
||||
int aeWeapon;
|
||||
char *modelPath;
|
||||
char *soundPath;
|
||||
void *next;
|
||||
} animentCustomInfo_t;
|
||||
|
||||
animentCustomInfo_t *animEntRoot = NULL;
|
||||
|
||||
animentCustomInfo_t *ExampleAnimEntCustomData(gentity_t *self)
|
||||
{
|
||||
animentCustomInfo_t *iter = animEntRoot;
|
||||
int safetyCheck = 0;
|
||||
|
||||
while (iter && safetyCheck < 30000)
|
||||
{
|
||||
if (iter->aeIndex == self->waterlevel)
|
||||
{
|
||||
return iter;
|
||||
}
|
||||
|
||||
iter = iter->next;
|
||||
safetyCheck++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
animentCustomInfo_t *ExampleAnimEntCustomDataExists(gentity_t *self, int alignment, int weapon, char *modelname,
|
||||
char *soundpath)
|
||||
{
|
||||
animentCustomInfo_t *iter = animEntRoot;
|
||||
int safetyCheck = 0;
|
||||
|
||||
while (iter && safetyCheck < 30000)
|
||||
{
|
||||
if (iter->aeAlignment == alignment &&
|
||||
iter->aeWeapon == weapon &&
|
||||
!Q_stricmp(iter->modelPath, modelname) &&
|
||||
!Q_stricmp(iter->soundPath, soundpath))
|
||||
{
|
||||
return iter;
|
||||
}
|
||||
|
||||
iter = iter->next;
|
||||
safetyCheck++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ExampleAnimEntCustomDataEntry(gentity_t *self, int alignment, int weapon, char *modelname, char *soundpath)
|
||||
{
|
||||
animentCustomInfo_t *find = ExampleAnimEntCustomDataExists(self, alignment, weapon, modelname, soundpath);
|
||||
animentCustomInfo_t *lastValid = NULL;
|
||||
int safetyCheck = 0;
|
||||
|
||||
if (find)
|
||||
{ //data for this guy already exists. Set our waterlevel (aeIndex) to use this.
|
||||
self->waterlevel = find->aeIndex;
|
||||
return;
|
||||
}
|
||||
|
||||
find = animEntRoot;
|
||||
|
||||
while (find && safetyCheck < 30000)
|
||||
{ //find the next null pointer
|
||||
lastValid = find;
|
||||
find = find->next;
|
||||
safetyCheck++;
|
||||
}
|
||||
|
||||
if (!find)
|
||||
{
|
||||
find = BG_Alloc(sizeof(animentCustomInfo_t));
|
||||
|
||||
if (!find)
|
||||
{ //careful not to exceed the BG_Alloc limit!
|
||||
return;
|
||||
}
|
||||
|
||||
find->aeAlignment = alignment;
|
||||
self->waterlevel = gAnimEntTypes;
|
||||
find->aeIndex = self->waterlevel;
|
||||
find->aeWeapon = weapon;
|
||||
find->next = NULL;
|
||||
|
||||
find->modelPath = BG_Alloc(strlen(modelname)+1);
|
||||
find->soundPath = BG_Alloc(strlen(soundpath)+1);
|
||||
|
||||
if (!find->modelPath || !find->soundPath)
|
||||
{
|
||||
find->aeIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(find->modelPath, modelname);
|
||||
strcpy(find->soundPath, soundpath);
|
||||
|
||||
find->modelPath[strlen(modelname)] = 0;
|
||||
find->soundPath[strlen(modelname)] = 0;
|
||||
|
||||
if (lastValid)
|
||||
{
|
||||
lastValid->next = find;
|
||||
}
|
||||
|
||||
if (!animEntRoot)
|
||||
{
|
||||
animEntRoot = find;
|
||||
}
|
||||
|
||||
gAnimEntTypes++;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimEntCustomSoundPrecache(animentCustomInfo_t *aeInfo)
|
||||
{
|
||||
if (!aeInfo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G_SoundIndex(va("%s/pain25", aeInfo->soundPath));
|
||||
G_SoundIndex(va("%s/pain50", aeInfo->soundPath));
|
||||
G_SoundIndex(va("%s/pain75", aeInfo->soundPath));
|
||||
G_SoundIndex(va("%s/pain100", aeInfo->soundPath));
|
||||
|
||||
G_SoundIndex(va("%s/death1", aeInfo->soundPath));
|
||||
G_SoundIndex(va("%s/death2", aeInfo->soundPath));
|
||||
G_SoundIndex(va("%s/death3", aeInfo->soundPath));
|
||||
|
||||
G_SoundIndex(va("%s/detected1", aeInfo->soundPath));
|
||||
G_SoundIndex(va("%s/detected2", aeInfo->soundPath));
|
||||
G_SoundIndex(va("%s/detected3", aeInfo->soundPath));
|
||||
G_SoundIndex(va("%s/detected4", aeInfo->soundPath));
|
||||
G_SoundIndex(va("%s/detected5", aeInfo->soundPath));
|
||||
}
|
||||
|
||||
void ExampleAnimEntCustomSound(gentity_t *self, int soundType)
|
||||
{
|
||||
animentCustomInfo_t *aeInfo = ExampleAnimEntCustomData(self);
|
||||
int customSounds[16];
|
||||
int numSounds = 0;
|
||||
|
||||
if (!aeInfo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (soundType == ANIMENT_CUSTOMSOUND_PAIN)
|
||||
{
|
||||
customSounds[0] = G_SoundIndex(va("%s/pain25", aeInfo->soundPath));
|
||||
customSounds[1] = G_SoundIndex(va("%s/pain50", aeInfo->soundPath));
|
||||
customSounds[2] = G_SoundIndex(va("%s/pain75", aeInfo->soundPath));
|
||||
customSounds[3] = G_SoundIndex(va("%s/pain100", aeInfo->soundPath));
|
||||
numSounds = 4;
|
||||
}
|
||||
else if (soundType == ANIMENT_CUSTOMSOUND_DEATH)
|
||||
{
|
||||
customSounds[0] = G_SoundIndex(va("%s/death1", aeInfo->soundPath));
|
||||
customSounds[1] = G_SoundIndex(va("%s/death2", aeInfo->soundPath));
|
||||
customSounds[2] = G_SoundIndex(va("%s/death3", aeInfo->soundPath));
|
||||
numSounds = 3;
|
||||
}
|
||||
else if (soundType == ANIMENT_CUSTOMSOUND_ALERT)
|
||||
{
|
||||
customSounds[0] = G_SoundIndex(va("%s/detected1", aeInfo->soundPath));
|
||||
customSounds[1] = G_SoundIndex(va("%s/detected2", aeInfo->soundPath));
|
||||
customSounds[2] = G_SoundIndex(va("%s/detected3", aeInfo->soundPath));
|
||||
customSounds[3] = G_SoundIndex(va("%s/detected4", aeInfo->soundPath));
|
||||
customSounds[4] = G_SoundIndex(va("%s/detected5", aeInfo->soundPath));
|
||||
numSounds = 5;
|
||||
}
|
||||
|
||||
if (!numSounds)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G_Sound(self, CHAN_AUTO, customSounds[Q_irand(0, numSounds-1)]);
|
||||
}
|
||||
|
||||
int ExampleAnimEntAlignment(gentity_t *self)
|
||||
{
|
||||
if (self->watertype == ANIMENT_TYPE_STORMTROOPER)
|
||||
{
|
||||
return ANIMENT_ALIGNED_BAD;
|
||||
}
|
||||
|
||||
if (self->watertype == ANIMENT_TYPE_RODIAN)
|
||||
{
|
||||
return ANIMENT_ALIGNED_BAD;
|
||||
}
|
||||
|
||||
if (self->watertype == ANIMENT_TYPE_JAN)
|
||||
{
|
||||
return ANIMENT_ALIGNED_GOOD;
|
||||
}
|
||||
|
||||
if (self->watertype == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
animentCustomInfo_t *aeInfo = ExampleAnimEntCustomData(self);
|
||||
|
||||
if (aeInfo)
|
||||
{
|
||||
return aeInfo->aeAlignment;
|
||||
}
|
||||
}
|
||||
|
||||
return ANIMENT_ALIGNED_UNKNOWN;
|
||||
}
|
||||
|
||||
void ExampleAnimEntAlertOthers(gentity_t *self)
|
||||
{
|
||||
//alert all the other animents in the area
|
||||
|
@ -1584,7 +1820,8 @@ void ExampleAnimEntAlertOthers(gentity_t *self)
|
|||
g_entities[i].s.eType == ET_GRAPPLE &&
|
||||
g_entities[i].health > 0)
|
||||
{
|
||||
if (g_entities[i].bolt_Motion == ENTITYNUM_NONE && trap_InPVS(self->r.currentOrigin, g_entities[i].r.currentOrigin))
|
||||
if (g_entities[i].bolt_Motion == ENTITYNUM_NONE && trap_InPVS(self->r.currentOrigin, g_entities[i].r.currentOrigin) &&
|
||||
ExampleAnimEntAlignment(self) == ExampleAnimEntAlignment(&g_entities[i]))
|
||||
{
|
||||
g_entities[i].bolt_Motion = self->bolt_Motion;
|
||||
g_entities[i].speed = level.time + 4000; //4 seconds til we forget about the enemy
|
||||
|
@ -1600,7 +1837,7 @@ void ExampleAnimEnt_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attac
|
|||
{
|
||||
self->s.torsoAnim = G_PickDeathAnim(self, self->pos1, damage, mod, HL_NONE);
|
||||
|
||||
if (self->s.torsoAnim < 0 || self->s.torsoAnim >= MAX_TOTALANIMATIONS)
|
||||
if (self->s.torsoAnim <= 0 || self->s.torsoAnim >= MAX_TOTALANIMATIONS)
|
||||
{ //?! (bad)
|
||||
self->s.torsoAnim = BOTH_DEATH1;
|
||||
}
|
||||
|
@ -1619,6 +1856,14 @@ void ExampleAnimEnt_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attac
|
|||
{
|
||||
G_Sound(self, CHAN_AUTO, gRodianSound_Death[Q_irand(0, RODIAN_DEATH_SOUNDS-1)]);
|
||||
}
|
||||
else if (self->watertype == ANIMENT_TYPE_JAN)
|
||||
{
|
||||
G_Sound(self, CHAN_AUTO, gJanSound_Death[Q_irand(0, JAN_DEATH_SOUNDS-1)]);
|
||||
}
|
||||
else if (self->watertype == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
ExampleAnimEntCustomSound(self, ANIMENT_CUSTOMSOUND_DEATH);
|
||||
}
|
||||
|
||||
if (mod == MOD_SABER)
|
||||
{ //Set the velocity up a bit to make the limb fly up more than it otherwise would.
|
||||
|
@ -1647,6 +1892,12 @@ void ExampleAnimEnt_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attac
|
|||
VectorCopy(preDelta, self->s.pos.trDelta);
|
||||
}
|
||||
|
||||
if (self->bolt_Motion == ENTITYNUM_NONE &&
|
||||
(attacker->client || attacker->s.eType == ET_GRAPPLE))
|
||||
{
|
||||
self->bolt_Motion = attacker->s.number;
|
||||
}
|
||||
|
||||
if (self->bolt_Motion != ENTITYNUM_NONE)
|
||||
{
|
||||
ExampleAnimEntAlertOthers(self);
|
||||
|
@ -1671,6 +1922,11 @@ void ExampleAnimEnt_Pain(gentity_t *self, gentity_t *attacker, int damage)
|
|||
self->s.legsAnim = painAnim;
|
||||
self->bolt_LArm = level.time + animLen;
|
||||
|
||||
if (self->s.torsoAnim <= 0 || self->s.torsoAnim >= MAX_TOTALANIMATIONS)
|
||||
{
|
||||
self->s.torsoAnim = self->s.legsAnim = BOTH_PAIN1;
|
||||
}
|
||||
|
||||
if (self->watertype == ANIMENT_TYPE_STORMTROOPER)
|
||||
{
|
||||
G_Sound(self, CHAN_AUTO, gTrooperSound_Pain[Q_irand(0, TROOPER_PAIN_SOUNDS-1)]);
|
||||
|
@ -1679,13 +1935,24 @@ void ExampleAnimEnt_Pain(gentity_t *self, gentity_t *attacker, int damage)
|
|||
{
|
||||
G_Sound(self, CHAN_AUTO, gRodianSound_Pain[Q_irand(0, RODIAN_PAIN_SOUNDS-1)]);
|
||||
}
|
||||
|
||||
if (attacker && attacker->client && self->bolt_Motion == ENTITYNUM_NONE)
|
||||
else if (self->watertype == ANIMENT_TYPE_JAN)
|
||||
{
|
||||
self->bolt_Motion = attacker->s.number;
|
||||
self->speed = level.time + 4000; //4 seconds til we forget about the enemy
|
||||
ExampleAnimEntAlertOthers(self);
|
||||
self->bolt_RArm = level.time + Q_irand(500, 1000);
|
||||
G_Sound(self, CHAN_AUTO, gJanSound_Pain[Q_irand(0, JAN_PAIN_SOUNDS-1)]);
|
||||
}
|
||||
else if (self->watertype == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
ExampleAnimEntCustomSound(self, ANIMENT_CUSTOMSOUND_PAIN);
|
||||
}
|
||||
|
||||
if (attacker && (attacker->client || attacker->s.eType == ET_GRAPPLE) && self->bolt_Motion == ENTITYNUM_NONE)
|
||||
{
|
||||
if (attacker->s.number >= MAX_CLIENTS || (ExampleAnimEntAlignment(self) != ANIMENT_ALIGNED_GOOD && !(attacker->r.svFlags & SVF_BOT)))
|
||||
{
|
||||
self->bolt_Motion = attacker->s.number;
|
||||
self->speed = level.time + 4000; //4 seconds til we forget about the enemy
|
||||
ExampleAnimEntAlertOthers(self);
|
||||
self->bolt_RArm = level.time + Q_irand(500, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1844,10 +2111,27 @@ qboolean ExampleAnimEntClearLOS(gentity_t *self, vec3_t point)
|
|||
|
||||
trap_Trace(&tr, self->r.currentOrigin, 0, 0, point, self->s.number, self->clipmask);
|
||||
|
||||
if (tr.fraction == 1 ||
|
||||
tr.entityNum < MAX_CLIENTS)
|
||||
{ //clear LOS, or would be hitting a client (they're all bad!), so fire.
|
||||
return qtrue;
|
||||
if (ExampleAnimEntAlignment(self) == ANIMENT_ALIGNED_GOOD)
|
||||
{
|
||||
if (tr.fraction == 1 ||
|
||||
(g_entities[tr.entityNum].s.eType == ET_GRAPPLE && ExampleAnimEntAlignment(&g_entities[tr.entityNum]) != ANIMENT_ALIGNED_GOOD) ||
|
||||
(self->bolt_Motion < MAX_CLIENTS && tr.entityNum == self->bolt_Motion))
|
||||
{ //clear LOS, or would be hitting a bad animent, so fire.
|
||||
return qtrue;
|
||||
}
|
||||
else if (g_entities[tr.entityNum].inuse && g_entities[tr.entityNum].client && (g_entities[tr.entityNum].r.svFlags & SVF_BOT))
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tr.fraction == 1 ||
|
||||
tr.entityNum < MAX_CLIENTS ||
|
||||
(g_entities[tr.entityNum].s.eType == ET_GRAPPLE && ExampleAnimEntAlignment(&g_entities[tr.entityNum]) != ANIMENT_ALIGNED_BAD))
|
||||
{ //clear LOS, or would be hitting a client (they're all bad!), so fire.
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
|
@ -1872,7 +2156,19 @@ void ExampleAnimEntWeaponHandling(gentity_t *self)
|
|||
{
|
||||
AnimEntFireWeapon(self, qfalse);
|
||||
G_AddEvent(self, EV_FIRE_WEAPON, 0);
|
||||
self->bolt_RArm = level.time + Q_irand(700, 1000);
|
||||
|
||||
if (self->s.weapon == WP_REPEATER)
|
||||
{
|
||||
self->bolt_RArm = level.time + Q_irand(1, 500);
|
||||
}
|
||||
else if (ExampleAnimEntAlignment(self) == ANIMENT_ALIGNED_GOOD)
|
||||
{
|
||||
self->bolt_RArm = level.time + Q_irand(200, 400);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->bolt_RArm = level.time + Q_irand(700, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2002,30 +2298,92 @@ void ExampleAnimEntEnemyHandling(gentity_t *self, float enDist)
|
|||
int bestIndex = -1;
|
||||
float minDist = enDist;
|
||||
|
||||
while (i < MAX_CLIENTS)
|
||||
if (ExampleAnimEntAlignment(self) == ANIMENT_ALIGNED_GOOD)
|
||||
{
|
||||
if (g_entities[i].inuse && g_entities[i].client && g_entities[i].health > 0 && g_entities[i].client->sess.sessionTeam != TEAM_SPECTATOR)
|
||||
while (i < MAX_GENTITIES)
|
||||
{
|
||||
vec3_t checkLen;
|
||||
float fCheckLen;
|
||||
|
||||
VectorSubtract(self->r.currentOrigin, g_entities[i].client->ps.origin, checkLen);
|
||||
|
||||
fCheckLen = VectorLength(checkLen);
|
||||
|
||||
if (fCheckLen < (minDist - 128))
|
||||
if (g_entities[i].inuse && (g_entities[i].s.eType == ET_GRAPPLE || (g_entities[i].client && (g_entities[i].r.svFlags & SVF_BOT))) && ExampleAnimEntAlignment(&g_entities[i]) != ANIMENT_ALIGNED_GOOD && g_entities[i].health > 0 && !(g_entities[i].s.eFlags & EF_DEAD))
|
||||
{
|
||||
vec3_t enAngles;
|
||||
VectorSubtract(g_entities[i].client->ps.origin, self->r.currentOrigin, enAngles);
|
||||
vectoangles(enAngles, enAngles);
|
||||
if ((InFieldOfVision(self->s.apos.trBase, 120, enAngles) || self->s.genericenemyindex > level.time) && ExampleAnimEntClearLOS(self, g_entities[i].client->ps.origin))
|
||||
vec3_t checkLen;
|
||||
float fCheckLen;
|
||||
|
||||
VectorSubtract(self->r.currentOrigin, g_entities[i].r.currentOrigin, checkLen);
|
||||
|
||||
fCheckLen = VectorLength(checkLen);
|
||||
|
||||
if (fCheckLen < (minDist - 128))
|
||||
{
|
||||
minDist = fCheckLen;
|
||||
bestIndex = i;
|
||||
vec3_t enAngles;
|
||||
VectorSubtract(g_entities[i].r.currentOrigin, self->r.currentOrigin, enAngles);
|
||||
vectoangles(enAngles, enAngles);
|
||||
if ((InFieldOfVision(self->s.apos.trBase, 120, enAngles) || self->s.genericenemyindex > level.time) && ExampleAnimEntClearLOS(self, g_entities[i].r.currentOrigin))
|
||||
{
|
||||
minDist = fCheckLen;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (i < MAX_CLIENTS)
|
||||
{
|
||||
if (g_entities[i].inuse && g_entities[i].client && !(g_entities[i].r.svFlags & SVF_BOT) && g_entities[i].health > 0 && !(g_entities[i].s.eFlags & EF_DEAD) && g_entities[i].client->sess.sessionTeam != TEAM_SPECTATOR)
|
||||
{
|
||||
vec3_t checkLen;
|
||||
float fCheckLen;
|
||||
|
||||
VectorSubtract(self->r.currentOrigin, g_entities[i].client->ps.origin, checkLen);
|
||||
|
||||
fCheckLen = VectorLength(checkLen);
|
||||
|
||||
if (fCheckLen < (minDist - 128))
|
||||
{
|
||||
vec3_t enAngles;
|
||||
VectorSubtract(g_entities[i].client->ps.origin, self->r.currentOrigin, enAngles);
|
||||
vectoangles(enAngles, enAngles);
|
||||
if ((InFieldOfVision(self->s.apos.trBase, 120, enAngles) || self->s.genericenemyindex > level.time) && ExampleAnimEntClearLOS(self, g_entities[i].client->ps.origin))
|
||||
{
|
||||
minDist = fCheckLen;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (bestIndex == -1)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
while (i < MAX_GENTITIES)
|
||||
{
|
||||
if (g_entities[i].inuse && g_entities[i].s.eType == ET_GRAPPLE && ExampleAnimEntAlignment(&g_entities[i]) != ANIMENT_ALIGNED_BAD && g_entities[i].health > 0 && !(g_entities[i].s.eFlags & EF_DEAD))
|
||||
{
|
||||
vec3_t checkLen;
|
||||
float fCheckLen;
|
||||
|
||||
VectorSubtract(self->r.currentOrigin, g_entities[i].r.currentOrigin, checkLen);
|
||||
|
||||
fCheckLen = VectorLength(checkLen);
|
||||
|
||||
if (fCheckLen < (minDist - 128))
|
||||
{
|
||||
vec3_t enAngles;
|
||||
VectorSubtract(g_entities[i].r.currentOrigin, self->r.currentOrigin, enAngles);
|
||||
vectoangles(enAngles, enAngles);
|
||||
if ((InFieldOfVision(self->s.apos.trBase, 120, enAngles) || self->s.genericenemyindex > level.time) && ExampleAnimEntClearLOS(self, g_entities[i].r.currentOrigin))
|
||||
{
|
||||
minDist = fCheckLen;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (bestIndex != -1)
|
||||
|
@ -2044,6 +2402,14 @@ void ExampleAnimEntEnemyHandling(gentity_t *self, float enDist)
|
|||
{
|
||||
G_Sound(self, CHAN_AUTO, gRodianSound_Alert[Q_irand(0, RODIAN_ALERT_SOUNDS-1)]);
|
||||
}
|
||||
else if (self->watertype == ANIMENT_TYPE_JAN)
|
||||
{
|
||||
G_Sound(self, CHAN_AUTO, gJanSound_Alert[Q_irand(0, JAN_ALERT_SOUNDS-1)]);
|
||||
}
|
||||
else if (self->watertype == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
ExampleAnimEntCustomSound(self, ANIMENT_CUSTOMSOUND_ALERT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2099,6 +2465,24 @@ void ExampleAnimEntUpdateSelf(gentity_t *self)
|
|||
}
|
||||
}
|
||||
|
||||
if (self->bolt_Motion < MAX_CLIENTS &&
|
||||
(!g_entities[self->bolt_Motion].inuse ||
|
||||
!g_entities[self->bolt_Motion].client))
|
||||
{
|
||||
self->bolt_Motion = ENTITYNUM_NONE;
|
||||
}
|
||||
|
||||
if (self->bolt_Motion != ENTITYNUM_NONE &&
|
||||
g_entities[self->bolt_Motion].inuse &&
|
||||
(g_entities[self->bolt_Motion].client || g_entities[self->bolt_Motion].s.eType == ET_GRAPPLE))
|
||||
{
|
||||
if (g_entities[self->bolt_Motion].health < 1 ||
|
||||
(g_entities[self->bolt_Motion].s.eFlags & EF_DEAD))
|
||||
{
|
||||
self->bolt_Motion = ENTITYNUM_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (gWPNum > 0)
|
||||
{
|
||||
if (self->bolt_Motion != ENTITYNUM_NONE &&
|
||||
|
@ -2123,6 +2507,19 @@ void ExampleAnimEntUpdateSelf(gentity_t *self)
|
|||
|
||||
hasEnemyLOS = ExampleAnimEntClearLOS(self, enemyOrigin);
|
||||
}
|
||||
else if (self->bolt_Motion != ENTITYNUM_NONE &&
|
||||
g_entities[self->bolt_Motion].inuse &&
|
||||
g_entities[self->bolt_Motion].s.eType == ET_GRAPPLE)
|
||||
{
|
||||
vec3_t enSubVec;
|
||||
VectorSubtract(self->r.currentOrigin, g_entities[self->bolt_Motion].r.currentOrigin, enSubVec);
|
||||
|
||||
enDist = VectorLength(enSubVec);
|
||||
|
||||
VectorCopy(g_entities[self->bolt_Motion].r.currentOrigin, enemyOrigin);
|
||||
|
||||
hasEnemyLOS = ExampleAnimEntClearLOS(self, enemyOrigin);
|
||||
}
|
||||
|
||||
if (hasEnemyLOS && enDist < 512 && self->splashRadius < level.time)
|
||||
{
|
||||
|
@ -2165,7 +2562,14 @@ void ExampleAnimEntUpdateSelf(gentity_t *self)
|
|||
|
||||
if (self->bolt_Motion == ENTITYNUM_NONE)
|
||||
{
|
||||
runSpeed = 6;
|
||||
if (ExampleAnimEntAlignment(self) == ANIMENT_ALIGNED_GOOD)
|
||||
{
|
||||
runSpeed = 18;
|
||||
}
|
||||
else
|
||||
{
|
||||
runSpeed = 6;
|
||||
}
|
||||
}
|
||||
|
||||
didMove = ExampleAnimEntMove(self, goalPos, runSpeed);
|
||||
|
@ -2189,24 +2593,57 @@ void ExampleAnimEntUpdateSelf(gentity_t *self)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (self->bolt_Motion != ENTITYNUM_NONE &&
|
||||
g_entities[self->bolt_Motion].inuse &&
|
||||
g_entities[self->bolt_Motion].s.eType == ET_GRAPPLE)
|
||||
{
|
||||
if (self->speed < level.time || g_entities[self->bolt_Motion].health < 1)
|
||||
{
|
||||
self->bolt_Motion = ENTITYNUM_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->bolt_Motion != originalEnemyIndex)
|
||||
{
|
||||
vec3_t enSubVec;
|
||||
VectorSubtract(self->r.currentOrigin, g_entities[self->bolt_Motion].r.currentOrigin, enSubVec);
|
||||
|
||||
enDist = VectorLength(enSubVec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExampleAnimEntEnemyHandling(self, enDist);
|
||||
|
||||
if (self->bolt_Motion != ENTITYNUM_NONE &&
|
||||
g_entities[self->bolt_Motion].inuse &&
|
||||
g_entities[self->bolt_Motion].client)
|
||||
(g_entities[self->bolt_Motion].client || g_entities[self->bolt_Motion].s.eType == ET_GRAPPLE))
|
||||
{
|
||||
vec3_t enOrigin;
|
||||
|
||||
if (g_entities[self->bolt_Motion].client)
|
||||
{
|
||||
VectorCopy(g_entities[self->bolt_Motion].client->ps.origin, enOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(g_entities[self->bolt_Motion].r.currentOrigin, enOrigin);
|
||||
}
|
||||
|
||||
if (originalEnemyIndex != self->bolt_Motion)
|
||||
{
|
||||
VectorCopy(g_entities[self->bolt_Motion].client->ps.origin, enemyOrigin);
|
||||
VectorCopy(enOrigin, enemyOrigin);
|
||||
|
||||
if (g_entities[self->bolt_Motion].client->pers.cmd.upmove < 0)
|
||||
if (g_entities[self->bolt_Motion].client)
|
||||
{
|
||||
enemyOrigin[2] -= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
enemyOrigin[2] += 8;
|
||||
if (g_entities[self->bolt_Motion].client->pers.cmd.upmove < 0)
|
||||
{
|
||||
enemyOrigin[2] -= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
enemyOrigin[2] += 8;
|
||||
}
|
||||
}
|
||||
|
||||
hasEnemyLOS = ExampleAnimEntClearLOS(self, enemyOrigin);
|
||||
|
@ -2219,7 +2656,7 @@ void ExampleAnimEntUpdateSelf(gentity_t *self)
|
|||
vec3_t selfAimOrg;
|
||||
vec3_t myZeroPitchAngles;
|
||||
|
||||
VectorCopy(g_entities[self->bolt_Motion].client->ps.origin, enAimOrg);
|
||||
VectorCopy(enOrigin, enAimOrg);
|
||||
VectorCopy(self->r.currentOrigin, selfAimOrg);
|
||||
enAimOrg[2] = selfAimOrg[2];
|
||||
|
||||
|
@ -2271,8 +2708,8 @@ void ExampleAnimEntUpdateSelf(gentity_t *self)
|
|||
|
||||
if (didMove == 1)
|
||||
{
|
||||
if (self->bolt_Motion == ENTITYNUM_NONE)
|
||||
{
|
||||
if (self->bolt_Motion == ENTITYNUM_NONE && ExampleAnimEntAlignment(self) != ANIMENT_ALIGNED_GOOD)
|
||||
{ //Good guys are always on "alert"
|
||||
self->s.torsoAnim = BOTH_WALK1;
|
||||
self->s.legsAnim = BOTH_WALK1;
|
||||
}
|
||||
|
@ -2306,7 +2743,7 @@ void ExampleAnimEntUpdateSelf(gentity_t *self)
|
|||
VectorCopy(preserveAngles, self->s.apos.trBase);
|
||||
}
|
||||
|
||||
void G_SpawnExampleAnimEnt(vec3_t pos, int aeType)
|
||||
void G_SpawnExampleAnimEnt(vec3_t pos, int aeType, animentCustomInfo_t *aeInfo)
|
||||
{
|
||||
gentity_t *animEnt;
|
||||
vec3_t playerMins;
|
||||
|
@ -2355,11 +2792,37 @@ void G_SpawnExampleAnimEnt(vec3_t pos, int aeType)
|
|||
gRodianSound_Alert[4] = G_SoundIndex("sound/chars/rodian1/misc/detected5");
|
||||
}
|
||||
}
|
||||
else if (aeType == ANIMENT_TYPE_JAN)
|
||||
{
|
||||
if (!gJanSound_Pain[0])
|
||||
{
|
||||
gJanSound_Pain[0] = G_SoundIndex("sound/chars/jan/misc/pain25");
|
||||
gJanSound_Pain[1] = G_SoundIndex("sound/chars/jan/misc/pain50");
|
||||
gJanSound_Pain[2] = G_SoundIndex("sound/chars/jan/misc/pain75");
|
||||
gJanSound_Pain[3] = G_SoundIndex("sound/chars/jan/misc/pain100");
|
||||
|
||||
gJanSound_Death[0] = G_SoundIndex("sound/chars/jan/misc/death1");
|
||||
gJanSound_Death[1] = G_SoundIndex("sound/chars/jan/misc/death2");
|
||||
gJanSound_Death[2] = G_SoundIndex("sound/chars/jan/misc/death3");
|
||||
|
||||
gJanSound_Alert[0] = G_SoundIndex("sound/chars/jan/misc/detected1");
|
||||
gJanSound_Alert[1] = G_SoundIndex("sound/chars/jan/misc/detected2");
|
||||
gJanSound_Alert[2] = G_SoundIndex("sound/chars/jan/misc/detected3");
|
||||
gJanSound_Alert[3] = G_SoundIndex("sound/chars/jan/misc/detected4");
|
||||
gJanSound_Alert[4] = G_SoundIndex("sound/chars/jan/misc/detected5");
|
||||
}
|
||||
}
|
||||
|
||||
animEnt = G_Spawn();
|
||||
|
||||
animEnt->watertype = aeType; //set the animent type
|
||||
|
||||
if (aeType == ANIMENT_TYPE_CUSTOM && aeInfo)
|
||||
{
|
||||
ExampleAnimEntCustomDataEntry(animEnt, aeInfo->aeAlignment, aeInfo->aeWeapon, aeInfo->modelPath, aeInfo->soundPath);
|
||||
AnimEntCustomSoundPrecache(aeInfo);
|
||||
}
|
||||
|
||||
animEnt->s.eType = ET_GRAPPLE; //ET_GRAPPLE is the reserved special type for G2 anim ents.
|
||||
|
||||
if (animEnt->watertype == ANIMENT_TYPE_STORMTROOPER)
|
||||
|
@ -2370,6 +2833,23 @@ void G_SpawnExampleAnimEnt(vec3_t pos, int aeType)
|
|||
{
|
||||
animEnt->s.modelindex = G_ModelIndex( "models/players/rodian/model.glm" );
|
||||
}
|
||||
else if (animEnt->watertype == ANIMENT_TYPE_JAN)
|
||||
{
|
||||
animEnt->s.modelindex = G_ModelIndex( "models/players/jan/model.glm" );
|
||||
}
|
||||
else if (animEnt->watertype == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
animentCustomInfo_t *aeInfo = ExampleAnimEntCustomData(animEnt);
|
||||
|
||||
if (aeInfo)
|
||||
{
|
||||
animEnt->s.modelindex = G_ModelIndex(aeInfo->modelPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
animEnt->s.modelindex = G_ModelIndex( "models/players/stormtrooper/model.glm" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G_Error("Unknown AnimEnt type!\n");
|
||||
|
@ -2385,6 +2865,23 @@ void G_SpawnExampleAnimEnt(vec3_t pos, int aeType)
|
|||
{
|
||||
animEnt->s.weapon = WP_DISRUPTOR; //These guys get disruptors instead of blasters.
|
||||
}
|
||||
else if (animEnt->watertype == ANIMENT_TYPE_JAN)
|
||||
{
|
||||
animEnt->s.weapon = WP_BLASTER;
|
||||
}
|
||||
else if (animEnt->watertype == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
animentCustomInfo_t *aeInfo = ExampleAnimEntCustomData(animEnt);
|
||||
|
||||
if (aeInfo)
|
||||
{
|
||||
animEnt->s.weapon = aeInfo->aeWeapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
animEnt->s.weapon = WP_BLASTER;
|
||||
}
|
||||
}
|
||||
|
||||
animEnt->s.modelGhoul2 = 1; //Deal with it like any other ghoul2 ent, as far as killing instances.
|
||||
|
||||
|
@ -2433,7 +2930,7 @@ qboolean gEscaping = qfalse;
|
|||
int gEscapeTime = 0;
|
||||
|
||||
#ifdef ANIMENT_SPAWNER
|
||||
int AESpawner_CountAnimEnts(void)
|
||||
int AESpawner_CountAnimEnts(gentity_t *spawner, qboolean onlySameType)
|
||||
{
|
||||
int i = 0;
|
||||
int count = 0;
|
||||
|
@ -2442,7 +2939,27 @@ int AESpawner_CountAnimEnts(void)
|
|||
{
|
||||
if (g_entities[i].inuse && g_entities[i].s.eType == ET_GRAPPLE)
|
||||
{
|
||||
count++;
|
||||
if (!onlySameType)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spawner->watertype == g_entities[i].watertype)
|
||||
{
|
||||
if (spawner->watertype == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
if (spawner->waterlevel == g_entities[i].waterlevel)
|
||||
{ //only count it if it's the same custom type template, indicated by equal "waterlevel" value.
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -2500,6 +3017,7 @@ qboolean AESpawner_PassAnimEntPVSCheck(gentity_t *ent)
|
|||
void AESpawner_Think(gentity_t *ent)
|
||||
{
|
||||
int animEntCount;
|
||||
animentCustomInfo_t *aeInfo = NULL;
|
||||
|
||||
if (gBotEdit)
|
||||
{
|
||||
|
@ -2513,7 +3031,13 @@ void AESpawner_Think(gentity_t *ent)
|
|||
}
|
||||
else
|
||||
{
|
||||
animEntCount = AESpawner_CountAnimEnts();
|
||||
qboolean onlySameType = qfalse;
|
||||
|
||||
if (ent->bolt_RLeg)
|
||||
{
|
||||
onlySameType = qtrue;
|
||||
}
|
||||
animEntCount = AESpawner_CountAnimEnts(ent, onlySameType);
|
||||
}
|
||||
|
||||
if (animEntCount < ent->bolt_LLeg)
|
||||
|
@ -2533,7 +3057,11 @@ void AESpawner_Think(gentity_t *ent)
|
|||
{
|
||||
if (AESpawner_PassAnimEntPVSCheck(ent))
|
||||
{
|
||||
G_SpawnExampleAnimEnt(ent->s.origin, ent->watertype);
|
||||
if (ent->watertype == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
aeInfo = ExampleAnimEntCustomData(ent); //we can get this info from the spawner, because it has its waterlevel set too.
|
||||
}
|
||||
G_SpawnExampleAnimEnt(ent->s.origin, ent->watertype, aeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2560,6 +3088,9 @@ void SP_misc_animent_spawner(gentity_t *ent)
|
|||
//0 is unlimited, but that could cause horrible disaster.
|
||||
G_SpawnInt( "spawntype", "0", &ent->watertype);
|
||||
//Spawn type. 0 is stormtrooper, 1 is rodian.
|
||||
G_SpawnInt( "sametype", "1", &ent->bolt_RLeg);
|
||||
//If 1, only counts other animates of the same type for deciding whether or not to spawn (as opposed to all types).
|
||||
//Default is 1.
|
||||
|
||||
//Just precache the assets now
|
||||
if (ent->watertype == ANIMENT_TYPE_STORMTROOPER)
|
||||
|
@ -2600,6 +3131,52 @@ void SP_misc_animent_spawner(gentity_t *ent)
|
|||
|
||||
G_ModelIndex( "models/players/rodian/model.glm" );
|
||||
}
|
||||
else if (ent->watertype == ANIMENT_TYPE_JAN)
|
||||
{
|
||||
gJanSound_Pain[0] = G_SoundIndex("sound/chars/jan/misc/pain25");
|
||||
gJanSound_Pain[1] = G_SoundIndex("sound/chars/jan/misc/pain50");
|
||||
gJanSound_Pain[2] = G_SoundIndex("sound/chars/jan/misc/pain75");
|
||||
gJanSound_Pain[3] = G_SoundIndex("sound/chars/jan/misc/pain100");
|
||||
|
||||
gJanSound_Death[0] = G_SoundIndex("sound/chars/jan/misc/death1");
|
||||
gJanSound_Death[1] = G_SoundIndex("sound/chars/jan/misc/death2");
|
||||
gJanSound_Death[2] = G_SoundIndex("sound/chars/jan/misc/death3");
|
||||
|
||||
gJanSound_Alert[0] = G_SoundIndex("sound/chars/jan/misc/detected1");
|
||||
gJanSound_Alert[1] = G_SoundIndex("sound/chars/jan/misc/detected2");
|
||||
gJanSound_Alert[2] = G_SoundIndex("sound/chars/jan/misc/detected3");
|
||||
gJanSound_Alert[3] = G_SoundIndex("sound/chars/jan/misc/detected4");
|
||||
gJanSound_Alert[4] = G_SoundIndex("sound/chars/jan/misc/detected5");
|
||||
|
||||
G_ModelIndex( "models/players/jan/model.glm" );
|
||||
}
|
||||
else if (ent->watertype == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
int alignment = 1;
|
||||
int weapon = 3;
|
||||
char *model;
|
||||
char *soundpath;
|
||||
animentCustomInfo_t *aeInfo;
|
||||
|
||||
G_SpawnInt( "ae_aligned", "1", &alignment );
|
||||
//Alignedment - 1 is bad, 2 is good.
|
||||
G_SpawnInt( "ae_weapon", "3", &weapon);
|
||||
//Weapon - Same values as normal weapons.
|
||||
G_SpawnString( "ae_model", "models/players/stormtrooper/model.glm", &model);
|
||||
//Model to use
|
||||
G_SpawnString( "ae_soundpath", "sound/chars/jan/misc", &soundpath);
|
||||
//Sound path to use
|
||||
|
||||
ExampleAnimEntCustomDataEntry(ent, alignment, weapon, model, soundpath);
|
||||
|
||||
aeInfo = ExampleAnimEntCustomData(ent);
|
||||
|
||||
if (aeInfo)
|
||||
{
|
||||
AnimEntCustomSoundPrecache(aeInfo);
|
||||
G_ModelIndex( aeInfo->modelPath );
|
||||
}
|
||||
}
|
||||
|
||||
ent->think = AESpawner_Think;
|
||||
ent->nextthink = level.time + Q_irand(50, 500);
|
||||
|
@ -2689,6 +3266,28 @@ void SP_target_escapetrig(gentity_t *ent)
|
|||
void G_CreateExampleAnimEnt(gentity_t *ent)
|
||||
{
|
||||
vec3_t fwd, fwdPos;
|
||||
animentCustomInfo_t aeInfo;
|
||||
char arg[MAX_STRING_CHARS];
|
||||
int iArg = 0;
|
||||
int argNum = trap_Argc();
|
||||
|
||||
memset(&aeInfo, 0, sizeof(aeInfo));
|
||||
|
||||
if (argNum > 1)
|
||||
{
|
||||
trap_Argv( 1, arg, sizeof( arg ) );
|
||||
|
||||
iArg = atoi(arg);
|
||||
|
||||
if (iArg < 0)
|
||||
{
|
||||
iArg = 0;
|
||||
}
|
||||
if (iArg >= MAX_ANIMENTS)
|
||||
{
|
||||
iArg = MAX_ANIMENTS-1;
|
||||
}
|
||||
}
|
||||
|
||||
AngleVectors(ent->client->ps.viewangles, fwd, 0, 0);
|
||||
|
||||
|
@ -2696,7 +3295,52 @@ void G_CreateExampleAnimEnt(gentity_t *ent)
|
|||
fwdPos[1] = ent->client->ps.origin[1] + fwd[1]*128;
|
||||
fwdPos[2] = ent->client->ps.origin[2] + fwd[2]*128;
|
||||
|
||||
G_SpawnExampleAnimEnt(fwdPos, 0);
|
||||
if (iArg == ANIMENT_TYPE_CUSTOM)
|
||||
{
|
||||
char arg2[MAX_STRING_CHARS];
|
||||
|
||||
if (argNum > 2)
|
||||
{
|
||||
trap_Argv( 2, arg, sizeof( arg ) );
|
||||
aeInfo.aeAlignment = atoi(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
aeInfo.aeAlignment = ANIMENT_ALIGNED_BAD;
|
||||
}
|
||||
|
||||
if (argNum > 3)
|
||||
{
|
||||
trap_Argv( 3, arg, sizeof( arg ) );
|
||||
aeInfo.aeWeapon = atoi(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
aeInfo.aeWeapon = WP_BRYAR_PISTOL;
|
||||
}
|
||||
|
||||
if (argNum > 4)
|
||||
{
|
||||
trap_Argv( 4, arg, sizeof( arg ) );
|
||||
aeInfo.modelPath = arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
aeInfo.modelPath = "models/players/stormtrooper/model.glm";
|
||||
}
|
||||
|
||||
if (argNum > 5)
|
||||
{
|
||||
trap_Argv( 5, arg2, sizeof( arg2 ) );
|
||||
aeInfo.soundPath = arg2;
|
||||
}
|
||||
else
|
||||
{
|
||||
aeInfo.soundPath = "sound/chars/jan/misc";
|
||||
}
|
||||
}
|
||||
|
||||
G_SpawnExampleAnimEnt(fwdPos, iArg, &aeInfo);
|
||||
}
|
||||
//rww - here ends the main example g2animent stuff
|
||||
|
||||
|
|
|
@ -190,7 +190,23 @@ qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 ) {
|
|||
|
||||
if (g_gametype.integer == GT_SINGLE_PLAYER)
|
||||
{
|
||||
return qtrue;
|
||||
qboolean ent1IsBot = qfalse;
|
||||
qboolean ent2IsBot = qfalse;
|
||||
|
||||
if (ent1->r.svFlags & SVF_BOT)
|
||||
{
|
||||
ent1IsBot = qtrue;
|
||||
}
|
||||
if (ent2->r.svFlags & SVF_BOT)
|
||||
{
|
||||
ent2IsBot = qtrue;
|
||||
}
|
||||
|
||||
if ((ent1IsBot && ent2IsBot) || (!ent1IsBot && !ent2IsBot))
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( g_gametype.integer < GT_TEAM ) {
|
||||
|
|
|
@ -816,7 +816,14 @@ static void WP_BowcasterMainFire( gentity_t *ent )
|
|||
gentity_t *missile;
|
||||
int i;
|
||||
|
||||
count = ( level.time - ent->client->ps.weaponChargeTime ) / BOWCASTER_CHARGE_UNIT;
|
||||
if (!ent->client)
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = ( level.time - ent->client->ps.weaponChargeTime ) / BOWCASTER_CHARGE_UNIT;
|
||||
}
|
||||
|
||||
if ( count < 1 )
|
||||
{
|
||||
|
@ -2524,8 +2531,16 @@ void WP_FireStunBaton( gentity_t *ent, qboolean alt_fire )
|
|||
vec3_t mins, maxs, end;
|
||||
vec3_t muzzleStun;
|
||||
|
||||
VectorCopy(ent->client->ps.origin, muzzleStun);
|
||||
muzzleStun[2] += ent->client->ps.viewheight-6;
|
||||
if (!ent->client)
|
||||
{
|
||||
VectorCopy(ent->r.currentOrigin, muzzleStun);
|
||||
muzzleStun[2] += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(ent->client->ps.origin, muzzleStun);
|
||||
muzzleStun[2] += ent->client->ps.viewheight-6;
|
||||
}
|
||||
|
||||
muzzleStun[0] += forward[0]*20;
|
||||
muzzleStun[1] += forward[1]*20;
|
||||
|
@ -2557,7 +2572,8 @@ void WP_FireStunBaton( gentity_t *ent, qboolean alt_fire )
|
|||
return;
|
||||
}
|
||||
|
||||
if (ent->client->ps.duelInProgress &&
|
||||
if (ent->client &&
|
||||
ent->client->ps.duelInProgress &&
|
||||
ent->client->ps.duelIndex != tr_ent->s.number)
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -672,7 +672,7 @@ extern vec4_t colorDkBlue;
|
|||
|
||||
#define Q_COLOR_ESCAPE '^'
|
||||
// you MUST have the last bit on here about colour strings being less than 7 or taiwanese strings register as colour!!!!
|
||||
#define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE && *((p)+1) <= '7' )
|
||||
#define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE && *((p)+1) <= '7' && *((p)+1) >= '0' )
|
||||
|
||||
|
||||
#define COLOR_BLACK '0'
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#define CONTENTS_WATER 0x00000004
|
||||
#define CONTENTS_FOG 0x00000008
|
||||
#define CONTENTS_PLAYERCLIP 0x00000010
|
||||
#define CONTENTS_MONSTERCLIP 0x00000020
|
||||
#define CONTENTS_BOTCLIP 0x00000040
|
||||
#define CONTENTS_MONSTERCLIP 0x00000020 // Physically block bots
|
||||
#define CONTENTS_BOTCLIP 0x00000040 // A hint for bots - do not enter this brush by navigation (if possible)
|
||||
#define CONTENTS_SHOTCLIP 0x00000080
|
||||
#define CONTENTS_BODY 0x00000100 // should never be on a brush, only in game
|
||||
#define CONTENTS_CORPSE 0x00000200 // should never be on a brush, only in game
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1089,7 +1089,8 @@ static bool G2_RadiusTracePolys( const mdxmSurface_t *surface, const vec3_t rayS
|
|||
{
|
||||
// we hit a triangle, so init a collision record...
|
||||
//
|
||||
for (int i=0; i<MAX_G2_COLLISIONS;i++)
|
||||
int i=0;
|
||||
for (i=0; i<MAX_G2_COLLISIONS;i++)
|
||||
{
|
||||
if (collRecMap[i].mEntityNum == -1)
|
||||
{
|
||||
|
|
53
CODE-mp/jk2mp-SDK.dsw
Normal file
53
CODE-mp/jk2mp-SDK.dsw
Normal file
|
@ -0,0 +1,53 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "JK2cgame"=".\cgame\JK2_cgame.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "JK2game"=".\game\JK2_game.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ui"=".\ui\ui.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
BIN
CODE-mp/jk2mp-SDK.opt
Normal file
BIN
CODE-mp/jk2mp-SDK.opt
Normal file
Binary file not shown.
Binary file not shown.
|
@ -3,6 +3,6 @@
|
|||
|
||||
// Current version of the multi player game
|
||||
|
||||
#define Q3_VERSION "JK2MP: v1.03"
|
||||
#define Q3_VERSION "JK2MP: v1.04"
|
||||
|
||||
//end
|
||||
|
|
|
@ -321,8 +321,8 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
|
||||
// read the fragment information
|
||||
if ( fragmented ) {
|
||||
fragmentStart = MSG_ReadShort( msg );
|
||||
fragmentLength = MSG_ReadShort( msg );
|
||||
fragmentStart = (unsigned short)MSG_ReadShort( msg );
|
||||
fragmentLength = (unsigned short)MSG_ReadShort( msg );
|
||||
} else {
|
||||
fragmentStart = 0; // stop warning message
|
||||
fragmentLength = 0;
|
||||
|
@ -425,10 +425,10 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
if ( chan->fragmentLength > msg->maxsize ) {
|
||||
if ( chan->fragmentLength+4 > msg->maxsize ) {
|
||||
Com_Printf( "%s:fragmentLength %i > msg->maxsize\n"
|
||||
, NET_AdrToString (chan->remoteAddress ),
|
||||
chan->fragmentLength );
|
||||
chan->fragmentLength+4 );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -437,10 +437,6 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
// make sure the sequence number is still there
|
||||
*(int *)msg->data = LittleLong( sequence );
|
||||
|
||||
if ( chan->fragmentLength + 4 > MAX_MSGLEN )
|
||||
{
|
||||
Com_Error( ERR_DROP, "Netchan_Process: length = %i",chan->fragmentLength + 4);
|
||||
}
|
||||
Com_Memcpy( msg->data + 4, chan->fragmentBuffer, chan->fragmentLength );
|
||||
msg->cursize = chan->fragmentLength + 4;
|
||||
chan->fragmentLength = 0;
|
||||
|
|
|
@ -196,7 +196,8 @@ PROTOCOL
|
|||
==============================================================
|
||||
*/
|
||||
|
||||
#define PROTOCOL_VERSION 15
|
||||
//v1.03 #define PROTOCOL_VERSION 15
|
||||
#define PROTOCOL_VERSION 16 //v1.04
|
||||
|
||||
#define UPDATE_SERVER_NAME "updatejk2.ravensoft.com"
|
||||
#define MASTER_SERVER_NAME "masterjk2.ravensoft.com"
|
||||
|
|
|
@ -671,6 +671,7 @@ static void SV_Status_f( void )
|
|||
const char *s;
|
||||
int ping;
|
||||
char state[32];
|
||||
qboolean avoidTruncation = qfalse;
|
||||
|
||||
// make sure server is running
|
||||
if ( !com_sv_running->integer )
|
||||
|
@ -679,6 +680,14 @@ static void SV_Status_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
if ( Cmd_Argc() > 1 )
|
||||
{
|
||||
if (!Q_stricmp("notrunc", Cmd_Argv(1)))
|
||||
{
|
||||
avoidTruncation = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
Com_Printf ("map: %s\n", sv_mapname->string );
|
||||
|
||||
Com_Printf ("num score ping name lastmsg address qport rate\n");
|
||||
|
@ -706,16 +715,33 @@ static void SV_Status_f( void )
|
|||
|
||||
ps = SV_GameClientNum( i );
|
||||
s = NET_AdrToString( cl->netchan.remoteAddress );
|
||||
Com_Printf ("%3i %5i %s %-15.15s %7i %21s %5i %5i\n",
|
||||
i,
|
||||
ps->persistant[PERS_SCORE],
|
||||
state,
|
||||
cl->name,
|
||||
svs.time - cl->lastPacketTime,
|
||||
s,
|
||||
cl->netchan.qport,
|
||||
cl->rate
|
||||
);
|
||||
|
||||
if (!avoidTruncation)
|
||||
{
|
||||
Com_Printf ("%3i %5i %s %-15.15s %7i %21s %5i %5i\n",
|
||||
i,
|
||||
ps->persistant[PERS_SCORE],
|
||||
state,
|
||||
cl->name,
|
||||
svs.time - cl->lastPacketTime,
|
||||
s,
|
||||
cl->netchan.qport,
|
||||
cl->rate
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf ("%3i %5i %s %s %7i %21s %5i %5i\n",
|
||||
i,
|
||||
ps->persistant[PERS_SCORE],
|
||||
state,
|
||||
cl->name,
|
||||
svs.time - cl->lastPacketTime,
|
||||
s,
|
||||
cl->netchan.qport,
|
||||
cl->rate
|
||||
);
|
||||
}
|
||||
}
|
||||
Com_Printf ("\n");
|
||||
}
|
||||
|
|
|
@ -756,7 +756,7 @@ void SV_Frame( int msec ) {
|
|||
|
||||
if (!com_dedicated->integer) SV_BotFrame( svs.time + sv.timeResidual );
|
||||
|
||||
if ( com_dedicated->integer && sv.timeResidual < frameMsec ) {
|
||||
if ( com_dedicated->integer && sv.timeResidual < frameMsec && (!com_timescale || com_timescale->value >= 1) ) {
|
||||
// NET_Sleep will give the OS time slices until either get a packet
|
||||
// or time enough for a server frame has gone by
|
||||
NET_Sleep(frameMsec - sv.timeResidual);
|
||||
|
|
|
@ -20,8 +20,6 @@ set cc=lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\
|
|||
@if errorlevel 1 goto quit
|
||||
%cc% ../ui_force.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../ui_util.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../ui_shared.c
|
||||
@if errorlevel 1 goto quit
|
||||
%cc% ../ui_gameinfo.c
|
||||
|
|
|
@ -172,10 +172,6 @@ SOURCE=.\ui_shared.c
|
|||
|
||||
SOURCE=.\ui_syscalls.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ui_util.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ ui_main
|
|||
..\ui_syscalls
|
||||
ui_atoms
|
||||
ui_force
|
||||
ui_util
|
||||
ui_shared
|
||||
ui_gameinfo
|
||||
bg_misc
|
||||
|
|
|
@ -777,6 +777,8 @@ typedef struct {
|
|||
char teamNames[MAX_CLIENTS][MAX_NAME_LENGTH];
|
||||
int teamClientNums[MAX_CLIENTS];
|
||||
|
||||
int playerIndexes[MAX_CLIENTS]; //so we can vote-kick by index
|
||||
|
||||
int mapCount;
|
||||
mapInfo mapList[MAX_MAPS];
|
||||
|
||||
|
|
|
@ -1736,20 +1736,22 @@ void UpdateForceStatus()
|
|||
}
|
||||
|
||||
|
||||
// Take the current team and force a skin color based on it.
|
||||
switch((int)(trap_Cvar_VariableValue("ui_myteam")))
|
||||
{
|
||||
case TEAM_RED:
|
||||
uiSkinColor = TEAM_RED;
|
||||
uiInfo.effectsColor = SABER_RED;
|
||||
break;
|
||||
case TEAM_BLUE:
|
||||
uiSkinColor = TEAM_BLUE;
|
||||
uiInfo.effectsColor = SABER_BLUE;
|
||||
break;
|
||||
default:
|
||||
uiSkinColor = TEAM_FREE;
|
||||
break;
|
||||
if ( !UI_TrueJediEnabled() )
|
||||
{// Take the current team and force a skin color based on it.
|
||||
switch((int)(trap_Cvar_VariableValue("ui_myteam")))
|
||||
{
|
||||
case TEAM_RED:
|
||||
uiSkinColor = TEAM_RED;
|
||||
uiInfo.effectsColor = SABER_RED;
|
||||
break;
|
||||
case TEAM_BLUE:
|
||||
uiSkinColor = TEAM_BLUE;
|
||||
uiInfo.effectsColor = SABER_BLUE;
|
||||
break;
|
||||
default:
|
||||
uiSkinColor = TEAM_FREE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2373,6 +2375,7 @@ static void UI_BuildPlayerList() {
|
|||
if (info[0]) {
|
||||
Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount], Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
|
||||
Q_CleanStr( uiInfo.playerNames[uiInfo.playerCount] );
|
||||
uiInfo.playerIndexes[uiInfo.playerCount] = n;
|
||||
uiInfo.playerCount++;
|
||||
team2 = atoi(Info_ValueForKey(info, "t"));
|
||||
if (team2 == team && n != uiInfo.playerNumber) {
|
||||
|
@ -2989,32 +2992,34 @@ static qboolean UI_Handicap_HandleKey(int flags, float *special, int key) {
|
|||
}
|
||||
|
||||
static qboolean UI_Effects_HandleKey(int flags, float *special, int key) {
|
||||
if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
|
||||
|
||||
int team = (int)(trap_Cvar_VariableValue("ui_myteam"));
|
||||
|
||||
if (team == TEAM_RED || team==TEAM_BLUE)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
|
||||
|
||||
if ( !UI_TrueJediEnabled() )
|
||||
{
|
||||
int team = (int)(trap_Cvar_VariableValue("ui_myteam"));
|
||||
|
||||
if (team == TEAM_RED || team==TEAM_BLUE)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
if (key == A_MOUSE2) {
|
||||
uiInfo.effectsColor--;
|
||||
uiInfo.effectsColor--;
|
||||
} else {
|
||||
uiInfo.effectsColor++;
|
||||
uiInfo.effectsColor++;
|
||||
}
|
||||
|
||||
if( uiInfo.effectsColor > 5 ) {
|
||||
uiInfo.effectsColor = 0;
|
||||
|
||||
if( uiInfo.effectsColor > 5 ) {
|
||||
uiInfo.effectsColor = 0;
|
||||
} else if (uiInfo.effectsColor < 0) {
|
||||
uiInfo.effectsColor = 5;
|
||||
uiInfo.effectsColor = 5;
|
||||
}
|
||||
|
||||
trap_Cvar_SetValue( "color1", /*uitogamecode[uiInfo.effectsColor]*/uiInfo.effectsColor );
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
|
||||
trap_Cvar_SetValue( "color1", /*uitogamecode[uiInfo.effectsColor]*/uiInfo.effectsColor );
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static qboolean UI_ClanName_HandleKey(int flags, float *special, int key) {
|
||||
|
@ -4419,7 +4424,8 @@ static void UI_RunMenuScript(char **args)
|
|||
}
|
||||
} else if (Q_stricmp(name, "voteKick") == 0) {
|
||||
if (uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount) {
|
||||
trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote kick \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex]) );
|
||||
//trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote kick \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex]) );
|
||||
trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote clientkick \"%i\"\n",uiInfo.playerIndexes[uiInfo.playerIndex]) );
|
||||
}
|
||||
} else if (Q_stricmp(name, "voteGame") == 0) {
|
||||
if (ui_netGameType.integer >= 0 && ui_netGameType.integer < uiInfo.numGameTypes) {
|
||||
|
@ -6922,7 +6928,7 @@ void UI_DrawConnectScreen( qboolean overlay ) {
|
|||
//UI_DrawProportionalString( 320, 96, "Press Esc to abort", UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color );
|
||||
|
||||
// display global MOTD at bottom
|
||||
Text_PaintCenter(centerPoint, 600, scale, colorWhite, Info_ValueForKey( cstate.updateInfoString, "motd" ), 0, FONT_MEDIUM);
|
||||
Text_PaintCenter(centerPoint, 425, scale, colorWhite, Info_ValueForKey( cstate.updateInfoString, "motd" ), 0, FONT_MEDIUM);
|
||||
// print any server info (server full, bad version, etc)
|
||||
if ( cstate.connState < CA_CONNECTED ) {
|
||||
Text_PaintCenter(centerPoint, yStart + 176, scale, colorWhite, cstate.messageString, 0, FONT_MEDIUM);
|
||||
|
@ -7392,10 +7398,10 @@ static void UI_StartServerRefresh(qboolean full)
|
|||
|
||||
ptr = UI_Cvar_VariableString("debug_protocol");
|
||||
if (strlen(ptr)) {
|
||||
trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %s full empty\n", i, ptr));
|
||||
trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %s\n", i, ptr));
|
||||
}
|
||||
else {
|
||||
trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %d full empty\n", i, (int)trap_Cvar_VariableValue( "protocol" ) ) );
|
||||
trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %d\n", i, (int)trap_Cvar_VariableValue( "protocol" ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4087,13 +4087,13 @@ void BindingFromName(const char *cvar) {
|
|||
break;
|
||||
}
|
||||
DC->keynumToStringBuf( b1, g_nameBind1, 32 );
|
||||
Q_strupr(g_nameBind1);
|
||||
// do NOT do this or it corrupts asian text!!! Q_strupr(g_nameBind1);
|
||||
|
||||
b2 = g_bindings[i].bind2;
|
||||
if (b2 != -1)
|
||||
{
|
||||
DC->keynumToStringBuf( b2, g_nameBind2, 32 );
|
||||
Q_strupr(g_nameBind2);
|
||||
// do NOT do this or it corrupts asian text!!! Q_strupr(g_nameBind2);
|
||||
|
||||
trap_SP_GetStringTextString("MENUS3_KEYBIND_OR",sOR, sizeof(sOR));
|
||||
|
||||
|
@ -4634,6 +4634,7 @@ void Item_ListBox_Paint(itemDef_t *item) {
|
|||
{
|
||||
imageStartX = listPtr->columnInfo[j+1].pos;
|
||||
}
|
||||
DC->setColor( NULL );
|
||||
if (optionalImage3 >= 0) {
|
||||
DC->drawHandlePic(imageStartX - listPtr->elementHeight*3, y+2, listPtr->elementHeight, listPtr->elementHeight, optionalImage3);
|
||||
}
|
||||
|
|
|
@ -5,4 +5,7 @@
|
|||
//
|
||||
// memory, string alloc
|
||||
|
||||
|
||||
void RichIsGettingTiredOfEmptyFileVMCompilerWarnings()
|
||||
{
|
||||
int andUnderstandablySo = 0;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ DLL_ONLY=false
|
|||
# bk001205: no mo' -I/usr/include/glide, no FX
|
||||
# bk001205: no mo' -Dstricmp=strcasecmp, see q_shared.h
|
||||
#BASE_CFLAGS = -pipe -fsigned-char -x c++ -D_JK2 -D_M_IX86 -I/home/drews/STLport-4.5.3/stlport -I/opt/intel/compiler50/ia32/include
|
||||
BASE_CFLAGS = -pipe -fsigned-char -Kc++ -D_JK2 -D_M_IX86 -I/opt/intel/compiler50/ia32/include
|
||||
BASE_CFLAGS = -pipe -fsigned-char -Kc++ -D_JK2 -D_M_IX86 -I/opt/intel/compiler50/ia32/include
|
||||
# rcg010216: DLL_ONLY for PPC
|
||||
ifeq ($(strip $(DLL_ONLY)),true)
|
||||
BASE_CFLAGS += -DDLL_ONLY
|
||||
|
@ -95,12 +95,12 @@ DLL_ONLY=false
|
|||
# DEBUG_CFLAGS=$(BASE_CFLAGS) -g -Wall -Werror -O
|
||||
ifeq ($(ARCH),axp)
|
||||
CC=pgcc
|
||||
RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O6 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations
|
||||
RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O2 -unroll
|
||||
else
|
||||
ifeq ($(ARCH),ppc)
|
||||
NEWPGCC=/loki/global/ppc/bin/gcc
|
||||
CC=$(NEWPGCC)
|
||||
RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O6 -fomit-frame-pointer -pipe -ffast-math -malign-loops=2 -malign-jumps=2 -malign-functions=2 -fno-strict-aliasing -fstrength-reduce
|
||||
RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O2 -pipe -unroll
|
||||
else
|
||||
#NEWPGCC=/usr/local/gcc-2.95.2/bin/gcc # bk001205
|
||||
#NEWPGCC=/loki/global/x86/bin/gcc
|
||||
|
@ -112,7 +112,7 @@ DLL_ONLY=false
|
|||
# TTimo: legacy RELEASE_CFLAGS
|
||||
# NOTE: the -fomit-frame-pointer option leads to an unstable binary on my test box if it was built on the main box
|
||||
# but building on the Mdk 7.2 baseline seems to work
|
||||
RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O6 -mcpu=pentiumpro -march=pentium -fomit-frame-pointer -pipe -ffast-math -malign-loops=2 -malign-jumps=2 -malign-functions=2 -fno-strict-aliasing -fstrength-reduce
|
||||
RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O2 -unroll -tpp6
|
||||
# TTimo: use this for building on P3 gcc 2.95.3 libc2.2 for all targets (experimental! -fomit-fram-pointer removed)
|
||||
# RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O6 -mcpu=pentiumpro -march=pentium -pipe -ffast-math -malign-loops=2 -malign-jumps=2 -malign-functions=2 -fno-strict-aliasing -fstrength-reduce
|
||||
endif
|
||||
|
@ -129,7 +129,7 @@ DLL_ONLY=false
|
|||
|
||||
THREAD_LDFLAGS=-lpthread
|
||||
#LDFLAGS=/opt/sxl/lib/sxlgcc3.a -lpthread -ldl -lm -lstdc++ -static -Wl --gc-sections
|
||||
LDFLAGS=-ldl -lm -lstdc++ -static
|
||||
LDFLAGS=-ldl -lm -static
|
||||
GLLDFLAGS=-L/usr/X11R6/lib -L$(MESADIR)/lib -lX11 -lXext -lXxf86dga -lXxf86vm
|
||||
|
||||
TARGETS=\
|
||||
|
@ -213,7 +213,6 @@ Q3DOBJ = \
|
|||
$(B)/ded/cm_polylib.o \
|
||||
$(B)/ded/cm_test.o \
|
||||
$(B)/ded/cm_trace.o \
|
||||
$(B)/ded/cm_shader.o \
|
||||
$(B)/ded/cmd.o \
|
||||
$(B)/ded/common.o \
|
||||
$(B)/ded/cvar.o \
|
||||
|
|
|
@ -254,7 +254,7 @@ qboolean Sys_IsLANAddress (netadr_t adr) {
|
|||
|
||||
// choose which comparison to use based on the class of the address being tested
|
||||
// any local adresses of a different class than the address being tested will fail based on the first byte
|
||||
|
||||
/*
|
||||
// Class A
|
||||
if( (adr.ip[0] & 0x80) == 0x00 ) {
|
||||
for ( i = 0 ; i < numIP ; i++ ) {
|
||||
|
@ -279,7 +279,8 @@ qboolean Sys_IsLANAddress (netadr_t adr) {
|
|||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
*/
|
||||
//we only look at class C since ISPs and Universities are using class A but we don't want to consider them on the same LAN.
|
||||
// Class C
|
||||
for ( i = 0 ; i < numIP ; i++ ) {
|
||||
if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] && adr.ip[2] == localIP[i][2] ) {
|
||||
|
@ -412,6 +413,9 @@ void NET_GetLocalAddress( void ) {
|
|||
int ip;
|
||||
int n;
|
||||
|
||||
// Set this early so we can just return if there is an error
|
||||
numIP = 0;
|
||||
|
||||
if ( gethostname( hostname, 256 ) == -1 ) {
|
||||
return;
|
||||
}
|
||||
|
@ -431,14 +435,14 @@ void NET_GetLocalAddress( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
numIP = 0;
|
||||
while( ( p = hostInfo->h_addr_list[numIP++] ) != NULL && numIP < MAX_IPS ) {
|
||||
while( ( p = hostInfo->h_addr_list[numIP] ) != NULL && numIP < MAX_IPS ) {
|
||||
ip = ntohl( *(int *)p );
|
||||
localIP[ numIP ][0] = p[0];
|
||||
localIP[ numIP ][1] = p[1];
|
||||
localIP[ numIP ][2] = p[2];
|
||||
localIP[ numIP ][3] = p[3];
|
||||
Com_Printf( "IP: %i.%i.%i.%i\n", ( ip >> 24 ) & 0xff, ( ip >> 16 ) & 0xff, ( ip >> 8 ) & 0xff, ip & 0xff );
|
||||
numIP++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -397,6 +397,7 @@ qboolean Sys_IsLANAddress( netadr_t adr ) {
|
|||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
// Class A
|
||||
if( (adr.ip[0] & 0x80) == 0x00 ) {
|
||||
for ( i = 0 ; i < numIP ; i++ ) {
|
||||
|
@ -421,6 +422,8 @@ qboolean Sys_IsLANAddress( netadr_t adr ) {
|
|||
}
|
||||
return qfalse;
|
||||
}
|
||||
*/
|
||||
//we only look at class C since ISPs and Universities are using class A but we don't want to consider them on the same LAN.
|
||||
|
||||
// Class C
|
||||
for ( i = 0 ; i < numIP ; i++ ) {
|
||||
|
@ -707,6 +710,9 @@ void NET_GetLocalAddress( void ) {
|
|||
int ip;
|
||||
int n;
|
||||
|
||||
// Set this early so we can just return if there is an error
|
||||
numIP = 0;
|
||||
|
||||
if( gethostname( hostname, 256 ) == SOCKET_ERROR ) {
|
||||
error = WSAGetLastError();
|
||||
return;
|
||||
|
@ -728,7 +734,6 @@ void NET_GetLocalAddress( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
numIP = 0;
|
||||
while( ( p = hostInfo->h_addr_list[numIP] ) != NULL && numIP < MAX_IPS ) {
|
||||
ip = ntohl( *(int *)p );
|
||||
localIP[ numIP ][0] = p[0];
|
||||
|
|
Loading…
Reference in a new issue