void CItem::ItemTouch(CBaseEntity *pOther) { if (!pOther->IsPlayer()) return; CBasePlayer *pPlayer = (CBasePlayer *)pOther; if (!g_pGameRules->CanHaveItem(pPlayer, this)) return; if (MyTouch(pPlayer)) { SUB_UseTargets(pOther, USE_TOGGLE, 0); SetTouch(NULL); g_pGameRules->PlayerGotItem(pPlayer, this); if (g_pGameRules->ItemShouldRespawn(this) == GR_ITEM_RESPAWN_YES) Respawn(); else UTIL_Remove(this); } else if (gEvilImpulse101) UTIL_Remove(this); }
void CGERocket::Spawn( void ) { Precache(); BaseClass::Spawn(); m_takedamage = DAMAGE_YES; m_iHealth = 1; m_bHitPlayer = false; // Default Damages they should be modified by the thrower SetDamage( 512 ); SetDamageRadius( 125 ); SetModel( "models/weapons/rocket_launcher/w_rocket.mdl" ); // Init our physics definition SetSolid( SOLID_VPHYSICS ); SetMoveType( MOVETYPE_FLY ); // So NPC's can "see" us AddFlag( FL_OBJECT ); // UTIL_SetSize( this, Vector(-10,-5,-5), Vector(10,5,5) ); SetCollisionGroup( COLLISION_GROUP_GRENADE ); SetThink( &CGERocket::IgniteThink ); SetNextThink( gpGlobals->curtime ); m_flSpawnTime = gpGlobals->curtime; // Explode if we hit anything solid SetTouch( &CGERocket::ExplodeTouch ); AddSolidFlags( FSOLID_NOT_STANDABLE ); }
void CItemSoda::CanTouch ( CBaseEntity *pOther ) { if ( !pOther->IsPlayer() ) { return; } // spoit sound here pOther->TakeHealth( 1, DMG_GENERIC );// a bit of health. if ( !FNullEnt( pev->owner ) ) { // tell the machine the can was taken pev->owner->v.frags = 0; } pev->solid = SOLID_NOT; pev->movetype = MOVETYPE_NONE; pev->effects = EF_NODRAW; SetTouch ( NULL ); SetThink ( SUB_Remove ); pev->nextthink = gpGlobals->time; }
void CBaseGrenadeConcussion::Spawn( void ) { // point sized, solid, bouncing SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); SetSolid( SOLID_BBOX ); SetCollisionGroup( COLLISION_GROUP_PROJECTILE ); SetModel( "models/weapons/w_grenade.mdl" ); // BUG: wrong model UTIL_SetSize(this, vec3_origin, vec3_origin); // contact grenades arc lower SetGravity( UTIL_ScaleForGravity( 400 ) ); // use a lower gravity for grenades to make them easier to see QAngle angles; VectorAngles(GetAbsVelocity(), angles ); SetLocalAngles( angles ); m_nRenderFX = kRenderFxGlowShell; SetRenderColor( 200, 200, 20 ); SetRenderAlpha( 255 ); // make NPCs afaid of it while in the air SetThink( &CBaseGrenadeConcussion::FallThink ); SetNextThink( gpGlobals->curtime ); // Tumble in air QAngle vecAngVel( random->RandomFloat ( -100, -500 ), 0, 0 ); SetLocalAngularVelocity( vecAngVel ); // Explode on contact SetTouch( &CBaseGrenadeConcussion::ExplodeConcussion ); m_flDamage = 80; // Allow player to blow this puppy up in the air m_takedamage = DAMAGE_YES; }
// // The door has reached the "up" position. Either go back down, or wait for another activation. // void CBaseDoor::DoorHitTop( void ) { if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) { STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) ); EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseArrived), 1, ATTN_NORM); } ASSERT(m_toggle_state == TS_GOING_UP); m_toggle_state = TS_AT_TOP; // toggle-doors don't come down automatically, they wait for refire. if (FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN)) { // Re-instate touch method, movement is complete if ( !FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ) SetTouch( DoorTouch ); } else { // In flWait seconds, DoorGoDown will fire, unless wait is -1, then door stays open pev->nextthink = pev->ltime + m_flWait; SetThink( DoorGoDown ); if ( m_flWait == -1 ) { pev->nextthink = -1; } } // Fire the close target (if startopen is set, then "top" is closed) - netname is the close target if ( pev->netname && (pev->spawnflags & SF_DOOR_START_OPEN) ) FireTargets( STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0 ); SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished }
/* <26e90> ../cstrike/dlls/buttons.cpp:394 */ int CBaseButton::__MAKE_VHOOK(TakeDamage)(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { BUTTON_CODE code = ButtonResponseToTouch(); if (code == BUTTON_NOTHING) { return 0; } // Temporarily disable the touch function, until movement is finished. SetTouch(NULL); m_hActivator = CBaseEntity::Instance(pevAttacker); if (m_hActivator == NULL) return 0; if (code == BUTTON_RETURN) { EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); // Toggle buttons fire when they get back to their "home" position if (!(pev->spawnflags & SF_BUTTON_TOGGLE)) { SUB_UseTargets(m_hActivator, USE_TOGGLE, 0); } ButtonReturn(); } else { // code == BUTTON_ACTIVATE ButtonActivate(); } return 0; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CShieldGrenade::Spawn( void ) { BaseClass::Spawn(); m_LastCollision.Init( 0, 0, 0 ); SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); SetSolid( SOLID_BBOX ); SetGravity( 1.0 ); SetFriction( 0.9 ); SetModel( "models/weapons/w_grenade.mdl"); UTIL_SetSize(this, Vector( -4, -4, -4), Vector(4, 4, 4)); m_IsEMPed = false; m_IsDeployed = false; m_flEMPDamageEndTime = 0.0f; SetTouch( StickyTouch ); SetCollisionGroup( TFCOLLISION_GROUP_GRENADE ); // Create a green light m_pLiveSprite = CSprite::SpriteCreate( "sprites/redglow1.vmt", GetLocalOrigin() + Vector(0,0,1), false ); m_pLiveSprite->SetTransparency( kRenderGlow, 0, 0, 255, 128, kRenderFxNoDissipation ); m_pLiveSprite->SetScale( 1 ); m_pLiveSprite->SetAttachment( this, 0 ); }
void CSqueakGrenade :: Spawn( void ) { Precache( ); // motor pev->movetype = MOVETYPE_BOUNCE; pev->solid = SOLID_BBOX; SET_MODEL(ENT(pev), "models/w_squeak.mdl"); UTIL_SetSize(pev, Vector( -4, -4, 0), Vector(4, 4, 8)); UTIL_SetOrigin( pev, pev->origin ); SetTouch( SuperBounceTouch ); SetThink( HuntThink ); pev->nextthink = gpGlobals->time + 0.1; m_flNextHunt = gpGlobals->time + 1E6; pev->flags |= FL_MONSTER; pev->takedamage = DAMAGE_AIM; pev->health = gSkillData.snarkHealth; pev->gravity = 0.5; pev->friction = 0.5; pev->dmg = gSkillData.snarkDmgPop; m_flDie = gpGlobals->time + SQUEEK_DETONATE_DELAY; m_flFieldOfView = 0; // 180 degrees if ( pev->owner ) m_hOwner = Instance( pev->owner ); m_flNextBounceSoundTime = gpGlobals->time;// reset each time a snark is spawned. pev->sequence = WSQUEAK_RUN; ResetSequenceInfo( ); }
CBaseEntity* CItem::Respawn( void ) { SetTouch( NULL ); AddEffects( EF_NODRAW ); VPhysicsDestroyObject(); SetMoveType( MOVETYPE_NONE ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_TRIGGER ); UTIL_SetOrigin( this, g_pGameRules->VecItemRespawnSpot( this ) );// blip to whereever you should respawn. SetAbsAngles( g_pGameRules->VecItemRespawnAngles( this ) );// set the angles. #if !defined( TF_DLL ) UTIL_DropToFloor( this, MASK_SOLID ); #endif RemoveAllDecals(); //remove any decals SetThink ( &CItem::Materialize ); SetNextThink( gpGlobals->curtime + g_pGameRules->FlItemRespawnTime( this ) ); return this; }
void CGrappleHook::Killed(entvars_t *pev, int gib) { ALERT( at_console, "^2HLU -> ^3weapon_grapple ^2-> Tongue was killed.\n"); // Fograin92: Clear player myowner->pev->movetype = MOVETYPE_WALK; //Re-apply gravity myowner->m_afPhysicsFlags &= ~PFLAG_ON_GRAPPLE; //Remove "on grapple" flag myowner->m_iGrappleExists = 0; myowner->m_flNextAttack = UTIL_WeaponTimeBase() + 1.0; // Fograin92: Clear monster if( (m_iHitMonster == 2) && (myHitMonster->IsAlive()) ) myHitMonster->pev->movetype = MOVETYPE_STEP; // Re-apply gravity to the pulled monster, if it's alive // Fograin92: Clear tongue leftovers bPullBack = false; UTIL_Remove( m_pTongue ); m_pTongue = NULL; m_iHitMonster = 0; SetThink(NULL); SetTouch(NULL); SUB_Remove( ); }
// // Throw a chunk // void CGib :: Spawn( const char *szGibModel ) { pev->movetype = MOVETYPE_BOUNCE; pev->friction = 0.55; // deading the bounce a bit // sometimes an entity inherits the edict from a former piece of glass, // and will spawn using the same render FX or rendermode! bad! pev->renderamt = 255; pev->rendermode = kRenderNormal; pev->renderfx = kRenderFxNone; pev->solid = SOLID_SLIDEBOX;/// hopefully this will fix the VELOCITY TOO LOW crap pev->classname = MAKE_STRING("gib"); SET_MODEL(ENT(pev), szGibModel); UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0)); pev->nextthink = gpGlobals->time + 4; m_lifeTime = 25; SetThink ( &CGib::WaitTillLand ); SetTouch ( &CGib::BounceGibTouch ); m_material = matNone; m_cBloodDecals = 5;// how many blood decals this gib can place (1 per bounce until none remain). }
//========================================================= // Randomly decide what powerup to be void CDiscwarPowerup::ChoosePowerupThink(void) { int iPowerup = RANDOM_LONG(0, NUM_POWERUPS - 1); m_iPowerupType = (1 << iPowerup); SET_MODEL(ENT(pev), szPowerupModels[iPowerup]); pev->effects &= ~EF_NODRAW; SetTouch(&CDiscwarPowerup::PowerupTouch); // Start Animating pev->sequence = 0; pev->frame = 0; ResetSequenceInfo(); SetThink(&CDiscwarPowerup::AnimateThink); pev->nextthink = gpGlobals->time + 0.1; pev->rendermode = kRenderTransAdd; pev->renderamt = 150; // Play the powerup appear sound EMIT_SOUND_DYN(edict(), CHAN_STATIC, "pspawn.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0, 3)); }
void CApache :: Spawn( void ) { Precache( ); // motor pev->movetype = MOVETYPE_FLY; pev->solid = SOLID_BBOX; SET_MODEL(ENT(pev), "models/apache.mdl"); UTIL_SetSize( pev, Vector( -32, -32, -64 ), Vector( 32, 32, 0 ) ); UTIL_SetOrigin( pev, pev->origin ); pev->flags |= FL_MONSTER; pev->takedamage = DAMAGE_AIM; pev->health = gSkillData.apacheHealth; m_flFieldOfView = -0.707; // 270 degrees pev->sequence = 0; ResetSequenceInfo( ); pev->frame = RANDOM_LONG(0, 0xFF); InitBoneControllers(); if (pev->spawnflags & SF_WAITFORTRIGGER) { SetUse( &CApache::StartupUse ); } else { SetThink( &CApache::HuntThink ); SetTouch( &CApache::FlyTouch ); pev->nextthink = gpGlobals->time + 1.0; } m_iRockets = 10; }
void CSatchelCharge :: Spawn( void ) { Precache( ); // motor pev->movetype = MOVETYPE_BOUNCE; pev->solid = SOLID_BBOX; SET_MODEL(ENT(pev), "models/w_satchel.mdl"); //UTIL_SetSize(pev, Vector( -16, -16, -4), Vector(16, 16, 32)); // Old box -- size of headcrab monsters/players get blocked by this UTIL_SetSize(pev, Vector( -4, -4, -4), Vector(4, 4, 4)); // Uses point-sized, and can be stepped over UTIL_SetOrigin( pev, pev->origin ); SetTouch(&CSatchelCharge::SatchelSlide ); SetUse(&CGrenade::DetonateUse ); SetThink(&CSatchelCharge::SatchelThink ); pev->nextthink = gpGlobals->time + 0.1; pev->gravity = 0.5; pev->friction = 0.8; pev->dmg = gSkillData.plrDmgSatchel; // ResetSequenceInfo( ); pev->sequence = 1; }
void CBasePlayerItem::Kill( void ) { SetTouch( NULL ); SetThink(SUB_Remove); pev->nextthink = gpGlobals->time + .1; }
//========================================================= // CWeaponBox - Touch: try to add my contents to the toucher // if the toucher is a player. //========================================================= void CWeaponBox::Touch( CBaseEntity *pOther ) { if ( !(pev->flags & FL_ONGROUND ) ) { return; } if ( !pOther->IsPlayer() ) { // only players may touch a weaponbox. return; } if ( !pOther->IsAlive() ) { // no dead guys. return; } CBasePlayer *pPlayer = (CBasePlayer *)pOther; int i; // dole out ammo for ( i = 0 ; i < MAX_AMMO_SLOTS ; i++ ) { if ( !FStringNull( m_rgiszAmmo[ i ] ) ) { // there's some ammo of this type. pPlayer->GiveAmmo( m_rgAmmo[ i ], (char *)STRING( m_rgiszAmmo[ i ] ), MaxAmmoCarry( m_rgiszAmmo[ i ] ) ); //ALERT ( at_console, "Gave %d rounds of %s\n", m_rgAmmo[i], STRING(m_rgiszAmmo[i]) ); // now empty the ammo from the weaponbox since we just gave it to the player m_rgiszAmmo[ i ] = iStringNull; m_rgAmmo[ i ] = 0; } } // go through my weapons and try to give the usable ones to the player. // it's important the the player be given ammo first, so the weapons code doesn't refuse // to deploy a better weapon that the player may pick up because he has no ammo for it. for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) { if ( m_rgpPlayerItems[ i ] ) { CBasePlayerItem *pItem; // have at least one weapon in this slot while ( m_rgpPlayerItems[ i ] ) { //ALERT ( at_console, "trying to give %s\n", STRING( m_rgpPlayerItems[ i ]->pev->classname ) ); pItem = m_rgpPlayerItems[ i ]; m_rgpPlayerItems[ i ] = m_rgpPlayerItems[ i ]->m_pNext;// unlink this weapon from the box if ( pPlayer->AddPlayerItem( pItem ) ) { pItem->AttachToPlayer( pPlayer ); } } } } EMIT_SOUND( pOther->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); SetTouch(NULL); UTIL_Remove(this); }
//========================================================= //========================================================= void CHornet :: Spawn( void ) { Precache(); pev->movetype = MOVETYPE_FLY; pev->solid = SOLID_BBOX; pev->takedamage = DAMAGE_YES; pev->flags |= FL_MONSTER; pev->health = 1;// weak! if ( g_pGameRules->IsMultiplayer() ) { // hornets don't live as long in multiplayer m_flStopAttack = gpGlobals->time + 3.5; } else { m_flStopAttack = gpGlobals->time + 5.0; } m_flFieldOfView = 0.9; // +- 25 degrees if ( RANDOM_LONG ( 1, 5 ) <= 2 ) { m_iHornetType = HORNET_TYPE_RED; m_flFlySpeed = HORNET_RED_SPEED; } else { m_iHornetType = HORNET_TYPE_ORANGE; m_flFlySpeed = HORNET_ORANGE_SPEED; } SET_MODEL(ENT( pev ), "models/hornet.mdl"); UTIL_SetSize( pev, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ) ); SetTouch( DieTouch ); SetThink( StartTrack ); edict_t *pSoundEnt = pev->owner; if ( !pSoundEnt ) pSoundEnt = edict(); switch (RANDOM_LONG(0,2)) { case 0: EMIT_SOUND( pSoundEnt, CHAN_WEAPON, "agrunt/ag_fire1.wav", 1, ATTN_NORM); break; case 1: EMIT_SOUND( pSoundEnt, CHAN_WEAPON, "agrunt/ag_fire2.wav", 1, ATTN_NORM); break; case 2: EMIT_SOUND( pSoundEnt, CHAN_WEAPON, "agrunt/ag_fire3.wav", 1, ATTN_NORM); break; } if ( !FNullEnt(pev->owner) && (pev->owner->v.flags & FL_CLIENT) ) { pev->dmg = gSkillData.plrDmgHornet; } else { // no real owner, or owner isn't a client. pev->dmg = gSkillData.monDmgHornet; } pev->nextthink = gpGlobals->time + 0.1; ResetSequenceInfo( ); }
//========================================================= // Hornet is flying, gently tracking target //========================================================= void CHornet :: TrackTarget ( void ) { Vector vecFlightDir; Vector vecDirToEnemy; float flDelta; StudioFrameAdvance( ); if (gpGlobals->time > m_flStopAttack) { SetTouch( NULL ); SetThink( SUB_Remove ); pev->nextthink = gpGlobals->time + 0.1; return; } // UNDONE: The player pointer should come back after returning from another level if ( m_hEnemy == NULL ) {// enemy is dead. Look( 512 ); m_hEnemy = BestVisibleEnemy( ); } if ( m_hEnemy != NULL && FVisible( m_hEnemy )) { m_vecEnemyLKP = m_hEnemy->BodyTarget( GetAbsOrigin() ); } else { m_vecEnemyLKP = m_vecEnemyLKP + GetAbsVelocity() * m_flFlySpeed * 0.1; } vecDirToEnemy = ( m_vecEnemyLKP - GetAbsOrigin() ).Normalize(); if (GetAbsVelocity().Length() < 0.1) vecFlightDir = vecDirToEnemy; else vecFlightDir = GetAbsVelocity().Normalize(); // measure how far the turn is, the wider the turn, the slow we'll go this time. flDelta = DotProduct ( vecFlightDir, vecDirToEnemy ); if ( flDelta < 0.5 ) {// hafta turn wide again. play sound switch (RANDOM_LONG(0,2)) { case 0: EMIT_SOUND( ENT(pev), CHAN_VOICE, "hornet/ag_buzz1.wav", HORNET_BUZZ_VOLUME, ATTN_NORM); break; case 1: EMIT_SOUND( ENT(pev), CHAN_VOICE, "hornet/ag_buzz2.wav", HORNET_BUZZ_VOLUME, ATTN_NORM); break; case 2: EMIT_SOUND( ENT(pev), CHAN_VOICE, "hornet/ag_buzz3.wav", HORNET_BUZZ_VOLUME, ATTN_NORM); break; } } if ( flDelta <= 0 && m_iHornetType == HORNET_TYPE_RED ) {// no flying backwards, but we don't want to invert this, cause we'd go fast when we have to turn REAL far. flDelta = 0.25; } SetAbsVelocity(( vecFlightDir + vecDirToEnemy).Normalize() ); if( pev->owner && ( pev->owner->v.flags & FL_MONSTER )) { // random pattern only applies to hornets fired by monsters, not players. Vector vecVelocity = GetAbsVelocity(); vecVelocity.x += RANDOM_FLOAT ( -0.10, 0.10 );// scramble the flight dir a bit. vecVelocity.y += RANDOM_FLOAT ( -0.10, 0.10 ); vecVelocity.z += RANDOM_FLOAT ( -0.10, 0.10 ); SetAbsVelocity( vecVelocity ); } switch ( m_iHornetType ) { case HORNET_TYPE_RED: SetAbsVelocity( GetAbsVelocity() * ( m_flFlySpeed * flDelta ));// scale the dir by the ( speed * width of turn ) pev->nextthink = gpGlobals->time + RANDOM_FLOAT( 0.1, 0.3 ); break; case HORNET_TYPE_ORANGE: SetAbsVelocity( GetAbsVelocity() * m_flFlySpeed ); // do not have to slow down to turn. pev->nextthink = gpGlobals->time + 0.1;// fixed think time break; } SetAbsAngles( UTIL_VecToAngles( GetAbsVelocity())); pev->solid = SOLID_BBOX; // if hornet is close to the enemy, jet in a straight line for a half second. // (only in the single player game) if ( m_hEnemy != NULL && !g_pGameRules->IsMultiplayer() ) { if ( flDelta >= 0.4 && ( GetAbsOrigin() - m_vecEnemyLKP ).Length() <= 300 ) { Vector vecOrigin = GetAbsOrigin(); MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecOrigin ); WRITE_BYTE( TE_SPRITE ); WRITE_COORD( vecOrigin.x ); // pos WRITE_COORD( vecOrigin.y ); WRITE_COORD( vecOrigin.z ); WRITE_SHORT( iHornetPuff ); // model // WRITE_BYTE( 0 ); // life * 10 WRITE_BYTE( 2 ); // size * 10 WRITE_BYTE( 128 ); // brightness MESSAGE_END(); switch( RANDOM_LONG( 0, 2 )) { case 0: EMIT_SOUND( ENT(pev), CHAN_VOICE, "hornet/ag_buzz1.wav", HORNET_BUZZ_VOLUME, ATTN_NORM ); break; case 1: EMIT_SOUND( ENT(pev), CHAN_VOICE, "hornet/ag_buzz2.wav", HORNET_BUZZ_VOLUME, ATTN_NORM ); break; case 2: EMIT_SOUND( ENT(pev), CHAN_VOICE, "hornet/ag_buzz3.wav", HORNET_BUZZ_VOLUME, ATTN_NORM ); break; } SetAbsVelocity( GetAbsVelocity() * 2 ); pev->nextthink = gpGlobals->time + 1.0; // don't attack again m_flStopAttack = gpGlobals->time; } } }
void CGrenadeAR2::Spawn( void ) { Precache( ); SetSolid( SOLID_BBOX ); SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); // Hits everything but debris SetCollisionGroup( COLLISION_GROUP_PROJECTILE ); SetModel( "models/Weapons/ar2_grenade.mdl"); UTIL_SetSize(this, Vector(-3, -3, -3), Vector(3, 3, 3)); // UTIL_SetSize(this, Vector(0, 0, 0), Vector(0, 0, 0)); SetUse( &CGrenadeAR2::DetonateUse ); SetTouch( &CGrenadeAR2::GrenadeAR2Touch ); SetThink( &CGrenadeAR2::GrenadeAR2Think ); SetNextThink( gpGlobals->curtime + 0.1f ); if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() ) { m_flDamage = sk_plr_dmg_smg1_grenade.GetFloat(); } else { m_flDamage = sk_npc_dmg_smg1_grenade.GetFloat(); } m_DmgRadius = sk_smg1_grenade_radius.GetFloat(); m_takedamage = DAMAGE_YES; m_bIsLive = true; m_iHealth = 1; SetGravity( UTIL_ScaleForGravity( 400 ) ); // use a lower gravity for grenades to make them easier to see SetFriction( 0.8 ); SetSequence( 0 ); m_fDangerRadius = 100; m_fSpawnTime = gpGlobals->curtime; // ------------- // Smoke trail. // ------------- if( g_CV_SmokeTrail.GetInt() && !IsXbox() ) { m_hSmokeTrail = SmokeTrail::CreateSmokeTrail(); if( m_hSmokeTrail ) { m_hSmokeTrail->m_SpawnRate = 48; m_hSmokeTrail->m_ParticleLifetime = 1; m_hSmokeTrail->m_StartColor.Init(0.1f, 0.1f, 0.1f); m_hSmokeTrail->m_EndColor.Init(0,0,0); m_hSmokeTrail->m_StartSize = 12; m_hSmokeTrail->m_EndSize = m_hSmokeTrail->m_StartSize * 4; m_hSmokeTrail->m_SpawnRadius = 4; m_hSmokeTrail->m_MinSpeed = 4; m_hSmokeTrail->m_MaxSpeed = 24; m_hSmokeTrail->m_Opacity = 0.2f; m_hSmokeTrail->SetLifetime(10.0f); m_hSmokeTrail->FollowEntity(this); } } }
void CHL1BaseGrenade::Explode( trace_t *pTrace, int bitsDamageType ) { float flRndSound;// sound randomizer SetModelName( NULL_STRING );//invisible AddSolidFlags( FSOLID_NOT_SOLID ); m_takedamage = DAMAGE_NO; // Pull out of the wall a bit if ( pTrace->fraction != 1.0 ) { SetLocalOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) ); } UTIL_Relink( this ); Vector vecAbsOrigin = GetAbsOrigin(); int contents = UTIL_PointContents ( vecAbsOrigin ); if ( pTrace->fraction != 1.0 ) { Vector vecNormal = pTrace->plane.normal; surfacedata_t *pdata = physprops->GetSurfaceData( pTrace->surface.surfaceProps ); CPASFilter filter( vecAbsOrigin ); te->Explosion( filter, 0.0, &vecAbsOrigin, !( contents & MASK_WATER ) ? g_sModelIndexFireball : g_sModelIndexWExplosion, m_DmgRadius * .03, 25, TE_EXPLFLAG_NONE, m_DmgRadius, m_flDamage, &vecNormal, (char) pdata->gameMaterial ); } else { CPASFilter filter( vecAbsOrigin ); te->Explosion( filter, 0.0, &vecAbsOrigin, !( contents & MASK_WATER ) ? g_sModelIndexFireball : g_sModelIndexWExplosion, m_DmgRadius * .03, 25, TE_EXPLFLAG_NONE, m_DmgRadius, m_flDamage ); } CSoundEnt::InsertSound ( SOUND_COMBAT, GetAbsOrigin(), BASEGRENADE_EXPLOSION_VOLUME, 3.0 ); // Use the owner's position as the reported position Vector vecReported = GetOwner() ? GetOwner()->GetAbsOrigin() : vec3_origin; CTakeDamageInfo info( this, GetOwner(), GetBlastForce(), GetAbsOrigin(), m_flDamage, bitsDamageType, 0, &vecReported ); RadiusDamage( info, GetAbsOrigin(), m_DmgRadius, CLASS_NONE ); UTIL_DecalTrace( pTrace, "Scorch" ); flRndSound = random->RandomFloat( 0 , 1 ); EmitSound( "BaseGrenade.Explode" ); SetTouch( NULL ); m_fEffects |= EF_NODRAW; SetAbsVelocity( vec3_origin ); SetThink( Smoke ); SetNextThink( gpGlobals->curtime + 0.3); if ( GetWaterLevel() == 0 ) { int sparkCount = random->RandomInt( 0,3 ); QAngle angles; VectorAngles( pTrace->plane.normal, angles ); for ( int i = 0; i < sparkCount; i++ ) Create( "spark_shower", GetAbsOrigin(), angles, NULL ); } }
void CSnark::HuntThink( void ) { if (!IsInWorld()) { SetTouch( NULL ); UTIL_Remove( this ); return; } StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1f ); // explode when ready if ( gpGlobals->curtime >= m_flDie ) { g_vecAttackDir = GetAbsVelocity(); VectorNormalize( g_vecAttackDir ); m_iHealth = -1; CTakeDamageInfo info( this, this, 1, DMG_GENERIC ); Event_Killed( info ); return; } // float if ( GetWaterLevel() != 0) { if ( GetMoveType() == MOVETYPE_FLYGRAVITY ) { SetMoveType( MOVETYPE_FLY, MOVECOLLIDE_FLY_BOUNCE ); } Vector vecVel = GetAbsVelocity(); vecVel *= 0.9; vecVel.z += 8.0; SetAbsVelocity( vecVel ); } else if ( GetMoveType() == MOVETYPE_FLY ) { SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); } // return if not time to hunt if ( m_flNextHunt > gpGlobals->curtime ) return; m_flNextHunt = gpGlobals->curtime + 2.0; Vector vecFlat = GetAbsVelocity(); vecFlat.z = 0; VectorNormalize( vecFlat ); if ( GetEnemy() == NULL || !GetEnemy()->IsAlive() ) { // find target, bounce a bit towards it. GetSenses()->Look( 512 ); SetEnemy( BestEnemy() ); } // squeek if it's about time blow up if ( (m_flDie - gpGlobals->curtime <= 0.5) && (m_flDie - gpGlobals->curtime >= 0.3) ) { CPASAttenuationFilter filter( this ); enginesound->EmitSound( filter, entindex(), CHAN_VOICE, "squeek/sqk_die1.wav", 1, ATTN_NORM, 0, 100 + random->RandomInt( 0, 0x3F ) ); CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 256, 0.25 ); } // higher pitch as squeeker gets closer to detonation time float flpitch = 155.0 - 60.0 * ( (m_flDie - gpGlobals->curtime) / SQUEEK_DETONATE_DELAY ); if ( flpitch < 80 ) flpitch = 80; if ( GetEnemy() != NULL ) { if ( FVisible( GetEnemy() ) ) { m_vecTarget = GetEnemy()->EyePosition() - GetAbsOrigin(); VectorNormalize( m_vecTarget ); } float flVel = GetAbsVelocity().Length(); float flAdj = 50.0 / ( flVel + 10.0 ); if ( flAdj > 1.2 ) flAdj = 1.2; // ALERT( at_console, "think : enemy\n"); // ALERT( at_console, "%.0f %.2f %.2f %.2f\n", flVel, m_vecTarget.x, m_vecTarget.y, m_vecTarget.z ); SetAbsVelocity( GetAbsVelocity() * flAdj + (m_vecTarget * 300) ); } if ( GetFlags() & FL_ONGROUND ) { SetLocalAngularVelocity( QAngle( 0, 0, 0 ) ); } else { QAngle angVel = GetLocalAngularVelocity(); if ( angVel == QAngle( 0, 0, 0 ) ) { angVel.x = random->RandomFloat( -100, 100 ); angVel.z = random->RandomFloat( -100, 100 ); SetLocalAngularVelocity( angVel ); } } if ( ( GetAbsOrigin() - m_posPrev ).Length() < 1.0 ) { Vector vecVel = GetAbsVelocity(); vecVel.x = random->RandomFloat( -100, 100 ); vecVel.y = random->RandomFloat( -100, 100 ); SetAbsVelocity( vecVel ); } m_posPrev = GetAbsOrigin(); QAngle angles; VectorAngles( GetAbsVelocity(), angles ); angles.z = 0; angles.x = 0; SetAbsAngles( angles ); }
void CFuncRotating :: Spawn( ) { // set final pitch. Must not be PITCH_NORM, since we // plan on pitch shifting later. m_pitch = PITCH_NORM - 1; // maintain compatibility with previous maps if (m_flVolume == 0.0) m_flVolume = 1.0; // if the designer didn't set a sound attenuation, default to one. m_flAttenuation = ATTN_NORM; if ( FBitSet ( pev->spawnflags, SF_BRUSH_ROTATE_SMALLRADIUS) ) { m_flAttenuation = ATTN_IDLE; } else if ( FBitSet ( pev->spawnflags, SF_BRUSH_ROTATE_MEDIUMRADIUS) ) { m_flAttenuation = ATTN_STATIC; } else if ( FBitSet ( pev->spawnflags, SF_BRUSH_ROTATE_LARGERADIUS) ) { m_flAttenuation = ATTN_NORM; } // prevent divide by zero if level designer forgets friction! if ( m_flFanFriction == 0 ) { m_flFanFriction = 1; } if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_Z_AXIS) ) pev->movedir = Vector(0,0,1); else if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_X_AXIS) ) pev->movedir = Vector(1,0,0); else pev->movedir = Vector(0,1,0); // y-axis // check for reverse rotation if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_BACKWARDS) ) pev->movedir = pev->movedir * -1; // some rotating objects like fake volumetric lights will not be solid. if ( FBitSet(pev->spawnflags, SF_ROTATING_NOT_SOLID) ) { pev->solid = SOLID_NOT; pev->skin = CONTENTS_EMPTY; pev->movetype = MOVETYPE_PUSH; } else { pev->solid = SOLID_BSP; pev->movetype = MOVETYPE_PUSH; } UTIL_SetOrigin(pev, pev->origin); SET_MODEL( ENT(pev), STRING(pev->model) ); SetUse( RotatingUse ); // did level designer forget to assign speed? if (pev->speed <= 0) pev->speed = 0; // Removed this per level designers request. -- JAY // if (pev->dmg == 0) // pev->dmg = 2; // instant-use brush? if ( FBitSet( pev->spawnflags, SF_BRUSH_ROTATE_INSTANT) ) { SetThink( SUB_CallUseToggle ); pev->nextthink = pev->ltime + 1.5; // leave a magic delay for client to start up } // can this brush inflict pain? if ( FBitSet (pev->spawnflags, SF_BRUSH_HURT) ) { SetTouch( HurtTouch ); } Precache( ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CItem::Spawn( void ) { SetNetworkQuantizeOriginAngAngles( true ); if ( g_pGameRules->IsAllowedToSpawn( this ) == false ) { UTIL_Remove( this ); return; } SetMoveType( MOVETYPE_FLYGRAVITY ); SetSolid( SOLID_BBOX ); SetBlocksLOS( false ); AddEFlags( EFL_NO_ROTORWASH_PUSH ); if( IsX360() ) { AddEffects( EF_ITEM_BLINK ); } // This will make them not collide with the player, but will collide // against other items + weapons SetCollisionGroup( COLLISION_GROUP_WEAPON ); if( HasBloatedCollision() ) { CollisionProp()->UseTriggerBounds( true, ITEM_PICKUP_BOX_BLOAT ); } SetTouch(&CItem::ItemTouch); if ( CreateItemVPhysicsObject() == false ) { return; } m_takedamage = DAMAGE_EVENTS_ONLY; #if !defined( CLIENT_DLL ) // Constrained start? if ( HasSpawnFlags( SF_ITEM_START_CONSTRAINED ) ) { //Constrain the weapon in place IPhysicsObject *pReferenceObject, *pAttachedObject; pReferenceObject = g_PhysWorldObject; pAttachedObject = VPhysicsGetObject(); if ( pReferenceObject && pAttachedObject ) { constraint_fixedparams_t fixed; fixed.Defaults(); fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject ); fixed.constraint.forceLimit = lbs2kg( 10000 ); fixed.constraint.torqueLimit = lbs2kg( 10000 ); m_pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed ); m_pConstraint->SetGameData( (void *) this ); } } #endif //CLIENT_DLL Vector origin = GetAbsOrigin(); QAngle angles = GetAbsAngles(); NetworkQuantize( origin, angles ); SetAbsOrigin( origin ); SetAbsAngles( angles ); }
BOOL CBaseMonster::CineCleanup() { CCineMonster *pOldCine = m_pCine; // am I linked to a cinematic? if(m_pCine) { // okay, reset me to what it thought I was before m_pCine->m_hTargetEnt = NULL; pev->movetype = m_pCine->m_saved_movetype; pev->solid = m_pCine->m_saved_solid; pev->effects = m_pCine->m_saved_effects; } else { // arg, punt pev->movetype = MOVETYPE_STEP; // this is evil pev->solid = SOLID_SLIDEBOX; } m_pCine = NULL; m_hTargetEnt = NULL; m_pGoalEnt = NULL; if(pev->deadflag == DEAD_DYING) { // last frame of death animation? pev->health = 0; pev->framerate = 0.0; pev->solid = SOLID_NOT; SetState(MONSTERSTATE_DEAD); pev->deadflag = DEAD_DEAD; UTIL_SetSize(pev, pev->mins, Vector(pev->maxs.x, pev->maxs.y, pev->mins.z + 2)); if(pOldCine && FBitSet(pOldCine->pev->spawnflags, SF_SCRIPT_LEAVECORPSE)) { SetUse(NULL); // BUGBUG -- This doesn't call Killed() SetThink(NULL); // This will probably break some stuff SetTouch(NULL); } else SUB_StartFadeOut(); // SetThink( SUB_DoNothing ); // This turns off animation & physics in case their origin ends up stuck in the world or something StopAnimation(); pev->movetype = MOVETYPE_NONE; pev->effects |= EF_NOINTERP; // Don't interpolate either, assume the corpse is positioned in its final resting place return FALSE; } // If we actually played a sequence if(pOldCine && pOldCine->m_iszPlay) { if(!(pOldCine->pev->spawnflags & SF_SCRIPT_NOSCRIPTMOVEMENT)) { // reset position Vector new_origin, new_angle; GetBonePosition(0, new_origin, new_angle); // Figure out how far they have moved // We can't really solve this problem because we can't query the movement of the origin relative // to the sequence. We can get the root bone's position as we do here, but there are // cases where the root bone is in a different relative position to the entity's origin // before/after the sequence plays. So we are stuck doing this: // !!!HACKHACK: Float the origin up and drop to floor because some sequences have // irregular motion that can't be properly accounted for. // UNDONE: THIS SHOULD ONLY HAPPEN IF WE ACTUALLY PLAYED THE SEQUENCE. Vector oldOrigin = pev->origin; // UNDONE: ugly hack. Don't move monster if they don't "seem" to move // this really needs to be done with the AX,AY,etc. flags, but that aren't consistantly // being set, so animations that really do move won't be caught. if((oldOrigin - new_origin).Length2D() < 8.0) new_origin = oldOrigin; pev->origin.x = new_origin.x; pev->origin.y = new_origin.y; pev->origin.z += 1; pev->flags |= FL_ONGROUND; int drop = DROP_TO_FLOOR(ENT(pev)); // Origin in solid? Set to org at the end of the sequence if(drop < 0) pev->origin = oldOrigin; else if(drop == 0) // Hanging in air? { pev->origin.z = new_origin.z; pev->flags &= ~FL_ONGROUND; } // else entity hit floor, leave there // pEntity->pev->origin.z = new_origin.z + 5.0; // damn, got to fix this UTIL_SetOrigin(pev, pev->origin); pev->effects |= EF_NOINTERP; } // We should have some animation to put these guys in, but for now it's idle. // Due to NOINTERP above, there won't be any blending between this anim & the sequence m_Activity = ACT_RESET; } // set them back into a normal state pev->enemy = NULL; if(pev->health > 0) m_IdealMonsterState = MONSTERSTATE_IDLE; // m_previousState; else { // Dropping out because he got killed // Can't call killed() no attacker and weirdness (late gibbing) may result m_IdealMonsterState = MONSTERSTATE_DEAD; SetConditions(bits_COND_LIGHT_DAMAGE); pev->deadflag = DEAD_DYING; FCheckAITrigger(); pev->deadflag = DEAD_NO; } // SetAnimation( m_MonsterState ); ClearBits(pev->spawnflags, SF_MONSTER_WAIT_FOR_SCRIPT); return TRUE; }
void CBaseScripted::InitScriptedEntity( void ) { #if defined ( LUA_SDK ) #if 0 #ifndef CLIENT_DLL // Let the instance reinitialize itself for the client. if ( m_nTableReference != LUA_NOREF ) return; #endif #endif SetThink( &CBaseScripted::Think ); #ifdef CLIENT_DLL SetNextClientThink( gpGlobals->curtime ); #endif SetNextThink( gpGlobals->curtime ); SetTouch( &CBaseScripted::Touch ); char className[ 255 ]; #if defined ( CLIENT_DLL ) if ( strlen( GetScriptedClassname() ) > 0 ) Q_strncpy( className, GetScriptedClassname(), sizeof( className ) ); else Q_strncpy( className, GetClassname(), sizeof( className ) ); #else Q_strncpy( m_iScriptedClassname.GetForModify(), GetClassname(), sizeof( className ) ); Q_strncpy( className, GetClassname(), sizeof( className ) ); #endif Q_strlower( className ); SetClassname( className ); if ( m_nTableReference == LUA_NOREF ) { LoadScriptedEntity(); m_nTableReference = luaL_ref( L, LUA_REGISTRYINDEX ); } else { lua_getglobal( L, "table" ); if ( lua_istable( L, -1 ) ) { lua_getfield( L, -1, "merge" ); if ( lua_isfunction( L, -1 ) ) { lua_remove( L, -2 ); lua_getref( L, m_nTableReference ); LoadScriptedEntity(); luasrc_pcall( L, 2, 0, 0 ); } else { lua_pop( L, 2 ); } } else { lua_pop( L, 1 ); } } BEGIN_LUA_CALL_ENTITY_METHOD( "Initialize" ); END_LUA_CALL_ENTITY_METHOD( 0, 0 ); #endif }
void CBaseDoor::Spawn( void ) { if( pev->skin == CONTENTS_NONE ) { // normal door if( FBitSet( pev->spawnflags, SF_DOOR_PASSABLE )) pev->solid = SOLID_NOT; else pev->solid = SOLID_BSP; } else { SetBits( pev->spawnflags, SF_DOOR_SILENT ); pev->solid = SOLID_NOT; // special contents } Precache(); pev->movetype = MOVETYPE_PUSH; SET_MODEL( edict(), GetModel() ); // NOTE: original Half-Life was contain a bug in LinearMove function // while m_flWait was equal 0 then object has stopped forever. See code from quake: /* void LinearMove( Vector vecDest, float flSpeed ) { ... ... ... if( flTravelTime < 0.1f ) { pev->velocity = g_vecZero; pev->nextthink = pev->ltime + 0.1f; return; } } */ // this block was removed from Half-Life and there no difference // between wait = 0 and wait = -1. But in Xash this bug was fixed // and level-designer errors is now actual. I'm set m_flWait to -1 for compatibility if( m_flWait == 0.0f ) m_flWait = -1; if( pev->speed == 0 ) pev->speed = 100; if( pev->movedir == g_vecZero ) pev->movedir = Vector( 1.0f, 0.0f, 0.0f ); m_vecPosition1 = GetLocalOrigin(); // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big Vector vecSize = pev->size - Vector( 2, 2, 2 ); m_vecPosition2 = m_vecPosition1 + (pev->movedir * (DotProductAbs( pev->movedir, vecSize ) - m_flLip)); ASSERTSZ( m_vecPosition1 != m_vecPosition2, "door start/end positions are equal" ); if( FBitSet( pev->spawnflags, SF_DOOR_START_OPEN )) { UTIL_SetOrigin( this, m_vecPosition2 ); m_vecPosition2 = m_vecPosition1; m_vecPosition1 = GetLocalOrigin(); } else { UTIL_SetOrigin( this, m_vecPosition1 ); } // another hack: PhysX 2.8.4.0 crashed while trying to created kinematic body from this brush-model if ( FStrEq( STRING( gpGlobals->mapname ), "c2a5e" ) && FStrEq( STRING( pev->model ), "*103" )); else m_pUserData = WorldPhysic->CreateKinematicBodyFromEntity( this ); m_iState = STATE_OFF; // if the door is flagged for USE button activation only, use NULL touch function if( FBitSet( pev->spawnflags, SF_DOOR_USE_ONLY )) { SetTouch( NULL ); } else { // touchable button SetTouch( DoorTouch ); } }
void CRotDoor :: Spawn( void ) { // set the axis of rotation AxisDir( pev ); if( FBitSet( pev->spawnflags, SF_DOOR_PASSABLE )) pev->solid = SOLID_NOT; else pev->solid = SOLID_BSP; Precache(); // check for clockwise rotation if( FBitSet( pev->spawnflags, SF_DOOR_ROTATE_BACKWARDS )) pev->movedir = pev->movedir * -1; m_vecAngle1 = GetLocalAngles(); m_vecAngle2 = GetLocalAngles() + pev->movedir * m_flMoveDistance; ASSERTSZ( m_vecAngle1 != m_vecAngle2, "rotating door start/end positions are equal" ); pev->movetype = MOVETYPE_PUSH; SET_MODEL( edict(), GetModel() ); // NOTE: original Half-Life was contain a bug in AngularMove function // while m_flWait was equal 0 then object has stopped forever. See code from quake: /* void AngularMove( Vector vecDest, float flSpeed ) { ... ... ... if( flTravelTime < 0.1f ) { pev->avelocity = g_vecZero; pev->nextthink = pev->ltime + 0.1f; return; } } */ // this block was removed from Half-Life and there no difference // between wait = 0 and wait = -1. But in Xash this bug was fixed // and level-designer errors is now actual. I'm set m_flWait to -1 for compatibility if( m_flWait == 0.0f ) m_flWait = -1; if( pev->speed == 0 ) pev->speed = 100; // DOOR_START_OPEN is to allow an entity to be lighted in the closed position // but spawn in the open position if( FBitSet( pev->spawnflags, SF_DOOR_START_OPEN )) { // swap pos1 and pos2, put door at pos2, invert movement direction Vector vecNewAngles = m_vecAngle2; m_vecAngle2 = m_vecAngle1; m_vecAngle1 = vecNewAngles; pev->movedir = pev->movedir * -1; // We've already had our physics setup in BaseClass::Spawn, so teleport to our // current position. If we don't do this, our vphysics shadow will not update. Teleport( NULL, &m_vecAngle1, NULL ); } else { SetLocalAngles( m_vecAngle1 ); } m_iState = STATE_OFF; RelinkEntity(); m_pUserData = WorldPhysic->CreateKinematicBodyFromEntity( this ); if( FBitSet( pev->spawnflags, SF_DOOR_USE_ONLY )) { SetTouch( NULL ); } else { // touchable button SetTouch( DoorTouch ); } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pOther - //----------------------------------------------------------------------------- void CGrappleHook::HookTouch(CBaseEntity *pOther) { if (!pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS)) return; if ((pOther != m_hOwner) && (pOther->m_takedamage != DAMAGE_NO)) { m_hOwner->NotifyHookDied(); SetTouch(NULL); SetThink(NULL); UTIL_Remove(this); } else { trace_t tr; tr = BaseClass::GetTouchTrace(); // See if we struck the world if (pOther->GetMoveType() == MOVETYPE_NONE && !(tr.surface.flags & SURF_SKY)) { EmitSound("Weapon_AR2.Reload_Push"); // if what we hit is static architecture, can stay around for a while. Vector vecDir = GetAbsVelocity(); //FIXME: We actually want to stick (with hierarchy) to what we've hit SetMoveType(MOVETYPE_NONE); Vector vForward; AngleVectors(GetAbsAngles(), &vForward); VectorNormalize(vForward); CEffectData data; data.m_vOrigin = tr.endpos; data.m_vNormal = vForward; data.m_nEntIndex = 0; // DispatchEffect( "Impact", data ); // AddEffects( EF_NODRAW ); SetTouch(NULL); VPhysicsDestroyObject(); VPhysicsInitNormal(SOLID_VPHYSICS, FSOLID_NOT_STANDABLE, false); AddSolidFlags(FSOLID_NOT_SOLID); // SetMoveType( MOVETYPE_NONE ); if (!m_hPlayer) { Assert(0); return; } // Set Jay's gai flag m_hPlayer->SetPhysicsFlag(PFLAG_VPHYSICS_MOTIONCONTROLLER, true); //IPhysicsObject *pPhysObject = m_hPlayer->VPhysicsGetObject(); IPhysicsObject *pRootPhysObject = VPhysicsGetObject(); Assert(pRootPhysObject); //Assert(pPhysObject); pRootPhysObject->EnableMotion(false); // Root has huge mass, tip has little pRootPhysObject->SetMass(VPHYSICS_MAX_MASS); // pPhysObject->SetMass( 100 ); // float damping = 3; // pPhysObject->SetDamping( &damping, &damping ); Vector origin = m_hPlayer->GetAbsOrigin(); Vector rootOrigin = GetAbsOrigin(); m_fSpringLength = (origin - rootOrigin).Length(); m_bPlayerWasStanding = ((m_hPlayer->GetFlags() & FL_DUCKING) == 0); SetThink(&CGrappleHook::HookedThink); SetNextThink(gpGlobals->curtime + 0.1f); } else { // Put a mark unless we've hit the sky if ((tr.surface.flags & SURF_SKY) == false) { UTIL_ImpactTrace(&tr, DMG_BULLET); } SetTouch(NULL); SetThink(NULL); m_hOwner->NotifyHookDied(); UTIL_Remove(this); } } }
void CBaseButton::Spawn() { char *pszSound; //---------------------------------------------------- //determine sounds for buttons //a sound of 0 should not make a sound //---------------------------------------------------- pszSound = ButtonSound(m_sounds); PRECACHE_SOUND(pszSound); pev->noise = ALLOC_STRING(pszSound); Precache(); if(FBitSet(pev->spawnflags, SF_BUTTON_SPARK_IF_OFF)) // this button should spark in OFF state { SetThink(&CBaseButton::ButtonSpark); pev->nextthink = gpGlobals->time + 0.5; // no hurry, make sure everything else spawns } SetMovedir(pev); pev->movetype = MOVETYPE_PUSH; pev->solid = SOLID_BSP; SET_MODEL(ENT(pev), STRING(pev->model)); if(pev->speed == 0) pev->speed = 40; if(pev->health > 0) { pev->takedamage = DAMAGE_YES; } if(m_flWait == 0) m_flWait = 1; if(m_flLip == 0) m_flLip = 4; m_toggle_state = TS_AT_BOTTOM; m_vecPosition1 = pev->origin; // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs(pev->movedir.x * (pev->size.x - 2)) + fabs(pev->movedir.y * (pev->size.y - 2)) + fabs(pev->movedir.z * (pev->size.z - 2)) - m_flLip)); // Is this a non-moving button? if(((m_vecPosition2 - m_vecPosition1).Length() < 1) || (pev->spawnflags & SF_BUTTON_DONTMOVE)) m_vecPosition2 = m_vecPosition1; m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE); m_fRotating = FALSE; // if the button is flagged for USE button activation only, take away it's touch function and add a use function if(FBitSet(pev->spawnflags, SF_BUTTON_TOUCH_ONLY)) // touchable button { SetTouch(&CBaseButton::ButtonTouch); } else { SetTouch(NULL); SetUse(&CBaseButton::ButtonUse); } }
//----------------------------------------------------------------------------- // Purpose: Stick to an entity (using hierarchy if we can) // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CWeaponStriderBuster::StickToEntity( CBaseEntity *pOther ) { // Make sure the object is travelling fast enough to stick if ( m_flCollisionSpeedSqr > 50 && !m_bNoseDiving ) { // See if this is a valid strider bit if ( ShouldStickToEntity( pOther ) ) { // Attempt to constraint to it if ( CreateConstraintToObject( pOther ) ) { // Only works for striders, at the moment CBaseEntity *pFollowParent = pOther->GetOwnerEntity(); if ( pFollowParent == NULL ) return false; // Allows us to identify our constrained object later SetOwnerEntity( pFollowParent ); // Make a sound EmitSound( "Weapon_StriderBuster.StickToEntity" ); DispatchParticleEffect( "striderbuster_attach", GetAbsOrigin(), GetAbsAngles(), NULL ); if( striderbuster_use_particle_flare.GetBool() ) { // We don't have to save any pointers or handles to this because it's parented to the buster. // So it will die when the buster dies. Yay. CParticleSystem *pFlare = (CParticleSystem *) CreateEntityByName( "info_particle_system" ); if ( pFlare != NULL ) { pFlare->KeyValue( "start_active", "1" ); pFlare->KeyValue( "effect_name", "striderbuster_attached_pulse" ); pFlare->SetParent( this ); pFlare->SetLocalOrigin( vec3_origin ); DispatchSpawn( pFlare ); pFlare->Activate(); } } else { // Create a glow sprite m_hGlowSprite = CSprite::SpriteCreate( "sprites/orangeflare1.vmt", GetLocalOrigin(), false ); Assert( m_hGlowSprite ); if ( m_hGlowSprite != NULL ) { m_hGlowSprite->TurnOn(); m_hGlowSprite->SetTransparency( kRenderWorldGlow, 255, 255, 255, 255, kRenderFxNoDissipation ); m_hGlowSprite->SetAbsOrigin( GetAbsOrigin() ); m_hGlowSprite->SetScale( 5.0f ); m_hGlowSprite->m_nRenderFX = kRenderFxStrobeFaster; m_hGlowSprite->SetGlowProxySize( 16.0f ); m_hGlowSprite->SetParent( this ); } } // Stop touching things SetTouch( NULL ); // Must be a strider CNPC_Strider *pStrider = dynamic_cast<CNPC_Strider *>(pFollowParent); if ( pStrider == NULL ) return false; // Notify the strider we're attaching to him pStrider->StriderBusterAttached( this ); m_OnAttachToStrider.FireOutput( this, this ); // Start the ping sound. SetContextThink( &CWeaponStriderBuster::BusterPingThink, gpGlobals->curtime + BUSTER_PING_SOUND_FREQ, s_pBusterPingThinkContext ); // Don't autodelete this one! WeaponManager_RemoveManaged( this ); return true; } return false; } } return false; }