diff --git a/3dtank.com/play/static/js/unpacked/hornet_bundle.js b/3dtank.com/play/static/js/unpacked/hornet_bundle.js index 75b230b..5d8203d 100644 --- a/3dtank.com/play/static/js/unpacked/hornet_bundle.js +++ b/3dtank.com/play/static/js/unpacked/hornet_bundle.js @@ -438,13 +438,15 @@ } // ===== 获取玩家坦克 ===== - // 优先 ezr_1(当前观察坦克),备用 fzr_1(本地控制坦克),再备用坦克列表第一个 - // checkPosition: 是否检查位置有效性(默认true;测试脚本传false以在死亡状态控制) + // 本地拥有的坦克优先(u10b_1 = onTankPossessed 设置的那辆)。 + // ⚠ 旧顺序先取 t10b_1(当前观察目标):玩家死亡后观察目标会切到别人(甚至敌人), + // 用它当队伍基准会导致「敌我一会儿对一会儿反」。 + // checkPosition: 是否检查位置有效性(默认 true) function GetPlayerTank(gm, checkPosition) { if (checkPosition === undefined) checkPosition = true; - var t = gm.t10b_1; + var t = gm.u10b_1; if (t && (!checkPosition || GetTankPosition(t))) return t; - t = gm.u10b_1; + t = gm.t10b_1; if (t && (!checkPosition || GetTankPosition(t))) return t; try { var tl = gm.m10b_1.j11y(); @@ -456,16 +458,34 @@ return null; } + // 本地队伍缓存:死亡后 u10b_1 会被清空(onTankUnpossessed),不能再用"当前观察目标"推断。 + // 这里记住最后一次有效的本地队伍,整局沿用。 + var LocalTeam = null; + var LocalTeamGm = null; + function RememberLocalTeam(gm) { + if (!ZCt) return; + if (gm !== LocalTeamGm) { LocalTeamGm = gm; LocalTeam = null; } + if (LocalTeam) return; + try { + var t = gm.u10b_1; + if (!t) return; + var Team = ZCt(t); + // 只缓存"非中立"队伍(m2Fn(Team,Team) 为 true 表示同队且非中立) + if (Team && (!m2Fn || m2Fn(Team, Team))) LocalTeam = Team; + } catch (e) {} + } + // ===== 判断是否友方 ===== - // 策略1(优先):ZCt 获取双方队伍ID,m2 比较(同队且非中立) - // 策略2(备用):比较 gm.gzr_1(本地队伍ID)与坦克队伍ID + // 优先用缓存的本地队伍;没有缓存时才退回 playerTank 的队伍 function IsFriendly(tank, playerTank, gm) { - if (!tank || !playerTank) return false; + if (!tank) return false; + if (gm) RememberLocalTeam(gm); if (ZCt && m2Fn) { try { var tankTeam = ZCt(tank); - var playerTeam = ZCt(playerTank); - if (tankTeam && playerTeam) return m2Fn(tankTeam, playerTeam); + var BaseTeam = LocalTeam; + if (!BaseTeam && playerTank) BaseTeam = ZCt(playerTank); + if (tankTeam && BaseTeam) return m2Fn(tankTeam, BaseTeam); } catch(e) {} } try { @@ -815,6 +835,7 @@ // 坦克状态:使用公共库(0=DEAD,1=DEAD_PHANTOM,2=SEMI_ACTIVE,3=ACTIVE,4=DISABLED) var GetTankState = lib.GetTankState; + var GetTankHealth = lib.GetTankHealth; // ===== 获取坦克方向(Kkt 组件的 dzc_1) ===== function getTankDirection(tank) { @@ -1401,10 +1422,11 @@ if (radarY < cy - radius) radarY = cy - radius; if (radarY > cy + radius) radarY = cy + radius; - // 死亡判断(同 3D透视):可见坦克 = ACTIVE(3) 或 SEMI_ACTIVE(2);其余画红 × + // 死亡判断(同 3D透视):可见坦克 = ACTIVE(3) 或 SEMI_ACTIVE(2);其余直接跳过(不再画红叉) + // 辅助:血量归零也视为死亡(状态字段偶有滞后) var tankState = GetTankState(tank); - if (tankState !== 2 && tankState !== 3) { - DrawDeadCross(radarX, radarY); + var hp = GetTankHealth(tank); + if ((tankState !== 2 && tankState !== 3) || (hp && hp.current <= 0)) { deadCount++; continue; } @@ -1617,6 +1639,7 @@ var GetTankState = lib.GetTankState; var IsTankAlive = lib.IsTankAlive; var GetTankName = lib.GetTankName; + var GetTankHealth = lib.GetTankHealth; function GetPlayerTank() { return lib.GetPlayerTank(gm); } function IsFriendly(tank, playerTank) { return lib.IsFriendly(tank, playerTank, gm); } function GetCameraInfo() { @@ -2738,6 +2761,9 @@ var tankState = GetTankState(tank); // 可见坦克 = ACTIVE(3) 或 SEMI_ACTIVE(2)(引擎 s14j() 判定),0/1/4 才跳过 if (tankState !== 2 && tankState !== 3) continue; + // 辅助判死:状态字段有时滞后一帧(爆毁动画期间仍是 ACTIVE),血量归零则不再画 + var hp = GetTankHealth(tank); + if (hp && hp.current <= 0) continue; // 本帧该坦克是否在移动(供「残留节点」检测:坦克在动而节点矩阵不动 = 旧位置遗留) // 用位移的指数滑动平均,而不是「单帧位移 > 10 单位」——后者对慢速移动几乎永远为假, diff --git a/3dtank_bundle.js b/3dtank_bundle.js index 75b230b..5d8203d 100644 --- a/3dtank_bundle.js +++ b/3dtank_bundle.js @@ -438,13 +438,15 @@ } // ===== 获取玩家坦克 ===== - // 优先 ezr_1(当前观察坦克),备用 fzr_1(本地控制坦克),再备用坦克列表第一个 - // checkPosition: 是否检查位置有效性(默认true;测试脚本传false以在死亡状态控制) + // 本地拥有的坦克优先(u10b_1 = onTankPossessed 设置的那辆)。 + // ⚠ 旧顺序先取 t10b_1(当前观察目标):玩家死亡后观察目标会切到别人(甚至敌人), + // 用它当队伍基准会导致「敌我一会儿对一会儿反」。 + // checkPosition: 是否检查位置有效性(默认 true) function GetPlayerTank(gm, checkPosition) { if (checkPosition === undefined) checkPosition = true; - var t = gm.t10b_1; + var t = gm.u10b_1; if (t && (!checkPosition || GetTankPosition(t))) return t; - t = gm.u10b_1; + t = gm.t10b_1; if (t && (!checkPosition || GetTankPosition(t))) return t; try { var tl = gm.m10b_1.j11y(); @@ -456,16 +458,34 @@ return null; } + // 本地队伍缓存:死亡后 u10b_1 会被清空(onTankUnpossessed),不能再用"当前观察目标"推断。 + // 这里记住最后一次有效的本地队伍,整局沿用。 + var LocalTeam = null; + var LocalTeamGm = null; + function RememberLocalTeam(gm) { + if (!ZCt) return; + if (gm !== LocalTeamGm) { LocalTeamGm = gm; LocalTeam = null; } + if (LocalTeam) return; + try { + var t = gm.u10b_1; + if (!t) return; + var Team = ZCt(t); + // 只缓存"非中立"队伍(m2Fn(Team,Team) 为 true 表示同队且非中立) + if (Team && (!m2Fn || m2Fn(Team, Team))) LocalTeam = Team; + } catch (e) {} + } + // ===== 判断是否友方 ===== - // 策略1(优先):ZCt 获取双方队伍ID,m2 比较(同队且非中立) - // 策略2(备用):比较 gm.gzr_1(本地队伍ID)与坦克队伍ID + // 优先用缓存的本地队伍;没有缓存时才退回 playerTank 的队伍 function IsFriendly(tank, playerTank, gm) { - if (!tank || !playerTank) return false; + if (!tank) return false; + if (gm) RememberLocalTeam(gm); if (ZCt && m2Fn) { try { var tankTeam = ZCt(tank); - var playerTeam = ZCt(playerTank); - if (tankTeam && playerTeam) return m2Fn(tankTeam, playerTeam); + var BaseTeam = LocalTeam; + if (!BaseTeam && playerTank) BaseTeam = ZCt(playerTank); + if (tankTeam && BaseTeam) return m2Fn(tankTeam, BaseTeam); } catch(e) {} } try { @@ -815,6 +835,7 @@ // 坦克状态:使用公共库(0=DEAD,1=DEAD_PHANTOM,2=SEMI_ACTIVE,3=ACTIVE,4=DISABLED) var GetTankState = lib.GetTankState; + var GetTankHealth = lib.GetTankHealth; // ===== 获取坦克方向(Kkt 组件的 dzc_1) ===== function getTankDirection(tank) { @@ -1401,10 +1422,11 @@ if (radarY < cy - radius) radarY = cy - radius; if (radarY > cy + radius) radarY = cy + radius; - // 死亡判断(同 3D透视):可见坦克 = ACTIVE(3) 或 SEMI_ACTIVE(2);其余画红 × + // 死亡判断(同 3D透视):可见坦克 = ACTIVE(3) 或 SEMI_ACTIVE(2);其余直接跳过(不再画红叉) + // 辅助:血量归零也视为死亡(状态字段偶有滞后) var tankState = GetTankState(tank); - if (tankState !== 2 && tankState !== 3) { - DrawDeadCross(radarX, radarY); + var hp = GetTankHealth(tank); + if ((tankState !== 2 && tankState !== 3) || (hp && hp.current <= 0)) { deadCount++; continue; } @@ -1617,6 +1639,7 @@ var GetTankState = lib.GetTankState; var IsTankAlive = lib.IsTankAlive; var GetTankName = lib.GetTankName; + var GetTankHealth = lib.GetTankHealth; function GetPlayerTank() { return lib.GetPlayerTank(gm); } function IsFriendly(tank, playerTank) { return lib.IsFriendly(tank, playerTank, gm); } function GetCameraInfo() { @@ -2738,6 +2761,9 @@ var tankState = GetTankState(tank); // 可见坦克 = ACTIVE(3) 或 SEMI_ACTIVE(2)(引擎 s14j() 判定),0/1/4 才跳过 if (tankState !== 2 && tankState !== 3) continue; + // 辅助判死:状态字段有时滞后一帧(爆毁动画期间仍是 ACTIVE),血量归零则不再画 + var hp = GetTankHealth(tank); + if (hp && hp.current <= 0) continue; // 本帧该坦克是否在移动(供「残留节点」检测:坦克在动而节点矩阵不动 = 旧位置遗留) // 用位移的指数滑动平均,而不是「单帧位移 > 10 单位」——后者对慢速移动几乎永远为假, diff --git a/tools/hornet_3d_wireframe.js b/tools/hornet_3d_wireframe.js index d549f57..0154db8 100644 --- a/tools/hornet_3d_wireframe.js +++ b/tools/hornet_3d_wireframe.js @@ -91,7 +91,8 @@ var GetTankPosition = lib.GetTankPosition; var GetTankState = lib.GetTankState; var IsTankAlive = lib.IsTankAlive; - var GetTankName = lib.GetTankName; + var GetTankName = lib.GetTankName; + var GetTankHealth = lib.GetTankHealth; function GetPlayerTank() { return lib.GetPlayerTank(gm); } function IsFriendly(tank, playerTank) { return lib.IsFriendly(tank, playerTank, gm); } function GetCameraInfo() { @@ -1213,6 +1214,9 @@ var tankState = GetTankState(tank); // 可见坦克 = ACTIVE(3) 或 SEMI_ACTIVE(2)(引擎 s14j() 判定),0/1/4 才跳过 if (tankState !== 2 && tankState !== 3) continue; + // 辅助判死:状态字段有时滞后一帧(爆毁动画期间仍是 ACTIVE),血量归零则不再画 + var hp = GetTankHealth(tank); + if (hp && hp.current <= 0) continue; // 本帧该坦克是否在移动(供「残留节点」检测:坦克在动而节点矩阵不动 = 旧位置遗留) // 用位移的指数滑动平均,而不是「单帧位移 > 10 单位」——后者对慢速移动几乎永远为假, diff --git a/tools/hornet_lib.js b/tools/hornet_lib.js index 1b9fc87..7b4f9d2 100644 --- a/tools/hornet_lib.js +++ b/tools/hornet_lib.js @@ -223,13 +223,15 @@ } // ===== 获取玩家坦克 ===== - // 优先 ezr_1(当前观察坦克),备用 fzr_1(本地控制坦克),再备用坦克列表第一个 - // checkPosition: 是否检查位置有效性(默认true;测试脚本传false以在死亡状态控制) + // 本地拥有的坦克优先(u10b_1 = onTankPossessed 设置的那辆)。 + // ⚠ 旧顺序先取 t10b_1(当前观察目标):玩家死亡后观察目标会切到别人(甚至敌人), + // 用它当队伍基准会导致「敌我一会儿对一会儿反」。 + // checkPosition: 是否检查位置有效性(默认 true) function GetPlayerTank(gm, checkPosition) { if (checkPosition === undefined) checkPosition = true; - var t = gm.t10b_1; + var t = gm.u10b_1; if (t && (!checkPosition || GetTankPosition(t))) return t; - t = gm.u10b_1; + t = gm.t10b_1; if (t && (!checkPosition || GetTankPosition(t))) return t; try { var tl = gm.m10b_1.j11y(); @@ -241,16 +243,34 @@ return null; } + // 本地队伍缓存:死亡后 u10b_1 会被清空(onTankUnpossessed),不能再用"当前观察目标"推断。 + // 这里记住最后一次有效的本地队伍,整局沿用。 + var LocalTeam = null; + var LocalTeamGm = null; + function RememberLocalTeam(gm) { + if (!ZCt) return; + if (gm !== LocalTeamGm) { LocalTeamGm = gm; LocalTeam = null; } + if (LocalTeam) return; + try { + var t = gm.u10b_1; + if (!t) return; + var Team = ZCt(t); + // 只缓存"非中立"队伍(m2Fn(Team,Team) 为 true 表示同队且非中立) + if (Team && (!m2Fn || m2Fn(Team, Team))) LocalTeam = Team; + } catch (e) {} + } + // ===== 判断是否友方 ===== - // 策略1(优先):ZCt 获取双方队伍ID,m2 比较(同队且非中立) - // 策略2(备用):比较 gm.gzr_1(本地队伍ID)与坦克队伍ID + // 优先用缓存的本地队伍;没有缓存时才退回 playerTank 的队伍 function IsFriendly(tank, playerTank, gm) { - if (!tank || !playerTank) return false; + if (!tank) return false; + if (gm) RememberLocalTeam(gm); if (ZCt && m2Fn) { try { var tankTeam = ZCt(tank); - var playerTeam = ZCt(playerTank); - if (tankTeam && playerTeam) return m2Fn(tankTeam, playerTeam); + var BaseTeam = LocalTeam; + if (!BaseTeam && playerTank) BaseTeam = ZCt(playerTank); + if (tankTeam && BaseTeam) return m2Fn(tankTeam, BaseTeam); } catch(e) {} } try { diff --git a/tools/hornet_radar.js b/tools/hornet_radar.js index 40c2d20..9bb844a 100644 --- a/tools/hornet_radar.js +++ b/tools/hornet_radar.js @@ -32,7 +32,8 @@ var GetTankPosition = lib.GetTankPosition; // 坦克状态:使用公共库(0=DEAD,1=DEAD_PHANTOM,2=SEMI_ACTIVE,3=ACTIVE,4=DISABLED) - var GetTankState = lib.GetTankState; + var GetTankState = lib.GetTankState; + var GetTankHealth = lib.GetTankHealth; // ===== 获取坦克方向(Kkt 组件的 dzc_1) ===== function getTankDirection(tank) { @@ -619,10 +620,11 @@ if (radarY < cy - radius) radarY = cy - radius; if (radarY > cy + radius) radarY = cy + radius; - // 死亡判断(同 3D透视):可见坦克 = ACTIVE(3) 或 SEMI_ACTIVE(2);其余画红 × + // 死亡判断(同 3D透视):可见坦克 = ACTIVE(3) 或 SEMI_ACTIVE(2);其余直接跳过(不再画红叉) + // 辅助:血量归零也视为死亡(状态字段偶有滞后) var tankState = GetTankState(tank); - if (tankState !== 2 && tankState !== 3) { - DrawDeadCross(radarX, radarY); + var hp = GetTankHealth(tank); + if ((tankState !== 2 && tankState !== 3) || (hp && hp.current <= 0)) { deadCount++; continue; }