Skip to content

Commit

Permalink
Remove Possible Softlocks with Noise Drops Randomizing (#8)
Browse files Browse the repository at this point in the history
* Support other bundles and scenario edits

* Moved parsed JSON data to bundle class

* Clean up Bundle Constants

* Set proper types for serialized data

* Select folder instead of each bundle

* Update README and bump version to 0.4
  • Loading branch information
SaltContainer authored Oct 27, 2024
1 parent a8fe629 commit 65a8f61
Show file tree
Hide file tree
Showing 95 changed files with 35,792 additions and 2,070 deletions.
Binary file modified Images/Randomizer_Img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 2 additions & 3 deletions NEO-TWEWY-Randomizer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Icons\ID001_NoBrand.ico</ApplicationIcon>
<AssemblyVersion>0.3.2</AssemblyVersion>
<FileVersion>0.3.2</FileVersion>
<AssemblyVersion>0.4.0</AssemblyVersion>
<FileVersion>0.4.0</FileVersion>
<Authors>SaltContainer</Authors>
</PropertyGroup>
<ItemGroup>
<Content Include="Icons\ID001_NoBrand.ico" />
<None Include="Resources\settings_string_versions.txt" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
Expand Down
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,27 @@ The Randomizer now supports the PC version of the game! That version specificall
With the PC version now being supported, all versions of the game _should_ be supported. I was not able to test the PS4 version myself but if it uses either un-encrypted bundles (like the Switch version) or bundles encrypted in the same way as the PC version, then it should work without any issues.

## Requirements
As of the latest version, there is only one file needed for the randomization to work properly (`4017d8fc.unity3d`).
To obtain this file, the process is a bit different for each version.
As of the latest version, there are 3 files needed for the randomization to work properly (`4017d8fc.unity3d`, `8b022f77.unity3d`, `a90d3deb.unity3d`). You will need to have all of them in the same folder. When loading the files in the randomizer, you'll just need to select that folder.

To obtain these files, the process is a bit different for each version.

### PC
You can find the file directly at `<directory>/NEO The World Ends with You_Data/StreamingAssets/Assets/4017d8fc.unity3d`.
You can find the files directly in this folder: `<directory>/NEO The World Ends with You_Data/StreamingAssets/Assets`.

### Switch
There are many tutorials online on how to extract the game files. You'll specifically want to find how to dump/extract the RomFS. Once you've done that, the file will be found at `<directory>/Data/StreamingAssets/Assets/4017d8fc.unity3d`.
There are many tutorials online on how to extract the game files. You'll specifically want to find how to dump/extract the RomFS. Once you've done that, the files will be found in thid folder: `<directory>/Data/StreamingAssets/Assets`.

### PS4
I am not aware on how to obtain the game files from the PS4 version of the game. There are likely tutorials online on how to do this. The path for the file will look similar to the ones for the other versions.
I am not aware on how to obtain the game files from the PS4 version of the game. There are likely tutorials online on how to do this. The path for the files will look similar to the ones for the other versions.

## Using the Randomized Data
Once you've obtained the file and ran it through the randomizer, you can then simply "replace" it in your game's installation.
Once you've obtained the files and ran them through the randomizer, you can then simply "replace" them in your game's installation.

### PC
Replace the `4017d8fc.unity3d` file in the game files with the one the randomizer generated. Make sure to keep a backup of the vanilla file!
Directly replace the files in your game with the ones the randomizer generated. Make sure to keep a backup of the vanilla files!

### Switch
Please follow tutorials online on how to use either an emulator's or Atmosphere's LayeredFS implementation to mod your game. Make sure you recreate the proper folder structure when creating your mod (`<directory>/Data/StreamingAssets/Assets/4017d8fc.unity3d`).
Please follow tutorials online on how to use either an emulator's or Atmosphere's LayeredFS implementation to mod your game. Make sure you recreate the proper folder structure when creating your mod (`<directory>/Data/StreamingAssets/Assets/xxxxx.unity3d`).

### PS4
I am not aware on how to mod games on the PS4. There are likely tutorials online on how to do this.
Expand All @@ -42,7 +43,8 @@ I am not aware on how to mod games on the PS4. There are likely tutorials online
- Pins dropped by Noise can be either shuffled or randomized.
- "Limited" Pins (Axion, Dilaton, Dibaryon, and Sfermion) can also be included.
- It is possible to only change drops for specific difficulties.
- Turning this option on may result in softlocks since some of the barrier requirements could be impossible to fulfill.
- Turning this option on will make the two missions that require specific pins automatically fulfilled after talking to the reaper again.
- The two missions are during W1D2 to go between 104 and Dogenzaka, and during W2D5 to go between 104 and TSUTAYA O-EAST.
- Drop Rates for these Pins can be randomized.
- It is possible to only change rates for specific difficulties.
- There is an option to "weigh" each difficulty so that pins are rarer or more common at different difficulties.
Expand Down
50 changes: 8 additions & 42 deletions Randomizer/Data/Bundle.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
using AssetsTools.NET;
using AssetsTools.NET.Extra;
using System.Collections.Generic;
using System.Linq;
using AssetsTools.NET.Extra;

namespace NEO_TWEWY_Randomizer
{
public class Bundle
public abstract class Bundle
{
private AssetsManager manager;
private string bundleKey;
private BundleFileInstance bundle;
private AssetsFileInstance assetsFile;
private bool encrypted;
protected AssetsManager manager;
protected string bundleKey;
protected BundleFileInstance bundle;
protected AssetsFileInstance assetsFile;
protected bool encrypted;

public AssetsManager Manager { get => manager; }
public string BundleKey { get => bundleKey; }
Expand All @@ -30,38 +27,7 @@ public Bundle(AssetsManager manager, BundleFileInstance bundle, string bundleKey
this.encrypted = encrypted;
}

public string GetScriptFile(string scriptName)
{
return GetBaseFieldOfScript(scriptName)?[FileConstants.Bundles[bundleKey].Classes[scriptName].Attribute].AsString;
}

public void SetScriptFiles(Dictionary<string, string> scripts)
{
foreach(var script in scripts)
{
var assetInfo = GetAssetInfoOfScript(script.Key);
var baseField = GetBaseFieldOfScript(script.Key);

baseField[FileConstants.Bundles[bundleKey].Classes[script.Key].Attribute].AsString = script.Value;
assetInfo.SetNewData(baseField);
}

SetAssetsFileInBundle();
}

private AssetFileInfo GetAssetInfoOfScript(string scriptName)
{
var assetInfos = assetsFile.file.GetAssetsOfType(AssetClassID.TextAsset);
return assetInfos.Where(f => manager.GetBaseField(assetsFile, f)["m_Name"].AsString == scriptName).FirstOrDefault();
}

private AssetTypeValueField GetBaseFieldOfScript(string scriptName)
{
var baseFields = assetsFile.file.GetAssetsOfType(AssetClassID.TextAsset).Select(f => manager.GetBaseField(assetsFile, f));
return baseFields.Where(f => f["m_Name"].AsString == scriptName).FirstOrDefault();
}

private void SetAssetsFileInBundle()
protected void SetAssetsFileInBundle()
{
bundle.file.BlockAndDirInfo.DirectoryInfos[0].SetNewData(assetsFile.file);
}
Expand Down
29 changes: 6 additions & 23 deletions Randomizer/Data/BundleEngine.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using AssetsTools.NET.Extra;
using AssetsTools.NET;
using System.Collections.Generic;
using System.IO;

namespace NEO_TWEWY_Randomizer
Expand All @@ -21,39 +19,24 @@ public void UnloadBundles()
manager.UnloadAll();
}

public Bundle LoadBundle(string path, string key)
public TextBundle LoadTextBundle(string path, string key)
{
return new Bundle(manager, LoadBundleFile(path, out bool encrypted), key, encrypted);
return new TextBundle(manager, LoadBundleFile(path, out bool encrypted), key, encrypted);
}

public BundleFileInstance LoadBundleFile(string path, out bool encrypted)
public ScenarioBundle LoadScenarioBundle(string path, string key)
{
return decryptor.LoadAndDecryptBundle(path, out encrypted);
}

public AssetsFileInstance LoadAssetsFileFromBundle(BundleFileInstance bundle)
{
return manager.LoadAssetsFileFromBundle(bundle, 0);
}

public void SaveBundleToFile(BundleFileInstance bundle, string path, bool encrypted)
{
decryptor.SaveAndEncryptBundle(bundle, path, encrypted);
return new ScenarioBundle(manager, LoadBundleFile(path, out bool encrypted), key, encrypted);
}

public void SaveBundleToFile(Bundle bundle, string path)
{
decryptor.SaveAndEncryptBundle(bundle.BundleInstance, Path.Combine(path, bundle.FileName), bundle.Encrypted);
}

private void SetAssetsFileInBundle(BundleFileInstance bundle, AssetsFileInstance assetsFile)
private BundleFileInstance LoadBundleFile(string path, out bool encrypted)
{
bundle.file.BlockAndDirInfo.DirectoryInfos[0].SetNewData(assetsFile.file);
}

private int FindObjectOfName(List<AssetTypeValueField> objBaseFields, string name)
{
return objBaseFields.FindIndex(s => s["m_Name"].AsString == name);
return decryptor.LoadAndDecryptBundle(path, out encrypted);
}
}
}
16 changes: 16 additions & 0 deletions Randomizer/Data/BundleSet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace NEO_TWEWY_Randomizer
{
public class BundleSet
{
public TextBundle TextData { get; set; } = null;
public ScenarioBundle W1D2Scenario { get; set; } = null;
public ScenarioBundle W2D5Scenario { get; set; } = null;

public bool AreAllBundlesLoaded()
{
return TextData != null &&
W1D2Scenario != null &&
W2D5Scenario != null;
}
}
}
Loading

0 comments on commit 65a8f61

Please sign in to comment.