mirror of
				https://github.com/MarioSpore/Grinch-AP.git
				synced 2025-10-21 20:21:32 -06:00 
			
		
		
		
	
		
			
	
	
		
			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)
 |