Jump to content

AI Blips... an unknown world


AchilleX

Recommended Posts

Hi guys.

Let's say I'm coding a callout and I want to attach a blip to a Ped. What I do is simply

Ped ped = new Ped();
Blip pedBlip = ped.AttachBlip(); // or new Blip(ped)

but this notation has drawbacks:

  1. The blip will always show up, even if the entity is far away (a simple solutions is SET_BLIP_AS_SHORT_RANGE, but still the blip will always be displayed on the map);
  2. If the ped enters a vehicle, the blip won't manually change size;
  3. If I want the blip to disappear if the ped dies, I have to manually check in the Process method if the entity has died. When the blips are not one but, for example, 40 this method can easily lead to bad performances and throw exceptions.

 

The best solutions to these problems is given by AI Blips: they change size when the ped enters a vehicle, if there are two or more peds in a vehicle a single blip will be displayed and the blip will disappear if the ped dies or is deleted.

The problem is that AI Blips are not so easy to use 😩. The correct way to create an AI Blip (without the blue vision cone) is:

Ped ped = new Ped();
NativeFunction.Natives.SET_PED_HAS_AI_BLIP(ped, true); // If the argument hasCone is setted to false, the blip won't be created for some reasons
NativeFunction.Natives.SET_PED_AI_BLIP_HAS_CONE(ped, false);

and this solves the problems that I have pointed out. But let's assume that I want to attach an AI Blip to a friendly ped or a cop: I don't want a red blip but a Police blip. What I do is:

NativeFunction.CallByHash<int>(0xFCFACD0DB9D7A57D, ped, (int)BlipSprite.Police); // _SET_PED_AI_BLIP_SPRITE(ped, 3)

but this does not work! There is also a native

Blip _GET_AI_BLIP(Ped ped) // 0x56176892826A4FE8 0xCA52CF43 b323

that I assume returns a int32 (an handle to the blip), and can be used to modify the scale, color, ecc.. using the natives for normal blips. The problem is that this native always returns 0 (same thing with her sister _GET_AI_BLIP_2), and so it is useless!

 

So my question is: is there a way to properly change the AI Blip? For now, an AI Blip is only useful with enemies (or, more generally, peds that you want to be displayed with a red blip) but not for friends or cops.

 

Addendum: _SET_PED_AI_BLIP_SPRITE appears to be working if used inside a loop (for example the Process method). But still, this can lead to troubles!

Check out my FIB HRT Callouts script for LSPDFR!

Link to comment
Share on other sites

2 minutes ago, Rich said:

Sorry but that is not useful at all (I've already checked them before posting this). The first link just repeats the code I wrote:

Ped ped = new Ped();
NativeFunction.Natives.SET_PED_HAS_AI_BLIP(ped, true); // If the argument hasCone is setted to false, the blip won't be created for some reasons
NativeFunction.Natives.SET_PED_AI_BLIP_HAS_CONE(ped, false);

And the second native did not work for me. And even if it did, I still can't change the sprite or the size.

Check out my FIB HRT Callouts script for LSPDFR!

Link to comment
Share on other sites

2 hours ago, AchilleX said:

but this notation has drawbacks:

  1. The blip will always show up, even if the entity is far away (a simple solutions is SET_BLIP_AS_SHORT_RANGE, but still the blip will always be displayed on the map);
  2. If the ped enters a vehicle, the blip won't manually change size;
  3. If I want the blip to disappear if the ped dies, I have to manually check in the Process method if the entity has died. When the blips are not one but, for example, 40 this method can easily lead to bad performances and throw exceptions.

 

1. Does setting the blip alpha to 0 still make it appear on the map?

2. You can write code for this

3.  I'm interested in knowing the performance impact of checking if n peds are dead and removing their blips.  I don't expect it to be much unless your code is poorly written, but perhaps I'm wrong.

Edited by Rich

Released plugins

Automatic Siren Cutout | Rich's Police EnhancementsScene Manager | Rich Ambiance

Retired - No more updates

Link to comment
Share on other sites

20 minutes ago, Rich said:

 

1. Does setting the blip alpha to 0 still make it appear on the map?

2. You can write code for this

3.  I'm interested in knowing the performance impact of checking if n peds are dead and removing their blips.  I don't expect it to be much unless your code is poorly written, but perhaps I'm wrong.

You have to check each tick:

  • If the blip exists,
  • If the entity exists. If not, delete the blip,
  • If the entity is alive. If not, delete the blip,
  • If the entity is on foot, scale the blip to 0.75f,
  • If the entity is in a vehicle, attach the blip to the vehicle (with scale 1.0f),
  • If the entity is in a vehicle and there are other peds in the vehicle, make sure to not attach another blip to the vehicle,
  • If the entity is far away, fade out the blip, 
  • null-checking the data structure, the blip, the entity and the vehicle.

There are lots of calls to natives. The complexity should be O(n) (fixing the problem of the single blip attached to the vehicle with an hash map, for example), but having to do it every tick is not something I would call neat 😀. AI Blips are way better, but I don’t understand why the natives involved with them are so broken!

Check out my FIB HRT Callouts script for LSPDFR!

Link to comment
Share on other sites

4 hours ago, AchilleX said:

AI Blips are way better

Sounds like it doesn't matter if they don't do what you want.

 

Also, you should be checking if entities exist/are valid regularly anyways, so that's not an extra check.  I don't think the performance impact is as significant as you imagine.

Edited by Rich

Released plugins

Automatic Siren Cutout | Rich's Police EnhancementsScene Manager | Rich Ambiance

Retired - No more updates

Link to comment
Share on other sites

5 hours ago, Rich said:

Also, you should be checking if entities exist/are valid regularly anyways, so that's not an extra check.

Yes, I have to extra check it when I manage all the blips.

5 hours ago, Rich said:

 I don't think the performance impact is as significant as you imagine.

I tried this code running in the Process method

// Have to clear the dictionary
foreach (Blip blip in vehicleHashMap.Values)
    if (blip?.Exists() ?? false)
        blip.Delete();
vehicleHashMap.Clear();
// Check each blip
foreach (Blip blip in blips ?? Enumerable.Empty<Blip>())
{
    // Check if the blips exists (and it is not null)
    if (blip?.Exists() ?? false)
    {
        // Get ped the blip is attached to
        Ped attachedPed = blip.Entity as Ped;
        // If it is null or non existent, delete the blip
        if (attachedPed == null || !attachedPed.Exists())
            blip.Delete();
        // If it exists
        else
        {
            // If the ped is dead, delete the blip
            if (attachedPed.IsDead)
                blip.Delete();
            // If it is alive
            else
            {
                // If it is in a vehicle, add a blip with scale 1.0f to the vehicle
                if (attachedPed.IsInAnyVehicle(false))
                {
                    // Hide the ped's blip 
                    blip.Alpha = 0f;
                    Vehicle currentPedVehicle = attachedPed.CurrentVehicle;
                    // Just to be sure 
                    if (currentPedVehicle == null || !currentPedVehicle.Exists())
                        continue;
                    // If the vehicle is already in the dictionary, continue
                    if (vehicleHashMap.ContainsKey(currentPedVehicle))
                        continue;
                    // Else, add the blip 
                    else
                        vehicleHashMap.Add(currentPedVehicle, currentPedVehicle.AttachBlip());
                }
                // If it is not in a vehicle, show the blip and set the scale to 0.75f
                else
                {
                    blip.Alpha = 1f;
                    blip.Scale = 0.75f;
                }
            }
        }
    }
}

where

List<Blip> blips;
Dictionary<Vehicle, Blip> vehicleHashMap;

with 40 peds, and yes the impact in the performance is noticeable. Note that I did not implement the distance from the Player fade out/fade in and I did not copy the color and the sprite of the ped's blip to the vehicle blip. This code could be run in a GameFiber that yields for 100ms, for example, but still AI Blips would be better.

5 hours ago, Rich said:

Sounds like it doesn't matter if they don't do what you want.

The concept of an AI Blip is better, but because _GET_AI_BLIP and other natives do not work the actual implementation is not. But maybe someone knows how to make them work 😀

Edited by AchilleX

Check out my FIB HRT Callouts script for LSPDFR!

Link to comment
Share on other sites

This code does not perform any resource intensive operations.  I did not test it, just refactored, but I don't see where the performance impact would come from.  Consider use GameFibers if you still experience performance issues for some reason.  I also don't understand the purpose of the dictionary unless it's being used somewhere else.

 

// Have to clear the dictionary
foreach (Blip blip in vehicleHashMap.Values)
{
    if (blip)
    {
        blip.Delete();
    }
}
vehicleHashMap.Clear();

// Remove invalid blips
blips.RemoveAll(b => !b);

// Check each blip
foreach (Blip blip in blips)
{
    // Get ped the blip is attached to
    Ped attachedPed = blip.Entity as Ped;
    
    // If it is null or non existent, delete the blip
    if (!attachedPed || attachedPed.IsDead)
    {
        blips.Remove(blip):
        blip.Delete();
        continue;
    }
    
    // If it is in a vehicle, add a blip with scale 1.0f to the vehicle
    if (attachedPed.CurrentVehicle)
    {
        // Hide the ped's blip 
        blip.Alpha = 0f;

        if(!vehicleHashMap.ContainsKey(attachedPed.CurrentVehicle))
        {
            vehicleHashMap.Add(attachedPed.CurrentVehicle, attachedPed.CurrentVehicle.AttachBlip());
        }
    }
    // If it is not in a vehicle, show the blip and set the scale to 0.75f
    else
    {
        blip.Alpha = 1f;
        blip.Scale = 0.75f;
    }
}

 

Edited by Rich

Released plugins

Automatic Siren Cutout | Rich's Police EnhancementsScene Manager | Rich Ambiance

Retired - No more updates

Link to comment
Share on other sites

3 hours ago, Rich said:

This code does not perform any resource intensive operations.  I did not test it, just refactored, but I don't see where the performance impact would come from.  Consider use GameFibers if you still experience performance issues for some reason.  I also don't understand the purpose of the dictionary unless it's being used somewhere else.

 

// Have to clear the dictionary
foreach (Blip blip in vehicleHashMap.Values)
{
    if (blip)
    {
        blip.Delete();
    }
}
vehicleHashMap.Clear();

// Remove invalid blips
blips.RemoveAll(b => !b);

// Check each blip
foreach (Blip blip in blips)
{
    // Get ped the blip is attached to
    Ped attachedPed = blip.Entity as Ped;
    
    // If it is null or non existent, delete the blip
    if (!attachedPed || attachedPed.IsDead)
    {
        blips.Remove(blip):
        blip.Delete();
        continue;
    }
    
    // If it is in a vehicle, add a blip with scale 1.0f to the vehicle
    if (attachedPed.CurrentVehicle)
    {
        // Hide the ped's blip 
        blip.Alpha = 0f;

        if(!vehicleHashMap.ContainsKey(attachedPed.CurrentVehicle))
        {
            vehicleHashMap.Add(attachedPed.CurrentVehicle, attachedPed.CurrentVehicle.AttachBlip());
        }
    }
    // If it is not in a vehicle, show the blip and set the scale to 0.75f
    else
    {
        blip.Alpha = 1f;
        blip.Scale = 0.75f;
    }
}

 

The dictionary is used to make a single blip for every vehicle, even if there are two or more peds inside it. I did not know that there is a implicit cast to bool for Entities, thanks. But isn't removing an element from a list while iterating it something that should not be done?

Maybe it is better to do

foreach (Blip blip in blips.ToList())

 

Check out my FIB HRT Callouts script for LSPDFR!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...