mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 19:24:01 +02:00
Merge pull request #1399 from AverageConsumer/codex/mod-battle-special-intents
This commit is contained in:
+8
-2
@@ -287,10 +287,16 @@ The shared Red, Blue, Yellow, and Gold intents are:
|
||||
- `{ kind = "move", slot = 1..4 }`
|
||||
- `{ kind = "back" }` while the move menu is active
|
||||
|
||||
Red, Blue, and Yellow also expose their generation-specific choices:
|
||||
|
||||
- `{ kind = "safari", action = "ball" }` (`bait`, `rock`, and `run` are the
|
||||
other accepted actions)
|
||||
- `{ kind = "mimic", index = 1 }` using an entry's snapshot `index`
|
||||
|
||||
Menu choices and moves use the same engine methods as the native controls;
|
||||
`party` and `item` open the native screens rather than exposing or duplicating
|
||||
their mutable logic. Tutorial, link, Safari, forced, stale, and covered battle
|
||||
states refuse these core intents. Use `mod.input` for ordinary text advance.
|
||||
their mutable logic. Tutorial, link, forced, stale, and covered battle states
|
||||
refuse core intents. Use `mod.input` for ordinary text advance.
|
||||
|
||||
## Rendering pipelines
|
||||
|
||||
|
||||
@@ -218,13 +218,20 @@ function BattleAPI:submit(intent)
|
||||
return nil, "stale battle context"
|
||||
end
|
||||
local kind = battle:battleKind()
|
||||
if kind == "oldman" or kind == "link" or kind == "safari" then
|
||||
if kind == "oldman" or kind == "link" then
|
||||
return nil, "battle kind is not controllable"
|
||||
end
|
||||
if top ~= battle then return nil, "battle menu is covered" end
|
||||
|
||||
local ok, err
|
||||
if intent.kind == "menu" then
|
||||
if intent.kind == "safari" then
|
||||
if kind ~= "safari" then return nil, "safari menu is not active" end
|
||||
ok, err = battle:chooseSafari(intent.action)
|
||||
elseif kind == "safari" then
|
||||
return nil, "battle kind is not controllable"
|
||||
elseif intent.kind == "mimic" then
|
||||
ok, err = battle:chooseMimic(intent.index)
|
||||
elseif intent.kind == "menu" then
|
||||
if battle.phase ~= "menu" then return nil, "battle menu is not active" end
|
||||
if not MENU_CHOICES[intent.choice] then
|
||||
return nil, "unknown battle menu choice"
|
||||
|
||||
@@ -2019,6 +2019,38 @@ function BattleState:cancelMove()
|
||||
return true
|
||||
end
|
||||
|
||||
local SAFARI_ACTION_INDEX = { ball = 1, bait = 2, rock = 3, run = 4 }
|
||||
|
||||
function BattleState:chooseSafari(action)
|
||||
if self.phase ~= "menu" or not self.safari then
|
||||
return nil, "safari menu is not active"
|
||||
end
|
||||
if self.safari.balls <= 0 then return nil, "no safari balls remain" end
|
||||
local index = SAFARI_ACTION_INDEX[action]
|
||||
if not index then return nil, "invalid safari action" end
|
||||
self.menuIndex = index
|
||||
self:safariAction(action)
|
||||
return true
|
||||
end
|
||||
|
||||
function BattleState:chooseMimic(index)
|
||||
if self.phase ~= "mimicSelect" then
|
||||
return nil, "mimic menu is not active"
|
||||
end
|
||||
if type(index) ~= "number" or index % 1 ~= 0 then
|
||||
return nil, "invalid mimic slot"
|
||||
end
|
||||
local pick = self.mimicMoves and self.mimicMoves[index]
|
||||
local ctx = self.mimicCtx
|
||||
if not pick or not ctx then return nil, "invalid mimic slot" end
|
||||
self.mimicIndex = index
|
||||
self.mimicMoves, self.mimicCtx = nil, nil
|
||||
self.phase = "messages"
|
||||
self.nextInsert = 0 -- the copy's anim + text go to the queue head
|
||||
self:applyMimic(ctx.user, ctx.target, ctx.moveInst, pick.slot)
|
||||
return true
|
||||
end
|
||||
|
||||
function BattleState:swapMoves(i, j)
|
||||
if i == j then return end
|
||||
local moves = self.player.curMoves
|
||||
@@ -2140,7 +2172,7 @@ function BattleState:update(dt)
|
||||
self.menuIndex = row * 2 + col + 1
|
||||
if input:wasPressed("a") then
|
||||
require("src.core.Sound").play(self.data, "Press_AB")
|
||||
self:safariAction(({ "ball", "bait", "rock", "run" })[self.menuIndex])
|
||||
self:chooseSafari(({ "ball", "bait", "rock", "run" })[self.menuIndex])
|
||||
end
|
||||
return
|
||||
end
|
||||
@@ -2248,12 +2280,7 @@ function BattleState:update(dt)
|
||||
self.mimicIndex = self.mimicIndex < #moves and self.mimicIndex + 1 or 1
|
||||
elseif input:wasPressed("a") then
|
||||
require("src.core.Sound").play(self.data, "Press_AB")
|
||||
local pick = moves[self.mimicIndex]
|
||||
local ctx = self.mimicCtx
|
||||
self.mimicMoves, self.mimicCtx = nil, nil
|
||||
self.phase = "messages"
|
||||
self.nextInsert = 0 -- the copy's anim + text go to the queue head
|
||||
self:applyMimic(ctx.user, ctx.target, ctx.moveInst, pick.slot)
|
||||
self:chooseMimic(self.mimicIndex)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
@@ -48,7 +48,7 @@ local battle = {
|
||||
enemy = { mon = { species = "TESTMON", level = 4, hp = 12,
|
||||
stats = { hp = 12 }, moves = {} }, curTypes = { "NORMAL" }, stages = {} },
|
||||
}
|
||||
function battle:battleKind() return "wild" end
|
||||
function battle:battleKind() return self.kind or "wild" end
|
||||
function battle:effectRecord() return { accuracyChecked = true } end
|
||||
function battle:visibleText() return { "Wild TESTMON appeared!" } end
|
||||
function battle:menuLockedAction() return nil end
|
||||
@@ -63,6 +63,14 @@ function battle:chooseMove(slot)
|
||||
return true
|
||||
end
|
||||
function battle:cancelMove() self.phase = "menu" return true end
|
||||
function battle:chooseSafari(action)
|
||||
self.chosenSafari, self.phase = action, "messages"
|
||||
return true
|
||||
end
|
||||
function battle:chooseMimic(slot)
|
||||
self.chosenMimic, self.phase = slot, "messages"
|
||||
return true
|
||||
end
|
||||
function battle:catchChance(ball)
|
||||
return require("src.battle.Catching").chance(ball, self.enemy.mon,
|
||||
game.data.pokemon[self.enemy.mon.species])
|
||||
@@ -123,6 +131,18 @@ check(api:submit({ id = 3, revision = back.revision, kind = "back" }),
|
||||
"Gen 1 accepts move-menu back")
|
||||
eq(battle.phase, "menu", "Gen 1 back restores the command menu")
|
||||
|
||||
battle.kind, battle.safari = "safari", { balls = 30 }
|
||||
local safari = api:snapshot()
|
||||
check(api:submit({ id = 4, revision = safari.revision,
|
||||
kind = "safari", action = "rock" }), "Gen 1 accepts a Safari action")
|
||||
eq(battle.chosenSafari, "rock", "Gen 1 uses the semantic Safari path")
|
||||
battle.kind, battle.safari = "wild", nil
|
||||
battle.phase, battle.mimicMoves = "mimicSelect", { { slot = 1 } }
|
||||
local mimic = api:snapshot()
|
||||
check(api:submit({ id = 5, revision = mimic.revision,
|
||||
kind = "mimic", index = 1 }), "Gen 1 accepts a Mimic choice")
|
||||
eq(battle.chosenMimic, 1, "Gen 1 uses the semantic Mimic path")
|
||||
|
||||
local player2 = { species = "CHIKORITA", level = 5, hp = 20,
|
||||
maxHp = 21, moves = { { id = "TACKLE", pp = 35, maxPp = 35 } } }
|
||||
local enemy2 = { species = "RATTATA", level = 3, hp = 12, maxHp = 12,
|
||||
@@ -228,6 +248,29 @@ do
|
||||
eq(real.phase, "menu", "native Gen 1 move-menu back still works")
|
||||
end
|
||||
|
||||
do
|
||||
local state = setmetatable({ phase = "menu", safari = { balls = 30 },
|
||||
menuIndex = 1 }, { __index = Gen1BattleState })
|
||||
function state:safariAction(action) self.safariChoice = action end
|
||||
local ok, err = state:chooseSafari("missing")
|
||||
check(not ok and err == "invalid safari action",
|
||||
"native Safari rejects an unknown action")
|
||||
check(state:chooseSafari("rock"), "native Safari choice is accepted")
|
||||
eq(state.menuIndex, 3, "native Safari cursor follows the semantic choice")
|
||||
eq(state.safariChoice, "rock", "native Safari action uses the shared path")
|
||||
|
||||
state.phase = "mimicSelect"
|
||||
state.mimicMoves = { { slot = 4 } }
|
||||
state.mimicCtx = { user = {}, target = {}, moveInst = {} }
|
||||
function state:applyMimic(_, _, _, slot) self.mimicSlot = slot end
|
||||
ok, err = state:chooseMimic(2)
|
||||
check(not ok and err == "invalid mimic slot",
|
||||
"native Mimic rejects an unknown choice")
|
||||
check(state:chooseMimic(1), "native Mimic choice is accepted")
|
||||
eq(state.phase, "messages", "native Mimic choice resumes battle messages")
|
||||
eq(state.mimicSlot, 4, "native Mimic choice copies the selected move slot")
|
||||
end
|
||||
|
||||
local Loader = require("src.mods.Loader")
|
||||
local fs = { read = function() end, getInfo = function() end,
|
||||
getDirectoryItems = function() return {} end }
|
||||
|
||||
Reference in New Issue
Block a user