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.
503 lines
21 KiB
503 lines
21 KiB
import {
|
|
BattleBagCardKind,
|
|
canDragMapTile,
|
|
canDropWeapon2OnCell,
|
|
isElementGlyphType,
|
|
MapCellKind,
|
|
PlaceRejectReason,
|
|
rejectReasonToMessage,
|
|
Weapon2TileType,
|
|
TileSource,
|
|
} from 'db://assets/mx/module/merge';
|
|
import type { BattleBagSession } from '../bag/BattleBagSession';
|
|
import { WeaponComposeConfigProvider } from '../bag/WeaponComposeConfigProvider';
|
|
import type { MapGrid } from '../map/legacy/MapGrid';
|
|
import type { MapManager } from '../map/legacy/MapManager';
|
|
import { unlockHeroTypeName } from '../map/legacy/MapAreaUnlock';
|
|
|
|
/** 地图格在拖拽悬停中的落子语义 */
|
|
export type MapDragDropState = 'valid' | 'blocked' | 'none';
|
|
|
|
/** 拖拽跟随字块上的落子提示(textGrid select / redSelect) */
|
|
export type DragPlacementHint = 'valid' | 'blocked' | 'off';
|
|
|
|
/** 拖字来源快照(升级判定用) */
|
|
export interface DragTileSourceInfo {
|
|
/** Weapon2.id */
|
|
weapon2Id: number;
|
|
/** 背包合成后的 Weapon1(单字) */
|
|
weapon1Id?: number;
|
|
/** 字块等级 */
|
|
level?: number;
|
|
/** 字块来源(用于 functiontype=3 的未开挖格规则) */
|
|
source?: TileSource;
|
|
/** 地图拖起原格;同组合内互拖时排除升级提示 */
|
|
fromMapGrid?: number;
|
|
/** 局内产卡种类(倍率卡/属性卡) */
|
|
battleCardKind?: number;
|
|
}
|
|
|
|
/** 拖拽期间高亮可落子格(加号仅 valid;type3 blocked 可走格仅红底) */
|
|
export class MapDragGuideHelper {
|
|
/**
|
|
* @param source 拖字来源快照;须带 source= PassiveFunction3 时未开挖格才有引导
|
|
*/
|
|
static show(
|
|
map: MapManager,
|
|
session: BattleBagSession,
|
|
weapon2Id: number,
|
|
source?: Omit<DragTileSourceInfo, 'weapon2Id'>,
|
|
): void {
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const grids = map.mapGrids;
|
|
if (!Array.isArray(grids)) return;
|
|
const w2Type = Number(
|
|
WeaponComposeConfigProvider.instance.getWeapon2Type(weapon2Id),
|
|
) as Weapon2TileType;
|
|
const dragSource: DragTileSourceInfo = { weapon2Id, ...source };
|
|
for (const mg of grids) {
|
|
if (!mg?.node?.isValid || !mg.node.active) continue;
|
|
mg.showWalkSprite = false;
|
|
mg.showBlockedWalkSprite = false;
|
|
mg.isGuideStatus = false;
|
|
mg.isBlockedGuideStatus = false;
|
|
const state = MapDragGuideHelper.getMapDragDropState(session, w2Type, mg, dragSource);
|
|
MapDragGuideHelper._applyMapDragGuideVisual(mg, w2Type, state);
|
|
}
|
|
}
|
|
|
|
static liveCellKind(mg: MapGrid): MapCellKind {
|
|
if (mg.isCanWalk) return MapCellKind.Walkable;
|
|
// 可放置优先:dig+putText 双标按 Put
|
|
if (mg.isCanPutText) return MapCellKind.Put;
|
|
if (mg.isAreaUnlock) return MapCellKind.Unlock;
|
|
if (mg.isCanBeDig) return MapCellKind.Dig;
|
|
return MapCellKind.Put;
|
|
}
|
|
|
|
static hasSpiderWeb(mg: MapGrid): boolean {
|
|
if (mg.hasSpiderWeb) return true;
|
|
const silk = mg.node?.getChildByName('spiderSilk');
|
|
return !!silk?.isValid && silk.active;
|
|
}
|
|
|
|
/**
|
|
* 引导加号语义:五行字空 Put 为 valid;待解锁格须类型(0 任意)与显示等级都达标。
|
|
* 已有字块的格不显示 +(升级目标由 isBagDropLineTarget / hover 单独放行)。
|
|
*/
|
|
static getMapDragDropState(
|
|
session: BattleBagSession,
|
|
w2Type: Weapon2TileType,
|
|
mg: MapGrid,
|
|
source?: DragTileSourceInfo,
|
|
): MapDragDropState {
|
|
if (!mg?.node?.isValid) return 'none';
|
|
const gridIndex = mg.Index;
|
|
const hasTile = session.merge.map.hasTile(gridIndex);
|
|
const canPutGrid = !!mg.isCanPutGrid;
|
|
if (MapDragGuideHelper.hasSpiderWeb(mg)) return 'blocked';
|
|
if (source?.weapon2Id != null
|
|
&& WeaponComposeConfigProvider.instance.passiveSpawnKeepsDigCell(source.weapon2Id)) {
|
|
if (!session.validator.isAllowedCampForPlace(gridIndex)) return 'blocked';
|
|
if (hasTile) return 'none';
|
|
if (mg.isCanBeDig && !mg.isCanWalk && mg.unlockAreaId <= 0) return 'valid';
|
|
if (mg.isCanPutText && !mg.isCanBeDig && !mg.isCanWalk) return 'valid';
|
|
if (mg.isCanWalk) return 'blocked';
|
|
return 'none';
|
|
}
|
|
if (source?.source === TileSource.PassiveFunction3) {
|
|
if (mg.isCanBeDig && !mg.isCanWalk && mg.unlockAreaId <= 0) {
|
|
if (!session.validator.isAllowedCampForPlace(gridIndex)) return 'blocked';
|
|
return hasTile ? 'none' : 'valid';
|
|
}
|
|
return hasTile ? 'none' : 'blocked';
|
|
}
|
|
if (isElementGlyphType(w2Type)) {
|
|
// 可放置优先:双标 put+dig 允许落字
|
|
if (mg.isCanPutText && !mg.isCanWalk) {
|
|
if (!session.validator.isAllowedCampForPlace(gridIndex)) return 'blocked';
|
|
if (hasTile) return 'none';
|
|
return 'valid';
|
|
}
|
|
if (mg.waitingUnlock && !hasTile) {
|
|
if (!session.validator.isAllowedCampForPlace(gridIndex)) return 'blocked';
|
|
if (!source || !session.canUnlockArea(gridIndex, source.weapon2Id, source.level)) {
|
|
return 'none';
|
|
}
|
|
return 'valid';
|
|
}
|
|
if (mg.isCanWalk || mg.isCanBeDig) return 'blocked';
|
|
return 'none';
|
|
}
|
|
if (w2Type === Weapon2TileType.Grid) {
|
|
if (!mg.isCanWalk || hasTile) return 'none';
|
|
if (!canPutGrid) return 'blocked';
|
|
if (!session.validator.isAllowedCampForPlace(gridIndex)) return 'blocked';
|
|
if (session.validator.canPlaceType3Grid(gridIndex)) return 'valid';
|
|
return 'blocked';
|
|
}
|
|
return 'none';
|
|
}
|
|
|
|
static getMapHoverHint(
|
|
session: BattleBagSession,
|
|
w2Type: Weapon2TileType,
|
|
mg: MapGrid,
|
|
source?: DragTileSourceInfo,
|
|
): DragPlacementHint {
|
|
const state = MapDragGuideHelper.getMapDragDropState(session, w2Type, mg, source);
|
|
if (state === 'valid') return 'valid';
|
|
if (state === 'blocked') return 'blocked';
|
|
if (source && MapDragGuideHelper._canBattleCardDropOnGrid(session, mg.Index, source)) {
|
|
return 'valid';
|
|
}
|
|
if (source && MapDragGuideHelper._canKeepDigMerge(session, mg.Index, source)) {
|
|
return 'valid';
|
|
}
|
|
if (source && MapDragGuideHelper._canUpgradeDropOnGrid(session, mg.Index, source)) {
|
|
return 'valid';
|
|
}
|
|
if (source && MapDragGuideHelper._canKeepDigSwap(session, mg.Index, source)) {
|
|
return 'valid';
|
|
}
|
|
if (source && MapDragGuideHelper._canSwapDropOnGrid(session, mg.Index, source)) {
|
|
return 'valid';
|
|
}
|
|
return 'off';
|
|
}
|
|
|
|
static getMapDropFailMessage(
|
|
session: BattleBagSession,
|
|
w2Type: Weapon2TileType,
|
|
mg: MapGrid,
|
|
source?: DragTileSourceInfo,
|
|
): string {
|
|
if (MapDragGuideHelper.getMapDragDropState(session, w2Type, mg, source) === 'valid') {
|
|
return '';
|
|
}
|
|
if (source && MapDragGuideHelper._canBattleCardDropOnGrid(session, mg.Index, source)) {
|
|
return '';
|
|
}
|
|
if (source && MapDragGuideHelper._canKeepDigMerge(session, mg.Index, source)) {
|
|
return '';
|
|
}
|
|
if (source && MapDragGuideHelper._canUpgradeDropOnGrid(session, mg.Index, source)) {
|
|
return '';
|
|
}
|
|
if (source && MapDragGuideHelper._canKeepDigSwap(session, mg.Index, source)) {
|
|
return '';
|
|
}
|
|
if (source && MapDragGuideHelper._canSwapDropOnGrid(session, mg.Index, source)) {
|
|
return '';
|
|
}
|
|
return MapDragGuideHelper.getBlockedDropMessage(session, w2Type, mg);
|
|
}
|
|
|
|
static getBlockedDropMessage(
|
|
session: BattleBagSession,
|
|
w2Type: Weapon2TileType,
|
|
mg: MapGrid,
|
|
): string {
|
|
if (!session.validator.isAllowedCampForPlace(mg.Index)) {
|
|
return rejectReasonToMessage(PlaceRejectReason.WrongCampArea);
|
|
}
|
|
if (mg.waitingUnlock && isElementGlyphType(w2Type)) {
|
|
const needType = session.currentUnlockNeedHeroType(mg.Index);
|
|
const name = unlockHeroTypeName(needType);
|
|
if (needType > 0 && name && Math.floor(Number(w2Type) || 0) !== needType) {
|
|
return `需要用${name}属性数字解锁`;
|
|
}
|
|
}
|
|
if (MapDragGuideHelper.hasSpiderWeb(mg) && w2Type === Weapon2TileType.Grid) {
|
|
return rejectReasonToMessage(PlaceRejectReason.SpiderWebBlocked);
|
|
}
|
|
if (w2Type === Weapon2TileType.Grid) {
|
|
const cellKind = MapDragGuideHelper.liveCellKind(mg);
|
|
const hasTile = session.merge.map.hasTile(mg.Index);
|
|
const canPutGrid = !!mg.isCanPutGrid;
|
|
if (
|
|
cellKind === MapCellKind.Walkable
|
|
&& !hasTile
|
|
&& canPutGrid
|
|
&& !session.validator.canPlaceType3Grid(mg.Index)
|
|
) {
|
|
return rejectReasonToMessage(PlaceRejectReason.PathBlocked);
|
|
}
|
|
}
|
|
return rejectReasonToMessage(PlaceRejectReason.WrongCellKind);
|
|
}
|
|
|
|
/**
|
|
* 拉线松手可落点:空可放置格,或已占格上的升级 / 交换。
|
|
*/
|
|
static isBagDropLineTarget(
|
|
map: MapManager,
|
|
session: BattleBagSession,
|
|
source: DragTileSourceInfo,
|
|
gridIndex: number,
|
|
): boolean {
|
|
const mg = map.getMapGridByIndex(gridIndex);
|
|
if (!mg?.node?.isValid || !mg.node.active) return false;
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const w2Type = Number(
|
|
WeaponComposeConfigProvider.instance.getWeapon2Type(source.weapon2Id),
|
|
) as Weapon2TileType;
|
|
if (MapDragGuideHelper.getMapDragDropState(session, w2Type, mg, source) === 'valid') {
|
|
return true;
|
|
}
|
|
if (MapDragGuideHelper._canBattleCardDropOnGrid(session, gridIndex, source)) {
|
|
return true;
|
|
}
|
|
if (MapDragGuideHelper._canKeepDigMerge(session, gridIndex, source)) {
|
|
return true;
|
|
}
|
|
if (MapDragGuideHelper._canUpgradeDropOnGrid(session, gridIndex, source)) {
|
|
return true;
|
|
}
|
|
if (MapDragGuideHelper._canKeepDigSwap(session, gridIndex, source)) {
|
|
return true;
|
|
}
|
|
return MapDragGuideHelper._canSwapDropOnGrid(session, gridIndex, source);
|
|
}
|
|
|
|
static isType3SpiderWebBlockedDrop(
|
|
map: MapManager,
|
|
session: BattleBagSession,
|
|
weapon2Id: number,
|
|
gridIndex: number,
|
|
): boolean {
|
|
const mg = map.getMapGridByIndex(gridIndex);
|
|
if (!mg?.node?.isValid || !mg.node.active) return false;
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const w2Type = Number(
|
|
WeaponComposeConfigProvider.instance.getWeapon2Type(weapon2Id),
|
|
) as Weapon2TileType;
|
|
if (isElementGlyphType(w2Type) || w2Type !== Weapon2TileType.Grid) return false;
|
|
if (WeaponComposeConfigProvider.instance.passiveSpawnKeepsDigCell(weapon2Id)) return false;
|
|
if (!MapDragGuideHelper.hasSpiderWeb(mg)) return false;
|
|
return MapDragGuideHelper.getMapDragDropState(session, w2Type, mg, { weapon2Id }) === 'blocked';
|
|
}
|
|
|
|
static isType3PathBlockedDrop(
|
|
map: MapManager,
|
|
session: BattleBagSession,
|
|
weapon2Id: number,
|
|
gridIndex: number,
|
|
): boolean {
|
|
const mg = map.getMapGridByIndex(gridIndex);
|
|
if (!mg?.node?.isValid || !mg.node.active) return false;
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const w2Type = Number(
|
|
WeaponComposeConfigProvider.instance.getWeapon2Type(weapon2Id),
|
|
) as Weapon2TileType;
|
|
if (isElementGlyphType(w2Type) || w2Type !== Weapon2TileType.Grid) return false;
|
|
if (MapDragGuideHelper.hasSpiderWeb(mg)) return false;
|
|
const cellKind = MapDragGuideHelper.liveCellKind(mg);
|
|
const hasTile = session.merge.map.hasTile(gridIndex);
|
|
const canPutGrid = !!mg.isCanPutGrid;
|
|
if (!canDropWeapon2OnCell(w2Type, cellKind, hasTile, canPutGrid)) return false;
|
|
return !session.validator.canPlaceType3Grid(gridIndex);
|
|
}
|
|
|
|
static clear(map: MapManager | null): void {
|
|
if (!map) return;
|
|
const grids = map.mapGrids;
|
|
if (!Array.isArray(grids)) return;
|
|
for (const mg of grids) {
|
|
if (!mg?.node?.isValid) continue;
|
|
mg.isGuideStatus = false;
|
|
mg.isBlockedGuideStatus = false;
|
|
mg.showWalkSprite = false;
|
|
mg.showBlockedWalkSprite = false;
|
|
}
|
|
}
|
|
|
|
/** 来源是否为 functiontype=3 产字 */
|
|
private static _isFunction3Source(source?: DragTileSourceInfo): boolean {
|
|
return source?.source === TileSource.PassiveFunction3;
|
|
}
|
|
|
|
/** 未开挖格上的 keepDig 文字可与同来源/同 id 文字合成 */
|
|
private static _canKeepDigMerge(
|
|
session: BattleBagSession,
|
|
gridIndex: number,
|
|
source: DragTileSourceInfo,
|
|
): boolean {
|
|
const target = session.merge.map.getTile(gridIndex);
|
|
if (!target || target.weapon2Id !== source.weapon2Id) return false;
|
|
if ((target.level ?? 1) !== (source.level ?? 1)) return false;
|
|
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const provider = WeaponComposeConfigProvider.instance;
|
|
const sourceFunction3 = MapDragGuideHelper._isFunction3Source(source);
|
|
const targetFunction3 = target.source === TileSource.PassiveFunction3;
|
|
if (sourceFunction3 || targetFunction3) {
|
|
if (!(sourceFunction3 && targetFunction3)) return false;
|
|
const weapon1Id = (source.weapon1Id && source.weapon1Id > 0)
|
|
? source.weapon1Id
|
|
: provider.getWeapon1ByGroupSequence([source.weapon2Id]);
|
|
if (weapon1Id == null) return false;
|
|
return (source.level ?? 1) < provider.getMaxWeaponLevel(weapon1Id);
|
|
}
|
|
|
|
if (!provider.passiveSpawnKeepsDigCell(source.weapon2Id)) return false;
|
|
if (!provider.passiveSpawnKeepsDigCell(target.weapon2Id)) return false;
|
|
return (source.level ?? 1) < provider.getKeepDigTileMaxLevel(source.weapon2Id);
|
|
}
|
|
|
|
/** 两棵保持 Dig 的蟠桃树不能合成时允许交换 */
|
|
private static _canKeepDigSwap(
|
|
session: BattleBagSession,
|
|
gridIndex: number,
|
|
source: DragTileSourceInfo,
|
|
): boolean {
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const provider = WeaponComposeConfigProvider.instance;
|
|
if (!provider.passiveSpawnKeepsDigCell(source.weapon2Id)) return false;
|
|
const target = session.merge.map.getTile(gridIndex);
|
|
if (!target) return false;
|
|
if (!provider.passiveSpawnKeepsDigCell(target.weapon2Id)) return false;
|
|
if (!session.validator.isAllowedCampForPlace(gridIndex)) return false;
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* 倍率卡/属性卡可落到己方阵营已占的五行字上(含已激活上阵)。
|
|
* @param session 背包会话
|
|
* @param gridIndex 地图格
|
|
* @param source 拖拽来源
|
|
*/
|
|
private static _canBattleCardDropOnGrid(
|
|
session: BattleBagSession,
|
|
gridIndex: number,
|
|
source: DragTileSourceInfo,
|
|
): boolean {
|
|
const kind = Math.floor(Number(source.battleCardKind) || 0);
|
|
if (kind !== BattleBagCardKind.Multiplier && kind !== BattleBagCardKind.Attr) return false;
|
|
const tile = session.merge.map.getTile(gridIndex);
|
|
if (!tile || tile.battleCardKind) return false;
|
|
if (!session.validator.isAllowedCampForPlace(gridIndex)) return false;
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const dstType = Math.floor(WeaponComposeConfigProvider.instance.getWeapon2Type(tile.weapon2Id));
|
|
return isElementGlyphType(dstType);
|
|
}
|
|
|
|
private static _canUpgradeDropOnGrid(
|
|
session: BattleBagSession,
|
|
gridIndex: number,
|
|
source: DragTileSourceInfo,
|
|
): boolean {
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const provider = WeaponComposeConfigProvider.instance;
|
|
const w2Type = Number(provider.getWeapon2Type(source.weapon2Id)) as Weapon2TileType;
|
|
if (!isElementGlyphType(w2Type)) return false;
|
|
const tile = session.merge.map.getTile(gridIndex);
|
|
if (!tile) return false;
|
|
if (!session.validator.isAllowedCampForPlace(gridIndex)) return false;
|
|
if (source.fromMapGrid != null && source.fromMapGrid === gridIndex) return false;
|
|
const srcLevel = Math.floor(source.level ?? 1);
|
|
const dstLevel = Math.floor(tile.level ?? 1);
|
|
const dstType = Math.floor(provider.getWeapon2Type(tile.weapon2Id));
|
|
if (dstType !== w2Type || srcLevel !== dstLevel) return false;
|
|
return srcLevel < provider.getElementMaxLevel(w2Type);
|
|
}
|
|
|
|
/**
|
|
* 已占可放置格:双方均为 type1/2 且目标可拖起时交换(与 MergeSession 一致)。
|
|
*/
|
|
private static _canSwapDropOnGrid(
|
|
session: BattleBagSession,
|
|
gridIndex: number,
|
|
source: DragTileSourceInfo,
|
|
): boolean {
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const provider = WeaponComposeConfigProvider.instance;
|
|
const srcType = Number(provider.getWeapon2Type(source.weapon2Id)) as Weapon2TileType;
|
|
if (!isElementGlyphType(srcType)) {
|
|
return false;
|
|
}
|
|
const tile = session.merge.map.getTile(gridIndex);
|
|
if (!tile) return false;
|
|
if (!session.validator.isAllowedCampForPlace(gridIndex)) return false;
|
|
if (session.validator.getLiveCellKind(gridIndex) !== MapCellKind.Put) return false;
|
|
const dstType = Number(provider.getWeapon2Type(tile.weapon2Id)) as Weapon2TileType;
|
|
if (!isElementGlyphType(dstType)) {
|
|
return false;
|
|
}
|
|
return canDragMapTile(tile, dstType, false);
|
|
}
|
|
|
|
private static _applyMapDragGuideVisual(
|
|
mg: MapGrid,
|
|
w2Type: Weapon2TileType,
|
|
state: MapDragDropState,
|
|
): void {
|
|
if (state === 'none') return;
|
|
if (state === 'valid') {
|
|
if (w2Type === Weapon2TileType.Grid) {
|
|
mg.showWalkSprite = true;
|
|
}
|
|
mg.isGuideStatus = true;
|
|
return;
|
|
}
|
|
if (w2Type === Weapon2TileType.Grid) {
|
|
mg.showBlockedWalkSprite = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 己方阵营背包中是否存在任一字块可落到地图(空 Put / 升级 / 交换,与拉线落子一致)。
|
|
* @param campAreaId CampAreaID(本机 0→1、敌方 1→2)
|
|
*/
|
|
static hasLocalCampBagPlacement(session: BattleBagSession, map: MapManager, campAreaId: number): boolean {
|
|
WeaponComposeConfigProvider.instance.load();
|
|
const slots = session.getBagSlots();
|
|
const grids = map.mapGrids;
|
|
if (!Array.isArray(grids)) return false;
|
|
for (let si = 0; si < slots.length; si++) {
|
|
const slot = slots[si];
|
|
if (!slot) continue;
|
|
const source: DragTileSourceInfo = {
|
|
weapon2Id: slot.weapon2Id,
|
|
weapon1Id: slot.weapon1Id,
|
|
level: slot.level,
|
|
};
|
|
for (let gi = 0; gi < grids.length; gi++) {
|
|
const mg = grids[gi];
|
|
if (!mg?.node?.isValid || !mg.node.active) continue;
|
|
if ((mg.CampAreaID | 0) !== campAreaId) continue;
|
|
if (MapDragGuideHelper.isBagDropLineTarget(map, session, source, mg.Index)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 己方阵营仍可将五行字放入的空 Put 格数量(与拖拽 + 号一致)。
|
|
* @param campAreaId CampAreaID(本机 0→1、敌方 1→2)
|
|
*/
|
|
static countLocalEmptyPutGrids(session: BattleBagSession, map: MapManager, campAreaId: number): number {
|
|
WeaponComposeConfigProvider.instance.load();
|
|
// 五行落空 Put 规则与具体 type 无关,取 1 作探测类型
|
|
const w2Type = 1 as Weapon2TileType;
|
|
let n = 0;
|
|
const grids = map.mapGrids;
|
|
if (!Array.isArray(grids)) return 0;
|
|
for (const mg of grids) {
|
|
if (!mg?.node?.isValid || !mg.node.active) continue;
|
|
if ((mg.CampAreaID | 0) !== campAreaId) continue;
|
|
if (MapDragGuideHelper.getMapDragDropState(session, w2Type, mg) === 'valid') {
|
|
n++;
|
|
}
|
|
}
|
|
return n;
|
|
}
|
|
|
|
/** 己方阵营是否仍有可放置空 Put */
|
|
static hasLocalEmptyPutGrid(session: BattleBagSession, map: MapManager, campAreaId: number): boolean {
|
|
return MapDragGuideHelper.countLocalEmptyPutGrids(session, map, campAreaId) > 0;
|
|
}
|
|
}
|
|
|