// File: /workspace/github_cpp_makefile_star2_O2/Thilotilo[P]DoaERando/Randomizer.cpp
// Function: DoaERando::Randomizer::MakeIronOreUseful()
void Randomizer::MakeIronOreUseful()
{
    // Blacksmith now returns a random top tier weapon (Qing Long, Qing Guang, Nu Long, Halberd)
    std::vector<BYTE> possibleGear = {0x4F, 0x50, 0x51, 0x52};
    BYTE gear = myRNG.GetRandomValueFromByteVector(possibleGear);

    printf("Giving the blacksmith weapon 0x%02X...\n", gear);

    std::vector<BYTE> newCode {
        0xA9, 0x1D,         // LDA #$1D
        0x85, 0xF2,         // STA $F2
        // This subroutine checks the party inventory for the item in $F2,
        // removes it if it finds it, and sets C to indicate if it was found.
        0x20, 0x39, 0x9E,   // JSR $3E39
        0x90, 0x1A,         // BCC ($B150)
        // If we found the item, set bit 3 of 6731 (indicates we have turned in
        // the ore), and set the bit indicating that the weapons were stolen in
        // vanilla
        0xAD, 0x31, 0x67,   // LDA $6731
        0x09, 0x08,         // ORA #$08
        0x8D, 0x31, 0x67,   // STA $6731
        // This subroutine gets B from bits 2-0 and X from bits 4-3.  It then sets
        // the bit B at $655X.
        // Here, 0x1A would be B = 2, X = 3, so it sets bit 5 of $6553
        0xA9, 0x1A,         // LDA #$1A
        0x20, 0xC6, 0x9C,   // JSR $9CC6
        // This is the dialog subroutine.  The dialogue is determined by the 2
        // bytes following the call, the first referring to the id, and the
        // second referring to the bank
        0x20, 0x0D, 0xD1,   // JSR $D10D
        0x14, 0x02,         // Text set below
        // This subroutine places the item in A into the inventory.  Since we
        // just lost the iron ore, we don't have to worry about space issues
        0xA9, gear,         // LDA #(gearId)
        0x20, 0x6F, 0xE9,   // JSR $E96F
        // Get us out of here
        0x4C, 0xA6, 0xC4,   // JMP $C4A6 (switches back to bank E, then returns)

        // This is the path if we don't have the ore in our inventory
        0xAD, 0x31, 0x67,   // LDA $6731
        0x29, 0x08,         // ORA #$08
        0xF0, 0x08,         // BEQ ($B15F)
        // We're here if we turned in the ore before
        0x20, 0x0D, 0xD1,   // JSR $D10D
        0x15, 0x02,         // Text set below
        0x4C, 0xA6, 0xC4,   // JMP $C4A6
        // We're here if we have never turned the ore in
        0x20, 0x0D, 0xD1,   // JSR $D10D
        0x13, 0x02,         // Text set below
        0x4C, 0xA6, 0xC4,   // JMP $C4A6

        // Zero out the remaining unused bytes (0x11 of them)
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00
    };

    for (int i = 0; i < newCode.size(); ++i)
    {
        myRom->WriteByte(0x3713D + i, newCode[i]);
    }

    // Now let's update some text strings:
    std::vector<BYTE> blacksmithText {
        // Bank 2 Text 0x13 - Text if you haven't turned in the ore and don't have the ore
        0x11,0x2D,0x38,0x3D,0x36,0x0A,0x3C,0x34,0x0A,0x2E,0x3E,0x3C,0x34,0x0A,0x18,0x2D,0x3E,0x3D,0xFB, // Bring me some Iron (19 bytes)
        0x1E,0x2D,0x34,0x0A,0x30,0x3D,0x33,0x0A,0x35,0x3E,0x2D,0x2F,0x64,0x3D,0x34,0xFB, // Ore and fortune (16 bytes)
        0x66,0x38,0x3B,0x3B,0x0A,0x2E,0x3C,0x38,0x3B,0x34,0x0A,0x64,0x3F,0x3E,0x3D,0xFB, // Will smile upon (16 bytes)
        0x2F,0x37,0x34,0x34,0xEC, // thee. (5 bytes)
        // Bank 2 Text 0x14 - Text if you have iron ore.
        0x23,0x37,0x30,0x3D,0x3A,0x0A,0x68,0x3E,0x64,0x0A,0x35,0x3E,0x2D,0x0A,0x2F,0x37,0x34,0xFB, // Thank you for the (18 bytes)
        0x3E,0x2D,0x34,0x63,0x0A,0x18,0x0A,0x37,0x30,0x65,0x34,0x0A,0x3C,0x30,0x33,0x34,0xFB, // ore. I have made (17 bytes)
        0xF1,gear,0xEC, // [WEAPON]. (3 bytes)
        // Bank 3 Text 0x15 - Text if you have turned in the ore and don't have ore in your inventory
        0x18,0x0A,0x30,0x3C,0x0A,0x2D,0x34,0x2F,0x38,0x2D,0x34,0x33,0x63,0xFB, // I am retired. (14 bytes)
        0x1F,0x3B,0x34,0x30,0x2E,0x34,0x0A,0x3B,0x34,0x30,0x65,0x34,0xEC, // Please leave. (13 bytes)
        // Bank 3 Text 0x16 - Now unused (1 byte)
        0xFF,
    };

    for (unsigned int i = 0; i < blacksmithText.size(); ++i)
    {
        myRom->WriteByte(0x2C613 + i, blacksmithText[i]);
    }

    // Free the currently unused bytes
    unsigned int numFreedBytes = 0x2C777 - 0x2C613 - blacksmithText.size();
    for (unsigned int i = 0; i < numFreedBytes; ++i)
    {
        myRom->WriteByte(0x2C613 + blacksmithText.size() + i, 0x00);
    }

    // Finally update the pointers to the new text
    myRom->WriteByte(0x2C024, 0x3B);
    myRom->WriteByte(0x2C025, 0x61);
    myRom->WriteByte(0x2C026, 0x7D);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0xd8, %rsp
movq %rdi, %rbx
leaq -0xe2(%rbp), %rsi
movl $0x5251504f, (%rsi)     # imm = 0x5251504F
leaq -0x68(%rbp), %r14
pushq $0x4
popq %rdx
leaq -0x50(%rbp), %rcx
movq %r14, %rdi
callq 0x409c64
leaq 0x8(%rbx), %rdi
movq %r14, %rsi
callq 0x40edc4
movl %eax, %r14d
movzbl %al, %esi
leaq 0x184465(%rip), %rdi    # 0x58b197
xorl %eax, %eax
callq 0x4e1140
movaps 0x184330(%rip), %xmm0   # 0x58b070
leaq -0xe2(%rbp), %rsi
movups %xmm0, (%rsi)
movabsq $0xd209cc6201aa967, %rax # imm = 0xD209CC6201AA967
movq %rax, 0x10(%rsi)
movl $0xa90214d1, 0x18(%rsi) # imm = 0xA90214D1
movb %r14b, 0x1c(%rsi)
movaps 0x184316(%rip), %xmm0   # 0x58b080
movups %xmm0, 0x1d(%rsi)
movabsq $-0x2ef2df3b59b3fdeb, %rax # imm = 0xD10D20C4A64C0215
movq %rax, 0x2d(%rsi)
movl $0xa64c0213, 0x35(%rsi) # imm = 0xA64C0213
movb $-0x3c, 0x39(%rsi)
xorps %xmm0, %xmm0
movups %xmm0, 0x3a(%rsi)
movb $0x0, 0x4a(%rsi)
leaq -0x50(%rbp), %rdi
pushq $0x4b
popq %rdx
leaq -0x38(%rbp), %rcx
callq 0x409c64
xorl %r15d, %r15d
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
jbe 0x406dce
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
leal 0x3713d(%r15), %esi
callq 0x404a00
incq %r15
jmp 0x406da5
movaps 0x1842bb(%rip), %xmm0   # 0x58b090
leaq -0xe2(%rbp), %rsi
movups %xmm0, (%rsi)
movaps 0x1842ba(%rip), %xmm0   # 0x58b0a0
movups %xmm0, 0x10(%rsi)
movaps 0x1842bf(%rip), %xmm0   # 0x58b0b0
movups %xmm0, 0x20(%rsi)
movaps 0x1842c4(%rip), %xmm0   # 0x58b0c0
movups %xmm0, 0x30(%rsi)
movaps 0x1842c9(%rip), %xmm0   # 0x58b0d0
movups %xmm0, 0x40(%rsi)
movabsq $0x303c0a346530370a, %rax # imm = 0x303C0A346530370A
movq %rax, 0x50(%rsi)
movl $0xf1fb3433, 0x58(%rsi) # imm = 0xF1FB3433
movb %r14b, 0x5c(%rsi)
movaps 0x1842b5(%rip), %xmm0   # 0x58b0e0
movups %xmm0, 0x5d(%rsi)
movabsq $0x343b0a342e30343b, %rax # imm = 0x343B0A342E30343B
movq %rax, 0x6d(%rsi)
movl $0xec346530, 0x75(%rsi) # imm = 0xEC346530
movb $-0x1, 0x79(%rsi)
leaq -0x38(%rbp), %rdi
pushq $0x7a
popq %rdx
leaq -0x19(%rbp), %rcx
callq 0x409c64
movl $0x2c613, %r14d         # imm = 0x2C613
leal -0x2c613(%r14), %eax
movq -0x38(%rbp), %rcx
movq -0x30(%rbp), %r15
subq %rcx, %r15
cmpq %rax, %r15
jbe 0x406e89
movq (%rbx), %rdi
movzbl (%rcx,%rax), %edx
movl %r14d, %esi
callq 0x404a00
incl %r14d
jmp 0x406e5e
movl $0x2c613, %r14d         # imm = 0x2C613
leal (%r15,%r14), %eax
movq (%rbx), %rdi
cmpl $0x2c777, %eax          # imm = 0x2C777
je 0x406eb2
movl -0x30(%rbp), %esi
subl -0x38(%rbp), %esi
addl %r14d, %esi
xorl %edx, %edx
callq 0x404a00
incl %r14d
jmp 0x406e8f
pushq $0x3b
popq %rdx
movl $0x2c024, %esi          # imm = 0x2C024
callq 0x404a00
movq (%rbx), %rdi
pushq $0x61
popq %rdx
movl $0x2c025, %esi          # imm = 0x2C025
callq 0x404a00
movq (%rbx), %rdi
pushq $0x7d
popq %rdx
movl $0x2c026, %esi          # imm = 0x2C026
callq 0x404a00
leaq -0x38(%rbp), %rdi
callq 0x404baa
leaq -0x50(%rbp), %rdi
callq 0x404baa
leaq -0x68(%rbp), %rdi
callq 0x404baa
addq $0xd8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
jmp 0x406f23
jmp 0x406f0c
movq %rax, %rbx
jmp 0x406f2f
jmp 0x406f15
jmp 0x406f15
movq %rax, %rbx
leaq -0x38(%rbp), %rdi
callq 0x404baa
jmp 0x406f26
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x404baa
leaq -0x68(%rbp), %rdi
callq 0x404baa
movq %rbx, %rdi
callq 0x4ba600