Bin seit gestern am Versuchen das Waffenkostüm system einzubauen aus lw im kampf gg die quarantäne bloss komme ich bei item.cpp einfach auf keinen nenner egal wie ich es versuche es kommen beim complien immer fehler meldungen den rest hab ich ohne probleme rein bekommen
Könnte mir vllt iwer das einfügen weil ich verzweifel schon langsam
Benütze Fliege Files v2.1
HowTo :
Original :
Danke im Vorraus
Discord : IlIllIIll#2993
Könnte mir vllt iwer das einfügen weil ich verzweifel schon langsam
Benütze Fliege Files v2.1
HowTo :
int CItem::FindEquipCell(LPCHARACTER ch, int iCandidateCell)
{
[..]
else if (GetType() == ITEM_COSTUME)
{
if (GetSubType() == COSTUME_BODY)
return WEAR_COSTUME_BODY;
else if (GetSubType() == COSTUME_HAIR)
return WEAR_COSTUME_HAIR;
#ifdef COSTUME_WEAPON
else if (GetSubType() == COSTUME_WEAPON_SWORD ||
GetSubType() == COSTUME_WEAPON_DAGGER ||
GetSubType() == COSTUME_WEAPON_BOW ||
GetSubType() == COSTUME_WEAPON_TWO_HANDED ||
GetSubType() == COSTUME_WEAPON_BELL ||
GetSubType() == COSTUME_WEAPON_FAN ||
GetSubType() == COSTUME_WEAPON_CLAW)
return WEAR_COSTUME_WEAPON;
#endif
}
else if (GetType() == ITEM_RING)
{
if (ch->GetWear(WEAR_RING1))
return WEAR_RING2;
else
return WEAR_RING1;
}
[..]
}
void CItem::ModifyPoints(bool bAdd)
{
[..]
switch (m_pProto->bType)
{
[..]
case ITEM_WEAPON:
{
#ifdef COSTUME_WEAPON
if (0 != m_pOwner->GetWear(WEAR_COSTUME_WEAPON))
break;
#endif
if (bAdd)
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, GetVnum());
}
else
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, m_pOwner->GetOriginalPart(PART_WEAPON));
}
break;
[..]
// ÄÚ˝şĂő ľĆŔĚĹŰ ŔÔľúŔ» ¶§ Äł¸ŻĹÍ parts Á¤ş¸ ĽĽĆĂ. ±âÁ¸ ˝şĹ¸ŔĎ´ë·Î Ăß°ˇÇÔ..
case ITEM_COSTUME:
{
DWORD toSetValue = this->GetVnum();
EParts toSetPart = PART_MAX_NUM;
// °©żĘ ÄÚ˝şĂő
if (GetSubType() == COSTUME_BODY)
{
toSetPart = PART_MAIN;
if (false == bAdd)
{
// ÄÚ˝şĂő °©żĘŔ» ąţľúŔ» ¶§ żř·ˇ °©żĘŔ» ŔÔ°í ŔÖľú´Ů¸é ±× °©żĘŔ¸·Î look ĽĽĆĂ, ŔÔÁö ľĘľŇ´Ů¸é default look
const CItem* pArmor = m_pOwner->GetWear(WEAR_BODY);
toSetValue = (NULL != pArmor) ? pArmor->GetVnum() : m_pOwner->GetOriginalPart(PART_MAIN);
}
}
// Çěľî ÄÚ˝şĂő
else if (GetSubType() == COSTUME_HAIR)
{
toSetPart = PART_HAIR;
// ÄÚ˝şĂő Çěľî´Â shape°ŞŔ» item protoŔÇ value3żˇ ĽĽĆĂÇϵµ·Ď ÇÔ. ĆŻş°ÇŃ ŔĚŔŻ´Â ľř°í ±âÁ¸ °©żĘ(ARMOR_BODY)ŔÇ shape°ŞŔĚ ÇÁ·ÎĹäŔÇ value3żˇ ŔÖľîĽ* Çěľîµµ °°ŔĚ value3Ŕ¸·Î ÇÔ.
// [NOTE] °©żĘŔş ľĆŔĚĹŰ vnumŔ» ş¸ł»°í Çěľî´Â shape(value3)°ŞŔ» ş¸ł»´Â ŔĚŔŻ´Â.. ±âÁ¸ ˝Ă˝şĹŰŔĚ ±×·¸°Ô µÇľîŔÖŔ˝...
toSetValue = (true == bAdd) ? this->GetValue(3) : 0;
}
#ifdef COSTUME_WEAPON
else if (GetSubType() == COSTUME_WEAPON_SWORD ||
GetSubType() == COSTUME_WEAPON_DAGGER ||
GetSubType() == COSTUME_WEAPON_BOW ||
GetSubType() == COSTUME_WEAPON_TWO_HANDED ||
GetSubType() == COSTUME_WEAPON_BELL ||
GetSubType() == COSTUME_WEAPON_FAN ||
GetSubType() == COSTUME_WEAPON_CLAW)
{
toSetPart = PART_WEAPON;
if (false == bAdd)
{
// 코1oAo 갑?EA?1???때 ?o? 갑?EA?A蹈?A?駭U면 그 갑?EA막?look 11AA, A讀?3E3O?면 default look
toSetValue = (NULL != pWeapon) ? pWeapon->GetVnum() : m_pOwner->GetOriginalPart(PART_WEAPON);
}
}
#endif const CItem* pWeapon = m_pOwner->GetWear(WEAR_WEAPON);
if (PART_MAX_NUM != toSetPart)
{
m_pOwner->SetPart((BYTE)toSetPart, toSetValue);
m_pOwner->UpdatePacket();
}
}
[..]
}
}
{
[..]
else if (GetType() == ITEM_COSTUME)
{
if (GetSubType() == COSTUME_BODY)
return WEAR_COSTUME_BODY;
else if (GetSubType() == COSTUME_HAIR)
return WEAR_COSTUME_HAIR;
#ifdef COSTUME_WEAPON
else if (GetSubType() == COSTUME_WEAPON_SWORD ||
GetSubType() == COSTUME_WEAPON_DAGGER ||
GetSubType() == COSTUME_WEAPON_BOW ||
GetSubType() == COSTUME_WEAPON_TWO_HANDED ||
GetSubType() == COSTUME_WEAPON_BELL ||
GetSubType() == COSTUME_WEAPON_FAN ||
GetSubType() == COSTUME_WEAPON_CLAW)
return WEAR_COSTUME_WEAPON;
#endif
}
else if (GetType() == ITEM_RING)
{
if (ch->GetWear(WEAR_RING1))
return WEAR_RING2;
else
return WEAR_RING1;
}
[..]
}
void CItem::ModifyPoints(bool bAdd)
{
[..]
switch (m_pProto->bType)
{
[..]
case ITEM_WEAPON:
{
#ifdef COSTUME_WEAPON
if (0 != m_pOwner->GetWear(WEAR_COSTUME_WEAPON))
break;
#endif
if (bAdd)
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, GetVnum());
}
else
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, m_pOwner->GetOriginalPart(PART_WEAPON));
}
break;
[..]
// ÄÚ˝şĂő ľĆŔĚĹŰ ŔÔľúŔ» ¶§ Äł¸ŻĹÍ parts Á¤ş¸ ĽĽĆĂ. ±âÁ¸ ˝şĹ¸ŔĎ´ë·Î Ăß°ˇÇÔ..
case ITEM_COSTUME:
{
DWORD toSetValue = this->GetVnum();
EParts toSetPart = PART_MAX_NUM;
// °©żĘ ÄÚ˝şĂő
if (GetSubType() == COSTUME_BODY)
{
toSetPart = PART_MAIN;
if (false == bAdd)
{
// ÄÚ˝şĂő °©żĘŔ» ąţľúŔ» ¶§ żř·ˇ °©żĘŔ» ŔÔ°í ŔÖľú´Ů¸é ±× °©żĘŔ¸·Î look ĽĽĆĂ, ŔÔÁö ľĘľŇ´Ů¸é default look
const CItem* pArmor = m_pOwner->GetWear(WEAR_BODY);
toSetValue = (NULL != pArmor) ? pArmor->GetVnum() : m_pOwner->GetOriginalPart(PART_MAIN);
}
}
// Çěľî ÄÚ˝şĂő
else if (GetSubType() == COSTUME_HAIR)
{
toSetPart = PART_HAIR;
// ÄÚ˝şĂő Çěľî´Â shape°ŞŔ» item protoŔÇ value3żˇ ĽĽĆĂÇϵµ·Ď ÇÔ. ĆŻş°ÇŃ ŔĚŔŻ´Â ľř°í ±âÁ¸ °©żĘ(ARMOR_BODY)ŔÇ shape°ŞŔĚ ÇÁ·ÎĹäŔÇ value3żˇ ŔÖľîĽ* Çěľîµµ °°ŔĚ value3Ŕ¸·Î ÇÔ.
// [NOTE] °©żĘŔş ľĆŔĚĹŰ vnumŔ» ş¸ł»°í Çěľî´Â shape(value3)°ŞŔ» ş¸ł»´Â ŔĚŔŻ´Â.. ±âÁ¸ ˝Ă˝şĹŰŔĚ ±×·¸°Ô µÇľîŔÖŔ˝...
toSetValue = (true == bAdd) ? this->GetValue(3) : 0;
}
#ifdef COSTUME_WEAPON
else if (GetSubType() == COSTUME_WEAPON_SWORD ||
GetSubType() == COSTUME_WEAPON_DAGGER ||
GetSubType() == COSTUME_WEAPON_BOW ||
GetSubType() == COSTUME_WEAPON_TWO_HANDED ||
GetSubType() == COSTUME_WEAPON_BELL ||
GetSubType() == COSTUME_WEAPON_FAN ||
GetSubType() == COSTUME_WEAPON_CLAW)
{
toSetPart = PART_WEAPON;
if (false == bAdd)
{
// 코1oAo 갑?EA?1???때 ?o? 갑?EA?A蹈?A?駭U면 그 갑?EA막?look 11AA, A讀?3E3O?면 default look
toSetValue = (NULL != pWeapon) ? pWeapon->GetVnum() : m_pOwner->GetOriginalPart(PART_WEAPON);
}
}
#endif const CItem* pWeapon = m_pOwner->GetWear(WEAR_WEAPON);
if (PART_MAX_NUM != toSetPart)
{
m_pOwner->SetPart((BYTE)toSetPart, toSetValue);
m_pOwner->UpdatePacket();
}
}
[..]
}
}
Original :
#include "stdafx.h"
#include "utils.h"
#include "config.h"
#include "char.h"
#include "desc.h"
#include "sectree_manager.h"
#include "packet.h"
#include "protocol.h"
#include "log.h"
#include "skill.h"
#include "unique_item.h"
#include "profiler.h"
#include "marriage.h"
#include "item_addon.h"
#include "dev_log.h"
#include "locale_service.h"
#include "item.h"
#include "item_manager.h"
#include "affect.h"
#include "DragonSoul.h"
#include "buff_on_attributes.h"
#include "belt_inventory_helper.h"
#include "../../common/VnumHelper.h"
CItem::CItem(DWORD dwVnum)
: m_dwVnum(dwVnum), m_bWindow(0), m_dwID(0), m_bEquipped(false), m_dwVID(0), m_wCell(0), m_dwCount(0), m_lFlag(0), m_dwLastOwnerPID(0),
m_bExchanging(false), m_pkDestroyEvent(NULL), m_pkUniqueExpireEvent(NULL), m_pkTimerBasedOnWearExpireEvent(NULL), m_pkRealTimeExpireEvent(NULL),
m_pkExpireEvent(NULL),
m_pkAccessorySocketExpireEvent(NULL), m_pkOwnershipEvent(NULL), m_dwOwnershipPID(0), m_bSkipSave(false), m_isLocked(false),
m_dwMaskVnum(0), m_dwSIGVnum (0)
{
memset( &m_alSockets, 0, sizeof(m_alSockets) );
memset( &m_aAttr, 0, sizeof(m_aAttr) );
}
CItem::~CItem()
{
Destroy();
}
void CItem::Initialize()
{
CEntity::Initialize(ENTITY_ITEM);
m_bWindow = RESERVED_WINDOW;
m_pOwner = NULL;
m_dwID = 0;
m_bEquipped = false;
m_dwVID = m_wCell = m_dwCount = m_lFlag = 0;
m_pProto = NULL;
m_bExchanging = false;
memset(&m_alSockets, 0, sizeof(m_alSockets));
memset(&m_aAttr, 0, sizeof(m_aAttr));
m_pkDestroyEvent = NULL;
m_pkOwnershipEvent = NULL;
m_dwOwnershipPID = 0;
m_pkUniqueExpireEvent = NULL;
m_pkTimerBasedOnWearExpireEvent = NULL;
m_pkRealTimeExpireEvent = NULL;
m_pkAccessorySocketExpireEvent = NULL;
m_bSkipSave = false;
m_dwLastOwnerPID = 0;
}
void CItem::Destroy()
{
event_cancel(&m_pkDestroyEvent);
event_cancel(&m_pkOwnershipEvent);
event_cancel(&m_pkUniqueExpireEvent);
event_cancel(&m_pkTimerBasedOnWearExpireEvent);
event_cancel(&m_pkRealTimeExpireEvent);
event_cancel(&m_pkAccessorySocketExpireEvent);
CEntity::Destroy();
if (GetSectree())
GetSectree()->RemoveEntity(this);
}
EVENTFUNC(item_destroy_event)
{
item_event_info* info = dynamic_cast<item_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "item_destroy_event> <Factor> Null pointer" );
return 0;
}
LPITEM pkItem = info->item;
if (pkItem->GetOwner())
sys_err("item_destroy_event: Owner exist. (item %s owner %s)", pkItem->GetName(), pkItem->GetOwner()->GetName());
pkItem->SetDestroyEvent(NULL);
M2_DESTROY_ITEM(pkItem);
return 0;
}
void CItem::SetDestroyEvent(LPEVENT pkEvent)
{
m_pkDestroyEvent = pkEvent;
}
void CItem::StartDestroyEvent(int iSec)
{
if (m_pkDestroyEvent)
return;
item_event_info* info = AllocEventInfo<item_event_info>();
info->item = this;
SetDestroyEvent(event_create(item_destroy_event, info, PASSES_PER_SEC(iSec)));
}
void CItem::EncodeInsertPacket(LPENTITY ent)
{
LPDESC d;
if (!(d = ent->GetDesc()))
return;
const PIXEL_POSITION & c_pos = GetXYZ();
struct packet_item_ground_add pack;
pack.bHeader = HEADER_GC_ITEM_GROUND_ADD;
pack.x = c_pos.x;
pack.y = c_pos.y;
pack.z = c_pos.z;
pack.dwVnum = GetVnum();
pack.dwVID = m_dwVID;
//pack.count = m_dwCount;
d->Packet(&pack, sizeof(pack));
if (m_pkOwnershipEvent != NULL)
{
item_event_info * info = dynamic_cast<item_event_info *>(m_pkOwnershipEvent->info);
if ( info == NULL )
{
sys_err( "CItem::EncodeInsertPacket> <Factor> Null pointer" );
return;
}
TPacketGCItemOwnership p;
p.bHeader = HEADER_GC_ITEM_OWNERSHIP;
p.dwVID = m_dwVID;
strlcpy(p.szName, info->szOwnerName, sizeof(p.szName));
d->Packet(&p, sizeof(TPacketGCItemOwnership));
}
}
void CItem::EncodeRemovePacket(LPENTITY ent)
{
LPDESC d;
if (!(d = ent->GetDesc()))
return;
struct packet_item_ground_del pack;
pack.bHeader = HEADER_GC_ITEM_GROUND_DEL;
pack.dwVID = m_dwVID;
d->Packet(&pack, sizeof(pack));
sys_log(2, "Item::EncodeRemovePacket %s to %s", GetName(), ((LPCHARACTER) ent)->GetName());
}
void CItem::SetProto(const TItemTable * table)
{
assert(table != NULL);
m_pProto = table;
SetFlag(m_pProto->dwFlags);
}
void CItem::UsePacketEncode(LPCHARACTER ch, LPCHARACTER victim, struct packet_item_use *packet)
{
if (!GetVnum())
return;
packet->header = HEADER_GC_ITEM_USE;
packet->ch_vid = ch->GetVID();
packet->victim_vid = victim->GetVID();
packet->Cell = TItemPos(GetWindow(), m_wCell);
packet->vnum = GetVnum();
}
void CItem::RemoveFlag(long bit)
{
REMOVE_BIT(m_lFlag, bit);
}
void CItem::AddFlag(long bit)
{
SET_BIT(m_lFlag, bit);
}
void CItem::UpdatePacket()
{
if (!m_pOwner || !m_pOwner->GetDesc())
return;
TPacketGCItemUpdate pack;
pack.header = HEADER_GC_ITEM_UPDATE;
pack.Cell = TItemPos(GetWindow(), m_wCell);
pack.count = m_dwCount;
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
pack.alSockets[i] = m_alSockets[i];
thecore_memcpy(pack.aAttr, GetAttributes(), sizeof(pack.aAttr));
sys_log(2, "UpdatePacket %s -> %s", GetName(), m_pOwner->GetName());
m_pOwner->GetDesc()->Packet(&pack, sizeof(pack));
}
DWORD CItem::GetCount()
{
if (GetType() == ITEM_ELK) return MIN(m_dwCount, INT_MAX);
else
{
return MIN(m_dwCount, 200);
}
}
bool CItem::SetCount(DWORD count)
{
if (GetType() == ITEM_ELK)
{
m_dwCount = MIN(count, INT_MAX);
}
else
{
m_dwCount = MIN(count, ITEM_MAX_COUNT);
}
if (count == 0 && m_pOwner)
{
if (GetSubType() == USE_ABILITY_UP || GetSubType() == USE_POTION || GetVnum() == 70020)
{
LPCHARACTER pOwner = GetOwner();
WORD wCell = GetCell();
RemoveFromCharacter();
if (!IsDragonSoul())
{
LPITEM pItem = pOwner->FindSpecifyItem(GetVnum());
if (NULL != pItem)
{
pOwner->ChainQuickslotItem(pItem, QUICKSLOT_TYPE_ITEM, wCell);
}
else
{
pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, wCell, 255);
}
}
M2_DESTROY_ITEM(this);
}
else
{
if (!IsDragonSoul())
{
m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, m_wCell, 255);
}
M2_DESTROY_ITEM(RemoveFromCharacter());
}
return false;
}
UpdatePacket();
Save();
return true;
}
LPITEM CItem::RemoveFromCharacter()
{
if (!m_pOwner)
{
sys_err("Item::RemoveFromCharacter owner null");
return (this);
}
LPCHARACTER pOwner = m_pOwner;
if (m_bEquipped) // ÀåÂøµÇ¾ú´Â°¡?
{
Unequip();
//pOwner->UpdatePacket();
SetWindow(RESERVED_WINDOW);
Save();
return (this);
}
else
{
if (GetWindow() != SAFEBOX && GetWindow() != MALL)
{
if (IsDragonSoul())
{
if (m_wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
sys_err("CItem::RemoveFromCharacter: pos >= DRAGON_SOUL_INVENTORY_MAX_NUM");
else
pOwner->SetItem(TItemPos(m_bWindow, m_wCell), NULL);
}
else
{
TItemPos cell(INVENTORY, m_wCell);
if (false == cell.IsDefaultInventoryPosition() && false == cell.IsBeltInventoryPosition()) // ¾Æ´Ï¸é ¼ÒÁöǰ¿¡?
sys_err("CItem::RemoveFromCharacter: Invalid Item Position");
else
{
pOwner->SetItem(cell, NULL);
}
}
}
m_pOwner = NULL;
m_wCell = 0;
SetWindow(RESERVED_WINDOW);
Save();
return (this);
}
}
bool CItem::AddToCharacter(LPCHARACTER ch, TItemPos Cell)
{
assert(GetSectree() == NULL);
assert(m_pOwner == NULL);
WORD pos = Cell.cell;
BYTE window_type = Cell.window_type;
if (INVENTORY == window_type)
{
if (m_wCell >= INVENTORY_MAX_NUM && BELT_INVENTORY_SLOT_START > m_wCell)
{
sys_err("CItem::AddToCharacter: cell overflow: %s to %s cell %d", m_pProto->szName, ch->GetName(), m_wCell);
return false;
}
}
else if (DRAGON_SOUL_INVENTORY == window_type)
{
if (m_wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
{
sys_err("CItem::AddToCharacter: cell overflow: %s to %s cell %d", m_pProto->szName, ch->GetName(), m_wCell);
return false;
}
}
if (ch->GetDesc())
m_dwLastOwnerPID = ch->GetPlayerID();
event_cancel(&m_pkDestroyEvent);
ch->SetItem(TItemPos(window_type, pos), this);
m_pOwner = ch;
Save();
return true;
}
LPITEM CItem::RemoveFromGround()
{
if (GetSectree())
{
SetOwnership(NULL);
GetSectree()->RemoveEntity(this);
ViewCleanup();
Save();
}
return (this);
}
bool CItem::AddToGround(long lMapIndex, const PIXEL_POSITION & pos, bool skipOwnerCheck)
{
if (0 == lMapIndex)
{
sys_err("wrong map index argument: %d", lMapIndex);
return false;
}
if (GetSectree())
{
sys_err("sectree already assigned");
return false;
}
if (!skipOwnerCheck && m_pOwner)
{
sys_err("owner pointer not null");
return false;
}
LPSECTREE tree = SECTREE_MANAGER::instance().Get(lMapIndex, pos.x, pos.y);
if (!tree)
{
sys_err("cannot find sectree by %dx%d", pos.x, pos.y);
return false;
}
//tree->Touch();
SetWindow(GROUND);
SetXYZ(pos.x, pos.y, pos.z);
tree->InsertEntity(this);
UpdateSectree();
Save();
return true;
}
bool CItem::DistanceValid(LPCHARACTER ch)
{
if (!GetSectree())
return false;
int iDist = DISTANCE_APPROX(GetX() - ch->GetX(), GetY() - ch->GetY());
if (iDist > 300)
return false;
return true;
}
bool CItem::CanUsedBy(LPCHARACTER ch)
{
// Anti flag check
switch (ch->GetJob())
{
case JOB_WARRIOR:
if (GetAntiFlag() & ITEM_ANTIFLAG_WARRIOR)
return false;
break;
case JOB_ASSASSIN:
if (GetAntiFlag() & ITEM_ANTIFLAG_ASSASSIN)
return false;
break;
case JOB_SHAMAN:
if (GetAntiFlag() & ITEM_ANTIFLAG_SHAMAN)
return false;
break;
case JOB_SURA:
if (GetAntiFlag() & ITEM_ANTIFLAG_SURA)
return false;
break;
}
return true;
}
int CItem::FindEquipCell(LPCHARACTER ch, int iCandidateCell)
{
// ÄÚ½ºÃõ ¾ÆÀÌÅÛ(ITEM_COSTUME)Àº WearFlag ¾ø¾îµµ µÊ. (sub typeÀ¸·Î Âø¿ëÀ§Ä¡ ±¸ºÐ. ±ÍÂú°Ô ¶Ç wear flag ÁÙ Çʿ䰡 ÀÖ³ª..)
// ¿ëÈ¥¼®(ITEM_DS, ITEM_SPECIAL_DS)µµ SUB_TYPEÀ¸·Î ±¸ºÐ. ½Å±Ô ¹ÝÁö, º§Æ®´Â ITEM_TYPEÀ¸·Î ±¸ºÐ -_-
if ((0 == GetWearFlag() || ITEM_TOTEM == GetType()) && ITEM_COSTUME != GetType() && ITEM_DS != GetType() && ITEM_SPECIAL_DS != GetType() && ITEM_RING != GetType() && ITEM_BELT != GetType())
return -1;
// ¿ëÈ¥¼® ½½·ÔÀ» WEAR·Î ó¸®ÇÒ ¼ö°¡ ¾ø¾î¼*(WEAR´Â ÃÖ´ë 32°³±îÁö °¡´ÉÇѵ¥ ¿ëÈ¥¼®À» Ãß°¡Çϸé 32°¡ ³Ñ´Â´Ù.)
// Àκ¥Å丮ÀÇ Æ¯Á¤ À§Ä¡((INVENTORY_MAX_NUM + WEAR_MAX_NUM)ºÎÅÍ (INVENTORY_MAX_NUM + WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX - 1)±îÁö)¸¦
// ¿ëÈ¥¼® ½½·ÔÀ¸·Î Á¤ÇÔ.
// return ÇÒ ¶§¿¡, INVENTORY_MAX_NUMÀ» »« ÀÌÀ¯´Â,
// º»·¡ WearCellÀÌ INVENTORY_MAX_NUM¸¦ »©°í return Çϱ⠶§¹®.
if (GetType() == ITEM_DS || GetType() == ITEM_SPECIAL_DS)
{
if (iCandidateCell < 0)
{
return WEAR_MAX_NUM + GetSubType();
}
else
{
for (int i = 0; i < DRAGON_SOUL_DECK_MAX_NUM; i++)
{
if (WEAR_MAX_NUM + i * DS_SLOT_MAX + GetSubType() == iCandidateCell)
{
return iCandidateCell;
}
}
return -1;
}
}
else if (GetType() == ITEM_COSTUME)
{
if (GetSubType() == COSTUME_BODY)
return WEAR_COSTUME_BODY;
else if (GetSubType() == COSTUME_HAIR)
return WEAR_COSTUME_HAIR;
}
else if (GetType() == ITEM_RING)
{
if (ch->GetWear(WEAR_RING1))
return WEAR_RING2;
else
return WEAR_RING1;
}
else if (GetType() == ITEM_BELT)
return WEAR_BELT;
else if (GetWearFlag() & WEARABLE_BODY)
return WEAR_BODY;
else if (GetWearFlag() & WEARABLE_HEAD)
return WEAR_HEAD;
else if (GetWearFlag() & WEARABLE_FOOTS)
return WEAR_FOOTS;
else if (GetWearFlag() & WEARABLE_WRIST)
return WEAR_WRIST;
else if (GetWearFlag() & WEARABLE_WEAPON)
return WEAR_WEAPON;
else if (GetWearFlag() & WEARABLE_SHIELD)
return WEAR_SHIELD;
else if (GetWearFlag() & WEARABLE_NECK)
return WEAR_NECK;
else if (GetWearFlag() & WEARABLE_EAR)
return WEAR_EAR;
else if (GetWearFlag() & WEARABLE_ARROW)
return WEAR_ARROW;
else if (GetWearFlag() & WEARABLE_UNIQUE)
{
if (ch->GetWear(WEAR_UNIQUE1))
return WEAR_UNIQUE2;
else
return WEAR_UNIQUE1;
}
// ¼öÁý Äù½ºÆ®¸¦ À§ÇÑ ¾ÆÀÌÅÛÀÌ ¹ÚÈ÷´Â°÷À¸·Î Çѹø ¹ÚÈ÷¸é Àý´ë –E¼ö ¾ø´Ù.
else if (GetWearFlag() & WEARABLE_ABILITY)
{
if (!ch->GetWear(WEAR_ABILITY1))
{
return WEAR_ABILITY1;
}
else if (!ch->GetWear(WEAR_ABILITY2))
{
return WEAR_ABILITY2;
}
else if (!ch->GetWear(WEAR_ABILITY3))
{
return WEAR_ABILITY3;
}
else if (!ch->GetWear(WEAR_ABILITY4))
{
return WEAR_ABILITY4;
}
else if (!ch->GetWear(WEAR_ABILITY5))
{
return WEAR_ABILITY5;
}
else if (!ch->GetWear(WEAR_ABILITY6))
{
return WEAR_ABILITY6;
}
else if (!ch->GetWear(WEAR_ABILITY7))
{
return WEAR_ABILITY7;
}
else if (!ch->GetWear(WEAR_ABILITY8))
{
return WEAR_ABILITY8;
}
else
{
return -1;
}
}
return -1;
}
void CItem::ModifyPoints(bool bAdd)
{
int accessoryGrade;
// ¹«±â¿Í °©¿Ê¸¸ ¼ÒÄÏÀ» Àû¿ë½ÃŲ´Ù.
if (false == IsAccessoryForSocket())
{
if (m_pProto->bType == ITEM_WEAPON || m_pProto->bType == ITEM_ARMOR)
{
// ¼ÒÄÏÀÌ ¼Ó¼º°*È*¿¡ »ç¿ëµÇ´Â °æ¿ì Àû¿ëÇÏÁö ¾Ê´Â´Ù (ARMOR_WRIST ARMOR_NECK ARMOR_EAR)
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
{
DWORD dwVnum;
if ((dwVnum = GetSocket(i)) <= 2)
continue;
TItemTable * p = ITEM_MANAGER::instance().GetTable(dwVnum);
if (!p)
{
sys_err("cannot find table by vnum %u", dwVnum);
continue;
}
if (ITEM_METIN == p->bType)
{
//m_pOwner->ApplyPoint(p->alValues[0], bAdd ? p->alValues[1] : -p->alValues[1]);
for (int i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
{
if (p->aApplies[i].bType == APPLY_NONE)
continue;
if (p->aApplies[i].bType == APPLY_SKILL)
m_pOwner->ApplyPoint(p->aApplies[i].bType, bAdd ? p->aApplies[i].lValue : p->aApplies[i].lValue ^ 0x00800000);
else
m_pOwner->ApplyPoint(p->aApplies[i].bType, bAdd ? p->aApplies[i].lValue : -p->aApplies[i].lValue);
}
}
}
}
accessoryGrade = 0;
}
else
{
accessoryGrade = MIN(GetAccessorySocketGrade(), ITEM_ACCESSORY_SOCKET_MAX_NUM);
}
for (int i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
{
if (m_pProto->aApplies[i].bType == APPLY_NONE)
continue;
long value = m_pProto->aApplies[i].lValue;
if (m_pProto->aApplies[i].bType == APPLY_SKILL)
{
m_pOwner->ApplyPoint(m_pProto->aApplies[i].bType, bAdd ? value : value ^ 0x00800000);
}
else
{
if (0 != accessoryGrade)
value += MAX(accessoryGrade, value * aiAccessorySocketEffectivePct[accessoryGrade] / 100);
m_pOwner->ApplyPoint(m_pProto->aApplies[i].bType, bAdd ? value : -value);
}
}
// Ãʽ´ÞÀÇ ¹ÝÁö, ÇÒ·ÎÀ© »çÅÁ, ÇູÀÇ ¹ÝÁö, ¿µ¿øÇÑ »ç¶ûÀÇ Ææ´øÆ®ÀÇ °æ¿ì
// ±âÁ¸ÀÇ Çϵå ÄÚµùÀ¸·Î °*Á¦·Î ¼Ó¼ºÀ» ºÎ¿©ÇßÁö¸¸,
// ±× ºÎºÐÀ» Á¦°ÅÇϰí special item group Å×ÀÌºí¿¡¼* ¼Ó¼ºÀ» ºÎ¿©Çϵµ·Ï º¯°æÇÏ¿´´Ù.
// ÇÏÁö¸¸ Çϵå ÄÚµùµÇ¾îÀÖÀ» ¶§ »ý¼ºµÈ ¾ÆÀÌÅÛÀÌ ³²¾ÆÀÖÀ» ¼öµµ ÀÖ¾î¼* Ư¼öó¸® ÇØ³õ´Â´Ù.
// ÀÌ ¾ÆÀÌÅÛµéÀÇ °æ¿ì, ¹Ø¿¡ ITEM_UNIQUEÀÏ ¶§ÀÇ Ã³¸®·Î ¼Ó¼ºÀÌ ºÎ¿©µÇ±â ¶§¹®¿¡,
// ¾ÆÀÌÅÛ¿¡ ¹ÚÇôÀÖ´Â attribute´Â Àû¿ëÇÏÁö ¾Ê°í ³Ñ¾î°£´Ù.
if (true == CItemVnumHelper::IsRamadanMoonRing(GetVnum()) || true == CItemVnumHelper::IsHalloweenCandy(GetVnum())
|| true == CItemVnumHelper::IsHappinessRing(GetVnum()) || true == CItemVnumHelper::IsLovePendant(GetVnum()))
{
// Do not anything.
}
else
{
for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
{
if (GetAttributeType(i))
{
const TPlayerItemAttribute& ia = GetAttribute(i);
if (ia.bType == APPLY_SKILL)
m_pOwner->ApplyPoint(ia.bType, bAdd ? ia.sValue : ia.sValue ^ 0x00800000);
else
m_pOwner->ApplyPoint(ia.bType, bAdd ? ia.sValue : -ia.sValue);
}
}
}
switch (m_pProto->bType)
{
case ITEM_PICK:
case ITEM_ROD:
{
if (bAdd)
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, GetVnum());
}
else
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, m_pOwner->GetOriginalPart(PART_WEAPON));
}
}
break;
case ITEM_WEAPON:
{
if (bAdd)
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, GetVnum());
}
else
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, m_pOwner->GetOriginalPart(PART_WEAPON));
}
}
break;
case ITEM_ARMOR:
{
// ÄÚ½ºÃõ body¸¦ ÀÔ°íÀÖ´Ù¸é armor´Â ¹þ´ø ÀÔ´ø »ó°ü ¾øÀÌ ºñÁÖ¾ó¿¡ ¿µÇâÀ» ÁÖ¸é ¾È µÊ.
if (0 != m_pOwner->GetWear(WEAR_COSTUME_BODY))
break;
if (GetSubType() == ARMOR_BODY || GetSubType() == ARMOR_HEAD || GetSubType() == ARMOR_FOOTS || GetSubType() == ARMOR_SHIELD)
{
if (bAdd)
{
if (GetProto()->bSubType == ARMOR_BODY)
m_pOwner->SetPart(PART_MAIN, GetVnum());
}
else
{
if (GetProto()->bSubType == ARMOR_BODY)
m_pOwner->SetPart(PART_MAIN, m_pOwner->GetOriginalPart(PART_MAIN));
}
}
}
break;
// ÄÚ½ºÃõ ¾ÆÀÌÅÛ ÀÔ¾úÀ» ¶§ ij¸¯ÅÍ parts Á¤º¸ ¼¼ÆÃ. ±âÁ¸ ½ºÅ¸ÀÏ´ë·Î Ãß°¡ÇÔ..
case ITEM_COSTUME:
{
DWORD toSetValue = this->GetVnum();
EParts toSetPart = PART_MAX_NUM;
// °©¿Ê ÄÚ½ºÃõ
if (GetSubType() == COSTUME_BODY)
{
toSetPart = PART_MAIN;
if (false == bAdd)
{
// ÄÚ½ºÃõ °©¿ÊÀ» ¹þ¾úÀ» ¶§ ¿ø·¡ °©¿ÊÀ» ÀÔ°í ÀÖ¾ú´Ù¸é ±× °©¿ÊÀ¸·Î look ¼¼ÆÃ, ÀÔÁö ¾Ê¾Ò´Ù¸é default look
const CItem* pArmor = m_pOwner->GetWear(WEAR_BODY);
toSetValue = (NULL != pArmor) ? pArmor->GetVnum() : m_pOwner->GetOriginalPart(PART_MAIN);
}
}
// Çì¾î ÄÚ½ºÃõ
else if (GetSubType() == COSTUME_HAIR)
{
toSetPart = PART_HAIR;
// ÄÚ½ºÃõ Çì¾î´Â shape°ªÀ» item protoÀÇ value3¿¡ ¼¼ÆÃÇϵµ·Ï ÇÔ. Ưº°ÇÑ ÀÌÀ¯´Â ¾ø°í ±âÁ¸ °©¿Ê(ARMOR_BODY)ÀÇ shape°ªÀÌ ÇÁ·ÎÅäÀÇ value3¿¡ ÀÖ¾î¼* Çì¾îµµ °°ÀÌ value3À¸·Î ÇÔ.
// [NOTE] °©¿ÊÀº ¾ÆÀÌÅÛ vnumÀ» º¸³»°í Çì¾î´Â shape(value3)°ªÀ» º¸³»´Â ÀÌÀ¯´Â.. ±âÁ¸ ½Ã½ºÅÛÀÌ ±×·¸°Ô µÇ¾îÀÖÀ½...
toSetValue = (true == bAdd) ? this->GetValue(3) : 0;
}
if (PART_MAX_NUM != toSetPart)
{
m_pOwner->SetPart((BYTE)toSetPart, toSetValue);
m_pOwner->UpdatePacket();
}
}
break;
case ITEM_UNIQUE:
{
if (0 != GetSIGVnum())
{
const CSpecialItemGroup* pItemGroup = ITEM_MANAGER::instance().GetSpecialItemGroup(GetSI GVnum());
if (NULL == pItemGroup)
break;
DWORD dwAttrVnum = pItemGroup->GetAttrVnum(GetVnum());
const CSpecialAttrGroup* pAttrGroup = ITEM_MANAGER::instance().GetSpecialAttrGroup(dwAtt rVnum);
if (NULL == pAttrGroup)
break;
for (auto it = pAttrGroup->m_vecAttrs.begin(); it != pAttrGroup->m_vecAttrs.end(); it++)
{
m_pOwner->ApplyPoint(it->apply_type, bAdd ? it->apply_value : -it->apply_value);
}
}
}
break;
}
}
bool CItem::IsEquipable() const
{
switch (this->GetType())
{
case ITEM_COSTUME:
case ITEM_ARMOR:
case ITEM_WEAPON:
case ITEM_ROD:
case ITEM_PICK:
case ITEM_UNIQUE:
case ITEM_DS:
case ITEM_SPECIAL_DS:
case ITEM_RING:
case ITEM_BELT:
return true;
}
return false;
}
// return false on error state
bool CItem::EquipTo(LPCHARACTER ch, BYTE bWearCell)
{
if (!ch)
{
sys_err("EquipTo: nil character");
return false;
}
// ¿ëÈ¥¼® ½½·Ô index´Â WEAR_MAX_NUM º¸´Ù Å*.
if (IsDragonSoul())
{
if (bWearCell < WEAR_MAX_NUM || bWearCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX)
{
sys_err("EquipTo: invalid dragon soul cell (this: #%d %s wearflag: %d cell: %d)", GetOriginalVnum(), GetName(), GetSubType(), bWearCell - WEAR_MAX_NUM);
return false;
}
}
else
{
if (bWearCell >= WEAR_MAX_NUM)
{
sys_err("EquipTo: invalid wear cell (this: #%d %s wearflag: %d cell: %d)", GetOriginalVnum(), GetName(), GetWearFlag(), bWearCell);
return false;
}
}
if (ch->GetWear(bWearCell))
{
sys_err("EquipTo: item already exist (this: #%d %s cell: %d %s)", GetOriginalVnum(), GetName(), bWearCell, ch->GetWear(bWearCell)->GetName());
return false;
}
if (GetOwner())
RemoveFromCharacter();
ch->SetWear(bWearCell, this); // ¿©±â¼* ÆÐŶ ³ª°¨
m_pOwner = ch;
m_bEquipped = true;
m_wCell = INVENTORY_MAX_NUM + bWearCell;
DWORD dwImmuneFlag = 0;
for (int i = 0 ; i < WEAR_MAX_NUM; i++)
{
LPITEM pItem = m_pOwner->GetWear(i);
if (pItem)
{
SET_BIT(dwImmuneFlag, m_pOwner->GetWear(i)->GetImmuneFlag());
}
}
if (IsDragonSoul())
{
DSManager::instance().ActivateDragonSoul(this);
}
else
{
ModifyPoints(true);
StartUniqueExpireEvent();
if (-1 != GetProto()->cLimitTimerBasedOnWearIndex)
StartTimerBasedOnWearExpireEvent();
// ACCESSORY_REFINE
StartAccessorySocketExpireEvent();
// END_OF_ACCESSORY_REFINE
}
ch->BuffOnAttr_AddBuffsFromItem(this);
m_pOwner->ComputeBattlePoints();
m_pOwner->UpdatePacket();
Save();
return (true);
}
bool CItem::Unequip()
{
if (!m_pOwner || GetCell() < INVENTORY_MAX_NUM)
{
// ITEM_OWNER_INVALID_PTR_BUG
sys_err("%s %u m_pOwner %p, GetCell %d",
GetName(), GetID(), get_pointer(m_pOwner), GetCell());
// END_OF_ITEM_OWNER_INVALID_PTR_BUG
return false;
}
if (this != m_pOwner->GetWear(GetCell() - INVENTORY_MAX_NUM))
{
sys_err("m_pOwner->GetWear() != this");
return false;
}
//½Å±Ô ¸» ¾ÆÀÌÅÛ Á¦°Å½Ã ó¸®
if (IsRideItem())
ClearMountAttributeAndAffect();
if (IsDragonSoul())
{
DSManager::instance().DeactivateDragonSoul(this);
}
else
{
ModifyPoints(false);
}
StopUniqueExpireEvent();
if (-1 != GetProto()->cLimitTimerBasedOnWearIndex)
StopTimerBasedOnWearExpireEvent();
// ACCESSORY_REFINE
StopAccessorySocketExpireEvent();
// END_OF_ACCESSORY_REFINE
m_pOwner->BuffOnAttr_RemoveBuffsFromItem(this);
m_pOwner->SetWear(GetCell() - INVENTORY_MAX_NUM, NULL);
DWORD dwImmuneFlag = 0;
for (int i = 0 ; i < WEAR_MAX_NUM; i++)
{
LPITEM pItem = m_pOwner->GetWear(i);
if (pItem)
{
SET_BIT(dwImmuneFlag, m_pOwner->GetWear(i)->GetImmuneFlag());
}
}
m_pOwner->ComputeBattlePoints();
m_pOwner->UpdatePacket();
m_pOwner = NULL;
m_wCell = 0;
m_bEquipped = false;
return true;
}
long CItem::GetValue(DWORD idx)
{
assert(idx < ITEM_VALUES_MAX_NUM);
return GetProto()->alValues[idx];
}
void CItem::SetExchanging(bool bOn)
{
m_bExchanging = bOn;
}
void CItem::Save()
{
if (m_bSkipSave)
return;
ITEM_MANAGER::instance().DelayedSave(this);
}
bool CItem::CreateSocket(BYTE bSlot, BYTE bGold)
{
assert(bSlot < ITEM_SOCKET_MAX_NUM);
if (m_alSockets[bSlot] != 0)
{
sys_err("Item::CreateSocket : socket already exist %s %d", GetName(), bSlot);
return false;
}
if (bGold)
m_alSockets[bSlot] = 2;
else
m_alSockets[bSlot] = 1;
UpdatePacket();
Save();
return true;
}
void CItem::SetSockets(const long * c_al)
{
thecore_memcpy(m_alSockets, c_al, sizeof(m_alSockets));
Save();
}
void CItem::SetSocket(int i, long v, bool bLog)
{
assert(i < ITEM_SOCKET_MAX_NUM);
m_alSockets[i] = v;
UpdatePacket();
Save();
if (bLog)
LogManager::instance().ItemLog(i, v, 0, GetID(), "SET_SOCKET", "", "", GetOriginalVnum());
}
int CItem::GetGold()
{
if (IS_SET(GetFlag(), ITEM_FLAG_COUNT_PER_1GOLD))
{
if (GetProto()->dwGold == 0)
return GetCount();
else
return GetCount() / GetProto()->dwGold;
}
else
return GetProto()->dwGold;
}
int CItem::GetShopBuyPrice()
{
return GetProto()->dwShopBuyPrice;
}
bool CItem::IsOwnership(LPCHARACTER ch)
{
if (!m_pkOwnershipEvent)
return true;
return m_dwOwnershipPID == ch->GetPlayerID() ? true : false;
}
EVENTFUNC(ownership_event)
{
item_event_info* info = dynamic_cast<item_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "ownership_event> <Factor> Null pointer" );
return 0;
}
LPITEM pkItem = info->item;
pkItem->SetOwnershipEvent(NULL);
TPacketGCItemOwnership p;
p.bHeader = HEADER_GC_ITEM_OWNERSHIP;
p.dwVID = pkItem->GetVID();
p.szName[0] = '\0';
pkItem->PacketAround(&p, sizeof(p));
return 0;
}
void CItem::SetOwnershipEvent(LPEVENT pkEvent)
{
m_pkOwnershipEvent = pkEvent;
}
void CItem::SetOwnership(LPCHARACTER ch, int iSec)
{
if (!ch)
{
if (m_pkOwnershipEvent)
{
event_cancel(&m_pkOwnershipEvent);
m_dwOwnershipPID = 0;
TPacketGCItemOwnership p;
p.bHeader = HEADER_GC_ITEM_OWNERSHIP;
p.dwVID = m_dwVID;
p.szName[0] = '\0';
PacketAround(&p, sizeof(p));
}
return;
}
if (m_pkOwnershipEvent)
return;
if (true == LC_IsEurope())
{
if (iSec <= 10)
iSec = 30;
}
m_dwOwnershipPID = ch->GetPlayerID();
item_event_info* info = AllocEventInfo<item_event_info>();
strlcpy(info->szOwnerName, ch->GetName(), sizeof(info->szOwnerName));
info->item = this;
SetOwnershipEvent(event_create(ownership_event, info, PASSES_PER_SEC(iSec)));
TPacketGCItemOwnership p;
p.bHeader = HEADER_GC_ITEM_OWNERSHIP;
p.dwVID = m_dwVID;
strlcpy(p.szName, ch->GetName(), sizeof(p.szName));
PacketAround(&p, sizeof(p));
}
int CItem::GetSocketCount()
{
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
{
if (GetSocket(i) == 0)
return i;
}
return ITEM_SOCKET_MAX_NUM;
}
bool CItem::AddSocket()
{
int count = GetSocketCount();
if (count == ITEM_SOCKET_MAX_NUM)
return false;
m_alSockets[count] = 1;
return true;
}
void CItem::AlterToSocketItem(int iSocketCount)
{
if (iSocketCount >= ITEM_SOCKET_MAX_NUM)
{
sys_log(0, "Invalid Socket Count %d, set to maximum", ITEM_SOCKET_MAX_NUM);
iSocketCount = ITEM_SOCKET_MAX_NUM;
}
for (int i = 0; i < iSocketCount; ++i)
SetSocket(i, 1);
}
void CItem::AlterToMagicItem()
{
int idx = GetAttributeSetIndex();
if (idx < 0)
return;
// Appeariance Second Third
// Weapon 50 20 5
// Armor 30 10 2
// Acc 20 10 1
int iSecondPct;
int iThirdPct;
if (g_iUseLocale)
{
switch (GetType())
{
case ITEM_WEAPON:
iSecondPct = 20;
iThirdPct = 5;
break;
case ITEM_ARMOR:
case ITEM_COSTUME:
if (GetSubType() == ARMOR_BODY)
{
iSecondPct = 10;
iThirdPct = 2;
}
else
{
iSecondPct = 10;
iThirdPct = 1;
}
break;
default:
return;
}
}
else
{
switch (GetType())
{
case ITEM_WEAPON:
iSecondPct = 30;
iThirdPct = 15;
break;
case ITEM_ARMOR:
case ITEM_COSTUME:
if (GetSubType() == ARMOR_BODY)
{
iSecondPct = 20;
iThirdPct = 10;
}
else
{
iSecondPct = 10;
iThirdPct = 5;
}
break;
default:
return;
}
}
// 100% È®·ü·Î ÁÁÀº ¼Ó¼º Çϳª
PutAttribute(aiItemMagicAttributePercentHigh);
if (number(1, 100) <= iSecondPct)
PutAttribute(aiItemMagicAttributePercentLow);
if (number(1, 100) <= iThirdPct)
PutAttribute(aiItemMagicAttributePercentLow);
}
DWORD CItem::GetRefineFromVnum()
{
return ITEM_MANAGER::instance().GetRefineFromVnum(GetVnum ());
}
int CItem::GetRefineLevel()
{
const char* name = GetBaseName();
char* p = const_cast<char*>(strrchr(name, '+'));
if (!p)
return 0;
int rtn = 0;
str_to_number(rtn, p+1);
const char* locale_name = GetName();
p = const_cast<char*>(strrchr(locale_name, '+'));
if (p)
{
int locale_rtn = 0;
str_to_number(locale_rtn, p+1);
if (locale_rtn != rtn)
{
sys_err("refine_level_based_on_NAME(%d) is not equal to refine_level_based_on_LOCALE_NAME(%d).", rtn, locale_rtn);
}
}
return rtn;
}
bool CItem::IsPolymorphItem()
{
return GetType() == ITEM_POLYMORPH;
}
EVENTFUNC(unique_expire_event)
{
item_event_info* info = dynamic_cast<item_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "unique_expire_event> <Factor> Null pointer" );
return 0;
}
LPITEM pkItem = info->item;
if (pkItem->GetValue(2) == 0)
{
if (pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) <= 1)
{
sys_log(0, "UNIQUE_ITEM: expire %s %u", pkItem->GetName(), pkItem->GetID());
pkItem->SetUniqueExpireEvent(NULL);
ITEM_MANAGER::instance().RemoveItem(pkItem, "UNIQUE_EXPIRE");
return 0;
}
else
{
pkItem->SetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME, pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) - 1);
return PASSES_PER_SEC(60);
}
}
else
{
time_t cur = get_global_time();
if (pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) <= cur)
{
pkItem->SetUniqueExpireEvent(NULL);
ITEM_MANAGER::instance().RemoveItem(pkItem, "UNIQUE_EXPIRE");
return 0;
}
else
{
// °ÔÀÓ ³»¿¡ ½Ã°£Á¦ ¾ÆÀÌÅÛµéÀÌ ºü¸´ºü¸´ÇÏ°Ô »ç¶óÁöÁö ¾Ê´Â ¹ö±×°¡ ÀÖ¾î
// ¼öÁ¤
// by rtsummit
if (pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) - cur < 600)
return PASSES_PER_SEC(pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) - cur);
else
return PASSES_PER_SEC(600);
}
}
}
// ½Ã°£ ÈĺÒÁ¦
// timer¸¦ ½ÃÀÛÇÒ ¶§¿¡ ½Ã°£ Â÷°¨ÇÏ´Â °ÍÀÌ ¾Æ´Ï¶ó,
// timer°¡ ¹ßÈ*ÇÒ ¶§¿¡ timer°¡ µ¿ÀÛÇÑ ½Ã°£ ¸¸Å* ½Ã°£ Â÷°¨À» ÇÑ´Ù.
EVENTFUNC(timer_based_on_wear_expire_event)
{
item_event_info* info = dynamic_cast<item_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "expire_event <Factor> Null pointer" );
return 0;
}
LPITEM pkItem = info->item;
int remain_time = pkItem->GetSocket(ITEM_SOCKET_REMAIN_SEC) - processing_time/passes_per_sec;
if (remain_time <= 0)
{
sys_log(0, "ITEM EXPIRED : expired %s %u", pkItem->GetName(), pkItem->GetID());
pkItem->SetTimerBasedOnWearExpireEvent(NULL);
pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, 0);
// ÀÏ´Ü timer based on wear ¿ëÈ¥¼®Àº ½Ã°£ ´Ù µÇ¾ú´Ù°í ¾ø¾ÖÁö ¾Ê´Â´Ù.
if (pkItem->IsDragonSoul())
{
DSManager::instance().DeactivateDragonSoul(pkItem) ;
}
else
{
ITEM_MANAGER::instance().RemoveItem(pkItem, "TIMER_BASED_ON_WEAR_EXPIRE");
}
return 0;
}
pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, remain_time);
return PASSES_PER_SEC (MIN (60, remain_time));
}
void CItem::SetUniqueExpireEvent(LPEVENT pkEvent)
{
m_pkUniqueExpireEvent = pkEvent;
}
void CItem::SetTimerBasedOnWearExpireEvent(LPEVENT pkEvent)
{
m_pkTimerBasedOnWearExpireEvent = pkEvent;
}
EVENTFUNC(real_time_expire_event)
{
const item_vid_event_info* info = reinterpret_cast<const item_vid_event_info*>(event->info);
if (NULL == info)
return 0;
const LPITEM item = ITEM_MANAGER::instance().FindByVID( info->item_vid );
if (NULL == item)
return 0;
const time_t current = get_global_time();
if (current > item->GetSocket(0))
{
switch (item->GetVnum())
{
if(item->IsNewMountItem())
{
if (item->GetSocket(2) != 0)
item->ClearMountAttributeAndAffect();
}
break;
}
ITEM_MANAGER::instance().RemoveItem(item, "REAL_TIME_EXPIRE");
return 0;
}
return PASSES_PER_SEC(1);
}
void CItem::StartRealTimeExpireEvent()
{
if (m_pkRealTimeExpireEvent)
return;
for (int i=0 ; i < ITEM_LIMIT_MAX_NUM ; i++)
{
if (LIMIT_REAL_TIME == GetProto()->aLimits[i].bType || LIMIT_REAL_TIME_START_FIRST_USE == GetProto()->aLimits[i].bType)
{
item_vid_event_info* info = AllocEventInfo<item_vid_event_info>();
info->item_vid = GetVID();
m_pkRealTimeExpireEvent = event_create( real_time_expire_event, info, PASSES_PER_SEC(1));
sys_log(0, "REAL_TIME_EXPIRE: StartRealTimeExpireEvent");
return;
}
}
}
bool CItem::IsRealTimeItem()
{
if(!GetProto())
return false;
for (int i=0 ; i < ITEM_LIMIT_MAX_NUM ; i++)
{
if (LIMIT_REAL_TIME == GetProto()->aLimits[i].bType)
return true;
}
return false;
}
void CItem::StartUniqueExpireEvent()
{
if (GetType() != ITEM_UNIQUE)
return;
if (m_pkUniqueExpireEvent)
return;
//±â°£Á¦ ¾ÆÀÌÅÛÀÏ °æ¿ì ½Ã°£Á¦ ¾ÆÀÌÅÛÀº µ¿ÀÛÇÏÁö ¾Ê´Â´Ù
if (IsRealTimeItem())
return;
// HARD CODING
if (GetVnum() == UNIQUE_ITEM_HIDE_ALIGNMENT_TITLE)
m_pOwner->ShowAlignment(false);
int iSec = GetSocket(ITEM_SOCKET_UNIQUE_SAVE_TIME);
if (iSec == 0)
iSec = 60;
else
iSec = MIN(iSec, 60);
SetSocket(ITEM_SOCKET_UNIQUE_SAVE_TIME, 0);
item_event_info* info = AllocEventInfo<item_event_info>();
info->item = this;
SetUniqueExpireEvent(event_create(unique_expire_ev ent, info, PASSES_PER_SEC(iSec)));
}
// ½Ã°£ ÈĺÒÁ¦
// timer_based_on_wear_expire_event ¼³¸í ÂüÁ¶
void CItem::StartTimerBasedOnWearExpireEvent()
{
if (m_pkTimerBasedOnWearExpireEvent)
return;
//±â°£Á¦ ¾ÆÀÌÅÛÀÏ °æ¿ì ½Ã°£Á¦ ¾ÆÀÌÅÛÀº µ¿ÀÛÇÏÁö ¾Ê´Â´Ù
if (IsRealTimeItem())
return;
if (-1 == GetProto()->cLimitTimerBasedOnWearIndex)
return;
int iSec = GetSocket(0);
// ³²Àº ½Ã°£À» ºÐ´ÜÀ§·Î ²÷±â À§ÇØ...
if (0 != iSec)
{
iSec %= 60;
if (0 == iSec)
iSec = 60;
}
item_event_info* info = AllocEventInfo<item_event_info>();
info->item = this;
SetTimerBasedOnWearExpireEvent(event_create(timer_ based_on_wear_expire_event, info, PASSES_PER_SEC(iSec)));
}
void CItem::StopUniqueExpireEvent()
{
if (!m_pkUniqueExpireEvent)
return;
if (GetValue(2) != 0) // °ÔÀӽð£Á¦ ÀÌ¿ÜÀÇ ¾ÆÀÌÅÛÀº UniqueExpireEvent¸¦ Áß´ÜÇÒ ¼ö ¾ø´Ù.
return;
// HARD CODING
if (GetVnum() == UNIQUE_ITEM_HIDE_ALIGNMENT_TITLE)
m_pOwner->ShowAlignment(true);
SetSocket(ITEM_SOCKET_UNIQUE_SAVE_TIME, event_time(m_pkUniqueExpireEvent) / passes_per_sec);
event_cancel(&m_pkUniqueExpireEvent);
ITEM_MANAGER::instance().SaveSingleItem(this);
}
void CItem::StopTimerBasedOnWearExpireEvent()
{
if (!m_pkTimerBasedOnWearExpireEvent)
return;
int remain_time = GetSocket(ITEM_SOCKET_REMAIN_SEC) - event_processing_time(m_pkTimerBasedOnWearExpireEv ent) / passes_per_sec;
SetSocket(ITEM_SOCKET_REMAIN_SEC, remain_time);
event_cancel(&m_pkTimerBasedOnWearExpireEvent);
ITEM_MANAGER::instance().SaveSingleItem(this);
}
void CItem::ApplyAddon(int iAddonType)
{
CItemAddonManager::instance().ApplyAddonTo(iAddonT ype, this);
}
int CItem::GetSpecialGroup() const
{
return ITEM_MANAGER::instance().GetSpecialGroupFromItem(G etVnum());
}
//
// ¾Ç¼¼¼*¸® ¼ÒÄÏ Ã³¸®.
//
bool CItem::IsAccessoryForSocket()
{
return (m_pProto->bType == ITEM_ARMOR && (m_pProto->bSubType == ARMOR_WRIST || m_pProto->bSubType == ARMOR_NECK || m_pProto->bSubType == ARMOR_EAR)) ||
(m_pProto->bType == ITEM_BELT); // 2013³â 2¿ù »õ·Î Ãß°¡µÈ 'º§Æ®' ¾ÆÀÌÅÛÀÇ °æ¿ì ±âȹÆÀ¿¡¼* ¾Ç¼¼¼*¸® ¼ÒÄÏ ½Ã½ºÅÛÀ» ±×´ë·Î ÀÌ¿ëÇÏÀÚ°í ÇÔ.
}
void CItem::SetAccessorySocketGrade(int iGrade)
{
SetSocket(0, MINMAX(0, iGrade, GetAccessorySocketMaxGrade()));
int iDownTime = aiAccessorySocketDegradeTime[GetAccessorySocketGrade()];
//if (test_server)
// iDownTime /= 60;
SetAccessorySocketDownGradeTime(iDownTime);
}
void CItem::SetAccessorySocketMaxGrade(int iMaxGrade)
{
SetSocket(1, MINMAX(0, iMaxGrade, ITEM_ACCESSORY_SOCKET_MAX_NUM));
}
void CItem::SetAccessorySocketDownGradeTime(DWORD time)
{
SetSocket(2, time);
if (test_server && GetOwner())
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s¿¡¼* ¼ÒÄÏ ºüÁú¶§±îÁö ³²Àº ½Ã°£ %d"), GetName(), time);
}
EVENTFUNC(accessory_socket_expire_event)
{
item_vid_event_info* info = dynamic_cast<item_vid_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "accessory_socket_expire_event> <Factor> Null pointer" );
return 0;
}
LPITEM item = ITEM_MANAGER::instance().FindByVID(info->item_vid);
if (item->GetAccessorySocketDownGradeTime() <= 1)
{
degrade:
item->SetAccessorySocketExpireEvent(NULL);
item->AccessorySocketDegrade();
return 0;
}
else
{
int iTime = item->GetAccessorySocketDownGradeTime() - 60;
if (iTime <= 1)
goto degrade;
item->SetAccessorySocketDownGradeTime(iTime);
if (iTime > 60)
return PASSES_PER_SEC(60);
else
return PASSES_PER_SEC(iTime);
}
}
void CItem::StartAccessorySocketExpireEvent()
{
if (!IsAccessoryForSocket())
return;
if (m_pkAccessorySocketExpireEvent)
return;
if (GetAccessorySocketMaxGrade() == 0)
return;
if (GetAccessorySocketGrade() == 0)
return;
int iSec = GetAccessorySocketDownGradeTime();
SetAccessorySocketExpireEvent(NULL);
if (iSec <= 1)
iSec = 5;
else
iSec = MIN(iSec, 60);
item_vid_event_info* info = AllocEventInfo<item_vid_event_info>();
info->item_vid = GetVID();
SetAccessorySocketExpireEvent(event_create(accesso ry_socket_expire_event, info, PASSES_PER_SEC(iSec)));
}
void CItem::StopAccessorySocketExpireEvent()
{
if (!m_pkAccessorySocketExpireEvent)
return;
if (!IsAccessoryForSocket())
return;
int new_time = GetAccessorySocketDownGradeTime() - (60 - event_time(m_pkAccessorySocketExpireEvent) / passes_per_sec);
event_cancel(&m_pkAccessorySocketExpireEvent);
if (new_time <= 1)
{
AccessorySocketDegrade();
}
else
{
SetAccessorySocketDownGradeTime(new_time);
}
}
bool CItem::IsRideItem()
{
if (ITEM_UNIQUE == GetType() && UNIQUE_SPECIAL_RIDE == GetSubType())
return true;
if (ITEM_UNIQUE == GetType() && UNIQUE_SPECIAL_MOUNT_RIDE == GetSubType())
return true;
return false;
}
//bool CItem::IsRamadanRing()
//{
// if (GetVnum() == UNIQUE_ITEM_RAMADAN_RING)
// return true;
// return false;
//}
void CItem::ClearMountAttributeAndAffect()
{
LPCHARACTER ch = GetOwner();
ch->RemoveAffect(AFFECT_MOUNT);
ch->RemoveAffect(AFFECT_MOUNT_BONUS);
ch->MountVnum(0);
ch->PointChange(POINT_ST, 0);
ch->PointChange(POINT_DX, 0);
ch->PointChange(POINT_HT, 0);
ch->PointChange(POINT_IQ, 0);
}
// fixme
// À̰ŠÁö±ÝÀº ¾È¾´µ¥... ±Ùµ¥ Ȥ½Ã³ª ½Í¾î¼* ³²°ÜµÒ.
// by rtsummit
bool CItem::IsNewMountItem()
{
switch(GetVnum())
{
case 76000: case 76001: case 76002: case 76003:
case 76004: case 76005: case 76006: case 76007:
case 76008: case 76009: case 76010: case 76011:
case 76012: case 76013: case 76014:
return true;
}
return false;
}
void CItem::SetAccessorySocketExpireEvent(LPEVENT pkEvent)
{
m_pkAccessorySocketExpireEvent = pkEvent;
}
void CItem::AccessorySocketDegrade()
{
if (GetAccessorySocketGrade() > 0)
{
LPCHARACTER ch = GetOwner();
if (ch)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s¿¡ ¹ÚÇôÀÖ´ø º¸¼®ÀÌ »ç¶óÁý´Ï´Ù."), GetName());
}
ModifyPoints(false);
SetAccessorySocketGrade(GetAccessorySocketGrade()-1);
ModifyPoints(true);
int iDownTime = aiAccessorySocketDegradeTime[GetAccessorySocketGrade()];
if (test_server)
iDownTime /= 60;
SetAccessorySocketDownGradeTime(iDownTime);
if (iDownTime)
StartAccessorySocketExpireEvent();
}
}
// ring¿¡ itemÀ» ¹ÚÀ» ¼ö ÀÖ´ÂÁö ¿©ºÎ¸¦ Ã¼Å©ÇØ¼* ¸®ÅÏ
static const bool CanPutIntoRing(LPITEM ring, LPITEM item)
{
const DWORD vnum = item->GetVnum();
return false;
}
bool CItem::CanPutInto(LPITEM item)
{
if (item->GetType() == ITEM_BELT)
return this->GetSubType() == USE_PUT_INTO_BELT_SOCKET;
else if(item->GetType() == ITEM_RING)
return CanPutIntoRing(item, this);
else if (item->GetType() != ITEM_ARMOR)
return false;
DWORD vnum = item->GetVnum();
struct JewelAccessoryInfo
{
DWORD jewel;
DWORD wrist;
DWORD neck;
DWORD ear;
};
const static JewelAccessoryInfo infos[] = {
{ 50634, 14420, 16220, 17220 },
{ 50635, 14500, 16500, 17500 },
{ 50636, 14520, 16520, 17520 },
{ 50637, 14540, 16540, 17540 },
{ 50638, 14560, 16560, 17560 },
};
DWORD item_type = (item->GetVnum() / 10) * 10;
for (int i = 0; i < sizeof(infos) / sizeof(infos[0]); i++)
{
const JewelAccessoryInfo& info = infos[i];
switch(item->GetSubType())
{
case ARMOR_WRIST:
if (info.wrist == item_type)
{
if (info.jewel == GetVnum())
{
return true;
}
else
{
return false;
}
}
break;
case ARMOR_NECK:
if (info.neck == item_type)
{
if (info.jewel == GetVnum())
{
return true;
}
else
{
return false;
}
}
break;
case ARMOR_EAR:
if (info.ear == item_type)
{
if (info.jewel == GetVnum())
{
return true;
}
else
{
return false;
}
}
break;
}
}
if (item->GetSubType() == ARMOR_WRIST)
vnum -= 14000;
else if (item->GetSubType() == ARMOR_NECK)
vnum -= 16000;
else if (item->GetSubType() == ARMOR_EAR)
vnum -= 17000;
else
return false;
DWORD type = vnum / 20;
if (type < 0 || type > 11)
{
type = (vnum - 170) / 20;
if (50623 + type != GetVnum())
return false;
else
return true;
}
else if (item->GetVnum() >= 16210 && item->GetVnum() <= 16219)
{
if (50625 != GetVnum())
return false;
else
return true;
}
else if (item->GetVnum() >= 16230 && item->GetVnum() <= 16239)
{
if (50626 != GetVnum())
return false;
else
return true;
}
return 50623 + type == GetVnum();
}
bool CItem::CheckItemUseLevel(int nLevel)
{
for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
{
if (this->m_pProto->aLimits[i].bType == LIMIT_LEVEL)
{
if (this->m_pProto->aLimits[i].lValue > nLevel) return false;
else return true;
}
}
return true;
}
long CItem::FindApplyValue(BYTE bApplyType)
{
if (m_pProto == NULL)
return 0;
for (int i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
{
if (m_pProto->aApplies[i].bType == bApplyType)
return m_pProto->aApplies[i].lValue;
}
return 0;
}
void CItem::CopySocketTo(LPITEM pItem)
{
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
{
pItem->m_alSockets[i] = m_alSockets[i];
}
}
int CItem::GetAccessorySocketGrade()
{
return MINMAX(0, GetSocket(0), GetAccessorySocketMaxGrade());
}
int CItem::GetAccessorySocketMaxGrade()
{
return MINMAX(0, GetSocket(1), ITEM_ACCESSORY_SOCKET_MAX_NUM);
}
int CItem::GetAccessorySocketDownGradeTime()
{
return MINMAX(0, GetSocket(2), aiAccessorySocketDegradeTime[GetAccessorySocketGrade()]);
}
void CItem::AttrLog()
{
const char * pszIP = NULL;
if (GetOwner() && GetOwner()->GetDesc())
pszIP = GetOwner()->GetDesc()->GetHostName();
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
{
if (m_alSockets[i])
{
LogManager::instance().ItemLog(i, m_alSockets[i], 0, GetID(), "INFO_SOCKET", "", pszIP ? pszIP : "", GetOriginalVnum());
}
}
for (int i = 0; i<ITEM_ATTRIBUTE_MAX_NUM; ++i)
{
int type = m_aAttr[i].bType;
int value = m_aAttr[i].sValue;
if (type)
LogManager::instance().ItemLog(i, type, value, GetID(), "INFO_ATTR", "", pszIP ? pszIP : "", GetOriginalVnum());
}
}
int CItem::GetLevelLimit()
{
for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
{
if (this->m_pProto->aLimits[i].bType == LIMIT_LEVEL)
{
return this->m_pProto->aLimits[i].lValue;
}
}
return 0;
}
bool CItem::OnAfterCreatedItem()
{
// ¾ÆÀÌÅÛÀ» ÇÑ ¹øÀÌ¶óµµ »ç¿ëÇß´Ù¸é, ±× ÀÌÈÄ¿£ »ç¿ë ÁßÀÌÁö ¾Ê¾Æµµ ½Ã°£ÀÌ Â÷°¨µÇ´Â ¹æ½Ä
if (-1 != this->GetProto()->cLimitRealTimeFirstUseIndex)
{
// Socket1¿¡ ¾ÆÀÌÅÛÀÇ »ç¿ë Ƚ¼ö°¡ ±â·ÏµÇ¾î ÀÖÀ¸´Ï, ÇÑ ¹øÀÌ¶óµµ »ç¿ëÇÑ ¾ÆÀÌÅÛÀº ŸÀ̸Ӹ¦ ½ÃÀÛÇÑ´Ù.
if (0 != GetSocket(1))
{
StartRealTimeExpireEvent();
}
}
return true;
}
bool CItem::IsDragonSoul()
{
return GetType() == ITEM_DS;
}
int CItem::GiveMoreTime_Per(float fPercent)
{
if (IsDragonSoul())
{
DWORD duration = DSManager::instance().GetDuration(this);
int remain_sec = GetSocket(ITEM_SOCKET_REMAIN_SEC);
int given_time = fPercent * duration / 100;
if (remain_sec == duration)
return false;
if ((given_time + remain_sec) >= duration)
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, duration);
return duration - remain_sec;
}
else
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, given_time + remain_sec);
return given_time;
}
}
// ¿ì¼± ¿ëÈ¥¼®¿¡ °üÇØ¼*¸¸ Çϵµ·Ï ÇÑ´Ù.
else
return 0;
}
int CItem::GiveMoreTime_Fix(DWORD dwTime)
{
if (IsDragonSoul())
{
DWORD duration = DSManager::instance().GetDuration(this);
int remain_sec = GetSocket(ITEM_SOCKET_REMAIN_SEC);
if (remain_sec == duration)
return false;
if ((dwTime + remain_sec) >= duration)
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, duration);
return duration - remain_sec;
}
else
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, dwTime + remain_sec);
return dwTime;
}
}
// ¿ì¼± ¿ëÈ¥¼®¿¡ °üÇØ¼*¸¸ Çϵµ·Ï ÇÑ´Ù.
else
return 0;
}
int CItem::GetDuration()
{
if(!GetProto())
return -1;
for (int i=0 ; i < ITEM_LIMIT_MAX_NUM ; i++)
{
if (LIMIT_REAL_TIME == GetProto()->aLimits[i].bType)
return GetProto()->aLimits[i].lValue;
}
if (-1 != GetProto()->cLimitTimerBasedOnWearIndex)
return GetProto()->aLimits[GetProto()->cLimitTimerBasedOnWearIndex].lValue;
return -1;
}
bool CItem::IsSameSpecialGroup(const LPITEM item) const
{
// ¼*·Î VNUMÀÌ °°´Ù¸é °°Àº ±×·ìÀÎ °ÍÀ¸·Î °£ÁÖ
if (this->GetVnum() == item->GetVnum())
return true;
if (GetSpecialGroup() && (item->GetSpecialGroup() == GetSpecialGroup()))
return true;
return false;
}
DWORD CItem::GetRealImmuneFlag()
{
DWORD dwImmuneFlag = GetImmuneFlag();
for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
{
if (!GetAttribute(i).sValue)
continue;
if (GetAttribute(i).bType == APPLY_IMMUNE_STUN)
SET_BIT(dwImmuneFlag, IMMUNE_STUN);
else if (GetAttribute(i).bType == APPLY_IMMUNE_SLOW)
SET_BIT(dwImmuneFlag, IMMUNE_SLOW);
else if (GetAttribute(i).bType == APPLY_IMMUNE_FALL)
SET_BIT(dwImmuneFlag, IMMUNE_FALL);
}
return dwImmuneFlag;
}
#include "utils.h"
#include "config.h"
#include "char.h"
#include "desc.h"
#include "sectree_manager.h"
#include "packet.h"
#include "protocol.h"
#include "log.h"
#include "skill.h"
#include "unique_item.h"
#include "profiler.h"
#include "marriage.h"
#include "item_addon.h"
#include "dev_log.h"
#include "locale_service.h"
#include "item.h"
#include "item_manager.h"
#include "affect.h"
#include "DragonSoul.h"
#include "buff_on_attributes.h"
#include "belt_inventory_helper.h"
#include "../../common/VnumHelper.h"
CItem::CItem(DWORD dwVnum)
: m_dwVnum(dwVnum), m_bWindow(0), m_dwID(0), m_bEquipped(false), m_dwVID(0), m_wCell(0), m_dwCount(0), m_lFlag(0), m_dwLastOwnerPID(0),
m_bExchanging(false), m_pkDestroyEvent(NULL), m_pkUniqueExpireEvent(NULL), m_pkTimerBasedOnWearExpireEvent(NULL), m_pkRealTimeExpireEvent(NULL),
m_pkExpireEvent(NULL),
m_pkAccessorySocketExpireEvent(NULL), m_pkOwnershipEvent(NULL), m_dwOwnershipPID(0), m_bSkipSave(false), m_isLocked(false),
m_dwMaskVnum(0), m_dwSIGVnum (0)
{
memset( &m_alSockets, 0, sizeof(m_alSockets) );
memset( &m_aAttr, 0, sizeof(m_aAttr) );
}
CItem::~CItem()
{
Destroy();
}
void CItem::Initialize()
{
CEntity::Initialize(ENTITY_ITEM);
m_bWindow = RESERVED_WINDOW;
m_pOwner = NULL;
m_dwID = 0;
m_bEquipped = false;
m_dwVID = m_wCell = m_dwCount = m_lFlag = 0;
m_pProto = NULL;
m_bExchanging = false;
memset(&m_alSockets, 0, sizeof(m_alSockets));
memset(&m_aAttr, 0, sizeof(m_aAttr));
m_pkDestroyEvent = NULL;
m_pkOwnershipEvent = NULL;
m_dwOwnershipPID = 0;
m_pkUniqueExpireEvent = NULL;
m_pkTimerBasedOnWearExpireEvent = NULL;
m_pkRealTimeExpireEvent = NULL;
m_pkAccessorySocketExpireEvent = NULL;
m_bSkipSave = false;
m_dwLastOwnerPID = 0;
}
void CItem::Destroy()
{
event_cancel(&m_pkDestroyEvent);
event_cancel(&m_pkOwnershipEvent);
event_cancel(&m_pkUniqueExpireEvent);
event_cancel(&m_pkTimerBasedOnWearExpireEvent);
event_cancel(&m_pkRealTimeExpireEvent);
event_cancel(&m_pkAccessorySocketExpireEvent);
CEntity::Destroy();
if (GetSectree())
GetSectree()->RemoveEntity(this);
}
EVENTFUNC(item_destroy_event)
{
item_event_info* info = dynamic_cast<item_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "item_destroy_event> <Factor> Null pointer" );
return 0;
}
LPITEM pkItem = info->item;
if (pkItem->GetOwner())
sys_err("item_destroy_event: Owner exist. (item %s owner %s)", pkItem->GetName(), pkItem->GetOwner()->GetName());
pkItem->SetDestroyEvent(NULL);
M2_DESTROY_ITEM(pkItem);
return 0;
}
void CItem::SetDestroyEvent(LPEVENT pkEvent)
{
m_pkDestroyEvent = pkEvent;
}
void CItem::StartDestroyEvent(int iSec)
{
if (m_pkDestroyEvent)
return;
item_event_info* info = AllocEventInfo<item_event_info>();
info->item = this;
SetDestroyEvent(event_create(item_destroy_event, info, PASSES_PER_SEC(iSec)));
}
void CItem::EncodeInsertPacket(LPENTITY ent)
{
LPDESC d;
if (!(d = ent->GetDesc()))
return;
const PIXEL_POSITION & c_pos = GetXYZ();
struct packet_item_ground_add pack;
pack.bHeader = HEADER_GC_ITEM_GROUND_ADD;
pack.x = c_pos.x;
pack.y = c_pos.y;
pack.z = c_pos.z;
pack.dwVnum = GetVnum();
pack.dwVID = m_dwVID;
//pack.count = m_dwCount;
d->Packet(&pack, sizeof(pack));
if (m_pkOwnershipEvent != NULL)
{
item_event_info * info = dynamic_cast<item_event_info *>(m_pkOwnershipEvent->info);
if ( info == NULL )
{
sys_err( "CItem::EncodeInsertPacket> <Factor> Null pointer" );
return;
}
TPacketGCItemOwnership p;
p.bHeader = HEADER_GC_ITEM_OWNERSHIP;
p.dwVID = m_dwVID;
strlcpy(p.szName, info->szOwnerName, sizeof(p.szName));
d->Packet(&p, sizeof(TPacketGCItemOwnership));
}
}
void CItem::EncodeRemovePacket(LPENTITY ent)
{
LPDESC d;
if (!(d = ent->GetDesc()))
return;
struct packet_item_ground_del pack;
pack.bHeader = HEADER_GC_ITEM_GROUND_DEL;
pack.dwVID = m_dwVID;
d->Packet(&pack, sizeof(pack));
sys_log(2, "Item::EncodeRemovePacket %s to %s", GetName(), ((LPCHARACTER) ent)->GetName());
}
void CItem::SetProto(const TItemTable * table)
{
assert(table != NULL);
m_pProto = table;
SetFlag(m_pProto->dwFlags);
}
void CItem::UsePacketEncode(LPCHARACTER ch, LPCHARACTER victim, struct packet_item_use *packet)
{
if (!GetVnum())
return;
packet->header = HEADER_GC_ITEM_USE;
packet->ch_vid = ch->GetVID();
packet->victim_vid = victim->GetVID();
packet->Cell = TItemPos(GetWindow(), m_wCell);
packet->vnum = GetVnum();
}
void CItem::RemoveFlag(long bit)
{
REMOVE_BIT(m_lFlag, bit);
}
void CItem::AddFlag(long bit)
{
SET_BIT(m_lFlag, bit);
}
void CItem::UpdatePacket()
{
if (!m_pOwner || !m_pOwner->GetDesc())
return;
TPacketGCItemUpdate pack;
pack.header = HEADER_GC_ITEM_UPDATE;
pack.Cell = TItemPos(GetWindow(), m_wCell);
pack.count = m_dwCount;
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
pack.alSockets[i] = m_alSockets[i];
thecore_memcpy(pack.aAttr, GetAttributes(), sizeof(pack.aAttr));
sys_log(2, "UpdatePacket %s -> %s", GetName(), m_pOwner->GetName());
m_pOwner->GetDesc()->Packet(&pack, sizeof(pack));
}
DWORD CItem::GetCount()
{
if (GetType() == ITEM_ELK) return MIN(m_dwCount, INT_MAX);
else
{
return MIN(m_dwCount, 200);
}
}
bool CItem::SetCount(DWORD count)
{
if (GetType() == ITEM_ELK)
{
m_dwCount = MIN(count, INT_MAX);
}
else
{
m_dwCount = MIN(count, ITEM_MAX_COUNT);
}
if (count == 0 && m_pOwner)
{
if (GetSubType() == USE_ABILITY_UP || GetSubType() == USE_POTION || GetVnum() == 70020)
{
LPCHARACTER pOwner = GetOwner();
WORD wCell = GetCell();
RemoveFromCharacter();
if (!IsDragonSoul())
{
LPITEM pItem = pOwner->FindSpecifyItem(GetVnum());
if (NULL != pItem)
{
pOwner->ChainQuickslotItem(pItem, QUICKSLOT_TYPE_ITEM, wCell);
}
else
{
pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, wCell, 255);
}
}
M2_DESTROY_ITEM(this);
}
else
{
if (!IsDragonSoul())
{
m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, m_wCell, 255);
}
M2_DESTROY_ITEM(RemoveFromCharacter());
}
return false;
}
UpdatePacket();
Save();
return true;
}
LPITEM CItem::RemoveFromCharacter()
{
if (!m_pOwner)
{
sys_err("Item::RemoveFromCharacter owner null");
return (this);
}
LPCHARACTER pOwner = m_pOwner;
if (m_bEquipped) // ÀåÂøµÇ¾ú´Â°¡?
{
Unequip();
//pOwner->UpdatePacket();
SetWindow(RESERVED_WINDOW);
Save();
return (this);
}
else
{
if (GetWindow() != SAFEBOX && GetWindow() != MALL)
{
if (IsDragonSoul())
{
if (m_wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
sys_err("CItem::RemoveFromCharacter: pos >= DRAGON_SOUL_INVENTORY_MAX_NUM");
else
pOwner->SetItem(TItemPos(m_bWindow, m_wCell), NULL);
}
else
{
TItemPos cell(INVENTORY, m_wCell);
if (false == cell.IsDefaultInventoryPosition() && false == cell.IsBeltInventoryPosition()) // ¾Æ´Ï¸é ¼ÒÁöǰ¿¡?
sys_err("CItem::RemoveFromCharacter: Invalid Item Position");
else
{
pOwner->SetItem(cell, NULL);
}
}
}
m_pOwner = NULL;
m_wCell = 0;
SetWindow(RESERVED_WINDOW);
Save();
return (this);
}
}
bool CItem::AddToCharacter(LPCHARACTER ch, TItemPos Cell)
{
assert(GetSectree() == NULL);
assert(m_pOwner == NULL);
WORD pos = Cell.cell;
BYTE window_type = Cell.window_type;
if (INVENTORY == window_type)
{
if (m_wCell >= INVENTORY_MAX_NUM && BELT_INVENTORY_SLOT_START > m_wCell)
{
sys_err("CItem::AddToCharacter: cell overflow: %s to %s cell %d", m_pProto->szName, ch->GetName(), m_wCell);
return false;
}
}
else if (DRAGON_SOUL_INVENTORY == window_type)
{
if (m_wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
{
sys_err("CItem::AddToCharacter: cell overflow: %s to %s cell %d", m_pProto->szName, ch->GetName(), m_wCell);
return false;
}
}
if (ch->GetDesc())
m_dwLastOwnerPID = ch->GetPlayerID();
event_cancel(&m_pkDestroyEvent);
ch->SetItem(TItemPos(window_type, pos), this);
m_pOwner = ch;
Save();
return true;
}
LPITEM CItem::RemoveFromGround()
{
if (GetSectree())
{
SetOwnership(NULL);
GetSectree()->RemoveEntity(this);
ViewCleanup();
Save();
}
return (this);
}
bool CItem::AddToGround(long lMapIndex, const PIXEL_POSITION & pos, bool skipOwnerCheck)
{
if (0 == lMapIndex)
{
sys_err("wrong map index argument: %d", lMapIndex);
return false;
}
if (GetSectree())
{
sys_err("sectree already assigned");
return false;
}
if (!skipOwnerCheck && m_pOwner)
{
sys_err("owner pointer not null");
return false;
}
LPSECTREE tree = SECTREE_MANAGER::instance().Get(lMapIndex, pos.x, pos.y);
if (!tree)
{
sys_err("cannot find sectree by %dx%d", pos.x, pos.y);
return false;
}
//tree->Touch();
SetWindow(GROUND);
SetXYZ(pos.x, pos.y, pos.z);
tree->InsertEntity(this);
UpdateSectree();
Save();
return true;
}
bool CItem::DistanceValid(LPCHARACTER ch)
{
if (!GetSectree())
return false;
int iDist = DISTANCE_APPROX(GetX() - ch->GetX(), GetY() - ch->GetY());
if (iDist > 300)
return false;
return true;
}
bool CItem::CanUsedBy(LPCHARACTER ch)
{
// Anti flag check
switch (ch->GetJob())
{
case JOB_WARRIOR:
if (GetAntiFlag() & ITEM_ANTIFLAG_WARRIOR)
return false;
break;
case JOB_ASSASSIN:
if (GetAntiFlag() & ITEM_ANTIFLAG_ASSASSIN)
return false;
break;
case JOB_SHAMAN:
if (GetAntiFlag() & ITEM_ANTIFLAG_SHAMAN)
return false;
break;
case JOB_SURA:
if (GetAntiFlag() & ITEM_ANTIFLAG_SURA)
return false;
break;
}
return true;
}
int CItem::FindEquipCell(LPCHARACTER ch, int iCandidateCell)
{
// ÄÚ½ºÃõ ¾ÆÀÌÅÛ(ITEM_COSTUME)Àº WearFlag ¾ø¾îµµ µÊ. (sub typeÀ¸·Î Âø¿ëÀ§Ä¡ ±¸ºÐ. ±ÍÂú°Ô ¶Ç wear flag ÁÙ Çʿ䰡 ÀÖ³ª..)
// ¿ëÈ¥¼®(ITEM_DS, ITEM_SPECIAL_DS)µµ SUB_TYPEÀ¸·Î ±¸ºÐ. ½Å±Ô ¹ÝÁö, º§Æ®´Â ITEM_TYPEÀ¸·Î ±¸ºÐ -_-
if ((0 == GetWearFlag() || ITEM_TOTEM == GetType()) && ITEM_COSTUME != GetType() && ITEM_DS != GetType() && ITEM_SPECIAL_DS != GetType() && ITEM_RING != GetType() && ITEM_BELT != GetType())
return -1;
// ¿ëÈ¥¼® ½½·ÔÀ» WEAR·Î ó¸®ÇÒ ¼ö°¡ ¾ø¾î¼*(WEAR´Â ÃÖ´ë 32°³±îÁö °¡´ÉÇѵ¥ ¿ëÈ¥¼®À» Ãß°¡Çϸé 32°¡ ³Ñ´Â´Ù.)
// Àκ¥Å丮ÀÇ Æ¯Á¤ À§Ä¡((INVENTORY_MAX_NUM + WEAR_MAX_NUM)ºÎÅÍ (INVENTORY_MAX_NUM + WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX - 1)±îÁö)¸¦
// ¿ëÈ¥¼® ½½·ÔÀ¸·Î Á¤ÇÔ.
// return ÇÒ ¶§¿¡, INVENTORY_MAX_NUMÀ» »« ÀÌÀ¯´Â,
// º»·¡ WearCellÀÌ INVENTORY_MAX_NUM¸¦ »©°í return Çϱ⠶§¹®.
if (GetType() == ITEM_DS || GetType() == ITEM_SPECIAL_DS)
{
if (iCandidateCell < 0)
{
return WEAR_MAX_NUM + GetSubType();
}
else
{
for (int i = 0; i < DRAGON_SOUL_DECK_MAX_NUM; i++)
{
if (WEAR_MAX_NUM + i * DS_SLOT_MAX + GetSubType() == iCandidateCell)
{
return iCandidateCell;
}
}
return -1;
}
}
else if (GetType() == ITEM_COSTUME)
{
if (GetSubType() == COSTUME_BODY)
return WEAR_COSTUME_BODY;
else if (GetSubType() == COSTUME_HAIR)
return WEAR_COSTUME_HAIR;
}
else if (GetType() == ITEM_RING)
{
if (ch->GetWear(WEAR_RING1))
return WEAR_RING2;
else
return WEAR_RING1;
}
else if (GetType() == ITEM_BELT)
return WEAR_BELT;
else if (GetWearFlag() & WEARABLE_BODY)
return WEAR_BODY;
else if (GetWearFlag() & WEARABLE_HEAD)
return WEAR_HEAD;
else if (GetWearFlag() & WEARABLE_FOOTS)
return WEAR_FOOTS;
else if (GetWearFlag() & WEARABLE_WRIST)
return WEAR_WRIST;
else if (GetWearFlag() & WEARABLE_WEAPON)
return WEAR_WEAPON;
else if (GetWearFlag() & WEARABLE_SHIELD)
return WEAR_SHIELD;
else if (GetWearFlag() & WEARABLE_NECK)
return WEAR_NECK;
else if (GetWearFlag() & WEARABLE_EAR)
return WEAR_EAR;
else if (GetWearFlag() & WEARABLE_ARROW)
return WEAR_ARROW;
else if (GetWearFlag() & WEARABLE_UNIQUE)
{
if (ch->GetWear(WEAR_UNIQUE1))
return WEAR_UNIQUE2;
else
return WEAR_UNIQUE1;
}
// ¼öÁý Äù½ºÆ®¸¦ À§ÇÑ ¾ÆÀÌÅÛÀÌ ¹ÚÈ÷´Â°÷À¸·Î Çѹø ¹ÚÈ÷¸é Àý´ë –E¼ö ¾ø´Ù.
else if (GetWearFlag() & WEARABLE_ABILITY)
{
if (!ch->GetWear(WEAR_ABILITY1))
{
return WEAR_ABILITY1;
}
else if (!ch->GetWear(WEAR_ABILITY2))
{
return WEAR_ABILITY2;
}
else if (!ch->GetWear(WEAR_ABILITY3))
{
return WEAR_ABILITY3;
}
else if (!ch->GetWear(WEAR_ABILITY4))
{
return WEAR_ABILITY4;
}
else if (!ch->GetWear(WEAR_ABILITY5))
{
return WEAR_ABILITY5;
}
else if (!ch->GetWear(WEAR_ABILITY6))
{
return WEAR_ABILITY6;
}
else if (!ch->GetWear(WEAR_ABILITY7))
{
return WEAR_ABILITY7;
}
else if (!ch->GetWear(WEAR_ABILITY8))
{
return WEAR_ABILITY8;
}
else
{
return -1;
}
}
return -1;
}
void CItem::ModifyPoints(bool bAdd)
{
int accessoryGrade;
// ¹«±â¿Í °©¿Ê¸¸ ¼ÒÄÏÀ» Àû¿ë½ÃŲ´Ù.
if (false == IsAccessoryForSocket())
{
if (m_pProto->bType == ITEM_WEAPON || m_pProto->bType == ITEM_ARMOR)
{
// ¼ÒÄÏÀÌ ¼Ó¼º°*È*¿¡ »ç¿ëµÇ´Â °æ¿ì Àû¿ëÇÏÁö ¾Ê´Â´Ù (ARMOR_WRIST ARMOR_NECK ARMOR_EAR)
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
{
DWORD dwVnum;
if ((dwVnum = GetSocket(i)) <= 2)
continue;
TItemTable * p = ITEM_MANAGER::instance().GetTable(dwVnum);
if (!p)
{
sys_err("cannot find table by vnum %u", dwVnum);
continue;
}
if (ITEM_METIN == p->bType)
{
//m_pOwner->ApplyPoint(p->alValues[0], bAdd ? p->alValues[1] : -p->alValues[1]);
for (int i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
{
if (p->aApplies[i].bType == APPLY_NONE)
continue;
if (p->aApplies[i].bType == APPLY_SKILL)
m_pOwner->ApplyPoint(p->aApplies[i].bType, bAdd ? p->aApplies[i].lValue : p->aApplies[i].lValue ^ 0x00800000);
else
m_pOwner->ApplyPoint(p->aApplies[i].bType, bAdd ? p->aApplies[i].lValue : -p->aApplies[i].lValue);
}
}
}
}
accessoryGrade = 0;
}
else
{
accessoryGrade = MIN(GetAccessorySocketGrade(), ITEM_ACCESSORY_SOCKET_MAX_NUM);
}
for (int i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
{
if (m_pProto->aApplies[i].bType == APPLY_NONE)
continue;
long value = m_pProto->aApplies[i].lValue;
if (m_pProto->aApplies[i].bType == APPLY_SKILL)
{
m_pOwner->ApplyPoint(m_pProto->aApplies[i].bType, bAdd ? value : value ^ 0x00800000);
}
else
{
if (0 != accessoryGrade)
value += MAX(accessoryGrade, value * aiAccessorySocketEffectivePct[accessoryGrade] / 100);
m_pOwner->ApplyPoint(m_pProto->aApplies[i].bType, bAdd ? value : -value);
}
}
// Ãʽ´ÞÀÇ ¹ÝÁö, ÇÒ·ÎÀ© »çÅÁ, ÇູÀÇ ¹ÝÁö, ¿µ¿øÇÑ »ç¶ûÀÇ Ææ´øÆ®ÀÇ °æ¿ì
// ±âÁ¸ÀÇ Çϵå ÄÚµùÀ¸·Î °*Á¦·Î ¼Ó¼ºÀ» ºÎ¿©ÇßÁö¸¸,
// ±× ºÎºÐÀ» Á¦°ÅÇϰí special item group Å×ÀÌºí¿¡¼* ¼Ó¼ºÀ» ºÎ¿©Çϵµ·Ï º¯°æÇÏ¿´´Ù.
// ÇÏÁö¸¸ Çϵå ÄÚµùµÇ¾îÀÖÀ» ¶§ »ý¼ºµÈ ¾ÆÀÌÅÛÀÌ ³²¾ÆÀÖÀ» ¼öµµ ÀÖ¾î¼* Ư¼öó¸® ÇØ³õ´Â´Ù.
// ÀÌ ¾ÆÀÌÅÛµéÀÇ °æ¿ì, ¹Ø¿¡ ITEM_UNIQUEÀÏ ¶§ÀÇ Ã³¸®·Î ¼Ó¼ºÀÌ ºÎ¿©µÇ±â ¶§¹®¿¡,
// ¾ÆÀÌÅÛ¿¡ ¹ÚÇôÀÖ´Â attribute´Â Àû¿ëÇÏÁö ¾Ê°í ³Ñ¾î°£´Ù.
if (true == CItemVnumHelper::IsRamadanMoonRing(GetVnum()) || true == CItemVnumHelper::IsHalloweenCandy(GetVnum())
|| true == CItemVnumHelper::IsHappinessRing(GetVnum()) || true == CItemVnumHelper::IsLovePendant(GetVnum()))
{
// Do not anything.
}
else
{
for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
{
if (GetAttributeType(i))
{
const TPlayerItemAttribute& ia = GetAttribute(i);
if (ia.bType == APPLY_SKILL)
m_pOwner->ApplyPoint(ia.bType, bAdd ? ia.sValue : ia.sValue ^ 0x00800000);
else
m_pOwner->ApplyPoint(ia.bType, bAdd ? ia.sValue : -ia.sValue);
}
}
}
switch (m_pProto->bType)
{
case ITEM_PICK:
case ITEM_ROD:
{
if (bAdd)
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, GetVnum());
}
else
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, m_pOwner->GetOriginalPart(PART_WEAPON));
}
}
break;
case ITEM_WEAPON:
{
if (bAdd)
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, GetVnum());
}
else
{
if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
m_pOwner->SetPart(PART_WEAPON, m_pOwner->GetOriginalPart(PART_WEAPON));
}
}
break;
case ITEM_ARMOR:
{
// ÄÚ½ºÃõ body¸¦ ÀÔ°íÀÖ´Ù¸é armor´Â ¹þ´ø ÀÔ´ø »ó°ü ¾øÀÌ ºñÁÖ¾ó¿¡ ¿µÇâÀ» ÁÖ¸é ¾È µÊ.
if (0 != m_pOwner->GetWear(WEAR_COSTUME_BODY))
break;
if (GetSubType() == ARMOR_BODY || GetSubType() == ARMOR_HEAD || GetSubType() == ARMOR_FOOTS || GetSubType() == ARMOR_SHIELD)
{
if (bAdd)
{
if (GetProto()->bSubType == ARMOR_BODY)
m_pOwner->SetPart(PART_MAIN, GetVnum());
}
else
{
if (GetProto()->bSubType == ARMOR_BODY)
m_pOwner->SetPart(PART_MAIN, m_pOwner->GetOriginalPart(PART_MAIN));
}
}
}
break;
// ÄÚ½ºÃõ ¾ÆÀÌÅÛ ÀÔ¾úÀ» ¶§ ij¸¯ÅÍ parts Á¤º¸ ¼¼ÆÃ. ±âÁ¸ ½ºÅ¸ÀÏ´ë·Î Ãß°¡ÇÔ..
case ITEM_COSTUME:
{
DWORD toSetValue = this->GetVnum();
EParts toSetPart = PART_MAX_NUM;
// °©¿Ê ÄÚ½ºÃõ
if (GetSubType() == COSTUME_BODY)
{
toSetPart = PART_MAIN;
if (false == bAdd)
{
// ÄÚ½ºÃõ °©¿ÊÀ» ¹þ¾úÀ» ¶§ ¿ø·¡ °©¿ÊÀ» ÀÔ°í ÀÖ¾ú´Ù¸é ±× °©¿ÊÀ¸·Î look ¼¼ÆÃ, ÀÔÁö ¾Ê¾Ò´Ù¸é default look
const CItem* pArmor = m_pOwner->GetWear(WEAR_BODY);
toSetValue = (NULL != pArmor) ? pArmor->GetVnum() : m_pOwner->GetOriginalPart(PART_MAIN);
}
}
// Çì¾î ÄÚ½ºÃõ
else if (GetSubType() == COSTUME_HAIR)
{
toSetPart = PART_HAIR;
// ÄÚ½ºÃõ Çì¾î´Â shape°ªÀ» item protoÀÇ value3¿¡ ¼¼ÆÃÇϵµ·Ï ÇÔ. Ưº°ÇÑ ÀÌÀ¯´Â ¾ø°í ±âÁ¸ °©¿Ê(ARMOR_BODY)ÀÇ shape°ªÀÌ ÇÁ·ÎÅäÀÇ value3¿¡ ÀÖ¾î¼* Çì¾îµµ °°ÀÌ value3À¸·Î ÇÔ.
// [NOTE] °©¿ÊÀº ¾ÆÀÌÅÛ vnumÀ» º¸³»°í Çì¾î´Â shape(value3)°ªÀ» º¸³»´Â ÀÌÀ¯´Â.. ±âÁ¸ ½Ã½ºÅÛÀÌ ±×·¸°Ô µÇ¾îÀÖÀ½...
toSetValue = (true == bAdd) ? this->GetValue(3) : 0;
}
if (PART_MAX_NUM != toSetPart)
{
m_pOwner->SetPart((BYTE)toSetPart, toSetValue);
m_pOwner->UpdatePacket();
}
}
break;
case ITEM_UNIQUE:
{
if (0 != GetSIGVnum())
{
const CSpecialItemGroup* pItemGroup = ITEM_MANAGER::instance().GetSpecialItemGroup(GetSI GVnum());
if (NULL == pItemGroup)
break;
DWORD dwAttrVnum = pItemGroup->GetAttrVnum(GetVnum());
const CSpecialAttrGroup* pAttrGroup = ITEM_MANAGER::instance().GetSpecialAttrGroup(dwAtt rVnum);
if (NULL == pAttrGroup)
break;
for (auto it = pAttrGroup->m_vecAttrs.begin(); it != pAttrGroup->m_vecAttrs.end(); it++)
{
m_pOwner->ApplyPoint(it->apply_type, bAdd ? it->apply_value : -it->apply_value);
}
}
}
break;
}
}
bool CItem::IsEquipable() const
{
switch (this->GetType())
{
case ITEM_COSTUME:
case ITEM_ARMOR:
case ITEM_WEAPON:
case ITEM_ROD:
case ITEM_PICK:
case ITEM_UNIQUE:
case ITEM_DS:
case ITEM_SPECIAL_DS:
case ITEM_RING:
case ITEM_BELT:
return true;
}
return false;
}
// return false on error state
bool CItem::EquipTo(LPCHARACTER ch, BYTE bWearCell)
{
if (!ch)
{
sys_err("EquipTo: nil character");
return false;
}
// ¿ëÈ¥¼® ½½·Ô index´Â WEAR_MAX_NUM º¸´Ù Å*.
if (IsDragonSoul())
{
if (bWearCell < WEAR_MAX_NUM || bWearCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX)
{
sys_err("EquipTo: invalid dragon soul cell (this: #%d %s wearflag: %d cell: %d)", GetOriginalVnum(), GetName(), GetSubType(), bWearCell - WEAR_MAX_NUM);
return false;
}
}
else
{
if (bWearCell >= WEAR_MAX_NUM)
{
sys_err("EquipTo: invalid wear cell (this: #%d %s wearflag: %d cell: %d)", GetOriginalVnum(), GetName(), GetWearFlag(), bWearCell);
return false;
}
}
if (ch->GetWear(bWearCell))
{
sys_err("EquipTo: item already exist (this: #%d %s cell: %d %s)", GetOriginalVnum(), GetName(), bWearCell, ch->GetWear(bWearCell)->GetName());
return false;
}
if (GetOwner())
RemoveFromCharacter();
ch->SetWear(bWearCell, this); // ¿©±â¼* ÆÐŶ ³ª°¨
m_pOwner = ch;
m_bEquipped = true;
m_wCell = INVENTORY_MAX_NUM + bWearCell;
DWORD dwImmuneFlag = 0;
for (int i = 0 ; i < WEAR_MAX_NUM; i++)
{
LPITEM pItem = m_pOwner->GetWear(i);
if (pItem)
{
SET_BIT(dwImmuneFlag, m_pOwner->GetWear(i)->GetImmuneFlag());
}
}
if (IsDragonSoul())
{
DSManager::instance().ActivateDragonSoul(this);
}
else
{
ModifyPoints(true);
StartUniqueExpireEvent();
if (-1 != GetProto()->cLimitTimerBasedOnWearIndex)
StartTimerBasedOnWearExpireEvent();
// ACCESSORY_REFINE
StartAccessorySocketExpireEvent();
// END_OF_ACCESSORY_REFINE
}
ch->BuffOnAttr_AddBuffsFromItem(this);
m_pOwner->ComputeBattlePoints();
m_pOwner->UpdatePacket();
Save();
return (true);
}
bool CItem::Unequip()
{
if (!m_pOwner || GetCell() < INVENTORY_MAX_NUM)
{
// ITEM_OWNER_INVALID_PTR_BUG
sys_err("%s %u m_pOwner %p, GetCell %d",
GetName(), GetID(), get_pointer(m_pOwner), GetCell());
// END_OF_ITEM_OWNER_INVALID_PTR_BUG
return false;
}
if (this != m_pOwner->GetWear(GetCell() - INVENTORY_MAX_NUM))
{
sys_err("m_pOwner->GetWear() != this");
return false;
}
//½Å±Ô ¸» ¾ÆÀÌÅÛ Á¦°Å½Ã ó¸®
if (IsRideItem())
ClearMountAttributeAndAffect();
if (IsDragonSoul())
{
DSManager::instance().DeactivateDragonSoul(this);
}
else
{
ModifyPoints(false);
}
StopUniqueExpireEvent();
if (-1 != GetProto()->cLimitTimerBasedOnWearIndex)
StopTimerBasedOnWearExpireEvent();
// ACCESSORY_REFINE
StopAccessorySocketExpireEvent();
// END_OF_ACCESSORY_REFINE
m_pOwner->BuffOnAttr_RemoveBuffsFromItem(this);
m_pOwner->SetWear(GetCell() - INVENTORY_MAX_NUM, NULL);
DWORD dwImmuneFlag = 0;
for (int i = 0 ; i < WEAR_MAX_NUM; i++)
{
LPITEM pItem = m_pOwner->GetWear(i);
if (pItem)
{
SET_BIT(dwImmuneFlag, m_pOwner->GetWear(i)->GetImmuneFlag());
}
}
m_pOwner->ComputeBattlePoints();
m_pOwner->UpdatePacket();
m_pOwner = NULL;
m_wCell = 0;
m_bEquipped = false;
return true;
}
long CItem::GetValue(DWORD idx)
{
assert(idx < ITEM_VALUES_MAX_NUM);
return GetProto()->alValues[idx];
}
void CItem::SetExchanging(bool bOn)
{
m_bExchanging = bOn;
}
void CItem::Save()
{
if (m_bSkipSave)
return;
ITEM_MANAGER::instance().DelayedSave(this);
}
bool CItem::CreateSocket(BYTE bSlot, BYTE bGold)
{
assert(bSlot < ITEM_SOCKET_MAX_NUM);
if (m_alSockets[bSlot] != 0)
{
sys_err("Item::CreateSocket : socket already exist %s %d", GetName(), bSlot);
return false;
}
if (bGold)
m_alSockets[bSlot] = 2;
else
m_alSockets[bSlot] = 1;
UpdatePacket();
Save();
return true;
}
void CItem::SetSockets(const long * c_al)
{
thecore_memcpy(m_alSockets, c_al, sizeof(m_alSockets));
Save();
}
void CItem::SetSocket(int i, long v, bool bLog)
{
assert(i < ITEM_SOCKET_MAX_NUM);
m_alSockets[i] = v;
UpdatePacket();
Save();
if (bLog)
LogManager::instance().ItemLog(i, v, 0, GetID(), "SET_SOCKET", "", "", GetOriginalVnum());
}
int CItem::GetGold()
{
if (IS_SET(GetFlag(), ITEM_FLAG_COUNT_PER_1GOLD))
{
if (GetProto()->dwGold == 0)
return GetCount();
else
return GetCount() / GetProto()->dwGold;
}
else
return GetProto()->dwGold;
}
int CItem::GetShopBuyPrice()
{
return GetProto()->dwShopBuyPrice;
}
bool CItem::IsOwnership(LPCHARACTER ch)
{
if (!m_pkOwnershipEvent)
return true;
return m_dwOwnershipPID == ch->GetPlayerID() ? true : false;
}
EVENTFUNC(ownership_event)
{
item_event_info* info = dynamic_cast<item_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "ownership_event> <Factor> Null pointer" );
return 0;
}
LPITEM pkItem = info->item;
pkItem->SetOwnershipEvent(NULL);
TPacketGCItemOwnership p;
p.bHeader = HEADER_GC_ITEM_OWNERSHIP;
p.dwVID = pkItem->GetVID();
p.szName[0] = '\0';
pkItem->PacketAround(&p, sizeof(p));
return 0;
}
void CItem::SetOwnershipEvent(LPEVENT pkEvent)
{
m_pkOwnershipEvent = pkEvent;
}
void CItem::SetOwnership(LPCHARACTER ch, int iSec)
{
if (!ch)
{
if (m_pkOwnershipEvent)
{
event_cancel(&m_pkOwnershipEvent);
m_dwOwnershipPID = 0;
TPacketGCItemOwnership p;
p.bHeader = HEADER_GC_ITEM_OWNERSHIP;
p.dwVID = m_dwVID;
p.szName[0] = '\0';
PacketAround(&p, sizeof(p));
}
return;
}
if (m_pkOwnershipEvent)
return;
if (true == LC_IsEurope())
{
if (iSec <= 10)
iSec = 30;
}
m_dwOwnershipPID = ch->GetPlayerID();
item_event_info* info = AllocEventInfo<item_event_info>();
strlcpy(info->szOwnerName, ch->GetName(), sizeof(info->szOwnerName));
info->item = this;
SetOwnershipEvent(event_create(ownership_event, info, PASSES_PER_SEC(iSec)));
TPacketGCItemOwnership p;
p.bHeader = HEADER_GC_ITEM_OWNERSHIP;
p.dwVID = m_dwVID;
strlcpy(p.szName, ch->GetName(), sizeof(p.szName));
PacketAround(&p, sizeof(p));
}
int CItem::GetSocketCount()
{
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
{
if (GetSocket(i) == 0)
return i;
}
return ITEM_SOCKET_MAX_NUM;
}
bool CItem::AddSocket()
{
int count = GetSocketCount();
if (count == ITEM_SOCKET_MAX_NUM)
return false;
m_alSockets[count] = 1;
return true;
}
void CItem::AlterToSocketItem(int iSocketCount)
{
if (iSocketCount >= ITEM_SOCKET_MAX_NUM)
{
sys_log(0, "Invalid Socket Count %d, set to maximum", ITEM_SOCKET_MAX_NUM);
iSocketCount = ITEM_SOCKET_MAX_NUM;
}
for (int i = 0; i < iSocketCount; ++i)
SetSocket(i, 1);
}
void CItem::AlterToMagicItem()
{
int idx = GetAttributeSetIndex();
if (idx < 0)
return;
// Appeariance Second Third
// Weapon 50 20 5
// Armor 30 10 2
// Acc 20 10 1
int iSecondPct;
int iThirdPct;
if (g_iUseLocale)
{
switch (GetType())
{
case ITEM_WEAPON:
iSecondPct = 20;
iThirdPct = 5;
break;
case ITEM_ARMOR:
case ITEM_COSTUME:
if (GetSubType() == ARMOR_BODY)
{
iSecondPct = 10;
iThirdPct = 2;
}
else
{
iSecondPct = 10;
iThirdPct = 1;
}
break;
default:
return;
}
}
else
{
switch (GetType())
{
case ITEM_WEAPON:
iSecondPct = 30;
iThirdPct = 15;
break;
case ITEM_ARMOR:
case ITEM_COSTUME:
if (GetSubType() == ARMOR_BODY)
{
iSecondPct = 20;
iThirdPct = 10;
}
else
{
iSecondPct = 10;
iThirdPct = 5;
}
break;
default:
return;
}
}
// 100% È®·ü·Î ÁÁÀº ¼Ó¼º Çϳª
PutAttribute(aiItemMagicAttributePercentHigh);
if (number(1, 100) <= iSecondPct)
PutAttribute(aiItemMagicAttributePercentLow);
if (number(1, 100) <= iThirdPct)
PutAttribute(aiItemMagicAttributePercentLow);
}
DWORD CItem::GetRefineFromVnum()
{
return ITEM_MANAGER::instance().GetRefineFromVnum(GetVnum ());
}
int CItem::GetRefineLevel()
{
const char* name = GetBaseName();
char* p = const_cast<char*>(strrchr(name, '+'));
if (!p)
return 0;
int rtn = 0;
str_to_number(rtn, p+1);
const char* locale_name = GetName();
p = const_cast<char*>(strrchr(locale_name, '+'));
if (p)
{
int locale_rtn = 0;
str_to_number(locale_rtn, p+1);
if (locale_rtn != rtn)
{
sys_err("refine_level_based_on_NAME(%d) is not equal to refine_level_based_on_LOCALE_NAME(%d).", rtn, locale_rtn);
}
}
return rtn;
}
bool CItem::IsPolymorphItem()
{
return GetType() == ITEM_POLYMORPH;
}
EVENTFUNC(unique_expire_event)
{
item_event_info* info = dynamic_cast<item_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "unique_expire_event> <Factor> Null pointer" );
return 0;
}
LPITEM pkItem = info->item;
if (pkItem->GetValue(2) == 0)
{
if (pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) <= 1)
{
sys_log(0, "UNIQUE_ITEM: expire %s %u", pkItem->GetName(), pkItem->GetID());
pkItem->SetUniqueExpireEvent(NULL);
ITEM_MANAGER::instance().RemoveItem(pkItem, "UNIQUE_EXPIRE");
return 0;
}
else
{
pkItem->SetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME, pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) - 1);
return PASSES_PER_SEC(60);
}
}
else
{
time_t cur = get_global_time();
if (pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) <= cur)
{
pkItem->SetUniqueExpireEvent(NULL);
ITEM_MANAGER::instance().RemoveItem(pkItem, "UNIQUE_EXPIRE");
return 0;
}
else
{
// °ÔÀÓ ³»¿¡ ½Ã°£Á¦ ¾ÆÀÌÅÛµéÀÌ ºü¸´ºü¸´ÇÏ°Ô »ç¶óÁöÁö ¾Ê´Â ¹ö±×°¡ ÀÖ¾î
// ¼öÁ¤
// by rtsummit
if (pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) - cur < 600)
return PASSES_PER_SEC(pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) - cur);
else
return PASSES_PER_SEC(600);
}
}
}
// ½Ã°£ ÈĺÒÁ¦
// timer¸¦ ½ÃÀÛÇÒ ¶§¿¡ ½Ã°£ Â÷°¨ÇÏ´Â °ÍÀÌ ¾Æ´Ï¶ó,
// timer°¡ ¹ßÈ*ÇÒ ¶§¿¡ timer°¡ µ¿ÀÛÇÑ ½Ã°£ ¸¸Å* ½Ã°£ Â÷°¨À» ÇÑ´Ù.
EVENTFUNC(timer_based_on_wear_expire_event)
{
item_event_info* info = dynamic_cast<item_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "expire_event <Factor> Null pointer" );
return 0;
}
LPITEM pkItem = info->item;
int remain_time = pkItem->GetSocket(ITEM_SOCKET_REMAIN_SEC) - processing_time/passes_per_sec;
if (remain_time <= 0)
{
sys_log(0, "ITEM EXPIRED : expired %s %u", pkItem->GetName(), pkItem->GetID());
pkItem->SetTimerBasedOnWearExpireEvent(NULL);
pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, 0);
// ÀÏ´Ü timer based on wear ¿ëÈ¥¼®Àº ½Ã°£ ´Ù µÇ¾ú´Ù°í ¾ø¾ÖÁö ¾Ê´Â´Ù.
if (pkItem->IsDragonSoul())
{
DSManager::instance().DeactivateDragonSoul(pkItem) ;
}
else
{
ITEM_MANAGER::instance().RemoveItem(pkItem, "TIMER_BASED_ON_WEAR_EXPIRE");
}
return 0;
}
pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, remain_time);
return PASSES_PER_SEC (MIN (60, remain_time));
}
void CItem::SetUniqueExpireEvent(LPEVENT pkEvent)
{
m_pkUniqueExpireEvent = pkEvent;
}
void CItem::SetTimerBasedOnWearExpireEvent(LPEVENT pkEvent)
{
m_pkTimerBasedOnWearExpireEvent = pkEvent;
}
EVENTFUNC(real_time_expire_event)
{
const item_vid_event_info* info = reinterpret_cast<const item_vid_event_info*>(event->info);
if (NULL == info)
return 0;
const LPITEM item = ITEM_MANAGER::instance().FindByVID( info->item_vid );
if (NULL == item)
return 0;
const time_t current = get_global_time();
if (current > item->GetSocket(0))
{
switch (item->GetVnum())
{
if(item->IsNewMountItem())
{
if (item->GetSocket(2) != 0)
item->ClearMountAttributeAndAffect();
}
break;
}
ITEM_MANAGER::instance().RemoveItem(item, "REAL_TIME_EXPIRE");
return 0;
}
return PASSES_PER_SEC(1);
}
void CItem::StartRealTimeExpireEvent()
{
if (m_pkRealTimeExpireEvent)
return;
for (int i=0 ; i < ITEM_LIMIT_MAX_NUM ; i++)
{
if (LIMIT_REAL_TIME == GetProto()->aLimits[i].bType || LIMIT_REAL_TIME_START_FIRST_USE == GetProto()->aLimits[i].bType)
{
item_vid_event_info* info = AllocEventInfo<item_vid_event_info>();
info->item_vid = GetVID();
m_pkRealTimeExpireEvent = event_create( real_time_expire_event, info, PASSES_PER_SEC(1));
sys_log(0, "REAL_TIME_EXPIRE: StartRealTimeExpireEvent");
return;
}
}
}
bool CItem::IsRealTimeItem()
{
if(!GetProto())
return false;
for (int i=0 ; i < ITEM_LIMIT_MAX_NUM ; i++)
{
if (LIMIT_REAL_TIME == GetProto()->aLimits[i].bType)
return true;
}
return false;
}
void CItem::StartUniqueExpireEvent()
{
if (GetType() != ITEM_UNIQUE)
return;
if (m_pkUniqueExpireEvent)
return;
//±â°£Á¦ ¾ÆÀÌÅÛÀÏ °æ¿ì ½Ã°£Á¦ ¾ÆÀÌÅÛÀº µ¿ÀÛÇÏÁö ¾Ê´Â´Ù
if (IsRealTimeItem())
return;
// HARD CODING
if (GetVnum() == UNIQUE_ITEM_HIDE_ALIGNMENT_TITLE)
m_pOwner->ShowAlignment(false);
int iSec = GetSocket(ITEM_SOCKET_UNIQUE_SAVE_TIME);
if (iSec == 0)
iSec = 60;
else
iSec = MIN(iSec, 60);
SetSocket(ITEM_SOCKET_UNIQUE_SAVE_TIME, 0);
item_event_info* info = AllocEventInfo<item_event_info>();
info->item = this;
SetUniqueExpireEvent(event_create(unique_expire_ev ent, info, PASSES_PER_SEC(iSec)));
}
// ½Ã°£ ÈĺÒÁ¦
// timer_based_on_wear_expire_event ¼³¸í ÂüÁ¶
void CItem::StartTimerBasedOnWearExpireEvent()
{
if (m_pkTimerBasedOnWearExpireEvent)
return;
//±â°£Á¦ ¾ÆÀÌÅÛÀÏ °æ¿ì ½Ã°£Á¦ ¾ÆÀÌÅÛÀº µ¿ÀÛÇÏÁö ¾Ê´Â´Ù
if (IsRealTimeItem())
return;
if (-1 == GetProto()->cLimitTimerBasedOnWearIndex)
return;
int iSec = GetSocket(0);
// ³²Àº ½Ã°£À» ºÐ´ÜÀ§·Î ²÷±â À§ÇØ...
if (0 != iSec)
{
iSec %= 60;
if (0 == iSec)
iSec = 60;
}
item_event_info* info = AllocEventInfo<item_event_info>();
info->item = this;
SetTimerBasedOnWearExpireEvent(event_create(timer_ based_on_wear_expire_event, info, PASSES_PER_SEC(iSec)));
}
void CItem::StopUniqueExpireEvent()
{
if (!m_pkUniqueExpireEvent)
return;
if (GetValue(2) != 0) // °ÔÀӽð£Á¦ ÀÌ¿ÜÀÇ ¾ÆÀÌÅÛÀº UniqueExpireEvent¸¦ Áß´ÜÇÒ ¼ö ¾ø´Ù.
return;
// HARD CODING
if (GetVnum() == UNIQUE_ITEM_HIDE_ALIGNMENT_TITLE)
m_pOwner->ShowAlignment(true);
SetSocket(ITEM_SOCKET_UNIQUE_SAVE_TIME, event_time(m_pkUniqueExpireEvent) / passes_per_sec);
event_cancel(&m_pkUniqueExpireEvent);
ITEM_MANAGER::instance().SaveSingleItem(this);
}
void CItem::StopTimerBasedOnWearExpireEvent()
{
if (!m_pkTimerBasedOnWearExpireEvent)
return;
int remain_time = GetSocket(ITEM_SOCKET_REMAIN_SEC) - event_processing_time(m_pkTimerBasedOnWearExpireEv ent) / passes_per_sec;
SetSocket(ITEM_SOCKET_REMAIN_SEC, remain_time);
event_cancel(&m_pkTimerBasedOnWearExpireEvent);
ITEM_MANAGER::instance().SaveSingleItem(this);
}
void CItem::ApplyAddon(int iAddonType)
{
CItemAddonManager::instance().ApplyAddonTo(iAddonT ype, this);
}
int CItem::GetSpecialGroup() const
{
return ITEM_MANAGER::instance().GetSpecialGroupFromItem(G etVnum());
}
//
// ¾Ç¼¼¼*¸® ¼ÒÄÏ Ã³¸®.
//
bool CItem::IsAccessoryForSocket()
{
return (m_pProto->bType == ITEM_ARMOR && (m_pProto->bSubType == ARMOR_WRIST || m_pProto->bSubType == ARMOR_NECK || m_pProto->bSubType == ARMOR_EAR)) ||
(m_pProto->bType == ITEM_BELT); // 2013³â 2¿ù »õ·Î Ãß°¡µÈ 'º§Æ®' ¾ÆÀÌÅÛÀÇ °æ¿ì ±âȹÆÀ¿¡¼* ¾Ç¼¼¼*¸® ¼ÒÄÏ ½Ã½ºÅÛÀ» ±×´ë·Î ÀÌ¿ëÇÏÀÚ°í ÇÔ.
}
void CItem::SetAccessorySocketGrade(int iGrade)
{
SetSocket(0, MINMAX(0, iGrade, GetAccessorySocketMaxGrade()));
int iDownTime = aiAccessorySocketDegradeTime[GetAccessorySocketGrade()];
//if (test_server)
// iDownTime /= 60;
SetAccessorySocketDownGradeTime(iDownTime);
}
void CItem::SetAccessorySocketMaxGrade(int iMaxGrade)
{
SetSocket(1, MINMAX(0, iMaxGrade, ITEM_ACCESSORY_SOCKET_MAX_NUM));
}
void CItem::SetAccessorySocketDownGradeTime(DWORD time)
{
SetSocket(2, time);
if (test_server && GetOwner())
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s¿¡¼* ¼ÒÄÏ ºüÁú¶§±îÁö ³²Àº ½Ã°£ %d"), GetName(), time);
}
EVENTFUNC(accessory_socket_expire_event)
{
item_vid_event_info* info = dynamic_cast<item_vid_event_info*>( event->info );
if ( info == NULL )
{
sys_err( "accessory_socket_expire_event> <Factor> Null pointer" );
return 0;
}
LPITEM item = ITEM_MANAGER::instance().FindByVID(info->item_vid);
if (item->GetAccessorySocketDownGradeTime() <= 1)
{
degrade:
item->SetAccessorySocketExpireEvent(NULL);
item->AccessorySocketDegrade();
return 0;
}
else
{
int iTime = item->GetAccessorySocketDownGradeTime() - 60;
if (iTime <= 1)
goto degrade;
item->SetAccessorySocketDownGradeTime(iTime);
if (iTime > 60)
return PASSES_PER_SEC(60);
else
return PASSES_PER_SEC(iTime);
}
}
void CItem::StartAccessorySocketExpireEvent()
{
if (!IsAccessoryForSocket())
return;
if (m_pkAccessorySocketExpireEvent)
return;
if (GetAccessorySocketMaxGrade() == 0)
return;
if (GetAccessorySocketGrade() == 0)
return;
int iSec = GetAccessorySocketDownGradeTime();
SetAccessorySocketExpireEvent(NULL);
if (iSec <= 1)
iSec = 5;
else
iSec = MIN(iSec, 60);
item_vid_event_info* info = AllocEventInfo<item_vid_event_info>();
info->item_vid = GetVID();
SetAccessorySocketExpireEvent(event_create(accesso ry_socket_expire_event, info, PASSES_PER_SEC(iSec)));
}
void CItem::StopAccessorySocketExpireEvent()
{
if (!m_pkAccessorySocketExpireEvent)
return;
if (!IsAccessoryForSocket())
return;
int new_time = GetAccessorySocketDownGradeTime() - (60 - event_time(m_pkAccessorySocketExpireEvent) / passes_per_sec);
event_cancel(&m_pkAccessorySocketExpireEvent);
if (new_time <= 1)
{
AccessorySocketDegrade();
}
else
{
SetAccessorySocketDownGradeTime(new_time);
}
}
bool CItem::IsRideItem()
{
if (ITEM_UNIQUE == GetType() && UNIQUE_SPECIAL_RIDE == GetSubType())
return true;
if (ITEM_UNIQUE == GetType() && UNIQUE_SPECIAL_MOUNT_RIDE == GetSubType())
return true;
return false;
}
//bool CItem::IsRamadanRing()
//{
// if (GetVnum() == UNIQUE_ITEM_RAMADAN_RING)
// return true;
// return false;
//}
void CItem::ClearMountAttributeAndAffect()
{
LPCHARACTER ch = GetOwner();
ch->RemoveAffect(AFFECT_MOUNT);
ch->RemoveAffect(AFFECT_MOUNT_BONUS);
ch->MountVnum(0);
ch->PointChange(POINT_ST, 0);
ch->PointChange(POINT_DX, 0);
ch->PointChange(POINT_HT, 0);
ch->PointChange(POINT_IQ, 0);
}
// fixme
// À̰ŠÁö±ÝÀº ¾È¾´µ¥... ±Ùµ¥ Ȥ½Ã³ª ½Í¾î¼* ³²°ÜµÒ.
// by rtsummit
bool CItem::IsNewMountItem()
{
switch(GetVnum())
{
case 76000: case 76001: case 76002: case 76003:
case 76004: case 76005: case 76006: case 76007:
case 76008: case 76009: case 76010: case 76011:
case 76012: case 76013: case 76014:
return true;
}
return false;
}
void CItem::SetAccessorySocketExpireEvent(LPEVENT pkEvent)
{
m_pkAccessorySocketExpireEvent = pkEvent;
}
void CItem::AccessorySocketDegrade()
{
if (GetAccessorySocketGrade() > 0)
{
LPCHARACTER ch = GetOwner();
if (ch)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s¿¡ ¹ÚÇôÀÖ´ø º¸¼®ÀÌ »ç¶óÁý´Ï´Ù."), GetName());
}
ModifyPoints(false);
SetAccessorySocketGrade(GetAccessorySocketGrade()-1);
ModifyPoints(true);
int iDownTime = aiAccessorySocketDegradeTime[GetAccessorySocketGrade()];
if (test_server)
iDownTime /= 60;
SetAccessorySocketDownGradeTime(iDownTime);
if (iDownTime)
StartAccessorySocketExpireEvent();
}
}
// ring¿¡ itemÀ» ¹ÚÀ» ¼ö ÀÖ´ÂÁö ¿©ºÎ¸¦ Ã¼Å©ÇØ¼* ¸®ÅÏ
static const bool CanPutIntoRing(LPITEM ring, LPITEM item)
{
const DWORD vnum = item->GetVnum();
return false;
}
bool CItem::CanPutInto(LPITEM item)
{
if (item->GetType() == ITEM_BELT)
return this->GetSubType() == USE_PUT_INTO_BELT_SOCKET;
else if(item->GetType() == ITEM_RING)
return CanPutIntoRing(item, this);
else if (item->GetType() != ITEM_ARMOR)
return false;
DWORD vnum = item->GetVnum();
struct JewelAccessoryInfo
{
DWORD jewel;
DWORD wrist;
DWORD neck;
DWORD ear;
};
const static JewelAccessoryInfo infos[] = {
{ 50634, 14420, 16220, 17220 },
{ 50635, 14500, 16500, 17500 },
{ 50636, 14520, 16520, 17520 },
{ 50637, 14540, 16540, 17540 },
{ 50638, 14560, 16560, 17560 },
};
DWORD item_type = (item->GetVnum() / 10) * 10;
for (int i = 0; i < sizeof(infos) / sizeof(infos[0]); i++)
{
const JewelAccessoryInfo& info = infos[i];
switch(item->GetSubType())
{
case ARMOR_WRIST:
if (info.wrist == item_type)
{
if (info.jewel == GetVnum())
{
return true;
}
else
{
return false;
}
}
break;
case ARMOR_NECK:
if (info.neck == item_type)
{
if (info.jewel == GetVnum())
{
return true;
}
else
{
return false;
}
}
break;
case ARMOR_EAR:
if (info.ear == item_type)
{
if (info.jewel == GetVnum())
{
return true;
}
else
{
return false;
}
}
break;
}
}
if (item->GetSubType() == ARMOR_WRIST)
vnum -= 14000;
else if (item->GetSubType() == ARMOR_NECK)
vnum -= 16000;
else if (item->GetSubType() == ARMOR_EAR)
vnum -= 17000;
else
return false;
DWORD type = vnum / 20;
if (type < 0 || type > 11)
{
type = (vnum - 170) / 20;
if (50623 + type != GetVnum())
return false;
else
return true;
}
else if (item->GetVnum() >= 16210 && item->GetVnum() <= 16219)
{
if (50625 != GetVnum())
return false;
else
return true;
}
else if (item->GetVnum() >= 16230 && item->GetVnum() <= 16239)
{
if (50626 != GetVnum())
return false;
else
return true;
}
return 50623 + type == GetVnum();
}
bool CItem::CheckItemUseLevel(int nLevel)
{
for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
{
if (this->m_pProto->aLimits[i].bType == LIMIT_LEVEL)
{
if (this->m_pProto->aLimits[i].lValue > nLevel) return false;
else return true;
}
}
return true;
}
long CItem::FindApplyValue(BYTE bApplyType)
{
if (m_pProto == NULL)
return 0;
for (int i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
{
if (m_pProto->aApplies[i].bType == bApplyType)
return m_pProto->aApplies[i].lValue;
}
return 0;
}
void CItem::CopySocketTo(LPITEM pItem)
{
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
{
pItem->m_alSockets[i] = m_alSockets[i];
}
}
int CItem::GetAccessorySocketGrade()
{
return MINMAX(0, GetSocket(0), GetAccessorySocketMaxGrade());
}
int CItem::GetAccessorySocketMaxGrade()
{
return MINMAX(0, GetSocket(1), ITEM_ACCESSORY_SOCKET_MAX_NUM);
}
int CItem::GetAccessorySocketDownGradeTime()
{
return MINMAX(0, GetSocket(2), aiAccessorySocketDegradeTime[GetAccessorySocketGrade()]);
}
void CItem::AttrLog()
{
const char * pszIP = NULL;
if (GetOwner() && GetOwner()->GetDesc())
pszIP = GetOwner()->GetDesc()->GetHostName();
for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
{
if (m_alSockets[i])
{
LogManager::instance().ItemLog(i, m_alSockets[i], 0, GetID(), "INFO_SOCKET", "", pszIP ? pszIP : "", GetOriginalVnum());
}
}
for (int i = 0; i<ITEM_ATTRIBUTE_MAX_NUM; ++i)
{
int type = m_aAttr[i].bType;
int value = m_aAttr[i].sValue;
if (type)
LogManager::instance().ItemLog(i, type, value, GetID(), "INFO_ATTR", "", pszIP ? pszIP : "", GetOriginalVnum());
}
}
int CItem::GetLevelLimit()
{
for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
{
if (this->m_pProto->aLimits[i].bType == LIMIT_LEVEL)
{
return this->m_pProto->aLimits[i].lValue;
}
}
return 0;
}
bool CItem::OnAfterCreatedItem()
{
// ¾ÆÀÌÅÛÀ» ÇÑ ¹øÀÌ¶óµµ »ç¿ëÇß´Ù¸é, ±× ÀÌÈÄ¿£ »ç¿ë ÁßÀÌÁö ¾Ê¾Æµµ ½Ã°£ÀÌ Â÷°¨µÇ´Â ¹æ½Ä
if (-1 != this->GetProto()->cLimitRealTimeFirstUseIndex)
{
// Socket1¿¡ ¾ÆÀÌÅÛÀÇ »ç¿ë Ƚ¼ö°¡ ±â·ÏµÇ¾î ÀÖÀ¸´Ï, ÇÑ ¹øÀÌ¶óµµ »ç¿ëÇÑ ¾ÆÀÌÅÛÀº ŸÀ̸Ӹ¦ ½ÃÀÛÇÑ´Ù.
if (0 != GetSocket(1))
{
StartRealTimeExpireEvent();
}
}
return true;
}
bool CItem::IsDragonSoul()
{
return GetType() == ITEM_DS;
}
int CItem::GiveMoreTime_Per(float fPercent)
{
if (IsDragonSoul())
{
DWORD duration = DSManager::instance().GetDuration(this);
int remain_sec = GetSocket(ITEM_SOCKET_REMAIN_SEC);
int given_time = fPercent * duration / 100;
if (remain_sec == duration)
return false;
if ((given_time + remain_sec) >= duration)
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, duration);
return duration - remain_sec;
}
else
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, given_time + remain_sec);
return given_time;
}
}
// ¿ì¼± ¿ëÈ¥¼®¿¡ °üÇØ¼*¸¸ Çϵµ·Ï ÇÑ´Ù.
else
return 0;
}
int CItem::GiveMoreTime_Fix(DWORD dwTime)
{
if (IsDragonSoul())
{
DWORD duration = DSManager::instance().GetDuration(this);
int remain_sec = GetSocket(ITEM_SOCKET_REMAIN_SEC);
if (remain_sec == duration)
return false;
if ((dwTime + remain_sec) >= duration)
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, duration);
return duration - remain_sec;
}
else
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, dwTime + remain_sec);
return dwTime;
}
}
// ¿ì¼± ¿ëÈ¥¼®¿¡ °üÇØ¼*¸¸ Çϵµ·Ï ÇÑ´Ù.
else
return 0;
}
int CItem::GetDuration()
{
if(!GetProto())
return -1;
for (int i=0 ; i < ITEM_LIMIT_MAX_NUM ; i++)
{
if (LIMIT_REAL_TIME == GetProto()->aLimits[i].bType)
return GetProto()->aLimits[i].lValue;
}
if (-1 != GetProto()->cLimitTimerBasedOnWearIndex)
return GetProto()->aLimits[GetProto()->cLimitTimerBasedOnWearIndex].lValue;
return -1;
}
bool CItem::IsSameSpecialGroup(const LPITEM item) const
{
// ¼*·Î VNUMÀÌ °°´Ù¸é °°Àº ±×·ìÀÎ °ÍÀ¸·Î °£ÁÖ
if (this->GetVnum() == item->GetVnum())
return true;
if (GetSpecialGroup() && (item->GetSpecialGroup() == GetSpecialGroup()))
return true;
return false;
}
DWORD CItem::GetRealImmuneFlag()
{
DWORD dwImmuneFlag = GetImmuneFlag();
for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
{
if (!GetAttribute(i).sValue)
continue;
if (GetAttribute(i).bType == APPLY_IMMUNE_STUN)
SET_BIT(dwImmuneFlag, IMMUNE_STUN);
else if (GetAttribute(i).bType == APPLY_IMMUNE_SLOW)
SET_BIT(dwImmuneFlag, IMMUNE_SLOW);
else if (GetAttribute(i).bType == APPLY_IMMUNE_FALL)
SET_BIT(dwImmuneFlag, IMMUNE_FALL);
}
return dwImmuneFlag;
}
Danke im Vorraus
Discord : IlIllIIll#2993