Skip to content

Commit 607cfec

Browse files
committed
feat:(Zone)
1 parent f778b41 commit 607cfec

34 files changed

+1083
-153
lines changed

enums/eLibEvents.lua

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ eLibEvents = {
44
emitCallback = 'lib.events.callback.emit',
55
receiveCallback = 'lib.events.callback.receive',
66
sendNotification = 'lib.game.notification.send',
7+
zoneAdd = 'lib.game.zone.add',
8+
zoneUpdate = 'lib.game.zone.update',
9+
zoneStateChange = 'lib.game.zone.stateChange',
710

811
};
912

enums/eMarkerType.lua

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
---@enum eMarkerType
2+
eMarkerType = {
3+
4+
---<img src="https://docs.fivem.net/markers/0.png?raw=true" height="200">
5+
UpsideDownCone = 0,
6+
---<img src="https://docs.fivem.net/markers/1.png?raw=true" height="200">
7+
VerticalCylinder = 1,
8+
---<img src="https://docs.fivem.net/markers/2.png?raw=true" height="200">
9+
ThickChevronUp = 2,
10+
---<img src="https://docs.fivem.net/markers/3.png?raw=true" height="200">
11+
ThinChevronUp = 3,
12+
---<img src="https://docs.fivem.net/markers/4.png?raw=true" height="200">
13+
CheckeredFlagRect = 4,
14+
---<img src="https://docs.fivem.net/markers/5.png?raw=true" height="200">
15+
CheckeredFlagCircle = 5,
16+
---<img src="https://docs.fivem.net/markers/6.png?raw=true" height="200">
17+
VerticleCircle = 6,
18+
---<img src="https://docs.fivem.net/markers/7.png?raw=true" height="200">
19+
PlaneModel = 7,
20+
---<img src="https://docs.fivem.net/markers/8.png?raw=true" height="200">
21+
LostMCTransparent = 8,
22+
---<img src="https://docs.fivem.net/markers/9.png?raw=true" height="200">
23+
LostMC = 9,
24+
---<img src="https://docs.fivem.net/markers/10.png?raw=true" height="200">
25+
Number0 = 10,
26+
---<img src="https://docs.fivem.net/markers/11.png?raw=true" height="200">
27+
Number1 = 11,
28+
---<img src="https://docs.fivem.net/markers/12.png?raw=true" height="200">
29+
Number2 = 12,
30+
---<img src="https://docs.fivem.net/markers/13.png?raw=true" height="200">
31+
Number3 = 13,
32+
---<img src="https://docs.fivem.net/markers/14.png?raw=true" height="200">
33+
Number4 = 14,
34+
---<img src="https://docs.fivem.net/markers/15.png?raw=true" height="200">
35+
Number5 = 15,
36+
---<img src="https://docs.fivem.net/markers/16.png?raw=true" height="200">
37+
Number6 = 16,
38+
---<img src="https://docs.fivem.net/markers/17.png?raw=true" height="200">
39+
Number7 = 17,
40+
---<img src="https://docs.fivem.net/markers/18.png?raw=true" height="200">
41+
Number8 = 18,
42+
---<img src="https://docs.fivem.net/markers/19.png?raw=true" height="200">
43+
Number9 = 19,
44+
---<img src="https://docs.fivem.net/markers/20.png?raw=true" height="200">
45+
ChevronUpx1 = 20,
46+
---<img src="https://docs.fivem.net/markers/21.png?raw=true" height="200">
47+
ChevronUpx2 = 21,
48+
---<img src="https://docs.fivem.net/markers/22.png?raw=true" height="200">
49+
ChevronUpx3 = 22,
50+
---<img src="https://docs.fivem.net/markers/23.png?raw=true" height="200">
51+
HorizontalCircleFat = 23,
52+
---<img src="https://docs.fivem.net/markers/24.png?raw=true" height="200">
53+
ReplayIcon = 24,
54+
---<img src="https://docs.fivem.net/markers/25.png?raw=true" height="200">
55+
HorizontalCircleSkinny = 25,
56+
---<img src="https://docs.fivem.net/markers/26.png?raw=true" height="200">
57+
HorizontalCircleSkinny_Arrow = 26,
58+
---<img src="https://docs.fivem.net/markers/27.png?raw=true" height="200">
59+
HorizontalSplitArrowCircle = 27,
60+
---<img src="https://docs.fivem.net/markers/28.png?raw=true" height="200">
61+
DebugSphere = 28,
62+
---<img src="https://docs.fivem.net/markers/29.png?raw=true" height="200">
63+
DollarSign = 29,
64+
---<img src="https://docs.fivem.net/markers/30.png?raw=true" height="200">
65+
HorizontalBars = 30,
66+
---<img src="https://docs.fivem.net/markers/31.png?raw=true" height="200">
67+
WolfHead = 31,
68+
---<img src="https://docs.fivem.net/markers/32.png?raw=true" height="200">
69+
QuestionMark = 32,
70+
---<img src="https://docs.fivem.net/markers/33.png?raw=true" height="200">
71+
PlaneSymbol = 33,
72+
---<img src="https://docs.fivem.net/markers/34.png?raw=true" height="200">
73+
HelicopterSymbol = 34,
74+
---<img src="https://docs.fivem.net/markers/35.png?raw=true" height="200">
75+
BoatSymbol = 35,
76+
---<img src="https://docs.fivem.net/markers/36.png?raw=true" height="200">
77+
CarSymbol = 36,
78+
---<img src="https://docs.fivem.net/markers/37.png?raw=true" height="200">
79+
MotorcycleSymbol = 37,
80+
---<img src="https://docs.fivem.net/markers/38.png?raw=true" height="200">
81+
BikeSymbol = 38,
82+
---<img src="https://docs.fivem.net/markers/39.png?raw=true" height="200">
83+
TruckSymbol = 39,
84+
---<img src="https://docs.fivem.net/markers/40.png?raw=true" height="200">
85+
ParachuteSymbol = 40,
86+
---<img src="https://docs.fivem.net/markers/41.png?raw=true" height="200">
87+
undefined1 = 41,
88+
---<img src="https://docs.fivem.net/markers/42.png?raw=true" height="200">
89+
SawbladeSymbol = 42,
90+
---<img src="https://docs.fivem.net/markers/43.png?raw=true" height="200">
91+
undefined2 = 43
92+
93+
};
94+
95+
return eMarkerType;

enums/index.lua

+1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ enums.discordColor = require 'enums.eDiscordColor';
66
enums.citizenFXEvents = require 'enums.eCitizenFXEvents';
77
enums.entityEvents = require 'enums.eEntityEvents';
88
enums.identifierType = require 'enums.eIdentifierType';
9+
enums.markerType = require 'enums.eMarkerType';
910

1011
return enums;

imports.lua

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
lib = {};
22
lib.cache = {};
3-
lib.cache.type = type;
43
lib.classes = {};
54
lib.is_server = IsDuplicityVersion();
65
lib.name = 'lib';
@@ -30,14 +29,14 @@ end
3029

3130
---@param resource? string
3231
function lib.set_required_resource(resource)
33-
current_resource = lib.cache.type(resource) == 'string' and resource or lib.current_resource;
32+
current_resource = type(resource) == 'string' and resource or lib.current_resource;
3433
end
3534

3635
---@param modname string
3736
---@return any
3837
function require(modname)
3938

40-
if lib.cache.type(modname) ~= 'string' then return; end
39+
if type(modname) ~= 'string' then return; end
4140

4241
local mod_id = ('%s.%s'):format(current_resource, modname);
4342
local module = modules[mod_id];
@@ -74,7 +73,7 @@ function require(modname)
7473
return error(err or ("Unable to load module '%s'"):format(modname), 0);
7574
end
7675

77-
if (lib.cache.type(console) == 'table' and lib.cache.type(console.debug) == 'function') then
76+
if (type(console) == 'table' and type(console.debug) == 'function') then
7877
if (lib.current_resource == current_resource) then
7978
console.debug(('Loaded module ^7\'^2%s^7\'^0'):format(modname));
8079
else
@@ -113,5 +112,8 @@ lib.error_handler = require 'system.modules.error_handler';
113112

114113
lib.classes.locale = require 'system.modules.locale';
115114
lib.classes.events = require 'system.modules.classes.EventEmitter';
115+
lib.classes.list = require 'system.modules.classes.List';
116+
lib.classes.map = require 'system.modules.classes.Map';
117+
lib.classes.color = require 'system.modules.classes.Color';
116118

117119
require 'lib.index';

internal/game/index.lua

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require 'internal.game.zone.index';

internal/game/zone/InternalZone.lua

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---@class InternalZone: BaseObject
2+
---@field public id string
3+
---@field public resource string
4+
---@field public active boolean
5+
---@field public position vector3
6+
---@field public size number
7+
---@field public metadata Map
8+
---@overload fun(id: string, resource: string): InternalZone
9+
local InternalZone = Class.new "InternalZone";
10+
11+
---@param id string
12+
---@param resource string
13+
function InternalZone:Constructor(id, resource)
14+
self.id = id;
15+
self.resource = resource;
16+
self.active = false;
17+
self.position = nil;
18+
self.size = 0;
19+
self.metadata = Map();
20+
end
21+
22+
return InternalZone;

internal/game/zone/ZoneService.lua

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
local InternalZone = require 'internal.game.zone.InternalZone';
2+
3+
---@type ZoneService
4+
local ZoneService = Class.singleton('ZoneService', 'EventEmitter', function(class)
5+
6+
---@class ZoneService: BaseObject
7+
---@field public zones table<string, InternalZone>
8+
---@field private resources table<string, string[]>
9+
local self = class;
10+
11+
function self:Constructor()
12+
self:super();
13+
self.zones = {};
14+
self.resources = {};
15+
end
16+
17+
---@param zone Zone
18+
function self:Register(zone)
19+
assert(not lib.is_server, 'ZoneService:Register is only available on client.');
20+
if (typeof(self.zones[zone.id]) == 'InternalZone') then
21+
console.warn(("^7[^6ZoneService^7] ^3Zone ^7[^5%s^7] ^3is already registered, overwriting..."):format(zone.id));
22+
end
23+
self.zones[zone.id] = InternalZone(zone.id, zone.resource);
24+
self.resources[zone.resource] = type(self.resources[zone.resource]) == 'table' and self.resources[zone.resource] or {};
25+
self.resources[zone.resource][#self.resources[zone.resource] + 1] = zone.id;
26+
console.success(("^7[^6ZoneService^7] ^3Zone ^7[^5%s^7] ^3has been registered."):format(zone.id));
27+
end
28+
29+
---@param id string
30+
---@return InternalZone
31+
function self:Get(id)
32+
assert(not lib.is_server, 'ZoneService:Get is only available on client.');
33+
return self.zones[id];
34+
end
35+
36+
---@return table<string, InternalZone>
37+
function self:GetAll()
38+
assert(not lib.is_server, 'ZoneService:GetAll is only available on client.')
39+
return self.zones;
40+
end
41+
42+
---@param resource string
43+
---@param id string
44+
---@return table<string, InternalZone>, number
45+
function self:GetByResource(resource, id)
46+
assert(not lib.is_server, 'ZoneService:GetByResource is only available on client.');
47+
if (type(self.resources[resource]) == 'table') then
48+
for i = 1, #self.resources[resource] do
49+
if (self.resources[resource][i] == id) then
50+
return self.zones[id], i;
51+
end
52+
end
53+
end
54+
end
55+
56+
---@param resource string
57+
---@return table<string, InternalZone> | nil
58+
function self:GetAllByResource(resource)
59+
assert(not lib.is_server, 'ZoneService:GetAllByResource is only available on client.');
60+
if (type(self.resources[resource]) == 'table') then
61+
local zones = {};
62+
for i = 1, #self.resources[resource] do
63+
zones[self.resources[resource][i]] = self.zones[self.resources[resource][i]];
64+
end
65+
return zones;
66+
end
67+
return nil;
68+
end
69+
70+
---@param id string
71+
function self:Remove(id)
72+
if (typeof(self.zones[id]) == 'InternalZone') then
73+
local _, index = self:GetByResource(self.zones[id].resource, id);
74+
self.zones[id] = nil;
75+
self.resources[self.zones[id].resource][index] = nil;
76+
console.warn(("^7[^6ZoneService^7] ^3Zone ^7[^5%s^7] ^3has been removed."):format(id));
77+
end
78+
end
79+
80+
---@param resource string
81+
function self:RemoveByResource(resource)
82+
assert(not lib.is_server, 'ZoneService:RemoveByResource is only available on client.');
83+
if (type(self.resources[resource]) == 'table') then
84+
for i = 1, #self.resources[resource] do
85+
self.zones[self.resources[resource][i]] = nil;
86+
console.warn(("^7[^6ZoneService^7] ^3Zone ^7[^5%s^7] ^3has been removed due to ^7[^5%s^7] ^3resource stop."):format(self.resources[resource][i], resource));
87+
end
88+
self.resources[resource] = nil;
89+
end
90+
end
91+
92+
return self;
93+
94+
end);
95+
96+
return ZoneService;

internal/game/zone/index.lua

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require 'internal.game.zone.listeners';

internal/game/zone/listeners.lua

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
local zoneService = require 'internal.game.zone.ZoneService';
2+
3+
if (lib.is_server) then return; end
4+
5+
local PLAYER_PED_ID = PlayerPedId;
6+
local GET_ENTITY_COORDS = GetEntityCoords;
7+
8+
lib.events.on(eLibEvents.zoneAdd, function(zone)
9+
zoneService:Register(zone);
10+
end);
11+
12+
lib.events.on(eCitizenFXEvents.onResourceStop, function(resource)
13+
zoneService:RemoveByResource(resource);
14+
end);
15+
16+
lib.events.on(eLibEvents.zoneUpdate, function(zoneId, key, value)
17+
local zone = zoneService:Get(zoneId)
18+
if (typeof(zone) == 'InternalZone') then
19+
zone[key] = value;
20+
end
21+
end);
22+
23+
async(function()
24+
while true do
25+
local zones = zoneService:GetAll();
26+
local ped = PLAYER_PED_ID();
27+
local coords = GET_ENTITY_COORDS(ped);
28+
for zoneId, zone in pairs(zones) do
29+
if (typeof(zone) ~= 'InternalZone') then goto continue; end
30+
if (zone.position == nil or zone.size == 0) then
31+
goto continue;
32+
end
33+
local distance = #(coords - zone.position);
34+
if (distance <= zone.size) then
35+
if (not zone.active) then
36+
lib.events.emit(eLibEvents.zoneStateChange, zoneId, 'active', true);
37+
zone.active = true;
38+
end
39+
else
40+
if (zone.active) then
41+
lib.events.emit(eLibEvents.zoneStateChange, zoneId, 'active', false);
42+
zone.active = false;
43+
end
44+
end
45+
::continue::
46+
end
47+
async.wait(1000);
48+
end
49+
end);

internal/index.lua

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
require 'internal.version_check';
2-
require 'internal.events.index';
2+
require 'internal.events.index';
3+
require 'internal.game.index';

lib/config/get_valid.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
---@return any
33
return function(key)
44

5-
if (has_type(lib.config.default[key], 'Config')) then
5+
if (typeof(lib.config.default[key]) == 'Config') then
66

77
if (type(Config) == 'table') then
88

lib/config/get_valid_sub.lua

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
---@return any
44
return function(parent, key)
55

6-
if (has_type(lib.config.default[parent], 'Config')) then
6+
if (typeof(lib.config.default[parent]) == 'Config') then
77

88
if (lib.config.default[parent].type == 'table') then
99

1010
local config = lib.config.get(parent);
1111

12-
if (has_type(lib.config.default[parent].data[key], 'Config')) then
12+
if (typeof(lib.config.default[parent].data[key]) 'Config') then
1313
if (type(config[key]) == lib.config.default[parent].data[key].type) then
1414
return config[key];
1515
elseif (type(lib.config.default[parent].data[key].secondary_type) == 'string') then

lib/config/register_sub.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
---@param valueType string
55
---@param secondaryType string
66
return function(parent, key, value, valueType, secondaryType)
7-
if (has_type(lib.config.default[parent],'Config')) then
7+
if (typeof(lib.config.default[parent]) == 'Config') then
88
if (type(lib.config.default[parent].data[key]) ~= 'Config') then
99
lib.config.default[parent].data[key] = lib.config.class.config(value, valueType, secondaryType);
1010
else

0 commit comments

Comments
 (0)