@ -70,6 +70,7 @@ static void* sItemDropTex[] = {
gDropRecoveryHeartTex , gDropBombTex , gDropArrows1Tex , gDropArrows2Tex ,
gDropArrows3Tex , gDropBombTex , gDropDekuNutTex , gDropDekuStickTex ,
gDropMagicLargeTex , gDropMagicSmallTex , gDropDekuSeedsTex , gDropKeySmallTex ,
// OTRTODO: use 2D bombchu texture
} ;
static u8 sItemDropIds [ ] = {
@ -390,6 +391,7 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) {
case ITEM00_RUPEE_ORANGE :
case ITEM00_RUPEE_PURPLE :
case ITEM00_FLEXIBLE :
case ITEM00_BOMBCHU :
yOffset = 500.0f ;
Actor_SetScale ( & this - > actor , 0.01f ) ;
this - > scale = 0.01f ;
@ -507,6 +509,9 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) {
case ITEM00_TUNIC_GORON :
case ITEM00_BOMBS_SPECIAL :
break ;
case ITEM00_BOMBCHU :
Item_Give ( globalCtx , ITEM_BOMBCHUS_5 ) ;
break ;
}
if ( ! Actor_HasParent ( & this - > actor , globalCtx ) ) {
@ -537,7 +542,8 @@ void func_8001DFC8(EnItem00* this, GlobalContext* globalCtx) {
( this - > actor . params = = ITEM00_HEART_PIECE ) ) {
this - > actor . shape . rot . y + = 960 ;
} else {
if ( ( this - > actor . params > = ITEM00_SHIELD_DEKU ) & & ( this - > actor . params ! = ITEM00_BOMBS_SPECIAL ) ) {
if ( ( this - > actor . params > = ITEM00_SHIELD_DEKU ) & & ( this - > actor . params ! = ITEM00_BOMBS_SPECIAL ) & &
( this - > actor . params ! = ITEM00_BOMBCHU ) ) {
if ( this - > unk_15A = = - 1 ) {
if ( Math_SmoothStepToS ( & this - > actor . shape . rot . x , this - > actor . world . rot . x - 0x4000 , 2 , 3000 , 1500 ) = =
0 ) {
@ -640,7 +646,8 @@ void func_8001E304(EnItem00* this, GlobalContext* globalCtx) {
if ( this - > actor . params < = ITEM00_RUPEE_RED ) {
this - > actor . shape . rot . y + = 960 ;
} else if ( ( this - > actor . params > = ITEM00_SHIELD_DEKU ) & & ( this - > actor . params ! = ITEM00_BOMBS_SPECIAL ) ) {
} else if ( ( this - > actor . params > = ITEM00_SHIELD_DEKU ) & & ( this - > actor . params ! = ITEM00_BOMBS_SPECIAL ) & &
( this - > actor . params ! = ITEM00_BOMBCHU ) ) {
this - > actor . world . rot . x - = 700 ;
this - > actor . shape . rot . y + = 400 ;
this - > actor . shape . rot . x = this - > actor . world . rot . x - 0x4000 ;
@ -722,7 +729,8 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) {
EnItem00 * this = ( EnItem00 * ) thisx ;
s32 pad ;
if ( CVar_GetS32 ( " gNewDrops " , 0 ) ) { //set the rotation system on selected model only :)
// OTRTODO: remove special case for bombchu when its 2D drop is implemented
if ( CVar_GetS32 ( " gNewDrops " , 0 ) | | this - > actor . params = = ITEM00_BOMBCHU ) { //set the rotation system on selected model only :)
if ( ( this - > actor . params = = ITEM00_RUPEE_GREEN ) | | ( this - > actor . params = = ITEM00_RUPEE_BLUE ) | |
( this - > actor . params = = ITEM00_RUPEE_RED ) | | ( this - > actor . params = = ITEM00_ARROWS_SINGLE ) | |
( this - > actor . params = = ITEM00_ARROWS_SMALL ) | | ( this - > actor . params = = ITEM00_ARROWS_MEDIUM ) | |
@ -730,7 +738,8 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) {
( this - > actor . params = = ITEM00_BOMBS_B ) | | ( this - > actor . params = = ITEM00_NUTS ) | |
( this - > actor . params = = ITEM00_MAGIC_SMALL ) | | ( this - > actor . params = = ITEM00_SEEDS ) | |
( this - > actor . params = = ITEM00_MAGIC_LARGE ) | | ( this - > actor . params = = ITEM00_HEART ) | |
( this - > actor . params = = ITEM00_BOMBS_SPECIAL ) | | this - > actor . params = = ITEM00_HEART_PIECE ) {
( this - > actor . params = = ITEM00_BOMBS_SPECIAL ) | | this - > actor . params = = ITEM00_HEART_PIECE | |
( this - > actor . params = = ITEM00_BOMBCHU ) ) {
this - > actor . shape . rot . y + = 960 ;
}
if ( this - > actor . params = = ITEM00_SMALL_KEY & & ! gSaveContext . n64ddFlag ) {
@ -891,6 +900,9 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) {
break ;
case ITEM00_BOMBS_SPECIAL :
break ;
case ITEM00_BOMBCHU :
Item_Give ( globalCtx , ITEM_BOMBCHUS_5 ) ;
break ;
}
params = & this - > actor . params ;
@ -1212,6 +1224,15 @@ void EnItem00_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnItem00_DrawCollectible ( this , globalCtx ) ;
break ;
}
case ITEM00_BOMBCHU :
// OTRTODO: Stop forcing chu drops to be 3D when the texture is added
Actor_SetScale ( & this - > actor , 0.2f ) ;
this - > scale = 0.2f ;
this - > actor . shape . yOffset = 50.0f ;
this - > actor . world . rot . x = 0x4000 ;
this - > actor . shape . shadowScale = 0.3f ;
GetItem_Draw ( globalCtx , GID_BOMBCHU ) ;
break ;
case ITEM00_SHIELD_DEKU :
GetItem_Draw ( globalCtx , GID_SHIELD_DEKU ) ;
break ;
@ -1370,6 +1391,9 @@ void EnItem00_DrawCollectible(EnItem00* this, GlobalContext* globalCtx) {
if ( this - > actor . params = = ITEM00_BOMBS_SPECIAL ) {
texIndex = 1 ;
// OTRTODO: 2D bombchu drops
//} else if (this->actor.params == ITEM00_BOMBCHU) {
// texIndex = 12;
} else if ( this - > actor . params > = ITEM00_ARROWS_SMALL ) {
texIndex - = 3 ;
}
@ -1435,6 +1459,36 @@ void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx) {
}
}
/**
* Sometimes convert the given drop ID into a bombchu .
* Returns the new drop type ID .
*/
s16 EnItem00_ConvertBombDropToBombchu ( s16 dropId ) {
if ( INV_CONTENT ( ITEM_BOMBCHU ) = = ITEM_NONE ) {
return dropId ;
}
if ( INV_CONTENT ( ITEM_BOMB ) = = ITEM_NONE ) {
return ITEM00_BOMBCHU ;
}
if ( AMMO ( ITEM_BOMB ) < = 15 ) {
// Player needs bombs and might need chus, so drop whichever has less
if ( AMMO ( ITEM_BOMB ) < = AMMO ( ITEM_BOMBCHU ) ) {
return dropId ;
} else {
return ITEM00_BOMBCHU ;
}
} else {
// Player has enough bombs, so drop chus if they need some, else it's 50/50
if ( AMMO ( ITEM_BOMBCHU ) < = 15 ) {
return ITEM00_BOMBCHU ;
} else {
return Rand_Next ( ) % 2 ? dropId : ITEM00_BOMBCHU ;
}
}
}
/**
* Converts a given drop type ID based on link ' s current age , health and owned items .
* Returns a new drop type ID or - 1 to cancel the drop .
@ -1452,6 +1506,11 @@ s16 func_8001F404(s16 dropId) {
}
}
if ( CVar_GetS32 ( " gBombchuDrops " , 0 ) & &
( dropId = = ITEM00_BOMBS_A | | dropId = = ITEM00_BOMBS_B | | dropId = = ITEM00_BOMBS_SPECIAL ) ) {
dropId = EnItem00_ConvertBombDropToBombchu ( dropId ) ;
}
// This is convoluted but it seems like it must be a single condition to match
// clang-format off
if ( ( ( dropId = = ITEM00_BOMBS_A | | dropId = = ITEM00_BOMBS_SPECIAL | | dropId = = ITEM00_BOMBS_B ) & & INV_CONTENT ( ITEM_BOMB ) = = ITEM_NONE ) | |