?? thrall.cpp
字號:
owner = G_GetEntity( this->owner );
if ( !owner )
{
owner = world;
}
if ( !other || ( ( other == owner ) && ( owner != world ) ) || ( other->isSubclassOf( DrunkMissile ) ) )
{
return;
}
flags &= ~FL_PRETHINK;
stopsound( CHAN_VOICE );
setSolidType( SOLID_NOT );
hideModel();
if ( HitSky() )
{
PostEvent( EV_Remove, 0 );
return;
}
damg = 40 + ( int )G_Random( 20 );
other->Damage( this, owner, damg, worldorigin, velocity, level.impact_trace.plane.normal, 200, 0, MOD_ROCKET, -1, -1, 1.0f );
SpawnBlastDamage( &level.impact_trace, damg, owner );
v = velocity;
v.normalize();
// don't do radius damage to the other, because all the damage
// was done in the impact
v = worldorigin - v * 36;
CreateExplosion( v, damg, 0.7f, true, this, owner, other );
PostEvent( EV_Remove, 0.1 );
}
EXPORT_FROM_DLL float DrunkMissile::ResolveMinimumDistance
(
Entity *potential_target,
float currmin
)
{
float currdist;
float dot;
Vector angle;
Vector delta;
Vector norm;
float sine = 0.4f;
delta = potential_target->centroid - worldorigin;
norm = delta;
norm.normalize();
// Test if the target is in front of the missile
dot = norm * orientation[ 0 ];
if ( dot < 0 )
{
return currmin;
}
// Test if we're within the rocket's viewcone (45 degree cone)
dot = norm * orientation[ 1 ];
if ( fabs( dot ) > sine )
{
return currmin;
}
dot = norm * orientation[ 2 ];
if ( fabs( dot ) > sine )
{
return currmin;
}
currdist = delta.length();
if ( currdist < currmin )
{
currmin = currdist;
target = potential_target;
}
return currmin;
}
EXPORT_FROM_DLL float DrunkMissile::AdjustAngle
(
float maxadjust,
float currangle,
float targetangle
)
{
float dangle;
float magangle;
dangle = currangle - targetangle;
if ( dangle )
{
magangle = ( float )fabs( dangle );
if ( magangle < maxadjust )
{
currangle = targetangle;
}
else
{
if ( magangle > 180.0f )
{
maxadjust = -maxadjust;
}
if ( dangle > 0 )
{
maxadjust = -maxadjust;
}
currangle += maxadjust;
}
}
while( currangle >= 360.0f )
{
currangle -= 360.0f;
}
while( currangle < 0.0f )
{
currangle += 360.0f;
}
return currangle;
}
EXPORT_FROM_DLL void DrunkMissile::HeatSeek
(
Event *ev
)
{
float mindist;
Entity *ent;
trace_t trace;
Vector delta;
Vector v;
int n;
int i;
if ( ( !target ) || ( target == world ) )
{
mindist = 8192.0f;
n = SentientList.NumObjects();
for( i = 1; i <= n; i++ )
{
ent = SentientList.ObjectAt( i );
if ( ent->entnum == owner )
{
continue;
}
if ( ( ( ent->takedamage != DAMAGE_AIM ) || ( ent->health <= 0 ) ) && !( edict->svflags & SVF_MONSTER ) )
{
continue;
}
trace = G_Trace( worldorigin, vec_zero, vec_zero, ent->centroid, this, MASK_SHOT, "DrunkMissile::HeatSeek" );
if ( ( trace.fraction != 1.0 ) && ( trace.ent != ent->edict ) )
{
continue;
}
mindist = ResolveMinimumDistance( ent, mindist );
}
}
else
{
float predict;
float dist;
float time;
float angspeed;
delta = target->centroid - worldorigin;
dist = delta.length();
time = dist * ( 1 / DRUNKMISSILE_SPEED );
predict = ( time * ( 0.5 + ( skill->value + 1 ) * 0.125 ) );
delta += target->velocity * predict;
delta.z = -delta.z;
v = delta.toAngles();
angspeed = 5.0f + skill->value;
angles.x = AdjustAngle( angspeed, angles.x, v.x );
angles.y = AdjustAngle( angspeed, angles.y, v.y );
angles.z = AdjustAngle( angspeed, angles.z, v.z );
}
if ( !target )
{
PostEvent( EV_DrunkMissile_HeatSeek, 0.2 );
}
else
{
PostEvent( EV_DrunkMissile_HeatSeek, 0.1 );
}
}
EXPORT_FROM_DLL void DrunkMissile::Prethink
(
void
)
{
trace_t trace;
Vector end;
angles += Vector( G_CRandom( 3 ), G_CRandom( 5 ), 0 );
// Check if we're about to hit the ground at a shallow angle
if ( ( velocity.z < 0 ) && ( angles.x < 15.0f ) )
{
end = worldorigin + velocity * 0.1f;
trace = G_Trace( worldorigin, vec_zero, vec_zero, end, this, MASK_SHOT, "DrunkMissile::Prethink" );
if ( trace.fraction != 1 )
{
if ( trace.plane.normal[ 2 ] > 0.6f )
{
angles.x = -3;
}
}
}
setAngles( angles );
velocity = Vector( orientation[ 0 ] ) * DRUNKMISSILE_SPEED;
}
EXPORT_FROM_DLL void DrunkMissile::Setup
(
Entity *owner,
Vector pos,
Vector dir
)
{
Event *ev;
this->owner = owner->entnum;
edict->owner = owner->edict;
flags |= FL_PRETHINK;
setMoveType( MOVETYPE_FLYMISSILE );
setSolidType( SOLID_BBOX );
edict->clipmask = MASK_PROJECTILE;
// set missile duration
ev = new Event( EV_Touch );
ev->AddEntity( world );
PostEvent( ev, 10 );
PostEvent( EV_DrunkMissile_HeatSeek, 0.1 + G_Random( 0.2f ) );
// set missile direction
angles = dir.toAngles();
angles[ PITCH ] = - angles[ PITCH ];
setAngles( angles );
velocity = Vector( orientation[ 0 ] ) * 800.0f;
target = NULL;
setModel( "trocket.def" );
setSize( "-1 -1 -1", "1 1 1" );
takedamage = DAMAGE_YES;
health = 10;
setOrigin( pos );
worldorigin.copyTo(edict->s.old_origin);
edict->s.renderfx |= RF_DLIGHT;
edict->s.effects |= EF_ROCKET;
edict->s.effects |= EF_EVERYFRAME;
edict->s.angles[ROLL] = rand() % 360;
avelocity = "0 0 90";
gravity = 0;
edict->s.color_r = 0.8;
edict->s.color_g = 0.4;
edict->s.color_b = 0;
edict->s.radius = 200;
// setup ambient thrust
ev = new Event( EV_RandomEntitySound );
//ev->AddString( "thrust" );
ev->AddString( "fire" );
ProcessEvent( ev );
}
CLASS_DECLARATION( Projectile, ThrallPulse, NULL );
ResponseDef ThrallPulse::Responses[] =
{
{ &EV_Touch, ( Response )ThrallPulse::Explode },
{ NULL, NULL }
};
EXPORT_FROM_DLL void ThrallPulse::Explode
(
Event *ev
)
{
int damg;
Vector v;
Entity *other;
Entity *owner;
ThrallPulseDebris *debris;
int i;
other = ev->GetEntity( 1 );
owner = G_GetEntity( this->owner );
if ( !owner )
owner = world;
if ( !other || ( other == owner ) || ( other->isSubclassOf( ThrallPulse ) ) )
{
return;
}
flags &= ~FL_PRETHINK;
stopsound( CHAN_VOICE );
setSolidType( SOLID_NOT );
hideModel();
if ( HitSky() )
{
PostEvent( EV_Remove, 0 );
return;
}
damg = 160 + ( int )G_Random( 50 );
other->Damage( this, owner, damg, worldorigin, velocity, level.impact_trace.plane.normal, 320, 0, MOD_ROCKET, -1, -1, 1.0f );
SpawnBlastDamage( &level.impact_trace, damg, owner );
v = velocity;
v.normalize();
// don't do radius damage to the other, because all the damage
// was done in the impact
v = worldorigin - v * 36;
CreateExplosion( v, damg, 0.7f, true, this, owner, other );
PostEvent( EV_Remove, 0.1 );
FlashPlayers( v, 1, 1, 1, 0.5, 768 );
for( i = 1; i < 4; i++ )
{
debris = new ThrallPulseDebris;
debris->Setup( owner, v, i );
}
}
EXPORT_FROM_DLL void ThrallPulse::Setup
(
Entity *owner,
Vector pos,
Vector dir
)
{
Event *ev;
this->owner = owner->entnum;
edict->owner = owner->edict;
setMoveType( MOVETYPE_FLYMISSILE );
setSolidType( SOLID_BBOX );
edict->clipmask = MASK_PROJECTILE;
// set missile duration
ev = new Event( EV_Touch );
ev->AddEntity( world );
PostEvent( ev, 10 );
// set missile direction
angles = dir.toAngles();
angles[ PITCH ] = - angles[ PITCH ];
setAngles( angles );
velocity = Vector( orientation[ 0 ] ) * 1400.0f;
setModel( "sprites/thrallpulse.spr" );
setSize( "-8 -8 -8", "8 8 8" );
takedamage = DAMAGE_NO;
setOrigin( pos );
worldorigin.copyTo(edict->s.old_origin);
showModel();
edict->s.renderfx |= RF_DLIGHT;
edict->s.angles[ROLL] = rand() % 360;
avelocity = "0 0 90";
gravity = 0;
edict->s.color_r = 0.8;
edict->s.color_g = 0;
edict->s.color_b = 0;
edict->s.radius = 200;
}
CLASS_DECLARATION( Projectile, ThrallPulseDebris, NULL );
ResponseDef ThrallPulseDebris::Responses[] =
{
{ &EV_Touch, ( Response )ThrallPulseDebris::Touch },
{ NULL, NULL }
};
EXPORT_FROM_DLL void ThrallPulseDebris::Touch
(
Event *ev
)
{
Entity *other;
Entity *owner;
if ( level.time < nexttouch )
{
return;
}
nexttouch = level.time + 1;
other = ev->GetEntity( 1 );
owner = G_GetEntity( this->owner );
if ( !owner )
{
owner = world;
}
if ( !other )
{
return;
}
other->Damage( this, owner, 10 * edict->s.scale, worldorigin, velocity,
level.impact_trace.plane.normal, velocity.length(), 0, MOD_DEBRIS, -1, -1, 1.0f );
}
EXPORT_FROM_DLL void ThrallPulseDebris::Prethink
(
void
)
{
if ( ( level.time - spawntime ) > 4 )
{
edict->s.scale *= 0.9;
setSize( Vector( -4, -4, -4 ) * edict->s.scale, Vector( 4, 4, 4 ) * edict->s.scale );
}
}
EXPORT_FROM_DLL void ThrallPulseDebris::Setup
(
Entity *owner,
Vector pos,
float size
)
{
this->owner = owner->entnum;
edict->owner = owner->edict;
nexttouch = 0;
spawntime = level.time;
flags |= FL_PRETHINK;
setModel( "thrallfire.def" );
setMoveType( MOVETYPE_BOUNCE );
setSolidType( SOLID_TRIGGER );
edict->s.effects |= EF_ROCKET;
showModel();
setOrigin( pos );
worldorigin.copyTo( edict->s.old_origin );
velocity = Vector( G_CRandom( 200 ), G_CRandom( 200 ), G_Random( 100 ) + 100 );
PostEvent( EV_Remove, 4 + 2 * size );
edict->s.scale *= size;
setSize( Vector( -4, -4, -4 ) * edict->s.scale, Vector( 4, 4, 4 ) * edict->s.scale );
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -