O am eu. Dă-mi MP
[ Postat de pe Android ]


Normal că să îți dea pm, de ce sa pui tu fixul aici pentru toți care vor sa foloseasca serverfilesul? Ca asa v-a zis si cartof in topic cand l-a postat, cine vrea serverfilesul sa-mi dea pm, nu?



Dacă o ai postează și aici să vadă și alții care folosesc acest serverfiles. Așa când aveți probleme imediat faceți subiecte și căutați rezolvarea, dar când o aveți nu postați și pentru alții. Nu e ok deloc


La mine nu functioneaza,cand dau accept la negot mi se inchide negotul...in sysser nu-mi apare nimic(am bagat azi barbut,insa nu merge corect momentan,dar nu cred ca e de la barbut)OnlyRipper scrie: ↑04 Sep 2019, 15:40
?!
Ce problema cu negotul.La mine functioneaza...ce faci exact de spuneti toti ca da crash la negot?

Pune te rog exchange.cpp si exchange.h sub forma de code si mai apoi spoiler aici.Kazuhiri scrie: ↑04 Sep 2019, 17:00La mine nu functioneaza,cand dau accept la negot mi se inchide negotul...in sysser nu-mi apare nimic(am bagat azi barbut,insa nu merge corect momentan,dar nu cred ca e de la barbut)OnlyRipper scrie: ↑04 Sep 2019, 15:40
?!
Ce problema cu negotul.La mine functioneaza...ce faci exact de spuneti toti ca da crash la negot?
Cod: Selectaţi tot
#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"
#include "../../common/length.h"
#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);
// 교환 패킷
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)
{
thecore_memcpy(&pack_exchg.alSockets, ((LPITEM) pvData)->GetSockets(), sizeof(pack_exchg.alSockets));
thecore_memcpy(&pack_exchg.aAttr, ((LPITEM) pvData)->GetAttributes(), sizeof(pack_exchg.aAttr));
}
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));
}
// 교환을 시작
bool CHARACTER::ExchangeStart(LPCHARACTER victim)
{
if (this == victim) // 자기 자신과는 교환을 못한다.
return false;
if (IsObserverMode())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관전 상태에서는 교환을 할 수 없습니다."));
return false;
}
if (victim->IsNPC())
return false;
//PREVENT_TRADE_WINDOW
if ( IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen())
{
ChatPacket( CHAT_TYPE_INFO, LC_TEXT("다른 거래창이 열려있을경우 거래를 할수 없습니다." ) );
return false;
}
if ( victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() )
{
ChatPacket( CHAT_TYPE_INFO, LC_TEXT("상대방이 다른 거래중이라 거래를 할수 없습니다." ) );
return false;
}
//END_PREVENT_TRADE_WINDOW
int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY());
// 거리 체크
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("상대방이 교환 거부 상태입니다."));
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;
// 장비는 교환할 수 없음
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("아이템을 건네줄 수 없습니다."));
return false;
}
if (true == item->isLocked())
{
return false;
}
// 이미 교환창에 추가된 아이템인가?
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;
}
// 추가할 공간이 없음
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)
{
// 가지고 있는 돈이 부족.
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0);
return false;
}
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;
}
// 돈이 충분히 있는지, 교환하려는 아이템이 실제로 있는지 확인 한다.
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 / 4); // inven page 1
static CGrid s_grid2(5, INVENTORY_MAX_NUM/5 / 4); // inven page 2
static CGrid s_grid3(5, INVENTORY_MAX_NUM/5 / 4); // inven page 3
static CGrid s_grid4(5, INVENTORY_MAX_NUM/5 / 4); // inven page 4
s_grid1.Clear();
s_grid2.Clear();
s_grid3.Clear();
s_grid4.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());
} */
for (i = 0; i < INVENTORY_MAX_NUM / 4; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;
s_grid1.Put(i, 1, item->GetSize());
}
for (i = INVENTORY_MAX_NUM / 4; i < (INVENTORY_MAX_NUM / 4) * 2; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;
s_grid2.Put(i - INVENTORY_MAX_NUM / 4, 1, item->GetSize());
}
for (i = (INVENTORY_MAX_NUM / 4) * 2; i < (INVENTORY_MAX_NUM / 4) * 3; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;
s_grid3.Put(i - (INVENTORY_MAX_NUM / 4) * 2, 1, item->GetSize());
}
for (i = (INVENTORY_MAX_NUM / 4) * 3; i < (INVENTORY_MAX_NUM / 4) * 4; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;
s_grid4.Put(i -(INVENTORY_MAX_NUM / 4) * 3, 1, item->GetSize());
}
/* #ifdef ENABLE_SPECIAL_STORAGE
LPITEM item2,item3;
static CGrid s_upp_grid1(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2);
static CGrid s_upp_grid2(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2);
static CGrid s_book_grid1(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2);
static CGrid s_book_grid2(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2);
static CGrid s_stone_grid1(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2);
static CGrid s_stone_grid2(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2);
s_upp_grid1.Clear();
s_upp_grid2.Clear();
s_book_grid1.Clear();
s_book_grid2.Clear();
s_stone_grid1.Clear();
s_stone_grid2.Clear();
for (int i = 0; i < SPECIAL_INVENTORY_MAX_NUM / 2; ++i)
{
if (!(item = victim->GetUpgradeInventoryItem(i)))
continue;
if (!(item2 = victim->GetBookInventoryItem(i)))
continue;
if (!(item3 = victim->GetStoneInventoryItem(i)))
continue;
s_upp_grid1.Put(i, 1, item->GetSize());
s_book_grid1.Put(i, 1, item2->GetSize());
s_stone_grid1.Put(i, 1, item3->GetSize());
}
for (int i = SPECIAL_INVENTORY_MAX_NUM / 2; i < SPECIAL_INVENTORY_MAX_NUM; ++i)
{
if (!(item = victim->GetUpgradeInventoryItem(i)))
continue;
if (!(item2 = victim->GetBookInventoryItem(i)))
continue;
if (!(item3 = victim->GetStoneInventoryItem(i)))
continue;
s_upp_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item->GetSize());
s_book_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item2->GetSize());
s_stone_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item3->GetSize());
}
#endif */
// 아... 뭔가 개병신 같지만... 용혼석 인벤을 노멀 인벤 보고 따라 만든 내 잘못이다 ㅠㅠ
static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM);
// 일단 용혼석을 교환하지 않을 가능성이 크므로, 용혼석 인벤 복사는 용혼석이 있을 때 하도록 한다.
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;
}
/* #ifdef ENABLE_SPECIAL_STORAGE
else if(item->IsUpgradeItem())
{
int iPos = s_upp_grid1.FindBlank(1, item->GetSize());
if (iPos >= 0)
s_upp_grid1.Put(iPos, 1, item->GetSize());
else
{
iPos = s_upp_grid2.FindBlank(1, item->GetSize());
if (iPos >= 0)
s_upp_grid2.Put(iPos, 1, item->GetSize());
else
return false;
}
}
else if(item->IsBook())
{
int iPos = s_book_grid1.FindBlank(1, item->GetSize());
if (iPos >= 0)
s_book_grid1.Put(iPos, 1, item->GetSize());
else
{
iPos = s_book_grid2.FindBlank(1, item->GetSize());
if (iPos >= 0)
s_book_grid2.Put(iPos, 1, item->GetSize());
else
return false;
}
}
else if(item->IsStone())
{
int iPos = s_stone_grid1.FindBlank(1, item->GetSize());
if (iPos >= 0)
s_stone_grid1.Put(iPos, 1, item->GetSize());
else
{
iPos = s_stone_grid2.FindBlank(1, item->GetSize());
if (iPos >= 0)
s_stone_grid2.Put(iPos, 1, item->GetSize());
else
return false;
}
}
#endif */
else
{
int iPos = s_grid1.FindBlank(1, item->GetSize());
if (iPos >= 0)
{
s_grid1.Put(iPos, 1, item->GetSize());
continue;
}
iPos = s_grid2.FindBlank(1, item->GetSize());
if (iPos >= 0)
{
s_grid2.Put(iPos, 1, item->GetSize());
continue;
}
iPos = s_grid3.FindBlank(1, item->GetSize());
if (iPos >= 0)
{
s_grid3.Put(iPos, 1, item->GetSize());
continue;
}
iPos = s_grid4.FindBlank(1, item->GetSize());
if (iPos >= 0)
{
s_grid4.Put(iPos, 1, item->GetSize());
continue;
}
return false; // No space left in inventory
}
}
return true;
}
/* 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;
} */
// 교환 끝 (아이템과 돈 등을 실제로 옮긴다)
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);
/* #ifdef ENABLE_SPECIAL_STORAGE
else if(item->IsUpgradeItem())
empty_pos = victim->GetEmptyUpgradeInventory(item);
else if(item->IsBook())
empty_pos = victim->GetEmptyBookInventory(item);
else if(item->IsStone())
empty_pos = victim->GetEmptyStoneInventory(item);
#endif */
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);
m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
item->RemoveFromCharacter();
if (item->IsDragonSoul())
item->AddToCharacter(victim, TItemPos(DRAGON_SOUL_INVENTORY, empty_pos));
/* #ifdef ENABLE_SPECIAL_STORAGE
else if(item->IsUpgradeItem())
item->AddToCharacter(victim, TItemPos(UPGRADE_INVENTORY, empty_pos));
else if(item->IsBook())
item->AddToCharacter(victim, TItemPos(BOOK_INVENTORY, empty_pos));
else if(item->IsStone())
item->AddToCharacter(victim, TItemPos(STONE_INVENTORY, empty_pos));
#endif */
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;
}
// 교환을 동의
bool CExchange::Accept(bool bAccept)
{
if (m_bAccept == bAccept)
return true;
m_bAccept = bAccept;
// 둘 다 동의 했으므로 교환 성립
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 에서는 교환할 아이템들이 제자리에 있나 확인하고,
// 엘크도 충분히 있나 확인한다, 두번째 인자로 교환할 아이템 개수
// 를 리턴한다.
if (!Check(&iItemCount))
{
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다."));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다."));
goto EXCHANGE_END;
}
// 리턴 받은 아이템 개수로 상대방의 소지품에 남은 자리가 있나 확인한다.
if (!CheckSpace())
{
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
goto EXCHANGE_END;
}
// 상대방도 마찬가지로..
if (!GetCompany()->Check(&iItemCount))
{
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다."));
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다."));
goto EXCHANGE_END;
}
if (!GetCompany()->CheckSpace())
{
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
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())
{
if (m_lGold) // 돈이 있을 만 저장
GetOwner()->Save();
if (GetCompany()->Done())
{
if (GetCompany()->m_lGold) // 돈이 있을 때만 저장
victim->Save();
// INTERNATIONAL_VERSION
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), victim->GetName());
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), GetOwner()->GetName());
// END_OF_INTERNATIONAL_VERSION
}
}
EXCHANGE_END:
Cancel();
return false;
}
else
{
// 아니면 accept에 대한 패킷을 보내자.
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;
}
}
// 교환 취소
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);
}
Cod: Selectaţi tot
#ifndef __INC_METIN_II_GAME_EXCHANGE_H__
#define __INC_METIN_II_GAME_EXCHANGE_H__
class CGrid;
enum EExchangeValues
{
EXCHANGE_ITEM_MAX_NUM = 12,
EXCHANGE_MAX_DISTANCE = 1000
};
class CExchange
{
public:
CExchange(LPCHARACTER pOwner);
~CExchange();
bool Accept(bool bIsAccept = true);
void Cancel();
bool AddGold(long lGold);
bool AddItem(TItemPos item_pos, BYTE display_pos);
bool RemoveItem(BYTE pos);
LPCHARACTER GetOwner() { return m_pOwner; }
CExchange * GetCompany() { return m_pCompany; }
bool GetAcceptStatus() { return m_bAccept; }
void SetCompany(CExchange * pExchange) { m_pCompany = pExchange; }
private:
bool Done();
bool Check(int * piItemCount);
bool CheckSpace();
private:
CExchange * m_pCompany; // 상대방의 CExchange 포인터
LPCHARACTER m_pOwner;
TItemPos m_aItemPos[EXCHANGE_ITEM_MAX_NUM];
LPITEM m_apItems[EXCHANGE_ITEM_MAX_NUM];
BYTE m_abItemDisplayPos[EXCHANGE_ITEM_MAX_NUM];
bool m_bAccept;
long m_lGold;
CGrid * m_pGrid;
};
#endif

exhange.cppOnlyRipper scrie: ↑04 Sep 2019, 17:21Pune te rog exchange.cpp si exchange.h sub forma de code si mai apoi spoiler aici.Kazuhiri scrie: ↑04 Sep 2019, 17:00La mine nu functioneaza,cand dau accept la negot mi se inchide negotul...in sysser nu-mi apare nimic(am bagat azi barbut,insa nu merge corect momentan,dar nu cred ca e de la barbut)OnlyRipper scrie: ↑04 Sep 2019, 15:40
?!
Ce problema cu negotul.La mine functioneaza...ce faci exact de spuneti toti ca da crash la negot?
Astea sunt ale mele.Vreau sa le compar sa vad...poate cand ai adaugat tu ceva ai sters ce nu trebuie.Este o problema intr-adevar,daca asa este el de la sine,nemodificat.Vreau sa vad si eu.
exchange.cppexchange.hABBC3_SPOILER_SHOWCod: Selectaţi tot
#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" #include "../../common/length.h" #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); // 교환 패킷 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) { thecore_memcpy(&pack_exchg.alSockets, ((LPITEM) pvData)->GetSockets(), sizeof(pack_exchg.alSockets)); thecore_memcpy(&pack_exchg.aAttr, ((LPITEM) pvData)->GetAttributes(), sizeof(pack_exchg.aAttr)); } 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)); } // 교환을 시작 bool CHARACTER::ExchangeStart(LPCHARACTER victim) { if (this == victim) // 자기 자신과는 교환을 못한다. return false; if (IsObserverMode()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관전 상태에서는 교환을 할 수 없습니다.")); return false; } if (victim->IsNPC()) return false; //PREVENT_TRADE_WINDOW if ( IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen()) { ChatPacket( CHAT_TYPE_INFO, LC_TEXT("다른 거래창이 열려있을경우 거래를 할수 없습니다." ) ); return false; } if ( victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() ) { ChatPacket( CHAT_TYPE_INFO, LC_TEXT("상대방이 다른 거래중이라 거래를 할수 없습니다." ) ); return false; } //END_PREVENT_TRADE_WINDOW int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY()); // 거리 체크 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("상대방이 교환 거부 상태입니다.")); 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; // 장비는 교환할 수 없음 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("아이템을 건네줄 수 없습니다.")); return false; } if (true == item->isLocked()) { return false; } // 이미 교환창에 추가된 아이템인가? 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; } // 추가할 공간이 없음 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) { // 가지고 있는 돈이 부족. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0); return false; } 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; } // 돈이 충분히 있는지, 교환하려는 아이템이 실제로 있는지 확인 한다. 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 / 4); // inven page 1 static CGrid s_grid2(5, INVENTORY_MAX_NUM/5 / 4); // inven page 2 static CGrid s_grid3(5, INVENTORY_MAX_NUM/5 / 4); // inven page 3 static CGrid s_grid4(5, INVENTORY_MAX_NUM/5 / 4); // inven page 4 s_grid1.Clear(); s_grid2.Clear(); s_grid3.Clear(); s_grid4.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()); } */ for (i = 0; i < INVENTORY_MAX_NUM / 4; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid1.Put(i, 1, item->GetSize()); } for (i = INVENTORY_MAX_NUM / 4; i < (INVENTORY_MAX_NUM / 4) * 2; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid2.Put(i - INVENTORY_MAX_NUM / 4, 1, item->GetSize()); } for (i = (INVENTORY_MAX_NUM / 4) * 2; i < (INVENTORY_MAX_NUM / 4) * 3; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid3.Put(i - (INVENTORY_MAX_NUM / 4) * 2, 1, item->GetSize()); } for (i = (INVENTORY_MAX_NUM / 4) * 3; i < (INVENTORY_MAX_NUM / 4) * 4; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid4.Put(i -(INVENTORY_MAX_NUM / 4) * 3, 1, item->GetSize()); } /* #ifdef ENABLE_SPECIAL_STORAGE LPITEM item2,item3; static CGrid s_upp_grid1(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_upp_grid2(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_book_grid1(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_book_grid2(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_stone_grid1(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_stone_grid2(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); s_upp_grid1.Clear(); s_upp_grid2.Clear(); s_book_grid1.Clear(); s_book_grid2.Clear(); s_stone_grid1.Clear(); s_stone_grid2.Clear(); for (int i = 0; i < SPECIAL_INVENTORY_MAX_NUM / 2; ++i) { if (!(item = victim->GetUpgradeInventoryItem(i))) continue; if (!(item2 = victim->GetBookInventoryItem(i))) continue; if (!(item3 = victim->GetStoneInventoryItem(i))) continue; s_upp_grid1.Put(i, 1, item->GetSize()); s_book_grid1.Put(i, 1, item2->GetSize()); s_stone_grid1.Put(i, 1, item3->GetSize()); } for (int i = SPECIAL_INVENTORY_MAX_NUM / 2; i < SPECIAL_INVENTORY_MAX_NUM; ++i) { if (!(item = victim->GetUpgradeInventoryItem(i))) continue; if (!(item2 = victim->GetBookInventoryItem(i))) continue; if (!(item3 = victim->GetStoneInventoryItem(i))) continue; s_upp_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item->GetSize()); s_book_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item2->GetSize()); s_stone_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item3->GetSize()); } #endif */ // 아... 뭔가 개병신 같지만... 용혼석 인벤을 노멀 인벤 보고 따라 만든 내 잘못이다 ㅠㅠ static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM); // 일단 용혼석을 교환하지 않을 가능성이 크므로, 용혼석 인벤 복사는 용혼석이 있을 때 하도록 한다. 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; } /* #ifdef ENABLE_SPECIAL_STORAGE else if(item->IsUpgradeItem()) { int iPos = s_upp_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) s_upp_grid1.Put(iPos, 1, item->GetSize()); else { iPos = s_upp_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) s_upp_grid2.Put(iPos, 1, item->GetSize()); else return false; } } else if(item->IsBook()) { int iPos = s_book_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) s_book_grid1.Put(iPos, 1, item->GetSize()); else { iPos = s_book_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) s_book_grid2.Put(iPos, 1, item->GetSize()); else return false; } } else if(item->IsStone()) { int iPos = s_stone_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) s_stone_grid1.Put(iPos, 1, item->GetSize()); else { iPos = s_stone_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) s_stone_grid2.Put(iPos, 1, item->GetSize()); else return false; } } #endif */ else { int iPos = s_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid1.Put(iPos, 1, item->GetSize()); continue; } iPos = s_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid2.Put(iPos, 1, item->GetSize()); continue; } iPos = s_grid3.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid3.Put(iPos, 1, item->GetSize()); continue; } iPos = s_grid4.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid4.Put(iPos, 1, item->GetSize()); continue; } return false; // No space left in inventory } } return true; } /* 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; } */ // 교환 끝 (아이템과 돈 등을 실제로 옮긴다) 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); /* #ifdef ENABLE_SPECIAL_STORAGE else if(item->IsUpgradeItem()) empty_pos = victim->GetEmptyUpgradeInventory(item); else if(item->IsBook()) empty_pos = victim->GetEmptyBookInventory(item); else if(item->IsStone()) empty_pos = victim->GetEmptyStoneInventory(item); #endif */ 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); m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255); item->RemoveFromCharacter(); if (item->IsDragonSoul()) item->AddToCharacter(victim, TItemPos(DRAGON_SOUL_INVENTORY, empty_pos)); /* #ifdef ENABLE_SPECIAL_STORAGE else if(item->IsUpgradeItem()) item->AddToCharacter(victim, TItemPos(UPGRADE_INVENTORY, empty_pos)); else if(item->IsBook()) item->AddToCharacter(victim, TItemPos(BOOK_INVENTORY, empty_pos)); else if(item->IsStone()) item->AddToCharacter(victim, TItemPos(STONE_INVENTORY, empty_pos)); #endif */ 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; } // 교환을 동의 bool CExchange::Accept(bool bAccept) { if (m_bAccept == bAccept) return true; m_bAccept = bAccept; // 둘 다 동의 했으므로 교환 성립 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 에서는 교환할 아이템들이 제자리에 있나 확인하고, // 엘크도 충분히 있나 확인한다, 두번째 인자로 교환할 아이템 개수 // 를 리턴한다. if (!Check(&iItemCount)) { GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다.")); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다.")); goto EXCHANGE_END; } // 리턴 받은 아이템 개수로 상대방의 소지품에 남은 자리가 있나 확인한다. if (!CheckSpace()) { GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다.")); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다.")); goto EXCHANGE_END; } // 상대방도 마찬가지로.. if (!GetCompany()->Check(&iItemCount)) { victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다.")); GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다.")); goto EXCHANGE_END; } if (!GetCompany()->CheckSpace()) { victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다.")); GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다.")); 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()) { if (m_lGold) // 돈이 있을 만 저장 GetOwner()->Save(); if (GetCompany()->Done()) { if (GetCompany()->m_lGold) // 돈이 있을 때만 저장 victim->Save(); // INTERNATIONAL_VERSION GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), victim->GetName()); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), GetOwner()->GetName()); // END_OF_INTERNATIONAL_VERSION } } EXCHANGE_END: Cancel(); return false; } else { // 아니면 accept에 대한 패킷을 보내자. 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; } } // 교환 취소 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); }ABBC3_SPOILER_SHOWCod: Selectaţi tot
#ifndef __INC_METIN_II_GAME_EXCHANGE_H__ #define __INC_METIN_II_GAME_EXCHANGE_H__ class CGrid; enum EExchangeValues { EXCHANGE_ITEM_MAX_NUM = 12, EXCHANGE_MAX_DISTANCE = 1000 }; class CExchange { public: CExchange(LPCHARACTER pOwner); ~CExchange(); bool Accept(bool bIsAccept = true); void Cancel(); bool AddGold(long lGold); bool AddItem(TItemPos item_pos, BYTE display_pos); bool RemoveItem(BYTE pos); LPCHARACTER GetOwner() { return m_pOwner; } CExchange * GetCompany() { return m_pCompany; } bool GetAcceptStatus() { return m_bAccept; } void SetCompany(CExchange * pExchange) { m_pCompany = pExchange; } private: bool Done(); bool Check(int * piItemCount); bool CheckSpace(); private: CExchange * m_pCompany; // 상대방의 CExchange 포인터 LPCHARACTER m_pOwner; TItemPos m_aItemPos[EXCHANGE_ITEM_MAX_NUM]; LPITEM m_apItems[EXCHANGE_ITEM_MAX_NUM]; BYTE m_abItemDisplayPos[EXCHANGE_ITEM_MAX_NUM]; bool m_bAccept; long m_lGold; CGrid * m_pGrid; }; #endif
Cod: Selectaţi tot
#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"
#include "../../common/length.h"
#include "exchange.h"
#include "DragonSoul.h"
#include "config.h"
#include "questmanager.h"
void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, BYTE dice, void * pvData = NULL);
// 교환 패킷
void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, BYTE dice, 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;
pack_exchg.dice = dice;
if (sub_header == EXCHANGE_SUBHEADER_GC_ITEM_ADD && pvData)
{
thecore_memcpy(&pack_exchg.alSockets, ((LPITEM) pvData)->GetSockets(), sizeof(pack_exchg.alSockets));
thecore_memcpy(&pack_exchg.aAttr, ((LPITEM) pvData)->GetAttributes(), sizeof(pack_exchg.aAttr));
}
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));
}
// 교환을 시작
bool CHARACTER::ExchangeStart(LPCHARACTER victim, BYTE dice)
{
if (this == victim) // 자기 자신과는 교환을 못한다.
return false;
if (IsObserverMode())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관전 상태에서는 교환을 할 수 없습니다."));
return false;
}
if (victim->IsNPC())
return false;
//PREVENT_TRADE_WINDOW
if ( IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen())
{
ChatPacket( CHAT_TYPE_INFO, LC_TEXT("다른 거래창이 열려있을경우 거래를 할수 없습니다." ) );
return false;
}
if ( victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() )
{
ChatPacket( CHAT_TYPE_INFO, LC_TEXT("상대방이 다른 거래중이라 거래를 할수 없습니다." ) );
return false;
}
//END_PREVENT_TRADE_WINDOW
int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY());
// 거리 체크
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, dice);
return false;
}
if (victim->IsBlockMode(BLOCK_EXCHANGE))
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방이 교환 거부 상태입니다."));
return false;
}
int dice_system = quest::CQuestManager::instance().GetEventFlag("dice_system");
if (dice == 1 && dice_system == 1)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceDISABLE"));
return false;
}
SetExchange(M2_NEW CExchange(this, dice));
victim->SetExchange(M2_NEW CExchange(victim, dice));
victim->GetExchange()->SetCompany(GetExchange());
GetExchange()->SetCompany(victim->GetExchange());
//
SetExchangeTime();
victim->SetExchangeTime();
exchange_packet(victim, EXCHANGE_SUBHEADER_GC_START, 0, GetVID(), NPOS, 0, dice);
exchange_packet(this, EXCHANGE_SUBHEADER_GC_START, 0, victim->GetVID(), NPOS, 0, dice);
return true;
}
CExchange::CExchange(LPCHARACTER pOwner, BYTE dice)
{
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_lDice = dice;
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;
// 장비는 교환할 수 없음
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("아이템을 건네줄 수 없습니다."));
return false;
}
if (true == item->isLocked())
{
return false;
}
// 이미 교환창에 추가된 아이템인가?
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(),
m_lDice,
item);
exchange_packet(GetCompany()->GetOwner(),
EXCHANGE_SUBHEADER_GC_ITEM_ADD,
false,
item->GetVnum(),
TItemPos(RESERVED_WINDOW, display_pos),
item->GetCount(),
m_lDice,
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;
}
// 추가할 공간이 없음
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, m_lDice);
exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_DEL, false, pos, PosOfInventory, 0, m_lDice);
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)
{
// 가지고 있는 돈이 부족.
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0, m_lDice);
return false;
}
if ( m_lGold > 0 )
{
return false;
}
if (m_lDice == 1)
return false;
Accept(false);
GetCompany()->Accept(false);
m_lGold = gold;
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, true, m_lGold, NPOS, 0, m_lDice);
exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, false, m_lGold, NPOS, 0, m_lDice);
return true;
}
// 돈이 충분히 있는지, 교환하려는 아이템이 실제로 있는지 확인 한다.
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());
}
// 아... 뭔가 개병신 같지만... 용혼석 인벤을 노멀 인벤 보고 따라 만든 내 잘못이다 ㅠㅠ
static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM);
// 일단 용혼석을 교환하지 않을 가능성이 크므로, 용혼석 인벤 복사는 용혼석이 있을 때 하도록 한다.
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;
}
// 교환 끝 (아이템과 돈 등을 실제로 옮긴다)
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);
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;
}
// 교환을 동의
bool CExchange::Accept(bool bAccept)
{
if (m_bAccept == bAccept)
return true;
m_bAccept = bAccept;
// 둘 다 동의 했으므로 교환 성립
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 에서는 교환할 아이템들이 제자리에 있나 확인하고,
// 엘크도 충분히 있나 확인한다, 두번째 인자로 교환할 아이템 개수
// 를 리턴한다.
if (!Check(&iItemCount))
{
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다."));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다."));
goto EXCHANGE_END;
}
// 리턴 받은 아이템 개수로 상대방의 소지품에 남은 자리가 있나 확인한다.
if (!CheckSpace())
{
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
goto EXCHANGE_END;
}
// 상대방도 마찬가지로..
if (!GetCompany()->Check(&iItemCount))
{
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다."));
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다."));
goto EXCHANGE_END;
}
if (!GetCompany()->CheckSpace())
{
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
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 (m_lDice == 1)
{
int myNumber = 0, targetNumber = 0, diceHasDone = 0;
myNumber = number(1,100); targetNumber = number(1, 100);
if (myNumber > targetNumber)
{
if (GetCompany()->Done())
diceHasDone = 1;
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceWon"));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceLoss"));
}
else if (myNumber < targetNumber)
{
if (Done())
diceHasDone = 1;
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceLoss"));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceWon"));
}
else
{
diceHasDone = 1;
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceNoWinner"));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceNoWinner"));
}
if (diceHasDone)
{
GetOwner()->ChatPacket(CHAT_TYPE_COMMAND, "DiceDone %d %d", myNumber, targetNumber);
victim->ChatPacket(CHAT_TYPE_COMMAND, "DiceDone %d %d", targetNumber, myNumber);
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s diceDone"), victim->GetName());
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s diceDone"), GetOwner()->GetName());
}
}else
{
if (Done())
{
if (m_lGold) // μ·AI AOA≫ ??¸¸ AuAa
GetOwner()->Save();
if (GetCompany()->Done())
{
if (GetCompany()->m_lGold) // μ·AI AOA≫ ¶§¸¸ AuAa
victim->Save();
// INTERNATIONAL_VERSION
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s ´O°uAC ±³E?AI ¼º≫c μC¾u½A´I´U."), victim->GetName());
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s ´O°uAC ±³E?AI ¼º≫c μC¾u½A´I´U."), GetOwner()->GetName());
// END_OF_INTERNATIONAL_VERSION
}
}
}
EXCHANGE_END:
Cancel();
return false;
}
else
{
// 아니면 accept에 대한 패킷을 보내자.
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, true, m_bAccept, NPOS, 0, m_lDice);
exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, false, m_bAccept, NPOS, 0, m_lDice);
return true;
}
}
// 교환 취소
void CExchange::Cancel()
{
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_END, 0, 0, NPOS, 0, m_lDice);
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);
}
Cod: Selectaţi tot
#ifndef __INC_METIN_II_GAME_EXCHANGE_H__
#define __INC_METIN_II_GAME_EXCHANGE_H__
class CGrid;
enum EExchangeValues
{
EXCHANGE_ITEM_MAX_NUM = 12,
EXCHANGE_MAX_DISTANCE = 1000
};
class CExchange
{
public:
CExchange(LPCHARACTER pOwner, BYTE dice);
~CExchange();
bool Accept(bool bIsAccept = true);
void Cancel();
bool AddGold(long lGold);
bool AddItem(TItemPos item_pos, BYTE display_pos);
bool RemoveItem(BYTE pos);
LPCHARACTER GetOwner() { return m_pOwner; }
CExchange * GetCompany() { return m_pCompany; }
bool GetAcceptStatus() { return m_bAccept; }
void SetCompany(CExchange * pExchange) { m_pCompany = pExchange; }
private:
bool Done();
bool Check(int * piItemCount);
bool CheckSpace();
private:
CExchange * m_pCompany; // 상대방의 CExchange 포인터
LPCHARACTER m_pOwner;
TItemPos m_aItemPos[EXCHANGE_ITEM_MAX_NUM];
LPITEM m_apItems[EXCHANGE_ITEM_MAX_NUM];
BYTE m_abItemDisplayPos[EXCHANGE_ITEM_MAX_NUM];
bool m_bAccept;
long m_lGold;
BYTE m_lDice;
CGrid * m_pGrid;
};
#endif

Nu stiu daca asta este rezolvarea pentru crash core la negot.Dar la o prima vedere as alinia cum trebuie liniile:Kazuhiri scrie: ↑04 Sep 2019, 17:33exhange.cppOnlyRipper scrie: ↑04 Sep 2019, 17:21Pune te rog exchange.cpp si exchange.h sub forma de code si mai apoi spoiler aici.
Astea sunt ale mele.Vreau sa le compar sa vad...poate cand ai adaugat tu ceva ai sters ce nu trebuie.Este o problema intr-adevar,daca asa este el de la sine,nemodificat.Vreau sa vad si eu.
exchange.cppexchange.hABBC3_SPOILER_SHOWCod: Selectaţi tot
#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" #include "../../common/length.h" #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); // 교환 패킷 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) { thecore_memcpy(&pack_exchg.alSockets, ((LPITEM) pvData)->GetSockets(), sizeof(pack_exchg.alSockets)); thecore_memcpy(&pack_exchg.aAttr, ((LPITEM) pvData)->GetAttributes(), sizeof(pack_exchg.aAttr)); } 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)); } // 교환을 시작 bool CHARACTER::ExchangeStart(LPCHARACTER victim) { if (this == victim) // 자기 자신과는 교환을 못한다. return false; if (IsObserverMode()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관전 상태에서는 교환을 할 수 없습니다.")); return false; } if (victim->IsNPC()) return false; //PREVENT_TRADE_WINDOW if ( IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen()) { ChatPacket( CHAT_TYPE_INFO, LC_TEXT("다른 거래창이 열려있을경우 거래를 할수 없습니다." ) ); return false; } if ( victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() ) { ChatPacket( CHAT_TYPE_INFO, LC_TEXT("상대방이 다른 거래중이라 거래를 할수 없습니다." ) ); return false; } //END_PREVENT_TRADE_WINDOW int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY()); // 거리 체크 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("상대방이 교환 거부 상태입니다.")); 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; // 장비는 교환할 수 없음 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("아이템을 건네줄 수 없습니다.")); return false; } if (true == item->isLocked()) { return false; } // 이미 교환창에 추가된 아이템인가? 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; } // 추가할 공간이 없음 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) { // 가지고 있는 돈이 부족. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0); return false; } 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; } // 돈이 충분히 있는지, 교환하려는 아이템이 실제로 있는지 확인 한다. 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 / 4); // inven page 1 static CGrid s_grid2(5, INVENTORY_MAX_NUM/5 / 4); // inven page 2 static CGrid s_grid3(5, INVENTORY_MAX_NUM/5 / 4); // inven page 3 static CGrid s_grid4(5, INVENTORY_MAX_NUM/5 / 4); // inven page 4 s_grid1.Clear(); s_grid2.Clear(); s_grid3.Clear(); s_grid4.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()); } */ for (i = 0; i < INVENTORY_MAX_NUM / 4; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid1.Put(i, 1, item->GetSize()); } for (i = INVENTORY_MAX_NUM / 4; i < (INVENTORY_MAX_NUM / 4) * 2; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid2.Put(i - INVENTORY_MAX_NUM / 4, 1, item->GetSize()); } for (i = (INVENTORY_MAX_NUM / 4) * 2; i < (INVENTORY_MAX_NUM / 4) * 3; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid3.Put(i - (INVENTORY_MAX_NUM / 4) * 2, 1, item->GetSize()); } for (i = (INVENTORY_MAX_NUM / 4) * 3; i < (INVENTORY_MAX_NUM / 4) * 4; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid4.Put(i -(INVENTORY_MAX_NUM / 4) * 3, 1, item->GetSize()); } /* #ifdef ENABLE_SPECIAL_STORAGE LPITEM item2,item3; static CGrid s_upp_grid1(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_upp_grid2(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_book_grid1(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_book_grid2(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_stone_grid1(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); static CGrid s_stone_grid2(5, SPECIAL_INVENTORY_MAX_NUM / 5 / 2); s_upp_grid1.Clear(); s_upp_grid2.Clear(); s_book_grid1.Clear(); s_book_grid2.Clear(); s_stone_grid1.Clear(); s_stone_grid2.Clear(); for (int i = 0; i < SPECIAL_INVENTORY_MAX_NUM / 2; ++i) { if (!(item = victim->GetUpgradeInventoryItem(i))) continue; if (!(item2 = victim->GetBookInventoryItem(i))) continue; if (!(item3 = victim->GetStoneInventoryItem(i))) continue; s_upp_grid1.Put(i, 1, item->GetSize()); s_book_grid1.Put(i, 1, item2->GetSize()); s_stone_grid1.Put(i, 1, item3->GetSize()); } for (int i = SPECIAL_INVENTORY_MAX_NUM / 2; i < SPECIAL_INVENTORY_MAX_NUM; ++i) { if (!(item = victim->GetUpgradeInventoryItem(i))) continue; if (!(item2 = victim->GetBookInventoryItem(i))) continue; if (!(item3 = victim->GetStoneInventoryItem(i))) continue; s_upp_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item->GetSize()); s_book_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item2->GetSize()); s_stone_grid2.Put(i - SPECIAL_INVENTORY_MAX_NUM / 2, 1, item3->GetSize()); } #endif */ // 아... 뭔가 개병신 같지만... 용혼석 인벤을 노멀 인벤 보고 따라 만든 내 잘못이다 ㅠㅠ static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM); // 일단 용혼석을 교환하지 않을 가능성이 크므로, 용혼석 인벤 복사는 용혼석이 있을 때 하도록 한다. 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; } /* #ifdef ENABLE_SPECIAL_STORAGE else if(item->IsUpgradeItem()) { int iPos = s_upp_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) s_upp_grid1.Put(iPos, 1, item->GetSize()); else { iPos = s_upp_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) s_upp_grid2.Put(iPos, 1, item->GetSize()); else return false; } } else if(item->IsBook()) { int iPos = s_book_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) s_book_grid1.Put(iPos, 1, item->GetSize()); else { iPos = s_book_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) s_book_grid2.Put(iPos, 1, item->GetSize()); else return false; } } else if(item->IsStone()) { int iPos = s_stone_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) s_stone_grid1.Put(iPos, 1, item->GetSize()); else { iPos = s_stone_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) s_stone_grid2.Put(iPos, 1, item->GetSize()); else return false; } } #endif */ else { int iPos = s_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid1.Put(iPos, 1, item->GetSize()); continue; } iPos = s_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid2.Put(iPos, 1, item->GetSize()); continue; } iPos = s_grid3.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid3.Put(iPos, 1, item->GetSize()); continue; } iPos = s_grid4.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid4.Put(iPos, 1, item->GetSize()); continue; } return false; // No space left in inventory } } return true; } /* 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; } */ // 교환 끝 (아이템과 돈 등을 실제로 옮긴다) 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); /* #ifdef ENABLE_SPECIAL_STORAGE else if(item->IsUpgradeItem()) empty_pos = victim->GetEmptyUpgradeInventory(item); else if(item->IsBook()) empty_pos = victim->GetEmptyBookInventory(item); else if(item->IsStone()) empty_pos = victim->GetEmptyStoneInventory(item); #endif */ 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); m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255); item->RemoveFromCharacter(); if (item->IsDragonSoul()) item->AddToCharacter(victim, TItemPos(DRAGON_SOUL_INVENTORY, empty_pos)); /* #ifdef ENABLE_SPECIAL_STORAGE else if(item->IsUpgradeItem()) item->AddToCharacter(victim, TItemPos(UPGRADE_INVENTORY, empty_pos)); else if(item->IsBook()) item->AddToCharacter(victim, TItemPos(BOOK_INVENTORY, empty_pos)); else if(item->IsStone()) item->AddToCharacter(victim, TItemPos(STONE_INVENTORY, empty_pos)); #endif */ 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; } // 교환을 동의 bool CExchange::Accept(bool bAccept) { if (m_bAccept == bAccept) return true; m_bAccept = bAccept; // 둘 다 동의 했으므로 교환 성립 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 에서는 교환할 아이템들이 제자리에 있나 확인하고, // 엘크도 충분히 있나 확인한다, 두번째 인자로 교환할 아이템 개수 // 를 리턴한다. if (!Check(&iItemCount)) { GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다.")); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다.")); goto EXCHANGE_END; } // 리턴 받은 아이템 개수로 상대방의 소지품에 남은 자리가 있나 확인한다. if (!CheckSpace()) { GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다.")); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다.")); goto EXCHANGE_END; } // 상대방도 마찬가지로.. if (!GetCompany()->Check(&iItemCount)) { victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다.")); GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다.")); goto EXCHANGE_END; } if (!GetCompany()->CheckSpace()) { victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다.")); GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다.")); 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()) { if (m_lGold) // 돈이 있을 만 저장 GetOwner()->Save(); if (GetCompany()->Done()) { if (GetCompany()->m_lGold) // 돈이 있을 때만 저장 victim->Save(); // INTERNATIONAL_VERSION GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), victim->GetName()); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), GetOwner()->GetName()); // END_OF_INTERNATIONAL_VERSION } } EXCHANGE_END: Cancel(); return false; } else { // 아니면 accept에 대한 패킷을 보내자. 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; } } // 교환 취소 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); }ABBC3_SPOILER_SHOWCod: Selectaţi tot
#ifndef __INC_METIN_II_GAME_EXCHANGE_H__ #define __INC_METIN_II_GAME_EXCHANGE_H__ class CGrid; enum EExchangeValues { EXCHANGE_ITEM_MAX_NUM = 12, EXCHANGE_MAX_DISTANCE = 1000 }; class CExchange { public: CExchange(LPCHARACTER pOwner); ~CExchange(); bool Accept(bool bIsAccept = true); void Cancel(); bool AddGold(long lGold); bool AddItem(TItemPos item_pos, BYTE display_pos); bool RemoveItem(BYTE pos); LPCHARACTER GetOwner() { return m_pOwner; } CExchange * GetCompany() { return m_pCompany; } bool GetAcceptStatus() { return m_bAccept; } void SetCompany(CExchange * pExchange) { m_pCompany = pExchange; } private: bool Done(); bool Check(int * piItemCount); bool CheckSpace(); private: CExchange * m_pCompany; // 상대방의 CExchange 포인터 LPCHARACTER m_pOwner; TItemPos m_aItemPos[EXCHANGE_ITEM_MAX_NUM]; LPITEM m_apItems[EXCHANGE_ITEM_MAX_NUM]; BYTE m_abItemDisplayPos[EXCHANGE_ITEM_MAX_NUM]; bool m_bAccept; long m_lGold; CGrid * m_pGrid; }; #endifexhange.hCod: Selectaţi tot
#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" #include "../../common/length.h" #include "exchange.h" #include "DragonSoul.h" #include "config.h" #include "questmanager.h" void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, BYTE dice, void * pvData = NULL); // 교환 패킷 void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, BYTE dice, 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; pack_exchg.dice = dice; if (sub_header == EXCHANGE_SUBHEADER_GC_ITEM_ADD && pvData) { thecore_memcpy(&pack_exchg.alSockets, ((LPITEM) pvData)->GetSockets(), sizeof(pack_exchg.alSockets)); thecore_memcpy(&pack_exchg.aAttr, ((LPITEM) pvData)->GetAttributes(), sizeof(pack_exchg.aAttr)); } 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)); } // 교환을 시작 bool CHARACTER::ExchangeStart(LPCHARACTER victim, BYTE dice) { if (this == victim) // 자기 자신과는 교환을 못한다. return false; if (IsObserverMode()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관전 상태에서는 교환을 할 수 없습니다.")); return false; } if (victim->IsNPC()) return false; //PREVENT_TRADE_WINDOW if ( IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen()) { ChatPacket( CHAT_TYPE_INFO, LC_TEXT("다른 거래창이 열려있을경우 거래를 할수 없습니다." ) ); return false; } if ( victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() ) { ChatPacket( CHAT_TYPE_INFO, LC_TEXT("상대방이 다른 거래중이라 거래를 할수 없습니다." ) ); return false; } //END_PREVENT_TRADE_WINDOW int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY()); // 거리 체크 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, dice); return false; } if (victim->IsBlockMode(BLOCK_EXCHANGE)) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방이 교환 거부 상태입니다.")); return false; } int dice_system = quest::CQuestManager::instance().GetEventFlag("dice_system"); if (dice == 1 && dice_system == 1) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceDISABLE")); return false; } SetExchange(M2_NEW CExchange(this, dice)); victim->SetExchange(M2_NEW CExchange(victim, dice)); victim->GetExchange()->SetCompany(GetExchange()); GetExchange()->SetCompany(victim->GetExchange()); // SetExchangeTime(); victim->SetExchangeTime(); exchange_packet(victim, EXCHANGE_SUBHEADER_GC_START, 0, GetVID(), NPOS, 0, dice); exchange_packet(this, EXCHANGE_SUBHEADER_GC_START, 0, victim->GetVID(), NPOS, 0, dice); return true; } CExchange::CExchange(LPCHARACTER pOwner, BYTE dice) { 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_lDice = dice; 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; // 장비는 교환할 수 없음 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("아이템을 건네줄 수 없습니다.")); return false; } if (true == item->isLocked()) { return false; } // 이미 교환창에 추가된 아이템인가? 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(), m_lDice, item); exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_ADD, false, item->GetVnum(), TItemPos(RESERVED_WINDOW, display_pos), item->GetCount(), m_lDice, 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; } // 추가할 공간이 없음 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, m_lDice); exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_DEL, false, pos, PosOfInventory, 0, m_lDice); 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) { // 가지고 있는 돈이 부족. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0, m_lDice); return false; } if ( m_lGold > 0 ) { return false; } if (m_lDice == 1) return false; Accept(false); GetCompany()->Accept(false); m_lGold = gold; exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, true, m_lGold, NPOS, 0, m_lDice); exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, false, m_lGold, NPOS, 0, m_lDice); return true; } // 돈이 충분히 있는지, 교환하려는 아이템이 실제로 있는지 확인 한다. 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()); } // 아... 뭔가 개병신 같지만... 용혼석 인벤을 노멀 인벤 보고 따라 만든 내 잘못이다 ㅠㅠ static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM); // 일단 용혼석을 교환하지 않을 가능성이 크므로, 용혼석 인벤 복사는 용혼석이 있을 때 하도록 한다. 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; } // 교환 끝 (아이템과 돈 등을 실제로 옮긴다) 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); 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; } // 교환을 동의 bool CExchange::Accept(bool bAccept) { if (m_bAccept == bAccept) return true; m_bAccept = bAccept; // 둘 다 동의 했으므로 교환 성립 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 에서는 교환할 아이템들이 제자리에 있나 확인하고, // 엘크도 충분히 있나 확인한다, 두번째 인자로 교환할 아이템 개수 // 를 리턴한다. if (!Check(&iItemCount)) { GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다.")); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다.")); goto EXCHANGE_END; } // 리턴 받은 아이템 개수로 상대방의 소지품에 남은 자리가 있나 확인한다. if (!CheckSpace()) { GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다.")); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다.")); goto EXCHANGE_END; } // 상대방도 마찬가지로.. if (!GetCompany()->Check(&iItemCount)) { victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다.")); GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다.")); goto EXCHANGE_END; } if (!GetCompany()->CheckSpace()) { victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다.")); GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다.")); 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 (m_lDice == 1) { int myNumber = 0, targetNumber = 0, diceHasDone = 0; myNumber = number(1,100); targetNumber = number(1, 100); if (myNumber > targetNumber) { if (GetCompany()->Done()) diceHasDone = 1; GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceWon")); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceLoss")); } else if (myNumber < targetNumber) { if (Done()) diceHasDone = 1; GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceLoss")); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceWon")); } else { diceHasDone = 1; GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceNoWinner")); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("diceNoWinner")); } if (diceHasDone) { GetOwner()->ChatPacket(CHAT_TYPE_COMMAND, "DiceDone %d %d", myNumber, targetNumber); victim->ChatPacket(CHAT_TYPE_COMMAND, "DiceDone %d %d", targetNumber, myNumber); GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s diceDone"), victim->GetName()); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s diceDone"), GetOwner()->GetName()); } }else { if (Done()) { if (m_lGold) // μ·AI AOA≫ ??¸¸ AuAa GetOwner()->Save(); if (GetCompany()->Done()) { if (GetCompany()->m_lGold) // μ·AI AOA≫ ¶§¸¸ AuAa victim->Save(); // INTERNATIONAL_VERSION GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s ´O°uAC ±³E?AI ¼º≫c μC¾u½A´I´U."), victim->GetName()); victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s ´O°uAC ±³E?AI ¼º≫c μC¾u½A´I´U."), GetOwner()->GetName()); // END_OF_INTERNATIONAL_VERSION } } } EXCHANGE_END: Cancel(); return false; } else { // 아니면 accept에 대한 패킷을 보내자. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, true, m_bAccept, NPOS, 0, m_lDice); exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, false, m_bAccept, NPOS, 0, m_lDice); return true; } } // 교환 취소 void CExchange::Cancel() { exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_END, 0, 0, NPOS, 0, m_lDice); 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); }Cod: Selectaţi tot
#ifndef __INC_METIN_II_GAME_EXCHANGE_H__ #define __INC_METIN_II_GAME_EXCHANGE_H__ class CGrid; enum EExchangeValues { EXCHANGE_ITEM_MAX_NUM = 12, EXCHANGE_MAX_DISTANCE = 1000 }; class CExchange { public: CExchange(LPCHARACTER pOwner, BYTE dice); ~CExchange(); bool Accept(bool bIsAccept = true); void Cancel(); bool AddGold(long lGold); bool AddItem(TItemPos item_pos, BYTE display_pos); bool RemoveItem(BYTE pos); LPCHARACTER GetOwner() { return m_pOwner; } CExchange * GetCompany() { return m_pCompany; } bool GetAcceptStatus() { return m_bAccept; } void SetCompany(CExchange * pExchange) { m_pCompany = pExchange; } private: bool Done(); bool Check(int * piItemCount); bool CheckSpace(); private: CExchange * m_pCompany; // 상대방의 CExchange 포인터 LPCHARACTER m_pOwner; TItemPos m_aItemPos[EXCHANGE_ITEM_MAX_NUM]; LPITEM m_apItems[EXCHANGE_ITEM_MAX_NUM]; BYTE m_abItemDisplayPos[EXCHANGE_ITEM_MAX_NUM]; bool m_bAccept; long m_lGold; BYTE m_lDice; CGrid * m_pGrid; }; #endif

Mai exact nu faceam nimic,dupa ce l-am urcat pe host fara nici o modificare s-a intamplat.Dar nu e singura problema,am implementat cateva sisteme.Se compileaza fara probleme,nu sunt nici macar warninguri la compilare si game si binary,porneste serverul dar cand da clientul sa se conecteze da crash la db.OnlyRipper scrie: ↑02 Sep 2019, 15:57Poti sa si spui ce faceai exact?jr1918 scrie: ↑01 Sep 2019, 10:11Salut,da,pe host se intampla,chiar m-am gandit ca-mi face tipu cu hostu vreo gluma. Acu e on de vreo 3 zile si nu s-a mai intamplatOnlyRipper scrie: ↑31 Aug 2019, 21:58
Eu inca lucrez pe acest svf.Nu am patit asta pana acum.Ce-i drept nu il tin non stop online.Lucrez pe el doar cand stau pelaptop.
L-ai urcat pe vreun host undeva?)
Din cate stiu eu datele din baza de date nu dispar asa pur si simplu.Trebuie sa faci ceva in fisiere sau cod/parte de cod care sa ti le afecteze.Sunt curios daca am si eu acceasi problema.

Nu are probleme, probleme are la cine nu stie sa lucreze.jr1918 scrie: ↑08 Sep 2019, 08:27Mai exact nu faceam nimic,dupa ce l-am urcat pe host fara nici o modificare s-a intamplat.Dar nu e singura problema,am implementat cateva sisteme.Se compileaza fara probleme,nu sunt nici macar warninguri la compilare si game si binary,porneste serverul dar cand da clientul sa se conecteze da crash la db.OnlyRipper scrie: ↑02 Sep 2019, 15:57Poti sa si spui ce faceai exact?
Din cate stiu eu datele din baza de date nu dispar asa pur si simplu.Trebuie sa faci ceva in fisiere sau cod/parte de cod care sa ti le afecteze.Sunt curios daca am si eu acceasi problema.
Are cam multe probleme,nu e stabil,nu recomand sa se inceapa pe el.E bun pentru comparatii.Nu dadea nimeni free o resursa clean,stabila fara buguri,crash,sa fim seriosi.Dupa cum scria cineva pe pagina anterioara cine vrea server file sa-i dea pm lui Cartof.
Bafta cu rezolvarile,eu l-am sters din VB

Utilizatori ce ce navighează pe acest forum: Niciun utilizator înregistrat și 9 vizitatori
