本文整理汇总了C++中G_TouchTriggers函数的典型用法代码示例。如果您正苦于以下问题:C++ G_TouchTriggers函数的具体用法?C++ G_TouchTriggers怎么用?C++ G_TouchTriggers使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了G_TouchTriggers函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SV_StepDirection
/*
======================
SV_StepDirection
Turns to the movement direction, and walks the current distance if
facing it.
======================
*/
qboolean SV_StepDirection (edict_t *ent, float yaw, float dist)
{
vec3_t move, oldorigin;
float delta;
ent->ideal_yaw = yaw;
M_ChangeYaw (ent);
yaw = yaw*M_PI*2 / 360;
move[0] = cos(yaw)*dist;
move[1] = sin(yaw)*dist;
move[2] = 0;
VectorCopy (ent->s.origin, oldorigin);
if (SV_movestep (ent, move, false))
{
delta = ent->s.angles[YAW] - ent->ideal_yaw;
if (delta > 45 && delta < 315)
{ // not turned far enough, so don't take the step
VectorCopy (oldorigin, ent->s.origin);
}
gi.linkentity (ent);
G_TouchTriggers (ent);
return true;
}
gi.linkentity (ent);
G_TouchTriggers (ent);
return false;
}
示例2: M_default_movestep
qboolean M_default_movestep (edict_t *self, usercmd_t *ucmd)
{
vec3_t movedir;
vec3_t neworigin;
int movetype;
float speed = 0;
AngleVectors( tv( 0, self->s.angles[YAW], 0), movedir, NULL, NULL);
if( ucmd->forwardmove > 200 )
speed = 20;
else if( ucmd->forwardmove > 10 )
speed = 5;
//else if( ucmd->forwardmove < -200 )
//speed = -20;
//else if( ucmd->forwardmove < -10 )
//speed = -5;
else {
//speed is 0
VectorCopy( self->s.origin, self->s.old_origin );
//relink
gi.linkentity(self);//trap_LinkEntity (self);
G_TouchTriggers (self);
return true;
}
VectorCopy( self->s.origin, self->s.old_origin );
//VectorCopy( self->ai->move_vector, movedir );
VectorNormalize( movedir );
movetype = M_default_GravityBoxStep( self->s.origin, speed, movedir, neworigin, self->mins, self->maxs, MASK_AISOLID, self );
if( movetype & LINK_INVALID )
{
return false;
} else {
VectorCopy( neworigin, self->s.origin );
//store velocity for dmclass move code checks
VectorSubtract(self->s.origin, self->s.old_origin, self->velocity);
//relink
gi.linkentity(self);//trap_LinkEntity (self);
G_TouchTriggers (self);
return true;
}
return false;
}
示例3: G_RoundTouchTriggers
static void G_RoundTouchTriggers (int team)
{
Actor* actor = nullptr;
while ((actor = G_EdictsGetNextLivingActorOfTeam(actor, team))) {
G_TouchTriggers(actor);
}
}
示例4: SpectatorThink
/*
=================
SpectatorThink
=================
*/
void SpectatorThink( gentity_t *ent, usercmd_t *ucmd )
{
gclient_t *client = ent->client;
if ( client->sess.spectatorState != SPECTATOR_FOLLOW )
{
client->ps.pm_type = PM_SPECTATOR;
client->ps.speed = 400; // faster than normal
pmove_t pm;
// set up for pmove
memset (&pm, 0, sizeof(pm));
pm.ps = &client->ps;
pm.cmd = *ucmd;
pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; // spectators can fly through bodies
pm.trace = trap_Trace;
pm.pointcontents = trap_PointContents;
pm.animations = NULL;
// perform a pmove
Pmove (&pm);
G_UpdatePlayerStateScores ( ent );
// save results of pmove
VectorCopy( client->ps.origin, ent->s.origin );
G_TouchTriggers( ent );
trap_UnlinkEntity( ent );
}
client->oldbuttons = client->buttons;
client->buttons = ucmd->buttons;
// attack button cycles through spectators
if ( client->sess.spectatorState != SPECTATOR_FOLLOW && g_forceFollow.integer )
{
Cmd_FollowCycle_f( ent, 1 );
}
if ( ( client->buttons & BUTTON_ATTACK ) && ! ( client->oldbuttons & BUTTON_ATTACK ) )
{
Cmd_FollowCycle_f( ent, 1 );
}
else if ( ( client->buttons & BUTTON_ALT_ATTACK ) && ! ( client->oldbuttons & BUTTON_ALT_ATTACK ) )
{
Cmd_FollowCycle_f( ent, -1 );
}
else if ( !g_forceFollow.integer && ucmd->upmove > 0 && (client->ps.pm_flags & PMF_FOLLOW) )
{
G_StopFollowing( ent );
}
}
示例5: SV_StepDirection
/*
======================
SV_StepDirection
Turns to the movement direction, and walks the current distance if
facing it.
======================
*/
qboolean SV_StepDirection (edict_t *ent, float yaw, float dist)
{
vec3_t move, oldorigin;
float delta;
if(!ent->inuse) return true; // PGM g_touchtrigger free problem
ent->ideal_yaw = yaw;
M_ChangeYaw (ent);
yaw = yaw*M_PI*2 / 360;
move[0] = cos(yaw)*dist;
move[1] = sin(yaw)*dist;
move[2] = 0;
VectorCopy (ent->s.origin, oldorigin);
if (SV_movestep (ent, move, false))
{
ent->monsterinfo.aiflags &= ~AI_BLOCKED;
if(!ent->inuse) return true; // PGM g_touchtrigger free problem
delta = ent->s.angles[YAW] - ent->ideal_yaw;
if (strncmp(ent->classname, "monster_widow", 13))
{
if (delta > 45 && delta < 315)
{ // not turned far enough, so don't take the step
VectorCopy (oldorigin, ent->s.origin);
}
}
gi.linkentity (ent);
G_TouchTriggers (ent);
return true;
}
gi.linkentity (ent);
G_TouchTriggers (ent);
return false;
}
示例6: SV_PushEntity
/*
* Does not change the entities velocity at all
*/
trace_t
SV_PushEntity(edict_t *ent, vec3_t push)
{
trace_t trace;
vec3_t start;
vec3_t end;
int mask;
VectorCopy(ent->s.origin, start);
VectorAdd(start, push, end);
retry:
if (ent->clipmask)
{
mask = ent->clipmask;
}
else
{
mask = MASK_SOLID;
}
trace = gi.trace(start, ent->mins, ent->maxs, end, ent, mask);
VectorCopy(trace.endpos, ent->s.origin);
gi.linkentity(ent);
if (trace.fraction != 1.0)
{
SV_Impact(ent, &trace);
/* if the pushed entity went away and the pusher is still there */
if (!trace.ent->inuse && ent->inuse)
{
/* move the pusher back and try again */
VectorCopy(start, ent->s.origin);
gi.linkentity(ent);
goto retry;
}
}
if (ent->inuse)
{
G_TouchTriggers(ent);
}
return trace;
}
示例7: SV_PushEntity
/*
============
SV_PushEntity
Does not change the entities velocity at all
============
*/
trace_t SV_PushEntity (edict_t *ent, vec3_t push)
{
trace_t trace;
vec3_t start;
vec3_t end;
int mask;
VectorCopy (ent->s.origin, start);
VectorAdd (start, push, end);
retry:
if (ent->clipmask)
mask = ent->clipmask;
else
mask = MASK_SOLID;
trace = gi.trace (start, ent->mins, ent->maxs, end, ent, mask);
VectorCopy (trace.endpos, ent->s.origin);
gi.linkentity (ent);
if (trace.fraction != 1.0)
{
SV_Impact (ent, &trace);
// if the pushed entity went away and the pusher is still there
if (!trace.ent->inuse && ent->inuse)
{
// move the pusher back and try again
VectorCopy (start, ent->s.origin);
gi.linkentity (ent);
goto retry;
}
}
// ================
// PGM
// FIXME - is this needed?
ent->gravity = 1.0;
// PGM
// ================
if (ent->inuse)
G_TouchTriggers (ent);
return trace;
}
示例8: G_ActorUseDoor
/**
* @brief Make the actor use (as in open/close) a door edict
* @note Will also check whether the door is still reachable (this might have
* changed due to the rotation) after the usage
* @param actor The actor that is using the door
* @param door The door that should be opened/closed
*/
void G_ActorUseDoor (Edict* actor, Edict* door)
{
/* check whether it's part of an edict group but not the master */
if (door->flags & FL_GROUPSLAVE)
door = door->groupMaster;
if (!G_ClientUseEdict(actor->getPlayer(), actor, door))
return;
/* end this loop here, for the AI this is a) not interesting,
* and b) could result in endless loops */
if (G_IsAI(actor))
return;
Edict* closeActor = nullptr;
while ((closeActor = G_FindRadius(closeActor, door->origin, UNIT_SIZE * 3))) {
/* check whether the door is still reachable (this might have
* changed due to the rotation) or whether an actor can reach it now */
G_TouchTriggers(closeActor);
}
}
示例9: G_PushEntity
/*
* @brief Does not change the entity's velocity at all
*/
c_trace_t G_PushEntity(g_edict_t *ent, vec3_t push) {
c_trace_t trace;
vec3_t start;
vec3_t end;
int32_t mask;
VectorCopy(ent->s.origin, start);
VectorAdd(start, push, end);
retry: if (ent->clip_mask)
mask = ent->clip_mask;
else
mask = MASK_SOLID;
trace = gi.Trace(start, end, ent->mins, ent->maxs, ent, mask);
VectorCopy(trace.end, ent->s.origin);
gi.LinkEdict(ent);
if (trace.fraction != 1.0) {
G_Impact(ent, &trace);
// if the pushed entity went away and the pusher is still there
if (!trace.ent->in_use && ent->in_use) {
// move the pusher back and try again
VectorCopy(start, ent->s.origin);
gi.LinkEdict(ent);
goto retry;
}
}
if (ent->in_use && ent->client && ent->locals.health > 0)
G_TouchTriggers(ent);
return trace;
}
示例10: SV_movestep
//FIXME since we need to test end position contents here, can we avoid doing
//it again later in catagorize position?
qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
{
float dz;
vec3_t oldorg, neworg, end;
trace_t trace;
int i;
float stepsize;
vec3_t test;
int contents;
// BEGIN: Xatrix/Ridah/Navigator/14-apr-1998
int mask = MASK_MONSTERSOLID;
if (ent->cast_info.aiflags & AI_PLAYERCLIP)
mask = MASK_PLAYERSOLID;
else if (ent->flags & FL_RESPAWN) // used for moveout command
mask = MASK_SOLID;
// END: Xatrix/Ridah/Navigator/14-apr-1998
// try the move
VectorCopy (ent->s.origin, oldorg);
VectorAdd (ent->s.origin, move, neworg);
// flying monsters don't step up
if ( ent->flags & (FL_SWIM | FL_FLY) )
{
// try one move with vertical motion, then one without
for (i=0 ; i<2 ; i++)
{
VectorAdd (ent->s.origin, move, neworg);
if (i == 0 && ent->enemy)
{
if (!ent->goalentity)
ent->goalentity = ent->enemy;
dz = ent->s.origin[2] - ent->goalentity->s.origin[2];
if (ent->goalentity->client)
{
if (dz > 40)
neworg[2] -= 8;
if (!((ent->flags & FL_SWIM) && (ent->waterlevel < 2)))
if (dz < 30)
neworg[2] += 8;
}
else
{
if (dz > 8)
neworg[2] -= 8;
else if (dz > 0)
neworg[2] -= dz;
else if (dz < -8)
neworg[2] += 8;
else
neworg[2] += dz;
}
}
// BEGIN: Xatrix/Ridah/Navigator/14-apr-1998 (use modified mask for Grunts)
trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, neworg, ent, mask);
// END: Xatrix/Ridah/Navigator/14-apr-1998
// fly monsters don't enter water voluntarily
if (ent->flags & FL_FLY)
{
if (!ent->waterlevel)
{
test[0] = trace.endpos[0];
test[1] = trace.endpos[1];
test[2] = trace.endpos[2] + ent->mins[2] + 1;
contents = gi.pointcontents(test);
if (contents & MASK_WATER)
return false;
}
}
// swim monsters don't exit water voluntarily
if (ent->flags & FL_SWIM)
{
if (ent->waterlevel < 2)
{
test[0] = trace.endpos[0];
test[1] = trace.endpos[1];
test[2] = trace.endpos[2] + ent->mins[2] + 1;
contents = gi.pointcontents(test);
if (!(contents & MASK_WATER))
return false;
}
}
if (trace.fraction == 1)
{
VectorCopy (trace.endpos, ent->s.origin);
if (relink)
{
gi.linkentity (ent);
G_TouchTriggers (ent);
}
return true;
//.........这里部分代码省略.........
示例11: ClientThink
//.........这里部分代码省略.........
{
pm.snapinitial = true;
// gi.dprintf ("pmove changed!\n");
}
pm.cmd = *ucmd;
pm.trace = PM_trace; // adds default parms
pm.pointcontents = gi.pointcontents;
// perform a pmove
gi.Pmove (&pm);
// save results of pmove
client->ps.pmove = pm.s;
client->old_pmove = pm.s;
for (i=0 ; i<3 ; i++)
{
ent->s.origin[i] = pm.s.origin[i]*0.125;
ent->velocity[i] = pm.s.velocity[i]*0.125;
}
VectorCopy (pm.mins, ent->mins);
VectorCopy (pm.maxs, ent->maxs);
client->resp.cmd_angles[0] = SHORT2ANGLE(ucmd->angles[0]);
client->resp.cmd_angles[1] = SHORT2ANGLE(ucmd->angles[1]);
client->resp.cmd_angles[2] = SHORT2ANGLE(ucmd->angles[2]);
if (ent->groundentity && !pm.groundentity && (pm.cmd.upmove >= 10) && (pm.waterlevel == 0))
{
gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
PlayerNoise(ent, ent->s.origin, PNOISE_SELF);
}
ent->viewheight = pm.viewheight;
ent->waterlevel = pm.waterlevel;
ent->watertype = pm.watertype;
ent->groundentity = pm.groundentity;
if (pm.groundentity)
ent->groundentity_linkcount = pm.groundentity->linkcount;
if (ent->deadflag)
{
client->ps.viewangles[ROLL] = 40;
client->ps.viewangles[PITCH] = -15;
client->ps.viewangles[YAW] = client->killer_yaw;
}
else
{
VectorCopy (pm.viewangles, client->v_angle);
VectorCopy (pm.viewangles, client->ps.viewangles);
}
gi.linkentity (ent);
if (ent->movetype != MOVETYPE_NOCLIP)
G_TouchTriggers (ent);
// touch other objects
for (i=0 ; i<pm.numtouch ; i++)
{
other = pm.touchents[i];
for (j=0 ; j<i ; j++)
if (pm.touchents[j] == other)
break;
if (j != i)
continue; // duplicated
if (!other->touch)
continue;
other->touch (other, ent, NULL, NULL);
}
client->oldbuttons = client->buttons;
client->buttons = ucmd->buttons;
client->latched_buttons |= client->buttons & ~client->oldbuttons;
// save light level the player is standing on for
// monster sighting AI
ent->light_level = ucmd->lightlevel;
// fire weapon from final position if needed
if (client->latched_buttons & BUTTON_ATTACK)
{
if (!client->weapon_thunk)
{
client->weapon_thunk = true;
Think_Weapon (ent);
}
}
#ifdef WITH_ACEBOT
// ACEBOT_ADD
if (!ent->is_bot && !ent->deadflag && !ent->client->resp.spectator)
ACEND_PathMap(ent);
// ACEBOT_END
#endif
}
示例12: G_ClientMove
//.........这里部分代码省略.........
G_EdictCalcOrigin(ent);
VectorCopy(ent->origin, pointTrace);
pointTrace[2] += PLAYER_MIN;
contentFlags = gi.PointContents(pointTrace);
/* link it at new position - this must be done for every edict
* movement - to let the server know about it. */
gi.LinkEdict(ent);
/* Only the PHALANX team has these stats right now. */
if (ent->chr.scoreMission) {
float truediv = gi.GetTUsForDirection(dir, 0); /* regardless of crouching ! */
if (G_IsCrouched(ent))
ent->chr.scoreMission->movedCrouched += truediv;
else
ent->chr.scoreMission->movedNormal += truediv;
}
/* write the step to the net */
G_WriteStep(ent, &stepAmount, dvec, contentFlags);
/* check if player appears/perishes, seen from other teams */
G_CheckVis(ent, true);
/* check for anything appearing, seen by "the moving one" */
status = G_CheckVisTeamAll(ent->team, false, ent);
/* Set ent->TU because the reaction code relies on ent->TU being accurate. */
G_ActorSetTU(ent, initTU - usedTUs);
clientAction = ent->clientAction;
oldState = ent->state;
oldHP = ent->HP;
/* check triggers at new position */
if (G_TouchTriggers(ent)) {
if (!clientAction)
status |= VIS_STOP;
}
G_TouchSolids(ent, 10.0f);
/* state has changed - maybe we walked on a trigger_hurt */
if (oldState != ent->state)
status |= VIS_STOP;
else if (oldHP != ent->HP)
status |= VIS_STOP;
} else if (crouchFlag == 1) {
/* Actor is standing */
G_ClientStateChange(player, ent, STATE_CROUCHED, true);
} else if (crouchFlag == -1) {
/* Actor is crouching and should stand up */
G_ClientStateChange(player, ent, STATE_CROUCHED, false);
}
/* check for reaction fire */
if (G_ReactionFireOnMovement(ent)) {
status |= VIS_STOP;
autoCrouchRequired = false;
}
/* check for death */
if (((oldHP != 0 && oldHP != ent->HP) || (oldState != ent->state)) && !G_IsDazed(ent)) {
/** @todo Handle dazed via trigger_hurt */
/* maybe this was due to rf - then the G_ActorDie was already called */
if (!G_IsDead(ent)) {
G_CheckDeathOrKnockout(ent, NULL, NULL, oldHP - ent->HP);
}
return;
}
if (G_ActorShouldStopInMidMove(ent, status, dvtab, numdv - 1)) {
/* don't autocrouch if new enemy becomes visible */
autoCrouchRequired = false;
break;
}
/* Restore ent->TU because the movement code relies on it not being modified! */
G_ActorSetTU(ent, initTU);
}
/* submit the TUs / round down */
if (g_notu != NULL && g_notu->integer)
G_ActorSetTU(ent, initTU);
else
G_ActorSetTU(ent, initTU - usedTUs);
G_SendStats(ent);
/* end the move */
G_GetFloorItems(ent);
gi.EndEvents();
}
if (autoCrouchRequired) {
/* toggle back to crouched state */
G_ClientStateChange(player, ent, STATE_CROUCHED, true);
}
}
示例13: SV_Push
//.........这里部分代码省略.........
// move to a visible node
if ((check->svflags & SVF_MONSTER) && !check->goal_ent)
{
extern void AI_FreeAndClearGoalEnt( edict_t *self );
node_t *node;
if (node = NAV_GetClosestNode( check, VIS_PARTIAL, false, false ))
{
check->goal_ent = G_Spawn();
check->goal_ent->owner = check;
VectorCopy( node->origin, check->goal_ent->s.origin );
check->goal_ent->think = AI_FreeAndClearGoalEnt;
check->goal_ent->nextthink = level.time + 3;
check->goal_ent->dmg_radius = 0; // get real close to it
if (check->cast_info.move_runwalk)
check->cast_info.currentmove = check->cast_info.move_runwalk;
else
check->cast_info.currentmove = check->cast_info.move_run;
}
}
// move this entity
pushed_p->ent = check;
VectorCopy (check->s.origin, pushed_p->origin);
VectorCopy (check->s.angles, pushed_p->angles);
pushed_p++;
// try moving the contacted entity
VectorAdd (check->s.origin, move, check->s.origin);
if (check->client)
{ // FIXME: doesn't rotate monsters?
check->client->ps.pmove.delta_angles[YAW] += amove[YAW];
// JOSEPH 5-APR-99
if (pusher->touch)
pusher->touch(pusher, check, 0, 0);
// END JOSEPH
}
// figure movement due to the pusher's amove
VectorSubtract (check->s.origin, pusher->s.origin, org);
org2[0] = DotProduct (org, forward);
org2[1] = -DotProduct (org, right);
org2[2] = DotProduct (org, up);
VectorSubtract (org2, org, move2);
VectorAdd (check->s.origin, move2, check->s.origin);
// may have pushed them off an edge
if (check->groundentity != pusher)
check->groundentity = NULL;
block = SV_TestEntityPosition (check);
if (!block)
{ // pushed ok
gi.linkentity (check);
// impact?
continue;
}
// if it is ok to leave in the old position, do it
// this is only relevent for riding entities, not pushed
// FIXME: this doesn't acount for rotation
VectorSubtract (check->s.origin, move, check->s.origin);
block = SV_TestEntityPosition (check);
if (!block)
{
pushed_p--;
continue;
}
}
// save off the obstacle so we can call the block function
obstacle = check;
// move back any entities we already moved
// go backwards, so if the same entity was pushed
// twice, it goes back to the original position
for (p=pushed_p-1 ; p>=pushed ; p--)
{
VectorCopy (p->origin, p->ent->s.origin);
VectorCopy (p->angles, p->ent->s.angles);
if (p->ent->client)
{
p->ent->client->ps.pmove.delta_angles[YAW] = p->deltayaw;
}
gi.linkentity (p->ent);
}
return false;
}
//FIXME: is there a better way to handle this?
// see if anything we moved has touched a trigger
for (p=pushed_p-1 ; p>=pushed ; p--)
G_TouchTriggers (p->ent);
return true;
}
示例14: G_ClientThink
//.........这里部分代码省略.........
VectorCopy(pm.maxs, ent->maxs);
client->cmd_angles[0] = SHORT2ANGLE(ucmd->angles[0]);
client->cmd_angles[1] = SHORT2ANGLE(ucmd->angles[1]);
client->cmd_angles[2] = SHORT2ANGLE(ucmd->angles[2]);
// check for jump, play randomized sound
if (ent->ground_entity && !pm.ground_entity && (pm.cmd.up >= 10)
&& (pm.water_level == 0) && client->jump_time < g_level.time
- 0.2) {
vec3_t angles, forward, velocity;
float speed;
VectorSet(angles, 0.0, ent->s.angles[YAW], 0.0);
AngleVectors(angles, forward, NULL, NULL);
VectorCopy(ent->velocity, velocity);
velocity[2] = 0.0;
speed = VectorNormalize(velocity);
if (DotProduct(velocity, forward) < 0.0 && speed > 200.0)
G_SetAnimation(ent, ANIM_LEGS_JUMP2, true);
else
G_SetAnimation(ent, ANIM_LEGS_JUMP1, true);
ent->s.event = EV_CLIENT_JUMP;
client->jump_time = g_level.time;
}
ent->view_height = pm.view_height;
ent->water_level = pm.water_level;
ent->water_type = pm.water_type;
ent->ground_entity = pm.ground_entity;
if (ent->ground_entity)
ent->ground_entity_link_count = ent->ground_entity->link_count;
VectorCopy(pm.angles, client->angles);
VectorCopy(pm.angles, client->ps.angles);
gi.LinkEntity(ent);
// touch jump pads, hurt brushes, etc..
if (ent->move_type != MOVE_TYPE_NO_CLIP && ent->health > 0)
G_TouchTriggers(ent);
// touch other objects
for (i = 0; i < pm.num_touch; i++) {
other = pm.touch_ents[i];
for (j = 0; j < i; j++)
if (pm.touch_ents[j] == other)
break;
if (j != i)
continue; // duplicated
if (!other->touch)
continue;
other->touch(other, ent, NULL, NULL);
}
}
client->old_buttons = client->buttons;
client->buttons = ucmd->buttons;
client->latched_buttons |= client->buttons & ~client->old_buttons;
// fire weapon if requested
if (client->latched_buttons & BUTTON_ATTACK) {
if (client->persistent.spectator) {
client->latched_buttons = 0;
if (client->chase_target) { // toggle chase camera
client->chase_target = NULL;
client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
} else {
G_ChaseTarget(ent);
}
} else if (client->weapon_think_time < g_level.time) {
G_WeaponThink(ent);
}
}
// update chase camera if being followed
for (i = 1; i <= sv_max_clients->integer; i++) {
other = g_game.edicts + i;
if (other->in_use && other->client->chase_target == ent) {
G_ChaseThink(other);
}
}
G_ClientInventoryThink(ent);
}
示例15: SV_Physics_Step
//.........这里部分代码省略.........
wasonground = true;
else
wasonground = false;
if (ent->avelocity[0] || ent->avelocity[1] || ent->avelocity[2])
SV_AddRotationalFriction (ent);
// add gravity except:
// flying monsters
// swimming monsters who are in the water
if (! wasonground)
if (!(ent->flags & FL_FLY))
if (!((ent->flags & FL_SWIM) && (ent->waterlevel > 2)))
{
if (ent->velocity[2] < sv_gravity->value*-0.1)
hitsound = true;
if (ent->waterlevel == 0)
SV_AddGravity (ent);
}
// friction for flying monsters that have been given vertical velocity
if ((ent->flags & FL_FLY) && (ent->velocity[2] != 0))
{
speed = fabs(ent->velocity[2]);
control = speed < sv_stopspeed->value ? sv_stopspeed->value : speed;
friction = sv_friction/3;
newspeed = speed - (FRAMETIME * control * friction);
if (newspeed < 0)
newspeed = 0;
newspeed /= speed;
ent->velocity[2] *= newspeed;
}
// friction for flying monsters that have been given vertical velocity
if ((ent->flags & FL_SWIM) && (ent->velocity[2] != 0))
{
speed = fabs(ent->velocity[2]);
control = speed < sv_stopspeed->value ? sv_stopspeed->value : speed;
newspeed = speed - (FRAMETIME * control * sv_waterfriction * ent->waterlevel);
if (newspeed < 0)
newspeed = 0;
newspeed /= speed;
ent->velocity[2] *= newspeed;
}
if (ent->velocity[2] || ent->velocity[1] || ent->velocity[0])
{
// apply friction
// let dead monsters who aren't completely onground slide
if ((wasonground) || (ent->flags & (FL_SWIM|FL_FLY)))
if (!(ent->health <= 0.0 && !M_CheckBottom(ent)))
{
vel = ent->velocity;
speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]);
if (speed)
{
friction = sv_friction;
control = speed < sv_stopspeed->value ? sv_stopspeed->value : speed;
newspeed = speed - FRAMETIME*control*friction;
if (newspeed < 0)
newspeed = 0;
newspeed /= speed;
vel[0] *= newspeed;
vel[1] *= newspeed;
}
}
if (ent->svflags & SVF_MONSTER)
mask = MASK_MONSTERSOLID;
else
mask = MASK_SOLID;
SV_FlyMove (ent, FRAMETIME, mask);
gi.linkentity (ent);
// ========
// PGM - reset this every time they move.
// G_touchtriggers will set it back if appropriate
ent->gravity = 1.0;
// ========
G_TouchTriggers (ent);
if (!ent->inuse)
return;
if (ent->groundentity)
if (!wasonground)
if (hitsound)
gi.sound (ent, 0, gi.soundindex("world/land.wav"), 1, 1, 0);
}
if(!ent->inuse) // PGM g_touchtrigger free problem
return;
// regular thinking
SV_RunThink (ent);
}