19 Mar 2010

This commit is contained in:
g-cont 2010-03-19 00:00:00 +03:00 committed by Alibek Omarov
parent 790df98906
commit c48cdf25e0
35 changed files with 659 additions and 600 deletions

View File

@ -165,7 +165,7 @@ void TE_ParseExplosion( void )
char szDecal[32];
sprintf( szDecal, "{scorch%i", RANDOM_LONG( 1, 3 ));
g_pTempEnts->PlaceDecal( pos2, scale * 24, szDecal );
g_pTempEnts->PlaceDecal( pos2, 48.0f, szDecal );
if( !( flags & TE_EXPLFLAG_NOSOUND ))
{
@ -406,7 +406,7 @@ void TE_ParseBSPDecal( void )
}
pEntity = GetEntityByIndex( entityIndex );
g_pTempEnts->PlaceDecal( pos, 5.0f, decalIndex );
g_pTempEnts->PlaceDecal( pos, 2.0f, decalIndex );
}
/*
@ -768,7 +768,7 @@ void TE_ParseDecal( int type )
if( type == TE_DECALHIGH || type == TE_WORLDDECALHIGH )
decalIndex += 256;
g_pTempEnts->PlaceDecal( pos, 5.0f, decalIndex );
g_pTempEnts->PlaceDecal( pos, 2.0f, decalIndex );
}
/*

View File

@ -197,6 +197,13 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
m_fLerp = 1.0f;
else m_fLerp = GetLerpFrac();
if( state->flags & FL_PROJECTILE && state->ed_flags & ( ESF_NO_PREDICTION|ESF_NODELTA ))
{
// cut rocket trail, dont pass it from teleport
// FIXME: don't work
g_pViewRenderBeams->KillDeadBeams( ent );
}
// copy state to progs
ent->v.modelindex = state->modelindex;
ent->v.weaponmodel = state->weaponmodel;

View File

@ -269,7 +269,7 @@ void EV_HLDM_CrowbarDecalTrace( TraceResult *pTrace, char *decalName )
// only decal brush models such as the world etc.
if( decalName && decalName[0] && pEnt && ( pEnt->v.solid == SOLID_BSP || pEnt->v.movetype == MOVETYPE_PUSHSTEP ) )
{
g_pTempEnts->PlaceDecal( pTrace->vecEndPos, 5.0f, decalName );
g_pTempEnts->PlaceDecal( pTrace->vecEndPos, 2.0f, decalName );
}
}

View File

@ -1063,7 +1063,7 @@ void CTempEnts::MuzzleFlash( edict_t *pEnt, int iAttachment, int type )
pTemp->renderMode = kRenderTransAdd;
pTemp->renderAmt = 255;
pTemp->renderFX = 0;
pTemp->die = gpGlobals->time + 0.01; // die at next frame
pTemp->die = gpGlobals->time + 0.015; // die at next frame
pTemp->m_flFrame = RANDOM_LONG( 0, frameCount - 1 );
pTemp->m_flFrameMax = frameCount - 1;
pTemp->clientIndex = pEnt->serialnumber;

View File

@ -306,7 +306,7 @@ void V_PreRender( ref_params_t *pparams )
//==========================
void V_CalcGlobalFog( ref_params_t *pparams )
{
int bOn = (pparams->waterlevel < 2) && (gHUD.m_flStartDist > 0) && (gHUD.m_flEndDist > 0);
int bOn = (pparams->waterlevel < 2) && (gHUD.m_flStartDist > 0) && (gHUD.m_flEndDist > 0 && gHUD.m_flStartDist);
g_engfuncs.pTriAPI->Fog( gHUD.m_vecFogColor, gHUD.m_flStartDist, gHUD.m_flEndDist, bOn );
}

View File

@ -718,6 +718,11 @@ void CFuncTeleport :: Touch( CBaseEntity *pOther )
{
Vector vecOriginOffs = pTarget->pev->origin - pLandmark->pev->origin;
if( pOther->pev->flags & FL_PROJECTILE )
{
pOther->pev->angles = UTIL_VecToAngles( pOther->pev->velocity );
}
// do we need to rotate the entity?
if ( pLandmark->pev->angles != pTarget->pev->angles )
{

View File

@ -1518,6 +1518,13 @@ int AddToFullPack( edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflag
default: return 0; // skipped
}
if( bIsPortalPass && (pEdict->v.flags & FL_PROJECTILE) && pEdict->v.teleport_time )
{
// HACKHACK - add grenades, rockets and other things that passed teleport into portal PVS
// as potentially visible. This is only for single frame.
return 1;
}
if( !ENGINE_CHECK_AREA( pEdict, hostarea ))
{
// blocked by a door

View File

@ -2317,10 +2317,10 @@ void UTIL_SetFogAll( Vector color, int iFadeTime, int iStartDist, int iEndDist )
{
// loop through all players
if(IsMultiplayer())
if( IsMultiplayer( ))
{
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
UTIL_SetFog( color, iFadeTime, iStartDist, iEndDist, i );
for ( int i = 0; i < gpGlobals->maxClients; i++ )
UTIL_SetFog( color, iFadeTime, iStartDist, iEndDist, i+1 );
}
else UTIL_SetFog( color, iFadeTime, iStartDist, iEndDist );
}

View File

@ -16,13 +16,6 @@
#include <stdlib.h>
#include <string.h>
#pragma warning( disable : 4244 )
// hack into header files that we can ship
typedef int qboolean;
typedef unsigned char byte;
//#include "../utils/common/mathlib.h"
#include "extdll.h"
#include "const.h"
#include "studio_ref.h"

View File

@ -193,8 +193,9 @@ public:
virtual Schedule_t *GetScheduleOfType( int Type );
virtual Schedule_t *GetSchedule( void );
virtual void ScheduleChange( void ) {}
virtual int CanPlaySequence( void ) { return ((m_pCine == NULL) && (m_MonsterState == MONSTERSTATE_NONE || m_MonsterState == MONSTERSTATE_IDLE || m_IdealMonsterState == MONSTERSTATE_IDLE)); }
virtual int CanPlaySequence( BOOL fDisregardState, int interruptLevel );
// virtual int CanPlaySequence( void ) { return ((m_pCine == NULL) && (m_MonsterState == MONSTERSTATE_NONE || m_MonsterState == MONSTERSTATE_IDLE || m_IdealMonsterState == MONSTERSTATE_IDLE)); }
virtual int CanPlaySequence( int interruptFlags );
// virtual int CanPlaySequence( BOOL fDisregardState, int interruptLevel );
virtual int CanPlaySentence( BOOL fDisregardState ) { return IsAlive(); }
virtual void PlaySentence( const char *pszSentence, float duration, float volume, float attenuation );
virtual void PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener );

View File

@ -52,13 +52,10 @@ Vector VecBModelOrigin( entvars_t* pevBModel )
/*QUAKED func_wall (0 .5 .8) ?
This is just a solid wall if not inhibited
*/
#define SF_FUNCWALL_ROTATE 1
class CFuncWall : public CBaseEntity
{
public:
void Spawn( void );
//void PostSpawn(void); //AJH
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual STATE GetState( void ) { return pev->frame?STATE_ON:STATE_OFF; };
@ -73,26 +70,14 @@ LINK_ENTITY_TO_CLASS( func_wall, CFuncWall );
void CFuncWall :: Spawn( void )
{
// If it can't move/go away, it's really part of the world
if (!m_pMoveWith) //LRC
pev->flags |= FL_WORLDBRUSH;
pev->angles = g_vecZero;
/* if (pev->spawnflags & SF_FUNCWALL_ROTATE){ //AJH - Now we can rotate complex stuff on spawn - Doesn't work!!!
ALERT(at_debug,"DEBUG: Rotate flag set, rotating brush in 0.1seconds\n");
pev->flags &= !FL_WORLDBRUSH;
SetThink(&CFuncWall::PostSpawn);
SetNextThink(0.1);
}
*/
pev->angles = g_vecZero;
pev->movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
pev->solid = SOLID_BSP;
SET_MODEL( ENT(pev), STRING(pev->model) );
// If it can't move/go away, it's really part of the world
if (!m_pMoveWith) //LRC
pev->flags |= FL_WORLDBRUSH;
//LRC
if (m_iStyle >= 32) LIGHT_STYLE(m_iStyle, "a");
@ -100,17 +85,6 @@ void CFuncWall :: Spawn( void )
}
/*
void CFuncWall :: PostSpawn (){ //AJH - Bug, this doesn't work, I have no idea why.
ALERT(at_debug,"DEBUG: Rotating from %f %f %f ", pev->angles.x,pev->angles.y,pev->angles.z);
//UTIL_AssignAngles(this,pev->vuser1);
pev->angles = pev->vuser1;
ALERT(at_debug,"to %f %f %f\n",pev->angles.x,pev->angles.y,pev->angles.z);
ALERT(at_debug,"String vuser1 = %s\n",pev->vuser1);
DontThink();
}
*/
void CFuncWall :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( ShouldToggle( useType, (int)(pev->frame)) )
@ -558,11 +532,6 @@ void CFuncRotating :: Spawn( )
UTIL_SetOrigin(this, pev->origin);
SET_MODEL( ENT(pev), STRING(pev->model) );
if(pev->origin == g_vecZero)//G-Cont. Set custom orirgin. Don't right work :(
{
UTIL_SetOrigin(this, VecBModelOrigin(pev));
ALERT(at_console, "DEBUG: Using custom origin: Rotate object coordinates is %f %f %f \n", pev->origin.x, pev->origin.y, pev->origin.z);
}
SetUse(&CFuncRotating :: RotatingUse );
// did level designer forget to assign speed?
if (pev->speed <= 0)
@ -681,7 +650,7 @@ void CFuncRotating :: HurtTouch ( CBaseEntity *pOther )
// pev->dmg = pev->avelocity.Length() / 10;
if (m_hActivator)
pOther->TakeDamage( pev, m_hActivator->pev, pev->dmg, DMG_CRUSH ); //AJH Attribute damage to he who switched me.
pOther->TakeDamage( pev, m_hActivator->pev, pev->dmg, DMG_CRUSH );
else
pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH );

View File

@ -1302,14 +1302,13 @@ void CLaser::TurnOn( void )
void CLaser::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
int active = (GetState() == STATE_ON);
if ( !ShouldToggle( useType, active ) )
return;
if ( active )
TurnOff();
else {
m_hActivator = pActivator; //AJH Storage variable to allow *locus start/end positions
else
TurnOn();
}
}
@ -1335,9 +1334,6 @@ void CLaser::FireAtPoint( Vector startpos, TraceResult &tr )
BeamDamage( &tr );
DoSparks( startpos, tr.vecEndPos );
SetEndPos( tr.vecEndPos );
if ( m_pStartSprite )
UTIL_SetOrigin( m_pStartSprite, tr.vecEndPos );
BeamDamage( &tr );
DoSparks( GetStartPos(), tr.vecEndPos );
}
@ -1347,18 +1343,18 @@ void CLaser::StrikeThink( void )
Vector startpos = pev->origin;
if (m_iszStartPosition)
{
startpos = CalcLocus_Position(this, m_hActivator, STRING(m_iszStartPosition)); //AJH allow *locus start/end positions
startpos = CalcLocus_Position(this, NULL, STRING(m_iszStartPosition));
}
if (m_iTowardsMode)
{
m_firePosition = startpos + CalcLocus_Velocity(this, m_hActivator, STRING(pev->message)); //AJH allow *locus start/end positions
m_firePosition = startpos + CalcLocus_Velocity(this, NULL, STRING(pev->message));
}
else
{
CBaseEntity *pEnd = RandomTargetname( STRING(pev->message) );
if ( pEnd ) m_firePosition = CalcLocus_Position(this,pEnd,STRING(pev->message));
if ( pEnd ) m_firePosition = pEnd->pev->origin;
}
TraceResult tr;
@ -2617,14 +2613,7 @@ void CBlood::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTyp
UTIL_TraceLine( start, start + forward * BloodAmount() * 2, ignore_monsters, NULL, &tr );
if ( tr.flFraction != 1.0 )
{
int blood;
if(Color() == BLOOD_COLOR_RED)blood = 1;
else if(Color() == BLOOD_COLOR_YELLOW)blood = 2;
CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit );
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&tr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pHit->entindex(), blood, 0, 0 );
//UTIL_BloodDecalTrace( &tr, Color() );
}
UTIL_BloodDecalTrace( &tr, Color() );
}
}
@ -3343,7 +3332,6 @@ void CEnvFootsteps::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
#define EXTENT_ARCING 2
#define EXTENT_OBSTRUCTED_REVERSE 3
#define EXTENT_ARCING_REVERSE 4
#define EXTENT_ARCING_THROUGH 5 //AJH
class CEnvRain : public CBaseEntity
{
@ -3505,8 +3493,8 @@ void CEnvRain::Spawn( void )
if (m_pitch)
pev->angles.x = m_pitch;
// else if (pev->angles.x == 0) // don't allow horizontal rain. //AJH -Why not?
// pev->angles.x = 90;
else if (pev->angles.x == 0) // don't allow horizontal rain.
pev->angles.x = 90;
if (m_burstSize == 0) // in case the level designer forgot to set it.
m_burstSize = 2;
@ -3587,10 +3575,6 @@ void CEnvRain::Think( void )
if (tr.flFraction == 1.0) bDraw = FALSE;
vecDest = tr.vecEndPos;
break;
case EXTENT_ARCING_THROUGH: //AJH - Arcs full length of brush only when blocked
UTIL_TraceLine( vecDest, vecSrc, dont_ignore_monsters, NULL, &tr);
if (tr.flFraction == 1.0) bDraw = FALSE;
break;
case EXTENT_ARCING_REVERSE:
UTIL_TraceLine( vecDest, vecSrc, ignore_monsters, NULL, &tr);
if (tr.flFraction == 1.0) bDraw = FALSE;
@ -4289,6 +4273,7 @@ void CItemSoda::CanTouch ( CBaseEntity *pOther )
//=========================================================
// LRC - env_fog, extended a bit from the DMC version
// g-cont - fix save\load issues, add multiplayer support
//=========================================================
#define SF_FOG_ACTIVE 1
#define SF_FOG_FADING 0x8000
@ -4297,14 +4282,10 @@ class CEnvFog : public CBaseEntity
{
public:
void Spawn( void );
void Precache( void );
void EXPORT ResumeThink( void );
void EXPORT Resume2Think( void );
void EXPORT TurnOn( void );
void EXPORT TurnOff( void );
void EXPORT FadeInDone( void );
void EXPORT FadeOutDone( void );
void SendData( Vector col, int fFadeTime, int StartDist, int iEndDist);
void KeyValue( KeyValueData *pkvd );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
@ -4395,22 +4376,10 @@ void CEnvFog :: Spawn ( void )
UTIL_DesiredThink( this );
}
// Precache is now used only to continue after a game has loaded.
// Precache();
// things get messed up if we try to draw fog with a startdist
// or an enddist of 0, so we don't allow it.
if (m_iStartDist == 0) m_iStartDist = 1;
if (m_iEndDist == 0) m_iEndDist = 1;
}
void CEnvFog :: Precache ( void )
{
if (pev->spawnflags & SF_FOG_ACTIVE)
{
SetThink(&CEnvFog :: ResumeThink );
SetNextThink( 0.1 );
}
if (m_iEndDist == 0) m_iEndDist = 1000;
}
extern int gmsgSetFog;
@ -4421,17 +4390,17 @@ void CEnvFog :: TurnOn ( void )
pev->spawnflags |= SF_FOG_ACTIVE;
UTIL_SetFogAll( pev->rendercolor, m_iFadeIn, m_iStartDist, m_iEndDist );
if( m_iFadeIn )
{
pev->spawnflags |= SF_FOG_FADING;
SendData( pev->rendercolor, m_iFadeIn, m_iStartDist, m_iEndDist);
SetNextThink( m_iFadeIn );
SetThink(&CEnvFog :: FadeInDone );
}
else
{
pev->spawnflags &= ~SF_FOG_FADING;
SendData( pev->rendercolor, 0, m_iStartDist, m_iEndDist);
if (m_fHoldTime)
{
SetNextThink( m_fHoldTime );
@ -4446,36 +4415,24 @@ void CEnvFog :: TurnOff ( void )
pev->spawnflags &= ~SF_FOG_ACTIVE;
UTIL_SetFogAll( pev->rendercolor, -m_iFadeOut, m_iStartDist, m_iEndDist );
if( m_iFadeOut )
{
pev->spawnflags |= SF_FOG_FADING;
SendData( pev->rendercolor, -m_iFadeOut, m_iStartDist, m_iEndDist);
SetNextThink( m_iFadeOut );
SetThink(&CEnvFog :: FadeOutDone );
}
else
{
pev->spawnflags &= ~SF_FOG_FADING;
SendData( g_vecZero, 0, 0, 0 );
DontThink();
}
}
//yes, this intermediate think function is necessary.
// the engine seems to ignore the nextthink time when starting up.
// So this function gets called immediately after the precache finishes,
// regardless of what nextthink time is specified.
void CEnvFog :: ResumeThink ( void )
{
// ALERT(at_console, "Fog resume %f\n", gpGlobals->time);
SetThink(&CEnvFog ::FadeInDone);
SetNextThink(0.1);
}
void CEnvFog :: FadeInDone ( void )
{
pev->spawnflags &= ~SF_FOG_FADING;
SendData( pev->rendercolor, 0, m_iStartDist, m_iEndDist);
if (m_fHoldTime)
{
@ -4487,7 +4444,6 @@ void CEnvFog :: FadeInDone ( void )
void CEnvFog :: FadeOutDone ( void )
{
pev->spawnflags &= ~SF_FOG_FADING;
SendData( g_vecZero, 0, 0, 0);
}
void CEnvFog :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
@ -4501,32 +4457,6 @@ void CEnvFog :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use
TurnOn();
}
}
void CEnvFog :: SendData ( Vector col, int iFadeTime, int iStartDist, int iEndDist )
{
// ALERT(at_console, "Fog send (%d %d %d), %d - %d\n", col.x, col.y, col.z, iStartDist, iEndDist);
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = (CBasePlayer*)UTIL_PlayerByIndex( i );
if ( pPlayer )
{
MESSAGE_BEGIN( MSG_ONE, gmsgSetFog, NULL, pPlayer->pev );
WRITE_BYTE ( col.x );
WRITE_BYTE ( col.y );
WRITE_BYTE ( col.z );
WRITE_SHORT ( iFadeTime );
WRITE_SHORT ( iStartDist );
WRITE_SHORT ( iEndDist );
MESSAGE_END();
// pPlayer->m_iFogStartDist = iStartDist;
// pPlayer->m_iFogEndDist = iEndDist;
// pPlayer->m_vecFogColor = col;
// pPlayer->m_bClientFogRefresh = FALSE;
}
}
}
LINK_ENTITY_TO_CLASS( env_fog, CEnvFog );
//=========================================================

View File

@ -412,7 +412,7 @@ CGrenade * CGrenade:: ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector v
pGrenade->pev->gravity = 0.5;
pGrenade->pev->friction = 0.8;
SET_MODEL(ENT(pGrenade->pev), "models/w_grenade.mdl");
SET_MODEL(ENT(pGrenade->pev), "models/hgrenade.mdl");
pGrenade->pev->dmg = 100;
return pGrenade;

View File

@ -68,6 +68,7 @@ void CHandGrenade::Precache( void )
PRECACHE_MODEL("models/w_grenade.mdl");
PRECACHE_MODEL("models/v_grenade.mdl");
PRECACHE_MODEL("models/p_grenade.mdl");
PRECACHE_MODEL("models/hgrenade.mdl"); // physic model. Xash3D requires it
}
int CHandGrenade::GetItemInfo(ItemInfo *p)

View File

@ -52,7 +52,7 @@ Vector CalcLocus_Velocity( CBaseEntity *pEntity, CBaseEntity *pLocus, const char
return g_vecZero;
}
float CalcLocus_Ratio( CBaseEntity *pLocus, const char *szText ,int mode) //AJH added 'mode' = ratio to return
float CalcLocus_Ratio( CBaseEntity *pLocus, const char *szText )
{
if ((*szText >= '0' && *szText <= '9') || *szText == '-')
{ // assume it's a float
@ -60,19 +60,12 @@ float CalcLocus_Ratio( CBaseEntity *pLocus, const char *szText ,int mode) //AJH
}
CBaseEntity *pCalc = UTIL_FindEntityByTargetname(NULL, szText, pLocus);
if (pCalc != NULL){
//ALERT(at_debug,"Entity \"%s\" found, calling CalcRatio, mode %i.\n",szText,mode);
return pCalc->CalcRatio( pLocus );
}else{
ALERT(at_aiconsole, "Bad or missing calc_ratio entity \"%s\", mode %i\n", szText,mode); // MJB/AJH - might need to be supressed; this error is often returned when there is no error
return 0; // we need some signal for "fail". NaN, maybe?
}
}
float CalcLocus_Ratio( CBaseEntity *pLocus, const char *szText) //AJH calls new CalcLocusRatio
{
return CalcLocus_Ratio(pLocus,szText,0);
if (pCalc != NULL)
return pCalc->CalcRatio( pLocus );
ALERT(at_error, "Bad or missing calc_ratio entity \"%s\"\n", szText);
return 0; // we need some signal for "fail". NaN, maybe?
}
//=============================================
@ -417,15 +410,15 @@ Vector CCalcPosition::CalcPosition( CBaseEntity *pLocus )
class CCalcRatio : public CPointEntity
{
public:
float CalcRatio( CBaseEntity *pLocus, int mode );
float CalcRatio( CBaseEntity *pLocus );
};
LINK_ENTITY_TO_CLASS( calc_ratio, CCalcRatio );
float CCalcRatio::CalcRatio( CBaseEntity *pLocus, int mode) //AJH 'mode' (ratio to return is overridden)
float CCalcRatio::CalcRatio( CBaseEntity *pLocus )
{
//ALERT(at_debug,"Calc_ratio 'ratio_to_return' is %i\n",pev->skin);
float fBasis = CalcLocus_Ratio( pLocus, STRING(pev->target),pev->skin); //AJH pev->skin is 'ratio to return'
float fBasis = CalcLocus_Ratio( pLocus, STRING(pev->target));
switch (pev->impulse)
{
case 1: fBasis = 1-fBasis; break; //reversed
@ -433,8 +426,8 @@ LINK_ENTITY_TO_CLASS( calc_ratio, CCalcRatio );
case 3: fBasis = 1/fBasis; break; //reciprocal
}
fBasis += CalcLocus_Ratio( pLocus, STRING(pev->netname),pev->body); //AJH pev->body is 'ratio to return'
fBasis = fBasis * CalcLocus_Ratio( pLocus, STRING(pev->message),pev->button);//AJH pev->iuser3 is 'ratio to return'
fBasis += CalcLocus_Ratio( pLocus, STRING(pev->netname));
fBasis = fBasis * CalcLocus_Ratio( pLocus, STRING(pev->message));
if (!FStringNull(pev->noise))
{
@ -488,98 +481,10 @@ LINK_ENTITY_TO_CLASS( calc_ratio, CCalcRatio );
else
return fBasis;
}
/*// calc_angletransform by MJB.
#define SF_ANGLETRANS_DEBUG 1 // MJB - debug info
class CCalcAngleTransform : public CPointEntity {
public:
Vector CalcVelocity( CBaseEntity *pLocus );
};
LINK_ENTITY_TO_CLASS( calc_angletransform, CCalcAngleTransform );
Vector CCalcAngleTransform::CalcVelocity( CBaseEntity *pLocus ) {
Vector vecBasis1 = CalcLocus_Velocity( this, pLocus, STRING(pev->netname)); // netname: input 1 velocity
if (pev->modelindex != 0) { // modelindex: is 0 - Y Z X
vecBasis1 = UTIL_VecToAngles( vecBasis1 ); // is 1 - [LV]
if(pev->spawnflags & SF_ANGLETRANS_DEBUG)
ALERT(at_debug,"VecToAngles(vecBasis1)\n"); // WOOT! Gotcha lil' bastard! You'll never deceive me again.
}
float basis1;
switch(pev->skin) { // skin: input 1 axis
case 0:basis1=vecBasis1.x;break;
case 1:basis1=vecBasis1.y;break;
case 2:basis1=vecBasis1.z;break;
default:ALERT(at_debug,"Invalid input-1 axis\n");break;
}
Vector vecBasis2 = CalcLocus_Velocity( this, pLocus, STRING(pev->message)); // message: input 2 velocity
if (pev->button != 0) { // button: is 0 - Y Z X
vecBasis2 = UTIL_VecToAngles( vecBasis2 ); // is 1 - [LV]
if(pev->spawnflags & SF_ANGLETRANS_DEBUG)
ALERT(at_debug,"VecToAngles(vecBasis2)\n"); // WOOT! And the same to you!
}
float basis2;
switch(pev->body) { // body: input 2 axis
case 0:basis2=vecBasis2.x;break;
case 1:basis2=vecBasis2.y;break;
case 2:basis2=vecBasis2.z;break;
default:ALERT(at_debug,"Invalid input-2 axis\n");break;
}
float pi = 3.14159;
float transformation;
switch(pev->effects) { // effects: choose calculation
case 0:transformation=basis1;break; // output = basis1
case 1:transformation=basis1+basis2;break; // add
case 2:transformation=basis1-basis2;break; // subtract
case 3:transformation=basis1*basis2;break; // multiply
case 4:transformation=basis1/basis2;break; // divide
case 5:transformation=basis1*sin(basis2*pi/180);break; // basis1 * sin(basis2)
case 6:transformation=basis1*cos(basis2*pi/180);break; // basis1 * cos(basis2)
case 7:transformation=basis1*tan(basis2*pi/180);break; // basis1 * tan(basis2)
case 8:transformation=basis1*(transformation=sin(basis2*pi/180))*transformation;break; // basis1 * sin²(basis2)
case 9:transformation=basis1*(transformation=cos(basis2*pi/180))*transformation;break; // basis1 * cos²(basis2)
case 10:transformation=basis1*(transformation=tan(basis2*pi/180))*transformation;break; // basis1 * tan²(basis2)
default:ALERT(at_debug,"Invalid transformation\n");break;
}
Vector vecOutput = Vector(0, 0, 0); // This is 'mister empty vector' to make sure that whatever targets this only inherits the desired axis.
switch(pev->impulse) { // impulse: choose output axis
case 0:vecOutput = Vector(transformation, 0, 0);break;
case 1:vecOutput = Vector(0, transformation, 0);break;
case 2:vecOutput = Vector(0, 0, transformation);break;
default:{ALERT(at_debug,"Invalid output axis\n");break;}
}
if(pev->spawnflags & SF_ANGLETRANS_DEBUG)
ALERT(at_debug,"Input-1 = %f, Input-2 = %f, Transformation = %f, Result = %f %f %f\n", basis1,basis2,transformation,vecOutput.x,vecOutput.y,vecOutput.z);
// OK - our work here is done. Now spit it out (makevectors vecoutput??)!!
UTIL_MakeVectors( vecOutput );
return (gpGlobals->v_forward);
// MJB There are two problems with this entity, which is why its commented out:
// Problem 1) Whenever it is used, all world surfaces are duplicated and the whole (duplicated) map's corner is positioned where you put the entity(s)
// Problem 2) When targeting this with a motion_manager, the 'roll' value appears to be completely ignored - no idea if the problem lies in the motion_manager or in here.
}*/
//=======================================================
#define SF_CALCVELOCITY_NORMALIZE 1
#define SF_CALCVELOCITY_SWAPZ 2 // MJB this should more correctly be called 'invertZ', but never mind.
#define SF_CALCVELOCITY_SWAPXY 4 // MJB axis swapping (pitch and yaw)
#define SF_CALCVELOCITY_SWAPYZ 8 // MJB axis swapping (yaw and roll)
#define SF_CALCVELOCITY_SWAPXZ 16 // MJB axis swapping (pitch and roll)
#define SF_CALCVELOCITY_DEBUGSWAP 32 // So what the hell is the swapping DOING?
#define SF_CALCVELOCITY_SWAPZ 2
class CCalcSubVelocity : public CPointEntity
{
Vector Convert( CBaseEntity *pLocus, Vector vecVel );
@ -601,7 +506,7 @@ Vector CCalcSubVelocity::CalcVelocity( CBaseEntity *pLocus )
{
case 1: //angles
return ConvertAngles( pLocus, pLocus->pev->angles );
case 2: //viewangles
case 2: //v_angle
return ConvertAngles( pLocus, pLocus->pev->viewangles );
case 5:
// this could cause problems.
@ -645,7 +550,6 @@ Vector CCalcSubVelocity::ConvertAngles( CBaseEntity *pLocus, Vector vecAngles )
}
//=======================================================
class CCalcVelocityPath : public CPointEntity
{
@ -737,57 +641,13 @@ Vector CCalcVelocityPolar::CalcVelocity( CBaseEntity *pLocus )
Vector vecBasis = CalcLocus_Velocity( this, pLocus, STRING(pev->netname) );
Vector vecAngles = UTIL_VecToAngles( vecBasis ) + pev->angles;
Vector vecOffset = CalcLocus_Velocity( this, pLocus, STRING(pev->message) );
float fFactor = CalcLocus_Ratio( pLocus, STRING(pev->noise) );
if (!(pev->spawnflags & SF_CALCVELOCITY_NORMALIZE))
fFactor = fFactor * vecBasis.Length();
/*float tempswap;
// MJB I've tried adding this code so I can swap the vector components,
// but for some reason it just isn't working. I have no idea why.
// Perhaps YOU know why and could fix it?
if(pev->spawnflags & SF_CALCVELOCITY_SWAPXY) { // MJB axis swapping - X and Y
tempswap = vecAngles.y;
vecAngles.y = vecAngles.x;
vecAngles.x = tempswap;
if(pev->spawnflags & SF_CALCVELOCITY_DEBUGSWAP)
ALERT(at_debug,"Swapping Pitch = %f, Yaw = %f, Temporary = %f\n", vecAngles.x,vecAngles.y,tempswap);
}
if(pev->spawnflags & SF_CALCVELOCITY_SWAPYZ) { // MJB axis swapping - Y and Z
tempswap = vecAngles.z;
vecAngles.z = vecAngles.y;
vecAngles.y = tempswap;
if(pev->spawnflags & SF_CALCVELOCITY_DEBUGSWAP)
ALERT(at_debug,"Swapping Yaw = %f, Roll = %f, Temporary = %f\n", vecAngles.y,vecAngles.z,tempswap);
}
if(pev->spawnflags & SF_CALCVELOCITY_SWAPXZ) { // MJB axis swapping - X and Z
tempswap = vecAngles.z;
vecAngles.z = vecAngles.x;
vecAngles.x = tempswap;
if(pev->spawnflags & SF_CALCVELOCITY_DEBUGSWAP)
ALERT(at_debug,"Swapping Pitch = %f, Roll = %f, Temporary = %f\n", vecAngles.x,vecAngles.z,tempswap);
}
// MJB I've tried adding this code so I can swap the vector components,
// but for some reason it just isn't working. I have no idea why.
// Perhaps YOU know why and could fix it?
*/
UTIL_MakeVectors( vecAngles );
/* MJB - a vain attempt at debugging the nonbehaving code.
if(pev->spawnflags & SF_CALCVELOCITY_SWAPXY) // MJB axis swapping - X and Y
ALERT(at_debug,"** Swapping Pitch = %f, Yaw = %f, Temporary = %f\n", vecAngles.x,vecAngles.y,tempswap);
if(pev->spawnflags & SF_CALCVELOCITY_SWAPYZ) // MJB axis swapping - Y and Z
ALERT(at_debug,"** Swapping Yaw = %f, Roll = %f, Temporary = %f\n", vecAngles.y,vecAngles.z,tempswap);
if(pev->spawnflags & SF_CALCVELOCITY_SWAPXZ) // MJB axis swapping - X and Z
ALERT(at_debug,"** Swapping Pitch = %f, Roll = %f, Temporary = %f\n", vecAngles.x,vecAngles.z,tempswap); */
return (gpGlobals->v_forward * fFactor) + vecOffset;
}
@ -798,7 +658,7 @@ class CMark : public CPointEntity
{
public:
Vector CalcVelocity(CBaseEntity *pLocus) { return pev->movedir; }
float CalcRatio(CBaseEntity *pLocus, int mode ) { return pev->frags; }//AJH added 'mode' = ratio to return
float CalcRatio(CBaseEntity *pLocus) { return pev->frags; }
void Think( void ) { SUB_Remove(); }
};
@ -808,7 +668,7 @@ public:
void Spawn( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
Vector CalcVelocity(CBaseEntity *pLocus) { return pev->movedir; }
float CalcRatio(CBaseEntity *pLocus, int mode ) { return pev->frags; }//AJH added 'mode' = ratio to return
float CalcRatio(CBaseEntity *pLocus) { return pev->frags; }
void KeyValue( KeyValueData *pkvd );
virtual int Save( CSave &save );

View File

@ -1,4 +1,3 @@
Vector CalcLocus_Position ( CBaseEntity *pEntity, CBaseEntity *pLocus, const char *szText );
Vector CalcLocus_Velocity ( CBaseEntity *pEntity, CBaseEntity *pLocus, const char *szText );
float CalcLocus_Ratio ( CBaseEntity *pLocus, const char *szText);
float CalcLocus_Ratio ( CBaseEntity *pLocus, const char *szText,int mode ); //AJH added 'mode' = ratio to return
float CalcLocus_Ratio ( CBaseEntity *pLocus, const char *szText);

View File

@ -1250,7 +1250,6 @@ void CBaseMonster :: SetActivity ( Activity NewActivity )
else
{
// Not available try to get default anim
// ZAEBALO!!!!!
ALERT ( at_aiconsole, "%s has no sequence for act:%d\n", STRING(pev->classname), NewActivity );
pev->sequence = 0; // Set to the reset anim (if it's there)
}
@ -3130,15 +3129,32 @@ BOOL CBaseMonster :: FCheckAITrigger ( void )
//LRC - to help debug when sequences won't play...
#define DEBUG_CANTPLAY
int CBaseMonster :: CanPlaySequence( BOOL fDisregardState, int interruptLevel )
int CBaseMonster :: CanPlaySequence( int interruptFlags )
{
if ( m_pCine || !IsAlive() || m_MonsterState == MONSTERSTATE_PRONE )
if ( m_pCine )
{
if ( interruptFlags & SS_INTERRUPT_SCRIPTS )
{
return true;
}
else
{
#ifdef DEBUG_CANTPLAY
ALERT(at_debug, "CANTPLAY: Already playing %s \"%s\"!\n", STRING(m_pCine->pev->classname), STRING(m_pCine->pev->targetname));
#endif
return false;
}
}
else if ( !IsAlive() || m_MonsterState == MONSTERSTATE_PRONE )
{
#ifdef DEBUG_CANTPLAY
ALERT(at_debug, "CANTPLAY: Dead/Barnacled!\n");
#endif
// monster is already running a scripted sequence or dead!
return FALSE;
}
if ( fDisregardState )
if ( interruptFlags & SS_INTERRUPT_ANYSTATE )
{
// ok to go, no matter what the monster state. (scripted AI)
return TRUE;
@ -3150,10 +3166,13 @@ int CBaseMonster :: CanPlaySequence( BOOL fDisregardState, int interruptLevel )
return TRUE;
}
if ( m_MonsterState == MONSTERSTATE_ALERT && interruptLevel >= SS_INTERRUPT_BY_NAME )
if ( m_MonsterState == MONSTERSTATE_ALERT && interruptFlags & SS_INTERRUPT_ALERT )
return TRUE;
// unknown situation
#ifdef DEBUG_CANTPLAY
ALERT(at_debug, "CANTPLAY: non-interruptable state.\n");
#endif
return FALSE;
}
@ -3222,14 +3241,16 @@ BOOL CBaseMonster :: FindLateralCover ( const Vector &vecThreat, const Vector &v
Vector CBaseMonster :: ShootAtEnemy( const Vector &shootOrigin )
{
CBaseEntity *pEnemy = m_hEnemy;
if ( pEnemy )
if (m_pCine != NULL && m_hTargetEnt != NULL && (m_pCine->m_fTurnType == 1))
{
return ( (pEnemy->BodyTarget( shootOrigin ) - pEnemy->pev->origin) + m_vecEnemyLKP - shootOrigin ).Normalize();
Vector vecDest = ( m_hTargetEnt->pev->absmin + m_hTargetEnt->pev->absmax ) / 2;
return ( vecDest - shootOrigin ).Normalize();
}
else
return gpGlobals->v_forward;
else if ( m_hEnemy )
{
return ( (m_hEnemy->BodyTarget( shootOrigin ) - m_hEnemy->pev->origin) + m_vecEnemyLKP - shootOrigin ).Normalize();
}
else return gpGlobals->v_forward;
}

View File

@ -1,189 +1,187 @@
/***
*
* 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.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef MONSTERS_H
#include "skill.h"
#define MONSTERS_H
/*
===== monsters.h ========================================================
Header file for monster-related utility code
*/
// CHECKLOCALMOVE result types
#define LOCALMOVE_INVALID 0 // move is not possible
#define LOCALMOVE_INVALID_DONT_TRIANGULATE 1 // move is not possible, don't try to triangulate
#define LOCALMOVE_VALID 2 // move is possible
// Hit Group standards
#define HITGROUP_GENERIC 0
#define HITGROUP_HEAD 1
#define HITGROUP_CHEST 2
#define HITGROUP_STOMACH 3
#define HITGROUP_LEFTARM 4
#define HITGROUP_RIGHTARM 5
#define HITGROUP_LEFTLEG 6
#define HITGROUP_RIGHTLEG 7
// Monster Spawnflags
#define SF_MONSTER_WAIT_TILL_SEEN 1// spawnflag that makes monsters wait until player can see them before attacking.
#define SF_MONSTER_GAG 2 // no idle noises from this monster
#define SF_MONSTER_HITMONSTERCLIP 4
// 8
#define SF_MONSTER_PRISONER 16 // monster won't attack anyone, no one will attacke him.
// 32
// 64
#define SF_MONSTER_NO_YELLOW_BLOBS 128 //LRC- if the monster is stuck, don't give errors or show yellow blobs.
//LRC- wasn't implemented. #define SF_MONSTER_WAIT_FOR_SCRIPT 128 //spawnflag that makes monsters wait to check for attacking until the script is done or they've been attacked
#define SF_MONSTER_PREDISASTER 256 //this is a predisaster scientist or barney. Influences how they speak.
#define SF_MONSTER_FADECORPSE 512 // Fade out corpse after death
#define SF_MONSTER_NO_WPN_DROP 1024 //LRC- never drop your weapon (player can't pick it up.)
//LRC - this clashes with 'not in deathmatch'. Replaced with m_iPlayerReact.
//#define SF_MONSTER_INVERT_PLAYERREACT 2048 //LRC- if this monster would usually attack the player, don't attack unless provoked. If you would usually NOT attack the player, attack him.
#define SF_MONSTER_FALL_TO_GROUND 0x80000000
// specialty spawnflags
#define SF_MONSTER_TURRET_AUTOACTIVATE 32
#define SF_MONSTER_TURRET_STARTINACTIVE 64
#define SF_MONSTER_WAIT_UNTIL_PROVOKED 64 // don't attack the player unless provoked
// MoveToOrigin stuff
#define MOVE_START_TURN_DIST 64 // when this far away from moveGoal, start turning to face next goal
#define MOVE_STUCK_DIST 32 // if a monster can't step this far, it is stuck.
// MoveToOrigin stuff
#define MOVE_NORMAL 0// normal move in the direction monster is facing
#define MOVE_STRAFE 1// moves in direction specified, no matter which way monster is facing
// spawn flags 256 and above are already taken by the engine
extern void UTIL_MoveToOrigin( edict_t* pent, const Vector &vecGoal, float flDist, int iMoveType );
Vector VecCheckToss ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj = 1.0 );
Vector VecCheckThrow ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj = 1.0 );
extern DLL_GLOBAL Vector g_vecAttackDir;
extern DLL_GLOBAL CONSTANT float g_flMeleeRange;
extern DLL_GLOBAL CONSTANT float g_flMediumRange;
extern DLL_GLOBAL CONSTANT float g_flLongRange;
extern void EjectBrass (const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype );
extern void ExplodeModel( const Vector &vecOrigin, float speed, int model, int count );
BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget );
BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize = 0.0 );
// monster to monster relationship types
#define R_AL -2 // (ALLY) pals. Good alternative to R_NO when applicable.
#define R_FR -1// (FEAR)will run
#define R_NO 0// (NO RELATIONSHIP) disregard
#define R_DL 1// (DISLIKE) will attack
#define R_HT 2// (HATE)will attack this character instead of any visible DISLIKEd characters
#define R_NM 3// (NEMESIS) A monster Will ALWAYS attack its nemsis, no matter what
// these bits represent the monster's memory
#define MEMORY_CLEAR 0
#define bits_MEMORY_PROVOKED ( 1 << 0 )// right now only used for houndeyes.
#define bits_MEMORY_INCOVER ( 1 << 1 )// monster knows it is in a covered position.
#define bits_MEMORY_SUSPICIOUS ( 1 << 2 )// Ally is suspicious of the player, and will move to provoked more easily
#define bits_MEMORY_PATH_FINISHED ( 1 << 3 )// Finished monster path (just used by big momma for now)
#define bits_MEMORY_ON_PATH ( 1 << 4 )// Moving on a path
#define bits_MEMORY_MOVE_FAILED ( 1 << 5 )// Movement has already failed
#define bits_MEMORY_FLINCHED ( 1 << 6 )// Has already flinched
#define bits_MEMORY_KILLED ( 1 << 7 )// HACKHACK -- remember that I've already called my Killed()
#define bits_MEMORY_CUSTOM4 ( 1 << 28 ) // Monster-specific memory
#define bits_MEMORY_CUSTOM3 ( 1 << 29 ) // Monster-specific memory
#define bits_MEMORY_CUSTOM2 ( 1 << 30 ) // Monster-specific memory
#define bits_MEMORY_CUSTOM1 ( 1 << 31 ) // Monster-specific memory
// trigger conditions for scripted AI
// these MUST match the CHOICES interface in halflife.fgd for the base monster
enum
{
AITRIGGER_NONE = 0,
AITRIGGER_SEEPLAYER_ANGRY_AT_PLAYER,
AITRIGGER_TAKEDAMAGE,
AITRIGGER_HALFHEALTH,
AITRIGGER_DEATH,
AITRIGGER_SQUADMEMBERDIE,
AITRIGGER_SQUADLEADERDIE,
AITRIGGER_HEARWORLD,
AITRIGGER_HEARPLAYER,
AITRIGGER_HEARCOMBAT,
AITRIGGER_SEEPLAYER_UNCONDITIONAL,
AITRIGGER_SEEPLAYER_NOT_IN_COMBAT,
};
/*
0 : "No Trigger"
1 : "See Player"
2 : "Take Damage"
3 : "50% Health Remaining"
4 : "Death"
5 : "Squad Member Dead"
6 : "Squad Leader Dead"
7 : "Hear World"
8 : "Hear Player"
9 : "Hear Combat"
*/
//
// A gib is a chunk of a body, or a piece of wood/metal/rocks/etc.
//
class CGib : public CBaseEntity
{
public:
void Spawn( const char *szGibModel );
void EXPORT BounceGibTouch ( CBaseEntity *pOther );
void EXPORT StickyGibTouch ( CBaseEntity *pOther );
void EXPORT WaitTillLand( void );
void LimitVelocity( void );
virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; }
static void SpawnHeadGib( entvars_t *pevVictim );
static void SpawnHeadGib( entvars_t *pevVictim, const char *szGibModel );
static void SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int human );
static void SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int notfirst, const char *szGibModel ); //LRC
static void SpawnStickyGibs( entvars_t *pevVictim, Vector vecOrigin, int cGibs );
int m_bloodColor;
int m_cBloodDecals;
int m_material;
float m_lifeTime;
};
#define CUSTOM_SCHEDULES\
virtual Schedule_t *ScheduleFromName( const char *pName );\
static Schedule_t *m_scheduleList[];
#define DEFINE_CUSTOM_SCHEDULES(derivedClass)\
Schedule_t *derivedClass::m_scheduleList[] =
#define IMPLEMENT_CUSTOM_SCHEDULES(derivedClass, baseClass)\
Schedule_t *derivedClass::ScheduleFromName( const char *pName )\
{\
Schedule_t *pSchedule = ScheduleInList( pName, m_scheduleList, ARRAYSIZE(m_scheduleList) );\
if ( !pSchedule )\
return baseClass::ScheduleFromName(pName);\
return pSchedule;\
}
#endif //MONSTERS_H
/***
*
* 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.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef MONSTERS_H
#include "skill.h"
#define MONSTERS_H
/*
===== monsters.h ========================================================
Header file for monster-related utility code
*/
// CHECKLOCALMOVE result types
#define LOCALMOVE_INVALID 0 // move is not possible
#define LOCALMOVE_INVALID_DONT_TRIANGULATE 1 // move is not possible, don't try to triangulate
#define LOCALMOVE_VALID 2 // move is possible
// Hit Group standards
#define HITGROUP_GENERIC 0
#define HITGROUP_HEAD 1
#define HITGROUP_CHEST 2
#define HITGROUP_STOMACH 3
#define HITGROUP_LEFTARM 4
#define HITGROUP_RIGHTARM 5
#define HITGROUP_LEFTLEG 6
#define HITGROUP_RIGHTLEG 7
// Monster Spawnflags
#define SF_MONSTER_WAIT_TILL_SEEN 1// spawnflag that makes monsters wait until player can see them before attacking.
#define SF_MONSTER_GAG 2 // no idle noises from this monster
#define SF_MONSTER_HITMONSTERCLIP 4
// 8
#define SF_MONSTER_PRISONER 16 // monster won't attack anyone, no one will attacke him.
// 32
// 64
#define SF_MONSTER_NO_YELLOW_BLOBS 128 //LRC- if the monster is stuck, don't give errors or show yellow blobs.
//LRC- wasn't implemented. #define SF_MONSTER_WAIT_FOR_SCRIPT 128 //spawnflag that makes monsters wait to check for attacking until the script is done or they've been attacked
#define SF_MONSTER_PREDISASTER 256 //this is a predisaster scientist or barney. Influences how they speak.
#define SF_MONSTER_FADECORPSE 512 // Fade out corpse after death
#define SF_MONSTER_NO_WPN_DROP 1024 //LRC- never drop your weapon (player can't pick it up.)
//LRC - this clashes with 'not in deathmatch'. Replaced with m_iPlayerReact.
//#define SF_MONSTER_INVERT_PLAYERREACT 2048 //LRC- if this monster would usually attack the player, don't attack unless provoked. If you would usually NOT attack the player, attack him.
#define SF_MONSTER_FALL_TO_GROUND 0x80000000
// specialty spawnflags
#define SF_MONSTER_TURRET_AUTOACTIVATE 32
#define SF_MONSTER_TURRET_STARTINACTIVE 64
#define SF_MONSTER_WAIT_UNTIL_PROVOKED 64 // don't attack the player unless provoked
// MoveToOrigin stuff
#define MOVE_START_TURN_DIST 64 // when this far away from moveGoal, start turning to face next goal
#define MOVE_STUCK_DIST 32 // if a monster can't step this far, it is stuck.
// MoveToOrigin stuff
#define MOVE_NORMAL 0// normal move in the direction monster is facing
#define MOVE_STRAFE 1// moves in direction specified, no matter which way monster is facing
// spawn flags 256 and above are already taken by the engine
extern void UTIL_MoveToOrigin( edict_t* pent, const Vector &vecGoal, float flDist, int iMoveType );
Vector VecCheckToss ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj = 1.0 );
Vector VecCheckThrow ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj = 1.0 );
extern DLL_GLOBAL Vector g_vecAttackDir;
extern DLL_GLOBAL CONSTANT float g_flMeleeRange;
extern DLL_GLOBAL CONSTANT float g_flMediumRange;
extern DLL_GLOBAL CONSTANT float g_flLongRange;
extern void EjectBrass (const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype );
extern void ExplodeModel( const Vector &vecOrigin, float speed, int model, int count );
BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget );
BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize = 0.0 );
// monster to monster relationship types
#define R_AL -2 // (ALLY) pals. Good alternative to R_NO when applicable.
#define R_FR -1// (FEAR)will run
#define R_NO 0// (NO RELATIONSHIP) disregard
#define R_DL 1// (DISLIKE) will attack
#define R_HT 2// (HATE)will attack this character instead of any visible DISLIKEd characters
#define R_NM 3// (NEMESIS) A monster Will ALWAYS attack its nemsis, no matter what
// these bits represent the monster's memory
#define MEMORY_CLEAR 0
#define bits_MEMORY_PROVOKED ( 1 << 0 )// right now only used for houndeyes.
#define bits_MEMORY_INCOVER ( 1 << 1 )// monster knows it is in a covered position.
#define bits_MEMORY_SUSPICIOUS ( 1 << 2 )// Ally is suspicious of the player, and will move to provoked more easily
#define bits_MEMORY_PATH_FINISHED ( 1 << 3 )// Finished monster path (just used by big momma for now)
#define bits_MEMORY_ON_PATH ( 1 << 4 )// Moving on a path
#define bits_MEMORY_MOVE_FAILED ( 1 << 5 )// Movement has already failed
#define bits_MEMORY_FLINCHED ( 1 << 6 )// Has already flinched
#define bits_MEMORY_KILLED ( 1 << 7 )// HACKHACK -- remember that I've already called my Killed()
#define bits_MEMORY_CUSTOM4 ( 1 << 28 ) // Monster-specific memory
#define bits_MEMORY_CUSTOM3 ( 1 << 29 ) // Monster-specific memory
#define bits_MEMORY_CUSTOM2 ( 1 << 30 ) // Monster-specific memory
#define bits_MEMORY_CUSTOM1 ( 1 << 31 ) // Monster-specific memory
// trigger conditions for scripted AI
// these MUST match the CHOICES interface in halflife.fgd for the base monster
enum
{
AITRIGGER_NONE = 0,
AITRIGGER_SEEPLAYER_ANGRY_AT_PLAYER,
AITRIGGER_TAKEDAMAGE,
AITRIGGER_HALFHEALTH,
AITRIGGER_DEATH,
AITRIGGER_SQUADMEMBERDIE,
AITRIGGER_SQUADLEADERDIE,
AITRIGGER_HEARWORLD,
AITRIGGER_HEARPLAYER,
AITRIGGER_HEARCOMBAT,
AITRIGGER_SEEPLAYER_UNCONDITIONAL,
AITRIGGER_SEEPLAYER_NOT_IN_COMBAT,
};
/*
0 : "No Trigger"
1 : "See Player"
2 : "Take Damage"
3 : "50% Health Remaining"
4 : "Death"
5 : "Squad Member Dead"
6 : "Squad Leader Dead"
7 : "Hear World"
8 : "Hear Player"
9 : "Hear Combat"
*/
//
// A gib is a chunk of a body, or a piece of wood/metal/rocks/etc.
//
class CGib : public CBaseEntity
{
public:
void Spawn( const char *szGibModel );
void EXPORT BounceGibTouch ( CBaseEntity *pOther );
void EXPORT StickyGibTouch ( CBaseEntity *pOther );
void EXPORT WaitTillLand( void );
void LimitVelocity( void );
virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; }
static void SpawnHeadGib( entvars_t *pevVictim );
static void SpawnHeadGib( entvars_t *pevVictim, const char *szGibModel );
static void SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int human );
static void SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int notfirst, const char *szGibModel ); //LRC
static void SpawnStickyGibs( entvars_t *pevVictim, Vector vecOrigin, int cGibs );
int m_bloodColor;
int m_cBloodDecals;
int m_material;
float m_lifeTime;
};
#define CUSTOM_SCHEDULES\
virtual Schedule_t *ScheduleFromName( const char *pName );\
static Schedule_t *m_scheduleList[];
#define DEFINE_CUSTOM_SCHEDULES(derivedClass)\
Schedule_t *derivedClass::m_scheduleList[] =
#define IMPLEMENT_CUSTOM_SCHEDULES(derivedClass, baseClass)\
Schedule_t *derivedClass::ScheduleFromName( const char *pName )\
{\
Schedule_t *pSchedule = ScheduleInList( pName, m_scheduleList, ARRAYSIZE(m_scheduleList) );\
if ( !pSchedule )\
return baseClass::ScheduleFromName(pName);\
return pSchedule;\
}
#endif //MONSTERS_H

View File

@ -130,7 +130,13 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] =
DEFINE_FIELD( CBasePlayer, viewEntity, FIELD_STRING),
DEFINE_FIELD( CBasePlayer, viewFlags, FIELD_INTEGER),
DEFINE_FIELD( CBasePlayer, viewNeedsUpdate, FIELD_INTEGER),
DEFINE_FIELD( CBasePlayer, m_iFogStartDist, FIELD_INTEGER),
DEFINE_FIELD( CBasePlayer, m_iFogEndDist, FIELD_INTEGER ),
DEFINE_FIELD( CBasePlayer, m_iFogFinalEndDist, FIELD_INTEGER ),
DEFINE_FIELD( CBasePlayer, m_FogColor, FIELD_VECTOR ),
DEFINE_FIELD( CBasePlayer, m_FogFadeTime, FIELD_INTEGER),
DEFINE_FIELD( CBasePlayer, m_flStartTime, FIELD_TIME ),
DEFINE_FIELD( CBasePlayer, Rain_dripsPerSecond, FIELD_INTEGER ),
DEFINE_FIELD( CBasePlayer, Rain_windX, FIELD_FLOAT ),
DEFINE_FIELD( CBasePlayer, Rain_windY, FIELD_FLOAT ),
@ -262,7 +268,7 @@ void LinkUserMessages( void )
gmsgShowGameTitle = REG_USER_MSG("GameTitle", 0 );
gmsgTempEntity = REG_USER_MSG( "TempEntity", -1);
gmsgSetFog = REG_USER_MSG("SetFog", 9 ); //LRC
gmsgSetFog = REG_USER_MSG("SetFog", 7 ); //LRC
gmsgKeyedDLight = REG_USER_MSG("KeyedDLight", -1 ); //LRC
gmsgSetSky = REG_USER_MSG( "SetSky", 7 ); //LRC
gmsgHUDColor = REG_USER_MSG( "HUDColor", 4 ); //LRC
@ -3071,6 +3077,7 @@ void CBasePlayer :: Precache( void )
// Make sure any necessary user messages have been registered
LinkUserMessages();
viewNeedsUpdate = 1;
fogNeedsUpdate = 1;
m_iUpdateTime = 5; // won't update for 1/2 a second
@ -3507,6 +3514,7 @@ void CBasePlayer :: ForceClientDllUpdate( void )
m_flFlashLightTime = 1; // Force to update flashlight
Rain_needsUpdate = 1;
viewNeedsUpdate = 1;
fogNeedsUpdate = 1;
// Now force all the necessary messages
// to be sent.
@ -4153,6 +4161,38 @@ void CBasePlayer :: UpdateClientData( void )
gDisplayTitle = 0;
}
if(m_FogFadeTime != 0)
{
float flDegree = (gpGlobals->time - m_flStartTime) / m_FogFadeTime;
m_iFogEndDist -= (FOG_HARDWARE_LIMIT - m_iFogFinalEndDist) * (flDegree / m_iFogFinalEndDist);
// cap it
if (m_iFogEndDist > FOG_HARDWARE_LIMIT )
{
m_iFogEndDist = FOG_HARDWARE_LIMIT;
m_FogFadeTime = 0;
}
if (m_iFogEndDist < m_iFogFinalEndDist)
{
m_iFogEndDist = m_iFogFinalEndDist;
m_FogFadeTime = 0;
}
fogNeedsUpdate = TRUE;
}
if(fogNeedsUpdate != 0)
{
//update fog
MESSAGE_BEGIN( MSG_ONE, gmsgSetFog, NULL, pev );
WRITE_BYTE ( m_FogColor.x );
WRITE_BYTE ( m_FogColor.y );
WRITE_BYTE ( m_FogColor.z );
WRITE_SHORT ( m_iFogStartDist );
WRITE_SHORT ( m_iFogEndDist );
MESSAGE_END();
fogNeedsUpdate = 0;
}
if (pev->health != m_iClientHealth)
{
int iHealth = max( pev->health, 0 ); // make sure that no negative health values are sent

View File

@ -313,11 +313,22 @@ public:
float m_flStatusBarDisappearDelay;
char m_SbarString0[ SBAR_STRING_SIZE ];
char m_SbarString1[ SBAR_STRING_SIZE ];
// for trigger_viewset
int viewEntity; // string
int viewFlags; // 1-active, 2-draw hud
int viewNeedsUpdate; // precache sets to 1, UpdateClientData() sets to 0
float m_flNextChatTime;
int viewEntity; // string
int viewFlags; // 1-active, 2-draw hud
int viewNeedsUpdate; // precache sets to 1, UpdateClientData() sets to 0
float m_flNextChatTime;
// fog variables
int m_iFogStartDist;
int m_iFogEndDist;
int m_iFogFinalEndDist;
int m_FogFadeTime;
Vector m_FogColor;
int fogNeedsUpdate;
float m_flStartTime;
int Rain_dripsPerSecond;
float Rain_windX, Rain_windY;
float Rain_randX, Rain_randY;

View File

@ -94,26 +94,47 @@ void CCineMonster :: KeyValue( KeyValueData *pkvd )
m_fMoveTo = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_fTurnType"))
{
m_fTurnType = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_fAction"))
{
m_fAction = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_flRepeat"))
{
m_flRepeat = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
// LRC else if (FStrEq(pkvd->szKeyName, "m_flRepeat"))
// {
// m_flRepeat = atof( pkvd->szValue );
// pkvd->fHandled = TRUE;
// }
else if (FStrEq(pkvd->szKeyName, "m_flRadius"))
{
m_flRadius = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_iRepeats"))
{
m_iRepeats = atoi( pkvd->szValue );
m_iRepeatsLeft = m_iRepeats;
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_fRepeatFrame"))
{
m_fRepeatFrame = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_iFinishSchedule"))
{
m_iFinishSchedule = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_iPriority"))
{
m_iPriority = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else
{
CBaseMonster::KeyValue( pkvd );
@ -127,11 +148,12 @@ TYPEDESCRIPTION CCineMonster::m_SaveData[] =
DEFINE_FIELD( CCineMonster, m_iszPlay, FIELD_STRING ),
DEFINE_FIELD( CCineMonster, m_iszEntity, FIELD_STRING ),
DEFINE_FIELD( CCineMonster, m_iszAttack, FIELD_STRING ), //LRC
DEFINE_FIELD( CCineMonster, m_iszMoveTarget, FIELD_STRING ), //LRC
DEFINE_FIELD( CCineMonster, m_iszMoveTarget, FIELD_STRING ), //LRC
DEFINE_FIELD( CCineMonster, m_iszFireOnBegin, FIELD_STRING ),
DEFINE_FIELD( CCineMonster, m_fMoveTo, FIELD_INTEGER ),
DEFINE_FIELD( CCineMonster, m_fTurnType, FIELD_INTEGER ),
DEFINE_FIELD( CCineMonster, m_fAction, FIELD_INTEGER ),
DEFINE_FIELD( CCineMonster, m_flRepeat, FIELD_FLOAT ),
//LRC- this is unused DEFINE_FIELD( CCineMonster, m_flRepeat, FIELD_FLOAT ),
DEFINE_FIELD( CCineMonster, m_flRadius, FIELD_FLOAT ),
DEFINE_FIELD( CCineMonster, m_iDelay, FIELD_INTEGER ),
@ -142,24 +164,26 @@ TYPEDESCRIPTION CCineMonster::m_SaveData[] =
DEFINE_FIELD( CCineMonster, m_saved_effects, FIELD_INTEGER ),
DEFINE_FIELD( CCineMonster, m_iFinishSchedule, FIELD_INTEGER ),
DEFINE_FIELD( CCineMonster, m_interruptable, FIELD_BOOLEAN ),
};IMPLEMENT_SAVERESTORE( CCineMonster, CBaseMonster );
//LRC
DEFINE_FIELD( CCineMonster, m_iRepeats, FIELD_INTEGER ),
DEFINE_FIELD( CCineMonster, m_iRepeatsLeft, FIELD_INTEGER ),
DEFINE_FIELD( CCineMonster, m_fRepeatFrame, FIELD_FLOAT ),
DEFINE_FIELD( CCineMonster, m_iPriority, FIELD_INTEGER ),
};
IMPLEMENT_SAVERESTORE( CCineMonster, CBaseMonster );
LINK_ENTITY_TO_CLASS( scripted_sequence, CCineMonster );
LINK_ENTITY_TO_CLASS( scripted_action, CCineMonster );
LINK_ENTITY_TO_CLASS( aiscripted_sequence, CCineMonster );
LINK_ENTITY_TO_CLASS( aiscripted_sequence, CCineMonster ); //LRC - aiscripted sequences don't need to be seperate
//=========================================================
// FCanOverrideState - returns FALSE, scripted sequences
// cannot possess entities regardless of state.
//=========================================================
BOOL CCineMonster :: FCanOverrideState( void )
{
if ( FClassnameIs(pev, "aiscripted_sequence") || pev->spawnflags & SF_SCRIPT_OVERRIDESTATE )
return TRUE;
return FALSE;
}
void CCineMonster :: Spawn( void )
{
// pev->solid = SOLID_TRIGGER;
@ -168,18 +192,26 @@ void CCineMonster :: Spawn( void )
m_iState = STATE_OFF; //LRC
// if no targetname, start now
if ( FStringNull(pev->targetname) || !FStringNull( m_iszIdle ) )
if ( FStringNull(m_iszIdle) && FStringNull(pev->targetname) ) // if no targetname, start now
{
SetThink( CineThink );
SetThink(&CCineMonster :: CineThink );
SetNextThink( 1.0 );
}
else if ( m_iszIdle )
{
SetThink(&CCineMonster :: InitIdleThink );
SetNextThink( 1.0 );
// Wait to be used?
if ( pev->targetname )
m_startTime = gpGlobals->time + 1E6;
}
if ( pev->spawnflags & SF_SCRIPT_NOINTERRUPT )
m_interruptable = FALSE;
else m_interruptable = TRUE;
else
m_interruptable = TRUE;
//LRC - the only difference between AI and normal sequences
if ( FClassnameIs(pev, "aiscripted_sequence") || pev->spawnflags & SF_SCRIPT_OVERRIDESTATE )
{
m_iPriority |= SS_INTERRUPT_ANYSTATE;
}
}
//
@ -196,18 +228,21 @@ void CCineMonster :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP
if ( pTarget )
{
// ALERT(at_console, "Sequence \"%s\" triggered, already has a target.\n", STRING(pev->targetname));
// am I already playing the script?
if ( pTarget->m_scriptState == SCRIPT_PLAYING )
return;
m_startTime = gpGlobals->time + 0.05;
m_startTime = gpGlobals->time + 0.05; //why the delay? -- LRC
}
else
{
// if not, try finding them
// ALERT(at_console, "Sequence \"%s\" triggered, can't find target; searching\n", STRING(pev->targetname));
m_hActivator = pActivator;
SetThink( CineThink );
pev->nextthink = gpGlobals->time;
// if not, try finding them
SetThink(&CCineMonster :: CineThink );
// SetNextThink( 0 );
CineThink(); //LRC
}
}
@ -276,7 +311,7 @@ void CCineMonster :: Pain( void )
// ********** Cinematic Think **********
//
// find a viable entity
//LRC: now redefined... find a viable entity with the given name, and return it (or NULL if not found).
CBaseMonster* CCineMonster :: FindEntity( const char* sName, CBaseEntity *pActivator )
{
CBaseEntity *pEntity;
@ -290,7 +325,7 @@ CBaseMonster* CCineMonster :: FindEntity( const char* sName, CBaseEntity *pActiv
if ( FBitSet( pEntity->pev->flags, FL_MONSTER ))
{
pMonster = pEntity->MyMonsterPointer( );
if ( pMonster && pMonster->CanPlaySequence( FCanOverrideState(), SS_INTERRUPT_BY_NAME ) )
if ( pMonster && pMonster->CanPlaySequence( m_iPriority | SS_INTERRUPT_ALERT ) )
{
return pMonster;
}
@ -311,7 +346,7 @@ CBaseMonster* CCineMonster :: FindEntity( const char* sName, CBaseEntity *pActiv
if ( FBitSet( pEntity->pev->flags, FL_MONSTER ))
{
pMonster = pEntity->MyMonsterPointer( );
if ( pMonster && pMonster->CanPlaySequence( FCanOverrideState(), SS_INTERRUPT_IDLE ) )
if ( pMonster && pMonster->CanPlaySequence( m_iPriority ) )
{
return pMonster;
}
@ -327,11 +362,17 @@ void CCineMonster :: PossessEntity( void )
{
CBaseEntity *pEntity = m_hTargetEnt;
CBaseMonster *pTarget = NULL;
if ( pEntity ) pTarget = pEntity->MyMonsterPointer();
if ( pEntity )
pTarget = pEntity->MyMonsterPointer();
// ALERT( at_console, "Possess: pEntity %s, pTarget %s\n", STRING(pEntity->pev->targetname), STRING(pTarget->pev->targetname));
if ( pTarget )
{
if (pTarget->m_pCine) pTarget->m_pCine->CancelScript();
if (pTarget->m_pCine)
{
pTarget->m_pCine->CancelScript();
}
pTarget->m_pCine = this;
if (m_iszAttack)
@ -341,12 +382,20 @@ void CCineMonster :: PossessEntity( void )
if ( pTarget->m_hTargetEnt == NULL )
{ // nothing. Anything with that classname?
while ((pTarget->m_hTargetEnt = UTIL_FindEntityInSphere( pTarget->m_hTargetEnt, pev->origin, m_flRadius )) != NULL)
{
if (FClassnameIs( pTarget->m_hTargetEnt->pev, STRING(m_iszAttack))) break;
}
}
if (pTarget->m_hTargetEnt == NULL)
{ // nothing. Oh well.
ALERT(at_debug,"%s %s has a missing \"turn target\": %s\n",STRING(pev->classname),STRING(pev->targetname),STRING(m_iszAttack));
pTarget->m_hTargetEnt = this;
}
}
else
{
pTarget->m_hTargetEnt = this;
}
else pTarget->m_hTargetEnt = this;
if (m_iszMoveTarget)
{
@ -358,60 +407,59 @@ void CCineMonster :: PossessEntity( void )
pTarget->m_pGoalEnt = this;
}
}
else pTarget->m_pGoalEnt = this;
else
{
pTarget->m_pGoalEnt = this;
}
// if (IsAction())
// pTarget->PushEnemy(this,pev->origin);
m_saved_movetype = pTarget->pev->movetype;
m_saved_solid = pTarget->pev->solid;
m_saved_effects = pTarget->pev->effects;
pTarget->pev->effects |= pev->effects;
// ALERT(at_console, "script. IsAction = %d",IsAction());
m_iState = STATE_ON; // LRC: assume we'll set it to 'on', unless proven otherwise...
switch (m_fMoveTo)
{
case 0:
pTarget->m_scriptState = SCRIPT_WAIT;
break;
case 1:
pTarget->m_scriptState = SCRIPT_WALK_TO_MARK;
DelayStart( 1 );
break;
case 2:
pTarget->m_scriptState = SCRIPT_RUN_TO_MARK;
DelayStart( 1 );
break;
case 4:
UTIL_SetOrigin( pTarget, pev->origin );
pTarget->pev->ideal_yaw = pev->angles.y;
pTarget->pev->avelocity = Vector( 0, 0, 0 );
pTarget->pev->velocity = Vector( 0, 0, 0 );
pTarget->pev->effects |= EF_NOINTERP;
pTarget->pev->angles.y = pev->angles.y;
pTarget->m_scriptState = SCRIPT_WAIT;
m_startTime = gpGlobals->time + 1E6;
//pTarget->pev->flags &= ~FL_ONGROUND;
DelayStart( 1 );
m_iState = STATE_TURN_ON;
// fall through...
case 0:
case 4:
case 5:
case 6:
pTarget->m_scriptState = SCRIPT_WAIT;
break;
}
// ALERT( at_aiconsole, "\"%s\" found and used (INT: %s)\n", STRING( pTarget->pev->targetname ), FBitSet(pev->spawnflags, SF_SCRIPT_NOINTERRUPT)?"No":"Yes" );
pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT;
if (m_iszIdle)
{
StartSequence( pTarget, m_iszIdle, FALSE );
if (FStrEq( STRING(m_iszIdle), STRING(m_iszPlay)))
{
pTarget->pev->framerate = 0;
}
}
// if (m_iszIdle)
// {
// ALERT(at_console, "Possess: Play idle sequence\n");
// StartSequence( pTarget, m_iszIdle, FALSE );
// if (FStrEq( STRING(m_iszIdle), STRING(m_iszPlay)))
// {
// pTarget->pev->framerate = 0;
// }
// }
// ALERT(at_console, "Finished PossessEntity, ms %d, ims %d\n", pTarget->m_MonsterState, pTarget->m_IdealMonsterState);
}
}
void CCineMonster :: CineThink( void )
// at the beginning of the level, set up the idle animation. --LRC
void CCineMonster :: InitIdleThink( void )
{
if ((m_hTargetEnt = FindEntity(STRING(m_iszEntity),m_hActivator)) != NULL)
if ((m_hTargetEnt = FindEntity(STRING(m_iszEntity), NULL)) != NULL)
{
PossessEntity( );
m_startTime = gpGlobals->time + 1E6;
ALERT( at_aiconsole, "script \"%s\" using monster \"%s\"\n", STRING( pev->targetname ), STRING( m_iszEntity ) );
}
else
@ -422,10 +470,30 @@ void CCineMonster :: CineThink( void )
}
}
void CCineMonster :: CineThink( void )
{
// ALERT(at_console, "Sequence think, activator %s\n", STRING(m_hActivator->pev->targetname));
if ((m_hTargetEnt = FindEntity(STRING(m_iszEntity),m_hActivator)) != NULL)
{
// ALERT(at_console, "Sequence found %s \"%s\"\n", STRING(m_hTargetEnt->pev->classname), STRING(m_hTargetEnt->pev->targetname));
PossessEntity( );
ALERT( at_aiconsole, "script \"%s\" using monster \"%s\"\n", STRING( pev->targetname ), STRING( m_iszEntity ) );
}
else
{
// ALERT(at_console, "Sequence found nothing called %s\n", STRING(m_iszEntity));
CancelScript( );
ALERT( at_aiconsole, "script \"%s\" can't find monster \"%s\"\n", STRING( pev->targetname ), STRING( m_iszEntity ) );
SetNextThink( 1.0 );
}
}
// lookup a sequence name and setup the target monster to play it
BOOL CCineMonster :: StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty )
{
// ALERT( at_console, "StartSequence %s \"%s\"\n", STRING(pev->classname), STRING(pev->targetname));
if ( !iszSeq && completeOnEmpty )
{
SequenceDone( pTarget );
@ -447,7 +515,7 @@ BOOL CCineMonster :: StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL comp
else
s = "Yes";
ALERT( at_console, "%s (%s): started \"%s\":INT:%s\n", STRING( pTarget->pev->targetname ), STRING( pTarget->pev->classname ), STRING( iszSeq), s );
ALERT( at_debug, "%s (%s): started \"%s\":INT:%s\n", STRING( pTarget->pev->targetname ), STRING( pTarget->pev->classname ), STRING( iszSeq), s );
#endif
pTarget->pev->frame = 0;
@ -464,8 +532,10 @@ BOOL CCineMonster :: StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL comp
//=========================================================
void CCineMonster :: SequenceDone ( CBaseMonster *pMonster )
{
//ALERT( at_aiconsole, "Sequence %s finished\n", STRING( m_pCine->m_iszPlay ) );
m_iRepeatsLeft = m_iRepeats; //LRC - reset the repeater count
m_iState = STATE_OFF; // we've finished.
// ALERT( at_console, "Sequence %s finished\n", STRING(pev->targetname));//STRING( m_pCine->m_iszPlay ) );
if ( !( pev->spawnflags & SF_SCRIPT_REPEATABLE ) )
{
SetThink(&CCineMonster :: SUB_Remove );
@ -495,7 +565,9 @@ void CCineMonster :: SequenceDone ( CBaseMonster *pMonster )
//=========================================================
void CCineMonster :: FixScriptMonsterSchedule( CBaseMonster *pMonster )
{
if ( pMonster->m_IdealMonsterState != MONSTERSTATE_DEAD ) pMonster->m_IdealMonsterState = MONSTERSTATE_IDLE;
if ( pMonster->m_IdealMonsterState != MONSTERSTATE_DEAD )
pMonster->m_IdealMonsterState = MONSTERSTATE_IDLE;
// pMonster->ClearSchedule();
switch ( m_iFinishSchedule )
{
@ -557,6 +629,9 @@ int CCineMonster::IgnoreConditions( void )
{
if ( CanInterrupt() )
return 0;
// Big fat BUG: This is an IgnoreConditions function - we need to return the conditions
// that _shouldn't_ be able to break the script, instead of the conditions that _should_!!
return SCRIPT_BREAK_CONDITIONS;
}
@ -612,7 +687,7 @@ void CCineMonster :: CancelScript( void )
}
// find all the cinematic entities with my targetname and tell them to wait before starting
// find all the cinematic entities with my targetname and tell them whether to wait before starting
void CCineMonster :: DelayStart( int state )
{
CBaseEntity *pCine = UTIL_FindEntityByTargetname(NULL, STRING(pev->targetname));
@ -622,9 +697,14 @@ void CCineMonster :: DelayStart( int state )
if (FClassnameIs( pCine->pev, "scripted_sequence" ) || FClassnameIs( pCine->pev, "scripted_action" ))
{
CCineMonster *pTarget = GetClassPtr((CCineMonster *)(pCine->pev));
if (state) pTarget->m_iDelay++;
if (state)
{
// ALERT(at_console, "Delaying start\n");
pTarget->m_iDelay++;
}
else
{
// ALERT(at_console, "Undelaying start\n");
pTarget->m_iDelay--;
if (pTarget->m_iDelay <= 0)
{
@ -696,9 +776,11 @@ BOOL CBaseMonster :: CineCleanup( )
{
// 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;
// LRC - why mess around with this? Solidity isn't changed by sequences!
// pev->solid = m_pCine->m_saved_solid;
if (m_pCine->pev->spawnflags & SF_SCRIPT_STAYDEAD)
pev->deadflag = DEAD_DYING;
@ -805,6 +887,11 @@ BOOL CBaseMonster :: CineCleanup( )
FCheckAITrigger();
pev->deadflag = DEAD_NO;
}
// SetAnimation( m_MonsterState );
//LRC- removed, was never implemented. ClearBits(pev->spawnflags, SF_MONSTER_WAIT_FOR_SCRIPT );
return TRUE;
}

View File

@ -32,12 +32,11 @@
#define SCRIPT_BREAK_CONDITIONS (bits_COND_LIGHT_DAMAGE|bits_COND_HEAVY_DAMAGE)
enum SS_INTERRUPT
{
SS_INTERRUPT_IDLE = 0,
SS_INTERRUPT_BY_NAME,
SS_INTERRUPT_AI,
};
//LRC - rearranged into flags
#define SS_INTERRUPT_IDLE 0x0
#define SS_INTERRUPT_ALERT 0x1
#define SS_INTERRUPT_ANYSTATE 0x2
#define SS_INTERRUPT_SCRIPTS 0x4
// when a monster finishes an AI scripted sequence, we can choose
// a schedule to place them in. These defines are the aliases to
@ -80,15 +79,18 @@ public:
// (Do a precise attack if we'll be turning to face the target, but we haven't just walked to the target.)
BOOL PreciseAttack( void )
{
if (m_fMoveTo == 0) { ALERT(at_console,"preciseattack fails check 2\n"); return FALSE; }
if (m_fMoveTo != 5 && m_iszAttack == 0) { ALERT(at_console,"preciseattack fails check 3\n"); return FALSE; }
return TRUE;
// if (m_fTurnType != 1) { ALERT(at_console,"preciseattack fails check 1\n"); return FALSE; }
// if (m_fMoveTo == 0) { ALERT(at_console,"preciseattack fails check 2\n"); return FALSE; }
// if (m_fMoveTo != 5 && m_iszAttack == 0) { ALERT(at_console,"preciseattack fails check 3\n"); return FALSE; }
// ALERT(at_console,"preciseattack passes!\n");
// return TRUE;
return m_fTurnType == 1 && ( m_fMoveTo == 5 || (m_fMoveTo != 0 && !FStrEq(STRING(m_iszAttack), STRING(m_iszMoveTarget)) ));
};
void ReleaseEntity( CBaseMonster *pEntity );
void CancelScript( void );
virtual BOOL StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty );
BOOL CCineMonster :: FCanOverrideState( void );
void SequenceDone ( CBaseMonster *pMonster );
virtual void FixScriptMonsterSchedule( CBaseMonster *pMonster );
BOOL CanInterrupt( void );
@ -102,10 +104,15 @@ public:
int m_iszMoveTarget; // entity to move to
int m_iszFireOnBegin; // entity to fire when the sequence _starts_.
int m_fMoveTo;
int m_fTurnType;
int m_fAction;
int m_iFinishSchedule;
float m_flRadius; // range to search
float m_flRepeat; // repeat rate
//LRC- this does nothing!! float m_flRepeat; // repeat rate
int m_iRepeats; //LRC - number of times to repeat the animation
int m_iRepeatsLeft; //LRC
float m_fRepeatFrame; //LRC
int m_iPriority; //LRC
int m_iDelay;
float m_startTime;
@ -113,6 +120,7 @@ public:
int m_saved_movetype;
int m_saved_solid;
int m_saved_effects;
// Vector m_vecOrigOrigin;
BOOL m_interruptable;
};

View File

@ -722,7 +722,7 @@ void CAmbientGeneric :: ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCalle
InitModulationParms();
// AJH / MJB - [LR] volume field:
if (pev->noise) m_dpv.vol = CalcLocus_Ratio(this, STRING(pev->noise), 0);
if (pev->noise) m_dpv.vol = CalcLocus_Ratio(this, STRING(pev->noise));
if (m_pPlayFrom)
{

View File

@ -71,7 +71,8 @@ public:
void Killed( entvars_t *pevAttacker, int iGib );
MONSTERSTATE GetIdealState ( void ) { return MONSTERSTATE_IDLE; };
int CanPlaySequence( BOOL fDisregardState ) { return TRUE; };
// int CanPlaySequence( BOOL fDisregardState ) { return TRUE; };
int CanPlaySequence( int interruptFlags ) { return TRUE; };
int Classify( void );

View File

@ -1499,6 +1499,46 @@ void UTIL_ShowMessageAll( const char *pString )
}
}
void UTIL_SetFogAll( Vector color, int iFadeTime, int iStartDist, int iEndDist )
{
// loop through all players
if( IsMultiplayer( ))
{
for ( int i = 0; i < gpGlobals->maxClients; i++ )
UTIL_SetFog( color, iFadeTime, iStartDist, iEndDist, i+1 );
}
else UTIL_SetFog( color, iFadeTime, iStartDist, iEndDist );
}
void UTIL_SetFog( Vector color, int iFadeTime, int iStartDist, int iEndDist, int playernum )
{
CBasePlayer *pPlayer = (CBasePlayer*)UTIL_PlayerByIndex( playernum );
if ( pPlayer )
{
if( pPlayer->m_FogFadeTime != 0 ) return;//fading in progress !!!TODO: make smooth re-fading
if( IsMultiplayer( )) iFadeTime = 0; // disable fading in multiplayer
if( iFadeTime > 0 )
{
pPlayer->m_iFogEndDist = FOG_HARDWARE_LIMIT;
pPlayer->m_iFogFinalEndDist = iEndDist;
}
else if( iFadeTime < 0 )
{
pPlayer->m_iFogEndDist = iEndDist;
pPlayer->m_iFogFinalEndDist = iEndDist;
}
else pPlayer->m_iFogEndDist = iEndDist;
pPlayer->m_iFogStartDist = iStartDist;
pPlayer->m_FogColor = color;
pPlayer->m_FogFadeTime = iFadeTime;
pPlayer->m_flStartTime = gpGlobals->time;
pPlayer->fogNeedsUpdate = TRUE;
}
}
// Overloaded to add IGNORE_GLASS
void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, IGNORE_GLASS ignoreGlass, edict_t *pentIgnore, TraceResult *ptr )
{

View File

@ -27,6 +27,8 @@
#include "enginecallback.h"
#include "event_api.h"
#define FOG_HARDWARE_LIMIT 8192
//g-cont. safe precaching models & sounds
int PRECACHE_MODEL( char* s ); // classic precache
int PRECACHE_MODEL( string_t s ); // pev->model as argument
@ -331,6 +333,9 @@ extern void UTIL_ShowMessage ( const char *pString, CBaseEntity *pPlayer );
extern void UTIL_ShowMessageAll ( const char *pString );
extern void UTIL_ScreenFadeAll ( const Vector &color, float fadeTime, float holdTime, int alpha, int flags );
extern void UTIL_ScreenFade ( CBaseEntity *pEntity, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags );
extern void UTIL_SetFog ( Vector color, int iFadeTime, int iStartDist, int iEndDist, int playernum = 1 );
extern void UTIL_SetFogAll ( Vector color, int iFadeTime, int iStartDist, int iEndDist );
extern void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr);
extern void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, IGNORE_GLASS ignoreGlass, edict_t *pentIgnore, TraceResult *ptr);

View File

@ -534,9 +534,9 @@ void CWorld :: Precache( void )
ALERT ( at_debug, "**COULD NOT CREATE SOUNDENT**\n" );
}
if( pev->message != 0 )
if( pev->target != 0 )
{
SET_SKYBOX( STRING( pev->message ));
SET_SKYBOX( STRING( pev->target ));
}
else
{
@ -677,7 +677,7 @@ void CWorld :: KeyValue( KeyValueData *pkvd )
if( FStrEq( pkvd->szKeyName, "skyname" ))
{
// Sent over net now.
pev->message = ALLOC_STRING( pkvd->szValue );
pev->target = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if ( FStrEq(pkvd->szKeyName, "sounds") )

View File

@ -28,4 +28,4 @@ Xash 0.71 Beta 05.05.10
4. complete lights.shader
5. revision server physic
6. revision monster moving
7. implement env_laser
7. reborn Xash 0.4 Source Code

View File

@ -436,6 +436,12 @@ typedef struct
int drawMode;
rgba_t color;
// linear fog stuff
vec4_t fogColor;
float fogStartDist;
float fogEndDist;
bool fogEnabled;
int features;
int numVertex;
int numColor;

View File

@ -307,7 +307,18 @@ static void Tri_CheckOverflow( int numIndices, int numVertices )
void Tri_Fog( float flFogColor[3], float flStart, float flEnd, int bOn )
{
// FIXME: implement
// ignore fog calls from TriApi callbacks
// to avoid strange artefacts and other issues
if( triState.fActive ) return;
// change fog params
triState.fogColor[0] = bound( 0.0f, flFogColor[0], 1.0f );
triState.fogColor[1] = bound( 0.0f, flFogColor[1], 1.0f );
triState.fogColor[2] = bound( 0.0f, flFogColor[2], 1.0f );
triState.fogColor[3] = 1.0f;
triState.fogStartDist = min( flStart, flEnd );
triState.fogEndDist = max( flStart, flEnd );
triState.fogEnabled = bOn;
}
void Tri_CullFace( int mode )

View File

@ -812,7 +812,6 @@ void R_Set2DMode( bool enable )
}
}
/*
============
R_PolyBlend
@ -1740,8 +1739,6 @@ void R_BeginFrame( bool clearScene )
}
}
pglDrawBuffer( GL_BACK );
if( r_colorbits->modified )
{
r_colorbits->modified = false;

View File

@ -632,6 +632,24 @@ void R_DrawPortals( void )
}
}
/*
===============
R_RenderFog
===============
*/
void R_RenderFog( void )
{
if( !triState.fogEnabled ) return;
pglEnable( GL_FOG );
// pglFogf( GL_FOG_DENSITY, 0.0025 );
pglFogi( GL_FOG_MODE, GL_LINEAR );
pglFogfv( GL_FOG_COLOR, triState.fogColor );
pglFogf( GL_FOG_START, triState.fogStartDist );
pglFogf( GL_FOG_END, triState.fogEndDist );
pglHint( GL_FOG_HINT, GL_NICEST );
}
/*
================
R_DrawMeshes
@ -642,6 +660,8 @@ void R_DrawMeshes( void )
int i;
meshbuffer_t *meshbuf;
R_RenderFog();
RI.previousentity = NULL;
if( RI.meshlist->num_opaque_meshes )
{
@ -652,6 +672,9 @@ void R_DrawMeshes( void )
}
Tri_RenderCallback( false );
// don't fogging translucent surfaces
if( triState.fogEnabled ) pglDisable( GL_FOG );
if( RI.meshlist->num_translucent_meshes )
{
meshbuf = RI.meshlist->meshbuffer_translucent;
@ -662,6 +685,9 @@ void R_DrawMeshes( void )
Tri_RenderCallback( true );
R_LoadIdentity();
// clearing fog after each frame
triState.fogEnabled = false;
}
/*

View File

@ -272,6 +272,15 @@ typedef uint GLhandleARB;
#define GL_INCR 0x1E02
#define GL_DECR 0x1E03
// fog stuff
#define GL_FOG 0x0B60
#define GL_FOG_INDEX 0x0B61
#define GL_FOG_DENSITY 0x0B62
#define GL_FOG_START 0x0B63
#define GL_FOG_END 0x0B64
#define GL_FOG_MODE 0x0B65
#define GL_FOG_COLOR 0x0B66
#define GL_POLYGON_OFFSET_FACTOR 0x8038
#define GL_POLYGON_OFFSET_UNITS 0x2A00
#define GL_POLYGON_OFFSET_POINT 0x2A01

View File

@ -261,6 +261,9 @@ static dllfunc_t opengl_110funcs[] =
{"glClipPlane", (void **) &pglClipPlane},
{"glGetClipPlane", (void **) &pglGetClipPlane},
{"glShadeModel", (void **) &pglShadeModel},
{"glFogfv", (void **) &pglFogfv},
{"glFogf", (void **) &pglFogf},
{"glFogi", (void **) &pglFogi},
{NULL, NULL}
};

View File

@ -79,6 +79,30 @@ static bool r_shaderHasDlightPass;
#define Shader_Malloc( size ) Mem_Alloc( r_shaderpool, size )
#define Shader_Free( data ) Mem_Free( data )
const char *R_SkyPath( void )
{
// reinstall loadformats by magic keyword :)
if( !com.stricmp( GI->texmode, "Xash3D" ) || !com.stricmp( GI->texmode, "Xash" ))
return "env";
else if( !com.stricmp( GI->texmode, "stalker" ) || !com.stricmp( GI->texmode, "S.T.A.L.K.E.R" ))
return "textures/sky";
else if( !com.stricmp( GI->texmode, "Doom1" ) || !com.stricmp( GI->texmode, "Doom2" ))
return "gfx/env";
else if( !com.stricmp( GI->texmode, "Quake1" ))
return "gfx/env";
else if( !com.stricmp( GI->texmode, "Quake2" ))
return "env";
else if( !com.stricmp( GI->texmode, "Quake3" ))
return "env";
else if( !com.stricmp( GI->texmode, "Quake4" ) || !com.stricmp( GI->texmode, "Doom3" ))
return "env";
else if( !com.stricmp( GI->texmode, "hl1" ) || !com.stricmp( GI->texmode, "Half-Life" ))
return "gfx/env";
else if( !com.stricmp( GI->texmode, "hl2" ) || !com.stricmp( GI->texmode, "Half-Life 2" ))
return "materials/skybox";
return "png";
}
/*
=======================================================================
@ -4076,7 +4100,7 @@ ref_shader_t *R_SetupSky( const char *name )
{
if( !Shader_CheckSkybox( loadname ))
{
com.strncpy( loadname, va( "env/%s", name ), sizeof( loadname ));
com.strncpy( loadname, va( "%s/%s", R_SkyPath(), name ), sizeof( loadname ));
if( Shader_CheckSkybox( loadname ))
shader_valid = true;
else shader_valid = true;