1 /** @file healthwidget.cpp GUI widget for -.
2 *
3 * @authors Copyright © 2005-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4 * @authors Copyright © 2005-2015 Daniel Swanson <danij@dengine.net>
5 *
6 * @par License
7 * GPL: http://www.gnu.org/licenses/gpl.html
8 *
9 * <small>This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. This program is distributed in the hope that it
13 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 * Public License for more details. You should have received a copy of the GNU
16 * General Public License along with this program; if not, write to the Free
17 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA</small>
19 */
20
21 #include "hud/widgets/healthwidget.h"
22
23 #include "g_common.h"
24 #if __JHERETIC__ || __JHEXEN__
25 # include "hu_inventory.h"
26 #endif
27 #include "player.h"
28 #include "p_actor.h"
29
30 using namespace de;
31
guidata_health_t(void (* updateGeometry)(HudWidget * wi),void (* drawer)(HudWidget * wi,Point2Raw const * offset),dint player)32 guidata_health_t::guidata_health_t(void (*updateGeometry) (HudWidget *wi),
33 void (*drawer) (HudWidget *wi, Point2Raw const *offset),
34 dint player)
35 : HudWidget(updateGeometry,
36 drawer,
37 player)
38 {}
39
~guidata_health_t()40 guidata_health_t::~guidata_health_t()
41 {}
42
reset()43 void guidata_health_t::reset()
44 {
45 _value = 1994;
46 }
47
tick(timespan_t)48 void guidata_health_t::tick(timespan_t /*elapsed*/)
49 {
50 if(Pause_IsPaused() || !DD_IsSharpTick()) return;
51
52 player_t const *plr = &::players[player()];
53 _value = plr->health;
54 }
55
HealthWidget_Draw(guidata_health_t * hlth,Point2Raw const * offset)56 void HealthWidget_Draw(guidata_health_t *hlth, Point2Raw const *offset)
57 {
58 #if __JDOOM__
59 # define X_OFFSET ( 0 )
60 # define Y_OFFSET ( 0 )
61 # define TRACKING ( 0 )
62 # define SUFFIX ( "%" )
63 #else
64 # define X_OFFSET (-1 )
65 # define Y_OFFSET (-1 )
66 # define TRACKING ( 1 )
67 # define SUFFIX ( "" )
68 #endif
69
70 DENG2_ASSERT(hlth);
71 dfloat const textOpacity = ::uiRendState->pageAlpha * ::cfg.common.hudColor[3];
72
73 if(hlth->_value == 1994) return;
74
75 if(!::cfg.hudShown[HUD_HEALTH]) return;
76 if(ST_AutomapIsOpen(hlth->player()) && ::cfg.common.automapHudDisplay == 0) return;
77 if(P_MobjIsCamera(::players[hlth->player()].plr->mo) && Get(DD_PLAYBACK)) return;
78
79 auto const valueAsText = String::number(hlth->_value) + SUFFIX;
80
81 DGL_MatrixMode(DGL_MODELVIEW);
82 DGL_PushMatrix();
83 if(offset) DGL_Translatef(offset->x, offset->y, 0);
84 DGL_Scalef(::cfg.common.hudScale, ::cfg.common.hudScale, 1);
85
86 DGL_Enable(DGL_TEXTURE_2D);
87
88 FR_SetFont(hlth->font());
89 FR_SetTracking(TRACKING);
90
91 #if __JHERETIC__
92 // Draw a shadow.
93 FR_SetColorAndAlpha(0, 0, 0, textOpacity * .4f);
94 FR_DrawTextXY(valueAsText.toUtf8().constData(), X_OFFSET + 2, Y_OFFSET + 2);
95 #endif
96
97 FR_SetColorAndAlpha(::cfg.common.hudColor[0], ::cfg.common.hudColor[1], ::cfg.common.hudColor[2], textOpacity);
98 FR_DrawTextXY(valueAsText.toUtf8().constData(), X_OFFSET, Y_OFFSET);
99
100 DGL_Disable(DGL_TEXTURE_2D);
101 DGL_MatrixMode(DGL_MODELVIEW);
102 DGL_PopMatrix();
103
104 #undef SUFFIX
105 #undef TRACKING
106 #undef Y_OFFSET
107 #undef X_OFFSET
108 }
109
SBarHealthWidget_Draw(guidata_health_t * hlth,Point2Raw const * offset)110 void SBarHealthWidget_Draw(guidata_health_t *hlth, Point2Raw const *offset)
111 {
112 #if __JDOOM__
113 # define X_OFFSET ( 90 )
114 # define Y_OFFSET ( 3 )
115 #elif __JHERETIC__
116 # define X_OFFSET ( 85 )
117 # define Y_OFFSET ( 12 )
118 #elif __JHEXEN__
119 # define X_OFFSET ( 64 )
120 # define Y_OFFSET ( 14 )
121 #else
122 # define X_OFFSET ( 0 )
123 # define Y_OFFSET ( 0 )
124 #endif
125 #if __JHERETIC__
126 # define TRACKING ( 1 )
127 #else
128 # define TRACKING ( 0 )
129 #endif
130 DENG2_ASSERT(hlth);
131
132 Vector2i const origin((-ST_WIDTH / 2 ) + X_OFFSET, (-ST_HEIGHT ) + Y_OFFSET );
133
134 if(hlth->_value == 1994) return;
135
136 dint const activeHud = ST_ActiveHud(hlth->player());
137 dint const yOffset = ST_HEIGHT * (1 - ST_StatusBarShown(hlth->player()));
138 dfloat const textOpacity = (activeHud == 0? 1 : ::uiRendState->pageAlpha * ::cfg.common.statusbarCounterAlpha);
139 //dfloat const iconOpacity = (activeHud == 0? 1 : ::uiRendState->pageAlpha * ::cfg.common.statusbarCounterAlpha);
140
141 #if __JHERETIC__ || __JHEXEN__
142 if(gfw_Rule(deathmatch)) return;
143 if(Hu_InventoryIsOpen(hlth->player())) return;
144 #endif
145
146 #if __JHEXEN__
147 if(ST_AutomapIsOpen(hlth->player())) return;
148 #else
149 if(ST_AutomapIsOpen(hlth->player()) && ::cfg.common.automapHudDisplay == 0) return;
150 #endif
151 if(P_MobjIsCamera(::players[hlth->player()].plr->mo) && Get(DD_PLAYBACK)) return;
152
153 auto const valueAsText = String::number(hlth->_value);
154
155 DGL_MatrixMode(DGL_MODELVIEW);
156 DGL_PushMatrix();
157 if(offset) DGL_Translatef(offset->x, offset->y, 0);
158 DGL_Scalef(::cfg.common.statusbarScale, ::cfg.common.statusbarScale, 1);
159 DGL_Translatef(0, yOffset, 0);
160
161 DGL_Enable(DGL_TEXTURE_2D);
162
163 FR_SetFont(hlth->font());
164 FR_SetTracking(TRACKING);
165 #if __JDOOM__
166 if(::gameMode == doom_chex)
167 {
168 FR_SetColorAndAlpha(::defFontRGB3[0], ::defFontRGB3[1], ::defFontRGB3[2], textOpacity);
169 }
170 else
171 #endif
172 {
173 FR_SetColorAndAlpha(::defFontRGB2[0], ::defFontRGB2[1], ::defFontRGB2[2], textOpacity);
174 }
175 FR_DrawTextXY3(valueAsText.toUtf8().constData(), origin.x, origin.y, ALIGN_TOPRIGHT, DTF_NO_EFFECTS);
176 #if __JDOOM__
177 FR_DrawCharXY('%', origin.x, origin.y);
178 #endif
179
180 DGL_Disable(DGL_TEXTURE_2D);
181 DGL_MatrixMode(DGL_MODELVIEW);
182 DGL_PopMatrix();
183
184 #undef TRACKING
185 #undef Y_OFFSET
186 #undef X_OFFSET
187 }
188
HealthWidget_UpdateGeometry(guidata_health_t * hlth)189 void HealthWidget_UpdateGeometry(guidata_health_t *hlth)
190 {
191 #if __JDOOM__
192 # define TRACKING ( 0 )
193 # define SUFFIX ( "%" )
194 #else
195 # define TRACKING ( 1 )
196 # define SUFFIX ( "" )
197 #endif
198
199 DENG2_ASSERT(hlth);
200 Rect_SetWidthHeight(&hlth->geometry(), 0, 0);
201
202 if(hlth->_value == 1994) return;
203
204 if(!::cfg.hudShown[HUD_HEALTH]) return;
205 if(ST_AutomapIsOpen(hlth->player()) && ::cfg.common.automapHudDisplay == 0) return;
206 if(P_MobjIsCamera(::players[hlth->player()].plr->mo) && Get(DD_PLAYBACK)) return;
207
208 auto const valueAsText = String::number(hlth->_value) + SUFFIX;
209
210 FR_SetFont(hlth->font());
211 FR_SetTracking(TRACKING);
212 Size2Raw textSize; FR_TextSize(&textSize, valueAsText.toUtf8().constData());
213 textSize.width *= ::cfg.common.hudScale;
214 textSize.height *= ::cfg.common.hudScale;
215 Rect_SetWidthHeight(&hlth->geometry(), textSize.width, textSize.height);
216
217 #undef SUFFIX
218 #undef TRACKING
219 }
220
SBarHealthWidget_UpdateGeometry(guidata_health_t * hlth)221 void SBarHealthWidget_UpdateGeometry(guidata_health_t *hlth)
222 {
223 #if __JHERETIC__
224 # define TRACKING ( 1 )
225 #else
226 # define TRACKING ( 0 )
227 #endif
228
229 DENG2_ASSERT(hlth);
230 Rect_SetWidthHeight(&hlth->geometry(), 0, 0);
231
232 if(hlth->_value == 1994) return;
233
234 #if __JHERETIC__ || __JHEXEN__
235 if(gfw_Rule(deathmatch)) return;
236 if(Hu_InventoryIsOpen(hlth->player())) return;
237 #endif
238
239 #if __JHEXEN__
240 if(ST_AutomapIsOpen(hlth->player())) return;
241 #else
242 if(ST_AutomapIsOpen(hlth->player()) && ::cfg.common.automapHudDisplay == 0) return;
243 #endif
244 if(P_MobjIsCamera(::players[hlth->player()].plr->mo) && Get(DD_PLAYBACK)) return;
245
246 auto const valueAsText = String::number(hlth->_value);
247
248 FR_SetFont(hlth->font());
249 FR_SetTracking(TRACKING);
250 Size2Raw textSize; FR_TextSize(&textSize, valueAsText.toUtf8().constData());
251 #if __JDOOM__
252 textSize.width += FR_CharWidth('%');
253 textSize.height = de::max(textSize.height, FR_CharHeight('%'));
254 #endif
255 Rect_SetWidthHeight(&hlth->geometry(), textSize.width * ::cfg.common.statusbarScale,
256 textSize.height * ::cfg.common.statusbarScale);
257
258 #undef TRACKING
259 }
260