public static void ShowMessage(string str, BaseEntity pPlayer) { if (pPlayer?.IsNetClient() != true) { return; } var message = NetMessage.Begin(MsgDest.One, "HudText", pPlayer.Edict()); message.WriteString(str); message.End(); }
public static void ScreenShake(Vector center, float amplitude, float frequency, float duration, float radius) { var shake = new ScreenShake { duration = TempEntity.FixedUnsigned16(duration, 1 << 12), // 4.12 fixed frequency = TempEntity.FixedUnsigned16(frequency, 1 << 8) // 8.8 fixed }; for (var i = 1; i <= Engine.Globals.MaxClients; ++i) { BaseEntity pPlayer = PlayerByIndex(i); if (pPlayer == null || (pPlayer.Flags & EntFlags.OnGround) == 0) // Don't shake if not onground { continue; } float localAmplitude = 0; if (radius <= 0) { localAmplitude = amplitude; } else { var delta = center - pPlayer.Origin; var distance = delta.Length(); // Had to get rid of this falloff - it didn't work well if (distance < radius) { localAmplitude = amplitude;//radius - distance; } } if (localAmplitude != 0) { shake.amplitude = TempEntity.FixedUnsigned16(localAmplitude, 1 << 12); // 4.12 fixed var message = NetMessage.Begin(MsgDest.One, "ScreenShake", pPlayer.Edict()); // use the magic #1 for "one client" message.WriteShort(shake.amplitude); // shake amount message.WriteShort(shake.duration); // shake lasts this long message.WriteShort(shake.frequency); // shake noise frequency message.End(); } } }
private float CheckSoundState() { // get pointer to client if visible; FindClientInPVS will // cycle through visible clients on consecutive calls. var player = Engine.Server.FindClientInPVS(Edict())?.TryGetEntity <BasePlayer>(); if (player == null) { return(SlowInterval); // no player in pvs of sound entity, slow it down } // check to see if this is the sound entity that is // currently affecting this player if (player.LastSound && (player.LastSound.Entity == this)) { // this is the entity currently affecting player, check // for validity if (player.SoundRoomType != 0 && player.SoundRange != 0) { // we're looking at a valid sound entity affecting // player, make sure it's still valid, update range if (FEnvSoundInRange(this, player, out var flRange)) { player.SoundRange = flRange; return(FastInterval); } else { // current sound entity affecting player is no longer valid, // flag this state by clearing room_type and range. // NOTE: we do not actually change the player's room_type // NOTE: until we have a new valid room_type to change it to. player.SoundRange = 0; player.SoundRoomType = 0; return(SlowInterval); } } else { // entity is affecting player but is out of range, // wait passively for another entity to usurp it... return(SlowInterval); } } // if we got this far, we're looking at an entity that is contending // for current player sound. the closest entity to player wins. { if (FEnvSoundInRange(this, player, out var flRange)) { if (flRange < player.SoundRange || player.SoundRange == 0) { // new entity is closer to player, so it wins. player.LastSound.Set(this); player.SoundRoomType = RoomType; player.SoundRange = flRange; // send room_type command to player's server. // this should be a rare event - once per change of room_type // only! //CLIENT_COMMAND(pentPlayer, "room_type %f", m_flRoomtype); var message = NetMessage.Begin(MsgDest.One, ServerCommand.RoomType, player.Edict()); // use the magic #1 for "one client" message.WriteShort((short)RoomType); // sequence number message.End(); // crank up nextthink rate for new active sound entity // by falling through to think_fast... } // player is not closer to the contending sound entity, // just fall through to think_fast. this effectively // cranks up the think_rate of entities near the player. } } // player is in pvs of sound entity, but either not visible or // not in range. do nothing, fall through to think_fast... return(FastInterval); }
/// <summary> /// Force it to update the client masks /// </summary> private void UpdateMasks() { UpdateInterval = 0; var allTalk = ServerAllTalk.Float != 0; for (var iClient = 0; iClient < MaxPlayers; ++iClient) { var pEnt = PlayerUtils.PlayerByIndex(iClient + 1); if (pEnt == null || !pEnt.IsPlayer()) { continue; } var data = Players[iClient]; // Request the state of their "VModEnable" cvar. if (data.WantEnable) { var message = NetMessage.Begin(MsgDest.One, "ReqState", pEnt.Edict()); message.End(); } var pPlayer = (BasePlayer)pEnt; var gameRulesMask = new BitVector32(); if (data.EnableVoice) { // Build a mask of who they can hear based on the game rules. for (var iOtherClient = 0; iOtherClient < MaxPlayers; ++iOtherClient) { var pOtherPlayer = (BasePlayer)PlayerUtils.PlayerByIndex(iOtherClient + 1); if (pOtherPlayer != null && (allTalk || Helper.CanPlayerHearPlayer(pPlayer, pOtherPlayer))) { gameRulesMask[iOtherClient] = true; } } } // If this is different from what the client has, send an update. if (!Utils.BitVectorsEqual(ref gameRulesMask, ref data.SentGameRulesMasks) || !Utils.BitVectorsEqual(ref data.BanMasks, ref data.SentBanMasks)) { data.SentGameRulesMasks = gameRulesMask; data.SentBanMasks = data.BanMasks; var message = NetMessage.Begin(MsgDest.One, "VoiceMask", pPlayer.Edict()); for (var dw = 0; dw < VOICE_MAX_PLAYERS_DW; ++dw) { message.WriteLong(gameRulesMask.Data); message.WriteLong(data.BanMasks.Data); } message.End(); } // Tell the engine. for (int iOtherClient = 0; iOtherClient < MaxPlayers; ++iOtherClient) { var canHear = gameRulesMask[iOtherClient] && !data.BanMasks[iOtherClient]; Engine.Server.SetClientListening(iClient + 1, iOtherClient + 1, canHear); } } }