mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
potentially CLOSES #758
This commit is contained in:
@@ -332,7 +332,7 @@ MoveEffects.primary = {
|
||||
battle.data.moves[id].name) }
|
||||
end,
|
||||
|
||||
SPLASH_EFFECT = function()
|
||||
SPLASH_EFFECT = function(battle)
|
||||
return { romText(battle.data, "_NoEffectText", "No effect!") }
|
||||
end,
|
||||
}
|
||||
|
||||
+31
-1
@@ -169,6 +169,8 @@ end
|
||||
|
||||
-- full identical link surfaces: nothing to negotiate, lockstep is safe
|
||||
-- vanilla_peer an old build, and we are unmodified, so it is right about us
|
||||
-- engine_skew both v2 on the same major, but different releases: trade
|
||||
-- still negotiates, battle is refused (see below)
|
||||
-- subset both v2 but the surfaces differ: negotiated trade, no battle
|
||||
-- refused an old build we would silently corrupt, or a different engine
|
||||
function Handshake.checkCompat(localHello, remoteHello)
|
||||
@@ -182,6 +184,16 @@ function Handshake.checkCompat(localHello, remoteHello)
|
||||
if major(remoteHello.engineVersion) ~= major(localHello.engineVersion) then
|
||||
return "refused", "engine_mismatch"
|
||||
end
|
||||
-- A lockstep battle needs the same engine RELEASE, not just the same
|
||||
-- major: the fingerprint only covers the data/mod link surface, and
|
||||
-- battle logic changes between minor releases (parity fixes, move
|
||||
-- effect rework...), so two honest vanilla installs a release apart
|
||||
-- pair as "full" and then diverge a few turns in -- the mid-battle
|
||||
-- "same mods?" desync draw of #758. Trade doesn't lockstep a
|
||||
-- simulation, so it stays negotiable across releases.
|
||||
if tostring(remoteHello.engineVersion) ~= tostring(localHello.engineVersion) then
|
||||
return "engine_skew", "engine_release_mismatch"
|
||||
end
|
||||
if remoteHello.fingerprint == localHello.fingerprint then
|
||||
return "full", nil
|
||||
end
|
||||
@@ -191,7 +203,7 @@ end
|
||||
-- only two v2 peers that agreed on a verdict may reject a mon outright; a v1
|
||||
-- peer keeps the old substitute-a-move behaviour it was built against
|
||||
function Handshake.strict(verdict)
|
||||
return verdict == "full" or verdict == "subset"
|
||||
return verdict == "full" or verdict == "subset" or verdict == "engine_skew"
|
||||
end
|
||||
|
||||
function Handshake.battleAllowed(verdict)
|
||||
@@ -278,6 +290,24 @@ function Handshake.describe(localHello, remoteHello, verdict, mode)
|
||||
end
|
||||
return lines
|
||||
end
|
||||
if verdict == "engine_skew" then
|
||||
-- name both releases so two friends can tell WHO updates: this used
|
||||
-- to surface three turns in as a desync draw blaming mods (#758)
|
||||
wrap(lines, "Your game versions")
|
||||
wrap(lines, "differ:")
|
||||
wrap(lines, (" you: v%s"):format(tostring(localHello.engineVersion)))
|
||||
wrap(lines, (" %s: v%s"):format(peer:sub(1, 8),
|
||||
tostring(remoteHello.engineVersion)))
|
||||
if mode == "battle" then
|
||||
wrap(lines, "Battle needs the")
|
||||
wrap(lines, "same version on")
|
||||
wrap(lines, "both games.")
|
||||
else
|
||||
wrap(lines, "Trading is limited")
|
||||
wrap(lines, "to shared POKéMON.")
|
||||
end
|
||||
return lines
|
||||
end
|
||||
wrap(lines, "Your games differ.")
|
||||
local diff = Handshake.modDiff(localHello, remoteHello)
|
||||
listMods(lines, peer .. " has:", diff.onlyTheirs)
|
||||
|
||||
@@ -202,7 +202,7 @@ function LinkBattle.new(game, net, opts)
|
||||
local theirName = opts.theirName or "FOE"
|
||||
|
||||
if not Handshake.battleAllowed(opts.verdict) then
|
||||
return nil, Strings("Link battle needs\nthe same mods on\nboth games.")
|
||||
return nil, Strings("Link battle needs\nthe same version\nand mods.")
|
||||
end
|
||||
|
||||
-- both parties pass through the same pack->unpack clamp on both
|
||||
@@ -342,7 +342,7 @@ function LinkBattle.new(game, net, opts)
|
||||
localHash = localH, remoteHash = remoteH,
|
||||
fatal = true })
|
||||
endAsDraw(s, Strings(
|
||||
"Link desync!\n%s differs.\fAre both games\nrunning the same\nmods?",
|
||||
"Link desync!\n%s differs.\fAre both games\nthe same version\nand mods?",
|
||||
component))
|
||||
end
|
||||
|
||||
@@ -692,7 +692,7 @@ function LinkBattle.newSpectator(game, net, opts)
|
||||
local guestName = opts.guestName or "GUEST"
|
||||
|
||||
if not Handshake.battleAllowed(opts.verdict) then
|
||||
return nil, Strings("Link battle needs\nthe same mods on\nboth games.")
|
||||
return nil, Strings("Link battle needs\nthe same version\nand mods.")
|
||||
end
|
||||
|
||||
local unpackOpts = { strict = opts.strict or false, forceLevel = opts.forceLevel }
|
||||
|
||||
@@ -714,7 +714,9 @@ function LinkState:draw()
|
||||
end
|
||||
|
||||
elseif self.stage == "notice" then
|
||||
drawTitle("CHECK YOUR MODS")
|
||||
-- a version-skew notice has nothing to do with mods (#758)
|
||||
drawTitle(self.verdict == "engine_skew" and "UPDATE YOUR GAME"
|
||||
or "CHECK YOUR MODS")
|
||||
for i, line in ipairs(self.noticeLines or {}) do
|
||||
if i > 8 then break end -- what fits above the prompt row
|
||||
Font.draw(line, 8, 24 + (i - 1) * 12)
|
||||
|
||||
@@ -378,6 +378,25 @@ local nextEngine = Handshake.hello(fakeGame(vanilla, "BLUE"), nil)
|
||||
nextEngine.engineVersion = "2.0.0"
|
||||
eq(Handshake.checkCompat(helloA, nextEngine), "refused", "engine major mismatch refuses")
|
||||
|
||||
-- same major, different release: the fingerprint can't see engine code,
|
||||
-- and battle logic changes between releases, so lockstep would desync a
|
||||
-- few turns in (#758) -- battle is refused up front, trade still works
|
||||
local skewed = Handshake.hello(fakeGame(vanilla, "BLUE"), nil)
|
||||
skewed.engineVersion = (tostring(helloA.engineVersion):match("^(%d+)") or "0") .. ".999.0"
|
||||
local skewVerdict, skewReason = Handshake.checkCompat(helloA, wire(skewed))
|
||||
eq(skewVerdict, "engine_skew", "same-major release skew is its own verdict")
|
||||
eq(skewReason, "engine_release_mismatch", "and says why")
|
||||
check(not Handshake.battleAllowed("engine_skew"), "release skew refuses lockstep")
|
||||
check(Handshake.tradeAllowed("engine_skew"), "release skew still trades")
|
||||
check(Handshake.strict("engine_skew"), "release skew negotiates strictly")
|
||||
local skewLines = Handshake.describe(helloA, wire(skewed), "engine_skew", "battle")
|
||||
local skewJoined = table.concat(skewLines, " ")
|
||||
check(skewJoined:find("version", 1, true) ~= nil, "skew notice mentions versions")
|
||||
check(skewJoined:find("999", 1, true) ~= nil, "skew notice names the peer release")
|
||||
for _, line in ipairs(skewLines) do
|
||||
check(#line <= 20, "skew line fits the screen: " .. line)
|
||||
end
|
||||
|
||||
local lines = Handshake.describe(helloA, wire(helloMod), "subset", "battle")
|
||||
check(#lines > 0, "the incompatibility screen has something to say")
|
||||
local joined = table.concat(lines, " ")
|
||||
|
||||
Reference in New Issue
Block a user