448 lines
10 KiB
Plaintext
448 lines
10 KiB
Plaintext
#include maps\_hud_util;
|
|
#include maps\_utility;
|
|
#include common_scripts\utility;
|
|
|
|
|
|
/************************************************************************************************************/
|
|
/* RADIATION EFFECT */
|
|
/************************************************************************************************************/
|
|
main()
|
|
{
|
|
// &&1 mR/hr
|
|
precacheString( &"SCOUTSNIPER_MRHR" );
|
|
// Avoid the radiation zones.\nListen for the clicks of the Geiger counter.
|
|
precacheString( &"SCRIPT_RADIATION_DEATH" );
|
|
precacheShellShock( "radiation_low" );
|
|
precacheShellShock( "radiation_med" );
|
|
precacheShellShock( "radiation_high" );
|
|
|
|
foreach ( key, player in level.players )
|
|
{
|
|
player.radiation = spawnstruct();
|
|
player.radiation.super_dose = false;
|
|
player.radiation.inside = false;
|
|
player ent_flag_init( "_radiation_poisoning" );
|
|
}
|
|
run_thread_on_targetname( "radiation", ::updateRadiationTriggers );
|
|
run_thread_on_targetname( "super_radiation", ::super_radiation_trigger );
|
|
|
|
array_thread( level.players, ::updateRadiationDosage );
|
|
array_thread( level.players, ::updateRadiationDosimeter );
|
|
array_thread( level.players, ::updateRadiationShock );
|
|
array_thread( level.players, ::updateRadiationBlackOut );
|
|
array_thread( level.players, ::updateRadiationSound );
|
|
array_thread( level.players, ::updateRadiationFlag );
|
|
array_thread( level.players, ::first_radiation_dialogue );
|
|
// array_thread( level.players, ::updateRadiationRatePercent );
|
|
}
|
|
|
|
updateRadiationTriggers()
|
|
{
|
|
self.members = 0;
|
|
|
|
for ( ;; )
|
|
{
|
|
self waittill( "trigger", player );
|
|
|
|
self thread updateRadiationTrigger_perplayer( player );
|
|
}
|
|
}
|
|
|
|
updateRadiationTrigger_perplayer( player )
|
|
{
|
|
if ( player.radiation.inside )
|
|
return;
|
|
|
|
player.radiation.inside = true;
|
|
player.radiation.triggers[ player.radiation.triggers.size ] = self;
|
|
|
|
while ( player isTouching( self ) )
|
|
wait 0.05;
|
|
|
|
player.radiation.inside = false;
|
|
player.radiation.triggers = array_remove( player.radiation.triggers, self );
|
|
}
|
|
|
|
super_radiation_trigger()
|
|
{
|
|
self waittill( "trigger", player );
|
|
player.radiation.super_dose = true;
|
|
}
|
|
|
|
updateRadiationDosage()
|
|
{
|
|
self.radiation.triggers = [];
|
|
self.radiation.rate = 0;
|
|
self.radiation.ratepercent = 0;
|
|
self.radiation.total = 0;
|
|
self.radiation.totalpercent = 0;
|
|
|
|
update_frequency = 1;
|
|
min_rate = 0;
|
|
max_rate = 1100000 / ( 60 * update_frequency ); // 60 REM / PH
|
|
max_total = 200000; // 200 REM
|
|
|
|
range = max_rate - min_rate;
|
|
|
|
for ( ;; )
|
|
{
|
|
rates = [];
|
|
for ( i = 0 ; i < self.radiation.triggers.size ; i++ )
|
|
{
|
|
trigger = self.radiation.triggers[ i ];
|
|
|
|
dist = ( distance( self.origin, trigger.origin ) - 15 );
|
|
rates[ i ] = max_rate - ( max_rate / trigger.radius ) * dist;
|
|
}
|
|
|
|
rate = 0;
|
|
for ( i = 0 ; i < rates.size ; i++ )
|
|
rate = rate + rates[ i ];
|
|
|
|
if ( rate < min_rate )
|
|
rate = min_rate;
|
|
|
|
if ( rate > max_rate )
|
|
rate = max_rate;
|
|
|
|
self.radiation.rate = rate;
|
|
self.radiation.ratepercent = ( rate - min_rate ) / range * 100;
|
|
|
|
if ( self.radiation.super_dose )
|
|
{
|
|
rate = max_rate;
|
|
self.radiation.ratepercent = 100;
|
|
}
|
|
|
|
if ( self.radiation.ratepercent > 25 )
|
|
{
|
|
self.radiation.total += rate;
|
|
self.radiation.totalpercent = self.radiation.total / max_total * 100;
|
|
}
|
|
|
|
else if ( self.radiation.ratepercent < 1 && self.radiation.total > 0 )
|
|
{
|
|
self.radiation.total -= 1500;
|
|
if ( self.radiation.total < 0 )
|
|
self.radiation.total = 0;
|
|
|
|
self.radiation.totalpercent = self.radiation.total / max_total * 100;
|
|
}
|
|
|
|
wait update_frequency;
|
|
}
|
|
}
|
|
|
|
updateRadiationShock()
|
|
{
|
|
update_frequency = 1;
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( self.radiation.ratepercent >= 75 )
|
|
self shellshock( "radiation_high", 5 );
|
|
else if ( self.radiation.ratepercent >= 50 )
|
|
self shellshock( "radiation_med", 5 );
|
|
else if ( self.radiation.ratepercent > 25 )
|
|
self shellshock( "radiation_low", 5 );
|
|
|
|
wait update_frequency;
|
|
}
|
|
}
|
|
|
|
updateRadiationSound()
|
|
{
|
|
self thread playRadiationSound();
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( self.radiation.ratepercent >= 75 )
|
|
self.radiation.sound = "item_geigercouner_level4";
|
|
else if ( self.radiation.ratepercent >= 50 )
|
|
self.radiation.sound = "item_geigercouner_level3";
|
|
else if ( self.radiation.ratepercent >= 25 )
|
|
self.radiation.sound = "item_geigercouner_level2";
|
|
else if ( self.radiation.ratepercent > 0 )
|
|
self.radiation.sound = "item_geigercouner_level1";
|
|
else
|
|
self.radiation.sound = "none";
|
|
|
|
wait 0.05;
|
|
}
|
|
}
|
|
|
|
updateRadiationFlag()
|
|
{
|
|
for ( ;; )
|
|
{
|
|
if ( self.radiation.ratepercent > 25 )
|
|
self ent_flag_set( "_radiation_poisoning" );
|
|
else
|
|
self ent_flag_clear( "_radiation_poisoning" );
|
|
|
|
wait 0.05;
|
|
}
|
|
}
|
|
|
|
playRadiationSound()
|
|
{
|
|
wait .05;
|
|
|
|
orgin = spawn( "script_origin", ( 0, 0, 0 ) );
|
|
orgin.origin = self.origin;
|
|
orgin.angles = self.angles;
|
|
orgin linkto( self );
|
|
|
|
temp = self.radiation.sound;
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( temp != self.radiation.sound )
|
|
{
|
|
orgin stoploopsound();
|
|
|
|
if ( isdefined( self.radiation.sound ) && self.radiation.sound != "none" )
|
|
orgin playloopsound( self.radiation.sound );
|
|
}
|
|
|
|
temp = self.radiation.sound;
|
|
|
|
wait 0.05;
|
|
}
|
|
}
|
|
|
|
updateRadiationRatePercent()
|
|
{
|
|
update_frequency = 0.05;
|
|
|
|
ratepercent = newClientHudElem( self );
|
|
ratepercent.fontScale = 1.2;
|
|
ratepercent.x = 670;
|
|
ratepercent.y = 350;
|
|
ratepercent.alignX = "right";
|
|
ratepercent.label = "";
|
|
//if you wanna put back in - delete this line
|
|
ratepercent.alpha = 0;
|
|
|
|
for ( ;; )
|
|
{
|
|
ratepercent.label = self.radiation.ratepercent;
|
|
|
|
wait update_frequency;
|
|
}
|
|
}
|
|
|
|
// set an update rate
|
|
// add variance so it is never stuck at a single value
|
|
// add background radiation
|
|
// add a radiation icon
|
|
updateRadiationDosimeter()
|
|
{
|
|
min_rate = 0.028;
|
|
max_rate = 100;
|
|
update_frequency = 1;
|
|
|
|
range = max_rate - min_rate;
|
|
last_origin = self.origin;
|
|
|
|
dosimeter = newClientHudElem( self );
|
|
dosimeter.fontScale = 1.2;
|
|
dosimeter.x = 676;
|
|
dosimeter.y = 360;
|
|
//if you wanna put back in - delete this line
|
|
dosimeter.alpha = 0;
|
|
|
|
dosimeter.alignX = "right";
|
|
// &&1 mR/hr
|
|
dosimeter.label = &"SCOUTSNIPER_MRHR";
|
|
|
|
dosimeter thread updateRadiationDosimeterColor( self );
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( self.radiation.rate <= min_rate )
|
|
{
|
|
variance = randomfloatrange( -0.001, 0.001 );
|
|
dosimeter setValue( min_rate + variance );
|
|
//println( "min_rate: ", min_rate, "variance: ", variance );
|
|
}
|
|
else if ( self.radiation.rate > max_rate )
|
|
{
|
|
dosimeter setValue( max_rate );
|
|
// TODO: Display a warning icon that the meter is beyond it's range
|
|
}
|
|
else
|
|
dosimeter setValue( self.radiation.rate );
|
|
|
|
wait update_frequency;
|
|
}
|
|
}
|
|
|
|
updateRadiationDosimeterColor( player )
|
|
{
|
|
update_frequency = 0.05;
|
|
|
|
for ( ;; )
|
|
{
|
|
colorvalue = 1;
|
|
stepamount = 0.13;
|
|
|
|
while ( player.radiation.rate >= 100 )
|
|
{
|
|
if ( colorvalue <= 0 || colorvalue >= 1 )
|
|
stepamount = stepamount * - 1;
|
|
|
|
colorvalue = colorvalue + stepamount;
|
|
|
|
if ( colorvalue <= 0 )
|
|
colorvalue = 0;
|
|
|
|
if ( colorvalue >= 1 )
|
|
colorvalue = 1;
|
|
|
|
self.color = ( 1, colorvalue, colorvalue );
|
|
//println( "colorvalue: ", colorvalue );
|
|
|
|
wait update_frequency;
|
|
}
|
|
|
|
self.color = ( 1, 1, 1 );
|
|
|
|
wait update_frequency;
|
|
}
|
|
}
|
|
|
|
// this is to indicate you are near your limit of radiation and are about to pass out
|
|
// as you near the last 33%( maybe 50% or 75% ) of your max dosage this will be visible while taking more radiation above a TBD threshold
|
|
// doing blurring at the same time as darkening
|
|
// should pulse, pulses should get longer closer to death and more frequent
|
|
// ramp up intensity and frequency
|
|
// smooth out pulsing, sin/cos?
|
|
// ramp up the low end of alpha somehow
|
|
// change pulse to pulse in/out, check some new values to determine what level to pulse out to
|
|
updateRadiationBlackOut()
|
|
{
|
|
level endon( "special_op_terminated" );
|
|
self endon( "death" );
|
|
|
|
overlay = newClientHudElem( self );
|
|
overlay.x = 0;
|
|
overlay.y = 0;
|
|
overlay setshader( "black", 640, 480 );
|
|
overlay.alignX = "left";
|
|
overlay.alignY = "top";
|
|
overlay.horzAlign = "fullscreen";
|
|
overlay.vertAlign = "fullscreen";
|
|
overlay.alpha = 0;
|
|
|
|
min_length = 1;
|
|
max_length = 4;
|
|
min_alpha = .25;
|
|
max_alpha = 1;
|
|
|
|
min_percent = 25;
|
|
max_percent = 100;
|
|
|
|
fraction = 0;
|
|
|
|
for ( ;; )
|
|
{
|
|
while ( self.radiation.totalpercent > 25 && self.radiation.ratepercent > 25 )
|
|
{
|
|
percent_range = max_percent - min_percent;
|
|
fraction = ( self.radiation.totalpercent - min_percent ) / percent_range;
|
|
|
|
if ( fraction < 0 )
|
|
fraction = 0;
|
|
else if ( fraction > 1 )
|
|
fraction = 1;
|
|
|
|
length_range = max_length - min_length;
|
|
length = min_length + ( length_range * ( 1 - fraction ) );
|
|
|
|
alpha_range = max_alpha - min_alpha;
|
|
alpha = min_alpha + ( alpha_range * fraction );
|
|
|
|
blur = 7.2 * alpha;
|
|
end_alpha = fraction * 0.5;
|
|
end_blur = 7.2 * end_alpha;
|
|
|
|
println( "fraction: ", fraction, " length: ", length, " alpha: ", alpha, " blur: ", blur );
|
|
|
|
if ( fraction == 1 )
|
|
break;
|
|
|
|
duration = length / 2;
|
|
|
|
overlay fadeinBlackOut( duration, alpha, blur, self );
|
|
overlay fadeoutBlackOut( duration, end_alpha, end_blur, self );
|
|
|
|
// wait a variable amount based on self.radiation.totalpercent, this is the space in between pulses
|
|
//wait 1;
|
|
wait( fraction * 0.5 );
|
|
}
|
|
|
|
if ( fraction == 1 )
|
|
break;
|
|
|
|
if ( overlay.alpha != 0 )
|
|
overlay fadeoutBlackOut( 1, 0, 0, self );
|
|
|
|
wait 0.05;
|
|
}
|
|
overlay fadeinBlackOut( 2, 1, 6, self );
|
|
self thread radiation_kill();
|
|
}
|
|
radiation_kill()
|
|
{
|
|
self.specialDamage = true;
|
|
self.specialDeath = true;
|
|
self.radiationDeath = true;
|
|
|
|
if ( !kill_wrapper() )
|
|
return;
|
|
waittillframeend;
|
|
|
|
assert( !isAlive( self ) );
|
|
// Avoid the radiation zones.\nListen for the clicks of the Geiger counter.
|
|
quote = &"SCRIPT_RADIATION_DEATH";
|
|
setdvar( "ui_deadquote", quote );
|
|
}
|
|
|
|
fadeinBlackOut( duration, alpha, blur, player )
|
|
{
|
|
//target_blur = 7.2 * alpha;
|
|
|
|
self fadeOverTime( duration );
|
|
self.alpha = alpha;
|
|
player setBlurForPlayer( blur, duration );
|
|
wait duration;
|
|
}
|
|
|
|
fadeoutBlackOut( duration, alpha, blur, player )
|
|
{
|
|
//target_blur = 7.2 * alpha;
|
|
|
|
self fadeOverTime( duration );
|
|
self.alpha = alpha;
|
|
player setBlurForPlayer( blur, duration );
|
|
wait duration;
|
|
}
|
|
|
|
first_radiation_dialogue()
|
|
{
|
|
self endon( "death" );
|
|
|
|
while ( 1 )
|
|
{
|
|
self ent_flag_wait( "_radiation_poisoning" );
|
|
|
|
if ( level.script == "scoutsniper" || level.script == "co_scoutsniper" )
|
|
level thread function_stack( ::radio_dialogue, "scoutsniper_mcm_youdaft" );
|
|
level notify( "radiation_warning" );
|
|
|
|
self ent_flag_waitopen( "_radiation_poisoning" );
|
|
wait( 10 );
|
|
}
|
|
}
|