Coder Social home page Coder Social logo

mkafrin / polyzone Goto Github PK

View Code? Open in Web Editor NEW
180.0 11.0 183.0 142 KB

PolyZone is a FiveM mod to define zones of different shapes and test whether a point is inside or outside of the zone

License: MIT License

Lua 100.00%
lua fivem fivem-mod

polyzone's Introduction

PolyZone

PolyZone is a FiveM mod to define zones of different shapes and test whether a point is inside or outside of the zone

PolyZone around the prison

Download

Click here to go to the releases page and download the latest release

Using PolyZone in a Script

In order to use PolyZone in your script, you must at least include PolyZone's client.lua directly in your __resource.lua or fxmanifest.lua. You can do that by using FiveM's @ syntax for importing resource files:

client_scripts {
    '@PolyZone/client.lua',
    'your_scripts_client.lua',
}

This will allow you to create PolyZones in your script, but will not import other zones, such as CircleZone, BoxZone, etc. All the other zones are extra, and require their own explicit imports. Here is a client_scripts value that will include all the zones. Note the relative order of these imports, as the ordering is necessary! Many zones rely on each other, for example EntityZone inherits from BoxZone, and all zones inherit from PolyZone (client.lua).

client_scripts {
  '@PolyZone/client.lua',
  '@PolyZone/BoxZone.lua',
  '@PolyZone/EntityZone.lua',
  '@PolyZone/CircleZone.lua',
  '@PolyZone/ComboZone.lua',
  'your_scripts_client.lua'
}

Documentation

For additional information on how to use PolyZone, please take a look at the wiki

Troubleshooting and Support

For help troubleshooting issues you've encountered (that aren't in the FAQ), or to suggest new features, use the issues page. Just a reminder though, I do this in my free time and so there is no guarantee an issue will be fixed or a feature will be added. In lieu of my limited time, I will prioritize issues and bugs over features.

FAQ - Frequently Asked Questions

I'm getting the error attempt to index a nil value when creating a zone, what's wrong?

Did you include all the necessary scripts in your __resource.lua or fxmanifest.lua? Remember some zones require other zones, like EntityZone.lua requires BoxZone.lua and BoxZone.lua requires client.lua.

I'm getting no errors, but I can't see my zone in the right place when I turn on debug drawing

If you are using them, is minZ and maxZ set correctly? Or if you are using a CircleZone with useZ=true, is your center's Z value correct? If using a PolyZone, did you manually select all your points, or use the creation script? If you did it manually, the ordering of the points could be causing issues. Are you using the correct option to enable debug drawing? For PolyZones, you can use debugPoly and debugGrid, but for other zones, debugPoly is the only one that works.

Is PolyZone faster than a distance check?

There's a page in the wiki for that, here.

License

Please see the LICENSE file. That file will always overrule anything mentioned in the README.md or wiki

polyzone's People

Contributors

mkafrin avatar mkeefeus avatar petrisgr avatar russianronin avatar spudgun avatar user123441221 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polyzone's Issues

pzcreate shortcut

Allow users to put all the info in pzcreate inline with the command to avoid the popup text boxes. For example, instead of doing "pzcreate circle" and then putting the name and radius in the text boxes, you'd just do "pzcreate circle circle1 3.0".

[Features] Add exports

Hello,

I develop in JS, and I can't use the LUA metatables, would it be possible to export the functions ?

Thank's !
I like your script

Combo Zone principal

Hi!

I don't know if it's a bug, but probably it should work that way. For example, if you teleport to different zone in same combo, it doesn't trigger PlayerInOut so for example I cannot get that zone metadata until I reenter zone. Maybe I'm just using it wrong?

For example:

local box1 = BoxZone:Create(vector3(344.37, -586.21, 28.8), 1, 1, {
  name="box1",
  debugPoly=false,
  minZ=27.8,
  maxZ=31.0,
  data={
      current = "box1"
  }
})

local box2 = BoxZone:Create(vector3(339.23, -584.14, 74.16), 1, 1, {
  name="box2",
  debugPoly=false,
  minZ=73.16,
  maxZ=75.16,
  data={
      current = "box2"
  }
})

local combo = ComboZone:Create({box1, box2}, {
    name="boxes",
    debugPoly=false
});

combo:onPlayerInOut(function(isPointInside, point, zone)
    if zone then
        print(zone.data.current)
        TriggerEvent('someEventWhichHandelsSameThing', zone.data)
    end
end)

If you enter any zone and teleport to other zone without leaving it (eg.: using SetEntityCoords() method). it's not retriggered and metadata is not updated. Like I said, maybe I'm using it the wrong way? Because as far wiki reaches, onPlayerInOut on individual zones doesn't return metadata. But maybe it could?

Separate minZ and maxZ checks

Checks for minZ and maxZ are done in the same if statement, so you have to have both, even if you only want one.

if minZ and maxZ and (z < minZ or z > maxZ) then

If there is no significant performance degradation, separate them to allow this functionality.

Question about combozones

So i'm trying to make an alarm script for the VIP's houses but is like 40 polyzones and i want to know if is possible to create combozones for polyzones...

The script is going to notify the house owner if anyone try to get in the house.

So i just need to the polyzone give the name of the zone if it's possible to create an combozones for polyzones

Some wiki was un-accessible

When I went to "Additional helper functions" page in wiki. It's say "You do not have permission to update this wiki."

Change commands to use events

Switch commands from using anonymous functions passed to RegisterCommand to using events, in order to accommodate alternative command systems

Possible performance improvement to grid calculation

If I understand the math correctly, min should be able to be added to x and y one time, instead of adding it to every vector. Ex) local x = cellX * gridCellWidth + min.x

PolyZone/client.lua

Lines 163 to 173 in d5c8462

local x = cellX * gridCellWidth
local y = cellY * gridCellHeight
local min = poly.min
-- poly.min must be added to all the points, in order to shift the grid cell to poly's starting position
return {
vector2(x, y) + min,
vector2(x + gridCellWidth, y) + min,
vector2(x + gridCellWidth, y + gridCellHeight) + min,
vector2(x, y + gridCellHeight) + min,
vector2(x, y) + min
}

debugBlip option

Add debugBlip option that will place a blip on the map where the zone is. For ComboZones, this should place a blip for all zones in the ComboZone, and also print out the number of zones in the ComboZone, and maybe a breakdown of their types (BoxZone, CircleZone, etc).

Metatables don't transfer when zones returned from exports

Exports don't support metatables, so the functions of a zone aren't being transferred when a zone is returned from an export. The best way I see to fix this is to have an ensureMetatable() function that re-connects the metatable to the zone instance. It is boilerplate and annoying, but necessary given the limitations of exports.

Permissions for create functions

Is there any type of ACE perms or anything on the creation script or would anyone be able to access it? I'd like to restrict it to just our staff team.

Lazy PolyZone grid creation

Would it be possible to lazily compute the PolyZone grid optimization? In other words, instead of building the entire grid at zone creation, the grid would stay empty until a point in the zone was tested, and then the grid cell that point correlates with would be computed and cached. That way you save massively on memory if the zone is never interacted with or only interacted with at specific points, and brings the startup performance cost to nearly zero. Also this might make it worthwhile to increase gridDivisions across the board since the grid creation cost would be amortized over a much larger period of time.

After a brief look over the code, I don't readily see any barriers to doing this, though care would need to be taken for situations like when drawGrid is turned on, since when that is the case, you'd have to build the whole grid at zone creation.

Alternative:
One possible alternative would be to lazily compute the entire grid upon first point in poly test, rather than lazily computing each grid cell. This would still give some of the memory and startup performance benefits, but could cause lag spikes during gameplay depending on the complexity of the zone and lose some other benefits of the prior option, like the ability to increase gridDivisions.

Event data amplification concerns

Hi,

as dbub pointed at in a discord conversion, having an event that resend all data to all clients from a single event without any verification is bad pratices.
Example : Some cheats just spam the event with massive chunk of data, the server just send it through all clients leading to network overflow.

Possible solutions :

  • Remove this feature if it doesn't see a lot of use
  • Replace this feature with preconfigured data vars
  • Verify for a valid data schema
  • Limit the sending of the event to certains clients in certains conditions only

I would have made a PR proposing some solution but I don't really understand what this event is for. (event from reading the original commit description i'm not sure why this feature exist in the first place)
The resources I read before making this PR, useful for context :

An different solution would be to create server-side checks for PolyZone, it would actually be useful to implement PolyZone server-side now that we have full knowledge of the entities position on Onesync.

The goal of this issue is not to shame the implementation or usage of this resource, just to open a discussion about modifications on this useful resource.

Height option for BoxZones

"height" option on BoxZones, that will set the minZ to the ground's Z where the zone's center is, and the maxZ to that plus the "height" value. So you could easily make any number of zones the same height without having to manually put in minZ and maxZ

[Bug] Z Scale in BoxZones

Hi, I've observed that the scale in the boxzone doesn't work.

Currently, I was this BoxZone's code.

BoxZone:Create(v.outdoor, 2.0, 2.0, {
  name = tostring(_ .. 'outdoor'),
  scale = {0.75, 0.75, 0.35, 0.35, 0.25, 0.75},
  debugPoly = true
})

The BoxZone that's created is way bigger in height that was is supposed to be.
image

Thanks for information/fix.

Circle entityzone?

Not an issue but wondering if it is posssible to give the option to create a circle entity zone rather than just a box zone?

Helper Function for isPointInside check

Create a helper function that takes in two callback functions, one that returns the point to be checked and the other that will be called anytime that point enters or exits the zone.

Implementation choices:
Create a new thread for every new helper setup
Create a table of point callbacks and one for enter/exit zone callbacks, then do all checks and calls in one thread

Question about object from server

If I create a object server side, how can I do has I do for my client:

redTeamBox:onPointInOut(function() return GetEntityCoords(soccerBall) end, function(isPointInside, point)
    if insideBlueGoal then
	DeleteObject(soccerBall)
        ESX.showNotification('Goal from red team!')
        if redScore < 7 then
            redScore = redScore + 1
            TriggerServerEvent('grz_rl:goalScore', red)
        else
            TriggerServerEvent('grz_rl:endGame', red) -- After 7 goals // end of game
        end
        return false
    end
end)

But for server side?

Separate out Poly zones and entity zones and create new zones

More zones are needed, like circle zones and box zones. Even though circle zones are just a distance check, all the helpers and QoL features in PolyZone are still quite helpful in that case. And box zones can be super optimized (already mostly how entity zones work) and are a common case.

At the same time, the code has already got unruly by shoving entity zones into the existing code and trying to keep everything in one file. That made sense for Poly zones, but at some point separation makes sense. Given we're going to be adding new zones, I think it makes more sense to have Poly zones be the only thing in the client.lua file, and have all the rest of the zones be in separate files that can be included as extensions of PolyZone. This will require decoupling the entity zone code from the original functions, and figuring out the best way to do inheritance in lua, but both are possible.

Lastly, there is one last problem to solve that can be solved by one last new zone type. If you have many zones in one resource that are all doing the same thing (think a box zones at the front desk of all the banks), using the helpers will spawn a new helper for each zone and be doing tons of duplicate work. I can't think of a way to handle this implicitly (automagically) that isn't crazy complex, but I think it can be done well explictly with a Combo zone (or Multi zone or something like that). Basically it's a zone that takes a list of other zones and the functions act on ALL the zones and therefore can easily coordinate duplicate work. No implicit orchestration needed.

Error with PoliZone

SCRIPT ERROR: @PolyZone/BoxZone.lua:76: attempt to index a nil value (local 'center')
Screenshot 2022-04-30 022844

minZ and maxZ for CircleZones (Cylinders)

Right now, CircleZones can only use the "useZ" option, which switches them back and forth from "circle" mode and "sphere" mode. We could add a third "cylinder" mode, by enabling the use of minZ and maxZ. This is only worth it IMO if the performance hit isn't too big.

Creation would have to be updated as well, but we could model the changes off of how BoxZones handle minZ and maxZ. Also in the process it would be good to add a way to move the CircleZone up and down when in "sphere" mode.

Using KVP to cache PolyZone grid and grid lines

Calculating the grid points and grid lines for PolyZones is incredibly expensive and never changes unless you move the points of the zone. Can this just be cached after the first calculation? Maybe using a JSON string stored in KVP or something similar? I'd guess most people are never moving their PolyZones around after creating them. The key could be a hash of the points in the zone.

Resetting keybinds?

i cant use my scroll down to adjust the polyzone anymore, it was working fine previously. how do i fix this? can i reset the keybind?

Question?

Is there currently a way to check to see if there is a anyone in a polyzone. What I would like to do is if everyone left a zone, then, remove a ped. If one person is still in the polyzone the ped is still there.

[Not an issue] Delete all vehicles in zone

Hello, I'd like to use a karting map and I've a problem inside it. Some npcs vehicles are spawning, I'd like to know if there a way with PolyZone to delete each vehicle which is not whitelisted in my config ? (I know how to configure a WL but I don't know what I should do to use my PolyZone like this)

Thank for your help, this tool is amazing !

Add onEntityDamaged helper

This helper is mostly to easily allow the caller to destroy an entity zone when the entity dies or is destroyed. But might as well generalize it to all damage.

This is really efficient because it can piggyback off of the CEvent "game events" that are triggered (meaning no on-frame check). Specifically, the event is "CEventNetworkEntityDamage", which includes "victim" at arg[1], "attacker" at arg[2], "victimDied" at arg[4], "weaponHash" at arg[5], "isMelee" at arg[10], and "vehicleDamageTypeFlag" at arg[11].

My thoughts on an api is:

zone:onEntityDamaged(function(entityDied, attacker, weaponHash, isMelee)
    print("stuff here")
end)

and the main use would be:

zone:onEntityDamaged(function(entityDied)
    if entityDied then zone:destroy() end
end)

Honestly, given the lack of anyone upgrading yet, might be a good idea to just slot this into 1.2.

Sources:
https://vespura.com/fivem/damageevents/
https://github.com/DevTestingPizza/DamageEvents/blob/v1.0.0/DamageEvents/DamageEvents.cs#L188

Failed Load

image
I unfortunately am no longer able to use latest artifacts, so had to install the Cayo Perico streamed map, which requires your PolyZone. Upon initial installation I receive this message, with no indication of why it failed. If I restart polyzone while in game, I get no error though. Is there something I'm missing like waiting for spawn?

Not an issue, more an question..

Hey, i've read the Wiki of this repo, but i can't find out what i want..

Is there an way to create an polyzone and when the player enters or leaves the zone it only executes the code, instead of looping the code when the player is in the zone?

Thnx.

Adding Zones

Could I get some examples on ComboZone AddZone().

Support EntityZones inside ComboZones

EntityZones won't work properly in ComboZones currently because of the grid optimization assuming zones are static positionally. EntityZones should probably just be stored in a separate list in ComboZones to get around this.

Explore drawing walls of zone with DrawPoly instead of DrawLine

Look into the performance of drawing the walls of the zone with DrawPoly instead of DrawLine

DrawPoly can only draw triangles, so you'd need two calls to make the rectangle necessary for the wall. Also it only draws the poly in one direction (see the native docs for more info), so to make both sides viewable, you'd need an additional two calls, for a total of 4 native calls per wall. This still is probably less than the number of DrawLine calls normally made for each wall currently, but actual testing would be needed to determine the performance impact.

[not an issue] help

i wanted to use PolyZone in combination with qtarget to make a doorlock script but if i do this:
test1 = GetClosestObjectOfType(482.2, -999.4, 30.8, 1.0, 165994623, false, false, false)
exports.qtarget:AddEntityZone("test", test1, {
debugPoly=true,
useZ = true
}, {
options = {
{
icon = 'fas fa-shopping-basket',
label = "test",
action = function()
-- some code
end
},
},distance = 2.5

})
i get this:
image
the issue is now to center the zone on the door.
do you have any idea how i can do it? maybe some offset which could be implemented in PolyZone
my discord is ๐“œ๐“ช๐”๐“ช๐“œ๐“ช๐”#5405

Further optimization of ComboZones

Dynamic waits, grid system (not to confuse with PolyZones grid), etc. What other ways can we trade off some memory for performance, since we have such low memory usage? Can we hit 1000 zones at 0.01ms?

Server-side knowledge of players in zones

The server should know what players are in what zones so events can be sent to everyone in or outside of a zone.

  • Whenever a player enter or leaves a zone, an event should be sent to the server with the zone (probably by name) and it'll keep a dict of zones to list of players inside of it.
  • Add an export or event on the server where you put in a zone and a function and it will run that function once for everyone in the zone.
  • Add an export to set an event-based callback that will run whenever the players inside a zone changes

Alternative:

  • Add a function to zones called "AddTrigger(triggerName, triggerCallback)"
    • This will create an event handler for the triggername which calls the triggercallback if the player is inside the zone
  • Add a RPC or event server-side called "PolyZone:TriggerZoneEvent"(triggerName) or something similar
    • This event will send the trigger event to all clients and then the event handler on the client will do the rest

Moving zones

Moving zones might be possible with minimal performance impact. Initial thought is that an offset can be stored when the zone is moved by subtracting the new position from the original one, and then the offset is added to the necessary values to offset the math to the correct position.

Questions:
What could this be used for?
What performance impact does it have?
What complexity impact does it have?
What changes to the api are necessary?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.