// 아이템 구입 void CShopManager::Buy(LPCHARACTER ch, BYTE pos) { if (!ch->GetShop()) return; if (!ch->GetShopOwner()) return; if (DISTANCE_APPROX(ch->GetX() - ch->GetShopOwner()->GetX(), ch->GetY() - ch->GetShopOwner()->GetY()) > 2000) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상점과의 거리가 너무 멀어 물건을 살 수 없습니다.")); return; } CShop* pkShop = ch->GetShop(); if (!pkShop->IsPCShop()) { //if (pkShop->GetVnum() == 0) // return; //const CMob* pkMob = CMobManager::instance().Get(pkShop->GetNPCVnum()); //if (!pkMob) // return; //if (pkMob->m_table.bType != CHAR_TYPE_NPC) //{ // return; //} } else { } //PREVENT_ITEM_COPY ch->SetMyShopTime(); //END_PREVENT_ITEM_COPY int ret = pkShop->Buy(ch, pos); if (SHOP_SUBHEADER_GC_OK != ret) // 문제가 있었으면 보낸다. { TPacketGCShop pack; pack.header = HEADER_GC_SHOP; pack.subheader = ret; pack.size = sizeof(TPacketGCShop); ch->GetDesc()->Packet(&pack, sizeof(pack)); } }
// 상점 거래를 종료 void CShopManager::StopShopping(LPCHARACTER ch) { LPSHOP shop; if (!(shop = ch->GetShop())) return; //PREVENT_ITEM_COPY; ch->SetMyShopTime(); //END_PREVENT_ITEM_COPY shop->RemoveGuest(ch); sys_log(0, "SHOP: END: %s", ch->GetName()); }
void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount) { if (!ch->GetShop()) return; if (!ch->GetShopOwner()) return; if (!ch->CanHandleItem()) return; if (ch->GetShop()->IsPCShop()) return; if (DISTANCE_APPROX(ch->GetX()-ch->GetShopOwner()->GetX(), ch->GetY()-ch->GetShopOwner()->GetY())>2000) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상점과의 거리가 너무 멀어 물건을 팔 수 없습니다.")); return; } LPITEM item = ch->GetInventoryItem(bCell); if (!item) return; if (item->IsEquipped() == true) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("착용 중인 아이템은 판매할 수 없습니다.")); return; } if (true == item->isLocked()) { return; } if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_SELL)) return; DWORD dwPrice; if (bCount == 0 || bCount > item->GetCount()) bCount = item->GetCount(); dwPrice = item->GetShopBuyPrice(); if (IS_SET(item->GetFlag(), ITEM_FLAG_COUNT_PER_1GOLD)) { if (dwPrice == 0) dwPrice = bCount; else dwPrice = bCount / dwPrice; } else dwPrice *= bCount; dwPrice /= 5; //세금 계산 DWORD dwTax = 0; int iVal = 3; if (LC_IsYMIR() || LC_IsKorea()) { dwTax = dwPrice * iVal / 100; dwPrice -= dwTax; } else { dwTax = dwPrice * iVal/100; dwPrice -= dwTax; } if (test_server) sys_log(0, "Sell Item price id %d %s itemid %d", ch->GetPlayerID(), ch->GetName(), item->GetID()); const int64_t nTotalMoney = static_cast<int64_t>(ch->GetGold()) + static_cast<int64_t>(dwPrice); if (GOLD_MAX <= nTotalMoney) { sys_err("[OVERFLOW_GOLD] id %u name %s gold %u", ch->GetPlayerID(), ch->GetName(), ch->GetGold()); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("20억냥이 초과하여 물품을 팔수 없습니다.")); return; } // 20050802.myevan.상점 판매 로그에 아이템 ID 추가 sys_log(0, "SHOP: SELL: %s item name: %s(x%d):%u price: %u", ch->GetName(), item->GetName(), bCount, item->GetID(), dwPrice); if (iVal > 0) ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("판매금액의 %d %% 가 세금으로 나가게됩니다"), iVal); DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), dwPrice); if (bCount == item->GetCount()) { // 한국에는 아이템을 버리고 복구해달라는 진상유저들이 많아서 // 상점 판매시 속성로그를 남긴다. if (LC_IsYMIR()) item->AttrLog(); ITEM_MANAGER::instance().RemoveItem(item, "SELL"); } else item->SetCount(item->GetCount() - bCount); //군주 시스템 : 세금 징수 CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch); ch->PointChange(POINT_GOLD, dwPrice, false); }
bool CShopEx::AddGuest(LPCHARACTER ch,DWORD owner_vid, bool bOtherEmpire) { if (!ch) return false; if (ch->GetExchange()) return false; if (ch->GetShop()) return false; ch->SetShop(this); m_map_guest.insert(GuestMapType::value_type(ch, bOtherEmpire)); TPacketGCShop pack; pack.header = HEADER_GC_SHOP; pack.subheader = SHOP_SUBHEADER_GC_START_EX; TPacketGCShopStartEx pack2; memset(&pack2, 0, sizeof(pack2)); pack2.owner_vid = owner_vid; pack2.shop_tab_count = m_vec_shopTabs.size(); char temp[8096]; // ГЦґл 1728 * 3 char* buf = &temp[0]; size_t size = 0; for (ShopTableExVector::const_iterator it = m_vec_shopTabs.begin(); it != m_vec_shopTabs.end(); it++) { const TShopTableEx& shop_tab = *it; TPacketGCShopStartEx::TSubPacketShopTab pack_tab; pack_tab.coin_type = shop_tab.coinType; memcpy(pack_tab.name, shop_tab.name.c_str(), SHOP_TAB_NAME_MAX); for (BYTE i = 0; i < SHOP_HOST_ITEM_MAX_NUM; i++) { pack_tab.items[i].vnum = shop_tab.items[i].vnum; pack_tab.items[i].count = shop_tab.items[i].count; switch(shop_tab.coinType) { case SHOP_COIN_TYPE_GOLD: if (bOtherEmpire) // no empire price penalty for pc shop pack_tab.items[i].price = shop_tab.items[i].price * 3; else pack_tab.items[i].price = shop_tab.items[i].price; break; case SHOP_COIN_TYPE_SECONDARY_COIN: pack_tab.items[i].price = shop_tab.items[i].price; break; } memset(pack_tab.items[i].aAttr, 0, sizeof(pack_tab.items[i].aAttr)); memset(pack_tab.items[i].alSockets, 0, sizeof(pack_tab.items[i].alSockets)); } memcpy(buf, &pack_tab, sizeof(pack_tab)); buf += sizeof(pack_tab); size += sizeof(pack_tab); } pack.size = sizeof(pack) + sizeof(pack2) + size; ch->GetDesc()->BufferedPacket(&pack, sizeof(TPacketGCShop)); ch->GetDesc()->BufferedPacket(&pack2, sizeof(TPacketGCShopStartEx)); ch->GetDesc()->Packet(temp, size); return true; }