|
|
|
|
import { MapCellKind, PlaceRejectReason, TileSource, Weapon2TileType, type MapTileRecord } from '../types/MergeTypes';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 新产品五行字:Text.type 1–5(金木水火土),与旧 Single/Combo/Grid 枚举值重叠(type=4 与遗留 Shovel 同值)。
|
|
|
|
|
* @param weapon2Type Text.type
|
|
|
|
|
*/
|
|
|
|
|
export function isElementGlyphType(weapon2Type: number): boolean {
|
|
|
|
|
const t = Math.floor(Number(weapon2Type));
|
|
|
|
|
return t >= 1 && t <= 5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 根据 Weapon2.type 判断能否落到该格(五行字只认空 Put) */
|
|
|
|
|
export function canDropWeapon2OnCell(
|
|
|
|
|
weapon2Type: Weapon2TileType,
|
|
|
|
|
cellKind: MapCellKind,
|
|
|
|
|
hasTile: boolean,
|
|
|
|
|
canPutGrid = false,
|
|
|
|
|
): boolean {
|
|
|
|
|
if (hasTile) return false;
|
|
|
|
|
const t = Number(weapon2Type);
|
|
|
|
|
if (isElementGlyphType(t)) return cellKind === MapCellKind.Put;
|
|
|
|
|
switch (t) {
|
|
|
|
|
case Weapon2TileType.Grid:
|
|
|
|
|
return cellKind === MapCellKind.Walkable && canPutGrid;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** type3 落子后:不可通行 + 可放置(由 MapGrid 自行刷新背景) */
|
|
|
|
|
export function cellKindAfterType3Place(): MapCellKind {
|
|
|
|
|
return MapCellKind.Put;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** type4 落子后的格语义 */
|
|
|
|
|
export function cellKindAfterType4Place(): MapCellKind {
|
|
|
|
|
return MapCellKind.Put;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 拖回背包后 type1/2 原格恢复为空的可放置格 */
|
|
|
|
|
export function cellKindAfterReturnToBag(): MapCellKind {
|
|
|
|
|
return MapCellKind.Put;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** type3 拖起/撤销后恢复可行走 */
|
|
|
|
|
export function cellKindAfterType3Pickup(): MapCellKind {
|
|
|
|
|
return MapCellKind.Walkable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 备战阶段该字块是否可再拖 */
|
|
|
|
|
export function canDragMapTile(
|
|
|
|
|
tile: MapTileRecord,
|
|
|
|
|
weapon2Type: Weapon2TileType,
|
|
|
|
|
isBuiltinPutWithoutTile: boolean,
|
|
|
|
|
): boolean {
|
|
|
|
|
const t = Number(weapon2Type);
|
|
|
|
|
if (isElementGlyphType(t)) return true;
|
|
|
|
|
switch (t) {
|
|
|
|
|
case Weapon2TileType.Grid:
|
|
|
|
|
return tile.source === TileSource.PrepPlaced && !isBuiltinPutWithoutTile;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** type3 落子后可再拖动的时长(毫秒) */
|
|
|
|
|
export const PREP_TYPE3_MOVE_WINDOW_MS = 5000;
|
|
|
|
|
|
|
|
|
|
/** 备战 type3 扩展格(无字块节点)是否可拖起(落子后限时) */
|
|
|
|
|
export function canDragPrepType3Cell(
|
|
|
|
|
isPrepType3: boolean,
|
|
|
|
|
hasTile: boolean,
|
|
|
|
|
placedAtMs: number | null = null,
|
|
|
|
|
nowMs: number = Date.now(),
|
|
|
|
|
): boolean {
|
|
|
|
|
if (!isPrepType3 || hasTile || placedAtMs == null) return false;
|
|
|
|
|
return nowMs - placedAtMs < PREP_TYPE3_MOVE_WINDOW_MS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function rejectReasonToMessage(reason: PlaceRejectReason): string {
|
|
|
|
|
switch (reason) {
|
|
|
|
|
case PlaceRejectReason.PathBlocked:
|
|
|
|
|
return '不能将路径堵死';
|
|
|
|
|
case PlaceRejectReason.WrongCellKind:
|
|
|
|
|
return '不能放在这里';
|
|
|
|
|
case PlaceRejectReason.CellOccupied:
|
|
|
|
|
return '格子已被占用';
|
|
|
|
|
case PlaceRejectReason.NotDraggable:
|
|
|
|
|
return '该格子不可移动';
|
|
|
|
|
case PlaceRejectReason.InvalidMerge:
|
|
|
|
|
return '无法升级';
|
|
|
|
|
case PlaceRejectReason.MaxLevel:
|
|
|
|
|
return '已达最高等级';
|
|
|
|
|
case PlaceRejectReason.BagFull:
|
|
|
|
|
return '背包已满';
|
|
|
|
|
case PlaceRejectReason.SpiderWebBlocked:
|
|
|
|
|
return '此处不能放置!';
|
|
|
|
|
case PlaceRejectReason.WrongCampArea:
|
|
|
|
|
return '只能放在己方区域';
|
|
|
|
|
case PlaceRejectReason.UnlockDrag:
|
|
|
|
|
return '';
|
|
|
|
|
case PlaceRejectReason.UnlockNeedElement:
|
|
|
|
|
return '';
|
|
|
|
|
default:
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|