ilk commit
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include "../shared/KOSocket.h"
|
||||
#include "MagicProcess.h"
|
||||
|
||||
class CAISocket : public KOSocket
|
||||
{
|
||||
public:
|
||||
CAISocket(uint16 socketID, SocketMgr * mgr) : KOSocket(socketID, mgr, 0, 524288, 524288), m_bHasConnected(false) {}
|
||||
|
||||
INLINE bool IsReconnecting() { return m_bHasConnected; }
|
||||
|
||||
virtual void OnConnect();
|
||||
virtual bool HandlePacket(Packet & pkt);
|
||||
|
||||
void Initialize();
|
||||
|
||||
|
||||
void LoginProcess(Packet & pkt);
|
||||
void RecvCheckAlive(Packet & pkt);
|
||||
void RecvServerInfo(Packet & pkt);
|
||||
void RecvNpcInfoAll(Packet & pkt);
|
||||
void RecvNpcMoveResult(Packet & pkt);
|
||||
void RecvNpcAttack(Packet & pkt);
|
||||
void RecvNpcInfo(Packet & pkt);
|
||||
void RecvNpcRegionUpdate(Packet & pkt);
|
||||
void RecvUserExp(Packet & pkt);
|
||||
void RecvSystemMsg(Packet & pkt);
|
||||
void RecvNpcGiveItem(Packet & pkt);
|
||||
void RecvUserFail(Packet & pkt);
|
||||
void RecvGateDestory(Packet & pkt);
|
||||
void RecvNpcDead(Packet & pkt);
|
||||
void RecvNpcInOut(Packet & pkt);
|
||||
void RecvBattleEvent(Packet & pkt);
|
||||
void RecvNpcEventItem(Packet & pkt);
|
||||
void RecvGateOpen(Packet & pkt);
|
||||
void RecvCompressed(Packet & pkt);
|
||||
void RecvNpcHpChange(Packet & pkt);
|
||||
void RecvNpcSpawnRequest(Packet & pkt);
|
||||
void RegionPacketAdd(Packet & pkt);
|
||||
virtual void OnDisconnect();
|
||||
virtual ~CAISocket() {}
|
||||
|
||||
private:
|
||||
bool m_bHasConnected;
|
||||
};
|
||||
@@ -0,0 +1,181 @@
|
||||
#include "stdafx.h"
|
||||
#include "User.h"
|
||||
#include "Region.h"
|
||||
#include "GameSocket.h"
|
||||
#include "Npc.h"
|
||||
#include "MAP.h"
|
||||
|
||||
#define MORAL_GOOD 0x01
|
||||
#define MORAL_BAD 0x02
|
||||
#define MORAL_NEUTRAL 0x03
|
||||
|
||||
static float surround_fx[8] = {0.0f, -0.7071f, -1.0f, -0.7083f, 0.0f, 0.7059f, 1.0000f, 0.7083f};
|
||||
static float surround_fz[8] = {1.0f, 0.7071f, 0.0f, -0.7059f, -1.0f, -0.7083f, -0.0017f, 0.7059f};
|
||||
|
||||
CUser::CUser() : Unit(UnitPlayer) {}
|
||||
CUser::~CUser() {}
|
||||
|
||||
void CUser::Initialize()
|
||||
{
|
||||
Unit::Initialize();
|
||||
|
||||
m_iUserId = -1;
|
||||
m_bLive = AI_USER_DEAD;
|
||||
m_sHP = m_sMP = 0;
|
||||
m_sMaxHP = m_sMaxMP = 0;
|
||||
m_state = 0;
|
||||
m_sItemAc = 0;
|
||||
m_byNowParty = 0;
|
||||
m_sPartyTotalLevel = 0;
|
||||
m_byPartyTotalMan = 0;
|
||||
m_sPartyNumber = -1;
|
||||
m_byIsOP = 0;
|
||||
m_bInvisibilityType = 0;
|
||||
|
||||
m_tLastRegeneTime = 0;
|
||||
m_bMaxWeightAmount = 100;
|
||||
|
||||
m_FlashExpBonus = 0;
|
||||
m_FlashDcBonus = 0;
|
||||
m_FlashWarBonus = 0;
|
||||
|
||||
m_sExpGainAmount = m_bNPGainAmount = m_bNoahGainAmount = 100;
|
||||
m_bPlayerAttackAmount = 100;
|
||||
m_bSkillNPBonus = 0;
|
||||
m_bAddWeaponDamage = 0;
|
||||
m_sAddArmourAc = 0;
|
||||
m_bPctArmourAc = 100;
|
||||
m_bPremiumMerchant = false;
|
||||
|
||||
InitNpcAttack();
|
||||
}
|
||||
|
||||
void CUser::OnDeath(Unit * pAttacker)
|
||||
{
|
||||
if (m_bLive == AI_USER_DEAD)
|
||||
return;
|
||||
|
||||
m_sHP = 0;
|
||||
m_bLive = AI_USER_DEAD;
|
||||
|
||||
InitNpcAttack();
|
||||
|
||||
MAP* pMap = GetMap();
|
||||
if (pMap == nullptr)
|
||||
return;
|
||||
|
||||
pMap->RegionUserRemove(m_sRegionX, m_sRegionZ, GetID());
|
||||
}
|
||||
|
||||
void CUser::InitNpcAttack()
|
||||
{
|
||||
memset(&m_sSurroundNpcNumber, -1, sizeof(m_sSurroundNpcNumber));
|
||||
}
|
||||
|
||||
int CUser::IsSurroundCheck(float fX, float fY, float fZ, int NpcID)
|
||||
{
|
||||
int nDir = 0;
|
||||
__Vector3 vNpc, vUser, vDis;
|
||||
vNpc.Set(fX, fY, fZ);
|
||||
float fDX, fDZ;
|
||||
float fDis = 0.0f, fCurDis=1000.0f;
|
||||
bool bFlag = false;
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
//if(m_sSurroundNpcNumber[i] != -1) continue;
|
||||
if(m_sSurroundNpcNumber[i] == NpcID)
|
||||
{
|
||||
if (bFlag)
|
||||
m_sSurroundNpcNumber[i] = -1;
|
||||
else
|
||||
{
|
||||
m_sSurroundNpcNumber[i] = NpcID;
|
||||
nDir = i+1;
|
||||
bFlag = true;
|
||||
}
|
||||
//return nDir;
|
||||
}
|
||||
|
||||
if(m_sSurroundNpcNumber[i] == -1 && bFlag==false)
|
||||
{
|
||||
fDX = GetX() + surround_fx[i];
|
||||
fDZ = GetZ() + surround_fz[i];
|
||||
vUser.Set(fDX, 0.0f, fDZ);
|
||||
vDis = vUser - vNpc;
|
||||
fDis = vDis.Magnitude();
|
||||
if(fDis < fCurDis)
|
||||
{
|
||||
nDir = i+1;
|
||||
fCurDis = fDis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TRACE("User-Sur : [0=%d,1=%d,2=%d,3=%d,4=%d,5=%d,6=%d,7=%d]\n", m_sSurroundNpcNumber[0],
|
||||
m_sSurroundNpcNumber[1], m_sSurroundNpcNumber[2], m_sSurroundNpcNumber[3], m_sSurroundNpcNumber[4],
|
||||
m_sSurroundNpcNumber[5],m_sSurroundNpcNumber[6], m_sSurroundNpcNumber[7]);
|
||||
*/
|
||||
if(nDir != 0)
|
||||
{
|
||||
m_sSurroundNpcNumber[nDir-1] = NpcID;
|
||||
}
|
||||
|
||||
return nDir;
|
||||
}
|
||||
|
||||
void CUser::HealMagic()
|
||||
{
|
||||
int region_x = (int)(GetX() / VIEW_DIST);
|
||||
int region_z = (int)(GetZ() / VIEW_DIST);
|
||||
|
||||
MAP* pMap = GetMap();
|
||||
if (pMap == nullptr) return;
|
||||
int min_x = region_x - 1; if(min_x < 0) min_x = 0;
|
||||
int min_z = region_z - 1; if(min_z < 0) min_z = 0;
|
||||
int max_x = region_x + 1; if(max_x > pMap->GetXRegionMax()) max_x = pMap->GetXRegionMax();
|
||||
int max_z = region_z + 1; if(min_z > pMap->GetZRegionMax()) min_z = pMap->GetZRegionMax();
|
||||
|
||||
int search_x = max_x - min_x + 1;
|
||||
int search_z = max_z - min_z + 1;
|
||||
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < search_x; i++)
|
||||
{
|
||||
for(j = 0; j < search_z; j++)
|
||||
{
|
||||
HealAreaCheck( min_x+i, min_z+j );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::HealAreaCheck(int rx, int rz)
|
||||
{
|
||||
MAP* pMap = GetMap();
|
||||
if (pMap == nullptr) return;
|
||||
|
||||
if (rx < 0 || rz < 0 || rx > pMap->GetXRegionMax() || rz > pMap->GetZRegionMax())
|
||||
{
|
||||
//TRACE("#### CUser-HealAreaCheck() Fail : [nid=%d, name=%s], nRX=%d, nRZ=%d #####\n", GetID(), GetName().c_str(), rx, rz);
|
||||
return;
|
||||
}
|
||||
|
||||
static const float fRadius = 10.0f; // 30m
|
||||
|
||||
Guard lock(pMap->m_lock);
|
||||
CRegion *pRegion = &pMap->m_ppRegion[rx][rz];
|
||||
|
||||
if (pRegion == nullptr)
|
||||
return;
|
||||
|
||||
foreach_stlmap (itr, pRegion->m_RegionNpcArray)
|
||||
{
|
||||
CNpc * pNpc = g_pMain->GetNpcPtr(itr->first);
|
||||
if (pNpc == nullptr || pNpc->isDead() || !pNpc->isHostileTo(this))
|
||||
continue;
|
||||
|
||||
if (isInRangeSlow(pNpc, fRadius))
|
||||
pNpc->ChangeTarget(1004, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,663 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#define COVERTITLE_CHANGE_TIME 15
|
||||
#define SKILLTITLE_CHANGE_TIME 15
|
||||
|
||||
void CUser::AchieveTimeQuest(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_ACHIEVE,uint8(99));
|
||||
uint16 ErrorCode;
|
||||
uint8 QuestID, type;
|
||||
uint16 RealQuestID;
|
||||
pkt >> QuestID, type;
|
||||
|
||||
RealQuestID = QuestID + 256;
|
||||
|
||||
_ACHIEVE_MAIN * pAchieveMain = g_pMain->GetAchieveMainPointer(RealQuestID);
|
||||
|
||||
if(pAchieveMain == nullptr)
|
||||
{
|
||||
ErrorCode = -2;
|
||||
goto fail_return;
|
||||
}
|
||||
|
||||
if(m_AchievequestMap[RealQuestID] == 2)
|
||||
{
|
||||
ErrorCode = -2;
|
||||
goto fail_return;
|
||||
}
|
||||
|
||||
if(m_tLastKillTime != 0)
|
||||
{
|
||||
ErrorCode = -1;
|
||||
goto fail_return2;
|
||||
}
|
||||
|
||||
|
||||
if(m_sChallangeAchieveID > 0 && m_sChallangeAchieveID != RealQuestID)
|
||||
{
|
||||
ErrorCode = -2;
|
||||
goto fail_return2;
|
||||
}
|
||||
|
||||
// 37237 There's no ongoing achievement 7 -1
|
||||
// 37238 This does not match the achievement you are challenging. 7 -2
|
||||
// 37239 You already have another ongoing achievement. 6 -1
|
||||
// 37240 Selected Achievement Error 6 -2
|
||||
|
||||
m_tLastKillTime = UNIXTIME;
|
||||
m_sChallangeAchieveID = RealQuestID;
|
||||
|
||||
result << uint8(1) << uint16(RealQuestID) << uint8(1);
|
||||
Send(&result);
|
||||
fail_return:
|
||||
result << uint8(6) << uint16(0) << uint16(ErrorCode);
|
||||
Send(&result);
|
||||
return;
|
||||
fail_return2:
|
||||
result << uint8(7) << uint16(0) << uint16(ErrorCode);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
void CUser::HandleAchieve(Packet & pkt)
|
||||
{
|
||||
|
||||
|
||||
auto OpCode = pkt.read<uint8>();
|
||||
|
||||
switch (OpCode)
|
||||
{
|
||||
case 2:// quest listesindeki iteme týklayýnca geliyor. Quest bitmiþse itemi vermek için.
|
||||
AchieveGetItem(pkt);
|
||||
break;
|
||||
case 3:
|
||||
LoadAchievementData(pkt);
|
||||
break;
|
||||
case 4:
|
||||
SendAchievementDetails();
|
||||
break;
|
||||
case 6: // süreli achievement iconlarýna týklayýnc gelen packet.
|
||||
AchieveTimeQuest(pkt);
|
||||
break;
|
||||
case 16: // cover title change
|
||||
ChangeCoverTitle(pkt);
|
||||
break;
|
||||
case 17: // skill title change
|
||||
ChangeSkillTitle(pkt);
|
||||
break;
|
||||
case 18: // Cover Title Reset
|
||||
CoverTitleReset();
|
||||
break;
|
||||
case 19: // Skill Title Reset
|
||||
SkillTitleReset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::AchieveGetItem(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_ACHIEVE, uint8(2));
|
||||
/*
|
||||
1 = Item has been issued.
|
||||
-1 = You cannot pick up the item because your item inventory is full.
|
||||
-2 = Item doesnt exist.
|
||||
*/
|
||||
int16 ReturnValue = 1;
|
||||
auto ID = pkt.read<uint16>();
|
||||
auto pAchieveMain = g_pMain->GetAchieveMainPointer(ID);
|
||||
|
||||
if (!pAchieveMain)
|
||||
goto failed_return;
|
||||
|
||||
// TODO: achieve item verme iþlemleri yapýlacak.
|
||||
|
||||
result << ID << ReturnValue;
|
||||
Send(&result);
|
||||
//SendAchieveStatus(ID, 5);
|
||||
return;
|
||||
failed_return:
|
||||
result << ID << ReturnValue;
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::LoadAchievementData(Packet & pkt)
|
||||
{
|
||||
auto pCount = pkt.read<uint16>();
|
||||
uint16 AchievementID = 0;
|
||||
|
||||
Packet result(WIZ_ACHIEVE, uint8(3));
|
||||
result << pCount;
|
||||
|
||||
for (size_t i = 0; i < pCount; i++)
|
||||
{
|
||||
pkt >> AchievementID;
|
||||
|
||||
auto pAchieveMain = g_pMain->GetAchieveMainPointer(AchievementID);
|
||||
_ACHIEVE_QUEST * pAchieveQuest = m_bAchieveKillCount.GetData(AchievementID);
|
||||
if (pAchieveMain)
|
||||
{
|
||||
switch (pAchieveMain->Type)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
result << AchievementID << uint8(m_AchievequestMap[AchievementID] == 2 ? 4 : 0) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[0]) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[1]);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
result << AchievementID << uint8(m_AchievequestMap[AchievementID] == 2 ? 4 : 0) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[0]) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[1]);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
result << AchievementID << uint8(m_AchievequestMap[AchievementID] == 2 ? 4 : 0) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[0]) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[1]);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
result << AchievementID << uint8(m_AchievequestMap[AchievementID] == 2 ? 4 : 0) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[0]) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[1]);
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
result << AchievementID << uint8(m_AchievequestMap[AchievementID] == 2 ? 4 : 0) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[0]) << uint16(pAchieveQuest == nullptr ? 0 : pAchieveQuest->KillCount[1]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result << AchievementID << uint8(0) << uint16(0) << uint16(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
result << AchievementID << uint8(0) << uint16(0) << uint16(0);
|
||||
}
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::SendAchievementDetails()
|
||||
{
|
||||
Packet result(WIZ_ACHIEVE, uint8(4));
|
||||
result << uint32(((UNIXTIME - m_TimeOnline) / 60) + m_dwTime) // Oyunda kalma süresi Dakika cinsinden
|
||||
<< m_iMonsterDefeatedCount
|
||||
<< m_iUserDefeatedCount
|
||||
<< m_iUserDeathCount
|
||||
<< m_iAchievementPoint
|
||||
<< AchieveLast1
|
||||
<< AchieveLast2
|
||||
<< AchieveLast3
|
||||
<< AchieveNormalCount // Normal Count
|
||||
<< AchieveQuestCount // Quest Count
|
||||
<< AchieveWarCount // War Count
|
||||
<< AchieveAdventureCount // Adventure Count
|
||||
<< AchieveChallengeCount;// Challenge Count
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::ChangeCoverTitle(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_ACHIEVE, uint8(16));
|
||||
|
||||
if (ChangeCoverTitleRequest + COVERTITLE_CHANGE_TIME >= UNIXTIME)
|
||||
goto failed_return;
|
||||
|
||||
ChangeCoverTitleRequest = UNIXTIME;
|
||||
|
||||
uint16 UnKnow1 = 0, Title = 0;
|
||||
pkt >> UnKnow1 >> Title;
|
||||
|
||||
auto pTitleData = g_pMain->GetAchieveTitlePointer(Title);
|
||||
if (!pTitleData
|
||||
|| m_AchievequestMap[pTitleData->UnKnow1] != 2)
|
||||
goto failed_return;
|
||||
|
||||
result << UnKnow1 << Title << uint16(1);
|
||||
|
||||
SetCoverTitle(Title);
|
||||
|
||||
Send(&result);
|
||||
StateChangeServerDirect(14, Title);
|
||||
return;
|
||||
failed_return:
|
||||
result << UnKnow1 << GetCoverTitle() << uint16(-5) << uint16(COVERTITLE_CHANGE_TIME - (UNIXTIME - ChangeCoverTitleRequest));
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::ChangeSkillTitle(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_ACHIEVE, uint8(17));
|
||||
|
||||
if (ChangeSkillTitleRequest + SKILLTITLE_CHANGE_TIME >= UNIXTIME)
|
||||
goto failed_return;
|
||||
|
||||
ChangeSkillTitleRequest = UNIXTIME;
|
||||
|
||||
uint16 UnKnow1 = 0, Title = 0;
|
||||
pkt >> UnKnow1 >> Title;
|
||||
|
||||
|
||||
auto pTitleData = g_pMain->GetAchieveTitlePointer(Title);
|
||||
if (!pTitleData
|
||||
|| m_AchievequestMap[pTitleData->UnKnow1] != 2)
|
||||
goto failed_return;
|
||||
|
||||
result << UnKnow1 << Title << uint16(1);
|
||||
|
||||
SetSkillTitle(Title);
|
||||
|
||||
Send(&result);
|
||||
SetUserAbility(true);
|
||||
return;
|
||||
failed_return:
|
||||
result << UnKnow1 << GetSkillTitle() << uint16(-5) << uint16(SKILLTITLE_CHANGE_TIME - (UNIXTIME - ChangeSkillTitleRequest));
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::CoverTitleReset()
|
||||
{
|
||||
Packet result(WIZ_ACHIEVE, uint8(18));
|
||||
|
||||
if (ResetCoverTitleRequest + COVERTITLE_CHANGE_TIME >= UNIXTIME)
|
||||
goto failed_return;
|
||||
|
||||
ResetCoverTitleRequest = UNIXTIME;
|
||||
|
||||
result << int16(1);
|
||||
|
||||
StateChangeServerDirect(14, 0);
|
||||
|
||||
Send(&result);
|
||||
return;
|
||||
failed_return:
|
||||
result << int16(-1) << uint16(COVERTITLE_CHANGE_TIME - (UNIXTIME - ResetCoverTitleRequest));
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::SkillTitleReset()
|
||||
{
|
||||
Packet result(WIZ_ACHIEVE, uint8(19));
|
||||
|
||||
if (ResetSkillTitleRequest + SKILLTITLE_CHANGE_TIME >= UNIXTIME)
|
||||
goto failed_return;
|
||||
|
||||
ResetSkillTitleRequest = UNIXTIME;
|
||||
|
||||
result << uint16(1);
|
||||
|
||||
SetSkillTitle(0);
|
||||
|
||||
Send(&result);
|
||||
SetUserAbility(true);
|
||||
return;
|
||||
failed_return:
|
||||
result << int16(-1) << uint16(SKILLTITLE_CHANGE_TIME - (UNIXTIME - ResetSkillTitleRequest));
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
/// ACHIEVE_WAR
|
||||
void CUser::AchieveType1(uint8 pType)
|
||||
{
|
||||
foreach_stlmap_nolock(itr, g_pMain->ACHIEVE_WAR)
|
||||
{
|
||||
auto pAchieveWarData = itr->second;
|
||||
|
||||
if (pAchieveWarData->Type != pType)
|
||||
continue;
|
||||
|
||||
if(m_AchievequestMap[pAchieveWarData->ID] == 2)
|
||||
continue;
|
||||
|
||||
auto pAchieveMain = g_pMain->GetAchieveMainPointer(pAchieveWarData->ID);
|
||||
_ACHIEVE_QUEST * pAchieveQuest = m_bAchieveKillCount.GetData(pAchieveWarData->ID);
|
||||
|
||||
if (pAchieveQuest == nullptr)
|
||||
{
|
||||
pAchieveQuest = new _ACHIEVE_QUEST;
|
||||
pAchieveQuest->ID = pAchieveWarData->ID;
|
||||
pAchieveQuest->KillCount[0] = 0;
|
||||
pAchieveQuest->KillCount[1] = 0;
|
||||
m_bAchieveKillCount.PutData(pAchieveQuest->ID,pAchieveQuest);
|
||||
}
|
||||
|
||||
|
||||
if ((pAchieveMain->ZoneID == ZONE_KARUS && (GetZoneID() != GetNation()))
|
||||
|| (pAchieveMain->ZoneID == ZONE_KARUS_ESLANT && (GetZoneID() != GetNation() + 10))
|
||||
|| (pAchieveMain->ZoneID != 0 && pAchieveMain->ZoneID != GetZoneID()))
|
||||
continue;
|
||||
|
||||
if(pType == 20
|
||||
&& (pAchieveWarData->ID == 94
|
||||
|| pAchieveWarData->ID == 95
|
||||
|| pAchieveWarData->ID == 96
|
||||
|| pAchieveWarData->ID == 97
|
||||
|| pAchieveWarData->ID == 98)
|
||||
&& m_bResHpType == USER_DEAD)
|
||||
{
|
||||
pAchieveQuest->KillCount[0] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(pAchieveMain->Time > 0 && (m_AchievequestMap[pAchieveWarData->ID] != 1 || m_sChallangeAchieveID != pAchieveWarData->ID))
|
||||
continue;
|
||||
|
||||
if(pAchieveQuest->KillCount[0] == 0
|
||||
&& pAchieveMain->Time == 0)
|
||||
m_AchievequestMap[pAchieveWarData->ID] = 1;
|
||||
else if(pAchieveQuest->KillCount[0] > 0
|
||||
&& ((m_tLastKillTime - UNIXTIME) > pAchieveMain->Time) && pAchieveMain->Time > 0)
|
||||
{
|
||||
pAchieveQuest->KillCount[0] = 0;
|
||||
m_AchievequestMap[pAchieveWarData->ID] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
pAchieveQuest->KillCount[0]++;
|
||||
|
||||
if (pAchieveWarData->Data == pAchieveQuest->KillCount[0]) // Görevi bitirme iþlemleri
|
||||
{
|
||||
SendAchieveStatus(pAchieveWarData->ID, 2);
|
||||
m_AchievequestMap[pAchieveWarData->ID] = 2;
|
||||
m_iAchievementPoint += pAchieveMain->Point;
|
||||
|
||||
switch(pAchieveMain->TabIndex)
|
||||
{
|
||||
case 0:
|
||||
AchieveNormalCount++; // Normal Count
|
||||
break;
|
||||
case 1:
|
||||
AchieveQuestCount++; // Quest Count
|
||||
break;
|
||||
case 2:
|
||||
AchieveWarCount++; // War Count
|
||||
break;
|
||||
case 3:
|
||||
AchieveAdventureCount++; // Adventure Count
|
||||
break;
|
||||
case 4:
|
||||
AchieveChallengeCount++;// Challenge Count
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(AchieveLast3 == 0
|
||||
&& AchieveLast2 == 0
|
||||
&& AchieveLast1 == 0)
|
||||
AchieveLast1 = pAchieveMain->ID;
|
||||
else
|
||||
{
|
||||
AchieveLast3 = AchieveLast2;
|
||||
AchieveLast2 = AchieveLast1;
|
||||
AchieveLast1 = pAchieveMain->ID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// ACHIEVE_MONSTER
|
||||
void CUser::AchieveType2(CNpc * pNpc)
|
||||
{
|
||||
if (!pNpc
|
||||
|| pNpc == nullptr)
|
||||
return;
|
||||
|
||||
AchieveType1(20);
|
||||
|
||||
m_iMonsterDefeatedCount++;
|
||||
|
||||
foreach_stlmap_nolock(itr, g_pMain->ACHIEVE_MAIN)
|
||||
{
|
||||
auto pMainData = itr->second;
|
||||
if (pMainData->Type != 2)
|
||||
continue;
|
||||
|
||||
if (pMainData->ZoneID != 0
|
||||
&& pMainData->ZoneID != GetZoneID())
|
||||
continue;
|
||||
|
||||
if(m_AchievequestMap[pMainData->ID] == 2)
|
||||
continue;
|
||||
|
||||
_ACHIEVE_MONSTER * pMonsterData = g_pMain->GetAchieveMonsterPointer(pMainData->ID);
|
||||
|
||||
if (pMonsterData == nullptr)
|
||||
continue;
|
||||
|
||||
|
||||
_ACHIEVE_QUEST * pAchieveQuest = m_bAchieveKillCount.GetData(pMainData->ID);
|
||||
|
||||
if (pAchieveQuest == nullptr)
|
||||
{
|
||||
pAchieveQuest = new _ACHIEVE_QUEST;
|
||||
pAchieveQuest->ID = pMainData->ID;
|
||||
pAchieveQuest->KillCount[0] = 0;
|
||||
pAchieveQuest->KillCount[1] = 0;
|
||||
m_bAchieveKillCount.PutData(pAchieveQuest->ID,pAchieveQuest);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 2; i++)
|
||||
{
|
||||
|
||||
if(pAchieveQuest->KillCount[i] == pMonsterData->MonsterCount[i])
|
||||
continue;
|
||||
|
||||
for (size_t ii = 0; ii < 4; ii++)
|
||||
{
|
||||
if (pMonsterData->MonsterID[i][ii] != pNpc->GetProtoID())
|
||||
continue;
|
||||
else if(pAchieveQuest->KillCount[i] == 0)
|
||||
{
|
||||
m_AchievequestMap[pMonsterData->ID] = 1;
|
||||
pAchieveQuest->KillCount[i]++;
|
||||
}
|
||||
else
|
||||
pAchieveQuest->KillCount[i]++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(pAchieveQuest->KillCount[0] == pMonsterData->MonsterCount[0]
|
||||
&& pAchieveQuest->KillCount[1] == pMonsterData->MonsterCount[1]
|
||||
&& m_AchievequestMap[pMonsterData->ID] == 1)
|
||||
{
|
||||
m_AchievequestMap[pMonsterData->ID] = 2;// görevi bitir
|
||||
SendAchieveStatus(pMonsterData->ID,2);
|
||||
m_iAchievementPoint += pMainData->Point;
|
||||
|
||||
|
||||
switch(pMainData->TabIndex)
|
||||
{
|
||||
case 0:
|
||||
AchieveNormalCount++; // Normal Count
|
||||
break;
|
||||
case 1:
|
||||
AchieveQuestCount++; // Quest Count
|
||||
break;
|
||||
case 2:
|
||||
AchieveWarCount++; // War Count
|
||||
break;
|
||||
case 3:
|
||||
AchieveAdventureCount++; // Adventure Count
|
||||
break;
|
||||
case 4:
|
||||
AchieveChallengeCount++;// Challenge Count
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(AchieveLast3 == 0
|
||||
&& AchieveLast2 == 0
|
||||
&& AchieveLast1 == 0)
|
||||
AchieveLast1 = pMainData->ID;
|
||||
else
|
||||
{
|
||||
AchieveLast3 = AchieveLast2;
|
||||
AchieveLast2 = AchieveLast1;
|
||||
AchieveLast1 = pMainData->ID;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ACHIEVE_COM
|
||||
void CUser::AchieveType3()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// ACHIEVE_NORMAL
|
||||
void CUser::AchieveType4(uint8 pType)
|
||||
{
|
||||
|
||||
/*
|
||||
type1 is king
|
||||
type2 Achieve Contribution x NP
|
||||
type3 Reach Level x
|
||||
type5 Achieve Knight Contribution Point of x CLAN NPSÝ
|
||||
type10 Become a member of Knight Trainees
|
||||
|
||||
*/
|
||||
foreach_stlmap_nolock(itr, g_pMain->ACHIEVE_NORMAL)
|
||||
{
|
||||
auto pAchieveNormalData = itr->second;
|
||||
|
||||
if (pAchieveNormalData->UnKnow1 != pType)
|
||||
continue;
|
||||
|
||||
if(m_AchievequestMap[pAchieveNormalData->ID] == 2)
|
||||
continue;
|
||||
|
||||
auto pAchieveMain = g_pMain->GetAchieveMainPointer(pAchieveNormalData->ID);
|
||||
_ACHIEVE_QUEST * pAchieveQuest = m_bAchieveKillCount.GetData(pAchieveNormalData->ID);
|
||||
|
||||
if (pAchieveQuest == nullptr)
|
||||
{
|
||||
pAchieveQuest = new _ACHIEVE_QUEST;
|
||||
pAchieveQuest->ID = pAchieveNormalData->ID;
|
||||
pAchieveQuest->KillCount[0] = 0;
|
||||
pAchieveQuest->KillCount[1] = 0;
|
||||
m_bAchieveKillCount.PutData(pAchieveQuest->ID,pAchieveQuest);
|
||||
}
|
||||
|
||||
|
||||
if ((pAchieveMain->ZoneID == ZONE_KARUS && (GetZoneID() != GetNation()))
|
||||
|| (pAchieveMain->ZoneID == ZONE_KARUS_ESLANT && (GetZoneID() != GetNation() + 10))
|
||||
|| (pAchieveMain->ZoneID != 0 && pAchieveMain->ZoneID != GetZoneID()))
|
||||
continue;
|
||||
|
||||
|
||||
if(pAchieveQuest->KillCount[0] == 0)
|
||||
m_AchievequestMap[pAchieveNormalData->ID] = 1;
|
||||
|
||||
|
||||
CKnights * pKnights = g_pMain->GetClanPtr(GetClanID());
|
||||
_KNIGHTS_SIEGE_WARFARE * pSiegeKnights = g_pMain->GetSiegeMasterKnightsPtr(1);
|
||||
switch(pType)
|
||||
{
|
||||
case 1:
|
||||
if(isKing())
|
||||
pAchieveQuest->KillCount[0] = pAchieveNormalData->UnKnow2;
|
||||
break;
|
||||
case 2:
|
||||
if(GetLoyalty() >= pAchieveNormalData->UnKnow2)
|
||||
pAchieveQuest->KillCount[0] = pAchieveNormalData->UnKnow2;
|
||||
break;
|
||||
case 3:
|
||||
if(GetLevel() >= pAchieveNormalData->UnKnow2)
|
||||
pAchieveQuest->KillCount[0] = pAchieveNormalData->UnKnow2;
|
||||
break;
|
||||
case 5:
|
||||
if(m_pKnightsUser == nullptr)
|
||||
continue;
|
||||
|
||||
if(m_pKnightsUser->nDonatedNP >= pAchieveNormalData->UnKnow2)
|
||||
pAchieveQuest->KillCount[0] = pAchieveNormalData->UnKnow2;
|
||||
break;
|
||||
case 10:
|
||||
// Become a member of Knight Trainees 419
|
||||
// Become a member of Knights 420
|
||||
// Become a member of Castle Knights 421
|
||||
if(pKnights == nullptr)
|
||||
continue;
|
||||
|
||||
if(pSiegeKnights == nullptr
|
||||
&& pAchieveNormalData->ID == 421)
|
||||
continue;
|
||||
|
||||
if(pSiegeKnights->sMasterKnights != GetClanID()
|
||||
&& pAchieveNormalData->ID == 421)
|
||||
continue;
|
||||
|
||||
if(pAchieveNormalData->ID == 419
|
||||
&& pKnights->m_byFlag < ClanTypePromoted)
|
||||
continue;
|
||||
|
||||
pAchieveQuest->KillCount[0] = pAchieveNormalData->UnKnow2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (pAchieveNormalData->UnKnow2 == pAchieveQuest->KillCount[0]) // Görevi bitirme iþlemleri
|
||||
{
|
||||
SendAchieveStatus(pAchieveNormalData->ID, 2);
|
||||
m_AchievequestMap[pAchieveNormalData->ID] = 2;
|
||||
m_iAchievementPoint += pAchieveMain->Point;
|
||||
|
||||
switch(pAchieveMain->TabIndex)
|
||||
{
|
||||
case 0:
|
||||
AchieveNormalCount++; // Normal Count
|
||||
break;
|
||||
case 1:
|
||||
AchieveQuestCount++; // Quest Count
|
||||
break;
|
||||
case 2:
|
||||
AchieveWarCount++; // War Count
|
||||
break;
|
||||
case 3:
|
||||
AchieveAdventureCount++; // Adventure Count
|
||||
break;
|
||||
case 4:
|
||||
AchieveChallengeCount++;// Challenge Count
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(AchieveLast3 == 0
|
||||
&& AchieveLast2 == 0
|
||||
&& AchieveLast1 == 0)
|
||||
AchieveLast1 = pAchieveMain->ID;
|
||||
else
|
||||
{
|
||||
AchieveLast3 = AchieveLast2;
|
||||
AchieveLast2 = AchieveLast1;
|
||||
AchieveLast1 = pAchieveMain->ID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// Ekranýn orta altýnda achieve i bitirdiðine dair uif çýkartmak için
|
||||
void CUser::SendAchieveStatus(uint16 AchieveID, uint8 AchieveStatus)
|
||||
{
|
||||
Packet result(WIZ_ACHIEVE, uint8(1));
|
||||
result << AchieveID << AchieveStatus;// achieve ok
|
||||
Send(&result);
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
#include "stdafx.h"
|
||||
#include "Map.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
enum
|
||||
{
|
||||
CHALLENGE_PVP_REQUEST = 1,
|
||||
CHALLENGE_PVP_CANCEL = 2,
|
||||
CHALLENGE_PVP_ACCEPT = 3,
|
||||
CHALLENGE_PVP_REJECT = 4,
|
||||
CHALLENGE_PVP_REQ_SENT = 5,
|
||||
CHALLENGE_CVC_REQUEST = 6,
|
||||
CHALLENGE_CVC_CANCEL = 7,
|
||||
CHALLENGE_CVC_ACCEPT = 8,
|
||||
CHALLENGE_CVC_REJECT = 9,
|
||||
CHALLENGE_CVC_REQ_SENT = 10,
|
||||
CHALLENGE_GENERIC_ERROR = 11,
|
||||
CHALLENGE_ZONE_ERROR = 12,
|
||||
CHALLENGE_CLAN_ERROR = 13
|
||||
};
|
||||
|
||||
// also known as CUser::BattleFields()
|
||||
void CUser::HandleChallenge(Packet & pkt)
|
||||
{
|
||||
if (isDead())
|
||||
return;
|
||||
|
||||
uint8 opcode = pkt.read<uint8>();
|
||||
switch (opcode)
|
||||
{
|
||||
case CHALLENGE_PVP_REQUEST:
|
||||
HandleChallengeRequestPVP(pkt);
|
||||
break;
|
||||
|
||||
case CHALLENGE_PVP_ACCEPT:
|
||||
HandleChallengeAcceptPVP(pkt);
|
||||
break;
|
||||
|
||||
case CHALLENGE_CVC_REQUEST:
|
||||
HandleChallengeRequestCVC(pkt);
|
||||
break;
|
||||
|
||||
case CHALLENGE_CVC_ACCEPT:
|
||||
HandleChallengeAcceptCVC(pkt);
|
||||
break;
|
||||
|
||||
case CHALLENGE_PVP_CANCEL:
|
||||
case CHALLENGE_CVC_CANCEL:
|
||||
HandleChallengeCancelled(opcode);
|
||||
break;
|
||||
|
||||
case CHALLENGE_PVP_REJECT:
|
||||
case CHALLENGE_CVC_REJECT:
|
||||
HandleChallengeRejected(opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This is sent when the challenger requests a PVP duel with a challengee.
|
||||
void CUser::HandleChallengeRequestPVP(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_CHALLENGE);
|
||||
CUser *pUser;
|
||||
string strUserID;
|
||||
uint8 bErrorCode = CHALLENGE_GENERIC_ERROR;
|
||||
|
||||
if (m_bRequestingChallenge
|
||||
|| m_bChallengeRequested
|
||||
|| GetZoneID() == ZONE_ARENA
|
||||
|| isInParty()
|
||||
|| isTrading()
|
||||
|| isMerchanting()
|
||||
|| m_bMerchantStatex
|
||||
|| isStoreOpen())
|
||||
goto fail_return;
|
||||
|
||||
if (GetMap()->isNationPVPZone()
|
||||
|| GetZoneID() == ZONE_DELOS
|
||||
|| GetMap()->isWarZone())
|
||||
{
|
||||
bErrorCode = CHALLENGE_ZONE_ERROR;
|
||||
goto fail_return;
|
||||
}
|
||||
|
||||
pkt.SByte();
|
||||
result.SByte();
|
||||
|
||||
pkt >> strUserID;
|
||||
|
||||
pUser = g_pMain->GetUserPtr(strUserID, TYPE_CHARACTER);
|
||||
if (pUser == nullptr
|
||||
|| !pUser->isInGame()
|
||||
|| pUser->isInParty()
|
||||
|| pUser->isDead()
|
||||
|| pUser->m_bRequestingChallenge
|
||||
|| pUser->m_bChallengeRequested
|
||||
|| pUser->m_bMerchantStatex
|
||||
|| pUser->isMerchanting()
|
||||
|| pUser->isTrading()
|
||||
|| pUser->isStoreOpen()
|
||||
|| pUser->GetZoneID() != GetZoneID())
|
||||
goto fail_return;
|
||||
|
||||
m_bRequestingChallenge = CHALLENGE_PVP_CANCEL;
|
||||
m_sChallengeUser = pUser->GetID();
|
||||
pUser->m_bChallengeRequested = CHALLENGE_PVP_REJECT;
|
||||
pUser->m_sChallengeUser = GetID();
|
||||
|
||||
result << uint8(CHALLENGE_PVP_REQUEST) << GetName();
|
||||
pUser->Send(&result);
|
||||
|
||||
result.clear();
|
||||
result << uint8(CHALLENGE_PVP_REQ_SENT) << pUser->GetName();
|
||||
Send(&result);
|
||||
return;
|
||||
|
||||
fail_return:
|
||||
result << bErrorCode;
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
// This is sent when the challenger requests a clan vs clan battle with a challengee.
|
||||
void CUser::HandleChallengeRequestCVC(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_CHALLENGE);
|
||||
CUser *pUser;
|
||||
string strUserID;
|
||||
uint8 bErrorCode = CHALLENGE_GENERIC_ERROR;
|
||||
|
||||
if (m_bRequestingChallenge
|
||||
|| m_bChallengeRequested
|
||||
|| GetZoneID() == ZONE_ARENA
|
||||
|| isInParty()
|
||||
|| m_bMerchantStatex
|
||||
|| isTrading()
|
||||
|| isMerchanting()
|
||||
|| isStoreOpen())
|
||||
goto fail_return;
|
||||
|
||||
// Are we entitled to speak for the clan?
|
||||
if (!isClanLeader())
|
||||
{
|
||||
bErrorCode = CHALLENGE_CLAN_ERROR;
|
||||
goto fail_return;
|
||||
}
|
||||
|
||||
if (GetMap()->isNationPVPZone()
|
||||
|| GetZoneID() == ZONE_DELOS
|
||||
|| GetMap()->isWarZone())
|
||||
{
|
||||
bErrorCode = CHALLENGE_ZONE_ERROR;
|
||||
goto fail_return;
|
||||
}
|
||||
|
||||
pkt.SByte();
|
||||
result.SByte();
|
||||
|
||||
pkt >> strUserID;
|
||||
|
||||
pUser = g_pMain->GetUserPtr(strUserID, TYPE_CHARACTER);
|
||||
if (pUser == nullptr
|
||||
|| !pUser->isInGame()
|
||||
|| pUser->isInParty()
|
||||
|| pUser->isDead()
|
||||
|| pUser->m_bMerchantStatex
|
||||
|| pUser->m_bRequestingChallenge
|
||||
|| pUser->m_bChallengeRequested
|
||||
|| pUser->isMerchanting()
|
||||
|| pUser->isTrading()
|
||||
|| pUser->isStoreOpen()
|
||||
|| pUser->GetZoneID() != GetZoneID())
|
||||
goto fail_return;
|
||||
|
||||
// Is the target entitled to speak for the clan?
|
||||
if (!pUser->isClanLeader())
|
||||
{
|
||||
bErrorCode = CHALLENGE_CLAN_ERROR; // might need to be set to CHALLENGE_ZONE_ERROR (it's set to that in 1.298)
|
||||
goto fail_return;
|
||||
}
|
||||
|
||||
m_bRequestingChallenge = CHALLENGE_CVC_CANCEL;
|
||||
m_sChallengeUser = pUser->GetID();
|
||||
pUser->m_bChallengeRequested = CHALLENGE_CVC_REJECT;
|
||||
pUser->m_sChallengeUser = GetID();
|
||||
|
||||
result << uint8(CHALLENGE_CVC_REQUEST) << GetName();
|
||||
pUser->Send(&result);
|
||||
|
||||
result.clear();
|
||||
result << uint8(CHALLENGE_CVC_REQ_SENT) << pUser->GetName();
|
||||
Send(&result);
|
||||
return;
|
||||
|
||||
fail_return:
|
||||
result << bErrorCode;
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
// This is sent when the challengee accepts a challenger's PVP request
|
||||
void CUser::HandleChallengeAcceptPVP(Packet & pkt)
|
||||
{
|
||||
if (!m_bChallengeRequested)
|
||||
return;
|
||||
|
||||
CUser *pUser = g_pMain->GetUserPtr(m_sChallengeUser);
|
||||
|
||||
m_sChallengeUser = -1;
|
||||
m_bChallengeRequested = 0;
|
||||
|
||||
if (pUser == nullptr)
|
||||
{
|
||||
Packet result(WIZ_CHALLENGE);
|
||||
result << uint8(CHALLENGE_GENERIC_ERROR);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
pUser->m_sChallengeUser = -1;
|
||||
pUser->m_bRequestingChallenge = 0;
|
||||
|
||||
// Glorious magic numbers!
|
||||
ZoneChange(ZONE_ARENA, 135.0f, 115.0f);
|
||||
pUser->ZoneChange(ZONE_ARENA, 120.0f, 115.0f);
|
||||
}
|
||||
|
||||
// This is sent when the challengee accepts a challenger's clan vs clan request
|
||||
void CUser::HandleChallengeAcceptCVC(Packet & pkt)
|
||||
{
|
||||
if (!m_bChallengeRequested)
|
||||
return;
|
||||
|
||||
Packet result(WIZ_CHALLENGE, uint8(CHALLENGE_GENERIC_ERROR));
|
||||
CUser *pUser = g_pMain->GetUserPtr(m_sChallengeUser);
|
||||
|
||||
m_sChallengeUser = -1;
|
||||
m_bChallengeRequested = 0;
|
||||
|
||||
if (pUser == nullptr)
|
||||
{
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
pUser->m_sChallengeUser = -1;
|
||||
pUser->m_bRequestingChallenge = 0;
|
||||
|
||||
CKnights *pClan1 = g_pMain->GetClanPtr(GetClanID());
|
||||
CKnights *pClan2 = g_pMain->GetClanPtr(pUser->GetClanID());
|
||||
|
||||
if (pClan1 == nullptr || pClan2 == nullptr)
|
||||
{
|
||||
Send(&result);
|
||||
pUser->Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach_array (i, pClan1->m_arKnightsUser)
|
||||
{
|
||||
_KNIGHTS_USER *p = &pClan1->m_arKnightsUser[i];
|
||||
if (!p->byUsed || p->pSession == nullptr)
|
||||
continue;
|
||||
|
||||
CUser *pClanMember = p->pSession;
|
||||
if (pClanMember->GetZoneID() == GetZoneID()
|
||||
&& !pClanMember->isStoreOpen()
|
||||
&& !pClanMember->isMerchanting()
|
||||
&& !pClanMember->isTrading()
|
||||
&& !pClanMember->m_bMerchantStatex
|
||||
&& !pClanMember->isInParty()
|
||||
&& !pClanMember->m_bRequestingChallenge
|
||||
&& pClanMember->m_sChallengeUser < 0)
|
||||
pClanMember->ZoneChange(ZONE_ARENA, 128.0f, 125.0f);
|
||||
}
|
||||
|
||||
foreach_array (i, pClan2->m_arKnightsUser)
|
||||
{
|
||||
_KNIGHTS_USER *p = &pClan2->m_arKnightsUser[i];
|
||||
if (!p->byUsed || p->pSession == nullptr)
|
||||
continue;
|
||||
|
||||
CUser *pClanMember = p->pSession;
|
||||
if (pClanMember->GetZoneID() == GetZoneID()
|
||||
&& !pClanMember->isStoreOpen()
|
||||
&& !pClanMember->isMerchanting()
|
||||
&& !pClanMember->isTrading()
|
||||
&& !pClanMember->m_bMerchantStatex
|
||||
&& !pClanMember->isInParty()
|
||||
&& !pClanMember->m_bRequestingChallenge
|
||||
&& pClanMember->m_sChallengeUser < 0)
|
||||
pClanMember->ZoneChange(ZONE_ARENA, 135.0f, 120.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// This is sent when the challenger cancels their request to the challengee.
|
||||
void CUser::HandleChallengeCancelled(uint8 opcode)
|
||||
{
|
||||
if (!m_bRequestingChallenge)
|
||||
return;
|
||||
|
||||
Packet result(WIZ_CHALLENGE);
|
||||
|
||||
CUser *pUser = g_pMain->GetUserPtr(m_sChallengeUser);
|
||||
if (pUser == nullptr || pUser->m_sChallengeUser != GetID())
|
||||
{
|
||||
result << uint8(CHALLENGE_GENERIC_ERROR);
|
||||
Send(&result);
|
||||
}
|
||||
else
|
||||
{
|
||||
pUser->m_sChallengeUser = -1;
|
||||
pUser->m_bChallengeRequested = 0;
|
||||
result << opcode;
|
||||
pUser->Send(&result);
|
||||
}
|
||||
|
||||
m_sChallengeUser = -1;
|
||||
m_bRequestingChallenge = 0;
|
||||
}
|
||||
|
||||
// This is sent when the challengee rejects the challenger's request.
|
||||
void CUser::HandleChallengeRejected(uint8 opcode)
|
||||
{
|
||||
if (!m_bChallengeRequested)
|
||||
return;
|
||||
|
||||
Packet result(WIZ_CHALLENGE);
|
||||
|
||||
CUser *pUser = g_pMain->GetUserPtr(m_sChallengeUser);
|
||||
if (pUser == nullptr || pUser->m_sChallengeUser != GetID())
|
||||
{
|
||||
result << uint8(CHALLENGE_GENERIC_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
pUser->m_sChallengeUser = -1;
|
||||
pUser->m_bRequestingChallenge = 0;
|
||||
result << opcode;
|
||||
pUser->Send(&result);
|
||||
}
|
||||
|
||||
m_sChallengeUser = -1;
|
||||
m_bChallengeRequested = 0;
|
||||
Send(&result);
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
#include "stdafx.h"
|
||||
#include "Map.h"
|
||||
|
||||
void CUser::Attack(Packet & pkt)
|
||||
{
|
||||
int16 sid = -1, tid = -1, damage, delaytime, distance;
|
||||
uint8 bType, bResult = 0;
|
||||
Unit * pTarget = nullptr;
|
||||
|
||||
pkt >> bType >> bResult >> tid >> delaytime >> distance;
|
||||
|
||||
// delaytime = delaytime / 100.0f;
|
||||
// distance = distance / 10.0f;
|
||||
|
||||
if (isIncapacitated())
|
||||
return;
|
||||
|
||||
RemoveStealth();
|
||||
|
||||
// If you're holding a weapon, do a client-based (ugh, do not trust!) delay check.
|
||||
_ITEM_TABLE *pTable = GetItemPrototype(RIGHTHAND);
|
||||
if (pTable != nullptr && !isMage())
|
||||
{
|
||||
if (distance > pTable->m_sRange)
|
||||
return;
|
||||
}
|
||||
// Empty handed.
|
||||
else if (delaytime < 100)
|
||||
return;
|
||||
|
||||
pTarget = g_pMain->GetUnitPtr(tid);
|
||||
bResult = ATTACK_FAIL;
|
||||
|
||||
|
||||
if (pTarget != nullptr
|
||||
&& isInAttackRange(pTarget)
|
||||
&& CanAttack(pTarget))
|
||||
{
|
||||
if (isAttackable(pTarget) && CanCastRHit(GetSocketID()))
|
||||
{
|
||||
if (isInTempEventZone() &&
|
||||
(!isSameEventRoom(pTarget)
|
||||
|| !g_pMain->pTempleEvent.isAttackable))
|
||||
return;
|
||||
|
||||
if(GetEventRoom() > 0 && pTarget->GetEventRoom() != GetEventRoom())
|
||||
return;
|
||||
|
||||
CUser *pUser = g_pMain->GetUserPtr(GetSocketID());
|
||||
|
||||
if (pUser != nullptr)
|
||||
pUser->m_RHitRepeatList.insert(std::make_pair(GetSocketID(), UNIXTIME));
|
||||
|
||||
damage = GetDamage(pTarget);
|
||||
|
||||
if(pTarget->GetID() > NPC_BAND)
|
||||
{
|
||||
|
||||
switch(TO_NPC(pTarget)->GetType())
|
||||
{
|
||||
case NPC_FOSSIL:
|
||||
damage = 1;
|
||||
break;
|
||||
case NPC_TREE:
|
||||
damage = 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Can't use R attacks in the Snow War.
|
||||
if (GetZoneID() == ZONE_SNOW_BATTLE && g_pMain->m_byBattleOpen == SNOW_BATTLE)
|
||||
damage = 0;
|
||||
else if (GetZoneID() == ZONE_CHAOS_DUNGEON && g_pMain->pTempleEvent.isAttackable)
|
||||
damage = 500 / 10;
|
||||
else if (GetZoneID() == ZONE_PRISON)
|
||||
{
|
||||
if (GetMana() < (m_iMaxMp / 5))
|
||||
return;
|
||||
|
||||
damage = 1;
|
||||
MSpChange(-(m_iMaxMp / 5));
|
||||
}
|
||||
|
||||
if (damage > 0)
|
||||
{
|
||||
pTarget->HpChange(-damage, this);
|
||||
if (pTarget->isDead())
|
||||
bResult = ATTACK_TARGET_DEAD;
|
||||
else
|
||||
bResult = ATTACK_SUCCESS;
|
||||
|
||||
// Every attack takes a little of your weapon's durability.
|
||||
ItemWoreOut(ATTACK, damage);
|
||||
|
||||
// Every hit takes a little of the defender's armour durability.
|
||||
if (pTarget->isPlayer())
|
||||
TO_USER(pTarget)->ItemWoreOut(DEFENCE, damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Packet result(WIZ_ATTACK, bType);
|
||||
result << bResult << GetSocketID() << tid;
|
||||
SendToRegion(&result);
|
||||
}
|
||||
|
||||
void CUser::Regene(uint8 regene_type, uint32 magicid /*= 0*/)
|
||||
{
|
||||
ASSERT(GetMap() != nullptr);
|
||||
|
||||
_OBJECT_EVENT* pEvent = nullptr;
|
||||
_START_POSITION* pStartPosition = nullptr;
|
||||
float x = 0.0f, z = 0.0f;
|
||||
|
||||
if (!isDead())
|
||||
return;
|
||||
|
||||
if (regene_type != 1 && regene_type != 2)
|
||||
regene_type = 1;
|
||||
|
||||
if (regene_type == 2)
|
||||
{
|
||||
// Is our level high enough to be able to resurrect using this skill?
|
||||
if (GetLevel() <= 5
|
||||
// Do we have enough resurrection stones?
|
||||
|| !RobItem(379006000, 3 * GetLevel()))
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're in a home zone, we'll want the coordinates from there. Otherwise, assume our own home zone.
|
||||
pStartPosition = g_pMain->m_StartPositionArray.GetData(GetZoneID());
|
||||
if (pStartPosition == nullptr)
|
||||
return;
|
||||
|
||||
UserInOut(INOUT_OUT);
|
||||
|
||||
pEvent = GetMap()->GetObjectEvent(m_sBind);
|
||||
|
||||
// If we're not using a spell to resurrect.
|
||||
if (magicid == 0)
|
||||
{
|
||||
// Resurrect at a bind/respawn point
|
||||
if (pEvent && pEvent->byLife == 1 && GetZoneID() != ZONE_DELOS)
|
||||
{
|
||||
SetPosition(pEvent->fPosX + x, 0.0f, pEvent->fPosZ + z);
|
||||
x = pEvent->fPosX;
|
||||
z = pEvent->fPosZ;
|
||||
}
|
||||
// Are we trying to respawn in a home zone?
|
||||
// If we're in a war zone (aside from snow wars, which apparently use different coords), use BattleZone coordinates.
|
||||
else if ((GetZoneID() <= ZONE_ELMORAD) || (GetZoneID() != ZONE_SNOW_BATTLE && GetZoneID() == (ZONE_BATTLE_BASE + g_pMain->m_byBattleZone)))
|
||||
{
|
||||
// Use the proper respawn area for our nation, as the opposite nation can
|
||||
// enter this zone at a war's invasion stage.
|
||||
x = (float)((GetNation() == KARUS ? pStartPosition->sKarusX : pStartPosition->sElmoradX) + myrand(0, pStartPosition->bRangeX));
|
||||
z = (float)((GetNation() == KARUS ? pStartPosition->sKarusZ : pStartPosition->sElmoradZ) + myrand(0, pStartPosition->bRangeZ));
|
||||
}
|
||||
else
|
||||
{
|
||||
short sx, sz;
|
||||
// If we're in a war zone (aside from snow wars, which apparently use different coords), use BattleZone coordinates.
|
||||
if ((GetZoneID() == ZONE_MORADON || GetZoneID() == ZONE_MORADONM2) && (isInArena() || isInPartyArena()))
|
||||
{
|
||||
x = (float)(MINI_ARENA_RESPAWN_X + myrand(-MINI_ARENA_RESPAWN_RADIUS, MINI_ARENA_RESPAWN_RADIUS));
|
||||
z = (float)(MINI_ARENA_RESPAWN_Z + myrand(-MINI_ARENA_RESPAWN_RADIUS, MINI_ARENA_RESPAWN_RADIUS));
|
||||
}
|
||||
else if (GetZoneID() == ZONE_CHAOS_DUNGEON)
|
||||
{
|
||||
GetStartPositionRandom(sx, sz);
|
||||
x = sx;
|
||||
z = sz;
|
||||
}
|
||||
else if (GetZoneID() == ZONE_JURAD_MOUNTAIN)
|
||||
{
|
||||
uint16 KillCount1, KillCount2, KillCount3;
|
||||
KillCount1 = GetNation() == KARUS ? g_pMain->pTempleEvent.KarusDeathRoom1[GetEventRoom()] : g_pMain->pTempleEvent.ElmoDeathRoom1[GetEventRoom()];
|
||||
KillCount2 = GetNation() == KARUS ? g_pMain->pTempleEvent.KarusDeathRoom2[GetEventRoom()] : g_pMain->pTempleEvent.ElmoDeathRoom2[GetEventRoom()];
|
||||
KillCount3 = GetNation() == KARUS ? g_pMain->pTempleEvent.KarusDeathRoom3[GetEventRoom()] : g_pMain->pTempleEvent.ElmoDeathRoom3[GetEventRoom()];
|
||||
|
||||
if (KillCount1 > 3 && KillCount2 < 4)
|
||||
{
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
x = (float) (223 + (myrand(-1,1)));
|
||||
z = (float) (672 + (myrand(-1,1)));
|
||||
}else
|
||||
{
|
||||
x = (float) (800 + (myrand(-1,1)));
|
||||
z = (float) (343 + (myrand(-1,1)));
|
||||
}
|
||||
}else if(KillCount2 > 3 && KillCount3 < 4)
|
||||
{
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
x = (float) (340 + (myrand(-1,1)));
|
||||
z = (float) (847 + (myrand(-1,1)));
|
||||
}else
|
||||
{
|
||||
x = (float) (690 + (myrand(-1,1)));
|
||||
z = (float) (172 + (myrand(-1,1)));
|
||||
}
|
||||
}else if(KillCount3 > 3)
|
||||
{
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
x = (float) (512 + (myrand(-1,1)));
|
||||
z = (float) (736 + (myrand(-1,1)));
|
||||
}else
|
||||
{
|
||||
x = (float) (512 + (myrand(-1,1)));
|
||||
z = (float) (282 + (myrand(-1,1)));
|
||||
}
|
||||
}else
|
||||
{
|
||||
GetStartPosition(sx, sz);
|
||||
x = sx;
|
||||
z = sz;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// For all else, just grab the start position (/town coordinates) from the START_POSITION table.
|
||||
else
|
||||
{
|
||||
GetStartPosition(sx, sz);
|
||||
x = sx;
|
||||
z = sz;
|
||||
}
|
||||
}
|
||||
|
||||
SetPosition(x, 0.0f, z);
|
||||
|
||||
m_LastX = x;
|
||||
m_LastZ = z;
|
||||
|
||||
m_bResHpType = USER_STANDING;
|
||||
m_bRegeneType = REGENE_NORMAL;
|
||||
}
|
||||
else // we're respawning using a resurrect skill.
|
||||
{
|
||||
_MAGIC_TYPE5 * pType = g_pMain->m_Magictype5Array.GetData(magicid);
|
||||
if (pType == nullptr)
|
||||
return;
|
||||
|
||||
MSpChange(-m_iMaxMp); // reset us to 0 MP.
|
||||
|
||||
if (m_sWhoKilledMe == -1)
|
||||
ExpChange((m_iLostExp * pType->bExpRecover) / 100); // Restore
|
||||
|
||||
m_bResHpType = USER_STANDING;
|
||||
m_bRegeneType = REGENE_MAGIC;
|
||||
}
|
||||
|
||||
Packet result(WIZ_REGENE);
|
||||
result << GetSPosX() << GetSPosZ() << GetSPosY();
|
||||
Send(&result);
|
||||
|
||||
m_tLastRegeneTime = UNIXTIME;
|
||||
m_sWhoKilledMe = -1;
|
||||
m_iLostExp = 0;
|
||||
|
||||
if (!isBlinking())
|
||||
{
|
||||
result.Initialize(AG_USER_REGENE);
|
||||
result << GetSocketID() << m_sHp;
|
||||
Send_AIServer(&result);
|
||||
}
|
||||
|
||||
SetRegion(GetNewRegionX(), GetNewRegionZ());
|
||||
|
||||
UserInOut(INOUT_RESPAWN);
|
||||
|
||||
g_pMain->RegionUserInOutForMe(this);
|
||||
g_pMain->RegionNpcInfoForMe(this);
|
||||
|
||||
InitializeStealth();
|
||||
SendUserStatusUpdate(USER_STATUS_DOT, USER_STATUS_CURE);
|
||||
SendUserStatusUpdate(USER_STATUS_POISON, USER_STATUS_CURE);
|
||||
|
||||
if (isInArena() || isInPartyArena())
|
||||
SendUserStatusUpdate(USER_STATUS_SPEED, USER_STATUS_CURE);
|
||||
|
||||
HpChange(GetMaxHealth());
|
||||
|
||||
InitType4();
|
||||
if (GetZoneID() != ZONE_CHAOS_DUNGEON)
|
||||
RecastSavedMagic();
|
||||
HpChange(GetMaxHealth());
|
||||
|
||||
// If we actually respawned (i.e. we weren't resurrected by a skill)...
|
||||
if (magicid == 0)
|
||||
{
|
||||
BlinkStart();
|
||||
// In PVP zones (not war zones), we must kick out players if they no longer
|
||||
// have any national points.
|
||||
if (GetLoyalty() == 0
|
||||
&& (GetMap()->isWarZone()
|
||||
|| isInPKZone()))
|
||||
KickOutZoneUser();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
#include "stdafx.h"
|
||||
#include "Map.h"
|
||||
#include "../shared/DateTime.h"
|
||||
|
||||
CBot::CBot()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void CBot::Initialize()
|
||||
{
|
||||
MerchantChat.clear();
|
||||
LastWarpTime = 0;
|
||||
m_tLastKillTime = 0;
|
||||
m_sChallangeAchieveID = 0;
|
||||
m_pktcount = 0;
|
||||
m_strUserID.clear();
|
||||
m_strMemo.clear();
|
||||
m_strAccountID.clear();
|
||||
for (int i = 0; i < STAT_COUNT; i++)
|
||||
m_bRebStats[i] = 0;
|
||||
m_sAchieveCoverTitle = 0;
|
||||
|
||||
memset(&m_arSellMerchantItems, 0, sizeof(m_arSellMerchantItems));
|
||||
memset(&m_arBuyMerchantItems, 0, sizeof(m_arBuyMerchantItems));
|
||||
m_bMerchantState = MERCHANT_STATE_NONE;
|
||||
m_bAuthority = 1;
|
||||
m_sBind = -1;
|
||||
m_state = GAME_STATE_CONNECTED;
|
||||
m_bPartyLeader = false;
|
||||
m_bIsChicken = false;
|
||||
m_bIsHidingHelmet = false;
|
||||
m_bIsHidingCospre = false;
|
||||
|
||||
m_bPremiumMerchant = false;
|
||||
m_bInParty = false;
|
||||
|
||||
m_bInvisibilityType = INVIS_NONE;
|
||||
|
||||
m_sDirection = 0;
|
||||
|
||||
memset(&m_bStats, 0, sizeof(m_bStats));
|
||||
|
||||
m_bAuthority = AUTHORITY_PLAYER;
|
||||
m_bLevel = 1;
|
||||
m_iExp = 0;
|
||||
m_iBank = m_iGold = 0;
|
||||
m_iLoyalty = 100;
|
||||
m_iLoyaltyMonthly = 0;
|
||||
m_iMannerPoint = 0;
|
||||
m_sHp = m_sMp = m_sSp = 0;
|
||||
|
||||
m_iMaxHp = 0;
|
||||
m_iMaxMp = 1;
|
||||
m_iMaxSp = 120;
|
||||
m_sMerchantsSocketID = -1;
|
||||
m_bResHpType = USER_STANDING;
|
||||
m_bBlockPrivateChat = false;
|
||||
m_sPrivateChatUser = -1;
|
||||
m_bNeedParty = 0x01;
|
||||
|
||||
|
||||
m_bAbnormalType = ABNORMAL_NORMAL; // User starts out in normal size.
|
||||
m_nOldAbnormalType = m_bAbnormalType;
|
||||
|
||||
|
||||
m_teamColour = TeamColourNone;
|
||||
|
||||
}
|
||||
|
||||
bool CBot::RegisterRegion()
|
||||
{
|
||||
uint16
|
||||
new_region_x = GetNewRegionX(), new_region_z = GetNewRegionZ(),
|
||||
old_region_x = GetRegionX(), old_region_z = GetRegionZ();
|
||||
|
||||
if (GetRegion() == nullptr || (old_region_x == new_region_x && old_region_z == new_region_z))
|
||||
return false;
|
||||
|
||||
AddToRegion(new_region_x, new_region_z);
|
||||
|
||||
RemoveRegion(old_region_x - new_region_x, old_region_z - new_region_z);
|
||||
InsertRegion(new_region_x - old_region_x, new_region_z - old_region_z);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBot::AddToRegion(int16 new_region_x, int16 new_region_z)
|
||||
{
|
||||
GetRegion()->Remove(this);
|
||||
SetRegion(new_region_x, new_region_z);
|
||||
GetRegion()->Add(this);
|
||||
}
|
||||
|
||||
void CBot::RemoveRegion(int16 del_x, int16 del_z)
|
||||
{
|
||||
ASSERT(GetMap() != nullptr);
|
||||
|
||||
Packet result;
|
||||
GetInOut(result, INOUT_OUT);
|
||||
g_pMain->Send_OldRegions(&result, del_x, del_z, GetMap(), GetRegionX(), GetRegionZ(),nullptr,0);
|
||||
}
|
||||
|
||||
void CBot::InsertRegion(int16 insert_x, int16 insert_z)
|
||||
{
|
||||
ASSERT(GetMap() != nullptr);
|
||||
|
||||
Packet result;
|
||||
GetInOut(result, INOUT_IN);
|
||||
g_pMain->Send_NewRegions(&result, insert_x, insert_z, GetMap(), GetRegionX(), GetRegionZ(),nullptr,0);
|
||||
}
|
||||
|
||||
void CBot::SetRegion(uint16 x /*= -1*/, uint16 z /*= -1*/)
|
||||
{
|
||||
m_sRegionX = x; m_sRegionZ = z;
|
||||
m_pRegion = m_pMap->GetRegion(x, z); // TODO: Clean this up
|
||||
}
|
||||
|
||||
void CBot::StateChangeServerDirect(uint8 bType, uint32 nBuff)
|
||||
{
|
||||
uint8 buff = *(uint8 *)&nBuff; // don't ask
|
||||
switch (bType)
|
||||
{
|
||||
case 1:
|
||||
m_bResHpType = buff;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_bNeedParty = buff;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_nOldAbnormalType = m_bAbnormalType;
|
||||
|
||||
|
||||
m_bAbnormalType = nBuff;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
m_bAbnormalType = nBuff;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
nBuff = m_bPartyLeader; // we don't set this here.
|
||||
break;
|
||||
|
||||
case 7:
|
||||
break;
|
||||
|
||||
case 8: // beginner quest
|
||||
break;
|
||||
|
||||
case 14:
|
||||
break;
|
||||
}
|
||||
|
||||
Packet result(WIZ_STATE_CHANGE);
|
||||
result << GetID() << bType << nBuff;
|
||||
SendToRegion(&result);
|
||||
}
|
||||
|
||||
void CBot::GetInOut(Packet & result, uint8 bType)
|
||||
{
|
||||
result.Initialize(WIZ_USER_INOUT);
|
||||
result << uint16(bType) << GetID();
|
||||
if (bType != INOUT_OUT)
|
||||
GetUserInfo(result);
|
||||
}
|
||||
|
||||
void CBot::UserInOut(uint8 bType)
|
||||
{
|
||||
Packet result;
|
||||
GetInOut(result, bType);
|
||||
|
||||
Guard lock(g_pMain->m_BotcharacterNameLock);
|
||||
if (bType == INOUT_OUT)
|
||||
{
|
||||
GetRegion()->Remove(this);
|
||||
m_state = GAME_STATE_CONNECTED;
|
||||
|
||||
std::string upperName = GetName();
|
||||
STRTOUPPER(upperName);
|
||||
|
||||
g_pMain->m_BotcharacterNameMap.erase(upperName);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetRegion()->Add(this);
|
||||
m_state = GAME_STATE_INGAME;
|
||||
|
||||
std::string upperName = GetName();
|
||||
STRTOUPPER(upperName);
|
||||
g_pMain->m_BotcharacterNameMap[upperName] = this;
|
||||
|
||||
}
|
||||
SendToRegion(&result);
|
||||
}
|
||||
|
||||
void CBot::SendToRegion(Packet *pkt)
|
||||
{
|
||||
g_pMain->Send_Region(pkt, GetMap(), GetRegionX(), GetRegionZ(), nullptr, 0);
|
||||
}
|
||||
|
||||
void CBot::GetUserInfo(Packet & pkt)
|
||||
{
|
||||
|
||||
pkt.SByte();
|
||||
pkt << GetName()
|
||||
<< uint16(m_bNation) << GetClanID() << m_bFame;
|
||||
|
||||
CKnights * pKnights = g_pMain->GetClanPtr(GetClanID());
|
||||
if (pKnights == nullptr)
|
||||
{
|
||||
pkt << uint32(0) << uint16(0) << uint8(0) << uint16(-1) << uint32(0) << uint8(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CKnights *aKnights = g_pMain->GetClanPtr(pKnights->GetAllianceID());
|
||||
|
||||
pkt << pKnights->GetAllianceID()
|
||||
<< pKnights->m_strName
|
||||
<< pKnights->m_byGrade << pKnights->m_byRanking
|
||||
<< uint16(pKnights->m_sMarkVersion) // symbol/mark version
|
||||
<< pKnights->GetCapeID(aKnights) // cape ID
|
||||
<< pKnights->m_bCapeR << pKnights->m_bCapeG << pKnights->m_bCapeB << uint8(0) // this is stored in 4 bytes after all.
|
||||
// not sure what this is, but it (just?) enables the clan symbol on the cape
|
||||
// value in dump was 9, but everything tested seems to behave as equally well...
|
||||
// we'll probably have to implement logic to respect requirements.
|
||||
<< uint8(1);
|
||||
}
|
||||
uint8 bInvisibilityType = m_bInvisibilityType;
|
||||
if (bInvisibilityType != INVIS_NONE)
|
||||
bInvisibilityType = INVIS_DISPEL_ON_MOVE;
|
||||
|
||||
pkt << m_bLevel << m_bRace << m_sClass
|
||||
<< GetSPosX() << GetSPosZ() << GetSPosY()
|
||||
<< m_bFace << m_nHair
|
||||
<< m_bResHpType << uint32(m_bAbnormalType)
|
||||
<< m_bNeedParty
|
||||
<< m_bAuthority
|
||||
<< m_bPartyLeader // is party leader (bool)
|
||||
<< bInvisibilityType // visibility state
|
||||
<< uint8(m_teamColour) // team colour (i.e. in soccer, 0=none, 1=blue, 2=red)
|
||||
<< m_bIsHidingHelmet << m_bIsHidingCospre // either this is correct and items are super buggy, or it causes baldness. You choose.
|
||||
<< m_sDirection // direction
|
||||
<< m_bIsChicken // chicken/beginner flag
|
||||
<< m_bRank // king flag
|
||||
<< uint16(0)
|
||||
<< int8(-1) << int8(-1); // NP ranks (total, monthly)
|
||||
|
||||
|
||||
uint8 equippedItems[] =
|
||||
{
|
||||
BREAST, LEG, HEAD, GLOVE, FOOT, SHOULDER, RIGHTHAND, LEFTHAND, CWING, CHELMET, CLEFT, CRIGHT, CTOP, FAIRY
|
||||
};
|
||||
|
||||
foreach_array (i, equippedItems)
|
||||
{
|
||||
_ITEM_DATA * pItem = &m_sItemArray[equippedItems[i]];
|
||||
|
||||
if(pItem == nullptr)
|
||||
continue;
|
||||
|
||||
pkt << pItem->nNum << pItem->sDuration << pItem->bFlag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
pkt << m_bZone << uint8(-1) << uint8(-1) << uint16(0) << uint16(0) << uint16(0) << m_bIsHidingCospre << uint8(0) << uint8(GetRebLevel()) << uint16(m_sAchieveCoverTitle) << uint16(0) << uint8(0) << uint8(0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
#pragma once
|
||||
|
||||
#include "LuaEngine.h"
|
||||
#include "../shared/KOSocket.h"
|
||||
|
||||
#include "Unit.h"
|
||||
#include "ChatHandler.h"
|
||||
|
||||
|
||||
|
||||
#include "GameDefine.h"
|
||||
|
||||
class CGameServerDlg;
|
||||
|
||||
class CBot
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual uint16 GetID() { return m_sSid; }
|
||||
|
||||
std::string & GetAccountName() { return m_strAccountID; }
|
||||
virtual std::string & GetName() { return m_strUserID; }
|
||||
|
||||
std::string m_strAccountID, m_strUserID, m_strMemo;
|
||||
GameState m_state;
|
||||
float m_curx, m_curz, m_cury;
|
||||
uint8 m_bNation, m_bLevel, m_bZone;
|
||||
std::string MerchantChat;
|
||||
KOMap * m_pMap;
|
||||
CRegion * m_pRegion;
|
||||
uint8 m_bResHpType;
|
||||
uint32 m_pktcount;
|
||||
uint8 m_bRace;
|
||||
uint16 m_sClass;
|
||||
time_t LastWarpTime;
|
||||
uint32 m_nHair;
|
||||
time_t m_tLastKillTime;
|
||||
uint16 m_sChallangeAchieveID;
|
||||
uint16 m_sSid;
|
||||
uint8 m_bRank;
|
||||
uint8 m_bTitle;
|
||||
int64 m_iExp;
|
||||
uint32 m_iLoyalty,m_iLoyaltyMonthly;
|
||||
uint32 m_iMannerPoint;
|
||||
uint8 m_bFace;
|
||||
uint8 m_bCity;
|
||||
int16 m_bKnights;
|
||||
uint8 m_bFame;
|
||||
int16 m_sHp, m_sMp, m_sSp;
|
||||
uint8 m_bStats[STAT_COUNT];
|
||||
uint8 m_bRebStats[STAT_COUNT];
|
||||
uint8 m_reblvl;
|
||||
uint8 m_bAuthority;
|
||||
int16 m_sPoints; // this is just to shut the compiler up
|
||||
uint32 m_iGold, m_iBank;
|
||||
int16 m_sBind;
|
||||
_ITEM_DATA m_sItemArray[INVENTORY_TOTAL];
|
||||
int8 m_bMerchantState;
|
||||
int8 m_bMerchantStatex;
|
||||
|
||||
uint8 m_bstrSkill[10];
|
||||
|
||||
int16 m_sMerchantsSocketID;
|
||||
std::list<uint16> m_arMerchantLookers;
|
||||
_MERCH_DATA m_arSellMerchantItems[MAX_MERCH_ITEMS]; //What is this person selling? Stored in "_MERCH_DATA" structure.
|
||||
_MERCH_DATA m_arBuyMerchantItems[MAX_MERCH_ITEMS]; //What is this person selling? Stored in "_MERCH_DATA" structure.
|
||||
bool m_bPremiumMerchant;
|
||||
|
||||
INLINE _ITEM_DATA * GetItem(uint8 pos)
|
||||
{
|
||||
return &m_sItemArray[pos];
|
||||
}
|
||||
INLINE uint8 GetNation() { return m_bNation; }
|
||||
INLINE uint8 GetRace() { return m_bRace; }
|
||||
INLINE uint8 GetLevel() { return m_bLevel; }
|
||||
INLINE uint16 GetClass() { return m_sClass; }
|
||||
INLINE uint8 GetStat(StatType type)
|
||||
{
|
||||
if (type >= STAT_COUNT)
|
||||
return 0;
|
||||
|
||||
return m_bStats[type];
|
||||
}
|
||||
|
||||
uint16 m_sAchieveCoverTitle;
|
||||
|
||||
float m_oldx, m_oldy, m_oldz;
|
||||
int16 m_sDirection;
|
||||
|
||||
uint8 m_bNeedParty;
|
||||
|
||||
bool m_bInParty;
|
||||
bool m_bPartyLeader;
|
||||
|
||||
bool m_bIsChicken; // Is the character taking the beginner/chicken quest?
|
||||
bool m_bIsHidingHelmet;
|
||||
bool m_bIsHidingCospre;
|
||||
|
||||
short m_iMaxHp, m_iMaxMp;
|
||||
uint8 m_iMaxSp;
|
||||
uint8 m_bInvisibilityType;
|
||||
|
||||
uint32 m_bAbnormalType; // Is the player normal, a giant, or a dwarf?
|
||||
uint32 m_nOldAbnormalType;
|
||||
bool m_bBlockPrivateChat;
|
||||
short m_sPrivateChatUser;
|
||||
|
||||
uint16 m_sRegionX, m_sRegionZ; // this is probably redundant
|
||||
|
||||
TeamColour m_teamColour;
|
||||
public:
|
||||
INLINE uint8 GetUniqueLevel() { return m_bRebStats[STAT_STR];} // Char Rebirth mi
|
||||
INLINE uint8 GetRebLevel() { return m_reblvl; }
|
||||
INLINE uint16 GetSPosX() { return uint16(GetX() * 10); };
|
||||
INLINE uint16 GetSPosY() { return uint16(GetY() * 10); };
|
||||
INLINE uint16 GetSPosZ() { return uint16(GetZ() * 10); };
|
||||
INLINE CRegion * GetRegion() { return m_pRegion; }
|
||||
void SetRegion(uint16 x = -1, uint16 z = -1);
|
||||
void StateChangeServerDirect(uint8 bType, uint32 nBuff);
|
||||
INLINE KOMap * GetMap() { return m_pMap; }
|
||||
INLINE float GetX() { return m_curx; }
|
||||
INLINE void SetPosition(float fx, float fy, float fz)
|
||||
{
|
||||
m_curx = fx;
|
||||
m_curz = fz;
|
||||
m_cury = fy;
|
||||
}
|
||||
|
||||
bool RegisterRegion();
|
||||
void AddToRegion(int16 new_region_x, int16 new_region_z);
|
||||
void RemoveRegion(int16 del_x, int16 del_z);
|
||||
void InsertRegion(int16 insert_x, int16 insert_z);
|
||||
|
||||
INLINE uint16 GetNewRegionX() { return (uint16)(GetX()) / VIEW_DISTANCE; }
|
||||
INLINE uint16 GetNewRegionZ() { return (uint16)(GetZ()) / VIEW_DISTANCE; }
|
||||
INLINE float GetY() { return m_cury; }
|
||||
INLINE float GetZ() { return m_curz; }
|
||||
INLINE int16 GetClanID() { return m_bKnights; }
|
||||
INLINE void SetClanID(int16 val) { m_bKnights = val; }
|
||||
INLINE uint16 GetRegionX() { return m_sRegionX; }
|
||||
INLINE uint16 GetRegionZ() { return m_sRegionZ; }
|
||||
INLINE uint32 GetCoins() { return m_iGold; }
|
||||
INLINE uint32 GetInnCoins() { return m_iBank; }
|
||||
INLINE uint32 GetLoyalty() { return m_iLoyalty; }
|
||||
INLINE uint32 GetMonthlyLoyalty() { return m_iLoyaltyMonthly; }
|
||||
INLINE uint32 GetManner() { return m_iMannerPoint; }
|
||||
INLINE bool isInGame() { return m_state == GAME_STATE_INGAME; }
|
||||
INLINE bool isMerchanting() { return (GetMerchantState() != MERCHANT_STATE_NONE); }
|
||||
INLINE bool isSellingMerchant() { return GetMerchantState() == MERCHANT_STATE_SELLING; }
|
||||
INLINE bool isBuyingMerchant() { return GetMerchantState() == MERCHANT_STATE_BUYING; }
|
||||
INLINE int8 GetMerchantState() { return m_bMerchantState; }
|
||||
virtual int32 GetHealth() { return m_sHp; }
|
||||
virtual int32 GetMaxHealth() { return m_iMaxHp; }
|
||||
virtual int32 GetMana() { return m_sMp; }
|
||||
virtual int32 GetMaxMana() { return m_iMaxMp; }
|
||||
|
||||
void Home();
|
||||
void SetMaxMp();
|
||||
void SetMaxSp();
|
||||
void SetMaxHp(int iFlag = 0);
|
||||
void LogOut();
|
||||
|
||||
void SendToRegion(Packet *pkt);
|
||||
virtual void GetInOut(Packet & result, uint8 bType);
|
||||
void UserInOut(uint8 bType);
|
||||
void GetUserInfo(Packet & pkt);
|
||||
virtual void Initialize();
|
||||
~CBot() {}
|
||||
CBot();
|
||||
|
||||
};
|
||||
@@ -0,0 +1,790 @@
|
||||
#include "stdafx.h"
|
||||
#include "DBAgent.h"
|
||||
|
||||
#pragma region Nation Transfer
|
||||
|
||||
|
||||
void CUser::SendNationChange()
|
||||
{
|
||||
if (isDead()
|
||||
|| isTrading()
|
||||
|| isMerchanting()
|
||||
|| isStoreOpen()
|
||||
|| isSellingMerchant()
|
||||
|| isBuyingMerchant()
|
||||
|| isMining()
|
||||
|| m_bMerchantStatex)
|
||||
return;
|
||||
|
||||
Packet result(WIZ_NATION_CHANGE);
|
||||
|
||||
if(!CheckExistItem(ITEM_NATION_TRANSFER))
|
||||
{
|
||||
result << uint8(3) << uint8(7);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInClan())
|
||||
{
|
||||
result << uint8(2) << uint8(2);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isKing())
|
||||
{
|
||||
result << uint8(3) << uint8(3);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
result.DByte();
|
||||
uint8 YanChar = g_DBAgent.YanChar(GetAccountName());
|
||||
uint8 YanCharClan = g_DBAgent.YanCharClan(GetAccountName());
|
||||
|
||||
if (YanChar == 0)
|
||||
{
|
||||
result << uint8(3) << uint8(6);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (YanCharClan == 1)
|
||||
{
|
||||
result << uint8(2) << uint8(2);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string strCharID1, strCharID2, strCharID3, strCharID4;
|
||||
uint16 Class1 = 0, Class2 = 0, Class3 = 0, Class4 = 0;
|
||||
|
||||
g_DBAgent.GetAllCharID(GetAccountName(), strCharID1, strCharID2, strCharID3, strCharID4);
|
||||
|
||||
result << uint8(2) << uint8(1) << YanChar;
|
||||
|
||||
if(!strCharID1.empty())
|
||||
Class1 = g_DBAgent.LoadAccountNTS(strCharID1);
|
||||
if(!strCharID2.empty())
|
||||
Class2 = g_DBAgent.LoadAccountNTS(strCharID2);
|
||||
if(!strCharID3.empty())
|
||||
Class3 = g_DBAgent.LoadAccountNTS(strCharID3);
|
||||
if(!strCharID4.empty())
|
||||
Class4 = g_DBAgent.LoadAccountNTS(strCharID4);
|
||||
|
||||
if(Class1 > 0)
|
||||
result << uint16(0) << strCharID1 << uint8(0) << uint8(0) << uint16(GetNation() == 1 ? (Class1 + 100) : (Class1 - 100)) << uint8(0) << uint32(0);
|
||||
if(Class2 > 0)
|
||||
result << uint16(1) << strCharID2 << uint8(0) << uint8(0) << uint16(GetNation() == 1 ? (Class2 + 100) : (Class2 - 100)) << uint8(0) << uint32(0);
|
||||
if(Class3 > 0)
|
||||
result << uint16(2) << strCharID3 << uint8(0) << uint8(0) << uint16(GetNation() == 1 ? (Class3 + 100) : (Class3 - 100)) << uint8(0) << uint32(0);
|
||||
if(Class4 > 0)
|
||||
result << uint16(3) << strCharID4 << uint8(0) << uint8(0) << uint16(GetNation() == 1 ? (Class4 + 100) : (Class4 - 100)) << uint8(0) << uint32(0);
|
||||
|
||||
Send(&result);
|
||||
|
||||
}
|
||||
|
||||
void CUser::NationChangeHandle(Packet & pkt)
|
||||
{
|
||||
|
||||
uint8 opcode = pkt.read<uint8>();
|
||||
|
||||
switch(opcode)
|
||||
{
|
||||
case 3:
|
||||
NationChange(pkt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CUser::NationChange(Packet & pkt)
|
||||
{
|
||||
if (isDead()
|
||||
|| isTrading()
|
||||
|| isMerchanting()
|
||||
|| isStoreOpen()
|
||||
|| isSellingMerchant()
|
||||
|| isBuyingMerchant()
|
||||
|| isMining()
|
||||
|| m_bMerchantStatex)
|
||||
return;
|
||||
|
||||
uint8 opcode;
|
||||
pkt >> opcode;
|
||||
|
||||
if(opcode == 0)
|
||||
return;
|
||||
|
||||
|
||||
Packet result(WIZ_NATION_CHANGE);
|
||||
|
||||
if(!CheckExistItem(ITEM_NATION_TRANSFER))
|
||||
{
|
||||
result << uint8(3) << uint8(7);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInClan())
|
||||
{
|
||||
result << uint8(2) << uint8(2);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isKing())
|
||||
{
|
||||
result << uint8(3) << uint8(3);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 YanChar = g_DBAgent.YanChar(GetAccountName());
|
||||
uint8 YanCharClan = g_DBAgent.YanCharClan(GetAccountName());
|
||||
|
||||
if (YanChar == 0)
|
||||
{
|
||||
result << uint8(3) << uint8(6);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (YanCharClan == 1)
|
||||
{
|
||||
result << uint8(2) << uint8(2);
|
||||
Send(&result);
|
||||
return;
|
||||
}// hata kýsmý
|
||||
|
||||
// Okuma kýsmý
|
||||
|
||||
uint8 Count;
|
||||
uint16 CharNum[4];
|
||||
std::string Nick[4];
|
||||
uint8 nRace[4];
|
||||
uint8 unkNown1[4];
|
||||
uint32 unkNown2[4];
|
||||
uint8 hisRace = 0, myRace = 0;
|
||||
|
||||
nRace[0] = 0;
|
||||
nRace[1] = 0;
|
||||
nRace[2] = 0;
|
||||
nRace[3] = 0;
|
||||
|
||||
|
||||
pkt >> Count;
|
||||
|
||||
if (Count == 0)
|
||||
{
|
||||
result << uint8(3) << uint8(6);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < Count; i++)
|
||||
{
|
||||
pkt >> CharNum[i] >> Nick[i] >> hisRace >> unkNown1[i] >> unkNown2[i];
|
||||
nRace[CharNum[i]] = hisRace;
|
||||
|
||||
if(hisRace == 0
|
||||
|| (hisRace < 10 && GetNation() == 1)
|
||||
|| (hisRace > 14)
|
||||
|| (hisRace > 6 && GetNation() == 2))
|
||||
{
|
||||
result << uint8(3) << uint8(6);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint8 nRet = g_DBAgent.NationTransfer(GetAccountName(),nRace[0],nRace[1],nRace[2],nRace[3]);
|
||||
|
||||
myRace = g_DBAgent.LoadCharRace(GetName());
|
||||
|
||||
if (myRace == 0)
|
||||
{
|
||||
result << uint8(2) << uint8(0);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nRet != 1)
|
||||
{
|
||||
result << uint8(3) << uint8(6);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
RobItem(ITEM_NATION_TRANSFER);
|
||||
|
||||
|
||||
|
||||
m_bRank = 0;
|
||||
m_bTitle = 0;
|
||||
m_bRace = myRace;
|
||||
m_sClass = GetNation() == KARUS ? GetClass() + 100 : GetClass() - 100;
|
||||
m_bNation = GetNation() == KARUS ? ELMORAD : KARUS;
|
||||
|
||||
if (GetHealth() < (GetMaxHealth() / 2))
|
||||
HpChange(GetMaxHealth());
|
||||
|
||||
SendMyInfo();
|
||||
|
||||
UserInOut(INOUT_OUT);
|
||||
SetRegion(GetNewRegionX(), GetNewRegionZ());
|
||||
UserInOut(INOUT_WARP);
|
||||
|
||||
g_pMain->UserInOutForMe(this);
|
||||
g_pMain->NpcInOutForMe(this);
|
||||
g_pMain->MerchantUserInOutForMe(this);
|
||||
|
||||
ResetWindows();
|
||||
|
||||
InitType4();
|
||||
RecastSavedMagic();
|
||||
|
||||
result << uint8(3) << uint8(1);
|
||||
Send(&result);
|
||||
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
uint8 CUser::GetNewRace()
|
||||
{
|
||||
|
||||
uint8 nNewRace = 0;
|
||||
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
if (m_bRace == KARUS_BIG)
|
||||
nNewRace = BABARIAN;
|
||||
else if (m_bRace == KARUS_MIDDLE)
|
||||
nNewRace = ELMORAD_MAN;
|
||||
else if (m_bRace == KARUS_SMALL)
|
||||
nNewRace = ELMORAD_MAN;
|
||||
else if (m_bRace == KARUS_WOMAN)
|
||||
nNewRace = ELMORAD_WOMAN;
|
||||
else if(m_bRace == KARUS_MONSTER)
|
||||
nNewRace = ELMORAD_MONSTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bRace == BABARIAN)
|
||||
nNewRace = KARUS_BIG;
|
||||
// El Morad Male and El Morad Warriors
|
||||
else if (m_bRace == ELMORAD_MAN && isWarrior())
|
||||
nNewRace = KARUS_BIG;
|
||||
// El Morad Female and El Morad Warriors
|
||||
else if (m_bRace == ELMORAD_WOMAN && isWarrior())
|
||||
nNewRace = KARUS_BIG;
|
||||
// El Morad Male and El Morad Rogues
|
||||
else if (m_bRace == ELMORAD_MAN && isRogue())
|
||||
nNewRace = KARUS_MIDDLE;
|
||||
// El Morad Female and El Morad Rogues
|
||||
else if (m_bRace == ELMORAD_WOMAN && isRogue())
|
||||
nNewRace = KARUS_MIDDLE;
|
||||
// El Morad Male and El Morad Magicians
|
||||
else if (m_bRace == ELMORAD_MAN && isMage())
|
||||
nNewRace = KARUS_SMALL;
|
||||
// El Morad Female and El Morad Magicians
|
||||
else if (m_bRace == ELMORAD_WOMAN && isMage())
|
||||
nNewRace = KARUS_WOMAN;
|
||||
// El Morad Male and El Morad Priests
|
||||
else if (m_bRace == ELMORAD_MAN && isPriest())
|
||||
nNewRace = KARUS_MIDDLE;
|
||||
// El Morad Female and El Morad Priests
|
||||
else if (m_bRace == ELMORAD_WOMAN && isPriest())
|
||||
nNewRace = KARUS_WOMAN;
|
||||
else if(m_bRace == ELMORAD_MONSTER)
|
||||
nNewRace = KARUS_MONSTER;
|
||||
}
|
||||
|
||||
return nNewRace;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Gender Change
|
||||
|
||||
void CUser::GenderChange(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_GENDER_CHANGE);
|
||||
|
||||
if (isDead()
|
||||
|| isTrading()
|
||||
|| isMerchanting()
|
||||
|| isStoreOpen()
|
||||
|| isSellingMerchant()
|
||||
|| isBuyingMerchant()
|
||||
|| isMining()
|
||||
|| m_bMerchantStatex)
|
||||
return;
|
||||
|
||||
if (GetRace() == 0
|
||||
|| GetRace() == KARUS_BIG
|
||||
|| (GetRace() == KARUS_MIDDLE && GetClass() % 100 < 10)
|
||||
|| GetRace() == KARUS_MONSTER
|
||||
|| GetRace() == ELMORAD_MONSTER)
|
||||
goto fail_return;
|
||||
|
||||
uint8 newRace, newFace, resultCode = 0, opCode;
|
||||
uint32 newHair;
|
||||
|
||||
pkt >> opCode >> newRace >> newFace >> newHair;
|
||||
|
||||
if(!CheckExistItem(ITEM_GENDER_CHANGE))
|
||||
goto fail_return;
|
||||
|
||||
if(newRace == 0 || newFace == 0 || newHair == 0)
|
||||
goto fail_return;
|
||||
|
||||
if(newRace < 10 && GetNation() != 1)
|
||||
goto fail_return;
|
||||
|
||||
if(newRace > 10 && GetNation() != 2)
|
||||
goto fail_return;
|
||||
|
||||
if(newRace > 13 || newRace == GetRace())
|
||||
goto fail_return;
|
||||
|
||||
if(newRace > 5 && GetNation() == 1)
|
||||
goto fail_return;
|
||||
|
||||
|
||||
m_bRace = newRace;
|
||||
m_nHair = newHair;
|
||||
m_bFace = newFace;
|
||||
|
||||
resultCode = g_DBAgent.UpdateUser(GetName(), UPDATE_PACKET_SAVE, this);
|
||||
|
||||
if(resultCode < 1)
|
||||
goto fail_return;
|
||||
|
||||
result << uint8(1) << uint16(GetID()) << newRace << newFace << newHair;
|
||||
SendToRegion(&result,nullptr,GetEventRoom());
|
||||
|
||||
RobItem(ITEM_GENDER_CHANGE);
|
||||
|
||||
if (GetHealth() < (GetMaxHealth() / 2))
|
||||
HpChange(GetMaxHealth());
|
||||
|
||||
return;
|
||||
fail_return:
|
||||
result << resultCode;
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Job Change
|
||||
|
||||
uint8 CUser::JobChange(uint8 NewJob /*= 0*/)
|
||||
{
|
||||
|
||||
if (isDead()
|
||||
|| isTrading()
|
||||
|| isMerchanting()
|
||||
|| isStoreOpen()
|
||||
|| isSellingMerchant()
|
||||
|| isBuyingMerchant()
|
||||
|| isMining()
|
||||
|| m_bMerchantStatex)
|
||||
return 5;
|
||||
|
||||
uint8 bNewClass = 0, bNewRace = 0;
|
||||
uint8 bResult = 0;
|
||||
|
||||
if (NewJob < 1 || NewJob > 5)
|
||||
return 5; // Unknown job is selected...
|
||||
|
||||
if(!CheckExistItem(ITEM_JOB_CHANGE))
|
||||
return 6; // Job Change scroll is not found...
|
||||
|
||||
for (int i = 0; i < SLOT_MAX; i++)
|
||||
{
|
||||
if (m_sItemArray[i].nNum)
|
||||
{
|
||||
bResult = 7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bResult == 7)
|
||||
{
|
||||
Packet result(WIZ_CLASS_CHANGE, uint8(ALL_POINT_CHANGE));
|
||||
result << uint8(4) << int(0);
|
||||
Send(&result);
|
||||
return bResult; // While there are items equipped on you.
|
||||
}
|
||||
|
||||
// If bResult between 1 and 5 character already selected job...
|
||||
|
||||
// If selected a new job Warrior
|
||||
if (NewJob == 1)
|
||||
{
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
// Beginner Karus Rogue, Magician, Priest
|
||||
if (isBeginnerRogue() || isBeginnerMage() || isBeginnerPriest() || isBeginnerPorutu())
|
||||
{
|
||||
bNewClass = KARUWARRIOR;
|
||||
bNewRace = KARUS_BIG;
|
||||
}
|
||||
// Skilled Karus Rogue, Magician, Priest
|
||||
else if (isNoviceRogue() || isNoviceMage() || isNovicePriest() || isNovicePorutu())
|
||||
{
|
||||
bNewClass = BERSERKER;
|
||||
bNewRace = KARUS_BIG;
|
||||
}
|
||||
// Mastered Karus Rogue, Magician, Priest
|
||||
else if (isMasteredRogue() || isMasteredMage() || isMasteredPriest() || isMasteredPorutu())
|
||||
{
|
||||
bNewClass = GUARDIAN;
|
||||
bNewRace = KARUS_BIG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Beginner El Morad Rogue, Magician, Priest
|
||||
if (isBeginnerRogue() || isBeginnerMage() || isBeginnerPriest() || isBeginnerPorutu())
|
||||
{
|
||||
bNewClass = ELMORWARRRIOR;
|
||||
if(GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Skilled El Morad Rogue, Magician, Priest
|
||||
else if (isNoviceRogue() || isNoviceMage() || isNovicePriest() || isNovicePorutu())
|
||||
{
|
||||
bNewClass = BLADE;
|
||||
if(GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Mastered El Morad Rogue, Magician, Priest
|
||||
else if (isMasteredRogue() || isMasteredMage() || isMasteredPriest() || isMasteredPorutu())
|
||||
{
|
||||
bNewClass = PROTECTOR;
|
||||
if(GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
}
|
||||
|
||||
// Character already Warrior.
|
||||
if (bNewClass == 0 || bNewRace == 0)
|
||||
bResult = NewJob;
|
||||
}
|
||||
|
||||
// If selected a new job Rogue
|
||||
if (NewJob == 2)
|
||||
{
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
// Beginner Karus Warrior, Magician, Priest
|
||||
if (isBeginnerWarrior() || isBeginnerMage() || isBeginnerPriest() || isBeginnerPorutu())
|
||||
{
|
||||
bNewClass = KARUROGUE;
|
||||
bNewRace = KARUS_MIDDLE;
|
||||
}
|
||||
// Skilled Karus Warrior, Magician, Priest
|
||||
else if (isNoviceWarrior() || isNoviceMage() || isNovicePriest() || isNovicePorutu())
|
||||
{
|
||||
bNewClass = HUNTER;
|
||||
bNewRace = KARUS_MIDDLE;
|
||||
}
|
||||
// Mastered Karus Warrior, Magician, Priest
|
||||
else if (isMasteredWarrior() || isMasteredMage() || isMasteredPriest() || isMasteredPorutu())
|
||||
{
|
||||
bNewClass = PENETRATOR;
|
||||
bNewRace = KARUS_MIDDLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Beginner El Morad Warrior, Magician, Priest
|
||||
if (isBeginnerWarrior() || isBeginnerMage() || isBeginnerPriest() || isBeginnerPorutu())
|
||||
{
|
||||
bNewClass = ELMOROGUE;
|
||||
|
||||
if (GetRace() == BABARIAN || GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Skilled El Morad Warrior, Magician, Priest
|
||||
else if (isNoviceWarrior() || isNoviceMage() || isNovicePriest() || isNovicePorutu())
|
||||
{
|
||||
bNewClass = RANGER;
|
||||
|
||||
if (GetRace() == BABARIAN || GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Mastered El Morad Warrior, Magician, Priest
|
||||
else if (isMasteredWarrior() || isMasteredMage() || isMasteredPriest() || isMasteredPorutu())
|
||||
{
|
||||
bNewClass = ASSASSIN;
|
||||
|
||||
if (GetRace() == BABARIAN || GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
}
|
||||
|
||||
// Character already Rogue.
|
||||
if (bNewClass == 0 || bNewRace == 0)
|
||||
bResult = NewJob;
|
||||
}
|
||||
|
||||
// If selected a new job Magician
|
||||
if (NewJob == 3)
|
||||
{
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
// Beginner Karus Warrior, Rogue, Priest
|
||||
if (isBeginnerWarrior() || isBeginnerRogue() || isBeginnerPriest() || isBeginnerPorutu())
|
||||
{
|
||||
bNewClass = KARUWIZARD;
|
||||
|
||||
if (GetRace() == KARUS_BIG || GetRace() == KARUS_MIDDLE || GetRace() == KARUS_MONSTER)
|
||||
bNewRace = KARUS_SMALL;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Skilled Karus Warrior, Rogue, Priest
|
||||
else if (isNoviceWarrior() || isNoviceRogue() || isNovicePriest() || isNovicePorutu())
|
||||
{
|
||||
bNewClass = SORSERER;
|
||||
|
||||
if (GetRace() == KARUS_BIG || GetRace() == KARUS_MIDDLE || GetRace() == KARUS_MONSTER)
|
||||
bNewRace = KARUS_SMALL;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Mastered Karus Warrior, Rogue, Priest
|
||||
else if (isMasteredWarrior() || isMasteredRogue() || isMasteredPriest() || isMasteredPorutu())
|
||||
{
|
||||
bNewClass = NECROMANCER;
|
||||
|
||||
if (GetRace() == KARUS_BIG || GetRace() == KARUS_MIDDLE || GetRace() == KARUS_MONSTER)
|
||||
bNewRace = KARUS_SMALL;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Beginner El Morad Warrior, Rogue, Priest
|
||||
if (isBeginnerWarrior() || isBeginnerRogue() || isBeginnerPriest() || isBeginnerPorutu())
|
||||
{
|
||||
bNewClass = ELMOWIZARD;
|
||||
|
||||
if (GetRace() == BABARIAN || GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Skilled El Morad Warrior, Rogue, Priest
|
||||
else if (isNoviceWarrior() || isNoviceRogue() || isNovicePriest() || isNovicePorutu())
|
||||
{
|
||||
bNewClass = MAGE;
|
||||
|
||||
if (GetRace() == BABARIAN || GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Mastered El Morad Warrior, Rogue, Priest
|
||||
else if (isMasteredWarrior() || isMasteredRogue() || isMasteredPriest() || isMasteredPorutu())
|
||||
{
|
||||
bNewClass = ENCHANTER;
|
||||
|
||||
if (GetRace() == BABARIAN || GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
}
|
||||
|
||||
// Character already Magician.
|
||||
if (bNewClass == 0 || bNewRace == 0)
|
||||
bResult = NewJob;
|
||||
}
|
||||
|
||||
// If selected a new job Priest
|
||||
if (NewJob == 4)
|
||||
{
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
// Beginner Karus Warrior, Rogue, Magician
|
||||
if (isBeginnerWarrior() || isBeginnerRogue() || isBeginnerMage() || isBeginnerPorutu())
|
||||
{
|
||||
bNewClass = KARUPRIEST;
|
||||
|
||||
if (GetRace() == KARUS_BIG || GetRace() == KARUS_SMALL || GetRace() == KARUS_MONSTER)
|
||||
bNewRace = KARUS_MIDDLE;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Skilled Karus Warrior, Rogue, Magician
|
||||
else if (isNoviceWarrior() || isNoviceRogue() || isNoviceMage() || isNovicePorutu())
|
||||
{
|
||||
bNewClass = SHAMAN;
|
||||
|
||||
if (GetRace() == KARUS_BIG || GetRace() == KARUS_SMALL || GetRace() == KARUS_MONSTER)
|
||||
bNewRace = KARUS_MIDDLE;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Mastered Karus Warrior, Rogue, Magician
|
||||
else if (isMasteredWarrior() || isMasteredRogue() || isMasteredMage() || isMasteredPorutu())
|
||||
{
|
||||
bNewClass = DARKPRIEST;
|
||||
|
||||
if (GetRace() == KARUS_BIG || GetRace() == KARUS_SMALL || GetRace() == KARUS_MONSTER)
|
||||
bNewRace = KARUS_MIDDLE;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Beginner El Morad Warrior, Rogue, Magician
|
||||
if (isBeginnerWarrior() || isBeginnerRogue() || isBeginnerMage() || isBeginnerPorutu())
|
||||
{
|
||||
bNewClass = ELMOPRIEST;
|
||||
|
||||
if (GetRace() == BABARIAN || GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Skilled El Morad Warrior, Rogue, Magician
|
||||
else if (isNoviceWarrior() || isNoviceRogue() || isNoviceMage() || isNovicePorutu())
|
||||
{
|
||||
bNewClass = CLERIC;
|
||||
|
||||
if (GetRace() == BABARIAN || GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
// Mastered El Morad Warrior, Rogue, Magician
|
||||
else if (isMasteredWarrior() || isMasteredRogue() || isMasteredMage() || isMasteredPorutu())
|
||||
{
|
||||
bNewClass = DRUID;
|
||||
|
||||
if (GetRace() == BABARIAN || GetRace() == ELMORAD_MONSTER)
|
||||
bNewRace = ELMORAD_MAN;
|
||||
else
|
||||
bNewRace = GetRace();
|
||||
}
|
||||
}
|
||||
|
||||
// Character already Priest.
|
||||
if (bNewClass == 0 || bNewRace == 0)
|
||||
bResult = NewJob;
|
||||
}
|
||||
|
||||
|
||||
// If selected a new job Kurian
|
||||
if (NewJob == 5 || NewJob == 6)
|
||||
{
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
// Beginner Karus Warrior, Rogue, Magician
|
||||
if (isBeginnerRogue() || isBeginnerMage() || isBeginnerPriest() || isBeginnerWarrior())
|
||||
{
|
||||
bNewClass = PORUTU;
|
||||
bNewRace = KARUS_MONSTER;
|
||||
}
|
||||
// Skilled Karus Warrior, Rogue, Magician
|
||||
else if (isNoviceRogue() || isNoviceMage() || isNovicePriest() || isNoviceWarrior())
|
||||
{
|
||||
bNewClass = PORUTUSKILLED;
|
||||
bNewRace = KARUS_MONSTER;
|
||||
}
|
||||
// Mastered Karus Warrior, Rogue, Magician
|
||||
else if (isMasteredRogue() || isMasteredMage() || isMasteredPriest() || isMasteredWarrior())
|
||||
{
|
||||
bNewClass = PORUTUMASTER;
|
||||
bNewRace = KARUS_MONSTER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Beginner El Morad Warrior, Rogue, Magician
|
||||
if (isBeginnerRogue() || isBeginnerMage() || isBeginnerPriest() || isBeginnerWarrior())
|
||||
{
|
||||
bNewClass = KURIAN;
|
||||
bNewRace = ELMORAD_MONSTER;
|
||||
}
|
||||
// Skilled El Morad Warrior, Rogue, Magician
|
||||
else if (isNoviceRogue() || isNoviceMage() || isNovicePriest() || isNoviceWarrior())
|
||||
{
|
||||
bNewClass = KURIANSKILLED;
|
||||
bNewRace = ELMORAD_MONSTER;
|
||||
}
|
||||
// Mastered El Morad Warrior, Rogue, Magician
|
||||
else if (isMasteredRogue() || isMasteredMage() || isMasteredPriest() || isMasteredWarrior())
|
||||
{
|
||||
bNewClass = KURIANMASTER;
|
||||
bNewRace = ELMORAD_MONSTER;
|
||||
}
|
||||
}
|
||||
|
||||
// Character already Kurian.
|
||||
if (bNewClass == 0 || bNewRace == 0)
|
||||
bResult = NewJob;
|
||||
}
|
||||
|
||||
|
||||
if (bResult == 0)
|
||||
{
|
||||
RobItem(ITEM_JOB_CHANGE,1,true);
|
||||
|
||||
m_sClass = bNewClass;
|
||||
m_bRace = bNewRace;
|
||||
|
||||
// Reset stat and skill points...
|
||||
AllPointChange(true);
|
||||
AllSkillPointChange(true);
|
||||
|
||||
g_DBAgent.UpdateUser(GetName(), UPDATE_PACKET_SAVE, this);;
|
||||
|
||||
if (GetHealth() < (GetMaxHealth() / 2))
|
||||
HpChange(GetMaxHealth());
|
||||
|
||||
SendMyInfo();
|
||||
|
||||
UserInOut(INOUT_OUT);
|
||||
SetRegion(GetNewRegionX(), GetNewRegionZ());
|
||||
UserInOut(INOUT_WARP);
|
||||
|
||||
g_pMain->UserInOutForMe(this);
|
||||
g_pMain->NpcInOutForMe(this);
|
||||
g_pMain->MerchantUserInOutForMe(this);
|
||||
|
||||
ResetWindows();
|
||||
|
||||
InitType4();
|
||||
RecastSavedMagic();
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
@@ -0,0 +1,976 @@
|
||||
#include "stdafx.h"
|
||||
#include "Map.h"
|
||||
|
||||
void CUser::MoveProcess(Packet & pkt)
|
||||
{
|
||||
ASSERT(GetMap() != nullptr);
|
||||
if (m_bWarp || isDead())
|
||||
return;
|
||||
|
||||
uint16 will_x, will_z, will_y;
|
||||
int16 speed = 0;
|
||||
float real_x, real_z, real_y;
|
||||
uint8 echo;
|
||||
|
||||
pkt >> will_x >> will_z >> will_y >> speed >> echo;
|
||||
real_x = will_x/10.0f; real_z = will_z/10.0f; real_y = will_y/10.0f;
|
||||
|
||||
m_sSpeed = speed;
|
||||
|
||||
|
||||
SpeedHackUser();
|
||||
|
||||
if (!GetMap()->IsValidPosition(real_x, real_z, real_y))
|
||||
return;
|
||||
|
||||
if (m_oldx != GetX() || m_oldz != GetZ())
|
||||
{
|
||||
m_oldx = GetX();
|
||||
m_oldy = GetY();
|
||||
m_oldz = GetZ();
|
||||
}
|
||||
|
||||
// TODO: Ensure this is checked properly to prevent speedhacking
|
||||
SetPosition(real_x, real_y, real_z);
|
||||
|
||||
if (RegisterRegion())
|
||||
{
|
||||
g_pMain->RegionNpcInfoForMe(this);
|
||||
g_pMain->RegionUserInOutForMe(this);
|
||||
g_pMain->MerchantUserInOutForMe(this);
|
||||
}
|
||||
|
||||
if (m_bInvisibilityType == INVIS_DISPEL_ON_MOVE)
|
||||
CMagicProcess::RemoveStealth(this, INVIS_DISPEL_ON_MOVE);
|
||||
|
||||
Packet result(WIZ_MOVE);
|
||||
result << GetSocketID() << will_x << will_z << will_y << speed << echo;
|
||||
SendToRegion(&result,nullptr,GetEventRoom());
|
||||
|
||||
GetMap()->CheckEvent(real_x, real_z, this);
|
||||
|
||||
// Petimi yolla pnp
|
||||
if(isSummonPet)
|
||||
{
|
||||
_ITEM_TABLE * pItemData = nullptr;
|
||||
if((pItemData = GetItemPrototype(SHOULDER)) == nullptr
|
||||
|| !pItemData->isPet())
|
||||
return;
|
||||
|
||||
_ITEM_DATA *pItem = nullptr;
|
||||
|
||||
if ((pItem = GetItem(SHOULDER)) == nullptr
|
||||
|| pItem->nNum != pItemData->Getnum())
|
||||
return;
|
||||
|
||||
CPet * pPet = g_pMain->GetPetPtr(pItem->nSerialNum);
|
||||
if (pPet == nullptr)
|
||||
return;
|
||||
|
||||
if(isSummonPet && SummonPetID > 0)
|
||||
{
|
||||
float x,z;
|
||||
if( m_curx < m_oldx || m_curx == m_oldx)
|
||||
x = real_x - 1;
|
||||
else
|
||||
x = real_x + 1;
|
||||
|
||||
if( m_curz < m_oldz || m_curz == m_oldz)
|
||||
z = real_z - 1;
|
||||
else
|
||||
z = real_z + 1;
|
||||
pPet->Moving(x,m_cury,z,uint8(speed));
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
result.Initialize(AG_USER_MOVE);
|
||||
result << GetSocketID() << m_curx << m_curz << m_cury << speed;
|
||||
Send_AIServer(&result);
|
||||
|
||||
}
|
||||
|
||||
void CUser::AddToRegion(int16 new_region_x, int16 new_region_z)
|
||||
{
|
||||
GetRegion()->Remove(this);
|
||||
SetRegion(new_region_x, new_region_z);
|
||||
GetRegion()->Add(this);
|
||||
}
|
||||
|
||||
void CUser::GetInOut(Packet & result, uint8 bType)
|
||||
{
|
||||
result.Initialize(WIZ_USER_INOUT);
|
||||
result << uint16(bType) << GetID();
|
||||
if (bType != INOUT_OUT)
|
||||
GetUserInfo(result);
|
||||
}
|
||||
|
||||
void CUser::UserInOut(uint8 bType)
|
||||
{
|
||||
if (GetRegion() == NULL)
|
||||
return;
|
||||
if(this == nullptr)
|
||||
return;
|
||||
Packet result;
|
||||
|
||||
if (bType != INOUT_OUT)
|
||||
ResetGMVisibility();
|
||||
|
||||
GetInOut(result, bType);
|
||||
|
||||
if (bType == INOUT_OUT)
|
||||
GetRegion()->Remove(this);
|
||||
else
|
||||
GetRegion()->Add(this);
|
||||
|
||||
// View Bug Fix by Terry
|
||||
|
||||
if (g_pMain->pTempleEvent.ActiveEvent != -1 && isInTempleEventZone())
|
||||
{
|
||||
SendToRegion(&result, this, GetEventRoom());
|
||||
}
|
||||
else
|
||||
SendToRegion(&result);
|
||||
|
||||
if (bType == INOUT_OUT || !isBlinking())
|
||||
{
|
||||
result.Initialize(AG_USER_INOUT);
|
||||
result.SByte();
|
||||
result << bType << GetSocketID() << GetName() << m_curx << m_curz;
|
||||
Send_AIServer(&result);
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::GetUserInfo(Packet & pkt)
|
||||
{
|
||||
if (m_bAbnormalType == ABNORMAL_INVISIBLE)
|
||||
return;
|
||||
|
||||
pkt.SByte();
|
||||
pkt << GetName()
|
||||
<< uint16(GetNation()) << GetClanID() << GetFame();
|
||||
|
||||
CKnights * pKnights = g_pMain->GetClanPtr(GetClanID());
|
||||
if (pKnights == nullptr)
|
||||
{
|
||||
pkt << uint32(0) << uint16(0) << uint8(0) << uint16(-1) << uint32(0) << uint8(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CKnights *aKnights = g_pMain->GetClanPtr(pKnights->GetAllianceID());
|
||||
|
||||
pkt << pKnights->GetAllianceID()
|
||||
<< pKnights->m_strName
|
||||
<< pKnights->m_byGrade << pKnights->m_byRanking
|
||||
<< uint16(pKnights->m_sMarkVersion) // symbol/mark version
|
||||
<< pKnights->GetCapeID(aKnights) // cape ID
|
||||
<< pKnights->m_bCapeR << pKnights->m_bCapeG << pKnights->m_bCapeB << uint8(0) // this is stored in 4 bytes after all.
|
||||
// not sure what this is, but it (just?) enables the clan symbol on the cape
|
||||
// value in dump was 9, but everything tested seems to behave as equally well...
|
||||
// we'll probably have to implement logic to respect requirements.
|
||||
<< uint8(1);
|
||||
}
|
||||
|
||||
// There are two event-driven invisibility states; dispel on attack, and dispel on move.
|
||||
// These are handled primarily server-side; from memory the client only cares about value 1 (which we class as 'dispel on move').
|
||||
// As this is the only place where this flag is actually sent to the client, we'll just convert 'dispel on attack'
|
||||
// back to 'dispel on move' as the client expects.
|
||||
uint8 bInvisibilityType = m_bInvisibilityType;
|
||||
if (bInvisibilityType != INVIS_NONE)
|
||||
bInvisibilityType = INVIS_DISPEL_ON_MOVE;
|
||||
|
||||
pkt << GetLevel() << m_bRace << m_sClass
|
||||
<< GetSPosX() << GetSPosZ() << GetSPosY()
|
||||
<< m_bFace << m_nHair
|
||||
<< m_bResHpType << uint32(m_bAbnormalType)
|
||||
<< m_bNeedParty;
|
||||
if (!isGM())
|
||||
pkt << m_bAuthority;
|
||||
else
|
||||
pkt << uint8(250);
|
||||
pkt << m_bPartyLeader // is party leader (bool)
|
||||
<< bInvisibilityType // visibility state
|
||||
<< uint8(m_teamColour); // team colour (i.e. in soccer, 0=none, 1=blue, 2=red)
|
||||
if(isDevil())
|
||||
pkt << uint16(1);
|
||||
else
|
||||
pkt << m_bIsHidingHelmet << m_bIsDevil; // either this is correct and items are super buggy, or it causes baldness. You choose.
|
||||
pkt << m_sDirection // direction
|
||||
<< m_bIsChicken // chicken/beginner flag
|
||||
<< m_bRank // king flag
|
||||
<< uint16(0)
|
||||
<< m_bKnightsRank << m_bPersonalRank; // NP ranks (total, monthly)
|
||||
|
||||
|
||||
uint8 equippedItems[] =
|
||||
{
|
||||
BREAST, LEG, HEAD, GLOVE, FOOT, SHOULDER, RIGHTHAND, LEFTHAND, CWING, CHELMET, CRIGHT, CLEFT, CTOP, FAIRY
|
||||
};
|
||||
|
||||
|
||||
|
||||
foreach_array (i, equippedItems)
|
||||
{
|
||||
_ITEM_DATA * pItem = GetItem(equippedItems[i]);
|
||||
|
||||
if(pItem == nullptr)
|
||||
continue;
|
||||
|
||||
/*if(!m_bIsHidingCospre)
|
||||
equippedItems[8] = 0;
|
||||
else
|
||||
equippedItems[8] = CWING;*/
|
||||
|
||||
pkt << pItem->nNum << pItem->sDuration << pItem->bFlag;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
pkt << GetZoneID() << uint8(-1) << uint8(-1) << uint16(0) << uint16(0) << uint16(0) << m_bIsHidingCospre << isGenieActive();
|
||||
|
||||
pkt << GetRebLevel() << GetCoverTitle() << uint32(isReturnee());
|
||||
}
|
||||
|
||||
void CUser::Rotate(Packet & pkt)
|
||||
{
|
||||
if (isDead())
|
||||
return;
|
||||
|
||||
Packet result(WIZ_ROTATE);
|
||||
pkt >> m_sDirection;
|
||||
result << GetSocketID() << m_sDirection;
|
||||
|
||||
SendToRegion(&result, this, GetEventRoom());
|
||||
}
|
||||
|
||||
bool CUser::CanChangeZone(C3DMap * pTargetMap, WarpListResponse & errorReason)
|
||||
{
|
||||
// While unofficial, game masters should be allowed to teleport anywhere.
|
||||
if (isGM())
|
||||
return true;
|
||||
|
||||
// Generic error reason; this should only be checked when the method returns false.
|
||||
errorReason = WarpListGenericError;
|
||||
|
||||
if (GetLevel() < pTargetMap->GetMinLevelReq()
|
||||
|| (pTargetMap->GetID() == ZONE_ARDREAM && !g_pMain->OpenArdream)
|
||||
|| GetLevel() > pTargetMap->GetMinLevelReq()
|
||||
&& (pTargetMap->GetID() == ZONE_RONARK_LAND && !g_pMain->OpenCZ)
|
||||
|| GetLevel() > pTargetMap->GetMinLevelReq()
|
||||
&& (pTargetMap->GetID() == ZONE_RONARK_LAND_BASE && !g_pMain->OpenCZ))
|
||||
{
|
||||
errorReason = WarpListMinLevel;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetLevel() > pTargetMap->GetMaxLevelReq()
|
||||
&& (pTargetMap->GetID() == ZONE_ARDREAM && !g_pMain->OpenArdream)
|
||||
|| GetLevel() > pTargetMap->GetMaxLevelReq()
|
||||
&& (pTargetMap->GetID() == ZONE_RONARK_LAND && !g_pMain->OpenCZ)
|
||||
|| GetLevel() > pTargetMap->GetMaxLevelReq()
|
||||
&& (pTargetMap->GetID() == ZONE_RONARK_LAND_BASE && !g_pMain->OpenCZ))
|
||||
{
|
||||
errorReason = WarpListDoNotQualify;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (pTargetMap->GetID())
|
||||
{
|
||||
case ZONE_KARUS:
|
||||
// Users may enter Luferson (1)/El Morad (2) if they are that nation,
|
||||
if (GetNation() == pTargetMap->GetID())
|
||||
return true;
|
||||
|
||||
// Users may also enter if there's a war invasion happening in that zone.
|
||||
if (GetNation() == ELMORAD)
|
||||
return g_pMain->m_byKarusOpenFlag;
|
||||
else
|
||||
return g_pMain->m_byElmoradOpenFlag;
|
||||
case ZONE_ELMORAD:
|
||||
// Users may enter Luferson (1)/El Morad (2) if they are that nation,
|
||||
if (GetNation() == pTargetMap->GetID())
|
||||
return true;
|
||||
|
||||
// Users may also enter if there's a war invasion happening in that zone.
|
||||
if (GetNation() == KARUS)
|
||||
return g_pMain->m_byElmoradOpenFlag;
|
||||
else
|
||||
return g_pMain->m_byKarusOpenFlag;
|
||||
case ZONE_KARUS_ESLANT:
|
||||
return GetNation() == pTargetMap->GetID() - 10;
|
||||
case ZONE_ELMORAD_ESLANT:
|
||||
return GetNation() == pTargetMap->GetID() - 10;
|
||||
case ZONE_DELOS: // TODO: implement CSW logic.
|
||||
if (g_pMain->m_byBattleOpen == CLAN_BATTLE && !g_pMain->m_byBattleSiegeWarTeleport || g_pMain->m_byBattleOpen == CLAN_BATTLE && GetClanID() <= 0 )
|
||||
{
|
||||
errorReason = WarpListNotDuringCSW;
|
||||
return false;
|
||||
}
|
||||
if (GetLoyalty() <= 0)
|
||||
{
|
||||
errorReason = WarpListNeedNP;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case ZONE_JURAD_MOUNTAIN:
|
||||
break;
|
||||
case ZONE_BORDER_DEFENSE_WAR:
|
||||
break;
|
||||
|
||||
case ZONE_BIFROST:
|
||||
case ZONE_DARK_LAND:
|
||||
case ZONE_PVP_EVENT:
|
||||
if (g_pMain->isWarOpen() || g_pMain->OpenArdream)
|
||||
{
|
||||
errorReason = WarpListNotDuringWar;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetLoyalty() <= 0)
|
||||
{
|
||||
errorReason = WarpListNeedNP;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
case ZONE_ARDREAM:
|
||||
if (g_pMain->isWarOpen())
|
||||
{
|
||||
errorReason = WarpListNotDuringWar;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetLoyalty() <= 0)
|
||||
{
|
||||
errorReason = WarpListNeedNP;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
case ZONE_RONARK_LAND_BASE:
|
||||
case ZONE_RONARK_LAND:
|
||||
if ((g_pMain->isWarOpen() && g_pMain->m_byBattleZoneType != ZONE_ARDREAM) || (g_pMain->m_bEventZoneIsActive && g_pMain->m_nEventZoneTime == 5))
|
||||
{
|
||||
errorReason = WarpListNotDuringWar;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetLoyalty() <= 0)
|
||||
{
|
||||
errorReason = WarpListNeedNP;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
// War zones may only be entered if that war zone is active.
|
||||
if (pTargetMap->isWarZone())
|
||||
{
|
||||
if(pTargetMap->GetID() == ZONE_SNOW_BATTLE)
|
||||
{
|
||||
if ((pTargetMap->GetID() - ZONE_SNOW_BATTLE) != g_pMain->m_byBattleZone)
|
||||
return false;
|
||||
}
|
||||
else if ((pTargetMap->GetID() - ZONE_BATTLE_BASE) != g_pMain->m_byBattleZone)
|
||||
return false;
|
||||
else if ((GetNation() == ELMORAD && g_pMain->m_byElmoradOpenFlag)
|
||||
|| (GetNation() == KARUS && g_pMain->m_byKarusOpenFlag))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CUser::CanLevelQualify(uint8 sLevel)
|
||||
{
|
||||
int16 nStatTotal = 300 + (sLevel - 1) * 3;
|
||||
uint8 nSkillTotal = (sLevel - 9) * 2;
|
||||
|
||||
if (sLevel > 60)
|
||||
nStatTotal += 2 * (sLevel - 60);
|
||||
|
||||
if ((m_sPoints + GetStatTotal()) > nStatTotal || GetTotalSkillPoints() > nSkillTotal)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CUser::ZoneChange(uint16 sNewZone, float x, float z, uint16 nEventRoom)
|
||||
{
|
||||
C3DMap * pMap = g_pMain->GetZoneByID(sNewZone);
|
||||
_KNIGHTS_SIEGE_WARFARE *pKnightSiege = g_pMain->GetSiegeMasterKnightsPtr(1);
|
||||
CKnights *pKnightsMaster = g_pMain->GetClanPtr(pKnightSiege->sMasterKnights);
|
||||
|
||||
if (pMap == nullptr)
|
||||
return;
|
||||
|
||||
WarpListResponse errorReason;
|
||||
if (!CanChangeZone(pMap, errorReason))
|
||||
{
|
||||
Packet result(WIZ_WARP_LIST, uint8(2));
|
||||
|
||||
result << uint8(errorReason);
|
||||
|
||||
if (errorReason == WarpListMinLevel)
|
||||
result << pMap->GetMinLevelReq();
|
||||
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(GetZoneID() == ZONE_STONE1)
|
||||
g_pMain->IsBusy1[GetEventRoom()] = false;
|
||||
if(GetZoneID() == ZONE_STONE2)
|
||||
g_pMain->IsBusy2[GetEventRoom()] = false;
|
||||
if(GetZoneID() == ZONE_STONE3)
|
||||
g_pMain->IsBusy3[GetEventRoom()] = false;
|
||||
|
||||
if (x == 0.0f && z == 0.0f)
|
||||
{
|
||||
_START_POSITION * pStartPosition = g_pMain->GetStartPosition(sNewZone);
|
||||
if (pStartPosition != nullptr)
|
||||
{
|
||||
x = (float)(GetNation() == KARUS ? pStartPosition->sKarusX : pStartPosition->sElmoradX + myrand(0, pStartPosition->bRangeX));
|
||||
z = (float)(GetNation() == KARUS ? pStartPosition->sKarusZ : pStartPosition->sElmoradZ + myrand(0, pStartPosition->bRangeZ));
|
||||
}
|
||||
}
|
||||
|
||||
if (sNewZone == ZONE_DELOS)
|
||||
{
|
||||
if (pKnightSiege->sMasterKnights == GetClanID() && GetClanID())
|
||||
{
|
||||
if (GetNation() == KARUS)
|
||||
{
|
||||
x = (float)(455 + myrand(0, 5));
|
||||
z = (float)(790 + myrand(0, 5));
|
||||
}
|
||||
else
|
||||
{
|
||||
x = (float)(555 + myrand(0, 5));
|
||||
z = (float)(790 + myrand(0, 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_bWarp = true;
|
||||
m_bZoneChangeFlag = true;
|
||||
|
||||
// Random respawn position...
|
||||
if (sNewZone == ZONE_CHAOS_DUNGEON)
|
||||
{
|
||||
short sx, sz;
|
||||
GetStartPositionRandom(sx,sz,(uint8)sNewZone);
|
||||
x = (float)sx;
|
||||
z = (float)sz;
|
||||
}
|
||||
|
||||
m_LastX = x;
|
||||
m_LastZ = z;
|
||||
|
||||
|
||||
uint16 OldEventRoom = GetEventRoom();
|
||||
if (GetZoneID() != sNewZone && isInTempleEventZone((uint8)sNewZone))
|
||||
{
|
||||
if (!isEventUser() && !isGM())
|
||||
g_pMain->AddEventUser(this);
|
||||
|
||||
if(!isGM())
|
||||
g_pMain->SetEventUser(this);
|
||||
|
||||
nEventRoom = GetEventRoom();
|
||||
SetUserEventRoom(OldEventRoom);
|
||||
SetUnitEventRoom(OldEventRoom);
|
||||
}
|
||||
|
||||
if(isGM())
|
||||
m_TimeMonsterStone = UNIXTIME + 3000;
|
||||
|
||||
|
||||
|
||||
if (GetZoneID() != sNewZone)
|
||||
{
|
||||
|
||||
UserInOut(INOUT_OUT);
|
||||
|
||||
m_bZoneChangeSameZone = false;
|
||||
SetZoneAbilityChange(sNewZone);
|
||||
|
||||
SetUserEventRoom(nEventRoom);
|
||||
SetUnitEventRoom(nEventRoom);
|
||||
|
||||
|
||||
// Reset the user's anger gauge when leaving the zone
|
||||
// Unknown if this is official behaviour, but it's logical.
|
||||
if (GetAngerGauge() > 0)
|
||||
UpdateAngerGauge(0);
|
||||
|
||||
|
||||
/*
|
||||
Here we also send a clan packet with subopcode 0x16 (with a byte flag of 2) if war zone/Moradon
|
||||
or subopcode 0x17 (with nWarEnemyID) for all else
|
||||
*/
|
||||
|
||||
if (isInParty() && !m_bZoneChangeSameZone)
|
||||
if (isPartyLeader())
|
||||
{
|
||||
_PARTY_GROUP * pParty = g_pMain->GetPartyPtr(GetPartyID());
|
||||
PartyPromote(pParty->uid[1]);
|
||||
}
|
||||
PartyRemove(GetSocketID());
|
||||
|
||||
if (hasRival())
|
||||
RemoveRival();
|
||||
|
||||
ResetWindows();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bWarp = false;
|
||||
Warp(uint16(x * 10), uint16(z * 10));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (sNewZone != ZONE_SNOW_BATTLE && GetZoneID() == ZONE_SNOW_BATTLE)
|
||||
SetMaxHp(1);
|
||||
else if (sNewZone != ZONE_CHAOS_DUNGEON && GetZoneID() == ZONE_CHAOS_DUNGEON)
|
||||
{
|
||||
SetMaxHp(1);
|
||||
RobChaosSkillItems();
|
||||
nEventRoom = 0;
|
||||
}
|
||||
else if((sNewZone != ZONE_BORDER_DEFENSE_WAR && GetZoneID() == ZONE_BORDER_DEFENSE_WAR)
|
||||
|| (sNewZone != ZONE_JURAD_MOUNTAIN && GetZoneID() == ZONE_JURAD_MOUNTAIN))
|
||||
{
|
||||
SetMaxHp(1);
|
||||
nEventRoom = 0;
|
||||
}
|
||||
else if (sNewZone == ZONE_FORGOTTEN_TEMPLE)
|
||||
g_pMain->m_nForgettenTempleUsers.push_back(GetSocketID());
|
||||
else if (sNewZone != ZONE_FORGOTTEN_TEMPLE && GetZoneID() == ZONE_FORGOTTEN_TEMPLE)
|
||||
g_pMain->m_nForgettenTempleUsers.erase(std::remove(g_pMain->m_nForgettenTempleUsers.begin(), g_pMain->m_nForgettenTempleUsers.end(), GetSocketID()), g_pMain->m_nForgettenTempleUsers.end());
|
||||
|
||||
else if (sNewZone == ZONE_DARK_LAND || sNewZone == ZONE_KROWAZ_DOMINION || sNewZone == ZONE_RONARK_LAND_BASE || sNewZone == ZONE_ARDREAM || sNewZone == ZONE_PVP_EVENT || (sNewZone == ZONE_JURAD_MOUNTAIN && GetZoneID() != sNewZone) || sNewZone == ZONE_LOST_TEMPLE)
|
||||
g_pMain->m_nEventZoneUsers.push_back(GetSocketID());
|
||||
else if ((sNewZone != ZONE_DARK_LAND && GetZoneID() == ZONE_DARK_LAND) || (sNewZone != ZONE_LOST_TEMPLE && GetZoneID() == ZONE_LOST_TEMPLE) || (sNewZone != ZONE_KROWAZ_DOMINION && GetZoneID() == ZONE_KROWAZ_DOMINION)
|
||||
|| (sNewZone != ZONE_JURAD_MOUNTAIN && GetZoneID() == ZONE_JURAD_MOUNTAIN) || (sNewZone != ZONE_RONARK_LAND_BASE && GetZoneID() == ZONE_RONARK_LAND_BASE) || (sNewZone != ZONE_ARDREAM && GetZoneID() == ZONE_ARDREAM) || (sNewZone != ZONE_PVP_EVENT && GetZoneID() == ZONE_PVP_EVENT))
|
||||
g_pMain->m_nEventZoneUsers.erase(std::remove(g_pMain->m_nEventZoneUsers.begin(), g_pMain->m_nEventZoneUsers.end(), GetSocketID()), g_pMain->m_nEventZoneUsers.end());
|
||||
|
||||
m_bZone = (uint8) sNewZone; // this is 2 bytes to support the warp data loaded from SMDs. It should not go above a byte, however.
|
||||
|
||||
if(GetZoneID() != sNewZone)
|
||||
{
|
||||
Packet result2(AG_USER_EVENTROOM);
|
||||
result2 << GetID() << uint16(nEventRoom);
|
||||
g_pMain->Send_AIServer(&result2);
|
||||
}
|
||||
|
||||
SetPosition(x, 0.0f, z);
|
||||
m_pMap = pMap;
|
||||
|
||||
|
||||
SetRegion(GetNewRegionX(), GetNewRegionZ());
|
||||
|
||||
Packet result(WIZ_ZONE_CHANGE, uint8(ZoneChangeTeleport));
|
||||
result << uint16(GetZoneID()) << GetSPosX() << GetSPosZ() << GetSPosY() << g_pMain->m_byOldVictory;
|
||||
Send(&result);
|
||||
|
||||
if (!m_bZoneChangeSameZone)
|
||||
{
|
||||
m_sWhoKilledMe = -1;
|
||||
m_iLostExp = 0;
|
||||
m_bRegeneType = 0;
|
||||
m_tLastRegeneTime = 0;
|
||||
m_sBind = -1;
|
||||
InitType3();
|
||||
InitType4();
|
||||
CMagicProcess::CheckExpiredType9Skills(this, true);
|
||||
SetUserAbility();
|
||||
}
|
||||
|
||||
if(isSummonPet)
|
||||
{
|
||||
_ITEM_TABLE * pItemData = nullptr;
|
||||
if(this == nullptr
|
||||
|| (pItemData = GetItemPrototype(SHOULDER)) == nullptr
|
||||
|| !pItemData->isPet())
|
||||
return;
|
||||
_ITEM_DATA *pItem = nullptr;
|
||||
|
||||
if ((pItem = GetItem(SHOULDER)) == nullptr
|
||||
|| pItem->nNum != pItemData->Getnum())
|
||||
return;
|
||||
|
||||
CPet *newPet = g_pMain->GetPetPtr(pItem->nSerialNum);
|
||||
if(newPet == nullptr || newPet->m_pNpc == nullptr)
|
||||
return;
|
||||
|
||||
if(newPet->m_pNpc != nullptr)
|
||||
{
|
||||
if(newPet->m_pNpc->isAlive())
|
||||
newPet->Dead();
|
||||
isSummonPet = false;
|
||||
}
|
||||
}
|
||||
|
||||
result.Initialize(AG_ZONE_CHANGE);
|
||||
result << GetSocketID() << GetZoneID();
|
||||
Send_AIServer(&result);
|
||||
|
||||
g_pMain->TempleEventSendActiveEventTime(this);
|
||||
|
||||
m_bZoneChangeFlag = false;
|
||||
|
||||
if (GetZoneID() == ZONE_BATTLE4)
|
||||
g_pMain->NereidsMonumentEvent(0,0,this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CUser::CheckWaiting(uint8 sNewZone,uint16 Time)
|
||||
{
|
||||
uint16 m_RemainEventZone = Time;
|
||||
|
||||
if (sNewZone != ZONE_STONE1
|
||||
&& sNewZone != ZONE_STONE2
|
||||
&& sNewZone != ZONE_STONE3)
|
||||
{
|
||||
Packet hata(WIZ_EVENT);
|
||||
hata << uint8(1); // Inventory Hatas?.
|
||||
Send(&hata);
|
||||
}
|
||||
|
||||
if (sNewZone == ZONE_CHAOS_DUNGEON)
|
||||
{
|
||||
Packet chaos(WIZ_SELECT_MSG);
|
||||
chaos << uint16(0x00) << uint8(0x07) << uint64(0x00) << 0x09 << uint8(0x18) << uint16(0x1B) << uint8(0x00) << Time;
|
||||
Send(&chaos);
|
||||
|
||||
Packet chaostime(WIZ_BIFROST, uint8(MONSTER_SQUARD));
|
||||
chaostime << uint16(m_RemainEventZone);
|
||||
Send(&chaostime);
|
||||
}
|
||||
|
||||
if (sNewZone == ZONE_BORDER_DEFENSE_WAR)
|
||||
{
|
||||
Packet border(WIZ_SELECT_MSG);
|
||||
border << uint16(0x00) << uint8(0x07) << uint64(0x00) << uint8(0x08) << uint32(0x00) << uint8(0x09) << Time << uint16(0x00);
|
||||
Send(&border);
|
||||
|
||||
Packet bordertime(WIZ_BIFROST, uint8(MONSTER_SQUARD));
|
||||
bordertime << uint16(m_RemainEventZone);
|
||||
Send(&bordertime);
|
||||
}
|
||||
|
||||
if (sNewZone == ZONE_JURAD_MOUNTAIN)
|
||||
{
|
||||
/*Packet juraid(WIZ_SELECT_MSG);
|
||||
juraid << uint16(0x00) << uint8(0x07) << uint64(0x00) << uint8(0x08) << uint32(0x00) << uint8(0x09) << Time << uint16(0x00);
|
||||
Send(&juraid);
|
||||
|
||||
Packet juraidtime(WIZ_BIFROST, uint8(MONSTER_SQUARD));
|
||||
juraidtime << uint16(m_RemainEventZone);
|
||||
Send(&juraidtime);*/
|
||||
|
||||
}
|
||||
|
||||
if (sNewZone == ZONE_STONE1 || sNewZone == ZONE_STONE2 || sNewZone == ZONE_STONE3)
|
||||
{
|
||||
|
||||
Packet stone(WIZ_SELECT_MSG);
|
||||
stone << uint16(0x00) << uint8(0x09) << uint64(0x00) << uint8(0x09) << uint32(0x00) << uint8(0x10) << Time << uint16(0x00);
|
||||
Send(&stone);
|
||||
|
||||
Packet stonetime(WIZ_BIFROST, uint8(MONSTER_SQUARD));
|
||||
stonetime << uint16(m_RemainEventZone);
|
||||
Send(&stonetime);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
void CUser::PlayerRankingProcess(uint16 ZoneID, bool RemoveInZone)
|
||||
{
|
||||
if(m_bZoneChangeSameZone)
|
||||
return;
|
||||
|
||||
if (ZoneID == ZONE_ARDREAM
|
||||
|| ZoneID == ZONE_RONARK_LAND_BASE
|
||||
|| ZoneID == ZONE_PVP_EVENT
|
||||
|| ZoneID == ZONE_RONARK_LAND
|
||||
|| ZoneID == ZONE_BORDER_DEFENSE_WAR
|
||||
|| ZoneID == ZONE_CHAOS_DUNGEON
|
||||
|| ZoneID == ZONE_JURAD_MOUNTAIN)
|
||||
{
|
||||
if (RemoveInZone)
|
||||
RemovePlayerRank();
|
||||
else
|
||||
{
|
||||
RemovePlayerRank();
|
||||
AddPlayerRank(ZoneID);
|
||||
}
|
||||
}
|
||||
else
|
||||
RemovePlayerRank();
|
||||
}
|
||||
|
||||
void CUser::AddPlayerRank(uint16 ZoneID)
|
||||
{
|
||||
m_iLoyaltyDaily = 0;
|
||||
m_iLoyaltyPremiumBonus = 0;
|
||||
m_KillCount = 0;
|
||||
m_DeathCount = 0;
|
||||
|
||||
_USER_RANKING * pData = new _USER_RANKING;
|
||||
|
||||
pData->m_socketID = GetSocketID();
|
||||
pData->m_iLoyaltyDaily = m_iLoyaltyDaily;
|
||||
pData->m_iLoyaltyPremiumBonus = m_iLoyaltyPremiumBonus;
|
||||
pData->m_KillCount = 0;
|
||||
pData->m_DeathCount = 0;
|
||||
pData->pUser = this;
|
||||
|
||||
if (!g_pMain->m_UserRankingArray[GetNation() - 1].PutData(pData->m_socketID, pData))
|
||||
delete pData;
|
||||
}
|
||||
|
||||
void CUser::RemovePlayerRank()
|
||||
{
|
||||
if(GetNation() < 1 || GetNation() > 2)
|
||||
return;
|
||||
|
||||
g_pMain->m_UserRankingArray[GetNation() - 1].DeleteData(GetSocketID());
|
||||
|
||||
}
|
||||
|
||||
void CUser::UpdatePlayerRank()
|
||||
{
|
||||
if (isGM())
|
||||
return;
|
||||
|
||||
_USER_RANKING * pRankInfo = g_pMain->m_UserRankingArray[GetNation() -1].GetData(GetSocketID());
|
||||
if (pRankInfo == nullptr)
|
||||
return;
|
||||
|
||||
pRankInfo->m_iLoyaltyDaily = m_iLoyaltyDaily;
|
||||
pRankInfo->m_iLoyaltyPremiumBonus = m_iLoyaltyPremiumBonus;
|
||||
pRankInfo->m_KillCount = m_KillCount;
|
||||
pRankInfo->m_DeathCount = m_DeathCount;
|
||||
}
|
||||
/**
|
||||
* @brief Changes the zone of all party members within the user's zone.
|
||||
* If the user is not in a party, they should still be teleported.
|
||||
*
|
||||
* @param sNewZone ID of the new zone.
|
||||
* @param x The x coordinate.
|
||||
* @param z The z coordinate.
|
||||
*/
|
||||
void CUser::ZoneChangeParty(uint16 sNewZone, float x, float z)
|
||||
{
|
||||
_PARTY_GROUP * pParty = g_pMain->GetPartyPtr(GetPartyID());
|
||||
if (pParty == nullptr)
|
||||
return ZoneChange(sNewZone, x, z);
|
||||
|
||||
short partyUsers[MAX_PARTY_USERS];
|
||||
|
||||
for (int i = 0; i < MAX_PARTY_USERS; i++)
|
||||
partyUsers[i] = pParty->uid[i];
|
||||
|
||||
for (int i = 0; i < MAX_PARTY_USERS; i++)
|
||||
{
|
||||
CUser * pUser = g_pMain->GetUserPtr(partyUsers[i]);
|
||||
if (pUser != nullptr)
|
||||
pUser->ZoneChange(sNewZone, x, z);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Changes the zone of all clan members in home/neutral zones (including Eslant).
|
||||
* If the user is not in a clan, they should not be teleported.
|
||||
*
|
||||
* @param sNewZone ID of the new zone.
|
||||
* @param x The x coordinate.
|
||||
* @param z The z coordinate.
|
||||
*/
|
||||
void CUser::ZoneChangeClan(uint16 sNewZone, float x, float z)
|
||||
{
|
||||
CKnights * pKnights = g_pMain->GetClanPtr(GetClanID());
|
||||
if (pKnights == nullptr)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < MAX_CLAN_USERS; i++)
|
||||
{
|
||||
_KNIGHTS_USER * p = &pKnights->m_arKnightsUser[i];
|
||||
CUser * pUser = p->pSession;
|
||||
if (p->byUsed && pUser != nullptr && pUser->GetZoneID() < ZONE_DELOS)
|
||||
pUser->ZoneChange(sNewZone, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::Warp(uint16 sPosX, uint16 sPosZ)
|
||||
{
|
||||
ASSERT(GetMap() != nullptr);
|
||||
if (m_bWarp)
|
||||
return;
|
||||
|
||||
float real_x = sPosX / 10.0f, real_z = sPosZ / 10.0f;
|
||||
if (!GetMap()->IsValidPosition(real_x, real_z, 0.0f))
|
||||
{
|
||||
TRACE("Invalid position %f,%f\n", real_x, real_z);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
m_LastX = real_x;
|
||||
m_LastZ = real_z;
|
||||
|
||||
Packet result(WIZ_WARP);
|
||||
result << sPosX << sPosZ;
|
||||
Send(&result);
|
||||
|
||||
|
||||
|
||||
UserInOut(INOUT_OUT);
|
||||
|
||||
m_curx = real_x;
|
||||
m_curz = real_z;
|
||||
|
||||
Packet resul(AG_USER_MOVE);
|
||||
resul << GetSocketID() << m_curx << m_curz << m_cury << int16(0);
|
||||
Send_AIServer(&resul);
|
||||
|
||||
SetRegion(GetNewRegionX(), GetNewRegionZ());
|
||||
|
||||
UserInOut(INOUT_WARP);
|
||||
|
||||
|
||||
g_pMain->UserInOutForMe(this);
|
||||
g_pMain->RegionNpcInfoForMe(this);
|
||||
g_pMain->MerchantUserInOutForMe(this);
|
||||
LastWarpTime = UNIXTIME;
|
||||
|
||||
if(isSummonPet)
|
||||
{
|
||||
_ITEM_DATA *pItem = nullptr;
|
||||
|
||||
if ((pItem = GetItem(SHOULDER)) == nullptr)
|
||||
return;
|
||||
|
||||
CPet *newPet = g_pMain->GetPetPtr(pItem->nSerialNum);
|
||||
if(newPet == nullptr || newPet->m_pNpc == nullptr)
|
||||
return;
|
||||
|
||||
if(newPet->m_pNpc != nullptr)
|
||||
{
|
||||
newPet->m_pNpc->SendInOut(INOUT_OUT,newPet->m_pNpc->GetX(),newPet->m_pNpc->GetZ(),newPet->m_pNpc->GetY());
|
||||
SetPosition(m_curx,m_cury,m_curz);
|
||||
newPet->m_pNpc->SendInOut(INOUT_IN,m_curx,m_cury,m_curz);
|
||||
}
|
||||
}
|
||||
|
||||
ResetWindows();
|
||||
}
|
||||
|
||||
|
||||
void CUser::RecvWarp(Packet & pkt)
|
||||
{
|
||||
uint16 warp_x, warp_z;
|
||||
pkt >> warp_x >> warp_z;
|
||||
Warp(warp_x, warp_z);
|
||||
}
|
||||
|
||||
void CUser::RecvZoneChange(Packet & pkt)
|
||||
{
|
||||
if (isDead()) // we also need to make sure we're actually waiting on this request...
|
||||
return;
|
||||
|
||||
uint8 opcode = pkt.read<uint8>();
|
||||
if (opcode == ZoneChangeLoading)
|
||||
{
|
||||
g_pMain->RegionUserInOutForMe(this);
|
||||
g_pMain->NpcInOutForMe(this);
|
||||
g_pMain->MerchantUserInOutForMe(this);
|
||||
|
||||
Packet result(WIZ_ZONE_CHANGE, uint8(ZoneChangeLoaded)); // finalise the zone change
|
||||
Send(&result);
|
||||
|
||||
}
|
||||
else if (opcode == ZoneChangeLoaded)
|
||||
{
|
||||
UserInOut(INOUT_RESPAWN);
|
||||
|
||||
// TODO: Fix all this up (it's too messy/confusing)
|
||||
if (!m_bZoneChangeSameZone)
|
||||
BlinkStart();
|
||||
|
||||
if (GetZoneID() != ZONE_CHAOS_DUNGEON)
|
||||
{
|
||||
InitType4();
|
||||
RecastSavedMagic();
|
||||
}
|
||||
|
||||
m_bZoneChangeFlag = false;
|
||||
m_bWarp = false;
|
||||
|
||||
_KNIGHTS_SIEGE_WARFARE *pKnightSiege = g_pMain->GetSiegeMasterKnightsPtr(1);
|
||||
CKnights *pKnightsMaster = g_pMain->GetClanPtr(pKnightSiege->sMasterKnights);
|
||||
|
||||
if (GetZoneID() == ZONE_DELOS)
|
||||
{
|
||||
Packet result16(WIZ_SIEGE, uint8(2));
|
||||
result16.SByte();
|
||||
result16 << uint8((pKnightsMaster != nullptr && g_pMain->m_byBattleSiegeWarOpen ? 1 : 0) + 1)<< (pKnightsMaster != nullptr ? pKnightsMaster->GetID() : uint16(0)) << (pKnightsMaster != nullptr ? pKnightsMaster->m_sMarkVersion : uint16(0)) << uint16(0)
|
||||
<< uint32(g_pMain->m_byBattleSiegeWarOpen ? g_pMain->m_byBattleSiegeWarOccupy : 0) << uint16(g_pMain->m_byBattleSiegeWarOpen ? ((50 * MINUTE) - g_pMain->m_sBattleTimeDelay) : 0)
|
||||
<< (pKnightsMaster != nullptr ? pKnightsMaster->GetName() : std::string(""));
|
||||
g_pMain->Send_Zone(&result16,ZONE_DELOS);
|
||||
}
|
||||
|
||||
}
|
||||
else if (opcode == MilitaryCampChange)
|
||||
{
|
||||
|
||||
uint8 MilitaryCampID = pkt.read<uint8>();
|
||||
|
||||
if (GetZoneID() != ZONE_MORADON
|
||||
&& GetZoneID() != ZONE_MORADONM2)
|
||||
return;
|
||||
if (MilitaryCampID != ZONE_MORADON
|
||||
&& MilitaryCampID != ZONE_MORADONM2)
|
||||
return;
|
||||
|
||||
if (MilitaryCampID == GetZoneID())
|
||||
return;
|
||||
|
||||
ZoneChange(MilitaryCampID, 0.0f, 0.0f);
|
||||
// Karus
|
||||
// 1 1
|
||||
// 2 5
|
||||
// 3 6
|
||||
// Elmorad
|
||||
// 1 2
|
||||
// 2 7
|
||||
// 3 8
|
||||
// Maradon
|
||||
// 1 21
|
||||
// 2 22
|
||||
// 3 23
|
||||
// 4 24
|
||||
// 5 25
|
||||
// Elmorad Eslant
|
||||
// 1 12
|
||||
// 2 15
|
||||
// 3 16
|
||||
// Karus Eslant
|
||||
// 1 11
|
||||
// 2 13
|
||||
// 3 14
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,569 @@
|
||||
#include "stdafx.h"
|
||||
#include "Map.h"
|
||||
#include "DBAgent.h"
|
||||
#include "../shared/DateTime.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
void CUser::Login(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_GLOGIN, uint8(1));
|
||||
result << int32(0);
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
|
||||
void CUser::SelNationToAgent(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_SEL_NATION);
|
||||
uint8 nation = pkt.read<uint8>();
|
||||
if (nation != KARUS && nation != ELMORAD)
|
||||
{
|
||||
result << uint8(0);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
result << nation;
|
||||
g_pMain->AddDatabaseRequest(result, this);
|
||||
}
|
||||
|
||||
void CUser::AllCharInfo(Packet &pkt)
|
||||
{
|
||||
uint8 opcode = pkt.read<uint8>();
|
||||
//TRACE("Opecode = %d", opcode);
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 1:
|
||||
AllCharInfoToAgent();
|
||||
break;
|
||||
case 3:
|
||||
CharacterLocationSend();
|
||||
break;
|
||||
case 4:
|
||||
CharacterLocationRecv(pkt);
|
||||
break;
|
||||
default:
|
||||
TRACE("Unhandle AllCharInfo Opecode %d", opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::AllCharInfoToAgent()
|
||||
{
|
||||
Packet result(WIZ_ALLCHAR_INFO_REQ);
|
||||
g_pMain->AddDatabaseRequest(result, this);
|
||||
}
|
||||
|
||||
void CUser::CharacterLocationSend()
|
||||
{
|
||||
Packet result(WIZ_ALLCHAR_INFO_REQ, uint8(3));
|
||||
|
||||
string strCharID1, strCharID2, strCharID3, strCharID4;
|
||||
|
||||
g_DBAgent.GetAllCharID(m_strAccountID, strCharID1, strCharID2, strCharID3, strCharID4);
|
||||
|
||||
if(strCharID1.length() != 0)
|
||||
result << strCharID1;
|
||||
else
|
||||
result << "";
|
||||
if(strCharID2.length() != 0)
|
||||
result << strCharID2;
|
||||
else
|
||||
result << "";
|
||||
if(strCharID3.length() != 0)
|
||||
result << strCharID3;
|
||||
else
|
||||
result << "";
|
||||
if(strCharID4.length() != 0)
|
||||
result << strCharID4;
|
||||
else
|
||||
result << "";
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::CharacterLocationRecv(Packet & pkt)
|
||||
{
|
||||
uint8 Charpos1, Charpos2, Charpos3, Charpos4;
|
||||
string strCharID1, strCharID2, strCharID3, strCharID4;
|
||||
string ID1, ID2, ID3, ID4;
|
||||
|
||||
Packet result(WIZ_ALLCHAR_INFO_REQ, uint8(4));
|
||||
|
||||
RobItem(ARRANGE_LINE);
|
||||
|
||||
pkt >> Charpos1 >> Charpos2 >> Charpos3 >> Charpos4;
|
||||
|
||||
g_DBAgent.GetAllCharID(m_strAccountID, strCharID1, strCharID2, strCharID3, strCharID4);
|
||||
|
||||
if(strCharID1.length() != 0)
|
||||
{
|
||||
switch(Charpos1)
|
||||
{
|
||||
case 1:
|
||||
ID1 = strCharID1;
|
||||
break;
|
||||
case 2:
|
||||
ID2 = strCharID1;
|
||||
break;
|
||||
case 3:
|
||||
ID3 = strCharID1;
|
||||
break;
|
||||
case 4:
|
||||
ID4 = strCharID1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Charpos1)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
ID1 = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(strCharID2.length() != 0)
|
||||
{
|
||||
switch(Charpos2)
|
||||
{
|
||||
case 1:
|
||||
ID1 = strCharID2;
|
||||
break;
|
||||
case 2:
|
||||
ID2 = strCharID2;
|
||||
break;
|
||||
case 3:
|
||||
ID3 = strCharID2;
|
||||
break;
|
||||
case 4:
|
||||
ID4 = strCharID2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Charpos2)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
ID2 = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(strCharID3.length() != 0)
|
||||
{
|
||||
switch(Charpos3)
|
||||
{
|
||||
case 1:
|
||||
ID1 = strCharID3;
|
||||
break;
|
||||
case 2:
|
||||
ID2 = strCharID3;
|
||||
break;
|
||||
case 3:
|
||||
ID3 = strCharID3;
|
||||
break;
|
||||
case 4:
|
||||
ID4 = strCharID3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Charpos3)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
ID3 = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(strCharID4.length() != 0)
|
||||
{
|
||||
switch(Charpos4)
|
||||
{
|
||||
case 1:
|
||||
ID1 = strCharID4;
|
||||
break;
|
||||
case 2:
|
||||
ID2 = strCharID4;
|
||||
break;
|
||||
case 3:
|
||||
ID3 = strCharID4;
|
||||
break;
|
||||
case 4:
|
||||
ID4 = strCharID4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Charpos4)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
ID4 = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_DBAgent.SetAllCharID(m_strAccountID, ID1, ID2, ID3, ID4);
|
||||
|
||||
result << uint8(1); // 0 = Failed || 1 = Success
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
|
||||
void CUser::ChangeHair(Packet & pkt)
|
||||
{
|
||||
|
||||
if (isDead()
|
||||
|| isTrading()
|
||||
|| isMerchanting()
|
||||
|| isStoreOpen()
|
||||
|| isSellingMerchant()
|
||||
|| isBuyingMerchant()
|
||||
|| isMining()
|
||||
|| m_bMerchantStatex)
|
||||
return;
|
||||
|
||||
std::string strUserID;
|
||||
uint32 nHair;
|
||||
uint8 bOpcode, bFace;
|
||||
|
||||
// The opcode:
|
||||
// 0 seems to be an in-game implementation for converting from old -> new hair data
|
||||
// 2 seems to be used with the hair change item(?).
|
||||
// Another note: there's 4 bytes at the end of the packet data that I can't account for (maybe a[nother] checksum?)
|
||||
|
||||
pkt.SByte();
|
||||
pkt >> bOpcode >> strUserID >> bFace >> nHair;
|
||||
|
||||
if (m_bSelectedCharacter){
|
||||
|
||||
if(CheckExistItem(810340000,1)){
|
||||
|
||||
m_bFace = bFace;
|
||||
m_nHair = nHair;
|
||||
RobItem(810340000,1);
|
||||
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Packet result(WIZ_CHANGE_HAIR);
|
||||
result.SByte();
|
||||
|
||||
result << bOpcode << strUserID << bFace << nHair;
|
||||
g_pMain->AddDatabaseRequest(result, this);
|
||||
}
|
||||
|
||||
void CUser::NewCharToAgent(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_NEW_CHAR);
|
||||
uint32 nHair;
|
||||
uint16 sClass;
|
||||
uint8 bCharIndex, bRace, bFace, str, sta, dex, intel, cha, errorCode = 0;
|
||||
std::string strUserID;
|
||||
|
||||
pkt >> bCharIndex >> strUserID >> bRace >> sClass >> bFace >> nHair
|
||||
>> str >> sta >> dex >> intel >> cha;
|
||||
|
||||
_CLASS_COEFFICIENT* p_TableCoefficient = g_pMain->m_CoefficientArray.GetData(sClass);
|
||||
|
||||
if (bCharIndex > 3)
|
||||
errorCode = NEWCHAR_NO_MORE;
|
||||
else if (p_TableCoefficient == nullptr
|
||||
|| (str + sta + dex + intel + cha) > 300)
|
||||
errorCode = NEWCHAR_INVALID_DETAILS;
|
||||
else if (str < 50 || sta < 50 || dex < 50 || intel < 50 || cha < 50)
|
||||
errorCode = NEWCHAR_STAT_TOO_LOW;
|
||||
else if(!g_pMain->WordGuardSystem(strUserID,strUserID.length()))
|
||||
errorCode = NEWCHAR_BAD_NAME;
|
||||
|
||||
if (errorCode != 0)
|
||||
{
|
||||
result << errorCode;
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
result << bCharIndex
|
||||
<< strUserID << bRace << sClass << bFace << nHair
|
||||
<< str << sta << dex << intel << cha;
|
||||
g_pMain->AddDatabaseRequest(result, this);
|
||||
}
|
||||
|
||||
void CUser::SelCharToAgent(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_SEL_CHAR);
|
||||
std::string strUserID, strAccountID;
|
||||
uint8 bInit;
|
||||
|
||||
|
||||
pkt >> strAccountID >> strUserID >> bInit;
|
||||
if (strAccountID.empty() || strAccountID.size() > MAX_ID_SIZE
|
||||
|| strUserID.empty() || strUserID.size() > MAX_ID_SIZE
|
||||
|| strAccountID != m_strAccountID)
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Disconnect any currently logged in sessions.
|
||||
CUser *pUser = g_pMain->GetUserPtr(strUserID, TYPE_CHARACTER);
|
||||
|
||||
if (pUser && (pUser->GetSocketID() != GetSocketID()))
|
||||
{
|
||||
pUser->Disconnect();
|
||||
|
||||
// And reject the login attempt (otherwise we'll probably desync char data)
|
||||
/*result << uint8(0);
|
||||
Send(&result);
|
||||
return;*/
|
||||
}
|
||||
|
||||
result << strUserID << bInit;
|
||||
|
||||
g_pMain->AddDatabaseRequest(result, this);
|
||||
}
|
||||
|
||||
void CUser::SelectCharacter(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_SEL_CHAR);
|
||||
uint8 bResult, bInit;
|
||||
|
||||
if (isBanned())
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
pkt >> bResult >> bInit;
|
||||
result << bResult;
|
||||
|
||||
if (bResult == 0 || !GetZoneID())
|
||||
goto fail_return;
|
||||
|
||||
m_pMap = g_pMain->GetZoneByID(GetZoneID());
|
||||
if (GetMap() == nullptr)
|
||||
goto fail_return;
|
||||
|
||||
if (g_pMain->m_nServerNo != GetMap()->m_nServerNo)
|
||||
{
|
||||
_ZONE_SERVERINFO *pInfo = g_pMain->m_ServerArray.GetData(GetMap()->m_nServerNo);
|
||||
if (pInfo == nullptr)
|
||||
goto fail_return;
|
||||
|
||||
SendServerChange(pInfo->strServerIP, bInit);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_pMain->isWarOpen() && GetFame() == COMMAND_CAPTAIN)
|
||||
m_bFame = CHIEF;
|
||||
|
||||
// Disallow players from relogging in the opposite nation's home zone when an invasion's not running.
|
||||
if (((GetZoneID() != GetNation() && GetZoneID() <= ZONE_ELMORAD && !g_pMain->m_byBattleOpen)
|
||||
// also disallow players from logging back into war zones that aren't currently active...
|
||||
|| (GetMap()->isWarZone() && !g_pMain->m_byBattleOpen)
|
||||
// Chaos, bdw and juraid montuain
|
||||
|| isInTempleEventZone()
|
||||
|| GetZoneID() == ZONE_STONE1
|
||||
|| GetZoneID() == ZONE_STONE2
|
||||
|| GetZoneID() == ZONE_STONE3
|
||||
// forgetten temple
|
||||
|| GetZoneID() == ZONE_FORGOTTEN_TEMPLE
|
||||
// Event Zones
|
||||
|| (g_pMain->m_nEventZoneTime != 1 && GetZoneID() == ZONE_DARK_LAND)
|
||||
|| (g_pMain->m_nEventZoneTime != 5 && GetZoneID() == ZONE_ARDREAM)
|
||||
|| (g_pMain->m_nEventZoneTime != 2 && GetZoneID() == ZONE_PVP_EVENT)
|
||||
|| (g_pMain->m_nEventZoneTime != 3 && GetZoneID() == ZONE_RONARK_LAND_BASE)
|
||||
|| (g_pMain->m_nEventZoneTime != 4 && GetZoneID() == ZONE_LOST_TEMPLE)
|
||||
// Ardream, Ronark Land Base, Ronark Land, Bifrost, Krowaz Dominion.
|
||||
|| ((g_pMain->m_byBattleOpen || (g_pMain->m_bEventZoneIsActive && g_pMain->m_nEventZoneTime == 5)) && (GetZoneID() == ZONE_RONARK_LAND
|
||||
|| GetZoneID() == ZONE_BIFROST))) && !isGM())
|
||||
{
|
||||
NativeZoneReturn();
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
SetLogInInfoToDB(bInit);
|
||||
|
||||
result << GetZoneID() << GetSPosX() << GetSPosZ() << GetSPosY() << g_pMain->m_byOldVictory;
|
||||
m_bSelectedCharacter = true;
|
||||
Send(&result);
|
||||
|
||||
SetUserAbility(false);
|
||||
|
||||
if (GetLevel() > g_pMain->MAXLVLINI)
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetRebLevel() > 5)
|
||||
{
|
||||
printf("Player rebirth State bad, update to 4, Player name %s", GetName().c_str());
|
||||
m_reblvl = 4;
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
m_iMaxExp = (GetRebLevel() > 0 ? (g_pMain->GetExpByLevel(GetLevel()) * (GetRebLevel() + 1)) : g_pMain->GetExpByLevel(GetLevel()));
|
||||
|
||||
SetRegion(GetNewRegionX(), GetNewRegionZ());
|
||||
|
||||
if(OfflineMerchant)
|
||||
OfflineMerchant = false;
|
||||
|
||||
if (GetClanID() == -1)
|
||||
{
|
||||
SetClanID(0);
|
||||
m_bFame = 0;
|
||||
return;
|
||||
}
|
||||
else if (GetClanID() != 0
|
||||
&& GetZoneID() > 2)
|
||||
{
|
||||
result.Initialize(WIZ_KNIGHTS_PROCESS);
|
||||
result << uint8(KNIGHTS_LIST_REQ) << GetClanID();
|
||||
g_pMain->AddDatabaseRequest(result, this);
|
||||
}
|
||||
return;
|
||||
|
||||
fail_return:
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::SendServerChange(std::string & ip, uint8 bInit)
|
||||
{
|
||||
Packet result(WIZ_SERVER_CHANGE);
|
||||
result << ip << uint16(g_pMain->m_GameServerPort) << bInit << GetZoneID() << g_pMain->m_byOldVictory;
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
// happens on character selection
|
||||
void CUser::SetLogInInfoToDB(uint8 bInit)
|
||||
{
|
||||
_ZONE_SERVERINFO *pInfo = g_pMain->m_ServerArray.GetData(g_pMain->m_nServerNo);
|
||||
if (pInfo == nullptr)
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
Packet result(WIZ_LOGIN_INFO);
|
||||
result << GetName()
|
||||
<< pInfo->strServerIP << uint16(g_pMain->m_GameServerPort) << GetRemoteIP()
|
||||
<< bInit;
|
||||
g_pMain->AddDatabaseRequest(result, this);
|
||||
}
|
||||
|
||||
void CUser::RecvLoginInfo(Packet & pkt)
|
||||
{
|
||||
int8 bResult = pkt.read<uint8>();
|
||||
if (bResult < 0)
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
// This packet actually contains the char name after the opcode
|
||||
void CUser::GameStart(Packet & pkt)
|
||||
{
|
||||
if (isInGame())
|
||||
return;
|
||||
|
||||
uint8 opcode = pkt.read<uint8>();
|
||||
|
||||
if (opcode == 1)
|
||||
{
|
||||
if ((m_LastOnline+3*DAY) < UNIXTIME)
|
||||
m_bisReturnee = true;
|
||||
else
|
||||
m_bisReturnee = false;
|
||||
|
||||
SendMyInfo();
|
||||
g_pMain->UserInOutForMe(this);
|
||||
g_pMain->MerchantUserInOutForMe(this);
|
||||
g_pMain->NpcInOutForMe(this);
|
||||
HandleUserInfo(pkt);
|
||||
SendNotice();
|
||||
TopSendNotice();
|
||||
SendTime();
|
||||
SendWeather();
|
||||
Packet result(WIZ_GAMESTART);
|
||||
Send(&result);
|
||||
}
|
||||
else if (opcode == 2)
|
||||
{
|
||||
m_state = GAME_STATE_INGAME;
|
||||
UserInOut(INOUT_RESPAWN);
|
||||
|
||||
if (!m_bCity && m_sHp <= 0)
|
||||
m_bCity = -1;
|
||||
|
||||
if (m_bCity > 0)
|
||||
{
|
||||
int level = GetLevel();
|
||||
if (m_bCity <= 100)
|
||||
level--;
|
||||
|
||||
// make sure we don't exceed bounds
|
||||
if (level > g_pMain->MAXLVLINI)
|
||||
level = g_pMain->MAXLVLINI;
|
||||
else if (level < 1)
|
||||
level = 1;
|
||||
|
||||
m_iLostExp = (g_pMain->GetExpByLevel(level) * (m_bCity % 10) / 100);
|
||||
if (((m_bCity % 10) / 100) == 1)
|
||||
m_iLostExp /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iLostExp = 0;
|
||||
}
|
||||
|
||||
BlinkStart();
|
||||
SetUserAbility();
|
||||
|
||||
// If we've relogged while dead, we need to make sure the client
|
||||
// is still given the option to revive.
|
||||
if (isDead())
|
||||
SendDeathAnimation();
|
||||
|
||||
g_pMain->TempleEventGetActiveEventTime(this);
|
||||
|
||||
m_tGameStartTimeSavedMagic = UNIXTIME;
|
||||
|
||||
m_LastX = GetX();
|
||||
m_LastZ = GetZ();
|
||||
}
|
||||
_KNIGHTS_SIEGE_WARFARE *pKnightSiege = g_pMain->GetSiegeMasterKnightsPtr(1);
|
||||
CKnights *pKnights = g_pMain->GetClanPtr(pKnightSiege->sMasterKnights);
|
||||
|
||||
if (GetZoneID() == ZONE_DELOS )
|
||||
{
|
||||
Packet result16(WIZ_SIEGE, uint8(2));
|
||||
result16.SByte();
|
||||
result16 << uint8((pKnights != nullptr && g_pMain->m_byBattleSiegeWarOpen ? 1 : 0) + 1)<< (pKnights != nullptr ? pKnights->GetID() : uint16(0)) << (pKnights != nullptr ? pKnights->m_sMarkVersion : uint16(0)) << uint16(0)
|
||||
<< uint32(g_pMain->m_byBattleSiegeWarOpen ? g_pMain->m_byBattleSiegeWarOccupy : 0) << uint16(g_pMain->m_byBattleSiegeWarOpen ? ((50 * MINUTE) - g_pMain->m_sBattleTimeDelay) : 0)
|
||||
<< (pKnights != nullptr ? pKnights->GetName() : std::string(""));
|
||||
g_pMain->Send_Zone(&result16,ZONE_DELOS);
|
||||
}
|
||||
|
||||
m_tHPLastTimeNormal = UNIXTIME;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
class ChatPacket
|
||||
{
|
||||
public:
|
||||
// Construct a chat packet from the data provided
|
||||
// NOTE: Using pointers here for more flexible input (references would be nice, but implementation can be fiddly)
|
||||
static void Construct(Packet * result, uint8 bType, std::string * strMessage = nullptr, std::string * strSender = nullptr,
|
||||
uint8 bNation = 1, int16 senderID = -1)
|
||||
{
|
||||
result->Initialize(WIZ_CHAT);
|
||||
*result << bType << bNation << senderID;
|
||||
|
||||
result->SByte();
|
||||
if (strSender == nullptr) *result << uint8(0);
|
||||
else *result << *strSender;
|
||||
|
||||
result->DByte();
|
||||
if (strMessage == nullptr) *result << uint16(0);
|
||||
else *result << *strMessage;
|
||||
}
|
||||
|
||||
static void Construct(Packet * result, uint8 bType, const char * szMessage, const char * szSender = "",
|
||||
uint8 bNation = 1, int16 senderID = -1)
|
||||
{
|
||||
std::string strSender = szSender, strMessage = szMessage;
|
||||
Construct(result, bType, &strMessage, &strSender, bNation, senderID);
|
||||
}
|
||||
};
|
||||
|
||||
#define COMMAND_HANDLER(name) bool name (CommandArgs & vargs, const char *args, const char *description)
|
||||
|
||||
typedef std::list<std::string> CommandArgs;
|
||||
|
||||
template <class T>
|
||||
class Command
|
||||
{
|
||||
public:
|
||||
const char * Name;
|
||||
COMMAND_HANDLER((T::*Handler));
|
||||
const char * Help;
|
||||
};
|
||||
|
||||
INLINE void* allocate_and_copy(uint32 len, void * pointer)
|
||||
{
|
||||
void * data = (void*)malloc(len);
|
||||
if (data == nullptr)
|
||||
return data;
|
||||
|
||||
memcpy(data, pointer, len);
|
||||
return data;
|
||||
}
|
||||
|
||||
#define init_command_table(t, command_table, command_map) \
|
||||
for (int i = 0; i < sizeof(command_table) / sizeof(*command_table); i++) \
|
||||
command_map.insert(std::make_pair(command_table[i].Name, (Command<t> *)(allocate_and_copy(sizeof(*command_table), (void *)&command_table[i]))));
|
||||
|
||||
#define free_command_table(command_map) \
|
||||
for (auto itr = command_map.begin(); itr != command_map.end(); ++itr) \
|
||||
delete itr->second; \
|
||||
command_map.clear();
|
||||
|
||||
static std::list<std::string> StrSplit(const std::string &src, const std::string &sep)
|
||||
{
|
||||
std::list<std::string> r;
|
||||
std::string s;
|
||||
for (std::string::const_iterator i = src.begin(); i != src.end(); ++i)
|
||||
{
|
||||
if (sep.find(*i) != std::string::npos)
|
||||
{
|
||||
if (!s.empty())
|
||||
r.push_back(s);
|
||||
s = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
s += *i;
|
||||
}
|
||||
}
|
||||
if (!s.empty())
|
||||
r.push_back(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
#include <map>
|
||||
class CGameServerDlg;
|
||||
typedef std::map<std::string, Command<CUser> *> ChatCommandTable;
|
||||
typedef std::map<std::string, Command<CGameServerDlg> *> ServerCommandTable;
|
||||
|
||||
#define CHAT_COMMAND_PREFIX '+'
|
||||
#define SERVER_COMMAND_PREFIX '/'
|
||||
@@ -0,0 +1,321 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
enum Chatroomopcodes
|
||||
{
|
||||
CHATROOM_LIST = 0x04,
|
||||
CHATROOM_CREATE = 0x05,
|
||||
CHATROOM_JOIN = 0x06,
|
||||
CHATROOM_LEAVE = 0x07,
|
||||
CHATROOM_SEARCH = 0x08,
|
||||
CHATROOM_UPDATECONFIG = 0x09,
|
||||
CHATROOM_MEMBEROPTION = 0x0B,
|
||||
CHATROOM_ADMIN = 0x0C,
|
||||
|
||||
CHATROOM_MANUEL = 0x0B
|
||||
};
|
||||
|
||||
void CUser::ChatRoomHandle(Packet & pkt )
|
||||
{
|
||||
uint8 chatroomManuel = pkt.read<uint8>();
|
||||
|
||||
if(chatroomManuel != CHATROOM_MANUEL)
|
||||
return;
|
||||
|
||||
uint8 opcode = pkt.read<uint8>();
|
||||
|
||||
switch(opcode)
|
||||
{
|
||||
case CHATROOM_LIST:
|
||||
ChatRoomList(pkt);
|
||||
break;
|
||||
case CHATROOM_CREATE:
|
||||
ChatRoomCreate(pkt);
|
||||
break;
|
||||
case CHATROOM_JOIN:
|
||||
ChatRoomJoin(pkt);
|
||||
break;
|
||||
case CHATROOM_LEAVE:
|
||||
ChatroomLeave(pkt);
|
||||
break;
|
||||
case CHATROOM_ADMIN:
|
||||
ChatroomAdmin(pkt);
|
||||
break;
|
||||
case CHATROOM_MEMBEROPTION:
|
||||
ChatroomMemberoption(pkt);
|
||||
break;
|
||||
default:
|
||||
printf("Chatroom Handle Unknow : %d\n",opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CUser::ChatRoomList(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_NATION_CHAT,uint8(0x0B));
|
||||
|
||||
uint16 count = 0;
|
||||
result << uint8(CHATROOM_LIST) << uint16(count);
|
||||
result.DByte();
|
||||
//190B04 0100 0200 0500 726573756C 00 01 00 0100 0A00
|
||||
foreach_stlmap(itr, g_pMain->m_ChatRoomArray)
|
||||
{
|
||||
_CHAT_ROOM* pChatRoom = itr->second;
|
||||
|
||||
if(pChatRoom == nullptr)
|
||||
continue;
|
||||
|
||||
result << uint16(++count)
|
||||
<< pChatRoom->strRoomName
|
||||
<< uint8(pChatRoom->isPassword())
|
||||
<< pChatRoom->m_bRoomNation
|
||||
<< uint8(0)
|
||||
<< pChatRoom->m_sCurrentUser
|
||||
<< pChatRoom->m_sMaxUser;
|
||||
}
|
||||
|
||||
result.put(2,count);
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::ChatRoomCreate(Packet & pkt )
|
||||
{
|
||||
if(m_ChatRoomIndex < 1 )
|
||||
return;
|
||||
|
||||
Packet result(WIZ_NATION_CHAT,uint8(0x0B));
|
||||
|
||||
uint8 isPassword,unk,m_bResult;
|
||||
uint16 RoomSize;
|
||||
std::string strRoomName , strPassword;
|
||||
|
||||
strPassword.empty();
|
||||
|
||||
pkt.DByte();
|
||||
pkt >> strRoomName >> isPassword ;
|
||||
|
||||
m_bResult = 0;
|
||||
|
||||
if(isPassword != 0)
|
||||
pkt >> strPassword;
|
||||
else
|
||||
pkt >> unk;
|
||||
|
||||
pkt >> RoomSize;
|
||||
|
||||
_CHAT_ROOM* m_pRoom = new _CHAT_ROOM();
|
||||
|
||||
m_pRoom->strRoomName = strRoomName;
|
||||
m_pRoom->m_bRoomNation = GetNation();
|
||||
m_pRoom->strAdministrator = m_strUserID;
|
||||
m_pRoom->m_sMaxUser = 10;
|
||||
m_pRoom->strPassword = strPassword;
|
||||
m_pRoom->nIndex = g_pMain->m_ChatRoomArray.GetSize() +1;
|
||||
m_pRoom->m_sCurrentUser = 0;
|
||||
|
||||
if(!m_pRoom->AddUser(m_strUserID))
|
||||
{
|
||||
printf("Room creation fail 1\n");
|
||||
delete m_pRoom;
|
||||
goto return_fail;
|
||||
}
|
||||
|
||||
bool check = false;
|
||||
foreach_stlmap_nolock(itr,g_pMain->m_ChatRoomArray)
|
||||
{
|
||||
if(itr->second != nullptr && itr->second->strRoomName == strRoomName)
|
||||
{
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!g_pMain->m_ChatRoomArray.PutData(m_pRoom->nIndex,m_pRoom) || check)
|
||||
{
|
||||
printf("Room creation fail 2\n");
|
||||
delete m_pRoom;
|
||||
goto return_fail;
|
||||
}
|
||||
|
||||
m_ChatRoomIndex = m_pRoom->nIndex;
|
||||
|
||||
//190B 05 01 0200 0500 72 65 73 75 6C 00 0100 0A00 00000000
|
||||
|
||||
result << uint8(0x05) << uint8(1) << uint16(m_pRoom->nIndex) << m_pRoom->strRoomName << uint8(isMeChatroom(m_pRoom->nIndex)) << m_pRoom->m_sCurrentUser << m_pRoom->m_sMaxUser << uint32(0);
|
||||
|
||||
Send(&result);
|
||||
return;
|
||||
|
||||
return_fail:
|
||||
result << uint8(0x05) << uint8(0);
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::ChatRoomJoin(Packet & pkt)
|
||||
{
|
||||
/*Result opcedes
|
||||
* 0 = Successfully
|
||||
* 1 = Already in room
|
||||
* 2 = Room does not exit !
|
||||
* 3 = Password lenght is correct
|
||||
* 4 = Password does not match
|
||||
* 5 = Nation do not match */
|
||||
|
||||
uint16 roomID ;
|
||||
uint8 isPassword ;
|
||||
std::string strPassword ;
|
||||
|
||||
pkt >> roomID >> isPassword >> strPassword;
|
||||
|
||||
_CHAT_ROOM* pRoom = g_pMain->m_ChatRoomArray.GetData(roomID);
|
||||
|
||||
uint8 nResult = 0;
|
||||
|
||||
if(g_pMain->m_ChatRoomArray.GetData(roomID) != nullptr)
|
||||
pRoom->m_UserList.erase(roomID);
|
||||
|
||||
if(pRoom == nullptr ||
|
||||
pRoom->m_sMaxUser < pRoom->m_sCurrentUser+1)
|
||||
nResult = 2;
|
||||
|
||||
if(pRoom->isPassword() &&
|
||||
STRCASECMP(strPassword.c_str(), pRoom->strPassword.c_str()) != 0)
|
||||
nResult = 4;
|
||||
|
||||
if(!pRoom->AddUser(GetName()))
|
||||
nResult = 2;
|
||||
|
||||
Packet result(WIZ_NATION_CHAT, uint8(CHATROOM_MANUEL));
|
||||
|
||||
result << uint8(CHATROOM_JOIN) << nResult << roomID;
|
||||
|
||||
Send(&result);
|
||||
|
||||
if(nResult == 0)
|
||||
m_ChatRoomIndex = pRoom->nIndex;
|
||||
}
|
||||
|
||||
void CUser::ChatroomLeave(Packet & pkt)
|
||||
{
|
||||
uint16 RoomID = pkt.read<uint16>();
|
||||
_CHAT_ROOM* pRoom = g_pMain->m_ChatRoomArray.GetData(RoomID);
|
||||
|
||||
if(pRoom == nullptr)
|
||||
return;
|
||||
|
||||
// Kullanıcıları odadan atma
|
||||
|
||||
if(pRoom->isAdministrator(GetName()) == 2 )
|
||||
g_pMain->m_ChatRoomArray.DeleteData(RoomID);
|
||||
|
||||
Packet result(WIZ_NATION_CHAT, uint8(CHATROOM_MANUEL));
|
||||
|
||||
result << uint8(CHATROOM_LEAVE) << uint8(0);
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::ChatRoomChat(std::string * strMessage, std::string strSender)
|
||||
{
|
||||
CUser* pUser = g_pMain->GetUserPtr(strSender, TYPE_CHARACTER);
|
||||
|
||||
if(pUser == nullptr)
|
||||
return;
|
||||
|
||||
Packet result(WIZ_CHAT,uint8(CHATROM_CHAT));
|
||||
result.DByte();
|
||||
result << uint8(0) << pUser->GetSocketID() << pUser->GetName() << *strMessage << pUser->GetZoneID();
|
||||
//10 21 00 0701 0B00 7370656369616C6C697374 0600 74656B726172 15
|
||||
|
||||
|
||||
|
||||
SendChatRoom(result);
|
||||
}
|
||||
|
||||
void CUser::ChatroomAdmin(Packet & pkt)
|
||||
{
|
||||
//19 0B 0C 00 0300 0500 726573756C 1802 0A00 0100 1802 0B00 4D617844616D616765336B
|
||||
|
||||
Packet result(WIZ_NATION_CHAT,uint8(CHATROOM_MANUEL));
|
||||
|
||||
uint16 count = 0 , subpkt = pkt.read<uint8>();
|
||||
|
||||
result << uint8(CHATROOM_ADMIN) << uint8(0) << subpkt;
|
||||
|
||||
_CHAT_ROOM* pRoom = g_pMain->m_ChatRoomArray.GetData(m_ChatRoomIndex);
|
||||
|
||||
if(pRoom == nullptr)
|
||||
return;
|
||||
|
||||
result.DByte();
|
||||
|
||||
result << pRoom->strRoomName << uint8(0x18) << uint8(0x02) << pRoom->m_sMaxUser << pRoom->m_sCurrentUser ;
|
||||
|
||||
foreach(itr,pRoom->m_UserList)
|
||||
{
|
||||
CUser* pSendUser = g_pMain->GetUserPtr(itr->second,TYPE_CHARACTER);
|
||||
|
||||
if(pSendUser == nullptr)
|
||||
continue;
|
||||
|
||||
result << uint8(0x18) << uint8(pRoom->isAdministrator(pSendUser->GetName())) << pSendUser->GetName();
|
||||
|
||||
}
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::ChatroomMemberoption(Packet & pkt)
|
||||
{
|
||||
uint8 subPkt = pkt.read<uint8>();
|
||||
|
||||
if(subPkt == 1)
|
||||
ChatroomKickout(pkt.read<uint16>());
|
||||
}
|
||||
|
||||
void CUser::ChatroomKickout(uint16 userID)
|
||||
{
|
||||
_CHAT_ROOM* pRoom = g_pMain->m_ChatRoomArray.GetData(m_ChatRoomIndex);
|
||||
|
||||
if(pRoom == nullptr)
|
||||
return;
|
||||
|
||||
Packet result(WIZ_NATION_CHAT,uint8(CHATROOM_MANUEL));
|
||||
|
||||
result << uint8(CHATROOM_MEMBEROPTION);
|
||||
|
||||
foreach(itr,pRoom->m_UserList)
|
||||
{
|
||||
if(itr->first == userID)
|
||||
{
|
||||
result << uint8(2);
|
||||
Send(&result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pRoom->m_UserList.erase(userID);
|
||||
|
||||
result << uint8(1) << userID;
|
||||
|
||||
SendChatRoom(result);
|
||||
}
|
||||
|
||||
void CUser::SendChatRoom(Packet & result)
|
||||
{
|
||||
_CHAT_ROOM* pRoom = g_pMain->m_ChatRoomArray.GetData(m_ChatRoomIndex);
|
||||
|
||||
if(pRoom == nullptr)
|
||||
return;
|
||||
|
||||
foreach(itr,pRoom->m_UserList)
|
||||
{
|
||||
CUser* pSendUser = g_pMain->GetUserPtr(itr->second,TYPE_CHARACTER);
|
||||
|
||||
if(pSendUser == nullptr)
|
||||
continue;
|
||||
|
||||
pSendUser->Send(&result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "stdafx.h"
|
||||
#include "ConsoleInputThread.h"
|
||||
#include <conio.h>
|
||||
|
||||
static Thread s_consoleInputThread;
|
||||
|
||||
void StartConsoleInputThread()
|
||||
{
|
||||
s_consoleInputThread.start(ConsoleInputThread, nullptr);
|
||||
}
|
||||
|
||||
void CleanupConsoleInputThread()
|
||||
{
|
||||
// The thread is still pretty primitive; there's no way to signal the thread to end
|
||||
// as it's blocking on fgets(). Need to fix this up so that we can wait for the thread.
|
||||
// Currently we close the thread when a read error occurs (ctrl-c causes a read error, exiting does not).
|
||||
s_consoleInputThread.waitForExit();
|
||||
}
|
||||
|
||||
uint32 THREADCALL ConsoleInputThread(void * lpParam)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t len;
|
||||
char cmd[300];
|
||||
|
||||
while (g_bRunning)
|
||||
{
|
||||
if (!_kbhit())
|
||||
{
|
||||
sleep(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read in single line from stdin
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
if (fgets(cmd, sizeof(cmd), stdin) == nullptr)
|
||||
{
|
||||
printf("Console input thread closing...\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!g_bRunning)
|
||||
break;
|
||||
|
||||
len = strlen(cmd);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (cmd[i] == '\n' || cmd[i] == '\r')
|
||||
cmd[i] = '\0';
|
||||
}
|
||||
g_pMain->HandleConsoleCommand(cmd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
void StartConsoleInputThread();
|
||||
void CleanupConsoleInputThread();
|
||||
uint32 THREADCALL ConsoleInputThread(void * lpParam);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,176 @@
|
||||
#pragma once
|
||||
|
||||
#include "../shared/database/OdbcConnection.h"
|
||||
|
||||
enum UserUpdateType
|
||||
{
|
||||
UPDATE_LOGOUT,
|
||||
UPDATE_ALL_SAVE,
|
||||
UPDATE_PACKET_SAVE,
|
||||
};
|
||||
|
||||
enum RentalType
|
||||
{
|
||||
RENTAL_TYPE_IN_LIST = 1,
|
||||
RENTAL_TYPE_LENDER = 2,
|
||||
RENTAL_TYPE_BORROWER = 3
|
||||
};
|
||||
|
||||
struct _USER_RENTAL_ITEM
|
||||
{
|
||||
std::string strUserID;
|
||||
uint64 nSerialNum;
|
||||
uint32 nRentalIndex, nItemID, nRentalMoney;
|
||||
uint16 sDurability, sRentalTime;
|
||||
int16 sMinutesRemaining;
|
||||
uint8 byRentalType, byRegType;
|
||||
char szTimeRental[30];
|
||||
|
||||
_USER_RENTAL_ITEM()
|
||||
{
|
||||
memset(&szTimeRental, 0, sizeof(szTimeRental));
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint64, _USER_RENTAL_ITEM *> UserRentalMap;
|
||||
|
||||
class Packet;
|
||||
class CUser;
|
||||
struct _ITEM_DATA;
|
||||
class CDBAgent
|
||||
{
|
||||
public:
|
||||
CDBAgent();
|
||||
|
||||
|
||||
bool Startup(bool bMarsEnabled,
|
||||
tstring & strAccountDSN, tstring & strAccountUID, tstring & strAccountPWD,
|
||||
tstring & strGameDSN, tstring & strGameUID, tstring & strGamePWD);
|
||||
|
||||
bool Connect(bool bMarsEnabled,
|
||||
tstring & strAccountDSN, tstring & strAccountUID, tstring & strAccountPWD,
|
||||
tstring & strGameDSN, tstring & strGameUID, tstring & strGamePWD);
|
||||
|
||||
void ReportSQLError(OdbcError *pError);
|
||||
|
||||
|
||||
int8 AccountLogin(std::string & strAccountID, std::string & strPasswd);
|
||||
uint8 NationSelect(std::string & strAccountID, uint8 bNation);
|
||||
bool GetAllCharID(std::string & strAccountID, std::string & strCharID1, std::string & strCharID2, std::string & strCharID3, std::string & strCharID4);
|
||||
bool SetAllCharID(std::string & strAccountID, std::string & strCharID1, std::string & strCharID2, std::string & strCharID3, std::string & strCharID4);
|
||||
void LoadCharInfo(std::string & strCharID, ByteBuffer & result);
|
||||
void LoadCharSeal(std::string & strCharID, ByteBuffer & result);
|
||||
uint16 LoadAccountNTS(std::string & strCharID);
|
||||
uint8 LoadYanCharHAS(std::string & strAccountID, std::string & strCharID);
|
||||
uint64 GetSerialByID(uint32 ID);
|
||||
uint8 LoadCharRace(std::string & strCharID);
|
||||
uint64 LoadCharExp(std::string & strCharID);
|
||||
uint8 LoadYanCharCount(std::string & strCharID);
|
||||
uint8 LoadCharLevel(std::string & strCharID);
|
||||
uint16 LoadCharKnights(std::string & strCharID);
|
||||
uint8 LoadCharNation(std::string & strCharID);
|
||||
void GetClanUserData(uint16 sClanID, _KNIGHTS_USER & p);
|
||||
int8 ChangeHair(std::string & strAccountID, std::string & strCharID, uint8 bOpcode, uint8 bFace, uint32 nHair);
|
||||
int8 CreateNewChar(std::string & strAccountID, int index, std::string & strCharID, uint8 bRace, uint16 sClass, uint32 nHair, uint8 bFace, uint8 bStr, uint8 bSta, uint8 bDex, uint8 bInt, uint8 bCha);
|
||||
void LoadRentalData(std::string & strAccountID, std::string & strCharID, UserRentalMap & rentalData);
|
||||
void LoadItemSealData(std::string & strAccountID, std::string & strCharID, UserItemSealMap & itemSealData);
|
||||
uint8 UpdatePetData(uint64 PetSerial, CPet *pPet);
|
||||
uint8 LoadPetData(uint64 PetSerial, CPet *pPet);
|
||||
uint8 InsertPetData(uint64 PetSerial, CPet *pPet);
|
||||
uint8 InsertCypherRingData(uint64 Serial, _CYPHERRING_DATA *pData, std::string strPasswd);
|
||||
uint8 InsertCypherRingChar(std::string strAccountID, uint64 Serial);
|
||||
bool LoadUserData(std::string & strAccountID, std::string & strCharID, CUser *pUser);
|
||||
bool LoadWarehouseData(std::string & strAccountID, CUser *pUser);
|
||||
bool LoadPremiumServiceUser(std::string & strAccountID, CUser *pUser);
|
||||
bool LoadSavedMagic(CUser *pUser);
|
||||
bool SetLogInInfo(std::string & strAccountID, std::string & strCharID, std::string & strServerIP, short sServerNo, std::string & strClientIP, uint8 bInit);
|
||||
bool SavePremiumServiceUser(CUser *pUser, _PREMIUM_TYPE * pPremium);
|
||||
|
||||
bool LoadWebItemMall(std::vector<_ITEM_DATA> & itemList, CUser *pUser);
|
||||
bool ClearWebItemMall(CUser *pUser);
|
||||
|
||||
bool LoadSkillShortcut(Packet & result, CUser *pUser);
|
||||
void SaveSkillShortcut(uint16 sCount, char *buff, CUser *pUser);
|
||||
void RequestFriendList(std::vector<std::string> & friendList, CUser *pUser);
|
||||
FriendAddResult AddFriend(short sid, short tid);
|
||||
FriendRemoveResult RemoveFriend(std::string & strCharID, CUser *pUser);
|
||||
|
||||
bool UpdateUser(std::string & strCharID, UserUpdateType type, CUser *pUser);
|
||||
bool UpdateWarehouseData(std::string & strAccountID, UserUpdateType type, CUser *pUser);
|
||||
bool UpdateSavedMagic(CUser *pUser);
|
||||
uint8 SealItem(std::string strSealPasswd, uint64 nItemSerial, uint32 nItemID, uint8 bSealType, CUser *pUser);
|
||||
|
||||
int8 CreateKnights(uint16 sClanID, uint8 bNation, std::string & strKnightsName, std::string & strChief, uint8 bFlag = 1);
|
||||
int UpdateKnights(uint8 bType, std::string & strCharID, uint16 sClanID, uint8 bDomination);
|
||||
int DeleteKnights(uint16 sClanID);
|
||||
void UpdateVIPStoragePassword(std::string strUserID, std::string VIPPassword);
|
||||
void UpdateVIPStorageMinute(std::string strUserID, uint32 VIPMinute);
|
||||
uint16 LoadKnightsAllMembers(uint16 sClanID, Packet & result);
|
||||
int8 CreateAlliance(uint8 byType, uint16 shAlliancIndex, uint16 shKnightsIndex, uint8 byEmptyIndex, uint8 bySiegeFlag);
|
||||
int8 InsertAlliance(uint8 byType, uint16 shAlliancIndex, uint16 shKnightsIndex, uint8 byEmptyIndex, uint8 bySiegeFlag);
|
||||
int8 RemoveAlliance(uint8 byType, uint16 shAlliancIndex, uint16 shKnightsIndex, uint8 byEmptyIndex, uint8 bySiegeFlag);
|
||||
int8 DestoryAlliance(uint8 byType, uint16 shAlliancIndex, uint16 shKnightsIndex, uint8 byEmptyIndex, uint8 bySiegeFlag);
|
||||
bool LoadKnightsInfo(uint16 sClanID, uint8 & bNation, std::string & strKnightsName, uint16 & sMembers, uint32 & nPoints, uint8 & bRank);
|
||||
void LoadKnightsAllList();
|
||||
bool UpdateClanSymbol(uint16 sClanID, uint16 sSymbolSize, char *clanSymbol);
|
||||
bool DonateClanPoints(CUser * pUser, uint32 amountNP);
|
||||
void RefundNP(std::string & strUserID, uint32 nRefundNP);
|
||||
void UpdateUserAuthority(std::string & strUserID, uint16 nAuthority);
|
||||
void UpdateClanFund(uint16 sClanID, uint32 nClanPointFund);
|
||||
void UpdateClanNotice(uint16 sClanID, std::string & strClanNotice);
|
||||
NameChangeOpcode UpdateCharacterName(std::string & strAccountID, std::string & strUserID, std::string & strNewUserID);
|
||||
ClanNameChangeOpcode UpdateClanName(std::string & strUserID, uint16 sClanID, std::string & strNewKnightsID);
|
||||
void UpdateCape(uint16 sClanID, uint16 sCapeID, uint8 r, uint8 g, uint8 b);
|
||||
void UpdatePremiumType(uint8 bType, std::string StrAccountID);
|
||||
void UpdateClanGrade(uint16 sClanID, uint8 byFlag, uint16 sCapeID);
|
||||
void UpdateAccountKnightCash(std::string & strAccountID, uint32 KnightCash = 0);
|
||||
void UpdateBattleEvent(std::string & strCharID, uint8 bNation);
|
||||
void AccountLogout(std::string & strAccountID);
|
||||
|
||||
void InsertRepurchase(uint32 nItemID, time_t RepTime, uint64 nSerial, CUser *pUser);
|
||||
void DeleteRepurchase(uint32 nItemID, time_t RepTime, CUser *pUser);
|
||||
void LoadRepurchase(CUser *pUser);
|
||||
|
||||
|
||||
void UpdateConCurrentUserCount(int nServerNo, int nZoneNo, int nCount);
|
||||
|
||||
uint8 GetUnreadLetterCount(std::string & strCharID);
|
||||
bool GetLetterList(std::string & strCharID, Packet & result, bool bNewLettersOnly = true);
|
||||
int8 SendLetter(std::string & strSenderID, std::string & strRecipientID, std::string & strSubject, std::string & strMessage, uint8 bType, _ITEM_DATA * pItem, int32 nCoins);
|
||||
bool ReadLetter(std::string & strCharID, uint32 nLetterID, std::string & strMessage);
|
||||
int8 GetItemFromLetter(std::string & strCharID, uint32 nLetterID, uint32 & nItemID, uint16 & sCount, uint16 & sDurability, uint32 & nCoins, uint64 & nSerialNum, uint32 & nExpirationTime);
|
||||
void DeleteLetter(std::string & strCharID, uint32 nLetterID);
|
||||
void ResendLetter(std::string & strCharID, uint32 nLetterID);
|
||||
void SendUDP_ElectionStatus(uint8 m_byType);
|
||||
bool GetElectionResult(uint8 byNation,CKingSystem *KingSystem);
|
||||
void UpdateElectionStatus(uint8 byType, uint8 byNation);
|
||||
void UpdateElectionList(uint8 byDBType, uint8 byType, uint8 byNation, uint16 sKnights, uint32 nAmount, std::string & strNominee, CUser * pUser);
|
||||
int16 UpdateElectionProc(CUser * pUser);
|
||||
int16 UpdateCandidacyRecommend(std::string & strNominator, std::string & strNominee, uint8 byNation);
|
||||
void UpdateCandidacyNoticeBoard(std::string & strCharID, uint8 byNation, std::string & strNotice);
|
||||
void UpdateNoahOrExpEvent(uint8 byType, uint8 byNation, uint8 byAmount, uint8 byDay, uint8 byHour, uint8 byMinute, uint16 sDuration);
|
||||
void InsertPrizeEvent(uint8 byType, uint8 byNation, uint32 nCoins, std::string & strCharID);
|
||||
void InsertTaxEvent(uint8 KingNationTax, uint8 Nation, uint32 TerritoryTax = 0);
|
||||
void InsertTaxUpEvent(uint8 Nation, uint32 TerritoryTax);
|
||||
void ResetLoyaltyMonthly();
|
||||
void ClearRemainUsers();
|
||||
void InsertUserDailyOp(_USER_DAILY_OP * pUserDailyOp);
|
||||
void UpdateUserDailyOp(std::string strUserId, uint8 type, int32 sUnixTime);
|
||||
void UpdateRanks();
|
||||
void UpdateSiege(int16 m_sCastleIndex, int16 m_sMasterKnights, int16 m_bySiegeType, int16 m_byWarDay, int16 m_byWarTime, int16 m_byWarMinute);
|
||||
void UpdateSiegeTax(uint8 Zone, int16 ZoneTarrif);
|
||||
|
||||
int8 NationTransfer(std::string strAccountID, uint16 Race1, uint16 Race2, uint16 Race3, uint16 Race4);
|
||||
int8 YanChar(std::string strAccountID);
|
||||
int8 YanCharClan(std::string strAccountID);
|
||||
|
||||
~CDBAgent();
|
||||
|
||||
private:
|
||||
OdbcConnection *m_GameDB, *m_AccountDB;
|
||||
std::recursive_mutex m_lock;
|
||||
|
||||
friend class CGameServerDlg;
|
||||
};
|
||||
|
||||
extern CDBAgent g_DBAgent;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
class DatabaseThread
|
||||
{
|
||||
public:
|
||||
// Startup the database threads
|
||||
static void Startup();
|
||||
|
||||
// Add to the queue and notify threads of activity.
|
||||
static void AddRequest(Packet * pkt);
|
||||
|
||||
// Main thread procedure
|
||||
static uint32 THREADCALL ThreadProc(void * lpParam);
|
||||
|
||||
// Shutdown threads.
|
||||
static void Shutdown();
|
||||
};
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,116 @@
|
||||
f:\005server\gameserver\debug\gameserver.pch
|
||||
f:\005server\gameserver\debug\vc142.pdb
|
||||
f:\005server\gameserver\debug\vc142.ıdb
|
||||
f:\005server\gameserver\debug\stdafx.obj
|
||||
f:\005server\gameserver\debug\n3shapemgr.obj
|
||||
f:\005server\gameserver\debug\magıcprocess.obj
|
||||
f:\005server\gameserver\debug\maın.obj
|
||||
f:\005server\gameserver\debug\map.obj
|
||||
f:\005server\gameserver\debug\npc.obj
|
||||
f:\005server\gameserver\debug\characterhandler.obj
|
||||
f:\005server\gameserver\debug\pet.obj
|
||||
f:\005server\gameserver\debug\regıon.obj
|
||||
f:\005server\gameserver\debug\rentalhandler.obj
|
||||
f:\005server\gameserver\debug\loadserverdata.obj
|
||||
f:\005server\gameserver\debug\sealhandler.obj
|
||||
f:\005server\gameserver\debug\shoppıngmallhandler.obj
|
||||
f:\005server\gameserver\debug\tradehandler.obj
|
||||
f:\005server\gameserver\debug\unıt.obj
|
||||
f:\005server\gameserver\debug\upgradehandler.obj
|
||||
f:\005server\gameserver\debug\vıp.obj
|
||||
f:\005server\gameserver\debug\characterselectıonhandler.obj
|
||||
f:\005server\gameserver\debug\charactermovementhandler.obj
|
||||
f:\005server\gameserver\debug\chatroomhandler.obj
|
||||
f:\005server\gameserver\debug\consoleınputthread.obj
|
||||
f:\005server\gameserver\debug\databasethread.obj
|
||||
f:\005server\gameserver\debug\dbagent.obj
|
||||
f:\005server\gameserver\debug\eventhandler.obj
|
||||
f:\005server\gameserver\debug\frıendhandler.obj
|
||||
f:\005server\gameserver\debug\gameevent.obj
|
||||
f:\005server\gameserver\debug\ıtemhandler.obj
|
||||
f:\005server\gameserver\debug\kıngsystem.obj
|
||||
f:\005server\gameserver\debug\knıghts.obj
|
||||
f:\005server\gameserver\debug\knıghtsmanager.obj
|
||||
f:\005server\gameserver\debug\letterhandler.obj
|
||||
f:\005server\gameserver\debug\logınhandler.obj
|
||||
f:\005server\gameserver\debug\luaengıne.obj
|
||||
f:\005server\gameserver\debug\lua_bındıngs.obj
|
||||
f:\005server\gameserver\debug\achıevementhandler.obj
|
||||
f:\005server\gameserver\debug\aısocket.obj
|
||||
f:\005server\gameserver\debug\arenahandler.obj
|
||||
f:\005server\gameserver\debug\attackhandler.obj
|
||||
f:\005server\gameserver\debug\bot.obj
|
||||
f:\005server\gameserver\debug\merchanthandler.obj
|
||||
f:\005server\gameserver\debug\npchandler.obj
|
||||
f:\005server\gameserver\debug\partyhandler.obj
|
||||
f:\005server\gameserver\debug\questhandler.obj
|
||||
f:\005server\gameserver\debug\user.obj
|
||||
f:\005server\gameserver\debug\chathandler.obj
|
||||
f:\005server\gameserver\debug\gameserverdlg.obj
|
||||
f:\005server\gameserver\debug\magıcınstance.obj
|
||||
f:\005server\gameserver\debug\vcpkg.applocal.log
|
||||
f:\bın\debug\gameserver.ılk
|
||||
f:\bın\debug\gameserver.exe
|
||||
f:\bın\debug\gameserver.pdb
|
||||
f:\005server\gameserver\debug\gameserver.res
|
||||
f:\005server\server source\gameserver\debug\achievementhandler.obj
|
||||
f:\005server\server source\gameserver\debug\aısocket.obj
|
||||
f:\005server\server source\gameserver\debug\arenahandler.obj
|
||||
f:\005server\server source\gameserver\debug\attackhandler.obj
|
||||
f:\005server\server source\gameserver\debug\bot.obj
|
||||
f:\005server\server source\gameserver\debug\characterhandler.obj
|
||||
f:\005server\server source\gameserver\debug\charactermovementhandler.obj
|
||||
f:\005server\server source\gameserver\debug\characterselectionhandler.obj
|
||||
f:\005server\server source\gameserver\debug\chathandler.obj
|
||||
f:\005server\server source\gameserver\debug\chatroomhandler.obj
|
||||
f:\005server\server source\gameserver\debug\consoleınputthread.obj
|
||||
f:\005server\server source\gameserver\debug\databasethread.obj
|
||||
f:\005server\server source\gameserver\debug\dbagent.obj
|
||||
f:\005server\server source\gameserver\debug\eventhandler.obj
|
||||
f:\005server\server source\gameserver\debug\friendhandler.obj
|
||||
f:\005server\server source\gameserver\debug\gameevent.obj
|
||||
f:\005server\server source\gameserver\debug\gameserverdlg.obj
|
||||
f:\005server\server source\gameserver\debug\ıtemhandler.obj
|
||||
f:\005server\server source\gameserver\debug\kingsystem.obj
|
||||
f:\005server\server source\gameserver\debug\knights.obj
|
||||
f:\005server\server source\gameserver\debug\knightsmanager.obj
|
||||
f:\005server\server source\gameserver\debug\letterhandler.obj
|
||||
f:\005server\server source\gameserver\debug\loadserverdata.obj
|
||||
f:\005server\server source\gameserver\debug\loginhandler.obj
|
||||
f:\005server\server source\gameserver\debug\luaengine.obj
|
||||
f:\005server\server source\gameserver\debug\lua_bindings.obj
|
||||
f:\005server\server source\gameserver\debug\magicınstance.obj
|
||||
f:\005server\server source\gameserver\debug\magicprocess.obj
|
||||
f:\005server\server source\gameserver\debug\main.obj
|
||||
f:\005server\server source\gameserver\debug\map.obj
|
||||
f:\005server\server source\gameserver\debug\merchanthandler.obj
|
||||
f:\005server\server source\gameserver\debug\n3shapemgr.obj
|
||||
f:\005server\server source\gameserver\debug\npc.obj
|
||||
f:\005server\server source\gameserver\debug\npchandler.obj
|
||||
f:\005server\server source\gameserver\debug\partyhandler.obj
|
||||
f:\005server\server source\gameserver\debug\pet.obj
|
||||
f:\005server\server source\gameserver\debug\questhandler.obj
|
||||
f:\005server\server source\gameserver\debug\region.obj
|
||||
f:\005server\server source\gameserver\debug\rentalhandler.obj
|
||||
f:\005server\server source\gameserver\debug\sealhandler.obj
|
||||
f:\005server\server source\gameserver\debug\shoppingmallhandler.obj
|
||||
f:\005server\server source\gameserver\debug\stdafx.obj
|
||||
f:\005server\server source\gameserver\debug\tradehandler.obj
|
||||
f:\005server\server source\gameserver\debug\unit.obj
|
||||
f:\005server\server source\gameserver\debug\upgradehandler.obj
|
||||
f:\005server\server source\gameserver\debug\user.obj
|
||||
f:\005server\server source\gameserver\debug\vıp.obj
|
||||
f:\005server\server source\gameserver\debug\gameserver.res
|
||||
f:\005server\server source\gameserver\debug\gameserver.pch
|
||||
f:\005server\server source\gameserver\debug\vc142.idb
|
||||
f:\005server\server source\gameserver\debug\vc142.pdb
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\cl.command.1.tlog
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\cl.read.1.tlog
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\cl.write.1.tlog
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\gameserver.write.1u.tlog
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\link.command.1.tlog
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\link.read.1.tlog
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\link.write.1.tlog
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\rc.command.1.tlog
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\rc.read.1.tlog
|
||||
f:\005server\server source\gameserver\debug\gameserver.tlog\rc.write.1.tlog
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
#TargetFrameworkVersion=v4.0:PlatformToolSet=v142:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0.17763.0
|
||||
Debug|Win32|F:\005SERVER\server source\|
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
cl : Command line warning D9035 : option 'Gm' has been deprecated and will be removed in a future release
|
||||
User.cpp
|
||||
F:\005SERVER\server source\GameServer\User.cpp(1286,68): warning C4267: '=': conversion from 'size_t' to 'uint8', possible loss of data
|
||||
F:\005SERVER\server source\GameServer\User.cpp(4300,48): warning C4267: '+=': conversion from 'size_t' to 'uint16', possible loss of data
|
||||
proj-GameServer.vcxproj -> F:\005SERVER\server source\..\bin\Debug\GameServer.exe
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
#pragma once
|
||||
|
||||
#define CONF_GAME_SERVER "./GameServer.ini"
|
||||
|
||||
#define _UDP_PORT 8888
|
||||
#define CLIENT_SOCKSIZE 100
|
||||
|
||||
#define MAX_NPC_SIZE 30
|
||||
|
||||
#define MAX_TYPE3_REPEAT 40
|
||||
#define MAX_TYPE4_BUFF 50
|
||||
|
||||
#define MAX_ITEM 28
|
||||
|
||||
#define NPC_HAVE_ITEM_LIST 6
|
||||
#define DROP_MAX_TIME 60 // As second
|
||||
#define ZONEITEM_MAX 2100000000
|
||||
#define COIN_MAX 2100000000
|
||||
#define LOYALTY_MAX 2100000000
|
||||
|
||||
#define MAX_CLASS 26
|
||||
#define MAX_LEVEL 83
|
||||
#define MAX_LEVEL_PET 60
|
||||
#define MAX_PLAYER_HP 14000
|
||||
#define MAX_DAMAGE 32000 // Game uses a signed 2 byte integer, so the limit is technically 32,767. The game, however, caps it at 32,000.
|
||||
|
||||
#define MAX_MESSAGE_EVENT 12
|
||||
#define MAX_TEMPLE_EVENT_ROOM 50
|
||||
#define MAX_MONSTER_STONE_EVENT_ROOM 200
|
||||
|
||||
// BBS Related
|
||||
#define MAX_BBS_PAGE 22
|
||||
#define MAX_BBS_MESSAGE 40
|
||||
#define MAX_BBS_TITLE 20
|
||||
#define MAX_BBS_POST 500
|
||||
|
||||
#define BUY_POST_PRICE 500
|
||||
#define SELL_POST_PRICE 1000
|
||||
|
||||
#define REMOTE_PURCHASE_PRICE 5000
|
||||
#define BBS_CHECK_TIME 36000
|
||||
|
||||
#define BATTLE 6
|
||||
|
||||
#define KARUS_ARRAY (KARUS - 1)
|
||||
#define ELMORAD_ARRAY (ELMORAD - 1)
|
||||
#define MONSTER_CHALLENGE_COUNT 32
|
||||
|
||||
|
||||
#define KING_RANK 1000
|
||||
#define WAR_HEROES_RANK 0
|
||||
#define LADDER_RANK 100
|
||||
#define CLAN_RANK 110
|
||||
#define BATTLE_HEROES_RANK 300
|
||||
|
||||
// Attack Type
|
||||
#define DIRECT_ATTACK 0
|
||||
#define LONG_ATTACK 1
|
||||
#define MAGIC_ATTACK 2
|
||||
#define DURATION_ATTACK 3
|
||||
|
||||
|
||||
// Kurian/Portu Absorbed
|
||||
#define ABSORBED_TOTAL -20000
|
||||
|
||||
enum InOutType
|
||||
{
|
||||
INOUT_IN = 1,
|
||||
INOUT_OUT = 2,
|
||||
INOUT_RESPAWN = 3,
|
||||
INOUT_WARP = 4,
|
||||
INOUT_SUMMON = 5
|
||||
};
|
||||
|
||||
#define BLINK_TIME (10) // in seconds
|
||||
#define CLAN_SUMMON_TIME (180)
|
||||
#define PLAYER_IDLE_TIME (300)
|
||||
|
||||
// About Map Object
|
||||
#define USER_BAND 0
|
||||
#define NPC_BAND 10000
|
||||
#define INVALID_BAND 30000
|
||||
|
||||
#define EVENT_MONSTER 20
|
||||
|
||||
// Snow Event
|
||||
#define SNOW_EVENT_MONEY 2000
|
||||
#define SNOW_EVENT_SKILL 490077
|
||||
|
||||
// Temple Event
|
||||
#define BIFROST_EVENT_COUNT 3
|
||||
#define CHAOS_EVENT_COUNT 3
|
||||
#define BORDER_DEFENSE_WAR_EVENT_COUNT 5
|
||||
#define JURAD_MOUNTAIN_EVENT_COUNT 3
|
||||
|
||||
// Users under level 35 require 3,000 coins to shout.
|
||||
#define SHOUT_COIN_REQUIREMENT 3000
|
||||
|
||||
// Battlezone Announcement
|
||||
#define BATTLEZONE_OPEN 0x00
|
||||
#define BATTLEZONE_CLOSE 0x01
|
||||
#define DECLARE_WINNER 0x02
|
||||
#define DECLARE_LOSER 0x03
|
||||
#define DECLARE_BAN 0x04
|
||||
#define KARUS_CAPTAIN_NOTIFY 0x05
|
||||
#define ELMORAD_CAPTAIN_NOTIFY 0x06
|
||||
#define KARUS_CAPTAIN_DEPRIVE_NOTIFY 0x07
|
||||
#define ELMORAD_CAPTAIN_DEPRIVE_NOTIFY 0x08
|
||||
#define SNOW_BATTLEZONE_OPEN 0x09
|
||||
#define UNDER_ATTACK_NOTIFY 0x10
|
||||
#define DECLARE_BATTLE_ZONE_STATUS 0x11
|
||||
#define DECLARE_BATTLE_MONUMENT_STATUS 0x12
|
||||
#define DECLARE_NATION_MONUMENT_STATUS 0x13
|
||||
#define DECLARE_NATION_REWARD_STATUS 0x14
|
||||
#define SNOW_BATTLEZONE_CLOSE 0x15
|
||||
#define SNOW_BAN 0x16
|
||||
|
||||
#define WAR_TIME_COUNT 3
|
||||
#define WAR_ZONE_COUNT WAR_TIME_COUNT
|
||||
#define WAR_DAY_COUNT 7
|
||||
|
||||
// Battle define
|
||||
#define NO_BATTLE 0
|
||||
#define NATION_BATTLE 1
|
||||
#define SNOW_BATTLE 2
|
||||
#define CLAN_BATTLE 3
|
||||
|
||||
// Zone IDs
|
||||
#define ZONE_KARUS 1
|
||||
#define ZONE_ELMORAD 2
|
||||
#define ZONE_KARUS_ESLANT 11
|
||||
#define ZONE_ELMORAD_ESLANT 12
|
||||
#define ZONE_MORADON 21
|
||||
#define ZONE_MORADONM2 22
|
||||
#define ZONE_DELOS 30
|
||||
#define ZONE_BIFROST 31
|
||||
#define ZONE_DESPERATION_ABYSS 32
|
||||
#define ZONE_HELL_ABYSS 33
|
||||
#define ZONE_DRAGON_CAVE 34
|
||||
#define ZONE_ARENA 48
|
||||
#define ZONE_ORC_ARENA 51
|
||||
#define ZONE_BLOOD_DON_ARENA 52
|
||||
#define ZONE_GOBLIN_ARENA 53
|
||||
#define ZONE_CAITHAROS_ARENA 54
|
||||
#define ZONE_FORGOTTEN_TEMPLE 55
|
||||
#define ZONE_LOST_TEMPLE 56
|
||||
|
||||
#define ZONE_BATTLE_BASE 60
|
||||
|
||||
#define ZONE_BATTLE ZONE_BATTLE_BASE + 1 // Napies Gorge
|
||||
#define ZONE_BATTLE2 ZONE_BATTLE_BASE + 2 // Alseids Prairie
|
||||
#define ZONE_BATTLE3 ZONE_BATTLE_BASE + 3 // Nieds Triangle
|
||||
#define ZONE_BATTLE4 ZONE_BATTLE_BASE + 4 // Nereid's Island
|
||||
#define ZONE_BATTLE5 ZONE_BATTLE_BASE + 5 // Zipang
|
||||
#define ZONE_BATTLE6 ZONE_BATTLE_BASE + 6 // Oreads
|
||||
|
||||
#define ZONE_SNOW_BATTLE 69
|
||||
#define ZONE_RONARK_LAND 71
|
||||
#define ZONE_ARDREAM 72
|
||||
#define ZONE_RONARK_LAND_BASE 73
|
||||
#define ZONE_KROWAZ_DOMINION 75
|
||||
#define ZONE_CLAN_EVENT 77
|
||||
#define ZONE_PVP_EVENT 78
|
||||
|
||||
#define ZONE_STONE1 81
|
||||
#define ZONE_STONE2 82
|
||||
#define ZONE_STONE3 83
|
||||
#define ZONE_BORDER_DEFENSE_WAR 84
|
||||
#define ZONE_CHAOS_DUNGEON 85
|
||||
#define ZONE_DARK_LAND 86
|
||||
#define ZONE_JURAD_MOUNTAIN 87
|
||||
#define ZONE_PRISON 92
|
||||
#define ZONE_ISILOON_ARENA 93
|
||||
#define ZONE_FELANKOR_ARENA 94
|
||||
#define ZONE_WINNER_CASTLE 97
|
||||
#define ZONE_WINNER_CASTLE2 98
|
||||
|
||||
#define MAX_BATTLE_ZONE_USERS 1000
|
||||
|
||||
// Zone level requirements (should really be in a database or something...)
|
||||
#define MIN_LEVEL_NATION_BASE 35
|
||||
#define MIN_LEVEL_ESLANT 60
|
||||
#define MIN_LEVEL_BIFROST 55
|
||||
#define MIN_LEVEL_WAR_ZONE 35
|
||||
#define MIN_LEVEL_NIEDS_TRIANGLE 35
|
||||
#define MIN_LEVEL_FOR_BATTLES 35
|
||||
#define MAX_LEVEL_NIEDS_TRIANGLE 62
|
||||
#define MIN_LEVEL_RONARK_LAND 55
|
||||
#define MIN_LEVEL_ARDREAM 35
|
||||
#define MAX_LEVEL_ARDREAM 62
|
||||
#define MIN_LEVEL_RONARK_LAND_BASE 45
|
||||
#define MAX_LEVEL_RONARK_LAND_BASE 69
|
||||
#define MIN_LEVEL_KROWAZ_DOMINION 70
|
||||
#define MIN_LEVEL_JURAD_MOUNTAIN 70
|
||||
|
||||
|
||||
// Where to respawn after dying in the Moradon arenas
|
||||
#define MINI_ARENA_RESPAWN_X 734
|
||||
#define MINI_ARENA_RESPAWN_Z 427
|
||||
#define MINI_ARENA_RESPAWN_RADIUS 5
|
||||
|
||||
// Bonus experience in War zones or PK zones
|
||||
#define PVP_BONUS_EXP 10000
|
||||
#define PVP_BONUS_GOLD 150000
|
||||
|
||||
// Where to Warp dodo or laon camp in the enemy nation zone
|
||||
#define DODO_CAMP_WARP_X 10540
|
||||
#define DODO_CAMP_WARP_Z 11410
|
||||
#define LAON_CAMP_WARP_X 10120
|
||||
#define LAON_CAMP_WARP_Z 9140
|
||||
#define DODO_LAON_WARP_RADIUS 5
|
||||
// Deva Kill Time
|
||||
#define DEVA_KILL_TIME 3 // Second
|
||||
// Automatic Ranking Minutes
|
||||
#define RELOAD_KNIGHTS_AND_USER_RATING 15 // Minute
|
||||
|
||||
// Where to respawn after dying in the Chaos Stone boss
|
||||
#define CHAOS_STONE_MONSTER_RESPAWN_RADIUS 20
|
||||
#define CHAOS_STONE_MONSTER_LIVE_TIME 900 // (15 minutes)
|
||||
|
||||
// Standard (pre-squared) range used for moradon mini arena.
|
||||
#define RANGE_20M 20.0f
|
||||
|
||||
// Standard (pre-squared) range used for party rewards and such.
|
||||
#define RANGE_50M (50.0f * 50.0f)
|
||||
|
||||
// Item IDs
|
||||
#define ITEM_CONT_RECOVERY 800370000
|
||||
#define ITEM_SCROLL_OF_IDENTITY 800032000
|
||||
#define ITEM_CLAN_NCS 800086000
|
||||
#define ITEM_NATION_TRANSFER 800360000
|
||||
#define ITEM_GENDER_CHANGE 810594000
|
||||
#define ITEM_JOB_CHANGE 900006000
|
||||
#define ITEM_MAKE_OVER 810340000
|
||||
#define ITEM_MEAT_DUMPLING 508216000
|
||||
#define ITEM_EVENT_PARTICI 930046000
|
||||
#define GOLDEN_MATTOCK 389135000
|
||||
#define MATTOCK 389132000
|
||||
#define MYSTERIOUS_ORE 399210000
|
||||
#define MYSTERIOUS_GOLD_ORE 399200000
|
||||
#define SLING 389043000
|
||||
#define KING_SCEPTER 910074311
|
||||
#define CHAOS_MAP 910246000
|
||||
#define VOUCHER_OF_CHAOS 900106000
|
||||
#define VOUCHER_OF_ORACLE 900184000
|
||||
#define CERTIFICATE_OF_VICTORY 900017000
|
||||
#define BORDER_SECURITY_SCROLL 900055000
|
||||
#define RED_TREASURE_CHEST 379154000
|
||||
#define GREEN_TREASURE_CHEST 379155000
|
||||
#define BLUE_TREASURE_CHEST 379156000
|
||||
#define KNIGHT_MEDAL 389217000
|
||||
#define ROYAL_MEDAL 389218000
|
||||
#define KING_MEDAL 389219000
|
||||
#define GOLD_EAGLE_WINGS 900177663
|
||||
#define ITEM_MONSTER_STONE 900144023
|
||||
#define MONSTERSTONEDROPRATE 50
|
||||
#define ITEM_MONSTER_HUNT1 910138000
|
||||
#define ITEM_MONSTER_HUNT2 910038000
|
||||
#define ITEM_MONSTER_HUNT3 910039000
|
||||
#define ITEM_ONLINE_REWARD 930045000
|
||||
#define ITEM_LIGHT_PIT 700041000
|
||||
#define ITEM_DRAIN_RESTORE 700040000
|
||||
#define ITEM_KILLING_BLADE 700037000
|
||||
#define FISHING 191346000
|
||||
#define GOLDEN_FISHING 191347000
|
||||
#define RAINWORM 508226000
|
||||
#define EXP_FLASH 399127000
|
||||
#define DC_FLASH 399128000
|
||||
#define WAR_FLASH 399129000
|
||||
#define ITEM_MENICIAS_LIST 810166000
|
||||
|
||||
#define ARRANGE_LINE 800444000
|
||||
|
||||
#define SILVERY_GEM 389196000
|
||||
#define RED_GEM 389197000
|
||||
#define YELLOW_GEM 389198000
|
||||
#define BLUE_GEM 389199000
|
||||
#define GREEN_GEM 389201000
|
||||
#define BLACK_GEM 389205000
|
||||
|
||||
// ID of the Seed quest, to be automatically started on first load.
|
||||
#define STARTER_SEED_QUEST 500
|
||||
#define PET_QUEST 525
|
||||
|
||||
#define MONUMENT_KARUS_SPID 14003
|
||||
#define MONUMENT_ELMORAD_SPID 14004
|
||||
#define MONUMENT_ENEMY_SPID 14005
|
||||
#define BDW_KARUS_MONUMENT_SPID 14105
|
||||
#define BDW_ELMO_MONUMENT_SPID 14105
|
||||
|
||||
#define ELMORAD_MONUMENT_SID 10301
|
||||
#define ASGA_VILLAGE_MONUMENT_SID 10302
|
||||
#define RAIBA_VILLAGE_MONUMENT_SID 10303
|
||||
#define DODO_CAMP_MONUMENT_SID 10304
|
||||
|
||||
#define LUFERSON_MONUMENT_SID 20301
|
||||
#define LINATE_MONUMENT_SID 20302
|
||||
#define BELLUA_MONUMENT_SID 20303
|
||||
#define LAON_CAMP_MONUMENT_SID 20304
|
||||
#define BORDER_WAR_MONUMENT_SID 31316
|
||||
|
||||
#define SAW_BLADE_SSID 32153
|
||||
#define CHAOS_CUBE_SSID 31527
|
||||
|
||||
enum UserStatus
|
||||
{
|
||||
USER_STATUS_DOT = 1,
|
||||
USER_STATUS_POISON = 2,
|
||||
USER_STATUS_SPEED = 3,
|
||||
USER_STATUS_BLIND = 4,
|
||||
USER_STATUS_BLACK = 5
|
||||
};
|
||||
|
||||
enum UserStatusBehaviour
|
||||
{
|
||||
USER_STATUS_CURE = 0,
|
||||
USER_STATUS_INFLICT = 1
|
||||
};
|
||||
|
||||
enum NpcStatusBehaviour
|
||||
{
|
||||
NPC_STATUS_CURE = 0,
|
||||
NPC_STATUS_INFLICT = 1
|
||||
};
|
||||
|
||||
enum LoyaltyType
|
||||
{
|
||||
LOYALTY_NATIONAL_POINTS = 1,
|
||||
LOYALTY_MANNER_POINTS = 2
|
||||
};
|
||||
|
||||
enum AttributeType
|
||||
{
|
||||
AttributeNone = 0,
|
||||
AttributeFire = 1,
|
||||
AttributeIce = 2,
|
||||
AttributeLightning = 3,
|
||||
AttributeLightMagic = 4,
|
||||
AttributeCurse = 5,
|
||||
AttributePosion = 6
|
||||
};
|
||||
|
||||
typedef union{
|
||||
uint16 w;
|
||||
uint8 b[2];
|
||||
} MYSHORT;
|
||||
|
||||
typedef union{
|
||||
uint64 i;
|
||||
uint8 b[8];
|
||||
} MYINT64;
|
||||
|
||||
#define TO_USER(v) static_cast<CUser *>(v)
|
||||
#define TO_NPC(v) static_cast<CNpc *>(v)
|
||||
|
||||
#include "../shared/globals.h"
|
||||
@@ -0,0 +1,423 @@
|
||||
#include "stdafx.h"
|
||||
#include "DBAgent.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
void CGameServerDlg::SendEventRemainingTime(bool bSendAll, CUser *pUser, uint8 ZoneID)
|
||||
{
|
||||
Packet result(WIZ_BIFROST,uint8(BIFROST_EVENT));
|
||||
uint16 nRemainingTime = 0;
|
||||
|
||||
if (ZoneID == ZONE_BATTLE4)
|
||||
nRemainingTime = m_byBattleRemainingTime / 2;
|
||||
else if (ZoneID == ZONE_BIFROST || ZoneID == ZONE_RONARK_LAND)
|
||||
nRemainingTime = m_sBifrostRemainingTime;
|
||||
|
||||
result << nRemainingTime;
|
||||
|
||||
if (pUser)
|
||||
pUser->Send(&result);
|
||||
else if (bSendAll)
|
||||
{
|
||||
if (ZoneID == ZONE_BATTLE4)
|
||||
Send_All(&result,nullptr, 0, ZONE_BATTLE4);
|
||||
else
|
||||
{
|
||||
Send_All(&result,nullptr, 0, ZONE_RONARK_LAND);
|
||||
Send_All(&result,nullptr, 0, ZONE_BIFROST);
|
||||
}
|
||||
}
|
||||
}
|
||||
void CUser::CastleSiegeWarProcess(CUser * pUser)
|
||||
{
|
||||
if (pUser == nullptr || GetClanID() <= 0)
|
||||
return;
|
||||
|
||||
_KNIGHTS_SIEGE_WARFARE *pKnightSiegeWar = g_pMain->GetSiegeMasterKnightsPtr(1);
|
||||
CKnights * pKnights = g_pMain->GetClanPtr(pUser->m_bKnights);
|
||||
|
||||
pKnightSiegeWar->sMasterKnights = pKnights->m_sIndex;
|
||||
|
||||
g_pMain->UpdateSiege(pKnightSiegeWar->sCastleIndex, pKnightSiegeWar->sMasterKnights, pKnightSiegeWar->bySiegeType, pKnightSiegeWar->byWarDay, pKnightSiegeWar->byWarTime, pKnightSiegeWar->byWarMinute);
|
||||
g_pMain->m_KnightsSiegeWarfareArray.GetData(pKnightSiegeWar->sMasterKnights);
|
||||
|
||||
g_pMain->m_SiegeWarWinKnightsNotice = pKnights->GetName();
|
||||
g_pMain->Announcement(IDS_NPC_GUIDON_DESTORY);
|
||||
g_pMain->m_byBattleSiegeWarMomument = true;
|
||||
g_pMain->m_byBattleSiegeWarOccupy = g_pMain->m_sBattleTimeDelay > 2100 ? (3000 - g_pMain->m_sBattleTimeDelay) : 900;
|
||||
//g_pMain->KickOutZoneUsers(ZONE_DELOS, ZONE_DELOS);
|
||||
if (pKnightSiegeWar != nullptr)
|
||||
{
|
||||
Packet result(WIZ_SIEGE, uint8(2));
|
||||
result.SByte();
|
||||
result << uint8(g_pMain->m_byBattleSiegeWarOpen + 1)<< pKnights->GetID() << pKnights->m_sMarkVersion << uint16(0)
|
||||
<< uint32(g_pMain->m_byBattleSiegeWarOpen ? g_pMain->m_byBattleSiegeWarOccupy : 0) << uint16(g_pMain->m_byBattleSiegeWarOpen ? ((50 * MINUTE) - g_pMain->m_sBattleTimeDelay) : 0)
|
||||
<< pKnights->GetName();
|
||||
g_pMain->Send_Zone(&result,ZONE_DELOS);
|
||||
}
|
||||
}
|
||||
void CUser::BifrostProcess(CUser * pUser)
|
||||
{
|
||||
if (pUser == nullptr)
|
||||
return;
|
||||
|
||||
if (g_pMain->m_BifrostVictory == 0 && g_pMain->m_bAttackBifrostMonument)
|
||||
{
|
||||
g_pMain->m_sBifrostTime = g_pMain->m_xBifrostTime;
|
||||
g_pMain->m_sBifrostRemainingTime = g_pMain->m_sBifrostTime;
|
||||
g_pMain->m_BifrostVictory = pUser->GetNation();
|
||||
g_pMain->SendFormattedResource(pUser->GetNation() == ELMORAD ? IDS_BEEF_ROAST_VICTORY_ELMORAD : IDS_BEEF_ROAST_VICTORY_KARUS, Nation::ALL,false);
|
||||
g_pMain->SendEventRemainingTime(true, nullptr, ZONE_BIFROST);
|
||||
|
||||
if (g_pMain->m_bAttackBifrostMonument)
|
||||
g_pMain->m_bAttackBifrostMonument = false;
|
||||
}
|
||||
else if (g_pMain->m_BifrostVictory == 1 || g_pMain->m_BifrostVictory == 2)
|
||||
{
|
||||
if (pUser->GetNation() != g_pMain->m_BifrostVictory && g_pMain->m_bAttackBifrostMonument)
|
||||
{
|
||||
g_pMain->m_BifrostVictory = 3;
|
||||
g_pMain->SendFormattedResource(pUser->GetNation() == ELMORAD ? IDS_BEEF_ROAST_VICTORY_ELMORAD : IDS_BEEF_ROAST_VICTORY_KARUS, Nation::ALL,false);
|
||||
|
||||
if (g_pMain->m_bAttackBifrostMonument)
|
||||
g_pMain->m_bAttackBifrostMonument = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::TempleProcess(Packet &pkt )
|
||||
{
|
||||
uint8 opcode = pkt.read<uint8>();
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case MONSTER_STONE:
|
||||
MonsterStoneProcess();
|
||||
break;
|
||||
case TEMPLE_EVENT_JOIN:
|
||||
TempleOperations(opcode);
|
||||
break;
|
||||
case TEMPLE_EVENT_DISBAND:
|
||||
TempleOperations(opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::MonsterStoneProcess()
|
||||
{
|
||||
if(GetZoneID() == ZONE_STONE1 ||
|
||||
GetZoneID() == ZONE_STONE3 ||
|
||||
GetZoneID() == ZONE_STONE3)
|
||||
return;
|
||||
|
||||
if(CheckExistItem(ITEM_MONSTER_STONE,1))
|
||||
{
|
||||
uint8 EventRoom = 0;
|
||||
uint8 ZoneNumber = 0;
|
||||
uint32 ZoneTime = 0;
|
||||
|
||||
if(GetLevel() < 40)
|
||||
ZoneNumber = ZONE_STONE1;
|
||||
else if(GetLevel() < 60)
|
||||
ZoneNumber = ZONE_STONE2;
|
||||
else if(GetLevel() < 84)
|
||||
ZoneNumber = ZONE_STONE3;
|
||||
else
|
||||
return;
|
||||
|
||||
bool IsFull = true;
|
||||
|
||||
for(int i = 1; i < MAX_MONSTER_STONE_EVENT_ROOM; i++)
|
||||
{
|
||||
|
||||
if(ZoneNumber == ZONE_STONE1)
|
||||
{
|
||||
IsFull = g_pMain->IsBusy1[i];
|
||||
ZoneTime = g_pMain->Zone1[i];
|
||||
}
|
||||
else if(ZoneNumber == ZONE_STONE2)
|
||||
{
|
||||
IsFull = g_pMain->IsBusy2[i];
|
||||
ZoneTime = g_pMain->Zone2[i];
|
||||
}
|
||||
else if(ZoneNumber == ZONE_STONE3)
|
||||
{
|
||||
IsFull = g_pMain->IsBusy3[i];
|
||||
ZoneTime = g_pMain->Zone3[i];
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
if(IsFull || ZoneTime > uint32(UNIXTIME))
|
||||
continue;
|
||||
|
||||
if(ZoneNumber == ZONE_STONE1)
|
||||
{
|
||||
g_pMain->Zone1[i] = uint32(UNIXTIME) + 1503;
|
||||
EventRoom = i;
|
||||
g_pMain->Zone1Family[i] = myrand(1,4);
|
||||
break;
|
||||
}else if(ZoneNumber == ZONE_STONE2)
|
||||
{
|
||||
g_pMain->Zone2[i] = uint32(UNIXTIME) + 1503;
|
||||
EventRoom = i;
|
||||
g_pMain->Zone2Family[i] = myrand(5,9);
|
||||
break;
|
||||
}else if(ZoneNumber == ZONE_STONE3)
|
||||
{
|
||||
g_pMain->Zone3[i] = uint32(UNIXTIME) + 1503;
|
||||
EventRoom = i;
|
||||
g_pMain->Zone3Family[i] = myrand(10,13);
|
||||
break;
|
||||
}else
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (EventRoom == 0)
|
||||
return;
|
||||
|
||||
|
||||
if(ZoneNumber == ZONE_STONE1)
|
||||
g_pMain->IsBusy1[EventRoom] = true;
|
||||
else if(ZoneNumber == ZONE_STONE2)
|
||||
g_pMain->IsBusy2[EventRoom] = true;
|
||||
else if(ZoneNumber == ZONE_STONE3)
|
||||
g_pMain->IsBusy3[EventRoom] = true;
|
||||
else
|
||||
return;
|
||||
|
||||
m_TimeMonsterStone = UNIXTIME + 1502;
|
||||
RobItem(ITEM_MONSTER_STONE,1);
|
||||
g_pMain->MonsterStoneSummon(EventRoom, ZoneNumber);
|
||||
ZoneChange(ZoneNumber,0.0f,0.0f,EventRoom);
|
||||
if (ZoneNumber == ZONE_STONE1)
|
||||
CheckWaiting(ZONE_STONE1, 1501);
|
||||
else if (ZoneNumber == ZONE_STONE2)
|
||||
CheckWaiting(ZONE_STONE2, 1501);
|
||||
else if (ZoneNumber == ZONE_STONE3)
|
||||
CheckWaiting(ZONE_STONE3, 1501);
|
||||
|
||||
printf("%s gonna go %d %d\n",GetName().c_str(),EventRoom,ZoneNumber);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::TempleOperations(uint8 bType)
|
||||
{
|
||||
uint16 nActiveEvent = (uint16)g_pMain->pTempleEvent.ActiveEvent;
|
||||
|
||||
uint8 bResult = 1;
|
||||
Packet result(WIZ_EVENT);
|
||||
Packet result2(WIZ_SELECT_MSG);
|
||||
|
||||
if(bType == TEMPLE_EVENT_JOIN && !isEventUser())
|
||||
{
|
||||
if (nActiveEvent == TEMPLE_EVENT_CHAOS)
|
||||
{
|
||||
if (CheckExistItem(CHAOS_MAP,1))
|
||||
bResult = 1;
|
||||
else if (m_sItemArray[RIGHTHAND].nNum == MATTOCK || m_sItemArray[RIGHTHAND].nNum == GOLDEN_MATTOCK || isMining())
|
||||
bResult = 4;
|
||||
else
|
||||
bResult = 3;
|
||||
}
|
||||
|
||||
else if (nActiveEvent == TEMPLE_EVENT_BORDER_DEFENCE_WAR)
|
||||
{
|
||||
if (GetLevel() < g_pMain->pTempleEvent.m_nBorderDefenseWarMINLEVEL)
|
||||
bResult = WarpListMinLevel;
|
||||
}
|
||||
|
||||
result << bType << bResult << nActiveEvent;
|
||||
Send(&result);
|
||||
|
||||
if (bResult == 1)
|
||||
{
|
||||
GetNation() == KARUS ? g_pMain->pTempleEvent.KarusUserCount++ :g_pMain->pTempleEvent.ElMoradUserCount++;
|
||||
g_pMain->pTempleEvent.AllUserCount = (g_pMain->pTempleEvent.KarusUserCount + g_pMain->pTempleEvent.ElMoradUserCount);
|
||||
g_pMain->AddEventUser(this);
|
||||
TempleOperations(TEMPLE_EVENT_COUNTER);
|
||||
}
|
||||
}
|
||||
else if (bType == TEMPLE_EVENT_DISBAND && isEventUser())
|
||||
{
|
||||
GetNation() == KARUS ? g_pMain->pTempleEvent.KarusUserCount-- : g_pMain->pTempleEvent.ElMoradUserCount--;
|
||||
g_pMain->pTempleEvent.AllUserCount = g_pMain->pTempleEvent.KarusUserCount + g_pMain->pTempleEvent.ElMoradUserCount;
|
||||
g_pMain->RemoveEventUser(this);
|
||||
result << bType << bResult << nActiveEvent;
|
||||
Send(&result);
|
||||
TempleOperations(TEMPLE_EVENT_COUNTER);
|
||||
}
|
||||
else if (bType == TEMPLE_EVENT_COUNTER)
|
||||
{
|
||||
result << bType << nActiveEvent;
|
||||
|
||||
if(nActiveEvent == TEMPLE_EVENT_CHAOS)
|
||||
result << g_pMain->pTempleEvent.AllUserCount;
|
||||
else if(nActiveEvent == TEMPLE_EVENT_BORDER_DEFENCE_WAR)
|
||||
result << g_pMain->pTempleEvent.KarusUserCount << g_pMain->pTempleEvent.ElMoradUserCount;
|
||||
else if(nActiveEvent == TEMPLE_EVENT_JURAD_MOUNTAIN)
|
||||
result2 << uint16(0x00) << uint8(0x07) << uint64(0x00) << uint32(0x06) << g_pMain->pTempleEvent.KarusUserCount << uint16(0x00) << g_pMain->pTempleEvent.ElMoradUserCount << uint16(0x00) << g_pMain->m_nTempleEventRemainSeconds << uint16(0x00);
|
||||
|
||||
if(nActiveEvent == TEMPLE_EVENT_JURAD_MOUNTAIN)
|
||||
g_pMain->Send_All(&result2,nullptr,Nation::ALL,0,true,0);
|
||||
else
|
||||
g_pMain->Send_All(&result,nullptr,Nation::ALL,0,true,0);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameServerDlg::AddEventUser(CUser *pUser)
|
||||
{
|
||||
if (pUser == nullptr)
|
||||
{
|
||||
TRACE("#### AddEventUser : pUser == nullptr ####\n");
|
||||
return;
|
||||
}
|
||||
|
||||
_TEMPLE_EVENT_USER * pEventUser = new _TEMPLE_EVENT_USER;
|
||||
|
||||
pEventUser->m_socketID = pUser->GetSocketID();
|
||||
pEventUser->m_bEventRoom = pUser->GetEventRoom();
|
||||
|
||||
if (!g_pMain->m_TempleEventUserArray.PutData(pEventUser->m_socketID, pEventUser))
|
||||
delete pEventUser;
|
||||
}
|
||||
|
||||
void CGameServerDlg::RemoveEventUser(CUser *pUser)
|
||||
{
|
||||
if (pUser == nullptr)
|
||||
{
|
||||
TRACE("#### RemoveEventUser : pUser == nullptr ####\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_pMain->m_TempleEventUserArray.GetData(pUser->GetSocketID()) != nullptr)
|
||||
g_pMain->m_TempleEventUserArray.DeleteData(pUser->GetSocketID());
|
||||
|
||||
}
|
||||
|
||||
void CGameServerDlg::UpdateEventUser(CUser *pUser, uint16 nEventRoom)
|
||||
{
|
||||
if (pUser == nullptr)
|
||||
{
|
||||
TRACE("#### UpdateEventUser : pUser == nullptr ####\n");
|
||||
return;
|
||||
}
|
||||
|
||||
_TEMPLE_EVENT_USER * pEventUser = g_pMain->m_TempleEventUserArray.GetData(pUser->GetSocketID());
|
||||
|
||||
if (pEventUser)
|
||||
{
|
||||
|
||||
Packet result2(AG_USER_EVENTROOM);
|
||||
result2 << pUser->GetID() << uint16(nEventRoom);
|
||||
g_pMain->Send_AIServer(&result2);
|
||||
|
||||
pEventUser->m_bEventRoom = nEventRoom;
|
||||
pUser->m_bEventRoom = nEventRoom;
|
||||
pUser->SetUserEventRoom(nEventRoom);
|
||||
pUser->SetUnitEventRoom(nEventRoom);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CGameServerDlg::SetEventUser(CUser *pUser)
|
||||
{
|
||||
if (pUser == nullptr)
|
||||
{
|
||||
TRACE("#### SetEventUser : pUser == nullptr ####\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 nMaxUserCount = 0;
|
||||
|
||||
switch (g_pMain->pTempleEvent.ActiveEvent)
|
||||
{
|
||||
case TEMPLE_EVENT_BORDER_DEFENCE_WAR:
|
||||
nMaxUserCount = 8;
|
||||
break;
|
||||
case TEMPLE_EVENT_CHAOS:
|
||||
nMaxUserCount = 18;
|
||||
break;
|
||||
case TEMPLE_EVENT_JURAD_MOUNTAIN:
|
||||
nMaxUserCount = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_pMain->TempleEventGetRoomUsers(g_pMain->pTempleEvent.LastEventRoom,pUser->GetNation()) >= nMaxUserCount)
|
||||
g_pMain->pTempleEvent.LastEventRoom++;
|
||||
|
||||
if (g_pMain->TempleEventGetRoomUsers(g_pMain->pTempleEvent.LastEventRoom,pUser->GetNation()) <= nMaxUserCount)
|
||||
g_pMain->UpdateEventUser(pUser, g_pMain->pTempleEvent.LastEventRoom);
|
||||
}
|
||||
|
||||
bool CUser::isEventUser()
|
||||
{
|
||||
_TEMPLE_EVENT_USER * pEventUser = g_pMain->m_TempleEventUserArray.GetData(GetSocketID());
|
||||
|
||||
if (pEventUser != nullptr)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8 CUser::GetMonsterChallengeTime()
|
||||
{
|
||||
if (g_pMain->m_bForgettenTempleIsActive
|
||||
&& g_pMain->m_nForgettenTempleLevelMin != 0
|
||||
&& g_pMain->m_nForgettenTempleLevelMax != 0
|
||||
&& GetLevel() >= g_pMain->m_nForgettenTempleLevelMin
|
||||
&& GetLevel() <= g_pMain->m_nForgettenTempleLevelMax
|
||||
&& !g_pMain->m_bForgettenTempleSummonMonsters)
|
||||
return g_pMain->m_nForgettenTempleChallengeTime;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 CUser::GetEventZoneTime()
|
||||
{
|
||||
if (g_pMain->m_bEventZoneIsActive
|
||||
&& g_pMain->m_nEventZoneLevelMin != 0
|
||||
&& g_pMain->m_nEventZoneLevelMax != 0
|
||||
&& GetLevel() >= g_pMain->m_nEventZoneLevelMin
|
||||
&& GetLevel() <= g_pMain->m_nEventZoneLevelMax)
|
||||
return g_pMain->m_nEventZoneTime;
|
||||
|
||||
return 0;
|
||||
}
|
||||
void CUser::HandleCapture(Packet & pkt)
|
||||
{
|
||||
if ((UNIXTIME - m_tBorderCapure) < 10)
|
||||
return;
|
||||
|
||||
if (GetZoneID() != ZONE_BORDER_DEFENSE_WAR || g_pMain->pTempleEvent.m_sMiniTimerNation[GetEventRoom()] == GetNation())
|
||||
return;
|
||||
|
||||
uint16 KO = 360;
|
||||
|
||||
g_pMain->pTempleEvent.m_sBdwMiniTimer[GetEventRoom()] = KO;
|
||||
g_pMain->pTempleEvent.m_sMiniTimerNation[GetEventRoom()] = GetNation();
|
||||
|
||||
GetNation() == KARUS ? g_pMain->pTempleEvent.ElmoDeathCount[GetEventRoom()] = g_pMain->pTempleEvent.ElmoDeathCount[GetEventRoom()] + 2 : g_pMain->pTempleEvent.KarusDeathCount[GetEventRoom()] = g_pMain->pTempleEvent.KarusDeathCount[GetEventRoom()] + 2;
|
||||
|
||||
Packet result1(WIZ_CAPTURE, uint8(0x05));
|
||||
result1 << GetNation() << GetName().c_str();
|
||||
Packet result(WIZ_CAPTURE, uint8(0x04));
|
||||
result << GetNation() << uint16(KO);
|
||||
|
||||
g_pMain->Send_Zone(&result1, GetZoneID(), nullptr, Nation::ALL,GetEventRoom());
|
||||
g_pMain->Send_Zone(&result, GetZoneID(), nullptr, Nation::ALL,GetEventRoom());
|
||||
|
||||
|
||||
result.Initialize(WIZ_EVENT);
|
||||
result << uint8(TEMPLE_EVENT_BORDER_COUNTER);
|
||||
m_iLoyaltyDaily += 2 ;
|
||||
UpdatePlayerRank();
|
||||
result << g_pMain->pTempleEvent.ElmoDeathCount[GetEventRoom()] << uint16(0x00) << g_pMain->pTempleEvent.KarusDeathCount[GetEventRoom()] << uint16(0x00);
|
||||
g_pMain->Send_Zone(&result, GetZoneID(), nullptr, Nation::ALL,GetEventRoom());
|
||||
|
||||
}
|
||||
uint8 CUser::GetMonsterChallengeUserCount() { return g_pMain->m_nForgettenTempleUsers.size(); }
|
||||
uint8 CUser::GetEventZoneUserCount() { return g_pMain->m_nEventZoneUsers.size(); }
|
||||
@@ -0,0 +1,120 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#define MAX_FRIEND_COUNT 24
|
||||
|
||||
// From the client
|
||||
void CUser::FriendProcess(Packet & pkt)
|
||||
{
|
||||
uint8 opcode = pkt.read<uint8>();
|
||||
switch (opcode)
|
||||
{
|
||||
case FRIEND_REQUEST:
|
||||
FriendRequest();
|
||||
break;
|
||||
case FRIEND_REPORT:
|
||||
FriendReport(pkt);
|
||||
break;
|
||||
case FRIEND_ADD:
|
||||
case FRIEND_REMOVE:
|
||||
FriendModify(pkt, opcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Request friend list.
|
||||
void CUser::FriendRequest()
|
||||
{
|
||||
Packet result(WIZ_FRIEND_PROCESS, uint8(FRIEND_REQUEST));
|
||||
g_pMain->AddDatabaseRequest(result, this);
|
||||
}
|
||||
|
||||
// Add or remove a friend from your list.
|
||||
void CUser::FriendModify(Packet & pkt, uint8 opcode)
|
||||
{
|
||||
std::string strUserID;
|
||||
CUser *pUser;
|
||||
CBot *pBot;
|
||||
pkt >> strUserID;
|
||||
|
||||
if (strUserID.empty() || strUserID.size() > MAX_ID_SIZE
|
||||
|| (opcode == FRIEND_ADD && ((pUser = g_pMain->GetUserPtr(strUserID, TYPE_CHARACTER)) == nullptr && (pBot = g_pMain->GetBotPtr(strUserID, TYPE_CHARACTER)) == nullptr)))
|
||||
return;
|
||||
|
||||
Packet result(WIZ_FRIEND_PROCESS, opcode);
|
||||
if (opcode == FRIEND_ADD && pUser != nullptr)
|
||||
result << pUser->GetSocketID();
|
||||
else if(pUser == nullptr && opcode == FRIEND_ADD)
|
||||
result << pBot->GetID();
|
||||
|
||||
|
||||
result.SByte();
|
||||
result << strUserID;
|
||||
g_pMain->AddDatabaseRequest(result, this);
|
||||
}
|
||||
|
||||
// Refresh the status of your friends.
|
||||
void CUser::FriendReport(Packet & pkt)
|
||||
{
|
||||
Packet result(WIZ_FRIEND_PROCESS, uint8(FRIEND_REPORT));
|
||||
uint16 usercount = pkt.read<uint16>();
|
||||
|
||||
if (usercount > MAX_FRIEND_COUNT)
|
||||
return;
|
||||
|
||||
result << usercount;
|
||||
for (int i = 0; i < usercount; i++)
|
||||
{
|
||||
std::string strUserID;
|
||||
int16 sid;
|
||||
|
||||
pkt >> strUserID;
|
||||
if (strUserID.empty() || strUserID.size() > MAX_ID_SIZE)
|
||||
return; // malformed packet, just ignore it.
|
||||
|
||||
uint8 status = GetFriendStatus(strUserID, sid);
|
||||
result << strUserID << sid << status;
|
||||
}
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
// Retrieves the status (and socket ID) of a character.
|
||||
uint8 CUser::GetFriendStatus(std::string & charName, int16 & sid)
|
||||
{
|
||||
CUser *pUser;
|
||||
CBot *pBot;
|
||||
if (charName.empty()
|
||||
|| ((pUser = g_pMain->GetUserPtr(charName, TYPE_CHARACTER)) == nullptr && (pBot = g_pMain->GetBotPtr(charName, TYPE_CHARACTER)) == nullptr))
|
||||
{
|
||||
sid = -1;
|
||||
return 0; // user not found
|
||||
}
|
||||
|
||||
sid = pUser != nullptr ? pUser->GetSocketID() : pBot->GetID();
|
||||
if(pUser != nullptr)
|
||||
{
|
||||
if (pUser->isInParty()) // user in party
|
||||
return 3;
|
||||
}
|
||||
return 1; // user not in party
|
||||
}
|
||||
|
||||
void CUser::RecvFriendModify(Packet & pkt, uint8 opcode)
|
||||
{
|
||||
Packet result(WIZ_FRIEND_PROCESS);
|
||||
std::string strUserID;
|
||||
int16 sid = -1;
|
||||
uint8 bResult = 0;
|
||||
|
||||
if (opcode == FRIEND_ADD)
|
||||
pkt >> sid;
|
||||
|
||||
pkt >> bResult;
|
||||
|
||||
pkt.SByte();
|
||||
pkt >> strUserID;
|
||||
|
||||
uint8 status = GetFriendStatus(strUserID, sid);
|
||||
result << opcode << bResult << strUserID << sid << status;
|
||||
Send(&result);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
#include "stdafx.h"
|
||||
#include "GameEvent.h"
|
||||
#include "User.h"
|
||||
|
||||
CGameEvent::CGameEvent() : m_bType(0)
|
||||
{
|
||||
memset(&m_iCond, 0, sizeof(m_iCond));
|
||||
memset(&m_iExec, 0, sizeof(m_iExec));
|
||||
}
|
||||
|
||||
void CGameEvent::RunEvent(CUser *pUser)
|
||||
{
|
||||
switch (m_bType)
|
||||
{
|
||||
case ZONE_CHANGE:
|
||||
if (pUser->m_bWarp)
|
||||
break;
|
||||
pUser->ZoneChange( m_iExec[0], (float)m_iExec[1], (float)m_iExec[2] );
|
||||
break;
|
||||
case ZONE_TRAP_DEAD:
|
||||
// TRACE("&&& User - zone trap dead ,, name=%s\n", pUser->GetName().c_str());
|
||||
// pUser->Dead();
|
||||
break;
|
||||
case ZONE_TRAP_AREA:
|
||||
pUser->TrapProcess();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
enum GameEventType
|
||||
{
|
||||
ZONE_CHANGE = 1,
|
||||
ZONE_TRAP_DEAD = 2,
|
||||
ZONE_TRAP_AREA = 3
|
||||
};
|
||||
|
||||
class CUser;
|
||||
class CGameEvent
|
||||
{
|
||||
public:
|
||||
CGameEvent();
|
||||
void RunEvent(CUser* pUser = nullptr);
|
||||
|
||||
uint16 m_sIndex;
|
||||
uint8 m_bType;
|
||||
|
||||
int32 m_iCond[5], m_iExec[5];
|
||||
};
|
||||
@@ -0,0 +1,112 @@
|
||||
[AI_SERVER]
|
||||
IP=127.0.0.1
|
||||
PORT=10020
|
||||
|
||||
[BATTLE]
|
||||
DAYS=1,6
|
||||
START_TIME0=7
|
||||
START_TIME1=14
|
||||
START_TIME2=21
|
||||
WAR_ZONE0=61
|
||||
WAR_ZONE1=62
|
||||
WAR_ZONE2=63
|
||||
|
||||
[BDW]
|
||||
START_TIME1=0
|
||||
START_TIME2=0
|
||||
START_TIME3=0
|
||||
START_TIME4=0
|
||||
START_TIME5=0
|
||||
|
||||
[BIFROST]
|
||||
START_TIME1=0
|
||||
START_TIME2=0
|
||||
START_TIME3=0
|
||||
|
||||
[BONUS]
|
||||
EXP=0
|
||||
MONEY=0
|
||||
NP=0
|
||||
|
||||
[CASTLE]
|
||||
NATION=1
|
||||
|
||||
[CHAOS]
|
||||
START_TIME1=0
|
||||
START_TIME2=0
|
||||
START_TIME3=0
|
||||
|
||||
[FISHING]
|
||||
FISHING=399127000
|
||||
FISHING_1=399128000
|
||||
FISHING_2=399129000
|
||||
GOLDEN_FISHING=399127000
|
||||
GOLDEN_FISHING_1=399128000
|
||||
GOLDEN_FISHING_2=399129000
|
||||
|
||||
[JURAID]
|
||||
START_TIME1=0
|
||||
START_TIME2=0
|
||||
START_TIME3=0
|
||||
|
||||
[MINING]
|
||||
MYSTERIOUS_GOLD_ORE=399210000
|
||||
MYSTERIOUS_GOLD_ORE_1=399210000
|
||||
MYSTERIOUS_GOLD_ORE_2=399210000
|
||||
MYSTERIOUS_GOLD_ORE_3=399210000
|
||||
MYSTERIOUS_GOLD_ORE_4=399210000
|
||||
MYSTERIOUS_ORE=399210000
|
||||
MYSTERIOUS_ORE_1=399210000
|
||||
MYSTERIOUS_ORE_2=399210000
|
||||
MYSTERIOUS_ORE_3=399210000
|
||||
MYSTERIOUS_ORE_4=399210000
|
||||
SLING=389043000
|
||||
|
||||
[NATIONAL_POINTS]
|
||||
ARDREAM_SOURCE=32
|
||||
ARDREAM_TARGET=-25
|
||||
MINI_PVP_SOURCE=0
|
||||
MINI_PVP_TARGET=0
|
||||
OTHER_ZONE_SOURCE=64
|
||||
OTHER_ZONE_TARGET=-50
|
||||
RONARK_LAND_BASE_SOURCE=64
|
||||
RONARK_LAND_BASE_TARGET=-50
|
||||
RONARK_LAND_SOURCE=64
|
||||
RONARK_LAND_TARGET=-50
|
||||
|
||||
[ODBC]
|
||||
ACCOUNT_DSN=KO_MAIN
|
||||
ACCOUNT_MARS=0
|
||||
ACCOUNT_PWD=password
|
||||
ACCOUNT_UID=username
|
||||
GAME_DSN=KO_GAME
|
||||
GAME_MARS=0
|
||||
GAME_PWD=password
|
||||
GAME_UID=username
|
||||
|
||||
[SETTINGS]
|
||||
GAME_MASTER_R_HIT_DAMAGE=30000
|
||||
GRADE1=720000
|
||||
GRADE2=340000
|
||||
GRADE3=50000
|
||||
GRADE4=25000
|
||||
PLAYER_RANKINGS_KNIGHT_CASH_REWARD=0
|
||||
PLAYER_RANKINGS_LOYALTY_REWARD=0
|
||||
PLAYER_RANKINGS_RESET_TIME=12
|
||||
PLAYER_RANKINGS_REWARD_ZONES=71,72,73
|
||||
PORT=15001
|
||||
|
||||
[TIMER]
|
||||
WEATHER=1
|
||||
|
||||
[UPGRADE_RATES]
|
||||
KARIVDIS_RATE=100
|
||||
TRINA_RATE=100
|
||||
|
||||
[ZONE_INFO]
|
||||
MY_INFO=1
|
||||
SERVER_00=1
|
||||
SERVER_COUNT=1
|
||||
SERVER_IP_00=127.0.0.1
|
||||
SERVER_NUM=0
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,828 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef GAMESERVER
|
||||
|
||||
#include "resource.h"
|
||||
#include "LuaEngine.h"
|
||||
|
||||
#include "Define.h"
|
||||
#include "ChatHandler.h"
|
||||
|
||||
class C3DMap;
|
||||
class CUser;
|
||||
class CBot;
|
||||
|
||||
|
||||
#include "LoadServerData.h"
|
||||
|
||||
#include "User.h"
|
||||
#include "Bot.h"
|
||||
#include "Pet.h"
|
||||
#include "AISocket.h"
|
||||
#include "../shared/ClientSocketMgr.h"
|
||||
|
||||
typedef std::map<std::string, CUser *> NameMap;
|
||||
typedef std::map<std::string, CBot *> BotNameMap;
|
||||
typedef std::map<uint16, uint16> ForgettenTempleMonsterList;
|
||||
|
||||
class CGameServerDlg
|
||||
{
|
||||
public:
|
||||
CGameServerDlg();
|
||||
bool Startup();
|
||||
|
||||
void GetTimeFromIni();
|
||||
bool WordGuardSystem(std::string Word, uint8 WordStr);
|
||||
uint8 GetTariffByZone(int zoneid);
|
||||
bool LoadItemTable();
|
||||
bool LoadItemDuper();
|
||||
bool LoadIlegalItems();
|
||||
bool LoadSetItemTable();
|
||||
bool LoadAchieveMonsterTable();
|
||||
bool LoadAchieveComTable();
|
||||
bool LoadAchieveMainTable();
|
||||
bool LoadAchieveNormalTable();
|
||||
bool LoadAchieveWarTable();
|
||||
bool LoadAchieveTitleTable();
|
||||
bool LoadItemMiningTable();
|
||||
bool LoadItemExchangeTable();
|
||||
bool LoadItemExchangeExpTable();
|
||||
bool LoadItemMixTable();
|
||||
bool LoadItemUpgradeTable();
|
||||
bool LoadItemOpTable();
|
||||
bool LoadServerResourceTable();
|
||||
bool LoadQuestHelperTable();
|
||||
bool LoadQuestMonsterTable();
|
||||
bool LoadMagicTable();
|
||||
bool LoadMagicType1();
|
||||
bool LoadMagicType2();
|
||||
bool LoadMagicType3();
|
||||
bool LoadMagicType4();
|
||||
bool LoadMagicType5();
|
||||
bool LoadMagicType6();
|
||||
bool LoadMagicType7();
|
||||
bool LoadMagicType8();
|
||||
bool LoadMagicType9();
|
||||
bool LoadItemCrashTable();
|
||||
bool LoadRentalList();
|
||||
bool LoadCoefficientTable();
|
||||
bool LoadLevelUpTable();
|
||||
bool LoadPetLevelUpTable();
|
||||
bool LoadAllKnights(bool bIsslient = false);
|
||||
bool ReloadAllKnights(bool bIsslient = false);
|
||||
bool LoadAllKnightsUserData(bool bIsslient = false);
|
||||
bool LoadKnightsAllianceTable(bool bIsslient = false);
|
||||
bool LoadKnightsSiegeWarsTable();
|
||||
bool LoadUserRankings();
|
||||
void CleanupUserRankings();
|
||||
bool LoadKnightsCapeTable();
|
||||
bool LoadKnightsRankTable(bool bWarTime = false, bool bIsslient = false);
|
||||
bool LoadStartPositionTable();
|
||||
bool LoadStartPositionRandomTable();
|
||||
bool LoadBattleTable();
|
||||
bool LoadKingSystem();
|
||||
bool LoadMonsterSummonListTable();
|
||||
bool LoadMonsterSummonListZoneTable();
|
||||
bool LoadMonsterRespawnListTable();
|
||||
bool LoadMonsterRespawnListInformationTable();
|
||||
bool LoadMonsterRespawnListRandomTable();
|
||||
bool LoadPremiumItemTable();
|
||||
bool LoadPremiumItemExpTable();
|
||||
bool LoadPetTable();
|
||||
bool LoadBotTable();
|
||||
bool LoadCypherRingTable();
|
||||
bool LoadUserDailyOpTable();
|
||||
bool LoadEventTriggerTable();
|
||||
bool LoadMonsterChallengeTable();
|
||||
bool LoadEventTimesTable();
|
||||
bool LoadMonsterChallengeSummonListTable();
|
||||
bool LoadUserItemTable();
|
||||
bool LoadObjectPosTable();
|
||||
|
||||
bool MapFileLoad();
|
||||
bool LoadNoticeData();
|
||||
bool LoadNoticeUpData();
|
||||
|
||||
void AIServerConnect();
|
||||
|
||||
static uint32 THREADCALL Timer_CheckGameEvents(void * lpParam);
|
||||
static uint32 THREADCALL Timer_BifrostTime(void * lpParam);
|
||||
static uint32 THREADCALL Timer_UpdateGameTime(void * lpParam);
|
||||
static uint32 THREADCALL Timer_UpdateSessions(void * lpParam);
|
||||
static uint32 THREADCALL Timer_UpdateConcurrent(void * lpParam);
|
||||
|
||||
void ReqUpdateConcurrent();
|
||||
|
||||
void SendFlyingSantaOrAngel();
|
||||
void Send_CommandChat(Packet *pkt, int nation , CUser* pExceptUser = nullptr);
|
||||
void SendItemZoneUsers(uint8 ZoneID, uint32 nItemID, uint16 sCount = 1, uint32 Time = 0);
|
||||
void KickOutZoneUsers(uint8 ZoneID, uint8 TargetZoneID = 0, uint8 bNation = Nation::ALL);
|
||||
void SendItemEventRoom(uint16 nEventRoom,uint32 nItemID, uint16 sCount = 1);
|
||||
uint64 GenerateItemSerial();
|
||||
int KickOutAllUsers();
|
||||
void CheckAliveUser();
|
||||
int GetKnightsGrade(uint32 nPoints);
|
||||
void WritePacketLog();
|
||||
uint16 GetKnightsAllMembers(uint16 sClanID, Packet & result, uint16 & pktSize, bool bClanLeader);
|
||||
void GetUserRank(CUser *pUser);
|
||||
void Announcement(uint16 type, int nation= Nation::ALL, int chat_type=8, CUser* pExceptUser = nullptr, CNpc *pExpectNpc = nullptr);
|
||||
void SnowBanishLosers();
|
||||
void SnowBattleZoneClose();
|
||||
void SnowBattleZoneOpenTimer();
|
||||
void ResetBattleZone();
|
||||
void BanishLosers();
|
||||
void BattleZoneVictoryCheck();
|
||||
void BattleZoneOpenTimer();
|
||||
void BattleZoneOpen(int nType, uint8 bZone = 0);
|
||||
void CastleSiegeWarZoneOpen(int nType, uint8 bZone = 0);
|
||||
void BattleZoneClose();
|
||||
void BattleZoneResult(uint8 nation);
|
||||
void BattleWinnerResult(BattleWinnerTypes winnertype);
|
||||
void AliveUserCheck();
|
||||
void TerminationFinish();
|
||||
void Send_PartyMember(int party, Packet *result);
|
||||
void Send_KnightsMember(int index, Packet *pkt);
|
||||
void Send_KnightsAlliance(uint16 sAllianceID, Packet *pkt);
|
||||
void SetGameTime();
|
||||
void ResetPlayerRankings(uint8 ZoneID = 0);
|
||||
void UpdateWeather();
|
||||
void UpdateGameTime();
|
||||
void ResetLoyaltyMonthly();
|
||||
void SendAllUserInfo();
|
||||
void DeleteAllNpcList(int flag = 0);
|
||||
CNpc* FindNpcInZone(uint16 sPid, uint8 byZone);
|
||||
CNpc* UpdateNpc();
|
||||
void ForgettenTempleEventTimer();
|
||||
void AutoNoticeEventTimer();
|
||||
uint8 GetMonsterChallengeTime();
|
||||
void EventZoneTimer();
|
||||
|
||||
int32 m_byEventTime;
|
||||
int32 m_byEventRemainingTime;
|
||||
int32 m_sEventTimeDelay;
|
||||
int32 m_byEventOpenedTime;
|
||||
void ArdreamEventOpen();
|
||||
bool OpenArdream;
|
||||
void CZEventOpen();
|
||||
bool OpenCZ;
|
||||
void ArdreamEventZoneClose();
|
||||
void CZEventZoneClose();
|
||||
void CheckEventTime();
|
||||
|
||||
|
||||
time_t m_lastBlessTime;
|
||||
time_t m_lastBorderTime;
|
||||
uint8 GetEventZoneTime();
|
||||
void TempleEventTimer();
|
||||
void TempleEventStart();
|
||||
void JuraidTempleEventStart();
|
||||
void TempleEventTeleportUsers();
|
||||
uint8 TempleEventGetRoomUsers(uint16 nEventRoom = 0,uint8 nNation = 0);
|
||||
void MonsterStoneSummon(uint16 EventRoom, uint8 ZoneID);
|
||||
void TempleEventSummon();
|
||||
void TempleEventFinish(uint16 m_sEventRoom = 0, uint8 m_bNation = 0);
|
||||
void TempleEventGetActiveEventTime(CUser *pUser);
|
||||
void TempleEventSendActiveEventTime(CUser *pUser);
|
||||
void TempleEventKickOutUser(CUser *pUser);
|
||||
void TempleEventReset();
|
||||
void AddEventUser(CUser * pUser);
|
||||
void Send_Noah_Knights(Packet *pkt);
|
||||
void LunarGoldShells(CUser *pUser = nullptr);
|
||||
void NereidsMonumentEvent(uint8 TrapNumber = 0, uint8 bNation = 0, CUser * pUser = nullptr);
|
||||
void DeleteLunarGoldShells();
|
||||
void RemoveEventUser(CUser * pUser);
|
||||
void UpdateEventUser(CUser * pUser, uint16 nEventRoom = 0);
|
||||
void SetEventUser(CUser *pUser);
|
||||
std::string GetBattleAndNationMonumentName(int16 TrapNumber = -1, uint8 ZoneID = 0);
|
||||
void CheckNationMonumentRewards();
|
||||
bool IsBusy1[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint32 Zone1[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint32 Zone2[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint32 Zone3[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint8 Zone1Family[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint8 Zone2Family[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint8 Zone3Family[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint16 Zone1Boss[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint16 Zone2Boss[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint16 Zone3Boss[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
bool IsBusy2[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
bool IsBusy3[MAX_MONSTER_STONE_EVENT_ROOM];
|
||||
uint32 KCmiktari,KCmiktari2;
|
||||
uint32 LastPetID;
|
||||
uint32 LastRingID;
|
||||
bool KCaktifmi, onbesinde,RoyalG1,KCaktifmi2;
|
||||
bool AutoNovice,AutoMaster,AutoSkills;
|
||||
Packet BoardCache[2];
|
||||
void ReloadKnightAndUserRanks();
|
||||
void SetPlayerRankingRewards(uint16 ZoneID);
|
||||
|
||||
bool OfflineMerchanting;
|
||||
|
||||
uint8 Dakika1,Dakika2;
|
||||
uint8 HediyeKC,HediyeKC2;
|
||||
|
||||
bool CastleSiegeWarAttack(CUser *pUser, CUser *pTargetUser);
|
||||
void UpdateSiege(int16 m_sCastleIndex, int16 m_sMasterKnights, int16 m_bySiegeType, int16 m_byWarDay, int16 m_byWarTime, int16 m_byWarMinute);
|
||||
void UpdateSiegeTax(uint8 Zone, int16 ZoneTarrif);
|
||||
|
||||
bool IsDuplicateItem(uint32 nItemID, uint64 nItemSerial);
|
||||
void AddUserItem(uint32 nItemID, uint64 nItemSerial);
|
||||
void AddDatabaseRequest(Packet & pkt, CUser *pUser = nullptr);
|
||||
// TerminitionTime
|
||||
|
||||
void TerminitionTime(uint8 sNewZone,uint16 Time);
|
||||
|
||||
// Get info for NPCs in regions around user (WIZ_REQ_NPCIN)
|
||||
void NpcInOutForMe(CUser* pSendUser);
|
||||
|
||||
// Get info for NPCs in region
|
||||
void GetRegionNpcIn(C3DMap* pMap, uint16 region_x, uint16 region_z, Packet & pkt, uint16 & t_count, uint16 nEventRoom, CUser* pSendUser);
|
||||
|
||||
// Get list of NPC IDs in region
|
||||
void GetRegionNpcList(C3DMap* pMap, uint16 region_x, uint16 region_z, Packet & pkt, uint16 & t_count, uint16 nEventRoom = 0);
|
||||
|
||||
// Get list of NPCs for regions around user (WIZ_NPC_REGION)
|
||||
void RegionNpcInfoForMe(CUser* pSendUser);
|
||||
|
||||
// Get raw list of all units in regions surrounding pOwner.
|
||||
void GetUnitListFromSurroundingRegions(Unit * pOwner, std::vector<uint16> * pList);
|
||||
|
||||
// Get info for users in regions around user (WIZ_REQ_USERIN)
|
||||
void UserInOutForMe(CUser* pSendUser);
|
||||
|
||||
// Get list of user IDs in region
|
||||
void GetRegionUserList(C3DMap* pMap, uint16 region_x, uint16 region_z, Packet & pkt, uint16 & t_count, uint16 nEventRoom = 0);
|
||||
|
||||
// Get list of users for regions around user (WIZ_REGIONCHANGE)
|
||||
void RegionUserInOutForMe(CUser* pSendUser);
|
||||
|
||||
// Get info for merchants in regions around user
|
||||
void MerchantUserInOutForMe(CUser* pSendUser);
|
||||
|
||||
// Get war status
|
||||
INLINE bool isWarOpen() { return m_byBattleOpen != NO_BATTLE;}
|
||||
|
||||
// Get list of merchants in region
|
||||
void GetRegionMerchantUserIn(C3DMap* pMap, uint16 region_x, uint16 region_z, Packet & pkt, uint16 & t_count, uint16 nEventRoom = 0);
|
||||
|
||||
void SendHelpDescription(CUser *pUser, std::string sHelpMessage);
|
||||
|
||||
INLINE bool isPermanentMessageSet() { return m_bPermanentChatMode; }
|
||||
void SetPermanentMessage(const char * format, ...);
|
||||
|
||||
void HandleConsoleCommand(const char * msg);
|
||||
|
||||
template <ChatType chatType>
|
||||
INLINE void SendChat(const char * msg, uint8 byNation = Nation::ALL, bool bFormatNotice = false)
|
||||
{
|
||||
Packet result;
|
||||
std::string buffer;
|
||||
|
||||
if (bFormatNotice)
|
||||
GetServerResource(IDP_ANNOUNCEMENT, &buffer, msg);
|
||||
else
|
||||
buffer = msg;
|
||||
|
||||
ChatPacket::Construct(&result, (uint8) chatType, &buffer);
|
||||
Send_All(&result, nullptr, byNation);
|
||||
}
|
||||
|
||||
template <ChatType chatType>
|
||||
INLINE void SendChatToZone(const char * msg, uint8 ZoneID, uint8 byNation = Nation::ALL, bool bFormatNotice = false)
|
||||
{
|
||||
Packet result;
|
||||
std::string buffer;
|
||||
|
||||
if (bFormatNotice)
|
||||
GetServerResource(IDP_ANNOUNCEMENT, &buffer, msg);
|
||||
else
|
||||
buffer = msg;
|
||||
|
||||
ChatPacket::Construct(&result, (uint8) chatType, &buffer);
|
||||
Send_Zone(&result, ZoneID, nullptr, byNation);
|
||||
}
|
||||
|
||||
template <ChatType chatType>
|
||||
INLINE void SendFormattedChat(const char * msg, uint8 byNation = Nation::ALL, bool bFormatNotice = false, va_list args = nullptr)
|
||||
{
|
||||
char buffer[512];
|
||||
vsnprintf(buffer, sizeof(buffer), msg, args);
|
||||
SendChat<chatType>(buffer, byNation, bFormatNotice);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
template <ChatType chatType>
|
||||
void SendFormattedChat(const char * msg, uint8 byNation = Nation::ALL, bool bFormatNotice = false, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, byNation);
|
||||
SendFormattedChat<chatType>(msg, byNation, bFormatNotice, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* The following are simply wrappers for more readable SendChat() calls */
|
||||
|
||||
INLINE void SendNotice(const char *msg, uint8 byNation = Nation::ALL)
|
||||
{
|
||||
SendChat<PUBLIC_CHAT>(msg, byNation, true);
|
||||
}
|
||||
|
||||
template <ChatType chatType>
|
||||
INLINE void SendNotice(const char *msg, uint8 ZoneID, uint8 byNation = Nation::ALL, bool bFormatNotice = false)
|
||||
{
|
||||
SendChatToZone<chatType>(msg, ZoneID, byNation, bFormatNotice);
|
||||
}
|
||||
|
||||
void SendFormattedNotice(const char *msg, uint8 byNation = Nation::ALL, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, byNation);
|
||||
SendFormattedChat<PUBLIC_CHAT>(msg, byNation, true, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
INLINE void SendAnnouncement(const char *msg, uint8 byNation = Nation::ALL)
|
||||
{
|
||||
SendChat<WAR_SYSTEM_CHAT>(msg, byNation, true);
|
||||
}
|
||||
|
||||
void SendFormattedAnnouncement(const char *msg, uint8 byNation = Nation::ALL, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, byNation);
|
||||
SendFormattedChat<WAR_SYSTEM_CHAT>(msg, byNation, true, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void SendFormattedResource(uint32 nResourceID, uint8 byNation = Nation::ALL, bool bIsNotice = true, ...);
|
||||
|
||||
void Send_Region(Packet *pkt, C3DMap *pMap, int x, int z, CUser* pExceptUser = nullptr, uint16 nEventRoom = 0);
|
||||
void Send_UnitRegion(Packet *pkt, C3DMap *pMap, int x, int z, CUser* pExceptUser = nullptr, uint16 nEventRoom = 0);
|
||||
void Send_OldRegions(Packet *pkt, int old_x, int old_z, C3DMap *pMap, int x, int z, CUser* pExceptUser = nullptr, uint16 nEventRoom = 0);
|
||||
void Send_NewRegions(Packet *pkt, int new_x, int new_z, C3DMap *pMap, int x, int z, CUser* pExceptUser = nullptr, uint16 nEventRoom = 0);
|
||||
|
||||
void Send_NearRegion(Packet *pkt, C3DMap *pMap, int region_x, int region_z, float curx, float curz, CUser* pExceptUser=nullptr, uint16 nEventRoom = 0);
|
||||
void Send_FilterUnitRegion(Packet *pkt, C3DMap *pMap, int x, int z, float ref_x, float ref_z, CUser* pExceptUser=nullptr, uint16 nEventRoom = 0);
|
||||
|
||||
void Send_Zone_Matched_Class(Packet *pkt, uint8 bZoneID, CUser* pExceptUser, uint8 nation, uint8 seekingPartyOptions, uint16 nEventRoom = 0);
|
||||
void Send_Zone(Packet *pkt, uint8 bZoneID, CUser* pExceptUser = nullptr, uint8 nation = Nation::ALL, uint16 nEventRoom = 0, float fRange = 0.0f);
|
||||
|
||||
void Send_All(Packet *pkt, CUser* pExceptUser = nullptr, uint8 nation = Nation::ALL, uint8 ZoneID = 0, bool isSendEventUsers = false, uint16 nEventRoom = 0);
|
||||
void Send_AIServer(Packet *pkt);
|
||||
|
||||
void GetServerResource(int nResourceID, std::string * result, ...);
|
||||
_START_POSITION *GetStartPosition(int nZoneID);
|
||||
|
||||
int64 GetExpByLevel(int nLevel);
|
||||
int64 GetPetExpByLevel(int nLevel);
|
||||
C3DMap * GetZoneByID(int zoneID);
|
||||
|
||||
CBot * GetBotPtr(std::string findName, NameType type);
|
||||
CUser * GetUserPtr(std::string findName, NameType type);
|
||||
CUser * GetUserPtr(uint16 sUserId);
|
||||
CNpc * GetNpcPtr(uint16 sNpcId);
|
||||
|
||||
_ACHIEVE_MONSTER * GetAchieveMonsterPointer(uint32 ID);
|
||||
_ACHIEVE_WAR * GetAchieveWarPointer(uint32 ID);
|
||||
_ACHIEVE_TITLE * GetAchieveTitlePointer(uint32 ID);
|
||||
_ACHIEVE_COM * GetAchieveComPointer(uint32 ID);
|
||||
_ACHIEVE_NORMAL * GetAchieveNormalPointer(uint32 ID);
|
||||
_ACHIEVE_MAIN * GetAchieveMainPointer(uint32 ID);
|
||||
|
||||
Unit * GetUnitPtr(uint16 id);
|
||||
|
||||
// Spawns an event NPC/monster
|
||||
void SpawnEventNpc(uint16 sSid, bool bIsMonster, uint8 byZone, float fX, float fY, float fZ, uint16 sCount = 1, uint16 sRadius = 0, uint16 sDuration = 0, uint8 nation = 0, int16 socketID = -1, uint16 nEventRoom = 0, bool nIsPet = false, std::string strPetName = "", std::string strUserName = "", uint64 nSerial = 1, uint16 UserId = -1);
|
||||
|
||||
uint16 SpawnBot(int Minute, uint8 byZone, float fX, float fY, float fZ, uint8 Restipi, uint8 minlevel = 1);
|
||||
|
||||
// Kill a Npc/Monster
|
||||
void KillNpc(uint16 sNid);
|
||||
|
||||
// Change NPC/Monster properties for Respawn
|
||||
void NpcUpdate(uint16 sSid, bool bIsMonster, uint8 byGroup = 0, uint16 sPid = 0);
|
||||
|
||||
// Adds the account name & session to a hashmap (on login)
|
||||
void AddAccountName(CUser *pSession);
|
||||
|
||||
// Adds the character name & session to a hashmap (when in-game)
|
||||
void AddCharacterName(CUser *pSession);
|
||||
|
||||
// Removes an existing character name/session from the hashmap, replaces the character's name
|
||||
// and reinserts the session with the new name into the hashmap.
|
||||
void ReplaceCharacterName(CUser *pSession, std::string & strNewUserID);
|
||||
|
||||
// Removes the account name & character names from the hashmaps (on logout)
|
||||
void RemoveSessionNames(CUser *pSession);
|
||||
|
||||
// Send to Zone NPC Effect
|
||||
void ShowNpcEffect(uint16 sNpcID, uint32 nEffectID, uint8 ZoneID, uint16 EventRoom);
|
||||
|
||||
_PARTY_GROUP * GetPartyPtr(uint16 sPartyID);
|
||||
CKnights * GetClanPtr(uint16 sClanID);
|
||||
_KNIGHTS_ALLIANCE * GetAlliancePtr(uint16 sAllianceID);
|
||||
_ITEM_TABLE * GetItemPtr(uint32 nItemID);
|
||||
CPet * GetPetPtr(uint64 nItemSerial);
|
||||
_CYPHERRING_DATA * GetCypherRingPtr(uint64 nItemSerial);
|
||||
_KNIGHTS_SIEGE_WARFARE * GetSiegeMasterKnightsPtr(uint16 sMasterKnights);
|
||||
|
||||
_PARTY_GROUP * CreateParty(CUser *pLeader);
|
||||
void DeleteParty(uint16 sIndex);
|
||||
|
||||
_EVENT_STATUS pTempleEvent;
|
||||
|
||||
~CGameServerDlg();
|
||||
|
||||
char m_ppNotice[20][128];
|
||||
char m_peNotice[20][128];
|
||||
std::string m_AIServerIP;
|
||||
uint32 m_AIServerPort;
|
||||
|
||||
NpcArray m_arNpcArray;
|
||||
BotArray m_arBotArray;
|
||||
ZoneArray m_ZoneArray;
|
||||
ItemtableArray m_ItemtableArray;
|
||||
SetItemArray m_SetItemArray;
|
||||
AchieveNormalArray ACHIEVE_NORMAL;
|
||||
AchieveTitleArray ACHIEVE_TITLE;
|
||||
AchieveWarArray ACHIEVE_WAR;
|
||||
AchieveMainArray ACHIEVE_MAIN;
|
||||
AchieveComArray ACHIEVE_COM;
|
||||
AchieveMonsterArray ACHIEVE_MONSTER;
|
||||
ItemMiningArray m_ItemMiningArray;
|
||||
MagictableArray m_MagictableArray;
|
||||
Magictype1Array m_Magictype1Array;
|
||||
Magictype2Array m_Magictype2Array;
|
||||
Magictype3Array m_Magictype3Array;
|
||||
Magictype4Array m_Magictype4Array;
|
||||
Magictype5Array m_Magictype5Array;
|
||||
Magictype6Array m_Magictype6Array;
|
||||
Magictype7Array m_Magictype7Array;
|
||||
Magictype8Array m_Magictype8Array;
|
||||
Magictype9Array m_Magictype9Array;
|
||||
CoefficientArray m_CoefficientArray;
|
||||
LevelUpArray m_LevelUpArray;
|
||||
LevelUpArray m_PetLevelUpArray;
|
||||
PartyArray m_PartyArray;
|
||||
KnightsArray m_KnightsArray;
|
||||
KnightsRatingArray m_KnightsRatingArray[2]; // one for both nations
|
||||
KnightsAllianceArray m_KnightsAllianceArray;
|
||||
KnightsUserArray m_KnightsUserArray;
|
||||
KnightsSiegeWarfareArray m_KnightsSiegeWarfareArray;
|
||||
KnightsCapeArray m_KnightsCapeArray;
|
||||
UserNameRankMap m_UserPersonalRankMap;
|
||||
UserNameRankMap m_UserKnightsRankMap;
|
||||
UserRankMap m_playerRankings[2]; // one for both nations
|
||||
UserRankMap m_playerPersonalRankings[2]; // one for both nations
|
||||
std::recursive_mutex m_userRankingsLock;
|
||||
StartPositionArray m_StartPositionArray;
|
||||
ServerResourceArray m_ServerResourceArray;
|
||||
QuestHelperArray m_QuestHelperArray;
|
||||
QuestNpcList m_QuestNpcList;
|
||||
QuestMonsterArray m_QuestMonsterArray;
|
||||
RentalItemArray m_RentalItemArray;
|
||||
ItemExchangeArray m_ItemExchangeArray;
|
||||
ItemExchangeExpArray m_ItemExchangeExpArray;
|
||||
ItemMixArray m_ItemMixArray;
|
||||
ItemUpgradeArray m_ItemUpgradeArray;
|
||||
ItemOpArray m_ItemOpArray;
|
||||
KingSystemArray m_KingSystemArray;
|
||||
EventTriggerArray m_EventTriggerArray;
|
||||
MonsterChallengeArray m_MonsterChallengeArray;
|
||||
MonsterChallengeSummonListArray m_MonsterChallengeSummonListArray;
|
||||
EventTimesArray m_EventTimesArray;
|
||||
MonsterSummonListArray m_MonsterSummonList;
|
||||
MonsterSummonListZoneArray m_MonsterSummonListZoneArray;
|
||||
MonsterRespawnListArray m_MonsterRespawnListArray;
|
||||
MonsterRespawnListInformationArray m_MonsterRespawnListInformationArray;
|
||||
MonsterRespawnListRandomArray m_MonsterRespawnListRandomArray;
|
||||
PremiumItemArray m_PremiumItemArray;
|
||||
PremiumItemExpArray m_PremiumItemExpArray;
|
||||
CypherRingArray m_CypherRingArray;
|
||||
std::recursive_mutex m_PetArraylock;
|
||||
PetArray m_PetArray;
|
||||
PetArray m_LivingPetArray;
|
||||
UserRankingArray m_UserRankingArray[2];
|
||||
UserDailyOpMap m_UserDailyOpMap;
|
||||
TempleEventUserArray m_TempleEventUserArray;
|
||||
NationMonumentInformationArray m_NationMonumentInformationArray;
|
||||
StartPositionRandomArray m_StartPositionRandomArray;
|
||||
UserItemArray m_UserItemArray;
|
||||
ObjectEventArray m_ObjectEventArray;
|
||||
ChatRoomArray m_ChatRoomArray;
|
||||
ItemCrashArray m_ItemCrashArray;
|
||||
ItemDupersArray m_ItemDupersArray;
|
||||
IlegalItemsArray m_IlegalItemsArray;
|
||||
|
||||
MerchantListArray m_MerchantListArray;
|
||||
|
||||
Atomic<uint16> m_sPartyIndex;
|
||||
short m_sZoneCount; // AI Server 재접속시 사용
|
||||
|
||||
bool m_bFirstServerFlag; // 서버가 처음시작한 후 게임서버가 붙은 경우에는 1, 붙지 않은 경우 0
|
||||
bool m_bServerCheckFlag;
|
||||
bool m_bPointCheckFlag; // AI서버와 재접전에 NPC포인터 참조막기 (true:포인터 참조, false:포인터 참조 못함)
|
||||
short m_sErrorSocketCount; // 이상소켓 감시용
|
||||
|
||||
uint16 m_sYear, m_sMonth, m_sDate, m_sHour, m_sMin, m_sSec;
|
||||
uint8 m_byWeather;
|
||||
uint16 m_sWeatherAmount;
|
||||
int m_nCastleCapture;
|
||||
uint8 m_ReloadKnightAndUserRanksMinute , m_DevakillSecond;
|
||||
|
||||
uint8 m_byBattleOpen, m_byOldBattleOpen;
|
||||
uint8 m_byBattleZone, m_byBattleZoneType, m_bVictory, m_byOldVictory, m_bResultDelayVictory, m_bKarusFlag, m_bElmoradFlag, m_bMiddleStatueNation;
|
||||
int32 m_byBattleOpenedTime;
|
||||
int32 m_byBattleTime;
|
||||
int32 m_byBattleRemainingTime;
|
||||
int32 m_sBattleTimeDelay;
|
||||
int32 m_sBattleResultDelay;
|
||||
|
||||
int32 m_byBattleSiegeWarStartTime;
|
||||
uint8 m_SiegeWarNoticeTime;
|
||||
std::string m_SiegeWarWinKnightsNotice;
|
||||
bool m_byBattleSiegeWarOpen;
|
||||
uint16 m_byBattleSiegeWarOccupy;
|
||||
bool m_byBattleSiegeWarMomument;
|
||||
bool m_byBattleSiegeWarTeleport;
|
||||
|
||||
uint8 m_sKilledKarusNpc, m_sKilledElmoNpc;
|
||||
uint8 m_sKarusMonuments, m_sElmoMonuments;
|
||||
uint8 m_sNereidsMonumentNation[7];
|
||||
uint16 m_sKarusMonumentPoint, m_sElmoMonumentPoint;
|
||||
bool m_byKarusOpenFlag, m_byElmoradOpenFlag, m_byBanishFlag, m_byBattleSave, m_bResultDelay, m_bySnowBanishFlag;
|
||||
short m_sDiscount;
|
||||
short m_sKarusDead, m_sElmoradDead, m_sBanishDelay;
|
||||
std::string m_sBattleZoneOpenDays;
|
||||
std::string m_sEventZoneOpenDays1;
|
||||
std::string m_sEventZoneOpenDays2;
|
||||
std::string m_sEventZoneOpenDays3;
|
||||
uint8 m_nBattleZoneOpenHourStart[WAR_TIME_COUNT], m_nBattlezoneOpenWarZone[WAR_ZONE_COUNT];
|
||||
|
||||
std::string m_strKarusCaptain, m_strElmoradCaptain;
|
||||
|
||||
uint8 m_nBorderDefenseWarTime[BORDER_DEFENSE_WAR_EVENT_COUNT], m_nChaosTime[CHAOS_EVENT_COUNT], m_nJuraidTime[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeWonItemNo1[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeWonItemNo2[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeWonItemNo3[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeWonItemNo4_K[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeWonItemNo4_H[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeWonLoyalty[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeWonKnightCash[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeLoserKnightCash[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeLoserLoyalty[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint32 m_nBorderDefenseWarPrizeLoserItem[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint8 m_nBorderDefenseWarMAXLEVEL[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
uint8 m_nBorderDefenseWarMINLEVEL[BORDER_DEFENSE_WAR_EVENT_COUNT];
|
||||
|
||||
bool m_nJuraidMountainOdulTipi[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeWonItemNo1[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeWonItemNo2[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeWonItemNo3[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeWonItemNo4_K[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeWonItemNo4_H[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeWonLoyalty[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeWonExp[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeWonKnightCash[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeLoserKnightCash[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeLoserLoyalty[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeLoserItem[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint32 m_nJuraidMountainPrizeLoserExp[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint8 m_nJuraidMountainMAXLEVEL[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
uint8 m_nJuraidMountainMINLEVEL[JURAD_MOUNTAIN_EVENT_COUNT];
|
||||
|
||||
|
||||
uint32 m_nChaosPrizeWonItemNo1[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeWonItemNo2[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeWonItemNo3[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeWonItemNo4_K[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeWonItemNo4_H[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeWonLoyalty[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeWonExp[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeWonKnightCash[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeLoserKnightCash[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeLoserLoyalty[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeLoserItem[CHAOS_EVENT_COUNT];
|
||||
uint32 m_nChaosPrizeLoserExp[CHAOS_EVENT_COUNT];
|
||||
|
||||
|
||||
uint8 m_nPVPMonumentNation[MAX_ZONE_ID];
|
||||
uint8 m_nEventMonumentNation[MAX_ZONE_ID];
|
||||
|
||||
uint32 m_GameServerPort;
|
||||
int32 m_nGameMasterRHitDamage;
|
||||
int32 m_nBonusTimeInterval, m_nBonusTimeGold, m_nBonusPVPWarItem;
|
||||
uint16 m_CountofTickets;
|
||||
uint8 m_nPlayerRankingResetTime;
|
||||
std::string m_sPlayerRankingsRewardZones;
|
||||
uint32 m_nPlayerRankingKnightCashReward;
|
||||
uint32 m_nPlayerRankingLoyaltyReward,m_Grade1,m_Grade2,m_Grade3,m_Grade4,m_Drop1,m_Drop2,m_Drop3,m_Drop4,m_Drop5,m_gDrop1,m_gDrop2,
|
||||
m_gDrop3,m_gDrop4,m_gDrop5,m_sling,f_Drop1,f_Drop2,f_Drop3,gf_Drop1,gf_Drop2,gf_Drop3;
|
||||
uint8 m_AutoNoticeIsActive;
|
||||
std::string m_AutoNotice;
|
||||
std::string m_AutoNoticeText;
|
||||
uint16 m_nTempleEventRemainSeconds;
|
||||
|
||||
uint8 m_bMaxRegenePoint;
|
||||
|
||||
bool m_bPermanentChatMode;
|
||||
std::string m_strPermanentChat;
|
||||
|
||||
uint8 m_bSantaOrAngel;
|
||||
uint8 m_sRankResetHour;
|
||||
|
||||
int TotalMiningExchangeRate;
|
||||
int TotalGoldenMiningExchangeRate;
|
||||
uint32 bRandArrayNormalMattock[10000];
|
||||
uint32 bRandArrayGoldenMattock[10000];
|
||||
|
||||
|
||||
// National Points Settings
|
||||
int m_Loyalty_Ardream_Source;
|
||||
int m_Loyalty_Ardream_Target;
|
||||
int m_Loyalty_Ronark_Land_Base_Source;
|
||||
int m_Loyalty_Ronark_Land_Base_Target;
|
||||
int m_Loyalty_Ronark_Land_Source;
|
||||
int m_Loyalty_Ronark_Land_Target;
|
||||
int m_Loyalty_Other_Zone_Source;
|
||||
int m_Loyalty_Other_Zone_Target;
|
||||
int m_Loyalty_Mini_Pvp_Source;
|
||||
int m_Loyalty_Mini_Pvp_Target;
|
||||
|
||||
// Bifrost
|
||||
uint8 m_nBifrostTime[BIFROST_EVENT_COUNT];
|
||||
|
||||
uint8 m_BifrostVictory;
|
||||
uint8 m_sBifrostVictoryAll;
|
||||
uint16 m_sBifrostRemainingTime;
|
||||
uint16 m_sBifrostTime;
|
||||
bool m_sBifrostWarStart;
|
||||
uint8 m_sBifrostVictoryNoticeAll;
|
||||
uint16 m_xBifrostRemainingTime;
|
||||
uint16 m_xJoinOtherNationBifrostTime;
|
||||
uint16 m_xBifrostTime;
|
||||
uint16 m_xBifrostMonumentAttackTime;
|
||||
bool m_bAttackBifrostMonument;
|
||||
|
||||
void SendEventRemainingTime(bool bSendAll = false, CUser *pUser = nullptr, uint8 ZoneID = 0);
|
||||
uint16 CalcEventRemainingTime();
|
||||
|
||||
bool m_IsMagicTableInUpdateProcess;
|
||||
bool m_IsPlayerRankingUpdateProcess;
|
||||
|
||||
// Forgetten Temple
|
||||
std::vector<uint16> m_nForgettenTempleUsers;
|
||||
bool m_bForgettenTempleIsActive;
|
||||
int8 m_nForgettenTempleStartHour;
|
||||
int8 m_nForgettenTempleLevelMin;
|
||||
int8 m_nForgettenTempleLevelMax;
|
||||
int32 m_nForgettenTempleStartTime;
|
||||
uint8 m_nForgettenTempleChallengeTime;
|
||||
bool m_bForgettenTempleSummonMonsters;
|
||||
uint8 m_nForgettenTempleCurrentStage;
|
||||
uint8 m_nForgettenTempleLastStage;
|
||||
ForgettenTempleMonsterList m_ForgettenTempleMonsterList;
|
||||
uint32 m_nForgettenTempleLastSummonTime;
|
||||
bool m_nForgettenTempleBanishFlag;
|
||||
uint8 m_nForgettenTempleBanishTime;
|
||||
|
||||
// Event Zones
|
||||
std::vector<uint16> m_nEventZoneUsers;
|
||||
bool m_bEventZoneIsActive;
|
||||
int8 m_nEventZoneStartHour;
|
||||
int8 m_nEventZoneLevelMin;
|
||||
int8 m_nEventZoneLevelMax;
|
||||
int32 m_nEventZoneStartTime;
|
||||
uint8 m_nEventZoneTime;
|
||||
bool m_nEventZoneBanishFlag;
|
||||
uint8 m_nEventZoneBanishTime;
|
||||
|
||||
// zone server info
|
||||
int m_nServerNo, m_nServerGroupNo;
|
||||
int m_nServerGroup; // server의 번호(0:서버군이 없다, 1:서버1군, 2:서버2군)
|
||||
ServerArray m_ServerArray;
|
||||
ServerArray m_ServerGroupArray;
|
||||
|
||||
NameMap m_accountNameMap,
|
||||
m_characterNameMap;
|
||||
BotNameMap m_BotcharacterNameMap;
|
||||
|
||||
std::recursive_mutex m_accountNameLock,
|
||||
m_characterNameLock, m_BotcharacterNameLock,
|
||||
m_questNpcLock;
|
||||
|
||||
|
||||
bool m_IsDupeUpdateProcess;
|
||||
bool m_IlegalItemsUpdateProcess;
|
||||
|
||||
// Controlled weather events set by Kings
|
||||
uint8 m_byKingWeatherEvent;
|
||||
uint8 m_byKingWeatherEvent_Day;
|
||||
uint8 m_byKingWeatherEvent_Hour;
|
||||
uint8 m_byKingWeatherEvent_Minute;
|
||||
|
||||
|
||||
// Military Camps
|
||||
uint8 KarusBaseMilitaryCampCount, ElmoradBaseMilitaryCampCount, KarusEslantMilitaryCampCount, ElmoradEslantMilitaryCampCount, MoradonMilitaryCampCount;
|
||||
|
||||
// XP/coin/NP events
|
||||
uint8 m_byNPEventAmount, m_byExpEventAmount, m_byCoinEventAmount,m_byPKZoneExpEventAmount,Reskillmoney,Restatmoney;
|
||||
uint8 MAXLVLINI;
|
||||
uint8 MaxLevel62Control;
|
||||
// EXP 2, EXP 10 , EXP 50, EXP 100, EXP 500, EXP 1000, EXP TOTAL
|
||||
int m_byExpx2, m_byExpx10, m_byExpx50, m_byExpx100, m_byExpx500, m_byExpx1000, m_byExpTotal;
|
||||
// Gold 2, Gold 10 , Gold 50, Gold 100, Gold 500, Gold 1000, Gold TOTAL
|
||||
int m_byGoldx2, m_byGoldx10, m_byGoldx50, m_byGoldx100, m_byGoldx500, m_byGoldx1000, m_byGoldTotal;
|
||||
|
||||
|
||||
INLINE CLuaEngine * GetLuaEngine() { return &m_luaEngine; }
|
||||
|
||||
KOSocketMgr<CUser> m_socketMgr;
|
||||
ClientSocketMgr<CAISocket> m_aiSocketMgr;
|
||||
|
||||
FILE *m_fpDeathUser;
|
||||
FILE *m_fpDeathNpc;
|
||||
FILE *m_fpChat;
|
||||
FILE *m_fpGM;
|
||||
FILE *m_upgradelog;
|
||||
FILE *m_fpCheat;
|
||||
FILE *m_fpMerchant;
|
||||
FILE *m_fpTrade;
|
||||
|
||||
|
||||
|
||||
void WriteMerchantUserLogFile(std::string & logMessage);
|
||||
void WriteTradeUserLogFile(std::string & logMessage);
|
||||
void WriteDeathUserLogFile(std::string & logMessage);
|
||||
void WriteDeathNpcLogFile(std::string & logMessage);
|
||||
void WriteChatLogFile(std::string & logMessage);
|
||||
void WriteGMLogFile(std::string & logMessage);
|
||||
void WriteUpgradeLogFile(std::string & logMessage);
|
||||
void WriteCheatLogFile(std::string & logMessage);
|
||||
|
||||
private:
|
||||
CLuaEngine m_luaEngine;
|
||||
|
||||
std::string m_strGameDSN, m_strAccountDSN;
|
||||
std::string m_strGameUID, m_strAccountUID;
|
||||
std::string m_strGamePWD, m_strAccountPWD;
|
||||
bool m_bMarsEnabled;
|
||||
|
||||
bool ProcessServerCommand(std::string & command);
|
||||
|
||||
public:
|
||||
void InitServerCommands();
|
||||
void CleanupServerCommands();
|
||||
|
||||
static ServerCommandTable s_commandTable;
|
||||
|
||||
COMMAND_HANDLER(HandleReloadDupeCommand);
|
||||
COMMAND_HANDLER(HandleReloadIlegalItemsCommand);
|
||||
COMMAND_HANDLER(HandleNoticeCommand);
|
||||
COMMAND_HANDLER(HandleNoticeallCommand);
|
||||
COMMAND_HANDLER(HandleKillUserCommand);
|
||||
COMMAND_HANDLER(HandleWar1OpenCommand);
|
||||
COMMAND_HANDLER(HandleWar2OpenCommand);
|
||||
COMMAND_HANDLER(HandleWar3OpenCommand);
|
||||
COMMAND_HANDLER(HandleWar4OpenCommand);
|
||||
COMMAND_HANDLER(HandleWar5OpenCommand);
|
||||
COMMAND_HANDLER(HandleWar6OpenCommand);
|
||||
COMMAND_HANDLER(HandleOpenArdreamCommand);
|
||||
COMMAND_HANDLER(HandleOpenCZCommand);
|
||||
COMMAND_HANDLER(HandleCloseCZEventCommand);
|
||||
COMMAND_HANDLER(HandleCloseArdreamEventCommand);
|
||||
COMMAND_HANDLER(HandleSnowWarOpenCommand);
|
||||
COMMAND_HANDLER(HandleSiegeWarOpenCommand);
|
||||
COMMAND_HANDLER(HandleWarCloseCommand);
|
||||
COMMAND_HANDLER(HandleShutdownCommand);
|
||||
COMMAND_HANDLER(HandleDiscountCommand);
|
||||
COMMAND_HANDLER(HandleGlobalDiscountCommand);
|
||||
COMMAND_HANDLER(HandleDiscountOffCommand);
|
||||
COMMAND_HANDLER(HandleCaptainCommand);
|
||||
COMMAND_HANDLER(HandleSantaCommand);
|
||||
COMMAND_HANDLER(HandleSantaOffCommand);
|
||||
COMMAND_HANDLER(HandleAngelCommand);
|
||||
COMMAND_HANDLER(HandlePermanentChatCommand);
|
||||
COMMAND_HANDLER(HandlePermanentChatOffCommand);
|
||||
COMMAND_HANDLER(HandleReloadNoticeCommand);
|
||||
COMMAND_HANDLER(HandleItemTablesCommand);
|
||||
COMMAND_HANDLER(HandleReloadTablesCommand);
|
||||
COMMAND_HANDLER(HandleReloadMagicsCommand);
|
||||
COMMAND_HANDLER(HandleReloadBotsCommand);
|
||||
COMMAND_HANDLER(HandleReloadQuestCommand);
|
||||
COMMAND_HANDLER(HandleReloadRanksCommand);
|
||||
COMMAND_HANDLER(HandleNPAddCommand);
|
||||
COMMAND_HANDLER(HandleExpAddCommand);
|
||||
COMMAND_HANDLER(HandleGiveItemCommand);
|
||||
COMMAND_HANDLER(HandleMoneyAddCommand);
|
||||
COMMAND_HANDLER(HandleTeleportAllCommand);
|
||||
COMMAND_HANDLER(HandleCountCommand);
|
||||
COMMAND_HANDLER(HandlePermitConnectCommand);
|
||||
COMMAND_HANDLER(HandleWarResultCommand);
|
||||
COMMAND_HANDLER(HandleMonSummonCommand);
|
||||
COMMAND_HANDLER(HandleSnowWarCloseCommand);
|
||||
};
|
||||
|
||||
extern CGameServerDlg * g_pMain;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,157 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
void CUser::HandleGenie(Packet & pkt)
|
||||
{
|
||||
uint8 command = pkt.read<uint8>();
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case 0x01:
|
||||
GenieNonAttackProgress(pkt);
|
||||
break;
|
||||
case 0x02:
|
||||
GenieAttackProgress(pkt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::GenieNonAttackProgress(Packet & pkt)
|
||||
{
|
||||
|
||||
enum GenieNonAttackType
|
||||
{
|
||||
GenieUseSpiringPotion = 1,
|
||||
GenieLoadOptions = 0x02,
|
||||
GenielSaveOptions = 0x03,
|
||||
GenieStartHandle = 0x04,
|
||||
GenieStopHandle = 0x05
|
||||
};
|
||||
|
||||
uint8 command = pkt.read<uint8>();
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case GenieUseSpiringPotion:
|
||||
GenieUseGenieSpirint();
|
||||
break;
|
||||
case GenieStartHandle:
|
||||
GenieStart();
|
||||
break;
|
||||
case GenielSaveOptions:
|
||||
for(int i=0; i<sizeof(m_GenieOptions); i++)
|
||||
{
|
||||
*(uint8 *)(m_GenieOptions + i ) = pkt.read<uint8>();
|
||||
}
|
||||
break;
|
||||
case GenieLoadOptions:
|
||||
{
|
||||
Packet result(WIZ_GENIE);
|
||||
|
||||
result << uint8(0x01) << uint8(2);// << m_GenieOptions;
|
||||
|
||||
for(int i=0; i<sizeof(m_GenieOptions); i++)
|
||||
result << uint8(*(uint8 *)(m_GenieOptions + i));
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
break;
|
||||
case GenieStopHandle:
|
||||
GenieStop();
|
||||
break;
|
||||
default:
|
||||
TRACE("[%s] Genie Non Attack Unknow Handle %d Packet Len [%d]\r\n",GetName().c_str(),command,pkt.size());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CUser::GenieAttackProgress(Packet & pkt)
|
||||
{
|
||||
enum GenieAttackHandle
|
||||
{
|
||||
GenieMove = 1,
|
||||
GenieSkillSave = 2,
|
||||
GenieMainAttack = 3,
|
||||
GenieMagic = 4
|
||||
};
|
||||
|
||||
uint8 command = pkt.read<uint8>();
|
||||
|
||||
if(m_GenieTime == 0)
|
||||
GenieStop();
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case GenieMove:
|
||||
MoveProcess(pkt);
|
||||
break;
|
||||
case GenieMagic:
|
||||
CMagicProcess::MagicPacket(pkt, this);
|
||||
break;
|
||||
case GenieMainAttack:
|
||||
Attack(pkt);
|
||||
break;
|
||||
default:
|
||||
TRACE("[%s] Genie Unknow Attack Handle %d Packet Len[%d]\r\n",GetName().c_str(),command,pkt.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CUser::GenieStart()
|
||||
{
|
||||
Packet result(WIZ_GENIE);
|
||||
|
||||
result << uint8(0x01) << uint8(4) << uint16(1) << uint16(m_GenieTime);
|
||||
m_bGenieStatus = true;
|
||||
UserInOut(INOUT_IN);
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::GenieStop()
|
||||
{
|
||||
Packet result(WIZ_GENIE);
|
||||
|
||||
result << uint8(0x01) << uint8(5) << uint16(1) << uint16(m_GenieTime);
|
||||
m_bGenieStatus = false;
|
||||
UserInOut(INOUT_IN);
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::UpdateGenieTime(uint16 m_sTime)
|
||||
{
|
||||
Packet result(WIZ_GENIE);
|
||||
|
||||
result << uint8(0x01) << uint8(4) << uint16(1) << uint16(m_GenieTime);
|
||||
m_bGenieStatus = true;
|
||||
|
||||
Send(&result);
|
||||
}
|
||||
|
||||
void CUser::GenieUseGenieSpirint()
|
||||
{
|
||||
Packet result(WIZ_GENIE);
|
||||
|
||||
// item check and rob
|
||||
uint8 CountA,CountB;
|
||||
|
||||
CountA = GetItemCount(810305000);
|
||||
CountB = GetItemCount(810306000);
|
||||
|
||||
if(CountA < 1 && CountB < 1)
|
||||
return;
|
||||
else if(CountA > 0 )
|
||||
RobItem(810305000);
|
||||
else if(CountB > 0)
|
||||
RobItem(810306000);
|
||||
|
||||
|
||||
|
||||
m_GenieTime = 120;
|
||||
|
||||
result << uint8(1) << uint8(1) << GetGenieTime();
|
||||
|
||||
Send(&result);
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user