knightonline/server/GameServer/Pet.cpp

321 lines
6.5 KiB
C++

#include "stdafx.h"
#include "Map.h"
#include "DBAgent.h"
CPet::CPet() : Unit(UnitType::UnitPet)
{
CPet::Initialize();
}
void CPet::Initialize()
{
m_MovingMap.DeleteAllData();
memset(m_sItemArray, 0x00, sizeof(m_sItemArray));
SpecialPetID = 0;
isMoving = false;
isDropping = false;
m_sSid = 0;
m_sPid = 0;
m_sSize = 100;
m_strPetID.clear();
m_byState = 0;
m_iSellingGroup = 0;
m_byDirection = 0;
m_iWeapon_1 = 0;
m_iWeapon_2 = 0;
m_oSocketID = -1;
m_bEventRoom = 0;
m_NpcState = NPC_LIVE;
m_iExp = 0;
m_bLevel = 0;
m_sClass = 0;
m_bNation = 0;
m_sSatisfaction = 0;
m_Serial = 0;
m_sMaxHp = 0;
m_sMaxMp = 0;
m_sHp = 0;
m_sMp = 0;
m_sAttack = 0;
m_sAc = 0;
m_bResistanceBonus = 0;
m_sFireR = m_sColdR = m_sLightningR = m_sMagicR = m_sDiseaseR = m_sPoisonR = 0;
m_pNpc = nullptr;
mode = 0;
LastStep = 1;
LastMovedTime = 0;
Unit::Initialize();
}
CPet::~CPet()
{
}
void CPet::AddtoMovingMap(float toX, float toY, float toZ, uint8 speed, bool IsDrop, uint32 BundleID)
{
if(m_pNpc == nullptr)
return;
_PET_MOVE * pMove = new _PET_MOVE;
pMove->X = toX;
pMove->Y = toY;
pMove->Z = toZ;
pMove->Speed = speed;
pMove->Time = uint32(UNIXTIME);
pMove->Drop = IsDrop;
pMove->BundleID = BundleID;
Moving(toX,toY,toZ,speed);
m_MovingMap.PutData(LastStep, pMove);
LastStep++;
}
void CPet::SendMoveResult(float fX, float fY, float fZ, float fSpeed /*= 0.0f*/)
{
Packet result(MOVE_RESULT, uint8(SUCCESS));
result << m_pNpc->GetID() << fX << fZ << fY << fSpeed;
g_pMain->Send_AIServer(&result);
}
void CPet::Moving(float toX, float toY, float toZ, uint8 Speed)
{
if(this == nullptr || m_pNpc == nullptr)
return;
m_pNpc->SetPosition(toX, toY, toZ);
m_pNpc->RegisterRegion();
SendMoveResult(toX,toY,toZ,Speed);
Packet result2(WIZ_NPC_MOVE);
result2 << uint8(Speed) << m_pNpc->GetID() << m_pNpc->GetSPosX() << m_pNpc->GetSPosZ() << m_pNpc->GetSPosY() << uint16(1);
m_pNpc->SendToRegion(&result2);
LastMovedTime = uint32(UNIXTIME);
}
void CPet::SummonPet(CUser * pSessionz)
{
pSession = pSessionz;
pSession->SummonPetID = SpecialPetID;
if(pSession->SummonPetID < 1)
return ;
m_NpcState = NPC_LIVE;
m_sNid = pSession->GetSocketID() + INVALID_BAND;
m_sSid = 19019;
m_sPid = 25500;
m_sSize = 80;
m_iWeapon_1 = m_iWeapon_2 = 0;
m_bZone = pSession->GetZoneID();
m_bNation= pSession->GetNation();
m_bLevel = 1;
m_curx = pSession->m_curx;
m_curz = pSession->m_curz;
m_cury =pSession->m_cury;
m_iSellingGroup = 0 ;
m_fTotalHitrate = 0;
m_fTotalEvasionrate = 0;
m_sTotalAc = 0;
m_sTotalHit = 5;
m_byDirection = 45;
m_oSocketID = pSession->GetSocketID() + INVALID_BAND;
m_bEventRoom = pSession->m_bEventRoom;
m_sFireR = m_sColdR = m_sLightningR = 0;
m_sMagicR = m_sDiseaseR = m_sPoisonR = 0;
m_sAttack = 20;
m_sAc = 5;
m_sMaxHp = 100;
m_sMaxMp = 100;
m_sHp = 100;
m_sMp = 100;
m_bMonster = false;
g_pMain->SpawnEventNpc(m_sSid,false,m_bZone,m_curx,m_cury,m_curz,1,2,0,m_bNation,m_oSocketID,m_bEventRoom, true, GetName(), pSession->GetName(), m_Serial, pSession->GetID());
}
void CPet::GetInOut(Packet& result, uint8 bType)
{
}
void CPet::AddToRegion(int16 new_region_x, int16 new_region_z)
{
}
void CPet::OnAttack(Unit* pTarget, AttackType attackType)
{
}
void CPet::OnDefend(Unit* pAttacker, AttackType attackType)
{
}
void CPet::InsertSavedMagic(uint32 nSkillID, uint16 sDuration)
{
}
void CPet::HpChange(int amount, Unit* pAttacker, bool bSendToAI)
{
if(m_pNpc == nullptr)
return;
CUser * pUser = g_pMain->GetUserPtr(m_pNpc->UserId);
if(pUser == nullptr)
return;
Packet result(WIZ_PET);
result << uint8(1) << uint8(7) << uint16(m_pNpc->GetMaxHealth()) << uint16(m_pNpc->GetHealth());
pUser->Send(&result);
if(m_pNpc->isDead())
{
Guard lock(pUser->_unitlock);
Type9BuffMap & buffMap = pUser->m_type9BuffMap;
g_DBAgent.UpdatePetData(m_Serial,this);
// Ensure this type of skill isn't already in use.
Packet result2(WIZ_PET);
result2 << uint8(1) << uint8(5) << uint8(2) << uint16(1);
pUser->SendToRegion(&result2);
g_pMain->m_LivingPetArray.erase(m_Serial);
if (buffMap.find(8) != buffMap.end())
return;
buffMap.insert(std::make_pair(8, _BUFF_TYPE9_INFO(500117, UNIXTIME - 1)));
}
// NOTE: This will handle the death notification/looting.
if (bSendToAI)
m_pNpc->SendHpChangeToAI(m_pNpc->m_sNid, m_pNpc->nIsPet && m_pNpc->nSerial > 0 && isDead() ? -50000 : amount);
}
void CPet::Dead()
{
if(m_pNpc == nullptr)
return;
if(m_pNpc->GetHealth() > 0)
m_pNpc->HpChange(-m_pNpc->GetHealth(),nullptr,true);
}
void CPet::HpChangeMagic(int amount, Unit* pAttacker, AttributeType attributeType)
{
}
void CPet::ExpChange(int amount)
{
CUser * pUser = g_pMain->GetUserPtr(m_pNpc->UserId);
if(pUser == nullptr)
return;
uint64 MaxEXP = g_pMain->GetPetExpByLevel(m_bLevel);
m_iExp += amount;
if (m_iExp < 0)
m_iExp = 0;
else if (m_iExp > MaxEXP && m_bLevel < MAX_LEVEL_PET)
{
m_iExp -= MaxEXP;
m_bLevel++;
}else if(m_iExp > MaxEXP && m_bLevel == MAX_LEVEL_PET)
m_iExp = MaxEXP;
Packet result(WIZ_PET);
result << uint8(1) << uint8(10) << uint64(amount) << uint16((m_iExp* 10000) / g_pMain->GetPetExpByLevel(m_bLevel)) << m_bLevel << m_sSatisfaction;
pUser->Send(&result);
}
void CPet::MSpChange(int amount)
{
CUser * pUser = g_pMain->GetUserPtr(m_pNpc->UserId);
if(pUser == nullptr)
return;
m_sMp += amount;
if (m_sMp < 0)
m_sMp = 0;
else if (m_sMp > m_sMaxMp)
m_sMp = m_sMaxMp;
Packet result(WIZ_PET);
result << uint8(1) << uint8(13) << uint16(m_sMaxMp) << uint16(m_sMp);
pUser->Send(&result);
}
void CPet::UpdatePetItem()
{
CUser * pUser = g_pMain->GetUserPtr(m_pNpc->UserId);
if(pUser == nullptr)
return;
Packet result(WIZ_PET);
result.DByte();
result << uint8(1) << uint8(14) << uint32(SpecialPetID) << m_strPetID << m_sClass << m_bLevel << uint16((m_iExp* 10000) / g_pMain->GetPetExpByLevel(m_bLevel)) << uint16(m_sSatisfaction);
pUser->Send(&result);
}
void CPet::SatisfactionChange(int amount)
{
if(m_pNpc == nullptr)
return;
CUser * pUser = g_pMain->GetUserPtr(m_pNpc->UserId);
if(pUser == nullptr)
return;
m_sSatisfaction += amount;
if (m_sSatisfaction < 0)
m_sSatisfaction = 0;
else if (m_sSatisfaction > 10000)
m_sSatisfaction = 10000;
if(amount > 0)
{
Packet result(WIZ_PET);
result << uint8(1) << uint8(16) << uint16(m_sSatisfaction);
pUser->Send(&result);
}
Packet result(WIZ_PET);
result << uint8(1) << uint8(15) << uint16(m_sSatisfaction);
pUser->Send(&result);
//UpdatePetItem();
}
void CPet::StateChangeServerDirect(uint8 bType, uint32 nBuff)
{
}