예제 #1
0
// DeadTakeDamage - takedamage function called when a monster's corpse is damaged.
int CBaseMonster::DeadTakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
{
	// grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit).
	Vector vecDir(0, 0, 0);

	if (!FNullEnt(pevInflictor))
	{
		CBaseEntity *pInflictor = CBaseEntity::Instance(pevInflictor);
		if (pInflictor)
		{
			vecDir = (pInflictor->Center() - Vector(0, 0, 10) - Center()).Normalize();
			vecDir = g_vecAttackDir = vecDir.Normalize();
		}
	}

// turn this back on when the bounding box issues are resolved.
#if 0

	pev->flags &= ~FL_ONGROUND;
	pev->origin.z += 1;

	// let the damage scoot the corpse around a bit.
	if (!FNullEnt(pevInflictor) && (pevAttacker->solid != SOLID_TRIGGER))
	{
		pev->velocity = pev->velocity + vecDir * -DamageForce(flDamage);
	}

#endif

	// kill the corpse if enough damage was done to destroy the corpse and the damage is of a type that is allowed to destroy the corpse.
	if (bitsDamageType & DMG_GIB_CORPSE)
	{
		if (pev->health <= flDamage)
		{
			pev->health = -50;
			Killed(pevAttacker, GIB_ALWAYS);
			return 0;
		}

		// Accumulate corpse gibbing damage, so you can gib with multiple hits
		pev->health -= flDamage * 0.1;
	}

	return 1;
}
예제 #2
0
void CFuncWallDetail::Think( void )
{
	//MAKE FAKE Level Of Detail
	CBaseEntity *pEntity = NULL;

    while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, 9999 )) != NULL) 
	{
		if ( pEntity->IsPlayer() ) 
		{
			float flDist = (pEntity->Center() - pev->origin).Length();
							
			ALERT ( at_console, "flDist is: %f\n",flDist );

			if ( flDist >= 800)
			{
				//ALERT ( at_console, "m_iszWallNormal\n" );
				FireTargets( STRING(m_iszWallLow), this, this, USE_ON, 0 );//LOW
				FireTargets( STRING(m_iszWallNormal), this, this, USE_OFF, 0 );
				FireTargets( STRING(m_iszWallDetail), this, this, USE_OFF, 0 );
			}
			else if ( flDist >= 400)
			{
				//ALERT ( at_console, "m_iszWallLow\n" );
				FireTargets( STRING(m_iszWallLow), this, this, USE_OFF, 0 );
				FireTargets( STRING(m_iszWallNormal), this, this, USE_ON, 0 );//NORMAL
				FireTargets( STRING(m_iszWallDetail), this, this, USE_OFF, 0 );
			}
			else//detallado
			{
				//ALERT ( at_console, "m_iszWallDetail\n" );
				FireTargets( STRING(m_iszWallLow), this, this, USE_OFF, 0 );
				FireTargets( STRING(m_iszWallNormal), this, this, USE_OFF, 0 );
				FireTargets( STRING(m_iszWallDetail), this, this, USE_ON, 0 );//DETAILED
			}	
		}
	}

	pev->nextthink = gpGlobals->time + 0.1;
}
예제 #3
0
파일: combat.cpp 프로젝트: 6779660/halflife
/*
============
TakeDamage

The damage is coming from inflictor, but get mad at attacker
This should be the only function that ever reduces health.
bitsDamageType indicates the type of damage sustained, ie: DMG_SHOCK

Time-based damage: only occurs while the monster is within the trigger_hurt.
When a monster is poisoned via an arrow etc it takes all the poison damage at once.



GLOBALS ASSUMED SET:  g_iSkillLevel
============
*/
int CBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
{
	float	flTake;
	Vector	vecDir;

	if (!pev->takedamage)
		return 0;

	if ( !IsAlive() )
	{
		return DeadTakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType );
	}

	if ( pev->deadflag == DEAD_NO )
	{
		// no pain sound during death animation.
		PainSound();// "Ouch!"
	}

	//!!!LATER - make armor consideration here!
	flTake = flDamage;

	// set damage type sustained
	m_bitsDamageType |= bitsDamageType;

	// grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit).
	vecDir = Vector( 0, 0, 0 );
	if (!FNullEnt( pevInflictor ))
	{
		CBaseEntity *pInflictor = CBaseEntity :: Instance( pevInflictor );
		if (pInflictor)
		{
			vecDir = ( pInflictor->Center() - Vector ( 0, 0, 10 ) - Center() ).Normalize();
			vecDir = g_vecAttackDir = vecDir.Normalize();
		}
	}

	// add to the damage total for clients, which will be sent as a single
	// message at the end of the frame
	// todo: remove after combining shotgun blasts?
	if ( IsPlayer() )
	{
		if ( pevInflictor )
			pev->dmg_inflictor = ENT(pevInflictor);

		pev->dmg_take += flTake;

		// check for godmode or invincibility
		if ( pev->flags & FL_GODMODE )
		{
			return 0;
		}
	}

	// if this is a player, move him around!
	if ( ( !FNullEnt( pevInflictor ) ) && (pev->movetype == MOVETYPE_WALK) && (!pevAttacker || pevAttacker->solid != SOLID_TRIGGER) )
	{
		pev->velocity = pev->velocity + vecDir * -DamageForce( flDamage );
	}

	// do the damage
	pev->health -= flTake;

	// HACKHACK Don't kill monsters in a script.  Let them break their scripts first
	if ( m_MonsterState == MONSTERSTATE_SCRIPT )
	{
		SetConditions( bits_COND_LIGHT_DAMAGE );
		return 0;
	}

	if ( pev->health <= 0 )
	{
		g_pevLastInflictor = pevInflictor;

		if ( bitsDamageType & DMG_ALWAYSGIB )
		{
			Killed( pevAttacker, GIB_ALWAYS );
		}
		else if ( bitsDamageType & DMG_NEVERGIB )
		{
			Killed( pevAttacker, GIB_NEVER );
		}
		else
		{
			Killed( pevAttacker, GIB_NORMAL );
		}

		g_pevLastInflictor = NULL;

		return 0;
	}

	// react to the damage (get mad)
	if ( (pev->flags & FL_MONSTER) && !FNullEnt(pevAttacker) )
	{
		if ( pevAttacker->flags & (FL_MONSTER | FL_CLIENT) )
		{// only if the attack was a monster or client!
			
			// enemy's last known position is somewhere down the vector that the attack came from.
			if (pevInflictor)
			{
				if (m_hEnemy == NULL || pevInflictor == m_hEnemy->pev || !HasConditions(bits_COND_SEE_ENEMY))
				{
					m_vecEnemyLKP = pevInflictor->origin;
				}
			}
			else
			{
				m_vecEnemyLKP = pev->origin + ( g_vecAttackDir * 64 ); 
			}

			MakeIdealYaw( m_vecEnemyLKP );

			// add pain to the conditions 
			// !!!HACKHACK - fudged for now. Do we want to have a virtual function to determine what is light and 
			// heavy damage per monster class?
			if ( flDamage > 0 )
			{
				SetConditions(bits_COND_LIGHT_DAMAGE);
			}

			if ( flDamage >= 20 )
			{
				SetConditions(bits_COND_HEAVY_DAMAGE);
			}
		}
	}

	return 1;
}
예제 #4
0
//=========================================================
// SonicAttack
//=========================================================
void CHoundeye :: SonicAttack ( void )
{
	float		flAdjustedDamage;
	float		flDist;

	switch ( RANDOM_LONG( 0, 2 ) )
	{
	case 0:	EMIT_SOUND(ENT(pev), CHAN_WEAPON, "houndeye/he_blast1.wav", 1, ATTN_NORM);	break;
	case 1:	EMIT_SOUND(ENT(pev), CHAN_WEAPON, "houndeye/he_blast2.wav", 1, ATTN_NORM);	break;
	case 2:	EMIT_SOUND(ENT(pev), CHAN_WEAPON, "houndeye/he_blast3.wav", 1, ATTN_NORM);	break;
	}

	// blast circles
	MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
		WRITE_BYTE( TE_BEAMCYLINDER );
		WRITE_COORD( pev->origin.x);
		WRITE_COORD( pev->origin.y);
		WRITE_COORD( pev->origin.z + 16);
		WRITE_COORD( pev->origin.x);
		WRITE_COORD( pev->origin.y);
		WRITE_COORD( pev->origin.z + 16 + HOUNDEYE_MAX_ATTACK_RADIUS / .2); // reach damage radius over .3 seconds
		WRITE_SHORT( m_iSpriteTexture );
		WRITE_BYTE( 0 ); // startframe
		WRITE_BYTE( 0 ); // framerate
		WRITE_BYTE( 2 ); // life
		WRITE_BYTE( 16 );  // width
		WRITE_BYTE( 0 );   // noise

		WriteBeamColor();

		WRITE_BYTE( 255 ); //brightness
		WRITE_BYTE( 0 );		// speed
	MESSAGE_END();

	MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
		WRITE_BYTE( TE_BEAMCYLINDER );
		WRITE_COORD( pev->origin.x);
		WRITE_COORD( pev->origin.y);
		WRITE_COORD( pev->origin.z + 16);
		WRITE_COORD( pev->origin.x);
		WRITE_COORD( pev->origin.y);
		WRITE_COORD( pev->origin.z + 16 + ( HOUNDEYE_MAX_ATTACK_RADIUS / 2 ) / .2); // reach damage radius over .3 seconds
		WRITE_SHORT( m_iSpriteTexture );
		WRITE_BYTE( 0 ); // startframe
		WRITE_BYTE( 0 ); // framerate
		WRITE_BYTE( 2 ); // life
		WRITE_BYTE( 16 );  // width
		WRITE_BYTE( 0 );   // noise

		WriteBeamColor();
		
		WRITE_BYTE( 255 ); //brightness
		WRITE_BYTE( 0 );		// speed
	MESSAGE_END();


	CBaseEntity *pEntity = NULL;
	// iterate on all entities in the vicinity.
	while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, HOUNDEYE_MAX_ATTACK_RADIUS )) != NULL)
	{
		if ( pEntity->pev->takedamage != DAMAGE_NO )
		{
			if ( !FClassnameIs(pEntity->pev, "monster_houndeye") )
			{// houndeyes don't hurt other houndeyes with their attack

				// houndeyes do FULL damage if the ent in question is visible. Half damage otherwise.
				// This means that you must get out of the houndeye's attack range entirely to avoid damage.
				// Calculate full damage first

				if ( SquadCount() > 1 )
				{
					// squad gets attack bonus.
					flAdjustedDamage = gSkillData.houndeyeDmgBlast + gSkillData.houndeyeDmgBlast * ( HOUNDEYE_SQUAD_BONUS * ( SquadCount() - 1 ) );
				}
				else
				{
					// solo
					flAdjustedDamage = gSkillData.houndeyeDmgBlast;
				}

				flDist = (pEntity->Center() - pev->origin).Length();

				flAdjustedDamage -= ( flDist / HOUNDEYE_MAX_ATTACK_RADIUS ) * flAdjustedDamage;

				if ( !FVisible( pEntity ) )
				{
					if ( pEntity->IsPlayer() )
					{
						// if this entity is a client, and is not in full view, inflict half damage. We do this so that players still 
						// take the residual damage if they don't totally leave the houndeye's effective radius. We restrict it to clients
						// so that monsters in other parts of the level don't take the damage and get pissed.
						flAdjustedDamage *= 0.5;
					}
					else if ( !FClassnameIs( pEntity->pev, "func_breakable" ) && !FClassnameIs( pEntity->pev, "func_pushable" ) ) 
					{
						// do not hurt nonclients through walls, but allow damage to be done to breakables
						flAdjustedDamage = 0;
					}
				}

				//ALERT ( at_aiconsole, "Damage: %f\n", flAdjustedDamage );

				if (flAdjustedDamage > 0 )
				{
					pEntity->TakeDamage ( pev, pev, flAdjustedDamage, DMG_SONIC | DMG_ALWAYSGIB );
				}
			}
		}
	}
}
예제 #5
0
/*
=========================================================
UpdateClientData

resends any changed player HUD info to the client.
Called every frame by PlayerPreThink
Also called at start of demo recording and playback by
ForceClientDllUpdate to ensure the demo gets messages
reflecting all of the HUD state info.
=========================================================
*/
void CBasePlayer::UpdateClientData()
{
	if( m_bNeedsNewConnectTime )
	{
		m_bNeedsNewConnectTime = false;

		m_flConnectTime = gpGlobals->time;
	}

	if( !m_bWeaponValidationReceived && m_flConnectTime + WEAPON_VALIDATION_GRACE_TIME < gpGlobals->time )
	{
		//If the client didn't send the message in time, drop the client. - Solokiller

		//Set it to true to avoid running this multiple times. - Solokiller
		m_bWeaponValidationReceived = true;

		UTIL_LogPrintf( "Player \"%s\" didn't send weapon validation in time, disconnecting\n", GetNetName() );

		if( !IS_DEDICATED_SERVER() )
		{
			//Listen server hosts usually don't have logging enabled, so echo to console unconditionally for them. - Solokiller
			UTIL_ServerPrintf( "Player \"%s\" didn't send weapon validation in time, disconnecting\n", GetNetName() );
		}

		if( IS_DEDICATED_SERVER() || entindex() != 1 )
		{
			SERVER_COMMAND( UTIL_VarArgs( "kick \"%s\" \"No weapon validation received\"\n", GetNetName() ) );
		}
		else
		{
			//The local player can't be kicked, so terminate the session instead - Solokiller
			CLIENT_COMMAND( edict(), "disconnect\n" );
		}
	}

	//The engine will not call ClientPutInServer after transitions, so we'll have to catch this event every map change. - Solokiller
	if( !m_bSentInitData )
	{
		m_bSentInitData = true;

		//Update Hud colors. - Solokiller
		CMap::GetInstance()->SendHudColors( this, true );
	}

	if( m_fInitHUD )
	{
		m_fInitHUD = false;
		gInitHUD = false;

		MESSAGE_BEGIN( MSG_ONE, gmsgResetHUD, NULL, this );
			WRITE_BYTE( 0 );
		MESSAGE_END();

		if( !m_fGameHUDInitialized )
		{
			MESSAGE_BEGIN( MSG_ONE, gmsgInitHUD, NULL, this );
			MESSAGE_END();

			g_pGameRules->InitHUD( this );
			m_fGameHUDInitialized = true;

			m_iObserverLastMode = OBS_ROAMING;

			if( g_pGameRules->IsMultiplayer() )
			{
				FireTargets( "game_playerjoin", this, this, USE_TOGGLE, 0 );
			}
		}

		FireTargets( "game_playerspawn", this, this, USE_TOGGLE, 0 );

		InitStatusBar();

		SendWeatherUpdate();
	}

	if( m_iHideHUD != m_iClientHideHUD )
	{
		MESSAGE_BEGIN( MSG_ONE, gmsgHideWeapon, NULL, this );
			WRITE_BYTE( m_iHideHUD );
		MESSAGE_END();

		m_iClientHideHUD = m_iHideHUD;
	}

	if( m_iFOV != m_iClientFOV )
	{
		MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, this );
			WRITE_BYTE( m_iFOV );
		MESSAGE_END();

		// cache FOV change at end of function, so weapon updates can see that FOV has changed
	}

	// HACKHACK -- send the message to display the game title
	if( gDisplayTitle )
	{
		MESSAGE_BEGIN( MSG_ONE, gmsgShowGameTitle, NULL, this );
			WRITE_BYTE( 0 );
		MESSAGE_END();
		gDisplayTitle = false;
	}

	if( pev->health != m_iClientHealth )
	{
		int iHealth = clamp( static_cast<int>( pev->health ), 0, 255 );  // make sure that no negative health values are sent
		if( pev->health > 0.0f && pev->health <= 1.0f )
			iHealth = 1;

		// send "health" update message
		MESSAGE_BEGIN( MSG_ONE, gmsgHealth, NULL, this );
			WRITE_BYTE( iHealth );
		MESSAGE_END();

		m_iClientHealth = pev->health;
	}


	if( pev->armorvalue != m_iClientBattery )
	{
		m_iClientBattery = pev->armorvalue;

		ASSERT( gmsgBattery > 0 );
		// send "health" update message
		MESSAGE_BEGIN( MSG_ONE, gmsgBattery, NULL, this );
			WRITE_SHORT( ( int ) pev->armorvalue );
		MESSAGE_END();
	}

	if( pev->dmg_take || pev->dmg_save || m_bitsHUDDamage != m_bitsDamageType )
	{
		// Comes from inside me if not set
		Vector damageOrigin = GetAbsOrigin();
		// send "damage" message
		// causes screen to flash, and pain compass to show direction of damage
		edict_t *other = pev->dmg_inflictor;
		if( other )
		{
			CBaseEntity *pEntity = CBaseEntity::Instance( other );
			if( pEntity )
				damageOrigin = pEntity->Center();
		}

		// only send down damage type that have hud art
		int visibleDamageBits = m_bitsDamageType & DMG_SHOWNHUD;

		MESSAGE_BEGIN( MSG_ONE, gmsgDamage, NULL, this );
			WRITE_BYTE( pev->dmg_save );
			WRITE_BYTE( pev->dmg_take );
			WRITE_LONG( visibleDamageBits );
			WRITE_COORD( damageOrigin.x );
			WRITE_COORD( damageOrigin.y );
			WRITE_COORD( damageOrigin.z );
		MESSAGE_END();

		//TODO: both of these can probably be removed. - Solokiller
		pev->dmg_take = 0;
		pev->dmg_save = 0;
		m_bitsHUDDamage = m_bitsDamageType;

		// Clear off non-time-based damage indicators
		m_bitsDamageType &= DMG_TIMEBASED;
	}

	// Update Flashlight
	if( ( m_flFlashLightTime ) && ( m_flFlashLightTime <= gpGlobals->time ) )
	{
		if( FlashlightIsOn() )
		{
			if( m_iFlashBattery )
			{
				m_flFlashLightTime = FLASH_DRAIN_TIME + gpGlobals->time;
				m_iFlashBattery--;

				if( !m_iFlashBattery )
					FlashlightTurnOff();
			}
		}
		else
		{
			if( m_iFlashBattery < 100 )
			{
				m_flFlashLightTime = FLASH_CHARGE_TIME + gpGlobals->time;
				m_iFlashBattery++;
			}
			else
				m_flFlashLightTime = 0;
		}

		MESSAGE_BEGIN( MSG_ONE, gmsgFlashBattery, NULL, this );
			WRITE_BYTE( m_iFlashBattery );
		MESSAGE_END();
	}

	if( m_iTrain & TRAIN_NEW )
	{
		ASSERT( gmsgTrain > 0 );
		// send "health" update message
		MESSAGE_BEGIN( MSG_ONE, gmsgTrain, NULL, this );
			WRITE_BYTE( m_iTrain & 0xF );
		MESSAGE_END();

		m_iTrain &= ~TRAIN_NEW;
	}

	SendAmmoUpdate();

	// Update all the items
	for( int i = 0; i < MAX_WEAPON_SLOTS; i++ )
	{
		if( m_rgpPlayerItems[ i ] )  // each item updates it's successors
			m_rgpPlayerItems[ i ]->UpdateClientData( this );
	}

	// Cache and client weapon change
	m_pClientActiveItem = m_pActiveItem;
	m_iClientFOV = m_iFOV;

	// Update Status Bar
	if( m_flNextSBarUpdateTime < gpGlobals->time )
	{
		UpdateStatusBar();
		m_flNextSBarUpdateTime = gpGlobals->time + 0.2;
	}
}
예제 #6
0
// The damage is coming from inflictor, but get mad at attacker
// This should be the only function that ever reduces health.
// bitsDamageType indicates the type of damage sustained, ie: DMG_SHOCK
//
// Time-based damage: only occurs while the monster is within the trigger_hurt.
// When a monster is poisoned via an arrow etc it takes all the poison damage at once.
int CBaseMonster::__MAKE_VHOOK(TakeDamage)(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
{
	if (pev->takedamage == DAMAGE_NO)
		return 0;

	if (!IsAlive())
	{
		return DeadTakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType);
	}

	if (pev->deadflag == DEAD_NO)
	{
		// no pain sound during death animation.
		PainSound();
	}

	// LATER: make armor consideration here!
	float flTake = flDamage;

	// set damage type sustained
	m_bitsDamageType |= bitsDamageType;

	// grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit).
	Vector vecDir(0, 0, 0);

	if (!FNullEnt(pevInflictor))
	{
		CBaseEntity *pInflictor = CBaseEntity::Instance(pevInflictor);

		if (pInflictor)
		{
#ifndef PLAY_GAMEDLL
			vecDir = (pInflictor->Center() - Vector(0, 0, 10) - Center()).Normalize();
#else
			// TODO: fix test demo
			vecDir = NormalizeSubtract<
				float_precision, float, float_precision, float_precision
				>(Center(), pInflictor->Center() - Vector(0, 0, 10));
#endif
			vecDir = g_vecAttackDir = vecDir.Normalize();
		}
	}

	// add to the damage total for clients, which will be sent as a single
	// message at the end of the frame
	// TODO: remove after combining shotgun blasts?
	if (IsPlayer())
	{
		if (pevInflictor)
		{
			pev->dmg_inflictor = ENT(pevInflictor);
		}

		pev->dmg_take += flTake;
	}

	pev->health -= flTake;

	if (m_MonsterState == MONSTERSTATE_SCRIPT)
	{
		SetConditions(bits_COND_LIGHT_DAMAGE);
		return 0;
	}

	if (pev->health <= 0.0f)
	{
		g_pevLastInflictor = pevInflictor;

		if (bitsDamageType & DMG_ALWAYSGIB)
			Killed(pevAttacker, GIB_ALWAYS);

		else if (bitsDamageType & DMG_NEVERGIB)
			Killed(pevAttacker, GIB_NEVER);
		else
			Killed(pevAttacker, GIB_NORMAL);

		g_pevLastInflictor = NULL;
		return 0;
	}
	if ((pev->flags & FL_MONSTER) && !FNullEnt(pevAttacker))
	{
		if (pevAttacker->flags & (FL_MONSTER | FL_CLIENT))
		{
			if (pevInflictor)
			{
				if (m_hEnemy == NULL || pevInflictor == m_hEnemy->pev || !HasConditions(bits_COND_SEE_ENEMY))
					m_vecEnemyLKP = pevInflictor->origin;
			}
			else
			{
				m_vecEnemyLKP = pev->origin + (g_vecAttackDir * 64);
			}

			MakeIdealYaw(m_vecEnemyLKP);

			if (flDamage > 20.0f)
			{
				SetConditions(bits_COND_LIGHT_DAMAGE);
			}

			if (flDamage >= 20.0f)
			{
				SetConditions(bits_COND_HEAVY_DAMAGE);
			}
		}
	}

	return 1;
}
예제 #7
0
void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType)
{
	CBaseEntity *pEntity = NULL;
	TraceResult tr;
	float flAdjustedDamage, falloff;
	Vector vecSpot;

	if (flRadius)
		falloff = flDamage / flRadius;
	else
		falloff = 1.0;

	int bInWater = (UTIL_PointContents(vecSrc) == CONTENTS_WATER);

	// in case grenade is lying on the ground
	vecSrc.z += 1;

	if (!pevAttacker)
		pevAttacker = pevInflictor;

	// iterate on all entities in the vicinity.
	while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecSrc, flRadius)) != NULL)
	{
		if (pEntity->pev->takedamage != DAMAGE_NO)
		{
			// UNDONE: this should check a damage mask, not an ignore
			if (iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore)
				continue;

			// blast's don't tavel into or out of water
			if (bInWater && pEntity->pev->waterlevel == 0)
				continue;

			if (!bInWater && pEntity->pev->waterlevel == 3)
				continue;

			bool useLOS = false;
			float damageRatio = 1.0f;

			if ((bitsDamageType & DMG_EXPLOSION) && g_bIsCzeroGame)
			{
				useLOS = true;
				damageRatio = GetAmountOfPlayerVisible(vecSrc, pEntity);
			}

			damageRatio = GetAmountOfPlayerVisible(vecSrc, pEntity);

			float length;
#ifdef REGAMEDLL_ADD
			// allow to damage breakable objects
			if (FClassnameIs(pEntity->pev, "func_breakable"))
				length = (vecSrc - pEntity->Center()).Length();
			else
#endif
				length = (vecSrc - pEntity->pev->origin).Length();

			if (useLOS)
			{
				if (!flRadius)
					flRadius = flDamage;

				if (!flDamage)
					flRadius = 0;

				flAdjustedDamage = (flRadius - length) * (flRadius - length) * 1.25 / (flRadius * flRadius) * (damageRatio * flDamage) * 1.5;
			}
			else
			{
				flAdjustedDamage = flDamage - length * falloff;
#ifdef REGAMEDLL_ADD
				// disable grenade damage through walls?
				if (hegrenade_penetration.string[0] == '1' && (bitsDamageType & DMG_EXPLOSION))
				{
					UTIL_TraceLine(vecSrc, pEntity->pev->origin, ignore_monsters, NULL, &tr);

					if (tr.flFraction != 1.0f)
						flAdjustedDamage = 0.0f;
				}
#endif
			}

#ifdef REGAMEDLL_FIXES
			// not allow inflict to the player damage is less than 1.0f and to entities not less than 0.0f
			if ((pEntity->Classify() == CLASS_PLAYER && flAdjustedDamage < 1.0f) || flAdjustedDamage <= 0.0f)
				continue;
#else
			if (flAdjustedDamage < 0)
				flAdjustedDamage = 0;
#endif
				pEntity->TakeDamage(pevInflictor, pevAttacker, flAdjustedDamage, bitsDamageType);
		}
	}
}
예제 #8
0
void CElite::SendShine( void )
{
	UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle );

	Vector vecSrc = m_pPlayer->GetGunPosition( ); // + gpGlobals->v_up * -8 + gpGlobals->v_right * 8;
	Vector vecDir = gpGlobals->v_forward;
	Vector vecDest = vecSrc + gpGlobals->v_up * 200;//-100

	edict_t *pentIgnore;
	TraceResult tr;
	pentIgnore = m_pPlayer->edict();

	UTIL_TraceLine(vecSrc, vecDest, dont_ignore_monsters, pentIgnore, &tr);
/*
	
		//UTIL_TraceLine( pev->origin, pev->origin - Vector(0,0,64), ignore_monsters, edict(), &tr );
		Vector		vecSpot;
		TraceResult	tr;

		vecSpot = pev->origin + Vector ( 0 , 0 , 8 );//move up a bit, and trace down.
		UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, 4096 ),  ignore_monsters, pentIgnore, & tr);
*/
		
	if (tr.flFraction != 1.0) // != 1.0)// Hemos tocado algo
	{
		CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
		float flDist = (pEntity->Center() - pev->origin).Length();

		if ( pEntity->IsBSPModel() )
		{
//			ALERT ( at_console, "I touch something!  %f\n", tr.flFraction );
			pev->skin = 0;
		}
		else
		{
//			ALERT ( at_console, "Is not a BSP model  %f\n", tr.flFraction );
		}
	}
	else
	{
//		ALERT ( at_console, "Im seeing the sky!  %f\n", tr.flFraction );
		pev->skin = 1;
	}
/*
	extern short g_sModelIndexLaser;
		MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
			WRITE_BYTE( TE_BEAMPOINTS );
			WRITE_COORD( vecSrc.x );
			WRITE_COORD( vecSrc.y );
			WRITE_COORD( vecSrc.z );

			WRITE_COORD( vecDest.x );
			WRITE_COORD( vecDest.y );
			WRITE_COORD( vecDest.z );
			WRITE_SHORT( g_sModelIndexLaser );
			WRITE_BYTE( 0 ); // framerate
			WRITE_BYTE( 0 ); // framerate

			WRITE_BYTE( 1 ); // life
			WRITE_BYTE( 1 );  // width

			WRITE_BYTE( 0 );   // noise
			WRITE_BYTE( 255 );   // r, g, b
			WRITE_BYTE( 255 );   // r, g, b
			WRITE_BYTE( 255 );   // r, g, b
			WRITE_BYTE( 255 );	// brightness
			WRITE_BYTE( 111 );		// speed
		MESSAGE_END();
*/
	/*
	MESSAGE_BEGIN( MSG_ONE, gmsgSetSkin, NULL, m_pPlayer->pev );
		WRITE_BYTE( pev->skin ); //weaponmodel skin.
	MESSAGE_END();
	*/
}
예제 #9
0
void AvHHealingSpray::FireProjectiles(void)
{
	#ifdef AVH_SERVER
	
	// Look for entities in cone
	CBaseEntity* theCurrentEntity = NULL;
	vec3_t theOriginatingPosition = this->m_pPlayer->GetGunPosition();

	while((theCurrentEntity = UTIL_FindEntityInSphere(theCurrentEntity, theOriginatingPosition, kHealingSprayRange)) != NULL)
	{
		bool isSelf=(theCurrentEntity == this->m_pPlayer);
		// Can't affect self
//		if(theCurrentEntity != this->m_pPlayer)
//		{
			// If entity is in view cone, and within range
			if(isSelf  || this->m_pPlayer->FInViewCone(&theCurrentEntity->pev->origin) )
			{
				// UTIL_FindEntityInSphere doesn't seem to take height into account.  Make sure the entity is within range.
                float theMaxEntitySize = max(Length(theCurrentEntity->pev->mins), Length(theCurrentEntity->pev->maxs));

                vec3_t theVectorDiff;
                VectorSubtract(theCurrentEntity->pev->origin, theOriginatingPosition, theVectorDiff);
				float theDiff = Length(theVectorDiff) - theMaxEntitySize;

                if(theDiff < kHealingSprayRange/2)
				{
					// Make sure entity is in line of fire
					TraceResult tr;
					UTIL_TraceLine(theOriginatingPosition, theCurrentEntity->Center(), dont_ignore_monsters, dont_ignore_glass, ENT(pev)/*pentIgnore*/, &tr);

					CBaseEntity* theBlockedByEntity = CBaseEntity::Instance(tr.pHit);

					if((tr.flFraction == 1.0) || (theBlockedByEntity == theCurrentEntity))
					{
						// Heal friendly player or building in range 
                        float theFocusAmount = 1.0f;
                        if(AvHSHUGetIsWeaponFocusable(AvHWeaponID(this->m_iId)))
                        {
                            theFocusAmount = AvHPlayerUpgrade::GetFocusDamageUpgrade(this->m_pPlayer->pev->iuser4);
                        }
                        
						float theDamage = this->mDamage*theFocusAmount;
						AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theCurrentEntity);
						
						if(theCurrentEntity->pev->team == this->m_pPlayer->pev->team)
						{
							// Players and buildables heal armor too
							AvHBaseBuildable* theBuildable = dynamic_cast<AvHBaseBuildable*>(theCurrentEntity);
							const int theBuildableHealingSprayScalar = BALANCE_VAR(kHealingSprayBuildableScalar);
							if(thePlayer)
							{
								// Players heal by base amount, plus percentage of health
								float thePercentage = BALANCE_VAR(kHealingSprayPlayerPercent)/100.0f;
								theDamage += thePercentage*theCurrentEntity->pev->max_health;
								if ( isSelf ) theDamage *= 0.5f;
								thePlayer->Heal(theDamage, true);
							}
							else if(theBuildable)
							{
								// Structures heal base amount times scalar
                                float theAmount = theDamage*(float)theBuildableHealingSprayScalar;
								if(theBuildable->Regenerate(theAmount, true))
                                {
                                    // Award experience for healing the hive.  Might award a little more if barely wounded, but that seems OK.
                                    if(GetGameRules()->GetIsCombatMode() && (theBuildable->pev->iuser3 == AVH_USER3_HIVE))
                                    {
                                        AvHPlayer* theHealsprayingPlayer = dynamic_cast<AvHPlayer*>(this->m_pPlayer);
                                        if(theHealsprayingPlayer && (theHealsprayingPlayer->pev->team == theBuildable->pev->team))
                                        {
                                            float theCombatHealExperienceScalar = BALANCE_VAR(kCombatHealExperienceScalar);
                                            theHealsprayingPlayer->AwardExperienceForObjective(theAmount*theCombatHealExperienceScalar, theBuildable->GetMessageID());
                                        }
                                    }
                                }
							}
							else
							{
								theCurrentEntity->TakeHealth(theDamage, this->GetDamageType());
							}
						}
						else if(thePlayer)
						{
							thePlayer->TakeDamage(this->pev, this->m_pPlayer->pev, theDamage, this->GetDamageType());
						}
					}
				}
			}
//		}
	}
	
	#endif	
}
예제 #10
0
void CGrappleHook::Move( void ) 
{
	// Fograin92: If owner (player) is dead
	if( !myowner->IsAlive() )
	{
		Killed(pev, 0); // Remove tongue instantly
		return;
	}

	// Fograin92: Player isn't holding attack buttons
	if( !(myowner->pev->button & (IN_ATTACK|IN_ATTACK2)) )
	{
		bPullBack = true;	// Fograin92: We should pull the tongue back
	}

	// Fograin92: Animate pull-back tongue animation ONLY if we didn't hit a monster
	if(bPullBack)
	{
		UTIL_MakeVectors( myowner->pev->v_angle + myowner->pev->punchangle ); 
		Vector GunPosition = myowner->GetGunPosition();
		GunPosition = GunPosition + gpGlobals->v_up * -4 + gpGlobals->v_right * 3 + gpGlobals->v_forward * 6;

		pev->velocity = (GunPosition - pev->origin) * 10;	// Pull back the tongue tip
		float fDistance = (GunPosition - pev->origin).Length2D();	// Calculate distance between tongue tip and player
		//ALERT( at_console, "^2HLU -> ^3weapon_grapple ^2-> %f\n", fDistance );

		if (fDistance < 40)
		{
			Killed(pev, 0);
			return;
		}
		
	}
	else
	{
		// Fograin92: We did hit a monster
		if(m_iHitMonster > 0)
		{
			// Fograin92: Let's "stick" grapple tongue XYZ to target's center XYZ
			pev->origin = myHitMonster->Center();

			// Fograin92: We did hit tiny monster, let's pull it
			if(m_iHitMonster == 2)
			{
				myHitMonster->pev->movetype = MOVETYPE_FLY;	// Remove gravity effect on our pulled monster
				myHitMonster->pev->velocity = (myowner->pev->origin - myHitMonster->pev->origin) * 4;	// Pull our monster
			}

			// Fograin92: Check distance (player <-> monster)
			float fDistance = (myowner->pev->origin - myHitMonster->pev->origin).Length2D();

			// Fograin92: The monster is very close to player, let's OWN IT!
			if (fDistance < 40)
			{
				ALERT( at_console, "^2HLU -> ^3weapon_grapple ^2-> OWNED -> ^3%s\n", STRING(myHitMonster->pev->classname) );

				// Fograin92: Did we pull the gib?
				if( myHitMonster->Classify() == CLASS_GIBS )
					myHitMonster->SUB_Remove();
				else 
					myHitMonster->TakeDamage(myHitMonster->pev, myowner->pev, 10000, DMG_GENERIC);

				Killed(pev, 0);	// Fograin92: Target died, kill tongue
			}

		}
	}

	// Fograin92: If tongue (beam) exists
	if( m_pTongue )
	{
		UTIL_MakeVectors( myowner->pev->v_angle + myowner->pev->punchangle ); 
		Vector GunPosition = myowner->GetGunPosition();
		GunPosition = GunPosition + gpGlobals->v_up * -4 + gpGlobals->v_right * 3 + gpGlobals->v_forward * 6;

		m_pTongue->PointEntInit( GunPosition, this->entindex() );
	}
	else
	{
		// Fograin92: Create tongue (beam)
		m_pTongue = CBeam::BeamCreate( "sprites/_tongue.spr", 8 );
		m_pTongue->SetFlags( 0x20 );	// Solid beam
		m_pTongue->SetColor( 100, 100, 100 );
		m_pTongue->SetScrollRate( 20 );
	}

	pev->nextthink = gpGlobals->time + 0.01;
}
예제 #11
0
//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//
// Returns number of events handled, 0 if none.
//=========================================================
void CISlave :: HandleAnimEvent( MonsterEvent_t *pEvent )
{
	// ALERT( at_console, "event %d : %f\n", pEvent->event, pev->frame );
	switch( pEvent->event )
	{
		case ISLAVE_AE_CLAW:
		{
			// SOUND HERE!
			CBaseEntity *pHurt = CheckTraceHullAttack( 70, gSkillData.slaveDmgClaw, DMG_SLASH );
			if ( pHurt )
			{
				if ( pHurt->pev->flags & (FL_MONSTER|FL_CLIENT) )
				{
					pHurt->pev->punchangle.z = -18;
					pHurt->pev->punchangle.x = 5;
				}
				// Play a random attack hit sound
				EMIT_SOUND_DYN ( ENT(pev), CHAN_WEAPON, pAttackHitSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, m_voicePitch );
			}
			else
			{
				// Play a random attack miss sound
				EMIT_SOUND_DYN ( ENT(pev), CHAN_WEAPON, pAttackMissSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, m_voicePitch );
			}
		}
		break;

		case ISLAVE_AE_CLAWRAKE:
		{
			CBaseEntity *pHurt = CheckTraceHullAttack( 70, gSkillData.slaveDmgClawrake, DMG_SLASH );
			if ( pHurt )
			{
				if ( pHurt->pev->flags & (FL_MONSTER|FL_CLIENT) )
				{
					pHurt->pev->punchangle.z = -18;
					pHurt->pev->punchangle.x = 5;
				}
				EMIT_SOUND_DYN ( ENT(pev), CHAN_WEAPON, pAttackHitSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, m_voicePitch );
			}
			else
			{
				EMIT_SOUND_DYN ( ENT(pev), CHAN_WEAPON, pAttackMissSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, m_voicePitch );
			}
		}
		break;

		case ISLAVE_AE_ZAP_POWERUP:
		{
			// speed up attack when on hard
			if (g_iSkillLevel == SKILL_HARD)
				pev->framerate = 1.5;

			UTIL_MakeAimVectors( pev->angles );

			if (m_iBeams == 0)
			{
				Vector vecSrc = pev->origin + gpGlobals->v_forward * 2;
				MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSrc );
					WRITE_BYTE(TE_DLIGHT);
					WRITE_COORD(vecSrc.x);	// X
					WRITE_COORD(vecSrc.y);	// Y
					WRITE_COORD(vecSrc.z);	// Z
					WRITE_BYTE( 12 );		// radius * 0.1
					WRITE_BYTE( 255 );		// r
					WRITE_BYTE( 180 );		// g
					WRITE_BYTE( 96 );		// b
					WRITE_BYTE( 20 / pev->framerate );		// time * 10
					WRITE_BYTE( 0 );		// decay * 0.1
				MESSAGE_END( );

			}
			if (m_hDead != NULL)
			{
				WackBeam( -1, m_hDead );
				WackBeam( 1, m_hDead );
			}
			else
			{
				ArmBeam( -1 );
				ArmBeam( 1 );
				BeamGlow( );
			}

			EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "debris/zap4.wav", 1, ATTN_NORM, 0, 100 + m_iBeams * 10 );
			pev->skin = m_iBeams / 2;
		}
		break;

		case ISLAVE_AE_ZAP_SHOOT:
		{
			ClearBeams( );

			if (m_hDead != NULL)
			{
				Vector vecDest = m_hDead->pev->origin + Vector( 0, 0, 38 );
				TraceResult trace;
				UTIL_TraceHull( vecDest, vecDest, dont_ignore_monsters, human_hull, m_hDead->edict(), &trace );

				if ( !trace.fStartSolid )
				{
					CBaseEntity *pNew = Create( "monster_alien_slave", m_hDead->pev->origin, m_hDead->pev->angles );
					CBaseMonster *pNewMonster = pNew->MyMonsterPointer( );
					pNew->pev->spawnflags |= 1;
					//sys test
					//pNew->pev->rendermode = kRenderTransTexture;
					pNew->pev->rendermode = kRenderNormal;
					pNew->pev->renderamt = 100;
					pNew->pev->renderfx = 19;
//pev->rendercolor.x = r;
//pev->rendercolor.y = g;
//pev->rendercolor.z = b;
					pNew->pev->rendercolor.x = 50;
					pNew->pev->rendercolor.y = 255;
					pNew->pev->rendercolor.z = 50;
					pNew->pev->health = gSkillData.slaveHealth /2;

					WackBeam( -1, pNew );
					WackBeam( 1, pNew );
					UTIL_Remove( m_hDead );
				//	EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "hassault/hw_shoot1.wav", 1, ATTN_NORM, 0, RANDOM_LONG( 130, 160 ) );
					EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "debris/zap4.wav", 1, ATTN_NORM, 0, 100 + m_iBeams * 10 );

//					if ( mp_am_movecorpses.value != 0  ) //no es cero esta _Activado_
//					{
						CBaseEntity *pEffect = Create( "test_effect", pNew->Center(), pev->angles );
						pEffect->Use( this, this, USE_ON, 1 );

						CBaseEntity *pEffect2 = Create( "env_teleport", pNew->Center(), pev->angles );
						pEffect2->Use( this, this, USE_ON, 1 );

//					}
					break;
				}
			}
			ClearMultiDamage();

			UTIL_MakeAimVectors( pev->angles );

			ZapBeam( -1 );
			ZapBeam( 1 );

			EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "hassault/hw_shoot1.wav", 1, ATTN_NORM, 0, RANDOM_LONG( 130, 160 ) );
			// STOP_SOUND( ENT(pev), CHAN_WEAPON, "debris/zap4.wav" );
			ApplyMultiDamage(pev, pev);

			m_flNextAttack = gpGlobals->time + RANDOM_FLOAT( 0.5, 4.0 );
		}
		break;

		case ISLAVE_AE_ZAP_DONE:
		{
			ClearBeams( );
		}
		break;

		default:
			CSquadMonster::HandleAnimEvent( pEvent );
			break;
	}
}