-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Artifact Code API] Custom artifact codes for Bulwark's Ambry (#299)
* Added first iteration of ArtifactCodeAPI * Updated files * Changes and Modifications according to CoreDevs Feedback ArtifactCodeAPI: * Uses a single Logger.LogInfo() to log the code inputted. * Improvement in the foreach loop in the awake hook, now uses a tupple correctly. * ArtifactCodeAPI now checks wether a code has already been added, should avoid code conflcts. * Moved wrapper * Replaced methods that asked for a List<int> and int[] with an IEnumerable<int>. ArtifactCodeScriptableObject: * Renamed to ArtifactCode * Moved to a new folder that holds scriptable object. * Now in the namespace R2API.ScriptableObjects README.MD * Added the pullrequest in the changelog * Readme fix * Ran codemaid to cleanup codestyle Co-authored-by: HarbingerOfMe <harbingerofme@gmail.com>
- Loading branch information
1 parent
1dbb5fc
commit e4304e6
Showing
3 changed files
with
255 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
using R2API.ScriptableObjects; | ||
using R2API.Utils; | ||
using RoR2; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using UnityEngine; | ||
using UnityEngine.Events; | ||
|
||
namespace R2API { | ||
|
||
/// <summary> | ||
/// API for adding custom artifact codes to the game. | ||
/// </summary> | ||
[R2APISubmodule] | ||
public static class ArtifactCodeAPI { | ||
private static readonly List<(ArtifactDef, Sha256HashAsset)> ArtifactsCodes = new List<(ArtifactDef, Sha256HashAsset)>(); | ||
|
||
/// <summary> | ||
/// Return true if the submodule is loaded. | ||
/// </summary> | ||
public static bool Loaded { | ||
get => _loaded; | ||
internal set => _loaded = value; | ||
} | ||
|
||
private static bool _loaded; | ||
|
||
#region Hooks | ||
|
||
[R2APISubmoduleInit(Stage = InitStage.SetHooks)] | ||
internal static void SetHooks() { | ||
On.RoR2.PortalDialerController.Awake += AddCodes; | ||
On.RoR2.PortalDialerController.PerformActionServer += PrintSha256HashCode; | ||
} | ||
|
||
/// <summary> | ||
/// Prints the Artifact Code that the player inputs in the dialer. Useful for mod creators. | ||
/// </summary> | ||
/// <param name="orig"></param> | ||
/// <param name="self"></param> | ||
/// <param name="sequence"></param> | ||
/// <returns></returns> | ||
private static bool PrintSha256HashCode(On.RoR2.PortalDialerController.orig_PerformActionServer orig, PortalDialerController self, byte[] sequence) { | ||
var result = self.GetResult(sequence); | ||
R2API.Logger.LogInfo("Inputted Artifact Code:\n_00_07: " + result._00_07 + "\n_08_15: " + result._08_15 + "\n_16_23: " + result._16_23 + "\n_24_31: " + result._24_31); | ||
return orig(self, sequence); | ||
} | ||
|
||
/// <summary> | ||
/// Adds custom ArtifactCodes to the portal dialer controller instance found in sky meadow. | ||
/// </summary> | ||
/// <param name="orig"></param> | ||
/// <param name="self"></param> | ||
private static void AddCodes(On.RoR2.PortalDialerController.orig_Awake orig, PortalDialerController self) { | ||
foreach ((ArtifactDef artifactDef, Sha256HashAsset artifactCode) in ArtifactsCodes) { | ||
if (!ArtifactCatalog.GetArtifactDef(artifactDef.artifactIndex)) { | ||
R2API.Logger.LogWarning($"ArtifactDef of name {artifactDef.cachedName} is not in the ArtifactCatalog. ignoring entry."); | ||
continue; | ||
} | ||
if (CheckIfCodeIsUsed(artifactCode, self.actions)) { | ||
R2API.Logger.LogWarning($"A code with the values of {artifactCode.name} has already been added to the portal dialer controller. ignoring entry."); | ||
continue; | ||
} | ||
void Wrapper() => self.OpenArtifactPortalServer(artifactDef); | ||
|
||
PortalDialerController.DialedAction dialedAction = new PortalDialerController.DialedAction(); | ||
dialedAction.hashAsset = artifactCode; | ||
dialedAction.action = new UnityEvent(); | ||
dialedAction.action.AddListener(Wrapper); | ||
|
||
HG.ArrayUtils.ArrayAppend(ref self.actions, dialedAction); | ||
R2API.Logger.LogInfo("Added code for " + artifactDef.cachedName); | ||
} | ||
orig(self); | ||
} | ||
|
||
private static bool CheckIfCodeIsUsed(Sha256HashAsset hashAsset, PortalDialerController.DialedAction[] dialedActions) { | ||
Sha256Hash hash = hashAsset.value; | ||
return dialedActions.Any(dialedAction => dialedAction.hashAsset.value.Equals(hash)); | ||
} | ||
|
||
#endregion Hooks | ||
|
||
#region Methods | ||
|
||
/// <summary> | ||
/// Add a custom Artifact code to the SkyMeadow Artifact portal dialer. | ||
/// The artifactDef must exist within the initialized ArtifactCatalog for it to properly added to the portal dialer. | ||
/// </summary> | ||
/// <param name="artifactDef">The artifactDef tied to the artifact code.</param> | ||
/// <param name="sha256HashAsset">The artifact code.</param> | ||
public static void Add(ArtifactDef? artifactDef, Sha256HashAsset? sha256HashAsset) { | ||
if (!Loaded) { | ||
throw new InvalidOperationException($"{nameof(ArtifactCodeAPI)} is not loaded. Please use [{nameof(R2APISubmoduleDependency)}(nameof({nameof(ArtifactCodeAPI)})]"); | ||
} | ||
ArtifactsCodes.Add((artifactDef, sha256HashAsset)); | ||
} | ||
|
||
/// <summary> | ||
/// Add a custom Artifact code to the SkyMeadow Artifact portal dialer. | ||
/// The artifactDef must exist within the initialized ArtifactCatalog for it to properly added to the portal dialer. | ||
/// </summary> | ||
/// <param name="artifactDef">The artifactDef tied to the artifact code.</param> | ||
/// <param name="artifactCode">The artifactCode written in the ArtifactCodeScriptableObject.</param> | ||
public static void Add(ArtifactDef? artifactDef, ArtifactCode? artifactCode) { | ||
if (!Loaded) { | ||
throw new InvalidOperationException($"{nameof(ArtifactCodeAPI)} is not loaded. Please use [{nameof(R2APISubmoduleDependency)}(nameof({nameof(ArtifactCodeAPI)})]"); | ||
} | ||
artifactCode.Start(); | ||
ArtifactsCodes.Add((artifactDef, artifactCode.hashAsset)); | ||
} | ||
|
||
/// <summary> | ||
/// Add a custom Artifact code to the SkyMeadow Artifact portal dialer. | ||
/// The artifactDef must exist within the initialized Artifactcatalog for it to be properly added to the portal dialer. | ||
/// </summary> | ||
/// <param name="artifactDef">The artifactDef tied to the artifact code.</param> | ||
/// <param name="code_00_07">The values printed by R2API when a code is inputted.</param> | ||
/// <param name="code_08_15">The values printed by R2API when a code is inputted.</param> | ||
/// <param name="code_16_23">The values printed by R2API when a code is inputted.</param> | ||
/// <param name="code_24_31">The values printed by R2API when a code is inputted.</param> | ||
public static void Add(ArtifactDef? artifactDef, ulong code_00_07, ulong code_08_15, ulong code_16_23, ulong code_24_31) { | ||
if (!Loaded) { | ||
throw new InvalidOperationException($"{nameof(ArtifactCodeAPI)} is not loaded. Please use [{nameof(R2APISubmoduleDependency)}(nameof({nameof(ArtifactCodeAPI)})]"); | ||
} | ||
Sha256HashAsset hashAsset = ScriptableObject.CreateInstance<Sha256HashAsset>(); | ||
hashAsset.value._00_07 = code_00_07; | ||
hashAsset.value._08_15 = code_08_15; | ||
hashAsset.value._16_23 = code_16_23; | ||
hashAsset.value._24_31 = code_24_31; | ||
|
||
ArtifactsCodes.Add((artifactDef, hashAsset)); | ||
} | ||
|
||
/// <summary> | ||
/// Add a custom Artifact code to the SkyMeadow Artifact portal dialer. | ||
/// The artifactDef must exist within the initialized ArtifactCatalog for it to be properly added to the portal dialer. | ||
/// </summary> | ||
/// <param name="artifactDef">The artifactDef tied to the artifact code.</param> | ||
/// <param name="CompoundValues">An IEnumerable of type "int" with a size of 9 filled with compound values. A list of size 9 filled with compound values.</param> | ||
public static void Add(ArtifactDef? artifactDef, IEnumerable<int> CompoundValues) { | ||
if (!Loaded) { | ||
throw new InvalidOperationException($"{nameof(ArtifactCodeAPI)} is not loaded. Please use [{nameof(R2APISubmoduleDependency)}(nameof({nameof(ArtifactCodeAPI)})]"); | ||
} | ||
ArtifactCode artifactCode = ScriptableObject.CreateInstance<ArtifactCode>(); | ||
artifactCode.ArtifactCompounds = (List<int>)CompoundValues; | ||
Add(artifactDef, artifactCode); | ||
} | ||
|
||
#endregion Methods | ||
|
||
#region Vanilla Compound Values | ||
|
||
/// <summary> | ||
/// Contains the values of Vanilla risk of rain 2 Artifact Compounds. | ||
/// </summary> | ||
public static class CompoundValues { | ||
|
||
/// <summary> | ||
/// Value of the Empty compound. | ||
/// </summary> | ||
public const int Empty = 11; | ||
|
||
/// <summary> | ||
/// Value of the Square compound. | ||
/// </summary> | ||
public const int Square = 7; | ||
|
||
/// <summary> | ||
/// Value of the Circle compound. | ||
/// </summary> | ||
public const int Circle = 1; | ||
|
||
/// <summary> | ||
/// Value for the Triangle compound. | ||
/// </summary> | ||
public const int Triangle = 3; | ||
|
||
/// <summary> | ||
/// Value for the Diamond compound. | ||
/// </summary> | ||
public const int Diamond = 5; | ||
} | ||
|
||
#endregion Vanilla Compound Values | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
using RoR2; | ||
using System.Collections.Generic; | ||
using System.Security.Cryptography; | ||
using UnityEngine; | ||
|
||
namespace R2API.ScriptableObjects { | ||
|
||
[CreateAssetMenu(fileName = "New Artifact Code", menuName = "R2API/ArtifactCodeAPI/ArtifactCode", order = 0)] | ||
public class ArtifactCode : ScriptableObject { | ||
|
||
/// <summary> | ||
/// List that contains your Artifact code. for information on how to fill this list, check this wiki page: | ||
/// <para>https://github.com/risk-of-thunder/R2Wiki/wiki/Creating-Custom-Artifacts</para> | ||
/// </summary> | ||
public List<int> ArtifactCompounds = new List<int>(); | ||
|
||
private int[] artifactSequence; | ||
|
||
private SHA256 hasher; | ||
|
||
/// <summary> | ||
/// The Sha256HashAsset stored in this scriptable object. | ||
/// </summary> | ||
[HideInInspector] | ||
public Sha256HashAsset hashAsset; | ||
|
||
public void Start() { | ||
hasher = SHA256.Create(); | ||
|
||
List<int> sequence = new List<int>(); | ||
|
||
sequence.Add(ArtifactCompounds[2]); | ||
sequence.Add(ArtifactCompounds[5]); | ||
sequence.Add(ArtifactCompounds[8]); | ||
sequence.Add(ArtifactCompounds[1]); | ||
sequence.Add(ArtifactCompounds[7]); | ||
sequence.Add(ArtifactCompounds[4]); | ||
sequence.Add(ArtifactCompounds[0]); | ||
sequence.Add(ArtifactCompounds[3]); | ||
sequence.Add(ArtifactCompounds[6]); | ||
|
||
artifactSequence = sequence.ToArray(); | ||
|
||
hashAsset = CreateHashAsset(CreateHash()); | ||
} | ||
|
||
internal Sha256Hash CreateHash() { | ||
byte[] array = new byte[artifactSequence.Length]; | ||
for (int i = 0; i < array.Length; i++) { | ||
array[i] = (byte)artifactSequence[i]; | ||
} | ||
return Sha256Hash.FromBytes(hasher.ComputeHash(array)); | ||
} | ||
|
||
internal Sha256HashAsset CreateHashAsset(Sha256Hash hash) { | ||
var asset = ScriptableObject.CreateInstance<Sha256HashAsset>(); | ||
asset.value._00_07 = hash._00_07; | ||
asset.value._08_15 = hash._08_15; | ||
asset.value._16_23 = hash._16_23; | ||
asset.value._24_31 = hash._24_31; | ||
return asset; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters