commit e860f52466dc29078526925e91c624df28fc0c28 Author: /dev/humancontroller Date: Mon Jun 13 03:10:04 2011 +0200 mover team code defucktardization diff --git a/src/game/g_mover.c b/src/game/g_mover.c index 6dc5bb4..fa7e962 100644 --- a/src/game/g_mover.c +++ b/src/game/g_mover.c @@ -377,6 +377,12 @@ void G_MoverTeam( gentity_t *ent ) pushed_p = pushed; for( part = ent; part; part = part->teamchain ) { + if( part->s.pos.trType == TR_STATIONARY && + part->s.apos.trType == TR_STATIONARY ) + { + continue; + } + // get current position BG_EvaluateTrajectory( &part->s.pos, level.time, origin ); BG_EvaluateTrajectory( &part->s.apos, level.time, angles ); @@ -391,6 +397,12 @@ void G_MoverTeam( gentity_t *ent ) // go back to the previous position for( part = ent; part; part = part->teamchain ) { + if( part->s.pos.trType == TR_STATIONARY && + part->s.apos.trType == TR_STATIONARY ) + { + continue; + } + part->s.pos.trTime += level.time - level.previousTime; part->s.apos.trTime += level.time - level.previousTime; BG_EvaluateTrajectory( &part->s.pos, level.time, part->r.currentOrigin ); @@ -440,10 +452,7 @@ void G_RunMover( gentity_t *ent ) if( ent->flags & FL_TEAMSLAVE ) return; - // if stationary at one of the positions, don't move anything - if( ( ent->s.pos.trType != TR_STATIONARY || ent->s.apos.trType != TR_STATIONARY ) && - ent->moverState < MODEL_POS1 ) //yuck yuck hack - G_MoverTeam( ent ); + G_MoverTeam( ent ); // check think function G_RunThink( ent ); @@ -552,7 +561,6 @@ void SetMoverState( gentity_t *ent, moverState_t moverState, int time ) MatchTeam All entities in a mover team will move from pos1 to pos2 -in the same amount of time ================ */ void MatchTeam( gentity_t *teamLeader, int moverState, int time ) @@ -564,40 +572,65 @@ void MatchTeam( gentity_t *teamLeader, int moverState, int time ) } +/* +================ +MasterOf +================ +*/ +gentity_t *MasterOf( gentity_t *ent ) +{ + if( ent->teammaster ) + return ent->teammaster; + else + return ent; +} + /* ================ -ReturnToPos1 +GetMoverTeamState + +Returns a MOVER_* value representing the phase (either one + of pos1, 1to2, pos2, or 2to1) of a mover team as a whole. ================ */ -void ReturnToPos1( gentity_t *ent ) +moverState_t GetMoverTeamState( gentity_t *ent ) { - MatchTeam( ent, MOVER_2TO1, level.time ); + qboolean pos1 = qfalse; - // looping sound - ent->s.loopSound = ent->soundLoop; + for( ent = MasterOf( ent ); ent; ent = ent->teamchain ) + { + if( ent->moverState == MOVER_POS1 || ent->moverState == ROTATOR_POS1 ) + pos1 = qtrue; + else if( ent->moverState == MOVER_1TO2 || ent->moverState == ROTATOR_1TO2 ) + return MOVER_1TO2; + else if( ent->moverState == MOVER_2TO1 || ent->moverState == ROTATOR_2TO1 ) + return MOVER_2TO1; + } - // starting sound - if( ent->sound2to1 ) - G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); + if( pos1 ) + return MOVER_POS1; + else + return MOVER_POS2; } /* ================ -ReturnToApos1 +ReturnToPos1orApos1 + +Used only by a master movers. ================ */ -void ReturnToApos1( gentity_t *ent ) -{ - MatchTeam( ent, ROTATOR_2TO1, level.time ); - // looping sound - ent->s.loopSound = ent->soundLoop; +void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ); - // starting sound - if( ent->sound2to1 ) - G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); +void ReturnToPos1orApos1( gentity_t *ent ) +{ + if( GetMoverTeamState( ent ) != MOVER_POS2 ) + return; // not every mover in the team has reached its endpoint yet + + Use_BinaryMover( ent, ent, ent->activator ); } @@ -688,10 +721,10 @@ void Think_OpenModelDoor( gentity_t *ent ) //set brush non-solid trap_UnlinkEntity( ent->clipBrush ); - // looping sound - ent->s.loopSound = ent->soundLoop; + // stop the looping sound + ent->s.loopSound = 0; - // starting sound + // play sound if( ent->soundPos2 ) G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos2 ); @@ -716,8 +749,10 @@ Reached_BinaryMover */ void Reached_BinaryMover( gentity_t *ent ) { + gentity_t *master = MasterOf( ent ); + // stop the looping sound - ent->s.loopSound = ent->soundLoop; + ent->s.loopSound = 0; if( ent->moverState == MOVER_1TO2 ) { @@ -729,8 +764,8 @@ void Reached_BinaryMover( gentity_t *ent ) G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos2 ); // return to pos1 after a delay - ent->think = ReturnToPos1; - ent->nextthink = level.time + ent->wait; + master->think = ReturnToPos1orApos1; + master->nextthink = MAX( master->nextthink, level.time + ent->wait ); // fire targets if( !ent->activator ) @@ -761,8 +796,8 @@ void Reached_BinaryMover( gentity_t *ent ) G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos2 ); // return to apos1 after a delay - ent->think = ReturnToApos1; - ent->nextthink = level.time + ent->wait; + master->think = ReturnToPos1orApos1; + master->nextthink = MAX( master->nextthink, level.time + ent->wait ); // fire targets if( !ent->activator ) @@ -797,6 +832,8 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) { int total; int partial; + gentity_t *master; + moverState_t teamState; // if this is a non-client-usable door return if( ent->targetname && other && other->client ) @@ -811,11 +848,17 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) ent->activator = activator; + master = MasterOf( ent ); + teamState = GetMoverTeamState( ent ); + + for( ent = master; ent; ent = ent->teamchain ) + { + //ind if( ent->moverState == MOVER_POS1 ) { // start moving 50 msec later, becase if this was player // triggered, level.time hasn't been advanced yet - MatchTeam( ent, MOVER_1TO2, level.time + 50 ); + SetMoverState( ent, MOVER_1TO2, level.time + 50 ); // starting sound if( ent->sound1to2 ) @@ -828,10 +871,30 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) if( ent->teammaster == ent || !ent->teammaster ) trap_AdjustAreaPortalState( ent, qtrue ); } - else if( ent->moverState == MOVER_POS2 ) + else if( ent->moverState == MOVER_POS2 && + !( teamState == MOVER_1TO2 || other == master ) ) { // if all the way up, just delay before coming down - ent->nextthink = level.time + ent->wait; + master->think = ReturnToPos1orApos1; + master->nextthink = MAX( master->nextthink, level.time + ent->wait ); + } + else if( ent->moverState == MOVER_POS2 && + ( teamState == MOVER_1TO2 || other == master ) ) + { + // start moving 50 msec later, becase if this was player + // triggered, level.time hasn't been advanced yet + SetMoverState( ent, MOVER_2TO1, level.time + 50 ); + + // starting sound + if( ent->sound2to1 ) + G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); + + // looping sound + ent->s.loopSound = ent->soundLoop; + + // open areaportal + if( ent->teammaster == ent || !ent->teammaster ) + trap_AdjustAreaPortalState( ent, qtrue ); } else if( ent->moverState == MOVER_2TO1 ) { @@ -842,7 +905,7 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) if( partial > total ) partial = total; - MatchTeam( ent, MOVER_1TO2, level.time - ( total - partial ) ); + SetMoverState( ent, MOVER_1TO2, level.time - ( total - partial ) ); if( ent->sound1to2 ) G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); @@ -856,7 +919,7 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) if( partial > total ) partial = total; - MatchTeam( ent, MOVER_2TO1, level.time - ( total - partial ) ); + SetMoverState( ent, MOVER_2TO1, level.time - ( total - partial ) ); if( ent->sound2to1 ) G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); @@ -865,7 +928,7 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) { // start moving 50 msec later, becase if this was player // triggered, level.time hasn't been advanced yet - MatchTeam( ent, ROTATOR_1TO2, level.time + 50 ); + SetMoverState( ent, ROTATOR_1TO2, level.time + 50 ); // starting sound if( ent->sound1to2 ) @@ -878,10 +941,30 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) if( ent->teammaster == ent || !ent->teammaster ) trap_AdjustAreaPortalState( ent, qtrue ); } - else if( ent->moverState == ROTATOR_POS2 ) + else if( ent->moverState == ROTATOR_POS2 && + !( teamState == MOVER_1TO2 || other == master ) ) { // if all the way up, just delay before coming down - ent->nextthink = level.time + ent->wait; + master->think = ReturnToPos1orApos1; + master->nextthink = MAX( master->nextthink, level.time + ent->wait ); + } + else if( ent->moverState == ROTATOR_POS2 && + ( teamState == MOVER_1TO2 || other == master ) ) + { + // start moving 50 msec later, becase if this was player + // triggered, level.time hasn't been advanced yet + SetMoverState( ent, ROTATOR_2TO1, level.time + 50 ); + + // starting sound + if( ent->sound2to1 ) + G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); + + // looping sound + ent->s.loopSound = ent->soundLoop; + + // open areaportal + if( ent->teammaster == ent || !ent->teammaster ) + trap_AdjustAreaPortalState( ent, qtrue ); } else if( ent->moverState == ROTATOR_2TO1 ) { @@ -892,7 +975,7 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) if( partial > total ) partial = total; - MatchTeam( ent, ROTATOR_1TO2, level.time - ( total - partial ) ); + SetMoverState( ent, ROTATOR_1TO2, level.time - ( total - partial ) ); if( ent->sound1to2 ) G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound1to2 ); @@ -906,7 +989,7 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) if( partial > total ) partial = total; - MatchTeam( ent, ROTATOR_2TO1, level.time - ( total - partial ) ); + SetMoverState( ent, ROTATOR_2TO1, level.time - ( total - partial ) ); if( ent->sound2to1 ) G_AddEvent( ent, EV_GENERAL_SOUND, ent->sound2to1 ); @@ -937,6 +1020,8 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) // if all the way up, just delay before coming down ent->nextthink = level.time + ent->wait; } + //outd + } } @@ -957,15 +1042,16 @@ void InitMover( gentity_t *ent ) vec3_t color; qboolean lightSet, colorSet; char *sound; + char *team; // if the "model2" key is set, use a seperate model // for drawing, but clip against the brushes if( ent->model2 ) ent->s.modelindex2 = G_ModelIndex( ent->model2 ); - // if the "loopsound" key is set, use a constant looping sound when moving - if( G_SpawnString( "noise", "100", &sound ) ) - ent->s.loopSound = G_SoundIndex( sound ); + // if the "noise" key is set, use a constant looping sound when moving + if( G_SpawnString( "noise", "", &sound ) ) + ent->soundLoop = G_SoundIndex( sound ); // if the "color" or "light" keys are set, setup constantLight lightSet = G_SpawnFloat( "light", "100", &light ); @@ -998,6 +1084,9 @@ void InitMover( gentity_t *ent ) ent->use = Use_BinaryMover; ent->reached = Reached_BinaryMover; + if( G_SpawnString( "team", "", &team ) ) + ent->team = team; + ent->moverState = MOVER_POS1; ent->r.svFlags = SVF_USE_CURRENT_ORIGIN; ent->s.eType = ET_MOVER; @@ -1037,15 +1126,16 @@ void InitRotator( gentity_t *ent ) vec3_t color; qboolean lightSet, colorSet; char *sound; + char *team; // if the "model2" key is set, use a seperate model // for drawing, but clip against the brushes if( ent->model2 ) ent->s.modelindex2 = G_ModelIndex( ent->model2 ); - // if the "loopsound" key is set, use a constant looping sound when moving - if( G_SpawnString( "noise", "100", &sound ) ) - ent->s.loopSound = G_SoundIndex( sound ); + // if the "noise" key is set, use a constant looping sound when moving + if( G_SpawnString( "noise", "", &sound ) ) + ent->soundLoop = G_SoundIndex( sound ); // if the "color" or "light" keys are set, setup constantLight lightSet = G_SpawnFloat( "light", "100", &light ); @@ -1082,6 +1172,9 @@ void InitRotator( gentity_t *ent ) ent->use = Use_BinaryMover; ent->reached = Reached_BinaryMover; + if( G_SpawnString( "team", "", &team ) ) + ent->team = team; + ent->moverState = ROTATOR_POS1; ent->r.svFlags = SVF_USE_CURRENT_ORIGIN; ent->s.eType = ET_MOVER; @@ -1297,25 +1390,30 @@ Touch_DoorTrigger */ void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace ) { + moverState_t teamState; + //buildables don't trigger movers if( other->s.eType == ET_BUILDABLE ) return; + teamState = GetMoverTeamState( ent->parent ); + if( other->client && other->client->sess.spectatorState != SPECTATOR_NOT ) { // if the door is not open and not opening - if( ent->parent->moverState != MOVER_1TO2 && - ent->parent->moverState != MOVER_POS2 && - ent->parent->moverState != ROTATOR_1TO2 && - ent->parent->moverState != ROTATOR_POS2 ) + if( teamState != MOVER_POS2 && teamState != MOVER_1TO2 ) Touch_DoorTriggerSpectator( ent, other, trace ); } - else if( ent->parent->moverState != MOVER_1TO2 && - ent->parent->moverState != ROTATOR_1TO2 && - ent->parent->moverState != ROTATOR_2TO1 ) - { + else if( teamState != MOVER_1TO2 ) Use_BinaryMover( ent->parent, ent, other ); - } +} + + +void Think_MatchTeam( gentity_t *ent ) +{ + if( ent->flags & FL_TEAMSLAVE ) + return; + MatchTeam( ent, ent->moverState, level.time ); } @@ -1367,12 +1465,7 @@ void Think_SpawnNewDoorTrigger( gentity_t *ent ) trap_LinkEntity( other ); if( ent->moverState < MODEL_POS1 ) - MatchTeam( ent, ent->moverState, level.time ); -} - -void Think_MatchTeam( gentity_t *ent ) -{ - MatchTeam( ent, ent->moverState, level.time ); + Think_MatchTeam( ent ); } @@ -1399,6 +1492,7 @@ void SP_func_door( gentity_t *ent ) vec3_t size; float lip; char *s; + int health; G_SpawnString( "sound2to1", "sound/movers/doors/dr1_strt.wav", &s ); ent->sound2to1 = G_SoundIndex( s ); @@ -1455,22 +1549,17 @@ void SP_func_door( gentity_t *ent ) ent->nextthink = level.time + FRAMETIME; - if( !( ent->flags & FL_TEAMSLAVE ) ) - { - int health; - - G_SpawnInt( "health", "0", &health ); - if( health ) - ent->takedamage = qtrue; + G_SpawnInt( "health", "0", &health ); + if( health ) + ent->takedamage = qtrue; - if( ent->targetname || health ) - { - // non touch/shoot doors - ent->think = Think_MatchTeam; - } - else - ent->think = Think_SpawnNewDoorTrigger; + if( ent->targetname || health ) + { + // non touch/shoot doors + ent->think = Think_MatchTeam; } + else + ent->think = Think_SpawnNewDoorTrigger; } /*QUAKED func_door_rotating (0 .5 .8) START_OPEN CRUSHER REVERSE TOGGLE X_AXIS Y_AXIS @@ -1495,6 +1584,7 @@ void SP_func_door( gentity_t *ent ) void SP_func_door_rotating( gentity_t *ent ) { char *s; + int health; G_SpawnString( "sound2to1", "sound/movers/doors/dr1_strt.wav", &s ); ent->sound2to1 = G_SoundIndex( s ); @@ -1573,23 +1663,17 @@ void SP_func_door_rotating( gentity_t *ent ) ent->nextthink = level.time + FRAMETIME; - if( !( ent->flags & FL_TEAMSLAVE ) ) - { - int health; - - G_SpawnInt( "health", "0", &health ); - - if( health ) - ent->takedamage = qtrue; + G_SpawnInt( "health", "0", &health ); + if( health ) + ent->takedamage = qtrue; - if( ent->targetname || health ) - { - // non touch/shoot doors - ent->think = Think_MatchTeam; - } - else - ent->think = Think_SpawnNewDoorTrigger; + if( ent->targetname || health ) + { + // non touch/shoot doors + ent->think = Think_MatchTeam; } + else + ent->think = Think_SpawnNewDoorTrigger; } /*QUAKED func_door_model (0 .5 .8) ? START_OPEN @@ -1613,6 +1697,7 @@ void SP_func_door_model( gentity_t *ent ) qboolean lightSet, colorSet; char *sound; gentity_t *clipBrush; + int health; G_SpawnString( "sound2to1", "sound/movers/doors/dr1_strt.wav", &s ); ent->sound2to1 = G_SoundIndex( s ); @@ -1659,9 +1744,9 @@ void SP_func_door_model( gentity_t *ent ) else ent->s.modelindex = G_ModelIndex( ent->model2 ); - // if the "loopsound" key is set, use a constant looping sound when moving - if( G_SpawnString( "noise", "100", &sound ) ) - ent->s.loopSound = G_SoundIndex( sound ); + // if the "noise" key is set, use a constant looping sound when moving + if( G_SpawnString( "noise", "", &sound ) ) + ent->soundLoop = G_SoundIndex( sound ); // if the "color" or "light" keys are set, setup constantLight lightSet = G_SpawnFloat( "light", "100", &light ); @@ -1716,19 +1801,14 @@ void SP_func_door_model( gentity_t *ent ) trap_LinkEntity( ent ); - if( !( ent->flags & FL_TEAMSLAVE ) ) - { - int health; - - G_SpawnInt( "health", "0", &health ); - if( health ) - ent->takedamage = qtrue; + G_SpawnInt( "health", "0", &health ); + if( health ) + ent->takedamage = qtrue; - if( !( ent->targetname || health ) ) - { - ent->nextthink = level.time + FRAMETIME; - ent->think = Think_SpawnNewDoorTrigger; - } + if( !( ent->targetname || health ) ) + { + ent->nextthink = level.time + FRAMETIME; + ent->think = Think_SpawnNewDoorTrigger; } } diff --git a/src/game/g_spawn.c b/src/game/g_spawn.c index 2a83d40..5a9cac2 100644 --- a/src/game/g_spawn.c +++ b/src/game/g_spawn.c @@ -134,7 +134,6 @@ field_t fields[ ] = {"targetname", FOFS(targetname), F_STRING}, {"targetShaderName", FOFS(targetShaderName), F_STRING}, {"targetShaderNewName", FOFS(targetShaderNewName), F_STRING}, - {"team", FOFS(team), F_STRING}, {"wait", FOFS(wait), F_FLOAT} };