mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-10-13 07:25:54 -04:00
force empty bottle OI to use the milk effect to avoid UB (#7247)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include <libultraship/bridge/consolevariablebridge.h>
|
||||
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
@@ -156,6 +157,17 @@ void RegisterAlwaysOnFixes() {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Empty Bottle OI (aka "Drinking Bugs") causes the bottle to read the potion effect array out of bounds
|
||||
// The exact effect this had on N64 depended on the game version, but on ship it seems to depend on the compiler or
|
||||
// build type. To resolve this UB, this hook forces the effect of milk, which is the most useful vanilla effect
|
||||
// (other versions do nothing). A setting can be trivially added if the option for it to do something else is
|
||||
// desired, but it should still be in this hook to avoid UB.
|
||||
COND_VB_SHOULD(VB_EMPTY_BOTTLE_OI, true, {
|
||||
if (!*should) {
|
||||
gSaveContext.healthAccumulator = 0x50;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initAlwaysOnFixes(RegisterAlwaysOnFixes, { "" });
|
||||
|
||||
@@ -4080,4 +4080,13 @@ typedef enum {
|
||||
// #### `args`
|
||||
// - `*Player`
|
||||
VB_PLAYER_UNEQUIP_MASK_WITHOUT_BUTTON,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// this->itemAction != PLAYER_IA_BOTTLE
|
||||
// ```
|
||||
// #### `args`
|
||||
// - none
|
||||
VB_EMPTY_BOTTLE_OI,
|
||||
|
||||
} GIVanillaBehavior;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
#include "objects/object_link_child/object_link_child.h"
|
||||
#include <soh/Enhancements/custom-message/CustomMessageTypes.h>
|
||||
#include "soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h"
|
||||
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
||||
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
@@ -14380,18 +14381,20 @@ void Player_Action_8084EAC0(Player* this, PlayState* play) {
|
||||
gSaveContext.healthAccumulator = rand * FULL_HEART_HEALTH;
|
||||
}
|
||||
} else {
|
||||
s32 sp28 = D_808549FC[this->itemAction - PLAYER_IA_BOTTLE_POTION_RED];
|
||||
if (GameInteractor_Should(VB_EMPTY_BOTTLE_OI, this->itemAction != PLAYER_IA_BOTTLE)) {
|
||||
s32 sp28 = D_808549FC[this->itemAction - PLAYER_IA_BOTTLE_POTION_RED];
|
||||
|
||||
if (sp28 & 1) {
|
||||
gSaveContext.healthAccumulator = MAX_HEALTH;
|
||||
}
|
||||
if (sp28 & 1) {
|
||||
gSaveContext.healthAccumulator = MAX_HEALTH;
|
||||
}
|
||||
|
||||
if (sp28 & 2) {
|
||||
Magic_Fill(play);
|
||||
}
|
||||
if (sp28 & 2) {
|
||||
Magic_Fill(play);
|
||||
}
|
||||
|
||||
if (sp28 & 4) {
|
||||
gSaveContext.healthAccumulator = 0x50;
|
||||
if (sp28 & 4) {
|
||||
gSaveContext.healthAccumulator = 0x50;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user