Commit 9e5c6f5c authored by Chunchi Che's avatar Chunchi Che

use location in CardType

parent 4eda5276
Pipeline #22068 failed with stages
in 8 minutes and 34 seconds
......@@ -13,7 +13,7 @@ export default async (confirmCards: ygopro.StocGameMessage.MsgConfirmCards) => {
const meta = await fetchCard(card.code);
target.meta = meta;
// 设置`position`,否则会横放
target.position = ygopro.CardPosition.ATTACK;
target.location.position = ygopro.CardPosition.ATTACK;
} else {
console.warn(`card of ${card} is null`);
}
......
......@@ -21,8 +21,8 @@ export default async (draw: ygopro.StocGameMessage.MsgDraw) => {
const meta = await fetchCard(code);
card.code = code;
card.meta = meta;
card.zone = ygopro.CardZone.HAND;
card.sequence = Number(idx) + handsLength;
card.location.zone = ygopro.CardZone.HAND;
card.location.sequence = Number(idx) + handsLength;
}
if (cnt++ < 2) {
......
......@@ -95,23 +95,27 @@ export default async (move: MsgMove) => {
// 维护sequence
// TODO: 这些逻辑是不是可以考虑沉淀到store里面
if ([HAND, GRAVE, REMOVED, DECK, EXTRA].includes(fromZone))
fromCards.forEach((c) => c.sequence > from.sequence && c.sequence--);
fromCards.forEach(
(c) => c.location.sequence > from.sequence && c.location.sequence--
);
if ([HAND, GRAVE, REMOVED, DECK, EXTRA].includes(toZone))
toCards.forEach((c) => c.sequence >= to.sequence && c.sequence++);
toCards.forEach(
(c) => c.location.sequence >= to.sequence && c.location.sequence++
);
// 更新信息
target.zone = toZone;
target.controller = to.controler;
target.sequence = to.sequence;
target.location.zone = toZone;
target.location.controler = to.controler;
target.location.sequence = to.sequence;
target.code = code;
target.position = to.position;
target.location.position = to.position;
// 维护完了之后,开始动画
const promises: Promise<unknown>[] = [];
promises.push(eventbus.call(Task.Move, target.uuid));
// 如果from或者to是手卡,那么需要刷新除了这张卡之外,这个玩家的所有手卡
if ([fromZone, toZone].includes(HAND)) {
cardStore.at(HAND, target.controller).forEach((card) => {
cardStore.at(HAND, target.location.controler).forEach((card) => {
if (card.uuid !== target.uuid)
promises.push(eventbus.call(Task.Move, card.uuid));
});
......
......@@ -7,7 +7,7 @@ export default async (posChange: MsgPosChange) => {
const target = cardStore.at(location, controler, sequence);
if (target) {
target.position = posChange.cur_position;
target.location.position = posChange.cur_position;
// TODO: 暂时用`Move`动画,后续可以单独实现一个改变表示形式的动画
await eventbus.call(Task.Move, target.uuid);
......
......@@ -17,7 +17,7 @@ export default (shuffleHand: MsgShuffleHand) => {
const sequence = hash.get(hand.code);
if (sequence !== undefined) {
if (sequence >= 0) {
hand.sequence = sequence;
hand.location.sequence = sequence;
hash.set(hand.code, sequence - 1);
} else {
console.warn(
......
......@@ -42,16 +42,19 @@ export default (start: ygopro.StocGameMessage.MsgStart) => {
genCard({
uuid: v4uuid(),
code: 0,
controller: i < 3 ? 0 : 1,
originController: i < 3 ? 0 : 1,
location: new ygopro.CardLocation({
controler: i < 3 ? 0 : 1,
zone: [
ygopro.CardZone.DECK,
ygopro.CardZone.EXTRA,
ygopro.CardZone.TZONE,
][i % 3],
sequence,
position: ygopro.CardPosition.FACEDOWN,
}),
originController: i < 3 ? 0 : 1,
counters: {},
idleInteractivities: [],
sequence,
meta: {
id: 0,
data: {},
......@@ -59,7 +62,6 @@ export default (start: ygopro.StocGameMessage.MsgStart) => {
},
isToken: !((i + 1) % 3),
overlayMaterials: [],
position: ygopro.CardPosition.FACEDOWN,
chaining: false,
directAttack: false,
})
......
......@@ -10,7 +10,9 @@ export default (updateData: MsgUpdateData) => {
actions.forEach((action) => {
const sequence = action.location?.sequence;
if (typeof sequence !== "undefined") {
const target = field.filter((card) => card.sequence == sequence).at(0);
const target = field
.filter((card) => card.location.sequence == sequence)
.at(0);
if (target) {
const meta = target.meta;
// 目前只更新以下字段
......@@ -19,7 +21,7 @@ export default (updateData: MsgUpdateData) => {
meta.text.id = action.code;
}
if (action.location !== undefined) {
target.position = action.location.position;
target.location.position = action.location.position;
}
if (action?.type_ >= 0) {
meta.data.type = action.type_;
......
......@@ -11,11 +11,8 @@ export interface CardType {
uuid: string; // 一张卡的唯一标识
code: number; // 卡号
meta: CardMeta; // 卡片元数据
controller: number; // 控制这个位置的玩家,0或1
location: ygopro.CardLocation;
originController: number; // 在卡组构建之中持有这张卡的玩家,方便reloadField的使用
zone: ygopro.CardZone; // 怪兽区/魔法陷阱区/手牌/卡组/墓地/除外区
position: ygopro.CardPosition; // 卡片的姿势:攻击还是守备
sequence: number; // 卡片在区域中的序号
idleInteractivities: Interactivity<number>[]; // IDLE状态下的互动信息
placeInteractivity?: Interactivity<{
controler: number;
......@@ -49,14 +46,15 @@ class CardStore {
return this.inner
.filter(
(card) =>
card.zone === zone &&
card.controller === controller &&
card.sequence === sequence
card.location.zone === zone &&
card.location.controler === controller &&
card.location.sequence === sequence
)
.at(0);
} else {
return this.inner.filter(
(card) => card.zone === zone && card.controller === controller
(card) =>
card.location.zone === zone && card.location.controler === controller
);
}
}
......@@ -80,8 +78,8 @@ class CardStore {
// target.code = meta.id;
target.meta = meta;
}
if (target.zone == ygopro.CardZone.HAND) {
target.position = isChaining
if (target.location.zone == ygopro.CardZone.HAND) {
target.location.position = isChaining
? ygopro.CardPosition.FACEUP_ATTACK
: ygopro.CardPosition.FACEDOWN_ATTACK;
}
......
......@@ -63,7 +63,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
};
useEffect(() => {
move(state.zone);
move(state.location.zone);
}, []);
const [highlight, setHighlight] = useState(false);
......@@ -80,7 +80,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
eventbus.register(Task.Move, async (uuid: string) => {
if (uuid === state.uuid) {
await addToAnimation(() => move(state.zone));
await addToAnimation(() => move(state.location.zone));
}
});
......@@ -112,9 +112,9 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
} as any as CSSProperties
}
onClick={() => {
if ([MZONE, SZONE, HAND].includes(state.zone)) {
if ([MZONE, SZONE, HAND].includes(state.location.zone)) {
onCardClick(state);
} else if ([EXTRA, GRAVE, REMOVED].includes(state.zone)) {
} else if ([EXTRA, GRAVE, REMOVED].includes(state.location.zone)) {
onFieldClick(state);
}
}}
......@@ -177,7 +177,10 @@ const onCardClick = (card: CardType) => {
};
const onFieldClick = (card: CardType) => {
const displayStates = cardStore.at(card.zone, card.controller);
const displayStates = cardStore.at(
card.location.zone,
card.location.controler
);
messageStore.cardListModal.list = displayStates.map((item) => ({
meta: {
id: item.code,
......
......@@ -11,9 +11,9 @@ import { asyncStart } from "./utils";
export const focus = async (props: { card: CardType; api: SpringApi }) => {
const { card, api } = props;
const current = api.current[0].get();
if (card.zone === ygopro.CardZone.HAND) {
if (card.location.zone === ygopro.CardZone.HAND) {
await asyncStart(api)({
y: current.y + (matStore.isMe(card.controller) ? -1 : 1) * 200, // TODO: 放到config之中
y: current.y + (matStore.isMe(card.location.controler) ? -1 : 1) * 200, // TODO: 放到config之中
rz: 0,
});
await asyncStart(api)({ y: current.y, rz: current.rz });
......
......@@ -30,7 +30,8 @@ const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, SZONE, TZONE } =
export const moveToDeck = async (props: { card: CardType; api: SpringApi }) => {
const { card, api } = props;
// report
const { zone, sequence, controller, xyzMonster, position } = card;
const { location, xyzMonster } = card;
const { controler, zone, sequence, position } = location;
const rightX = DECK_OFFSET_X.value + 2 * (BLOCK_WIDTH.value + COL_GAP.value);
const leftX = -rightX;
......@@ -41,20 +42,20 @@ export const moveToDeck = async (props: { card: CardType; api: SpringApi }) => {
2 * ROW_GAP.value -
BLOCK_HEIGHT_S.value;
const topY = -bottomY;
let x = isMe(controller) ? rightX : leftX;
let y = isMe(controller) ? bottomY : topY;
let x = isMe(controler) ? rightX : leftX;
let y = isMe(controler) ? bottomY : topY;
if (zone === EXTRA) {
x = isMe(controller) ? leftX : rightX;
x = isMe(controler) ? leftX : rightX;
}
let rz = zone === EXTRA ? DECK_ROTATE_Z.value : -DECK_ROTATE_Z.value;
rz += isMe(controller) ? 0 : 180;
rz += isMe(controler) ? 0 : 180;
const z = sequence;
api.start({
x,
y,
z,
rz,
ry: isMe(controller) ? (zone === DECK ? 180 : 0) : 180,
ry: isMe(controler) ? (zone === DECK ? 180 : 0) : 180,
zIndex: z,
height: DECK_CARD_HEIGHT.value,
});
......
......@@ -33,11 +33,15 @@ export const moveToGround = async (props: {
const { card, api } = props;
// 如果是超量素材,那么,应该看超量素材所属的xyzMonster
const targetCard =
card.zone === OVERLAY ? (card.xyzMonster ? card.xyzMonster : card) : card;
const targetCard = card.location.is_overlay
? card.xyzMonster
? card.xyzMonster
: card
: card;
const { zone, sequence, controller, xyzMonster, position, overlayMaterials } =
targetCard;
const { location, xyzMonster, overlayMaterials } = targetCard;
const { controler, zone, sequence, position } = location;
// 根据zone计算卡片的宽度
const cardWidth =
......@@ -80,7 +84,7 @@ export const moveToGround = async (props: {
}
}
if (!isMe(controller)) {
if (!isMe(controler)) {
x = -x;
y = -y;
}
......@@ -92,7 +96,7 @@ export const moveToGround = async (props: {
ygopro.CardPosition.FACEUP_DEFENSE,
].includes(position ?? 5);
height = defence ? BLOCK_WIDTH.value : height;
let rz = isMe(controller) ? 0 : 180;
let rz = isMe(controler) ? 0 : 180;
rz += defence ? 90 : 0;
// 动画
......
......@@ -28,7 +28,7 @@ const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, SZONE, TZONE } =
export const moveToHand = async (props: { card: CardType; api: SpringApi }) => {
const { card, api } = props;
const { zone, sequence, controller } = card;
const { zone, sequence, controler } = card.location;
// 手卡会有很复杂的计算...
const hand_circle_center_x = 0;
const hand_circle_center_y =
......@@ -48,22 +48,22 @@ export const moveToHand = async (props: { card: CardType; api: SpringApi }) => {
) *
0.9;
// 接下来计算每一张手卡
const hands_length = cardStore.at(HAND, controller).length;
const hands_length = cardStore.at(HAND, controler).length;
const angle = (sequence - (hands_length - 1) / 2) * THETA;
const r = HAND_CIRCLE_CENTER_OFFSET_Y.value + HAND_CARD_HEIGHT.value / 2;
const negativeX = Math.sin(angle) * r;
const negativeY = Math.cos(angle) * r + HAND_CARD_HEIGHT.value / 2;
const x = hand_circle_center_x + negativeX * (isMe(controller) ? 1 : -1);
const x = hand_circle_center_x + negativeX * (isMe(controler) ? 1 : -1);
const y = hand_circle_center_y - negativeY + 130; // 常量 是手动调的 这里肯定有问题 有空来修
const _rz = (angle * 180) / Math.PI;
api.start({
x: isMe(controller) ? x : -x,
y: isMe(controller) ? y : -y,
x: isMe(controler) ? x : -x,
y: isMe(controler) ? y : -y,
z: 0,
rz: isMe(controller) ? _rz : 180 - _rz,
ry: isMe(controller) ? 0 : 180,
rz: isMe(controler) ? _rz : 180 - _rz,
ry: isMe(controler) ? 0 : 180,
height: HAND_CARD_HEIGHT.value,
zIndex: sequence,
// rx: -PLANE_ROTATE_X.value,
......
......@@ -32,12 +32,12 @@ export const moveToOutside = async (props: {
}) => {
const { card, api } = props;
// report
const { zone, sequence, controller, xyzMonster, position, overlayMaterials } =
card;
const { xyzMonster, overlayMaterials } = card;
const { zone, sequence, controler, position } = card.location;
let x = (BLOCK_WIDTH.value + COL_GAP.value) * 3,
y = zone === GRAVE ? BLOCK_HEIGHT_M.value + ROW_GAP.value : 0;
if (!isMe(controller)) {
if (!isMe(controler)) {
x = -x;
y = -y;
}
......@@ -46,7 +46,7 @@ export const moveToOutside = async (props: {
y,
z: 0,
height: BLOCK_HEIGHT_S.value,
rz: isMe(controller) ? 0 : 180,
rz: isMe(controler) ? 0 : 180,
ry: [ygopro.CardPosition.FACEDOWN].includes(position) ? 180 : 0,
});
};
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