mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 00:10:56 +02:00
Fix Karate Master gate
This commit is contained in:
@@ -171,6 +171,28 @@ local function dojoBall(species, ownBall, otherBall, askKey)
|
||||
end
|
||||
end
|
||||
|
||||
-- FightingDojoDefaultScript does not use the Master's facing direction for
|
||||
-- this battle. It checks exactly the cell left of him, turns both sprites
|
||||
-- toward one another, and then displays his trainer text. Keeping this out
|
||||
-- of trainer sight also lets him keep his original downward-facing pose.
|
||||
local function dojoMasterGate(game, ow, x, y)
|
||||
if x ~= 4 or y ~= 3 or game.save.flags.EVENT_BEAT_KARATE_MASTER then
|
||||
return false
|
||||
end
|
||||
local master
|
||||
for _, npc in ipairs(ow.npcs) do
|
||||
if npc.def and npc.def.name == "FIGHTINGDOJO_KARATE_MASTER" then
|
||||
master = npc
|
||||
break
|
||||
end
|
||||
end
|
||||
if not master or ow:trainerDefeated(master) then return false end
|
||||
ow.player.facing = "right"
|
||||
master:facePlayer(ow.player)
|
||||
ow:engageTrainer(master)
|
||||
return true
|
||||
end
|
||||
|
||||
M.FIGHTING_DOJO = {
|
||||
talk = {
|
||||
TEXT_FIGHTINGDOJO_HITMONLEE_POKE_BALL =
|
||||
@@ -197,6 +219,7 @@ M.FIGHTING_DOJO = {
|
||||
end
|
||||
return false
|
||||
end,
|
||||
onStep = dojoMasterGate,
|
||||
}
|
||||
|
||||
-- -------------------------------------------------------------------
|
||||
|
||||
+3
-3
@@ -144,8 +144,8 @@ end
|
||||
-- no def_trainers row (DisplayTextID routes to his ASM script), so the
|
||||
-- extractor emits headers only for the four blackbelts ([2]..[5]). Seed
|
||||
-- object index [1] so he behaves like the real leader:
|
||||
-- * range 4 (matches the strongest blackbelt) -> CheckFightingMapTrainers
|
||||
-- spots the player in his DOWN line and he challenges on sight (#197),
|
||||
-- * range 0: FightingDojoDefaultScript, not trainer sight, starts his
|
||||
-- battle from the single tile to his left (#495),
|
||||
-- * battle = his pre-battle challenge, won = "Hwa! Arrgh! Beaten!",
|
||||
-- * after = the "Stay and train at Karate with us!" re-talk line.
|
||||
-- Deliberately NO `event`: EVENT_BEAT_KARATE_MASTER is owned by
|
||||
@@ -160,7 +160,7 @@ function Data:seedFightingDojoKarateMaster()
|
||||
headers.FightingDojo = headers.FightingDojo or {}
|
||||
if headers.FightingDojo[1] then return end
|
||||
headers.FightingDojo[1] = {
|
||||
range = 4,
|
||||
range = 0,
|
||||
battle = "_FightingDojoKarateMasterText",
|
||||
won = "_FightingDojoKarateMasterDefeatedText",
|
||||
after = "_FightingDojoKarateMasterStayAndTrainWithUsText",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- Driver: Fighting Dojo Karate Master bundle (#197).
|
||||
-- Six sub-bugs live in FIGHTING_DOJO (scripts/FightingDojo.asm):
|
||||
-- BUG1 no aggro -- the master has no trainer header so range=0
|
||||
-- BUG1 gate -- the master stops the player on the tile to his left
|
||||
-- BUG2 no speech -- no won text + no prize dialogue after the win
|
||||
-- BUG3 wrong re-talk -- shows the pre-battle challenge, not the after line
|
||||
-- BUG4 (verify) -- the ball ask() is the Gen1 descriptor, not a dex entry
|
||||
@@ -112,21 +112,23 @@ return function(game)
|
||||
------------------------------------------------------------------
|
||||
local hdr = game.data:trainerHeader("FightingDojo", 1)
|
||||
check(hdr ~= nil, "BUG1/2/3: Karate Master trainer header (index 1) exists")
|
||||
check(hdr and (hdr.range or 0) > 0, "BUG1: master has a sight range")
|
||||
check(hdr and (hdr.range or 0) == 0,
|
||||
"BUG1: master relies on the exact-tile gate, not trainer sight")
|
||||
check(hdr and hdr.won ~= nil, "BUG2: master has a won (defeat) text")
|
||||
check(hdr and hdr.after ~= nil, "BUG3: master has an after (re-talk) text")
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- BUG1: sight aggro. Stand directly below the master (5,3 faces DOWN,
|
||||
-- range 4) with the four blackbelts pre-cleared so only he can engage.
|
||||
-- BUG1: exact gate. Start just north of the tile to the Master's left,
|
||||
-- then step down once. The four blackbelts are cleared so only he reacts.
|
||||
------------------------------------------------------------------
|
||||
local ow = resetDojo(5, 4, "up", {})
|
||||
local ow = resetDojo(4, 2, "down", {})
|
||||
U.shot(game, DIR .. "/dojo_1_before.png")
|
||||
U.wait(20) -- the idle sight scan runs every frame
|
||||
local engaged = ow.engaging or (ow.emote ~= nil)
|
||||
U.log("aggro engaging:", tostring(ow.engaging), "emote:", tostring(ow.emote ~= nil))
|
||||
U.tap(game, "down")
|
||||
U.wait(30)
|
||||
local engaged = topIsTextBox()
|
||||
U.log("gate dialogue open:", tostring(engaged))
|
||||
U.shot(game, DIR .. "/dojo_2_aggro.png")
|
||||
check(engaged, "BUG1: Karate Master aggros on sight")
|
||||
check(engaged, "BUG1: Karate Master stops the player at his left")
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- BUG3: talk to the already-beaten master -> "Stay and train..." and
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
-- Driver: Fighting Dojo Karate Master gate (#495).
|
||||
--
|
||||
-- Run:
|
||||
-- POKEPORT_DRIVER=tests/drivers/fighting_dojo_gate_bug495_test.lua \
|
||||
-- POKEPORT_TOUCH=0 POKEPORT_VERSION=yellow love .
|
||||
--
|
||||
-- The scene starts one tile north of the only trigger tile. The reported
|
||||
-- behaviour is an interaction timing and position question for a human to
|
||||
-- observe, not an assertion this driver can decide.
|
||||
return function(game)
|
||||
local U = dofile("tests/drivers/util.lua")
|
||||
|
||||
local function check(label, ok)
|
||||
U.log(ok and "PASS" or "FAIL", label)
|
||||
return ok
|
||||
end
|
||||
|
||||
U.teleport(game, "FIGHTING_DOJO", 4, 2, "down")
|
||||
local ow = game.stack:top()
|
||||
local master
|
||||
for _, npc in ipairs(ow.npcs) do
|
||||
if npc.def and npc.def.name == "FIGHTINGDOJO_KARATE_MASTER" then
|
||||
master = npc
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Fixture checks only: the room, player, and Master must be in the layout
|
||||
-- that makes the reported tile meaningful.
|
||||
check("Fighting Dojo is loaded", ow.map.id == "FIGHTING_DOJO")
|
||||
check("player starts north of the trigger tile",
|
||||
ow.player.cellX == 4 and ow.player.cellY == 2)
|
||||
check("Karate Master is at (5,3)",
|
||||
master and master.cellX == 5 and master.cellY == 3)
|
||||
|
||||
U.log("Issue #495: Karate Master gate")
|
||||
U.log("Do this: press Down once, onto the tile left of the Master.")
|
||||
U.log("Right: he turns left and starts his challenge on that tile only.")
|
||||
U.log("Wrong: nothing happens here, while standing below him triggers a battle.")
|
||||
|
||||
while true do
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
-- FightingDojoDefaultScript gates the Karate Master at the one tile to his
|
||||
-- left. He is not a regular sight-line trainer (#495).
|
||||
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
if not _G.love then _G.love = require("tests.love_stub") end
|
||||
|
||||
local Data = require("src.core.Data")
|
||||
if not Data.maps then Data:load() end
|
||||
|
||||
local S = require("tests.harness").suite("parity Fighting Dojo gate")
|
||||
local check, eq = S.check, S.eq
|
||||
local script = require("data.scripts.story4").FIGHTING_DOJO.onStep
|
||||
|
||||
local function scene()
|
||||
local master = {
|
||||
def = { name = "FIGHTINGDOJO_KARATE_MASTER" },
|
||||
facing = "down",
|
||||
facePlayer = function(self, player)
|
||||
self.facing = player.cellX < 5 and "left" or "right"
|
||||
end,
|
||||
}
|
||||
local ow = {
|
||||
npcs = { master },
|
||||
player = { cellX = 4, cellY = 3, facing = "down" },
|
||||
trainerDefeated = function() return false end,
|
||||
engageTrainer = function(self, npc) self.engaged = npc end,
|
||||
}
|
||||
return { save = { flags = {} } }, ow, master
|
||||
end
|
||||
|
||||
local header = Data:trainerHeader("FightingDojo", 1)
|
||||
eq(header and header.range, 0,
|
||||
"Karate Master has no generic trainer sight range")
|
||||
|
||||
do
|
||||
local game, ow = scene()
|
||||
check(not script(game, ow, 5, 4),
|
||||
"standing below the downward-facing Master does not trigger him")
|
||||
check(ow.engaged == nil, "the below tile does not begin a battle")
|
||||
end
|
||||
|
||||
do
|
||||
local game, ow, master = scene()
|
||||
check(script(game, ow, 4, 3),
|
||||
"the tile immediately left of the Master triggers his script")
|
||||
eq(ow.engaged, master, "the Master starts the battle")
|
||||
eq(master.facing, "left", "the Master turns toward the player")
|
||||
eq(ow.player.facing, "right", "the player turns toward the Master")
|
||||
end
|
||||
|
||||
do
|
||||
local game, ow = scene()
|
||||
game.save.flags.EVENT_BEAT_KARATE_MASTER = true
|
||||
check(not script(game, ow, 4, 3),
|
||||
"the gate stays inactive after the Karate Master is beaten")
|
||||
end
|
||||
|
||||
S.finish()
|
||||
Reference in New Issue
Block a user