Started adding player 2 / Luigi

This commit is contained in:
MysterD 2020-07-29 21:08:38 -07:00
parent 131fc7ea11
commit 6b3ab5f115
12 changed files with 104 additions and 30 deletions

View file

@ -3522,6 +3522,17 @@ const BehaviorScript bhvMario[] = {
END_LOOP(), END_LOOP(),
}; };
const BehaviorScript bhvLuigi[] = {
BEGIN(OBJ_LIST_PLAYER),
SET_INT(oIntangibleTimer, 0),
OR_INT(oFlags, OBJ_FLAG_0100),
OR_INT(oUnk94, 0x0001),
SET_HITBOX(/*Radius*/ 37, /*Height*/ 160),
BEGIN_LOOP(),
CALL_NATIVE(bhv_luigi_update),
END_LOOP(),
};
const BehaviorScript bhvToadMessage[] = { const BehaviorScript bhvToadMessage[] = {
BEGIN(OBJ_LIST_GENACTOR), BEGIN(OBJ_LIST_GENACTOR),
OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), OR_INT(oFlags, (OBJ_FLAG_PERSISTENT_RESPAWN | OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)),

View file

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

View file

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

View file

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

View file

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

View file

@ -438,6 +438,21 @@ static void level_cmd_init_mario(void) {
sCurrentCmd = CMD_NEXT; sCurrentCmd = CMD_NEXT;
} }
static void level_cmd_init_luigi(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) { static void level_cmd_place_object(void) {
u8 val7 = 1 << (gCurrActNum - 1); u8 val7 = 1 << (gCurrActNum - 1);
u16 model; u16 model;
@ -651,15 +666,16 @@ static void level_cmd_unload_area(void) {
} }
static void level_cmd_set_mario_start_pos(void) { static void level_cmd_set_mario_start_pos(void) {
gMarioSpawnInfo->areaIndex = CMD_GET(u8, 2); for (int i = 0; i < 2; i++) {
gPlayerSpawnInfos[i].areaIndex = CMD_GET(u8, 2);
#if IS_64_BIT
vec3s_set(gMarioSpawnInfo->startPos, CMD_GET(s16, 6), CMD_GET(s16, 8), CMD_GET(s16, 10));
#else
vec3s_copy(gMarioSpawnInfo->startPos, CMD_GET(Vec3s, 6));
#endif
vec3s_set(gMarioSpawnInfo->startAngle, 0, CMD_GET(s16, 4) * 0x8000 / 180, 0);
#if IS_64_BIT
vec3s_set(gPlayerSpawnInfos[i].startPos, CMD_GET(s16, 6), CMD_GET(s16, 8), CMD_GET(s16, 10));
#else
vec3s_copy(gPlayerSpawnInfos[i].startPos, CMD_GET(Vec3s, 6));
#endif
vec3s_set(gPlayerSpawnInfos[i].startAngle, 0, CMD_GET(s16, 4) * 0x8000 / 180, 0);
}
sCurrentCmd = CMD_NEXT; sCurrentCmd = CMD_NEXT;
} }
@ -858,6 +874,7 @@ static void (*LevelScriptJumpTable[])(void) = {
/*3C*/ level_cmd_get_or_set_var, /*3C*/ level_cmd_get_or_set_var,
/*3D*/ level_cmd_advdemo, /*3D*/ level_cmd_advdemo,
/*3E*/ level_cmd_cleardemoptr, /*3E*/ level_cmd_cleardemoptr,
/*3F*/ level_cmd_init_luigi,
}; };
struct LevelCommand *level_script_execute(struct LevelCommand *cmd) { struct LevelCommand *level_script_execute(struct LevelCommand *cmd) {

View file

@ -24,7 +24,7 @@
#include "gfx_dimensions.h" #include "gfx_dimensions.h"
struct SpawnInfo gPlayerSpawnInfos[1]; struct SpawnInfo gPlayerSpawnInfos[2];
struct GraphNode *D_8033A160[0x100]; struct GraphNode *D_8033A160[0x100];
struct Area gAreaData[8]; struct Area gAreaData[8];
@ -187,7 +187,8 @@ void clear_areas(void) {
gCurrentArea = NULL; gCurrentArea = NULL;
gWarpTransition.isActive = FALSE; gWarpTransition.isActive = FALSE;
gWarpTransition.pauseRendering = FALSE; gWarpTransition.pauseRendering = FALSE;
gMarioSpawnInfo->areaIndex = -1; gPlayerSpawnInfos[0].areaIndex = -1;
gPlayerSpawnInfos[1].areaIndex = -1;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
gAreaData[i].index = i; gAreaData[i].index = i;

View file

@ -155,7 +155,7 @@ struct CreditsEntry sCreditsSequence[] = {
{ LEVEL_NONE, 0, 1, 0, { 0, 0, 0 }, NULL }, { LEVEL_NONE, 0, 1, 0, { 0, 0, 0 }, NULL },
}; };
struct MarioState gMarioStates[1]; struct MarioState gMarioStates[2];
struct HudDisplay gHudDisplay; struct HudDisplay gHudDisplay;
s16 sCurrPlayMode; s16 sCurrPlayMode;
u16 D_80339ECA; u16 D_80339ECA;
@ -371,21 +371,23 @@ void init_mario_after_warp(void) {
u32 marioSpawnType = get_mario_spawn_type(spawnNode->object); u32 marioSpawnType = get_mario_spawn_type(spawnNode->object);
if (gMarioState->action != ACT_UNINITIALIZED) { if (gMarioState->action != ACT_UNINITIALIZED) {
gPlayerSpawnInfos[0].startPos[0] = (s16) spawnNode->object->oPosX; for (int i = 0; i < 2; i++) {
gPlayerSpawnInfos[0].startPos[1] = (s16) spawnNode->object->oPosY; gPlayerSpawnInfos[i].startPos[0] = (s16) spawnNode->object->oPosX;
gPlayerSpawnInfos[0].startPos[2] = (s16) spawnNode->object->oPosZ; gPlayerSpawnInfos[i].startPos[1] = (s16) spawnNode->object->oPosY;
gPlayerSpawnInfos[i].startPos[2] = (s16) spawnNode->object->oPosZ;
gPlayerSpawnInfos[0].startAngle[0] = 0; gPlayerSpawnInfos[i].startAngle[0] = 0;
gPlayerSpawnInfos[0].startAngle[1] = spawnNode->object->oMoveAngleYaw; gPlayerSpawnInfos[i].startAngle[1] = spawnNode->object->oMoveAngleYaw;
gPlayerSpawnInfos[0].startAngle[2] = 0; gPlayerSpawnInfos[i].startAngle[2] = 0;
if (marioSpawnType == MARIO_SPAWN_DOOR_WARP) { if (marioSpawnType == MARIO_SPAWN_DOOR_WARP) {
init_door_warp(&gPlayerSpawnInfos[0], sWarpDest.arg); init_door_warp(&gPlayerSpawnInfos[i], sWarpDest.arg);
} }
if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL || sWarpDest.type == WARP_TYPE_CHANGE_AREA) { if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL || sWarpDest.type == WARP_TYPE_CHANGE_AREA) {
gPlayerSpawnInfos[0].areaIndex = sWarpDest.areaIdx; gPlayerSpawnInfos[i].areaIndex = sWarpDest.areaIdx;
load_mario_area(); if (i == 0) { load_mario_area(); }
}
} }
init_mario(); init_mario();
@ -504,12 +506,14 @@ void warp_credits(void) {
load_area(sWarpDest.areaIdx); load_area(sWarpDest.areaIdx);
vec3s_set(gPlayerSpawnInfos[0].startPos, gCurrCreditsEntry->marioPos[0], for (int i = 0; i < 2; i++) {
gCurrCreditsEntry->marioPos[1], gCurrCreditsEntry->marioPos[2]); vec3s_set(gPlayerSpawnInfos[i].startPos, gCurrCreditsEntry->marioPos[0],
gCurrCreditsEntry->marioPos[1], gCurrCreditsEntry->marioPos[2]);
vec3s_set(gPlayerSpawnInfos[0].startAngle, 0, 0x100 * gCurrCreditsEntry->marioAngle, 0); vec3s_set(gPlayerSpawnInfos[i].startAngle, 0, 0x100 * gCurrCreditsEntry->marioAngle, 0);
gPlayerSpawnInfos[0].areaIndex = sWarpDest.areaIdx; gPlayerSpawnInfos[i].areaIndex = sWarpDest.areaIdx;
}
load_mario_area(); load_mario_area();
init_mario(); init_mario();

View file

@ -1839,6 +1839,10 @@ s32 execute_mario_action(UNUSED struct Object *o) {
**************************************************/ **************************************************/
void init_mario(void) { void init_mario(void) {
bool isMario = (gMarioState == &gMarioStates[0]);
if (isMario && gMarioObject == NULL) { goto skippy; }
if (!isMario && gLuigiObject == NULL) { goto skippy; }
Vec3s capPos; Vec3s capPos;
struct Object *capObject; struct Object *capObject;
@ -1875,12 +1879,13 @@ void init_mario(void) {
find_water_level(gMarioSpawnInfo->startPos[0], gMarioSpawnInfo->startPos[2]); find_water_level(gMarioSpawnInfo->startPos[0], gMarioSpawnInfo->startPos[2]);
gMarioState->area = gCurrentArea; gMarioState->area = gCurrentArea;
gMarioState->marioObj = gMarioObject; gMarioState->marioObj = isMario ? gMarioObject : gLuigiObject;
gMarioState->marioObj->header.gfx.unk38.animID = -1; gMarioState->marioObj->header.gfx.unk38.animID = -1;
vec3s_copy(gMarioState->faceAngle, gMarioSpawnInfo->startAngle); vec3s_copy(gMarioState->faceAngle, gMarioSpawnInfo->startAngle);
vec3s_set(gMarioState->angleVel, 0, 0, 0); vec3s_set(gMarioState->angleVel, 0, 0, 0);
vec3s_to_vec3f(gMarioState->pos, gMarioSpawnInfo->startPos); vec3s_to_vec3f(gMarioState->pos, gMarioSpawnInfo->startPos);
vec3f_set(gMarioState->vel, 0, 0, 0); vec3f_set(gMarioState->vel, 0, 0, 0);
if (!isMario) { gMarioState->pos[0] -= 50; }
gMarioState->floorHeight = gMarioState->floorHeight =
find_floor(gMarioState->pos[0], gMarioState->pos[1], gMarioState->pos[2], &gMarioState->floor); find_floor(gMarioState->pos[0], gMarioState->pos[1], gMarioState->pos[2], &gMarioState->floor);
@ -1919,15 +1924,23 @@ void init_mario(void) {
capObject->oMoveAngleYaw = 0; capObject->oMoveAngleYaw = 0;
} }
skippy:
if (isMario) {
gMarioState = &gMarioStates[1];
init_mario();
gMarioState = &gMarioStates[0];
}
} }
void init_mario_from_save_file(void) { void init_mario_from_save_file(void) {
gMarioState->unk00 = 0; gMarioState->unk00 = 0;
gMarioState->flags = 0; gMarioState->flags = 0;
gMarioState->action = 0; gMarioState->action = 0;
gMarioState->spawnInfo = &gPlayerSpawnInfos[0]; int i = (gMarioState == &gMarioStates[0]) ? 0 : 1;
gMarioState->spawnInfo = &gPlayerSpawnInfos[i];
gMarioState->statusForCamera = &gPlayerCameraState[0]; gMarioState->statusForCamera = &gPlayerCameraState[0];
gMarioState->marioBodyState = &gBodyStates[0]; gMarioState->marioBodyState = &gBodyStates[i];
gMarioState->controller = &gControllers[0]; gMarioState->controller = &gControllers[0];
gMarioState->animation = &D_80339D10; gMarioState->animation = &D_80339D10;
@ -1944,4 +1957,10 @@ void init_mario_from_save_file(void) {
gHudDisplay.coins = 0; gHudDisplay.coins = 0;
gHudDisplay.wedges = 8; gHudDisplay.wedges = 8;
if (gMarioState == &gMarioStates[0]) {
gMarioState = &gMarioStates[1];
init_mario_from_save_file();
gMarioState = &gMarioStates[0];
}
} }

View file

@ -286,6 +286,12 @@ void bhv_mario_update(void) {
} }
} }
void bhv_luigi_update(void) {
gMarioState = &gMarioStates[1];
bhv_mario_update();
gMarioState = &gMarioStates[0];
}
/** /**
* Update every object that occurs after firstObj in the given object list, * Update every object that occurs after firstObj in the given object list,
* including firstObj itself. Return the number of objects that were updated. * including firstObj itself. Return the number of objects that were updated.
@ -500,6 +506,11 @@ void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo) {
geo_make_first_child(&object->header.gfx.node); geo_make_first_child(&object->header.gfx.node);
} }
if (spawnInfo->behaviorArg & 0x02) {
gLuigiObject = object;
geo_make_first_child(&object->header.gfx.node);
}
geo_obj_init_spawninfo(&object->header.gfx, spawnInfo); geo_obj_init_spawninfo(&object->header.gfx, spawnInfo);
object->oPosX = spawnInfo->startPos[0]; object->oPosX = spawnInfo->startPos[0];
@ -531,6 +542,7 @@ void clear_objects(void) {
gTHIWaterDrained = 0; gTHIWaterDrained = 0;
gTimeStopState = 0; gTimeStopState = 0;
gMarioObject = NULL; gMarioObject = NULL;
gLuigiObject = NULL;
gMarioCurrentRoom = 0; gMarioCurrentRoom = 0;
for (i = 0; i < 60; i++) { for (i = 0; i < 60; i++) {

View file

@ -122,6 +122,7 @@ extern s16 gMarioOnMerryGoRound;
void bhv_mario_update(void); void bhv_mario_update(void);
void bhv_luigi_update(void);
void set_object_respawn_info_bits(struct Object *obj, u8 bits); void set_object_respawn_info_bits(struct Object *obj, u8 bits);
void unload_objects_from_area(UNUSED s32 unused, s32 areaIndex); void unload_objects_from_area(UNUSED s32 unused, s32 areaIndex);
void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo); void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo);

View file

@ -282,6 +282,7 @@ void main_func(void) {
#ifdef DISCORDRPC #ifdef DISCORDRPC
discord_update_rich_presence(); discord_update_rich_presence();
#endif #endif
fflush(stdout);
} }
#endif #endif
} }