 81a239325d
			
		
	
	81a239325d
	
	
	
		
			
			Adds Link's Awakening: DX. Fully imports and forks LADXR, with permission - https://github.com/daid/LADXR
		
			
				
	
	
		
			309 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from ..assembler import ASM
 | |
| from ..roomEditor import RoomEditor, ObjectHorizontal, ObjectVertical, Object
 | |
| from .. import entityData
 | |
| 
 | |
| 
 | |
| def addMultiworldShop(rom, this_player, player_count):
 | |
|     # Make a copy of the shop into GrandpaUlrira house
 | |
|     re = RoomEditor(rom, 0x2A9)
 | |
|     re.objects = [
 | |
|         ObjectHorizontal(1,1, 0x00, 8),
 | |
|         ObjectHorizontal(1,2, 0x00, 8),
 | |
|         ObjectHorizontal(1,3, 0xCD, 8),
 | |
|         Object(2, 0, 0xC7),
 | |
|         Object(7, 0, 0xC7),
 | |
|         Object(7, 7, 0xFD),
 | |
|     ] + re.getWarps()
 | |
|     re.entities = [(0, 6, 0xD4)]
 | |
|     for n in range(player_count):
 | |
|         if n != this_player:
 | |
|             re.entities.append((n + 1, 6, 0xD4))
 | |
|     re.animation_id = 0x04
 | |
|     re.floor_object = 0x0D
 | |
|     re.store(rom)
 | |
|     # Fix the tileset
 | |
|     rom.banks[0x20][0x2EB3 + 0x2A9 - 0x100] = rom.banks[0x20][0x2EB3 + 0x2A1 - 0x100]
 | |
| 
 | |
|     re = RoomEditor(rom, 0x0B1)
 | |
|     re.getWarps()[0].target_x = 128
 | |
|     re.store(rom)
 | |
| 
 | |
|     # Load the shopkeeper sprites
 | |
|     entityData.SPRITE_DATA[0xD4] = entityData.SPRITE_DATA[0x4D]
 | |
|     rom.patch(0x03, 0x01CF, "00", "98") # Fix the hitbox of the ghost to be 16x16
 | |
| 
 | |
|     # Patch Ghost to work as a multiworld shop
 | |
|     rom.patch(0x19, 0x1E18, 0x20B0, ASM("""
 | |
|     ld   a, $01
 | |
|     ld   [$C50A], a ; this stops link from using items
 | |
| 
 | |
|     ldh  a, [$EE] ; X
 | |
|     cp   $08
 | |
|     ; Jump to other code which is placed on the old owl code. As we do not have enough space here.
 | |
|     jp   z, shopItemsHandler
 | |
| 
 | |
| ;Draw shopkeeper
 | |
|     ld   de, OwnerSpriteData
 | |
|     call $3BC0 ; render sprite pair
 | |
|     ldh  a, [$E7] ; frame counter
 | |
|     swap a
 | |
|     and  $01
 | |
|     call $3B0C ; set sprite variant
 | |
| 
 | |
|     ldh  a, [$F0]
 | |
|     and  a
 | |
|     jr   nz, checkTalkingResult
 | |
| 
 | |
|     call $7CA2 ; prevent link from moving into the sprite
 | |
|     call $7CF0 ; check if talking to NPC
 | |
|     call c, talkHandler ; talk handling
 | |
|     ret
 | |
| 
 | |
| checkTalkingResult:
 | |
|     ld   a, [$C19F]
 | |
|     and  a
 | |
|     ret  nz ; still taking
 | |
|     call $3B12 ; increase entity state
 | |
|     ld   [hl], $00
 | |
|     ld   a, [$C177] ; dialog selection
 | |
|     and  a
 | |
|     ret  nz
 | |
|     jp TalkResultHandler
 | |
| 
 | |
| OwnerSpriteData:
 | |
|     ;db   $60, $03, $62, $03, $62, $23, $60, $23 ; down
 | |
|     db   $64, $03, $66, $03, $66, $23, $64, $23 ; up
 | |
|     ;db   $68, $03, $6A, $03, $6C, $03, $6E, $03 ; left
 | |
|     ;db   $6A, $23, $68, $23, $6E, $23, $6C, $23 ; right
 | |
| 
 | |
| shopItemsHandler:
 | |
| ; Render the shop items
 | |
|     ld   h, $00
 | |
| loop:
 | |
|     ; First load links position to render the item at
 | |
|     ldh  a, [$98] ; LinkX
 | |
|     ldh  [$EE], a ; X
 | |
|     ldh  a, [$99] ; LinkY
 | |
|     sub  $0E
 | |
|     ldh  [$EC], a ; Y
 | |
|     ; Check if this is the item we have picked up
 | |
|     ld   a, [$C509] ; picked up item in shop
 | |
|     dec  a
 | |
|     cp   h
 | |
|     jr   z, .renderCarry
 | |
| 
 | |
|     ld   a, h
 | |
|     swap a
 | |
|     add  a, $20
 | |
|     ldh  [$EE], a ; X
 | |
|     ld   a, $30
 | |
|     ldh  [$EC], a ; Y
 | |
| .renderCarry:
 | |
|     ld   a, h
 | |
|     push hl
 | |
|     ldh  [$F1], a ; variant
 | |
|     cp   $03
 | |
|     jr   nc, .singleSprite
 | |
|     ld   de, ItemsDualSpriteData
 | |
|     call $3BC0 ; render sprite pair
 | |
|     jr   .renderDone
 | |
| .singleSprite:
 | |
|     ld   de, ItemsSingleSpriteData
 | |
|     call $3C77 ; render sprite
 | |
| .renderDone:
 | |
| 
 | |
|     pop  hl
 | |
| .skipItem:
 | |
|     inc  h
 | |
|     ld   a, $07
 | |
|     cp   h
 | |
|     jr   nz, loop
 | |
| 
 | |
| ;   check if we want to pickup or drop an item
 | |
|     ldh  a, [$CC]
 | |
|     and  $30 ; A or B button
 | |
|     call nz, checkForPickup
 | |
| 
 | |
| ;   check if we have an item
 | |
|     ld   a, [$C509] ; carry item
 | |
|     and  a
 | |
|     ret  z
 | |
| 
 | |
|     ; Set that link has picked something up
 | |
|     ld   a, $01
 | |
|     ld   [$C15C], a
 | |
|     call $0CAF ; reset spin attack...
 | |
| 
 | |
|     ; Check if we are trying to exit the shop and so drop our item.
 | |
|     ldh  a, [$99]
 | |
|     cp   $78
 | |
|     ret  c
 | |
|     xor  a
 | |
|     ld   [$C509], a
 | |
| 
 | |
|     ret
 | |
| 
 | |
| checkForPickup:
 | |
|     ldh  a, [$9E] ; direction
 | |
|     cp   $02
 | |
|     ret  nz
 | |
|     ldh  a, [$99] ; LinkY
 | |
|     cp   $48
 | |
|     ret  nc
 | |
| 
 | |
|     ld   a, $13
 | |
|     ldh  [$F2], a ; play SFX
 | |
| 
 | |
|     ld   a, [$C509] ; picked up shop item
 | |
|     and  a
 | |
|     jr   nz, .drop
 | |
| 
 | |
|     ldh  a, [$98] ; LinkX
 | |
|     sub  $08
 | |
|     swap a
 | |
|     and  $07
 | |
|     ld   [$C509], a ; picked up shop item
 | |
|     ret
 | |
| .drop:
 | |
|     xor  a
 | |
|     ld   [$C509], a
 | |
|     ret
 | |
| 
 | |
| ItemsDualSpriteData:
 | |
|     db   $60, $08, $60, $28 ; zol
 | |
|     db   $68, $09 ; chicken (left)
 | |
| ItemsSingleSpriteData: ; (first 3 entries are still dual sprites)
 | |
|     db   $6A, $09 ; chicken (right)
 | |
|     db   $14, $02, $14, $22 ; piece of power
 | |
| ;Real single sprite data starts here
 | |
|     db   $00, $0F ; bomb
 | |
|     db   $38, $0A ; rupees
 | |
|     db   $20, $0C ; medicine
 | |
|     db   $28, $0C ; heart
 | |
| 
 | |
| ;------------------------------------trying to buy something starts here
 | |
| talkHandler:
 | |
|     ld   a, [$C509] ; carry item
 | |
|     add  a, a
 | |
|     ret  z ; check if we have something to buy
 | |
|     sub  $02
 | |
| 
 | |
|     ld   hl, itemNames
 | |
|     ld   e, a
 | |
|     ld   d, b ; b=0
 | |
|     add  hl, de
 | |
|     ld   e, [hl]
 | |
|     inc  hl
 | |
|     ld   d, [hl]
 | |
| 
 | |
|     ld   hl, wCustomMessage
 | |
|     call appendString
 | |
|     dec  hl
 | |
|     call padString
 | |
|     ld   de, postMessage
 | |
|     call appendString
 | |
|     dec  hl
 | |
|     ld   a, $fe
 | |
|     ld   [hl], a
 | |
|     ld   de, $FFEF
 | |
|     add  hl, de
 | |
|     ldh  a, [$EE]
 | |
|     swap a
 | |
|     and  $0F
 | |
|     add  a, $30
 | |
|     ld   [hl], a
 | |
|     ld   a, $C9
 | |
|     call $2385 ; open dialog
 | |
|     call $3B12 ; increase entity state
 | |
|     ret
 | |
| 
 | |
| appendString:
 | |
|     ld   a, [de]
 | |
|     inc  de
 | |
|     and  a
 | |
|     ret  z
 | |
|     ldi  [hl], a
 | |
|     jr   appendString
 | |
| 
 | |
| padString:
 | |
|     ld   a, l
 | |
|     and  $0F
 | |
|     ret  z
 | |
|     ld   a, $20
 | |
|     ldi  [hl], a
 | |
|     jr   padString
 | |
| 
 | |
| itemNames:
 | |
|     dw itemZol
 | |
|     dw itemChicken
 | |
|     dw itemPieceOfPower
 | |
|     dw itemBombs
 | |
|     dw itemRupees
 | |
|     dw itemMedicine
 | |
|     dw itemHealth
 | |
| 
 | |
| postMessage:
 | |
|     db  "For player X?       Yes  No  ", $00
 | |
| 
 | |
| itemZol:
 | |
|     db  m"Slime storm|100 {RUPEES}", $00
 | |
| itemChicken:
 | |
|     db  m"Coccu party|50 {RUPEES}", $00
 | |
| itemPieceOfPower:
 | |
|     db  m"Piece of Power|50 {RUPEES}", $00
 | |
| itemBombs:
 | |
|     db  m"10 Bombs|50 {RUPEES}", $00
 | |
| itemRupees:
 | |
|     db  m"100 {RUPEES}|200 {RUPEES}", $00
 | |
| itemMedicine:
 | |
|     db  m"Medicine|100 {RUPEES}", $00
 | |
| itemHealth:
 | |
|     db  m"Health refill|10 {RUPEES}", $00
 | |
| 
 | |
| TalkResultHandler:
 | |
|     ld  hl, ItemPriceTableBCD
 | |
|     ld  a, [$C509]
 | |
|     dec a
 | |
|     add a, a
 | |
|     ld  c, a ; b=0
 | |
|     add hl, bc
 | |
|     ldi a, [hl]
 | |
|     ld  d, [hl]
 | |
|     ld  e, a
 | |
|     ld  a, [$DB5D]
 | |
|     cp  d
 | |
|     ret c
 | |
|     jr  nz, .highEnough
 | |
|     ld  a, [$DB5E]
 | |
|     cp  e
 | |
|     ret c
 | |
| .highEnough:
 | |
|     ; Got enough money, take it.
 | |
|     ld  hl, ItemPriceTableDEC
 | |
|     ld  a, [$C509]
 | |
|     dec a
 | |
|     ld  c, a ; b=0
 | |
|     add hl, bc
 | |
|     ld  a, [hl]
 | |
|     ld  [$DB92], a ; set substract buffer
 | |
|     
 | |
|     ; Set the item to send
 | |
|     ld  hl, $DDFE
 | |
|     ld  a, [$C509] ; currently picked up item 
 | |
|     ldi [hl], a
 | |
|     ldh a, [$EE]   ; X position of NPC
 | |
|     ldi [hl], a
 | |
|     ld  hl, $DDF7
 | |
|     set 2, [hl]
 | |
| 
 | |
|     ; No longer picked up item
 | |
|     xor a
 | |
|     ld  [$C509], a
 | |
|     ret
 | |
| 
 | |
| ItemPriceTableBCD:
 | |
|     dw $0100, $0050, $0050, $0050, $0200, $0100, $0010
 | |
| ItemPriceTableDEC:
 | |
|     db $64, $32, $32, $32, $C8, $64, $0A
 | |
|     """, 0x5E18), fill_nop=True)
 |