Files
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

432 lines
12 KiB
C++

#include "stdafx.h"
#include "CastleGate.h"
#include <Skill/SkillTable.h>
#include <Skill/SkillMgr.h>
#include <Utility/Math/Math.h>
#include <Item/ItemFactory.h>
#include <Map/FieldMap/CellManager.h>
#include <Map/DuelMap/DuelCellManager.h>
#include <Network/Packet/WrapPacket.h>
#include <Network/Packet/PacketCommand.h>
#include <Network/Packet/PacketStruct/ServerInfo.h>
#include <Network/Dispatch/GameClient/GameClientDispatch.h>
#include <Network/Dispatch/GameClient/SendCharItem.h>
#include <Network/Dispatch/GameClient/SendCharCastle.h>
#include <Network/Dispatch/GameClient/SendCharAttack.h>
#include <Network/Dispatch/DBAgent/DBAgentDispatch.h>
#include <Network/Dispatch/DBAgent/DBAgentRequest.h>
#include <Network/ClientSocket/ClientConstants.h>
CCastleGate::CCastleGate(MonsterCreateInfo& MonsterCreate, const CastleObjectInfo& CastleObject)
: CSiegeObject(MonsterCreate, CastleObject)
{
}
CCastleGate::~CCastleGate()
{
}
bool CCastleGate::Dead(CAggresiveCreature* pOffencer)
{
if (NULL == pOffencer) return false;
if (STATE_ID_DIE == m_nCurrentState) return false;
m_CreatureStatus.m_nNowHP = 0;
m_dwLastBehaviorTick = m_dwLastTime = CPulse::GetInstance().GetLastTick();
m_lCurrentFrame = FPS;
m_bAttacking = false;
m_bCasting = false;
m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_ZERO_HP);
// Áß°č ź­šöˇÎ ĆĐĹś ŔüźŰ
GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable());
if (lpDBAgentDispatch)
{
return GameClientSendPacket::SendCharCastleCmdToDBAgent(lpDBAgentDispatch->GetSendStream(), pOffencer->GetCID(),
GetCastleID(), m_dwCID, 0, 0, PktCastleCmd::CASTLE_DESTROY_GATE,
PktBase::NO_SERVER_ERR);
}
return false;
}
void CCastleGate::AddProtectGate(CCharacter* lpProtectChar)
{
if (lpProtectChar && lpProtectChar->GetStatus().m_nNowHP > 0)
{
ProtectCIDList::iterator itr = std::find(m_ProtectCharList.begin(), m_ProtectCharList.end(), lpProtectChar->GetCID());
if (itr == m_ProtectCharList.end())
{
m_ProtectCharList.push_back(lpProtectChar->GetCID());
lpProtectChar->SetProtectGateCID(m_dwCID);
++m_CreatureStatus.m_StatusInfo.m_wBlock;
SendProtectGateInfo();
}
}
}
void CCastleGate::DeleteProtectGate(CCharacter* lpProtectChar)
{
if (lpProtectChar)
{
ProtectCIDList::iterator itr = std::find(m_ProtectCharList.begin(), m_ProtectCharList.end(), lpProtectChar->GetCID());
if (itr != m_ProtectCharList.end())
{
m_ProtectCharList.erase(itr);
lpProtectChar->SetProtectGateCID(0);
if (0 < m_CreatureStatus.m_StatusInfo.m_wBlock)
{
--m_CreatureStatus.m_StatusInfo.m_wBlock;
}
SendProtectGateInfo();
}
}
}
void CCastleGate::DivideDamage(CAggresiveCreature* pOffencer, unsigned short wDamage)
{
if (NULL == pOffencer)
{
return;
}
int nNum = static_cast<int>(m_ProtectCharList.size());
wDamage = static_cast<unsigned short>(wDamage * 100 / 1.33f);
unsigned short wCharDamage = (nNum == 0) ? 0 : wDamage / nNum;
ProtectCIDList::iterator itr = m_ProtectCharList.begin();
while (itr != m_ProtectCharList.end())
{
CCharacter* lpCharacter = CCreatureManager::GetInstance().GetCharacter((*itr));
if (lpCharacter)
{
unsigned short wNowHP = lpCharacter->GetStatus().m_nNowHP;
const unsigned short wThreatAmount = (wNowHP < wCharDamage) ? wNowHP : wCharDamage;
lpCharacter->GetThreat().AddToThreatList(pOffencer, wThreatAmount);
lpCharacter->GetStatus().m_nNowHP = (wNowHP > wCharDamage) ? wNowHP - wCharDamage : 0;
if (0 == lpCharacter->GetStatus().m_nNowHP)
{
lpCharacter->Dead(pOffencer);
lpCharacter->GetThreat().ClearAll();
}
AtType attackType;
attackType.m_wType = AtType::RIGHT_MELEE;
CGameClientDispatch* pCharacterDispatcher = lpCharacter->GetDispatcher();
if (NULL != pCharacterDispatcher)
{
GameClientSendPacket::SendCharAttacked(pCharacterDispatcher->GetSendStream(), pOffencer, lpCharacter,
attackType, 0, wCharDamage, ClientConstants::Judge_Front, 0, PktBase::NO_SERVER_ERR);
}
}
}
}
void CCastleGate::SendProtectGateInfo()
{
int nNum = static_cast<int>(m_ProtectCharList.size());
// şíˇ°ˇü °čťę˝Ä : INT((99 * şíˇ°źöÄĄ / 2) / (şíˇ°źöÄĄ / 2 + 50) * 100) / 100
int nBlockRate = static_cast<int>((99 * m_CreatureStatus.m_StatusInfo.m_wBlock / 2) / (m_CreatureStatus.m_StatusInfo.m_wBlock / 2 + 50) * 100) / 100;
if (0 == nNum) return;
ProtectCIDList::iterator itr = m_ProtectCharList.begin();
while (itr != m_ProtectCharList.end())
{
CCharacter* lpCharacter = CCreatureManager::GetInstance().GetCharacter((*itr));
if (lpCharacter)
{
CGameClientDispatch* pCharacterDispatcher = lpCharacter->GetDispatcher();
if (NULL != pCharacterDispatcher)
{
GameClientSendPacket::SendCharCastleCmd(pCharacterDispatcher->GetSendStream(), GetCastleID(), m_dwCID,
nBlockRate, m_CreatureStatus.m_nNowHP,
PktCastleCmd::CASTLE_GATE_PROTECT_INFO, PktBase::NO_SERVER_ERR);
}
}
++itr;
}
}
void CCastleGate::Open()
{
if ( !IsGate() ) return;
m_cSubState = Siege::OPENED;
// źşšŽŔĚ ŔÖ´Â šÝ°ć 5źż ŔĚłťżĄ ŔüźŰ
PktCastleCmd pktCC;
pktCC.m_dwCastleID = GetCastleID();
pktCC.m_dwCastleObjectID = m_dwCID;
pktCC.m_cState = m_cState;
pktCC.m_dwValue1 = m_cSubState;
pktCC.m_dwValue2 = 0;
pktCC.m_cSubCmd = PktCastleCmd::CASTLE_GATE_OPEN;
char* szPacket = reinterpret_cast<char *>(&pktCC);
if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0))
{
// Vincent - şęˇÎľĺ Äł˝şĆŽ Ĺ×˝şĆŽ ÄÚľĺ
//SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
}
}
void CCastleGate::Close()
{
if ( !IsGate() ) return;
m_cSubState = Siege::CLOSED;
// źşšŽŔĚ ŔÖ´Â šÝ°ć 5źż ŔĚłťżĄ ŔüźŰ
PktCastleCmd pktCC;
pktCC.m_dwCastleID = GetCastleID();
pktCC.m_dwCastleObjectID = m_dwCID;
pktCC.m_cState = m_cState;
pktCC.m_dwValue1 = m_cSubState;
pktCC.m_dwValue2 = 0;
pktCC.m_cSubCmd = PktCastleCmd::CASTLE_GATE_CLOSE;
char* szPacket = reinterpret_cast<char *>(&pktCC);
if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0))
{
// Vincent - şęˇÎľĺ Äł˝şĆŽ Ĺ×˝şĆŽ ÄÚľĺ
//SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
}
}
void CCastleGate::ForceOpen()
{
if ( !IsGate() ) return;
if ( Siege::COMPLETE == m_cState && Siege::OPENED == m_cSubState )
{
return;
}
m_cState = Siege::COMPLETE;
m_cSubState = Siege::OPENED;
m_nCurrentState = STATE_ID_NORMAL;
UpdateObjectInfo(Siege::FULL_HP, 0);
// źşšŽŔĚ ŔÖ´Â šÝ°ć 5źż ŔĚłťżĄ ŔüźŰ
PktCastleCmd pktCC;
pktCC.m_dwCastleID = GetCastleID();
pktCC.m_dwCastleObjectID = m_dwCID;
pktCC.m_cState = m_cState;
pktCC.m_dwValue1 = m_cSubState;
pktCC.m_dwValue2 = 0;
pktCC.m_cSubCmd = PktCastleCmd::CASTLE_GATE_OPEN;
char* szPacket = reinterpret_cast<char *>(&pktCC);
if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0))
{
// Vincent - şęˇÎľĺ Äł˝şĆŽ Ĺ×˝şĆŽ ÄÚľĺ
//SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
}
}
void CCastleGate::ForceClose()
{
if ( !IsGate() ) return;
if ( Siege::COMPLETE == m_cState && Siege::CLOSED == m_cSubState )
{
return;
}
m_cState = Siege::COMPLETE;
m_cSubState = Siege::CLOSED;
m_nCurrentState = STATE_ID_NORMAL;
UpdateObjectInfo(Siege::FULL_HP, 0);
// źşšŽŔĚ ŔÖ´Â šÝ°ć 5źż ŔĚłťżĄ ŔüźŰ
PktCastleCmd pktCC;
pktCC.m_dwCastleID = GetCastleID();
pktCC.m_dwCastleObjectID = m_dwCID;
pktCC.m_cState = m_cState;
pktCC.m_dwValue1 = m_cSubState;
pktCC.m_dwValue2 = 0;
pktCC.m_cSubCmd = PktCastleCmd::CASTLE_GATE_CLOSE;
char* szPacket = reinterpret_cast<char *>(&pktCC);
if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0))
{
// Vincent - şęˇÎľĺ Äł˝şĆŽ Ĺ×˝şĆŽ ÄÚľĺ
//SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
}
}
bool CCastleGate::Upgrade(unsigned char cUpgradeStep)
{
m_cState = Siege::COMPLETE;
m_cUpgradeStep = cUpgradeStep;
UpdateObjectInfo(Siege::UPGRADE_HP);
// źşšŽŔĚ ŔÖ´Â šÝ°ć 5źż ŔĚłťżĄ ŔüźŰ
PktCastleCmd pktCC;
pktCC.m_dwCastleID = GetCastleID();
pktCC.m_dwCastleObjectID = m_dwCID;
pktCC.m_cState = m_cState;
pktCC.m_dwValue1 = m_cUpgradeStep; // ž÷ą×ˇšŔĚľĺ ´Ü°č
pktCC.m_dwValue2 = 0;
pktCC.m_cSubCmd = PktCastleCmd::CASTLE_UPGRADE_GATE_COMPLETE;
char* szPacket = reinterpret_cast<char *>(&pktCC);
if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0))
{
// Vincent - şęˇÎľĺ Äł˝şĆŽ Ĺ×˝şĆŽ ÄÚľĺ
//SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
}
return true;
}
bool CCastleGate::Repair(unsigned short wRepairHP)
{
m_cState = Siege::COMPLETE;
UpdateObjectInfo(Siege::REPAIR_HP, wRepairHP);
// źşšŽŔĚ ŔÖ´Â šÝ°ć 5źż ŔĚłťżĄ ŔüźŰ
PktCastleCmd pktCC;
pktCC.m_dwCastleID = GetCastleID();
pktCC.m_dwCastleObjectID = m_dwCID;
pktCC.m_cState = m_cState;
pktCC.m_dwValue1 = m_CreatureStatus.m_nNowHP; // ÇöŔç HP
pktCC.m_dwValue2 = 0;
pktCC.m_cSubCmd = PktCastleCmd::CASTLE_REPAIR_GATE_COMPLETE;
char* szPacket = reinterpret_cast<char *>(&pktCC);
if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0))
{
// Vincent - şęˇÎľĺ Äł˝şĆŽ Ĺ×˝şĆŽ ÄÚľĺ
//SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
}
return true;
}
bool CCastleGate::Restore()
{
m_cState = Siege::COMPLETE;
m_cUpgradeStep = 0;
m_nCurrentState = STATE_ID_NORMAL;
UpdateObjectInfo();
// źşšŽŔĚ ŔÖ´Â šÝ°ć 5źż ŔĚłťżĄ ŔüźŰ
PktCastleCmd pktCC;
pktCC.m_dwCastleID = GetCastleID();
pktCC.m_dwCastleObjectID = m_dwCID;
pktCC.m_cState = m_cState;
pktCC.m_dwValue1 = m_CreatureStatus.m_nNowHP; // ÇöŔç HP
pktCC.m_dwValue2 = 0;
pktCC.m_cSubCmd = PktCastleCmd::CASTLE_RESTORE_GATE_COMPLETE;
char* szPacket = reinterpret_cast<char *>(&pktCC);
if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0))
{
// Vincent - şęˇÎľĺ Äł˝şĆŽ Ĺ×˝şĆŽ ÄÚľĺ
//SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
}
return true;
}
bool CCastleGate::Destroy(unsigned char cOffencerNation, bool bTakeGold)
{
m_cState = Siege::DESTROYED;
m_cSubState = Siege::OPENED;
m_cUpgradeStep = 0;
m_CreatureStatus.m_nNowHP = 0;
UpdateObjectInfo();
// ¸ŢźźÁö Ăł¸Ž ś§šŽżĄ Á¸ŔÇ ¸đľç ŔÎżřżĄ°Ô ş¸ł˝´Ů.
PktCastleCmd pktCC;
pktCC.m_dwCastleID = GetCastleID();
pktCC.m_dwCastleObjectID = m_dwCID;
pktCC.m_cState = m_cState;
pktCC.m_dwValue1 = 0;
pktCC.m_dwValue2 = 0;
pktCC.m_cSubCmd = PktCastleCmd::CASTLE_DESTROY_GATE;
char* szPacket = reinterpret_cast<char *>(&pktCC);
if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0))
{
CCreatureManager::GetInstance().SendAllCharacter(szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
}
return true;
}
bool CCastleGate::Update(unsigned char cState, unsigned long dwValue1, unsigned long dwValue2, unsigned long dwNoValue, unsigned char cSubCmd)
{
m_cState = cState;
if (PktCastleCmd::CASTLE_RESTORE_GATE == cSubCmd)
{
UpdateObjectInfo(Siege::FULL_HP);
}
else
{
UpdateObjectInfo();
}
// źşšŽŔĚ ŔÖ´Â šÝ°ć 5źż ŔĚłťżĄ ŔüźŰ
PktCastleCmd pktCC;
pktCC.m_dwCastleID = GetCastleID();
pktCC.m_dwCastleObjectID = m_dwCID;
pktCC.m_cState = m_cState;
pktCC.m_dwValue1 = dwValue1;
pktCC.m_dwValue2 = 0;
pktCC.m_cSubCmd = cSubCmd;
char* szPacket = reinterpret_cast<char *>(&pktCC);
if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0))
{
// Vincent - şęˇÎľĺ Äł˝şĆŽ Ĺ×˝şĆŽ ÄÚľĺ
//SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd);
}
return true;
}
unsigned long CCastleGate::GetRepairGold() const
{
// int nDiffHP = m_CreatureStatus.m_StatusInfo.m_nMaxHP - m_CreatureStatus.m_nNowHP;
// int nShare = nDiffHP / Siege::CASTLE_ARMS_REPAIR_HP_UNIT;
// int nLeftOver = nDiffHP % Siege::CASTLE_ARMS_REPAIR_HP_UNIT;
// if (nLeftOver > 0) ++nShare;
//
// return nShare * Siege::CASTLE_ARMS_REPAIR_GOLD_PER_UNIT;
return 0;
}