Rewrote how players are initialized, stored, and displayed

Since the second-player code was the first code I wrote, it was implemented
poorly. At that point, I didn't know the code base at all and the way it was
written would prevent anyone from ever adding to those parts.

The rewrite allows me to use the default geo.inc.c file for Mario, and removes
all of the geo2.inc.c files. I no longer do a bunch of bit shifting to figure
out which player is being drawn in the rendering code.

I'm also now able to remove tons of duplicate code that exists just for the
remote player. The main player code is generic enough to support both indices.
A side-effect of the rewrite is I was able to remove many assumptions in the
code where two-players is assumed, but many other parts of the code still
assume two players.

This is a fairly major change that, if all goes well, will be completely
unnoticed by the player. However, I do expect new bugs to pop up in strange
places. Time will tell.
This commit is contained in:
MysterD 2020-09-06 18:52:52 -07:00
parent df7904e288
commit e0903003f4
50 changed files with 206 additions and 339 deletions

View File

@ -263,57 +263,6 @@ extern const Gfx mario_cap_wings_transparent[];
extern const Gfx mario_metal_cap_wings[];
extern const Gfx mario_metal_cap_wings_transparent[];
// mario (player 2)
extern const GeoLayout mario2_geo_face_and_wings[];
extern const GeoLayout mario2_geo_left_hand[];
extern const GeoLayout mario2_geo_right_hand[];
extern const GeoLayout mario2_geo_body[];
extern const GeoLayout mario2_geo_medium_poly_left_hand[];
extern const GeoLayout mario2_geo_medium_poly_right_hand[];
extern const GeoLayout mario2_geo_medium_poly_body[];
extern const GeoLayout mario2_geo_low_poly_face_and_wings[];
extern const GeoLayout mario2_geo_low_poly_left_hand[];
extern const GeoLayout mario2_geo_low_poly_right_hand[];
extern const GeoLayout mario2_geo_low_poly_body[];
extern const GeoLayout mario2_vanish_geo_face_and_wings[];
extern const GeoLayout mario2_vanish_geo_left_hand[];
extern const GeoLayout mario2_vanish_geo_right_hand[];
extern const GeoLayout mario2_vanish_geo_body[];
extern const GeoLayout mario2_vanish_geo_medium_poly_left_hand[];
extern const GeoLayout mario2_vanish_geo_medium_poly_right_hand[];
extern const GeoLayout mario2_vanish_geo_medium_poly_body[];
extern const GeoLayout mario2_vanish_geo_low_poly_face_and_wings[];
extern const GeoLayout mario2_vanish_geo_low_poly_left_hand[];
extern const GeoLayout mario2_vanish_geo_low_poly_right_hand[];
extern const GeoLayout mario2_vanish_geo_low_poly_body[];
extern const GeoLayout mario2_metal_geo_face_and_wings[];
extern const GeoLayout mario2_metal_geo_left_hand[];
extern const GeoLayout mario2_metal_geo_right_hand[];
extern const GeoLayout mario2_metal_geo_body[];
extern const GeoLayout mario2_metal_geo_medium_poly_left_hand[];
extern const GeoLayout mario2_metal_geo_medium_poly_right_hand[];
extern const GeoLayout mario2_metal_geo_medium_poly_body[];
extern const GeoLayout mario2_metal_geo_low_poly_face_and_wings[];
extern const GeoLayout mario2_metal_geo_low_poly_left_hand[];
extern const GeoLayout mario2_metal_geo_low_poly_right_hand[];
extern const GeoLayout mario2_metal_geo_low_poly_body[];
extern const GeoLayout mario2_metal_vanish_geo_face_and_wings[];
extern const GeoLayout mario2_metal_vanish_geo_left_hand[];
extern const GeoLayout mario2_metal_vanish_geo_right_hand[];
extern const GeoLayout mario2_metal_vanish_geo_body[];
extern const GeoLayout mario2_metal_vanish_geo_medium_poly_left_hand[];
extern const GeoLayout mario2_metal_vanish_geo_medium_poly_right_hand[];
extern const GeoLayout mario2_metal_vanish_geo_medium_poly_body[];
extern const GeoLayout mario2_metal_vanish_geo_low_poly_face_and_wings[];
extern const GeoLayout mario2_metal_vanish_geo_low_poly_left_hand[];
extern const GeoLayout mario2_metal_vanish_geo_low_poly_right_hand[];
extern const GeoLayout mario2_metal_vanish_geo_low_poly_body[];
extern const GeoLayout mario2_geo_load_body[];
extern const GeoLayout mario2_geo_load_medium_poly_body[];
extern const GeoLayout mario2_geo_load_low_poly_body[];
extern const GeoLayout mario2_geo_render_body[];
extern const GeoLayout mario2_geo[];
// luigi
#include "actors/luigi/geo_header.h"

View File

@ -3837,19 +3837,6 @@ const BehaviorScript bhvMario[] = {
END_LOOP(),
};
const BehaviorScript bhvMario2[] = {
BEGIN(OBJ_LIST_PLAYER),
ID(id_bhvMario2),
SET_INT(oIntangibleTimer, 0),
OR_INT(oFlags, OBJ_FLAG_0100),
OR_INT(oUnk94, 0x0001),
SET_HITBOX(/*Radius*/ 37, /*Height*/ 160),
SET_INTERACT_TYPE(INTERACT_PLAYER),
BEGIN_LOOP(),
CALL_NATIVE(bhv_mario2_update),
END_LOOP(),
};
const BehaviorScript bhvToadMessage[] = {
BEGIN(OBJ_LIST_GENACTOR),
ID(id_bhvToadMessage),

View File

@ -290,7 +290,6 @@ const BehaviorScript* gBehaviorTable[id_bhv_max_count] = {
[id_bhvSLWalkingPenguin] = bhvSLWalkingPenguin,
[id_bhvYellowBall] = bhvYellowBall,
[id_bhvMario] = bhvMario,
[id_bhvMario2] = bhvMario2,
[id_bhvToadMessage] = bhvToadMessage,
[id_bhvUnlockDoorStar] = bhvUnlockDoorStar,
[id_bhvRandomAnimatedTexture] = bhvRandomAnimatedTexture,

View File

@ -302,7 +302,6 @@ extern const BehaviorScript bhvSLSnowmanWind[];
extern const BehaviorScript bhvSLWalkingPenguin[];
extern const BehaviorScript bhvYellowBall[];
extern const BehaviorScript bhvMario[];
extern const BehaviorScript bhvMario2[];
extern const BehaviorScript bhvToadMessage[];
extern const BehaviorScript bhvUnlockDoorStar[];
extern const BehaviorScript bhvInstantActiveWarp[];

View File

@ -294,7 +294,6 @@ enum BehaviorId {
id_bhvSLWalkingPenguin,
id_bhvYellowBall,
id_bhvMario,
id_bhvMario2,
id_bhvToadMessage,
id_bhvUnlockDoorStar,
id_bhvRandomAnimatedTexture,

View File

@ -188,11 +188,6 @@
CMD_W(behArg), \
CMD_PTR(beh)
#define MARIO2(unk3, behArg, beh) \
CMD_BBBB(0x3F, 0x0C, 0x00, unk3), \
CMD_W(behArg), \
CMD_PTR(beh)
#define WARP_NODE(id, destLevel, destArea, destNode, flags) \
CMD_BBBB(0x26, 0x08, id, destLevel), \
CMD_BBBB(destArea, destNode, flags, 0x00)

View File

@ -382,13 +382,11 @@ struct MarioState
// HOWEVER, simply increasing this to 3 will not magically work
// many things will have to be overhauled!
#define MAX_PLAYERS 2
// still deciding to increase it?
// are you still deciding to increase it?
// networking will have to be rewritten to have more than one destination. 'reliable' messages would need to be sent per-player
// things that base priority on whether they are the host or not would need priority based on player index instead
// player 2's mario2.geo file will need a different one for player 3, 4, 5, etc... and will need values within it adjusted in a similar manner (diff them)
// read all of the code surrounding a search through the entire codebase of the following:
// gMarioObject
// gMario2Object
// gMarioStates[0]
// gMarioStates[1]
// two-player hack

View File

@ -89,7 +89,6 @@ const LevelScript level_bbh_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_10),
JUMP_LINK(script_func_global_18),

View File

@ -53,7 +53,6 @@ const LevelScript level_bitdw_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_12),
JUMP_LINK(script_func_global_18),
JUMP_LINK(script_func_global_1),

View File

@ -64,7 +64,6 @@ const LevelScript level_bitfs_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_3),
JUMP_LINK(script_func_global_18),
JUMP_LINK(script_func_global_1),

View File

@ -54,7 +54,6 @@ const LevelScript level_bits_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_15),
JUMP_LINK(script_func_global_1),
LOAD_MODEL_FROM_GEO(MODEL_LEVEL_GEOMETRY_03, bits_geo_000430),

View File

@ -66,7 +66,6 @@ const LevelScript level_bob_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_4),
JUMP_LINK(script_func_global_15),

View File

@ -24,7 +24,6 @@ const LevelScript level_bowser_1_entry[] = {
LOAD_RAW( /*seg*/ 0x0D, _group12_geoSegmentRomStart, _group12_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_13),
LOAD_MODEL_FROM_GEO(MODEL_LEVEL_GEOMETRY_03, bowser_1_yellow_sphere_geo),

View File

@ -34,7 +34,6 @@ const LevelScript level_bowser_2_entry[] = {
LOAD_RAW( /*seg*/ 0x0D, _group12_geoSegmentRomStart, _group12_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_13),
LOAD_MODEL_FROM_GEO(MODEL_BOWSER_2_TILTING_ARENA, bowser_2_geo_000170),

View File

@ -42,7 +42,6 @@ const LevelScript level_bowser_3_entry[] = {
LOAD_MIO0(/*seg*/ 0x0A, _bits_skybox_mio0SegmentRomStart, _bits_skybox_mio0SegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_13),
LOAD_MODEL_FROM_GEO(MODEL_BOWSER_3_FALLING_PLATFORM_1, bowser_3_geo_000290),
LOAD_MODEL_FROM_GEO(MODEL_BOWSER_3_FALLING_PLATFORM_2, bowser_3_geo_0002A8),

View File

@ -40,7 +40,6 @@ const LevelScript level_castle_courtyard_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_10),
LOAD_MODEL_FROM_GEO(MODEL_COURTYARD_SPIKY_TREE, spiky_tree_geo),

View File

@ -105,7 +105,6 @@ const LevelScript level_castle_grounds_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_11),
JUMP_LINK(script_func_global_16),

View File

@ -227,7 +227,6 @@ const LevelScript level_castle_inside_entry[] = {
LOAD_RAW( /*seg*/ 0x0D, _group15_geoSegmentRomStart, _group15_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_16),
LOAD_MODEL_FROM_GEO(MODEL_CASTLE_BOWSER_TRAP, castle_geo_000F18),
LOAD_MODEL_FROM_GEO(MODEL_CASTLE_WATER_LEVEL_PILLAR, castle_geo_001940),

View File

@ -63,7 +63,6 @@ const LevelScript level_ccm_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_8),
JUMP_LINK(script_func_global_17),

View File

@ -40,7 +40,6 @@ const LevelScript level_cotmc_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_9),
JUMP_LINK(script_func_global_18),
JUMP_LINK(script_func_global_1),

View File

@ -74,7 +74,6 @@ const LevelScript level_ddd_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_5),
JUMP_LINK(script_func_global_14),

View File

@ -80,7 +80,6 @@ const LevelScript level_hmc_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_7),
JUMP_LINK(script_func_global_18),

View File

@ -126,7 +126,6 @@ const LevelScript level_jrb_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_5),
JUMP_LINK(script_func_global_14),

View File

@ -130,7 +130,6 @@ const LevelScript level_lll_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_3),
JUMP_LINK(script_func_global_18),

View File

@ -25,7 +25,6 @@ const LevelScript level_pss_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_9),

View File

@ -79,7 +79,6 @@ const LevelScript level_rr_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_12),
JUMP_LINK(script_func_global_1),
LOAD_MODEL_FROM_GEO(MODEL_LEVEL_GEOMETRY_03, rr_geo_000660),

View File

@ -38,7 +38,6 @@ const LevelScript level_sa_entry[] = {
LOAD_RAW( /*seg*/ 0x0D, _group13_geoSegmentRomStart, _group13_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_5),
JUMP_LINK(script_func_global_14),

View File

@ -56,7 +56,6 @@ const LevelScript level_sl_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_8),
JUMP_LINK(script_func_global_17),

View File

@ -78,7 +78,6 @@ const LevelScript level_ssl_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_6),
LOAD_MODEL_FROM_GEO(MODEL_SSL_PALM_TREE, palm_tree_geo),

View File

@ -90,7 +90,6 @@ const LevelScript level_thi_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_12),
JUMP_LINK(script_func_global_15),

View File

@ -37,7 +37,6 @@ const LevelScript level_totwc_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_9),
LOAD_MODEL_FROM_GEO(MODEL_LEVEL_GEOMETRY_03, totwc_geo_000160),

View File

@ -41,7 +41,6 @@ const LevelScript level_ttc_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_2),
LOAD_MODEL_FROM_GEO(MODEL_TTC_ROTATING_CUBE, ttc_geo_000240),

View File

@ -91,7 +91,6 @@ const LevelScript level_ttm_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_7),
LOAD_MODEL_FROM_GEO(MODEL_TTM_SLIDE_EXIT_PODIUM, ttm_geo_000DF4),

View File

@ -47,7 +47,6 @@ const LevelScript level_vcutm_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_9),
LOAD_MODEL_FROM_GEO(MODEL_VCUTM_SEESAW_PLATFORM, vcutm_geo_0001F0),

View File

@ -80,7 +80,6 @@ const LevelScript level_wdw_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_2),
JUMP_LINK(script_func_global_14),

View File

@ -104,7 +104,6 @@ const LevelScript level_wf_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_2),
JUMP_LINK(script_func_global_15),

View File

@ -43,7 +43,6 @@ const LevelScript level_wmotr_entry[] = {
LOAD_RAW( /*seg*/ 0x0F, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
MARIO2(/*model*/ MODEL_MARIO2, /*behParam*/ 0x00000002, /*beh*/ bhvMario2),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_3),
JUMP_LINK(script_func_global_18),

View File

@ -437,7 +437,7 @@ static void level_cmd_init_mario(void) {
spawnInfo->activeAreaIndex = -1;
spawnInfo->areaIndex = 0;
spawnInfo->behaviorArg = i;
spawnInfo->behaviorArg = (u32)i | (1 << 31);
spawnInfo->behaviorScript = behaviorScript;
spawnInfo->unk18 = unk18;
spawnInfo->next = NULL;
@ -451,21 +451,6 @@ static void level_cmd_init_mario(void) {
sCurrentCmd = CMD_NEXT;
}
static void level_cmd_init_mario2(void) {
vec3s_set(gPlayerSpawnInfos[1].startPos, 0, 0, 0);
vec3s_set(gPlayerSpawnInfos[1].startAngle, 0, 0, 0);
gPlayerSpawnInfos[1].activeAreaIndex = -1;
gPlayerSpawnInfos[1].areaIndex = 0;
gPlayerSpawnInfos[1].behaviorArg = CMD_GET(u32, 4);
gPlayerSpawnInfos[1].behaviorScript = CMD_GET(void *, 8);
gPlayerSpawnInfos[1].unk18 = gLoadedGraphNodes[CMD_GET(u8, 3)];
gPlayerSpawnInfos[1].next = NULL;
gMarioSpawnInfo->next = &gPlayerSpawnInfos[1];
sCurrentCmd = CMD_NEXT;
}
static void level_cmd_place_object(void) {
u8 val7 = 1 << (gCurrActNum - 1);
u16 model;
@ -887,7 +872,6 @@ static void (*LevelScriptJumpTable[])(void) = {
/*3C*/ level_cmd_get_or_set_var,
/*3D*/ level_cmd_advdemo,
/*3E*/ level_cmd_cleardemoptr,
/*3F*/ level_cmd_init_mario2,
};
struct LevelCommand *level_script_execute(struct LevelCommand *cmd) {

View File

@ -16,6 +16,7 @@
#include "surface_load.h"
#include "game/game_init.h"
#include "engine/math_util.h"
#include "game/level_update.h"
s32 unused8038BE90;
@ -765,17 +766,15 @@ void load_object_collision_model(void) {
s16 vertexData[600];
s16* collisionData = gCurrentObject->collisionData;
f32 marioDist = gCurrentObject->oDistanceToMario;
f32 mario2Dist = gCurrentObject->oDistanceToMario;
f32 tangibleDist = gCurrentObject->oCollisionDistance;
// On an object's first frame, the distance is set to 19000.0f.
// If the distance hasn't been updated, update it now.
if (gCurrentObject->oDistanceToMario == 19000.0f) {
marioDist = dist_between_objects(gCurrentObject, gMarioObject);
u8 anyPlayerInTangibleRange = FALSE;
u8 anyPlayerInDrawRange = FALSE;
for (int i = 0; i < MAX_PLAYERS; i++) {
f32 dist = dist_between_objects(gCurrentObject, gMarioStates[i].marioObj);
if (dist < tangibleDist) { anyPlayerInTangibleRange = TRUE; }
if (dist < gCurrentObject->oDrawingDistance) { anyPlayerInDrawRange = TRUE; }
}
// two-player hack
mario2Dist = dist_between_objects(gCurrentObject, gMario2Object);
// If the object collision is supposed to be loaded more than the
// drawing distance of 4000, extend the drawing range.
@ -785,7 +784,7 @@ void load_object_collision_model(void) {
// Update if no Time Stop, in range, and in the current room.
if (!(gTimeStopState & TIME_STOP_ACTIVE)
&& (marioDist < tangibleDist || mario2Dist < tangibleDist)
&& (anyPlayerInTangibleRange)
&& !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
collisionData++;
transform_object_vertices(&collisionData, vertexData);
@ -797,7 +796,7 @@ void load_object_collision_model(void) {
}
#ifndef NODRAWINGDISTANCE
if (marioDist < gCurrentObject->oDrawingDistance) {
if (anyPlayerInDrawRange) {
#endif
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
#ifndef NODRAWINGDISTANCE

View File

@ -434,7 +434,6 @@ u8 sFramesSinceCutsceneEnded = 0;
*/
u8 sCutsceneDialogResponse = 0;
struct PlayerCameraState *sMarioCamState = &gPlayerCameraState[0];
struct PlayerCameraState *sMario2CamState = &gPlayerCameraState[1];
u32 unused8032D008 = 0;
Vec3f sFixedModeBasePosition = { 646.0f, 143.0f, -1513.0f };
Vec3f sUnusedModeBasePosition_2 = { 646.0f, 143.0f, -1513.0f };
@ -3297,8 +3296,6 @@ void reset_camera(struct Camera *c) {
c->doorStatus = DOOR_DEFAULT;
sMarioCamState->headRotation[0] = 0;
sMarioCamState->headRotation[1] = 0;
sMario2CamState->headRotation[0] = 0;
sMario2CamState->headRotation[1] = 0;
sMarioCamState->cameraEvent = 0;
sMarioCamState->usedObj = NULL;
gLakituState.shakeMagnitude[0] = 0;

View File

@ -740,18 +740,11 @@ u32 take_damage_from_interact_object(struct MarioState *m) {
return damage;
}
int get_invincibility_flag(struct MarioState *m) {
// two-player hack
return (m == &gMarioStates[0])
? INT_SUBTYPE_DELAY_INVINCIBILITY
: INT_SUBTYPE_DELAY_INVINCIBILITY_MARIO2;
}
u32 take_damage_and_knock_back(struct MarioState *m, struct Object *o) {
u32 damage;
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
&& !(o->oInteractionSubtype & get_invincibility_flag(m))) {
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO;
m->interactObj = o;
@ -1208,7 +1201,7 @@ u32 interact_player(struct MarioState* m, UNUSED u32 interactType, struct Object
// attacked
u8 isInCutscene = ((m->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE) || ((m2->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE);
u8 isInvulnerable = (m2->action & ACT_FLAG_INVULNERABLE) || m2->invincTimer != 0 || m2->hurtCounter != 0 || isInCutscene;
if ((interaction & INT_ANY_ATTACK) && !isInvulnerable) {
if ((interaction & INT_ANY_ATTACK) && !(interaction & INT_HIT_FROM_ABOVE) && !isInvulnerable) {
if (m->action == ACT_GROUND_POUND) {
m2->squishTimer = max(m2->squishTimer, 20);
}
@ -1310,7 +1303,7 @@ u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object
u32 burningAction = ACT_BURNING_JUMP;
if (!sInvulnerable && !(m->flags & MARIO_METAL_CAP) && !(m->flags & MARIO_VANISH_CAP)
&& !(o->oInteractionSubtype & get_invincibility_flag(m))) {
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
queue_rumble_data_mario(m, 5, 80);
o->oInteractStatus = INT_STATUS_INTERACTED;
@ -1353,7 +1346,7 @@ u32 interact_snufit_bullet(struct MarioState *m, UNUSED u32 interactType, struct
}
}
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE;
}
@ -1369,7 +1362,7 @@ u32 interact_clam_or_bubba(struct MarioState *m, UNUSED u32 interactType, struct
return TRUE;
}
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE;
}
return TRUE;
@ -1401,7 +1394,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
}
else if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
&& !(o->oInteractionSubtype & get_invincibility_flag(m))) {
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
o->oInteractStatus = INT_STATUS_INTERACTED;
m->invincTimer = 2;
@ -1421,7 +1414,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
&& !(o->oInteractionSubtype & get_invincibility_flag(m))) {
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
u32 actionArg = (m->action & (ACT_FLAG_AIR | ACT_FLAG_ON_POLE | ACT_FLAG_HANGING)) == 0;
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO;
@ -1439,14 +1432,14 @@ u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object
}
}
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE;
}
return FALSE;
}
static u32 interact_stub(UNUSED struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE;
}
return FALSE;
@ -1457,7 +1450,7 @@ u32 interact_mr_blizzard(struct MarioState *m, UNUSED u32 interactType, struct O
return TRUE;
}
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE;
}
@ -1499,7 +1492,7 @@ u32 interact_hit_from_below(struct MarioState *m, UNUSED u32 interactType, struc
return TRUE;
}
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE;
}
return FALSE;
@ -1534,7 +1527,7 @@ u32 interact_bounce_top(struct MarioState *m, UNUSED u32 interactType, struct Ob
return TRUE;
}
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE;
}
return FALSE;
@ -1550,7 +1543,7 @@ u32 interact_unknown_08(struct MarioState *m, UNUSED u32 interactType, struct Ob
return TRUE;
}
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE;
}
return FALSE;
@ -1561,7 +1554,7 @@ u32 interact_damage(struct MarioState *m, UNUSED u32 interactType, struct Object
return TRUE;
}
if (!(o->oInteractionSubtype & get_invincibility_flag(m))) {
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE;
}
return FALSE;

View File

@ -44,7 +44,6 @@
// Damaging interactions
#define INT_SUBTYPE_DELAY_INVINCIBILITY 0x00000002
#define INT_SUBTYPE_DELAY_INVINCIBILITY_MARIO2 0x00008000
#define INT_SUBTYPE_BIG_KNOCKBACK 0x00000008 /* Used by Bowser, sets Mario's forward velocity to 40 on hit */
// INTERACT_GRABBABLE

View File

@ -145,7 +145,7 @@ struct CreditsEntry sCreditsSequence[] = {
{ LEVEL_NONE, 0, 1, 0, { 0, 0, 0 }, NULL },
};
struct MarioState gMarioStates[MAX_PLAYERS];
struct MarioState gMarioStates[MAX_PLAYERS] = { 0 };
struct HudDisplay gHudDisplay;
s16 sCurrPlayMode;
u16 D_80339ECA;

View File

@ -1969,101 +1969,90 @@ s32 execute_mario_action(UNUSED struct Object *o) {
* INITIALIZATION *
**************************************************/
void init_mario(void) {
gFreezeMario = 0;
gInsidePainting = false;
bool isLocal = (gMarioState == &gMarioStates[0]);
if (isLocal && gMarioObject == NULL) { goto skippy; }
if (!isLocal && gMario2Object == NULL) { goto skippy; }
// two-player hack
gMarioState->playerIndex = isLocal ? 0 : 1;
static void init_single_mario(struct MarioState* m) {
Vec3s capPos;
struct Object* capObject;
u16 playerIndex = m->playerIndex;
struct SpawnInfo* spawnInfo = &gPlayerSpawnInfos[playerIndex];
unused80339F10 = 0;
gMarioState->actionTimer = 0;
gMarioState->framesSinceA = 0xFF;
gMarioState->framesSinceB = 0xFF;
m->actionTimer = 0;
m->framesSinceA = 0xFF;
m->framesSinceB = 0xFF;
gMarioState->invincTimer = 0;
m->invincTimer = 0;
if (save_file_get_flags()
& (SAVE_FLAG_CAP_ON_GROUND | SAVE_FLAG_CAP_ON_KLEPTO | SAVE_FLAG_CAP_ON_UKIKI
| SAVE_FLAG_CAP_ON_MR_BLIZZARD)) {
gMarioState->flags = 0;
if (save_file_get_flags() & (SAVE_FLAG_CAP_ON_GROUND | SAVE_FLAG_CAP_ON_KLEPTO | SAVE_FLAG_CAP_ON_UKIKI | SAVE_FLAG_CAP_ON_MR_BLIZZARD)) {
m->flags = 0;
} else {
gMarioState->flags = (MARIO_CAP_ON_HEAD | MARIO_NORMAL_CAP);
m->flags = (MARIO_CAP_ON_HEAD | MARIO_NORMAL_CAP);
}
gMarioState->forwardVel = 0.0f;
gMarioState->squishTimer = 0;
m->forwardVel = 0.0f;
m->squishTimer = 0;
gMarioState->hurtCounter = 0;
gMarioState->healCounter = 0;
m->hurtCounter = 0;
m->healCounter = 0;
gMarioState->capTimer = 0;
gMarioState->quicksandDepth = 0.0f;
m->capTimer = 0;
m->quicksandDepth = 0.0f;
gMarioState->heldObj = NULL;
gMarioState->heldByObj = NULL;
gMarioState->riddenObj = NULL;
gMarioState->usedObj = NULL;
gMarioState->bubbleObj = NULL;
m->heldObj = NULL;
m->heldByObj = NULL;
m->riddenObj = NULL;
m->usedObj = NULL;
m->bubbleObj = NULL;
gMarioState->waterLevel =
find_water_level(gMarioSpawnInfo->startPos[0], gMarioSpawnInfo->startPos[2]);
m->waterLevel = find_water_level(spawnInfo->startPos[0], spawnInfo->startPos[2]);
gMarioState->area = gCurrentArea;
// two-player hack
gMarioState->marioObj = isLocal ? gMarioObject : gMario2Object;
gMarioState->marioObj->header.gfx.unk38.animID = -1;
vec3s_copy(gMarioState->faceAngle, gMarioSpawnInfo->startAngle);
vec3s_set(gMarioState->angleVel, 0, 0, 0);
vec3s_to_vec3f(gMarioState->pos, gMarioSpawnInfo->startPos);
vec3f_set(gMarioState->vel, 0, 0, 0);
m->area = gCurrentArea;
m->marioObj = gMarioObjects[m->playerIndex];
if (m->marioObj == NULL) { return; }
m->marioObj->header.gfx.unk38.animID = -1;
vec3s_copy(m->faceAngle, spawnInfo->startAngle);
vec3s_set(m->angleVel, 0, 0, 0);
vec3s_to_vec3f(m->pos, spawnInfo->startPos);
vec3f_set(m->vel, 0, 0, 0);
// two-player hack
u8 isLocal = (m->playerIndex == 0);
if ((gNetworkType == NT_CLIENT && isLocal) || (gNetworkType == NT_SERVER && !isLocal)) {
gMarioState->pos[0] += 50.0f * coss(gMarioState->faceAngle[1]);
gMarioState->pos[2] += 50.0f * sins(gMarioState->faceAngle[1]);
} else {
gMarioState->pos[0] -= 50.0f * coss(gMarioState->faceAngle[1]);
gMarioState->pos[2] -= 50.0f * sins(gMarioState->faceAngle[1]);
m->pos[0] += 50.0f * coss(m->faceAngle[1]);
m->pos[2] += 50.0f * sins(m->faceAngle[1]);
}
else {
m->pos[0] -= 50.0f * coss(m->faceAngle[1]);
m->pos[2] -= 50.0f * sins(m->faceAngle[1]);
}
gMarioState->floorHeight =
find_floor(gMarioState->pos[0], gMarioState->pos[1], gMarioState->pos[2], &gMarioState->floor);
m->floorHeight = find_floor(m->pos[0], m->pos[1], m->pos[2], &m->floor);
if (gMarioState->pos[1] < gMarioState->floorHeight) {
gMarioState->pos[1] = gMarioState->floorHeight;
if (m->pos[1] < m->floorHeight) {
m->pos[1] = m->floorHeight;
}
gMarioState->marioObj->header.gfx.pos[1] = gMarioState->pos[1];
m->marioObj->header.gfx.pos[1] = m->pos[1];
gMarioState->action =
(gMarioState->pos[1] <= (gMarioState->waterLevel - 100)) ? ACT_WATER_IDLE : ACT_IDLE;
m->action = (m->pos[1] <= (m->waterLevel - 100)) ? ACT_WATER_IDLE : ACT_IDLE;
mario_reset_bodystate(gMarioState);
update_mario_info_for_cam(gMarioState);
gMarioState->marioBodyState->punchState = 0;
mario_reset_bodystate(m);
update_mario_info_for_cam(m);
m->marioBodyState->punchState = 0;
gMarioState->marioObj->oPosX = gMarioState->pos[0];
gMarioState->marioObj->oPosY = gMarioState->pos[1];
gMarioState->marioObj->oPosZ = gMarioState->pos[2];
m->marioObj->oPosX = m->pos[0];
m->marioObj->oPosY = m->pos[1];
m->marioObj->oPosZ = m->pos[2];
gMarioState->marioObj->oMoveAnglePitch = gMarioState->faceAngle[0];
gMarioState->marioObj->oMoveAngleYaw = gMarioState->faceAngle[1];
gMarioState->marioObj->oMoveAngleRoll = gMarioState->faceAngle[2];
m->marioObj->oMoveAnglePitch = m->faceAngle[0];
m->marioObj->oMoveAngleYaw = m->faceAngle[1];
m->marioObj->oMoveAngleRoll = m->faceAngle[2];
vec3f_copy(gMarioState->marioObj->header.gfx.pos, gMarioState->pos);
vec3s_set(gMarioState->marioObj->header.gfx.angle, 0, gMarioState->faceAngle[1], 0);
vec3f_copy(m->marioObj->header.gfx.pos, m->pos);
vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0);
if (save_file_get_cap_pos(capPos)) {
capObject = spawn_object(gMarioState->marioObj, MODEL_MARIOS_CAP, bhvNormalCap);
capObject = spawn_object(m->marioObj, MODEL_MARIOS_CAP, bhvNormalCap);
capObject->oPosX = capPos[0];
capObject->oPosY = capPos[1];
@ -2075,46 +2064,50 @@ void init_mario(void) {
}
// set mario/luigi model
gMarioState->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[(gNetworkType == NT_SERVER) ? MODEL_MARIO : MODEL_LUIGI];
skippy:
// two-player hack
if (isLocal) {
gMarioState = &gMarioStates[1];
init_mario();
gMarioState = &gMarioStates[0];
m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[(gNetworkType == NT_SERVER) ? MODEL_MARIO : MODEL_LUIGI];
} else {
m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[(gNetworkType == NT_CLIENT) ? MODEL_MARIO : MODEL_LUIGI];
}
}
void init_mario(void) {
gFreezeMario = 0;
gInsidePainting = false;
for (int i = 0; i < MAX_PLAYERS; i++) {
gMarioStates[i].playerIndex = i;
init_single_mario(&gMarioStates[i]);
}
}
static void init_mario_single_from_save_file(struct MarioState* m, u16 index) {
// two-player hack
m->playerIndex = index;
m->flags = 0;
m->action = 0;
m->spawnInfo = &gPlayerSpawnInfos[index];
m->statusForCamera = &gPlayerCameraState[index];
m->marioBodyState = &gBodyStates[index];
m->controller = &gControllers[index];
m->animation = &D_80339D10[index];
m->numCoins = 0;
m->numStars = save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1);
m->numKeys = 0;
m->numLives = 3;
m->health = 0x880;
m->prevNumStarsForDialog = m->numStars;
m->unkB0 = 0xBD;
}
void init_mario_from_save_file(void) {
bool isLocal = (gMarioState == &gMarioStates[0]);
// two-player hack
gMarioState->playerIndex = isLocal ? 0 : 1;
gMarioState->flags = 0;
gMarioState->action = 0;
int i = isLocal ? 0 : 1;
gMarioState->spawnInfo = &gPlayerSpawnInfos[i];
gMarioState->statusForCamera = &gPlayerCameraState[i];
gMarioState->marioBodyState = &gBodyStates[i];
gMarioState->controller = &gControllers[i];
gMarioState->animation = &D_80339D10[i];
gMarioState->numCoins = 0;
gMarioState->numStars =
save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1);
gMarioState->numKeys = 0;
gMarioState->numLives = 3;
gMarioState->health = 0x880;
gMarioState->prevNumStarsForDialog = gMarioState->numStars;
gMarioState->unkB0 = 0xBD;
for (int i = 0; i < MAX_PLAYERS; i++) {
init_mario_single_from_save_file(&gMarioStates[i], i);
}
gHudDisplay.coins = 0;
gHudDisplay.wedges = 8;
if (isLocal) {
gMarioState = &gMarioStates[1];
init_mario_from_save_file();
gMarioState = &gMarioStates[0];
}
}

View File

@ -318,6 +318,12 @@ static Gfx *make_gfx_mario_alpha(struct GraphNodeGenerated *node, s16 alpha) {
return gfxHead;
}
struct MarioState* geo_get_mario_state(void) {
return (gCurGraphNodeProcessingObject == NULL)
? &gMarioStates[0]
: &gMarioStates[gCurGraphNodeProcessingObject->oBehParams - 1];
}
struct MarioBodyState* geo_get_body_state(void) {
return (gCurGraphNodeProcessingObject == NULL)
? &gBodyStates[0]
@ -546,11 +552,12 @@ Gfx* geo_switch_mario_cap_on_off(s32 callContext, struct GraphNode* node, UNUSED
Gfx* geo_mario_rotate_wing_cap_wings(s32 callContext, struct GraphNode* node, UNUSED Mat4* c) {
s16 rotX;
struct GraphNodeGenerated* asGenerated = (struct GraphNodeGenerated*) node;
struct MarioBodyState* bodyState = geo_get_body_state();
if (callContext == GEO_CONTEXT_RENDER) {
struct GraphNodeRotation* rotNode = (struct GraphNodeRotation*) node->next;
if (gBodyStates[asGenerated->parameter >> 1].wingFlutter == FALSE) {
if (bodyState->wingFlutter == FALSE) {
rotX = (coss((gAreaUpdateCounter & 0xF) << 12) + 1.0f) * 4096.0f;
}
else {
@ -572,7 +579,7 @@ Gfx* geo_mario_rotate_wing_cap_wings(s32 callContext, struct GraphNode* node, UN
Gfx* geo_switch_mario_hand_grab_pos(s32 callContext, struct GraphNode* b, Mat4* mtx) {
struct GraphNodeHeldObject* asHeldObj = (struct GraphNodeHeldObject*) b;
Mat4* curTransform = mtx;
struct MarioState* marioState = &gMarioStates[asHeldObj->playerIndex];
struct MarioState* marioState = geo_get_mario_state();
if (callContext == GEO_CONTEXT_RENDER) {
asHeldObj->objNode = NULL;
@ -615,7 +622,8 @@ Gfx* geo_switch_mario_hand_grab_pos(s32 callContext, struct GraphNode* b, Mat4*
*/
Gfx* geo_render_mirror_mario(s32 callContext, struct GraphNode* node, UNUSED Mat4* c) {
f32 mirroredX;
struct Object* mario = gMarioStates->marioObj;
struct MarioState* marioState = geo_get_mario_state();
struct Object* mario = marioState->marioObj;
switch (callContext) {
case GEO_CONTEXT_CREATE:

View File

@ -561,7 +561,7 @@ static s32 obj_resolve_object_collisions(s32 *targetYaw) {
if (o->numCollidedObjs != 0) {
otherObject = o->collidedObjs[0];
if (otherObject != gMarioObject && otherObject != gMario2Object) {
if (!(otherObject->oInteractType & INTERACT_PLAYER)) {
//! If one object moves after collisions are detected and this code
// runs, the objects can move toward each other (transport cloning)

View File

@ -78,6 +78,11 @@ int detect_object_hitbox_overlap(struct Object *a, struct Object *b) {
f32 collisionRadius = a->hitboxRadius + b->hitboxRadius;
f32 distance = sqrtf(dx * dx + dz * dz);
// do not check for player interactions here
if ((a->oInteractType & INTERACT_PLAYER) && (b->oInteractType & INTERACT_PLAYER)) {
return 0;
}
if (collisionRadius > distance) {
f32 sp20 = a->hitboxHeight + sp3C;
f32 sp1C = b->hitboxHeight + sp38;
@ -115,9 +120,9 @@ int detect_object_hurtbox_overlap(struct Object *a, struct Object *b) {
f32 sp28 = a->hurtboxRadius + b->hurtboxRadius;
f32 sp24 = sqrtf(sp34 * sp34 + sp2C * sp2C);
// two-player hack
if (a == gMarioObject) { b->oInteractionSubtype |= INT_SUBTYPE_DELAY_INVINCIBILITY; }
if (a == gMario2Object) { b->oInteractionSubtype |= INT_SUBTYPE_DELAY_INVINCIBILITY_MARIO2; }
if ((a->oInteractType & INTERACT_PLAYER) && a->oBehParams == 1) {
b->oInteractionSubtype |= INT_SUBTYPE_DELAY_INVINCIBILITY;
}
if (sp28 > sp24) {
f32 sp20 = a->hitboxHeight + sp3C;
@ -129,9 +134,9 @@ int detect_object_hurtbox_overlap(struct Object *a, struct Object *b) {
if (sp20 < sp38) {
return 0;
}
// two-player hack
if (a == gMarioObject) { b->oInteractionSubtype &= ~INT_SUBTYPE_DELAY_INVINCIBILITY; }
if (a == gMario2Object) { b->oInteractionSubtype &= ~INT_SUBTYPE_DELAY_INVINCIBILITY_MARIO2; }
if ((a->oInteractType & INTERACT_PLAYER) && a->oBehParams == 1) {
b->oInteractionSubtype &= ~INT_SUBTYPE_DELAY_INVINCIBILITY;
}
return 1;
}

View File

@ -2904,7 +2904,7 @@ s32 obj_attack_collided_from_other_object(struct Object *obj) {
if (numCollidedObjs != 0) {
other = obj->collidedObjs[0];
if (other != gMarioObject && other != gMario2Object) {
if (!(other->oInteractType & INTERACT_PLAYER)) {
other->oInteractStatus |= ATTACK_PUNCH | INT_STATUS_WAS_ATTACKED | INT_STATUS_INTERACTED
| INT_STATUS_TOUCHED_BOB_OMB;
touchedOtherObject = TRUE;

View File

@ -96,7 +96,7 @@ struct Object *gMarioObject;
* second player. This is speculation, based on its position and its usage in
* shadow.c.
*/
struct Object *gMario2Object;
struct Object *gMarioObjects[MAX_PLAYERS];
/**
* The object whose behavior script is currently being updated.
@ -222,21 +222,14 @@ struct ParticleProperties sParticleTypes[] = {
* Copy position, velocity, and angle variables from MarioState to the Mario
* object.
*/
void copy_mario_state_to_object(void) {
s32 i = 0;
// L is real
// two-player hack
if (gCurrentObject != gMarioObject) {
i += 1;
}
void copy_mario_state_to_object(struct MarioState* m) {
gCurrentObject->oVelX = m->vel[0];
gCurrentObject->oVelY = m->vel[1];
gCurrentObject->oVelZ = m->vel[2];
gCurrentObject->oVelX = gMarioStates[i].vel[0];
gCurrentObject->oVelY = gMarioStates[i].vel[1];
gCurrentObject->oVelZ = gMarioStates[i].vel[2];
gCurrentObject->oPosX = gMarioStates[i].pos[0];
gCurrentObject->oPosY = gMarioStates[i].pos[1];
gCurrentObject->oPosZ = gMarioStates[i].pos[2];
gCurrentObject->oPosX = m->pos[0];
gCurrentObject->oPosY = m->pos[1];
gCurrentObject->oPosZ = m->pos[2];
gCurrentObject->oMoveAnglePitch = gCurrentObject->header.gfx.angle[0];
gCurrentObject->oMoveAngleYaw = gCurrentObject->header.gfx.angle[1];
@ -246,9 +239,9 @@ void copy_mario_state_to_object(void) {
gCurrentObject->oFaceAngleYaw = gCurrentObject->header.gfx.angle[1];
gCurrentObject->oFaceAngleRoll = gCurrentObject->header.gfx.angle[2];
gCurrentObject->oAngleVelPitch = gMarioStates[i].angleVel[0];
gCurrentObject->oAngleVelYaw = gMarioStates[i].angleVel[1];
gCurrentObject->oAngleVelRoll = gMarioStates[i].angleVel[2];
gCurrentObject->oAngleVelPitch = m->angleVel[0];
gCurrentObject->oAngleVelYaw = m->angleVel[1];
gCurrentObject->oAngleVelRoll = m->angleVel[2];
}
/**
@ -267,6 +260,9 @@ void spawn_particle(u32 activeParticleFlag, s16 model, const BehaviorScript *beh
* Mario's primary behavior update function.
*/
void bhv_mario_update(void) {
// set mario state to the current player
gMarioState = &gMarioStates[gCurrentObject->oBehParams - 1];
u32 particleFlags = 0;
s32 i;
@ -275,7 +271,7 @@ void bhv_mario_update(void) {
// Mario code updates MarioState's versions of position etc, so we need
// to sync it with the Mario object
copy_mario_state_to_object();
copy_mario_state_to_object(gMarioState);
i = 0;
while (sParticleTypes[i].particleFlag != 0) {
@ -286,11 +282,8 @@ void bhv_mario_update(void) {
i++;
}
}
void bhv_mario2_update(void) {
gMarioState = &gMarioStates[1];
bhv_mario_update();
// reset mario state to the local player
gMarioState = &gMarioStates[0];
}
@ -503,13 +496,12 @@ void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo) {
object->respawnInfoType = RESPAWN_INFO_TYPE_32;
object->respawnInfo = &spawnInfo->behaviorArg;
if (spawnInfo->behaviorArg & 0x01) {
gMarioObject = object;
geo_make_first_child(&object->header.gfx.node);
}
if (spawnInfo->behaviorArg & 0x02) {
gMario2Object = object;
// found a player
if (spawnInfo->behaviorArg & (1 << 31)) {
u16 playerIndex = (spawnInfo->behaviorArg & ~(1 << 31));
object->oBehParams = playerIndex + 1;
gMarioObjects[playerIndex] = object;
if (playerIndex == 0) { gMarioObject = object; }
geo_make_first_child(&object->header.gfx.node);
}
@ -544,7 +536,9 @@ void clear_objects(void) {
gTHIWaterDrained = 0;
gTimeStopState = 0;
gMarioObject = NULL;
gMario2Object = NULL;
for (int i = 0; i < MAX_PLAYERS; i++) {
gMarioObjects[i] = NULL;
}
gMarioCurrentRoom = 0;
for (int i = 0; i < MAX_PLAYERS; i++) {

View File

@ -90,7 +90,7 @@ extern struct ObjectNode *gObjectLists;
extern struct ObjectNode gFreeObjectList;
extern struct Object *gMarioObject;
extern struct Object *gMario2Object;
extern struct Object *gMarioObjects[];
extern struct Object *gCurrentObject;
extern const BehaviorScript *gCurBhvCommand;
@ -122,7 +122,6 @@ extern s16 gMarioOnMerryGoRound;
void bhv_mario_update(void);
void bhv_mario2_update(void);
void set_object_respawn_info_bits(struct Object *obj, u8 bits);
void unload_objects_from_area(UNUSED s32 unused, s32 areaIndex);
void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo);