本文整理汇总了C++中G_RunThink函数的典型用法代码示例。如果您正苦于以下问题:C++ G_RunThink函数的具体用法?C++ G_RunThink怎么用?C++ G_RunThink使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了G_RunThink函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: G_RunItem
/*
================
G_RunItem
================
*/
void G_RunItem( gentity_t *ent ) {
vec3_t origin;
trace_t tr;
int contents;
int mask;
// if groundentity has been set to -1, it may have been pushed off an edge
if ( ent->s.groundEntityNum == -1 ) {
if ( ent->s.pos.trType != TR_GRAVITY ) {
ent->s.pos.trType = TR_GRAVITY;
ent->s.pos.trTime = level.time;
}
}
if ( ent->s.pos.trType == TR_STATIONARY ) {
// check think function
G_RunThink( ent );
return;
}
// get current position
BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
// trace a line from the previous position to the current position
if ( ent->clipmask ) {
mask = ent->clipmask;
} else {
mask = MASK_PLAYERSOLID & ~CONTENTS_BODY;//MASK_SOLID;
}
trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin,
ent->r.ownerNum, mask );
VectorCopy( tr.endpos, ent->r.currentOrigin );
if ( tr.startsolid ) {
tr.fraction = 0;
}
trap_LinkEntity( ent ); // FIXME: avoid this for stationary?
// check think function
G_RunThink( ent );
if ( tr.fraction == 1 ) {
return;
}
// if it is in a nodrop volume, remove it
contents = trap_PointContents( ent->r.currentOrigin, -1 );
if ( contents & CONTENTS_NODROP ) {
if (ent->item && ent->item->giType == IT_TEAM) {
Team_FreeEntity(ent);
} else {
G_FreeEntity( ent );
}
return;
}
G_BounceItem( ent, &tr );
}
示例2: G_RunMissile
/*
================
G_RunMissile
================
*/
void G_RunMissile( gentity_t *ent ) {
vec3_t origin;
trace_t tr;
int passent;
// get current position
BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
// if this missile bounced off an invulnerability sphere
if ( ent->target_ent ) {
passent = ent->target_ent->s.number;
}
// prox mines that left the owner bbox will attach to anything, even the owner
else if (ent->s.weapon == WP_PROX_LAUNCHER && ent->count) {
passent = ENTITYNUM_NONE;
}
else {
// ignore interactions with the missile owner
passent = ent->r.ownerNum;
}
// trace a line from the previous position to the current position
trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, passent, ent->clipmask );
if ( tr.startsolid || tr.allsolid ) {
// make sure the tr.entityNum is set to the entity we're stuck in
trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, passent, ent->clipmask );
tr.fraction = 0;
}
else {
VectorCopy( tr.endpos, ent->r.currentOrigin );
}
trap_LinkEntity( ent );
if ( tr.fraction != 1 ) {
// never explode or bounce on sky
if ( tr.surfaceFlags & SURF_NOIMPACT ) {
// If grapple, reset owner
if (ent->parent && ent->parent->client && ent->parent->client->hook == ent) {
ent->parent->client->hook = NULL;
}
G_FreeEntity( ent );
return;
}
G_MissileImpact( ent, &tr );
if ( ent->s.eType != ET_MISSILE ) {
return; // exploded
}
}
// if the prox mine wasn't yet outside the player body
if (ent->s.weapon == WP_PROX_LAUNCHER && !ent->count) {
// check if the prox mine is outside the owner bbox
trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, ENTITYNUM_NONE, ent->clipmask );
if (!tr.startsolid || tr.entityNum != ent->r.ownerNum) {
ent->count = 1;
}
}
// check think function after bouncing
G_RunThink( ent );
}
示例3: G_Physics_Noclip
/*
* @brief A moving object that doesn't obey physics
*/
static void G_Physics_Noclip(g_edict_t *ent) {
if (!G_RunThink(ent))
return;
VectorMA(ent->s.angles, gi.frame_seconds, ent->locals.avelocity, ent->s.angles);
VectorMA(ent->s.origin, gi.frame_seconds, ent->locals.velocity, ent->s.origin);
gi.LinkEdict(ent);
}
示例4: G_RunMissile
/*
================
G_RunMissile
================
*/
void G_RunMissile( gentity_t *ent )
{
vec3_t origin;
trace_t tr;
int passent;
// get current position
BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
// ignore interactions with the missile owner
passent = ent->r.ownerNum;
// trace a line from the previous position to the current position
trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, passent, ent->clipmask );
if( tr.startsolid || tr.allsolid )
{
// make sure the tr.entityNum is set to the entity we're stuck in
trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, passent, ent->clipmask );
tr.fraction = 0;
}
else
VectorCopy( tr.endpos, ent->r.currentOrigin );
ent->r.contents = CONTENTS_SOLID; //trick trap_LinkEntity into...
trap_LinkEntity( ent );
ent->r.contents = 0; //...encoding bbox information
if( tr.fraction != 1 )
{
// never explode or bounce on sky
if( tr.surfaceFlags & SURF_NOIMPACT )
{
// If grapple, reset owner
if( ent->parent && ent->parent->client && ent->parent->client->hook == ent )
ent->parent->client->hook = NULL;
G_FreeEntity( ent );
return;
}
G_MissileImpact( ent, &tr );
if( ent->s.eType != ET_MISSILE )
return; // exploded
}
// check think function after bouncing
G_RunThink( ent );
}
示例5: G_RunStuckMissile
void G_RunStuckMissile( gentity_t *ent ) {
if ( ent->takedamage ) {
if ( ent->s.groundEntityNum >= 0 && ent->s.groundEntityNum < ENTITYNUM_WORLD ) {
gentity_t *other = &g_entities[ent->s.groundEntityNum];
if ( (!VectorCompare( &vec3_origin, &other->s.pos.trDelta ) && other->s.pos.trType != TR_STATIONARY) ||
(!VectorCompare( &vec3_origin, &other->s.apos.trDelta ) && other->s.apos.trType != TR_STATIONARY) ) {//thing I stuck to is moving or rotating now, kill me
G_Damage( ent, other, other, NULL, NULL, 99999, 0, MOD_CRUSH );
return;
}
}
}
// check think function
G_RunThink( ent );
}
示例6: G_RunMover
/*
================
G_RunMover
================
*/
void G_RunMover( gentity_t *ent ) {
// if not a team captain, don't do anything, because
// the captain will handle everything
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 ) {
G_MoverTeam( ent );
}
// check think function
G_RunThink( ent );
}
示例7: G_Physics_Pusher
/*
* @brief Bmodel objects don't interact with each other, but push all box objects
*/
static void G_Physics_Pusher(g_edict_t *ent) {
vec3_t move, amove;
g_edict_t *part, *mv;
// if not a team captain, so movement will be handled elsewhere
if (ent->locals.flags & FL_TEAM_SLAVE)
return;
// make sure all team slaves can move before committing
// any moves or calling any think functions
// if the move is blocked, all moved objects will be backed out
// retry:
g_pushed_p = g_pushed;
for (part = ent; part; part = part->locals.team_chain) {
if (!VectorCompare(part->locals.velocity, vec3_origin) || !VectorCompare(
part->locals.avelocity, vec3_origin)) { // object is moving
VectorScale(part->locals.velocity, gi.frame_seconds, move);
VectorScale(part->locals.avelocity, gi.frame_seconds, amove);
if (!G_Push(part, move, amove))
break; // move was blocked
}
}
if (g_pushed_p > &g_pushed[MAX_EDICTS])
gi.Error("MAX_EDICTS exceeded\n");
if (part) {
// the move failed, bump all next_think times and back out moves
for (mv = ent; mv; mv = mv->locals.team_chain) {
if (mv->locals.next_think > 0)
mv->locals.next_think += gi.frame_millis;
}
// if the pusher has a "blocked" function, call it
// otherwise, just stay in place until the obstacle is gone
if (part->locals.Blocked)
part->locals.Blocked(part, obstacle);
} else {
// the move succeeded, so call all think functions
for (part = ent; part; part = part->locals.team_chain) {
G_RunThink(part);
}
}
}
示例8: G_RunMover
void G_RunMover( gentity_t *ent ) {
// if not a team captain, don't do anything, because
// the captain will handle everything
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 ) {
//OSP: pause
if ( level.pause.state == PAUSE_NONE )
G_MoverTeam( ent );
else
ent->s.pos.trTime += level.time - level.previousTime;
}
// check think function
G_RunThink( ent );
}
示例9: G_RunItem
/*
================
G_RunItem
================
*/
void G_RunItem( gentity_t *ent ) {
vec3_t origin;
trace_t tr;
int contents;
int mask;
// if groundentity has been set to -1, it may have been pushed off an edge
if ( ent->s.groundEntityNum == ENTITYNUM_NONE )
{
if ( ent->s.pos.trType != TR_GRAVITY )
{
ent->s.pos.trType = TR_GRAVITY;
ent->s.pos.trTime = level.time;
}
}
if ( ent->s.pos.trType == TR_STATIONARY )
{
// check think function
G_RunThink( ent );
if ( !g_gravity->value )
{
ent->s.pos.trType = TR_GRAVITY;
ent->s.pos.trTime = level.time;
ent->s.pos.trDelta[0] += crandom() * 40.0f; // I dunno, just do this??
ent->s.pos.trDelta[1] += crandom() * 40.0f;
ent->s.pos.trDelta[2] += random() * 20.0f;
}
else if ( (ent->flags&FL_DROPPED_ITEM)
&& ent->item
&& ent->item->giType == IT_WEAPON
&& ent->item->giTag == WP_SABER )
{//a dropped saber item, check below, just in case
int ignore = ENTITYNUM_NONE;
if ( ent->clipmask )
{
mask = ent->clipmask;
}
else
{
mask = MASK_SOLID|CONTENTS_PLAYERCLIP;//shouldn't be able to get anywhere player can't
}
if ( ent->owner )
{
ignore = ent->owner->s.number;
}
else if ( ent->activator )
{
ignore = ent->activator->s.number;
}
VectorSet( origin, ent->currentOrigin[0], ent->currentOrigin[1], ent->currentOrigin[2]-1 );
gi.trace( &tr, ent->currentOrigin, ent->mins, ent->maxs, origin, ignore, mask, (EG2_Collision)0, 0 );
if ( !tr.allsolid
&& !tr.startsolid
&& tr.fraction > 0.001f )
{//wha? fall....
ent->s.pos.trType = TR_GRAVITY;
ent->s.pos.trTime = level.time;
}
}
return;
}
// get current position
EvaluateTrajectory( &ent->s.pos, level.time, origin );
if ( ent->s.apos.trType != TR_STATIONARY )
{
EvaluateTrajectory( &ent->s.apos, level.time, ent->currentAngles );
G_SetAngles( ent, ent->currentAngles );
}
// trace a line from the previous position to the current position
if ( ent->clipmask )
{
mask = ent->clipmask;
}
else
{
mask = MASK_SOLID|CONTENTS_PLAYERCLIP;//shouldn't be able to get anywhere player can't
}
int ignore = ENTITYNUM_NONE;
if ( ent->owner )
{
ignore = ent->owner->s.number;
}
else if ( ent->activator )
{
ignore = ent->activator->s.number;
}
gi.trace( &tr, ent->currentOrigin, ent->mins, ent->maxs, origin, ignore, mask, (EG2_Collision)0, 0 );
VectorCopy( tr.endpos, ent->currentOrigin );
//.........这里部分代码省略.........
示例10: G_RunFrame
/*
================
G_RunFrame
Advances the non-player objects in the world
================
*/
void G_RunFrame( int levelTime )
{
int i;
// if we are waiting for the level to restart, do nothing
if( theLevel.restarted_ )
return;
theLevel.framenum_++;
theLevel.previousTime_ = theLevel.time_;
theLevel.time_ = levelTime;
int msec = theLevel.time_ - theLevel.previousTime_;
// get any cvar changes
G_UpdateCvars();
//
// go through all allocated objects
//
int start = Sys_Milliseconds();
GameEntity* ent = 0;//&g_entities[0];
for( i=0 ; i<theLevel.num_entities_ ; i++ )
{
ent = theLevel.getEntity(i);
if( !ent || !ent->inuse_ )
continue;
// clear events that are too old
if( theLevel.time_ - ent->eventTime_ > EVENT_VALID_MSEC )
{
if( ent->s.event )
{
ent->s.event = 0; // &= EV_EVENT_BITS;
if( ent->client_ )
{
ent->client_->ps_.externalEvent = 0;
// predicted events should never be set to zero
//ent->client->ps.events[0] = 0;
//ent->client->ps.events[1] = 0;
}
}
if( ent->freeAfterEvent_ )
{
// tempEntities or dropped items completely go away after their event
ent->freeUp();// former G_FreeEntity
continue;
}
else if( ent->unlinkAfterEvent_ )
{
// items that will respawn will hide themselves after their pickup event
ent->unlinkAfterEvent_ = false;
SV_UnlinkEntity( ent );
}
}
// temporary entities don't think
if( ent->freeAfterEvent_ )
continue;
if( ent->s.eType == ET_MISSILE ||
ent->s.eType == ET_BULLET )
{
G_RunMissile( ent );
continue;
}
if( ent->s.eType == ET_ITEM || ent->physicsObject_ )
{
G_RunItem( ent );
continue;
}
if( ent->s.eType == ET_MOVER )
{
G_RunMover( ent );
continue;
}
if( ent->client_ )
{
G_RunClient( ent );
continue;
}
G_RunThink( ent );
}
int end = Sys_Milliseconds();
start = Sys_Milliseconds();
// perform final fixups on the players
//ent = &g_entities[0];
for( i=1 ; i <= theLevel.maxclients_ ; i++ )
{
ent = theLevel.getEntity(i);
if( ent && ent->inuse_ )
ClientEndFrame( ent );
}
end = Sys_Milliseconds();
//.........这里部分代码省略.........
示例11: G_Physics
/*
================
G_Physics
================
*/
void G_Physics( gentity_t *ent, int msec )
{
vec3_t origin;
trace_t tr;
int contents;
// if groundentity has been set to ENTITYNUM_NONE, it may have been pushed off an edge
if ( ent->s.groundEntityNum == ENTITYNUM_NONE )
{
if ( ent->s.eType == ET_BUILDABLE )
{
if ( ent->s.pos.trType != BG_Buildable( ent->s.modelindex )->traj )
{
ent->s.pos.trType = BG_Buildable( ent->s.modelindex )->traj;
ent->s.pos.trTime = level.time;
}
}
else if ( ent->s.pos.trType != TR_GRAVITY )
{
ent->s.pos.trType = TR_GRAVITY;
ent->s.pos.trTime = level.time;
}
}
if ( ent->s.pos.trType == TR_STATIONARY )
{
// check think function
G_RunThink( ent );
//check floor infrequently
if ( ent->nextPhysicsTime < level.time )
{
VectorCopy( ent->r.currentOrigin, origin );
VectorMA( origin, -2.0f, ent->s.origin2, origin );
trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, ent->s.number, ent->clipmask );
if ( tr.fraction == 1.0f )
{
ent->s.groundEntityNum = ENTITYNUM_NONE;
}
ent->nextPhysicsTime = level.time + PHYSICS_TIME;
}
return;
}
// trace a line from the previous position to the current position
// get current position
BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, ent->s.number, ent->clipmask );
VectorCopy( tr.endpos, ent->r.currentOrigin );
if ( tr.startsolid )
{
tr.fraction = 0;
}
trap_LinkEntity( ent ); // FIXME: avoid this for stationary?
// check think function
G_RunThink( ent );
if ( tr.fraction == 1.0f )
{
return;
}
// if it is in a nodrop volume, remove it
contents = trap_PointContents( ent->r.currentOrigin, -1 );
if ( contents & CONTENTS_NODROP )
{
G_FreeEntity( ent );
return;
}
G_Bounce( ent, &tr );
}
示例12: G_RunMissile
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 );
//.........这里部分代码省略.........
示例13: G_RunFrame
/*
================
G_RunFrame
Advances the non-player objects in the world
================
*/
void G_RunFrame( int levelTime ) {
int i;
gentity_t *ent;
// if we are waiting for the level to restart, do nothing
if ( level.restarted ) {
return;
}
level.framenum++;
level.previousTime = level.time;
level.time = levelTime;
// get any cvar changes
G_UpdateCvars();
//
// go through all allocated objects
//
ent = &g_entities[0];
for (i=0 ; i<level.num_entities ; i++, ent++) {
if ( !ent->inuse ) {
continue;
}
// clear events that are too old
if ( level.time - ent->eventTime > EVENT_VALID_MSEC ) {
if ( ent->s.event ) {
ent->s.event = 0; // &= EV_EVENT_BITS;
if ( ent->client ) {
ent->client->ps.externalEvent = 0;
// predicted events should never be set to zero
//ent->client->ps.events[0] = 0;
//ent->client->ps.events[1] = 0;
}
}
if ( ent->freeAfterEvent ) {
// tempEntities or dropped items completely go away after their event
G_FreeEntity( ent );
continue;
} else if ( ent->unlinkAfterEvent ) {
// items that will respawn will hide themselves after their pickup event
ent->unlinkAfterEvent = qfalse;
trap_UnlinkEntity( ent );
}
}
// temporary entities don't think
if ( ent->freeAfterEvent ) {
continue;
}
if ( !ent->r.linked && ent->neverFree ) {
continue;
}
if ( ent->s.eType == ET_MISSILE ) {
G_RunMissile( ent );
continue;
}
if ( ent->s.eType == ET_ITEM || ent->physicsObject ) {
G_RunItem( ent );
continue;
}
if ( ent->s.eType == ET_MOVER ) {
G_RunMover( ent );
continue;
}
if ( i < MAX_CLIENTS ) {
G_RunClient( ent );
continue;
}
G_RunThink( ent );
}
// perform final fixups on the players
ent = &g_entities[0];
for (i=0 ; i < level.maxclients ; i++, ent++ ) {
if ( ent->inuse ) {
ClientEndFrame( ent );
}
}
// see if it is time to do a tournement restart
CheckTournament();
// see if it is time to end the level
CheckExitRules();
//.........这里部分代码省略.........
示例14: G_Physics_None
/*
* @brief Non moving objects can only think
*/
static void G_Physics_None(g_edict_t *ent) {
// regular thinking
G_RunThink(ent);
}
示例15: G_Physics_Toss
/*
* @brief Toss, bounce, and fly movement. When on ground, do nothing.
*/
static void G_Physics_Toss(g_edict_t *ent) {
vec3_t org, move;
// regular thinking
G_RunThink(ent);
// if not a team captain, movement will be handled elsewhere
if (ent->locals.flags & FL_TEAM_SLAVE)
return;
// check for the ground entity going away
if (ent->locals.ground_entity) {
if (!ent->locals.ground_entity->in_use)
ent->locals.ground_entity = NULL;
else if (ent->locals.velocity[2] > ent->locals.ground_entity->locals.velocity[2] + 0.1)
ent->locals.ground_entity = NULL;
else
return;
}
// if on ground, or intentionally floating, return without moving
if (ent->locals.ground_entity || (ent->locals.item && (ent->locals.spawn_flags & 4)))
return;
// enforce max velocity values
G_ClampVelocity(ent);
// move angles
VectorMA(ent->s.angles, gi.frame_seconds, ent->locals.avelocity, ent->s.angles);
// move origin
VectorCopy(ent->s.origin, org);
VectorScale(ent->locals.velocity, gi.frame_seconds, move);
// push through the world, interacting with triggers and other ents
c_trace_t trace = G_PushEntity(ent, move);
if (!ent->in_use)
return;
if (trace.fraction < 1.0) { // move was blocked
// if it was a floor, we might bounce or come to rest
vec_t *vel = ent->locals.velocity;
if (G_ClipVelocity(vel, trace.plane.normal, vel, 1.3) & 1) {
VectorSubtract(ent->s.origin, org, move);
// if we're approaching a stop, clear our velocity and set ground
if (VectorLength(move) < STOP_EPSILON) {
VectorClear(ent->locals.velocity);
ent->locals.ground_entity = trace.ent;
ent->locals.ground_entity_link_count = trace.ent->link_count;
} else {
// bounce and slide along the floor
vec_t bounce, speed = VectorLength(ent->locals.velocity);
bounce = sqrt(speed);
if (ent->locals.velocity[2] < bounce)
ent->locals.velocity[2] = bounce;
}
}
// all impacts reduce velocity and angular velocity
VectorScale(ent->locals.velocity, 0.9, ent->locals.velocity);
VectorScale(ent->locals.avelocity, 0.9, ent->locals.avelocity);
}
// check for water transition
const _Bool was_in_water = (ent->locals.water_type & MASK_WATER);
ent->locals.water_type = gi.PointContents(ent->s.origin);
const _Bool is_in_water = ent->locals.water_type & MASK_WATER;
if (is_in_water)
ent->locals.water_level = 1;
else
ent->locals.water_level = 0;
// add gravity
if (ent->locals.move_type == MOVE_TYPE_FLY)
G_AddFlying(ent);
else
G_AddGravity(ent);
if (!was_in_water && is_in_water) {
gi.PositionedSound(ent->s.origin, g_game.edicts, gi.SoundIndex("world/water_in"), ATTEN_NORM);
VectorScale(ent->locals.velocity, 0.66, ent->locals.velocity);
} else if (was_in_water && !is_in_water)
gi.PositionedSound(ent->s.origin, g_game.edicts, gi.SoundIndex("world/water_out"),
ATTEN_NORM);
// move team slaves
g_edict_t *slave = ent->locals.team_chain;
while (slave) {
VectorCopy(ent->s.origin, slave->s.origin);
//.........这里部分代码省略.........