OpenMoHAA 0.82.0
Loading...
Searching...
No Matches
characterstate.h
1/*
2===========================================================================
3Copyright (C) 2024 the OpenMoHAA team
4
5This file is part of OpenMoHAA source code.
6
7OpenMoHAA source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12OpenMoHAA source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OpenMoHAA source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20===========================================================================
21*/
22
23// characterstate.h: Character state
24
25#pragma once
26
27#include "g_local.h"
28#include "entity.h"
29#include "script.h"
30
31enum testcondition_t {
32 TC_ISTRUE, // no prefix
33 TC_ISFALSE, // !
34 TC_EDGETRUE, // +
35 TC_EDGEFALSE // -
36};
37
38enum movecontrol_t {
39 MOVECONTROL_NONE,
40 MOVECONTROL_USER, // Quake style
41 MOVECONTROL_LEGS, // Quake style, legs state system active
42 MOVECONTROL_USER_MOVEANIM,
43 MOVECONTROL_ANIM, // move based on animation, with full collision testing
44 MOVECONTROL_ABSOLUTE, // move based on animation, with full collision testing but no turning
45 MOVECONTROL_HANGING, // move based on animation, with full collision testing, hanging
46 MOVECONTROL_ROPE_GRAB,
47 MOVECONTROL_ROPE_RELEASE,
48 MOVECONTROL_ROPE_MOVE,
49 MOVECONTROL_PICKUPENEMY,
50 MOVECONTROL_PUSH,
51 MOVECONTROL_CLIMBWALL,
52 MOVECONTROL_USEANIM,
53 MOVECONTROL_CROUCH,
54 MOVECONTROL_LOOPUSEANIM,
55 MOVECONTROL_USEOBJECT,
56 MOVECONTROL_COOLOBJECT,
57};
58
59enum cameratype_t {
60 CAMERA_TOPDOWN,
61 CAMERA_BEHIND,
62 CAMERA_FRONT,
63 CAMERA_SIDE,
64 CAMERA_BEHIND_FIXED,
65 CAMERA_SIDE_LEFT,
66 CAMERA_SIDE_RIGHT,
67 CAMERA_BEHIND_NOPITCH
68};
69
70#define DEFAULT_MOVETYPE MOVECONTROL_NONE
71#define DEFAULT_CAMERA CAMERA_BEHIND
72
73class Conditional;
74
75template<class Type>
76struct Condition {
77 const char *name;
78 qboolean (Type::*func)(Conditional& condition);
79};
80
81class Conditional : public Class
82{
83private:
84 qboolean result;
85 qboolean previous_result;
86 bool checked;
87
88public:
89 CLASS_PROTOTYPE(Conditional);
90
91 Condition<Class> condition;
92 Container<str> parmList;
93
94 bool getResult(testcondition_t test, Entity &ent);
95 const char *getName(void);
96
97 Conditional(Condition<Class>& condition);
98 Conditional();
99
100 const char *getParm(int number);
101 void addParm(str parm);
102 int numParms(void);
103 void clearCheck(void);
104 void clearPrevious(void);
105};
106
107inline void Conditional::addParm(str parm)
108
109{
110 parmList.AddObject(parm);
111}
112
113inline const char *Conditional::getParm(int number)
114
115{
116 if ((number < 1) || (number > parmList.NumObjects())) {
117 gi.Error(ERR_DROP, "Parm #%d out of range on %s condition\n", number, condition.name);
118 }
119 return parmList.ObjectAt(number).c_str();
120}
121
122inline int Conditional::numParms(void)
123
124{
125 return parmList.NumObjects();
126}
127
128inline void Conditional::clearCheck(void)
129
130{
131 checked = false;
132}
133
134inline void Conditional::clearPrevious(void)
135
136{
137 previous_result = 0;
138}
139
140inline const char *Conditional::getName(void)
141
142{
143 return condition.name;
144}
145
146inline bool Conditional::getResult(testcondition_t test, Entity& ent)
147{
148 if (condition.func && !checked) {
149 checked = true;
150 previous_result = result;
151
152 result = (ent.*condition.func)(*this);
153 }
154
155 switch (test) {
156 case TC_ISFALSE:
157 return !result;
158
159 case TC_EDGETRUE:
160 return result && !previous_result;
161
162 case TC_EDGEFALSE:
163 return !result && previous_result;
164
165 case TC_ISTRUE:
166 default:
167 return result != false;
168 }
169}
170
171class State;
172class StateMap;
173
174class Expression : public Class
175{
176private:
177 struct condition_t {
178 testcondition_t test;
179 int condition_index;
180 };
181
182 str value;
183 Container<condition_t> conditions;
184
185public:
186 Expression();
187 Expression(const Expression& exp);
188 Expression(Script& script, State& state);
189
190 void operator=(const Expression& exp);
191
192 bool getResult(State &state, Entity &ent, Container<Conditional *> *sent_conditionals);
193 const char *getValue(void);
194};
195
196inline void Expression::operator=(const Expression& exp)
197
198{
199 int i;
200
201 value = exp.value;
202
203 conditions.FreeObjectList();
204 for (i = 1; i <= exp.conditions.NumObjects(); i++) {
205 conditions.AddObject(exp.conditions.ObjectAt(i));
206 }
207}
208
209inline const char *Expression::getValue(void)
210
211{
212 return value.c_str();
213}
214
215class State : public Class
216{
217private:
218 Container<int> condition_indexes;
219
220 StateMap& statemap;
221
222 str name;
223
224 str nextState;
225 movecontrol_t movetype;
226 cameratype_t cameratype;
227
228 str behaviorName;
229 Container<str> behaviorParmList;
230
231 float minTime;
232 float maxTime;
233
234 Container<Expression> legAnims;
235 Container<Expression> m_actionAnims;
236 int m_iActionAnimType;
237
239 Container<str> entryCommands;
240 Container<str> exitCommands;
241
242 void readNextState(Script& script);
243 void readMoveType(Script& script);
244 void readCamera(Script& script);
245 void readLegs(Script& script);
246 void readAction(Script& script);
247 void readBehavior(Script& script);
248 void readTime(Script& script);
249 void readStates(Script& script);
250 void readCommands(Script& script, Container<str>& container);
251
252 void ParseAndProcessCommand(str command, Entity *target);
253
254public:
255 State(const char *name, Script& script, StateMap& map);
256
257 State *Evaluate(Entity& ent, Container<Conditional *> *ent_conditionals);
258 int addCondition(const char *name, Script &script);
259 void CheckStates(void);
260
261 const char *getName(void);
262
263 const char *getLegAnim(Entity &ent, Container<Conditional *> *sent_conditionals);
264 const char *getActionAnim(Entity &ent, Container<Conditional *> *sent_conditionals, int *piAnimType = NULL);
265 const char *getBehaviorName(void);
266 State *getNextState(void);
267 movecontrol_t getMoveType(void);
268 cameratype_t getCameraType(void);
269 qboolean setCameraType(str ctype);
270
271 const char *getBehaviorParm(int number = 1);
272 void addBehaviorParm(str parm);
273 int numBehaviorParms(void);
274
275 float getMinTime(void);
276 float getMaxTime(void);
277 void ProcessEntryCommands(Entity *target);
278 void ProcessExitCommands(Entity *target);
279 void GetLegAnims(Container<const char *> *c);
280 void GetActionAnims(Container<const char *> *c);
281};
282
283inline void State::addBehaviorParm(str parm)
284
285{
286 behaviorParmList.AddObject(parm);
287}
288
289inline const char *State::getBehaviorParm(int number)
290
291{
292 return behaviorParmList.ObjectAt(number).c_str();
293}
294
295inline int State::numBehaviorParms(void)
296
297{
298 return behaviorParmList.NumObjects();
299}
300
301class StateMap : public Class
302{
303private:
304 Container<State *> stateList;
305 Condition<Class> *current_conditions;
306 Container<Conditional *> *current_conditionals;
307 str filename;
308
309public:
310 StateMap(const char *filename, Condition<Class> *conditions, Container<Conditional *> *conditionals);
311 ~StateMap();
312
313 Condition<Class> *getCondition(const char *name);
314 int findConditional(Conditional *condition);
315 int addConditional(Conditional *condition);
316 Conditional *getConditional(const char *name);
317 void GetAllAnims(Container<const char *> *c);
318 State *FindState(const char *name);
319 const char *Filename();
320};
321
322inline const char *StateMap::Filename(void)
323
324{
325 return filename.c_str();
326}
327
328inline const char *State::getName(void)
329
330{
331 return name.c_str();
332}
333
334inline State *State::getNextState(void)
335
336{
337 return statemap.FindState(nextState.c_str());
338}
339
340inline movecontrol_t State::getMoveType(void)
341
342{
343 return movetype;
344}
345
346inline cameratype_t State::getCameraType(void)
347
348{
349 return cameratype;
350}
351
352void ClearCachedStatemaps(void);
353StateMap *GetStatemap(
354 str filename,
355 Condition<Class> *conditions,
356 Container<Conditional *> *conditionals,
357 qboolean reload,
358 qboolean cache_only = false
359);
360void CacheStatemap(str filename, Condition<Class> *conditions);
Definition characterstate.h:82
Definition container.h:85
Definition entity.h:203
Definition characterstate.h:175
Definition script.h:60
Definition characterstate.h:302
Definition characterstate.h:216
Definition str.h:77
Definition characterstate.h:76
Definition puff.c:88