//TODO: When transition to 0 grav, push away from surface you were resting on //TODO: When free-floating in air, apply some friction to your trDelta (based on mass?) void G_RunObject( gentity_t *ent ) { vector3 origin, oldOrg; trace_t tr; gentity_t *traceEnt = NULL; //FIXME: floaters need to stop floating up after a while, even if gravity stays negative? if ( ent->s.pos.trType == TR_STATIONARY )//g_gravity.value <= 0 && { ent->s.pos.trType = TR_GRAVITY; VectorCopy( &ent->r.currentOrigin, &ent->s.pos.trBase ); ent->s.pos.trTime = level.previousTime;//?necc? if ( !g_gravity.value ) { ent->s.pos.trDelta.z += 100; } } ent->nextthink = level.time + FRAMETIME; VectorCopy( &ent->r.currentOrigin, &oldOrg ); // get current position BG_EvaluateTrajectory( &ent->s.pos, level.time, &origin ); //Get current angles? BG_EvaluateTrajectory( &ent->s.apos, level.time, &ent->r.currentAngles ); if ( VectorCompare( &ent->r.currentOrigin, &origin ) ) {//error - didn't move at all! return; } // trace a line from the previous position to the current position, // ignoring interactions with the missile owner trap->Trace( &tr, &ent->r.currentOrigin, &ent->r.mins, &ent->r.maxs, &origin, ent->parent ? ent->parent->s.number : ent->s.number, ent->clipmask, qfalse, 0, 0 ); if ( !tr.startsolid && !tr.allsolid && tr.fraction ) { VectorCopy( &tr.endpos, &ent->r.currentOrigin ); trap->LinkEntity( (sharedEntity_t *)ent ); } else //if ( tr.startsolid ) { tr.fraction = 0; } G_MoverTouchPushTriggers( ent, &oldOrg ); /* if ( !(ent->s.eFlags & EF_TELEPORT_BIT) && !(ent->svFlags & SVF_NO_TELEPORT) ) { G_MoverTouchTeleportTriggers( ent, oldOrg ); if ( ent->s.eFlags & EF_TELEPORT_BIT ) {//was teleported return; } } else { ent->s.eFlags &= ~EF_TELEPORT_BIT; } */ if ( tr.fraction == 1 ) { if ( g_gravity.value <= 0 ) { if ( ent->s.apos.trType == TR_STATIONARY ) { VectorCopy( &ent->r.currentAngles, &ent->s.apos.trBase ); ent->s.apos.trType = TR_LINEAR; ent->s.apos.trDelta.y = flrand( -300, 300 ); ent->s.apos.trDelta.x = flrand( -10, 10 ); ent->s.apos.trDelta.z = flrand( -10, 10 ); ent->s.apos.trTime = level.time; } } //friction in zero-G if ( !g_gravity.value ) { float friction = 0.975f; //friction -= ent->mass/1000.0f; if ( friction < 0.1f ) { friction = 0.1f; } VectorScale( &ent->s.pos.trDelta, friction, &ent->s.pos.trDelta ); VectorCopy( &ent->r.currentOrigin, &ent->s.pos.trBase ); ent->s.pos.trTime = level.time; } return; } //hit something //Do impact damage traceEnt = &g_entities[tr.entityNum]; if ( tr.fraction || (traceEnt && traceEnt->takedamage) ) { if ( !VectorCompare( &ent->r.currentOrigin, &oldOrg ) ) {//moved and impacted if ( (traceEnt && traceEnt->takedamage) ) {//hurt someone // G_Sound( ent, G_SoundIndex( "sound/movers/objects/objectHurt.wav" ) ); } // G_Sound( ent, G_SoundIndex( "sound/movers/objects/objectHit.wav" ) ); } if ( ent->s.weapon != WP_SABER ) { DoImpact( ent, traceEnt, qtrue ); } } if ( !ent || (ent->takedamage&&ent->health <= 0) ) {//been destroyed by impact //chunks? // G_Sound( ent, G_SoundIndex( "sound/movers/objects/objectBreak.wav" ) ); return; } //do impact physics if ( ent->s.pos.trType == TR_GRAVITY )//tr.fraction < 1.0f && {//FIXME: only do this if no trDelta if ( g_gravity.value <= 0 || tr.plane.normal.z < 0.7f ) { if ( ent->flags&(FL_BOUNCE | FL_BOUNCE_HALF) ) { if ( tr.fraction <= 0.0f ) { VectorCopy( &tr.endpos, &ent->r.currentOrigin ); VectorCopy( &tr.endpos, &ent->s.pos.trBase ); VectorClear( &ent->s.pos.trDelta ); ent->s.pos.trTime = level.time; } else { G_BounceObject( ent, &tr ); } } else {//slide down? //FIXME: slide off the slope } } else { ent->s.apos.trType = TR_STATIONARY; pitch_roll_for_slope( ent, &tr.plane.normal ); //ent->r.currentAngles[0] = 0;//FIXME: match to slope //ent->r.currentAngles[2] = 0;//FIXME: match to slope VectorCopy( &ent->r.currentAngles, &ent->s.apos.trBase ); //okay, we hit the floor, might as well stop or prediction will //make us go through the floor! //FIXME: this means we can't fall if something is pulled out from under us... G_StopObjectMoving( ent ); } } else if ( ent->s.weapon != WP_SABER ) { ent->s.apos.trType = TR_STATIONARY; pitch_roll_for_slope( ent, &tr.plane.normal ); //ent->r.currentAngles[0] = 0;//FIXME: match to slope //ent->r.currentAngles[2] = 0;//FIXME: match to slope VectorCopy( &ent->r.currentAngles, &ent->s.apos.trBase ); } //call touch func ent->touch( ent, &g_entities[tr.entityNum], &tr ); }
void G_RunMissile( gentity_t *ent ) { vec3_t oldOrg; trace_t tr; int trHitLoc=HL_NONE; if ( (ent->s.eFlags&EF_HELD_BY_SAND_CREATURE) ) {//in a sand creature's mouth if ( ent->activator ) { mdxaBone_t boltMatrix; // Getting the bolt here //in hand vec3_t scAngles = {0}; scAngles[YAW] = ent->activator->currentAngles[YAW]; gi.G2API_GetBoltMatrix( ent->activator->ghoul2, ent->activator->playerModel, ent->activator->gutBolt, &boltMatrix, scAngles, ent->activator->currentOrigin, (cg.time?cg.time:level.time), NULL, ent->activator->s.modelScale ); // Storing ent position, bolt position, and bolt axis gi.G2API_GiveMeVectorFromMatrix( boltMatrix, ORIGIN, ent->currentOrigin ); G_SetOrigin( ent, ent->currentOrigin ); } // check think function G_RunThink( ent ); return; } VectorCopy( ent->currentOrigin, oldOrg ); // get current position if ( ent->s.pos.trType == TR_INTERPOLATE ) {//rolling missile? //FIXME: WTF?!! Sticks to stick missiles? //FIXME: they stick inside the player G_RollMissile( ent ); if ( ent->s.eType != ET_GENERAL ) {//didn't explode VectorCopy( ent->currentOrigin, ent->s.pos.trBase ); gi.trace( &tr, oldOrg, ent->mins, ent->maxs, ent->currentOrigin, ent->s.number, ent->clipmask, G2_RETURNONHIT, 10 ); if ( VectorCompare( ent->s.pos.trDelta, vec3_origin ) ) { //VectorCopy( ent->currentAngles, ent->s.apos.trBase ); VectorClear( ent->s.apos.trDelta ); } else { vec3_t ang, fwdDir, rtDir; float speed; ent->s.apos.trType = TR_INTERPOLATE; VectorSet( ang, 0, ent->s.apos.trBase[1], 0 ); AngleVectors( ang, fwdDir, rtDir, NULL ); speed = VectorLength( ent->s.pos.trDelta )*4; //HMM, this works along an axis-aligned dir, but not along diagonals //This is because when roll gets to 90, pitch becomes yaw, and vice-versa //Maybe need to just set the angles directly? ent->s.apos.trDelta[0] = DotProduct( fwdDir, ent->s.pos.trDelta ); ent->s.apos.trDelta[1] = 0;//never spin! ent->s.apos.trDelta[2] = DotProduct( rtDir, ent->s.pos.trDelta ); VectorNormalize( ent->s.apos.trDelta ); VectorScale( ent->s.apos.trDelta, speed, ent->s.apos.trDelta ); ent->s.apos.trTime = level.previousTime; } } } else { vec3_t origin; EvaluateTrajectory( &ent->s.pos, level.time, origin ); // trace a line from the previous position to the current position, // ignoring interactions with the missile owner gi.trace( &tr, ent->currentOrigin, ent->mins, ent->maxs, origin, ent->owner ? ent->owner->s.number : ent->s.number, ent->clipmask, G2_COLLIDE, 10 ); if ( tr.entityNum != ENTITYNUM_NONE ) { gentity_t *other = &g_entities[tr.entityNum]; // check for hitting a lightsaber if ( other->contents & CONTENTS_LIGHTSABER ) {//hit a lightsaber bbox if ( other->owner && other->owner->client && !other->owner->client->ps.saberInFlight && ( Q_irand( 0, (other->owner->client->ps.forcePowerLevel[FP_SABER_DEFENSE]*other->owner->client->ps.forcePowerLevel[FP_SABER_DEFENSE]) ) == 0 || !InFront( ent->currentOrigin, other->owner->currentOrigin, other->owner->client->ps.viewangles, SABER_REFLECT_MISSILE_CONE ) ) )//other->owner->s.number == 0 && {//Jedi cannot block shots from behind! //re-trace from here, ignoring the lightsaber gi.trace( &tr, tr.endpos, ent->mins, ent->maxs, origin, tr.entityNum, ent->clipmask, G2_RETURNONHIT, 10 ); } } } VectorCopy( tr.endpos, ent->currentOrigin ); } // get current angles VectorMA( ent->s.apos.trBase, (level.time - ent->s.apos.trTime) * 0.001, ent->s.apos.trDelta, ent->s.apos.trBase ); //FIXME: Rolling things hitting G2 polys is weird /////////////////////////////////////////////////////// //? if ( tr.fraction != 1 ) { // did we hit or go near a Ghoul2 model? // qboolean hitModel = qfalse; for (int i=0; i < MAX_G2_COLLISIONS; i++) { if (tr.G2CollisionMap[i].mEntityNum == -1) { break; } CCollisionRecord &coll = tr.G2CollisionMap[i]; gentity_t *hitEnt = &g_entities[coll.mEntityNum]; // process collision records here... // make sure we only do this once, not for all the entrance wounds we might generate if ((coll.mFlags & G2_FRONTFACE)/* && !(hitModel)*/ && hitEnt->health) { if (trHitLoc==HL_NONE) { G_GetHitLocFromSurfName( &g_entities[coll.mEntityNum], gi.G2API_GetSurfaceName( &g_entities[coll.mEntityNum].ghoul2[coll.mModelIndex], coll.mSurfaceIndex ), &trHitLoc, coll.mCollisionPosition, NULL, NULL, ent->methodOfDeath ); } break; // NOTE: the way this whole section was working, it would only get inside of this IF once anyway, might as well break out now } } } ///////////////////////////////////////////////////////// if ( tr.startsolid ) { tr.fraction = 0; } gi.linkentity( ent ); if ( ent->s.pos.trType == TR_STATIONARY && (ent->s.eFlags&EF_MISSILE_STICK) ) {//stuck missiles should check some special stuff G_RunStuckMissile( ent ); return; } // check think function G_RunThink( ent ); if ( ent->s.eType != ET_MISSILE ) { return; // exploded } if ( ent->mass ) { G_MoverTouchPushTriggers( ent, oldOrg ); } /* if ( !(ent->s.eFlags & EF_TELEPORT_BIT) ) { G_MoverTouchTeleportTriggers( ent, oldOrg ); if ( ent->s.eFlags & EF_TELEPORT_BIT ) {//was teleported return; } } else { ent->s.eFlags &= ~EF_TELEPORT_BIT; } */ AddSightEvent( ent->owner, ent->currentOrigin, 512, AEL_DISCOVERED, 75 );//wakes them up when see a shot passes in front of them if ( !Q_irand( 0, 10 ) ) {//not so often... if ( ent->splashDamage && ent->splashRadius ) {//I'm an exploder, let people around me know danger is coming if ( ent->s.weapon == WP_TRIP_MINE ) {//??? } else { if ( ent->s.weapon == WP_ROCKET_LAUNCHER && ent->e_ThinkFunc == thinkF_rocketThink ) {//homing rocket- run like hell! AddSightEvent( ent->owner, ent->currentOrigin, ent->splashRadius, AEL_DANGER_GREAT, 50 ); } else { AddSightEvent( ent->owner, ent->currentOrigin, ent->splashRadius, AEL_DANGER, 50 ); } AddSoundEvent( ent->owner, ent->currentOrigin, ent->splashRadius, AEL_DANGER ); } } else {//makes them run from near misses AddSightEvent( ent->owner, ent->currentOrigin, 48, AEL_DANGER, 50 ); } } if ( tr.fraction == 1 ) { if ( ent->s.weapon == WP_THERMAL && ent->s.pos.trType == TR_INTERPOLATE ) {//a rolling thermal that didn't hit anything G_MissileAddAlerts( ent ); } return; } // never explode or bounce on sky if ( tr.surfaceFlags & SURF_NOIMPACT ) { G_FreeEntity( ent ); return; } G_MissileImpact( ent, &tr, trHitLoc ); }
void G_RunObject( gentity_t *ent ) { vec3_t origin, oldOrg; trace_t tr; gentity_t *traceEnt = NULL; //FIXME: floaters need to stop floating up after a while, even if gravity stays negative? if ( ent->s.pos.trType == TR_STATIONARY )//g_gravity->value <= 0 && { ent->s.pos.trType = TR_GRAVITY; VectorCopy( ent->currentOrigin, ent->s.pos.trBase ); ent->s.pos.trTime = level.previousTime;//?necc? if ( !g_gravity->value ) { ent->s.pos.trDelta[2] += 100; } } ent->nextthink = level.time + FRAMETIME; VectorCopy( ent->currentOrigin, oldOrg ); // get current position EvaluateTrajectory( &ent->s.pos, level.time, origin ); //Get current angles? EvaluateTrajectory( &ent->s.apos, level.time, ent->currentAngles ); if ( VectorCompare( ent->currentOrigin, origin ) ) {//error - didn't move at all! return; } // trace a line from the previous position to the current position, // ignoring interactions with the missile owner gi.trace( &tr, ent->currentOrigin, ent->mins, ent->maxs, origin, ent->owner ? ent->owner->s.number : ent->s.number, ent->clipmask, (EG2_Collision)0, 0 ); if ( !tr.startsolid && !tr.allsolid && tr.fraction ) { VectorCopy( tr.endpos, ent->currentOrigin ); gi.linkentity( ent ); } else //if ( tr.startsolid ) { tr.fraction = 0; } G_MoverTouchPushTriggers( ent, oldOrg ); /* if ( !(ent->s.eFlags & EF_TELEPORT_BIT) && !(ent->svFlags & SVF_NO_TELEPORT) ) { G_MoverTouchTeleportTriggers( ent, oldOrg ); if ( ent->s.eFlags & EF_TELEPORT_BIT ) {//was teleported return; } } else { ent->s.eFlags &= ~EF_TELEPORT_BIT; } */ if ( tr.fraction == 1 ) { if ( g_gravity->value <= 0 ) { if ( ent->s.apos.trType == TR_STATIONARY ) { VectorCopy( ent->currentAngles, ent->s.apos.trBase ); ent->s.apos.trType = TR_LINEAR; ent->s.apos.trDelta[1] = Q_flrand( -300, 300 ); ent->s.apos.trDelta[0] = Q_flrand( -10, 10 ); ent->s.apos.trDelta[2] = Q_flrand( -10, 10 ); ent->s.apos.trTime = level.time; } } //friction in zero-G if ( !g_gravity->value ) { float friction = 0.975f; /*friction -= ent->mass/1000.0f; if ( friction < 0.1 ) { friction = 0.1f; } */ VectorScale( ent->s.pos.trDelta, friction, ent->s.pos.trDelta ); VectorCopy( ent->currentOrigin, ent->s.pos.trBase ); ent->s.pos.trTime = level.time; } return; } //hit something //Do impact damage traceEnt = &g_entities[tr.entityNum]; if ( tr.fraction || (traceEnt && traceEnt->takedamage) ) { if ( !VectorCompare( ent->currentOrigin, oldOrg ) ) {//moved and impacted if ( (traceEnt && traceEnt->takedamage) ) {//hurt someone vec3_t fxDir; VectorNormalize2( ent->s.pos.trDelta, fxDir ); VectorScale( fxDir, -1, fxDir ); G_PlayEffect( G_EffectIndex( "melee/kick_impact" ), tr.endpos, fxDir ); //G_Sound( ent, G_SoundIndex( va( "sound/weapons/melee/punch%d", Q_irand( 1, 4 ) ) ) ); } else { G_PlayEffect( G_EffectIndex( "melee/kick_impact_silent" ), tr.endpos, tr.plane.normal ); } if ( ent->mass > 100 ) { G_Sound( ent, G_SoundIndex( "sound/movers/objects/objectHitHeavy.wav" ) ); } else { G_Sound( ent, G_SoundIndex( "sound/movers/objects/objectHit.wav" ) ); } } DoImpact( ent, traceEnt, !(tr.surfaceFlags&SURF_NODAMAGE), &tr ); } if ( !ent || (ent->takedamage&&ent->health <= 0) ) {//been destroyed by impact //chunks? G_Sound( ent, G_SoundIndex( "sound/movers/objects/objectBreak.wav" ) ); return; } //do impact physics if ( ent->s.pos.trType == TR_GRAVITY )//tr.fraction < 1.0 && {//FIXME: only do this if no trDelta if ( g_gravity->value <= 0 || tr.plane.normal[2] < 0.7 ) { if ( ent->s.eFlags&(EF_BOUNCE|EF_BOUNCE_HALF) ) { if ( tr.fraction <= 0.0f ) { VectorCopy( tr.endpos, ent->currentOrigin ); VectorCopy( tr.endpos, ent->s.pos.trBase ); VectorClear( ent->s.pos.trDelta ); ent->s.pos.trTime = level.time; } else { G_BounceObject( ent, &tr ); } } else {//slide down? //FIXME: slide off the slope } } else { ent->s.apos.trType = TR_STATIONARY; pitch_roll_for_slope( ent, tr.plane.normal ); //ent->currentAngles[0] = 0;//FIXME: match to slope //ent->currentAngles[2] = 0;//FIXME: match to slope VectorCopy( ent->currentAngles, ent->s.apos.trBase ); //okay, we hit the floor, might as well stop or prediction will //make us go through the floor! //FIXME: this means we can't fall if something is pulled out from under us... G_StopObjectMoving( ent ); } } else { ent->s.apos.trType = TR_STATIONARY; pitch_roll_for_slope( ent, tr.plane.normal ); //ent->currentAngles[0] = 0;//FIXME: match to slope //ent->currentAngles[2] = 0;//FIXME: match to slope VectorCopy( ent->currentAngles, ent->s.apos.trBase ); } //call touch func GEntity_TouchFunc( ent, &g_entities[tr.entityNum], &tr ); }
void G_RunMissile( gentity_t *ent ) { vec3_t origin, oldOrg; trace_t tr; int trHitLoc=HL_NONE; VectorCopy( ent->currentOrigin, oldOrg ); // get current position if ( ent->s.pos.trType == TR_INTERPOLATE ) {//rolling missile? //FIXME: WTF?!! Sticks to stick missiles? //FIXME: they stick inside the player G_RollMissile( ent ); if ( ent->s.eType != ET_GENERAL ) {//didn't explode VectorCopy( ent->currentOrigin, ent->s.pos.trBase ); gi.trace( &tr, oldOrg, ent->mins, ent->maxs, ent->currentOrigin, ent->s.number, ent->clipmask, G2_RETURNONHIT, 10 ); if ( VectorCompare( ent->s.pos.trDelta, vec3_origin ) ) { //VectorCopy( ent->currentAngles, ent->s.apos.trBase ); VectorClear( ent->s.apos.trDelta ); } else { vec3_t ang, fwdDir, rtDir; float speed; ent->s.apos.trType = TR_INTERPOLATE; VectorSet( ang, 0, ent->s.apos.trBase[1], 0 ); AngleVectors( ang, fwdDir, rtDir, NULL ); speed = VectorLength( ent->s.pos.trDelta )*4; //HMM, this works along an axis-aligned dir, but not along diagonals //This is because when roll gets to 90, pitch becomes yaw, and vice-versa //Maybe need to just set the angles directly? ent->s.apos.trDelta[0] = DotProduct( fwdDir, ent->s.pos.trDelta ); ent->s.apos.trDelta[1] = 0;//never spin! ent->s.apos.trDelta[2] = DotProduct( rtDir, ent->s.pos.trDelta ); VectorNormalize( ent->s.apos.trDelta ); VectorScale( ent->s.apos.trDelta, speed, ent->s.apos.trDelta ); ent->s.apos.trTime = level.previousTime; } } } else { EvaluateTrajectory( &ent->s.pos, level.time, origin ); // trace a line from the previous position to the current position, // ignoring interactions with the missile owner /* gi.trace( &tr, ent->currentOrigin, ent->mins, ent->maxs, origin, ent->owner ? ent->owner->s.number : ENTITYNUM_NONE, ent->clipmask, G2_RETURNONHIT, 10 ); */ gi.trace( &tr, ent->currentOrigin, ent->mins, ent->maxs, origin, ent->owner ? ent->owner->s.number : ent->s.number, ent->clipmask, G2_COLLIDE, 10 ); /* if ( !VectorCompare( ent->mins, vec3_origin ) || !VectorCompare( ent->maxs, vec3_origin ) ) {//don't do ghoul trace if ent has size because g2 just ignores that anyway gi.trace( &tr, ent->currentOrigin, ent->mins, ent->maxs, origin, ent->owner ? ent->owner->s.number : ENTITYNUM_NONE, ent->clipmask, G2_NOCOLLIDE, 10 ); } else //Now we always do ghoul trace, regardless of bbox size of missile, this is presuming that non-point ghoul traces will be possible...? { gi.trace( &tr, ent->currentOrigin, vec3_origin, vec3_origin, origin, ent->owner ? ent->owner->s.number : ENTITYNUM_NONE, ent->clipmask, G2_RETURNONHIT, 10 ); } */ /* if ( tr.fraction == 0.0f && tr.plane.normal[2] == 1.0f && origin[2] < ent->currentOrigin[2] ) { if ( ent->s.pos.trType == TR_GRAVITY && !(ent->s.eFlags&EF_BOUNCE) && !(ent->s.eFlags&EF_BOUNCE_HALF) && ent->s.weapon == WP_THERMAL )//FIXME: EF_ROLLING { //FIXME: Needs to stop sometime! ent->s.pos.trType = TR_LINEAR; ent->s.pos.trDelta[2] = 0; EvaluateTrajectory( &ent->s.pos, level.time, origin ); // trace a line from the previous position to the current position, // ignoring interactions with the missile owner gi.trace( &tr, ent->currentOrigin, ent->mins, ent->maxs, origin, ent->owner ? ent->owner->s.number : ENTITYNUM_NONE, ent->clipmask | CONTENTS_GHOUL2 ); if ( tr.fraction == 1.0f ) { VectorCopy( tr.endpos, ent->s.pos.trBase ); VectorScale( ent->s.pos.trDelta, 0.975f, ent->s.pos.trDelta ); ent->s.pos.trTime = level.time; } ent->s.pos.trType = TR_GRAVITY; } } */ if ( tr.entityNum != ENTITYNUM_NONE && &g_entities[tr.entityNum] != NULL ) { gentity_t *other = &g_entities[tr.entityNum]; // check for hitting a lightsaber if ( other->contents & CONTENTS_LIGHTSABER ) {//hit a lightsaber bbox if ( other->owner && other->owner->client && !other->owner->client->ps.saberInFlight && !InFront( ent->currentOrigin, other->owner->currentOrigin, other->owner->client->ps.viewangles, SABER_REFLECT_MISSILE_CONE ) )//other->owner->s.number == 0 && {//Jedi cannot block shots from behind! //re-trace from here, ignoring the lightsaber gi.trace( &tr, tr.endpos, ent->mins, ent->maxs, origin, tr.entityNum, ent->clipmask, G2_RETURNONHIT, 10 ); } } } VectorCopy( tr.endpos, ent->currentOrigin ); } // get current angles VectorMA( ent->s.apos.trBase, (level.time - ent->s.apos.trTime) * 0.001, ent->s.apos.trDelta, ent->s.apos.trBase ); //FIXME: Rolling things hitting G2 polys is weird /////////////////////////////////////////////////////// //? if ( tr.fraction != 1 ) { // did we hit or go near a Ghoul2 model? // qboolean hitModel = qfalse; for (int i=0; i < MAX_G2_COLLISIONS; i++) { if (tr.G2CollisionMap[i].mEntityNum == -1) { break; } CCollisionRecord &coll = tr.G2CollisionMap[i]; gentity_t *hitEnt = &g_entities[coll.mEntityNum]; /* Sorry...this was just getting in the way.... #if _DEBUG vec3_t delta; VectorSubtract(origin, coll.mCollisionPosition, delta); VectorNormalize(delta); VectorScale(delta, 30, delta); if (coll.mFlags & G2_BACKFACE) { VectorAdd(delta, coll.mCollisionPosition, delta); G_DebugLine(coll.mCollisionPosition, delta, 10000, 0x00ff0000, qtrue); } else { VectorSubtract(coll.mCollisionPosition, delta, delta); G_DebugLine(coll.mCollisionPosition, delta, 10000, 0x0000ff00, qtrue); } //loadsavecrash // VectorCopy(hitEnt->mins, hitEnt->s.mins); // VectorCopy(hitEnt->maxs, hitEnt->s.maxs); #endif */ // process collision records here... // make sure we only do this once, not for all the entrance wounds we might generate if ((coll.mFlags & G2_FRONTFACE)/* && !(hitModel)*/ && hitEnt->health) { // create a new surface using the details of what poly/surface/model we hit // int newSurface = gi.G2API_AddSurface(&hitEnt->ghoul2[coll.mModelIndex], coll.mSurfaceIndex, coll.mPolyIndex, coll.mBarycentricI, coll.mBarycentricJ, 10); // surfaceInfo_t *newSuf = &hitEnt->ghoul2[coll.mModelIndex].mSlist[newSurface]; // attach a bolt to this surface // int newBolt = gi.G2API_AddBoltSurfNum(&hitEnt->ghoul2[coll.mModelIndex], newSurface); // now attach an effect to this new bolt // Bolting on this effect just looks dumb and adds lots of unnecessary effects to the scene // // G_PlayEffect( G_EffectIndex( "blaster/smoke_bolton") , coll.mModelIndex, newBolt, hitEnt->s.number); // // // G_SetBoltSurfaceRemoval(coll.mEntityNum, coll.mModelIndex, newBolt, newSurface, 10000); // hitModel = qtrue; if (trHitLoc==HL_NONE) { G_GetHitLocFromSurfName( &g_entities[coll.mEntityNum], gi.G2API_GetSurfaceName( &g_entities[coll.mEntityNum].ghoul2[coll.mModelIndex], coll.mSurfaceIndex ), &trHitLoc, coll.mCollisionPosition, NULL, NULL, ent->methodOfDeath ); } break; // NOTE: the way this whole section was working, it would only get inside of this IF once anyway, might as well break out now } } } ///////////////////////////////////////////////////////// if ( tr.startsolid ) { tr.fraction = 0; } gi.linkentity( ent ); if ( ent->s.pos.trType == TR_STATIONARY && (ent->s.eFlags&EF_MISSILE_STICK) ) {//stuck missiles should check some special stuff G_RunStuckMissile( ent ); return; } // check think function G_RunThink( ent ); if ( ent->s.eType != ET_MISSILE ) { return; // exploded } if ( ent->mass ) { G_MoverTouchPushTriggers( ent, oldOrg ); } /* if ( !(ent->s.eFlags & EF_TELEPORT_BIT) ) { G_MoverTouchTeleportTriggers( ent, oldOrg ); if ( ent->s.eFlags & EF_TELEPORT_BIT ) {//was teleported return; } } else { ent->s.eFlags &= ~EF_TELEPORT_BIT; } */ AddSightEvent( ent->owner, ent->currentOrigin, 512, AEL_DISCOVERED, 75 );//wakes them up when see a shot passes in front of them if ( !Q_irand( 0, 10 ) ) {//not so often... if ( ent->splashDamage && ent->splashRadius ) {//I'm an exploder, let people around me know danger is coming if ( ent->s.weapon == WP_TRIP_MINE ) {//??? } else { if ( ent->s.weapon == WP_ROCKET_LAUNCHER && ent->e_ThinkFunc == thinkF_rocketThink ) {//homing rocket- run like hell! AddSightEvent( ent->owner, ent->currentOrigin, ent->splashRadius, AEL_DANGER_GREAT, 50 ); } else { AddSightEvent( ent->owner, ent->currentOrigin, ent->splashRadius, AEL_DANGER, 50 ); } AddSoundEvent( ent->owner, ent->currentOrigin, ent->splashRadius, AEL_DANGER ); } } else {//makes them run from near misses AddSightEvent( ent->owner, ent->currentOrigin, 48, AEL_DANGER, 50 ); } } if ( tr.fraction == 1 ) { return; } // never explode or bounce on sky if ( tr.surfaceFlags & SURF_NOIMPACT ) { G_FreeEntity( ent ); return; } G_MissileImpact( ent, &tr, trHitLoc ); }