IW4-Dump-Files/common_scripts/_painter.gsc

1100 lines
30 KiB
Plaintext

#include common_scripts\utility;
main( painter_spmp )
{
painter_setup_array = getentarray( "painter_setup", "targetname" );
if ( !painter_setup_array.size )
return;
if ( !getdvarint( "painter" ) )
{
array_thread( painter_setup_array, ::painter_clean_me );
return;
}
painter_initvars( painter_spmp );
painter_groups = [];
groups = get_painter_groups( painter_setup_array );
foreach ( group in groups )
setup_painter_group( group );
thread painter_init();
array_thread( level.spam_model_group, ::default_undefined );
level.stop_load = true;
level waittill( "forever" );
}
painter_clean_me()
{
if( isdefined( self.target ) )
{
ent = getent(self.target,"targetname");
ent delete();
}
self delete();
}
default_undefined()
{
if ( !isdefined( self.bPosedstyle ) )
self.bPosedstyle = false;
if ( !isdefined( self.bOrienttoplayeryrot ) )
self.bOrienttoplayeryrot = false;
if ( !isdefined( self.bTreeOrient ) )
self.bTreeOrient = false;
if ( !isdefined( self.bFacade ) )
self.bFacade = false;
if ( !isdefined( self.density ) )
self.density = 32;
if ( !isdefined( self.radius ) )
self.radius = 84;
if ( !isdefined( self.maxdist ) )
self.maxdist = 1000;
if ( !isdefined( self.angleoffset ) )
self.angleoffset = [];
}
setup_painter_group( group )
{
density = 100000001;
group_copy = group;
// figure out default radius and density for the group
bTreeOrient = undefined;
bFacade = undefined;
radius = undefined;
maxdist = undefined;
offsetheight = undefined;
bPosedstyle = undefined;
bOrienttoplayeryrot = undefined;
angleoffset = undefined;
foreach ( obj in group )
{
angleoffset = get_angle_offset( obj );
offsetheight = get_height_offset( obj );
modeluseprefab = ( isdefined( obj.script_parameters ) && obj.script_parameters == "use_prefab_model" );
if ( isdefined( obj.radius ) )
radius = obj.radius;
if ( isdefined( obj.script_painter_treeorient ) && obj.script_painter_treeorient )
bTreeOrient = true;
if ( isdefined( obj.script_painter_maxdist ) && obj.script_painter_maxdist )
maxdist = obj.script_painter_maxdist;
if ( isdefined( obj.script_painter_facade ) && obj.script_painter_facade )
bFacade = true;
foreach ( other_obj in group_copy )
{
if ( obj == other_obj )
continue;
dist = distance( obj.origin, other_obj.origin );
assert( dist > 0 );
if ( dist < density )
density = dist;
}
if ( density == 100000001 )
density = undefined;
add_spammodel( obj.script_paintergroup, obj.model, bTreeOrient, bFacade, density, radius, maxdist, offsetheight, bPosedstyle, bOrienttoplayeryrot, angleoffset, modeluseprefab );
}
}
get_angle_offset( obj )
{
if( !isdefined( obj.target ) )
return undefined;
targent = getent( obj.target, "targetname" );
assert( isdefined ( targent ) );
return targent.angles - obj.angles;
}
get_height_offset( obj )
{
if( !isdefined( obj.target ) )
return undefined;
targent = getent( obj.target, "targetname" );
assert( isdefined ( targent ) );
origin = targent.origin[2] - obj.origin[2];
targent delete();
return origin;
}
get_painter_groups( painter_setup_array )
{
groups = [];
script_paintergroup = "";
foreach ( paint_obj in painter_setup_array )
{
if ( !isdefined( paint_obj.script_paintergroup ) )
{
paint_obj.script_paintergroup = paint_obj.model;
}
script_paintergroup = paint_obj.script_paintergroup;
level.painter_startgroup = script_paintergroup;
if ( !isdefined( groups[ script_paintergroup ] ) || ! groups[ script_paintergroup ].size )
groups[ script_paintergroup ] = [];
groups[ script_paintergroup ][ groups[ script_paintergroup ].size ] = paint_obj;
}
return groups;
}
painter_initvars( painter_spmp )
{
level._clearalltextafterhudelem = false;
level.bPosedstyle = false;
level.bOrienttoplayeryrot = false;
level.spam_density_scale = 16;
level.spaming_models = false;
level.spam_model_group = [];
level.spamed_models = [];
level.spam_models_flowrate = .1;
level.spam_model_radius = 31;
level.spam_maxdist = 1000;
level.previewmodels = [];
level.spam_models_isCustomrotation = false;
level.spam_models_isCustomheight = false;
level.spam_models_customheight = 0;
level.spam_model_circlescale_lasttime = 0;
level.spam_model_circlescale_accumtime = 0;
level.paintadd = ::add_spammodel;
// level.geteyeoffset = (0,0,24);
level.timeLimitOverride = true;
thread hack_start( painter_spmp );
thread hud_init();
}
hack_start( painter_spmp )
{
if ( !isdefined( painter_spmp ) )
painter_spmp = "painter";
precachemenu( painter_spmp );
//who knows what the mp scripts are doing I took a dive deep into them and discovered many hud elements being controled through code and not through a menu that can be easily disabled
// here I simply automate some things to get the user up and running.
// get the player going. I don't handle people dieing in this tool since they are in ufo mode anyway.
flag_init( "user_alive" );
while ( !isdefined( get_player() ) )
wait .05;
level.painter_player = get_player();
wait .05;
menu = "team_marinesopfor";
response = "autoassign";
level.painter_player notify( "menuresponse", menu, response );
wait .05;
menu = "changeclass_offline";
response = "offline_class1_mp, 0";
level.painter_player notify( "menuresponse", menu, response );
level.painter_player openpopupmenu( painter_spmp );// painter.menu execs some console commands( ufo mode ).. sneaky hacks.
wait .05;
level.painter_player closepopupmenu();
flag_set( "user_alive" );
}
painter_init()
{
array_call( getentarray( "script_model", "classname" ), ::delete );
setcurrentgroup( level.painter_startgroup );
level.painter_startgroup = undefined;
playerInit();
}
hud_update_placed_model_count()
{
level.hud_controler[ "helppm" ].description setvalue( level.spamed_models.size );
whitecap = 256;
if ( level.spamed_models.size < whitecap )
{
level.hud_controler[ "helppm" ].description.color = ( 1, 1, 1 );
return;
}
r = 1;
g = 1 - ( ( level.spamed_models.size - whitecap ) / whitecap );
b = g;
level.hud_controler[ "helppm" ].description.color = ( r, g, b );
}
hud_init()
{
flag_init( "user_hud_active" );
flag_wait( "user_alive" );
//shorter list for mp cause it's got too many g_configstring somesuch. There is probably better check than substr on the mapname. I don't think this will bite me though, knock on wood.
listsize = 7;
if ( is_mp() )
listsize = 7;
hudelems = [];
spacer = 15;
div = int( listsize / 2 );
org = 240 + div * spacer;
alphainc = .5 / div;
alpha = alphainc;
for ( i = 0;i < listsize;i++ )
{
hudelems[ i ] = _newhudelem();
hudelems[ i ].location = 0;
hudelems[ i ].alignX = "left";
hudelems[ i ].alignY = "middle";
hudelems[ i ].foreground = 1;
hudelems[ i ].fontScale = 2;
hudelems[ i ].sort = 20;
if ( i == div )
hudelems[ i ].alpha = 1;
else
hudelems[ i ].alpha = alpha;
hudelems[ i ].x = 20;
hudelems[ i ].y = org;
hudelems[ i ] _settext( "." );
if ( i == div )
alphainc *= -1;
alpha += alphainc;
org -= spacer;
}
level.spam_group_hudelems = hudelems;
crossHair = _newhudelem();
crossHair.location = 0;
crossHair.alignX = "center";
crossHair.alignY = "bottom";
crossHair.foreground = 1;
crossHair.fontScale = 2;
crossHair.sort = 20;
crossHair.alpha = 1;
crossHair.x = 320;
crossHair.y = 244;
crossHair _settext( "." );
level.crosshair = crossHair;
// setup "crosshair"
crossHair = _newhudelem();
crossHair.location = 0;
crossHair.alignX = "center";
crossHair.alignY = "bottom";
crossHair.foreground = 1;
crossHair.fontScale = 2;
crossHair.sort = 20;
crossHair.alpha = 0;
crossHair.x = 320;
crossHair.y = 244;
crossHair setvalue( 0 );
level.crosshair_value = crossHair;
controler_hud_add( "helppm", 1, "^5Placed Models: ", undefined, level.spamed_models.size );
controler_hud_add( "helpdensity", 2, "^5Spacing: ", undefined, level.spam_density_scale );
controler_hud_add( "helpradius", 3, "^5Radius: ", undefined, level.spam_model_radius );
controler_hud_add( "helpxy", 6, "^4X / ^3Y: ", undefined, level.spam_model_radius );
controler_hud_add( "helpab", 7, "^2A / ^1B^7: ", " - " );
controler_hud_add( "helplsrs", 8, "^8L^7 / R Stick: ", " - " );
controler_hud_add( "helplbrb", 9, "^8L^7 / R Shoulder: ", " - " );
controler_hud_add( "helpdpu", 10, "^8DPad U / ^7D: ", " - " );
controler_hud_add( "helpdpl", 11, "^8DPad L / ^7R: ", " - " );
controler_hud_add( "helpF", 17, "^8F: ^7( dump ) ^3map_source/" + level.script + "_modeldump.map", "" );
hint_buttons_main();
flag_set( "user_hud_active" );
}
hint_buttons_main()
{
controler_hud_update_text( "helpxy", "^4Select Set Up ^7 / ^3Down" );
controler_hud_update_text( "helpab", "^2Spacing Down ^7 / ^1up " );
controler_hud_update_text( "helplsrs", "^8Radius Down ^7 / Up" );
controler_hud_update_text( "helplbrb", "^8Remove ^7 / Place" );
controler_hud_update_text( "helpdpl", "^8zOffset Clear ^7 / Set" );
controler_hud_update_text( "helpdpu", "^8Rotation Clear ^7 / Set" );
// controler_hud_update_text( "helpF", text );
}
hint_buttons_zoffset()
{
controler_hud_update_text( "helpxy", "^4 - ^7 / ^3 - " );
controler_hud_update_text( "helpab", "^2Height Down ^7 / ^1Up " );
controler_hud_update_text( "helplsrs", "^8 - ^7 / - " );
controler_hud_update_text( "helplbrb", "^8 - ^7 / - " );
controler_hud_update_text( "helpdpl", "^8 - ^7 / Set" );
controler_hud_update_text( "helpdpu", "^8 - ^7 / - " );
controler_hud_update_text( "helpF", " - " );
}
hint_buttons_rotation()
{
controler_hud_update_text( "helpxy", "^4 - ^7 / ^3 - " );
controler_hud_update_text( "helpab", "^2RotateOther Up ^7 / ^1Down " );
controler_hud_update_text( "helplsrs", "^8 - ^7 / - " );
controler_hud_update_text( "helplbrb", "^8 - ^7 / - " );
controler_hud_update_text( "helpdpl", "^8 - ^7 / - " );
controler_hud_update_text( "helpdpu", "^8Set ^7 / - " );
controler_hud_update_text( "helpF", " - " );
}
setcurrentgroup( group )
{
flag_wait( "user_hud_active" );
level.spam_model_current_group = group;
keys = getarraykeys( level.spam_model_group );
index = 0;
div = int( level.spam_group_hudelems.size / 2 );
for ( i = 0;i < keys.size;i++ )
if ( keys[ i ] == group )
{
index = i;
break;
}
level.spam_group_hudelems[ div ] _settext( keys[ index ] );
for ( i = 1;i < level.spam_group_hudelems.size - div;i++ )
{
if ( index - i < 0 )
{
level.spam_group_hudelems[ div + i ] _settext( "." );
continue;
}
level.spam_group_hudelems[ div + i ] _settext( keys[ index - i ] );
}
for ( i = 1;i < level.spam_group_hudelems.size - div;i++ )
{
if ( index + i > keys.size - 1 )
{
// -- --
level.spam_group_hudelems[ div - i ] _settext( "." );
continue;
}
level.spam_group_hudelems[ div - i ] _settext( keys[ index + i ] );
}
group = getcurrent_groupstruct();
level.bOrienttoplayeryrot = group.bOrienttoplayeryrot;
level.bPosedstyle = group.bPosedstyle;
level.spam_maxdist = group.maxdist;
level.spam_model_radius = group.radius;
level.hud_controler[ "helpradius" ].description setvalue( level.spam_model_radius );
level.spam_density_scale = group.density;
level.hud_controler[ "helpdensity" ].description setvalue( level.spam_density_scale );
}
setgroup_up()
{
index = undefined;
keys = getarraykeys( level.spam_model_group );
for ( i = 0;i < keys.size;i++ )
if ( keys[ i ] == level.spam_model_current_group )
{
index = i + 1;
break;
}
if ( index == keys.size )
return;
setcurrentgroup( keys[ index ] );
while ( level.painter_player buttonpressed( "BUTTON_Y" ) )
wait .05;
}
setgroup_down()
{
index = undefined;
keys = getarraykeys( level.spam_model_group );
for ( i = 0;i < keys.size;i++ )
if ( keys[ i ] == level.spam_model_current_group )
{
index = i - 1;
break;
}
if ( index < 0 )
return;
setcurrentgroup( keys[ index ] );
while ( level.painter_player buttonpressed( "BUTTON_X" ) )
wait .05;
}
Add_Spammodel( group, model, bTreeOrient, bFacade, density, radius, maxdist, offsetheight, bPosedstyle, bOrienttoplayeryrot, angleoffset, modelusesprefab )
{
if ( !isdefined( level.spam_model_group[ group ] ) )
{
struct = spawnstruct();
level.spam_model_group[ group ] = struct;
level.spam_model_group[ group ].models = [];
}
if( !isdefined( angleoffset ) )
angleoffset = (0,0,0);
level.spam_model_group[ group ].bFacade = bFacade;
level.spam_model_group[ group ].bTreeOrient = bTreeOrient;
level.spam_model_group[ group ].density = density;
level.spam_model_group[ group ].radius = radius;
level.spam_model_group[ group ].maxdist = maxdist;
level.spam_model_group[ group ].bPosedstyle = bPosedstyle;
level.spam_model_group[ group ].bOrienttoplayeryrot = bOrienttoplayeryrot;
if( !isdefined( level.spam_model_group[ group ].angleoffset ) )
level.spam_model_group[ group ].angleoffset = [];
level.spam_model_group[ group ].angleoffset[ model ] = angleoffset;
if( !isdefined( level.spam_model_group[ group ].heightoffset ) )
level.spam_model_group[ group ].heightoffset = [];
level.spam_model_group[ group ].heightoffset[ model ] = offsetheight;
if( !isdefined( level.spam_model_group[ group ].modelusesprefab ) )
level.spam_model_group[ group ].modelusesprefab = [];
level.spam_model_group[ group ].modelusesprefab[ model ] = modelusesprefab;
level.spam_model_group[ group ].models[ level.spam_model_group[ group ].models.size ] = model;
}
playerInit()
{
level.painter_max = 700;
level.painter_player takeAllWeapons();
flag_wait( "user_hud_active" );
while ( 1 )
{
trace = player_view_trace();
draw_placement_circle( trace );
if ( level.painter_player buttonpressed( "f" ) )
dump_models();
if ( level.painter_player buttonpressed( "DPAD_UP" ) )
customrotation_mode( trace, "DPAD_UP" );
else if ( level.painter_player buttonpressed( "DPAD_DOWN" ) )
customrotation_mode_off();
else if ( level.painter_player buttonpressed( "DPAD_RIGHT" ) )
customheight_mode( trace, "DPAD_RIGHT" );
else if ( level.painter_player buttonpressed( "DPAD_LEFT" ) )
customheight_mode_off();
else if ( level.painter_player buttonpressed( "BUTTON_X" ) )
setgroup_down();
else if ( level.painter_player buttonpressed( "BUTTON_Y" ) )
setgroup_up();
else if ( level.painter_player buttonpressed( "BUTTON_LSTICK" ) )
spam_model_circlescale( trace, -1 );
else if ( level.painter_player buttonpressed( "BUTTON_RSTICK" ) )
spam_model_circlescale( trace, 1 );
else if ( level.painter_player buttonpressed( "BUTTON_A" ) )
spam_model_densityscale( trace, -1 );
else if ( level.painter_player buttonpressed( "BUTTON_B" ) )
spam_model_densityscale( trace, 1 );
else
{
if ( level.painter_player buttonpressed( "BUTTON_LSHLDR" ) )
spam_model_erase( trace );
if ( level.painter_player buttonpressed( "BUTTON_RSHLDR" ) )
thread spam_model_place( trace );// threaded for delay
}
level notify( "clear_previews" );
wait .05;
hud_update_placed_model_count();
}
}
customheight_mode_off()
{
level.spam_models_isCustomheight = false;
hint_buttons_main();
}
customheight_mode( trace, button )
{
if ( trace[ "fraction" ] == 1 )
return;
while ( level.painter_player buttonpressed( button ) )
wait .05;
level.spam_models_isCustomheight = true;
hint_buttons_zoffset();
models = [];
models = spam_models_atcircle( trace, false, true );
inc = 2;
dir = 1;
origin = trace[ "position" ];
while ( !level.painter_player buttonpressed( button ) )
{
height = level.spam_models_customheight;
if ( level.painter_player buttonpressed( "BUTTON_A" ) )
dir = -1;
else if ( level.painter_player buttonpressed( "BUTTON_B" ) )
dir = 1;
else
dir = 0;
height += dir * inc;
if ( height == 0 )
height += dir * inc;
level.spam_models_customheight = height;
array_thread( models, ::customheight_mode_offsetmodels, trace );
draw_placement_circle( trace, ( 1, 1, 1 ) );
wait .05;
}
array_thread( models, ::deleteme );
hint_buttons_main();
while ( level.painter_player buttonpressed( button ) )
wait .05;
}
customheight_mode_offsetmodels( trace )
{
self.origin = self.orgorg + ( trace[ "normal" ] * level.spam_models_customheight );
}
customrotation_mode_off()
{
level.spam_models_isCustomrotation = false;
hint_buttons_main();
}
customrotation_mode( trace, button )
{
if ( trace[ "fraction" ] == 1 )
return;
while ( level.painter_player buttonpressed( button ) )
wait .05;
hint_buttons_rotation();
level.spam_models_isCustomrotation = true;
level.spam_models_customrotation = level.painter_player getplayerangles();
models = [];
models = spam_models_atcircle( trace, true, true );
otherangle = 0;
otherangleinc = 1;
dir = 0;
while ( !level.painter_player buttonpressed( button ) )
{
dir = 0;
if ( level.painter_player buttonpressed( "BUTTON_A" ) )
dir = -1;
else if ( level.painter_player buttonpressed( "BUTTON_B" ) )
dir = 1;
otherangle += dir * otherangleinc;
if ( otherangle > 360 )
otherangle = 1;
if ( otherangle < 0 )
otherangle = 359;
draw_placement_circle( trace, ( 0, 0, 1 ) );
level.spam_models_customrotation = level.painter_player getplayerangles();
level.spam_models_customrotation += ( 0, 0, otherangle );
for ( i = 0;i < models.size;i++ )
models[ i ].angles = level.spam_models_customrotation;
wait .05;
}
hint_buttons_main();
while ( level.painter_player buttonpressed( button ) )
wait .05;
for ( i = 0;i < models.size;i++ )
models[ i ] thread deleteme();
}
deleteme()
{
self delete();
}
spam_model_clearcondition()
{
self endon( "death" );
level waittill( "clear_previews" );
level.previewmodels = array_remove( level.previewmodels, self );
self delete();
}
crosshair_fadetopoint()
{
level notify( "crosshair_fadetopoint" );
level endon( "crosshair_fadetopoint" );
wait 2;
level.crosshair_value.alpha = 0;
level.crosshair.alpha = 1;
}
spam_model_circlescale( trace, dir )
{
if ( gettime() - level.spam_model_circlescale_lasttime > 60 )
level.spam_model_circlescale_accumtime = 0;
level.spam_model_circlescale_accumtime += .05;
if ( level.spam_model_circlescale_accumtime < .5 )
inc = 2;
else
inc = level.spam_model_circlescale_accumtime / .3;
radius = level.spam_model_radius;
radius += dir * inc;
if ( radius > 0 )
level.spam_model_radius = radius;
level.hud_controler[ "helpradius" ].description setvalue( level.spam_model_radius );
level.spam_model_circlescale_lasttime = gettime();
}
spam_model_densityscale( trace, dir )
{
// ghetto hack here. density scale used for distance on floating model types
inc = 2;
scale = level.spam_density_scale;
scale += dir * inc;
if ( scale > 0 )
level.spam_density_scale = scale;
level.crosshair_value.alpha = 1;
level.crosshair.alpha = 0;
level.crosshair_value setvalue( level.spam_density_scale );
level.hud_controler[ "helpdensity" ].description setvalue( level.spam_density_scale );
thread crosshair_fadetopoint();
}
draw_placement_circle( trace, coloroverride )
{
if ( !isdefined( coloroverride ) )
coloroverride = ( 0, 1, 0 );
if ( trace[ "fraction" ] == 1 )
return;
// angles = vectortoangles( anglestoup( vectortoangles( trace[ "normal" ] ) ) );
angles = vectortoangles( trace[ "normal" ] );
origin = trace[ "position" ];
radius = level.spam_model_radius;
// plot_circle( origin, radius, angles, color, circleres );
plot_circle( origin, radius, angles, coloroverride, 40, level.spam_model_radius );
if ( level.spam_models_isCustomrotation )
draw_axis( origin, level.spam_models_customrotation );
if ( level.spam_models_isCustomheight )
draw_arrow( origin, origin + ( trace[ "normal" ] * level.spam_models_customheight ), ( 1, 1, 1 ) );
}
player_view_trace()
{
maxdist = level.spam_maxdist;
traceorg = level.painter_player geteye();
return bullettrace( traceorg, traceorg + ( anglestoforward( level.painter_player getplayerangles() ) * maxdist ), 0, self );
}
Orienttoplayeryrot()
{
self addyaw( level.painter_player getplayerangles()[ 1 ] - flat_angle( self.angles )[ 1 ] );
// self.angles = ( x, y, z );
}
getcurrent_groupstruct()
{
return level.spam_model_group[ level.spam_model_current_group ];
}
orient_model()
{
group = getcurrent_groupstruct();
if ( level.spam_models_isCustomrotation )
{
self.angles = level.spam_models_customrotation;
return;
}
if ( level.bPosedstyle )
self.angles = level.painter_player getplayerangles();
if ( level.bOrienttoplayeryrot )
self Orienttoplayeryrot();
if ( group.bTreeOrient )
self.angles = flat_angle( self.angles );
if ( ! level.bOrienttoplayeryrot && !level.bPosedstyle )
self addyaw( randomint( 360 ) );
if ( group.bFacade )
{
self.angles = flat_angle( vectortoangles( self.origin - level.painter_player geteye() ) );
self addyaw( 90 );
}
assert( isdefined( group.angleoffset ) && isdefined( group.angleoffset[ self.model] ) );
self addroll( group.angleoffset[self.model][ 0 ] );
self addpitch( group.angleoffset[self.model][ 1 ] );
self addyaw( group.angleoffset[self.model][ 2 ] );
}
spam_model_place( trace )
{
if ( level.spaming_models )
return;
if ( trace[ "fraction" ] == 1 && !level.bPosedstyle )
return;
level.spaming_models = true;
models = spam_models_atcircle( trace, true );
level.spamed_models = array_combine( level.spamed_models, models );
level.spaming_models = false;
}
getrandom_spammodel()
{
models = level.spam_model_group[ level.spam_model_current_group ].models;
return models[ randomint( models.size ) ];
}
spam_models_atcircle( trace, bRandomrotation, bForcedSpam )
{
if ( !isdefined( bForcedSpam ) )
bForcedSpam = false;
models = [];
incdistance = level.spam_density_scale;
radius = level.spam_model_radius;
incs = int( radius / incdistance ) * 2;
startpoint = 0;
traceorg = trace[ "position" ];
angles = vectortoangles( trace[ "normal" ] );
if ( bRandomrotation )
angles += ( 0, randomfloat( 360 ), 0 );
xvect = vectornormalize( anglestoright( angles ) );
yvect = vectornormalize( anglestoup( angles ) );
startpos = traceorg;
startpos -= ( xvect * radius );
startpos -= ( yvect * radius );
startpos += ( xvect * incdistance );
startpos += ( yvect * incdistance );
modelpos = startpos;
// special for when circle is too small for current density to place anything. Just place one in the center..
if ( incs == 0 || level.bPosedstyle )
{
if ( !bForcedSpam )
if ( is_too_dense( traceorg ) )
return models;
if ( !bForcedSpam )
if ( level.spamed_models.size + models.size > level.painter_max )
return models;
getmodel = getrandom_spammodel();
models[ 0 ] = spam_modelattrace( trace, getmodel );
models[ 0 ] orient_model();
return models;
}
countourtrace = [];
for ( x = startpoint;x < incs;x++ )
for ( y = startpoint;y < incs;y++ )
{
if ( !bForcedSpam )
if ( level.spamed_models.size + models.size > level.painter_max )
return models;;
modelpos = startpos;
modelpos += ( xvect * x * incdistance );
modelpos += ( yvect * y * incdistance );
if ( distance( modelpos, traceorg ) > radius )
continue;
// if ( !bForcedSpam )
countourtrace = contour_point( modelpos, angles, level.spam_model_radius );
if ( countourtrace[ "fraction" ] == 1 )
continue;
if ( is_too_dense( countourtrace[ "position" ] ) )
continue;
getmodel = getrandom_spammodel();
model = spam_modelattrace( countourtrace, getmodel );
model orient_model();
models[ models.size ] = model;
}
return models;
}
is_too_dense( testorg )
{
// going backwards will be faster
for ( i = level.spamed_models.size - 1; i >= 0; i -- )
if ( distance( level.spamed_models[ i ].orgorg, testorg ) < ( level.spam_density_scale - 1 ) )
return true;
return false;
}
get_player()
{
return getentarray( "player", "classname" )[ 0 ];
}
spam_modelattrace( trace, getmodel )
{
model = spawn( "script_model", level.painter_player.origin );
model setmodel( getmodel );
model notsolid();
model.origin = trace[ "position" ];
model.angles = vectortoangles( trace[ "normal" ] );
model addpitch( 90 );
model.orgorg = model.origin;
group = getcurrent_groupstruct();
if ( level.spam_models_isCustomheight )
model.origin += ( trace[ "normal" ] * level.spam_models_Customheight );
group = getcurrent_groupstruct();
if( isdefined( group.heightoffset[ getmodel ] ) )
model.origin += ( trace[ "normal" ] * group.heightoffset[ getmodel ] );
if( isdefined( group.modelusesprefab[ getmodel ] ) )
model.modelusesprefab = group.modelusesprefab[ getmodel ];
return model;
}
contour_point( origin, angles, height )
{
offset = height;
vect = anglestoforward( angles );
destorg = origin + ( vect * offset );
targetorg = origin + ( vect * - 1 * offset );
return bullettrace( destorg, targetorg, 0, level.painter_player );
}
plot_circle( origin, radius, angles, color, circleres, contourdepth )
{
if ( !isdefined( color ) )
color = ( 0, 1, 0 );
if ( !isdefined( circleres ) )
circleres = 16;
hemires = circleres / 2;
circleinc = 360 / circleres;
circleres++ ;
plotpoints = [];
rad = 0;
plotpoints = [];
rad = 0.000;
for ( i = 0;i < circleres;i++ )
{
baseorg = origin + ( anglestoup( ( angles + ( 0, 0, rad ) ) ) * radius );
point = contour_point( baseorg, angles, level.spam_model_radius );
if ( point[ "fraction" ] != 1 )
plotpoints[ plotpoints.size ] = point[ "position" ];
rad += circleinc;
}
plot_points( plotpoints, color[ 0 ], color[ 1 ], color[ 2 ] );
plotpoints = [];
}
spam_model_erase( trace )
{
traceorg = trace[ "position" ];
keepmodels = [];
deletemodels = [];
for ( i = 0;i < level.spamed_models.size;i++ )
{
if ( distance( level.spamed_models[ i ].orgorg, traceorg ) > level.spam_model_radius )
keepmodels[ keepmodels.size ] = level.spamed_models[ i ];
else
deletemodels[ deletemodels.size ] = level.spamed_models[ i ];
}
level.spamed_models = keepmodels;
for ( i = 0;i < deletemodels.size;i++ )
deletemodels[ i ] delete();
}
dump_models()
{
/#
if ( ! level.spamed_models.size )
return;
fileprint_launcher_start_file();
fileprint_map_start();
for ( i = 0;i < level.spamed_models.size;i++ )
{
origin = fileprint_radiant_vec( level.spamed_models[ i ].origin );// convert these vectors to mapfile keypair format
angles = fileprint_radiant_vec( level.spamed_models[ i ].angles );
fileprint_map_entity_start();
if( isdefined ( level.spamed_models[ i ].modelusesprefab ) && level.spamed_models[ i ].modelusesprefab )
{
fileprint_map_keypairprint( "classname", "misc_prefab" );
fileprint_map_keypairprint( "model", "prefabs/misc_models/" + level.spamed_models[ i ].model + ".map" );
}
else
{
fileprint_map_keypairprint( "classname", "misc_model" );
fileprint_map_keypairprint( "model", level.spamed_models[ i ].model );
}
fileprint_map_keypairprint( "origin", origin );
fileprint_map_keypairprint( "angles", angles );
fileprint_map_keypairprint( "spammed_model", level.spam_model_current_group );
fileprint_map_entity_end();
}
map_path = level.script+"_modeldump.map";
if( !fileprint_launcher_end_file( "/map_source/"+map_path,false ) )
return;
launcher_write_clipboard( map_path );
array_thread( level.spamed_models, ::deleteme );
level.spamed_models = [];
#/
}
draw_axis( org, angles )
{
range = 32;
forward = range * anglestoforward( angles );
right = range * anglestoright( angles );
up = range * anglestoup( angles );
line( org, org + forward, ( 1, 0, 0 ), 1 );
line( org, org + up, ( 0, 1, 0 ), 1 );
line( org, org + right, ( 0, 0, 1 ), 1 );
}
_newhudelem()
{
if ( !isdefined( level.scripted_elems ) )
level.scripted_elems = [];
elem = newhudelem();
level.scripted_elems[ level.scripted_elems.size ] = elem;
return elem;
}
_settext( text )
{
self.realtext = text;
self settext( "_" );
self thread _clearalltextafterhudelem();
sizeofelems = 0;
foreach ( elem in level.scripted_elems )
{
if ( isdefined( elem.realtext ) )
{
sizeofelems += elem.realtext.size;
elem settext( elem.realtext );
}
}
println( "SIze of elems: " + sizeofelems );
}
controler_hud_add( identifier, inc, initial_text, initial_description_text, initial_value )
{
startx = 520;
if ( is_mp() )
startx = 630;
starty = 120;
space = 18;
basealpha = .8;
denradoffset = 20;
descriptionscale = 1.4;
if ( !isdefined( initial_text ) )
initial_text = "";
if ( !isdefined( level.hud_controler ) || !isdefined( level.hud_controler[ identifier ] ) )
{
level.hud_controler[ identifier ] = _newhudelem();
description = _newhudelem();
}
else
description = level.hud_controler[ identifier ].description;
level.hud_controler[ identifier ].location = 0;
level.hud_controler[ identifier ].alignX = "right";
level.hud_controler[ identifier ].alignY = "middle";
level.hud_controler[ identifier ].foreground = 1;
level.hud_controler[ identifier ].fontscale = 1.5;
level.hud_controler[ identifier ].sort = 20;
level.hud_controler[ identifier ].alpha = basealpha;
level.hud_controler[ identifier ].x = startx + denradoffset;
level.hud_controler[ identifier ].y = starty + ( inc * space );
level.hud_controler[ identifier ] _settext( initial_text );
level.hud_controler[ identifier ].base_button_text = initial_text;
description.location = 0;
description.alignX = "left";
description.alignY = "middle";
description.foreground = 1;
description.fontscale = descriptionscale;
description.sort = 20;
description.alpha = basealpha;
description.x = startx + denradoffset;
description.y = starty + ( inc * space );
if ( isdefined( initial_value ) )
description setvalue( initial_value );
if ( isdefined( initial_description_text ) )
description _settext( initial_description_text );
level.hud_controler[ identifier ].description = description;
}
controler_hud_update_text( hudid, text )
{
if ( is_mp() )
{
level.hud_controler[ hudid ] _settext( level.hud_controler[ hudid ].base_button_text + text );
level.hud_controler[ hudid ].description _settext( "" );
}
else
level.hud_controler[ hudid ].description _settext( text );
}
controler_hud_update_button( hudid, text )
{
level.hud_controler[ hudid ] _settext( text );
}
_clearalltextafterhudelem()
{
if ( level._clearalltextafterhudelem )
return;
level._clearalltextafterhudelem = true;
self clearalltextafterhudelem();
wait .05;
level._clearalltextafterhudelem = false;
}
is_mp()
{
return issubstr( level.script, "mp_" );
}