mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 19:24:01 +02:00
Merge branch 'dev' of https://github.com/bryanthaboi/gen1recomp into dev
This commit is contained in:
+55
-11
@@ -638,6 +638,44 @@ local function newBattle(game)
|
||||
return self
|
||||
end
|
||||
|
||||
local function scopedPlayerParty(game, indices)
|
||||
if indices == nil then return nil, nil end
|
||||
if type(indices) ~= "table" then
|
||||
Logger.warn("trainer battle party scope is not a table; using full party")
|
||||
return nil, nil
|
||||
end
|
||||
local count = #indices
|
||||
local keyCount = 0
|
||||
for key in pairs(indices) do
|
||||
keyCount = keyCount + 1
|
||||
if type(key) ~= "number" or key % 1 ~= 0 or key < 1 or key > count then
|
||||
Logger.warn("trainer battle party scope is malformed; using full party")
|
||||
return nil, nil
|
||||
end
|
||||
end
|
||||
if count == 0 or keyCount ~= count then
|
||||
Logger.warn("trainer battle party scope is empty or sparse; using full party")
|
||||
return nil, nil
|
||||
end
|
||||
local party, normalized, seen = {}, {}, {}
|
||||
for i = 1, count do
|
||||
local index = indices[i]
|
||||
if type(index) ~= "number" or index % 1 ~= 0
|
||||
or not game.save.party[index] or seen[index] then
|
||||
Logger.warn("trainer battle party scope contains an invalid index; using full party")
|
||||
return nil, nil
|
||||
end
|
||||
seen[index] = true
|
||||
normalized[i] = index
|
||||
party[i] = game.save.party[index]
|
||||
end
|
||||
return party, normalized
|
||||
end
|
||||
|
||||
function BattleState:playerPartyView()
|
||||
return self.playerParty or self.game.save.party
|
||||
end
|
||||
|
||||
-- opts.hooked: rod encounter, announced with _HookedMonAttackedText
|
||||
function BattleState.newWild(game, species, level, opts)
|
||||
local self = newBattle(game)
|
||||
@@ -713,13 +751,15 @@ local function applySpecialMoves(data, oppClass, partyIndex, party)
|
||||
end
|
||||
end
|
||||
|
||||
function BattleState.newTrainer(game, oppClass, partyIndex)
|
||||
function BattleState.newTrainer(game, oppClass, partyIndex, opts)
|
||||
local self = newBattle(game)
|
||||
self.kind = "trainer"
|
||||
self.oppClass = oppClass
|
||||
-- the object_event trainer arg (roster index). computeMusicKind keys
|
||||
-- data/scripts/victories.lua on class#party, so keep it on the battle (#782).
|
||||
self.partyIndex = partyIndex or 1
|
||||
self.playerParty, self.playerPartyIndices = scopedPlayerParty(game,
|
||||
type(opts) == "table" and opts.playerPartyIndices or nil)
|
||||
self.trainer = game.data.trainers[oppClass]
|
||||
assert(self.trainer, "unknown trainer class " .. tostring(oppClass))
|
||||
-- pret GetTrainerName_: RIVAL1/2/3 copy wRivalName into wTrainerName
|
||||
@@ -763,7 +803,7 @@ function BattleState.newTrainer(game, oppClass, partyIndex)
|
||||
end
|
||||
end
|
||||
self.enemyIndex = 1
|
||||
local playerMon = Party.firstHealthy(game.save.party)
|
||||
local playerMon = Party.firstHealthy(self:playerPartyView())
|
||||
if not playerMon then
|
||||
Logger.warn("trainer battle with no healthy party; skipping")
|
||||
self.dead = true
|
||||
@@ -2022,7 +2062,7 @@ function BattleState:update(dt)
|
||||
-- loops the party menu until a healthy mon is picked, so B and
|
||||
-- fainted picks land back here and reopen it
|
||||
if self.player.mon.hp <= 0 then
|
||||
if Party.firstHealthy(self.game.save.party) then
|
||||
if Party.firstHealthy(self:playerPartyView()) then
|
||||
self:openReplacementMenu()
|
||||
end
|
||||
return
|
||||
@@ -3910,7 +3950,8 @@ function BattleState:awardExp()
|
||||
-- (RemoveFaintedPlayerMon), so it drops out of the divisor and only
|
||||
-- the surviving participants are counted and paid
|
||||
local participants, alive = 0, {}
|
||||
for _, mon in ipairs(self.game.save.party) do
|
||||
local playerParty = self:playerPartyView()
|
||||
for _, mon in ipairs(playerParty) do
|
||||
if self.participants and self.participants[mon] then
|
||||
participants = participants + 1
|
||||
if mon.hp > 0 then table.insert(alive, mon) end
|
||||
@@ -4004,9 +4045,9 @@ function BattleState:awardExp()
|
||||
-- experience.asm:9-13); each mon gets its own GainedText with the
|
||||
-- "with EXP.ALL," tail (wBoostExpByExpAll) -- pokered prints no
|
||||
-- summary line
|
||||
for _, mon in ipairs(self.game.save.party) do
|
||||
for _, mon in ipairs(playerParty) do
|
||||
if mon.hp > 0 then
|
||||
ctx.applyShare(mon, math.max(1, ctx.participants) * #self.game.save.party * 2, "expAll")
|
||||
ctx.applyShare(mon, math.max(1, ctx.participants) * #playerParty * 2, "expAll")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4047,7 +4088,7 @@ function BattleState:enemyMonFainted()
|
||||
local nextName = nextMon.nickname or self.data.pokemon[nextMon.species].name
|
||||
local style = tostring((self.game.save.options or {}).battleStyle or "shift")
|
||||
:lower()
|
||||
local partyCount = #self.game.save.party
|
||||
local partyCount = #self:playerPartyView()
|
||||
-- ReplaceFaintedEnemyMon (core.asm:892-896): DrawEnemyPokeballs puts the
|
||||
-- foe's party ball row -- and the HUD chrome PlaceEnemyHUDTiles lays
|
||||
-- down under it (draw_hud_pokeball_gfx.asm:9-11, 33-45, 134-141) -- into
|
||||
@@ -4074,6 +4115,7 @@ function BattleState:enemyMonFainted()
|
||||
local game = self.game
|
||||
Screens.push(game, "PartyMenu", {
|
||||
battle = self,
|
||||
party = self:playerPartyView(),
|
||||
forceSwitch = true,
|
||||
onSwitch = function(mon)
|
||||
if mon ~= self.player.mon and mon.hp > 0 then
|
||||
@@ -4246,7 +4288,7 @@ function BattleState.isOaksLabStarterRival(self)
|
||||
end
|
||||
|
||||
function BattleState:playerMonFainted()
|
||||
local nextMon = Party.firstHealthy(self.game.save.party)
|
||||
local nextMon = Party.firstHealthy(self:playerPartyView())
|
||||
-- Being out of useable POKéMON blacks you out even when the battle was
|
||||
-- already decided in our favour. A double faint -- our last mon dying
|
||||
-- to residual damage on the turn it lands the KO -- used to hit the
|
||||
@@ -4319,6 +4361,7 @@ function BattleState:openReplacementMenu()
|
||||
self:ui(function()
|
||||
return self:buildScreen("PartyMenu", {
|
||||
battle = self,
|
||||
party = self:playerPartyView(),
|
||||
-- ChooseNextMon: pick immediately (no SWITCH/STATS/CANCEL)
|
||||
forceSwitch = true,
|
||||
onSwitch = function(mon)
|
||||
@@ -4799,6 +4842,7 @@ function BattleState:openParty()
|
||||
self:ui(function()
|
||||
return self:buildScreen("PartyMenu", {
|
||||
battle = self,
|
||||
party = self:playerPartyView(),
|
||||
onSwitch = function(mon)
|
||||
if mon == self.player.mon then
|
||||
self:say(Strings("%s is\nalready out!", self.player.name))
|
||||
@@ -4845,8 +4889,8 @@ function BattleState:finish()
|
||||
-- here it did not, so say so rather than silently papering over it.
|
||||
-- The old-man / PROF.OAK demo also skips it: the party never fought
|
||||
-- (Yellow's Pallet intro runs before the player owns a mon at all).
|
||||
if self.result ~= "lose" and not self.demo
|
||||
and not Party.firstHealthy(self.game.save.party) then
|
||||
if self.kind ~= "link" and self.result ~= "lose" and not self.demo
|
||||
and not Party.firstHealthy(self:playerPartyView()) then
|
||||
Logger.warn("battle finished %s with no healthy party; forcing blackout",
|
||||
tostring(self.result))
|
||||
self.result = "lose"
|
||||
@@ -5727,7 +5771,7 @@ function BattleState:drawHUDs(slide)
|
||||
for i = 10, 17 do hudTile(0x76, i * 8, 88) end
|
||||
hudTile(0x6F, 72, 88)
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
self:drawBallRow(self.playerParty or self.game.save.party, 88, 80, 8)
|
||||
self:drawBallRow(self:playerPartyView(), 88, 80, 8)
|
||||
end
|
||||
local hidePlayer = self.safari or self.demo
|
||||
if showStatus and self.player and not hidePlayer and not self.showPlayerBack
|
||||
|
||||
Reference in New Issue
Block a user