GetEntityType() of specific props in MLO's always returns 0

Hello everyone,
the server I’m working on uses MLO’s. In those MLO’s some props are being used, that normally aren’t in the game.
FiveM offers a function to determine what type an entity has (GetEntityType()). Typically, props like chairs and benches would have type 3, because they are objects. But some chairs and benches that weren’t originally in the game return type 0 (==no entity) when given to GetEntityType().
Does somebody now how one could fix that? Would I be able to set the entity type in the XML files of the modded entities that are being used? And if so, what property would I have to change?

To give you some idea why this is so important for me: I want to make the world more interactive using qtarget. A friend and I are working on a script for sitting on all kinds of chairs and benches. The type problem has given us a bit of a headache, since qtarget checks if an entitys type is greater than 0 before getting it’s hash with GetEntityModel(). Otherwise it could lead to resource crashes if you’re looking onto some house.

In the FiveM source code GET_ENTITY_TYPE is defined inside the following file on the lines 355-385:
https://github.com/citizenfx/fivem/blob/f186f705a20b6c791a2c6f1944e5c271004266b4/code/components/citizen-server-impl/src/state/ServerGameState_Scripting.cpp

1 Like

Rather than trying to find out why a type is wrong, it might be better to look at where you are getting these entity handles from: if GET_ENTITY_TYPE doesn’t work, most other entity functions will also not work, as you are likely referring to a static object, where most script functions expect CPhysical.

Also, that code link likely has no relation to what you’re doing as that’s server-side and given your explanation it looks like you’re trying to do something client-side - however this is hard to confirm as you aren’t providing any specific code or ‘MLO’ metadata.

1 Like

Good evening,

thank you very much for the quick answer, @nta!

I have not been idle in the meantime. First of all, my assumption that the chair I meant was not an original game prop was wrong. I just didn’t find its hash on pages listing available props. (gta-objects, gtahash)

Also, I noted the answer that it depends on whether a prop is a static object or an entity. So I did some tests.

For this, I used the following objects that were already present in an MLO:

-1608185467 = apa_mp_h_stn_chairstrip_07
1546354612 = v_ret_ps_chair
-470815620 = bkr_prop_biker_boardchair01

As already mentioned, we use qtarget. This resource provides function to get the objects in the player’s crosshairs with a raycast, the raycast() function.
The following is the code for the raycast() function:

local RaycastCamera = function(flag)
	local cam = GetGameplayCamCoord()
	local direction = GetGameplayCamRot()
	direction = vec2(math.rad(direction.x), math.rad(direction.z))
	local num = math.abs(math.cos(direction.x))
	direction = vec3((-math.sin(direction.y) * num), (math.cos(direction.y) * num), math.sin(direction.x))
	local destination = vec3(cam.x + direction.x * 30, cam.y + direction.y * 30, cam.z + direction.z * 30)
	local rayHandle = StartShapeTestLosProbe(cam, destination, flag or -1, playerPed or PlayerPedId(), 0)
	while true do
		Wait(2)
		local result, _, endCoords, _, materialHash, entityHit = GetShapeTestResultIncludingMaterial(rayHandle)
		if result ~= 1 then
			local entityType
			if entityHit then entityType = GetEntityType(entityHit) end
			return flag, endCoords, entityHit, entityType or 0
		end
	end
end
exports("raycast", RaycastCamera)

The complete code of qtarget can be found under the following link: GitHub - overextended/qtarget: Use ox_target instead.

For testing I used an ID-Gun, which uses the raycast() function and lists some data from the received entity.
Here is the code of the ID-Gun:

Citizen.CreateThread(function()
    while true do
        local pause = 0                                  
        if infoOn then                                     
            local player = PlayerPedId()                    
            if IsPlayerFreeAiming(PlayerId()) then          
                local _,_,entity,_ = exports.qtarget:raycast()    
                local coords = GetEntityCoords(entity)      
                local heading = GetEntityHeading(entity)    
                local model = GetEntityModel(entity)
                coordsText = coords
                headingText = heading
                modelText = model
                entityText = entity
                typeText = GetEntityType(entity)
                nentityText = NetworkGetNetworkIdFromEntity(entity)
                ownerText = NetworkGetEntityOwner(entity)
                SendNUIMessage({
                    coords = model
                })
            end
            DrawInfos("\nHash: " .. modelText .. "\nID: " .. entityText .. "\nNID: " .. nentityText .. "\nOwner: " .. ownerText .. "\nType: " .. typeText)
        end
        Citizen.Wait(pause)
    end
end)

It’s important to note here that ID-Gun normally relied on GetEntityPlayerIsFreeAimingAt() to display the entity data for the entity the player is looking at. However, during the development process we decided to use the qtarget-raycast function for the ID-Gun, because GetEntityPlayerIsFreeAimingAt() did not return any entity data for some chairs and tables, after which, according to your answer, @nta, they are estimated to be static objects.

Here are the interior objects tested, with their definitions in the interior-ytype file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<CMapTypes>
  <extensions/>
  <archetypes>
    <Item type="CMloArchetypeDef">
      <lodDist value="150.00000000"/>
      <flags value="0"/>
      <specialAttribute value="0"/>
      <bbMin x="0.00000000" y="0.00000000" z="0.00000000"/>
      <bbMax x="0.00000000" y="0.00000000" z="0.00000000"/>
      <bsCentre x="0.00000000" y="0.00000000" z="0.00000000"/>
      <bsRadius value="150.00000000"/>
      <hdTextureDist value="50.00000000"/>
      <name>int_taxi</name>
      <textureDictionary/>
      <clipDictionary/>
      <drawableDictionary/>
      <physicsDictionary>int_taxi</physicsDictionary>
      <assetType>ASSET_TYPE_ASSETLESS</assetType>
      <assetName>int_taxi</assetName>
      <extensions/>
      <mloFlags value="0"/>
      <entities>
        <Item type="CEntityDef">
          <archetypeName>apa_mp_h_stn_chairstrip_07</archetypeName>
          <flags value="32"/>
          <guid value="0"/>
          <position x="-1.43076900" y="16.23474000" z="-0.49271000"/>
          <rotation x="0.00000000" y="0.00000000" z="-0.99998070" w="-0.00621864"/>
          <scaleXY value="1.00000000"/>
          <scaleZ value="1.00000000"/>
          <parentIndex value="-1"/>
          <lodDist value="500.00000000"/>
          <childLodDist value="500.00000000"/>
          <lodLevel>LODTYPES_DEPTH_HD</lodLevel>
          <numChildren value="0"/>
          <priorityLevel>PRI_REQUIRED</priorityLevel>
          <extensions/>
          <ambientOcclusionMultiplier value="255"/>
          <artificialAmbientOcclusion value="255"/>
          <tintValue value="0"/>
        </Item>
        <Item type="CEntityDef">
          <archetypeName>v_ret_ps_chair</archetypeName>
          <flags value="32"/>
          <guid value="0"/>
          <position x="-6.41844300" y="20.87214000" z="-0.49271000"/>
          <rotation x="0.00000000" y="0.00000000" z="-0.98152120" w="0.19135360"/>
          <scaleXY value="1.00000000"/>
          <scaleZ value="1.00000000"/>
          <parentIndex value="-1"/>
          <lodDist value="500.00000000"/>
          <childLodDist value="500.00000000"/>
          <lodLevel>LODTYPES_DEPTH_HD</lodLevel>
          <numChildren value="0"/>
          <priorityLevel>PRI_REQUIRED</priorityLevel>
          <extensions/>
          <ambientOcclusionMultiplier value="255"/>
          <artificialAmbientOcclusion value="255"/>
          <tintValue value="0"/>
        </Item>
        <Item type="CEntityDef">
          <archetypeName>bkr_prop_biker_boardchair01</archetypeName>
          <flags value="32"/>
          <guid value="0"/>
          <position x="-0.29756710" y="26.37279000" z="0.11143000"/>
          <rotation x="0.00000000" y="0.00000000" z="0.58834650" w="0.80860900"/>
          <scaleXY value="1.00000000"/>
          <scaleZ value="1.00000000"/>
          <parentIndex value="-1"/>
          <lodDist value="500.00000000"/>
          <childLodDist value="500.00000000"/>
          <lodLevel>LODTYPES_DEPTH_HD</lodLevel>
          <numChildren value="0"/>
          <priorityLevel>PRI_REQUIRED</priorityLevel>
          <extensions/>
          <ambientOcclusionMultiplier value="255"/>
          <artificialAmbientOcclusion value="255"/>
          <tintValue value="0"/>
        </Item>
      </entities>
      <entitySets/>
      <timeCycleModifiers/>
    </Item>
  </archetypes>
  <name>int_taxi</name>
  <dependencies/>
  <compositeEntityTypes/>
</CMapTypes>

According to the XML-file now the pictures of the ID-gun outputs:


BigChair (2)
(Type 0 and therefor a static object?)


NobleChair (2)
(Type 0 and therefor a static object?)


OfficeChair (2)
(Type 3 and therefor an entity?)

Why is it so important to me to get back entities with an entity type>0 for these chairs? qtarget checks if the type of an entity is>0 to avoid accidentally executing GetEntityModel() on a house or a house interior, which would crash the resource. And since qtarget needs to check which EntityModel is present to display appropriate interaction options, it is important for me to get this to run.
The following is an error that occurred because GetEntityModel was executed on an interior:

The most important question that arises at the end is what distinguishes an entity and a static object, and how to determine whether an object is an entity or a static object. Does this require definition in an MLO file, or setting specific metadata to objects in the game files?
If setting these values is not possible, which natives are recommended to achieve my goal?

Thank you very much and have a nice day!

1 Like

Right, it’s interesting that some entity natives still work for static objects like such.

I believe it’s either a flag in the CBaseArchetypeDef or CEntityDef that determines whether or not an entity is going to be static (CBuilding) or dynamic (CObject). CodeWalker’s editing tools in their ‘project window’ - make sure to download the latest from their Discord chat as for whatever reason some other places link outdated versions - should have a visualization for the flags that are set without having to manually deal with the bit fields. I believe newer versions should also be able to load an entire stream/ folder in the project window right away, making it even easier to check on this.

1 Like

Hello,

thank you again @nta, as assumed a flag in CBaseArchetypeDef was responsible. (131072 - Dynamic)
Subsequently setting the flag and streaming the changed archetype brought the desired result. I placed the changes in the Interiour .ytyp file. The chair “v_ret_ps_chair”, which originally returned 0 with GetEntityType(), is now of type CObject and returns EntityType 3.

For all those who also encounter this problem, here is the content of the changed CBaseArchetypeDef:

    <Item type="CBaseArchetypeDef">
      <lodDist value="20.00000000"/>
      <flags value="549584896"/>
      <specialAttribute value="0"/>
      <bbMin x="-0.54568100" y="-0.47923800" z="0.00046300"/>
      <bbMax x="0.54568000" y="0.47924000" z="0.68781400"/>
      <bsCentre x="-0.00000048" y="0.00000098" z="0.34413850"/>
      <bsRadius value="8034613.00000000"/>
      <hdTextureDist value="6.00000000"/>
      <name>v_ret_ps_chair</name>
      <textureDictionary>v_ret_pons_chair</textureDictionary>
      <clipDictionary/>
      <drawableDictionary/>
      <physicsDictionary>v_ret_pons</physicsDictionary>
      <assetType>ASSET_TYPE_DRAWABLE</assetType>
      <assetName>v_ret_ps_chair</assetName>
      <extensions/>
    </Item>

(flags before the change: 549453824)
An overview of the flags of CBaseArchetypeDef can be found in Codewalker after selecting an entity and clicking on “Edit Archetype” in the project window.

However, after some testing, I suspect that this change is limited to the MLO that contains the change, and in other MLO’s the flag change is not applied. Am I correct in my assumption? Additionally, after the change in other MLO’s that did not have the change defined in the BaseArchetypeDef in their own .ytyp files, the affected chairs were no longer visible. How can I stream the change globally for all MLOs?

H-huh?

If you’re redefining an archetype from another .#typ, don’t. The game will not handle duplicate definitions well and at times will crash with very vague errors.

Either rename the name of the duplicate archetype (+ the same name in all entity definitions that you want changed), or replace the original .#typ file (still not recommended, this has a few other concerns).

1 Like

If you’re redefining an archetype from another .#typ, don’t.

Thank you for pointing that out @nta, but that was not my plan. I expressed myself too vaguely in that respect.

I actually only meant overwriting the archetypes already integrated into the game. So no double definition in several MLO’s. That should be possible without any problems, right? (See my redefinition of “v_ret_ps_chair”, I have already tested it and at first glance there were no problems with it, except that some chairs of the same type seemed to be hidden in a different MLO… That’s why I asked the question.)

Or is it also recommended here to create a new archetype with its own name and the correct flag instead of a redefinition, as recommended in your last sentence?

That’s still a double definition: the base game file and whatever defines your interior.

Good evening,

I have one more question: Would I be able to stream the original gamefile with my own modifications? Would that overwrite the gamefile and use my custom archetype-definition?

Unfortunately, I am not at home at the moment and therefore cannot test it, but I wanted to ask the question because this idea came to my mind.

Yeah, that would work fine, might lead to some other issues as well however which is why copying the definition with a different name is recommended.

Good evening @nta,

I would like to conclude by thanking you once again for the really helpful information you have provided. It has brought me a lot forward in a short time.

Have a nice day!

Hey, i’ve ran into this issue myself as i require the EntityType as apart of one of my checks.
I’ve tried applying the dynamic flag to the entity replacing the gamefiles by streaming it however it still returns 0 for GetEntityType.

Was there anything else in particular you did?

Hello @Zehaava,

I followed the instructions given by d-bubble from the post which is marked as the solution.

It is important not to confuse Archetype- and Entity definitions.
(as mentioned:

)

Create your own archetype definition for the entities you want to set as dynamic. You can do that by:

So in the end your new archetype has a different name and different flags, but the other data is still the same.
You can then set the archetype in all entities you want to change.

2 Likes

I gave this a try, creating new CBaseArchetypeDef definitions that minor the originals just with new names, and then updated my CEntityDef definitions, but the props now don’t appear in my MLO at all. Some searching around suggested that the archetype name must exactly match the model name, but that sounds contradictory to this whole post. Any ideas what I might have missed? Cheers