2022-03-05 12:44:06 +02:00
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "../../libgame/include/grid.h"
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
#include "desc.h"
|
|
|
|
|
#include "desc_client.h"
|
|
|
|
|
#include "char.h"
|
|
|
|
|
#include "item.h"
|
|
|
|
|
#include "item_manager.h"
|
|
|
|
|
#include "packet.h"
|
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "db.h"
|
|
|
|
|
#include "locale_service.h"
|
2022-03-05 19:59:39 +02:00
|
|
|
|
#include <common/length.h>
|
2022-03-05 12:44:06 +02:00
|
|
|
|
#include "exchange.h"
|
|
|
|
|
#include "DragonSoul.h"
|
|
|
|
|
|
|
|
|
|
void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData = NULL);
|
|
|
|
|
|
|
|
|
|
// <20><>ȯ <20><>Ŷ
|
|
|
|
|
void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData)
|
|
|
|
|
{
|
|
|
|
|
if (!ch->GetDesc())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
struct packet_exchange pack_exchg;
|
|
|
|
|
|
|
|
|
|
pack_exchg.header = HEADER_GC_EXCHANGE;
|
|
|
|
|
pack_exchg.sub_header = sub_header;
|
|
|
|
|
pack_exchg.is_me = is_me;
|
|
|
|
|
pack_exchg.arg1 = arg1;
|
|
|
|
|
pack_exchg.arg2 = arg2;
|
|
|
|
|
pack_exchg.arg3 = arg3;
|
|
|
|
|
|
|
|
|
|
if (sub_header == EXCHANGE_SUBHEADER_GC_ITEM_ADD && pvData)
|
|
|
|
|
{
|
2022-03-06 17:36:43 +02:00
|
|
|
|
memcpy(&pack_exchg.alSockets, ((LPITEM) pvData)->GetSockets(), sizeof(pack_exchg.alSockets));
|
|
|
|
|
memcpy(&pack_exchg.aAttr, ((LPITEM) pvData)->GetAttributes(), sizeof(pack_exchg.aAttr));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
memset(&pack_exchg.alSockets, 0, sizeof(pack_exchg.alSockets));
|
|
|
|
|
memset(&pack_exchg.aAttr, 0, sizeof(pack_exchg.aAttr));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ch->GetDesc()->Packet(&pack_exchg, sizeof(pack_exchg));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
bool CHARACTER::ExchangeStart(LPCHARACTER victim)
|
|
|
|
|
{
|
|
|
|
|
if (this == victim) // <20>ڱ<EFBFBD> <20>ڽŰ<DABD><C5B0><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD>Ѵ<EFBFBD>.
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (IsObserverMode())
|
|
|
|
|
{
|
|
|
|
|
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (victim->IsNPC())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//PREVENT_TRADE_WINDOW
|
|
|
|
|
if ( IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen())
|
|
|
|
|
{
|
|
|
|
|
ChatPacket( CHAT_TYPE_INFO, LC_TEXT("<EFBFBD>ٸ<EFBFBD> <20>ŷ<EFBFBD>â<EFBFBD><C3A2> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ŷ<EFBFBD><C5B7><EFBFBD> <20>Ҽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>." ) );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() )
|
|
|
|
|
{
|
|
|
|
|
ChatPacket( CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٸ<EFBFBD> <20>ŷ<EFBFBD><C5B7><EFBFBD><EFBFBD>̶<EFBFBD> <20>ŷ<EFBFBD><C5B7><EFBFBD> <20>Ҽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>." ) );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//END_PREVENT_TRADE_WINDOW
|
|
|
|
|
int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY());
|
|
|
|
|
|
|
|
|
|
// <20>Ÿ<EFBFBD> üũ
|
|
|
|
|
if (iDist >= EXCHANGE_MAX_DISTANCE)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (GetExchange())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (victim->GetExchange())
|
|
|
|
|
{
|
|
|
|
|
exchange_packet(this, EXCHANGE_SUBHEADER_GC_ALREADY, 0, 0, NPOS, 0);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (victim->IsBlockMode(BLOCK_EXCHANGE))
|
|
|
|
|
{
|
|
|
|
|
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ <20>ź<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetExchange(M2_NEW CExchange(this));
|
|
|
|
|
victim->SetExchange(M2_NEW CExchange(victim));
|
|
|
|
|
|
|
|
|
|
victim->GetExchange()->SetCompany(GetExchange());
|
|
|
|
|
GetExchange()->SetCompany(victim->GetExchange());
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
SetExchangeTime();
|
|
|
|
|
victim->SetExchangeTime();
|
|
|
|
|
|
|
|
|
|
exchange_packet(victim, EXCHANGE_SUBHEADER_GC_START, 0, GetVID(), NPOS, 0);
|
|
|
|
|
exchange_packet(this, EXCHANGE_SUBHEADER_GC_START, 0, victim->GetVID(), NPOS, 0);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CExchange::CExchange(LPCHARACTER pOwner)
|
|
|
|
|
{
|
|
|
|
|
m_pCompany = NULL;
|
|
|
|
|
|
|
|
|
|
m_bAccept = false;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
|
|
|
|
|
{
|
|
|
|
|
m_apItems[i] = NULL;
|
|
|
|
|
m_aItemPos[i] = NPOS;
|
|
|
|
|
m_abItemDisplayPos[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_lGold = 0;
|
|
|
|
|
|
|
|
|
|
m_pOwner = pOwner;
|
|
|
|
|
pOwner->SetExchange(this);
|
|
|
|
|
|
|
|
|
|
m_pGrid = M2_NEW CGrid(4,3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CExchange::~CExchange()
|
|
|
|
|
{
|
|
|
|
|
M2_DELETE(m_pGrid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CExchange::AddItem(TItemPos item_pos, BYTE display_pos)
|
|
|
|
|
{
|
|
|
|
|
assert(m_pOwner != NULL && GetCompany());
|
|
|
|
|
|
|
|
|
|
if (!item_pos.IsValidItemPosition())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
if (item_pos.IsEquipPosition())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
LPITEM item;
|
|
|
|
|
|
|
|
|
|
if (!(item = m_pOwner->GetItem(item_pos)))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_GIVE))
|
|
|
|
|
{
|
|
|
|
|
m_pOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>dz<EFBFBD><C7B3><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (true == item->isLocked())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>̹<EFBFBD> <20><>ȯâ<C8AF><C3A2> <20>߰<EFBFBD><DFB0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD>?
|
|
|
|
|
if (item->IsExchanging())
|
|
|
|
|
{
|
|
|
|
|
sys_log(0, "EXCHANGE under exchanging");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!m_pGrid->IsEmpty(display_pos, 1, item->GetSize()))
|
|
|
|
|
{
|
|
|
|
|
sys_log(0, "EXCHANGE not empty item_pos %d %d %d", display_pos, 1, item->GetSize());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Accept(false);
|
|
|
|
|
GetCompany()->Accept(false);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (m_apItems[i])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
m_apItems[i] = item;
|
|
|
|
|
m_aItemPos[i] = item_pos;
|
|
|
|
|
m_abItemDisplayPos[i] = display_pos;
|
|
|
|
|
m_pGrid->Put(display_pos, 1, item->GetSize());
|
|
|
|
|
|
|
|
|
|
item->SetExchanging(true);
|
|
|
|
|
|
|
|
|
|
exchange_packet(m_pOwner,
|
|
|
|
|
EXCHANGE_SUBHEADER_GC_ITEM_ADD,
|
|
|
|
|
true,
|
|
|
|
|
item->GetVnum(),
|
|
|
|
|
TItemPos(RESERVED_WINDOW, display_pos),
|
|
|
|
|
item->GetCount(),
|
|
|
|
|
item);
|
|
|
|
|
|
|
|
|
|
exchange_packet(GetCompany()->GetOwner(),
|
|
|
|
|
EXCHANGE_SUBHEADER_GC_ITEM_ADD,
|
|
|
|
|
false,
|
|
|
|
|
item->GetVnum(),
|
|
|
|
|
TItemPos(RESERVED_WINDOW, display_pos),
|
|
|
|
|
item->GetCount(),
|
|
|
|
|
item);
|
|
|
|
|
|
|
|
|
|
sys_log(0, "EXCHANGE AddItem success %s pos(%d, %d) %d", item->GetName(), item_pos.window_type, item_pos.cell, display_pos);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>߰<EFBFBD><DFB0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CExchange::RemoveItem(BYTE pos)
|
|
|
|
|
{
|
|
|
|
|
if (pos >= EXCHANGE_ITEM_MAX_NUM)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!m_apItems[pos])
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
TItemPos PosOfInventory = m_aItemPos[pos];
|
|
|
|
|
m_apItems[pos]->SetExchanging(false);
|
|
|
|
|
|
|
|
|
|
m_pGrid->Get(m_abItemDisplayPos[pos], 1, m_apItems[pos]->GetSize());
|
|
|
|
|
|
|
|
|
|
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_DEL, true, pos, NPOS, 0);
|
|
|
|
|
exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_DEL, false, pos, PosOfInventory, 0);
|
|
|
|
|
|
|
|
|
|
Accept(false);
|
|
|
|
|
GetCompany()->Accept(false);
|
|
|
|
|
|
|
|
|
|
m_apItems[pos] = NULL;
|
|
|
|
|
m_aItemPos[pos] = NPOS;
|
|
|
|
|
m_abItemDisplayPos[pos] = 0;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CExchange::AddGold(long gold)
|
|
|
|
|
{
|
|
|
|
|
if (gold <= 0)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (GetOwner()->GetGold() < gold)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
|
|
|
|
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( LC_IsCanada() == true || LC_IsEurope() == true )
|
|
|
|
|
{
|
|
|
|
|
if ( m_lGold > 0 )
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Accept(false);
|
|
|
|
|
GetCompany()->Accept(false);
|
|
|
|
|
|
|
|
|
|
m_lGold = gold;
|
|
|
|
|
|
|
|
|
|
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, true, m_lGold, NPOS, 0);
|
|
|
|
|
exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, false, m_lGold, NPOS, 0);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD>, <20><>ȯ<EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> Ȯ<><C8AE> <20>Ѵ<EFBFBD>.
|
|
|
|
|
bool CExchange::Check(int * piItemCount)
|
|
|
|
|
{
|
|
|
|
|
if (GetOwner()->GetGold() < m_lGold)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
int item_count = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (!m_apItems[i])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (!m_aItemPos[i].IsValidItemPosition())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (m_apItems[i] != GetOwner()->GetItem(m_aItemPos[i]))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
++item_count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*piItemCount = item_count;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CExchange::CheckSpace()
|
|
|
|
|
{
|
|
|
|
|
static CGrid s_grid1(5, INVENTORY_MAX_NUM/5 / 2); // inven page 1
|
|
|
|
|
static CGrid s_grid2(5, INVENTORY_MAX_NUM/5 / 2); // inven page 2
|
|
|
|
|
|
|
|
|
|
s_grid1.Clear();
|
|
|
|
|
s_grid2.Clear();
|
|
|
|
|
|
|
|
|
|
LPCHARACTER victim = GetCompany()->GetOwner();
|
|
|
|
|
LPITEM item;
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < INVENTORY_MAX_NUM / 2; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (!(item = victim->GetInventoryItem(i)))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
s_grid1.Put(i, 1, item->GetSize());
|
|
|
|
|
}
|
|
|
|
|
for (i = INVENTORY_MAX_NUM / 2; i < INVENTORY_MAX_NUM; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (!(item = victim->GetInventoryItem(i)))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
s_grid2.Put(i - INVENTORY_MAX_NUM / 2, 1, item->GetSize());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>... <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>... <20><>ȥ<EFBFBD><C8A5> <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>߸<EFBFBD><DFB8>̴<EFBFBD> <20>Ф<EFBFBD>
|
|
|
|
|
static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM);
|
|
|
|
|
|
|
|
|
|
// <20>ϴ<EFBFBD> <20><>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD><C8AF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD> ũ<>Ƿ<EFBFBD>, <20><>ȥ<EFBFBD><C8A5> <20>κ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ϵ<EFBFBD><CFB5><EFBFBD> <20>Ѵ<EFBFBD>.
|
|
|
|
|
bool bDSInitialized = false;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (!(item = m_apItems[i]))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (item->IsDragonSoul())
|
|
|
|
|
{
|
|
|
|
|
if (!victim->DragonSoul_IsQualified())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!bDSInitialized)
|
|
|
|
|
{
|
|
|
|
|
bDSInitialized = true;
|
|
|
|
|
victim->CopyDragonSoulItemGrid(s_vDSGrid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool bExistEmptySpace = false;
|
|
|
|
|
WORD wBasePos = DSManager::instance().GetBasePosition(item);
|
|
|
|
|
if (wBasePos >= DRAGON_SOUL_INVENTORY_MAX_NUM)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < DRAGON_SOUL_BOX_SIZE; i++)
|
|
|
|
|
{
|
|
|
|
|
WORD wPos = wBasePos + i;
|
|
|
|
|
if (0 == s_vDSGrid[wBasePos])
|
|
|
|
|
{
|
|
|
|
|
bool bEmpty = true;
|
|
|
|
|
for (int j = 1; j < item->GetSize(); j++)
|
|
|
|
|
{
|
|
|
|
|
if (s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM])
|
|
|
|
|
{
|
|
|
|
|
bEmpty = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (bEmpty)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < item->GetSize(); j++)
|
|
|
|
|
{
|
|
|
|
|
s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM] = wPos + 1;
|
|
|
|
|
}
|
|
|
|
|
bExistEmptySpace = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (bExistEmptySpace)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!bExistEmptySpace)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int iPos = s_grid1.FindBlank(1, item->GetSize());
|
|
|
|
|
|
|
|
|
|
if (iPos >= 0)
|
|
|
|
|
{
|
|
|
|
|
s_grid1.Put(iPos, 1, item->GetSize());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
iPos = s_grid2.FindBlank(1, item->GetSize());
|
|
|
|
|
|
|
|
|
|
if (iPos >= 0)
|
|
|
|
|
{
|
|
|
|
|
s_grid2.Put(iPos, 1, item->GetSize());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>ȯ <20><> (<28><><EFBFBD><EFBFBD><EFBFBD>۰<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ű<EFBFBD><C5B1><EFBFBD>)
|
|
|
|
|
bool CExchange::Done()
|
|
|
|
|
{
|
|
|
|
|
int empty_pos, i;
|
|
|
|
|
LPITEM item;
|
|
|
|
|
|
|
|
|
|
LPCHARACTER victim = GetCompany()->GetOwner();
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (!(item = m_apItems[i]))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (item->IsDragonSoul())
|
|
|
|
|
empty_pos = victim->GetEmptyDragonSoulInventory(item);
|
|
|
|
|
else
|
|
|
|
|
empty_pos = victim->GetEmptyInventory(item->GetSize());
|
|
|
|
|
|
|
|
|
|
if (empty_pos < 0)
|
|
|
|
|
{
|
|
|
|
|
sys_err("Exchange::Done : Cannot find blank position in inventory %s <-> %s item %s",
|
|
|
|
|
m_pOwner->GetName(), victim->GetName(), item->GetName());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(empty_pos >= 0);
|
|
|
|
|
|
|
|
|
|
if (item->GetVnum() == 90008 || item->GetVnum() == 90009) // VCARD
|
|
|
|
|
{
|
|
|
|
|
VCardUse(m_pOwner, victim, item);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
|
|
|
|
|
|
|
|
|
|
item->RemoveFromCharacter();
|
|
|
|
|
if (item->IsDragonSoul())
|
|
|
|
|
item->AddToCharacter(victim, TItemPos(DRAGON_SOUL_INVENTORY, empty_pos));
|
|
|
|
|
else
|
|
|
|
|
item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
|
|
|
|
|
ITEM_MANAGER::instance().FlushDelayedSave(item);
|
|
|
|
|
|
|
|
|
|
item->SetExchanging(false);
|
|
|
|
|
{
|
|
|
|
|
char exchange_buf[51];
|
|
|
|
|
|
|
|
|
|
snprintf(exchange_buf, sizeof(exchange_buf), "%s %u %u", item->GetName(), GetOwner()->GetPlayerID(), item->GetCount());
|
|
|
|
|
LogManager::instance().ItemLog(victim, item, "EXCHANGE_TAKE", exchange_buf);
|
|
|
|
|
|
|
|
|
|
snprintf(exchange_buf, sizeof(exchange_buf), "%s %u %u", item->GetName(), victim->GetPlayerID(), item->GetCount());
|
|
|
|
|
LogManager::instance().ItemLog(GetOwner(), item, "EXCHANGE_GIVE", exchange_buf);
|
|
|
|
|
|
|
|
|
|
if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
|
|
|
|
|
{
|
|
|
|
|
LogManager::instance().GoldBarLog(victim->GetPlayerID(), item->GetID(), EXCHANGE_TAKE, "");
|
|
|
|
|
LogManager::instance().GoldBarLog(GetOwner()->GetPlayerID(), item->GetID(), EXCHANGE_GIVE, "");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_apItems[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_lGold)
|
|
|
|
|
{
|
|
|
|
|
GetOwner()->PointChange(POINT_GOLD, -m_lGold, true);
|
|
|
|
|
victim->PointChange(POINT_GOLD, m_lGold, true);
|
|
|
|
|
|
|
|
|
|
if (m_lGold > 1000)
|
|
|
|
|
{
|
|
|
|
|
char exchange_buf[51];
|
|
|
|
|
snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", GetOwner()->GetPlayerID(), GetOwner()->GetName());
|
|
|
|
|
LogManager::instance().CharLog(victim, m_lGold, "EXCHANGE_GOLD_TAKE", exchange_buf);
|
|
|
|
|
|
|
|
|
|
snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", victim->GetPlayerID(), victim->GetName());
|
|
|
|
|
LogManager::instance().CharLog(GetOwner(), m_lGold, "EXCHANGE_GOLD_GIVE", exchange_buf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pGrid->Clear();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
bool CExchange::Accept(bool bAccept)
|
|
|
|
|
{
|
|
|
|
|
if (m_bAccept == bAccept)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
m_bAccept = bAccept;
|
|
|
|
|
|
|
|
|
|
// <20><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><>ȯ <20><><EFBFBD><EFBFBD>
|
|
|
|
|
if (m_bAccept && GetCompany()->m_bAccept)
|
|
|
|
|
{
|
|
|
|
|
int iItemCount;
|
|
|
|
|
|
|
|
|
|
LPCHARACTER victim = GetCompany()->GetOwner();
|
|
|
|
|
|
|
|
|
|
//PREVENT_PORTAL_AFTER_EXCHANGE
|
|
|
|
|
GetOwner()->SetExchangeTime();
|
|
|
|
|
victim->SetExchangeTime();
|
|
|
|
|
//END_PREVENT_PORTAL_AFTER_EXCHANGE
|
|
|
|
|
|
|
|
|
|
// exchange_check <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD><EFBFBD>۵<EFBFBD><DBB5><EFBFBD> <20><><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD> <20>ֳ<EFBFBD> Ȯ<><C8AE><EFBFBD>ϰ<EFBFBD>,
|
|
|
|
|
// <20><>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ֳ<EFBFBD> Ȯ<><C8AE><EFBFBD>Ѵ<EFBFBD>, <20>ι<EFBFBD>° <20><><EFBFBD>ڷ<EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
|
|
|
|
if (!Check(&iItemCount))
|
|
|
|
|
{
|
|
|
|
|
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
goto EXCHANGE_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0> <20><><EFBFBD><EFBFBD> <20>ڸ<EFBFBD><DAB8><EFBFBD> <20>ֳ<EFBFBD> Ȯ<><C8AE><EFBFBD>Ѵ<EFBFBD>.
|
|
|
|
|
if (!CheckSpace())
|
|
|
|
|
{
|
|
|
|
|
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
goto EXCHANGE_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>浵 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
|
|
|
|
|
if (!GetCompany()->Check(&iItemCount))
|
|
|
|
|
{
|
|
|
|
|
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
goto EXCHANGE_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!GetCompany()->CheckSpace())
|
|
|
|
|
{
|
|
|
|
|
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
|
|
|
|
goto EXCHANGE_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (db_clientdesc->GetSocket() == INVALID_SOCKET)
|
|
|
|
|
{
|
|
|
|
|
sys_err("Cannot use exchange feature while DB cache connection is dead.");
|
|
|
|
|
victim->ChatPacket(CHAT_TYPE_INFO, "Unknown error");
|
|
|
|
|
GetOwner()->ChatPacket(CHAT_TYPE_INFO, "Unknown error");
|
|
|
|
|
goto EXCHANGE_END;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Done())
|
|
|
|
|
{
|
2022-03-06 17:36:43 +02:00
|
|
|
|
if (m_lGold) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ??<3F><> <20><><EFBFBD><EFBFBD>
|
2022-03-05 12:44:06 +02:00
|
|
|
|
GetOwner()->Save();
|
|
|
|
|
|
|
|
|
|
if (GetCompany()->Done())
|
|
|
|
|
{
|
|
|
|
|
if (GetCompany()->m_lGold) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
victim->Save();
|
|
|
|
|
|
|
|
|
|
// INTERNATIONAL_VERSION
|
|
|
|
|
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s <20><EFBFBD><D4B0><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>."), victim->GetName());
|
|
|
|
|
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s <20><EFBFBD><D4B0><EFBFBD> <20><>ȯ<EFBFBD><C8AF> <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>."), GetOwner()->GetName());
|
|
|
|
|
// END_OF_INTERNATIONAL_VERSION
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXCHANGE_END:
|
|
|
|
|
Cancel();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// <20>ƴϸ<C6B4> accept<70><74> <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|
|
|
|
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, true, m_bAccept, NPOS, 0);
|
|
|
|
|
exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, false, m_bAccept, NPOS, 0);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>ȯ <20><><EFBFBD><EFBFBD>
|
|
|
|
|
void CExchange::Cancel()
|
|
|
|
|
{
|
|
|
|
|
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_END, 0, 0, NPOS, 0);
|
|
|
|
|
GetOwner()->SetExchange(NULL);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (m_apItems[i])
|
|
|
|
|
m_apItems[i]->SetExchanging(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GetCompany())
|
|
|
|
|
{
|
|
|
|
|
GetCompany()->SetCompany(NULL);
|
|
|
|
|
GetCompany()->Cancel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
M2_DELETE(this);
|
|
|
|
|
}
|
|
|
|
|
|