// resets all entities that need reseting void CBaseRoundRules::ResetWorld(bool bResetCustom, bool bResetOnlyCustom) { if(bResetOnlyCustom == false) { // - breakables CBreakable * pBreakable = NULL; pBreakable = (CBreakable*)UTIL_FindEntityByClassname( pBreakable, "func_breakable" ); while (pBreakable) { pBreakable->Reset(); pBreakable = (CBreakable*)UTIL_FindEntityByClassname( pBreakable, "func_breakable" ); } // - doors CBaseDoor *pDoor = NULL; pDoor = (CBaseDoor*)UTIL_FindEntityByClassname( pBreakable, "func_door" ); while (pBreakable) { pDoor->Spawn(); pDoor->SUB_UseTargets(pDoor, USE_OFF, 0.0); pDoor = (CBaseDoor*)UTIL_FindEntityByClassname( pDoor, "func_door" ); } // - points pPointManager->ResetAllPoints(); pPointManager->UpdatePlayersHUD(); // - spawn containers g_pBGRules->InitSpawns(); } if(bResetCustom == true) { g_pBGRules->InitSpawns(); // -reseter ent CBaseEntity *pResetEnt = NULL; pResetEnt = (CBaseEntity*)UTIL_FindEntityByClassname( pResetEnt, "info_reset" ); // -this allows us to reset the ents the mapper wants // -ben : I didn't want to do this but this could solve some bh probs CountPlayersOnTeam(true); if(GetNumOfBritishPlayers() <= 0 || GetNumOfAmericanPlayers() <= 0) return; while (pResetEnt) { pResetEnt->ResetEnt(); pResetEnt = (CBaseEntity*)UTIL_FindEntityByClassname( pResetEnt, "info_reset" ); } } }
virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask ) { CBaseEntity *pEntity = (CBaseEntity *)pServerEntity; if ( pEntity->GetCollisionGroup() == COLLISION_GROUP_WEAPON ) return false; // Don't collide with the tracing entity's vehicle (if it exists) if ( pServerEntity == m_pVehicle ) return false; if ( pEntity->GetHealth() > 0 ) { CBreakable *pBreakable = dynamic_cast<CBreakable *>(pEntity); if ( pBreakable && pBreakable->IsBreakable() && pBreakable->GetMaterialType() == matGlass) { return false; } } return BaseClass::ShouldHitEntity( pServerEntity, contentsMask ); }
void CTank :: Fire ( int canon ) { Vector vecGun; GetAttachment( canon, vecGun, Vector(0,0,0) ); if ( !FStrEq(STRING(gpGlobals->mapname), "l3m10") && !FStrEq(STRING(gpGlobals->mapname), "l3m12") && !FStrEq(STRING(gpGlobals->mapname), "l3m14") ) { CSprite *pSprite = CSprite::SpriteCreate( SPRITE_SMOKE, vecGun, TRUE ); pSprite->AnimateAndDie( 15 ); pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); pSprite->SetAttachment( edict(), canon+1 ); pSprite->SetScale( SPRITE_SMOKE_SCALE ); } TraceResult tr; UTIL_MakeVectors ( TourelleAngle() ); UTIL_TraceLine( vecGun, vecGun + gpGlobals->v_forward * 8192, dont_ignore_monsters, edict(), &tr ); // pas de dommages - la fonction standart donne un rayon 2.5 fois les dommages // 250 * 2.5 = 625 - bcp trop grand ExplosionCreate( tr.vecEndPos, pev->angles, NULL/*edict()*/, 250, FALSE ); // on applique nous-même les dommages - rayon : 250 ::RadiusDamage( tr.vecEndPos, pev, pev, 300, 300, CLASS_NONE, DMG_BLAST ); //effet de fumée EnvSmokeCreate( tr.vecEndPos, 4, 10, 2, NULL ); /* // sprites de feu for ( int i=0; i<4; i++ ) { for ( int j=0; j<3; j++ ) { CSprite *pSpr = CSprite::SpriteCreate ( SPRITE_FEU, tr.vecEndPos + Vector(0,0,50), TRUE ); pSpr->SetTransparency ( kRenderTransAdd, 255, 255, 255, 180, kRenderFxNone ); pSpr->pev->scale = (float)((float)SPRITE_FEU_SCALE*2*(1/(i+1))); pSpr->pev->framerate = RANDOM_FLOAT(18,24); pSpr->pev->velocity = Vector ( RANDOM_FLOAT(-50,50)*(3-i)/3,RANDOM_FLOAT(-50,50)*(3-i)/3, 50*(i)); pSpr->pev->spawnflags |= SF_SPRITE_ONCE; pSpr->TurnOn(); } } */ /* for ( i=0; i<1; i++ ) { CSprite *pSpr = CSprite::SpriteCreate ( SPRITE_SMOKEBALL, Vector(pev->origin.x,pev->origin.y,pev->origin.z + 100), TRUE ); pSpr->SetScale ( SPRITE_SMOKEBALL_SCALE ); pSpr->AnimateAndDie ( RANDOM_FLOAT(3,4) ); pSpr->SetTransparency ( kRenderTransAlpha, 255, 255, 255, 200, kRenderFxNone ); pSpr->pev->velocity = Vector ( RANDOM_FLOAT(-50,50),RANDOM_FLOAT(-50,50),RANDOM_FLOAT(130,150) ); } */ //breakable spéciaux if ( FClassnameIs (tr.pHit, "func_breakable") && VARS(tr.pHit)->spawnflags & SF_BREAK_TANKTOUCH ) { CBreakable *pBreak = (CBreakable*) CBaseEntity::Instance(tr.pHit); if ( pBreak->CheckTankPrev() ) { pBreak->pev->health = 0; pBreak->Killed( pev, GIB_NORMAL ); pBreak->Die(); } } }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CCrossbowBolt::BoltTouch( CBaseEntity *pOther ) { if ( pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS | FSOLID_TRIGGER) ) { // Some NPCs are triggers that can take damage (like antlion grubs). We should hit them. if ( ( pOther->m_takedamage == DAMAGE_NO ) || ( pOther->m_takedamage == DAMAGE_EVENTS_ONLY ) ) return; } if ( pOther->m_takedamage != DAMAGE_NO ) { trace_t tr, tr2; tr = BaseClass::GetTouchTrace(); Vector vecNormalizedVel = GetAbsVelocity(); ClearMultiDamage(); VectorNormalize( vecNormalizedVel ); #if defined(HL2_EPISODIC) //!!!HACKHACK - specific hack for ep2_outland_10 to allow crossbow bolts to pass through her bounding box when she's crouched in front of the player // (the player thinks they have clear line of sight because Alyx is crouching, but her BBOx is still full-height and blocks crossbow bolts. if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->Classify() == CLASS_PLAYER_ALLY_VITAL && FStrEq(STRING(gpGlobals->mapname), "ep2_outland_10") ) { // Change the owner to stop further collisions with Alyx. We do this by making her the owner. // The player won't get credit for this kill but at least the bolt won't magically disappear! SetOwnerEntity( pOther ); return; } #endif//HL2_EPISODIC if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC() ) { CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_crossbow.GetFloat(), DMG_NEVERGIB ); dmgInfo.AdjustPlayerDamageInflictedForSkillLevel(); CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f ); dmgInfo.SetDamagePosition( tr.endpos ); pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr ); CBasePlayer *pPlayer = ToBasePlayer( GetOwnerEntity() ); if ( pPlayer ) { gamestats->Event_WeaponHit( pPlayer, true, "weapon_crossbow", dmgInfo ); } } else { CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_crossbow.GetFloat(), DMG_BULLET | DMG_NEVERGIB ); CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f ); dmgInfo.SetDamagePosition( tr.endpos ); pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr ); } ApplyMultiDamage(); //Adrian: keep going through the glass. if ( pOther->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS ) return; if (FClassnameIs(pOther, "func_breakable")) { CBreakable* pOtherEntity = static_cast<CBreakable*> (pOther); if (pOtherEntity->GetMaterialType() == matGlass) return; } if ( !pOther->IsAlive() ) { // We killed it! const surfacedata_t *pdata = physprops->GetSurfaceData( tr.surface.surfaceProps ); if ( pdata->game.material == CHAR_TEX_GLASS ) { return; } } SetAbsVelocity( Vector( 0, 0, 0 ) ); // play body "thwack" sound EmitSound( "Weapon_Crossbow.BoltHitBody" ); Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); VectorNormalize ( vForward ); UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vForward * 128, MASK_BLOCKLOS, pOther, COLLISION_GROUP_NONE, &tr2 ); if ( tr2.fraction != 1.0f ) { // NDebugOverlay::Box( tr2.endpos, Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 255, 0, 0, 10 ); // NDebugOverlay::Box( GetAbsOrigin(), Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 0, 255, 0, 10 ); if ( tr2.m_pEnt == NULL || ( tr2.m_pEnt && tr2.m_pEnt->GetMoveType() == MOVETYPE_NONE ) ) { CEffectData data; data.m_vOrigin = tr2.endpos; data.m_vNormal = vForward; data.m_nEntIndex = tr2.fraction != 1.0f; DispatchEffect( "BoltImpact", data ); } } SetTouch( NULL ); SetThink( NULL ); if ( !g_pGameRules->IsMultiplayer() ) { 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_Crossbow.BoltHitWorld" ); // if what we hit is static architecture, can stay around for a while. Vector vecDir = GetAbsVelocity(); float speed = VectorNormalize( vecDir ); // See if we should reflect off this surface float hitDot = DotProduct( tr.plane.normal, -vecDir ); if ( ( hitDot < 0.5f ) && ( speed > 100 ) ) { Vector vReflection = 2.0f * tr.plane.normal * hitDot + vecDir; QAngle reflectAngles; VectorAngles( vReflection, reflectAngles ); SetLocalAngles( reflectAngles ); SetAbsVelocity( vReflection * speed * 0.75f ); // Start to sink faster SetGravity( 1.0f ); } else { SetThink( &CCrossbowBolt::SUB_Remove ); SetNextThink( gpGlobals->curtime + 2.0f ); //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( "BoltImpact", data ); UTIL_ImpactTrace( &tr, DMG_BULLET ); AddEffects( EF_NODRAW ); SetTouch( NULL ); SetThink( &CCrossbowBolt::SUB_Remove ); SetNextThink( gpGlobals->curtime + 2.0f ); if ( m_pGlowSprite != NULL ) { m_pGlowSprite->TurnOn(); m_pGlowSprite->FadeAndDie( 3.0f ); } if (m_pGlowTrail != NULL) { m_pGlowTrail->TurnOn(); m_pGlowTrail->FadeAndDie(6.0f); } CBaseEntity *tmp = CreateEntityByName("item_ammo_custom"); if (tmp) { tmp->KeyValue("origin", GetAbsOrigin()); tmp->KeyValue("angles", vForward); tmp->KeyValue("model", ""); tmp->KeyValue("ammoName", "XBowBolt"); tmp->KeyValue("ammoCount", 1); tmp->SetGravity(0); tmp->SetMoveType(MOVETYPE_NONE); DispatchSpawn(tmp); } } // Shoot some sparks if ( UTIL_PointContents( GetAbsOrigin() ) != CONTENTS_WATER) { g_pEffects->Sparks( GetAbsOrigin() ); } } else { // Put a mark unless we've hit the sky if ( ( tr.surface.flags & SURF_SKY ) == false ) { UTIL_ImpactTrace( &tr, DMG_BULLET ); } UTIL_Remove( this ); } } if ( g_pGameRules->IsMultiplayer() ) { // SetThink( &CCrossbowBolt::ExplodeThink ); // SetNextThink( gpGlobals->curtime + 0.1f ); } }