public bool Apply(SaveObjectModel rootItem) { 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; 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 SatisfactorySaveParser.Structures.Vector3() { X = 1, Y = 1, Z = 1 }, WasPlacedInLevel = false, ParentObjectName = "", ParentObjectRoot = "" }; newSaveObject.DataFields = new SerializedFields(); newSaveObject.DataFields.Add(new ObjectProperty("mInventory", 0) { LevelName = "Persistent_Level", PathName = $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}.inventory" }); 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); }
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); }
private int MassDismantle(List <SaveObjectModel> objects, ArrayProperty inventory, SaveObjectModel rootItem) { int count = 0; foreach (SaveObjectModel item in objects) { if (item is SaveEntityModel) { if (IsPointInPolygon(((SaveEntityModel)item).Position, polygon) && minZ <= ((SaveEntityModel)item).Position.Z && ((SaveEntityModel)item).Position.Z <= maxZ) { ArrayPropertyViewModel dismantleRefund = ((SaveEntityModel)item).FindField <ArrayPropertyViewModel>("mDismantleRefund"); if (dismantleRefund != null) { foreach (SerializedPropertyViewModel property in dismantleRefund.Elements) { DynamicStructData itemAmountStruct = (DynamicStructData)((StructProperty)property.Model).Data; string itemPath = ((ObjectProperty)itemAmountStruct.Fields[0]).PathName; int itemAmount = ((IntProperty)itemAmountStruct.Fields[1]).Value; byte[] bytes = PrepareForParse(itemPath, itemAmount); using (MemoryStream ms = new MemoryStream(bytes)) using (BinaryReader reader = new BinaryReader(ms)) { SerializedProperty prop = SerializedProperty.Parse(reader); inventory.Elements.Add(prop); } } } if (item.FindField <ObjectPropertyViewModel>("mInventory") != null) { inventory.Elements.AddRange(((ArrayProperty)rootItem.FindChild(item.FindField <ObjectPropertyViewModel>("mInventory").Str2, false).FindField <ArrayPropertyViewModel>("mInventoryStacks").Model).Elements); } if (item.FindField <ObjectPropertyViewModel>("mStorageInventory") != null) { inventory.Elements.AddRange(((ArrayProperty)rootItem.FindChild(item.FindField <ObjectPropertyViewModel>("mStorageInventory").Str2, false).FindField <ArrayPropertyViewModel>("mInventoryStacks").Model).Elements); } if (item.FindField <ObjectPropertyViewModel>("mInputInventory") != null) { inventory.Elements.AddRange(((ArrayProperty)rootItem.FindChild(item.FindField <ObjectPropertyViewModel>("mInputInventory").Str2, false).FindField <ArrayPropertyViewModel>("mInventoryStacks").Model).Elements); } if (item.FindField <ObjectPropertyViewModel>("mOutputInventory") != null) { inventory.Elements.AddRange(((ArrayProperty)rootItem.FindChild(item.FindField <ObjectPropertyViewModel>("mOutputInventory").Str2, false).FindField <ArrayPropertyViewModel>("mInventoryStacks").Model).Elements); } rootItem.Remove(item); count++; } } } return(count); }
public bool Apply(SaveObjectModel rootItem) { 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); } 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")) //{ animalSpawner.FindField("mSpawnData", (ArrayPropertyViewModel arrayProperty) => { foreach (StructPropertyViewModel elem in arrayProperty.Elements) { // 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 = 1000000000; } }); //} } // 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); } } return(true); }
private int MassDismantle(List <SaveObjectModel> objects, ArrayProperty inventory, SaveObjectModel rootItem) { int count = 0; foreach (SaveObjectModel item in objects) { if (item is SaveEntityModel) { if (IsPointInPolygon(((SaveEntityModel)item).Position, polygon) && minZ <= ((SaveEntityModel)item).Position.Z && ((SaveEntityModel)item).Position.Z <= maxZ) { ArrayPropertyViewModel dismantleRefund = ((SaveEntityModel)item).FindField <ArrayPropertyViewModel>("mDismantleRefund"); if (dismantleRefund != null) { foreach (SerializedPropertyViewModel property in dismantleRefund.Elements) { DynamicStructData itemAmountStruct = (DynamicStructData)((StructProperty)property.Model).Data; string itemPath = ((ObjectProperty)itemAmountStruct.Fields[0]).PathName; int itemAmount = ((IntProperty)itemAmountStruct.Fields[1]).Value; byte[] bytes = PrepareForParse(itemPath, itemAmount); using (MemoryStream ms = new MemoryStream(bytes)) using (BinaryReader reader = new BinaryReader(ms)) { SerializedProperty prop = SerializedProperty.Parse(reader); inventory.Elements.Add(prop); } } } if (item.FindField <ObjectPropertyViewModel>("mInventory") != null) { inventory.Elements.AddRange(((ArrayProperty)rootItem.FindChild(item.FindField <ObjectPropertyViewModel>("mInventory").Str2, false).FindField <ArrayPropertyViewModel>("mInventoryStacks").Model).Elements); } if (item.FindField <ObjectPropertyViewModel>("mStorageInventory") != null) { inventory.Elements.AddRange(((ArrayProperty)rootItem.FindChild(item.FindField <ObjectPropertyViewModel>("mStorageInventory").Str2, false).FindField <ArrayPropertyViewModel>("mInventoryStacks").Model).Elements); } if (item.FindField <ObjectPropertyViewModel>("mInputInventory") != null) { inventory.Elements.AddRange(((ArrayProperty)rootItem.FindChild(item.FindField <ObjectPropertyViewModel>("mInputInventory").Str2, false).FindField <ArrayPropertyViewModel>("mInventoryStacks").Model).Elements); } if (item.FindField <ObjectPropertyViewModel>("mOutputInventory") != null) { inventory.Elements.AddRange(((ArrayProperty)rootItem.FindChild(item.FindField <ObjectPropertyViewModel>("mOutputInventory").Str2, false).FindField <ArrayPropertyViewModel>("mInventoryStacks").Model).Elements); } // Unlink miners & geysers if (item.Model.TypePath.StartsWith("/Game/FactoryGame/Buildable/Factory/Miner") || item.Model.TypePath.StartsWith("/Game/FactoryGame/Buildable/Factory/GeneratorGeoThermal") || item.Model.TypePath.StartsWith("/Game/FactoryGame/Buildable/Factory/OilPump")) { string resourceNode = item.FindField <ObjectPropertyViewModel>("mExtractResourceNode").Str2; rootItem.FindChild(resourceNode, false).FindField <BoolPropertyViewModel>("mIsOccupied", property => property.Value = false); } var gameState = rootItem.FindChild("Persistent_Level:PersistentLevel.BP_GameState_C_0", false); if (item.Model.TypePath.StartsWith("/Game/FactoryGame/Buildable/Factory/TradingPost/Build_TradingPost.Build_TradingPost_C")) { gameState.FindField <BoolPropertyViewModel>("mIsTradingPostBuilt", property => property.Value = false); } if (item.Model.TypePath.StartsWith("/Game/FactoryGame/Buildable/Factory/SpaceElevator/Build_SpaceElevator.Build_SpaceElevator_C")) { gameState.FindField <BoolPropertyViewModel>("mIsSpaceElevatorBuilt", property => property.Value = false); } rootItem.Remove(item); count++; } } } return(count); }