📄 scriptslave.cpp
字号:
}
}
void ScriptSlave::OnBlock
(
Event *ev
)
{
const char *jumpto;
blocklabel = "";
jumpto = ev->GetString( 1 );
blockthread = ev->GetThread();
assert( jumpto && blockthread );
if ( blockthread && !blockthread->labelExists( jumpto ) )
{
ev->Error( "Label '%s' not found", jumpto );
return;
}
blocklabel = jumpto;
}
void ScriptSlave::NoBlock
(
Event *ev
)
{
blocklabel = "";
}
void ScriptSlave::BlockFunc
(
Event *ev
)
{
Event *e;
Entity *other;
other = ev->GetEntity( 1 );
if ( level.time >= attack_finished )
{
attack_finished = level.time + ( float )0.5;
if ( dmg != 0 )
{
other->Damage( this, this, dmg, origin, vec_zero, vec_zero, 0, 0, MOD_CRUSH, -1, -1, 1.0f );
}
}
if ( blocklabel.length() )
{
// since we use a SafePtr, the thread pointer will be NULL if the thread has ended
// so we should just clear our label and continue
if ( !blockthread )
{
blocklabel = "";
return;
}
e = new Event( EV_ScriptThread_Callback );
e->AddEntity( this );
e->AddString( blocklabel );
e->AddEntity( other );
blockthread->ProcessEvent( e );
}
}
void ScriptSlave::OnTrigger
(
Event *ev
)
{
const char *jumpto;
triggerlabel = "";
jumpto = ev->GetString( 1 );
triggerthread = ev->GetThread();
assert( jumpto && triggerthread );
if ( triggerthread && !triggerthread->labelExists( jumpto ) )
{
ev->Error( "Label '%s' not found", jumpto );
return;
}
triggerlabel = jumpto;
}
void ScriptSlave::NoTrigger
(
Event *ev
)
{
triggerlabel = "";
}
void ScriptSlave::TriggerFunc
(
Event *ev
)
{
Event *e;
Entity *other;
if ( triggerlabel.length() )
{
// since we use a SafePtr, the thread pointer will be NULL if the thread has ended
// so we should just clear our label and continue
if ( !triggerthread )
{
triggerlabel = "";
return;
}
other = ev->GetEntity( 1 );
e = new Event( EV_ScriptThread_Callback );
e->AddEntity( this );
e->AddString( triggerlabel );
e->AddEntity( other );
triggerthread->ProcessEvent( e );
}
}
void ScriptSlave::OnUse
(
Event *ev
)
{
const char *jumpto;
uselabel = "";
jumpto = ev->GetString( 1 );
usethread = ev->GetThread();
assert( jumpto && usethread );
if ( usethread && !usethread->labelExists( jumpto ) )
{
ev->Error( "Label '%s' not found", jumpto );
return;
}
uselabel = jumpto;
}
void ScriptSlave::NoUse
(
Event *ev
)
{
uselabel = "";
}
void ScriptSlave::UseFunc
(
Event *ev
)
{
Event *e;
Entity *other;
other = ev->GetEntity( 1 );
if ( key.length() )
{
if ( !other->isSubclassOf( Sentient ) || !( ( (Sentient *)other )->HasItem( key.c_str() ) ) )
{
Item *item;
ClassDef *cls;
cls = getClass( key.c_str() );
if ( !cls )
{
gi.dprintf( "No item named '%s'\n", key.c_str() );
return;
}
item = ( Item * )cls->newInstance();
item->CancelEventsOfType( EV_Item_DropToFloor );
item->CancelEventsOfType( EV_Remove );
item->ProcessPendingEvents();
gi.centerprintf ( other->edict, "jcx yv 20 string \"You need this item:\" jcx yv -20 icon %d", item->GetIconIndex() );
delete item;
return;
}
}
if ( uselabel.length() )
{
ScriptVariableList *vars;
// since we use a SafePtr, the thread pointer will be NULL if the thread has ended
// so we should just clear our label and continue
if ( !usethread )
{
uselabel = "";
return;
}
e = new Event( EV_ScriptThread_Callback );
e->AddEntity( this );
e->AddString( uselabel );
e->AddEntity( other );
vars = usethread->Vars();
vars->SetVariable( "other", other );
if ( key.length() )
{
vars->SetVariable( "key", key.c_str() );
}
usethread->ProcessEvent( e );
}
}
void ScriptSlave::OnDamage
(
Event *ev
)
{
const char *jumpto;
damagelabel = "";
jumpto = ev->GetString( 1 );
damagethread = ev->GetThread();
assert( jumpto && damagethread );
if ( damagethread && !damagethread->labelExists( jumpto ) )
{
ev->Error( "Label '%s' not found", jumpto );
return;
}
damagelabel = jumpto;
}
void ScriptSlave::NoDamage
(
Event *ev
)
{
damagelabel = "";
}
void ScriptSlave::DamageFunc
(
Event *ev
)
{
Event *e;
Entity *inflictor;
Entity *attacker;
int damage;
Vector position;
Vector direction;
ScriptVariableList *vars;
if ( damagelabel.length() )
{
// since we use a SafePtr, the thread pointer will be NULL if the thread has ended
// so we should just clear our label and continue
if ( !damagethread )
{
damagelabel = "";
return;
}
attacker = ev->GetEntity( 3 );
e = new Event( EV_ScriptThread_Callback );
e->AddEntity( this );
e->AddString( damagelabel );
e->AddEntity( attacker );
damage = ev->GetInteger( 1 );
inflictor = ev->GetEntity( 2 );
position = ev->GetVector( 4 );
direction = ev->GetVector( 5 );
vars = damagethread->Vars();
vars->SetVariable( "damage", damage );
vars->SetVariable( "inflictor", inflictor );
vars->SetVariable( "attacker", attacker );
vars->SetVariable( "position", position );
vars->SetVariable( "direction", direction );
damagethread->ProcessEvent( e );
}
}
void ScriptSlave::SetDamage
(
Event *ev
)
{
dmg = ev->GetInteger( 1 );
}
void ScriptSlave::CreatePath
(
SplinePath *path,
splinetype_t type
)
{
SplinePath *node;
if ( !splinePath )
{
splinePath = new BSpline;
}
splinePath->Clear();
splinePath->SetType( type );
node = path;
while( node != NULL )
{
splinePath->AppendControlPoint( node->worldorigin, node->angles, node->speed );
node = node->GetNext();
if ( node == path )
{
break;
}
}
}
void ScriptSlave::FollowPath
(
Event *ev
)
{
int i, argnum;
Entity * ent;
const char * token;
SplinePath *path;
qboolean clamp;
float starttime;
ent = ev->GetEntity( 1 );
argnum = 2;
starttime = -2;
clamp = true;
ignoreangles = false;
splineangles = true;
for ( i = argnum; i <= ev->NumArgs() ; i++ )
{
token = ev->GetString( i );
if (!strcmpi( token, "ignoreangles"))
{
ignoreangles = true;
}
if (!strcmpi( token, "normalangles"))
{
splineangles = false;
}
else if (!strcmpi (token, "loop"))
{
clamp = false;
}
else if ( IsNumeric( token ) )
{
starttime = atof( token );
}
else
{
ev->Error( "Unknown followpath command %s.", token );
}
}
if ( ent && ent->isSubclassOf( SplinePath ) )
{
commandswaiting = true;
path = ( SplinePath * )ent;
if ( clamp )
CreatePath( path, SPLINE_CLAMP );
else
CreatePath( path, SPLINE_LOOP );
splineTime = starttime;
CancelEventsOfType( EV_ScriptSlave_FollowingPath );
avelocity = vec_zero;
velocity = vec_zero;
}
}
void ScriptSlave::EndPath
(
Event *ev
)
{
if ( !splinePath )
return;
delete splinePath;
splinePath = NULL;
velocity = vec_zero;
avelocity = vec_zero;
}
void ScriptSlave::FollowingPath
(
Event *ev
)
{
Vector pos;
Vector orient;
float speed_multiplier;
if ( !splinePath )
return;
if ( ( splinePath->GetType() == SPLINE_CLAMP ) && ( splineTime > ( splinePath->EndPoint() - 2 ) ) )
{
delete splinePath;
splinePath = NULL;
velocity = vec_zero;
avelocity = vec_zero;
ProcessEvent( EV_ScriptSlave_MoveDone );
return;
}
speed_multiplier = splinePath->Eval( splineTime, pos, orient );
splineTime += FRAMETIME * speed_multiplier;
velocity = ( pos - origin ) * ( 1 / FRAMETIME );
if ( !ignoreangles )
{
if ( splineangles )
{
avelocity = ( orient - angles ) * ( 1 / FRAMETIME );
}
else
{
float len;
len = velocity.length();
if ( len > 0.05 )
{
Vector ang;
Vector dir;
float aroll;
aroll = avelocity[ ROLL ];
dir = velocity * ( 1 / len );
ang = dir.toAngles();
ang[ PITCH ] = -ang[ PITCH ];
avelocity = ( ang - angles ) * ( 1 / FRAMETIME );
avelocity[ ROLL ] = aroll;
}
else
avelocity = vec_zero;
}
}
PostEvent( EV_ScriptSlave_FollowingPath, FRAMETIME );
}
void ScriptSlave::Explode
(
Event *ev
)
{
float radius;
float scale;
float damage;
if ( ev->NumArgs() )
{
damage = ev->GetFloat( 1 );
if ( ev->NumArgs() > 1 )
{
scale = ev->GetFloat( 2 );
}
else
{
radius = size.length() * 0.5f;
scale = radius * 0.02f;
}
CreateExplosion( worldorigin, damage, scale, true, this, this, this );
}
else
{
radius = size.length() * 0.5f;
CreateExplosion( worldorigin, radius*3, radius * 0.02f, true, this, this, this );
}
}
void ScriptSlave::NotShootable
(
Event *ev
)
{
edict->svflags &= ~SVF_SHOOTABLE;
}
/*****************************************************************************/
/*SINED func_scriptmodel (0 .5 .8) (0 0 0) (0 0 0) NOT_SOLID
/*****************************************************************************/
CLASS_DECLARATION( ScriptSlave, ScriptModel, "func_scriptmodel" );
ResponseDef ScriptModel::Responses[] =
{
{ &EV_Gib, ( Response )ScriptModel::GibEvent },
{ NULL, NULL },
};
ScriptModel::ScriptModel()
{
const char * animname;
const char * skinname;
Vector defangles;
if ( (gi.IsModel( edict->s.modelindex )) && !mins.length() && !maxs.length())
{
gi.CalculateBounds( edict->s.modelindex, edict->s.scale, mins.vec3(), maxs.vec3() );
}
// angles
defangles = Vector( 0, G_GetFloatArg( "angle", 0 ), 0 );
if (defangles.y == -1)
{
defangles = Vector( -90, 0, 0 );
}
else if (defangles.y == -2)
{
defangles = Vector( 90, 0, 0 );
}
angles = G_GetVectorArg( "angles", defangles );
setAngles( angles );
animname = G_GetSpawnArg( "anim" );
if ( animname && strlen(animname) && gi.IsModel( edict->s.modelindex ) )
{
int animnum;
animnum = gi.Anim_NumForName( edict->s.modelindex, animname );
if (animnum >= 0)
NextAnim( animnum );
StartAnimating();
}
skinname = G_GetSpawnArg( "skin" );
if ( skinname && strlen(skinname) && gi.IsModel( edict->s.modelindex ) )
{
int skinnum;
skinnum = gi.Skin_NumForName( edict->s.modelindex, skinname );
if (skinnum >= 0)
edict->s.skinnum = skinnum;
}
}
void ScriptModel::GibEvent
(
Event *ev
)
{
int num,power;
float scale;
str gibmodel;
setSolidType( SOLID_NOT );
hideModel();
if ( !sv_gibs->value || parentmode->value )
{
PostEvent( EV_Remove, 0 );
return;
}
num = ev->GetInteger( 1 );
power = ev->GetInteger( 2 );
scale = ev->GetFloat( 3 );
gibmodel = ev->GetString( 4 );
power = -power;
if ( gibmodel == "organic" )
CreateGibs( this, power, scale, num );
else if ( gibmodel == "feather" )
CreateGibs( this, power, scale, num, "feather.def" );
PostEvent( EV_Remove, 0 );
}
/*****************************************************************************/
/*SINED func_scriptorigin (0 .5 .8) (-8 -8 -8) (8 8 8)
Used as an alternate origin for objects. Bind the object to the func_scriptorigin
in order to simulate changing that object's origin.
/*****************************************************************************/
CLASS_DECLARATION( ScriptSlave, ScriptOrigin, "func_scriptorigin" );
ResponseDef ScriptOrigin::Responses[] =
{
{ NULL, NULL }
};
ScriptOrigin::ScriptOrigin()
{
edict->svflags &= ~SVF_SHOOTABLE;
setSolidType( SOLID_NOT );
}
/*****************************************************************************/
/*SINED func_volumetric (0 .5 .8) ?
Use this to make non-solid volumes. You still need to set up the surface
properties with the "add" flag.
/*****************************************************************************/
CLASS_DECLARATION( ScriptSlave, ScriptVolumetric, "func_volumetric" );
ResponseDef ScriptVolumetric::Responses[] =
{
{ NULL, NULL }
};
ScriptVolumetric::ScriptVolumetric()
{
edict->svflags &= ~SVF_SHOOTABLE;
setSolidType( SOLID_NOT );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -