afxSpellButton.cpp
Engine/source/afx/ui/afxSpellButton.cpp
Public Defines
define
COOLDOWN_PROFILE() &GFXDefaultGUIProfile, ("%s() - Cooldown Texture (line %d)", __FUNCTION__, __LINE__)
Public Functions
ConsoleDocClass(afxSpellButton , "@brief A GUI button with some special features that are useful <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> casting AFX <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">spells.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxGUI\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" )
DefineEngineMethod(afxSpellButton , getFreeTargetStyle , S32 , () , "Get the free targeting style used by the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">spell.\n</a>" )
DefineEngineMethod(afxSpellButton , getSpellDataBlock , S32 , () , "Get the spell's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n</a>" )
DefineEngineMethod(afxSpellButton , getSpellDescription , const char * , () , "Get the text description of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">spell.\n</a>" )
DefineEngineMethod(afxSpellButton , getSpellRPGDataBlock , S32 , () , "Get the spell's RPG <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n</a>" )
DefineEngineMethod(afxSpellButton , onSpellbookChange , void , (afxSpellBook *spellbook, U32 page) , "Notify an <a href="/coding/class/classafxspellbutton/">afxSpellButton</a> when its associated spellbook has <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">changed.\n</a>" )
DefineEngineMethod(afxSpellButton , onTurnPage , void , (U32 page) , "Notify an <a href="/coding/class/classafxspellbutton/">afxSpellButton</a> when the spellbook turns <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">page.\n</a>" )
DefineEngineMethod(afxSpellButton , useFreeTargeting , bool , () , "Test <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> spell uses free <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">targeting.\n</a>" )
Detailed Description
Public Defines
COOLDOWN_PROFILE() &GFXDefaultGUIProfile, ("%s() - Cooldown Texture (line %d)", __FUNCTION__, __LINE__)
Public Functions
ConsoleDocClass(afxSpellButton , "@brief A GUI button with some special features that are useful <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> casting AFX <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">spells.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxGUI\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" )
DefineEngineMethod(afxSpellButton , getFreeTargetStyle , S32 , () , "Get the free targeting style used by the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">spell.\n</a>" )
DefineEngineMethod(afxSpellButton , getSpellDataBlock , S32 , () , "Get the spell's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n</a>" )
DefineEngineMethod(afxSpellButton , getSpellDescription , const char * , () , "Get the text description of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">spell.\n</a>" )
DefineEngineMethod(afxSpellButton , getSpellRPGDataBlock , S32 , () , "Get the spell's RPG <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n</a>" )
DefineEngineMethod(afxSpellButton , onSpellbookChange , void , (afxSpellBook *spellbook, U32 page) , "Notify an <a href="/coding/class/classafxspellbutton/">afxSpellButton</a> when its associated spellbook has <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">changed.\n</a>" )
DefineEngineMethod(afxSpellButton , onTurnPage , void , (U32 page) , "Notify an <a href="/coding/class/classafxspellbutton/">afxSpellButton</a> when the spellbook turns <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">page.\n</a>" )
DefineEngineMethod(afxSpellButton , useFreeTargeting , bool , () , "Test <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> spell uses free <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">targeting.\n</a>" )
IMPLEMENT_CONOBJECT(afxSpellButton )
1 2 3//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 4// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 5// Copyright (C) 2015 Faust Logic, Inc. 6// 7// Permission is hereby granted, free of charge, to any person obtaining a copy 8// of this software and associated documentation files (the "Software"), to 9// deal in the Software without restriction, including without limitation the 10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11// sell copies of the Software, and to permit persons to whom the Software is 12// furnished to do so, subject to the following conditions: 13// 14// The above copyright notice and this permission notice shall be included in 15// all copies or substantial portions of the Software. 16// 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23// IN THE SOFTWARE. 24// 25//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 26 27//------------------------------------- 28// 29// Bitmap Button Contrl 30// Set 'bitmap' comsole field to base name of bitmaps to use. This control will 31// append '_n' for normal 32// append '_h' for hilighted 33// append '_d' for depressed 34// 35// if bitmap cannot be found it will use the default bitmap to render. 36// 37// if the extent is set to (0,0) in the gui editor and appy hit, this control will 38// set it's extent to be exactly the size of the normal bitmap (if present) 39// 40 41#include "afx/arcaneFX.h" 42 43#include "console/engineAPI.h" 44#include "gfx/gfxDrawUtil.h" 45 46#include "afx/ui/afxSpellButton.h" 47#include "afx/afxSpellBook.h" 48#include "afx/afxMagicSpell.h" 49#include "afx/rpg/afxRPGMagicSpell.h" 50 51IMPLEMENT_CONOBJECT(afxSpellButton); 52 53ConsoleDocClass( afxSpellButton, 54 "@brief A GUI button with some special features that are useful for casting AFX spells.\n\n" 55 56 "@ingroup afxGUI\n" 57 "@ingroup AFX\n" 58); 59 60#define COOLDOWN_PROFILE &GFXDefaultGUIProfile, avar("%s() - Cooldown Texture (line %d)", __FUNCTION__, __LINE__) 61 62StringTableEntry afxSpellButton::sUnknownSpellBitmap = ""; 63StringTableEntry afxSpellButton::sSpellCooldownBitmaps = ""; 64 65//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 66 67afxSpellButton::afxSpellButton() 68{ 69 if (sUnknownSpellBitmap == NULL) 70 sUnknownSpellBitmap = ST_NULLSTRING; 71 if (sSpellCooldownBitmaps == NULL) 72 sSpellCooldownBitmaps = ST_NULLSTRING; 73 mBitmapName = ST_NULLSTRING; 74 setExtent(140, 30); 75 spellbook = NULL; 76 book_slot.set(0, 0); 77} 78 79afxSpellButton::~afxSpellButton() 80{ 81} 82 83//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 84 85void afxSpellButton::initPersistFields() 86{ 87 addField("bitmap", TypeFilename, Offset(mBitmapName, afxSpellButton), 88 "..."); 89 addField("book_slot", TypePoint2I, Offset(book_slot, afxSpellButton), 90 "..."); 91 92 Parent::initPersistFields(); 93 94 Con::addVariable("pref::afxSpellButton::unknownSpellBitmap", TypeFilename, &sUnknownSpellBitmap); 95 Con::addVariable("pref::afxSpellButton::spellCooldownBitmaps", TypeFilename, &sSpellCooldownBitmaps); 96} 97 98//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 99 100bool afxSpellButton::onAdd() 101{ 102 if (!Parent::onAdd()) 103 return false; 104 105 if (sSpellCooldownBitmaps != NULL) 106 { 107 char buffer[256]; 108 for (int i = 0; i < NUM_COOLDOWN_FRAMES; i++) 109 { 110 dSprintf(buffer, 256, "%s_%.2d", sSpellCooldownBitmaps, i); 111 cooldown_txrs[i].set(buffer, COOLDOWN_PROFILE); 112 } 113 } 114 115 return true; 116} 117 118bool afxSpellButton::onWake() 119{ 120 if (! Parent::onWake()) 121 return false; 122 123 setActive(true); 124 125 update_bitmap(); 126 127 return true; 128} 129 130void afxSpellButton::onSleep() 131{ 132 mTextureNormal = NULL; 133 mTextureHilight = NULL; 134 mTextureDepressed = NULL; 135 Parent::onSleep(); 136} 137 138void afxSpellButton::onMouseEnter(const GuiEvent &event) 139{ 140 Parent::onMouseEnter(event); 141 Con::executef(this, "onMouseEnter"); 142} 143 144void afxSpellButton::onMouseLeave(const GuiEvent &event) 145{ 146 Parent::onMouseLeave(event); 147 Con::executef(this, "onMouseLeave"); 148} 149 150void afxSpellButton::inspectPostApply() 151{ 152 // if the extent is set to (0,0) in the gui editor and apply hit, this control will 153 // set it's extent to be exactly the size of the normal bitmap (if present) 154 Parent::inspectPostApply(); 155 156 if ((getWidth() == 0) && (getHeight() == 0) && mTextureNormal) 157 { 158 setExtent(mTextureNormal->getWidth(), mTextureNormal->getHeight()); 159 } 160} 161 162void afxSpellButton::setBitmap(const char *name, bool placeholder) 163{ 164 mBitmapName = (name) ? StringTable->insert(name) : ST_NULLSTRING; 165 if (!isAwake()) 166 return; 167 168 if (mBitmapName != ST_NULLSTRING) 169 { 170 char buffer[1024]; 171 char *p; 172 173 if (placeholder) 174 { 175 dStrcpy(buffer, name, 1024); 176 S32 pLen = 1024 - dStrlen(buffer); 177 p = buffer + dStrlen(buffer); 178 179 dStrcpy(p, "_i", pLen); 180 mTextureInactive.set(buffer, COOLDOWN_PROFILE); 181 mTextureNormal = mTextureInactive; 182 mTextureHilight = mTextureInactive; 183 mTextureDepressed = mTextureInactive; 184 setActive(false); 185 } 186 else 187 { 188 dStrcpy(buffer, name, 1024); 189 S32 pLen = 1024 - dStrlen(buffer); 190 p = buffer + dStrlen(buffer); 191 dStrcpy(p, "_n", pLen); 192 mTextureNormal.set(buffer, COOLDOWN_PROFILE); 193 dStrcpy(p, "_h", pLen); 194 mTextureHilight.set(buffer, COOLDOWN_PROFILE); 195 if (!mTextureHilight) 196 mTextureHilight = mTextureNormal; 197 dStrcpy(p, "_d", pLen); 198 mTextureDepressed.set(buffer, COOLDOWN_PROFILE); 199 if (!mTextureDepressed) 200 mTextureDepressed = mTextureHilight; 201 dStrcpy(p, "_i", pLen); 202 mTextureInactive.set(buffer, COOLDOWN_PROFILE); 203 if (!mTextureInactive) 204 mTextureInactive = mTextureNormal; 205 setActive(true); 206 } 207 } 208 else 209 { 210 mTextureNormal = NULL; 211 mTextureHilight = NULL; 212 mTextureDepressed = NULL; 213 mTextureInactive = NULL; 214 } 215 216 setUpdate(); 217} 218 219void afxSpellButton::onRender(Point2I offset, const RectI& updateRect) 220{ 221 enum { NORMAL, HILIGHT, DEPRESSED, INACTIVE } state = NORMAL; 222 223 if (mActive) 224 { 225 if (mMouseOver) state = HILIGHT; 226 if (mDepressed || mStateOn) state = DEPRESSED; 227 } 228 else 229 state = INACTIVE; 230 231 switch (state) 232 { 233 case NORMAL: renderButton(mTextureNormal, offset, updateRect); break; 234 case HILIGHT: renderButton(mTextureHilight ? mTextureHilight : mTextureNormal, offset, updateRect); break; 235 case DEPRESSED: renderButton(mTextureDepressed, offset, updateRect); break; 236 case INACTIVE: renderButton(mTextureInactive ? mTextureInactive : mTextureNormal, offset, updateRect); break; 237 } 238} 239 240void afxSpellButton::onDeleteNotify(SimObject* obj) 241{ 242 // Handle Shape Deletion 243 afxSpellBook* book = dynamic_cast<afxSpellBook*>(obj); 244 if (book != NULL) 245 { 246 if (book == spellbook) 247 { 248 spellbook = NULL; 249 setBitmap(""); 250 setVisible(false); 251 return; 252 } 253 } 254 255 Parent::onDeleteNotify(obj); 256} 257 258//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 259// protected: 260 261void afxSpellButton::renderButton(GFXTexHandle &texture, Point2I &offset, 262 const RectI& updateRect) 263{ 264 if (texture) 265 { 266 RectI rect(offset, getExtent()); 267 GFX->getDrawUtil()->clearBitmapModulation(); 268 GFX->getDrawUtil()->drawBitmapStretch(texture, rect); 269 270 if (spellbook) 271 { 272 F32 cooldown = spellbook->getCooldownFactor(book_slot.x, book_slot.y); 273 if (cooldown < 1.0f) 274 { 275 276 if (cooldown_txrs[(int)(36.0f*cooldown)]) 277 GFX->getDrawUtil()->drawBitmapStretch(cooldown_txrs[(int)(36.0f*cooldown)], rect); 278 } 279 } 280 281 renderChildControls( offset, updateRect); 282 } 283 else 284 Parent::onRender(offset, updateRect); 285} 286 287void afxSpellButton::update_bitmap() 288{ 289 const char* icon_name = 0; 290 291 bool is_placeholder = false; 292 if (spellbook) 293 { 294 icon_name = spellbook->getSpellIcon(book_slot.x, book_slot.y); 295 is_placeholder = spellbook->isPlaceholder(book_slot.x, book_slot.y); 296 if (icon_name && icon_name[0] == '\0') 297 icon_name = sUnknownSpellBitmap; 298 } 299 300 if (icon_name) 301 { 302 setBitmap(icon_name, is_placeholder); 303 setVisible(true); 304 } 305 else 306 { 307 setBitmap(""); 308 setVisible(false); 309 } 310} 311 312void afxSpellButton::setSpellBook(afxSpellBook* book, U8 page) 313{ 314 book_slot.x = page; 315 316 if (spellbook) 317 clearNotify(spellbook); 318 319 spellbook = book; 320 update_bitmap(); 321 322 if (spellbook) 323 deleteNotify(spellbook); 324} 325 326void afxSpellButton::setPage(U8 page) 327{ 328 book_slot.x = page; 329 update_bitmap(); 330} 331 332char* afxSpellButton::formatDesc(char* buffer, int len) const 333{ 334 return (spellbook) ? spellbook->formatDesc(buffer, len, book_slot.x, book_slot.y) : (char*)""; 335} 336 337afxMagicSpellData* afxSpellButton::getSpellDataBlock() const 338{ 339 return (spellbook) ? spellbook->getSpellData(book_slot.x, book_slot.y) : 0; 340} 341 342afxRPGMagicSpellData* afxSpellButton::getSpellRPGDataBlock() const 343{ 344 return (spellbook) ? spellbook->getSpellRPGData(book_slot.x, book_slot.y) : 0; 345} 346 347//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 348 349DefineEngineMethod( afxSpellButton, onSpellbookChange, void, ( afxSpellBook* spellbook, U32 page ),, 350 "Notify an afxSpellButton when its associated spellbook has changed.\n" ) 351{ 352 object->setSpellBook(spellbook, (U8)page); 353} 354 355DefineEngineMethod( afxSpellButton, onTurnPage, void, (U32 page ),, 356 "Notify an afxSpellButton when the spellbook turns to a new page.\n" ) 357{ 358 object->setPage((U8)page); 359} 360 361DefineEngineMethod( afxSpellButton, getSpellDescription, const char*, (),, 362 "Get the text description of a spell.\n" ) 363{ 364 char buf[1024]; 365 return object->formatDesc(buf, 1024); 366} 367 368DefineEngineMethod( afxSpellButton, getSpellDataBlock, S32, (),, 369 "Get the spell's datablock.\n" ) 370{ 371 afxMagicSpellData* spell_data = object->getSpellDataBlock(); 372 return (spell_data) ? spell_data->getId() : -1; 373} 374 375DefineEngineMethod( afxSpellButton, getSpellRPGDataBlock, S32, (),, 376 "Get the spell's RPG datablock.\n" ) 377{ 378 afxRPGMagicSpellData* spell_rpg_data = object->getSpellRPGDataBlock(); 379 return (spell_rpg_data) ? spell_rpg_data->getId() : -1; 380} 381 382DefineEngineMethod( afxSpellButton, useFreeTargeting, bool, (),, 383 "Test if spell uses free targeting.\n" ) 384{ 385 afxRPGMagicSpellData* spell_rpg_data = object->getSpellRPGDataBlock(); 386 return (spell_rpg_data) ? (spell_rpg_data->spell_target == afxRPGMagicSpellData::TARGET_FREE) : false; 387} 388 389DefineEngineMethod( afxSpellButton, getFreeTargetStyle, S32, (),, 390 "Get the free targeting style used by the spell.\n" ) 391{ 392 afxRPGMagicSpellData* spell_rpg_data = object->getSpellRPGDataBlock(); 393 return (spell_rpg_data) ? spell_rpg_data->free_target_style : 0; 394} 395 396//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 397