ScummVM API documentation
actor.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef TWINE_SCENE_ACTOR_H
23 #define TWINE_SCENE_ACTOR_H
24 
25 #include "common/scummsys.h"
26 #include "twine/parser/anim.h"
27 #include "twine/parser/body.h"
28 #include "twine/parser/entity.h"
29 #include "twine/shared.h"
30 
31 namespace TwinE {
32 
34 #define NUM_SPRITES 425 // 200 for lba1
35 
37 #define NUM_BODIES 469 // 131 for lba1
38 
40 struct RealValue {
41  int16 startValue = 0;
42  int16 endValue = 0;
43  int16 timeValue = 0;
44  int32 memoTicks = 0;
45 
50  int16 getRealValueFromTime(int32 time);
51  int16 getRealAngle(int32 time);
52 };
53 
56  uint32 bComputeCollisionWithObj : 1; // 0x000001 CHECK_OBJ_COL
57  uint32 bComputeCollisionWithBricks : 1; // 0x000002 CHECK_BRICK_COL
58  uint32 bCheckZone : 1; // 0x000004 CHECK_ZONE - testing of scenaric areas
59  uint32 bSpriteClip : 1; // 0x000008 SPRITE_CLIP - (doors) fixed clip area
60  uint32 bCanBePushed : 1; // 0x000010 PUSHABLE
61  uint32 bComputeLowCollision : 1; // 0x000020 COL_BASSE
62  uint32 bCanDrown : 1; // 0x000040 CHECK_CODE_JEU
63  uint32 bComputeCollisionWithFloor : 1; // 0x000080 CHECK_WATER_COL
64  uint32 bUnk0100 : 1; // 0x000100
65  uint32 bIsInvisible : 1; // 0x000200 INVISIBLE - not drawn but all computed
66  uint32 bSprite3D : 1; // 0x000400 SPRITE_3D - a sprite not a 3D object
67  uint32 bObjFallable : 1; // 0x000800 OBJ_FALLABLE
68  uint32 bNoShadow : 1; // 0x001000 NO_SHADOW - no auto shadow
69  uint32 bIsBackgrounded : 1; // 0x002000 OBJ_BACKGROUND - is embedded in the decor the 1st time
70  uint32 bIsCarrierActor : 1; // 0x004000 OBJ_CARRIER - can carry and move an obj
71  // take smaller value for bound, or if not set take average for bound
72  uint32 bUseMiniZv : 1; // 0x008000 MINI_ZV - square on smaller dimension (if 3D object)
73  uint32 bHasInvalidPosition : 1; // 0x010000 POS_INVALIDE - carrier considered as an invalid position
74  uint32 bNoElectricShock : 1; // 0x020000 NO_CHOC - does not trigger electric shock animation
75  uint32 bHasSpriteAnim3D : 1; // 0x040000 ANIM_3DS - 3DS animation (extension of 3D sprite)
76  uint32 bNoPreClipping : 1; // 0x080000 NO_PRE_CLIP - does not pre-clip the object (for large objects)
77  uint32 bHasZBuffer : 1; // 0x100000 OBJ_ZBUFFER - displays object in ZBuffer (exterior only!)
78  uint32 bHasZBufferInWater : 1; // 0x200000 OBJ_IN_WATER - displays object in ZBuffer in water (exterior only!)
79 };
80 
83  uint32 bWaitHitFrame : 1; // 0x0001 WAIT_HIT_FRAME - wait for hit frame
84  uint32 bIsHitting : 1; // 0x0002 OK_HIT - hit frame anim
85  uint32 bAnimEnded : 1; // 0x0004 ANIM_END - anim ended in the current loop (will be looped in the next engine loop)
86  uint32 bAnimNewFrame : 1; // 0x0008 NEW_FRAME - new frame anim reached
87  uint32 bWasDrawn : 1; // 0x0010 WAS_DRAWN - actor has been drawn in this loop
88  uint32 bIsDead : 1; // 0x0020 OBJ_DEAD - is dead
89  uint32 bIsSpriteMoving : 1; // 0x0040 AUTO_STOP_DOOR - door is opening or closing (wait to reach the destination position)
90  uint32 bIsRotationByAnim : 1; // 0x0080 ANIM_MASTER_ROT - actor rotation is managed by its animation not by the engine
91  uint32 bIsFalling : 1; // 0x0100 FALLING - is falling on scene
92  uint32 bIsTargetable : 1; // 0x0200 IS_TARGETABLE (lba1) OK_SUPER_HIT (lba2)
93  uint32 bIsBlinking : 1; // 0x0400 IS_BLINKING (lba1) FRAME_SHIELD (lba2)
94  uint32 bWasWalkingBeforeFalling : 1; // 0x0800 DRAW_SHADOW (lba2) - bWasWalkingBeforeFalling in lba1
95  uint32 bANIM_MASTER_GRAVITY : 1; // 0x1000 ANIM_MASTER_GRAVITY (lba2)
96  uint32 bSKATING : 1; // 0x2000 SKATING (lba2) Ouch! I slip in a forbidden collision
97  uint32 bOK_RENVOIE : 1; // 0x4000 OK_RENVOIE (lba2) ready to send back a projectile
98  uint32 bLEFT_JUMP : 1; // 0x8000 LEFT_JUMP (lba2) ready to jump from the left foot
99  uint32 bRIGHT_JUMP : 1; // RIGHT_JUMP (1<<16) // (lba2) ready to jump from the right foot
100  uint32 bWAIT_SUPER_HIT : 1; // WAIT_SUPER_HIT (1<<17) // (lba2) waiting for the end of the animation before giving another super hit
101  uint32 bTRACK_MASTER_ROT : 1; // TRACK_MASTER_ROT (1<<18) // (lba2) it's the track that manages the direction
102  uint32 bFLY_JETPACK : 1; // FLY_JETPACK (1<<19) // (lba2) flying with the Jetpack
103  uint32 bDONT_PICK_CODE_JEU : 1; // DONT_PICK_CODE_JEU (1<<20) // (lba2) Cheat - Conveyor Belt Zones
104  uint32 bMANUAL_INTER_FRAME : 1; // MANUAL_INTER_FRAME (1<<21) // (lba2) Manually performs the ObjectSetInterFrame()
105  uint32 bWAIT_COORD : 1; // WAIT_COORD (1<<22) // (lba2) waiting to have been displayed to pass the coordinates from one point to an extra
106  uint32 bCHECK_FALLING : 1; // CHECK_FALLING (1<<23) // (lba2) forces object to test FALLING during a frame
107 };
108 
120  uint16 givenNothing : 1;
121  uint16 unk2 : 1; // unused in lba1
122  uint16 unk3 : 1; // unused in lba1
123  uint16 unk4 : 1; // unused in lba1
124  uint16 kashes : 1;
125  uint16 lifepoints : 1;
126  uint16 magicpoints : 1;
127  uint16 key : 1;
128  uint16 cloverleaf : 1;
129  uint16 unused : 7;
130 };
131 
137 class ActorStruct { // T_OBJET
138 private:
139  ShapeType _col = ShapeType::kNone; // collision
140  bool _brickCausesDamage = false;
141  int32 _maxLife;
142 
143 public:
144  ActorStruct(int maxLife = 0) : _lifePoint(maxLife), _maxLife(maxLife) {}
145  StaticFlagsStruct _flags;
146  DynamicFlagsStruct _workFlags;
147 
148  EntityData _entityData;
149  inline ShapeType brickShape() const { return _col; }
150  inline void setCollision(ShapeType shapeType) {
151  _col = shapeType;
152  _brickCausesDamage = false;
153  }
154  inline void setBrickCausesDamage() { _brickCausesDamage = true; }
155  inline bool brickCausesDamage() { return _brickCausesDamage; }
156 
157  void addLife(int32 val);
158 
159  void setLife(int32 val);
160 
161  bool isAttackWeaponAnimationActive() const;
162  bool isAttackAnimationActive() const;
163  bool isJumpAnimationActive() const;
164 
165  const IVec3 &posObj() const;
166 
167  int32 _body = -1; // costumeIndex - index into bodyTable
168  BodyType _genBody = BodyType::btNormal;
169  BodyType _saveGenBody = BodyType::btNormal; // lba2
170  AnimationTypes _genAnim = AnimationTypes::kAnimNone;
171  AnimationTypes _nextGenAnim = AnimationTypes::kStanding;
172  AnimationTypes _ptrAnimAction = AnimationTypes::kAnimNone;
173  int32 _sprite = 0;
174  EntityData *_entityDataPtr = nullptr;
175 
176  int16 _actorIdx = 0; // own actor index
177  IVec3 _posObj; // PosObjX, PosObjY, PosObjZ
178 
179  // T_ANIM_3DS - Coord.A3DS
180  struct A3DSAnim {
181  int32 Num;
182  int32 Deb;
183  int32 Fin;
184  } A3DS;
185 
186  int32 _hitForce = 0;
187  int32 _hitBy = -1;
188  BonusParameter _bonusParameter;
189  int32 _beta = 0; // facing angle of actor. Minumum is 0 (SW). Going counter clock wise
190  int32 _srot = 40; // speed of rotation
191  ControlMode _move = ControlMode::kNoMove; // Move
192  int32 _delayInMillis = 0; // Info
193  int32 _cropLeft = 0; // Info
194  int32 _cropTop = 0; // Info1
195  int32 _cropRight = 0; // Info2
196  int32 _cropBottom = 0; // Info3
197  int32 _followedActor = 0; // same as Info3
198  int32 _bonusAmount = 0;
199  int32 _talkColor = COLOR_BLACK;
200  int32 _armor = 1;
201  int32 _lifePoint = 0;
202 
205  IVec3 _oldPos; // OldPosX, OldPosY, OldPosZ
206 
207  int32 _offsetTrack = -1;
208  uint8 *_ptrTrack = nullptr;
209  int32 _moveScriptSize = 0;
210 
211  int32 _offsetLife = 0;
212  int32 _saveOffsetLife = 0; // lba2
213  uint8 *_lifeScript = nullptr;
214  int32 _lifeScriptSize = 0;
215 
216  int32 _labelTrack = 0; // script label index
217  int32 _offsetLabelTrack = 0; // pointer to LABEL offset
218  int32 _memoLabelTrack = 0;
219 
223  int32 _objCol = -1;
227  int32 _carryBy = -1;
228  int32 _zoneSce = -1;
229 
230  int32 _animStepBeta = 0;
231  IVec3 _animStep;
232  int32 _anim = -1;
233  int32 _doorWidth = 0;
234  int32 _frame = 0;
235  AnimType _flagAnim = AnimType::kAnimationTypeRepeat;
236  int32 _spriteActorRotation = 0;
237  uint8 _brickSound = 0U; // CodeJeu
238  int32 SampleAlways = 0; // lba2
239  uint8 SampleVolume = 0; // lba2
240  // SizeSHit contains the number of the brick under the wagon - hack
241  int16 SizeSHit; // lba2 - always square
242 
243  // T_OBJ_3D Obj; // lba2
244  // T_GROUP_INFO CurrentFrame[30]; // lba2
245 
246  BoundingBox _boundingBox; // Xmin, YMin, Zmin, Xmax, Ymax, Zmax
247  RealValue realAngle;
248 };
249 
250 inline const IVec3 &ActorStruct::posObj() const {
251  return _posObj;
252 }
253 
254 inline void ActorStruct::addLife(int32 val) {
255  setLife(_lifePoint + val);
256 }
257 
258 inline void ActorStruct::setLife(int32 val) {
259  _lifePoint = val;
260  if (_lifePoint > _maxLife) {
261  _lifePoint = _maxLife;
262  }
263 }
264 
265 class TwinEEngine;
266 
267 class Actor {
268 private:
269  TwinEEngine *_engine;
270 
272  EntityData _heroEntityNORMAL;
274  EntityData _heroEntityATHLETIC;
276  EntityData _heroEntityAGGRESSIVE;
278  EntityData _heroEntityDISCRETE;
280  EntityData _heroEntityPROTOPACK;
281 
287  int32 searchBody(BodyType bodyIdx, int32 actorIdx, ActorBoundingBox &actorBoundingBox);
288 
289  void loadBehaviourEntity(ActorStruct *actor, EntityData &entityData, int16 &bodyAnimIndex, int32 index);
290 
291  void copyInterAnim(const BodyData &src, BodyData &dest);
292 
293 public:
294  Actor(TwinEEngine *engine);
295 
296  HeroBehaviourType _heroBehaviour = HeroBehaviourType::kNormal; // Comportement
297  HeroBehaviourType _saveHeroBehaviour = HeroBehaviourType::kNormal; // SaveComportementHero (lba2)
299  bool _combatAuto = true;
301  HeroBehaviourType _previousHeroBehaviour = HeroBehaviourType::kNormal;
303  int16 _previousHeroAngle = 0;
304 
305  int16 _cropBottomScreen = 0; // TODO: usage differ in original sources
306 
308  int16 _heroAnimIdxNORMAL = 0;
310  int16 _heroAnimIdxATHLETIC = 0;
312  int16 _heroAnimIdxAGGRESSIVE = 0;
314  int16 _heroAnimIdxDISCRETE = 0;
316  int16 _heroAnimIdxPROTOPACK = 0;
317 
319  int16 _heroAnimIdx[4];
320 
321  void initSprite(int32 spriteNum, int32 actorIdx);
322  void setFrame(int32 actorIdx, uint32 frame);
323 
325  void restartPerso();
326 
328  void loadHeroEntities();
329 
330  TextId getTextIdForBehaviour() const;
331 
336  void setBehaviour(HeroBehaviourType behaviour); // SetComportement
337 
343  void initBody(BodyType bodyIdx, int16 actorIdx);
344 
349  void startInitObj(int16 actorIdx);
350 
355  void initObject(int16 actorIdx);
356 
364  void hitObj(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32 angle);
365 
367  void checkCarrier(int32 actorIdx);
368 
370  void giveExtraBonus(int32 actorIdx);
371 
372  // Lba2
373  void posObjectAroundAnother(uint8 numsrc, uint8 numtopos); // PosObjetAroundAnother
374 };
375 
376 } // namespace TwinE
377 
378 #endif
int16 getRealValueFromTime(int32 time)
Definition: actor.h:137
Definition: actor.h:267
Definition: shared.h:125
Definition: actor.h:119
Definition: actor.h:55
Definition: actor.h:180
Definition: actor.h:40
Associate 3d models from body hqr with animations from anim.hqr for the game characters.
Definition: entity.h:83
Definition: twine.h:207
Definition: achievements_tables.h:27
Axis aligned bounding box.
Definition: shared.h:191
Definition: actor.h:82
IVec3 _processActor
Definition: actor.h:204
Definition: shared.h:200
Definition: body.h:41