Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
0
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;
}