File: simpleactor.h

package info (click to toggle)
openmohaa 0.81.1%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: trixie
  • size: 29,124 kB
  • sloc: ansic: 270,865; cpp: 250,173; sh: 234; asm: 141; xml: 64; makefile: 7
file content (480 lines) | stat: -rw-r--r-- 16,865 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team

This file is part of OpenMoHAA source code.

OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.

OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
*/

// simpleactor.h: Base class for character AI.

#pragma once

#include "weapon.h"
#include "sentient.h"
#include "container.h"
#include "stack.h"
#include "navigate.h"
#include "scriptmaster.h"
#include "characterstate.h"
#include "actorpath.h"

enum eEmotionMode {
    EMOTION_NONE,
    EMOTION_NEUTRAL,
    EMOTION_WORRY,
    EMOTION_PANIC,
    EMOTION_FEAR,
    EMOTION_DISGUST,
    EMOTION_ANGER,
    EMOTION_AIMING,
    EMOTION_DETERMINED,
    EMOTION_DEAD,
    EMOTION_CURIOUS
};

enum eAnimMode {
    ANIM_MODE_NONE,
    ANIM_MODE_NORMAL,
    ANIM_MODE_PATH,
    ANIM_MODE_PATH_GOAL,
    ANIM_MODE_DEST,
    ANIM_MODE_SCRIPTED,
    ANIM_MODE_NOCLIP,
    ANIM_MODE_FALLING_PATH,
    ANIM_MODE_FROZEN,
    ANIM_MODE_ATTACHED,
};

enum eAnimWeightType {
    ANIM_WEIGHT_NONE,
    ANIM_WEIGHT_MOTION,
    ANIM_WEIGHT_ACTION,
    ANIM_WEIGHT_CROSSBLEND_1,
    ANIM_WEIGHT_CROSSBLEND_2,
    ANIM_WEIGHT_CROSSBLEND_DIALOG,
    ANIM_WEIGHT_SAY,
    ANIM_WEIGHT_AIM,
    ANIM_WEIGHT_LASTFRAME,
};

class SimpleActor;

typedef SafePtr<SimpleActor> SimpleActorPtr;

class SimpleActor : public Sentient
{
public:
    int                   m_eAnimMode;
    ScriptThreadLabel     m_Anim;
    SafePtr<ScriptThread> m_pAnimThread;
    int                   m_eNextAnimMode;
    const_str             m_csNextAnimString;
    ScriptThreadLabel     m_NextAnimLabel;
    bool                  m_bNextForceStart;
    float                 m_fCrouchWeight;
    bool                  m_YawAchieved;
    float                 m_DesiredYaw;
    bool                  m_bHasDesiredLookDest;
    bool                  m_bHasDesiredLookAngles;
    Vector                m_vDesiredLookDest;
    Vector                m_DesiredLookAngles;
    Vector                m_DesiredGunDir;
    ActorPath             m_Path;
    float                 m_Dest[3];
    float                 m_NoClipDest[3];
    float                 path_failed_time;
    float                 m_fPathGoalTime;
    bool                  m_bStartPathGoalEndAnim;
    const_str             m_csPathGoalEndAnimScript;
    qboolean              m_walking;
    qboolean              m_groundPlane;
    vec3_t                m_groundPlaneNormal;
    Vector                watch_offset;
    bool                  m_bThink;
    int                   m_PainTime;
    eEmotionMode          m_eEmotionMode;
    float                 m_fAimLimit_up;
    float                 m_fAimLimit_down;
    int                   m_ChangeMotionAnimIndex;
    int                   m_ChangeActionAnimIndex;
    int                   m_ChangeSayAnimIndex;

protected:
    unsigned int m_weightType[MAX_FRAMEINFOS];
    float        m_weightBase[MAX_FRAMEINFOS];
    float        m_weightCrossBlend[MAX_FRAMEINFOS];
    bool         m_AnimMotionHigh;
    bool         m_AnimActionHigh;
    bool         m_AnimDialogHigh;

public:
    int               hit_obstacle_time;
    float             obstacle_vel[2];
    const_str         m_csAnimName;
    const_str         m_csSayAnim;
    const_str         m_csUpperAnim;
    const_str         m_csCurrentPosition;
    int               m_bPathErrorTime;
    class PathNode   *m_NearestNode;
    Vector            m_vNearestNodePos;
    short             m_bUpdateAnimDoneFlags;
    float             m_maxspeed;
    const_str         m_csMood;
    const_str         m_csIdleMood;
    int               m_iMotionSlot;
    int               m_iActionSlot;
    int               m_iSaySlot;
    bool              m_bLevelMotionAnim;
    bool              m_bLevelActionAnim;
    byte              m_bLevelSayAnim;
    byte              m_bNextLevelSayAnim;
    bool              m_bMotionAnimSet;
    bool              m_bActionAnimSet;
    bool              m_bSayAnimSet;
    bool              m_bAimAnimSet;
    int               m_iVoiceTime;
    bool              m_bDoAI;
    ScriptThreadLabel m_PainHandler;
    ScriptThreadLabel m_DeathHandler;
    ScriptThreadLabel m_AttackHandler;
    ScriptThreadLabel m_SniperHandler;
    float             m_fCrossblendTime;

public:
    CLASS_PROTOTYPE(SimpleActor);

    SimpleActor();
    ~SimpleActor();

    void         Archive(Archiver        &arc) override;
    virtual void SetMoveInfo(mmove_t *mm);
    virtual void GetMoveInfo(mmove_t *mm);
    bool         CanSeeFrom(vec3_t pos, Entity *ent);
    virtual bool CanTarget(void);
    virtual bool IsImmortal(void);
    bool         DoesTheoreticPathExist(Vector vDestPos, float fMaxPath);
    void
    SetPath(Vector vDestPos, const char *description, int iMaxDirtyTime, float *vLeashHome, float fLeashDistSquared);
    void                SetPath(SimpleEntity *pDestNode, const char *description, int iMaxDirtyTime);
    void                SetPathWithinDistance(Vector vDestPos, char *description, float fMaxPath, int iMaxDirtyTime);
    void                FindPathAway(vec3_t vAwayFrom, vec2_t vDirPreferred, float fMinSafeDist);
    void                ClearPath(void);
    bool                PathComplete(void) const;
    bool                PathExists(void) const;
    bool                PathIsValid(void) const;
    bool                PathAvoidsSquadMates(void) const;
    void                ShortenPathToAvoidSquadMates(void);
    PathInfo           *CurrentPathNode(void) const;
    PathInfo           *LastPathNode(void) const;
    float               PathDist(void) const;
    bool                PathHasCompleteLookahead(void) const;
    Vector              PathGoal(void) const;
    const float        *PathDelta(void) const;
    bool                PathGoalSlowdownStarted(void) const;
    void                SetDest(vec3_t dest);
    void                StopTurning(void);
    void                SetDesiredYaw(float yaw);
    void                SetDesiredYawDir(const vec2_t vec);
    void                SetDesiredYawDest(const vec3_t vec);
    void                UpdateEmotion(void);
    int                 GetEmotionAnim(void);
    int                 GetMotionSlot(int slot);
    int                 GetActionSlot(int slot);
    int                 GetSaySlot(void);
    void                StartCrossBlendAnimSlot(int slot);
    void                StartMotionAnimSlot(int slot, int anim, float weight);
    void                StartAimMotionAnimSlot(int slot, int anim);
    void                StartActionAnimSlot(int anim);
    void                StartSayAnimSlot(int anim);
    void                StartAimAnimSlot(int slot, int anim);
    void                SetBlendedWeight(int slot);
    void                EventSetAnimLength(Event *ev);
    void                UpdateNormalAnimSlot(int slot);
    void                UpdateCrossBlendAnimSlot(int slot);
    void                UpdateCrossBlendDialogAnimSlot(int slot);
    void                UpdateSayAnimSlot(int slot);
    void                UpdateLastFrameSlot(int slot);
    void                UpdateAnimSlot(int slot);
    void                StopAllAnimating(void);
    void                ChangeMotionAnim(void);
    void                ChangeActionAnim(void);
    void                ChangeSayAnim(void);
    void                StopAnimating(int slot);
    void                AnimFinished(int slot) override;
    void                UpdateAim(void);
    void                UpdateAimMotion(void);
    void                EventAIOn(Event *ev);
    void                EventAIOff(Event *ev);
    void                EventGetWeaponGroup(Event *ev);
    void                EventGetWeaponType(Event *ev);
    void                EventGetPainHandler(Event *ev);
    void                EventSetPainHandler(Event *ev);
    void                EventGetDeathHandler(Event *ev);
    void                EventSetDeathHandler(Event *ev);
    void                EventGetAttackHandler(Event *ev);
    void                EventSetAttackHandler(Event *ev);
    void                EventGetSniperHandler(Event *ev);
    void                EventSetSniperHandler(Event *ev);
    void                EventSetCrossblendTime(Event *ev);
    void                EventGetCrossblendTime(Event *ev);
    void                EventSetEmotion(Event *ev);
    void                EventGetPosition(Event *ev);
    void                EventSetPosition(Event *ev);
    void                EventGetAnimMode(Event *ev);
    void                EventSetAnimMode(Event *ev);
    void                EventSetAnimFinal(Event *ev);
    void                EventNoAnimLerp(Event *ev); // Added in 2.0
    const_str           GetRunAnim(void);
    const_str           GetWalkAnim(void);
    void                DesiredAnimation(int eAnimMode, const_str csAnimString);
    void                StartAnimation(int eAnimMode, const_str csAnimString);
    void                DesiredAnimation(int eAnimMode, ScriptThreadLabel AnimLabel);
    void                StartAnimation(int eAnimMode, ScriptThreadLabel AnimLabel);
    void                ContinueAnimationAllowNoPath(void);
    void                ContinueAnimation(void);
    void                SetPathGoalEndAnim(const_str csEndAnim);
    bool                UpdateSelectedAnimation(void);
    void                Anim_Attack(void);
    void                Anim_Suppress(void); // Added in 2.0
    void                Anim_Sniper(void);
    void                Anim_Aim(void);
    void                Anim_Shoot(void);
    void                Anim_Idle(void);
    void                Anim_Crouch(void);
    void                Anim_Prone(void);
    void                Anim_Stand(void);
    void                Anim_Cower(void);
    void                Anim_Killed(void);
    void                Anim_StartPain(void);
    void                Anim_Pain(void);
    void                Anim_CrouchRunTo(int eAnimMode);
    void                Anim_CrouchWalkTo(int eAnimMode);
    void                Anim_StandRunTo(int eAnimMode);
    void                Anim_StandWalkTo(int eAnimMode);
    void                Anim_RunTo(int eAnimMode);
    void                Anim_WalkTo(int eAnimMode);
    void                Anim_RunAwayFiring(int eAnimMode);
    void                Anim_RunToShooting(int eAnimMode);
    void                Anim_RunToAlarm(int eAnimMode);
    void                Anim_RunToCasual(int eAnimMode);
    void                Anim_RunToCover(int eAnimMode);
    void                Anim_RunToDanger(int eAnimMode);
    void                Anim_RunToDive(int eAnimMode);
    void                Anim_RunToFlee(int eAnimMode);
    void                Anim_RunToInOpen(int eAnimMode);
    void                Anim_Emotion(eEmotionMode eEmotMode);
    void                Anim_Say(const_str csSayAnimScript, int iMinTimeSinceLastSay, bool bCanInterrupt);
    void                Anim_FullBody(const_str csFullBodyAnim, int eAnimMode);
    virtual const char *DumpCallTrace(const char *pszFmt, ...) const;
};

inline void SimpleActor::StartAnimation(int eAnimMode, const_str csAnimString)
{
    m_eNextAnimMode    = eAnimMode;
    m_csNextAnimString = csAnimString;
    m_bNextForceStart  = true;
}

inline void SimpleActor::DesiredAnimation(int eAnimMode, const_str csAnimString)
{
    m_eNextAnimMode    = eAnimMode;
    m_csNextAnimString = csAnimString;
    m_bNextForceStart  = false;
}

inline void SimpleActor::StartAnimation(int eAnimMode, ScriptThreadLabel AnimLabel)
{
    m_eNextAnimMode    = eAnimMode;
    m_csNextAnimString = STRING_NULL;
    m_NextAnimLabel    = AnimLabel;
    m_bNextForceStart  = true;
}

inline void SimpleActor::DesiredAnimation(int eAnimMode, ScriptThreadLabel AnimLabel)
{
    m_eNextAnimMode    = eAnimMode;
    m_csNextAnimString = STRING_NULL;
    m_NextAnimLabel    = AnimLabel;
    m_bNextForceStart  = false;
}

inline void SimpleActor::ContinueAnimationAllowNoPath(void)
{
    if (m_eNextAnimMode < ANIM_MODE_NONE) {
        m_eNextAnimMode    = m_eAnimMode;
        m_csNextAnimString = STRING_NULL;
        m_NextAnimLabel    = m_Anim;
        m_bNextForceStart  = false;
    }
}

inline void SimpleActor::ContinueAnimation(void)
{
    ContinueAnimationAllowNoPath();

    if ((m_eNextAnimMode == ANIM_MODE_PATH || m_eNextAnimMode == ANIM_MODE_PATH_GOAL) && !PathExists()) {
        assert(!"ContinueAnimation() called on a pathed animation, but no path exists");
        Anim_Stand();
    }
}

inline void SimpleActor::SetPathGoalEndAnim(const_str csEndAnim)
{
    m_csPathGoalEndAnimScript = csEndAnim;
}

inline void SimpleActor::Archive(Archiver& arc)
{
    int i;

    Sentient::Archive(arc);

    arc.ArchiveInteger(&m_eAnimMode);
    m_Anim.Archive(arc);

    arc.ArchiveBool(&m_bHasDesiredLookDest);
    arc.ArchiveBool(&m_bHasDesiredLookAngles);
    arc.ArchiveVector(&m_vDesiredLookDest);
    arc.ArchiveVec3(m_DesiredLookAngles);
    arc.ArchiveVec3(m_DesiredGunDir);

    m_Path.Archive(arc);
    arc.ArchiveVec3(m_Dest);
    arc.ArchiveVec3(m_NoClipDest);

    arc.ArchiveFloat(&path_failed_time);
    arc.ArchiveFloat(&m_fPathGoalTime);
    arc.ArchiveBool(&m_bStartPathGoalEndAnim);
    Director.ArchiveString(arc, m_csPathGoalEndAnimScript);

    arc.ArchiveInteger(&m_eNextAnimMode);
    Director.ArchiveString(arc, m_csNextAnimString);
    m_NextAnimLabel.Archive(arc);
    arc.ArchiveBool(&m_bNextForceStart);

    arc.ArchiveBoolean(&m_walking);
    arc.ArchiveBoolean(&m_groundPlane);
    arc.ArchiveVec3(m_groundPlaneNormal);

    arc.ArchiveVector(&watch_offset);
    arc.ArchiveBool(&m_bThink);
    arc.ArchiveInteger(&m_PainTime);

    arc.ArchiveBool(&m_bAimAnimSet);
    arc.ArchiveBool(&m_bActionAnimSet);

    Director.ArchiveString(arc, m_csMood);
    Director.ArchiveString(arc, m_csIdleMood);

    ArchiveEnum(m_eEmotionMode, eEmotionMode);

    arc.ArchiveFloat(&m_fAimLimit_up);
    arc.ArchiveFloat(&m_fAimLimit_down);

    for (i = 0; i < MAX_FRAMEINFOS; i++) {
        arc.ArchiveUnsigned(&m_weightType[i]);
    }

    for (i = 0; i < MAX_FRAMEINFOS; i++) {
        arc.ArchiveFloat(&m_weightBase[i]);
    }

    for (i = 0; i < MAX_FRAMEINFOS; i++) {
        arc.ArchiveFloat(&m_weightCrossBlend[i]);
    }

    arc.ArchiveBool(&m_AnimMotionHigh);
    arc.ArchiveBool(&m_AnimActionHigh);
    arc.ArchiveBool(&m_AnimDialogHigh);

    arc.ArchiveVec2(obstacle_vel);

    Director.ArchiveString(arc, m_csCurrentPosition);

    arc.ArchiveBool(&m_bMotionAnimSet);
    arc.ArchiveBool(&m_bDoAI);

    arc.ArchiveFloat(&m_fCrossblendTime);

    arc.ArchiveSafePointer(&m_pAnimThread);

    arc.ArchiveBool(&m_YawAchieved);
    arc.ArchiveFloat(&m_DesiredYaw);

    arc.ArchiveInteger(&m_iVoiceTime);
    arc.ArchiveBool(&m_bSayAnimSet);

    arc.ArchiveInteger(&hit_obstacle_time);

    Director.ArchiveString(arc, m_csAnimName);

    arc.ArchiveInteger(&m_bPathErrorTime);
    arc.ArchiveInteger(&m_iMotionSlot);
    arc.ArchiveInteger(&m_iActionSlot);
    arc.ArchiveInteger(&m_iSaySlot);

    arc.ArchiveBool(&m_bLevelMotionAnim);
    arc.ArchiveBool(&m_bLevelActionAnim);
    arc.ArchiveByte(&m_bLevelSayAnim);
    arc.ArchiveByte(&m_bNextLevelSayAnim);

    Director.ArchiveString(arc, m_csSayAnim);
    Director.ArchiveString(arc, m_csUpperAnim);

    m_PainHandler.Archive(arc);
    m_DeathHandler.Archive(arc);
    m_AttackHandler.Archive(arc);
    m_SniperHandler.Archive(arc);

    arc.ArchiveObjectPointer((Class **)&m_NearestNode);
    arc.ArchiveVector(&m_vNearestNodePos);

    arc.ArchiveFloat(&m_fCrouchWeight);
    arc.ArchiveFloat(&m_maxspeed);
}

inline void SimpleActor::StopTurning(void)
{
    m_YawAchieved = true;
}

inline void SimpleActor::SetDesiredYaw(float yaw)
{
    m_YawAchieved = false;
    m_DesiredYaw  = yaw;
}

inline void SimpleActor::SetDesiredYawDir(const vec2_t vec)
{
    SetDesiredYaw(vectoyaw(vec));
}

inline void SimpleActor::SetDesiredYawDest(const vec3_t vec)
{
    vec2_t facedir;
    VectorSub2D(vec, origin, facedir);

    if (facedir[0] || facedir[1]) {
        SetDesiredYawDir(facedir);
    }
}

inline void SimpleActor::SetDest(vec3_t dest)
{
    VectorCopy(dest, m_Dest);
}