/// <summary> /// More cleanup, when we call end you clean away anything left over /// This is also important as this will be called if a callout gets aborted (for example if you force a new callout) /// </summary> public override void End() { hasEnded = true; base.End(); if (blip.Exists()) { blip.Delete(); } if (ped.Exists()) { ped.Tasks.Clear(); ped.Dismiss(); } if (pedObj.Exists()) { pedObj.Detach(); pedObj.Dismiss(); } }
public void CreateScenario(int scenario) { GameFiber.StartNew(delegate { Logger.LogTrivial(this.GetType().Name, "Scenario: " + scenario); if (scenario == 1) // SHOOT { Logger.LogDebug(this.GetType().Name, "Scenario: Shoot"); ped.Inventory.GiveNewWeapon(weaponAssets.GetRandomElement(true), 9999, true); Vector3 posToShoot = ped.Position + (ped.ForwardVector * MathHelper.GetRandomSingle(1.5f, 8.0f)) + (ped.UpVector * MathHelper.GetRandomSingle(8.0f, 20.0f)) + (ped.RightVector * MathHelper.GetRandomSingle(-15.0f, 15.0f)); NativeFunction.CallByName <uint>("TASK_SHOOT_AT_COORD", ped, posToShoot.X, posToShoot.Y, posToShoot.Z, -1, (uint)Rage.FiringPattern.BurstFire); } else if (scenario == 2) // PROTEST { Logger.LogDebug(this.GetType().Name, "Scenario: Protest"); ped.Tasks.PlayAnimation("special_ped@griff@monologue_1@monologue_1e", "iamnotaracist_4", 5.0f, AnimationFlags.UpperBodyOnly | AnimationFlags.SecondaryTask | AnimationFlags.Loop); ped.Tasks.Wander(); pedObj = new Rage.Object("prop_cs_protest_sign_01", Vector3.Zero); pedObj.AttachToEntity(ped, ped.GetBoneIndex(PedBoneId.RightPhHand), Vector3.Zero, Rotator.Zero); GameFiber.StartNew(delegate { //GameFiber.StartNew(delegate //{ // while (!hasEnded && ped.Exists() && ped.IsAlive && !Functions.IsPedArrested(ped)) // { // if (Vector3.Distance(Game.LocalPlayer.Character.Position, ped.Position) < 17.5f) // { // if (new Random().Next(0, 151) < 20) // { // string[] protestSpeeches = { "GENERIC_CURSE_MED", "GENERIC_CURSE_HIGH", "GENERIC_FUCK_YOU" }; // ped.PlayAmbientSpeech(null, protestSpeeches[new Random().Next(protestSpeeches.Length)], 0, SpeechModifier.Force); // } // GameFiber.Sleep(2500); // } // GameFiber.Yield(); // } //}); GameFiber.Sleep(125); while (ped.IsPlayingAnimation("special_ped@griff@monologue_1@monologue_1e", "iamnotaracist_4") && ped.IsPersistent) { GameFiber.Yield(); } if (!hasEnded && pedObj.Exists()) { pedObj.Detach(); } if (!hasEnded && pedObj.Exists()) { pedObj.Dismiss(); } }); } else if (scenario == 3) // DRUNK NUDE GUY { Logger.LogDebug(this.GetType().Name, "Scenario: Drunk nude guy"); ped.SetMovementAnimationSet("move_m@drunk@verydrunk"); ped.Tasks.Wander(); } else if (scenario == 4) // GUITARRIST { Logger.LogDebug(this.GetType().Name, "Scenario: Guitarrist"); ped.Tasks.PlayAnimation("amb@world_human_musician@guitar@male@base", "base", 5.0f, AnimationFlags.UpperBodyOnly | AnimationFlags.SecondaryTask | AnimationFlags.Loop); ped.Tasks.Wander(); pedObj = new Rage.Object(guitarModels.GetRandomElement(true), Vector3.Zero); pedObj.AttachToEntity(ped, ped.GetBoneIndex(PedBoneId.LeftPhHand), Vector3.Zero, Rotator.Zero); GameFiber.StartNew(delegate { GameFiber.Sleep(500); while (ped.IsPlayingAnimation("amb@world_human_musician@guitar@male@base", "base") && ped.IsPersistent) { GameFiber.Yield(); } if (!hasEnded && pedObj.Exists()) { pedObj.Detach(); } if (!hasEnded && pedObj.Exists()) { pedObj.Dismiss(); } }); } else if (scenario == 5) // TOPLESS GIRL { Logger.LogDebug(this.GetType().Name, "Scenario: Topless girl"); ped.Tasks.PlayAnimation("amb@world_human_prostitute@hooker@base", "base", 5.0f, AnimationFlags.UpperBodyOnly | AnimationFlags.SecondaryTask | AnimationFlags.Loop); ped.Tasks.Wander(); } else if (scenario == 6) // SUNBATHE { Logger.LogDebug(this.GetType().Name, "Scenario: Sunbathe"); AnimationDictionary maleAnimDict = sunbatheMale.GetRandomElement(true); AnimationDictionary femaleAnimDict = sunbatheFemale.GetRandomElement(true); if (ped.IsMale) { ped.Tasks.PlayAnimation(maleAnimDict, "base", 2.0f, AnimationFlags.Loop); } else if (ped.IsFemale) { ped.Tasks.PlayAnimation(femaleAnimDict, "base", 2.0f, AnimationFlags.Loop); } ped.BlockPermanentEvents = true; GameFiber.StartNew(delegate { GameFiber.Sleep(500); if (ped.IsMale) { while (ped.IsPlayingAnimation(maleAnimDict, "base") && ped.IsPersistent) { GameFiber.Yield(); } if (!hasEnded && ped.Exists()) { ped.BlockPermanentEvents = false; } } else if (ped.IsFemale) { while (ped.IsPlayingAnimation(femaleAnimDict, "base") && ped.IsPersistent) { GameFiber.Yield(); } if (!hasEnded && ped.Exists()) { ped.BlockPermanentEvents = false; } } }); } else if (scenario == 7) // FREAK OUT GUY { Logger.LogDebug(this.GetType().Name, "Scenario: Freak out guy"); string animName = monkeyFreakOutAnimNames.GetRandomElement(); ped.Tasks.PlayAnimation("missfbi5ig_30monkeys", animName, 5.0f, AnimationFlags.Loop); ped.BlockPermanentEvents = true; GameFiber.StartNew(delegate { GameFiber.Sleep(500); while (ped.IsPlayingAnimation("missfbi5ig_30monkeys", animName) && ped.IsPersistent && ped.Exists()) { GameFiber.Yield(); } if (!hasEnded && ped.Exists()) { ped.BlockPermanentEvents = false; } }); } else if (scenario == 8) // EPSILON { Logger.LogDebug(this.GetType().Name, "Scenario: Epsilon"); ped.Tasks.PlayAnimation("rcmepsilonism3", "ep_3_rcm_marnie_meditating", 2.0f, AnimationFlags.Loop); ped.BlockPermanentEvents = true; GameFiber.StartNew(delegate { GameFiber.Sleep(500); while (!hasEnded) { if (ped.Exists()) { if (Vector3.Distance(Game.LocalPlayer.Character.Position, ped.Position) < 6.0f) { if (ped.IsMale) { ped.PlayAmbientSpeech(epsilonVoicesMale.GetRandomElement(), "KIFFLOM_GREET", 0, SpeechModifier.Force); } else { ped.PlayAmbientSpeech(epsilonVoicesFemale.GetRandomElement(), "KIFFLOM_GREET", 0, SpeechModifier.Force); } break; } } GameFiber.Yield(); } if (!hasEnded && ped.Exists()) { ped.BlockPermanentEvents = false; } }); } else if (scenario == 9) // BONGOS { Logger.LogDebug(this.GetType().Name, "Scenario: Bongos"); ped.Tasks.PlayAnimation("amb@world_human_musician@bongos@male@idle_a", "idle_a", 5.0f, AnimationFlags.UpperBodyOnly | AnimationFlags.SecondaryTask | AnimationFlags.Loop); ped.Tasks.Wander(); pedObj = new Rage.Object(bongosModel, Vector3.Zero); pedObj.AttachToEntity(ped, ped.GetBoneIndex(PedBoneId.LeftPhHand), Vector3.Zero, Rotator.Zero); GameFiber.StartNew(delegate { GameFiber.Sleep(500); while (ped.IsPlayingAnimation("amb@world_human_musician@bongos@male@idle_a", "idle_a") && ped.IsPersistent && ped.Exists()) { GameFiber.Yield(); } if (!hasEnded && pedObj.Exists()) { pedObj.Detach(); } if (!hasEnded && pedObj.Exists()) { pedObj.Dismiss(); } }); } else if (scenario == 10) // BEGGER { Logger.LogDebug(this.GetType().Name, "Scenario: Begger"); string[] idles = { "idle_a", "idle_b", "idle_c" }; string idleUsed = idles.GetRandomElement(); ped.Tasks.PlayAnimation("amb@world_human_bum_freeway@male@idle_a", idleUsed, 5.0f, AnimationFlags.UpperBodyOnly | AnimationFlags.SecondaryTask | AnimationFlags.Loop); ped.Tasks.Wander(); pedObj = new Rage.Object(beggersSignModels.GetRandomElement(), Vector3.Zero); pedObj.AttachToEntity(ped, ped.GetBoneIndex(PedBoneId.RightPhHand), Vector3.Zero, Rotator.Zero); GameFiber.StartNew(delegate { GameFiber.Sleep(125); while (ped.IsPlayingAnimation("amb@world_human_bum_freeway@male@idle_a", idleUsed) && ped.IsPersistent && ped.Exists()) { GameFiber.Yield(); } if (!hasEnded && pedObj.Exists()) { pedObj.Detach(); } if (!hasEnded && pedObj.Exists()) { pedObj.Dismiss(); } }); } else if (scenario == 11) // NUDE GIRL CHEERING { Logger.LogDebug(this.GetType().Name, "Scenario: Topless girl cheering"); char[] letters = { 'a', 'b', 'c', 'd' }; ped.Tasks.PlayAnimation("amb@world_human_cheering@female_" + letters.GetRandomElement(), "base", 5.0f, AnimationFlags.Loop); } else if (scenario == 12) // Pushups { Logger.LogDebug(this.GetType().Name, "Scenario: Pushups"); Tuple <AnimationDictionary, string>[] anims = { new Tuple <AnimationDictionary, string>("amb@world_human_push_ups@male@idle_a", "idle_d"), new Tuple <AnimationDictionary, string>("amb@world_human_push_ups@male@base", "base") }; Tuple <AnimationDictionary, string> animUsed = anims.GetRandomElement(); ped.Tasks.PlayAnimation(animUsed.Item1, animUsed.Item2, 2.0f, AnimationFlags.Loop); ped.BlockPermanentEvents = true; GameFiber.StartNew(delegate { GameFiber.Sleep(500); while (ped.IsPlayingAnimation(animUsed.Item1, animUsed.Item2) && ped.IsPersistent && ped.Exists()) { GameFiber.Yield(); } if (!hasEnded && ped.Exists()) { ped.BlockPermanentEvents = false; } }); } }); }
private void CheckForDeliverTicketTrigger() { if (!Globals.HasTrafficTicketsInHand() && (ShouldEndPullover.HasValue && ShouldEndPullover.Value) && !Game.LocalPlayer.Character.HasScenario()) { ShouldEndPullover = null; GameFiber.StartNew(() => { if (Game.LocalPlayer.LastVehicle && !Game.LocalPlayer.LastVehicle.HasDriver) { Game.DisplayNotification("The driver will wait until you are back in your vehicle before taking off"); } while (Game.LocalPlayer.LastVehicle && !Game.LocalPlayer.LastVehicle.HasDriver) { GameFiber.Yield(); //Wait for the player to enter their vehicle } Function.Log("Starting Ending pull over wait timer for ped to leave"); var stopAt = DateTime.Now.AddMilliseconds(5000); //have the sadPed drive off in 5 seconds if the traffic stop isnt over while (DateTime.Now < stopAt) { GameFiber.Yield(); } try { lock (mPromptedCitations) mPromptedCitations.Clear(); var handle = Functions.GetCurrentPullover(); if (handle != null) { Functions.ForceEndCurrentPullover(); } } catch (Exception e) { Function.LogCatch(e.Message); } }); } else if (Globals.HasTrafficTicketsInHand() && !Game.LocalPlayer.Character.HasScenario()) //only run when we have tickets and we're not already doing WORLD_HUMAN_CLIPBOARD { var stopped = World.GetEntities(Game.LocalPlayer.Character.Position, 2.5f, GetEntitiesFlags.ConsiderAllPeds); if (stopped != null && stopped.Count() > 0) { var pedsAboutToGetTheSmackDown = stopped.Select(x => x as Ped) .Where(x => x.DistanceTo(Game.LocalPlayer.Character.FrontPosition) < 2f && Globals.GetTrafficCitationsInHandForPed(x) != null); //may have to add ordering by distance foreach (var sadPed in pedsAboutToGetTheSmackDown) { if (Configs.GiveTicketsToPed.Any(x => x.IsPressed)) { //The user wants to give the sad ped the ticket now.. GameFiber.StartNew(() => { var item = new Rage.Object(new Model("prop_cs_documents_01"), Game.LocalPlayer.Character.Position); item.AttachTo(Game.LocalPlayer.Character, Game.LocalPlayer.Character.GetBoneIndex(PedBoneId.RightThumb1), new Vector3(item.Model.Dimensions.Length() * 0.4f, 0, 0), Rotator.Zero); Game.LocalPlayer.Character.Tasks.PlayAnimation("mp_common", "givetake1_b", 3f, AnimationFlags.None).WaitForCompletion(); item.Detach(); item.Delete(); }); ShouldEndPullover = true; Globals.RemoveTrafficCitationsInHandForPed(sadPed); break; } else { //Prompt the user that they can deliver the ticket OnFacingPedWithPendingTickets(null, sadPed, Globals.GetTrafficCitationsInHandForPed(sadPed)); } } } } else if (Functions.GetCurrentPullover() == null && Globals.HasTrafficTicketsInHand()) { Globals.ClearTrafficCitationsInHand(); return; } }