#include maps/mp/gametypes/_battlechatter_mp; #include maps/mp/killstreaks/_dogs; #include maps/mp/killstreaks/_airsupport; #include common_scripts/utility; #include maps/mp/_utility; init() { level.tabuninitialgasshockduration = weapons_get_dvar_int( "scr_tabunInitialGasShockDuration", "7" ); level.tabunwalkingasshockduration = weapons_get_dvar_int( "scr_tabunWalkInGasShockDuration", "4" ); level.tabungasshockradius = weapons_get_dvar_int( "scr_tabun_shock_radius", "185" ); level.tabungasshockheight = weapons_get_dvar_int( "scr_tabun_shock_height", "20" ); level.tabungaspoisonradius = weapons_get_dvar_int( "scr_tabun_effect_radius", "185" ); level.tabungaspoisonheight = weapons_get_dvar_int( "scr_tabun_shock_height", "20" ); level.tabungasduration = weapons_get_dvar_int( "scr_tabunGasDuration", "8" ); level.poisonduration = weapons_get_dvar_int( "scr_poisonDuration", "8" ); level.poisondamage = weapons_get_dvar_int( "scr_poisonDamage", "13" ); level.poisondamagehardcore = weapons_get_dvar_int( "scr_poisonDamageHardcore", "5" ); level.fx_tabun_0 = "tabun_tiny_mp"; level.fx_tabun_1 = "tabun_small_mp"; level.fx_tabun_2 = "tabun_medium_mp"; level.fx_tabun_3 = "tabun_large_mp"; level.fx_tabun_single = "tabun_center_mp"; precacheitem( level.fx_tabun_0 ); precacheitem( level.fx_tabun_1 ); precacheitem( level.fx_tabun_2 ); precacheitem( level.fx_tabun_3 ); precacheitem( level.fx_tabun_single ); level.fx_tabun_radius0 = weapons_get_dvar_int( "scr_fx_tabun_radius0", 55 ); level.fx_tabun_radius1 = weapons_get_dvar_int( "scr_fx_tabun_radius1", 55 ); level.fx_tabun_radius2 = weapons_get_dvar_int( "scr_fx_tabun_radius2", 50 ); level.fx_tabun_radius3 = weapons_get_dvar_int( "scr_fx_tabun_radius3", 25 ); level.sound_tabun_start = "wpn_gas_hiss_start"; level.sound_tabun_loop = "wpn_gas_hiss_lp"; level.sound_tabun_stop = "wpn_gas_hiss_end"; level.sound_shock_tabun_start = ""; level.sound_shock_tabun_loop = ""; level.sound_shock_tabun_stop = ""; /# level thread checkdvarupdates(); #/ } checkdvarupdates() { while ( 1 ) { level.tabungaspoisonradius = weapons_get_dvar_int( "scr_tabun_effect_radius", level.tabungaspoisonradius ); level.tabungaspoisonheight = weapons_get_dvar_int( "scr_tabun_shock_height", level.tabungaspoisonheight ); level.tabungasshockradius = weapons_get_dvar_int( "scr_tabun_shock_radius", level.tabungasshockradius ); level.tabungasshockheight = weapons_get_dvar_int( "scr_tabun_shock_height", level.tabungasshockheight ); level.tabuninitialgasshockduration = weapons_get_dvar_int( "scr_tabunInitialGasShockDuration", level.tabuninitialgasshockduration ); level.tabunwalkingasshockduration = weapons_get_dvar_int( "scr_tabunWalkInGasShockDuration", level.tabunwalkingasshockduration ); level.tabungasduration = weapons_get_dvar_int( "scr_tabunGasDuration", level.tabungasduration ); level.poisonduration = weapons_get_dvar_int( "scr_poisonDuration", level.poisonduration ); level.poisondamage = weapons_get_dvar_int( "scr_poisonDamage", level.poisondamage ); level.poisondamagehardcore = weapons_get_dvar_int( "scr_poisonDamageHardcore", level.poisondamagehardcore ); level.fx_tabun_radius0 = weapons_get_dvar_int( "scr_fx_tabun_radius0", level.fx_tabun_radius0 ); level.fx_tabun_radius1 = weapons_get_dvar_int( "scr_fx_tabun_radius1", level.fx_tabun_radius1 ); level.fx_tabun_radius2 = weapons_get_dvar_int( "scr_fx_tabun_radius2", level.fx_tabun_radius2 ); level.fx_tabun_radius3 = weapons_get_dvar_int( "scr_fx_tabun_radius3", level.fx_tabun_radius3 ); wait 1; } } watchtabungrenadedetonation( owner ) { self waittill( "explode", position, surface ); if ( !isDefined( level.water_duds ) || level.water_duds == 1 ) { if ( isDefined( surface ) && surface == "water" ) { return; } } if ( weapons_get_dvar_int( "scr_enable_new_tabun", 1 ) ) { generatelocations( position, owner ); } else { singlelocation( position, owner ); } } damageeffectarea( owner, position, radius, height, killcament ) { shockeffectarea = spawn( "trigger_radius", position, 0, radius, height ); gaseffectarea = spawn( "trigger_radius", position, 0, radius, height ); /# if ( getDvarInt( "scr_draw_triggers" ) ) { level thread drawcylinder( position, radius, height, undefined, "tabun_draw_cylinder_stop" ); #/ } owner thread maps/mp/killstreaks/_dogs::flash_dogs( shockeffectarea ); owner thread maps/mp/killstreaks/_dogs::flash_dogs( gaseffectarea ); loopwaittime = 0,5; durationoftabun = level.tabungasduration; while ( durationoftabun > 0 ) { players = get_players(); i = 0; while ( i < players.size ) { if ( level.friendlyfire == 0 ) { if ( players[ i ] != owner ) { if ( !isDefined( owner ) || !isDefined( owner.team ) ) { i++; continue; } else { if ( level.teambased && players[ i ].team == owner.team ) { i++; continue; } } } else { if ( !isDefined( players[ i ].inpoisonarea ) || players[ i ].inpoisonarea == 0 ) { if ( players[ i ] istouching( gaseffectarea ) && players[ i ].sessionstate == "playing" ) { if ( !players[ i ] hasperk( "specialty_proximityprotection" ) ) { trace = bullettrace( position, players[ i ].origin + vectorScale( ( 0, 0, 0 ), 12 ), 0, players[ i ] ); if ( trace[ "fraction" ] == 1 ) { players[ i ].lastpoisonedby = owner; players[ i ] thread damageinpoisonarea( shockeffectarea, killcament, trace, position ); } } players[ i ] thread maps/mp/gametypes/_battlechatter_mp::incomingspecialgrenadetracking( "gas" ); } } } } i++; } wait loopwaittime; durationoftabun -= loopwaittime; } if ( level.tabungasduration < level.poisonduration ) { wait ( level.poisonduration - level.tabungasduration ); } shockeffectarea delete(); gaseffectarea delete(); /# if ( getDvarInt( "scr_draw_triggers" ) ) { level notify( "tabun_draw_cylinder_stop" ); #/ } } damageinpoisonarea( gaseffectarea, killcament, trace, position ) { self endon( "disconnect" ); self endon( "death" ); self thread watch_death(); self.inpoisonarea = 1; self startpoisoning(); tabunshocksound = spawn( "script_origin", ( 0, 0, 0 ) ); tabunshocksound thread deleteentonownerdeath( self ); tabunshocksound.origin = position; tabunshocksound playsound( level.sound_shock_tabun_start ); tabunshocksound playloopsound( level.sound_shock_tabun_loop ); timer = 0; while ( trace[ "fraction" ] == 1 && isDefined( gaseffectarea ) && self istouching( gaseffectarea ) && self.sessionstate == "playing" && isDefined( self.lastpoisonedby ) ) { damage = level.poisondamage; if ( level.hardcoremode ) { damage = level.poisondamagehardcore; } self dodamage( damage, gaseffectarea.origin, self.lastpoisonedby, killcament, "none", "MOD_GAS", 0, "tabun_gas_mp" ); if ( self mayapplyscreeneffect() ) { switch( timer ) { case 0: self shellshock( "tabun_gas_mp", 1 ); break; timer++; continue; case 1: self shellshock( "tabun_gas_nokick_mp", 1 ); break; timer++; continue; default: } timer++; if ( timer >= 2 ) { timer = 0; } self hide_hud(); } wait 1; trace = bullettrace( position, self.origin + vectorScale( ( 0, 0, 0 ), 12 ), 0, self ); } tabunshocksound stoploopsound( 0,5 ); wait 0,5; thread playsoundinspace( level.sound_shock_tabun_stop, position ); wait 0,5; tabunshocksound notify( "delete" ); tabunshocksound delete(); self show_hud(); self stoppoisoning(); self.inpoisonarea = 0; } } deleteentonownerdeath( owner ) { self endon( "delete" ); owner waittill( "death" ); self delete(); } watch_death() { self waittill( "death" ); self show_hud(); } hide_hud() { self setclientuivisibilityflag( "hud_visible", 0 ); } show_hud() { self setclientuivisibilityflag( "hud_visible", 1 ); } weapons_get_dvar_int( dvar, def ) { return int( weapons_get_dvar( dvar, def ) ); } weapons_get_dvar( dvar, def ) { if ( getDvar( dvar ) != "" ) { return getDvarFloat( dvar ); } else { setdvar( dvar, def ); return def; } } generatelocations( position, owner ) { onefoot = vectorScale( ( 0, 0, 0 ), 12 ); startpos = position + onefoot; /# level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 ); if ( level.tabun_debug ) { black = vectorScale( ( 0, 0, 0 ), 0,2 ); debugstar( startpos, 2000, black ); #/ } spawnalllocs( owner, startpos ); } singlelocation( position, owner ) { spawntimedfx( level.fx_tabun_single, position ); killcament = spawn( "script_model", position + vectorScale( ( 0, 0, 0 ), 60 ) ); killcament deleteaftertime( 15 ); killcament.starttime = getTime(); damageeffectarea( owner, position, level.tabungaspoisonradius, level.tabungaspoisonheight, killcament ); } hitpos( start, end, color ) { trace = bullettrace( start, end, 0, undefined ); /# level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 ); if ( level.tabun_debug ) { debugstar( trace[ "position" ], 2000, color ); } thread debug_line( start, trace[ "position" ], color, 80 ); #/ return trace[ "position" ]; } spawnalllocs( owner, startpos ) { defaultdistance = weapons_get_dvar_int( "scr_defaultDistanceTabun", 220 ); cos45 = 0,707; negcos45 = -0,707; red = ( 0,9, 0,2, 0,2 ); blue = ( 0,2, 0,2, 0,9 ); green = ( 0,2, 0,9, 0,2 ); white = vectorScale( ( 0, 0, 0 ), 0,9 ); north = startpos + ( defaultdistance, 0, 0 ); south = startpos - ( defaultdistance, 0, 0 ); east = startpos + ( 0, defaultdistance, 0 ); west = startpos - ( 0, defaultdistance, 0 ); nw = startpos + ( cos45 * defaultdistance, negcos45 * defaultdistance, 0 ); ne = startpos + ( cos45 * defaultdistance, cos45 * defaultdistance, 0 ); sw = startpos + ( negcos45 * defaultdistance, negcos45 * defaultdistance, 0 ); se = startpos + ( negcos45 * defaultdistance, cos45 * defaultdistance, 0 ); locations = []; locations[ "color" ] = []; locations[ "loc" ] = []; locations[ "tracePos" ] = []; locations[ "distSqrd" ] = []; locations[ "fxtoplay" ] = []; locations[ "radius" ] = []; locations[ "color" ][ 0 ] = red; locations[ "color" ][ 1 ] = red; locations[ "color" ][ 2 ] = blue; locations[ "color" ][ 3 ] = blue; locations[ "color" ][ 4 ] = green; locations[ "color" ][ 5 ] = green; locations[ "color" ][ 6 ] = white; locations[ "color" ][ 7 ] = white; locations[ "point" ][ 0 ] = north; locations[ "point" ][ 1 ] = ne; locations[ "point" ][ 2 ] = east; locations[ "point" ][ 3 ] = se; locations[ "point" ][ 4 ] = south; locations[ "point" ][ 5 ] = sw; locations[ "point" ][ 6 ] = west; locations[ "point" ][ 7 ] = nw; count = 0; while ( count < 8 ) { trace = hitpos( startpos, locations[ "point" ][ count ], locations[ "color" ][ count ] ); locations[ "tracePos" ][ count ] = trace; locations[ "loc" ][ count ] = ( startpos / 2 ) + ( trace / 2 ); locations[ "loc" ][ count ] -= vectorScale( ( 0, 0, 0 ), 12 ); locations[ "distSqrd" ][ count ] = distancesquared( startpos, trace ); count++; } centroid = getcentroid( locations ); killcament = spawn( "script_model", centroid + vectorScale( ( 0, 0, 0 ), 60 ) ); killcament deleteaftertime( 15 ); killcament.starttime = getTime(); center = getcenter( locations ); i = 0; while ( i < 8 ) { fxtoplay = setuptabunfx( owner, locations, i ); switch( fxtoplay ) { case 0: locations[ "fxtoplay" ][ i ] = level.fx_tabun_0; locations[ "radius" ][ i ] = level.fx_tabun_radius0; break; i++; continue; case 1: locations[ "fxtoplay" ][ i ] = level.fx_tabun_1; locations[ "radius" ][ i ] = level.fx_tabun_radius1; break; i++; continue; case 2: locations[ "fxtoplay" ][ i ] = level.fx_tabun_2; locations[ "radius" ][ i ] = level.fx_tabun_radius2; break; i++; continue; case 3: locations[ "fxtoplay" ][ i ] = level.fx_tabun_3; locations[ "radius" ][ i ] = level.fx_tabun_radius3; break; i++; continue; default: locations[ "radius" ][ i ] = 0; } i++; } singleeffect = 1; freepassused = 0; i = 0; while ( i < 8 ) { if ( locations[ "radius" ][ i ] != level.fx_tabun_radius0 ) { if ( freepassused == 0 && locations[ "radius" ][ i ] == level.fx_tabun_radius1 ) { freepassused = 1; i++; continue; } else { singleeffect = 0; } } i++; } onefoot = vectorScale( ( 0, 0, 0 ), 12 ); startpos -= onefoot; thread playtabunsound( startpos ); if ( singleeffect == 1 ) { singlelocation( startpos, owner ); } else { spawntimedfx( level.fx_tabun_3, startpos ); count = 0; while ( count < 8 ) { if ( isDefined( locations[ "fxtoplay" ][ count ] ) ) { spawntimedfx( locations[ "fxtoplay" ][ count ], locations[ "loc" ][ count ] ); thread damageeffectarea( owner, locations[ "loc" ][ count ], locations[ "radius" ][ count ], locations[ "radius" ][ count ], killcament ); } count++; } } } playtabunsound( position ) { tabunsound = spawn( "script_origin", ( 0, 0, 0 ) ); tabunsound.origin = position; tabunsound playsound( level.sound_tabun_start ); tabunsound playloopsound( level.sound_tabun_loop ); wait level.tabungasduration; thread playsoundinspace( level.sound_tabun_stop, position ); tabunsound stoploopsound( 0,5 ); wait 0,5; tabunsound delete(); } setuptabunfx( owner, locations, count ) { fxtoplay = undefined; previous = count - 1; if ( previous < 0 ) { previous += locations[ "loc" ].size; } next = count + 1; if ( next >= locations[ "loc" ].size ) { next -= locations[ "loc" ].size; } effect0dist = level.fx_tabun_radius0 * level.fx_tabun_radius0; effect1dist = level.fx_tabun_radius1 * level.fx_tabun_radius1; effect2dist = level.fx_tabun_radius2 * level.fx_tabun_radius2; effect3dist = level.fx_tabun_radius3 * level.fx_tabun_radius3; effect4dist = level.fx_tabun_radius3; fxtoplay = -1; if ( locations[ "distSqrd" ][ count ] > effect0dist && locations[ "distSqrd" ][ previous ] > effect1dist && locations[ "distSqrd" ][ next ] > effect1dist ) { fxtoplay = 0; } else { if ( locations[ "distSqrd" ][ count ] > effect1dist && locations[ "distSqrd" ][ previous ] > effect2dist && locations[ "distSqrd" ][ next ] > effect2dist ) { fxtoplay = 1; } else { if ( locations[ "distSqrd" ][ count ] > effect2dist && locations[ "distSqrd" ][ previous ] > effect3dist && locations[ "distSqrd" ][ next ] > effect3dist ) { fxtoplay = 2; } else { if ( locations[ "distSqrd" ][ count ] > effect3dist && locations[ "distSqrd" ][ previous ] > effect4dist && locations[ "distSqrd" ][ next ] > effect4dist ) { fxtoplay = 3; } } } } return fxtoplay; } getcentroid( locations ) { centroid = ( 0, 0, 0 ); i = 0; while ( i < locations[ "loc" ].size ) { centroid += locations[ "loc" ][ i ] / locations[ "loc" ].size; i++; } /# level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 ); if ( level.tabun_debug ) { purple = ( 0,9, 0,2, 0,9 ); debugstar( centroid, 2000, purple ); #/ } return centroid; } getcenter( locations ) { center = ( 0, 0, 0 ); curx = locations[ "tracePos" ][ 0 ][ 0 ]; cury = locations[ "tracePos" ][ 0 ][ 1 ]; minx = curx; maxx = curx; miny = cury; maxy = cury; i = 1; while ( i < locations[ "tracePos" ].size ) { curx = locations[ "tracePos" ][ i ][ 0 ]; cury = locations[ "tracePos" ][ i ][ 1 ]; if ( curx > maxx ) { maxx = curx; } else { if ( curx < minx ) { minx = curx; } } if ( cury > maxy ) { maxy = cury; i++; continue; } else { if ( cury < miny ) { miny = cury; } } i++; } avgx = ( maxx + minx ) / 2; avgy = ( maxy + miny ) / 2; center = ( avgx, avgy, locations[ "tracePos" ][ 0 ][ 2 ] ); /# level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 ); if ( level.tabun_debug ) { cyan = ( 0,2, 0,9, 0,9 ); debugstar( center, 2000, cyan ); #/ } return center; }