public void onUpdate() { if (DateTime.Now.Subtract(LastSecond).TotalMilliseconds > 1000) { LastSecond = DateTime.Now; if (RaceStartCountdown > 0) { RaceStartCountdown--; if (RaceStartCountdown == 3) { API.triggerClientEventForAll("startRaceCountdown"); } else if (RaceStartCountdown == 0) { IsRaceOngoing = true; lock (Opponents) foreach (var opponent in Opponents) { API.setEntityPositionFrozen(opponent.Client, opponent.Vehicle, false); opponent.HasStarted = true; } RaceTimer = DateTime.Now; } } } if (!IsRaceOngoing) { return; } CalculatePositions(); UpdateScoreboard(); lock (Opponents) { lock (CurrentRaceCheckpoints) foreach (var opponent in Opponents) { if (opponent.HasFinished || !opponent.HasStarted) { continue; } if (CurrentRaceCheckpoints.Any() && opponent.Client.position.IsInRangeOf(CurrentRaceCheckpoints[opponent.CheckpointsPassed], 10f)) { opponent.CheckpointsPassed++; if (opponent.CheckpointsPassed >= CurrentRaceCheckpoints.Count) { if (Opponents.All(op => !op.HasFinished)) { API.exported.mapcycler.endRoundEx(60000); } opponent.HasFinished = true; var pos = Opponents.Count(o => o.HasFinished); var suffix = pos.ToString().EndsWith("1") ? "st" : pos.ToString().EndsWith("2") ? "nd" : pos.ToString().EndsWith("3") ? "rd" : "th"; var timeElapsed = DateTime.Now.Subtract(RaceTimer); API.sendChatMessageToAll("~h~" + opponent.Client.name + "~h~ has finished " + pos + suffix + " (" + timeElapsed.ToString("mm\\:ss\\.fff") + ")"); opponent.TimeFinished = timeElapsed.ToString("mm\\:ss\\.fff"); API.triggerClientEvent(opponent.Client, "finishRace"); continue; } Vector3 nextPos = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; Vector3 nextDir = null; if (CurrentRaceCheckpoints.Count > opponent.CheckpointsPassed + 1) { var nextCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]; var curCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; if (nextCp != null && curCp != null) { Vector3 dir = nextCp.Subtract(curCp); dir.Normalize(); nextDir = dir; } } if (nextDir == null) { API.triggerClientEvent(opponent.Client, "setNextCheckpoint", nextPos, true, true); } else { API.triggerClientEvent(opponent.Client, "setNextCheckpoint", nextPos, false, true, nextDir, CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]); } } } } }
public override void OnTick() { if (!IsRaceOngoing) { return; } lock (Opponents) { lock (CurrentRaceCheckpoints) foreach (var opponent in Opponents) { if (opponent.HasFinished || !opponent.HasStarted) { continue; } if (CurrentRaceCheckpoints.Any() && opponent.Client.LastKnownPosition.IsInRangeOf(CurrentRaceCheckpoints[opponent.CheckpointsPassed], 10f)) { opponent.CheckpointsPassed++; if (opponent.CheckpointsPassed >= CurrentRaceCheckpoints.Count) { if (Opponents.All(op => !op.HasFinished)) { var t = new Thread((ThreadStart) delegate { Thread.Sleep(10000); Program.ServerInstance.SendChatMessageToAll("Vote for next map will start in 60 seconds!"); Thread.Sleep(30000); Program.ServerInstance.SendChatMessageToAll("Vote for next map will start in 30 seconds!"); Thread.Sleep(30000); if (!IsVoteActive()) { StartVote(); } }); t.Start(); } opponent.HasFinished = true; var pos = Opponents.Count(o => o.HasFinished); var suffix = pos.ToString().EndsWith("1") ? "st" : pos.ToString().EndsWith("2") ? "nd" : pos.ToString().EndsWith("3") ? "rd" : "th"; Program.ServerInstance.SendNotificationToAll("~h~" + opponent.Client.DisplayName + "~h~ has finished " + pos + suffix); Program.ServerInstance.SendNativeCallToPlayer(opponent.Client, 0x45FF974EEE1C8734, opponent.Blip, 0); Program.ServerInstance.RecallNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER"); Program.ServerInstance.RecallNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER_DIR"); continue; } Program.ServerInstance.SendNativeCallToPlayer(opponent.Client, 0xAE2AF67E9D9AF65D, opponent.Blip, CurrentRaceCheckpoints[opponent.CheckpointsPassed].X, CurrentRaceCheckpoints[opponent.CheckpointsPassed].Y, CurrentRaceCheckpoints[opponent.CheckpointsPassed].Z); Program.ServerInstance.SetNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER", 0x28477EC23D892089, 1, CurrentRaceCheckpoints[opponent.CheckpointsPassed], new Vector3(), new Vector3(), new Vector3() { X = 10f, Y = 10f, Z = 2f }, 241, 247, 57, 180, false, false, 2, false, false, false, false); if (CurrentRaceCheckpoints.Count > opponent.CheckpointsPassed + 1) { var nextCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]; var curCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; if (nextCp != null && curCp != null) { Vector3 dir = nextCp.Subtract(curCp); dir = dir.Normalize(); Program.ServerInstance.SetNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER_DIR", 0x28477EC23D892089, 20, curCp.Subtract(new Vector3() { X = 0f, Y = 0f, Z = -2f }), dir, new Vector3() { X = 60f, Y = 0f, Z = 0f }, new Vector3() { X = 4f, Y = 4f, Z = 4f }, 87, 193, 250, 200, false, false, 2, false, false, false, false); } } else { Program.ServerInstance.RecallNativeCallOnTickForPlayer(opponent.Client, "RACE_CHECKPOINT_MARKER_DIR"); } } } } }
public void onUpdate(object sender, EventArgs e) { if (!IsRaceOngoing) { return; } lock (Opponents) { lock (CurrentRaceCheckpoints) foreach (var opponent in Opponents) { if (opponent.HasFinished || !opponent.HasStarted) { continue; } if (CurrentRaceCheckpoints.Any() && opponent.Client.Position.IsInRangeOf(CurrentRaceCheckpoints[opponent.CheckpointsPassed], 10f)) { opponent.CheckpointsPassed++; if (opponent.CheckpointsPassed >= CurrentRaceCheckpoints.Count) { if (Opponents.All(op => !op.HasFinished)) { API.startThread((ThreadStart) delegate { API.sleep(10000); API.sendChatMessageToAll("Vote for next map will start in 60 seconds!"); API.sleep(30000); API.sendChatMessageToAll("Vote for next map will start in 30 seconds!"); API.sleep(30000); if (!IsVoteActive()) { StartVote(); } }); } opponent.HasFinished = true; var pos = Opponents.Count(o => o.HasFinished); var suffix = pos.ToString().EndsWith("1") ? "st" : pos.ToString().EndsWith("2") ? "nd" : pos.ToString().EndsWith("3") ? "rd" : "th"; API.sendChatMessageToAll("~h~" + opponent.Client.Name + "~h~ has finished " + pos + suffix); API.triggerClientEvent(opponent.Client, "finishRace"); continue; } Vector3 nextPos = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; Vector3 nextDir = null; if (CurrentRaceCheckpoints.Count > opponent.CheckpointsPassed + 1) { var nextCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]; var curCp = CurrentRaceCheckpoints[opponent.CheckpointsPassed]; if (nextCp != null && curCp != null) { Vector3 dir = nextCp.Subtract(curCp); dir = dir.Normalize(); nextDir = dir; } } if (nextDir == null) { API.triggerClientEvent(opponent.Client, "setNextCheckpoint", nextPos, true, true); } else { API.triggerClientEvent(opponent.Client, "setNextCheckpoint", nextPos, false, true, nextDir, CurrentRaceCheckpoints[opponent.CheckpointsPassed + 1]); } } } } }