543 lines
22 KiB
Plaintext
543 lines
22 KiB
Plaintext
#using scripts\codescripts\struct;
|
|
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\clientfield_shared;
|
|
#using scripts\shared\filter_shared;
|
|
#using scripts\shared\flag_shared;
|
|
#using scripts\shared\flagsys_shared;
|
|
#using scripts\shared\visionset_mgr_shared;
|
|
#using scripts\shared\util_shared;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#using scripts\shared\system_shared;
|
|
|
|
#namespace duplicate_render;
|
|
|
|
|
|
|
|
|
|
|
|
function autoexec __init__sytem__() { system::register("duplicate_render",&__init__,undefined,undefined); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function __init__()
|
|
{
|
|
if(!isdefined(level.drfilters))level.drfilters=[];
|
|
|
|
callback::on_spawned( &on_player_spawned );
|
|
callback::on_localclient_connect( &on_player_connect );
|
|
|
|
set_dr_filter_framebuffer( "none_fb", 0, undefined, undefined, 0, 1, 0 );
|
|
set_dr_filter_framebuffer_duplicate( "none_fbd", 0, undefined, undefined, 1, 0, 0 );
|
|
set_dr_filter_offscreen( "none_os", 0, undefined, undefined, 2, 0, 0 );
|
|
|
|
set_dr_filter_framebuffer( "enveh_fb", 8, "enemyvehicle_fb", undefined, 0, 4, 1 );
|
|
set_dr_filter_framebuffer( "frveh_fb", 8, "friendlyvehicle_fb", undefined, 0, 1, 1 );
|
|
|
|
set_dr_filter_offscreen( "retrv", 5, "retrievable", undefined, 2, "mc/hud_keyline_retrievable", 1 );
|
|
set_dr_filter_offscreen( "unplc", 7, "unplaceable", undefined, 2, "mc/hud_keyline_unplaceable", 1 );
|
|
set_dr_filter_offscreen( "eneqp", 8, "enemyequip", undefined, 2, "mc/hud_outline_rim", 1 );
|
|
set_dr_filter_offscreen( "enexp", 8, "enemyexplo", undefined, 2, "mc/hud_outline_rim", 1 );
|
|
set_dr_filter_offscreen( "enveh", 8, "enemyvehicle", undefined, 2, "mc/hud_outline_rim", 1 );
|
|
set_dr_filter_offscreen( "freqp", 8, "friendlyequip", undefined, 2, "mc/hud_keyline_friendlyequip", 1 );
|
|
set_dr_filter_offscreen( "frexp", 8, "friendlyexplo", undefined, 2, "mc/hud_keyline_friendlyequip", 1 );
|
|
set_dr_filter_offscreen( "frveh", 8, "friendlyvehicle", undefined, 2, "mc/hud_keyline_friendlyequip", 1 );
|
|
|
|
set_dr_filter_offscreen( "infrared", 9, "infrared_entity", undefined, 2, 2, 1 );
|
|
set_dr_filter_offscreen( "threat_detector_enemy", 10, "threat_detector_enemy", undefined, 2, "mc/hud_keyline_enemyequip", 1 );
|
|
|
|
set_dr_filter_offscreen( "hthacked", 5, "hacker_tool_hacked", undefined, 2, "mc/mtl_hacker_tool_hacked", 1 );
|
|
set_dr_filter_offscreen( "hthacking", 5, "hacker_tool_hacking", undefined, 2, "mc/mtl_hacker_tool_hacking", 1 );
|
|
set_dr_filter_offscreen( "htbreaching", 5, "hacker_tool_breaching", undefined, 2, "mc/mtl_hacker_tool_breaching", 1 );
|
|
|
|
set_dr_filter_offscreen( "bcarrier", 9, "ballcarrier", undefined, 2, "mc/hud_keyline_friendlyequip", 1 );
|
|
set_dr_filter_offscreen( "poption", 9, "passoption", undefined, 2, "mc/hud_keyline_friendlyequip", 1 );
|
|
|
|
set_dr_filter_offscreen( "prop_look_through", 9, "prop_look_through", undefined, 2, "mc/hud_keyline_friendlyequip", 1 );
|
|
set_dr_filter_offscreen( "prop_ally", 8, "prop_ally", undefined, 2, "mc/hud_keyline_friendlyequip", 1 );
|
|
set_dr_filter_offscreen( "prop_clone", 7, "prop_clone", undefined, 2, "mc/hud_keyline_ph_yellow", 1 );
|
|
|
|
level.friendlyContentOutlines = GetDvarInt( "friendlyContentOutlines", false );
|
|
}
|
|
|
|
function on_player_spawned( local_client_num )
|
|
{
|
|
self.currentdrfilter=[];
|
|
self change_dr_flags(local_client_num);
|
|
|
|
if( !level flagsys::get( "duplicaterender_registry_ready" ) )
|
|
{
|
|
{wait(.016);};//We need a frame once player is valid to set up the materials
|
|
level flagsys::set( "duplicaterender_registry_ready" );
|
|
}
|
|
}
|
|
|
|
function on_player_connect( localClientNum )
|
|
{
|
|
level wait_team_changed( localClientNum );
|
|
}
|
|
|
|
function wait_team_changed( localClientNum )
|
|
{
|
|
while( 1 )
|
|
{
|
|
level waittill( "team_changed" );
|
|
|
|
// the local player might not be valid yet and will cause the team detection functionality not to work
|
|
while ( !isdefined( GetLocalPlayer( localClientNum ) ) )
|
|
{
|
|
wait( .05 );
|
|
}
|
|
|
|
player = GetLocalPlayer( localClientNum );
|
|
player Codcaster_Keyline_Enable( false );
|
|
}
|
|
}
|
|
|
|
function set_dr_filter( filterset, name, priority, require_flags, refuse_flags, drtype1, drval1, drcull1, drtype2, drval2, drcull2, drtype3, drval3, drcull3 )
|
|
{
|
|
if(!isdefined(level.drfilters))level.drfilters=[];
|
|
if ( !IsDefined( level.drfilters[ filterset ] ) )
|
|
{
|
|
level.drfilters[filterset]=[];
|
|
}
|
|
if (!IsDefined(level.drfilters[filterset][name]))
|
|
{
|
|
level.drfilters[filterset][name] = spawnstruct();
|
|
}
|
|
filter = level.drfilters[filterset][name];
|
|
filter.name = name;
|
|
// set priority negative until the materials are registered. This will keep it from being used
|
|
filter.priority = -priority;
|
|
if (!IsDefined(require_flags))
|
|
filter.require = [];
|
|
else if ( IsArray(require_flags) )
|
|
filter.require = require_flags;
|
|
else
|
|
filter.require = StrTok( require_flags, "," );
|
|
if (!IsDefined(refuse_flags))
|
|
filter.refuse = [];
|
|
else if ( IsArray(refuse_flags) )
|
|
filter.refuse = refuse_flags;
|
|
else
|
|
filter.refuse = StrTok( refuse_flags, "," );
|
|
filter.types = [];
|
|
filter.values = [];
|
|
filter.culling = [];
|
|
if (IsDefined(drtype1))
|
|
{
|
|
idx = filter.types.size;
|
|
filter.types[idx]=drtype1;
|
|
filter.values[idx]=drval1;
|
|
filter.culling[idx]=drcull1;
|
|
}
|
|
if (IsDefined(drtype2))
|
|
{
|
|
idx = filter.types.size;
|
|
filter.types[idx]=drtype2;
|
|
filter.values[idx]=drval2;
|
|
filter.culling[idx]=drcull2;
|
|
}
|
|
if (IsDefined(drtype3))
|
|
{
|
|
idx = filter.types.size;
|
|
filter.types[idx]=drtype3;
|
|
filter.values[idx]=drval3;
|
|
filter.culling[idx]=drcull3;
|
|
}
|
|
|
|
thread register_filter_materials( filter );
|
|
}
|
|
|
|
function set_dr_filter_framebuffer( name, priority, require_flags, refuse_flags, drtype1, drval1, drcull1, drtype2, drval2, drcull2, drtype3, drval3, drcull3 )
|
|
{
|
|
set_dr_filter( "framebuffer", name, priority, require_flags, refuse_flags, drtype1, drval1, drcull1, drtype2, drval2, drcull2, drtype3, drval3, drcull3 );
|
|
}
|
|
|
|
function set_dr_filter_framebuffer_duplicate( name, priority, require_flags, refuse_flags, drtype1, drval1, drcull1, drtype2, drval2, drcull2, drtype3, drval3, drcull3 )
|
|
{
|
|
set_dr_filter( "framebuffer_duplicate", name, priority, require_flags, refuse_flags, drtype1, drval1, drcull1, drtype2, drval2, drcull2, drtype3, drval3, drcull3 );
|
|
}
|
|
|
|
function set_dr_filter_offscreen( name, priority, require_flags, refuse_flags, drtype1, drval1, drcull1, drtype2, drval2, drcull2, drtype3, drval3, drcull3 )
|
|
{
|
|
set_dr_filter( "offscreen", name, priority, require_flags, refuse_flags, drtype1, drval1, drcull1, drtype2, drval2, drcull2, drtype3, drval3, drcull3 );
|
|
}
|
|
|
|
function register_filter_materials( filter )
|
|
{
|
|
playerCount = undefined;
|
|
opts = filter.types.size;
|
|
for ( i=0; i<opts; i++ )
|
|
{
|
|
value = filter.values[i];
|
|
if ( IsString( value ) )
|
|
{
|
|
if ( !IsDefined(playerCount) )
|
|
{
|
|
while( !isDefined(level.localPlayers) && !isDefined(level.frontendClientConnected) )
|
|
{
|
|
{wait(.016);};
|
|
}
|
|
if( isDefined(level.frontendClientConnected) )
|
|
{
|
|
playerCount = 1;
|
|
}
|
|
else
|
|
{
|
|
util::waitforallclients();
|
|
playerCount = level.localPlayers.size;
|
|
}
|
|
}
|
|
if ( !IsDefined(filter::mapped_material_id( value ) ) )
|
|
{
|
|
for ( localClientNum = 0; localClientNum < playerCount; localClientNum++ )
|
|
{
|
|
filter::map_material_helper_by_localclientnum( localClientNum, value );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// make it usable
|
|
filter.priority = abs( filter.priority );
|
|
}
|
|
|
|
function update_dr_flag( localClientNum, toset, setto=true )
|
|
{
|
|
if ( set_dr_flag( toset, setto ) )
|
|
{
|
|
update_dr_filters(localClientNum);
|
|
}
|
|
}
|
|
|
|
|
|
function set_dr_flag_not_array( toset, setto=true )
|
|
{
|
|
if ( !IsDefined( self.flag ) || !IsDefined( self.flag[toset] ) )
|
|
{
|
|
self flag::init(toset);
|
|
}
|
|
|
|
if ( setto == self.flag[toset] )
|
|
{
|
|
return false;
|
|
}
|
|
if ( ( isdefined( setto ) && setto ) )
|
|
{
|
|
self flag::set(toset);
|
|
}
|
|
else
|
|
{
|
|
self flag::clear(toset);
|
|
}
|
|
return true;
|
|
}
|
|
function set_dr_flag( toset, setto=true )
|
|
{
|
|
Assert( IsDefined(setto) );
|
|
|
|
if ( IsArray(toset))
|
|
{
|
|
foreach( ts in toset )
|
|
{
|
|
set_dr_flag( ts, setto );
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ( !IsDefined( self.flag ) || !IsDefined( self.flag[toset] ) )
|
|
{
|
|
self flag::init(toset);
|
|
}
|
|
|
|
if ( setto == self.flag[toset] )
|
|
{
|
|
return false;
|
|
}
|
|
if ( ( isdefined( setto ) && setto ) )
|
|
{
|
|
self flag::set(toset);
|
|
}
|
|
else
|
|
{
|
|
self flag::clear(toset);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function clear_dr_flag( toclear )
|
|
{
|
|
set_dr_flag( toclear, false );
|
|
}
|
|
|
|
function change_dr_flags( localClientNum, toset, toclear )
|
|
{
|
|
if ( IsDefined(toset) )
|
|
{
|
|
if( IsString( toset ) )
|
|
{
|
|
toset = StrTok( toset, "," );
|
|
}
|
|
self set_dr_flag(toset);
|
|
}
|
|
if ( IsDefined(toclear) )
|
|
{
|
|
if( IsString( toclear ) )
|
|
{
|
|
toclear = StrTok( toclear, "," );
|
|
}
|
|
self clear_dr_flag(toclear);
|
|
}
|
|
|
|
update_dr_filters(localClientNum);
|
|
}
|
|
|
|
function _update_dr_filters(localClientNum)
|
|
{
|
|
self notify("update_dr_filters");
|
|
self endon("update_dr_filters");
|
|
self endon("entityshutdown");
|
|
|
|
waittillframeend;
|
|
|
|
foreach( key, filterset in level.drfilters )
|
|
{
|
|
filter = self find_dr_filter(filterset);
|
|
if ( isdefined(filter) && (!isdefined(self.currentdrfilter) || !( self.currentdrfilter[key] === filter.name ) ) )
|
|
{
|
|
self apply_filter( localClientNum, filter, key );
|
|
}
|
|
}
|
|
}
|
|
|
|
function update_dr_filters(localClientNum)
|
|
{
|
|
self thread _update_dr_filters(localClientNum);
|
|
}
|
|
|
|
function find_dr_filter( filterset = level.drfilters["framebuffer"] )
|
|
{
|
|
best = undefined;
|
|
foreach( filter in filterset )
|
|
{
|
|
if ( self can_use_filter( filter ) )
|
|
{
|
|
if (!IsDefined(best) || filter.priority > best.priority)
|
|
{
|
|
best = filter;
|
|
}
|
|
}
|
|
}
|
|
return best;
|
|
}
|
|
|
|
function can_use_filter( filter )
|
|
{
|
|
for ( i = 0; i < filter.require.size; i++ )
|
|
{
|
|
if ( !self flagsys::get( filter.require[i] ))
|
|
return false;
|
|
}
|
|
for ( i = 0; i < filter.refuse.size; i++ )
|
|
{
|
|
if ( self flagsys::get( filter.refuse[i] ))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function apply_filter( localClientNum, filter, filterset = "framebuffer" )
|
|
{
|
|
if ( IsDefined( level.postGame ) && level.postGame && !( isdefined( level.showedTopThreePlayers ) && level.showedTopThreePlayers ) )
|
|
{
|
|
player = GetLocalPlayer( localClientNum );
|
|
if ( !(player GetInKillcam( localClientNum )) )
|
|
return;
|
|
}
|
|
|
|
/#
|
|
if ( GetDvarInt( "scr_debug_duplicaterender" ) )
|
|
{
|
|
name = "[entity]";
|
|
if ( self IsPlayer() )
|
|
{
|
|
if (IsDefined(self.name))
|
|
name = "player "+self.name;
|
|
}
|
|
else if (IsDefined(self.model))
|
|
{
|
|
name += "." + self.model;
|
|
}
|
|
|
|
msg = "DUPLICATERENDER: Applying filter "+filter.name+" to "+name+" for set "+filterset;
|
|
Println(msg);
|
|
//IPrintlnBold(msg);
|
|
}
|
|
#/
|
|
if (!IsDefined(self.currentdrfilter))
|
|
self.currentdrfilter=[];
|
|
self.currentdrfilter[filterset]=filter.name;
|
|
opts = filter.types.size;
|
|
for ( i=0; i<opts; i++ )
|
|
{
|
|
type = filter.types[i];
|
|
value = filter.values[i];
|
|
culling = filter.culling[i];
|
|
material = undefined;
|
|
if ( IsString( value ) )
|
|
{
|
|
material = filter::mapped_material_id( value );
|
|
value = 3;
|
|
if (IsDefined(value) && IsDefined(material))
|
|
{
|
|
// right now all duplicate rendering is see through walls
|
|
self addduplicaterenderoption( type, value, material, culling );
|
|
}
|
|
else
|
|
{
|
|
self.currentdrfilter[filterset]=undefined;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
self addduplicaterenderoption( type, value, -1, culling );
|
|
}
|
|
}
|
|
|
|
if( SessionModeIsMultiplayerGame() ) // Save client script vars for other game modes
|
|
{
|
|
self thread disable_all_filters_on_game_ended();
|
|
}
|
|
}
|
|
|
|
function disable_all_filters_on_game_ended()
|
|
{
|
|
self endon("entityshutdown");
|
|
self notify("disable_all_filters_on_game_ended");
|
|
self endon("disable_all_filters_on_game_ended");
|
|
|
|
level waittill( "post_game" );
|
|
|
|
self disableduplicaterendering();
|
|
}
|
|
|
|
|
|
//===================================================================================
|
|
|
|
function set_item_retrievable( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "retrievable", on_off );
|
|
}
|
|
|
|
function set_item_unplaceable( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "unplaceable", on_off );
|
|
}
|
|
|
|
function set_item_enemy_equipment( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "enemyequip", on_off );
|
|
}
|
|
|
|
function set_item_friendly_equipment( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "friendlyequip", on_off );
|
|
}
|
|
|
|
function set_item_enemy_explosive( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "enemyexplo", on_off );
|
|
}
|
|
|
|
function set_item_friendly_explosive( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "friendlyexplo", on_off );
|
|
}
|
|
|
|
function set_item_enemy_vehicle( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "enemyvehicle", on_off );
|
|
}
|
|
|
|
function set_item_friendly_vehicle( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "friendlyvehicle", on_off );
|
|
}
|
|
|
|
function set_entity_thermal( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "infrared_entity", on_off );
|
|
}
|
|
|
|
function set_player_threat_detected( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "threat_detector_enemy", on_off );
|
|
}
|
|
|
|
|
|
function set_hacker_tool_hacked( localClientNum,on_off )
|
|
{
|
|
self update_dr_flag( localClientNum, "hacker_tool_hacked", on_off );
|
|
}
|
|
|
|
|
|
function set_hacker_tool_hacking( localClientNum, on_off )
|
|
{
|
|
self update_dr_flag( localClientNum,"hacker_tool_hacking", on_off );
|
|
}
|
|
|
|
|
|
function set_hacker_tool_breaching( localClientNum, on_off )
|
|
{
|
|
flags_changed = self set_dr_flag( "hacker_tool_breaching", on_off );
|
|
if ( on_off )
|
|
{
|
|
flags_changed = self set_dr_flag( "enemyvehicle", false ) || flags_changed;
|
|
}
|
|
else
|
|
{
|
|
if ( ( isdefined( self.isEnemyVehicle ) && self.isEnemyVehicle ) )
|
|
{
|
|
flags_changed = self set_dr_flag( "enemyvehicle", true ) || flags_changed;
|
|
}
|
|
}
|
|
|
|
if ( flags_changed )
|
|
{
|
|
update_dr_filters(localClientNum);
|
|
}
|
|
}
|
|
|
|
function show_friendly_outlines( local_client_num )
|
|
{
|
|
if ( !( isdefined( level.friendlyContentOutlines ) && level.friendlyContentOutlines ) )
|
|
return false;
|
|
|
|
if ( IsShoutcaster( local_client_num ) )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|