private void OnEstablishCall(string handle, string positionJson) { if (!Int32.TryParse(handle, out int serverId)) { return; } if (VoiceManager._voiceClients.TryGetValue(serverId, out VoiceClient client)) { if (client.DistanceCulled) { client.LastPosition = Newtonsoft.Json.JsonConvert.DeserializeObject <CitizenFX.Core.Vector3>(positionJson); client.SendPlayerStateUpdate(this); } CitizenFX.Core.Vector3 playerPosition = Game.PlayerPed.Position; CitizenFX.Core.Vector3 remotePlayerPosition = client.LastPosition; int signalDistortion = API.GetZoneScumminess(API.GetZoneAtCoords(playerPosition.X, playerPosition.Y, playerPosition.Z)); signalDistortion += API.GetZoneScumminess(API.GetZoneAtCoords(remotePlayerPosition.X, remotePlayerPosition.Y, remotePlayerPosition.Z)); this.ExecuteCommand( new PluginCommand( Command.PhoneCommunicationUpdate, VoiceManager.ServerUniqueIdentifier, new PhoneCommunication( client.TeamSpeakName, signalDistortion ) ) ); } }
private async Task ATMTick() { if (this.InAnim || Game.Player.Character.IsInVehicle()) { return; } var atm = this.atms .Select(a => new { atm = a, distance = new Vector3(a.Position.X, a.Position.Y, a.Position.Z).DistanceToSquared(Game.Player.Character.Position) }) .Where(a => a.distance < 5.0F) // Nearby .Select(a => new { a.atm, prop = new Prop(API.GetClosestObjectOfType(a.atm.Position.X, a.atm.Position.Y, a.atm.Position.Z, 1, (uint)a.atm.Hash, false, false, false)), a.distance }) .Where(p => p.prop.Model.IsValid) .Where(a => Vector3.Dot(a.prop.ForwardVector, Vector3.Normalize(a.prop.Position - Game.Player.Character.Position)).IsBetween(0f, 1.0f)) // In front of .OrderBy(a => a.distance) .Select(a => new Tuple <BankATM, Prop>(a.atm, a.prop)) .FirstOrDefault(); if (atm == null) { return; } new Text("Press Z to use ATM", new PointF(50, Screen.Height - 50), 0.4f, Color.FromArgb(255, 255, 255), Font.ChaletLondon, Alignment.Left, false, true).Draw(); if (!this.interactKey.IsJustPressed()) { return; } var atmModel = atm.Item2; var ts = new TaskSequence(); ts.AddTask.LookAt(atmModel); var moveToPos = atmModel.Position.ToVector3().InFrontOf(atmModel.Heading + 180f, 0.5f); ts.AddTask.SlideTo(moveToPos.ToCitVector3(), atmModel.Heading); ts.AddTask.ClearLookAt(); ts.Close(); await Game.Player.Character.RunTaskSequence(ts); API.SetScenarioTypeEnabled("PROP_HUMAN_ATM", true); API.ResetScenarioTypesEnabled(); API.TaskStartScenarioInPlace(Game.PlayerPed.Handle, "PROP_HUMAN_ATM", 0, true); this.InAnim = true; // Camera var atmCameraPos = atmModel.Position.ToVector3().ToPosition().TranslateDir(atmModel.Heading - 50f, 1.5f); this.Camera = World.CreateCamera( new Vector3(atmCameraPos.X, atmCameraPos.Y, atmCameraPos.Z) + (Vector3.UnitZ * 1.8f), GameplayCamera.Rotation, 50 ); this.Camera.PointAt(new Vector3(atmModel.Position.X, atmModel.Position.Y, atmModel.Position.Z) + Vector3.UnitZ * 1f); World.RenderingCamera.InterpTo(this.Camera, 1000, true, true); API.RenderScriptCams(true, true, 1000, true, false); }
/// <summary> /// Used for <see cref="Command.PlayerStateUpdate"/> /// </summary> /// <param name="name"></param> /// <param name="position"></param> /// <param name="voiceRange"></param> /// <param name="isAlive"></param> /// <param name="distanceCulled"></param> /// <param name="muffleIntensity"></param> public PlayerState(string name, CitizenFX.Core.Vector3 position, float voiceRange, bool isAlive, bool distanceCulled = false, int?muffleIntensity = null) { this.Name = name; this.Position = new Vector3(position.X, position.Y, position.Z); this.VoiceRange = voiceRange; this.IsAlive = isAlive; this.DistanceCulled = distanceCulled; if (muffleIntensity.HasValue) { this.Muffle = new MuffleEffect(muffleIntensity.Value); } }
/// <summary> /// 新增一条传送命令使用记录 /// </summary> /// <param name="playerIdentifier"></param> /// <param name="commandName"></param> /// <param name="position"></param> /// <param name="heading"></param> /// <param name="creatorIdentifier"></param> /// <param name="usedTime"></param> /// <returns></returns> public async Task AddNewRecordAsync( string playerIdentifier, string commandName, Vector3 position, float heading, string creatorIdentifier, DateTime usedTime) { using (var db = RecordDbFactory.Open()) { await db.SaveAsync(new RecordTable.PlayerTeleportPointRecord { PlayerIdentifier = playerIdentifier, CommandName = commandName, PositionX = position.X, PositionY = position.Y, PositionZ = position.Z, Heading = heading, CreatorIdentifier = creatorIdentifier, UsedTime = usedTime, }); } }
/// <summary> /// Used for <see cref="Command.PlayerStateUpdate"/> with volume override /// </summary> /// <param name="name"></param> /// <param name="position"></param> /// <param name="voiceRange"></param> /// <param name="isAlive"></param> /// <param name="volumeOverride">Overrides the volume (phone, radio and proximity) - from 0 (0%) to 1.6 (160%)</param> public PlayerState(string name, CitizenFX.Core.Vector3 position, float voiceRange, bool isAlive, float volumeOverride) { this.Name = name; this.Position = new Vector3(position.X, position.Y, position.Z); this.VoiceRange = voiceRange; this.IsAlive = isAlive; if (volumeOverride > 1.6f) { this.VolumeOverride = 1.6f; } else if (volumeOverride < 0f) { this.VolumeOverride = 0f; } else { this.VolumeOverride = volumeOverride; } }
public void Save(string commandName, Vector3 position, float heading, string playerIdentifier) { using (var db = DbFactory.Open()) { // Save if not exists Table.PlayerTeleportPoint if (!db.Exists <Table.PlayerTeleportPoint>(new { CommandName = playerIdentifier })) { db.Save(new Table.PlayerTeleportPoint { CommandName = commandName, PositionX = position.X, PositionY = position.Y, PositionZ = position.Z, Heading = heading, Creator = playerIdentifier, }); } // Otherwise, skip } }
private async Task OnStateUpdateTick() { if (VoiceManager.IsConnected && VoiceManager.IsIngame) { List <PlayerState> playerStates = new List <PlayerState>(); Ped playerPed = Game.PlayerPed; CitizenFX.Core.Vector3 playerPosition = playerPed.Position; int playerRoomId = API.GetRoomKeyFromEntity(playerPed.Handle); foreach (VoiceClient client in VoiceManager.VoiceClients) { Player nPlayer = client.Player; if (nPlayer == null) { if (client.DistanceCulled) { continue; } client.DistanceCulled = true; playerStates.Add( new PlayerState( client.TeamSpeakName, client.LastPosition, client.VoiceRange, client.IsAlive, client.DistanceCulled ) ); } else { if (client.DistanceCulled) { client.DistanceCulled = false; } Ped nPed = nPlayer.Character; client.LastPosition = nPed.Position; int nPlayerRoomId = API.GetRoomKeyFromEntity(nPed.Handle); playerStates.Add( new PlayerState( client.TeamSpeakName, client.LastPosition, client.VoiceRange, client.IsAlive, client.DistanceCulled, nPlayerRoomId != playerRoomId && !API.HasEntityClearLosToEntity(playerPed.Handle, nPed.Handle, 17) ) ); } } this.ExecuteCommand( new PluginCommand( Command.BulkUpdate, VoiceManager.ServerUniqueIdentifier, new BulkUpdate( playerStates, new PlayerState( playerPosition, API.GetGameplayCamRot(0).Z ) ) ) ); } await BaseScript.Delay(250); }
private async Task OnStateUpdateTick() { if (this.IsConnected && this.IsIngame) { List <PlayerState> playerStates = new List <PlayerState>(); Ped playerPed = Game.PlayerPed; CitizenFX.Core.Vector3 playerPosition = playerPed.Position; int playerRoomId = API.GetRoomKeyFromEntity(playerPed.Handle); Vehicle playerVehicle = playerPed.CurrentVehicle; bool hasPlayerVehicleOpening = playerVehicle == null || playerVehicle.HasOpening(); foreach (VoiceClient client in this.VoiceClients) { Player nPlayer = client.Player; if (nPlayer == null) { if (client.DistanceCulled) { continue; } client.DistanceCulled = true; playerStates.Add( new PlayerState( client.TeamSpeakName, client.LastPosition, client.VoiceRange, client.IsAlive, client.DistanceCulled ) ); } else { if (client.DistanceCulled) { client.DistanceCulled = false; } Ped nPed = nPlayer.Character; client.LastPosition = nPed.Position; int?muffleIntensity = null; int nPlayerRoomId = API.GetRoomKeyFromEntity(nPed.Handle); if (nPlayerRoomId != playerRoomId && !API.HasEntityClearLosToEntity(playerPed.Handle, nPed.Handle, 17)) { muffleIntensity = 10; } else { Vehicle nPlayerVehicle = nPed.CurrentVehicle; if (playerVehicle != nPlayerVehicle) { bool hasNPlayerVehicleOpening = nPlayerVehicle == null || nPlayerVehicle.HasOpening(); if (!hasPlayerVehicleOpening && !hasNPlayerVehicleOpening) { muffleIntensity = 10; } else if (!hasPlayerVehicleOpening || !hasNPlayerVehicleOpening) { muffleIntensity = 6; } } } playerStates.Add( new PlayerState( client.TeamSpeakName, client.LastPosition, client.VoiceRange, client.IsAlive, client.DistanceCulled, muffleIntensity ) ); } } this.ExecuteCommand( new PluginCommand( Command.BulkUpdate, this.ServerUniqueIdentifier, new BulkUpdate( playerStates, new SelfState( playerPosition, API.GetGameplayCamRot(0).Z ) ) ) ); } await BaseScript.Delay(250); }