Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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, long long arg1, TItemPos arg2, DWORD arg3, void * pvData = NULL);
- // ±łČŻ ĆĐŶ
- void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, long long 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,6);
- }
- 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 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 ( 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;
- }
- // µ·ŔĚ ĂćşĐČ÷ ŔÖ´ÂÁö, ±łČŻÇĎ·Á´Â ľĆŔĚĹŰŔĚ ˝ÇÁ¦·Î ŔÖ´ÂÁö Č®ŔÎ ÇŃ´Ů.
- 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 / 5); // inven page 1
- static CGrid s_grid2(5, INVENTORY_MAX_NUM / 5 / 5); // inven page 2
- static CGrid s_grid3(5, INVENTORY_MAX_NUM / 5 / 5); // inven page 3
- static CGrid s_grid4(5, INVENTORY_MAX_NUM / 5 / 5); // inven page 4
- static CGrid s_grid5(5, INVENTORY_MAX_NUM / 5 / 5); // inven page 5
- s_grid1.Clear();
- s_grid2.Clear();
- s_grid3.Clear();
- s_grid4.Clear();
- s_grid5.Clear();
- LPCHARACTER victim = GetCompany()->GetOwner();
- LPITEM item;
- int i;
- const int PageSlotCount = INVENTORY_MAX_NUM / 5;
- for (i = 0; i < INVENTORY_MAX_NUM; ++i)
- {
- if (!(item = victim->GetInventoryItem(i)))
- continue;
- BYTE itemSize = item->GetSize();
- if (i < PageSlotCount)
- s_grid1.Put(i, 1, itemSize);
- else if (i < PageSlotCount * 2)
- s_grid2.Put(i - PageSlotCount, 1, itemSize);
- else if (i < PageSlotCount * 3)
- s_grid3.Put(i - PageSlotCount * 2, 1, itemSize);
- else if (i < PageSlotCount * 4)
- s_grid4.Put(i - PageSlotCount * 3, 1, itemSize);
- else if (i < PageSlotCount * 5)
- s_grid5.Put(i - PageSlotCount * 4, 1, itemSize);
- }
- 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))
- continue;
- BYTE itemSize = item->GetSize();
- 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, itemSize);
- if (iPos >= 0)
- {
- s_grid1.Put(iPos, 1, itemSize);
- continue;
- }
- iPos = s_grid2.FindBlank(1, itemSize);
- if (iPos >= 0)
- {
- s_grid2.Put(iPos, 1, itemSize);
- continue;
- }
- iPos = s_grid3.FindBlank(1, itemSize);
- if (iPos >= 0)
- {
- s_grid3.Put(iPos, 1, itemSize);
- continue;
- }
- iPos = s_grid4.FindBlank(1, itemSize);
- if (iPos >= 0)
- {
- s_grid4.Put(iPos, 1, itemSize);
- continue;
- }
- iPos = s_grid5.FindBlank(1, itemSize);
- if (iPos >= 0)
- {
- s_grid5.Put(iPos, 1, itemSize);
- continue;
- }
- 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);
- if (item->GetVnum() == 90008 || item->GetVnum() == 90009) // VCARD
- {
- VCardUse(m_pOwner, victim, item);
- continue;
- }
- m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 1000);
- 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 (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);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement