#include "g_local.h"Go to the source code of this file.
|
|
Definition at line 3229 of file g_mover.c. Referenced by SP_func_wall(). |
|
|
Definition at line 28 of file g_mover.c. Referenced by Blocked_Door(). |
|
|
Definition at line 27 of file g_mover.c. Referenced by G_EntIsUnlockedDoor(), and SP_func_door(). |
|
|
|
|
|
Definition at line 33 of file g_mover.c. Referenced by InitMover(). |
|
|
Definition at line 30 of file g_mover.c. Referenced by G_EntIsUnlockedDoor(), LockDoors(), SP_func_door(), Touch_DoorTrigger(), UnLockDoors(), and Use_BinaryMover(). |
|
|
Definition at line 32 of file g_mover.c. Referenced by G_EntIsUnlockedDoor(), InitMover(), and SP_func_door(). |
|
|
|
|
|
Definition at line 29 of file g_mover.c. Referenced by UnLockDoors(). |
|
|
Definition at line 1708 of file g_mover.c. Referenced by SP_func_train(). |
|
|
|
|
|
|
|
||||||||||||
|
Definition at line 1008 of file g_mover.c. References gentity_s::damage, G_Damage(), gentity_t, MOD_CRUSH, MOVER_CRUSHER, NULL, gentity_s::spawnflags, and Use_BinaryMover(). Referenced by SP_func_door(), and SP_func_plat().
01009 {
01010 if ( ent->damage ) {
01011 G_Damage( other, ent, ent, NULL, NULL, ent->damage, 0, MOD_CRUSH );
01012 }
01013 if ( ent->spawnflags & MOVER_CRUSHER ) {
01014 return; // crushers don't reverse
01015 }
01016
01017 // reverse direction
01018 Use_BinaryMover( ent, ent, other );
01019 }
|
|
||||||||||||
|
Definition at line 501 of file g_mover.c. References gentity_t, entityShared_t::maxs, entityShared_t::mins, gentity_s::r, gentity_s::teamchain, vec3_t, VectorAdd, and VectorScale. Referenced by NAVNEW_ResolveEntityCollision(), Reached_BinaryMover(), and Use_BinaryMover_Go().
00502 {
00503 vec3_t slavecenter;
00504 gentity_t *slave;
00505
00506 //Start with our center
00507 VectorAdd(ent->r.mins, ent->r.maxs, center);
00508 VectorScale(center, 0.5, center);
00509 for ( slave = ent->teamchain ; slave ; slave = slave->teamchain )
00510 {
00511 //Find slave's center
00512 VectorAdd(slave->r.mins, slave->r.maxs, slavecenter);
00513 VectorScale(slavecenter, 0.5, slavecenter);
00514 //Add that to our own, find middle
00515 VectorAdd(center, slavecenter, center);
00516 VectorScale(center, 0.5, center);
00517 }
00518 }
|
|
||||||||||||||||
|
Definition at line 2028 of file g_mover.c. References entityState_s::apos, BMS_END, BMS_MID, BMS_START, EV_BMODEL_SOUND, G_AddEvent(), G_SoundSetIndex(), gentity_t, entityState_s::loopIsSoundset, entityState_s::loopSound, qfalse, qtrue, gentity_s::s, gentity_s::soundSet, entityState_s::soundSetIndex, TR_LINEAR, TR_STATIONARY, and trajectory_t::trType.
02029 {
02030 if( self->s.apos.trType == TR_LINEAR )
02031 {
02032 self->s.apos.trType = TR_STATIONARY;
02033 // stop the sound if it stops moving
02034 self->s.loopSound = 0;
02035 self->s.loopIsSoundset = qfalse;
02036 // play stop sound too?
02037 if ( self->soundSet && self->soundSet[0] )
02038 {
02039 self->s.soundSetIndex = G_SoundSetIndex(self->soundSet);
02040 G_AddEvent( self, EV_BMODEL_SOUND, BMS_END );
02041 }
02042 }
02043 else
02044 {
02045 if ( self->soundSet && self->soundSet[0] )
02046 {
02047 self->s.soundSetIndex = G_SoundSetIndex(self->soundSet);
02048 G_AddEvent( self, EV_BMODEL_SOUND, BMS_START );
02049 self->s.loopSound = BMS_MID;
02050 self->s.loopIsSoundset = qtrue;
02051 }
02052 self->s.apos.trType = TR_LINEAR;
02053 }
02054 }
|
|
||||||||||||||||
|
Definition at line 2009 of file g_mover.c. References BSET_USE, entityState_s::frame, G_ActivateBehavior(), G_UseTargets(), gentity_t, gentity_s::s, and gentity_s::spawnflags. Referenced by SP_func_static().
02010 {
02011 G_ActivateBehavior( self, BSET_USE );
02012
02013 if ( self->spawnflags & 4/*SWITCH_SHADER*/ )
02014 {
02015 self->s.frame = self->s.frame ? 0 : 1;//toggle frame
02016 }
02017 G_UseTargets( self, activator );
02018 }
|
|
||||||||||||||||||||||||
|
Definition at line 3099 of file g_mover.c. References gentity_t, GlobalUse(), qfalse, and gentity_s::takedamage. Referenced by SP_func_usable().
03100 {
03101 self->takedamage = qfalse;
03102 GlobalUse(self, inflictor, attacker);
03103 }
|
|
||||||||||||||||
|
Definition at line 3094 of file g_mover.c. References gentity_t, and GlobalUse(). Referenced by SP_func_usable().
03095 {
03096 GlobalUse(self, attacker, attacker);
03097 }
|
|
|
Definition at line 3013 of file g_mover.c. References func_usable_use(), gentity_t, gentity_s::r, gentity_s::spawnflags, SVF_PLAYER_USABLE, entityShared_t::svFlags, gentity_s::think, and gentity_s::use. Referenced by func_usable_use().
03014 {
03015 if ( self->spawnflags & 8 )
03016 {
03017 self->r.svFlags |= SVF_PLAYER_USABLE; //Replace the usable flag
03018 self->use = func_usable_use;
03019 self->think = 0;
03020 }
03021 }
|
|
||||||||||||||||
|
Definition at line 3036 of file g_mover.c. References BSET_USE, gentity_s::clipmask, entityShared_t::contents, gentity_s::count, EF_NODRAW, EF_SHADER_ANIM, entityState_s::eFlags, entityState_s::frame, func_usable_think(), func_wait_return_solid(), G_ActivateBehavior(), G_UseTargets(), gentity_s::genericValue5, gentity_t, level, gentity_s::nextthink, gentity_s::r, gentity_s::s, entityState_s::solid, gentity_s::spawnflags, SVF_NOCLIENT, SVF_PLAYER_USABLE, entityShared_t::svFlags, gentity_s::target, gentity_s::think, level_locals_t::time, gentity_s::use, and gentity_s::wait. Referenced by func_usable_think(), func_wait_return_solid(), and SP_func_usable().
03037 {//Toggle on and off
03038 G_ActivateBehavior( self, BSET_USE );
03039 if ( self->s.eFlags & EF_SHADER_ANIM )
03040 {//animate shader when used
03041 self->s.frame++;//inc frame
03042 if ( self->s.frame > self->genericValue5 )
03043 {//wrap around
03044 self->s.frame = 0;
03045 }
03046 if ( self->target && self->target[0] )
03047 {
03048 G_UseTargets( self, activator );
03049 }
03050 }
03051 else if ( self->spawnflags & 8 )
03052 {//ALWAYS_ON
03053 //Remove the ability to use the entity directly
03054 self->r.svFlags &= ~SVF_PLAYER_USABLE;
03055 //also remove ability to call any use func at all!
03056 self->use = 0;
03057
03058 if(self->target && self->target[0])
03059 {
03060 G_UseTargets(self, activator);
03061 }
03062
03063 if ( self->wait )
03064 {
03065 self->think = func_usable_think;
03066 self->nextthink = level.time + ( self->wait * 1000 );
03067 }
03068
03069 return;
03070 }
03071 else if ( !self->count )
03072 {//become solid again
03073 self->count = 1;
03074 func_wait_return_solid( self );
03075 }
03076 else
03077 {
03078 self->s.solid = 0;
03079 self->r.contents = 0;
03080 self->clipmask = 0;
03081 self->r.svFlags |= SVF_NOCLIENT;
03082 self->s.eFlags |= EF_NODRAW;
03083 self->count = 0;
03084
03085 if(self->target && self->target[0])
03086 {
03087 G_UseTargets(self, activator);
03088 }
03089 self->think = 0;
03090 self->nextthink = -1;
03091 }
03092 }
|
|
|
||||||||||||||||||||||||
|
Definition at line 2486 of file g_mover.c. References gentity_s::delay, gentity_s::enemy, floor(), funcBBrushDieGo(), gentity_t, level, gentity_s::nextthink, qfalse, gentity_s::takedamage, gentity_s::think, and level_locals_t::time. Referenced by funcBBrushUse().
02487 {
02488 self->takedamage = qfalse;//stop chain reaction runaway loops
02489
02490 self->enemy = attacker;
02491
02492 if(self->delay)
02493 {
02494 self->think = funcBBrushDieGo;
02495 self->nextthink = level.time + floor(self->delay * 1000.0f);
02496 return;
02497 }
02498
02499 funcBBrushDieGo(self);
02500 }
|
|
|
Definition at line 2384 of file g_mover.c. References entityShared_t::absmax, entityShared_t::absmin, gentity_s::client, gentity_s::clipmask, entityShared_t::contents, entityShared_t::currentOrigin, EF_MISSILE_STICK, entityState_s::eFlags, gentity_s::enemy, EV_GENERAL_SOUND, entityState_s::eventParm, G_Chunks(), G_Damage(), g_entities, G_FreeEntity(), G_MiscModelExplosion(), G_PlayEffectID(), G_RadiusDamage(), G_SoundIndex(), G_TempEntity(), G_UseTargets(), gentity_s::genericValue15, gentity_t, entityState_s::groundEntityNum, level, gentity_s::mass, gentity_s::material, material_t, MAX_GENTITIES, MOD_CRUSH, MOD_UNKNOWN, gentity_s::nextthink, NULL, entityState_s::number, qtrue, gentity_s::r, gentity_s::radius, random, gentity_s::s, entityState_s::solid, gentity_s::spawnflags, gentity_s::splashDamage, gentity_s::splashRadius, sqrt(), gentity_s::target, gentity_s::think, level_locals_t::time, trap_AdjustAreaPortalState(), trap_LinkEntity(), vec3_t, VectorAdd, VectorCopy, VectorMA, VectorNormalize(), VectorScale, VectorSet, and VectorSubtract. Referenced by funcBBrushDie().
02385 {
02386 vec3_t org, dir, up;
02387 gentity_t *attacker = self->enemy;
02388 float scale;
02389 int i, numChunks, size = 0;
02390 material_t chunkType = self->material;
02391
02392 // if a missile is stuck to us, blow it up so we don't look dumb
02393 for ( i = 0; i < MAX_GENTITIES; i++ )
02394 {
02395 if ( g_entities[i].s.groundEntityNum == self->s.number && ( g_entities[i].s.eFlags & EF_MISSILE_STICK ))
02396 {
02397 G_Damage( &g_entities[i], self, self, NULL, NULL, 99999, 0, MOD_CRUSH ); //?? MOD?
02398 }
02399 }
02400
02401 //So chunks don't get stuck inside me
02402 self->s.solid = 0;
02403 self->r.contents = 0;
02404 self->clipmask = 0;
02405 trap_LinkEntity(self);
02406
02407 VectorSet(up, 0, 0, 1);
02408
02409 if ( self->target && attacker != NULL )
02410 {
02411 G_UseTargets(self, attacker);
02412 }
02413
02414 VectorSubtract( self->r.absmax, self->r.absmin, org );// size
02415
02416 numChunks = random() * 6 + 18;
02417
02418 // This formula really has no logical basis other than the fact that it seemed to be the closest to yielding the results that I wanted.
02419 // Volume is length * width * height...then break that volume down based on how many chunks we have
02420 scale = sqrt( sqrt( org[0] * org[1] * org[2] )) * 1.75f;
02421
02422 if ( scale > 48 )
02423 {
02424 size = 2;
02425 }
02426 else if ( scale > 24 )
02427 {
02428 size = 1;
02429 }
02430
02431 scale = scale / numChunks;
02432
02433 if ( self->radius > 0.0f )
02434 {
02435 // designer wants to scale number of chunks, helpful because the above scale code is far from perfect
02436 // I do this after the scale calculation because it seems that the chunk size generally seems to be very close, it's just the number of chunks is a bit weak
02437 numChunks *= self->radius;
02438 }
02439
02440 VectorMA( self->r.absmin, 0.5, org, org );
02441 VectorAdd( self->r.absmin,self->r.absmax, org );
02442 VectorScale( org, 0.5f, org );
02443
02444 if ( attacker != NULL && attacker->client )
02445 {
02446 VectorSubtract( org, attacker->r.currentOrigin, dir );
02447 VectorNormalize( dir );
02448 }
02449 else
02450 {
02451 VectorCopy(up, dir);
02452 }
02453
02454 if ( !(self->spawnflags & 2048) ) // NO_EXPLOSION
02455 {
02456 // we are allowed to explode
02457 G_MiscModelExplosion( self->r.absmin, self->r.absmax, size, chunkType );
02458 }
02459
02460 if (self->genericValue15)
02461 { //a custom effect to play
02462 vec3_t ang;
02463 VectorSet(ang, 0.0f, 1.0f, 0.0f);
02464 G_PlayEffectID(self->genericValue15, org, ang);
02465 }
02466
02467 if ( self->splashDamage > 0 && self->splashRadius > 0 )
02468 {
02469 gentity_t *te;
02470 //explode
02471 G_RadiusDamage( org, self, self->splashDamage, self->splashRadius, self, NULL, MOD_UNKNOWN );
02472
02473 te = G_TempEntity( org, EV_GENERAL_SOUND );
02474 te->s.eventParm = G_SoundIndex("sound/weapons/explosions/cargoexplode.wav");
02475 }
02476
02477 //FIXME: base numChunks off size?
02478 G_Chunks( self->s.number, org, dir, self->r.absmin, self->r.absmax, 300, numChunks, chunkType, 0, (scale*self->mass) );
02479
02480 trap_AdjustAreaPortalState( self, qtrue );
02481 self->think = G_FreeEntity;
02482 self->nextthink = level.time + 50;
02483 //G_FreeEntity( self );
02484 }
|
|
||||||||||||||||
|
Definition at line 2518 of file g_mover.c. References entityShared_t::absmax, entityShared_t::absmin, gentity_s::activator, BSET_PAIN, ceil(), gentity_s::client, entityShared_t::currentOrigin, G_ActivateBehavior(), G_Chunks(), G_UseTargets2(), gentity_t, gentity_s::inuse, level, gentity_s::mass, MAT_DRK_STONE, MAT_GREY_STONE, MAT_LT_STONE, MAT_SNOWY_ROCK, gentity_s::material, NULL, entityState_s::number, gentity_s::pain, gentity_s::painDebounceTime, gentity_s::paintarget, Q_irand(), gentity_s::r, gentity_s::radius, gentity_s::s, level_locals_t::time, vec3_t, VectorAdd, VectorMA, VectorNormalize(), VectorScale, VectorSet, VectorSubtract, and gentity_s::wait. Referenced by SP_func_breakable().
02519 {
02520 if ( self->painDebounceTime > level.time )
02521 {
02522 return;
02523 }
02524
02525 if ( self->paintarget && self->paintarget[0] )
02526 {
02527 if (!self->activator)
02528 {
02529 if (attacker && attacker->inuse && attacker->client)
02530 {
02531 G_UseTargets2 (self, attacker, self->paintarget);
02532 }
02533 }
02534 else
02535 {
02536 G_UseTargets2 (self, self->activator, self->paintarget);
02537 }
02538 }
02539
02540 G_ActivateBehavior( self, BSET_PAIN );
02541
02542 if ( self->material == MAT_DRK_STONE
02543 || self->material == MAT_LT_STONE
02544 || self->material == MAT_GREY_STONE
02545 || self->material == MAT_SNOWY_ROCK )
02546 {
02547 vec3_t org, dir;
02548 float scale;
02549 int numChunks;
02550 VectorSubtract( self->r.absmax, self->r.absmin, org );// size
02551 // This formula really has no logical basis other than the fact that it seemed to be the closest to yielding the results that I wanted.
02552 // Volume is length * width * height...then break that volume down based on how many chunks we have
02553 scale = VectorLength( org ) / 100.0f;
02554 VectorMA( self->r.absmin, 0.5, org, org );
02555 VectorAdd( self->r.absmin,self->r.absmax, org );
02556 VectorScale( org, 0.5f, org );
02557 if ( attacker != NULL && attacker->client )
02558 {
02559 VectorSubtract( attacker->r.currentOrigin, org, dir );
02560 VectorNormalize( dir );
02561 }
02562 else
02563 {
02564 VectorSet( dir, 0, 0, 1 );
02565 }
02566 numChunks = Q_irand( 1, 3 );
02567 if ( self->radius > 0.0f )
02568 {
02569 // designer wants to scale number of chunks, helpful because the above scale code is far from perfect
02570 // I do this after the scale calculation because it seems that the chunk size generally seems to be very close, it's just the number of chunks is a bit weak
02571 numChunks = ceil(numChunks*self->radius);
02572 }
02573 G_Chunks( self->s.number, org, dir, self->r.absmin, self->r.absmax, 300, numChunks, self->material, 0, (scale*self->mass) );
02574 }
02575
02576 if ( self->wait == -1 )
02577 {
02578 self->pain = 0;
02579 return;
02580 }
02581
02582 self->painDebounceTime = level.time + self->wait;
02583 }
|
|
||||||||||||||||
|
Definition at line 2649 of file g_mover.c. References gentity_t. Referenced by SP_func_breakable().
02650 {
02651 }
|
|
||||||||||||||||
|
Definition at line 2502 of file g_mover.c. References BSET_USE, funcBBrushDie(), G_ActivateBehavior(), G_UseTargets(), gentity_t, gentity_s::health, MOD_UNKNOWN, gentity_s::spawnflags, and gentity_s::target. Referenced by SP_func_breakable().
02503 {
02504 G_ActivateBehavior( self, BSET_USE );
02505 if(self->spawnflags & 64)
02506 {//Using it doesn't break it, makes it use it's targets
02507 if(self->target && self->target[0])
02508 {
02509 G_UseTargets(self, activator);
02510 }
02511 }
02512 else
02513 {
02514 funcBBrushDie(self, other, activator, self->health, MOD_UNKNOWN);
02515 }
02516 }
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 2365 of file g_mover.c. References entityState_s::angles, entityState_s::angles2, entityState_s::apos, EV_DEBRIS, entityState_s::eventParm, G_TempEntity(), gentity_t, material_t, entityState_s::modelindex, entityState_s::origin, entityState_s::origin2, entityState_s::owner, gentity_s::s, entityState_s::speed, trajectory_t::trBase, entityState_s::trickedentindex, vec3_t, and VectorCopy. Referenced by funcBBrushDieGo(), and funcBBrushPain().
02367 {
02368 gentity_t *te = G_TempEntity( origin, EV_DEBRIS );
02369
02370 //Now it's time to cram everything horribly into the entitystate of an event entity.
02371 te->s.owner = owner;
02372 VectorCopy(origin, te->s.origin);
02373 VectorCopy(normal, te->s.angles);
02374 VectorCopy(maxs, te->s.origin2);
02375 VectorCopy(mins, te->s.angles2);
02376 te->s.speed = speed;
02377 te->s.eventParm = numChunks;
02378 te->s.trickedentindex = chunkType;
02379 te->s.modelindex = customChunk;
02380 te->s.apos.trBase[0] = baseScale;
02381 }
|
|
||||||||||||
|
Definition at line 118 of file g_mover.c. References AngleVectors(), and vec3_t. Referenced by G_TryPushingEntity().
00118 {
00119 AngleVectors(angles, matrix[0], matrix[1], matrix[2]);
00120 VectorInverse(matrix[1]);
00121 }
|
|
|
Definition at line 2817 of file g_mover.c. References gentity_s::classname, ENTITYNUM_WORLD, g_entities, gentity_t, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::r, SVF_GLASS_BRUSH, and entityShared_t::svFlags. Referenced by NAV_TestBestNode(), vmMain(), and WP_SaberRadiusDamage().
02818 {
02819 gentity_t *ent;
02820
02821 if ( entityNum < 0 || entityNum >= ENTITYNUM_WORLD )
02822 {
02823 return qfalse;
02824 }
02825
02826 ent = &g_entities[entityNum];
02827 if ( (ent->r.svFlags & SVF_GLASS_BRUSH) )
02828 {
02829 return qtrue;
02830 }
02831 /*
02832 if ( (ent->svFlags&SVF_BBRUSH) )
02833 {
02834 return qtrue;
02835 }
02836 */
02837 if ( !Q_stricmp( "func_breakable", ent->classname ) )
02838 {
02839 return qtrue;
02840 }
02841
02842 if ( !Q_stricmp( "misc_model_breakable", ent->classname ) )
02843 {
02844 return qtrue;
02845 }
02846 if ( !Q_stricmp( "misc_maglock", ent->classname ) )
02847 {
02848 return qtrue;
02849 }
02850
02851 return qfalse;
02852 }
|
|
|
Definition at line 1212 of file g_mover.c. References gentity_s::classname, ENTITYNUM_WORLD, g_entities, gentity_t, Q_stricmp(), qboolean, qfalse, and qtrue. Referenced by G_EntIsUnlockedDoor(), NAV_TestBestNode(), and vmMain().
01213 {
01214 gentity_t *ent;
01215
01216 if ( entityNum < 0 || entityNum >= ENTITYNUM_WORLD )
01217 {
01218 return qfalse;
01219 }
01220
01221 ent = &g_entities[entityNum];
01222 if ( ent && !Q_stricmp( "func_door", ent->classname ) )
01223 {//blocked by a door
01224 return qtrue;
01225 }
01226 return qfalse;
01227 }
|
|
|
Definition at line 3023 of file g_mover.c. References gentity_s::classname, EF_SHADER_ANIM, entityState_s::eFlags, g_entities, gentity_t, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::s, gentity_s::spawnflags, and gentity_s::targetname. Referenced by NAV_TestBestNode(), and vmMain().
03024 {
03025 gentity_t *ent = &g_entities[entNum];
03026 if ( ent->classname && !Q_stricmp( "func_usable", ent->classname ) )
03027 {
03028 if ( !(ent->s.eFlags&EF_SHADER_ANIM) && !(ent->spawnflags&8) && ent->targetname )
03029 {//not just a shader-animator and not ALWAYS_ON, so it must be removable somehow
03030 return qtrue;
03031 }
03032 }
03033 return qfalse;
03034 }
|
|
|
Definition at line 1272 of file g_mover.c. References gentity_s::classname, ENTITYNUM_WORLD, FL_INACTIVE, FL_TEAMSLAVE, gentity_s::flags, FOFS, G_EntIsDoor(), g_entities, G_Find(), G_FindDoorTrigger(), gentity_t, gentity_s::health, MOVER_FORCE_ACTIVATE, MOVER_LOCKED, MOVER_PLAYER_USE, NULL, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::spawnflags, gentity_s::targetname, and gentity_s::teammaster. Referenced by NAV_CheckAhead(), NAV_ResolveEntityCollision(), NAV_TestBestNode(), and vmMain().
01273 {
01274 if ( entityNum < 0 || entityNum >= ENTITYNUM_WORLD )
01275 {
01276 return qfalse;
01277 }
01278
01279 if ( G_EntIsDoor( entityNum ) )
01280 {
01281 gentity_t *ent = &g_entities[entityNum];
01282 gentity_t *owner = NULL;
01283 if ( ent->flags & FL_TEAMSLAVE )
01284 {//not the master door, get the master door
01285 while ( ent->teammaster && (ent->flags&FL_TEAMSLAVE))
01286 {
01287 ent = ent->teammaster;
01288 }
01289 }
01290 if ( ent->targetname )
01291 {//find out what is targetting it
01292 owner = NULL;
01293 //FIXME: if ent->targetname, check what kind of trigger/ent is targetting it? If a normal trigger (active, etc), then it's okay?
01294 while ( (owner = G_Find( owner, FOFS( target ), ent->targetname )) != NULL )
01295 {
01296 if ( !Q_stricmp( "trigger_multiple", owner->classname ) )//FIXME: other triggers okay too?
01297 {
01298 if ( !(owner->flags & FL_INACTIVE) )
01299 {
01300 return qtrue;
01301 }
01302 }
01303 }
01304 owner = NULL;
01305 while ( (owner = G_Find( owner, FOFS( target2 ), ent->targetname )) != NULL )
01306 {
01307 if ( !Q_stricmp( "trigger_multiple", owner->classname ) )//FIXME: other triggers okay too?
01308 {
01309 if ( !(owner->flags & FL_INACTIVE) )
01310 {
01311 return qtrue;
01312 }
01313 }
01314 }
01315 return qfalse;
01316 }
01317 else
01318 {//check the door's auto-created trigger instead
01319 owner = G_FindDoorTrigger( ent );
01320 if ( owner && (owner->flags&FL_INACTIVE) )
01321 {//owning auto-created trigger is inactive
01322 return qfalse;
01323 }
01324 }
01325 if ( !(ent->flags & FL_INACTIVE) && //assumes that the reactivate trigger isn't right next to the door!
01326 !ent->health &&
01327 !(ent->spawnflags & MOVER_PLAYER_USE) &&
01328 !(ent->spawnflags & MOVER_FORCE_ACTIVATE) &&
01329 !(ent->spawnflags & MOVER_LOCKED))
01330 //FIXME: what about MOVER_GOODIE?
01331 {
01332 return qtrue;
01333 }
01334 }
01335 return qfalse;
01336 }
|
|
|
Definition at line 215 of file g_missile.c.
00215 {
00216 vec3_t dir;
00217 vec3_t origin;
00218
00219 BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
00220 SnapVector( origin );
00221 G_SetOrigin( ent, origin );
00222
00223 // we don't have a valid direction, so just point straight up
00224 dir[0] = dir[1] = 0;
00225 dir[2] = 1;
00226
00227 ent->s.eType = ET_GENERAL;
00228 G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) );
00229
00230 ent->freeAfterEvent = qtrue;
00231
00232 ent->takedamage = qfalse;
00233 // splash damage
00234 if ( ent->splashDamage ) {
00235 if( G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent,
00236 ent, ent->splashMethodOfDeath ) )
00237 {
00238 if (ent->parent)
00239 {
00240 g_entities[ent->parent->s.number].client->accuracy_hits++;
00241 }
00242 else if (ent->activator)
00243 {
00244 g_entities[ent->activator->s.number].client->accuracy_hits++;
00245 }
00246 }
00247 }
00248
00249 trap_LinkEntity( ent );
00250 }
|
|
|
Definition at line 1229 of file g_mover.c. References entityShared_t::contents, CONTENTS_TRIGGER, FL_TEAMSLAVE, gentity_s::flags, FOFS, G_Find(), gentity_t, NULL, gentity_s::parent, gentity_s::r, gentity_s::targetname, and gentity_s::teammaster. Referenced by G_EntIsUnlockedDoor(), and maglock_link().
01230 {
01231 gentity_t *owner = NULL;
01232 gentity_t *door = ent;
01233 if ( door->flags & FL_TEAMSLAVE )
01234 {//not the master door, get the master door
01235 while ( door->teammaster && (door->flags&FL_TEAMSLAVE))
01236 {
01237 door = door->teammaster;
01238 }
01239 }
01240 if ( door->targetname )
01241 {//find out what is targeting it
01242 //FIXME: if ent->targetname, check what kind of trigger/ent is targetting it? If a normal trigger (active, etc), then it's okay?
01243 while ( (owner = G_Find( owner, FOFS( target ), door->targetname )) != NULL )
01244 {
01245 if ( owner && (owner->r.contents&CONTENTS_TRIGGER) )
01246 {
01247 return owner;
01248 }
01249 }
01250 owner = NULL;
01251 while ( (owner = G_Find( owner, FOFS( target2 ), door->targetname )) != NULL )
01252 {
01253 if ( owner && (owner->r.contents&CONTENTS_TRIGGER) )
01254 {
01255 return owner;
01256 }
01257 }
01258 }
01259
01260 owner = NULL;
01261 while ( (owner = G_Find( owner, FOFS( classname ), "trigger_door" )) != NULL )
01262 {
01263 if ( owner->parent == door )
01264 {
01265 return owner;
01266 }
01267 }
01268
01269 return NULL;
01270 }
|
|
||||||||||||||||||||
|
Definition at line 2349 of file g_mover.c. References entityState_s::angles2, EV_MISC_MODEL_EXP, entityState_s::eventParm, G_TempEntity(), gentity_t, material_t, entityState_s::origin2, gentity_s::s, entityState_s::time, vec3_t, VectorAdd, VectorCopy, and VectorScale. Referenced by funcBBrushDieGo().
02350 {
02351 gentity_t *te;
02352 vec3_t mid;
02353
02354 VectorAdd( mins, maxs, mid );
02355 VectorScale( mid, 0.5f, mid );
02356
02357 te = G_TempEntity( mid, EV_MISC_MODEL_EXP );
02358
02359 VectorCopy(maxs, te->s.origin2);
02360 VectorCopy(mins, te->s.angles2);
02361 te->s.time = size;
02362 te->s.eventParm = chunkType;
02363 }
|
|
||||||||||||||||||||
|
Definition at line 273 of file g_mover.c. References entityShared_t::absmax, entityShared_t::absmin, pushed_t::angles, entityState_s::apos, gentity_s::client, entityShared_t::currentAngles, entityShared_t::currentOrigin, gentity_s::damage, playerState_s::delta_angles, pushed_t::deltayaw, pushed_t::ent, ET_BODY, ET_NPC, ET_PLAYER, entityState_s::eType, G_Damage(), g_entities, G_TestEntityPosition(), G_TryPushingEntity(), gentity_t, entityState_s::groundEntityNum, gentity_s::health, MAX_GENTITIES, entityShared_t::maxs, entityShared_t::mins, MOD_CRUSH, NULL, entityState_s::number, playerState_s::origin, pushed_t::origin, gentity_s::physicsObject, entityState_s::pos, gclient_s::ps, pushed, pushed_p, qboolean, qfalse, qtrue, gentity_s::r, RadiusFromBounds(), gentity_s::s, gentity_s::spawnflags, TR_SINE, trap_EntitiesInBox(), trap_LinkEntity(), trap_UnlinkEntity(), trajectory_t::trBase, trajectory_t::trType, vec3_t, VectorAdd, VectorCopy, and YAW. Referenced by G_MoverTeam().
00273 {
00274 int i, e;
00275 gentity_t *check;
00276 vec3_t mins, maxs;
00277 pushed_t *p;
00278 int entityList[MAX_GENTITIES];
00279 int listedEntities;
00280 vec3_t totalMins, totalMaxs;
00281
00282 *obstacle = NULL;
00283
00284
00285 // mins/maxs are the bounds at the destination
00286 // totalMins / totalMaxs are the bounds for the entire move
00287 if ( pusher->r.currentAngles[0] || pusher->r.currentAngles[1] || pusher->r.currentAngles[2]
00288 || amove[0] || amove[1] || amove[2] ) {
00289 float radius;
00290
00291 radius = RadiusFromBounds( pusher->r.mins, pusher->r.maxs );
00292 for ( i = 0 ; i < 3 ; i++ ) {
00293 mins[i] = pusher->r.currentOrigin[i] + move[i] - radius;
00294 maxs[i] = pusher->r.currentOrigin[i] + move[i] + radius;
00295 totalMins[i] = mins[i] - move[i];
00296 totalMaxs[i] = maxs[i] - move[i];
00297 }
00298 } else {
00299 for (i=0 ; i<3 ; i++) {
00300 mins[i] = pusher->r.absmin[i] + move[i];
00301 maxs[i] = pusher->r.absmax[i] + move[i];
00302 }
00303
00304 VectorCopy( pusher->r.absmin, totalMins );
00305 VectorCopy( pusher->r.absmax, totalMaxs );
00306 for (i=0 ; i<3 ; i++) {
00307 if ( move[i] > 0 ) {
00308 totalMaxs[i] += move[i];
00309 } else {
00310 totalMins[i] += move[i];
00311 }
00312 }
00313 }
00314
00315 // unlink the pusher so we don't get it in the entityList
00316 trap_UnlinkEntity( pusher );
00317
00318 listedEntities = trap_EntitiesInBox( totalMins, totalMaxs, entityList, MAX_GENTITIES );
00319
00320 // move the pusher to it's final position
00321 VectorAdd( pusher->r.currentOrigin, move, pusher->r.currentOrigin );
00322 VectorAdd( pusher->r.currentAngles, amove, pusher->r.currentAngles );
00323 trap_LinkEntity( pusher );
00324
00325 // see if any solid entities are inside the final position
00326 for ( e = 0 ; e < listedEntities ; e++ ) {
00327 check = &g_entities[ entityList[ e ] ];
00328
00329 // only push items and players
00330 if ( /*check->s.eType != ET_ITEM &&*/ check->s.eType != ET_PLAYER && check->s.eType != ET_NPC && !check->physicsObject ) {
00331 continue;
00332 }
00333
00334 // if the entity is standing on the pusher, it will definitely be moved
00335 if ( check->s.groundEntityNum != pusher->s.number ) {
00336 // see if the ent needs to be tested
00337 if ( check->r.absmin[0] >= maxs[0]
00338 || check->r.absmin[1] >= maxs[1]
00339 || check->r.absmin[2] >= maxs[2]
00340 || check->r.absmax[0] <= mins[0]
00341 || check->r.absmax[1] <= mins[1]
00342 || check->r.absmax[2] <= mins[2] ) {
00343 continue;
00344 }
00345 // see if the ent's bbox is inside the pusher's final position
00346 // this does allow a fast moving object to pass through a thin entity...
00347 if (!G_TestEntityPosition (check)) {
00348 continue;
00349 }
00350 }
00351
00352 // the entity needs to be pushed
00353 if ( G_TryPushingEntity( check, pusher, move, amove ) ) {
00354 continue;
00355 }
00356
00357 if (pusher->damage && check->client && (pusher->spawnflags & 32))
00358 {
00359 G_Damage( check, pusher, pusher, NULL, NULL, pusher->damage, 0, MOD_CRUSH );
00360 continue;
00361 }
00362
00363 if (check->s.eType == ET_BODY ||
00364 (check->s.eType == ET_PLAYER && check->health < 1))
00365 { //whatever, just crush it
00366 G_Damage( check, pusher, pusher, NULL, NULL, 999, 0, MOD_CRUSH );
00367 continue;
00368 }
00369
00370 // the move was blocked an entity
00371
00372 // bobbing entities are instant-kill and never get blocked
00373 if ( pusher->s.pos.trType == TR_SINE || pusher->s.apos.trType == TR_SINE ) {
00374 G_Damage( check, pusher, pusher, NULL, NULL, 99999, 0, MOD_CRUSH );
00375 continue;
00376 }
00377
00378
00379 // save off the obstacle so we can call the block function (crush, etc)
00380 *obstacle = check;
00381
00382 // move back any entities we already moved
00383 // go backwards, so if the same entity was pushed
00384 // twice, it goes back to the original position
00385 for ( p=pushed_p-1 ; p>=pushed ; p-- ) {
00386 VectorCopy (p->origin, p->ent->s.pos.trBase);
00387 VectorCopy (p->angles, p->ent->s.apos.trBase);
00388 if ( p->ent->client ) {
00389 p->ent->client->ps.delta_angles[YAW] = p->deltayaw;
00390 VectorCopy (p->origin, p->ent->client->ps.origin);
00391 }
00392 trap_LinkEntity (p->ent);
00393 }
00394 return qfalse;
00395 }
00396
00397 return qtrue;
00398 }
|
|
|
Definition at line 406 of file g_mover.c. References entityState_s::apos, BG_EvaluateTrajectory(), entityShared_t::currentAngles, entityShared_t::currentOrigin, G_MoverPush(), gentity_t, level, NULL, entityState_s::pos, level_locals_t::previousTime, pushed, pushed_p, gentity_s::r, gentity_s::reached, gentity_s::s, gentity_s::teamchain, level_locals_t::time, TR_LINEAR_STOP, TR_NONLINEAR_STOP, trap_LinkEntity(), trajectory_t::trDuration, trajectory_t::trTime, trajectory_t::trType, vec3_origin, vec3_t, and VectorSubtract. Referenced by G_RunMover().
00406 {
00407 vec3_t move, amove;
00408 gentity_t *part, *obstacle;
00409 vec3_t origin, angles;
00410
00411 obstacle = NULL;
00412
00413 // make sure all team slaves can move before commiting
00414 // any moves or calling any think functions
00415 // if the move is blocked, all moved objects will be backed out
00416 pushed_p = pushed;
00417 for (part = ent ; part ; part=part->teamchain) {
00418 // get current position
00419 BG_EvaluateTrajectory( &part->s.pos, level.time, origin );
00420 BG_EvaluateTrajectory( &part->s.apos, level.time, angles );
00421 VectorSubtract( origin, part->r.currentOrigin, move );
00422 VectorSubtract( angles, part->r.currentAngles, amove );
00423 if ( !VectorCompare( move, vec3_origin )
00424 || !VectorCompare( amove, vec3_origin ) )
00425 {//actually moved
00426 if ( !G_MoverPush( part, move, amove, &obstacle ) ) {
00427 break; // move was blocked
00428 }
00429 }
00430 }
00431
00432 if (part) {
00433 // go back to the previous position
00434 for ( part = ent ; part ; part = part->teamchain ) {
00435 part->s.pos.trTime += level.time - level.previousTime;
00436 part->s.apos.trTime += level.time - level.previousTime;
00437 BG_EvaluateTrajectory( &part->s.pos, level.time, part->r.currentOrigin );
00438 BG_EvaluateTrajectory( &part->s.apos, level.time, part->r.currentAngles );
00439 trap_LinkEntity( part );
00440 }
00441
00442 // if the pusher has a "blocked" function, call it
00443 if (ent->blocked) {
00444 ent->blocked( ent, obstacle );
00445 }
00446 return;
00447 }
00448
00449 // the move succeeded
00450 for ( part = ent ; part ; part = part->teamchain ) {
00451 // call the reached function if time is at or past end point
00452 if ( part->s.pos.trType == TR_LINEAR_STOP ||
00453 part->s.pos.trType == TR_NONLINEAR_STOP) {
00454 if ( level.time >= part->s.pos.trTime + part->s.pos.trDuration ) {
00455 if ( part->reached ) {
00456 part->reached( part );
00457 }
00458 }
00459 }
00460 }
00461 }
|
|
|
Definition at line 45 of file g_mover.c. References BMS_MID, G_SoundSetIndex(), gentity_t, entityState_s::loopIsSoundset, entityState_s::loopSound, qtrue, gentity_s::s, gentity_s::soundSet, and entityState_s::soundSetIndex. Referenced by Q3_Lerp2End(), Q3_Lerp2Origin(), Q3_Lerp2Pos(), Q3_Lerp2Start(), Reached_Train(), ReturnToPos1(), Think_BeginMoving(), and Use_BinaryMover_Go().
00046 {
00047 if (!ent->soundSet || !ent->soundSet[0])
00048 {
00049 return;
00050 }
00051
00052 ent->s.soundSetIndex = G_SoundSetIndex(ent->soundSet);
00053 ent->s.loopIsSoundset = qtrue;
00054 ent->s.loopSound = BMS_MID;
00055 /*
00056 ent->s.soundSetIndex = G_SoundSetIndex(ent->soundSet);
00057 ent->loopingOnClient = qtrue;
00058 G_AddEvent(ent, EV_PLAYDOORLOOPSOUND, 0);
00059 */
00060 }
|
|
||||||||||||
|
Definition at line 68 of file g_mover.c. References EV_PLAYDOORSOUND, G_AddEvent(), G_SoundSetIndex(), gentity_t, gentity_s::s, gentity_s::soundSet, and entityState_s::soundSetIndex. Referenced by moverCallback(), Q3_Lerp2End(), Q3_Lerp2Origin(), Q3_Lerp2Pos(), Q3_Lerp2Start(), Reached_BinaryMover(), Reached_Train(), ReturnToPos1(), Think_BeginMoving(), and Use_BinaryMover_Go().
00069 {
00070 if (!ent->soundSet || !ent->soundSet[0])
00071 {
00072 return;
00073 }
00074
00075 ent->s.soundSetIndex = G_SoundSetIndex(ent->soundSet);
00076
00077 G_AddEvent(ent, EV_PLAYDOORSOUND, type);
00078 }
|
|
||||||||||||
|
Definition at line 142 of file g_mover.c. References DotProduct, vec3_t, and VectorCopy. Referenced by G_TryPushingEntity().
00142 {
00143 vec3_t tvec;
00144
00145 VectorCopy(point, tvec);
00146 point[0] = DotProduct(matrix[0], tvec);
00147 point[1] = DotProduct(matrix[1], tvec);
00148 point[2] = DotProduct(matrix[2], tvec);
00149 }
|
|
|
Definition at line 469 of file g_mover.c. References entityState_s::apos, FL_TEAMSLAVE, gentity_s::flags, G_MoverTeam(), G_RunThink(), gentity_t, entityState_s::pos, gentity_s::s, TR_STATIONARY, and trajectory_t::trType. Referenced by G_RunFrame().
00469 {
00470 // if not a team captain, don't do anything, because
00471 // the captain will handle everything
00472 if ( ent->flags & FL_TEAMSLAVE ) {
00473 return;
00474 }
00475
00476 // if stationary at one of the positions, don't move anything
00477 if ( ent->s.pos.trType != TR_STATIONARY || ent->s.apos.trType != TR_STATIONARY ) {
00478 G_MoverTeam( ent );
00479 }
00480
00481 // check think function
00482 G_RunThink( ent );
00483 }
|
|
|
Definition at line 86 of file g_mover.c. References gentity_s::client, gentity_s::clipmask, trace_t::entityNum, g_entities, gentity_t, MASK_SOLID, entityShared_t::maxs, entityShared_t::mins, NULL, entityState_s::number, playerState_s::origin, entityState_s::pos, gclient_s::ps, gentity_s::r, gentity_s::s, trace_t::startsolid, trap_Trace(), trajectory_t::trBase, vec3_t, and VectorCopy. Referenced by func_wait_return_solid(), G_MoverPush(), and G_TryPushingEntity().
00086 {
00087 trace_t tr;
00088 int mask;
00089
00090 if ( ent->clipmask ) {
00091 mask = ent->clipmask;
00092 } else {
00093 mask = MASK_SOLID;
00094 }
00095 if ( ent->client ) {
00096 vec3_t vMax;
00097 VectorCopy(ent->r.maxs, vMax);
00098 if (vMax[2] < 1)
00099 {
00100 vMax[2] = 1;
00101 }
00102 trap_Trace( &tr, ent->client->ps.origin, ent->r.mins, vMax, ent->client->ps.origin, ent->s.number, mask );
00103 } else {
00104 trap_Trace( &tr, ent->s.pos.trBase, ent->r.mins, ent->r.maxs, ent->s.pos.trBase, ent->s.number, mask );
00105 }
00106
00107 if (tr.startsolid)
00108 return &g_entities[ tr.entityNum ];
00109
00110 return NULL;
00111 }
|
|
||||||||||||
|
Definition at line 128 of file g_mover.c. References vec3_t. Referenced by G_TryPushingEntity().
00128 {
00129 int i, j;
00130 for (i = 0; i < 3; i++) {
00131 for (j = 0; j < 3; j++) {
00132 transpose[i][j] = matrix[j][i];
00133 }
00134 }
00135 }
|
|
||||||||||||||||||||
|
Definition at line 158 of file g_mover.c. References ANGLE2SHORT, pushed_t::angles, entityState_s::apos, gentity_s::classname, gentity_s::client, entityShared_t::currentOrigin, gentity_s::damage, DAMAGE_NO_KNOCKBACK, playerState_s::delta_angles, pushed_t::deltayaw, pushed_t::ent, ENTITYNUM_NONE, G_CreateRotationMatrix(), G_Damage(), G_Error(), G_RotatePoint(), G_TestEntityPosition(), G_TransposeMatrix(), gentity_t, entityState_s::groundEntityNum, gentity_s::health, MAX_CLIENTS, MAX_GENTITIES, MOD_CRUSH, MOD_UNKNOWN, NULL, entityState_s::number, playerState_s::origin, pushed_t::origin, entityShared_t::ownerNum, entityState_s::pos, gclient_s::ps, pushed, pushed_p, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, gentity_s::spawnflags, gentity_s::takedamage, TR_STATIONARY, trap_LinkEntity(), trajectory_t::trBase, trajectory_t::trType, vec3_origin, vec3_t, VectorAdd, VectorCopy, VectorSubtract, entityState_s::weapon, and YAW. Referenced by G_MoverPush().
00158 {
00159 vec3_t matrix[3], transpose[3];
00160 vec3_t org, org2, move2;
00161 gentity_t *block;
00162
00163 //This was only serverside not to mention it was never set.
00164 /*
00165 // EF_MOVER_STOP will just stop when contacting another entity
00166 // instead of pushing it, but entities can still ride on top of it
00167 if ( ( pusher->s.eFlags & EF_MOVER_STOP ) &&
00168 check->s.groundEntityNum != pusher->s.number ) {
00169 return qfalse;
00170 }
00171 */
00172 if ( pusher->s.apos.trType != TR_STATIONARY//rotating
00173 && (pusher->spawnflags&16) //IMPACT
00174 && Q_stricmp( "func_rotating", pusher->classname ) == 0 )
00175 {//just blow the fuck out of them
00176 G_Damage( check, pusher, pusher, NULL, NULL, pusher->damage, DAMAGE_NO_KNOCKBACK, MOD_CRUSH );
00177 return qtrue;
00178 }
00179
00180 // save off the old position
00181 if (pushed_p > &pushed[MAX_GENTITIES]) {
00182 G_Error( "pushed_p > &pushed[MAX_GENTITIES]" );
00183 }
00184 pushed_p->ent = check;
00185 VectorCopy (check->s.pos.trBase, pushed_p->origin);
00186 VectorCopy (check->s.apos.trBase, pushed_p->angles);
00187 if ( check->client ) {
00188 pushed_p->deltayaw = check->client->ps.delta_angles[YAW];
00189 VectorCopy (check->client->ps.origin, pushed_p->origin);
00190 }
00191 pushed_p++;
00192
00193 // try moving the contacted entity
00194 // figure movement due to the pusher's amove
00195 G_CreateRotationMatrix( amove, transpose );
00196 G_TransposeMatrix( transpose, matrix );
00197 if ( check->client ) {
00198 VectorSubtract (check->client->ps.origin, pusher->r.currentOrigin, org);
00199 }
00200 else {
00201 VectorSubtract (check->s.pos.trBase, pusher->r.currentOrigin, org);
00202 }
00203 VectorCopy( org, org2 );
00204 G_RotatePoint( org2, matrix );
00205 VectorSubtract (org2, org, move2);
00206 // add movement
00207 VectorAdd (check->s.pos.trBase, move, check->s.pos.trBase);
00208 VectorAdd (check->s.pos.trBase, move2, check->s.pos.trBase);
00209 if ( check->client ) {
00210 VectorAdd (check->client->ps.origin, move, check->client->ps.origin);
00211 VectorAdd (check->client->ps.origin, move2, check->client->ps.origin);
00212 // make sure the client's view rotates when on a rotating mover
00213 check->client->ps.delta_angles[YAW] += ANGLE2SHORT(amove[YAW]);
00214 }
00215
00216 // may have pushed them off an edge
00217 if ( check->s.groundEntityNum != pusher->s.number ) {
00218 check->s.groundEntityNum = ENTITYNUM_NONE;//-1;
00219 }
00220
00221 block = G_TestEntityPosition( check );
00222 if (!block) {
00223 // pushed ok
00224 if ( check->client ) {
00225 VectorCopy( check->client->ps.origin, check->r.currentOrigin );
00226 } else {
00227 VectorCopy( check->s.pos.trBase, check->r.currentOrigin );
00228 }
00229 trap_LinkEntity (check);
00230 return qtrue;
00231 }
00232
00233 if (check->takedamage && !check->client && check->s.weapon && check->r.ownerNum < MAX_CLIENTS &&
00234 check->health < 500)
00235 {
00236 if (check->health > 0)
00237 {
00238 G_Damage(check, pusher, pusher, vec3_origin, check->r.currentOrigin, 999, 0, MOD_UNKNOWN);
00239 }
00240 return qfalse;
00241 }
00242 // if it is ok to leave in the old position, do it
00243 // this is only relevent for riding entities, not pushed
00244 // Sliding trapdoors can cause this.
00245 VectorCopy( (pushed_p-1)->origin, check->s.pos.trBase);
00246 if ( check->client ) {
00247 VectorCopy( (pushed_p-1)->origin, check->client->ps.origin);
00248 }
00249 VectorCopy( (pushed_p-1)->angles, check->s.apos.trBase );
00250 block = G_TestEntityPosition (check);
00251 if ( !block ) {
00252 check->s.groundEntityNum = -1;
00253 pushed_p--;
00254 return qtrue;
00255 }
00256
00257 // blocked
00258 return qfalse;
00259 }
|
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
Definition at line 2891 of file g_mover.c. References entityShared_t::absmax, entityShared_t::absmin, entityState_s::angles, EV_GLASS_SHATTER, G_FreeEntity(), G_TempEntity(), G_UseTargets(), entityState_s::genericenemyindex, gentity_t, entityShared_t::maxs, entityShared_t::mins, entityState_s::number, entityState_s::origin, gentity_s::r, gentity_s::s, vec3_t, and VectorCopy.
02892 {
02893 gentity_t *te;
02894 vec3_t dif;
02895
02896 dif[0] = (self->r.absmax[0]+self->r.absmin[0])/2;
02897 dif[1] = (self->r.absmax[1]+self->r.absmin[1])/2;
02898 dif[2] = (self->r.absmax[2]+self->r.absmin[2])/2;
02899
02900 G_UseTargets(self, attacker);
02901
02902 te = G_TempEntity( dif, EV_GLASS_SHATTER );
02903 te->s.genericenemyindex = self->s.number;
02904 VectorCopy(self->r.maxs, te->s.origin);
02905 VectorCopy(self->r.mins, te->s.angles);
02906
02907 G_FreeEntity(self);
02908 }
|
|
||||||||||||||||
|
Definition at line 2910 of file g_mover.c. References gentity_t. Referenced by SP_func_glass().
02911 {
02912 //G_Printf("Mr. Glass says: PLZ NO IT HURTS\n");
02913 //Make "cracking" sound?
02914 }
|
|
||||||||||||||||
|
Definition at line 2916 of file g_mover.c. References gentity_t, GlassDie(), entityShared_t::maxs, entityShared_t::mins, MOD_UNKNOWN, gentity_s::pos1, gentity_s::pos2, gentity_s::r, vec3_t, VectorAdd, VectorCopy, VectorNormalize(), VectorScale, and VectorSubtract. Referenced by SP_func_glass().
02917 {
02918 vec3_t temp1, temp2;
02919
02920 //no direct object to blame for the break, so fill the values with whatever
02921 VectorAdd( self->r.mins, self->r.maxs, temp1 );
02922 VectorScale( temp1, 0.5f, temp1 );
02923
02924 VectorAdd( other->r.mins, other->r.maxs, temp2 );
02925 VectorScale( temp2, 0.5f, temp2 );
02926
02927 VectorSubtract( temp1, temp2, self->pos2 );
02928 VectorCopy( temp1, self->pos1 );
02929
02930 VectorNormalize( self->pos2 );
02931 VectorScale( self->pos2, 390, self->pos2 );
02932
02933 GlassDie(self, other, activator, 100, MOD_UNKNOWN);
02934 }
|
|
|
Definition at line 926 of file g_mover.c. References entityState_s::constantLight, entityShared_t::currentOrigin, ET_MOVER, entityState_s::eType, FL_INACTIVE, gentity_s::flags, G_ModelIndex(), G_SpawnFloat(), G_SpawnVector(), gentity_t, InitMoverTrData(), gentity_s::model2, entityState_s::modelindex2, MOVER_INACTIVE, MOVER_PLAYER_USE, MOVER_POS1, gentity_s::moverState, gentity_s::pos1, qboolean, gentity_s::r, gentity_s::reached, Reached_BinaryMover(), gentity_s::s, gentity_s::spawnflags, strstr(), SVF_PLAYER_USABLE, SVF_USE_CURRENT_ORIGIN, entityShared_t::svFlags, trap_LinkEntity(), gentity_s::use, Use_BinaryMover(), vec3_t, and VectorCopy. Referenced by func_wait_return_solid(), SP_func_bobbing(), SP_func_button(), SP_func_door(), SP_func_glass(), SP_func_pendulum(), SP_func_plat(), SP_func_rotating(), SP_func_static(), SP_func_train(), SP_func_usable(), and SP_func_wall().
00927 {
00928 float light;
00929 vec3_t color;
00930 qboolean lightSet, colorSet;
00931
00932 // if the "model2" key is set, use a seperate model
00933 // for drawing, but clip against the brushes
00934 if ( ent->model2 )
00935 {
00936 if ( strstr( ent->model2, ".glm" ))
00937 { //for now, not supported in MP.
00938 ent->s.modelindex2 = 0;
00939 }
00940 else
00941 {
00942 ent->s.modelindex2 = G_ModelIndex( ent->model2 );
00943 }
00944 }
00945
00946 // if the "color" or "light" keys are set, setup constantLight
00947 lightSet = G_SpawnFloat( "light", "100", &light );
00948 colorSet = G_SpawnVector( "color", "1 1 1", color );
00949 if ( lightSet || colorSet ) {
00950 int r, g, b, i;
00951
00952 r = color[0] * 255;
00953 if ( r > 255 ) {
00954 r = 255;
00955 }
00956 g = color[1] * 255;
00957 if ( g > 255 ) {
00958 g = 255;
00959 }
00960 b = color[2] * 255;
00961 if ( b > 255 ) {
00962 b = 255;
00963 }
00964 i = light / 4;
00965 if ( i > 255 ) {
00966 i = 255;
00967 }
00968 ent->s.constantLight = r | ( g << 8 ) | ( b << 16 ) | ( i << 24 );
00969 }
00970
00971 ent->use = Use_BinaryMover;
00972 ent->reached = Reached_BinaryMover;
00973
00974 ent->moverState = MOVER_POS1;
00975 ent->r.svFlags = SVF_USE_CURRENT_ORIGIN;
00976 if ( ent->spawnflags & MOVER_INACTIVE )
00977 {// Make it inactive
00978 ent->flags |= FL_INACTIVE;
00979 }
00980 if(ent->spawnflags & MOVER_PLAYER_USE)
00981 {//Can be used by the player's BUTTON_USE
00982 ent->r.svFlags |= SVF_PLAYER_USABLE;
00983 }
00984 ent->s.eType = ET_MOVER;
00985 VectorCopy( ent->pos1, ent->r.currentOrigin );
00986 trap_LinkEntity( ent );
00987
00988 InitMoverTrData( ent );
00989 }
|
|
|
Definition at line 903 of file g_mover.c. References gentity_t, entityState_s::pos, gentity_s::pos1, gentity_s::pos2, gentity_s::s, gentity_s::speed, TR_STATIONARY, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trDuration, trajectory_t::trType, vec3_t, VectorCopy, VectorScale, and VectorSubtract. Referenced by InitMover(), Q3_Lerp2Origin(), and Q3_Lerp2Pos().
00904 {
00905 vec3_t move;
00906 float distance;
00907
00908 ent->s.pos.trType = TR_STATIONARY;
00909 VectorCopy( ent->pos1, ent->s.pos.trBase );
00910
00911 // calculate time to reach second position from speed
00912 VectorSubtract( ent->pos2, ent->pos1, move );
00913 distance = VectorLength( move );
00914 if ( ! ent->speed )
00915 {
00916 ent->speed = 100;
00917 }
00918 VectorScale( move, ent->speed, ent->s.pos.trDelta );
00919 ent->s.pos.trDuration = distance * 1000 / ent->speed;
00920 if ( ent->s.pos.trDuration <= 0 )
00921 {
00922 ent->s.pos.trDuration = 1;
00923 }
00924 }
|
|
|
Definition at line 836 of file g_mover.c. References entityState_s::frame, gentity_t, MOVER_LOCKED, gentity_s::s, gentity_s::spawnflags, and gentity_s::teamchain. Referenced by Q3_Set().
00837 {
00838 //noise?
00839 //go through and lock the door and all the slaves
00840 gentity_t *slave = ent;
00841 do
00842 {
00843 slave->spawnflags |= MOVER_LOCKED;
00844 slave->s.frame = 0;//first stage of anim
00845 slave = slave->teamchain;
00846 } while ( slave );
00847 }
|
|
||||||||||||||||
|
Referenced by moverCallback(), Q3_Lerp2Origin(), Q3_Lerp2Pos(), ReturnToPos1(), Think_MatchTeam(), Think_SpawnNewDoorTrigger(), and Use_BinaryMover_Go(). |
|
|
Definition at line 624 of file g_mover.c. References gentity_s::activator, BMS_END, CalcTeamDoorCenter(), gentity_s::closetarget, G_Error(), G_PlayDoorSound(), G_UseTargets2(), gentity_t, level, entityState_s::loopIsSoundset, entityState_s::loopSound, MOVER_1TO2, MOVER_2TO1, MOVER_POS1, MOVER_POS2, gentity_s::moverState, gentity_s::nextthink, gentity_s::opentarget, qfalse, ReturnToPos1(), gentity_s::s, SetMoverState(), gentity_s::spawnflags, gentity_s::teammaster, gentity_s::think, level_locals_t::time, trap_AdjustAreaPortalState(), gentity_s::use, vec3_t, and gentity_s::wait. Referenced by InitMover().
00625 {
00626 // stop the looping sound
00627 ent->s.loopSound = 0;
00628 ent->s.loopIsSoundset = qfalse;
00629
00630 if ( ent->moverState == MOVER_1TO2 )
00631 {//reached open
00632 vec3_t doorcenter;
00633
00634 // reached pos2
00635 SetMoverState( ent, MOVER_POS2, level.time );
00636
00637 CalcTeamDoorCenter( ent, doorcenter );
00638
00639 // play sound
00640 G_PlayDoorSound( ent, BMS_END );
00641
00642 if ( ent->wait < 0 )
00643 {//Done for good
00644 ent->think = 0;
00645 ent->nextthink = 0;
00646 ent->use = 0;
00647 }
00648 else
00649 {
00650 // return to pos1 after a delay
00651 ent->think = ReturnToPos1;
00652 if(ent->spawnflags & 8)
00653 {//Toggle, keep think, wait for next use?
00654 ent->nextthink = -1;
00655 }
00656 else
00657 {
00658 ent->nextthink = level.time + ent->wait;
00659 }
00660 }
00661
00662 // fire targets
00663 if ( !ent->activator )
00664 {
00665 ent->activator = ent;
00666 }
00667 G_UseTargets2( ent, ent->activator, ent->opentarget );
00668 }
00669 else if ( ent->moverState == MOVER_2TO1 )
00670 {//closed
00671 vec3_t doorcenter;
00672
00673 // reached pos1
00674 SetMoverState( ent, MOVER_POS1, level.time );
00675
00676 CalcTeamDoorCenter( ent, doorcenter );
00677
00678 // play sound
00679 G_PlayDoorSound( ent, BMS_END );
00680
00681 // close areaportals
00682 if ( ent->teammaster == ent || !ent->teammaster )
00683 {
00684 trap_AdjustAreaPortalState( ent, qfalse );
00685 }
00686 G_UseTargets2( ent, ent->activator, ent->closetarget );
00687 }
00688 else
00689 {
00690 G_Error( "Reached_BinaryMover: bad moverState" );
00691 }
00692 }
|
|
|
Definition at line 1729 of file g_mover.c. References BMS_END, G_PlayDoorLoopSound(), G_PlayDoorSound(), G_UseTargets(), gentity_t, level, entityState_s::loopIsSoundset, entityState_s::loopSound, MOVER_1TO2, gentity_s::nextthink, gentity_s::nextTrain, NULL, entityState_s::origin, entityState_s::pos, gentity_s::pos1, gentity_s::pos2, qfalse, gentity_s::s, SetMoverState(), gentity_s::speed, gentity_s::think, Think_BeginMoving(), level_locals_t::time, TR_STATIONARY, trajectory_t::trDuration, trajectory_t::trType, vec3_t, VectorCopy, VectorSubtract, and gentity_s::wait. Referenced by SP_func_train(), and Think_SetupTrainTargets().
01729 {
01730 gentity_t *next;
01731 float speed;
01732 vec3_t move;
01733 float length;
01734
01735 // copy the apropriate values
01736 next = ent->nextTrain;
01737 if ( !next || !next->nextTrain ) {
01738 return; // just stop
01739 }
01740
01741 // fire all other targets
01742 G_UseTargets( next, NULL );
01743
01744 // set the new trajectory
01745 ent->nextTrain = next->nextTrain;
01746 VectorCopy( next->s.origin, ent->pos1 );
01747 VectorCopy( next->nextTrain->s.origin, ent->pos2 );
01748
01749 // if the path_corner has a speed, use that
01750 if ( next->speed ) {
01751 speed = next->speed;
01752 } else {
01753 // otherwise use the train's speed
01754 speed = ent->speed;
01755 }
01756 if ( speed < 1 ) {
01757 speed = 1;
01758 }
01759
01760 // calculate duration
01761 VectorSubtract( ent->pos2, ent->pos1, move );
01762 length = VectorLength( move );
01763
01764 ent->s.pos.trDuration = length * 1000 / speed;
01765
01766 // start it going
01767 SetMoverState( ent, MOVER_1TO2, level.time );
01768
01769 G_PlayDoorSound( ent, BMS_END );
01770
01771 // if there is a "wait" value on the target, don't start moving yet
01772 if ( next->wait ) {
01773 ent->s.loopSound = 0;
01774 ent->s.loopIsSoundset = qfalse;
01775 ent->nextthink = level.time + next->wait * 1000;
01776 ent->think = Think_BeginMoving;
01777 ent->s.pos.trType = TR_STATIONARY;
01778 }
01779 else
01780 {
01781 G_PlayDoorLoopSound( ent );
01782 }
01783 }
|
|
|
Definition at line 605 of file g_mover.c. References BMS_START, G_PlayDoorLoopSound(), G_PlayDoorSound(), gentity_t, level, MatchTeam(), MOVER_2TO1, gentity_s::nextthink, gentity_s::s, gentity_s::think, level_locals_t::time, and entityState_s::time. Referenced by Reached_BinaryMover(), and Use_BinaryMover_Go().
|
|
||||||||||||||||
|
Definition at line 525 of file g_mover.c. References gentity_s::alt_fire, BG_EvaluateTrajectory(), entityShared_t::currentOrigin, gentity_t, level, MOVER_1TO2, MOVER_2TO1, MOVER_POS1, MOVER_POS2, gentity_s::moverState, entityState_s::pos, gentity_s::pos1, gentity_s::pos2, gentity_s::r, gentity_s::s, level_locals_t::time, TR_LINEAR_STOP, TR_NONLINEAR_STOP, TR_STATIONARY, trap_LinkEntity(), trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trDuration, trajectory_t::trTime, trajectory_t::trType, vec3_t, VectorCopy, VectorScale, and VectorSubtract. Referenced by MatchTeam(), Reached_BinaryMover(), and Reached_Train().
00525 {
00526 vec3_t delta;
00527 float f;
00528
00529 ent->moverState = moverState;
00530
00531 ent->s.pos.trTime = time;
00532
00533 if ( ent->s.pos.trDuration <= 0 )
00534 {//Don't allow divide by zero!
00535 ent->s.pos.trDuration = 1;
00536 }
00537
00538 switch( moverState ) {
00539 case MOVER_POS1:
00540 VectorCopy( ent->pos1, ent->s.pos.trBase );
00541 ent->s.pos.trType = TR_STATIONARY;
00542 break;
00543 case MOVER_POS2:
00544 VectorCopy( ent->pos2, ent->s.pos.trBase );
00545 ent->s.pos.trType = TR_STATIONARY;
00546 break;
00547 case MOVER_1TO2:
00548 VectorCopy( ent->pos1, ent->s.pos.trBase );
00549 VectorSubtract( ent->pos2, ent->pos1, delta );
00550 f = 1000.0 / ent->s.pos.trDuration;
00551 VectorScale( delta, f, ent->s.pos.trDelta );
00552 if ( ent->alt_fire )
00553 {
00554 ent->s.pos.trType = TR_LINEAR_STOP;
00555 }
00556 else
00557 {
00558 ent->s.pos.trType = TR_NONLINEAR_STOP;
00559 }
00560 //ent->s.eFlags &= ~EF_BLOCKED_MOVER;
00561 break;
00562 case MOVER_2TO1:
00563 VectorCopy( ent->pos2, ent->s.pos.trBase );
00564 VectorSubtract( ent->pos1, ent->pos2, delta );
00565 f = 1000.0 / ent->s.pos.trDuration;
00566 VectorScale( delta, f, ent->s.pos.trDelta );
00567 if ( ent->alt_fire )
00568 {
00569 ent->s.pos.trType = TR_LINEAR_STOP;
00570 }
00571 else
00572 {
00573 ent->s.pos.trType = TR_NONLINEAR_STOP;
00574 }
00575 //ent->s.eFlags &= ~EF_BLOCKED_MOVER;
00576 break;
00577 }
00578 BG_EvaluateTrajectory( &ent->s.pos, level.time, ent->r.currentOrigin );
00579 trap_LinkEntity( ent );
00580 }
|
|
|
Definition at line 2217 of file g_mover.c. References entityShared_t::currentOrigin, gentity_s::damage, G_SpawnFloat(), G_SpawnInt(), gentity_t, InitMover(), gentity_s::model, entityState_s::origin, entityState_s::pos, gentity_s::r, gentity_s::s, gentity_s::spawnflags, gentity_s::speed, TR_SINE, trap_SetBrushModel(), trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trDuration, trajectory_t::trTime, trajectory_t::trType, and VectorCopy.
02217 {
02218 float height;
02219 float phase;
02220
02221 G_SpawnFloat( "speed", "4", &ent->speed );
02222 G_SpawnFloat( "height", "32", &height );
02223 G_SpawnInt( "dmg", "2", &ent->damage );
02224 G_SpawnFloat( "phase", "0", &phase );
02225
02226 trap_SetBrushModel( ent, ent->model );
02227 InitMover( ent );
02228
02229 VectorCopy( ent->s.origin, ent->s.pos.trBase );
02230 VectorCopy( ent->s.origin, ent->r.currentOrigin );
02231
02232 ent->s.pos.trDuration = ent->speed * 1000;
02233 ent->s.pos.trTime = ent->s.pos.trDuration * phase;
02234 ent->s.pos.trType = TR_SINE;
02235
02236 // set the axis of bobbing
02237 if ( ent->spawnflags & 1 ) {
02238 ent->s.pos.trDelta[0] = height;
02239 } else if ( ent->spawnflags & 2 ) {
02240 ent->s.pos.trDelta[1] = height;
02241 } else {
02242 ent->s.pos.trDelta[2] = height;
02243 }
02244 }
|
|
|
Definition at line 2717 of file g_mover.c. References atoi(), FL_DMG_BY_HEAVY_WEAP_ONLY, FL_DMG_BY_SABER_ONLY, gentity_s::flags, funcBBrushPain(), funcBBrushTouch(), funcBBrushUse(), G_EffectIndex(), G_Error(), g_gametype, G_ScaleNetHealth(), G_SoundIndex(), G_SpawnFloat(), G_SpawnInt(), G_SpawnString(), gentity_s::genericValue15, gentity_s::genericValue4, gentity_t, GT_SIEGE, gentity_s::health, vmCvar_t::integer, gentity_s::mass, gentity_s::material, gentity_s::maxHealth, gentity_s::model, NULL, gentity_s::pain, qtrue, gentity_s::radius, gentity_s::spawnflags, gentity_s::splashDamage, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::team, gentity_s::teamnodmg, gentity_s::touch, and gentity_s::use.
02718 {
02719 int t;
02720 char *s = NULL;
02721
02722 G_SpawnString("playfx", "", &s);
02723
02724 if (s && s[0])
02725 { //should we play a special death effect?
02726 self->genericValue15 = G_EffectIndex(s);
02727 }
02728 else
02729 {
02730 self->genericValue15 = 0;
02731 }
02732
02733 if(!(self->spawnflags & 1))
02734 {
02735 if(!self->health)
02736 {
02737 self->health = 10;
02738 }
02739 }
02740
02741 G_SpawnInt( "showhealth", "0", &t );
02742
02743 if (t)
02744 { //a non-0 maxhealth value will mean we want to show the health on the hud
02745 self->maxHealth = self->health;
02746 G_ScaleNetHealth(self);
02747 }
02748
02749 //NOTE: g_spawn.c does this automatically now
02750 //G_SpawnInt( "teamowner", "0", &t );
02751 //self->s.teamowner = t;
02752
02753 if ( self->spawnflags & 16 ) // saber only
02754 {
02755 self->flags |= FL_DMG_BY_SABER_ONLY;
02756 }
02757 else if ( self->spawnflags & 32 ) // heavy weap
02758 {
02759 self->flags |= FL_DMG_BY_HEAVY_WEAP_ONLY;
02760 }
02761
02762 if (self->health)
02763 {
02764 self->takedamage = qtrue;
02765 }
02766
02767 G_SoundIndex("sound/weapons/explosions/cargoexplode.wav");//precaching
02768 G_SpawnFloat( "radius", "1", &self->radius ); // used to scale chunk code if desired by a designer
02769 G_SpawnInt( "material", "0", (int*)&self->material );
02770
02771 G_SpawnInt( "splashDamage", "0", &self->splashDamage );
02772 G_SpawnInt( "splashRadius", "0", &self->splashRadius );
02773
02774 CacheChunkEffects( self->material );
02775
02776 self->use = funcBBrushUse;
02777
02778 //if ( self->paintarget )
02779 {
02780 self->pain = funcBBrushPain;
02781 }
02782
02783 self->touch = funcBBrushTouch;
02784
02785 /*
02786 if ( self->team && self->team[0] )
02787 {
02788 self->alliedTeam = TranslateTeamName( self->team );
02789 if(self->alliedTeam == TEAM_FREE)
02790 {
02791 G_Error("team name %s not recognized\n", self->team);
02792 }
02793 }
02794 */
02795 if ( self->team && self->team[0] && g_gametype.integer == GT_SIEGE &&
02796 !self->teamnodmg)
02797 {
02798 self->teamnodmg = atoi(self->team);
02799 }
02800 self->team = NULL;
02801 if (!self->model) {
02802 G_Error("func_breakable with NULL model\n");
02803 }
02804 InitBBrush( self );
02805
02806 if ( !self->radius )
02807 {//numchunks multiplier
02808 self->radius = 1.0f;
02809 }
02810 if ( !self->mass )
02811 {//chunksize multiplier
02812 self->mass = 1.0f;
02813 }
02814 self->genericValue4 = 1; //so damage sys knows it's a bbrush
02815 }
|
|
|
Definition at line 1650 of file g_mover.c. References entityState_s::angles, fabs(), G_SetMovedir(), G_SpawnFloat(), gentity_t, gentity_s::health, InitMover(), entityShared_t::maxs, entityShared_t::mins, gentity_s::model, gentity_s::movedir, entityState_s::origin, gentity_s::pos1, gentity_s::pos2, qtrue, gentity_s::r, gentity_s::s, gentity_s::speed, gentity_s::takedamage, gentity_s::touch, Touch_Button(), trap_SetBrushModel(), vec3_t, VectorCopy, VectorMA, VectorSubtract, and gentity_s::wait.
01650 {
01651 vec3_t abs_movedir;
01652 float distance;
01653 vec3_t size;
01654 float lip;
01655
01656 // ent->sound1to2 = G_SoundIndex("sound/movers/switches/butn2.wav");
01657
01658 if ( !ent->speed ) {
01659 ent->speed = 40;
01660 }
01661
01662 if ( !ent->wait ) {
01663 ent->wait = 1;
01664 }
01665 ent->wait *= 1000;
01666
01667 // first position
01668 VectorCopy( ent->s.origin, ent->pos1 );
01669
01670 // calculate second position
01671 trap_SetBrushModel( ent, ent->model );
01672
01673 G_SpawnFloat( "lip", "4", &lip );
01674
01675 G_SetMovedir( ent->s.angles, ent->movedir );
01676 abs_movedir[0] = fabs(ent->movedir[0]);
01677 abs_movedir[1] = fabs(ent->movedir[1]);
01678 abs_movedir[2] = fabs(ent->movedir[2]);
01679 VectorSubtract( ent->r.maxs, ent->r.mins, size );
01680 distance = abs_movedir[0] * size[0] + abs_movedir[1] * size[1] + abs_movedir[2] * size[2] - lip;
01681 VectorMA (ent->pos1, distance, ent->movedir, ent->pos2);
01682
01683 if (ent->health) {
01684 // shootable button
01685 ent->takedamage = qtrue;
01686 } else {
01687 // touchable button
01688 ent->touch = Touch_Button;
01689 }
01690
01691 InitMover( ent );
01692 }
|
|
|
Definition at line 1370 of file g_mover.c. References gentity_s::alliedTeam, entityState_s::angles, gentity_s::blocked, Blocked_Door(), entityState_s::bolt1, gentity_s::damage, gentity_s::delay, DotProduct, EF_SHADER_ANIM, entityState_s::eFlags, fabs(), FL_TEAMSLAVE, gentity_s::flags, entityState_s::frame, FRAMETIME, G_SetMovedir(), G_SpawnFloat(), G_SpawnInt(), gentity_s::genericValue14, gentity_t, InitMover(), level, entityShared_t::maxs, entityShared_t::mins, gentity_s::model, gentity_s::movedir, MOVER_FORCE_ACTIVATE, MOVER_LOCKED, MOVER_PLAYER_USE, gentity_s::nextthink, entityState_s::origin, gentity_s::pos1, gentity_s::pos2, qtrue, gentity_s::r, gentity_s::s, gentity_s::spawnflags, gentity_s::speed, gentity_s::takedamage, gentity_s::targetname, gentity_s::think, Think_MatchTeam(), Think_SpawnNewDoorTrigger(), level_locals_t::time, trap_SetBrushModel(), vec3_t, VectorCopy, VectorMA, VectorSubtract, and gentity_s::wait.
01371 {
01372 vec3_t abs_movedir;
01373 float distance;
01374 vec3_t size;
01375 float lip;
01376
01377 G_SpawnInt("vehopen", "0", &ent->genericValue14);
01378
01379 ent->blocked = Blocked_Door;
01380
01381 // default speed of 400
01382 if (!ent->speed)
01383 ent->speed = 400;
01384
01385 // default wait of 2 seconds
01386 if (!ent->wait)
01387 ent->wait = 2;
01388 ent->wait *= 1000;
01389
01390 ent->delay *= 1000;
01391
01392 // default lip of 8 units
01393 G_SpawnFloat( "lip", "8", &lip );
01394
01395 // default damage of 2 points
01396 G_SpawnInt( "dmg", "2", &ent->damage );
01397 if ( ent->damage < 0 )
01398 {
01399 ent->damage = 0;
01400 }
01401
01402 G_SpawnInt( "teamallow", "0", &ent->alliedTeam );
01403
01404 // first position at start
01405 VectorCopy( ent->s.origin, ent->pos1 );
01406
01407 // calculate second position
01408 trap_SetBrushModel( ent, ent->model );
01409 G_SetMovedir( ent->s.angles, ent->movedir );
01410 abs_movedir[0] = fabs( ent->movedir[0] );
01411 abs_movedir[1] = fabs( ent->movedir[1] );
01412 abs_movedir[2] = fabs( ent->movedir[2] );
01413 VectorSubtract( ent->r.maxs, ent->r.mins, size );
01414 distance = DotProduct( abs_movedir, size ) - lip;
01415 VectorMA( ent->pos1, distance, ent->movedir, ent->pos2 );
01416
01417 // if "start_open", reverse position 1 and 2
01418 if ( ent->spawnflags & 1 )
01419 {
01420 vec3_t temp;
01421
01422 VectorCopy( ent->pos2, temp );
01423 VectorCopy( ent->s.origin, ent->pos2 );
01424 VectorCopy( temp, ent->pos1 );
01425 }
01426
01427 if ( ent->spawnflags & MOVER_LOCKED )
01428 {//a locked door, set up as locked until used directly
01429 ent->s.eFlags |= EF_SHADER_ANIM;//use frame-controlled shader anim
01430 ent->s.frame = 0;//first stage of anim
01431 }
01432 InitMover( ent );
01433
01434 ent->nextthink = level.time + FRAMETIME;
01435
01436 if ( !(ent->flags&FL_TEAMSLAVE) )
01437 {
01438 int health;
01439
01440 G_SpawnInt( "health", "0", &health );
01441
01442 if ( health )
01443 {
01444 ent->takedamage = qtrue;
01445 }
01446
01447 if ( !(ent->spawnflags&MOVER_LOCKED) && (ent->targetname || health || ent->spawnflags & MOVER_PLAYER_USE || ent->spawnflags & MOVER_FORCE_ACTIVATE) )
01448 {
01449 // non touch/shoot doors
01450 ent->think = Think_MatchTeam;
01451
01452 if (ent->spawnflags & MOVER_FORCE_ACTIVATE)
01453 { //so we know it's push/pullable on the client
01454 ent->s.bolt1 = 1;
01455 }
01456 }
01457 else
01458 {//locked doors still spawn a trigger
01459 ent->think = Think_SpawnNewDoorTrigger;
01460 }
01461 }
01462 }
|
|
|
|
Definition at line 2266 of file g_mover.c. References entityState_s::angles, entityState_s::apos, entityShared_t::currentOrigin, gentity_s::damage, fabs(), g_gravity, G_SpawnFloat(), G_SpawnInt(), gentity_t, InitMover(), M_PI, entityShared_t::mins, gentity_s::model, entityState_s::origin, entityState_s::pos, gentity_s::r, gentity_s::s, sqrt(), TR_SINE, trap_SetBrushModel(), trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trDuration, trajectory_t::trTime, trajectory_t::trType, vmCvar_t::value, and VectorCopy.
02266 {
02267 float freq;
02268 float length;
02269 float phase;
02270 float speed;
02271
02272 G_SpawnFloat( "speed", "30", &speed );
02273 G_SpawnInt( "dmg", "2", &ent->damage );
02274 G_SpawnFloat( "phase", "0", &phase );
02275
02276 trap_SetBrushModel( ent, ent->model );
02277
02278 // find pendulum length
02279 length = fabs( ent->r.mins[2] );
02280 if ( length < 8 ) {
02281 length = 8;
02282 }
02283
02284 freq = 1 / ( M_PI * 2 ) * sqrt( g_gravity.value / ( 3 * length ) );
02285
02286 ent->s.pos.trDuration = ( 1000 / freq );
02287
02288 InitMover( ent );
02289
02290 VectorCopy( ent->s.origin, ent->s.pos.trBase );
02291 VectorCopy( ent->s.origin, ent->r.currentOrigin );
02292
02293 VectorCopy( ent->s.angles, ent->s.apos.trBase );
02294
02295 ent->s.apos.trDuration = 1000 / freq;
02296 ent->s.apos.trTime = ent->s.apos.trDuration * phase;
02297 ent->s.apos.trType = TR_SINE;
02298 ent->s.apos.trDelta[2] = speed;
02299 }
|
|
|
Definition at line 1566 of file g_mover.c. References entityState_s::angles, gentity_s::blocked, Blocked_Door(), gentity_s::damage, G_SpawnFloat(), G_SpawnInt(), gentity_t, InitMover(), entityShared_t::maxs, entityShared_t::mins, gentity_s::model, entityState_s::origin, gentity_s::parent, gentity_s::pos1, gentity_s::pos2, gentity_s::r, gentity_s::s, SpawnPlatTrigger(), gentity_s::speed, gentity_s::targetname, gentity_s::touch, Touch_Plat(), trap_SetBrushModel(), VectorClear, VectorCopy, and gentity_s::wait.
01566 {
01567 float lip, height;
01568
01569 // ent->sound1to2 = ent->sound2to1 = G_SoundIndex("sound/movers/plats/pt1_strt.wav");
01570 // ent->soundPos1 = ent->soundPos2 = G_SoundIndex("sound/movers/plats/pt1_end.wav");
01571
01572 VectorClear (ent->s.angles);
01573
01574 G_SpawnFloat( "speed", "200", &ent->speed );
01575 G_SpawnInt( "dmg", "2", &ent->damage );
01576 G_SpawnFloat( "wait", "1", &ent->wait );
01577 G_SpawnFloat( "lip", "8", &lip );
01578
01579 ent->wait = 1000;
01580
01581 // create second position
01582 trap_SetBrushModel( ent, ent->model );
01583
01584 if ( !G_SpawnFloat( "height", "0", &height ) ) {
01585 height = (ent->r.maxs[2] - ent->r.mins[2]) - lip;
01586 }
01587
01588 // pos1 is the rest (bottom) position, pos2 is the top
01589 VectorCopy( ent->s.origin, ent->pos2 );
01590 VectorCopy( ent->pos2, ent->pos1 );
01591 ent->pos1[2] -= height;
01592
01593 InitMover( ent );
01594
01595 // touch function keeps the plat from returning while
01596 // a live player is standing on it
01597 ent->touch = Touch_Plat;
01598
01599 ent->blocked = Blocked_Door;
01600
01601 ent->parent = ent; // so it can be treated as a door
01602
01603 // spawn the trigger if one hasn't been custom made
01604 if ( !ent->targetname ) {
01605 SpawnPlatTrigger(ent);
01606 }
01607 }
|
|
|
Definition at line 2121 of file g_mover.c. References entityShared_t::absmax, entityShared_t::absmin, entityState_s::apos, entityShared_t::currentAngles, entityShared_t::currentOrigin, gentity_s::damage, EF_RADAROBJECT, entityState_s::eFlags, G_SpawnInt(), G_SpawnVector(), gentity_t, gentity_s::health, entityState_s::iModelScale, InitMover(), gentity_s::model, entityState_s::origin, entityState_s::pos, gentity_s::r, gentity_s::s, SP_func_breakable(), gentity_s::spawnflags, gentity_s::speed, entityState_s::speed, TR_LINEAR, trap_LinkEntity(), trap_SetBrushModel(), trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trType, vec3_t, and VectorCopy. Referenced by asteroid_field_think().
02121 {
02122 vec3_t spinangles;
02123 if ( ent->health )
02124 {
02125 int sav_spawnflags = ent->spawnflags;
02126 ent->spawnflags = 0;
02127 SP_func_breakable( ent );
02128 ent->spawnflags = sav_spawnflags;
02129 }
02130 else
02131 {
02132 trap_SetBrushModel( ent, ent->model );
02133 InitMover( ent );
02134
02135 VectorCopy( ent->s.origin, ent->s.pos.trBase );
02136 VectorCopy( ent->s.pos.trBase, ent->r.currentOrigin );
02137 VectorCopy( ent->s.apos.trBase, ent->r.currentAngles );
02138
02139 trap_LinkEntity( ent );
02140 }
02141
02142 #ifdef _XBOX
02143 int tempModelScale;
02144 G_SpawnInt("model2scale", "0", &tempModelScale);
02145 ent->s.iModelScale = tempModelScale;
02146 #else
02147 G_SpawnInt("model2scale", "0", &ent->s.iModelScale);
02148 #endif
02149 if (ent->s.iModelScale < 0)
02150 {
02151 ent->s.iModelScale = 0;
02152 }
02153 else if (ent->s.iModelScale > 1023)
02154 {
02155 ent->s.iModelScale = 1023;
02156 }
02157
02158 if ( G_SpawnVector( "spinangles", "0 0 0", spinangles ) )
02159 {
02160 ent->speed = VectorLength( spinangles );
02161 // set the axis of rotation
02162 VectorCopy( spinangles, ent->s.apos.trDelta );
02163 }
02164 else
02165 {
02166 if ( !ent->speed ) {
02167 ent->speed = 100;
02168 }
02169 // set the axis of rotation
02170 if ( ent->spawnflags & 4 ) {
02171 ent->s.apos.trDelta[2] = ent->speed;
02172 } else if ( ent->spawnflags & 8 ) {
02173 ent->s.apos.trDelta[0] = ent->speed;
02174 } else {
02175 ent->s.apos.trDelta[1] = ent->speed;
02176 }
02177 }
02178 ent->s.apos.trType = TR_LINEAR;
02179
02180 if (!ent->damage) {
02181 if ( (ent->spawnflags&16) )//IMPACT
02182 {
02183 ent->damage = 10000;
02184 }
02185 else
02186 {
02187 ent->damage = 2;
02188 }
02189 }
02190 if ( (ent->spawnflags&2) )//RADAR
02191 {//show up on Radar at close range and play impact sound when close...? Range based on my size
02192 ent->s.speed = Distance( ent->r.absmin, ent->r.absmax )*0.5f;
02193 ent->s.eFlags |= EF_RADAROBJECT;
02194 }
02195 }
|
|
|
Definition at line 1946 of file g_mover.c. References entityState_s::angles, entityState_s::bolt1, EF2_HYPERSPACE, EF_PERMANENT, EF_SHADER_ANIM, entityState_s::eFlags, entityState_s::eFlags2, entityState_s::frame, func_static_use(), G_SetAngles(), G_SetOrigin(), G_SpawnInt(), gentity_t, entityState_s::iModelScale, InitMover(), level, level_locals_t::mBSPInstanceDepth, gentity_s::model, entityState_s::origin, gentity_s::pos1, gentity_s::pos2, gentity_s::r, gentity_s::reached, gentity_s::s, gentity_s::spawnflags, SVF_BROADCAST, entityShared_t::svFlags, trap_LinkEntity(), trap_SetBrushModel(), gentity_s::use, and VectorCopy.
01947 {
01948 int test;
01949 trap_SetBrushModel( ent, ent->model );
01950
01951 VectorCopy( ent->s.origin, ent->pos1 );
01952 VectorCopy( ent->s.origin, ent->pos2 );
01953
01954 InitMover( ent );
01955
01956 ent->use = func_static_use;
01957 ent->reached = 0;
01958
01959 G_SetOrigin( ent, ent->s.origin );
01960 G_SetAngles( ent, ent->s.angles );
01961
01962 if( ent->spawnflags & 2048 )
01963 { // yes this is very very evil, but for now (pre-alpha) it's a solution
01964 ent->r.svFlags |= SVF_BROADCAST; // I need to rotate something that is huge and it's touching too many area portals...
01965 }
01966
01967 if ( ent->spawnflags & 4/*SWITCH_SHADER*/ )
01968 {
01969 ent->s.eFlags |= EF_SHADER_ANIM;//use frame-controlled shader anim
01970 ent->s.frame = 0;//first stage of anim
01971 }
01972
01973 if ((ent->spawnflags & 1) || (ent->spawnflags & 2))
01974 { //so we know it's push/pullable on the client
01975 ent->s.bolt1 = 1;
01976 }
01977
01978 #ifdef _XBOX
01979 int tempModelScale;
01980 G_SpawnInt("model2scale", "0", &tempModelScale);
01981 ent->s.iModelScale = tempModelScale;
01982 #else
01983 G_SpawnInt("model2scale", "0", &ent->s.iModelScale);
01984 #endif
01985 if (ent->s.iModelScale < 0)
01986 {
01987 ent->s.iModelScale = 0;
01988 }
01989 else if (ent->s.iModelScale > 1023)
01990 {
01991 ent->s.iModelScale = 1023;
01992 }
01993
01994 G_SpawnInt( "hyperspace", "0", &test );
01995 if ( test )
01996 {
01997 ent->r.svFlags |= SVF_BROADCAST; // I need to rotate something that is huge and it's touching too many area portals...
01998 ent->s.eFlags2 |= EF2_HYPERSPACE;
01999 }
02000
02001 trap_LinkEntity( ent );
02002
02003 if (level.mBSPInstanceDepth)
02004 { // this means that this guy will never be updated, moved, changed, etc.
02005 ent->s.eFlags = EF_PERMANENT;
02006 }
02007 }
|
|
|
Definition at line 1887 of file g_mover.c. References entityShared_t::absmin, entityState_s::angles, gentity_s::damage, FRAMETIME, G_FreeEntity(), G_Printf(), gentity_t, InitMover(), level, gentity_s::model, gentity_s::nextthink, gentity_s::r, gentity_s::reached, Reached_Train(), gentity_s::s, gentity_s::spawnflags, gentity_s::speed, gentity_s::target, gentity_s::think, Think_SetupTrainTargets(), level_locals_t::time, TRAIN_BLOCK_STOPS, trap_SetBrushModel(), VectorClear, and vtos().
01887 {
01888 VectorClear (self->s.angles);
01889
01890 if (self->spawnflags & TRAIN_BLOCK_STOPS) {
01891 self->damage = 0;
01892 } else {
01893 if (!self->damage) {
01894 self->damage = 2;
01895 }
01896 }
01897
01898 if ( !self->speed ) {
01899 self->speed = 100;
01900 }
01901
01902 if ( !self->target ) {
01903 G_Printf ("func_train without a target at %s\n", vtos(self->r.absmin));
01904 G_FreeEntity( self );
01905 return;
01906 }
01907
01908 trap_SetBrushModel( self, self->model );
01909 InitMover( self );
01910
01911 self->reached = Reached_Train;
01912
01913 // start trains on the second frame, to make sure their targets have had
01914 // a chance to spawn
01915 self->nextthink = level.time + FRAMETIME;
01916 self->think = Think_SetupTrainTargets;
01917 }
|
|
|
Definition at line 3126 of file g_mover.c. References gentity_s::clipmask, entityShared_t::contents, gentity_s::count, entityShared_t::currentOrigin, gentity_s::die, EF_NODRAW, EF_SHADER_ANIM, entityState_s::eFlags, entityState_s::frame, func_usable_die(), func_usable_pain(), func_usable_use(), G_ModelIndex(), G_SpawnInt(), gentity_s::genericValue5, gentity_t, gentity_s::health, InitMover(), gentity_s::model, gentity_s::model2, entityState_s::modelindex2, entityState_s::origin, gentity_s::pain, entityState_s::pos, gentity_s::pos1, qtrue, gentity_s::r, gentity_s::s, entityState_s::solid, gentity_s::spawnflags, strstr(), SVF_NOCLIENT, entityShared_t::svFlags, gentity_s::takedamage, entityState_s::time, trap_LinkEntity(), trap_SetBrushModel(), trajectory_t::trBase, gentity_s::use, and VectorCopy.
03127 {
03128 trap_SetBrushModel( self, self->model );
03129 InitMover( self );
03130 VectorCopy( self->s.origin, self->s.pos.trBase );
03131 VectorCopy( self->s.origin, self->r.currentOrigin );
03132 VectorCopy( self->s.origin, self->pos1 );
03133
03134 G_SpawnInt("endframe", "0", &self->genericValue5);
03135
03136 if ( self->model2 && self->model2[0] )
03137 {
03138 if ( strstr( self->model2, ".glm" ))
03139 { //for now, not supported in MP.
03140 self->s.modelindex2 = 0;
03141 }
03142 else
03143 {
03144 self->s.modelindex2 = G_ModelIndex( self->model2 );
03145 }
03146 }
03147
03148 self->count = 1;
03149 if (self->spawnflags & 1)
03150 {
03151 self->s.solid = 0;
03152 self->r.contents = 0;
03153 self->clipmask = 0;
03154 self->r.svFlags |= SVF_NOCLIENT;
03155 self->s.eFlags |= EF_NODRAW;
03156 self->count = 0;
03157 }
03158
03159 //FIXME: Animation?
03160 /*
03161 if (self->spawnflags & 2)
03162 {
03163 self->s.eFlags |= EF_ANIM_ALLFAST;
03164 }
03165
03166 if (self->spawnflags & 4)
03167 {//FIXME: need to be able to do change to something when it's done? Or not be usable until it's done?
03168 self->s.eFlags |= EF_ANIM_ONCE;
03169 }
03170 */
03171
03172 self->use = func_usable_use;
03173
03174 if ( self->health )
03175 {
03176 self->takedamage = qtrue;
03177 self->die = func_usable_die;
03178 self->pain = func_usable_pain;
03179 }
03180
03181 if ( self->genericValue5 > 0 )
03182 {
03183 self->s.frame = 0;
03184 self->s.eFlags |= EF_SHADER_ANIM;
03185 self->s.time = self->genericValue5 + 1;
03186 }
03187
03188 trap_LinkEntity (self);
03189 }
|
|
|
|
Definition at line 1863 of file g_mover.c. References G_FreeEntity(), G_Printf(), gentity_t, entityState_s::origin, gentity_s::s, gentity_s::targetname, and vtos().
01863 {
01864 if ( !self->targetname ) {
01865 G_Printf ("path_corner with no targetname at %s\n", vtos(self->s.origin));
01866 G_FreeEntity( self );
01867 return;
01868 }
01869 // path corners don't need to be linked in
01870 }
|
|
|
Definition at line 1517 of file g_mover.c. References entityShared_t::contents, CONTENTS_TRIGGER, G_Spawn(), gentity_t, entityShared_t::maxs, entityShared_t::mins, gentity_s::parent, gentity_s::pos1, gentity_s::r, gentity_s::touch, Touch_PlatCenterTrigger(), trap_LinkEntity(), vec3_t, and VectorCopy. Referenced by SP_func_plat().
01517 {
01518 gentity_t *trigger;
01519 vec3_t tmin, tmax;
01520
01521 // the middle trigger will be a thin trigger just
01522 // above the starting position
01523 trigger = G_Spawn();
01524 trigger->touch = Touch_PlatCenterTrigger;
01525 trigger->r.contents = CONTENTS_TRIGGER;
01526 trigger->parent = ent;
01527
01528 tmin[0] = ent->pos1[0] + ent->r.mins[0] + 33;
01529 tmin[1] = ent->pos1[1] + ent->r.mins[1] + 33;
01530 tmin[2] = ent->pos1[2] + ent->r.mins[2];
01531
01532 tmax[0] = ent->pos1[0] + ent->r.maxs[0] - 33;
01533 tmax[1] = ent->pos1[1] + ent->r.maxs[1] - 33;
01534 tmax[2] = ent->pos1[2] + ent->r.maxs[2] + 8;
01535
01536 if ( tmax[0] <= tmin[0] ) {
01537 tmin[0] = ent->pos1[0] + (ent->r.mins[0] + ent->r.maxs[0]) *0.5;
01538 tmax[0] = tmin[0] + 1;
01539 }
01540 if ( tmax[1] <= tmin[1] ) {
01541 tmin[1] = ent->pos1[1] + (ent->r.mins[1] + ent->r.maxs[1]) *0.5;
01542 tmax[1] = tmin[1] + 1;
01543 }
01544
01545 VectorCopy (tmin, trigger->r.mins);
01546 VectorCopy (tmax, trigger->r.maxs);
01547
01548 trap_LinkEntity (trigger);
01549 }
|
|
|
Definition at line 1717 of file g_mover.c. References BMS_START, G_PlayDoorLoopSound(), G_PlayDoorSound(), gentity_t, level, entityState_s::pos, gentity_s::s, level_locals_t::time, TR_LINEAR_STOP, trajectory_t::trTime, and trajectory_t::trType. Referenced by Reached_Train().
01717 {
01718 G_PlayDoorSound( ent, BMS_START );
01719 G_PlayDoorLoopSound( ent );
01720 ent->s.pos.trTime = level.time;
01721 ent->s.pos.trType = TR_LINEAR_STOP;
01722 }
|
|
|
Definition at line 1207 of file g_mover.c. References gentity_t, level, MatchTeam(), gentity_s::moverState, and level_locals_t::time. Referenced by SP_func_door().
01208 {
01209 MatchTeam( ent, ent->moverState, level.time );
01210 }
|
|
|
Definition at line 1792 of file g_mover.c. References entityShared_t::absmin, gentity_s::classname, Com_Printf(), FOFS, G_Find(), G_SetOrigin(), gentity_t, gentity_s::nextTrain, NULL, entityState_s::origin, gentity_s::r, Reached_Train(), gentity_s::s, gentity_s::spawnflags, strcmp(), gentity_s::target, gentity_s::targetname, and vtos(). Referenced by SP_func_train().
01792 {
01793 gentity_t *path, *next, *start;
01794
01795 ent->nextTrain = G_Find( NULL, FOFS(targetname), ent->target );
01796 if ( !ent->nextTrain ) {
01797 Com_Printf( "func_train at %s with an unfound target\n",
01798 vtos(ent->r.absmin) );
01799 //Free me?`
01800 return;
01801 }
01802
01803 //FIXME: this can go into an infinite loop if last path_corner doesn't link to first
01804 //path_corner, like so:
01805 // t1---->t2---->t3
01806 // ^ |
01807 // \_____|
01808 start = NULL;
01809 for ( path = ent->nextTrain ; path != start ; path = next ) {
01810 if ( !start ) {
01811 start = path;
01812 }
01813
01814 if ( !path->target ) {
01815 // gi.Printf( "Train corner at %s without a target\n",
01816 // vtos(path->s.origin) );
01817 //end of path
01818 break;
01819 }
01820
01821 // find a path_corner among the targets
01822 // there may also be other targets that get fired when the corner
01823 // is reached
01824 next = NULL;
01825 do {
01826 next = G_Find( next, FOFS(targetname), path->target );
01827 if ( !next ) {
01828 // gi.Printf( "Train corner at %s without a target path_corner\n",
01829 // vtos(path->s.origin) );
01830 //end of path
01831 break;
01832 }
01833 } while ( strcmp( next->classname, "path_corner" ) );
01834
01835 if ( next )
01836 {
01837 path->nextTrain = next;
01838 }
01839 else
01840 {
01841 break;
01842 }
01843 }
01844
01845 if ( !ent->targetname || (ent->spawnflags&1) /*start on*/)
01846 {
01847 // start the train moving from the first corner
01848 Reached_Train( ent );
01849 }
01850 else
01851 {
01852 G_SetOrigin( ent, ent->s.origin );
01853 }
01854 }
|
|
|
Definition at line 1158 of file g_mover.c. References entityShared_t::absmax, entityShared_t::absmin, AddPointToBounds(), gentity_s::classname, entityShared_t::contents, CONTENTS_TRIGGER, gentity_s::count, G_Spawn(), gentity_t, level, MatchTeam(), entityShared_t::maxs, entityShared_t::mins, gentity_s::moverState, gentity_s::parent, qtrue, gentity_s::r, gentity_s::takedamage, gentity_s::teamchain, level_locals_t::time, gentity_s::touch, Touch_DoorTrigger(), trap_LinkEntity(), vec3_t, and VectorCopy. Referenced by SP_func_door().
01159 {
01160 gentity_t *other;
01161 vec3_t mins, maxs;
01162 int i, best;
01163
01164 // set all of the slaves as shootable
01165 if ( ent->takedamage )
01166 {
01167 for ( other = ent ; other ; other = other->teamchain )
01168 {
01169 other->takedamage = qtrue;
01170 }
01171 }
01172
01173 // find the bounds of everything on the team
01174 VectorCopy (ent->r.absmin, mins);
01175 VectorCopy (ent->r.absmax, maxs);
01176
01177 for (other = ent->teamchain ; other ; other=other->teamchain) {
01178 AddPointToBounds (other->r.absmin, mins, maxs);
01179 AddPointToBounds (other->r.absmax, mins, maxs);
01180 }
01181
01182 // find the thinnest axis, which will be the one we expand
01183 best = 0;
01184 for ( i = 1 ; i < 3 ; i++ ) {
01185 if ( maxs[i] - mins[i] < maxs[best] - mins[best] ) {
01186 best = i;
01187 }
01188 }
01189 maxs[best] += 120;
01190 mins[best] -= 120;
01191
01192 // create a trigger with this size
01193 other = G_Spawn ();
01194 VectorCopy (mins, other->r.mins);
01195 VectorCopy (maxs, other->r.maxs);
01196 other->parent = ent;
01197 other->r.contents = CONTENTS_TRIGGER;
01198 other->touch = Touch_DoorTrigger;
01199 trap_LinkEntity (other);
01200 other->classname = "trigger_door";
01201 // remember the thinnest axis
01202 other->count = best;
01203
01204 MatchTeam( ent, ent->moverState, level.time );
01205 }
|
|
||||||||||||||||
|
Definition at line 1623 of file g_mover.c. References gentity_s::client, gentity_t, MOVER_POS1, gentity_s::moverState, and Use_BinaryMover(). Referenced by ForceThrow(), SP_func_button(), and TryUse().
01623 {
01624 if ( !other->client ) {
01625 return;
01626 }
01627
01628 if ( ent->moverState == MOVER_POS1 ) {
01629 Use_BinaryMover( ent, other, other );
01630 }
01631 }
|
|
||||||||||||||||
|
Definition at line 1068 of file g_mover.c. References gentity_s::alliedTeam, CLASS_VEHICLE, gentity_s::client, ET_NPC, entityState_s::eType, FL_INACTIVE, FL_TEAMSLAVE, gentity_s::flags, gentity_s::genericValue14, gentity_t, playerState_s::m_iVehicleNum, MAX_CLIENTS, MOVER_1TO2, MOVER_LOCKED, MOVER_POS2, gentity_s::moverState, entityState_s::NPC_class, NULL, entityState_s::number, gentity_s::parent, gclient_s::ps, gentity_s::s, gclient_s::sess, clientSession_t::sessionTeam, gentity_s::spawnflags, TEAM_SPECTATOR, gentity_s::teammaster, and Use_BinaryMover(). Referenced by G_TouchTriggers(), and Think_SpawnNewDoorTrigger().
01069 {
01070 gentity_t *relockEnt = NULL;
01071
01072 if ( other->client && other->client->sess.sessionTeam == TEAM_SPECTATOR )
01073 {
01074 // if the door is not open and not opening
01075 if ( ent->parent->moverState != MOVER_1TO2 &&
01076 ent->parent->moverState != MOVER_POS2 )
01077 {
01078 Touch_DoorTriggerSpectator( ent, other, trace );
01079 }
01080 return;
01081 }
01082
01083 if (!ent->genericValue14 &&
01084 (!ent->parent || !ent->parent->genericValue14))
01085 {
01086 if (other->client && other->s.number >= MAX_CLIENTS &&
01087 other->s.eType == ET_NPC && other->s.NPC_class == CLASS_VEHICLE)
01088 { //doors don't open for vehicles
01089 return;
01090 }
01091
01092 if (other->client && other->s.number < MAX_CLIENTS &&
01093 other->client->ps.m_iVehicleNum)
01094 { //can't open a door while on a vehicle
01095 return;
01096 }
01097 }
01098
01099 if ( ent->flags & FL_INACTIVE )
01100 {
01101 return;
01102 }
01103
01104 if ( ent->parent->spawnflags & MOVER_LOCKED )
01105 {//don't even try to use the door if it's locked
01106 if ( !ent->parent->alliedTeam //we don't have a "teamallow" team
01107 || !other->client //we do have a "teamallow" team, but this isn't a client
01108 || other->client->sess.sessionTeam != ent->parent->alliedTeam )//it is a client, but it's not on the right team
01109 {
01110 return;
01111 }
01112 else
01113 {//temporarily unlock us while we call Use_BinaryMover (so it doesn't unlock all the doors in this team)
01114 if ( ent->parent->flags & FL_TEAMSLAVE )
01115 {
01116 relockEnt = ent->parent->teammaster;
01117 }
01118 else
01119 {
01120 relockEnt = ent->parent;
01121 }
01122 if ( relockEnt != NULL )
01123 {
01124 relockEnt->spawnflags &= ~MOVER_LOCKED;
01125 }
01126 }
01127 }
01128
01129 if ( ent->parent->moverState != MOVER_1TO2 )
01130 {//Door is not already opening
01131 //if ( ent->parent->moverState == MOVER_POS1 || ent->parent->moverState == MOVER_2TO1 )
01132 //{//only check these if closed or closing
01133
01134 //If door is closed, opening or open, check this
01135 Use_BinaryMover( ent->parent, ent, other );
01136 }
01137 if ( relockEnt != NULL )
01138 {//re-lock us
01139 relockEnt->spawnflags |= MOVER_LOCKED;
01140 }
01141
01142 /*
01143 //Old style
01144 if ( ent->parent->moverState != MOVER_1TO2 ) {
01145 Use_BinaryMover( ent->parent, ent, other );
01146 }
01147 */
01148 }
|
|
||||||||||||||||
|
Definition at line 1479 of file g_mover.c. References gentity_s::client, gentity_t, level, MOVER_POS2, gentity_s::moverState, gentity_s::nextthink, gclient_s::ps, STAT_HEALTH, playerState_s::stats, and level_locals_t::time. Referenced by SP_func_plat().
01479 {
01480 if ( !other->client || other->client->ps.stats[STAT_HEALTH] <= 0 ) {
01481 return;
01482 }
01483
01484 // delay return-to-pos1 by one second
01485 if ( ent->moverState == MOVER_POS2 ) {
01486 ent->nextthink = level.time + 1000;
01487 }
01488 }
|
|
||||||||||||||||
|
Definition at line 1497 of file g_mover.c. References gentity_s::client, gentity_t, MOVER_POS1, gentity_s::moverState, gentity_s::parent, and Use_BinaryMover(). Referenced by SpawnPlatTrigger().
01497 {
01498 if ( !other->client ) {
01499 return;
01500 }
01501
01502 if ( ent->parent->moverState == MOVER_POS1 ) {
01503 Use_BinaryMover( ent->parent, ent, other );
01504 }
01505 }
|
|
|
Definition at line 820 of file g_mover.c. References entityState_s::frame, gentity_t, MOVER_LOCKED, MOVER_TOGGLE, NULL, gentity_s::s, gentity_s::spawnflags, gentity_s::targetname, and gentity_s::teamchain. Referenced by Q3_Set(), and Use_BinaryMover().
00821 {
00822 //noise?
00823 //go through and unlock the door and all the slaves
00824 gentity_t *slave = ent;
00825 do
00826 { // want to allow locked toggle doors, so keep the targetname
00827 if( !(slave->spawnflags & MOVER_TOGGLE) )
00828 {
00829 slave->targetname = NULL;//not usable ever again
00830 }
00831 slave->spawnflags &= ~MOVER_LOCKED;
00832 slave->s.frame = 1;//second stage of anim
00833 slave = slave->teamchain;
00834 } while ( slave );
00835 }
|
|
||||||||||||||||
|
Definition at line 853 of file g_mover.c. References gentity_s::activator, BSET_USE, gentity_s::delay, gentity_s::enemy, FL_INACTIVE, FL_TEAMSLAVE, gentity_s::flags, G_ActivateBehavior(), gentity_t, level, MOVER_LOCKED, gentity_s::nextthink, gentity_s::spawnflags, gentity_s::teammaster, gentity_s::think, level_locals_t::time, UnLockDoors(), gentity_s::use, and Use_BinaryMover_Go(). Referenced by Blocked_Door(), InitMover(), Touch_Button(), Touch_DoorTrigger(), and Touch_PlatCenterTrigger().
00854 {
00855 if ( !ent->use )
00856 {//I cannot be used anymore, must be a door with a wait of -1 that's opened.
00857 return;
00858 }
00859
00860 // only the master should be used
00861 if ( ent->flags & FL_TEAMSLAVE )
00862 {
00863 Use_BinaryMover( ent->teammaster, other, activator );
00864 return;
00865 }
00866
00867 if ( ent->flags & FL_INACTIVE )
00868 {
00869 return;
00870 }
00871
00872 if ( ent->spawnflags & MOVER_LOCKED )
00873 {//a locked door, unlock it
00874 UnLockDoors(ent);
00875 return;
00876 }
00877
00878 G_ActivateBehavior(ent,BSET_USE);
00879
00880 ent->enemy = other;
00881 ent->activator = activator;
00882 if(ent->delay)
00883 {
00884 ent->think = Use_BinaryMover_Go;
00885 ent->nextthink = level.time + ent->delay;
00886 }
00887 else
00888 {
00889 Use_BinaryMover_Go(ent);
00890 }
00891 }
|
|
|
Definition at line 700 of file g_mover.c. References acos(), gentity_s::activator, BMS_START, CalcTeamDoorCenter(), entityShared_t::currentOrigin, floor(), FRAMETIME, G_PlayDoorLoopSound(), G_PlayDoorSound(), G_UseTargets(), G_UseTargets2(), gentity_t, level, MatchTeam(), MOVER_1TO2, MOVER_2TO1, MOVER_POS1, MOVER_POS2, gentity_s::moverState, gentity_s::nextthink, entityState_s::pos, gentity_s::pos1, gentity_s::pos2, qtrue, gentity_s::r, RAD2DEG, ReturnToPos1(), gentity_s::s, gentity_s::spawnflags, gentity_s::target2, gentity_s::teammaster, gentity_s::think, entityState_s::time, level_locals_t::time, TR_NONLINEAR_STOP, trap_AdjustAreaPortalState(), trajectory_t::trDelta, trajectory_t::trDuration, trajectory_t::trTime, trajectory_t::trType, vec3_t, VectorScale, VectorSubtract, and gentity_s::wait. Referenced by Use_BinaryMover().
00701 {
00702 int total;
00703 int partial;
00704 // gentity_t *other = ent->enemy;
00705 gentity_t *activator = ent->activator;
00706
00707 ent->activator = activator;
00708
00709 if ( ent->moverState == MOVER_POS1 )
00710 {
00711 vec3_t doorcenter;
00712
00713 // start moving 50 msec later, becase if this was player
00714 // triggered, level.time hasn't been advanced yet
00715 MatchTeam( ent, MOVER_1TO2, level.time + 50 );
00716
00717 CalcTeamDoorCenter( ent, doorcenter );
00718
00719 // starting sound
00720 G_PlayDoorLoopSound( ent );
00721 G_PlayDoorSound( ent, BMS_START );
00722 ent->s.time = level.time;
00723
00724 // open areaportal
00725 if ( ent->teammaster == ent || !ent->teammaster ) {
00726 trap_AdjustAreaPortalState( ent, qtrue );
00727 }
00728 G_UseTargets( ent, ent->activator );
00729 return;
00730 }
00731
00732 // if all the way up, just delay before coming down
00733 if ( ent->moverState == MOVER_POS2 ) {
00734 //have to do this because the delay sets our think to Use_BinaryMover_Go
00735 ent->think = ReturnToPos1;
00736 if ( ent->spawnflags & 8 )
00737 {//TOGGLE doors don't use wait!
00738 ent->nextthink = level.time + FRAMETIME;
00739 }
00740 else
00741 {
00742 ent->nextthink = level.time + ent->wait;
00743 }
00744 G_UseTargets2( ent, ent->activator, ent->target2 );
00745 return;
00746 }
00747
00748 // only partway down before reversing
00749 if ( ent->moverState == MOVER_2TO1 )
00750 {
00751 if ( ent->s.pos.trType == TR_NONLINEAR_STOP )
00752 {
00753 vec3_t curDelta;
00754 float fPartial;
00755 total = ent->s.pos.trDuration-50;
00756 VectorSubtract( ent->r.currentOrigin, ent->pos1, curDelta );
00757 fPartial = VectorLength( curDelta )/VectorLength( ent->s.pos.trDelta );
00758 VectorScale( ent->s.pos.trDelta, fPartial, curDelta );
00759 fPartial /= ent->s.pos.trDuration;
00760 fPartial /= 0.001f;
00761 fPartial = acos( fPartial );
00762 fPartial = RAD2DEG( fPartial );
00763 fPartial = (90.0f - fPartial)/90.0f*ent->s.pos.trDuration;
00764 partial = total - floor( fPartial );
00765 }
00766 else
00767 {
00768 total = ent->s.pos.trDuration;
00769 partial = level.time - ent->s.pos.trTime;
00770 }
00771
00772 if ( partial > total ) {
00773 partial = total;
00774 }
00775 ent->s.pos.trTime = level.time - ( total - partial );//ent->s.time;
00776
00777 MatchTeam( ent, MOVER_1TO2, ent->s.pos.trTime );
00778
00779 G_PlayDoorSound( ent, BMS_START );
00780
00781 return;
00782 }
00783
00784 // only partway up before reversing
00785 if ( ent->moverState == MOVER_1TO2 )
00786 {
00787 if ( ent->s.pos.trType == TR_NONLINEAR_STOP )
00788 {
00789 vec3_t curDelta;
00790 float fPartial;
00791 total = ent->s.pos.trDuration-50;
00792 VectorSubtract( ent->r.currentOrigin, ent->pos2, curDelta );
00793 fPartial = VectorLength( curDelta )/VectorLength( ent->s.pos.trDelta );
00794 VectorScale( ent->s.pos.trDelta, fPartial, curDelta );
00795 fPartial /= ent->s.pos.trDuration;
00796 fPartial /= 0.001f;
00797 fPartial = acos( fPartial );
00798 fPartial = RAD2DEG( fPartial );
00799 fPartial = (90.0f - fPartial)/90.0f*ent->s.pos.trDuration;
00800 partial = total - floor( fPartial );
00801 }
00802 else
00803 {
00804 total = ent->s.pos.trDuration;
00805 partial = level.time - ent->s.pos.trTime;
00806 }
00807 if ( partial > total ) {
00808 partial = total;
00809 }
00810
00811 ent->s.pos.trTime = level.time - ( total - partial );//ent->s.time;
00812 MatchTeam( ent, MOVER_2TO1, ent->s.pos.trTime );
00813
00814 G_PlayDoorSound( ent, BMS_START );
00815
00816 return;
00817 }
00818 }
|
|
||||||||||||||||
|
Definition at line 3201 of file g_mover.c. References BSET_USE, entityShared_t::contents, CONTENTS_SOLID, EF_NODRAW, entityState_s::eFlags, G_ActivateBehavior(), gentity_t, qfalse, qtrue, gentity_s::r, gentity_s::s, gentity_s::spawnflags, SVF_NOCLIENT, entityShared_t::svFlags, and trap_AdjustAreaPortalState(). Referenced by SP_func_wall().
03202 {
03203 G_ActivateBehavior(ent,BSET_USE);
03204
03205 // Not there so make it there
03206 if (!(ent->r.contents & CONTENTS_SOLID))
03207 {
03208 ent->r.svFlags &= ~SVF_NOCLIENT;
03209 ent->s.eFlags &= ~EF_NODRAW;
03210 ent->r.contents = CONTENTS_SOLID;
03211 if ( !(ent->spawnflags&1) )
03212 {//START_OFF doesn't effect area portals
03213 trap_AdjustAreaPortalState( ent, qfalse );
03214 }
03215 }
03216 // Make it go away
03217 else
03218 {
03219 ent->r.contents = 0;
03220 ent->r.svFlags |= SVF_NOCLIENT;
03221 ent->s.eFlags |= EF_NODRAW;
03222 if ( !(ent->spawnflags&1) )
03223 {//START_OFF doesn't effect area portals
03224 trap_AdjustAreaPortalState( ent, qtrue );
03225 }
03226 }
03227 }
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 24 of file g_mover.c. Referenced by G_MoverPush(), G_MoverTeam(), and G_TryPushingEntity(). |
|
|
Definition at line 24 of file g_mover.c. Referenced by G_MoverPush(), G_MoverTeam(), and G_TryPushingEntity(). |