X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Flib%2Frandom.qc;h=a5ff69356a21f516ba290bac01761eac2a7cce88;hb=d13b85731d2a23db27bb221646b3701a06e8f350;hp=149323b8fa8b00194e599f3700a869fa2b1ddb61;hpb=a39af09cb4b15ec94461af2c1f314098ffe7ce0c;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/lib/random.qc b/qcsrc/lib/random.qc index 149323b8f..a5ff69356 100644 --- a/qcsrc/lib/random.qc +++ b/qcsrc/lib/random.qc @@ -1,81 +1,142 @@ #include "random.qh" +ERASEABLE void RandomSelection_Init() { - RandomSelection_totalweight = 0; - RandomSelection_chosen_ent = NULL; - RandomSelection_chosen_float = 0; - RandomSelection_chosen_string = string_null; - RandomSelection_best_priority = -1; + RandomSelection_totalweight = 0; + RandomSelection_chosen_ent = NULL; + RandomSelection_chosen_float = 0; + RandomSelection_chosen_string = string_null; + RandomSelection_best_priority = -1; } -void RandomSelection_Add(entity e, float f, string s, float weight, float priority) +ERASEABLE +void RandomSelection_Add(entity e, float f, string s, vector v, float weight, float priority) { - if (priority > RandomSelection_best_priority) - { - RandomSelection_best_priority = priority; - RandomSelection_chosen_ent = e; - RandomSelection_chosen_float = f; - RandomSelection_chosen_string = s; - RandomSelection_totalweight = weight; - } - else if (priority == RandomSelection_best_priority) - { - RandomSelection_totalweight += weight; - if (random() * RandomSelection_totalweight <= weight) - { - RandomSelection_chosen_ent = e; - RandomSelection_chosen_float = f; - RandomSelection_chosen_string = s; - } - } + if (priority > RandomSelection_best_priority) + { + RandomSelection_best_priority = priority; + RandomSelection_chosen_ent = e; + RandomSelection_chosen_float = f; + RandomSelection_chosen_string = s; + RandomSelection_chosen_vec = v; + RandomSelection_totalweight = weight; + } + else if (priority == RandomSelection_best_priority) + { + RandomSelection_totalweight += weight; + if (random() * RandomSelection_totalweight <= weight) + { + RandomSelection_chosen_ent = e; + RandomSelection_chosen_float = f; + RandomSelection_chosen_string = s; + RandomSelection_chosen_vec = v; + } + } } +float DistributeEvenly_amount; +float DistributeEvenly_totalweight; -// prandom - PREDICTABLE random number generator (not seeded yet) - -#ifdef USE_PRANDOM -float prandom_seed; -float prandom() +ERASEABLE +void DistributeEvenly_Init(float amount, float totalweight) { - float c; - c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI))); - prandom_seed = c; - -#ifdef USE_PRANDOM_DEBUG - LOG_TRACE("RANDOM -> ", ftos(c), "\n"); -#endif - - return c / 65536; // in [0..1[ + if (DistributeEvenly_amount) + { + LOG_TRACE("DistributeEvenly_Init: UNFINISHED DISTRIBUTION (", ftos(DistributeEvenly_amount), " for ", ftos(DistributeEvenly_totalweight), " left!)"); + } + if (totalweight == 0) DistributeEvenly_amount = 0; + else DistributeEvenly_amount = amount; + DistributeEvenly_totalweight = totalweight; } -vector prandomvec() +ERASEABLE +float DistributeEvenly_Get(float weight) { - vector v; - - do - { - v.x = prandom(); - v.y = prandom(); - v.z = prandom(); - } - while(v * v > 1); - - return v; + float f; + if (weight <= 0) return 0; + f = floor(0.5 + DistributeEvenly_amount * weight / DistributeEvenly_totalweight); + DistributeEvenly_totalweight -= weight; + DistributeEvenly_amount -= f; + return f; } -void psrandom(float seed) +ERASEABLE +float DistributeEvenly_GetRandomized(float weight) { - prandom_seed = seed; -#ifdef USE_PRANDOM_DEBUG - LOG_TRACE("SRANDOM ", ftos(seed), "\n"); -#endif + float f; + if (weight <= 0) return 0; + f = floor(random() + DistributeEvenly_amount * weight / DistributeEvenly_totalweight); + DistributeEvenly_totalweight -= weight; + DistributeEvenly_amount -= f; + return f; } -#ifdef USE_PRANDOM_DEBUG -void prandom_debug() +// from the GNU Scientific Library +float gsl_ran_gaussian_lastvalue; +float gsl_ran_gaussian_lastvalue_set; +ERASEABLE +float gsl_ran_gaussian(float sigma) { - LOG_TRACE("Current random seed = ", ftos(prandom_seed), "\n"); + if (gsl_ran_gaussian_lastvalue_set) + { + gsl_ran_gaussian_lastvalue_set = 0; + return sigma * gsl_ran_gaussian_lastvalue; + } + else + { + float a = random() * 2 * M_PI; + float b = sqrt(-2 * log(random())); + gsl_ran_gaussian_lastvalue = cos(a) * b; + gsl_ran_gaussian_lastvalue_set = 1; + return sigma * sin(a) * b; + } } -#endif + +// prandom - PREDICTABLE random number generator (not seeded yet) + +#ifdef USE_PRANDOM + float prandom_seed; + float prandom() + { + float c; + c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI))); + prandom_seed = c; + + #ifdef USE_PRANDOM_DEBUG + LOG_TRACE("RANDOM -> ", ftos(c)); + #endif + + return c / 65536; // in [0..1[ + } + + vector prandomvec() + { + vector v; + + do + { + v.x = prandom(); + v.y = prandom(); + v.z = prandom(); + } + while (v * v > 1); + + return v; + } + + void psrandom(float seed) + { + prandom_seed = seed; + #ifdef USE_PRANDOM_DEBUG + LOG_TRACE("SRANDOM ", ftos(seed)); + #endif + } + + #ifdef USE_PRANDOM_DEBUG + void prandom_debug() + { + LOG_TRACE("Current random seed = ", ftos(prandom_seed)); + } + #endif #endif