You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
AdLike2048/assets/mx/module/merge/rules/MapPlaceRules.ts

150 lines
4.8 KiB

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;
}
/**
* 背包功能符:Text.type 10–13(双倍符/四倍符/随机牌/衰弱符)。
* @param weapon2Type Text.type
*/
export function isBagToolTextType(weapon2Type: number): boolean {
const t = Math.floor(Number(weapon2Type));
return t >= 10 && t <= 13;
}
/**
* 铲子:Text.type 14(开挖 Dig→Put;与遗留 Weapon2TileType.Shovel=4 无关)。
* @param weapon2Type Text.type
*/
export function isShovelTextType(weapon2Type: number): boolean {
return Math.floor(Number(weapon2Type)) === 14;
}
/**
* 功能符背包展示预制体名(battleHero/prefab/buff)。
* @param weapon2Type Text.type
*/
export function bagToolPrefabName(weapon2Type: number): string | null {
switch (Math.floor(Number(weapon2Type))) {
case 10: return '双倍符';
case 11: return '四倍符';
case 12: return '随机牌';
case 13: return '衰弱符';
default: return null;
}
}
/**
* 功能符等级增量:+1/+2/-1;随机牌返回 0。
* @param weapon2Type Text.type
*/
export function bagToolLevelDelta(weapon2Type: number): number {
switch (Math.floor(Number(weapon2Type))) {
case 10: return 1;
case 11: return 2;
case 13: return -1;
default: return 0;
}
}
/** 根据 Weapon2.type 判断能否落到该格(五行字只认空 Put;铲只认空 Dig) */
export function canDropWeapon2OnCell(
weapon2Type: Weapon2TileType,
cellKind: MapCellKind,
hasTile: boolean,
canPutGrid = false,
): boolean {
if (hasTile) return false;
const t = Number(weapon2Type);
if (isShovelTextType(t)) return cellKind === MapCellKind.Dig;
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.MinLevel:
return '数字已是最小值,无法使用';
case PlaceRejectReason.BagFull:
return '背包已满';
case PlaceRejectReason.SpiderWebBlocked:
return '此处不能放置!';
case PlaceRejectReason.WrongCampArea:
return '只能放在己方区域';
default:
return '';
}
}