lufia2ac: ability to swap party members mid-run and option to gain EXP while inactive (#2800)
This commit is contained in:
parent
1021df8b1b
commit
14437d653f
|
@ -593,6 +593,20 @@ class HealingFloorChance(Range):
|
|||
default = 16
|
||||
|
||||
|
||||
class InactiveExpGain(Choice):
|
||||
"""The rate at which characters not currently in the active party gain EXP.
|
||||
|
||||
Supported values: disabled, half, full
|
||||
Default value: disabled (same as in an unmodified game)
|
||||
"""
|
||||
|
||||
display_name = "Inactive character EXP gain"
|
||||
option_disabled = 0
|
||||
option_half = 50
|
||||
option_full = 100
|
||||
default = option_disabled
|
||||
|
||||
|
||||
class InitialFloor(Range):
|
||||
"""The initial floor, where you begin your journey.
|
||||
|
||||
|
@ -805,7 +819,7 @@ class ShufflePartyMembers(Toggle):
|
|||
false — all 6 optional party members are present in the cafe and can be recruited right away
|
||||
true — only Maxim is available from the start; 6 new "items" are added to your pool and shuffled into the
|
||||
multiworld; when one of these items is found, the corresponding party member is unlocked for you to use.
|
||||
While cave diving, you can add newly unlocked ones to your party by using the character items from the inventory
|
||||
While cave diving, you can add or remove unlocked party members by using the character items from the inventory
|
||||
Default value: false (same as in an unmodified game)
|
||||
"""
|
||||
|
||||
|
@ -838,6 +852,7 @@ class L2ACOptions(PerGameCommonOptions):
|
|||
goal: Goal
|
||||
gold_modifier: GoldModifier
|
||||
healing_floor_chance: HealingFloorChance
|
||||
inactive_exp_gain: InactiveExpGain
|
||||
initial_floor: InitialFloor
|
||||
iris_floor_chance: IrisFloorChance
|
||||
iris_treasures_required: IrisTreasuresRequired
|
||||
|
|
|
@ -232,6 +232,7 @@ class L2ACWorld(World):
|
|||
rom_bytearray[0x280018:0x280018 + 1] = self.o.shuffle_party_members.unlock.to_bytes(1, "little")
|
||||
rom_bytearray[0x280019:0x280019 + 1] = self.o.shuffle_capsule_monsters.unlock.to_bytes(1, "little")
|
||||
rom_bytearray[0x28001A:0x28001A + 1] = self.o.shop_interval.value.to_bytes(1, "little")
|
||||
rom_bytearray[0x28001B:0x28001B + 1] = self.o.inactive_exp_gain.value.to_bytes(1, "little")
|
||||
rom_bytearray[0x280030:0x280030 + 1] = self.o.goal.value.to_bytes(1, "little")
|
||||
rom_bytearray[0x28003D:0x28003D + 1] = self.o.death_link.value.to_bytes(1, "little")
|
||||
rom_bytearray[0x281200:0x281200 + 470] = self.get_capsule_cravings_table()
|
||||
|
|
|
@ -309,6 +309,12 @@ org $8EFD2E ; unused region at the end of bank $8E
|
|||
DB $1E,$0B,$01,$2B,$05,$1A,$05,$00 ; add dekar
|
||||
DB $1E,$0B,$01,$2B,$04,$1A,$06,$00 ; add tia
|
||||
DB $1E,$0B,$01,$2B,$06,$1A,$07,$00 ; add lexis
|
||||
DB $1F,$0B,$01,$2C,$01,$1B,$02,$00 ; remove selan
|
||||
DB $1F,$0B,$01,$2C,$02,$1B,$03,$00 ; remove guy
|
||||
DB $1F,$0B,$01,$2C,$03,$1B,$04,$00 ; remove arty
|
||||
DB $1F,$0B,$01,$2C,$05,$1B,$05,$00 ; remove dekar
|
||||
DB $1F,$0B,$01,$2C,$04,$1B,$06,$00 ; remove tia
|
||||
DB $1F,$0B,$01,$2C,$06,$1B,$07,$00 ; remove lexis
|
||||
pullpc
|
||||
|
||||
SpecialItemUse:
|
||||
|
@ -328,11 +334,15 @@ SpecialItemUse:
|
|||
SEP #$20
|
||||
LDA $8ED8C7,X ; load predefined bitmask with a single bit set
|
||||
BIT $077E ; check against EV flags $02 to $07 (party member flags)
|
||||
BNE + ; abort if character already present
|
||||
LDA $07A9 ; load EV register $11 (party counter)
|
||||
BEQ ++
|
||||
LDA.b #$30 ; character already present; modify pointer to point to L2SASM leave script
|
||||
ADC $09B7
|
||||
STA $09B7
|
||||
BRA +++
|
||||
++: LDA $07A9 ; character not present; load EV register $0B (party counter)
|
||||
CMP.b #$03
|
||||
BPL + ; abort if party full
|
||||
LDA.b #$8E
|
||||
+++ LDA.b #$8E
|
||||
STA $09B9
|
||||
PHK
|
||||
PEA ++
|
||||
|
@ -340,7 +350,6 @@ SpecialItemUse:
|
|||
JML $83BB76 ; initialize parser variables
|
||||
++: NOP
|
||||
JSL $809CB8 ; call L2SASM parser
|
||||
JSL $81F034 ; consume the item
|
||||
TSX
|
||||
INX #13
|
||||
TXS
|
||||
|
@ -490,6 +499,73 @@ pullpc
|
|||
|
||||
|
||||
|
||||
; allow inactive characters to gain exp
|
||||
pushpc
|
||||
org $81DADD
|
||||
; DB=$81, x=0, m=1
|
||||
NOP ; overwrites BNE $81DAE2 : JMP $DBED
|
||||
JML HandleActiveExp
|
||||
AwardExp:
|
||||
; isolate exp distribution into a subroutine, to be reused for both active party members and inactive characters
|
||||
org $81DAE9
|
||||
NOP #2 ; overwrites JMP $DBBD
|
||||
RTL
|
||||
org $81DB42
|
||||
NOP #2 ; overwrites JMP $DBBD
|
||||
RTL
|
||||
org $81DD11
|
||||
; DB=$81, x=0, m=1
|
||||
JSL HandleInactiveExp ; overwrites LDA $0A8A : CLC
|
||||
pullpc
|
||||
|
||||
HandleActiveExp:
|
||||
BNE + ; (overwritten instruction; modified) check if statblock not empty
|
||||
JML $81DBED ; (overwritten instruction; modified) abort
|
||||
+: JSL AwardExp ; award exp (X=statblock pointer, Y=position in battle order, $00=position in menu order)
|
||||
JML $81DBBD ; (overwritten instruction; modified) continue to next level text
|
||||
|
||||
HandleInactiveExp:
|
||||
LDA $F0201B ; load inactive exp gain rate
|
||||
BEQ + ; zero gain; skip everything
|
||||
CMP.b #$64
|
||||
BCS ++ ; full gain
|
||||
LSR $1607
|
||||
ROR $1606 ; half gain
|
||||
ROR $1605
|
||||
++: LDY.w #$0000 ; start looping through all characters
|
||||
-: TDC
|
||||
TYA
|
||||
LDX.w #$0003 ; start looping through active party
|
||||
--: CMP $0A7B,X
|
||||
BEQ ++ ; skip if character in active party
|
||||
DEX
|
||||
BPL -- ; continue looping through active party
|
||||
STA $153D ; inactive character detected; overwrite character index of 1st slot in party battle order
|
||||
ASL
|
||||
TAX
|
||||
REP #$20
|
||||
LDA $859EBA,X ; convert character index to statblock pointer
|
||||
SEP #$20
|
||||
TAX
|
||||
PHY ; stash character loop index
|
||||
LDY $0A80
|
||||
PHY ; stash 1st (in menu order) party member statblock pointer
|
||||
STX $0A80 ; overwrite 1st (in menu order) party member statblock pointer
|
||||
LDY.w #$0000 ; set to use 1st position (in battle order)
|
||||
STY $00 ; set to use 1st position (in menu order)
|
||||
JSL AwardExp ; award exp (X=statblock pointer, Y=position in battle order, $00=position in menu order)
|
||||
PLY ; restore 1st (in menu order) party member statblock pointer
|
||||
STY $0A80
|
||||
PLY ; restore character loop index
|
||||
++: INY
|
||||
CPY.w #$0007
|
||||
BCC - ; continue looping through all characters
|
||||
+: LDA $0A8A ; (overwritten instruction) load current gold
|
||||
CLC ; (overwritten instruction)
|
||||
RTL
|
||||
|
||||
|
||||
|
||||
; receive death link
|
||||
pushpc
|
||||
org $83BC91
|
||||
|
@ -1226,6 +1302,7 @@ pullpc
|
|||
; $F02018 1 party members available
|
||||
; $F02019 1 capsule monsters available
|
||||
; $F0201A 1 shop interval
|
||||
; $F0201B 1 inactive exp gain rate
|
||||
; $F02030 1 selected goal
|
||||
; $F02031 1 goal completion: boss
|
||||
; $F02032 1 goal completion: iris_treasure_hunt
|
||||
|
|
Binary file not shown.
|
@ -53,8 +53,9 @@ Your Party Leader will hold up the item they received when not in a fight or in
|
|||
- Randomize enemy movement patterns, enemy sprites, and which enemy types can appear at which floor numbers
|
||||
- Option to make shops appear in the cave so that you have a way to spend your hard-earned gold
|
||||
- Option to shuffle your party members and/or capsule monsters into the multiworld, meaning that someone will have to
|
||||
find them in order to unlock them for you to use. While cave diving, you can add newly unlocked members to your party
|
||||
by using the character items from your inventory
|
||||
find them in order to unlock them for you to use. While cave diving, you can add or remove unlocked party members by
|
||||
using the character items from your inventory. There's also an option to allow inactive characters to gain some EXP,
|
||||
so that new party members added during a run don't have to start off at a low level
|
||||
|
||||
###### Quality of life:
|
||||
|
||||
|
|
Loading…
Reference in New Issue