1 /* ResidualVM - A 3D game interpreter
2  *
3  * ResidualVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the AUTHORS
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef STARK_RESOURCES_ITEM_H
24 #define STARK_RESOURCES_ITEM_H
25 
26 #include "engines/stark/resources/object.h"
27 #include "engines/stark/resourcereference.h"
28 
29 #include "common/rect.h"
30 #include "common/str.h"
31 
32 #include "math/vector3d.h"
33 
34 namespace Stark {
35 
36 class Movement;
37 class Visual;
38 
39 namespace Gfx {
40 class RenderEntry;
41 }
42 
43 namespace Formats {
44 class XRCReadStream;
45 }
46 
47 namespace Resources {
48 
49 class Anim;
50 class AnimHierarchy;
51 class BonesMesh;
52 class Bookmark;
53 class ItemVisual;
54 class Script;
55 class TextureSet;
56 
57 /**
58  * A scene element
59  *
60  * Can be a character, background, animation, ...
61  */
62 class Item : public Object {
63 public:
64 	static const Type::ResourceType TYPE = Type::kItem;
65 
66 	enum SubType {
67 		kItemGlobalTemplate = 1,
68 		kItemInventory = 2,
69 		kItemLevelTemplate = 3,
70 		kItemStaticProp = 5,
71 		kItemAnimatedProp = 6,
72 		kItemBackgroundElement = 7,
73 		kItemBackground = 8,
74 		kItemModel = 10
75 	};
76 
77 	/** Item factory */
78 	static Object *construct(Object *parent, byte subType, uint16 index, const Common::String &name);
79 
80 	Item(Object *parent, byte subType, uint16 index, const Common::String &name);
81 	virtual ~Item();
82 
83 	// Resource API
84 	virtual void readData(Formats::XRCReadStream *stream) override;
85 	virtual void onGameLoop() override;
86 	virtual void saveLoad(ResourceSerializer *serializer) override;
87 	virtual void saveLoadCurrent(ResourceSerializer *serializer) override;
88 
89 	/** Is the item present in the scene */
90 	bool isEnabled() const;
91 
92 	/** Enable or disable the item */
93 	virtual void setEnabled(bool enabled);
94 
95 	/** Get the item's character index */
96 	int32 getCharacterIndex() const;
97 
98 	/** Obtain the render entry to use to display the item */
99 	virtual Gfx::RenderEntry *getRenderEntry(const Common::Point &positionOffset);
100 
101 	/** Obtain the concrete instance of an item template */
102 	virtual ItemVisual *getSceneInstance() = 0;
103 
104 	/** Replace the current movement with an other */
105 	void setMovement(Movement *movement);
106 
107 	/** Get the current movement if any */
108 	Movement *getMovement() const;
109 
110 	/**
111 	 * Set the script waiting for the item's movement to complete.
112 	 *
113 	 * This script will be updated with the outcome of the movement
114 	 * (completion or abortion)
115 	 */
116 	void setMovementSuspendedScript(Script *script);
117 
118 	/** Set the currently active anim hierachy */
119 	virtual void setAnimHierarchy(AnimHierarchy *animHierarchy) = 0;
120 
121 protected:
122 	void printData() override;
123 
124 	bool _enabled;
125 	int32 _characterIndex;
126 
127 	Movement *_movement;
128 	Script *_movementSuspendedScript;
129 };
130 
131 /**
132  * A renderable item
133  *
134  * Renderable items are found in location layers
135  */
136 class ItemVisual : public Item {
137 public:
138 	ItemVisual(Object *parent, byte subType, uint16 index, const Common::String &name);
139 	virtual ~ItemVisual();
140 
141 	// Resource API
142 	virtual void readData(Formats::XRCReadStream *stream) override;
143 	virtual void onAllLoaded() override;
144 	virtual void saveLoad(ResourceSerializer *serializer) override;
145 	virtual void saveLoadCurrent(ResourceSerializer *serializer) override;
146 	virtual void onPreDestroy() override;
147 
148 	// Item API
149 	void setEnabled(bool enabled) override;
150 	ItemVisual *getSceneInstance() override;
151 	void setAnimHierarchy(AnimHierarchy *animHierarchy) override;
152 
153 	/**
154 	 * Change the item's 2D position.
155 	 *
156 	 * Only applies to 2D items
157 	 */
158 	virtual void setPosition2D(const Common::Point &position);
159 
160 	/** Get the hotspot index for an item relative position */
161 	int getHotspotIndexForPoint(const Common::Point &point);
162 
163 	/** Obtain the title for one of the item's hotspots */
164 	Common::String getHotspotTitle(uint32 hotspotIndex);
165 
166 	/** Check whether the item has runnable scripts for the specified action */
167 	bool canPerformAction(uint32 action, uint32 hotspotIndex);
168 
169 	/** Perform an action on one of the item's hotspots */
170 	bool doAction(uint32 action, uint32 hotspotIndex);
171 
172 	/** Define the current animation kind for the item */
173 	void setAnimKind(int32 usage);
174 
175 	/** Get the current animation kind */
176 	int32 getAnimKind() const;
177 
178 	/** Get the currently playing animation */
179 	Anim *getAnim() const;
180 
181 	/** Get the currently playing action animation, if any */
182 	Anim *getActionAnim() const;
183 
184 	/** Replace the current generic animation with an action specific animation */
185 	void playActionAnim(Anim *anim);
186 
187 	/** Remove the current specific animation and revert to a generic one */
188 	void resetActionAnim();
189 
190 protected:
191 	// Resource API
192 	void printData() override;
193 
194 	Visual *getVisual();
195 
196 	Gfx::RenderEntry *_renderEntry;
197 
198 	Anim *_actionAnim;
199 	AnimHierarchy *_animHierarchy;
200 	int32 _currentAnimKind;
201 	bool _clickable;
202 };
203 
204 /**
205  * An item template
206  *
207  * Item templates need to be instanciated into renderable items to be displayed
208  */
209 class ItemTemplate : public Item {
210 public:
211 	ItemTemplate(Object *parent, byte subType, uint16 index, const Common::String &name);
212 	virtual ~ItemTemplate();
213 
214 	// Resource API
215 	void onAllLoaded() override;
216 	void onEnterLocation() override;
217 	void saveLoadCurrent(ResourceSerializer *serializer) override;
218 
219 	// Item API
220 	ItemVisual *getSceneInstance() override;
221 	void setAnimHierarchy(AnimHierarchy *animHierarchy) override;
222 
223 	/** Obtain the bone mesh to use to render the item */
224 	virtual BonesMesh *findBonesMesh() = 0;
225 
226 	/** Obtain the texture to use to render the item */
227 	virtual TextureSet *findTextureSet(uint32 textureType) = 0;
228 
229 	/** Obtain the animation hierarchy to fetch animations from */
230 	virtual AnimHierarchy *findStockAnimHierarchy() = 0;
231 
232 	/** Define the anim hierarchy to be persisted across locations */
233 	void setStockAnimHierachy(AnimHierarchy *animHierarchy);
234 
235 	/** Change the item's mesh */
236 	void setBonesMesh(int32 index);
237 
238 	/** Set the mesh main or face texture */
239 	void setTexture(int32 index, uint32 textureType);
240 
241 	/** Set the scene instanciation for this template */
242 	void setInstanciatedItem(Item *instance);
243 
244 protected:
245 	int32 _meshIndex;
246 	int32 _textureNormalIndex;
247 	int32 _textureFaceIndex;
248 	int32 _animHierarchyIndex;
249 
250 	Item *_instanciatedItem;
251 	ItemTemplate *_referencedItem;
252 };
253 
254 /**
255  * A global item template
256  *
257  * Global item templates are found in the global level
258  */
259 class GlobalItemTemplate : public ItemTemplate {
260 public:
261 	GlobalItemTemplate(Object *parent, byte subType, uint16 index, const Common::String &name);
262 	virtual ~GlobalItemTemplate();
263 
264 	// ItemTemplate API
265 	BonesMesh *findBonesMesh() override;
266 	TextureSet *findTextureSet(uint32 textureType) override;
267 	AnimHierarchy *findStockAnimHierarchy() override;
268 
269 protected:
270 };
271 
272 /**
273  * An inventory item
274  */
275 class InventoryItem : public ItemVisual {
276 public:
277 	InventoryItem(Object *parent, byte subType, uint16 index, const Common::String &name);
278 	virtual ~InventoryItem();
279 
280 	// Item API
281 	Gfx::RenderEntry *getRenderEntry(const Common::Point &positionOffset) override;
282 	void setEnabled(bool enabled) override;
283 
284 	/** Obtain an action menu icon */
285 	Visual *getActionVisual(bool active) const;
286 
287 	/** Obtain an inventory item cursor */
288 	Visual *getCursorVisual() const;
289 
290 protected:
291 };
292 
293 /**
294  * A level item template
295  *
296  * Level item templates are found in levels so that they can be shared between
297  * locations.
298  */
299 class LevelItemTemplate : public ItemTemplate {
300 public:
301 	LevelItemTemplate(Object *parent, byte subType, uint16 index, const Common::String &name);
302 	virtual ~LevelItemTemplate();
303 
304 	// Resource API
305 	void readData(Formats::XRCReadStream *stream) override;
306 	void onAllLoaded() override;
307 
308 	// ItemTemplate API
309 	BonesMesh *findBonesMesh() override;
310 	TextureSet *findTextureSet(uint32 textureType) override;
311 	AnimHierarchy *findStockAnimHierarchy() override;
312 
313 	/** Get the item's level or global template if any */
314 	ItemTemplate *getItemTemplate() const;
315 
316 protected:
317 	void printData() override;
318 
319 	ResourceReference _reference;
320 };
321 
322 /**
323  * 3D positioned item
324  *
325  * Items with a 3D position, used in 3D layers. The sort key determines the order
326  * in which such items are drawn in.
327  */
328 class FloorPositionedItem : public ItemVisual {
329 public:
330 	FloorPositionedItem(Object *parent, byte subType, uint16 index, const Common::String &name);
331 	virtual ~FloorPositionedItem();
332 
333 	// Object API
334 	void saveLoad(ResourceSerializer *serializer) override;
335 
336 	/** Move the item to a bookmarked position */
337 	void placeOnBookmark(Bookmark *target);
338 
339 	/** Place the item on the center of the first floor face */
340 	void placeDefaultPosition();
341 
342 	/** Get the item position */
343 	Math::Vector3d getPosition3D() const;
344 	/** Move the item */
345 	void setPosition3D(const Math::Vector3d &position);
346 
347 	/** Get the floor face index the item is standing on */
348 	int32 getFloorFaceIndex() const;
349 	/** Change the face the item is standing on */
350 	void setFloorFaceIndex(int32 faceIndex);
351 
352 	/** Get a vector pointing in the same direction as the item */
353 	Math::Vector3d getDirectionVector() const;
354 
355 	/** Set the direction the item faces */
356 	void setDirection(const Math::Angle &direction);
357 
358 	/** Obtain the sort value for the item, used to compute the draw order */
359 	float getSortKey() const;
360 
361 	/**
362 	 * Don't rely on the floor face to compute the sort key, use the provided value instead.
363 	 *
364 	 * This can be used to handle cases where the item is not over the floor.
365 	 */
366 	void overrideSortKey(float sortKey);
367 
368 protected:
369 	int32 _floorFaceIndex;
370 	Math::Vector3d _position3D;
371 	float _direction3D;
372 
373 	bool _sortKeyOverride;
374 	float _sortKeyOverridenValue;
375 };
376 
377 /**
378  * 3D positioned image item
379  *
380  * Used to display still images or animated images in 3D layers
381  */
382 class FloorPositionedImageItem : public FloorPositionedItem {
383 public:
384 	FloorPositionedImageItem(Object *parent, byte subType, uint16 index, const Common::String &name);
385 	virtual ~FloorPositionedImageItem();
386 
387 	// Resource API
388 	virtual void readData(Formats::XRCReadStream *stream) override;
389 
390 	// Item API
391 	Gfx::RenderEntry *getRenderEntry(const Common::Point &positionOffset) override;
392 
393 	// ItemVisual API
394 	void setPosition2D(const Common::Point &position) override;
395 
396 protected:
397 	void printData() override;
398 
399 	Common::Point _position;
400 };
401 
402 /**
403  * Model item
404  *
405  * Used to draw characters
406  */
407 class ModelItem : public FloorPositionedItem {
408 public:
409 	ModelItem(Object *parent, byte subType, uint16 index, const Common::String &name);
410 	virtual ~ModelItem();
411 
412 	// Resource API
413 	void readData(Formats::XRCReadStream *stream) override;
414 	void onAllLoaded() override;
415 	void onEnterLocation() override;
416 	void onExitLocation() override;
417 	void saveLoadCurrent(ResourceSerializer *serializer) override;
418 
419 	// Item API
420 	Gfx::RenderEntry *getRenderEntry(const Common::Point &positionOffset) override;
421 
422 	/** Set the mesh main or face texture */
423 	void setTexture(int32 index, uint32 textureType);
424 
425 	/** Change the item's mesh */
426 	void setBonesMesh(int32 index);
427 
428 	/** Obtain the bone mesh to use to render the item */
429 	BonesMesh *findBonesMesh();
430 
431 	/** Obtain the texture to use to render the item */
432 	TextureSet *findTextureSet(uint32 textureType);
433 
434 	/** Get the item's level or global template if any */
435 	ItemTemplate *getItemTemplate() const;
436 
437 	/** Update the item's animation after a texture / mesh change */
438 	void updateAnim();
439 
440 	/** Reset animation blending */
441 	void resetAnimationBlending();
442 
443 	/** Randomize an idle action animation */
444 	Anim *getIdleActionAnim() const;
445 
446 protected:
447 	void printData() override;
448 
449 	int32 _meshIndex;
450 	int32 _textureNormalIndex;
451 	int32 _textureFaceIndex;
452 
453 	ResourceReference _reference;
454 	ItemTemplate *_referencedItem;
455 };
456 
457 /**
458  * 2D positioned image item
459  *
460  * Used to display background elements in 2D layers
461  */
462 class ImageItem : public ItemVisual {
463 public:
464 	ImageItem(Object *parent, byte subType, uint16 index, const Common::String &name);
465 	virtual ~ImageItem();
466 
467 	// Resource API
468 	virtual void readData(Formats::XRCReadStream *stream) override;
469 
470 	// Item API
471 	Gfx::RenderEntry *getRenderEntry(const Common::Point &positionOffset) override;
472 
473 	// ItemVisual API
474 	void setPosition2D(const Common::Point &position) override;
475 
476 protected:
477 	void printData() override;
478 
479 	ResourceReference _reference;
480 	Common::Point _position;
481 };
482 
483 } // End of namespace Resources
484 } // End of namespace Stark
485 
486 #endif // STARK_RESOURCES_ITEM_H
487