attackpanel.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  ***************************************************************************/
00009 
00010 #include <pgimage.h>
00011 #include <pgtooltiphelp.h>
00012 
00013 #include "attackpanel.h"
00014 
00015 #include "../paradialog.h"
00016 #include "../attack.h"
00017 #include "../explosivemines.h"
00018 #include "../iconrepository.h"
00019 
00020 #include "../soundList.h"
00021 #include "../gamemap.h"
00022 #include "../events.h"
00023 #include "../gameoptions.h"
00024 #include "../windowing.h"
00025 #include "../sdl/graphicsqueue.h"
00026 
00027 #define USE_COLOR_CONSTANTS
00028 #include <pgcolors.h>
00029 
00030 
00031 class GetAttackerImage : public FightVisitor {
00032    private:
00033       const SDL_Rect dst;
00034       Surface& surf;
00035 
00036       void paint( UnitAttacksSomething& battle )
00037       {
00038          battle.getAttackingUnit()->typ->paint( surf, SPoint( dst.x, dst.y ), battle.getAttackingUnit()->getOwningPlayer().getPlayerColor() );
00039       }
00040       
00041    public:
00042       GetAttackerImage( tfight& battle, Surface& surface, const SDL_Rect& dest ) : dst ( dest ), surf( surface )
00043       {
00044          battle.visit( *this );
00045       };
00046       
00047       void visit( tunitattacksobject& battle )  { paint(battle); };
00048       void visit( tunitattacksbuilding& battle )  { paint(battle); };
00049       void visit( tunitattacksunit& battle )  { paint(battle); };
00050       
00051       void visit( tmineattacksunit& battle )
00052       {
00053          Mine* m = battle.getFirstMine();
00054          if ( m )
00055             m->paint( surf, SPoint( dst.x, dst.y ) );
00056       }
00057 };
00058 
00059 class GetTargetImage : public FightVisitor {
00060    private:
00061       const SDL_Rect dst;
00062       Surface& surf;
00063    public:
00064       GetTargetImage( tfight& battle, Surface& surface, const SDL_Rect& dest ) : dst ( dest ), surf( surface )
00065       {
00066          battle.visit( *this );
00067       };
00068 
00069       
00070       void visit( tunitattacksobject& battle )
00071       {
00072          battle.getTarget()->typ->display( surf, SPoint( dst.x, dst.y ) );
00073       };
00074       
00075       void visit( tmineattacksunit& battle )
00076       {
00077          battle.getTarget()->typ->paint( surf, SPoint( dst.x, dst.y ), battle.getTarget()->getOwningPlayer().getPlayerColor() );
00078       }
00079       
00080       void visit( tunitattacksbuilding& battle )
00081       {
00082          battle.getTarget()->paintSingleField( surf, SPoint(dst.x, dst.y), battle.getTarget()->typ->entry );
00083       };
00084       
00085       void visit( tunitattacksunit& battle )
00086       {
00087          battle.getTarget()->typ->paint( surf, SPoint( dst.x, dst.y ), battle.getTarget()->getOwningPlayer().getPlayerColor() );
00088       };
00089 };
00090 
00091 
00092 
00093 class AttackPanel : public Panel {
00094        tfight& engine;
00095        int attacker_exp;
00096        int defender_exp;
00097    public:
00098       AttackPanel ( tfight& engine_ ) ;
00099       void setBarGraphValue( const ASCString& widgetName, float fraction ) { Panel::setBargraphValue( widgetName, fraction ); };
00100       void setLabelText ( const ASCString& widgetName, int i ) { Panel::setLabelText ( widgetName, i ); };
00101       void setLabelText ( const ASCString& widgetName, const ASCString& i ) { Panel::setLabelText ( widgetName, i ); };
00102       void dispValue ( const ASCString& name, float value, float maxvalue, PG_Color color );
00103       void setBarGraphColor( const ASCString& widgetName, PG_Color color ) { Panel::setBarGraphColor( widgetName, color ); };
00104       void painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst);
00105    private:
00106       void registerSpecialDisplay( const ASCString& name );
00107 };
00108 
00109 
00110 
00111 AttackPanel::AttackPanel ( tfight& engine_ ) : Panel( PG_Application::GetWidgetById(ASC_PG_App::mainScreenID), PG_Rect(0,0,170,200), "Attack" ), engine( engine_ )
00112 {
00113    registerSpecialDisplay( "attacker_unit_pic" );
00114    registerSpecialDisplay( "defender_unit_pic" );
00115    registerSpecialDisplay( "attacker_unitexp" );
00116    registerSpecialDisplay( "defender_unitexp" );
00117    registerSpecialDisplay( "attacker_level" );
00118    registerSpecialDisplay( "defender_level" );
00119    registerSpecialDisplay( "attacker_weaponsymbol" );
00120    registerSpecialDisplay( "defender_weaponsymbol" );
00121    attacker_exp = engine.av.experience;
00122    defender_exp = engine.dv.experience;
00123 }
00124 
00125 
00126 void AttackPanel::registerSpecialDisplay( const ASCString& name )
00127 {
00128    SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( name, true ) );
00129    if ( sdw )
00130       sdw->display.connect( SigC::slot( *this, &AttackPanel::painter ));
00131 }
00132 
00133 
00134 void AttackPanel::painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst)
00135 {
00136    Surface s = Surface::Wrap( PG_Application::GetScreen() );
00137 
00138    if ( name  == "attacker_unit_pic" ) {
00139       GetAttackerImage( engine, s, dst );
00140       return;
00141    }
00142    if ( name  == "defender_unit_pic" ) {
00143       GetTargetImage( engine, s, dst );
00144       return;
00145    }
00146    if ( name  == "attacker_unitexp" ) {
00147       s.Blit( IconRepository::getIcon("experience" + ASCString::toString(attacker_exp) + ".png"), SPoint(dst.x, dst.y) );
00148       return;
00149    }
00150    if ( name  == "defender_unitexp" ) {
00151       s.Blit( IconRepository::getIcon("experience" + ASCString::toString(defender_exp) + ".png"), SPoint(dst.x, dst.y) );
00152       return;
00153    }
00154    if ( name  == "attacker_level" && engine.av.height ) {
00155       s.Blit( IconRepository::getIcon("height-a" + ASCString::toString(getFirstBit(engine.av.height)) + ".png"), SPoint(dst.x, dst.y) );
00156       return;
00157    }
00158    if ( name  == "defender_level" && engine.dv.height ) {
00159       s.Blit( IconRepository::getIcon("height-a" + ASCString::toString(getFirstBit(engine.dv.height)) + ".png"), SPoint(dst.x, dst.y) );
00160       return;
00161    }
00162 
00163    if ( name  == "attacker_weaponsymbol" && engine.av.weapontype >= 0  ) {
00164       s.Blit( IconRepository::getIcon(SingleWeapon::getIconFileName( engine.av.weapontype ) + "-small.png"), SPoint(dst.x, dst.y) );
00165       return;
00166    }
00167    if ( name  == "defender_weaponsymbol" && engine.dv.weapontype >= 0  ) {
00168       s.Blit( IconRepository::getIcon(SingleWeapon::getIconFileName( engine.dv.weapontype ) + "-small.png"), SPoint(dst.x, dst.y) );
00169       return;
00170    }
00171 
00172 }
00173 
00174 
00175 void AttackPanel::dispValue ( const ASCString& name, float value, float maxvalue, PG_Color color )
00176 {
00177    if ( value > 0 ) {
00178       setBarGraphColor( name + "bar", color );
00179       if ( value > maxvalue )
00180          setBarGraphValue( name + "bar", 1 );
00181       else
00182          setBarGraphValue( name + "bar", value / maxvalue );
00183    } else {
00184       setBarGraphColor( name + "bar", PG_Colormap::yellow );
00185       if ( value < -maxvalue )
00186          setBarGraphValue( name + "bar", 1 );
00187       else
00188          setBarGraphValue( name + "bar", -value / maxvalue );
00189    }
00190    ASCString s;
00191    s.format ( "%d", int(value * 100) );
00192    setLabelText( name, s );
00193 }
00194 
00195 
00196 
00197 class BattleSoundPlayer : public FightVisitor {
00198    private:
00199       bool first;
00200       tfight& the_battle;
00201             
00202       void play( UnitAttacksSomething& battle )
00203       {
00204          SoundList::getInstance().playSound ( SoundList::shooting,
00205                                               battle.getAttackingUnit()->getWeapon(battle.av.weapnum)->getScalarWeaponType(),
00206                                               false,
00207                                               battle.getAttackingUnit()->getWeapon(battle.av.weapnum)->soundLabel );
00208       };
00209       
00210    public:
00211       BattleSoundPlayer( tfight& battle ) : first ( true ), the_battle(battle)
00212       {
00213          battle.visit( *this );
00214       };
00215 
00216       void playEnd()
00217       {
00218          first = false;
00219          the_battle.visit( *this );
00220       }
00221       
00222       void visit( tunitattacksobject& battle )
00223       {
00224          if ( first )
00225             play( battle );
00226       };
00227       
00228       void visit( tunitattacksbuilding& battle )
00229       {
00230          if ( first )
00231             play( battle );
00232          else
00233             if ( battle.dv.damage >= 100 )
00234                SoundList::getInstance().playSound( SoundList::buildingCollapses );
00235       };
00236       
00237       void visit( tunitattacksunit& battle )
00238       {
00239          if ( first )
00240             play( battle );
00241          else {
00242             if ( battle.av.damage >= 100  )
00243                SoundList::getInstance().playSound( SoundList::unitExplodes , 0, false, battle.getAttackingUnit()->typ->killSoundLabel );
00244             
00245             if ( battle.dv.damage >= 100 )
00246                SoundList::getInstance().playSound( SoundList::unitExplodes , 0, false, battle.getTarget()->typ->killSoundLabel );
00247 
00248          }
00249       };
00250       
00251       void visit( tmineattacksunit& battle )
00252       {
00253          if ( first )
00254             SoundList::getInstance().playSound( SoundList::shooting , 1 );
00255          else
00256             if ( battle.dv.damage >= 100 )
00257                SoundList::getInstance().playSound( SoundList::unitExplodes , 0, false, battle.getTarget()->typ->killSoundLabel );
00258       }
00259       
00260 };
00261 
00262 const int maxdefenseshown = 2;
00263 const int maxattackshown = 2;
00264 
00269 void waitWithUpdate( int millisecs ) 
00270 {
00271    int frameDelay;
00272    if ( CGameOptions::Instance()->video.ascframeratelimit  > 0 )
00273       frameDelay = 100 / CGameOptions::Instance()->video.ascframeratelimit ;
00274    else
00275       frameDelay = 10;
00276    
00277    int t = ticker;
00278    do {
00279       int t2 = ticker;
00280       do {
00281          releasetimeslice();
00282       } while ( t2 + frameDelay > ticker );
00283       postScreenUpdate( PG_Application::GetScreen() );
00284    } while ( t + millisecs/20 > ticker ); 
00285 }
00286 
00287 
00288 void showAttackAnimation( tfight& battle, GameMap* actmap, int ad, int dd )
00289 {
00290 
00291    BattleSoundPlayer bsp( battle );
00292    
00293    auto_ptr<AttackPanel> at ( new AttackPanel(battle));
00294 
00295    float avd = float( 100 - battle.av.damage )/100;
00296    float dvd = float( 100 - battle.dv.damage )/100;
00297 
00298    PG_Color attackingColor = lighten_Color( actmap->player[battle.getAttackingPlayer()].getColor(), 22 );
00299    PG_Color defendingColor = lighten_Color( actmap->player[battle.getDefendingPlayer()].getColor(), 22 );
00300 
00301    at->setBarGraphValue( "attacker_unitstatusbar", avd );
00302    at->setBarGraphColor( "attacker_unitstatusbar", attackingColor );
00303 
00304    at->setBarGraphValue( "defender_unitstatusbar", dvd );
00305    at->setBarGraphColor( "defender_unitstatusbar", defendingColor );
00306 
00307    at->setLabelText( "attacker_unitstatus", 100 - battle.av.damage );
00308    at->setLabelText( "defender_unitstatus", 100 - battle.dv.damage );
00309 
00310 
00311 
00312    at->setBarGraphValue( "attacker_hemmingbar", (battle.dv.hemming -1) / 1.4 );
00313    at->setBarGraphColor( "attacker_hemmingbar", attackingColor );
00314    at->setBarGraphValue( "defender_hemmingbar", (battle.av.hemming -1) / 1.4 );
00315    at->setBarGraphColor( "defender_hemmingbar", defendingColor );
00316 
00317    at->setLabelText( "defender_hemming", "-" );
00318    at->setLabelText( "attacker_hemming", int((battle.dv.hemming-1) * 100 ));
00319 
00320    at->dispValue( "attacker_attackbonus", battle.strength_attackbonus(battle.av.attackbonus), maxattackshown, attackingColor );
00321    at->dispValue( "defender_attackbonus", battle.strength_attackbonus(battle.dv.attackbonus), maxattackshown, defendingColor );
00322 
00323 
00324    at->dispValue( "attacker_defencebonus", battle.defense_defensebonus(battle.av.defensebonus), maxattackshown, attackingColor );
00325    at->dispValue( "defender_defencebonus", battle.defense_defensebonus(battle.dv.defensebonus), maxattackshown, defendingColor );
00326 
00327 
00328    battle.calc();
00329    at->Show();
00330 
00331 
00332    int time1 = CGameOptions::Instance()->attackspeed1;
00333    if ( time1 <= 0 )
00334       time1 = 30;
00335 
00336    int time2 = CGameOptions::Instance()->attackspeed2;
00337    if ( time2 <= 0 )
00338       time2 = 50;
00339 
00340    int time3 = CGameOptions::Instance()->attackspeed3;
00341    if ( time3 <= 0 )
00342       time3 = 30;
00343 
00344    waitWithUpdate( time1*10 );
00345 
00346 
00347 
00348    if ( ad != -1 )
00349       battle.av.damage = ad;
00350 
00351    if ( dd != -1 )
00352       battle.dv.damage = dd;
00353 
00354 
00355    float avd2 = float( 100 - battle.av.damage )/100;
00356    float dvd2 = float( 100 - battle.dv.damage )/100;
00357 
00358    int starttime = ticker;
00359    while ( ticker < starttime + time2 ) {
00360       float p = float(ticker - starttime ) / time2;
00361 
00362       at->setBarGraphValue( "attacker_unitstatusbar", avd + (avd2-avd) * p );
00363       at->setBarGraphValue( "defender_unitstatusbar", dvd + (dvd2-dvd) * p );
00364 
00365       at->setLabelText( "attacker_unitstatus", int( 100.0 * (avd + (avd2-avd) * p )) );
00366       at->setLabelText( "defender_unitstatus", int( 100.0 * (dvd + (dvd2-dvd) * p )) );
00367       at->Update();
00368 
00369       releasetimeslice();
00370    }
00371 
00372    at->setBarGraphValue( "attacker_unitstatusbar", avd2 );
00373    at->setBarGraphValue( "defender_unitstatusbar", dvd2 );
00374    at->Update();
00375 
00376    bsp.playEnd();
00377    
00378    waitWithUpdate( time3*10 );
00379 }
00380 

Generated on Mon May 21 01:26:28 2012 for Advanced Strategic Command by  doxygen 1.5.1