etqw-sdk/base/script/maps/generic/zappor.script

540 lines
12 KiB
Plaintext

// Zappor: Strogg thing that calls down a giant airstrike
#define ZA_DEPLOY 1
#define ZA_IDLE_DAMAGED 2
#define ZA_STARTFIRE 3
#define ZA_FIRING 4
#define ZA_FIRED 5
object mining_laser_beacon {
void SetEntities( entity o, entity l );
}
object mining_laser_objective : constructible_materials {
void preinit();
void SetupConstruction();
void OnConstructionFinished( entity p );
void DoZap( entity p );
void SetEntities( entity o, entity l );
float OnUpdateCrosshairInfo( entity p );
boolean IsPrimaryConstruction() { return true; }
entity vGetSpectateEntity();
boolean vIsObjectiveComplete();
entity deployer;
entity laser;
boolean hasZapped;
handle constructedMessage;
handle objectName;
}
void mining_laser_objective::preinit() {
forceShowProgress = true;
constructedMessage = sys.localizeString( "maps/generic/zappor/constructed" );
objectName = sys.localizeString( getKey( "object_name" ) );
}
void mining_laser_objective::SetupConstruction() {
multipleStages = false;
if ( sys.isClient() ) {
OnStateChanged();
return;
}
firstStage = sys.spawn( getKey( "def_construction" ) );
firstStage.setOrigin( getWorldOrigin() );
firstStage.setAngles( getAngles() );
firstStage.setGameTeam( getGameTeam() );
firstStage.vSetOwner( self );
SetConstructionState( CSTATE_NONE );
}
void mining_laser_objective::OnConstructionFinished( entity p ) {
OnFinishCurrentState( p );
counter = constructionCount;
if ( !sys.isClient() ) {
objManager.PushCPrintString( p.getUserName() );
objManager.CPrintEvent( constructedMessage, $null );
objManager.OnMiningLaserConstructed( self );
firstStage.remove();
DoZap( p );
}
}
void mining_laser_objective::DoZap( entity p ) {
if ( deployer == $null_entity || hasZapped ) {
return;
}
mining_laser_beacon targ = deployer.getEntityKey( "target" );
if ( targ == $null_entity ) {
sys.error( "mining_laser_objective::DoZap could not find target" );
}
targ.SetEntities( p, laser );
targ.vOnDeploy();
hasZapped = true;
}
void mining_laser_objective::SetEntities( entity o, entity l ) {
deployer = o;
laser = l;
if ( deployer != $null_entity ) {
vStartObjective();
}
}
float mining_laser_objective::OnUpdateCrosshairInfo( entity p ) {
if ( !sys.doClientSideStuff() ) {
return 1.f;
}
float allegiance = getEntityAllegiance( p );
float distance;
if ( deployer != $null_entity ) {
distance = deployer.chGetDistance();
} else {
distance = chGetDistance();
}
float range = InchesToMetres( distance );
chSetNumLines( 0 );
team_base team;
if ( p != $null_entity ) {
if ( p.isLocalPlayer() && objectiveIndex != -1 ) {
p.sendToolTip( GetToolTip( getKey( "tt_intro_info" ) ) );
}
// see if theres a valid action to perform
float code = GetActivateCode( p, distance );
if ( code != AK_NONE && p.vHasActionItem( code ) ) {
float index = chAddLine();
chSetLineMaterial( index, p.vGetActionIcon( code ) );
chSetLineType( index, CI_IMAGE );
chSetLineSize( index, 64, 64 );
chSetLineColor( index, g_colorWhite, 0.9f );
if ( p.isLocalPlayer() ) {
if ( !p.isToolTipPlaying() ) {
if ( sys.getTime() - p.getCrosshairStartTime() > 1.f ) {
if ( p.getCurrentWeapon() != p.vGetActionItem( code ) ) {
p.sendToolTip( useMeToolTip1 );
} else {
p.sendToolTip( useMeToolTip2 );
}
}
}
}
}
}
vector color = GetAllegianceColor( allegiance );
index = chAddLine();
chSetLineTextIndex( index, objectName );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
if( range <= 100 ) {
index = chAddLine();
chSetLineText( index, G_BuildRangeStr( range ) );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
}
return 1.f;
}
entity mining_laser_objective::vGetSpectateEntity() {
float time = sys.getTime();
if ( lastConstructTime >= time - 0.5f ) {
return constructor;
}
return $null_entity;
}
boolean mining_laser_objective::vIsObjectiveComplete() {
if ( multipleStages ) {
if ( state == CSTATE_FIRST_SECOND ) {
return true;
}
} else {
if ( state == CSTATE_FIRST ) {
return true;
}
}
return false;
}
object mining_laser {
void init();
void syncFields();
void vOnDeploy();
void vSetManualDeploy();
void vSetOwner( entity o );
void DoDeployAnim();
float AnimState( float state );
void OnAnimStateChanged();
void BoundsKillThread();
float OnUpdateCrosshairInfo( entity p );
boolean manualDeploy;
entity deployer;
boolean deployed;
float currentAnimState;
handle objectName;
}
void mining_laser::syncFields() {
syncBroadcast( "deployed" );
syncCallback( "deployed", "vOnDeploy" );
syncBroadcast( "currentAnimState" );
syncCallback( "currentAnimState", "OnAnimStateChanged" );
}
void mining_laser::init() {
setContents( CONTENTS_PLAYERCLIP | CONTENTS_VEHICLECLIP | CONTENTS_FLYERHIVECLIP );
objectName = sys.localizeString( getKey( "object_name" ) );
if ( !sys.isClient() ) {
thread BoundsKillThread();
if ( !manualDeploy ) {
vOnDeploy();
}
}
disableImpact();
}
void mining_laser::OnAnimStateChanged() {
AnimState( currentAnimState );
}
void mining_laser::vOnDeploy() {
deployed = true;
putToRest();
disableImpact();
if ( !sys.isClient() ) {
sys.killThread( "BoundsKillThread_" + getName() );
mining_laser_objective objectiveThing = sys.spawn( getKey( "def_objective" ) );
if ( objectiveThing == $null ) {
sys.error( "mining_laser::vOnDeploy failed to spawn objective" );
}
objectiveThing.setOrigin( getWorldOrigin() );
objectiveThing.setAngles( getAngles() );
objectiveThing.setGameTeam( getGameTeam() );
objectiveThing.SetEntities( deployer, self );
objectiveThing.vOnDeploy();
objManager.OnMiningLaserDeployed( objectiveThing );
thread DoDeployAnim();
}
}
float mining_laser::AnimState( float state ) {
currentAnimState = state;
if ( currentAnimState == ZA_DEPLOY ) {
return playAnim( ANIMCHANNEL_ALL, "deploy" );
}
if ( currentAnimState == ZA_IDLE_DAMAGED ) {
return playAnim( ANIMCHANNEL_ALL, "idle_damaged" );
}
if ( currentAnimState == ZA_STARTFIRE ) {
return playAnim( ANIMCHANNEL_ALL, "startfire" );
}
if ( currentAnimState == ZA_FIRING ) {
return playAnim( ANIMCHANNEL_ALL, "fire" );
}
if ( currentAnimState == ZA_FIRED ) {
return playAnim( ANIMCHANNEL_ALL, "idle_after_firing" );
}
return 0.f;
}
void mining_laser::DoDeployAnim() {
sys.wait( AnimState( ZA_DEPLOY ) );
AnimState( ZA_IDLE_DAMAGED );
}
void mining_laser::vSetOwner( entity o ) {
deployer = o;
}
void mining_laser::vSetManualDeploy() {
manualDeploy = true;
}
void mining_laser::BoundsKillThread() {
float damageIndex = GetDamage( getKey( "dmg_crush" ) );
while ( true ) {
BoundsDamage( self, damageIndex );
sys.waitFrame();
}
}
float mining_laser::OnUpdateCrosshairInfo( entity p ) {
if ( !sys.doClientSideStuff() ) {
return 1.0f;
}
float allegiance = getEntityAllegiance( p );
vector color = GetAllegianceColor( allegiance );
float distance;
if ( deployer != $null_entity ) {
distance = deployer.chGetDistance();
} else {
distance = chGetDistance();
}
float range = InchesToMetres( distance );
chSetNumLines( 0 );
float index;
index = chAddLine();
chSetLineTextIndex( index, objectName );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
if( range <= 100 ) {
index = chAddLine();
chSetLineText( index, G_BuildRangeStr( range ) );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
}
return 1.f;
}
object mining_laser_beacon {
void preinit();
void init();
void destroy();
void syncFields();
void Idle();
void Update();
void vOnDeploy();
void OnFiringChanged();
boolean vInhibitStats() { return true; }
entity destroyTarget;
entity destroyTarget2;
float beamEndTime;
float beamRotationSpeed;
object beamEffect;
float damageIndex;
float splashDamageIndex;
boolean hasFired;
boolean firing;
float muzzleJoint;
entity caller;
mining_laser laser;
vector target_offset;
}
void mining_laser_beacon::preinit() {
beamRotationSpeed = getFloatKey( "beam_rotation_speed" );
damageIndex = GetDamage( getKey( "dmg_damage" ) );
splashDamageIndex = GetDamage( getKey( "dmg_splash_damage" ) );
target_offset = getVectorKey( "target_offset" );
}
void mining_laser_beacon::init() {
destroyTarget = getEntityKey( "target" );
destroyTarget2 = getEntityKey( "target_secondary" );
}
void mining_laser_beacon::destroy() {
stopEffect( "fx_beam_impact" );
if ( beamEffect != $null_entity ) {
beamEffect.remove();
beamEffect = $null_entity;
}
}
void mining_laser_beacon::syncFields() {
syncBroadcast( "laser" );
syncBroadcast( "firing" );
syncCallback( "firing", "OnFiringChanged" );
}
void mining_laser_beacon::vOnDeploy() {
setState( "Idle" );
}
void mining_laser_beacon::OnFiringChanged() {
if ( firing ) {
setState( "Idle" );
}
}
void mining_laser_beacon::SetEntities( entity o, entity l ) {
caller = o;
laser = l;
}
void mining_laser_beacon::Idle() {
if ( !sys.isClient() ) {
sys.wait( laser.AnimState( ZA_STARTFIRE ) );
beamEndTime = sys.getTime() + laser.AnimState( ZA_FIRING );
firing = true;
}
muzzleJoint = laser.getJointHandle( "muzzle" );
while ( firing ) {
Update();
sys.waitFrame();
}
if ( !sys.isClient() ) {
laser.AnimState( ZA_FIRED );
} else {
stopEffect( "fx_beam_impact" );
playOriginEffect( "fx_explode", "", getWorldOrigin(), getWorldAxis( 0 ), 0 );
startSound( "snd_beam_stop", SND_WEAPON_FIRE2 );
if ( beamEffect != $null_entity ) {
beamEffect.remove();
beamEffect = $null_entity;
}
}
sys.wait( 10.f );
stopEffect( "fx_beam_impact" );
if ( beamEffect != $null_entity ) {
beamEffect.remove();
beamEffect = $null_entity;
}
}
void mining_laser_beacon::Update() {
float currentTime = sys.getTime();
vector endPos = getWorldOrigin();
vector startPos = laser.getJointPos( muzzleJoint );
float count = entitiesInTranslation( startPos, endPos, MASK_SHOT_RENDERMODEL | MASK_SHOT_BOUNDINGBOX, $null_entity );
boolean doFire;
if ( sys.isClient() ) {
doFire = firing;
} else {
doFire = currentTime < beamEndTime;
}
if ( doFire ) {
if ( beamEffect == $null_entity ) {
beamEffect = spawnClientEffect( "fx_beam" );
if ( beamEffect != $null_entity ) {
beamEffect.setEffectLooping( 1 );
beamEffect.setOrigin( startPos );
beamEffect.setEffectEndOrigin( endPos );
}
playOriginEffect( "fx_beam_impact", "", endPos + target_offset, getWorldAxis( 0 ), true );
startSound( "snd_beam_start", SND_WEAPON_FIRE2 );
}
float i;
for ( i = 0; i < count; i++ ) {
entity ent = getBoundsCacheEntity( i );
if ( ent == $null_entity ) {
continue;
}
if ( ent == destroyTarget || ent == destroyTarget2 ) {
continue;
}
ent.applyDamage( self, $null_entity, vec3_down, damageIndex, 1.0f, $null_entity );
}
} else {
firing = false;
if ( beamEffect != $null_entity ) {
beamEffect.endEffect( false );
}
if ( !hasFired ) {
stopEffect( "fx_beam_impact" );
playOriginEffect( "fx_explode", "", endPos, getWorldAxis( 0 ), 0 );
startSound( "snd_beam_stop", SND_WEAPON_FIRE2 );
if ( destroyTarget != $null_entity ) {
destroyTarget.applyDamage( self, caller, '0 0 1', damageIndex, 1.0f, $null_entity );
}
if ( destroyTarget2 != $null_entity ) {
destroyTarget2.applyDamage( self, caller, '0 0 1', damageIndex, 1.0f, $null_entity );
}
sys.applyRadiusDamage( endPos, self, caller, $null_entity, self, splashDamageIndex, 1.f, 1.f );
hasFired = true;
}
}
if ( beamEffect != $null_entity ) {
vector forward = sys.vecNormalize(endPos - startPos);
vector up = '0 0 1';
vector right = sys.crossProduct( up, forward );
up = sys.crossProduct( forward, right );
beamEffect.setWorldAxis( forward, right, up );
}
}