mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-21 19:45:10 +00:00
Fixed ~240 possible crashes
This commit is contained in:
parent
f06a422ff9
commit
1ee3fd1d13
100 changed files with 620 additions and 331 deletions
|
@ -11543,13 +11543,13 @@ MAX_LOCAL_VERSION_LENGTH = 36
|
|||
MAX_VERSION_LENGTH = 32
|
||||
|
||||
--- @type integer
|
||||
MINOR_VERSION_NUMBER = 1
|
||||
MINOR_VERSION_NUMBER = 0
|
||||
|
||||
--- @type integer
|
||||
PATCH_VERSION_NUMBER = 0
|
||||
|
||||
--- @type integer
|
||||
VERSION_NUMBER = 34
|
||||
VERSION_NUMBER = 35
|
||||
|
||||
--- @type string
|
||||
VERSION_REGION = "JP"
|
||||
|
|
|
@ -7187,6 +7187,12 @@ function get_object_list_from_behavior(behavior)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param trajectory Pointer_Trajectory
|
||||
--- @return integer
|
||||
function get_trajectory_length(trajectory)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param value number
|
||||
--- @param center number
|
||||
--- @param zeroThreshold number
|
||||
|
@ -9000,8 +9006,9 @@ function cur_obj_play_sound_2(soundMagic)
|
|||
end
|
||||
|
||||
--- @param soundStates SoundState
|
||||
--- @param maxSoundStates integer
|
||||
--- @return nil
|
||||
function exec_anim_sound_state(soundStates)
|
||||
function exec_anim_sound_state(soundStates, maxSoundStates)
|
||||
-- ...
|
||||
end
|
||||
|
||||
|
@ -9076,5 +9083,5 @@ end
|
|||
--- @class Pointer_number
|
||||
--- @class Pointer_Vec4s
|
||||
--- @class Pointer_Mtx
|
||||
--- @class Pointer_Collision
|
||||
--- @class Pointer_Trajectory
|
||||
--- @class Pointer_Collision
|
||||
|
|
|
@ -908,10 +908,12 @@ s16 *DynOS_Level_GetWarp(s32 aLevel, s32 aArea, u8 aWarpId) {
|
|||
}
|
||||
|
||||
DynOS_Level_Init();
|
||||
for (const auto &_Warp : sDynosLevelWarps[aLevel]) {
|
||||
if (_Warp.mArea == aArea) {
|
||||
if (_Warp.mId == aWarpId) {
|
||||
return (s16 *) &_Warp;
|
||||
if (aLevel < LEVEL_COUNT) {
|
||||
for (const auto &_Warp : sDynosLevelWarps[aLevel]) {
|
||||
if (_Warp.mArea == aArea) {
|
||||
if (_Warp.mId == aWarpId) {
|
||||
return (s16 *) &_Warp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4650,6 +4650,26 @@
|
|||
|
||||
<br />
|
||||
|
||||
## [get_trajectory_length](#get_trajectory_length)
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = get_trajectory_length(trajectory)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| trajectory | `Pointer` <`Trajectory`> |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`s32 get_trajectory_length(Trajectory* trajectory);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [increment_velocity_toward_range](#increment_velocity_toward_range)
|
||||
|
||||
### Lua Example
|
||||
|
|
|
@ -2569,18 +2569,19 @@
|
|||
## [exec_anim_sound_state](#exec_anim_sound_state)
|
||||
|
||||
### Lua Example
|
||||
`exec_anim_sound_state(soundStates)`
|
||||
`exec_anim_sound_state(soundStates, maxSoundStates)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| soundStates | [SoundState](structs.md#SoundState) |
|
||||
| maxSoundStates | `integer` |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void exec_anim_sound_state(struct SoundState *soundStates);`
|
||||
`void exec_anim_sound_state(struct SoundState *soundStates, u16 maxSoundStates);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
|
@ -1348,6 +1348,7 @@
|
|||
- [find_unimportant_object](functions-4.md#find_unimportant_object)
|
||||
- [geo_offset_klepto_debug](functions-4.md#geo_offset_klepto_debug)
|
||||
- [get_object_list_from_behavior](functions-4.md#get_object_list_from_behavior)
|
||||
- [get_trajectory_length](functions-4.md#get_trajectory_length)
|
||||
- [increment_velocity_toward_range](functions-4.md#increment_velocity_toward_range)
|
||||
- [is_item_in_array](functions-4.md#is_item_in_array)
|
||||
- [is_mario_moving_fast_or_in_air](functions-4.md#is_mario_moving_fast_or_in_air)
|
||||
|
|
|
@ -130,6 +130,7 @@ void obj_update_gfx_pos_and_angle(struct Object *obj) {
|
|||
static void cur_obj_bhv_stack_push(uintptr_t bhvAddr) {
|
||||
gCurrentObject->bhvStack[gCurrentObject->bhvStackIndex] = bhvAddr;
|
||||
gCurrentObject->bhvStackIndex++;
|
||||
if (gCurrentObject->bhvStackIndex >= 8) { gCurrentObject->bhvStackIndex = 8 - 1; }
|
||||
}
|
||||
|
||||
// Retrieve the last behavior command address from the object's behavior stack.
|
||||
|
@ -137,6 +138,7 @@ static uintptr_t cur_obj_bhv_stack_pop(void) {
|
|||
uintptr_t bhvAddr;
|
||||
|
||||
gCurrentObject->bhvStackIndex--;
|
||||
if (gCurrentObject->bhvStackIndex >= 8) { gCurrentObject->bhvStackIndex = 0; }
|
||||
bhvAddr = gCurrentObject->bhvStack[gCurrentObject->bhvStackIndex];
|
||||
|
||||
return bhvAddr;
|
||||
|
@ -858,7 +860,9 @@ static s32 bhv_cmd_parent_bit_clear(void) {
|
|||
s32 value = BHV_CMD_GET_U32(1);
|
||||
|
||||
value = value ^ 0xFFFFFFFF;
|
||||
obj_and_int(gCurrentObject->parentObj, field, value);
|
||||
if (gCurrentObject->parentObj) {
|
||||
obj_and_int(gCurrentObject->parentObj, field, value);
|
||||
}
|
||||
|
||||
gCurBhvCommand += 2;
|
||||
return BHV_PROC_CONTINUE;
|
||||
|
@ -1337,6 +1341,7 @@ cur_obj_update_begin:;
|
|||
|
||||
if (!skipBehavior) {
|
||||
do {
|
||||
if (!gCurBhvCommand) { break; }
|
||||
bhvCmdProc = BehaviorCmdTable[*gCurBhvCommand >> 24];
|
||||
bhvProcResult = bhvCmdProc();
|
||||
} while (bhvProcResult == BHV_PROC_CONTINUE);
|
||||
|
|
|
@ -488,7 +488,7 @@ struct GraphNodeBackground *init_graph_node_background(struct AllocOnlyPool *poo
|
|||
if (graphNode != NULL) {
|
||||
init_scene_graph_node_links(&graphNode->fnNode.node, GRAPH_NODE_TYPE_BACKGROUND);
|
||||
|
||||
if (background > BACKGROUND_CUSTOM) {
|
||||
if (backgroundFunc && background > BACKGROUND_CUSTOM) {
|
||||
LOG_ERROR("invalid background id");
|
||||
background = BACKGROUND_OCEAN_SKY;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ static s32 sRegister;
|
|||
static struct LevelCommand *sCurrentCmd;
|
||||
|
||||
static u8 sLevelOwnedGraphNodes[MAX_LOADED_GRAPH_NODES] = { 0 };
|
||||
static u8 sFinishedLoadingPerm = false;
|
||||
|
||||
static s32 eval_script_area(s32 arg) {
|
||||
return (sWarpDest.areaIdx == arg);
|
||||
|
@ -389,6 +390,7 @@ static void level_cmd_alloc_level_pool(void) {
|
|||
// reset level graph node ownership
|
||||
for (s32 i = 0; i < MAX_LOADED_GRAPH_NODES; i++) {
|
||||
if (sLevelOwnedGraphNodes[i]) {
|
||||
gLoadedGraphNodes[i] = NULL;
|
||||
sLevelOwnedGraphNodes[i] = false;
|
||||
}
|
||||
}
|
||||
|
@ -455,7 +457,7 @@ static void level_cmd_load_model_from_dl(void) {
|
|||
|
||||
if (val1 < MAX_LOADED_GRAPH_NODES) {
|
||||
gLoadedGraphNodes[val1] = (struct GraphNode *) init_graph_node_display_list(sLevelPool, 0, val2, val3);
|
||||
sLevelOwnedGraphNodes[val1] = true;
|
||||
if (sFinishedLoadingPerm) { sLevelOwnedGraphNodes[val1] = true; }
|
||||
smlua_model_util_remember(val1, val2, val3, 1);
|
||||
}
|
||||
|
||||
|
@ -468,8 +470,11 @@ static void level_cmd_load_model_from_geo(void) {
|
|||
|
||||
if (arg0 < MAX_LOADED_GRAPH_NODES) {
|
||||
gLoadedGraphNodes[arg0] = process_geo_layout(sLevelPool, arg1);
|
||||
sLevelOwnedGraphNodes[arg0] = true;
|
||||
if (sFinishedLoadingPerm) { sLevelOwnedGraphNodes[arg0] = true; }
|
||||
smlua_model_util_remember(arg0, LAYER_OPAQUE, arg1, 0);
|
||||
if (arg0 == MODEL_ERROR_MODEL) {
|
||||
sFinishedLoadingPerm = true;
|
||||
}
|
||||
}
|
||||
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
|
@ -491,7 +496,7 @@ static void level_cmd_23(void) {
|
|||
// GraphNodeScale has a GraphNode at the top. This
|
||||
// is being stored to the array, so cast the pointer.
|
||||
gLoadedGraphNodes[model] = (struct GraphNode *) init_graph_node_scale(sLevelPool, 0, arg0H, arg1, arg2.f);
|
||||
sLevelOwnedGraphNodes[model] = true;
|
||||
if (sFinishedLoadingPerm) { sLevelOwnedGraphNodes[model] = true; }
|
||||
smlua_model_util_remember(model, arg0H, arg1, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef BEHAVIOR_ACTIONS_H
|
||||
#define BEHAVIOR_ACTIONS_H
|
||||
|
||||
#define BHV_ARR_CHECK(_arr, _idx, _arritem) (((size_t)_idx) < (sizeof(_arr) / sizeof(_arritem)))
|
||||
#define BHV_ARR(_arr, _idx, _arritem) (BHV_ARR_CHECK(_arr, _idx, _arritem) ? _arr[_idx] : 0)
|
||||
|
||||
void spawn_mist_particles_variable(s32 count, s32 offsetY, f32 size);
|
||||
void bhv_spawn_star_no_level_exit(struct Object* object, u32 params, u8 networkSendEvent);
|
||||
void bhv_star_door_loop_2(void);
|
||||
|
|
|
@ -35,7 +35,9 @@ void bhv_alpha_boo_key_loop(void) {
|
|||
// Another theory is that the boo key was intended to be spawned by a
|
||||
// spawner that used object field 0x00 for something else. This
|
||||
// is elaborated on more in beta_boo_key_dropped_loop.
|
||||
o->parentObj->oBooDeathStatus = BOO_DEATH_STATUS_DYING;
|
||||
if (o->parentObj) {
|
||||
o->parentObj->oBooDeathStatus = BOO_DEATH_STATUS_DYING;
|
||||
}
|
||||
|
||||
// Delete the object and spawn sparkles
|
||||
obj_mark_for_deletion(o);
|
||||
|
@ -94,7 +96,7 @@ static void beta_boo_key_dropped_loop(void) {
|
|||
// One theory about this code is that there was a boo spawner, which
|
||||
// spawned "false" boos and one "true" boo with the key, and the player
|
||||
// was intended to find the one with the key to progress.
|
||||
o->parentObj->oInteractStatus = INT_STATUS_HOOT_GRABBED_BY_MARIO;
|
||||
if (o->parentObj) { o->parentObj->oInteractStatus = INT_STATUS_HOOT_GRABBED_BY_MARIO; }
|
||||
|
||||
// Delete the object and spawn sparkles
|
||||
obj_mark_for_deletion(o);
|
||||
|
@ -120,7 +122,9 @@ static void beta_boo_key_drop(void) {
|
|||
// which stops this function from running again.
|
||||
if (o->oTimer == 0) {
|
||||
// Separate from the parent boo
|
||||
o->parentObj = parent->parentObj;
|
||||
if (parent) {
|
||||
o->parentObj = parent->parentObj;
|
||||
}
|
||||
|
||||
o->oAction = BETA_BOO_KEY_ACT_DROPPED;
|
||||
|
||||
|
@ -154,7 +158,7 @@ static void beta_boo_key_inside_boo_loop(void) {
|
|||
o->oPosY += 40.0f;
|
||||
|
||||
// If the boo is dying/dead, set the action to BETA_BOO_KEY_ACT_DROPPING.
|
||||
if (parent->oBooDeathStatus != BOO_DEATH_STATUS_ALIVE) {
|
||||
if (parent && parent->oBooDeathStatus != BOO_DEATH_STATUS_ALIVE) {
|
||||
o->oAction = BETA_BOO_KEY_ACT_DROPPING;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ static void bird_act_fly(void) {
|
|||
// A spawned bird's parent is its spawner bird. A spawner bird's parent
|
||||
// is itself. In other words, when a group of birds has its spawner bird
|
||||
// fly past Y=8000, they will all despawn simultaneously. Otherwise, fly.
|
||||
if (o->parentObj->oPosY > 8000.0f) {
|
||||
if (!o->parentObj || o->parentObj->oPosY > 8000.0f) {
|
||||
obj_mark_for_deletion(o);
|
||||
} else {
|
||||
// If the bird is a spawner bird, fly towards its home; otherwise,
|
||||
|
|
|
@ -28,7 +28,7 @@ void bhv_hidden_blue_coin_loop(void) {
|
|||
// Wait until the blue coin switch starts ticking to activate.
|
||||
blueCoinSwitch = o->oHiddenBlueCoinSwitch;
|
||||
|
||||
if (blueCoinSwitch->oAction == BLUE_COIN_SWITCH_ACT_TICKING) {
|
||||
if (blueCoinSwitch && blueCoinSwitch->oAction == BLUE_COIN_SWITCH_ACT_TICKING) {
|
||||
o->oAction++; // Set to HIDDEN_BLUE_COIN_ACT_ACTIVE
|
||||
}
|
||||
|
||||
|
@ -107,8 +107,10 @@ void bhv_blue_coin_number_loop(void) {
|
|||
*/
|
||||
void bhv_blue_coin_switch_init(void) {
|
||||
struct Object *blueCoinNumber = spawn_object(o, MODEL_NUMBER, bhvBlueCoinNumber);
|
||||
blueCoinNumber->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; // to make sure it's updated even during time stop
|
||||
blueCoinNumber->oHiddenBlueCoinSwitch = o;
|
||||
if (blueCoinNumber) {
|
||||
blueCoinNumber->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; // to make sure it's updated even during time stop
|
||||
blueCoinNumber->oHiddenBlueCoinSwitch = o;
|
||||
}
|
||||
o->oHomeY = o->oPosY;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ void bhv_blue_fish_movement_loop(void) {
|
|||
cur_obj_move_using_fvel_and_gravity();
|
||||
|
||||
// Deletes object if the parent has oAction set to BLUE_FISH_ACT_DUPLICATE.
|
||||
if (o->parentObj->oAction == BLUE_FISH_ACT_DUPLICATE) {
|
||||
if (!o->parentObj || o->parentObj->oAction == BLUE_FISH_ACT_DUPLICATE) {
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -266,7 +266,7 @@ void bhv_bob_pit_bowling_ball_loop(void) {
|
|||
UNUSED s16 collisionFlags = object_step();
|
||||
|
||||
find_floor_height_and_data(o->oPosX, o->oPosY, o->oPosZ, &sp1c);
|
||||
if ((sp1c->normalX == 0) && (sp1c->normalZ == 0))
|
||||
if (sp1c && (sp1c->normalX == 0) && (sp1c->normalZ == 0))
|
||||
o->oForwardVel = 28.0f;
|
||||
|
||||
bowling_ball_set_hitbox();
|
||||
|
|
|
@ -48,6 +48,7 @@ s16 D_8032F520[][3] = { { 1, 10, 40 }, { 0, 0, 74 }, { -1, -10, 114 }, { 1
|
|||
{ -1, 80, 184 }, { 1, 160, 186 }, { -1, -160, 186 }, { 1, 0, 0 }, };
|
||||
|
||||
void bhv_bowser_tail_anchor_init(void) {
|
||||
if (!o->parentObj) { mark_obj_for_deletion(o); return; }
|
||||
sync_object_init_field(o->parentObj, &o->oAction);
|
||||
sync_object_init_field(o->parentObj, &o->oPrevAction);
|
||||
sync_object_init_field(o->parentObj, &o->oTimer);
|
||||
|
@ -59,6 +60,7 @@ void bhv_bowser_tail_anchor_init(void) {
|
|||
}
|
||||
|
||||
void bhv_bowser_tail_anchor_loop(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBowserTailAnchorActions);
|
||||
o->oParentRelativePosX = 90.0f;
|
||||
if (o->parentObj->oAction == 4)
|
||||
|
@ -71,6 +73,7 @@ void bhv_bowser_flame_spawn_loop(void) {
|
|||
sync_object_init(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
}
|
||||
struct Object *bowser = o->parentObj;
|
||||
if (!bowser) { return; }
|
||||
s32 sp30;
|
||||
f32 sp2C;
|
||||
f32 sp28;
|
||||
|
@ -79,8 +82,9 @@ void bhv_bowser_flame_spawn_loop(void) {
|
|||
s16 *sp1C = segmented_to_virtual(bowser_seg6_unkmoveshorts_060576FC);
|
||||
if (bowser->oSoundStateID == 6) {
|
||||
sp30 = bowser->header.gfx.animInfo.animFrame + 1.0f;
|
||||
if (bowser->header.gfx.animInfo.curAnim->loopEnd == sp30)
|
||||
if (bowser->header.gfx.animInfo.curAnim && bowser->header.gfx.animInfo.curAnim->loopEnd == sp30) {
|
||||
sp30 = 0;
|
||||
}
|
||||
if (sp30 > 45 && sp30 < 85) {
|
||||
cur_obj_play_sound_1(SOUND_AIR_BOWSER_SPIT_FIRE);
|
||||
sp2C = sp1C[5 * sp30];
|
||||
|
@ -106,6 +110,7 @@ void bhv_bowser_flame_spawn_loop(void) {
|
|||
}
|
||||
|
||||
void bhv_bowser_body_anchor_init(void) {
|
||||
if (!o->parentObj) { mark_obj_for_deletion(o); return; }
|
||||
sync_object_init_field(o->parentObj, &o->oInteractType);
|
||||
sync_object_init_field(o->parentObj, &o->oInteractStatus);
|
||||
sync_object_init_field(o->parentObj, &o->oIntangibleTimer);
|
||||
|
@ -113,6 +118,7 @@ void bhv_bowser_body_anchor_init(void) {
|
|||
}
|
||||
|
||||
void bhv_bowser_body_anchor_loop(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
obj_copy_pos_and_angle(o, o->parentObj);
|
||||
if (o->parentObj->oAction == 4) {
|
||||
#ifndef VERSION_JP
|
||||
|
@ -1213,7 +1219,7 @@ void bowser_free_update(void) {
|
|||
o->platform = floor->object;
|
||||
else
|
||||
o->platform = NULL;
|
||||
exec_anim_sound_state(D_8032F5B8);
|
||||
exec_anim_sound_state(D_8032F5B8, sizeof(D_8032F5B8) / sizeof(struct SoundState));
|
||||
}
|
||||
|
||||
void bowser_held_update(void) {
|
||||
|
@ -1262,9 +1268,11 @@ void bowser_thrown_dropped_update(void) {
|
|||
o->oForwardVel = coss(o->oBowserHeldAnglePitch) * sp1C;
|
||||
o->oVelY = -sins(o->oBowserHeldAnglePitch) * sp1C;
|
||||
cur_obj_become_intangible();
|
||||
o->prevObj->oAction = 1; // not sure what prevObj is
|
||||
o->prevObj->oTimer = 0;
|
||||
o->prevObj->oSubAction = 0;
|
||||
if (o->prevObj) {
|
||||
o->prevObj->oAction = 1; // not sure what prevObj is
|
||||
o->prevObj->oTimer = 0;
|
||||
o->prevObj->oSubAction = 0;
|
||||
}
|
||||
o->oTimer = 0;
|
||||
o->oSubAction = 0;
|
||||
|
||||
|
@ -1549,7 +1557,9 @@ Gfx *geo_bits_bowser_coloring(s32 run, struct GraphNode *node, UNUSED s32 a2) {
|
|||
|
||||
void falling_bowser_plat_act_0(void) {
|
||||
o->oPlatformUnkF8 = cur_obj_nearest_object_with_behavior(bhvBowser);
|
||||
obj_set_collision_data(o, D_8032F698[o->oBehParams2ndByte].unk0);
|
||||
if (BHV_ARR_CHECK(D_8032F698, o->oBehParams2ndByte, struct Struct8032F698)) {
|
||||
obj_set_collision_data(o, D_8032F698[o->oBehParams2ndByte].unk0);
|
||||
}
|
||||
if (o->oPlatformUnkF8 != 0)
|
||||
o->oAction = 1;
|
||||
}
|
||||
|
@ -1558,13 +1568,13 @@ void falling_bowser_plat_act_1(void) {
|
|||
u8 doSend = FALSE;
|
||||
UNUSED s32 unused;
|
||||
struct Object *sp0 = o->oPlatformUnkF8;
|
||||
if (sp0->platform == o) {
|
||||
if (sp0 && sp0->platform == o) {
|
||||
if (sp0->oAction == 13 && sp0->oBowserUnkF4 & 0x10000) {
|
||||
o->oAction = 2;
|
||||
doSend = TRUE;
|
||||
}
|
||||
}
|
||||
if (sp0->oHealth == 1 && (sp0->oAction == 3 || sp0->oHeldState != HELD_FREE))
|
||||
if (sp0 && sp0->oHealth == 1 && (sp0->oAction == 3 || sp0->oHeldState != HELD_FREE))
|
||||
o->oSubAction = 1;
|
||||
if (o->oSubAction == 0)
|
||||
o->oPlatformUnkFC = 0;
|
||||
|
@ -1594,7 +1604,7 @@ void falling_bowser_plat_act_2(void) {
|
|||
o->oGravity = 0.0f;
|
||||
} else
|
||||
o->oGravity = -4.0f;
|
||||
if ((o->oTimer & 1) == 0 && o->oTimer < 14) {
|
||||
if ((o->oTimer & 1) == 0 && o->oTimer < 14 && BHV_ARR_CHECK(D_8032F698, o->oBehParams2ndByte, struct Struct8032F698)) {
|
||||
sp22 = D_8032F698[o->oBehParams2ndByte].unk3 + (gDebugInfo[4][1] << 8);
|
||||
sp1C = -(o->oTimer / 2) * 290 + 1740;
|
||||
vec3f_copy_2(sp24, &o->oPosX);
|
||||
|
@ -1779,10 +1789,16 @@ void bhv_flame_floating_landing_loop(void) {
|
|||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_move_standard(0x4e);
|
||||
bowser_flame_move();
|
||||
if (bowser_flame_should_despawn(900))
|
||||
if (bowser_flame_should_despawn(900)) {
|
||||
obj_mark_for_deletion(o);
|
||||
if (o->oVelY < D_8032F748[o->oBehParams2ndByte])
|
||||
o->oVelY = D_8032F748[o->oBehParams2ndByte];
|
||||
}
|
||||
|
||||
if (BHV_ARR_CHECK(D_8032F748, o->oBehParams2ndByte, f32)) {
|
||||
if (o->oVelY < D_8032F748[o->oBehParams2ndByte]) {
|
||||
o->oVelY = D_8032F748[o->oBehParams2ndByte];
|
||||
}
|
||||
}
|
||||
|
||||
if (o->oMoveFlags & OBJ_MOVE_LANDED) {
|
||||
if (o->oBehParams2ndByte == 0)
|
||||
spawn_object(o, MODEL_RED_FLAME, bhvFlameLargeBurningOut);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
void bub_spawner_act_0(void) {
|
||||
s32 i;
|
||||
s32 sp18 = o->oBirdChirpChirpUnkF4;
|
||||
if (sp18 > 20) { sp18 = 20; }
|
||||
for (i = 0; i < sp18; i++)
|
||||
spawn_object(o, MODEL_BUB, bhvBub);
|
||||
o->oAction = 1;
|
||||
|
@ -138,6 +139,6 @@ void bhv_bub_loop(void) {
|
|||
cur_obj_update_floor_and_walls();
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sCheepCheepActions);
|
||||
cur_obj_move_using_fvel_and_gravity();
|
||||
if (o->parentObj->oAction == 2)
|
||||
if (!o->parentObj || o->parentObj->oAction == 2)
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
|
|
|
@ -53,9 +53,9 @@ void opened_cannon_act_4(void) {
|
|||
o->oPosZ += (f32)((o->oTimer / 2 & 1) - 0.5) * 4;
|
||||
o->oAction = 6;
|
||||
}
|
||||
if (o->oCannonPlayerIndex != 0) {
|
||||
if (o->oCannonPlayerIndex != 0 && o->oCannonPlayerIndex < MAX_PLAYERS) {
|
||||
struct MarioState* controlledBy = &gMarioStates[o->oCannonPlayerIndex];
|
||||
if (controlledBy->marioObj != NULL) {
|
||||
if (controlledBy && controlledBy->marioObj != NULL) {
|
||||
controlledBy->marioObj->oMarioCannonObjectYaw = o->oMoveAngleYaw;
|
||||
controlledBy->marioObj->oMarioCannonInputYaw = 0;
|
||||
}
|
||||
|
@ -75,9 +75,9 @@ void opened_cannon_act_6(void) {
|
|||
o->oMoveAngleYaw = sins(o->oCannonUnkF4) * 0x4000 + ((s16)(o->oBehParams2ndByte << 8));
|
||||
o->oCannonUnkF4 += 0x400;
|
||||
} else if (o->oTimer < 26) {
|
||||
} else {
|
||||
} else if (o->oCannonPlayerIndex < MAX_PLAYERS) {
|
||||
struct MarioState* controlledBy = &gMarioStates[o->oCannonPlayerIndex];
|
||||
if (controlledBy->marioObj != NULL) {
|
||||
if (controlledBy && controlledBy->marioObj != NULL) {
|
||||
controlledBy->marioObj->oMarioCannonObjectYaw = o->oMoveAngleYaw;
|
||||
controlledBy->marioObj->oMarioCannonInputYaw = 0;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ void opened_cannon_act_1(void) {
|
|||
if (o->oCannonPlayerIndex == 0) {
|
||||
cur_obj_become_intangible();
|
||||
cur_obj_disable_rendering();
|
||||
} else {
|
||||
} else if (o->oCannonPlayerIndex < MAX_PLAYERS) {
|
||||
struct MarioState* controlledBy = &gMarioStates[o->oCannonPlayerIndex];
|
||||
o->oMoveAnglePitch = 14563 + controlledBy->faceAngle[0] * -0.5f;
|
||||
if (controlledBy->marioObj != NULL) {
|
||||
|
@ -245,7 +245,7 @@ void bhv_cannon_base_loop(void) {
|
|||
|
||||
void bhv_cannon_barrel_loop(void) {
|
||||
struct Object *parent = o->parentObj;
|
||||
if (parent->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) {
|
||||
if (parent && parent->header.gfx.node.flags & GRAPH_RENDER_ACTIVE) {
|
||||
cur_obj_enable_rendering();
|
||||
obj_copy_pos(o, o->parentObj);
|
||||
o->oMoveAngleYaw = o->parentObj->oMoveAngleYaw;
|
||||
|
|
|
@ -8,7 +8,7 @@ void cap_switch_act_0(void) {
|
|||
o->oPosY += 71.0f;
|
||||
spawn_object_relative_with_scale(0, 0, -71, 0, 0.5f, o, MODEL_CAP_SWITCH_BASE, bhvCapSwitchBase);
|
||||
if (gCurrLevelNum != LEVEL_UNKNOWN_32) {
|
||||
if (save_file_get_flags() & D_8032F0C0[o->oBehParams2ndByte]) {
|
||||
if (save_file_get_flags() & BHV_ARR(D_8032F0C0, o->oBehParams2ndByte, s32)) {
|
||||
o->oAction = 3;
|
||||
o->header.gfx.scale[1] = 0.1f;
|
||||
} else
|
||||
|
@ -19,7 +19,7 @@ void cap_switch_act_0(void) {
|
|||
|
||||
void cap_switch_act_1(void) {
|
||||
if (capSwitchForcePress || cur_obj_is_mario_on_platform()) {
|
||||
save_file_set_flags(D_8032F0C0[o->oBehParams2ndByte]);
|
||||
save_file_set_flags(BHV_ARR(D_8032F0C0, o->oBehParams2ndByte, s32));
|
||||
o->oAction = 2;
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_ACTIVATE_CAP_SWITCH);
|
||||
if (!capSwitchForcePress) {
|
||||
|
|
|
@ -6,9 +6,12 @@ void bhv_floor_trap_in_castle_loop(void) {
|
|||
if (!is_player_active(&gMarioStates[i])) { continue; }
|
||||
onPlatform = onPlatform || (gMarioStates[i].marioObj->platform == o);
|
||||
}
|
||||
if (onPlatform)
|
||||
o->parentObj->oInteractStatus |= INT_STATUS_TRAP_TURN;
|
||||
o->oFaceAngleRoll = o->parentObj->oFaceAngleRoll;
|
||||
if (o->parentObj) {
|
||||
if (onPlatform) {
|
||||
o->parentObj->oInteractStatus |= INT_STATUS_TRAP_TURN;
|
||||
}
|
||||
o->oFaceAngleRoll = o->parentObj->oFaceAngleRoll;
|
||||
}
|
||||
}
|
||||
|
||||
void bhv_castle_floor_trap_init(void) {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// celebration_star.c.inc
|
||||
|
||||
void bhv_celebration_star_init(void) {
|
||||
o->oHomeX = o->parentObj->header.gfx.pos[0];
|
||||
o->oPosY = o->parentObj->header.gfx.pos[1] + 30.0f;
|
||||
o->oHomeZ = o->parentObj->header.gfx.pos[2];
|
||||
o->oMoveAngleYaw = o->parentObj->header.gfx.angle[1] + 0x8000;
|
||||
if (o->parentObj) {
|
||||
o->oHomeX = o->parentObj->header.gfx.pos[0];
|
||||
o->oPosY = o->parentObj->header.gfx.pos[1] + 30.0f;
|
||||
o->oHomeZ = o->parentObj->header.gfx.pos[2];
|
||||
o->oMoveAngleYaw = o->parentObj->header.gfx.angle[1] + 0x8000;
|
||||
}
|
||||
o->oCelebStarDiameterOfRotation = 100;
|
||||
#if BUGFIX_STAR_BOWSER_KEY
|
||||
if (gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2) {
|
||||
|
@ -57,7 +59,7 @@ void celeb_star_act_face_camera(void) {
|
|||
cur_obj_scale((f32) o->oTimer / 10.0);
|
||||
#endif
|
||||
o->oFaceAngleYaw += 0x1000;
|
||||
} else {
|
||||
} else if (o->parentObj) {
|
||||
o->oFaceAngleYaw = o->parentObj->header.gfx.angle[1];
|
||||
}
|
||||
|
||||
|
|
|
@ -38,13 +38,17 @@ void bhv_chain_chomp_chain_part_update(void) {
|
|||
obj_mark_for_deletion(o);
|
||||
network_send_object(o);
|
||||
} else if (o->oBehParams2ndByte != CHAIN_CHOMP_CHAIN_PART_BP_PIVOT) {
|
||||
struct ChainSegment *segment = &o->parentObj->oChainChompSegments[o->oBehParams2ndByte];
|
||||
struct ChainSegment *segment = (o->oBehParams2ndByte <= 4 && o->parentObj)
|
||||
? &o->parentObj->oChainChompSegments[o->oBehParams2ndByte]
|
||||
: NULL;
|
||||
|
||||
// Set position relative to the pivot
|
||||
if (segment) {
|
||||
o->oPosX = o->parentObj->parentObj->oPosX + segment->posX;
|
||||
o->oPosY = o->parentObj->parentObj->oPosY + segment->posY;
|
||||
o->oPosZ = o->parentObj->parentObj->oPosZ + segment->posZ;
|
||||
if (segment && o->parentObj && o->parentObj->parentObj) {
|
||||
if (o->parentObj->oChainChompSegments) {
|
||||
o->oPosX = o->parentObj->parentObj->oPosX + segment->posX;
|
||||
o->oPosY = o->parentObj->parentObj->oPosY + segment->posY;
|
||||
o->oPosZ = o->parentObj->parentObj->oPosZ + segment->posZ;
|
||||
}
|
||||
}
|
||||
} else if (o->parentObj->oChainChompReleaseStatus != CHAIN_CHOMP_NOT_RELEASED) {
|
||||
cur_obj_update_floor_and_walls();
|
||||
|
@ -379,6 +383,10 @@ static void chain_chomp_act_move(void) {
|
|||
chain_chomp_act_uninitialized();
|
||||
}
|
||||
|
||||
if (!o->parentObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Segment 0 connects the pivot to the chain chomp itself
|
||||
o->oChainChompSegments[0].posX = o->oPosX - o->parentObj->oPosX;
|
||||
o->oChainChompSegments[0].posY = o->oPosY - o->parentObj->oPosY;
|
||||
|
@ -447,8 +455,10 @@ static void chain_chomp_act_unload_chain(void) {
|
|||
o->oAction = CHAIN_CHOMP_ACT_UNINITIALIZED;
|
||||
|
||||
if (o->oChainChompReleaseStatus != CHAIN_CHOMP_NOT_RELEASED) {
|
||||
for (u8 i = 0; i < 5; i++) {
|
||||
obj_mark_for_deletion((struct Object*)&o->oChainChompSegments[i]);
|
||||
if (o->oChainChompSegments) {
|
||||
for (u8 i = 0; i < 5; i++) {
|
||||
obj_mark_for_deletion((struct Object*)&o->oChainChompSegments[i]);
|
||||
}
|
||||
}
|
||||
obj_mark_for_deletion(o);
|
||||
obj_mark_for_deletion(o->parentObj);
|
||||
|
|
|
@ -57,7 +57,7 @@ static void bhv_checkerboard_platform_run_once(void) {
|
|||
}
|
||||
|
||||
void bhv_checkerboard_platform_init(void) {
|
||||
o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte;
|
||||
o->oCheckerBoardPlatformUnkFC = o->parentObj ? o->parentObj->oBehParams2ndByte : 0;
|
||||
o->areaTimerType = AREA_TIMER_TYPE_LOOP;
|
||||
o->areaTimer = 0;
|
||||
o->areaTimerDuration = 132 + o->oCheckerBoardPlatformUnkFC * 2;
|
||||
|
|
|
@ -115,7 +115,7 @@ static void cloud_act_main(void) {
|
|||
|
||||
localOffsetPhase = 0x800 * gGlobalTimer;
|
||||
|
||||
if (o->parentObj != o) {
|
||||
if (o->parentObj && o->parentObj != o) {
|
||||
// Despawn if the parent lakitu does
|
||||
if (o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
|
||||
o->oAction = CLOUD_ACT_UNLOAD;
|
||||
|
@ -180,7 +180,7 @@ void bhv_cloud_update(void) {
|
|||
* Update function for bhvCloudPart. Follow the parent cloud with some oscillation.
|
||||
*/
|
||||
void bhv_cloud_part_update(void) {
|
||||
if (o->parentObj->oAction == CLOUD_ACT_UNLOAD) {
|
||||
if (!o->parentObj || o->parentObj->oAction == CLOUD_ACT_UNLOAD) {
|
||||
obj_mark_for_deletion(o);
|
||||
} else {
|
||||
f32 size = 2.0f / 3.0f * o->parentObj->header.gfx.scale[0];
|
||||
|
@ -206,8 +206,7 @@ void bhv_cloud_part_update(void) {
|
|||
|
||||
o->oPosX = o->parentObj->oCloudCenterX + cloudRadius * sins(angleFromCenter) + localOffset;
|
||||
|
||||
o->oPosY =
|
||||
o->parentObj->oCloudCenterY + localOffset + size * sCloudPartHeights[o->oBehParams2ndByte];
|
||||
o->oPosY = o->parentObj->oCloudCenterY + localOffset + size * BHV_ARR(sCloudPartHeights, o->oBehParams2ndByte, s8);
|
||||
|
||||
o->oPosZ = o->parentObj->oPosZ + cloudRadius * coss(angleFromCenter) + localOffset;
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ void coffin_act_stand_up(void) {
|
|||
*/
|
||||
void bhv_coffin_loop(void) {
|
||||
// Gotta save those 6 object slots
|
||||
if (o->parentObj->oAction == COFFIN_SPAWNER_ACT_COFFINS_UNLOADED) {
|
||||
if (o->parentObj && o->parentObj->oAction == COFFIN_SPAWNER_ACT_COFFINS_UNLOADED) {
|
||||
obj_mark_for_deletion(o);
|
||||
} else {
|
||||
// Scale the coffin vertically? Must have thought it was too short?
|
||||
|
|
|
@ -133,11 +133,12 @@ void bhv_coin_formation_spawn_loop(void) {
|
|||
cur_obj_set_model(smlua_model_util_load(E_MODEL_YELLOW_COIN_NO_SHADOW));
|
||||
}
|
||||
} else {
|
||||
if (bhv_coin_sparkles_init())
|
||||
if (o->parentObj && bhv_coin_sparkles_init()) {
|
||||
o->parentObj->oCoinUnkF4 |= bit_shift_left(o->oBehParams2ndByte);
|
||||
}
|
||||
o->oAnimState++;
|
||||
}
|
||||
if (o->parentObj->oAction == 2)
|
||||
if (!o->parentObj || o->parentObj->oAction == 2)
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,11 @@ void bhv_controllable_platform_sub_loop(void) {
|
|||
if (gMarioStates[0].marioObj->platform == o) {
|
||||
D_80331694 = o->oBehParams2ndByte;
|
||||
#ifdef VERSION_SH
|
||||
o->parentObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
if (o->parentObj) { o->parentObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; }
|
||||
#endif
|
||||
o->oAction = 1;
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_MOVING_PLATFORM_SWITCH);
|
||||
network_send_object(o->parentObj);
|
||||
if (o->parentObj) { network_send_object(o->parentObj); }
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -48,11 +48,13 @@ void bhv_controllable_platform_sub_loop(void) {
|
|||
break;
|
||||
}
|
||||
|
||||
o->oVelX = o->parentObj->oVelX;
|
||||
o->oVelZ = o->parentObj->oVelZ;
|
||||
if (o->parentObj) {
|
||||
o->oVelX = o->parentObj->oVelX;
|
||||
o->oVelZ = o->parentObj->oVelZ;
|
||||
|
||||
if (o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED)
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
if (o->parentObj->activeFlags == ACTIVE_FLAG_DEACTIVATED)
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
}
|
||||
|
||||
static void bhv_controllable_platform_on_received_post(UNUSED u8 localIndex) {
|
||||
|
@ -279,6 +281,7 @@ void bhv_controllable_platform_loop(void) {
|
|||
D_80331694 = 0;
|
||||
o->oTimer = 0;
|
||||
for (s32 i = 0; i < 4; i++) {
|
||||
if (!controllablePlatformSubs[i]) { continue; }
|
||||
controllablePlatformSubs[i]->oParentRelativePosY = 51.0f;
|
||||
controllablePlatformSubs[i]->oAction = 0;
|
||||
controllablePlatformSubs[i]->oTimer = 0;
|
||||
|
|
|
@ -122,15 +122,15 @@ void elevator_act_3(void) // nearly identical to action 2
|
|||
}
|
||||
|
||||
void bhv_elevator_init(void) {
|
||||
s32 sp1C = D_8032F38C[o->oBehParams2ndByte * 3 + 2];
|
||||
s32 sp1C = BHV_ARR(D_8032F38C, o->oBehParams2ndByte * 3 + 2, s16);
|
||||
if (sp1C == 0) {
|
||||
o->oElevatorUnkF4 = D_8032F38C[o->oBehParams2ndByte * 3];
|
||||
o->oElevatorUnkF4 = BHV_ARR(D_8032F38C, o->oBehParams2ndByte * 3, s16);
|
||||
o->oElevatorUnkF8 = o->oHomeY;
|
||||
o->oElevatorUnkFC = (o->oElevatorUnkF4 + o->oElevatorUnkF8) / 2;
|
||||
o->oElevatorUnk100 = cur_obj_has_behavior(bhvRrElevatorPlatform);
|
||||
} else {
|
||||
o->oElevatorUnkF4 = D_8032F38C[o->oBehParams2ndByte * 3];
|
||||
o->oElevatorUnkF8 = D_8032F38C[o->oBehParams2ndByte * 3 + 1];
|
||||
o->oElevatorUnkF4 = BHV_ARR(D_8032F38C, o->oBehParams2ndByte * 3, s16);
|
||||
o->oElevatorUnkF8 = BHV_ARR(D_8032F38C, o->oBehParams2ndByte * 3 + 1, s16);
|
||||
o->oElevatorUnkFC = (o->oElevatorUnkF4 + o->oElevatorUnkF8) / 2;
|
||||
o->oElevatorUnk100 = 2;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ struct Struct802C0DF0 sExclamationBoxContents[] = { { 0, 0, 0, MODEL_MARIOS_WING
|
|||
{ 99, 0, 0, 0, NULL } };
|
||||
|
||||
void bhv_rotating_exclamation_box_loop(void) {
|
||||
if (o->parentObj->oAction != 1)
|
||||
if (!o->parentObj || o->parentObj->oAction != 1)
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ void exclamation_box_act_0(void) {
|
|||
o->oExclamationBoxForce = FALSE;
|
||||
if (o->oBehParams2ndByte < 3) {
|
||||
o->oAnimState = o->oBehParams2ndByte;
|
||||
if ((save_file_get_flags() & D_8032F0C0[o->oBehParams2ndByte])
|
||||
if ((save_file_get_flags() & BHV_ARR(D_8032F0C0, o->oBehParams2ndByte, s32))
|
||||
|| ((o->oBehParams >> 24) & 0xFF) != 0)
|
||||
o->oAction = 2;
|
||||
else
|
||||
|
@ -56,7 +56,7 @@ void exclamation_box_act_1(void) {
|
|||
spawn_object(o, smlua_model_util_load(E_MODEL_EXCLAMATION_POINT), bhvRotatingExclamationMark);
|
||||
cur_obj_set_model(smlua_model_util_load(E_MODEL_EXCLAMATION_BOX_OUTLINE));
|
||||
}
|
||||
if ((save_file_get_flags() & D_8032F0C0[o->oBehParams2ndByte])
|
||||
if ((save_file_get_flags() & BHV_ARR(D_8032F0C0, o->oBehParams2ndByte, s32))
|
||||
|| ((o->oBehParams >> 24) & 0xFF) != 0) {
|
||||
o->oAction = 2;
|
||||
cur_obj_set_model(smlua_model_util_load(E_MODEL_EXCLAMATION_BOX));
|
||||
|
|
|
@ -208,6 +208,7 @@ static void eyerok_boss_act_die(void) {
|
|||
}
|
||||
|
||||
void bhv_eyerok_boss_loop(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
if (o->oAction == EYEROK_BOSS_ACT_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
@ -232,7 +233,7 @@ void bhv_eyerok_boss_loop(void) {
|
|||
}
|
||||
|
||||
if (o->oAction != oldAction) {
|
||||
if (sync_object_is_owned_locally(o->parentObj->oSyncID)) {
|
||||
if (o->parentObj && sync_object_is_owned_locally(o->parentObj->oSyncID)) {
|
||||
eyerokBossImmediateUpdate = TRUE;
|
||||
} else {
|
||||
o->oAction = EYEROK_BOSS_ACT_PAUSE;
|
||||
|
@ -246,6 +247,7 @@ void bhv_eyerok_boss_loop(void) {
|
|||
}
|
||||
|
||||
static s32 eyerok_hand_check_attacked(void) {
|
||||
if (!o->parentObj) { return FALSE; }
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
|
||||
if (o->oEyerokReceivedAttack != 0 && abs_angle_diff(angleToPlayer, o->oFaceAngleYaw) < 0x3000) {
|
||||
|
@ -279,7 +281,8 @@ static void eyerok_hand_pound_ground(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_sleep(void) {
|
||||
if (o->parentObj->oAction != EYEROK_BOSS_ACT_SLEEP
|
||||
if (!o->parentObj) { return; }
|
||||
if (o->parentObj && o->parentObj->oAction != EYEROK_BOSS_ACT_SLEEP
|
||||
&& ++o->oEyerokHandWakeUpTimer > -3 * o->oBehParams2ndByte) {
|
||||
if (cur_obj_check_if_near_animation_end()) {
|
||||
o->parentObj->oEyerokBossNumHands += 1;
|
||||
|
@ -305,6 +308,7 @@ static void eyerok_hand_act_sleep(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_idle(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
|
||||
cur_obj_init_animation_with_sound(2);
|
||||
|
@ -342,6 +346,7 @@ static void eyerok_hand_act_idle(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_open(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
|
||||
o->parentObj->oEyerokBossUnk1AC = o->oBehParams2ndByte;
|
||||
|
@ -365,6 +370,7 @@ static void eyerok_hand_act_open(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_show_eye(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
|
||||
UNUSED s16 val06;
|
||||
|
@ -373,7 +379,7 @@ static void eyerok_hand_act_show_eye(void) {
|
|||
cur_obj_play_sound_at_anim_range(0, 0, SOUND_OBJ_EYEROK_SHOW_EYE);
|
||||
|
||||
if (!eyerok_hand_check_attacked()) {
|
||||
if (o->parentObj->oEyerokBossActiveHand == 0) {
|
||||
if (o->parentObj && o->parentObj->oEyerokBossActiveHand == 0) {
|
||||
if (o->oAnimState < 3) {
|
||||
o->oAnimState += 1;
|
||||
} else if (cur_obj_check_if_near_animation_end()) {
|
||||
|
@ -385,13 +391,13 @@ static void eyerok_hand_act_show_eye(void) {
|
|||
if (o->oEyerokHandUnkFC != 0) {
|
||||
o->oEyerokHandUnkFC -= 1;
|
||||
}
|
||||
o->oAnimState = D_80331BA4[o->oEyerokHandUnkFC];
|
||||
o->oAnimState = BHV_ARR(D_80331BA4, o->oEyerokHandUnkFC, s8);
|
||||
} else {
|
||||
o->oEyerokHandUnkFC = 5;
|
||||
o->oEyerokHandUnk100 = random_linear_offset(20, 50);
|
||||
}
|
||||
|
||||
if (o->parentObj->oEyerokBossNumHands != 2) {
|
||||
if (o->parentObj && o->parentObj->oEyerokBossNumHands != 2) {
|
||||
obj_face_yaw_approach(o->oMoveAngleYaw, 0x800);
|
||||
if (o->oTimer > 10
|
||||
&& ((player && o->oPosZ - player->oPosZ > 0.0f) || (o->oMoveFlags & OBJ_MOVE_HIT_EDGE))) {
|
||||
|
@ -404,6 +410,7 @@ static void eyerok_hand_act_show_eye(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_close(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
if (cur_obj_init_anim_check_frame(7, 1)) {
|
||||
o->collisionData = segmented_to_virtual(ssl_seg7_collision_07028274);
|
||||
|
||||
|
@ -435,6 +442,7 @@ static void eyerok_hand_act_recover(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_become_active(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
if (o->parentObj->oEyerokBossActiveHand == 0 || o->parentObj->oEyerokBossNumHands != 2) {
|
||||
o->oAction = EYEROK_HAND_ACT_RETREAT;
|
||||
o->parentObj->oEyerokBossActiveHand = o->oBehParams2ndByte;
|
||||
|
@ -454,6 +462,7 @@ static void eyerok_hand_act_die_event(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_die(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
if (cur_obj_init_anim_and_check_if_end(1)) {
|
||||
o->parentObj->oEyerokBossUnk1AC = 0;
|
||||
eyerok_hand_act_die_event();
|
||||
|
@ -490,6 +499,7 @@ static void eyerok_hand_act_retreat(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_target_mario(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
|
||||
if (eyerok_check_mario_relative_z(400) != 0 || (player && o->oPosZ - player->oPosZ > 0.0f)
|
||||
|
@ -553,6 +563,7 @@ static void eyerok_hand_act_fist_push(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_fist_sweep(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
if (o->oPosZ - o->parentObj->oPosZ < 1000.0f || (o->oMoveFlags & OBJ_MOVE_HIT_EDGE)) {
|
||||
o->oAction = EYEROK_HAND_ACT_RETREAT;
|
||||
o->oForwardVel = 0.0f;
|
||||
|
@ -564,6 +575,7 @@ static void eyerok_hand_act_fist_sweep(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_begin_double_pound(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
f32 sp4;
|
||||
|
||||
if (o->parentObj->oEyerokBossUnk104 < 0
|
||||
|
@ -582,6 +594,7 @@ static void eyerok_hand_act_begin_double_pound(void) {
|
|||
}
|
||||
|
||||
static void eyerok_hand_act_double_pound(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
if (o->parentObj->oEyerokBossNumHands != 2) {
|
||||
o->parentObj->oEyerokBossActiveHand = o->oBehParams2ndByte;
|
||||
}
|
||||
|
@ -608,6 +621,7 @@ static void eyerok_hand_act_double_pound(void) {
|
|||
}
|
||||
|
||||
void bhv_eyerok_hand_loop(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
if (o->oAction == EYEROK_HAND_ACT_DEAD) {
|
||||
eyerok_hand_act_die_event();
|
||||
return;
|
||||
|
@ -679,7 +693,7 @@ void bhv_eyerok_hand_loop(void) {
|
|||
o->header.gfx.scale[0] = 1.5f * o->oBehParams2ndByte;
|
||||
|
||||
if (o->oAction != oldAction) {
|
||||
if (sync_object_is_owned_locally(o->parentObj->oSyncID)) {
|
||||
if (o->parentObj && sync_object_is_owned_locally(o->parentObj->oSyncID)) {
|
||||
eyerokBossImmediateUpdate = TRUE;
|
||||
} else {
|
||||
o->oAction = EYEROK_HAND_ACT_PAUSE;
|
||||
|
|
|
@ -129,6 +129,7 @@ void bhv_falling_pillar_loop(void) {
|
|||
* Main loop for the invisible hitboxes.
|
||||
*/
|
||||
void bhv_falling_pillar_hitbox_loop(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
// Get the state of the pillar.
|
||||
s32 pitch = o->parentObj->oFaceAnglePitch;
|
||||
s32 yaw = o->parentObj->oFaceAngleYaw;
|
||||
|
|
|
@ -31,6 +31,10 @@ void bhv_ferris_wheel_axle_init(void) {
|
|||
struct Object *platform;
|
||||
s32 i;
|
||||
|
||||
if (!BHV_ARR_CHECK(sFerrisWheelProperties, o->oBehParams2ndByte, struct FerrisWheelProperties)) {
|
||||
return;
|
||||
}
|
||||
|
||||
o->collisionData = segmented_to_virtual(sFerrisWheelProperties[o->oBehParams2ndByte].axleCollision);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
|
@ -60,6 +64,8 @@ void bhv_ferris_wheel_platform_update(void) {
|
|||
f32 offsetXZ;
|
||||
s16 offsetAngle;
|
||||
|
||||
if (!o->parentObj) { return; }
|
||||
|
||||
obj_perform_position_op(POS_OP_SAVE_POSITION);
|
||||
|
||||
offsetAngle = o->parentObj->oFaceAngleRoll + o->oBehParams2ndByte * 0x4000;
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
* These settings are animations, colour, and spawn quantity.
|
||||
*/
|
||||
static void fish_spawner_act_spawn(void) {
|
||||
s32 i;
|
||||
s32 schoolQuantity;
|
||||
s16 model;
|
||||
const struct Animation * const *fishAnimation;
|
||||
s32 i = 0;
|
||||
s32 schoolQuantity = 0;
|
||||
s16 model = MODEL_ERROR_MODEL;
|
||||
const struct Animation * const *fishAnimation = NULL;
|
||||
struct Object *fishObject;
|
||||
|
||||
switch (o->oBehParams2ndByte) {
|
||||
|
@ -280,7 +280,7 @@ void bhv_fish_loop(void)
|
|||
cur_obj_move_using_fvel_and_gravity();
|
||||
|
||||
// If the parent object has action set to two, then delete the fish object.
|
||||
if (o->parentObj->oAction == FISH_SPAWNER_ACT_RESPAWN) {
|
||||
if (!o->parentObj || o->parentObj->oAction == FISH_SPAWNER_ACT_RESPAWN) {
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ void bhv_flamethrower_flame_loop(void) {
|
|||
o->oVelY = 0;
|
||||
o->oPosY = o->oFloorHeight + 25.0f * size;
|
||||
}
|
||||
sp18 = o->parentObj->oFlameThowerFlameUnk110 / 1.2;
|
||||
sp18 = o->parentObj ? o->parentObj->oFlameThowerFlameUnk110 / 1.2 : 0;
|
||||
} else
|
||||
sp18 = o->parentObj->oFlameThowerFlameUnk110;
|
||||
sp18 = o->parentObj ? o->parentObj->oFlameThowerFlameUnk110 : 0;
|
||||
cur_obj_scale(size);
|
||||
if (o->oBehParams2ndByte == 4)
|
||||
o->oPosY += o->oForwardVel; // weird?
|
||||
|
|
|
@ -336,6 +336,7 @@ void bhv_book_switch_loop(void) {
|
|||
|
||||
o->header.gfx.scale[0] = 2.0f;
|
||||
o->header.gfx.scale[1] = 0.9f;
|
||||
if (!o->parentObj) { return; }
|
||||
|
||||
if (o->parentObj->oAction == 4) {
|
||||
obj_mark_for_deletion(o);
|
||||
|
|
|
@ -138,12 +138,9 @@ static void goomba_begin_jump(void) {
|
|||
* comes back.
|
||||
*/
|
||||
void mark_goomba_as_dead(void) {
|
||||
if (o->parentObj != o) {
|
||||
set_object_respawn_info_bits(o->parentObj,
|
||||
(o->oBehParams2ndByte & GOOMBA_BP_TRIPLET_FLAG_MASK) >> 2);
|
||||
|
||||
o->parentObj->oBehParams =
|
||||
o->parentObj->oBehParams | (o->oBehParams2ndByte & GOOMBA_BP_TRIPLET_FLAG_MASK) << 6;
|
||||
if (o->parentObj && o->parentObj != o) {
|
||||
set_object_respawn_info_bits(o->parentObj, (o->oBehParams2ndByte & GOOMBA_BP_TRIPLET_FLAG_MASK) >> 2);
|
||||
o->parentObj->oBehParams = o->parentObj->oBehParams | (o->oBehParams2ndByte & GOOMBA_BP_TRIPLET_FLAG_MASK) << 6;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,7 +279,7 @@ void bhv_goomba_update(void) {
|
|||
if (obj_update_standard_actions(o->oGoombaScale)) {
|
||||
// If this goomba has a spawner and mario moved away from the spawner,
|
||||
// unload
|
||||
if (o->parentObj != o) {
|
||||
if (o->parentObj && o->parentObj != o) {
|
||||
if (o->parentObj->oAction == GOOMBA_TRIPLET_SPAWNER_ACT_UNLOADED) {
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ struct OpenableGrill gOpenableGrills[] = { { 320, MODEL_BOB_BARS_GRILLS, bob_seg
|
|||
|
||||
void bhv_openable_cage_door_loop(void) {
|
||||
if (gCurrentObject->oAction == 0) {
|
||||
if (gCurrentObject->parentObj->oOpenableGrillUnk88 != 0)
|
||||
if (gCurrentObject->parentObj && gCurrentObject->parentObj->oOpenableGrillUnk88 != 0)
|
||||
gCurrentObject->oAction++;
|
||||
} else if (gCurrentObject->oAction == 1) {
|
||||
if (gCurrentObject->oTimer < 64)
|
||||
|
@ -21,18 +21,20 @@ void bhv_openable_grill_loop(void) {
|
|||
switch (o->oAction) {
|
||||
case 0:
|
||||
grillIdx = o->oBehParams2ndByte;
|
||||
grillObj = spawn_object_relative(-1, gOpenableGrills[grillIdx].halfWidth, 0, 0, o, gOpenableGrills[grillIdx].modelID,
|
||||
bhvOpenableCageDoor);
|
||||
if (grillObj != NULL) {
|
||||
grillObj->oMoveAngleYaw += 0x8000;
|
||||
obj_set_collision_data(grillObj, gOpenableGrills[grillIdx].collision);
|
||||
if (BHV_ARR_CHECK(gOpenableGrills, grillIdx, struct OpenableGrill)) {
|
||||
grillObj = spawn_object_relative(-1, gOpenableGrills[grillIdx].halfWidth, 0, 0, o, gOpenableGrills[grillIdx].modelID,
|
||||
bhvOpenableCageDoor);
|
||||
if (grillObj != NULL) {
|
||||
grillObj->oMoveAngleYaw += 0x8000;
|
||||
obj_set_collision_data(grillObj, gOpenableGrills[grillIdx].collision);
|
||||
}
|
||||
grillObj = spawn_object_relative(1, -gOpenableGrills[grillIdx].halfWidth, 0, 0, o, gOpenableGrills[grillIdx].modelID,
|
||||
bhvOpenableCageDoor);
|
||||
if (grillObj != NULL) {
|
||||
obj_set_collision_data(grillObj, gOpenableGrills[grillIdx].collision);
|
||||
}
|
||||
o->oAction++;
|
||||
}
|
||||
grillObj = spawn_object_relative(1, -gOpenableGrills[grillIdx].halfWidth, 0, 0, o, gOpenableGrills[grillIdx].modelID,
|
||||
bhvOpenableCageDoor);
|
||||
if (grillObj != NULL) {
|
||||
obj_set_collision_data(grillObj, gOpenableGrills[grillIdx].collision);
|
||||
}
|
||||
o->oAction++;
|
||||
break;
|
||||
case 1:
|
||||
if ((o->oOpenableGrillUnkF4 = cur_obj_nearest_object_with_behavior(bhvFloorSwitchGrills))
|
||||
|
@ -41,7 +43,7 @@ void bhv_openable_grill_loop(void) {
|
|||
break;
|
||||
case 2:
|
||||
grillObj = o->oOpenableGrillUnkF4;
|
||||
if (grillObj->oAction == 2) {
|
||||
if (grillObj && grillObj->oAction == 2) {
|
||||
o->oOpenableGrillUnk88 = 2;
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_CAGE_OPEN);
|
||||
o->oAction++;
|
||||
|
|
|
@ -25,7 +25,9 @@ void spawn_smoke_with_velocity(void) {
|
|||
|
||||
// TODO Fix name
|
||||
void clear_particle_flags(u32 flags) {
|
||||
o->parentObj->oActiveParticleFlags &= flags ^ -1; // Clear the flags given (could just be ~flags)
|
||||
if (o->parentObj) {
|
||||
o->parentObj->oActiveParticleFlags &= flags ^ -1; // Clear the flags given (could just be ~flags)
|
||||
}
|
||||
}
|
||||
|
||||
void bhv_ground_snow_init(void) {
|
||||
|
|
|
@ -11,24 +11,26 @@ void bhv_heave_ho_throw_mario_loop(void) {
|
|||
o->oParentRelativePosX = 200.0f;
|
||||
o->oParentRelativePosY = -50.0f;
|
||||
o->oParentRelativePosZ = 0.0f;
|
||||
o->oMoveAngleYaw = o->parentObj->oMoveAngleYaw;
|
||||
switch (o->parentObj->oHeaveHoUnk88) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
cur_obj_play_sound_2(SOUND_OBJ_HEAVEHO_TOSSED);
|
||||
if (player) {
|
||||
player->oInteractStatus |= INT_STATUS_MARIO_UNK2;
|
||||
}
|
||||
if (marioState) {
|
||||
marioState->forwardVel = -45.0f;
|
||||
marioState->vel[1] = 95.0f;
|
||||
}
|
||||
o->parentObj->oHeaveHoUnk88 = 0;
|
||||
o->parentObj->usingObj = NULL;
|
||||
break;
|
||||
if (o->parentObj) {
|
||||
o->oMoveAngleYaw = o->parentObj->oMoveAngleYaw;
|
||||
switch (o->parentObj->oHeaveHoUnk88) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
cur_obj_play_sound_2(SOUND_OBJ_HEAVEHO_TOSSED);
|
||||
if (player) {
|
||||
player->oInteractStatus |= INT_STATUS_MARIO_UNK2;
|
||||
}
|
||||
if (marioState) {
|
||||
marioState->forwardVel = -45.0f;
|
||||
marioState->vel[1] = 95.0f;
|
||||
}
|
||||
o->parentObj->oHeaveHoUnk88 = 0;
|
||||
o->parentObj->usingObj = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -366,7 +366,7 @@ void king_bobomb_move(void) {
|
|||
else
|
||||
cur_obj_move_using_fvel_and_gravity();
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sKingBobombActions);
|
||||
exec_anim_sound_state(sKingBobombSoundStates);
|
||||
exec_anim_sound_state(sKingBobombSoundStates, sizeof(sKingBobombSoundStates) / sizeof(struct SoundState));
|
||||
s32 distanceToPlayer = dist_between_objects(o, gMarioStates[0].marioObj);
|
||||
if (distanceToPlayer < 5000.0f * draw_distance_scalar())
|
||||
cur_obj_enable_rendering();
|
||||
|
|
|
@ -587,7 +587,7 @@ s32 obj_begin_race(s32 noTimer) {
|
|||
level_control_timer(TIMER_CONTROL_SHOW);
|
||||
level_control_timer(TIMER_CONTROL_START);
|
||||
|
||||
o->parentObj->oKoopaRaceEndpointRaceBegun = TRUE;
|
||||
if (o->parentObj) { o->parentObj->oKoopaRaceEndpointRaceBegun = TRUE; }
|
||||
}
|
||||
|
||||
// Unfreeze mario and disable time stop to begin the race
|
||||
|
@ -630,7 +630,7 @@ u8 koopa_the_quick_act_show_init_text_continue_dialog(void) { return o->oAction
|
|||
static void koopa_the_quick_act_show_init_text(void) {
|
||||
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
||||
s32 response = 0;
|
||||
if (marioState && should_start_or_continue_dialog(marioState, o)) {
|
||||
if (marioState && should_start_or_continue_dialog(marioState, o) && BHV_ARR_CHECK(sKoopaTheQuickProperties, o->oKoopaTheQuickRaceIndex, struct KoopaTheQuickProperties)) {
|
||||
response = obj_update_race_proposition_dialog(&gMarioStates[0], *sKoopaTheQuickProperties[o->oKoopaTheQuickRaceIndex].initText, koopa_the_quick_act_show_init_text_continue_dialog);
|
||||
}
|
||||
|
||||
|
@ -738,7 +738,7 @@ static void koopa_the_quick_act_race(void) {
|
|||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000;
|
||||
|
||||
if (o->parentObj->oKoopaRaceEndpointRaceStatus != 0 && distanceToPlayer > 1500.0f
|
||||
if (o->parentObj && o->parentObj->oKoopaRaceEndpointRaceStatus != 0 && distanceToPlayer > 1500.0f
|
||||
&& (o->oPathedPrevWaypointFlags & WAYPOINT_MASK_00FF) < 28) {
|
||||
// Move faster if mario has already finished the race or
|
||||
// cheated by shooting from cannon
|
||||
|
@ -840,6 +840,7 @@ static void koopa_the_quick_act_after_race(void) {
|
|||
cur_obj_init_animation_with_sound(7);
|
||||
|
||||
struct MarioState* marioState = nearest_mario_state_to_object(o);
|
||||
if (!o->parentObj) { return; }
|
||||
|
||||
if (o->parentObj->oKoopaRaceEndpointUnk100 == 0) {
|
||||
if (marioState == &gMarioStates[0] && cur_obj_can_mario_activate_textbox_2(&gMarioStates[0], 400.0f, 400.0f)) {
|
||||
|
@ -913,7 +914,7 @@ static void koopa_the_quick_update(void) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (o->parentObj != o) {
|
||||
if (o->parentObj != o && o->parentObj) {
|
||||
if (dist_between_objects(o, o->parentObj) < 400.0f) {
|
||||
o->parentObj->oKoopaRaceEndpointKoopaFinished = TRUE;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ void bhv_lll_wood_piece_loop(void) {
|
|||
o->oPosY -= 100.0f;
|
||||
o->oPosY += sins(o->oLllWoodPieceOscillationTimer) * 3.0f;
|
||||
o->oLllWoodPieceOscillationTimer += 0x400;
|
||||
if (o->parentObj->oAction == 2)
|
||||
if (o->parentObj && o->parentObj->oAction == 2)
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ s16 *D_8032F8C8[] = { D_8032F860, D_8032F894 };
|
|||
|
||||
|
||||
s32 lll_octagonal_mesh_move(s16 *a0, s32 a1) {
|
||||
if (!BHV_ARR_CHECK(D_8032F860, a1, s16)) { return 0; }
|
||||
switch (a0[a1]) {
|
||||
case 4:
|
||||
o->oMoveAngleYaw = a0[a1 + 2];
|
||||
|
@ -70,9 +71,9 @@ void bhv_lll_moving_octagonal_mesh_platform_loop(void) {
|
|||
if (o->oAction == 0) {
|
||||
o->oHorizontalMovementUnkF8 = 0;
|
||||
o->oAction++;
|
||||
} else
|
||||
o->oHorizontalMovementUnkF8 =
|
||||
lll_octagonal_mesh_move(D_8032F8C8[o->oBehParams2ndByte], o->oHorizontalMovementUnkF8);
|
||||
} else if (BHV_ARR_CHECK(D_8032F8C8, o->oBehParams2ndByte, s16*)) {
|
||||
o->oHorizontalMovementUnkF8 = lll_octagonal_mesh_move(D_8032F8C8[o->oBehParams2ndByte], o->oHorizontalMovementUnkF8);
|
||||
}
|
||||
print_debug_top_down_objectinfo("number %d\n", o->oHorizontalMovementUnkF8);
|
||||
cur_obj_move_using_fvel_and_gravity();
|
||||
if (lll_octagonal_mesh_find_y_offset(&o->oHorizontalMovementUnk104, &o->oHorizontalMovementUnk108, 0x400, -80)) {
|
||||
|
|
|
@ -4,10 +4,15 @@ void bhv_lll_rotating_hex_flame_loop(void) {
|
|||
f32 sp24 = o->oLllRotatingHexFlameUnkF4;
|
||||
f32 sp20 = o->oLllRotatingHexFlameUnkF8;
|
||||
f32 sp1C = o->oLllRotatingHexFlameUnkFC;
|
||||
cur_obj_set_pos_relative(o->parentObj, sp24, sp20, sp1C);
|
||||
o->oPosY = o->parentObj->oPosY + 100.0f;
|
||||
if (o->parentObj->oAction == 3)
|
||||
|
||||
if (o->parentObj) {
|
||||
cur_obj_set_pos_relative(o->parentObj, sp24, sp20, sp1C);
|
||||
o->oPosY = o->parentObj->oPosY + 100.0f;
|
||||
if (o->parentObj->oAction == 3)
|
||||
obj_mark_for_deletion(o);
|
||||
} else {
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
}
|
||||
|
||||
void fire_bar_spawn_flames(s16 a0) {
|
||||
|
|
|
@ -146,12 +146,14 @@ void bhv_mips_act_wait_for_nearby_mario(void) {
|
|||
void bhv_mips_act_follow_path(void) {
|
||||
s16 collisionFlags = 0;
|
||||
s32 followStatus = 0;
|
||||
struct Waypoint ***pathBase;
|
||||
struct Waypoint **pathBase;
|
||||
struct Waypoint *waypoint;
|
||||
|
||||
// Retrieve current waypoint.
|
||||
pathBase = segmented_to_virtual(sMipsPaths);
|
||||
waypoint = segmented_to_virtual(*(*pathBase + o->oMipsStartWaypointIndex));
|
||||
pathBase = segmented_to_virtual(sMipsPaths[0]);
|
||||
s32 length = get_trajectory_length((Trajectory*)pathBase);
|
||||
if (o->oMipsStartWaypointIndex >= length) { return; }
|
||||
waypoint = segmented_to_virtual(pathBase[o->oMipsStartWaypointIndex]);
|
||||
|
||||
// Set start waypoint and follow the path from there.
|
||||
o->oPathedStartWaypoint = waypoint;
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
void bhv_invisible_objects_under_bridge_init(void) {
|
||||
if (save_file_get_flags() & SAVE_FLAG_MOAT_DRAINED) {
|
||||
gEnvironmentRegions[6] = -800;
|
||||
gEnvironmentRegions[12] = -800;
|
||||
if (gEnvironmentRegions) {
|
||||
gEnvironmentRegions[6] = -800;
|
||||
gEnvironmentRegions[12] = -800;
|
||||
}
|
||||
o->oAction = 2;
|
||||
} else {
|
||||
o->oAction = 0;
|
||||
|
@ -18,12 +20,14 @@ void bhv_invisible_objects_under_bridge_loop(void) {
|
|||
break;
|
||||
case 1:
|
||||
// approach -800
|
||||
gEnvironmentRegions[6] = (s16)approach_f32_symmetric(gEnvironmentRegions[6], -800, 5.0f);
|
||||
gEnvironmentRegions[12] = (s16)approach_f32_symmetric(gEnvironmentRegions[12], -800, 5.0f);
|
||||
if (gEnvironmentRegions[6] <= -795 && gEnvironmentRegions[12] <= -795) {
|
||||
gEnvironmentRegions[6] = -800;
|
||||
gEnvironmentRegions[12] = -800;
|
||||
o->oAction = 2;
|
||||
if (gEnvironmentRegions) {
|
||||
gEnvironmentRegions[6] = (s16)approach_f32_symmetric(gEnvironmentRegions[6], -800, 5.0f);
|
||||
gEnvironmentRegions[12] = (s16)approach_f32_symmetric(gEnvironmentRegions[12], -800, 5.0f);
|
||||
if (gEnvironmentRegions[6] <= -795 && gEnvironmentRegions[12] <= -795) {
|
||||
gEnvironmentRegions[6] = -800;
|
||||
gEnvironmentRegions[12] = -800;
|
||||
o->oAction = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
|
|
@ -196,7 +196,9 @@ void bhv_moneybag_loop(void) {
|
|||
o->oOpacity += 12;
|
||||
if (o->oOpacity >= 256) {
|
||||
o->oOpacity = 255;
|
||||
o->parentObj->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
if (o->parentObj) {
|
||||
o->parentObj->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
o->oAction = MONEYBAG_ACT_MOVE_AROUND;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -64,6 +64,7 @@ static struct Object *monty_mole_select_available_hole(f32 minDistToMario) {
|
|||
|
||||
struct Object *hole = sMontyMoleHoleList;
|
||||
s32 numAvailableHoles = 0;
|
||||
s32 sanity = 0;
|
||||
|
||||
while (hole != NULL) {
|
||||
player = nearest_player_to_object(hole);
|
||||
|
@ -74,6 +75,8 @@ static struct Object *monty_mole_select_available_hole(f32 minDistToMario) {
|
|||
}
|
||||
}
|
||||
|
||||
if (sanity++ > 100) { break; }
|
||||
if (hole == hole->parentObj) { break; }
|
||||
hole = hole->parentObj;
|
||||
}
|
||||
|
||||
|
|
|
@ -436,7 +436,7 @@ void bhv_mr_blizzard_update(void) {
|
|||
|
||||
static void mr_blizzard_snowball_act_0(void) {
|
||||
cur_obj_move_using_fvel_and_gravity();
|
||||
if (o->parentObj->prevObj == o) {
|
||||
if (o->parentObj && o->parentObj->prevObj == o) {
|
||||
o->oAction = 1;
|
||||
o->oParentRelativePosX = 190.0f;
|
||||
o->oParentRelativePosY = o->oParentRelativePosZ = -38.0f;
|
||||
|
@ -453,7 +453,7 @@ static void mr_blizzard_snowball_act_1(void) {
|
|||
|
||||
f32 marioDist;
|
||||
|
||||
if (o->parentObj->prevObj == NULL) {
|
||||
if (o->parentObj && o->parentObj->prevObj == NULL) {
|
||||
if (o->parentObj->oAction == MR_BLIZZARD_ACT_THROW_SNOWBALL) {
|
||||
marioDist = distanceToPlayer;
|
||||
if (marioDist > 800.0f) {
|
||||
|
|
|
@ -54,6 +54,10 @@ void spawn_mr_i_particle(void) {
|
|||
}
|
||||
|
||||
void bhv_mr_i_body_loop(void) {
|
||||
if (!o->parentObj) {
|
||||
obj_mark_for_deletion(o);
|
||||
return;
|
||||
}
|
||||
obj_copy_pos_and_angle(o, o->parentObj);
|
||||
if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
|
||||
obj_copy_scale(o, o->parentObj);
|
||||
|
|
|
@ -93,10 +93,13 @@ void bhv_platform_on_track_init(void) {
|
|||
|
||||
o->oPlatformOnTrackIsNotSkiLift = o->oPlatformOnTrackType - PLATFORM_ON_TRACK_TYPE_SKI_LIFT;
|
||||
|
||||
o->collisionData =
|
||||
segmented_to_virtual(sPlatformOnTrackCollisionModels[o->oPlatformOnTrackType]);
|
||||
if (BHV_ARR_CHECK(sPlatformOnTrackCollisionModels, o->oPlatformOnTrackType, void const *)) {
|
||||
o->collisionData = segmented_to_virtual(sPlatformOnTrackCollisionModels[o->oPlatformOnTrackType]);
|
||||
}
|
||||
|
||||
o->oPlatformOnTrackStartWaypoint = segmented_to_virtual(*sPlatformOnTrackPaths[pathIndex]);
|
||||
if (BHV_ARR_CHECK(sPlatformOnTrackPaths, pathIndex, Trajectory**)) {
|
||||
o->oPlatformOnTrackStartWaypoint = segmented_to_virtual(*sPlatformOnTrackPaths[pathIndex]);
|
||||
}
|
||||
|
||||
o->oPlatformOnTrackIsNotHMC = pathIndex - 4;
|
||||
|
||||
|
@ -353,8 +356,9 @@ void bhv_platform_on_track_update(void) {
|
|||
*/
|
||||
void bhv_track_ball_update(void) {
|
||||
// Despawn after the elevator passes this ball
|
||||
s16 relativeIndex =
|
||||
(s16) o->oBehParams2ndByte - (s16) o->parentObj->oPlatformOnTrackBaseBallIndex - 1;
|
||||
s16 relativeIndex = o->parentObj ?
|
||||
((s16) o->oBehParams2ndByte - (s16) o->parentObj->oPlatformOnTrackBaseBallIndex - 1)
|
||||
: 0;
|
||||
if (relativeIndex < 1 || relativeIndex > 5) {
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
|
|
|
@ -157,7 +157,9 @@ void bhv_pyramid_pillar_touch_detector_loop(void) {
|
|||
cur_obj_become_tangible();
|
||||
if ((o->oInteractStatus & INT_STATUS_INTERACTED) || obj_check_if_collided_with_object(o, gMarioStates[0].marioObj) == 1) {
|
||||
// Increase the pyramid top's count of pillars touched.
|
||||
o->parentObj->oPyramidTopPillarsTouched++;
|
||||
if (o->parentObj) {
|
||||
o->parentObj->oPyramidTopPillarsTouched++;
|
||||
}
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
if (!(o->oInteractStatus & INT_STATUS_INTERACTED)) {
|
||||
network_send_collect_item(o);
|
||||
|
|
|
@ -31,9 +31,11 @@ void bhv_racing_penguin_the_quick_override_ownership(u8* shouldOverride, u8* sho
|
|||
|
||||
void bhv_racing_penguin_run_once(void) {
|
||||
cur_obj_align_gfx_with_floor();
|
||||
cur_obj_push_mario_away_from_cylinder(
|
||||
*sRacingPenguinData[o->oBehParams2ndByte].radius,
|
||||
*sRacingPenguinData[o->oBehParams2ndByte].height);
|
||||
if (BHV_ARR_CHECK(sRacingPenguinData, o->oBehParams2ndByte, struct RacingPenguinData)) {
|
||||
cur_obj_push_mario_away_from_cylinder(
|
||||
*sRacingPenguinData[o->oBehParams2ndByte].radius,
|
||||
*sRacingPenguinData[o->oBehParams2ndByte].height);
|
||||
}
|
||||
}
|
||||
|
||||
void bhv_racing_penguin_init(void) {
|
||||
|
@ -44,10 +46,10 @@ void bhv_racing_penguin_init(void) {
|
|||
}
|
||||
|
||||
struct Object* objFinishLine = cur_obj_nearest_object_with_behavior(bhvPenguinRaceFinishLine);
|
||||
objFinishLine->parentObj = o;
|
||||
if (objFinishLine) { objFinishLine->parentObj = o; }
|
||||
|
||||
struct Object* objShortcutCheck = cur_obj_nearest_object_with_behavior(bhvPenguinRaceShortcutCheck);
|
||||
objShortcutCheck->parentObj = o;
|
||||
if (objShortcutCheck) { objShortcutCheck->parentObj = o; }
|
||||
|
||||
struct SyncObject* so = sync_object_init(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
if (so) {
|
||||
|
@ -95,6 +97,7 @@ u8 racing_penguin_act_show_init_text_continue_dialog(void) { return o->oAction =
|
|||
|
||||
static void racing_penguin_act_show_init_text(void) {
|
||||
if (!gMarioStates[0].visibleToEnemies) { return; }
|
||||
if (!BHV_ARR_CHECK(sRacingPenguinData, o->oBehParams2ndByte, struct RacingPenguinData)) { return; }
|
||||
s32 response = obj_update_race_proposition_dialog(&gMarioStates[0], *sRacingPenguinData[o->oBehParams2ndByte].text, racing_penguin_act_show_init_text_continue_dialog);
|
||||
|
||||
if (response == 1) {
|
||||
|
@ -136,12 +139,12 @@ static void racing_penguin_act_race(void) {
|
|||
|
||||
// prevent segfault / error state
|
||||
if (o->oPathedStartWaypoint == NULL) {
|
||||
struct Object* child;
|
||||
struct Object* child = NULL;
|
||||
child = cur_obj_nearest_object_with_behavior(bhvPenguinRaceFinishLine);
|
||||
child->parentObj = o;
|
||||
if (child) { child->parentObj = o; }
|
||||
|
||||
child = cur_obj_nearest_object_with_behavior(bhvPenguinRaceShortcutCheck);
|
||||
child->parentObj = o;
|
||||
if (child) { child->parentObj = o; }
|
||||
|
||||
o->oPathedStartWaypoint = o->oPathedPrevWaypoint = segmented_to_virtual(gBehaviorValues.trajectories.RacingPenguinTrajectory);
|
||||
o->oPathedPrevWaypointFlags = 0;
|
||||
|
@ -295,6 +298,9 @@ void bhv_racing_penguin_update(void) {
|
|||
void bhv_penguin_race_finish_line_update(void) {
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000;
|
||||
if (!o->parentObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (o->parentObj->oRacingPenguinReachedBottom
|
||||
|| (player && distanceToPlayer < 1000.0f && player->oPosZ - o->oPosZ < 0.0f)) {
|
||||
|
@ -308,7 +314,7 @@ void bhv_penguin_race_finish_line_update(void) {
|
|||
void bhv_penguin_race_shortcut_check_update(void) {
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000;
|
||||
if (distanceToPlayer < 500.0f && !o->parentObj->oRacingPenguinMarioCheated) {
|
||||
if (distanceToPlayer < 500.0f && o->parentObj && !o->parentObj->oRacingPenguinMarioCheated) {
|
||||
o->parentObj->oRacingPenguinMarioCheated = TRUE;
|
||||
network_send_object(o->parentObj);
|
||||
}
|
||||
|
|
|
@ -8,8 +8,10 @@ void const *D_80331A44[] = {
|
|||
s16 D_80331A4C[] = { 300, -300, 600, -600 };
|
||||
|
||||
void bhv_rotating_octagonal_plat_init(void) {
|
||||
o->collisionData = segmented_to_virtual(D_80331A44[(u8)(o->oBehParams >> 16)]);
|
||||
o->oAngleVelYaw = D_80331A4C[(u8)(o->oBehParams >> 24)];
|
||||
if (BHV_ARR_CHECK(D_80331A44, (u8)(o->oBehParams >> 16), void const*)) {
|
||||
o->collisionData = segmented_to_virtual(D_80331A44[(u8)(o->oBehParams >> 16)]);
|
||||
}
|
||||
o->oAngleVelYaw = BHV_ARR(D_80331A4C, (u8)(o->oBehParams >> 24), s16);
|
||||
}
|
||||
|
||||
void bhv_rotating_octagonal_plat_loop(void) {
|
||||
|
|
|
@ -39,7 +39,7 @@ void bhv_wf_rotating_wooden_platform_loop(void) {
|
|||
|
||||
void bhv_rotating_platform_loop(void) {
|
||||
s8 sp1F = o->oBehParams >> 24;
|
||||
if (o->oTimer == 0) {
|
||||
if (o->oTimer == 0 && BHV_ARR_CHECK(sWFRotatingPlatformData, o->oBehParams2ndByte, struct WFRotatingPlatformData)) {
|
||||
obj_set_collision_data(o, sWFRotatingPlatformData[o->oBehParams2ndByte].collisionData);
|
||||
o->oCollisionDistance = sWFRotatingPlatformData[o->oBehParams2ndByte].collisionDistance;
|
||||
cur_obj_scale(sWFRotatingPlatformData[o->oBehParams2ndByte].scale * 0.01f);
|
||||
|
|
|
@ -129,7 +129,7 @@ void bhv_scuttlebug_loop(void) {
|
|||
if (o->parentObj != o) {
|
||||
if (obj_is_hidden(o))
|
||||
obj_mark_for_deletion(o);
|
||||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
|
||||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED && o->parentObj) {
|
||||
o->parentObj->oScuttlebugSpawnerUnk88 = 1;
|
||||
network_send_object(o->parentObj);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,9 @@ static void const *sSeesawPlatformCollisionModels[] = {
|
|||
* Init function for bhvSeesawPlatform.
|
||||
*/
|
||||
void bhv_seesaw_platform_init(void) {
|
||||
o->collisionData = segmented_to_virtual(sSeesawPlatformCollisionModels[o->oBehParams2ndByte]);
|
||||
if (BHV_ARR_CHECK(sSeesawPlatformCollisionModels, o->oBehParams2ndByte, void const*)) {
|
||||
o->collisionData = segmented_to_virtual(sSeesawPlatformCollisionModels[o->oBehParams2ndByte]);
|
||||
}
|
||||
|
||||
// The S-shaped seesaw platform in BitS is large, so increase its collision
|
||||
// distance
|
||||
|
|
|
@ -22,11 +22,11 @@ static s32 sl_walking_penguin_turn(void) {
|
|||
// Stay still and use walking animation for the turn.
|
||||
o->oForwardVel = 0.0f;
|
||||
cur_obj_init_animation_with_accel_and_sound(PENGUIN_ANIM_WALK, 1.0f);
|
||||
|
||||
|
||||
// Turn around.
|
||||
o->oAngleVelYaw = 0x400;
|
||||
o->oMoveAngleYaw += o->oAngleVelYaw;
|
||||
|
||||
|
||||
if (o->oTimer == 31)
|
||||
return TRUE; // Finished turning
|
||||
else
|
||||
|
@ -52,7 +52,7 @@ void bhv_sl_walking_penguin_loop(void) {
|
|||
|
||||
o->oAngleVelYaw = 0;
|
||||
cur_obj_update_floor_and_walls();
|
||||
|
||||
|
||||
switch (o->oAction) {
|
||||
// Walk erratically across the ice bridge using preset steps.
|
||||
case SL_WALKING_PENGUIN_ACT_MOVING_FORWARDS:
|
||||
|
@ -61,68 +61,69 @@ void bhv_sl_walking_penguin_loop(void) {
|
|||
o->oSLWalkingPenguinCurStep = 0;
|
||||
o->oSLWalkingPenguinCurStepTimer = 0;
|
||||
}
|
||||
|
||||
if (o->oSLWalkingPenguinCurStepTimer < sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].stepLength)
|
||||
o->oSLWalkingPenguinCurStepTimer++;
|
||||
else {
|
||||
// Move to next step
|
||||
o->oSLWalkingPenguinCurStepTimer = 0;
|
||||
o->oSLWalkingPenguinCurStep++;
|
||||
if (sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].stepLength < 0)
|
||||
// Reached the end of the list, go back to the start
|
||||
o->oSLWalkingPenguinCurStep = 0;
|
||||
}
|
||||
|
||||
if (o->oPosX < 300.0f)
|
||||
o->oAction++; // If reached the end of the bridge, turn around and head back.
|
||||
else {
|
||||
// Move and animate the penguin
|
||||
o->oForwardVel = sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].speed;
|
||||
|
||||
cur_obj_init_animation_with_accel_and_sound(
|
||||
sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].anim,
|
||||
sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].animSpeed
|
||||
);
|
||||
if (BHV_ARR_CHECK(sSLWalkingPenguinErraticSteps, o->oSLWalkingPenguinCurStep, struct SLWalkingPenguinStep)) {
|
||||
if (o->oSLWalkingPenguinCurStepTimer < sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].stepLength)
|
||||
o->oSLWalkingPenguinCurStepTimer++;
|
||||
else {
|
||||
// Move to next step
|
||||
o->oSLWalkingPenguinCurStepTimer = 0;
|
||||
o->oSLWalkingPenguinCurStep++;
|
||||
if (sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].stepLength < 0)
|
||||
// Reached the end of the list, go back to the start
|
||||
o->oSLWalkingPenguinCurStep = 0;
|
||||
}
|
||||
|
||||
if (o->oPosX < 300.0f)
|
||||
o->oAction++; // If reached the end of the bridge, turn around and head back.
|
||||
else {
|
||||
// Move and animate the penguin
|
||||
o->oForwardVel = sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].speed;
|
||||
|
||||
cur_obj_init_animation_with_accel_and_sound(
|
||||
sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].anim,
|
||||
sSLWalkingPenguinErraticSteps[o->oSLWalkingPenguinCurStep].animSpeed
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// At the end, turn around and prepare to head back across the bridge.
|
||||
case SL_WALKING_PENGUIN_ACT_TURNING_BACK:
|
||||
if (sl_walking_penguin_turn())
|
||||
o->oAction++; // Finished turning
|
||||
break;
|
||||
|
||||
|
||||
// Walk back across the bridge at a constant speed.
|
||||
case SL_WALKING_PENGUIN_ACT_RETURNING:
|
||||
// Move and animate the penguin
|
||||
o->oForwardVel = 12.0f;
|
||||
cur_obj_init_animation_with_accel_and_sound(PENGUIN_ANIM_WALK, 2.0f);
|
||||
|
||||
|
||||
if (o->oPosX > 1700.0f)
|
||||
o->oAction++; // If reached the start of the bridge, turn around.
|
||||
break;
|
||||
|
||||
|
||||
// At the start, turn around and prepare to walk erratically across the bridge.
|
||||
case SL_WALKING_PENGUIN_ACT_TURNING_FORWARDS:
|
||||
if (sl_walking_penguin_turn())
|
||||
o->oAction = SL_WALKING_PENGUIN_ACT_MOVING_FORWARDS; // Finished turning
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
cur_obj_move_standard(-78);
|
||||
if (!cur_obj_hide_if_mario_far_away_y(1000.0f))
|
||||
play_penguin_walking_sound(PENGUIN_WALK_BIG);
|
||||
|
||||
|
||||
// Adjust the position to get a point better lined up with the visual model, for stopping the wind.
|
||||
// The new point is 60 units behind the penguin and 100 units perpedicularly, away from the snowman.
|
||||
|
||||
|
||||
adjustedXPos = o->oPosX + sins(0xDBB0) * 60.0f; // 0xDBB0 = -51 degrees, the angle the penguin is facing
|
||||
adjustedZPos = o->oPosZ + coss(0xDBB0) * 60.0f;
|
||||
adjustedXPos += perpendicularOffset * sins(0x1BB0); // 0x1BB0 = 39 degrees, perpendicular to the penguin
|
||||
adjustedZPos += perpendicularOffset * coss(0x1BB0);
|
||||
o->oSLWalkingPenguinWindCollisionXPos = adjustedXPos;
|
||||
o->oSLWalkingPenguinWindCollisionZPos = adjustedZPos;
|
||||
|
||||
|
||||
print_debug_bottom_up("x %d", o->oPosX);
|
||||
print_debug_bottom_up("z %d", o->oPosZ);
|
||||
}
|
||||
|
|
|
@ -256,6 +256,10 @@ void bhv_snowmans_head_loop(void) {
|
|||
}
|
||||
|
||||
void bhv_snowmans_body_checkpoint_loop(void) {
|
||||
if (!o->parentObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 800)) {
|
||||
o->parentObj->oSnowmansBottomUnk1AC++;
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
|
|
|
@ -13,8 +13,9 @@ struct ObjectHitbox sSparkleSpawnStarHitbox = {
|
|||
};
|
||||
|
||||
void bhv_spawned_star_init(void) {
|
||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_NO_EXIT))
|
||||
if (!(o->oInteractionSubtype & INT_SUBTYPE_NO_EXIT) && o->parentObj) {
|
||||
o->oBehParams = o->parentObj->oBehParams;
|
||||
}
|
||||
s32 sp24 = (o->oBehParams >> 24) & 0xFF;
|
||||
if (bit_shift_left(sp24) & save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1))
|
||||
cur_obj_set_model(smlua_model_util_load(E_MODEL_TRANSPARENT_STAR));
|
||||
|
|
|
@ -41,7 +41,7 @@ void bhv_thi_tiny_island_top_loop(void) {
|
|||
}
|
||||
} else {
|
||||
if (o->oTimer < 50) {
|
||||
gEnvironmentRegions[18]--;
|
||||
if (gEnvironmentRegions) { gEnvironmentRegions[18]--; }
|
||||
cur_obj_play_sound_1(SOUND_ENV_WATER_DRAIN);
|
||||
} else {
|
||||
gTHIWaterDrained |= 1;
|
||||
|
@ -50,8 +50,9 @@ void bhv_thi_tiny_island_top_loop(void) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (o->oTimer == 0)
|
||||
gEnvironmentRegions[18] = 700;
|
||||
if (o->oTimer == 0) {
|
||||
if (gEnvironmentRegions) { gEnvironmentRegions[18] = 700; }
|
||||
}
|
||||
cur_obj_hide();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// tower_platform.c.inc
|
||||
|
||||
void bhv_wf_solid_tower_platform_loop(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
if (o->parentObj->oAction == 1) {
|
||||
cur_obj_become_tangible();
|
||||
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
|
@ -45,12 +46,14 @@ void bhv_wf_elevator_tower_platform_loop(void) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (o->parentObj->oAction == 1) {
|
||||
cur_obj_become_tangible();
|
||||
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
} else if (o->parentObj->oAction > 1) {
|
||||
cur_obj_become_intangible();
|
||||
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
|
||||
if (o->parentObj) {
|
||||
if (o->parentObj->oAction == 1) {
|
||||
cur_obj_become_tangible();
|
||||
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
} else if (o->parentObj->oAction > 1) {
|
||||
cur_obj_become_intangible();
|
||||
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,12 +76,14 @@ void bhv_wf_sliding_tower_platform_loop(void) {
|
|||
o->oPosX += o->oVelX;
|
||||
o->oPosZ += o->oVelZ;
|
||||
|
||||
if (o->parentObj->oAction == 1) {
|
||||
cur_obj_become_tangible();
|
||||
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
} else if (o->parentObj->oAction > 1) {
|
||||
cur_obj_become_intangible();
|
||||
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
|
||||
if (o->parentObj) {
|
||||
if (o->parentObj->oAction == 1) {
|
||||
cur_obj_become_tangible();
|
||||
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
} else if (o->parentObj->oAction > 1) {
|
||||
cur_obj_become_intangible();
|
||||
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ void tox_box_act_3(void) {
|
|||
}
|
||||
|
||||
void tox_box_act_0(void) {
|
||||
if (!BHV_ARR_CHECK(D_8032F96C, o->oBehParams2ndByte, s8*)) { return; }
|
||||
s8 *sp1C = D_8032F96C[o->oBehParams2ndByte];
|
||||
o->oAction = cur_obj_set_direction_table(sp1C);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,10 @@ static struct ObjectHitbox sTreasureChestBottomHitbox = {
|
|||
|
||||
|
||||
void bhv_treasure_chest_top_loop(void) {
|
||||
if (!o->parentObj || !o->parentObj->parentObj) {
|
||||
obj_mark_for_deletion(o);
|
||||
return;
|
||||
}
|
||||
struct Object *rootParent = o->parentObj->parentObj;
|
||||
|
||||
switch (o->oAction) {
|
||||
|
@ -67,6 +71,7 @@ void bhv_treasure_chest_bottom_init(void) {
|
|||
}
|
||||
|
||||
void bhv_treasure_chest_bottom_loop(void) {
|
||||
if (!o->parentObj) { return; }
|
||||
if (o->parentObj != NULL && o->parentObj->oTreasureChestSound != 0) {
|
||||
switch (o->parentObj->oTreasureChestSound) {
|
||||
case 1: play_sound(SOUND_GENERAL2_RIGHT_ANSWER, gGlobalSoundSource); break;
|
||||
|
|
|
@ -36,10 +36,12 @@ static void triplet_butterfly_act_init(void) {
|
|||
}
|
||||
|
||||
//! TODO: Describe this glitch
|
||||
if (o->parentObj->oTripletButterflySelectedButterfly == o->oBehParams2ndByte) {
|
||||
o->oTripletButterflyType = TRIPLET_BUTTERFLY_TYPE_SPAWN_1UP;
|
||||
} else if (o->parentObj->oBehParams2ndByte & TRIPLET_BUTTERFLY_BP_NO_BOMBS) {
|
||||
o->oTripletButterflyType = TRIPLET_BUTTERFLY_TYPE_NORMAL;
|
||||
if (o->parentObj) {
|
||||
if (o->parentObj->oTripletButterflySelectedButterfly == o->oBehParams2ndByte) {
|
||||
o->oTripletButterflyType = TRIPLET_BUTTERFLY_TYPE_SPAWN_1UP;
|
||||
} else if (o->parentObj->oBehParams2ndByte & TRIPLET_BUTTERFLY_BP_NO_BOMBS) {
|
||||
o->oTripletButterflyType = TRIPLET_BUTTERFLY_TYPE_NORMAL;
|
||||
}
|
||||
}
|
||||
// Default butterfly type is TRIPLET_BUTTERFLY_TYPE_EXPLODES
|
||||
|
||||
|
@ -82,6 +84,7 @@ static void triplet_butterfly_act_wander(void) {
|
|||
}
|
||||
|
||||
static void triplet_butterfly_act_activate(void) {
|
||||
if (!BHV_ARR_CHECK(sTripletButterflyActivationData, o->oTripletButterflyType, struct TripletButterflyActivationData)) { return; }
|
||||
if (o->oTimer > 20) {
|
||||
if (o->oTripletButterflyModel == 0) {
|
||||
spawn_object_relative_with_scale(0, 0, -40, 0, 1.5f, o, MODEL_SMOKE, bhvWhitePuffSmoke2);
|
||||
|
@ -90,8 +93,7 @@ static void triplet_butterfly_act_activate(void) {
|
|||
obj_set_billboard(o);
|
||||
o->oTripletButterflyScale = 0.0f;
|
||||
o->oHomeY = o->oPosY;
|
||||
} else if (o->oTripletButterflyScale
|
||||
>= sTripletButterflyActivationData[o->oTripletButterflyType].scale) {
|
||||
} else if (o->oTripletButterflyScale >= sTripletButterflyActivationData[o->oTripletButterflyType].scale) {
|
||||
if (o->oTripletButterflyType != TRIPLET_BUTTERFLY_TYPE_EXPLODES) {
|
||||
spawn_object(o, o->oTripletButterflyModel,
|
||||
sTripletButterflyActivationData[o->oTripletButterflyType].behavior);
|
||||
|
@ -102,8 +104,7 @@ static void triplet_butterfly_act_activate(void) {
|
|||
}
|
||||
}
|
||||
|
||||
o->oTripletButterflyScale +=
|
||||
sTripletButterflyActivationData[o->oTripletButterflyType].scale / 30.0f;
|
||||
o->oTripletButterflyScale += sTripletButterflyActivationData[o->oTripletButterflyType].scale / 30.0f;
|
||||
if (o->oTripletButterflyType == TRIPLET_BUTTERFLY_TYPE_EXPLODES) {
|
||||
o->oGraphYOffset = 250.0f * o->oTripletButterflyScale;
|
||||
o->oPosY = o->oHomeY - o->oGraphYOffset;
|
||||
|
|
|
@ -37,9 +37,10 @@ static s16 sTTC2DRotatorTimeBetweenTurns[][4] = {
|
|||
* Init function for bhvTTC2DRotator.
|
||||
*/
|
||||
void bhv_ttc_2d_rotator_init(void) {
|
||||
o->oTTC2DRotatorMinTimeUntilNextTurn =
|
||||
sTTC2DRotatorTimeBetweenTurns[o->oBehParams2ndByte][gTTCSpeedSetting];
|
||||
o->oTTC2DRotatorIncrement = o->oTTC2DRotatorSpeed = sTTC2DRotatorSpeeds[o->oBehParams2ndByte];
|
||||
if (o->oBehParams2ndByte < 2 && gTTCSpeedSetting < 4) {
|
||||
o->oTTC2DRotatorMinTimeUntilNextTurn = sTTC2DRotatorTimeBetweenTurns[o->oBehParams2ndByte][gTTCSpeedSetting];
|
||||
o->oTTC2DRotatorIncrement = o->oTTC2DRotatorSpeed = sTTC2DRotatorSpeeds[o->oBehParams2ndByte];
|
||||
}
|
||||
|
||||
struct SyncObject* so = sync_object_init(o, 4000.0f);
|
||||
if (so) {
|
||||
|
|
|
@ -37,7 +37,9 @@ static struct TTCPitBlockProperties sTTCPitBlockProperties[][2] = {
|
|||
* Init function for bhvTTCPitBlock.
|
||||
*/
|
||||
void bhv_ttc_pit_block_init(void) {
|
||||
o->collisionData = segmented_to_virtual(sTTCPitBlockCollisionModels[o->oBehParams2ndByte]);
|
||||
if (BHV_ARR_CHECK(sTTCPitBlockCollisionModels, o->oBehParams2ndByte, Collision const *)) {
|
||||
o->collisionData = segmented_to_virtual(sTTCPitBlockCollisionModels[o->oBehParams2ndByte]);
|
||||
}
|
||||
|
||||
o->oTTCPitBlockPeakY = o->oPosY + 330.0f;
|
||||
|
||||
|
@ -65,13 +67,15 @@ void bhv_ttc_pit_block_update(void) {
|
|||
if (clamp_f32(&o->oPosY, o->oHomeY, o->oTTCPitBlockPeakY)) {
|
||||
o->oTTCPitBlockDir = o->oTTCPitBlockDir ^ 0x1;
|
||||
|
||||
if ((o->oTTCPitBlockWaitTime =
|
||||
sTTCPitBlockProperties[gTTCSpeedSetting][o->oTTCPitBlockDir & 0x1].waitTime)
|
||||
< 0) {
|
||||
o->oTTCPitBlockWaitTime = random_mod_offset(10, 20, 6);
|
||||
}
|
||||
if (gTTCSpeedSetting < 4) {
|
||||
if ((o->oTTCPitBlockWaitTime = sTTCPitBlockProperties[gTTCSpeedSetting][o->oTTCPitBlockDir & 0x1].waitTime) < 0) {
|
||||
o->oTTCPitBlockWaitTime = random_mod_offset(10, 20, 6);
|
||||
}
|
||||
|
||||
o->oVelY = sTTCPitBlockProperties[gTTCSpeedSetting][o->oTTCPitBlockDir].speed;
|
||||
if (o->oTTCPitBlockDir < 2) {
|
||||
o->oVelY = sTTCPitBlockProperties[gTTCSpeedSetting][o->oTTCPitBlockDir].speed;
|
||||
}
|
||||
}
|
||||
o->oTimer = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,9 @@ static u8 sTTCRotatingSolidInitialDelays[] = {
|
|||
* Init function for bhvTTCRotatingSolid.
|
||||
*/
|
||||
void bhv_ttc_rotating_solid_init(void) {
|
||||
o->collisionData = segmented_to_virtual(sTTCRotatingSolidCollisionModels[o->oBehParams2ndByte]);
|
||||
if (BHV_ARR_CHECK(sTTCRotatingSolidCollisionModels, o->oBehParams2ndByte, void const*)) {
|
||||
o->collisionData = segmented_to_virtual(sTTCRotatingSolidCollisionModels[o->oBehParams2ndByte]);
|
||||
}
|
||||
|
||||
o->oTTCRotatingSolidNumSides = o->oBehParams2ndByte == TTC_ROTATING_SOLID_BP_CUBE ? 4 : 3;
|
||||
|
||||
|
@ -68,8 +70,9 @@ void bhv_ttc_rotating_solid_update(void) {
|
|||
if (o->oAngleVelRoll == 0) {
|
||||
cur_obj_play_sound_2(SOUND_GENERAL2_ROTATING_BLOCK_CLICK);
|
||||
|
||||
o->oTTCRotatingSolidNumTurns =
|
||||
(o->oTTCRotatingSolidNumTurns + 1) % o->oTTCRotatingSolidNumSides;
|
||||
if (o->oTTCRotatingSolidNumSides) {
|
||||
o->oTTCRotatingSolidNumTurns = (o->oTTCRotatingSolidNumTurns + 1) % o->oTTCRotatingSolidNumSides;
|
||||
}
|
||||
|
||||
o->oTimer = 0;
|
||||
if (gTTCSpeedSetting == TTC_SPEED_RANDOM) {
|
||||
|
|
|
@ -31,7 +31,7 @@ void bhv_tumbling_bridge_platform_loop(void) {
|
|||
}
|
||||
}
|
||||
|
||||
if (o->parentObj != NULL && gCurrCourseNum == COURSE_LLL) {
|
||||
if (o->parentObj && gCurrCourseNum == COURSE_LLL) {
|
||||
if (o->parentObj->oIntangibleTimer == -1) {
|
||||
cur_obj_hide();
|
||||
o->oIntangibleTimer = o->parentObj->oIntangibleTimer;
|
||||
|
@ -74,12 +74,12 @@ void bhv_tumbling_bridge_platform_loop(void) {
|
|||
case 3:
|
||||
break;
|
||||
}
|
||||
if (o->parentObj->oAction == 3) {
|
||||
if (o->parentObj && o->parentObj->oAction == 3) {
|
||||
obj_mark_for_deletion(o);
|
||||
if (isLLL) { network_send_object(o); }
|
||||
}
|
||||
|
||||
if (o->parentObj != NULL && o->parentObj->oIntangibleTimer != -1) {
|
||||
if (o->parentObj && o->parentObj->oIntangibleTimer != -1) {
|
||||
load_object_collision_model();
|
||||
} else if (gCurrCourseNum != COURSE_LLL) {
|
||||
load_object_collision_model();
|
||||
|
@ -94,6 +94,7 @@ void tumbling_bridge_act_1(void) {
|
|||
s32 relativePlatformZ;
|
||||
s32 relativePlatformY = 0;
|
||||
s32 relativeInitialPlatformY = 0;
|
||||
if (!BHV_ARR_CHECK(sTumblingBridgeParams, bridgeID, struct Struct8032F34C)) { return; }
|
||||
|
||||
for (i = 0; i < sTumblingBridgeParams[bridgeID].numBridgeSections; i++) {
|
||||
relativePlatformX = 0;
|
||||
|
|
|
@ -57,7 +57,7 @@ void tuxies_mother_act_1(void) {
|
|||
cur_obj_init_animation_with_sound(3);
|
||||
if (!cur_obj_is_mario_on_platform()) {
|
||||
sp2C = (o->oBehParams >> 0x10) & 0xFF;
|
||||
sp28 = (o->prevObj->oBehParams >> 0x10) & 0xFF;
|
||||
sp28 = o->prevObj ? ((o->prevObj->oBehParams >> 0x10) & 0xFF) : 0;
|
||||
if (sp2C == sp28) {
|
||||
dialogID = gBehaviorValues.dialogs.TuxieMotherBabyFoundDialog;
|
||||
} else {
|
||||
|
@ -75,7 +75,7 @@ void tuxies_mother_act_1(void) {
|
|||
cur_obj_init_animation_with_sound(0);
|
||||
break;
|
||||
case 1:
|
||||
if (o->prevObj->oHeldState == HELD_FREE) {
|
||||
if (o->prevObj && o->prevObj->oHeldState == HELD_FREE) {
|
||||
//! This line is was almost certainly supposed to be something
|
||||
// like o->prevObj->oInteractionSubtype &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
|
||||
// however, this code uses the value of o->oInteractionSubtype
|
||||
|
@ -98,7 +98,7 @@ void tuxies_mother_act_1(void) {
|
|||
}
|
||||
break;
|
||||
case 2:
|
||||
if (o->prevObj->oHeldState == HELD_FREE) {
|
||||
if (o->prevObj && o->prevObj->oHeldState == HELD_FREE) {
|
||||
//! Same bug as above
|
||||
o->prevObj->OBJECT_FIELD_S32(o->oInteractionSubtype) &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
|
||||
obj_set_behavior(o->prevObj, bhvPenguinBaby);
|
||||
|
|
|
@ -516,7 +516,7 @@ void ukiki_free_loop(void) {
|
|||
handle_cap_ukiki_reset();
|
||||
|
||||
if(!(o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER)) {
|
||||
exec_anim_sound_state(sUkikiSoundStates);
|
||||
exec_anim_sound_state(sUkikiSoundStates, sizeof(sUkikiSoundStates) / sizeof(struct SoundState));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ void bhv_ukiki_cage_star_loop(void) {
|
|||
obj_copy_behavior_params(o, o->parentObj);
|
||||
|
||||
// When they cage hides itself, spawn particles and the star.
|
||||
if (o->parentObj->oAction == UKIKI_CAGE_ACT_HIDE) {
|
||||
if (o->parentObj && o->parentObj->oAction == UKIKI_CAGE_ACT_HIDE) {
|
||||
o->oAction++;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -53,9 +53,11 @@ void unagi_act_0(void) {
|
|||
s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000;
|
||||
if (distanceToPlayer > 4500.0f && o->oSubAction != 0) {
|
||||
o->oAction = 1;
|
||||
o->oPosX = o->oPathedStartWaypoint->pos[0];
|
||||
o->oPosY = o->oPathedStartWaypoint->pos[1];
|
||||
o->oPosZ = o->oPathedStartWaypoint->pos[2];
|
||||
if (o->oPathedStartWaypoint) {
|
||||
o->oPosX = o->oPathedStartWaypoint->pos[0];
|
||||
o->oPosY = o->oPathedStartWaypoint->pos[1];
|
||||
o->oPosZ = o->oPathedStartWaypoint->pos[2];
|
||||
}
|
||||
} else if (o->oUnagiUnk1AC < 700.0f) {
|
||||
o->oSubAction = 1;
|
||||
}
|
||||
|
@ -200,7 +202,7 @@ void bhv_unagi_subobject_loop(void) {
|
|||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000;
|
||||
|
||||
if (o->parentObj->oUnagiUnk1B2 == 0) {
|
||||
if (!o->parentObj || o->parentObj->oUnagiUnk1B2 == 0) {
|
||||
obj_mark_for_deletion(o);
|
||||
} else {
|
||||
val04 = 300.0f * o->oBehParams2ndByte;
|
||||
|
|
|
@ -54,12 +54,12 @@ void bhv_water_bomb_spawner_update(void) {
|
|||
marioState = &gMarioStates[i];
|
||||
}
|
||||
}
|
||||
if (!player) { return; }
|
||||
|
||||
spawnerRadius = 50 * (u16)(o->oBehParams >> 16) + 200.0f;
|
||||
|
||||
// When mario is in range and a water bomb isn't already active
|
||||
if (!o->oWaterBombSpawnerBombActive && latDistToMario < spawnerRadius
|
||||
&& player->oPosY - o->oPosY < 1000.0f) {
|
||||
if (!o->oWaterBombSpawnerBombActive && latDistToMario < spawnerRadius && player->oPosY - o->oPosY < 1000.0f) {
|
||||
if (o->oWaterBombSpawnerTimeToSpawn != 0) {
|
||||
o->oWaterBombSpawnerTimeToSpawn -= 1;
|
||||
} else if (sync_object_is_owned_locally(o->oSyncID)) {
|
||||
|
@ -206,7 +206,9 @@ static void water_bomb_act_drop(void) {
|
|||
*/
|
||||
static void water_bomb_act_explode(void) {
|
||||
water_bomb_spawn_explode_particles(25, 60, 10);
|
||||
o->parentObj->oWaterBombSpawnerBombActive = FALSE;
|
||||
if (o->parentObj) {
|
||||
o->parentObj->oWaterBombSpawnerBombActive = FALSE;
|
||||
}
|
||||
obj_mark_for_deletion(o);
|
||||
}
|
||||
|
||||
|
@ -278,7 +280,7 @@ void bhv_water_bomb_update(void) {
|
|||
* Despawn when the parent water bomb does.
|
||||
*/
|
||||
void bhv_water_bomb_shadow_update(void) {
|
||||
if (o->parentObj->oAction == WATER_BOMB_ACT_EXPLODE) {
|
||||
if (!o->parentObj || o->parentObj->oAction == WATER_BOMB_ACT_EXPLODE) {
|
||||
obj_mark_for_deletion(o);
|
||||
} else {
|
||||
// TODO: What is happening here
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
void bhv_bubble_cannon_barrel_loop(void) {
|
||||
struct Object *val04;
|
||||
|
||||
if (o->parentObj->oAction == 2) {
|
||||
if (!o->parentObj || o->parentObj->oAction == 2) {
|
||||
obj_mark_for_deletion(o);
|
||||
} else {
|
||||
o->oMoveAngleYaw = o->parentObj->oFaceAngleYaw;
|
||||
|
|
|
@ -81,6 +81,8 @@ void bhv_water_level_pillar_loop(void) {
|
|||
water_level_pillar_drained();
|
||||
else
|
||||
water_level_pillar_undrained();
|
||||
gEnvironmentRegions[18] = gEnvironmentLevels[2];
|
||||
gEnvironmentRegions[6] = gEnvironmentLevels[0];
|
||||
if (gEnvironmentRegions) {
|
||||
gEnvironmentRegions[18] = gEnvironmentLevels[2];
|
||||
gEnvironmentRegions[6] = gEnvironmentLevels[0];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,9 @@ void water_ring_act_not_collected(void) {
|
|||
//! In this case ringSpawner and ringManager are the same object,
|
||||
// because the Jet Stream Ring Spawner is its own parent object.
|
||||
struct Object *ringSpawner = o->parentObj;
|
||||
if (!ringSpawner) { return; }
|
||||
struct Object *ringManager = ringSpawner->parentObj;
|
||||
if (!ringManager) { return; }
|
||||
|
||||
if (o->oTimer >= 226) {
|
||||
o->oOpacity -= 2;
|
||||
|
@ -160,7 +162,8 @@ void water_ring_spawner_act_inactive(void) {
|
|||
// from the Manta Ray, which spawns rings but also has a Ring Manager object as its
|
||||
// parent. The Jet Stream Ring Spawner functions as both a spawner and a Ring Manager.
|
||||
struct Object *currentObj = o->parentObj;
|
||||
struct Object *waterRing;
|
||||
struct Object *waterRing = NULL;
|
||||
if (!currentObj) { return; }
|
||||
|
||||
//! Because the index counter overflows at 10000, it's possible to wait
|
||||
// for about 4 hours and 38 minutes if you miss a ring, and the index will
|
||||
|
@ -217,7 +220,9 @@ void bhv_manta_ray_water_ring_init(void) {
|
|||
void manta_water_ring_act_not_collected(void) {
|
||||
f32 avgScale = (f32) o->oTimer / 50.0f * 1.3 + 0.1;
|
||||
struct Object *ringSpawner = o->parentObj;
|
||||
if (!ringSpawner) { return; }
|
||||
struct Object *ringManager = ringSpawner->parentObj;
|
||||
if (!ringManager) { return; }
|
||||
|
||||
if (avgScale > 1.3)
|
||||
avgScale = 1.3;
|
||||
|
|
|
@ -22,9 +22,10 @@ void bhv_init_changing_water_level_loop(void) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!gEnvironmentRegions) { return; }
|
||||
|
||||
if (gCurrentObject->oAction == 0) {
|
||||
if (gEnvironmentRegions != NULL)
|
||||
gCurrentObject->oAction++;
|
||||
gCurrentObject->oAction++;
|
||||
} else if (gCurrentObject->oTimer < 10)
|
||||
*gEnvironmentLevels = gEnvironmentRegions[6];
|
||||
else {
|
||||
|
|
|
@ -72,6 +72,7 @@ void bhv_wiggler_body_part_update(void) {
|
|||
// This should never be higher then 3
|
||||
// in normal circumstances.
|
||||
if (o->oBehParams2ndByte > 3 || o->oBehParams2ndByte < 0) { return; }
|
||||
if (!parent->oWigglerSegments) { return; }
|
||||
|
||||
struct ChainSegment *segment = &parent->oWigglerSegments[o->oBehParams2ndByte];
|
||||
|
||||
|
@ -126,11 +127,13 @@ void bhv_wiggler_body_part_update(void) {
|
|||
*/
|
||||
void wiggler_init_segments(void) {
|
||||
struct ChainSegment *segments = mem_pool_alloc(gObjectMemoryPool, 4 * sizeof(struct ChainSegment));
|
||||
|
||||
// Each segment represents the global position and orientation of each
|
||||
// object. Segment 0 represents the wiggler's head, and segment i>0
|
||||
// represents body part i.
|
||||
o->oWigglerSegments = segments;
|
||||
|
||||
if (segments != NULL) {
|
||||
// Each segment represents the global position and orientation of each
|
||||
// object. Segment 0 represents the wiggler's head, and segment i>0
|
||||
// represents body part i.
|
||||
o->oWigglerSegments = segments;
|
||||
for (s32 i = 0; i <= 3; i++) {
|
||||
chain_segment_init(segments + i);
|
||||
|
||||
|
@ -171,11 +174,12 @@ void wiggler_init_segments(void) {
|
|||
*/
|
||||
void wiggler_update_segments(void) {
|
||||
f32 segmentLength = 35.0f * o->header.gfx.scale[0];
|
||||
if (!o->oWigglerSegments) { return; }
|
||||
|
||||
for (s32 i = 1; i <= 3; i++) {
|
||||
struct ChainSegment *prevBodyPart = &o->oWigglerSegments[i - 1];
|
||||
struct ChainSegment *bodyPart = &o->oWigglerSegments[i];
|
||||
|
||||
if (!prevBodyPart || !bodyPart) { continue; }
|
||||
f32 dx = bodyPart->posX - prevBodyPart->posX;
|
||||
f32 dy = bodyPart->posY - prevBodyPart->posY;
|
||||
f32 dz = bodyPart->posZ - prevBodyPart->posZ;
|
||||
|
@ -235,7 +239,7 @@ static void wiggler_act_walk(void) {
|
|||
// to 4 until after this runs the first time. It indexes out of bounds
|
||||
// and uses the value 113762.3 for one frame on US. This is fixed up
|
||||
// in wiggler_init_segments if AVOID_UB is defined.
|
||||
obj_forward_vel_approach(sWigglerSpeeds[o->oHealth - 1], 1.0f);
|
||||
obj_forward_vel_approach(BHV_ARR(sWigglerSpeeds, o->oHealth - 1, f32), 1.0f);
|
||||
|
||||
if (o->oWigglerWalkAwayFromWallTimer != 0) {
|
||||
o->oWigglerWalkAwayFromWallTimer -= 1;
|
||||
|
@ -522,11 +526,13 @@ void bhv_wiggler_update(void) {
|
|||
}
|
||||
|
||||
// Update segment 0 with data from the wiggler object
|
||||
o->oWigglerSegments[0].posX = o->oPosX;
|
||||
o->oWigglerSegments[0].posY = o->oPosY;
|
||||
o->oWigglerSegments[0].posZ = o->oPosZ;
|
||||
o->oWigglerSegments[0].pitch = o->oFaceAnglePitch;
|
||||
o->oWigglerSegments[0].yaw = o->oFaceAngleYaw;
|
||||
if (o->oWigglerSegments) {
|
||||
o->oWigglerSegments[0].posX = o->oPosX;
|
||||
o->oWigglerSegments[0].posY = o->oPosY;
|
||||
o->oWigglerSegments[0].posZ = o->oPosZ;
|
||||
o->oWigglerSegments[0].pitch = o->oFaceAnglePitch;
|
||||
o->oWigglerSegments[0].yaw = o->oFaceAngleYaw;
|
||||
}
|
||||
|
||||
// Update the rest of the segments to follow segment 0
|
||||
wiggler_update_segments();
|
||||
|
|
|
@ -3658,24 +3658,28 @@ void stub_camera_3(UNUSED struct Camera *c) {
|
|||
}
|
||||
|
||||
void vec3f_sub(Vec3f dst, Vec3f src) {
|
||||
if (!dst || !src) { return; }
|
||||
dst[0] -= src[0];
|
||||
dst[1] -= src[1];
|
||||
dst[2] -= src[2];
|
||||
}
|
||||
|
||||
void object_pos_to_vec3f(Vec3f dst, struct Object *o) {
|
||||
if (!dst || !o) { return; }
|
||||
dst[0] = o->oPosX;
|
||||
dst[1] = o->oPosY;
|
||||
dst[2] = o->oPosZ;
|
||||
}
|
||||
|
||||
void vec3f_to_object_pos(struct Object *o, Vec3f src) {
|
||||
if (!o || !src) { return; }
|
||||
o->oPosX = src[0];
|
||||
o->oPosY = src[1];
|
||||
o->oPosZ = src[2];
|
||||
}
|
||||
|
||||
void unused_object_angle_to_vec3s(Vec3s dst, struct Object *o) {
|
||||
if (!dst || !o) { return; }
|
||||
dst[0] = o->oMoveAnglePitch;
|
||||
dst[1] = o->oMoveAngleYaw;
|
||||
dst[2] = o->oMoveAngleRoll;
|
||||
|
|
|
@ -1479,7 +1479,7 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l
|
|||
|
||||
while (pageState == DIALOG_PAGE_STATE_NONE) {
|
||||
change_and_flash_dialog_text_color_lines(colorMode, lineNum);
|
||||
strChar = str[strIdx];
|
||||
strChar = str ? str[strIdx] : DIALOG_CHAR_TERMINATOR;
|
||||
|
||||
switch (strChar) {
|
||||
case DIALOG_CHAR_TERMINATOR:
|
||||
|
@ -1932,6 +1932,10 @@ void render_dialog_entries(void) {
|
|||
break;
|
||||
}
|
||||
#else
|
||||
if (gDialogID >= DIALOG_COUNT || gDialogID < 0) {
|
||||
gDialogID = -1;
|
||||
return;
|
||||
}
|
||||
dialogTable = segmented_to_virtual(seg2_dialog_table);
|
||||
#endif
|
||||
dialog = segmented_to_virtual(dialogTable[gDialogID]);
|
||||
|
|
|
@ -2239,7 +2239,7 @@ void mario_process_interactions(struct MarioState *m) {
|
|||
|
||||
m->collidedObjInteractTypes &= ~interactType;
|
||||
|
||||
if (!(object->oInteractStatus & INT_STATUS_INTERACTED)) {
|
||||
if (object && !(object->oInteractStatus & INT_STATUS_INTERACTED)) {
|
||||
bool allow = true;
|
||||
smlua_call_event_hooks_interact_params_ret_bool(HOOK_ALLOW_INTERACT, m, object, interactType, &allow);
|
||||
if (allow) {
|
||||
|
|
|
@ -677,6 +677,7 @@ s16 music_changed_through_warp(s16 arg) {
|
|||
}
|
||||
|
||||
struct ObjectWarpNode *warpNode = area_get_warp_node(arg);
|
||||
if (!warpNode) { return FALSE; }
|
||||
s16 levelNum = warpNode->node.destLevel & 0x7F;
|
||||
|
||||
#if BUGFIX_KOOPA_RACE_MUSIC
|
||||
|
|
|
@ -2313,9 +2313,11 @@ static void end_peach_cutscene_summon_jumbo_star(struct MarioState *m) {
|
|||
advance_cutscene_step(m);
|
||||
}
|
||||
|
||||
sEndJumboStarObj->oFaceAngleYaw += 0x0400;
|
||||
generate_yellow_sparkles(0, 2528, -1800, 250.0f);
|
||||
play_sound(SOUND_AIR_PEACH_TWINKLE, sEndJumboStarObj->header.gfx.cameraToObject);
|
||||
if (sEndJumboStarObj) {
|
||||
sEndJumboStarObj->oFaceAngleYaw += 0x0400;
|
||||
generate_yellow_sparkles(0, 2528, -1800, 250.0f);
|
||||
play_sound(SOUND_AIR_PEACH_TWINKLE, sEndJumboStarObj->header.gfx.cameraToObject);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(VERSION_EU)
|
||||
|
@ -2344,7 +2346,7 @@ static void end_peach_cutscene_spawn_peach(struct MarioState *m) {
|
|||
play_transition(WARP_TRANSITION_FADE_FROM_COLOR, 192, 255, 255, 255);
|
||||
}
|
||||
if (m->actionTimer == 40) {
|
||||
obj_mark_for_deletion(sEndJumboStarObj);
|
||||
if (sEndJumboStarObj) { obj_mark_for_deletion(sEndJumboStarObj); }
|
||||
|
||||
sEndPeachObj = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_PEACH, bhvEndPeach, 0, 2428,
|
||||
-1300, 0, 0, 0);
|
||||
|
|
|
@ -287,6 +287,8 @@ void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size) {
|
|||
}
|
||||
if (addr == NULL) {
|
||||
LOG_ERROR("Allocate only pool failed to allocate memory of size 0x%X on at pool %p.", size, pool);
|
||||
} else {
|
||||
memset(addr, 0, size);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
@ -374,6 +376,7 @@ void *mem_pool_alloc(struct MemoryPool *pool, u32 size) {
|
|||
* Free a block that was allocated using mem_pool_alloc.
|
||||
*/
|
||||
void mem_pool_free(struct MemoryPool *pool, void *addr) {
|
||||
if (!addr) { return; }
|
||||
struct MemoryBlock *block = (struct MemoryBlock *) ((u8 *) addr - sizeof(struct MemoryBlock));
|
||||
struct MemoryBlock *freeList = pool->freeList.next;
|
||||
|
||||
|
@ -419,6 +422,7 @@ void *alloc_display_list(u32 size) {
|
|||
if (gGfxPoolEnd - size >= (u8 *) gDisplayListHead) {
|
||||
gGfxPoolEnd -= size;
|
||||
ptr = gGfxPoolEnd;
|
||||
memset(ptr, 0, size);
|
||||
} else {
|
||||
LOG_ERROR("Failed to allocate display list of size 0x%X!", size);
|
||||
}
|
||||
|
|
|
@ -319,8 +319,10 @@ Gfx *geo_wdw_set_initial_water_level(s32 callContext, UNUSED struct GraphNode *n
|
|||
} else {
|
||||
wdwWaterHeight = 1024;
|
||||
}
|
||||
for (i = 0; i < *gEnvironmentRegions; i++) {
|
||||
gEnvironmentRegions[i * 6 + 6] = wdwWaterHeight;
|
||||
if (gEnvironmentRegions) {
|
||||
for (i = 0; i < *gEnvironmentRegions; i++) {
|
||||
gEnvironmentRegions[i * 6 + 6] = wdwWaterHeight;
|
||||
}
|
||||
}
|
||||
gWdwWaterLevelSet = TRUE;
|
||||
}
|
||||
|
|
|
@ -178,6 +178,7 @@ void platform_on_track_update_pos_or_spawn_ball(s32 ballIndex, f32 x, f32 y, f32
|
|||
|
||||
do {
|
||||
prevWaypoint = nextWaypoint;
|
||||
if (!prevWaypoint) { break; }
|
||||
|
||||
nextWaypoint += 1;
|
||||
if (nextWaypoint->flags == WAYPOINT_FLAGS_END) {
|
||||
|
|
|
@ -219,7 +219,7 @@ Gfx *geo_switch_area(s32 callContext, struct GraphNode *node) {
|
|||
if (door == NULL) { continue; }
|
||||
if (door->oInteractType != INTERACT_DOOR) { continue; }
|
||||
if (door->oAction == 0) { continue; }
|
||||
if (gDoorAdjacentRooms[door->oDoorUnkF8][0] != gMarioCurrentRoom && gDoorAdjacentRooms[door->oDoorUnkF8][1] != gMarioCurrentRoom) { continue; }
|
||||
if (door->oDoorUnkF8 < 60 && gDoorAdjacentRooms[door->oDoorUnkF8][0] != gMarioCurrentRoom && gDoorAdjacentRooms[door->oDoorUnkF8][1] != gMarioCurrentRoom) { continue; }
|
||||
|
||||
find_floor(door->oHomeX, door->oHomeY, door->oHomeZ, &sp20);
|
||||
if (!sp20) { continue; }
|
||||
|
@ -755,6 +755,7 @@ void cur_obj_move_using_vel(void) {
|
|||
}
|
||||
|
||||
void obj_copy_graph_y_offset(struct Object *dst, struct Object *src) {
|
||||
if (!dst || !src) { return; }
|
||||
dst->oGraphYOffset = src->oGraphYOffset;
|
||||
}
|
||||
|
||||
|
@ -764,12 +765,14 @@ void obj_copy_pos_and_angle(struct Object *dst, struct Object *src) {
|
|||
}
|
||||
|
||||
void obj_copy_pos(struct Object *dst, struct Object *src) {
|
||||
if (!dst || !src) { return; }
|
||||
dst->oPosX = src->oPosX;
|
||||
dst->oPosY = src->oPosY;
|
||||
dst->oPosZ = src->oPosZ;
|
||||
}
|
||||
|
||||
void obj_copy_angle(struct Object *dst, struct Object *src) {
|
||||
if (!dst || !src) { return; }
|
||||
dst->oMoveAnglePitch = src->oMoveAnglePitch;
|
||||
dst->oMoveAngleYaw = src->oMoveAngleYaw;
|
||||
dst->oMoveAngleRoll = src->oMoveAngleRoll;
|
||||
|
@ -780,6 +783,7 @@ void obj_copy_angle(struct Object *dst, struct Object *src) {
|
|||
}
|
||||
|
||||
void obj_set_gfx_pos_from_pos(struct Object *obj) {
|
||||
if (!obj) { return; }
|
||||
obj->header.gfx.pos[0] = obj->oPosX;
|
||||
obj->header.gfx.pos[1] = obj->oPosY;
|
||||
obj->header.gfx.pos[2] = obj->oPosZ;
|
||||
|
@ -1211,15 +1215,15 @@ BAD_RETURN(s16) cur_obj_reverse_animation(void) {
|
|||
|
||||
BAD_RETURN(s32) cur_obj_extend_animation_if_at_end(void) {
|
||||
s32 sp4 = o->header.gfx.animInfo.animFrame;
|
||||
s32 sp0 = o->header.gfx.animInfo.curAnim->loopEnd - 2;
|
||||
s32 sp0 = o->header.gfx.animInfo.curAnim ? o->header.gfx.animInfo.curAnim->loopEnd - 2 : 0;
|
||||
|
||||
if (sp4 == sp0) o->header.gfx.animInfo.animFrame--;
|
||||
}
|
||||
|
||||
s32 cur_obj_check_if_near_animation_end(void) {
|
||||
u32 animFlags = (s32) o->header.gfx.animInfo.curAnim->flags;
|
||||
u32 animFlags = o->header.gfx.animInfo.curAnim ? (s32) o->header.gfx.animInfo.curAnim->flags : 0;
|
||||
s32 animFrame = o->header.gfx.animInfo.animFrame;
|
||||
s32 nearLoopEnd = o->header.gfx.animInfo.curAnim->loopEnd - 2;
|
||||
s32 nearLoopEnd = o->header.gfx.animInfo.curAnim ? o->header.gfx.animInfo.curAnim->loopEnd - 2 : 0;
|
||||
s32 isNearEnd = FALSE;
|
||||
|
||||
if (animFlags & ANIM_FLAG_NOLOOP && nearLoopEnd + 1 == animFrame) {
|
||||
|
@ -1235,7 +1239,7 @@ s32 cur_obj_check_if_near_animation_end(void) {
|
|||
|
||||
s32 cur_obj_check_if_at_animation_end(void) {
|
||||
s32 animFrame = o->header.gfx.animInfo.animFrame;
|
||||
s32 lastFrame = o->header.gfx.animInfo.curAnim->loopEnd - 1;
|
||||
s32 lastFrame = o->header.gfx.animInfo.curAnim ? o->header.gfx.animInfo.curAnim->loopEnd - 1 : 0;
|
||||
|
||||
if (animFrame == lastFrame) {
|
||||
return TRUE;
|
||||
|
@ -1732,6 +1736,7 @@ s32 cur_obj_has_behavior(const BehaviorScript *behavior) {
|
|||
}
|
||||
|
||||
s32 obj_has_behavior(struct Object *obj, const BehaviorScript *behavior) {
|
||||
if (!obj || !behavior) { return FALSE; }
|
||||
behavior = smlua_override_behavior(behavior);
|
||||
if (obj->behavior == segmented_to_virtual(behavior)) {
|
||||
return TRUE;
|
||||
|
@ -2242,6 +2247,7 @@ void obj_set_throw_matrix_from_transform(struct Object *obj) {
|
|||
void obj_build_transform_relative_to_parent(struct Object *obj) {
|
||||
if (obj == NULL) { return; }
|
||||
struct Object *parent = obj->parentObj;
|
||||
if (!parent) { return; }
|
||||
|
||||
obj_build_transform_from_pos_and_angle(obj, O_PARENT_RELATIVE_POS_INDEX, O_FACE_ANGLE_INDEX);
|
||||
obj_apply_scale_to_transform(obj);
|
||||
|
@ -2305,6 +2311,8 @@ s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
|
|||
startWaypoint = o->oPathedStartWaypoint;
|
||||
lastWaypoint = o->oPathedPrevWaypoint;
|
||||
|
||||
if (!startWaypoint) { return PATH_NONE; }
|
||||
|
||||
// sanity check waypoints
|
||||
if (lastWaypoint == NULL) { lastWaypoint = startWaypoint; }
|
||||
struct Waypoint* tmpWaypoint = (lastWaypoint + 1);
|
||||
|
@ -2593,6 +2601,7 @@ s32 cur_obj_progress_direction_table(void) {
|
|||
s8 spF;
|
||||
s8 *sp8 = o->oToxBoxMovementPattern;
|
||||
s32 sp4 = o->oToxBoxMovementStep + 1;
|
||||
if (!sp8) { return 0; }
|
||||
|
||||
if (sp8[sp4] != -1) {
|
||||
spF = sp8[sp4];
|
||||
|
@ -2701,7 +2710,7 @@ void spawn_base_star_with_no_lvl_exit(void) {
|
|||
}
|
||||
|
||||
s32 bit_shift_left(s32 a0) {
|
||||
return D_8032F0A4[a0];
|
||||
return BHV_ARR(D_8032F0A4, a0, s16);
|
||||
}
|
||||
|
||||
s32 cur_obj_mario_far_away(void) {
|
||||
|
@ -3297,4 +3306,15 @@ void cur_obj_set_home_once(void) {
|
|||
o->oHomeX = o->oPosX;
|
||||
o->oHomeY = o->oPosY;
|
||||
o->oHomeZ = o->oPosZ;
|
||||
}
|
||||
|
||||
s32 get_trajectory_length(Trajectory* trajectory) {
|
||||
if (!trajectory) { return 0; }
|
||||
s32 count = 0;
|
||||
s16* c = trajectory;
|
||||
while (*c != -1) {
|
||||
count++;
|
||||
c += 4;
|
||||
}
|
||||
return count;
|
||||
}
|
|
@ -326,5 +326,6 @@ void cur_obj_spawn_star_at_y_offset(f32 targetX, f32 targetY, f32 targetZ, f32 o
|
|||
#endif
|
||||
|
||||
void cur_obj_set_home_once(void);
|
||||
s32 get_trajectory_length(Trajectory* trajectory);
|
||||
|
||||
#endif // OBJECT_HELPERS_H
|
||||
|
|
|
@ -275,6 +275,7 @@ void bhv_mario_update(void) {
|
|||
|
||||
// set mario state to the current player
|
||||
s32 stateIndex = (gCurrentObject->oBehParams - 1);
|
||||
if (stateIndex > MAX_PLAYERS) { return; }
|
||||
gMarioState = &gMarioStates[stateIndex];
|
||||
|
||||
// sanity check torsoPos, it isn't updated off-screen otherwise
|
||||
|
@ -465,6 +466,7 @@ void set_object_respawn_info_bits(struct Object *obj, u8 bits) {
|
|||
u16 *info16;
|
||||
u8 oldRespawnInfoBits = 0;
|
||||
u8 newRespawnInfoBits = 0;
|
||||
if (!obj) { return; }
|
||||
|
||||
switch (obj->respawnInfoType) {
|
||||
case RESPAWN_INFO_TYPE_32:
|
||||
|
|
|
@ -109,11 +109,14 @@ struct Object *try_allocate_object(struct ObjectNode *destList, struct ObjectNod
|
|||
geo_remove_child(&nextObj->gfx.node);
|
||||
geo_add_child(&gObjParentGraphNode, &nextObj->gfx.node);
|
||||
|
||||
((struct Object *)nextObj)->ctx = 0
|
||||
struct Object* ret = (struct Object *) nextObj;
|
||||
ret->ctx = 0
|
||||
| ((u8)CTX_WITHIN(CTX_LEVEL_SCRIPT) << 0)
|
||||
| ((u8)CTX_WITHIN(CTX_HOOK) << 1);
|
||||
|
||||
return (struct Object *) nextObj;
|
||||
ret->header.gfx.sharedChild = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
* of sound states. Used for the stepping sounds of various
|
||||
* objects. (King Bobomb, Bowser, King Whomp)
|
||||
*/
|
||||
void exec_anim_sound_state(struct SoundState *soundStates) {
|
||||
void exec_anim_sound_state(struct SoundState *soundStates, u16 maxSoundStates) {
|
||||
s32 stateIdx = gCurrentObject->oSoundStateID;
|
||||
if (stateIdx >= maxSoundStates) { return; }
|
||||
|
||||
switch (soundStates[stateIdx].playSound) {
|
||||
// since we have an array of sound states corresponding to
|
||||
|
|
|
@ -19,6 +19,6 @@ struct SoundState
|
|||
void cur_obj_play_sound_1(s32 soundMagic);
|
||||
void cur_obj_play_sound_2(s32 soundMagic);
|
||||
void create_sound_spawner(s32 soundMagic);
|
||||
void exec_anim_sound_state(struct SoundState *soundStates);
|
||||
void exec_anim_sound_state(struct SoundState *soundStates, u16 maxSoundStates);
|
||||
|
||||
#endif // SPAWN_SOUND_H
|
||||
|
|
|
@ -577,7 +577,7 @@ void render_score_menu_buttons(struct Object *scoreButton) {
|
|||
spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711,
|
||||
311, -100, 0, -0x8000, 0);
|
||||
}
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A]->oMenuButtonScale = 0.11111111f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A]) { sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A]->oMenuButtonScale = 0.11111111f; }
|
||||
// File B
|
||||
if (save_file_exists(SAVE_FILE_B) == TRUE) {
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B] =
|
||||
|
@ -588,7 +588,7 @@ void render_score_menu_buttons(struct Object *scoreButton) {
|
|||
spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton,
|
||||
-166, 311, -100, 0, -0x8000, 0);
|
||||
}
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B]->oMenuButtonScale = 0.11111111f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B]) { sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B]->oMenuButtonScale = 0.11111111f; }
|
||||
// File C
|
||||
if (save_file_exists(SAVE_FILE_C) == TRUE) {
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C] = spawn_object_rel_with_rot(
|
||||
|
@ -597,7 +597,7 @@ void render_score_menu_buttons(struct Object *scoreButton) {
|
|||
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C] = spawn_object_rel_with_rot(
|
||||
scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0);
|
||||
}
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C]->oMenuButtonScale = 0.11111111f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C]) { sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C]->oMenuButtonScale = 0.11111111f; }
|
||||
// File D
|
||||
if (save_file_exists(SAVE_FILE_D) == TRUE) {
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D] =
|
||||
|
@ -607,19 +607,19 @@ void render_score_menu_buttons(struct Object *scoreButton) {
|
|||
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D] = spawn_object_rel_with_rot(
|
||||
scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, -166, 0, -100, 0, -0x8000, 0);
|
||||
}
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D]->oMenuButtonScale = 0.11111111f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D]) { sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D]->oMenuButtonScale = 0.11111111f; }
|
||||
// Return to main menu button
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_RETURN] = spawn_object_rel_with_rot(
|
||||
scoreButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 711, -388, -100, 0, -0x8000, 0);
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_RETURN]->oMenuButtonScale = 0.11111111f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SCORE_RETURN]) { sMainMenuButtons[MENU_BUTTON_SCORE_RETURN]->oMenuButtonScale = 0.11111111f; }
|
||||
// Switch to copy menu button
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_COPY_FILE] = spawn_object_rel_with_rot(
|
||||
scoreButton, MODEL_MAIN_MENU_BLUE_COPY_BUTTON, bhvMenuButton, 0, -388, -100, 0, -0x8000, 0);
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_COPY_FILE]->oMenuButtonScale = 0.11111111f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SCORE_COPY_FILE]) { sMainMenuButtons[MENU_BUTTON_SCORE_COPY_FILE]->oMenuButtonScale = 0.11111111f; }
|
||||
// Switch to erase menu button
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_ERASE_FILE] = spawn_object_rel_with_rot(
|
||||
scoreButton, MODEL_MAIN_MENU_RED_ERASE_BUTTON, bhvMenuButton, -711, -388, -100, 0, -0x8000, 0);
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE_ERASE_FILE]->oMenuButtonScale = 0.11111111f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SCORE_ERASE_FILE]) { sMainMenuButtons[MENU_BUTTON_SCORE_ERASE_FILE]->oMenuButtonScale = 0.11111111f; }
|
||||
}
|
||||
|
||||
#ifdef VERSION_EU
|
||||
|
@ -1325,7 +1325,7 @@ void bhv_menu_button_manager_init(void) {
|
|||
spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE,
|
||||
bhvMenuButton, -6400, 2800, 0, 0, 0, 0);
|
||||
}
|
||||
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A]->oMenuButtonScale = 1.0f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A]) { sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A]->oMenuButtonScale = 1.0f; }
|
||||
// File B
|
||||
if (save_file_exists(SAVE_FILE_B) == TRUE) {
|
||||
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B] =
|
||||
|
@ -1336,7 +1336,7 @@ void bhv_menu_button_manager_init(void) {
|
|||
spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE,
|
||||
bhvMenuButton, 1500, 2800, 0, 0, 0, 0);
|
||||
}
|
||||
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B]->oMenuButtonScale = 1.0f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B]) { sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B]->oMenuButtonScale = 1.0f; }
|
||||
// File C
|
||||
if (save_file_exists(SAVE_FILE_C) == TRUE) {
|
||||
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C] =
|
||||
|
@ -1346,7 +1346,7 @@ void bhv_menu_button_manager_init(void) {
|
|||
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C] = spawn_object_rel_with_rot(
|
||||
gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE, bhvMenuButton, -6400, 0, 0, 0, 0, 0);
|
||||
}
|
||||
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C]->oMenuButtonScale = 1.0f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C]) { sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C]->oMenuButtonScale = 1.0f; }
|
||||
// File D
|
||||
if (save_file_exists(SAVE_FILE_D) == TRUE) {
|
||||
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D] = spawn_object_rel_with_rot(
|
||||
|
@ -1355,23 +1355,23 @@ void bhv_menu_button_manager_init(void) {
|
|||
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D] = spawn_object_rel_with_rot(
|
||||
gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE, bhvMenuButton, 1500, 0, 0, 0, 0, 0);
|
||||
}
|
||||
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D]->oMenuButtonScale = 1.0f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D]) { sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D]->oMenuButtonScale = 1.0f; }
|
||||
// Score menu button
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE] = spawn_object_rel_with_rot(
|
||||
gCurrentObject, MODEL_MAIN_MENU_GREEN_SCORE_BUTTON, bhvMenuButton, -6400, -3500, 0, 0, 0, 0);
|
||||
sMainMenuButtons[MENU_BUTTON_SCORE]->oMenuButtonScale = 1.0f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SCORE]) { sMainMenuButtons[MENU_BUTTON_SCORE]->oMenuButtonScale = 1.0f; }
|
||||
// Copy menu button
|
||||
sMainMenuButtons[MENU_BUTTON_COPY] = spawn_object_rel_with_rot(
|
||||
gCurrentObject, MODEL_MAIN_MENU_BLUE_COPY_BUTTON, bhvMenuButton, -2134, -3500, 0, 0, 0, 0);
|
||||
sMainMenuButtons[MENU_BUTTON_COPY]->oMenuButtonScale = 1.0f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_COPY]) { sMainMenuButtons[MENU_BUTTON_COPY]->oMenuButtonScale = 1.0f; }
|
||||
// Erase menu button
|
||||
sMainMenuButtons[MENU_BUTTON_ERASE] = spawn_object_rel_with_rot(
|
||||
gCurrentObject, MODEL_MAIN_MENU_RED_ERASE_BUTTON, bhvMenuButton, 2134, -3500, 0, 0, 0, 0);
|
||||
sMainMenuButtons[MENU_BUTTON_ERASE]->oMenuButtonScale = 1.0f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_ERASE]) { sMainMenuButtons[MENU_BUTTON_ERASE]->oMenuButtonScale = 1.0f; }
|
||||
// Sound mode menu button (Option Mode in EU)
|
||||
sMainMenuButtons[MENU_BUTTON_SOUND_MODE] = spawn_object_rel_with_rot(
|
||||
gCurrentObject, MODEL_MAIN_MENU_PURPLE_SOUND_BUTTON, bhvMenuButton, 6400, -3500, 0, 0, 0, 0);
|
||||
sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonScale = 1.0f;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SOUND_MODE]) { sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonScale = 1.0f; }
|
||||
|
||||
sTextBaseAlpha = 0;
|
||||
}
|
||||
|
@ -1392,7 +1392,7 @@ void check_main_menu_clicked_buttons(void) {
|
|||
#endif
|
||||
// Sound mode menu is handled separately because the button ID for it
|
||||
// is not grouped with the IDs of the other submenus.
|
||||
if (check_clicked_button(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosX,
|
||||
if (sMainMenuButtons[MENU_BUTTON_SOUND_MODE] && check_clicked_button(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosX,
|
||||
sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosY, 200.0f) == TRUE) {
|
||||
sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING;
|
||||
sSelectedButtonID = MENU_BUTTON_SOUND_MODE;
|
||||
|
@ -1401,6 +1401,7 @@ void check_main_menu_clicked_buttons(void) {
|
|||
s8 buttonID;
|
||||
// Configure Main Menu button group
|
||||
for (buttonID = MENU_BUTTON_MAIN_MIN; buttonID < MENU_BUTTON_MAIN_MAX; buttonID++) {
|
||||
if (!sMainMenuButtons[buttonID]) { continue; }
|
||||
s16 buttonX = sMainMenuButtons[buttonID]->oPosX;
|
||||
s16 buttonY = sMainMenuButtons[buttonID]->oPosY;
|
||||
|
||||
|
@ -1415,7 +1416,9 @@ void check_main_menu_clicked_buttons(void) {
|
|||
#ifdef VERSION_EU
|
||||
// Open Options Menu if sOpenLangSettings is TRUE (It's TRUE when there's no saves)
|
||||
if (sOpenLangSettings == TRUE) {
|
||||
sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING;
|
||||
if (sMainMenuButtons[MENU_BUTTON_SOUND_MODE]) {
|
||||
sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING;
|
||||
}
|
||||
sSelectedButtonID = MENU_BUTTON_SOUND_MODE;
|
||||
sOpenLangSettings = FALSE;
|
||||
}
|
||||
|
|
|
@ -34,20 +34,20 @@
|
|||
*/
|
||||
|
||||
// Star Selector count models printed in the act selector menu.
|
||||
static struct Object *sStarSelectorModels[8];
|
||||
static struct Object *sStarSelectorModels[8] = { 0 };
|
||||
|
||||
// The act the course is loaded as, affects whether some objects spawn.
|
||||
s8 sLoadedActNum;
|
||||
s8 sLoadedActNum = 0;
|
||||
s8 sReceivedLoadedActNum = 0;
|
||||
|
||||
// Number of obtained stars, excluding the coin star.
|
||||
static u8 sObtainedStars;
|
||||
static u8 sObtainedStars = 0;
|
||||
|
||||
// Total number of stars that appear in the act selector menu.
|
||||
static s8 sVisibleStars;
|
||||
static s8 sVisibleStars = 0;
|
||||
|
||||
// Act selected when the act menu is first opened.
|
||||
static u8 sInitSelectedActNum;
|
||||
static u8 sInitSelectedActNum = 0;
|
||||
|
||||
// Index value of the act selected in the act menu.
|
||||
s8 sSelectedActIndex = 0;
|
||||
|
@ -96,7 +96,7 @@ void bhv_act_selector_star_type_loop(void) {
|
|||
* Renders the 100 coin star with an special star selector type.
|
||||
*/
|
||||
void render_100_coin_star(u8 stars) {
|
||||
if (stars & (1 << 6)) {
|
||||
if ((stars & (1 << 6)) && sStarSelectorModels[6]) {
|
||||
// If the 100 coin star has been collected, create a new star selector next to the coin score.
|
||||
sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR,
|
||||
bhvActSelectorStarType, 370, 24, -300, 0, 0, 0);
|
||||
|
@ -205,6 +205,7 @@ void bhv_act_selector_loop(void) {
|
|||
|
||||
// Star selector type handler
|
||||
for (i = 0; i < sVisibleStars; i++) {
|
||||
if (!sStarSelectorModels[i]) { continue; }
|
||||
if (sSelectedActIndex == i) {
|
||||
sStarSelectorModels[i]->oStarSelectorType = STAR_SELECTOR_SELECTED;
|
||||
} else {
|
||||
|
|
|
@ -4022,8 +4022,8 @@ char gSmluaConstants[] = ""
|
|||
"COOP_OBJ_FLAG_NON_SYNC = (1 << 2)\n"
|
||||
"COOP_OBJ_FLAG_INITIALIZED = (1 << 3)\n"
|
||||
"VERSION_TEXT = 'beta'\n"
|
||||
"VERSION_NUMBER = 34\n"
|
||||
"MINOR_VERSION_NUMBER = 1\n"
|
||||
"VERSION_NUMBER = 35\n"
|
||||
"MINOR_VERSION_NUMBER = 0\n"
|
||||
"PATCH_VERSION_NUMBER = 0\n"
|
||||
"VERSION_REGION = 'JP'\n"
|
||||
"VERSION_REGION = 'EU'\n"
|
||||
|
|
|
@ -23663,6 +23663,24 @@ int smlua_func_get_object_list_from_behavior(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_get_trajectory_length(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_trajectory_length", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Trajectory* trajectory = (Trajectory*)smlua_to_cpointer(L, 1, LVT_TRAJECTORY_P);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_trajectory_length"); return 0; }
|
||||
|
||||
extern s32 get_trajectory_length(Trajectory* trajectory);
|
||||
lua_pushinteger(L, get_trajectory_length(trajectory));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_increment_velocity_toward_range(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
|
@ -29058,16 +29076,18 @@ int smlua_func_exec_anim_sound_state(lua_State* L) {
|
|||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "exec_anim_sound_state", 1, top);
|
||||
if (top != 2) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "exec_anim_sound_state", 2, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct SoundState* soundStates = (struct SoundState*)smlua_to_cobject(L, 1, LOT_SOUNDSTATE);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "exec_anim_sound_state"); return 0; }
|
||||
u16 maxSoundStates = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "exec_anim_sound_state"); return 0; }
|
||||
|
||||
extern void exec_anim_sound_state(struct SoundState *soundStates);
|
||||
exec_anim_sound_state(soundStates);
|
||||
extern void exec_anim_sound_state(struct SoundState *soundStates, u16 maxSoundStates);
|
||||
exec_anim_sound_state(soundStates, maxSoundStates);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -30685,6 +30705,7 @@ void smlua_bind_functions_autogen(void) {
|
|||
//smlua_bind_function(L, "geo_update_layer_transparency", smlua_func_geo_update_layer_transparency); <--- UNIMPLEMENTED
|
||||
//smlua_bind_function(L, "geo_update_projectile_pos_from_parent", smlua_func_geo_update_projectile_pos_from_parent); <--- UNIMPLEMENTED
|
||||
smlua_bind_function(L, "get_object_list_from_behavior", smlua_func_get_object_list_from_behavior);
|
||||
smlua_bind_function(L, "get_trajectory_length", smlua_func_get_trajectory_length);
|
||||
smlua_bind_function(L, "increment_velocity_toward_range", smlua_func_increment_velocity_toward_range);
|
||||
smlua_bind_function(L, "is_item_in_array", smlua_func_is_item_in_array);
|
||||
smlua_bind_function(L, "is_mario_moving_fast_or_in_air", smlua_func_is_mario_moving_fast_or_in_air);
|
||||
|
|
|
@ -585,6 +585,11 @@ u16 smlua_model_util_load_with_pool_and_cache_id(enum ModelExtendedId extId, str
|
|||
}
|
||||
}
|
||||
|
||||
if (pickLoadedId >= MAX_LOADED_GRAPH_NODES) {
|
||||
LOG_ERROR("Could not find slot for extId - %u", extId);
|
||||
return UNLOADED_ID;
|
||||
}
|
||||
|
||||
// load
|
||||
bool resizePool = false;
|
||||
if (pool == NULL) {
|
||||
|
|
|
@ -404,3 +404,23 @@ void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index) {
|
|||
gAreas[area].whirlpools[index]->pos[2] = z;
|
||||
gAreas[area].whirlpools[index]->strength = strength;
|
||||
}
|
||||
|
||||
#ifdef DEVELOPMENT
|
||||
void obj_randomize(struct Object* o) {
|
||||
for (int i = 0; i < 80; i++) {
|
||||
if (rand() % 10 < 5) {
|
||||
o->rawData.asU32[i] = rand() % 10;
|
||||
} else {
|
||||
o->rawData.asU32[i] = rand();
|
||||
}
|
||||
}
|
||||
struct Object* objs[] = { NULL, gMarioStates[0].marioObj, o };
|
||||
if (rand()%4 > 0) { o->parentObj = objs[rand()%3]; }
|
||||
if (rand()%4 > 0) { o->prevObj = objs[rand()%3]; }
|
||||
if (rand()%4 > 0) { o->usingObj = objs[rand()%3]; }
|
||||
|
||||
if (rand() % 10 < 5) {
|
||||
o->oAction = rand() % 10;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -103,7 +103,7 @@ void network_send_area(struct NetworkPlayer* toNp) {
|
|||
// TODO: move find model to a utility file/function
|
||||
// find model
|
||||
u32 model = 0;
|
||||
for (s32 j = 0; j < 256; j++) {
|
||||
for (s32 j = 0; j < MAX_LOADED_GRAPH_NODES; j++) {
|
||||
if (so->o->header.gfx.sharedChild == gLoadedGraphNodes[j]) {
|
||||
model = j;
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue