1.3.0 (Generator Energy/Biiofuel Modding)

This commit is contained in:
mikx 2025-10-22 19:42:04 -04:00
parent 5fefe8eba9
commit 54ec385800
2 changed files with 221 additions and 142 deletions

View File

@ -6,55 +6,95 @@ using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using System.Runtime; using System.Runtime;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jsarus namespace Jsarus
{ {
internal class Program internal class Program
{ {
public static string version = "1.2.0"; public static string version = "1.3.0";
public static string cd = Directory.GetCurrentDirectory(); public static string cd = Directory.GetCurrentDirectory();
public static Process p = new Process(); public static Process p = new Process();
private static ConsoleKeyInfo keyInfo;
static void Main(string[] args) static void Main(string[] args)
{ {
WebClient wc = new WebClient();
Message.Splash("Jsarus", "mikx"); Message.Splash("Jsarus", "mikx");
Message.CMW("Creating directories...", true, 1); Message.CMW("Creating directories...", true, 1);
if (!Directory.Exists($@"Data\Modded")) { Directory.CreateDirectory($@"Data\Modded"); } if (!Directory.Exists($@"Data\Modded")) { Directory.CreateDirectory($@"Data\Modded"); }
if (!Directory.Exists($@"Data\Modded\data")) { Directory.CreateDirectory($@"Data\Modded\data"); } if (!Directory.Exists($@"Data\Modded\data")) { Directory.CreateDirectory($@"Data\Modded\data"); }
Message.CMW("Preparing variables...",true,1); Message.CMW("Preparing variables...", true, 1);
JObject settings = JObject.Parse(File.ReadAllText("settings.json")); JObject settings = JObject.Parse(File.ReadAllText("settings.json"));
string ModName = settings["ModName"].ToObject<string>(); string ModName = settings["ModName"].ToObject<string>();
string GameContentPath = settings["GameContentPath"].ToObject<string>(); string GameContentPath = settings["GameContentPath"].ToObject<string>();
bool KeepData = settings["KeepData"].ToObject<bool>();
string[] CopyList = settings["CopyList"].ToObject<string[]>(); string[] CopyList = settings["CopyList"].ToObject<string[]>();
int ItemWeight = settings["D_Itemable"]["ItemWeight"].ToObject<int>(); if (!File.Exists("data.json")) { wc.DownloadFile("https://mxio.ovh/icarus/jsarus/data.json", "data.json"); }
int ItemStack = settings["D_Itemable"]["ItemStack"].ToObject<int>();
int ExperienceMultiplier = settings["D_ExperienceEvents"]["ExperienceMultiplier"].ToObject<int>(); JObject data = JObject.Parse(File.ReadAllText("data.json"));
int DataVersion = data["version"].ToObject<int>();
JObject dataRemote = JObject.Parse(wc.DownloadString("https://mxio.ovh/icarus/jsarus/data.json"));
int DataVersionRemote = dataRemote["version"].ToObject<int>();
string[] ActionList = settings["D_StaminaActionCosts"]["ActionList"].ToObject<string>().Split('|'); if (KeepData)
int DivideCostPer = settings["D_StaminaActionCosts"]["DivideCostPer"].ToObject<int>(); {
Message.CMW("Keeping your custom data.", true, 1);
if (DataVersion < DataVersionRemote)
{
Message.CMW("Consider setting \"KeepData\" to \"true\" in your \"settings.json\"!", true, 1);
Message.CMW("Your data is outdated. Should we update it? (y/n)", true, 3);
Message.CMW("If you are not sure, answer \"y\".", true, 1);
keyInfo = Console.ReadKey(true);
if (keyInfo.Key == ConsoleKey.Y)
{
Message.CMW("Getting the latest data...", true, 1);
if (File.Exists("data.json")) { File.Copy("data.json", "data.backup.json", true); }
Message.CMW("A backup has been made to \"data.backup.json\".", true, 1);
wc.DownloadFile("https://mxio.ovh/icarus/jsarus/data.json", "data.json");
}
}
}
else
{
Message.CMW("Getting the latest data...", true, 1);
wc.DownloadFile("https://mxio.ovh/icarus/jsarus/data.json", "data.json");
}
string[] PickList = settings["D_ToolDamage"]["PickList"].ToObject<string>().Split('|'); int ItemWeight = data["D_Itemable"]["ItemWeight"].ToObject<int>();
string[] PickEfficiencyList = settings["D_ToolDamage"]["PickEfficiencyList"].ToObject<string>().Split('|'); int ItemStack = data["D_Itemable"]["ItemStack"].ToObject<int>();
string[] AxeList = settings["D_ToolDamage"]["AxeList"].ToObject<string>().Split('|'); int ExperienceMultiplier = data["D_ExperienceEvents"]["ExperienceMultiplier"].ToObject<int>();
string[] AxeEfficiencyList = settings["D_ToolDamage"]["AxeEfficiencyList"].ToObject<string>().Split('|');
string[] RecipeListOre = settings["D_ProcessorRecipes"]["RecipeListOre"].ToObject<string>().Split('|'); string[] ActionList = data["D_StaminaActionCosts"]["ActionList"].ToObject<string>().Split('|');
string[] RecipeList = settings["D_ProcessorRecipes"]["RecipeList"].ToObject<string>().Split('|'); int DivideCostPer = data["D_StaminaActionCosts"]["DivideCostPer"].ToObject<int>();
string[] RecipeListStack = settings["D_ProcessorRecipes"]["RecipeListStack"].ToObject<string>().Split('|');
int RequiredMillijoules = settings["D_ProcessorRecipes"]["RequiredMillijoules"].ToObject<int>();
int RequiredAmount = settings["D_ProcessorRecipes"]["RequiredAmount"].ToObject<int>();
int CraftedAmount = settings["D_ProcessorRecipes"]["CraftedAmount"].ToObject<int>();
string[] InventoryList = settings["D_InventoryInfo"]["InventoryList"].ToObject<string>().Split('|'); string[] PickList = data["D_ToolDamage"]["PickList"].ToObject<string>().Split('|');
int InventorySize = settings["D_InventoryInfo"]["InventorySize"].ToObject<int>(); string[] PickEfficiencyList = data["D_ToolDamage"]["PickEfficiencyList"].ToObject<string>().Split('|');
string[] supportedJson = { @"Traits\D_Itemable.json", @"Experience\D_ExperienceEvents.json", @"Tools\D_StaminaActionCosts.json", @"Tools\D_ToolDamage.json", @"Crafting\D_ProcessorRecipes.json", @"Inventory\D_InventoryInfo.json" }; string[] AxeList = data["D_ToolDamage"]["AxeList"].ToObject<string>().Split('|');
string[] AxeEfficiencyList = data["D_ToolDamage"]["AxeEfficiencyList"].ToObject<string>().Split('|');
string[] RecipeListOre = data["D_ProcessorRecipes"]["RecipeListOre"].ToObject<string>().Split('|');
string[] RecipeList = data["D_ProcessorRecipes"]["RecipeList"].ToObject<string>().Split('|');
string[] RecipeListStack = data["D_ProcessorRecipes"]["RecipeListStack"].ToObject<string>().Split('|');
int RequiredMillijoules = data["D_ProcessorRecipes"]["RequiredMillijoules"].ToObject<int>();
int RequiredAmount = data["D_ProcessorRecipes"]["RequiredAmount"].ToObject<int>();
int CraftedAmount = data["D_ProcessorRecipes"]["CraftedAmount"].ToObject<int>();
string[] InventoryList = data["D_InventoryInfo"]["InventoryList"].ToObject<string>().Split('|');
int InventorySize = data["D_InventoryInfo"]["InventorySize"].ToObject<int>();
string[] GeneratorList = data["D_Generator"]["GeneratorList"].ToObject<string>().Split('|');
int GenerationRate = data["D_Generator"]["GenerationRate"].ToObject<int>();
int GenerationRatio = data["D_Generator"]["GenerationRatio"].ToObject<int>();
string[] supportedJson = { @"Traits\D_Itemable.json", @"Experience\D_ExperienceEvents.json", @"Tools\D_StaminaActionCosts.json", @"Tools\D_ToolDamage.json", @"Crafting\D_ProcessorRecipes.json", @"Inventory\D_InventoryInfo.json", @"Traits\D_Generator.json" };
var dir = Directory.GetDirectories(@"Data\Vanilla"); var dir = Directory.GetDirectories(@"Data\Vanilla");
@ -75,153 +115,191 @@ namespace Jsarus
Message.CMW($"Copied {sj.Split('\\')[1]}.", true, 2); Message.CMW($"Copied {sj.Split('\\')[1]}.", true, 2);
} }
Message.CMW($"We extracted the data, should we continue and mod it? (y/n)", true, 1); Message.CMW("Generating the Item Database for dynamic modding...", true, 1);
ConsoleKeyInfo keyInfo = Console.ReadKey(true); JArray itemsDB = new JArray();
if (keyInfo.Key == ConsoleKey.N) { return; } else JObject items = new JObject();
JObject item = JObject.Parse(File.ReadAllText(@"Data\Vanilla\Traits\D_Itemable.json"));
foreach (var d in dir) foreach (var i in item["Rows"])
{ {
var json = Directory.GetFiles(d); string iname = i["Name"].ToObject<string>().Substring(5);
foreach (var file in json) int iweight = 0;
if (i["Weight"] != null) { iweight = i["Weight"].ToObject<int>(); } else { iweight = 0; }
bool istack = false;
int istacksize = 1;
if (i["MaxStack"] != null) { istack = true; istacksize = i["MaxStack"].ToObject<int>(); }
items = new JObject()
{ {
string f = Path.GetFileName(file); { "name", iname },
Message.CMW($"Processing {f}...", true, 1); { "weight", iweight },
JObject job = JObject.Parse(File.ReadAllText(file)); { "dostack", istack },
switch (f) { "stack", istacksize }
{ };
case "D_Itemable.json": itemsDB.Add(items);
foreach (var r in job["Rows"]) }
var rawDB = JsonConvert.SerializeObject(itemsDB, Formatting.Indented);
File.WriteAllText($@"Data/itemDB.json", rawDB);
foreach (var d in dir)
{
var json = Directory.GetFiles(d);
foreach (var file in json)
{
string f = Path.GetFileName(file);
Message.CMW($"Processing {f}...", true, 1);
JObject job = JObject.Parse(File.ReadAllText(file));
switch (f)
{
case "D_Itemable.json":
foreach (var r in job["Rows"])
{
r["Name"] = r["Name"].ToObject<string>();
r["DisplayName"] = r["DisplayName"].ToObject<string>();
if (r["Icon"] != null)
{ {
r["Name"] = r["Name"].ToObject<string>(); r["Icon"] = r["Icon"].ToObject<string>();
r["DisplayName"] = r["DisplayName"].ToObject<string>(); }
if (r["Icon"] != null) if (r["Description"] != null)
{
r["Description"] = r["Description"].ToObject<string>();
}
if (r["FlavorText"] != null)
{
r["FlavorText"] = r["FlavorText"].ToObject<string>();
}
r["Weight"] = ItemWeight;
if (r["MaxStack"] != null)
{
r["MaxStack"] = ItemStack;
}
}
break;
case "D_ExperienceEvents.json":
foreach (var r in job["Rows"])
{
r["Name"] = r["Name"].ToObject<string>();
if (r["EventDescription"] != null)
{
r["EventDescription"] = r["EventDescription"].ToObject<string>();
}
if (r["SharedExperience"] != null)
{
r["SharedExperience"] = r["SharedExperience"].ToObject<bool>();
}
if (r["ExperienceGranted"] != null)
{
r["ExperienceGranted"] = r["ExperienceGranted"].ToObject<int>() * ExperienceMultiplier;
}
}
break;
case "D_StaminaActionCosts.json":
foreach (var r in job["Rows"])
{
if (ActionList.Contains(r["Name"].ToString()))
{
if (r["PerSecondCost"] != null)
{ {
r["Icon"] = r["Icon"].ToObject<string>(); r["PerSecondCost"] = r["PerSecondCost"].ToObject<int>() / DivideCostPer;
} }
if (r["Description"] != null) if (r["BeginActionCost"] != null)
{ {
r["Description"] = r["Description"].ToObject<string>(); r["BeginActionCost"] = r["BeginActionCost"].ToObject<int>() / DivideCostPer;
}
if (r["FlavorText"] != null)
{
r["FlavorText"] = r["FlavorText"].ToObject<string>();
}
r["Weight"] = ItemWeight;
if (r["MaxStack"] != null)
{
r["MaxStack"] = ItemStack;
} }
} }
break; }
break;
case "D_ExperienceEvents.json": case "D_ToolDamage.json":
foreach (var r in job["Rows"]) foreach (var r in job["Rows"])
{
if (PickList.Contains(r["Name"].ToString()))
{ {
r["Name"] = r["Name"].ToObject<string>(); int index = Array.IndexOf(PickList, r["Name"].ToString());
if (r["EventDescription"] != null) r["Mining_Efficiency"] = PickEfficiencyList[index];
{
r["EventDescription"] = r["EventDescription"].ToObject<string>();
}
if (r["SharedExperience"] != null)
{
r["SharedExperience"] = r["SharedExperience"].ToObject<bool>();
}
if (r["ExperienceGranted"] != null)
{
r["ExperienceGranted"] = r["ExperienceGranted"].ToObject<int>() * ExperienceMultiplier;
}
} }
break;
case "D_StaminaActionCosts.json": if (AxeList.Contains(r["Name"].ToString()))
foreach (var r in job["Rows"])
{ {
if(ActionList.Contains(r["Name"].ToString())) int index = Array.IndexOf(AxeList, r["Name"].ToString());
r["Felling_Efficiency"] = AxeEfficiencyList[index];
}
}
break;
case "D_ProcessorRecipes.json":
JArray itemDB = JArray.Parse(File.ReadAllText(@"Data\itemDB.json"));
foreach (var r in job["Rows"])
{
//JToken entry = itemDB.FirstOrDefault(t => (bool)(t["name"]?.ToString().Contains(r["Name"]?.ToString())));
if (r["Inputs"].Count() > 0)
{
if (RecipeListOre.Contains(r["Name"].ToString()))
{ {
if (r["PerSecondCost"] != null) if (r["RequiredMillijoules"] != null)
{ {
r["PerSecondCost"] = r["PerSecondCost"].ToObject<int>() / DivideCostPer; r["RequiredMillijoules"] = RequiredMillijoules;
} }
if (r["BeginActionCost"] != null) foreach (var i in r["Inputs"])
{ {
r["BeginActionCost"] = r["BeginActionCost"].ToObject<int>() / DivideCostPer; i["Count"] = RequiredAmount;
} }
r["Outputs"][0]["Count"] = CraftedAmount;
}
if (RecipeList.Contains(r["Name"].ToString()))
{
foreach (var i in r["Inputs"])
{
i["Count"] = RequiredAmount;
}
r["Outputs"][0]["Count"] = 1;
}
if (RecipeListStack.Contains(r["Name"].ToString()))
{
foreach (var i in r["Inputs"])
{
i["Count"] = RequiredAmount;
}
r["Outputs"][0]["Count"] = CraftedAmount;
} }
} }
break;
case "D_ToolDamage.json": }
foreach (var r in job["Rows"]) break;
case "D_InventoryInfo.json":
foreach (var r in job["Rows"])
{
if (InventoryList.Contains(r["Name"].ToString()))
{ {
if (PickList.Contains(r["Name"].ToString())) r["StartingSlots"] = InventorySize;
{
int index = Array.IndexOf(PickList, r["Name"].ToString());
r["Mining_Efficiency"] = PickEfficiencyList[index];
}
if (AxeList.Contains(r["Name"].ToString()))
{
int index = Array.IndexOf(AxeList, r["Name"].ToString());
r["Felling_Efficiency"] = AxeEfficiencyList[index];
}
} }
break; }
break;
case "D_ProcessorRecipes.json": case "D_Generator.json":
foreach (var r in job["Rows"]) foreach (var r in job["Rows"])
{
if (GeneratorList.Contains(r["Name"].ToString()))
{ {
if (r["Inputs"].Count() > 0) r["GenerationRate"] = GenerationRate;
if (r["GenerationRatio"] != null)
{ {
if (RecipeListOre.Contains(r["Name"].ToString())) r["GenerationRatio"] = GenerationRatio;
{ }
if (r["RequiredMillijoules"] != null)
{
r["RequiredMillijoules"] = RequiredMillijoules;
}
foreach (var i in r["Inputs"])
{
i["Count"] = RequiredAmount;
}
r["Outputs"][0]["Count"] = CraftedAmount;
}
if (RecipeList.Contains(r["Name"].ToString()))
{
foreach (var i in r["Inputs"])
{
i["Count"] = RequiredAmount;
}
r["Outputs"][0]["Count"] = 1;
}
if (RecipeListStack.Contains(r["Name"].ToString()))
{
foreach (var i in r["Inputs"])
{
i["Count"] = RequiredAmount;
}
r["Outputs"][0]["Count"] = CraftedAmount;
}
}
} }
break; }
break;
case "D_InventoryInfo.json":
foreach (var r in job["Rows"])
{
if (InventoryList.Contains(r["Name"].ToString()))
{
r["StartingSlots"] = InventorySize;
}
}
break;
}
Message.CMW($"Saving {f}...", true, 1);
var raw = JsonConvert.SerializeObject(job, Formatting.Indented);
if (!Directory.Exists($@"{cd}\Data\Modded\data\{Path.GetFileName(d)}")) { Directory.CreateDirectory($@"{cd}\Data\Modded\data\{Path.GetFileName(d)}"); }
File.WriteAllText($@"Data/Modded/data/{Path.GetFileName(d)}/{f}", raw);
} }
Message.CMW($"Saving {f}...", true, 1);
var raw = JsonConvert.SerializeObject(job, Formatting.Indented);
if (!Directory.Exists($@"{cd}\Data\Modded\data\{Path.GetFileName(d)}")) { Directory.CreateDirectory($@"{cd}\Data\Modded\data\{Path.GetFileName(d)}"); }
File.WriteAllText($@"Data/Modded/data/{Path.GetFileName(d)}/{f}", raw);
} }
}
if (File.Exists($@"{cd}\Paks\{ModName}.txt")) { File.Delete($@"{cd}\Paks\{ModName}.txt"); } if (File.Exists($@"{cd}\Paks\{ModName}.txt")) { File.Delete($@"{cd}\Paks\{ModName}.txt"); }
File.WriteAllText($@"{cd}\Paks\{ModName}.txt", $@"""{cd}\Data\Modded\*.*"" ""..\..\..\Icarus\Content\*.*"""); File.WriteAllText($@"{cd}\Paks\{ModName}.txt", $@"""{cd}\Data\Modded\*.*"" ""..\..\..\Icarus\Content\*.*""");
@ -238,7 +316,7 @@ namespace Jsarus
{ {
File.Copy($@"{cd}\Paks\{ModName}_P.pak", $@"{p}\{ModName}_P.pak", true); File.Copy($@"{cd}\Paks\{ModName}_P.pak", $@"{p}\{ModName}_P.pak", true);
} }
} }
} }
} }
} }

View File

@ -17,12 +17,13 @@ Official MxIcarus Modding Tool for Icarus.
- Reduce all required mats of a recipe to 1, using a list. (Edited in settings.json) - Reduce all required mats of a recipe to 1, using a list. (Edited in settings.json)
- Set output of all stacking recipes to a specified value. (Edited in settings.json) - Set output of all stacking recipes to a specified value. (Edited in settings.json)
- Adjust the size of all inventory specified in a list. (Edited in settings.json) - Adjust the size of all inventory specified in a list. (Edited in settings.json)
- Adjust the energy produced and the biofuel consumed by all specified generator in a list. (Edited in settings.json)
## How-To ## How-To
1. Download the latest [release](https://mxgit.ovh/Icarus/Jsarus/releases). 1. Download the latest [release](https://mxgit.ovh/Icarus/Jsarus/releases).
2. Copy the archive content in an empty folder on your disk. 2. Copy the archive content in an empty folder on your disk.
3. Open "settings.json" and edit the "ModName" and "GameContentPath". 3. Open "settings.json" and edit the "ModName" and "GameContentPath".
4. IMPORTANT: Escape "\" in your path with "/". Ex.: "C:\/SteamLibrary\/steamapps\/common\/Icarus\/Icarus\/Content" 4. IMPORTANT: Escape "\\" in your path with "\\\\". Ex.: "C:\\\\SteamLibrary\\\\steamapps\\\\common\\\\Icarus\\\\Icarus\\\\Content"
5. Save the "settings.json" file and run "Jsarus.exe". 5. Save the "settings.json" file and run "Jsarus.exe".
6. Jsarus will extract your game data, press "y" when asked to mod it and generate a mod pak. 6. Jsarus will extract your game data, press "y" when asked to mod it and generate a mod pak.
7. Copy the created pak file from the "Paks" folder to your game "mods" folder. 7. Copy the created pak file from the "Paks" folder to your game "mods" folder.