mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-22 03:55:11 +00:00
Fix more possible crashes
This commit is contained in:
parent
af01a214ee
commit
f785050ccb
19 changed files with 807 additions and 44 deletions
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/bash
|
||||
python3 ./autogen/convert_structs.py
|
||||
python3 ./autogen/convert_functions.py
|
||||
python3 ./autogen/convert_constants.py
|
||||
python3 ./autogen/convert_structs.py $1
|
||||
python3 ./autogen/convert_functions.py $1
|
||||
python3 ./autogen/convert_constants.py $1
|
|
@ -576,7 +576,7 @@ def build_call(function):
|
|||
|
||||
if ftype == 'void':
|
||||
return ' %s;\n' % ccall
|
||||
# We can't possibly know the type of a void pointer,
|
||||
# We can't possibly know the type of a void pointer,
|
||||
# So we just don't return anything from it
|
||||
elif ftype == 'void *':
|
||||
return ' %s;\n' % ccall
|
||||
|
@ -605,7 +605,7 @@ def build_call(function):
|
|||
def build_function(function, do_extern):
|
||||
s = ''
|
||||
fid = function['identifier']
|
||||
|
||||
|
||||
if fid in override_function_version_excludes:
|
||||
s += '#ifndef ' + override_function_version_excludes[fid] + '\n'
|
||||
|
||||
|
@ -614,6 +614,12 @@ def build_function(function, do_extern):
|
|||
else:
|
||||
s += 'int smlua_func_%s(lua_State* L) {\n' % function['identifier']
|
||||
|
||||
# make sure the bhv functions have a current object
|
||||
fname = function['filename']
|
||||
if fname == 'behavior_actions.h' or fname == 'obj_behaviors_2.h' or fname == 'obj_behaviors.h':
|
||||
if 'bhv_' in fid:
|
||||
s += ' if (!gCurrentObject) { return 0; }\n'
|
||||
|
||||
s += """ if (L == NULL) { return 0; }\n
|
||||
int top = lua_gettop(L);
|
||||
if (top != %d) {
|
||||
|
@ -640,7 +646,7 @@ def build_function(function, do_extern):
|
|||
s += '\n'
|
||||
|
||||
s += ' return 1;\n}\n'
|
||||
|
||||
|
||||
if fid in override_function_version_excludes:
|
||||
s += '#endif\n'
|
||||
|
||||
|
@ -659,6 +665,7 @@ def build_functions(processed_files):
|
|||
s += gen_comment_header(processed_file['filename'])
|
||||
|
||||
for function in processed_file['functions']:
|
||||
function['filename'] = processed_file['filename']
|
||||
s += build_function(function, processed_file['extern'])
|
||||
return s
|
||||
|
||||
|
@ -792,28 +799,51 @@ def process_files():
|
|||
|
||||
############################################################################
|
||||
|
||||
def output_nuke_function(fname, function):
|
||||
fuzz_functions = ""
|
||||
|
||||
def output_fuzz_function(fname, function):
|
||||
first = True
|
||||
comment = ''
|
||||
comment = ' -- '
|
||||
fid = function['identifier']
|
||||
print(fid + '(', end='')
|
||||
|
||||
line = ' ' + fid + '('
|
||||
|
||||
for param in function['params']:
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
print(', ', end='')
|
||||
line += ', '
|
||||
comment += ', '
|
||||
pid = param['identifier']
|
||||
ptype = param['type']
|
||||
ptype, plink = translate_type_to_lua(ptype)
|
||||
|
||||
if ptype == '`integer`' or ptype == '`number`' or 'enum' in ptype:
|
||||
print('0', end='')
|
||||
else:
|
||||
print('nil', end='')
|
||||
if 'enum ' in ptype:
|
||||
ptype = 'integer'
|
||||
line += 'rnd_' + ptype.strip().replace('`', '').replace(' ', '').split('<')[-1].split('>')[0].split('(')[0] + '()'
|
||||
|
||||
|
||||
#if ptype == '`integer`' or ptype == '`number`' or 'enum' in ptype:
|
||||
# print('0', end='')
|
||||
#else:
|
||||
# print('nil', end='')
|
||||
comment += ptype
|
||||
|
||||
print(') -- ' + comment)
|
||||
line += ')'
|
||||
if len(line) >= 80:
|
||||
line = line + '\n ' + comment + '\n'
|
||||
else:
|
||||
line = line.ljust(80) + comment + '\n'
|
||||
|
||||
global fuzz_functions
|
||||
fuzz_functions += line
|
||||
|
||||
def output_fuzz_file():
|
||||
global fuzz_functions
|
||||
with open('./autogen/fuzz_template.lua') as f:
|
||||
file_str = f.read()
|
||||
with open('/home/djoslin/.local/share/sm64ex-coop/mods/test-fuzz.lua', 'w') as f:
|
||||
f.write(file_str.replace('-- $[FUNCS]', fuzz_functions))
|
||||
|
||||
############################################################################
|
||||
|
||||
|
@ -877,7 +907,8 @@ def doc_function(fname, function):
|
|||
return ''
|
||||
|
||||
# debug print out lua nuke functions
|
||||
# output_nuke_function(fname, function)
|
||||
if len(sys.argv) >= 2 and sys.argv[1] == 'fuzz':
|
||||
output_fuzz_function(fname, function)
|
||||
|
||||
if not doc_should_document(fname, function['identifier']):
|
||||
return ''
|
||||
|
@ -1073,5 +1104,8 @@ def main():
|
|||
global total_functions
|
||||
print('Total functions: ' + str(total_functions))
|
||||
|
||||
if len(sys.argv) >= 2 and sys.argv[1] == 'fuzz':
|
||||
output_fuzz_file()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -242,6 +242,27 @@ def parse_structs(extracted):
|
|||
|
||||
############################################################################
|
||||
|
||||
def output_fuzz_struct(struct):
|
||||
sid = struct['identifier']
|
||||
print('function Nuke' + sid + "(struct)")
|
||||
for field in struct['fields']:
|
||||
fid, ftype, fimmutable, lvt, lot = get_struct_field_info(struct, field)
|
||||
if fimmutable == 'true':
|
||||
continue
|
||||
if sid in override_field_invisible:
|
||||
if fid in override_field_invisible[sid]:
|
||||
continue
|
||||
if lvt == 'LVT_COBJECT':
|
||||
print(' Fuzz' + ftype.replace('struct ', '') + '(struct.' + fid + ')')
|
||||
elif lvt == 'LVT_COBJECT_P':
|
||||
print(' struct.' + fid + ' = nil')
|
||||
else:
|
||||
print(' struct.' + fid + ' = 0')
|
||||
print('end')
|
||||
print('')
|
||||
|
||||
############################################################################
|
||||
|
||||
sLuaObjectTable = []
|
||||
sLotAutoGenList = []
|
||||
|
||||
|
@ -272,28 +293,10 @@ def get_struct_field_info(struct, field):
|
|||
|
||||
return fid, ftype, fimmutable, lvt, lot
|
||||
|
||||
def output_nuke_struct(struct):
|
||||
sid = struct['identifier']
|
||||
print('function Nuke' + sid + "(struct)")
|
||||
for field in struct['fields']:
|
||||
fid, ftype, fimmutable, lvt, lot = get_struct_field_info(struct, field)
|
||||
if fimmutable == 'true':
|
||||
continue
|
||||
if sid in override_field_invisible:
|
||||
if fid in override_field_invisible[sid]:
|
||||
continue
|
||||
if lvt == 'LVT_COBJECT':
|
||||
print(' Nuke' + ftype.replace('struct ', '') + '(struct.' + fid + ')')
|
||||
elif lvt == 'LVT_COBJECT_P':
|
||||
print(' struct.' + fid + ' = nil')
|
||||
else:
|
||||
print(' struct.' + fid + ' = 0')
|
||||
print('end')
|
||||
print('')
|
||||
|
||||
def build_struct(struct):
|
||||
# debug print out lua nuke functions
|
||||
# output_nuke_struct(struct)
|
||||
# debug print out lua fuzz functions
|
||||
if len(sys.argv) >= 2 and sys.argv[1] == 'fuzz':
|
||||
output_fuzz_struct(struct)
|
||||
|
||||
sid = struct['identifier']
|
||||
|
||||
|
|
141
autogen/fuzz_template.lua
Normal file
141
autogen/fuzz_template.lua
Normal file
|
@ -0,0 +1,141 @@
|
|||
-- $[STRUCTS]
|
||||
|
||||
--------
|
||||
|
||||
function FuzzVec3s(struct)
|
||||
struct.x = 0
|
||||
struct.y = 0
|
||||
struct.z = 0
|
||||
end
|
||||
|
||||
function FuzzVec3f(struct)
|
||||
struct.x = 0
|
||||
struct.y = 0
|
||||
struct.z = 0
|
||||
end
|
||||
|
||||
function FuzzVec4s(struct)
|
||||
struct.x = 0
|
||||
struct.y = 0
|
||||
struct.z = 0
|
||||
struct.w = 0
|
||||
end
|
||||
|
||||
function FuzzVec4f(struct)
|
||||
struct.x = 0
|
||||
struct.y = 0
|
||||
struct.z = 0
|
||||
struct.w = 0
|
||||
end
|
||||
|
||||
function FuzzMat4(struct)
|
||||
struct.a = 0
|
||||
struct.b = 0
|
||||
struct.c = 0
|
||||
struct.d = 0
|
||||
struct.e = 0
|
||||
struct.f = 0
|
||||
struct.g = 0
|
||||
struct.h = 0
|
||||
struct.i = 0
|
||||
struct.j = 0
|
||||
struct.k = 0
|
||||
struct.l = 0
|
||||
struct.m = 0
|
||||
struct.n = 0
|
||||
struct.o = 0
|
||||
struct.p = 0
|
||||
end
|
||||
|
||||
--------
|
||||
|
||||
function rnd_string()
|
||||
t = { 0, "test", "this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string this is a very long string" }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_integer()
|
||||
t = { 0, math.random(1, 10), math.random(-2147483648, 2147483647) }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_number()
|
||||
t = { 0, math.random(), (math.random() - 0.5) * 2 * 4294967296 }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_Vec3s()
|
||||
t = { nil, { x = rnd_integer(), y = rnd_integer(), z = rnd_integer() } }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_Vec3f()
|
||||
t = { nil, { x = rnd_number(), y = rnd_number(), z = rnd_number() } }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_Vec4s()
|
||||
t = { nil, { x = rnd_integer(), y = rnd_integer(), z = rnd_integer(), w = rnd_integer() } }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_Vec4f()
|
||||
t = { nil, { x = rnd_number(), y = rnd_number(), z = rnd_number(), w = rnd_number() } }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_Mat4()
|
||||
t = { nil, { a = rnd_integer(), b = rnd_integer(), c = rnd_integer(), d = rnd_integer(), e = rnd_integer(), f = rnd_integer(), g = rnd_integer(), h = rnd_integer(), i = rnd_integer(), j = rnd_integer(), k = rnd_integer(), l = rnd_integer(), m = rnd_integer(), n = rnd_integer(), o = rnd_integer(), p = rnd_integer() } }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_Object()
|
||||
t = { nil, gMarioStates[0].marioObj, gMarioStates[1].marioObj }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_MarioState()
|
||||
t = { nil, gMarioStates[math.random(0, MAX_PLAYERS)] }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_NetworkPlayer()
|
||||
t = { nil, gNetworkPlayers[math.random(0, MAX_PLAYERS)] }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_SpawnParticlesInfo()
|
||||
t = { nil, obj_get_temp_spawn_particles_info(math.random(0, E_MODEL_MAX)) }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_BehaviorScript()
|
||||
t = { nil, get_behavior_from_id(math.random(0, id_bhv_max_count)) }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_Camera()
|
||||
t = { nil, gMarioStates[0].area.camera }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
function rnd_PlayerGeometry()
|
||||
t = { nil, {} }
|
||||
return t[math.random(#t)]
|
||||
end
|
||||
|
||||
--------
|
||||
|
||||
function fuzz_functions()
|
||||
-- $[FUNCS]
|
||||
end
|
||||
|
||||
--------
|
||||
|
||||
function fuzz_structs()
|
||||
end
|
||||
|
||||
hook_chat_command('fuzz-funcs', 'funcs', fuzz_functions)
|
||||
hook_chat_command('fuzz-structs', 'structs', fuzz_structs)
|
||||
fuzz_functions()
|
||||
print('!')
|
|
@ -52,7 +52,7 @@ u16 random_u16(void) {
|
|||
if (gOverrideRngPosition != NULL) {
|
||||
// override this function for rng positions
|
||||
gRandomSeed16 = gOverrideRngPosition->seed;
|
||||
} else if (gCurrentObject->oSyncID != 0) {
|
||||
} else if (gCurrentObject && gCurrentObject->oSyncID != 0) {
|
||||
// override this function for synchronized entities
|
||||
so = sync_object_get(gCurrentObject->oSyncID);
|
||||
if (so != NULL && so->o == gCurrentObject) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// chuckya.c.inc
|
||||
|
||||
void common_anchor_mario_behavior(f32 sp28, f32 sp2C, s32 sp30) {
|
||||
if (!o) { return; }
|
||||
for (s32 i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (!is_player_active(&gMarioStates[i])) { continue; }
|
||||
struct MarioState* marioState = &gMarioStates[i];
|
||||
|
@ -38,6 +39,7 @@ void bhv_chuckya_anchor_mario_loop(void) {
|
|||
}
|
||||
|
||||
s32 unknown_chuckya_function(s32 sp20, f32 sp24, f32 sp28, s32 sp2C) {
|
||||
if (!o) { return 0; }
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000;
|
||||
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
|
||||
|
@ -82,6 +84,7 @@ s32 approach_forward_vel(f32 *arr, f32 spC, f32 sp10) {
|
|||
}
|
||||
|
||||
void chuckya_act_0(void) {
|
||||
if (!o) { return; }
|
||||
struct Object* player = nearest_player_to_object(o);
|
||||
s32 angleToPlayer = player ? obj_angle_to_object(o, player) : 0;
|
||||
s32 sp3C = 0;
|
||||
|
@ -137,6 +140,7 @@ void chuckya_act_0(void) {
|
|||
}
|
||||
|
||||
void chuckya_act_1(void) {
|
||||
if (!o) { return; }
|
||||
if (o->oSubAction == 0) {
|
||||
if (cur_obj_init_animation_and_check_if_near_end(0))
|
||||
o->oSubAction++;
|
||||
|
@ -174,6 +178,7 @@ void chuckya_act_1(void) {
|
|||
}
|
||||
|
||||
void chuckya_act_3(void) {
|
||||
if (!o) { return; }
|
||||
o->oForwardVel = 0;
|
||||
o->oVelY = 0;
|
||||
cur_obj_init_animation_with_sound(4);
|
||||
|
@ -182,6 +187,7 @@ void chuckya_act_3(void) {
|
|||
}
|
||||
|
||||
void chuckya_act_2(void) {
|
||||
if (!o) { return; }
|
||||
if (o->oMoveFlags & (OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER | OBJ_MOVE_LANDED)) {
|
||||
obj_mark_for_deletion(o);
|
||||
obj_spawn_loot_yellow_coins(o, 5, 20.0f);
|
||||
|
@ -192,6 +198,7 @@ void chuckya_act_2(void) {
|
|||
void (*sChuckyaActions[])(void) = { chuckya_act_0, chuckya_act_1, chuckya_act_2, chuckya_act_3 };
|
||||
|
||||
void chuckya_move(void) {
|
||||
if (!o) { return; }
|
||||
cur_obj_update_floor_and_walls();
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sChuckyaActions);
|
||||
cur_obj_move_standard(-30);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// grand_star.c.inc
|
||||
|
||||
s32 arc_to_goal_pos(Vec3f empty, Vec3f pos, f32 yVel, f32 gravity) {
|
||||
if (!o) { return 0; }
|
||||
f32 dx = empty[0] - pos[0];
|
||||
f32 dz = empty[2] - pos[2];
|
||||
f32 planarDist = sqrtf(dx * dx + dz * dz);
|
||||
|
@ -13,6 +14,7 @@ s32 arc_to_goal_pos(Vec3f empty, Vec3f pos, f32 yVel, f32 gravity) {
|
|||
}
|
||||
|
||||
void grand_star_zero_velocity(void) {
|
||||
if (!o) { return; }
|
||||
o->oGravity = 0.0f;
|
||||
o->oVelY = 0.0f;
|
||||
o->oForwardVel = 0.0f;
|
||||
|
|
|
@ -25,7 +25,7 @@ void spawn_smoke_with_velocity(void) {
|
|||
|
||||
// TODO Fix name
|
||||
void clear_particle_flags(u32 flags) {
|
||||
if (o->parentObj) {
|
||||
if (o && o->parentObj) {
|
||||
o->parentObj->oActiveParticleFlags &= flags ^ -1; // Clear the flags given (could just be ~flags)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ void spawn_child_obj_relative(struct Object *parent, s16 xOffset, s16 yOffset, s
|
|||
s16 yawOffset, s16 rollOffset, s16 forwardVel,
|
||||
s32 model, const BehaviorScript *behavior) {
|
||||
struct Object *sp1C = spawn_object(parent, model, behavior);
|
||||
if (!sp1C) { return; }
|
||||
|
||||
sp1C->header.gfx.animInfo.animFrame = random_float() * 6.f;
|
||||
sp1C->oEndBirdUnk104 = sCutsceneVars[9].point[0];
|
||||
|
|
|
@ -13,6 +13,7 @@ struct ObjectHitbox sMetalBoxHitbox = {
|
|||
};
|
||||
|
||||
s32 check_if_moving_over_floor(f32 a0, f32 a1) {
|
||||
if (!o) { return 0; }
|
||||
struct Surface *sp24;
|
||||
f32 sp20 = o->oPosX + sins(o->oMoveAngleYaw) * a1;
|
||||
f32 floorHeight;
|
||||
|
|
|
@ -27,17 +27,19 @@ void spawn_star_number(void) {
|
|||
|
||||
// Check if the star already has a number
|
||||
struct Object *starNumber = obj_get_first_with_behavior_id(id_bhvStarNumber);
|
||||
u32 sanityDepth = 0;
|
||||
for (; starNumber; starNumber = obj_get_next_with_same_behavior_id(starNumber)) {
|
||||
if (++sanityDepth >= 10000) { break; }
|
||||
if (!starNumber || starNumber->parentObj == o) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If not, spawn a number
|
||||
if (!starNumber) {
|
||||
if (!starNumber && o) {
|
||||
starNumber = spawn_object(o, MODEL_NUMBER, bhvStarNumber);
|
||||
}
|
||||
if (starNumber) {
|
||||
if (starNumber && o) {
|
||||
starNumber->parentObj = o;
|
||||
starNumber->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; // to make sure it's updated even during time stop
|
||||
starNumber->oStarBehavior = (const void *) smlua_override_behavior(o->behavior);
|
||||
|
@ -208,6 +210,7 @@ struct Object *spawn_default_star(f32 x, f32 y, f32 z) {
|
|||
}
|
||||
|
||||
struct Object *spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
|
||||
if (!o) { return NULL; }
|
||||
u32 behParams = o->oBehParams;
|
||||
|
||||
// de-duplication checking
|
||||
|
@ -225,6 +228,7 @@ struct Object *spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z) {
|
|||
}
|
||||
|
||||
struct Object *spawn_no_exit_star(f32 x, f32 y, f32 z) {
|
||||
if (!o) { return NULL; }
|
||||
u32 behParams = o->oBehParams;
|
||||
|
||||
// de-duplication checking
|
||||
|
|
|
@ -9,12 +9,13 @@ s8 D_8032F948[] = { 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 2, 5, 1, 5, 1, 5, 1, 5,
|
|||
s8 *D_8032F96C[] = { D_8032F8F0, D_8032F924, D_8032F948 };
|
||||
|
||||
void tox_box_shake_screen(void) {
|
||||
if (o->oDistanceToMario < 3000.0f)
|
||||
if (o && o->oDistanceToMario < 3000.0f)
|
||||
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
||||
}
|
||||
|
||||
void tox_box_move(f32 forwardVel, f32 a1, s16 deltaPitch, s16 deltaRoll)
|
||||
{
|
||||
if (!o) { return; }
|
||||
o->oPosY = 99.41124 * sins((f32)(o->oTimer + 1) / 8 * 0x8000) + o->oHomeY + 3.0f;
|
||||
o->oForwardVel = forwardVel;
|
||||
o->oUnkC0 = a1;
|
||||
|
@ -47,6 +48,7 @@ void tox_box_act_7(void) {
|
|||
}
|
||||
|
||||
void tox_box_act_1(void) {
|
||||
if (!o) { return; }
|
||||
o->oForwardVel = 0.0f;
|
||||
if (o->oTimer == 0)
|
||||
tox_box_shake_screen();
|
||||
|
@ -56,16 +58,19 @@ void tox_box_act_1(void) {
|
|||
}
|
||||
|
||||
void tox_box_act_2(void) {
|
||||
if (!o) { return; }
|
||||
if (o->oTimer == 20)
|
||||
o->oAction = cur_obj_progress_direction_table();
|
||||
}
|
||||
|
||||
void tox_box_act_3(void) {
|
||||
if (!o) { return; }
|
||||
if (o->oTimer == 20)
|
||||
o->oAction = cur_obj_progress_direction_table();
|
||||
}
|
||||
|
||||
void tox_box_act_0(void) {
|
||||
if (!o) { return; }
|
||||
if (!BHV_ARR_CHECK(D_8032F96C, o->oBehParams2ndByte, s8*)) { return; }
|
||||
s8 *sp1C = D_8032F96C[o->oBehParams2ndByte];
|
||||
o->oAction = cur_obj_set_direction_table(sp1C);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
void play_penguin_walking_sound(s32 walk) {
|
||||
s32 sound;
|
||||
if (o->oSoundStateID == 0) {
|
||||
if (o && o->oSoundStateID == 0) {
|
||||
if (walk == PENGUIN_WALK_BABY)
|
||||
sound = SOUND_OBJ_BABY_PENGUIN_WALK;
|
||||
else // PENGUIN_WALK_BIG
|
||||
|
|
|
@ -5410,6 +5410,7 @@ void warp_camera(f32 displacementX, f32 displacementY, f32 displacementZ) {
|
|||
* unless smooth movement is off, in which case the y coordinate is simply set to `goal`
|
||||
*/
|
||||
void approach_camera_height(struct Camera *c, f32 goal, f32 inc) {
|
||||
if (!c) { return; }
|
||||
if (sStatusFlags & CAM_FLAG_SMOOTH_MOVEMENT) {
|
||||
if (c->pos[1] < goal) {
|
||||
if ((c->pos[1] += inc) > goal) {
|
||||
|
|
|
@ -106,7 +106,7 @@ struct Object *gMarioObjects[MAX_PLAYERS];
|
|||
* This object is used frequently in object behavior code, and so is often
|
||||
* aliased as "o".
|
||||
*/
|
||||
struct Object *gCurrentObject;
|
||||
struct Object *gCurrentObject = NULL;
|
||||
|
||||
/**
|
||||
* The next object behavior command to be executed.
|
||||
|
@ -350,6 +350,7 @@ s32 update_objects_starting_at(struct ObjectNode *objList, struct ObjectNode *fi
|
|||
if (!firstObj) { return 0; }
|
||||
|
||||
s32 count = 0;
|
||||
struct Object* prevObject = gCurrentObject;
|
||||
|
||||
while (objList != firstObj) {
|
||||
gCurrentObject = (struct Object *) firstObj;
|
||||
|
@ -362,6 +363,8 @@ s32 update_objects_starting_at(struct ObjectNode *objList, struct ObjectNode *fi
|
|||
count += 1;
|
||||
}
|
||||
|
||||
gCurrentObject = prevObject;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -378,6 +381,7 @@ s32 update_objects_during_time_stop(struct ObjectNode *objList, struct ObjectNod
|
|||
if (!firstObj) { return 0; }
|
||||
s32 count = 0;
|
||||
s32 unfrozen;
|
||||
struct Object* prevObject = gCurrentObject;
|
||||
|
||||
while (objList != firstObj) {
|
||||
gCurrentObject = (struct Object *) firstObj;
|
||||
|
@ -414,6 +418,8 @@ s32 update_objects_during_time_stop(struct ObjectNode *objList, struct ObjectNod
|
|||
count++;
|
||||
}
|
||||
|
||||
gCurrentObject = prevObject;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -440,6 +446,7 @@ s32 update_objects_in_list(struct ObjectNode *objList) {
|
|||
s32 unload_deactivated_objects_in_list(struct ObjectNode *objList) {
|
||||
if (!objList) { return 0; }
|
||||
struct ObjectNode *obj = objList->next;
|
||||
struct Object* prevObject = gCurrentObject;
|
||||
|
||||
while (objList != obj) {
|
||||
gCurrentObject = (struct Object *) obj;
|
||||
|
@ -458,6 +465,8 @@ s32 unload_deactivated_objects_in_list(struct ObjectNode *objList) {
|
|||
}
|
||||
}
|
||||
|
||||
gCurrentObject = prevObject;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -123,10 +123,12 @@ struct Object *obj_get_first(enum ObjectList objList) {
|
|||
|
||||
struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId) {
|
||||
const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
|
||||
u32 sanityDepth = 0;
|
||||
behavior = smlua_override_behavior(behavior);
|
||||
if (behavior) {
|
||||
enum ObjectList objList = get_object_list_from_behavior(behavior);
|
||||
for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) {
|
||||
if (++sanityDepth > 10000) { break; }
|
||||
if (obj->behavior == behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED) {
|
||||
return obj;
|
||||
}
|
||||
|
@ -137,10 +139,12 @@ struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId) {
|
|||
|
||||
struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value) {
|
||||
const BehaviorScript* behavior = get_behavior_from_id(behaviorId);
|
||||
u32 sanityDepth = 0;
|
||||
behavior = smlua_override_behavior(behavior);
|
||||
if (behavior) {
|
||||
enum ObjectList objList = get_object_list_from_behavior(behavior);
|
||||
for (struct Object *obj = obj_get_first(objList); obj != NULL; obj = obj_get_next(obj)) {
|
||||
if (++sanityDepth > 10000) { break; }
|
||||
if (obj->behavior == behavior && obj->activeFlags != ACTIVE_FLAG_DEACTIVATED && obj->OBJECT_FIELD_S32(fieldIndex) == value) {
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -216,9 +216,11 @@ void network_receive_level_macro(struct Packet* p) {
|
|||
u8 mask = ((o2->oBehParams2ndByte & GOOMBA_BP_TRIPLET_FLAG_MASK) >> 2);
|
||||
if (info & mask) {
|
||||
extern void mark_goomba_as_dead(void);
|
||||
struct Object* prevObject = gCurrentObject;
|
||||
gCurrentObject = o2;
|
||||
mark_goomba_as_dead();
|
||||
obj_mark_for_deletion(o2);
|
||||
gCurrentObject = prevObject;
|
||||
}
|
||||
}
|
||||
LOG_INFO("rx macro special: goomba triplet");
|
||||
|
|
|
@ -68,6 +68,7 @@ void network_receive_spawn_star(struct Packet* p) {
|
|||
}
|
||||
|
||||
void network_send_spawn_star_nle(struct Object* o, u32 params) {
|
||||
if (!o) { return; }
|
||||
u8 globalIndex = UNKNOWN_GLOBAL_INDEX;
|
||||
if (o->behavior == smlua_override_behavior(bhvMario)) {
|
||||
u8 localIndex = o->oBehParams - 1;
|
||||
|
|
Loading…
Reference in a new issue