1 /* Copyright (C) 2013-2014 Michal Brzozowski (rusolis@poczta.fm)
2 
3    This file is part of KeeperRL.
4 
5    KeeperRL is free software; you can redistribute it and/or modify it under the terms of the
6    GNU General Public License as published by the Free Software Foundation; either version 2
7    of the License, or (at your option) any later version.
8 
9    KeeperRL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10    even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License along with this program.
14    If not, see http://www.gnu.org/licenses/ . */
15 
16 #pragma once
17 
18 #include "util.h"
19 #include "gui_elem.h"
20 #include "view_id.h"
21 #include "unique_entity.h"
22 #include "view_index.h"
23 #include "entity_map.h"
24 #include "view_object.h"
25 
26 class MapMemory;
27 class MapLayout;
28 class Renderer;
29 class CreatureView;
30 class Clock;
31 class Creature;
32 class Options;
33 class TutorialInfo;
34 
35 class MapGui : public GuiElem {
36   public:
37   struct Callbacks {
38     function<void(Vec2)> continuousLeftClickFun;
39     function<void(Vec2)> leftClickFun;
40     function<void(Vec2)> rightClickFun;
41     function<void(UniqueEntity<Creature>::Id)> creatureClickFun;
42     function<void()> refreshFun;
43     function<void(UniqueEntity<Creature>::Id, ViewId, Vec2)> creatureDragFun;
44     function<void(UniqueEntity<Creature>::Id, Vec2)> creatureDroppedFun;
45     function<void(TeamId, Vec2)> teamDroppedFun;
46   };
47   MapGui(Callbacks, Clock*, Options*, GuiFactory*);
48 
49   virtual void render(Renderer&) override;
50   virtual bool onLeftClick(Vec2) override;
51   virtual bool onRightClick(Vec2) override;
52   virtual bool onMouseMove(Vec2) override;
53   virtual void onMouseGone() override;
54   virtual void onMouseRelease(Vec2) override;
55   virtual bool onKeyPressed2(SDL::SDL_Keysym) override;
56 
57   void updateObjects(CreatureView*, MapLayout*, bool smoothMovement, bool mouseUI, const optional<TutorialInfo>&);
58   void setSpriteMode(bool);
59   optional<Vec2> getHighlightedTile(Renderer& renderer);
60   void addAnimation(PAnimation animation, Vec2 position);
61   void setCenter(double x, double y);
62   void setCenter(Vec2 pos);
63   void clearCenter();
64   void resetScrolling();
65   bool isCentered() const;
66   Vec2 getScreenPos() const;
67   optional<Vec2> projectOnMap(Vec2 screenCoord);
68   void highlightTeam(const vector<UniqueEntity<Creature>::Id>&);
69   void unhighlightTeam(const vector<UniqueEntity<Creature>::Id>&);
70   void setButtonViewId(ViewId);
71   void clearButtonViewId();
72   bool highlightMorale = true;
73   bool highlightEnemies = true;
74   bool displayAllHealthBars = true;
75   bool hideFullHealthBars = true;
76   bool colorWoundedRed = false;
77   struct HighlightedInfo {
78     optional<Vec2> creaturePos;
79     optional<Vec2> tilePos;
80     optional<ViewObject> object;
81   };
82   const HighlightedInfo& getLastHighlighted();
83   bool isCreatureHighlighted(UniqueEntity<Creature>::Id);
84 
85   private:
86   void updateObject(Vec2, CreatureView*, milliseconds currentTime);
87   void drawObjectAbs(Renderer&, Vec2 pos, const ViewObject&, Vec2 size, Vec2 movement, Vec2 tilePos, milliseconds currentTimeReal);
88   void drawCreatureHighlights(Renderer&, const ViewObject&, Vec2 pos, Vec2 sz, milliseconds currentTimeReal);
89   void drawCreatureHighlight(Renderer&, Vec2 pos, Vec2 size, Color);
90   void drawSquareHighlight(Renderer&, Vec2 pos, Vec2 size);
91   void considerRedrawingSquareHighlight(Renderer&, milliseconds currentTimeReal, Vec2 pos, Vec2 size);
92  // void drawFloorBorders(Renderer& r, DirSet borders, int x, int y);
93   void drawFoWSprite(Renderer&, Vec2 pos, Vec2 size, DirSet dirs);
94   void renderExtraBorders(Renderer&, milliseconds currentTimeReal);
95   void renderHighlights(Renderer&, Vec2 size, milliseconds currentTimeReal, bool lowHighlights);
96   optional<Vec2> getMousePos();
97   void softScroll(double x, double y);
98   void setSoftCenter(Vec2);
99   void setSoftCenter(double x, double y);
100   HighlightedInfo lastHighlighted;
101   void renderMapObjects(Renderer&, Vec2 size, milliseconds currentTimeReal);
102   HighlightedInfo getHighlightedInfo(Vec2 size, milliseconds currentTimeReal);
103   void renderAnimations(Renderer&, milliseconds currentTimeReal);
104 
105   Vec2 getMovementOffset(const ViewObject&, Vec2 size, double time, milliseconds curTimeReal, bool verticalMovement);
106   Vec2 projectOnScreen(Vec2 wpos);
107   bool considerCreatureClick(Vec2 mousePos);
108   struct CreatureInfo {
109     UniqueEntity<Creature>::Id id;
110     ViewId viewId;
111   };
112   optional<CreatureInfo> getCreature(Vec2 mousePos);
113   void considerContinuousLeftClick(Vec2 mousePos);
114   MapLayout* layout;
115   Table<optional<ViewIndex>> objects;
116   bool spriteMode;
117   Rectangle levelBounds = Rectangle(1, 1);
118   Callbacks callbacks;
119   optional<milliseconds> lastScrollUpdate;
120   Clock* clock;
121   optional<Vec2> mouseHeldPos;
122   optional<CreatureInfo> draggedCandidate;
123   optional<Vec2> lastMapLeftClick;
124   struct AnimationInfo {
125     PAnimation animation;
126     Vec2 position;
127   };
128   vector<AnimationInfo> animations;
129   Options* options;
130   DirtyTable<bool> fogOfWar;
131   DirtyTable<vector<ViewId>> extraBorderPos;
132   bool isFoW(Vec2 pos) const;
133   struct Coords {
134     double x;
135     double y;
136     COMPARE_ALL(x, y)
137   } mouseOffset, center;
138   WConstLevel previousLevel = nullptr;
139   const CreatureView* previousView = nullptr;
140   Table<optional<milliseconds>> lastSquareUpdate;
141   optional<Coords> softCenter;
142   Vec2 lastMousePos;
143   optional<Vec2> lastMouseMove;
144   bool isScrollingNow = false;
145   double currentTimeGame = 0;
146   struct ScreenMovement {
147     milliseconds startTimeReal;
148     milliseconds endTimeReal;
149     double startTimeGame;
150   };
151   optional<ScreenMovement> screenMovement;
152   Table<EnumSet<ViewId>> connectionMap;
153   bool keyScrolling = false;
154   bool mouseUI = false;
155   bool lockedView = true;
156   optional<milliseconds> lastRightClick;
157   EntityMap<Creature, int> teamHighlight;
158   optional<ViewId> buttonViewId;
159   set<Vec2> shadowed;
160   bool isRenderedHighlight(const ViewIndex&, HighlightType);
161   bool isRenderedHighlightLow(const ViewIndex&, HighlightType);
162   optional<ViewId> getHighlightedFurniture();
163   Color getHighlightColor(const ViewIndex&, HighlightType);
164   void renderHighlight(Renderer& renderer, Vec2 pos, Vec2 size, const ViewIndex& index, HighlightType highlight);
165   void renderTexturedHighlight(Renderer&, Vec2 pos, Vec2 size, Color);
166   void processScrolling(milliseconds);
167   void considerScrollingToCreature();
168   GuiFactory* guiFactory;
169   optional<UniqueEntity<Creature>::Id> getDraggedCreature() const;
170   void setDraggedCreature(UniqueEntity<Creature>::Id, ViewId, Vec2 origin);
171   vector<Vec2> tutorialHighlightLow;
172   vector<Vec2> tutorialHighlightHigh;
173   void drawHealthBar(Renderer&, Vec2 pos, Vec2 size, double health);
174   double lastEndTimeGame = -1000;
175   double getDistanceToEdgeRatio(Vec2);
176   struct CenteredCreatureInfo {
177     Vec2 pos;
178     bool softScroll;
179   };
180   optional<CenteredCreatureInfo> centeredCreaturePosition;
181   DirSet getConnectionSet(Vec2 tilePos, ViewId);
182 };
183