Tipologie server(PvM / PvP):-
*Resursă folosită: niciuna,pur si simplu am vrut sa vad daca merge sursa compilata
*ServerFiles utilizat: chuli without game play
*Syserr:
Poză:
petsystem.cpp
#include "stdafx.h"
#include "utils.h"
#include "vector.h"
#include "char.h"
#include "sectree_manager.h"
#include "char_manager.h"
#include "mob_manager.h"
#include "PetSystem.h"
#include "../../common/VnumHelper.h"
#include "packet.h"
#include "item_manager.h"
#include "item.h"
extern int passes_per_sec;
EVENTINFO(petsystem_event_info)
{
CPetSystem* pPetSystem;
};
// PetSystemÀ» update ÇØÁÖ´Â event.
// PetSystemÀº CHRACTER_MANAGER¿¡¼ ±âÁ¸ FSMÀ¸·Î update ÇØÁÖ´Â ±âÁ¸ chracters¿Í ´Þ¸®,
// OwnerÀÇ STATE¸¦ update ÇÒ ¶§ _UpdateFollowAI ÇÔ¼ö·Î update ÇØÁØ´Ù.
// ±×·±µ¥ ownerÀÇ state¸¦ update¸¦ CHRACTER_MANAGER¿¡¼ ÇØÁֱ⠶§¹®¿¡,
// petsystemÀ» updateÇÏ´Ù°¡ petÀ» unsummonÇÏ´Â ºÎºÐ¿¡¼ ¹®Á¦°¡ »ý°å´Ù.
// (CHRACTER_MANAGER¿¡¼ update Çϸé chracter destroy°¡ pendingµÇ¾î, CPetSystem¿¡¼´Â dangling Æ÷ÀÎÅ͸¦ °¡Áö°í ÀÖ°Ô µÈ´Ù.)
// µû¶ó¼ PetSystem¸¸ ¾÷µ¥ÀÌÆ® ÇØÁÖ´Â event¸¦ ¹ß»ý½ÃÅ´.
EVENTFUNC(petsystem_update_event)
{
petsystem_event_info* info = dynamic_cast<petsystem_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "check_speedhack_event> <Factor> Null pointer" );
return 0;
}
CPetSystem* pPetSystem = info->pPetSystem;
if (NULL == pPetSystem)
return 0;
pPetSystem->Update(0);
// 0.25Ãʸ¶´Ù °»½Å.
return PASSES_PER_SEC(1) / 4;
}
/// NOTE: 1ij¸¯ÅͰ¡ ¸î°³ÀÇ ÆêÀ» °¡Áú ¼ö ÀÖ´ÂÁö Á¦ÇÑ... ij¸¯Å͸¶´Ù °³¼ö¸¦ ´Ù¸£°Ô ÇҰŶó¸é º¯¼ö·Î ³Öµî°¡... À½..
/// °¡Áú ¼ö ÀÖ´Â °³¼ö¿Í µ¿½Ã¿¡ ¼ÒȯÇÒ ¼ö ÀÖ´Â °³¼ö°¡ Ʋ¸± ¼ö Àִµ¥ ÀÌ·±°Ç ±âȹ ¾øÀ¸´Ï ÀÏ´Ü ¹«½Ã
const float PET_COUNT_LIMIT = 3;
///////////////////////////////////////////////////////////////////////////////////////
// CPetActor
///////////////////////////////////////////////////////////////////////////////////////
CPetActor::CPetActor(LPCHARACTER owner, DWORD vnum, DWORD options)
{
m_dwVnum = vnum;
m_dwVID = 0;
m_dwOptions = options;
m_dwLastActionTime = 0;
m_pkChar = 0;
m_pkOwner = owner;
m_originalMoveSpeed = 0;
m_dwSummonItemVID = 0;
m_dwSummonItemVnum = 0;
}
CPetActor::~CPetActor()
{
this->Unsummon();
m_pkOwner = 0;
}
void CPetActor::SetName(const char* name)
{
std::string petName = m_pkOwner->GetName();
if (0 != m_pkOwner &&
0 == name &&
0 != m_pkOwner->GetName())
{
petName += "'s Pet";
}
else
petName += name;
if (true == IsSummoned())
m_pkChar->SetName(petName);
m_name = petName;
}
bool CPetActor::Mount()
{
if (0 == m_pkOwner)
return false;
if (true == HasOption(EPetOption_Mountable))
m_pkOwner->MountVnum(m_dwVnum);
return m_pkOwner->GetMountVnum() == m_dwVnum;;
}
void CPetActor::Unmount()
{
if (0 == m_pkOwner)
return;
if (m_pkOwner->IsHorseRiding())
m_pkOwner->StopRiding();
}
void CPetActor::Unsummon()
{
if (true == this->IsSummoned())
{
// ¹öÇÁ »èÁ¦
this->ClearBuff();
this->SetSummonItem(NULL);
if (NULL != m_pkOwner)
m_pkOwner->ComputePoints();
if (NULL != m_pkChar)
M2_DESTROY_CHARACTER(m_pkChar);
m_pkChar = 0;
m_dwVID = 0;
}
}
DWORD CPetActor::Summon(const char* petName, LPITEM pSummonItem, bool bSpawnFar)
{
long x = m_pkOwner->GetX();
long y = m_pkOwner->GetY();
long z = m_pkOwner->GetZ();
if (true == bSpawnFar)
{
x += (number(0, 1) * 2 - 1) * number(2000, 2500);
y += (number(0, 1) * 2 - 1) * number(2000, 2500);
}
else
{
x += number(-100, 100);
y += number(-100, 100);
}
if (0 != m_pkChar)
{
m_pkChar->Show (m_pkOwner->GetMapIndex(), x, y);
m_dwVID = m_pkChar->GetVID();
return m_dwVID;
}
m_pkChar = CHARACTER_MANAGER::instance().SpawnMob(
m_dwVnum,
m_pkOwner->GetMapIndex(),
x, y, z,
false, (int)(m_pkOwner->GetRotation()+180), false);
if (0 == m_pkChar)
{
sys_err("[CPetSystem::Summon] Failed to summon the pet. (vnum: %d)", m_dwVnum);
return 0;
}
m_pkChar->SetPet();
// m_pkOwner->DetailLog();
// m_pkChar->DetailLog();
//ÆêÀÇ ±¹°¡¸¦ ÁÖÀÎÀÇ ±¹°¡·Î ¼³Á¤ÇÔ.
m_pkChar->SetEmpire(m_pkOwner->GetEmpire());
m_dwVID = m_pkChar->GetVID();
this->SetName(petName);
// SetSummonItem(pSummonItem)¸¦ ºÎ¸¥ ÈÄ¿¡ ComputePoints¸¦ ºÎ¸£¸é ¹öÇÁ Àû¿ëµÊ.
this->SetSummonItem(pSummonItem);
m_pkOwner->ComputePoints();
m_pkChar->Show(m_pkOwner->GetMapIndex(), x, y, z);
return m_dwVID;
}
bool CPetActor::_UpdatAloneActionAI(float fMinDist, float fMaxDist)
{
float fDist = number(fMinDist, fMaxDist);
float r = (float)number (0, 359);
float dest_x = GetOwner()->GetX() + fDist * cos(r);
float dest_y = GetOwner()->GetY() + fDist * sin(r);
//m_pkChar->SetRotation(number(0, 359)); // ¹æÇâÀº ·£´ýÀ¸·Î ¼³Á¤
//GetDeltaByDegree(m_pkChar->GetRotation(), fDist, &fx, &fy);
// ´À½¼ÇÑ ¸ø°¨ ¼Ó¼º üũ; ÃÖÁ¾ À§Ä¡¿Í Áß°£ À§Ä¡°¡ °¥¼ö¾ø´Ù¸é °¡Áö ¾Ê´Â´Ù.
//if (!(SECTREE_MANAGER::instance().IsMovablePosition(m_pkChar->GetMapIndex(), m_pkChar->GetX() + (int) fx, m_pkChar->GetY() + (int) fy)
// && SECTREE_MANAGER::instance().IsMovablePosition(m_pkChar->GetMapIndex(), m_pkChar->GetX() + (int) fx/2, m_pkChar->GetY() + (int) fy/2)))
// return true;
m_pkChar->SetNowWalking(true);
//if (m_pkChar->Goto(m_pkChar->GetX() + (int) fx, m_pkChar->GetY() + (int) fy))
// m_pkChar->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
if (!m_pkChar->IsStateMove() && m_pkChar->Goto(dest_x, dest_y))
m_pkChar->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
m_dwLastActionTime = get_dword_time();
return true;
}
// char_state.cpp StateHorseÇÔ¼ö ±×³É C&P -_-;
bool CPetActor::_UpdateFollowAI()
{
if (0 == m_pkChar->m_pkMobData)
{
//sys_err("[CPetActor::_UpdateFollowAI] m_pkChar->m_pkMobData is NULL");
return false;
}
// NOTE: ij¸¯ÅÍ(Æê)ÀÇ ¿ø·¡ À̵¿ ¼Óµµ¸¦ ¾Ë¾Æ¾ß Çϴµ¥, ÇØ´ç °ª(m_pkChar->m_pkMobData->m_table.sMovingSpeed)À» Á÷Á¢ÀûÀ¸·Î Á¢±ÙÇØ¼ ¾Ë¾Æ³¾ ¼öµµ ÀÖÁö¸¸
// m_pkChar->m_pkMobData °ªÀÌ invalidÇÑ °æ¿ì°¡ ÀÚÁÖ ¹ß»ýÇÔ. ÇöÀç ½Ã°£°ü°è»ó ¿øÀÎÀº ´ÙÀ½¿¡ ÆÄ¾ÇÇϰí ÀÏ´ÜÀº m_pkChar->m_pkMobData °ªÀ» ¾Æ¿¹ »ç¿ëÇÏÁö ¾Êµµ·Ï ÇÔ.
// ¿©±â¼ ¸Å¹ø °Ë»çÇÏ´Â ÀÌÀ¯´Â ÃÖÃÊ ÃʱâÈ ÇÒ ¶§ Á¤»ó °ªÀ» Á¦´ë·Î ¸ø¾ò¾î¿À´Â °æ¿ìµµ ÀÖÀ½.. -_-;; ¤Ð¤Ð¤Ð¤Ð¤Ð¤Ð¤Ð¤Ð¤Ð
if (0 == m_originalMoveSpeed)
{
const CMob* mobData = CMobManager::Instance().Get(m_dwVnum);
if (0 != mobData)
m_originalMoveSpeed = mobData->m_table.sMovingSpeed;
}
float START_FOLLOW_DISTANCE = 300.0f; // ÀÌ °Å¸® ÀÌ»ó ¶³¾îÁö¸é ÂѾư¡±â ½ÃÀÛÇÔ
float START_RUN_DISTANCE = 900.0f; // ÀÌ °Å¸® ÀÌ»ó ¶³¾îÁö¸é ¶Ù¾î¼ ÂѾư¨.
float RESPAWN_DISTANCE = 4500.f; // ÀÌ °Å¸® ÀÌ»ó ¸Ö¾îÁö¸é ÁÖÀÎ ¿·À¸·Î ¼ÒȯÇÔ.
int APPROACH = 200; // Á¢±Ù °Å¸®
bool bDoMoveAlone = true; // ij¸¯ÅÍ¿Í °¡±îÀÌ ÀÖÀ» ¶§ È¥ÀÚ ¿©±âÀú±â ¿òÁ÷ÀϰÇÁö ¿©ºÎ -_-;
bool bRun = false; // ¶Ù¾î¾ß Çϳª?
DWORD currentTime = get_dword_time();
long ownerX = m_pkOwner->GetX(); long ownerY = m_pkOwner->GetY();
long charX = m_pkChar->GetX(); long charY = m_pkChar->GetY();
float fDist = DISTANCE_APPROX(charX - ownerX, charY - ownerY);
if (fDist >= RESPAWN_DISTANCE)
{
float fOwnerRot = m_pkOwner->GetRotation() * 3.141592f / 180.f;
float fx = -APPROACH * cos(fOwnerRot);
float fy = -APPROACH * sin(fOwnerRot);
if (m_pkChar->Show(m_pkOwner->GetMapIndex(), ownerX + fx, ownerY + fy))
{
return true;
}
}
if (fDist >= START_FOLLOW_DISTANCE)
{
if( fDist >= START_RUN_DISTANCE)
{
bRun = true;
}
m_pkChar->SetNowWalking(!bRun); // NOTE: ÇÔ¼ö À̸§º¸°í ¸ØÃߴ°ÇÁÙ ¾Ë¾Ò´Âµ¥ SetNowWalking(false) ÇÏ¸é ¶Ù´Â°ÅÀÓ.. -_-;
Follow(APPROACH);
m_pkChar->SetLastAttacked(currentTime);
m_dwLastActionTime = currentTime;
}
//else
//{
// if (fabs(m_pkChar->GetRotation() - GetDegreeFromPositionXY(charX, charY, ownerX, ownerX)) > 10.f || fabs(m_pkChar->GetRotation() - GetDegreeFromPositionXY(charX, charY, ownerX, ownerX)) < 350.f)
// {
// m_pkChar->Follow(m_pkOwner, APPROACH);
// m_pkChar->SetLastAttacked(currentTime);
// m_dwLastActionTime = currentTime;
// }
//}
// Follow ÁßÀÌÁö¸¸ ÁÖÀΰú ÀÏÁ¤ °Å¸® À̳»·Î °¡±î¿öÁ³´Ù¸é ¸ØÃã
else
m_pkChar->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
//else if (currentTime - m_dwLastActionTime > number(5000, 12000))
//{
// this->_UpdatAloneActionAI(START_FOLLOW_DISTANCE / 2, START_FOLLOW_DISTANCE);
//}
return true;
}
bool CPetActor::Update(DWORD deltaTime)
{
bool bResult = true;
// Æê ÁÖÀÎÀÌ Á×¾ú°Å³ª, ¼ÒȯµÈ ÆêÀÇ »óŰ¡ ÀÌ»óÇÏ´Ù¸é ÆêÀ» ¾ø¾Ú. (NOTE: °¡²û°¡´Ù ÀÌ·± Àú·± ÀÌÀ¯·Î ¼ÒȯµÈ ÆêÀÌ DEAD »óÅ¿¡ ºüÁö´Â °æ¿ì°¡ ÀÖÀ½-_-;)
// ÆêÀ» ¼ÒȯÇÑ ¾ÆÀÌÅÛÀÌ ¾ø°Å³ª, ³»°¡ °¡Áø »óŰ¡ ¾Æ´Ï¶ó¸é ÆêÀ» ¾ø¾Ú.
if (m_pkOwner->IsDead() || (IsSummoned() && m_pkChar->IsDead())
|| NULL == ITEM_MANAGER::instance().FindByVID(this->GetSummonItemVID())
|| ITEM_MANAGER::instance().FindByVID(this->GetSummonItemVID())->GetOwner() != this->GetOwner()
)
{
this->Unsummon();
return true;
}
if (this->IsSummoned() && HasOption(EPetOption_Followable))
bResult = bResult && this->_UpdateFollowAI();
return bResult;
}
//NOTE : ÁÖÀÇ!!! MinDistance¸¦ Å©°Ô ÀâÀ¸¸é ±× º¯À§¸¸ÅÀÇ º¯Èµ¿¾ÈÀº followÇÏÁö ¾Ê´Â´Ù,
bool CPetActor::Follow(float fMinDistance)
{
// °¡·Á´Â À§Ä¡¸¦ ¹Ù¶óºÁ¾ß ÇÑ´Ù.
if( !m_pkOwner || !m_pkChar)
return false;
float fOwnerX = m_pkOwner->GetX();
float fOwnerY = m_pkOwner->GetY();
float fPetX = m_pkChar->GetX();
float fPetY = m_pkChar->GetY();
float fDist = DISTANCE_SQRT(fOwnerX - fPetX, fOwnerY - fPetY);
if (fDist <= fMinDistance)
return false;
m_pkChar->SetRotationToXY(fOwnerX, fOwnerY);
float fx, fy;
float fDistToGo = fDist - fMinDistance;
GetDeltaByDegree(m_pkChar->GetRotation(), fDistToGo, &fx, &fy);
if (!m_pkChar->Goto((int)(fPetX+fx+0.5f), (int)(fPetY+fy+0.5f)) )
return false;
m_pkChar->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0, 0);
return true;
}
void CPetActor::SetSummonItem (LPITEM pItem)
{
if (NULL == pItem)
{
m_dwSummonItemVID = 0;
m_dwSummonItemVnum = 0;
return;
}
m_dwSummonItemVID = pItem->GetVID();
m_dwSummonItemVnum = pItem->GetVnum();
}
void CPetActor::GiveBuff()
{
// ÆÄȲ Æê ¹öÇÁ´Â ´øÀü¿¡¼¸¸ ¹ß»ýÇÔ.
if (34004 == m_dwVnum || 34009 == m_dwVnum)
{
if (NULL == m_pkOwner->GetDungeon())
{
return;
}
}
LPITEM item = ITEM_MANAGER::instance().FindByVID(m_dwSummonItemVID);
if (NULL != item)
item->ModifyPoints(true);
return ;
}
void CPetActor::ClearBuff()
{
if (NULL == m_pkOwner)
return ;
TItemTable* item_proto = ITEM_MANAGER::instance().GetTable(m_dwSummonItemVnum);
if (NULL == item_proto)
return;
for (int i = 0; i < ITEM_APPLY_MAX_NUM; i++)
{
if (item_proto->aApplies.bType == APPLY_NONE)
continue;
m_pkOwner->ApplyPoint(item_proto->aApplies.bType, -item_proto->aApplies.lValue);
}
return ;
}
///////////////////////////////////////////////////////////////////////////////////////
// CPetSystem
///////////////////////////////////////////////////////////////////////////////////////
CPetSystem::CPetSystem(LPCHARACTER owner)
{
// assert(0 != owner && "[CPetSystem::CPetSystem] Invalid owner");
m_pkOwner = owner;
m_dwUpdatePeriod = 400;
m_dwLastUpdateTime = 0;
}
CPetSystem::~CPetSystem()
{
Destroy();
}
void CPetSystem::Destroy()
{
for (TPetActorMap::iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
{
CPetActor* petActor = iter->second;
if (0 != petActor)
{
delete petActor;
}
}
event_cancel(&m_pkPetSystemUpdateEvent);
m_petActorMap.clear();
}
/// Æê ½Ã½ºÅÛ ¾÷µ¥ÀÌÆ®. µî·ÏµÈ ÆêµéÀÇ AI ó¸® µîÀ» ÇÔ.
bool CPetSystem::Update(DWORD deltaTime)
{
bool bResult = true;
DWORD currentTime = get_dword_time();
// CHARACTER_MANAGER¿¡¼ ij¸¯ÅÍ·ù UpdateÇÒ ¶§ ¸Å°³º¯¼ö·Î ÁÖ´Â (Pulse¶ó°í µÇ¾îÀÖ´Â)°ªÀÌ ÀÌÀü ÇÁ·¹ÀÓ°úÀÇ ½Ã°£Â÷ÀÌÀÎÁÙ ¾Ë¾Ò´Âµ¥
// ÀüÇô ´Ù¸¥ °ªÀ̶ó¼-_-; ¿©±â¿¡ ÀÔ·ÂÀ¸·Î µé¾î¿À´Â deltaTimeÀº Àǹ̰¡ ¾øÀ½¤Ð¤Ð
if (m_dwUpdatePeriod > currentTime - m_dwLastUpdateTime)
return true;
std::vector <CPetActor*> v_garbageActor;
for (TPetActorMap::iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
{
CPetActor* petActor = iter->second;
if (0 != petActor && petActor->IsSummoned())
{
LPCHARACTER pPet = petActor->GetCharacter();
if (NULL == CHARACTER_MANAGER::instance().Find(pPet->GetVID()))
{
v_garbageActor.push_back(petActor);
}
else
{
bResult = bResult && petActor->Update(deltaTime);
}
}
}
for (std::vector<CPetActor*>::iterator it = v_garbageActor.begin(); it != v_garbageActor.end(); it++)
DeletePet(*it);
m_dwLastUpdateTime = currentTime;
return bResult;
}
/// °ü¸® ¸ñ·Ï¿¡¼ ÆêÀ» Áö¿ò
void CPetSystem::DeletePet(DWORD mobVnum)
{
TPetActorMap::iterator iter = m_petActorMap.find(mobVnum);
if (m_petActorMap.end() == iter)
{
sys_err("[CPetSystem::DeletePet] Can't find pet on my list (VNUM: %d)", mobVnum);
return;
}
CPetActor* petActor = iter->second;
if (0 == petActor)
sys_err("[CPetSystem::DeletePet] Null Pointer (petActor)");
else
delete petActor;
m_petActorMap.erase(iter);
}
/// °ü¸® ¸ñ·Ï¿¡¼ ÆêÀ» Áö¿ò
void CPetSystem::DeletePet(CPetActor* petActor)
{
for (TPetActorMap::iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
{
if (iter->second == petActor)
{
delete petActor;
m_petActorMap.erase(iter);
return;
}
}
sys_err("[CPetSystem::DeletePet] Can't find petActor(0x%x) on my list(size: %d) ", petActor, m_petActorMap.size());
}
void CPetSystem::Unsummon(DWORD vnum, bool bDeleteFromList)
{
CPetActor* actor = this->GetByVnum(vnum);
if (0 == actor)
{
sys_err("[CPetSystem::GetByVnum(%d)] Null Pointer (petActor)", vnum);
return;
}
actor->Unsummon();
if (true == bDeleteFromList)
this->DeletePet(actor);
bool bActive = false;
for (TPetActorMap::iterator it = m_petActorMap.begin(); it != m_petActorMap.end(); it++)
{
bActive |= it->second->IsSummoned();
}
if (false == bActive)
{
event_cancel(&m_pkPetSystemUpdateEvent);
m_pkPetSystemUpdateEvent = NULL;
}
}
CPetActor* CPetSystem::Summon(DWORD mobVnum, LPITEM pSummonItem, const char* petName, bool bSpawnFar, DWORD options)
{
CPetActor* petActor = this->GetByVnum(mobVnum);
// µî·ÏµÈ ÆêÀÌ ¾Æ´Ï¶ó¸é »õ·Î »ý¼º ÈÄ °ü¸® ¸ñ·Ï¿¡ µî·ÏÇÔ.
if (0 == petActor)
{
petActor = M2_NEW CPetActor(m_pkOwner, mobVnum, options);
m_petActorMap.insert(std::make_pair(mobVnum, petActor));
}
DWORD petVID = petActor->Summon(petName, pSummonItem, bSpawnFar);
if (NULL == m_pkPetSystemUpdateEvent)
{
petsystem_event_info* info = AllocEventInfo<petsystem_event_info>();
info->pPetSystem = this;
m_pkPetSystemUpdateEvent = event_create(petsystem_update_event, info, PASSES_PER_SEC(1) / 4); // 0.25ÃÊ
}
return petActor;
}
CPetActor* CPetSystem::GetByVID(DWORD vid) const
{
CPetActor* petActor = 0;
bool bFound = false;
for (TPetActorMap::const_iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
{
petActor = iter->second;
if (0 == petActor)
{
sys_err("[CPetSystem::GetByVID(%d)] Null Pointer (petActor)", vid);
continue;
}
bFound = petActor->GetVID() == vid;
if (true == bFound)
break;
}
return bFound ? petActor : 0;
}
/// µî·Ï µÈ Æê Áß¿¡¼ ÁÖ¾îÁø ¸÷ VNUMÀ» °¡Áø ¾×Å͸¦ ¹ÝȯÇÏ´Â ÇÔ¼ö.
CPetActor* CPetSystem::GetByVnum(DWORD vnum) const
{
CPetActor* petActor = 0;
TPetActorMap::const_iterator iter = m_petActorMap.find(vnum);
if (m_petActorMap.end() != iter)
petActor = iter->second;
return petActor;
}
size_t CPetSystem::CountSummoned() const
{
size_t count = 0;
for (TPetActorMap::const_iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
{
CPetActor* petActor = iter->second;
if (0 != petActor)
{
if (petActor->IsSummoned())
++count;
}
}
return count;
}
void CPetSystem::RefreshBuff()
{
for (TPetActorMap::const_iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
{
CPetActor* petActor = iter->second;
if (0 != petActor)
{
if (petActor->IsSummoned())
{
petActor->GiveBuff();
}
}
}
}questlua_item.cpp
#include "stdafx.h"
#include "questmanager.h"
#include "char.h"
#include "item.h"
#include "item_manager.h"
#include "over9refine.h"
#include "log.h"
#include "refine.h"
#undef sys_err
#ifndef __WIN32__
#define sys_err(fmt, args...) quest::CQuestManager::instance().QuestError(__FUNCTION__, __LINE__, fmt, ##args)
#else
#define sys_err(fmt, ...) quest::CQuestManager::instance().QuestError(__FUNCTION__, __LINE__, fmt, __VA_ARGS__)
#endif
namespace quest
{
//
// "item" Lua functions
//
int item_get_cell(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
if (q.GetCurrentItem())
{
lua_pushnumber(L, q.GetCurrentItem()->GetCell());
}
else
lua_pushnumber(L, 0);
return 1;
}
int item_select_cell(lua_State* L)
{
lua_pushboolean(L, 0);
if (!lua_isnumber(L, 1))
{
return 1;
}
DWORD cell = (DWORD) lua_tonumber(L, 1);
LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
LPITEM item = ch ? ch->GetInventoryItem(cell) : NULL;
if (!item)
{
return 1;
}
CQuestManager::instance().SetCurrentItem(item);
lua_pushboolean(L, 1);
return 1;
}
int item_select(lua_State* L)
{
lua_pushboolean(L, 0);
if (!lua_isnumber(L, 1))
{
return 1;
}
DWORD id = (DWORD) lua_tonumber(L, 1);
LPITEM item = ITEM_MANAGER::instance().Find(id);
if (!item)
{
return 1;
}
CQuestManager::instance().SetCurrentItem(item);
lua_pushboolean(L, 1);
return 1;
}
int item_get_id(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
if (q.GetCurrentItem())
{
lua_pushnumber(L, q.GetCurrentItem()->GetID());
}
else
lua_pushnumber(L, 0);
return 1;
}
int item_remove(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item != NULL) {
if (q.GetCurrentCharacterPtr() == item->GetOwner()) {
ITEM_MANAGER::instance().RemoveItem(item);
} else {
sys_err("Tried to remove invalid item %p", get_pointer(item));
}
q.ClearCurrentItem();
}
return 0;
}
int item_get_socket(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
if (q.GetCurrentItem() && lua_isnumber(L, 1))
{
int idx = (int) lua_tonumber(L, 1);
if (idx < 0 || idx >= ITEM_SOCKET_MAX_NUM)
lua_pushnumber(L,0);
else
lua_pushnumber(L, q.GetCurrentItem()->GetSocket(idx));
}
else
{
lua_pushnumber(L,0);
}
return 1;
}
int item_set_socket(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
if (q.GetCurrentItem() && lua_isnumber(L,1) && lua_isnumber(L,2))
{
int idx = (int) lua_tonumber(L, 1);
int value = (int) lua_tonumber(L, 2);
if (idx >=0 && idx < ITEM_SOCKET_MAX_NUM)
q.GetCurrentItem()->SetSocket(idx, value);
}
return 0;
}
int item_get_vnum(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item)
lua_pushnumber(L, item->GetVnum());
else
lua_pushnumber(L, 0);
return 1;
}
int item_has_flag(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (!lua_isnumber(L, 1))
{
sys_err("flag is not a number.");
lua_pushboolean(L, 0);
return 1;
}
if (!item)
{
lua_pushboolean(L, 0);
return 1;
}
long lCheckFlag = (long) lua_tonumber(L, 1);
lua_pushboolean(L, IS_SET(item->GetFlag(), lCheckFlag));
return 1;
}
int item_get_value(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (!item)
{
lua_pushnumber(L, 0);
return 1;
}
if (!lua_isnumber(L, 1))
{
sys_err("index is not a number");
lua_pushnumber(L, 0);
return 1;
}
int index = (int) lua_tonumber(L, 1);
if (index < 0 || index >= ITEM_VALUES_MAX_NUM)
{
sys_err("index(%d) is out of range (0..%d)", index, ITEM_VALUES_MAX_NUM);
lua_pushnumber(L, 0);
}
else
lua_pushnumber(L, item->GetValue(index));
return 1;
}
int item_set_value(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (!item)
{
lua_pushnumber(L, 0);
return 1;
}
if (false == (lua_isnumber(L, 1) && lua_isnumber(L, 2) && lua_isnumber(L, 3)))
{
sys_err("index is not a number");
lua_pushnumber(L, 0);
return 1;
}
item->SetForceAttribute(
lua_tonumber(L, 1), // index
lua_tonumber(L, 2), // apply type
lua_tonumber(L, 3) // apply value
);
return 0;
}
int item_get_name(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item)
lua_pushstring(L, item->GetName());
else
lua_pushstring(L, "");
return 1;
}
int item_get_size(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item)
lua_pushnumber(L, item->GetSize());
else
lua_pushnumber(L, 0);
return 1;
}
int item_get_count(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item)
lua_pushnumber(L, item->GetCount());
else
lua_pushnumber(L, 0);
return 1;
}
int item_get_type(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item)
lua_pushnumber(L, item->GetType());
else
lua_pushnumber(L, 0);
return 1;
}
int item_get_sub_type(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item)
lua_pushnumber(L, item->GetSubType());
else
lua_pushnumber(L, 0);
return 1;
}
int item_get_refine_vnum(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item)
lua_pushnumber(L, item->GetRefinedVnum());
else
lua_pushnumber(L, 0);
return 1;
}
int item_next_refine_vnum(lua_State* L)
{
DWORD vnum = 0;
if (lua_isnumber(L, 1))
vnum = (DWORD) lua_tonumber(L, 1);
TItemTable* pTable = ITEM_MANAGER::instance().GetTable(vnum);
if (pTable)
{
lua_pushnumber(L, pTable->dwRefinedVnum);
}
else
{
sys_err("Cannot find item table of vnum %u", vnum);
lua_pushnumber(L, 0);
}
return 1;
}
int item_get_level(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item)
lua_pushnumber(L, item->GetRefineLevel());
else
lua_pushnumber(L, 0);
return 1;
}
int item_can_over9refine(lua_State* L)
{
LPITEM item = CQuestManager::instance().GetCurrentItem();
if ( item == NULL ) return 0;
lua_pushnumber(L, COver9RefineManager::instance().canOver9Refine(item->GetVnum()));
return 1;
}
int item_change_to_over9(lua_State* L)
{
LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
LPITEM item = CQuestManager::instance().GetCurrentItem();
if ( ch == NULL || item == NULL ) return 0;
lua_pushboolean(L, COver9RefineManager::instance().Change9ToOver9(ch, item));
return 1;
}
int item_over9refine(lua_State* L)
{
LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
LPITEM item = CQuestManager::instance().GetCurrentItem();
if ( ch == NULL || item == NULL ) return 0;
lua_pushboolean(L, COver9RefineManager::instance().Over9Refine(ch, item));
return 1;
}
int item_get_over9_material_vnum(lua_State* L)
{
if ( lua_isnumber(L, 1) == true )
{
lua_pushnumber(L, COver9RefineManager::instance().GetMaterialVnum((DWORD)lua_tonumber(L, 1)));
return 1;
}
return 0;
}
int item_get_level_limit (lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
if (q.GetCurrentItem())
{
if (q.GetCurrentItem()->GetType() != ITEM_WEAPON && q.GetCurrentItem()->GetType() != ITEM_ARMOR)
{
return 0;
}
lua_pushnumber(L, q.GetCurrentItem() -> GetLevelLimit());
return 1;
}
return 0;
}
int item_start_realtime_expire(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM pItem = q.GetCurrentItem();
if (pItem)
{
pItem->StartRealTimeExpireEvent();
return 1;
}
return 0;
}
int item_copy_and_give_before_remove(lua_State* L)
{
lua_pushboolean(L, 0);
if (!lua_isnumber(L, 1))
return 1;
DWORD vnum = (DWORD)lua_tonumber(L, 1);
CQuestManager& q = CQuestManager::instance();
LPITEM pItem = q.GetCurrentItem();
LPCHARACTER pChar = q.GetCurrentCharacterPtr();
LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(vnum, 1, 0, false);
if (pkNewItem)
{
ITEM_MANAGER::CopyAllAttrTo(pItem, pkNewItem);
LogManager::instance().ItemLog(pChar, pkNewItem, "COPY SUCCESS", pkNewItem->GetName());
BYTE bCell = pItem->GetCell();
ITEM_MANAGER::instance().RemoveItem(pItem, "REMOVE (COPY SUCCESS)");
pkNewItem->AddToCharacter(pChar, TItemPos(INVENTORY, bCell));
ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem);
pkNewItem->AttrLog();
// ¼º°ø!
lua_pushboolean(L, 1);
}
return 1;
}
void RegisterITEMFunctionTable()
{
luaL_reg item_functions[] =
{
{ "get_id", item_get_id },
{ "get_cell", item_get_cell },
{ "select", item_select },
{ "select_cell", item_select_cell },
{ "remove", item_remove },
{ "get_socket", item_get_socket },
{ "set_socket", item_set_socket },
{ "get_vnum", item_get_vnum },
{ "has_flag", item_has_flag },
{ "get_value", item_get_value },
{ "set_value", item_set_value },
{ "get_name", item_get_name },
{ "get_size", item_get_size },
{ "get_count", item_get_count },
{ "get_type", item_get_type },
{ "get_sub_type", item_get_sub_type },
{ "get_refine_vnum", item_get_refine_vnum },
{ "get_level", item_get_level },
{ "next_refine_vnum", item_next_refine_vnum },
{ "can_over9refine", item_can_over9refine },
{ "change_to_over9", item_change_to_over9 },
{ "over9refine", item_over9refine },
{ "get_over9_material_vnum", item_get_over9_material_vnum },
{ "get_level_limit", item_get_level_limit },
{ "start_realtime_expire", item_start_realtime_expire },
{ "copy_and_give_before_remove", item_copy_and_give_before_remove},
{ NULL, NULL }
};
CQuestManager::instance().AddLuaFunctionTable("item", item_functions);
}
//
// "item_get_id" under!
//
int item_get_attribute_type(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item == NULL)
{
sys_err("item_get_attribute_type::can not find given item index");
lua_pushnumber(L, 0);
return 1;
}
if (!lua_isnumber(L, 1))
{
sys_err("item_get_attribute_type::number is not given!!!");
lua_pushnumber(L, 0);
return 1;
}
int iAttrIndex = (int)lua_tonumber(L, 1);
if (iAttrIndex < 0 || iAttrIndex >= ITEM_ATTRIBUTE_MAX_NUM)
{
sys_err("item_get_attribute_type::given attribute index is out of range: %d", iAttrIndex);
lua_pushnumber(L, 0);
return 1;
}
const TPlayerItemAttribute& attrItem = item->GetAttribute(iAttrIndex);
lua_pushnumber(L, attrItem.bType);
return 1;
}
int item_get_attribute_value(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPITEM item = q.GetCurrentItem();
if (item == NULL)
{
sys_err("item_get_attribute_value::can not find given item index");
lua_pushnumber(L, 0);
return 1;
}
if (!lua_isnumber(L, 1))
{
sys_err("item_get_attribute_value::number is not given!!!");
lua_pushnumber(L, 0);
return 1;
}
int iAttrIndex = (int)lua_tonumber(L, 1);
if (iAttrIndex < 0 || iAttrIndex >= ITEM_ATTRIBUTE_MAX_NUM)
{
sys_err("item_get_attribute_value::given attribute index is out of range: %d", iAttrIndex);
lua_pushnumber(L, 0);
return 1;
}
const TPlayerItemAttribute& attrItem = item->GetAttribute(iAttrIndex);
lua_pushnumber(L, attrItem.sValue);
return 1;
}
int item_get_attribute(lua_State* L)
{
LPITEM item = CQuestManager::instance().GetCurrentItem();
if (!item) return 0;
if (!lua_isnumber(L, 1))
{
sys_err("Wrong argument, need a number from range(0..%d)!", ITEM_ATTRIBUTE_MAX_NUM-2);
lua_pushnumber(L, 0);
return 1;
}
int iAttrIndex = (int)lua_tonumber(L, 1);
if (iAttrIndex < 0 || iAttrIndex >= ITEM_ATTRIBUTE_MAX_NUM-2)
{
sys_err("Invalid index %d. Index out of range(0..%d)", iAttrIndex, ITEM_ATTRIBUTE_MAX_NUM-2);
lua_pushnumber(L, 0);
return 1;
}
const TPlayerItemAttribute& AttrItem = item->GetAttribute(iAttrIndex);
lua_newtable(L);
lua_pushnumber(L, AttrItem.bType);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, AttrItem.sValue);
lua_rawseti(L, -2, 2);
return 1;
}
int item_set_attribute(lua_State* L)
{
LPITEM item = CQuestManager::instance().GetCurrentItem();
if (!item) return 0;
if (item->GetType() == ITEM_COSTUME)
{
lua_pushboolean(L, false);
return 1;
}
if (!lua_isnumber(L, 1))
{
sys_err("Wrong argument[AttrIdx] #1.");
lua_pushboolean(L, false);
return 1;
}
else if (!lua_isnumber(L, 2))
{
sys_err("Wrong argument[AttrType] #2.");
lua_pushboolean(L, false);
return 1;
}
else if (!lua_isnumber(L, 3))
{
sys_err("Wrong argument[AttrValue] #3.");
lua_pushboolean(L, false);
return 1;
}
int bAttrIndex = (int)lua_tonumber(L, 1);
if (bAttrIndex < 0 || bAttrIndex >= ITEM_ATTRIBUTE_MAX_NUM-2)
{
sys_err("Invalid AttrIndex %d. AttrIndex out of range(0..4)", bAttrIndex);
lua_pushboolean(L, false);
return 1;
}
int bAttrType = (int)lua_tonumber(L, 2);
if (bAttrType < 1 || bAttrType >= MAX_APPLY_NUM)
{
sys_err("Invalid AttrType %d. AttrType out of range(1..%d)", MAX_APPLY_NUM);
lua_pushboolean(L, false);
return 1;
}
if (item->HasAttr(bAttrType) && (item->GetAttribute(bAttrIndex).bType != bAttrType))
{
sys_err("AttrType[%d] multiplicated.", bAttrType);
lua_pushboolean(L, false);
return 1;
}
int bAttrValue = (int)lua_tonumber(L, 3);
if (bAttrValue < 1 || bAttrValue >= 32768)
{
sys_err("Invalid AttrValue %d. AttrValue should be between 1 and 32767!", bAttrValue);
lua_pushboolean(L, false);
return 1;
}
bool bRet = TRUE;
int bAttrCount = item->GetAttributeCount();
if (bAttrCount <= 4 && bAttrCount >= 0)
{
if (bAttrCount < bAttrIndex)
bAttrIndex = bAttrCount;
item->SetForceAttribute(bAttrIndex, bAttrType, bAttrValue);
}
else
bRet = FALSE;
lua_pushboolean(L, bRet);
return 1;
}
/* add to list! */
void RegisterITEMFunctionTable()
{
luaL_reg item_functions[] =
{
{ "get_attribute", item_get_attribute },
{ "set_attribute", item_set_attribute },
{ "get_attribute_type", item_get_attribute_type },
{ "get_attribute_value", item_get_attribute_value },
{ NULL, NULL }
};
CQuestManager::instance().AddLuaFunctionTable("item", item_functions);
}
}questlua_npc
#include "stdafx.h"
#include "utils.h"
#include "config.h"
#include "questmanager.h"
#include "char.h"
#include "party.h"
#include "xmas_event.h"
#include "char_manager.h"
#include "shop_manager.h"
#include "guild.h"
namespace quest
{
//
// "npc" lua functions
//
int npc_open_shop(lua_State * L)
{
int iShopVnum = 0;
if (lua_gettop(L) == 1)
{
if (lua_isnumber(L, 1))
iShopVnum = (int) lua_tonumber(L, 1);
}
if (CQuestManager::instance().GetCurrentNPCCharacterPtr())
CShopManager::instance().StartShopping(CQuestManager::instance().GetCurrentCharacterPtr(), CQuestManager::instance().GetCurrentNPCCharacterPtr(), iShopVnum);
return 0;
}
int npc_is_pc(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
if (npc && npc->IsPC())
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int npc_get_empire(lua_State * L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
if (npc)
lua_pushnumber(L, npc->GetEmpire());
else
lua_pushnumber(L, 0);
return 1;
}
int npc_get_race(lua_State * L)
{
lua_pushnumber(L, CQuestManager::instance().GetCurrentNPCRace());
return 1;
}
int npc_get_guild(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
CGuild* pGuild = NULL;
if (npc)
pGuild = npc->GetGuild();
lua_pushnumber(L, pGuild ? pGuild->GetID() : 0);
return 1;
}
int npc_get_remain_skill_book_count(lua_State* L)
{
LPCHARACTER npc = CQuestManager::instance().GetCurrentNPCCharacterPtr();
if (!npc || npc->IsPC() || npc->GetRaceNum() != xmas::MOB_SANTA_VNUM)
{
lua_pushnumber(L, 0);
return 1;
}
lua_pushnumber(L, MAX(0, npc->GetPoint(POINT_ATT_GRADE_BONUS)));
return 1;
}
int npc_dec_remain_skill_book_count(lua_State* L)
{
LPCHARACTER npc = CQuestManager::instance().GetCurrentNPCCharacterPtr();
if (!npc || npc->IsPC() || npc->GetRaceNum() != xmas::MOB_SANTA_VNUM)
{
return 0;
}
npc->SetPoint(POINT_ATT_GRADE_BONUS, MAX(0, npc->GetPoint(POINT_ATT_GRADE_BONUS)-1));
return 0;
}
int npc_get_remain_hairdye_count(lua_State* L)
{
LPCHARACTER npc = CQuestManager::instance().GetCurrentNPCCharacterPtr();
if (!npc || npc->IsPC() || npc->GetRaceNum() != xmas::MOB_SANTA_VNUM)
{
lua_pushnumber(L, 0);
return 1;
}
lua_pushnumber(L, MAX(0, npc->GetPoint(POINT_DEF_GRADE_BONUS)));
return 1;
}
int npc_dec_remain_hairdye_count(lua_State* L)
{
LPCHARACTER npc = CQuestManager::instance().GetCurrentNPCCharacterPtr();
if (!npc || npc->IsPC() || npc->GetRaceNum() != xmas::MOB_SANTA_VNUM)
{
return 0;
}
npc->SetPoint(POINT_DEF_GRADE_BONUS, MAX(0, npc->GetPoint(POINT_DEF_GRADE_BONUS)-1));
return 0;
}
int npc_is_quest(lua_State * L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
if (npc)
{
const std::string & r_st = q.GetCurrentQuestName();
if (q.GetQuestIndexByName(r_st) == npc->GetQuestBy())
{
lua_pushboolean(L, 1);
return 1;
}
}
lua_pushboolean(L, 0);
return 1;
}
int npc_kill(lua_State * L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER ch = q.GetCurrentCharacterPtr();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
ch->SetQuestNPCID(0);
if (npc)
{
npc->Dead();
}
return 0;
}
int npc_purge(lua_State * L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER ch = q.GetCurrentCharacterPtr();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
ch->SetQuestNPCID(0);
if (npc)
{
M2_DESTROY_CHARACTER(npc);
}
return 0;
}
int npc_is_near(lua_State * L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER ch = q.GetCurrentCharacterPtr();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
lua_Number dist = 10;
if (lua_isnumber(L, 1))
dist = lua_tonumber(L, 1);
if (ch == NULL || npc == NULL)
{
lua_pushboolean(L, false);
}
else
{
lua_pushboolean(L, DISTANCE_APPROX(ch->GetX() - npc->GetX(), ch->GetY() - npc->GetY()) < dist*100);
}
return 1;
}
int npc_is_near_vid(lua_State* L)
{
if (!lua_isnumber(L, 1))
{
sys_err("invalid vid");
lua_pushboolean(L, 0);
return 1;
}
CQuestManager& q = CQuestManager::instance();
LPCHARACTER ch = CHARACTER_MANAGER::instance().Find((DWORD)lua_tonumber(L, 1));
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
lua_Number dist = 10;
if (lua_isnumber(L, 2))
dist = lua_tonumber(L, 2);
if (ch == NULL || npc == NULL)
{
lua_pushboolean(L, false);
}
else
{
lua_pushboolean(L, DISTANCE_APPROX(ch->GetX() - npc->GetX(), ch->GetY() - npc->GetY()) < dist*100);
}
return 1;
}
int npc_unlock(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER ch = q.GetCurrentCharacterPtr();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
if ( npc != NULL )
{
if (npc->IsPC())
return 0;
if (npc->GetQuestNPCID() == ch->GetPlayerID())
{
npc->SetQuestNPCID(0);
}
}
return 0;
}
int npc_lock(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER ch = q.GetCurrentCharacterPtr();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
if (!npc || npc->IsPC())
{
lua_pushboolean(L, TRUE);
return 1;
}
if (npc->GetQuestNPCID() == 0 || npc->GetQuestNPCID() == ch->GetPlayerID())
{
npc->SetQuestNPCID(ch->GetPlayerID());
lua_pushboolean(L, TRUE);
}
else
{
lua_pushboolean(L, FALSE);
}
return 1;
}
int npc_get_leader_vid(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
LPPARTY party = npc->GetParty();
LPCHARACTER leader = party->GetLeader();
if (leader)
lua_pushnumber(L, leader->GetVID());
else
lua_pushnumber(L, 0);
return 1;
}
int npc_get_vid(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
LPCHARACTER npc = q.GetCurrentNPCCharacterPtr();
lua_pushnumber(L, npc->GetVID());
return 1;
}
int npc_get_vid_attack_mul(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
lua_Number vid = lua_tonumber(L, 1);
LPCHARACTER targetChar = CHARACTER_MANAGER::instance().Find(vid);
if (targetChar)
lua_pushnumber(L, targetChar->GetAttMul());
else
lua_pushnumber(L, 0);
return 1;
}
int npc_set_vid_attack_mul(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
lua_Number vid = lua_tonumber(L, 1);
lua_Number attack_mul = lua_tonumber(L, 2);
LPCHARACTER targetChar = CHARACTER_MANAGER::instance().Find(vid);
if (targetChar)
targetChar->SetAttMul(attack_mul);
return 0;
}
int npc_get_vid_damage_mul(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
lua_Number vid = lua_tonumber(L, 1);
LPCHARACTER targetChar = CHARACTER_MANAGER::instance().Find(vid);
if (targetChar)
lua_pushnumber(L, targetChar->GetDamMul());
else
lua_pushnumber(L, 0);
return 1;
}
int npc_set_vid_damage_mul(lua_State* L)
{
CQuestManager& q = CQuestManager::instance();
lua_Number vid = lua_tonumber(L, 1);
lua_Number damage_mul = lua_tonumber(L, 2);
LPCHARACTER targetChar = CHARACTER_MANAGER::instance().Find(vid);
if (targetChar)
targetChar->SetDamMul(damage_mul);
return 0;
}
void RegisterNPCFunctionTable()
{
luaL_reg npc_functions[] =
{
{ "getrace", npc_get_race },
{ "get_race", npc_get_race },
{ "open_shop", npc_open_shop },
{ "get_empire", npc_get_empire },
{ "is_pc", npc_is_pc },
{ "is_quest", npc_is_quest },
{ "kill", npc_kill },
{ "purge", npc_purge },
{ "is_near", npc_is_near },
{ "is_near_vid", npc_is_near_vid },
{ "lock", npc_lock },
{ "unlock", npc_unlock },
{ "get_guild", npc_get_guild },
{ "get_leader_vid", npc_get_leader_vid },
{ "get_vid", npc_get_vid },
{ "get_vid_attack_mul", npc_get_vid_attack_mul },
{ "set_vid_attack_mul", npc_set_vid_attack_mul },
{ "get_vid_damage_mul", npc_get_vid_damage_mul },
{ "set_vid_damage_mul", npc_set_vid_damage_mul },
// X-mas santa special
{ "get_remain_skill_book_count", npc_get_remain_skill_book_count },
{ "dec_remain_skill_book_count", npc_dec_remain_skill_book_count },
{ "get_remain_hairdye_count", npc_get_remain_hairdye_count },
{ "dec_remain_hairdye_count", npc_dec_remain_hairdye_count },
{ NULL, NULL }
};
CQuestManager::instance().AddLuaFunctionTable("npc", npc_functions);
}
};


