Contributor Amun 1899 Posted April 14, 2022 Contributor Share Posted April 14, 2022 (edited) Hello, good people! I was writing something to validate the server data(like blend.txt, cube, etc) and stumbled upon this lovely comment: Quote // Choong Ki-hwan's probability table // It would be neat if we fix it so that it also receives the probability from blend.txt // by rtsummit So then I asked myself "Why not?" Anyhow, here's the code(everything is in blend_item.cpp): // after the last #include, add #include <random> // Optional: You can add this after the last import if you want. // I've replaced the "Token" thing because Visual Studio was playing tricks with the tabs and it was too annoying. #define str_match(s1,s2) _stricmp(s1,s2)==0 // or, if you want, you can just completely replace the Token stuff, like I did. Up to you, it's just optional stuff.. // Anyhow, now edit this struct: struct BLEND_ITEM_INFO { DWORD item_vnum; int apply_type; int apply_value[MAX_BLEND_ITEM_VALUE]; int apply_duration[MAX_BLEND_ITEM_VALUE]; // add these int apply_prob[MAX_BLEND_ITEM_VALUE]; int duration_prob[MAX_BLEND_ITEM_VALUE]; int apply_prob_sum;// we'll just do the sum straight away int duration_prob_sum;// since we have to check if it has probability or not }; // search for static int FN_random_index() // add these before(or after.. whatever) // You don't really have to add this, you can just use number(min, max) if you want to int Randomi(int minx, int maxx) { std::random_device rd; // obtain a random number from hardware std::mt19937 gen(rd()); // seed the generator std::uniform_int_distribution<> distr(minx, maxx); // define the range return distr(gen); } int RandomFromProbs(int probs[], int probsSum) { int rand = Randomi(1, probsSum); int accumulated = 0; for (int i = 0; i < MAX_BLEND_ITEM_VALUE; i++) { // this is just a fallback in case someone puts 0 for all of them // or maybe we should call FN_random_index from here instead? // up to you.. if (i == MAX_BLEND_ITEM_VALUE - 1) return i; // if the probability is 0, then it's disabled, skip it if (!probs[i]) continue; accumulated += probs[i]; if (rand <= accumulated) return i; } } // search for else Token("end") // Add this before // if you didn't add that define, change these to Token // here: else Token("apply_prob") // and the second one: else Token("duration_prob") else if (0 == strcmp(key, "apply_prob")) { for (int i = 0; i < MAX_BLEND_ITEM_VALUE; ++i) { v = strtok(NULL, delim); if (!v) { fclose(fp); return false; } blend_item_info->apply_prob_sum += std::stoi(v); str_to_number(blend_item_info->apply_prob[i], v); } } else if (0 == strcmp(key, "duration_prob")) { for (int i = 0; i < MAX_BLEND_ITEM_VALUE; ++i) { v = strtok(NULL, delim); if (!v) { fclose(fp); return false; } blend_item_info->duration_prob_sum += std::stoi(v); str_to_number(blend_item_info->duration_prob[i], v); } } // Search for bool Blend_Item_set_value(LPITEM item) // Inside look for: if (item->GetVnum() == 51002) // energy crystal { apply_type = blend_info->apply_type; apply_value = blend_info->apply_value[FN_ECS_random_index()]; apply_duration = blend_info->apply_duration[FN_ECS_random_index()]; } else { apply_type = blend_info->apply_type; apply_value = blend_info->apply_value[FN_random_index()]; apply_duration = blend_info->apply_duration[FN_random_index()]; } // Comment them or just replace them with this: apply_type = blend_info->apply_type; if (blend_info->apply_prob_sum) { apply_value = blend_info->apply_value[RandomFromProbs(blend_info->apply_prob, blend_info->apply_prob_sum)]; } else { if (item->GetVnum() == 51002) // energy crystal apply_value = blend_info->apply_value[FN_ECS_random_index()]; else apply_value = blend_info->apply_value[FN_random_index()]; } if (blend_info->duration_prob_sum) { apply_duration = blend_info->apply_value[RandomFromProbs(blend_info->duration_prob, blend_info->duration_prob_sum)]; } else { if (item->GetVnum() == 51002) // energy crystal apply_duration = blend_info->apply_duration[FN_ECS_random_index()]; else apply_duration = blend_info->apply_duration[FN_random_index()]; } That's it, you're good to go. I should mention that I didn't try it on the live server, just in the validation app, but everything should work just fine. Example usage: # this is just to prove that you don't have to add the probability stuff in all of them # you can just add where you want to #Blue Dew section item_vnum 50825 apply_type ATT_BONUS apply_value 30 50 70 90 120 apply_duration 60 120 180 300 600 end #white dew section item_vnum 50826 apply_type DEF_BONUS apply_value 40 70 100 150 200 # you can also add values like 0 1000 20 500 0 # it will just ignore the 0 and do the math for the other ones apply_prob 0 1000 200 150 90 # if you have something like this it will ignore the 0 # and just give the one with a "valid" probability(the fifth, in this case - apply_value 200) # apply_prob 0 0 0 0 1 apply_duration 60 120 180 300 600 duration_prob 1 2 3 4 5 end #energy crystal section item_vnum 51002 apply_type ENERGY apply_value 1 3 5 7 10 apply_duration 7200 7200 7200 7200 7200 # and you don't have to add both probabilities(for duration and apply), you can just use one.. or none! apply_prob 10 50 10 20 10 end Have fun and let me know if you have any problems with it! Cheers! Edited April 14, 2022 by Amun More details about Randomi function 5 3 Link to comment Share on other sites More sharing options...
Recommended Posts