// File: /workspace/github_c_makefile_star2_O3/Ziddykins[P]Dawn/src/spells.c
// Function: cast_fireball
void cast_fireball(const char *username, const char *target) {
    int pindex = get_pindex(username);
    int tindex = get_pindex(target);
    char out[MAX_MESSAGE_BUFFER];

    if (tindex == -1) {
        snprintf(out, MAX_MESSAGE_BUFFER, "PRIVMSG %s :Invalid target\r\n", dawn->active_room);
        add_msg(out, strlen(out));
        return;
    }

    if (!dawn->players[pindex].spellbook.fireball.learned) {
        snprintf(out, MAX_MESSAGE_BUFFER, "PRIVMSG %s :%s, you do not know this spell\r\n",
                 dawn->active_room, username);
        add_msg(out, strlen(out));
        return;
    }

    if (dawn->players[tindex].health <= 0) {
        snprintf(out, MAX_MESSAGE_BUFFER, "PRIVMSG %s :%s, %s is dead\r\n",
                 dawn->active_room, username, target);
        add_msg(out, strlen(out));
        return;
    }

    if (dawn->players[pindex].level >= dawn->players[tindex].level * 3) {
        snprintf(out, MAX_MESSAGE_BUFFER, "PRIVMSG %s :%s, pick on someone your own size!\r\n",
                 dawn->active_room, username);
        add_msg(out, strlen(out));
        return;
    }

    if (strcmp(username, target) == 0) {
        snprintf(out, MAX_MESSAGE_BUFFER, "PRIVMSG %s :%s whips a fireball at a mirror; it bounces back"
                ", hitting themselves for 1 point of damage. Well done.\r\n", dawn->active_room, username);
        dawn->players[pindex].health--;
        add_msg(out, strlen(out));
        return;
    }

    int fireball_cost = 1 + dawn->players[pindex].spellbook.fireball.level * 7;
    int fireball_damage =
            1 + rand() % dawn->players[pindex].intelligence * dawn->players[pindex].spellbook.fireball.level;

    if (dawn->players[pindex].mana >= fireball_cost) {
        int target_save = 1 + rand() % dawn->players[tindex].m_def;
        char result[128];
        dawn->players[pindex].mana -= fireball_cost;
        snprintf(out, MAX_MESSAGE_BUFFER, "PRIVMSG %s :%s hurls a fireball at %s! ",
                 dawn->active_room, username, target);
        if (target_save == fireball_damage) {
            snprintf(result, 128, "%s's shields had just enough energy to absorb the entire fireball!\r\n", target);
        } else if (target_save < fireball_damage) {
            struct Message tmpmsg;
            strcpy(tmpmsg.sender_nick, target);
            strcpy(tmpmsg.receiver, dawn->active_room);
            snprintf(result, 128, "%s is hit for %d damage!\r\n", target, fireball_damage - target_save);
            dawn->players[tindex].health -= fireball_damage - target_save;
            check_alive(&tmpmsg);
        } else if (target_save > fireball_damage) {
            snprintf(result, 128, "%s swats the fireball out of the sky with ease\r\n", target);
        }
        strncat(out, result, MAX_MESSAGE_BUFFER - strlen(result));
    }
    add_msg(out, strlen(out));
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb28, %rsp            # imm = 0xB28
movq %rsi, %rbx
movq %rdi, %r14
callq 0xda6c
movl %eax, %ebp
movq %rbx, %rdi
callq 0xda6c
leaq 0x12e98(%rip), %rcx     # 0x21a80
movq (%rcx), %r15
cmpl $-0x1, %eax
je 0xed20
movslq %ebp, %rcx
imulq $0x26a8, %rcx, %rbp     # imm = 0x26A8
cmpl $0x0, 0x1320(%r15,%rbp)
je 0xed47
leaq 0x1a0(%r15), %rcx
cltq
imulq $0x26a8, %rax, %r13     # imm = 0x26A8
cmpq $0x0, 0x2650(%rcx,%r13)
jle 0xed57
leaq (%r15,%rbp), %r12
addq $0x1a0, %r12            # imm = 0x1A0
addq %r13, %rcx
movl 0x2668(%rcx), %eax
leal (%rax,%rax,2), %eax
cmpl %eax, 0x2668(%r12)
jge 0xed84
movq %r14, %rdi
movq %rbx, %rsi
callq 0x22d0
testl %eax, %eax
je 0xedd9
movl 0x1178(%r12), %eax
leal (,%rax,8), %r15d
subl %eax, %r15d
callq 0x2080
leaq 0x12dfd(%rip), %r12     # 0x21a80
movq (%r12), %rcx
cltd
idivl 0x2828(%rcx,%rbp)
cmpl %r15d, 0x2820(%rcx,%rbp)
jle 0xedac
imull 0x1318(%rcx,%rbp), %edx
movl %edx, 0xc(%rsp)
notl %r15d
callq 0x2080
movq (%r12), %rcx
cltd
idivl 0x2830(%rcx,%r13)
movl %edx, 0x8(%rsp)
addl %r15d, 0x2820(%rcx,%rbp)
addq $0x100, %rcx            # imm = 0x100
leaq 0x93bc(%rip), %rdx      # 0x18094
leaq 0x90(%rsp), %rdi
movl $0x190, %esi            # imm = 0x190
movq %r14, %r8
movq %rbx, %r9
xorl %eax, %eax
callq 0x2390
movl 0xc(%rsp), %ebp
subl 0x8(%rsp), %ebp
jne 0xee15
leaq 0x93b5(%rip), %rdx      # 0x180bc
leaq 0x10(%rsp), %rdi
movl $0x80, %esi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x2390
jmp 0xee8a
addq $0x100, %r15            # imm = 0x100
leaq 0x908a(%rip), %rdx      # 0x17db8
leaq 0x90(%rsp), %rdi
movl $0x190, %esi            # imm = 0x190
movq %r15, %rcx
xorl %eax, %eax
callq 0x2390
jmp 0xedac
addq $0x100, %r15            # imm = 0x100
leaq 0x908e(%rip), %rdx      # 0x17de3
jmp 0xed92
addq $0x100, %r15            # imm = 0x100
leaq 0x926c(%rip), %rdx      # 0x17fd1
leaq 0x90(%rsp), %rdi
movl $0x190, %esi            # imm = 0x190
movq %r15, %rcx
movq %r14, %r8
movq %rbx, %r9
xorl %eax, %eax
callq 0x2390
jmp 0xedac
addq $0x100, %r15            # imm = 0x100
leaq 0x925c(%rip), %rdx      # 0x17fee
leaq 0x90(%rsp), %rdi
movl $0x190, %esi            # imm = 0x190
movq %r15, %rcx
movq %r14, %r8
xorl %eax, %eax
callq 0x2390
leaq 0x90(%rsp), %rbx
movq %rbx, %rdi
callq 0x20c0
movq %rbx, %rdi
movq %rax, %rsi
callq 0xcefe
addq $0xb28, %rsp            # imm = 0xB28
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
addq $0x100, %r15            # imm = 0x100
leaq 0x9238(%rip), %rdx      # 0x1801f
leaq 0x90(%rsp), %rdi
movl $0x190, %esi            # imm = 0x190
movq %r15, %rcx
movq %r14, %r8
xorl %eax, %eax
callq 0x2390
leaq 0x12c78(%rip), %rax     # 0x21a80
movq (%rax), %rax
decq 0x27f0(%rax,%rbp)
jmp 0xedac
jle 0xee7c
leaq 0x228(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x21c0
leaq 0x2e8(%rsp), %rdi
movl $0x100, %esi            # imm = 0x100
leaq 0x12c42(%rip), %r15     # 0x21a80
addq (%r15), %rsi
callq 0x21c0
leaq 0x92b4(%rip), %rdx      # 0x18101
leaq 0x10(%rsp), %rdi
movl $0x80, %esi
movq %rbx, %rcx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x2390
movslq %ebp, %rax
movq (%r15), %rcx
subq %rax, 0x27f0(%rcx,%r13)
movq %r14, %rdi
callq 0x45bc
jmp 0xee8a
jge 0xee8a
leaq 0x9297(%rip), %rdx      # 0x1811c
jmp 0xed07
leaq 0x10(%rsp), %rbx
movq %rbx, %rdi
callq 0x20c0
movl $0x190, %edx            # imm = 0x190
subq %rax, %rdx
leaq 0x90(%rsp), %rdi
movq %rbx, %rsi
callq 0x2120
jmp 0xedac