-
Notifications
You must be signed in to change notification settings - Fork 24
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
9 changed files
with
338 additions
and
0 deletions.
There are no files selected for viewing
44 changes: 44 additions & 0 deletions
44
MultiplayerMod/Game/UI/Screens/Events/ImmigrantScreenEvents.cs
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,44 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Threading.Tasks; | ||
using HarmonyLib; | ||
using MultiplayerMod.Core.Dependency; | ||
using MultiplayerMod.Core.Patch; | ||
using MultiplayerMod.Core.Scheduling; | ||
|
||
namespace MultiplayerMod.Game.UI.Screens.Events; | ||
|
||
[HarmonyPatch(typeof(ImmigrantScreen))] | ||
[SuppressMessage("ReSharper", "UnusedMember.Local")] | ||
public static class ImmigrantScreenEvents { | ||
public static event Action<List<ITelepadDeliverable>> ImmigrationInitialized; | ||
public static event System.Action ImmigrationRejected; | ||
public static event Action<ITelepadDeliverable> ImmigrationProceed; | ||
|
||
[HarmonyPostfix] | ||
[HarmonyPatch(nameof(ImmigrantScreen.Initialize))] | ||
private static void Initialize(ImmigrantScreen __instance) => PatchControl.RunIfEnabled( | ||
() => new TaskFactory(Container.Get<UnityTaskScheduler>()).StartNew( | ||
async () => { | ||
if (ImmigrantScreenPatch.Deliverables != null) return; | ||
|
||
var readyDeliverables = await ImmigrantScreenPatch.WaitForAllDeliverablesReady(__instance); | ||
if (readyDeliverables != null) { | ||
ImmigrationInitialized?.Invoke(readyDeliverables); | ||
ImmigrantScreenPatch.Deliverables = readyDeliverables; | ||
} | ||
} | ||
) | ||
); | ||
|
||
[HarmonyPostfix] | ||
[HarmonyPatch(nameof(ImmigrantScreen.OnRejectionConfirmed))] | ||
private static void OnRejectionConfirmed() => PatchControl.RunIfEnabled(() => ImmigrationRejected?.Invoke()); | ||
|
||
[HarmonyPrefix] | ||
[HarmonyPatch("OnProceed")] | ||
private static void OnProceed(ImmigrantScreen __instance) => | ||
PatchControl.RunIfEnabled(() => ImmigrationProceed?.Invoke(__instance.selectedDeliverables[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,120 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using HarmonyLib; | ||
using MultiplayerMod.Core.Dependency; | ||
using MultiplayerMod.Core.Patch; | ||
using MultiplayerMod.Core.Scheduling; | ||
using UnityEngine; | ||
|
||
namespace MultiplayerMod.Game.UI.Screens; | ||
|
||
[HarmonyPatch(typeof(ImmigrantScreen))] | ||
public static class ImmigrantScreenPatch { | ||
|
||
private const int delayMS = 1; | ||
private const int maxWaitMS = 50; | ||
|
||
public static List<ITelepadDeliverable> Deliverables { get; set; } | ||
|
||
[HarmonyPostfix] | ||
[HarmonyPatch(nameof(ImmigrantScreen.Initialize))] | ||
private static void Initialize(ImmigrantScreen __instance) => PatchControl.RunIfEnabled( | ||
() => new TaskFactory(Container.Get<UnityTaskScheduler>()).StartNew( | ||
async () => { | ||
if (Deliverables == null) return; | ||
|
||
// Wait until default initialize is complete | ||
await WaitForAllDeliverablesReady(__instance); | ||
// Create correct containers. | ||
InitializeContainers(ImmigrantScreen.instance); | ||
// Wait until those containers are initialized with random data. | ||
await WaitForAllDeliverablesReady(__instance); | ||
|
||
SetDeliverablesData(__instance); | ||
} | ||
) | ||
); | ||
|
||
public static async Task<List<ITelepadDeliverable>> WaitForAllDeliverablesReady(ImmigrantScreen instance) { | ||
var currentDelay = 0; | ||
while (currentDelay < maxWaitMS) { | ||
var readyDeliverables = instance.containers?.Select( | ||
a => a switch { | ||
CharacterContainer container => (ITelepadDeliverable) container.stats, | ||
CarePackageContainer packageContainer => packageContainer.carePackageInstanceData, | ||
_ => null | ||
} | ||
).Where(a => a != null).ToList(); | ||
if (readyDeliverables != null && readyDeliverables.Count == instance.containers.Count) | ||
return readyDeliverables; | ||
|
||
await Task.Delay(delayMS); | ||
currentDelay += delayMS; | ||
} | ||
return null; | ||
} | ||
|
||
private static void InitializeContainers(CharacterSelectionController screen) { | ||
screen.OnReplacedEvent = null; | ||
screen.containers?.ForEach(cc => Object.Destroy(cc.GetGameObject())); | ||
screen.containers?.Clear(); | ||
screen.containers = new List<ITelepadDeliverableContainer>(); | ||
|
||
screen.numberOfCarePackageOptions = 0; | ||
screen.numberOfDuplicantOptions = 0; | ||
screen.selectedDeliverables = new List<ITelepadDeliverable>(); | ||
|
||
foreach (var deliverable in Deliverables) { | ||
if (deliverable is MinionStartingStats) { | ||
var characterContainer = Util.KInstantiateUI<CharacterContainer>( | ||
screen.containerPrefab.gameObject, | ||
screen.containerParent | ||
); | ||
screen.containers.Add(characterContainer); | ||
characterContainer.SetController(screen); | ||
characterContainer.SetReshufflingState(false); | ||
screen.numberOfDuplicantOptions++; | ||
} else { | ||
var packageContainer = Util.KInstantiateUI<CarePackageContainer>( | ||
screen.carePackageContainerPrefab.gameObject, | ||
screen.containerParent | ||
); | ||
screen.containers.Add(packageContainer); | ||
packageContainer.SetController(screen); | ||
screen.numberOfCarePackageOptions++; | ||
} | ||
} | ||
} | ||
|
||
private static void SetDeliverablesData(CharacterSelectionController screen) { | ||
var minionStats = Deliverables.OfType<MinionStartingStats>().ToArray(); | ||
var packageData = | ||
Deliverables.OfType<CarePackageContainer.CarePackageInstanceData>().ToArray(); | ||
for (var i = 0; i < minionStats.Length; i++) { | ||
SetCharacterStats(screen.containers.OfType<CharacterContainer>().ToArray()[i], minionStats[i]); | ||
} | ||
for (var i = 0; i < packageData.Length; i++) { | ||
SetPackageData(screen.containers.OfType<CarePackageContainer>().ToArray()[i], packageData[i]); | ||
} | ||
} | ||
|
||
private static void SetCharacterStats(CharacterContainer characterContainer, MinionStartingStats stats) { | ||
// Based on CharacterContainer.GenerateCharacter | ||
characterContainer.stats = stats; | ||
characterContainer.SetAnimator(); | ||
characterContainer.SetInfoText(); | ||
} | ||
|
||
private static void SetPackageData( | ||
CarePackageContainer packageContainer, | ||
CarePackageContainer.CarePackageInstanceData data | ||
) { | ||
// Based on CharacterContainer.GenerateCharacter | ||
packageContainer.carePackageInstanceData = data; | ||
packageContainer.info = data.info; | ||
packageContainer.ClearEntryIcons(); | ||
packageContainer.SetAnimator(); | ||
packageContainer.SetInfoText(); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
MultiplayerMod/Multiplayer/Commands/Screens/Immigration/InitializeImmigration.cs
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,19 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using MultiplayerMod.Game.UI.Screens; | ||
|
||
namespace MultiplayerMod.Multiplayer.Commands.Screens.Immigration; | ||
|
||
[Serializable] | ||
public class InitializeImmigration : IMultiplayerCommand { | ||
|
||
private List<ITelepadDeliverable> deliverables; | ||
|
||
public InitializeImmigration(List<ITelepadDeliverable> deliverables) { | ||
this.deliverables = deliverables; | ||
} | ||
|
||
public void Execute() { | ||
ImmigrantScreenPatch.Deliverables = deliverables; | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
MultiplayerMod/Multiplayer/Commands/Screens/Immigration/ProceedImmigration.cs
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,24 @@ | ||
using System; | ||
using MultiplayerMod.Game.UI.Screens; | ||
|
||
namespace MultiplayerMod.Multiplayer.Commands.Screens.Immigration; | ||
|
||
[Serializable] | ||
public class ProceedImmigration : IMultiplayerCommand { | ||
private readonly ITelepadDeliverable deliverable; | ||
|
||
public ProceedImmigration(ITelepadDeliverable deliverable) { | ||
this.deliverable = deliverable; | ||
} | ||
|
||
public void Execute() { | ||
var immigrantScreen = ImmigrantScreen.instance; | ||
if (immigrantScreen == null) return; | ||
|
||
immigrantScreen.RemoveLast(); | ||
immigrantScreen.AddDeliverable(deliverable); | ||
immigrantScreen.proceedButton.SignalClick(KKeyCode.Mouse0); | ||
|
||
ImmigrantScreenPatch.Deliverables = null; | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
MultiplayerMod/Multiplayer/Commands/Screens/Immigration/RejectImmigration.cs
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,16 @@ | ||
using System; | ||
using MultiplayerMod.Game.UI.Screens; | ||
|
||
namespace MultiplayerMod.Multiplayer.Commands.Screens.Immigration; | ||
|
||
[Serializable] | ||
public class RejectImmigration : IMultiplayerCommand { | ||
|
||
public void Execute() { | ||
if (ImmigrantScreen.instance == null) return; | ||
|
||
ImmigrantScreen.instance.OnRejectionConfirmed(); | ||
|
||
ImmigrantScreenPatch.Deliverables = null; | ||
} | ||
} |
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
34 changes: 34 additions & 0 deletions
34
...playerMod/Platform/Steam/Network/Messaging/Surrogates/CarePackageInstanceDataSurrogate.cs
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,34 @@ | ||
using System; | ||
using System.Runtime.Serialization; | ||
|
||
namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates; | ||
|
||
public class CarePackageInstanceDataSurrogate : ISerializationSurrogate, ISurrogateType { | ||
|
||
public Type Type => typeof(CarePackageContainer.CarePackageInstanceData); | ||
|
||
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) { | ||
var node = (CarePackageContainer.CarePackageInstanceData) obj; | ||
info.AddValue("facadeID", node.facadeID); | ||
info.AddValue("info.id", node.info.id); | ||
info.AddValue("info.quantity", node.info.quantity); | ||
info.AddValue("info.facadeID", node.info.facadeID); | ||
} | ||
|
||
public object SetObjectData( | ||
object obj, | ||
SerializationInfo info, | ||
StreamingContext context, | ||
ISurrogateSelector selector | ||
) { | ||
var node = (CarePackageContainer.CarePackageInstanceData) obj; | ||
node.info = new CarePackageInfo( | ||
info.GetString("info.id"), | ||
(float) info.GetDouble("info.quantity"), | ||
null, | ||
info.GetString("info.facadeID") | ||
); | ||
node.facadeID = info.GetString("facadeID"); | ||
return node; | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/MinionStartingStatsSurrogate.cs
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,73 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Runtime.Serialization; | ||
|
||
namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates; | ||
|
||
public class MinionStartingStatsSurrogate : ISerializationSurrogate, ISurrogateType { | ||
|
||
public Type Type => typeof(MinionStartingStats); | ||
|
||
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) { | ||
var node = (MinionStartingStats) obj; | ||
info.AddValue("Name", node.Name); | ||
info.AddValue("NameStringKey", node.NameStringKey); | ||
info.AddValue("GenderStringKey", node.GenderStringKey); | ||
info.AddValue("stressTrait", node.stressTrait?.Id); | ||
info.AddValue("joyTrait", node.joyTrait?.Id); | ||
info.AddValue("congenitaltrait", node.congenitaltrait?.Id); | ||
info.AddValue("stickerType", node.stickerType); | ||
info.AddValue("voiceIdx", node.voiceIdx); | ||
info.AddValue("personality", node.personality?.Id); | ||
info.AddValue("Traits", node.Traits.Select(a => a?.Id).ToArray()); | ||
info.AddValue("StartingLevels.Keys", node.StartingLevels.Keys.ToArray()); | ||
info.AddValue("StartingLevels.Values", node.StartingLevels.Values.ToArray()); | ||
info.AddValue("skillAptitudes.Keys", node.skillAptitudes.Keys.Select(a => a.Id).ToArray()); | ||
info.AddValue("skillAptitudes.Values", node.skillAptitudes.Values.ToArray()); | ||
} | ||
|
||
public object SetObjectData( | ||
object obj, | ||
SerializationInfo info, | ||
StreamingContext context, | ||
ISurrogateSelector selector | ||
) { | ||
var node = (MinionStartingStats) obj; | ||
node.Name = info.GetString("Name"); | ||
node.NameStringKey = info.GetString("NameStringKey"); | ||
node.GenderStringKey = info.GetString("GenderStringKey"); | ||
node.stressTrait = Db.Get().traits.Get(info.GetString("stressTrait")); | ||
node.joyTrait = Db.Get().traits.Get(info.GetString("joyTrait")); | ||
node.congenitaltrait = Db.Get().traits.TryGet(info.GetString("congenitaltrait")); | ||
node.stickerType = info.GetString("stickerType"); | ||
node.voiceIdx = info.GetInt32("voiceIdx"); | ||
node.Traits = ((string[]) info.GetValue("Traits", typeof(string[]))).Select(id => Db.Get().traits.Get(id)) | ||
.ToList(); | ||
node.personality = Db.Get().Personalities.Get(info.GetString("personality")); | ||
node.StartingLevels = | ||
ToDictionary( | ||
(string[]) info.GetValue("StartingLevels.Keys", typeof(string[])), | ||
(int[]) info.GetValue("StartingLevels.Values", typeof(int[])) | ||
); | ||
node.skillAptitudes = | ||
ToDictionary( | ||
((string[]) info.GetValue("skillAptitudes.Keys", typeof(string[]))) | ||
.Select(key => Db.Get().SkillGroups.Get(key)).ToArray(), | ||
(float[]) info.GetValue("skillAptitudes.Values", typeof(float[])) | ||
); | ||
node.IsValid = true; | ||
return node; | ||
} | ||
|
||
private static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>( | ||
IReadOnlyList<TKey> keys, | ||
IReadOnlyList<TValue> values | ||
) { | ||
var result = new Dictionary<TKey, TValue>(); | ||
for (var i = 0; i < keys.Count; i++) { | ||
result[keys[i]] = values[i]; | ||
} | ||
return result; | ||
} | ||
} |
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