From 952fc43e3c4b6aae2c06dde80a1f48caf70a6d0c Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 12 Dec 2009 11:07:59 +0000 Subject: [PATCH] multiplayer fixes git-svn-id: https://svn.eduke32.com/eduke32@1560 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/src/winlayer.c | 4 +- polymer/eduke32/source/duke3d.h | 22 ++- polymer/eduke32/source/funct.h | 1 + polymer/eduke32/source/game.c | 283 +++++++++++++++++++-------- polymer/eduke32/source/gameexec.c | 72 ++----- polymer/eduke32/source/player.c | 2 +- polymer/eduke32/source/premap.c | 69 +++++++ 7 files changed, 300 insertions(+), 153 deletions(-) diff --git a/polymer/eduke32/build/src/winlayer.c b/polymer/eduke32/build/src/winlayer.c index 1b0f8407d..230269709 100644 --- a/polymer/eduke32/build/src/winlayer.c +++ b/polymer/eduke32/build/src/winlayer.c @@ -3403,7 +3403,9 @@ static int32_t SetupOpenGL(int32_t width, int32_t height, int32_t bitspp) else if (!Bstrcmp(glinfo.vendor,"3Dfx Interactive Inc.")) err = 1; else if (!Bstrcmp(glinfo.vendor,"Intel")) { - if (!Bstrcmp(glinfo.renderer,"Intel 865G")) + if (!Bstrcmp(glinfo.renderer,"Intel 845G")) + err = 0; + else if (!Bstrcmp(glinfo.renderer,"Intel 865G")) err = 0; else if (!Bstrcmp(glinfo.renderer,"Intel 915G")) err = 0; diff --git a/polymer/eduke32/source/duke3d.h b/polymer/eduke32/source/duke3d.h index 3a47940bb..296bbfede 100644 --- a/polymer/eduke32/source/duke3d.h +++ b/polymer/eduke32/source/duke3d.h @@ -832,6 +832,7 @@ enum GamevarFlags_t { GAMEVAR_CHARPTR = 0x00010000, // plValues is a pointer to a char GAMEVAR_NORESET = 0x00020000, // var values are not reset when restoring map state GAMEVAR_SPECIAL = 0x00040000, // flag for structure member shortcut vars + GAMEVAR_NOMULTI = 0x00080000, // don't attach to multiplayer packets }; enum GamearrayFlags_t { @@ -1094,31 +1095,32 @@ enum DukePacket_t { PACKET_MASTER_TO_SLAVE, PACKET_SLAVE_TO_MASTER, - PACKET_VERSION, - - /* don't change anything above this line */ PACKET_NUM_PLAYERS, PACKET_PLAYER_INDEX, PACKET_PLAYER_DISCONNECTED, - PACKET_MESSAGE, - + PACKET_PLAYER_SPAWN, + PACKET_REQUEST_GAMESTATE, PACKET_NEW_GAME, + PACKET_LOAD_GAME, + + // any packet with an ID higher than PACKET_BROADCAST is rebroadcast by server + // this is so hacked clients can't create fake server packets and get the server + // to send them to everyone + + PACKET_BROADCAST, PACKET_RTS, - PACKET_MENU_LEVEL_QUIT, PACKET_WEAPON_CHOICE, PACKET_PLAYER_OPTIONS, PACKET_PLAYER_NAME, - - PACKET_REQUEST_GAMESTATE, + PACKET_VERSION, + PACKET_MESSAGE, PACKET_USER_MAP, PACKET_MAP_VOTE, PACKET_MAP_VOTE_INITIATE, PACKET_MAP_VOTE_CANCEL, - PACKET_LOAD_GAME, - PACKET_NULL_PACKET, PACKET_PLAYER_READY, PACKET_QUIT = 255 // should match mmulti I think }; diff --git a/polymer/eduke32/source/funct.h b/polymer/eduke32/source/funct.h index 07fc9d06e..c73e33e9b 100644 --- a/polymer/eduke32/source/funct.h +++ b/polymer/eduke32/source/funct.h @@ -184,6 +184,7 @@ extern void G_MoveWorld(void); extern void A_MoveCyclers(void); extern void A_MoveDummyPlayers(void); extern void P_ResetStatus(int32_t snum); +extern void P_ResetPlayer(int32_t snum); // game.c extern inline void G_SetStatusBarScale(int32_t sc); diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 89e8e4b02..b5d83dfb0 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -52,6 +52,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ENetHost * net_server = NULL; ENetHost * net_client = NULL; ENetPeer * net_peer = NULL; +int32_t net_port = 23513; #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -78,7 +79,6 @@ static int32_t g_noSound = 0; static int32_t g_noMusic = 0; static char *CommandMap = NULL; static char *CommandName = NULL; -static int32_t g_keepAddr = 0; int32_t CommandWeaponChoice = 0; static struct strllist { @@ -608,6 +608,7 @@ void Net_Disconnect(void) enet_peer_reset(net_peer); net_peer = NULL; enet_host_destroy(net_client); + net_client = NULL; } if (net_server) @@ -636,6 +637,7 @@ void Net_Disconnect(void) } } enet_host_destroy(net_server); + net_server = NULL; } } @@ -794,7 +796,8 @@ void Net_NewGame(int32_t volume, int32_t level) } static mapstate_t *g_multiMapState = NULL; -static int32_t spritecrc[MAXSPRITES], lastupdate[MAXSPRITES]; +static int32_t spritecrc[MAXSPRITES], lastupdate[MAXSPRITES], sectcrc[MAXSECTORS], lastsectupdate[MAXSECTORS]; +static int32_t wallcrc[MAXWALLS], lastwallupdate[MAXWALLS]; static int32_t peractorvals[MAXGAMEVARS][MAXSPRITES], perplayervals[MAXGAMEVARS][MAXPLAYERS]; void Net_ParsePacket(ENetEvent * event) @@ -816,9 +819,9 @@ void Net_ParsePacket(ENetEvent * event) j = 1; - packbufleng = qlz_size_decompressed((char *)packbuf+1); + packbufleng = qlz_size_decompressed((char *)(packbuf)+1); packbuf = Bcalloc(1, packbufleng); - packbufleng = qlz_decompress((char *)event->packet->data+1, packbuf+1, state_decompress); + packbufleng = qlz_decompress((char *)(event->packet->data)+1, (char *)(packbuf)+1, state_decompress); Bmemcpy(&ticrandomseed, &packbuf[j], sizeof(ticrandomseed)); j += sizeof(ticrandomseed); @@ -827,10 +830,13 @@ void Net_ParsePacket(ENetEvent * event) { if (g_player[i].playerquitflag == 0) continue; - if (i == myconnectindex) + Bmemcpy(&g_player[i].ps->dead_flag, &packbuf[j], sizeof(int16_t)); + j += sizeof(int16_t); + + if (i == myconnectindex && !g_player[i].ps->dead_flag) { - j += sizeof(input_t)-sizeof(loc.filler)+(sizeof(vec3_t)*3) + 4; - goto process; + j += sizeof(input_t)-sizeof(loc.filler)+(sizeof(vec3_t)*3) + sizeof(int16_t)*2; + goto process; } nsyn = (input_t *)&inputfifo[0][0]; @@ -853,6 +859,8 @@ void Net_ParsePacket(ENetEvent * event) process: Bmemcpy(&sprite[g_player[i].ps->i].extra, &packbuf[j], sizeof(int16_t)); j += sizeof(int16_t); + Bmemcpy(&sprite[g_player[i].ps->i].cstat, &packbuf[j], sizeof(int16_t)); + j += sizeof(int16_t); Bmemcpy(&g_player[i].ps->kickback_pic, &packbuf[j], sizeof(int16_t)); j += sizeof(int16_t); Bmemcpy(&g_player[i].ps->shield_amount, &packbuf[j], sizeof(int16_t)); @@ -877,11 +885,22 @@ process: j += sizeof(int16_t); Bmemcpy(&g_player[i].ps->last_extra, &packbuf[j], sizeof(int16_t)); j += sizeof(int16_t); - Bmemcpy(&g_player[i].ps->dead_flag, &packbuf[j], sizeof(int16_t)); - j += sizeof(int16_t); l = i; + { + int16_t i = g_player[l].ps->i, jj = j++; + int32_t oa = T5-(intptr_t)&script[0]; + + Bmemcpy(&T5, &packbuf[j], sizeof(T5)); + j += sizeof(T5); + + if (oa != T5) T3 = T4 = 0; + if (packbuf[jj] & 2) T5 += (intptr_t)&script[0]; + } + + i = l; + do { int16_t var_id; @@ -935,10 +954,12 @@ process: deletesprite(ahead); // sprite updates tacked on to the end of the packet - while ((unsigned)(packbufleng-j) > sizeof(spritetype)+sizeof(ActorData_t)) + + l = packbuf[j++]; + while (l--) { - int16_t i, sect, statnum, osect, ostatnum, jj, lightid, opicnum; - _prlight *mylight; + int16_t i, sect, statnum, osect, ostatnum, jj, lightid = -1, opicnum; + _prlight *mylight = NULL; Bmemcpy(&i, &packbuf[j], sizeof(int16_t)); j += sizeof(int16_t); @@ -968,16 +989,17 @@ process: sprite[i].statnum = ostatnum; if (sect != osect) changespritesect(i, sect); if (statnum != ostatnum) changespritestat(i, statnum); + mylight = ActorExtra[i].lightptr; + lightid = ActorExtra[i].lightId; } j += sizeof(spritetype); jj = j++; - mylight = ActorExtra[i].lightptr; - lightid = ActorExtra[i].lightId; - Bmemcpy(&ActorExtra[i], &packbuf[j], sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)); - j += sizeof(ActorData_t)-sizeof(ActorExtra[0].filler); + Bmemcpy(&ActorExtra[i], &packbuf[j], sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)- + sizeof(ActorExtra[0].projectile)-sizeof(ActorExtra[0].lightptr)); + j += sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)-sizeof(ActorExtra[0].projectile)-sizeof(ActorExtra[0].lightptr); ActorExtra[i].projectile = &SpriteProjectile[i]; ActorExtra[i].lightptr = mylight; @@ -1001,6 +1023,24 @@ process: } while (1); } + + l = packbuf[j++]; + while (l--) + { + Bmemcpy(&i, &packbuf[j], sizeof(int16_t)); + j += sizeof(int16_t); + Bmemcpy(§or[i], &packbuf[j], sizeof(sectortype)); + j += sizeof(sectortype); + } + + l = packbuf[j++]; + while (l--) + { + Bmemcpy(&i, &packbuf[j], sizeof(int16_t)); + j += sizeof(int16_t); + Bmemcpy(§or[i], &packbuf[j], sizeof(walltype)); + j += sizeof(walltype); + } } Bfree(packbuf); @@ -1010,9 +1050,9 @@ process: case PACKET_SLAVE_TO_MASTER: //[1] (receive slave sync buffer) j = 1; - packbufleng = qlz_size_decompressed((char *)packbuf+1); + packbufleng = qlz_size_decompressed((char *)(packbuf)+1); packbuf = Bcalloc(1, packbufleng); - packbufleng = qlz_decompress((char *)event->packet->data+1, packbuf+1, state_decompress); + packbufleng = qlz_decompress((char *)(event->packet->data)+1, (char *)(packbuf)+1, state_decompress); nsyn = (input_t *)&inputfifo[0][0]; @@ -1022,6 +1062,13 @@ process: g_player[other].movefifoend++; + // anyone the server thinks is dead can go fuck themselves + if (g_player[other].ps->dead_flag) + { + Bfree(packbuf); + break; + } + Bmemcpy(&g_player[other].ps->posx, &packbuf[j], sizeof(vec3_t) * 3); Bmemcpy(&sprite[g_player[other].ps->i], &packbuf[j], sizeof(vec3_t)); sprite[g_player[other].ps->i].z += PHEIGHT; @@ -1033,22 +1080,17 @@ process: { int16_t i = g_player[other].ps->i, jj = j++; + int32_t oa = T5-(intptr_t)&script[0]; - Bmemcpy(&T3, &packbuf[j], sizeof(T3)); - j += sizeof(T3); - Bmemcpy(&T4, &packbuf[j], sizeof(T4)); - j += sizeof(T4); Bmemcpy(&T5, &packbuf[j], sizeof(T5)); j += sizeof(T5); + if (oa != T5) T3 = T4 = 0; if (packbuf[jj] & 2) T5 += (intptr_t)&script[0]; } Bfree(packbuf); break; - case PACKET_NULL_PACKET: - break; - case PACKET_PLAYER_READY: if (net_server) { @@ -1135,6 +1177,11 @@ process: for (i=0; igm & MODE_GAME) { - j = g_player[i].ps->i; - Bmemcpy(g_player[i].ps, g_player[0].ps, sizeof(DukePlayer_t)); - g_player[i].ps->i = j; - changespritestat(j, STAT_PLAYER); - P_ResetStatus(i); - P_ResetWeapons(i); - P_ResetInventory(i); - - g_player[i].ps->last_extra = g_player[i].ps->max_player_health; - sprite[g_player[i].ps->i].extra = g_player[i].ps->max_player_health; - g_player[i].ps->runspeed = g_playerFriction; - if (g_multiMapState == NULL) g_multiMapState = Bcalloc(1, sizeof(mapstate_t)); if (g_multiMapState) { char * buf = Bmalloc(sizeof(mapstate_t)<<1); + + j = g_player[i].ps->i; + Bmemcpy(g_player[i].ps, g_player[0].ps, sizeof(DukePlayer_t)); + g_player[i].ps->i = j; + changespritestat(j, STAT_PLAYER); + P_ResetStatus(i); + P_ResetWeapons(i); + P_ResetInventory(i); + + g_player[i].ps->last_extra = g_player[i].ps->max_player_health; + sprite[g_player[i].ps->i].extra = g_player[i].ps->max_player_health; + sprite[g_player[i].ps->i].cstat = 1+256; + g_player[i].ps->runspeed = g_playerFriction; + G_SaveMapState(g_multiMapState); j = qlz_compress((char *)g_multiMapState, buf, sizeof(mapstate_t), state_compress); while (j > 1024) @@ -1431,7 +1480,7 @@ void Net_GetPackets(void) // broadcast takes care of enet_packet_destroy itself // we set the state to disconnected so enet_host_broadcast doesn't send the player back his own packets // SLAVE_TO_MASTER packets are channelID 1, so they aren't broadcast anywhere - if (event.channelID == 0) + if (event.channelID == 0 && event.packet->data[0] > PACKET_BROADCAST) { event.peer->state = ENET_PEER_STATE_DISCONNECTED; enet_host_broadcast(net_server, 0, event.packet); @@ -1467,12 +1516,12 @@ void Net_GetPackets(void) switch (event.type) { case ENET_EVENT_TYPE_RECEIVE: -/* + initprintf ("A packet of length %u was received from player %d on channel %u.\n", event.packet -> dataLength, event.peer -> data, event.channelID); -*/ + // channelID 1 is the map state transfer from the server if (event.channelID == 1) { @@ -1579,13 +1628,12 @@ void faketimerhandler(void) if (numplayers < 2) { - if (ud.multimode > 1) + if (ud.multimode > 1 && ud.playerai) TRAVERSE_CONNECT(i) if (i != myconnectindex) { //clearbufbyte(&inputfifo[g_player[i].movefifoend&(MOVEFIFOSIZ-1)][i],sizeof(input_t),0L); - if (ud.playerai) - computergetinput(i,&inputfifo[0][i]); + computergetinput(i,&inputfifo[0][i]); } } @@ -1615,10 +1663,6 @@ void faketimerhandler(void) T5 -= (intptr_t)&script[0]; } - Bmemcpy(&packbuf[j], &T3, sizeof(T3)); - j += sizeof(T3); - Bmemcpy(&packbuf[j], &T4, sizeof(T4)); - j += sizeof(T4); Bmemcpy(&packbuf[j], &T5, sizeof(T5)); j += sizeof(T5); @@ -1627,8 +1671,8 @@ void faketimerhandler(void) { char buf[1024]; - j = qlz_compress((char *)packbuf+1, (char *)buf, j, state_compress); - Bmemcpy((char *)packbuf+1, (char *)buf, j); + j = qlz_compress((char *)(packbuf)+1, (char *)buf, j, state_compress); + Bmemcpy((char *)(packbuf)+1, (char *)buf, j); j++; } @@ -1662,6 +1706,8 @@ void faketimerhandler(void) Bmemcpy(&osyn[i], &nsyn[i], sizeof(input_t)); + Bmemcpy(&packbuf[j], &g_player[i].ps->dead_flag, sizeof(int16_t)); + j += sizeof(int16_t); Bmemcpy(&packbuf[j], &nsyn[i], sizeof(input_t)); j += sizeof(input_t)-sizeof(loc.filler); Bmemcpy(&packbuf[j], &g_player[i].ps->posx, sizeof(vec3_t) * 3); @@ -1670,6 +1716,8 @@ void faketimerhandler(void) j += sizeof(int16_t) * 2; Bmemcpy(&packbuf[j], &sprite[g_player[i].ps->i].extra, sizeof(int16_t)); j += sizeof(int16_t); + Bmemcpy(&packbuf[j], &sprite[g_player[i].ps->i].cstat, sizeof(int16_t)); + j += sizeof(int16_t); Bmemcpy(&packbuf[j], &g_player[i].ps->kickback_pic, sizeof(int16_t)); j += sizeof(int16_t); Bmemcpy(&packbuf[j], &g_player[i].ps->shield_amount, sizeof(int16_t)); @@ -1694,16 +1742,39 @@ void faketimerhandler(void) j += sizeof(int16_t); Bmemcpy(&packbuf[j], &g_player[i].ps->last_extra, sizeof(int16_t)); j += sizeof(int16_t); - Bmemcpy(&packbuf[j], &g_player[i].ps->dead_flag, sizeof(int16_t)); - j += sizeof(int16_t); l = i; + + { + int32_t jj, oa; + + i = g_player[l].ps->i; + + packbuf[(jj = j++)] = 0; + + if (T5 >= (intptr_t)&script[0] && T5 < (intptr_t)(&script[g_scriptSize])) + { + packbuf[jj] |= 2; + T5 -= (intptr_t)&script[0]; + } + + oa = T5; + + Bmemcpy(&packbuf[j], &T5, sizeof(T5)); + j += sizeof(T5); + + if (oa != T5) T3 = T4 = 0; + + if (packbuf[jj] & 2) T5 += (intptr_t)&script[0]; + } + + i = l; { int16_t ii=g_gameVarCount-1, kk = 0; for (; ii>=0; ii--) { - if ((aGameVars[ii].dwFlags & GAMEVAR_PERACTOR) && aGameVars[ii].val.plValues) + if ((aGameVars[ii].dwFlags & (GAMEVAR_PERACTOR|GAMEVAR_NOMULTI)) == GAMEVAR_PERACTOR && aGameVars[ii].val.plValues) { if (peractorvals[ii][i] != aGameVars[ii].val.plValues[i]) { @@ -1729,7 +1800,7 @@ void faketimerhandler(void) for (; ii>=0; ii--) { - if ((aGameVars[ii].dwFlags & GAMEVAR_PERPLAYER) && aGameVars[ii].val.plValues) + if ((aGameVars[ii].dwFlags & (GAMEVAR_PERPLAYER|GAMEVAR_NOMULTI)) == GAMEVAR_PERPLAYER && aGameVars[ii].val.plValues) { if (perplayervals[ii][i] != aGameVars[ii].val.plValues[i]) { @@ -1763,6 +1834,9 @@ void faketimerhandler(void) { int32_t lists[] = { STAT_STANDABLE, STAT_EFFECTOR, STAT_ACTOR, STAT_ZOMBIEACTOR, STAT_PROJECTILE }, zz; + int32_t zj = j++; + + packbuf[zj] = 0; for (zz = 0; (unsigned)zz < (sizeof(lists)/sizeof(lists[0])); zz++) TRAVERSE_SPRITE_STAT(headspritestat[lists[zz]], i, nexti) @@ -1799,8 +1873,9 @@ void faketimerhandler(void) packbuf[jj] |= 4; T6 -= (intptr_t)&script[0]; } - Bmemcpy(&packbuf[j], &ActorExtra[i], sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)); - j += sizeof(ActorData_t)-sizeof(ActorExtra[0].filler); + Bmemcpy(&packbuf[j], &ActorExtra[i], sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)- + sizeof(ActorExtra[0].projectile)-sizeof(ActorExtra[0].lightptr)); + j += sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)-sizeof(ActorExtra[0].projectile)-sizeof(ActorExtra[0].lightptr); if (packbuf[jj] & 1) T2 += (intptr_t)&script[0]; if (packbuf[jj] & 2) T5 += (intptr_t)&script[0]; @@ -1836,13 +1911,59 @@ void faketimerhandler(void) } if (k > 4) break; } + packbuf[zj] = k; + + packbuf[(zj = j++)] = 0; + for (i = numsectors-1; i >= 0; i--) + { + if (totalclock > (lastsectupdate[i] + (TICSPERFRAME * 12))) + { + l = crc32once((uint8_t *)§or[i], sizeof(sectortype)); + + if (sectcrc[i] != l) + { + sectcrc[i] = l; + lastsectupdate[i] = totalclock; + Bmemcpy(&packbuf[j], &i, sizeof(int16_t)); + j += sizeof(int16_t); + Bmemcpy(&packbuf[j], §or[i], sizeof(sectortype)); + j += sizeof(sectortype); + k++; + } + } + if (k > 6) break; + } + packbuf[zj] = k; + + packbuf[(zj = j++)] = 0; + for (i = numwalls-1; i >= 0; i--) + { + if (totalclock > (lastwallupdate[i] + (TICSPERFRAME * 12))) + { + l = crc32once((uint8_t *)&wall[i], sizeof(walltype)); + + if (wallcrc[i] != l) + { + wallcrc[i] = l; + lastwallupdate[i] = totalclock; + Bmemcpy(&packbuf[j], &i, sizeof(int16_t)); + j += sizeof(int16_t); + Bmemcpy(&packbuf[j], &wall[i], sizeof(walltype)); + j += sizeof(walltype); + k++; + } + } + if (k > 6) break; + } + packbuf[zj] = k; + } { char buf[4096]; - j = qlz_compress((char *)packbuf+1, (char *)buf, j, state_compress); - Bmemcpy((char *)packbuf+1, (char *)buf, j); + j = qlz_compress((char *)(packbuf)+1, (char *)buf, j, state_compress); + Bmemcpy((char *)(packbuf)+1, (char *)buf, j); j++; } @@ -5313,7 +5434,7 @@ int32_t A_Spawn(int32_t j, int32_t pn) { sp->xrepeat = 31; sp->yrepeat = 1; - sp->z = sector[sprite[j].sectnum].floorz-(40<<8); + sp->z = sector[sprite[j].sectnum].floorz-PHEIGHT; } else { @@ -7183,8 +7304,10 @@ void G_DoSpriteAnimations(int32_t x,int32_t y,int32_t a,int32_t smoothratio) { t->x -= mulscale16(65536-smoothratio,g_player[s->yvel].ps->posx-g_player[s->yvel].ps->oposx); t->y -= mulscale16(65536-smoothratio,g_player[s->yvel].ps->posy-g_player[s->yvel].ps->oposy); - t->z += /*g_player[s->yvel].ps->oposz +*/ mulscale16(smoothratio,g_player[s->yvel].ps->posz-g_player[s->yvel].ps->oposz) - PHEIGHT; - t->z += (40<<8); + // dirty hack + if (g_player[s->yvel].ps->dead_flag) t->z = g_player[s->yvel].ps->oposz; + t->z += mulscale16(smoothratio,g_player[s->yvel].ps->posz-g_player[s->yvel].ps->oposz) - + (g_player[s->yvel].ps->dead_flag ? 0 : PHEIGHT) + PHEIGHT; } else if ((s->statnum == STAT_DEFAULT && s->picnum != CRANEPOLE) || s->statnum == STAT_PLAYER || s->statnum == STAT_STANDABLE || s->statnum == STAT_PROJECTILE || s->statnum == STAT_MISC || s->statnum == STAT_ACTOR) @@ -7353,7 +7476,7 @@ void G_DoSpriteAnimations(int32_t x,int32_t y,int32_t a,int32_t smoothratio) { t->x = omy.x+mulscale16((int32_t)(my.x-omy.x),smoothratio); t->y = omy.y+mulscale16((int32_t)(my.y-omy.y),smoothratio); - t->z = omy.z+mulscale16((int32_t)(my.z-omy.z),smoothratio)+(40<<8); + t->z = omy.z+mulscale16((int32_t)(my.z-omy.z),smoothratio)+PHEIGHT; t->ang = omyang+mulscale16((int32_t)(((myang+1024-omyang)&2047)-1024),smoothratio); t->sectnum = mycursectnum; } @@ -9196,7 +9319,6 @@ static void G_ShowParameterHelp(void) "-map [file.map]\tLoads a map\n" "-m\t\tDisable monsters\n" "-nam/-ww2gi\tRun in NAM or WW2GI-compatible mode\n" - "-net\t\tEnable multiplayer (see documentation)\n" "-r\t\tRecord demo\n" "-s#\t\tSet skill level (1-4)\n" #if defined RENDERTYPEWIN || (defined RENDERTYPESDL && !defined __APPLE__ && defined HAVE_GTK2) @@ -9237,9 +9359,6 @@ static void G_ShowDebugHelp(void) "-nologo\t\tSkip the logo anim\n" "-ns/-nm\t\tDisable sound or music\n" "-q#\t\tFake multiplayer with # (2-8) players\n" - "-rmnet\t\tUse network config file (OBSOLETE, see -net)\n" - "-stun\t\tUse UDP hole punching for multiplayer connections\n" - /*"-unstable \tForce EDuke32 to execute unsafe CON commands (and crash)\n"*/ "-w\t\tShow coordinates\n" "-z#/-condebug\tEnable line-by-line CON compile debugging at level #\n" ; @@ -9756,15 +9875,13 @@ static void G_CheckCommandLine(int32_t argc, const char **argv) i++; continue; } - if (!Bstrcasecmp(c+1,"keepaddr")) + if (!Bstrcasecmp(c+1,"port")) { - g_keepAddr = 1; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"stun")) - { - natfree = 1; //Addfaz NatFree + if (argc > i+1) + { + net_port = atoi(argv[i+1]); + i++; + } i++; continue; } @@ -9777,7 +9894,7 @@ static void G_CheckCommandLine(int32_t argc, const char **argv) /* enet_address_set_host (& address, "x.x.x.x"); */ address.host = ENET_HOST_ANY; - address.port = 23513; + address.port = net_port; net_server = enet_host_create (&address, MAXPLAYERS, 0, 0); @@ -9794,6 +9911,7 @@ static void G_CheckCommandLine(int32_t argc, const char **argv) { ENetAddress address; ENetEvent event; + char * addrstr = NULL; Net_Disconnect(); @@ -9806,8 +9924,9 @@ static void G_CheckCommandLine(int32_t argc, const char **argv) continue; } - enet_address_set_host (&address, (char *)argv[i+1]); - address.port = 23513; + addrstr = strtok((char *)argv[i+1],":"); + enet_address_set_host (&address, addrstr); + address.port = atoi((addrstr = strtok(NULL,":")) == NULL ? "23513" : addrstr); // use 2 channels for easy packet sorting at a lower level than the game later net_peer = enet_host_connect (net_client, &address, 2); diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index 7079f6bcd..6674375c6 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -2770,68 +2770,22 @@ nullquote: } else { - vec3_t tmpvect; + if (vm.g_p == myconnectindex) + { + g_cameraDistance = 0; + g_cameraClock = totalclock; + } - tmpvect.x = g_player[vm.g_p].ps->posx; - tmpvect.y = g_player[vm.g_p].ps->posy; - tmpvect.z = g_player[vm.g_p].ps->posz+PHEIGHT; - P_RandomSpawnPoint(vm.g_p); - vm.g_sp->x = ActorExtra[vm.g_i].bposx = g_player[vm.g_p].ps->bobposx = g_player[vm.g_p].ps->oposx = g_player[vm.g_p].ps->posx; - vm.g_sp->y = ActorExtra[vm.g_i].bposy = g_player[vm.g_p].ps->bobposy = g_player[vm.g_p].ps->oposy =g_player[vm.g_p].ps->posy; - vm.g_sp->z = ActorExtra[vm.g_i].bposy = g_player[vm.g_p].ps->oposz =g_player[vm.g_p].ps->posz; - updatesector(g_player[vm.g_p].ps->posx,g_player[vm.g_p].ps->posy,&g_player[vm.g_p].ps->cursectnum); - setsprite(g_player[vm.g_p].ps->i,&tmpvect); - vm.g_sp->cstat = 257; + if (net_server) + { + P_ResetPlayer(vm.g_p); - vm.g_sp->shade = -12; - vm.g_sp->clipdist = 64; - vm.g_sp->xrepeat = 42; - vm.g_sp->yrepeat = 36; - vm.g_sp->owner = vm.g_i; - vm.g_sp->xoffset = 0; - vm.g_sp->pal = g_player[vm.g_p].ps->palookup; + packbuf[0] = PACKET_PLAYER_SPAWN; + packbuf[1] = vm.g_p; + packbuf[2] = 0; - g_player[vm.g_p].ps->last_extra = vm.g_sp->extra = g_player[vm.g_p].ps->max_player_health; - g_player[vm.g_p].ps->wantweaponfire = -1; - g_player[vm.g_p].ps->horiz = 100; - g_player[vm.g_p].ps->on_crane = -1; - g_player[vm.g_p].ps->frag_ps = vm.g_p; - g_player[vm.g_p].ps->horizoff = 0; - g_player[vm.g_p].ps->opyoff = 0; - g_player[vm.g_p].ps->wackedbyactor = -1; - g_player[vm.g_p].ps->shield_amount = g_startArmorAmount; - g_player[vm.g_p].ps->dead_flag = 0; - g_player[vm.g_p].ps->pals_time = 0; - g_player[vm.g_p].ps->footprintcount = 0; - g_player[vm.g_p].ps->weapreccnt = 0; - g_player[vm.g_p].ps->fta = 0; - g_player[vm.g_p].ps->ftq = 0; - g_player[vm.g_p].ps->posxv = g_player[vm.g_p].ps->posyv = 0; - g_player[vm.g_p].ps->rotscrnang = 0; - g_player[vm.g_p].ps->runspeed = g_playerFriction; - g_player[vm.g_p].ps->falling_counter = 0; - - ActorExtra[vm.g_i].extra = -1; - ActorExtra[vm.g_i].owner = vm.g_i; - - ActorExtra[vm.g_i].cgg = 0; - ActorExtra[vm.g_i].movflag = 0; - ActorExtra[vm.g_i].tempang = 0; - ActorExtra[vm.g_i].actorstayput = -1; - ActorExtra[vm.g_i].dispicnum = 0; - ActorExtra[vm.g_i].owner = g_player[vm.g_p].ps->i; - - P_ResetInventory(vm.g_p); - P_ResetWeapons(vm.g_p); - - g_player[vm.g_p].ps->reloading = 0; - - g_player[vm.g_p].ps->movement_lock = 0; - - if (apScriptGameEvent[EVENT_RESETPLAYER]) - X_OnEvent(EVENT_RESETPLAYER, g_player[vm.g_p].ps->i, vm.g_p, -1); - g_cameraDistance = 0; - g_cameraClock = totalclock; + enet_host_broadcast(net_server, 0 , enet_packet_create(packbuf, 3, ENET_PACKET_FLAG_RELIABLE)); + } } P_UpdateScreenPal(g_player[vm.g_p].ps); //AddLog("EOF: resetplayer"); diff --git a/polymer/eduke32/source/player.c b/polymer/eduke32/source/player.c index 1a7210860..51085d77e 100644 --- a/polymer/eduke32/source/player.c +++ b/polymer/eduke32/source/player.c @@ -187,7 +187,7 @@ int32_t A_GetHitscanRange(int32_t i) int32_t zoff = 0; hitdata_t hitinfo; - if (PN == APLAYER) zoff = (40<<8); + if (PN == APLAYER) zoff = PHEIGHT; SZ -= zoff; hitscan((const vec3_t *)&sprite[i],SECT, diff --git a/polymer/eduke32/source/premap.c b/polymer/eduke32/source/premap.c index e4d25296b..0ded2afc5 100644 --- a/polymer/eduke32/source/premap.c +++ b/polymer/eduke32/source/premap.c @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "duke3d.h" #include "osd.h" +#include "gamedef.h" #ifdef RENDERTYPEWIN #define WIN32_LEAN_AND_MEAN @@ -619,6 +620,74 @@ void P_RandomSpawnPoint(int32_t snum) p->oposz = p->posz = g_playerSpawnPoints[i].oz; p->ang = g_playerSpawnPoints[i].oa; p->cursectnum = g_playerSpawnPoints[i].os; + sprite[p->i].cstat = 1+256; +} + +void P_ResetPlayer(int32_t snum) +{ + vec3_t tmpvect; + spritetype *sp = &sprite[g_player[snum].ps->i]; + + tmpvect.x = g_player[snum].ps->posx; + tmpvect.y = g_player[snum].ps->posy; + tmpvect.z = g_player[snum].ps->posz+PHEIGHT; + P_RandomSpawnPoint(snum); + sp->x = ActorExtra[g_player[snum].ps->i].bposx = g_player[snum].ps->bobposx = g_player[snum].ps->oposx = g_player[snum].ps->posx; + sp->y = ActorExtra[g_player[snum].ps->i].bposy = g_player[snum].ps->bobposy = g_player[snum].ps->oposy =g_player[snum].ps->posy; + sp->z = ActorExtra[g_player[snum].ps->i].bposy = g_player[snum].ps->oposz =g_player[snum].ps->posz; + updatesector(g_player[snum].ps->posx,g_player[snum].ps->posy,&g_player[snum].ps->cursectnum); + setsprite(g_player[snum].ps->i,&tmpvect); + sp->cstat = 257; + + sp->shade = -12; + sp->clipdist = 64; + sp->xrepeat = 42; + sp->yrepeat = 36; + sp->owner = g_player[snum].ps->i; + sp->xoffset = 0; + sp->pal = g_player[snum].ps->palookup; + + g_player[snum].ps->last_extra = sp->extra = g_player[snum].ps->max_player_health; + g_player[snum].ps->wantweaponfire = -1; + g_player[snum].ps->horiz = 100; + g_player[snum].ps->on_crane = -1; + g_player[snum].ps->frag_ps = snum; + g_player[snum].ps->horizoff = 0; + g_player[snum].ps->opyoff = 0; + g_player[snum].ps->wackedbyactor = -1; + g_player[snum].ps->shield_amount = g_startArmorAmount; + g_player[snum].ps->dead_flag = 0; + g_player[snum].ps->pals_time = 0; + g_player[snum].ps->footprintcount = 0; + g_player[snum].ps->weapreccnt = 0; + g_player[snum].ps->fta = 0; + g_player[snum].ps->ftq = 0; + g_player[snum].ps->posxv = g_player[snum].ps->posyv = 0; + g_player[snum].ps->rotscrnang = 0; + g_player[snum].ps->runspeed = g_playerFriction; + g_player[snum].ps->falling_counter = 0; + + ActorExtra[g_player[snum].ps->i].extra = -1; + ActorExtra[g_player[snum].ps->i].owner = g_player[snum].ps->i; + + ActorExtra[g_player[snum].ps->i].cgg = 0; + ActorExtra[g_player[snum].ps->i].movflag = 0; + ActorExtra[g_player[snum].ps->i].tempang = 0; + ActorExtra[g_player[snum].ps->i].actorstayput = -1; + ActorExtra[g_player[snum].ps->i].dispicnum = 0; + ActorExtra[g_player[snum].ps->i].owner = g_player[snum].ps->i; + + ActorExtra[g_player[snum].ps->i].temp_data[4] = 0; + + P_ResetInventory(snum); + P_ResetWeapons(snum); + + g_player[snum].ps->reloading = 0; + + g_player[snum].ps->movement_lock = 0; + + if (apScriptGameEvent[EVENT_RESETPLAYER]) + X_OnEvent(EVENT_RESETPLAYER, g_player[snum].ps->i, snum, -1); } void P_ResetStatus(int32_t snum)