Skip to content

Commit

Permalink
Skins Customs, Inner Dictories and Portrair Layer
Browse files Browse the repository at this point in the history
  • Loading branch information
RedDude committed Jun 8, 2023
1 parent dc1f2f2 commit cf915b3
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 104 deletions.
54 changes: 35 additions & 19 deletions Mod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,6 @@ public static void Start()
{
var allCustomArchers = new List<ArcherCustomData>();

#if DEBUG
Debugger.Launch();
#endif
allCustomArchers.AddRange(LoadContentAtPath($"{Calc.LOADPATH}{_contentCustomArchersPath}", ContentAccess.Content));
var contentPath = Content.GetContentPath("");
allCustomArchers.AddRange(LoadContentAtPath(contentPath+$"/{_customArchersPath}", ContentAccess.ModContent));
Expand Down Expand Up @@ -298,23 +295,35 @@ private static void LoadAltArcher(List<ArcherCustomData> newAltCustom, Dictionar
}
}

private static List<ArcherCustomData> LoadContentAtPath(string path, ContentAccess contentAccess)
private static List<ArcherCustomData> LoadContentAtPath(string path, ContentAccess contentAccess, bool warnNotFound = true)
{
var allCustomArchers = new List<ArcherCustomData>();
if (!Directory.Exists(path))
{
Console.WriteLine($"\nNo Archer Found in \"{path}\" Folder");
if(warnNotFound)
Console.WriteLine($"\nNo Archer Found in \"{path}\" Folder");
return allCustomArchers;
}

var customArchersFound = Directory.GetDirectories(path);

foreach (var directory in customArchersFound)
{
allCustomArchers.AddRange(LoadArchersContent(Content, directory, contentAccess, contentAccess == ContentAccess.Content));
if(directory.EndsWith("Content"))
continue;

allCustomArchers.AddRange(LoadContent(Content, directory, contentAccess, contentAccess == ContentAccess.Content));
}

Console.WriteLine($"\n{allCustomArchers.Count} New Archer(s) Found in \"{path}\" Folder");
if (warnNotFound && allCustomArchers.Count == 0)
{
Console.WriteLine($"\nNo New Archers Found in \"{path}\" Folder");
}
if (allCustomArchers.Count > 0)
{
Console.WriteLine($"\n{allCustomArchers.Count} New Archer(s) Found in \"{path}\" Folder");
}

if (allCustomArchers.Count == 0)
{
return allCustomArchers;
Expand All @@ -329,22 +338,29 @@ private static List<ArcherCustomData> LoadContentAtPath(string path, ContentAcce
return allCustomArchers;
}

private static List<ArcherCustomData> LoadArchersContent(FortContent content, string directory, ContentAccess contentAccess, bool addContentPrefix = false)
private static List<ArcherCustomData> LoadContent(FortContent content, string directory, ContentAccess contentAccess, bool addContentPrefix = false)
{
var newArchers = new List<ArcherCustomData>();
newArchers.AddRange(LoadContentAtPath(directory, contentAccess, false));

var archerName = directory.Split(Convert.ToChar(_separator)).Last();
var path = $"{directory}{_separator}".Replace($"Content{_separator}", $"");
var atlasArcher = content.CreateAtlas($"{path}atlas.xml", $"{path}atlas.png", true, contentAccess);

var pathWithContentPrefix = addContentPrefix ? Calc.LOADPATH + path : path;
// var atlasArcher = new Atlas($"{path}atlas.xml", $"{path}atlas.png", load: true);
customAtlasList.Add(atlasArcher);

if (!File.Exists($"{pathWithContentPrefix}spriteData.xml"))

Atlas atlas = null;
if (File.Exists($"{pathWithContentPrefix}atlas.xml") && File.Exists($"{pathWithContentPrefix}atlas.png"))
{
return new List<ArcherCustomData>(0);
atlas = content.CreateAtlas($"{path}atlas.xml", $"{path}atlas.png", true, contentAccess);
customAtlasList.Add(atlas);
}

var spriteData = content.CreateSpriteData($"{path}spriteData.xml", atlasArcher, contentAccess);

if (!File.Exists($"{pathWithContentPrefix}spriteData.xml") || atlas == null)
{
return newArchers;
}

var spriteData = content.CreateSpriteData($"{path}spriteData.xml", atlas, contentAccess);
var sprites = DynamicData.For(spriteData).Get<Dictionary<string, XmlElement>>("sprites");

if (sprites.Count > 0)
Expand Down Expand Up @@ -374,7 +390,7 @@ private static List<ArcherCustomData> LoadArchersContent(FortContent content, st
customSpriteDataList.Add(spriteData);
}

var atlasArcherMenu = atlasArcher;
var atlasArcherMenu = atlas;
if (File.Exists($"{pathWithContentPrefix}menuAtlas.xml") &&
File.Exists($"{pathWithContentPrefix}menuAtlas.png"))
{
Expand All @@ -385,8 +401,8 @@ private static List<ArcherCustomData> LoadArchersContent(FortContent content, st
}

var filePath = $"{pathWithContentPrefix}archerData.xml";
if (!File.Exists(filePath)) return new List<ArcherCustomData>(0);
var newArchersFromPack = InitializeArcherData(pathWithContentPrefix, atlasArcher, atlasArcherMenu, archerName.ToUpper());
if (!File.Exists(filePath)) return newArchers;
var newArchersFromPack = InitializeArcherData(pathWithContentPrefix, atlas, atlasArcherMenu, archerName.ToUpper());
return newArchersFromPack;
}

Expand Down
112 changes: 35 additions & 77 deletions Source/Layers/PortraitLayers/PortraitLayerPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,53 @@
using MonoMod.Utils;
using TowerFall;
using ArcherPortrait = On.TowerFall.ArcherPortrait;
using MainMenu = On.TowerFall.MainMenu;
using RollcallElement = On.TowerFall.RollcallElement;

namespace ArcherLoaderMod.Source.Layers.PortraitLayers
{
public class PortraitLayerPatch
{
private static bool enabled = false;
public static bool Enabled { get; set; }

private static Dictionary<TowerFall.ArcherPortrait, List<PortraitLayerSpriteComponent>> portraitLayers =
new ();

public static void Load()
{
if(FortEntrance.Settings.DisableLayers)
return;

ArcherPortrait.SetCharacter += OnSetCharacter;
ArcherPortrait.StartJoined += OnArcherPortraitOnStartJoined;
ArcherPortrait.Leave += OnArcherPortraitOnLeave;
ArcherPortrait.Update += OnArcherPortraitOnUpdate;
enabled = true;
MainMenu.DestroyRollcall += OnMainMenuOnDestroyRollcall;
RollcallElement.ctor += OnRollcallElementConstructor;
Enabled = true;
}

public static void Unload()
{
if(!enabled)
if(!Enabled)
return;

ArcherPortrait.SetCharacter -= OnSetCharacter;
ArcherPortrait.StartJoined -= OnArcherPortraitOnStartJoined;
ArcherPortrait.Leave -= OnArcherPortraitOnLeave;
ArcherPortrait.Update -= OnArcherPortraitOnUpdate;
MainMenu.DestroyRollcall -= OnMainMenuOnDestroyRollcall;
RollcallElement.ctor -= OnRollcallElementConstructor;
}

private static void OnRollcallElementConstructor(RollcallElement.orig_ctor orig, TowerFall.RollcallElement self, int index)
{
orig(self, index);
var portrait = DynamicData.For(self).Get<TowerFall.ArcherPortrait>("portrait");
CreateLayersComponents(portrait, portrait.CharacterIndex, portrait.AltSelect);
}

private static void OnMainMenuOnDestroyRollcall(MainMenu.orig_DestroyRollcall orig, TowerFall.MainMenu self)
{
PortraitLayersManager.Clear();
}


private static void OnArcherPortraitOnUpdate(ArcherPortrait.orig_Update orig, TowerFall.ArcherPortrait self)
{
Expand All @@ -44,85 +60,27 @@ private static void OnArcherPortraitOnUpdate(ArcherPortrait.orig_Update orig, To
private static void OnArcherPortraitOnLeave(ArcherPortrait.orig_Leave orig, TowerFall.ArcherPortrait self)
{
orig(self);
if (!portraitLayers.ContainsKey(self)) return;
var layers = portraitLayers[self];
if (layers == null) return;
foreach (var portraitLayerInfo in layers)
{
portraitLayerInfo.Visible = portraitLayerInfo.layerInfo.AttachTo == PortraitLayersAttachType.NotJoin;
}
PortraitLayersManager.OnPortraitLeave(self);
}


private static void OnArcherPortraitOnStartJoined(ArcherPortrait.orig_StartJoined orig, TowerFall.ArcherPortrait self)
{
orig(self);
if (!portraitLayers.ContainsKey(self)) return;
var layers = portraitLayers[self];
if (layers == null) return;
foreach (var portraitLayerInfo in layers)
{
portraitLayerInfo.Visible = portraitLayerInfo.layerInfo.AttachTo == PortraitLayersAttachType.Join;
}
PortraitLayersManager.OnPortraitStartJoin(self);
}

private static void OnSetCharacter(ArcherPortrait.orig_SetCharacter origSetCharacter, TowerFall.ArcherPortrait self, int characterIndex, ArcherData.ArcherTypes altSelect, int moveDir)
{
PortraitLayersManager.HideAllLayers(self);
origSetCharacter(self, characterIndex, altSelect, moveDir);
CreateLayersComponents(self, characterIndex, altSelect);
}

private static void OnSetCharacter(ArcherPortrait.orig_SetCharacter origSetCharacter, TowerFall.ArcherPortrait archerPortrait, int characterIndex, ArcherData.ArcherTypes altSelect, int moveDir)
public static void CreateLayersComponents(TowerFall.ArcherPortrait archerPortrait, int characterIndex, ArcherData.ArcherTypes altSelect)
{
if (portraitLayers.ContainsKey(archerPortrait))
{
var currentLayers = portraitLayers[archerPortrait];
if (currentLayers == null) return;
foreach (var portraitLayerInfo in currentLayers)
{
portraitLayerInfo.Visible = false;
}
}

origSetCharacter(archerPortrait, characterIndex, altSelect, moveDir);
var data = ArcherData.Get(characterIndex, altSelect);

var exist = Mod.ArcherCustomDataDict.TryGetValue(data, out var archerCustomData);
if (!exist) return;

var layerInfos = archerCustomData.PortraitLayerInfos;
if (layerInfos == null) return;

if (!portraitLayers.ContainsKey(archerPortrait))
{
var flashSprite = DynamicData.For(archerPortrait).Get<Sprite<string>>("flash");
var flashIndex = -1;
for (var i = 0; i < archerPortrait.Components.Count; i++)
{
if (archerPortrait.Components[i] == flashSprite)
{
flashIndex = i;
}
}

var newLayers = new List<PortraitLayerSpriteComponent>(layerInfos.Count);
foreach (var portraitLayerInfo in layerInfos)
{
var layer = new PortraitLayerSpriteComponent(portraitLayerInfo,true, false);
archerPortrait.Add(layer);
newLayers.Add(layer);
archerPortrait.Components.Remove(layer);
archerPortrait.Components.Insert(flashIndex, layer);
}
portraitLayers[archerPortrait] = newLayers;
}

var layers = portraitLayers[archerPortrait];
foreach (var portraitLayerInfo in layers)
{
if (portraitLayerInfo.layerInfo.AttachTo == PortraitLayersAttachType.Join)
portraitLayerInfo.Visible = false;
else if (portraitLayerInfo.layerInfo.AttachTo == PortraitLayersAttachType.NotJoin)
{
portraitLayerInfo.Visible = true;
}

else
portraitLayerInfo.Visible = portraitLayerInfo.Visible;
}
PortraitLayersManager.CreateLayersComponents(archerPortrait, data);
}
}
}
121 changes: 121 additions & 0 deletions Source/Layers/PortraitLayers/PortraitLayersManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using System.Collections.Generic;
using Monocle;
using MonoMod.Utils;
using TowerFall;

namespace ArcherLoaderMod.Source.Layers.PortraitLayers
{
public class PortraitLayersManager
{
public static Dictionary<ArcherPortrait, Dictionary<ArcherData, List<PortraitLayerSpriteComponent>>> PortraitLayers =
new ();

public static void Clear()
{
PortraitLayers.Clear();
}

public static void HideAllLayers(ArcherPortrait self)
{
if (GetLayerByPortraitAndData(self, out var layers)) return;
if (layers == null) return;
foreach (var portraitLayerInfo in layers)
{
portraitLayerInfo.Visible = false;
}
}

public static void ShowAllLayersFromType(PortraitLayersAttachType type, ArcherPortrait self)
{
if (GetLayerByPortraitAndData(self, out var layers)) return;
if (layers == null) return;
foreach (var portraitLayerInfo in layers)
{
portraitLayerInfo.Visible = portraitLayerInfo.layerInfo.AttachTo == type;
}
}

public static void ShowAllLayersFromType(PortraitLayersAttachType type, ArcherPortrait self, ArcherData data)
{
if (GetLayerByPortraitAndData(self, data, out var layers)) return;
if (layers == null) return;
foreach (var portraitLayerInfo in layers)
{
portraitLayerInfo.Visible = portraitLayerInfo.layerInfo.AttachTo == type;
}
}

public static void OnPortraitLeave(ArcherPortrait self)
{
if (GetLayerByPortraitAndData(self, out var layers)) return;
if (layers == null) return;
ShowAllLayersFromType(PortraitLayersAttachType.NotJoin, self);
}

public static void OnPortraitStartJoin(ArcherPortrait self)
{
if (GetLayerByPortraitAndData(self, out var layers)) return;
if (layers == null) return;
ShowAllLayersFromType(PortraitLayersAttachType.Join, self);
}

private static bool GetLayerByPortraitAndData(ArcherPortrait self, out List<PortraitLayerSpriteComponent> layers)
{
if (!PortraitLayers.ContainsKey(self))
{
layers = null;
return true;
}

var data = ArcherData.Get(self.CharacterIndex, self.AltSelect);
return !PortraitLayers[self].TryGetValue(data, out layers);
}

private static bool GetLayerByPortraitAndData(ArcherPortrait self, ArcherData data, out List<PortraitLayerSpriteComponent> layers)
{
if (PortraitLayers.ContainsKey(self))
return !PortraitLayers[self].TryGetValue(data, out layers);

layers = null;
return true;
}

public static void CreateLayersComponents(ArcherPortrait archerPortrait, ArcherData data)
{
var exist = Mod.ArcherCustomDataDict.TryGetValue(data, out var archerCustomData);
if (!exist) return;

var layerInfos = archerCustomData.PortraitLayerInfos;
if (layerInfos == null) return;

if (!PortraitLayers.ContainsKey(archerPortrait))
{
PortraitLayers[archerPortrait] = new Dictionary<ArcherData, List<PortraitLayerSpriteComponent>>();
}

if (PortraitLayers[archerPortrait].ContainsKey(data)) return;

var flashSprite = DynamicData.For(archerPortrait).Get<Sprite<int>>("flash");
var flashIndex = -1;
for (var i = 0; i < archerPortrait.Components.Count; i++)
{
if (archerPortrait.Components[i] == flashSprite)
{
flashIndex = i;
}
}

var newLayers = new List<PortraitLayerSpriteComponent>(layerInfos.Count);
foreach (var portraitLayerInfo in layerInfos)
{
var layer = new PortraitLayerSpriteComponent(portraitLayerInfo, true, false);
archerPortrait.Add(layer);
newLayers.Add(layer);
archerPortrait.Components.Remove(layer);
archerPortrait.Components.Insert(flashIndex, layer);
}

PortraitLayers[archerPortrait][data] = newLayers;
}
}
}
5 changes: 1 addition & 4 deletions Source/Patch/ContentLoaderPatcher.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using Monocle;
using TowerFall;
using Sounds = On.TowerFall.Sounds;
using SpriteData = On.Monocle.SpriteData;
using Sounds = On.TowerFall.Sounds;

namespace ArcherLoaderMod.Patch
{
Expand Down
Loading

0 comments on commit cf915b3

Please sign in to comment.