Commit cd1f92c4 authored by Chunchi Che's avatar Chunchi Che

handle overlay

parent 9e5c6f5c
Pipeline #22069 failed with stages
in 10 minutes and 53 seconds
...@@ -7,7 +7,7 @@ import { REASON_MATERIAL } from "../../common"; ...@@ -7,7 +7,7 @@ import { REASON_MATERIAL } from "../../common";
type MsgMove = ygopro.StocGameMessage.MsgMove; type MsgMove = ygopro.StocGameMessage.MsgMove;
const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, TZONE } = ygopro.CardZone; const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, TZONE } = ygopro.CardZone;
const overlayStack: CardType[] = []; const overlayStack: ygopro.CardLocation[] = [];
export default async (move: MsgMove) => { export default async (move: MsgMove) => {
const code = move.code; const code = move.code;
...@@ -15,12 +15,10 @@ export default async (move: MsgMove) => { ...@@ -15,12 +15,10 @@ export default async (move: MsgMove) => {
const to = move.to; const to = move.to;
const reason = move.reason; const reason = move.reason;
// FIXME: 考虑超量素材的情况
const fromCards = cardStore.at(from.zone, from.controler); const fromCards = cardStore.at(from.zone, from.controler);
const toCards = cardStore.at(to.zone, to.controler); const toCards = cardStore.at(to.zone, to.controler);
// TODO: 这段逻辑有点迷惑,后面问问作者 // TODO: 是否能有更solid的衍生物判断方式?
const fromZone = const fromZone =
move.from.toArray().at(1) === undefined ? ygopro.CardZone.TZONE : from.zone; move.from.toArray().at(1) === undefined ? ygopro.CardZone.TZONE : from.zone;
const toZone = const toZone =
...@@ -30,9 +28,12 @@ export default async (move: MsgMove) => { ...@@ -30,9 +28,12 @@ export default async (move: MsgMove) => {
await (async () => { await (async () => {
const { text } = await fetchCard(code); const { text } = await fetchCard(code);
console.color("green")( console.color("green")(
`${text.name} ${ygopro.CardZone[fromZone]}:${from.sequence}${ygopro.CardZone[toZone]}:${to.sequence}` `${text.name} ${ygopro.CardZone[fromZone]}:${from.sequence}:${
from.is_overlay ? from.overlay_sequence : ""
}${ygopro.CardZone[toZone]}:${to.sequence}:${
to.is_overlay ? to.overlay_sequence : ""
}`
); );
// console.color("green")("overlay", from.overlay_sequence, to.overlay_sequence);
})(); })();
let target: CardType; let target: CardType;
...@@ -43,23 +44,17 @@ export default async (move: MsgMove) => { ...@@ -43,23 +44,17 @@ export default async (move: MsgMove) => {
target = cardStore.at(TZONE, from.controler)[0]; // 必有,随便取一个没用到的token target = cardStore.at(TZONE, from.controler)[0]; // 必有,随便取一个没用到的token
} else if (from.is_overlay) { } else if (from.is_overlay) {
// 超量素材的去除 // 超量素材的去除
const xyzMonster = cardStore.at(MZONE, from.controler, from.sequence); const overlayMaterial = cardStore.at(
if (xyzMonster) { MZONE,
const overlay = xyzMonster.overlayMaterials from.controler,
.splice(from.overlay_sequence, 1) from.sequence,
.at(0); from.overlay_sequence
if (overlay) { );
target = overlay; if (overlayMaterial) {
target.xyzMonster = undefined; target = overlayMaterial;
} else {
console.warn(
`<Move>overlay from zone=${MZONE}, controller=${from.controler}, sequence=${from.sequence}, overlay_sequence=${from.overlay_sequence} is null`
);
return;
}
} else { } else {
console.warn( console.warn(
`<Move>xyzMonster from zone=${MZONE}, controller=${from.controler}, sequence=${from.sequence} is null` `<Move>overlayMaterial from zone=${MZONE}, controller=${from.controler}, sequence=${from.sequence}, overlay_sequence=${from.overlay_sequence} is null`
); );
return; return;
} }
...@@ -79,21 +74,30 @@ export default async (move: MsgMove) => { ...@@ -79,21 +74,30 @@ export default async (move: MsgMove) => {
// 超量 // 超量
if (to.is_overlay) { if (to.is_overlay) {
// 准备超量召唤,超量素材入栈 // 准备超量召唤,超量素材入栈
if (reason == REASON_MATERIAL) overlayStack.push(target); if (reason == REASON_MATERIAL) overlayStack.push(to);
// 超量素材的添加
else {
target.overlayMaterials.splice(to.overlay_sequence, 0, target);
target.xyzMonster = undefined;
}
} }
if (toZone === MZONE && overlayStack.length) { if (toZone === MZONE && overlayStack.length) {
// 超量召唤 // 超量召唤
target.overlayMaterials = overlayStack.splice(0, overlayStack.length); const xyzLocations = overlayStack.splice(0, overlayStack.length);
target.overlayMaterials.forEach((c) => (c.xyzMonster = target)); for (const location of xyzLocations) {
const overlayMaterial = cardStore.at(
location.zone,
location.controler,
location.sequence,
location.overlay_sequence
);
if (overlayMaterial) {
// 超量素材的位置应该和超量怪兽保持一致
overlayMaterial.location.controler = to.controler;
overlayMaterial.location.zone = to.zone;
overlayMaterial.location.sequence = to.sequence;
await eventbus.call(Task.Move, overlayMaterial.uuid);
}
}
} }
// 维护sequence // 维护sequence
// TODO: 这些逻辑是不是可以考虑沉淀到store里面
if ([HAND, GRAVE, REMOVED, DECK, EXTRA].includes(fromZone)) if ([HAND, GRAVE, REMOVED, DECK, EXTRA].includes(fromZone))
fromCards.forEach( fromCards.forEach(
(c) => c.location.sequence > from.sequence && c.location.sequence-- (c) => c.location.sequence > from.sequence && c.location.sequence--
...@@ -104,11 +108,8 @@ export default async (move: MsgMove) => { ...@@ -104,11 +108,8 @@ export default async (move: MsgMove) => {
); );
// 更新信息 // 更新信息
target.location.zone = toZone;
target.location.controler = to.controler;
target.location.sequence = to.sequence;
target.code = code; target.code = code;
target.location.position = to.position; target.location = to;
// 维护完了之后,开始动画 // 维护完了之后,开始动画
const promises: Promise<unknown>[] = []; const promises: Promise<unknown>[] = [];
...@@ -122,6 +123,19 @@ export default async (move: MsgMove) => { ...@@ -122,6 +123,19 @@ export default async (move: MsgMove) => {
} }
await Promise.all(promises); await Promise.all(promises);
// 超量素材位置随之移动
if (from.zone == MZONE && !from.is_overlay) {
for (const overlay of cardStore.findOverlay(
from.zone,
from.controler,
from.sequence
)) {
overlay.location = to;
await eventbus.call(Task.Move, overlay.uuid);
}
}
// TODO: 如果涉及了有超量素材的怪兽的移动,那么这个怪兽的移动应该也会带动超量素材的移动 // TODO: 如果涉及了有超量素材的怪兽的移动,那么这个怪兽的移动应该也会带动超量素材的移动
// 注意,一个monster的overlayMaterials中的每一项都是一个cardType, // 注意,一个monster的overlayMaterials中的每一项都是一个cardType,
......
...@@ -61,7 +61,6 @@ export default (start: ygopro.StocGameMessage.MsgStart) => { ...@@ -61,7 +61,6 @@ export default (start: ygopro.StocGameMessage.MsgStart) => {
text: {}, text: {},
}, },
isToken: !((i + 1) % 3), isToken: !((i + 1) % 3),
overlayMaterials: [],
chaining: false, chaining: false,
directAttack: false, directAttack: false,
}) })
......
...@@ -19,8 +19,6 @@ export interface CardType { ...@@ -19,8 +19,6 @@ export interface CardType {
zone: ygopro.CardZone; zone: ygopro.CardZone;
sequence: number; sequence: number;
}>; // 选择位置状态下的互动信息 }>; // 选择位置状态下的互动信息
overlayMaterials: CardType[]; // 超量素材, FIXME: 这里需要加上UUID
xyzMonster?: CardType; // 超量怪兽(这张卡作为这个怪兽的超量素材)
counters: { [type: number]: number }; // 指示器 counters: { [type: number]: number }; // 指示器
reload?: boolean; // 这个字段会在收到MSG_RELOAD_FIELD的时候设置成true,在收到MSG_UPDATE_DATE的时候设置成false reload?: boolean; // 这个字段会在收到MSG_RELOAD_FIELD的时候设置成true,在收到MSG_UPDATE_DATE的时候设置成false
isToken: boolean; // 是否是token isToken: boolean; // 是否是token
...@@ -39,18 +37,38 @@ class CardStore { ...@@ -39,18 +37,38 @@ class CardStore {
at( at(
zone: ygopro.CardZone, zone: ygopro.CardZone,
controller: number, controller: number,
sequence?: number sequence?: number,
overlay_sequence?: number
): CardType | undefined; ): CardType | undefined;
at(zone: ygopro.CardZone, controller: number, sequence?: number) { at(
zone: ygopro.CardZone,
controller: number,
sequence?: number,
overlay_sequence?: number
) {
if (sequence !== undefined) { if (sequence !== undefined) {
return this.inner if (overlay_sequence !== undefined) {
.filter( return this.inner
(card) => .filter(
card.location.zone === zone && (card) =>
card.location.controler === controller && card.location.zone === zone &&
card.location.sequence === sequence card.location.controler === controller &&
) card.location.sequence === sequence &&
.at(0); card.location.is_overlay == true &&
card.location.overlay_sequence == overlay_sequence
)
.at(0);
} else {
return this.inner
.filter(
(card) =>
card.location.zone === zone &&
card.location.controler === controller &&
card.location.sequence === sequence &&
card.location.is_overlay == false
)
.at(0);
}
} else { } else {
return this.inner.filter( return this.inner.filter(
(card) => (card) =>
...@@ -61,6 +79,20 @@ class CardStore { ...@@ -61,6 +79,20 @@ class CardStore {
find(location: ygopro.CardLocation): CardType | undefined { find(location: ygopro.CardLocation): CardType | undefined {
return this.at(location.zone, location.controler, location.sequence); return this.at(location.zone, location.controler, location.sequence);
} }
// 获取特定位置下的所有超量素材
findOverlay(
zone: ygopro.CardZone,
controller: number,
sequence: number
): CardType[] {
return this.inner.filter(
(card) =>
card.location.zone == zone &&
card.location.controler == controller &&
card.location.sequence == sequence &&
card.location.is_overlay
);
}
async setChaining( async setChaining(
location: ygopro.CardLocation, location: ygopro.CardLocation,
code: number, code: number,
......
...@@ -162,9 +162,14 @@ const onCardClick = (card: CardType) => { ...@@ -162,9 +162,14 @@ const onCardClick = (card: CardType) => {
messageStore.cardModal.isOpen = true; messageStore.cardModal.isOpen = true;
// 侧边栏展示超量素材信息 // 侧边栏展示超量素材信息
if (card.overlayMaterials.length > 0) { const overlayMaterials = cardStore.findOverlay(
card.location.zone,
card.location.controler,
card.location.sequence
);
if (overlayMaterials.length > 0) {
messageStore.cardListModal.list = messageStore.cardListModal.list =
card.overlayMaterials.map((overlay) => ({ overlayMaterials.map((overlay) => ({
meta: { meta: {
id: overlay.code, id: overlay.code,
text: overlay.meta.text, text: overlay.meta.text,
......
...@@ -30,7 +30,7 @@ const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, SZONE, TZONE } = ...@@ -30,7 +30,7 @@ const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, SZONE, TZONE } =
export const moveToDeck = async (props: { card: CardType; api: SpringApi }) => { export const moveToDeck = async (props: { card: CardType; api: SpringApi }) => {
const { card, api } = props; const { card, api } = props;
// report // report
const { location, xyzMonster } = card; const { location } = card;
const { controler, zone, sequence, position } = location; const { controler, zone, sequence, position } = location;
const rightX = DECK_OFFSET_X.value + 2 * (BLOCK_WIDTH.value + COL_GAP.value); const rightX = DECK_OFFSET_X.value + 2 * (BLOCK_WIDTH.value + COL_GAP.value);
......
...@@ -32,16 +32,9 @@ export const moveToGround = async (props: { ...@@ -32,16 +32,9 @@ export const moveToGround = async (props: {
}) => { }) => {
const { card, api } = props; const { card, api } = props;
// 如果是超量素材,那么,应该看超量素材所属的xyzMonster const { location } = card;
const targetCard = card.location.is_overlay
? card.xyzMonster
? card.xyzMonster
: card
: card;
const { location, xyzMonster, overlayMaterials } = targetCard; const { controler, zone, sequence, position, is_overlay } = location;
const { controler, zone, sequence, position } = location;
// 根据zone计算卡片的宽度 // 根据zone计算卡片的宽度
const cardWidth = const cardWidth =
...@@ -104,7 +97,7 @@ export const moveToGround = async (props: { ...@@ -104,7 +97,7 @@ export const moveToGround = async (props: {
x, x,
y, y,
height, height,
z: overlayMaterials.length ? 200 : 120, z: is_overlay ? 120 : 200,
ry: [ ry: [
ygopro.CardPosition.FACEDOWN, ygopro.CardPosition.FACEDOWN,
ygopro.CardPosition.FACEDOWN_ATTACK, ygopro.CardPosition.FACEDOWN_ATTACK,
...@@ -120,7 +113,7 @@ export const moveToGround = async (props: { ...@@ -120,7 +113,7 @@ export const moveToGround = async (props: {
}); });
await asyncStart(api)({ await asyncStart(api)({
z: 0, z: 0,
zIndex: overlayMaterials.length ? 3 : 1, zIndex: is_overlay ? 1 : 3,
config: { config: {
easing: easings.easeInOutQuad, easing: easings.easeInOutQuad,
mass: 5, mass: 5,
......
...@@ -32,7 +32,6 @@ export const moveToOutside = async (props: { ...@@ -32,7 +32,6 @@ export const moveToOutside = async (props: {
}) => { }) => {
const { card, api } = props; const { card, api } = props;
// report // report
const { xyzMonster, overlayMaterials } = card;
const { zone, sequence, controler, position } = card.location; const { zone, sequence, controler, position } = card.location;
let x = (BLOCK_WIDTH.value + COL_GAP.value) * 3, let x = (BLOCK_WIDTH.value + COL_GAP.value) * 3,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment