int32 doSynthFail(CCharEntity* PChar) { uint8 carrentCraft = PChar->CraftContainer->getInvSlotID(0); double synthDiff = getSynthDifficulty(PChar, carrentCraft); double moghouseAura = 0; if (PChar->getZone() == 0) // неправильное условие, т.к. аура действует лишь в собственном доме { // Проверяем элемент синтеза switch (PChar->CraftContainer->getType()) { case ELEMENT_FIRE: moghouseAura = 0.05 * charutils::hasKeyItem(PChar,MOGHANCEMENT_FIRE); break; case ELEMENT_EARTH: moghouseAura = 0.05 * charutils::hasKeyItem(PChar,MOGHANCEMENT_EARTH); break; case ELEMENT_WATER: moghouseAura = 0.05 * charutils::hasKeyItem(PChar,MOGHANCEMENT_WATER); break; case ELEMENT_WIND: moghouseAura = 0.05 * charutils::hasKeyItem(PChar,MOGHANCEMENT_WIND); break; case ELEMENT_ICE: moghouseAura = 0.05 * charutils::hasKeyItem(PChar,MOGHANCEMENT_ICE); break; case ELEMENT_LIGHTNING: moghouseAura = 0.05 * charutils::hasKeyItem(PChar,MOGHANCEMENT_LIGHTNING); break; case ELEMENT_LIGHT: moghouseAura = 0.05 * charutils::hasKeyItem(PChar,MOGHANCEMENT_LIGHT); break; case ELEMENT_DARK: moghouseAura = 0.05 * charutils::hasKeyItem(PChar,MOGHANCEMENT_DARK); break; } if (moghouseAura == 0) { switch (carrentCraft) { case SKILL_WDW: moghouseAura = 0.075 * charutils::hasKeyItem(PChar,MOGLIFICATION_WOODWORKING); break; case SKILL_SMT: moghouseAura = 0.075 * charutils::hasKeyItem(PChar,MOGLIFICATION_SMITHING); break; case SKILL_GLD: moghouseAura = 0.075 * charutils::hasKeyItem(PChar,MOGLIFICATION_GOLDSMITHING); break; case SKILL_CLT: moghouseAura = 0.075 * charutils::hasKeyItem(PChar,MOGLIFICATION_CLOTHCRAFT); break; case SKILL_LTH: moghouseAura = 0.075 * charutils::hasKeyItem(PChar,MOGLIFICATION_LEATHERCRAFT); break; case SKILL_BON: moghouseAura = 0.075 * charutils::hasKeyItem(PChar,MOGLIFICATION_BONECRAFT); break; case SKILL_ALC: moghouseAura = 0.075 * charutils::hasKeyItem(PChar,MOGLIFICATION_ALCHEMY); break; case SKILL_COK: moghouseAura = 0.075 * charutils::hasKeyItem(PChar,MOGLIFICATION_COOKING); break; } } if (moghouseAura == 0) { switch (carrentCraft) { case SKILL_WDW: moghouseAura = 0.1 * charutils::hasKeyItem(PChar,MEGA_MOGLIFICATION_WOODWORKING); break; case SKILL_SMT: moghouseAura = 0.1 * charutils::hasKeyItem(PChar,MEGA_MOGLIFICATION_SMITHING); break; case SKILL_GLD: moghouseAura = 0.1 * charutils::hasKeyItem(PChar,MEGA_MOGLIFICATION_GOLDSMITHING); break; case SKILL_CLT: moghouseAura = 0.1 * charutils::hasKeyItem(PChar,MEGA_MOGLIFICATION_CLOTHCRAFT); break; case SKILL_LTH: moghouseAura = 0.1 * charutils::hasKeyItem(PChar,MEGA_MOGLIFICATION_LEATHERCRAFT); break; case SKILL_BON: moghouseAura = 0.1 * charutils::hasKeyItem(PChar,MEGA_MOGLIFICATION_BONECRAFT); break; case SKILL_ALC: moghouseAura = 0.1 * charutils::hasKeyItem(PChar,MEGA_MOGLIFICATION_ALCHEMY); break; case SKILL_COK: moghouseAura = 0.1 * charutils::hasKeyItem(PChar,MEGA_MOGLIFICATION_COOKING); break; } } } uint8 invSlotID = 0; uint8 nextSlotID = 0; uint8 lostCount = 0; double random = 0; double lostItem = 0.15 - moghouseAura + (synthDiff > 0 ? synthDiff/20 : 0); invSlotID = PChar->CraftContainer->getInvSlotID(1); for(uint8 slotID = 1; slotID <= 8; ++slotID) { if (slotID != 8) nextSlotID = PChar->CraftContainer->getInvSlotID(slotID+1); random = WELL512::drand(); #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Lost Item: %g Random: %g\n" CL_RESET, lostItem, random); #endif if(random < lostItem) { PChar->CraftContainer->setQuantity(slotID, 0); lostCount++; } if(invSlotID != nextSlotID) { CItem* PItem = PChar->getStorage(LOC_INVENTORY)->GetItem(invSlotID); if (PItem != NULL) { PItem->setSubType(ITEM_UNLOCKED); if(lostCount > 0) { #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Removing quantity %u from inventory slot %u\n" CL_RESET, lostCount, invSlotID); #endif charutils::UpdateItem(PChar, LOC_INVENTORY, invSlotID, -(int32)lostCount); lostCount = 0; }else{ PChar->pushPacket(new CInventoryAssignPacket(PItem, INV_NORMAL)); } } invSlotID = nextSlotID; nextSlotID = 0; } if(invSlotID == 0xFF) break; } if(PChar->loc.zone->GetID() != 255 && PChar->loc.zone->GetID() != 0) { PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE, new CSynthResultMessagePacket(PChar, SYNTH_FAIL)); PChar->pushPacket(new CSynthMessagePacket(PChar, SYNTH_FAIL)); } else { PChar->pushPacket(new CSynthMessagePacket(PChar, SYNTH_FAIL)); } return 0; }
int32 doSynthSkillUp(CCharEntity* PChar) { //if (PChar->CraftContainer->getType() == ELEMENT_LIGHTNING) //{ // return 0; //} bad idea, you cannot synth any item with lightning crystal // double MoonPhase = (double)CVanaTime::getInstance()->getMoonPhase(); // double MoonCorrection = MoonPhase / 500; // removed: there's no evidence that moon phase directly modifies skill up rate for(uint8 skillID = 49; skillID < 57; ++skillID) { if (PChar->CraftContainer->getQuantity(skillID-40) == 0) // получаем необходимый уровень умения рецепта { continue; } uint16 ModID = 0; switch (skillID) { case SKILL_WDW: ModID = MOD_WOOD; break; case SKILL_SMT: ModID = MOD_SMITH; break; case SKILL_GLD: ModID = MOD_GOLDSMITH; break; case SKILL_CLT: ModID = MOD_CLOTH; break; case SKILL_LTH: ModID = MOD_LEATHER; break; case SKILL_BON: ModID = MOD_BONE; break; case SKILL_ALC: ModID = MOD_ALCHEMY; break; case SKILL_COK: ModID = MOD_COOK; break; } uint8 skillRank = PChar->RealSkills.rank[skillID]; uint16 maxSkill = (skillRank+1)*100; int32 charSkill = PChar->RealSkills.skill[skillID]; int32 basDiff = PChar->CraftContainer->getQuantity(skillID-40) - (charSkill/10 + PChar->getMod(ModID)); //the 5 lvl difference rule for breaks does consider the effects of image support/gear double synthDiff = getSynthDifficulty(PChar, skillID); if ((basDiff <= 0) || ((basDiff > 5) && (PChar->CraftContainer->getQuantity(0) == SYNTHESIS_FAIL))) // результат синтеза хранится в quantity нулевой ячейки { continue; } if (charSkill < maxSkill) { double skillUpChance = (synthDiff*(map_config.craft_chance_multiplier - (log(1.2 + charSkill/100))))/10; skillUpChance = skillUpChance/(1 + (PChar->CraftContainer->getQuantity(0) == SYNTHESIS_FAIL)); // результат синтеза хранится в quantity нулевой ячейки double random = WELL512::drand(); #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Skill up chance: %g Random: %g\n" CL_RESET, skillUpChance, random); #endif if (random < skillUpChance) { int32 satier = 0; int32 skillAmount = 1; double chance = 0; if((synthDiff >= 1) && (synthDiff < 3)){ satier = 1; }else if((synthDiff >= 3) && (synthDiff < 5)){ satier = 2; }else if((synthDiff >= 5) && (synthDiff < 8)){ satier = 3; }else if((synthDiff >= 8) && (synthDiff < 10)){ satier = 4; }else if (synthDiff >= 10) satier = 5; //if (skillRank > 5) // satier--; for(uint8 i = 0; i < 4; i ++) { random = WELL512::drand(); #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"SkillAmount Tier: %i Random: %g\n" CL_RESET, satier, random); #endif switch(satier) { case 5: chance = 0.900; break; case 4: chance = 0.700; break; case 3: chance = 0.500; break; case 2: chance = 0.300; break; case 1: chance = 0.200; break; default: chance = 0.000; break; } if(chance < random) break; skillAmount += 1; satier -= 1; } // Do craft amount multiplier if (map_config.craft_amount_multiplier > 1) { skillAmount += skillAmount * map_config.craft_amount_multiplier; if (skillAmount > 9) { skillAmount = 9; } } if((skillAmount + charSkill) > maxSkill) { skillAmount = maxSkill - charSkill; } PChar->RealSkills.skill[skillID] += skillAmount; PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, skillID, skillAmount, 38)); if((charSkill/10) < (charSkill + skillAmount)/10) { PChar->WorkingSkills.skill[skillID] += 0x20; PChar->pushPacket(new CCharSkillsPacket(PChar)); PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, skillID, (charSkill + skillAmount)/10, 53)); } charutils::SaveCharSkills(PChar, skillID); } } } return 0; }
uint8 calcSynthResult(CCharEntity* PChar) { uint8 result = 1; uint8 hqtier = 0; uint8 mainID = getGeneralCraft(PChar); bool canHQ = true; double success = 0; double chance = 0; double MoonPhase = (double)CVanaTime::getInstance()->getMoonPhase(); uint8 WeekDay = (uint8)CVanaTime::getInstance()->getWeekday(); uint8 crystalElement = PChar->CraftContainer->getType(); uint8 strongElement[8] = {2,3,5,4,0,1,7,6}; for(uint8 skillID = 49; skillID < 57; ++skillID) { uint8 checkSkill = PChar->CraftContainer->getQuantity(skillID-40); if(checkSkill != 0) { double synthDiff = getSynthDifficulty(PChar, skillID); hqtier = 0; if(synthDiff <= 0) { success = 0.95; if((synthDiff <= 0) && (synthDiff >= -10)) { success -= (double)(PChar->CraftContainer->getType() == ELEMENT_LIGHTNING) * 0.2; hqtier = 1; } else if((synthDiff <= -11) && (synthDiff >= -30)) hqtier = 2; else if((synthDiff <= -31) && (synthDiff >= -50)) hqtier = 3; else if(synthDiff <= -51) hqtier = 4; } else { success = 0.95 - (synthDiff / 10) - (double)(PChar->CraftContainer->getType() == ELEMENT_LIGHTNING) * 0.2; canHQ = false; if(success < 0.05) success = 0.05; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"SkillID %u: difficulty > 0\n" CL_RESET, skillID); #endif } if(!canSynthesizeHQ(PChar,skillID)) { success += 0.01; //the crafting rings that block HQ synthesis all also increase their respective craft's success rate by 1% canHQ = false; //assuming here that if a crafting ring is used matching a recipe's subsynth, overall HQ will still be blocked } double random = WELL512::drand(); #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Success: %g Random: %g\n" CL_RESET, success, random); #endif if(random < success) { for(uint8 i = 0; i < 3; ++i) { if(mainID != skillID) break; random = WELL512::drand(); switch(hqtier) { //case 5: chance = 0.700; break; //Removed - HQ rate caps at 50% case 4: chance = 0.500; break; case 3: chance = 0.300; break; case 2: chance = 0.100; break; case 1: chance = 0.015; break; default: chance = 0.000; break; } if(chance > 0) { chance *= 1.0 - (MoonPhase - 50)/150; //new moon +33% of base rate bonus to hq chance, full moon -33%, corresponding/weakday/lightsday -33%, opposing/darksday +33% if (crystalElement == WeekDay) chance *= 1.0 - ((double)1/3); else if (strongElement[crystalElement] == WeekDay) chance *= 1.0 + ((double)1/3); else if (strongElement[WeekDay] == crystalElement) chance *= 1.0 - ((double)1/3); else if (WeekDay == LIGHTSDAY) chance *= 1.0 - ((double)1/3); else if (WeekDay == DARKSDAY) chance *= 1.0 + ((double)1/3); } if(chance > 0.500) chance = 0.500; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"HQ Tier: %i HQ Chance: %g Random: %g SkillID: %u\n" CL_RESET, hqtier, chance, random, skillID); #endif if(chance < random) break; result += 1; hqtier -= 1; } }else{ // сохраняем умение, из-за которого синтез провалился. // используем slotID ячейки кристалла, т.к. он был удален еще в начале синтеза PChar->CraftContainer->setInvSlotID(0,skillID); result = 0; break; } } } if(result > SYNTHESIS_SUCCESS && !canHQ) result = SYNTHESIS_SUCCESS; // результат синтеза записываем в поле quantity ячейки кристалла. PChar->CraftContainer->setQuantity(0, result); switch(result) { case SYNTHESIS_FAIL: result = RESULT_FAIL; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth failed.\n" CL_RESET); #endif break; case SYNTHESIS_SUCCESS: result = RESULT_SUCCESS; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth success.\n" CL_RESET); #endif break; case SYNTHESIS_HQ: result = RESULT_HQ; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth HQ.\n" CL_RESET); #endif break; case SYNTHESIS_HQ2: result = RESULT_HQ; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth HQ2.\n" CL_RESET); #endif break; case SYNTHESIS_HQ3: result = RESULT_HQ; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth HQ3.\n" CL_RESET); #endif break; } return result; }
int32 doSynthSkillUp(CCharEntity* PChar) { PROFILE_FUNC(); //if (PChar->CraftContainer->getType() == ELEMENT_LIGHTNING) //{ // return 0; //} bad idea, you cannot synth any item with lightning crystal double MoonPhase = (double)CVanaTime::getInstance()->getMoonPhase(); double MoonCorrection = MoonPhase / 500; for(uint8 skillID = 49; skillID < 57; ++skillID) { if (PChar->CraftContainer->getQuantity(skillID-40) == 0) // получаем необходимый уровень умения рецепта { continue; } uint8 skillRank = PChar->RealSkills.rank[skillID]; uint16 maxSkill = (skillRank+1)*100; int32 charSkill = PChar->RealSkills.skill[skillID]; int32 basDiff = PChar->CraftContainer->getQuantity(skillID-40) - charSkill/10; double synthDiff = getSynthDifficulty(PChar, skillID); if ((basDiff <= 0) || ((basDiff > 5) && (PChar->CraftContainer->getQuantity(0) == SYNTHESIS_FAIL))) // результат синтеза хранится в quantity нулевой ячейки { return 0; } if (charSkill < maxSkill) { double skillUpChance = (synthDiff*(map_config.craft_multiplier - (log(1.2 + charSkill/100) + MoonCorrection)))/10; skillUpChance = skillUpChance/(1 + (PChar->CraftContainer->getQuantity(0) == SYNTHESIS_FAIL)); // результат синтеза хранится в quantity нулевой ячейки double random = rand() / ((double)RAND_MAX); #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Skill up chance: %g Random: %g\n" CL_RESET, skillUpChance, random); #endif if (random < skillUpChance) { int32 satier = 0; int32 skillAmount = 1; double chance = 0; if((synthDiff >= 1) && (synthDiff < 3)){ satier = 1; }else if((synthDiff >= 3) && (synthDiff < 5)){ satier = 2; }else if((synthDiff >= 5) && (synthDiff < 8)){ satier = 3; }else if((synthDiff >= 8) && (synthDiff < 10)){ satier = 4; }else if (synthDiff >= 10) satier = 5; //if (skillRank > 5) // satier--; for(uint8 i = 0; i < 4; i ++) { random = rand() / ((double)RAND_MAX); #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"SkillAmount Tier: %i Random: %g\n" CL_RESET, satier, random); #endif switch(satier) { case 5: chance = 0.900; break; case 4: chance = 0.700; break; case 3: chance = 0.500; break; case 2: chance = 0.300; break; case 1: chance = 0.200; break; default: chance = 0.000; break; } if(chance < random) break; skillAmount += 1; satier -= 1; } if((skillAmount + charSkill) > maxSkill) { skillAmount = maxSkill - charSkill; } PChar->RealSkills.skill[skillID] += skillAmount; PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, skillID, skillAmount, 38)); if((charSkill/10) < (charSkill + skillAmount)/10) { PChar->WorkingSkills.skill[skillID] += 0x20; PChar->pushPacket(new CCharSkillsPacket(PChar)); PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, skillID, (charSkill + skillAmount)/10, 53)); } charutils::SaveCharSkills(PChar, skillID); } } } return 0; }
uint8 calcSynthResult(CCharEntity* PChar) { PROFILE_FUNC(); uint8 count = 0; uint8 result = 0; uint8 hqtier = 0; double success = 0; double chance = 0; for(uint8 skillID = 49; skillID < 57; ++skillID) { uint8 checkSkill = PChar->CraftContainer->getQuantity(skillID-40); if(checkSkill != 0) { double synthDiff = getSynthDifficulty(PChar, skillID); hqtier = 0; count++; if(synthDiff <= 0) { success = 0.95; if((synthDiff <= 0) && (synthDiff >= -10)){ success -= (double)(PChar->CraftContainer->getType() == ELEMENT_LIGHTNING) * 0.2; hqtier = 1; }else if((synthDiff <= -11) && (synthDiff >= -30)){ hqtier = 2; }else if((synthDiff <= -31) && (synthDiff >= -50)){ hqtier = 3; }else if((synthDiff <= -51) && (synthDiff >= -70)){ hqtier = 4; }else if (synthDiff <= -71) hqtier = 5; }else{ success = 0.95 - (synthDiff / 10) - (double)(PChar->CraftContainer->getType() == ELEMENT_LIGHTNING) * 0.2; if(success < 0.05) success = 0.05; } double random = rand() / ((double) RAND_MAX); #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Success: %g Random: %g\n" CL_RESET, success, random); #endif if(random < success) { for(int32 i = 0; i < 3; ++i) { random = rand() / ((double) RAND_MAX); #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"HQ Tier: %i Random: %g\n" CL_RESET, hqtier, random); #endif switch(hqtier) { case 5: chance = 0.700; break; case 4: chance = 0.500; break; case 3: chance = 0.300; break; case 2: chance = 0.100; break; case 1: chance = 0.015; break; default: chance = 0.000; break; } if(chance < random) break; result += 1; hqtier -= 1; } }else{ // сохраняем умение, из-за которого синтез провалился. // используем slotID ячейки кристалла, т.к. он был удален еще в начале синтеза PChar->CraftContainer->setInvSlotID(0,skillID); result = -1; break; } } } result = (count == 0 ? SYNTHESIS_SUCCESS : (result == 0xFF ? SYNTHESIS_FAIL : (result/count+1))); if ((result > SYNTHESIS_SUCCESS) && (!canSynthesizeHQ(PChar,getGeneralCraft(PChar)))) { result = SYNTHESIS_SUCCESS; } // результат синтеза записываем в поле quantity ячейки кристалла. PChar->CraftContainer->setQuantity(0, result); switch(result) { case SYNTHESIS_FAIL: result = RESULT_FAIL; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth failed.\n" CL_RESET); #endif break; case SYNTHESIS_SUCCESS: result = RESULT_SUCCESS; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth success.\n" CL_RESET); #endif break; case SYNTHESIS_HQ: result = RESULT_HQ; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth HQ.\n" CL_RESET); #endif break; case SYNTHESIS_HQ2: result = RESULT_HQ; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth HQ2.\n" CL_RESET); #endif break; case SYNTHESIS_HQ3: result = RESULT_HQ; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth HQ3.\n" CL_RESET); #endif break; } return result; }
uint8 calcSynthResult(CCharEntity* PChar) { uint8 result = SYNTHESIS_SUCCESS; uint8 hqtier = 0; uint8 mainID = getGeneralCraft(PChar); bool canHQ = true; double success = 0; double chance = 0; double MoonPhase = (double)CVanaTime::getInstance()->getMoonPhase(); uint8 WeekDay = (uint8)CVanaTime::getInstance()->getWeekday(); uint8 crystalElement = PChar->CraftContainer->getType(); uint8 strongElement[8] = {2,3,5,4,0,1,7,6}; for(uint8 skillID = 49; skillID < 57; ++skillID) { uint8 checkSkill = PChar->CraftContainer->getQuantity(skillID-40); if(checkSkill != 0) { double synthDiff = getSynthDifficulty(PChar, skillID); hqtier = 0; if(synthDiff <= 0) { success = 0.95; if(synthDiff > -11) //0-10 levels over recipe { success -= (double)(PChar->CraftContainer->getType() == ELEMENT_LIGHTNING) * 0.2; hqtier = 1; } else if(synthDiff > -31) //11-30 levels over recipe hqtier = 2; else if(synthDiff > -51) //31-50 levels over recipe hqtier = 3; else //51+ levels over recipe hqtier = 4; } else { success = 0.95 - (synthDiff / 10) - (double)(PChar->CraftContainer->getType() == ELEMENT_LIGHTNING) * 0.2; canHQ = false; if(success < 0.05) success = 0.05; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"SkillID %u: difficulty > 0\n" CL_RESET, skillID); #endif } // Apply synthesis success rate modifier int16 modSynthSuccess = PChar->getMod(Mod::SYNTH_SUCCESS); success += (double)modSynthSuccess * 0.01; if(!canSynthesizeHQ(PChar,skillID)) { success += 0.01; //the crafting rings that block HQ synthesis all also increase their respective craft's success rate by 1% canHQ = false; //assuming here that if a crafting ring is used matching a recipe's subsynth, overall HQ will still be blocked } if (success > 0.99) { // Clamp success rate to 0.99 // Even if using kitron macaron, breaks can still happen // https://www.bluegartr.com/threads/120352-CraftyMath // "I get a 99% success rate, so Kitron is doing something and it's not small." // http://www.ffxiah.com/item/5781/kitron-macaron // "According to one of the Japanese wikis, it is said to decrease the minimum break rate from ~5% to 0.5%-2%." success = 0.99; } double random = dsprand::GetRandomNumber(1.); #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Success: %g Random: %g\n" CL_RESET, success, random); #endif if(random < success) { if(mainID == skillID) { random = dsprand::GetRandomNumber(1.); switch(hqtier) { case 4: chance = 0.500; break; case 3: chance = 0.300; break; case 2: chance = 0.100; break; case 1: chance = 0.015; break; default: chance = 0.000; break; } if(chance > 0) { if (map_config.craft_moonphase_matters) chance *= 1.0 - (MoonPhase - 50)/150; //new moon +33% of base rate bonus to hq chance, full moon -33%, corresponding/weakday/lightsday -33%, opposing/darksday +33% if (map_config.craft_day_matters) { if (crystalElement == WeekDay) chance *= 1.0 - ((double)1 / 3); else if (strongElement[crystalElement] == WeekDay) chance *= 1.0 + ((double)1 / 3); else if (strongElement[WeekDay] == crystalElement) chance *= 1.0 - ((double)1 / 3); else if (WeekDay == LIGHTSDAY) chance *= 1.0 - ((double)1 / 3); else if (WeekDay == DARKSDAY) chance *= 1.0 + ((double)1 / 3); } chance = dsp_cap(chance, 0., 0.500); } #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"HQ Tier: %i HQ Chance: %g Random: %g SkillID: %u\n" CL_RESET, hqtier, chance, random, skillID); #endif if (random < chance && canHQ) { random = dsprand::GetRandomNumber(0, 16); if (random == 0) result = SYNTHESIS_HQ3; else if (random < 4) result = SYNTHESIS_HQ2; else result = SYNTHESIS_HQ; } } } else { // сохраняем умение, из-за которого синтез провалился. // используем slotID ячейки кристалла, т.к. он был удален еще в начале синтеза PChar->CraftContainer->setInvSlotID(0,skillID); result = SYNTHESIS_FAIL; break; } } } // результат синтеза записываем в поле quantity ячейки кристалла. PChar->CraftContainer->setQuantity(0, result); switch(result) { case SYNTHESIS_FAIL: result = RESULT_FAIL; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth failed.\n" CL_RESET); #endif break; case SYNTHESIS_SUCCESS: result = RESULT_SUCCESS; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth success.\n" CL_RESET); #endif break; case SYNTHESIS_HQ: result = RESULT_HQ; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth HQ.\n" CL_RESET); #endif break; case SYNTHESIS_HQ2: result = RESULT_HQ; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth HQ2.\n" CL_RESET); #endif break; case SYNTHESIS_HQ3: result = RESULT_HQ; #ifdef _DSP_SYNTH_DEBUG_MESSAGES_ ShowDebug(CL_CYAN"Synth HQ3.\n" CL_RESET); #endif break; } return result; }