diff --git a/Common/Rewards/CardTransformReward.cs b/Common/Rewards/CardTransformReward.cs new file mode 100644 index 00000000..15bdf1f5 --- /dev/null +++ b/Common/Rewards/CardTransformReward.cs @@ -0,0 +1,106 @@ +using BaseLib.Abstracts; +using BaseLib.Extensions; +using BaseLib.Patches.Content; +using MegaCrit.Sts2.Core.Entities.Players; +using MegaCrit.Sts2.Core.Localization; +using MegaCrit.Sts2.Core.Models.Cards; +using MegaCrit.Sts2.Core.Rewards; +using MegaCrit.Sts2.Core.Runs; +using MegaCrit.Sts2.Core.Saves.Runs; + +namespace BaseLib.Common.Rewards; + +/// +/// A reward class similar to the card removal one created by , +/// only for transforming instead of removing cards +/// +/// +/// In a relic or power's AfterCombatEnd override +/// +/// room.AddExtraReward(Owner.Player, new CardTransformReward(Owner.Player) {Amount = Amount, Upgrade = true}); +/// +public sealed class CardTransformReward(Player player) : CustomReward(player) +{ + /// + /// A new defined with the attribute + /// + [CustomEnum] public static RewardType CardTransform; + /// + /// Reference to the defined earlier + /// + protected override RewardType RewardType => CardTransform; + + /// + /// Whether the card rewards should be upgraded or not + /// + public required bool Upgrade; + /// + /// How many cards can be selected in this reward screen + /// + public required int Amount; + + /// + /// The description to show in the reward screen, + /// switches based on whether the reward will upgrade the transformed cards + /// + public override LocString Description + { + get + { + LocString locString = new LocString("gameplay_ui", "COMBAT_REWARD_CARD_TRANSFORM"); + locString.Add("cards", Amount); + locString.Add("Upgrade", Upgrade); + return locString; + } + } + /// + public override bool IsPopulated => true; + public static string RewardIcon => ImageHelperExtensions.GetModImagePath("ui/reward_screen/reward_icon_card_transform.png"); + /// + protected override string IconPath => RewardIcon; + + + /// + /// Serializing the reward, saving whether to upgrade and how many cards to transform in the vanilla fields + /// + public override SerializableReward ToSerializable() + { + return new SerializableReward() + { + RewardType = CardTransform, + GoldAmount = Amount, + WasGoldStolenBack = Upgrade + }; + } + + /// + /// Recreates the reward from the saved + /// + /// The that was created and saved from + /// + /// The the reward belongs to + public CardTransformReward CreateFromSerializable(SerializableReward save, Player player) + { + return new CardTransformReward(player) { + // hijacking the gold amounts as a temp hack before worrying about extending the serialized values + Amount = save.GoldAmount, + Upgrade = save.WasGoldStolenBack + }; + } + + /// + public override SerializableCustomReward SerializeMethod => CreateFromSerializable; + + /// + public override void MarkContentAsSeen() { } + + /// + public override Task Populate() { return Task.CompletedTask; } + + /// + protected override async Task OnSelect() + { + BaseLibMain.Logger.Info("Obtained card transformation from reward"); + return await RunManager.Instance.RewardSynchronizer.DoLocalCardTransform(Amount, true); + } +} diff --git a/Common/Rewards/CardTransformRewardMessage.cs b/Common/Rewards/CardTransformRewardMessage.cs new file mode 100644 index 00000000..955e0487 --- /dev/null +++ b/Common/Rewards/CardTransformRewardMessage.cs @@ -0,0 +1,78 @@ +using BaseLib.Abstracts; +using BaseLib.Patches.Content; +using MegaCrit.Sts2.Core.Combat; +using MegaCrit.Sts2.Core.Entities.Players; +using MegaCrit.Sts2.Core.Helpers; +using MegaCrit.Sts2.Core.Logging; +using MegaCrit.Sts2.Core.Multiplayer.Game; +using MegaCrit.Sts2.Core.Multiplayer.Serialization; +using MegaCrit.Sts2.Core.Runs; + +namespace BaseLib.Common.Rewards; + +/// +/// Message for transforming a card from a new reward type +/// +public sealed class ZZ_CardTransformRewardMessage : CustomRewardMessage +{ + internal void HandleCardTransformedMessage(ZZ_CardTransformRewardMessage message, ulong senderId) + { + BaseLibMain.Logger.Debug($"Handling message {message}"); + var rs = RunManager.Instance.RewardSynchronizer; + if (CombatManager.Instance.IsInProgress) + { + rs.BufferCustomRewardMessage(message, senderId); + BaseLibMain.Logger.Debug($"Buffered card transform message for {rs.PlayerCollection()?.GetPlayer(senderId)}"); + return; + } + + Player? player = rs.PlayerCollection()?.GetPlayer(senderId); + if (player == rs.LocalPlayerRef()) + { + throw new InvalidOperationException("CardTransformRewardMessage should not be sent to the player transforming the card"); + } + TaskHelper.RunSafely(rs.DoCardTransform(player, message.Amount, message.Upgrade)); + } + + /// + public override void Dispose(RunLocationTargetedMessageBuffer messageBuffer) + { + BaseLibMain.Logger.Debug($"Unregistering handler for {GetType()}"); + messageBuffer.UnregisterMessageHandler(HandleCardTransformedMessage); + } + + /// + public override void Initialize(RunLocationTargetedMessageBuffer messageBuffer) + { + BaseLibMain.Logger.Debug($"Registering handler for {GetType()}"); + messageBuffer.RegisterMessageHandler(HandleCardTransformedMessage); + } + + /// + /// Whether to upgrade the card as well as transforming + /// + public required bool Upgrade; + /// + /// The amount of cards to select from + /// + public required int Amount; + + /// + public override LogLevel LogLevel => LogLevel.Debug; + + /// + public override void Deserialize(PacketReader reader) + { + Location = reader.Read(); + Amount = reader.ReadInt(); + Upgrade = reader.ReadBool(); + } + + /// + public override void Serialize(PacketWriter writer) + { + writer.Write(Location); + writer.WriteInt(Amount); + writer.WriteBool(Upgrade); + } +}