greed/CODE/NET.C
2014-12-12 00:00:00 +00:00

1017 lines
28 KiB
C

/***************************************************************************/
/* */
/* */
/* Raven 3D Engine */
/* Copyright (C) 1996 by Softdisk Publishing */
/* */
/* Original Design: */
/* John Carmack of id Software */
/* */
/* Enhancements by: */
/* Robert Morgan of Channel 7............................Main Engine Code */
/* Todd Lewis of Softdisk Publishing......Tools,Utilities,Special Effects */
/* John Bianca of Softdisk Publishing..............Low-level Optimization */
/* Carlos Hasan..........................................Music/Sound Code */
/* */
/* */
/***************************************************************************/
#include <STDIO.H>
#include <STRING.H>
#include <DOS.H>
#include <CONIO.H>
#include <STDLIB.H>
#include "d_global.h"
#include "d_ints.h"
#include "d_misc.h"
#include "r_public.h"
#include "protos.h"
#include "d_disk.h"
#include "r_refdef.h"
#include "audio.h"
/**** CONSTANTS ****/
#define CMD_SEND 1
#define CMD_GET 2
#define GREEDCOM_ID 0xC7C7C7C7L
#define NETIPX 1
#define NETSERIAL 2
#define NETMODEM 3
#define INITEVENTID 1
#define PLAYEREVENTID 2
#define SPAWNEVENTID 3
#define QUITEVENTID 4
#define DOOREVENTID 5
#define FRAGEVENTID 6
#define NEWPLAYEREVENTID 7
#define ITEMEVENTID 8
#define BONUSEVENTID 9
#define PAUSEEVENTID 10
#define UNPAUSEEVENTID 11
#define TRIGGEREVENTID 12
#define SOUNDEVENTID 13
#define JAMMEREVENTID 14
#define EVENTEVENTID 15
#define MESSAGEEVENTID 16
#define REG_TX uart
#define REG_RX uart
#define REG_INT_EN (uart+0x01)
#define IER_RX_DATA_READY 0x01
#define IER_TX_HOLDING_REGISTER_EMPTY 0x02
#define IER_LINE_STATUS 0x04
#define IER_MODEM_STATUS 0x08
#define REG_INT_ID (uart+0x02)
#define IIR_NOPEND 0x01
#define IIR_MSTAT 0x00
#define IIR_TX 0x02
#define IIR_RX 0x04
#define IIR_LSTAT 0x06
#define REG_FCONT (uart+0x02)
#define FCR_FIFO_ENABLE 0x01
#define FCR_RCVR_FIFO_RESET 0x02
#define FCR_XMIT_FIFO_RESET 0x04
#define FCR_RCVR_TRIGGER_LSB 0x40
#define FCR_RCVR_TRIGGER_MSB 0x80
#define FCR_TRIGGER_01 0x00
#define FCR_TRIGGER_04 0x40
#define FCR_TRIGGER_08 0x80
#define FCR_TRIGGER_14 0xc0
#define REG_LCONT (uart+0x03)
#define LCONT_WORD_LENGTH_MASK 0x03
#define LCONT_WORD_LENGTH_SELECT_0 0x01
#define LCONT_WORD_LENGTH_SELECT_1 0x02
#define LCONT_STOP_BITS 0x04
#define LCONT_PARITY_MASK 0x38
#define LCONT_PARITY_ENABLE 0x08
#define LCONT_EVEN_PARITY_SELECT 0x10
#define LCONT_STICK_PARITY 0x20
#define LCONT_SET_BREAK 0x40
#define LCONT_DLAB 0x80
#define REG_MCONT (uart+0x04)
#define MCONT_DTR 0x01
#define MCONT_RTS 0x02
#define MCONT_OUT1 0x04
#define MCONT_OUT2 0x08
#define MCONT_LOOPBACK 0x10
#define REG_LSTAT (uart+0x05)
#define LSTAT_DATA_READY 0x01
#define LSTAT_OVERRUN_ERROR 0x02
#define LSTAT_PARITY_ERROR 0x04
#define LSTAT_FRAMING_ERROR 0x08
#define LSTAT_BREAK_DETECT 0x10
#define LSTAT_THRE 0x20
#define REG_MSTAT (uart+0x06)
#define MSTAT_DELTA_CTS 0x01
#define MSTAT_DELTA_DSR 0x02
#define MSTAT_TERI 0x04
#define MSTAT_DELTA_CD 0x08
#define MSTAT_CTS 0x10
#define MSTAT_DSR 0x20
#define MSTAT_RI 0x40
#define MSTAT_CD 0x80
#define QUESIZE 4095
#define PEL_WRITE_ADR 0x3c8
#define PEL_DATA 0x3c9
#define I_ColorBlack(r,g,b) outp(PEL_WRITE_ADR,0); \
outp(PEL_DATA,r); \
outp(PEL_DATA,g); \
outp(PEL_DATA,b)
#define NETINT() intr(greedcom->intnum,&r)
/**** TYPES ****/
typedef struct
{
int id;
int playerid;
int found;
int start;
char netname[13];
int map;
int difficulty;
} ievent_t; // initialization
typedef struct
{
int id;
int playerid;
int value;
fixed_t x;
fixed_t y;
fixed_t z;
fixed_t zadj;
int angle;
int angle2;
int active;
int spawnid;
} sevent_t; // spawn
typedef struct
{
int id;
int playerid;
} qevent_t; // quit game
typedef struct
{
int id;
int playerid;
fixed_t x, y;
int angle;
} devent_t; // door open (by player) / trigger flipped
typedef struct
{
int id;
int playerid;
int bulletid;
} fevent_t; // frag
typedef struct
{
int id;
int playerid;
int time, score;
int tilex, tiley;
int num;
} bevent_t; // bonus item spawn
typedef struct
{
int id;
int playerid;
int tilex, tiley, mapspot;
int type, chartype;
} ipevent_t; // item pickup
typedef struct
{
int id;
int playerid;
fixed_t x, y;
int effect, variation;
} eevent_t; // sound effect
typedef struct
{
int id;
int playerid;
char message[30];
} mevent_t;
enum {UART_8250, UART_16550} uart_type;
typedef struct
{
long head, tail; // bytes are put on head and pulled from tail
byte data[QUESIZE+1];
} que_t;
typedef struct
{
que_t in;
que_t out;
short uart, uarttype, irqintnum;
short intseg, intofs;
short rsent, rreceived;
short psent, preceived;
} ques_t;
/**** VARIABLES ****/
pevent_t *pevent;
sevent_t *sevent;
ievent_t *ievent;
qevent_t *qevent;
devent_t *devent;
fevent_t *fevent;
bevent_t *bevent;
ipevent_t *ipevent;
eevent_t *eevent;
mevent_t *mevent;
greedcom_t *greedcom;
union REGPACK r;
char msg[60];
scaleobj_t *playersprites[MAXPLAYERS], *sprite_p, *sprite2_p, *temp_p;
pevent_t playerdata[MAXPLAYERS];
char netnames[MAXPLAYERS][13];
int playernum=1, netpaused, netwarpjamtime;
boolean netwarpjammer;
int playermapspot[MAXPLAYERS], pmapspot, oldsprites[MAXPLAYERS];
ques_t *que;
int uart, irqintnum, maxcount;
int pseg, pofs, rseg, rofs;
int fragcount[MAXPLAYERS];
extern SoundCard SC;
/**** FUNCTIONS ****/
void interrupt ISR_8250(void)
{
int count;
STI;
while (1)
{
switch(inbyte(REG_INT_ID) & 7)
{
case IIR_RX: // receive
que->in.data[que->in.head&QUESIZE]=inbyte(REG_RX);
que->in.head++;
que->preceived++;
continue;
case IIR_TX: // transmit
for (count=0;count<maxcount && que->out.tail<que->out.head;count++)
{
outbyte(REG_TX,que->out.data[que->out.tail&QUESIZE]);
que->out.tail++;
que->psent++;
}
continue;
case IIR_MSTAT:
inbyte(REG_MSTAT);
continue;
case IIR_LSTAT:
inbyte(REG_LSTAT);
continue;
default: // done
outbyte(0x20,0x20);
return;
}
}
}
void netstub2(void)
{
}
void SetupModem(void)
{
int parm, seraddr;
union REGS r;
parm=MS_CheckParm("serial");
if (parm && parm<my_argc-1) seraddr=atoi(my_argv[parm+1]);
else MS_Error("Serial data not found!");
que=(ques_t*)seraddr;
uart=que->uart;
uart_type=que->uarttype;
irqintnum=que->irqintnum;
if (uart_type==UART_16550) maxcount=14;
else maxcount=1;
lock_region((void near *)ISR_8250,(char *)netstub2 - (char near *)ISR_8250);
lock_region(&que,4);
lock_region(&uart,4);
lock_region(&maxcount,4);
lock_region(&uart_type,4);
r.x.eax=0x204; // get prot
r.h.bl=irqintnum;
int386(0x31,&r,&r);
if (r.x.cflag) MS_Error("Error getting prot handler");
pseg=r.x.ecx;
pofs=r.x.edx;
r.x.eax=0x0200; // get real
r.h.bl=irqintnum;
int386(0x31,&r,&r);
if (r.x.cflag) MS_Error("Error getting real handler");
rseg=r.x.ecx;
rofs=r.x.edx;
r.x.eax=0x205; // set prot
r.h.bl=irqintnum;
r.x.edx=FP_OFF(ISR_8250);
r.x.ecx=FP_SEG(ISR_8250);
int386(0x31,&r,&r);
if (r.x.cflag) MS_Error("Error setting prot handler");
r.x.eax=0x0201; // set real
r.h.bl=irqintnum;
r.x.ecx=que->intseg;
r.x.edx=que->intofs;
int386(0x31,&r,&r);
if (r.x.cflag) MS_Error("Error setting real handler");
}
/***************************************************************************/
void netstub(void);
void SpawnNewPlayer()
{
sprite_p=RF_GetSprite();
playersprites[pevent->playerid]=sprite_p;
sprite_p->rotate=rt_eight;
sprite_p->basepic=CA_GetNamedNum(charnames[pevent->chartype]);
DemandLoadMonster(sprite_p->basepic,48);
sprite_p->scale=1;
sprite_p->startpic=sprite_p->basepic;
sprite_p->intelligence=255;
sprite_p->x=pevent->x;
sprite_p->y=pevent->y;
sprite_p->z=pevent->z;
sprite_p->angle=pevent->angle;
sprite_p->type=S_NETPLAYER;
sprite_p->hitpoints=500;
sprite_p->height=60<<FRACBITS;
pmapspot=(sprite_p->y>>FRACTILESHIFT)*MAPCOLS+(sprite_p->x>>FRACTILESHIFT);
playermapspot[pevent->playerid]=pmapspot;
if (mapsprites[pmapspot]==0)
mapsprites[pmapspot]=SM_NETPLAYER;
}
void NetInit(void *addr)
{
printf("Multiplayer:\n");
greedcom=(greedcom_t *)addr;
if (greedcom->id!=GREEDCOM_ID) MS_Error("Invalid ComData Address! ID=0x%X",greedcom->id);
printf("\tPlayers=%i\n",greedcom->numplayers);
playernum=greedcom->consoleplayer;
printf("\tYou are player #%i\n",playernum+1);
printf("\tNetMode=");
if (greedcom->nettype==NETIPX) printf("IPX Net");
else if (greedcom->nettype==NETSERIAL) printf("Serial");
else if (greedcom->nettype==NETMODEM) printf("Modem");
else MS_Error("Unknown net type!");
printf("\n");
if (greedcom->nettype==NETMODEM || greedcom->nettype==NETSERIAL) SetupModem();
pevent=(pevent_t *)greedcom->data;
sevent=(sevent_t *)greedcom->data;
ievent=(ievent_t *)greedcom->data;
qevent=(qevent_t *)greedcom->data;
devent=(devent_t *)greedcom->data;
fevent=(fevent_t *)greedcom->data;
bevent=(bevent_t *)greedcom->data;
ipevent=(ipevent_t *)greedcom->data;
eevent=(eevent_t *)greedcom->data;
mevent=(mevent_t *)greedcom->data;
lock_region((void near *)NetOpenDoor,(char *)netstub - (char near *)NetOpenDoor);
lock_region(&greedcom,sizeof(greedcom));
lock_region(&devent,sizeof(devent));
lock_region(&r,sizeof(r));
memset(&r,0,sizeof(r));
}
void PlayerCommand(void);
void NetWaitStart(void)
{
int players[MAXPLAYERS], found, playersfound[MAXPLAYERS], ready, i;
longint timeout, waittime;
INT_TimerHook(NULL);
StartWait();
memset(players,0,sizeof(players));
memset(playersfound,0,sizeof(playersfound));
strncpy(netnames[playernum],SC.netname,12);
if (netnames[playernum][10]==' ')
{
i=10;
while (i>0 && netnames[playernum][i]==' ')
{
netnames[playernum][i]=0;
i--;
}
}
players[playernum]=1; // found ourself
found=1;
ready=0;
timeout=timecount+42000; // 10 minute wait
newascii=false;
waittime=timecount+70;
while (1)
{
UpdateWait();
if (timecount>timeout)
MS_Error("Multiplayer synch time-out error");
if (newascii && lastascii==27)
MS_Error("Multiplay Cancelled");
newascii=false;
if (timecount>waittime)
{
found=0;
for(i=0;i<greedcom->numplayers;i++)
if (players[i]) found++; // count how many we've found
playersfound[playernum]=found;
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS; // broadcast
greedcom->datalength=sizeof(ievent_t);
ievent->id=INITEVENTID;
ievent->playerid=playernum; // tell who we are
ievent->found=found; // tell how many we've found
ievent->start=ready; // player 0 tells when to start
ievent->map=player.map;
ievent->difficulty=player.difficulty;
strncpy(ievent->netname,netnames[playernum],12);
NETINT();
waittime=timecount + 140;
}
if (ievent->start==greedcom->numplayers)
break;
greedcom->command=CMD_GET;
NETINT();
if (greedcom->remotenode==-1)
continue; // no broadcasts
if (ievent->id!=INITEVENTID)
continue; // wrong packet id!
if (greedcom->nettype!=NETIPX && ievent->start==greedcom->numplayers)
break; // we can start now
if (ievent->playerid==0)
player.difficulty=ievent->difficulty;
if (ievent->map!=player.map)
MS_Error("Player #%i is playing a different map!",ievent->playerid);
players[ievent->playerid]=1; // found new player
playersfound[ievent->playerid]=ievent->found; // how many they've found
strncpy(netnames[ievent->playerid],ievent->netname,12);
if (playernum==0) // player 0 checks for readiness
{
ready=0;
for(i=0;i<greedcom->numplayers;i++)
if (playersfound[i]==greedcom->numplayers)
ready++; // check everybody
}
}
timecount=0;
greedcom->maxusage=0;
EndWait();
NetNewPlayerData();
INT_TimerHook(PlayerCommand);
if (greedcom->nettype!=NETIPX && greedcom->consoleplayer==0)
timecount=19;
NetGetData();
}
void NetGetData(void)
{
static int i, angle, angleinc;
do
{
/* if (greedcom->nettype==NETIPX && greedcom->maxusage==25)
MS_Error("Network Overload\n"
"Possible solutions:\n"
" 1. increase the speed of this machine\n"
" 2. remove other non-game machines from the net\n"
" 3. reduce number of players in game\n"); */
greedcom->command=CMD_GET;
NETINT();
if (greedcom->remotenode==-1) return;
if (pevent->playerid==playernum) continue;
switch (pevent->id)
{
case PLAYEREVENTID:
sprite_p=playersprites[pevent->playerid];
if (sprite_p==NULL)
continue;
sprite_p->x=pevent->x;
sprite_p->y=pevent->y;
sprite_p->z=pevent->z-pevent->height;
sprite_p->angle=pevent->angle;
sprite_p->hitpoints=500;
pmapspot=playermapspot[pevent->playerid];
if (mapsprites[pmapspot]==SM_NETPLAYER)
mapsprites[pmapspot]=0;
pmapspot=(sprite_p->y>>FRACTILESHIFT)*MAPCOLS+(sprite_p->x>>FRACTILESHIFT);
if (mapsprites[pmapspot]==0)
mapsprites[pmapspot]=SM_NETPLAYER;
playermapspot[pevent->playerid]=pmapspot;
if (pevent->status==1) // hit
{
sprite_p->basepic=sprite_p->startpic+32;
sprite_p->modetime=timecount+12;
}
else if (pevent->status==2) // firing
{
sprite_p->basepic=sprite_p->startpic+24;
sprite_p->modetime=timecount+12;
playerdata[pevent->playerid].x=-1; // so it draws the walk frame
}
if (timecount>sprite_p->modetime)
{
if (playerdata[pevent->playerid].x!=pevent->x || playerdata[pevent->playerid].y!=pevent->y)
{
if (sprite_p->movemode==3)
{
sprite_p->movemode=0;
sprite_p->basepic=sprite_p->startpic;
}
else if (sprite_p->movemode==2)
{
sprite_p->basepic=sprite_p->startpic + 8; // midstep
++sprite_p->movemode;
}
else
{
++sprite_p->movemode;
sprite_p->basepic=sprite_p->startpic+sprite_p->movemode*8;
}
}
sprite_p->modetime=timecount+12;
}
memcpy(&playerdata[pevent->playerid],pevent,sizeof(pevent_t));
if (pevent->holopic)
{
// if (MS_RndT()>253)
// {
// sprite_p->basepic=sprite_p->startpic;
// sprite_p->scale=1;
// sprite_p->rotate=rt_eight;
// }
// else
// {
sprite_p->basepic=pevent->holopic;
sprite_p->scale=pevent->holoscale;
sprite_p->rotate=rt_one;
// }
}
if (pevent->specialeffect==SE_INVISIBILITY)
sprite_p->specialtype=st_transparent;
else
sprite_p->specialtype=0;
break;
case SPAWNEVENTID:
gameloading=true;
if (sevent->value==S_BULLET18)
{
angleinc=ANGLES/12;
angle=0;
for(i=0,angle=0;i<12;i++,angle+=angleinc)
SpawnSprite(sevent->value,sevent->x,sevent->y,sevent->z,sevent->zadj,angle,sevent->angle2,sevent->active,sevent->spawnid);
}
else if (sevent->value==S_SOULBULLET)
{
angleinc=ANGLES/16;
angle=0;
for(i=0,angle=0;i<16;i++,angle+=angleinc)
SpawnSprite(sevent->value,sevent->x,sevent->y,sevent->z,sevent->zadj,angle,sevent->angle2,sevent->active,sevent->spawnid);
}
else SpawnSprite(sevent->value,sevent->x,sevent->y,sevent->z,sevent->zadj,sevent->angle,sevent->angle2,sevent->active,sevent->spawnid);
gameloading=false;
break;
case DOOREVENTID:
TryDoor(devent->x,devent->y);
break;
case ITEMEVENTID:
mapsprites[ipevent->mapspot]=ipevent->type;
CheckItems(ipevent->tilex,ipevent->tiley,false,ipevent->chartype);
mapsprites[ipevent->mapspot]=0;
break;
case SOUNDEVENTID:
SoundEffect(eevent->effect,eevent->variation,eevent->x,eevent->y);
break;
case BONUSEVENTID:
if (BonusItem.score>0)
{
for (sprite_p=firstscaleobj.next; sprite_p!=&lastscaleobj;sprite_p=sprite_p->next)
if (sprite_p->type==S_BONUSITEM)
{
RF_RemoveSprite(sprite_p);
mapsprites[BonusItem.mapspot]=0;
break;
}
SpawnSprite(S_WARP,(BonusItem.tilex*MAPSIZE+32)<<FRACBITS,(BonusItem.tiley*MAPSIZE+32)<<FRACBITS,0,0,0,0,false,0);
}
do
{
BonusItem.tilex=bevent->tilex;
BonusItem.tiley=bevent->tiley;
BonusItem.mapspot=BonusItem.tiley*MAPCOLS + BonusItem.tilex;
} while (floorpic[BonusItem.mapspot]==0 || mapsprites[BonusItem.mapspot]>0 || mapeffects[BonusItem.mapspot]&FL_FLOOR);
BonusItem.score=bevent->score;
BonusItem.time=bevent->time;
BonusItem.num=bevent->num;
BonusItem.name=randnames[BonusItem.num];
BonusItem.sprite=SpawnSprite(S_BONUSITEM,(BonusItem.tilex*MAPSIZE+32)<<FRACBITS,(BonusItem.tiley*MAPSIZE+32)<<FRACBITS,0,0,0,0,false,0);
SpawnSprite(S_WARP,(BonusItem.tilex*MAPSIZE+32)<<FRACBITS,(BonusItem.tiley*MAPSIZE+32)<<FRACBITS,0,0,0,0,false,0);
BonusItem.sprite->basepic+=BonusItem.num;
oldgoalitem=-1;
writemsg("Bonus item located!");
break;
case TRIGGEREVENTID:
CheckHere(false,devent->x,devent->y,devent->angle);
break;
case FRAGEVENTID:
if (fevent->bulletid<MAXPLAYERS)
{
oldgoalitem=-1;
fragcount[fevent->bulletid]++;
goalitem=fevent->bulletid+1;
}
if (playernum==fevent->bulletid)
{
player.frags[fevent->playerid]++;
addscore(5000);
sprintf(msg,"Fragged %s! %i of %i",netnames[fevent->playerid],player.frags[fevent->playerid],fragcount[playernum]);
writemsg(msg);
}
else if (fevent->bulletid<MAXPLAYERS)
{
sprintf(msg,"%s fragged %s.",netnames[fevent->bulletid],netnames[fevent->playerid]);
writemsg(msg);
}
else
{
sprintf(msg,"%s was killed.",netnames[fevent->playerid]);
writemsg(msg);
}
sprite_p=playersprites[fevent->playerid];
if (sprite_p->startpic==CA_GetNamedNum(charnames[0]))
{
gameloading=true; // do not transmit
sprite2_p=SpawnSprite(S_TIMEMINE,sprite_p->x,sprite_p->y,0,0,0,0,false,playernum);
gameloading=false;
sprite2_p->basepic=sprite_p->startpic+40;
sprite_p->basepic=sprite_p->startpic+40;
sprite2_p->scale=1;
sprite_p->animation=0 + (0<<1) + (0<<5) + (0<<9) + ANIM_SELFDEST;
}
else
{
sprite_p->basepic=sprite_p->startpic + 40;
sprite_p->animation = 0 + (0<<1) + (8<<5) + ((6+(MS_RndT()&3))<<9);
}
sprite_p->rotate=rt_one;
sprite_p->heat=0;
sprite_p->active=false;
sprite_p->moveSpeed=0;
sprite_p->hitpoints=0;
sprite_p->intelligence=0;
mapsprites[playermapspot[fevent->playerid]]=0;
playersprites[fevent->playerid]=NULL;
break;
case NEWPLAYEREVENTID:
SpawnNewPlayer(); // new player
break;
case PAUSEEVENTID:
netpaused=true;
break;
case UNPAUSEEVENTID:
netpaused=false;
break;
case JAMMEREVENTID:
for (sprite_p=firstscaleobj.next; sprite_p!=&lastscaleobj;sprite_p=sprite_p->next)
if (sprite_p->type==S_GENERATOR || (sprite_p->type>=S_GENSTART && sprite_p->type<=S_GENEND))
{
mapsprites[(sprite_p->y>>FRACTILESHIFT)*MAPCOLS + (sprite_p->x>>FRACTILESHIFT)]=0;
temp_p=sprite_p;
sprite_p=sprite_p->next;
RF_RemoveSprite(temp_p);
}
else
sprite_p=sprite_p->next;
sprintf(msg,"%s activated Warp Jammer!",netnames[qevent->playerid]);
writemsg(msg);
netwarpjammer=true;
netwarpjamtime=timecount+70*60;
break;
case EVENTEVENTID:
Event(fevent->bulletid,false);
break;
case QUITEVENTID:
sprintf(msg,"%s has left the game!",netnames[qevent->playerid]);
writemsg(msg);
break;
case MESSAGEEVENTID:
sprintf(msg,"%s: %s",netnames[mevent->playerid],mevent->message);
writemsg(msg);
SoundEffect(SN_NEXUS,0,player.x,player.y);
break;
}
} while (1);
}
void NetSendPlayerData(void)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS; // broadcast
greedcom->datalength=sizeof(pevent_t);
pevent->playerid=playernum;
pevent->id=PLAYEREVENTID;
pevent->x=player.x;
pevent->y=player.y;
pevent->z=player.z;
pevent->angle=player.angle;
pevent->angst=player.angst;
pevent->height=player.height;
pevent->chartype=player.chartype;
pevent->status=player.status;
pevent->holopic=player.holopic;
pevent->holoscale=player.holoscale;
pevent->specialeffect=specialeffect;
player.status=0;
memcpy(&playerdata[playernum],pevent,sizeof(pevent_t));
NETINT();
}
void NetNewPlayerData(void)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS; // broadcast
greedcom->datalength=sizeof(pevent_t);
pevent->playerid=playernum;
pevent->id=NEWPLAYEREVENTID;
pevent->x=player.x;
pevent->y=player.y;
pevent->z=player.z;
pevent->angle=player.angle;
pevent->angst=player.angst;
pevent->height=player.height;
pevent->chartype=player.chartype;
pevent->status=player.status;
pevent->holopic=player.holopic;
pevent->specialeffect=specialeffect;
player.status=0;
memcpy(&playerdata[playernum],pevent,sizeof(pevent_t));
NETINT();
}
void NetSendSpawn(int value, fixed_t x, fixed_t y, fixed_t z,fixed_t zadj,int angle,int angle2,boolean active,int spawnid)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS; // broadcast
greedcom->datalength=sizeof(sevent_t);
sevent->id=SPAWNEVENTID;
sevent->value=value;
sevent->x=x;
sevent->y=y;
sevent->z=z;
sevent->zadj=zadj;
sevent->angle=angle;
sevent->angle2=angle2;
sevent->active=active;
sevent->spawnid=spawnid;
sevent->playerid=playernum;
NETINT();
}
void NetQuitGame(void)
{
NetDeath(255);
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(qevent_t);
qevent->id=QUITEVENTID;
qevent->playerid=playernum;
NETINT();
}
void NetOpenDoor(fixed_t x,fixed_t y)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(devent_t);
devent->id=DOOREVENTID;
devent->playerid=playernum;
devent->x=x;
devent->y=y;
NETINT();
}
void netstub(void)
{
}
void NetDeath(int bulletid)
{
char str1[50];
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(fevent_t);
fevent->id=FRAGEVENTID;
fevent->playerid=playernum;
fevent->bulletid=bulletid;
if (fevent->bulletid<MAXPLAYERS)
{
oldgoalitem=-1;
fragcount[bulletid]++;
goalitem=bulletid+1;
sprintf(str1,"You were fragged by %s!",netnames[fevent->bulletid]);
writemsg(str1);
}
NETINT();
}
void NetItemPickup(int x,int y)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(ipevent_t);
ipevent->id=ITEMEVENTID;
ipevent->playerid=playernum;
ipevent->tilex=x;
ipevent->tiley=y;
ipevent->mapspot=y*MAPCOLS+x;
ipevent->type=mapsprites[ipevent->mapspot];
ipevent->chartype=player.chartype;
NETINT();
}
void NetBonusItem(void)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(bevent_t);
bevent->id=BONUSEVENTID;
bevent->playerid=playernum;
bevent->time=BonusItem.time;
bevent->score=BonusItem.score;
bevent->tilex=BonusItem.tilex;
bevent->tiley=BonusItem.tiley;
bevent->num=BonusItem.num;
NETINT();
}
void NetGetClosestPlayer(int sx,int sy)
{
longint mindist, minplayer, dist;
int i, px, py;
minplayer=-1;
mindist=0x7FFFFFFFL;
for(i=0;i<greedcom->numplayers;i++)
if (playerdata[i].angst && playerdata[i].specialeffect!=SE_INVISIBILITY)
// gotta be alive && visible
{
px=playerdata[i].x>>FRACTILESHIFT;
py=playerdata[i].y>>FRACTILESHIFT;
dist=(px-sx)*(px-sx) + (py-sy)*(py-sy);
if (dist<mindist)
{
mindist=dist;
minplayer=i;
}
}
targx=playerdata[minplayer].x;
targy=playerdata[minplayer].y;
targz=playerdata[minplayer].z;
}
void NetPause(void)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(qevent_t);
qevent->id=PAUSEEVENTID;
qevent->playerid=playernum;
NETINT();
}
void NetUnPause(void)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(qevent_t);
qevent->id=UNPAUSEEVENTID;
qevent->playerid=playernum;
NETINT();
}
void NetCheckHere(fixed_t centerx,fixed_t centery,int angle)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(devent_t);
devent->id=TRIGGEREVENTID;
devent->playerid=playernum;
devent->x=centerx;
devent->y=centery;
devent->angle=angle;
NETINT();
}
void NetSoundEffect(int n,int variation,fixed_t x,fixed_t y)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(eevent_t);
eevent->id=SOUNDEVENTID;
eevent->playerid=playernum;
eevent->x=x;
eevent->y=y;
eevent->variation=variation;
eevent->effect=n;
NETINT();
}
void NetWarpJam(void)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(qevent_t);
qevent->id=JAMMEREVENTID;
qevent->playerid=playernum;
NETINT();
}
void NetEvent(int n)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(fevent_t);
fevent->id=EVENTEVENTID;
fevent->playerid=playernum;
fevent->bulletid=n;
NETINT();
}
void NetSendMessage(char *s)
{
greedcom->command=CMD_SEND;
greedcom->remotenode=MAXPLAYERS;
greedcom->datalength=sizeof(mevent_t);
mevent->id=MESSAGEEVENTID;
mevent->playerid=playernum;
strcpy(mevent->message,s);
NETINT();
}