예제 #1
0
        public static void Start(MissionType type, int labIndex, List <Vector3> coords, float vehicleHeading, int timeMs, int productAmount = 0)
        {
            if (!IsActive)
            {
                IsActive = true;

                _missionType    = type;
                _missionEndTime = Game.GameTime + timeMs;
                _missionModel   = Game.Player.Character.Model.Hash;
                _missionLabIdx  = labIndex;
                _productAmount  = productAmount;

                _objectiveCoords = coords;

                if (_missionBarPool == null)
                {
                    _missionBarPool = new TimerBarPool();

                    _missionTimeBar = new TextTimerBar("TIME LEFT", "00:00");
                    _missionBarPool.Add(_missionTimeBar);
                }

                foreach (Vector3 pos in _objectiveCoords)
                {
                    Function.Call(Hash.CLEAR_AREA, pos.X, pos.Y, pos.Z, 5f, true, false, false, false);
                }

                // spaghetti
                switch (_missionType)
                {
                case MissionType.Setup:
                {
                    _missionVehicle = World.CreateVehicle(VehicleHash.Pounder, _objectiveCoords[0], vehicleHeading);
                    _missionVehicle.PrimaryColor   = VehicleColor.MetallicBlack;
                    _missionVehicle.SecondaryColor = VehicleColor.MetallicBlack;
                    _missionVehicle.IsPersistent   = true;

                    Blip vehicleBlip = _missionVehicle.AddBlip();
                    vehicleBlip.Sprite       = BlipSprite.Package2;
                    vehicleBlip.Color        = BlipColor.Blue;
                    vehicleBlip.IsShortRange = false;
                    vehicleBlip.Name         = "Supply Truck";

                    Blip deliveryBlip = World.CreateBlip(_objectiveCoords[1]);
                    deliveryBlip.Sprite       = BlipSprite.Standard;
                    deliveryBlip.Color        = BlipColor.Yellow;
                    deliveryBlip.IsShortRange = false;
                    deliveryBlip.Alpha        = 0;
                    deliveryBlip.Name         = "Meth Lab";

                    _missionBlips.Add("vehicle", vehicleBlip);
                    _missionBlips.Add("deliveryPoint", deliveryBlip);

                    NotificationQueue.Add("LJT", $"{Util.GetCharacterFromModel(_missionModel)}, a gang member posted about their supply truck online. Go to {World.GetZoneName(_objectiveCoords[0])} and take it, they won't even know!", "CHAR_LJT", 1);
                    break;
                }

                case MissionType.Delivery:
                {
                    _missionVehicle = World.CreateVehicle(Constants.DeliveryVehicles[Constants.RandomGenerator.Next(0, Constants.DeliveryVehicles.Length)], _objectiveCoords[0], vehicleHeading);
                    _missionVehicle.IsPersistent = true;

                    Blip vehicleBlip = _missionVehicle.AddBlip();
                    vehicleBlip.Sprite       = BlipSprite.Package2;
                    vehicleBlip.Color        = BlipColor.Blue;
                    vehicleBlip.IsShortRange = false;
                    vehicleBlip.Name         = "Delivery Vehicle";

                    Blip deliveryBlip = World.CreateBlip(_objectiveCoords[1]);
                    deliveryBlip.Sprite       = BlipSprite.Standard;
                    deliveryBlip.Color        = BlipColor.Yellow;
                    deliveryBlip.IsShortRange = false;
                    deliveryBlip.Alpha        = 0;
                    deliveryBlip.Name         = "Delivery Point";

                    _missionBlips.Add("vehicle", vehicleBlip);
                    _missionBlips.Add("deliveryPoint", deliveryBlip);

                    NotificationQueue.Add("LJT", $"{Util.GetCharacterFromModel(_missionModel)}, the buyer wants the product to be delivered to {World.GetZoneName(_objectiveCoords[1])}.", "CHAR_LJT", 1);
                    break;
                }
                }

                foreach (Lab lab in Main.MethLabs)
                {
                    lab.SetBlipVisible(false);
                }

                SetStage(MissionStage.GetInVehicle);
            }
        }
예제 #2
0
        public void Script_Tick(object sender, EventArgs e)
        {
            // Load labs
            #region Lab Loading
            if (!MethLabsLoaded && !Game.IsLoading && Game.Player.CanControlCharacter)
            {
                try
                {
                    string labsFile = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "mod_methoperation"), "methoperation_labs.xml");

                    if (!File.Exists(labsFile))
                    {
                        string backupLabsFile = Path.Combine("scripts", "methoperation_labs.xml");

                        Directory.CreateDirectory(Path.GetDirectoryName(labsFile));
                        File.Copy(backupLabsFile, labsFile);
                    }


                    if (File.Exists(labsFile))
                    {
                        MethLabs = XmlUtil.Deserialize <List <Lab> >(File.ReadAllText(labsFile));
                        foreach (Lab lab in MethLabs)
                        {
                            lab.CreateEntities();
                        }

                        ManagementBlip              = World.CreateBlip(Constants.MethLabLaptop);
                        ManagementBlip.Alpha        = 0;
                        ManagementBlip.Sprite       = BlipSprite.Laptop;
                        ManagementBlip.IsShortRange = true;
                        Function.Call(Hash.SET_BLIP_DISPLAY, ManagementBlip.Handle, 8);
                    }
                    else
                    {
                        UI.Notify($"~r~MethOperation labs file not found!");
                    }
                }
                catch (Exception ex)
                {
                    UI.Notify($"~r~MethOperation loading error: {ex.Message}");
                }

                MethLabsLoaded = true;
            }
            #endregion

            // process queued notifications
            if (!NotificationQueue.IsEmpty())
            {
                if (!Game.IsLoading)
                {
                    NotificationQueue.ProcessAll();
                }
            }

            // No need to go further if in a mission
            if (Mission.IsActive)
            {
                return;
            }

            // Update player position
            int gameTime = Game.GameTime;
            if (gameTime > NextUpdate)
            {
                NextUpdate     = gameTime + Constants.UpdateInterval;
                PlayerPosition = Game.Player.Character.Position;

                if (InsideMethLabIdx != -1)
                {
                    int interiorID = Function.Call <int>(Hash.GET_INTERIOR_AT_COORDS_WITH_TYPE, PlayerPosition.X, PlayerPosition.Y, PlayerPosition.Z, "bkr_biker_dlc_int_ware01");
                    if (interiorID != LabInteriorID)
                    {
                        LeftMethLab.Invoke(InsideMethLabIdx, LabExitReason.Teleport);
                        InsideMethLabIdx = -1;
                    }
                    else if (Game.Player.Character.Model.Hash != PlayerLabModel)
                    {
                        LeftMethLab.Invoke(InsideMethLabIdx, LabExitReason.CharacterChange);
                        InsideMethLabIdx = -1;
                    }
                }
            }

            // Draw markers & helptexts
            #region Drawing
            if (InsideMethLabIdx != -1)
            {
                // Handle NativeUI
                ManagementMenuPool.ProcessMenus();

                // Inside, draw interactable markers
                World.DrawMarker(MarkerType.VerticalCylinder, Constants.MethLabExit, Vector3.Zero, Vector3.Zero, Constants.MarkerScale, Constants.MarkerColor);
                World.DrawMarker(MarkerType.VerticalCylinder, Constants.MethLabLaptop, Vector3.Zero, Vector3.Zero, Constants.MarkerScale, Constants.MarkerColor);

                // Laptop screen
                if (LaptopRTID != -1)
                {
                    Function.Call(Hash.SET_TEXT_RENDER_ID, LaptopRTID);
                    Function.Call(Hash._SET_SCREEN_DRAW_POSITION, 73, 73);
                    Function.Call(Hash._SET_2D_LAYER, 4);
                    Function.Call(Hash._0xC6372ECD45D73BCD, true);
                    Function.Call((Hash)0x2BC54A8188768488, "prop_screen_biker_laptop", "prop_screen_biker_laptop_2", 0.5f, 0.5f, 1f, 1f, 0f, 255, 255, 255, 255);
                    Function.Call((Hash)0xE3A3DB414A373DAB);
                    Function.Call(Hash.SET_TEXT_RENDER_ID, 1);
                }

                if (PlayerPosition.DistanceTo(Constants.MethLabExit) <= Constants.MarkerInteractionDistance)
                {
                    CurrentInteractionType = InteractionType.ExitMethLab;
                    Util.DisplayHelpText($"Press {HelpTextKeys.Get(InteractionControl)} to leave the meth lab.");
                }
                else if (PlayerPosition.DistanceTo(Constants.MethLabLaptop) <= Constants.MarkerInteractionDistance)
                {
                    CurrentInteractionType = InteractionType.ManageMethLab;
                    Util.DisplayHelpText($"Press {HelpTextKeys.Get(InteractionControl)} to manage the meth lab.");
                }
                else
                {
                    ManagementMenuPool.CloseAllMenus();

                    if (IsLeaning)
                    {
                        CurrentInteractionType = InteractionType.CancelLean;
                        Util.DisplayHelpText($"Press {HelpTextKeys.Get(InteractionControl)} to stop leaning on the rail.");
                    }
                    else
                    {
                        if (Game.Player.Character.IsInArea(Constants.LeanAreaMin, Constants.LeanAreaMax))
                        {
                            CurrentInteractionType = InteractionType.Lean;
                            Util.DisplayHelpText($"Press {HelpTextKeys.Get(InteractionControl)} to lean on the rail.");
                        }
                    }
                }

                // Disable some controls inside the interior
                for (int i = 0; i < Constants.ControlsToDisable.Length; i++)
                {
                    Function.Call(Hash.DISABLE_CONTROL_ACTION, 2, Constants.ControlsToDisable[i], true);
                }
            }
            else
            {
                // Outside, draw lab markers
                for (int i = 0; i < MethLabs.Count; i++)
                {
                    DistanceToInteractable = PlayerPosition.DistanceTo(MethLabs[i].Position);

                    if (DistanceToInteractable <= Constants.MarkerDrawDistance)
                    {
                        World.DrawMarker(MarkerType.VerticalCylinder, MethLabs[i].Position, Vector3.Zero, Vector3.Zero, Constants.MarkerScale, Constants.MarkerColor);

                        if (DistanceToInteractable <= Constants.MarkerInteractionDistance)
                        {
                            InteractableLabIdx = i;

                            if (MethLabs[i].HasFlag(LabFlags.IsOwned))
                            {
                                CurrentInteractionType = InteractionType.EnterMethLab;
                                Util.DisplayHelpText($"Press {HelpTextKeys.Get(InteractionControl)} to enter the meth lab.");
                            }
                            else
                            {
                                CurrentInteractionType = InteractionType.BuyMethLab;
                                Util.DisplayHelpText($"Press {HelpTextKeys.Get(InteractionControl)} to buy the {MethLabs[i].Location} meth lab.~n~Price: ~g~${MethLabs[i].Price:N0}");
                            }

                            break;
                        }
                    }
                }
            }
            #endregion

            // Handle interactions
            #region Interaction Handling
            if (Game.IsControlJustPressed(2, (Control)InteractionControl))
            {
                int labIdx = InteractableLabIdx == -1 ? InsideMethLabIdx : InteractableLabIdx;
                if (labIdx == -1)
                {
                    return;
                }

                Character currentCharacter = Util.GetCharacterFromModel(Game.Player.Character.Model.Hash);
                if (currentCharacter == Character.Unknown)
                {
                    UI.Notify("Only Michael, Franklin and Trevor can interact with meth labs.");
                    return;
                }

                switch (CurrentInteractionType)
                {
                case InteractionType.BuyMethLab:
                    if (PlayerPosition.DistanceTo(MethLabs[labIdx].Position) > Constants.MarkerInteractionDistance)
                    {
                        return;
                    }

                    if (Game.Player.Money < MethLabs[labIdx].Price)
                    {
                        UI.Notify("You don't have enough money to buy this meth lab.");
                        return;
                    }

                    MethLabs[labIdx].Owner = currentCharacter;

                    MethLabs[labIdx].LastVisit = Util.GetGameDate();
                    MethLabs[labIdx].Flags     = LabFlags.None;
                    MethLabs[labIdx].AddFlag(LabFlags.IsOwned);

                    Game.Player.Money -= MethLabs[InteractableLabIdx].Price;
                    Save();

                    Util.NotifyWithPicture("LJT", $"{currentCharacter}, good call buying the {MethLabs[labIdx].Location} meth lab. Go inside and check the laptop to get started.", "CHAR_LJT", 1);
                    break;

                case InteractionType.EnterMethLab:
                    if (PlayerPosition.DistanceTo(MethLabs[labIdx].Position) > Constants.MarkerInteractionDistance)
                    {
                        return;
                    }

                    if (currentCharacter != MethLabs[labIdx].Owner)
                    {
                        UI.Notify($"Only the owner ({MethLabs[labIdx].Owner}) can enter this meth lab.");
                        return;
                    }

                    if (Game.MissionFlag)
                    {
                        UI.Notify("You can't enter meth labs while being in a mission.");
                        return;
                    }

                    if (Game.Player.WantedLevel > 0)
                    {
                        UI.Notify("You can't enter meth labs while being wanted by the police.");
                        return;
                    }

                    PlayerLabModel   = Game.Player.Character.Model.Hash;
                    InsideMethLabIdx = labIdx;
                    EnteredMethLab.Invoke(labIdx);

                    Game.Player.Character.Position = Constants.MethLabExit;
                    Game.Player.Character.Heading  = Constants.MethLabHeading;
                    Game.Player.Character.Weapons.Select(WeaponHash.Unarmed);
                    break;

                case InteractionType.ExitMethLab:
                    if (PlayerPosition.DistanceTo(Constants.MethLabExit) > Constants.MarkerInteractionDistance)
                    {
                        return;
                    }

                    Game.Player.Character.Position = MethLabs[labIdx].Position;

                    LeftMethLab.Invoke(labIdx, LabExitReason.Player);
                    InsideMethLabIdx = -1;
                    break;

                case InteractionType.ManageMethLab:
                    if (PlayerPosition.DistanceTo(Constants.MethLabLaptop) > Constants.MarkerInteractionDistance)
                    {
                        return;
                    }

                    ManagementMenuPool.RefreshIndex();
                    ManagementMain.Visible = true;
                    break;

                case InteractionType.Lean:
                    if (IsLeaning || !Game.Player.Character.IsInArea(Constants.LeanAreaMin, Constants.LeanAreaMax))
                    {
                        return;
                    }

                    Util.RequestAnimDict("anim@amb@yacht@rail@standing@male@variant_01@");
                    using (TaskSequence tseq = new TaskSequence())
                    {
                        Function.Call(Hash.TASK_GO_STRAIGHT_TO_COORD, 0, Constants.LeanPos.X, Constants.LeanPos.Y, Constants.LeanPos.Z, 1.0f, -1, Constants.LeanHeading, 0.0f);
                        tseq.AddTask.PlayAnimation("anim@amb@yacht@rail@standing@male@variant_01@", "enter");
                        tseq.AddTask.PlayAnimation("anim@amb@yacht@rail@standing@male@variant_01@", "base", 8.0f, -1, AnimationFlags.Loop);
                        tseq.Close();

                        Game.Player.Character.Task.PerformSequence(tseq);
                    }

                    IsLeaning = true;
                    break;

                case InteractionType.CancelLean:
                    if (!IsLeaning)
                    {
                        return;
                    }

                    Game.Player.Character.Task.PlayAnimation("anim@amb@yacht@rail@standing@male@variant_01@", "exit");
                    IsLeaning = false;
                    break;
                }
            }
            #endregion
        }