]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/mutators/base.qc
Use a different way to check distance and dragging requirements. This fixes a bug...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / base.qc
1 .float() cbc_func;
2 .entity cbc_next;
3 .float cbc_order;
4
5 entity CallbackChain_New(string name)
6 {
7         entity e;
8         e = spawn();
9         e.classname = "callbackchain";
10         e.netname = name;
11         return e;
12 }
13
14 float CallbackChain_Add(entity cb, float() func, float order)
15 {
16         entity e;
17         if(order & CBC_ORDER_FIRST)
18         {
19                 if(order & CBC_ORDER_LAST)
20                         if(cb.cbc_order & CBC_ORDER_ANY)
21                                 return 0;
22                 if(cb.cbc_order & CBC_ORDER_FIRST)
23                         return 0;
24         }
25         else if(order & CBC_ORDER_LAST)
26         {
27                 if(cb.cbc_order & CBC_ORDER_LAST)
28                         return 0;
29         }
30         entity thiscb;
31         thiscb = spawn();
32         thiscb.classname = "callback";
33         thiscb.cbc_func = func;
34         thiscb.cbc_order = order;
35         if(order & CBC_ORDER_FIRST)
36         {
37                 thiscb.cbc_next = cb.cbc_next;
38                 cb.cbc_next = thiscb;
39         }
40         else if(order & CBC_ORDER_LAST)
41         {
42                 for(e = cb; e.cbc_next; e = e.cbc_next);
43                 e.cbc_next = thiscb;
44         }
45         else
46         {
47                 // by default we execute last, but before a possible CBC_ORDER_LAST callback
48                 for(e = cb; e.cbc_next && !(e.cbc_next.cbc_order & CBC_ORDER_LAST); e = e.cbc_next); // we must make sure that we insert BEFORE an CBC_ORDER_LAST mutator!
49                 thiscb.cbc_next = e.cbc_next;
50                 e.cbc_next = thiscb;
51         }
52         cb.cbc_order |= (order | CBC_ORDER_ANY);
53         return 1;
54 }
55
56 float CallbackChain_Remove(entity cb, float() func)
57 {
58         float order;
59         entity e;
60         float n;
61         n = 0;
62         for(e = cb; e.cbc_next; e = e.cbc_next)
63         {
64                 while(e.cbc_next.cbc_func == func)
65                 {
66                         // remove e.cbc_next from the chain
67                         entity e2;
68                         e2 = e.cbc_next.cbc_next;
69                         remove(e.cbc_next);
70                         e.cbc_next = e2;
71                         ++n;
72                 }
73                 // e.cbc_next is now something we want to keep
74                 order |= (e.cbc_next.cbc_order & CBC_ORDER_ANY);
75         }
76         cb.cbc_order = order;
77         return n;
78 }
79
80 float CallbackChain_Call(entity cb)
81 {
82         float r;
83         entity e;
84         r = 0;
85         for(e = cb; e.cbc_next; e = e.cbc_next)
86         {
87                 CallbackChain_ReturnValue = r;
88                 r |= e.cbc_next.cbc_func();
89         }
90         return r; // callbacks return an error status, so 0 is default return value
91 }
92
93 #define MAX_MUTATORS 8
94 string loaded_mutators[MAX_MUTATORS];
95 float Mutator_Add(mutatorfunc_t func, string name)
96 {
97         float i, j;
98         j = -1;
99         for(i = 0; i < MAX_MUTATORS; ++i)
100         {
101                 if(name == loaded_mutators[i])
102                         return 1; // already added
103                 if(!loaded_mutators[i])
104                         j = i;
105         }
106         if(j < 0)
107         {
108                 backtrace("WARNING: too many mutators, cannot add any more\n");
109                 return 0;
110         }
111         loaded_mutators[j] = name;
112
113         if(func(MUTATOR_ADDING) == 0)
114         {
115                 // good
116                 return 1;
117         }
118         backtrace("WARNING: when adding mutator: adding failed\n");
119         Mutator_Remove(func, name);
120         return 0;
121 }
122 void Mutator_Remove(float(float) func, string name)
123 {
124         float i;
125         for(i = 0; i < MAX_MUTATORS; ++i)
126                 if(name == loaded_mutators[i])
127                         break;
128         if(i >= MAX_MUTATORS)
129         {
130                 backtrace("WARNING: removing not-added mutator\n");
131                 return;
132         }
133         loaded_mutators[i] = string_null;
134
135         if(func(MUTATOR_REMOVING) != 0)
136         {
137                 // baaaaad
138                 error("Mutator_Remove: removing mutator failed");
139         }
140 }