multiplayer fixes

git-svn-id: https://svn.eduke32.com/eduke32@1560 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2009-12-12 11:07:59 +00:00
parent 173edd4b3f
commit 952fc43e3c
7 changed files with 300 additions and 153 deletions

View file

@ -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,"3Dfx Interactive Inc.")) err = 1;
else if (!Bstrcmp(glinfo.vendor,"Intel")) 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; err = 0;
else if (!Bstrcmp(glinfo.renderer,"Intel 915G")) else if (!Bstrcmp(glinfo.renderer,"Intel 915G"))
err = 0; err = 0;

View file

@ -832,6 +832,7 @@ enum GamevarFlags_t {
GAMEVAR_CHARPTR = 0x00010000, // plValues is a pointer to a char GAMEVAR_CHARPTR = 0x00010000, // plValues is a pointer to a char
GAMEVAR_NORESET = 0x00020000, // var values are not reset when restoring map state GAMEVAR_NORESET = 0x00020000, // var values are not reset when restoring map state
GAMEVAR_SPECIAL = 0x00040000, // flag for structure member shortcut vars GAMEVAR_SPECIAL = 0x00040000, // flag for structure member shortcut vars
GAMEVAR_NOMULTI = 0x00080000, // don't attach to multiplayer packets
}; };
enum GamearrayFlags_t { enum GamearrayFlags_t {
@ -1094,31 +1095,32 @@ enum DukePacket_t
{ {
PACKET_MASTER_TO_SLAVE, PACKET_MASTER_TO_SLAVE,
PACKET_SLAVE_TO_MASTER, PACKET_SLAVE_TO_MASTER,
PACKET_VERSION,
/* don't change anything above this line */
PACKET_NUM_PLAYERS, PACKET_NUM_PLAYERS,
PACKET_PLAYER_INDEX, PACKET_PLAYER_INDEX,
PACKET_PLAYER_DISCONNECTED, PACKET_PLAYER_DISCONNECTED,
PACKET_MESSAGE, PACKET_PLAYER_SPAWN,
PACKET_REQUEST_GAMESTATE,
PACKET_NEW_GAME, 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_RTS,
PACKET_MENU_LEVEL_QUIT,
PACKET_WEAPON_CHOICE, PACKET_WEAPON_CHOICE,
PACKET_PLAYER_OPTIONS, PACKET_PLAYER_OPTIONS,
PACKET_PLAYER_NAME, PACKET_PLAYER_NAME,
PACKET_VERSION,
PACKET_REQUEST_GAMESTATE, PACKET_MESSAGE,
PACKET_USER_MAP, PACKET_USER_MAP,
PACKET_MAP_VOTE, PACKET_MAP_VOTE,
PACKET_MAP_VOTE_INITIATE, PACKET_MAP_VOTE_INITIATE,
PACKET_MAP_VOTE_CANCEL, PACKET_MAP_VOTE_CANCEL,
PACKET_LOAD_GAME,
PACKET_NULL_PACKET,
PACKET_PLAYER_READY, PACKET_PLAYER_READY,
PACKET_QUIT = 255 // should match mmulti I think PACKET_QUIT = 255 // should match mmulti I think
}; };

View file

@ -184,6 +184,7 @@ extern void G_MoveWorld(void);
extern void A_MoveCyclers(void); extern void A_MoveCyclers(void);
extern void A_MoveDummyPlayers(void); extern void A_MoveDummyPlayers(void);
extern void P_ResetStatus(int32_t snum); extern void P_ResetStatus(int32_t snum);
extern void P_ResetPlayer(int32_t snum);
// game.c // game.c
extern inline void G_SetStatusBarScale(int32_t sc); extern inline void G_SetStatusBarScale(int32_t sc);

View file

@ -52,6 +52,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
ENetHost * net_server = NULL; ENetHost * net_server = NULL;
ENetHost * net_client = NULL; ENetHost * net_client = NULL;
ENetPeer * net_peer = NULL; ENetPeer * net_peer = NULL;
int32_t net_port = 23513;
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -78,7 +79,6 @@ static int32_t g_noSound = 0;
static int32_t g_noMusic = 0; static int32_t g_noMusic = 0;
static char *CommandMap = NULL; static char *CommandMap = NULL;
static char *CommandName = NULL; static char *CommandName = NULL;
static int32_t g_keepAddr = 0;
int32_t CommandWeaponChoice = 0; int32_t CommandWeaponChoice = 0;
static struct strllist static struct strllist
{ {
@ -608,6 +608,7 @@ void Net_Disconnect(void)
enet_peer_reset(net_peer); enet_peer_reset(net_peer);
net_peer = NULL; net_peer = NULL;
enet_host_destroy(net_client); enet_host_destroy(net_client);
net_client = NULL;
} }
if (net_server) if (net_server)
@ -636,6 +637,7 @@ void Net_Disconnect(void)
} }
} }
enet_host_destroy(net_server); 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 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]; static int32_t peractorvals[MAXGAMEVARS][MAXSPRITES], perplayervals[MAXGAMEVARS][MAXPLAYERS];
void Net_ParsePacket(ENetEvent * event) void Net_ParsePacket(ENetEvent * event)
@ -816,9 +819,9 @@ void Net_ParsePacket(ENetEvent * event)
j = 1; j = 1;
packbufleng = qlz_size_decompressed((char *)packbuf+1); packbufleng = qlz_size_decompressed((char *)(packbuf)+1);
packbuf = Bcalloc(1, packbufleng); 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)); Bmemcpy(&ticrandomseed, &packbuf[j], sizeof(ticrandomseed));
j += sizeof(ticrandomseed); j += sizeof(ticrandomseed);
@ -827,10 +830,13 @@ void Net_ParsePacket(ENetEvent * event)
{ {
if (g_player[i].playerquitflag == 0) continue; 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; j += sizeof(input_t)-sizeof(loc.filler)+(sizeof(vec3_t)*3) + sizeof(int16_t)*2;
goto process; goto process;
} }
nsyn = (input_t *)&inputfifo[0][0]; nsyn = (input_t *)&inputfifo[0][0];
@ -853,6 +859,8 @@ void Net_ParsePacket(ENetEvent * event)
process: process:
Bmemcpy(&sprite[g_player[i].ps->i].extra, &packbuf[j], sizeof(int16_t)); Bmemcpy(&sprite[g_player[i].ps->i].extra, &packbuf[j], sizeof(int16_t));
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)); Bmemcpy(&g_player[i].ps->kickback_pic, &packbuf[j], sizeof(int16_t));
j += sizeof(int16_t); j += sizeof(int16_t);
Bmemcpy(&g_player[i].ps->shield_amount, &packbuf[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); j += sizeof(int16_t);
Bmemcpy(&g_player[i].ps->last_extra, &packbuf[j], sizeof(int16_t)); Bmemcpy(&g_player[i].ps->last_extra, &packbuf[j], sizeof(int16_t));
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; 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 do
{ {
int16_t var_id; int16_t var_id;
@ -935,10 +954,12 @@ process:
deletesprite(ahead); deletesprite(ahead);
// sprite updates tacked on to the end of the packet // 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; int16_t i, sect, statnum, osect, ostatnum, jj, lightid = -1, opicnum;
_prlight *mylight; _prlight *mylight = NULL;
Bmemcpy(&i, &packbuf[j], sizeof(int16_t)); Bmemcpy(&i, &packbuf[j], sizeof(int16_t));
j += sizeof(int16_t); j += sizeof(int16_t);
@ -968,16 +989,17 @@ process:
sprite[i].statnum = ostatnum; sprite[i].statnum = ostatnum;
if (sect != osect) changespritesect(i, sect); if (sect != osect) changespritesect(i, sect);
if (statnum != ostatnum) changespritestat(i, statnum); if (statnum != ostatnum) changespritestat(i, statnum);
mylight = ActorExtra[i].lightptr;
lightid = ActorExtra[i].lightId;
} }
j += sizeof(spritetype); j += sizeof(spritetype);
jj = j++; jj = j++;
mylight = ActorExtra[i].lightptr; Bmemcpy(&ActorExtra[i], &packbuf[j], sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)-
lightid = ActorExtra[i].lightId; sizeof(ActorExtra[0].projectile)-sizeof(ActorExtra[0].lightptr));
Bmemcpy(&ActorExtra[i], &packbuf[j], sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)); j += sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)-sizeof(ActorExtra[0].projectile)-sizeof(ActorExtra[0].lightptr);
j += sizeof(ActorData_t)-sizeof(ActorExtra[0].filler);
ActorExtra[i].projectile = &SpriteProjectile[i]; ActorExtra[i].projectile = &SpriteProjectile[i];
ActorExtra[i].lightptr = mylight; ActorExtra[i].lightptr = mylight;
@ -1001,6 +1023,24 @@ process:
} }
while (1); while (1);
} }
l = packbuf[j++];
while (l--)
{
Bmemcpy(&i, &packbuf[j], sizeof(int16_t));
j += sizeof(int16_t);
Bmemcpy(&sector[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(&sector[i], &packbuf[j], sizeof(walltype));
j += sizeof(walltype);
}
} }
Bfree(packbuf); Bfree(packbuf);
@ -1010,9 +1050,9 @@ process:
case PACKET_SLAVE_TO_MASTER: //[1] (receive slave sync buffer) case PACKET_SLAVE_TO_MASTER: //[1] (receive slave sync buffer)
j = 1; j = 1;
packbufleng = qlz_size_decompressed((char *)packbuf+1); packbufleng = qlz_size_decompressed((char *)(packbuf)+1);
packbuf = Bcalloc(1, packbufleng); 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]; nsyn = (input_t *)&inputfifo[0][0];
@ -1022,6 +1062,13 @@ process:
g_player[other].movefifoend++; 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(&g_player[other].ps->posx, &packbuf[j], sizeof(vec3_t) * 3);
Bmemcpy(&sprite[g_player[other].ps->i], &packbuf[j], sizeof(vec3_t)); Bmemcpy(&sprite[g_player[other].ps->i], &packbuf[j], sizeof(vec3_t));
sprite[g_player[other].ps->i].z += PHEIGHT; sprite[g_player[other].ps->i].z += PHEIGHT;
@ -1033,22 +1080,17 @@ process:
{ {
int16_t i = g_player[other].ps->i, jj = j++; 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)); Bmemcpy(&T5, &packbuf[j], sizeof(T5));
j += sizeof(T5); j += sizeof(T5);
if (oa != T5) T3 = T4 = 0;
if (packbuf[jj] & 2) T5 += (intptr_t)&script[0]; if (packbuf[jj] & 2) T5 += (intptr_t)&script[0];
} }
Bfree(packbuf); Bfree(packbuf);
break; break;
case PACKET_NULL_PACKET:
break;
case PACKET_PLAYER_READY: case PACKET_PLAYER_READY:
if (net_server) if (net_server)
{ {
@ -1135,6 +1177,11 @@ process:
for (i=0; i<playerswhenstarted-1; i++) connectpoint2[i] = i+1; for (i=0; i<playerswhenstarted-1; i++) connectpoint2[i] = i+1;
connectpoint2[playerswhenstarted-1] = -1; connectpoint2[playerswhenstarted-1] = -1;
Net_SendVersion();
Net_SendPlayerName();
Net_SendPlayerOptions();
Net_SendWeaponChoice();
break; break;
// receive client player index from server // receive client player index from server
@ -1147,7 +1194,6 @@ process:
Net_SendPlayerName(); Net_SendPlayerName();
Net_SendPlayerOptions(); Net_SendPlayerOptions();
Net_SendWeaponChoice(); Net_SendWeaponChoice();
Net_SendUserMapName();
break; break;
@ -1157,6 +1203,10 @@ process:
g_player[packbuf[1]].playerquitflag = 0; g_player[packbuf[1]].playerquitflag = 0;
break; break;
case PACKET_PLAYER_SPAWN:
P_ResetPlayer(packbuf[1]);
break;
case PACKET_PLAYER_OPTIONS: case PACKET_PLAYER_OPTIONS:
other = packbuf[1]; other = packbuf[1];
i = 2; i = 2;
@ -1200,11 +1250,6 @@ process:
break; break;
case PACKET_MENU_LEVEL_QUIT:
//slaves in M/S mode only send to master
break;
case PACKET_USER_MAP: case PACKET_USER_MAP:
Bstrcpy(boardfilename,(char *)packbuf+1); Bstrcpy(boardfilename,(char *)packbuf+1);
boardfilename[packbufleng-1] = 0; boardfilename[packbufleng-1] = 0;
@ -1313,6 +1358,8 @@ process:
// a player connecting is a good time to mark everything as needing to be updated // a player connecting is a good time to mark everything as needing to be updated
Bmemset(spritecrc, 0, sizeof(spritecrc)); Bmemset(spritecrc, 0, sizeof(spritecrc));
Bmemset(sectcrc, 0, sizeof(sectcrc));
Bmemset(wallcrc, 0, sizeof(wallcrc));
Bmemset(peractorvals, 0, sizeof(peractorvals)); Bmemset(peractorvals, 0, sizeof(peractorvals));
Bmemset(perplayervals, 0, sizeof(perplayervals)); Bmemset(perplayervals, 0, sizeof(perplayervals));
} }
@ -1389,22 +1436,24 @@ void Net_GetPackets(void)
if (g_player[0].ps->gm & MODE_GAME) if (g_player[0].ps->gm & 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 == NULL) g_multiMapState = Bcalloc(1, sizeof(mapstate_t));
if (g_multiMapState) if (g_multiMapState)
{ {
char * buf = Bmalloc(sizeof(mapstate_t)<<1); 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); G_SaveMapState(g_multiMapState);
j = qlz_compress((char *)g_multiMapState, buf, sizeof(mapstate_t), state_compress); j = qlz_compress((char *)g_multiMapState, buf, sizeof(mapstate_t), state_compress);
while (j > 1024) while (j > 1024)
@ -1431,7 +1480,7 @@ void Net_GetPackets(void)
// broadcast takes care of enet_packet_destroy itself // 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 // 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 // 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; event.peer->state = ENET_PEER_STATE_DISCONNECTED;
enet_host_broadcast(net_server, 0, event.packet); enet_host_broadcast(net_server, 0, event.packet);
@ -1467,12 +1516,12 @@ void Net_GetPackets(void)
switch (event.type) switch (event.type)
{ {
case ENET_EVENT_TYPE_RECEIVE: case ENET_EVENT_TYPE_RECEIVE:
/*
initprintf ("A packet of length %u was received from player %d on channel %u.\n", initprintf ("A packet of length %u was received from player %d on channel %u.\n",
event.packet -> dataLength, event.packet -> dataLength,
event.peer -> data, event.peer -> data,
event.channelID); event.channelID);
*/
// channelID 1 is the map state transfer from the server // channelID 1 is the map state transfer from the server
if (event.channelID == 1) if (event.channelID == 1)
{ {
@ -1579,13 +1628,12 @@ void faketimerhandler(void)
if (numplayers < 2) if (numplayers < 2)
{ {
if (ud.multimode > 1) if (ud.multimode > 1 && ud.playerai)
TRAVERSE_CONNECT(i) TRAVERSE_CONNECT(i)
if (i != myconnectindex) if (i != myconnectindex)
{ {
//clearbufbyte(&inputfifo[g_player[i].movefifoend&(MOVEFIFOSIZ-1)][i],sizeof(input_t),0L); //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]; 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)); Bmemcpy(&packbuf[j], &T5, sizeof(T5));
j += sizeof(T5); j += sizeof(T5);
@ -1627,8 +1671,8 @@ void faketimerhandler(void)
{ {
char buf[1024]; char buf[1024];
j = qlz_compress((char *)packbuf+1, (char *)buf, j, state_compress); j = qlz_compress((char *)(packbuf)+1, (char *)buf, j, state_compress);
Bmemcpy((char *)packbuf+1, (char *)buf, j); Bmemcpy((char *)(packbuf)+1, (char *)buf, j);
j++; j++;
} }
@ -1662,6 +1706,8 @@ void faketimerhandler(void)
Bmemcpy(&osyn[i], &nsyn[i], sizeof(input_t)); 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)); Bmemcpy(&packbuf[j], &nsyn[i], sizeof(input_t));
j += sizeof(input_t)-sizeof(loc.filler); j += sizeof(input_t)-sizeof(loc.filler);
Bmemcpy(&packbuf[j], &g_player[i].ps->posx, sizeof(vec3_t) * 3); Bmemcpy(&packbuf[j], &g_player[i].ps->posx, sizeof(vec3_t) * 3);
@ -1670,6 +1716,8 @@ void faketimerhandler(void)
j += sizeof(int16_t) * 2; j += sizeof(int16_t) * 2;
Bmemcpy(&packbuf[j], &sprite[g_player[i].ps->i].extra, sizeof(int16_t)); Bmemcpy(&packbuf[j], &sprite[g_player[i].ps->i].extra, sizeof(int16_t));
j += 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)); Bmemcpy(&packbuf[j], &g_player[i].ps->kickback_pic, sizeof(int16_t));
j += sizeof(int16_t); j += sizeof(int16_t);
Bmemcpy(&packbuf[j], &g_player[i].ps->shield_amount, 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); j += sizeof(int16_t);
Bmemcpy(&packbuf[j], &g_player[i].ps->last_extra, sizeof(int16_t)); Bmemcpy(&packbuf[j], &g_player[i].ps->last_extra, sizeof(int16_t));
j += 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; 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; int16_t ii=g_gameVarCount-1, kk = 0;
for (; ii>=0; ii--) 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]) if (peractorvals[ii][i] != aGameVars[ii].val.plValues[i])
{ {
@ -1729,7 +1800,7 @@ void faketimerhandler(void)
for (; ii>=0; ii--) 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]) 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 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++) for (zz = 0; (unsigned)zz < (sizeof(lists)/sizeof(lists[0])); zz++)
TRAVERSE_SPRITE_STAT(headspritestat[lists[zz]], i, nexti) TRAVERSE_SPRITE_STAT(headspritestat[lists[zz]], i, nexti)
@ -1799,8 +1873,9 @@ void faketimerhandler(void)
packbuf[jj] |= 4; packbuf[jj] |= 4;
T6 -= (intptr_t)&script[0]; T6 -= (intptr_t)&script[0];
} }
Bmemcpy(&packbuf[j], &ActorExtra[i], sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)); Bmemcpy(&packbuf[j], &ActorExtra[i], sizeof(ActorData_t)-sizeof(ActorExtra[0].filler)-
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);
if (packbuf[jj] & 1) T2 += (intptr_t)&script[0]; if (packbuf[jj] & 1) T2 += (intptr_t)&script[0];
if (packbuf[jj] & 2) T5 += (intptr_t)&script[0]; if (packbuf[jj] & 2) T5 += (intptr_t)&script[0];
@ -1836,13 +1911,59 @@ void faketimerhandler(void)
} }
if (k > 4) break; 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 *)&sector[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], &sector[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]; char buf[4096];
j = qlz_compress((char *)packbuf+1, (char *)buf, j, state_compress); j = qlz_compress((char *)(packbuf)+1, (char *)buf, j, state_compress);
Bmemcpy((char *)packbuf+1, (char *)buf, j); Bmemcpy((char *)(packbuf)+1, (char *)buf, j);
j++; j++;
} }
@ -5313,7 +5434,7 @@ int32_t A_Spawn(int32_t j, int32_t pn)
{ {
sp->xrepeat = 31; sp->xrepeat = 31;
sp->yrepeat = 1; sp->yrepeat = 1;
sp->z = sector[sprite[j].sectnum].floorz-(40<<8); sp->z = sector[sprite[j].sectnum].floorz-PHEIGHT;
} }
else 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->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->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; // dirty hack
t->z += (40<<8); 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 || 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) 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->x = omy.x+mulscale16((int32_t)(my.x-omy.x),smoothratio);
t->y = omy.y+mulscale16((int32_t)(my.y-omy.y),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->ang = omyang+mulscale16((int32_t)(((myang+1024-omyang)&2047)-1024),smoothratio);
t->sectnum = mycursectnum; t->sectnum = mycursectnum;
} }
@ -9196,7 +9319,6 @@ static void G_ShowParameterHelp(void)
"-map [file.map]\tLoads a map\n" "-map [file.map]\tLoads a map\n"
"-m\t\tDisable monsters\n" "-m\t\tDisable monsters\n"
"-nam/-ww2gi\tRun in NAM or WW2GI-compatible mode\n" "-nam/-ww2gi\tRun in NAM or WW2GI-compatible mode\n"
"-net\t\tEnable multiplayer (see documentation)\n"
"-r\t\tRecord demo\n" "-r\t\tRecord demo\n"
"-s#\t\tSet skill level (1-4)\n" "-s#\t\tSet skill level (1-4)\n"
#if defined RENDERTYPEWIN || (defined RENDERTYPESDL && !defined __APPLE__ && defined HAVE_GTK2) #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" "-nologo\t\tSkip the logo anim\n"
"-ns/-nm\t\tDisable sound or music\n" "-ns/-nm\t\tDisable sound or music\n"
"-q#\t\tFake multiplayer with # (2-8) players\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" "-w\t\tShow coordinates\n"
"-z#/-condebug\tEnable line-by-line CON compile debugging at level #\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++; i++;
continue; continue;
} }
if (!Bstrcasecmp(c+1,"keepaddr")) if (!Bstrcasecmp(c+1,"port"))
{ {
g_keepAddr = 1; if (argc > i+1)
i++; {
continue; net_port = atoi(argv[i+1]);
} i++;
if (!Bstrcasecmp(c+1,"stun")) }
{
natfree = 1; //Addfaz NatFree
i++; i++;
continue; continue;
} }
@ -9777,7 +9894,7 @@ static void G_CheckCommandLine(int32_t argc, const char **argv)
/* enet_address_set_host (& address, "x.x.x.x"); */ /* enet_address_set_host (& address, "x.x.x.x"); */
address.host = ENET_HOST_ANY; address.host = ENET_HOST_ANY;
address.port = 23513; address.port = net_port;
net_server = enet_host_create (&address, MAXPLAYERS, 0, 0); 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; ENetAddress address;
ENetEvent event; ENetEvent event;
char * addrstr = NULL;
Net_Disconnect(); Net_Disconnect();
@ -9806,8 +9924,9 @@ static void G_CheckCommandLine(int32_t argc, const char **argv)
continue; continue;
} }
enet_address_set_host (&address, (char *)argv[i+1]); addrstr = strtok((char *)argv[i+1],":");
address.port = 23513; 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 // use 2 channels for easy packet sorting at a lower level than the game later
net_peer = enet_host_connect (net_client, &address, 2); net_peer = enet_host_connect (net_client, &address, 2);

View file

@ -2770,68 +2770,22 @@ nullquote:
} }
else else
{ {
vec3_t tmpvect; if (vm.g_p == myconnectindex)
{
g_cameraDistance = 0;
g_cameraClock = totalclock;
}
tmpvect.x = g_player[vm.g_p].ps->posx; if (net_server)
tmpvect.y = g_player[vm.g_p].ps->posy; {
tmpvect.z = g_player[vm.g_p].ps->posz+PHEIGHT; P_ResetPlayer(vm.g_p);
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;
vm.g_sp->shade = -12; packbuf[0] = PACKET_PLAYER_SPAWN;
vm.g_sp->clipdist = 64; packbuf[1] = vm.g_p;
vm.g_sp->xrepeat = 42; packbuf[2] = 0;
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;
g_player[vm.g_p].ps->last_extra = vm.g_sp->extra = g_player[vm.g_p].ps->max_player_health; enet_host_broadcast(net_server, 0 , enet_packet_create(packbuf, 3, ENET_PACKET_FLAG_RELIABLE));
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;
} }
P_UpdateScreenPal(g_player[vm.g_p].ps); P_UpdateScreenPal(g_player[vm.g_p].ps);
//AddLog("EOF: resetplayer"); //AddLog("EOF: resetplayer");

View file

@ -187,7 +187,7 @@ int32_t A_GetHitscanRange(int32_t i)
int32_t zoff = 0; int32_t zoff = 0;
hitdata_t hitinfo; hitdata_t hitinfo;
if (PN == APLAYER) zoff = (40<<8); if (PN == APLAYER) zoff = PHEIGHT;
SZ -= zoff; SZ -= zoff;
hitscan((const vec3_t *)&sprite[i],SECT, hitscan((const vec3_t *)&sprite[i],SECT,

View file

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "duke3d.h" #include "duke3d.h"
#include "osd.h" #include "osd.h"
#include "gamedef.h"
#ifdef RENDERTYPEWIN #ifdef RENDERTYPEWIN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -619,6 +620,74 @@ void P_RandomSpawnPoint(int32_t snum)
p->oposz = p->posz = g_playerSpawnPoints[i].oz; p->oposz = p->posz = g_playerSpawnPoints[i].oz;
p->ang = g_playerSpawnPoints[i].oa; p->ang = g_playerSpawnPoints[i].oa;
p->cursectnum = g_playerSpawnPoints[i].os; 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) void P_ResetStatus(int32_t snum)