Skip to content
View in the app

A better way to browse. Learn more.

LCPDFR.com

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Infinite Loop Crash

Featured Replies

Hey there,
So as my first callout slowly progresses, I have finally made it to the near end.
Unfortunately, I have run into a graphics glitch.
Basically, the screen of GTA 5 bugs out and flashes, and a huge diamond forms around a newly created blip on my minimap.

I know this is because my infinite loop is repeatedly executing, and causing the blip to regenerate.

I have placed a GameFiber.Yield(), but it still seems to not work. I have placed the .Yield() in a couple of different spots, and none of them cause the plugin to work correctly, and either crashes LSPDFR, or the game.

Help appreciated,
Thanks.

Code

Spoiler

 while (true)
            {
                if (gunman1.IsDead && gunman2.IsDead && gunman3.IsDead)
                {
                    
                    Game.DisplayNotification("~b~Dispatch~w~: The prisoner escaped! Find him before he gets away!");
                    Game.DisplaySubtitle("Find the ~r~prisioner~w~", 6500);
                    if (blip.Exists()) blip.Delete();
                    pblip = prisoner.AttachBlip();
                    pblip.EnableRoute(Color.Red);
                    GameFiber.Yield();
                   
                    if (!prisoner.Exists())
                    {
                        Game.DisplayNotification("~b~Dispatch~w~: Disregard, FIB have captured suspect");
                        Game.DisplayNotification("~b~Dispatch~w~: Code four, resume patrol");
                        this.End();
                    }

                    if (Game.LocalPlayer.Character.Position.DistanceTo(pspawn) <= 15)
                    {
                        Game.DisplayNotification("~y~You~w~: Perp spotted, requesting assitance!");
                        //Dismiss the prisoner from our plugin and add it to the LSPDFR API
                        prisoner.Dismiss();
                        Functions.AddPedToPursuit(this.pursuit, prisoner);
                        state = EConvoyState.endlogic;
                        //Request backup
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.LocalUnit);
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.LocalUnit);
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.LocalUnit);
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.StateUnit);
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.SwatTeam);
                    }
                }
            }
        }

 

 

Edited by tanu1215

  • Management Team

Yield does not stop execution for ever, it just returns control of the current thread to the caller, so other things can be processed. It's basically what Non-preemptive multitasking (cooperating threads) are to operating systems. The OS (in this case RAGE Plugin Hook) expects the callee to hand back control every now and then so it can process other waiting tasks. If this does not happen, the whole system will come to a halt (since RPH is only pseudo-multithreading this will cause the game to freeze). So what happens when you call Yield, is that execution in your plugin is paused, all other waiting tasks (other script threads) are executed, and then control is handed back to you and your code is resumed. So you effectively only pause your code for one game tick before it executes again.

To prevent things from being executed every tick, use variables indicating whether something has been done already, such as introducing a Boolean hasBlipBeenCreated or checking for the existence of the blip and only creating it, if it doesn't exist.

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

You can also use switch..case and enum of states to control which chunks of code you want to run in a specific moment, eg.

 

enum EState
{
    Initialize,
    CheckConditions,
    Finalize,
};
EState currentState = SState.Initialize;

switch(currentState)
{
    case Initialize:
      //create blips and stuff
      currentState = EState.CheckConditions;
      break;
    case CheckConditions:
      if(Ped.IsDead) currentState = EState.Finalize;
      break;
    case Finalize:
      //delete blips etc.
      break;
}

 

  • Management Team

To add to what @LtFlash said, if you require certain actions to be executed most of the time and still want to use a state enum, you can use bit flags. Basically that allows you to have one state variable, which can contain several states at once. So maybe you want the CheckConditions part executed most of the time as well, so you can specify that along with the "real" state.

LSPDFR exposes such functionality through RegisterStateCallback for callouts.

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

  • Author
4 hours ago, LMS said:

To add to what @LtFlash said, if you require certain actions to be executed most of the time and still want to use a state enum, you can use bit flags. Basically that allows you to have one state variable, which can contain several states at once. So maybe you want the CheckConditions part executed most of the time as well, so you can specify that along with the "real" state.

LSPDFR exposes such functionality through RegisterStateCallback for callouts.

Okay, so I am still somewhat at a loss. I tried doing what @LtFlash said, and incorporated a switch statement with enums so I could  take control over the process.

 

  ECheck check = ECheck.Initialize;

            switch (check)
            {
                case ECheck.Initialize:
                    Game.DisplaySubtitle("~w~Kill all ~r~hostilies", 6500);
                    check = ECheck.Checkconditions;
                    break;

                case ECheck.Checkconditions:

                    check = ECheck.Wait;

                    if (gunman1.IsDead && gunman2.IsDead && gunman3.IsDead && check == ECheck.Wait)
                    {
                        Game.DisplayNotification("~b~Dispatch~w~: The prisoner escaped! Find him before he gets away!");
                        Game.DisplaySubtitle("Find the ~r~prisioner~w~", 6500);
                        check = ECheck.Finalize;
                    }

                    break;

                case ECheck.Finalize:
                    if (blip.Exists()) blip.Delete();
                    pblip = prisoner.AttachBlip();
                    pblip.EnableRoute(Color.Red);
                    if (!prisoner.Exists() || !pblip.Exists())
                    {
                        Game.DisplayNotification("~b~Dispatch~w~: Disregard, FIB have captured suspect");
                        Game.DisplayNotification("~b~Dispatch~w~: Code four, resume patrol");
                        this.End();
                    }

                    if (Game.LocalPlayer.Character.Position.DistanceTo(pspawn) <= 15)
                    {
                        Game.DisplayNotification("~y~You~w~: Perp spotted, requesting assitance!");
                        //Dismiss the prisoner from our plugin and add it to the LSPDFR API
                        prisoner.Dismiss();
                        Functions.AddPedToPursuit(this.pursuit, prisoner);
                        state = EConvoyState.endlogic;
                        //Request backup
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.LocalUnit);
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.LocalUnit);
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.LocalUnit);
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.StateUnit);
                        Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.SwatTeam);

                    }

                    break;
            }

So, the  if (gunman1.IsDead && gunman2.IsDead && gunman3.IsDead && check == ECheck.Wait) still doesn't get called because the gunmen aren't dead when the player gets on scene. 

If I'm right (probably not), shouldn't it still execute because of the ECheck.Wait enum?
You said something about executing the "Checkconditions" part repeatedly, which would probably wait until all 3 gunmen are dead until moving on, and I could use the "RegisterStateCallback" for that?

Would you mind explaining that again in a more "noobish" way, I don't really understand.
Thanks again,

Tanu

The ECheck.Wait enum is whats stopping it being checked. The next pass, your switch wont execute any code as there is no case for ECheck.Wait. You could try adding a Case ECheck.Wait identical to your Case ECheck.Checkconditions, or just leave the enum at .Checkconditions till it finalizes.

My YouTube Channel: Darkmyre Gaming (Australian LSPDFR patrols, plugins in development, and other games)

My Discord Server | AusGamer Network

 

Please do not PM me for technical support or bug reports, use the appropriate forum or plugin's comments instead.

@tanu1215

This variable needs to be global in the callout class:

ECheck check = ECheck.Initialize;

I assume it is, let's go further:

case ECheck.Checkconditions:

                    check = ECheck.Wait;

                    if (gunman1.IsDead && gunman2.IsDead && gunman3.IsDead && check == ECheck.Wait)
                    {
                        Game.DisplayNotification("~b~Dispatch~w~: The prisoner escaped! Find him before he gets away!");
                        Game.DisplaySubtitle("Find the ~r~prisioner~w~", 6500);
                        check = ECheck.Finalize;
                    }

                    break;

 

I assume the switch...case is run in an infinite loop. With that in mind look what happened here:

1st loop:

1. You immediately changed the current state to Wait.

2. You checked if "AreGunmenDead" (unknown result) && state == Wait (true). If yes -> state = Finalize.

2nd loop:

3. In the next loop your "AreGunmenDead" && state won't be called at all. Why? Because the state is now Wait which is empty as I suppose.

 

Try to change this case to:

case ECheck.Checkconditions:

	if (gunman1.IsDead && gunman2.IsDead && gunman3.IsDead)
    {
    	Game.DisplayNotification("~b~Dispatch~w~: The prisoner escaped! Find him before he gets away!");
		Game.DisplaySubtitle("Find the ~r~prisioner~w~", 6500);
      
        check = ECheck.Finalize;
    }
    break;

+ define the check variable as a global one.

+ simplify the callout, firstly try to make one where a player is supposed to kill all 3 suspects. The part of code in Finalize which is responsible of handling a pursuit won't work.

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...

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.