Skip to content

Commit

Permalink
Merge pull request #18 from PrashantMohta/dandydev
Browse files Browse the repository at this point in the history
Global Swaps and bug fixes
  • Loading branch information
PrashantMohta authored Apr 30, 2022
2 parents bc2fce4 + 26469da commit 9df50c5
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 69 deletions.
5 changes: 4 additions & 1 deletion AddonExample/AsymmetricKnight/AsymmetricKnight.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ public bool isCustomKnightInstalled(){
public void AddCustomKnightHandlers(){
SkinManager.OnSetSkin += (_,e) => {
var skin = SkinManager.GetCurrentSkin();
var currDirIsLeft = HeroController.instance.transform.localScale.x < 0;
var currDirIsLeft = false;
if(HeroController.instance != null && HeroController.instance.transform.localScale.x < 0){
currDirIsLeft = true;
}

if(lastSkin != skin.GetId()){
Knight = new Asymmetrical(CustomKnight.Knight.NAME);
Expand Down
2 changes: 1 addition & 1 deletion CustomKnight/CustomKnight.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public override void Initialize(Dictionary<string, Dictionary<string, GameObject

SkinManager.getSkinNames();
SkinManager.CurrentSkin = SkinManager.GetSkinById(CustomKnight.GlobalSettings.DefaultSkin);

swapManager.SkinChangeSwap(SkinManager.CurrentSkin);
// Initial load
if (preloadedObjects != null)
{
Expand Down
5 changes: 4 additions & 1 deletion CustomKnight/CustomKnight.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<OutputType>Library</OutputType>
<RootNamespace>CustomKnight</RootNamespace>
<AssemblyName>CustomKnight</AssemblyName>
<AssemblyVersion>2.0.1</AssemblyVersion>
<AssemblyVersion>2.1.0</AssemblyVersion>
<TargetFramework>net472</TargetFramework>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
Expand All @@ -28,6 +28,9 @@
<Reference Include="MMHOOK_PlayMaker">
<HintPath>$(ModdingAPi)\MMHOOK_PlayMaker.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>$(ModdingAPI)\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PlayMaker">
<HintPath>$(VanillaFiles)\PlayMaker.dll</HintPath>
</Reference>
Expand Down
8 changes: 7 additions & 1 deletion CustomKnight/Menu/BetterMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ internal static void ToggleDumping(){
SetDumpButton();
}

internal static void DumpAll(){
CustomKnight.dumpManager.enabled = !CustomKnight.dumpManager.enabled;
CustomKnight.dumpManager.walk();
}

private static void OpenSkins(){
IoUtils.OpenDefault(SkinManager.SKINS_FOLDER);
}
Expand Down Expand Up @@ -106,7 +111,8 @@ internal static Menu PrepareMenu(ModToggleDelegates toggleDelegates){
){ XDelta = 425f},
new MenuRow(
new List<Element>{
new MenuButton("DumpButton","Dumps the sprites that Swapper supports (Expect lag)",(_)=>ToggleDumping(),Id:"DumpButton"),
new MenuButton("Dump","Dumps the sprites that Swapper supports (Expect lag)",(_)=>ToggleDumping(),Id:"DumpButton"),
//new MenuButton("Dump All","Dumps Everything (Can take hours)",(_)=>DumpAll(),Id:"DumpAllButton"),
//new MenuButton("Need Help?","Join the HK Modding Discord",(_)=>OpenLink("https://discord.gg/J4SV6NFxAA")),
},
Id:"AdditonalButtonGroup"
Expand Down
10 changes: 8 additions & 2 deletions CustomKnight/Menu/SkinsList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,15 @@ private static IEnumerator applyAndGoBack()
MenuRef.Find("applying").isVisible = true;
setSkinButtonVisibility(false);
yield return new WaitForSecondsRealtime(0.2f);
BetterMenu.MenuRef?.Find("SelectSkinOption")?.updateAfter(_ => BetterMenu.ApplySkin());
BetterMenu.MenuRef?.Find("SelectSkinOption")?.updateAfter(_ => {
try {
BetterMenu.ApplySkin();
} catch(Exception e){
CustomKnight.Instance.Log(e.ToString());
}
}
);
yield return new WaitForSecondsRealtime(0.2f);

UIManager.instance.UIGoToDynamicMenu(lastMenu);
yield return new WaitForSecondsRealtime(0.2f);

Expand Down
14 changes: 6 additions & 8 deletions CustomKnight/Skin/Base/SkinManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ internal static void Unload(){
}
private static IEnumerator ChangeSkinRoutine(bool skipFlash)
{
if(!skipFlash){
if(!skipFlash && HeroController.instance != null){
HeroController.instance.GetComponent<SpriteFlash>().flashFocusHeal();
}
LoadSkin();
Expand Down Expand Up @@ -242,9 +242,7 @@ public static ISelectableSkin[] GetInstalledSkins(){
/// </summary>
/// <param name="skipFlash">a <c>bool</c> that determines if the knight should flash white</param>
public static void RefreshSkin(bool skipFlash){
if(HeroController.instance != null){
GameManager.instance.StartCoroutine(ChangeSkinRoutine(skipFlash));
}
GameManager.instance.StartCoroutine(ChangeSkinRoutine(skipFlash));
}
public static event EventHandler<EventArgs> OnSetSkin;

Expand All @@ -256,14 +254,14 @@ public static void SetSkinById(string id)
{
var Skin = GetSkinById(id);
CustomKnight.Instance.Log("Trying to apply skin :" + Skin.GetId());
if(CurrentSkin.GetId() == Skin.GetId()) { return; }
if(CurrentSkin != null && CurrentSkin.GetId() == Skin.GetId()) { return; }
CurrentSkin = Skin;
// use this when saving so you save to the right settings
if(GameManager.instance.IsNonGameplayScene()){
CustomKnight.GlobalSettings.DefaultSkin = Skin.GetId();
CustomKnight.GlobalSettings.DefaultSkin = CurrentSkin.GetId();
} else {
CustomKnight.GlobalSettings.DefaultSkin = Skin.GetId();
CustomKnight.SaveSettings.DefaultSkin = Skin.GetId();
CustomKnight.GlobalSettings.DefaultSkin = CurrentSkin.GetId();
CustomKnight.SaveSettings.DefaultSkin = CurrentSkin.GetId();
};
RefreshSkin(false);
OnSetSkin?.Invoke(CustomKnight.Instance,new EventArgs());
Expand Down
8 changes: 2 additions & 6 deletions CustomKnight/Skin/Base/SpriteLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ internal static void ModifyHeroTextures(SaveGameData data = null)

internal static IEnumerator Start()
{
CustomKnight.swapManager.SkinChangeSwap(SkinManager.CurrentSkin);
yield return new WaitWhile(
() => HeroController.instance == null || GameManager.instance == null || GameManager.instance.gameMap == null
);

LoadSprites();
}

Expand Down Expand Up @@ -123,11 +123,7 @@ private static IEnumerator SetHeroTex()
}*/

PullDefaultTextures();
CustomKnight.swapManager.resetAllTextures();
CustomKnight.swapManager.resetAndLoadGlobalSwaps();
if(CurrentSkin.hasSwapper()){
CustomKnight.swapManager.Swap(CurrentSkin.getSwapperPath());
}
CustomKnight.swapManager.SkinChangeSwap(SkinManager.CurrentSkin);
foreach(KeyValuePair<string,Skinable> kvp in SkinManager.Skinables){
kvp.Value.Apply();
}
Expand Down
171 changes: 146 additions & 25 deletions CustomKnight/Skin/Swapper/DumpManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
using static Satchel.IoUtils;

namespace CustomKnight {

public class coroutineHelper : MonoBehaviour{}
public class DumpManager{

internal bool enabled = false;
Expand All @@ -29,66 +31,177 @@ internal DumpManager(){
}

internal Dictionary<string,bool> isTextureDumped = new Dictionary<string,bool>();
internal Dictionary<int,string> MaterialProcessed = new();

internal void dumpSpriteForGo(Scene scene,GameObject go){
if(go == null) {return;}
var name = go.GetPath(true);
Log("game object to be dumped -" + go.name);
Log($"gameobject path {name}");
Animator anim = go.GetComponent<Animator>();
SpriteRenderer sr = go.GetComponent<SpriteRenderer>();
if(anim != null && sr != null && false){ //since custom animation frames dont work anyway lets disable them for now
var caf = go.GetAddComponent<CustomAnimationFrames>();
caf.dumpPath = Path.Combine(SkinManager.DATA_DIR,"Dump");
caf.dump = true;
return;
tk2dSprite tk2ds = go.GetComponent<tk2dSprite>();

var mat = sr != null ? sr.material : (tk2ds != null ? tk2ds.GetCurrentSpriteDef()?.material : null);
int crc = 0;
var validForGlobal = true;
if(mat != null){
crc = mat.ComputeCRC();
if(MaterialProcessed.TryGetValue(crc,out var _hash)){
validForGlobal = false;
}
}
Log($"dumping {done}/{detected}");
Log("game object to be dumped -" + go.name);
Log($"gameobject path {name}");

if(sr != null && sr.sprite != null){
SaveSpriteDump(scene,name, sr.sprite);
if(scene.name == "DontDestroyOnLoad"){
return; // dont dump sprites only tk2d from DontDestroyOnLoad
if(validForGlobal){
var tex = SpriteUtils.ExtractTextureFromSprite(sr.sprite);
var hash = tex.getHash();
MaterialProcessed[crc] = hash;
SaveTextureByPath("Global",hash,tex);
GameObject.Destroy(tex);
}
} else {
if(anim != null){
// remove the animation component
GameObject.Destroy(anim);
}
SaveSpriteDump(scene,name, sr.sprite);
}
return;
}
tk2dSprite tk2ds = go.GetComponent<tk2dSprite>();
if(tk2ds != null){
SaveTextureDump(scene,name, (Texture2D) tk2ds.GetCurrentSpriteDef().material.mainTexture);
//dump as texture hash
var sdef = tk2ds.GetCurrentSpriteDef();
var tex = (Texture2D) sdef.material.mainTexture;
if(validForGlobal){
var dupe = TextureUtils.duplicateTexture(tex);
var hash = dupe.getHash();
MaterialProcessed[crc] = hash;
SaveTextureByPath("Global",hash,dupe);
GameObject.Destroy(dupe);
}
if(scene.name != "DontDestroyOnLoad"){
SaveTextureDump(scene,name, tex);
}
return;
}
}

internal Coroutine dumpAllSpritesCoroutineRef;
internal bool pending = false;
internal int detected = 0 , done = 0;
internal bool DontDestroyOnLoadScene = true;

internal void dumpAllSpritesInScene(Scene scene){
if(scene == null || !scene.IsValid()){return;}
var GOList = scene.GetAllGameObjects();
detected += GOList.Count();
foreach(var go in GOList){
try{
dumpSpriteForGo(scene,go);
} catch(Exception e){
Log(e.ToString());
}
done += 1;
}
}
internal IEnumerator dumpAllSpritesCoroutine(){
done = 0;
detected = done;

do{
pending = false;
yield return null;
var scenes = SceneUtils.GetAllLoadedScenes();
var scenes = SceneUtils.GetAllLoadedScenes(false);
foreach(var scene in scenes){
var GOList = scene.GetAllGameObjects();
foreach(var go in GOList){
try{
dumpSpriteForGo(scene,go);
} catch(Exception e){
Log(e.ToString());
}
yield return null;
if(scene == null || !scene.IsValid()){continue;}
var GOList = scene.GetAllGameObjects();
detected += GOList.Count();
foreach(var go in GOList){
try{
dumpSpriteForGo(scene,go);
} catch(Exception e){
Log(e.ToString());
}
done += 1;
yield return null;
}
}
pending = false;
} while(pending); // handle the case where a new go is spawned while the coro is still dumping
if(DontDestroyOnLoadScene){
dumpAllSpritesInScene(SceneUtils.GetDontDestorOnLoadScene());
DontDestroyOnLoadScene = false;
}
dumpAllSpritesCoroutineRef = null;
}
internal AsyncOperation loadScene(int i){
AsyncOperation asyncLoad = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(i,LoadSceneMode.Additive);
asyncLoad.priority = i;
return asyncLoad;
}

internal IEnumerator walkScenes(){
yield return null;
var sceneCount = UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings;
var i = 4;
while(true){
if(dumpAllSpritesCoroutineRef == null || !pending){
Log($"loading next scene : id {i}");
//load next scenes
if( i < sceneCount){
AsyncOperation asyncLoad = loadScene(i);
yield return new WaitForSeconds(2);
dumpAllSprites();
yield return new WaitForSeconds(2);
// Wait until the asynchronous scene fully loads & dumps
while (detected > done)
{
yield return null;
}
if(i > 3){
UnityEngine.SceneManagement.SceneManager.UnloadSceneAsync(i);
}
i++;
}
}
yield return new WaitForSeconds(0.1f);
}
}
internal void walk(){
var g = new GameObject();
GameObject.DontDestroyOnLoad(g);
g.AddComponent<coroutineHelper>().StartCoroutine(walkScenes());
}
private GameObject coroHelperObj;
internal void dumpAllSprites(){
if(!enabled) {return;}
pending = true;
if(coroHelperObj == null){
coroHelperObj = new GameObject();
GameObject.DontDestroyOnLoad(coroHelperObj);
}
if(dumpAllSpritesCoroutineRef == null){
dumpAllSpritesCoroutineRef = GameManager.instance.StartCoroutine(dumpAllSpritesCoroutine());
dumpAllSpritesCoroutineRef = coroHelperObj.GetAddComponent<coroutineHelper>().StartCoroutine(dumpAllSpritesCoroutine());
}
}

internal void dumpAllSprites(Scene scene,LoadSceneMode mode){
if(!enabled) {return;}
Log($"Entered scene : Name {scene.name}");
/*if(coroHelperObj != null){
coroHelperObj.GetAddComponent<coroutineHelper>().StopCoroutine(dumpAllSpritesCoroutineRef);
GameObject.Destroy(coroHelperObj);
dumpAllSpritesCoroutineRef = null;
}*/
dumpAllSprites();
}

internal void dumpAllSprites(On.HutongGames.PlayMaker.Actions.ActivateGameObject.orig_DoActivateGameObject orig, HutongGames.PlayMaker.Actions.ActivateGameObject self){
orig(self);
if(!enabled) {return;}
if(self.gameObject.GameObject.Value != null){
dumpAllSprites();
}
Expand Down Expand Up @@ -117,10 +230,11 @@ internal void SaveSpriteDump(Scene scene,string objectName, Sprite sprite){
isTextureDumped[outpath] = true;
}
}
internal void SaveTextureDump(Scene scene,string objectName, Texture2D texture){
if(!enabled) {return;}

internal void SaveTextureByPath(string sceneName,string objectName, Texture2D texture){
string DUMP_DIR = Path.Combine(SkinManager.DATA_DIR,"Dump");
string scenePath = Path.Combine(DUMP_DIR,scene.name);
string scenePath = Path.Combine(DUMP_DIR,sceneName);

EnsureDirectory(DUMP_DIR);
EnsureDirectory(scenePath);

Expand All @@ -131,8 +245,11 @@ internal void SaveTextureDump(Scene scene,string objectName, Texture2D texture){
Log(e.ToString());
}
if(!isTextureDumped.TryGetValue(outpath,out bool path) && !File.Exists(outpath)){
Texture2D dupe = TextureUtils.duplicateTexture(texture);
Texture2D dupe = texture.isReadable ? texture : TextureUtils.duplicateTexture(texture);
byte[] texBytes = dupe.EncodeToPNG();
if(dupe != texture){
GameObject.Destroy(dupe);
}
try{
File.WriteAllBytes(outpath,texBytes);
} catch (IOException e){
Expand All @@ -141,6 +258,10 @@ internal void SaveTextureDump(Scene scene,string objectName, Texture2D texture){
isTextureDumped[outpath] = true;
}
}
internal void SaveTextureDump(Scene scene,string objectName, Texture2D texture){
if(!enabled) {return;}
SaveTextureByPath(scene.name,objectName,texture);
}
internal void SaveTextDump( string key, string value){
if(!enabled) {return;}
string DUMP_DIR = Path.Combine(SkinManager.DATA_DIR,"Dump");
Expand Down
Loading

0 comments on commit 9df50c5

Please sign in to comment.