diff --git a/port/include/net/net.h b/port/include/net/net.h index b1aa6af98..80ae4df05 100644 --- a/port/include/net/net.h +++ b/port/include/net/net.h @@ -5,7 +5,7 @@ #include "constants.h" #include "net/netbuf.h" -#define NET_PROTOCOL_VER 4 +#define NET_PROTOCOL_VER 5 #define NET_MAX_CLIENTS MAX_PLAYERS #define NET_MAX_NAME MAX_PLAYERNAME diff --git a/port/include/net/netmsg.h b/port/include/net/netmsg.h index c822d9a36..5aed9c64c 100644 --- a/port/include/net/netmsg.h +++ b/port/include/net/netmsg.h @@ -20,6 +20,7 @@ #define SVC_PROP_PICKUP 0x33 // prop was picked up #define SVC_PROP_USE 0x34 // door/lift/etc was used #define SVC_PROP_DOOR 0x35 // door state changed +#define SVC_PROP_LIFT 0x36 // lift state changed #define SVC_CHR_DAMAGE 0x42 // chr was damaged #define SVC_CHR_DISARM 0x43 // chr's weapons were dropped @@ -60,6 +61,8 @@ u32 netmsgSvcPropUseWrite(struct netbuf *dst, struct prop *prop, struct netclien u32 netmsgSvcPropUseRead(struct netbuf *src, struct netclient *srccl); u32 netmsgSvcPropDoorWrite(struct netbuf *dst, struct prop *prop, struct netclient *usercl); u32 netmsgSvcPropDoorRead(struct netbuf *src, struct netclient *srccl); +u32 netmsgSvcPropLiftWrite(struct netbuf *dst, struct prop *prop); +u32 netmsgSvcPropLiftRead(struct netbuf *src, struct netclient *srccl); u32 netmsgSvcChrDamageWrite(struct netbuf *dst, struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *aprop, s32 hitpart, bool damageshield, struct prop *prop2, s32 side, s16 *arg11, bool explosion, struct coord *explosionpos); u32 netmsgSvcChrDamageRead(struct netbuf *src, struct netclient *srccl); u32 netmsgSvcChrDisarmWrite(struct netbuf *dst, struct chrdata *chr, struct prop *attacker, u8 weaponnum, f32 wpndamage, struct coord *wpnpos); diff --git a/port/src/net/net.c b/port/src/net/net.c index 06597f20a..719177f32 100644 --- a/port/src/net/net.c +++ b/port/src/net/net.c @@ -598,6 +598,7 @@ static void netClientEvReceive(struct netclient *cl) case SVC_PROP_PICKUP: rc = netmsgSvcPropPickupRead(&cl->in, cl); break; case SVC_PROP_USE: rc = netmsgSvcPropUseRead(&cl->in, cl); break; case SVC_PROP_DOOR: rc = netmsgSvcPropDoorRead(&cl->in, cl); break; + case SVC_PROP_LIFT: rc = netmsgSvcPropLiftRead(&cl->in, cl); break; case SVC_CHR_DAMAGE: rc = netmsgSvcChrDamageRead(&cl->in, cl); break; case SVC_CHR_DISARM: rc = netmsgSvcChrDisarmRead(&cl->in, cl); break; default: diff --git a/port/src/net/netmsg.c b/port/src/net/netmsg.c index 65a9e4b68..d5c2ea6c1 100644 --- a/port/src/net/netmsg.c +++ b/port/src/net/netmsg.c @@ -1168,10 +1168,12 @@ u32 netmsgSvcPropUseRead(struct netbuf *src, struct netclient *srccl) switch (prop->type) { case PROPTYPE_OBJ: case PROPTYPE_WEAPON: - ownop = propobjInteract(prop); + if (!prop->obj || prop->obj->type != OBJTYPE_LIFT) { + ownop = propobjInteract(prop); + } break; default: - // NOTE: doors are handled with SVC_PROP_DOOR + // NOTE: doors and lifts are handled with SVC_PROP_DOOR/_LIFT // TODO: eventually remove this message completely ownop = TICKOP_NONE; break; @@ -1237,6 +1239,72 @@ u32 netmsgSvcPropDoorRead(struct netbuf *src, struct netclient *srccl) return src->error; } +u32 netmsgSvcPropLiftWrite(struct netbuf *dst, struct prop *prop) +{ + if (prop->type != PROPTYPE_OBJ || !prop->obj || prop->obj->type != OBJTYPE_LIFT) { + return dst->error; + } + + struct liftobj *lift = (struct liftobj *)prop->obj; + + netbufWriteU8(dst, SVC_PROP_LIFT); + netbufWritePropPtr(dst, prop); + netbufWriteS8(dst, lift->levelcur); + netbufWriteS8(dst, lift->levelaim); + netbufWriteF32(dst, lift->accel); + netbufWriteF32(dst, lift->speed); + netbufWriteF32(dst, lift->dist); + netbufWriteU32(dst, lift->base.flags); + netbufWriteCoord(dst, &prop->pos); + netbufWriteRooms(dst, prop->rooms, ARRAYCOUNT(prop->rooms)); + + return dst->error; +} + +u32 netmsgSvcPropLiftRead(struct netbuf *src, struct netclient *srccl) +{ + struct prop *prop = netbufReadPropPtr(src); + const s8 levelcur = netbufReadS8(src); + const s8 levelaim = netbufReadS8(src); + const f32 accel = netbufReadF32(src); + const f32 speed = netbufReadF32(src); + const f32 dist = netbufReadF32(src); + const u32 flags = netbufReadU32(src); + struct coord pos; netbufReadCoord(src, &pos); + RoomNum rooms[8]; netbufReadRooms(src, rooms, ARRAYCOUNT(rooms)); + + if (!prop || srccl->state < CLSTATE_GAME) { + return src->error; + } + + if (!prop->obj || prop->type != PROPTYPE_OBJ || prop->obj->type != OBJTYPE_LIFT) { + sysLogPrintf(LOG_WARNING, "NET: SVC_PROP_LIFT: prop %u should be a lift, but isn't", prop->syncid); + return src->error; + } + + struct liftobj *lift = (struct liftobj *)prop->obj; + lift->levelcur = levelcur; + lift->levelaim = levelaim; + lift->speed = speed; + lift->dist = dist; + lift->accel = accel; + lift->base.flags = flags; + + prop->pos = pos; + + if (!propRoomsEqual(rooms, prop->rooms)) { + if (prop->active) { + propDeregisterRooms(prop); + } + roomsCopy(rooms, prop->rooms); + if (prop->active) { + propRegisterRooms(prop); + } + } + + return src->error; +} + u32 netmsgSvcChrDamageWrite(struct netbuf *dst, struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *aprop, s32 hitpart, bool damageshield, struct prop *prop2, s32 side, s16 *arg11, bool explosion, struct coord *explosionpos) { diff --git a/src/game/propobj.c b/src/game/propobj.c index b52eb9def..be4170787 100644 --- a/src/game/propobj.c +++ b/src/game/propobj.c @@ -159,6 +159,13 @@ bool doorCallLift(struct prop *doorprop, bool allowclose) struct doorobj *door = doorprop->door; bool handled = false; +#ifndef PLATFORM_N64 + if (g_NetMode == NETMODE_CLIENT) { + // don't automatically do anything with lifts + return handled; + } +#endif + if (door->base.hidden & OBJHFLAG_LIFTDOOR) { struct linkliftdoorobj *link = g_LiftDoors; @@ -5089,6 +5096,11 @@ void liftGoToStop(struct liftobj *lift, s32 stopnum) // Sanity check to make sure lift is actually not moving if (lift->dist == 0 && lift->speed == 0) { lift->levelaim = stopnum; +#ifndef PLATFORM_N64 + if (g_NetMode == NETMODE_SERVER) { + netmsgSvcPropLiftWrite(&g_NetMsgRel, lift->base.prop); + } +#endif return; } } @@ -5135,6 +5147,12 @@ void liftGoToStop(struct liftobj *lift, s32 stopnum) lift->speed = -lift->speed; lift->levelaim = stopnum; } + +#ifndef PLATFORM_N64 + if (g_NetMode == NETMODE_SERVER) { + netmsgSvcPropLiftWrite(&g_NetMsgRel, lift->base.prop); + } +#endif } }