1 /*
2  *  This file is part of Dune Legacy.
3  *
4  *  Dune Legacy is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Dune Legacy 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 Dune Legacy.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <GameInterface.h>
19 
20 #include <globals.h>
21 
22 #include <FileClasses/GFXManager.h>
23 #include <House.h>
24 #include <Game.h>
25 
26 #include <ObjectBase.h>
27 #include <GUI/ObjectInterfaces/ObjectInterface.h>
28 #include <GUI/ObjectInterfaces/MultiUnitInterface.h>
29 
30 #include <misc/draw_util.h>
31 
32 #include <SDL.h>
33 
GameInterface()34 GameInterface::GameInterface() : Window(0,0,0,0) {
35     pObjectContainer = nullptr;
36     objectID = NONE_ID;
37 
38     setTransparentBackground(true);
39 
40     setCurrentPosition(0,0,getRendererWidth(),getRendererHeight());
41 
42     setWindowWidget(&windowWidget);
43 
44     // top bar
45     SDL_Texture* pTopBarTex = pGFXManager->getUIGraphic(UI_TopBar, pLocalHouse->getHouseID());
46     topBar.setTexture(pTopBarTex,false);
47     windowWidget.addWidget(&topBar,Point(0,0),Point(getWidth(pTopBarTex),getHeight(pTopBarTex) - 12));
48 
49     // side bar
50     SDL_Texture* pSideBarTex = pGFXManager->getUIGraphic(UI_SideBar, pLocalHouse->getHouseID());
51     sideBar.setTexture(pSideBarTex,false);
52     SDL_Rect dest = calcAlignedDrawingRect(pSideBarTex, HAlign::Right, VAlign::Top);
53     windowWidget.addWidget(&sideBar, dest);
54 
55     // add buttons
56     windowWidget.addWidget(&topBarHBox,Point(5,5),
57                             Point(getRendererWidth() - sideBar.getSize().x, topBar.getSize().y - 10));
58 
59     topBarHBox.addWidget(&newsticker);
60 
61     topBarHBox.addWidget(Spacer::create());
62 
63     optionsButton.setTextures(  pGFXManager->getUIGraphic(UI_Options, pLocalHouse->getHouseID()), false,
64                                 pGFXManager->getUIGraphic(UI_Options_Pressed, pLocalHouse->getHouseID()), false);
65     optionsButton.setOnClick(std::bind(&Game::onOptions, currentGame));
66     topBarHBox.addWidget(&optionsButton);
67 
68     topBarHBox.addWidget(Spacer::create());
69 
70     mentatButton.setTextures(   pGFXManager->getUIGraphic(UI_Mentat, pLocalHouse->getHouseID()), false,
71                                 pGFXManager->getUIGraphic(UI_Mentat_Pressed, pLocalHouse->getHouseID()), false);
72     mentatButton.setOnClick(std::bind(&Game::onMentat, currentGame));
73     topBarHBox.addWidget(&mentatButton);
74 
75     topBarHBox.addWidget(Spacer::create());
76 
77     // add radar
78     windowWidget.addWidget(&radarView,Point(getRendererWidth()-sideBar.getSize().x+SIDEBAR_COLUMN_WIDTH, 0),radarView.getMinimumSize());
79     radarView.setOnRadarClick(std::bind(&Game::onRadarClick, currentGame, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
80 
81     // add chat manager
82     windowWidget.addWidget(&chatManager, Point(20, 60), Point(getRendererWidth() - sideBar.getSize().x, 360));
83 }
84 
~GameInterface()85 GameInterface::~GameInterface() {
86     removeOldContainer();
87 }
88 
draw(Point position)89 void GameInterface::draw(Point position) {
90     Window::draw(position);
91 
92     // draw Power Indicator and Spice indicator
93 
94     SDL_Rect powerIndicatorPos = {  getRendererWidth() - sideBar.getSize().x + 14, 146, 4, getRendererHeight() - 146 - 2 };
95     renderFillRect(renderer, &powerIndicatorPos, COLOR_BLACK);
96 
97     SDL_Rect spiceIndicatorPos = {  getRendererWidth() - sideBar.getSize().x + 20, 146, 4, getRendererHeight() - 146 - 2 };
98     renderFillRect(renderer, &spiceIndicatorPos, COLOR_BLACK);
99 
100     int xCount = 0, yCount = 0;
101     int yCount2 = 0;
102 
103     //draw power level indicator
104     if (pLocalHouse->getPowerRequirement() == 0)    {
105         if (pLocalHouse->getProducedPower() > 0) {
106             yCount2 = powerIndicatorPos.h + 1;
107         } else {
108             yCount2 = powerIndicatorPos.h/2;
109         }
110     } else {
111         yCount2 = lround((double)pLocalHouse->getProducedPower()/(double)pLocalHouse->getPowerRequirement()*(double)(powerIndicatorPos.h/2));
112     }
113 
114     if (yCount2 > powerIndicatorPos.h + 1) {
115         yCount2 = powerIndicatorPos.h + 1;
116     }
117 
118     setRenderDrawColor(renderer, COLOR_GREEN);
119     for (yCount = 0; yCount < yCount2; yCount++) {
120         for (xCount = 1; xCount < powerIndicatorPos.w - 1; xCount++) {
121             if(((yCount/2) % 3) != 0) {
122                 SDL_RenderDrawPoint(renderer, xCount + powerIndicatorPos.x, powerIndicatorPos.y + powerIndicatorPos.h - yCount);
123             }
124         }
125     }
126 
127     //draw spice level indicator
128     if (pLocalHouse->getCapacity() == 0) {
129         yCount2 = 0;
130     } else {
131         yCount2 = lround((pLocalHouse->getStoredCredits()/pLocalHouse->getCapacity())*spiceIndicatorPos.h);
132     }
133 
134     if (yCount2 > spiceIndicatorPos.h + 1) {
135         yCount2 = spiceIndicatorPos.h + 1;
136     }
137 
138     setRenderDrawColor(renderer, COLOR_ORANGE);
139     for (yCount = 0; yCount < yCount2; yCount++) {
140         for (xCount = 1; xCount < spiceIndicatorPos.w - 1; xCount++) {
141             if(((yCount/2) % 3) != 0) {
142                 SDL_RenderDrawPoint(renderer, xCount + spiceIndicatorPos.x, spiceIndicatorPos.y + spiceIndicatorPos.h - yCount);
143             }
144         }
145     }
146 
147     //draw credits
148     char CreditsBuffer[10];
149     int credits = pLocalHouse->getCredits();
150     sprintf(CreditsBuffer, "%d", (credits < 0) ? 0 : credits);
151     int NumDigits = strlen(CreditsBuffer);
152     SDL_Texture* digitsTex = pGFXManager->getUIGraphic(UI_CreditsDigits);
153 
154     for(int i=NumDigits-1; i>=0; i--) {
155         SDL_Rect source = calcSpriteSourceRect(digitsTex, CreditsBuffer[i] - '0', 10);
156         SDL_Rect dest = calcSpriteDrawingRect(digitsTex, getRendererWidth() - sideBar.getSize().x + 49 + (6 - NumDigits + i)*10, 135, 10);
157         SDL_RenderCopy(renderer, digitsTex, &source, &dest);
158     }
159 }
160 
updateObjectInterface()161 void GameInterface::updateObjectInterface() {
162     if(currentGame->getSelectedList().size() == 1) {
163         ObjectBase* pObject = currentGame->getObjectManager().getObject( *(currentGame->getSelectedList().begin()));
164         Uint32 newObjectID = pObject->getObjectID();
165 
166         if(newObjectID != objectID) {
167             removeOldContainer();
168 
169             pObjectContainer = pObject->getInterfaceContainer();
170 
171             if(pObjectContainer != nullptr) {
172                 objectID = newObjectID;
173 
174                 windowWidget.addWidget(pObjectContainer,
175                                         Point(getRendererWidth() - sideBar.getSize().x + 24, 146),
176                                         Point(sideBar.getSize().x - 25,getRendererHeight() - 148));
177 
178             }
179 
180         } else {
181             if(pObjectContainer->update() == false) {
182                 removeOldContainer();
183             }
184         }
185     } else if(currentGame->getSelectedList().size() > 1) {
186 
187         if((pObjectContainer == nullptr) || (objectID != NONE_ID)) {
188             // either there was nothing selected before or exactly one unit
189 
190             if(pObjectContainer != nullptr) {
191                 removeOldContainer();
192             }
193 
194             pObjectContainer = MultiUnitInterface::create();
195 
196             windowWidget.addWidget(pObjectContainer,
197                                     Point(getRendererWidth() - sideBar.getSize().x + 24, 146),
198                                     Point(sideBar.getSize().x - 25,getRendererHeight() - 148));
199         } else {
200             if(pObjectContainer->update() == false) {
201                 removeOldContainer();
202             }
203         }
204     } else {
205         removeOldContainer();
206     }
207 }
208 
removeOldContainer()209 void GameInterface::removeOldContainer() {
210     if(pObjectContainer != nullptr) {
211         delete pObjectContainer;
212         pObjectContainer = nullptr;
213         objectID = NONE_ID;
214     }
215 }
216