Files
Justin Marshall 101266ab72 Initial commit.
2026-04-27 10:35:40 -07:00

4247 lines
122 KiB
C++

//******************************************************************
// msg.cpp
//******************************************************************
/* dig.patch1.start.1/30/97
Replaced all occurrences of "DObject" with "DObjectStr"
Replaced all occurrences of "DMonster" with "DMonsterStr"
This was done because of a debugger bug. The debugger was
not able to distinguish between the global variable dObject
and the structure name DObject.
The change should have no effect on the executable.
dig.patch1.end.1/30/97
*/
/* PATCH1.JMM
Added extensive logging to the msg handlers. All droplogs do not
compile in non-_DEBUG compiles.
*/
#include "diablo.h"
#pragma hdrstop
#include "sound.h"
#include "msg.h"
#include "multi.h"
#include "engine.h"
#include "gendung.h"
#include "items.h"
#include "player.h"
#include "monster.h"
#include "monstdat.h"
#include "inv.h"
#include "lighting.h"
#include "objects.h"
#include "objdat.h"
#include "spells.h"
#include "spelldat.h"
#include "control.h"
#include "dead.h"
#include "storm/h/storm.h"
#include "diabloui.h"
#include "cursor.h"
#include "automap.h"
#include "portal.h"
#include "quests.h"
#include "missiles.h"
#include "drlg_l1.h"
#include "trigs.h"
#include "effects.h"
/*-----------------------------------------------------------------------**
** extern
**-----------------------------------------------------------------------*/
DWORD Compress(LPBYTE data, DWORD bytes);
void Expand(LPBYTE data, DWORD bytes, DWORD dwMaxBytes);
void M_ClearSquares(int nMonster);
void Obj_Trap(int i);
void StartStand(int pnum, int dir);
void SyncPlrAnim(int p);
void SyncInitPlr(int pnum);
void SendLocalPlayerInfo(int pnum,BYTE bCmd);
void recv_plrinfo(int pnum,const TCmdPlrInfoHdr * p,BOOL bAck);
void dthread_SendPlayerInfoChunk(int pnum,BYTE bCmd,const BYTE * pbSrc,DWORD dwLen);
void plrmsg_add(int pnum,const char * pszStr);
void M_UpdateLeader(int i);
void gamemenu_off();
void DeleteItem(int ii, int i);
void SyncPortal(int i, BOOL open, int x, int y, int level, int ltype);
void __cdecl sysmsg_add(const char * pszFmt,...);
void NextPlrLevel(int pnum);
void nthread_set_delta_request();
void NewPlrAnim(int pnum, BYTE *pAnim, int numFrames, int Delay, long width);
void AddWarpMissile(int i, int x, int y);
// JMM.PATCH1.2.22.97
void sysmsg_add_string(const char * pszMsg);
// END.JMM.PATCH1.2.22.97
void OpenNaKrul();
void OpenNest();
void OpenCrypt();
/*-----------------------------------------------------------------------**
** public
**-----------------------------------------------------------------------*/
BOOL deltaload = FALSE;
BYTE gbBufferMsgs = BUFFER_OFF;
/*-----------------------------------------------------------------------**
** private
**-----------------------------------------------------------------------*/
#pragma pack(push,1)
typedef struct TCmdLoc {
BYTE bCmd;
BYTE x;
BYTE y;
} TCmdLoc;
typedef struct TCmdLocParam1 {
BYTE bCmd;
BYTE x;
BYTE y;
WORD wParam1;
} TCmdLocParam1;
typedef struct TCmdLocParam2 {
BYTE bCmd;
BYTE x;
BYTE y;
WORD wParam1;
WORD wParam2;
} TCmdLocParam2;
typedef struct TCmdLocParam3 {
BYTE bCmd;
BYTE x;
BYTE y;
WORD wParam1;
WORD wParam2;
WORD wParam3;
} TCmdLocParam3;
typedef struct TCmdParam1 {
BYTE bCmd;
WORD wParam1;
} TCmdParam1;
typedef struct TCmdParam2 {
BYTE bCmd;
WORD wParam1;
WORD wParam2;
} TCmdParam2;
typedef struct TCmdParam3 {
BYTE bCmd;
WORD wParam1;
WORD wParam2;
WORD wParam3;
} TCmdParam3;
typedef struct TCmdString {
BYTE bCmd;
char str[MAX_SEND_STR_LEN];
} TCmdString;
typedef struct TCmdGolem {
BYTE bCmd;
BYTE _mx;
BYTE _my;
BYTE _mdir;
BYTE _menemy;
long _mhitpoints;
BYTE _currlevel;
} TCmdGolem;
typedef struct TCmdQuest {
BYTE bCmd;
BYTE q;
BYTE qstate;
BYTE qlog;
BYTE qvar1;
} TCmdQuest;
typedef struct TCmdGItem {
BYTE bCmd;
BYTE bMaster;
BYTE bPnum;
BYTE bCursitem;
// drb.patch1.start.2/05/97
BYTE bLevel;
// drb.patch1.end.2/05/97
BYTE x;
BYTE y;
WORD wIndx;
WORD wCI;
DWORD dwSeed;
BYTE bId;
BYTE bDur;
BYTE bMDur;
BYTE bCh;
BYTE bMCh;
WORD wValue;
DWORD dwBuff;
DWORD dwTime;
WORD wPLToHit;
WORD wMaxDam;
BYTE bMinStr;
BYTE bMinMag;
BYTE bMinDex;
BYTE bAC;
} TCmdGItem;
typedef struct TCmdPItem {
BYTE bCmd;
BYTE x;
BYTE y;
WORD wIndx;
WORD wCI;
DWORD dwSeed;
BYTE bId;
BYTE bDur;
BYTE bMDur;
BYTE bCh;
BYTE bMCh;
WORD wValue;
DWORD dwBuff;
WORD wPLToHit;
WORD wMaxDam;
BYTE bMinStr;
BYTE bMinMag;
BYTE bMinDex;
BYTE bAC;
} TCmdPItem;
typedef struct TCmdChItem {
BYTE bCmd;
BYTE bLoc;
WORD wIndx;
WORD wCI;
DWORD dwSeed;
// drb.patch1.start.02/10/97
BYTE bId;
// drb.patch1.end.02/10/97
} TCmdChItem;
typedef struct TCmdDelItem {
BYTE bCmd;
BYTE bLoc;
} TCmdDelItem;
typedef struct TCmdDamage{
BYTE bCmd;
BYTE bPlr;
DWORD dwDam;
} TCmdDamage;
typedef struct TCmdMonstDamage{
BYTE bCmd;
WORD wMonst;
DWORD dwDam;
} TCmdMonstDamage;
typedef struct TFakeCmdPlr {
BYTE bCmd;
BYTE bPlr;
} TFakeCmdPlr;
typedef struct TFakeDropPlr {
BYTE bCmd;
BYTE bPlr;
DWORD dwReason;
} TFakeDropPlr;
// stuff that is on every level
typedef struct DMonsterStr {
BYTE _mx;
BYTE _my;
BYTE _mdir;
BYTE _menemy;
BYTE _msquelch;
long _mhitpoints;
} DMonsterStr;
typedef struct DObjectStr {
BYTE bCmd;
} DObjectStr;
typedef struct DLevel {
TCmdPItem item[MAXITEMS];
DObjectStr object[MAXOBJECTS];
DMonsterStr monster[MAXMONSTERS];
} DLevel;
typedef struct LocalLevel {
BYTE automapsv[AUTOMAPX][AUTOMAPY];
} LocalLevel;
// stuff which is dungeon global
typedef struct DPortal {
BYTE x;
BYTE y;
BYTE level;
BYTE ltype;
BYTE setlvl;
} DPortal;
typedef struct MultiQuests {
BYTE qstate;
BYTE qlog;
BYTE qvar1;
} MultiQuests;
typedef struct DJunk {
DPortal portal[MAXPORTAL];
MultiQuests quests[MAXMULTIQUESTS + 1];
} DJunk;
#pragma pack(pop)
#define INIT_VAL 0xff
static DJunk sgJunk;
static DLevel sgLevels[NUMLEVELS]; // sent to other players
static LocalLevel sgLocals[NUMLEVELS]; // not sent
// number of chunks of info we must receive to get all delta info
// 16 levels + 1 town level = NUMLEVELS
// + 1 global "junk" chunk
// + 1 terminator
// + 1 startup
// + 1 "99%" complete
#define DELTA_CHUNKS (NUMLEVELS+1+1+1+1)
// allocate extra space to account for flag byte
#define SEND_LEVEL_SIZE (max(sizeof(DLevel),sizeof(DJunk)) + 1)
// buffer to receive level information
static BYTE sgbRecvLevel[SEND_LEVEL_SIZE];
static BYTE sgbRecvCmd;
static DWORD sgdwRecvOffset;
static BYTE sgbDeltaChunks;
static BYTE sgbDeltaChanged;
static DWORD sgdwOwnerWait;
// item flags which go into sgLevel[].item[].bCmd
// item generated on floor of dungeon -- presently on floor
#define ITEM_GEN_FLOOR 0
// item generated on floor of dungeon -- presently not on floor
#define ITEM_GEN_TAKEN 1
// item was dropped -- presently on floor
#define ITEM_DROP_FLOOR 2
// we don't have to keep track of items which were not originally
// part of the dungeon and were dropped and then picked up
// item slot not in use
#define ITEM_FREE INIT_VAL
//******************************************************************
//******************************************************************
// time to keep resending messages if they don't make sense yet
#define RESEND_TIME 5000 // milliseconds
//******************************************************************
// delta buffering
//******************************************************************
#pragma pack(push,1)
// this structure contains a whole bunch of link packets
typedef struct TMegaPkt {
struct TMegaPkt * pNext;
DWORD dwSpaceLeft;
BYTE data[32000];
} TMegaPkt;
#pragma pack(pop)
static TMegaPkt * sgpMegaPkt;
static TMegaPkt * sgpCurrPkt;
static int sgnCurrMegaPlayer;
// PATCH1.JMM
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
DWORD dwRecCount = 0;
#if _DEBUG
void __cdecl DROPLOG(const char * pszFmt,...) {
extern BOOL gbDumpDropLog;
if (! gbDumpDropLog) return;
static FILE * f = NULL;
if (! f) f = fopen("c:\\droplog.txt","wb");
if (! f) return;
va_list args;
va_start(args,pszFmt);
fprintf(f,"(%8.8x,%2.2d):",dwRecCount,numitems);
vfprintf(f,pszFmt,args);
fflush(f);
va_end(args);
}
#else
#define DROPLOG //
#endif
// ENDPATCH1.JMM
//******************************************************************
//******************************************************************
static void mega_add_pkt() {
sgpCurrPkt = (TMegaPkt *) DiabloAllocPtrSig(sizeof(TMegaPkt),'MEGA');
sgpCurrPkt->pNext = NULL;
sgpCurrPkt->dwSpaceLeft = sizeof(sgpCurrPkt->data);
TMegaPkt ** ppCurr = &sgpMegaPkt;
while (*ppCurr) ppCurr = &(*ppCurr)->pNext;
*ppCurr = sgpCurrPkt;
}
//******************************************************************
//******************************************************************
static void mega_free_pkts() {
while (sgpMegaPkt) {
sgpCurrPkt = sgpMegaPkt->pNext;
DiabloFreePtr(sgpMegaPkt);
sgpMegaPkt = sgpCurrPkt;
}
// NOTE: both sgpMegaPkt & sgpCurrPkt are NULL
}
//******************************************************************
//******************************************************************
static void mega_run_pkts() {
int nPlayer = -1;
for (TMegaPkt * pMega = sgpMegaPkt; pMega; pMega = pMega->pNext) {
const BYTE * pbData = pMega->data;
DWORD dwBytes = sizeof(pMega->data);
while (dwBytes != pMega->dwSpaceLeft) {
if (*pbData == FAKE_CMD_SETID) {
const TFakeCmdPlr * p = (const TFakeCmdPlr *) pbData;
pbData += sizeof(TFakeCmdPlr);
dwBytes -= sizeof(TFakeCmdPlr);
nPlayer = p->bPlr;
}
else if (*pbData == FAKE_CMD_DROPID) {
const TFakeDropPlr * p = (const TFakeDropPlr *) pbData;
pbData += sizeof(TFakeDropPlr);
dwBytes -= sizeof(TFakeDropPlr);
void unbuffer_remove_player(int pnum,DWORD dwReason);
unbuffer_remove_player(p->bPlr,p->dwReason);
}
else {
app_assert((DWORD) nPlayer < MAX_PLRS);
const TCmd * p = (const TCmd *) pbData;
DWORD dwTemp = ParseCmd(nPlayer,p);
pbData += dwTemp;
dwBytes -= dwTemp;
}
}
}
}
//******************************************************************
//******************************************************************
static void mega_add_data(int pnum,const void * pMsg,DWORD dwLen) {
app_assert((DWORD) pnum < MAX_PLRS);
app_assert(pMsg);
app_assert(dwLen <= gdwLargestMsgSize);
if (pnum != sgnCurrMegaPlayer) {
// add a command to set the current player
TFakeCmdPlr cmd;
sgnCurrMegaPlayer = pnum;
cmd.bCmd = FAKE_CMD_SETID;
cmd.bPlr = (BYTE) pnum;
mega_add_data(pnum,&cmd,sizeof(cmd));
}
// if there isn't enough space in the current megapkt, add another
app_assert(sgpCurrPkt);
if (sgpCurrPkt->dwSpaceLeft < dwLen)
mega_add_pkt();
app_assert(sgpCurrPkt->dwSpaceLeft >= dwLen);
// add data to megapacket
CopyMemory(
sgpCurrPkt->data + sizeof(sgpCurrPkt->data) - sgpCurrPkt->dwSpaceLeft,
pMsg,
dwLen
);
sgpCurrPkt->dwSpaceLeft -= dwLen;
}
//******************************************************************
//******************************************************************
void buffer_drop_player(int pnum,DWORD dwReason) {
TFakeDropPlr cmd;
cmd.bCmd = FAKE_CMD_DROPID;
cmd.bPlr = (BYTE) pnum;
cmd.dwReason = dwReason;
mega_add_data(pnum,&cmd,sizeof(cmd));
}
//******************************************************************
//******************************************************************
// pjw.patch2.start
static int CALLBACK delta_progress() {
if (sgbDeltaChunks == 0) {
// wait until we receive master player's future
// turn before we process our first turn. This is
// designed so that we don't start several turns ahead
// of the master player and stay there forever. We are
// waiting for turn X from all players. We wait for
// turn (X+gdwTurnsInTransit) from the master player, which
// means that the master player processed turn X and has
// sent turns X+1 and X+2. When we process turn X, we will be
// synced with the master player less the one-way packet
// latency from the master player.
DWORD dwTurns;
nthread_fill_sync_queue(0,0);
if (! SNetGetOwnerTurnsWaiting(&dwTurns)) {
if (GetLastError() == SNET_ERROR_NOT_IN_GAME)
return 100;
}
// wait a maximum of 2 seconds before we give
// up syncing and just try for whatever we can get
// if a turn got dropped by the owner, it is possible
// we could wait forever for the owner, while he waits
// forever for us to resend the dropped turn.
if (GetTickCount() - sgdwOwnerWait <= 2000) {
if (dwTurns < gdwTurnsInTransit)
return 0;
}
sgbDeltaChunks++;
}
// handle asynchronous messages
NetReceivePackets();
// handle synchronous messages
BOOL bSendAsync;
nthread_fill_sync_queue(0,0);
// pjw.patch2.start -- if we call nthread_msg_check() without
// protection against "overcalling" then the gameclock will get
// continually reset and other systems will drop into timeout mode
// nthread_msg_check(&bSendAsync);
if (nthread_run_gameloop(FALSE)) nthread_msg_check(&bSendAsync);
// pjw.patch2.end
// if the game was destroyed, return "100% complete" to exit dialog
if (gbGameDestroyed) return 100;
// if the person sending us delta info dropped out,
// then we need to re-request the delta information
if (gbDeltaSender >= MAX_PLRS) {
sgbRecvCmd = CMD_DLEVEL_END;
sgbDeltaChunks = 0;
gbDeltaSender = (BYTE) myplr;
nthread_set_delta_request();
}
// make bar "full"
if (sgbDeltaChunks == DELTA_CHUNKS - 1) {
sgbDeltaChunks++;
return 99;
}
// return completion status
return (sgbDeltaChunks * 100) / DELTA_CHUNKS;
}
// pjw.patch2.end
//******************************************************************
//******************************************************************
BOOL wait_delta_info() {
app_assert(ghMainWnd);
app_assert(! sgpMegaPkt);
app_assert(! sgpCurrPkt);
mega_add_pkt();
sgbRecvCmd = CMD_DLEVEL_END;
sgbDeltaChunks = 0;
gbBufferMsgs = BUFFER_ON;
sgnCurrMegaPlayer = -1;
sgdwOwnerWait = GetTickCount();
BOOL bResult = UiProgressDialog(
ghMainWnd,
"Waiting for game data...",
TRUE, // allow abort
delta_progress,
GAME_FRAMES_PER_SECOND // calls per second
);
// done buffering messages, but don't go into BUFFER_PROCESS
// mode until we've successfully loaded the level
gbBufferMsgs = BUFFER_OFF;
if (! bResult) {
// no message -- user canceled
mega_free_pkts();
return FALSE;
}
else if (gbGameDestroyed) {
app_warning("The game ended");
mega_free_pkts();
return FALSE;
}
else if (sgbDeltaChunks != DELTA_CHUNKS) {
app_warning("Unable to get level data");
mega_free_pkts();
return FALSE;
}
// leave the delta information around
// until the game level has been loaded
// and then run all the accumulated packets
return TRUE;
}
//******************************************************************
//******************************************************************
void run_delta_info() {
if (gbMaxPlayers == 1) return;
app_assert(currlevel == 0);
app_assert(plr[myplr].plrlevel == 0);
gbBufferMsgs = BUFFER_PROCESS;
mega_run_pkts();
gbBufferMsgs = BUFFER_OFF;
mega_free_pkts();
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BYTE * dbuild_items(BYTE * pbData,const TCmdPItem * pItem) {
for (int i = 0; i < MAXITEMS; i++,pItem++) {
if (pItem->bCmd == INIT_VAL) {
*pbData++ = INIT_VAL;
}
else {
//CopyMemory(pbData,pItem,sizeof(TCmdPItem));
*(reinterpret_cast<TCmdPItem *>(pbData)) = *pItem;
pbData += sizeof(TCmdPItem);
}
}
return pbData;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static const BYTE * dparse_items(const BYTE * pbData,TCmdPItem * pItem) {
for (int i = 0; i < MAXITEMS; i++,pItem++) {
if (*pbData == INIT_VAL) {
FillMemory(pItem,sizeof(TCmdPItem),INIT_VAL);
pbData++;
}
else {
//CopyMemory(pItem,pbData,sizeof(TCmdPItem));
*pItem = *(reinterpret_cast<const TCmdPItem *>(pbData));
pbData += sizeof(TCmdPItem);
}
}
return pbData;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BYTE * dbuild_objects(BYTE * pbData,const DObjectStr * pObj) {
// the object structure is only one byte, so just
// rely upon data compression to make it smaller
CopyMemory(pbData,pObj,MAXOBJECTS * sizeof(DObjectStr));
return pbData + MAXOBJECTS * sizeof(DObjectStr);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static const BYTE * dparse_objects(const BYTE * pbData,DObjectStr * pObj) {
// the object structure is only one byte, so just
// rely upon data compression to make it smaller
CopyMemory(pObj,pbData,MAXOBJECTS * sizeof(DObjectStr));
return pbData + MAXOBJECTS * sizeof(DObjectStr);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BYTE * dbuild_monsters(BYTE * pbData,const DMonsterStr * pM) {
for (int m = 0; m < MAXMONSTERS; m++,pM++) {
if (pM->_mx == INIT_VAL) {
*pbData++ = INIT_VAL;
}
else {
//CopyMemory(pbData,pM,sizeof(DMonsterStr));
*(reinterpret_cast<DMonsterStr *>(pbData)) = *pM;
pbData += sizeof(DMonsterStr);
}
}
return pbData;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static const BYTE * dparse_monsters(const BYTE * pbData,DMonsterStr * pM) {
for (int m = 0; m < MAXMONSTERS; m++,pM++) {
if (*pbData == INIT_VAL) {
FillMemory(pM,sizeof(DMonsterStr),INIT_VAL);
pbData++;
}
else {
//CopyMemory(pM,pbData,sizeof(DMonsterStr));
*pM = *(reinterpret_cast<const DMonsterStr *> (pbData));
pbData += sizeof(DMonsterStr);
}
}
return pbData;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
extern QuestData questlist[];
static BYTE * dbuild_junk(BYTE * pbData) {
for (int i = 0; i < MAXPORTAL; i++) {
if (sgJunk.portal[i].x == INIT_VAL) {
*pbData++ = INIT_VAL;
}
else {
//CopyMemory(pbData,&sgJunk.portal[i],sizeof(DPortal));
*(reinterpret_cast<DPortal *>(pbData)) = sgJunk.portal[i];
pbData += sizeof(DPortal);
}
}
i = 0;
for (int q = 0; q < MAXQUESTS; q++) {
if (questlist[q]._qflags & QFLAG_MULTI) {
sgJunk.quests[i].qlog = quests[q]._qlog;
sgJunk.quests[i].qstate = quests[q]._qactive;
sgJunk.quests[i].qvar1 = quests[q]._qvar1;
//CopyMemory(pbData,&sgJunk.quests[i],sizeof(MultiQuests));
*(reinterpret_cast<MultiQuests *>(pbData)) = sgJunk.quests[i];
pbData += sizeof(MultiQuests);
i++;
}
}
return pbData;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void dparse_junk(const BYTE * pbData) {
int i;
for (i = 0; i < MAXPORTAL; i++) {
if (*pbData == INIT_VAL) {
FillMemory(&sgJunk.portal[i],sizeof(DPortal),INIT_VAL);
pbData++;
SyncPortal(i, FALSE, 0, 0, 0, 0);
}
else {
//CopyMemory(&sgJunk.portal[i],pbData,sizeof(DPortal));
sgJunk.portal[i] = *(reinterpret_cast<const DPortal *>(pbData));
pbData += sizeof(DPortal);
SyncPortal(i, TRUE, sgJunk.portal[i].x, sgJunk.portal[i].y, sgJunk.portal[i].level, sgJunk.portal[i].ltype);
}
}
i = 0;
for (int q = 0; q < MAXQUESTS; q++) {
if (questlist[q]._qflags & QFLAG_MULTI) {
//CopyMemory(&sgJunk.quests[i],pbData,sizeof(MultiQuests));
sgJunk.quests[i] = *(reinterpret_cast<const MultiQuests *>(pbData));
pbData += sizeof(MultiQuests);
quests[q]._qlog = sgJunk.quests[i].qlog;
quests[q]._qactive = sgJunk.quests[i].qstate;
quests[q]._qvar1 = sgJunk.quests[i].qvar1;
i++;
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD compress_chunk(BYTE * pbStart,BYTE * pbEnd) {
// calculate length excluding leading byte
DWORD dwLen = pbEnd - pbStart - 1;
// compress data excluding leading byte
DWORD dwBytes = Compress(pbStart + 1,dwLen);
// set compress flag ==> TRUE = compressed
*pbStart = (dwLen != dwBytes);
// add one extra byte for compress flag
return dwBytes + 1;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void DeltaSendAllLevels(int pnum) {
// send all delta information to player pnum
if (sgbDeltaChanged) {
BYTE * pbData;
DWORD dwBytes;
BYTE * pbBase = (BYTE *) DiabloAllocPtrSig(SEND_LEVEL_SIZE,'DLTt');
for (int bLevel = 0; bLevel < NUMLEVELS; bLevel++) {
// save 1 byte for compress/uncompress flag
pbData = pbBase + 1;
// build level data
pbData = dbuild_items(pbData,&sgLevels[bLevel].item[0]);
pbData = dbuild_objects(pbData,&sgLevels[bLevel].object[0]);
pbData = dbuild_monsters(pbData,&sgLevels[bLevel].monster[0]);
dwBytes = compress_chunk(pbBase,pbData);
dthread_SendPlayerInfoChunk(pnum,CMD_DLEVEL_0 + bLevel,pbBase,dwBytes);
}
// send junk chunk -- save one byte for compress/uncompress flag
pbData = dbuild_junk(pbBase + 1);
dwBytes = compress_chunk(pbBase,pbData);
dthread_SendPlayerInfoChunk(pnum,CMD_DLEVEL_JUNK,pbBase,dwBytes);
DiabloFreePtr(pbBase);
}
// send 1 byte terminator chunk
BYTE c = 0; // mark as "uncompressed"
dthread_SendPlayerInfoChunk(pnum,CMD_DLEVEL_END,&c,1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void dparse_chunk(BYTE bMsg,DWORD dwLen) {
// first byte is a flag which indicates whether the data is compressed
if (sgbRecvLevel[0]) Expand(&sgbRecvLevel[1],dwLen,sizeof(sgbRecvLevel) - 1);
const BYTE * pbData = &sgbRecvLevel[1];
if (bMsg == CMD_DLEVEL_JUNK) {
dparse_junk(pbData);
}
else if (bMsg >= CMD_DLEVEL_0 && bMsg <= CMD_DLEVEL_24) {
BYTE bLevel = bMsg - CMD_DLEVEL_0;
pbData = dparse_items(pbData,&sgLevels[bLevel].item[0]);
pbData = dparse_objects(pbData,&sgLevels[bLevel].object[0]);
pbData = dparse_monsters(pbData,&sgLevels[bLevel].monster[0]);
}
else {
app_fatal("msg:1");
}
sgbDeltaChanged = TRUE;
sgbDeltaChunks++;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD dreceive_chunk(int pnum,const TCmdPlrInfoHdr * p) {
if (gbDeltaSender != pnum) {
// we are unexpectedly receiving delta info from somebody
// if they aren't sending us the starting information, ignore it
// otherwise, make them the new delta source
if (p->bCmd == CMD_DLEVEL_END) {
// we're getting an end chunk without any intervening delta
// which means there is no delta information
}
else if (p->bCmd != CMD_DLEVEL_0 || p->wOffset != 0) {
return p->wBytes + sizeof(TCmdPlrInfoHdr);
}
gbDeltaSender = (BYTE) pnum;
sgbRecvCmd = CMD_DLEVEL_END;
}
if (sgbRecvCmd == CMD_DLEVEL_END) {
if (p->bCmd == CMD_DLEVEL_END) {
// we received the end command immediately, which
// means there was no level delta info
sgbDeltaChunks = DELTA_CHUNKS - 1; // set 99% done
return p->wBytes + sizeof(TCmdPlrInfoHdr);
}
if (p->bCmd != CMD_DLEVEL_0 || p->wOffset != 0) {
// someone is in the middle of sending us info
// but we don't have the beginning
// just ignore the message
return p->wBytes + sizeof(TCmdPlrInfoHdr);
}
// we just started receiving new data from the player
sgdwRecvOffset = 0;
sgbRecvCmd = p->bCmd;
}
else if (sgbRecvCmd != p->bCmd) {
// since we are receiving a new delta chunk,
// we must have finished receiving the last delta chunk.
// process last chunk before handling next chunk.
// ???dparse_chunk(sgbRecvCmd,sgdwRecvOffset + p->wBytes);
dparse_chunk(sgbRecvCmd,sgdwRecvOffset);
// what's the new command?
if (p->bCmd == CMD_DLEVEL_END) {
// set 99% done flag
sgbDeltaChunks = DELTA_CHUNKS - 1;
sgbRecvCmd = CMD_DLEVEL_END;
return p->wBytes + sizeof(TCmdPlrInfoHdr);
}
sgdwRecvOffset = 0;
sgbRecvCmd = p->bCmd;
}
app_assert(p->wOffset == sgdwRecvOffset);
CopyMemory( &sgbRecvLevel[p->wOffset],
((BYTE *)p) + sizeof(TCmdPlrInfoHdr),
p->wBytes
);
sgdwRecvOffset += p->wBytes;
return p->wBytes + sizeof(TCmdPlrInfoHdr);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void delta_init() {
sgbDeltaChanged = FALSE;
FillMemory(&sgJunk,sizeof sgJunk,INIT_VAL);
FillMemory(&sgLevels[0],sizeof sgLevels,INIT_VAL);
ZeroMemory(sgLocals,sizeof sgLocals);
deltaload = FALSE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void delta_kill_monster(int mi, BYTE x, BYTE y, BYTE bLevel) {
if (gbMaxPlayers == 1) return;
app_assert((DWORD)mi < MAXMONSTERS);
app_assert(x < DMAXX);
app_assert(y < DMAXY);
app_assert(bLevel < NUMLEVELS);
sgbDeltaChanged = TRUE;
DMonsterStr * p = &sgLevels[bLevel].monster[mi];
p->_mx = x;
p->_my = y;
p->_mdir = monster[mi]._mdir;
p->_mhitpoints = 0;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void delta_monster_hp(int mi,long hp,BYTE bLevel) {
if (gbMaxPlayers == 1) return;
app_assert((DWORD)mi < MAXMONSTERS);
app_assert(bLevel < NUMLEVELS);
sgbDeltaChanged = TRUE;
DMonsterStr * p = &sgLevels[bLevel].monster[mi];
if (p->_mhitpoints > hp) p->_mhitpoints = hp;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void delta_sync_monster(const TSyncMonster * pSync,BYTE bLevel) {
if (gbMaxPlayers == 1) return;
app_assert(pSync != NULL);
app_assert(bLevel < NUMLEVELS);
sgbDeltaChanged = TRUE;
DMonsterStr * pD = &sgLevels[bLevel].monster[pSync->_mndx];
// is this monster already dead?
if (! pD->_mhitpoints) return;
pD->_mx = pSync->_mx;
pD->_my = pSync->_my;
pD->_msquelch = 255;
//app_assert((DWORD) pSync->_menemy < MAX_PLRS); @@@ Taken out becasue monster enemy could be a monster
pD->_menemy = pSync->_menemy;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void delta_sync_golem(const TCmdGolem * pG, int pnum, BYTE bLevel) {
if (gbMaxPlayers == 1) return;
app_assert(bLevel < NUMLEVELS);
app_assert(bLevel != 0);
sgbDeltaChanged = TRUE;
DMonsterStr * pD = &sgLevels[bLevel].monster[pnum];
pD->_mx = pG->_mx;
pD->_my = pG->_my;
pD->_msquelch = 255;
pD->_menemy = pG->_menemy;
pD->_mdir = pG->_mdir;
pD->_mhitpoints = pG->_mhitpoints;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void delta_leave_sync(BYTE bLevel) {
if (gbMaxPlayers == 1) return;
// recycle town store seeds
if (currlevel == 0) glSeedTbl[0] = GetRndSeed();
if (currlevel <= 0) return;
app_assert(bLevel < NUMLEVELS);
for (int i = 0; i < nummonsters; i++) {
int ii = monstactive[i];
if (monster[ii]._mhitpoints == 0) continue;
sgbDeltaChanged = TRUE;
DMonsterStr * pD = &sgLevels[bLevel].monster[ii];
pD->_mx = monster[ii]._mx;
pD->_my = monster[ii]._my;
pD->_mdir = monster[ii]._mdir;
pD->_menemy = encode_enemy(ii);
//app_assert((DWORD) pD->_menemy < MAX_PLRS);
pD->_mhitpoints = monster[ii]._mhitpoints;
pD->_msquelch = monster[ii]._msquelch;
}
// copy automap
app_assert(sizeof(sgLocals[bLevel].automapsv) == sizeof(automapview));
CopyMemory(
&sgLocals[bLevel].automapsv[0][0],
&automapview[0][0],
sizeof(sgLocals[bLevel].automapsv)
);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void delta_sync_object(int oi,BYTE bCmd,BYTE bLevel) {
if (gbMaxPlayers == 1) return;
app_assert((DWORD)oi < MAXOBJECTS);
app_assert(bLevel < NUMLEVELS);
sgbDeltaChanged = TRUE;
DObjectStr * p = &sgLevels[bLevel].object[oi];
p->bCmd = bCmd;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BOOL delta_get_item(const TCmdGItem * pI, BYTE bLevel) {
if (gbMaxPlayers == 1) return(TRUE);
app_assert(pI != NULL);
app_assert(bLevel < NUMLEVELS);
TCmdPItem * pD = &sgLevels[bLevel].item[0];
for (int i = 0; i < MAXITEMS; i++,pD++) {
// find item
if (pD->bCmd == ITEM_FREE) continue;
if (pD->wIndx != pI->wIndx) continue;
if (pD->wCI != pI->wCI) continue;
if (pD->dwSeed != pI->dwSeed) continue;
if (pD->bCmd == ITEM_GEN_TAKEN) {
// PATCH1.JMM
DROPLOG(" delta_get_item: item already picked up?!\n");
// ENDPATCH1.JMM
// someone else already picked it up?!
return(TRUE);
}
else if (pD->bCmd == ITEM_GEN_FLOOR) {
// pick item up from floor, but keep track
// of the fact that it is a generated item
// PATCH1.JMM
DROPLOG(" delta_get_item: native item picked up from floor\n");
// ENDPATCH1.JMM
sgbDeltaChanged = TRUE;
pD->bCmd = ITEM_GEN_TAKEN;
return(TRUE);
}
else if (pD->bCmd == ITEM_DROP_FLOOR) {
// since the item was dropped on the floor but
// not part of the generated dungeon, as soon
// as it is picked up we can forget about it
// PATCH1.JMM
DROPLOG(" delta_get_item: foreign item picked up from floor\n");
// ENDPATCH1.JMM
sgbDeltaChanged = TRUE;
pD->bCmd = ITEM_FREE;
return(TRUE);
}
else {
app_fatal("delta:1");
}
break;
}
// PATCH1.JMM
DROPLOG(" delta_get_item: item not found\n");
// ENDPATCH1.JMM
// If we are trying to remove an item from the delta list and it is not a dungeon
// pregenerated item, then forget it. Chances are that it was a message sent and
// buffered before the level delta was passed to us. So the level delta has the
// change in it already and we are processing the buffered message which is just
// duplicating what is already there.
// The above is true, or it could be we are processing the pickup before the drop
// so, we will be resending this message to ourselves
if (!(pI->wCI & ICI_PREGEN))
return(FALSE);
//app_assert(bLevel > 0);
// If not found, then an item generated by a level that I have not been to yet
pD = &sgLevels[bLevel].item[0];
for (i = 0; i < MAXITEMS; i++,pD++) {
// Free slot?
if (pD->bCmd != ITEM_FREE) continue;
// put the item into the delta table
// PATCH1.JMM
DROPLOG(" delta_get_item: added item to delta tbl");
// ENDPATCH1.JMM
sgbDeltaChanged = TRUE;
pD->bCmd = ITEM_GEN_TAKEN;
pD->x = pI->x;
pD->y = pI->y;
pD->wIndx = pI->wIndx;
pD->wCI = pI->wCI;
pD->dwSeed = pI->dwSeed;
pD->bId = pI->bId;
pD->bDur = pI->bDur;
pD->bMDur = pI->bMDur;
pD->bCh = pI->bCh;
pD->bMCh = pI->bMCh;
pD->wValue = pI->wValue;
pD->dwBuff = pI->dwBuff;
pD->wPLToHit = pI->wPLToHit;
pD->wMaxDam = pI->wMaxDam;
pD->bMinStr = pI->bMinStr;
pD->bMinMag = pI->bMinMag;
pD->bMinDex = pI->bMinDex;
pD->bAC = pI->bAC;
return(TRUE);
}
// PATCH1.JMM
DROPLOG(" delta_get_item: could not add item to delta tbl");
// ENDPATCH1.JMM
return(TRUE);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void delta_put_item(const TCmdPItem * pI, int x, int y, BYTE bLevel) {
if (gbMaxPlayers == 1) return;
app_assert(pI != NULL);
app_assert(x < DMAXX);
app_assert(y < DMAXY);
app_assert(bLevel < NUMLEVELS);
// see if the item was already part of the generated dungeon
TCmdPItem * pD = &sgLevels[bLevel].item[0];
for (int i = 0; i < MAXITEMS; i++,pD++) {
if (pD->bCmd == ITEM_GEN_TAKEN) continue;
if (pD->bCmd == ITEM_FREE) continue;
if (pD->wIndx != pI->wIndx) continue;
if (pD->wCI != pI->wCI) continue;
if (pD->dwSeed != pI->dwSeed) continue;
// Already placed?
if (pD->bCmd == ITEM_DROP_FLOOR) {
return;
}
app_fatal("Trying to drop a floor item?");
}
// find a location to drop this item
pD = &sgLevels[bLevel].item[0];
for (i = 0; i < MAXITEMS; i++,pD++) {
if (pD->bCmd != ITEM_FREE) continue;
// put the item back onto the floor at its
// new location and with its new state
sgbDeltaChanged = TRUE;
//CopyMemory(pD,pI,sizeof(TCmdPItem));
*pD = *pI; // struct copy.
pD->bCmd = ITEM_DROP_FLOOR;
pD->x = x;
pD->y = y;
return;
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
BOOL delta_portal_inited(int i)
{
app_assert((DWORD)i < MAXPORTAL);
if (sgJunk.portal[i].x == INIT_VAL) return(TRUE);
else return(FALSE);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
BOOL delta_quest_inited(int i)
{
app_assert((DWORD)i <= MAXMULTIQUESTS);
if (sgJunk.quests[i].qstate == INIT_VAL) return(FALSE);
else return(TRUE);
}
/*-----------------------------------------------------------------------**
** Called when level creating
**-----------------------------------------------------------------------*/
void DeltaAddItem(int ii) {
if (gbMaxPlayers == 1) return;
app_assert((DWORD)ii < MAXITEMS);
// Already in delta?
TCmdPItem * pD = &sgLevels[currlevel].item[0];
for (int i = 0; i < MAXITEMS; i++,pD++) {
if (pD->bCmd == ITEM_FREE) continue;
if (pD->wIndx != item[ii].IDidx) continue;
if (pD->wCI != item[ii]._iCreateInfo) continue;
if (pD->dwSeed != (DWORD)item[ii]._iSeed) continue;
// taken?
if (pD->bCmd == ITEM_GEN_TAKEN) return;
// 2nd time down?
if (pD->bCmd == ITEM_GEN_FLOOR) return;
}
// find a location to drop this item
pD = &sgLevels[currlevel].item[0];
for (i = 0; i < MAXITEMS; i++,pD++) {
if (pD->bCmd != ITEM_FREE) continue;
// put the item back onto the floor at its
// new location and with its new state
sgbDeltaChanged = TRUE;
pD->bCmd = ITEM_GEN_FLOOR;
pD->x = item[ii]._ix;
pD->y = item[ii]._iy;
pD->wIndx = item[ii].IDidx;
pD->wCI = item[ii]._iCreateInfo;
pD->dwSeed = item[ii]._iSeed;
pD->bId = item[ii]._iIdentified;
pD->bDur = item[ii]._iDurability;
pD->bMDur = item[ii]._iMaxDur;
pD->bCh = item[ii]._iCharges;
pD->bMCh = item[ii]._iMaxCharges;
pD->wValue = item[ii]._ivalue;
pD->wPLToHit = item[ii]._iPLToHit;
pD->wMaxDam = item[ii]._iMaxDam;
pD->bMinStr = item[ii]._iMinStr;
pD->bMinMag = item[ii]._iMinMag;
pD->bMinDex = item[ii]._iMinDex;
pD->bAC = item[ii]._iAC;
return;
}
}
/*-----------------------------------------------------------------------*
**-----------------------------------------------------------------------*/
void DeltaSaveLevel() {
if (gbMaxPlayers == 1) return;
// throw away everyone else's graphics, they
// are probably out of date anyway
for (int i = 0; i < MAX_PLRS; i++)
if (i != myplr) plr[i]._pGFXLoad = 0;
app_assert((DWORD) currlevel < NUMLEVELS);
plr[myplr]._pLvlVisited[currlevel] = TRUE;
delta_leave_sync(currlevel);
}
/*-----------------------------------------------------------------------*
**-----------------------------------------------------------------------*/
// PATCH1.JMM
BOOL CanPut(int i, int j);
// ENDPATCH1.JMM
void DeltaLoadLevel() {
if (gbMaxPlayers == 1) return;
int i, ii;
deltaload = TRUE;
// don't do the monster stuff for level 0, that is the town!
if (currlevel != 0) {
for (i = 0; i < nummonsters; i++) {
if (sgLevels[currlevel].monster[i]._mx == INIT_VAL) continue;
M_ClearSquares(i);
monster[i]._mx = sgLevels[currlevel].monster[i]._mx;
monster[i]._my = sgLevels[currlevel].monster[i]._my;
monster[i]._moldx = monster[i]._mx;
monster[i]._moldy = monster[i]._my;
monster[i]._mfutx = monster[i]._mx;
monster[i]._mfuty = monster[i]._my;
if (sgLevels[currlevel].monster[i]._mhitpoints != -1)
monster[i]._mhitpoints = sgLevels[currlevel].monster[i]._mhitpoints;
// Is monster dead?
if (sgLevels[currlevel].monster[i]._mhitpoints == 0) {
monster[i]._moldx = sgLevels[currlevel].monster[i]._mx;
monster[i]._moldy = sgLevels[currlevel].monster[i]._my;
M_ClearSquares(i);
if (monster[i]._mAi != AI_DIABLO) { // Diablo has no death frame
if (monster[i]._uniqtype == 0) {
app_assert(monster[i].MType != NULL);
AddDead(monster[i]._mx, monster[i]._my, monster[i].MType->mdeadval, monster[i]._mdir);
} else {
AddDead(monster[i]._mx, monster[i]._my, monster[i]._udeadval, monster[i]._mdir);
}
}
monster[i]._mDelFlag = TRUE;
M_UpdateLeader(i);
} else {
int enemy = sgLevels[currlevel].monster[i]._menemy;
//app_assert((DWORD) enemy < MAX_PLRS);
decode_enemy(i, enemy);
if (((monster[i]._mx != 0) && (monster[i]._mx != 1)) || (monster[i]._my != 0)) dMonster[monster[i]._mx][monster[i]._my] = i + 1;
if (i < 4) {
MAI_Golum(i);
monster[i]._mFlags |= MFLAG_MID;
monster[i]._mFlags |= MFLAG_MKILLER;
} else M_StartStand(i, monster[i]._mdir);
monster[i]._msquelch = sgLevels[currlevel].monster[i]._msquelch;
}
}
// copy automap
app_assert(sizeof(sgLocals[currlevel].automapsv) == sizeof(automapview));
CopyMemory(
&automapview[0][0],
&sgLocals[currlevel].automapsv[0][0],
sizeof(automapview)
);
}
for (i = 0; i < MAXITEMS; i++) {
if (sgLevels[currlevel].item[i].bCmd == ITEM_FREE) continue;
if (sgLevels[currlevel].item[i].bCmd == ITEM_GEN_TAKEN) {
ii = FindGetItem(sgLevels[currlevel].item[i].wIndx,
sgLevels[currlevel].item[i].wCI,
sgLevels[currlevel].item[i].dwSeed);
if (ii != -1) {
if (dItem[item[ii]._ix][item[ii]._iy] == (ii+1)) dItem[item[ii]._ix][item[ii]._iy] = 0;
DeleteItem(ii, i);
}
}
if (sgLevels[currlevel].item[i].bCmd == ITEM_DROP_FLOOR) {
ii = itemavail[0];
itemavail[0] = itemavail[MAXITEMS - numitems - 1];
itemactive[numitems] = ii;
if (sgLevels[currlevel].item[i].wIndx == IDI_EAR) {
RecreateEar(ii,
sgLevels[currlevel].item[i].wCI,
sgLevels[currlevel].item[i].dwSeed,
sgLevels[currlevel].item[i].bId,
sgLevels[currlevel].item[i].bDur,
sgLevels[currlevel].item[i].bMDur,
sgLevels[currlevel].item[i].bCh,
sgLevels[currlevel].item[i].bMCh,
sgLevels[currlevel].item[i].wValue,
sgLevels[currlevel].item[i].dwBuff);
} else {
RecreateItem(ii,
sgLevels[currlevel].item[i].wIndx,
sgLevels[currlevel].item[i].wCI,
sgLevels[currlevel].item[i].dwSeed,
sgLevels[currlevel].item[i].wValue);
if (sgLevels[currlevel].item[i].bId) item[ii]._iIdentified = TRUE;
item[ii]._iDurability = sgLevels[currlevel].item[i].bDur;
item[ii]._iMaxDur = sgLevels[currlevel].item[i].bMDur;
item[ii]._iCharges = sgLevels[currlevel].item[i].bCh;
item[ii]._iMaxCharges = sgLevels[currlevel].item[i].bMCh;
item[ii]._iPLToHit = sgLevels[currlevel].item[i].wPLToHit;
item[ii]._iMaxDam = sgLevels[currlevel].item[i].wMaxDam;
item[ii]._iMinStr = sgLevels[currlevel].item[i].bMinStr;
item[ii]._iMinMag = sgLevels[currlevel].item[i].bMinMag;
item[ii]._iMinDex = sgLevels[currlevel].item[i].bMinDex;
item[ii]._iAC = sgLevels[currlevel].item[i].bAC;
}
int ox = sgLevels[currlevel].item[i].x;
int oy = sgLevels[currlevel].item[i].y;
// PATCH1.JMM
if (!CanPut(ox,oy)) {
BOOL done = FALSE;
// radial search outward until a space is found
for (int l = 1; (l < 50) && !done; l++) {
for (int j = -l; (j <= l) && !done; j++) {
int yy = oy + j;
for (int i = -l; (i <= l) && !done; i++) {
int xx = ox + i;
if (!CanPut(xx,yy)) continue;
done = TRUE;
DROPLOG(" DeltaLoadLevel: moving object from (x,y)->(%2.2x,%2.2x) to (x,y)->(%2.2x,%2.2x)!\n",ox,oy,xx,yy);
ox = xx;
oy = yy;
}
}
}
app_assert(done);
}
// ENDPATCH1.JMM
item[ii]._ix = ox;
item[ii]._iy = oy;
dItem[item[ii]._ix][item[ii]._iy] = ii+1;
// PATCH1.JMM
DROPLOG(" DeltaLoadLevel: respawning %d (%4.4x,%4.4x,%8.8x) @ (x,y)->(%2.2x,%2.2x)\n",ii,item[ii]._itype,item[ii]._iCreateInfo,item[ii]._iSeed,item[ii]._ix,item[ii]._iy);
// ENDPATCH1.JMM
RespawnItem(ii, FALSE);
numitems++;
}
}
if (currlevel != 0) {
for (i = 0; i < MAXOBJECTS; i++) {
switch (sgLevels[currlevel].object[i].bCmd) {
case INIT_VAL:
// no object
break;
case CMD_OPENDOOR:
case CMD_CLOSEDOOR:
case CMD_OPERATEOBJ:
case CMD_PLROPOBJ:
SyncOpObject(-1, sgLevels[currlevel].object[i].bCmd, i);
break;
case CMD_BREAKOBJ:
SyncBreakObj(-1, i);
break;
}
}
for (i = 0; i < numobjects; i++) {
ii = objectactive[i];
if ((object[ii]._otype == OBJ_TRAPL) || (object[ii]._otype == OBJ_TRAPR)) Obj_Trap(ii);
}
}
deltaload = FALSE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmd(BOOL bHiPri,BYTE bCmd) {
TCmd cmd;
cmd.bCmd = bCmd;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdGolem(BYTE mx, BYTE my, BYTE dir, BYTE menemy, long hp, BYTE cl) {
app_assert(mx < DMAXX);
app_assert(my < DMAXY);
TCmdGolem cmd;
cmd.bCmd = CMD_AWAKEGOLEM;
cmd._mx = mx;
cmd._my = my;
cmd._mdir = dir;
cmd._menemy = menemy;
cmd._mhitpoints = hp;
cmd._currlevel = cl;
NetSendLoPri((BYTE *) &cmd, sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdLoc(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y) {
app_assert(x < DMAXX);
app_assert(y < DMAXY);
TCmdLoc cmd;
cmd.bCmd = bCmd;
cmd.x = x;
cmd.y = y;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdLocParam1(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y,WORD wParam1) {
app_assert(x < DMAXX);
app_assert(y < DMAXY);
TCmdLocParam1 cmd;
cmd.bCmd = bCmd;
cmd.x = x;
cmd.y = y;
cmd.wParam1 = wParam1;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdLocParam2(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y,WORD wParam1,WORD wParam2) {
app_assert(x < DMAXX);
app_assert(y < DMAXY);
TCmdLocParam2 cmd;
cmd.bCmd = bCmd;
cmd.x = x;
cmd.y = y;
cmd.wParam1 = wParam1;
cmd.wParam2 = wParam2;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdLocParam3(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y,WORD wParam1,WORD wParam2,WORD wParam3) {
app_assert(x < DMAXX);
app_assert(y < DMAXY);
TCmdLocParam3 cmd;
cmd.bCmd = bCmd;
cmd.x = x;
cmd.y = y;
cmd.wParam1 = wParam1;
cmd.wParam2 = wParam2;
cmd.wParam3 = wParam3;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdParam1(BOOL bHiPri,BYTE bCmd,WORD wParam1) {
TCmdParam1 cmd;
cmd.bCmd = bCmd;
cmd.wParam1 = wParam1;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdParam2(BOOL bHiPri,BYTE bCmd,WORD wParam1,WORD wParam2) {
TCmdParam2 cmd;
cmd.bCmd = bCmd;
cmd.wParam1 = wParam1;
cmd.wParam2 = wParam2;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdParam3(BOOL bHiPri,BYTE bCmd,WORD wParam1,WORD wParam2, WORD wParam3) {
TCmdParam3 cmd;
cmd.bCmd = bCmd;
cmd.wParam1 = wParam1;
cmd.wParam2 = wParam2;
cmd.wParam3 = wParam3;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdQuest(BOOL bHiPri,BYTE q) {
TCmdQuest cmd;
cmd.bCmd = CMD_SYNCQUEST;
cmd.q = q;
cmd.qstate = quests[q]._qactive;
cmd.qlog = quests[q]._qlog;
cmd.qvar1 = quests[q]._qvar1;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdGItem(BOOL bHiPri,BYTE bCmd,BYTE mast,BYTE pnum,BYTE ii) {
app_assert(ii < MAXITEMS);
app_assert(pnum < MAX_PLRS);
TCmdGItem cmd;
cmd.bCmd = bCmd;
cmd.bPnum = pnum;
cmd.bMaster = mast;
cmd.dwTime = 0;
cmd.bLevel = currlevel;
cmd.bCursitem = ii;
cmd.x = item[ii]._ix;
cmd.y = item[ii]._iy;
cmd.wIndx = item[ii].IDidx;
if (item[ii].IDidx == IDI_EAR) {
cmd.wCI = (item[ii]._iName[7] << 8) | item[ii]._iName[8];
cmd.dwSeed = (item[ii]._iName[9] << 24) |
(item[ii]._iName[10] << 16) |
(item[ii]._iName[11] << 8) |
item[ii]._iName[12];
cmd.bId = item[ii]._iName[13];
cmd.bDur = item[ii]._iName[14];
cmd.bMDur = item[ii]._iName[15];
cmd.bCh = item[ii]._iName[16];
cmd.bMCh = item[ii]._iName[17];
cmd.wValue = (item[ii]._iName[18] << 8) | ((item[ii]._iCurs - ITEM_EAR1) << 6) | item[ii]._ivalue;
cmd.dwBuff = (item[ii]._iName[19] << 24) |
(item[ii]._iName[20] << 16) |
(item[ii]._iName[21] << 8) |
item[ii]._iName[22];
} else {
cmd.wCI = item[ii]._iCreateInfo;
cmd.dwSeed = item[ii]._iSeed;
cmd.bId = item[ii]._iIdentified;
cmd.bDur = item[ii]._iDurability;
cmd.bMDur = item[ii]._iMaxDur;
cmd.bCh = item[ii]._iCharges;
cmd.bMCh = item[ii]._iMaxCharges;
cmd.wValue = item[ii]._ivalue;
cmd.wPLToHit = item[ii]._iPLToHit;
cmd.wMaxDam = item[ii]._iMaxDam;
cmd.bMinStr = item[ii]._iMinStr;
cmd.bMinMag = item[ii]._iMinMag;
cmd.bMinDex = item[ii]._iMinDex;
cmd.bAC = item[ii]._iAC;
}
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void NetSendCmdGItem2(BOOL usonly,BYTE bCmd,BYTE mast,BYTE pnum,const TCmdGItem * p) {
app_assert(pnum < MAX_PLRS);
app_assert(p != NULL);
TCmdGItem cmd;
//CopyMemory(&cmd,p,sizeof(TCmdGItem));
cmd = *p; // struct copy.
cmd.bCmd = bCmd;
cmd.bPnum = pnum;
cmd.bMaster = mast;
// Should I init the timer?
if (!usonly) {
cmd.dwTime = 0;
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
}
else {
// Have I been sending this back to myself for more than 5 seconds?
DWORD dwCurr = GetTickCount();
if (cmd.dwTime == 0)
cmd.dwTime = dwCurr;
else if ((long) (dwCurr - cmd.dwTime) > RESEND_TIME)
return;
NetSendMyselfPri((BYTE *) &cmd,sizeof(cmd));
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
BOOL NetSendCmdReq2(BYTE bCmd,BYTE mast,BYTE pnum,const TCmdGItem * p) {
app_assert(pnum < MAX_PLRS);
app_assert(p != NULL);
TCmdGItem cmd;
//CopyMemory(&cmd,p,sizeof(TCmdGItem));
cmd = *p; // struct copy.
cmd.bCmd = bCmd;
cmd.bPnum = pnum;
cmd.bMaster = mast;
// Have I been sending this back to myself for more than 5 seconds?
DWORD dwCurr = GetTickCount();
if (cmd.dwTime == 0) // Timer inited in original send
cmd.dwTime = dwCurr;
else if ((long) (dwCurr - cmd.dwTime) > RESEND_TIME)
return(FALSE);
NetSendMyselfPri((BYTE *) &cmd,sizeof(cmd));
return(TRUE);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdExtra(const TCmdGItem * p)
{
app_assert(p != NULL);
TCmdGItem cmd;
//CopyMemory(&cmd,p,sizeof(TCmdGItem));
cmd = *p; // struct copy
cmd.bCmd = CMD_ITEMEXTRA;
cmd.dwTime = 0;
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdPItem(BOOL bHiPri,BYTE bCmd,BYTE x,BYTE y) {
app_assert(x < DMAXX);
app_assert(y < DMAXY);
TCmdPItem cmd;
cmd.bCmd = bCmd;
cmd.x = x;
cmd.y = y;
cmd.wIndx = plr[myplr].HoldItem.IDidx;
if (plr[myplr].HoldItem.IDidx == IDI_EAR) {
cmd.wCI = (plr[myplr].HoldItem._iName[7] << 8) | plr[myplr].HoldItem._iName[8];
cmd.dwSeed = (plr[myplr].HoldItem._iName[9] << 24) |
(plr[myplr].HoldItem._iName[10] << 16) |
(plr[myplr].HoldItem._iName[11] << 8) |
plr[myplr].HoldItem._iName[12];
cmd.bId = plr[myplr].HoldItem._iName[13];
cmd.bDur = plr[myplr].HoldItem._iName[14];
cmd.bMDur = plr[myplr].HoldItem._iName[15];
cmd.bCh = plr[myplr].HoldItem._iName[16];
cmd.bMCh = plr[myplr].HoldItem._iName[17];
cmd.wValue = (plr[myplr].HoldItem._iName[18] << 8) |
((plr[myplr].HoldItem._iCurs - ITEM_EAR1) << 6) |
plr[myplr].HoldItem._ivalue;
cmd.dwBuff = (plr[myplr].HoldItem._iName[19] << 24) |
(plr[myplr].HoldItem._iName[20] << 16) |
(plr[myplr].HoldItem._iName[21] << 8) |
plr[myplr].HoldItem._iName[22];
} else {
cmd.wCI = plr[myplr].HoldItem._iCreateInfo;
cmd.dwSeed = plr[myplr].HoldItem._iSeed;
cmd.bId = plr[myplr].HoldItem._iIdentified;
cmd.bDur = plr[myplr].HoldItem._iDurability;
cmd.bMDur = plr[myplr].HoldItem._iMaxDur;
cmd.bCh = plr[myplr].HoldItem._iCharges;
cmd.bMCh = plr[myplr].HoldItem._iMaxCharges;
cmd.wValue = plr[myplr].HoldItem._ivalue;
cmd.wPLToHit = plr[myplr].HoldItem._iPLToHit;
cmd.wMaxDam = plr[myplr].HoldItem._iMaxDam;
cmd.bMinStr = plr[myplr].HoldItem._iMinStr;
cmd.bMinMag = plr[myplr].HoldItem._iMinMag;
cmd.bMinDex = plr[myplr].HoldItem._iMinDex;
cmd.bAC = plr[myplr].HoldItem._iAC;
}
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdChItem(BOOL bHiPri,BYTE bLoc) {
TCmdChItem cmd;
cmd.bCmd = CMD_CHANGEPLRITEMS;
cmd.bLoc = bLoc;
cmd.wIndx = plr[myplr].HoldItem.IDidx;
cmd.wCI = plr[myplr].HoldItem._iCreateInfo;
cmd.dwSeed = plr[myplr].HoldItem._iSeed;
// drb.patch1.start.02/10/97
cmd.bId = plr[myplr].HoldItem._iIdentified;
// drb.patch1.end.02/10/97
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdDelItem(BOOL bHiPri,BYTE bLoc) {
TCmdDelItem cmd;
cmd.bCmd = CMD_DELPLRITEMS;
cmd.bLoc = bLoc;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdDItem(BOOL bHiPri,int ii) {
app_assert((DWORD)ii < MAXITEMS);
TCmdPItem cmd;
cmd.bCmd = CMD_DROPITEM;
cmd.x = item[ii]._ix;
cmd.y = item[ii]._iy;
cmd.wIndx = item[ii].IDidx;
if (item[ii].IDidx == IDI_EAR) {
cmd.wCI = (item[ii]._iName[7] << 8) | item[ii]._iName[8];
cmd.dwSeed = (item[ii]._iName[9] << 24) |
(item[ii]._iName[10] << 16) |
(item[ii]._iName[11] << 8) |
item[ii]._iName[12];
cmd.bId = item[ii]._iName[13];
cmd.bDur = item[ii]._iName[14];
cmd.bMDur = item[ii]._iName[15];
cmd.bCh = item[ii]._iName[16];
cmd.bMCh = item[ii]._iName[17];
cmd.wValue = (item[ii]._iName[18] << 8) |
((item[ii]._iCurs - ITEM_EAR1) << 6) |
item[ii]._ivalue;
cmd.dwBuff = (item[ii]._iName[19] << 24) |
(item[ii]._iName[20] << 16) |
(item[ii]._iName[21] << 8) |
item[ii]._iName[22];
} else {
cmd.wCI = item[ii]._iCreateInfo;
cmd.dwSeed = item[ii]._iSeed;
cmd.bId = item[ii]._iIdentified;
cmd.bDur = item[ii]._iDurability;
cmd.bMDur = item[ii]._iMaxDur;
cmd.bCh = item[ii]._iCharges;
cmd.bMCh = item[ii]._iMaxCharges;
cmd.wValue = item[ii]._ivalue;
cmd.wPLToHit = item[ii]._iPLToHit;
cmd.wMaxDam = item[ii]._iMaxDam;
cmd.bMinStr = item[ii]._iMinStr;
cmd.bMinMag = item[ii]._iMinMag;
cmd.bMinDex = item[ii]._iMinDex;
cmd.bAC = item[ii]._iAC;
}
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BOOL i_own_level(int nReqLevel) {
// the lowest numbered player on a level is
// responsible for arbitrating disputes.
for (int i = 0; i < MAX_PLRS; i++) {
if (! plr[i].plractive) continue;
if (plr[i]._pLvlChanging) continue;
if (plr[i].plrlevel != nReqLevel) continue;
if (i == myplr && gbBufferMsgs != BUFFER_OFF) continue;
break;
}
return i == myplr;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdDamage(BOOL bHiPri,BYTE bPlr,DWORD dwDam) {
app_assert(bPlr < MAX_PLRS);
TCmdDamage cmd;
cmd.bCmd = CMD_PLRDAMAGE;
cmd.bPlr = bPlr;
cmd.dwDam = dwDam;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendCmdMonstDamage(BOOL bHiPri,WORD wMonst,DWORD dwDam) {
app_assert(wMonst < MAXMONSTERS);
TCmdMonstDamage cmd;
cmd.bCmd = CMD_MONSTDAMAGE;
cmd.wMonst = wMonst;
cmd.dwDam = dwDam;
if (bHiPri)
NetSendHiPri((BYTE *) &cmd,sizeof(cmd));
else
NetSendLoPri((BYTE *) &cmd,sizeof(cmd));
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void NetSendString(DWORD dwSendMask,const char * pszStr) {
app_assert(pszStr);
TCmdString cmd;
DWORD dwStrLen = strlen(pszStr);
app_assert(dwStrLen < sizeof(cmd.str));
cmd.bCmd = CMD_STRING;
strcpy(cmd.str,pszStr);
NetSendMask(
dwSendMask,
(BYTE *) &cmd,
(BYTE) (sizeof(cmd) - sizeof(cmd.str) + dwStrLen + 1)
);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD cmd_string(int pnum,const TCmdString * p) {
app_assert((DWORD)pnum < MAX_PLRS);
app_assert(p != NULL);
DWORD dwStrLen = strlen(p->str);
// don't display messages while buffering or processing
if (gbBufferMsgs == BUFFER_OFF)
plrmsg_add(pnum,p->str);
return sizeof(*p) - sizeof(p->str) + dwStrLen + 1;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void delta_open_portal(
int pnum,
BYTE x,
BYTE y,
BYTE bLevel,
BYTE bLType,
BYTE bSetLvl
) {
app_assert((DWORD)pnum < MAX_PLRS);
app_assert(x < DMAXX);
app_assert(y < DMAXY);
app_assert(bLevel < NUMLEVELS);
sgJunk.portal[pnum].x = x;
sgJunk.portal[pnum].y = y;
sgJunk.portal[pnum].level = bLevel;
sgJunk.portal[pnum].ltype = bLType;
sgJunk.portal[pnum].setlvl = bSetLvl;
sgbDeltaChanged = TRUE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void delta_close_portal(int pnum) {
app_assert((DWORD)pnum < MAX_PLRS);
FillMemory(&sgJunk.portal[pnum],sizeof(sgJunk.portal[pnum]),INIT_VAL);
sgbDeltaChanged = TRUE;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void check_update_plr(int pnum) {
if (gbMaxPlayers == 1) return;
app_assert((DWORD)pnum < MAX_PLRS);
if (pnum != myplr) return;
void TimedUpdatePlayerFile(BOOL bForce);
TimedUpdatePlayerFile(TRUE);
}
// PATCH2.JMM.3/5/97
#define MAX_ADDSTAT 256
#define MAX_LEVEL 51
#define MAX_STAT 750
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
#define CHEATER_DISP_INTERVAL 5
static DWORD sgdwLastCheaterTime = 0;
static void __cdecl IdentifyCheater( LPCSTR szFormat, ... ) {
DWORD dwCurrTime;
char szOut[256];
dwCurrTime = GetTickCount( );
if((dwCurrTime - sgdwLastCheaterTime) < (CHEATER_DISP_INTERVAL*1000))
return;
sgdwLastCheaterTime = dwCurrTime;
va_list args;
va_start(args,szFormat);
vsprintf(szOut,szFormat,args);
va_end(args);
sysmsg_add_string( szOut );
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SYNCDATA( const TCmd* pCmd, int pnum ) {
// sync_update handles gbBufferMsgs
DROPLOG( "CMD_SYNCDATA(%d)\n", pnum );
return sync_update( pnum, (CONST BYTE *) pCmd );
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_WALKXY( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLoc * p = (const TCmdLoc *) pCmd;
DROPLOG("CMD_WALKXY(%d):(%d,%d)\n",pnum,p->x,p->y);
ClrPlrPath(pnum);
MakePlrPath(pnum, p->x, p->y, TRUE);
plr[pnum].destAction = PCMD_NOTHING;
}
return sizeof(TCmdLoc);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ADDSTR( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_ADDSTR(%d)\n",pnum);
// PATCH2.JMM.3/5/97
if(p->wParam1 < 0 || p->wParam1 > MAX_ADDSTAT) {
return sizeof(TCmdParam1);
}
// ENDPATCH2.JMM.3/5/97
ModifyPlrStr(pnum, p->wParam1);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ADDMAG( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_ADDMAG(%d)\n",pnum);
// PATCH2.JMM.3/5/97
if(p->wParam1 < 0 || p->wParam1 > MAX_ADDSTAT) {
return sizeof(TCmdParam1);
}
// ENDPATCH2.JMM.3/5/97
ModifyPlrMag(pnum, p->wParam1);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ADDDEX( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_ADDDEX(%d)\n",pnum);
// PATCH2.JMM.3/5/97
if(p->wParam1 < 0 || p->wParam1 > MAX_ADDSTAT) {
return sizeof(TCmdParam1);
}
// ENDPATCH2.JMM.3/5/97
ModifyPlrDex(pnum, p->wParam1);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ADDVIT( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_ADDVIT(%d)\n",pnum);
// PATCH2.JMM.3/5/97
if(p->wParam1 < 0 || p->wParam1 > MAX_ADDSTAT) {
return sizeof(TCmdParam1);
}
// ENDPATCH2.JMM.3/5/97
ModifyPlrVit(pnum, p->wParam1);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SBSPELL( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_SBSPELL(%d)\n",pnum);
// PATCH2.JMM.3/5/97
UINT nSplType = p->wParam1;
if(currlevel == 0 && !spelldata[nSplType].sTownSpell) {
IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName);
return sizeof(TCmdParam1);
}
// ENDPATCH2.JMM.3/5/97
plr[pnum]._pSpell = p->wParam1;
plr[pnum]._pSplType = plr[pnum]._pSBkSplType;
plr[pnum]._pSplFrom = SPL_FROMBK;
plr[pnum].destAction = PCMD_SPELL;
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_GOTOGETITEM( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd;
DROPLOG("CMD_GOTOGETITEM(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
MakePlrPath(pnum, p->x, p->y, FALSE);
plr[pnum].destAction = PCMD_REQGETITEM;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdLocParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_REQUESTGITEM( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else {
const TCmdGItem * p = (const TCmdGItem *) pCmd;
DROPLOG("CMD_REQUESTGETITEM(%d,%8.8x): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->dwTime,p->wIndx,p->wCI,p->dwSeed,p->x,p->y);
if (i_own_level(plr[pnum].plrlevel)) {
app_assert(currlevel == plr[myplr].plrlevel);
// make sure we don't start resending an item we just picked up.
if( !CheckGetRecord( p->dwSeed, p->wCI, p->wIndx ) )
return sizeof(TCmdGItem);
int ii = FindGetItem(p->wIndx, p->wCI, p->dwSeed);
if (ii != -1) {
DROPLOG(" Item found. FindGetItem returned %d and iDelFlag is FALSE.\n",ii);
NetSendCmdGItem2(FALSE, CMD_GETITEM, myplr, p->bPnum, p);
if (p->bPnum != myplr) {
SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed);
}
else {
InvGetItem(myplr, ii);
}
AddGetRecord( p->dwSeed, p->wCI, p->wIndx );
}
else {
if (ii == -1) {
DROPLOG(" Item not found. Resending.\n");
if (! NetSendCmdReq2(CMD_REQUESTGITEM, myplr, p->bPnum, p)) {
DROPLOG(" Resend expired. Extra Item.\n");
NetSendCmdExtra(p);
}
}
}
}
}
return sizeof(TCmdGItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_GETITEM( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdGItem));
}
else {
const TCmdGItem * p = (const TCmdGItem *) pCmd;
DROPLOG("CMD_GETITEM(%d,%8.8x,%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->dwTime,p->bPnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y);
DROPLOG(" Data: bCmd = %2.2x\n", p->bCmd);
DROPLOG(" Data: bMaster = %2.2x\n",p->bMaster);
DROPLOG(" Data: bPnum = %2.2x\n",p->bPnum);
DROPLOG(" Data: bCursitem = %2.2x\n",p->bCursitem);
DROPLOG(" Data: bLevel = %2.2x\n",p->bLevel);
DROPLOG(" Data: x = %2.2x\n",p->x);
DROPLOG(" Data: y = %2.2x\n",p->y);
DROPLOG(" Data: wIndx = %4.4x\n",p->wIndx);
DROPLOG(" Data: wCI = %4.4x\n",p->wCI);
DROPLOG(" Data: dwSeed = %8.8x\n",p->dwSeed);
DROPLOG(" Data: bID = %2.2x\n",p->bId);
DROPLOG(" Data: bDur = %2.2x\n",p->bDur);
DROPLOG(" Data: bMDur = %2.2x\n",p->bMDur);
DROPLOG(" Data: bCh = %2.2x\n",p->bCh);
DROPLOG(" Data: bMCh = %2.2x\n",p->bMCh);
DROPLOG(" Data: wValue = %4.4x\n",p->wValue);
DROPLOG(" Data: dwBuff = %8.8x\n",p->dwBuff);
DROPLOG(" Data: dwTime = %8.8x\n",p->dwTime);
int nIndex = FindGetItem( p->wIndx, p->wCI, p->dwSeed );
// Check if in the delta table
DROPLOG(" Looking in delta tbl[%d]\n",p->bLevel);
//if (delta_get_item(p, plr[pnum].plrlevel) && (nIndex != -1)) {
if (delta_get_item(p, p->bLevel)) {
// Found in delta
DROPLOG(" Found in delta tbl.\n");
//if (currlevel == plr[pnum].plrlevel) {
if ((currlevel == p->bLevel) || (p->bPnum == myplr)) {
if (p->bMaster == myplr) {
// item has already been picked up
DROPLOG(" Item already picked up.\n");
}
else if (p->bPnum == myplr) {
if (currlevel != p->bLevel) {
int hitem = SyncPutItem(myplr,
plr[myplr]._px,
plr[myplr]._py,
p->wIndx,
p->wCI,
p->dwSeed,
p->bId,
p->bDur,
p->bMDur,
p->bCh,
p->bMCh,
p->wValue,
p->dwBuff,
p->wPLToHit,
p->wMaxDam,
p->bMinStr,
p->bMinMag,
p->bMinDex,
p->bAC );
if (hitem != -1) InvGetItem(myplr, hitem);
} else
InvGetItem(myplr, nIndex);
DROPLOG(" Local player got item.\n");
}
else {
SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed);
DROPLOG(" Remote player (%d) got item.\n",p->bPnum);
}
}
}
else {
// Not found, so let's send it to ourselves again
DROPLOG(" Not found in delta tbl. Resending...\n");
NetSendCmdGItem2(TRUE, CMD_GETITEM, p->bMaster, p->bPnum, p);
}
}
return sizeof(TCmdGItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_GOTOAGETITEM( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd;
DROPLOG("CMD_GOTOAUTOGETITEM(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
MakePlrPath(pnum, p->x, p->y, FALSE);
plr[pnum].destAction = PCMD_REQAGETITEM;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdLocParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_REQUESTAGITEM( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else {
const TCmdGItem * p = (const TCmdGItem *) pCmd;
DROPLOG("CMD_REQUESTAUTOGETITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y);
if (i_own_level(plr[pnum].plrlevel)) {
app_assert(currlevel == plr[myplr].plrlevel);
// make sure we don't start resending an item we just picked up.
if( !CheckGetRecord( p->dwSeed, p->wCI, p->wIndx ) )
return sizeof(TCmdGItem);
int ii = FindGetItem(p->wIndx, p->wCI, p->dwSeed);
if (ii != -1) {
NetSendCmdGItem2(FALSE, CMD_AGETITEM, myplr, p->bPnum, p);
DROPLOG(" Item found.\n");
if (p->bPnum != myplr) SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed);
else AutoGetItem(myplr, p->bCursitem);
// PATCH1.JMM
AddGetRecord( p->dwSeed, p->wCI, p->wIndx );
// ENDPATCH1.JMM
} else {
if (ii == -1) {
DROPLOG(" Item not found. Resending.\n");
if (! NetSendCmdReq2(CMD_REQUESTAGITEM, myplr, p->bPnum, p)) {
DROPLOG(" Resend expired. Extra Item.\n");
NetSendCmdExtra(p);
}
}
}
}
}
return sizeof(TCmdGItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_AGETITEM( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdGItem));
}
else {
const TCmdGItem * p = (const TCmdGItem *) pCmd;
// PATCH1.JMM
DROPLOG("CMD_AUTOGETITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y);
DROPLOG(" Data: bCmd = %2.2x\n", p->bCmd);
DROPLOG(" Data: bMaster = %2.2x\n",p->bMaster);
DROPLOG(" Data: bPnum = %2.2x\n",p->bPnum);
DROPLOG(" Data: bCursitem = %2.2x\n",p->bCursitem);
DROPLOG(" Data: bLevel = %2.2x\n",p->bLevel);
DROPLOG(" Data: x = %2.2x\n",p->x);
DROPLOG(" Data: y = %2.2x\n",p->y);
DROPLOG(" Data: wIndx = %4.4x\n",p->wIndx);
DROPLOG(" Data: wCI = %4.4x\n",p->wCI);
DROPLOG(" Data: dwSeed = %8.8x\n",p->dwSeed);
DROPLOG(" Data: bID = %2.2x\n",p->bId);
DROPLOG(" Data: bDur = %2.2x\n",p->bDur);
DROPLOG(" Data: bMDur = %2.2x\n",p->bMDur);
DROPLOG(" Data: bCh = %2.2x\n",p->bCh);
DROPLOG(" Data: bMCh = %2.2x\n",p->bMCh);
DROPLOG(" Data: wValue = %4.4x\n",p->wValue);
DROPLOG(" Data: dwBuff = %8.8x\n",p->dwBuff);
DROPLOG(" Data: dwTime = %8.8x\n",p->dwTime);
int nIndex = FindGetItem( p->wIndx, p->wCI, p->dwSeed );
// ENDPATCH1.JMM
// Check if in the delta table
// drb.patch1.start.2/05/97
//if (delta_get_item(p, plr[pnum].plrlevel)) {
DROPLOG(" Looking in delta tbl[%d]\n",p->bLevel);
if (delta_get_item(p, p->bLevel)) {
// drb.patch1.end.2/05/97
// Found in delta
DROPLOG(" Found in delta tbl.\n");
// PATCH1.JMM
//if (currlevel == plr[pnum].plrlevel) {
if ((currlevel == p->bLevel) || (p->bPnum == myplr)) {
// ENDPATCH1.JMM
if (p->bMaster == myplr) {
// item already picked up
DROPLOG(" Item already picked up.\n");
}
else if (p->bPnum == myplr) {
// drb.patch1.start.02/14/97
// This is the biggest kludge I have ever written.
// I am so ashamed, but it will work
if (currlevel != p->bLevel) {
int hitem = SyncPutItem(myplr,
plr[myplr]._px,
plr[myplr]._py,
p->wIndx,
p->wCI,
p->dwSeed,
p->bId,
p->bDur,
p->bMDur,
p->bCh,
p->bMCh,
p->wValue,
p->dwBuff,
p->wPLToHit,
p->wMaxDam,
p->bMinStr,
p->bMinMag,
p->bMinDex,
p->bAC );
if (hitem != -1) AutoGetItem(myplr, hitem);
} else
AutoGetItem(myplr, p->bCursitem);
// drb.patch1.end.02.14/97
DROPLOG(" Local player got item.\n");
}
else {
SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed);
DROPLOG(" Remote player (%d) got item.\n",p->bPnum);
}
}
}
else {
// Not found, so let's send it to ourselves again
NetSendCmdGItem2(TRUE, CMD_AGETITEM, p->bMaster, p->bPnum, p);
DROPLOG(" Not found in delta tbl. Resending...\n");
}
}
return sizeof(TCmdGItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ITEMEXTRA( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdGItem));
}
else {
const TCmdGItem * p = (const TCmdGItem *) pCmd;
DROPLOG("CMD_ITEMEXTRA(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y);
// Check if in the delta table
// drb.patch1.start.2/05/97
//delta_get_item(p, plr[p->bPnum].plrlevel);
DROPLOG(" Looking in delta tbl[%d]\n",p->bLevel);
delta_get_item(p, p->bLevel);
if (currlevel == plr[pnum].plrlevel) {
//if (currlevel == p->bLevel) {
// drb.patch1.end.2/05/97
SyncGetItem(p->x, p->y, p->wIndx, p->wCI, p->dwSeed);
}
}
return sizeof(TCmdGItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_PUTITEM( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdPItem));
}
else {
const TCmdPItem * p = (const TCmdPItem *) pCmd;
DROPLOG("CMD_PUTITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y);
if (currlevel == plr[pnum].plrlevel) {
DROPLOG(" Item on my level.\n");
int ii;
if (pnum == myplr) {
ii = InvPutItem(pnum, p->x, p->y);
}
else {
ii = SyncPutItem(pnum,
p->x,
p->y,
p->wIndx,
p->wCI,
p->dwSeed,
p->bId,
p->bDur,
p->bMDur,
p->bCh,
p->bMCh,
p->wValue,
p->dwBuff,
p->wPLToHit,
p->wMaxDam,
p->bMinStr,
p->bMinMag,
p->bMinDex,
p->bAC );
}
if (ii != -1) {
DROPLOG(" Put successful. Putting item into delta...\n");
RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx );
DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel);
delta_put_item(p,item[ii]._ix,item[ii]._iy,plr[pnum].plrlevel);
check_update_plr(pnum);
}
else {
DROPLOG(" Put unsuccessful.\n");
}
return sizeof(TCmdPItem);
}
RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx );
DROPLOG(" Item not on my level. Adding to delta...\n");
DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel);
delta_put_item(p, p->x, p->y, plr[pnum].plrlevel);
check_update_plr(pnum);
}
return sizeof(TCmdPItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SYNCPUTITEM( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdPItem));
}
else {
const TCmdPItem * p = (const TCmdPItem *) pCmd;
DROPLOG("CMD_SYNCPUTITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y);
if (currlevel == plr[pnum].plrlevel) {
DROPLOG(" Item on my level.\n");
int ii = SyncPutItem(pnum,
p->x,
p->y,
p->wIndx,
p->wCI,
p->dwSeed,
p->bId,
p->bDur,
p->bMDur,
p->bCh,
p->bMCh,
p->wValue,
p->dwBuff,
p->wPLToHit,
p->wMaxDam,
p->bMinStr,
p->bMinMag,
p->bMinDex,
p->bAC );
if (ii != -1) {
RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx );
DROPLOG(" Put successful. Putting item into delta...\n");
delta_put_item(p,item[ii]._ix,item[ii]._iy,plr[pnum].plrlevel);
DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel);
check_update_plr(pnum);
}
else {
DROPLOG(" Put unsuccessful.\n");
}
return sizeof(TCmdPItem);
}
RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx );
DROPLOG(" Item not on my level. Adding to delta...\n");
delta_put_item(p, p->x, p->y, plr[pnum].plrlevel);
DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel);
check_update_plr(pnum);
}
return sizeof(TCmdPItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_RESPAWNITEM( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdPItem));
}
else {
const TCmdPItem * p = (const TCmdPItem *) pCmd;
DROPLOG("CMD_RESPAWNITEM(%d): index->0x%8.8x ci->0x%8.8x seed->0x%8.8x xy->(%d,%d)\n",pnum,p->wIndx,p->wCI,p->dwSeed,p->x,p->y);
if ((currlevel == plr[pnum].plrlevel) && (pnum != myplr)) {
DROPLOG(" SyncPutting into level.\n");
int ii = SyncPutItem(pnum,
p->x,
p->y,
p->wIndx,
p->wCI,
p->dwSeed,
p->bId,
p->bDur,
p->bMDur,
p->bCh,
p->bMCh,
p->wValue,
p->dwBuff,
p->wPLToHit,
p->wMaxDam,
p->bMinStr,
p->bMinMag,
p->bMinDex,
p->bAC );
}
RemoveGetRecord( p->dwSeed, p->wCI, p->wIndx );
DROPLOG(" Adding to delta...\n");
delta_put_item(p, p->x, p->y, plr[pnum].plrlevel);
DROPLOG(" Dropping into delta tbl[%d]\n",plr[pnum].plrlevel);
}
return sizeof(TCmdPItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ATTACKXY( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLoc * p = (const TCmdLoc *) pCmd;
DROPLOG("CMD_ATTACKXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
MakePlrPath(pnum, p->x, p->y, FALSE);
plr[pnum].destAction = PCMD_ATTACK;
plr[pnum].destParam1 = p->x;
plr[pnum].destParam2 = p->y;
}
return sizeof(TCmdLoc);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SATTACKXY( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLoc * p = (const TCmdLoc *) pCmd;
DROPLOG("CMD_SATTACKXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_ATTACK;
plr[pnum].destParam1 = p->x;
plr[pnum].destParam2 = p->y;
}
return sizeof(TCmdLoc);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_RATTACKXY( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLoc * p = (const TCmdLoc *) pCmd;
DROPLOG("CMD_RATTACKXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_RATTACK;
plr[pnum].destParam1 = p->x;
plr[pnum].destParam2 = p->y;
}
return sizeof(TCmdLoc);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SPELLXYD( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLocParam3 * p = (const TCmdLocParam3 *) pCmd;
DROPLOG("CMD_SPELLXYD(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
// PATCH2.JMM.3/5/97
UINT nSplType = p->wParam1;
if(currlevel == 0 && !spelldata[nSplType].sTownSpell) {
IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName);
return sizeof(TCmdLocParam3);
}
// ENDPATCH2.JMM.3/5/97
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_SPELLXYD;
plr[pnum].destParam1 = p->x;
plr[pnum].destParam2 = p->y;
plr[pnum].destParam3 = p->wParam2;
plr[pnum].destParam4 = p->wParam3;
plr[pnum]._pSpell = p->wParam1;
plr[pnum]._pSplType = plr[pnum]._pRSplType;
plr[pnum]._pSplFrom = SPL_FROMR;
}
return sizeof(TCmdLocParam3);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SPELLXY( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLocParam2 * p = (const TCmdLocParam2 *) pCmd;
DROPLOG("CMD_SPELLXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
// PATCH2.JMM.3/5/97
UINT nSplType = p->wParam1;
if(currlevel == 0 && !spelldata[nSplType].sTownSpell) {
IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName);
return sizeof(TCmdLocParam2);
}
// ENDPATCH2.JMM.3/5/97
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_SPELL;
plr[pnum].destParam1 = p->x;
plr[pnum].destParam2 = p->y;
plr[pnum].destParam3 = p->wParam2;
plr[pnum]._pSpell = p->wParam1;
plr[pnum]._pSplType = plr[pnum]._pRSplType;
plr[pnum]._pSplFrom = SPL_FROMR;
}
return sizeof(TCmdLocParam2);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_TSPELLXY( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLocParam2 * p = (const TCmdLocParam2 *) pCmd;
DROPLOG("CMD_TSPELLXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
// PATCH2.JMM.3/5/97
UINT nSplType = p->wParam1;
if(currlevel == 0 && !spelldata[nSplType].sTownSpell) {
IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName);
return sizeof(TCmdLocParam2);
}
// ENDPATCH2.JMM.3/5/97
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_SPELL;
plr[pnum].destParam1 = p->x;
plr[pnum].destParam2 = p->y;
plr[pnum].destParam3 = p->wParam2;
plr[pnum]._pSpell = p->wParam1;
plr[pnum]._pSplType = plr[pnum]._pTSplType;
plr[pnum]._pSplFrom = SPL_FROMT;
}
return sizeof(TCmdLocParam2);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_OPOBJXY( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd;
DROPLOG("CMD_OPOBJXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
if (!object[p->wParam1]._oSolidFlag && !object[p->wParam1]._oDoorFlag)
MakePlrPath(pnum, p->x, p->y, TRUE);
else
MakePlrPath(pnum, p->x, p->y, FALSE);
plr[pnum].destAction = PCMD_OPOBJ;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdLocParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_DISARMXY( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd;
DROPLOG("CMD_DISARMXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
if (!object[p->wParam1]._oSolidFlag && !object[p->wParam1]._oDoorFlag)
MakePlrPath(pnum, p->x, p->y, TRUE);
else
MakePlrPath(pnum, p->x, p->y, FALSE);
plr[pnum].destAction = PCMD_DISARM;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdLocParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_OPOBJT( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_OPOBJT(%d)\n",pnum);
plr[pnum].destAction = PCMD_TELEK;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ATTACKID( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_ATTACKID(%d): id->%d\n",pnum,p->wParam1);
int dx = abs(plr[pnum]._px - monster[p->wParam1]._mfutx);
int dy = abs(plr[pnum]._py - monster[p->wParam1]._mfuty);
if ((dx > 1) || (dy > 1))
MakePlrPath(pnum, monster[p->wParam1]._mfutx, monster[p->wParam1]._mfuty, FALSE);
plr[pnum].destAction = PCMD_ATTACKID;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ATTACKPID( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_ATTACKPID(%d): id->%d\n",pnum,p->wParam1);
MakePlrPath(pnum, plr[p->wParam1]._pfutx, plr[p->wParam1]._pfuty, FALSE);
plr[pnum].destAction = PCMD_ATTACKPID;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_RATTACKID( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_RATTACKID(%d): id->%d\n",pnum,p->wParam1);
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_RATTACKID;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_RATTACKPID( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_RATTACKPID(%d): id->%d\n",pnum,p->wParam1);
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_RATTACKPID;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SPELLID( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam3 * p = (const TCmdParam3 *) pCmd;
DROPLOG("CMD_SPELLID(%d): id->%d\n",pnum,p->wParam1);
// PATCH2.JMM.3/5/97
UINT nSplType = p->wParam2;
if(currlevel == 0 && !spelldata[nSplType].sTownSpell) {
IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName);
return sizeof(TCmdParam3);
}
// ENDPATCH2.JMM.3/5/97
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_SPELLID;
plr[pnum].destParam1 = p->wParam1;
plr[pnum].destParam2 = p->wParam3;
plr[pnum]._pSpell = p->wParam2;
plr[pnum]._pSplType = plr[pnum]._pRSplType;
plr[pnum]._pSplFrom = SPL_FROMR;
}
return sizeof(TCmdParam3);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SPELLPID( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam3 * p = (const TCmdParam3 *) pCmd;
DROPLOG("CMD_SPELLPID(%d): id->%d\n",pnum,p->wParam1);
// PATCH2.JMM.3/5/97
UINT nSplType = p->wParam2;
if(currlevel == 0 && !spelldata[nSplType].sTownSpell) {
IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName);
return sizeof(TCmdParam3);
}
// ENDPATCH2.JMM.3/5/97
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_SPELLPID;
plr[pnum].destParam1 = p->wParam1;
plr[pnum].destParam2 = p->wParam3;
plr[pnum]._pSpell = p->wParam2;
plr[pnum]._pSplType = plr[pnum]._pRSplType;
plr[pnum]._pSplFrom = SPL_FROMR;
}
return sizeof(TCmdParam3);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_TSPELLID( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam3 * p = (const TCmdParam3 *) pCmd;
DROPLOG("CMD_TSPELLID(%d): id->%d\n",pnum,p->wParam1);
// PATCH2.JMM.3/5/97
UINT nSplType = p->wParam2;
if(currlevel == 0 && !spelldata[nSplType].sTownSpell) {
IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName);
return sizeof(TCmdParam3);
}
// ENDPATCH2.JMM.3/5/97
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_SPELLID;
plr[pnum].destParam1 = p->wParam1;
plr[pnum].destParam2 = p->wParam3;
plr[pnum]._pSpell = p->wParam2;
plr[pnum]._pSplType = plr[pnum]._pTSplType;
plr[pnum]._pSplFrom = SPL_FROMT;
}
return sizeof(TCmdParam3);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_TSPELLPID( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam3 * p = (const TCmdParam3 *) pCmd;
DROPLOG("CMD_TSPELLPID(%d): id->%d\n",pnum,p->wParam1);
// PATCH2.JMM.3/5/97
UINT nSplType = p->wParam2;
if(currlevel == 0 && !spelldata[nSplType].sTownSpell) {
IdentifyCheater("%s has cast an illegal spell.",plr[pnum]._pName);
return sizeof(TCmdParam3);
}
// ENDPATCH2.JMM.3/5/97
ClrPlrPath(pnum);
plr[pnum].destAction = PCMD_SPELLPID;
plr[pnum].destParam1 = p->wParam1;
plr[pnum].destParam2 = p->wParam3;
plr[pnum]._pSpell = p->wParam2;
plr[pnum]._pSplType = plr[pnum]._pTSplType;
plr[pnum]._pSplFrom = SPL_FROMT;
}
return sizeof(TCmdParam3);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_KNOCKBACK( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_KNOCKBACK(%d): id->%d\n",pnum,p->wParam1);
if (currlevel == plr[pnum].plrlevel) {
M_GetKnockback(p->wParam1);
M_StartHit(p->wParam1, pnum, 0);
}
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_RESURRECT( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_RESURRECT(%d): id->%d\n",pnum,p->wParam1);
DoResurrect(pnum, p->wParam1);
// update character file to prevent cheating
check_update_plr(pnum);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_HEALOTHER( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_HEALOTHER(%d): id->%d\n",pnum,p->wParam1);
DoHealOther(pnum, p->wParam1);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_TALKXY( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else if (currlevel == plr[pnum].plrlevel) {
const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd;
DROPLOG("CMD_TALKXY(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
MakePlrPath(pnum, p->x, p->y, FALSE);
plr[pnum].destAction = PCMD_TALK;
plr[pnum].destParam1 = p->wParam1;
}
return sizeof(TCmdLocParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_NEWLVL( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam2));
}
else if (pnum != myplr) {
const TCmdParam2 * p = (const TCmdParam2 *) pCmd;
DROPLOG("CMD_NEWLVL(%d)\n",pnum);
StartNewLvl(pnum,p->wParam1,p->wParam2);
}
return sizeof(TCmdParam2);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_WARP( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_WARP(%d)\n",pnum);
StartWarpLvl(pnum, p->wParam1);
// drb.patch1.start.02/15/97
if ((pnum == myplr) && (curs >= ICSTART)) {
item[TEMPAVAIL] = plr[myplr].HoldItem;
AutoGetItem(myplr, TEMPAVAIL);
}
// drb.patch1.end.02/15/97
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_MONSTDEATH( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdLocParam1));
}
else if (pnum != myplr) {
const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd;
DROPLOG("CMD_MONSTDEATH(%d): id->%d xy->(%d,%d)\n",pnum,p->wParam1,p->x,p->y);
if (currlevel == plr[pnum].plrlevel)
M_SyncStartKill(p->wParam1, p->x, p->y, pnum);
delta_kill_monster(p->wParam1, p->x, p->y,plr[pnum].plrlevel);
}
return sizeof(TCmdLocParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_KILLGOLEM( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdLocParam1));
}
else if (pnum != myplr) {
const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd;
DROPLOG("CMD_KILLGOLEM(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
if (currlevel == p->wParam1)
M_SyncStartKill(pnum, p->x, p->y, pnum);
delta_kill_monster(pnum, p->x, p->y, plr[pnum].plrlevel);
}
return sizeof(TCmdLocParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_AWAKEGOLEM( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON)
mega_add_data(pnum, pCmd, sizeof(TCmdGolem));
else {
DROPLOG("CMD_AWAKENGOLEM(%d)\n",pnum);
if (currlevel != plr[pnum].plrlevel)
delta_sync_golem((const TCmdGolem *) pCmd, pnum, ((const TCmdGolem *) pCmd)->_currlevel);
else {
if (pnum != myplr) {
BOOL addok = TRUE;
for (int i = 0; i < nummissiles; i++) {
int mi = missileactive[i];
if ((missile[mi]._mitype == MIT_GOLEM) && (missile[mi]._misource == pnum)) addok = FALSE;
}
const TCmdGolem * pG = (const TCmdGolem *) pCmd;
if (addok) AddMissile(plr[pnum]._px, plr[pnum]._py, pG->_mx, pG->_my, pG->_mdir, MIT_GOLEM, MI_ENEMYMONST, pnum, 0, 1);
}
}
}
return sizeof(TCmdGolem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_MONSTDAMAGE( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam2));
}
else if (pnum != myplr) {
const TCmdMonstDamage * p = (const TCmdMonstDamage *) pCmd;
DROPLOG("CMD_MONSTDAMAGE(%d): id->%d\n",pnum,p->wMonst);
if (currlevel == plr[pnum].plrlevel) {
monster[p->wMonst].mWhoHit |= (1 << pnum);
if (monster[p->wMonst]._mhitpoints >= 0) {
monster[p->wMonst]._mhitpoints -= p->dwDam;
// take damage but don't kill him
if ((monster[p->wMonst]._mhitpoints >> HP_SHIFT) < 1)
monster[p->wMonst]._mhitpoints = 1 << HP_SHIFT;
delta_monster_hp(p->wMonst,monster[p->wMonst]._mhitpoints,plr[pnum].plrlevel);
}
}
else {
// @@@@ Dave -- need some way to calculate new monster hp
// since we don't have its info handy
}
}
return sizeof(TCmdMonstDamage);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_PLRDEAD( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else if (pnum != myplr) {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_PLAYERDEAD(%d): id->%d\n",pnum,p->wParam1);
SyncPlrKill(pnum, p->wParam1);
}
else {
DROPLOG("CMD_PLAYERDEAD(I'm dead!!!)\n",pnum);
check_update_plr(pnum);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_PLRDAMAGE( const TCmd* pCmd, int pnum ) {
app_assert(gbBufferMsgs != BUFFER_PROCESS);
const TCmdDamage * p = (const TCmdDamage *) pCmd;
DROPLOG("CMD_PLAYERDAMAGE(%d)\n",pnum);
if (p->bPlr != myplr) {
// ignore message
}
// JMM.PATCH1
else if (currlevel == 0) {
// illegal message!
}
// JMM.ENDPATCH1
else if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered, because
// the player isn't active yet, so he
// can't be taking any damage
}
// PATCH2.JMM.3/5/97
else if (currlevel != plr[pnum].plrlevel) {
// illegal message! (player must be on same level)
}
else if ( p->dwDam > (3000<<HP_SHIFT)) {
// illegal message!
}
// ENDPATCH2
else {
DROPLOG(" I'm taking damage.\n");
DROPLOG(" Current level->%d\n",currlevel);
// If I am already dead, don't kill me again.
if ((plr[myplr]._pHitPoints >> HP_SHIFT) > 0) {
// not dead yet
drawhpflag = TRUE;
plr[myplr]._pHitPoints -= p->dwDam;
plr[myplr]._pHPBase -= p->dwDam;
if (plr[myplr]._pHitPoints > plr[myplr]._pMaxHP) {
plr[myplr]._pHitPoints = plr[myplr]._pMaxHP;
plr[myplr]._pHPBase = plr[myplr]._pMaxHPBase;
}
if ((plr[myplr]._pHitPoints >> HP_SHIFT) <= 0) {
// rjs - manashld fix? - plr[myplr]._pHitPoints = 0;
StartPlrKill(myplr, TRUE);
}
}
}
return sizeof(TCmdDamage);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_OPENDOOR( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_OPENDOOR(%d): id->%d\n",pnum,p->wParam1);
if (currlevel == plr[pnum].plrlevel)
SyncOpObject(pnum, CMD_OPENDOOR, p->wParam1);
delta_sync_object(p->wParam1,CMD_OPENDOOR,plr[pnum].plrlevel);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**----------------------------------------------------------------------*/
static DWORD On_CLOSEDOOR( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_CLOSEDOOR(%d): id->%d\n",pnum,p->wParam1);
if (currlevel == plr[pnum].plrlevel)
SyncOpObject(pnum, CMD_CLOSEDOOR, p->wParam1);
delta_sync_object(p->wParam1,CMD_CLOSEDOOR,plr[pnum].plrlevel);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_OPERATEOBJ( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_OPERATEOBJ(%d): id->%d\n",pnum,p->wParam1);
if (currlevel == plr[pnum].plrlevel)
SyncOpObject(pnum, CMD_OPERATEOBJ, p->wParam1);
delta_sync_object(p->wParam1,CMD_OPERATEOBJ,plr[pnum].plrlevel);
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_PLROPOBJ( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam2));
}
else {
const TCmdParam2 * p = (const TCmdParam2 *) pCmd;
DROPLOG("CMD_PLAYEROPOBJ(%d): plrid->%d objid->%d\n",pnum,p->wParam1,p->wParam2);
if (currlevel == plr[pnum].plrlevel)
SyncOpObject(p->wParam1, CMD_PLROPOBJ, p->wParam2);
delta_sync_object(p->wParam2,CMD_PLROPOBJ,plr[pnum].plrlevel);
}
return sizeof(TCmdParam2);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_BREAKOBJ( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam2));
}
else {
const TCmdParam2 * p = (const TCmdParam2 *) pCmd;
DROPLOG("CMD_BREAKOBJ(%d): id1->%d id2->%d\n",pnum,p->wParam1,p->wParam2);
if (currlevel == plr[pnum].plrlevel)
SyncBreakObj(p->wParam1, p->wParam2);
delta_sync_object(p->wParam2,CMD_BREAKOBJ,plr[pnum].plrlevel);
}
return sizeof(TCmdParam2);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_CHANGEPLRITEMS( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdChItem));
}
else {
const TCmdChItem * p = (const TCmdChItem *) pCmd;
DROPLOG("CMD_CHANGEPLAYERITEMS(%d): index->%8.8x ci->%8.8x seed->%8.8x\n",pnum,p->wIndx, p->wCI, p->dwSeed);
// drb.patch1.start.02/10/97
// if (pnum != myplr) SyncInvPaste(pnum, p->bLoc, p->wIndx, p->wCI, p->dwSeed);
if (pnum != myplr) SyncInvPaste(pnum, p->bLoc, p->wIndx, p->wCI, p->dwSeed, p->bId);
// drb.patch1.end.02/10/97
}
return sizeof(TCmdChItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_DELPLRITEMS( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdDelItem));
}
else {
const TCmdDelItem * p = (const TCmdDelItem *) pCmd;
DROPLOG("CMD_DELPLAYERITEMS(%d): loc->%d\n",pnum, p->bLoc);
if (pnum != myplr) SyncInvCut(pnum, p->bLoc);
}
return sizeof(TCmdDelItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_PLRLEVEL( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_PLAYERLEVEL(%d)\n",pnum);
if ((p->wParam1 <= MAX_LEVEL) && pnum != myplr)
plr[pnum]._pLevel = (char) p->wParam1;
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_DROPITEM( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdPItem));
}
else {
// item dropped by a dead monster/chest/etc.
// doesn't have to do anything to level data
// only to delta info
const TCmdPItem * p = (const TCmdPItem *) pCmd;
DROPLOG("CMD_DROPITEM(%d): index->%8.8x ci->%8.8x seed->%8.8x xy->(%d,%d)\n",pnum,p->wIndx, p->wCI, p->dwSeed, p->x, p->y);
delta_put_item(p,p->x,p->y,plr[pnum].plrlevel);
}
return sizeof(TCmdPItem);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SEND_PLRINFO( const TCmd* pCmd, int pnum ) {
const TCmdPlrInfoHdr * p = (const TCmdPlrInfoHdr *) pCmd;
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,p,p->wBytes + sizeof(TCmdPlrInfoHdr));
}
else {
DROPLOG("CMD_ACK\\SENDPLRINFO(%d)\n",pnum);
recv_plrinfo(pnum,p,p->bCmd == CMD_ACK_PLRINFO);
}
return p->wBytes + sizeof(TCmdPlrInfoHdr);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ACK_PLRINFO( const TCmd* pCmd, int pnum ) {
return On_SEND_PLRINFO( pCmd, pnum );
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_PLAYER_JOINLEVEL( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdLocParam1));
}
else {
app_assert((DWORD)pnum < MAX_PLRS);
DROPLOG("CMD_PLAYERJOINLEVEL(%d)\n",pnum);
plr[pnum]._pLvlChanging = FALSE;
// joining game?
if (! plr[pnum]._pName[0]) {
// we are probably unbuffering messages,
// and we received this message before we
// received the message that tells us who
// this player is. Just ignore this message.
// Eventually we will get a PLRINFO message
// which will activate this player
#if TRACEOUT
TraceOut("(%d) received %d joinlevel before plrdata",myplr,pnum);
#endif
}
else if (! plr[pnum].plractive) {
plr[pnum].plractive = 1;
gbActivePlayers++;
sysmsg_add("Player '%s' (level %d) just joined the game",plr[pnum]._pName,plr[pnum]._pLevel);
#if TRACEOUT
TraceOut("(%d) activating %d on joinlevel",myplr,pnum);
#endif
}
// activate player on this level
if (plr[pnum].plractive && myplr != pnum) {
const TCmdLocParam1 * p = (const TCmdLocParam1 *) pCmd;
plr[pnum]._px = p->x;
plr[pnum]._py = p->y;
plr[pnum].plrlevel = p->wParam1;
plr[pnum]._pGFXLoad = 0;
if (currlevel == plr[pnum].plrlevel) {
LoadPlrGFX(pnum,PGL_STAND);
SyncInitPlr(pnum);
if ((plr[pnum]._pHitPoints >> HP_SHIFT) > 0) {
StartStand(pnum,0);
} else {
plr[pnum]._pgfxnum = PGFX_NGUY;
LoadPlrGFX(pnum, PGL_DEAD);
plr[pnum]._pmode = PM_DEATH;
NewPlrAnim(pnum, plr[pnum]._pDAnim[DIR_D], plr[pnum]._pDFrames, 1, plr[pnum]._pDWidth);
plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen - 1;
plr[pnum]._pVar8 = plr[pnum]._pAnimLen << 1;
dFlags[plr[pnum]._px][plr[pnum]._py] |= BFLAG_DEADPLR;
}
plr[pnum]._pvid = AddVision(plr[pnum]._px, plr[pnum]._py,
plr[pnum]._pLightRad, pnum==myplr);
plr[pnum]._plid = -1;
}
}
}
return sizeof(TCmdLocParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ACTIVATEPORTAL( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdLocParam3));
}
else {
const TCmdLocParam3 * p = (const TCmdLocParam3 *) pCmd;
DROPLOG("CMD_ACTIVATEPORTAL(%d): xy->(%d,%d)\n",pnum,p->x,p->y);
ActivatePortal(pnum, p->x, p->y, p->wParam1, p->wParam2, p->wParam3);
if (pnum != myplr) {
if (currlevel == 0) {
AddInTownPortal(pnum);
} else {
if (currlevel == plr[pnum].plrlevel) {
// If on same level make sure portal appears
int i,mi;
BOOL addok = TRUE;
for (i = 0; i < nummissiles; i++) {
mi = missileactive[i];
if ((missile[mi]._mitype == MIT_TOWN) && (missile[mi]._misource == pnum)) addok = FALSE;
}
if (addok) AddWarpMissile(pnum, p->x, p->y);
} else {
// Remove portal if it was on my level before
RemovePortalMissile(pnum);
}
}
}
delta_open_portal(pnum,p->x,p->y,(BYTE) p->wParam1,(BYTE) p->wParam2, (BYTE) p->wParam3);
}
return sizeof(TCmdLocParam3);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_DEACTIVATEPORTAL( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmd));
}
else {
DROPLOG("CMD_DEACTIVEPORTAL(%d)\n",pnum);
if (PortalOnLevel(pnum)) RemovePortalMissile(pnum);
DeactivatePortal(pnum);
delta_close_portal(pnum);
}
return sizeof(TCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_RETOWN( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmd));
}
else {
DROPLOG("CMD_RETOWN(%d)\n",pnum);
if (pnum == myplr) {
deathflag = FALSE;
gamemenu_off();
}
RestartTownLvl(pnum);
}
return sizeof(TCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SETSTR( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_SETSTR(%d)\n",pnum);
if( p->wParam1 > MAX_STAT )
return sizeof( TCmdParam1 );
if (pnum != myplr) {
SetPlrStr(pnum, p->wParam1);
}
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SETDEX( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_SETDEX(%d)\n",pnum);
if( p->wParam1 > MAX_STAT )
return sizeof( TCmdParam1 );
if (pnum != myplr) {
SetPlrDex(pnum, p->wParam1);
}
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SETMAG( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_SETMAG(%d)\n",pnum);
if( p->wParam1 > MAX_STAT )
return sizeof( TCmdParam1 );
if (pnum != myplr) {
SetPlrMag(pnum, p->wParam1);
}
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SETVIT( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdParam1));
}
else {
const TCmdParam1 * p = (const TCmdParam1 *) pCmd;
DROPLOG("CMD_SETVIT(%d)\n",pnum);
if( p->wParam1 > MAX_STAT )
return sizeof( TCmdParam1 );
if (pnum != myplr) {
SetPlrVit(pnum, p->wParam1);
}
}
return sizeof(TCmdParam1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_STRING( const TCmd* pCmd, int pnum ) {
DROPLOG("CMD_STRING(%d)\n",pnum);
// cmd_string handles gbBufferMsgs
return cmd_string(pnum,(const TCmdString *) pCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_SYNCQUEST( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmdQuest));
}
else {
DROPLOG("CMD_SYNCQUEST(%d)\n",pnum);
if (pnum != myplr) {
const TCmdQuest * p = (const TCmdQuest *) pCmd;
SetMultiQuest(p->q, p->qstate, p->qlog, p->qvar1);
}
sgbDeltaChanged = TRUE;
}
return sizeof(TCmdQuest);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ENDSHIELD( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else {
DROPLOG("CMD_ENDSHIELD(%d)\n",pnum);
if ((pnum != myplr) && (currlevel == plr[pnum].plrlevel)) {
void DeleteMissile(int, int);
for (int i = 0; i < nummissiles; i++) {
int mi = missileactive[i];
if ((missile[mi]._mitype == MIT_MANASHIELD) && (missile[mi]._misource == pnum)) {
ClearMissileSpot(mi);
DeleteMissile(mi, i);
}
}
}
}
return sizeof(TCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_ENDREFLECT( const TCmd* pCmd, int pnum ) {
if (gbBufferMsgs == BUFFER_ON) {
// doesn't need to be buffered
}
else {
DROPLOG("CMD_ENDREFLECT(%d)\n",pnum);
if ((pnum != myplr) && (currlevel == plr[pnum].plrlevel)) {
void DeleteMissile(int, int);
for (int i = 0; i < nummissiles; i++) {
int mi = missileactive[i];
if ((missile[mi]._mitype == MIT_REFLECT) && (missile[mi]._misource == pnum)) {
ClearMissileSpot(mi);
DeleteMissile(mi, i);
}
}
}
}
return sizeof(TCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_CHEAT_EXPERIENCE( const TCmd* pCmd, int pnum ) {
#if _DEBUG
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmd));
}
else {
DROPLOG("CMD_CHEATEXPERIENCE(%d)\n",pnum);
if (plr[pnum]._pLevel < 50) {
plr[pnum]._pExperience = plr[pnum]._pNextExper;
NextPlrLevel(pnum);
}
}
#endif
return sizeof(TCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_CHEAT_SPELL_LEVEL( const TCmd* pCmd, int pnum ) {
#if _DEBUG
if (gbBufferMsgs == BUFFER_ON) {
mega_add_data(pnum,pCmd,sizeof(TCmd));
}
else {
DROPLOG("CMD_CHEATSPELLLEVEL(%d)\n",pnum);
plr[pnum]._pSplLvl[plr[pnum]._pRSpell]++;
}
#endif
return sizeof(TCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_OPEN_NAKRUL(const TCmd* pCmd, int pnum)
{
if (gbBufferMsgs == BUFFER_ON)
{
// doesn't need to be buffered
}
else
{
DROPLOG("CMD_OPEN_NAKRUL(%d)\n",pnum);
OpenNaKrul();
Na_Krul.Books = TRUE;
quests[Q_NA_KRUL]._qactive = QUEST_DONE;
Hose_NaKrul();
}
return sizeof(TCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_OPEN_NEST(const TCmd * pCmd, int pnum)
{
if (gbBufferMsgs == BUFFER_ON)
{
// doesn't need to be buffered
}
else
{
DROPLOG("CMD_OPEN_NEST(%d)\n",pnum);
const TCmdLocParam2 * p = (const TCmdLocParam2 *) pCmd;
AddMissile (p->x, p->y, p->wParam1, p->wParam2, 0, MIT_OPENNEST, MI_PLR, pnum, 0, 0);
OpenNest();
}
return sizeof(TCmdLocParam2);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_OPEN_CRYPT(const TCmd* pCmd, int pnum)
{
if (gbBufferMsgs == BUFFER_ON)
{
// doesn't need to be buffered
}
else
{
DROPLOG("CMD_OPEN_CRYPT(%d)\n",pnum);
OpenCrypt();
InitTownTriggers();
if (currlevel == TLVL_START) // In town
PlaySFX(IS_SARC);
}
return sizeof(TCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static DWORD On_DEBUG( const TCmd* pCmd, int pnum ) {
return sizeof(TCmd);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
// PATCH3.JMM
extern WORD sgwPackPlrOffsetTbl[MAX_PLRS];
// ENDPATCH3.JMM
#define HANDLE_CMD( c ) case CMD_##c : return On_##c( pCmd, pnum )
DWORD ParseCmd(int pnum,const TCmd * pCmd) {
app_assert((DWORD)pnum < MAX_PLRS);
app_assert(pCmd != NULL);
static BYTE sbLastCmd;
sbLastCmd = pCmd->bCmd;
// patch3.jmm
if( sgwPackPlrOffsetTbl[pnum] &&
sbLastCmd != CMD_ACK_PLRINFO &&
sbLastCmd != CMD_SEND_PLRINFO )
return 0;
// endpatch3.jmm
switch(pCmd->bCmd) {
HANDLE_CMD( SYNCDATA );
HANDLE_CMD( WALKXY );
HANDLE_CMD( ADDSTR );
HANDLE_CMD( ADDDEX );
HANDLE_CMD( ADDMAG );
HANDLE_CMD( ADDVIT );
HANDLE_CMD( SBSPELL );
HANDLE_CMD( GOTOGETITEM );
HANDLE_CMD( REQUESTGITEM );
HANDLE_CMD( GETITEM );
HANDLE_CMD( GOTOAGETITEM );
HANDLE_CMD( REQUESTAGITEM );
HANDLE_CMD( AGETITEM );
HANDLE_CMD( ITEMEXTRA );
HANDLE_CMD( PUTITEM );
HANDLE_CMD( SYNCPUTITEM );
HANDLE_CMD( RESPAWNITEM );
HANDLE_CMD( ATTACKXY );
HANDLE_CMD( SATTACKXY );
HANDLE_CMD( RATTACKXY );
HANDLE_CMD( SPELLXYD );
HANDLE_CMD( SPELLXY );
HANDLE_CMD( TSPELLXY );
HANDLE_CMD( OPOBJXY );
HANDLE_CMD( DISARMXY );
HANDLE_CMD( OPOBJT );
HANDLE_CMD( ATTACKID );
HANDLE_CMD( ATTACKPID );
HANDLE_CMD( RATTACKID );
HANDLE_CMD( RATTACKPID );
HANDLE_CMD( SPELLID );
HANDLE_CMD( SPELLPID );
HANDLE_CMD( TSPELLID );
HANDLE_CMD( TSPELLPID );
HANDLE_CMD( KNOCKBACK );
HANDLE_CMD( RESURRECT );
HANDLE_CMD( HEALOTHER );
HANDLE_CMD( TALKXY );
HANDLE_CMD( DEBUG );
HANDLE_CMD( NEWLVL );
HANDLE_CMD( WARP );
HANDLE_CMD( MONSTDEATH );
HANDLE_CMD( KILLGOLEM );
HANDLE_CMD( AWAKEGOLEM );
HANDLE_CMD( MONSTDAMAGE );
HANDLE_CMD( PLRDEAD );
HANDLE_CMD( PLRDAMAGE );
HANDLE_CMD( OPENDOOR );
HANDLE_CMD( CLOSEDOOR );
HANDLE_CMD( OPERATEOBJ );
HANDLE_CMD( PLROPOBJ );
HANDLE_CMD( BREAKOBJ );
HANDLE_CMD( CHANGEPLRITEMS );
HANDLE_CMD( DELPLRITEMS );
HANDLE_CMD( PLRLEVEL );
HANDLE_CMD( DROPITEM );
HANDLE_CMD( ACK_PLRINFO );
HANDLE_CMD( SEND_PLRINFO );
HANDLE_CMD( PLAYER_JOINLEVEL );
HANDLE_CMD( ACTIVATEPORTAL );
HANDLE_CMD( DEACTIVATEPORTAL );
HANDLE_CMD( RETOWN );
HANDLE_CMD( SETSTR );
HANDLE_CMD( SETMAG );
HANDLE_CMD( SETDEX );
HANDLE_CMD( SETVIT );
HANDLE_CMD( STRING );
HANDLE_CMD( SYNCQUEST );
HANDLE_CMD( ENDSHIELD );
HANDLE_CMD( CHEAT_EXPERIENCE );
HANDLE_CMD( CHEAT_SPELL_LEVEL );
HANDLE_CMD( ENDREFLECT );
HANDLE_CMD( OPEN_NAKRUL );
HANDLE_CMD( OPEN_NEST );
HANDLE_CMD( OPEN_CRYPT );
default:
// dreceive_level handles gbBufferMsgs
if (pCmd->bCmd >= CMD_DLEVEL_0 && pCmd->bCmd <= CMD_DLEVEL_END)
return dreceive_chunk(pnum,(const TCmdPlrInfoHdr *) pCmd);
// PATCH3.JMM
// app_fatal("Unknown PCMD %d (last cmd %d)\n",pCmd->bCmd,sbLastCmd);
SNetDropPlayer( pnum, SNET_EXIT_NOTRESPONDING );
return 0; // 0 is error condition: ditch rest of packet
// ENDPATCH3.JMM
}
// NO final return statement -- each case
// should have its own return statement
}
// ENDPATCH2.JMM.3/5/97
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*
int GetLDeltaItem(int itm)
{
TCmdPItem * pD = &sgLevels[currlevel].item[0];
for (int i = 0; i < MAXITEMS; i++,pD++) {
// find item
if (pD->bCmd == ITEM_FREE) continue;
if (pD->wIndx != item[itm].IDidx) continue;
if (pD->wCI != item[itm]._iCreateInfo) continue;
if (pD->dwSeed != (DWORD)item[itm]._iSeed) continue;
return(i);
}
return(-1);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
/*
old old old
void test_delta() {
static DLevel lvl[NUMLEVELS];
// randomize the level delta data
sgbDeltaChanged = TRUE;
srand(time(NULL));
WORD * p = (WORD *) &sgLevels[0];
for (int i = sizeof(sgLevels)/2; i--; )
*p++ = rand();
// save level data for later comparison
CopyMemory(&lvl[0],&sgLevels[0],sizeof lvl);
// send level delta info to myself
DeltaSendAllLevels(myplr);
// reinit level delta info
ZeroMemory(&sgLevels[0],sizeof sgLevels);
// get level delta packets
NetReceivePackets();
// make sure everything comps ok
for (i = 0; i < NUMLEVELS; i++) {
for (int j = 0; j < MAXITEMS; j++) {
if (sgLevels[i].item[j].bCmd == INIT_VAL) {
if (lvl[i].item[j].bCmd != INIT_VAL)
DebugBreak();
}
else if (memcmp(&sgLevels[i].item[j],&lvl[i].item[j],sizeof(TCmdPItem))) {
DebugBreak();
}
}
for (j = 0; j < MAXOBJECTS; j++) {
if (memcmp(&sgLevels[i].object[j],&lvl[i].object[j],sizeof(DObjectStr)))
DebugBreak();
}
for (j = 0; j < MAXMONSTERS; j++) {
if (sgLevels[i].monster[j]._mx == INIT_VAL) {
if (lvl[i].monster[j]._mx != INIT_VAL)
DebugBreak();
}
else if (memcmp(&sgLevels[i].monster[j],&lvl[i].monster[j],sizeof(DMonsterStr))) {
DebugBreak();
}
}
}
// reinit delta info
delta_init();
}
*/