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