diff --git a/Assets/ExportedMods/Basic.umod b/Assets/ExportedMods/Basic.umod index 67f2697f..3a5825a7 100644 --- a/Assets/ExportedMods/Basic.umod +++ b/Assets/ExportedMods/Basic.umod @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:139564ff86e1db541019256f8e294a1b3de8b04fb00bd15892a947c167fcf262 -size 483213816 +oid sha256:e473e69bf6fb29bb5c91294a25b101432eb4c98227327a633b5c9ee355649750 +size 483294125 diff --git a/Assets/Mods/Basic/Basic_Manifest.asset b/Assets/Mods/Basic/Basic_Manifest.asset index 5dde15b9..a7b3b168 100644 --- a/Assets/Mods/Basic/Basic_Manifest.asset +++ b/Assets/Mods/Basic/Basic_Manifest.asset @@ -55,6 +55,7 @@ MonoBehaviour: - CardData_Basic_Cover - CardData_Basic_EchoOfHonor - CardData_Basic_GuardianAura + - CardData_Basic_IronWall - CardData_Basic_KightDefense - CardData_Basic_KnightStrike - CardData_Basic_OathOfCourage diff --git a/Assets/Mods/Basic/Cards/Data/PlayerHeros/Knight/CardData_Basic_IronWall.asset b/Assets/Mods/Basic/Cards/Data/PlayerHeros/Knight/CardData_Basic_IronWall.asset new file mode 100644 index 00000000..e4e14389 --- /dev/null +++ b/Assets/Mods/Basic/Cards/Data/PlayerHeros/Knight/CardData_Basic_IronWall.asset @@ -0,0 +1,61 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9a4129cdd7011ca46b83d8c17d9f3623, type: 3} + m_Name: CardData_Basic_IronWall + m_EditorClassIdentifier: + modName: Basic + className: IronWall + displayName: Card_Basic_IronWall_DisplayName + cardRarity: 20 + cardType: 20 + keywords: + - TargetSelf + cardSprite: {fileID: 21300000, guid: 423e0c7f7f5e3904f8b117dcb99dc195, type: 3} + cardLayoutTags: [] + functionText: Card_Basic_IronWall_FunctionText + cardDescription: + baseWeight: 1 + variableAttributes: + dictionaryList: + - Key: StaminaCost + Value: 3 + index: 0 + isKeyDuplicated: 0 + - Key: ManaCost + Value: 0 + index: 1 + isKeyDuplicated: 0 + - Key: TargetCount + Value: 0 + index: 2 + isKeyDuplicated: 0 + - Key: BuffCount_Withstand + Value: 10 + index: 3 + isKeyDuplicated: 0 + dividerPosProp: 0.5 + originalAttributes: + dictionaryList: [] + dividerPosProp: 0.5 + runtimeCurrentAttributes: + dictionaryList: [] + dividerPosProp: 0.5 + upgradeNode: + sourceCard: {fileID: 0} + isTerminalNode: 0 + isInfiniteUpgrade: 0 + maxUpgradeLevel: 0 + upgradeCards: [] + customDescriptions: [] + prefabRefs: [] + derivativeCardDataRefs: [] + derivativeCharacterDataRefs: [] diff --git a/Assets/Mods/Basic/Cards/Data/PlayerHeros/Knight/CardData_Basic_IronWall.asset.meta b/Assets/Mods/Basic/Cards/Data/PlayerHeros/Knight/CardData_Basic_IronWall.asset.meta new file mode 100644 index 00000000..f3e886be --- /dev/null +++ b/Assets/Mods/Basic/Cards/Data/PlayerHeros/Knight/CardData_Basic_IronWall.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf83d1221ea596749a05a285fee6c313 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Mods/Basic/Cards/Scripts/General/Tactic.cs b/Assets/Mods/Basic/Cards/Scripts/General/Tactic.cs index 3ddab0e2..6962dcf3 100644 --- a/Assets/Mods/Basic/Cards/Scripts/General/Tactic.cs +++ b/Assets/Mods/Basic/Cards/Scripts/General/Tactic.cs @@ -30,7 +30,7 @@ namespace Continentis.Mods.Basic.Cards private void SelectEffect(CardInstance card) { - user.deckSubmodule.DiscardCard(card); + CommandQueueManager.Instance.AddCommand(user.deckSubmodule.DiscardCard(card), new CommandContext()); } } } \ No newline at end of file diff --git a/Assets/Mods/Basic/Cards/Scripts/Knight/IronWall.cs b/Assets/Mods/Basic/Cards/Scripts/Knight/IronWall.cs index e8f7bbf8..cefaf10b 100644 --- a/Assets/Mods/Basic/Cards/Scripts/Knight/IronWall.cs +++ b/Assets/Mods/Basic/Cards/Scripts/Knight/IronWall.cs @@ -1,16 +1,25 @@ +using System.Collections.Generic; +using Continentis.MainGame.Card; +using Continentis.MainGame.Character; +using Continentis.MainGame.Commands; +using Continentis.Mods.Basic.Buffs; +using SLSFramework.General; using UnityEngine; -public class IronWall : MonoBehaviour +namespace Continentis.Mods.Basic.Cards { - // Start is called once before the first execution of Update after the MonoBehaviour is created - void Start() + public class IronWall : CardLogicBase { - - } + protected override CommandBase PlayEffect(List targetList) + { + CommandGroup mainGroup = new CommandGroup(ExecutionMode.Sequential, + new Cmd_PlayAnimation(user.characterView, "Skill"), + new Cmd_Function(() => + { + CreateCharacterBuff(GetAttribute("BuffCount_Withstand")).Apply(user, user, this); + })); - // Update is called once per frame - void Update() - { - + return mainGroup; + } } -} +} \ No newline at end of file diff --git a/Assets/Mods/Basic/Cards/Scripts/Knight/UtmostStrike.cs b/Assets/Mods/Basic/Cards/Scripts/Knight/UtmostStrike.cs new file mode 100644 index 00000000..0f6d058b --- /dev/null +++ b/Assets/Mods/Basic/Cards/Scripts/Knight/UtmostStrike.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +public class UtmostStrike : MonoBehaviour +{ + // Start is called once before the first execution of Update after the MonoBehaviour is created + void Start() + { + + } + + // Update is called once per frame + void Update() + { + + } +} diff --git a/Assets/Mods/Basic/Cards/Scripts/Knight/UtmostStrike.cs.meta b/Assets/Mods/Basic/Cards/Scripts/Knight/UtmostStrike.cs.meta new file mode 100644 index 00000000..68ed85f9 --- /dev/null +++ b/Assets/Mods/Basic/Cards/Scripts/Knight/UtmostStrike.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9299438b564ba4a4aa59e98ea7d83c9d \ No newline at end of file diff --git a/Assets/Mods/Basic/Cards/Scripts/ObsoleteGeneral/CommonHolyWater.cs b/Assets/Mods/Basic/Cards/Scripts/ObsoleteGeneral/CommonHolyWater.cs index d2258d0f..e6100816 100644 --- a/Assets/Mods/Basic/Cards/Scripts/ObsoleteGeneral/CommonHolyWater.cs +++ b/Assets/Mods/Basic/Cards/Scripts/ObsoleteGeneral/CommonHolyWater.cs @@ -35,7 +35,7 @@ namespace Continentis.Mods.Basic.Cards public void SelectEffect(CardInstance card) { - card.deck.ExhaustCard(card); + CommandQueueManager.Instance.AddCommand(card.deck.ExhaustCard(card)); } } } \ No newline at end of file diff --git a/Assets/Mods/Basic/Cards/Scripts/ObsoleteGeneral/Oblivion.cs b/Assets/Mods/Basic/Cards/Scripts/ObsoleteGeneral/Oblivion.cs index 0e8f780f..da57c112 100644 --- a/Assets/Mods/Basic/Cards/Scripts/ObsoleteGeneral/Oblivion.cs +++ b/Assets/Mods/Basic/Cards/Scripts/ObsoleteGeneral/Oblivion.cs @@ -20,7 +20,7 @@ namespace Continentis.Mods.Basic.Cards { if (handPile.Filtered(CardFilter).TryGetRandom(out CardInstance randomCard)) { - user.deckSubmodule.ExhaustCard(randomCard); + CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(randomCard)); } } })); diff --git a/Assets/Mods/Basic/Characters/CombatBuffs/General/Withstand.cs b/Assets/Mods/Basic/Characters/CombatBuffs/General/Withstand.cs new file mode 100644 index 00000000..766100e5 --- /dev/null +++ b/Assets/Mods/Basic/Characters/CombatBuffs/General/Withstand.cs @@ -0,0 +1,41 @@ +using Continentis.MainGame; +using Continentis.MainGame.Character; +using SLSFramework.General; +using UnityEngine; + +namespace Continentis.Mods.Basic.Buffs +{ + public class Withstand : CharacterCombatBuffBase + { + public Withstand(int stack) + { + Initialize(BuffType.Positive, BuffDispelLevel.Strong); + + this.contentSubmodule = new ContentSubmodule(this) + .AddParameterGetter("Stack", () => unitedStackSubmodule.stackAmount.ToString()); + + this.iconSubmodule = new IconSubmodule(this); + + this.unitedStackSubmodule = new UnitedStackSubmodule(this, stack); + + this.eventSubmodule = new EventSubmodule(this); + this.eventSubmodule.onActionEnd.Add("Withstand", new EventUnit(() => + { + attachedCharacter.AddBlock(this.unitedStackSubmodule.stackAmount, false); + })); + } + + public override bool OnBuffApply(out CharacterCombatBuffBase existingBuff) + { + MainGameManager.Instance.basePrefabs.GenerateInfoText(contentSubmodule.displayName, attachedCharacter.characterView); + + if (FindExistingSameBuff(out existingBuff)) + { + existingBuff.unitedStackSubmodule.AddStack(this.unitedStackSubmodule.stackAmount); + return false; + } + + return true; + } + } +} \ No newline at end of file diff --git a/Assets/Mods/Basic/Characters/CombatBuffs/General/Withstand.cs.meta b/Assets/Mods/Basic/Characters/CombatBuffs/General/Withstand.cs.meta new file mode 100644 index 00000000..bce034e0 --- /dev/null +++ b/Assets/Mods/Basic/Characters/CombatBuffs/General/Withstand.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f3ab0c664289dcf47ac75d37cfa8b474 \ No newline at end of file diff --git a/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_Knight.asset b/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_Knight.asset index 844c6c16..739cab04 100644 --- a/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_Knight.asset +++ b/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_Knight.asset @@ -209,5 +209,6 @@ MonoBehaviour: - CardData_Basic_BattlefieldExperience - CardData_Basic_BodyAsShield - CardData_Basic_EchoOfHonor + - CardData_Basic_IronWall hudDataRefs: - HUDData_Basic_Default diff --git a/Assets/Mods/Basic/Sprites/Buffs/BuffIcon_Basic_Withstand.png b/Assets/Mods/Basic/Sprites/Buffs/BuffIcon_Basic_Withstand.png new file mode 100644 index 00000000..98bae37e Binary files /dev/null and b/Assets/Mods/Basic/Sprites/Buffs/BuffIcon_Basic_Withstand.png differ diff --git a/Assets/Mods/Basic/Sprites/Buffs/BuffIcon_Basic_Withstand.png.meta b/Assets/Mods/Basic/Sprites/Buffs/BuffIcon_Basic_Withstand.png.meta new file mode 100644 index 00000000..f87a480a --- /dev/null +++ b/Assets/Mods/Basic/Sprites/Buffs/BuffIcon_Basic_Withstand.png.meta @@ -0,0 +1,119 @@ +fileFormatVersion: 2 +guid: 1682919049c032045955857bd5349a22 +labels: +- UnityAI +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 1024 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 256 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Mods/Basic/Sprites/Cards/AI/00091-1_waifu2x_2x_3n_png.png b/Assets/Mods/Basic/Sprites/Cards/AI/CardSprite_Basic_IronWall.png similarity index 100% rename from Assets/Mods/Basic/Sprites/Cards/AI/00091-1_waifu2x_2x_3n_png.png rename to Assets/Mods/Basic/Sprites/Cards/AI/CardSprite_Basic_IronWall.png diff --git a/Assets/Mods/Basic/Sprites/Cards/AI/00091-1_waifu2x_2x_3n_png.png.meta b/Assets/Mods/Basic/Sprites/Cards/AI/CardSprite_Basic_IronWall.png.meta similarity index 100% rename from Assets/Mods/Basic/Sprites/Cards/AI/00091-1_waifu2x_2x_3n_png.png.meta rename to Assets/Mods/Basic/Sprites/Cards/AI/CardSprite_Basic_IronWall.png.meta diff --git a/Assets/Scenes/GameScene.unity b/Assets/Scenes/GameScene.unity index 2be32cec..25407d6f 100644 --- a/Assets/Scenes/GameScene.unity +++ b/Assets/Scenes/GameScene.unity @@ -3708,6 +3708,7 @@ RectTransform: - {fileID: 1584623665} - {fileID: 373312358} - {fileID: 1985189514} + - {fileID: 1843380378} - {fileID: 1951045391} - {fileID: 1570153706} - {fileID: 1250440202} @@ -3754,6 +3755,7 @@ MonoBehaviour: handPile: {fileID: 682317577} discardPile: {fileID: 373312359} exhaustPile: {fileID: 1985189515} + gravePile: {fileID: 1843380381} teamSwitchButton: {fileID: 368630476} handCardSelector: {fileID: 1250440204} customCardSelector: {fileID: 530081956} @@ -7350,6 +7352,96 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1808733956} m_CullTransparentMesh: 1 +--- !u!1 &1843380377 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1843380378} + - component: {fileID: 1843380381} + - component: {fileID: 1843380380} + - component: {fileID: 1843380379} + m_Layer: 5 + m_Name: GravePile + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1843380378 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1843380377} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 922348735} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: -100, y: 105} + m_SizeDelta: {x: 60, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1843380379 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1843380377} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: -530572372, guid: 132358e9bf26b60458b731bf001e31db, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1843380380 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1843380377} + m_CullTransparentMesh: 1 +--- !u!114 &1843380381 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1843380377} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f997d4e8f500b944eb3cbb0f5c4ac7c5, type: 3} + m_Name: + m_EditorClassIdentifier: GameAPI::Continentis.MainGame.UI.GravePile + rectTransform: {fileID: 1843380378} + cardViews: [] --- !u!1 &1869082636 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/MainGame/Card/CardMainFunctions.cs b/Assets/Scripts/MainGame/Card/CardMainFunctions.cs index dc3a95a8..cb02fd0b 100644 --- a/Assets/Scripts/MainGame/Card/CardMainFunctions.cs +++ b/Assets/Scripts/MainGame/Card/CardMainFunctions.cs @@ -232,15 +232,21 @@ namespace Continentis.MainGame.Card protected virtual void AfterPlayEffect(List targetList) { + if (contentSubmodule.cardType == CardType.Power) + { + CommandQueueManager.Instance.AddCommand(user.deckSubmodule.UsePowerCard(cardInstance)); + return; + } + if (user is PlayerHero playerHero) { if (HasKeyword("Exhaust")) { - playerHero.deckSubmodule.ExhaustCard(cardInstance); + CommandQueueManager.Instance.AddCommand(playerHero.deckSubmodule.ExhaustCard(cardInstance)); } else if(!HasKeyword("Reuse")) { - playerHero.deckSubmodule.DiscardCard(cardInstance); + CommandQueueManager.Instance.AddCommand(playerHero.deckSubmodule.DiscardCard(cardInstance)); CommandQueueManager.Instance.AddCommand(new Cmd_Function(() => { if (handCardView != null) @@ -254,7 +260,7 @@ namespace Continentis.MainGame.Card { if (HasKeyword("Exhaust")) { - npc.deckSubmodule.ExhaustCard(cardInstance); + CommandQueueManager.Instance.AddCommand(npc.deckSubmodule.ExhaustCard(cardInstance)); } } } diff --git a/Assets/Scripts/MainGame/Character/CharacterSubmodules/DeckSubmodule.cs b/Assets/Scripts/MainGame/Character/CharacterSubmodules/DeckSubmodule.cs index 04bedf5d..a3079784 100644 --- a/Assets/Scripts/MainGame/Character/CharacterSubmodules/DeckSubmodule.cs +++ b/Assets/Scripts/MainGame/Character/CharacterSubmodules/DeckSubmodule.cs @@ -22,6 +22,7 @@ namespace Continentis.MainGame.Character piles.Add("Draw", new List()); piles.Add("Discard", new List()); piles.Add("Exhaust", new List()); + piles.Add("Grave", new List()); piles.Add("Pool", new List()); piles.Add("Intention", new List()); } @@ -84,35 +85,98 @@ namespace Continentis.MainGame.Character { card.cardLogic.Play(targetList, owner); } - - public void DiscardCard(CardInstance card, float interval = 0.1f) - { - CommandQueueManager.Instance.AddCommand(new Cmd_DiscardCards(card.deck, new List { card }, interval)); - } - public void DiscardCards(List cards, float interval = 0.1f) + public CommandGroup DiscardCard(CardInstance card, float interval = 0.1f) + { + CommandContext context = new CommandContext(); + CommandGroup discardCardGroup = new CommandGroup(ExecutionMode.Sequential, context, + new Cmd_DiscardCards(card.deck, new List() { card }, interval), + new Cmd_Function(0, () => + { + //Debug.Log((context.sharedInfo["DrawnCards"] as List).Count); //TODO: 弃牌后的处理 + })); + + return discardCardGroup; + } + + public CommandGroup DiscardCards(List cards, float interval = 0.1f) { Dictionary> groupedCards = cards.GroupBy(card => card.deck) .ToDictionary(group => group.Key, group => group.ToList()); + CommandContext context = new CommandContext(); + CommandGroup discardCardGroup = new CommandGroup(ExecutionMode.Sequential, context); foreach (var kvp in groupedCards) { - CommandQueueManager.Instance.AddCommand(new Cmd_DiscardCards(kvp.Key, kvp.Value, interval)); + discardCardGroup.AddCommand(new Cmd_DiscardCards(kvp.Key, kvp.Value, interval)); } + discardCardGroup.AddCommand(new Cmd_Function(0, () => + { + //Debug.Log((context.sharedInfo["DrawnCards"] as List).Count); //TODO: 弃牌后的处理 + })); + + return discardCardGroup; } - public void ExhaustCard(CardInstance card, float interval = 0.1f) + public CommandGroup ExhaustCard(CardInstance card, float interval = 0.1f) { - CommandQueueManager.Instance.AddCommand(new Cmd_ExhaustCards(owner is PlayerHero, card.deck, new List { card }, interval)); + CommandContext context = new CommandContext(); + CommandGroup discardCardGroup = new CommandGroup(ExecutionMode.Sequential, context, + new Cmd_ExhaustCards(owner is PlayerHero, card.deck, new List() { card }, interval), + new Cmd_Function(0, () => + { + //Debug.Log((context.sharedInfo["DrawnCards"] as List).Count); //TODO: 消耗牌后的处理 + })); + + return discardCardGroup; } - public void ExhaustCards(List cards, float interval = 0.1f) + public CommandGroup ExhaustCards(List cards, float interval = 0.1f) { Dictionary> groupedCards = cards.GroupBy(card => card.deck) .ToDictionary(group => group.Key, group => group.ToList()); + CommandContext context = new CommandContext(); + CommandGroup discardCardGroup = new CommandGroup(ExecutionMode.Sequential, context); foreach (var kvp in groupedCards) { - CommandQueueManager.Instance.AddCommand(new Cmd_ExhaustCards(owner is PlayerHero, kvp.Key, kvp.Value, interval)); + discardCardGroup.AddCommand(new Cmd_ExhaustCards(owner is PlayerHero, kvp.Key, kvp.Value, interval)); } + discardCardGroup.AddCommand(new Cmd_Function(0, () => + { + //Debug.Log((context.sharedInfo["DrawnCards"] as List).Count); //TODO: 弃牌后的处理 + })); + + return discardCardGroup; + } + + public CommandGroup UsePowerCard(CardInstance card, float interval = 0.1f) + { + CommandContext context = new CommandContext(); + CommandGroup discardCardGroup = new CommandGroup(ExecutionMode.Sequential, context, + new Cmd_UsePowerCards(owner is PlayerHero, card.deck, new List() { card }, interval), + new Cmd_Function(0, () => + { + //Debug.Log((context.sharedInfo["DrawnCards"] as List).Count); //TODO: 消耗牌后的处理 + })); + + return discardCardGroup; + } + + public CommandGroup UsePowerCards(List cards, float interval = 0.1f) + { + Dictionary> groupedCards = cards.GroupBy(card => card.deck) + .ToDictionary(group => group.Key, group => group.ToList()); + CommandContext context = new CommandContext(); + CommandGroup discardCardGroup = new CommandGroup(ExecutionMode.Sequential, context); + foreach (var kvp in groupedCards) + { + discardCardGroup.AddCommand(new Cmd_UsePowerCards(owner is PlayerHero, kvp.Key, kvp.Value, interval)); + } + discardCardGroup.AddCommand(new Cmd_Function(0, () => + { + //Debug.Log((context.sharedInfo["DrawnCards"] as List).Count); //TODO: 弃牌后的处理 + })); + + return discardCardGroup; } public void ReshuffleDeck(float interval = 0.1f) @@ -189,6 +253,7 @@ namespace Continentis.MainGame.Character public List DrawPile => Pile("Draw"); public List DiscardPile => Pile("Discard"); public List ExhaustPile => Pile("Exhaust"); + public List GravePile => Pile("Grave"); public List PoolPile => Pile("Pool"); public List IntentionPile => Pile("Intention"); } diff --git a/Assets/Scripts/MainGame/Combat/CombatMainManager.cs b/Assets/Scripts/MainGame/Combat/CombatMainManager.cs index 9d5545da..248ae3c6 100644 --- a/Assets/Scripts/MainGame/Combat/CombatMainManager.cs +++ b/Assets/Scripts/MainGame/Combat/CombatMainManager.cs @@ -219,8 +219,8 @@ namespace Continentis.MainGame.Combat List cardToRetain = handPile.Where(card => card.cardLogic.HasKeyword("Retain")).ToList(); //含有“保留”关键词的卡牌 List cardToExhaust = handPile.Where(card => card.cardLogic.HasKeyword("Ethereal")).ToList(); //含有“虚无”关键词的卡牌 List cardsToDiscard = handPile.Except(cardToRetain).Except(cardToExhaust).ToList(); //其他卡牌,默认丢弃 - playerHero.deckSubmodule.ExhaustCards(cardToExhaust); - playerHero.deckSubmodule.DiscardCards(cardsToDiscard); + CommandQueueManager.Instance.AddCommand(playerHero.deckSubmodule.ExhaustCards(cardToExhaust)); + CommandQueueManager.Instance.AddCommand(playerHero.deckSubmodule.DiscardCards(cardsToDiscard)); } characterController.actionOrderList.Remove(currentCharacter); diff --git a/Assets/Scripts/MainGame/Commands/Cmd_UsePowerCards.cs b/Assets/Scripts/MainGame/Commands/Cmd_UsePowerCards.cs new file mode 100644 index 00000000..a95b3e27 --- /dev/null +++ b/Assets/Scripts/MainGame/Commands/Cmd_UsePowerCards.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Continentis.MainGame.Card; +using Continentis.MainGame.Character; +using DG.Tweening; +using SLSFramework.General; +using UniRx; +using UnityEngine; +using Random = UnityEngine.Random; + +namespace Continentis.MainGame.Commands +{ + public class Cmd_UsePowerCards : CommandBase + { + private bool isPlayer; + private readonly DeckSubmodule deck; + private readonly List cardsToUse; + private readonly float interval; + private readonly float singleCardAnimationDuration = 0.5f; // 单张卡牌的动画时长 + + public Cmd_UsePowerCards(bool isPlayer, DeckSubmodule deck, List cards, float interval) + { + this.isPlayer = isPlayer; + this.deck = deck; + this.cardsToUse = cards; + this.interval = interval; + } + + protected override IObservable OnExecute(CommandContext outerContext) + { + if (cardsToUse == null || cardsToUse.Count == 0) + { + return Observable.Return(Unit.Default); + } + + Func> exhaustAction = isPlayer ? PlayerUsePowers : NpcUsePowers; + + // --- 情况1:并行丢弃 (所有卡牌动画同时开始) --- + if (interval <= 0f) + { + // 为每张卡牌创建一个“懒加载”的丢弃动画流。 + var allDiscardAnimations = cardsToUse.Select(card => + Observable.Defer(() => exhaustAction(card)) + ); + + // 使用 WhenAll 等待所有的并行任务都完成。 + // 只有当最后一个动画结束时,WhenAll 才会发出完成信号。 + return Observable.WhenAll(allDiscardAnimations).AsUnitObservable(); + } + + // --- 情况2:交错丢弃 (按固定间隔开始动画) --- + else + { + var cardStream = cardsToUse.ToObservable(); + var timerStream = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(interval)); + + return timerStream + .Zip(cardStream, (_, card) => card) + // 核心:不再使用 .Do(..).Subscribe(),而是使用 Select 将每个 card 转换为 + // 其对应的动画流。这样主流程就“知道”了每个动画的存在。 + .Select(card => exhaustAction(card)) + // 使用 Merge 将所有交错开始的动画流合并为一个流。 + // Merge 会同时运行所有这些动画,并在最后一个动画也完成时,它才会完成。 + .Merge() + // 使用 Last 来确保我们只在整个 Merge 流全部结束后,才发出最终的完成信号。 + .Last() + .AsUnitObservable(); + } + } + + + private IObservable PlayerUsePowers(CardInstance card) + { + deck.TransferCard(deck.Pile(card.cardLocation.pileName), deck.GravePile, card); + + card.handCardView.TransferCardView(CombatUIManager.Instance.combatMainPage.gravePile); + + RectTransform cardTransform = card.handCardView.cardTransform; + Vector2 userViewPosition = card.cardLogic.user.characterView.hudContainer.GetComponent().position; + cardTransform.DOMove(userViewPosition, singleCardAnimationDuration).SetEase(Ease.Linear).Play(); + cardTransform.DOScale(Vector3.zero, singleCardAnimationDuration).SetEase(Ease.Linear).OnComplete(() => + { + cardTransform.anchoredPosition = Vector2.zero; + }).Play(); + + return Observable.Timer(TimeSpan.FromSeconds(singleCardAnimationDuration)).AsUnitObservable(); + } + + private IObservable NpcUsePowers(CardInstance card) + { + deck.TransferCard(deck.Pile(card.cardLocation.pileName), deck.GravePile, card); + return Observable.Timer(TimeSpan.FromSeconds(singleCardAnimationDuration)).AsUnitObservable(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/MainGame/Commands/Cmd_UsePowerCards.cs.meta b/Assets/Scripts/MainGame/Commands/Cmd_UsePowerCards.cs.meta new file mode 100644 index 00000000..1194f09a --- /dev/null +++ b/Assets/Scripts/MainGame/Commands/Cmd_UsePowerCards.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 11580fee6c93e4445b768eb40c5780bb \ No newline at end of file diff --git a/Assets/Scripts/MainGame/UI/CombatMainPage/CombatMainPage.cs b/Assets/Scripts/MainGame/UI/CombatMainPage/CombatMainPage.cs index 26648668..fe82c1fb 100644 --- a/Assets/Scripts/MainGame/UI/CombatMainPage/CombatMainPage.cs +++ b/Assets/Scripts/MainGame/UI/CombatMainPage/CombatMainPage.cs @@ -13,6 +13,7 @@ namespace Continentis.MainGame.UI public HandPile handPile; public DiscardPile discardPile; public ExhaustPile exhaustPile; + public GravePile gravePile; public TeamSwitchButton teamSwitchButton; public HandCardSelectionInterface handCardSelector; public CustomCardSelectionInterface customCardSelector; @@ -32,11 +33,13 @@ namespace Continentis.MainGame.UI handPile.cardViews.ForEach(c => LeanPool.Despawn(c.gameObject)); discardPile.cardViews.ForEach(c => LeanPool.Despawn(c.gameObject)); exhaustPile.cardViews.ForEach(c => LeanPool.Despawn(c.gameObject)); + gravePile.cardViews.ForEach(c => LeanPool.Despawn(c.gameObject)); drawPile.cardViews.Clear(); handPile.cardViews.Clear(); discardPile.cardViews.Clear(); exhaustPile.cardViews.Clear(); + gravePile.cardViews.Clear(); } public PileBase Pile(string pileName) @@ -51,6 +54,8 @@ namespace Continentis.MainGame.UI return discardPile; case "Exhaust": return exhaustPile; + case "Grave": + return gravePile; case "Intention": throw new NotImplementedException("Intention pile UI is in HUD, not in DeckPage."); default: diff --git a/Assets/Scripts/MainGame/UI/CombatMainPage/ExhaustPile.cs b/Assets/Scripts/MainGame/UI/CombatMainPage/ExhaustPile.cs index cccfc5d7..8af6d52f 100644 --- a/Assets/Scripts/MainGame/UI/CombatMainPage/ExhaustPile.cs +++ b/Assets/Scripts/MainGame/UI/CombatMainPage/ExhaustPile.cs @@ -4,16 +4,6 @@ namespace Continentis.MainGame.UI { public class ExhaustPile : PileBase { - // Start is called once before the first execution of Update after the MonoBehaviour is created - void Start() - { - } - - // Update is called once per frame - void Update() - { - - } } } diff --git a/Assets/Scripts/MainGame/UI/CombatMainPage/GravePile.cs b/Assets/Scripts/MainGame/UI/CombatMainPage/GravePile.cs new file mode 100644 index 00000000..ec4a54c4 --- /dev/null +++ b/Assets/Scripts/MainGame/UI/CombatMainPage/GravePile.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace Continentis.MainGame.UI +{ + public class GravePile : PileBase + { + + } +} \ No newline at end of file diff --git a/Assets/Scripts/MainGame/UI/CombatMainPage/GravePile.cs.meta b/Assets/Scripts/MainGame/UI/CombatMainPage/GravePile.cs.meta new file mode 100644 index 00000000..1abb946e --- /dev/null +++ b/Assets/Scripts/MainGame/UI/CombatMainPage/GravePile.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f997d4e8f500b944eb3cbb0f5c4ac7c5 \ No newline at end of file diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-73fc-7fa4-a5c1-1ecc64657b7c.jpg b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-73fc-7fa4-a5c1-1ecc64657b7c.jpg new file mode 100644 index 00000000..faa1a32e Binary files /dev/null and b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-73fc-7fa4-a5c1-1ecc64657b7c.jpg differ diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-73fc-7fa4-a5c1-1ecc64657b7c.jpg.json b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-73fc-7fa4-a5c1-1ecc64657b7c.jpg.json new file mode 100644 index 00000000..47684df6 --- /dev/null +++ b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-73fc-7fa4-a5c1-1ecc64657b7c.jpg.json @@ -0,0 +1,20 @@ +{ + "asset": "1682919049c032045955857bd5349a22", + "fileName": "019a3801-73fc-7fa4-a5c1-1ecc64657b7c.jpg", + "prompt": "a silhouette of a person holding a shield, representing \"withstand\"", + "negativePrompt": "", + "model": "9118f8cf-d5fa-4ffe-91d5-9268467fcbe1", + "modelName": "Game Icons", + "customSeed": -1, + "w3CTraceId": "79d6406b196797bf219a654838e28988", + "refinementMode": "Generation", + "pixelateTargetSize": 0, + "pixelateKeepImageSize": false, + "pixelatePixelBlockSize": 0, + "pixelateMode": 0, + "pixelateOutlineThickness": 0, + "doodles": { + "m_Items": [] + }, + "upscaleFactor": 0 +} \ No newline at end of file diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-d4a2-7667-be40-5394a9b08d14.jpg b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-d4a2-7667-be40-5394a9b08d14.jpg new file mode 100644 index 00000000..4dc00cd8 Binary files /dev/null and b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-d4a2-7667-be40-5394a9b08d14.jpg differ diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-d4a2-7667-be40-5394a9b08d14.jpg.json b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-d4a2-7667-be40-5394a9b08d14.jpg.json new file mode 100644 index 00000000..82fcb3c9 --- /dev/null +++ b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3801-d4a2-7667-be40-5394a9b08d14.jpg.json @@ -0,0 +1,20 @@ +{ + "asset": "1682919049c032045955857bd5349a22", + "fileName": "019a3801-d4a2-7667-be40-5394a9b08d14.jpg", + "prompt": "a silhouette of \"a person holding a shield\", representing \"withstand\"", + "negativePrompt": "", + "model": "9118f8cf-d5fa-4ffe-91d5-9268467fcbe1", + "modelName": "Game Icons", + "customSeed": -1, + "w3CTraceId": "0919f3fde2d9e8b111cb5d73d49445f8", + "refinementMode": "Generation", + "pixelateTargetSize": 0, + "pixelateKeepImageSize": false, + "pixelatePixelBlockSize": 0, + "pixelateMode": 0, + "pixelateOutlineThickness": 0, + "doodles": { + "m_Items": [] + }, + "upscaleFactor": 0 +} \ No newline at end of file diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-4d8a-7381-b2e8-b33d7d69d506.jpg b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-4d8a-7381-b2e8-b33d7d69d506.jpg new file mode 100644 index 00000000..1d9448f1 Binary files /dev/null and b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-4d8a-7381-b2e8-b33d7d69d506.jpg differ diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-4d8a-7381-b2e8-b33d7d69d506.jpg.json b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-4d8a-7381-b2e8-b33d7d69d506.jpg.json new file mode 100644 index 00000000..86be57f8 --- /dev/null +++ b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-4d8a-7381-b2e8-b33d7d69d506.jpg.json @@ -0,0 +1,20 @@ +{ + "asset": "1682919049c032045955857bd5349a22", + "fileName": "019a3802-4d8a-7381-b2e8-b33d7d69d506.jpg", + "prompt": "a silhouette of a person holding a silhouette of a shield, representing \"withstand\"", + "negativePrompt": "", + "model": "9118f8cf-d5fa-4ffe-91d5-9268467fcbe1", + "modelName": "Game Icons", + "customSeed": -1, + "w3CTraceId": "0ec03ee92d7bb166b863371448b6c9dc", + "refinementMode": "Generation", + "pixelateTargetSize": 0, + "pixelateKeepImageSize": false, + "pixelatePixelBlockSize": 0, + "pixelateMode": 0, + "pixelateOutlineThickness": 0, + "doodles": { + "m_Items": [] + }, + "upscaleFactor": 0 +} \ No newline at end of file diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-796f-7954-aebd-77a44c1a1e9b.png b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-796f-7954-aebd-77a44c1a1e9b.png new file mode 100644 index 00000000..98bae37e Binary files /dev/null and b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-796f-7954-aebd-77a44c1a1e9b.png differ diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-796f-7954-aebd-77a44c1a1e9b.png.json b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-796f-7954-aebd-77a44c1a1e9b.png.json new file mode 100644 index 00000000..882406a6 --- /dev/null +++ b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-796f-7954-aebd-77a44c1a1e9b.png.json @@ -0,0 +1,20 @@ +{ + "asset": "1682919049c032045955857bd5349a22", + "fileName": "019a3802-796f-7954-aebd-77a44c1a1e9b.png", + "prompt": "", + "negativePrompt": "", + "model": "", + "modelName": "", + "customSeed": -1, + "w3CTraceId": "6f06756051933a7d3ccd044a1f9090be", + "refinementMode": "RemoveBackground", + "pixelateTargetSize": 0, + "pixelateKeepImageSize": false, + "pixelatePixelBlockSize": 0, + "pixelateMode": 0, + "pixelateOutlineThickness": 0, + "doodles": { + "m_Items": [] + }, + "upscaleFactor": 0 +} \ No newline at end of file diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-80b0-740c-8260-5be563ddbd8f.png b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-80b0-740c-8260-5be563ddbd8f.png new file mode 100644 index 00000000..98bae37e Binary files /dev/null and b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-80b0-740c-8260-5be563ddbd8f.png differ diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-80b0-740c-8260-5be563ddbd8f.png.json b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-80b0-740c-8260-5be563ddbd8f.png.json new file mode 100644 index 00000000..61831321 --- /dev/null +++ b/GeneratedAssets/1682919049c032045955857bd5349a22/019a3802-80b0-740c-8260-5be563ddbd8f.png.json @@ -0,0 +1,20 @@ +{ + "asset": "1682919049c032045955857bd5349a22", + "fileName": "019a3802-80b0-740c-8260-5be563ddbd8f.png", + "prompt": "", + "negativePrompt": "", + "model": "", + "modelName": "", + "customSeed": -1, + "w3CTraceId": "1f14e422fd99b9f0d1cdb4e11dc81a35", + "refinementMode": "RemoveBackground", + "pixelateTargetSize": 0, + "pixelateKeepImageSize": false, + "pixelatePixelBlockSize": 0, + "pixelateMode": 0, + "pixelateOutlineThickness": 0, + "doodles": { + "m_Items": [] + }, + "upscaleFactor": 0 +} \ No newline at end of file diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/BuffIcon_Basic_Withstand.png b/GeneratedAssets/1682919049c032045955857bd5349a22/BuffIcon_Basic_Withstand.png new file mode 100644 index 00000000..287a2967 Binary files /dev/null and b/GeneratedAssets/1682919049c032045955857bd5349a22/BuffIcon_Basic_Withstand.png differ diff --git a/GeneratedAssets/1682919049c032045955857bd5349a22/BuffIcon_Basic_Withstand.png.json b/GeneratedAssets/1682919049c032045955857bd5349a22/BuffIcon_Basic_Withstand.png.json new file mode 100644 index 00000000..11419e83 --- /dev/null +++ b/GeneratedAssets/1682919049c032045955857bd5349a22/BuffIcon_Basic_Withstand.png.json @@ -0,0 +1,20 @@ +{ + "asset": "1682919049c032045955857bd5349a22", + "fileName": "BuffIcon_Basic_Withstand.png", + "prompt": "", + "negativePrompt": "", + "model": "", + "modelName": "", + "customSeed": -1, + "w3CTraceId": "", + "refinementMode": "Generation", + "pixelateTargetSize": 0, + "pixelateKeepImageSize": false, + "pixelatePixelBlockSize": 0, + "pixelateMode": 0, + "pixelateOutlineThickness": 0, + "doodles": { + "m_Items": [] + }, + "upscaleFactor": 0 +} \ No newline at end of file