ScummVM API documentation
actionzone.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 NANCY_ACTION_ACTIONZONE_H
23 #define NANCY_ACTION_ACTIONZONE_H
24 
25 #include "common/array.h"
26 #include "common/rect.h"
27 #include "common/str.h"
28 
29 #include "engines/nancy/commontypes.h"
30 
31 namespace Common {
32 class SeekableReadStream;
33 }
34 
35 namespace Nancy {
36 namespace Action {
37 
38 // The zone's subtype, stored in the low byte of its leading int32. It selects both
39 // what the zone does at runtime and how much trailing data follows the shared base.
40 // Subtypes whose meaning has not been worked out yet are named after their value;
41 // those still read (or skip) the right number of bytes.
42 enum ActionZoneType : byte {
43  kZoneSpecialEffect = 0x00, // carries a scene id plus an optional fade
44  kZoneBaseOnly = 0x01, // base fields only, no behavior of its own
45  kZoneTeleport = 0x02, // pipe: swallows the ball and re-emits it elsewhere
46  kZoneTerrain = 0x03, // sand trap / mud puddle: slows whatever is inside
47  kZoneSlope = 0x04, // hill: a velocity kick while crossing the zone
48  kZoneUnknown05 = 0x05, // base fields only
49  kZoneEventFlag = 0x0b, // checkpoint / sewing seam: sets an event flag
50  kZoneSceneChange = 0x0c, // finish line / golf cup: fade + target scene + flag
51  kZoneOverlay = 0x0d, // cosmetic overlay sprite
52  kZoneUnknown0E = 0x0e,
53  kZoneUnknown0F = 0x0f,
54  kZoneUnknown10 = 0x10, // base fields only
55  kZoneDestination = 0x11, // driving: a location entrance the car can park in
56  kZoneUnknown12 = 0x12, // another special-effect variant
57  kZoneUnknown13 = 0x13, // another special-effect variant
58  kZoneBoundary = 0x14, // play-area wall
59  kZoneUnknown15 = 0x15, // Nancy12: on entry, sound + special effect + change to scene specialEffectId; a damage range in Nancy13
60  kZoneBumper = 0x16, // Nancy12: an overlay variant; Nancy13: a pachinko hole
61  kZoneFlatTire = 0x17, // pothole: damages the car driving over it
62  kZoneCursor = 0x1a // Nancy17: changes the cursor over the zone
63 };
64 
65 // A polymorphic "ActionZone" record, embedded as a count-prefixed array inside
66 // every Nancy12 PuzzleBase puzzle (Driving/Minigolf/MirrorLight/BoardGame/Mind/
67 // Chase). Each subtype reads a different amount of trailing data; readData()
68 // consumes exactly the right number of bytes so the surrounding chunk stays in sync.
69 struct ActionZone {
70  ActionZoneType type = kZoneSpecialEffect;
71  int32 typeField = 0; // full leading int32; low byte == type
72 
73  Common::Rect rect;
74  Common::String ovlName; // OVL sprite name ("" / sentinel == none)
75 
76  int32 pointA = 0; // 8 bytes (a point) at base+0x39
77  int32 pointB = 0;
78  int32 valC = 0; // 8 bytes at base+0x41
79  int32 valD = 0;
80  int16 val49 = 0;
81  byte val4b = 0;
82 
83  RandomSoundBlock _sound;
84 
85  // Special Effect (an embedded 21-byte SpecialEffect record, present on the
86  // special-effect subtypes when the effect byte is not the terminator).
87  uint16 specialEffectId = 0;
88  bool hasSpecialEffect = false;
89  byte seType = 0; // 1 = blackout, 2 = cross-dissolve, 3 = through-black
90  uint16 seTotalTime = 0;
91  uint16 seFadeToBlackTime = 0;
92  Common::Rect seRect;
93 
94  // int16 + byte trailer carried by kZoneEventFlag and kZoneSceneChange. For the
95  // former it is an event-flag id + on/off; for the latter a target scene id + a
96  // flag. kZoneCursor has a cursor type + whether the cursor is the highlighted
97  // one. Left at their defaults for the other subtypes.
98  int16 tailId = 0;
99  byte tailFlag = 0;
100 
101  // kZoneTeleport: the ball entering this zone is held for teleportDelay ms, then
102  // re-emerges at exitRect travelling at exitSpeed along exitAngle (degrees).
103  Common::Rect exitRect;
104  int32 teleportDelay = 0;
105  int16 exitAngle = 0;
106  int16 exitSpeed = 0;
107 
108  // kZoneTerrain: extra deceleration added to the moving object's friction while
109  // it is inside this zone.
110  double terrainDecel = 0.0;
111 
112  // kZoneFlatTire: entering the zone adds a random amount of damage in
113  // [flatTireMin, flatTireMax].
114  int32 flatTireMin = 0;
115  int32 flatTireMax = 0;
116 
117  // kZoneSlope: a velocity kick of slopeForce along slopeAngle (degrees), applied
118  // on entering the zone and removed on leaving.
119  double slopeForce = 0.0;
120  int16 slopeAngle = 0;
121 
122  // kZoneOverlay (and kZoneBumper in Nancy12)
123  Common::String overlayName;
124  Common::Array<Common::Rect> overlaySrcRects;
125  Common::Rect overlayDestRect;
126  byte overlayPlayMode = 0; // 1 = drawn opaque; anything else = color-keyed
127  int32 overlayLayer = 0; // draw pass: 0 renders under the car, 1 over it
128 
129  // The Nancy13 pinball layout (AR 175) differs from the Nancy12 one: the base carries an
130  // extra int32 before the sound block, and the overlay/unknown-0x15/bumper subtypes have
131  // different trailers. Pass isNancy13 = true to parse it; the default keeps Nancy12.
132  void readData(Common::SeekableReadStream &stream, bool isNancy13 = false);
133 
134 private:
135  void readSpecialEffect(Common::SeekableReadStream &stream);
136  void readOverlayZone(Common::SeekableReadStream &stream, bool isNancy13);
137  void readSubtype(Common::SeekableReadStream &stream, bool isNancy13);
138 };
139 
140 // Reads an int16 count, then that many ActionZones.
141 void readActionZoneArray(Common::SeekableReadStream &stream, Common::Array<ActionZone> &out, bool isNancy13 = false);
142 
143 } // End of namespace Action
144 } // End of namespace Nancy
145 
146 #endif // NANCY_ACTION_ACTIONZONE_H
Definition: str.h:59
Definition: rect.h:536
Definition: stream.h:745
Definition: commontypes.h:324
Definition: algorithm.h:29
Definition: actionzone.h:69
Definition: actionmanager.h:32