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 = 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; }
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; }