Advanced Strategic Command
attackpanel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * This program is free software; you can redistribute it and/or modify *
4  * it under the terms of the GNU General Public License as published by *
5  * the Free Software Foundation; either version 2 of the License, or *
6  * (at your option) any later version. *
7  * *
8  ***************************************************************************/
9 
10 #include <pgimage.h>
11 #include <pgtooltiphelp.h>
12 
13 #include "attackpanel.h"
14 
15 #include "../paradialog.h"
16 #include "../attack.h"
17 #include "../explosivemines.h"
18 #include "../iconrepository.h"
19 
20 #include "../soundList.h"
21 #include "../gamemap.h"
22 #include "../events.h"
23 #include "../gameoptions.h"
24 #include "../windowing.h"
25 #include "../sdl/graphicsqueue.h"
26 
27 #define USE_COLOR_CONSTANTS
28 #include <pgcolors.h>
29 
30 
32  private:
33  const SDL_Rect dst;
34  Surface& surf;
35 
36  void paint( UnitAttacksSomething& battle )
37  {
38  battle.getAttackingUnit()->typ->paint( surf, SPoint( dst.x, dst.y ), battle.getAttackingUnit()->getOwningPlayer().getPlayerColor() );
39  }
40 
41  public:
42  GetAttackerImage( tfight& battle, Surface& surface, const SDL_Rect& dest ) : dst ( dest ), surf( surface )
43  {
44  battle.visit( *this );
45  };
46 
47  void visit( tunitattacksobject& battle ) { paint(battle); };
48  void visit( tunitattacksbuilding& battle ) { paint(battle); };
49  void visit( tunitattacksunit& battle ) { paint(battle); };
50 
51  void visit( tmineattacksunit& battle )
52  {
53  Mine* m = battle.getFirstMine();
54  if ( m )
55  m->paint( surf, SPoint( dst.x, dst.y ) );
56  }
57 };
58 
59 class GetTargetImage : public FightVisitor {
60  private:
61  const SDL_Rect dst;
62  Surface& surf;
63  public:
64  GetTargetImage( tfight& battle, Surface& surface, const SDL_Rect& dest ) : dst ( dest ), surf( surface )
65  {
66  battle.visit( *this );
67  };
68 
69 
70  void visit( tunitattacksobject& battle )
71  {
72  battle.getTarget()->typ->display( surf, SPoint( dst.x, dst.y ) );
73  };
74 
75  void visit( tmineattacksunit& battle )
76  {
77  battle.getTarget()->typ->paint( surf, SPoint( dst.x, dst.y ), battle.getTarget()->getOwningPlayer().getPlayerColor() );
78  }
79 
80  void visit( tunitattacksbuilding& battle )
81  {
82  battle.getTarget()->paintSingleField( surf, SPoint(dst.x, dst.y), battle.getTarget()->typ->entry );
83  };
84 
85  void visit( tunitattacksunit& battle )
86  {
87  battle.getTarget()->typ->paint( surf, SPoint( dst.x, dst.y ), battle.getTarget()->getOwningPlayer().getPlayerColor() );
88  };
89 };
90 
91 
92 
93 class AttackPanel : public Panel {
94  tfight& engine;
95  int attacker_exp_offensive;
96  int attacker_exp_defensive;
97  int defender_exp_offensive;
98  int defender_exp_defensive;
99  public:
100  AttackPanel ( tfight& engine_ ) ;
101  void setBarGraphValue( const ASCString& widgetName, float fraction ) { Panel::setBargraphValue( widgetName, fraction ); };
102  void setLabelText ( const ASCString& widgetName, int i ) { Panel::setLabelText ( widgetName, i ); };
103  void setLabelText ( const ASCString& widgetName, const ASCString& i ) { Panel::setLabelText ( widgetName, i ); };
104  void dispValue ( const ASCString& name, float value, float maxvalue, PG_Color color );
105  void setBarGraphColor( const ASCString& widgetName, PG_Color color ) { Panel::setBarGraphColor( widgetName, color ); };
106  void painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst);
107  private:
108  void registerSpecialDisplay( const ASCString& name );
109 };
110 
111 
112 
113 AttackPanel::AttackPanel ( tfight& engine_ ) : Panel( PG_Application::GetWidgetById(ASC_PG_App::mainScreenID), PG_Rect(0,0,170,200), "Attack" ), engine( engine_ )
114 {
115  registerSpecialDisplay( "attacker_unit_pic" );
116  registerSpecialDisplay( "defender_unit_pic" );
117  registerSpecialDisplay( "attacker_unitexp" );
118  registerSpecialDisplay( "defender_unitexp" );
119  registerSpecialDisplay( "attacker_level" );
120  registerSpecialDisplay( "defender_level" );
121  registerSpecialDisplay( "attacker_weaponsymbol" );
122  registerSpecialDisplay( "defender_weaponsymbol" );
123  attacker_exp_offensive = engine.av.experience_offensive;
124  attacker_exp_defensive = engine.av.experience_defensive;
125  defender_exp_offensive = engine.dv.experience_offensive;
126  defender_exp_defensive = engine.dv.experience_defensive;
127 }
128 
129 
130 void AttackPanel::registerSpecialDisplay( const ASCString& name )
131 {
132  SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( name, true ) );
133  if ( sdw )
134  sdw->display.connect( sigc::mem_fun( *this, &AttackPanel::painter ));
135 }
136 
137 
138 void AttackPanel::painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst)
139 {
140  Surface s = Surface::Wrap( PG_Application::GetScreen() );
141 
142  if ( name == "attacker_unit_pic" ) {
143  GetAttackerImage( engine, s, dst );
144  return;
145  }
146  if ( name == "defender_unit_pic" ) {
147  GetTargetImage( engine, s, dst );
148  return;
149  }
150  if ( name == "attacker_unitexp" ) {
151  s.Blit( IconRepository::getIcon("experience" + ASCString::toString( engine.getIconIndex( attacker_exp_offensive, true ) ) + ".png"), SPoint(dst.x, dst.y) );
152  return;
153  }
154  if ( name == "defender_unitexp" ) {
155  s.Blit( IconRepository::getIcon("experience" + ASCString::toString( engine.getIconIndex( defender_exp_defensive, false ) ) + ".png"), SPoint(dst.x, dst.y) );
156  return;
157  }
158  if ( name == "attacker_level" && engine.av.height ) {
159  s.Blit( IconRepository::getIcon("height-a" + ASCString::toString(getFirstBit(engine.av.height)) + ".png"), SPoint(dst.x, dst.y) );
160  return;
161  }
162  if ( name == "defender_level" && engine.dv.height ) {
163  s.Blit( IconRepository::getIcon("height-a" + ASCString::toString(getFirstBit(engine.dv.height)) + ".png"), SPoint(dst.x, dst.y) );
164  return;
165  }
166 
167  if ( name == "attacker_weaponsymbol" && engine.av.weapontype >= 0 ) {
168  s.Blit( IconRepository::getIcon(SingleWeapon::getIconFileName( engine.av.weapontype ) + "-small.png"), SPoint(dst.x, dst.y) );
169  return;
170  }
171  if ( name == "defender_weaponsymbol" && engine.dv.weapontype >= 0 ) {
172  s.Blit( IconRepository::getIcon(SingleWeapon::getIconFileName( engine.dv.weapontype ) + "-small.png"), SPoint(dst.x, dst.y) );
173  return;
174  }
175 
176 }
177 
178 
179 void AttackPanel::dispValue ( const ASCString& name, float value, float maxvalue, PG_Color color )
180 {
181  if ( value > 0 ) {
182  setBarGraphColor( name + "bar", color );
183  if ( value > maxvalue )
184  setBarGraphValue( name + "bar", 1 );
185  else
186  setBarGraphValue( name + "bar", value / maxvalue );
187  } else {
188  setBarGraphColor( name + "bar", PG_Colormap::yellow );
189  if ( value < -maxvalue )
190  setBarGraphValue( name + "bar", 1 );
191  else
192  setBarGraphValue( name + "bar", -value / maxvalue );
193  }
194  ASCString s;
195  s.format ( "%d", int(value * 100) );
196  setLabelText( name, s );
197 }
198 
199 
200 
202  private:
203  bool first;
204  tfight& the_battle;
205 
206  void play( UnitAttacksSomething& battle )
207  {
210  false,
211  battle.getAttackingUnit()->getWeapon(battle.av.weapnum)->soundLabel );
212  };
213 
214  public:
215  BattleSoundPlayer( tfight& battle ) : first ( true ), the_battle(battle)
216  {
217  battle.visit( *this );
218  };
219 
220  void playEnd()
221  {
222  first = false;
223  the_battle.visit( *this );
224  }
225 
226  void visit( tunitattacksobject& battle )
227  {
228  if ( first )
229  play( battle );
230  };
231 
232  void visit( tunitattacksbuilding& battle )
233  {
234  if ( first )
235  play( battle );
236  else
237  if ( battle.dv.damage >= 100 )
239  };
240 
241  void visit( tunitattacksunit& battle )
242  {
243  if ( first )
244  play( battle );
245  else {
246  if ( battle.av.damage >= 100 )
248 
249  if ( battle.dv.damage >= 100 )
251 
252  }
253  };
254 
255  void visit( tmineattacksunit& battle )
256  {
257  if ( first )
259  else
260  if ( battle.dv.damage >= 100 )
262  }
263 
264 };
265 
266 const int maxdefenseshown = 2;
267 const int maxattackshown = 2;
268 
273 void waitWithUpdate( int millisecs )
274 {
275  int frameDelay;
276  if ( CGameOptions::Instance()->video.ascframeratelimit > 0 )
277  frameDelay = 100 / CGameOptions::Instance()->video.ascframeratelimit ;
278  else
279  frameDelay = 10;
280 
281  int t = ticker;
282  do {
283  int t2 = ticker;
284  do {
286  } while ( t2 + frameDelay > ticker );
287  postScreenUpdate( PG_Application::GetScreen() );
288  } while ( t + millisecs/20 > ticker );
289 }
290 
291 
292 void showAttackAnimation( tfight& battle, GameMap* actmap, int ad, int dd )
293 {
294 
295  BattleSoundPlayer bsp( battle );
296 
297  auto_ptr<AttackPanel> at ( new AttackPanel(battle));
298 
299  float avd = float( 100 - battle.av.damage )/100;
300  float dvd = float( 100 - battle.dv.damage )/100;
301 
302  PG_Color attackingColor = lighten_Color( actmap->player[battle.getAttackingPlayer()].getColor(), 22 );
303  PG_Color defendingColor = lighten_Color( actmap->player[battle.getDefendingPlayer()].getColor(), 22 );
304 
305  at->setBarGraphValue( "attacker_unitstatusbar", avd );
306  at->setBarGraphColor( "attacker_unitstatusbar", attackingColor );
307 
308  at->setBarGraphValue( "defender_unitstatusbar", dvd );
309  at->setBarGraphColor( "defender_unitstatusbar", defendingColor );
310 
311  at->setLabelText( "attacker_unitstatus", 100 - battle.av.damage );
312  at->setLabelText( "defender_unitstatus", 100 - battle.dv.damage );
313 
314 
315 
316  at->setBarGraphValue( "attacker_hemmingbar", (battle.dv.hemming -1) / 1.4 );
317  at->setBarGraphColor( "attacker_hemmingbar", attackingColor );
318  at->setBarGraphValue( "defender_hemmingbar", (battle.av.hemming -1) / 1.4 );
319  at->setBarGraphColor( "defender_hemmingbar", defendingColor );
320 
321  at->setLabelText( "defender_hemming", "-" );
322  at->setLabelText( "attacker_hemming", int((battle.dv.hemming-1) * 100 ));
323 
324  at->dispValue( "attacker_attackbonus", battle.strength_attackbonus(battle.av.attackbonus), maxattackshown, attackingColor );
325  at->dispValue( "defender_attackbonus", battle.strength_attackbonus(battle.dv.attackbonus), maxattackshown, defendingColor );
326 
327 
328  at->dispValue( "attacker_defencebonus", battle.defense_defensebonus(battle.av.defensebonus), maxattackshown, attackingColor );
329  at->dispValue( "defender_defencebonus", battle.defense_defensebonus(battle.dv.defensebonus), maxattackshown, defendingColor );
330 
331 
332  battle.calc();
333  at->Show();
334 
335 
336  int time1 = CGameOptions::Instance()->attackspeed1;
337  if ( time1 <= 0 )
338  time1 = 30;
339 
340  int time2 = CGameOptions::Instance()->attackspeed2;
341  if ( time2 <= 0 )
342  time2 = 50;
343 
344  int time3 = CGameOptions::Instance()->attackspeed3;
345  if ( time3 <= 0 )
346  time3 = 30;
347 
348  waitWithUpdate( time1*10 );
349 
350 
351 
352  if ( ad != -1 )
353  battle.av.damage = ad;
354 
355  if ( dd != -1 )
356  battle.dv.damage = dd;
357 
358 
359  float avd2 = float( 100 - battle.av.damage )/100;
360  float dvd2 = float( 100 - battle.dv.damage )/100;
361 
362  int starttime = ticker;
363  while ( ticker < starttime + time2 ) {
364  float p = float(ticker - starttime ) / time2;
365 
366  at->setBarGraphValue( "attacker_unitstatusbar", avd + (avd2-avd) * p );
367  at->setBarGraphValue( "defender_unitstatusbar", dvd + (dvd2-dvd) * p );
368 
369  at->setLabelText( "attacker_unitstatus", int( 100.0 * (avd + (avd2-avd) * p ) + 0.5) );
370  at->setLabelText( "defender_unitstatus", int( 100.0 * (dvd + (dvd2-dvd) * p ) + 0.5) );
371  at->Update();
372 
374  }
375 
376  at->setBarGraphValue( "attacker_unitstatusbar", avd2 );
377  at->setBarGraphValue( "defender_unitstatusbar", dvd2 );
378  at->Update();
379 
380  bsp.playEnd();
381 
382  waitWithUpdate( time3*10 );
383 }
384 
void visit(tunitattacksbuilding &battle)
const int maxdefenseshown
int defensebonus
Definition: attack.h:100
AttackPanel(tfight &engine_)
BattleSoundPlayer(tfight &battle)
Building * getTarget()
Definition: attack.h:205
DisplayHook display
Definition: paradialog.h:182
const BuildingType * typ
Definition: buildings.h:48
struct tfight::tavalues dv
void dispValue(const ASCString &name, float value, float maxvalue, PG_Color color)
struct tfight::tavalues av
void paintSingleField(Surface &s, SPoint imgpos, BuildingType::LocalCoordinate pos) const
Definition: buildings.cpp:198
virtual void visit(FightVisitor &visitor)=0
int getFirstBit(int zahl)
Count the number of zero bits on the LSB side of "zahl".
Definition: misc.cpp:45
GetAttackerImage(tfight &battle, Surface &surface, const SDL_Rect &dest)
Definition: attackpanel.cpp:42
float hemming
Definition: attack.h:102
static SoundList & getInstance()
Definition: soundList.cpp:60
Vehicle * getTarget()
Definition: attack.h:168
virtual int getDefendingPlayer()=0
Vehicle * getTarget()
Definition: attack.h:248
void setBarGraphColor(const ASCString &widgetName, PG_Color color)
PlayerColor getPlayerColor() const
Definition: player.cpp:268
void visit(tunitattacksunit &battle)
void visit(tunitattacksbuilding &battle)
Definition: attackpanel.cpp:48
void display(Surface &surface, const SPoint &pos) const
displays the objecttype at x/y on the screen
Definition: objecttype.cpp:289
virtual int getAttackingPlayer()=0
void waitWithUpdate(int millisecs)
Waits the given time, but still updates the screen.
ASCString & format(const charT *pFormat,...)
Definition: ascstring.cpp:78
const int maxattackshown
int getIconIndex(int experience, bool offensive)
Definition: attack.cpp:156
void visit(tunitattacksunit &battle)
Definition: attackpanel.cpp:49
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
void paint(Surface &surf, SPoint pos) const
display the mine
void calc(void)
Performs the calculation of the attack. The result is only stored in the av and dv structures and is ...
Definition: attack.cpp:178
int experience_offensive
Definition: attack.h:98
int ascframeratelimit
Definition: gameoptions.h:243
int getScalarWeaponType(void) const
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
Player & getOwningPlayer() const
returns the player this vehicle/building belongs to
void showAttackAnimation(tfight &battle, GameMap *actmap, int ad, int dd)
Performs the calculation of the attack and displays the result on screen.
void setBarGraphValue(const ASCString &widgetName, float fraction)
const ObjectType * typ
Definition: objects.h:48
void visit(tunitattacksobject &battle)
void setBarGraphColor(const ASCString &widgetName, PG_Color color, PG_Widget *parent=NULL)
Definition: windowing.cpp:801
void painter(const PG_Rect &src, const ASCString &name, const PG_Rect &dst)
void setBargraphValue(const ASCString &widgetName, float fraction, PG_Widget *parent=NULL)
Definition: windowing.cpp:790
static ASCString getIconFileName(int weaponType)
ASCString killSoundLabel
this label can select a special sound to be played when this unit is killed
Definition: vehicletype.h:277
int attackspeed1
are fields marked that a unit could move to if there was no other unit standing
Definition: gameoptions.h:84
void setLabelText(const ASCString &widgetName, int i)
void visit(tunitattacksunit &battle)
Definition: attackpanel.cpp:85
DI_Color getColor() const
Definition: player.cpp:249
int releasetimeslice(void)
Definition: events.cpp:209
void visit(tunitattacksobject &battle)
Definition: attackpanel.cpp:70
void visit(tunitattacksobject &battle)
Definition: attackpanel.cpp:47
void visit(tunitattacksbuilding &battle)
Definition: attackpanel.cpp:80
SDLmm::SPoint SPoint
Definition: surface.h:27
Player player[9]
Definition: gamemap.h:253
static CGameOptions * Instance()
returns the only Instance
Definition: gameoptions.cpp:38
Sound * playSound(Sample snd, int subType=0, bool looping=false, const ASCString &label="")
Definition: soundList.cpp:265
sigc::signal< void, const SDL_Surface * > postScreenUpdate
Definition: events.cpp:392
float strength_attackbonus(int abonus)
Definition: attack.cpp:143
Definition: attack.h:83
int attackspeed3
second delay in attack display
Definition: gameoptions.h:90
const VehicleType * typ
Definition: vehicle.h:83
void visit(tmineattacksunit &battle)
static Surface & getIcon(const ASCString &name)
void paint(Surface &s, SPoint pos, const PlayerColor &player, int direction=0) const
struct CGameOptions::@11 video
GameMap * actmap
Definition: spfst.cpp:64
void visit(tmineattacksunit &battle)
Definition: attackpanel.cpp:75
int experience_defensive
Definition: attack.h:99
static Surface Wrap(SDL_Surface *surface)
Definition: surface.h:76
int attackspeed2
speed of moving bars in attack display
Definition: gameoptions.h:87
void visit(tmineattacksunit &battle)
Definition: attackpanel.cpp:51
Vehicle * getAttackingUnit()
Definition: attack.h:137
const int yellow
Definition: basegfx.h:101
float defense_defensebonus(int defensebonus)
Definition: attack.cpp:150
Mine * getFirstMine()
Definition: attack.cpp:716
GetTargetImage(tfight &battle, Surface &surface, const SDL_Rect &dest)
Definition: attackpanel.cpp:64
SDLmm::Color lighten_Color(SDLmm::Color color, int factor16)
Definition: lighten.h:37
LocalCoordinate entry
the position of the entrance, which is the field of the building where units can enter and leave ...
Definition: buildingtype.h:74
const SingleWeapon * getWeapon(unsigned weaponNum) const
Returns the SingleWeapon corresponding to the weaponNum for this vehicle.
Definition: vehicle.cpp:1760
void setLabelText(const ASCString &widgetName, const ASCString &text, PG_Widget *parent=NULL)
Definition: windowing.cpp:685
ASCString soundLabel
Definition: vehicletype.h:147
void setLabelText(const ASCString &widgetName, const ASCString &i)
The map. THE central structure of ASC, which holds everything not globally available together...
Definition: gamemap.h:182
volatile int ticker
Definition: events.cpp:234
Object * getTarget()
Definition: attack.h:280