diff --git a/ReallifeGamemode.Client/CharCreator/main.ts b/ReallifeGamemode.Client/CharCreator/main.ts index 19ab25ac..5294d9db 100644 --- a/ReallifeGamemode.Client/CharCreator/main.ts +++ b/ReallifeGamemode.Client/CharCreator/main.ts @@ -237,10 +237,13 @@ export default function charCreator(globalData: IGlobalData) { saveItem.HighlightedBackColor = new Color(25, 118, 210); creatorMainMenu.AddItem(saveItem); - //let cancelItem = new UIMenuItem("Abbrechen", "Setzt alle \u00c4nderungen zur\u00fcck."); - //cancelItem.BackColor = new Color(213, 0, 0); - //cancelItem.HighlightedBackColor = new Color(229, 57, 53); - //creatorMainMenu.AddItem(cancelItem); + if (isSurgery) { + let cancelItem = new UIMenuItem("Abbrechen", "Bricht die Operation ab"); + cancelItem.BackColor = new Color(213, 0, 0); + cancelItem.HighlightedBackColor = new Color(229, 57, 53); + creatorMainMenu.AddItem(cancelItem); + } + creatorMainMenu.ListChange.on((item, listIndex) => { if (item === genderItem) { @@ -571,7 +574,7 @@ export default function charCreator(globalData: IGlobalData) { creatorCamera.pointAtCoord(creatorCoords.cameraLookAt.x, creatorCoords.cameraLookAt.y, creatorCoords.cameraLookAt.z); creatorCamera.setActive(true); } - + resetAppearanceMenu(); resetFeaturesMenu(); resetHairAndColorsMenu(); @@ -588,6 +591,7 @@ export default function charCreator(globalData: IGlobalData) { localPlayer.freezePosition(true); mp.game.cam.renderScriptCams(true, false, 0, true, false); applyCreatorOutfit(); + mp.events.callRemote("creator_GenderChange", 0); } }); @@ -611,5 +615,42 @@ export default function charCreator(globalData: IGlobalData) { globalData.InMenu = false; globalData.InMenu = false; if (isSurgery) isSurgery = false; + + } + + mp.events.add("render", () => { + if (mp.cameras.exists(creatorCamera)) disableInput(); + }); + + function disableInput() { + + //WASD + mp.game.controls.disableControlAction(0, 30, true); + mp.game.controls.disableControlAction(0, 31, true); + mp.game.controls.disableControlAction(0, 32, true); + mp.game.controls.disableControlAction(0, 33, true); + mp.game.controls.disableControlAction(0, 34, true); + mp.game.controls.disableControlAction(0, 35, true); + mp.game.controls.disableControlAction(0, 266, true); + mp.game.controls.disableControlAction(0, 267, true); + mp.game.controls.disableControlAction(0, 268, true); + mp.game.controls.disableControlAction(0, 269, true); + + //SPACE + mp.game.controls.disableControlAction(0, 22, true); + + //R + mp.game.controls.disableControlAction(0, 140, true); + mp.game.controls.disableControlAction(0, 263, true); + + //LMB + mp.game.controls.disableControlAction(0, 24, true); + mp.game.controls.disableControlAction(0, 257, true); + + //LEFT CTRL + mp.game.controls.disableControlAction(0, 36, true); + + //Q + mp.game.controls.disableControlAction(0, 44, true); } } \ No newline at end of file diff --git a/ReallifeGamemode.Client/Player/polygons.ts b/ReallifeGamemode.Client/Player/polygons.ts index ea468a4b..6c755cbf 100644 --- a/ReallifeGamemode.Client/Player/polygons.ts +++ b/ReallifeGamemode.Client/Player/polygons.ts @@ -56,18 +56,25 @@ const muellbaseVector1 = new mp.Vector3(521.6251, -2194.5068, 5.985945); const muellbaseVector2 = new mp.Vector3(454.88348, -2158.1938, 5.9788494); const muellbaseVector3 = new mp.Vector3(529.06635, -2088.4097, 8.303088); +const krankenhausVector1 = new mp.Vector3(-508.50705, -351.24368, 34); +//const krankenhausVector2 = new mp.Vector3(-437.00146, -357.10526, 32.735916 +const krankenhausVector2 = new mp.Vector3(-442.62323, -356.99185, 33); +const krankenhausVector3 = new mp.Vector3(-448.9346, -297.23972, 33.68); +const krankenhausVector4 = new mp.Vector3(-504.952, -315.21698, 35.04881); + const polygon_busbase = polygons.add([busbaseVector1, busbaseVector2, busbaseVector3, busbaseVector4], 15, false, [255, 155, 0, 255], 0); const polygon_stadthalle = polygons.add([stadthalleVector1, stadthalleVector2, stadthalleVector3, stadthalleVector4], 15, false, [255, 155, 0, 255], 0); const polygon_fahrschule = polygons.add([fahrschuleVector1, fahrschuleVector2, fahrschuleVector3, fahrschuleVector4, fahrschuleVector5], 15, false, [255, 155, 0, 255], 0); const polygon_pilotAnfaenger = polygons.add([pilotAnfaengerVector1, pilotAnfaengerVector2, pilotAnfaengerVector3, pilotAnfaengerVector4], 15, false, [255, 155, 0, 255], 0); const polygon_pilotProfi = polygons.add([pilotProfiVector1, pilotProfiVector2, pilotProfiVector3, pilotProfiVector4], 15, false, [255, 155, 0, 255], 0); const polygon_muellbase = polygons.add([muellbaseVector1, muellbaseVector2, muellbaseVector3], 15, false, [255, 155, 0, 255], 0); +const polygon_krankenhaus = polygons.add([krankenhausVector1, krankenhausVector2, krankenhausVector3, krankenhausVector4], 50, false, [255, 155, 0, 255], 0); const polygon_prison = polygons.add([prisonVector1, prisonVector2, prisonVector3, prisonVector4, prisonVector5, prisonVector6, prisonVector7, prisonVector8, prisonVector9, prisonVector10, prisonVector11, prisonVector12, prisonVector13, prisonVector14, prisonVector15, prisonVector16, prisonVector17, prisonVector18, prisonVector19, prisonVector20, prisonVector21, prisonVector22, prisonVector23, prisonVector24], 40, false, [255, 155, 0, 255], 0); -export let listNoDMZones = [polygon_busbase, polygon_stadthalle, polygon_fahrschule, polygon_pilotAnfaenger, polygon_pilotProfi, polygon_muellbase]; +export let listNoDMZones = [polygon_busbase, polygon_stadthalle, polygon_fahrschule, polygon_pilotAnfaenger, polygon_pilotProfi, polygon_muellbase, polygon_krankenhaus]; export let isInAnyNoDMPolygon; export default function polygonHandler() { diff --git a/ReallifeGamemode.Client/admin/spectate.ts b/ReallifeGamemode.Client/admin/spectate.ts index cf66bb43..532c54ad 100644 --- a/ReallifeGamemode.Client/admin/spectate.ts +++ b/ReallifeGamemode.Client/admin/spectate.ts @@ -1,12 +1,29 @@ -let cam: CameraMp = mp.cameras.new('spectateCam');; +let cam: CameraMp; + +let specPlayer: PlayerMp; + mp.events.add("SERVER:ADMIN_SPECTATE", (targetPlayer) => { - cam.attachTo(targetPlayer.handle, 10.0, 0.0, 10.0, true); - cam.setActive(true); + //cam.attachTo(targetPlayer.handle, 0, 1.0, 1.0, 1.0, 0, 0, 0, true, false, false, false, 0, false); + specPlayer = targetPlayer; + cam = mp.cameras.new('spectateCam'); + cam.attachTo(targetPlayer.handle, 0, -4, 1.5, true); + cam.pointAt(targetPlayer.handle, 0, 0, 0, true); + cam.setActive(true); + mp.game.cam.renderScriptCams(true, false, 0, true, false); + mp.players.local.attachTo(targetPlayer.handle, 0, 0, -4, 1, 0, 0, 0, true, false, false, false, 0, false); }); mp.events.add("SERVER:ADMIN_STOP_SPECTATE", () => { - if (cam.isActive() == true) { - cam.setActive(false); + if (mp.cameras.exists(cam)) { + cam.destroy(); + mp.game.cam.renderScriptCams(false, false, 0, true, false); + mp.players.local.detach(true, true); + } +}); + +mp.events.add("render", () => { + if (mp.cameras.exists(cam)) { + cam.setRot(0, 0, specPlayer.getRotation(0).z, 0); } }); \ No newline at end of file diff --git a/ReallifeGamemode.Client/dlcpacks/drafterintcept/dlc.rpf b/ReallifeGamemode.Client/dlcpacks/drafterintcept/dlc.rpf deleted file mode 100644 index 166831eb..00000000 --- a/ReallifeGamemode.Client/dlcpacks/drafterintcept/dlc.rpf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a4100176763845d0d863b7e4782dd8ba3e316a078084704c80eba2e565b1edc6 -size 106824192 diff --git a/ReallifeGamemode.Client/dlcpacks/lsfd/dlc.rpf b/ReallifeGamemode.Client/dlcpacks/lsfd/dlc.rpf deleted file mode 100644 index 1a90dcee..00000000 --- a/ReallifeGamemode.Client/dlcpacks/lsfd/dlc.rpf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e350a25ff37d9d2d13a628558e96cb8fe91c5e5ad210d5f2697d1c981b7976f9 -size 110010880 diff --git a/ReallifeGamemode.Client/dlcpacks/polcoquette/dlc.rpf b/ReallifeGamemode.Client/dlcpacks/polcoquette/dlc.rpf deleted file mode 100644 index cb5e800d..00000000 --- a/ReallifeGamemode.Client/dlcpacks/polcoquette/dlc.rpf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fc9132404cdc1d20830d4684697bf82f3738bc4345cc6d1189cf2b63f0b15de8 -size 2962432 diff --git a/ReallifeGamemode.Client/dlcpacks/sheriffcoqm/dlc.rpf b/ReallifeGamemode.Client/dlcpacks/sheriffcoqm/dlc.rpf deleted file mode 100644 index 801bb4bb..00000000 --- a/ReallifeGamemode.Client/dlcpacks/sheriffcoqm/dlc.rpf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7a66cd9ec235636bd61c7cf90c0602be8bf97c303fe2fa6703b49c42352aeb7c -size 18657792 diff --git a/ReallifeGamemode.Client/dlcpacks/vtvicechee/dlc.rpf b/ReallifeGamemode.Client/dlcpacks/vtvicechee/dlc.rpf deleted file mode 100644 index df9b9593..00000000 --- a/ReallifeGamemode.Client/dlcpacks/vtvicechee/dlc.rpf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a7eb55afdb7bc022b5308388902e886291bff38a688b38e0dfcb48d492232a1a -size 5581312 diff --git a/ReallifeGamemode.Client/util/waypoint.ts b/ReallifeGamemode.Client/util/waypoint.ts index f7293d13..b8c5b06c 100644 --- a/ReallifeGamemode.Client/util/waypoint.ts +++ b/ReallifeGamemode.Client/util/waypoint.ts @@ -1,5 +1,23 @@ export default function waypointUtil() { - mp.events.add("SERVER:Util_setWaypoint", (x, y) => { + + let x_saved: number; + let y_saved: number; + let z_saved: number; + let waypointSet: boolean; + + mp.events.add("SERVER:Util_setWaypoint", (x, y, z) => { mp.game.ui.setNewWaypoint(x, y); }); + + mp.events.add("playerCreateWaypoint", (position) => { + x_saved = position.x; + y_saved = position.y; + z_saved = position.z; + waypointSet = true; + mp.events.callRemote("SERVER:waypointToDriver", position.x, position.y); + }); + + mp.events.add("playerRemoveWaypoint", () => { + waypointSet = false; + }); } \ No newline at end of file diff --git a/ReallifeGamemode.Database/Add-Migration.ps1 b/ReallifeGamemode.Database/Add-Migration.ps1 index 43d4d65d..6bac6232 100644 --- a/ReallifeGamemode.Database/Add-Migration.ps1 +++ b/ReallifeGamemode.Database/Add-Migration.ps1 @@ -7,4 +7,6 @@ $root = $PSScriptRoot dotnet tool update dotnet-ef --global -dotnet ef migrations add $MigrationName --project "$root\ReallifeGamemode.Database.csproj" --startup-project "$root\..\ReallifeGamemode.Server\ReallifeGamemode.Server.csproj" --configuration "Database" \ No newline at end of file +dotnet ef migrations add $MigrationName --project "$root\ReallifeGamemode.Database.csproj" --startup-project "$root\..\ReallifeGamemode.Server\ReallifeGamemode.Server.csproj" --configuration "Database" + +pause \ No newline at end of file diff --git a/ReallifeGamemode.Database/Update-Database.ps1 b/ReallifeGamemode.Database/Update-Database.ps1 index 0f57198a..0ab4722d 100644 --- a/ReallifeGamemode.Database/Update-Database.ps1 +++ b/ReallifeGamemode.Database/Update-Database.ps1 @@ -1,4 +1,5 @@ $root = $PSScriptRoot dotnet tool update dotnet-ef --global -dotnet ef database update --project "$root\ReallifeGamemode.Database.csproj" --startup-project "$root\..\ReallifeGamemode.Server\ReallifeGamemode.Server.csproj" --configuration "Database" \ No newline at end of file +dotnet ef database update --project "$root\ReallifeGamemode.Database.csproj" --startup-project "$root\..\ReallifeGamemode.Server\ReallifeGamemode.Server.csproj" --configuration "Database" +pause \ No newline at end of file diff --git a/ReallifeGamemode.Server/Commands/AdminCommands.cs b/ReallifeGamemode.Server/Commands/AdminCommands.cs index 0a8848a3..79ab1b4d 100644 --- a/ReallifeGamemode.Server/Commands/AdminCommands.cs +++ b/ReallifeGamemode.Server/Commands/AdminCommands.cs @@ -259,7 +259,7 @@ namespace ReallifeGamemode.Server.Commands } break; case "all": - if(!player.HasData("togall")) + if (!player.HasData("togall")) { player.SetData("togip", true); player.SetData("togdeath", true); @@ -314,6 +314,12 @@ namespace ReallifeGamemode.Server.Commands player.TriggerEvent("toggleTSupportMode", false); player.SetData("SAdminduty", false); ChatService.SendMessage(player, "!{#ee4d2e}** " + "Du befindest dich nicht mehr im T-Support"); + + if (user.GetData("adminUnshow") == true) + { + user.SetData("adminUnshow", false); + player.TriggerEvent("toggleAdminUnshowMode", false); + } } user.SetBlipAndNametagColor(); } @@ -351,7 +357,7 @@ namespace ReallifeGamemode.Server.Commands [Command("o", "~m~Benutzung: ~s~/o [Nachricht]", GreedyArg = true)] public void CmdAdminO(Player player, string message) { - if(!player.IsLoggedIn()) + if (!player.IsLoggedIn()) { return; } @@ -1784,12 +1790,16 @@ namespace ReallifeGamemode.Server.Commands [Command("spectate", "~m~Benutzung: ~s~/spectate [NAME/ID]", Alias = "spec")] public void CmdAdminSpectate(Player player, string targetname = null) { - if (!player.GetUser()?.IsAdmin(AdminLevel.ADMIN) ?? true) + User user = player.GetUser(); + if (!user.IsAdmin(AdminLevel.ADMIN)) { ChatService.NotAuthorized(player); return; } Player target; + + bool currentStatus = player.GetData("adminUnshow"); + if (targetname != null) { target = PlayerService.GetPlayerByNameOrId(targetname); @@ -1798,19 +1808,44 @@ namespace ReallifeGamemode.Server.Commands ChatService.PlayerNotFound(player); return; } - player.TriggerEvent("SERVER:ADMIN_SPECTATE", target); + + if (target.Name == player.Name) + { + ChatService.ErrorMessage(player, "Du kannst dich nicht selbst spectaten"); + return; + } + + if (!currentStatus) + { + currentStatus = !currentStatus; + player.SetData("adminUnshow", currentStatus); + } + player.TriggerEvent("toggleAdminUnshowMode", currentStatus); + player.SetData("specPosition", player.Position); + + player.SafeTeleport(target.Position); + + NAPI.Task.Run(() => + { + player.TriggerEvent("SERVER:ADMIN_SPECTATE", target); + }, 100); } else { + currentStatus = !currentStatus; + player.SetData("adminUnshow", currentStatus); player.TriggerEvent("SERVER:ADMIN_STOP_SPECTATE"); - } + player.TriggerEvent("toggleAdminUnshowMode", currentStatus); + player.SafeTeleport(player.GetData("specPosition")); + } + user.SetBlipAndNametagColor(); } [Command("aunshow", "~m~Benutzung:~s~ /aunshow")] public void CmdAdminUnshow(Player player) { User user = player.GetUser(); - if (!user.IsAdmin(AdminLevel.ADMIN)) + if (!user.IsAdmin(AdminLevel.HEADADMIN)) { ChatService.NotAuthorized(player); return; @@ -1822,9 +1857,9 @@ namespace ReallifeGamemode.Server.Commands return; } - bool currentStatus = user.GetData("adminUnshow"); + bool currentStatus = player.GetData("adminUnshow"); currentStatus = !currentStatus; - user.SetData("adminUnshow", currentStatus); + player.SetData("adminUnshow", currentStatus); player.TriggerEvent("toggleAdminUnshowMode", currentStatus); user.SetBlipAndNametagColor(); @@ -2169,18 +2204,15 @@ namespace ReallifeGamemode.Server.Commands return; } - Weather weatherBefore = NAPI.World.GetWeather(); - NAPI.World.SetWeather(weather); - Weather weatherAfter = NAPI.World.GetWeather(); + Weather weatherBefore = World.WeatherSync.Weather; + World.WeatherSync.SetWeather(weather); + Weather weatherAfter = World.WeatherSync.Weather; + + ChatService.SendMessage(player, "~w~Wetter geändert: " + weatherAfter); if (!weatherBefore.Equals(weatherAfter)) { - ChatService.SendMessage(player, "~w~Wetter geändert: " + NAPI.World.GetWeather()); - NAPI.Notification.SendNotificationToAll("Das Wetter wurde von ~g~" + player.Name + " ~s~auf ~g~" + NAPI.World.GetWeather() + "~s~ geändert.", true); - } - else - { - ChatService.SendMessage(player, "~w~Das Wetter konnte nicht geändert werden"); + NAPI.Notification.SendNotificationToAll("Das Wetter wurde von ~g~" + player.Name + " ~s~auf ~g~" + weatherAfter + "~s~ geändert.", true); } } @@ -3914,7 +3946,7 @@ namespace ReallifeGamemode.Server.Commands [RemoteEvent("Noclip")] public void Noclip(Player player) { - if (!player.GetUser()?.IsAdmin(AdminLevel.ADMIN) ?? true) + if (!player.GetUser().IsAdmin(AdminLevel.HEADADMIN)) { return; } diff --git a/ReallifeGamemode.Server/Events/UpdateCharacterElevator.cs b/ReallifeGamemode.Server/Events/UpdateCharacterElevator.cs index f7947846..540259c2 100644 --- a/ReallifeGamemode.Server/Events/UpdateCharacterElevator.cs +++ b/ReallifeGamemode.Server/Events/UpdateCharacterElevator.cs @@ -7,7 +7,7 @@ namespace ReallifeGamemode.Server.Events public class UpdateCharacterElevator : Script { [RemoteEvent("sendPlayerToStage")] - public void SaveWeaponSelection(Player client, string stage) + public void SendPlayerToStageRemoteEvent(Player client, string stage) { ElevatorPoint elevator = PositionManager.ElevatorPoints.Find(e => e.Stage == stage); if (elevator != null) diff --git a/ReallifeGamemode.Server/Events/Waypoint.cs b/ReallifeGamemode.Server/Events/Waypoint.cs new file mode 100644 index 00000000..a8a0cf07 --- /dev/null +++ b/ReallifeGamemode.Server/Events/Waypoint.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Text; +using GTANetworkAPI; +using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Server.Services; +using ReallifeGamemode.Services; + +namespace ReallifeGamemode.Server.Events +{ + class Waypoint : Script + { + [RemoteEvent("SERVER:waypointToDriver")] + public void setWaypointToDriver(Player player, float x, float y) + { + if (!player.IsInVehicle) + { + return; + } + + if (player.VehicleSeat == 0) + { + return; + } + + Entity entity = NAPI.Vehicle.GetVehicleDriver(player.Vehicle); + Player driver = PlayerService.GetPlayerByNameOrId(entity.Value.ToString()); + + if (driver == null || entity == null) + { + return; + } + + driver.TriggerEvent("SERVER:Util_setWaypoint", x, y); + driver.SendNotification(player.Name + " hat dir eine Markierung auf der Karte gesetzt"); + player.SendNotification("Du hast " + driver.Name + " eine Markierung auf der Karte gesetzt"); + } + } +} diff --git a/ReallifeGamemode.Server/Extensions/ClientExtension.cs b/ReallifeGamemode.Server/Extensions/ClientExtension.cs index e2e1636b..5463e0f6 100644 --- a/ReallifeGamemode.Server/Extensions/ClientExtension.cs +++ b/ReallifeGamemode.Server/Extensions/ClientExtension.cs @@ -356,7 +356,7 @@ namespace ReallifeGamemode.Server.Extensions } bool duty = user.GetData("duty"); - bool adminUnshow = user.GetData("adminUnshow"); + bool adminUnshow = player.GetData("adminUnshow"); if (adminUnshow) { diff --git a/ReallifeGamemode.Server/Main.cs b/ReallifeGamemode.Server/Main.cs index d6314dfc..28e226d3 100644 --- a/ReallifeGamemode.Server/Main.cs +++ b/ReallifeGamemode.Server/Main.cs @@ -148,6 +148,8 @@ namespace ReallifeGamemode.Server LoadManager.LoadLoadManager(); Rentcar.Setup(); + World.WeatherSync.Load(); + TempBlip tempBlip = new TempBlip() { Color = 1, diff --git a/ReallifeGamemode.Server/Managers/VehicleManager.cs b/ReallifeGamemode.Server/Managers/VehicleManager.cs index 4468e454..80aa1580 100644 --- a/ReallifeGamemode.Server/Managers/VehicleManager.cs +++ b/ReallifeGamemode.Server/Managers/VehicleManager.cs @@ -691,14 +691,6 @@ namespace ReallifeGamemode.Server.Managers "thrax", "zorrusso", "zion3", - "lsfd", //Mod - "lsfd2", //Mod - "lsfd3", //Mod - "lsfd4", //Mod - "lsfd5", //Mod - "lsfdtruck", //Mod - "lsfdtruck2", //Mod - "lsfdtruck3", //Mod "polbullet", //Mod "polbullet2", //Mod "sherbullet", //Mod @@ -773,11 +765,6 @@ namespace ReallifeGamemode.Server.Managers "fibj",//mod "fibn3",//mod "fibr",//mod - "vicechee", //mod - "sheriffcoqm", //mod - "polcoquette", //mod - "pdrafter", //mod - "pdrafter2", //mod }; private static readonly Dictionary _serverVehicles = new Dictionary(); diff --git a/ReallifeGamemode.Server/Wanted/Jail.cs b/ReallifeGamemode.Server/Wanted/Jail.cs index 6af59153..f3aadfdf 100644 --- a/ReallifeGamemode.Server/Wanted/Jail.cs +++ b/ReallifeGamemode.Server/Wanted/Jail.cs @@ -209,8 +209,8 @@ namespace ReallifeGamemode.Server.Wanted public static void BreakOut(Player player) { - User user = player.GetUser(); - + if (player.IsTSupport()) return; + User user = player.GetUser(); using (var dbContext = new DatabaseContext()) { user = player.GetUser(dbContext); @@ -225,8 +225,8 @@ namespace ReallifeGamemode.Server.Wanted [RemoteEvent("SERVER:BreakOutIfInPrison")] public void breakOutIfInPrison(Player player) { + if (player.IsTSupport()) return; User user = player.GetUser(); - using (var dbContext = new DatabaseContext()) { if (Jailtime.ContainsKey(user.Id)) diff --git a/ReallifeGamemode.Server/World/WeatherSync.cs b/ReallifeGamemode.Server/World/WeatherSync.cs new file mode 100644 index 00000000..2b2acc9b --- /dev/null +++ b/ReallifeGamemode.Server/World/WeatherSync.cs @@ -0,0 +1,103 @@ +using System; +using System.Timers; +using GTANetworkAPI; + +/** +* @overview Life of German Reallife - WeatherSync +* @author Alex_qp +* @copyright (c) 2008 - 2021 Life of German +*/ + +namespace ReallifeGamemode.Server.World +{ + + /// + /// Serverwide WeatherSystem (+ sync) + /// + static class WeatherSync + { + // SETTINGS + private const uint _syncInterval = 5 * 60 * 1000; // 5 min + private static readonly int[] _countRange = new int[] { 3, 5 }; // min, max both inclusive. How often should weather be synced before actual changing? + + // INTERNAL + private static int _count = 0; + private static int _targetCount = GetNewTargetCount(); + + /// + /// Get/Set the current weather. + /// Only use in main thread! + /// + public static Weather Weather + { + get { return NAPI.World.GetWeather(); } + set { NAPI.World.SetWeather(value); } + } + + /// + /// Set the current weather by string. + /// + /// Only use in main thread! + /// + /// + public static void SetWeather(string weather) + { + NAPI.World.SetWeather(weather); + } + + private static Timer weatherTimer; + + /// + /// Loads/Starts the WeatherSync. + /// + public static void Load() + { + weatherTimer = new Timer(_syncInterval); + weatherTimer.Start(); + weatherTimer.Elapsed += OnWeatherTimer; + NAPI.Util.ConsoleOutput("Loaded WeatherSync"); + } + + private static int GetNewTargetCount() + { + return new Random().Next(_countRange[0], _countRange[1] + 1); + } + + private static Weather GetRandomWeather(Weather[] weathers) + { + return weathers[new Random().Next(weathers.Length)]; + } + + private static void OnWeatherTimer(object sender, ElapsedEventArgs e) + { + NAPI.Task.Run(() => + { + if (_count < _targetCount) + { + // sync weather for all players + _count++; + Weather = Weather; + } + else + { + // change weather and reset counters + _count = 0; + _targetCount = GetNewTargetCount(); + Weather = Weather switch + { + Weather.EXTRASUNNY => GetRandomWeather(new Weather[] { Weather.EXTRASUNNY, Weather.CLEAR }), + Weather.CLEAR => GetRandomWeather(new Weather[] { Weather.EXTRASUNNY, Weather.CLEAR, Weather.CLOUDS, Weather.SMOG }), + Weather.CLOUDS => GetRandomWeather(new Weather[] { Weather.CLEAR, Weather.CLOUDS, Weather.SMOG, Weather.FOGGY, Weather.OVERCAST }), + Weather.SMOG => GetRandomWeather(new Weather[] { Weather.CLOUDS, Weather.SMOG, Weather.FOGGY, Weather.OVERCAST }), + Weather.FOGGY => GetRandomWeather(new Weather[] { Weather.CLOUDS, Weather.SMOG, Weather.FOGGY, Weather.OVERCAST, Weather.RAIN }), + Weather.OVERCAST => GetRandomWeather(new Weather[] { Weather.CLOUDS, Weather.SMOG, Weather.RAIN, Weather.CLEARING }), // may add overcast + Weather.RAIN => GetRandomWeather(new Weather[] { Weather.OVERCAST, Weather.RAIN, Weather.CLEARING, Weather.THUNDER }), + Weather.THUNDER => GetRandomWeather(new Weather[] { Weather.RAIN, Weather.THUNDER, Weather.CLEARING }), + Weather.CLEARING => GetRandomWeather(new Weather[] { Weather.CLEAR, Weather.CLOUDS, Weather.CLEARING }), + _ => GetRandomWeather(new Weather[] { Weather.EXTRASUNNY, Weather.CLEAR }), + }; + } + }); + } + } +}