boiii-scripts/shared/player_shared.gsc
2023-04-13 17:30:38 +02:00

441 lines
19 KiB
Plaintext

#using scripts\shared\clientfield_shared;
#using scripts\shared\flag_shared;
#using scripts\shared\util_shared;
#using scripts\shared\system_shared;
#using scripts\shared\callbacks_shared;
#using scripts\shared\flag_shared;
#using scripts\shared\flagsys_shared;
#namespace player;
function autoexec __init__sytem__() { system::register("player",&__init__,undefined,undefined); }
function __init__()
{
callback::on_spawned( &on_player_spawned );
clientfield::register( "world", "gameplay_started", 4000, 1, "int" );
}
function on_player_spawned()
{
// No need of this callback in frontend
mapname = GetDvarString( "mapname" );
if( mapname === "core_frontend" )
{
return;
}
if( SessionModeIsZombiesGame() || SessionModeIsCampaignGame() )
{
snappedOrigin = self get_snapped_spot_origin( self.origin );
if( !(self flagsys::get( "shared_igc" )) )
{
self SetOrigin( snappedOrigin );
}
}
isMultiplayer = !SessionModeIsZombiesGame() && !SessionModeIsCampaignGame();
if ( !isMultiplayer || ( isdefined( level._enableLastValidPosition ) && level._enableLastValidPosition ) )
{
self thread last_valid_position();
}
}
// cached navmesh position for player
function last_valid_position()
{
self endon( "disconnect" );
self notify( "stop_last_valid_position" );
self endon( "stop_last_valid_position" );
// try to at least get a valid position
while ( !isdefined( self.last_valid_position ) )
{
self.last_valid_position = GetClosestPointOnNavMesh( self.origin, 2048, 0 );
wait 0.1;
}
while ( 1 )
{
// if haven't moved very far, don't bother
if ( Distance2DSquared( self.origin, self.last_valid_position ) < ( (15) * (15) ) &&
( (self.origin[2] - self.last_valid_position[2]) * (self.origin[2] - self.last_valid_position[2]) ) < ( (16) * (16) ) )
{
wait 0.1;
continue;
}
// position is already good
if ( IsDefined( level.last_valid_position_override ) && self [[ level.last_valid_position_override ]]() )
{
wait 0.1;
continue;
}
else if ( IsPointOnNavMesh( self.origin, self ) )
{
self.last_valid_position = self.origin;
}
else if( !IsPointOnNavmesh( self.origin, self )
&& IsPointOnNavMesh( self.last_valid_position, self )
&& ( Distance2DSquared( self.origin, self.last_valid_position ) < ( (64 / 2) * (64 / 2) ) )
)
{
// dont update the self.last_valid_position
wait 0.1;
continue;
}
else
{
position = GetClosestPointOnNavMesh( self.origin, 100, 15 );
if ( isdefined( position ) )
{
self.last_valid_position = position;
}
}
wait( 0.1 );
}
}
function take_weapons()
{
if ( !( isdefined( self.gun_removed ) && self.gun_removed ) )
{
self.gun_removed = true;
self._weapons = [];
// Update current weapon only if a valid weapon is returned from code.
// If the player is in the proccess of switching weapons, it will be "none"
// and we don't want to save that as the player's weapon.
if(!isdefined(self._current_weapon))self._current_weapon=level.weaponNone;
w_current = self GetCurrentWeapon();
if ( w_current != level.weaponNone )
{
self._current_weapon = w_current;
}
a_weapon_list = self GetWeaponsList();
// If we still don't have a valid weapon saved off for current weapon, use the first weapon
// in the player's weapon list
if ( self._current_weapon == level.weaponNone )
{
if ( isdefined( a_weapon_list[ 0 ] ) )
{
self._current_weapon = a_weapon_list[ 0 ];
}
}
foreach ( weapon in a_weapon_list )
{
if(( isdefined( weapon.dniweapon ) && weapon.dniweapon )) //DT#93790
continue;
if ( !isdefined( self._weapons ) ) self._weapons = []; else if ( !IsArray( self._weapons ) ) self._weapons = array( self._weapons ); self._weapons[self._weapons.size]=get_weapondata( weapon );;
self TakeWeapon( weapon );
}
}
}
function generate_weapon_data()
{
self._generated_weapons = [];
if(!isdefined(self._generated_current_weapon))self._generated_current_weapon=level.weaponNone;
if( ( isdefined( self.gun_removed ) && self.gun_removed ) && IsDefined( self._weapons ) )
{
self._generated_weapons = ArrayCopy( self._weapons );
self._generated_current_weapon = self._current_weapon;
}
else
{
w_current = self GetCurrentWeapon();
if ( w_current != level.weaponNone )
{
self._generated_current_weapon = w_current;
}
a_weapon_list = self GetWeaponsList();
// If we still don't have a valid weapon saved off for current weapon, use the first weapon
// in the player's weapon list
if ( self._generated_current_weapon == level.weaponNone )
{
if ( isdefined( a_weapon_list[ 0 ] ) )
{
self._generated_current_weapon = a_weapon_list[ 0 ];
}
}
foreach ( weapon in a_weapon_list )
{
if(( isdefined( weapon.dniweapon ) && weapon.dniweapon )) //DT#93790
continue;
if ( !isdefined( self._generated_weapons ) ) self._generated_weapons = []; else if ( !IsArray( self._generated_weapons ) ) self._generated_weapons = array( self._generated_weapons ); self._generated_weapons[self._generated_weapons.size]=get_weapondata( weapon );;
}
}
}
function give_back_weapons( b_immediate = false )
{
if ( isdefined( self._weapons ) )
{
foreach ( weapondata in self._weapons )
{
weapondata_give( weapondata );
}
if ( isdefined( self._current_weapon ) && ( self._current_weapon != level.weaponNone ) )
{
if ( b_immediate )
{
self SwitchToWeaponImmediate( self._current_weapon );
}
else
{
self SwitchToWeapon( self._current_weapon );
}
}
else if ( isdefined( self.primaryloadoutweapon ) && self HasWeapon( self.primaryloadoutweapon ) ) //If current weapon is not set, let's try to switch to primary
{
switch_to_primary_weapon( b_immediate );
}
}
self._weapons = undefined;
self.gun_removed = undefined;
}
function get_weapondata( weapon )
{
weapondata = [];
if ( !isdefined( weapon ) )
{
weapon = self GetCurrentWeapon();
}
weapondata[ "weapon" ] = weapon.name;
if ( weapon != level.weaponNone )
{
weapondata[ "clip" ] = self GetWeaponAmmoClip( weapon );
weapondata[ "stock" ] = self GetWeaponAmmoStock( weapon );
weapondata[ "fuel" ] = self GetWeaponAmmoFuel( weapon );
weapondata[ "heat" ] = self IsWeaponOverheating( 1, weapon );
weapondata[ "overheat" ] = self IsWeaponOverheating( 0, weapon );
weapondata[ "renderOptions" ] = self GetWeaponOptions( weapon );
weapondata[ "acvi" ] = self GetPlayerAttachmentCosmeticVariantIndexes( weapon );
if ( weapon.isRiotShield )
{
weapondata[ "health" ] = self.weaponHealth;
}
}
else
{
weapondata[ "clip" ] = 0;
weapondata[ "stock" ] = 0;
weapondata[ "fuel" ] = 0;
weapondata[ "heat" ] = 0;
weapondata[ "overheat" ] = 0;
}
if ( weapon.dualWieldWeapon != level.weaponNone )
{
weapondata[ "lh_clip" ] = self GetWeaponAmmoClip( weapon.dualWieldWeapon );
}
else
{
weapondata[ "lh_clip" ] = 0;
}
if ( weapon.altWeapon != level.weaponNone )
{
weapondata[ "alt_clip" ] = self GetWeaponAmmoClip( weapon.altWeapon );
weapondata[ "alt_stock" ] = self GetWeaponAmmoStock( weapon.altWeapon );
}
else
{
weapondata[ "alt_clip" ] = 0;
weapondata[ "alt_stock" ] = 0;
}
return weapondata;
}
function weapondata_give( weapondata )
{
weapon = util::get_weapon_by_name( weapondata[ "weapon" ] );
self GiveWeapon( weapon, weapondata[ "renderOptions" ], weapondata[ "acvi" ] );
if ( weapon != level.weaponNone )
{
self SetWeaponAmmoClip( weapon, weapondata[ "clip" ] );
self SetWeaponAmmoStock( weapon, weapondata[ "stock" ] );
if ( IsDefined( weapondata[ "fuel" ] ) )
{
self SetWeaponAmmoFuel( weapon, weapondata[ "fuel" ] );
}
if ( IsDefined( weapondata[ "heat" ] ) && IsDefined( weapondata[ "overheat" ] ) )
{
self SetWeaponOverheating( weapondata[ "overheat" ], weapondata[ "heat" ], weapon );
}
if ( weapon.isRiotShield && IsDefined( weapondata[ "health" ] ) )
{
self.weaponHealth = weapondata[ "health" ];
}
}
if ( weapon.dualWieldWeapon != level.weaponNone )
{
self SetWeaponAmmoClip( weapon.dualWieldWeapon, weapondata[ "lh_clip" ] );
}
if ( weapon.altWeapon != level.weaponNone )
{
self SetWeaponAmmoClip( weapon.altWeapon, weapondata[ "alt_clip" ] );
self SetWeaponAmmoStock( weapon.altWeapon, weapondata[ "alt_stock" ] );
}
}
function switch_to_primary_weapon( b_immediate = false )
{
if ( is_valid_weapon( self.primaryloadoutweapon ) )
{
if ( b_immediate )
{
self SwitchToWeaponImmediate( self.primaryloadoutweapon );
}
else
{
self SwitchToWeapon( self.primaryloadoutweapon );
}
}
}
function fill_current_clip() //self = player
{
w_current = self GetCurrentWeapon();
if ( w_current.isheroweapon ) //We don't want to give the player more hero ammo
{
w_current = self.primaryloadoutweapon; //Let's give them primary weapon ammo instead
}
if ( isdefined( w_current ) && self HasWeapon( w_current ) ) // with "copycat" ability, the player might not have their primary loadout weapon
{
self SetWeaponAmmoClip( w_current, w_current.clipsize );
}
}
function is_valid_weapon( weaponObject )
{
return ( isdefined( weaponObject ) && ( weaponObject != level.weaponNone ) );
}
function is_spawn_protected()
{
return ( GetTime() - (isdefined(self.spawntime)?self.spawntime:0) <= level.spawnProtectionTimeMS );
}
/@
"Name: simple_respawn()"
"Summary: Respawn a player at whatever the current best spawn point is using the gamemodes base spawn function. Most of the spawn logic is not included and this is mostly just a teleport using the spawn logic. The player entity is untouched, and no spawn callbacks are called."
"CallOn: player"
"Example: e_player player::simple_respawn();"
@/
function simple_respawn()
{
self [[ level.onSpawnPlayer ]]( false );
}
function get_snapped_spot_origin( spot_position )
{
snap_max_height = 100;
size = 15;
height = size * 2;
mins = (-1 * size, -1 * size, 0 );
maxs = ( size, size, height );
spot_position = (spot_position[0], spot_position[1], spot_position[2] + 5);
new_spot_position = ( spot_position[0], spot_position[1], spot_position[2] - snap_max_height);
trace = physicstrace( spot_position, new_spot_position, mins, maxs, self);
if ( trace["fraction"] < 1 )
{
return trace["position"];
}
return spot_position;
}
function allow_stance_change( b_allow = true )
{
if ( b_allow )
{
self AllowProne( true );
self AllowCrouch( true );
self AllowStand( true );
}
else
{
str_stance = self GetStance();
switch ( str_stance )
{
case "prone":
self AllowProne( true );
self AllowCrouch( false );
self AllowStand( false );
break;
case "crouch":
self AllowProne( false );
self AllowCrouch( true );
self AllowStand( false );
break;
case "stand":
self AllowProne( false );
self AllowCrouch( false );
self AllowStand( true );
break;
}
}
}