// ============================================================================ // 02_SubGame_Input.js —— 平台输入/回调接口「转发壳」(框架维护,子游戏不碰) // 平台按全局名调用 gameHallImport.* / Game_Modify.*;本文件统一转发到 SubGameHooks 同名 hook。 // 子游戏只需在 codes/ 的 SubGameHooks 里实现需要的接口(见 codes/SubGameHooks.js)。 // 严格 ES5。接口清单与默认值依据 spec §9。 // ============================================================================ var gameHallImport = gameHallImport || {}; var Game_Modify = Game_Modify || {}; // ============================================================================ // gameHallImport.* — 大厅接口(9 个) // ============================================================================ // A 类:纯子游戏行为,无 hook 即 no-op // 注:与 Game_Modify.appStart 同名但语义不同(大厅启动 vs 游戏启动),故 hook 名加 hall 前缀区分 gameHallImport.appStart = function () { if (window.SubGameHooks && SubGameHooks.hallAppStart) return SubGameHooks.hallAppStart(); }; // A 类:纯子游戏行为,无 hook 即 no-op gameHallImport.jumpMenuScene = function () { if (window.SubGameHooks && SubGameHooks.jumpMenuScene) return SubGameHooks.jumpMenuScene(); }; // A 类:纯子游戏行为,无 hook 即 no-op gameHallImport.gameStart = function () { if (window.SubGameHooks && SubGameHooks.gameStart) return SubGameHooks.gameStart(); }; // A 类:纯子游戏行为,无 hook 即 no-op gameHallImport.setGameList = function () { if (window.SubGameHooks && SubGameHooks.setGameList) return SubGameHooks.setGameList(); }; // A 类:纯子游戏行为,无 hook 即 no-op gameHallImport.clearGameinfo = function () { if (window.SubGameHooks && SubGameHooks.clearGameinfo) return SubGameHooks.clearGameinfo(); }; // A 类:纯子游戏行为,无 hook 即 no-op gameHallImport.getWebdata = function (data) { if (window.SubGameHooks && SubGameHooks.getWebdata) return SubGameHooks.getWebdata(data); }; // B 类:有平台默认返回值,无 hook 即返回默认 gameHallImport.isInstalled = function (data) { if (window.SubGameHooks && SubGameHooks.isInstalled) return SubGameHooks.isInstalled(data); return 1; }; // A 类:纯子游戏行为,无 hook 即 no-op gameHallImport.up_imgurl = function (recid, photo) { if (window.SubGameHooks && SubGameHooks.up_imgurl) return SubGameHooks.up_imgurl(recid, photo); }; // A 类:纯子游戏行为,无 hook 即 no-op gameHallImport.getphoto = function (recid, photo) { if (window.SubGameHooks && SubGameHooks.getphoto) return SubGameHooks.getphoto(recid, photo); }; // ============================================================================ // Game_Modify.* — 生命周期/回调接口(来自 02,45 个) // ============================================================================ // A 类:纯子游戏行为,无 hook 即 no-op Game_Modify.appStart = function () { if (window.SubGameHooks && SubGameHooks.appStart) return SubGameHooks.appStart(); }; // A 类:开战回调,无 hook 即 no-op Game_Modify.StartWar = function (_msg) { if (window.SubGameHooks && SubGameHooks.StartWar) return SubGameHooks.StartWar(_msg); }; // A 类:接收数据包,无 hook 即 no-op Game_Modify._ReceiveData = function (_msg) { if (window.SubGameHooks && SubGameHooks._ReceiveData) return SubGameHooks._ReceiveData(_msg); }; // A 类:创建房间,无 hook 即 no-op Game_Modify.createRoom = function (_roomtype, _infinite) { if (window.SubGameHooks && SubGameHooks.createRoom) return SubGameHooks.createRoom(_roomtype, _infinite); }; // A 类:自己进入房间,无 hook 即 no-op Game_Modify.myJoinRoom = function (_msg) { if (window.SubGameHooks && SubGameHooks.myJoinRoom) return SubGameHooks.myJoinRoom(_msg); }; // A 类:重连,无 hook 即 no-op Game_Modify.Reconnect = function (_deskinfo) { if (window.SubGameHooks && SubGameHooks.Reconnect) return SubGameHooks.Reconnect(_deskinfo); }; // A 类:关闭所有声音,无 hook 即 no-op Game_Modify.stopAllSounds = function () { if (window.SubGameHooks && SubGameHooks.stopAllSounds) return SubGameHooks.stopAllSounds(); }; // A 类:投票解散确认,无 hook 即 no-op Game_Modify.Free = function (_msg) { if (window.SubGameHooks && SubGameHooks.Free) return SubGameHooks.Free(_msg); }; // A 类:未开战状态加入牌桌数据,无 hook 即 no-op Game_Modify.DeskInfo = function (_msg) { if (window.SubGameHooks && SubGameHooks.DeskInfo) return SubGameHooks.DeskInfo(_msg); }; // A 类:开局后自己退出房间,无 hook 即 no-op Game_Modify.breakRoom = function () { if (window.SubGameHooks && SubGameHooks.breakRoom) return SubGameHooks.breakRoom(); }; // A 类:其他玩家加入房间,无 hook 即 no-op Game_Modify.playerJoinRoom = function (seat) { if (window.SubGameHooks && SubGameHooks.playerJoinRoom) return SubGameHooks.playerJoinRoom(seat); }; // A 类:其他玩家离开房间,无 hook 即 no-op Game_Modify.playerLeaveRoom = function (seat) { if (window.SubGameHooks && SubGameHooks.playerLeaveRoom) return SubGameHooks.playerLeaveRoom(seat); }; // A 类:更新游戏界面,无 hook 即 no-op Game_Modify.updateScene = function () { if (window.SubGameHooks && SubGameHooks.updateScene) return SubGameHooks.updateScene(); }; // A 类:关闭游戏界面,无 hook 即 no-op Game_Modify.closeGameScene = function () { if (window.SubGameHooks && SubGameHooks.closeGameScene) return SubGameHooks.closeGameScene(); }; // A 类:玩家离线,无 hook 即 no-op Game_Modify.playerOffline = function (seat) { if (window.SubGameHooks && SubGameHooks.playerOffline) return SubGameHooks.playerOffline(seat); }; // A 类:玩家上线,无 hook 即 no-op Game_Modify.playerOnline = function (seat) { if (window.SubGameHooks && SubGameHooks.playerOnline) return SubGameHooks.playerOnline(seat); }; // A 类:玩家电话状态,无 hook 即 no-op Game_Modify.playerphonestate = function (seat, type) { if (window.SubGameHooks && SubGameHooks.playerphonestate) return SubGameHooks.playerphonestate(seat, type); }; // A 类:摇一摇事件,无 hook 即 no-op Game_Modify.shakeEvent = function () { if (window.SubGameHooks && SubGameHooks.shakeEvent) return SubGameHooks.shakeEvent(); }; // A 类:计算结果,无 hook 即 no-op Game_Modify.calResult = function (inputArr) { if (window.SubGameHooks && SubGameHooks.calResult) return SubGameHooks.calResult(inputArr); }; // A 类:进入游戏主场景,无 hook 即 no-op Game_Modify.onEnterMainScene = function (roomtype) { if (window.SubGameHooks && SubGameHooks.onEnterMainScene) return SubGameHooks.onEnterMainScene(roomtype); }; // A 类:退出游戏主场景,无 hook 即 no-op Game_Modify.onExitMainScene = function () { if (window.SubGameHooks && SubGameHooks.onExitMainScene) return SubGameHooks.onExitMainScene(); }; // A 类:获取游戏配置时调用,无 hook 即 no-op Game_Modify.onGameConfig = function (_gameConfig) { if (window.SubGameHooks && SubGameHooks.onGameConfig) return SubGameHooks.onGameConfig(_gameConfig); }; // A 类:进入牌局回放,无 hook 即 no-op Game_Modify.onEnterVideo = function () { if (window.SubGameHooks && SubGameHooks.onEnterVideo) return SubGameHooks.onEnterVideo(); }; // A 类:收到投降回包,无 hook 即 no-op Game_Modify.onSurrender = function (_msg) { if (window.SubGameHooks && SubGameHooks.onSurrender) return SubGameHooks.onSurrender(_msg); }; // A 类:玩家准备触发,无 hook 即 no-op Game_Modify.onReady = function (seat) { if (window.SubGameHooks && SubGameHooks.onReady) return SubGameHooks.onReady(seat); }; // B 类:获取房间描述,无 hook 返回默认文案 Game_Modify.getRoomInfo = function (roomtype, type, tea) { if (window.SubGameHooks && SubGameHooks.getRoomInfo) return SubGameHooks.getRoomInfo(roomtype, type, tea); return "房间描述" + roomtype; }; // B 类:获取房间星星场下限,无 hook 返回默认值 Game_Modify.getStarLimit = function (roomtype) { if (window.SubGameHooks && SubGameHooks.getStarLimit) return SubGameHooks.getStarLimit(roomtype); return 2001000; }; // B 类:获取房间星星场倍数,无 hook 返回默认值 Game_Modify.getMult = function (roomtype, type) { if (window.SubGameHooks && SubGameHooks.getMult) return SubGameHooks.getMult(roomtype, type); return 10000; }; // B 类:获取房间全部信息描述,无 hook 返回默认文案 Game_Modify.getFullRoomInfo = function (roomtype) { if (window.SubGameHooks && SubGameHooks.getFullRoomInfo) return SubGameHooks.getFullRoomInfo(roomtype); return "房间描述" + roomtype; }; // A 类:打开帮助页面,无 hook 即 no-op Game_Modify.onOpenHelp = function (spid) { if (window.SubGameHooks && SubGameHooks.onOpenHelp) return SubGameHooks.onOpenHelp(spid); }; // A 类:显示大厅界面,无 hook 即 no-op Game_Modify.onMainMenuScene = function () { if (window.SubGameHooks && SubGameHooks.onMainMenuScene) return SubGameHooks.onMainMenuScene(); }; // A 类:数字输入框确认回调,无 hook 即 no-op Game_Modify.onCheckInput = function (_result) { if (window.SubGameHooks && SubGameHooks.onCheckInput) return SubGameHooks.onCheckInput(_result); }; // A 类:创建房间成功后触发,无 hook 即 no-op Game_Modify.onCreateRoom = function (_data) { if (window.SubGameHooks && SubGameHooks.onCreateRoom) return SubGameHooks.onCreateRoom(_data); }; // B 类:获取离场限制,无 hook 返回默认值 Game_Modify.getLeaveLimit = function (roomtype) { if (window.SubGameHooks && SubGameHooks.getLeaveLimit) return SubGameHooks.getLeaveLimit(roomtype); return 10; }; // A 类:成功获取定位信息,无 hook 即 no-op Game_Modify.onLocationInfo = function (_locationInfo) { if (window.SubGameHooks && SubGameHooks.onLocationInfo) return SubGameHooks.onLocationInfo(_locationInfo); }; // A 类:进入游戏界面创建牌桌之前,无 hook 即 no-op Game_Modify.onCreateDesk = function (roomtype) { if (window.SubGameHooks && SubGameHooks.onCreateDesk) return SubGameHooks.onCreateDesk(roomtype); }; // B 类:获取是否开启视频功能,无 hook 返回默认值 Game_Modify.getVideoByRoomType = function (roomtype) { if (window.SubGameHooks && SubGameHooks.getVideoByRoomType) return SubGameHooks.getVideoByRoomType(roomtype); return 1; }; // B 类:获取房间顶部描述数组,无 hook 返回默认文案数组 Game_Modify.getRoomTopDescAry = function (roomtype) { if (window.SubGameHooks && SubGameHooks.getRoomTopDescAry) return SubGameHooks.getRoomTopDescAry(roomtype); return ["" + roomtype]; }; // A 类:星星场房间列表,无 hook 即 no-op Game_Modify.getShareRoom = function (_msg) { if (window.SubGameHooks && SubGameHooks.getShareRoom) return SubGameHooks.getShareRoom(_msg); }; // A 类:玩家自己退出房间,无 hook 即 no-op Game_Modify.myExitRoom = function (seat) { if (window.SubGameHooks && SubGameHooks.myExitRoom) return SubGameHooks.myExitRoom(seat); }; // A 类:接收到换座包触发,无 hook 即 no-op Game_Modify.changeSeat = function (seat1, seat2) { if (window.SubGameHooks && SubGameHooks.changeSeat) return SubGameHooks.changeSeat(seat1, seat2); }; // A 类:关闭 vip 选项时调用,无 hook 即 no-op Game_Modify.onCloseVip = function () { if (window.SubGameHooks && SubGameHooks.onCloseVip) return SubGameHooks.onCloseVip(); }; // B 类:判断房间是否为金币场,无 hook 返回默认值(0=非金币场) Game_Modify.getRoomMode = function (roomtype) { if (window.SubGameHooks && SubGameHooks.getRoomMode) return SubGameHooks.getRoomMode(roomtype); return 0; }; // B 类:获取房间最大玩家数量,无 hook 返回默认值 Game_Modify.getMaxPlayerCount = function (roomtype) { if (window.SubGameHooks && SubGameHooks.getMaxPlayerCount) return SubGameHooks.getMaxPlayerCount(roomtype); // 默认值依赖全局 Game_Config(须在本模板之前加载);无则回退 4 return (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; }; // 内部辅助(非平台接口):把相对显示位序 relPos 映射为 { ind:精灵槽, configIndex:物理布局位 }。 // 2/3 人时 ind≠configIndex;无效返回 null。updatePlayerInfoUI 与桌面气泡默认实现共用此映射, // 保证头像面板与聊天/语音气泡落在同一玩家位。 Game_Modify._resolveDisplaySlot = function (relPos, playerCount) { var ind = -1, configIndex = -1; if (playerCount === 2) { if (relPos === 0) { ind = 0; configIndex = 0; } else if (relPos === 1) { ind = 1; configIndex = 2; } } else if (playerCount === 3) { if (relPos === 0) { ind = 0; configIndex = 0; } else if (relPos === 1) { ind = 1; configIndex = 1; } else if (relPos === 2) { ind = 2; configIndex = 3; } } else { if (relPos === 0) { ind = 0; configIndex = 0; } else if (relPos === 1) { ind = 1; configIndex = 1; } else if (relPos === 2) { ind = 2; configIndex = 2; } else if (relPos === 3) { ind = 3; configIndex = 3; } } if (ind === -1) return null; return { ind: ind, configIndex: configIndex }; }; // B 类:更新指定座位的玩家信息 UI(昵称/分数/头像)。 // 有 hook 则委托子游戏;无 hook 时由本模板提供默认头像等 UI 的显示逻辑,其逻辑与子游戏 // codes 内 GameView.updatePlayerInfoUI 保持一致,布局取自 Game_Modify.PLAYER_INFO_LAYOUT(见 01)。 // 精灵操作一律经框架 SpriteManager(setPosition/setSize/setText/show|hideGroup),不直接调 // set_self/set_group 等引擎原语;头像加载走平台 Func.up_imgurl(非精灵原语,SpriteManager 无对应能力)。 // 不引用任何 codes 模块。平台 GameUI.updatePlayerInfoUI 会对每个座位逐一调用本接口,故按单座位渲染。 Game_Modify.updatePlayerInfoUI = function (targetSeat) { if (window.SubGameHooks && SubGameHooks.updatePlayerInfoUI) return SubGameHooks.updatePlayerInfoUI(targetSeat); // ---- 模板默认:与 GameView.updatePlayerInfoUI 一致的单座位渲染 ---- if (typeof Desk === 'undefined' || typeof C_Player === 'undefined' || typeof SpriteManager === 'undefined') return false; var layout = Game_Modify.PLAYER_INFO_LAYOUT; if (!layout || !layout.POSITIONS) return false; if (!Desk.PlayerList || targetSeat < 0 || targetSeat >= Desk.PlayerList.length) return false; var selfSeat = (typeof C_Player.seat === 'number') ? C_Player.seat : 0; var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; var relPos = (targetSeat - selfSeat + playerCount) % playerCount; // 显示槽 ind 与布局位 configIndex(2/3 人时两者不同) var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount); if (!slot) return false; var ind = slot.ind, configIndex = slot.configIndex; var player = Desk.PlayerList[targetSeat]; // 空座位:隐藏该位玩家信息群组 if (!player || !player.playerid || player.playerid === -1) { SpriteManager.hideGroup(43 + ind); return true; } var posConfig = layout.POSITIONS[configIndex]; if (!posConfig) return false; // 底框(346+ind) if (posConfig.FRAME_X !== undefined) { SpriteManager.setPosition(346 + ind, posConfig.FRAME_X, posConfig.FRAME_Y); SpriteManager.setSize(346 + ind, posConfig.FRAME_WIDTH, posConfig.FRAME_HEIGHT); } // 头像框(376+ind):基于底框 + 相对偏移 var avatarX = posConfig.FRAME_X + posConfig.AVATAR.OFFSET_X; var avatarY = posConfig.FRAME_Y + posConfig.AVATAR.OFFSET_Y; var avatarWidth = posConfig.AVATAR.WIDTH; var avatarHeight = posConfig.AVATAR.HEIGHT; var nameOffsetX = posConfig.AVATAR.NAME_OFFSET_X || 0; var nameOffsetY = posConfig.AVATAR.NAME_OFFSET_Y || 0; var scoreOffsetX = posConfig.AVATAR.SCORE_OFFSET_X || 0; var scoreOffsetY = posConfig.AVATAR.SCORE_OFFSET_Y || 0; SpriteManager.setPosition(376 + ind, avatarX, avatarY); SpriteManager.setSize(376 + ind, avatarWidth, avatarHeight); var textStyle = layout.TEXT_STYLE || {}; var maxLen = textStyle.NAME_MAX_LENGTH || 8; var charWidth = textStyle.CHAR_WIDTH || 7; // 昵称(406+ind) var nickname = Func.subString(player.nickname || '', maxLen, true); SpriteManager.setText(406 + ind, nickname); var nameX = avatarX + nameOffsetX; if (posConfig.NAME_CENTER_ALIGN) { var textWidth = (typeof nickname.gblen === 'function') ? nickname.gblen() * charWidth : nickname.length * charWidth; nameX = avatarX + avatarWidth / 2 - textWidth / 2; } SpriteManager.setPosition(406 + ind, nameX, avatarY + nameOffsetY); // 分数(436+ind) var score = (typeof player.score === 'number') ? player.score : 0; SpriteManager.setText(436 + ind, score); var scoreX = avatarX + scoreOffsetX; if (posConfig.NAME_CENTER_ALIGN) { var scoreWidth = String(score).length * charWidth; scoreX = avatarX + avatarWidth / 2 - scoreWidth / 2; } SpriteManager.setPosition(436 + ind, scoreX, avatarY + scoreOffsetY); // 头像图(116+ind):Func.up_imgurl 为平台头像加载接口(非引擎精灵原语) if (player.avatar && typeof Func !== 'undefined' && typeof Func.up_imgurl === 'function') { Func.up_imgurl(116 + ind, player.avatar); } // 显示该座位玩家信息群组 SpriteManager.showGroup(43 + ind); return true; }; // 桌面文字聊天气泡:有 hook 委托子游戏;无 hook 时按【可变人数】默认渲染,使气泡贴合各玩家。 // seat 为绝对座位;经 SpriteManager 操作精灵(背景552+ind/文字582+ind),位置取自 Game_Modify.BUBBLE_LAYOUT // 的物理位配置,尺寸(内边距/字宽/显示时长)复用 Game_Config.Chat/Max;不直接调引擎原语、不引用 codes。 Game_Modify.ShowChat = function (seat, text) { if (window.SubGameHooks && SubGameHooks.ShowChat) return SubGameHooks.ShowChat(seat, text); GameUI.CloseChat(); if (typeof Desk === 'undefined' || typeof C_Player === 'undefined' || typeof SpriteManager === 'undefined') return; var layout = Game_Modify.BUBBLE_LAYOUT; if (!layout || !layout.POSITIONS) return; var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; var relPos = (seat - C_Player.seat + playerCount) % playerCount; var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount); if (!slot) return; var pos = layout.POSITIONS[slot.configIndex]; if (!pos) return; var ind = slot.ind; text = String(text); var chat = Game_Config.Chat || {}; var dis_x = (chat.ChatDis && chat.ChatDis[0]) || 0; var dis_y = (chat.ChatDis && chat.ChatDis[1]) || 0; var text_w = chat.textwidth || 14; var text_len = (typeof text.gblen === 'function') ? text.gblen() : text.length; var bgW = text_len * text_w + dis_x * 2; SpriteManager.setText(582 + ind, text); if (pos.IS_LEFT) { SpriteManager.setPosition(552 + ind, pos.X, pos.Y); SpriteManager.setPosition(582 + ind, pos.X + dis_x, pos.Y + dis_y); SpriteManager.setImage(552 + ind, layout.IMG_LEFT); } else { SpriteManager.setPosition(552 + ind, pos.X - bgW, pos.Y); SpriteManager.setPosition(582 + ind, pos.X - text_len * text_w - dis_x, pos.Y + dis_y); SpriteManager.setImage(552 + ind, layout.IMG_RIGHT); } SpriteManager.setWidth(552 + ind, bgW); SpriteManager.show(552 + ind); SpriteManager.show(582 + ind); // 自动隐藏:复用平台配置的显示时长(观感与固定人数版一致),按槽位去重定时器 var dur = (Game_Config.Max && Game_Config.Max.ShowChat) || 3000; Game_Modify._chatHideTimers = Game_Modify._chatHideTimers || {}; if (Game_Modify._chatHideTimers[ind]) { clearTimeout(Game_Modify._chatHideTimers[ind]); } Game_Modify._chatHideTimers[ind] = setTimeout(function () { SpriteManager.hide(552 + ind); SpriteManager.hide(582 + ind); Game_Modify._chatHideTimers[ind] = null; }, dur); }; // 桌面语音气泡(播放):有 hook 委托子游戏;无 hook 时按【可变人数】默认渲染。 // uiIndex 已是相对显示位序(relPos);经 SpriteManager 操作精灵(背景612+ind/内容642+ind), // 位置取自 Game_Modify.BUBBLE_LAYOUT,气泡宽度依据内容精灵当前宽度;尺寸复用 Game_Config.Voice。 Game_Modify.gameui_play_voice = function (uiIndex) { if (window.SubGameHooks && SubGameHooks.gameui_play_voice) return SubGameHooks.gameui_play_voice(uiIndex); if (typeof SpriteManager === 'undefined') return; var layout = Game_Modify.BUBBLE_LAYOUT; if (!layout || !layout.POSITIONS) return; var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; var relPos = ((Number(uiIndex) % playerCount) + playerCount) % playerCount; var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount); if (!slot) return; var pos = layout.POSITIONS[slot.configIndex]; if (!pos) return; var ind = slot.ind; var voice = Game_Config.Voice || {}; var dis_x = (voice.VoiceDis && voice.VoiceDis[0]) || 0; var dis_y = (voice.VoiceDis && voice.VoiceDis[1]) || 0; var contentSize = SpriteManager.getSize(642 + ind); var text_len = (contentSize && typeof contentSize.width === 'number') ? contentSize.width : 0; var bgW = text_len + dis_x * 2; if (pos.IS_LEFT) { SpriteManager.setPosition(612 + ind, pos.X, pos.Y); SpriteManager.setPosition(642 + ind, pos.X + dis_x, pos.Y + dis_y); SpriteManager.setImage(612 + ind, layout.IMG_LEFT); } else { SpriteManager.setPosition(612 + ind, pos.X - bgW, pos.Y); SpriteManager.setPosition(642 + ind, pos.X - text_len - dis_x, pos.Y + dis_y); SpriteManager.setImage(612 + ind, layout.IMG_RIGHT); } SpriteManager.setWidth(612 + ind, bgW); SpriteManager.show(612 + ind); SpriteManager.show(642 + ind); play_ani(1, 642 + ind, 43, 1, 3, 0, Game_Config.Voice.VoiceTime, 0, 0, 0, 0, 0, 0); }; // 桌面语音气泡(停止):有 hook 委托子游戏;无 hook 时隐藏对应槽位的语音气泡。 Game_Modify.gameui_stop_voice = function (uiIndex) { if (window.SubGameHooks && SubGameHooks.gameui_stop_voice) return SubGameHooks.gameui_stop_voice(uiIndex); if (typeof SpriteManager === 'undefined') return; var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; var relPos = ((Number(uiIndex) % playerCount) + playerCount) % playerCount; var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount); if (!slot) return; var ind = slot.ind; SpriteManager.hide(612 + ind); SpriteManager.hide(642 + ind); };