//
// ����˸������ݴ���
//
// QueryFinishLevel()
////////////////////////////////////////////////////////////
//
// ͷ�ļ�
#include <algorithm>
#include <vector>
#include <winsock2.h>
#include <windows.h>
#include <strsafe.h>
#include "Bicho.h"
#include "Resource.h"
////////////////////////////////////////////////////////////
//
// ȫ�ֱ���
extern COLORREF g_rgbPlayer[8];
extern GAMECOREINFO g_gci;
extern HBITMAP g_phbmIconBig[SIZE_ICONARRAY];
extern HANDLE g_hHeap;
extern HINSTANCE g_hInstance;
extern HWND g_hWnd;
extern MAP g_map;
extern PBEAM g_ppb[SIZE_PLAYERS];
extern PRISINGSCORE g_pprs[SIZE_RSARRAY];
extern PTEXTBLOCK g_pptb[SIZE_TBARRAY];
extern PTCPPACK g_pptp[SIZE_PLAYERS];
extern RECT g_rcLogic;
extern UINT g_fGlobal;
extern std::vector<PBICHO> g_vpbBlue;
extern std::vector<PBICHO> g_vpbGreen;
extern std::vector<PBICHO> g_vpbRed;
extern std::vector<PBICHO> g_vpbYellow;
extern std::vector<PFIREBALL> g_vpf;
extern std::vector<PSKULL> g_vps;
extern std::vector<PLAYER> g_vPlayers;
////////////////////////////////////////////////////////////
//
// ���� SUpdateData
VOID SUpdateData()
{
INT i, n;
//
// beam list traversal
//
// Damage Judgment and Beam TTL Decreasementing
//
// ������ݽṹ��ͬ�� pptb �� pprs������Զ�� SIZE_PLAYERS ��С������Ҫ�ı��С
// �����һ�ֲ���ƽ������Ĺ������ڽ���� id ��ǰ�Ĺ���֮���������ж���
for (i = 0; i < SIZE_PLAYERS; ++i)
{
if (g_ppb[i])
{
if (g_ppb[i]->ttl)
SApplyBeam(i);
else
{
HeapFree(g_hHeap, 0, g_ppb[i]);
g_ppb[i] = NULL;
SPushDword(TPH_DELBEAM, i);
SSynchronizeBall(0, TRUE);
}
}
}
//
// bicho, fireball, skull, boss list traversal
//
// Move Within Given Rectangle, Under Edge Detection
//
// Skull
n = g_vps.size();
for (i = 0; i < n; ++i)
{
SMoveIt(&g_vps.at(i)->rc, &g_rcLogic,
&g_vps.at(i)->dx, &g_vps.at(i)->dy, FALSE);
}
// Bicho
n = g_vpbBlue.size();
for (i = 0; i < n; ++i)
{
if (g_vpbBlue.at(i)->state)
{
if (SMoveIt(&g_vpbBlue.at(i)->rc, &g_rcLogic,
&g_vpbBlue.at(i)->dx, &g_vpbBlue.at(i)->dy, FALSE))
{
if (g_vpbBlue.at(i)->dx > 0)
g_vpbBlue.at(i)->icon = g_phbmIconBig[ICON_BLUE1];
else
g_vpbBlue.at(i)->icon = g_phbmIconBig[ICON_BLUE2];
}
}
else if (g_vpbBlue.at(i)->ttl)
--g_vpbBlue.at(i)->ttl;
else
{
HeapFree(g_hHeap, 0, g_vpbBlue.at(i));
g_vpbBlue.at(i) = NULL;
}
}
g_vpbBlue.erase(std::remove(g_vpbBlue.begin(),
g_vpbBlue.end(), (PBICHO)NULL), g_vpbBlue.end());
n = g_vpbGreen.size();
for (i = 0; i < n; ++i)
{
if (g_vpbGreen.at(i)->state)
{
if (SMoveIt(&g_vpbGreen.at(i)->rc, &g_rcLogic,
&g_vpbGreen.at(i)->dx, &g_vpbGreen.at(i)->dy, FALSE))
{
if (g_vpbGreen.at(i)->dx > 0)
g_vpbGreen.at(i)->icon = g_phbmIconBig[ICON_GREEN1];
else
g_vpbGreen.at(i)->icon = g_phbmIconBig[ICON_GREEN2];
}
}
else if (g_vpbGreen.at(i)->ttl)
--g_vpbGreen.at(i)->ttl;
else
{
HeapFree(g_hHeap, 0, g_vpbGreen.at(i));
g_vpbGreen.at(i) = NULL;
}
}
g_vpbGreen.erase(std::remove(g_vpbGreen.begin(),
g_vpbGreen.end(), (PBICHO)NULL), g_vpbGreen.end());
n = g_vpbRed.size();
for (i = 0; i < n; ++i)
{
if (g_vpbRed.at(i)->state)
{
if (SMoveIt(&g_vpbRed.at(i)->rc, &g_rcLogic,
&g_vpbRed.at(i)->dx, &g_vpbRed.at(i)->dy, FALSE))
{
if (g_vpbRed.at(i)->dx > 0)
g_vpbRed.at(i)->icon = g_phbmIconBig[ICON_RED1];
else
g_vpbRed.at(i)->icon = g_phbmIconBig[ICON_RED2];
}
}
else if (g_vpbRed.at(i)->ttl)
--g_vpbRed.at(i)->ttl;
else
{
HeapFree(g_hHeap, 0, g_vpbRed.at(i));
g_vpbRed.at(i) = NULL;
}
}
g_vpbRed.erase(std::remove(g_vpbRed.begin(),
g_vpbRed.end(), (PBICHO)NULL), g_vpbRed.end());
n = g_vpbYellow.size();
for (i = 0; i < n; ++i)
{
if (g_vpbYellow.at(i)->state)
{
if (SMoveIt(&g_vpbYellow.at(i)->rc, &g_rcLogic,
&g_vpbYellow.at(i)->dx, &g_vpbYellow.at(i)->dy, FALSE))
{
if (g_vpbYellow.at(i)->dx > 0)
g_vpbYellow.at(i)->icon = g_phbmIconBig[ICON_YELLOW1];
else
g_vpbYellow.at(i)->icon = g_phbmIconBig[ICON_YELLOW2];
}
}
else if (g_vpbYellow.at(i)->ttl)
--g_vpbYellow.at(i)->ttl;
else
{
HeapFree(g_hHeap, 0, g_vpbYellow.at(i));
g_vpbYellow.at(i) = NULL;
}
}
g_vpbYellow.erase(std::remove(g_vpbYellow.begin(),
g_vpbYellow.end(), (PBICHO)NULL), g_vpbYellow.end());
// Fireball ��Ҫ����ͼ��
n = g_vpf.size();
for (i = 0; i < n; ++i)
{
if (g_vpf.at(i)->state)
SMoveIt(&g_vpf.at(i)->rc, &g_rcLogic, &g_vpf.at(i)->dx, &g_vpf.at(i)->dy, FALSE);
else if (g_vpf.at(i)->ttl)
--g_vpf.at(i)->ttl;
else
{
HeapFree(g_hHeap, 0, g_vpf.at(i));
g_vpf.at(i) = NULL;
}
}
g_vpf.erase(std::remove(g_vpf.begin(), g_vpf.end(), (PFIREBALL)NULL), g_vpf.end());
SUpdatePlayer();
}
////////////////////////////////////////////////////////////
//
// SUpdatePlayer
// player list traversal
VOID SUpdatePlayer()
{
int i;
SHORT dx, dy; // player velocity
for (i = 0; i < SIZE_PLAYERS; ++i)
{
if (g_vPlayers.at(i).state == STATE_LIVE)
{
//
// player attack cd ttl decreasementing
//
if (g_vPlayers.at(i).ttl)
--g_vPlayers.at(i).ttl;
//
// player buff ttl decreasementing
//
if (g_vPlayers.at(i).blue)
--g_vPlayers.at(i).blue;
if (g_vPlayers.at(i).green)
--g_vPlayers.at(i).green;
if (g_vPlayers.at(i).red)
--g_vPlayers.at(i).red;
if (g_vPlayers.at(i).yellow)
--g_vPlayers.at(i).yellow;
if (g_vPlayers.at(i).skull)
--g_vPlayers.at(i).skull;
if (g_vPlayers.at(i).pwned)
--g_vPlayers.at(i).pwned;
//
// �
//
if (g_vPlayers.at(i).arrow)
{
switch (g_vPlayers.at(i).arrow)
{
case VK_LEFT:
if (g_vPlayers.at(i).yellow)
dx = -DIFFER_PLAYERFAST;
else if (g_vPlayers.at(i).green)
dx = -DIFFER_PLAYERSLOW;
else
dx = -DIFFER_PLAYERNORMAL;
dy = 0;
break;
case VK_UP:
if (g_vPlayers.at(i).yellow)
dy = -DIFFER_PLAYERFAST;
else if (g_vPlayers.at(i).green)
dy = -DIFFER_PLAYERSLOW;
else
dy = -DIFFER_PLAYERNORMAL;
dx = 0;
break;
case VK_RIGHT:
if (g_vPlayers.at(i).yellow)
dx = DIFFER_PLAYERFAST;
else if (g_vPlayers.at(i).green)
dx = DIFFER_PLAYERSLOW;
else
dx = DIFFER_PLAYERNORMAL;
dy = 0;
break;
case VK_DOWN:
if (g_vPlayers.at(i).yellow)
dy = DIFFER_PLAYERFAST;
else if (g_vPlayers.at(i).green)
dy = DIFFER_PLAYERSLOW;
else
dy = DIFFER_PLAYERNORMAL;
dx = 0;
break;
default:
dx = dy = 0;
break;
}
SMoveIt(&g_vPlayers.at(i).rc, &g_rcLogic, &dx, &dy, TRUE);
}
}
else if (g_vPlayers.at(i).state == STATE_REBORN)
{
// ������� reborn ״̬�����״̬��ʾ���������������ܲ�������
// Ҫ����Ϸ�趨�����磬�� coop ģʽ�£�life �Ƿ�����㡣
if (g_vPlayers.at(i).ttl)
--g_vPlayers.at(i).ttl;
else
{
switch (LOWORD(g_gci.dwGameMode))
{
case GMODE_COOP:
case GMODE_TEAM:
case GMODE_DUEL:
if (g_vPlayers.at(i).life);
else
{
g_vPlayers.at(i).state = STATE_DEAD;
PostMessage(g_hWnd, GM_STATECHANGE, STATE_DEAD, i);
break;
}
// fall through
case GMODE_FAIR:
PostMessage(g_hWnd, GM_WANTJOIN, g_vPlayers.at(i).color, i);
}
}
}
}
}
////////////////////////////////////////////////////////////
//
// SApplyBeam
VOID SApplyBeam(INT i)
{
INT n, j;
//
// skull
//
n = g_vps.size();
for (j = 0; j < n; ++j)
{
if (SDamageJudgment(g_ppb[i], &g_vps.at(j)->rc))
{
++g_ppb[i]->skulls;
++g_ppb[i]->total;
break;
}
}
if (g_ppb[i]->skulls)
{
g_ppb[i]->ttl = 0;
return;
}
//
// bichos
//
n = g_vpbBlue.size();
for (j = 0; j < n; ++j)
{
if (g_vpbBlue.at(j)->state)
{
if (SDamageJudgment(g_ppb[i], &g_vpbBlue.at(j)->rc))
{
++g_ppb[i]->blues;
++g_ppb[i]->total;
g_vpbBlue.at(j)->state = STATE_ABSENCE;
g_vpbBlue.at(j)->ttl = TTL_DEADBICHO;
}
}
}
n = g_vpbGreen.size();
for (j = 0; j < n; ++j)
{
if (g_vpbGreen.at(j)->state)
{
if (SDamageJudgment(g_ppb[i], &g_vpbGreen.at(j)->rc))
{
++g_ppb[i]->greens;
++g_ppb[i]->total;
g_vpbGreen.at(j)->state = STATE_ABSENCE;
g_vpbGreen.at(j)->ttl = TTL_DEADBICHO;
}
}
}
n = g_vpbRed.size();
for (j = 0; j < n; ++j)
{
if (g_vpbRed.at(j)->state)
{
if (SDamageJudgment(g_ppb[i], &g_vpbRed.at(j)->rc))
{
++g_ppb[i]->reds;
++g_ppb[i]->total;
g_vpbRed.at(j)->state = STATE_ABSENCE;
g_vpbRed.at(j)->ttl = TTL_DEADBICHO;
}
}
}
n = g_vpbYellow.size();
for (j = 0; j < n; ++j)
{
if (g_vpbYellow.at(j)->state)
{
if (SDamageJudgment(g_ppb[i], &g_vpbYellow.at(j)->rc))
{
++g_ppb[i]->yellows;
++g_ppb[i]->total;
g_vpbYellow.at(j)->state = STATE_ABSENCE;
g_vpbYellow.at(j)->ttl = TTL_DEADBICHO;
}
}
}
n = g_vpf.size();
for (j = 0; j < n; ++j)
{
if (g_vpf.at(j)->state)
{
if (SDamageJudgment(g_ppb[i], &g_vpf.at(j)->rc))
{
++g_ppb[i]->oranges;
++g_ppb[i]->total;
g_vpf.at(j)->state = STATE_ABSENCE;
g_vpf.at(j)->ttl = TTL_DEADBICHO;
}
}
}
switch (LOWORD(g_gci.dwGameMode))
{
case GMODE_COOP: break;
case GMODE_FAIR: SApplyFAIRBeam(i); break;
case GMODE_TEAM: SApplyTEAMBeam(i); break;
case GMODE_DUEL: SApplyDUELBeam(i); break;
}
--g_ppb[i]->ttl;
}
// PVP
VOID SApplyFAIRBeam(INT i)
{
int j;
TCHAR sz[64];
for (j = 0; j < SIZE_PLAYERS; ++j)
{
if (g_vPlayers.at(j).state == STATE_LIVE)
{
if (g_ppb[i]->excludes & 1 << j);
else
{
if (SDamageJudgment(g_ppb[i], &g_vPlayers.at(j).rc))
{
if (g_vPlayers.at(j).red)
{
g_vPlayers.at(j).red = 0;
g_ppb[i]->excludes |= 1 << j;
SPushDword(TPH_SHIELDDROP, j);
}
else
{
if (g_ppb[i]->quad)
MDecreasePlayerLifeByFour(j);
else
MDecreasePlayerLifeByOne(j);
++g_vPlayers.at(i).kills;
HeapFree(g_hHeap, 0, g_ppb[j]);
g_ppb[j] = NULL;
SPushDword(TPH_DELBEAM, j);
SPushDword(TPH_UPDATEKILLS, MAKELPARAM(i, g_vPlayers.at(i).kills));
SSynchronizeBall(0, TRUE);
StringCchPrintf(sz, 64, TEXT("%s ɱ���� %s"),
g_vPlayers.at(i).name, g_vPlayers.at(j).name);
SAnnounce(sz);
}
}
}
}
}
}
// team
VOID SApplyTEAMBeam(INT i)
{
int j;
TCHAR sz[64];
for (j = 0; j < SIZE_PLAYERS; ++j)
{
if (g_vPlayers.at(j).state == STATE_LIVE)
{
if (g_vPlayers.at(i).color == g_vPlayers.at(j).color);
else if (g_ppb[i]->excludes & 1 << j);
else
{
if (SDamageJudgment(g_ppb[i], &g_vPlayers.at(j).rc))
{
if (g_vPlayers.at(j).red)
{
g_vPlayers.at(j).red = 0;
g_ppb[i]->excludes |= 1 << j;
SPushDword(TPH_SHIELDDROP, j);
}
else
{
if (g_ppb[i]->quad)
MDecreasePlayerLifeByFour(j);
else
MDecreasePlayerLifeByOne(j);
++g_vPlayers.at(i).kills;
HeapFree(g_hHeap, 0, g_ppb[j]);
g_ppb[j] = NULL;
SPushDword(TPH_DELBEAM, j);
SSynchronizeBall(0, TRUE);
StringCchPrintf(sz, 64, TEXT("%s ɱ���� %s"),
g_vPlayers.at(i).name, g_vPlayers.at(j).name);
SAnnounce(sz);
}
}
}
}
}
}
// duel
VOID SApplyDUELBeam(INT i)
{
int j;
TCHAR sz[64];
for (j = 0; j < SIZE_PLAYERS; ++j)
{
if (g_vPlayers.at(j).state == STATE_LIVE)
{
if (g_ppb[i]->excludes & 1 << j);
else
{
if (SDamageJudgment(g_ppb[i], &g_vPlayers.at(j).rc))
{
if (g_vPlayers.at(j).red)
{
g_vPlayers.at(j).red = 0;
g_ppb[i]->excludes |= 1 << j;
SPushDword(TPH_SHIELDDROP, j);
}
else
{
if (g_ppb[i]->quad)
MDecreasePlayerLifeByFour(j);
else
MDecreasePlayerLifeByOne(j);
++g_vPlayers.at(i).kills;
HeapFree(g_hHeap, 0, g_ppb[j]);
g_ppb[j] = NULL;
SPushDword(TPH_DELBEAM, j);
SSynchronizeBall(0, TRUE);
StringCchPrintf(sz, 64, TEXT("%s ɱ���� %s"),
g_vPlayers.at(i).name, g_vPlayers.at(j).name);
SAnnounce(sz);
}
}
}
}
}
}
////////////////////////////////////////////////////////////
//
// SDamageJudgment
BOOL SDamageJudgment(PBEAM pb, PRECT prc)
{
int x, y;
RECT rcAtk, rc;
if (pb->quad)
{
x = pb->x + (SIZE_PLAYERBIG - SIZE_QUAD) / 2;
y = pb->y + (SIZE_PLAYERBIG - SIZE_QUAD) / 2;
// ����
SetRect(&rcAtk, x, 0, x + SIZE_QUAD, SIZE_LOGICY);
IntersectRect(&rc, &rcAtk, prc);
if (IsRectEmpty(&rc));
else
return TRUE;
// ����
SetRect(&rcAtk, 0, y, SIZE_LOGICX, y + SIZE_QUAD);
IntersectRect(&rc, &rcAtk, prc);
if (IsRectEmpty(&rc));
else
return TRUE;
}
else
{
x = pb->x + SIZE_PLAYERBIG / 2;
y = pb->y + SIZE_PLAYERBIG / 2;
// ����
SetRect(&rcAtk, x, 0, x + 2, SIZE_LOGICY);
IntersectRect(&rc, &rcAtk, prc);
if (IsRectEmpty(&rc));
else
return TRUE;
// ����
SetRect(&rcAtk, 0, y, SIZE_LOGICX, y + 2);
IntersectRect(&rc, &rcAtk, prc);
if (IsRectEmpty(&rc));
else
return TRUE;
}
return FALSE;
}
////////////////////////////////////////////////////////////
//
// SFinalDispatcher
// our cute dispatcher...
VOID CALLBACK SFinalDispatcher(UINT uTimerID, UINT uMsg,
DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
PostMessage(g_hWnd, GM_UPDATE, 0, 0);
UNREFERENCED_PARAMETER(uTimerID);
UNREFERENCED_PARAMETER(uMsg);
UNREFERENCED_PARAMETER(dwUser);
UNREFERENCED_PARAMETER(dw1);
UNREFERENCED_PARAMETER(dw2);
}
////////////////////////////////////////////////////////////
//
// SMoveIt
// move within given rectangle
BOOL SMoveIt(PRECT prcObj, CONST PRECT prcFrame, PSHORT pdx, PSHORT pdy, BOOL bPlayer)
{
RECT rect;
BOOL bRet;
bRet = FALSE;
OffsetRect(prcObj, *pdx, *pdy);
IntersectRect(&rect, prcObj, prcFrame);
if (EqualRect(&rect, prcObj));
else
{
if (*pdx < 0)
{
if (prcObj->left < prcFrame->left)
{
if (bPlayer)
OffsetRect(prcObj, prcFrame->left - prcObj->left, 0);
else
{
OffsetRect(prcObj, (prcFrame->left - prcObj->left) * 2, 0);
*pdx = -*pdx;
}
bRet = TRUE;
}
}
else
{
if (prcObj->right > prcFrame->right)
{
if (bPlayer)
OffsetRect(prcObj, prcFrame->right - prcObj->right, 0);
else
{
OffsetRect(prcObj, (prcFrame->right - prcObj->right) * 2, 0);
*pdx = -*pdx;
}
bRet = TRUE;
}
}
if (*pdy < 0)
{
if (prcObj->top < prcFrame->top)
{
if (bPlayer)
OffsetRect(prcObj, 0, prcFrame->top - prcObj->top);
else
{
OffsetRect(prcObj, 0, (prcFrame->top - prcObj->top) * 2);
*pdy = -*pdy;
}
}
}
else
{
if (prcObj->bottom > prcFrame->bottom)
{
if (bPlayer)
OffsetRect(prcObj, 0, prcFrame->bottom - prcObj->bottom);
else
{
OffsetRect(prcObj, 0, (prcFrame->bottom - prcObj->bottom) * 2);
*pdy = -*pdy;
}
}
}
}
return bRet;
}
////////////////////////////////////////////////////////////
//
// Network n Players
//
////////////////////////////////////////////////////////////
SOCKET g_sTcp[6]; // ������������ʱ������䡣SRemovePlayer ����رղ����㡣
SOCKET g_sUdp; // GM_UDP
////////////////////////////////////////////////////////////
//
// SRunServer
// �˿ںſ���ʧ�ܣ����� -1
INT SRunServer()
{
SOCKADDR_IN addr;
g_sTcp[0] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
g_sUdp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
addr.sin_family = AF_INET;
addr.sin_port = htons((USHORT)g_gci.nPort);
addr.sin_addr.s_addr = htonl(INADDR_ANY); // ����� 3 �� ip �ϼ�������������Ҫ��
if (bind(g_sTcp[0], (PSOCKADDR)&addr, sizeof addr))
return -1;
if (bind(g_sUdp, (PSOCKADDR)&addr, sizeof addr))
return -1;
listen(g_sTcp[0], 3);
WSAAsyncSelect(g_sTcp[0], g_hWnd, GM_NEWCONNECT, FD_ACCEPT);
WSAAsyncSelect(g_sUdp, g_hWnd, GM_UDP, FD_READ | FD_WRITE);
return 0;
}
//
// ��������������
//
VOID SShutdownServer()
{
INT i;
if (g_sUdp)
closesocket(g_sUdp);
g_sUdp = NULL;
for (i = 0; i < SIZE_PLAYERS; ++i)
{
if (g_vPlayers.at(i).state)
SRemovePlayer(i);
}
}
////////////////////////////////////////////////////////////
//
// managing g_vPlayers and g_sTcp array
// ����ֵ�� 0~5��������ӳɹ�������������б��е�������
// ���� -1 �������ʧ�ܣ�������Ϊ�б�����
int SCanAddPlayer()
{
int i;
for (i = 1; i < 6; ++i)
{
if (g_sTcp[i])
continue;
else
return i;
}
return -1;
}
VOID SAddPlayer(PPLAYERCOREINFO ppci)
{
int i;
i = ppci->id;
g_vPlayers.at(i).dwicon = ppci->dwicon;
StringCchCopy(g_vPlayers.at(i).name, SIZE_NAMELEN, ppci->name);
g_vPlayers.at(i).addr = ppci->addr;
g_vPlayers.at(i).id = (BYTE)i;
g_vPlayers.at(i).state = ppci->state;
g_vPlayers.at(i).life = ppci->life;
g_vPlayers.at(i).color = ppci->color;
g_vPlayers.at(i).ttl = ppci->ttl;
g_vPlayers.at(i).kills = ppci->kills;
//
// Outline
//
g_vPlayers.at(i).icon = IMakePlayerIcon(g_vPlayers.at(i).dwicon);
g_vPlayers.at(i).sicon = IMakePlayerIcon(g_vPlayers.at(i).dwicon); // no implementation
g_vPlayers.at(i).pen = CreatePen(PS_SOLID, 2,
g_rgbPlayer[LOWORD(g_vPlayers.at(i).dwicon)]);
g_vPlayers.at(i).brush = CreateHatchBrush(HS_DIAGCROSS,
g_rgbPlayer[LOWORD(g_vPlayers.at(i).dwicon)]);
}
//
// g_vPlayers ���� SIZE_PLAYERS �� PLAYER �ṹ�����飨vector��
//
VOID SRemovePlayer(INT i)
{
DeleteObject(g_vPlayers.at(i).icon);
DeleteObject(g_vPlayers.at(i).sicon);
DeleteObject(g_vPlayers.at(i).pen);
DeleteObject(g_vPlayers.at(i).brush);
g_vPlayers.at(i).icon = NULL;
g_vPlayers.at(i).sicon = NULL;
g_vPlayers.at(i).pen = NULL;
g_vPlayers.at(i).brush = NULL;
g_vPlayers.at(i).state = STATE_ABSENCE;
if (g_sTcp[i])
{
closesocket(g_sTcp[i]);
g_sTcp[i] = NULL;
PostMessage(g_hWnd, GM_REMOVEPLAYER, i, 0);
}
}
////////////////////////////////////////////////////////////
//
// Beam
VOID SAddBeam(int i)
{
PBEAM pb;
// �����ڳ��ϲ��ҹ��� cd �Ѿ�����
if (g_vPlayers.at(i).state == STATE_LIVE &&
g_vPlayers.at(i).ttl == 0 &&
g_map.flag & MAP_CANADDBEAM)
{
if (g_ppb[i]);
else
{
pb = (PBEAM)HeapAlloc(g_hHeap, 0, sizeof(BEAM));
pb->x = (WORD)g_vPlayers.at(i).rc.left;
pb->y = (WORD)g_vPlayers.at(i).rc.top;
if (g_vPlayers.at(i).blue || g_vPlayers.at(i).skull)
pb->quad = TRUE;
else
pb->quad = FALSE;
pb->ttl = pb->quad ? TTL_BEAMQUAD : TTL_BEAMNORMAL;
pb->excludes = 0;
pb->excludes |= 1 << i; // �ų������
pb->cr = g_rgbPlayer[g_vPlayers.at(i).color];
pb->pen = pb->quad ? (HGDIOBJ)g_vPlayers.at(i).brush : (HGDIOBJ)g_vPlayers.at(i).pen;
pb->blues = 0;
pb->greens = 0;
pb->reds = 0;
pb->yellows = 0;
pb->skulls = 0;
pb->oranges = 0;
pb->pks = 0;
pb->total = 0;
g_ppb[i] = pb;
// ������ƹ����ӳٲ��á�����ӱ��ι����еõ��� buff�������ӳ�Ҫ���������
// �� buff ������֮������¼��㡣
// Ӧ�ø�Ϊһ���ٶ��� ttl -= 2�������� ttl -= 1������ ttl -= 4��etc.
if (g_vPlayers.at(i).yellow)
g_vPlayers.at(i).ttl = TTL_FASTATTACK;
else if (g_vPlayers.at(i).green)
g_vPlayers.at(i).ttl = TTL_SLOWATTACK;
else
g_vPlayers.at(i).ttl = TTL_ATTACK;
SPushDword(TPH_ADDBEAM, i);
}
}
}
VOID SClearPpb()
{
int i;
for (i = 0; i < SIZE_PLAYERS; ++i)
HeapFree(g_hHeap, 0, g_ppb[i]);
ZeroMemory(g_ppb, sizeof g_ppb[0] * SIZE_PLAYERS);
}
////////////////////////////////////////////////////////////
//
// SPush
// �����ʹ������ǣ����¼������� fd_write���� ptp ���ô˺��������
// �� WSAEWOULDBLOCK ��������ӣ��ڽ���ŵ� fd_write ������дһ�Σ����
// ptp �� NULL ��i �� fd_write �������������ֵ��һ�㶼�ܳɹ�������Ҫ��
// ���¼�������˳����������д���ε����������ȷʵ��Ҫ�ý�������ݸ�
// ��������ݡ�
// TCPPACK �� to �ֶ��ô����Ǻܴ�push ʱ����� ptp��i ���� to�������
// �� ptp��һ������ FD_WRITE �е��ã���ʱ to ������Ӧ�� tcp ���ӱ�š�
// ������ݲ���������� i �� to ����ͬ����������ǽ��նˣ��ͻ�����
// �ڷ��� XSDE1 ʹ�� to������ʱ�䲻�ã����Ի��㰲ȫ����Ȼ�����ÿ�ζ���
// ������ ptp �� i��
VOID SPush(CONST PTCPPACK ptp, CONST INT i)
{
int nWritten;
if (ptp)
{
// �״η��ͣ�����ɹ������
nWritten = send(g_sTcp[i], (PCHAR)ptp, sizeof(TCPPACK) + ptp->msglen, 0);
if (nWritten == SOCKET_ERROR)
{
nWritten = WSAGetLastError();
if (g_pptp[i]) // discard
HeapFree(g_hHeap, 0, g_pptp[i]);
if (nWritten == WSAEWOULDBLOCK)
{
g_pptp[i] = (PTCPPACK)HeapAlloc(g_hHeap, 0, sizeof(TCPPACK) + ptp->msglen);
CopyMemory(g_pptp[i], ptp, sizeof(TCPPACK) + ptp->msglen);
}
else
SRemovePlayer(i);
}
}
else if (g_pptp[i]) // in FD_WRITE
{
nWritten = send(g_sTcp[i], (PCHAR)g_pptp[i], sizeof(TCPPACK) + g_pptp[i]->msglen, 0);
if (nWritten == SOCKET_ERROR)
SRemovePlayer(i);
HeapFree(g_hHeap, 0, g_pptp[i]);
g_pptp[i] = NULL;
}
}
////////////////////////////////////////////////////////////
//
// SPushAll
VOID SPushAll(PTCPPACK ptp)
{
int i;
for (i = 1; i < SIZE_PLAYERS; ++i)
{
if (g_sTcp[i])
{
ptp->to = (BYTE)i;
SPush(ptp, i);
}
}
}
////////////////////////////////////////////////////////////
//
// SPushDword
VOID SPushDword(INT msgtype, DWORD value)
{
CHAR pbuf[sizeof(TCPPACK) + sizeof(DWORD)];
((PTCPPACK)pbuf)->msgtype = (BYTE)msgtype;
((PTCPPACK)pbuf)->to = 0;
((PTCPPACK)pbuf)->msglen = sizeof(DWORD);
*((PDWORD)((PTCPPACK)pbuf + 1)) = value;
SPushAll((PTCPPACK)pbuf);
}
////////////////////////////////////////////////////////////
//
// SAnnounce
VOID SAnnounce(CONST PWSTR psz)
{
CHAR sz[200];
CopyMemory(sz + sizeof(TCPPACK), psz, 200 - sizeof(TCPPACK));
sz[198] = sz[199] = 0;
((PTCPPACK)sz)->msgtype = TPH_TEXT;
((PTCPPACK)sz)->to = 0; // won't use it
((PTCPPACK)sz)->msglen = (WORD)(2 * lstrlen((PTSTR)(sz + sizeof(TCPPACK))) + 2);
SPushAll((PTCPPACK)sz);
HAddTextBlock(g_pptb, (PTSTR)(sz + sizeof(TCPPACK)), RGB_TBSERVER, TTL_TBSERVER);
}
////////////////////////////////////////////////////////////
//
// SPushRS
VOID SPushRS(PTSTR psz, INT color, CONST PRECT prc)
{
CHAR pbuf[200];
int i;
i = sizeof(TCPPACK) + sizeof(RECT) + sizeof(INT);
StringCchCopy((PTSTR)(pbuf + i), (200 - i) / sizeof(TCHAR), psz);
CopyRect((PRECT)((PTCPPACK)pbuf + 1), prc);
((PRSPACK)((PTCPPACK)pbuf + 1))->color = color;
((PTCPPACK)pbuf)->msgtype = TPH_RSPACK;
((PTCPPACK)pbuf)->to = 0; // won't use it
((PTCPPACK)pbuf)->msglen = (WORD)(2 * (lstrlen((PTSTR)(pbuf + i)) + 1) + i - sizeof(TCPPACK));
SPushAll((PTCPPACK)pbuf);
CAddRisingScore(g_pprs, psz, color, prc, TTL_RISINGSCORE);
}
////////////////////////////////////////////////////////////
//
// SSendXSDE2
VOID SSendXSDE2(INT i)
{
CHAR pbuf[1024];
INT n, j;
#define X ((PPLAYERCOREINFO)((PTCPPACK)pbuf + 1) + n)
n = 0;
for (j = 0; j < SIZE_PLAYERS; ++j)
{
if (g_vPlayers.at(j).state)
{
X->id = (BYTE)j;
X->state = g_vPlayers.at(j).state;
X->life = g_vPlayers.at(j).life;
X->color = g_vPlayers.at(j).color;
X->ttl = g_vPlayers.at(j).ttl;
X->kills = g_vPlayers.at(j).kills;
X->dwicon = g_vPlayers.at(j).dwicon;
StringCchCopy(X->name, SIZE_NAMELEN, g_vPlayers.at(j).name);
X->addr = g_vPlayers.at(j).addr;
++n;
}
}
#undef X
((PTCPPACK)pbuf)->msgtype = TPH_DE2;
((PTCPPACK)pbuf)->to = (BYTE)i;
((PTCPPACK)pbuf)->msglen = (WORD)(n * sizeof(PLAYERCOREINFO));
SPush((PTCPPACK)pbuf, i);
}
////////////////////////////////////////////////////////////
//
// Synchronization
//
////////////////////////////////////////////////////////////
VOID SSynchronizeBall(INT nIndex, BOOL toall)
{
char pbuf[1024];
int i, j, n;
#define X ((PBALLCOREINFO)((PTCPPACK)pbuf + 1) + j)
j = 0;
n = g_vpbBlue.size();
for (i = 0; i < n; ++i)
{
if (g_vpbBlue.at(i)->state)
{
X->color = g_vpbBlue.at(i)->dx > 0 ? ICON_BLUE1 : ICON_BLUE2;
X->dx = (signed char)g_vpbBlue.at(i)->dx;
X->dy = (signed char)g_vpbBlue.at(i)->dy;
X->cx = (WORD)g_vpbBlue.at(i)->rc.left;
X->cy = (WORD)g_vpbBlue.at(i)->rc.top;
}
else
{
X->color = ICON_PWNED1;
X->dx = 0;
X->dy = 0;
X->cx = (WORD)g_vpbBlue.at(i)->rc.left;
X->cy = (WORD)g_vpbBlue.at(i)->rc.top;
}
++j;
}
n = g_vpbGreen.size();
for (i = 0; i < n; ++i)
{
if (g_vpbGreen.at(i)->state)
{
X->color = g_vpbGreen.at(i)->dx > 0 ? ICON_GREEN1 : ICON_GREEN2;
X->dx = (signed char)g_vpbGreen.at(i)->dx;
X->dy = (signed char)g_vpbGreen.at(i)->dy;
X->cx = (WORD)g_vpbGreen.at(i)->rc.left;
X->cy = (WORD)g_vpbGreen.at(i)->rc.top;
}
else
{
X->color = ICON_PWNED1;
X->dx = 0;
X->dy = 0;
X->cx = (WORD)g_vpbGreen.at(i)->rc.left;
X->cy = (WORD)g_vpbGreen.at(i)->rc.top;
}
++j;
}
n = g_vpbRed.size();
for (i = 0; i < n; ++i)
{
if (g_vpbRed.at(i)->state)
{
X->color = g_vpbRed.at(i)->dx > 0 ? ICON_RED1 : ICON_RED2;
X->dx = (signed char)g_vpbRed.at(i)->dx;
X->dy = (signed char)g_vpbRed.at(i)->dy;
X->cx = (WORD)g_vpbRed.at(i)->rc.left;
X->cy = (WORD)g_vpbRed.at(i)->rc.top;
}
else
{
X->color = ICON_PWNED1;
X->dx = 0;
X->dy = 0;
X->cx = (WORD)g_vpbRed.at(i)->rc.left;
X->cy = (WORD)g_vpbRed.at(i)->rc.top;
}
++j;
}
n = g_vpbYellow.size();
for (i = 0; i < n; ++i)
{
if (g_vpbYellow.at(i)->state)
{
X->color = g_vpbYellow.at(i)->dx > 0 ? ICON_YELLOW1 : ICON_YELLOW2;
X->dx = (signed char)g_vpbYellow.at(i)->dx;
X->dy = (signed char)g_vpbYellow.at(i)->dy;
X->cx = (WORD)g_vpbYellow.at(i)->rc.left;
X->cy = (WORD)g_vpbYellow.at(i)->rc.top;
}
else
{
X->color = ICON_PWNED1;
X->dx = 0;
X->dy = 0;
X->cx = (WORD)g_vpbYellow.at(i)->rc.left;
X->cy = (WORD)g_vpbYellow.at(i)->rc.top;
}
++j;
}
n = g_vpf.size();
for (i = 0; i < n; ++i)
{
if (g_vpf.at(i)->state)
{
X->color = ICON_ORANGE1;
X->dx = (signed char)g_vpf.at(i)->dx;
X->dy = (signed char)g_vpf.at(i)->dy;
X->cx = (WORD)g_vpf.at(i)->rc.left;
X->cy = (WORD)g_vpf.at(i)->rc.top;
}
else
{
X->color = ICON_PWNED2;
X->dx = 0;
X->dy = 0;
X->cx = (WORD)g_vpf.at(i)->rc.left;
X->cy = (WORD)g_vpf.at(i)->rc.top;
}
++j;
}
n = g_vps.size();
for (i = 0; i < n; ++i)
{
X->color = ICON_SKULL;
X->dx = (signed char)g_vps.at(i)->dx;
X->dy = (signed char)g_vps.at(i)->dy;
X->cx = (WORD)g_vps.at(i)->rc.left;
X->cy = (WORD)g_vps.at(i)->rc.top;
++j;
}
#undef X
((PTCPPACK)pbuf)->msgtype = TPH_SYNBALL;
((PTCPPACK)pbuf)->to = (BYTE)nIndex;
((PTCPPACK)pbuf)->msglen = (WORD)(j * sizeof(BALLCOREINFO));
if (toall)
SPushAll((PTCPPACK)pbuf);
else
SPush((PTCPPACK)pbuf, nIndex);
}
// Player Position
VOID SSynchronizePlayerPos(INT nIndex, BOOL toall)
{
char pbuf[512];
int i, j;
#define X ((PPLAYERSTATE)((PTCPPACK)pbuf + 1) + j)
j = 0;
for (i = 0; i < SIZE_PLAYERS; ++i)
{
if (g_vPlayers.at(i).state)
{
X->id = (BYTE)i;
X->state = g_vPlayers.at(i).state;
X->arrow = g_vPlayers.at(i).arrow;
X->cx = (WORD)g_vPlayers.at(i).rc.left;
X->cy = (WORD)g_vPlayers.at(i).rc.top;
X->blue = g_vPlayers.at(i).blue;
X->green = g_vPlayers.at(i).green;
X->red = g_vPlayers.at(i).red;
X->yellow = g_vPlayers.at(i).yellow;
++j;
}
}
#undef X
((PTCPPACK)pbuf)->msgtype = TPH_SYNPLAYER;
((PTCPPACK)pbuf)->to = (BYTE)nIndex;
((PTCPPACK)pbuf)->msglen = (WORD)(j * sizeof(PLAYERSTATE));
if (toall)
SPushAll((PTCPPACK)pbuf);
else
SPush((PTCPPACK)pbuf, nIndex);
}
////////////////////////////////////////////////////////////
//
// SSynPosition
VOID SSynPosition()
{
static INT nCount;
switch (++nCount)
{
case 15:
if (g_sTcp[1])
{
SSynchronizePlayerPos(1, FALSE);
break;
}
// fall through
case 25:
if (g_sTcp[1])
{
SSynchronizeBall(1, FALSE);
break;
}
else
nCount = 40;
// fall through
case 40:
if (g_sTcp[2])
{
SSynchronizePlayerPos(2, FALSE);
break;
}
// fall through
case 50:
if (g_sTcp[2])
{
SSynchronizeBall(2, FALSE);
break;
}
else
nCount = 65;
// fall through
case 65:
if (g_sTcp[3])
{
SSynchronizePlayerPos(3, FALSE);
break;
}
// fall through
case 75:
if (g_sTcp[3])
{
SSynchronizeBall(3, FALSE);
break;
}
else
nCount = 90;
// fall through
case 90:
if (g_sTcp[4])
{
SSynchronizePlayerPos(4, FALSE);
break;
}
// fall through
case 100:
if (g_sTcp[4])
{
SSynchronizeBall(4, FALSE);
break;
}
else
nCount = 115;
// fall through
case 115:
if (g_sTcp[5])
{
SSynchronizePlayerPos(5, FALSE);
break;
}
// fall through
case 125:
if (g_sTcp[5])
SSynchronizeBall(5, FALSE);
break;
case 126:
nCount = 0;
break;
}
}
////////////////////////////////////////////////////////////
//
// SSynAndGo
VOID SSynAndGo()
{
SSynchronizeBall(0, TRUE);
SSynchronizePlayerPos(0, TRUE);
SPushDword(TPH_RUNMAP, 0);
}