到IronWall

This commit is contained in:
SoulliesOfficial
2025-10-30 23:31:29 -04:00
parent 8b72c75128
commit 5d09ef7b53
39 changed files with 688 additions and 41 deletions

Binary file not shown.

View File

@@ -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

View File

@@ -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: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cf83d1221ea596749a05a285fee6c313
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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());
}
}
}

View File

@@ -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<CharacterBase> targetList)
{
CommandGroup mainGroup = new CommandGroup(ExecutionMode.Sequential,
new Cmd_PlayAnimation(user.characterView, "Skill"),
new Cmd_Function(() =>
{
CreateCharacterBuff<Withstand>(GetAttribute("BuffCount_Withstand")).Apply(user, user, this);
}));
// Update is called once per frame
void Update()
{
return mainGroup;
}
}
}
}

View File

@@ -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()
{
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9299438b564ba4a4aa59e98ea7d83c9d

View File

@@ -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));
}
}
}

View File

@@ -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));
}
}
}));

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f3ab0c664289dcf47ac75d37cfa8b474

View File

@@ -209,5 +209,6 @@ MonoBehaviour:
- CardData_Basic_BattlefieldExperience
- CardData_Basic_BodyAsShield
- CardData_Basic_EchoOfHonor
- CardData_Basic_IronWall
hudDataRefs:
- HUDData_Basic_Default

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

View File

@@ -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:

View File

Before

Width:  |  Height:  |  Size: 5.0 MiB

After

Width:  |  Height:  |  Size: 5.0 MiB

View File

@@ -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

View File

@@ -232,15 +232,21 @@ namespace Continentis.MainGame.Card
protected virtual void AfterPlayEffect(List<CharacterBase> 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));
}
}
}

View File

@@ -22,6 +22,7 @@ namespace Continentis.MainGame.Character
piles.Add("Draw", new List<CardInstance>());
piles.Add("Discard", new List<CardInstance>());
piles.Add("Exhaust", new List<CardInstance>());
piles.Add("Grave", new List<CardInstance>());
piles.Add("Pool", new List<CardInstance>());
piles.Add("Intention", new List<CardInstance>());
}
@@ -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<CardInstance> { card }, interval));
}
public void DiscardCards(List<CardInstance> 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<CardInstance>() { card }, interval),
new Cmd_Function(0, () =>
{
//Debug.Log((context.sharedInfo["DrawnCards"] as List<CardInstance>).Count); //TODO: 弃牌后的处理
}));
return discardCardGroup;
}
public CommandGroup DiscardCards(List<CardInstance> cards, float interval = 0.1f)
{
Dictionary<DeckSubmodule, List<CardInstance>> 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<CardInstance>).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<CardInstance> { card }, interval));
CommandContext context = new CommandContext();
CommandGroup discardCardGroup = new CommandGroup(ExecutionMode.Sequential, context,
new Cmd_ExhaustCards(owner is PlayerHero, card.deck, new List<CardInstance>() { card }, interval),
new Cmd_Function(0, () =>
{
//Debug.Log((context.sharedInfo["DrawnCards"] as List<CardInstance>).Count); //TODO: 消耗牌后的处理
}));
return discardCardGroup;
}
public void ExhaustCards(List<CardInstance> cards, float interval = 0.1f)
public CommandGroup ExhaustCards(List<CardInstance> cards, float interval = 0.1f)
{
Dictionary<DeckSubmodule, List<CardInstance>> 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<CardInstance>).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<CardInstance>() { card }, interval),
new Cmd_Function(0, () =>
{
//Debug.Log((context.sharedInfo["DrawnCards"] as List<CardInstance>).Count); //TODO: 消耗牌后的处理
}));
return discardCardGroup;
}
public CommandGroup UsePowerCards(List<CardInstance> cards, float interval = 0.1f)
{
Dictionary<DeckSubmodule, List<CardInstance>> 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<CardInstance>).Count); //TODO: 弃牌后的处理
}));
return discardCardGroup;
}
public void ReshuffleDeck(float interval = 0.1f)
@@ -189,6 +253,7 @@ namespace Continentis.MainGame.Character
public List<CardInstance> DrawPile => Pile("Draw");
public List<CardInstance> DiscardPile => Pile("Discard");
public List<CardInstance> ExhaustPile => Pile("Exhaust");
public List<CardInstance> GravePile => Pile("Grave");
public List<CardInstance> PoolPile => Pile("Pool");
public List<CardInstance> IntentionPile => Pile("Intention");
}

View File

@@ -219,8 +219,8 @@ namespace Continentis.MainGame.Combat
List<CardInstance> cardToRetain = handPile.Where(card => card.cardLogic.HasKeyword("Retain")).ToList(); //含有“保留”关键词的卡牌
List<CardInstance> cardToExhaust = handPile.Where(card => card.cardLogic.HasKeyword("Ethereal")).ToList(); //含有“虚无”关键词的卡牌
List<CardInstance> 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);

View File

@@ -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<CardInstance> cardsToUse;
private readonly float interval;
private readonly float singleCardAnimationDuration = 0.5f; // 单张卡牌的动画时长
public Cmd_UsePowerCards(bool isPlayer, DeckSubmodule deck, List<CardInstance> cards, float interval)
{
this.isPlayer = isPlayer;
this.deck = deck;
this.cardsToUse = cards;
this.interval = interval;
}
protected override IObservable<Unit> OnExecute(CommandContext outerContext)
{
if (cardsToUse == null || cardsToUse.Count == 0)
{
return Observable.Return(Unit.Default);
}
Func<CardInstance, IObservable<Unit>> 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<Unit> 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<RectTransform>().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<Unit> NpcUsePowers(CardInstance card)
{
deck.TransferCard(deck.Pile(card.cardLocation.pileName), deck.GravePile, card);
return Observable.Timer(TimeSpan.FromSeconds(singleCardAnimationDuration)).AsUnitObservable();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 11580fee6c93e4445b768eb40c5780bb

View File

@@ -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:

View File

@@ -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()
{
}
}
}

View File

@@ -0,0 +1,9 @@
using UnityEngine;
namespace Continentis.MainGame.UI
{
public class GravePile : PileBase
{
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f997d4e8f500b944eb3cbb0f5c4ac7c5

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@@ -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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

View File

@@ -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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

View File

@@ -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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

View File

@@ -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
}