citizenfx / fivem

The source code for the Cfx.re modification frameworks, such as FiveM, RedM and LibertyM, as well as FXServer.
https://cfx.re/
3.58k stars 2.12k forks source link

[BUG] AddDoorToSystem native rounds x, y, z values to integers #1602

Closed jag3dagster closed 2 years ago

jag3dagster commented 2 years ago

Description When adding doors to the door system to add locks, if two of the same archetype of door are at coordinates that have coordinates at the same rounded integer values, they conflict and only the first door registered is added to the door lock system.

i.e. ADD_DOOR_TO_SYSTEM treats the following vectors as the same location vec3(189.577179, -929.293335, 30.875042) vec3(189.877182, -929.6633, 30.875042)

https://docs.fivem.net/natives/?_0x6F8838D03D1DC226 void ADD_DOOR_TO_SYSTEM(Hash doorHash, Hash modelHash, float x, float y, float z, BOOL p5, BOOL scriptDoor, BOOL isLocal);

Expected When adding doors with the same archetype at different float coordinates, all doors get added to the door system.

Actual Only the first door added to the door system gets registered to the door system and any following doors are not registered.

Repro

  1. Load up the following resource brokendoor.zip
  2. Go to the middle of Legion Square vec3(189.0, -929.0, 30.0)
  3. Observe that one door is locked in place while the other door swings freely (they should both be locked)
blattersturm commented 2 years ago

This isn't a place for discussing scripting/game behavior, and I don't think this is a 'bug' in this context either.

Try the forums.

jag3dagster commented 2 years ago

...and I don't think this is a 'bug' in this context either

As a first time poster here, mind if I ask for some clarification on why you don't see this behavior as a 'bug'?

Lucas7yoshi commented 2 years ago

...and I don't think this is a 'bug' in this context either

As a first time poster here, mind if I ask for some clarification on why you don't see this behavior as a 'bug'?

I'm not him, but this behaviour is likely like this as a result of Rockstars code, and fixing it would involve patching an otherwised unchanged native to effectively add functionality where rockstar deemed it not necessary for whatever reason. If its behaving as it does in regular GTA, its not a bug, and requesting anything otherwise would be effectively asking for new functionality, which would be a feature request.

lvto2000 commented 8 months ago

...and I don't think this is a 'bug' in this context either

As a first time poster here, mind if I ask for some clarification on why you don't see this behavior as a 'bug'?

I'm not him, but this behaviour is likely like this as a result of Rockstars code, and fixing it would involve patching an otherwised unchanged native to effectively add functionality where rockstar deemed it not necessary for whatever reason. If its behaving as it does in regular GTA, its not a bug, and requesting anything otherwise would be effectively asking for new functionality, which would be a feature request.

Not sure I get why this is a good and the only answer. Seems to be more speculation about what could have happened vs. what did happen.

gottfriedleibniz commented 8 months ago

Seems to be more speculation about what could have happened vs. what did happen.

This unfortunately is the case: the packing/hashing algorithm rounds the position before bit-twiddling. This is explicit in game assembly and is the culprit here.

Speculation: Since this system interfaces with other game components (interiors, game saving, replay editor), floating point inaccuracies/differences will certainly be a problem. Replacing that packing/hash subroutine with something less sensitive (e.g., include one decimal point of precision) is possible, but still susceptible to unknown regressions elsewhere.

lvto2000 commented 8 months ago

I have another but possibly related approach to fixing this issue. Generally speaking, when the coordinates are close enough for this anomaly to occur, then it is very likely that the model name for each conflicting door are very similar if not exactly the same. My experience is that double doors share very similar coordinates and model names in some cases. As an example, if you are like me then you may have received a large quantity of door names and locations in a flat text file with both single and double doors. In my case, I created an automated maintenance program to sift through that large flat text file then build a better json file for more conducive parameters to support the Door System functions. I keyed on certain model name values and vectors coordinates. I assuming there are enough differences in model names to not risk conflicts.

My maintenance program was designed to read the large text file with all door names and coordinates then spit out a json file to support automated use of the AddDoorToSystem and DoorSystemSetDoorState functions. So if the flat file had the following entries: As an example if I had two doors as a part of a double door location:

   Door 1:  model name: `v_prod_door_backroom`  vector: vector3(1.111, 2.222, 3.333) 
   Door 2:  model name: `v_prod_door_backroom`  vector: vector3(1.999, 2.555, 3.343)

I assumed that since Rockstar was able to get away with having two model names with exactly the same values and similar but not equal vector coordinates, then I could too for the output values everywhere in the resulting json file. So, the resulting and VERY WRONG output from my maintenance program produced in the json file that looked like the following:


   Config = {}

   Config.Doors = {

    ["v_prod_door_backroom"] = {
       DoorHash = `v_prod_door_backroom`,
       ModelHash = `v_prod_door_backroom`,
       vector = vector3(1.111, 2.222, 3.333),
    },
    ["v_prod_door_backroom"] = {
       DoorHash = `v_prod_door_backroom`,
       ModelHash = `v_prod_door_backroom`,
       vector = vector3(1.999, 2.555, 3.343),
    }
   };

So the resulting use of DoorSystemSetDoorState function calls when fed each of these values above created significant silent conflicts that produced no errors. If you got the problem immediately by looking at the short code snippet here then congratulations Mr. or Ms obvious. Very easy to find here. The problem is more subtle when considering very large files with hundreds of lines of model names and coordinates. Consider that and assuming that Rockstar made these names unique, then there is a problem.

So summing this up, if you have double doors or at least doors that are very close in proximity with the same model names in a large file you have programmatically processed, you will need to look for duplicates for array names and DoorHash names if you followed a similar approach like mine where you allowed another program to sift through a larger text file containing many other coordinates and model names. In that case, mistakes can and will happen. Under the fivem Door System, you absolutely must make the array names and DoorHash names unique for each entry even though the model names may be the same. So if you write a program to sift through a text file to then create entries then those entries should look like the following:

Config = {}
Config.Doors = {

     ["v_prod_door_backroom4343"] = {
       DoorHash = `v_prod_door_backroom12321`,
       ModelHash = `v_prod_door_backroom`,
       vector = vector3(1.111, 2.222, 3.333),
     },
     ["v_prod_door_backroom3453"] = {
       DoorHash = `v_prod_door_backroom12121`,
       ModelHash = `v_prod_door_backroom`,
       vector = vector3(1.999, 2.555, 3.343),
     }
};

Hopefully this helps someone. It just does not sit well with me when trolls come to these forums and instead of adding or contributing to answers they feel are beneath them, they admonish the folks asking questions. If I can't help then I stay quiet. Hopefully this helped someone.

gottfriedleibniz commented 8 months ago

In the case of custom assets -- at least ones you control -- you should be able to work around this by duplicating the archetype, e.g., model_l and model_r (or front vs. back, etc.)