mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
Various bugfixes by Tobias Kuehnhammer (#5270)
- A stupid bug where bots re-trigger jumppads if they fell onto it. - A small "memset" bug concerning player animations. - Reward sounds were never cleared and thus they are played on a map restart. - Safer and more secure handling of disconnected clients and clients with malformed or illegal info strings. - first_gauntlet_hit.wav was not played (ops/ps) bug - capturelimit not hit (from OAX)
This commit is contained in:
parent
1af9c636a5
commit
56f16e10d6
11 changed files with 32 additions and 29 deletions
|
@ -742,7 +742,7 @@ void BotAddAvoidSpot(int movestate, vec3_t origin, float radius, int type)
|
||||||
int BotGetReachabilityToGoal(vec3_t origin, int areanum,
|
int BotGetReachabilityToGoal(vec3_t origin, int areanum,
|
||||||
int lastgoalareanum, int lastareanum,
|
int lastgoalareanum, int lastareanum,
|
||||||
int *avoidreach, float *avoidreachtimes, int *avoidreachtries,
|
int *avoidreach, float *avoidreachtimes, int *avoidreachtries,
|
||||||
bot_goal_t *goal, int travelflags, int movetravelflags,
|
bot_goal_t *goal, int travelflags,
|
||||||
struct bot_avoidspot_s *avoidspots, int numavoidspots, int *flags)
|
struct bot_avoidspot_s *avoidspots, int numavoidspots, int *flags)
|
||||||
{
|
{
|
||||||
int i, t, besttime, bestreachnum, reachnum;
|
int i, t, besttime, bestreachnum, reachnum;
|
||||||
|
@ -754,7 +754,6 @@ int BotGetReachabilityToGoal(vec3_t origin, int areanum,
|
||||||
if (AAS_AreaDoNotEnter(areanum) || AAS_AreaDoNotEnter(goal->areanum))
|
if (AAS_AreaDoNotEnter(areanum) || AAS_AreaDoNotEnter(goal->areanum))
|
||||||
{
|
{
|
||||||
travelflags |= TFL_DONOTENTER;
|
travelflags |= TFL_DONOTENTER;
|
||||||
movetravelflags |= TFL_DONOTENTER;
|
|
||||||
} //end if
|
} //end if
|
||||||
//use the routing to find the next area to go to
|
//use the routing to find the next area to go to
|
||||||
besttime = 0;
|
besttime = 0;
|
||||||
|
@ -787,7 +786,7 @@ int BotGetReachabilityToGoal(vec3_t origin, int areanum,
|
||||||
if (lastgoalareanum == goal->areanum && reach.areanum == lastareanum) continue;
|
if (lastgoalareanum == goal->areanum && reach.areanum == lastareanum) continue;
|
||||||
//if (AAS_AreaContentsTravelFlags(reach.areanum) & ~travelflags) continue;
|
//if (AAS_AreaContentsTravelFlags(reach.areanum) & ~travelflags) continue;
|
||||||
//if the travel isn't valid
|
//if the travel isn't valid
|
||||||
if (!BotValidTravel(origin, &reach, movetravelflags)) continue;
|
if (!BotValidTravel(origin, &reach, travelflags)) continue;
|
||||||
//get the travel time
|
//get the travel time
|
||||||
t = AAS_AreaTravelTimeToGoalArea(reach.areanum, reach.end, goal->areanum, travelflags);
|
t = AAS_AreaTravelTimeToGoalArea(reach.areanum, reach.end, goal->areanum, travelflags);
|
||||||
//if the goal area isn't reachable from the reachable area
|
//if the goal area isn't reachable from the reachable area
|
||||||
|
@ -874,7 +873,7 @@ int BotMovementViewTarget(int movestate, bot_goal_t *goal, int travelflags, floa
|
||||||
reachnum = BotGetReachabilityToGoal(reach.end, reach.areanum,
|
reachnum = BotGetReachabilityToGoal(reach.end, reach.areanum,
|
||||||
ms->lastgoalareanum, lastareanum,
|
ms->lastgoalareanum, lastareanum,
|
||||||
ms->avoidreach, ms->avoidreachtimes, ms->avoidreachtries,
|
ms->avoidreach, ms->avoidreachtimes, ms->avoidreachtries,
|
||||||
goal, travelflags, travelflags, NULL, 0, NULL);
|
goal, travelflags, NULL, 0, NULL);
|
||||||
VectorCopy(reach.end, end);
|
VectorCopy(reach.end, end);
|
||||||
lastareanum = reach.areanum;
|
lastareanum = reach.areanum;
|
||||||
if (lastareanum == goal->areanum)
|
if (lastareanum == goal->areanum)
|
||||||
|
@ -933,7 +932,7 @@ int BotPredictVisiblePosition(vec3_t origin, int areanum, bot_goal_t *goal, int
|
||||||
reachnum = BotGetReachabilityToGoal(end, areanum,
|
reachnum = BotGetReachabilityToGoal(end, areanum,
|
||||||
lastgoalareanum, lastareanum,
|
lastgoalareanum, lastareanum,
|
||||||
avoidreach, avoidreachtimes, avoidreachtries,
|
avoidreach, avoidreachtimes, avoidreachtries,
|
||||||
goal, travelflags, travelflags, NULL, 0, NULL);
|
goal, travelflags, NULL, 0, NULL);
|
||||||
if (!reachnum) return qfalse;
|
if (!reachnum) return qfalse;
|
||||||
AAS_ReachabilityFromNum(reachnum, &reach);
|
AAS_ReachabilityFromNum(reachnum, &reach);
|
||||||
//
|
//
|
||||||
|
@ -3246,7 +3245,7 @@ void BotMoveToGoal(bot_moveresult_t *result, int movestate, bot_goal_t *goal, in
|
||||||
reachnum = BotGetReachabilityToGoal(ms->origin, ms->areanum,
|
reachnum = BotGetReachabilityToGoal(ms->origin, ms->areanum,
|
||||||
ms->lastgoalareanum, ms->lastareanum,
|
ms->lastgoalareanum, ms->lastareanum,
|
||||||
ms->avoidreach, ms->avoidreachtimes, ms->avoidreachtries,
|
ms->avoidreach, ms->avoidreachtimes, ms->avoidreachtries,
|
||||||
goal, travelflags, travelflags,
|
goal, travelflags,
|
||||||
ms->avoidspots, ms->numavoidspots, &resultflags);
|
ms->avoidspots, ms->numavoidspots, &resultflags);
|
||||||
//the area number the reachability starts in
|
//the area number the reachability starts in
|
||||||
ms->reachareanum = ms->areanum;
|
ms->reachareanum = ms->areanum;
|
||||||
|
@ -3369,7 +3368,7 @@ void BotMoveToGoal(bot_moveresult_t *result, int movestate, bot_goal_t *goal, in
|
||||||
lastreachnum = BotGetReachabilityToGoal(end, areas[i],
|
lastreachnum = BotGetReachabilityToGoal(end, areas[i],
|
||||||
ms->lastgoalareanum, ms->lastareanum,
|
ms->lastgoalareanum, ms->lastareanum,
|
||||||
ms->avoidreach, ms->avoidreachtimes, ms->avoidreachtries,
|
ms->avoidreach, ms->avoidreachtimes, ms->avoidreachtries,
|
||||||
goal, travelflags, TFL_JUMPPAD, ms->avoidspots, ms->numavoidspots, NULL);
|
goal, TFL_JUMPPAD, ms->avoidspots, ms->numavoidspots, NULL);
|
||||||
if (lastreachnum)
|
if (lastreachnum)
|
||||||
{
|
{
|
||||||
ms->lastreachnum = lastreachnum;
|
ms->lastreachnum = lastreachnum;
|
||||||
|
@ -3389,7 +3388,6 @@ void BotMoveToGoal(bot_moveresult_t *result, int movestate, bot_goal_t *goal, in
|
||||||
ms->lastreachnum = lastreachnum;
|
ms->lastreachnum = lastreachnum;
|
||||||
ms->lastareanum = areas[i];
|
ms->lastareanum = areas[i];
|
||||||
//botimport.Print(PRT_MESSAGE, "found jumppad reachability hard!!\n");
|
//botimport.Print(PRT_MESSAGE, "found jumppad reachability hard!!\n");
|
||||||
break;
|
|
||||||
} //end if
|
} //end if
|
||||||
} //end for
|
} //end for
|
||||||
if (lastreachnum) break;
|
if (lastreachnum) break;
|
||||||
|
|
|
@ -323,7 +323,7 @@ void ElevatorBottomCenter(aas_reachability_t *reach, vec3_t bottomcenter);
|
||||||
int BotGetReachabilityToGoal(vec3_t origin, int areanum,
|
int BotGetReachabilityToGoal(vec3_t origin, int areanum,
|
||||||
int lastgoalareanum, int lastareanum,
|
int lastgoalareanum, int lastareanum,
|
||||||
int *avoidreach, float *avoidreachtimes, int *avoidreachtries,
|
int *avoidreach, float *avoidreachtimes, int *avoidreachtries,
|
||||||
bot_goal_t *goal, int travelflags, int movetravelflags,
|
bot_goal_t *goal, int travelflags,
|
||||||
struct bot_avoidspot_s *avoidspots, int numavoidspots, int *flags);
|
struct bot_avoidspot_s *avoidspots, int numavoidspots, int *flags);
|
||||||
|
|
||||||
int AAS_PointLight(vec3_t origin, int *red, int *green, int *blue);
|
int AAS_PointLight(vec3_t origin, int *red, int *green, int *blue);
|
||||||
|
|
|
@ -668,20 +668,21 @@ CG_AdjustPositionForMover
|
||||||
Also called by client movement prediction code
|
Also called by client movement prediction code
|
||||||
=========================
|
=========================
|
||||||
*/
|
*/
|
||||||
void CG_AdjustPositionForMover( const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out ) {
|
void CG_AdjustPositionForMover(const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out, vec3_t angles_in, vec3_t angles_out) {
|
||||||
centity_t *cent;
|
centity_t *cent;
|
||||||
vec3_t oldOrigin, origin, deltaOrigin;
|
vec3_t oldOrigin, origin, deltaOrigin;
|
||||||
vec3_t oldAngles, angles;
|
vec3_t oldAngles, angles, deltaAngles;
|
||||||
//vec3_t deltaAngles;
|
|
||||||
|
|
||||||
if ( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL ) {
|
if ( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL ) {
|
||||||
VectorCopy( in, out );
|
VectorCopy( in, out );
|
||||||
|
VectorCopy(angles_in, angles_out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cent = &cg_entities[ moverNum ];
|
cent = &cg_entities[ moverNum ];
|
||||||
if ( cent->currentState.eType != ET_MOVER ) {
|
if ( cent->currentState.eType != ET_MOVER ) {
|
||||||
VectorCopy( in, out );
|
VectorCopy( in, out );
|
||||||
|
VectorCopy(angles_in, angles_out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,10 +693,10 @@ void CG_AdjustPositionForMover( const vec3_t in, int moverNum, int fromTime, int
|
||||||
BG_EvaluateTrajectory( ¢->currentState.apos, toTime, angles );
|
BG_EvaluateTrajectory( ¢->currentState.apos, toTime, angles );
|
||||||
|
|
||||||
VectorSubtract( origin, oldOrigin, deltaOrigin );
|
VectorSubtract( origin, oldOrigin, deltaOrigin );
|
||||||
//VectorSubtract( angles, oldAngles, deltaAngles );
|
VectorSubtract( angles, oldAngles, deltaAngles );
|
||||||
|
|
||||||
VectorAdd( in, deltaOrigin, out );
|
VectorAdd( in, deltaOrigin, out );
|
||||||
|
VectorAdd( angles_in, deltaAngles, angles_out );
|
||||||
// FIXME: origin change when on a rotating object
|
// FIXME: origin change when on a rotating object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,7 +774,7 @@ static void CG_CalcEntityLerpPositions( centity_t *cent ) {
|
||||||
// player state
|
// player state
|
||||||
if ( cent != &cg.predictedPlayerEntity ) {
|
if ( cent != &cg.predictedPlayerEntity ) {
|
||||||
CG_AdjustPositionForMover( cent->lerpOrigin, cent->currentState.groundEntityNum,
|
CG_AdjustPositionForMover( cent->lerpOrigin, cent->currentState.groundEntityNum,
|
||||||
cg.snap->serverTime, cg.time, cent->lerpOrigin );
|
cg.snap->serverTime, cg.time, cent->lerpOrigin, cent->lerpAngles, cent->lerpAngles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1333,7 +1333,7 @@ void CG_PainEvent( centity_t *cent, int health );
|
||||||
void CG_SetEntitySoundPosition( centity_t *cent );
|
void CG_SetEntitySoundPosition( centity_t *cent );
|
||||||
void CG_AddPacketEntities( void );
|
void CG_AddPacketEntities( void );
|
||||||
void CG_Beam( centity_t *cent );
|
void CG_Beam( centity_t *cent );
|
||||||
void CG_AdjustPositionForMover( const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out );
|
void CG_AdjustPositionForMover(const vec3_t in, int moverNum, int fromTime, int toTime, vec3_t out, vec3_t angles_in, vec3_t angles_out);
|
||||||
|
|
||||||
void CG_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
|
void CG_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
|
||||||
qhandle_t parentModel, char *tagName );
|
qhandle_t parentModel, char *tagName );
|
||||||
|
|
|
@ -2615,7 +2615,7 @@ void CG_ResetPlayerEntity( centity_t *cent ) {
|
||||||
cent->pe.legs.pitchAngle = 0;
|
cent->pe.legs.pitchAngle = 0;
|
||||||
cent->pe.legs.pitching = qfalse;
|
cent->pe.legs.pitching = qfalse;
|
||||||
|
|
||||||
memset( ¢->pe.torso, 0, sizeof( cent->pe.legs ) );
|
memset( ¢->pe.torso, 0, sizeof( cent->pe.torso ) );
|
||||||
cent->pe.torso.yawAngle = cent->rawAngles[YAW];
|
cent->pe.torso.yawAngle = cent->rawAngles[YAW];
|
||||||
cent->pe.torso.yawing = qfalse;
|
cent->pe.torso.yawing = qfalse;
|
||||||
cent->pe.torso.pitchAngle = cent->rawAngles[PITCH];
|
cent->pe.torso.pitchAngle = cent->rawAngles[PITCH];
|
||||||
|
|
|
@ -375,7 +375,7 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
|
||||||
}
|
}
|
||||||
if (ps->persistant[PERS_GAUNTLET_FRAG_COUNT] != ops->persistant[PERS_GAUNTLET_FRAG_COUNT]) {
|
if (ps->persistant[PERS_GAUNTLET_FRAG_COUNT] != ops->persistant[PERS_GAUNTLET_FRAG_COUNT]) {
|
||||||
#ifdef MISSIONPACK
|
#ifdef MISSIONPACK
|
||||||
if (ops->persistant[PERS_GAUNTLET_FRAG_COUNT] == 1) {
|
if (ps->persistant[PERS_GAUNTLET_FRAG_COUNT] == 1) {
|
||||||
sfx = cgs.media.firstHumiliationSound;
|
sfx = cgs.media.firstHumiliationSound;
|
||||||
} else {
|
} else {
|
||||||
sfx = cgs.media.humiliationSound;
|
sfx = cgs.media.humiliationSound;
|
||||||
|
|
|
@ -534,9 +534,9 @@ void CG_PredictPlayerState( void ) {
|
||||||
}
|
}
|
||||||
cg.thisFrameTeleport = qfalse;
|
cg.thisFrameTeleport = qfalse;
|
||||||
} else {
|
} else {
|
||||||
vec3_t adjusted;
|
vec3_t adjusted, new_angles;
|
||||||
CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
|
CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
|
||||||
cg.predictedPlayerState.groundEntityNum, cg.physicsTime, cg.oldTime, adjusted );
|
cg.predictedPlayerState.groundEntityNum, cg.physicsTime, cg.oldTime, adjusted, cg.predictedPlayerState.viewangles, new_angles);
|
||||||
|
|
||||||
if ( cg_showmiss.integer ) {
|
if ( cg_showmiss.integer ) {
|
||||||
if (!VectorCompare( oldPlayerState.origin, adjusted )) {
|
if (!VectorCompare( oldPlayerState.origin, adjusted )) {
|
||||||
|
@ -604,7 +604,7 @@ void CG_PredictPlayerState( void ) {
|
||||||
// adjust for the movement of the groundentity
|
// adjust for the movement of the groundentity
|
||||||
CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
|
CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
|
||||||
cg.predictedPlayerState.groundEntityNum,
|
cg.predictedPlayerState.groundEntityNum,
|
||||||
cg.physicsTime, cg.time, cg.predictedPlayerState.origin );
|
cg.physicsTime, cg.time, cg.predictedPlayerState.origin, cg.predictedPlayerState.viewangles, cg.predictedPlayerState.viewangles);
|
||||||
|
|
||||||
if ( cg_showmiss.integer ) {
|
if ( cg_showmiss.integer ) {
|
||||||
if (cg.predictedPlayerState.eventSequence > oldPlayerState.eventSequence + MAX_PS_EVENTS) {
|
if (cg.predictedPlayerState.eventSequence > oldPlayerState.eventSequence + MAX_PS_EVENTS) {
|
||||||
|
|
|
@ -457,7 +457,8 @@ static void CG_MapRestart( void ) {
|
||||||
cg.fraglimitWarnings = 0;
|
cg.fraglimitWarnings = 0;
|
||||||
|
|
||||||
cg.timelimitWarnings = 0;
|
cg.timelimitWarnings = 0;
|
||||||
|
cg.rewardTime = 0;
|
||||||
|
cg.rewardStack = 0;
|
||||||
cg.intermissionStarted = qfalse;
|
cg.intermissionStarted = qfalse;
|
||||||
cg.levelShot = qfalse;
|
cg.levelShot = qfalse;
|
||||||
|
|
||||||
|
|
|
@ -722,6 +722,8 @@ void ClientUserinfoChanged( int clientNum ) {
|
||||||
// check for malformed or illegal info strings
|
// check for malformed or illegal info strings
|
||||||
if ( !Info_Validate(userinfo) ) {
|
if ( !Info_Validate(userinfo) ) {
|
||||||
strcpy (userinfo, "\\name\\badinfo");
|
strcpy (userinfo, "\\name\\badinfo");
|
||||||
|
// don't keep those clients and userinfo
|
||||||
|
trap_DropClient(clientNum, "Invalid userinfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for local client
|
// check for local client
|
||||||
|
@ -938,7 +940,12 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) {
|
||||||
return "Invalid password";
|
return "Invalid password";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if a player reconnects quickly after a disconnect, the client disconnect may never be called, thus flag can get lost in the ether
|
||||||
|
if (ent->inuse) {
|
||||||
|
G_LogPrintf("Forcing disconnect on active client: %i\n", ent-g_entities);
|
||||||
|
// so lets just fix up anything that should happen on a disconnect
|
||||||
|
ClientDisconnect(ent-g_entities);
|
||||||
|
}
|
||||||
// they can connect
|
// they can connect
|
||||||
ent->client = level.clients + clientNum;
|
ent->client = level.clients + clientNum;
|
||||||
client = ent->client;
|
client = ent->client;
|
||||||
|
@ -1271,7 +1278,7 @@ void ClientDisconnect( int clientNum ) {
|
||||||
G_RemoveQueuedBotBegin( clientNum );
|
G_RemoveQueuedBotBegin( clientNum );
|
||||||
|
|
||||||
ent = g_entities + clientNum;
|
ent = g_entities + clientNum;
|
||||||
if ( !ent->client ) {
|
if (!ent->client || ent->client->pers.connected == CON_DISCONNECTED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1590,7 +1590,7 @@ void ClientCommand( int clientNum ) {
|
||||||
char cmd[MAX_TOKEN_CHARS];
|
char cmd[MAX_TOKEN_CHARS];
|
||||||
|
|
||||||
ent = g_entities + clientNum;
|
ent = g_entities + clientNum;
|
||||||
if ( !ent->client ) {
|
if (!ent->client || ent->client->pers.connected != CON_CONNECTED) {
|
||||||
return; // not fully in game yet
|
return; // not fully in game yet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1363,10 +1363,6 @@ void CheckExitRules( void ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( level.numPlayingClients < 2 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( g_gametype.integer < GT_CTF && g_fraglimit.integer ) {
|
if ( g_gametype.integer < GT_CTF && g_fraglimit.integer ) {
|
||||||
if ( level.teamScores[TEAM_RED] >= g_fraglimit.integer ) {
|
if ( level.teamScores[TEAM_RED] >= g_fraglimit.integer ) {
|
||||||
trap_SendServerCommand( -1, "print \"Red hit the fraglimit.\n\"" );
|
trap_SendServerCommand( -1, "print \"Red hit the fraglimit.\n\"" );
|
||||||
|
|
Loading…
Reference in a new issue