guiHealthTextHud.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. // ----------------------------------------------------------------------------
  23. // A gui control that displays health or energy information. Based upon the
  24. // stock healthBar control but rewritten by M.Hall to display a numerical value.
  25. // ----------------------------------------------------------------------------
  26. #include "platform/platform.h"
  27. #include "gui/core/guiControl.h"
  28. #include "console/consoleTypes.h"
  29. #include "T3D/gameBase/gameConnection.h"
  30. #include "T3D/shapeBase.h"
  31. #include "gfx/gfxDrawUtil.h"
  32. class GuiHealthTextHud : public GuiControl
  33. {
  34. typedef GuiControl Parent;
  35. bool mShowFrame;
  36. bool mShowFill;
  37. bool mShowEnergy;
  38. bool mShowTrueHealth;
  39. LinearColorF mFillColor;
  40. LinearColorF mFrameColor;
  41. LinearColorF mTextColor;
  42. LinearColorF mWarnColor;
  43. F32 mWarnLevel;
  44. F32 mPulseThreshold;
  45. S32 mPulseRate;
  46. F32 mValue;
  47. public:
  48. GuiHealthTextHud();
  49. void onRender(Point2I, const RectI &);
  50. static void initPersistFields();
  51. DECLARE_CONOBJECT(GuiHealthTextHud);
  52. DECLARE_CATEGORY("Gui Game");
  53. DECLARE_DESCRIPTION("Shows the damage or energy level of the current\n"
  54. "PlayerObjectType control object as a numerical text display.");
  55. };
  56. // ----------------------------------------------------------------------------
  57. IMPLEMENT_CONOBJECT(GuiHealthTextHud);
  58. ConsoleDocClass(GuiHealthTextHud,
  59. "@brief Shows the health or energy value of the current PlayerObjectType control object.\n\n"
  60. "This gui can be configured to display either the health or energy value of the current Player Object. "
  61. "It can use an alternate display color if the health or drops below a set value. "
  62. "It can also be set to pulse if the health or energy drops below a set value. "
  63. "This control only works if a server connection exists and it's control object "
  64. "is a PlayerObjectType. If either of these requirements is false, the control is not rendered.\n\n"
  65. "@tsexample\n"
  66. "\n new GuiHealthTextHud()"
  67. "{\n"
  68. " fillColor = \"0.0 0.0 0.0 0.5\"; // Fills with a transparent black color\n"
  69. " frameColor = \"1.0 1.0 1.0 1.0\"; // Solid white frame color\n"
  70. " textColor = \"0.0 1.0 0.0 1.0\" // Solid green text color\n"
  71. " warningColor = \"1.0 0.0 0.0 1.0\"; // Solid red color, used when damaged\n"
  72. " showFill = \"true\";\n"
  73. " showFrame = \"true\";\n"
  74. " showTrueValue = \"false\";\n"
  75. " showEnergy = \"false\";\n"
  76. " warnThreshold = \"50\";\n"
  77. " pulseThreshold = \"25\";\n"
  78. " pulseRate = \"500\";\n"
  79. " profile = \"GuiBigTextProfile\";\n"
  80. "};\n"
  81. "@endtsexample\n\n"
  82. "@ingroup GuiGame\n"
  83. );
  84. GuiHealthTextHud::GuiHealthTextHud()
  85. {
  86. mShowFrame = mShowFill = true;
  87. mShowEnergy = false;
  88. mShowTrueHealth = false;
  89. mFillColor.set(0, 0, 0, 0.5);
  90. mFrameColor.set(1, 1, 1, 1);
  91. mTextColor.set(0, 1, 0, 1);
  92. mWarnColor.set(1, 0, 0, 1);
  93. mWarnLevel = 50.0f;
  94. mPulseThreshold = 25.0f;
  95. mPulseRate = 0;
  96. mValue = 0.2f;
  97. }
  98. void GuiHealthTextHud::initPersistFields()
  99. {
  100. addGroup("Colors");
  101. addField("fillColor", TypeColorF, Offset(mFillColor, GuiHealthTextHud), "Color for the background of the control.");
  102. addField("frameColor", TypeColorF, Offset(mFrameColor, GuiHealthTextHud), "Color for the control's frame.");
  103. addField("textColor", TypeColorF, Offset(mTextColor, GuiHealthTextHud), "Color for the text on this control.");
  104. addField("warningColor", TypeColorF, Offset(mWarnColor, GuiHealthTextHud), "Color for the text when health is low.");
  105. endGroup("Colors");
  106. addGroup("View");
  107. addField("showFill", TypeBool, Offset(mShowFill, GuiHealthTextHud), "If true, draw the background.");
  108. addField("showFrame", TypeBool, Offset(mShowFrame, GuiHealthTextHud), "If true, draw the frame.");
  109. addField("showTrueValue", TypeBool, Offset(mShowTrueHealth, GuiHealthTextHud), "If true, we don't hardcode maxHealth to 100.");
  110. addField("showEnergy", TypeBool, Offset(mShowEnergy, GuiHealthTextHud), "If true, display the energy value rather than the damage value.");
  111. endGroup("View");
  112. addGroup("Alert");
  113. addField("warnThreshold", TypeF32, Offset(mWarnLevel, GuiHealthTextHud), "The health level at which to use the warningColor.");
  114. addField("pulseThreshold", TypeF32, Offset(mPulseThreshold, GuiHealthTextHud), "Health level at which to begin pulsing.");
  115. addField("pulseRate", TypeS32, Offset(mPulseRate, GuiHealthTextHud), "Speed at which the control will pulse.");
  116. endGroup("Alert");
  117. Parent::initPersistFields();
  118. }
  119. // ----------------------------------------------------------------------------
  120. void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
  121. {
  122. // Must have a connection and player control object
  123. GameConnection* conn = GameConnection::getConnectionToServer();
  124. if (!conn)
  125. return;
  126. ShapeBase* control = dynamic_cast<ShapeBase*>(conn->getControlObject());
  127. if (!control || !(control->getTypeMask() & PlayerObjectType))
  128. return;
  129. // Just grab the damage/energy right off the control object.
  130. // Damage value 0 = no damage (full health).
  131. if(mShowEnergy)
  132. mValue = control->getEnergyLevel();
  133. else
  134. {
  135. if (mShowTrueHealth)
  136. mValue = control->getMaxDamage() - control->getDamageLevel();
  137. else
  138. mValue = 100 - (100 * control->getDamageValue());
  139. }
  140. GFXDrawUtil* drawUtil = GFX->getDrawUtil();
  141. // If enabled draw background first
  142. if (mShowFill)
  143. drawUtil->drawRectFill(updateRect, mFillColor.toColorI());
  144. // Prepare text and center it
  145. S32 val = (S32)mValue;
  146. char buf[256];
  147. dSprintf(buf, sizeof(buf), "%d", val);
  148. offset.x += (getBounds().extent.x - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;
  149. offset.y += (getBounds().extent.y - mProfile->mFont->getHeight()) / 2;
  150. LinearColorF tColor = mTextColor;
  151. // If warning level is exceeded switch to warning color
  152. if(mValue < mWarnLevel)
  153. {
  154. tColor = mWarnColor;
  155. // If the pulseRate is set then pulse the text if health is below the threshold
  156. if (mPulseRate != 0 && mValue < mPulseThreshold)
  157. {
  158. U32 time = Platform::getVirtualMilliseconds();
  159. F32 alpha = 2.0f * F32(time % mPulseRate) / F32(mPulseRate);
  160. tColor.alpha = (alpha > 1.0f)? 2.0f - alpha: alpha;
  161. }
  162. }
  163. drawUtil->setBitmapModulation(tColor.toColorI());
  164. drawUtil->drawText(mProfile->mFont, offset, buf);
  165. drawUtil->clearBitmapModulation();
  166. // If enabled draw the border last
  167. if (mShowFrame)
  168. drawUtil->drawRect(updateRect, mFrameColor.toColorI());
  169. }