diff --git a/actors/klepto/geo.inc.c b/actors/klepto/geo.inc.c index 8afe5ef8..4e807d7b 100644 --- a/actors/klepto/geo.inc.c +++ b/actors/klepto/geo.inc.c @@ -31,9 +31,11 @@ const GeoLayout klepto_geo[] = { GEO_OPEN_NODE(), GEO_SCALE(0x00, 16384), GEO_OPEN_NODE(), - GEO_ASM(0, geo_mario_set_player_colors), GEO_ASM(0, geo_offset_klepto_held_object), - GEO_TRANSLATE_ROTATE_WITH_DL(LAYER_OPAQUE, 0, 100, 0, 180, 270, 0, mario_cap_seg3_dl_03022F48), + GEO_TRANSLATE_ROTATE(LAYER_OPAQUE, 0, 100, 0, 180, 270, 0), + GEO_OPEN_NODE(), + GEO_ASM(0, geo_mario_cap_display_list), + GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_NODE_START(), @@ -55,14 +57,6 @@ const GeoLayout klepto_geo[] = { GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_NODE_START(), - GEO_OPEN_NODE(), - GEO_SCALE(0x00, 16384), - GEO_OPEN_NODE(), - GEO_ASM(0, geo_mario_set_player_colors), - GEO_ASM(0, geo_offset_klepto_held_object), - GEO_TRANSLATE_ROTATE_WITH_DL(LAYER_OPAQUE, 0, 100, 0, 180, 270, 0, luigi_cap_seg3_dl_03022F48), - GEO_CLOSE_NODE(), - GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), diff --git a/actors/ukiki/geo.inc.c b/actors/ukiki/geo.inc.c index fdf88015..a7708af8 100644 --- a/actors/ukiki/geo.inc.c +++ b/actors/ukiki/geo.inc.c @@ -22,26 +22,23 @@ const GeoLayout ukiki_geo[] = { GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, ukiki_seg5_dl_0500B2E8), GEO_OPEN_NODE(), - GEO_ASM(0, geo_mario_set_player_colors), - GEO_TRANSLATE_ROTATE_WITH_DL(LAYER_OPAQUE, 100, 0, 0, -90, -90, 0, mario_cap_seg3_dl_03022F48), + GEO_TRANSLATE_ROTATE(LAYER_OPAQUE, 120, 0, 0, -90, -90, 0), + GEO_OPEN_NODE(), + GEO_ASM(0, geo_mario_cap_display_list), + GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_NODE_START(), GEO_OPEN_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, ukiki_seg5_dl_0500B310), GEO_OPEN_NODE(), - GEO_ASM(0, geo_mario_set_player_colors), - GEO_TRANSLATE_ROTATE_WITH_DL(LAYER_OPAQUE, 100, 0, 0, -90, -90, 0, mario_cap_seg3_dl_03022F48), + GEO_TRANSLATE_ROTATE(LAYER_OPAQUE, 120, 0, 0, -90, -90, 0), + GEO_OPEN_NODE(), + GEO_ASM(0, geo_mario_cap_display_list), + GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_NODE_START(), - GEO_OPEN_NODE(), - GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, ukiki_seg5_dl_0500B2E8), - GEO_OPEN_NODE(), - GEO_ASM(0, geo_mario_set_player_colors), - GEO_TRANSLATE_ROTATE_WITH_DL(LAYER_OPAQUE, 100, 0, 0, -90, -90, 0, luigi_cap_seg3_dl_03022F48), - GEO_CLOSE_NODE(), - GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_CLOSE_NODE(), GEO_ANIMATED_PART(LAYER_OPAQUE, 71, 69, -9, NULL), diff --git a/include/object_constants.h b/include/object_constants.h index 8c546977..671894c6 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -664,7 +664,6 @@ #define UKIKI_ANIM_STATE_EYE_CLOSED 1 // unused #define UKIKI_ANIM_STATE_HAT_ON 2 #define UKIKI_ANIM_STATE_UNUSED 3 // unused, HAT_ON+EYE_CLOSED - #define UKIKI_ANIM_STATE_HAT_ON_LUIGI 4 /* oUkikiHasHat */ #define UKIKI_HAT_ON 1 @@ -885,7 +884,6 @@ #define KLEPTO_ANIM_STATE_HOLDING_NOTHING 0 #define KLEPTO_ANIM_STATE_HOLDING_CAP 1 #define KLEPTO_ANIM_STATE_HOLDING_STAR 2 - #define KLEPTO_ANIM_STATE_HOLDING_CAP_LUIGI 4 /* Bird */ /* oAction */ diff --git a/src/game/behaviors/klepto.inc.c b/src/game/behaviors/klepto.inc.c index 9d1cfdaa..fce4ec85 100644 --- a/src/game/behaviors/klepto.inc.c +++ b/src/game/behaviors/klepto.inc.c @@ -292,7 +292,7 @@ static void klepto_act_dive_at_mario(void) { && !(marioState->action & (ACT_FLAG_SHORT_HITBOX | ACT_FLAG_BUTT_OR_STOMACH_SLIDE)) && distanceToPlayer < 200.0f && dy > 50.0f && dy < 90.0f) { if (network_owns_object(o) && mario_lose_cap_to_enemy(marioState, 1) && marioState->playerIndex == 0) { - o->oAnimState = marioState->character->capKleptoAnimState; + o->oAnimState = KLEPTO_ANIM_STATE_HOLDING_CAP; o->globalPlayerIndex = gNetworkPlayers[marioState->playerIndex].globalIndex; network_send_object(o); } @@ -416,16 +416,14 @@ void bhv_klepto_update(void) { if (obj_handle_attacks(&sKleptoHitbox, o->oAction, sKleptoAttackHandlers)) { cur_obj_play_sound_2(SOUND_OBJ_KLEPTO2); - u8 kleptoHoldingCap = FALSE; - u32 capModel = MODEL_MARIOS_CAP; - for (int i = 0; i < CT_MAX; i++) { - if (o->oAnimState == gCharacters[i].capKleptoAnimState) { - kleptoHoldingCap = TRUE; - capModel = gCharacters[i].capModelId; - } - } + u8 kleptoHoldingCap = (o->oAnimState == KLEPTO_ANIM_STATE_HOLDING_CAP); if (network_owns_object(o) && kleptoHoldingCap) { + struct NetworkPlayer* np = network_player_from_global_index(o->globalPlayerIndex); + if (np == NULL) { np = gNetworkPlayerLocal; } + u8 modelIndex = (np->modelIndex < CT_MAX) ? np->modelIndex : 0; + u32 capModel = gCharacters[modelIndex].capModelId; + save_file_clear_flags(SAVE_FLAG_CAP_ON_KLEPTO); struct Object* cap = spawn_object(o, capModel, bhvNormalCap); diff --git a/src/game/behaviors/ukiki.inc.c b/src/game/behaviors/ukiki.inc.c index 7f5de13b..f61e2f8f 100644 --- a/src/game/behaviors/ukiki.inc.c +++ b/src/game/behaviors/ukiki.inc.c @@ -693,7 +693,7 @@ void bhv_ukiki_loop(void) { for (int i = 0; i < MAX_PLAYERS; i++) { if (!is_player_active(&gMarioStates[i])) { continue; } if (!does_mario_have_hat(&gMarioStates[i])) { - o->oAnimState = gMarioStates[i].character->capUkikiAnimState; + o->oAnimState = UKIKI_ANIM_STATE_HAT_ON; break; } } diff --git a/src/game/characters.c b/src/game/characters.c index b46a2a5c..4310c21d 100644 --- a/src/game/characters.c +++ b/src/game/characters.c @@ -1,3 +1,4 @@ +#include "sm64.h" #include "types.h" #include "characters.h" #include "hud.h" @@ -8,6 +9,9 @@ #include "pc/configfile.h" #include "audio/external.h" +extern Gfx mario_cap_seg3_dl_03022F48[]; +extern Gfx luigi_cap_seg3_dl_03022F48[]; + struct Character gCharacters[CT_MAX] = { [CT_MARIO] = { .hudHead = ',', @@ -17,8 +21,9 @@ struct Character gCharacters[CT_MAX] = { .capMetalModelId = MODEL_MARIOS_METAL_CAP, .capWingModelId = MODEL_MARIOS_WING_CAP, .capMetalWingModelId = MODEL_MARIOS_WINGED_METAL_CAP, - .capKleptoAnimState = KLEPTO_ANIM_STATE_HOLDING_CAP, - .capUkikiAnimState = UKIKI_ANIM_STATE_HAT_ON, + .capEnemyLayer = LAYER_OPAQUE, + .capEnemyGfx = mario_cap_seg3_dl_03022F48, + .capEnemyDecalGfx = NULL, .soundFreqScale = 1.0f, // sounds .soundYahWahHoo = SOUND_MARIO_YAH_WAH_HOO, @@ -73,8 +78,9 @@ struct Character gCharacters[CT_MAX] = { .capMetalModelId = MODEL_LUIGIS_METAL_CAP, .capWingModelId = MODEL_LUIGIS_WING_CAP, .capMetalWingModelId = MODEL_LUIGIS_WINGED_METAL_CAP, - .capKleptoAnimState = KLEPTO_ANIM_STATE_HOLDING_CAP_LUIGI, - .capUkikiAnimState = UKIKI_ANIM_STATE_HAT_ON_LUIGI, + .capEnemyLayer = LAYER_OPAQUE, + .capEnemyGfx = luigi_cap_seg3_dl_03022F48, + .capEnemyDecalGfx = NULL, .soundFreqScale = 1.0f, // sounds .soundYahWahHoo = SOUND_LUIGI_YAH_WAH_HOO, diff --git a/src/game/characters.h b/src/game/characters.h index 08fe5c23..307f2182 100644 --- a/src/game/characters.h +++ b/src/game/characters.h @@ -19,8 +19,9 @@ struct Character { u32 capMetalModelId; u32 capWingModelId; u32 capMetalWingModelId; - s32 capKleptoAnimState; - s32 capUkikiAnimState; + u8 capEnemyLayer; + Gfx* capEnemyGfx; + Gfx* capEnemyDecalGfx; f32 soundFreqScale; // sounds s32 soundYahWahHoo; diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 9705466b..45cf61b9 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -832,3 +832,32 @@ Gfx* geo_mario_set_player_colors(s32 callContext, struct GraphNode* node, UNUSED } return gfx; } + +Gfx* geo_mario_cap_display_list(s32 callContext, struct GraphNode* node, UNUSED Mat4* c) { + if (callContext != GEO_CONTEXT_RENDER) { return NULL; } + u8 globalIndex = geo_get_processing_object_index(); + u8 colorIndex = gNetworkPlayers[globalIndex].paletteIndex; + u8 charIndex = gNetworkPlayers[globalIndex].modelIndex; + if (charIndex >= CT_MAX) { charIndex = 0; } + struct Character* character = &gCharacters[charIndex]; + + u8 dpLength = 5; + if (character->capEnemyGfx != NULL) { dpLength++; } + if (character->capEnemyDecalGfx != NULL) { dpLength++; } + Gfx* gfx = alloc_display_list(dpLength * sizeof(*gfx)); + Gfx* onGfx = gfx; + + // put the player colors into lights 3, 4, 5, 6 + // they will be later copied to lights 1, 2 with gsSPCopyLightEXT + gSPLight(onGfx++, &gPlayerColors[colorIndex].pants.l, 3); + gSPLight(onGfx++, &gPlayerColors[colorIndex].pants.a, 4); + gSPLight(onGfx++, &gPlayerColors[colorIndex].shirt.l, 5); + gSPLight(onGfx++, &gPlayerColors[colorIndex].shirt.a, 6); + if (character->capEnemyGfx != NULL) { gSPDisplayList(onGfx++, character->capEnemyGfx); } + if (character->capEnemyDecalGfx != NULL) { gSPDisplayList(onGfx++, character->capEnemyDecalGfx); } + gSPEndDisplayList(onGfx++); + + struct GraphNodeGenerated* asGenerated = (struct GraphNodeGenerated*)node; + asGenerated->fnNode.node.flags = (asGenerated->fnNode.node.flags & 0xFF) | (character->capEnemyLayer << 8); + return gfx; +} \ No newline at end of file diff --git a/src/game/mario_misc.h b/src/game/mario_misc.h index fe36f29c..533665b6 100644 --- a/src/game/mario_misc.h +++ b/src/game/mario_misc.h @@ -32,6 +32,6 @@ Gfx *geo_switch_mario_hand_grab_pos(s32 callContext, struct GraphNode *b, Mat4 * Gfx *geo_render_mirror_mario(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c); Gfx *geo_mirror_mario_backface_culling(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c); Gfx* geo_mario_set_player_colors(s32 callContext, struct GraphNode* node, UNUSED Mat4* c); -Gfx* geo_klepto_set_player_colors(s32 callContext, struct GraphNode* node, UNUSED Mat4* c); +Gfx* geo_mario_cap_display_list(s32 callContext, struct GraphNode* node, UNUSED Mat4* c); #endif // MARIO_MISC_H