Topic: Source Duel System S4
Source Duel System S4
DuelManager.h
#pragma once
#include "user.h"
#include "..includeprodef.h"
#include "DarkSpirit.h"
#include "GameMain.h"
#define DUEL_WIN_POINT_COUNT 10
#define MAX_DUEL_ROOMS 4
#define MAX_DUEL_LEARNERS 10
#define DUEL_TIME 30 // 15 minutos
////////////////////////////////////////////////////////////////////////////////////////////////
// PROTOCOL PACKETS
////////////////////////////////////////////////////////////////////////////////////////////////
#pragma pack(1)
struct PMSG_DUEL_ANSWER_START
{
PBMSG_HEAD2 h;
bool bDuelOK;
BYTE NumberH;
BYTE NumberL;
char szName[10];
};
struct PMSG_DUEL_START
{
PBMSG_HEAD2 h; // C1:AA
BYTE bDuelStart; // 3
BYTE NumberH; // 4
BYTE NumberL; // 5
char szName[10]; // 6
};
struct PMSG_DUEL_REQUEST_END
{
PBMSG_HEAD2 h;
BYTE NumberH; // 3
BYTE NumberL; // 4
char szName[10]; // 6
};
struct PMSG_DUEL_REQUEST_WATCH // 0x07
{
PBMSG_HEAD2 h;
BYTE btRoomIndex;
BYTE btRandomValue;
};
// SERVER -> CLIENT
struct PMSG_DUEL_QUESTION_START // 0x01
{
PBMSG_HEAD2 h;
BYTE NumberH;
BYTE NumberL;
BYTE szName[10];
};
struct PMSG_DUEL_REQUEST_START // 0x02
{
PBMSG_HEAD2 h;
BYTE NumberH; // 3
BYTE NumberL; // 4
char szName[10]; // 5
};
struct PMSG_DUEL_END // 0x03
{
PBMSG_HEAD2 h;
};
struct PMSG_DUEL_SCORE // 0x04
{
PBMSG_HEAD2 h;
BYTE NumberH1;
BYTE NumberL1;
BYTE NumberH2;
BYTE NumberL2;
BYTE btDuelScore1;
BYTE btDuelScore2;
};
struct PMSG_DUEL_LIFEBAR_REFILL // 0x05
{
PBMSG_HEAD2 h;
BYTE btObjId01H;
BYTE btObjId01L;
BYTE btObjId02H;
BYTE btObjId02L;
BYTE btLife01;
BYTE btLife02;
BYTE btShield01;
BYTE btShield02;
};
struct PMSG_DUEL_ROOMSTATUS // Complemento de 0x06
{
BYTE szName1[10];
BYTE szName2[10];
BYTE btDuelRunning;
BYTE btDuelOpen;
};
struct PMSG_DUEL_STATUS // 0x06
{
PBMSG_HEAD2 h;
PMSG_DUEL_ROOMSTATUS pRoomStatus[MAX_DUEL_ROOMS];
};
struct PMSG_DUEL_LIFEBAR_NAME // 0x07 00
{
PBMSG_HEAD2 h;
WORD Type; // 4
BYTE szName1[10]; // 5
BYTE szName2[10]; // f
BYTE btObjId1H;
BYTE btObjId1L;
BYTE btObjId2H;
BYTE btObjId2L;
};
struct PMSG_DUEL_SPEC_ADD // 0x08
{
PBMSG_HEAD2 h;
BYTE szName[10];
};
struct PMSG_DUEL_SPEC_DELEX // 0x09 - confirmar
{
PBMSG_HEAD2 h;
BYTE szName[10];
};
struct PMSG_DUEL_SPEC_DEL // 0x0A
{
PBMSG_HEAD2 h;
BYTE szName[10];
};
struct PMSG_DUEL_SPEC_LIST // 0x0B
{
PBMSG_HEAD2 h;
BYTE btCount;
BYTE szName[MAX_DUEL_LEARNERS][10];
};
struct PMSG_DUEL_FINISH // 0x0C
{
PBMSG_HEAD2 h;
BYTE szWinner[10];
BYTE szLooser[10];
};
struct PMSG_DUEL_LIFEBAR_INIT // 0x0D
{
PBMSG_HEAD2 h;
BYTE Unknow00;
};
#pragma pack()
////////////////////////////////////////////////////////////////////////////////////////////////
// END PROTOCOL PACKETS
////////////////////////////////////////////////////////////////////////////////////////////////
struct DUEL_ROOM
{
BOOL bFree;
BOOL bWaiting;
LPOBJ lpObj01;
BYTE btPoints01;
LPOBJ lpObj02;
BYTE btPoints02;
LPOBJ lpLearners[MAX_DUEL_LEARNERS];
DWORD dwTickCount;
DWORD dwStartTime;
BOOL bHasWinner;
};
static const struct DUEL_RESPAWN_RECTS
{
int LowX;
int LowY;
int HighX;
int HighY;
}
g_DuelRespawns [MAX_DUEL_ROOMS] =
{
{ 89, 62, 110, 81 },
{ 89, 113, 110, 130 },
{ 141, 63, 163, 82 },
{ 142, 111, 163, 131 }
};
class CDuelManager
{
private:
DWORD m_UpdateTickCount;
DWORD m_UpdateLifebarTime;
public:
DUEL_ROOM m_Rooms[MAX_DUEL_ROOMS];
CDuelManager(void);
~CDuelManager(void);
void Run();
void ProtocolCore(LPOBJ lpObj, BYTE* lpPacket);
void KillUserProc ( LPOBJ lpObj, LPOBJ lpTarget);
int GetUserDuelRoom(LPOBJ lpObj);
int GetFreeRoomIndex();
bool IsDuelEnable(int aIndex);
bool DuelCheck(LPOBJ lpObj) { return this->IsOnDuel(lpObj->m_Index); }
bool DuelCheck(LPOBJ lpObj, LPOBJ lpObj2) { return this->IsOnDuel(lpObj->m_Index, lpObj2->m_Index); }
void UserDuelInfoReset(LPOBJ lpObj);
void RoomReset(int iRoom, bool dontMove = false, bool dontSendEnd = false);
void RemoveUser(LPOBJ lpObj);
void SetDuelOption(int lpObj, BOOL bState);
bool IsOnDuel(int lpObj);
bool IsOnDuel(int lpObj, int lpObj2);
void PlayerScore(LPOBJ lpObj);
int GetSpectatorCount(int iRoom);
void SendDuelStatus(LPOBJ lpObj);
void UpdateDuelScore(int iRoom);
void RecvDuelRequest(LPOBJ lpObj, PMSG_DUEL_REQUEST_START* lpMsg);
void RecvDuelAnswer(LPOBJ lpObj, PMSG_DUEL_ANSWER_START* lpMsg);
void RecvWatchRequest(LPOBJ lpObj, PMSG_DUEL_REQUEST_WATCH* lpMsg);
void SendRefuseDuel(LPOBJ lpObj)
{
if(lpObj == NULL) return;
PMSG_DUEL_START pMsgSend;
pMsgSend.h.c = 0xC1;
pMsgSend.h.headcode = 0xAA;
pMsgSend.h.subcode = 0x01;
pMsgSend.bDuelStart = 0x0F;
pMsgSend.h.size = sizeof(pMsgSend);
DataSend(lpObj->m_Index, (BYTE*)&pMsgSend, pMsgSend.h.size);
}
void SendEndDuel(LPOBJ lpObj);
void SendEndDuelNotification(LPOBJ lpObj, char* Winner, char* Looser);
void SendLifebarStatus(int iRoom);
void SendLifebarStatus(LPOBJ lpObj, int iRoom);
void SendLifebarInit(LPOBJ lpObj, int iRoom);
void SendSpectatorList(int iRoom);
void SendSpectatorList(LPOBJ lpObj, int iRoom);
void SendSpectatorAdd(int iSpecIndex, int iRoom);
void SendSpectatorRemove(int iSpecIndex, int iRoom);
};
extern CDuelManager g_DuelManager;
DuelManager.cpp
#include "stdafx.h"
#include "user.h"
#include "protocol.h"
#include "..includeprodef.h"
#include "..commonwinutil.h"
#include "LogProc.h"
#include "DuelManager.h"
#include "GameMain.h"
#include "IllusionTemple.h"
#include "BloodCastle.h"
#include "ChaosCastle.h"
#include "DevilSquare.h"
#include "DarkSpirit.h"
#include "ObjUseSkill.h"
static const struct DUEL_GATES
{
int UserGate01;
int UserGate02;
int LearnerGate;
}
g_DuelGates[MAX_DUEL_ROOMS] =
{
{ 295, 296, 303 },
{ 297, 298, 304 },
{ 299, 300, 305 },
{ 301, 302, 306 }
};
CDuelManager g_DuelManager;
CDuelManager::CDuelManager(void)
{
ZeroMemory(&this->m_Rooms, sizeof(this->m_Rooms));
for(int i = 0; i < MAX_DUEL_ROOMS; i++)
{
this->m_Rooms[i].bFree = true;
this->m_Rooms[i].bWaiting = false;
this->m_Rooms[i].bHasWinner = false;
}
}
CDuelManager::~CDuelManager(void)
{
}
int CDuelManager::GetUserDuelRoom(LPOBJ lpObj)
{
for(int i = 0; i < MAX_DUEL_ROOMS; i++)
{
if(this->m_Rooms[i].lpObj01 == lpObj ||
this->m_Rooms[i].lpObj02 == lpObj)
{
return i;
}
}
return -1;
}
void CDuelManager::Run()
{
for(int i = 0; i < MAX_DUEL_ROOMS; i++)
{
if(this->m_Rooms[i].bFree == FALSE)
{
if(GetTickCount() - this->m_Rooms[i].dwStartTime < 5000) continue;
for(int u = 0; u < MAX_DUEL_LEARNERS; u++)
{
if(this->m_Rooms[i].lpLearners[u] == NULL) continue;
if(gObjIsConnected(this->m_Rooms[i].lpLearners[u]->m_Index))
{
if(this->m_Rooms[i].lpLearners[u]->MapNumber != MAP_INDEX_VULCANROOM)
{
this->SendEndDuel(this->m_Rooms[i].lpLearners[u]);
GCStateInfoSend(this->m_Rooms[i].lpLearners[u], 0, eVS_INVISIBLE);
GCStateInfoSend(this->m_Rooms[i].lpLearners[u], 0, eVS_TRANSPARENCY);
GCStateInfoSend(this->m_Rooms[i].lpLearners[u], 0, eVS_DUEL_INTERFACE);
LogAddTD("[Duel Manager] Spectator (%s) leaves room %d", this->m_Rooms[i].lpLearners[u]->Name, i + 1);
this->SendSpectatorRemove(u, i);
this->m_Rooms[i].lpLearners[u] = NULL;
}
}
else
{
LogAddTD("[Duel Manager] Some spectator leaves room %d", this->m_Rooms[i].lpLearners[u]->Name, i + 1);
this->m_Rooms[i].lpLearners[u] = NULL;
this->SendSpectatorList(i);
}
}
if(this->m_Rooms[i].lpObj01 != NULL && this->m_Rooms[i].lpObj02 != NULL)
{
if(gObjIsConnected(this->m_Rooms[i].lpObj01->m_Index) == FALSE ||
gObjIsConnected(this->m_Rooms[i].lpObj02->m_Index) == FALSE)
{
this->RoomReset(i);
continue;
}
else if ((this->m_Rooms[i].lpObj01->MapNumber != MAP_INDEX_VULCANROOM ||
this->m_Rooms[i].lpObj02->MapNumber != MAP_INDEX_VULCANROOM) &&
this->m_Rooms[i].bHasWinner == FALSE)
{
this->RoomReset(i);
continue;
}
else if (this->m_Rooms[i].lpObj01->Connected < PLAYER_PLAYING ||
this->m_Rooms[i].lpObj02->Connected < PLAYER_PLAYING)
{
this->RoomReset(i);
continue;
}
}
else
{
this->RoomReset(i);
continue;
}
if(this->m_UpdateLifebarTime < GetTickCount())
{
this->SendLifebarStatus(i);
this->m_UpdateLifebarTime = GetTickCount() + 2000;
}
if(this->m_Rooms[i].dwTickCount != 0)
{
if(this->m_Rooms[i].dwTickCount < GetTickCount())
{
this->RoomReset(i);
LogAddTD("[Duel Manager] Room %d cleaned.", i+1);
}
}
}
}
if(this->m_UpdateTickCount < GetTickCount())
{
for(int i = OBJ_STARTUSERINDEX; i < OBJMAX; i++)
{
if((gObj[i].m_IfState.use) && gObj[i].m_IfState.type == 20)
{
this->SendDuelStatus(&gObj[i]);
}
}
this->m_UpdateTickCount = GetTickCount() + 6000;
}
return;
}
void CDuelManager::UpdateDuelScore(int iRoom)
{
if(iRoom < 0 || iRoom > MAX_DUEL_ROOMS - 1)
return;
if(this->m_Rooms[iRoom].lpObj01 == NULL || this->m_Rooms[iRoom].lpObj02 == NULL) return;
int aIndex1 = this->m_Rooms[iRoom].lpObj01->m_Index;
int aIndex2 = this->m_Rooms[iRoom].lpObj02->m_Index;
if ( !OBJMAX_RANGE(aIndex1) || !OBJMAX_RANGE(aIndex2))
return;
if ( !gObjIsConnected(aIndex1) || !gObjIsConnected(aIndex2) )
return;
if ( gObj[aIndex1].Type == OBJ_MONSTER || gObj[aIndex2].Type == OBJ_MONSTER )
return;
if ( gObj[aIndex1].CloseCount >= 0 || gObj[aIndex2].CloseCount >= 0 )
return;
PMSG_DUEL_SCORE pMsg;
pMsg.h.c = 0xC1;
pMsg.h.size = sizeof(pMsg);
pMsg.h.headcode = 0xAA;
pMsg.h.subcode = 0x04;
pMsg.NumberH1 = SET_NUMBERH(aIndex1);
pMsg.NumberL1 = SET_NUMBERL(aIndex1);
pMsg.NumberH2 = SET_NUMBERH(aIndex2);
pMsg.NumberL2 = SET_NUMBERL(aIndex2);
pMsg.btDuelScore1 = this->m_Rooms[iRoom].btPoints01;
pMsg.btDuelScore2 = this->m_Rooms[iRoom].btPoints02;
DataSend(aIndex1, (LPBYTE)&pMsg, pMsg.h.size);
DataSend(aIndex2, (LPBYTE)&pMsg, pMsg.h.size);
for(int i = 0; i < MAX_DUEL_LEARNERS; i++)
{
if(this->m_Rooms[iRoom].lpLearners[i] == NULL)
{
continue;
}
DataSend(this->m_Rooms[iRoom].lpLearners[i]->m_Index, (LPBYTE)&pMsg, pMsg.h.size);
}
}
void CDuelManager::PlayerScore(LPOBJ lpObj)
{
int iRoom = this->GetUserDuelRoom(lpObj);
if(iRoom >= 0 && iRoom < MAX_DUEL_ROOMS)
{
if(this->m_Rooms[iRoom].lpObj01 == lpObj)
{
this->m_Rooms[iRoom].btPoints01++;
this->UpdateDuelScore(iRoom);
}
else if(this->m_Rooms[iRoom].lpObj02 == lpObj)
{
this->m_Rooms[iRoom].btPoints02++;
this->UpdateDuelScore(iRoom);
}
}
}
void CDuelManager::SendEndDuel(LPOBJ lpObj)
{
if(lpObj == NULL) return;
if(gObjIsConnected(lpObj->m_Index) == FALSE) return;
BYTE lpMsgClose[5] = { 0xC1, 0x05, 0xAA, 0x03, 0x00 } ;
DataSend(lpObj->m_Index, &lpMsgClose[0], lpMsgClose[1]);
}
int CDuelManager::GetSpectatorCount(int iRoom)
{
if(iRoom < 0 || iRoom >= MAX_DUEL_ROOMS)
{
return -1;
}
int iCount = 0;
for(int i = 0; i < MAX_DUEL_LEARNERS; i++)
{
if(this->m_Rooms[iRoom].lpLearners[i] != NULL)
{
iCount++;
}
}
return iCount;
}
void CDuelManager::RemoveUser(LPOBJ lpObj)
{
//verificar se faz parte do duel
//verificar se eh da batalha...
// -> se for, finalizar a sala
//resetar informações do duel
//se for um watcher remover interface
//mover para gate 294
}
void CDuelManager::SendDuelStatus(LPOBJ lpObj)
{
PMSG_DUEL_STATUS pMsg;
pMsg.h.c = 0xC1;
pMsg.h.size = sizeof(pMsg);
pMsg.h.headcode = 0xAA;
pMsg.h.subcode = 0x06;
ZeroMemory(&pMsg.pRoomStatus, sizeof(pMsg.pRoomStatus));
for(int i = 0; i < MAX_DUEL_ROOMS; i++)
{
if(this->m_Rooms[i].bFree == FALSE)
{
if(this->m_Rooms[i].lpObj01 == NULL || this->m_Rooms[i].lpObj02 == NULL)
{
continue;
}
pMsg.pRoomStatus[i].btDuelRunning = TRUE;
int iSpecCount = this->GetSpectatorCount(i);
if(iSpecCount < 0 || iSpecCount >= 10)
{
pMsg.pRoomStatus[i].btDuelOpen = FALSE;
}
else
{
pMsg.pRoomStatus[i].btDuelOpen = TRUE;
}
memcpy(&pMsg.pRoomStatus[i].szName1[0], &this->m_Rooms[i].lpObj01->Name[0], 10);
memcpy(&pMsg.pRoomStatus[i].szName2[0], &this->m_Rooms[i].lpObj02->Name[0], 10);
}
}
DataSend(lpObj->m_Index, (BYTE*)&pMsg, pMsg.h.size);
}
int CDuelManager::GetFreeRoomIndex()
{
for(int i = 0; i < MAX_DUEL_ROOMS; i++)
{
if(this->m_Rooms[i].bFree == TRUE)
{
if(this->m_Rooms[i].bWaiting == FALSE)
{
return i;
}
}
}
return -1;
}
void CDuelManager::UserDuelInfoReset(LPOBJ lpObj)
{
if(lpObj == NULL)
{
return;
}
lpObj->m_iDuelRoom = -1;
lpObj->m_iDuelUser = -1;
lpObj->m_iDuelUserRequested = -1;
lpObj->m_iDuelUserReserved = -1;
lpObj->m_btDuelScore = 0;
gDarkSpirit[lpObj->m_Index].ReSetTarget(lpObj->m_Index);
}
void CDuelManager::RoomReset(int iRoom, bool dontMove, bool dontSendEnd)
{
if(this->m_Rooms[iRoom].lpObj01 != NULL)
{
if(gObjIsConnected(this->m_Rooms[iRoom].lpObj01->m_Index))
{
if(dontSendEnd == false)
this->SendEndDuel(this->m_Rooms[iRoom].lpObj01);
if(this->m_Rooms[iRoom].lpObj01->MapNumber == MAP_INDEX_VULCANROOM)
{
if(dontMove == false)
gObjMoveGate(this->m_Rooms[iRoom].lpObj01->m_Index, 294);
}
}
this->UserDuelInfoReset(this->m_Rooms[iRoom].lpObj01);
}
if(this->m_Rooms[iRoom].lpObj02 != NULL)
{
if(gObjIsConnected(this->m_Rooms[iRoom].lpObj02->m_Index))
{
if(dontSendEnd == false)
this->SendEndDuel(this->m_Rooms[iRoom].lpObj02);
if(this->m_Rooms[iRoom].lpObj02->MapNumber == MAP_INDEX_VULCANROOM)
{
if(dontMove == false)
gObjMoveGate(this->m_Rooms[iRoom].lpObj02->m_Index, 294);
}
}
this->UserDuelInfoReset(this->m_Rooms[iRoom].lpObj02);
}
for(int i = 0; i < MAX_DUEL_LEARNERS; i++)
{
if(this->m_Rooms[iRoom].lpLearners[i] != NULL)
{
this->SendEndDuel(this->m_Rooms[iRoom].lpLearners[i]);
GCStateInfoSend(this->m_Rooms[iRoom].lpLearners[i], 0, eVS_INVISIBLE);
GCStateInfoSend(this->m_Rooms[iRoom].lpLearners[i], 0, eVS_TRANSPARENCY);
GCStateInfoSend(this->m_Rooms[iRoom].lpLearners[i], 0, eVS_DUEL_INTERFACE);
gObjMoveGate(this->m_Rooms[iRoom].lpLearners[i]->m_Index, 294);
}
this->m_Rooms[iRoom].lpLearners[i] = NULL;
}
this->m_Rooms[iRoom].lpObj01 = NULL;
this->m_Rooms[iRoom].btPoints01 = 0;
this->m_Rooms[iRoom].lpObj02 = NULL;
this->m_Rooms[iRoom].btPoints02 = 0;
this->m_Rooms[iRoom].bFree = TRUE;
this->m_Rooms[iRoom].bWaiting = FALSE;
this->m_Rooms[iRoom].bHasWinner = FALSE;
this->m_Rooms[iRoom].dwTickCount = 0;
this->m_Rooms[iRoom].dwStartTime = 0;
LogAddTD("[Duel Manager] Room Reset - Number: %d", iRoom + 1);
}
void CDuelManager::SendEndDuelNotification(LPOBJ lpObj, char* Winner, char* Looser)
{
PMSG_DUEL_FINISH pMsg;
pMsg.h.c = 0xC1;
pMsg.h.size = sizeof(pMsg);
pMsg.h.headcode = 0xAA;
pMsg.h.subcode = 0x0C;
memcpy(pMsg.szWinner, Winner, 10);
memcpy(pMsg.szLooser, Looser, 10);
DataSend(lpObj->m_Index, (BYTE*)&pMsg, pMsg.h.size);
}
void CDuelManager::SendSpectatorAdd(int iSpecIndex, int iRoom)
{
if(iRoom < 0 || iRoom >= MAX_DUEL_ROOMS)
{
return;
}
if(iSpecIndex < 0 || iSpecIndex >= MAX_DUEL_LEARNERS)
{
return;
}
if(this->m_Rooms[iRoom].lpLearners[iSpecIndex] == NULL) return;
if(this->m_Rooms[iRoom].lpObj01 == NULL ||
this->m_Rooms[iRoom].lpObj02 == NULL)
{
return;
}
PMSG_DUEL_SPEC_ADD pMsg;
pMsg.h.c = 0xC1;
pMsg.h.size = sizeof(pMsg);
pMsg.h.headcode = 0xAA;
pMsg.h.subcode = 0x08;
memcpy(pMsg.szName, this->m_Rooms[iRoom].lpLearners[iSpecIndex]->Name, 10);
for(int i = 0; i < MAX_DUEL_LEARNERS; i++)
{
if(i == iSpecIndex) continue;
if(this->m_Rooms[iRoom].lpLearners[i] != NULL)
{
DataSend(this->m_Rooms[iRoom].lpLearners[i]->m_Index, (BYTE*)&pMsg, pMsg.h.size);
}
}
}
void CDuelManager::SendSpectatorRemove(int iSpecIndex, int iRoom)
{
if(iRoom < 0 || iRoom >= MAX_DUEL_ROOMS)
{
return;
}
if(iSpecIndex < 0 || iSpecIndex >= MAX_DUEL_LEARNERS)
{
return;
}
if(this->m_Rooms[iRoom].lpLearners[iSpecIndex] == NULL) return;
if(this->m_Rooms[iRoom].lpObj01 == NULL ||
this->m_Rooms[iRoom].lpObj02 == NULL)
{
return;
}
PMSG_DUEL_SPEC_ADD pMsg;
pMsg.h.c = 0xC1;
pMsg.h.size = sizeof(pMsg);
pMsg.h.headcode = 0xAA;
pMsg.h.subcode = 0x0A;
memcpy(pMsg.szName, this->m_Rooms[iRoom].lpLearners[iSpecIndex]->Name, 10);
for(int i = 0; i < MAX_DUEL_LEARNERS; i++)
{
if(i == iSpecIndex) continue;
if(this->m_Rooms[iRoom].lpLearners[i] != NULL)
{
DataSend(this->m_Rooms[iRoom].lpLearners[i]->m_Index, (BYTE*)&pMsg, pMsg.h.size);
}
}
}
void CDuelManager::SendSpectatorList(int iRoom)
{
if(iRoom < 0 || iRoom >= MAX_DUEL_ROOMS)
{
return;
}
if(this->m_Rooms[iRoom].bFree == FALSE)
{
for(int u = 0; u < MAX_DUEL_LEARNERS; u++)
{
if(this->m_Rooms[iRoom].lpLearners[u] != NULL)
{
this->SendSpectatorList(this->m_Rooms[iRoom].lpLearners[u], iRoom);
}
}
}
}
void CDuelManager::SendSpectatorList(LPOBJ lpObj, int iRoom)
{
if(iRoom < 0 || iRoom >= MAX_DUEL_ROOMS)
{
return;
}
if(this->m_Rooms[iRoom].lpObj01 == NULL ||
this->m_Rooms[iRoom].lpObj02 == NULL)
{
return;
}
PMSG_DUEL_SPEC_LIST pMsg;
pMsg.h.c = 0xC1;
pMsg.h.headcode = 0xAA;
pMsg.h.subcode = 0x0B;
pMsg.btCount = 0;
if(this->m_Rooms[iRoom].bFree == FALSE)
{
for(int u = 0; u < MAX_DUEL_LEARNERS; u++)
{
if(this->m_Rooms[iRoom].lpLearners[u] != NULL)
{
memcpy(&pMsg.szName[pMsg.btCount++][0], this->m_Rooms[iRoom].lpLearners[u]->Name, 10);
}
}
}
pMsg.h.size = 5 + (pMsg.btCount * 10);
DataSend(lpObj->m_Index, (BYTE*)&pMsg, pMsg.h.size);
}
void CDuelManager::SendLifebarStatus(int iRoom)
{
if(iRoom < 0 || iRoom >= MAX_DUEL_ROOMS)
{
return;
}
if(this->m_Rooms[iRoom].lpObj01 == NULL ||
this->m_Rooms[iRoom].lpObj02 == NULL)
{
return;
}
if(this->m_Rooms[iRoom].bFree == FALSE)
{
for(int u = 0; u < MAX_DUEL_LEARNERS; u++)
{
if(this->m_Rooms[iRoom].lpLearners[u] != NULL)
{
this->SendLifebarStatus(this->m_Rooms[iRoom].lpLearners[u], iRoom);
}
}
}
}
void CDuelManager::SendLifebarStatus(LPOBJ lpObj, int iRoom)
{
if(iRoom < 0 || iRoom >= MAX_DUEL_ROOMS)
{
return;
}
if(this->m_Rooms[iRoom].lpObj01 == NULL ||
this->m_Rooms[iRoom].lpObj02 == NULL)
{
return;
}
PMSG_DUEL_LIFEBAR_REFILL pMsg;
pMsg.h.c = 0xC1;
pMsg.h.size = sizeof(pMsg);
pMsg.h.headcode = 0xAA;
pMsg.h.subcode = 0x05;
pMsg.btObjId01H = HIBYTE(this->m_Rooms[iRoom].lpObj01->m_Index);
pMsg.btObjId01L = LOBYTE(this->m_Rooms[iRoom].lpObj01->m_Index);
pMsg.btObjId02H = HIBYTE(this->m_Rooms[iRoom].lpObj02->m_Index);
pMsg.btObjId02L = LOBYTE(this->m_Rooms[iRoom].lpObj02->m_Index);
pMsg.btLife01 = this->m_Rooms[iRoom].lpObj01->Life / ((this->m_Rooms[iRoom].lpObj01->MaxLife + this->m_Rooms[iRoom].lpObj01->AddLife) / 100);
pMsg.btLife02 = this->m_Rooms[iRoom].lpObj02->Life / ((this->m_Rooms[iRoom].lpObj02->MaxLife + this->m_Rooms[iRoom].lpObj02->AddLife) / 100);
pMsg.btShield01 = this->m_Rooms[iRoom].lpObj01->iShield / ((this->m_Rooms[iRoom].lpObj01->iMaxShield + this->m_Rooms[iRoom].lpObj01->iAddShield) / 100);
pMsg.btShield02 = this->m_Rooms[iRoom].lpObj02->iShield / ((this->m_Rooms[iRoom].lpObj02->iMaxShield + this->m_Rooms[iRoom].lpObj02->iAddShield) / 100);
DataSend(lpObj->m_Index, (BYTE*)&pMsg, pMsg.h.size);
}
void CDuelManager::SendLifebarInit(LPOBJ lpObj, int iRoom)
{
if(iRoom < 0 || iRoom >= MAX_DUEL_ROOMS)
{
return;
}
if(this->m_Rooms[iRoom].lpObj01 == NULL ||
this->m_Rooms[iRoom].lpObj02 == NULL)
{
return;
}
PMSG_DUEL_LIFEBAR_NAME pMsg2;
pMsg2.h.c = 0xC1;
pMsg2.h.size = sizeof(pMsg2);
pMsg2.h.headcode = 0xAA;
pMsg2.h.subcode = 0x07;
pMsg2.Type = 0x00;
memcpy(pMsg2.szName1, this->m_Rooms[iRoom].lpObj01->Name, 10);
memcpy(pMsg2.szName2, this->m_Rooms[iRoom].lpObj02->Name, 10);
pMsg2.btObjId1H = HIBYTE(this->m_Rooms[iRoom].lpObj01->m_Index);
pMsg2.btObjId1L = LOBYTE(this->m_Rooms[iRoom].lpObj01->m_Index);
pMsg2.btObjId2H = HIBYTE(this->m_Rooms[iRoom].lpObj02->m_Index);
pMsg2.btObjId2L = LOBYTE(this->m_Rooms[iRoom].lpObj02->m_Index);
DataSend(lpObj->m_Index, (BYTE*)&pMsg2, pMsg2.h.size);
PMSG_DUEL_LIFEBAR_INIT pMsg;
pMsg.h.c = 0xC1;
pMsg.h.size = sizeof(pMsg);
pMsg.h.headcode = 0xAA;
pMsg.h.subcode = 0x0D;
DataSend(lpObj->m_Index, (BYTE*)&pMsg, pMsg.h.size);
}
void CDuelManager::KillUserProc(LPOBJ lpObj, LPOBJ lpTarget)
{
if(!this->DuelCheck(lpObj, lpTarget)) return;
int iDuelRoom = this->GetUserDuelRoom(lpObj);
if(iDuelRoom == -1)
{
return;
}
lpTarget->KillerType = 3;
int Points = ((lpObj == this->m_Rooms[iDuelRoom].lpObj01) ? this->m_Rooms[iDuelRoom].btPoints01 : this->m_Rooms[iDuelRoom].btPoints02);
if(Points >= DUEL_WIN_POINT_COUNT)
{
this->m_Rooms[iDuelRoom].bHasWinner = TRUE;
this->SendEndDuel(lpTarget);
this->SendEndDuel(lpObj);
this->SendEndDuelNotification(lpTarget, lpObj->Name, lpTarget->Name);
this->SendEndDuelNotification(lpObj, lpObj->Name, lpTarget->Name);
gDarkSpirit[lpObj->m_Index].ReSetTarget(lpTarget->m_Index);
gDarkSpirit[lpTarget->m_Index].ReSetTarget(lpObj->m_Index);
char szMsg[256];
wsprintf(szMsg,lMsg.Get(1216),lpTarget->Name);
GCServerMsgStringSend(szMsg,lpObj->m_Index,1);
wsprintf(szMsg,lMsg.Get(1217),lpObj->Name);
GCServerMsgStringSend(szMsg,lpTarget->m_Index,1);
PMSG_SERVERCMD ServerCmd;
PHeadSubSetB((LPBYTE)&ServerCmd, 0xF3, 0x40, sizeof(ServerCmd));
ServerCmd.CmdType = 0;
ServerCmd.X = lpObj->X;
ServerCmd.Y = lpObj->Y;
MsgSendV2(lpObj,(unsigned char *)&ServerCmd,sizeof(ServerCmd));
DataSend(lpObj->m_Index,(unsigned char *)&ServerCmd,sizeof(ServerCmd));
gObjUseSkill.AddOrRemoveBuff(eVS_DUEL_MEDAL, lpObj->m_Index, TRUE);
this->m_Rooms[iDuelRoom].dwTickCount = GetTickCount() + 10000;
LogAdd("[Duel] [%s][%s] Win Duel, Loser [%s][%s]",lpObj->AccountID,lpObj->Name,lpTarget->AccountID,lpTarget->Name);
}
}
void CDuelManager::ProtocolCore(LPOBJ lpObj, BYTE* lpPacket)
{
PMSG_DEFAULT2* pMsg = (PMSG_DEFAULT2*)lpPacket;
switch(pMsg->subcode)
{
case 0x01:
this->RecvDuelRequest(lpObj, (PMSG_DUEL_REQUEST_START*)lpPacket);
break;
case 0x02:
this->RecvDuelAnswer(lpObj, (PMSG_DUEL_ANSWER_START*)lpPacket);
break;
case 0x07:
this->RecvWatchRequest(lpObj, (PMSG_DUEL_REQUEST_WATCH*)lpPacket);
break;
case 0x09:
if(lpObj->MapNumber == MAP_INDEX_VULCANROOM)
{
gObjMoveGate(lpObj->m_Index, 294); // vai pro vulcan map
}
break;
}
}
void CDuelManager::RecvWatchRequest(LPOBJ lpObj, PMSG_DUEL_REQUEST_WATCH* lpMsg)
{
if(lpObj->m_IfState.use == 0 || lpObj->m_IfState.type != 20)
{
return;
}
lpObj->m_IfState.use = 0;
lpObj->m_IfState.type = 0;
if(lpMsg->btRoomIndex >= 0 && lpMsg->btRoomIndex < MAX_DUEL_ROOMS)
{
if(this->m_Rooms[lpMsg->btRoomIndex].bFree == TRUE)
{
GCServerMsgStringSend("Não há ninguém no duelo que você está tentando assistir.", lpObj->m_Index, 1);
LogAddC(2, "[Duel Manager] (%s)(%s) Watch request error: wrong duel state! (%d)", lpObj->AccountID, lpObj->Name, lpMsg->btRoomIndex);
return;
}
for(int i = 0; i < MAX_DUEL_LEARNERS; i++)
{
if(this->m_Rooms[lpMsg->btRoomIndex].lpLearners[i] == NULL)
{
if(gObjMoveGate(lpObj->m_Index, g_DuelGates[lpMsg->btRoomIndex].LearnerGate))
{
this->m_Rooms[lpMsg->btRoomIndex].lpLearners[i] = lpObj;
this->SendSpectatorList(lpObj, lpMsg->btRoomIndex);
this->SendSpectatorAdd(i, lpMsg->btRoomIndex);
GCServerMsgStringSend("Você está agora na sala de duelo.", lpObj->m_Index, 1);
GCStateInfoSend(lpObj, 1, eVS_DUEL_INTERFACE);
GCStateInfoSend(lpObj, 1, eVS_TRANSPARENCY);
GCStateInfoSend(lpObj, 1, eVS_INVISIBLE, TRUE, TRUE);
this->SendLifebarInit(lpObj, lpMsg->btRoomIndex);
this->SendLifebarStatus(lpObj, lpMsg->btRoomIndex);
this->UpdateDuelScore(lpMsg->btRoomIndex);
return;
}
GCServerMsgStringSend("Impossível mover você.", lpObj->m_Index, 1);
return;
}
}
GCServerMsgStringSend("O duelo que você está tentando assistir já está cheio.", lpObj->m_Index, 1);
LogAddC(2, "[Duel Manager] (%s)(%s) Watch request error: room is full! (%d)", lpObj->AccountID, lpObj->Name, lpMsg->btRoomIndex);
return;
}
LogAddC(2, "[Duel Manager] (%s)(%s) Wrong room index! (%d)", lpObj->AccountID, lpObj->Name, lpMsg->btRoomIndex);
}
void CDuelManager::RecvDuelAnswer(LPOBJ lpObj, PMSG_DUEL_ANSWER_START* lpMsg)
{
int iDuelIndex = -1;
int iDuelRoom = lpObj->m_iDuelRoom;
PMSG_DUEL_START pMsgSend;
pMsgSend.h.c = 0xC1;
pMsgSend.h.headcode = 0xAA;
pMsgSend.h.subcode = 0x01;
pMsgSend.bDuelStart = 0;
pMsgSend.h.size = sizeof(pMsgSend);
if(iDuelRoom < 0 || iDuelRoom > MAX_DUEL_ROOMS - 1)
{
return;
}
if ( gObj[lpObj->m_Index].CloseType != -1 )
return;
iDuelIndex = MAKE_NUMBERW(lpMsg->NumberH, lpMsg->NumberL);
if ( OBJMAX_RANGE(iDuelIndex) )
{
if ( !gObjIsConnected(iDuelIndex) )
return;
if ( gObj[iDuelIndex].Type == OBJ_MONSTER )
return;
if ( gObj[iDuelIndex].CloseCount >= 0 )
return;
if ( lpMsg->bDuelOK )
{
if ( BC_MAP_RANGE(gObj[iDuelIndex].MapNumber) ||
CC_MAP_RANGE(gObj[iDuelIndex].MapNumber) ||
DS_MAP_RANGE(gObj[iDuelIndex].MapNumber) ||
IT_MAP_RANGE(gObj[iDuelIndex].MapNumber) )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 207)), lpObj->m_Index, 1);
this->RoomReset(iDuelRoom, true, true);
memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));
DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);
return;
}
}
if ( OBJMAX_RANGE(lpObj->m_iDuelUser ) )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 160)), lpObj->m_Index, 1);
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 161)), lpObj->m_Index, 1);
this->RoomReset(iDuelRoom, true, true);
memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));
DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);
return;
}
if ( OBJMAX_RANGE(lpObj->m_iDuelUserReserved) )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 173)), lpObj->m_Index, 1);
this->RoomReset(iDuelRoom, true, true);
memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));
DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);
return;
}
if ( gObj[iDuelIndex].m_iDuelUserReserved == lpObj->m_Index )
{
char szDuelName[MAX_ACCOUNT_LEN+1]={0};
char szDuelName2[MAX_ACCOUNT_LEN+1]={0};
memcpy(szDuelName, gObj[iDuelIndex].Name, MAX_ACCOUNT_LEN);
szDuelName[MAX_ACCOUNT_LEN] = 0;
memcpy(szDuelName2, lpMsg->szName, MAX_ACCOUNT_LEN);
szDuelName2[MAX_ACCOUNT_LEN] = 0;
if ( !strcmp(szDuelName, szDuelName2))
{
if ( lpMsg->bDuelOK == false)
{
this->RoomReset(iDuelRoom, true, true);
pMsgSend.bDuelStart = 0x0F;
memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));
DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);
}
else if ( lpMsg->bDuelOK == true )
{
if ( lpObj->Money < 30000 )
{
this->SendEndDuel(&gObj[iDuelIndex]);
this->RoomReset(iDuelRoom, true);
pMsgSend.bDuelStart = 0x0e;
pMsgSend.h.size = sizeof(pMsgSend);
DataSend(lpObj->m_Index, (BYTE*)&pMsgSend, pMsgSend.h.size);
return;
}
if(gObj[iDuelIndex].Money < 30000)
{
this->SendEndDuel(lpObj);
this->RoomReset(iDuelRoom, true);
pMsgSend.bDuelStart = 0x0e;
pMsgSend.h.size = sizeof(pMsgSend);
DataSend(iDuelIndex, (BYTE*)&pMsgSend, pMsgSend.h.size);
return;
}
if(gObjMoveGate(lpObj->m_Index, g_DuelGates[iDuelRoom].UserGate01) == false)
{
this->RoomReset(iDuelRoom, true, true);
return;
}
if(gObjMoveGate(iDuelIndex, g_DuelGates[iDuelRoom].UserGate02) == false)
{
this->RoomReset(iDuelRoom, true, true);
return;
}
lpObj->Money -= 30000;
GCMoneySend(lpObj->m_Index, lpObj->Money);
gObj[iDuelIndex].Money -= 30000;
GCMoneySend(iDuelIndex, gObj[iDuelIndex].Money);
gObj[iDuelIndex].m_iDuelUserReserved = -1;
gObj[iDuelIndex].m_btDuelScore = 0;
gObj[iDuelIndex].m_iDuelUser = lpObj->m_Index;
this->m_Rooms[iDuelRoom].dwStartTime = GetTickCount();
this->m_Rooms[iDuelRoom].dwTickCount = GetTickCount() + (DUEL_TIME * 60000);
lpObj->m_iDuelUserRequested = -1;
lpObj->m_iDuelUserReserved = -1;
lpObj->m_btDuelScore = 0;
lpObj->m_iDuelUser = iDuelIndex;
this->m_Rooms[iDuelRoom].bFree = FALSE;
this->m_Rooms[iDuelRoom].bWaiting = FALSE;
this->m_Rooms[iDuelRoom].bHasWinner = FALSE;
pMsgSend.bDuelStart = 0;
pMsgSend.NumberH = SET_NUMBERH(iDuelIndex);
pMsgSend.NumberL = SET_NUMBERL(iDuelIndex);
memcpy(pMsgSend.szName, szDuelName, sizeof(pMsgSend.szName));
DataSend(lpObj->m_Index, (LPBYTE)&pMsgSend, pMsgSend.h.size);
pMsgSend.NumberH = SET_NUMBERH(lpObj->m_Index);
pMsgSend.NumberL = SET_NUMBERL(lpObj->m_Index);
memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));
DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);
this->UpdateDuelScore(iDuelRoom);
LogAddTD("[Duel] [%s][%s] Duel Started [%s][%s] on Room [%d]", lpObj->AccountID, lpObj->Name,
gObj[iDuelIndex].AccountID, gObj[iDuelIndex].Name, iDuelRoom + 1);
}
}
else
{
this->RoomReset(iDuelRoom);
DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);
return;
}
}
else
{
this->RoomReset(iDuelRoom);
DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);
return;
}
}
}
void CDuelManager::RecvDuelRequest(LPOBJ lpObj, PMSG_DUEL_REQUEST_START* lpMsg)
{
if(g_DuelSystemState != TRUE)
{
GCServerMsgStringSend("O duel foi desativado neste servidor!", lpObj->m_Index, 1);
return;
}
int iDuelIndex = MAKE_NUMBERW(lpMsg->NumberH, lpMsg->NumberL);
if ( !OBJMAX_RANGE(iDuelIndex) )
{
LogAdd("error : %s %d (%d)", __FILE__, __LINE__, iDuelIndex);
return;
}
if ( iDuelIndex == lpObj->m_Index )
return;
char szTempText[256];
if ( lpObj->CloseType != -1 )
return;
if ( gNonPK )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 174)), lpObj->m_Index, 1);
return;
}
if ( !gPkLimitFree )
{
if ( lpObj->m_PK_Level >= 6 )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 175)), lpObj->m_Index, 1);
return;
}
if ( gObj[iDuelIndex].m_PK_Level >= 6 )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 176)), lpObj->m_Index, 1);
return;
}
}
if ( OBJMAX_RANGE(lpObj->m_iDuelUserReserved) )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 159)), lpObj->m_Index, 1);
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 161)), lpObj->m_Index, 1);
return;
}
if ( OBJMAX_RANGE( lpObj->m_iDuelUser ) )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 160)), lpObj->m_Index, 1);
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 161)), lpObj->m_Index, 1);
return;
}
if ( DS_MAP_RANGE(gObj[iDuelIndex].MapNumber ) )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 180)), lpObj->m_Index, 1);
return;
}
if ( BC_MAP_RANGE(lpObj->MapNumber) )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 166)), lpObj->m_Index, 1);
return;
}
if ( CC_MAP_RANGE(lpObj->MapNumber) )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 207)), lpObj->m_Index, 1);
return;
}
if ( IT_MAP_RANGE(lpObj->MapNumber) != FALSE )
{
::GCServerMsgStringSend("Duelos não são permitidos no Illusion Temple.", lpObj->m_Index, 1);
return;
}
if ( lpObj->Level < 30 || gObj[iDuelIndex].Level < 30)
{
PMSG_DUEL_START pMsgSend;
pMsgSend.h.c = 0xC1;
pMsgSend.h.headcode = 0xAA;
pMsgSend.h.subcode = 0x01;
pMsgSend.bDuelStart = 0x0C;
pMsgSend.h.size = sizeof(pMsgSend);
DataSend(lpObj->m_Index, (BYTE*)&pMsgSend, pMsgSend.h.size);
return;
}
if ( lpObj->Money < 30000 || gObj[iDuelIndex].Money < 30000 )
{
PMSG_DUEL_START pMsgSend;
pMsgSend.h.c = 0xC1;
pMsgSend.h.headcode = 0xAA;
pMsgSend.h.subcode = 0x01;
pMsgSend.bDuelStart = 0x1e;
pMsgSend.h.size = sizeof(pMsgSend);
DataSend(lpObj->m_Index, (BYTE*)&pMsgSend, pMsgSend.h.size);
return;
}
int iDuelRoom = this->GetFreeRoomIndex();
if ( iDuelRoom == -1 )
{
PMSG_DUEL_START pMsgSend;
pMsgSend.h.c = 0xC1;
pMsgSend.h.headcode = 0xAA;
pMsgSend.h.subcode = 0x01;
pMsgSend.bDuelStart = 0x10;
pMsgSend.h.size = sizeof(pMsgSend);
DataSend(lpObj->m_Index, (BYTE*)&pMsgSend, pMsgSend.h.size);
return;
}
if ( ( GetTickCount() - lpObj->m_PacketCheckTime ) < 300 )
{
return;
}
lpObj->m_PacketCheckTime = GetTickCount();
char szDuelName[MAX_ACCOUNT_LEN+1] = {0};
char szDuelName2[MAX_ACCOUNT_LEN+1] = {0};
memcpy(szDuelName, gObj[iDuelIndex].Name, MAX_ACCOUNT_LEN);
szDuelName[MAX_ACCOUNT_LEN] = 0;
memcpy(szDuelName2, lpMsg->szName, MAX_ACCOUNT_LEN);
szDuelName2[MAX_ACCOUNT_LEN] = 0;
if ( strcmp(szDuelName, szDuelName2) )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 162)), lpObj->m_Index, 1);
return;
}
if ( this->IsDuelEnable(iDuelIndex) == FALSE )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 163)), lpObj->m_Index, 1);
return;
}
if ( lpObj->lpGuild && lpObj->lpGuild->WarState == 1 )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 164)), lpObj->m_Index, 1);
return;
}
if ( gObj[iDuelIndex].lpGuild && gObj[iDuelIndex].lpGuild->WarState == 1 )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 165)), lpObj->m_Index, 1);
return;
}
if ( gObjIsConnected(iDuelIndex) == FALSE )
return;
if ( gObj[iDuelIndex].Type == OBJ_MONSTER )
return;
if ( gObj[iDuelIndex].CloseCount >= 0 )
return;
for (int n=0;n<MAX_SELF_DEFENSE;n++)
{
if ( lpObj->SelfDefense[n] >= 0 || gObj[iDuelIndex].SelfDefense[n] >= 0 )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 189)), lpObj->m_Index, 1);
return;
}
}
if ( lpObj->m_IfState.use > 0 )
{
GCServerMsgStringSend(lMsg.Get(MSGGET(4, 167)), lpObj->m_Index, 1);
return;
}
if ( gObj[iDuelIndex].m_IfState.use > 0 )
{
wsprintf(szTempText, lMsg.Get(MSGGET(4, 168)), gObj[iDuelIndex].Name);
GCServerMsgStringSend(szTempText, lpObj->m_Index, 1);
return;
}
if ( OBJMAX_RANGE(gObj[iDuelIndex].m_iDuelUserRequested) )
{
wsprintf(szTempText, lMsg.Get(MSGGET(4, 169)), gObj[iDuelIndex].Name);
GCServerMsgStringSend(szTempText, lpObj->m_Index, 1);
return;
}
if ( OBJMAX_RANGE(gObj[iDuelIndex].m_iDuelUserReserved) )
{
wsprintf(szTempText, lMsg.Get(MSGGET(4, 170)), gObj[iDuelIndex].Name);
GCServerMsgStringSend(szTempText, lpObj->m_Index, 1);
return;
}
if ( OBJMAX_RANGE(gObj[iDuelIndex].m_iDuelUser) )
{
wsprintf(szTempText, lMsg.Get(MSGGET(4, 171)), gObj[iDuelIndex].Name);
GCServerMsgStringSend(szTempText, lpObj->m_Index, 1);
return;
}
lpObj->m_iDuelUser = -1;
lpObj->m_iDuelUserReserved = iDuelIndex;
gObj[iDuelIndex].m_iDuelUserRequested = lpObj->m_Index;
lpObj->m_iDuelRoom = iDuelRoom;
gObj[iDuelIndex].m_iDuelRoom = iDuelRoom;
this->m_Rooms[iDuelRoom].lpObj01 = lpObj;
this->m_Rooms[iDuelRoom].lpObj02 = &gObj[iDuelIndex];
this->m_Rooms[iDuelRoom].bWaiting = TRUE;
PMSG_DUEL_QUESTION_START pMsg;
pMsg.h.c = 0xC1;
pMsg.h.headcode = 0xAA;
pMsg.h.subcode = 0x02;
pMsg.h.size = sizeof(pMsg);
pMsg.NumberH = SET_NUMBERH(lpObj->m_Index);
pMsg.NumberL = SET_NUMBERL(lpObj->m_Index);
memcpy(pMsg.szName, lpObj->Name, sizeof(pMsg.szName));
DataSend(iDuelIndex, (LPBYTE)&pMsg, pMsg.h.size);
wsprintf(szTempText, lMsg.Get(MSGGET(4, 172)), gObj[iDuelIndex].Name);
GCServerMsgStringSend(szTempText, lpObj->m_Index, 1);
LogAddTD("[Duel Manager] [%s][%s] Requested to Start Duel to [%s][%s] on Room [%d]", lpObj->AccountID, lpObj->Name, gObj[iDuelIndex].AccountID, gObj[iDuelIndex].Name, iDuelRoom+1);
}
bool CDuelManager::IsDuelEnable(int aIndex)
{
if ( OBJMAX_RANGE(aIndex ) == FALSE)
{
return false;
}
if ( gObjIsConnected(aIndex) == TRUE )
{
if ( ( gObj[aIndex].m_Option & 2 ) == 2 )
{
return true;
}
}
return false;
}
void CDuelManager::SetDuelOption(int lpObj, BOOL bState)
{
if ( gObjIsConnected(lpObj) == TRUE )
{
if ( bState == 0 )
{
gObj[lpObj].m_Option = 0;
}
else
{
gObj[lpObj].m_Option |= 2;
}
}
}
bool CDuelManager::IsOnDuel(int lpObj)
{
for(int i = 0; i < MAX_DUEL_ROOMS; i++)
{
if(this->m_Rooms[i].lpObj01 == &gObj[lpObj])
{
return true;
}
if(this->m_Rooms[i].lpObj02 == &gObj[lpObj])
{
return true;
}
}
return false;
}
bool CDuelManager::IsOnDuel(int lpObj, int lpObj2)
{
for(int i = 0; i < MAX_DUEL_ROOMS; i++)
{
if(this->m_Rooms[i].bFree == FALSE)
{
if(this->m_Rooms[i].lpObj01 == &gObj[lpObj] &&
this->m_Rooms[i].lpObj02 == &gObj[lpObj2])
{
return true;
}
if(this->m_Rooms[i].lpObj01 == &gObj[lpObj2] &&
this->m_Rooms[i].lpObj02 == &gObj[lpObj])
{
return true;
}
}
}
return false;
}
Change the #include according to the dll, you're using also make sure you tune up the #define -s
Downloads:
Duel System S4:(7 KB)
Download
Credits:
- Wolf (DarkTeam)