]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/random.qc
Merge branch 'master' into TimePath/csqc_viewmodels
[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 ");
42                 LOG_TRACE(ftos(DistributeEvenly_totalweight), " left!)\n");
43         }
44         if (totalweight == 0) DistributeEvenly_amount = 0;
45         else DistributeEvenly_amount = amount;
46         DistributeEvenly_totalweight = totalweight;
47 }
48
49 float DistributeEvenly_Get(float weight)
50 {
51         float f;
52         if (weight <= 0) return 0;
53         f = floor(0.5 + DistributeEvenly_amount * weight / DistributeEvenly_totalweight);
54         DistributeEvenly_totalweight -= weight;
55         DistributeEvenly_amount -= f;
56         return f;
57 }
58
59 float DistributeEvenly_GetRandomized(float weight)
60 {
61         float f;
62         if (weight <= 0) return 0;
63         f = floor(random() + DistributeEvenly_amount * weight / DistributeEvenly_totalweight);
64         DistributeEvenly_totalweight -= weight;
65         DistributeEvenly_amount -= f;
66         return f;
67 }
68
69 // from the GNU Scientific Library
70 float gsl_ran_gaussian_lastvalue;
71 float gsl_ran_gaussian_lastvalue_set;
72 float gsl_ran_gaussian(float sigma)
73 {
74         if (gsl_ran_gaussian_lastvalue_set)
75         {
76                 gsl_ran_gaussian_lastvalue_set = 0;
77                 return sigma * gsl_ran_gaussian_lastvalue;
78         }
79         else
80         {
81                 float a = random() * 2 * M_PI;
82                 float b = sqrt(-2 * log(random()));
83                 gsl_ran_gaussian_lastvalue = cos(a) * b;
84                 gsl_ran_gaussian_lastvalue_set = 1;
85                 return sigma * sin(a) * b;
86         }
87 }
88
89 // prandom - PREDICTABLE random number generator (not seeded yet)
90
91 #ifdef USE_PRANDOM
92         float prandom_seed;
93         float prandom()
94         {
95                 float c;
96                 c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI)));
97                 prandom_seed = c;
98
99         #ifdef USE_PRANDOM_DEBUG
100                         LOG_TRACE("RANDOM -> ", ftos(c), "\n");
101         #endif
102
103                 return c / 65536;  // in [0..1[
104         }
105
106         vector prandomvec()
107         {
108                 vector v;
109
110                 do
111                 {
112                         v.x = prandom();
113                         v.y = prandom();
114                         v.z = prandom();
115                 }
116                 while (v * v > 1);
117
118                 return v;
119         }
120
121         void psrandom(float seed)
122         {
123                 prandom_seed = seed;
124         #ifdef USE_PRANDOM_DEBUG
125                         LOG_TRACE("SRANDOM ", ftos(seed), "\n");
126         #endif
127         }
128
129         #ifdef USE_PRANDOM_DEBUG
130                 void prandom_debug()
131                 {
132                         LOG_TRACE("Current random seed = ", ftos(prandom_seed), "\n");
133                 }
134         #endif
135 #endif