From 540bc44a565bfae73cdb04919d4fa24c1997a4ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emre=20C=C3=BCrg=C3=BCl?= Date: Sun, 27 May 2018 17:08:17 +0200 Subject: [PATCH] Use Entity Decors for Spawning, Syncing and Despawning --- CorruptSnail/CorruptSnail.csproj | 2 + .../Spawners/Ambient/FlyingByPlaneSpawner.cs | 4 +- CorruptSnail/Spawners/Despawner.cs | 31 +++++++ .../Spawners/Events/ArmyHeliSquadSpawner.cs | 21 ++++- .../Spawners/Events/RebelSquadSpawner.cs | 19 ++-- CorruptSnail/Spawners/ObjectSpawner.cs | 2 +- CorruptSnail/Spawners/SpawnerHost.cs | 2 + CorruptSnail/Spawners/VehicleSpawner.cs | 2 +- CorruptSnail/Spawners/ZombieSpawner.cs | 31 ++++--- CorruptSnail/TimeSync.cs | 19 +--- CorruptSnail/Util/EntityEnum.cs | 93 +++++++++++++++++++ menu.lua | 3 +- server.lua | 11 ++- 13 files changed, 188 insertions(+), 52 deletions(-) create mode 100644 CorruptSnail/Spawners/Despawner.cs create mode 100644 CorruptSnail/Util/EntityEnum.cs diff --git a/CorruptSnail/CorruptSnail.csproj b/CorruptSnail/CorruptSnail.csproj index 9f98909..7d4154b 100644 --- a/CorruptSnail/CorruptSnail.csproj +++ b/CorruptSnail/CorruptSnail.csproj @@ -46,6 +46,7 @@ + @@ -59,6 +60,7 @@ + diff --git a/CorruptSnail/Spawners/Ambient/FlyingByPlaneSpawner.cs b/CorruptSnail/Spawners/Ambient/FlyingByPlaneSpawner.cs index 667275e..819e354 100644 --- a/CorruptSnail/Spawners/Ambient/FlyingByPlaneSpawner.cs +++ b/CorruptSnail/Spawners/Ambient/FlyingByPlaneSpawner.cs @@ -40,8 +40,8 @@ private async Task OnTick() else if (flyingByPlane != null) if (!Utils.IsPosShitSpawn(Players, flyingByPlane.Plane.Position, SpawnerHost.SPAWN_DESPAWN_DISTANCE * 3)) { - flyingByPlane.Plane.MarkAsNoLongerNeeded(); - flyingByPlane.Pilot.MarkAsNoLongerNeeded(); + flyingByPlane.Plane.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); + flyingByPlane.Pilot.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); flyingByPlane = null; } } diff --git a/CorruptSnail/Spawners/Despawner.cs b/CorruptSnail/Spawners/Despawner.cs new file mode 100644 index 0000000..e1e11ac --- /dev/null +++ b/CorruptSnail/Spawners/Despawner.cs @@ -0,0 +1,31 @@ +using CitizenFX.Core; +using CorruptSnail.Util; +using System.Threading.Tasks; + +namespace CorruptSnail.Spawners +{ + class Despawner : BaseScript + { + public Despawner() + { + Tick += OnTick; + } + + private async Task OnTick() + { + await Delay(SpawnerHost.SPAWN_TICK_RATE); + + foreach (Prop prop in EntityEnum.GetProps()) + if (prop.HasDecor(SpawnerHost.SPAWN_DESPAWN_DECOR)) + prop.MarkAsNoLongerNeeded(); + + foreach (Ped ped in EntityEnum.GetPeds()) + if (ped.HasDecor(SpawnerHost.SPAWN_DESPAWN_DECOR)) + ped.MarkAsNoLongerNeeded(); + + foreach (Vehicle veh in EntityEnum.GetVehicles()) + if (veh.HasDecor(SpawnerHost.SPAWN_DESPAWN_DECOR)) + veh.MarkAsNoLongerNeeded(); + } + } +} diff --git a/CorruptSnail/Spawners/Events/ArmyHeliSquadSpawner.cs b/CorruptSnail/Spawners/Events/ArmyHeliSquadSpawner.cs index 7f5ec18..fbfe65d 100644 --- a/CorruptSnail/Spawners/Events/ArmyHeliSquadSpawner.cs +++ b/CorruptSnail/Spawners/Events/ArmyHeliSquadSpawner.cs @@ -10,6 +10,7 @@ class ArmyHeliSquadSpawner : BaseScript private const int ARMYHELI_SPAWNHEIGHT_MIN_OFFSET = 100; private const int ARMYHELI_SPAWNHEIGHT_MAX_OFFSET = 500; private const int ARMYHELI_MIN_SPEED = 10; + private const string ARMYHELI_DECOR = "_TOUGH_AF_FRIENDS"; private static VehicleHash[] HELI_LIST { get; } = { VehicleHash.Buzzard, VehicleHash.Buzzard2, VehicleHash.Savage, VehicleHash.Cargobob }; @@ -48,12 +49,14 @@ private async Task OnTick() else if (armyHeliSquad != null) if (!Utils.IsPosShitSpawn(Players, armyHeliSquad.Heli.Position, SpawnerHost.SPAWN_DESPAWN_DISTANCE * 3)) { - armyHeliSquad.Heli.MarkAsNoLongerNeeded(); - armyHeliSquad.Pilot.MarkAsNoLongerNeeded(); - armyHeliSquad.Gunman1.MarkAsNoLongerNeeded(); - armyHeliSquad.Gunman2.MarkAsNoLongerNeeded(); + armyHeliSquad.Heli.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); + armyHeliSquad.Pilot.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); + armyHeliSquad.Gunman1.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); + armyHeliSquad.Gunman2.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); armyHeliSquad = null; } + + HandleArmyHeliSquads(); } private async void SpawnRandomArmyHeli() @@ -73,6 +76,7 @@ private async void SpawnRandomArmyHeli() pilot.RelationshipGroup = ArmyHeliSquadGroup; pilot.SetIntoVehicle(heli, VehicleSeat.Driver); pilot.AlwaysKeepTask = true; + pilot.SetDecor(ARMYHELI_DECOR, true); Vector3 targetPos = Game.PlayerPed .GetOffsetPosition(new Vector3(0f, -SpawnerHost.SPAWN_DESPAWN_DISTANCE * 100f, 0f)); API.TaskHeliMission(pilot.Handle, heli.Handle, 0, 0, targetPos.X, targetPos.Y, targetPos.Z, @@ -88,15 +92,22 @@ private async void SpawnRandomArmyHeli() gunman.Accuracy = 100; gunman.AlwaysKeepTask = true; gunman.Task.FightAgainstHatedTargets(float.MaxValue); + gunman.SetDecor(ARMYHELI_DECOR, true); gunmans[i] = gunman; } gunmans[0].SetIntoVehicle(heli, VehicleSeat.LeftRear); gunmans[1].SetIntoVehicle(heli, VehicleSeat.RightRear); - ArmyHeliSquadGroup.SetRelationshipBetweenGroups(Game.PlayerPed.RelationshipGroup, Relationship.Respect, true); ArmyHeliSquadGroup.SetRelationshipBetweenGroups(ZombieSpawner.ZombieGroup, Relationship.Hate); armyHeliSquad = new ArmyHeliSquad(heli, pilot, gunmans[0], gunmans[1]); } } + + private void HandleArmyHeliSquads() + { + foreach (Ped ped in EntityEnum.GetPeds()) + if (ped.HasDecor(ARMYHELI_DECOR)) + ped.RelationshipGroup.SetRelationshipBetweenGroups(Game.PlayerPed.RelationshipGroup, Relationship.Like, true); + } } } diff --git a/CorruptSnail/Spawners/Events/RebelSquadSpawner.cs b/CorruptSnail/Spawners/Events/RebelSquadSpawner.cs index 36768c5..8556d7f 100644 --- a/CorruptSnail/Spawners/Events/RebelSquadSpawner.cs +++ b/CorruptSnail/Spawners/Events/RebelSquadSpawner.cs @@ -8,7 +8,7 @@ namespace CorruptSnail.Spawners.Events class RebelSquadSpawner : BaseScript { private const int REBELSQUAD_MAXMEMBERS = 8; - private const float REBELSQUAD_FRIENDLY_CHANCE = 0.5f; + private const string REBELSQUAD_DECOR = "_HOSTILE_REBELS"; private static WeaponHash[] WEAPON_LIST { get; } = { WeaponHash.Pistol, WeaponHash.AssaultRifle, WeaponHash.PumpShotgun, WeaponHash.Bat }; @@ -48,7 +48,7 @@ private async Task OnTick() { if (!Utils.IsPosShitSpawn(Players, rebel.Position, SpawnerHost.SPAWN_DESPAWN_DISTANCE) || rebel.IsDead) - rebel.MarkAsNoLongerNeeded(); + rebel.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); else allObsolete = false; } @@ -69,9 +69,6 @@ private async void SpawnRandomRebelSquad() Ped[] rebels = new Ped[rebelAmount]; for (int i = 0; i < rebelAmount; i++) { - spawnPos.X += 5; - spawnPos.Y += 5; - Ped rebel = await World.CreatePed(PedHash.Hillbilly01AMM, spawnPos); API.SetPedCombatRange(rebel.Handle, 2); API.SetPedHearingRange(rebel.Handle, float.MaxValue); @@ -80,17 +77,21 @@ private async void SpawnRandomRebelSquad() rebel.Accuracy = 100; rebel.Armor = 100; rebel.Task.WanderAround(); + rebel.SetDecor(REBELSQUAD_DECOR, true); rebels[i] = rebel; } - if (Utils.GetRandomFloat(1f) > REBELSQUAD_FRIENDLY_CHANCE) - RebelSquadGroup.SetRelationshipBetweenGroups(Game.PlayerPed.RelationshipGroup, Relationship.Hate, true); - else - RebelSquadGroup.SetRelationshipBetweenGroups(Game.PlayerPed.RelationshipGroup, Relationship.Respect, true); RebelSquadGroup.SetRelationshipBetweenGroups(ZombieSpawner.ZombieGroup, Relationship.Hate, true); RebelSquadGroup.SetRelationshipBetweenGroups(ArmyHeliSquadSpawner.ArmyHeliSquadGroup, Relationship.Hate, true); rebelSquad = new RebelSquad(rebels); } } + + private void HandleRebelSquads() + { + foreach (Ped ped in EntityEnum.GetPeds()) + if (ped.HasDecor(REBELSQUAD_DECOR)) + ped.RelationshipGroup.SetRelationshipBetweenGroups(Game.PlayerPed.RelationshipGroup, Relationship.Hate, true); + } } } diff --git a/CorruptSnail/Spawners/ObjectSpawner.cs b/CorruptSnail/Spawners/ObjectSpawner.cs index 3ba464e..36675ff 100644 --- a/CorruptSnail/Spawners/ObjectSpawner.cs +++ b/CorruptSnail/Spawners/ObjectSpawner.cs @@ -32,7 +32,7 @@ private async Task OnTick() foreach (Prop obstacle in obstacles.ToArray()) if (!Utils.IsPosShitSpawn(Players, obstacle.Position, SpawnerHost.SPAWN_DESPAWN_DISTANCE)) { - obstacle.Delete(); + obstacle.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); obstacles.Remove(obstacle); } } diff --git a/CorruptSnail/Spawners/SpawnerHost.cs b/CorruptSnail/Spawners/SpawnerHost.cs index ff0cede..01c4378 100644 --- a/CorruptSnail/Spawners/SpawnerHost.cs +++ b/CorruptSnail/Spawners/SpawnerHost.cs @@ -12,6 +12,7 @@ class SpawnerHost : BaseScript public const float SPAWN_DESPAWN_DISTANCE = 350f; public const double SPAWN_EVENT_CHANCE = 0.005; public const int SPAWN_TICK_RATE = 100; + public const string SPAWN_DESPAWN_DECOR = "_MARKED_FOR_DESPAWN"; private const float SPAWN_HOST_DECIDE_DISTANCE = 500f; public static bool IsHost { get; private set; } @@ -20,6 +21,7 @@ public SpawnerHost() { IsHost = false; + EntityDecoration.RegisterProperty(SPAWN_DESPAWN_DECOR, DecorationType.Bool); Tick += OnTick; } diff --git a/CorruptSnail/Spawners/VehicleSpawner.cs b/CorruptSnail/Spawners/VehicleSpawner.cs index 81250a6..b2e4043 100644 --- a/CorruptSnail/Spawners/VehicleSpawner.cs +++ b/CorruptSnail/Spawners/VehicleSpawner.cs @@ -26,7 +26,7 @@ private async Task OnTick() if (!Utils.IsPosShitSpawn(Players, spawnedVeh.Position, SpawnerHost.SPAWN_DESPAWN_DISTANCE) || spawnedVeh.EngineHealth == 0f) { - spawnedVeh.MarkAsNoLongerNeeded(); + spawnedVeh.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); spawnedVeh = null; } } diff --git a/CorruptSnail/Spawners/ZombieSpawner.cs b/CorruptSnail/Spawners/ZombieSpawner.cs index 562f084..5742b4e 100644 --- a/CorruptSnail/Spawners/ZombieSpawner.cs +++ b/CorruptSnail/Spawners/ZombieSpawner.cs @@ -12,7 +12,8 @@ class ZombieSpawner : BaseScript private const int ZOMBIE_AMOUNT = 30; private const double ZOMBIE_ATTR_CHANCE = 0.5; private const int ZOMBIE_MAX_HEALTH = 500; - private const int ZOMBIE_MAX_ARMOR = 500; + private const int ZOMBIE_MAX_ARMOR = 500; + private const string ZOMBIE_DECOR = "_I_AM_RAWWRRR"; private List zombies; public static RelationshipGroup ZombieGroup { get; private set; } @@ -22,7 +23,7 @@ public ZombieSpawner() zombies = new List(); ZombieGroup = World.AddRelationshipGroup("zombies"); - EventHandlers["corruptsnail:client:newZombie"] += new Action(OnNewZombie); + EntityDecoration.RegisterProperty(ZOMBIE_DECOR, DecorationType.Bool); Tick += OnTick; } @@ -37,9 +38,11 @@ private async Task OnTick() if (!Utils.IsPosShitSpawn(Players, zombie.Position, SpawnerHost.SPAWN_DESPAWN_DISTANCE) || zombie.IsDead) { - zombie.MarkAsNoLongerNeeded(); + zombie.SetDecor(SpawnerHost.SPAWN_DESPAWN_DECOR, true); zombies.Remove(zombie); } + + HandleZombies(); } private async void SpawnRandomZombie() @@ -66,27 +69,29 @@ private async void SpawnRandomZombie() zombie.Health = randHealth; zombie.Armor = Utils.GetRandomInt(ZOMBIE_MAX_ARMOR); zombie.RelationshipGroup = ZombieGroup; - ZombieGroup.SetRelationshipBetweenGroups(Game.PlayerPed.RelationshipGroup, Relationship.Hate, true); ZombieAttrChances(zombie); zombie.Task.WanderAround(); - TriggerServerEvent("corruptsnail:newZombie", API.PedToNet(zombieHandle)); + zombie.SetDecor(ZOMBIE_DECOR, true); zombies.Add(zombie); } } - private void OnNewZombie(int zombieNetHandle) + private void HandleZombies() { - int zombieHandle = API.NetToPed(zombieNetHandle); - Ped zombie = new Ped(zombieHandle) + foreach (Ped ped in EntityEnum.GetPeds()) { - Voice = "ALIENS", - IsPainAudioEnabled = false - }; + if (ped.HasDecor(ZOMBIE_DECOR)) + { + ped.Voice = "ALIENS"; + ped.IsPainAudioEnabled = false; + ped.RelationshipGroup.SetRelationshipBetweenGroups(Game.PlayerPed.RelationshipGroup, Relationship.Hate, true); - API.RequestAnimSet("move_m@drunk@verydrunk"); - API.SetPedMovementClipset(zombieHandle, "move_m@drunk@verydrunk", 1f); + API.RequestAnimSet("move_m@drunk@verydrunk"); + API.SetPedMovementClipset(ped.Handle, "move_m@drunk@verydrunk", 1f); + } + } } private void ZombieAttrChances(Ped zombie) diff --git a/CorruptSnail/TimeSync.cs b/CorruptSnail/TimeSync.cs index bcf03a8..2a1be87 100644 --- a/CorruptSnail/TimeSync.cs +++ b/CorruptSnail/TimeSync.cs @@ -1,28 +1,17 @@ using CitizenFX.Core; +using CitizenFX.Core.Native; using System; namespace CorruptSnail { class TimeSync : BaseScript { - private bool synced = false; - public TimeSync() { EventHandlers["playerSpawned"] += new Action(delegate { - if (!synced) - TriggerServerEvent("corruptsnail:timeSync"); - else - { - TimeSpan currentTime = World.CurrentDayTime; - TriggerServerEvent("corruptsnail:updateTime", currentTime.Hours, currentTime.Minutes, currentTime.Seconds); - } - }); - - EventHandlers["corruptsnail:client:timeSync"] += new Action((timeH, timeM, timeS) => - { - World.CurrentDayTime = new TimeSpan(timeH, timeM, timeS); - synced = true; + int h = 0; int m = 0; int s = 0; + API.NetworkGetServerTime(ref h, ref m, ref s); + API.NetworkOverrideClockTime(h, m, s); }); } } diff --git a/CorruptSnail/Util/EntityEnum.cs b/CorruptSnail/Util/EntityEnum.cs new file mode 100644 index 0000000..d2e8fe1 --- /dev/null +++ b/CorruptSnail/Util/EntityEnum.cs @@ -0,0 +1,93 @@ +using CitizenFX.Core; +using CitizenFX.Core.Native; +using System.Collections.Generic; + +namespace CorruptSnail.Util +{ + class EntityEnum + { + public static List GetProps() + { + List props = new List(); + int entHandle = 0; + + int handle = API.FindFirstObject(ref entHandle); + Prop prop = (Prop) Entity.FromHandle(entHandle); + if (prop != null) + props.Add(prop); + + while (API.FindNextObject(handle, ref entHandle)) + { + prop = (Prop) Entity.FromHandle(entHandle); + if (prop != null) + props.Add(prop); + } + + API.EndFindObject(handle); + return props; + } + + public static List GetPeds() + { + List peds = new List(); + int entHandle = 0; + + int handle = API.FindFirstPed(ref entHandle); + Ped ped = (Ped) Entity.FromHandle(entHandle); + if (ped != null) + peds.Add(ped); + + while (API.FindNextPed(handle, ref entHandle)) + { + ped = (Ped) Entity.FromHandle(entHandle); + if (ped != null) + peds.Add(ped); + } + + API.EndFindPed(handle); + return peds; + } + + public static List GetVehicles() + { + List vehs = new List(); + int entHandle = 0; + + int handle = API.FindFirstVehicle(ref entHandle); + Vehicle veh = (Vehicle) Entity.FromHandle(entHandle); + if (veh != null) + vehs.Add(veh); + + while (API.FindNextVehicle(handle, ref entHandle)) + { + veh = (Vehicle) Entity.FromHandle(entHandle); + if (veh != null) + vehs.Add(veh); + } + + API.EndFindVehicle(handle); + return vehs; + } + + public static List GetPickups() + { + List pickups = new List(); + int entHandle = 0; + + int handle = API.FindFirstPickup(ref entHandle); + Pickup pickup = new Pickup(entHandle); + if (pickup != null && pickup.Exists()) + pickups.Add(pickup); + + while (API.FindNextPickup(handle, ref entHandle)) + { + pickup = new Pickup(entHandle); + if (pickup != null && pickup.Exists()) + pickups.Add(pickup); + } + + API.EndFindPickup(handle); + return pickups; + } + } +} diff --git a/menu.lua b/menu.lua index 5dbad92..b609fec 100644 --- a/menu.lua +++ b/menu.lua @@ -41,7 +41,8 @@ function spawnVehicleToPlayer(model) RequestModel(model) end - local veh = CreateVehicle(model, x + 2.5, y + 2.5, z + 1, 0.0, true, true) + local veh = CreateVehicle(model, x + 2.5, y + 2.5, z + 1, 0.0, true, false) + SetVehicleAsNoLongerNeeded(veh) drawNotification("~g~Vehicle spawned!") end diff --git a/server.lua b/server.lua index c725edf..01f8788 100644 --- a/server.lua +++ b/server.lua @@ -1,7 +1,10 @@ -RegisterNetEvent("corruptsnail:newZombie") +--[[RegisterNetEvent("corruptsnail:newZombie") AddEventHandler("corruptsnail:newZombie", function(zombieNetHandle) TriggerClientEvent("corruptsnail:client:newZombie", -1, zombieNetHandle) end) +local timeH = 0 +local timeM = 0 +local timeS = 0 RegisterNetEvent("corruptsnail:updateTime") AddEventHandler("corruptsnail:updateTime", function(newTimeH, newTimeM, newTimeS) @@ -12,7 +15,5 @@ end) RegisterNetEvent("corruptsnail:timeSync") AddEventHandler("corruptsnail:timeSync", function() - if timeH and timeM and timeS then - TriggerClientEvent("corruptsnail:client:timeSync", source, timeH, timeM, timeS) - end -end) \ No newline at end of file + TriggerClientEvent("corruptsnail:client:timeSync", source, timeH, timeM, timeS) +end)]]-- \ No newline at end of file