#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; } } }