|
|
|
@ -29,6 +29,7 @@ |
|
|
|
#include "storm/storm.h" |
|
|
|
#include "storm/storm.h" |
|
|
|
#include "sync.h" |
|
|
|
#include "sync.h" |
|
|
|
#include "town.h" |
|
|
|
#include "town.h" |
|
|
|
|
|
|
|
#include "towners.h" |
|
|
|
#include "tmsg.h" |
|
|
|
#include "tmsg.h" |
|
|
|
#include "trigs.h" |
|
|
|
#include "trigs.h" |
|
|
|
#include "utils/language.h" |
|
|
|
#include "utils/language.h" |
|
|
|
@ -682,7 +683,7 @@ DWORD OnGotoGetItem(const TCmd *pCmd, Player &player) |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLocParam1 *>(pCmd); |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLocParam1 *>(pCmd); |
|
|
|
const Point position { message.x, message.y }; |
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && InDungeonBounds(position)) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && InDungeonBounds(position) && message.wParam1 < MAXITEMS + 1) { |
|
|
|
MakePlrPath(player, position, false); |
|
|
|
MakePlrPath(player, position, false); |
|
|
|
player.destAction = ACTION_PICKUPITEM; |
|
|
|
player.destAction = ACTION_PICKUPITEM; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
@ -747,15 +748,16 @@ DWORD OnGetItem(const TCmd *pCmd, int pnum) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnGotoAutoGetItem(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnGotoAutoGetItem(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLocParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLocParam1 *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && InDungeonBounds(position) && message.wParam1 < MAXITEMS + 1) { |
|
|
|
MakePlrPath(player, { p->x, p->y }, false); |
|
|
|
MakePlrPath(player, position, false); |
|
|
|
player.destAction = ACTION_PICKUPAITEM; |
|
|
|
player.destAction = ACTION_PICKUPAITEM; |
|
|
|
player.destParam1 = p->wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnRequestAutoGetItem(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnRequestAutoGetItem(const TCmd *pCmd, Player &player) |
|
|
|
@ -898,44 +900,47 @@ DWORD OnRespawnItem(const TCmd *pCmd, int pnum) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnAttackTile(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnAttackTile(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLoc *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLoc *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && InDungeonBounds(position)) { |
|
|
|
MakePlrPath(player, { p->x, p->y }, false); |
|
|
|
MakePlrPath(player, position, false); |
|
|
|
player.destAction = ACTION_ATTACK; |
|
|
|
player.destAction = ACTION_ATTACK; |
|
|
|
player.destParam1 = p->x; |
|
|
|
player.destParam1 = position.x; |
|
|
|
player.destParam2 = p->y; |
|
|
|
player.destParam2 = position.y; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnStandingAttackTile(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnStandingAttackTile(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLoc *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLoc *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && InDungeonBounds(position)) { |
|
|
|
ClrPlrPath(player); |
|
|
|
ClrPlrPath(player); |
|
|
|
player.destAction = ACTION_ATTACK; |
|
|
|
player.destAction = ACTION_ATTACK; |
|
|
|
player.destParam1 = p->x; |
|
|
|
player.destParam1 = position.x; |
|
|
|
player.destParam2 = p->y; |
|
|
|
player.destParam2 = position.y; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnRangedAttackTile(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnRangedAttackTile(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLoc *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLoc *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && InDungeonBounds(position)) { |
|
|
|
ClrPlrPath(player); |
|
|
|
ClrPlrPath(player); |
|
|
|
player.destAction = ACTION_RATTACK; |
|
|
|
player.destAction = ACTION_RATTACK; |
|
|
|
player.destParam1 = p->x; |
|
|
|
player.destParam1 = position.x; |
|
|
|
player.destParam2 = p->y; |
|
|
|
player.destParam2 = position.y; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnSpellWall(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnSpellWall(const TCmd *pCmd, Player &player) |
|
|
|
@ -1012,94 +1017,96 @@ DWORD OnTargetSpellTile(const TCmd *pCmd, Player &player) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnOperateObjectTile(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnOperateObjectTile(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLocParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLocParam1 *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && InDungeonBounds(position) && message.wParam1 < MAXOBJECTS) { |
|
|
|
MakePlrPath(player, { p->x, p->y }, !Objects[p->wParam1]._oSolidFlag && !Objects[p->wParam1]._oDoorFlag); |
|
|
|
MakePlrPath(player, position, !Objects[message.wParam1]._oSolidFlag && !Objects[message.wParam1]._oDoorFlag); |
|
|
|
player.destAction = ACTION_OPERATE; |
|
|
|
player.destAction = ACTION_OPERATE; |
|
|
|
player.destParam1 = p->wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnDisarm(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnDisarm(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLocParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLocParam1 *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && InDungeonBounds(position) && message.wParam1 < MAXOBJECTS) { |
|
|
|
MakePlrPath(player, { p->x, p->y }, !Objects[p->wParam1]._oSolidFlag && !Objects[p->wParam1]._oDoorFlag); |
|
|
|
MakePlrPath(player, position, !Objects[message.wParam1]._oSolidFlag && !Objects[message.wParam1]._oDoorFlag); |
|
|
|
player.destAction = ACTION_DISARM; |
|
|
|
player.destAction = ACTION_DISARM; |
|
|
|
player.destParam1 = p->wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnOperateObjectTelekinesis(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnOperateObjectTelekinesis(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && message.wParam1 < MAXOBJECTS) { |
|
|
|
player.destAction = ACTION_OPERATETK; |
|
|
|
player.destAction = ACTION_OPERATETK; |
|
|
|
player.destParam1 = p->wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnAttackMonster(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnAttackMonster(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && message.wParam1 < MAXMONSTERS) { |
|
|
|
Point position = Monsters[p->wParam1].position.future; |
|
|
|
Point position = Monsters[message.wParam1].position.future; |
|
|
|
if (player.position.tile.WalkingDistance(position) > 1) |
|
|
|
if (player.position.tile.WalkingDistance(position) > 1) |
|
|
|
MakePlrPath(player, position, false); |
|
|
|
MakePlrPath(player, position, false); |
|
|
|
player.destAction = ACTION_ATTACKMON; |
|
|
|
player.destAction = ACTION_ATTACKMON; |
|
|
|
player.destParam1 = p->wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnAttackPlayer(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnAttackPlayer(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && message.wParam1 < MAX_PLRS) { |
|
|
|
MakePlrPath(player, Players[p->wParam1].position.future, false); |
|
|
|
MakePlrPath(player, Players[message.wParam1].position.future, false); |
|
|
|
player.destAction = ACTION_ATTACKPLR; |
|
|
|
player.destAction = ACTION_ATTACKPLR; |
|
|
|
player.destParam1 = p->wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnRangedAttackMonster(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnRangedAttackMonster(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && message.wParam1 < MAXMONSTERS) { |
|
|
|
ClrPlrPath(player); |
|
|
|
ClrPlrPath(player); |
|
|
|
player.destAction = ACTION_RATTACKMON; |
|
|
|
player.destAction = ACTION_RATTACKMON; |
|
|
|
player.destParam1 = p->wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnRangedAttackPlayer(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnRangedAttackPlayer(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && message.wParam1 < MAX_PLRS) { |
|
|
|
ClrPlrPath(player); |
|
|
|
ClrPlrPath(player); |
|
|
|
player.destAction = ACTION_RATTACKPLR; |
|
|
|
player.destAction = ACTION_RATTACKPLR; |
|
|
|
player.destParam1 = p->wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnSpellMonster(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnSpellMonster(const TCmd *pCmd, Player &player) |
|
|
|
@ -1194,51 +1201,52 @@ DWORD OnTargetSpellPlayer(const TCmd *pCmd, Player &player) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnKnockback(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnKnockback(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == Players[pnum].plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == Players[pnum].plrlevel && message.wParam1 < MAXMONSTERS) { |
|
|
|
M_GetKnockback(p->wParam1); |
|
|
|
M_GetKnockback(message.wParam1); |
|
|
|
M_StartHit(p->wParam1, pnum, 0); |
|
|
|
M_StartHit(message.wParam1, pnum, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnResurrect(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnResurrect(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
} else { |
|
|
|
} else if (message.wParam1 < MAX_PLRS) { |
|
|
|
DoResurrect(pnum, p->wParam1); |
|
|
|
DoResurrect(pnum, message.wParam1); |
|
|
|
CheckUpdatePlayer(pnum); |
|
|
|
CheckUpdatePlayer(pnum); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnHealOther(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnHealOther(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == Players[pnum].plrlevel) |
|
|
|
if (gbBufferMsgs != 1 && currlevel == Players[pnum].plrlevel && message.wParam1 < MAX_PLRS) |
|
|
|
DoHealOther(pnum, p->wParam1); |
|
|
|
DoHealOther(pnum, message.wParam1); |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnTalkXY(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnTalkXY(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLocParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLocParam1 *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel) { |
|
|
|
if (gbBufferMsgs != 1 && currlevel == player.plrlevel && InDungeonBounds(position) && message.wParam1 < NUM_TOWNERS) { |
|
|
|
MakePlrPath(player, { p->x, p->y }, false); |
|
|
|
MakePlrPath(player, position, false); |
|
|
|
player.destAction = ACTION_TALK; |
|
|
|
player.destAction = ACTION_TALK; |
|
|
|
player.destParam1 = p->wParam1; |
|
|
|
player.destParam1 = message.wParam1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnNewLevel(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnNewLevel(const TCmd *pCmd, int pnum) |
|
|
|
@ -1255,46 +1263,48 @@ DWORD OnNewLevel(const TCmd *pCmd, int pnum) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnWarp(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnWarp(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
} else { |
|
|
|
} else if (message.wParam1 < MAXPORTAL) { |
|
|
|
StartWarpLvl(pnum, p->wParam1); |
|
|
|
StartWarpLvl(pnum, message.wParam1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnMonstDeath(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnMonstDeath(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLocParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLocParam1 *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
else if (pnum != MyPlayerId && p->wParam1 < MAXMONSTERS) { |
|
|
|
else if (pnum != MyPlayerId && InDungeonBounds(position) && message.wParam1 < MAXMONSTERS) { |
|
|
|
int playerLevel = Players[pnum].plrlevel; |
|
|
|
int playerLevel = Players[pnum].plrlevel; |
|
|
|
if (currlevel == playerLevel) |
|
|
|
if (currlevel == playerLevel) |
|
|
|
M_SyncStartKill(p->wParam1, { p->x, p->y }, pnum); |
|
|
|
M_SyncStartKill(message.wParam1, position, pnum); |
|
|
|
delta_kill_monster(p->wParam1, { p->x, p->y }, playerLevel); |
|
|
|
delta_kill_monster(message.wParam1, position, playerLevel); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnKillGolem(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnKillGolem(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLocParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLocParam1 *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
else if (pnum != MyPlayerId) { |
|
|
|
else if (pnum != MyPlayerId && InDungeonBounds(position) && message.wParam1 < NUMLEVELS) { |
|
|
|
if (currlevel == p->wParam1) |
|
|
|
if (currlevel == message.wParam1) |
|
|
|
M_SyncStartKill(pnum, { p->x, p->y }, pnum); |
|
|
|
M_SyncStartKill(pnum, position, pnum); |
|
|
|
delta_kill_monster(pnum, { p->x, p->y }, p->wParam1); |
|
|
|
delta_kill_monster(pnum, position, message.wParam1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnAwakeGolem(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnAwakeGolem(const TCmd *pCmd, int pnum) |
|
|
|
@ -1348,16 +1358,16 @@ DWORD OnMonstDamage(const TCmd *pCmd, int pnum) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnPlayerDeath(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnPlayerDeath(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
else if (pnum != MyPlayerId) |
|
|
|
else if (pnum != MyPlayerId) |
|
|
|
StartPlayerKill(pnum, p->wParam1); |
|
|
|
StartPlayerKill(pnum, message.wParam1); |
|
|
|
else |
|
|
|
else |
|
|
|
CheckUpdatePlayer(pnum); |
|
|
|
CheckUpdatePlayer(pnum); |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnPlayerDamage(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnPlayerDamage(const TCmd *pCmd, Player &player) |
|
|
|
@ -1375,50 +1385,50 @@ DWORD OnPlayerDamage(const TCmd *pCmd, Player &player) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnOpenDoor(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnOpenDoor(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
} else { |
|
|
|
} else if (message.wParam1 < MAXOBJECTS) { |
|
|
|
int playerLevel = Players[pnum].plrlevel; |
|
|
|
int playerLevel = Players[pnum].plrlevel; |
|
|
|
if (currlevel == playerLevel) |
|
|
|
if (currlevel == playerLevel) |
|
|
|
SyncOpObject(pnum, CMD_OPENDOOR, p->wParam1); |
|
|
|
SyncOpObject(pnum, CMD_OPENDOOR, message.wParam1); |
|
|
|
DeltaSyncObject(p->wParam1, CMD_OPENDOOR, playerLevel); |
|
|
|
DeltaSyncObject(message.wParam1, CMD_OPENDOOR, playerLevel); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnCloseDoor(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnCloseDoor(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
} else { |
|
|
|
} else if (message.wParam1 < MAXOBJECTS) { |
|
|
|
int playerLevel = Players[pnum].plrlevel; |
|
|
|
int playerLevel = Players[pnum].plrlevel; |
|
|
|
if (currlevel == playerLevel) |
|
|
|
if (currlevel == playerLevel) |
|
|
|
SyncOpObject(pnum, CMD_CLOSEDOOR, p->wParam1); |
|
|
|
SyncOpObject(pnum, CMD_CLOSEDOOR, message.wParam1); |
|
|
|
DeltaSyncObject(p->wParam1, CMD_CLOSEDOOR, playerLevel); |
|
|
|
DeltaSyncObject(message.wParam1, CMD_CLOSEDOOR, playerLevel); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnOperateObject(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnOperateObject(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
} else { |
|
|
|
} else if (message.wParam1 < MAXOBJECTS) { |
|
|
|
int playerLevel = Players[pnum].plrlevel; |
|
|
|
int playerLevel = Players[pnum].plrlevel; |
|
|
|
if (currlevel == playerLevel) |
|
|
|
if (currlevel == playerLevel) |
|
|
|
SyncOpObject(pnum, CMD_OPERATEOBJ, p->wParam1); |
|
|
|
SyncOpObject(pnum, CMD_OPERATEOBJ, message.wParam1); |
|
|
|
DeltaSyncObject(p->wParam1, CMD_OPERATEOBJ, playerLevel); |
|
|
|
DeltaSyncObject(message.wParam1, CMD_OPERATEOBJ, playerLevel); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnPlayerOperateObject(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnPlayerOperateObject(const TCmd *pCmd, int pnum) |
|
|
|
@ -1484,14 +1494,14 @@ DWORD OnDeletePlayerItems(const TCmd *pCmd, int pnum) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnPlayerLevel(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnPlayerLevel(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
else if (p->wParam1 <= MAXCHARLEVEL && pnum != MyPlayerId) |
|
|
|
else if (message.wParam1 < MAXCHARLEVEL && pnum != MyPlayerId) |
|
|
|
Players[pnum]._pLevel = p->wParam1; |
|
|
|
Players[pnum]._pLevel = message.wParam1; |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnDropItem(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnDropItem(const TCmd *pCmd, int pnum) |
|
|
|
@ -1520,17 +1530,23 @@ DWORD OnSendPlayerInfo(const TCmd *pCmd, int pnum) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnPlayerJoinLevel(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnPlayerJoinLevel(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLocParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLocParam1 *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
if (gbBufferMsgs == 1) { |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int playerLevel = message.wParam1; |
|
|
|
|
|
|
|
if (playerLevel > (gbIsHellfire ? 24 : 16) || !InDungeonBounds(position)) { |
|
|
|
|
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
auto &player = Players[pnum]; |
|
|
|
auto &player = Players[pnum]; |
|
|
|
|
|
|
|
|
|
|
|
player._pLvlChanging = false; |
|
|
|
player._pLvlChanging = false; |
|
|
|
if (player._pName[0] != 0 && !player.plractive) { |
|
|
|
if (player._pName[0] != '\0' && !player.plractive) { |
|
|
|
ResetPlayerGFX(player); |
|
|
|
ResetPlayerGFX(player); |
|
|
|
player.plractive = true; |
|
|
|
player.plractive = true; |
|
|
|
gbActivePlayers++; |
|
|
|
gbActivePlayers++; |
|
|
|
@ -1538,8 +1554,8 @@ DWORD OnPlayerJoinLevel(const TCmd *pCmd, int pnum) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (player.plractive && MyPlayerId != pnum) { |
|
|
|
if (player.plractive && MyPlayerId != pnum) { |
|
|
|
player.position.tile = { p->x, p->y }; |
|
|
|
player.position.tile = position; |
|
|
|
player.plrlevel = p->wParam1; |
|
|
|
player.plrlevel = playerLevel; |
|
|
|
ResetPlayerGFX(player); |
|
|
|
ResetPlayerGFX(player); |
|
|
|
if (currlevel == player.plrlevel) { |
|
|
|
if (currlevel == player.plrlevel) { |
|
|
|
SyncInitPlr(pnum); |
|
|
|
SyncInitPlr(pnum); |
|
|
|
@ -1557,7 +1573,7 @@ DWORD OnPlayerJoinLevel(const TCmd *pCmd, int pnum) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnActivatePortal(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnActivatePortal(const TCmd *pCmd, int pnum) |
|
|
|
@ -1624,50 +1640,50 @@ DWORD OnRestartTown(const TCmd *pCmd, int pnum) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnSetStrength(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnSetStrength(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
else if (p->wParam1 <= 750 && pnum != MyPlayerId) |
|
|
|
else if (message.wParam1 <= 750 && pnum != MyPlayerId) |
|
|
|
SetPlrStr(Players[pnum], p->wParam1); |
|
|
|
SetPlrStr(Players[pnum], message.wParam1); |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnSetDexterity(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnSetDexterity(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
else if (p->wParam1 <= 750 && pnum != MyPlayerId) |
|
|
|
else if (message.wParam1 <= 750 && pnum != MyPlayerId) |
|
|
|
SetPlrDex(Players[pnum], p->wParam1); |
|
|
|
SetPlrDex(Players[pnum], message.wParam1); |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnSetMagic(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnSetMagic(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
else if (p->wParam1 <= 750 && pnum != MyPlayerId) |
|
|
|
else if (message.wParam1 <= 750 && pnum != MyPlayerId) |
|
|
|
SetPlrMag(Players[pnum], p->wParam1); |
|
|
|
SetPlrMag(Players[pnum], message.wParam1); |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnSetVitality(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnSetVitality(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
if (gbBufferMsgs == 1) |
|
|
|
SendPacket(pnum, p, sizeof(*p)); |
|
|
|
SendPacket(pnum, &message, sizeof(message)); |
|
|
|
else if (p->wParam1 <= 750 && pnum != MyPlayerId) |
|
|
|
else if (message.wParam1 <= 750 && pnum != MyPlayerId) |
|
|
|
SetPlrVit(Players[pnum], p->wParam1); |
|
|
|
SetPlrVit(Players[pnum], message.wParam1); |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnString(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnString(const TCmd *pCmd, int pnum) |
|
|
|
@ -1732,22 +1748,23 @@ DWORD OnDebug(const TCmd *pCmd) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnNova(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnNova(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLoc *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdLoc *>(pCmd); |
|
|
|
|
|
|
|
const Point position { message.x, message.y }; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1) { |
|
|
|
if (gbBufferMsgs != 1) { |
|
|
|
auto &player = Players[pnum]; |
|
|
|
auto &player = Players[pnum]; |
|
|
|
if (currlevel == player.plrlevel && pnum != MyPlayerId) { |
|
|
|
if (currlevel == player.plrlevel && pnum != MyPlayerId && InDungeonBounds(position)) { |
|
|
|
ClrPlrPath(player); |
|
|
|
ClrPlrPath(player); |
|
|
|
player._pSpell = SPL_NOVA; |
|
|
|
player._pSpell = SPL_NOVA; |
|
|
|
player._pSplType = RSPLTYPE_INVALID; |
|
|
|
player._pSplType = RSPLTYPE_INVALID; |
|
|
|
player._pSplFrom = 3; |
|
|
|
player._pSplFrom = 3; |
|
|
|
player.destAction = ACTION_SPELL; |
|
|
|
player.destAction = ACTION_SPELL; |
|
|
|
player.destParam1 = p->x; |
|
|
|
player.destParam1 = position.x; |
|
|
|
player.destParam2 = p->y; |
|
|
|
player.destParam2 = position.y; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnSetShield(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnSetShield(const TCmd *pCmd, Player &player) |
|
|
|
@ -1768,11 +1785,12 @@ DWORD OnRemoveShield(const TCmd *pCmd, Player &player) |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnSetReflect(const TCmd *pCmd, Player &player) |
|
|
|
DWORD OnSetReflect(const TCmd *pCmd, Player &player) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdParam1 *)pCmd; |
|
|
|
const auto &message = *reinterpret_cast<const TCmdParam1 *>(pCmd); |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1) |
|
|
|
if (gbBufferMsgs != 1) |
|
|
|
player.wReflections = p->wParam1; |
|
|
|
player.wReflections = message.wParam1; |
|
|
|
|
|
|
|
|
|
|
|
return sizeof(*p); |
|
|
|
return sizeof(message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DWORD OnNakrul(const TCmd *pCmd) |
|
|
|
DWORD OnNakrul(const TCmd *pCmd) |
|
|
|
@ -1789,6 +1807,7 @@ DWORD OnNakrul(const TCmd *pCmd) |
|
|
|
DWORD OnOpenHive(const TCmd *pCmd, int pnum) |
|
|
|
DWORD OnOpenHive(const TCmd *pCmd, int pnum) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto *p = (TCmdLocParam2 *)pCmd; |
|
|
|
auto *p = (TCmdLocParam2 *)pCmd; |
|
|
|
|
|
|
|
|
|
|
|
if (gbBufferMsgs != 1) { |
|
|
|
if (gbBufferMsgs != 1) { |
|
|
|
AddMissile({ p->x, p->y }, { p->wParam1, p->wParam2 }, Direction::South, MIS_HIVEEXP2, TARGET_MONSTERS, pnum, 0, 0); |
|
|
|
AddMissile({ p->x, p->y }, { p->wParam1, p->wParam2 }, Direction::South, MIS_HIVEEXP2, TARGET_MONSTERS, pnum, 0, 0); |
|
|
|
TownOpenHive(); |
|
|
|
TownOpenHive(); |
|
|
|
|