1 /* GemRB - Infinity Engine Emulator
2  * Copyright (C) 2003 The GemRB Project
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  */
19 
20 /**
21  * @file GameControl.h
22  * Declares GameControl widget which is responsible for displaying areas,
23  * interacting with PCs, NPCs and the rest of the game world.
24  * @author The GemRB Project
25  */
26 
27 #ifndef GAMECONTROL_H
28 #define GAMECONTROL_H
29 
30 #include "GUI/Control.h"
31 
32 #include "exports.h"
33 
34 #include "Dialog.h"
35 #include "Map.h"
36 
37 #include <vector>
38 
39 namespace GemRB {
40 
41 class GameControl;
42 class Window;
43 class DialogHandler;
44 
45 //dialog flags
46 #define DF_IN_DIALOG      1
47 #define DF_TALKCOUNT      2
48 #define DF_UNBREAKABLE    4
49 #define DF_FREEZE_SCRIPTS 8
50 #define DF_INTERACT       16
51 #define DF_IN_CONTAINER   32
52 #define DF_OPENCONTINUEWINDOW 64
53 #define DF_OPENENDWINDOW 128
54 #define DF_POSTPONE_SCRIPTS 256
55 
56 //screen flags
57 // !!! Keep these synchronized with GUIDefines.py !!!
58 #define SF_CENTERONACTOR 1  //
59 #define SF_ALWAYSCENTER  2
60 #define SF_CUTSCENE      4 //don't push new actions onto the action queue
61 
62 // target modes and types
63 // !!! Keep these synchronized with GUIDefines.py !!!
64 #define TARGET_MODE_NONE    0
65 #define TARGET_MODE_TALK    1
66 #define TARGET_MODE_ATTACK  2
67 #define TARGET_MODE_CAST    3
68 #define TARGET_MODE_DEFEND  4
69 #define TARGET_MODE_PICK    5
70 
71 /**
72  * @class GameControl
73  * Widget displaying areas, where most of the game 'happens'.
74  * It allows for interacting with PCs, NPCs and the rest of the world.
75  * It's also a very core part of GemRB, as some processes are driven from it.
76  * It's always assigned Control index 0.
77  */
78 
79 class GEM_EXPORT GameControl : public View {
80 private:
81 	ieDword lastActorID;
82 	ieDword trackerID;
83 	ieDword distance;  //tracking distance
84 	std::vector<Actor*> highlighted;
85 
86 	bool isSelectionRect;
87 	bool isFormationRotation;
88 
89 	// mouse coordinates represented in game coordinates
90 	Point gameClickPoint;
91 	Point screenMousePos;
92 	Point vpOrigin;
93 	bool updateVPTimer;
94 	double formationBaseAngle = 0.0;
95 
96 	// currently selected targeting type, such as talk, attack, cast, ...
97 	// private to enforce proper cursor changes
98 	int target_mode;
99 	int lastCursor;
100 	short moveX, moveY;
101 	int numScrollCursor;
102 	PathNode* drawPath;
103 	unsigned int ScreenFlags;
104 	unsigned int DialogueFlags;
105 	String* DisplayText;
106 	unsigned int DisplayTextTime;
107 	bool AlwaysRun;
108 	bool ShouldTriggerWorldMap(const Actor *pc) const;
109 	void ExecuteMovement(Actor *actor, unsigned short x, unsigned short y, bool createWaypoint);
110 	Actor *user; //the user of item or spell
111 
112 	Door* overDoor;
113 	Container* overContainer;
114 	InfoPoint* overInfoPoint;
115 
116 	EventMgr::TapMonitorId eventMonitors[2];
117 
118 public:
119 	static uint32_t DebugFlags;
120 
121 	DialogHandler *dialoghandler;
122 	//the name of the spell to cast
123 	ieResRef spellName;
124 	//using spell or item
125 	int spellOrItem; // -1 = item, otherwise the spell type
126 	//the user of spell or item
127 	Actor *spellUser;
128 	int spellSlot, spellIndex; //or inventorySlot/itemHeader
129 	int spellCount; //multiple targeting
130 	// allow targeting allies, enemies and/or neutrals (bitmask)
131 	int target_types;
132 
133 private:
134 	using FormationPoints = std::vector<Point>;
135 	Map* CurrentArea() const;
136 
137 	Region SelectionRect() const;
138 	void ReadFormations() const;
139 	/** Draws an arrow on the edge of the screen based on the point (points at offscreen actors) */
140 	void DrawArrowMarker(Point p, const Color& color) const;
141 	void DrawFormation(const std::vector<Actor*>& actors, const Point& formationPoint, double angle) const;
142 
143 	Point GetFormationPoint(const Point& origin, size_t pos, double angle, const FormationPoints& exclude = FormationPoints()) const;
144 	FormationPoints GetFormationPoints(const Point& origin, const std::vector<Actor*>& actors, double angle) const;
145 
146 	void Scroll(const Point& amt);
147 
148 	//containers
149 	int GetCursorOverContainer(const Container *overContainer) const;
150 	void HandleContainer(Container *container, Actor *actor);
151 	//doors
152 	int GetCursorOverDoor(const Door *overDoor) const;
153 	void HandleDoor(Door *door, Actor *actor);
154 
155 	void UpdateCursor();
156 	bool IsDisabledCursor() const override;
157 
158 	void PerformSelectedAction(const Point& p);
159 	void CommandSelectedMovement(const Point& p, bool append = false, bool tryToRun = false);
160 
161 	//infopoints
162 	int GetCursorOverInfoPoint(const InfoPoint *overInfoPoint) const;
163 	bool OnGlobalMouseMove(const Event&);
164 
165 	/** Draws the Control on the Output Display */
166 	void DrawSelf(Region drawFrame, const Region& clip) override;
167 	void WillDraw(const Region& /*drawFrame*/, const Region& /*clip*/) override;
168 
CanLockFocus()169 	bool CanLockFocus() const override { return true; };
170 	void FlagsChanged(unsigned int /*oldflags*/) override;
171 
172 public:
173 	GameControl(const Region& frame);
174 	~GameControl(void) override;
175 
176 	// GameControl always needs to redraw unless we arent in a game (disabled)
IsAnimated()177 	bool IsAnimated() const override { return !IsDisabled(); }
178 	void DrawTargetReticle(int size, const Color& color, const Point& p) const;
179 	/** Draws the target reticle for Actor movement. */
180 	void DrawTargetReticle(const Movable* target, const Point& point) const;
181 	/** Sets multiple quicksaves flag*/
182 	//static void MultipleQuickSaves(int arg);
183 	void SetTracker(Actor *actor, ieDword dist);
184 
185 	void DrawTooltip(const Point& p) const;
186 	String TooltipText() const override;
187 
188 	void SetTargetMode(int mode);
GetTargetMode()189 	int GetTargetMode() const { return target_mode; }
190 	bool SetScreenFlags(unsigned int value, int mode);
191 	void SetDialogueFlags(unsigned int value, int mode);
GetScreenFlags()192 	int GetScreenFlags() const { return ScreenFlags; }
GetDialogueFlags()193 	int GetDialogueFlags() const { return DialogueFlags; }
194 	void SetDisplayText(String* text, unsigned int time);
195 	void SetDisplayText(ieStrRef text, unsigned int time);
196 	void ClearMouseState();
197 	Point GameMousePos() const;
198 
199 	void MoveViewportUnlockedTo(Point, bool center);
200 	bool MoveViewportTo(Point, bool center, int speed = 0);
201 	Region Viewport() const;
202 
203 	/** Selects one or all PC */
204 	void SelectActor(int whom, int type = -1);
205 	void SetCutSceneMode(bool active);
206 	void TryToAttack(Actor *source, const Actor *target) const;
207 	void TryToCast(Actor *source, const Point &p);
208 	void TryToCast(Actor *source, const Actor *target);
209 	void TryToDefend(Actor *source, const Actor *target) const;
210 	void TryToTalk(Actor *source, const Actor *target) const;
211 	void TryToPick(Actor *source, const Scriptable *tgt) const;
212 	void TryToDisarm(Actor *source, const InfoPoint *tgt) const;
213 	void PerformActionOn(Actor *actor);
214 	void ResetTargetMode();
215 	void UpdateTargetMode();
216 
217 	// returns the default cursor fitting the targeting mode
218 	Holder<Sprite2D> GetTargetActionCursor() const;
219 	Holder<Sprite2D> Cursor() const override;
220 
221 	bool HandleActiveRegion(InfoPoint *trap, Actor *actor, const Point& p);
222 
223 	void MakeSelection(bool extend = false);
224 	void InitFormation(const Point &);
225 	Point GetFormationOffset(ieDword formation, ieDword pos) const;
226 	/** calls MoveToPoint or RunToPoint */
227 	void CreateMovement(Actor *actor, const Point &p, bool append = true, bool tryToRun = false) const;
228 	/** checks if the actor should be running instead of walking */
229 	bool CanRun(const Actor *actor) const;
230 	bool ShouldRun(const Actor *actor) const;
231 	/** Displays a string over an object */
232 	void DisplayString(const Scriptable* target) const;
233 	/** Displays a string on screen */
234 	void DisplayString(const Point &p, const char *Text);
235 	Actor *GetLastActor();
236 	void SetLastActor(Actor* lastActor);
237 	/** changes map to the current PC */
238 	void ChangeMap(Actor *pc, bool forced);
239 	/** Sets up targeting with spells or items */
240 	void SetupItemUse(int slot, int header, Actor *actor, int targettype, int cnt);
241 	/** Page is the spell type + spell level info */
242 	void SetupCasting(ieResRef spellname, int type, int level, int slot, Actor *actor, int targettype, int cnt);
243 	void ToggleAlwaysRun();
244 
245 protected:
246 	//Events
247 	/** Key Press Event */
248 	bool OnKeyPress(const KeyboardEvent& Key, unsigned short Mod) override;
249 	/** Key Release Event */
250 	bool OnKeyRelease(const KeyboardEvent& Key, unsigned short Mod) override;
251 	/** Mouse Over Event */
252 	bool OnMouseOver(const MouseEvent&) override;
253 	bool OnMouseDrag(const MouseEvent& /*me*/) override;
254 
255 	bool OnTouchDown(const TouchEvent& /*te*/, unsigned short /*Mod*/) override;
256 	bool OnTouchUp(const TouchEvent& /*te*/, unsigned short /*Mod*/) override;
257 	bool OnTouchGesture(const GestureEvent& gesture) override;
258 
259 	/** Currently only deals with the GEM_TAB exception */
260 	bool DispatchEvent(const Event& event) const;
261 
262 	/** Mouse Button Down */
263 	bool OnMouseDown(const MouseEvent& /*me*/, unsigned short Mod) override;
264 	/** Mouse Button Up */
265 	bool OnMouseUp(const MouseEvent& /*me*/, unsigned short Mod) override;
266 	bool OnMouseWheelScroll(const Point& delta) override;
267 
268 	bool OnControllerButtonDown(const ControllerEvent& ce) override;
269 };
270 
271 }
272 
273 #endif
274