void PC::Reward(LPCHARACTER ch) { if (m_bIsGivenReward) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<ДщЅєЖ®> АМАьїЎ °°Ає єё»уА» №ЮАє АыАМ АЦѕо ґЩЅГ №ЮБц ѕКЅАґПґЩ.")); m_bIsGivenReward = false; } for (vector<RewardData>::iterator it = m_vRewardData.begin(); it != m_vRewardData.end(); ++it) { switch (it->type) { case RewardData::REWARD_TYPE_EXP: sys_log(0, "EXP cur %d add %d next %d",ch->GetExp(), it->value1, ch->GetNextExp()); if (ch->GetExp() + it->value1 > ch->GetNextExp()) ch->PointChange(POINT_EXP, ch->GetNextExp() - 1 - ch->GetExp()); else ch->PointChange(POINT_EXP, it->value1); break; case RewardData::REWARD_TYPE_ITEM: ch->AutoGiveItem(it->value1, it->value2); break; case RewardData::REWARD_TYPE_NONE: default: sys_err("Invalid RewardData type"); break; } } m_vRewardData.clear(); }
void CItem::ClearMountAttributeAndAffect() { LPCHARACTER ch = GetOwner(); ch->RemoveAffect(AFFECT_MOUNT); ch->RemoveAffect(AFFECT_MOUNT_BONUS); ch->MountVnum(0); ch->PointChange(POINT_ST, 0); ch->PointChange(POINT_DX, 0); ch->PointChange(POINT_HT, 0); ch->PointChange(POINT_IQ, 0); }
void CParty::HealParty() { // XXX DELETEME 클라이언트 완료될때까지 { return; } if (!m_bPartyHealReady) return; TMemberMap::iterator it; LPCHARACTER l = GetLeaderCharacter(); for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (!it->second.pCharacter) continue; LPCHARACTER ch = it->second.pCharacter; if (DISTANCE_APPROX(l->GetX()-ch->GetX(), l->GetY()-ch->GetY()) < PARTY_DEFAULT_RANGE) { ch->PointChange(POINT_HP, ch->GetMaxHP()-ch->GetHP()); ch->PointChange(POINT_SP, ch->GetMaxSP()-ch->GetSP()); } } m_bPartyHealReady = false; m_dwPartyHealTime = get_dword_time(); }
void CParty::ComputeRolePoint(LPCHARACTER ch, BYTE bRole, bool bAdd) { if (!bAdd) { ch->PointChange(POINT_PARTY_ATTACKER_BONUS, -ch->GetPoint(POINT_PARTY_ATTACKER_BONUS)); ch->PointChange(POINT_PARTY_TANKER_BONUS, -ch->GetPoint(POINT_PARTY_TANKER_BONUS)); ch->PointChange(POINT_PARTY_BUFFER_BONUS, -ch->GetPoint(POINT_PARTY_BUFFER_BONUS)); ch->PointChange(POINT_PARTY_SKILL_MASTER_BONUS, -ch->GetPoint(POINT_PARTY_SKILL_MASTER_BONUS)); ch->PointChange(POINT_PARTY_DEFENDER_BONUS, -ch->GetPoint(POINT_PARTY_DEFENDER_BONUS)); ch->PointChange(POINT_PARTY_HASTE_BONUS, -ch->GetPoint(POINT_PARTY_HASTE_BONUS)); ch->ComputeBattlePoints(); return; } //SKILL_POWER_BY_LEVEL float k = (float) ch->GetSkillPowerByLevel( MIN(SKILL_MAX_LEVEL, m_iLeadership ) )/ 100.0f; //float k = (float) aiSkillPowerByLevel[MIN(SKILL_MAX_LEVEL, m_iLeadership)] / 100.0f; // //sys_log(0,"ComputeRolePoint %fi %d, %d ", k, SKILL_MAX_LEVEL, m_iLeadership ); //END_SKILL_POWER_BY_LEVEL switch (bRole) { case PARTY_ROLE_ATTACKER: { //int iBonus = (int) (10 + 90 * k); int iBonus = (int) (10 + 60 * k); if (ch->GetPoint(POINT_PARTY_ATTACKER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_ATTACKER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_ATTACKER_BONUS)); ch->ComputePoints(); } } break; case PARTY_ROLE_TANKER: { int iBonus = (int) (50 + 1450 * k); if (ch->GetPoint(POINT_PARTY_TANKER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_TANKER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_TANKER_BONUS)); ch->ComputePoints(); } } break; case PARTY_ROLE_BUFFER: { int iBonus = (int) (5 + 45 * k); if (ch->GetPoint(POINT_PARTY_BUFFER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_BUFFER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_BUFFER_BONUS)); } } break; case PARTY_ROLE_SKILL_MASTER: { int iBonus = (int) (25 + 600 * k); if (ch->GetPoint(POINT_PARTY_SKILL_MASTER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_SKILL_MASTER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_SKILL_MASTER_BONUS)); ch->ComputePoints(); } } break; case PARTY_ROLE_HASTE: { int iBonus = (int) (1+5*k); if (ch->GetPoint(POINT_PARTY_HASTE_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_HASTE_BONUS, iBonus - ch->GetPoint(POINT_PARTY_HASTE_BONUS)); ch->ComputePoints(); } } break; case PARTY_ROLE_DEFENDER: { int iBonus = (int) (5+30*k); if (ch->GetPoint(POINT_PARTY_DEFENDER_BONUS) != iBonus) { ch->PointChange(POINT_PARTY_DEFENDER_BONUS, iBonus - ch->GetPoint(POINT_PARTY_DEFENDER_BONUS)); ch->ComputePoints(); } } break; } }
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); }
int CShopEx::Buy(LPCHARACTER ch, BYTE pos) { BYTE tabIdx = pos / SHOP_HOST_ITEM_MAX_NUM; BYTE slotPos = pos % SHOP_HOST_ITEM_MAX_NUM; if (tabIdx >= GetTabCount()) { sys_log(0, "ShopEx::Buy : invalid position %d : %s", pos, ch->GetName()); return SHOP_SUBHEADER_GC_INVALID_POS; } sys_log(0, "ShopEx::Buy : name %s pos %d", ch->GetName(), pos); GuestMapType::iterator it = m_map_guest.find(ch); if (it == m_map_guest.end()) return SHOP_SUBHEADER_GC_END; TShopTableEx& shopTab = m_vec_shopTabs[tabIdx]; TShopItemTable& r_item = shopTab.items[slotPos]; if (r_item.price <= 0) { LogManager::instance().HackLog("SHOP_BUY_GOLD_OVERFLOW", ch); return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY; } DWORD dwPrice = r_item.price; switch (shopTab.coinType) { case SHOP_COIN_TYPE_GOLD: if (it->second) // if other empire, price is triple dwPrice *= 3; if (ch->GetGold() < (int) dwPrice) { sys_log(1, "ShopEx::Buy : Not enough money : %s has %d, price %d", ch->GetName(), ch->GetGold(), dwPrice); return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY; } break; case SHOP_COIN_TYPE_SECONDARY_COIN: { int count = ch->CountSpecifyTypeItem(ITEM_SECONDARY_COIN); if (count < dwPrice) { sys_log(1, "ShopEx::Buy : Not enough myeongdojun : %s has %d, price %d", ch->GetName(), count, dwPrice); return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_EX; } } break; } LPITEM item; item = ITEM_MANAGER::instance().CreateItem(r_item.vnum, r_item.count); if (!item) return SHOP_SUBHEADER_GC_SOLD_OUT; int iEmptyPos; if (item->IsDragonSoul()) { iEmptyPos = ch->GetEmptyDragonSoulInventory(item); } else { iEmptyPos = ch->GetEmptyInventory(item->GetSize()); } if (iEmptyPos < 0) { sys_log(1, "ShopEx::Buy : Inventory full : %s size %d", ch->GetName(), item->GetSize()); M2_DESTROY_ITEM(item); return SHOP_SUBHEADER_GC_INVENTORY_FULL; } switch (shopTab.coinType) { case SHOP_COIN_TYPE_GOLD: ch->PointChange(POINT_GOLD, -dwPrice, false); break; case SHOP_COIN_TYPE_SECONDARY_COIN: ch->RemoveSpecifyTypeItem(ITEM_SECONDARY_COIN, dwPrice); break; } if (item->IsDragonSoul()) item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos)); else item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); ITEM_MANAGER::instance().FlushDelayedSave(item); LogManager::instance().ItemLog(ch, item, "BUY", item->GetName()); if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007) { LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), PERSONAL_SHOP_BUY, ""); } DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), -dwPrice); if (item) sys_log(0, "ShopEx: BUY: name %s %s(x %d):%u price %u", ch->GetName(), item->GetName(), item->GetCount(), item->GetID(), dwPrice); if (LC_IsBrazil()) { ch->SaveReal(); db_clientdesc->DBPacketHeader(HEADER_GD_FLUSH_CACHE, 0, sizeof(DWORD)); DWORD pid = ch->GetPlayerID(); db_clientdesc->Packet(&pid, sizeof(DWORD)); } else { ch->Save(); } return (SHOP_SUBHEADER_GC_OK); }
bool DSManager::DoRefineStrength(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE]) { if (NULL == ch) return false; if (NULL == aItemPoses) { return false; } if (!ch->DragonSoul_RefineWindow_CanRefine()) { sys_err ("%s do not activate DragonSoulRefineWindow. But how can he come here?", ch->GetName()); ch->ChatPacket(CHAT_TYPE_INFO, "[SYSTEM ERROR]You cannot use dragon soul refine window."); return false; } // И¤ЅГіЄ ёрё¦ БЯє№µЗґВ item pointer ѕшѕЦ±в А§ЗШј set »зїл // АМ»уЗС ЖРЕ¶А» єёіѕ °жїм, БЯє№µИ TItemPos°Ў АЦА» јцµµ АЦ°н, АЯёшµИ TItemPos°Ў АЦА» јцµµ АЦґЩ. std::set <LPITEM> set_items; for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++) { LPITEM pItem = ch->GetItem(aItemPoses[i]); if (pItem) { set_items.insert(pItem); } } if (set_items.size() == 0) { return false; } int fee; LPITEM pRefineStone = NULL; LPITEM pDragonSoul = NULL; for (std::set <LPITEM>::iterator it = set_items.begin(); it != set_items.end(); it++) { LPITEM pItem = *it; // Е¬¶у uiїЎј АеВшЗС ѕЖАМЕЫАє °і·®ГўїЎ їГё± јц ѕшµµ·П ё·ѕТ±в ¶§№®їЎ, // є°µµАЗ ѕЛёІ Гіё®ґВ ѕИЗФ. if (pItem->IsEquipped()) { return false; } // їлИҐј®°ъ °Иј®ёёАМ °і·®ГўїЎ АЦА» јц АЦґЩ. // ±Чё®°н ЗПіЄѕїёё АЦѕоѕЯЗСґЩ. if (pItem->IsDragonSoul()) { if (pDragonSoul != NULL) { SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } pDragonSoul = pItem; } else if(IsDragonSoulRefineMaterial(pItem)) { if (pRefineStone != NULL) { SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } pRefineStone = pItem; } else { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°ИїЎ ЗКїдЗС Аз·б°Ў ѕЖґХґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } } BYTE bType, bGrade, bStep, bStrength; if (!pDragonSoul || !pRefineStone) { SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL, NPOS); return false; } if (NULL != pDragonSoul) { GetDragonSoulInfo(pDragonSoul->GetVnum(), bType, bGrade, bStep, bStrength); float fWeight = 0.f; // °ЎБЯДЎ °ЄАМ ѕшґЩёй °ИЗТ јц ѕшґВ їлИҐј® if (!m_pTable->GetWeight(bType, bGrade, bStep, bStrength + 1, fWeight)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°ИЗТ јц ѕшґВ їлИҐј®АФґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell())); return false; } // °ИЗЯА» ¶§ °ЎБЯДЎ°Ў 0АМ¶уёй ґх АМ»у °ИµЗјґВ ѕИµИґЩ. if (fWeight < FLT_EPSILON) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°ИЗТ јц ѕшґВ їлИҐј®АФґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell())); return false; } } float fProb; if (!m_pTable->GetRefineStrengthValues(bType, pRefineStone->GetSubType(), bStrength, fee, fProb)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°ИЗТ јц ѕшґВ їлИҐј®АФґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell())); return false; } if (ch->GetGold() < fee) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°і·®А» ЗП±в А§ЗС µ·АМ єОБ·ЗХґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY, NPOS); return false; } ch->PointChange(POINT_GOLD, -fee); LPITEM pResult = NULL; BYTE bSubHeader; if (fnumber(0.f, 100.f) <= fProb) { pResult = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(bType, bGrade, bStep, bStrength + 1)); if (NULL == pResult) { sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(bType, bGrade, bStep, bStrength + 1)); return false; } pDragonSoul->RemoveFromCharacter(); pDragonSoul->CopyAttributeTo(pResult); RefreshItemAttributes(pResult); pDragonSoul->SetCount(pDragonSoul->GetCount() - 1); pRefineStone->SetCount(pRefineStone->GetCount() - 1); char buf[128]; sprintf(buf, "STRENGTH : %d -> %d", bStrength, bStrength + 1); LogManager::instance().ItemLog(ch, pDragonSoul, "DS_STRENGTH_REFINE_SUCCESS", buf); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°ИїЎ јє°шЗЯЅАґПґЩ.")); ch->AutoGiveItem(pResult, true); bSubHeader = DS_SUB_HEADER_REFINE_SUCCEED; } else { if (bStrength != 0) { pResult = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(bType, bGrade, bStep, bStrength - 1)); if (NULL == pResult) { sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(bType, bGrade, bStep, bStrength - 1)); return false; } pDragonSoul->CopyAttributeTo(pResult); RefreshItemAttributes(pResult); } bSubHeader = DS_SUB_HEADER_REFINE_FAIL; char buf[128]; sprintf(buf, "STRENGTH : %d -> %d", bStrength, bStrength - 1); // strength°ИґВ ЅЗЖРЅГ ±ъБъ јцµµ АЦѕо, їшє» ѕЖАМЕЫА» №ЩЕБАё·О ·О±Чё¦ іІ±и. LogManager::instance().ItemLog(ch, pDragonSoul, "DS_STRENGTH_REFINE_FAIL", buf); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°ИїЎ ЅЗЖРЗЯЅАґПґЩ.")); pDragonSoul->SetCount(pDragonSoul->GetCount() - 1); pRefineStone->SetCount(pRefineStone->GetCount() - 1); if (NULL != pResult) ch->AutoGiveItem(pResult, true); } SendRefineResultPacket(ch, bSubHeader, NULL == pResult? NPOS : TItemPos (pResult->GetWindow(), pResult->GetCell())); return true; }
bool DSManager::DoRefineStep(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE]) { if (NULL == ch) return false; if (NULL == aItemPoses) { return false; } if (!ch->DragonSoul_RefineWindow_CanRefine()) { sys_err ("%s do not activate DragonSoulRefineWindow. But how can he come here?", ch->GetName()); ch->ChatPacket(CHAT_TYPE_INFO, "[SYSTEM ERROR]You cannot use dragon soul refine window."); return false; } // И¤ЅГіЄ ёрё¦ БЯє№µЗґВ item pointer ѕшѕЦ±в А§ЗШј set »зїл // АМ»уЗС ЖРЕ¶А» єёіѕ °жїм, БЯє№µИ TItemPos°Ў АЦА» јцµµ АЦ°н, АЯёшµИ TItemPos°Ў АЦА» јцµµ АЦґЩ. std::set <LPITEM> set_items; for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++) { LPITEM pItem = ch->GetItem(aItemPoses[i]); if (NULL != pItem) { // їлИҐј®АМ ѕЖґС ѕЖАМЕЫАМ °і·®ГўїЎ АЦА» јц ѕшґЩ. if (!pItem->IsDragonSoul()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ґЬ°и °і·®їЎ ЗКїдЗС Аз·б°Ў ѕЖґХґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } set_items.insert(pItem); } } if (set_items.size() == 0) { SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL, NPOS); return false; } std::string stGroupName; int count = set_items.size(); int need_count = 0; int fee = 0; std::vector <float> vec_probs; BYTE ds_type, grade_idx, step_idx, strength_idx; int result_step; // °ЎАе ГіАЅ °НА» °ИАЗ ±вБШАё·О »пґВґЩ. std::set <LPITEM>::iterator it = set_items.begin(); { LPITEM pItem = *it; GetDragonSoulInfo(pItem->GetVnum(), ds_type, grade_idx, step_idx, strength_idx); if (!m_pTable->GetRefineStepValues(ds_type, step_idx, need_count, fee, vec_probs)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ґЬ°и °і·®ЗТ јц ѕшґВ їлИҐј®АФґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } } while(++it != set_items.end()) { LPITEM pItem = *it; // Е¬¶у uiїЎј АеВшЗС ѕЖАМЕЫАє °і·®ГўїЎ їГё± јц ѕшµµ·П ё·ѕТ±в ¶§№®їЎ, // є°µµАЗ ѕЛёІ Гіё®ґВ ѕИЗФ. if (pItem->IsEquipped()) { return false; } if (ds_type != GetType(pItem->GetVnum()) || grade_idx != GetGradeIdx(pItem->GetVnum()) || step_idx != GetStepIdx(pItem->GetVnum())) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ґЬ°и °і·®їЎ ЗКїдЗС Аз·б°Ў ѕЖґХґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } } // Е¬¶уїЎј ЗС№ш °№јц ГјЕ©ё¦ ЗП±в ¶§№®їЎ count != need_count¶уёй invalid Е¬¶уАП °ЎґЙјєАМ Е©ґЩ. if (count != need_count) { sys_err ("Possiblity of invalid client. Name %s", ch->GetName()); BYTE bSubHeader = count < need_count? DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL : DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL; SendRefineResultPacket(ch, bSubHeader, NPOS); return false; } if (ch->GetGold() < fee) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°і·®А» ЗП±в А§ЗС µ·АМ єОБ·ЗХґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY, NPOS); return false; } float sum = 0.f; if (-1 == (result_step = Gamble(vec_probs))) { sys_err ("Gamble failed. See RefineStepTables' probabilities"); return false; } LPITEM pResultItem = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(ds_type, grade_idx, (BYTE)result_step, 0)); if (NULL == pResultItem) { sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(ds_type, grade_idx, (BYTE)result_step, 0)); return false; } ch->PointChange(POINT_GOLD, -fee); int left_count = need_count; for (std::set <LPITEM>::iterator it = set_items.begin(); it != set_items.end(); it++) { LPITEM pItem = *it; int n = pItem->GetCount(); if (left_count > n) { pItem->RemoveFromCharacter(); M2_DESTROY_ITEM(pItem); left_count -= n; } else { pItem->SetCount(n - left_count); } } ch->AutoGiveItem(pResultItem, true); if (result_step > step_idx) { char buf[128]; sprintf(buf, "STEP : %d -> %d", step_idx, result_step); LogManager::instance().ItemLog(ch, pResultItem, "DS_STEP_REFINE_SUCCESS", buf); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ґЬ°и °і·®їЎ јє°шЗЯЅАґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_SUCCEED, TItemPos (pResultItem->GetWindow(), pResultItem->GetCell())); return true; } else { char buf[128]; sprintf(buf, "STEP : %d -> %d", step_idx, result_step); LogManager::instance().ItemLog(ch, pResultItem, "DS_STEP_REFINE_FAIL", buf); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ґЬ°и °і·®їЎ ЅЗЖРЗЯЅАґПґЩ.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL, TItemPos (pResultItem->GetWindow(), pResultItem->GetCell())); return false; } }
bool DSManager::DoRefineStrength(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE]) { if (NULL == ch) return false; if (NULL == aItemPoses) { return false; } if (!ch->DragonSoul_RefineWindow_CanRefine()) { sys_err ("%s do not activate DragonSoulRefineWindow. But how can he come here?", ch->GetName()); ch->ChatPacket(CHAT_TYPE_INFO, "[SYSTEM ERROR]You cannot use dragon soul refine window."); return false; } // 혹시나 모를 중복되는 item pointer 없애기 위해서 set 사용 // 이상한 패킷을 보낼 경우, 중복된 TItemPos가 있을 수도 있고, 잘못된 TItemPos가 있을 수도 있다. std::set <LPITEM> set_items; for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++) { LPITEM pItem = ch->GetItem(aItemPoses[i]); if (pItem) { set_items.insert(pItem); } } if (set_items.size() == 0) { return false; } int fee; LPITEM pRefineStone = NULL; LPITEM pDragonSoul = NULL; for (std::set <LPITEM>::iterator it = set_items.begin(); it != set_items.end(); it++) { LPITEM pItem = *it; // 클라 ui에서 장착한 아이템은 개량창에 올릴 수 없도록 막았기 때문에, // 별도의 알림 처리는 안함. if (pItem->IsEquipped()) { return false; } // 용혼석과 강화석만이 개량창에 있을 수 있다. // 그리고 하나씩만 있어야한다. if (pItem->IsDragonSoul()) { if (pDragonSoul != NULL) { SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } pDragonSoul = pItem; } else if(IsDragonSoulRefineMaterial(pItem)) { if (pRefineStone != NULL) { SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } pRefineStone = pItem; } else { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화에 필요한 재료가 아닙니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } } BYTE bType, bGrade, bStep, bStrength; if (!pDragonSoul || !pRefineStone) { SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL, NPOS); return false; } if (NULL != pDragonSoul) { GetDragonSoulInfo(pDragonSoul->GetVnum(), bType, bGrade, bStep, bStrength); float fWeight = 0.f; // 가중치 값이 없다면 강화할 수 없는 용혼석 if (!m_pTable->GetWeight(bType, bGrade, bStep, bStrength + 1, fWeight)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화할 수 없는 용혼석입니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell())); return false; } // 강화했을 때 가중치가 0이라면 더 이상 강화되서는 안된다. if (fWeight < FLT_EPSILON) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화할 수 없는 용혼석입니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell())); return false; } } float fProb; if (!m_pTable->GetRefineStrengthValues(bType, pRefineStone->GetSubType(), bStrength, fee, fProb)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화할 수 없는 용혼석입니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell())); return false; } if (ch->GetGold() < fee) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량을 하기 위한 돈이 부족합니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY, NPOS); return false; } ch->PointChange(POINT_GOLD, -fee); LPITEM pResult = NULL; BYTE bSubHeader; if (fnumber(0.f, 100.f) <= fProb) { pResult = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(bType, bGrade, bStep, bStrength + 1)); if (NULL == pResult) { sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(bType, bGrade, bStep, bStrength + 1)); return false; } pDragonSoul->RemoveFromCharacter(); pDragonSoul->CopyAttributeTo(pResult); RefreshItemAttributes(pResult); pDragonSoul->SetCount(pDragonSoul->GetCount() - 1); pRefineStone->SetCount(pRefineStone->GetCount() - 1); char buf[128]; sprintf(buf, "STRENGTH : %d -> %d", bStrength, bStrength + 1); LogManager::instance().ItemLog(ch, pDragonSoul, "DS_STRENGTH_REFINE_SUCCESS", buf); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화에 성공했습니다.")); ch->AutoGiveItem(pResult, true); bSubHeader = DS_SUB_HEADER_REFINE_SUCCEED; } else { if (bStrength != 0) { pResult = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(bType, bGrade, bStep, bStrength - 1)); if (NULL == pResult) { sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(bType, bGrade, bStep, bStrength - 1)); return false; } pDragonSoul->CopyAttributeTo(pResult); RefreshItemAttributes(pResult); } bSubHeader = DS_SUB_HEADER_REFINE_FAIL; char buf[128]; sprintf(buf, "STRENGTH : %d -> %d", bStrength, bStrength - 1); // strength강화는 실패시 깨질 수도 있어, 원본 아이템을 바탕으로 로그를 남김. LogManager::instance().ItemLog(ch, pDragonSoul, "DS_STRENGTH_REFINE_FAIL", buf); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화에 실패했습니다.")); pDragonSoul->SetCount(pDragonSoul->GetCount() - 1); pRefineStone->SetCount(pRefineStone->GetCount() - 1); if (NULL != pResult) ch->AutoGiveItem(pResult, true); } SendRefineResultPacket(ch, bSubHeader, NULL == pResult? NPOS : TItemPos (pResult->GetWindow(), pResult->GetCell())); return true; }
bool DSManager::DoRefineStep(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE]) { if (NULL == ch) return false; if (NULL == aItemPoses) { return false; } if (!ch->DragonSoul_RefineWindow_CanRefine()) { sys_err ("%s do not activate DragonSoulRefineWindow. But how can he come here?", ch->GetName()); ch->ChatPacket(CHAT_TYPE_INFO, "[SYSTEM ERROR]You cannot use dragon soul refine window."); return false; } // 혹시나 모를 중복되는 item pointer 없애기 위해서 set 사용 // 이상한 패킷을 보낼 경우, 중복된 TItemPos가 있을 수도 있고, 잘못된 TItemPos가 있을 수도 있다. std::set <LPITEM> set_items; for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++) { LPITEM pItem = ch->GetItem(aItemPoses[i]); if (NULL != pItem) { // 용혼석이 아닌 아이템이 개량창에 있을 수 없다. if (!pItem->IsDragonSoul()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("단계 개량에 필요한 재료가 아닙니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } set_items.insert(pItem); } } if (set_items.size() == 0) { SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL, NPOS); return false; } std::string stGroupName; int count = set_items.size(); int need_count = 0; int fee = 0; std::vector <float> vec_probs; BYTE ds_type, grade_idx, step_idx, strength_idx; int result_step; // 가장 처음 것을 강화의 기준으로 삼는다. std::set <LPITEM>::iterator it = set_items.begin(); { LPITEM pItem = *it; GetDragonSoulInfo(pItem->GetVnum(), ds_type, grade_idx, step_idx, strength_idx); if (!m_pTable->GetRefineStepValues(ds_type, step_idx, need_count, fee, vec_probs)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("단계 개량할 수 없는 용혼석입니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } } while(++it != set_items.end()) { LPITEM pItem = *it; // 클라 ui에서 장착한 아이템은 개량창에 올릴 수 없도록 막았기 때문에, // 별도의 알림 처리는 안함. if (pItem->IsEquipped()) { return false; } if (ds_type != GetType(pItem->GetVnum()) || grade_idx != GetGradeIdx(pItem->GetVnum()) || step_idx != GetStepIdx(pItem->GetVnum())) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("단계 개량에 필요한 재료가 아닙니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell())); return false; } } // 클라에서 한번 갯수 체크를 하기 때문에 count != need_count라면 invalid 클라일 가능성이 크다. if (count != need_count) { sys_err ("Possiblity of invalid client. Name %s", ch->GetName()); BYTE bSubHeader = count < need_count? DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL : DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL; SendRefineResultPacket(ch, bSubHeader, NPOS); return false; } if (ch->GetGold() < fee) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량을 하기 위한 돈이 부족합니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY, NPOS); return false; } float sum = 0.f; if (-1 == (result_step = Gamble(vec_probs))) { sys_err ("Gamble failed. See RefineStepTables' probabilities"); return false; } LPITEM pResultItem = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(ds_type, grade_idx, (BYTE)result_step, 0)); if (NULL == pResultItem) { sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(ds_type, grade_idx, (BYTE)result_step, 0)); return false; } ch->PointChange(POINT_GOLD, -fee); int left_count = need_count; for (std::set <LPITEM>::iterator it = set_items.begin(); it != set_items.end(); it++) { LPITEM pItem = *it; int n = pItem->GetCount(); if (left_count > n) { pItem->RemoveFromCharacter(); M2_DESTROY_ITEM(pItem); left_count -= n; } else { pItem->SetCount(n - left_count); } } ch->AutoGiveItem(pResultItem, true); if (result_step > step_idx) { char buf[128]; sprintf(buf, "STEP : %d -> %d", step_idx, result_step); LogManager::instance().ItemLog(ch, pResultItem, "DS_STEP_REFINE_SUCCESS", buf); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("단계 개량에 성공했습니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_SUCCEED, TItemPos (pResultItem->GetWindow(), pResultItem->GetCell())); return true; } else { char buf[128]; sprintf(buf, "STEP : %d -> %d", step_idx, result_step); LogManager::instance().ItemLog(ch, pResultItem, "DS_STEP_REFINE_FAIL", buf); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("단계 개량에 실패했습니다.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL, TItemPos (pResultItem->GetWindow(), pResultItem->GetCell())); return false; } }