ref: 12bb1f82bc08e34febad33844dfdd1f30dfbf5e9
parent: 9b608eb53acb868e11d49c6dd356e4dcac920341
author: Snesrev <[email protected]>
date: Fri Oct 7 14:06:12 EDT 2022
Using the Cane of Somaria might refund magic. (#126) Changed so it's more explicit when magic is refunded. Bug report: If you use the Cane of Somaria while two bombs and the boomerang are active, magic will be refunded instead of used.
--- a/ancilla.c
+++ b/ancilla.c
@@ -4753,12 +4753,10 @@
}
}
-void AncillaAdd_SomariaBlock(uint8 type, uint8 y) { // 88e078
+int AncillaAdd_SomariaBlock(uint8 type, uint8 y) { // 88e078
int k = AncillaAdd_AddAncilla_Bank08(type, y);
- if (k < 0) {
- Refund_Magic(4);
- return;
- }
+ if (k < 0)
+ return k;
for (int j = 4; j >= 0; j--) {
if (j == k || ancilla_type[j] != 0x2c)
continue;
@@ -4771,7 +4769,7 @@
bitmask_of_dragstate = 0;
link_speed_setting = 0;
}
- return;
+ return k;
}
Ancilla_Sfx3_Near(0x2a);
@@ -4804,6 +4802,7 @@
Ancilla_SetY(k, link_y_coord + kCaneOfSomaria_Y[j]);
SomariaBlock_CheckForTransitTile(k);
}
+ return k;
}
void SomariaBlock_CheckForTransitTile(int k) { // 88e191
--- a/ancilla.h
+++ b/ancilla.h
@@ -173,7 +173,7 @@
void Ancilla_SwordBeam(int k);
void Ancilla0D_SpinAttackFullChargeSpark(int k);
void Ancilla27_Duck(int k);
-void AncillaAdd_SomariaBlock(uint8 type, uint8 y);
+int AncillaAdd_SomariaBlock(uint8 type, uint8 y);
void SomariaBlock_CheckForTransitTile(int k);
int Ancilla_CheckBasicSpriteCollision(int k);
bool Ancilla_CheckBasicSpriteCollision_Single(int k, int j);
--- a/player.c
+++ b/player.c
@@ -3260,18 +3260,30 @@
if (player_on_somaria_platform || is_standing_in_doorway || !CheckYButtonPress())
return;
int i = 4;
+ bool did_charge_magic = false;
+
while (ancilla_type[i] != 0x2c) {
if (--i < 0) {
if (!LinkCheckMagicCost(4)) {
+ // If you use the Cane of Somaria with an empty magic meter,
+ // then quickly switch to the mushroom or magic powder after
+ // the "no magic" prompt, you will automatically sprinkle magic powder
+ // despite pressing no button and having no magic.
if (enhanced_features0 & kFeatures0_MiscBugFixes)
goto out;
return;
}
+ did_charge_magic = true;
break;
}
}
link_debug_value_2 = 1;
- AncillaAdd_SomariaBlock(44, 1);
+ if (AncillaAdd_SomariaBlock(0x2c, 1) < 0) {
+ // If you use the Cane of Somaria while two bombs and the boomerang are active,
+ // magic will be refunded instead of used.
+ if (did_charge_magic || !(enhanced_features0 & kFeatures0_MiscBugFixes))
+ Refund_Magic(4);
+ }
link_delay_timer_spin_attack = kRodAnimDelays[0];
link_animation_steps = 0;
player_handler_timer = 0;