2020-08-31 18:50:41 +02:00
|
|
|
/***
|
|
|
|
*
|
|
|
|
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
|
|
*
|
|
|
|
* This product contains software technology licensed from Id
|
|
|
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use, distribution, and modification of this source code and/or resulting
|
|
|
|
* object code is restricted to non-commercial enhancements to products from
|
|
|
|
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
|
|
* without written permission from Valve LLC.
|
|
|
|
*
|
|
|
|
****/
|
|
|
|
#include "extdll.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "cbase.h"
|
|
|
|
#include "monsters.h"
|
|
|
|
#include "weapons.h"
|
|
|
|
#include "animation.h"
|
|
|
|
#include "effects.h"
|
|
|
|
#include "nodes.h"
|
|
|
|
#include "explode.h"
|
|
|
|
#include "player.h"
|
|
|
|
|
|
|
|
#define FIRE_SPRITE_NAME "sprites/flame2.spr"
|
|
|
|
#define BURNIND_SOUND_NAME "ambience/burning1.wav"
|
|
|
|
|
|
|
|
// must match definition in modelgen.h
|
|
|
|
enum synctype_t
|
|
|
|
{
|
|
|
|
ST_SYNC=0,
|
|
|
|
ST_RAND
|
|
|
|
};
|
|
|
|
|
|
|
|
// TODO: shorten these?
|
|
|
|
typedef struct {
|
|
|
|
int ident;
|
|
|
|
int version;
|
|
|
|
int type;
|
|
|
|
int texFormat;
|
|
|
|
float boundingradius;
|
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
int numframes;
|
|
|
|
float beamlength;
|
|
|
|
synctype_t synctype;
|
|
|
|
} dsprite_t;
|
|
|
|
|
|
|
|
class CPropExplosion : public CGrenade
|
|
|
|
{
|
|
|
|
void Spawn( void );
|
|
|
|
void Precache( void );
|
|
|
|
int BloodColor( void ) { return DONT_BLEED; };
|
|
|
|
|
|
|
|
void EXPORT PropThink( void );
|
|
|
|
|
|
|
|
void RunFire( void );
|
|
|
|
void StartExplode( void );
|
|
|
|
|
|
|
|
float CalculationSpriteScale( );
|
|
|
|
|
|
|
|
void KeyValue( KeyValueData *pkvd );
|
|
|
|
|
|
|
|
virtual int Save( CSave &save );
|
|
|
|
virtual int Restore( CRestore &restore );
|
|
|
|
|
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
|
|
|
|
|
|
|
string_t m_iszParentName;
|
|
|
|
|
|
|
|
int m_startHealth;
|
|
|
|
float m_firetime;
|
|
|
|
float m_explosiontime;
|
|
|
|
float m_dmgradius;
|
|
|
|
bool m_isfire;
|
|
|
|
};
|
|
|
|
|
|
|
|
LINK_ENTITY_TO_CLASS( prop_explosion, CPropExplosion );
|
|
|
|
|
|
|
|
TYPEDESCRIPTION CPropExplosion::m_SaveData[] =
|
|
|
|
{
|
|
|
|
DEFINE_FIELD( CPropExplosion, m_startHealth, FIELD_INTEGER ),
|
|
|
|
DEFINE_FIELD( CPropExplosion, m_firetime, FIELD_FLOAT ),
|
|
|
|
DEFINE_FIELD( CPropExplosion, m_explosiontime, FIELD_FLOAT ),
|
|
|
|
DEFINE_FIELD( CPropExplosion, m_dmgradius, FIELD_FLOAT ),
|
|
|
|
DEFINE_FIELD( CPropExplosion, m_isfire, FIELD_INTEGER ),
|
|
|
|
};
|
|
|
|
|
|
|
|
IMPLEMENT_SAVERESTORE( CPropExplosion, CGrenade );
|
|
|
|
|
|
|
|
void CPropExplosion :: KeyValue( KeyValueData *pkvd )
|
|
|
|
{
|
|
|
|
if (FStrEq(pkvd->szKeyName, "health"))//skin is used for content type
|
|
|
|
{
|
|
|
|
m_startHealth = atoi(pkvd->szValue);
|
|
|
|
pkvd->fHandled = TRUE;
|
|
|
|
}
|
|
|
|
else if (FStrEq(pkvd->szKeyName, "firetime"))
|
|
|
|
{
|
|
|
|
m_firetime = atof(pkvd->szValue);
|
|
|
|
pkvd->fHandled = TRUE;
|
|
|
|
}
|
|
|
|
else if (FStrEq(pkvd->szKeyName, "damageradius"))
|
|
|
|
{
|
|
|
|
m_dmgradius = atof(pkvd->szValue);
|
|
|
|
pkvd->fHandled = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
CGrenade::KeyValue( pkvd );
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPropExplosion :: Spawn( void )
|
|
|
|
{
|
|
|
|
Precache( );
|
|
|
|
// motor
|
|
|
|
pev->movetype = MOVETYPE_FLY;
|
|
|
|
pev->solid = SOLID_BBOX;
|
|
|
|
|
|
|
|
SET_MODEL( ENT(pev), STRING(pev->model) );
|
|
|
|
|
|
|
|
Vector mins;
|
|
|
|
Vector maxs;
|
|
|
|
|
|
|
|
ExtractBbox( pev->sequence, mins, maxs );
|
|
|
|
|
|
|
|
UTIL_SetSize(pev, mins, maxs ); //Whi it is not using for other entities ?
|
|
|
|
UTIL_SetOrigin( this, pev->origin );
|
|
|
|
|
|
|
|
DROP_TO_FLOOR( edict() );
|
|
|
|
|
|
|
|
pev->nextthink = gpGlobals->time + 0.1;
|
|
|
|
|
|
|
|
// SetTouch( PropTouch ); //maybe later
|
|
|
|
SetThink( PropThink );
|
|
|
|
|
|
|
|
//If not defined, add standart value
|
|
|
|
if(!m_startHealth )
|
|
|
|
{
|
|
|
|
m_startHealth = 50;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!m_firetime)
|
|
|
|
{
|
|
|
|
m_firetime = 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!m_dmgradius )
|
|
|
|
{
|
|
|
|
m_dmgradius = 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_isfire = false;
|
|
|
|
|
|
|
|
pev->flags |= FL_MONSTER;
|
|
|
|
pev->takedamage = DAMAGE_YES;
|
|
|
|
pev->health = m_startHealth;
|
|
|
|
pev->dmg = 50;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPropExplosion::Precache( void )
|
|
|
|
{
|
|
|
|
PRECACHE_MODEL((char *)STRING(pev->model));
|
|
|
|
PRECACHE_MODEL( FIRE_SPRITE_NAME );
|
|
|
|
PRECACHE_SOUND( BURNIND_SOUND_NAME );
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPropExplosion::PropThink( void )
|
|
|
|
{
|
|
|
|
if( pev->health < m_startHealth )
|
|
|
|
{
|
|
|
|
if(!m_explosiontime)
|
|
|
|
{
|
|
|
|
m_explosiontime = gpGlobals->time + m_firetime;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( m_explosiontime < gpGlobals->time )
|
|
|
|
{
|
|
|
|
StartExplode( );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RunFire( );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pev->nextthink = gpGlobals->time + 0.1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPropExplosion::RunFire( void )
|
|
|
|
{
|
|
|
|
if(!m_isfire )
|
|
|
|
{
|
|
|
|
CSprite *pSprite = CSprite::SpriteCreate( FIRE_SPRITE_NAME, pev->origin, TRUE );
|
|
|
|
|
|
|
|
pSprite->AnimateAndDie( m_firetime );
|
|
|
|
pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation );
|
|
|
|
pSprite->SetScale( CalculationSpriteScale() );
|
|
|
|
|
|
|
|
EMIT_SOUND(ENT(pev), CHAN_WEAPON, BURNIND_SOUND_NAME, 1, ATTN_NORM);
|
|
|
|
|
|
|
|
m_isfire = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CPropExplosion::StartExplode( void )
|
|
|
|
{
|
|
|
|
STOP_SOUND( ENT(pev), CHAN_WEAPON, BURNIND_SOUND_NAME );
|
|
|
|
|
|
|
|
UTIL_ScreenShake( pev->origin, 16, 200, 5, m_dmgradius );
|
|
|
|
|
|
|
|
ExplosionCreate( pev->origin, pev->angles, edict(), (int)m_dmgradius, true );
|
|
|
|
|
|
|
|
UTIL_Remove( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
float CPropExplosion::CalculationSpriteScale( )
|
|
|
|
{
|
|
|
|
dsprite_t *szSprite = NULL;
|
|
|
|
|
|
|
|
float SpriteX = 0;
|
|
|
|
float SpriteY = 0;
|
|
|
|
|
|
|
|
float ModelX = 0;
|
|
|
|
float ModelY = 0;
|
|
|
|
|
|
|
|
szSprite = (dsprite_t *)g_engfuncs.pfnLoadFileForMe( FIRE_SPRITE_NAME, NULL );
|
|
|
|
|
|
|
|
if (!szSprite)
|
|
|
|
{
|
|
|
|
ALERT( at_aiconsole,"Couldn't open fire sprites !\n");
|
|
|
|
|
|
|
|
return 1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SpriteX = szSprite->width;
|
|
|
|
SpriteY = szSprite->height;
|
|
|
|
|
|
|
|
g_engfuncs.pfnFreeFile( szSprite );
|
|
|
|
|
|
|
|
Vector mins;
|
|
|
|
Vector maxs;
|
|
|
|
|
|
|
|
ExtractBbox( pev->sequence, mins, maxs );
|
|
|
|
|
|
|
|
ModelX = maxs.x - mins.x;
|
|
|
|
ModelY = maxs.z - mins.z;
|
|
|
|
|
|
|
|
float FullSprSizeX = ModelX * 3; //pixel to unit ~ 2 ???
|
|
|
|
float FullSprSizeY = ModelY * 3;
|
|
|
|
|
|
|
|
float ScaleX = FullSprSizeX / SpriteX;
|
|
|
|
float ScaleY = FullSprSizeY / SpriteY;
|
|
|
|
|
|
|
|
float Averagescale = ( ScaleX + ScaleY ) / 2;
|
|
|
|
|
|
|
|
//Debug
|
|
|
|
/*
|
|
|
|
ALERT( at_console, "Sprite: x = %f, y = %f\n", SpriteX, SpriteY );
|
|
|
|
ALERT( at_console, "Model: x = %f, y = %f\n", ModelX, ModelY );
|
|
|
|
|
|
|
|
ALERT( at_console, "Full Sprite size: x = %f, y = %f\n", SpriteX * Averagescale, SpriteY * Averagescale );
|
|
|
|
ALERT( at_console, "Scale: x = %f, y = %f\n", ScaleX, ScaleY );
|
|
|
|
ALERT( at_console, "Average Scale: %f", Averagescale );
|
|
|
|
*/
|
|
|
|
|
|
|
|
return Averagescale;
|
2020-08-31 00:15:53 +02:00
|
|
|
}
|