diff --git a/src/d_enet.c b/src/d_enet.c index 07662b0434f676cb1c53624ac8e3116d268fb06a..05a7d6edc6f2f0f5835cf713997736ffae4dc7b1 100644 --- a/src/d_enet.c +++ b/src/d_enet.c @@ -47,6 +47,7 @@ enum { CLIENT_CHAT, CLIENT_CHARACTER, CLIENT_MOVE, + CLIENT_ATTACK, SERVER_MSINFO = 0, SERVER_MAPINFO, @@ -58,7 +59,8 @@ enum { SERVER_MOVE, SERVER_PLAYER_DAMAGE, SERVER_PLAYER_RINGS, - SERVER_FORCE_MOVE + SERVER_FORCE_MOVE, + SERVER_POWERUP }; static ENetHost *ServerHost = NULL, @@ -221,6 +223,35 @@ static void ServerHandlePacket(UINT8 node, DataWrap data) break; } + case CLIENT_ATTACK: + { + player_t *player; + fixed_t x,y,z,oldz; + + if (nodetoplayer[node] == -1) + break; + + player = &players[nodetoplayer[node]]; + if (player->pflags & PF_JUMPED) + break; + + x = DW_ReadFixed(data); + y = DW_ReadFixed(data); + z = DW_ReadFixed(data); + + oldz = player->mo->z; + player->mo->z = z; + if (!P_TryMove(player->mo, x, y, true)) + { + player->mo->z = oldz; + Net_ForceMove(player); + } + player->pflags |= PF_JUMPDOWN; + P_DoJump(player, true); + P_SetTarget(&tmthing, NULL); + break; + } + default: CONS_Printf("NETWORK: Unknown message type recieved from node %u!\n", node); break; @@ -229,8 +260,10 @@ static void ServerHandlePacket(UINT8 node, DataWrap data) void CL_ConnectionSuccessful(void); -static void ClientHandlePacket(UINT8 node, DataWrap data) +static void ClientHandlePacket(DataWrap data) { + player_t *player = &players[consoleplayer]; + switch(DW_ReadUINT8(data)) { case SERVER_MAPINFO: @@ -264,13 +297,10 @@ static void ClientHandlePacket(UINT8 node, DataWrap data) // Spawn a player. if (id < 1000) { - /*const fixed_t x = DW_ReadINT16(data) << 16, - y = DW_ReadINT16(data) << 16, - z = DW_ReadINT16(data) << 16;*/ mobj_t *mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); mobj->flags &= ~MF_SOLID; + mobj->flags |= MF_SLIDEME; mobj->mobjnum = id; - //mobj->angle = DW_ReadUINT8(data) << 24; mobj->skin = &skins[DW_ReadUINT8(data)]; mobj->color = DW_ReadUINT8(data); } @@ -280,18 +310,30 @@ static void ClientHandlePacket(UINT8 node, DataWrap data) case SERVER_KILL: { thinker_t *th; - mobj_t *mobj = NULL; + mobj_t *target = NULL; + mobj_t *killer = NULL; UINT16 id = DW_ReadUINT16(data); + UINT16 kid = DW_ReadUINT16(data); for (th = thinkercap.next; th != &thinkercap; th = th->next) - if (th->function.acp1 == (actionf_p1)P_MobjThinker && ((mobj_t *)th)->mobjnum == id) + if (th->function.acp1 == (actionf_p1)P_MobjThinker) { - mobj = (mobj_t *)th; - break; + mobj_t *mobj = (mobj_t *)th; + if (mobj->mobjnum == id) + target = mobj; + if (kid && mobj->mobjnum == kid) + killer = mobj; + if (target && (killer || !kid)) + break; } - if (mobj) - P_KillMobj(mobj, NULL, NULL, 0); + if (target) + { + target->mobjnum = 0; + if (target->flags & MF_SPECIAL && !(target->flags & (MF_ENEMY|MF_BOSS))) + S_StartSound(killer, target->info->deathsound); + P_KillMobj(target, killer, killer, 0); + } break; } @@ -392,29 +434,34 @@ static void ClientHandlePacket(UINT8 node, DataWrap data) const fixed_t x = DW_ReadFixed(data), y = DW_ReadFixed(data), z = DW_ReadFixed(data); - P_TeleportMove(players[consoleplayer].mo, x, y, z); + player->mo->z = z; + P_TryMove(player->mo, x, y, true); P_SetTarget(&tmthing, NULL); - if (players[consoleplayer].health > 1 && !(damagetype & DMG_DEATHMASK)) + + if (!(damagetype & DMG_DEATHMASK) && (player->health > 1 || player->powers[pw_shield])) { - P_DoPlayerPain(&players[consoleplayer], NULL, NULL); - switch(damagetype) - { - case DMG_SPIKE: - S_StartSound(players[consoleplayer].mo, sfx_spkdth); - break; - default: - P_PlayRinglossSound(players[consoleplayer].mo); - break; - } - break; + P_DoPlayerPain(player, NULL, NULL); + + if (player->powers[pw_shield]) + P_RemoveShield(player); + else + P_PlayerRingBurst(player, player->health - 1); + + if (damagetype == DMG_SPIKE) + S_StartSound(player->mo, sfx_spkdth); + else if (player->powers[pw_shield]) + S_StartSound(player->mo, sfx_shldls); + else + P_PlayRinglossSound(player->mo); } - P_KillMobj(players[consoleplayer].mo, NULL, NULL, damagetype); + else + P_KillMobj(player->mo, NULL, NULL, damagetype); break; } case SERVER_PLAYER_RINGS: - players[consoleplayer].health = DW_ReadUINT16(data) + 1; - players[consoleplayer].mo->health = players[consoleplayer].health; + player->health = DW_ReadUINT16(data) + 1; + player->mo->health = player->health; break; case SERVER_FORCE_MOVE: @@ -422,13 +469,48 @@ static void ClientHandlePacket(UINT8 node, DataWrap data) const fixed_t x = DW_ReadFixed(data), y = DW_ReadFixed(data), z = DW_ReadFixed(data); - P_TeleportMove(players[consoleplayer].mo, x, y, z); + P_TeleportMove(player->mo, x, y, z); P_SetTarget(&tmthing, NULL); break; } + case SERVER_POWERUP: + { + powertype_t power = DW_ReadUINT8(data); + UINT16 setting = DW_ReadUINT16(data); + switch(power) + { + case pw_shield: + player->powers[pw_shield] = setting | (player->powers[pw_shield] & SH_STACK); + switch(setting) + { + case SH_FORCE: + player->powers[pw_shield] |= 1; + break; + case SH_ELEMENTAL: + if (player->powers[pw_underwater] > 1 && player->powers[pw_underwater] <= 12*TICRATE + 1) + P_RestoreMusic(player); + player->powers[pw_underwater] = 0; + + if (player->powers[pw_spacetime] > 1) + P_RestoreMusic(player); + player->powers[pw_spacetime] = 0; + break; + default: + break; + } + S_StartSound(player->mo, sfx_shield); + P_SpawnShieldOrb(player); + break; + default: + CONS_Printf("NETWORK: Unknown power type recieved from server.\n"); + break; + } + break; + } + default: - CONS_Printf("NETWORK: Unknown message type recieved from node %u!\n", node); + CONS_Printf("NETWORK: Unknown message type recieved from server!\n"); break; } } @@ -477,7 +559,7 @@ void Net_AckTicker(void) if (setjmp(safety)) CONS_Printf("NETWORK: There was an EOF error in a recieved packet from server! len %u\n", e.packet->dataLength); else - ClientHandlePacket(servernode, D_NewDataWrap(e.packet->data, e.packet->dataLength, &safety)); + ClientHandlePacket(D_NewDataWrap(e.packet->data, e.packet->dataLength, &safety)); enet_packet_destroy(e.packet); break; @@ -609,6 +691,7 @@ boolean D_NetConnect(const char *hostname, const char *port) } CONS_Printf("NETWORK: Connection failed...\n"); + server = true; servernode = 0; enet_host_destroy(ClientHost); ClientHost = NULL; @@ -817,8 +900,9 @@ void Net_SendClientMove(boolean force) ENetPacket *packet; UINT8 *buf = net_buffer; boolean reliable = false; + player_t *player = &players[consoleplayer]; - if (!netgame || server || !addedtogame || !players[consoleplayer].mo) + if (!netgame || server || !addedtogame || !player->mo) return; // only update once a second unless buttons changed. @@ -827,19 +911,36 @@ void Net_SendClientMove(boolean force) if (lastMove+NEWTICRATE < I_GetTime() && !reliable) return; lastMove = I_GetTime(); - G_CopyTiccmd(&lastCmd, &players[consoleplayer].cmd, 1); + G_CopyTiccmd(&lastCmd, &player->cmd, 1); WRITEUINT8(buf, CLIENT_MOVE); - WRITESINT8(buf, players[consoleplayer].cmd.forwardmove); - WRITESINT8(buf, players[consoleplayer].cmd.sidemove); - WRITEINT16(buf, players[consoleplayer].cmd.angleturn); - WRITEINT16(buf, players[consoleplayer].cmd.aiming); - WRITEUINT16(buf, players[consoleplayer].cmd.buttons); + WRITESINT8(buf, player->cmd.forwardmove); + WRITESINT8(buf, player->cmd.sidemove); + WRITEINT16(buf, player->cmd.angleturn); + WRITEINT16(buf, player->cmd.aiming); + WRITEUINT16(buf, player->cmd.buttons); + WRITEFIXED(buf, player->mo->x); + WRITEFIXED(buf, player->mo->y); + WRITEFIXED(buf, player->mo->z); + + packet = enet_packet_create(net_buffer, buf-net_buffer, reliable ? ENET_PACKET_FLAG_RELIABLE : 0); + enet_peer_send(nodetopeer[servernode], CHANNEL_MOVE, packet); +} + +void Net_SendClientJump(void) +{ + ENetPacket *packet; + UINT8 *buf = net_buffer; + + if (!netgame || server || !addedtogame || !players[consoleplayer].mo) + return; + + WRITEUINT8(buf, CLIENT_ATTACK); WRITEFIXED(buf, players[consoleplayer].mo->x); WRITEFIXED(buf, players[consoleplayer].mo->y); WRITEFIXED(buf, players[consoleplayer].mo->z); - packet = enet_packet_create(net_buffer, buf-net_buffer, reliable ? ENET_PACKET_FLAG_RELIABLE : 0); + packet = enet_packet_create(net_buffer, buf-net_buffer, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(nodetopeer[servernode], CHANNEL_MOVE, packet); } @@ -971,7 +1072,7 @@ void Net_SendRemove(UINT16 id) enet_host_broadcast(ServerHost, CHANNEL_MOVE, packet); } -void Net_SendKill(UINT16 id) +void Net_SendKill(UINT16 id, UINT16 kid) { ENetPacket *packet; UINT8 *buf = net_buffer; @@ -994,6 +1095,7 @@ void Net_SendKill(UINT16 id) WRITEUINT8(buf, SERVER_KILL); WRITEUINT16(buf, id); + WRITEUINT16(buf, kid); packet = enet_packet_create(net_buffer, buf-net_buffer, ENET_PACKET_FLAG_RELIABLE); enet_host_broadcast(ServerHost, CHANNEL_MOVE, packet); @@ -1054,3 +1156,20 @@ static void Net_ForceMove(player_t *player) packet = enet_packet_create(net_buffer, buf-net_buffer, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(nodetopeer[playernode[player-players]], CHANNEL_GENERAL, packet); } + +void Net_AwardPowerup(player_t *player, powertype_t power, UINT16 data) +{ + + ENetPacket *packet; + UINT8 *buf = net_buffer; + + if (!netgame || !server) + return; + + WRITEUINT8(buf, SERVER_POWERUP); + WRITEUINT8(buf, power); + WRITEUINT16(buf, data); + + packet = enet_packet_create(net_buffer, buf-net_buffer, ENET_PACKET_FLAG_RELIABLE); + enet_peer_send(nodetopeer[playernode[player-players]], CHANNEL_GENERAL, packet); +} diff --git a/src/d_enet.h b/src/d_enet.h index 4fc98628f85847eef022d303fcecb1a2b495b53e..6c874322ad994b5ae3a470165fdf23998e9803a4 100644 --- a/src/d_enet.h +++ b/src/d_enet.h @@ -21,12 +21,14 @@ void Net_CloseConnection(INT32 node); void Net_SendJoin(void); void Net_SendCharacter(void); void Net_SendClientMove(boolean force); +void Net_SendClientJump(void); void Net_SpawnPlayer(UINT8 pnum, UINT8 node); void Net_SendChat(char *line); void Net_SendPlayerDamage(UINT8 pnum, UINT8 damagetype); void Net_SendMobjMove(mobj_t *mobj); void Net_SendRemove(UINT16 id); -void Net_SendKill(UINT16 id); +void Net_SendKill(UINT16 id, UINT16 kid); void Net_SendPlayerRings(UINT8 pnum); void Net_ResetLevel(void); +void Net_AwardPowerup(player_t *player, powertype_t power, UINT16 data); diff --git a/src/p_enemy.c b/src/p_enemy.c index 0b6e9a3279143322fbd710326aee4fa0a8396bf4..754d88f47b9d9134632ad9f08d1d2d988a79d045 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -23,6 +23,7 @@ #include "r_things.h" #include "i_video.h" #include "lua_hook.h" +#include "d_enet.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -2971,6 +2972,7 @@ void A_JumpShield(mobj_t *actor) player->powers[pw_shield] = SH_JUMP|(player->powers[pw_shield] & SH_STACK); P_SpawnShieldOrb(player); } + Net_AwardPowerup(player, pw_shield, SH_JUMP); S_StartSound(player->mo, actor->info->seesound); } @@ -3003,6 +3005,7 @@ void A_RingShield(mobj_t *actor) player->powers[pw_shield] = SH_ATTRACT|(player->powers[pw_shield] & SH_STACK); P_SpawnShieldOrb(player); } + Net_AwardPowerup(player, pw_shield, SH_ATTRACT); S_StartSound(player->mo, actor->info->seesound); } @@ -3201,6 +3204,7 @@ void A_BombShield(mobj_t *actor) player->powers[pw_shield] = SH_BOMB|(player->powers[pw_shield] & SH_STACK); P_SpawnShieldOrb(player); } + Net_AwardPowerup(player, pw_shield, SH_BOMB); S_StartSound(player->mo, actor->info->seesound); } @@ -3233,6 +3237,7 @@ void A_WaterShield(mobj_t *actor) player->powers[pw_shield] = SH_ELEMENTAL|(player->powers[pw_shield] & SH_STACK); P_SpawnShieldOrb(player); } + Net_AwardPowerup(player, pw_shield, SH_ELEMENTAL); if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1) P_RestoreMusic(player); @@ -3277,6 +3282,7 @@ void A_ForceShield(mobj_t *actor) } else player->powers[pw_shield] = SH_FORCE|(player->powers[pw_shield] & SH_STACK)|0x01; + Net_AwardPowerup(player, pw_shield, SH_FORCE); S_StartSound(player->mo, actor->info->seesound); } @@ -3313,6 +3319,7 @@ void A_PityShield(mobj_t *actor) player->powers[pw_shield] = SH_PITY+(player->powers[pw_shield] & SH_STACK); P_SpawnShieldOrb(player); } + Net_AwardPowerup(player, pw_shield, SH_PITY); S_StartSound(player->mo, actor->info->seesound); } diff --git a/src/p_inter.c b/src/p_inter.c index e3886f346081683e7eca3ebf035ac706fc0f76d3..2bf84e88cdd14bd625fbc3a85d91746bd02256b9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2319,7 +2319,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (server && !target->player && target->mobjnum != 0) { - Net_SendKill(target->mobjnum); + Net_SendKill(target->mobjnum, source ? source->mobjnum : 0); target->mobjnum = 0; } diff --git a/src/p_map.c b/src/p_map.c index 201805170c9e0b70835f4d8e9b8b5310a1b2e8a4..ca9b10aa3c3d13b7a495a29d7f265713c4409c7b 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -354,14 +354,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if ((tmznext <= thzh && tmz > thzh) || (tmznext > thzh - sprarea && tmznext < thzh)) { - const fixed_t oldz = tmthing->z; - if (tmthing->eflags & MFE_VERTICALFLIP) - tmthing->z = thing->z - tmthing->height - 1; - else - tmthing->z = thing->z + thing->height + 1; - Net_SendClientMove(true); // Tell the server EXACTLY where we were since we detected a potential hit here! - tmthing->z = oldz; - + // TODO: tell the server we're springing (somehow) so it doesn't hurt us. P_DoSpring(thing, tmthing); return true; } @@ -527,7 +520,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } if ((thing->type == MT_SPRINGSHELL || thing->type == MT_YELLOWSHELL) && thing->health > 0 - && (tmthing->player || (tmthing->flags & MF_PUSHABLE)) && tmthing->health > 0) + && (tmthing->type == MT_PLAYER || (tmthing->flags & MF_PUSHABLE)) && tmthing->health > 0) { // Multiplying by -1 inherently flips "less than" and "greater than" fixed_t tmz = ((thing->eflags & MFE_VERTICALFLIP) ? -(tmthing->z + tmthing->height) : tmthing->z); diff --git a/src/p_mobj.c b/src/p_mobj.c index 8df3a43e40739c812ca2ed07a872dac585c30202..cc54f6e5c3c7668834473595a31360f716b75a02 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -567,14 +567,14 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) if (st->action.acp1) { - boolean runit = server; + boolean runit = server || !mobj->mobjnum; var1 = st->var1; var2 = st->var2; #ifdef HAVE_BLUA astate = st; #endif - if (!runit - && (st->action.acp1 == A_PlayActiveSound + if (runit + || st->action.acp1 == A_PlayActiveSound || st->action.acp1 == A_PlayAttackSound || st->action.acp1 == A_PlaySeeSound || st->action.acp1 == A_PlaySound @@ -589,7 +589,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) || st->action.acp1 == A_ParticleSpawn || st->action.acp1 == A_SetSolidSteam || st->action.acp1 == A_UnsetSolidSteam - || st->action.acp1 == A_BubbleCheck)) + || st->action.acp1 == A_BubbleCheck) runit = true; if (runit) st->action.acp1(mobj); diff --git a/src/p_user.c b/src/p_user.c index 76ef1f1f12b45c679101dd5e28d3e777011fd84b..e96a52a91832a11eb2adc6168b30eef043652b20 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3578,6 +3578,8 @@ void P_DoJump(player_t *player, boolean soundandstate) if (!player->jumpfactor) return; + Net_SendClientJump(); + if (player->climbing) { // Jump this high.