557 lines
14 KiB
Plaintext
557 lines
14 KiB
Plaintext
#include maps\mp\_utility;
|
|
#include maps\mp\gametypes\_hud_util;
|
|
#include common_scripts\utility;
|
|
#include maps\mp\agents\_agent_utility;
|
|
//#include maps\mp\bots\_bots_strategy;
|
|
#include maps\mp\agents\_scriptedAgents;
|
|
#include maps\mp\_vl_camera;
|
|
#include maps\mp\_vl_firingrange;
|
|
#include maps\mp\_vl_selfiebooth;
|
|
|
|
PARTYSTATUS_EMPTY = 0;
|
|
PARTYSTATUS_ZOMBIE = 1;
|
|
PARTYSTATUS_ANONYMOUS = 2;
|
|
PARTYSTATUS_JOINED = 3;
|
|
PARTYSTATUS_COMMITTED = 4;
|
|
PARTYSTATUS_PRESENT = 5;
|
|
|
|
|
|
vlprint( str )
|
|
{
|
|
print( "VLOBBY["+GetTime()+"]: " + str );
|
|
}
|
|
|
|
vlprintln( str )
|
|
{
|
|
println( "VLOBBY["+GetTime()+"]: " + str );
|
|
}
|
|
|
|
vl_init()
|
|
{
|
|
level.vl_onSpawnPlayer = ::onSpawnPlayer;
|
|
vl_main();
|
|
}
|
|
|
|
|
|
vl_main()
|
|
{
|
|
SetDvar("r_dof_physical_enable", 1);
|
|
SetDvar("r_dof_physical_bokehEnable", 1);
|
|
SetDvar("r_adaptiveSubdiv", 0);
|
|
SetDvar("r_eyePupil", 0.15);
|
|
SetDvar("r_uiblurdstmode", 3);
|
|
SetDvar("r_blurdstgaussianblurradius", 1.5);
|
|
ResetEntPlayerXuidForEmblems();
|
|
|
|
//level.PartyMemberClassChange_cb = ::PartyMemberClassChange;
|
|
level.PartyMembers_cb = ::party_members;
|
|
level.vlavatars = [];
|
|
level.xuid2ownerId = [];
|
|
level.vl_focus = 0;
|
|
level.avatarInfo = [];
|
|
maxAvatars = 18;
|
|
if ( level.ps3 || level.xenon )
|
|
maxAvatars = 12;
|
|
for ( i=0; i<maxAvatars; i++ )
|
|
{
|
|
level.avatarInfo[i] = SpawnStruct();
|
|
level.avatarInfo[i].timeToDelete = 0;
|
|
level.avatarInfo[i].xuid = "";
|
|
}
|
|
level.maxAvatars = maxAvatars;
|
|
|
|
thread monitor_member_class_changes();
|
|
thread monitor_member_timeouts();
|
|
|
|
SetDvar( "virtuallobbymembers", 0 ); // ensure this is cleared whenever we enter the vl
|
|
/#
|
|
SetDvarIfUninitialized( "scr_vl_addfakemembers", "0" );
|
|
SetDvarIfUninitialized( "scr_vl_debugfly", "0" );
|
|
SetDvarIfUninitialized( "scr_vl_printcostume", "0" );
|
|
level.vl_fakemembers = 0;
|
|
#/
|
|
level.num_lobby_idles = 4;
|
|
init_firingrange();
|
|
init_selfiebooth();
|
|
//lighying values
|
|
//level.sunpitch_damage = 0;
|
|
//waitframe();
|
|
//level.sunpitch = GetEnt("sun_pitch_swap", "targetname");
|
|
//level.sunpitch_origin = level.sunpitch getOrigin();
|
|
}
|
|
|
|
init_avatars()
|
|
{
|
|
EXTRA_AVATARS = 1; // for cao
|
|
maxAvatars = level.maxAvatars + EXTRA_AVATARS;
|
|
level.vlavatarpool = [];
|
|
for ( i=0; i<maxAvatars; i++ )
|
|
{
|
|
avatar = getFreeAgent();
|
|
level.vlavatarpool[i] = avatar;
|
|
avatar SpawnAgent( (0,0,0), (0,0,0) );
|
|
avatar set_agent_values( "spectator", "none" );
|
|
avatar maps\mp\agents\_agent_common::set_agent_health( 100 );
|
|
|
|
avatar BotClearScriptEnemy();
|
|
avatar BotClearScriptGoal();
|
|
avatar bot_disable_tactical_goals();
|
|
avatar BotSetFlag("disable_movement", 1);
|
|
avatar BotSetFlag("disable_rotation",1); // they shouldn't try and rotate
|
|
avatar.isfree = true;
|
|
}
|
|
}
|
|
|
|
alloc_avatar()
|
|
{
|
|
if ( !IsDefined(level.vlavatarpool) )
|
|
init_avatars();
|
|
|
|
foreach ( avatar in level.vlavatarpool )
|
|
{
|
|
if ( avatar.isfree )
|
|
{
|
|
avatar.isfree = false;
|
|
return avatar;
|
|
}
|
|
}
|
|
assertmsg( "Unable to alloc_avatar" );
|
|
}
|
|
|
|
free_avatar( avatar )
|
|
{
|
|
assert( !avatar.isfree );
|
|
avatar notify( "free_avatar" );
|
|
avatar.isfree = true;
|
|
}
|
|
|
|
onSpawnPlayer()
|
|
{
|
|
level.agent_funcs["player"]["on_killed"] = ::on_agent_player_killed;
|
|
self thread vlobby_player();
|
|
level.playerStatus[0] = PARTYSTATUS_JOINED;
|
|
self thread monitor_member_focus_change();
|
|
self thread monitor_create_an_operator(0);
|
|
self thread monitor_create_a_class(0);
|
|
self thread monitor_clans();
|
|
thread monitor_move_btn_fr_vl( self );
|
|
self disable_player_controls();
|
|
// TODO needs to replinish grenade after player uses one in firing range. It's weird after you use one and hold it too long nothing happens but it eats your grenade.
|
|
self SetDemiGod(true); /// needed to skip mod_suicide death call from holding a grenade too long. Grenade suicide called in code
|
|
self SetMLGSpectator( 0 ); // needed to catch a bug where we don't properly clear this when the host of a game ends the match while in MLG Broadcaster
|
|
}
|
|
|
|
on_agent_player_killed(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
|
|
{
|
|
// don't do anything
|
|
}
|
|
|
|
|
|
player_sticks_in_lefty_config()
|
|
{
|
|
if ( self is_player_gamepad_enabled() )
|
|
{
|
|
sticksLayoutName = self GetLocalPlayerProfileData( "gpadSticksConfig" );
|
|
return IsDefined( sticksLayoutName ) && ( ( sticksLayoutName == "thumbstick_southpaw" ) || ( sticksLayoutName == "thumbstick_legacy" ) );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
player_setup_lefty_angle( avatar )
|
|
{
|
|
if ( !IsDefined( avatar.fakeAngle ) )
|
|
{
|
|
if ( IsDefined( avatar.storedRightStickY ) )
|
|
{
|
|
avatar.fakeAngle = avatar.storedRightStickY;
|
|
}
|
|
else
|
|
{
|
|
avatar.fakeAngle = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
player_get_right_stick_y( avatar )
|
|
{
|
|
if ( self player_sticks_in_lefty_config() )
|
|
{
|
|
player_setup_lefty_angle( avatar );
|
|
return avatar.fakeAngle;
|
|
}
|
|
else
|
|
{
|
|
rightStick = self GetUnNormalizedCameraMovement();
|
|
return rightStick[1];
|
|
}
|
|
}
|
|
|
|
player_update_right_stick_y( avatar )
|
|
{
|
|
|
|
rightStickY = 0;
|
|
if ( self player_sticks_in_lefty_config() )
|
|
{
|
|
player_setup_lefty_angle( avatar );
|
|
|
|
rightStick = self GetNormalizedMovement();
|
|
rotSpeed = -12;
|
|
rotDelta = rightStick[1] * rotSpeed;
|
|
avatar.fakeAngle = AngleClamp( avatar.fakeAngle + rotDelta );
|
|
rightStickY = avatar.fakeAngle;
|
|
}
|
|
else
|
|
{
|
|
rightStick = self GetUnNormalizedCameraMovement();
|
|
rightStickY = rightStick[1];
|
|
|
|
if ( IsDefined( avatar.fakeAngle ) )
|
|
{
|
|
avatar.fakeAngle = undefined;
|
|
}
|
|
}
|
|
|
|
return rightStickY;
|
|
}
|
|
|
|
prep_for_controls( avatar, set_avatar_angles )
|
|
{
|
|
avatar.storedRightStickY = self player_get_right_stick_y( avatar ); // storing where right stick is so we can track changes
|
|
avatar.rotation_total = 0; // setting difference in right stick change
|
|
avatar.storedangleY = avatar.angles[1];
|
|
avatar.mouseRot = 0;
|
|
avatar.positivewrap = 0;
|
|
avatar.negativewrap = 0;
|
|
avatar.addtobaseangle = 0;
|
|
set_avatar_angles = (0, set_avatar_angles[1], 0); // forcing X and Z. Avatar should only spin
|
|
if(IsDefined(set_avatar_angles))
|
|
{
|
|
if(IsAgent(avatar))
|
|
{
|
|
avatar HackAgentAngles(set_avatar_angles);
|
|
}
|
|
else
|
|
avatar.angles = set_avatar_angles;
|
|
}
|
|
}
|
|
|
|
avatar_scheduled_for_removal( ownerid )
|
|
{
|
|
assert( level.avatarInfo[ownerid].timeToDelete == 0 ); // this should never get set now that we never truly free avatars
|
|
return level.avatarInfo[ownerid].timeToDelete > 0;
|
|
}
|
|
|
|
schedule_remove_avatar( ownerid, dly )
|
|
{
|
|
remove_avatar( ownerid );
|
|
}
|
|
|
|
all_avatars_scheduled_for_delete()
|
|
{
|
|
if (level.vlavatars.size == 0)
|
|
return false;
|
|
foreach ( ownerId, avatarInfo in level.avatarInfo )
|
|
{
|
|
if ( !IsDefined( level.vlavatars[ownerId] ) )
|
|
continue;
|
|
if ( avatarInfo.timeToDelete == 0 )
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
reuse_avatar( xuid )
|
|
{
|
|
assert( level.vlavatars.size == 1 );
|
|
avatar = undefined;
|
|
foreach ( xuidtmp, idx in level.xuid2ownerId )
|
|
{
|
|
avatar = level.vlavatars[idx];
|
|
level.vlavatars[idx] = undefined;
|
|
setEntPlayerXuidForEmblem( avatar, xuidtmp, true ); // release this xuid
|
|
level.xuid2ownerId[xuidtmp] = undefined;
|
|
}
|
|
|
|
level.xuid2ownerId[xuid] = 0;
|
|
level.avatarInfo[0].timeToDelete = 0;
|
|
level.avatarInfo[0].xuid = xuid;
|
|
if ( isDefined(avatar) )
|
|
{
|
|
setEntPlayerXuidForEmblem( avatar, xuid ); // associate with new xuid
|
|
level.vlavatars[0] = avatar;
|
|
}
|
|
}
|
|
|
|
add_avatar( xuid )
|
|
{
|
|
// first find an unused ownerId
|
|
ownerId = -1;
|
|
oId = -1;
|
|
while (oId == ownerId)
|
|
{
|
|
ownerId++;
|
|
foreach ( oId in level.xuid2ownerId )
|
|
{
|
|
if (oId == ownerId)
|
|
break;
|
|
}
|
|
}
|
|
vlprint( "Adding new xuid "+xuid+" with ownerId="+ownerId+"\n");
|
|
level.xuid2ownerId[xuid] = ownerId;
|
|
level.avatarInfo[ownerId].xuid = xuid;
|
|
level.avatarInfo[ownerId].timeToDelete = 0;
|
|
return ownerId;
|
|
}
|
|
|
|
avatar_after_spawn( ownerId )
|
|
{
|
|
if ( isdefined(level.needToPresent) )
|
|
{
|
|
thread SetVirtualLobbyPresentable();
|
|
}
|
|
}
|
|
|
|
update_avatars()
|
|
{
|
|
anyRemoved = false;
|
|
foreach ( ownerId, avatarInfo in level.avatarInfo )
|
|
{
|
|
if ( ( avatarInfo.timeToDelete > 0 ) && ( GetTime() > avatarInfo.timeToDelete ) )
|
|
{
|
|
vlprint( "update_avatars removing ownerId"+ownerId + "\n");
|
|
remove_avatar( ownerId );
|
|
anyRemoved = true;
|
|
}
|
|
}
|
|
if ( anyRemoved )
|
|
wait 0.1; // to deal with an issue where we can't spawn an agent we just deleted.
|
|
}
|
|
|
|
hide_non_owner_avatars()
|
|
{
|
|
foreach ( idx, avatar in level.vlavatars )
|
|
{
|
|
if ( idx == 0 )
|
|
continue;
|
|
hide_avatar( avatar );
|
|
}
|
|
if(level.camParams.mode != "prelobby") // camera cut if we are not in pre lobby
|
|
{
|
|
level.camParams.camera.cut = true;
|
|
}
|
|
|
|
level.vl_focus = 0;
|
|
level.old_vl_focus = level.vl_focus;
|
|
|
|
}
|
|
|
|
show_non_owner_avatars()
|
|
{
|
|
foreach ( idx, avatar in level.vlavatars )
|
|
{
|
|
if ( idx == 0 )
|
|
continue;
|
|
show_avatar( avatar );
|
|
}
|
|
}
|
|
|
|
RightStickRotateAvatar(targetAvatar, ratio)
|
|
{
|
|
rightStickY = self player_update_right_stick_y( targetAvatar );
|
|
rightStickDiffY = AngleClamp(rightStickY - targetAvatar.storedRightStickY);
|
|
|
|
mouseRot = GetDvarFloat( "ui_mouse_char_rot", 0 );
|
|
if ( mouseRot != 0 )
|
|
{
|
|
targetAvatar.mouseRot = AngleClamp(targetAvatar.mouseRot + mouseRot);
|
|
SetDynamicDvar( "ui_mouse_char_rot", 0 ); // rotation is "consumed", reset it, UI will continue adding each frame
|
|
}
|
|
|
|
AddtoAngle = GetModifiedRotationAngle(targetAvatar, rightStickDiffY, ratio);
|
|
AddtoAngle *= -1; // reversing rotation
|
|
AvatarYAngle = AngleClamp(targetAvatar.storedangleY + AddtoAngle + targetAvatar.mouseRot);
|
|
avatar_angles = ( 0, AvatarYAngle, 0 ); // forcing X and Z. Avatar should only spin
|
|
// targetAvatar SetPlayerAngles(avatar_angles);
|
|
if(IsAgent(targetAvatar))
|
|
{
|
|
// targetAvatar ScrAgentSetOrientMode("face angle abs", avatar_angles, avatar_angles); // doesn't work anymore on agents?
|
|
targetAvatar SetPlayerAngles(avatar_angles);
|
|
}
|
|
else
|
|
{
|
|
// for CAC weapons or other non agents
|
|
targetAvatar.angles = avatar_angles;
|
|
}
|
|
}
|
|
PlayerHasTouchedStick(targetAvatar)
|
|
{
|
|
rightStickY = self player_get_right_stick_y( targetAvatar );
|
|
rightStickDiffY = AngleClamp(rightStickY - targetAvatar.storedRightStickY);
|
|
if(self.HasTouchedStick == false)
|
|
{
|
|
if(abs(rightStickDiffY) >= 1 )
|
|
{
|
|
targetAvatar.storedangleY = targetAvatar.angles[1];
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// targetAvatar.storedangleY = targetAvatar.angles;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
disable_player_controls()
|
|
{
|
|
self notify("kill_enable_weapons");
|
|
// self freezeControlsWrapper(true);
|
|
|
|
self AllowFire(false);
|
|
// self DisableWeapons();
|
|
// self DisableOffhandWeapons();
|
|
// self DisableWeaponSwitch();
|
|
|
|
}
|
|
|
|
enable_player_controls()
|
|
{
|
|
self endon("enter_lobby");
|
|
self endon("kill_enable_weapons");
|
|
|
|
// self freezeControlsWrapper(false);
|
|
|
|
// wait(2);
|
|
|
|
val = GetDvarInt( "virtualLobbyInFiringRange", 0 );
|
|
if ( ( val == 1 ) && level.in_firingrange == true)
|
|
{
|
|
// self freezeControlsWrapper(false);
|
|
self AllowFire(true);
|
|
// self EnableWeapons();
|
|
// self EnableOffhandWeapons();
|
|
// self EnableWeaponSwitch();
|
|
}
|
|
|
|
// self playerAllowHighJump(false);
|
|
// self playerAllowHighJumpDrop(false);
|
|
// self playerAllowBoostJump(false);
|
|
// self playerAllowPowerSlide(false);
|
|
// self playerAllowDodge(false);
|
|
|
|
}
|
|
|
|
enter_vlobby( player )
|
|
{
|
|
deactivate_targets();
|
|
//SetDvar( "virtualLobbyInFiringRange", "0" );
|
|
|
|
camera = player.camera;
|
|
player SetOrigin(camera.origin);
|
|
player PlayerLinkTo( camera, "tag_player" );
|
|
player CameraLinkTo( camera, "tag_player" );
|
|
player SetClientDVar( "cg_fovscale", "0.6153" );
|
|
|
|
//player VisionSetNakedForPlayer("mp_virtual_lobby", 0);
|
|
player VisionSetNakedForPlayer("mp_virtual_lobby_cac", 0);
|
|
//player LightSetForPlayer("mp_vl_create_a_class");
|
|
|
|
if(isdefined(level.vlavatars) && isdefined(level.old_vl_focus) && isdefined(level.vlavatars[level.old_vl_focus]))
|
|
{
|
|
player prep_for_controls(level.vlavatars[level.old_vl_focus], level.vlavatars[level.old_vl_focus].angles);
|
|
}
|
|
|
|
level.in_firingrange = false;
|
|
player AllowFire(false);
|
|
updateSessionState("spectator");
|
|
}
|
|
|
|
monitor_move_btn_fr_vl( player )
|
|
{
|
|
while (true)
|
|
{
|
|
if ( isDefined( level.in_firingrange ) )
|
|
{
|
|
val = GetDvarInt( "virtualLobbyInFiringRange", 0 );
|
|
if ( ( val == 1 ) && !level.in_firingrange )
|
|
{
|
|
// attempting to wait until weapon model is actually loaded
|
|
class_num = getClassIndex( "lobby"+(player.currentSelectedClass+1) );
|
|
classLoc = cac_getCustomClassLoc();
|
|
loadout = player.loadouts[classLoc][class_num];
|
|
loadoutPrimary = loadout["primary"];
|
|
loadoutSecondary = loadout["secondary"];
|
|
|
|
if(isdefined(level.vlavatars) && isdefined(level.old_vl_focus) && isdefined(level.vlavatars[level.old_vl_focus]))
|
|
{
|
|
player prep_for_controls(level.vlavatars[level.old_vl_focus], level.vlavatars[level.old_vl_focus].angles);
|
|
}
|
|
|
|
WeaponNames = [];
|
|
{
|
|
if(isdefined(loadoutPrimary) && loadoutPrimary !="specialty_null")
|
|
{
|
|
WeaponNames[WeaponNames.size] = maps\mp\gametypes\_class::buildWeaponName( loadoutPrimary, loadout["primaryAttachment1"], loadout["primaryAttachment2"], loadout["primaryAttachment3"], 0, 0 );
|
|
}
|
|
if(isdefined(loadoutSecondary) && loadoutSecondary !="specialty_null")
|
|
{
|
|
WeaponNames[WeaponNames.size] = maps\mp\gametypes\_class::buildWeaponName( loadoutSecondary, loadout["secondaryAttachment1"], loadout["secondaryAttachment2"], loadout["secondaryAttachment3"], 0, 0 );
|
|
}
|
|
}
|
|
|
|
while(WeaponNames.size > 0)
|
|
{
|
|
HasLoadededWeapons = player loadweapons(WeaponNames);
|
|
if(HasLoadededWeapons == true)
|
|
{
|
|
break;
|
|
}
|
|
wait(0.05);
|
|
}
|
|
|
|
player ShowViewModel();
|
|
|
|
enter_firingrange( player );
|
|
player clientclearsoundsubmix( "mp_no_foley", 1 );
|
|
SetDvar("r_dof_physical_bokehEnable", 0);
|
|
SetDvar("r_dof_physical_enable", 0);
|
|
SetDvar("r_uiblurdstmode", 0);
|
|
SetDvar("r_blurdstgaussianblurradius", 1);
|
|
}
|
|
else if ( ( val == 0 ) && level.in_firingrange )
|
|
{
|
|
player HideViewModel();
|
|
player FiringRangeCleanup();
|
|
player disable_player_controls();
|
|
|
|
player notify("enter_lobby");
|
|
enter_vlobby( player );
|
|
player clientaddsoundsubmix( "mp_no_foley", 1 );
|
|
SetDvar("r_dof_physical_enable", 1);
|
|
SetDvar("r_dof_physical_bokehEnable", 1);
|
|
SetDvar("r_uiblurdstmode", 3);
|
|
SetDvar("r_blurdstgaussianblurradius", 1.5);
|
|
}
|
|
}
|
|
|
|
wait 0.05;
|
|
}
|
|
}
|
|
|
|
FiringRangeCleanup()
|
|
{
|
|
player = self;
|
|
player GrenadeCleanup(); // clean up grenades left in firing range
|
|
player thread RiotShieldCleanup();
|
|
weaponListOffhand = player GetWeaponsListOffhands();
|
|
foreach( weapon in weaponListOffhand )
|
|
{
|
|
player maps\mp\gametypes\_class::takeOffhand( weapon ); // remove any exo abilities
|
|
}
|
|
}
|
|
|
|
|