Jump to content
alexslx

My API questions

Recommended Posts

Hi there,

 

I'm trying to play around with LCPDFR API and I have some questions:

 

1) I spawn some peds on OnCalloutAccepted(), but when I approach the location ingame, they appear to just be spawned right when I enter on the area (I can see they being spawned ["falling from the sky"]). I'm missing something?

 

2) AddToScriptDeletionList() takes care of ped/vehicle deletion right? So, when (what kind of condition) I need to set IsRequiredForMission to false? Eg. dying? vehicle exploding? end of callout?

 

3) There is any way to disable pullout on my mission vehicle?

 

4) For security checks, should I do (something == null || something.Exists()) or just something.Exists() is fine? On my programming understanding I should check for object null and for exists method (I dont know what this really does).

 

5) I have a Vector3 where I spawn a vehicle, but the vehicle do not spawn exactly on the position I want... how can I solve this? I'm doing this way: new LVehicle(World.GetNextPositionOnStreet(POSITION), MODEL); Also, I'm not using PlaceOnNextStreetProperly()

 

6) There is any way to get a vehicle route? I set my vehicle to go to place X, but I want to know the route this vehicle will use...

 

7) How to make a roadblock using the API?

 

8) How to make a vehicle attacker other vehicle (not from player)?

 

Sorry for the long list of questions and thank you in advance.

 

Regards,

Edited by alexslx

[sharedmedia=downloads:files:6360]

Share this post


Link to post
Share on other sites

Hello,

 

1.) more likely a resource/game issue. As a self test, you can add blips to the peds spawned in OnCalloutAccepted and check when they appear.

 

2.) You don't have to set IsRequiredForMission is false, it's done by LCPDFR for you in case the ped dies, the callouts ends, LCPDFR is shut down etc.

 

3.) What do you mean exactly? Removing the ability to pull over your suspect? The ped needs to be in a chase for this. Maybe creating a fake chase (maximum units to zero, not called in) can help here.

 

4.) It all depends on how you retrieve the object. If you do LPed ped = new LPed(); it can't be null and you only need to call Exists. However other functions will probably return a null pointer if a ped/vehicle is not found, e.g. retrieving one from a vehicle seat. So you'd have to add both checks here. While the null check addresses the .NET object instance existence, Exists checks whether the entity the object instance represents is still valid in-game.

 

5.) Well because you use GetNextPositionOnStreet it will try to find the closest vehicle node and not use your exact position.

 

6.) Not really no, it's random.

 

7.) You can't.

 

8.) What do you mean?


Please do not PM me unless really necessary (knowing you helps). If you think you need my attention in a topic, tag me.

Share this post


Link to post
Share on other sites

Hello,

 

1.) more likely a resource/game issue. As a self test, you can add blips to the peds spawned in OnCalloutAccepted and check when they appear.

 

2.) You don't have to set IsRequiredForMission is false, it's done by LCPDFR for you in case the ped dies, the callouts ends, LCPDFR is shut down etc.

 

3.) What do you mean exactly? Removing the ability to pull over your suspect? The ped needs to be in a chase for this. Maybe creating a fake chase (maximum units to zero, not called in) can help here.

 

4.) It all depends on how you retrieve the object. If you do LPed ped = new LPed(); it can't be null and you only need to call Exists. However other functions will probably return a null pointer if a ped/vehicle is not found, e.g. retrieving one from a vehicle seat. So you'd have to add both checks here. While the null check addresses the .NET object instance existence, Exists checks whether the entity the object instance represents is still valid in-game.

 

5.) Well because you use GetNextPositionOnStreet it will try to find the closest vehicle node and not use your exact position.

 

6.) Not really no, it's random.

 

7.) You can't.

 

8.) What do you mean?

 

Hi LMS,

 

Thank you for your reply (and for LCPDFR :) )

 

Following up my previous post:

 

1) I fixed it, I was putting freeze on them :P

 

2) Okay, now I understand it.

 

3) On my current situation, I have a friend car with a friend blip on him (without any persuit, I need to follow him), but if I want, I can press SHIFT behind this car and start a pullover, I want to disable this for this car. It is possible?

 

4) Okay. 

 

5) I'll try to figure out. There is anyway to remove all vehicles around a position?

 

6) The vehicle calculate the route on time so? And if I use a blip with a route, the ped will have the same route as mine?

 

7)  :confused:

 

8) I want a ped from vehicle1 attack a ped from vehicle2. I'm using FightAgainst (ped1 -> ped2), but sometimes the ped1 (attacker) takes other route and flee from the battle.

 

9) Can you explain when it is safe to use DelayedCaller.Call? I was trying to use it with a vehicle (spawn, put peds in -> delay -> drive and attack), but it was crashing (and I had Exists() checks inside of the delayed call. It's ok if you don't know because I deleted the logs, so I can't show you  :wacko:

 

10) It is safe to use List<> on the scripts? Because I read on your blog (I think) that GTAIV uses static arrays for resources allocations... I'm thinking if maybe list dynamic allocation can not mess up with GTAIV memory (I don't know how memory are managed with these scripts...)

 

Sorry for a lot of questions, especially if any of those are dumb, but I want try to understand how it works.  :pirate:


[sharedmedia=downloads:files:6360]

Share this post


Link to post
Share on other sites

ad. 5) use GTA.World.GetVehicles() to get vehicles within given distance around the position and remove them all from the array.

ad. 6) Depends on the situation - sometimes a ped can use nodes that are not available to cars (eg. pavements that are not going along the street) or - when configured specifically - he can ignorePath = true and go through yards etc. Also, there's a native method to get a distance to the waypoint probably, you have to revise them and check.

ad. 8) set BlockPermanentEvents = true and AlwaysKeepTask = true. I'd also create a sequence of 1. ped.Task.LeaveVehicle(), 2. ped.Task.FightAgainst()

ad. 9) please, post here a snippet from your code so we can check what's wrong in there.

ad. 10) even an API example uses List<>, the issue with GTA memory allocation is something different I believe.

Share this post


Link to post
Share on other sites

Thank you all, I solved almost everything from there, just need to solve a bug where sometimes the ped get out of game memory and the game get in a infinite loop (I can't even do alt-tab hahaha) with this message:

[ERROR - 8:44:41 AM] [CPedExtension] GetPedFromPool: Possible invalid/dummy handle: -64402944

 

 


[sharedmedia=downloads:files:6360]

Share this post


Link to post
Share on other sites

Never got such error, try this:

if (ped != null && ped.Exists())
{
    //all actions here
}

also you should protect a ped you want to control from being removed from memory (eg. when he's too far from you he gets removed by a game as an useless resource). You can use API functions (SetPedIsOwned... and AddToScriptDeletionList) or ped.BecomeMissionCharacter() and ped.NoLongerNeeded() of SHDN. It's very important to "claim the ownership" of the ped for any script.

Share this post


Link to post
Share on other sites

Thanks LtFlash,

 

I discovered that I was trying to assign a FightAgainst task on a non checked ped.

 

-----------------

 

I have just one more error, when I try to create a pursuit, the LCPDFR create the following error:

[ERROR - 10:51:03 AM] [Main] CRITICAL ERROR DURING MAINLOOP! REPORT THIS ISSUE AT LCPDFR.COM BY INCLUDING THIS LOGFILE.
[ERROR - 10:51:03 AM] [] System.Exception: Entity already has an owner! Name: BankTransport Requesting owner name: Chase
   at hm.b(gf A_0, Boolean A_1)
   at eg.b(im A_0, Boolean A_1)
   at eg.a(ij A_0)
   at ij..ctor(im A_0, im A_1)
   at fb.a(eo A_0)
   at eo.a.Invoke(eo A_0)
   at eo..ctor(im A_0)
   at ci.d(im A_0)
   at gl.f(im A_0)
   at fd.ad()
   at h5.ad()
   at LCPD_First_Response.Engine.Main.c()
[ERROR - 10:51:03 AM] [ExceptionHandler]  hm.b(gf A_0, Boolean A_1) L_0259 
 eg.b(im A_0, Boolean A_1) L_0171 
 eg.a(ij A_0) L_0089 
 ij..ctor(im A_0, im A_1) L_001d 
 fb.a(eo A_0) L_0145 
 eo+a.Invoke(eo A_0) L_ffffffff 
 eo..ctor(im A_0) L_0016 
 ci.d(im A_0) L_014c 
 gl.f(im A_0) L_001c 
 fd.ad() L_00dd 
 h5.ad() L_046d 
 LCPD_First_Response.Engine.Main.c() L_00f4 
Error hash: 76E575C87D23CFF3130510369CBAAC5B649D9BB4
[ERROR - 10:51:03 AM] [Main] CRITICAL ERROR DURING MAINLOOP! REPORT THIS ISSUE AT LCPDFR.COM BY INCLUDING THIS LOGFILE.
[ERROR - 10:51:03 AM] [] System.Exception: Entity already has an owner! Name: BankTransport Requesting owner name: Chase
   at hm.b(gf A_0, Boolean A_1)
   at eg.b(im A_0, Boolean A_1)
   at eg.a(ij A_0)
   at ij..ctor(im A_0, im A_1)
   at fb.a(eo A_0)
   at eo.a.Invoke(eo A_0)
   at eo..ctor(im A_0)
   at ci.d(im A_0)
   at gl.f(im A_0)
   at fd.ad()
   at h5.ad()
   at LCPD_First_Response.Engine.Main.c()
[ERROR - 10:51:03 AM] [ExceptionHandler]  hm.b(gf A_0, Boolean A_1) L_0259 
 eg.b(im A_0, Boolean A_1) L_0171 
 eg.a(ij A_0) L_0089 
 ij..ctor(im A_0, im A_1) L_001d 
 fb.a(eo A_0) L_0145 
 eo+a.Invoke(eo A_0) L_ffffffff 
 eo..ctor(im A_0) L_0016 
 ci.d(im A_0) L_014c 
 gl.f(im A_0) L_001c 
 fd.ad() L_00dd 
 h5.ad() L_046d 
 LCPD_First_Response.Engine.Main.c() L_00f4 
Error hash: 76E575C87D23CFF3130510369CBAAC5B649D9BB4
[ERROR - 10:51:03 AM] [Main] CRITICAL ERROR DURING MAINLOOP! REPORT THIS ISSUE AT LCPDFR.COM BY INCLUDING THIS LOGFILE.
[ERROR - 10:51:03 AM] [] System.Exception: Entity already has an owner! Name: BankTransport Requesting owner name: Chase
   at hm.b(gf A_0, Boolean A_1)
   at eg.b(im A_0, Boolean A_1)
   at eg.a(ij A_0)
   at ij..ctor(im A_0, im A_1)
   at fb.a(eo A_0)
   at eo.a.Invoke(eo A_0)
   at eo..ctor(im A_0)
   at ci.d(im A_0)
   at gl.f(im A_0)
   at fd.ad()
   at h5.ad()
   at LCPD_First_Response.Engine.Main.c()
[ERROR - 10:51:03 AM] [ExceptionHandler]  hm.b(gf A_0, Boolean A_1) L_0259 
 eg.b(im A_0, Boolean A_1) L_0171 
 eg.a(ij A_0) L_0089 
 ij..ctor(im A_0, im A_1) L_001d 
 fb.a(eo A_0) L_0145 
 eo+a.Invoke(eo A_0) L_ffffffff 
 eo..ctor(im A_0) L_0016 
 ci.d(im A_0) L_014c 
 gl.f(im A_0) L_001c 
 fd.ad() L_00dd 
 h5.ad() L_046d 
 LCPD_First_Response.Engine.Main.c() L_00f4 
Error hash: 76E575C87D23CFF3130510369CBAAC5B649D9BB4
[ERROR - 10:51:03 AM] [Main] CRITICAL ERROR DURING MAINLOOP! REPORT THIS ISSUE AT LCPDFR.COM BY INCLUDING THIS LOGFILE.
[ERROR - 10:51:03 AM] [] System.Exception: Entity already has an owner! Name: BankTransport Requesting owner name: Chase
   at hm.b(gf A_0, Boolean A_1)
   at eg.b(im A_0, Boolean A_1)
   at eg.a(ij A_0)
   at ij..ctor(im A_0, im A_1)
   at fb.a(eo A_0)
   at eo.a.Invoke(eo A_0)
   at eo..ctor(im A_0)
   at ci.d(im A_0)
   at gl.f(im A_0)
   at fd.ad()
   at h5.ad()
   at LCPD_First_Response.Engine.Main.c()
[ERROR - 10:51:03 AM] [ExceptionHandler]  hm.b(gf A_0, Boolean A_1) L_0259 
 eg.b(im A_0, Boolean A_1) L_0171 
 eg.a(ij A_0) L_0089 
 ij..ctor(im A_0, im A_1) L_001d 
 fb.a(eo A_0) L_0145 
 eo+a.Invoke(eo A_0) L_ffffffff 
 eo..ctor(im A_0) L_0016 
 ci.d(im A_0) L_014c 
 gl.f(im A_0) L_001c 
 fd.ad() L_00dd 
 h5.ad() L_046d 
 LCPD_First_Response.Engine.Main.c() L_00f4 
Error hash: 76E575C87D23CFF3130510369CBAAC5B649D9BB4

 
This is the part where I create the pursuit:

if (this.attackPursuitHandler == null)
{
this.attackPursuitHandler = Functions.CreatePursuit();
 
foreach (LPed attacker in this.attackPedList)
{
if( !ResourceHelper.CheckForObjectExistance(attacker) )
continue;
 
Functions.AddPedToPursuit(this.attackPursuitHandler, attacker);
attacker.Task.FightAgainst(LPlayer.LocalPlayer.Ped);
}
 
Functions.SetPursuitAllowVehiclesForSuspects(this.attackPursuitHandler, true);
Functions.SetPursuitAllowWeaponsForSuspects(this.attackPursuitHandler, true);
Functions.SetPursuitCopsCanJoin(this.attackPursuitHandler, true);
Functions.SetPursuitDontEnableCopBlips(this.attackPursuitHandler, true);
Functions.SetPursuitForceSuspectsToFight(this.attackPursuitHandler, true);
Functions.SetPursuitIsActiveForPlayer(this.attackPursuitHandler, true);
Functions.SetPursuitCalledIn(this.attackPursuitHandler, true);
}

[sharedmedia=downloads:files:6360]

Share this post


Link to post
Share on other sites

I believe the error might be caused by this part:

Functions.AddPedToPursuit(this.attackPursuitHandler, attacker);
attacker.Task.FightAgainst(LPlayer.LocalPlayer.Ped);

You may do it this way:

//attacker.DisablePursuitAI = true;
attacker.RangeToDetectEnemies = fRange;
Functions.SetPursuitForceSuspectsToFight(hPursuit, true);

You might turn off the AI and set up ped's task before creating a pursuit so he will be eg. WanderAround() and not running away. When you or any other Officer will be closer than fRange attacker will start fighting because he's forced to.

Edited by LtFlash

Share this post


Link to post
Share on other sites

In case this applies to your scenario, use AddPedToPursuit before calling SetPedIsOwnedByScript. If you aren't using SetPedIsOwnedByScript, verify you are only adding each ped once.


Please do not PM me unless really necessary (knowing you helps). If you think you need my attention in a topic, tag me.

Share this post


Link to post
Share on other sites

My scenario is:

 

1) I spawn the peds on a method and make them wait for the player or my other controlled vehicle get closer...

2) When them get closer, I make them start the attack.

 

I tried to modify the scripts according with you LMS and LtFlash said, but I still getting the same error.

This is where I create the peds:

this.attackPedList = new List<LPed>();
					int count = Common.GetRandomValue(3,6);
					for (int i = 0; i < count; i++ )
					{
						LPed attacker = new LPed(World.GetNextPositionOnStreet(this.attackVehicle.Position), Common.GetRandomCollectionValue<string>(AIHelper.criminalModels), LPed.EPedGroup.Criminal);
						attacker.DisablePursuitAI = true;
						this.SetBasicAttacker(attacker);
						this.attackPedList.Add(attacker);
					}
 

This is the method I use to set some ped attributes:

private void SetBasicAttacker(LPed ped)
{
if( !ResourceHelper.CheckForObjectExistance(ped) )
return;
 
DebugHelper.Instance.Log(DebugHelper.ELogType.LOG_DEBUG, "Setting basic attacker ped...");
 
Functions.SetPedIsOwnedByScript(ped, this, true);
Functions.AddToScriptDeletionList(ped, this);
 
//ped.BecomeMissionCharacter();
ped.Accuracy = Common.GetRandomValue(45, 80);
ped.IsRequiredForMission = true;
ped.BlockPermanentEvents = true;
ped.Task.AlwaysKeepTask = true;
ped.Health = 200;
ped.Armor = 200;
ped.WillDoDrivebys = true;
ped.RandomizeOutfit();
ped.DefaultWeapon = Common.GetRandomCollectionValue<Weapon>(AIHelper.commonWeapons);
}
and finally, here is where I'm starting the pursuit:

if (this.attackPursuitHandler == null)
					{
						this.attackPursuitHandler = Functions.CreatePursuit();
						this.StartPursuit(this.attackPursuitHandler);

						foreach (LPed attacker in this.attackPedList)
						{
							if( !ResourceHelper.CheckForObjectExistance(attacker) )
								continue;

							attacker.DisablePursuitAI = false;
							Functions.SetPedIsOwnedByScript(attacker, this, false);
							Functions.AddPedToPursuit(this.attackPursuitHandler, attacker);
							//attacker.Task.FightAgainst(LPlayer.LocalPlayer.Ped);
						}
					}
I appreciate your help, thank you (both you LMS and LtFlash).

@LMS

Maybe you can include a check on next version about that? I do not think the LCPDFR should crash when that happen... maybe just ignore? Just a suggestion.

Regards,


[sharedmedia=downloads:files:6360]

Share this post


Link to post
Share on other sites

Is there any chance you are owning a cop model? From the log it seems it tries to add a cop to the chase (the cop responds to a your pursuit as he's nearby), but there is an error because your script has control of it. I think it's a bug within the SetPedIsOwnedByScript API function, because it treats every ped the same and doesn't set the special flags for cops. The exception however is intended and should break the whole script because if requesting ownership failed code running after that line is not guaranteed to have access to the object and is most likely an indicator of a major design flaw where no else block is available for when the ped can't be owned. In this case I think it's a bug in the APi though, which occurs when you set a cop as owned and a chase starts. Can you confirm that it works for non cop models?


Please do not PM me unless really necessary (knowing you helps). If you think you need my attention in a topic, tag me.

Share this post


Link to post
Share on other sites

Is there any chance you are owning a cop model? From the log it seems it tries to add a cop to the chase (the cop responds to a your pursuit as he's nearby), but there is an error because your script has control of it. I think it's a bug within the SetPedIsOwnedByScript API function, because it treats every ped the same and doesn't set the special flags for cops. The exception however is intended and should break the whole script because if requesting ownership failed code running after that line is not guaranteed to have access to the object and is most likely an indicator of a major design flaw where no else block is available for when the ped can't be owned. In this case I think it's a bug in the APi though, which occurs when you set a cop as owned and a chase starts. Can you confirm that it works for non cop models?

You mean the models or the group? The criminals are created using this line:

LPed attacker = new LPed(World.GetNextPositionOnStreet(this.attackVehicle.Position), Common.GetRandomCollectionValue<string>(AIHelper.criminalModels), LPed.EPedGroup.Criminal);
and these models:

"M_Y_THIEF",
"M_Y_THIEF",
"M_Y_GRUS_LO_01",
"M_Y_GRU2_LO_01",
"M_Y_GMAF_LO_01",
"M_Y_GMAF_HI_01",
"M_Y_GTRI_LO_01",
"M_Y_GTRI_LO_02",
"M_Y_GALB_LO_01",
"M_Y_GALB_LO_02"
while the security guards are created using this line:

this.targetPedList = new LPed(World.GetNextPositionOnStreet(this.targetVehicle.Position), Common.GetRandomCollectionValue<string>(this.securityModels), LPed.EPedGroup.Cop);
using these models:


"M_M_ARMOURED",
"M_M_SECURITYMAN"
However, I don't add the security guards to the chase (I think they will react by themselves as they are set to be cops and the criminals will attack them).

[sharedmedia=downloads:files:6360]

Share this post


Link to post
Share on other sites

Yes, they are added automatically. And that's where the problem occurs: A cop the chase would like to use is owned by BankTransport already.

Okay, I got it. Instead of using the cop relationship for my peds, I changed to Special group and configured the relationship betweens criminals and cops, no more instant crash.

Edited by alexslx

[sharedmedia=downloads:files:6360]

Share this post


Link to post
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...