#include maps\_utility; #include common_scripts\utility; main() { leaks = getentarray( "leaking", "targetname" ); if ( !leaks.size ) return; leaks thread precacheFX(); leaks thread methodsInit(); array_thread( leaks, ::leak_setup ); } leak_setup() { switch( self.script_noteworthy ) { case "barrel_oil":{ self leak_barrel_setup(); }break; case "barrel_acid":{ self leak_barrel_setup(); }break; case "barrel_sludge":{ self leak_barrel_setup(); }break; case "barrel_water":{ self leak_barrel_setup(); }break; } self thread leak_think(); } leak_barrel_setup() { self.A = self.origin; self.up = anglestoup( self.angles ); worldup = anglestoup( ( 0, 90, 0 ) ); self.org = self.A + vector_multiply( self.up, 22 ); self.A = self.A + vector_multiply( self.up, 1.5 ); self.B = self.A + vector_multiply( self.up, 41.4 ); self.volume = ( 3.1416 * ( 14 * 14 ) * 42 );// pi * ( r squared ) * height self.curvol = self.volume; dot = vectordot( self.up, worldup ); top = self.B; if ( dot < 0 ) top = self.A; dot = abs( 1 - abs( dot ) ); self.lowZ = ( physicstrace( ( self.org ), ( self.org + ( 0, 0, -80 ) ) ) )[ 2 ]; self.highZ = top[ 2 ] + ( dot * 14 ); } leak_think() { self setcandamage( true ); self endon( "drained" ); while ( 1 ) { self waittill( "damage", damage, other, direction_vec, P, type ); if ( type == "MOD_MELEE" || type == "MOD_IMPACT" ) continue; P = self [[ level._leak_methods[ type ] ]]( P, type ); if ( !isdefined( P ) ) continue; self thread leak_drain( P ); } } leak_drain( P ) { Q = pointOnSegmentNearestToPoint( self.A, self.B, P ); vec = undefined; if ( Q == self.A ) vec = vector_multiply( self.up, -1 ); else if ( Q == self.B ) vec = self.up; else vec = vectorFromLineToPoint( self.A, self.B, P ); depth = P[ 2 ] - self.lowZ; if ( depth < .02 ) depth = 0; ratio = ( depth / ( self.highZ - self.lowZ ) ) * self.volume; if ( self.curvol > ratio ) { while ( self.curvol > ratio ) { playfx( level._effect[ "leak_interactive_leak" ][ self.script_noteworthy ], P, vec ); self.curvol -= 100; wait .1; } playfx( level._effect[ "leak_interactive_drain" ][ self.script_noteworthy ], P, vec ); } if ( ( self.curvol / self.volume ) <= .05 ) self notify( "drained" ); } methodsInit() { level._leak_methods = []; level._leak_methods[ "MOD_UNKNOWN" ] = ::leak_calc_splash; level._leak_methods[ "MOD_PISTOL_BULLET" ] = ::leak_calc_ballistic; level._leak_methods[ "MOD_RIFLE_BULLET" ] = ::leak_calc_ballistic; level._leak_methods[ "MOD_GRENADE" ] = ::leak_calc_splash; level._leak_methods[ "MOD_GRENADE_SPLASH" ] = ::leak_calc_splash; level._leak_methods[ "MOD_PROJECTILE" ] = ::leak_calc_splash; level._leak_methods[ "MOD_PROJECTILE_SPLASH" ] = ::leak_calc_splash; level._leak_methods[ "MOD_MELEE" ] = ::leak_calc_nofx; level._leak_methods[ "MOD_HEAD_SHOT" ] = ::leak_calc_nofx; level._leak_methods[ "MOD_CRUSH" ] = ::leak_calc_nofx; level._leak_methods[ "MOD_TELEFRAG" ] = ::leak_calc_nofx; level._leak_methods[ "MOD_FALLING" ] = ::leak_calc_nofx; level._leak_methods[ "MOD_SUICIDE" ] = ::leak_calc_nofx; level._leak_methods[ "MOD_TRIGGER_HURT" ] = ::leak_calc_splash; level._leak_methods[ "MOD_EXPLOSIVE" ] = ::leak_calc_splash; level._leak_methods[ "MOD_IMPACT" ] = ::leak_calc_nofx; } leak_calc_ballistic( P, type ) { return P; } leak_calc_splash( P, type ) { vec = vectornormalize( vectorFromLineToPoint( self.A, self.B, P ) ); P = pointOnSegmentNearestToPoint( self.A, self.B, P ); return( P + vector_multiply( vec, 4 ) ); //return P; } leak_calc_nofx( P, type ) { return undefined; } leak_calc_assert( P, type ) { assertMsg( "BUG to MOHAMMAD ALAVI under LEVEL DESIGN. leaking object at (" + self getorigin() + ") was impacted with unknown type: " + type + "." ); } precacheFX() { for ( i = 0; i < self.size; i++ ) { if ( self[ i ].script_noteworthy != "barrel_oil" ) continue; level._effect[ "leak_interactive_leak" ][ self[ i ].script_noteworthy ] = loadfx( "impacts/barrel_leak" ); level._effect[ "leak_interactive_drain" ][ self[ i ].script_noteworthy ] = loadfx( "impacts/barrel_drain" ); //level._sound["leak_interactive"][self[i].script_noteworthy] = "mtl_steam_pipe_hit"; //level.pipe_fx_time[self[i].script_noteworthy] = 5; break; } for ( i = 0; i < self.size; i++ ) { if ( self[ i ].script_noteworthy != "barrel_acid" ) continue; level._effect[ "leak_interactive_leak" ][ self[ i ].script_noteworthy ] = loadfx( "impacts/barrel_leak" ); level._effect[ "leak_interactive_drain" ][ self[ i ].script_noteworthy ] = loadfx( "impacts/barrel_drain" ); break; } for ( i = 0; i < self.size; i++ ) { if ( self[ i ].script_noteworthy != "barrel_water" ) continue; level._effect[ "leak_interactive_leak" ][ self[ i ].script_noteworthy ] = loadfx( "impacts/barrel_leak" ); level._effect[ "leak_interactive_drain" ][ self[ i ].script_noteworthy ] = loadfx( "impacts/barrel_drain" ); break; } for ( i = 0; i < self.size; i++ ) { if ( self[ i ].script_noteworthy != "barrel_sludge" ) continue; level._effect[ "leak_interactive_leak" ][ self[ i ].script_noteworthy ] = loadfx( "impacts/barrel_leak" ); level._effect[ "leak_interactive_drain" ][ self[ i ].script_noteworthy ] = loadfx( "impacts/barrel_drain" ); break; } }