mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-01-07 08:01:16 +00:00
Eject a player if more than one is in the cannon
Two players in the same cannon was causing softlocks and general insanity. Now this should be fixed. Also prevented players from being able to push or attack a player inside of a cannon.
This commit is contained in:
parent
58a3156180
commit
cf732c7beb
4 changed files with 46 additions and 1 deletions
|
@ -146,14 +146,47 @@ u8 unused0EA1FC[] = { 2, 0, 0, 0, 0, 0, 0, 0, 63, 128, 0, 0, 2, 0, 0, 0
|
|||
63, 128, 0, 0, 2, 0, 0, 0, 65, 160, 0, 0, 63, 128, 0, 0, 2, 0, 0, 0,
|
||||
65, 160, 0, 0, 63, 128, 0, 0, 8, 0, 0, 0, 65, 32, 0, 0, 63, 128, 0, 0 };
|
||||
|
||||
u8 cannon_ignore_remote_updates(struct Object* object) { return object->oCannonIsLocal; }
|
||||
u8 cannon_ignore_remote_updates(struct Object* object) {
|
||||
// two-player hack
|
||||
return ((gNetworkType == NT_SERVER) && object->oCannonIsLocal);
|
||||
}
|
||||
|
||||
static void cannon_on_received(void) {
|
||||
// check if we're on in the cannon too
|
||||
struct MarioState* m = &gMarioStates[0];
|
||||
if (m->action != ACT_IN_CANNON) { return; }
|
||||
if (m->interactObj != o) { return; }
|
||||
// two-player hack
|
||||
if (gNetworkType == NT_SERVER) { return; }
|
||||
|
||||
// eject the player by shooting out of the cannon weakly
|
||||
m->forwardVel = 10.0f * coss(m->faceAngle[0]);
|
||||
m->vel[1] = 10.0f * sins(m->faceAngle[0]);
|
||||
m->pos[0] += 120.0f * coss(m->faceAngle[0]) * sins(m->faceAngle[1]);
|
||||
m->pos[1] += 120.0f * sins(m->faceAngle[0]);
|
||||
m->pos[2] += 120.0f * coss(m->faceAngle[0]) * coss(m->faceAngle[1]);
|
||||
set_mario_action(m, ACT_SHOT_FROM_CANNON, 0);
|
||||
|
||||
// reset things that got messed up
|
||||
m->marioObj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
|
||||
reset_camera(gCamera);
|
||||
o->oCannonIsLocal = FALSE;
|
||||
cur_obj_become_tangible();
|
||||
cur_obj_enable_rendering();
|
||||
}
|
||||
|
||||
void bhv_cannon_base_loop(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
so->ignore_if_true = &cannon_ignore_remote_updates;
|
||||
so->on_received = &cannon_on_received;
|
||||
network_init_object_field(o, &o->oAction);
|
||||
network_init_object_field(o, &o->oPrevAction);
|
||||
network_init_object_field(o, &o->oTimer);
|
||||
network_init_object_field(o, &o->oPosX);
|
||||
network_init_object_field(o, &o->oPosY);
|
||||
network_init_object_field(o, &o->oPosZ);
|
||||
network_init_object_field(o, &o->oCannonUnk10C);
|
||||
network_init_object_field(o, &o->oCannonUnk10C);
|
||||
network_init_object_field(o, &o->oCannonUnkF8);
|
||||
network_init_object_field(o, &o->oCannonUnkF4);
|
||||
|
|
|
@ -1233,6 +1233,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);
|
||||
isInCutscene = isInCutscene || (m->action == ACT_IN_CANNON) || (m2->action == ACT_IN_CANNON);
|
||||
u8 isInvulnerable = (m2->action & ACT_FLAG_INVULNERABLE) || m2->invincTimer != 0 || m2->hurtCounter != 0 || isInCutscene;
|
||||
if ((interaction & INT_ANY_ATTACK) && !(interaction & INT_HIT_FROM_ABOVE) && !isInvulnerable) {
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ struct SyncObject {
|
|||
bool hasStandardFields;
|
||||
float maxUpdateRate;
|
||||
u8 (*ignore_if_true)(struct Object*);
|
||||
void (*on_received)(void);
|
||||
void* extraFields[MAX_SYNC_OBJECT_FIELDS];
|
||||
};
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ struct SyncObject* network_init_object(struct Object *o, float maxSyncDistance)
|
|||
so->hasStandardFields = (maxSyncDistance >= 0);
|
||||
so->maxUpdateRate = 0;
|
||||
so->ignore_if_true = NULL;
|
||||
so->on_received = NULL;
|
||||
so->syncDeathEvent = true;
|
||||
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS);
|
||||
|
||||
|
@ -372,6 +373,15 @@ void network_receive_object(struct Packet* p) {
|
|||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
|
||||
network_forget_sync_object(so);
|
||||
}
|
||||
|
||||
// trigger on-received callback
|
||||
if (so->on_received != NULL) {
|
||||
extern struct Object* gCurrentObject;
|
||||
struct Object* tmp = gCurrentObject;
|
||||
gCurrentObject = so->o;
|
||||
(*so->on_received)();
|
||||
gCurrentObject = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void network_forget_sync_object(struct SyncObject* so) {
|
||||
|
|
Loading…
Reference in a new issue