?? trigger.cpp
字號:
if "killtarget" is set, any objects that have a matching "target" will be
removed when the trigger is fired.
if "angle" is set, the trigger will only fire when someone is facing the
direction of the angle. Use "360" for an angle of 0.
"key" The item needed to activate this. (default nothing)
If NOT_PLAYERS is set, the trigger does not respond to players
If MONSTERS is set, the trigger will respond to monsters
If PROJECTILES is set, the trigger will respond to projectiles (rockets, grenades, etc.)
set "message" to text string
/*****************************************************************************/
CLASS_DECLARATION( Trigger, TriggerOnce, "trigger_once" );
ResponseDef TriggerOnce::Responses[] =
{
{ NULL, NULL }
};
TriggerOnce::TriggerOnce()
{
//
// gross HACK for oilrig.bsp
//
if ( message == "Foreman jumps over the edge of the rig" )
{
PostEvent( EV_Remove, 0 );
}
//
// no matter what, we only trigger once
//
count = 1;
respondto = spawnflags ^ TRIGGER_PLAYERS;
//
// if it's not supposed to be touchable, clear the trigger
//
if ( spawnflags & 1 )
setSolidType( SOLID_NOT );
}
/*****************************************************************************/
/*SINED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) x x NOT_PLAYERS MONSTERS PROJECTILES
This fixed size trigger cannot be touched, it can only be fired by other events.
It can contain killtargets, targets, delays, and messages.
If NOT_PLAYERS is set, the trigger does not respond to events triggered by players
If MONSTERS is set, the trigger will respond to events triggered by monsters
If PROJECTILES is set, the trigger will respond to events triggered by projectiles (rockets, grenades, etc.)
/*****************************************************************************/
CLASS_DECLARATION( Trigger, TriggerRelay, "trigger_relay" );
ResponseDef TriggerRelay::Responses[] =
{
{ &EV_Touch, NULL },
{ NULL, NULL }
};
TriggerRelay::TriggerRelay()
{
setSolidType( SOLID_NOT );
}
/*****************************************************************************/
/*SINED trigger_damagethreshold (0 .5 .8) ? x INVISIBLE NOT_PLAYERS MONSTERS ACCUMULATIVE
Triggers only when a threshold of damage is exceeded.
When used in conjunction with func_breakawaywall, allows
walls that may be destroyed with a rocket blast. Will also trigger
any targeted func_areaportals when not invisible.
INVISIBLE tells the trigger to not be visible.
"health" specifies how much damage must occur before trigger fires.
Default is 60.
"cnt" specifies how many times the trigger can fire before it will remove itself.
-1 sepecies infinite firing. Default is 1.
"key" The item needed to activate this. (default nothing)
If NOT_PLAYERS is set, the trigger does not respond to damage caused by players
If MONSTERS is set, the trigger will respond to damage caused by monsters
/*****************************************************************************/
#define DAMAGETHRESHOLD_ACCUMULATIVE ( 1 << 4 )
CLASS_DECLARATION( Trigger, DamageThreshold, "trigger_damagethreshold" );
// Only used internally
static Event EV_DamageThreshold_Setup( "setup" );
ResponseDef DamageThreshold::Responses[] =
{
{ &EV_Damage, ( Response )DamageThreshold::DamageEvent },
{ &EV_DamageThreshold_Setup, ( Response )DamageThreshold::Setup },
{ &EV_Touch, NULL },
{ NULL, NULL }
};
void DamageThreshold::DamageEvent
(
Event *ev
)
{
Event *event;
Entity *inflictor;
Entity *attacker;
int damage;
if ( takedamage == DAMAGE_NO )
{
return;
}
damage = ev->GetInteger( 1 );
inflictor = ev->GetEntity( 2 );
attacker = ev->GetEntity( 3 );
if ( spawnflags & DAMAGETHRESHOLD_ACCUMULATIVE )
{
health -= damage;
damage_taken += damage;
if ( health > 0 )
return;
}
else
{
if ( damage < health )
{
return;
}
damage_taken = damage;
}
event = new Event( EV_Activate );
event->AddEntity( attacker );
ProcessEvent( event );
}
void DamageThreshold::Setup
(
Event *ev
)
{
SetAreaPortals( Target(), false );
}
DamageThreshold::DamageThreshold()
{
//
// Default behavior is one use
//
count = G_GetIntArg( "cnt", 1 );
damage_taken = 0;
setSolidType( SOLID_BSP );
setMoveType( MOVETYPE_PUSH );
if ( !( spawnflags & INVISIBLE ) )
{
showModel();
PostEvent( EV_DamageThreshold_Setup, 0 );
}
health = G_GetFloatArg( "health", 60 );
max_health = health;
takedamage = DAMAGE_YES;
respondto = ( spawnflags ^ TRIGGER_PLAYERS ) & ~TRIGGER_PROJECTILES;
}
/*****************************************************************************/
/*SINED trigger_secret (.5 .5 .5) ? notouch x NOT_PLAYERS MONSTERS PROJECTILES
Secret counter trigger. Automatically sets and increments script variables \
level.total_secrets and level.found_secrets.
set "message" to text string
"key" The item needed to activate this. (default nothing)
"thread" name of thread to trigger. This can be in a different script file as well \
by using the '::' notation. (defaults to "global/universal_script.scr::secret")
If NOT_PLAYERS is set, the trigger does not respond to players
If MONSTERS is set, the trigger will respond to monsters
If PROJECTILES is set, the trigger will respond to projectiles (rockets, grenades, etc.)
/*****************************************************************************/
CLASS_DECLARATION( TriggerOnce, TriggerSecret, "trigger_secret" );
ResponseDef TriggerSecret::Responses[] =
{
{ &EV_Trigger_Effect, ( Response )TriggerSecret::FoundSecret },
{ NULL, NULL }
};
TriggerSecret::TriggerSecret()
{
if ( !LoadingSavegame )
{
level.total_secrets++;
levelVars.SetVariable( "total_secrets", level.total_secrets );
}
respondto = spawnflags ^ TRIGGER_PLAYERS;
// set the thread to trigger when secrets are found
thread = G_GetStringArg( "thread", "global/universal_script.scr::secret" );
}
void TriggerSecret::FoundSecret
(
Event *ev
)
{
//
// anything that causes the trigger to fire increments the number
// of secrets found. This way, if the level designer triggers the
// secret from the script, the player still gets credit for finding
// it. This is to prevent a secret from becoming undiscoverable.
//
level.found_secrets++;
levelVars.SetVariable( "found_secrets", level.found_secrets );
}
/*****************************************************************************/
/*SINED trigger_push (.5 .5 .5) ? x x NOT_PLAYERS NOT_MONSTERS NOT_PROJECTILES
Pushes entities as if they were caught in a heavy wind.
"speed" indicates the rate that entities are pushed (default 1000).
"angle" indicates the direction the wind is blowing (-1 is up, -2 is down)
"key" The item needed to activate this. (default nothing)
"target" if target is set, then a velocity will be calculated based on speed
If NOT_PLAYERS is set, the trigger does not push players
If NOT_MONSTERS is set, the trigger will not push monsters
If NOT_PROJECTILES is set, the trigger will not push projectiles (rockets, grenades, etc.)
/*****************************************************************************/
CLASS_DECLARATION( Trigger, TriggerPush, "trigger_push" );
ResponseDef TriggerPush::Responses[] =
{
{ &EV_Trigger_Effect, ( Response )TriggerPush::Push },
{ NULL, NULL }
};
void TriggerPush::Push
(
Event *ev
)
{
Entity *other;
other = ev->GetEntity( 1 );
if ( other )
{
const char * targ;
Entity *ent;
int num;
targ = Target ();
if ( targ[ 0 ] )
{
num = G_FindTarget( 0, Target() );
ent = G_GetEntity( num );
if ( num && ent )
{
other->velocity = G_CalculateImpulse
(
other->worldorigin,
ent->worldorigin,
speed,
other->gravity
);
}
}
else
other->velocity = pushvelocity;
}
}
TriggerPush::TriggerPush()
{
speed = G_GetFloatArg( "speed", 1000 );
pushvelocity = G_GetMovedir() * speed;
respondto = spawnflags ^ ( TRIGGER_PLAYERS | TRIGGER_MONSTERS | TRIGGER_PROJECTILES );
}
/*****************************************************************************/
/*SINED trigger_pushany (.5 .5 .5) ? x x NOT_PLAYERS NOT_MONSTERS NOT_PROJECTILES
Pushes entities as if they were caught in a heavy wind.
"speed" indicates the rate that entities are pushed (default 1000).
"angles" indicates the direction of the push
"key" The item needed to activate this. (default nothing)
"target" if target is set, then a velocity will be calculated based on speed
If NOT_PLAYERS is set, the trigger does not push players
If NOT_MONSTERS is set, the trigger will not push monsters
If NOT_PROJECTILES is set, the trigger will not push projectiles (rockets, grenades, etc.)
/*****************************************************************************/
CLASS_DECLARATION( Trigger, TriggerPushAny, "trigger_pushany" );
ResponseDef TriggerPushAny::Responses[] =
{
{ &EV_Trigger_Effect, ( Response )TriggerPushAny::Push },
{ NULL, NULL }
};
void TriggerPushAny::Push
(
Event *ev
)
{
Entity *other;
other = ev->GetEntity( 1 );
if ( other )
{
const char * targ;
Entity *ent;
int num;
targ = Target ();
if ( targ[ 0 ] )
{
num = G_FindTarget( 0, Target() );
ent = G_GetEntity( num );
if ( num && ent )
{
other->velocity = G_CalculateImpulse
(
other->worldorigin,
ent->worldorigin,
speed,
other->gravity
);
}
}
else
other->velocity = pushvelocity;
}
}
TriggerPushAny::TriggerPushAny()
{
float mat[3][3];
setAngles( G_GetVectorArg( "angles", Vector( 0, 0, 0 ) ) );
AnglesToMat( angles.vec3(), mat );
speed = G_GetFloatArg( "speed", 1000 );
pushvelocity = Vector( mat[0][0],mat[0][1], mat[0][2] ) * speed;
respondto = spawnflags ^ ( TRIGGER_PLAYERS | TRIGGER_MONSTERS | TRIGGER_PROJECTILES );
}
/*****************************************************************************/
/*SINED play_sound_triggered (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) AMBIENT-ON RELIABLE NOT_PLAYERS MONSTERS PROJECTILES AMBIENT-OFF x TOGGLE
DO NOT USE, USE TRIGGER_SPEAKER INSTEAD
play a sound when it is used
AMBIENT-ON specifies an ambient sound that starts on
RELIABLE should only be set for crucial voice-overs or sounds
AMBIENT-OFF specifies an ambient sound that starts off
if (AMBIENT-?) is not set, then the sound is sent over explicitly this creates more net traffic
"volume" how loud 0-4 (1 default full volume, ambients do not respond to volume)
"noise" sound to play
"channel" channel on which to play sound (0-7) (2 (voice) is default)
"attenuation" attenuation factor (0 becomes 1 for non-ambients, 2 for ambients)
-1 - none, send to whole level
0 - default (normal or ambient)
1 - normal fighting sounds
2 - idle monster sounds
3 - ambient sounds
"key" The item needed to activate this. (default nothing)
Normal sounds play each time the target is used.
Ambient Looped sounds have an attenuation of 2 by default, volume 1, and the use function toggles it on/off.
Multiple identical ambient looping sounds will just increase volume without any speed cost.
The attenuation factor can be over-ridden by specifying an attenuation factor.
If NOT_PLAYERS is set, the trigger does not respond to players
If MONSTERS is set, the trigger will respond to monsters
If PROJECTILES is set, the trigger will respond to projectiles (rockets, grenades, etc.)
/*****************************************************************************/
CLASS_DECLARATION( Trigger, TriggerPlaySound, "play_sound_triggered" );
Event EV_TriggerPlaySound_SetVolume( "volume" );
Event EV_TriggerPlaySound_SetAttenuation( "attenuation" );
Event EV_TriggerPlaySound_SetChannel( "channel" );
ResponseDef TriggerPlaySound::Responses[] =
{
{ &EV_Trigger_Effect, ( Response )TriggerPlaySound::ToggleSound },
{ &EV_TriggerPlaySound_SetVolume, ( Response )TriggerPlaySound::SetVolume },
{ &EV_TriggerPlaySound_SetAttenuation, ( Response )TriggerPlaySound::SetAttenuation },
{ &EV_TriggerPlaySound_SetChannel, ( Response )TriggerPlaySound::SetChannel },
{ &EV_Touch, NULL },
{ NULL, NULL }
};
void TriggerPlaySound::ToggleSound
(
Event *ev
)
{
if ( !state )
{
// noise should already be initialized
assert( Noise().length() );
if ( ambient || spawnflags & 128 )
state = 1;
if (ambient)
{
int attn;
attn = attenuation;
if (attn > 3) attn = 3;
if (attn < 0) attn = 0;
edict->s.sound = ( gi.soundindex( Noise().c_str() ) ) + (attn<<14);
}
else
{
sound( Noise().c_str(), volume, channel, attenuation, pitch, timeofs, fadetime );
}
}
else
{
state = 0;
if (ambient)
edict->s.sound = 0;
else
RandomGlobalSound( "null_sound", volume, channel | CHAN_NO_PHS_ADD, -1 );
}
}
void TriggerPlaySound::SetVolume
(
Event *ev
)
{
//FIXME
// update sound volume on client
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -