summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Noga <Tempus@chronometry.ca>2012-12-13 17:02:55 -0600
committerColin Noga <Tempus@chronometry.ca>2012-12-13 17:02:55 -0600
commitac0ced5b71d2cf2bce444fce88e7b359ac08815c (patch)
tree6305e51ef39ba2a34b93f39e1a650ae346f6cebb
parente1425a9dcaf00f3f0932a0a8830d8593bf91ab60 (diff)
downloadkamek-ac0ced5b71d2cf2bce444fce88e7b359ac08815c.tar.gz
kamek-ac0ced5b71d2cf2bce444fce88e7b359ac08815c.zip
Added thundercloud sprite, made area death clouds
Diffstat (limited to '')
-rw-r--r--NewerProjectKP.yaml1
-rw-r--r--kamek_pal.x4
-rw-r--r--spritetex.yaml29
-rw-r--r--src/bossRamboo.cpp12
-rwxr-xr-xsrc/spritetex.S84
-rwxr-xr-xsrc/thundercloud.cpp407
-rw-r--r--thundercloud.yaml23
-rw-r--r--tools/UsedProfileAndSpriteList.txt4
8 files changed, 560 insertions, 4 deletions
diff --git a/NewerProjectKP.yaml b/NewerProjectKP.yaml
index 275df02..a8369d8 100644
--- a/NewerProjectKP.yaml
+++ b/NewerProjectKP.yaml
@@ -59,6 +59,7 @@ modules:
- processed/shyguyGiants.yaml
- processed/meteor.yaml
- processed/electricLine.yaml
+ - processed/thundercloud.yaml
- processed/makeYourOwn.yaml
- processed/challengeStar.yaml
- processed/singAlong.yaml
diff --git a/kamek_pal.x b/kamek_pal.x
index eb18718..4e4b426 100644
--- a/kamek_pal.x
+++ b/kamek_pal.x
@@ -85,11 +85,15 @@ SECTIONS {
BigHanaFireball = 0x809B3A50;
BigHanaIceball = 0x809B3A20;
+ dAcPy_vf3F4 = 0x80146230;
dAcPy_vf3F8 = 0x80146310;
dAcPy_vf3FC = 0x80146A10;
/* Back to other shit I didn't want to scroll for */
+ Cloud_death_execute = 0x809DDB80;
+ Cloud_execute = 0x809DFD40;
+
GlobalTickCount = 0x8042A648;
GetSpecificPlayerActor = 0x8005F900;
diff --git a/spritetex.yaml b/spritetex.yaml
index 7264fb4..79bcf46 100644
--- a/spritetex.yaml
+++ b/spritetex.yaml
@@ -735,3 +735,32 @@ hooks:
target_func: 'GLOW_LightBlock'
+
+ - name: TEX_CloudLT_A
+ type: branch_insn
+ branch_type: bl
+ src_addr_pal: 0x809DFBF0
+ target_func: 'TEX_CloudLT_A'
+
+ - name: TEX_CloudLT_B
+ type: branch_insn
+ branch_type: bl
+ src_addr_pal: 0x809DFC00
+ target_func: 'TEX_CloudLT_B'
+
+ - name: TEX_CloudLT_C
+ type: branch_insn
+ branch_type: bl
+ src_addr_pal: 0x809DFC10
+ target_func: 'TEX_CloudLT_C'
+
+ # - name: CloudLT_Execute
+ # type: branch_insn
+ # branch_type: bl
+ # src_addr_pal: 0x809E07F0
+ # target_func: 'CloudLT_Execute'
+
+ - name: CloudLT_Execute
+ type: add_func_pointer
+ src_addr_pal: 0x80AE1868
+ target_func: 'CloudLT_Execute'
diff --git a/src/bossRamboo.cpp b/src/bossRamboo.cpp
index 2dcd885..ea97629 100644
--- a/src/bossRamboo.cpp
+++ b/src/bossRamboo.cpp
@@ -159,7 +159,7 @@ int daRamboo_c::onCreate() {
ActivePhysics::Info HitMeBaby;
HitMeBaby.xDistToCenter = 160.0;
- HitMeBaby.yDistToCenter = -80.0;
+ HitMeBaby.yDistToCenter = 80.0;
HitMeBaby.xDistToEdge = 148.0;
HitMeBaby.yDistToEdge = 148.0;
@@ -173,8 +173,16 @@ int daRamboo_c::onCreate() {
this->aPhysics.initWithStruct(this, &HitMeBaby);
- this->aPhysics.addToList();
+ this->aPhysics.collisionCheckType = 2;
+ this->aPhysics._8 = 48.0;
+ this->aPhysics._C = 48.0;
+ this->aPhysics._18 = 48.0;
+ this->aPhysics.trpValue0 = 48.0;
+ this->aPhysics.trpValue1 = 48.0;
+ this->aPhysics.trpValue2 = 48.0;
+ this->aPhysics.trpValue3 = 48.0;
+ this->aPhysics.addToList();
this->Baseline = this->pos.y;
this->rot.x = 0; // X is vertical axis
diff --git a/src/spritetex.S b/src/spritetex.S
index 50d2419..b24c77a 100755
--- a/src/spritetex.S
+++ b/src/spritetex.S
@@ -2,6 +2,9 @@
.extern GenerateRandomNumber
.extern BombExplodeState
.extern AbsValue
+.extern Cloud_death_execute
+.extern Cloud_execute
+
#ifndef __MWERKS__
.set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4
@@ -1344,6 +1347,78 @@ GLOW_LightBlock:
bctr
+.global CloudLT_Execute
+CloudLT_Execute:
+ lwz r8, 4(r31)
+
+ slwi r8, r8, 28
+ cmpwi r8, 1
+ beq CloudD_Execute
+
+ b Cloud_execute
+ blr
+
+CloudD_Execute:
+ b Cloud_death_execute
+ blr
+
+
+.global TEX_CloudLT_A
+TEX_CloudLT_A:
+ lwz r8, 4(r31)
+
+ slwi r8, r8, 28
+ cmpwi r8, 1
+
+ beq TEX_CloudLT_Aa
+
+ addi r4, r28, 0x2C
+ blr
+
+TEX_CloudLT_Aa:
+ lis r4, CloudA@h
+ ori r4, r4, CloudA@l
+ blr
+
+
+.global TEX_CloudLT_B
+TEX_CloudLT_B:
+ lwz r8, 4(r31)
+
+ slwi r8, r8, 28
+ cmpwi r8, 1
+
+ beq TEX_CloudLT_Ba
+
+ addi r4, r28, 0x38
+ blr
+
+TEX_CloudLT_Ba:
+ lis r4, CloudB@h
+ ori r4, r4, CloudB@l
+ blr
+
+
+.global TEX_CloudLT_C
+TEX_CloudLT_C:
+ lwz r8, 4(r31)
+
+ slwi r8, r8, 28
+ cmpwi r8, 1
+
+ beq TEX_CloudLT_Ca
+
+ addi r4, r28, 0x44
+ blr
+
+TEX_CloudLT_Ca:
+ lis r4, CloudC@h
+ ori r4, r4, CloudC@l
+ blr
+
+
+
+
.data
BomombDir:
.word 0x0400FC00
@@ -1465,4 +1540,13 @@ YoshiStrings:
.align 4
+CloudA:
+ .string "wny_mist.9"
+.align 4
+CloudB:
+ .string "wny_mist.10"
+.align 4
+CloudC:
+ .string "wny_mist.11"
+.align 4
diff --git a/src/thundercloud.cpp b/src/thundercloud.cpp
new file mode 100755
index 0000000..a84340f
--- /dev/null
+++ b/src/thundercloud.cpp
@@ -0,0 +1,407 @@
+#include <common.h>
+#include <game.h>
+#include <g3dhax.h>
+
+#include "boss.h"
+
+const char* TLCarcNameList [] = {
+ "tcloud",
+ NULL
+};
+
+class dThunderCloud : public dEn_c {
+ int onCreate();
+ int onDelete();
+ int onExecute();
+ int onDraw();
+
+ mHeapAllocator_c allocator;
+ m3d::mdl_c bodyModel;
+ nw4r::g3d::ResFile resFile;
+ m3d::anmChr_c anm;
+
+ mEf::es2 bolt;
+ mEf::es2 charge;
+
+ float Baseline;
+ u32 timer;
+ int dying;
+ char killFlag;
+
+ u64 eventFlag;
+
+ ActivePhysics Lightning;
+
+ void dieFall_Begin();
+ void dieFall_Execute();
+ static dThunderCloud *build();
+
+ void updateModelMatrices();
+
+ void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther);
+ void yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat7_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat7_GroundPoundYoshi(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat5_Mario(ActivePhysics *apThis, ActivePhysics *apOther);
+ void collisionCat11_PipeCannon(ActivePhysics *apThis, ActivePhysics *apOther);
+
+ void bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate);
+
+ void _vf148();
+ void _vf14C();
+ bool CreateIceActors();
+
+ USING_STATES(dThunderCloud);
+ DECLARE_STATE(Follow);
+ DECLARE_STATE(Lightning);
+};
+
+dThunderCloud *dThunderCloud::build() {
+ void *buffer = AllocFromGameHeap1(sizeof(dThunderCloud));
+ return new(buffer) dThunderCloud;
+}
+
+
+CREATE_STATE(dThunderCloud, Follow);
+CREATE_STATE(dThunderCloud, Lightning);
+
+
+// Collision Callbacks
+ extern "C" void dAcPy_vf3F4(void* mario, void* other, int t);
+ extern "C" void BigHanaFireball(dEn_c* t, ActivePhysics *apThis, ActivePhysics *apOther);
+ extern "C" void *dAcPy_c__ChangePowerupWithAnimation(void * Player, int powerup);
+ extern "C" int CheckExistingPowerup(void * Player);
+
+ void dThunderCloud::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) {
+ if (apThis->info.category2 == 0x9) {
+ int p = CheckExistingPowerup(apOther->owner);
+ if (p != 0 && p != 3) { // Powerups - 0 = small; 1 = big; 2 = fire; 3 = mini; 4 = prop; 5 = peng; 6 = ice; 7 = hammer
+ dAcPy_c__ChangePowerupWithAnimation(apOther->owner, 3);
+ }
+ else { dAcPy_vf3F4(apOther->owner, this, 9); }
+ }
+
+ else { dAcPy_vf3F4(apOther->owner, this, 9); }
+ }
+
+ void dThunderCloud::yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); }
+ void dThunderCloud::collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); }
+ void dThunderCloud::collisionCat7_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); }
+ void dThunderCloud::collisionCat7_GroundPoundYoshi(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); }
+ void dThunderCloud::collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); }
+ void dThunderCloud::collisionCat5_Mario(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); }
+ void dThunderCloud::collisionCat11_PipeCannon(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); }
+
+ void dThunderCloud::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { BigHanaFireball(this, apThis, apOther); }
+ void dThunderCloud::collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther) { BigHanaFireball(this, apThis, apOther); }
+
+ void dThunderCloud::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) {
+ if (apThis->info.category2 == 0x9) { return; }
+ PlaySound(this, SE_EMY_DOWN);
+ doStateChange(&StateID_DieFall); }
+ void dThunderCloud::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) { this->collisionCat13_Hammer(apThis, apOther); }
+ void dThunderCloud::collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther) {
+ if (apThis->info.category2 == 0x9) { return; }
+ dEn_c::collisionCat3_StarPower(apThis, apOther);
+ this->collisionCat13_Hammer(apThis, apOther); }
+
+
+ // These handle the ice crap
+ void dThunderCloud::_vf148() {
+ dEn_c::_vf148();
+ doStateChange(&StateID_DieFall);
+ }
+ void dThunderCloud::_vf14C() {
+ dEn_c::_vf14C();
+ doStateChange(&StateID_DieFall);
+ }
+
+ extern "C" void sub_80024C20(void);
+ extern "C" void __destroy_arr(void*, void(*)(void), int, int);
+ //extern "C" __destroy_arr(struct DoSomethingCool, void(*)(void), int cnt, int bar);
+
+ bool dThunderCloud::CreateIceActors() {
+ struct DoSomethingCool my_struct = { 0, (Vec){pos.x, pos.y - 16.0, pos.z}, {1.75, 1.4, 1.5}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+ this->frzMgr.Create_ICEACTORs( (void*)&my_struct, 1 );
+ __destroy_arr( (void*)&my_struct, sub_80024C20, 0x3C, 1 );
+ return true;
+ }
+
+
+void dThunderCloud::dieFall_Begin() {
+ this->Lightning.removeFromList();
+ this->timer = 0;
+ this->dEn_c::dieFall_Begin();
+}
+void dThunderCloud::dieFall_Execute() {
+ if (this->killFlag == 1) { return; }
+
+ this->timer = this->timer + 1;
+
+ this->dying = this->dying + 0.15;
+
+ this->pos.x = this->pos.x + 0.15;
+ this->pos.y = this->pos.y - ((-0.2 * (this->dying*this->dying)) + 5);
+
+ this->dEn_c::dieFall_Execute();
+
+ if (this->timer > 450) {
+
+ if ((this->settings >> 28) > 0) {
+ this->kill();
+ this->pos.y = this->pos.y + 800.0;
+ this->killFlag = 1;
+ return;
+ }
+
+ dStageActor_c *Player = GetSpecificPlayerActor(0);
+ if (Player == 0) { Player = GetSpecificPlayerActor(1); }
+ if (Player == 0) { Player = GetSpecificPlayerActor(2); }
+ if (Player == 0) { Player = GetSpecificPlayerActor(3); }
+
+
+ if (Player == 0) {
+ this->pos.x = 0;
+ doStateChange(&StateID_Follow); }
+ else {
+ Player->pos;
+ this->pos.x = Player->pos.x - 300;
+ }
+
+ this->pos.y = this->Baseline;
+
+ this->aPhysics.addToList();
+ doStateChange(&StateID_Follow);
+ }
+}
+
+
+void dThunderCloud::bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate) {
+ nw4r::g3d::ResAnmChr anmChr = this->resFile.GetResAnmChr(name);
+ this->anm.bind(&this->bodyModel, anmChr, unk);
+ this->bodyModel.bindAnim(&this->anm, unk2);
+ this->anm.setUpdateRate(rate);
+}
+
+
+int dThunderCloud::onCreate() {
+
+ // Setup the model
+ allocator.link(-1, GameHeaps[0], 0, 0x20);
+
+ this->resFile.data = getResource("tcloud", "g3d/tcloud.brres");
+ nw4r::g3d::ResMdl mdl = this->resFile.GetResMdl("cloud");
+ bodyModel.setup(mdl, &allocator, 0x224, 1, 0);
+ SetupTextures_Enemy(&bodyModel, 0);
+
+ bool ret;
+ nw4r::g3d::ResAnmChr anmChr = this->resFile.GetResAnmChr("thundershoot");
+ ret = this->anm.setup(mdl, anmChr, &this->allocator, 0);
+
+ allocator.unlink();
+
+
+ // Scale and Physics
+ ActivePhysics::Info Cloud;
+ Cloud.xDistToCenter = 0.0;
+ Cloud.yDistToCenter = 0.0;
+ Cloud.category1 = 0x3;
+ Cloud.category2 = 0x0;
+ Cloud.bitfield1 = 0x4F;
+
+ Cloud.bitfield2 = 0xffbafffe;
+ Cloud.xDistToEdge = 18.0;
+ Cloud.yDistToEdge = 12.0;
+
+ Cloud.unkShort1C = 0;
+ Cloud.callback = &dEn_c::collisionCallback;
+
+ this->aPhysics.initWithStruct(this, &Cloud);
+ this->aPhysics.addToList();
+
+
+ ActivePhysics::Info Shock;
+ Shock.xDistToCenter = 0.0;
+ Shock.yDistToCenter = -104.0;
+ Shock.category1 = 0x3;
+ Shock.category2 = 0x9;
+ Shock.bitfield1 = 0x4F;
+
+ Shock.bitfield2 = 0xffbafffe;
+ Shock.xDistToEdge = 12.0;
+ Shock.yDistToEdge = 90.0;
+
+ Shock.unkShort1C = 0;
+ Shock.callback = &dEn_c::collisionCallback;
+
+ this->Lightning.initWithStruct(this, &Shock);
+
+
+ // Some Settings
+ this->Baseline = this->pos.y;
+ this->dying = -5;
+ this->killFlag = 0;
+ this->pos.z = 5750.0f; // sun
+
+ char eventNum = (this->settings >> 16) & 0xFF;
+
+ this->eventFlag = (u64)1 << (eventNum - 1);
+
+
+ // State Change!
+ doStateChange(&StateID_Follow);
+
+ this->onExecute();
+ return true;
+}
+
+int dThunderCloud::onDelete() {
+ return true;
+}
+
+int dThunderCloud::onExecute() {
+ acState.execute();
+ updateModelMatrices();
+ bodyModel._vf1C();
+
+ if (dFlagMgr_c::instance->flags & this->eventFlag) {
+ if (this->killFlag == 0) {
+ this->kill();
+ this->pos.y = this->pos.y + 800.0;
+ this->killFlag = 1;
+ doStateChange(&StateID_DieFall);
+ }
+ }
+
+ return true;
+}
+
+int dThunderCloud::onDraw() {
+ bodyModel.scheduleForDrawing();
+
+ return true;
+}
+
+
+void dThunderCloud::updateModelMatrices() {
+ // This won't work with wrap because I'm lazy.
+ matrix.translation(pos.x, pos.y, pos.z);
+ matrix.applyRotationYXZ(&rot.x, &rot.y, &rot.z);
+
+ bodyModel.setDrawMatrix(matrix);
+ bodyModel.setScale(&scale);
+ bodyModel.calcWorld(false);
+}
+
+
+// Follow State
+
+void dThunderCloud::beginState_Follow() {
+ this->timer = 0;
+ this->bindAnimChr_and_setUpdateRate("thundershoot", 1, 0.0, 1.0);
+ this->rot.x = 0;
+ this->rot.y = 0;
+ this->rot.z = 0;
+ PlaySound(this, SE_AMB_THUNDER_CLOUD);
+}
+void dThunderCloud::executeState_Follow() {
+
+ charge.spawn("Wm_mr_electricshock_biri02_s", 0, &pos, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5});
+
+ if(this->anm.isAnimationDone()) {
+ this->anm.setCurrentFrame(0.0); }
+
+ if (this->timer > 200) { this->doStateChange(&StateID_Lightning); }
+
+ this->direction = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, this->pos);
+
+ float speedDelta;
+ speedDelta = 0.05;
+
+ if (this->direction == 0) {
+ this->speed.x = this->speed.x + speedDelta;
+
+ if (this->speed.x < 0) { this->speed.x = this->speed.x + (speedDelta / 1.5); }
+ if (this->speed.x < 6.0) { this->speed.x = this->speed.x + (speedDelta); }
+ }
+ else {
+ this->speed.x = this->speed.x - speedDelta;
+
+ if (this->speed.x > 0) { this->speed.x = this->speed.x - (speedDelta / 1.5); }
+ if (this->speed.x > 6.0) { this->speed.x = this->speed.x - (speedDelta); }
+ }
+
+ this->HandleXSpeed();
+
+ float yDiff;
+ yDiff = (this->Baseline - this->pos.y) / 8;
+ this->speed.y = yDiff;
+
+ this->HandleYSpeed();
+
+ this->UpdateObjectPosBasedOnSpeedValuesReal();
+
+ this->timer = this->timer + 1;
+}
+void dThunderCloud::endState_Follow() {
+ this->speed.y = 0;
+}
+
+
+// Wait State
+
+void dThunderCloud::beginState_Lightning() {
+ this->timer = 0;
+ this->speed.x = 0.0;
+}
+void dThunderCloud::executeState_Lightning() {
+
+ switch (timer) {
+ case 0:
+ charge.spawn("Wm_en_birikyu", 0, &(Vec){pos.x, pos.y, pos.z}, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5});
+ break;
+ case 1:
+ charge.spawn("Wm_en_birikyu", 0, &(Vec){pos.x, pos.y, pos.z}, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5});
+ break;
+ case 2:
+ this->Lightning.addToList();
+ PlaySound(this, SE_BOSS_JR_ELEC_APP);
+ PlaySound(this, SE_BOSS_JR_DAMAGE_ELEC);
+ PlaySound(this, SE_OBJ_KAZAN_ERUPTION);
+
+ bolt.spawn("Wm_jr_electricline", 0, &(Vec){pos.x, pos.y - 98.0, 0}, &(S16Vec){0,0,0}, &(Vec){1.0, 2.5, 1.0});
+ break;
+ case 3:
+ this->Lightning.removeFromList();
+ charge.spawn("Wm_mr_electricshock_biri02_s", 0, &pos, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5});
+ break;
+ case 4:
+ charge.spawn("Wm_mr_electricshock_biri02_s", 0, &pos, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5});
+ break;
+ case 5:
+ this->doStateChange(&StateID_Follow);
+ break;
+ default:
+ charge.spawn("Wm_mr_electricshock_biri02_s", 0, &pos, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5});
+ break;
+ }
+
+ if(this->anm.isAnimationDone() && this->anm.getCurrentFrame() != 0.0) {
+ this->timer += 1;
+ if (timer == 2) { this->bindAnimChr_and_setUpdateRate("thundershoot", 1, 0.0, 1.0); }
+ if (timer == 3) { this->bindAnimChr_and_setUpdateRate("cloud_wait", 1, 0.0, 1.0); }
+ this->anm.setCurrentFrame(0.0); }
+
+}
+void dThunderCloud::endState_Lightning() {
+ this->timer = 0;
+}
+
+
diff --git a/thundercloud.yaml b/thundercloud.yaml
new file mode 100644
index 0000000..e8a74c3
--- /dev/null
+++ b/thundercloud.yaml
@@ -0,0 +1,23 @@
+---
+# Replaces WM_BUBBLE
+
+source_files: [../src/thundercloud.cpp]
+hooks:
+ - name: BuildThundercloud
+ type: add_func_pointer
+ src_addr_pal: 0x80981E0C
+ target_func: 'dThunderCloud::build(void)'
+
+ - name: ThundercloudSpriteFileInfo
+ type: add_func_pointer
+ src_addr_pal: 0x8031ADEC
+ target_func: 'TLCarcNameList'
+ # 0x8031AB4C + sprite num * 0x4 == offset
+
+ - name: UpdateThundercloudSpriteInfo
+ type: patch
+ # 0x8030A340 + sprite num * 0x28 == offset
+ addr_pal: 0x8030BD80
+ # -ID- ---- -X Offs- -Y Offs- -RectX1- -RectY1- -RectX2- -RectY2- -1C- -1E- -20- -22- Flag ----
+ # Orig 01FC 0000 00000008 00000000 00000000 FFFFFFC0 00000010 00000040 0030 0030 0000 0000 0008 0000
+ data: '02A6 0000 00000000 00000000 00000000 00000000 00000200 00000200 0030 0030 0000 0000 0000 0000'
diff --git a/tools/UsedProfileAndSpriteList.txt b/tools/UsedProfileAndSpriteList.txt
index fc12126..7370670 100644
--- a/tools/UsedProfileAndSpriteList.txt
+++ b/tools/UsedProfileAndSpriteList.txt
@@ -28,6 +28,7 @@
107 : EN_LIFT_ROTATION_HALF : Message Box Manager
152 : EN_BLUR : Message Block
167 : WM_TREASURESHIP : Shy Guy Giant
+168 : WM_BUBBLE : Thundercloud
169 : EN_SLIP_PENGUIN : Magic Platform
183 : EN_TARZANROPE : Meteor
210 : TARZAN_ROPE : Topman
@@ -85,6 +86,7 @@ WALLINSECT_MGR
WM_ANCHOR
WM_ANTLION
WM_BOSS_IGGY
+WM_BUBBLE
WM_CLOUD
WM_DANCE_PAKKUN
WM_GHOST
@@ -121,7 +123,6 @@ WM_BOSS_MORTON
WM_BOSS_ROY
WM_BOSS_WENDY
WM_BROS
-WM_BUBBLE
WM_CANNON
WM_CASTLE
WM_COURSE
@@ -156,7 +157,6 @@ WM_TEST
WM_TEST2
WM_TORIDE
WM_TOWER
-
WM_YOGANPILLAR
WORLD_SELECT
WORLD_SELECT_GUIDE