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