Example #1
0
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var gameState = rootItem.FindChild("Persistent_Level:PersistentLevel.UnlockSubsystem", false);

            if (gameState == null)
            {
                MessageBox.Show("This save does not contain a UnlockSubsystem.\nThis means that the loaded save is probably corrupt. Aborting.", "Cannot find UnlockSubsystem", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            var numAdditionalSlots = gameState.FindOrCreateField <IntPropertyViewModel>("mNumTotalInventorySlots");

            var dialog = new CheatInventoryWindow
            {
                Owner = Application.Current.MainWindow
            };
            var cvm = (CheatInventoryViewModel)dialog.DataContext;

            cvm.NumberChosen    = numAdditionalSlots.Value;
            cvm.OldSlotsDisplay = numAdditionalSlots.Value;
            dialog.ShowDialog();

            if (cvm.NumberChosen < 0 || cvm.NumberChosen == numAdditionalSlots.Value)
            {
                MessageBox.Show("Inventory slot count unchanged", "Unchanged", MessageBoxButton.OK, MessageBoxImage.Information);
                return(false);
            }

            numAdditionalSlots.Value = cvm.NumberChosen;
            MessageBox.Show($"Inventory slot count set to {cvm.NumberChosen} slots.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            return(true);
        }
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var schematicManager = rootItem.FindChild("Persistent_Level:PersistentLevel.schematicManager", false);

            if (schematicManager == null)
            {
                MissingTagMsg("schematicManager");
                return(false);
            }

            var available = schematicManager.FindField <ArrayPropertyViewModel>("mAvailableSchematics");
            var found     = new HashSet <string>();
            var removed   = 0;

            foreach (var obj in available.Elements.Cast <ObjectPropertyViewModel>().ToList())
            {
                if (found.Contains(obj.Str2))
                {
                    available.RemoveElementCommand.Execute(obj);
                    removed++;
                }
                else
                {
                    found.Add(obj.Str2);
                }
            }

            MessageBox.Show($"Removed {removed} duplicate schematics.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);

            return(true);
        }
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            int doggocount = 1;

            var dialog = new StringPromptWindow
            {
                Owner = Application.Current.MainWindow
            };
            var cvm = (StringPromptViewModel)dialog.DataContext;

            cvm.WindowTitle     = "Enter doggo count";
            cvm.PromptMessage   = "Count (integer):";
            cvm.ValueChosen     = "1";
            cvm.OldValueMessage = "";
            dialog.ShowDialog();

            try
            {
                doggocount = int.Parse(cvm.ValueChosen);
                //MessageBox.Show("" + doggocount);

                if (doggocount > 0)
                {
                    int  counter;
                    bool pastSuccess = true; //don't keep running the loop if one run fails
                    for (counter = 0; counter < doggocount && pastSuccess; counter++)
                    {
                        pastSuccess = deleteEnemiesCheat.AddDoggo(rootItem, saveGame);
                    }

                    if (pastSuccess)
                    {
                        MessageBox.Show("Spawned " + counter + " doggo(s) at the host player.");
                        return(true);
                    }
                    else
                    {
                        //failed to spawn some doggos for some reason
                        return(false);
                    }
                }
                else
                {
                    MessageBox.Show("You can't spawn " + doggocount + " doggos.");
                    return(false);
                }
            }
            catch (Exception)
            {
                if (!(cvm.ValueChosen == "cancel"))
                {
                    MessageBox.Show("Could not parse: " + cvm.ValueChosen);
                }
                return(false);
            }
        }
Example #4
0
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var animalSpawners = rootItem.FindChild("BP_CreatureSpawner.BP_CreatureSpawner_C", false);

            if (animalSpawners == null)
            {
                MessageBox.Show("This save does not contain animals or it is corrupt.", "Cannot find animals", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            float offset          = -50000;
            var   hostPlayerModel = rootItem.FindChild("Char_Player.Char_Player_C", false);

            if (hostPlayerModel == null || hostPlayerModel.Items.Count < 1)
            {
                MessageBox.Show("This save does not contain a host player or it is corrupt.", "Cannot find host player", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            Vector3 playerPosition = ((SaveEntityModel)hostPlayerModel.Items[0]).Position;

            foreach (SaveObjectModel animalSpawner in animalSpawners.DescendantSelfViewModel)
            {
                // Some crab hatchers are marked as CreatureSpawner instead of EnemySpawner and there is no other trace of the difference between enemy and friendly in the savefile
                //if (animalSpawner.Title.ToLower().Contains("enemy"))
                //{
                ((SaveEntityModel)animalSpawner).Position.Z += offset; // Move the spawn under the map
                animalSpawner.FindField("mSpawnData", (ArrayPropertyViewModel arrayProperty) =>
                {
                    foreach (StructPropertyViewModel elem in arrayProperty.Elements)
                    {
                        ((Vector)((StructProperty)((DynamicStructDataViewModel)elem.StructData).Fields[0].Model).Data).Data.Z += offset; // Move the spawn point under the map
                        // Set WasKilled to true so they don't respawn after deleting them
                        ((BoolPropertyViewModel)((DynamicStructDataViewModel)elem.StructData).Fields[2]).Value = true;
                        // Set KilledOnDayNumber to a huge number (some far away animals respawn if the number is too small)
                        ((IntPropertyViewModel)((DynamicStructDataViewModel)elem.StructData).Fields[3]).Value = (int)(Distance(playerPosition, ((Vector)((StructProperty)((DynamicStructDataViewModel)elem.StructData).Fields[0].Model).Data).Data) / 10000);
                    }
                });
            }

            // Delete the already spawned enemies
            var enemies = rootItem.FindChild("Creature", false).FindChild("Enemy", false);

            rootItem.Remove(enemies);

            if (MessageBox.Show($"Deleted all spawned enemies, and all unspawned creatures (enemy & friendly). Would you like 3 tamed Lizzard Doggos as a compensation?", "Success", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                for (int i = 0; i < 3; i++)
                {
                    AddDoggo(rootItem, saveGame);
                }
            }
            return(true);
        }
Example #5
0
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave save)
        {
            var animalSpawners = rootItem.FindChild("BP_CreatureSpawner.BP_CreatureSpawner_C", false);

            if (animalSpawners == null)
            {
                MessageBox.Show("This save does not contain animals or it is corrupt.", "Cannot find animals", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            float offset          = -50000;
            var   hostPlayerModel = rootItem.FindChild("Char_Player.Char_Player_C", false);

            if (hostPlayerModel == null || hostPlayerModel.Items.Count < 1)
            {
                MessageBox.Show("This save does not contain a host player or it is corrupt.", "Cannot find host player", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            Vector3 playerPosition = ((SaveEntityModel)hostPlayerModel.Items[0]).Position;

            foreach (SaveObjectModel animalSpawner in animalSpawners.DescendantSelfViewModel)
            {
                var probablyEdited = ((SaveEntityModel)animalSpawner).Position.Z < -14200f;

                // Some crab hatchers are marked as CreatureSpawner instead of EnemySpawner and there is no other trace of the difference between enemy and friendly in the savefile
                //if (animalSpawner.Title.ToLower().Contains("enemy"))
                //{
                if (probablyEdited)
                {
                    ((SaveEntityModel)animalSpawner).Position.Z -= offset; // Move the spawn under the map
                }
                animalSpawner.FindField("mSpawnData", (ArrayPropertyViewModel arrayProperty) =>
                {
                    foreach (StructPropertyViewModel elem in arrayProperty.Elements)
                    {
                        if (probablyEdited)
                        {
                            ((Vector)((StructProperty)((DynamicStructDataViewModel)elem.StructData).Fields[0].Model).Data).Data.Z -= offset; // Move the spawn point under the map
                        }
                        // Set WasKilled to true so they don't respawn after deleting them
                        ((BoolPropertyViewModel)((DynamicStructDataViewModel)elem.StructData).Fields[2]).Value = false;
                        // Set KilledOnDayNumber to a huge number (some far away animals respawn if the number is too small)
                        ((IntPropertyViewModel)((DynamicStructDataViewModel)elem.StructData).Fields[3]).Value = (int)0;
                    }
                });
            }

            return(true);
        }
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var gameState = rootItem.FindChild("Persistent_Level:PersistentLevel.BP_GameState_C_0", false);

            if (gameState == null)
            {
                MessageBox.Show("This save does not contain a GameState.\nThis means that the loaded save is probably corrupt. Aborting.", "Cannot find GameState", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            var numAdditionalSlots = gameState.FindOrCreateField <BoolPropertyViewModel>("mCheatNoCost");

            numAdditionalSlots.Value = !numAdditionalSlots.Value;
            MessageBox.Show($"{(numAdditionalSlots.Value ? "Enabled" : "Disabled")} no building cost cheat", "Success", MessageBoxButton.OK, MessageBoxImage.Information);

            return(true);
        }
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var gameState = rootItem.FindChild("Persistent_Level:PersistentLevel.BP_GameState_C_*", false);

            if (gameState == null)
            {
                MessageBox.Show("This save does not contain a GameState.\nThis means that the loaded save is probably corrupt. Aborting.", "Cannot find GameState", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            var numAdditionalSlots = gameState.FindOrCreateField <BoolPropertyViewModel>("mCheatNoPower");

            numAdditionalSlots.Value = !numAdditionalSlots.Value;
            MessageBox.Show((numAdditionalSlots.Value ? "Enabled no power cheat.\nNote that buildings still need to be connected to an electrical network to function" : "Disabled no power cheat"), "Success", MessageBoxButton.OK, MessageBoxImage.Information);

            return(true);
        }
Example #8
0
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var gameState = rootItem.FindChild("Persistent_Level:PersistentLevel.UnlockSubsystem", false);

            if (gameState == null)
            {
                MessageBox.Show("This save does not contain an UnlockSubsystem.\nThis means that the loaded save is probably corrupt. Aborting.", "Cannot find UnlockSubsystem", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            var isMapUnlocked = gameState.FindOrCreateField <BoolPropertyViewModel>("mIsMapUnlocked");

            isMapUnlocked.Value = true;

            MessageBox.Show("Map unlocked", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            return(true);
        }
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var slugTypes = new[] {
                "/Game/FactoryGame/Resource/Environment/Crystal/BP_Crystal.BP_Crystal_C",
                "/Game/FactoryGame/Resource/Environment/Crystal/BP_Crystal_mk2.BP_Crystal_mk2_C",
                "/Game/FactoryGame/Resource/Environment/Crystal/BP_Crystal_mk3.BP_Crystal_mk3_C"
            };

            var slugs = saveGame.Entries.Where(x => slugTypes.Contains(x.TypePath));

            saveGame.CollectedObjects.RemoveAll(x => x.PathName.Contains("PersistentLevel.BP_Crystal"));
            saveGame.CollectedObjects.AddRange(slugs.Select(s => new ObjectReference
            {
                LevelName = s.RootObject,
                PathName  = s.InstanceName
            }));

            return(true);
        }
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            BuildPolygon();
            if (polygon.Length < 2)
            {
                MessageBox.Show("At least 2 points needed to mass dismantle", "Could not mass dismantle", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            ArrayProperty inventory = new ArrayProperty("mInventoryStacks")
            {
                Type = "StructProperty"
            };
            int countFactory = 0, countBuilding = 0, countCrate = 0;

            try
            {
                countFactory = MassDismantle(rootItem.FindChild("Buildable", true).FindChild("Factory", true).DescendantSelfViewModel, inventory, rootItem);
            }
            catch (NullReferenceException) { }
            try
            {
                countBuilding = MassDismantle(rootItem.FindChild("Buildable", true).FindChild("Building", true).DescendantSelfViewModel, inventory, rootItem);
            }
            catch (NullReferenceException) { }
            try
            {
                countCrate = MassDismantle(rootItem.FindChild("-Shared", true).FindChild("BP_Crate.BP_Crate_C", true).DescendantSelfViewModel, inventory, rootItem);
            }
            catch (NullReferenceException) { }
            if (countFactory + countBuilding + countCrate == 0)
            {
                MessageBox.Show("Nothing was dismantled. Make sure the coordinates are correct and in clockwise order.", "Mass dismantle", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            MessageBoxResult result = MessageBox.Show($"Dismantled {countFactory} factory buildings, {countBuilding} foundations and {countCrate} crates. Drop the items (including items in storages) in a single crate?", "Dismantled", MessageBoxButton.YesNo, MessageBoxImage.Question);

            if (result == MessageBoxResult.Yes)
            {
                CreateCrateEntityFromInventory(rootItem, inventory);
            }
            return(true);
        }
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var cratesList = rootItem.FindChild("BP_Crate.BP_Crate_C", false);

            if (cratesList == null)
            {
                MessageBox.Show("This save does not appear to have any crates.\nCrates appear on death and when your inventory is too full to hold items during deconstruction.", "Cannot find any Crates", MessageBoxButton.OK, MessageBoxImage.Information);
                return(false);
            }

            var hostPlayerModel = rootItem.FindChild("Char_Player.Char_Player_C", false);

            if (hostPlayerModel == null || hostPlayerModel.Items.Count < 1)
            {
                MessageBox.Show("This save does not contain a host player or it is corrupt.\nTry loading and re-saving the save from within the game.", "Cannot find host player", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            var playerEntityModel = (SaveEntityModel)hostPlayerModel.Items[0];

            int crateSpacingOffset = 80;
            int stackHeight        = 5;

            float playerX = playerEntityModel.Position.X + (1.5f * crateSpacingOffset);
            float playerY = playerEntityModel.Position.Y;
            float playerZ = playerEntityModel.Position.Z - crateSpacingOffset;

            int counter = 0;

            foreach (SaveObjectModel thisCrate in cratesList.DescendantSelfViewModel)
            {
                //MessageBox.Show($"Modifying crate {counter}: {thisCrate.ToString()}");
                ((SaveEntityModel)thisCrate).Position.X = playerX + ((counter / stackHeight) * crateSpacingOffset);//((counter % stackHeight == 0) ? crateHeightSpacingOffset * counter / stackHeight : 0);
                ((SaveEntityModel)thisCrate).Position.Y = playerY;
                ((SaveEntityModel)thisCrate).Position.Z = playerZ + (crateSpacingOffset * (counter % stackHeight));
                counter++;
            }
            MessageBox.Show($"Successfully moved {counter} crates to the host player. They are stacked in piles of 5 slightly east of you.");
            return(true);
        }
Example #12
0
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var gameState = rootItem.FindChild("Persistent_Level:PersistentLevel.UnlockSubsystem", false);

            if (gameState == null)
            {
                MessageBox.Show("This save does not contain a UnlockSubsystem.\nThis means that the loaded save is probably corrupt. Aborting.", "Cannot find UnlockSubsystem", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            var numAdditionalArmSlots = gameState.FindOrCreateField <IntPropertyViewModel>("mNumTotalArmEquipmentSlots");

            var dialog = new CheatInventoryWindow //reusing CheatInventory since it's the same kind of prompt
            {
                Owner = Application.Current.MainWindow
            };
            var cvm = (CheatInventoryViewModel)dialog.DataContext;

            cvm.NumberChosen    = numAdditionalArmSlots.Value;
            cvm.OldSlotsDisplay = numAdditionalArmSlots.Value;
            dialog.ShowDialog();

            if (cvm.NumberChosen < 0 || cvm.NumberChosen == numAdditionalArmSlots.Value)
            {
                MessageBox.Show("Arm slot count unchanged", "Unchanged", MessageBoxButton.OK, MessageBoxImage.Information);
                return(false);
            }

            numAdditionalArmSlots.Value = cvm.NumberChosen;
            string message = $"Arm slot count set to {cvm.NumberChosen} slots.\n\nPlease note that you may need to complete at least one milestone that unlocks arm slots for your changes to take effect.";

            if (numAdditionalArmSlots.Value > 6)
            {
                message += "\n\nArm slot counts greater than 6 cause visual problems in the inventory screen.";
            }
            MessageBox.Show(message, "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            return(true);
        }
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var sinkSubsystem = rootItem.FindChild("Persistent_Level:PersistentLevel.ResourceSinkSubsystem", false);

            if (sinkSubsystem == null)
            {
                MessageBox.Show("This save does not contain a ResourceSinkSubsystem.\nThis means that the loaded save is probably corrupt. Aborting.", "Cannot find ResourceSinkSubsystem", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            var pointsTowardsCurrentTicket = sinkSubsystem.FindOrCreateField <Int64PropertyViewModel>("mTotalResourceSinkPoints");
            var mCurrentPointLevel         = sinkSubsystem.FindOrCreateField <IntPropertyViewModel>("mCurrentPointLevel");

            var dialog = new StringPromptWindow
            {
                Owner = Application.Current.MainWindow
            };
            var cvm = (StringPromptViewModel)dialog.DataContext;

            cvm.WindowTitle     = "Enter earned ticket count";
            cvm.PromptMessage   = "Tickets";
            cvm.ValueChosen     = "0";
            cvm.OldValueMessage = $"Sets the AWESOME Sink ticket prices as if you had earned N tickets.\nFor example, entering 0 sets the price for the next ticket back to 1,000\nCurrent tickets earned: {mCurrentPointLevel.Value}\nMore info on AWESOME Sink wiki page";
            dialog.ShowDialog();

            int requestedTicketCount = 0;

            try
            {
                requestedTicketCount = int.Parse(cvm.ValueChosen);

                if (requestedTicketCount < 0)
                {
                    MessageBox.Show("You must enter a number greater than 0.", "Ticket count unchanged.", MessageBoxButton.OK, MessageBoxImage.Error);
                    return(false);
                }
                else if (requestedTicketCount > 288100000)
                {
                    MessageBox.Show("The highest ticket count supported is about 288,100,000, since the highest supported points per ticket is around 9,223,372,036,854,775,807 (int64 max value)", "That's a lot of tickets!");
                    return(false);
                }

                mCurrentPointLevel.Value = requestedTicketCount; //"point level" is 0 if no tickets have been earned, 1 if one ticket has, etc.

                pointsTowardsCurrentTicket.Value = 0;            //reset progress towards the current ticket so the game GUI doesn't get confused

                long calculatedPointsCount = pointsRequiredFromTicketCount(requestedTicketCount);

                MessageBox.Show($"Earned ticket count set to {requestedTicketCount}.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
                //MessageBox.Show($"Ticket count set to {requestedTicketCount}. The next ticket will take {calculatedPointsCount} points to earn.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
                return(true);
            }
            catch (Exception)
            {
                if (!(cvm.ValueChosen == "cancel"))
                {
                    MessageBox.Show($"Could not parse: {cvm.ValueChosen}");
                }
                return(false);
            }
        }
Example #14
0
 public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
 {
     saveGame.CollectedObjects.RemoveAll(x => x.PathName.Contains("PersistentLevel.BP_Crystal"));
     return(true);
 }
Example #15
0
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var tutorialManager = rootItem.FindChild("Persistent_Level:PersistentLevel.TutorialIntroManager", false);

            if (tutorialManager == null)
            {
                MissingTagMsg("TutorialIntroManager");
                return(false);
            }

            var schematicManager = rootItem.FindChild("Persistent_Level:PersistentLevel.schematicManager", false);

            if (schematicManager == null)
            {
                MissingTagMsg("schematicManager");
                return(false);
            }

            var gameState = rootItem.FindChild("Persistent_Level:PersistentLevel.BP_GameState_C_*", false);

            if (gameState == null)
            {
                MissingTagMsg("GameState");
                return(false);
            }

            var gamePhaseManager = rootItem.FindChild("Persistent_Level:PersistentLevel.GamePhaseManager", false);

            if (gamePhaseManager == null)
            {
                MissingTagMsg("GamePhaseManager");
                return(false);
            }

            var unlockSystem = rootItem.FindChild("Persistent_Level:PersistentLevel.UnlockSubsystem", false);

            if (unlockSystem == null)
            {
                MissingTagMsg("UnlockSubsystem");
                return(false);
            }

            var tradingPostBuilt = tutorialManager.FindField <BoolPropertyViewModel>("mTradingPostBuilt");

            if (tradingPostBuilt == null)
            {
                MessageBox.Show("You should build a hub before attempting to unlock all research.", "No hub found", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            var availableSchematics = schematicManager.FindField <ArrayPropertyViewModel>("mAvailableSchematics");
            var purchasedSchematics = schematicManager.FindField <ArrayPropertyViewModel>("mPurchasedSchematics");

            var researches = Research.GetResearches().Select(r => r.Path);

            var purchasedList = purchasedSchematics.Elements.Cast <ObjectPropertyViewModel>().Select(o => o.Str2);
            var availableList = researches.Union(availableSchematics.Elements.Cast <ObjectPropertyViewModel>().Select(o => o.Str2)).Except(purchasedList);

            var window = new UnlockResearchWindow()
            {
                Owner = Application.Current.MainWindow
            };
            var vm = (UnlockResearchWindowViewModel)window.DataContext;

            vm.Available = new ObservableCollection <string>(availableList);
            vm.Unlocked  = new ObservableCollection <string>(purchasedList);

            if (!window.ShowDialog().Value)
            {
                return(false);
            }

            purchasedSchematics.Elements.Clear();
            foreach (var item in vm.Unlocked)
            {
                purchasedSchematics.Elements.Add(new ObjectPropertyViewModel(new ObjectProperty(null, "", item)));

                //if (!availableList.Any(x => x == item))
                //{
                //    availableSchematics.Elements.Add(new ObjectPropertyViewModel(new ObjectProperty(null, "", item)));
                //}
            }

            //clear PaidOffSchematic and ActiveSchematic fields so the progress indicator in the top right doesn't linger after unlocking
            var paidOffSchematicField = schematicManager.FindField <ArrayPropertyViewModel>("mPaidOffSchematic");
            var activeSchematicField  = schematicManager.FindField <ObjectPropertyViewModel>("mActiveSchematic");

            schematicManager.RemovePropertyCommand.Execute(paidOffSchematicField);
            schematicManager.RemovePropertyCommand.Execute(activeSchematicField);

            tutorialManager.FindOrCreateField <EnumPropertyViewModel>("mPendingTutorial", f => f.Value = "EIntroTutorialSteps::ITS_DONE");
            tutorialManager.FindOrCreateField <IntPropertyViewModel>("mTradingPostLevel", f => f.Value = 6);
            CreateOrSetBoolField(tutorialManager, "mHasCompletedIntroTutorial", true);
            CreateOrSetBoolField(tutorialManager, "mHasCompletedIntroSequence", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep1Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep1_5Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep2Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep3Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep4Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep5Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidPickUpIronOre", true);
            CreateOrSetBoolField(tutorialManager, "mDidDismantleDropPod", true);
            CreateOrSetBoolField(tutorialManager, "mDidEquipStunSpear", true);
            CreateOrSetBoolField(tutorialManager, "mDidOpenCodex", true);

            // TODO: Set GameState->mScannableResources
            CreateOrSetBoolField(unlockSystem, "mIsMapUnlocked", true);
            CreateOrSetBoolField(unlockSystem, "mIsBuildingEfficiencyUnlocked", true);
            CreateOrSetBoolField(unlockSystem, "mIsBuildingOverclockUnlocked", true);

            gamePhaseManager.FindOrCreateField <BytePropertyViewModel>("mGamePhase", f =>
            {
                f.Value = "EGP_EndGame";
                f.Type  = "EGamePhase";
            });

            MessageBox.Show("Research successfully unlocked.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            return(true);
        }
Example #16
0
        public bool AddDoggo(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            currentDoggoID = GetNextDoggoID(currentDoggoID, rootItem);

            var hostPlayerModel = rootItem.FindChild("Char_Player.Char_Player_C", false);

            if (hostPlayerModel == null || hostPlayerModel.Items.Count < 1)
            {
                MessageBox.Show("This save does not contain a host player or it is corrupt.", "Cannot find host player", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            var player = (SaveEntityModel)hostPlayerModel.Items[0];

            SaveComponent healthComponent = new SaveComponent("/Script/FactoryGame.FGHealthComponent", "Persistent_Level", $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}.HealthComponent")
            {
                DataFields       = new SerializedFields(),
                ParentEntityName = $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}"
            };

            byte[]        bytes = PrepareForParse("", 0);
            SaveComponent inventoryComponent;

            using (BinaryReader reader = new BinaryReader(new MemoryStream(bytes)))
            {
                inventoryComponent = new SaveComponent("/Script/FactoryGame.FGInventoryComponent", "Persistent_Level", $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}.mInventory")
                {
                    DataFields = new SerializedFields()
                    {
                        new ArrayProperty("mInventoryStacks")
                        {
                            Type     = StructProperty.TypeName,
                            Elements = new System.Collections.Generic.List <SerializedProperty>()
                            {
                                SerializedProperty.Parse(reader, saveGame.Header.BuildVersion)
                            }
                        },
                        new ArrayProperty("mArbitrarySlotSizes")
                        {
                            Type     = IntProperty.TypeName,
                            Elements = new System.Collections.Generic.List <SerializedProperty>()
                            {
                                new IntProperty("Element")
                                {
                                    Value = 0
                                }
                            }
                        },
                        new ArrayProperty("mAllowedItemDescriptors")
                        {
                            Type     = ObjectProperty.TypeName,
                            Elements = new System.Collections.Generic.List <SerializedProperty>()
                            {
                                new ObjectProperty("Element")
                                {
                                    LevelName = "", PathName = ""
                                }
                            }
                        }
                    },
                    ParentEntityName = $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}"
                };
            }
            SaveEntity doggo = new SaveEntity("/Game/FactoryGame/Character/Creature/Wildlife/SpaceRabbit/Char_SpaceRabbit.Char_SpaceRabbit_C", "Persistent_Level", $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}")
            {
                NeedTransform = true,
                Rotation      = ((SaveEntity)player.Model).Rotation,
                Position      = new Vector3()
                {
                    X = ((SaveEntity)player.Model).Position.X,
                    Y = ((SaveEntity)player.Model).Position.Y + 100 + 10 * currentDoggoID, // so they don't glitch one into another like the tractors did
                    Z = ((SaveEntity)player.Model).Position.Z + 10
                },
                Scale = new Vector3()
                {
                    X = 1, Y = 1, Z = 1
                },
                WasPlacedInLevel = false,
                ParentObjectName = "",
                ParentObjectRoot = ""
            };

            doggo.Components = new System.Collections.Generic.List <SatisfactorySaveParser.Structures.ObjectReference>()
            {
                new SatisfactorySaveParser.Structures.ObjectReference()
                {
                    LevelName = "Persistent_Level", PathName = $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}.mInventory"
                },
                new SatisfactorySaveParser.Structures.ObjectReference()
                {
                    LevelName = "Persistent_Level", PathName = $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}.HealthComponent"
                }
            };
            byte[] emptyDynamicStructData = { 0x05, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x6e, 0x65 }; // Length prefixed "None"
            using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(emptyDynamicStructData)))
            {
                doggo.DataFields = new SerializedFields()
                {
                    new ObjectProperty("mFriendActor")
                    {
                        LevelName = "Persistent_Level", PathName = player.Title
                    },
                    new IntProperty("mLootTableIndex")
                    {
                        Value = 0
                    },
                    new StructProperty("mLootTimerHandle")
                    {
                        Data = new DynamicStructData(binaryReader, "TimerHandle", saveGame.Header.BuildVersion),
                        Unk1 = 0,
                        Unk2 = 0,
                        Unk3 = 0,
                        Unk4 = 0,
                        Unk5 = 0
                    },
                    new BoolProperty("mIsPersistent")
                    {
                        Value = true
                    },
                    new ObjectProperty("mHealthComponent")
                    {
                        LevelName = "Persistent_Level", PathName = $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}.HealthComponent"
                    }
                };
            }
            FindOrCreatePath(rootItem, new string[] { "Character", "Creature", "Wildlife", "SpaceRabbit", "Char_SpaceRabbit.Char_SpaceRabbit_C" }).Items.Add(new SaveEntityModel(doggo));
            rootItem.FindChild("FactoryGame.FGInventoryComponent", false).Items.Add(new SaveComponentModel(inventoryComponent));
            rootItem.FindChild("FactoryGame.FGHealthComponent", false).Items.Add(new SaveComponentModel(healthComponent));
            return(true);
        }
Example #17
0
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var hostPlayerModel = rootItem.FindChild("Char_Player.Char_Player_C", false);

            if (hostPlayerModel == null || hostPlayerModel.Items.Count < 1)
            {
                MessageBox.Show("This save does not contain a host player or it is corrupt.\nTry loading and re-saving the save from within the game.", "Cannot find host player", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            var playerEntityModel = (SaveEntityModel)hostPlayerModel.Items[0];

            int itemStackQuantity = 500;

            var dialog = new StringPromptWindow
            {
                Owner = Application.Current.MainWindow
            };
            var cvm = (StringPromptViewModel)dialog.DataContext;

            cvm.WindowTitle     = "Enter quantity of each item to spawn";
            cvm.PromptMessage   = "Count (integer):";
            cvm.ValueChosen     = "500";
            cvm.OldValueMessage = "";
            dialog.ShowDialog();

            try
            {
                itemStackQuantity = int.Parse(cvm.ValueChosen);

                if (itemStackQuantity <= 0)
                {
                    MessageBox.Show("The quantity you entered is invalid.");
                    return(false);
                }
            }
            catch (Exception)
            {
                if (!(cvm.ValueChosen == "cancel"))
                {
                    MessageBox.Show("Could not parse: " + cvm.ValueChosen);
                }
                return(false);
            }

            ArrayProperty inventory = new ArrayProperty("mInventoryStacks")
            {
                Type = "StructProperty"
            };

            HashSet <string> resourceStrings    = new HashSet <string>();
            HashSet <string> radioactiveStrings = new HashSet <string>();

            //dump all resources in a hashset first to remove duplicates TODO consider making a hashmap to numbers so they maintain order
            foreach (var resource in Resource.GetResources())
            {
                if (resource.IsRadioactive)
                {
                    radioactiveStrings.Add(resource.Path);
                }
                else
                {
                    resourceStrings.Add(resource.Path);
                }
            }

            //Populate the inventory with every item in ResourcesUnfiltered.xml
            foreach (var resource in resourceStrings)
            {
                if (!radioactiveStrings.Contains(resource))//because duplicates can be in the xml file in order, still need to check every string here for radioactivity
                {
                    //MessageBox.Show($"Processing resource {resource}");
                    byte[] bytes = MassDismantleCheat.PrepareForParse(resource, itemStackQuantity); //reuse mass dismantle cheat's parsing method
                    using (MemoryStream ms = new MemoryStream(bytes))
                        using (BinaryReader reader = new BinaryReader(ms))
                        {
                            SerializedProperty prop = SerializedProperty.Parse(reader);
                            inventory.Elements.Add(prop);
                        }
                }
            }

            string skipped = "";

            foreach (string radioactiveResource in radioactiveStrings)
            {
                skipped += $"{radioactiveResource.Split('.')[1]}\n";
            }

            //Use Mass Dismantle Cheat's crate creation function to package the items into a crate entity
            MassDismantleCheat.CreateCrateEntityFromInventory(rootItem, inventory);

            //MessageBox.Show("Player name " + playerEntityModel.Title);
            MessageBox.Show($"Crate created.\nNote that normally unstackable items will visually display as being stacked to 1. Use Ctrl+Click to transfer items out of the crate without deleting part of the stack.\n\nSkipped the following items marked as radioactive:\n\n{skipped}", $"Processed {resourceStrings.Count} resource paths");

            //Ask the player if they'd like the be equipped with a hazmat suit and filters since the box will be radioactive

            /*MessageBoxResult result = MessageBox.Show("A crate with all resources has been generated at your feet. This includes radioactive items. Would you like a Hazmat suit and filters? They will replace your current equipment and first inventory item.", $"Processed {resourceStrings.Count} resource paths", MessageBoxButton.YesNo, MessageBoxImage.Question);
             * if (result == MessageBoxResult.Yes)
             * {
             *  string hazmatPath = "/Game/FactoryGame/Resource/Equipment/HazmatSuit/BP_EquipmentDescriptorHazmatSuit.BP_EquipmentDescriptorHazmatSuit_C";
             *  string filterPath = "/Game/FactoryGame/Resource/Parts/IodineInfusedFilter/Desc_HazmatFilter.Desc_HazmatFilter_C";
             *
             *  //playerEntityModel.FindOrCreateField<ObjectProperty>("mInventory");
             *  var playerName = playerEntityModel.Title;
             *  var playerBackSlot = rootItem.FindChild(playerName + ".BackSlot", true);
             *  if (playerBackSlot == null)
             *  {
             *      MessageBox.Show("Your player does not seem to have an associated back slot.\nThe crate has still been created, but you have not been given Hazmat equipment.", "Cannot find host player inventory.", MessageBoxButton.OK, MessageBoxImage.Warning);
             *  }
             *  else
             *  {
             *      //MessageBox.Show(playerBackSlot.FindOrCreateField<ArrayPropertyViewModel>("mInventoryStacks").Elements[0]);
             *      MessageBox.Show("Currently unimplemented");
             *  }
             * }*/

            return(true);
        }
Example #18
0
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var tutorialManager = rootItem.FindChild("Persistent_Level:PersistentLevel.TutorialIntroManager", false);

            if (tutorialManager == null)
            {
                MissingTagMsg("TutorialIntroManager");
                return(false);
            }

            var schematicManager = rootItem.FindChild("Persistent_Level:PersistentLevel.schematicManager", false);

            if (schematicManager == null)
            {
                MissingTagMsg("schematicManager");
                return(false);
            }

            var gameState = rootItem.FindChild("Persistent_Level:PersistentLevel.BP_GameState_C_*", false);

            if (gameState == null)
            {
                MissingTagMsg("GameState");
                return(false);
            }

            var gamePhaseManager = rootItem.FindChild("Persistent_Level:PersistentLevel.GamePhaseManager", false);

            if (gamePhaseManager == null)
            {
                MissingTagMsg("GamePhaseManager");
                return(false);
            }

            var tradingPostBuilt = tutorialManager.FindField <BoolPropertyViewModel>("mTradingPostBuilt");

            if (tradingPostBuilt == null)
            {
                MessageBox.Show("You should build a hub before attempting to unlock all research.", "No hub found", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            tutorialManager.FindOrCreateField <EnumPropertyViewModel>("mPendingTutorial", f => f.Value = "EIntroTutorialSteps::ITS_DONE");
            tutorialManager.FindOrCreateField <IntPropertyViewModel>("mTradingPostLevel", f => f.Value = 5);
            CreateOrSetBoolField(tutorialManager, "mHasCompletedIntroTutorial", true);
            CreateOrSetBoolField(tutorialManager, "mHasCompletedIntroSequence", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep1Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep2Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep3Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep4Upgrade", true);
            CreateOrSetBoolField(tutorialManager, "mDidStep5Upgrade", true);


            // TODO: Set GameState->mScannableResources
            CreateOrSetBoolField(gameState, "mIsBuildingEfficiencyUnlocked", true);
            CreateOrSetBoolField(gameState, "mIsBuildingOverclockUnlocked", true);

            gamePhaseManager.FindOrCreateField <BytePropertyViewModel>("mGamePhase", f =>
            {
                f.Value = "EGP_EndGame";
                f.Type  = "EGamePhase";
            });

            foreach (var field in schematicManager.Fields)
            {
                if (field.PropertyName == "mAvailableSchematics" || field.PropertyName == "mPurchasedSchematics")
                {
                    if (!(field is ArrayPropertyViewModel arrayField))
                    {
                        MessageBox.Show("Expected schematic data is of wrong type.\nThis means that the loaded save is probably corrupt. Aborting.", "Wrong schematics type", MessageBoxButton.OK, MessageBoxImage.Error);
                        return(false);
                    }

                    foreach (var research in Research.GetResearches())
                    {
                        if (!arrayField.Elements.Cast <ObjectPropertyViewModel>().Any(e => e.Str2 == research.Path))
                        {
                            arrayField.Elements.Add(new ObjectPropertyViewModel(new ObjectProperty(null, "", research.Path)));
                        }
                    }
                }
            }

            //clear PaidOffSchematic and ActiveSchematic fields so the progress indicator in the top right doesn't linger after unlocking
            var paidOffSchematicField = schematicManager.FindField <ArrayPropertyViewModel>("mPaidOffSchematic");
            var activeSchematicField  = schematicManager.FindField <ObjectPropertyViewModel>("mActiveSchematic");

            schematicManager.RemovePropertyCommand.Execute(paidOffSchematicField);
            schematicManager.RemovePropertyCommand.Execute(activeSchematicField);

            MessageBox.Show("All research successfully unlocked.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            return(true);
        }
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var players = rootItem.FindChild("Char_Player.Char_Player_C", false);

            if (players == null)
            {
                MessageBox.Show("This save does not contain a Player.\nThis means that the loaded save is probably corrupt. Aborting.", "Cannot find Player", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            int currentStorageID = 0;

            foreach (SaveObjectModel player in players.DescendantSelfViewModel)
            {
                string          inventoryPath      = player.FindField <ObjectPropertyViewModel>("mInventory").Str2;
                SaveObjectModel inventoryState     = rootItem.FindChild(inventoryPath, false);
                SaveComponent   inventoryComponent = (SaveComponent)inventoryState.Model;
                if (!InventoryEmpty(inventoryComponent))
                {
                    currentStorageID = GetNextStorageID(currentStorageID, rootItem);
                    SaveComponent newInventory = new SaveComponent(inventoryComponent.TypePath, inventoryComponent.RootObject, $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}.inventory")
                    {
                        ParentEntityName = $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}",
                        DataFields       = inventoryComponent.DataFields
                    };
                    rootItem.FindChild("FactoryGame.FGInventoryComponent", false).Items.Add(new SaveComponentModel(newInventory));
                    SaveEntity newSaveObject = new SaveEntity("/Game/FactoryGame/-Shared/Crate/BP_Crate.BP_Crate_C", "Persistent_Level", $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}")
                    {
                        NeedTransform = true,
                        Rotation      = ((SaveEntity)player.Model).Rotation,
                        Position      = ((SaveEntity)player.Model).Position,
                        Scale         = new Vector3()
                        {
                            X = 1, Y = 1, Z = 1
                        },
                        WasPlacedInLevel = false,
                        ParentObjectName = "",
                        ParentObjectRoot = ""
                    };
                    newSaveObject.DataFields = new SerializedFields()
                    {
                        TrailingData = null
                    };
                    newSaveObject.DataFields.Add(new ObjectProperty("mInventory", 0)
                    {
                        LevelName = "Persistent_Level", PathName = $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}.inventory"
                    });
                    if (rootItem.FindChild("Crate", false) == null)
                    {
                        rootItem.FindChild("-Shared", false).Items.Add(new SaveObjectModel("Crate"));
                    }
                    if (rootItem.FindChild("BP_Crate.BP_Crate_C", false) == null)
                    {
                        rootItem.FindChild("Crate", false).Items.Add(new SaveObjectModel("BP_Crate.BP_Crate_C"));
                    }
                    rootItem.FindChild("BP_Crate.BP_Crate_C", false).Items.Add(new SaveEntityModel(newSaveObject));
                }
                rootItem.Remove(player);
                rootItem.Remove(inventoryState);
                MessageBox.Show($"Killed {player.Title}.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            return(true);
        }
Example #20
0
        public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
        {
            var mapManager = rootItem.FindChild("Persistent_Level:PersistentLevel.MapManager", false);

            if (mapManager == null)
            {
                MessageBox.Show("This save does not contain a MapManager.\nThis means that the loaded save is probably corrupt. Aborting.", "Cannot find MapManager", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            //map data is an Array(Byte) containing 1048576 elements ranging from 0 to 255, where 255 is fully revealed.
            var fogOfWarRawData = mapManager.FindOrCreateField <ArrayPropertyViewModel>("mFogOfWarRawData");

            if (!(fogOfWarRawData is ArrayPropertyViewModel))
            {
                MessageBox.Show("FogOfWarRawData is of wrong type.\nThis means that the loaded save is probably corrupt. Aborting.", "Wrong property type", MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }

            if (fogOfWarRawData.Elements.Count != 1048576)
            {
                MessageBox.Show($"Expected 1048576 fog of war elements to be present, but there were actually {fogOfWarRawData.Elements.Count}.\nThis does not necessarily mean that the process will fail. Please report this error on the Github Issues page regardless.", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
            }

            int mapRevealThreshold = 0;

            var dialog = new StringPromptWindow
            {
                Owner = Application.Current.MainWindow
            };
            var cvm = (StringPromptViewModel)dialog.DataContext;

            cvm.WindowTitle     = "Enter map reveal threshold";
            cvm.PromptMessage   = "Enter a number between 0 and 255 (integer):";
            cvm.ValueChosen     = "255";
            cvm.OldValueMessage = "Sets the reveal state of every map region to the value you choose.\n255 is fully explored\n0 is entirely unexplored";
            dialog.ShowDialog();

            try
            {
                mapRevealThreshold = int.Parse(cvm.ValueChosen);
                if (mapRevealThreshold >= 0 && mapRevealThreshold <= 255)
                {
                    for (int i = 0; i < fogOfWarRawData.Elements.Count; i++)
                    {
                        ((BytePropertyViewModel)fogOfWarRawData.Elements[i]).Value = $"{mapRevealThreshold}";
                    }
                }
                else
                {
                    MessageBox.Show("You must enter a number between 0 and 255.");
                    return(false);
                }
            }
            catch (Exception)
            {
                if (!(cvm.ValueChosen == "cancel"))
                {
                    MessageBox.Show($"Could not parse: {cvm.ValueChosen}");
                }
                return(false);
            }

            MessageBox.Show("Map data uncovered. Remember to enable the map as well if desired.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            return(true);
        }