Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions SatisfactorySaveEditor/Cheats/CouponChangerCheat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ public class CouponChangerCheat : ICheat

private long pointsRequiredFromTicketCount(int tickets)
{
//equation for ticket count from points is y={x>3:(ceil(x/3)^2)*1000, x<4:1000} where x is ticket count and y is points required. from here: https://satisfactory.gamepedia.com/AWESOME_Sink
//OLD ticket cost function for pre-0.3.3 AWESOME sink --TODO update to new ticket cost function once that is determined
// see ticket equations https://satisfactory.gamepedia.com/AWESOME_Sink
// ticket cost pre-0.3.3 was Pow(Ceiling(tickets / 3.0), 2) * 1000
// ticket cost U7 is (Pow(Ceiling(tickets / 3.0)-1, 2) * 500) + 1000
// TODO: keep the cost function up to date.
if (tickets < 4)
return 1000;
else
return (long) (Pow(Ceiling(tickets / 3.0), 2) * 1000);
return (long) (Pow(Ceiling(tickets / 3.0)-1, 2) * 500) + 1000;
}

public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
Expand All @@ -35,7 +37,17 @@ public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
}

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

// how many tickets are currently printable from sink.
var numResourceSinkCoupons = sinkSubsystem.FindOrCreateField<IntPropertyViewModel>("mNumResourceSinkCoupons");

// which ticket point level (modulo 3) the sink currently is (points, alien DNA).
var pointLevels = sinkSubsystem.FindOrCreateField<ArrayPropertyViewModel>("mCurrentPointLevels");

// the accumulated points the sink currently has (points, alien DNA).
var accumulatedPoints = sinkSubsystem.FindOrCreateField<ArrayPropertyViewModel>("mTotalPoints");


var dialog = new StringPromptWindow
{
Expand All @@ -45,7 +57,8 @@ public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
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";
//mCurrentPointLevel.Value
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: {((IntPropertyViewModel)pointLevels.Elements[0]).Value}\nMore info on AWESOME Sink wiki page";
dialog.ShowDialog();

int requestedTicketCount = 0;
Expand All @@ -65,14 +78,15 @@ public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
return false;
}

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

((IntPropertyViewModel)pointLevels.Elements[0]).Value = requestedTicketCount;

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

long calculatedPointsCount = pointsRequiredFromTicketCount(requestedTicketCount);
long calculatedPointsCountNextTicket = pointsRequiredFromTicketCount(requestedTicketCount+1);

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);
MessageBox.Show($"Earned ticket count set to {requestedTicketCount}. The next ticket will take {calculatedPointsCountNextTicket} points to earn.", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
return true;
}
catch (Exception)
Expand Down
39 changes: 20 additions & 19 deletions SatisfactorySaveEditor/Cheats/DeleteEnemiesCheat.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
using SatisfactorySaveEditor.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using SatisfactorySaveEditor.Model;
using SatisfactorySaveEditor.ViewModel.Property;
using SatisfactorySaveEditor.ViewModel.Struct;
using SatisfactorySaveParser;
using SatisfactorySaveParser.PropertyTypes;
using SatisfactorySaveParser.PropertyTypes.Structs;
using SatisfactorySaveParser.Structures;
using System;
using System.Diagnostics;
using System.IO;
using System.Windows;
using Vector = SatisfactorySaveParser.PropertyTypes.Structs.Vector;
using Vector3 = SatisfactorySaveParser.Structures.Vector3;

namespace SatisfactorySaveEditor.Cheats
{
Expand Down Expand Up @@ -91,7 +89,7 @@ public bool AddDoggo(SaveObjectModel rootItem, SatisfactorySave saveGame)
}
var player = (SaveEntityModel)hostPlayerModel.Items[0];

SaveComponent healthComponent = new SaveComponent("/Script/FactoryGame.FGHealthComponent", "Persistent_Level", $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}.HealthComponent")
SaveComponent healthComponent = new SaveComponent(saveGame.Header.MapName, "/Script/FactoryGame.FGHealthComponent", "Persistent_Level", $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}.HealthComponent")
{
DataFields = new SerializedFields(),
ParentEntityName = $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}"
Expand All @@ -100,30 +98,30 @@ public bool AddDoggo(SaveObjectModel rootItem, SatisfactorySave saveGame)
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")
inventoryComponent = new SaveComponent(saveGame.Header.MapName, "/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>()
Elements = new List<SerializedProperty>()
{
SerializedProperty.Parse(reader, saveGame.Header.BuildVersion)
}
},
new ArrayProperty("mArbitrarySlotSizes")
{
Type = IntProperty.TypeName,
Elements = new System.Collections.Generic.List<SerializedProperty>()
Elements = new List<SerializedProperty>()
{
new IntProperty("Element") { Value = 0 }
}
},
new ArrayProperty("mAllowedItemDescriptors")
{
Type = ObjectProperty.TypeName,
Elements = new System.Collections.Generic.List<SerializedProperty>()
Elements = new List<SerializedProperty>()
{
new ObjectProperty("Element") { LevelName = "", PathName = "" }
}
Expand All @@ -132,7 +130,7 @@ public bool AddDoggo(SaveObjectModel rootItem, SatisfactorySave saveGame)
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}")
SaveEntity doggo = new SaveEntity(saveGame.Header.MapName, "/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,
Expand All @@ -147,10 +145,10 @@ public bool AddDoggo(SaveObjectModel rootItem, SatisfactorySave saveGame)
ParentObjectName = "",
ParentObjectRoot = ""
};
doggo.Components = new System.Collections.Generic.List<SatisfactorySaveParser.Structures.ObjectReference>()
doggo.Components = new List<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"}
new ObjectReference() {LevelName = "Persistent_Level", PathName = $"Persistent_Level:PersistentLevel.Char_SpaceRabbit_C_{currentDoggoID}.mInventory"},
new 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)))
Expand Down Expand Up @@ -192,6 +190,7 @@ public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
return false;
}


float offset = -50000;
var hostPlayerModel = rootItem.FindChild("Char_Player.Char_Player_C", false);
if (hostPlayerModel == null || hostPlayerModel.Items.Count < 1)
Expand All @@ -211,11 +210,13 @@ public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
{
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;
((BoolPropertyViewModel)((DynamicStructDataViewModel)elem.StructData).Fields[1]).Value = true;
// Set NumTimesKilled to at least 1 i guess. Better to increment.
((IntPropertyViewModel)((DynamicStructDataViewModel)elem.StructData).Fields[2]).Value += 1;
// 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);
((IntPropertyViewModel)((DynamicStructDataViewModel)elem.StructData).Fields[3]).Value = (int)(Distance(playerPosition, ((SaveEntityModel)animalSpawner).Position) /10000);
}
});
}
Expand Down
15 changes: 6 additions & 9 deletions SatisfactorySaveEditor/Cheats/EverythingBoxCheat.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
using SatisfactorySaveEditor.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using SatisfactorySaveEditor.Model;
using SatisfactorySaveEditor.View;
using SatisfactorySaveEditor.ViewModel;
using SatisfactorySaveEditor.ViewModel.Property;
using SatisfactorySaveParser;
using SatisfactorySaveParser.Data;
using SatisfactorySaveParser.PropertyTypes;
using SatisfactorySaveParser.PropertyTypes.Structs;
using SatisfactorySaveParser.Structures;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;

namespace SatisfactorySaveEditor.Cheats
{
Expand Down Expand Up @@ -101,7 +98,7 @@ public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
}

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

//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");
Expand Down
4 changes: 2 additions & 2 deletions SatisfactorySaveEditor/Cheats/KillPlayersCheat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
if (!InventoryEmpty(inventoryComponent))
{
currentStorageID = GetNextStorageID(currentStorageID, rootItem);
SaveComponent newInventory = new SaveComponent(inventoryComponent.TypePath, inventoryComponent.RootObject, $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}.inventory")
SaveComponent newInventory = new SaveComponent(saveGame.Header.MapName, 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}")
SaveEntity newSaveObject = new SaveEntity(saveGame.Header.MapName, "/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,
Expand Down
8 changes: 4 additions & 4 deletions SatisfactorySaveEditor/Cheats/MassDismantleCheat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,16 +217,16 @@ public bool Apply(SaveObjectModel rootItem, SatisfactorySave saveGame)
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, saveGame.Header.BuildVersion);
CreateCrateEntityFromInventory(saveGame.Header.MapName, rootItem, inventory, saveGame.Header.BuildVersion);
}
return true;
}

public static SaveEntityModel CreateCrateEntityFromInventory(SaveObjectModel rootItem, ArrayProperty inventory, int buildVersion)
public static SaveEntityModel CreateCrateEntityFromInventory(string levelname, SaveObjectModel rootItem, ArrayProperty inventory, int buildVersion)
{
inventory = ArrangeInventory(inventory, buildVersion);
int currentStorageID = GetNextStorageID(0, rootItem);
SaveComponent newInventory = new SaveComponent("/Script/FactoryGame.FGInventoryComponent", "Persistent_Level", $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}.inventory")
SaveComponent newInventory = new SaveComponent(levelname, "/Script/FactoryGame.FGInventoryComponent", "Persistent_Level", $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}.inventory")
{
ParentEntityName = $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}",
DataFields = new SerializedFields()
Expand All @@ -250,7 +250,7 @@ public static SaveEntityModel CreateCrateEntityFromInventory(SaveObjectModel roo
};
rootItem.FindChild("FactoryGame.FGInventoryComponent", false).Items.Add(new SaveComponentModel(newInventory));
SaveEntity player = (SaveEntity)rootItem.FindChild("Char_Player.Char_Player_C", false).DescendantSelf[0];
SaveEntity newSaveObject = new SaveEntity("/Game/FactoryGame/-Shared/Crate/BP_Crate.BP_Crate_C", "Persistent_Level", $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}")
SaveEntity newSaveObject = new SaveEntity(levelname, "/Game/FactoryGame/-Shared/Crate/BP_Crate.BP_Crate_C", "Persistent_Level", $"Persistent_Level:PersistentLevel.BP_Crate_C_{currentStorageID}")
{
NeedTransform = true,
Rotation = player.Rotation,
Expand Down
Loading