]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/random.qc
Add an intrusive list for warpzones
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / random.qc
1 #include "random.qh"
2
3 void RandomSelection_Init()
4 {
5         RandomSelection_totalweight = 0;
6         RandomSelection_chosen_ent = NULL;
7         RandomSelection_chosen_float = 0;
8         RandomSelection_chosen_string = string_null;
9         RandomSelection_best_priority = -1;
10 }
11
12 void RandomSelection_Add(entity e, float f, string s, float weight, float priority)
13 {
14         if (priority > RandomSelection_best_priority)
15         {
16                 RandomSelection_best_priority = priority;
17                 RandomSelection_chosen_ent = e;
18                 RandomSelection_chosen_float = f;
19                 RandomSelection_chosen_string = s;
20                 RandomSelection_totalweight = weight;
21         }
22         else if (priority == RandomSelection_best_priority)
23         {
24                 RandomSelection_totalweight += weight;
25                 if (random() * RandomSelection_totalweight <= weight)
26                 {
27                         RandomSelection_chosen_ent = e;
28                         RandomSelection_chosen_float = f;
29                         RandomSelection_chosen_string = s;
30                 }
31         }
32 }
33
34 float DistributeEvenly_amount;
35 float DistributeEvenly_totalweight;
36
37 void DistributeEvenly_Init(float amount, float totalweight)
38 {
39         if (DistributeEvenly_amount)
40         {
41                 LOG_TRACE("DistributeEvenly_Init: UNFINISHED DISTRIBUTION (", ftos(DistributeEvenly_amount), " for ", ftos(DistributeEvenly_totalweight), " left!)");
42         }
43         if (totalweight == 0) DistributeEvenly_amount = 0;
44         else DistributeEvenly_amount = amount;
45         DistributeEvenly_totalweight = totalweight;
46 }
47
48 float DistributeEvenly_Get(float weight)
49 {
50         float f;
51         if (weight <= 0) return 0;
52         f = floor(0.5 + DistributeEvenly_amount * weight / DistributeEvenly_totalweight);
53         DistributeEvenly_totalweight -= weight;
54         DistributeEvenly_amount -= f;
55         return f;
56 }
57
58 float DistributeEvenly_GetRandomized(float weight)
59 {
60         float f;
61         if (weight <= 0) return 0;
62         f = floor(random() + DistributeEvenly_amount * weight / DistributeEvenly_totalweight);
63         DistributeEvenly_totalweight -= weight;
64         DistributeEvenly_amount -= f;
65         return f;
66 }
67
68 // from the GNU Scientific Library
69 float gsl_ran_gaussian_lastvalue;
70 float gsl_ran_gaussian_lastvalue_set;
71 float gsl_ran_gaussian(float sigma)
72 {
73         if (gsl_ran_gaussian_lastvalue_set)
74         {
75                 gsl_ran_gaussian_lastvalue_set = 0;
76                 return sigma * gsl_ran_gaussian_lastvalue;
77         }
78         else
79         {
80                 float a = random() * 2 * M_PI;
81                 float b = sqrt(-2 * log(random()));
82                 gsl_ran_gaussian_lastvalue = cos(a) * b;
83                 gsl_ran_gaussian_lastvalue_set = 1;
84                 return sigma * sin(a) * b;
85         }
86 }
87
88 // prandom - PREDICTABLE random number generator (not seeded yet)
89
90 #ifdef USE_PRANDOM
91         float prandom_seed;
92         float prandom()
93         {
94                 float c;
95                 c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI)));
96                 prandom_seed = c;
97
98         #ifdef USE_PRANDOM_DEBUG
99                         LOG_TRACE("RANDOM -> ", ftos(c));
100         #endif
101
102                 return c / 65536;  // in [0..1[
103         }
104
105         vector prandomvec()
106         {
107                 vector v;
108
109                 do
110                 {
111                         v.x = prandom();
112                         v.y = prandom();
113                         v.z = prandom();
114                 }
115                 while (v * v > 1);
116
117                 return v;
118         }
119
120         void psrandom(float seed)
121         {
122                 prandom_seed = seed;
123         #ifdef USE_PRANDOM_DEBUG
124                         LOG_TRACE("SRANDOM ", ftos(seed));
125         #endif
126         }
127
128         #ifdef USE_PRANDOM_DEBUG
129                 void prandom_debug()
130                 {
131                         LOG_TRACE("Current random seed = ", ftos(prandom_seed));
132                 }
133         #endif
134 #endif