-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
502 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,20 @@ | ||
global using System; | ||
global using System.Collections.Generic; | ||
global using System.Linq; | ||
global using System.Reflection; | ||
global using System.Runtime.CompilerServices; | ||
|
||
global using HutongGames.PlayMaker; | ||
|
||
global using Modding; | ||
|
||
global using Satchel; | ||
|
||
global using TribeOfBattle.Util; | ||
|
||
global using UnityEngine; | ||
global using UnityEngine.SceneManagement; | ||
|
||
global using Lang = Language.Language; | ||
global using UObject = UnityEngine.Object; | ||
global using USceneManager = UnityEngine.SceneManagement.SceneManager; |
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,31 @@ | ||
using static Modding.IMenuMod; | ||
|
||
namespace TribeOfBattle; | ||
|
||
public sealed partial class TribeOfBattle : IMenuMod { | ||
bool IMenuMod.ToggleButtonInsideMenu => true; | ||
|
||
List<MenuEntry> IMenuMod.GetMenuData(MenuEntry? toggleButtonEntry) => new() { | ||
toggleButtonEntry!.Value, | ||
new( | ||
"Option/ModifyPantheons".Localize(), | ||
new string[] { | ||
Lang.Get("MOH_OFF", "MainMenu"), | ||
Lang.Get("MOH_ON", "MainMenu") | ||
}, | ||
"", | ||
i => GlobalSettings.modifyPantheons = i != 0, | ||
() => GlobalSettings.modifyPantheons ? 1 : 0 | ||
), | ||
new( | ||
"Option/UnfixBugs".Localize(), | ||
new string[] { | ||
Lang.Get("MOH_OFF", "MainMenu"), | ||
Lang.Get("MOH_ON", "MainMenu") | ||
}, | ||
"", | ||
i => GlobalSettings.unfixBugs = i != 0, | ||
() => GlobalSettings.unfixBugs ? 1 : 0 | ||
) | ||
}; | ||
} |
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,222 @@ | ||
using System.IO; | ||
|
||
using HutongGames.PlayMaker.Actions; | ||
|
||
namespace TribeOfBattle; | ||
|
||
public sealed partial class TribeOfBattle { | ||
private static GameObject? mantisPreload = null; | ||
|
||
private static GameObject? traitorPrefab = null; | ||
private static GameObject? traitorInstance = null; | ||
|
||
private static bool didGlobalChange = false; | ||
|
||
private static GameObject? grassPrefab = null; | ||
|
||
private static tk2dSprite? traitorSprite = null; | ||
private static Texture2D? traitorTexOrig = null; | ||
private static readonly Lazy<Texture2D> traitorTex = new(() => { | ||
Stream stream = typeof(TribeOfBattle).Assembly | ||
.GetManifestResourceStream("TribeOfBattle.Resources.TraitorLord.png"); | ||
MemoryStream ms = new((int) stream.Length); | ||
|
||
stream.CopyTo(ms); | ||
stream.Close(); | ||
|
||
byte[] bytes = ms.ToArray(); | ||
ms.Close(); | ||
|
||
Texture2D texture2D = new(2, 2); | ||
texture2D.LoadImage(bytes, true); | ||
|
||
return texture2D; | ||
}); | ||
|
||
public override List<(string, string)> GetPreloadNames() => new() { | ||
("GG_Mantis_Lords_V", "Mantis Battle/Battle Main/Mantis Lord"), | ||
("GG_Traitor_Lord", "Battle Scene/Wave 3/Mantis Traitor Lord") | ||
}; | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static void SavePreloads(Dictionary<string, Dictionary<string, GameObject>> preloads) { | ||
if (preloads == null) { | ||
return; | ||
} | ||
|
||
mantisPreload = preloads["GG_Mantis_Lords_V"]["Mantis Battle/Battle Main/Mantis Lord"]; | ||
traitorPrefab = CreateTraitorPrefab(preloads["GG_Traitor_Lord"]["Battle Scene/Wave 3/Mantis Traitor Lord"]); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static GameObject CreateTraitorPrefab(GameObject preload) { | ||
var prefab = GameObject.Instantiate(preload); | ||
GameObject.DontDestroyOnLoad(prefab); | ||
|
||
grassPrefab = prefab.GetComponent<PersonalObjectPool>().startupPool | ||
.Filter(pool => pool.prefab.name == "mega_mantis_tall_slash") | ||
.Single().prefab.Child("Grass")!; | ||
|
||
traitorSprite = prefab.GetComponent<tk2dSprite>(); | ||
traitorTexOrig = traitorSprite.CurrentSprite.material.mainTexture as Texture2D; | ||
|
||
prefab.name = "TOB Traitor Lord"; | ||
prefab.transform.SetPosition2D(35f, 22f); | ||
UObject.DestroyImmediate(prefab.Child("Pt Mist")!); | ||
UObject.DestroyImmediate(prefab.GetComponent<EnemyDeathEffects>()); | ||
UObject.DestroyImmediate(prefab.GetComponent<InfectedEnemyEffects>()); | ||
prefab.AddComponent<DontClinkGates>(); | ||
prefab.AddComponent<NonBouncer>().active = false; | ||
|
||
#region Dream Convo | ||
|
||
EnemyDreamnailReaction dreamConvo = prefab.GetComponent<EnemyDreamnailReaction>(); | ||
EnemyDreamnailReaction mantisDreamConvo = mantisPreload!.GetComponent<EnemyDreamnailReaction>(); | ||
|
||
ReflectionHelper.SetField( | ||
dreamConvo, | ||
"convoAmount", | ||
ReflectionHelper.GetField<EnemyDreamnailReaction, int>(mantisDreamConvo, "convoAmount") | ||
); | ||
dreamConvo.SetConvoTitle( | ||
ReflectionHelper.GetField<EnemyDreamnailReaction, string>(mantisDreamConvo, "convoTitle") | ||
); | ||
|
||
#endregion | ||
|
||
#region Constrain Position | ||
|
||
ConstrainPosition constraint = prefab.AddComponent<ConstrainPosition>(); | ||
constraint.constrainX = true; | ||
constraint.xMin = 24.4f; | ||
constraint.xMax = 36.7f; | ||
|
||
#endregion | ||
|
||
#region Hit Effect | ||
|
||
EnemyHitEffectsUninfected hitEffect = prefab.AddComponent<EnemyHitEffectsUninfected>(); | ||
ReflectionHelper.SetField(prefab.GetComponent<HealthManager>(), "hitEffectReceiver", hitEffect as IHitEffectReciever); | ||
|
||
EnemyHitEffectsUninfected mantisEffect = mantisPreload!.GetComponent<EnemyHitEffectsUninfected>(); | ||
hitEffect.effectOrigin = mantisEffect.effectOrigin; | ||
hitEffect.audioPlayerPrefab = mantisEffect.audioPlayerPrefab; | ||
hitEffect.enemyDamage = mantisEffect.enemyDamage; | ||
hitEffect.uninfectedHitPt = mantisEffect.uninfectedHitPt; | ||
hitEffect.slashEffectGhost1 = mantisEffect.slashEffectGhost1; | ||
hitEffect.slashEffectGhost2 = mantisEffect.slashEffectGhost2; | ||
hitEffect.uninfectedHitPt = mantisEffect.uninfectedHitPt; | ||
|
||
#endregion | ||
|
||
return prefab; | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static void InstantiateTraitor(GameObject parent) { | ||
traitorInstance = GameObject.Instantiate(traitorPrefab)!; | ||
traitorInstance!.transform.parent = parent.transform; | ||
|
||
HealthManager hm = traitorInstance.GetComponent<HealthManager>(); | ||
DamageHero dh = traitorInstance.GetComponent<DamageHero>(); | ||
NonBouncer nb = traitorInstance.GetComponent<NonBouncer>(); | ||
PlayMakerFSM fsm = traitorInstance.LocateMyFSM("Mantis"); | ||
|
||
#region FSM Changes | ||
|
||
#region Intro | ||
|
||
// Sync with Mantis Lords roar | ||
fsm.RemoveAction("Cloth?", 1); | ||
fsm.RemoveAction("Cloth?", 0); | ||
fsm.GetAction<Wait>("Emerge Dust", 1).time = 1.6f; | ||
fsm.RemoveAction("Emerge Dust", 2); | ||
fsm.RemoveTransition("Intro Land", FsmEvent.Finished.Name); | ||
fsm.AddTransition("Intro Land", "SUBS ROAR 2", "Roar"); | ||
fsm.RemoveTransition("Roar", FsmEvent.Finished.Name); | ||
fsm.AddTransition("Roar", "MLORD START SUB", "Roar End"); | ||
fsm.AddCustomAction("Roar End", () => { | ||
hm.IsInvincible = false; | ||
dh.damageDealt = 1; | ||
}); | ||
|
||
// Remove roar & title | ||
fsm.RemoveAction("Roar", 9); | ||
fsm.RemoveAction("Roar", 8); | ||
fsm.RemoveAction("Roar", 7); | ||
fsm.RemoveAction("Roar", 6); | ||
|
||
#endregion | ||
|
||
#region Death | ||
|
||
FsmState stateDefeated = fsm.AddState("Defeated"); | ||
fsm.ChangeTransition("Idle", "DEATH SCENE", stateDefeated.Name); | ||
fsm.AddAction(stateDefeated.Name, fsm.GetAction("Walk", 2)); | ||
fsm.AddAction(stateDefeated.Name, fsm.GetAction("Idle", 1)); | ||
fsm.AddCustomAction(stateDefeated.Name, () => { | ||
hm.IsInvincible = true; | ||
dh.damageDealt = 0; | ||
nb.active = true; | ||
traitorInstance.Child("Head Box")!.SetActive(false); | ||
}); | ||
|
||
FsmState stateBowAntic = fsm.AddState("Bow Antic"); | ||
fsm.AddTransition(stateDefeated.Name, "MANTIS DEFEAT", stateBowAntic.Name); | ||
fsm.AddAction(stateBowAntic.Name, new Wait() { time = 1.6f, finishEvent = FsmEvent.Finished }); | ||
|
||
FsmState stateBow = fsm.AddState("Bow"); | ||
fsm.AddTransition(stateBowAntic.Name, FsmEvent.Finished.Name, stateBow.Name); | ||
fsm.AddAction(stateBow.Name, fsm.GetAction("Roar Recover", 0)); | ||
|
||
#endregion | ||
|
||
#region Change attacks | ||
|
||
// Fix Y | ||
fsm.GetAction<FloatCompare>("Fall", 10).float2 = 9.6f; | ||
fsm.GetAction<SetPosition>("Intro Land", 0).y = 9.6f; | ||
fsm.GetAction<FloatCompare>("DSlash", 13).float2 = 9.6f; | ||
fsm.GetAction<SetPosition>("Land", 0).y = 9.6f; | ||
|
||
// No feint | ||
fsm.ChangeTransition("Attack Choice", "SLASH", "Attack Antic"); | ||
|
||
// No walk | ||
fsm.RemoveAction("Idle", 5); | ||
|
||
// No back feint | ||
fsm.RemoveAction("Too Close?", 1); | ||
fsm.RemoveAction("Too Close?", 0); | ||
|
||
// Slam ignore HP | ||
fsm.RemoveAction("Slam?", 2); | ||
|
||
#endregion | ||
|
||
#endregion | ||
|
||
if (!GlobalSettings.unfixBugs) { | ||
// roar lock | ||
fsm.RemoveAction("Roar", 3); | ||
fsm.RemoveAction("Roar", 2); | ||
|
||
// Not interactable until roar finish | ||
hm.IsInvincible = true; | ||
dh.damageDealt = 0; | ||
nb.active = true; | ||
fsm.RemoveAction("Fall", 6); | ||
fsm.AddCustomAction("Roar End", () => nb.active = false); | ||
|
||
// Fix slamming after death | ||
fsm.InsertAction("Slam?", new BoolTest() { | ||
boolVariable = fsm.FsmVariables.FindFsmBool("Zero HP"), | ||
isTrue = FsmEvent.Finished | ||
}, 0); | ||
fsm.InsertAction("Repeat?", new BoolTest() { | ||
boolVariable = fsm.FsmVariables.FindFsmBool("Zero HP"), | ||
isTrue = FsmEvent.Finished | ||
}, 0); | ||
} | ||
} | ||
} |
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,9 @@ | ||
{ | ||
"Name": "Tribe of Battle", | ||
"Desc": "Reunited gods of pride", | ||
"Title/Super": "", | ||
"Title/Main": "Tribe", | ||
"Title/Sub": "Of Battle", | ||
"Option/ModifyPantheons": "Modify Pantheons", | ||
"Option/UnfixBugs": "Unfix Bugs" | ||
} |
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,9 @@ | ||
{ | ||
"Name": "战斗部落", | ||
"Desc": "重聚的骄傲之神", | ||
"Title/Super": "", | ||
"Title/Main": "战斗部落", | ||
"Title/Sub": "", | ||
"Option/ModifyPantheons": "更改门内", | ||
"Option/UnfixBugs": "还原 Bug" | ||
} |
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,53 @@ | ||
using HealthShare; | ||
|
||
namespace TribeOfBattle; | ||
|
||
public sealed partial class TribeOfBattle { | ||
private static void EditScene(Scene _, Scene next) { | ||
if (Instance == null) { | ||
goto Inactive; | ||
} | ||
|
||
if (next.name != "GG_Mantis_Lords_V") { | ||
goto Inactive; | ||
} | ||
|
||
if (BossSequenceController.IsInSequence && !GlobalSettings.modifyPantheons) { | ||
goto Inactive; | ||
} | ||
|
||
if (!didGlobalChange) { | ||
traitorSprite!.CurrentSprite.material.mainTexture = traitorTex.Value; | ||
grassPrefab!.SetActive(false); | ||
didGlobalChange = true; | ||
} | ||
|
||
GameObject battle = next.GetRootGameObjects().First(go => go.name == "Mantis Battle"); | ||
|
||
InstantiateTraitor(battle); | ||
|
||
battle.Child("Mantis Lord Throne 2") | ||
.LocateMyFSM("Mantis Throne Main") | ||
.InsertCustomAction("I Stand", () => { | ||
traitorInstance!.SetActive(true); | ||
|
||
new[] { 1, 2, 3 } | ||
.Map(i => "Battle Sub/Mantis Lord S" + i) | ||
.Map(path => battle.Child(path)!) | ||
.Append(traitorInstance!) | ||
.ShareHealth(name: "Tribe Of Battle").HP = | ||
BossSceneController.Instance.BossLevel == 0 ? 3550 : 4750; | ||
}, 4); | ||
|
||
return; | ||
|
||
Inactive: | ||
if (didGlobalChange) { | ||
traitorSprite!.CurrentSprite.material.mainTexture = traitorTexOrig; | ||
grassPrefab!.SetActive(true); | ||
didGlobalChange = false; | ||
} | ||
|
||
return; | ||
} | ||
} |
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,12 @@ | ||
namespace TribeOfBattle; | ||
|
||
public sealed partial class TribeOfBattle : IGlobalSettings<GlobalSettings> { | ||
public static GlobalSettings GlobalSettings { get; private set; } = new(); | ||
public void OnLoadGlobal(GlobalSettings s) => GlobalSettings = s; | ||
public GlobalSettings OnSaveGlobal() => GlobalSettings; | ||
} | ||
|
||
public sealed class GlobalSettings { | ||
public bool modifyPantheons = false; | ||
public bool unfixBugs = false; | ||
} |
Oops, something went wrong.