1100 lines
30 KiB
Plaintext
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_" );
|
|
} |