Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;Mgamerz Enhanced Enemies Mod v0.001
- ;12/17/2016
- ;Apply to MMBN3 ENGLISH WHITE version only! Apply with ARMIPS:
- ;armips filename.asm
- input equ whitevanilla.gba ; Put the name of your ROM here
- fspace equ 0x800000; Put the ROM free space offset here
- .gba
- .open input,output.gba,8000000h
- rngaddress EQU 0x080016a2|1b
- timestopchipcall EQU 08008E54h
- GetPlayer EQU 0x080013E0
- RecoveryChipRoutine EQU 0x80ADB04
- SpawnObject EQU 0x08003084
- ;FieldConfiguration EQU 0x
- SetPanelTeam EQU 0x0800B7C4
- PlaySound EQU 0x080005B8
- CalculateAIConstantsAddress EQU 0x080AEDBC
- GetPanelType EQU 0x0800B4F2
- SetInvincible EQU 0x080012B4
- SpawnLance EQU 0x080DE69E
- SpawnEnemyBoomer EQU 0x080DB2D4
- SpawnSnake EQU 0x080DD954
- SetPanelType EQU 0x0800B790
- GetPanelTeam EQU 0x0800BF06
- //Impacts
- FlinchAndInvisImpact EQU 0x3
- FlinchImpact EQU 0x1
- SuperArmorImpact EQU 0x0
- ;Plantman
- plantmanPostVinesDelayRoutine EQU 0x080C1D33
- plantmanVinesEndingIndex EQU 0x4 ;Multiply index by 4 - default 2 indices (0, 4), now has 0=chooser, starting at 4 for attacks.
- ;Flashman Chips
- flashmanchipcount EQU 1h
- flashmanChipHookAddress EQU 0x080B6726
- gutsmanChipHookAddress EQU 0x080B8592
- gutsmanZPunchHookAddress EQU 0x080B84C6
- gutsmanChipCount EQU 4h
- gutsmanZPunchChipCount EQU 3h
- gutsmanMovesBeforeZPunch EQU 6h
- teamfamily EQU 3Fh
- areafamily EQU 0h
- stagefamily EQU 4h
- trumpyfamily EQU 26h
- sensorfamily EQU 3Eh
- grabbackfamily EQU 15h
- mpchipfamily EQU 18h
- div EQU swi 6
- .org 0x08235154 ;Free Space
- .area 0xDAC
- .align 2
- rngRoutine:
- ldr r0, =rngaddress
- bx r0
- pop r15
- ;setPanelToTeam:
- ; ldr r0 =fieldConfiguration
- ;callTimestopChipWithoutTimestop:
- ;requires routine and parameters.
- ;healSelf:
- ;r0 = how much to heal
- ;r5 = who to heal
- ;bl RecoveryChipRoutine
- ;===========================FLASH MAN==========================
- armRaiseMove:
- ;Hijack at 080D7A66
- push r1-r3,r5,r6
- push r14
- ;b performBulbSpawn
- push r0
- ldrh r0, [r5,24h] ;GetHP
- ldr r4, =12Ch
- cmp r0,r4
- pop r0
- bgt notInRecoveryThreshold
- inRecoveryThreshold:
- ldr r0, =0x7D ;how much HP to heal at level 0 (125)
- ldr r4, [r5,4h] ;get level
- add r4, r4, 1h ; prevents *0
- mul r0, r4 ;multiply how much HP to heal
- bl RecoveryChipRoutine
- mov r1, 0h ;0 = Navi Pixelated Summon
- strb r1,[r5, 0xC]
- mov r1, 1h ;Give Flashman another chip to use as he may run out.
- strb r1,[r5,0x1A] ;0xA offset is how many chips an AI have to use, but r5 is incremented by 4 here for some reason.
- pop r1
- pop r1-r3,r5,r6; including get rid of return address, we will set our own to resume control
- ldr r0, =080D7A84h|1b
- bx r0 ;ignore post spawn
- notInRecoveryThreshold:
- push r1-r3
- bl rngRoutine ;GET RNG result AND PUT INTO r0
- mov r1, 02h ;remainder 0 = steal, anything else = bulbs
- swi 6; Divide, remainder is in r1
- mov r0, 0h
- cmp r0, r1
- pop r1
- pop r2
- pop r3
- bne performBulbSpawn
- stealPanels:
- ;position is on the stack it seems...?
- ;Make the areagrab noise since it won't automatically
- mov r0, 0x78
- bl PlaySound
- mov r0, 9h
- b armRaiseFinish
- pop r1-r3,r5,r6
- ldr r0, =080D7A84h|1b
- bx r0 ;ignore post spawn
- performBulbSpawn:
- mov r0, 11h
- armRaiseFinish:
- bl SpawnObject
- pop r15 ;finish
- snakeTrace:
- push r14
- bl GetPlayer ;load X,Y into r0 r1
- ;r0 - Player Current X
- ;r1 - Player Current Y
- push r1
- push r3 ;temporary variable
- ldr r1, [sp,0xC] ;next X pos of bulb
- add r1, r1, 1h
- cmp r0, r1 ;compare next X+1 (same) vs Megaman's X
- ldrb r2,[r5,13h] ; highjacks at 080D7688 ;Current Y position
- bne snakeTraceNotLinedUp ;exit if numbers aren't the same
- snakeTraceLinedUp:
- pop r3
- pop r0 ;Player Y
- cmp r2, r0 ;compare Y coordinates. also used by the routine we return to
- bne snakeTraceDifferentYs
- b snakeTraceLinedUpExit ;same Ys.
- snakeTraceDifferentYs:
- str r1, [sp,0x4] ;store same X if our current Y is not the same as the player Y (hit and leave field)
- snakeTraceLinedUpExit:
- pop r15
- snakeTraceNotLinedUp:
- pop r3
- mov r1, 1h
- cmp r1, 1h ;force same y
- pop r1
- ;mov r2, 1h
- ;cmp r2, 2h ;Same Y
- pop r15
- loadFlashmanRandomChip:
- push r14
- bl rngRoutine ;GET RNG result AND PUT INTO r0
- mov r1, flashmanchipcount ;number of chips in selection list
- swi 6; Divide
- ldr r0,=@@flashmanChipLookupTable ;Load address of chip lookup table (defined below)
- mov r2,0x03 ; Load r2 with 3
- mul r1,r2 ;Multiply the remainder result by the size of the structs (3 bytes) - this will provide an offset into the chip lookup table
- add r0,r0,r1 ;calculate the address using the offset, store in r0
- ldrb r3, [r0,0x02] ;load byte from *r0 (offset 2 forward) into r3 (dmg)
- ldrb r1, [r0,0x01] ;load byte from *r0 (offset 1 forward) into r1 (sublevel)
- ldrb r0, [r0,0x00] ;load byte from *r0 (direct addr) into r0 (family)
- ldrb r2,[r5,16h] ; ...this is actually the object's alliance enemy/allied
- pop r15
- .pool
- @@flashmanChipLookupTable:
- ;.byte teamfamily, 1h, 0h
- .byte areafamily, 0h, 10h
- ;.byte stagefamily, 4h, 0h
- ;.byte trumpyfamily, 2h, 0h
- ;Flashman zap throwdown
- .align 4
- flashmanThrowdownAction:
- push r1,r2,r5,r6
- push r14
- bl rngRoutine ;GET RNG result AND PUT INTO r0
- mov r1, 0x3 ;number of available actions
- swi 6; Divide
- ldr r0,=flashmanThrowdownLookupTable ;Load address of actions
- add r0,r0,r1 ;calculate the address using the offset, store in r0
- ldrb r1, [r0, 1h] ;sound check
- ldrb r0, [r0] ;action
- tst r1, r1
- bne playThrowdownSFX
- b finishFlashmanThrowdown
- playThrowdownSFX:
- push r0
- mov r0, r1
- bl PlaySound
- pop r0
- finishFlashmanThrowdown:
- pop r15
- .pool
- flashmanThrowdownLookupTable:
- .byte 0x35, 0x00 ;Mine
- .byte 0x3A, 0x9D ;YoYo
- .byte 0x10, 0x00 ;ZapAttack
- ;-----------------------------GUTS MAN----------------------
- ;This block is unused right now due to spam issues
- ;loadGutsmanRandomChip:
- ;push r14
- ;bl rngRoutine
- ;mov r1, gutsmanchipcount
- ;swi 6; Divide
- ;ldr r0,=@@gutsmanChipLookupTable ;Load address of chip lookup table (defined below)
- ;mov r2,0x03 ; Load r2 with 3
- ;mul r1,r2 ;Multiple the remainder result by the size of the structs (3 bytes) - this will provide ;an offset into the chip lookup table
- ;add r0,r0,r1 ;calculate the address using the offset, store in r0
- ;ldrb r3, [r0,0x02] ;load byte from *r0 (offset 2 forward) into r3 (dmg)
- ;ldrb r1, [r0,0x01] ;load byte from *r0 (offset 1 forward) into r1 (sublevel)
- ;ldrb r0, [r0,0x00] ;load byte from *r0 (direct addr) into r0 (family)
- ;ldrb r2,[r5,16h] ; ...this is actually the object's alliance enemy/allied
- ;pop r15
- ;.pool
- ;@@gutsmanChipLookupTable:
- ;.byte teamfamily, 0h, 0h
- ;.byte areafamily, 1h, 10h
- ;.byte stagefamily, 4h, 0h
- ;.byte trumpyfamily, 1h, 0h
- ;.align 4
- loadZPunchRandomChip:
- .align 2
- push r14
- bl rngRoutine
- mov r1, gutsmanZPunchChipCount
- swi 6; Divide
- ldr r0,=@@gutsmanZPunchLookupTable ;Load address of chip lookup table (defined below)
- mov r2,0x03 ; Load r2 with 3
- mul r1,r2 ;Multiple the remainder result by the size of the structs (3 bytes) - this will provide an offset into the chip lookup table
- add r0,r0,r1 ;calculate the address using the offset, store in r0
- ldrb r3, [r0,0x02] ;load byte from *r0 (offset 2 forward) into r3 (dmg)
- ldrb r1, [r0,0x01] ;load byte from *r0 (offset 1 forward) into r1 (sublevel)
- ldrb r0, [r0,0x00] ;load byte from *r0 (direct addr) into r0 (family;)
- ldrb r2,[r5,16h] ; ...this is actually the object's alliance enemy/allied
- pop r15
- .pool
- @@gutsmanZPunchLookupTable:
- ;.byte teamfamily, 0h, 0h
- ;.byte areafamily, 1h, 10h
- ;.byte stagefamily, 4h, 0h
- .byte trumpyfamily, 2h, 0h
- .byte sensorfamily, 2h, 100h
- .byte mpchipfamily, 2h, 0h
- ;=================GRAB REVENGE===========
- .align 2
- grabRevengeResetBoard:
- push r14
- //Read what team called this chip 00 = Player 04 = Enemy. This conveniently also means the return value can be used as an offset to the list of timer pointers
- ldrb r0, [r5,6h]
- //lsr r2, r2, 2h //Divide by 4 - 1 is enemy 0 is us
- //mul r1, r2, 4h ;0x4 = no offset, 1x4 = 2nd offset (enemy team offset in the pool)
- ldr r1, =GrabRevengeMemoryTimerPointer
- //ldr r1, [r1] //Load pointer to first item in pool
- add r0, r1, r0 //get offset in the pool below
- ldr r0, [r0] //load the value into 40 from there
- mov r1, 5h ;timer value to set, will be incremented by 15 frames every time to create a nice
- push r2,r3
- mov r2, 0h
- mov r3, 2h ;0-2 columns
- returnColumnsInCascade:
- strh r1, [r0] ;Set the current timer of panels to 5 frames. After those 5 frames the panels will return
- add r0, r0, 4h ;Go to next position for next row.
- push r0
- mov r0, 20h
- add r1, r1, r0
- pop r0
- //add r1, r1, 7h;Add 14 frames for cascade
- //add r1, r1, 7h;Add 14 frames for cascade
- add r2, r2, 1h ;Update counter
- cmp r2,r3
- ble returnColumnsInCascade
- pop r2,r3
- mov r0, 5h ;original code
- mov r1, 4h ;original code
- pop r15
- .pool
- GrabRevengeMemoryTimerPointer:
- .dw 0200F7A4h ;Panels that the enemy stole from you will reset
- .dw 0200F7B0h ;Panels that the player stole from the other team will reset
- //=========================FLAME MAN======================================
- flamemanNextCandleStateRandom: //return next state on r0.
- push r14
- push r2
- push r3
- strb r0, [r5,6h]
- bl rngRoutine
- mov r1, 4h //Number of candle states
- div //r1 = remainder
- mov r0, r1
- pop r3
- pop r2
- pop r15
- flamemanYellowGuyChangeToHorizontalOnSameRowAsPlayer:
- push r14
- push r0-r2
- bl GetPlayer ;r0 = X, r1 = Y
- mov r3, r1 //Put player Y in r3
- pop r0-r2
- ldr r1,[r5,44h]
- tst r1,r1
- pop r15
- flamemanYellowGuyChangeToVerticalOnSameColumnAsPlayer:
- push r14
- push r0-r2
- bl GetPlayer ;r0 = X, r1 = Y
- mov r3, r0 //Put player X in r3
- pop r0-r2
- ldr r1,[r5,40h]
- tst r1,r1
- pop r15
- flamemanLevelUpCandleExtinguished:
- push r14
- push r1,r2
- ldrb r0, [r5,0Ch] //Read state that is being extinguished
- //Check if it is 0x4 (Level Up)
- cmp r0, 8h //8 as its left shifted by 1.
- bne @@flamemanCandleExtinguishedFinish
- //We are extinguishing a level up flame
- ldr r0,[r5,4Ch] //Get Pointer To Parent
- ldrb r2, [r0,4h] //Get current level
- sub r2, 1h
- strb r2,[r0,4h] //Store level -1
- bl flamemanUpdateAIConstantsAddress
- @@flamemanCandleExtinguishedFinish:
- pop r1,r2
- mov r0, 0h //Original Code
- strb r0,[r5,0Ch] //Original Code
- pop r15
- flamemanLevelUpCandleActivating:
- push r1,r2,r14
- ldrh r0, [r5,20h] //Read activation timer
- cmp r0, 0h
- bne @@flamemanEndCandleActivation
- add r0, 1h
- strh r0, [r5,20h] //Set candle timer to 1 (it doesn't count down while active) to indicate this effect has already been applied
- ldrh r0, [r5,24h] //Get HP
- lsl r0, r0, 0x2 //Quadruple HP
- strh r0, [r5,24h]
- //strh r0, [r5,26h]
- ldr r0,[r5,4Ch] //Get Pointer To Parent
- ldrb r2, [r0,4h] //Get current level
- add r2, 1h
- strb r2,[r0,4h] //Store level +1
- bl flamemanUpdateAIConstantsAddress //R0 = FlamemanPointer, R2 = Level
- @@flamemanEndCandleActivation:
- pop r1,r2,r15
- .align 4
- flamemanCustomCandleActivationArray:
- .word 0x080E2CC9 //Green Empty Function
- .word 0x080E2CCD //Red Empty Function
- .word 0x080E2CD1 //Yellow Empty Function
- //NEW ONE HERE //NEW Level Up Startup Function
- .word flamemanLevelUpCandleActivating|1b
- flamemanUpdateAIConstantsAddress:
- push r14
- push r5 //This operation requires r5 to point to flameman memory
- mov r5, r0 //Update R5 with the one referenced by the candle parent
- ldr r0, =flamemanNewAIData ;Flameman AI Base
- mov r1, 0Ah ;Flameman's data is 0xA bytes wide per level
- bl CalculateAIConstantsAddress
- pop r5
- pop r15
- .pool
- //Flameman New AI Data
- flamemanNewAIData:
- // 0 1 2 3 4 5 6 7 8 9
- .byte 0x3C,0x3C,0x3C,0x1E,0x2D,0x08,0xA4,0x0A,0x10,0x78 //Normal
- .byte 0x64,0x50,0x50,0x19,0x28,0x0C,0x90,0x09,0x18,0x64 //Alpha
- .byte 0x96,0x96,0x96,0x14,0x23,0x15,0x70,0x08,0x20,0x50 //Beta
- .byte 0xC8,0xC8,0xC8,0x0F,0x1E,0x20,0x58,0x06,0x20,0x3C //Omega
- .byte 0xE1,0xE1,0xE1,0x0A,0x0F,0x25,0x44,0x03,0x28,0x28 //Omega + 1
- .byte 0xFA,0xFA,0xFA,0x05,0x0A,0x28,0x40,0x01,0x30,0x16 //Omega + 2
- //Candle info
- //[02038A74]=CURRENT SELF POINTER
- //[02038AC0]=PARENT POINTER
- //r5+4C = Parent Pointer
- flamemanAdditionalAttacksWithLevelUpCandleCheck:
- push r0-r2,r14
- mov r0, #0x0 //init bitmask
- //Check Candle 1
- ldr r1, [r5,#0x60]
- tst r1,r1 //Candle 1 is not null check
- beq @@CheckCandle2
- ldrb r2, [r1,#0xC]
- orr r0, r2 //add effect to bitmask
- //Check Candle 2
- @@CheckCandle2:
- ldr r1, [r5,#0x64]
- tst r1,r1 //Candle 2 is not null check
- beq @@candleEffectCheck
- ldrb r2, [r1,#0xC]
- orr r0, r2
- @@candleEffectCheck:
- //8 = Leveled Up
- mov r1, 8h
- and r0, r1
- tst r0, r0
- beq @@flamemanLaunchStandardFlameAttack
- //Different Flame Attack
- @@flamemanLaunchDifferentFlameAttack:
- bl rngRoutine ;GET RNG result AND PUT INTO r0
- mov r1, 0x4
- swi 6
- tst r1,r1
- bne @@flamemanLaunchModifiedFlameAttack
- @@flamemanSpawnFireRatn:
- //Check if square we are going to spawn in is occupied by something. If it is, we shouldn't spawn a ratton
- pop r0-r2
- push r0-r2 //we might still need these...
- mov r0, r1
- mov r1, r2 //move positions to correct registers
- bl GetPanelType
- mov r1, 0xE
- lsl r1, r1, 0x18 //Occupied mask
- //mov r1, 0x10 //broken panel mask
- //orr r0, r1 //also check if panel is broken
- tst r0, r1
- bne @@flamemanLaunchModifiedFlameAttack //it is occupied
- //Spawn Ratton
- pop r0-r2 //Discard
- mov r0, 0xC8 //HP of Object
- mov r3, 1h //Enemy Team
- mov r4, 0h //Memory Space that will be assigned to this object on spawn (by spawnobject)
- mov r6, 0xE6 //230 Damage
- bl 0x080DA218 ;SpawnRatton
- pop r15
- @@flamemanLaunchModifiedFlameAttack:
- //Recover a small amount of HP
- push r4
- ldr r0, =0xA ;how much HP to heal at level 0 (125)
- ldrb r4, [r5,4h] ;get level
- add r4, r4, 1h ; prevents *0
- mul r0, r4 ;multiply how much HP to heal
- bl RecoveryChipRoutine
- pop r4
- mov r0, 30h
- lsl r1, r1, 18h
- orr r4, r1
- @@flamemanLaunchStandardFlameAttack:
- pop r0-r2
- bl 0x080E317E ;FlamemanSpawnInitialFlameTower
- pop r15
- .align 4
- .pool
- @@FlamemanCustomFlameAttackPattern:
- .word 0x06280C00 //Straight Flame
- .word 0x02241401 //WideFlame
- .word 0x32241401 //WideFlame, goes 3 rows deep (at least)
- .word 0x02241400
- //========================PLANT MAN================================
- setImpactEffect:
- //r0 = Object Memory
- //r3 = Impact Effect Bitmask (0x3 = Flinch + Invis, 0x1 = Flinch, 0x0 = Nothing)
- ldr r1,[r0,0x60]
- strb r3,[r1,0xA]
- mov r15,r14
- createCoordinateByte:
- //r0 = X
- //r1 = Y
- lsl r0, r0, 4h
- orr r0, r1
- mov r15, r14
- getFarthestRightPlayerColumn:
- push r14
- mov r0, 0h //Y
- mov r1, 0h //X
- mov r2, 0h //Farthest X
- @@incrementY:
- add r0, 1h //Y++
- cmp r0, 3h //Y > 3
- bgt @@returnFarthestRow
- mov r1, 0h //X = 0
- @@incrementX:
- add r1, 1h //X++
- push r0-r3 //Push Values
- mov r2, 0x10
- mov r3, 0x08
- lsl r3, r3, 0x18
- bl GetPanelTeam //team on r1, address on r2
- tst r0,r0 // 1 = red team...?
- pop r0-r3
- beq @@incrementY //next row
- cmp r1, r2
- blt @@continueLoop
- mov r2, r1 //FarthestX = New X
- @@continueLoop:
- //pop r0-r2
- cmp r1, 6h // X > 6
- bgt @@incrementY
- b @@incrementX
- @@returnFarthestRow:
- mov r0, r2
- pop r15
- getNumPanelsForPlayer:
- push r14
- mov r0, 0h //Y
- mov r1, 0h //X
- mov r2, 0h
- incrementY:
- add r0, 1h //Y++
- cmp r0, 3h //Y > 3
- bgt returnNumPanels
- mov r1, 0h //X = 0
- incrementX:
- add r1, 1h //X++
- push r0-r2
- bl GetPanelTeam
- tst r0,r0 // 0 = red team
- bne continueLoop
- add r2, 1h //Team Panel
- continueLoop:
- pop r0-r2
- cmp r1, 6h // X > 6
- bgt incrementY
- b incrementX
- returnNumPanels:
- pop r15
- splitByteToPosition:
- //r0 input = byte with X in upper 4 bits, lower 4 bits being Y
- push r2,r14
- lsr r2, r0, #0x4 //X - this can only be loaded with 8 bits so discard the bottom 4
- lsl r1, r0, #0x1D //register is 32 bits wide so shift 28 left to discard bits 7-4
- lsr r1, r1, #0x1D
- mov r0, r2 //put X into r0
- pop r2,r15
- getRandomPositionWithLessThanXIgnoringR3:
- push r5,r14
- //r2 = Farthest X we can choose.
- //r3 = 32-bits of 8 bit coordinates that should not be chosen
- //Internal r4 is the number of attempts. After so many attempts we will give up to prevent deadlock
- //Internal r5 the original register we can restore to r3 if we find a bad coordinate
- mov r4, 0h //attempts = 0
- mov r5, r3 //cache the ignored bytes
- mov r6, r2 //cache farthest right as r6
- @@GetRandomCoordinatesInRange:
- cmp r4, 9h
- bgt @@GiveUpFindingCoordinate
- bl rngRoutine
- mov r1, r6 //farthest right
- swi 6
- add r1, 0x1 //remainder + 1 is our X
- push r1 //pop as r0
- bl rngRoutine
- mov r1, 0x3 //Max Y
- swi 6
- add r1, 0x1 //remainder + 1 is our Y.
- pop r0 //X
- bl createCoordinateByte
- mov r3, r5 //Restore Ignored Bytes
- @@emptyR3RegisterLoop:
- //r0 = coordinate to check
- mov r1, #0xFF
- and r1, r3 //keep only bottom 8 bits
- tst r1,r1 //check if 00. if it is we have nothing left to check.
- beq @@FinishFindingCoordinate
- cmp r0, r1 //Test if values are the same
- beq @@CoordinateShouldBeIgnored
- lsr r3, r3, 0x08 //next coordinate check
- b @@emptyR3RegisterLoop
- @@CoordinateShouldBeIgnored:
- add r4, 0x1
- b @@GetRandomCoordinatesInRange
- @@GiveUpFindingCoordinate:
- mov r0, 0h
- @@FinishFindingCoordinate:
- pop r5,r15
- plantmanInvincibilityCheck:
- push r14
- ldrb r0,[r5,0x12] ;GetX
- ldrb r1,[r5,0x13] ;GetY
- bl GetPanelType //Returns on r0
- mov r1, #0x4
- lsl r1, r1, #0x8 //Grass Bitmask
- tst r0, r1
- beq plantmanEndInvincibilityCheck
- plantmanStandingOnGrass:
- ldrb r0,[r5,0x4] ;Get Level
- mov r1, #0x2 //Beta or higher
- cmp r0, r1
- blt plantmanEndInvincibilityCheck
- plantmanSetInvincible:
- mov r0, #0x1D ;Enemy Invincibility apparently
- bl SetInvincible
- plantmanEndInvincibilityCheck:
- bl #0x08000F58 //Original Hook Code
- pop r15
- plantmanLanceRowAttack:
- push r14
- ldrb r0,[r5,#0xB]
- tst r0, r0 //Check that we are busy
- bne plantmanLanceRowDecrementEndingTimer
- //Setup Damage
- mov r6,#0x8C //Get AI Constants Offset
- ldr r6,[r5,r6]
- ldrb r6,[r6,#0x2] //Set Damage
- bl GetPlayer
- ;r0 - Player Current X
- mov r2, 1h //if player is in back row
- cmp r0, r2
- beq plantmanLance
- //Check our HP, snakes on lower HP, needles on higher
- ldrh r0,[r5,0x24]
- ldrh r1,[r5,0x26]
- lsr r1, r1, 0x1
- cmp r0, r1
- blt plantmanHalfHPBasicAttack //Half HP or less
- b plantmanNeedle //Half HP More
- plantmanNeedle:
- mov r6,#0x8C //Get AI Constants Offset
- ldr r6,[r5,r6]
- ldrb r1,[r5,#0x12] ;My X Value
- ldrb r2,[r5,#0x13] ;My Y Value
- ldrb r3,[r6,#0x3] //Speed of Needle
- ldrb r6,[r6,#0x2] //Damage of Needle
- lsl r3, r3, 0xC
- bl 0x080E07D6 //SpawnNeedle()
- b plantmanAttackCleanup
- plantmanLance:
- mov r0, #0x4
- strb r0,[r5,#0x10]
- mov r1, #0x1 //Players X column
- mov r2, #0x3
- lsr r6, r6, 0x1
- plantmanLanceSpawnLoop:
- mov r0, 4h //Element
- mov r7, 3h //Impact Effect
- bl SpawnLance
- //push r3
- //mov r3, FlinchAndInvisImpact
- //mov r0, r7 //oldwood pillar memory
- //bl setImpactEffect
- //pop r3
- sub r2, #0x1
- bne plantmanLanceSpawnLoop
- b plantmanAttackCleanup
- plantmanHalfHPBasicAttack:
- //Randomly choose an attack (boomer or snake)
- //bl rngRoutine
- //mov r1, #0x2
- //swi 6
- //tst r1,r1
- //beq plantmanSnake
- b plantmanSnake
- plantmanBoomer:
- mov r0, 0xB7 ;Boomer Throw
- bl PlaySound
- mov r1, 6h //Spawn position
- ldrb r2,[r5,#0x13] ;My Y Value
- ldrb r0,[r6,#0x3] //Speed of Boomer
- lsl r0, r0, 0xB
- //mov r7, 3h //Impact Effect
- push r6
- mov r6, 0x1E
- bl SpawnEnemyBoomer
- pop r6
- b plantmanAttackCleanup
- plantmanSnake:
- //end
- bl GetPlayer
- mov r2, r0
- mov r3, r1
- //start
- ldrb r0,[r5,0x12]
- ldrb r1,[r5,0x13]
- //mov r2, 0x2
- //mov r3, 0x2
- mov r4, 0x64 //Damage
- bl SpawnSnake
- b plantmanAttackCleanup
- plantmanAttackCleanup:
- mov r0, #0x4
- strb r0,[r5,#0x10]
- mov r0,#0x1E
- strh r0,[r5,#0x20]
- mov r0, #0x4
- strb r0,[r5,#0xB]
- b plantmanLanceRowAttackEnd
- plantmanLanceRowDecrementEndingTimer:
- ldrh r0,[r5,#0x20]
- sub r0, #0x1
- strh r0,[r5,#0x20]
- bgt plantmanLanceRowAttackEnd
- mov r0, #0x8
- strh r0,[r5,#0xA]
- plantmanLanceRowAttackEnd:
- pop r15
- plantmanVinesInGroundAttackChooser:
- push r14
- //Check panel standing on
- ldrb r0,[r5,0x12] //X
- ldrb r1,[r5,0x13] //Y
- bl GetPanelType //Returns on r0
- mov r1, #0x4
- lsl r1, r1, #0x8 //Grass Bitmask
- tst r0, r1
- beq plantmanAttackChoosingNotStandingOnGrass
- plantmanAttackChoosingStandingOnGrass:
- //Check HP
- ldrh r0,[r5,#0x24]
- ldrh r1,[r5,#0x26]
- lsr r1,r1,#0x1 //divide max HP by 2
- cmp r0, r1
- bge plantmanOnGrassMoreThanHalfHP
- //less than half HP, on grass. Restore HP.
- mov r0, 0x8 //Restore HP Vines
- b plantmanVinesInGroundAttackChooserEnd
- //On grass panel but not at less than half HP
- plantmanOnGrassMoreThanHalfHP:
- bl rngRoutine
- mov r1, #0x2
- swi 6
- mov r0, 0x4
- //r1 = remainder
- mul r1, r0
- mov r0, 0x10 //start of normal attacks
- add r0, r0, r1
- b plantmanVinesInGroundAttackChooserEnd
- plantmanAttackChoosingNotStandingOnGrass:
- //mov r1, 0x2 //attacks that don't restore HP directly
- bl rngRoutine
- mov r1, #0x3 //+1 chance to grass spawn
- swi 6
- tst r1,r1
- beq plantmanForceGrassSpawn
- sub r1, 0x1 //subtract one since its already 1 or 2
- mov r0, 0x4
- //r1 = remainder
- mul r1, r0
- mov r0, 0xC //start of normal attacks
- add r0, r0, r1
- b plantmanVinesInGroundAttackChooserEnd
- plantmanForceGrassSpawn:
- mov r0, 0xC
- b plantmanVinesInGroundAttackChooserEnd
- plantmanVinesInGroundAttackChooserEnd:
- strb r0,[r5,0xA]
- pop r15
- SpawnOldWoodPillarObject EQU 0x080E0684
- plantmanVinesSpawnOldWood:
- push r14
- ldrb r0, [r5,#0xB]
- tst r0, r0 //Check that we are busy
- bne plantmanVinesSpawnOldWoodDecrementTimer
- //First loop here. Set timers and set busy
- mov r0, #0x1E
- strh r0,[r5,#0x20]
- mov r0, #0x3
- strb r0,[r5,#0x10]
- mov r0, #0x4
- strb r0,[r5,#0xB]
- ldrb r0,[r5,0x4]
- add r0, 0x1
- strb r0,[r5,0x6] //Number of times we should do spikes
- b plantmanVinesSpawnOldWoodAttackEnd
- plantmanVinesSpawnOldWoodDecrementTimer:
- ldrh r0,[r5,#0x20]
- sub r0, #0x1
- strh r0,[r5,#0x20]
- //Make Invincible while using super grass attack
- push r0
- mov r0, #0x1D ;Enemy Invincibility apparently
- bl SetInvincible
- pop r0
- mov r1, #0x1
- cmp r0, r1 //When timer hits 1
- bne plantmanVinesSpawnOldWoodAttackEnd
- //Play the sound
- mov r0, #0x5 //Make plantman vines in ground wiggle sprite
- strb r0,[r5,#0x10]
- bl GetPlayer
- push r0
- bl createCoordinateByte
- mov r3, r0 //Byte of coordinate
- pop r0
- mov r2, r1 //Y
- mov r1, r0 //X
- push r3 //save megaman's pos
- mov r0, 0x4
- mov r3, 0x4
- mov r4, 0x4 //seems important for some reason...
- mov r6, 0x64 //Damage...?
- mov r7, 3h //Impact Effect
- bl SpawnOldWoodPillarObject
- push r3
- mov r3, FlinchAndInvisImpact
- mov r0, r7 //oldwood pillar memory
- bl setImpactEffect
- pop r3
- //Spawn Extra Wood Setup
- bl getFarthestRightPlayerColumn
- mov r2, r0 //farthest X we can choose
- pop r3 //Megaman's position. We'll left shift this with the new spawn position up to 3 times for a full 32-bits of stored wood coordinates
- mov r0, 0h //how many wood we've spawned
- push r0
- plantmanSpawnAdditionalWood:
- pop r0
- add r0, 0x1 //spawning a new wood
- push r0
- push r3
- bl getRandomPositionWithLessThanXIgnoringR3
- //r0 = random position where X < r4 and nothing in r3 is chosen.
- pop r3
- lsl r3, 0x8
- orr r3, r0 //New coordinate is added to the register of used positions
- bl splitByteToPosition
- //Spawn Wood
- mov r2, r1 //Y
- mov r1, r0 //X
- mov r0, 0x4
- mov r3, 0x4
- mov r4, 0x4 //seems important for some reason...
- mov r6, 0x64 //Damage...?
- mov r7, 3h //Impact Effect
- bl SpawnOldWoodPillarObject
- ldrb r1,[r5,0x4] //Get Level
- add r1, 0x1 //0 based
- ldr r0,[sp] //How many wood have spawned
- cmp r0, r1
- blt plantmanSpawnAdditionalWood
- //All wood spawned
- ldrb r0,[r5,0x6]
- sub r0, 0x1
- strb r0,[r5,0x6]
- tst r0,r0
- beq plantmanVinesSpawnOldWoodCleanup
- //Spawn More In a few seconds
- mov r0, #0x40 //Timer Value
- mov r1, #0x20 //Timer Offset
- strb r0,[r5,r1] //Next Timer
- b plantmanVinesSpawnOldWoodAttackEnd
- //tst r7,r7
- //beq plantmanOldWoodFailed
- //ldrb r0,[r7]
- //mov r1, #0x10
- //orr r0, r1
- //strb r0,[r7] //seems to be timestop related...
- ; ldr r4, =plantmanGrassSpawningArray
- ; ldrb r3,[r5,#0x6] ;Get initial offset into the array
- ; push r3 //push the original offset value
- ; add r4, r4, r3 //Base offset
- ; ldrb r3,[r4] //Get first byte of our offset. This is how many panels will be spawned
- ; tst r3,r3
- ;beq plantmanVinesSpawnOldWoodCleanup //Hit end marker 00
- //plantmanOldWoodFailed:
- // b plantmanVinesSpawnOldWoodCleanup
- //mov r0, #0x10
- //add r0, #0xFF
- //bl PlaySound //Play Brushman Noise
- //mov r7, 0x0 //how many panels have spawned so far
- //plantmanSpawnOldWoodPanel:
- // add r7, 0x1
- // ldrb r0,[r4,r7] //panel position to spawn at
- // bl splitByteToPosition
- // mov r2, 0x6 //Grass type
- // push r3-r4,r7
- // bl SetPanelType //X Y TYPE
- // pop r3-r4,r7
- // //Check if we have more panels to spawn
- // cmp r7, r3
- // blt plantmanSpawnOldWoodPanel
- //Store next offset
- ; pop r3 //the original offset
- ; add r7, 0x1
- ; add r3, r3, r7
- ; strb r3,[r5,#0x6] //Store next starting offset
- ; ldrb r3,[r4,r7]
- ; tst r3,r3 //if 00 we hit the end
- ; beq plantmanVinesSpawnOldWoodCleanup
- //Set next timer
- //mov r0, #0x15
- //mul r0, r3
- //strh r0,[r5,#0x20] //next timer = 0x15*num panels to spawn next
- //b plantmanVinesSpawnOldWoodAttackEnd
- plantmanVinesSpawnOldWoodCleanup:
- pop r0 //Get rid of how many wood we've spawned
- //Reset panel i'm on.
- ldrb r0,[r5,0x12]
- ldrb r1,[r5,0x13]
- mov r2, 0x2; Normal Panel
- bl SetPanelType
- mov r0, 0x91 ;Chippoof
- bl PlaySound
- mov r0, plantmanVinesEndingIndex
- strh r0,[r5,#0xA]
- plantmanVinesSpawnOldWoodAttackEnd:
- pop r0
- pop r15
- plantmanVinesSpawnGrass:
- push r14
- ldrb r0,[r5,#0xB]
- tst r0, r0 //Check that we are busy
- bne plantmanVinesSpawnGrassDecrementTimer
- //First loop here. Set timers and set busy
- mov r0, #0x1E
- strh r0,[r5,#0x20]
- mov r0, #0x3
- strb r0,[r5,#0x10]
- mov r0, #0x4
- strb r0,[r5,#0xB]
- mov r0, #0x0 //Current offset into spawning array
- strb r0,[r5,#0x6]
- b plantmanVinesSpawnGrassAttackEnd
- plantmanVinesSpawnGrassDecrementTimer:
- ldrh r0,[r5,#0x20]
- sub r0, #0x1
- strh r0,[r5,#0x20]
- mov r1, #0x1 //stop on timer = 1
- cmp r0, r1
- bne plantmanVinesSpawnGrassAttackEnd
- //Play the sound
- mov r0, #0x5 //Make plantman vines in ground wiggle sprite
- strb r0,[r5,#0x10]
- ldr r4, =plantmanGrassSpawningArray
- ldrb r3,[r5,#0x6] ;Get initial offset into the array
- push r3 //push the original offset value
- add r4, r4, r3 //Base offset
- ldrb r3,[r4] //Get first byte of our offset. This is how many panels will be spawned
- tst r3,r3
- beq plantmanVinesSpawnGrassCleanup //Hit end marker 00
- mov r0, #0x10
- add r0, #0xFF
- bl PlaySound //Play Brushman Noise
- mov r7, 0x0 //how many panels have spawned so far
- plantmanSpawnGrassPanel:
- add r7, 0x1
- ldrb r0,[r4,r7] //panel position to spawn at
- bl splitByteToPosition
- push r0,r1
- //Check to make sure its not broken
- bl GetPanelType //Returns on r0
- mov r1, #0x1
- lsl r1, r1, 0x8
- tst r0, r1
- pop r0,r1
- bne plantmanSkipPanel
- //not broken
- mov r2, 0x6 //Grass type
- push r3-r4,r7
- bl SetPanelType //X Y TYPE
- pop r3-r4,r7
- //Check our level for extra effects on player side
- // Beta = Sand, Omega = Poison
- ldrb r0,[r5,0x4]
- cmp r0, 2h //Min Level (Beta)
- blt plantmanFinishPanelChange
- ldrb r0,[r4,r7]
- sub r0, 0x30 //left 3 panels
- bl splitByteToPosition
- push r0,r1
- //Check to make sure its not broken
- bl GetPanelType //Returns on r0
- mov r1, #0x1
- lsl r1, r1, 0x8
- tst r0, r1
- pop r0,r1
- bne plantmanFinishPanelChange
- push r0
- ldrb r0,[r5,0x4]
- cmp r0, 2h //Min Level (Beta)
- pop r0
- bgt plantmanOmegaPanel
- beq plantmanBetaPanel
- b plantmanFinishPanelChange
- plantmanOmegaPanel:
- push r4,r5
- mov r5, 1h //palette
- mov r2, 0x4 //Poison
- b plantmanSetPlayersSidePanel
- plantmanBetaPanel:
- push r4,r5
- mov r2, 0xA //Sand
- mov r5, 4h //palette
- b plantmanSetPlayersSidePanel
- plantmanSetPlayersSidePanel:
- push r3,r7
- push r0,r1
- bl SetPanelType
- pop r0,r1
- bl 0x0801455A //Get Pixel Coordinates
- mov r2,r1
- mov r1,r0
- mov r4,r5
- bl 0x080EE26E // SpawnGeddonPoof
- pop r3,r7
- pop r4,r5
- b plantmanFinishPanelChange
- plantmanFinishPanelChange:
- //pop r3-r4,r7
- plantmanSkipPanel:
- //Check if we have more panels to spawn
- cmp r7, r3
- blt plantmanSpawnGrassPanel
- //Store next offset
- pop r3 //the original offset
- add r7, 0x1
- add r3, r3, r7
- strb r3,[r5,#0x6] //Store next starting offset
- ldrb r3,[r4,r7]
- tst r3,r3 //if 00 we hit the end
- beq plantmanVinesSpawnGrassCleanup
- //Set next timer
- mov r1, #0x6
- ldrb r0,[r5,0x4] //get level
- mul r1, r0
- mov r0, #0x20
- sub r0, r0, r1
- mul r0, r3
- strh r0,[r5,#0x20] //next timer = 0x20-(level*8)*numberPanelsToSpawn
- b plantmanVinesSpawnGrassAttackEnd
- plantmanVinesSpawnGrassCleanup:
- mov r0, plantmanVinesEndingIndex
- strh r0, [r5,#0xA]
- plantmanVinesSpawnGrassAttackEnd:
- pop r15
- .pool
- plantmanGrassSpawningArray:
- //Panels to spawn at each interval. Values need to be bitshifted to get their proper values separated
- .byte 0x1, 0x52
- .byte 0x2, 0x51, 0x53
- .byte 0x2, 0x42, 0x62
- .byte 0x4, 0x41, 0x61,0x43, 0x63
- .byte 0x0 //End marker
- plantmanVinesRestoreHP:
- push r14
- ldrb r0, [r5,#0xB]
- tst r0, r0 //Check that we are busy
- bne plantmanVinesRestoreHPTimerCheck
- mov r0, #0x76
- strh r0,[r5,#0x20]
- mov r0, #0x3
- strb r0,[r5,#0x10]
- //bl #0x080C1DF6 //PlantmanFindPositionToSpawnVineInRow
- //strb r0,[r5,#0x6]
- //strb r1,[r5,#0x7]
- mov r0, #0x4
- strb r0,[r5,#0xB]
- b plantmanVinesRestoreHPAttackEnd
- plantmanVinesRestoreHPTimerCheck:
- ldrh r0,[r5,#0x20]
- //cmp r0,#0x1E
- //bne plantmanVinesRestoreHPTimerCheckIsTen
- mov r1, #0x10
- strh r1,[r5,#0x30]
- lsr r0, r0, #0x2
- bcc plantmanVinesRestoreHPDecrementTimer
- ldrb r0, [r5,#0x6]
- ldrb r1, [r5,#0x7]
- //bl 0x0800B76C //unknown what this does
- plantmanVinesRestoreHPDecrementTimer:
- ldrh r0,[r5,#0x20]
- sub r0, #0x1
- strh r0,[r5,#0x20]
- //Make Invincible while using super grass attack
- push r0
- mov r0, #0x1D ;Enemy Invincibility apparently
- bl SetInvincible
- pop r0
- mov r1, #0x25 //every 25 frames, check to see if we should heal our HP.
- swi 6
- //r1 = remainder
- ldrb r0,[r5,#0x4]
- add r0,r0,#0x1 ;Set to level+X to make sure 1 bit is set.
- //and r0, r0, r1
- tst r0, r1
- beq plantmanTestIfSoundShouldPlay
- //RestoreHP
- //mov r0, #0x1
- push r1
- bl 0x080ADA0C //AddHPRoutine
- pop r1
- plantmanTestIfSoundShouldPlay:
- tst r1, r1
- bne plantmanVinesRestoreHPAttackEnd
- //Play the sound
- mov r0, #0x5 //Make plantman vines in ground wiggle sprite
- strb r0,[r5,#0x10]
- mov r0, #0x80
- bl PlaySound //Play Bass Fist Charging Noise
- ldrh r0,[r5,#0x20]
- tst r0,r0
- beq plantmanVinesRestoreHPCleanup
- b plantmanVinesRestoreHPAttackEnd
- plantmanVinesRestoreHPCleanup:
- ldrb r0,[r5,0x12]
- ldrb r1,[r5,0x13]
- mov r2, 0x2; Normal Panel
- bl SetPanelType
- mov r0, 0x91 ;Chippoof
- bl PlaySound
- mov r0, plantmanVinesEndingIndex
- strh r0,[r5,#0xA]
- plantmanVinesRestoreHPAttackEnd:
- pop r15
- plantmanVinesInGroundAttack:
- push r14
- ldrb r0,[r5,#0xB]
- tst r0, r0 //Check that we are busy
- bne plantmanVinesTimerCheck
- mov r0, #0x2B
- strh r0,[r5,#0x20]
- mov r0, #0x3
- strb r0,[r5,#0x10]
- bl #0x080C1DF6 //PlantmanFindPositionToSpawnVineInRow
- strb r0,[r5,#0x6]
- strb r1,[r5,#0x7]
- mov r0, #0x4
- strb r0,[r5,#0xB]
- b plantmanVinesInGroundAttackEnd
- plantmanVinesTimerCheck:
- ldrh r0,[r5,#0x20]
- cmp r0,#0x1E
- bne VineSproutCheckIfTimerIsTen
- mov r1, #0x10
- strh r1,[r5,#0x30]
- VineSproutCheckIfTimerIsTen:
- cmp r0, #0x10
- bge plantmanVineSproutDecrementTimer
- lsr r0, r0, #0x2
- bcc plantmanVineSproutDecrementTimer
- ldrb r0,[r5,#0x6]
- ldrb r1,[r5,#0x7]
- bl 0x0800B76C //unknown what this does
- plantmanVineSproutDecrementTimer:
- ldrh r0,[r5,#0x20]
- sub r0, #0x1
- strh r0,[r5,#0x20]
- bgt plantmanVinesInGroundAttackEnd
- plantmanVineSproutTimerZero:
- mov r0, #0x5
- strb r0,[r5,#0x10]
- ldrb r1,[r5,#0x6]
- tst r1,r1
- beq plantmanVineSproutCleanup
- ldrb r2,[r5,#0x7]
- mov r3,#0x8C
- ldr r3,[r5,r3]
- ldrb r6,[r3,#0x4]
- ldrb r3,[r3,#0x5]
- mov r0, #0x60
- strh r3,[r5,r0]
- ldrb r3,[r5,#0x4]
- mov r7,r5
- bl 0x80E09F4 //PlantmanSpawnVine
- plantmanVineSproutCleanup:
- mov r0, plantmanVinesEndingIndex
- strh r0,[r5,#0xA]
- plantmanVinesInGroundAttackEnd:
- pop r15
- plantmanVinesSpawnVine EQU 0x080C1CCC //Sprout a vine
- .pool
- plantmanVinesInGroundRoutinesArray:
- .word plantmanVinesInGroundAttackChooser|1b
- .word plantmanPostVinesDelayRoutine|1b //This is in the default game and we can share it across others it seems. The default goes to 0x4 so we need to keep this here.
- .word plantmanVinesRestoreHP|1b ;0x8
- .word plantmanVinesSpawnGrass|1b ;0xC
- .word plantmanVinesSpawnVine|1b ;0x10
- .word plantmanVinesSpawnOldWood|1b ;0x14
- //plantmanLowHPAttackRoutinesArray
- ; plantmanVinesSpawnFlowers EQU 0x080C1D7D //Sprout a vine
- ; .pool
- ; plantmanVinesInGroundRoutinesArray:
- ; .word plantmanVinesInGroundAttackChooser|1b
- ; .word plantmanPostVinesDelayRoutine|1b //This is in the default game and we can share it across others it seems. The default goes to 0x4 so we need to keep this here.
- ; .word plantmanVinesRestoreHP|1b ;0x8
- ; .word plantmanVinesSpawnGrass|1b ;0xC
- ; .word plantmanVinesSpawnVine|1b ;0x10
- ; .word plantmanVinesSpawnOldWood|1b ;0x14
- .endarea
- ;==================HOOKS================
- ;.org 0x080C1990
- ;plantmanGrassInvincibilityHook: //bl #0x08000F58
- ; bl plantmanInvincibilityCheck
- .org 0x080E2F84 //ldr r1,[r5,44h]
- flamemanYellowGuyYHook:
- bl flamemanYellowGuyChangeToHorizontalOnSameRowAsPlayer
- .org 0x080E2F2A //ldr r1,[r5,40h]
- flamemanYellowGuyXHook:
- bl flamemanYellowGuyChangeToVerticalOnSameColumnAsPlayer
- .org 0x080E2D46 //strb r0,[r5,6h]
- flamemanRandomCandleStateHook:
- push r14
- nop
- bl flamemanNextCandleStateRandom
- pop r15
- .org 0x080E2C10 //mov r0, 0h
- flamemanCandleExtinguishLevelUpHook:
- bl flamemanLevelUpCandleExtinguished
- .org 0x080C57C0 //bl FlameManSpawnInitialTower
- bl flamemanAdditionalAttacksWithLevelUpCandleCheck
- .org 0x080F9E9E
- grabRevengeResetBoardHook:
- bl grabRevengeResetBoard
- .org flashmanChipHookAddress
- flashmanChipHook:
- bl loadFlashmanRandomChip
- nop
- .org 0x080D7A66 ;Flashman Bulb Spawn (Arm Raise Move to heal)
- flashmanArmRaiseMoveHook:
- bl armRaiseMove
- nop
- nop
- .org 0x080D7664 ;In the Follow Trace Y calculation area (will only affect follow and not zigzag tracer)
- snakeTraceHook:
- bl snakeTrace
- nop
- nop
- .org 0x080D7850 ;Flashman zap throwdown
- flashmanThrowdownHook:
- bl flashmanThrowdownAction
- ;.org gutsmanChipHookAddress
- ;gutsmanAreaGrabChipHook:
- ;bl loadGutsmanRandomChip
- ;nop
- .org gutsmanZPunchHookAddress
- bl loadZPunchRandomChip ;Hook z-punch chip and use my routine instead
- ;nop
- ;=================PATCHES===============
- ;--------------HP SPEED PATCH---------------------
- ;Makes HP display change faster than default (which is 2)
- .org 0x08010E22
- mov r0, 8h
- ;------------FLAME MAN PATCHES----------
- .org 0x080C53EC
- mov r1, 5h ;Candle 1 at X=5 rather than X=6
- .org 0x080C5406
- mov r1, 5h ;Candle 2 at X=5 rather than X=6
- .org 0x080E2F98
- cmp r0, r3 ;YellowGuyY will now go left on same row rather than 3
- .org 0x080E2F40
- cmp r0, r3 ;YellowGuyX will now go down on same row rather than 3
- .org 0x080E2CB8
- .word flamemanCustomCandleActivationArray ;Rewrite the activation array pointer to my own so the level up function can activate (and avoid crash)
- .org 0x080C5440
- .word flamemanNewAIData ;Repoint AI data to my own so we have omega +2 levels
- .org 0x080C5916
- .byte 7h ;Allow flameman to attack from back row
- .org 0x080C5424
- //Patch out Flameman's Off-Limits 6,2 position.
- nop
- nop
- nop
- nop
- .org 0x080C566A
- //Patch out FlameMan's additional off-limits 6,2 check
- nop
- nop
- .org 0x080E30B8
- //Patch out flames despawning on holes
- nop
- nop
- .org 0x080C559A
- cmp r0, #0x6 //Flameman 6 moves in upper half HP instead of 8
- .org 0x080C55B8
- cmp r0, #0x3 //Flameman 3 moves in lower half of HP instead of 5
- ;--------------Flashman Patches---------
- ;--------------Plantman Patches---------
- //.org 0x080C1C4A
- // bl SpawnLance ;TEST INSTEAD OF NEEDLE
- .org 0x080C1C08
- .word plantmanLanceRowAttack|1b ;TEST MY SPAWNLANCE METHOD INSTEAD
- .org 0x080C1CC0 ;Plantman Vines In Ground Attack Choosing Array
- .word plantmanVinesInGroundRoutinesArray
- ;.org 0x080DE5E0
- ; mov r0, #0x1 //Make lance give mercy frames
- //.org 0x080C2D74 ;Plantman Vines In Ground Flower Attack Array
- // .word plantmanLowHPAttackRoutinesArray
- .org 0x080C1B9A ;Plantman Can't Spawn Anything cause flowers exist
- bne 0x080C1BCE ;Make it so he chooses a normal attack instead
- .org 0x080EE284 ;Old Wood Delay (0x1E by default)
- .byte 0x18
- .org 0x080C1D32 ;VineSprout (not flower sprout) post-delay
- mov r0, #0x40
- .org 0x080AE923 ;Plantman Omega Movement Delay
- .byte 0x2A
- .org 0x080AE92C ;Plantman Omega Movement Delay
- .byte 0x25
- .org 0x080E0425 ;Old Wood Impact Effect... don't know how this got stored like this in data.
- .byte FlinchAndInvisImpact
- ;--------------GUTSMAN PATCHES----------
- ;.org 0x080B7DF0 ;gutsmans sets move counter here to 0xFF so Z-Punch attack no longer comes up
- ;mov r0, #0x0 ;reset to 0 instead so he can use it again. this is the amount of moves he has done.
- ;.org 0x080b7de8 ;gutsmans checks if his move count is same as this in order to activate Z-Punch
- ;cmp r0, gutsmanMovesBeforeZPunch
- ;.org 0x080b7dcc ;gutsman checks this value and if his hp is less he can use zpunch. by default it is division by 2 by shifting to the right by 1.
- ;add r1, r1, 1 ;add 1 HP so its one over the max. Can use zpunch anytime now
- .org 0x080b8590 ;gutsmans areagrab response chip
- mov r0, grabbackfamily
- mov r1, 0x1 ;grabrevenge sublevel
- ldrb r2,[r5,#0x16]
- mov r3,#0x32 ;50 damage per hit
- ;-.org 0x080ae6a4 ;gutsman beta AI - delay after shockwave
- ;-.byte 0x64 ;contact damage
- .org 0x08019b68 ;flashman beta HP
- .byte 0xe8
- .byte 0x03 ;1000 HP 0x03e8
- .close
- ; eof
Advertisement
Add Comment
Please, Sign In to add comment