Prevent two players from holding the same object

Fixes #40
This commit is contained in:
MysterD 2020-09-11 22:14:42 -07:00
parent 284ab37406
commit 3070d2bfdb
5 changed files with 22 additions and 6 deletions

View file

@ -1492,6 +1492,9 @@ void update_mario_inputs(struct MarioState *m) {
& (INT_STATUS_HOOT_GRABBED_BY_MARIO | INT_STATUS_MARIO_UNK1 | INT_STATUS_MARIO_UNK4)) {
m->input |= INPUT_UNKNOWN_10;
}
if (m->heldObj != NULL) {
m->heldObj->heldByPlayerIndex = 0;
}
}
// This function is located near other unused trampoline functions,
@ -1973,6 +1976,11 @@ s32 execute_mario_action(UNUSED struct Object *o) {
return 0;
}
s32 force_idle_state(struct MarioState* m) {
u8 underWater = (m->pos[1] < ((f32)m->waterLevel));
return set_mario_action(m, underWater ? ACT_WATER_IDLE : ACT_IDLE, 0);
}
/**************************************************
* INITIALIZATION *
**************************************************/

View file

@ -49,6 +49,7 @@ s32 check_common_hold_action_exits(struct MarioState *m);
s32 transition_submerged_to_walking(struct MarioState *m);
s32 set_water_plunge_action(struct MarioState *m);
s32 execute_mario_action(UNUSED struct Object *o);
s32 force_idle_state(struct MarioState* m);
void init_mario(void);
void init_mario_from_save_file(void);

View file

@ -951,8 +951,7 @@ s32 act_bubbled(struct MarioState* m) {
m->vel[1] = 0;
m->vel[2] = 0;
m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
u8 underWater = (m->pos[1] < ((f32)m->waterLevel));
return set_mario_action(m, underWater ? ACT_WATER_IDLE : ACT_IDLE, 0);
return force_idle_state(m);
}
return FALSE;

View file

@ -364,10 +364,12 @@ void network_receive_object(struct Packet* p) {
if (so == NULL) { return; }
struct Object* o = so->o;
if (!network_sync_object_initialized(o)) { return; }
if (gMarioStates[0].heldByObj == o) { return; }
// make sure no one can update an object we're holding
if (gNetworkType == NT_SERVER) { // two-player hack: needs priority
if (gMarioStates[0].heldObj == o) { return; }
if (gMarioStates[0].heldByObj == o) { return; }
}
// read the rest of the packet data
packet_read_object_full_sync(p, o);
@ -424,7 +426,7 @@ void network_update_objects(void) {
float dist = player_distance(&gMarioStates[0], so->o);
if (so->maxSyncDistance != SYNC_DISTANCE_INFINITE && dist > so->maxSyncDistance) { continue; }
float updateRate = dist / 1000.0f;
if (gMarioStates[0].heldObj == so->o) { updateRate = 0; }
if (gMarioStates[0].heldObj == so->o) { updateRate = 0.33f; }
// set max and min update rate
if (so->maxUpdateRate > 0 && updateRate < so->maxUpdateRate) { updateRate = so->maxUpdateRate; }

View file

@ -3,7 +3,9 @@
#include "object_fields.h"
#include "object_constants.h"
#include "sm64.h"
#include "src/audio/external.h"
#include "game/interaction.h"
#include "game/mario.h"
#include "audio/external.h"
#define SET_BIT(val, num) ((((u8)(val)) & 0x01) << (num));
#define GET_BIT(val, num) (((val) >> (num)) & 0x01)
@ -81,6 +83,10 @@ void network_receive_player(struct Packet* p) {
if (heldSyncID != 0 && gSyncObjects[heldSyncID].o != NULL) {
// TODO: do we have to move graphics nodes around to make this visible?
struct Object* heldObj = gSyncObjects[heldSyncID].o;
if (gMarioStates[0].heldObj == heldObj && gNetworkType == NT_CLIENT) { // two-player hack: needs priority
mario_drop_held_object(&gMarioStates[0]);
force_idle_state(&gMarioStates[0]);
}
gMarioStates[1].heldObj = heldObj;
heldObj->oHeldState = HELD_HELD;
heldObj->heldByPlayerIndex = 1;