codemp/game/g_object.c File Reference

#include "g_local.h"

Go to the source code of this file.

Functions

void G_MoverTouchPushTriggers (gentity_t *ent, vec3_t oldOrg)
void G_StopObjectMoving (gentity_t *object)
void pitch_roll_for_slope (gentity_t *forwhom, vec3_t pass_slope)
void G_BounceObject (gentity_t *ent, trace_t *trace)
void DoImpact (gentity_t *self, gentity_t *other, qboolean damageSelf)
void G_RunObject (gentity_t *ent)
void G_StartObjectMoving (gentity_t *object, vec3_t dir, float speed, trType_t trType)


Function Documentation

void DoImpact gentity_t self,
gentity_t other,
qboolean  damageSelf
 

10;

Definition at line 213 of file g_active.c.

References entityShared_t::absmax, gentity_s::client, CONTENTS_WATER, entityShared_t::currentOrigin, DAMAGE_NO_ARMOR, DotProduct, ENTITYNUM_NONE, ENTITYNUM_WORLD, playerState_s::fd, FL_BBRUSH, gentity_s::flags, forcedata_s::forceJumpZStart, G_ApplyKnockback(), G_Damage(), g_gravity, gentity_t, playerState_s::groundEntityNum, gentity_s::health, playerState_s::lastOnGround, level, gentity_s::mass, MAT_GLASS, MAT_GLASS_METAL, MAT_GRATE1, gentity_s::material, entityShared_t::maxs, entityShared_t::mins, MOD_CRUSH, MOD_FALLING, NULL, entityState_s::number, entityState_s::pos, gclient_s::ps, qboolean, qtrue, gentity_s::r, gentity_s::s, gentity_s::spawnflags, gentity_s::splashRadius, SVF_GLASS_BRUSH, entityShared_t::svFlags, gentity_s::takedamage, level_locals_t::time, TR_GRAVITY, trap_PointContents(), trajectory_t::trDelta, trajectory_t::trType, vmCvar_t::value, vec3_origin, vec3_t, VectorCopy, VectorNormalize(), VectorSubtract, playerState_s::velocity, entityState_s::weapon, and WP_SABER.

Referenced by Client_CheckImpactBBrush(), and G_RunObject().

00214 {
00215         float magnitude, my_mass;
00216         vec3_t  velocity;
00217         int cont;
00218         qboolean easyBreakBrush = qtrue;
00219 
00220         if( self->client )
00221         {
00222                 VectorCopy( self->client->ps.velocity, velocity );
00223                 if( !self->mass )
00224                 {
00225                         my_mass = 10;
00226                 }
00227                 else
00228                 {
00229                         my_mass = self->mass;
00230                 }
00231         }
00232         else 
00233         {
00234                 VectorCopy( self->s.pos.trDelta, velocity );
00235                 if ( self->s.pos.trType == TR_GRAVITY )
00236                 {
00237                         velocity[2] -= 0.25f * g_gravity.value;
00238                 }
00239                 if( !self->mass )
00240                 {
00241                         my_mass = 1;
00242                 }
00243                 else if ( self->mass <= 10 )
00244                 {
00245                         my_mass = 10;
00246                 }
00247                 else
00248                 {
00249                         my_mass = self->mass;
00250                 }
00251         }
00252 
00253         magnitude = VectorLength( velocity ) * my_mass / 10;
00254 
00255         /*
00256         if(pointcontents(self.absmax)==CONTENT_WATER)//FIXME: or other watertypes
00257                 magnitude/=3;                                                   //water absorbs 2/3 velocity
00258 
00259         if(self.classname=="barrel"&&self.aflag)//rolling barrels are made for impacts!
00260                 magnitude*=3;
00261 
00262         if(self.frozen>0&&magnitude<300&&self.flags&FL_ONGROUND&&loser==world&&self.velocity_z<-20&&self.last_onground+0.3<time)
00263                 magnitude=300;
00264         */
00265         if ( other->material == MAT_GLASS 
00266                 || other->material == MAT_GLASS_METAL 
00267                 || other->material == MAT_GRATE1
00268                 || ((other->flags&FL_BBRUSH)&&(other->spawnflags&8/*THIN*/))
00269                 || (other->r.svFlags&SVF_GLASS_BRUSH) )
00270         {
00271                 easyBreakBrush = qtrue;
00272         }
00273 
00274         if ( !self->client || self->client->ps.lastOnGround+300<level.time || ( self->client->ps.lastOnGround+100 < level.time && easyBreakBrush ) )
00275         {
00276                 vec3_t dir1, dir2;
00277                 float force = 0, dot;
00278 
00279                 if ( easyBreakBrush )
00280                         magnitude *= 2;
00281 
00282                 //damage them
00283                 if ( magnitude >= 100 && other->s.number < ENTITYNUM_WORLD )
00284                 {
00285                         VectorCopy( velocity, dir1 );
00286                         VectorNormalize( dir1 );
00287                         if( VectorCompare( other->r.currentOrigin, vec3_origin ) )
00288                         {//a brush with no origin
00289                                 VectorCopy ( dir1, dir2 );
00290                         }
00291                         else
00292                         {
00293                                 VectorSubtract( other->r.currentOrigin, self->r.currentOrigin, dir2 );
00294                                 VectorNormalize( dir2 );
00295                         }
00296 
00297                         dot = DotProduct( dir1, dir2 );
00298 
00299                         if ( dot >= 0.2 )
00300                         {
00301                                 force = dot;
00302                         }
00303                         else
00304                         {
00305                                 force = 0;
00306                         }
00307 
00308                         force *= (magnitude/50);
00309 
00310                         cont = trap_PointContents( other->r.absmax, other->s.number );
00311                         if( (cont&CONTENTS_WATER) )//|| (self.classname=="barrel"&&self.aflag))//FIXME: or other watertypes
00312                         {
00313                                 force /= 3;                                                     //water absorbs 2/3 velocity
00314                         }
00315 
00316                         /*
00317                         if(self.frozen>0&&force>10)
00318                                 force=10;
00319                         */
00320 
00321                         if( ( force >= 1 && other->s.number != 0 ) || force >= 10)
00322                         {
00323         /*                      
00324                                 dprint("Damage other (");
00325                                 dprint(loser.classname);
00326                                 dprint("): ");
00327                                 dprint(ftos(force));
00328                                 dprint("\n");
00329         */
00330                                 if ( other->r.svFlags & SVF_GLASS_BRUSH )
00331                                 {
00332                                         other->splashRadius = (float)(self->r.maxs[0] - self->r.mins[0])/4.0f;
00333                                 }
00334                                 if ( other->takedamage )
00335                                 {
00336                                         G_Damage( other, self, self, velocity, self->r.currentOrigin, force, DAMAGE_NO_ARMOR, MOD_CRUSH);//FIXME: MOD_IMPACT
00337                                 }
00338                                 else
00339                                 {
00340                                         G_ApplyKnockback( other, dir2, force );
00341                                 }
00342                         }
00343                 }
00344 
00345                 if ( damageSelf && self->takedamage )
00346                 {
00347                         //Now damage me
00348                         //FIXME: more lenient falling damage, especially for when driving a vehicle
00349                         if ( self->client && self->client->ps.fd.forceJumpZStart )
00350                         {//we were force-jumping
00351                                 if ( self->r.currentOrigin[2] >= self->client->ps.fd.forceJumpZStart )
00352                                 {//we landed at same height or higher than we landed
00353                                         magnitude = 0;
00354                                 }
00355                                 else
00356                                 {//FIXME: take off some of it, at least?
00357                                         magnitude = (self->client->ps.fd.forceJumpZStart-self->r.currentOrigin[2])/3;
00358                                 }
00359                         }
00360                         //if(self.classname!="monster_mezzoman"&&self.netname!="spider")//Cats always land on their feet
00361                                 if( ( magnitude >= 100 + self->health && self->s.number != 0 && self->s.weapon != WP_SABER ) || ( magnitude >= 700 ) )//&& self.safe_time < level.time ))//health here is used to simulate structural integrity
00362                                 {
00363                                         if ( (self->s.weapon == WP_SABER || self->s.number == 0) && self->client && self->client->ps.groundEntityNum < ENTITYNUM_NONE && magnitude < 1000 )
00364                                         {//players and jedi take less impact damage
00365                                                 //allow for some lenience on high falls
00366                                                 magnitude /= 2;
00367                                                 /*
00368                                                 if ( self.absorb_time >= time )//crouching on impact absorbs 1/2 the damage
00369                                                 {
00370                                                         magnitude/=2;
00371                                                 }
00372                                                 */
00373                                         }
00374                                         magnitude /= 40;
00375                                         magnitude = magnitude - force/2;//If damage other, subtract half of that damage off of own injury
00376                                         if ( magnitude >= 1 )
00377                                         {
00378                 //FIXME: Put in a thingtype impact sound function
00379                 /*                                      
00380                                                 dprint("Damage self (");
00381                                                 dprint(self.classname);
00382                                                 dprint("): ");
00383                                                 dprint(ftos(magnitude));
00384                                                 dprint("\n");
00385                 */
00386                                                 /*
00387                                                 if ( self.classname=="player_sheep "&& self.flags&FL_ONGROUND && self.velocity_z > -50 )
00388                                                         return;
00389                                                 */
00390                                                 G_Damage( self, NULL, NULL, NULL, self->r.currentOrigin, magnitude/2, DAMAGE_NO_ARMOR, MOD_FALLING );//FIXME: MOD_IMPACT
00391                                         }
00392                                 }
00393                 }
00394 
00395                 //FIXME: slow my velocity some?
00396 
00397                 // NOTENOTE We don't use lastimpact as of yet
00398 //              self->lastImpact = level.time;
00399 
00400                 /*
00401                 if(self.flags&FL_ONGROUND)
00402                         self.last_onground=time;
00403                 */
00404         }
00405 }

void G_BounceObject gentity_t ent,
trace_t trace
 

Definition at line 14 of file g_object.c.

References entityState_s::apos, BG_EvaluateTrajectoryDelta(), entityShared_t::currentAngles, entityShared_t::currentOrigin, DotProduct, trace_t::endpos, FL_BOUNCE_HALF, gentity_s::flags, trace_t::fraction, g_gravity, gentity_t, level, cplane_s::normal, trace_t::plane, entityState_s::pos, gentity_s::pos1, level_locals_t::previousTime, gentity_s::r, gentity_s::s, level_locals_t::time, TR_STATIONARY, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, vmCvar_t::value, vec3_t, VectorCopy, VectorMA, and VectorScale.

Referenced by G_RunObject().

00015 {
00016         vec3_t  velocity;
00017         float   dot, bounceFactor;
00018         int             hitTime;
00019 
00020         // reflect the velocity on the trace plane
00021         hitTime = level.previousTime + ( level.time - level.previousTime ) * trace->fraction;
00022         BG_EvaluateTrajectoryDelta( &ent->s.pos, hitTime, velocity );
00023         dot = DotProduct( velocity, trace->plane.normal );
00024 //      bounceFactor = 60/ent->mass;            // NOTENOTE Mass is not yet implemented
00025         bounceFactor = 1.0f;
00026         if ( bounceFactor > 1.0f )
00027         {
00028                 bounceFactor = 1.0f;
00029         }
00030         VectorMA( velocity, -2*dot*bounceFactor, trace->plane.normal, ent->s.pos.trDelta );
00031 
00032         //FIXME: customized or material-based impact/bounce sounds
00033         if ( ent->flags & FL_BOUNCE_HALF ) 
00034         {
00035                 VectorScale( ent->s.pos.trDelta, 0.5, ent->s.pos.trDelta );
00036 
00037                 // check for stop
00038                 if ( ((trace->plane.normal[2] > 0.7&&g_gravity.value>0) || (trace->plane.normal[2]<-0.7&&g_gravity.value<0)) && ((ent->s.pos.trDelta[2]<40&&g_gravity.value>0)||(ent->s.pos.trDelta[2]>-40&&g_gravity.value<0)) ) //this can happen even on very slightly sloped walls, so changed it from > 0 to > 0.7
00039                 {
00040                         //G_SetOrigin( ent, trace->endpos );
00041                         //ent->nextthink = level.time + 500;
00042                         ent->s.apos.trType = TR_STATIONARY;
00043                         VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
00044                         VectorCopy( trace->endpos, ent->r.currentOrigin );
00045                         VectorCopy( trace->endpos, ent->s.pos.trBase );
00046                         ent->s.pos.trTime = level.time;
00047                         return;
00048                 }
00049         }
00050 
00051         // NEW--It would seem that we want to set our trBase to the trace endpos
00052         //      and set the trTime to the actual time of impact....
00053         //      FIXME: Should we still consider adding the normal though??
00054         VectorCopy( trace->endpos, ent->r.currentOrigin );
00055         ent->s.pos.trTime = hitTime;
00056 
00057         VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
00058         VectorCopy( trace->plane.normal, ent->pos1 );//???
00059 }

void G_MoverTouchPushTriggers gentity_t ent,
vec3_t  oldOrg
 

Definition at line 601 of file g_active.c.

References entityShared_t::contents, CONTENTS_TRIGGER, entityShared_t::currentOrigin, ET_PUSH_TRIGGER, entityState_s::eType, g_entities, gentity_t, MAX_GENTITIES, entityShared_t::maxs, memset(), entityShared_t::mins, NULL, entityState_s::pos, gentity_s::r, gentity_s::s, gentity_s::touch, trap_EntitiesInBox(), trap_EntityContact(), trajectory_t::trDelta, vec3_t, VectorAdd, VectorMA, VectorNormalize(), and VectorSubtract.

Referenced by G_RunObject().

00602 {
00603         int                     i, num;
00604         float           step, stepSize, dist;
00605         int                     touch[MAX_GENTITIES];
00606         gentity_t       *hit;
00607         trace_t         trace;
00608         vec3_t          mins, maxs, dir, size, checkSpot;
00609         const vec3_t    range = { 40, 40, 52 };
00610 
00611         // non-moving movers don't hit triggers!
00612         if ( !VectorLengthSquared( ent->s.pos.trDelta ) ) 
00613         {
00614                 return;
00615         }
00616 
00617         VectorSubtract( ent->r.mins, ent->r.maxs, size );
00618         stepSize = VectorLength( size );
00619         if ( stepSize < 1 )
00620         {
00621                 stepSize = 1;
00622         }
00623 
00624         VectorSubtract( ent->r.currentOrigin, oldOrg, dir );
00625         dist = VectorNormalize( dir );
00626         for ( step = 0; step <= dist; step += stepSize )
00627         {
00628                 VectorMA( ent->r.currentOrigin, step, dir, checkSpot );
00629                 VectorSubtract( checkSpot, range, mins );
00630                 VectorAdd( checkSpot, range, maxs );
00631 
00632                 num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES );
00633 
00634                 // can't use ent->r.absmin, because that has a one unit pad
00635                 VectorAdd( checkSpot, ent->r.mins, mins );
00636                 VectorAdd( checkSpot, ent->r.maxs, maxs );
00637 
00638                 for ( i=0 ; i<num ; i++ ) 
00639                 {
00640                         hit = &g_entities[touch[i]];
00641 
00642                         if ( hit->s.eType != ET_PUSH_TRIGGER )
00643                         {
00644                                 continue;
00645                         }
00646 
00647                         if ( hit->touch == NULL ) 
00648                         {
00649                                 continue;
00650                         }
00651 
00652                         if ( !( hit->r.contents & CONTENTS_TRIGGER ) ) 
00653                         {
00654                                 continue;
00655                         }
00656 
00657 
00658                         if ( !trap_EntityContact( mins, maxs, hit ) ) 
00659                         {
00660                                 continue;
00661                         }
00662 
00663                         memset( &trace, 0, sizeof(trace) );
00664 
00665                         if ( hit->touch != NULL ) 
00666                         {
00667                                 hit->touch(hit, ent, &trace);
00668                         }
00669                 }
00670         }
00671 }

void G_RunObject gentity_t ent  ) 
 

Definition at line 72 of file g_object.c.

References trace_t::allsolid, entityState_s::apos, BG_EvaluateTrajectory(), gentity_s::clipmask, entityShared_t::currentAngles, entityShared_t::currentOrigin, DoImpact(), trace_t::endpos, trace_t::entityNum, FL_BOUNCE, FL_BOUNCE_HALF, gentity_s::flags, flrand(), trace_t::fraction, FRAMETIME, G_BounceObject(), g_entities, g_gravity, G_MoverTouchPushTriggers(), G_StopObjectMoving(), gentity_t, gentity_s::health, level, entityShared_t::maxs, entityShared_t::mins, gentity_s::nextthink, cplane_s::normal, NULL, entityState_s::number, gentity_s::parent, pitch_roll_for_slope(), trace_t::plane, entityState_s::pos, level_locals_t::previousTime, qtrue, gentity_s::r, gentity_s::s, trace_t::startsolid, gentity_s::takedamage, level_locals_t::time, gentity_s::touch, TR_GRAVITY, TR_LINEAR, TR_STATIONARY, trap_LinkEntity(), trap_Trace(), trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, vmCvar_t::value, vec3_t, VectorClear, VectorCopy, VectorScale, entityState_s::weapon, and WP_SABER.

Referenced by DeadSaberThink(), DownedSaberThink(), drop_charge(), G_StartObjectMoving(), HolocronThink(), JMSaberThink(), pas_fire(), saberFirstThrown(), SP_PAS(), thermalThinkStandard(), and TrapThink().

00073 {
00074         vec3_t          origin, oldOrg;
00075         trace_t         tr;
00076         gentity_t       *traceEnt = NULL;
00077 
00078         //FIXME: floaters need to stop floating up after a while, even if gravity stays negative?
00079         if ( ent->s.pos.trType == TR_STATIONARY )//g_gravity.value <= 0 && 
00080         {
00081                 ent->s.pos.trType = TR_GRAVITY;
00082                 VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
00083                 ent->s.pos.trTime = level.previousTime;//?necc?
00084                 if ( !g_gravity.value )
00085                 {
00086                         ent->s.pos.trDelta[2] += 100;
00087                 }
00088         }
00089 
00090         ent->nextthink = level.time + FRAMETIME;
00091 
00092         VectorCopy( ent->r.currentOrigin, oldOrg );
00093         // get current position
00094         BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
00095         //Get current angles?
00096         BG_EvaluateTrajectory( &ent->s.apos, level.time, ent->r.currentAngles );
00097 
00098         if ( VectorCompare( ent->r.currentOrigin, origin ) )
00099         {//error - didn't move at all!
00100                 return;
00101         }
00102         // trace a line from the previous position to the current position,
00103         // ignoring interactions with the missile owner
00104         trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, 
00105                 ent->parent ? ent->parent->s.number : ent->s.number, ent->clipmask );
00106 
00107         if ( !tr.startsolid && !tr.allsolid && tr.fraction ) 
00108         {
00109                 VectorCopy( tr.endpos, ent->r.currentOrigin );
00110                 trap_LinkEntity( ent );
00111         }
00112         else
00113         //if ( tr.startsolid ) 
00114         {
00115                 tr.fraction = 0;
00116         }
00117 
00118         G_MoverTouchPushTriggers( ent, oldOrg );
00119         /*
00120         if ( !(ent->s.eFlags & EF_TELEPORT_BIT) && !(ent->svFlags & SVF_NO_TELEPORT) )
00121         {
00122                 G_MoverTouchTeleportTriggers( ent, oldOrg );
00123                 if ( ent->s.eFlags & EF_TELEPORT_BIT )
00124                 {//was teleported
00125                         return;
00126                 }
00127         }
00128         else
00129         {
00130                 ent->s.eFlags &= ~EF_TELEPORT_BIT;
00131         }
00132         */
00133 
00134         if ( tr.fraction == 1 ) 
00135         {
00136                 if ( g_gravity.value <= 0 )
00137                 {
00138                         if ( ent->s.apos.trType == TR_STATIONARY )
00139                         {
00140                                 VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
00141                                 ent->s.apos.trType = TR_LINEAR;
00142                                 ent->s.apos.trDelta[1] = flrand( -300, 300 );
00143                                 ent->s.apos.trDelta[0] = flrand( -10, 10 );
00144                                 ent->s.apos.trDelta[2] = flrand( -10, 10 );
00145                                 ent->s.apos.trTime = level.time;
00146                         }
00147                 }
00148                 //friction in zero-G
00149                 if ( !g_gravity.value )
00150                 {
00151                         float friction = 0.975f;
00152                         //friction -= ent->mass/1000.0f;
00153                         if ( friction < 0.1 )
00154                         {
00155                                 friction = 0.1f;
00156                         }
00157 
00158                         VectorScale( ent->s.pos.trDelta, friction, ent->s.pos.trDelta );
00159                         VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
00160                         ent->s.pos.trTime = level.time;
00161                 }
00162                 return;
00163         }
00164 
00165         //hit something
00166 
00167         //Do impact damage
00168         traceEnt = &g_entities[tr.entityNum];
00169         if ( tr.fraction || (traceEnt && traceEnt->takedamage) )
00170         {
00171                 if ( !VectorCompare( ent->r.currentOrigin, oldOrg ) )
00172                 {//moved and impacted
00173                         if ( (traceEnt && traceEnt->takedamage) )
00174                         {//hurt someone
00175 //                              G_Sound( ent, G_SoundIndex( "sound/movers/objects/objectHurt.wav" ) );
00176                         }
00177 //                      G_Sound( ent, G_SoundIndex( "sound/movers/objects/objectHit.wav" ) );
00178                 }
00179 
00180                 if (ent->s.weapon != WP_SABER)
00181                 {
00182                         DoImpact( ent, traceEnt, qtrue );
00183                 }
00184         }
00185 
00186         if ( !ent || (ent->takedamage&&ent->health <= 0) )
00187         {//been destroyed by impact
00188                 //chunks?
00189 //              G_Sound( ent, G_SoundIndex( "sound/movers/objects/objectBreak.wav" ) );
00190                 return;
00191         }
00192 
00193         //do impact physics
00194         if ( ent->s.pos.trType == TR_GRAVITY )//tr.fraction < 1.0 && 
00195         {//FIXME: only do this if no trDelta
00196                 if ( g_gravity.value <= 0 || tr.plane.normal[2] < 0.7 )
00197                 {
00198                         if ( ent->flags&(FL_BOUNCE|FL_BOUNCE_HALF) )
00199                         {
00200                                 if ( tr.fraction <= 0.0f )
00201                                 {
00202                                         VectorCopy( tr.endpos, ent->r.currentOrigin );
00203                                         VectorCopy( tr.endpos, ent->s.pos.trBase );
00204                                         VectorClear( ent->s.pos.trDelta );
00205                                         ent->s.pos.trTime = level.time;
00206                                 }
00207                                 else
00208                                 {
00209                                         G_BounceObject( ent, &tr );
00210                                 }
00211                         }
00212                         else
00213                         {//slide down?
00214                                 //FIXME: slide off the slope
00215                         }
00216                 }
00217                 else
00218                 {
00219                         ent->s.apos.trType = TR_STATIONARY;
00220                         pitch_roll_for_slope( ent, tr.plane.normal );
00221                         //ent->r.currentAngles[0] = 0;//FIXME: match to slope
00222                         //ent->r.currentAngles[2] = 0;//FIXME: match to slope
00223                         VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
00224                         //okay, we hit the floor, might as well stop or prediction will
00225                         //make us go through the floor!
00226                         //FIXME: this means we can't fall if something is pulled out from under us...
00227                         G_StopObjectMoving( ent );
00228                 }
00229         }
00230         else if (ent->s.weapon != WP_SABER)
00231         {
00232                 ent->s.apos.trType = TR_STATIONARY;
00233                 pitch_roll_for_slope( ent, tr.plane.normal );
00234                 //ent->r.currentAngles[0] = 0;//FIXME: match to slope
00235                 //ent->r.currentAngles[2] = 0;//FIXME: match to slope
00236                 VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
00237         }
00238 
00239         //call touch func
00240         ent->touch( ent, &g_entities[tr.entityNum], &tr );
00241 }

void G_StartObjectMoving gentity_t object,
vec3_t  dir,
float  speed,
trType_t  trType
 

Definition at line 260 of file g_object.c.

References entityShared_t::currentOrigin, FRAMETIME, G_RunObject(), gentity_t, level, gentity_s::nextthink, NULL, entityState_s::pos, gentity_s::r, gentity_s::s, gentity_s::think, level_locals_t::time, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, vec3_t, VectorCopy, VectorNormalize(), and VectorScale.

00261 {
00262         VectorNormalize (dir);
00263 
00264         //object->s.eType = ET_GENERAL;
00265         object->s.pos.trType = trType;
00266         VectorCopy( object->r.currentOrigin, object->s.pos.trBase );
00267         VectorScale(dir, speed, object->s.pos.trDelta );
00268         object->s.pos.trTime = level.time;
00269 
00270         /*
00271         //FIXME: incorporate spin?
00272         vectoangles(dir, object->s.angles);
00273         VectorCopy(object->s.angles, object->s.apos.trBase);
00274         VectorSet(object->s.apos.trDelta, 300, 0, 0 );
00275         object->s.apos.trTime = level.time;
00276         */
00277 
00278         //FIXME: make these objects go through G_RunObject automatically, like missiles do
00279         if ( object->think == NULL )
00280         {
00281                 object->nextthink = level.time + FRAMETIME;
00282                 object->think = G_RunObject;
00283         }
00284         else
00285         {//You're responsible for calling RunObject
00286         }
00287 }

void G_StopObjectMoving gentity_t object  ) 
 

Definition at line 244 of file g_object.c.

References entityShared_t::currentOrigin, gentity_t, entityState_s::origin, entityState_s::pos, gentity_s::r, gentity_s::s, TR_STATIONARY, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trType, VectorClear, and VectorCopy.

Referenced by G_RunObject().

00245 {
00246         object->s.pos.trType = TR_STATIONARY;
00247         VectorCopy( object->r.currentOrigin, object->s.origin );
00248         VectorCopy( object->r.currentOrigin, object->s.pos.trBase );
00249         VectorClear( object->s.pos.trDelta );
00250 
00251         /*
00252         //Stop spinning
00253         VectorClear( self->s.apos.trDelta );
00254         vectoangles(trace->plane.normal, self->s.angles);
00255         VectorCopy(self->s.angles, self->r.currentAngles );
00256         VectorCopy(self->s.angles, self->s.apos.trBase);
00257         */
00258 }

void pitch_roll_for_slope gentity_t forwhom,
vec3_t  pass_slope
 

Definition at line 395 of file NPC.c.

References AngleVectors(), gentity_s::client, entityShared_t::currentAngles, entityShared_t::currentOrigin, DotProduct, fabs(), trace_t::fraction, gentity_t, MASK_SOLID, entityShared_t::mins, cplane_s::normal, NULL, entityState_s::number, playerState_s::origin, PITCH, trace_t::plane, gclient_s::ps, Q_fabs(), gentity_s::r, ROLL, gentity_s::s, trap_LinkEntity(), trap_Trace(), vec3_origin, vec3_t, vectoangles(), VectorCopy, and playerState_s::viewangles.

00396 {
00397         vec3_t  slope;
00398         vec3_t  nvf, ovf, ovr, startspot, endspot, new_angles = { 0, 0, 0 };
00399         float   pitch, mod, dot;
00400 
00401         //if we don't have a slope, get one
00402         if( !pass_slope || VectorCompare( vec3_origin, pass_slope ) )
00403         {
00404                 trace_t trace;
00405 
00406                 VectorCopy( forwhom->r.currentOrigin, startspot );
00407                 startspot[2] += forwhom->r.mins[2] + 4;
00408                 VectorCopy( startspot, endspot );
00409                 endspot[2] -= 300;
00410                 trap_Trace( &trace, forwhom->r.currentOrigin, vec3_origin, vec3_origin, endspot, forwhom->s.number, MASK_SOLID );
00411 //              if(trace_fraction>0.05&&forwhom.movetype==MOVETYPE_STEP)
00412 //                      forwhom.flags(-)FL_ONGROUND;
00413 
00414                 if ( trace.fraction >= 1.0 )
00415                         return;
00416 
00417                 if( !( &trace.plane ) )
00418                         return;
00419 
00420                 if ( VectorCompare( vec3_origin, trace.plane.normal ) )
00421                         return;
00422 
00423                 VectorCopy( trace.plane.normal, slope );
00424         }
00425         else
00426         {
00427                 VectorCopy( pass_slope, slope );
00428         }
00429 
00430 
00431         AngleVectors( forwhom->r.currentAngles, ovf, ovr, NULL );
00432 
00433         vectoangles( slope, new_angles );
00434         pitch = new_angles[PITCH] + 90;
00435         new_angles[ROLL] = new_angles[PITCH] = 0;
00436 
00437         AngleVectors( new_angles, nvf, NULL, NULL );
00438 
00439         mod = DotProduct( nvf, ovr );
00440 
00441         if ( mod<0 )
00442                 mod = -1;
00443         else
00444                 mod = 1;
00445 
00446         dot = DotProduct( nvf, ovf );
00447 
00448         if ( forwhom->client )
00449         {
00450                 float oldmins2;
00451 
00452                 forwhom->client->ps.viewangles[PITCH] = dot * pitch;
00453                 forwhom->client->ps.viewangles[ROLL] = ((1-Q_fabs(dot)) * pitch * mod);
00454                 oldmins2 = forwhom->r.mins[2];
00455                 forwhom->r.mins[2] = -24 + 12 * fabs(forwhom->client->ps.viewangles[PITCH])/180.0f;
00456                 //FIXME: if it gets bigger, move up
00457                 if ( oldmins2 > forwhom->r.mins[2] )
00458                 {//our mins is now lower, need to move up
00459                         //FIXME: trace?
00460                         forwhom->client->ps.origin[2] += (oldmins2 - forwhom->r.mins[2]);
00461                         forwhom->r.currentOrigin[2] = forwhom->client->ps.origin[2];
00462                         trap_LinkEntity( forwhom );
00463                 }
00464         }
00465         else
00466         {
00467                 forwhom->r.currentAngles[PITCH] = dot * pitch;
00468                 forwhom->r.currentAngles[ROLL] = ((1-Q_fabs(dot)) * pitch * mod);
00469         }
00470 }