Click here to Skip to main content
15,896,524 members
Articles / Multimedia / GDI

A Bicho Hunting Multiplayer Game

Rate me:
Please Sign up or sign in to vote.
4.09/5 (6 votes)
18 Feb 2010CPOL7 min read 20.7K   972   13  
A practice of using Windows GDI and Winsock.
//
// ����˸������ݴ���
//

// 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);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions