1 /***************************************************************************
2 equip.cpp - Equipped items/spells/abilities widget
3 -------------------
4 begin : Sat May 3 2003
5 copyright : (C) 2003 by Gabor Torok
6 email : cctorok@yahoo.com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "common/constants.h"
19 #include "equip.h"
20 #include "render/renderlib.h"
21 #include "rpg/rpglib.h"
22 #include "sound.h"
23 #include "sdlhandler.h"
24 #include "sdleventhandler.h"
25 #include "sdlscreenview.h"
26 #include "scourge.h"
27 #include "item.h"
28 #include "creature.h"
29 #include "tradedialog.h"
30 #include "uncursedialog.h"
31 #include "identifydialog.h"
32 #include "rechargedialog.h"
33 #include "sqbinding/sqbinding.h"
34 #include "characterinfo.h"
35 #include "shapepalette.h"
36 #include "skillsview.h"
37 #include "gui/confirmdialog.h"
38 #include "pcui.h"
39 #include "gui/scrollinglabel.h"
40 #include "storable.h"
41
42 using namespace std;
43
44 /**
45 *@author Gabor Torok
46 */
47
48 #define SPELL_SIZE 30
49 #define DEBUG_SPECIAL_SKILL 0
50
51 // fixme: this should be a property of the magicschool and should come from the .cfg file.
52 char *schoolIcons[] = {
53 "nature", "divine", "life", "history", "tricks", "confrontation"
54 };
55
Equip(PcUi * pcUi,int x,int y,int w,int h)56 Equip::Equip( PcUi *pcUi, int x, int y, int w, int h ) {
57 this->pcUi = pcUi;
58 this->creature = NULL;
59 this->backgroundTexture = pcUi->getScourge()->getShapePalette()->getNamedTexture( "equip" );
60 this->scrollTexture = pcUi->getScourge()->getShapePalette()->getNamedTexture( "scroll" );
61 this->currentHole = -1;
62 this->x = x;
63 this->y = y;
64 this->w = w;
65 this->h = h;
66 this->lastItem = NULL;
67 this->mode = EQUIP_MODE;
68 this->schoolIndex = -1;
69 this->spellIndex = -1;
70 this->specialSkill = NULL;
71 this->storable = NULL;
72
73 canvas = new Canvas( x, y, x + w, y + h, this, this );
74 canvas->setDrawBorders( false );
75 }
76
~Equip()77 Equip::~Equip() {
78 }
79
handleEvent(Widget * widget,SDL_Event * event)80 bool Equip::handleEvent( Widget *widget, SDL_Event *event ) {
81 if ( widget == canvas ) {
82 if ( pcUi->getScourge()->getSDLHandler()->isDoubleClick ) {
83 if ( mode == EQUIP_MODE ) {
84 Item *item = getItemAtPos( pcUi->getScourge()->getSDLHandler()->mouseX - pcUi->getWindow()->getX() - x,
85 pcUi->getScourge()->getSDLHandler()->mouseY - pcUi->getWindow()->getY() - y - TITLE_HEIGHT );
86 if ( item && item->getRpgItem()->isContainer() ) {
87 pcUi->getScourge()->openContainerGui( item );
88 }
89 }
90 } else if ( pcUi->getScourge()->getSDLHandler()->mouseButton == SDL_BUTTON_RIGHT ) {
91 if ( mode == EQUIP_MODE ) {
92 Item *item = getItemAtPos( pcUi->getScourge()->getSDLHandler()->mouseX - pcUi->getWindow()->getX() - x,
93 pcUi->getScourge()->getSDLHandler()->mouseY - pcUi->getWindow()->getY() - y - TITLE_HEIGHT );
94 if ( item ) {
95 pcUi->getScourge()->getInfoGui()->setItem( item );
96 if ( !pcUi->getScourge()->getInfoGui()->getWindow()->isVisible() )
97 pcUi->getScourge()->getInfoGui()->getWindow()->setVisible( true );
98 }
99 } else if ( mode == SPELLS_MODE ) {
100 int mx = pcUi->getScourge()->getSDLHandler()->mouseX - pcUi->getWindow()->getX() - x;
101 int my = pcUi->getScourge()->getSDLHandler()->mouseY - pcUi->getWindow()->getY() - TITLE_HEIGHT;
102 int si = getSchoolIndex( mx, my );
103 int spi = getSpellIndex( mx, my, si );
104 Spell *spell = ( si > -1 && spi > -1 ?
105 MagicSchool::getMagicSchool( si )->getSpell( spi ) :
106 NULL );
107 if ( spell ) {
108 pcUi->getScourge()->getInfoGui()->setSpell( spell );
109 if ( !pcUi->getScourge()->getInfoGui()->getWindow()->isVisible() ) pcUi->getScourge()->getInfoGui()->getWindow()->setVisible( true );
110 }
111 } else if ( mode == CAPABILITIES_MODE ) {
112 if ( specialSkill ) {
113 pcUi->getScourge()->getInfoGui()->setSkill( specialSkill );
114 if ( !pcUi->getScourge()->getInfoGui()->getWindow()->isVisible() ) pcUi->getScourge()->getInfoGui()->getWindow()->setVisible( true );
115 }
116 }
117 } else if ( pcUi->getScourge()->getSDLHandler()->mouseButton == SDL_BUTTON_LEFT ) {
118 if ( mode == SPELLS_MODE ) {
119 // reset buttons first b/c it changes the cursor
120 bool cast = pcUi->isCastSelected();
121 bool store = pcUi->isStoreSpellSelected();
122 if ( cast || store ) {
123 pcUi->hide();
124
125 int mx = pcUi->getScourge()->getSDLHandler()->mouseX - pcUi->getWindow()->getX() - x;
126 int my = pcUi->getScourge()->getSDLHandler()->mouseY - pcUi->getWindow()->getY() - TITLE_HEIGHT;
127 int si = getSchoolIndex( mx, my );
128 int spi = getSpellIndex( mx, my, si );
129 Spell *spell = ( si > -1 && spi > -1 ?
130 MagicSchool::getMagicSchool( si )->getSpell( spi ) :
131 NULL );
132 if ( spell ) {
133 if ( cast ) {
134 castSpell( spell );
135 } else if ( store ) {
136 storeSpell( spell );
137 }
138 }
139 }
140 } else if ( mode == CAPABILITIES_MODE ) {
141 // reset buttons first b/c it changes the cursor
142 bool cast = pcUi->isCastSelected();
143 bool store = pcUi->isStoreSpellSelected();
144 if ( cast || store ) {
145 pcUi->hide();
146
147 if ( specialSkill ) {
148 if ( cast ) {
149 useSpecialSkill( specialSkill );
150 } else if ( store ) {
151 storeSpecialSkill( specialSkill );
152 }
153 }
154 }
155 }
156 }
157 }
158 return false;
159 }
160
handleEvent(SDL_Event * event)161 bool Equip::handleEvent( SDL_Event *event ) {
162 int si, spi, mx, my;
163 Item *item;
164 Spell *spell;
165 enum { TEXT_SIZE = 3000 };
166 char tooltip[ TEXT_SIZE ], tmp[ TEXT_SIZE ];
167 switch ( event->type ) {
168 case SDL_MOUSEMOTION:
169 mx = event->motion.x - pcUi->getWindow()->getX() - x;
170 my = event->motion.y - pcUi->getWindow()->getY() - TITLE_HEIGHT;
171 if ( mode == EQUIP_MODE ) {
172 schoolIndex = spellIndex = -1;
173 currentHole = getHoleAtPos( mx, my );
174 item = getItemInHole( currentHole );
175 if ( item != lastItem ) {
176 lastItem = item;
177 if ( item ) {
178 item->getTooltip( tooltip );
179 canvas->setTooltip( tooltip );
180 } else {
181 canvas->setTooltip( NULL );
182 }
183 }
184 } else if ( mode == SPELLS_MODE ) {
185 lastItem = NULL;
186 si = getSchoolIndex( mx, my );
187 spi = getSpellIndex( mx, my, si );
188 if ( schoolIndex != si || spellIndex != spi ) {
189 schoolIndex = si;
190 spellIndex = spi;
191 spell = ( schoolIndex > -1 && spellIndex > -1 ?
192 MagicSchool::getMagicSchool( schoolIndex )->getSpell( spellIndex ) :
193 NULL );
194 if ( spell && creature && creature->isSpellMemorized( spell ) ) {
195 Util::addLineBreaks( spell->getNotes(), tmp );
196 snprintf( tooltip, TEXT_SIZE, "%s:|%s|%s:%d %s:%d",
197 spell->getDisplayName(),
198 tmp,
199 _( "Level" ), spell->getLevel(),
200 _( "MP Cost" ), spell->getMp() );
201 canvas->setTooltip( tooltip );
202 } else {
203 canvas->setTooltip( "" );
204 }
205 }
206 }
207
208 break;
209 default: break;
210 }
211 return false;
212 }
213
214 /*
215 // FIXME: brittle. This will break if drawCapabilities is changed.
216 SpecialSkill *Equip::findSpecialSkill( int x, int y ) {
217 int startX = 20;
218 int xx = startX;
219 int yy = 20;
220 yy += 5;
221 for( int i = 0; i < SpecialSkill::getSpecialSkillCount(); i++ ) {
222 SpecialSkill *ss = SpecialSkill::getSpecialSkill( i );
223 if( 1 || creature->hasSpecialSkill( ss ) ) {
224
225 }
226 }
227 }
228 */
229
230 /// Converts screen coordinates to a magic school (aka row in the spell list).
231
getSchoolIndex(int x,int y)232 int Equip::getSchoolIndex( int x, int y ) {
233 int n = ( y - 20 ) / 47;
234 return( n >= 0 && n < MagicSchool::getMagicSchoolCount() ? n : -1 );
235 }
236
237 /// Converts screen coordinates to a spell index.
238
getSpellIndex(int x,int y,int schoolIndex)239 int Equip::getSpellIndex( int x, int y, int schoolIndex ) {
240 int n = ( x - 20 ) / ( SPELL_SIZE + 2 );
241 return( schoolIndex > -1 &&
242 n >= 0 &&
243 n < MagicSchool::getMagicSchool( schoolIndex )->getSpellCount() ? n : -1 );
244 }
245
246 /// Returns the item at an equip index.
247
getItemInHole(int hole)248 Item *Equip::getItemInHole( int hole ) {
249 return( hole > -1 && creature ? creature->getEquippedItemByIndex( hole ) : NULL );
250 }
251
252 /// Takes screen coordinates and determines which equipped item these point at.
253
getItemAtPos(int x,int y)254 Item *Equip::getItemAtPos( int x, int y ) {
255 int hole = getHoleAtPos( x, y );
256 return getItemInHole( hole );
257 }
258
259 /// Converts a screen coordinate to an equip index.
260
getHoleAtPos(int x,int y)261 int Equip::getHoleAtPos( int x, int y ) {
262 SDL_Rect point;
263 point.x = x;
264 point.y = y;
265 point.w = point.h = 1;
266 for ( int i = 0; i < Constants::EQUIP_LOCATION_COUNT; i++ ) {
267 SDL_Rect *rect = pcUi->getScourge()->getShapePalette()->getEquipHole( i );
268 if ( SDLHandler::intersects( rect, &point ) ) {
269 return i;
270 }
271 }
272 return -1;
273 }
274
275 /// Handles dragging items onto the paperdoll.
276
receive(Widget * widget)277 void Equip::receive( Widget *widget ) {
278 if ( mode == EQUIP_MODE && creature ) {
279 Item *item = pcUi->getScourge()->getMovingItem();
280 if ( item ) {
281 char *err = creature->canEquipItem( item );
282 if ( err ) {
283 pcUi->getScourge()->showMessageDialog( err );
284 pcUi->getScourge()->getSession()->getSound()->playSound( Window::DROP_FAILED, 127 );
285 } else {
286 if ( creature->addToBackpack( item ) ) {
287 // message: the player accepted the item
288 char message[120];
289 snprintf( message, 119, _( "%s picks up %s." ),
290 creature->getName(),
291 item->getItemName() );
292 pcUi->getScourge()->writeLogMessage( message );
293 pcUi->getScourge()->endItemDrag();
294 int index = creature->findInBackpack( item );
295 creature->equipFromBackpack( index, currentHole );
296 pcUi->getScourge()->getSession()->getSound()->playSound( Window::DROP_SUCCESS, 127 );
297 } else {
298 // message: the player's backpack is full
299 pcUi->getScourge()->getSession()->getSound()->playSound( Window::DROP_FAILED, 127 );
300 pcUi->getScourge()->showMessageDialog( _( "You can't fit the item!" ) );
301 }
302 }
303 }
304 }
305 }
306
307 /// Handles picking up of items from the paperdoll.
308
startDrag(Widget * widget,int x,int y)309 bool Equip::startDrag( Widget *widget, int x, int y ) {
310 if ( mode == EQUIP_MODE && creature ) {
311
312 if ( pcUi->getScourge()->getTradeDialog()->getWindow()->isVisible() ) {
313 pcUi->getScourge()->showMessageDialog( _( "Can't change backpack while trading." ) );
314 return false;
315 } else if ( pcUi->getScourge()->getUncurseDialog()->getWindow()->isVisible() ) {
316 pcUi->getScourge()->showMessageDialog( _( "Can't change backpack while employing a sage's services." ) );
317 return false;
318 } else if ( pcUi->getScourge()->getIdentifyDialog()->getWindow()->isVisible() ) {
319 pcUi->getScourge()->showMessageDialog( _( "Can't change backpack while employing a sage's services." ) );
320 return false;
321 } else if ( pcUi->getScourge()->getRechargeDialog()->getWindow()->isVisible() ) {
322 pcUi->getScourge()->showMessageDialog( _( "Can't change backpack while employing a sage's services." ) );
323 return false;
324 }
325
326 // what's equipped at this slot?
327 currentHole = getHoleAtPos( x, y );
328 Item *item = getItemAtPos( x, y );
329 if ( item ) {
330 if ( item->isCursed() ) {
331 pcUi->getScourge()->showMessageDialog( _( "Can't remove cursed item!" ) );
332 return false;
333 } else {
334 creature->removeFromBackpack( creature->findInBackpack( item ) );
335 pcUi->getScourge()->startItemDragFromGui( item );
336 char message[120];
337 snprintf( message, 119, _( "%s drops %s." ),
338 creature->getName(),
339 item->getItemName() );
340 pcUi->getScourge()->writeLogMessage( message );
341
342 return true;
343 }
344 }
345 }
346 return false;
347 }
348
setCreature(Creature * creature)349 void Equip::setCreature( Creature *creature ) {
350 this->creature = creature;
351 }
352
drawWidgetContents(Widget * widget)353 void Equip::drawWidgetContents( Widget *widget ) {
354 glEnable( GL_TEXTURE_2D );
355 // glEnable( GL_ALPHA_TEST );
356 // glAlphaFunc( GL_NOTEQUAL, 0 );
357 glEnable( GL_BLEND );
358 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
359 if ( mode == EQUIP_MODE ) {
360 backgroundTexture.glBind();
361 } else {
362 scrollTexture.glBind();
363 }
364 glColor4f( 1, 1, 1, 1 );
365 glBegin( GL_TRIANGLE_STRIP );
366 glTexCoord2d( 0, 0 );
367 glVertex2d( 0, 0 );
368 glTexCoord2d( 1, 0 );
369 glVertex2d( w, 0 );
370 glTexCoord2d( 0, 1 );
371 glVertex2d( 0, h );
372 glTexCoord2d( 1, 1 );
373 glVertex2d( w, h );
374 glEnd();
375 glDisable( GL_BLEND );
376 // glDisable( GL_ALPHA_TEST );
377 if ( creature ) {
378 if ( mode == EQUIP_MODE ) {
379 drawEquipment();
380 } else if ( mode == SPELLS_MODE ) {
381 drawSpells();
382 } else {
383 drawCapabilities();
384 }
385 }
386 }
387
388 /// Draws the paperdoll with the equipped items.
389
drawEquipment()390 void Equip::drawEquipment() {
391 for ( int i = 0; i < Constants::EQUIP_LOCATION_COUNT; i++ ) {
392 SDL_Rect *rect = pcUi->getScourge()->getShapePalette()->getEquipHole( i );
393 Item *item = creature->getEquippedItemByIndex( i );
394 if ( item ) {
395 if ( rect && rect->w && rect->h ) {
396 glEnable( GL_TEXTURE_2D );
397 item->renderIcon( pcUi->getScourge(), rect );
398 }
399 }
400 }
401 if ( currentHole > -1 ) {
402 SDL_Rect *rect = pcUi->getScourge()->getShapePalette()->getEquipHole( currentHole );
403 glDisable( GL_TEXTURE_2D );
404 pcUi->getWindow()->setTopWindowBorderColor();
405 glBegin( GL_LINE_LOOP );
406 glVertex2d( rect->x, rect->y + rect->h );
407 glVertex2d( rect->x, rect->y );
408 glVertex2d( rect->x + rect->w, rect->y );
409 glVertex2d( rect->x + rect->w, rect->y + rect->h );
410 glEnd();
411 }
412 }
413
414 /// Draws the spell list.
415
drawSpells()416 void Equip::drawSpells() {
417 int startX = 20;
418 int xx = startX;
419 int yy = 20;
420
421 glEnable( GL_BLEND );
422 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
423
424 for ( int i = 0; i < MagicSchool::getMagicSchoolCount(); i++ ) {
425 MagicSchool *school = MagicSchool::getMagicSchool( i );
426
427 glPushMatrix();
428 glTranslatef( xx, yy - 12, 0 );
429
430 int size = 15;
431 int width = w - 55;
432
433 glDisable( GL_TEXTURE_2D );
434 glColor4f( 0, 0, 0, 0.75 );
435 glBegin( GL_TRIANGLE_STRIP );
436 glVertex2d( 0, 1 );
437 glVertex2d( size + width, 1 );
438 glVertex2d( 0, size );
439 glVertex2d( size + width, size );
440 glEnd();
441 glEnable( GL_TEXTURE_2D );
442
443 pcUi->getScourge()->getShapePalette()->getNamedTexture( schoolIcons[ i ] ).glBind();
444 glColor4f( 1, 1, 1, 1 );
445 glBegin( GL_TRIANGLE_STRIP );
446 glTexCoord2d( 0, 0 );
447 glVertex2d( 0, 0 );
448 glTexCoord2d( 1, 0 );
449 glVertex2d( size, 0 );
450 glTexCoord2d( 0, 1 );
451 glVertex2d( 0, size );
452 glTexCoord2d( 1, 1 );
453 glVertex2d( size, size );
454 glEnd();
455
456 glColor4f( 1, 0.35f, 0, 1 );
457 pcUi->getScourge()->getSDLHandler()->setFontType( Constants::SCOURGE_MONO_FONT );
458 pcUi->getScourge()->getSDLHandler()->texPrint( size + 5, 13, school->getDisplayName() );
459 pcUi->getScourge()->getSDLHandler()->setFontType( Constants::SCOURGE_DEFAULT_FONT );
460
461 glPopMatrix();
462
463 yy += 5;
464 for ( int t = 0; t < school->getSpellCount(); t++, xx += SPELL_SIZE + 2 ) {
465 Spell *spell = school->getSpell( t );
466 if ( creature && creature->isSpellMemorized( spell ) ) {
467 pcUi->getScourge()->getShapePalette()->spellsTex[ spell->getIconTileX() ][ spell->getIconTileY() ].glBind();
468 glColor4f( 1, 1, 1, 1 );
469 glBegin( GL_TRIANGLE_STRIP );
470 glTexCoord2d( 0, 0 );
471 glVertex2d( xx, yy );
472 glTexCoord2d( 1, 0 );
473 glVertex2d( xx + SPELL_SIZE, yy );
474 glTexCoord2d( 0, 1 );
475 glVertex2d( xx, yy + SPELL_SIZE );
476 glTexCoord2d( 1, 1 );
477 glVertex2d( xx + SPELL_SIZE, yy + SPELL_SIZE );
478 glEnd();
479 }
480 if ( schoolIndex == i && spellIndex == t ) {
481 glColor4f( 1, 1, 0, 1 );
482 } else {
483 pcUi->getWindow()->setTopWindowBorderColor();
484 }
485 glDisable( GL_TEXTURE_2D );
486 glBegin( GL_LINE_LOOP );
487 glVertex2d( xx, yy + SPELL_SIZE );
488 glVertex2d( xx, yy );
489 glVertex2d( xx + SPELL_SIZE, yy );
490 glVertex2d( xx + SPELL_SIZE, yy + SPELL_SIZE );
491 glEnd();
492 glEnable( GL_TEXTURE_2D );
493 }
494
495 xx = startX;
496 yy += SPELL_SIZE + 12;
497 }
498 glDisable( GL_BLEND );
499 }
500
501 /// Draws the list of special capabilities.
502
drawCapabilities()503 void Equip::drawCapabilities() {
504 int startX = 20;
505 int xx = startX;
506 int yy = 20;
507
508 glPushMatrix();
509 glTranslatef( xx, yy - 12, 0 );
510
511 int size = 15;
512 int width = w - 55;
513
514 glEnable( GL_BLEND );
515 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
516 glDisable( GL_TEXTURE_2D );
517
518 glColor4f( 0, 0, 0, 0.75 );
519 glBegin( GL_TRIANGLE_STRIP );
520 glVertex2d( 0, 1 );
521 glVertex2d( size + width, 1 );
522 glVertex2d( 0, size );
523 glVertex2d( size + width, size );
524 glEnd();
525
526 glEnable( GL_TEXTURE_2D );
527
528 glColor4f( 1, 0.35f, 0, 1 );
529 pcUi->getScourge()->getSDLHandler()->setFontType( Constants::SCOURGE_MONO_FONT );
530 pcUi->getScourge()->getSDLHandler()->texPrint( size + 5, 13, _( "Special Capabilities" ) );
531 pcUi->getScourge()->getSDLHandler()->setFontType( Constants::SCOURGE_DEFAULT_FONT );
532
533 glPopMatrix();
534
535 int mx = pcUi->getScourge()->getSDLHandler()->mouseX - pcUi->getWindow()->getX() - x;
536 int my = pcUi->getScourge()->getSDLHandler()->mouseY - pcUi->getWindow()->getY() - TITLE_HEIGHT;
537
538 yy += 5;
539 bool found = false;
540 for ( int i = 0; i < SpecialSkill::getSpecialSkillCount(); i++ ) {
541 SpecialSkill *ss = SpecialSkill::getSpecialSkill( i );
542 if ( DEBUG_SPECIAL_SKILL || creature->hasSpecialSkill( ss ) ) {
543
544 if ( !found &&
545 mx >= xx && mx < xx + SPELL_SIZE &&
546 yy >= yy && my < yy + SPELL_SIZE ) {
547 if ( specialSkill != ss ) {
548 specialSkill = ss;
549 enum { TEXT_SIZE = 3000 };
550 char tmp[ TEXT_SIZE ], tooltip[ TEXT_SIZE ];
551 Util::addLineBreaks( ss->getDescription(), tmp );
552 snprintf( tooltip, TEXT_SIZE, "%s:|%s|%s",
553 ss->getDisplayName(),
554 tmp,
555 ss->getType() == SpecialSkill::SKILL_TYPE_MANUAL ?
556 _( "Manual Capability" ) :
557 _( "Automatic Capability" ) );
558 canvas->setTooltip( tooltip );
559 }
560 found = true;
561 }
562
563 pcUi->getScourge()->getShapePalette()->spellsTex[ ss->getIconTileX() ][ ss->getIconTileY() ].glBind();
564 glColor4f( 1, 1, 1, 1 );
565 glBegin( GL_TRIANGLE_STRIP );
566 glTexCoord2d( 0, 0 );
567 glVertex2d( xx, yy );
568 glTexCoord2d( 1, 0 );
569 glVertex2d( xx + SPELL_SIZE, yy );
570 glTexCoord2d( 0, 1 );
571 glVertex2d( xx, yy + SPELL_SIZE );
572 glTexCoord2d( 1, 1 );
573 glVertex2d( xx + SPELL_SIZE, yy + SPELL_SIZE );
574 glEnd();
575
576 if ( specialSkill == ss ) {
577 glColor4f( 1, 1, 0, 1 );
578 } else {
579 pcUi->getWindow()->setTopWindowBorderColor();
580 }
581 glDisable( GL_TEXTURE_2D );
582 glBegin( GL_LINE_LOOP );
583 glVertex2d( xx, yy + SPELL_SIZE );
584 glVertex2d( xx, yy );
585 glVertex2d( xx + SPELL_SIZE, yy );
586 glVertex2d( xx + SPELL_SIZE, yy + SPELL_SIZE );
587 glEnd();
588 glEnable( GL_TEXTURE_2D );
589
590 xx += SPELL_SIZE + 2;
591 if ( xx > w - 50 ) {
592 xx = startX;
593 yy += SPELL_SIZE + 2;
594 }
595 }
596 }
597 if ( !found ) {
598 specialSkill = NULL;
599 canvas->setTooltip( "" );
600 }
601 glDisable( GL_BLEND );
602 }
603
604 /// Using a special capability from the list.
605
useSpecialSkill(SpecialSkill * ss)606 void Equip::useSpecialSkill( SpecialSkill *ss ) {
607 if ( ss && ( DEBUG_SPECIAL_SKILL || creature->hasSpecialSkill( ss ) ) ) {
608 if ( ss->getType() != SpecialSkill::SKILL_TYPE_MANUAL ) {
609 pcUi->getScourge()->showMessageDialog( _( "Only manual type capabilities can be used this way." ) );
610 } else {
611
612 creature->setAction( Constants::ACTION_SPECIAL, NULL, NULL, ss );
613 creature->setTargetCreature( creature );
614
615 // set this as a quickspell if there is space
616 for ( int i = 0; i < 12; i++ ) {
617 if ( !creature->getQuickSpell( i ) ) {
618 creature->setQuickSpell( i, ss );
619 break;
620 }
621 }
622 }
623 }
624 }
625
626 /// Casting a spell from the spell list.
627
castSpell(Spell * spell)628 void Equip::castSpell( Spell *spell ) {
629 if ( spell ) {
630 if ( spell->getMp() > creature->getMp() ) {
631 pcUi->getScourge()->showMessageDialog( _( "Not enough Magic Points to cast this spell!" ) );
632 } else {
633 // set this as a quickspell if there is space
634 for ( int i = 0; i < 12; i++ ) {
635 if ( !creature->getQuickSpell( i ) ) {
636 creature->setQuickSpell( i, spell );
637 break;
638 }
639 }
640
641 creature->setAction( Constants::ACTION_CAST_SPELL, NULL, spell );
642 if ( !spell->isPartyTargetAllowed() ) {
643 pcUi->getScourge()->setTargetSelectionFor( creature );
644 } else {
645 creature->setTargetCreature( creature );
646 }
647 }
648 }
649 }
650
651 /// Handles storing a spell in a quickspell slot.
652
storeSpell(Spell * spell)653 void Equip::storeSpell( Spell *spell ) {
654 if ( spell ) {
655 storeStorable( ( Storable* )spell );
656 }
657 }
658
659 /// Handles storing a special capability in a quickspell slot.
660
storeSpecialSkill(SpecialSkill * ss)661 void Equip::storeSpecialSkill( SpecialSkill *ss ) {
662 if ( ss && ( DEBUG_SPECIAL_SKILL || creature->hasSpecialSkill( ss ) ) ) {
663 if ( ss->getType() != SpecialSkill::SKILL_TYPE_MANUAL ) {
664 pcUi->getScourge()->showMessageDialog( _( "Only manual type capabilities can be stored." ) );
665 } else {
666 storeStorable( ( Storable* )ss );
667 }
668 }
669 }
670
671 /// Stores a spell or special capability in a quickspell slot.
672
storeStorable(Storable * storable)673 void Equip::storeStorable( Storable *storable ) {
674 this->storable = NULL;
675 const char *p = storable->isStorable();
676 if ( p ) {
677 pcUi->getScourge()->showMessageDialog( p );
678 } else {
679 this->storable = storable;
680 pcUi->getScourge()->showMessageDialog( _( "Click a quickspell slot to store this spell." ) );
681 }
682 }
683
MissionInfoUI(PcUi * pcUi,int x,int y,int w,int h)684 MissionInfoUI::MissionInfoUI( PcUi *pcUi, int x, int y, int w, int h ) {
685 this->pcUi = pcUi;
686 this->x = x;
687 this->y = y;
688 this->w = w;
689 this->h = h;
690
691 description = new ScrollingLabel( x, y, w, h - 95, "" );
692 pcUi->getWindow()->addWidget( description );
693
694 objectivesLabel = pcUi->getWindow()->createLabel( x, y + h - 80, _( "Mission Objectives" ) );
695 objectiveList = new ScrollingList( x, y + h - 75, w, 45, pcUi->getScourge()->getShapePalette()->getHighlightTexture() );
696 pcUi->getWindow()->addWidget( objectiveList );
697 consoleButton = pcUi->getWindow()->createButton( x, y + h - 25, x + w, y + h - 5, _( "Show Squirrel Console" ) );
698 }
699
~MissionInfoUI()700 MissionInfoUI::~MissionInfoUI() {
701 // objectiveText has static size now
702 }
703
refresh()704 void MissionInfoUI::refresh() {
705 enum { TMP_SIZE = 80, MISSNTXT_SIZE = 3000 };
706 Color green( 0.2f, 0.7f, 0.2f ), red( 0.7f, 0.2f, 0.2f );
707 char missionText[MISSNTXT_SIZE], tmp[TMP_SIZE];
708 Scourge *scourge = pcUi->getScourge();
709 Mission* curMission = scourge->getSession()->getCurrentMission();
710 objectiveText.clear();
711 missionColor.clear();
712
713 if ( curMission ) {
714 snprintf( tmp, TMP_SIZE, _( "Depth: %d out of %d." ), ( scourge->getCurrentDepth() + 1 ), curMission->getDepth() );
715 snprintf( missionText, MISSNTXT_SIZE, "%s:|%s|%s", curMission->getDisplayName(), tmp, curMission->getDescription() );
716
717 for ( int t = 0; t < curMission->getItemCount(); t++ ) {
718 snprintf( tmp, TMP_SIZE, _( "Find %s" ), curMission->getItem( t )->getDisplayName() );
719 if ( curMission->getItemHandled( t ) ) {
720 objectiveText.push_back( tmp + string( ". " ) + _( "(completed)" ) );
721 missionColor.push_back( green );
722 } else {
723 objectiveText.push_back( tmp + string( ". " ) + _( "(not yet found)" ) );
724 missionColor.push_back( red );
725 }
726 }
727
728 for ( int t = 0; t < curMission->getCreatureCount(); t++ ) {
729 snprintf( tmp, TMP_SIZE, _( "Vanquish %s." ), curMission->getCreature( t )->getDisplayName() );
730 if ( curMission->getCreatureHandled( t ) ) {
731 objectiveText.push_back( tmp + string( ". " ) + _( "(completed)" ) );
732 missionColor.push_back( green );
733 } else {
734 objectiveText.push_back( tmp + string( ". " ) + _( "(not yet done)" ) );
735 missionColor.push_back( red );
736 }
737 }
738
739 if ( objectiveText.size() == 0 && curMission->isCompleted() ) {
740 objectiveText.push_back( _( "Special" ) + string( ". " ) + _( "(completed)" ) );
741 missionColor.push_back( green );
742 } else if ( objectiveText.size() == 0 ) {
743 objectiveText.push_back( _( "Special" ) + string( ". " ) + _( "(not yet done)" ) );
744 missionColor.push_back( red );
745 }
746 objectiveList->setLines( objectiveText.begin(), objectiveText.end(), &missionColor[0] );
747 } else {
748 strncpy( missionText, _( "No current mission." ), MISSNTXT_SIZE );
749 }
750 description->setText( missionText );
751 }
752
show()753 void MissionInfoUI::show() {
754 description->setVisible( true );
755 objectiveList->setVisible( true );
756 objectivesLabel->setVisible( true );
757 consoleButton->setVisible( true );
758 }
759
hide()760 void MissionInfoUI::hide() {
761 description->setVisible( false );
762 objectiveList->setVisible( false );
763 objectivesLabel->setVisible( false );
764 consoleButton->setVisible( false );
765 }
766
767