// IW6 GSC SOURCE // Generated by https://github.com/xensik/gsc-tool #using_animtree("animals"); main() { var_0 = spawnstruct(); var_0.name = "fish_school_sardines"; var_0.targetname = "interactive_fish_school_sardines"; var_0.piece = spawnstruct(); var_0.piece.model = "sardines_flocking_rig"; var_0.piece.tagprefix = "tag_attach"; var_0.piece.maxturn = 5; var_0.piece.animtree = #animtree; var_0.piece.anims = []; var_0.piece.anims["idle_loop"] = %sardines_flock_loop; var_0.piece.anims["add_bend_left"] = %sardines_flock_add_left60; var_0.piece.anims["add_bend_right"] = %sardines_flock_add_right60; var_0.piece.anims["add_fast"] = %sardines_flock_add_stretch_horiz; var_0.piece.anims["add_tilt_left"] = %sardines_flock_add_tilt_left_add; var_0.piece.anims["add_tilt_right"] = %sardines_flock_add_tilt_right_add; var_0.piece.anims["add_tilt_left_child"] = %sardines_flock_add_tilt_left; var_0.piece.anims["add_tilt_right_child"] = %sardines_flock_add_tilt_right; var_0.piece.anims["add_rotate_left"] = %sardines_flock_add_rotate_left_add; var_0.piece.anims["add_rotate_left_child"] = %sardines_flock_add_rotate_left; var_0.piece.anims["add_rotate_right"] = %sardines_flock_add_rotate_right_add; var_0.piece.anims["add_rotate_right_child"] = %sardines_flock_add_rotate_right; var_0.fish = spawnstruct(); var_0.fish.model = []; var_0.fish.model[0]["bright"] = "sardines_single"; var_0.fish.model[1]["bright"] = "sardines_smallergroup"; var_0.fish.model[2]["bright"] = "sardines_smallgroup"; var_0.fish.model[2]["grey1"] = "sardines_smallgroup_grey75"; var_0.fish.model[2]["grey2"] = "sardines_smallgroup_grey50"; var_0.fish.anims = []; var_0.fish.anims["idle_loop"] = %sardines_smallgroup_loop1; var_0.ball = spawnstruct(); var_0.ball.rotationperiod = 5; var_0.ball.numtags = 16; var_0.ball.relocatespeed = 20; var_0.ball.reactdistance = 300; var_0.ball.panicdistance = 150; var_0.ball.maxdriftdist = 150; var_0.ball.driftspeed = 10; var_0.ball.ringvertoffset = 48; var_0.ball.rings = []; var_0.ball.rings[0] = spawnstruct(); var_0.ball.rings[0].numpieces = 6; var_0.ball.rings[0].radius = 64; var_0.ball.rings[0].offset = -1 * var_0.ball.ringvertoffset; var_0.ball.rings[1] = spawnstruct(); var_0.ball.rings[1].numpieces = 6; var_0.ball.rings[1].radius = 96; var_0.ball.rings[1].offset = -1 * var_0.ball.ringvertoffset; var_0.ball.rings[2] = spawnstruct(); var_0.ball.rings[2].numpieces = 6; var_0.ball.rings[2].radius = 64; var_0.ball.rings[2].offset = var_0.ball.ringvertoffset; var_0.ball.rings[3] = spawnstruct(); var_0.ball.rings[3].numpieces = 6; var_0.ball.rings[3].radius = 96; var_0.ball.rings[3].offset = var_0.ball.ringvertoffset; var_0.line = spawnstruct(); var_0.line.spacing = 3; var_0.line.anims = []; var_0.line.anim_base = %sardines_flock_spin; var_0.line.anims[0] = %sardines_flock_spinloop; var_0.line.anims[1] = %sardines_flock_spinloop_fast; var_0.line.anims[2] = %sardines_flock_spinloop_faster; var_0.line.animspeeds[0] = 8.8; var_0.line.animspeeds[1] = 17.6; var_0.line.animspeeds[2] = 44.0; var_0.line.animoffset = 0.12; var_0.line.taper = 10; var_0.line.tagmodels = []; var_0.line.tagmodels["1"] = 4; var_0.line.tagmodels["2"] = 3; var_0.line.tagmodels["3"] = 3; var_0.line.tagmodels["5"] = 3; var_0.line.tagmodels["6"] = 3; var_0.line.tagmodels["7"] = 2.5; var_0.line.tagmodels["8"] = 2.5; var_0.line.tagmodels["10"] = 2; var_0.line.tagmodels["11"] = 2; var_0.line.tagmodels["12"] = 2; var_0.line.tagmodels["14"] = 2; var_0.line.tagmodels["15"] = 2; var_0.line.tagmodels["16"] = 2; var_0.line.tagmodels["17"] = 1.5; var_0.line.tagmodels["19"] = 1.5; var_0.line.tagmodels["20"] = 1.5; var_0.line.tagmodels["21"] = 1; var_0.line.tagmodels["22"] = 1; var_0.line.tagmodels["23"] = 1; var_0.line.tagmodels["25"] = 1; var_0.line.tagmodels["26"] = 0.5; var_0.line.tagmodels["27"] = 0.5; var_0.line.tagmodels["28"] = 0.5; var_0.line.tagmodels["30"] = 0.5; var_0.line.tagmodels["31"] = 0.5; if ( !isdefined( level._interactive ) ) level._interactive = []; level._interactive["sardines"] = var_0; thread sardines( var_0 ); } sardines( var_0 ) { precachemodel( var_0.piece.model ); foreach ( var_2 in var_0.fish.model ) { foreach ( var_4 in var_2 ) precachemodel( var_4 ); } precachestring( &"PLATFORM_HOLD_TO_USE" ); level waittill( "load_finished" ); if ( !isdefined( level._interactive[var_0.name + "_setup"] ) ) { level._interactive[var_0.name + "_setup"] = 1; var_0.line.animlengths = []; for ( var_7 = 0; var_7 < var_0.line.animspeeds.size; var_7++ ) var_0.line.animlengths[var_7] = getanimlength( var_0.line.anims[var_7] ); var_8 = getentarray( var_0.targetname, "targetname" ); foreach ( var_10 in var_8 ) { if ( var_10.model == "sardines_ball_radiant" ) { var_10 thread sardines_ball( var_0 ); continue; } var_10 thread sardines_line( var_0 ); } } } sardines_line( var_0 ) { self endon( "death" ); self hideallparts(); var_1 = []; if ( isdefined( self.target ) ) var_1 = getvehiclenodearray( self.target, "targetname" ); if ( var_1.size >= 1 ) var_2 = common_scripts\utility::getclosest( self.origin, var_1 ); else { var_1 = getvehiclenodearray( "fish_path", "script_noteworthy" ); var_2 = undefined; foreach ( var_4 in var_1 ) { if ( distance( var_4.origin, self.origin ) < 1 ) { var_2 = var_4; break; } } } var_6 = common_scripts\_csplines::cspline_findpathnodes( var_2 ); self.path = common_scripts\_csplines::cspline_makepath( var_6, 1 ); var_7 = common_scripts\_csplines::cspline_length( self.path ); var_8 = common_scripts\_csplines::cspline_time( self.path ); var_9 = int( var_8 / var_0.line.spacing + 0.5 ); self.spacing = var_8 / var_9; if ( isdefined( self.interactive_number ) ) self.numpieces = int( min( var_9, self.interactive_number ) ); else self.numpieces = var_9; sardines_linemonitortriggers( var_0 ); } sardines_linemonitortriggers( var_0 ) { var_1 = undefined; if ( isdefined( self.target ) ) var_1 = getentarray( self.target, "targetname" ); var_2 = 0; if ( isdefined( var_1 ) && var_1.size > 0 ) { var_3 = []; foreach ( var_5 in var_1 ) { if ( !isdefined( var_5.script_triggername ) ) var_5.script_triggername = "start"; var_5 thread maps\interactive_models\_interactive_utility::waittill_notify( "trigger", self, var_5.script_triggername, undefined, 1 ); } } self.startstopstate = "stopped"; for (;;) { var_2 = 0; var_7 = common_scripts\utility::waittill_any_return( "start", "start_instant", "stop", "stop_instant" ); if ( self.startstopstate == "stopped" && ( var_7 == "start" || var_7 == "start_instant" ) ) { self.startstopstate = var_7; thread sardines_linethinkloop( var_0, self.interactive_number ); continue; } self.startstopstate = var_7; } } sardines_linethinkloop( var_0, var_1 ) { var_2 = var_1; self.numberoffishinexistence = 0; var_3 = common_scripts\_csplines::cspline_time( self.path ); var_4 = common_scripts\_csplines::cspline_getpointattime( self.path, 0 ); var_5 = vectortoangles( var_4["vel"] ); var_4 = var_4["pos"]; sardines_linespawnpieces( var_0 ); if ( self.startstopstate == "start_instant" ) { if ( isdefined( var_2 ) ) var_6 = self.spacing * var_1; else var_6 = self.spacing * self.numpieces; self.startstopstate = "started"; foreach ( var_8 in self.pieces ) { if ( !isdefined( var_2 ) || var_2 > 0 ) { var_8 showallparts(); self.numberoffishinexistence++; var_8.visible = 1; var_8 sardines_lineattachmodelsandtaperends( var_0, self.numberoffishinexistence, var_2 ); var_6 = var_6 - self.spacing; var_8.distance = var_6; if ( isdefined( var_2 ) ) var_2--; } } } else { } self.startstopstate = "started"; while ( !isdefined( var_2 ) || var_2 > 0 || self.numberoffishinexistence > 0 ) { if ( self.startstopstate == "stop" && ( !isdefined( var_2 ) || var_2 > var_0.line.taper ) ) var_2 = var_0.line.taper; else if ( self.startstopstate == "stop_instant" ) break; for ( var_10 = self.pieces.size - 1; var_10 >= 0; var_10-- ) { var_8 = self.pieces[var_10]; if ( var_8.distance == 0 ) { if ( !isdefined( var_2 ) || var_2 > 0 ) { var_8 showallparts(); self.numberoffishinexistence++; var_8.visible = 1; var_8 sardines_lineattachmodelsandtaperends( var_0, self.numberoffishinexistence, var_2 ); } if ( isdefined( var_2 ) ) var_2--; } var_8.distance = var_8.distance + 1; var_11 = undefined; if ( var_8.distance > var_3 ) { var_8.distance = 0; var_8.animoffset = self.pieces[maps\interactive_models\_interactive_utility::wrap( var_10 + 1, self.pieces.size )].animoffset - var_0.line.animoffset; var_8.animoffset = var_8.animoffset + 1 - int( var_8.animoffset + 1 ); for ( var_12 = 0; var_12 < var_0.line.anims.size; var_12++ ) var_8 setanimtime( var_0.line.anims[var_12], var_8.animoffset ); var_8 sardines_piecesetmodelsfromarray( var_0, var_0.line.tagmodels, undefined ); if ( var_8.visible ) self.numberoffishinexistence--; var_8.visible = 0; var_11 = 0; } if ( var_8.visible ) { var_13 = common_scripts\_csplines::cspline_getpointattime( self.path, var_8.distance ); var_8.origin = var_13["pos"] + ( 0, 0, var_8.offset ); var_14 = vectortoangles( var_13["vel"] ); var_8.angles = var_14; var_8 maps\interactive_models\_interactive_utility::blendanimsbyspeed( var_13["speed"] * var_8.speedforanimmult, var_0.line.anims, var_0.line.animspeeds, var_0.line.animlengths, var_11 ); continue; } var_8.origin = var_4; var_8.angles = var_5; } wait 0.05; } sardines_linedeletepieces(); self.startstopstate = "stopped"; } sardines_lineattachmodelsandtaperends( var_0, var_1, var_2 ) { if ( isdefined( var_2 ) ) var_3 = min( var_1, var_2 ); else var_3 = var_1; if ( var_3 < var_0.line.taper ) { if ( var_3 == 2 ) { self.speedforanimmult = 1; sardines_piecesetmodelsfromarray( var_0, var_0.line.tagmodels, undefined ); } else { self.speedforanimmult = 4 - 3 * var_3 / var_0.line.taper; var_4 = -4 + 4 * var_3 / var_0.line.taper; sardines_piecesetmodelsfromarray( var_0, var_0.line.tagmodels, "bright", var_4 ); } } else { self.speedforanimmult = 1; sardines_piecesetmodelsfromarray( var_0, var_0.line.tagmodels, "bright", 0 ); } } sardines_linespawnpieces( var_0 ) { if ( !isdefined( self.pieces ) ) { var_1 = int( 1 + common_scripts\_csplines::cspline_time( self.path ) ); self.pieces = []; for ( var_2 = 0; var_2 < self.numpieces; var_2++ ) { self.pieces[var_2] = spawn( "script_model", self.origin ); var_3 = self.pieces[var_2]; var_3.piecenum = var_2; var_3 setmodel( var_0.piece.model ); var_3 useanimtree( var_0.piece.animtree ); var_3 setanim( var_0.line.anim_base, 1, 0.1, 1 ); for ( var_4 = 0; var_4 < var_0.line.anims.size; var_4++ ) var_3 setanim( var_0.line.anims[var_4], 0.01, 0.1, 0 ); if ( var_2 == 0 ) { var_5 = 0; var_6 = 0; } else { var_5 = self.pieces[var_2 - 1].offset; if ( var_2 > 1 ) var_6 = self.pieces[var_2 - 2].offset; else var_6 = 0; } if ( var_2 == self.numpieces - 1 ) var_3.offset = 0.5 * ( var_5 + self.pieces[0].offset ); else var_3.offset = 0.85 * ( randomfloatrange( -18, 18 ) + 1.5 * var_5 - 0.5 * var_6 ); var_3.distance = var_1; var_1 = var_1 - self.spacing; } self.pieces[0].distance = 0; common_scripts\utility::waitframe(); for ( var_2 = 0; var_2 < self.numpieces; var_2++ ) { var_3 = self.pieces[var_2]; var_3.animoffset = var_2 * var_0.line.animoffset; var_7 = var_3.animoffset + var_3.distance / 20; var_7 = var_7 - int( var_7 ); for ( var_4 = 0; var_4 < var_0.line.anims.size; var_4++ ) var_3 setanimtime( var_0.line.anims[var_4], var_7 ); var_3.visible = 0; } } } sardines_linedeletepieces() { foreach ( var_1 in self.pieces ) var_1 delete(); self.pieces = undefined; } sardines_linedebugdrawstats() { } sardines_ball( var_0 ) { self endon( "death" ); self setmodel( "tag_origin" ); self.origin = self.origin + ( 0, 0, 32 ); self.pieces = []; self.rotationspeed = 360 / ( 20 * var_0.ball.rotationperiod ); self.locations = []; self.locations[0] = self.origin; self.currectlocindex = 0; var_1 = maps\_utility::getstruct_delete( self.target, "targetname" ); if ( !isdefined( var_1 ) ) self.locations[1] = self.origin + ( -800, 0, 0 ); else { while ( isdefined( var_1 ) ) { self.locations[self.locations.size] = var_1.origin + ( 0, 0, 32 ); if ( isdefined( var_1.target ) ) { var_1 = getent( var_1.target, "targetname" ); continue; } var_1 = undefined; } } var_2 = 0; self.rings = []; for ( var_3 = 0; var_3 < var_0.ball.rings.size; var_3++ ) { self.rings[var_3] = []; for ( var_4 = 0; var_4 < var_0.ball.rings[var_3].numpieces; var_4++ ) { self.pieces[var_2] = spawn( "script_model", self.origin ); self.rings[var_3][var_4] = var_2; self.pieces[var_2].ball_ring = var_3; self.pieces[var_2].ball_angle = var_4 * 360 / var_0.ball.rings[var_3].numpieces; self.pieces[var_2].ball_offset = var_0.ball.rings[var_3].offset; self.pieces[var_2].ball_i = var_4; self.pieces[var_2].ball_inplace = 1; self.pieces[var_2] setmodel( var_0.piece.model ); self.pieces[var_2] sardines_balllinkpiece( self, self.pieces[var_2].ball_angle, var_0.ball.rings[var_3].radius, var_0.ball.rings[var_3].offset ); self.pieces[var_2] useanimtree( var_0.piece.animtree ); self.pieces[var_2] setanimknob( var_0.piece.anims["idle_loop"], 1, 0.1, 1 ); self.pieces[var_2] setanimknob( var_0.piece.anims["add_bend_left"], 1, 0.1, 1 ); self.pieces[var_2] setanim( var_0.piece.anims["add_tilt_left_child"] ); self.pieces[var_2] setanim( var_0.piece.anims["add_tilt_right_child"] ); var_5 = maps\interactive_models\_interactive_utility::clampandnormalize( self.pieces[var_2].ball_offset, 0, var_0.ball.ringvertoffset ); self.pieces[var_2] setanim( var_0.piece.anims["add_tilt_left"], var_5, 0.1, 1 ); var_5 = maps\interactive_models\_interactive_utility::clampandnormalize( self.pieces[var_2].ball_offset, 0, -1 * var_0.ball.ringvertoffset ); self.pieces[var_2] setanim( var_0.piece.anims["add_tilt_right"], var_5, 0.1, 1 ); self.pieces[var_2] setanimlimited( var_0.piece.anims["add_rotate_left_child"] ); self.pieces[var_2] setanimlimited( var_0.piece.anims["add_rotate_right_child"] ); self.pieces[var_2] setanim( var_0.fish.anims["idle_loop"], 1, 0.1, 1 ); var_6 = var_0.fish.model[2]["grey2"]; if ( var_3 == 1 || var_3 == 3 ) var_6 = var_0.fish.model[2]["bright"]; self.pieces[var_2].fish_model = []; self.pieces[var_2] thread sardines_piecesetmodels( var_6, var_0.ball.numtags, var_0.piece.tagprefix, 0 ); var_2++; } self.rings_isspread[var_3] = 0; } common_scripts\utility::waitframe(); for ( var_4 = 0; var_4 < self.pieces.size; var_4++ ) { var_7 = var_4 * 5 / 24; var_7 = var_7 - int( var_7 ); self.pieces[var_4] setanimtime( var_0.piece.anims["idle_loop"], var_7 ); } var_8 = 0; for (;;) { thread sardines_ballrotate( var_0 ); wait 2; thread sardines_detectpeople( var_0.ball.reactdistance, var_0.ball.panicdistance, var_0.ball.driftspeed, var_0.ball.maxdriftdist, "detectPeople" ); self waittill( "detectPeople" ); self notify( "stop_ballRotate" ); self.currectlocindex = maps\interactive_models\_interactive_utility::wrap( self.currectlocindex + 1, self.locations.size ); var_9 = self.locations[self.currectlocindex]; sardines_ballpanic( var_0, var_9 - self.origin, self.intruderorigin - self.origin, var_0.ball.relocatespeed ); common_scripts\utility::waitframe(); } } sardines_piecesetmodels( var_0, var_1, var_2, var_3 ) { self endon( "death" ); self notify( "sardines_pieceSetModels_starting" ); self endon( "sardines_pieceSetModels_starting" ); var_4 = var_3 / var_1; for ( var_5 = 1; var_5 <= var_1; var_5++ ) { if ( isdefined( self.fish_model[var_5] ) ) self detach( self.fish_model[var_5], var_2 + var_5 ); self attach( var_0, var_2 + var_5 ); self.fish_model[var_5] = var_0; wait( var_4 ); } } sardines_piecesetmodelsfromarray( var_0, var_1, var_2, var_3, var_4 ) { if ( !isdefined( var_2 ) ) { self detachall(); self.brightness = undefined; self.thicknessoffset = undefined; return; } if ( !isdefined( var_3 ) ) var_3 = 0; self endon( "death" ); if ( !isdefined( var_4 ) ) var_4 = 0; var_5 = var_4 / var_1.size; var_6 = getarraykeys( var_1 ); var_7 = self.piecenum / 10; foreach ( var_9 in var_6 ) { var_7 = ( var_7 + 0.1 ) * 6; var_7 = var_7 - int( var_7 ); if ( isdefined( self.brightness ) ) { var_10 = int( var_1[var_9] + self.thicknessoffset + ( 2 * var_7 - 1 ) ); if ( var_10 >= var_0.fish.model.size ) var_10 = var_0.fish.model.size - 1; if ( var_10 >= 0 ) { if ( isdefined( var_0.fish.model[var_10] ) ) self detach( var_0.fish.model[var_10][self.brightness], var_0.piece.tagprefix + var_9 ); } } var_11 = int( var_1[var_9] + var_3 + ( 2 * var_7 - 1 ) ); if ( var_11 >= var_0.fish.model.size ) var_11 = var_0.fish.model.size - 1; if ( var_11 >= 0 ) { if ( isdefined( var_0.fish.model[var_11] ) ) self attach( var_0.fish.model[var_11][var_2], var_0.piece.tagprefix + var_9 ); wait( var_5 ); } } self.brightness = var_2; self.thicknessoffset = var_3; } sardines_ballrotate( var_0 ) { self endon( "death" ); self endon( "stop_ballRotate" ); var_1 = self.angles[1]; for (;;) { var_1 = var_1 + self.rotationspeed; if ( var_1 > 360 ) var_1 = var_1 - 360; self.angles = ( 0, var_1, 0 ); for ( var_2 = 0; var_2 < var_0.ball.rings.size; var_2++ ) { if ( !self.rings_isspread[var_2] ) self.rings_isspread[var_2] = sardines_spreadring( var_0, self, var_2 ); } common_scripts\utility::waitframe(); } } sardines_ballpanic( var_0, var_1, var_2, var_3 ) { var_4 = []; for ( var_5 = 0; var_5 < self.pieces.size; var_5++ ) { var_6 = self.pieces[var_5]; if ( isdefined( var_6.ball_ring ) && var_6.ball_inplace ) { var_7 = var_6.ball_angle + self.angles[1]; var_8 = cos( var_7 ); var_9 = sin( var_7 ); var_4[var_5] = ( var_8, var_9, 0 ); var_4[var_5] = var_4[var_5] * ( self.rotationspeed * 3.14159 / 180 * var_0.ball.rings[var_6.ball_ring].radius ); var_6 unlink(); var_6 thread sardines_piecesetmodels( var_0.fish.model[2]["bright"], var_0.ball.numtags, var_0.piece.tagprefix, 0.2 ); continue; } var_6 notify( "stop_path" ); var_10 = common_scripts\_csplines::cspline_getpointattime( var_6.path, var_6.path_distance ); var_4[var_5] = var_10["vel"] * var_6.speed; var_11 = vectortoangles( var_6.origin - self.origin ); var_6.ball_angle = var_11[1] + 90; } var_12 = vectortoangles( var_2 ); var_2 = ( var_2[0], var_2[1], 0 ); var_13 = vectornormalize( var_2 ); var_14 = length( var_1 ); var_15 = var_1 / var_14; var_16 = ( -1 * var_15[1], var_15[0], var_15[2] ); var_17 = self.origin + var_15 * ( var_14 - 150 ) - var_16 * 64; var_18[0] = spawnstruct(); var_18[1] = spawnstruct(); var_18[0].pieces = []; var_18[1].pieces = []; var_18[0].currentvels = []; var_18[1].currentvels = []; var_18[0].endvel = undefined; var_18[1].endvel = undefined; var_19 = vectortoangles( var_1 ); var_20 = angleclamp180( var_19[1] - var_12[1] ); if ( var_20 > 90 || var_20 < -90 ) { var_18[0].midpoint = self.origin - 100 * var_16 - 100 * var_15 - ( 0, 0, 100 ); var_18[0].midvel = ( var_15 - var_16 - ( 0, 0, 1 ) ) / 1.732; var_18[0].endpoint = var_17 - var_16 * 50; var_18[1].midpoint = self.origin + 100 * var_16 + 100 * var_15 + ( 0, 0, 100 ); var_18[1].midvel = ( 2 * var_15 - var_16 + ( 0, 0, 1 ) ) / 2.45; var_18[1].endpoint = var_17 + var_16 * 50; for ( var_5 = 0; var_5 < self.pieces.size; var_5++ ) { var_7 = angleclamp180( self.pieces[var_5].ball_angle + self.angles[1] - var_20 ); if ( var_7 < 0 ) { var_18[0].pieces[var_18[0].pieces.size] = self.pieces[var_5]; var_18[0].currentvels[var_18[0].currentvels.size] = var_4[var_5]; continue; } var_18[1].pieces[var_18[1].pieces.size] = self.pieces[var_5]; var_18[1].currentvels[var_18[1].currentvels.size] = var_4[var_5]; } } else if ( var_20 > -90 && var_20 < 20 ) { var_12 = var_12 - self.angles; var_21 = ( -1 * var_13[1], var_13[0], var_13[2] ); var_18[0].midpoint = self.origin + var_2 + 100 * var_21 + 20 * var_16 + ( 0, 0, 100 ); var_18[0].midvel = ( var_13 + var_21 + ( 0, 0, 1 ) ) / 1.732; var_18[0].endpoint = var_17 + var_16 * 20 - ( 0, 0, 20 ); var_18[0].endvel = ( var_15 - var_16 * 0.5 + ( 0, 0, 0.5 ) ) / 1.225; var_18[1].midpoint = self.origin + 130 * var_13 - 200 * var_21 - ( 0, 0, 100 ); var_18[1].midvel = ( var_13 - ( 0, 0, 1 ) ) / 1.414; var_18[1].endpoint = var_17 - var_16 * 150 + ( 0, 0, 40 ); var_18[1].endvel = ( var_15 + var_16 - ( 0, 0, 1 ) ) / 1.732; for ( var_5 = 0; var_5 < self.pieces.size; var_5++ ) { var_7 = angleclamp180( self.pieces[var_5].ball_angle - var_12[1] ); if ( var_7 > 45 || var_7 < -135 ) { var_18[0].pieces[var_18[0].pieces.size] = self.pieces[var_5]; var_18[0].currentvels[var_18[0].currentvels.size] = var_4[var_5]; continue; } var_18[1].pieces[var_18[1].pieces.size] = self.pieces[var_5]; var_18[1].currentvels[var_18[1].currentvels.size] = var_4[var_5]; } } else { var_15 = vectornormalize( var_1 ); var_16 = ( -1 * var_15[1], var_15[0], var_15[2] ); var_18[0].midpoint = self.origin + 20 * var_16 + 180 * var_15 + ( 0, 0, 100 ); var_18[0].midvel = ( 2 * var_15 + var_16 + ( 0, 0, 1 ) ) / 2.45; var_18[0].endpoint = var_17; var_18[1].midpoint = self.origin + 150 * var_16 - 60 * var_15 - ( 0, 0, 100 ); var_18[1].midvel = ( 2 * var_15 + var_16 - ( 0, 0, 1 ) ) / 2.45; var_18[1].endpoint = var_17 - var_15 * 50 + var_16 * 50; var_12 = var_12 - self.angles; for ( var_5 = 0; var_5 < self.pieces.size; var_5++ ) { var_7 = angleclamp180( self.pieces[var_5].ball_angle - var_12[1] ); if ( var_7 > -45 && var_7 < 135 ) { var_18[0].pieces[var_18[0].pieces.size] = self.pieces[var_5]; var_18[0].currentvels[var_18[0].currentvels.size] = var_4[var_5]; continue; } var_18[1].pieces[var_18[1].pieces.size] = self.pieces[var_5]; var_18[1].currentvels[var_18[1].currentvels.size] = var_4[var_5]; } } foreach ( var_23 in var_18 ) { var_24 = undefined; if ( var_14 > 400 ) var_24 = common_scripts\_csplines::cspline_makepathtopoint( var_23.midpoint, var_23.endpoint, var_23.midvel, var_23.endvel ); var_25 = []; var_26 = []; var_27 = []; for ( var_5 = 0; var_5 < var_23.pieces.size; var_5++ ) { var_25[var_5] = common_scripts\_csplines::cspline_makepathtopoint( var_23.pieces[var_5].origin, var_23.midpoint, var_23.currentvels[var_5] / var_3, var_23.midvel, 1 ); var_26[var_5] = common_scripts\_csplines::cspline_time( var_25[var_5] ); var_27[var_5] = var_5; } var_28 = var_0.line.spacing * var_3; var_27 = maps\interactive_models\_interactive_utility::array_sortbyarray( var_27, var_26 ); var_29 = 0; for ( var_30 = 0; var_30 < var_27.size; var_30++ ) { var_5 = var_27[var_30]; var_31 = var_29 + var_28 * var_5; if ( var_26[var_5] > var_31 ) var_29 = var_29 + ( var_26[var_5] - var_31 ); } var_29 = var_29 / 2; for ( var_30 = 0; var_30 < var_27.size; var_30++ ) { var_5 = var_27[var_30]; var_32 = var_29 + var_28 * var_5; common_scripts\_csplines::cspline_adjusttime( var_25[var_5], var_32 ); } for ( var_5 = 0; var_5 < var_23.pieces.size; var_5++ ) { var_23.pieces[var_5] setanimknob( var_0.line.anim_base, 1, 0.3 ); var_23.pieces[var_5] thread sardines_setpathanimstarttimes( var_5, var_0.line.anims ); if ( var_5 == 0 || var_5 == var_23.pieces.size - 1 ) var_23.pieces[var_5] thread sardines_pieceswimpath( var_0, var_25[var_5], var_3, undefined, var_24, 3 ); else var_23.pieces[var_5] thread sardines_pieceswimpath( var_0, var_25[var_5], var_3, undefined, var_24 ); if ( isdefined( var_23.pieces[var_5].ball_ring ) ) { self.rings[var_23.pieces[var_5].ball_ring][var_23.pieces[var_5].ball_i] = undefined; var_23.pieces[var_5].ball_ring = undefined; var_23.pieces[var_5].ball_i = undefined; var_23.pieces[var_5].ball_angle = undefined; var_23.pieces[var_5].ball_offset = undefined; var_23.pieces[var_5].ball_inplace = undefined; } } } self.origin = self.origin + var_1; for ( var_5 = 0; var_5 < self.pieces.size; var_5++ ) self.pieces[var_5] thread sardines_ballwaitthenaddpiece( var_0, self, var_5 ); } sardines_setpathanimstarttimes( var_0, var_1 ) { self endon( "death" ); self endon( "stop_path" ); common_scripts\utility::waitframe(); var_2 = var_0 * 5 / 24; var_2 = var_2 - int( var_2 ); for ( var_0 = 0; var_0 < var_1.size; var_0++ ) self setanimtime( var_1[var_0], var_2 ); } sardines_pieceswimpath( var_0, var_1, var_2, var_3, var_4, var_5 ) { if ( !isdefined( var_5 ) ) var_5 = 1; self endon( "death" ); self endon( "stop_path" ); var_6 = undefined; if ( isdefined( var_3 ) ) var_6 = var_3.origin; self.path = var_1; self.path_distance = 0; var_7 = common_scripts\_csplines::cspline_time( var_1 ); self.speed = var_7 / int( var_7 / var_2 + 0.5 ); while ( self.path_distance < var_7 - self.speed / 2 ) { self.path_distance = self.path_distance + self.speed; if ( self.path_distance > var_7 ) self.path_distance = var_7; var_8 = common_scripts\_csplines::cspline_getpointattime( var_1, self.path_distance ); self.origin = var_8["pos"]; var_9 = vectortoangles( var_8["vel"] ); var_10 = var_9 - self.angles; var_10 = ( angleclamp180( var_10[0] ), angleclamp180( var_10[1] ), 0 ); var_11 = []; var_11[0] = clamp( var_10[0], -1 * var_0.piece.maxturn, var_0.piece.maxturn ); var_11[1] = clamp( var_10[1], -1 * var_0.piece.maxturn, var_0.piece.maxturn ); self.angles = self.angles + ( var_11[0], var_11[1], 0 ); if ( isdefined( var_3 ) ) { self.origin = self.origin + ( var_3.origin - var_6 ); var_12 = ( var_7 - self.path_distance ) / ( self.speed * 5 ); if ( var_12 < 1 ) { var_13 = var_10[1] - var_11[1]; var_14 = self.angles[1] + var_13 * ( 1 - var_12 ); self.angles = ( angleclamp180( self.angles[0] ) * var_12, var_14, 0 ); } } var_13 = angleclamp180( self.angles[1] - var_9[1] ); var_15 = maps\interactive_models\_interactive_utility::clampandnormalize( var_13, 0, -150 ); self setanim( var_0.piece.anims["add_rotate_left"], var_15, 0.05 ); var_15 = maps\interactive_models\_interactive_utility::clampandnormalize( var_13, 0, 150 ); self setanim( var_0.piece.anims["add_rotate_right"], var_15, 0.05 ); maps\interactive_models\_interactive_utility::blendanimsbyspeed( self.speed * var_8["speed"] * var_5, var_0.line.anims, var_0.line.animspeeds, var_0.line.animlengths, 0.5 ); common_scripts\utility::waitframe(); } if ( isdefined( var_4 ) ) sardines_pieceswimpath( var_0, var_4, var_2, var_3, undefined, var_5 ); else self notify( "path_complete" ); } sardines_ballwaitthenaddpiece( var_0, var_1, var_2, var_3 ) { self endon( "death" ); self endon( "stop_path" ); self waittill( "path_complete" ); var_4 = sardines_ballfindemptyspot( var_0.ball.rings, var_1 ); self.ball_ring = var_4.ring; self.ball_i = var_4.i; var_5 = var_0.ball.rings[self.ball_ring].radius; var_6 = self.origin - var_1.origin; self.ball_offset = var_6[2] / 2; self.ball_offset = clamp( self.ball_offset, -50, 50 ); var_6 = ( var_6[0], var_6[1], var_6[2] - self.ball_offset ); var_7 = lengthsquared( var_6 ); var_8 = sqrt( var_7 + var_5 * var_5 ); var_9 = vectortoangles( var_1.origin - self.origin ); var_10 = var_9[1]; var_11 = var_5 * anglestoforward( ( 0, var_10 - 90, 0 ) ); var_11 = var_11 + ( var_1.origin + ( 0, 0, self.ball_offset ) ); var_12 = ( var_8 / self.speed - 1 ) * 1.2; var_10 = var_10 - ( var_12 - 1 ) * var_1.rotationspeed; var_10 = var_10 - var_1.angles[1]; var_1.rings[self.ball_ring][self.ball_i] = var_2; self.ball_angle = var_10; self.ball_inplace = 0; sardines_sortring( var_0.ball.rings[self.ball_ring], var_1, self.ball_ring ); var_1.rings_isspread[self.ball_ring] = 0; var_13 = common_scripts\_csplines::cspline_getpointattime( self.path, self.path_distance ); var_9 = ( var_9[0], var_9[1] + var_1.rotationspeed, var_9[2] ); var_14 = anglestoforward( var_9 ); var_14 = var_14 * ( var_1.rotationspeed * 3.14159 / 180 * var_5 ); var_15 = common_scripts\_csplines::cspline_makepathtopoint( self.origin, var_11, var_13["vel"], var_14 / self.speed ); common_scripts\_csplines::cspline_adjusttime( var_15, var_12 * self.speed ); self setanimknob( var_0.line.anim_base ); thread sardines_pieceswimpath( var_0, var_15, self.speed, var_1, undefined, var_3 ); var_16 = common_scripts\_csplines::cspline_length( var_15 ) / ( self.speed * 20 ); self setanimknob( var_0.piece.anims["idle_loop"], 1, var_16 + 0.5 ); self setanim( var_0.piece.anims["add_bend_left"], 1, var_16 + 0.5 ); self waittill( "path_complete" ); self.ball_inplace = 1; var_1.rings_isspread[self.ball_ring] = 0; if ( self.ball_ring == 0 || self.ball_ring == 2 ) { thread sardines_piecesetmodels( var_0.fish.model[2]["grey1"], var_0.ball.numtags, var_0.piece.tagprefix, 3 ); thread maps\interactive_models\_interactive_utility::wait_then_fn( 3, "sardines_pieceSetModels_starting", ::sardines_piecesetmodels, var_0.fish.model[2]["grey2"], var_0.ball.numtags, var_0.piece.tagprefix, 2 ); } sardines_balllinkpiece( var_1, self.ball_angle, var_5, self.ball_offset ); } sardines_balllinkpiece( var_0, var_1, var_2, var_3 ) { var_4 = var_2 * sin( var_1 ); var_5 = -1 * var_2 * cos( var_1 ); self linkto( var_0, "tag_origin", ( var_4, var_5, var_3 ), ( 0, var_1, 0 ) ); } sardines_detectpeople( var_0, var_1, var_2, var_3, var_4 ) { self endon( "death" ); self endon( "damage" ); self endon( var_4 ); var_5 = ( 0, 0, -1 * var_0 ); var_6 = spawn( "trigger_radius", self.origin + var_5, 0, var_0, var_0 * 2 ); thread maps\interactive_models\_interactive_utility::delete_on_notify( var_6, "death", "damage", var_4 ); var_7 = self.origin; var_8 = 1; var_9 = 1; while ( var_8 ) { var_6 waittill( "trigger", var_10 ); if ( isdefined( var_10 ) && isplayer( var_10 ) ) { var_11 = var_3 * var_3; var_12 = 1; while ( ( var_12 || !var_9 ) && var_8 ) { self.intruderorigin = var_10.origin + ( 0, 0, 64 ); var_13 = var_10.origin - self.origin; var_14 = length( var_13 ); if ( var_14 < var_0 ) { var_16 = ( var_0 - var_14 ) / ( var_0 - var_1 ); var_17 = var_13 / var_14; self.origin = self.origin - var_16 * var_2 * var_17; var_6.origin = self.origin + var_5; var_9 = 0; if ( distancesquared( self.origin, var_7 ) > var_11 || var_14 < var_1 ) var_8 = 0; common_scripts\utility::waitframe(); continue; } var_12 = 0; self.intruderorigin = undefined; var_18 = distance( self.origin, var_7 ); if ( var_18 > 1 ) { var_19 = ( var_7 - self.origin ) / var_18; self.origin = self.origin + var_19 * 0.5; var_6.origin = self.origin + var_5; common_scripts\utility::waitframe(); var_18 = distance( self.origin, var_7 ); } else var_9 = 1; } continue; } common_scripts\utility::waitframe(); } self notify( var_4 ); } sardines_ballfindemptyspot( var_0, var_1 ) { var_2 = spawnstruct(); var_3 = 0; var_4 = 0; var_5 = 0; while ( var_3 < var_0.size && !var_5 ) { var_4 = 0; while ( var_4 < var_0[var_3].numpieces && !var_5 ) { if ( !isdefined( var_1.rings[var_3][var_4] ) ) var_5 = 1; if ( !var_5 ) var_4++; } if ( !var_5 ) var_3++; } var_2.ring = var_3; var_2.i = var_4; return var_2; } sardines_sortring( var_0, var_1, var_2 ) { var_3 = []; var_4 = []; for ( var_5 = 0; var_5 < var_0.numpieces; var_5++ ) { if ( isdefined( var_1.rings[var_2][var_5] ) ) { var_6 = var_3.size; var_3[var_6] = var_1.rings[var_2][var_5]; var_7 = var_1.pieces[var_1.rings[var_2][var_5]].ball_angle; var_1.pieces[var_3[var_6]].ball_angle = angleclamp( var_7 ); var_4[var_6] = var_1.pieces[var_3[var_6]].ball_angle; } } var_1.rings[var_2] = maps\interactive_models\_interactive_utility::array_sortbyarray( var_3, var_4 ); } sardines_spreadring( var_0, var_1, var_2 ) { var_3 = var_1.rings[var_2]; if ( var_3.size == 0 ) return 1; var_4 = var_0.ball.rings[var_2]; var_5 = 1; var_6 = 2; var_7 = var_3.size - 1; var_8 = 360 / var_3.size - 5; var_9 = []; var_10 = []; var_11 = []; var_12 = []; var_13 = []; for ( var_14 = 0; var_14 <= var_7; var_14++ ) var_13[var_14] = var_1.pieces[var_3[var_14]]; for ( var_14 = 0; var_14 <= var_7; var_14++ ) { var_9[var_14] = 0; var_10[var_14] = 0; var_11[var_14] = 0; var_15 = var_13[var_14].ball_angle; var_16 = var_13[maps\interactive_models\_interactive_utility::wrap( var_14 - 1, var_3.size )].ball_angle; var_17 = var_13[maps\interactive_models\_interactive_utility::wrap( var_14 - 2, var_3.size )].ball_angle; var_18 = var_13[maps\interactive_models\_interactive_utility::wrap( var_14 - 3, var_3.size )].ball_angle; if ( var_14 == 0 ) var_16 = var_16 - 360; if ( var_14 <= 1 ) var_17 = var_17 - 360; if ( var_14 <= 2 ) var_18 = var_18 - 360; if ( var_15 - var_16 < var_8 ) { var_9[var_14] = var_6 * ( 1.01 - ( var_15 - var_16 ) / var_8 ); var_5 = 0; } if ( var_15 - var_17 < 2 * var_8 && var_13[maps\interactive_models\_interactive_utility::wrap( var_14 - 1, var_3.size )].ball_inplace ) { var_10[var_14] = var_10[var_14] + var_6 * ( 1.01 - ( var_15 - var_17 ) / ( var_8 * 2 ) ); if ( var_15 - var_17 < 3 * var_8 && var_13[maps\interactive_models\_interactive_utility::wrap( var_14 - 1, var_3.size )].ball_inplace ) var_11[var_14] = var_11[var_14] + var_6 * ( 1.01 - ( var_15 - var_18 ) / ( var_8 * 3 ) ); } if ( var_13[var_14].ball_offset != var_4.offset ) { if ( var_13[var_14].ball_inplace ) { var_19 = var_4.offset - var_13[var_14].ball_offset; var_19 = clamp( var_19, -1, 1 ); var_13[var_14].ball_offset = var_13[var_14].ball_offset + var_19; var_12[var_14] = 1; } var_20 = maps\interactive_models\_interactive_utility::clampandnormalize( var_13[var_14].ball_offset, 0, var_0.ball.ringvertoffset ); var_13[var_14] setanimlimited( var_0.piece.anims["add_tilt_left"], var_20, 0.1, 1 ); var_20 = maps\interactive_models\_interactive_utility::clampandnormalize( var_13[var_14].ball_offset, 0, -1 * var_0.ball.ringvertoffset ); var_13[var_14] setanimlimited( var_0.piece.anims["add_tilt_right"], var_20, 0.1, 1 ); var_5 = 0; } } if ( !var_5 ) { var_21 = 0; for ( var_14 = 0; var_14 <= var_7; var_14++ ) { if ( var_13[var_14].ball_inplace ) { var_22 = var_9[var_14] + var_10[var_14] + var_11[var_14]; var_22 = var_22 - ( var_9[maps\interactive_models\_interactive_utility::wrap( var_14 + 1, var_3.size )] + var_10[maps\interactive_models\_interactive_utility::wrap( var_14 + 2, var_3.size )] + var_11[maps\interactive_models\_interactive_utility::wrap( var_14 + 3, var_3.size )] ); var_22 = clamp( var_22, -1 * var_6, var_6 ); if ( var_22 != 0 || isdefined( var_12[var_14] ) ) { var_13[var_14].ball_angle = var_13[var_14].ball_angle + var_22; if ( var_13[var_14].ball_angle < 0 || var_13[var_14].ball_angle > 360 ) var_21 = 1; var_13[var_14] sardines_balllinkpiece( var_1, var_13[var_14].ball_angle, var_4.radius, var_13[var_14].ball_offset ); } } } if ( var_21 ) sardines_sortring( var_4, var_1, var_2 ); } return var_5; }