diff --git a/port/include/net/net.h b/port/include/net/net.h index 83e3cb997..8be7618fa 100644 --- a/port/include/net/net.h +++ b/port/include/net/net.h @@ -78,6 +78,7 @@ struct netclient { struct { char name[NET_MAX_NAME]; + u16 options; u8 headnum; u8 bodynum; u8 team; diff --git a/port/src/net/net.c b/port/src/net/net.c index 07a1ee0c7..23ee02cd6 100644 --- a/port/src/net/net.c +++ b/port/src/net/net.c @@ -276,6 +276,21 @@ static inline s32 netClientNeedMove(const struct netclient *cl) return (memcmp(cmpa, cmpb, sizeof(*move) - sizeof(move->tick)) != 0); } +static inline void netClientReadConfig(struct netclient *cl, const s32 playernum) +{ + cl->settings.options = g_PlayerConfigsArray[playernum].options; + cl->settings.bodynum = g_PlayerConfigsArray[playernum].base.mpbodynum; + cl->settings.headnum = g_PlayerConfigsArray[playernum].base.mpheadnum; + cl->settings.fovy = g_PlayerExtCfg[playernum].fovy; + cl->settings.fovzoommult = g_PlayerExtCfg[playernum].fovzoommult; + memcpy(cl->settings.name, g_PlayerConfigsArray[playernum].base.name, sizeof(cl->settings.name)); + // the \n will be readded in the playerconfig + char *newline = strrchr(g_NetLocalClient->settings.name, '\n'); + if (newline) { + *newline = '\0'; + } +} + static inline void netFlushSendBuffers(void) { if (g_NetMsgRel.wp) { @@ -343,16 +358,7 @@ s32 netStartServer(u16 port, s32 maxclients) // the server's local client is client 0 g_NetLocalClient = &g_NetClients[0]; g_NetLocalClient->state = CLSTATE_LOBBY; // local client doesn't need auth - g_NetLocalClient->settings.bodynum = g_PlayerConfigsArray[0].base.mpbodynum; - g_NetLocalClient->settings.headnum = g_PlayerConfigsArray[0].base.mpheadnum; - g_NetLocalClient->settings.fovy = g_PlayerExtCfg[0].fovy; - g_NetLocalClient->settings.fovzoommult = g_PlayerExtCfg[0].fovzoommult; - memcpy(g_NetLocalClient->settings.name, g_PlayerConfigsArray[0].base.name, sizeof(g_NetLocalClient->settings.name)); - // the \n will be readded in the playerconfig - char *newline = strrchr(g_NetLocalClient->settings.name, '\n'); - if (newline) { - *newline = '\0'; - } + netClientReadConfig(g_NetLocalClient, 0); g_NetMode = NETMODE_SERVER; @@ -377,6 +383,9 @@ void netServerStageStart(void) return; } + // re-read the player config in case it changed + netClientReadConfig(g_NetLocalClient, 0); + g_NetLocalClient->state = CLSTATE_GAME; netbufStartWrite(&g_NetMsgRel); @@ -449,16 +458,7 @@ s32 netStartClient(const char *addr) } g_NetLocalClient->state = CLSTATE_CONNECTING; - g_NetLocalClient->settings.bodynum = g_PlayerConfigsArray[0].base.mpbodynum; - g_NetLocalClient->settings.headnum = g_PlayerConfigsArray[0].base.mpheadnum; - g_NetLocalClient->settings.fovy = g_PlayerExtCfg[0].fovy; - g_NetLocalClient->settings.fovzoommult = g_PlayerExtCfg[0].fovzoommult; - memcpy(g_NetLocalClient->settings.name, g_PlayerConfigsArray[0].base.name, sizeof(g_NetLocalClient->settings.name)); - // the \n will be readded in the playerconfig - char *newline = strrchr(g_NetLocalClient->settings.name, '\n'); - if (newline) { - *newline = '\0'; - } + netClientReadConfig(g_NetLocalClient, 0); g_NetMode = NETMODE_CLIENT; @@ -828,6 +828,12 @@ void netPlayersAllocate(void) cfg->base.mpbodynum = cl->settings.bodynum; cfg->base.mpheadnum = cl->settings.headnum; snprintf(cfg->base.name, sizeof(cfg->base.name), "%s\n", cl->settings.name); + // take some of the options from our local player and others from the client + cfg->options = g_PlayerConfigsArray[0].options & OPTION_PAINTBALL; + cfg->options |= cl->settings.options & ~OPTION_PAINTBALL; + // don't enable toggle aim, invert pitch or lookahead for remote players + cfg->options &= ~(OPTION_AIMCONTROL | OPTION_LOOKAHEAD | OPTION_ASKEDSAVEPLAYER); + cfg->options |= OPTION_FORWARDPITCH; } cl->player = g_Vars.players[cl->playernum]; diff --git a/port/src/net/netmsg.c b/port/src/net/netmsg.c index 56c98a67d..b45e07b3a 100644 --- a/port/src/net/netmsg.c +++ b/port/src/net/netmsg.c @@ -157,6 +157,7 @@ u32 netmsgClcAuthWrite(struct netbuf *dst) netbufWriteStr(dst, g_RomName); // TODO: use a CRC or something netbufWriteStr(dst, modDir); netbufWriteU8(dst, 1); // TODO: number of local players + netbufWriteU16(dst, g_NetLocalClient->settings.options); netbufWriteU8(dst, g_NetLocalClient->settings.bodynum); netbufWriteU8(dst, g_NetLocalClient->settings.headnum); netbufWriteF32(dst, g_NetLocalClient->settings.fovy); @@ -176,6 +177,7 @@ u32 netmsgClcAuthRead(struct netbuf *src, struct netclient *srccl) const char *romName = netbufReadStr(src); const char *modDir = netbufReadStr(src); const u8 players = netbufReadU8(src); + const u16 options = netbufReadU16(src); const u8 bodynum = netbufReadU8(src); const u8 headnum = netbufReadU8(src); const f32 fovy = netbufReadF32(src); @@ -206,6 +208,7 @@ u32 netmsgClcAuthRead(struct netbuf *src, struct netclient *srccl) } strncpy(srccl->settings.name, name, sizeof(srccl->settings.name) - 1); + srccl->settings.options = options; srccl->settings.bodynum = bodynum; srccl->settings.headnum = headnum; srccl->settings.fovy = fovy; @@ -394,6 +397,7 @@ u32 netmsgSvcStageStartWrite(struct netbuf *dst) ncl->settings.team = g_PlayerConfigsArray[ncl->id].base.team; netbufWriteU8(dst, ncl->id); netbufWriteU8(dst, ncl->settings.team); + netbufWriteU16(dst, ncl->settings.options); netbufWriteU8(dst, ncl->settings.bodynum); netbufWriteU8(dst, ncl->settings.headnum); netbufWriteF32(dst, ncl->settings.fovy); @@ -459,6 +463,7 @@ u32 netmsgSvcStageStartRead(struct netbuf *src, struct netclient *srccl) ncl->settings.team = netbufReadU8(src); if (ncl != g_NetLocalClient) { ncl->id = id; + ncl->settings.options = netbufReadU16(src); ncl->settings.bodynum = netbufReadU8(src); ncl->settings.headnum = netbufReadU8(src); ncl->settings.fovy = netbufReadF32(src); @@ -472,6 +477,7 @@ u32 netmsgSvcStageStartRead(struct netbuf *src, struct netclient *srccl) } } else { // skip our own settings except for the team + netbufReadU16(src); netbufReadU8(src); netbufReadU8(src); netbufReadF32(src); diff --git a/src/game/bondmove.c b/src/game/bondmove.c index b5f45cf47..a27aaf40a 100644 --- a/src/game/bondmove.c +++ b/src/game/bondmove.c @@ -2683,7 +2683,13 @@ void bmoveUpdateHead(f32 arg0, f32 arg1, f32 arg2, Mtxf *arg3, f32 arg4) bheadUpdate(sp244, arg2); mtx4LoadXRotation(BADDEG2RAD(360 - g_Vars.currentplayer->vv_verta360), &sp180); +#ifdef PLATFORM_N64 if (optionsGetHeadRoll(g_Vars.currentplayerstats->mpindex)) { +#else + // in net games only allow headroll in the death animation + // TODO: figure out how to deal with headroll in other situations + if (optionsGetHeadRoll(g_Vars.currentplayerstats->mpindex) && (!g_NetMode || g_Vars.currentplayer->isdead)) { +#endif mtx00016d58(&sp116, 0, 0, 0, -g_Vars.currentplayer->headlook.x, -g_Vars.currentplayer->headlook.y, -g_Vars.currentplayer->headlook.z, diff --git a/src/game/options.c b/src/game/options.c index 62007527d..d8ff82093 100644 --- a/src/game/options.c +++ b/src/game/options.c @@ -111,13 +111,6 @@ u8 optionsGetCutsceneSubtitles(void) s32 optionsGetHeadRoll(s32 mpchrnum) { -#ifndef PLATFORM_N64 - if (g_NetMode) { - // remove headroll from netplay for now for better shot consistency - // TODO: make it an option or something - return false; - } -#endif return (g_PlayerConfigsArray[mpchrnum].options & OPTION_HEADROLL) != 0; }