Initial commit
This commit is contained in:
568
engines/saga2/contain.h
Normal file
568
engines/saga2/contain.h
Normal file
@@ -0,0 +1,568 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
* Based on the original sources
|
||||
* Faery Tale II -- The Halls of the Dead
|
||||
* (c) 1993-1996 The Wyrmkeep Entertainment Co.
|
||||
*/
|
||||
|
||||
#ifndef SAGA2_CONTAIN_H
|
||||
#define SAGA2_CONTAIN_H
|
||||
|
||||
#include "saga2/floating.h"
|
||||
|
||||
namespace Saga2 {
|
||||
|
||||
// gPanel
|
||||
// gControl
|
||||
class ContainerView;
|
||||
class ScrollingContainerView;
|
||||
class ActorContainerView;
|
||||
class ReadyContainerView;
|
||||
class SmallContainerView;
|
||||
class EnchantContainerView;
|
||||
// gWindow
|
||||
// DecoratedWindow
|
||||
// FloatingWindow
|
||||
class ContainerWindow;
|
||||
class ContainerNode;
|
||||
class ContainerManager;
|
||||
struct ContainerAppearanceDef;
|
||||
|
||||
class CMassWeightIndicator;
|
||||
class ProtoObj;
|
||||
|
||||
class GfxCompButton;
|
||||
class GfxCompImage;
|
||||
class GfxMultCompButton;
|
||||
struct TilePoint;
|
||||
|
||||
/* ===================================================================== *
|
||||
Class definitions
|
||||
* ===================================================================== */
|
||||
|
||||
// The base class for all container panels
|
||||
|
||||
class ContainerView : public gControl {
|
||||
|
||||
friend class ContainerWindow;
|
||||
friend class TangibleContainerWindow;
|
||||
friend class IntangibleContainerWindow;
|
||||
|
||||
protected:
|
||||
|
||||
enum imageData {
|
||||
kSelectorX = 10,
|
||||
kSelectorY = 25
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
ContainerNode &_node;
|
||||
|
||||
Point16 _iconOrigin; // of the top left icon.
|
||||
Point16 _iconSpacing; // The spacing between icons (in both X and Y)
|
||||
|
||||
// The number of rows and columns of icons that can be seen
|
||||
int16 _visibleRows,
|
||||
_visibleCols;
|
||||
|
||||
// The total number of rows, and the scroll position of the control
|
||||
int16 _totalRows,
|
||||
_scrollPosition;
|
||||
|
||||
// Pointer to the object that this control is showing the
|
||||
// contents of.
|
||||
GameObject *_containerObject;
|
||||
|
||||
// Mass and bulk indicators
|
||||
int16 _totalMass,
|
||||
_totalBulk;
|
||||
|
||||
// Number of visible objects currently in the container
|
||||
int16 _numObjects;
|
||||
|
||||
// Constructor
|
||||
ContainerView(
|
||||
gPanelList &,
|
||||
const Rect16 &,
|
||||
ContainerNode &nd,
|
||||
const ContainerAppearanceDef &app,
|
||||
AppFunc *cmd = NULL);
|
||||
|
||||
// Destructor
|
||||
~ContainerView();
|
||||
|
||||
// redraw the panel offscreen
|
||||
virtual void drawClipped(gPort &port, const Point16 &offset, const Rect16 &clip);
|
||||
|
||||
// draws the mereged object multi-item selector
|
||||
void drawSelector(gPort &port, Point16 &pos);
|
||||
|
||||
// Draw the quantity indicator below the object if quantity > 1
|
||||
void drawQuantity(gPort &port, GameObject *item, ProtoObj *objProto, int16 x, int16 y);
|
||||
|
||||
// returns true if the object is visible for this type of
|
||||
// container.
|
||||
virtual bool isVisible(GameObject *obj);
|
||||
|
||||
// total the mass, bulk, and number of all objects in container.
|
||||
void totalObjects();
|
||||
|
||||
// Get the Nth visible object from this container.
|
||||
ObjectID getObject(int16 slotNum);
|
||||
|
||||
void setContainer(GameObject *container);
|
||||
|
||||
// get the slot the point is over
|
||||
TilePoint pickObjectSlot(const Point16 &pickPos);
|
||||
|
||||
// Get the object in a slot (u/v)
|
||||
GameObject *getObject(const TilePoint &slot);
|
||||
|
||||
// Get the object that the point is over
|
||||
GameObject *pickObject(const Point16 &pickPos);
|
||||
|
||||
// Get the object ID that the point is over
|
||||
ObjectID pickObjectID(const Point16 &pickPos);
|
||||
|
||||
protected: // actions within a container
|
||||
|
||||
// These are the actions when there is no Item in the mouse
|
||||
virtual void clickOn(gPanelMessage &msg, GameObject *mObj, GameObject *cObj);
|
||||
virtual void dblClickOn(gPanelMessage &msg, GameObject *mObj, GameObject *cObj);
|
||||
|
||||
// this gets a merged item
|
||||
void getMerged(GameObject *obj);
|
||||
|
||||
// drop Physical Object into container
|
||||
virtual void dropPhysical(gPanelMessage &msg, GameObject *mObj, GameObject *cObj, int16 num = 1);
|
||||
|
||||
// Use Physical Object on other object in container
|
||||
virtual void usePhysical(gPanelMessage &msg, GameObject *mObj, GameObject *cObj);
|
||||
|
||||
// Use Concept or Psycological object in container
|
||||
// note: only valid container use is to drop into
|
||||
// center characters's ready container.
|
||||
virtual void useConcept(gPanelMessage &msg, GameObject *mObj, GameObject *cObj);
|
||||
|
||||
// Use Spell or Skill on other object in container or
|
||||
// drop into center characters's ready container.
|
||||
virtual void useSpell(gPanelMessage &msg, GameObject *mObj, GameObject *cObj);
|
||||
|
||||
// Event-handling functions
|
||||
|
||||
bool activate(gEventType why); // activate the control
|
||||
void deactivate();
|
||||
|
||||
virtual void pointerMove(gPanelMessage &msg);
|
||||
virtual bool pointerHit(gPanelMessage &msg);
|
||||
virtual void pointerRelease(gPanelMessage &msg);
|
||||
virtual void timerTick(gPanelMessage &msg);
|
||||
|
||||
void dblClick(GameObject *mouseObject, GameObject *slotObject, gPanelMessage &msg);
|
||||
|
||||
private:
|
||||
// Container manipulation functions
|
||||
void add(ObjectID newObj);
|
||||
void remove(ObjectID obj);
|
||||
void swap(ObjectID newObj, ObjectID oldObj);
|
||||
|
||||
// Determine if the mouse is pointing a new object, and if so,
|
||||
// adjust the mouse text
|
||||
void updateMouseText(Point16 &pickPos);
|
||||
void setCursorText(GameObject *obj);
|
||||
void setDelayedCursorText(GameObject *obj);
|
||||
};
|
||||
|
||||
// sub class for ready inventory items
|
||||
|
||||
class ReadyContainerView : public ContainerView {
|
||||
private:
|
||||
void **_backImages; // pointers to background imagery
|
||||
int16 _numIm;
|
||||
|
||||
public:
|
||||
|
||||
ReadyContainerView(gPanelList &,
|
||||
const Rect16 &,
|
||||
ContainerNode &,
|
||||
void **backgrounds,
|
||||
int16 numRes,
|
||||
int16 numRows,
|
||||
int16 numCols,
|
||||
int16 totRows,
|
||||
AppFunc *cmd);
|
||||
|
||||
// redraw the panel offscreen
|
||||
virtual void drawClipped(gPort &port, const Point16 &offset, const Rect16 &clip);
|
||||
|
||||
void setScrollOffset(int8 num);
|
||||
void timerTick(gPanelMessage &msg);
|
||||
};
|
||||
|
||||
// sub class for enchantment container panels
|
||||
|
||||
class EnchantmentContainerView : public ContainerView {
|
||||
public:
|
||||
EnchantmentContainerView(gPanelList &list,
|
||||
ContainerNode &nd,
|
||||
const ContainerAppearanceDef &app,
|
||||
AppFunc *cmd = NULL);
|
||||
|
||||
virtual void pointerMove(gPanelMessage &msg);
|
||||
virtual bool pointerHit(gPanelMessage &msg);
|
||||
};
|
||||
|
||||
|
||||
// The container window is simply a floating window with an embedded
|
||||
// container view panel and a close button control
|
||||
|
||||
class ContainerWindow : public FloatingWindow {
|
||||
protected:
|
||||
GfxCompButton *_closeCompButton; // the close button object
|
||||
ContainerView *_view; // the container view object
|
||||
|
||||
public:
|
||||
ContainerWindow(ContainerNode &nd,
|
||||
const ContainerAppearanceDef &app,
|
||||
const char saveas[]);
|
||||
|
||||
virtual ~ContainerWindow();
|
||||
|
||||
ContainerView &getView();
|
||||
GameObject *containerObject() {
|
||||
return getView()._containerObject;
|
||||
}
|
||||
|
||||
virtual void massBulkUpdate() {}
|
||||
};
|
||||
|
||||
// Base class for all container windows with scroll control
|
||||
class ScrollableContainerWindow : public ContainerWindow {
|
||||
protected:
|
||||
GfxCompButton *_scrollCompButton;
|
||||
|
||||
public:
|
||||
ScrollableContainerWindow(ContainerNode &nd,
|
||||
const ContainerAppearanceDef &app,
|
||||
const char saveas[]);
|
||||
|
||||
void scrollUp() {
|
||||
if (_view->_scrollPosition > 0) _view->_scrollPosition--;
|
||||
}
|
||||
|
||||
void scrollDown() {
|
||||
if (_view->_scrollPosition + _view->_visibleRows < _view->_totalRows)
|
||||
_view->_scrollPosition++;
|
||||
}
|
||||
};
|
||||
|
||||
// A container window for tangible containers
|
||||
class TangibleContainerWindow : public ScrollableContainerWindow {
|
||||
private:
|
||||
GfxCompImage *_containerSpriteImg;
|
||||
CMassWeightIndicator *_massWeightIndicator;
|
||||
|
||||
Rect16 _objRect;
|
||||
bool _deathFlag;
|
||||
|
||||
private:
|
||||
void setContainerSprite();
|
||||
|
||||
public:
|
||||
|
||||
TangibleContainerWindow(ContainerNode &nd,
|
||||
const ContainerAppearanceDef &app);
|
||||
~TangibleContainerWindow();
|
||||
|
||||
void drawClipped(gPort &port, const Point16 &offset, const Rect16 &clip);
|
||||
|
||||
// this sets the mass and bulk gauges for physical containers
|
||||
void massBulkUpdate();
|
||||
};
|
||||
|
||||
class IntangibleContainerWindow : public ScrollableContainerWindow {
|
||||
protected:
|
||||
friend void setMindContainer(int index, IntangibleContainerWindow &cw);
|
||||
private:
|
||||
GfxMultCompButton *_mindSelectorCompButton;
|
||||
|
||||
public:
|
||||
|
||||
IntangibleContainerWindow(ContainerNode &nd, const ContainerAppearanceDef &app);
|
||||
};
|
||||
|
||||
class EnchantmentContainerWindow : public ContainerWindow {
|
||||
protected:
|
||||
GfxCompButton *_scrollCompButton;
|
||||
|
||||
public:
|
||||
EnchantmentContainerWindow(ContainerNode &nd,
|
||||
const ContainerAppearanceDef &app);
|
||||
};
|
||||
|
||||
/* ===================================================================== *
|
||||
ContainerAppearanceDef: A record listing container appearance info
|
||||
* ===================================================================== */
|
||||
|
||||
struct ContainerAppearanceDef {
|
||||
StaticRect defaultWindowPos; // default position of window
|
||||
StaticRect viewRect; // position of view within window
|
||||
StaticRect closeRect, // position of close button
|
||||
scrollRect, // position of scrolling button
|
||||
iconRect, // position of container icon
|
||||
massRect; // position of mass & bulk indicator
|
||||
|
||||
hResID closeResID[2], // resource ID's for close box
|
||||
scrollResID[2]; // resource ID's for scroll indicator
|
||||
|
||||
StaticPoint16 iconOrigin,
|
||||
iconSpacing;
|
||||
uint16 rows,
|
||||
cols,
|
||||
totRows;
|
||||
};
|
||||
|
||||
/* ===================================================================== *
|
||||
ContainerNode: records the fact that a container was open for a
|
||||
specific player
|
||||
* ===================================================================== */
|
||||
|
||||
// ContainerNode records the fact that a container was opened for a
|
||||
// specific player
|
||||
|
||||
// REM: What about the ordering of windows?
|
||||
|
||||
class ContainerNode {
|
||||
|
||||
friend class ContainerManager;
|
||||
friend class ContainerView;
|
||||
friend class ContainerWindow;
|
||||
|
||||
public:
|
||||
enum ContainerNodeOwnerType {
|
||||
kReadyType = 0, // This is a player ready container
|
||||
kDeadType, // The "dead" container
|
||||
kMentalType, // A player's mental container
|
||||
kPhysicalType, // Physical container
|
||||
kEnchantType // Enchantment container
|
||||
};
|
||||
|
||||
enum ContainerNodeOwners {
|
||||
kNobody = 255 // owner = 255 means it's on the ground
|
||||
};
|
||||
|
||||
enum containerAction {
|
||||
kActionUpdate = (1 << 0), // Refresh this window
|
||||
kActionDelete = (1 << 1), // Delete this window
|
||||
kActionHide = (1 << 2), // Refresh this window
|
||||
kActionShow = (1 << 3) // Refresh this window
|
||||
};
|
||||
|
||||
private:
|
||||
ObjectID _object; // Object being viewed
|
||||
uint8 _type; // type of container
|
||||
uint8 _owner; // which brother owns this container
|
||||
Rect16 _position; // position of window
|
||||
ContainerWindow *_window; // window, which may be NULL if hidden.
|
||||
uint8 _action; // What action to take on container
|
||||
public:
|
||||
uint8 _mindType; // mindContainer type
|
||||
|
||||
private:
|
||||
// Nested structure used to archive ContainerNodes
|
||||
struct Archive {
|
||||
ObjectID object;
|
||||
uint8 type;
|
||||
uint8 owner;
|
||||
Rect16 position;
|
||||
uint8 mindType;
|
||||
bool shown;
|
||||
};
|
||||
|
||||
public:
|
||||
ContainerNode() {
|
||||
_object = 0;
|
||||
_type = 0;
|
||||
_owner = 0;
|
||||
_window = nullptr;
|
||||
_action = 0;
|
||||
_mindType = 0;
|
||||
}
|
||||
ContainerNode(ContainerManager &cl, ObjectID id, int type);
|
||||
~ContainerNode();
|
||||
|
||||
static int32 archiveSize() {
|
||||
return sizeof(Archive);
|
||||
}
|
||||
|
||||
void read(Common::InSaveFile *in);
|
||||
void write(Common::MemoryWriteStreamDynamic *out);
|
||||
|
||||
// Hide or show this container window.
|
||||
void hide();
|
||||
void show();
|
||||
void update(); // Update container associated with this node
|
||||
|
||||
// Set for lazy deletion
|
||||
void markForDelete() {
|
||||
_action |= kActionDelete;
|
||||
}
|
||||
void markForShow() {
|
||||
_action |= kActionShow;
|
||||
_action &= ~kActionHide;
|
||||
}
|
||||
void markForHide() {
|
||||
_action |= kActionHide;
|
||||
_action &= ~kActionShow;
|
||||
}
|
||||
void markForUpdate() {
|
||||
_action |= kActionUpdate;
|
||||
}
|
||||
|
||||
// Find the address of the window and/or view
|
||||
ContainerWindow *getWindow();
|
||||
ContainerView *getView();
|
||||
|
||||
// Access functions
|
||||
uint8 getType() {
|
||||
return _type;
|
||||
}
|
||||
uint8 getOwnerIndex() {
|
||||
return _owner;
|
||||
}
|
||||
ObjectID getObject() {
|
||||
return _object;
|
||||
}
|
||||
Rect16 &getPosition() {
|
||||
return _position;
|
||||
}
|
||||
void setObject(ObjectID id) {
|
||||
_object = id;
|
||||
}
|
||||
|
||||
// returns true if the object represented by the container can be
|
||||
// accessed by the player.
|
||||
bool isAccessable(ObjectID enactor);
|
||||
|
||||
void changeOwner(int16 newOwner);
|
||||
};
|
||||
|
||||
// A list of container nodes
|
||||
|
||||
class ContainerManager {
|
||||
public:
|
||||
Common::List<ContainerNode *> _list;
|
||||
|
||||
enum {
|
||||
kBufSize = 60,
|
||||
};
|
||||
|
||||
// used to ignore doubleClick when doubleClick == singleClick
|
||||
bool _alreadyDone;
|
||||
|
||||
// this will be used to determine if the cursor has been
|
||||
// held over an object long enough to qualify for the hint to be displayed
|
||||
bool _objTextAlarm;
|
||||
|
||||
// determines if the cursor is in *A* container view
|
||||
bool _mouseInView;
|
||||
|
||||
ObjectID _lastPickedObjectID;
|
||||
|
||||
// number of items to move for merged objects
|
||||
uint16 _numPicked;
|
||||
|
||||
int16 _amountIndY;
|
||||
|
||||
// this will be used to hold a value of uint16 plus a -1 as a flag
|
||||
int32 _lastPickedObjectQuantity;
|
||||
|
||||
int32 _amountAccumulator;
|
||||
|
||||
// merged object currently being gotten
|
||||
GameObject *_objToGet;
|
||||
|
||||
// selector image pointer
|
||||
void *_selImage;
|
||||
|
||||
// buffer for the mouse text
|
||||
char _mouseText[kBufSize];
|
||||
|
||||
ContainerManager() {
|
||||
_alreadyDone = _objTextAlarm = _mouseInView = false;
|
||||
_lastPickedObjectID = Nothing;
|
||||
_numPicked = 1;
|
||||
_amountIndY = -1;
|
||||
_lastPickedObjectQuantity = - 1;
|
||||
_amountAccumulator = 0;
|
||||
_objToGet = nullptr;
|
||||
_selImage = nullptr;
|
||||
memset(_mouseText, 0, sizeof(_mouseText));
|
||||
}
|
||||
|
||||
void add(ContainerNode *cn) {
|
||||
_list.push_front(cn);
|
||||
}
|
||||
|
||||
void remove(ContainerNode *cn) {
|
||||
_list.remove(cn);
|
||||
}
|
||||
|
||||
void moveToFront(ContainerNode *cn) {
|
||||
remove(cn);
|
||||
add(cn);
|
||||
}
|
||||
|
||||
ContainerNode *find(ObjectID id);
|
||||
ContainerNode *find(ObjectID id, int16 type);
|
||||
|
||||
// Set which player is viewing the container windows.
|
||||
void setPlayerNum(PlayerActorID playerNum);
|
||||
void doDeferredActions();
|
||||
void setUpdate(ObjectID id);
|
||||
};
|
||||
|
||||
ContainerNode *CreateContainerNode(ObjectID id, bool open = true, int16 mindType = 0);
|
||||
ContainerNode *CreateReadyContainerNode(PlayerActorID player);
|
||||
ContainerNode *OpenMindContainer(PlayerActorID player, int16 open, int16 type);
|
||||
|
||||
/* ===================================================================== *
|
||||
Exports
|
||||
* ===================================================================== */
|
||||
|
||||
void initContainers();
|
||||
void cleanupContainers();
|
||||
|
||||
void initContainerNodes();
|
||||
void saveContainerNodes(Common::OutSaveFile *outS);
|
||||
void loadContainerNodes(Common::InSaveFile *in);
|
||||
void cleanupContainerNodes();
|
||||
|
||||
extern void updateContainerWindows();
|
||||
|
||||
extern APPFUNC(cmdCloseButtonFunc);
|
||||
extern APPFUNC(cmdMindContainerFunc);
|
||||
extern APPFUNC(cmdScrollFunc);
|
||||
|
||||
} // end of namespace Saga2
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user