Item drops 3D! (#633)

* Initial 3D Item Drops Toggle

* Use generic hooks and other tweaks

* 3d drop fixes and changes

* move slime item draw to VB hook; fix arrow GID

* whitespacing

---------

Co-authored-by: Garrett Cox <garrettjcox@gmail.com>
Co-authored-by: Archez <archez39@me.com>
This commit is contained in:
Captain Kitty Cat 2024-07-24 04:39:25 +03:00 committed by GitHub
parent 57cb5d2b51
commit 51af06463f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 208 additions and 4 deletions

View File

@ -8,6 +8,7 @@
#include <unordered_map>
#include <string>
#include "2s2h/Enhancements/Enhancements.h"
#include "2s2h/Enhancements/Graphics/3DItemDrops.h"
#include "2s2h/Enhancements/Graphics/MotionBlur.h"
#include "2s2h/Enhancements/Graphics/PlayAsKafei.h"
#include "2s2h/Enhancements/Modes/TimeMovesWhenYouMove.h"
@ -537,6 +538,10 @@ void DrawEnhancementsMenu() {
"model and texture on the boot logo start screen" });
UIWidgets::CVarCheckbox("Bow Reticle", "gEnhancements.Graphics.BowReticle",
{ .tooltip = "Gives the bow a reticle when you draw an arrow" });
if (UIWidgets::CVarCheckbox("3D Item Drops", "gEnhancements.Graphics.3DItemDrops",
{ .tooltip = "Makes item drops 3D" })) {
Register3DItemDrops();
}
UIWidgets::CVarCheckbox(
"Disable Black Bar Letterboxes", "gEnhancements.Graphics.DisableBlackBars",
{ .tooltip = "Disables Black Bar Letterboxes during cutscenes and Z-targeting\nNote: there may be "

View File

@ -29,6 +29,7 @@ void InitEnhancements() {
// Graphics
RegisterDisableBlackBars();
Register3DItemDrops();
// Masks
RegisterFastTransformation();

View File

@ -23,6 +23,7 @@
#include "Restorations/PowerCrouchStab.h"
#include "Restorations/SideRoll.h"
#include "Restorations/TatlISG.h"
#include "Graphics/3DItemDrops.h"
#include "Graphics/PlayAsKafei.h"
#include "Player/Player.h"
#include "Songs/EnableSunsSong.h"

View File

@ -55,6 +55,7 @@ typedef enum {
GI_VB_FLIP_HOP_VARIABLE,
GI_VB_DISABLE_LETTERBOX,
GI_VB_CLOCK_TOWER_OPENING_CONSIDER_THIS_FIRST_CYCLE,
GI_VB_DRAW_SLIME_BODY_ITEM,
} GIVanillaBehavior;
typedef enum {

View File

@ -0,0 +1,185 @@
#include "3DItemDrops.h"
#include "libultraship/libultraship.h"
#include "2s2h/Enhancements/GameInteractor/GameInteractor.h"
extern "C" {
#include "z64.h"
#include "functions.h"
#include "overlays/actors/ovl_En_Slime/z_en_slime.h"
extern PlayState* gPlayState;
void EnItem00_Draw(Actor* thisx, PlayState* play);
}
bool ItemShouldSpinWhen3D(Actor* actor) {
EnItem00* enItem00 = (EnItem00*)actor;
// Exclude actors that already have spin normally, or shouldn't spin ever
if ((actor->params <= ITEM00_RUPEE_RED) || ((actor->params == ITEM00_RECOVERY_HEART) && (enItem00->unk152 < 0)) ||
(actor->params == ITEM00_HEART_PIECE) || (actor->params == ITEM00_HEART_CONTAINER) ||
(actor->params == ITEM00_RUPEE_HUGE) || (actor->params == ITEM00_RUPEE_PURPLE) ||
(actor->params == ITEM00_SHIELD_HERO) || (actor->params == ITEM00_MAP) || (actor->params == ITEM00_COMPASS)) {
return false;
}
return true;
}
void EnItem00_3DItemsDraw(Actor* actor, PlayState* play) {
EnItem00* enItem00 = (EnItem00*)actor;
if (!(enItem00->unk14E & enItem00->unk150)) {
switch (enItem00->actor.params) {
case ITEM00_RUPEE_GREEN:
Matrix_Scale(25.0f, 25.0f, 25.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_RUPEE_GREEN);
break;
case ITEM00_RUPEE_BLUE:
Matrix_Scale(25.0f, 25.0f, 25.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_RUPEE_BLUE);
break;
case ITEM00_RUPEE_RED:
Matrix_Scale(25.0f, 25.0f, 25.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_RUPEE_RED);
break;
case ITEM00_RUPEE_HUGE:
Matrix_Scale(17.5f, 17.5f, 17.5f, MTXMODE_APPLY);
GetItem_Draw(play, GID_RUPEE_HUGE);
break;
case ITEM00_RUPEE_PURPLE:
Matrix_Scale(17.5f, 17.5f, 17.5f, MTXMODE_APPLY);
GetItem_Draw(play, GID_RUPEE_PURPLE);
break;
case ITEM00_HEART_PIECE:
Matrix_Scale(16.0f, 16.0f, 16.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_HEART_PIECE);
break;
case ITEM00_HEART_CONTAINER:
Matrix_Scale(16.0f, 16.0f, 16.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_HEART_CONTAINER);
break;
case ITEM00_RECOVERY_HEART:
Matrix_Scale(16.0f, 16.0f, 16.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_RECOVERY_HEART);
break;
case ITEM00_BOMBS_A:
case ITEM00_BOMBS_B:
case ITEM00_BOMBS_0:
Matrix_Scale(8.0f, 8.0f, 8.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_BOMB);
break;
case ITEM00_ARROWS_10:
Matrix_Scale(7.0f, 7.0f, 7.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_ARROWS_SMALL);
break;
case ITEM00_ARROWS_30:
Matrix_Scale(7.0f, 7.0f, 7.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_ARROWS_MEDIUM);
break;
case ITEM00_ARROWS_40:
case ITEM00_ARROWS_50:
Matrix_Scale(7.0f, 7.0f, 7.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_ARROWS_LARGE);
break;
case ITEM00_MAGIC_JAR_SMALL:
Matrix_Scale(8.0f, 8.0f, 8.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_MAGIC_JAR_SMALL);
break;
case ITEM00_MAGIC_JAR_BIG:
Matrix_Scale(8.0f, 8.0f, 8.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_MAGIC_JAR_BIG);
break;
case ITEM00_DEKU_STICK:
Matrix_Scale(7.5f, 7.5f, 7.5f, MTXMODE_APPLY);
GetItem_Draw(play, GID_DEKU_STICK);
break;
case ITEM00_SMALL_KEY:
Matrix_Scale(8.0f, 8.0f, 8.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_KEY_SMALL);
break;
case ITEM00_DEKU_NUTS_1:
case ITEM00_DEKU_NUTS_10:
Matrix_Scale(9.0f, 9.0f, 9.0f, MTXMODE_APPLY);
GetItem_Draw(play, GID_DEKU_NUTS);
break;
case ITEM00_SHIELD_HERO:
GetItem_Draw(play, GID_SHIELD_HERO);
break;
case ITEM00_MAP:
GetItem_Draw(play, GID_DUNGEON_MAP);
break;
case ITEM00_COMPASS:
GetItem_Draw(play, GID_COMPASS);
break;
}
}
}
void DrawSlime3DItem(GIVanillaBehavior _, bool* should, void* opt) {
*should = false;
EnSlime* slime = static_cast<EnSlime*>(opt);
// Rotate 3D item with chu body
Matrix_RotateYS(slime->actor.shape.rot.y, MTXMODE_APPLY);
Matrix_Scale(0.25f, 0.25f, 0.25f, MTXMODE_APPLY);
switch (slime->actor.params) {
case EN_SLIME_TYPE_RED:
GetItem_Draw(gPlayState, GID_RECOVERY_HEART);
break;
case EN_SLIME_TYPE_GREEN:
GetItem_Draw(gPlayState, GID_MAGIC_JAR_SMALL);
break;
case EN_SLIME_TYPE_YELLOW:
GetItem_Draw(gPlayState, GID_ARROWS_SMALL);
break;
}
}
void Register3DItemDrops() {
static HOOK_ID actorInitHookID = 0;
static HOOK_ID actorUpdateHookID = 0;
static HOOK_ID slimeVBHookID = 0;
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnActorInit>(actorInitHookID);
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnActorUpdate>(actorUpdateHookID);
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::ShouldVanillaBehavior>(slimeVBHookID);
actorInitHookID = 0;
actorUpdateHookID = 0;
slimeVBHookID = 0;
if (gPlayState != NULL) {
Actor* actor = gPlayState->actorCtx.actorLists[ACTORCAT_MISC].first;
while (actor != NULL) {
if (actor->id == ACTOR_EN_ITEM00) {
if (CVarGetInteger("gEnhancements.Graphics.3DItemDrops", 0)) {
actor->draw = EnItem00_3DItemsDraw;
} else {
actor->draw = EnItem00_Draw;
// Reset rotation for bill-boarded sprites
if (ItemShouldSpinWhen3D(actor)) {
actor->shape.rot.y = 0;
}
}
}
actor = actor->next;
}
}
if (!CVarGetInteger("gEnhancements.Graphics.3DItemDrops", 0)) {
return;
}
actorInitHookID = GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorInit>(
ACTOR_EN_ITEM00, [](Actor* actor) { actor->draw = EnItem00_3DItemsDraw; });
actorUpdateHookID = GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(
ACTOR_EN_ITEM00, [](Actor* actor) {
// Add spin to normally bill-boarded items
if (ItemShouldSpinWhen3D(actor)) {
actor->shape.rot.y += 0x3C0;
}
});
slimeVBHookID = GameInteractor::Instance->RegisterGameHookForID<GameInteractor::ShouldVanillaBehavior>(
GI_VB_DRAW_SLIME_BODY_ITEM, DrawSlime3DItem);
}

View File

@ -0,0 +1,6 @@
#ifndef GRAPHICS_3D_ITEM_DROPS_H
#define GRAPHICS_3D_ITEM_DROPS_H
void Register3DItemDrops();
#endif // GRAPHICS_3D_ITEM_DROPS_H

View File

@ -7,6 +7,8 @@
#include "z_en_slime.h"
#include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h"
#include "2s2h/Enhancements/GameInteractor/GameInteractor.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_200)
#define THIS ((EnSlime*)thisx)
@ -1239,11 +1241,14 @@ void EnSlime_Draw(Actor* thisx, PlayState* play) {
Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y + (2000.0f * this->actor.scale.y),
this->actor.world.pos.z, MTXMODE_NEW);
Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY);
gSPSegment(POLY_OPA_DISP++, 8, (uintptr_t)this->itemDropTex);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gItemDropDL);
if (GameInteractor_Should(GI_VB_DRAW_SLIME_BODY_ITEM, true, this)) {
Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY);
gSPSegment(POLY_OPA_DISP++, 8, (uintptr_t)this->itemDropTex);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gItemDropDL);
}
}
Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, EN_SLIME_BODYPART_MAX, this->drawDmgEffScale,