Rendering multiple entities OnWorldObjectStreamIn/Out callback gets called multiple times
kyro95 opened this issue · comments
Description of the problem
When rendering multiple entities OnWorldObjectStreamIn/Out gets called multiple times for the second entity.
Two entities in the same range (doesn't work fine)
Grand.Theft.Auto.V.2023.09.24.-.14.26.51.01.mp4
Single entity in the same range (works fine)
Grand.Theft.Auto.V.2023.09.24.-.14.29.11.02.mp4
Reproduction steps
Example;
There are within the same range two virtual entities.
Steps =>
- Render the first virtual entity, it gets rendered correctly,
- Render the second virtual entity and go toward the area of the second virtual entity
OnWorldObjectStreamIn/Out will be get called multiple times on the second virtual entity.
namespace Armonia.Client.Handler.House;
public class HouseMarkerHandler
{
private Hashtable _markers;
private readonly ChatService _chatService;
public HouseMarkerHandler(ChatService chatService)
{
_chatService = chatService;
_markers = new();
Alt.OnWorldObjectStreamIn += OnWorldObjectStreamIn;
Alt.OnWorldObjectStreamOut += OnWorldObjectStreamOut;
}
private void OnWorldObjectStreamIn(IWorldObject target)
{
if (worldObject is not IVirtualEntity entity)
return;
var entity = (IVirtualEntity) target;
var position = entity.Position;
position.Z -= 1.0f;
entity.GetStreamSyncedMetaData<string>("id", out var id);
_chatService.SendMessage($"Debug: Called OnStreamedIn with id {id}");
if (_markers.Contains(id))
{
_chatService.SendMessage("Debug: Called OnStreamedIn but marker already exists");
return;
}
var marker = Alt.CreateMarker(MarkerType.MarkerCylinder, position, new Rgba(247, 2, 1, 255), false, 0);
_markers.Add(id, marker);
marker.Scale = new Vector3(1.5f, 1.5f, 1.5f);
}
private void OnWorldObjectStreamOut(IWorldObject target)
{
if (worldObject is not IVirtualEntity entity)
return;
var entity = (IVirtualEntity) target;
entity.GetStreamSyncedMetaData<string>("id", out var id);
_chatService.SendMessage($"Debug: Called OnStreamedOut with id {id}");
if (!_markers.Contains(id))
{
_chatService.SendMessage("Debug: Called OnStreamedOut but marker not found");
return;
}
IMarker marker = (IMarker)_markers[id]!;
_markers.Remove(id);
marker.Destroy();
}
}
Expected behaviour
OnWorldObjectStreamIn/Out with multiple entities should be called once when entering that area and once when leaving that area
(the actual behaviour of the single area)
Additional context
JS TEST
import * as alt from "alt-client";
const _streamedMarkers = new Map();
alt.on("worldObjectStreamIn", (worldObject) => {
const id = worldObject.getStreamSyncedMeta("id");
var position = new alt.Vector3(worldObject.pos.x, worldObject.pos.y, worldObject.pos.z - 1.0);
alt.log(`Debug: Called OnStreamedIn with id ${id}}`);
if(_streamedMarkers.has(id)) {
alt.log("Debug: Called OnStreamedIn but marker already exists");
return;
}
const marker = new alt.Marker(id, position, new alt.RGBA(247, 2, 1, 255), false, 0);
_streamedMarkers.set(id, marker);
});
alt.on("worldObjectStreamOut", (worldObject) => {
const id = worldObject.getStreamSyncedMeta("id");
alt.log(`Debug: Called OnStreamedOut with id ${id}}`);
if(!_streamedMarkers.has(id)) {
alt.log("Debug: Called OnStreamedOut but marker not found");
return;
}
const marker = _streamedMarkers.get(id);
marker.destroy();
_streamedMarkers.delete(id);
});
Grand.Theft.Auto.V.2023.09.24.-.15.52.40.03.mp4
Operating system
Windows 11 (10.0.22621 build 22621)
Version
15.0-dev683 (dev)
Crashdump ID
No response
Reproduction tested
- I confirm that I have made sure that this issue is also present on the newest dev version
your C# Code is not the same like JS
U Create Marker by OnWorldObjectStreamOut and delete on OnWorldObjectStreamIn
your C# Code is not the same like JS
U Create Marker by OnWorldObjectStreamOut and delete on OnWorldObjectStreamIn
my bad i edited a little bit the code cause i wrote a wrapper on top of it on my gamemode, now the test is fixed
can u give me the positions and the create VirtualEntity, that i can easy repo oit?
Dictionary<string, object> marker1 = new()
{
{"id", "650f552569330d6c234bef88"},
};
Dictionary<string, object> marker2 = new()
{
{"id", "650f554669330d6c234bef8d"},
};
_pickupGroup = Alt.CreateVirtualEntityGroup(500);
var virtualEntity1 = Alt.CreateVirtualEntity(_pickupGroup, new Position(-274.1802062988281f, -674.8087768554688f, 33.087890625f), 5, marker1);
var virtualEntity2 = Alt.CreateVirtualEntity(_pickupGroup, new Position(-289.002197265625f, -672.5538330078125f, 33.037353515625f), 5, marker2);
thx
@kyro95 cannot repo it https://streamable.com/p50k05
private void OnWorldObjectStreamIn(IWorldObject worldObject)
{
if (worldObject is not IVirtualEntity entity)
return;
var position = entity.Position;
position.Z -= 1.0f;
entity.GetStreamSyncedMetaData<string>("id", out var id);
Alt.Log($"Debug: Called OnStreamedIn with id {id}");
if (_markers.Contains(id))
{
Alt.Log("Debug: Called OnStreamedIn but marker already exists");
return;
}
var marker = Alt.CreateMarker(MarkerType.MarkerCylinder, position, new Rgba(247, 2, 1, 255), false, 0);
_markers.Add(id, marker);
marker.Scale = new Vector3(1.5f, 1.5f, 1.5f);
}
private void OnWorldObjectStreamOut(IWorldObject worldObject)
{
if (worldObject is not IVirtualEntity entity)
return;
entity.GetStreamSyncedMetaData<string>("id", out var id);
Alt.Log($"Debug: Called OnStreamedOut with id {id}");
if (!_markers.Contains(id))
{
Alt.Log("Debug: Called OnStreamedOut but marker not found");
return;
}
IMarker marker = (IMarker)_markers[id]!;
_markers.Remove(id);
marker.Destroy();
}