Воскресенье, 23.07.2017, 20:14
Приветствую Вас Guest | RSS
Главная страница | Статьи | Регистрация | Вход
Меню сайта

Случайный рисунок

Категории каталога
Туториалы по маппингу (HL2) [68]
Туториалы по маппингу для Half-Life
Туториалы по текстурированию (HL2) [10]
Туторы по текстурированию для Half-Life
Туториалы по моделированию (HL2) [9]
Туторы по моделированию для Half-Life
Туториалы по программированию (HL2) [53]
Туторы по прагроммированию для Half-life
Другие туториалы (HL1 и HL2) [4]
Туторы которые не вошли в другие категории
Half-Life 2 Beta [1]
Статьи о npc и weapon в бете Half-Life 2, а так же мануалы и FAQ.
Туториалы по маппингу (HL1) [14]
Туторы по маппингу для Half-Life 1
Туториалы по текстурированию (HL1) [1]
Туторы по текстурированию для Half-Life 1
Туториалы по моделированию (HL1) [1]
Туторы по моделированию для Half-Life 1
Туториалы по программированию (HL1) [30]
Туторы по программированию для Half-Life 1

Наш опрос
Приводить ли сайт в чувство?
Всего ответов: 699

Начало » Статьи » Туториалы по программированию (HL2)

FlashBanG в вашем моде !!!
FlashBanG в вашем моде !!!
Или по русски Слеповуха!!! 
Добрый день! И так... сегодня я вам раааскажу как сделать мммм световоую гранату....
И так... приступим.... создадим файлик на сервере (HL2 DLL) например weapon_flashbang...
в нём напишем:


  
#include "player.h"
#include "gamerules.h"
#include "grenade_flash.h"
#include "npcevent.h"
#include "engine/IEngineSound.h"
#include "items.h"
#include "in_buttons.h"
#include "cbase.h"
#include "NPCEvent.h"
#include "basehlcombatweapon.h"
#include "soundent.h"
#include "ieffects.h"
#include "vstdlib/random.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

#define GRENADE_TIMER 3.0f //Seconds

#define GRENADE_PAUSED_NO 0
#define GRENADE_PAUSED_PRIMARY 1
#define GRENADE_PAUSED_SECONDARY 2

#define GRENADE_RADIUS 4.0f // inches

//-----------------------------------------------------------------------------
// Fragmentation grenades
//-----------------------------------------------------------------------------
class CWeaponFlash: public CBaseHLCombatWeapon
{
DECLARE_CLASS( CWeaponFlash, CBaseHLCombatWeapon );
public:
DECLARE_SERVERCLASS();
virtual float GetFireRate( void ) { return 1; };

void Precache( void );
void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
void PrimaryAttack( void );
void SecondaryAttack( void );
void DecrementAmmo( CBaseCombatCharacter *pOwner );
void ItemPostFrame( void );

bool Deploy( void );
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );

int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }

bool Reload( void );

private:
void ThrowGrenade( CBasePlayer *pPlayer );
void RollGrenade( CBasePlayer *pPlayer );
void LobGrenade( CBasePlayer *pPlayer );
// check a throw from vecSrc. If not valid, move the position back along the line to vecEye
void CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc );

bool m_bRedraw; //Draw the weapon again after throwing a grenade

int m_AttackPaused;
bool m_fDrawbackFinished;

DECLARE_ACTTABLE();

DECLARE_DATADESC();
};


BEGIN_DATADESC( CWeaponFlash )
DEFINE_FIELD( m_bRedraw, FIELD_BOOLEAN ),
DEFINE_FIELD( m_AttackPaused, FIELD_INTEGER ),
DEFINE_FIELD( m_fDrawbackFinished, FIELD_BOOLEAN ),
END_DATADESC()

acttable_t CWeaponFlash::m_acttable[] = 
{
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },
};

IMPLEMENT_ACTTABLE(CWeaponFlash);

IMPLEMENT_SERVERCLASS_ST(CWeaponFlash, DT_WeaponFlash)
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( weapon_flash, CWeaponFlash );
PRECACHE_WEAPON_REGISTER(weapon_flash);

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponFlash::Precache( void )
{
BaseClass::Precache();

UTIL_PrecacheOther( "npc_grenade_flash" );

PrecacheScriptSound( "WeaponFlash.Throw" );
PrecacheScriptSound( "WeaponFlash.Roll" );

m_bRedraw = false;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CWeaponFlash:eploy( void )
{
m_bRedraw = false;
m_fDrawbackFinished = false;

return BaseClass:eploy();
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponFlash::Holster( CBaseCombatWeapon *pSwitchingTo )
{
m_bRedraw = false;
m_fDrawbackFinished = false;

return BaseClass::Holster( pSwitchingTo );
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input : *pEvent - 
// *pOperator - 
//-----------------------------------------------------------------------------
void CWeaponFlash::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
bool fThrewGrenade = false;

switch( pEvent->event )
{
case EVENT_WEAPON_SEQUENCE_FINISHED:
m_fDrawbackFinished = true;
break;

case EVENT_WEAPON_THROW:
ThrowGrenade( pOwner );
DecrementAmmo( pOwner );
fThrewGrenade = true;
break;

case EVENT_WEAPON_THROW2:
RollGrenade( pOwner );
DecrementAmmo( pOwner );
fThrewGrenade = true;
break;

case EVENT_WEAPON_THROW3:
LobGrenade( pOwner );
DecrementAmmo( pOwner );
fThrewGrenade = true;
break;

default:
BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
break;
}

#define RETHROW_DELAY 0.5
if( fThrewGrenade )
{
m_flNextPrimaryAttack = gpGlobals->curtime + RETHROW_DELAY;
m_flNextSecondaryAttack = gpGlobals->curtime + RETHROW_DELAY;
m_flTimeWeaponIdle = FLT_MAX; //NOTE: This is set once the animation has finished up!

// Make a sound designed to scare snipers back into their holes!
CBaseCombatCharacter *pOwner = GetOwner();

if( pOwner )
{
Vector vecSrc = pOwner->Weapon_ShootPosition();
Vector vecDir;

AngleVectors( pOwner->EyeAngles(), &vecDir );

trace_t tr;

UTIL_TraceLine( vecSrc, vecSrc + vecDir * 1024, MASK_SOLID_BRUSHONLY, pOwner, COLLISION_GROUP_NONE, &tr );

CSoundEnt::InsertSound( SOUND_DANGER_SNIPERONLY, tr.endpos, 384, 0.2, pOwner );
}
}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponFlash::Reload( void )
{
if ( !HasPrimaryAmmo() )
return false;

if ( ( m_bRedraw ) && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) && ( m_flNextSecondaryAttack <= gpGlobals->curtime ) )
{
//Redraw the weapon
SendWeaponAnim( ACT_VM_DRAW );

//Update our times
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration();

//Mark this as done
m_bRedraw = false;
}

return true;
}  

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponFlash::SecondaryAttack( void )
{
if ( m_bRedraw )
return;

if ( !HasPrimaryAmmo() )
return;

CBaseCombatCharacter *pOwner = GetOwner();

if ( pOwner == NULL )
return;

CBasePlayer *pPlayer = ToBasePlayer( pOwner );

if ( pPlayer == NULL )
return;

// Note that this is a secondary attack and prepare the grenade attack to pause.
m_AttackPaused = GRENADE_PAUSED_SECONDARY;
SendWeaponAnim( ACT_VM_PULLBACK_LOW );

// Don't let weapon idle interfere in the middle of a throw!
m_flTimeWeaponIdle = FLT_MAX;
m_flNextSecondaryAttack = FLT_MAX;

// If I'm now out of ammo, switch away
if ( !HasPrimaryAmmo() )
{
pPlayer->SwitchToNextBestWeapon( this );
}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponFlash::PrimaryAttack( void )
{
if ( m_bRedraw )
return;

CBaseCombatCharacter *pOwner = GetOwner();

if ( pOwner == NULL )

return;
}

CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );;



if ( !pPlayer )
return;

// Note that this is a primary attack and prepare the grenade attack to pause.
m_AttackPaused = GRENADE_PAUSED_PRIMARY;
SendWeaponAnim( ACT_VM_PULLBACK_HIGH );

// Put both of these off indefinitely. We do not know how long
// the player will hold the grenade.
m_flTimeWeaponIdle = FLT_MAX;
m_flNextPrimaryAttack = FLT_MAX;

// If I'm now out of ammo, switch away
if ( !HasPrimaryAmmo() )
{
pPlayer->SwitchToNextBestWeapon( this );
}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input : *pOwner - 
//-----------------------------------------------------------------------------
void CWeaponFlash:ecrementAmmo( CBaseCombatCharacter *pOwner )
{
pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponFlash::ItemPostFrame( void )
{
if( m_fDrawbackFinished )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

if (pOwner)
{
switch( m_AttackPaused )
{
case GRENADE_PAUSED_PRIMARY:
if( !(pOwner->m_nButtons & IN_ATTACK) )
{
SendWeaponAnim( ACT_VM_THROW );
m_fDrawbackFinished = false;
}
break;

case GRENADE_PAUSED_SECONDARY:
if( !(pOwner->m_nButtons & IN_ATTACK2) )
{
//See if we're ducking
if ( pOwner->m_nButtons & IN_DUCK )
{
//Send the weapon animation
SendWeaponAnim( ACT_VM_SECONDARYATTACK );
}
else
{
//Send the weapon animation
SendWeaponAnim( ACT_VM_HAULBACK );
}

m_fDrawbackFinished = false;
}
break;

default:
break;
}
}
}

BaseClass::ItemPostFrame();

if ( m_bRedraw )
{
if ( IsViewModelSequenceFinished() )
{
Reload();
}
}
}

// check a throw from vecSrc. If not valid, move the position back along the line to vecEye
void CWeaponFlash::CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc )
{
trace_t tr;

UTIL_TraceHull( vecEye, vecSrc, -Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2), Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2), 
pPlayer->PhysicsSolidMaskForEntity(), pPlayer, pPlayer->GetCollisionGroup(), &tr );

if ( tr.DidHit() )
{
vecSrc = tr.endpos;
}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input : *pPlayer - 
//-----------------------------------------------------------------------------
void CWeaponFlash::ThrowGrenade( CBasePlayer *pPlayer )
{
Vector vecEye = pPlayer->EyePosition();
Vector vForward, vRight;

pPlayer->EyeVectors( &vForward, &vRight, NULL );
Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f;
CheckThrowPosition( pPlayer, vecEye, vecSrc );
// vForward[0] += 0.1f;
vForward[2] += 0.1f;

Vector vecThrow;
pPlayer->GetVelocity( &vecThrow, NULL );
vecThrow += vForward * 1200;
Flashgrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, GRENADE_TIMER );
pPlayer->ViewPunch( QAngle(random->RandomFloat( -5, 10 ),0,0) );

// CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
/*CFlare *pFlare = CFlare::Create( pOwner->Weapon_ShootPosition(), pOwner->EyeAngles(), pOwner, FLARE_DURATION );
Vector forward;
pOwner->EyeVectors( &forward );
pFlare->SetAbsVelocity( forward * 700 );

if ( pFlare == NULL )
return;
*/

m_bRedraw = true;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input : *pPlayer - 
//-----------------------------------------------------------------------------
void CWeaponFlash::LobGrenade( CBasePlayer *pPlayer )
{
Vector vecEye = pPlayer->EyePosition();
Vector vForward, vRight;

pPlayer->EyeVectors( &vForward, &vRight, NULL );
Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f + Vector( 0, 0, -8 );
CheckThrowPosition( pPlayer, vecEye, vecSrc );

Vector vecThrow;
pPlayer->GetVelocity( &vecThrow, NULL );
vecThrow += vForward * 350 + Vector( 0, 0, 50 );
Flashgrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(200,random->RandomInt(-600,600),0), pPlayer, GRENADE_TIMER );

WeaponSound( WPN_DOUBLE );

m_bRedraw = true;
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input : *pPlayer - 
//-----------------------------------------------------------------------------
void CWeaponFlash::RollGrenade( CBasePlayer *pPlayer )
{
// BUGBUG: Hardcoded grenade width of 4 - better not change the model 
Vector vecSrc;
pPlayer->CollisionProp()->NormalizedToWorldSpace( Vector( 0.5f, 0.5f, 0.0f ), &vecSrc );
vecSrc.z += GRENADE_RADIUS;

Vector vecFacing = pPlayer->BodyDirection2D( );
// no up/down direction
vecFacing.z = 0;
VectorNormalize( vecFacing );
trace_t tr;
UTIL_TraceLine( vecSrc, vecSrc - Vector(0,0,16), MASK_PLAYERSOLID, pPlayer, COLLISION_GROUP_NONE, &tr );
if ( tr.fraction != 1.0 )
{
// compute forward vec parallel to floor plane and roll grenade along that
Vector tangent;
CrossProduct( vecFacing, tr.plane.normal, tangent );
CrossProduct( tr.plane.normal, tangent, vecFacing );
}
vecSrc += (vecFacing * 18.0);
CheckThrowPosition( pPlayer, pPlayer->WorldSpaceCenter(), vecSrc );

Vector vecThrow;
pPlayer->GetVelocity( &vecThrow, NULL );
vecThrow += vecFacing * 700;
// put it on its side
QAngle orientation(0,pPlayer->GetLocalAngles().y,-90);
// roll it
AngularImpulse rotSpeed(0,0,720);
Flashgrenade_Create( vecSrc, orientation, vecThrow, rotSpeed, pPlayer, GRENADE_TIMER );

WeaponSound( SPECIAL1 );

m_bRedraw = true;
}





С этим всё... дале там-же создадим файл grenade_flash.cpp
Вот его код:

  #include "cbase.h"
#include "basegrenade_shared.h"
#include "grenade_flash.h"
#include "Sprite.h"
#include "SpriteTrail.h"
#include "soundent.h"
#include "particle_smokegrenade.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

#define FLASH_GRENADE_BLIP_FREQUENCY 1.0f
#define FLASH_GRENADE_BLIP_FAST_FREQUENCY 0.3f

#define FLASH_GRENADE_GRACE_TIME_AFTER_PICKUP 1.5f

const float GRENADE_COEFFICIENT_OF_RESTITUTION = 0.2f;
/*
ConVar sk_plr_dmg_fraggrenade ( "sk_plr_dmg_fraggrenade","0");
ConVar sk_npc_dmg_fraggrenade ( "sk_npc_dmg_fraggrenade","0");
*/
ConVar sk_flashgrenade_radius ( "sk_flashgrenade_radius", "0");

#define FLASHGRENADE_MODEL "models/Weapons/w_flashgrenade.mdl"

class CGrenadeFlash : public CBaseGrenade
{
DECLARE_CLASS( CGrenadeFlash, CBaseGrenade );

#if !defined( CLIENT_DLL )
DECLARE_DATADESC();
#endif

~CGrenadeFlash( void );

public:
void Spawn( void );
void OnRestore( void );
void Precache( void );
bool CreateVPhysics( void );
void CreateEffects( void );
void SetTimer( float detonateDelay, float warnDelay );
void SetVelocity( const Vector &velocity, const AngularImpulse &angVelocity );
int OnTakeDamage( const CTakeDamageInfo &inputInfo );
void BlipSound() { EmitSound( "Grenade.Blip" ); }
void DelayThink();
void CreateSmokeTrail( void );
void VPhysicsUpdate( IPhysicsObject *pPhysics );
void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
protected:
CHandle m_pMainGlow;
CHandle m_pGlowTrail;

float m_flNextBlipTime;
bool m_inSolid;
};

LINK_ENTITY_TO_CLASS( npc_grenade_flash, CGrenadeFlash );

BEGIN_DATADESC( CGrenadeFlash )

// Fields
DEFINE_FIELD( m_pMainGlow, FIELD_EHANDLE ),
DEFINE_FIELD( m_pGlowTrail, FIELD_EHANDLE ),
DEFINE_FIELD( m_flNextBlipTime, FIELD_TIME ),
DEFINE_FIELD( m_inSolid, FIELD_BOOLEAN ),

// Function Pointers
DEFINE_THINKFUNC( DelayThink ),

END_DATADESC()


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CGrenadeFlash::~CGrenadeFlash( void )
{
}


void RadiusFlash( 
Vector vecSrc, 
CBaseEntity *pevInflictor, 
CBaseEntity *pevAttacker, 
float flDamage, 
int iClassIgnore, 
int bitsDamageType )
{
CBaseEntity *pEntity = NULL;
trace_t tr;
float flAdjustedDamage, falloff;
Vector vecSpot;
float flRadius = 1500;


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

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

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

if ( !pevAttacker )
pevAttacker = pevInflictor;

// iterate on all entities in the vicinity.
while ((pEntity = gEntList.FindEntityInSphere( pEntity, vecSrc, flRadius )) != NULL)
{
// get the heck out of here if it aint a player.
if (pEntity->IsPlayer() == FALSE)
continue;

if (( pEntity->m_takedamage != DAMAGE_NO ) && (pEntity->m_lifeState != LIFE_DEAD))
{
// blast's don't tavel into or out of water
if (bInWater && pEntity->GetWaterLevel() == 0)
continue;
if (!bInWater && pEntity->GetWaterLevel() == 3)
continue;

vecSpot = pEntity->BodyTarget( vecSrc );

UTIL_TraceLine( vecSrc, vecSpot, MASK_SHOT, pevInflictor, COLLISION_GROUP_NONE, &tr );

if ( tr.fraction == 1.0 || tr.m_pEnt == pEntity )
{// the explosion can 'see' this entity, so hurt them!
if (tr.startsolid)
{
// if we're stuck inside them, fixup the position and distance
tr.endpos = vecSrc;
tr.fraction = 0.0;
}

// decrease damage for an ent that's farther from the bomb.
flAdjustedDamage = ( vecSrc - tr.endpos ).Length() * falloff;
flAdjustedDamage = flDamage - flAdjustedDamage;

if ( flAdjustedDamage < 0 )
{
flAdjustedDamage = 0;
}

Vector vecLOS;
float flDot;
Vector vForward;
AngleVectors( pEntity->EyeAngles(), &vForward );

vecLOS = ( vecSrc - (pEntity->EyePosition()));

flDot = DotProduct (vecLOS, vForward);


float fadeTime, fadeHold;
int alpha;

// if target is facing the bomb, the effect lasts longer
if (flDot >= 0.0)
{
fadeTime = flAdjustedDamage * 3.0f;
fadeHold = flAdjustedDamage / 1.5f;
alpha = 255;
}
else
{
fadeTime = flAdjustedDamage * 1.75f;
fadeHold = flAdjustedDamage / 3.5f;
alpha = 200;
}

color32 clr = { 255, 255, 255, 255 };
UTIL_ScreenFade( pEntity, clr, fadeTime, fadeHold, FFADE_IN );

//MIKETODO: bots
/*
CBasePlayer *pPlayer = static_cast( pEntity );
if (pPlayer->IsBot())
{
// blind the bot
CCSBot *pBot = static_cast( pPlayer );
pBot->Blind( 0.33f * fadeTime );
}
*/
}
}
}
}


void CGrenadeFlash::Spawn( void )
{
Precache( );

SetModel( FLASHGRENADE_MODEL );

if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() )
{
//m_flDamage = sk_plr_dmg_fraggrenade.GetFloat();
m_DmgRadius = sk_flashgrenade_radius.GetFloat();
}
else
{
//m_flDamage = sk_npc_dmg_fraggrenade.GetFloat();
m_DmgRadius = sk_flashgrenade_radius.GetFloat();
}

m_takedamage = DAMAGE_YES;
m_iHealth = 1;

SetSize( -Vector(4,4,4), Vector(4,4,4) );
SetCollisionGroup( COLLISION_GROUP_WEAPON );
CreateVPhysics();

CreateEffects();

BlipSound();
m_flNextBlipTime = gpGlobals->curtime + FLASH_GRENADE_BLIP_FREQUENCY;

AddSolidFlags( FSOLID_NOT_STANDABLE );

BaseClass::Spawn();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CGrenadeFlash::OnRestore( void )
{
CreateEffects();

BaseClass::OnRestore();


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CGrenadeFlash::CreateEffects( void )
{
// Start up the eye glow
//m_pMainGlow = CSprite::SpriteCreate( "sprites/redglow1.vmt", GetLocalOrigin(), false );

// int nAttachment = LookupAttachment( "fuse" );

/* if ( m_pMainGlow != NULL )
{
m_pMainGlow->FollowEntity( this );
m_pMainGlow->SetAttachment( this, nAttachment );
m_pMainGlow->SetTransparency( kRenderGlow, 255, 255, 255, 200, kRenderFxNoDissipation );
m_pMainGlow->SetScale( 0.2f );
m_pMainGlow->SetGlowProxySize( 4.0f );
}

// Start up the eye trail
// m_pGlowTrail = CSpriteTrail::SpriteTrailCreate( "sprites/bluelaser1.vmt", GetLocalOrigin(), false );

if ( m_pGlowTrail != NULL )
{
m_pGlowTrail->FollowEntity( this );
m_pGlowTrail->SetAttachment( this, nAttachment );
m_pGlowTrail->SetTransparency( kRenderTransAdd, 255, 0, 0, 255, kRenderFxNone );
m_pGlowTrail->SetStartWidth( 8.0f );
m_pGlowTrail->SetEndWidth( 1.0f );
m_pGlowTrail->SetLifeTime( 0.5f );
}
*/
}

bool CGrenadeFlash::CreateVPhysics()
{
// Create the object in the physics system
VPhysicsInitNormal( SOLID_BBOX, 0, false );
return true;
}

// this will hit only things that are in newCollisionGroup, but NOT in collisionGroupAlreadyChecked
class CTraceFilterCollisionGroupDelta : public CTraceFilterEntitiesOnly
{
public:
// It does have a base, but we'll never network anything below here..
DECLARE_CLASS_NOBASE( CTraceFilterCollisionGroupDelta );

CTraceFilterCollisionGroupDelta( const IHandleEntity *passentity, int collisionGroupAlreadyChecked, int newCollisionGroup )
: m_pPassEnt(passentity), m_collisionGroupAlreadyChecked( collisionGroupAlreadyChecked ), m_newCollisionGroup( newCollisionGroup )
{
}

virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
{
if ( !PassServerEntityFilter( pHandleEntity, m_pPassEnt ) )
return false;
CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity );

if ( pEntity )
{
if ( g_pGameRules->ShouldCollide( m_collisionGroupAlreadyChecked, pEntity->GetCollisionGroup() ) )
return false;
if ( g_pGameRules->ShouldCollide( m_newCollisionGroup, pEntity->GetCollisionGroup() ) )
return true;
}

return false;
}

protected:
const IHandleEntity *m_pPassEnt;
int m_collisionGroupAlreadyChecked;
int m_newCollisionGroup;
};

void CGrenadeFlash::VPhysicsUpdate( IPhysicsObject *pPhysics )
{
BaseClass::VPhysicsUpdate( pPhysics );
Vector vel;
AngularImpulse angVel;
pPhysics->GetVelocity( &vel, &angVel );

Vector start = GetAbsOrigin();
// find all entities that my collision group wouldn't hit, but COLLISION_GROUP_NONE would and bounce off of them as a ray cast
CTraceFilterCollisionGroupDelta filter( this, GetCollisionGroup(), COLLISION_GROUP_NONE );
trace_t tr;

// UNDONE: Hull won't work with hitboxes - hits outer hull. But the whole point of this test is to hit hitboxes.
#if 0
UTIL_TraceHull( start, start + vel * gpGlobals->frametime, CollisionProp()->OBBMins(), CollisionProp()->OBBMaxs(), CONTENTS_HITBOX|CONTENTS_MONSTER|CONTENTS_SOLID, &filter, &tr );
#else
UTIL_TraceLine( start, start + vel * gpGlobals->frametime, CONTENTS_HITBOX|CONTENTS_MONSTER|CONTENTS_SOLID, &filter, &tr );
#endif
if ( tr.startsolid )
{
if ( !m_inSolid )
{
// UNDONE: Do a better contact solution that uses relative velocity?
vel *= -GRENADE_COEFFICIENT_OF_RESTITUTION; // bounce backwards
pPhysics->SetVelocity( &vel, NULL );
}
m_inSolid = true;
return;
}
m_inSolid = false;
if ( tr.DidHit() )
{
Vector dir = vel;
VectorNormalize(dir);
// send a tiny amount of damage so the character will react to getting bonked
CTakeDamageInfo info( this, GetThrower(), pPhysics->GetMass() * vel, GetAbsOrigin(), 0.1f, DMG_CRUSH );
tr.m_pEnt->TakeDamage( info );

// reflect velocity around normal
vel = -2.0f * tr.plane.normal * DotProduct(vel,tr.plane.normal) + vel;

// absorb 80% in impact
vel *= GRENADE_COEFFICIENT_OF_RESTITUTION;
angVel *= -0.5f;
pPhysics->SetVelocity( &vel, &angVel );
}
}


void CGrenadeFlash::Precache( void )
{
PrecacheModel( FLASHGRENADE_MODEL );
PrecacheScriptSound( "Grenade.Blip" );
BaseClass::Precache();
}

void CGrenadeFlash::SetTimer( float detonateDelay, float warnDelay )
{
m_flDetonateTime = gpGlobals->curtime + detonateDelay;
m_flWarnAITime = gpGlobals->curtime + warnDelay;
SetThink( &CGrenadeFlash:elayThink );
SetNextThink( gpGlobals->curtime );
}

void CGrenadeFlash::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason )
{
#ifdef HL2MP
SetTimer( FLASH_GRENADE_GRACE_TIME_AFTER_PICKUP, FLASH_GRENADE_GRACE_TIME_AFTER_PICKUP / 2);
SetThrower( pPhysGunUser );

BlipSound();
m_flNextBlipTime = gpGlobals->curtime + FLASH_GRENADE_BLIP_FAST_FREQUENCY;
m_bHasWarnedAI = true;
#endif

BaseClass::OnPhysGunPickup( pPhysGunUser, reason );
}

void CGrenadeFlash:elayThink() 
{
RadiusFlash ( GetAbsOrigin(), this, false, 4, CLASS_NONE, DMG_BLAST );

if( gpGlobals->curtime > m_flDetonateTime )
{
AddEffects( EF_NODRAW );
return;
}

if( !m_bHasWarnedAI && gpGlobals->curtime >= m_flWarnAITime )
{
#if !defined( CLIENT_DLL )
CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), 400, 1.5, this );
#endif
m_bHasWarnedAI = true;
}

if( gpGlobals->curtime > m_flNextBlipTime )
{
BlipSound();

if( m_bHasWarnedAI )
{
m_flNextBlipTime = gpGlobals->curtime + FLASH_GRENADE_BLIP_FAST_FREQUENCY;
}
else
{
m_flNextBlipTime = gpGlobals->curtime + FLASH_GRENADE_BLIP_FREQUENCY;
}
}

SetNextThink( gpGlobals->curtime + 0.1 );
}

void CGrenadeFlash::SetVelocity( const Vector &velocity, const AngularImpulse &angVelocity )
{
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
if ( pPhysicsObject )
{
pPhysicsObject->AddVelocity( &velocity, &angVelocity );
}
}


int CGrenadeFlash::OnTakeDamage( const CTakeDamageInfo &inputInfo )
{
// Manually apply vphysics because BaseCombatCharacter takedamage doesn't call back to CBaseEntity OnTakeDamage
VPhysicsTakeDamage( inputInfo );

// Grenades only suffer blast damage and burn damage.
if( !(inputInfo.GetDamageType() & (DMG_BLAST|DMG_BURN) ) )
return 0;

return BaseClass::OnTakeDamage( inputInfo );
}


CBaseGrenade *Flashgrenade_Create( 
const Vector &position, 
const QAngle &angles, 
const Vector &velocity, 
const AngularImpulse &angVelocity, 
CBaseCombatCharacter *pOwner, 
float timer )
{
CGrenadeFlash *pGrenade = (CGrenadeFlash *)CBaseEntity::Create( "npc_grenade_flash", position, angles, pOwner );

// Set the timer for 1 second less than requested. We're going to issue a SOUND_DANGER
// one second before detonation.
pGrenade->SetTimer( timer, timer - 1.5f );
pGrenade->SetVelocity( velocity, angVelocity );
pGrenade->SetThrower( ToBaseCombatCharacter( pOwner ) );
pGrenade->m_takedamage = DAMAGE_EVENTS_ONLY;

pGrenade->SetThink( &CGrenadeFlash:elayThink );
pGrenade->SetNextThink( gpGlobals->curtime + timer );

return pGrenade;
}

 



Теперь нам нужен ещё h файл... создадим: grenade_flash.h
Code:

   
#ifndef GRENADE_FLASH_H
#define GRENADE_FLASH_H
#pragma once

class CBaseGrenade;
struct edict_t;
#include "basegrenade_shared.h"
CBaseGrenade *Flashgrenade_Create( 
const Vector &position, 
const QAngle &angles, 
const Vector &velocity, 
const AngularImpulse &angVelocity, 
CBaseCombatCharacter *pOwner, 
float timer );
  



С серверной частью закончили... теперь собсно обратимся к клиенту...
ну тут мало... короче откроем файлик c_weapon__stubs_hl2.cpp
в нём после слов: STUB_WEAPON_CLASS( weapon_frag, WeaponFrag, C_BaseHLCombatWeapon );
напишем:


   STUB_WEAPON_CLASS( weapon_flash, WeaponFlash, C_BaseHLCombatWeapon );   



Всё компилируем... затем добавим в папку scripts файлик weapon_flash.txt туда собсно всё писанём... запускаем мод.. give weapon_flash и вуаля!!!


Источник: http://bbs.nashalife.ru/forumdisplay.php?s=&forumid=99
Категория: Туториалы по программированию (HL2) | Добавил: DetLeR (14.07.2007) | Автор: Fena
Просмотров: 2647 | Комментарии: 2 | Рейтинг: 0.0 |

Всего комментариев: 2
2  
[quote]Всё компилируем... затем добавим в папку scripts файлик weapon_flash.txt туда собсно всё писанём... запускаем мод.. give weapon_flash и вуаля!!![/quote]
что надо прописать в weapon_flash.txt?
напишите на мыло плизз x13_ok@bk.ru

1  
Этот тотур с конкретным глюком. Много чего не хватило((

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Кто в Онлайн

Друзья сайта

Баннеры

  Сайт CrazyArts   Black   Сообщество сайтов о Half-Life   Самый   Только   Все   hl2 top 100     Rambler's Top100  

игры
игры

  Каталог сайтов Планета Топ 100 - Planet Top 100       ТОП ЛУЧШИХ ИГРОВЫХ САЙТОВ           Detroit Team Site :: Моды от Detroit Team, видео, новости.   Naruto-kun[Звезда Наруто]  


The idea of dising: Homie7