]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/verbstack.qc
eol-style only
[divverent/nexuiz.git] / data / qcsrc / server / verbstack.qc
1 /// Some default stacks.
2 .entity verbs_idle;
3 .entity verbs_attack;
4 .entity verbs_move;
5
6 /// This global gets set to the verb in question each time the stack manager calls verb_call
7 entity verb;
8
9 /// Execure this verb
10 #define VCM_DO     0
11 /// Return the value of this verb. Return VS_CALL_REMOVE to delete it.
12 #define VCM_EVAL   1
13 /// This verb is beeing removed NOW (not sent when verb_call returns VS_CALL_REMOVE)
14 #define VCM_REMOVE 2
15
16 /// Verb callback
17 .float(float message) verb_call;
18
19 /// Points to this verb's stack.
20 .entity  verbstack;
21
22 /// Static value of this verb
23 .float verb_static_value;
24
25 /// verb_call returns this when a verb in not doable
26 #define VS_CALL_NO        0
27 /// verb_call(VCM_DO) returns this when a verb is executing
28 #define VS_CALL_YES_DOING -1
29 /// verb_call(VCM_DO) returns this when a verb did execure and is done
30 #define VS_CALL_YES_DONE  -2
31 /// verb_call(VCM_DO) returns this when a verb should be deleted by the stack manager
32 #define VS_CALL_REMOVE    -3
33
34 /**
35     Push a new verb onto the specified stack. Set vrb_life to make it time-limited.
36 **/
37 entity verbstack_push(entity stack, float(float eval) vrb_call, float val_static, float vrb_life,entity verb_owner)
38 {
39     entity vrb;
40
41     if not(stack)
42         return world;
43
44     if not(vrb_call)
45         return world;
46
47     vrb                   = spawn();
48     vrb.owner             = verb_owner;
49     vrb.verbstack         = stack;
50     vrb.verb_call         = vrb_call;
51     vrb.verb_static_value = val_static;
52
53     if(vrb_life)
54     {
55         vrb.think     = SUB_Remove;
56         vrb.nextthink = time + vrb_life;
57     }
58
59     return vrb;
60 }
61
62 /**
63     Find the best verb in this stack and execurte it.
64     ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL or VCM_DO
65 **/
66 float verbstack_pop(entity stack)
67 {
68     entity vrb, bestverb, oldself;
69     float  value, bestvalue;
70
71     oldself = self;
72
73     vrb = findchainentity(verbstack,stack);
74     while(vrb)
75     {
76         verb  = vrb;
77         vrb   = vrb.chain;
78         self  = verb.owner;
79         value = verb.verb_call(VCM_EVAL);
80
81         if(value < 0)
82         {
83             if(value == VS_CALL_REMOVE)
84                 remove(verb);
85         }
86         else
87         {
88             if(value > bestvalue)
89             {
90                 bestverb  = verb;
91                 bestvalue = value;
92             }
93         }
94     }
95
96     if(bestverb)
97     {
98         verb  = bestverb;
99         self  = verb.owner;
100         value = verb.verb_call(VCM_DO);
101
102         if(value == VS_CALL_REMOVE)
103             remove(bestverb);
104     }
105
106     self = oldself;
107
108     return value;
109 }
110
111 float verbstack_popfifo(entity stack)
112 {
113     entity oldself;
114     float ret;
115
116     oldself = self;
117     verb = findentity(stack,verbstack,stack);
118     if not (verb)
119         ret = 0;
120     else
121     {
122         self = verb.owner;
123         ret = verb.verb_call(VCM_DO);
124
125         if(ret == VS_CALL_REMOVE)
126             remove(verb);
127     }
128
129     self = oldself;
130     return ret;
131 }
132
133 /**
134     Find the best verb in this stack and return it.
135     ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL.
136 **/
137 entity verbstack_pull(entity stack)
138 {
139     entity vrb;
140     entity bestverb, oldself;
141     float  value, bestvalue;
142
143     oldself = self;
144
145     vrb = findchainentity(verbstack,stack);
146     while(vrb)
147     {
148         self = vrb.owner;
149
150         verb  = vrb;
151         vrb   = vrb.chain;
152         value = verb.verb_call(VCM_EVAL);
153
154         if(value > 0)
155         {
156             if(value == VS_CALL_REMOVE)
157                 remove(verb);
158         }
159         else
160         {
161             if(value > bestvalue)
162             {
163                 bestverb = verb;
164                 bestvalue = value;
165             }
166         }
167     }
168
169     self = oldself;
170
171     return bestverb;
172 }
173
174 entity verbstack_pullfifo(entity stack)
175 {
176     return findentity(stack,verbstack,stack);
177 }
178
179 /**
180     Delete every verb on this stack, signaling them with VCM_REMOVE first.
181 **/
182 void verbstack_flush(entity stack)
183 {
184     entity vrb, oldself;
185
186     oldself = self;
187
188     vrb = findchainentity(verbstack,stack);
189     while(vrb)
190     {
191         self = vrb.owner;
192
193         verb = vrb;
194         vrb  = vrb.chain;
195         verb.verb_call(VCM_REMOVE);
196         remove(verb);
197     }
198
199     self = oldself;
200 }