summaryrefslogtreecommitdiff
path: root/src/enemy/miniSlime.c
blob: 38a42e9691835955823d8fcaf743508c7407b50d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
 * @file miniSlime.c
 * @ingroup Enemies
 *
 * @brief Mini Slime enemy
 */
#include "enemy.h"
#include "sound.h"
#include "effects.h"
#include "physics.h"
#include "asm.h"

typedef struct {
    /*0x00*/ Entity base;
    /*0x68*/ u8 unused1[4];
    /*0x6c*/ u8 unk_6c;
    /*0x6d*/ u8 unk_6d;
} MiniSlimeEntity;

void sub_08045374(MiniSlimeEntity* this);
void MiniSlime_OnTick(MiniSlimeEntity* this);
void MiniSlime_OnCollision(MiniSlimeEntity* this);
void MiniSlime_OnDeath(MiniSlimeEntity* this);
void MiniSlime_OnGrabbed(MiniSlimeEntity* this);
void sub_080452A4(MiniSlimeEntity* this);
void sub_080452E4(MiniSlimeEntity* this);
void sub_080452FC(MiniSlimeEntity* this);

extern void ReplaceMonitoredEntity(Entity*, Entity*);

static void (*const MiniSlime_Functions[])(MiniSlimeEntity*) = {
    MiniSlime_OnTick,
    MiniSlime_OnCollision,
    (void (*)(MiniSlimeEntity*))GenericKnockback,
    MiniSlime_OnDeath,
    (void (*)(MiniSlimeEntity*))GenericConfused,
    MiniSlime_OnGrabbed,
};

void MiniSlime(MiniSlimeEntity* this) {
    EnemyFunctionHandler(super, (EntityActionArray)MiniSlime_Functions);
    EnemySetFXOffset(super, 0, 1, -8);
}

void MiniSlime_OnTick(MiniSlimeEntity* this) {
    static void (*const actionFuncs[])(MiniSlimeEntity*) = {
        sub_080452A4,
        sub_080452E4,
        sub_080452FC,
        sub_08045374,
    };
    actionFuncs[super->action](this);
}

void MiniSlime_OnCollision(MiniSlimeEntity* this) {
    if (super->confusedTime)
        EnemyCreateFX(super, FX_STARS);

    EnemyFunctionHandlerAfterCollision(super, MiniSlime_Functions);
}

void MiniSlime_OnDeath(MiniSlimeEntity* this) {
    Entity* parent = super->parent;
    if ((super != parent) && (parent != NULL)) {
        this->unk_6c &= ~0x80;
        super->parent->child = super->child;
        super->child->parent = super->parent;
        if (this->unk_6d & 0x40)
            ReplaceMonitoredEntity(super, parent);
    }
    GenericDeath(super);
}

void MiniSlime_OnGrabbed(MiniSlimeEntity* this) {
}

void sub_080452A4(MiniSlimeEntity* this) {
    super->action = 1;
    super->spriteSettings.draw = 1;
    super->speed = 0x100;
    sub_0804A720(super);
    InitializeAnimation(super, 6);
    if (super->type2) {
        super->action = 2;
        super->timer = 1;
    } else {
        sub_080452E4(this);
    }
}

void sub_080452E4(MiniSlimeEntity* this) {
    super->action = 2;
    super->timer = (Random() & 0x1f) + 1;
}

void sub_080452FC(MiniSlimeEntity* this) {
    u32 cVar2, bVar3;
    GetNextFrame(super);
    if (--super->timer == 0) {
        super->action = 3;
        super->timer = 1;
        if (0 < super->speed)
            super->timer = FixedDiv(0x1000, super->speed) >> 8;

        if (sub_08049FA0(super) == 0 && (Random() & 3)) {
            cVar2 = sub_08049EE4(super);
            bVar3 = Random() & 8;
            bVar3 += 0xfc;
            super->direction = DirectionRound(cVar2 + bVar3);
        } else {
            super->direction = DirectionRound(Random());
            sub_08045374(this);
        }
    }
}

void sub_08045374(MiniSlimeEntity* this) {
    ProcessMovement0(super);
    GetNextFrame(super);
    if (--super->timer == 0)
        super->action = 1;
}