Advanced Strategic Command
attack.cpp
Go to the documentation of this file.
1 
6 /*
7  This file is part of Advanced Strategic Command; http://www.asc-hq.de
8  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
9 
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; see the file COPYING. If not, write to the
22  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23  Boston, MA 02111-1307 USA
24 */
25 
26 
27 
28 #include <stdio.h>
29 #include <math.h>
30 #include <iostream>
31 #include <fstream>
32 
33 #include "typen.h"
34 #include "buildingtype.h"
35 #include "vehicletype.h"
36 #include "attack.h"
37 #include "spfst.h"
38 #include "gameoptions.h"
39 
41 #include "actions/consumeammo.h"
43 #include "actions/inflictdamage.h"
44 #include "actions/removemine.h"
45 #include "actions/removeobject.h"
47 
48 
50 {
51  this->gamemap = gamemap;
52 }
53 
54 bool AttackFormula :: checkHemming ( Vehicle* d_eht, int direc )
55 {
56  Vehicle* s_eht;
57 
58  int x = d_eht->xpos;
59  int y = d_eht->ypos;
60  x += getnextdx ( direc, y);
61  y += getnextdy ( direc );
62  MapField* fld = d_eht->getMap()->getField(x,y);
63 
64  if ( fld )
65  s_eht = fld->vehicle;
66  else
67  s_eht = NULL;
68 
69  if ( !s_eht )
70  return false;
71 
72  if ( s_eht->height >= chtieffliegend || d_eht->height >= chtieffliegend )
73  return false;
74 
75  return attackpossible2n ( s_eht, d_eht );
76 }
77 
78 
80 {
81  const float maxHemmingFactor = 1.4; // = +140% !
82  const float hemming[sidenum-1] = { 4, 11, 16, 11, 4 };
83  const float maxHemmingSum = 46;
84  relDir %= 6;
85  if ( relDir < 0 )
86  relDir += sidenum;
87 
88  if ( relDir == 5 )
89  warningMessage("float AttackFormula :: getHemmingFactor - invalid direction" );
90 
91  return hemming[relDir]*maxHemmingFactor/maxHemmingSum;
92 }
93 
94 
95 float AttackFormula :: strength_hemming ( int ax, int ay, Vehicle* d_eht )
96 {
97  float hemm = 0;
98  int attackDir = getdirection(ax,ay,d_eht->xpos,d_eht->ypos);
99  for ( int i = 0; i < sidenum-1; i++) {
100 
101  int direc = i+1 + (attackDir-sidenum/2);
102  if (direc < 0)
103  direc += sidenum;
104 
105  if (direc >= sidenum)
106  direc -= sidenum;
107 
108  if ( checkHemming (d_eht,direc ))
109  hemm += getHemmingFactor(i);
110  }
111 
112  return hemm + 1;
113 }
114 
115 
117 {
118  return 1 - (2.0 * float(damage) / 300.0);
119 }
120 
121 float AttackFormula :: strength_experience ( int experience )
122 {
123  if ( experience < 0 )
124  return 0.0;
125  // =1+(($B$33-1)*(1-(0.1^(1/$B$34))^B48))
127  float maxExpBonus = ((float)gamemap->getgameparameter( cgp_maxAttackExperienceBonus ))/100.0;
128  float e = maxExpBonus * ( 1.0 - pow( pow( 0.1, 1.0/ninety), experience ));
129  return e;
130 }
131 
132 float AttackFormula :: defense_experience ( int experience )
133 {
134  if ( experience < 0 )
135  return 0.0;
136 
138  float maxExpBonus = ((float)gamemap->getgameparameter( cgp_maxDefenseExperienceBonus ))/100.0;
139  float e = maxExpBonus * (1.0 - pow( pow( 0.1, 1.0/ninety), experience ));
140  return e;
141 }
142 
144 {
145  float a = abonus;
146  return a/8;
147 }
148 
149 
150 float AttackFormula :: defense_defensebonus ( int defensebonus )
151 {
152  float d = defensebonus;
153  return d/8;
154 }
155 
156 int AttackFormula :: getIconIndex( int experience, bool offensive )
157 {
158  int idx;
159  if ( offensive )
161  else
162  idx = (int) (experienceIcons * defense_experience( experience ) / defense_experience( maxunitexperience ));
163 
164  if ( idx >= experienceIcons )
165  idx = experienceIcons-1;
166 
167  if ( idx < 0 )
168  idx = 0;
169 
170  if ( idx > experience )
171  idx = experience;
172 
173  return idx;
174 }
175 
176 
177 
178 void tfight :: calc ( void )
179 {
180  int damagefactor = gamemap->getgameparameter ( cgp_attackPower );
181  const float armordivisor = 5;
182 
183 
184  if ( av.strength ) {
185  float absstrength = float(av.strength )
187  * strength_damage ( av.damage )
188  * dv.hemming;
189 
190  float absdefense = float(dv.armor / armordivisor )
192 
193  int w = int( ceil(dv.damage + absstrength / absdefense * 1000 / damagefactor ));
194 
195  if (dv.damage > w )
196  warningMessage("fatal error at attack: \ndecrease of damage d!");
197 
198  if (dv.damage == w )
199  w = dv.damage+1;
200 
201  if (w > 100)
202  dv.damage = 100;
203  else
204  dv.damage = w;
205 
206  if ( av.weapcount > 0 )
207  av.weapcount--;
208  else
209  av.weapcount = 0;
210 
211 
213 
214  if ( dist <= 10 && dv.strength > 0 )
216 
217  /*
218  if ( dv.damage >= 100 )
219  av.experience_offensive += 1;
220  */
221 
224 
228 
229  }
230 
231  if ( dv.strength ) {
232  float absstrength = float(dv.strength )
234  * strength_damage ( dv.damage ) ;
235 
236  float absdefense = float(av.armor / armordivisor)
238 
239  int w = int( ceil(av.damage + absstrength / absdefense * 1000 / damagefactor ));
240 
241  if (av.damage > w )
242  warningMessage("fatal error at attack: \ndecrease of damage a!");
243 
244  if (w > 100)
245  av.damage = 100;
246  else
247  av.damage = w;
248 
249 
250  if ( dv.weapcount > 0 )
251  dv.weapcount--;
252  else
253  dv.weapcount = 0;
254 
255  /*
256  if ( av.damage >= 100 ) {
257  dv.experience_offensive += 2;
258  if ( dv.experience_offensive > maxunitexperience )
259  dv.experience_offensive = maxunitexperience;
260 
261  } else
262  */
265 
269 
270  }
271 
272  if ( av.kamikaze )
273  av.damage = 100;
274 
275 }
276 
277 
278 
279 tunitattacksunit :: tunitattacksunit ( Vehicle* &attackingunit, Vehicle* &attackedunit, bool respond, int weapon, bool reactionfire )
280  : UnitAttacksSomething( attackingunit->getMap() )
281 {
282  this->reactionfire = reactionfire;
283  setup ( attackingunit, attackedunit, respond, weapon );
284 }
285 
286 void tunitattacksunit :: setup ( Vehicle* &attackingunit, Vehicle* &attackedunit, bool respond, int weapon )
287 {
288  _attackingunit = attackingunit;
289  _attackedunit = attackedunit;
290 
291  _pattackingunit = &attackingunit;
292  _pattackedunit = &attackedunit;
293 
294  dist = beeline ( attackingunit->xpos, attackingunit->ypos, attackedunit->xpos, attackedunit->ypos );
295  int _weapon;
296 
297  if ( weapon == -1 ) {
298  AttackWeap* atw = attackpossible( attackingunit, attackedunit->xpos, attackedunit->ypos );
299  int n = -1;
300  int s = 0;
301  for ( int i = 0; i < atw->count; i++ )
302  if ( atw->strength[i] > s ) {
303  s = atw->strength[i];
304  n = i;
305  }
306 
307  _weapon = atw->num[n];
308 
309  delete atw;
310 
311  } else
312  _weapon = weapon;
313 
314  const SingleWeapon* weap = attackingunit->getWeapon(_weapon);
315 
316 
317  int targetWeather = attackedunit->getMap()->getField( attackedunit->getPosition() )->getWeather();
318 
319  av.strength = int ( ceil( attackingunit->weapstrength[_weapon]
320  * WeapDist::getWeaponStrength(weap, targetWeather, dist, attackingunit->height, attackedunit->height )
321  * attackingunit->typ->weapons.weapon[_weapon].targetingAccuracy[attackedunit->typ->movemalustyp] / 100 ));
322  av.armor = attackingunit->getArmor();
323  av.damage = attackingunit->damage;
326  av.hemming = 1;
327  av.weapnum = _weapon;
328  av.weapcount = attackingunit->ammo [ _weapon ];
329  av.color = attackingunit->getOwner();
330  av.initiative = attackingunit->typ->initiative;
332  av.height = attackingunit->height;
333  av.weapontype = attackingunit->typ->weapons.weapon[ _weapon ].getScalarWeaponType();
334 
335  MapField* field = attackingunit->getMap()->getField ( attackingunit->xpos, attackingunit->ypos );
336 
337  if ( attackingunit->height <= chfahrend ) {
338  // if ( dist <= maxmalq )
339  av.attackbonus = field->getattackbonus();
340  //else
341  // av.attackbonus = 0;
342  av.defensebonus = field->getdefensebonus();
343  } else {
344  av.attackbonus = 0;
345  av.defensebonus = 0;
346  }
347 
348 
349  dv.weapnum = -1;
350  if ( dist <= maxmalq && respond && !av.kamikaze && fieldvisiblenow( field, attackedunit->getOwner()) ) {
351  AttackWeap atw;
352  attackpossible2n ( attackedunit, attackingunit, &atw );
353  int n = -1;
354  int s = 0;
355  for ( int i = 0; i < atw.count; i++ )
356  if ( atw.strength[i] > s ) {
357  s = atw.strength[i];
358  n = i;
359  }
360 
361  if ( n < 0 )
362  respond = 0;
363  else
364  dv.weapnum = atw.num [ n ];
365 
366  } else
367  respond = 0;
368 
369  if ( attackedunit->typ->hasFunction( ContainerBaseType::KamikazeOnly ))
370  respond = 0;
371 
372  if ( respond ) {
373  weap = attackedunit->getWeapon( dv.weapnum );
374 
375 
376  int attackerWeather = attackingunit->getMap()->getField( attackingunit->getPosition() )->getWeather();
377 
378  dv.strength = int ( ceil( attackedunit->weapstrength[ dv.weapnum ]
379  * WeapDist::getWeaponStrength(weap, attackerWeather, dist, attackedunit->height, attackingunit->height )
380  * attackedunit->typ->weapons.weapon[ dv.weapnum ].targetingAccuracy[attackingunit->typ->movemalustyp] / 100 ));
381  field = attackingunit->getMap()->getField ( attackedunit->xpos, attackedunit->ypos );
382  dv.attackbonus = field->getattackbonus();
383  _respond = 1;
384 
385  dv.weapcount = attackedunit->ammo [ dv.weapnum ];
387 
388  } else {
389  dv.strength = 0;
390  dv.attackbonus = 0;
391  _respond = 0;
392  }
393 
394 
395  dv.armor = attackedunit->getArmor();
396  dv.damage = attackedunit->damage;
399  if ( dist <= maxmalq && attackingunit->height < chtieffliegend )
400  dv.hemming = strength_hemming ( attackingunit->xpos, attackingunit->ypos, attackedunit );
401  else
402  dv.hemming = 1;
403 
404 
405  if ( attackedunit->height <= chfahrend )
406  dv.defensebonus = attackedunit->getMap()->getField ( attackedunit->xpos, attackedunit->ypos ) -> getdefensebonus();
407  else
408  dv.defensebonus = 0;
409 
410  dv.color = attackedunit->getOwner();
411  dv.initiative = attackedunit->typ->initiative;
412  dv.kamikaze = 0;
413  dv.height = attackedunit->height;
414 }
415 
416 
417 void log( const Vehicle* attacker, const Vehicle* attackee )
418 {
419  if( CGameOptions::Instance()->logKillsToConsole ) {
420  static bool header = false;
421  ASCString msg;
422  if ( !header ) {
423  msg += "# Attacked player; Attacking player ; attacked unit type id ; attacked unit type name ; attacked unit offensive experience ; turn \n";
424  header = true;
425  }
426 
427  msg += ASCString::toString(attackee->getOwner()) + ";"
428  + ASCString::toString(attacker->getOwner()) + ";"
429  + ASCString::toString(attackee->typ->id) + ";"
430  + attackee->typ->name + ";"
431  + ASCString::toString(attackee->getExperience_offensive()) + ";"
432  + ASCString::toString(attacker->getMap()->time.turn()) + "\n" ;
433 
434  std::cout << msg;
435 #ifdef WIN32
436  ASCString filename = constructFileName( 0, "", "kills.txt");
437  std::ofstream outfile;
438 
439  outfile.open( filename.c_str(), std::ios_base::app);
440  outfile << msg;
441 #endif
442  }
443 }
444 
446 {
447  int nwid = _attackingunit->networkid;
448  GameMap* map = _attackingunit->getMap();
449 
450  if ( !reactionfire ) {
452  a->execute ( context );
453 
455  a2->execute ( context );
456  }
457 
459  b->execute ( context );
460 
461  _attackingunit->postAttack( reactionfire, context );
462 
463  GameAction* c = new RegisterUnitRFTarget( map, nwid, av.weapnum, _attackedunit->networkid );
464  c->execute ( context );
465 
466  if ( _respond ) {
468  d->execute ( context );
469 
470  GameAction* e = new ConsumeAmmo( _attackedunit, _attackedunit->typ->weapons.weapon[dv.weapnum].getScalarWeaponType(), dv.weapnum, _attackedunit->ammo[ dv.weapnum ] - dv.weapcount );
471  e->execute ( context );
472  }
473 
474  if ( !reactionfire ) {
476  d2->execute ( context );
477  }
478 
479  if( av.damage >= 100 )
480  log ( _attackedunit, _attackingunit );
481 
482  if( dv.damage >= 100 )
483  log ( _attackingunit, _attackedunit );
484 
486  f->execute ( context );
487 
488  GameAction* g = new InflictDamage( _attackedunit, dv.damage - _attackedunit->damage );
489  g->execute ( context );
490 
491 
492  /* If the attacking vehicle was destroyed, remove it */
493  if ( av.damage >= 100 ) {
494  *_pattackingunit = NULL;
495  }
496 
497  /* If the attacked vehicle was destroyed, remove it */
498  if ( dv.damage >= 100 ) {
499  *_pattackedunit = NULL;
500  }
501 }
502 
503 
504 
505 
506 
507 
508 
509 tunitattacksbuilding :: tunitattacksbuilding ( Vehicle* attackingunit, int x, int y, int weapon )
510  : UnitAttacksSomething( attackingunit->getMap() )
511 {
512  setup ( attackingunit, x, y, weapon );
513 }
514 
515 
516 void tunitattacksbuilding :: setup ( Vehicle* attackingunit, int x, int y, int weapon )
517 {
518  _attackingunit = attackingunit;
519  _x = x;
520  _y = y;
521  _attackedbuilding = attackingunit->getMap()->getField ( x, y ) -> building;
522 
523  dist = beeline ( attackingunit->xpos, attackingunit->ypos, x, y );
524  int _weapon;
525 
526  if ( weapon == -1 ) {
527  AttackWeap* atw = attackpossible( attackingunit, x, y );
528  int n = -1;
529  int s = 0;
530  for ( int i = 0; i < atw->count; i++ )
531  if ( atw->strength[i] > s ) {
532  s = atw->strength[i];
533  n = i;
534  }
535 
536  _weapon = atw->num[n];
537 
538  delete atw;
539  } else
540  _weapon = weapon;
541 
542  const SingleWeapon *weap = &attackingunit->typ->weapons.weapon[_weapon];
543 
544  int targetWeather = attackingunit->getMap()->getField(x,y)->getWeather();
545 
546  av.strength = int (ceil( attackingunit->weapstrength[_weapon]
547  * WeapDist::getWeaponStrength(weap, targetWeather, dist, attackingunit->height, _attackedbuilding->typ->height )
548  * attackingunit->typ->weapons.weapon[_weapon].targetingAccuracy[cmm_building] / 100 ));
549 
550  av.armor = attackingunit->getArmor();
551  av.damage = attackingunit->damage;
554  av.hemming = 1;
555  av.weapnum = _weapon;
556  av.weapcount = attackingunit->ammo [ _weapon ];
557  av.weapontype = attackingunit->typ->weapons.weapon[ _weapon ].getScalarWeaponType();
558  av.color = attackingunit->getOwner();
559  av.initiative = attackingunit->typ->initiative;
561  av.height = attackingunit->height;
562 
563  MapField* field = attackingunit->getMap()->getField ( attackingunit->xpos, attackingunit->ypos );
564 
565  if ( attackingunit->height <= chfahrend ) {
566  av.defensebonus = field->getdefensebonus();
567  // if ( dist <= maxmalq )
568  av.attackbonus = field->getattackbonus();
569  //else
570  // av.attackbonus = 0;
571  } else {
572  av.defensebonus = 0;
573  av.attackbonus = 0;
574  }
575 
576 
577  dv.strength = 0;
578  dv.attackbonus = 0;
579 
580 
581  dv.armor = _attackedbuilding->getArmor();
582  dv.damage = _attackedbuilding->damage;
585  dv.hemming = 1;
586  dv.weapnum = -1;
587 
588  dv.defensebonus = 0; // getfield ( x, y ) -> getdefensebonus();
589  dv.color = _attackedbuilding->getOwner();
590  dv.initiative = 0;
591  dv.kamikaze = 0;
592  dv.height = _attackedbuilding->typ->height;
593 }
594 
595 
597 {
599  b->execute ( context );
600 
601  _attackingunit->postAttack( false, context );
602 
604  f->execute ( context );
605 
606  GameAction* g = new InflictDamage( _attackedbuilding, dv.damage - _attackedbuilding->damage );
607  g->execute ( context );
608 }
609 
610 
611 
612 tmineattacksunit :: tmineattacksunit ( const MapCoordinate& mineposition, int minenum, Vehicle* &attackedunit )
613  : tfight( attackedunit->getMap() )
614 {
615  setup ( mineposition, minenum, attackedunit );
616 }
617 
618 void tmineattacksunit :: setup ( const MapCoordinate& position, int minenum, Vehicle* &attackedunit )
619 {
620  this->position = position;
621 
622  MapField* mineposition = attackedunit->getMap()->getField( position );
623 
624  if ( mineposition->mines.empty() )
625  errorMessage(" tmineattacksunit :: setup \n no mine to attack !\n" );
626 
627  if ( attackedunit->height >= chtieffliegend )
628  errorMessage(" tmineattacksunit :: setup \n mine attacks flying unit!\n" );
629 
630  dist = 10;
631 
632  _mineposition = mineposition;
633  _attackedunit = attackedunit;
634  _pattackedunit = &attackedunit;
635 
636 
637  _minenum = minenum;
638 
639  if ( minenum == -1 ) {
640  int cnt = 1;
641  av.strength = 0;
642  for ( MapField::MineContainer::iterator m = mineposition->mines.begin(); m != mineposition->mines.end(); m++ )
643  if ( m->attacksunit ( attackedunit )) {
644  int strength = m->strength;
645  if ( m->type == cmantipersonnelmine && (attackedunit->typ->movemalustyp == cmm_trooper ) )
646  strength *= 2;
647 
648  for ( int j = 1; j < cnt; j++ )
649  strength = strength * 2 / 3;
650 
651  av.strength += strength;
652  cnt++;
653  }
654  } else {
655  Mine& m = mineposition->getMine ( minenum );
656  av.strength = m.strength;
657  if ( m.type == cmantipersonnelmine && (attackedunit->typ->movemalustyp == cmm_trooper ) )
658  av.strength *= 2;
659  }
660 
661  av.armor = 1;
662  av.damage = 0;
665  av.defensebonus = 0;
666  av.hemming = 1;
667  av.weapnum = 0;
668  av.weapcount = 1;
669  av.color = 8;
670  av.initiative = 256;
671  av.attackbonus = 8;
672  av.kamikaze = 0;
673  av.height = 0;
675 
676  dv.strength = 0;
677  dv.armor = attackedunit->getArmor();
678  dv.damage = attackedunit->damage;
681  dv.defensebonus = 0;
682  dv.hemming = 1;
683  dv.weapnum = 0;
684  dv.weapcount = 0;
685  dv.color = attackedunit->getOwner();
686  dv.initiative = attackedunit->typ->initiative;
687  dv.attackbonus = 0;
688  dv.kamikaze = 0;
689  dv.height = attackedunit->height;
690 }
691 
692 
694 {
695  vector<GameAction*> actions;
696  if ( _minenum == -1 ) {
697  for ( MapField::MineContainer::iterator m = _mineposition->mines.begin(); m != _mineposition->mines.end(); ++m)
698  if ( m->attacksunit ( _attackedunit ))
699  actions.push_back ( new RemoveMine(_attackedunit->getMap(), position, m->identifier));
700  } else {
701  int counter = 0;
702  for ( MapField::MineContainer::iterator m = _mineposition->mines.begin(); m != _mineposition->mines.end(); ++m, ++counter)
703  if ( counter == _minenum )
704  actions.push_back ( new RemoveMine(_attackedunit->getMap(), position, m->identifier));
705  }
706 
707  for ( vector<GameAction*>::iterator i = actions.begin(); i != actions.end(); ++i )
708  (*i)->execute( context );
709 
710 
711  (new InflictDamage( _attackedunit, dv.damage - _attackedunit->damage ))->execute ( context );
712 
713 }
714 
715 
717 {
718  if ( _mineposition && _mineposition->mines.size() )
719  return &( * _mineposition->mines.begin() );
720  else
721  return NULL;
722 }
723 
724 
725 
726 tunitattacksobject :: tunitattacksobject ( Vehicle* attackingunit, int obj_x, int obj_y, int weapon )
727  : UnitAttacksSomething( attackingunit->getMap() )
728 {
729  setup ( attackingunit, obj_x, obj_y, weapon );
730 }
731 
732 void tunitattacksobject :: setup ( Vehicle* attackingunit, int obj_x, int obj_y, int weapon )
733 {
734 
735  _x = obj_x;
736  _y = obj_y;
737 
738  targetField = attackingunit->getMap()->getField ( obj_x, obj_y );
739 
740  _attackingunit = attackingunit;
741 
742  dist = beeline ( attackingunit->xpos, attackingunit->ypos, obj_x, obj_y );
743 
744  for ( MapField::ObjectContainer::reverse_iterator o = targetField->objects.rbegin(); o != targetField->objects.rend(); o++ )
745  if ( o->typ->armor > 0 ) {
746  _obji = &(*o);
747  break;
748  }
749 
750  int _weapon;
751 
752  if ( weapon == -1 ) {
753 
754  AttackWeap* atw = attackpossible( attackingunit, obj_x, obj_y );
755  int n = -1;
756  int s = 0;
757  for ( int i = 0; i < atw->count; i++ )
758  if ( atw->strength[i] > s ) {
759  s = atw->strength[i];
760  n = i;
761  }
762 
763  _weapon = atw->num[n];
764 
765  delete atw;
766 
767  } else
768  _weapon = weapon;
769 
770  const SingleWeapon *weap = &attackingunit->typ->weapons.weapon[_weapon];
771  av.strength = int ( ceil( attackingunit->weapstrength[_weapon]
772  * WeapDist::getWeaponStrength(weap, targetField->getWeather(), dist, attackingunit->height, _obji->typ->getEffectiveHeight() )
773  * attackingunit->typ->weapons.weapon[_weapon].targetingAccuracy[cmm_building] / 100 ));
774 
775  av.armor = attackingunit->getArmor();
776  av.damage = attackingunit->damage;
779  av.weapnum = _weapon;
780  av.weapcount = attackingunit->ammo [ _weapon ];
782  av.height = attackingunit->height;
783  av.weapontype = attackingunit->typ->weapons.weapon[ _weapon ].getScalarWeaponType();
784 
785  MapField* field2 = attackingunit->getMap()->getField ( attackingunit->xpos, attackingunit->ypos );
786 
787  if ( attackingunit->height <= chfahrend ) {
788  av.defensebonus = field2->getdefensebonus();
789  // if ( dist <= maxmalq )
790  av.attackbonus = field2->getattackbonus();
791  //else
792  // av.attackbonus = 0;
793  } else {
794  av.defensebonus = 0;
795  av.attackbonus = 0;
796  }
797 
798 
799  dv.strength = 0;
800  dv.attackbonus = 0;
801 
802  dv.armor = _obji->typ->armor;
803  dv.damage = _obji->damage;
806 
807  dv.defensebonus = 0; // field -> getdefensebonus();
808  dv.hemming = 1;
809  dv.color = 8 ;
810  dv.kamikaze = 0;
811  dv.height = 0;
812 }
813 
814 
816 {
817  GameMap* map = _attackingunit->getMap();
818 
820  b->execute ( context );
821 
822  _attackingunit->postAttack( false, context );
823 
825  f->execute ( context );
826 
827 
828  MapCoordinate position( _x, _y );
829 
830  if ( dv.damage >= 100 ) {
831  (new RemoveObject(map, position, _obji->typ->id))->execute(context);
832  } else {
833  GameAction* g = new ChangeObjectProperty( map, position, _obji, ChangeObjectProperty::Damage, dv.damage );
834  g->execute ( context );
835  }
836 }
837 
838 
839 
840 
841 
842 AttackWeap* attackpossible( const Vehicle* attacker, int x, int y)
843 {
844  AttackWeap* atw = new AttackWeap;
845 
846  memset(atw, 0, sizeof(*atw));
847 
848 
849  if ((x < 0) || (y < 0) || (x >= attacker->getMap()->xsize) || (y >= attacker->getMap()->ysize))
850  return atw;
851  if (attacker == NULL)
852  return atw;
853  if (attacker->typ->weapons.count == 0)
854  return atw;
855 
856  MapField* efield = attacker->getMap()->getField(x,y);
857 
858  if ( efield->getVehicle() ) {
859  if (fieldvisiblenow(efield, attacker->color/8))
860  attackpossible2n ( attacker, efield->getVehicle(), atw );
861  }
862  else if (efield->building != NULL) {
863  if ( attacker->getMap()->getPlayer(attacker).diplomacy.isHostile( efield->building->getOwner() ) || efield->building->color == 8*8 )
864  for (int i = 0; i < attacker->typ->weapons.count ; i++)
865  if (attacker->typ->weapons.weapon[i].shootable() )
866  if (attacker->typ->weapons.weapon[i].offensive() )
867  if ( attacker->typ->weapons.weapon[i].targetingAccuracy[cmm_building] > 0 ) {
868  int tm = efield->building->typ->height;
869  if (tm & attacker->typ->weapons.weapon[i].targ) {
870  if (fieldvisiblenow(efield, attacker->color/8)) {
871  int d = beeline(attacker->xpos,attacker->ypos,x,y);
872  if (d <= attacker->typ->weapons.weapon[i].maxdistance)
873  if (d >= attacker->typ->weapons.weapon[i].mindistance) {
874  if (attacker->height & attacker->typ->weapons.weapon[i].sourceheight)
875  if ( attacker->typ->weapons.weapon[i].efficiency[6 + getheightdelta ( getFirstBit( attacker->height), getFirstBit(tm))] )
876  if (attacker->ammo[i] > 0) {
877  atw->strength[atw->count ] = attacker->weapstrength[i];
878  atw->typ[atw->count ] = 1 << attacker->typ->weapons.weapon[i].getScalarWeaponType() ;
879  atw->num[atw->count ] = i;
881  atw->count++;
882  }
883 
884  }
885  }
886  }
887  }
888  } else if ( efield->objects.size() ) {
889  int n = 0;
890  for ( MapField::ObjectContainer::iterator j = efield->objects.begin(); j != efield->objects.end(); j++ )
891  if ( j->typ->armor > 0 )
892  n++;
893 
894  if ( n > 0 )
895  if ((efield->vehicle == NULL) && ( efield->building == NULL)) {
896  bool found = false;
897  for ( MapField::ObjectContainer::reverse_iterator j = efield->objects.rbegin(); j != efield->objects.rend(); ++j ) {
898  for ( int i = 0; i <= attacker->typ->weapons.count - 1; i++)
899  if (attacker->typ->weapons.weapon[i].shootable() )
900  if ( attacker->typ->weapons.weapon[i].getScalarWeaponType() == cwcannonn ||
901  attacker->typ->weapons.weapon[i].getScalarWeaponType() == cwlasern ||
905  attacker->typ->weapons.weapon[i].getScalarWeaponType() == cwtorpedon ||
906  attacker->typ->weapons.weapon[i].getScalarWeaponType() == cwbombn ) {
907  if ( attacker->typ->weapons.weapon[i].targetingAccuracy[cmm_building] )
908  if (fieldvisiblenow(efield, attacker->color/8)) {
909  int d = beeline(attacker->xpos,attacker->ypos,x,y);
910  if (d <= attacker->typ->weapons.weapon[i].maxdistance)
911  if (d >= attacker->typ->weapons.weapon[i].mindistance) {
912  if (attacker->height & attacker->typ->weapons.weapon[i].sourceheight )
913  if ( attacker->typ->weapons.weapon[i].targ & j->typ->getEffectiveHeight() )
914  if ( attacker->typ->weapons.weapon[i].efficiency[6 + getheightdelta ( getFirstBit( attacker->height), getFirstBit(j->typ->getEffectiveHeight()))] )
915  if (attacker->ammo[i] > 0) {
916  atw->strength[atw->count ] = attacker->weapstrength[i];
917  atw->num[atw->count ] = i;
918  atw->typ[atw->count ] = 1 << attacker->typ->weapons.weapon[i].getScalarWeaponType();
919  atw->target = AttackWeap::object;
920  atw->count++;
921  found = true;
922  }
923 
924  }
925  }
926 
927  }
928  if ( found )
929  return atw;
930  }
931 
932  }
933  }
934 
935  return atw;
936 }
937 
938 
939 bool attackpossible2u( const Vehicle* attacker, const Vehicle* target, AttackWeap* atw, int targetheight )
940 {
941  if ( targetheight == -1 )
942  targetheight = target->height;
943 
944  int result = false;
945  if ( atw )
946  atw->count = 0;
947 
948  if ( !attacker )
949  return false ;
950 
951  if ( !target )
952  return false ;
953 
954  if (attacker->typ->weapons.count == 0)
955  return false ;
956 
957  if ( attacker->getMap()->player[attacker->getOwner()].diplomacy.isHostile( target->getOwner() ) )
958  for ( int i = 0; i < attacker->typ->weapons.count ; i++)
959  for ( int h = 0; h < 8; h++ )
960  if ( targetheight & (1<<h))
961  if (attacker->typ->weapons.weapon[i].shootable() )
962  if (attacker->typ->weapons.weapon[i].offensive() )
963  if ( (1<<h) & attacker->typ->weapons.weapon[i].targ )
964  if (attacker->height & attacker->typ->weapons.weapon[i].sourceheight )
965  if ( attacker->typ->weapons.weapon[i].targetingAccuracy[ target->typ->movemalustyp] > 0 )
966  if ( attacker->typ->weapons.weapon[i].efficiency[6 + getheightdelta ( getFirstBit( attacker->height), h)] )
967  if (attacker->ammo[i] > 0) {
968  result = true;
969  if ( atw ) {
970  atw->strength[atw->count] = attacker->weapstrength[i] * attacker->typ->weapons.weapon[i].targetingAccuracy[ target->typ->movemalustyp] / 100;
971  atw->num[atw->count ] = i;
972  atw->typ[atw->count ] = 1 << attacker->typ->weapons.weapon[i].getScalarWeaponType();
974  atw->count++;
975  }
976  }
977 
978  return result;
979 }
980 
981 
982 
983 bool attackpossible28( const Vehicle* attacker, const Vehicle* target, AttackWeap* atw, int targetHeight )
984 {
985  if ( targetHeight < 0 )
986  targetHeight = target->height;
987 
988  bool result = false;
989  if ( atw )
990  atw->count = 0;
991 
992  if (attacker == NULL)
993  return false ;
994 
995  if (target == NULL)
996  return false ;
997 
998  if (attacker->typ->weapons.count == 0)
999  return false ;
1000 
1001 // if ( attacker->getMap()->player[attacker->getOwner()].diplomacy.isHostile( target->getOwner() ) )
1002  for ( int i = 0; i < attacker->typ->weapons.count ; i++)
1003  if (attacker->typ->weapons.weapon[i].shootable() )
1004  if (attacker->typ->weapons.weapon[i].offensive() )
1005  if (targetHeight & attacker->typ->weapons.weapon[i].targ )
1006  if (minmalq <= attacker->typ->weapons.weapon[i].maxdistance)
1007  if (minmalq >= attacker->typ->weapons.weapon[i].mindistance)
1008  if (attacker->height & attacker->typ->weapons.weapon[i].sourceheight )
1009  if ( attacker->typ->weapons.weapon[i].targetingAccuracy[ target->typ->movemalustyp ] > 0)
1010  if ( attacker->typ->weapons.weapon[i].efficiency[6 + getheightdelta ( getFirstBit( attacker->height), getFirstBit(targetHeight))] )
1011  if (attacker->ammo[i] > 0) {
1012  result = true;
1013  if ( atw ) {
1014  atw->strength[atw->count] = attacker->weapstrength[i] * attacker->typ->weapons.weapon[i].targetingAccuracy[ target->typ->movemalustyp] / 100;
1015  atw->num[atw->count ] = i;
1016  atw->typ[atw->count ] = 1 << attacker->typ->weapons.weapon[i].getScalarWeaponType();
1017  atw->target = AttackWeap::vehicle;
1018  atw->count++;
1019  }
1020  }
1021 
1022  return result;
1023 }
1024 
1025 
1026 bool attackpossible2n( const Vehicle* attacker, const Vehicle* target, AttackWeap* atw )
1027 {
1028  int result = false;
1029  if ( atw )
1030  atw->count = 0;
1031 
1032  if (attacker == NULL)
1033  return false ;
1034 
1035  if (target == NULL)
1036  return false ;
1037 
1038  if (attacker->typ->weapons.count == 0)
1039  return false ;
1040 
1041  int dist = beeline ( attacker, target );
1042  if ( attacker->getMap()->player[attacker->getOwner()].diplomacy.isHostile( target->getOwner() ) )
1043  if ( !attacker->attacked )
1044  if ( !attacker->typ->wait || !attacker->hasMoved() || attacker->reactionfire.getStatus() == Vehicle::ReactionFire::ready)
1045  for ( int i = 0; i < attacker->typ->weapons.count ; i++)
1046  if (attacker->typ->weapons.weapon[i].shootable() )
1047  if (attacker->typ->weapons.weapon[i].offensive() )
1048  if (target->height & attacker->typ->weapons.weapon[i].targ )
1049  if (dist <= attacker->typ->weapons.weapon[i].maxdistance)
1050  if (dist >= attacker->typ->weapons.weapon[i].mindistance)
1051  if (attacker->height & attacker->typ->weapons.weapon[i].sourceheight )
1052  if ( attacker->typ->weapons.weapon[i].efficiency[6 + getheightdelta ( getFirstBit( attacker->height), getFirstBit(target->height))] )
1053  if ( attacker->typ->weapons.weapon[i].targetingAccuracy[ target->typ->movemalustyp ] > 0)
1054  if (attacker->ammo[i] > 0) {
1055  result = true;
1056  if ( atw ) {
1057  atw->strength[atw->count] = attacker->weapstrength[i] * attacker->typ->weapons.weapon[i].targetingAccuracy[ target->typ->movemalustyp ] / 100;
1058  atw->num[atw->count ] = i;
1059  atw->typ[atw->count ] = 1 << attacker->typ->weapons.weapon[i].getScalarWeaponType();
1060  atw->target = AttackWeap::vehicle;
1061  atw->count++;
1062  }
1063  }
1064 
1065 
1066  return result;
1067 }
1068 
1069 bool vehicleplattfahrbar( const Vehicle* vehicle,
1070  const MapField* field)
1071 {
1072  return false;
1073 /*
1074  if (vehicle == NULL)
1075  return ( false );
1076  if (field == NULL)
1077  return ( false );
1078  if (field->vehicle == NULL)
1079  return ( false );
1080 
1081  if ((vehicle->color != field->vehicle->color) &&
1082  (vehicle->height == chfahrend) &&
1083  (field->vehicle->height == chfahrend) &&
1084  (field->vehicle->functions & cftrooper) &&
1085  (vehicle->weight() >= fusstruppenplattfahrgewichtsfaktor * field->vehicle->weight()))
1086  return ( true );
1087  return ( false );
1088 */
1089 }
1090 
1091 
1092 float WeapDist::getWeaponStrength ( const SingleWeapon* weap, int weather, int dist, int attacker_height, int defender_height, int reldiff )
1093 {
1094 /*
1095  int translat[31] = { 6, 255, 1, 3, 2, 4, 0, 5, 255, 255, 6, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1096  255, 255, 255, 255, 255, 255};
1097 */
1098 
1099  if ( !weap )
1100  return 0;
1101 
1102  int scalar = weap->getScalarWeaponType();
1103  if ( scalar >= 31 || scalar < 0 )
1104  return 0;
1105 
1106  if ( scalar == 1 ) // mine
1107  return 1;
1108 
1109  /*
1110  int typ = translat[ scalar ];
1111  if ( typ == 255 ) {
1112  displaymessage("tweapdist::getweapstrength: invalid type ", 1 );
1113  return 1;
1114  }
1115  */
1116 
1117 
1118  if ( weap->maxdistance == 0 )
1119  return 0;
1120 
1121  if ( weap->minstrength == 0 )
1122  return 0;
1123 
1124  if ( reldiff == -1) {
1125  if ( dist < weap->mindistance || dist > weap->maxdistance ) {
1126  warningMessage("tweapdist::getweapstrength: invalid range: \n min = " + ASCString::toString(weap->mindistance ) + " ; max = " + ASCString::toString( weap->maxdistance ) + " ; req = " + ASCString::toString( dist));
1127  return 0;
1128  }
1129 
1130  if ( weap->maxdistance - weap->mindistance != 0 )
1131  reldiff = 255 * (dist - weap->mindistance) / ( weap->maxdistance - weap->mindistance) ;
1132  else
1133  reldiff = 0;
1134  }
1135 
1136 // int minstrength = 255 - 255 * weap->minstrength / weap->maxstrength;
1137 
1138 // int relstrength = 255 - ( 255 - data[typ][reldiff] ) * minstrength / ( 255 - data[typ][255] );
1139 
1140  float relpos = float(reldiff) / 255.0;
1141 
1142 /* if ( weap->maxstrength && weap->minstrength )
1143  relpos /= float(weap->maxstrength) / float(weap->minstrength);
1144 
1145  return 1.0 - relpos;*/
1146 
1147 
1148  float relstrength = weap->maxstrength - relpos * ( weap->maxstrength - weap->minstrength );
1149 
1150  float weatherFactor = 1;
1151  int heightEff = 100;
1152  if ( attacker_height != -1 && defender_height != -1 ) {
1153  int hd = getheightdelta ( getFirstBit ( attacker_height ), getFirstBit ( defender_height ));
1154  heightEff = weap->efficiency[6+hd];
1155 
1156  if ( attacker_height >= chtieffliegend && weather != 0 && defender_height != -1) {
1157  int weatherRelevantHeightDelta = min( abs( getheightdelta ( getFirstBit ( attacker_height ), getFirstBit ( defender_height ))), 3);
1158  if ( weather == 1 || weather == 3 )
1159  weatherFactor = 1 - 0.07*weatherRelevantHeightDelta;
1160  else
1161  if ( weather == 2 || weather == 4 || weather == 5 )
1162  weatherFactor = 1 - 0.2 * weatherRelevantHeightDelta;
1163  }
1164 
1165  if ( attacker_height == chsatellit )
1166  weatherFactor = 1 - (1-weatherFactor)/2;
1167  }
1168 
1169 
1170  return relstrength * heightEff * weatherFactor / float(weap->maxstrength * 100) ;
1171 
1172 /* if ( attacker_height != -1 && defender_height!= -1 ) {
1173  int hd = getheightdelta ( getFirstBit ( attacker_height ), getFirstBit ( defender_height ));
1174  return relstrength * weap->efficiency[6+hd] / 100 ;
1175  } else
1176  return relstrength ;
1177  */
1178 }
1179 
1180 
static const int experienceIcons
Definition: attack.h:49
int defensebonus
Definition: attack.h:100
bool wait
If the unit cannot attack in the same turn after it has moved, it has to wait.
Definition: vehicletype.h:197
const int cmm_building
The movemalus type for a building. It is used for SingleWeapon::targetingAccuracy ...
Definition: typen.h:387
enum AttackWeap::Target target
Player & getPlayer(PlayerID p)
Definition: gamemap.h:257
int xsize
the size of the map
Definition: gamemap.h:201
int getExperience_defensive() const
Definition: vehicle.cpp:258
Mine & getMine(int n)
returns the nth mine. This function should only be used by legacy code; new code should store an iter...
Definition: mapfield.cpp:204
int id
the id of the object, used when referencing objects in files
Definition: objecttype.h:35
map accessing and usage routines used by ASC and the mapeditor
int getattackbonus(void)
the attack bonus that unit get when they are attacking
Definition: mapfield.cpp:490
const BuildingType * typ
Definition: buildings.h:48
struct tfight::tavalues dv
void setup(Vehicle *attackingunit, int obj_x, int obj_y, int weapon)
Definition: attack.cpp:732
#define cwsmallmissilen
Definition: vehicletype.h:73
int damage
Damage. 0 is no damage, when damage reaches 100 the container is destroyed.
int getArmor() const
Definition: vehicle.cpp:1675
Vehicle * vehicle
Definition: mapfield.h:89
int initiative
unused
Definition: vehicletype.h:215
bool isHostile(PlayerID towardsPlayer) const
Definition: player.h:80
Structure to store the weapons which a unit can use to perform an attack.
Definition: attack.h:291
struct tfight::tavalues av
int getheightdelta(const ContainerBase *c1, const ContainerBase *c2)
calculate the height difference between two levels of height.
Definition: spfst.cpp:393
int ammo[16]
Definition: vehicle.h:87
#define cwcruisemissilen
Definition: vehicletype.h:65
int strength[16]
Definition: attack.h:295
#define cwbombn
Definition: vehicletype.h:69
int getFirstBit(int zahl)
Count the number of zero bits on the LSB side of "zahl".
Definition: misc.cpp:45
UnitWeapon weapons
The weapons.
Definition: vehicletype.h:248
int sourceheight
the weapon can be shot from these levels of height (bitmapped)
Definition: vehicletype.h:108
float hemming
Definition: attack.h:102
int efficiency[13]
the targeting accuracy of the weapon over different height differences between the attacking unit and...
Definition: vehicletype.h:132
int damage
Definition: objects.h:49
bool shootable(void) const
DiplomaticStateVector diplomacy
Definition: player.h:209
int targ
the weapon can attack targets at these levels of height (bitmapped)
Definition: vehicletype.h:105
bool hasFunction(ContainerFunctions function) const
int turn() const
Definition: typen.h:181
int getOwner() const
returns the number of the player this vehicle/building belongs to
Vehicle * getVehicle() const
Definition: mapfield.h:94
void warningMessage(const ASCString &str)
MapCoordinate3D getPosition() const
returns the units position
Definition: vehicle.cpp:1552
float strength_damage(int damage)
Definition: attack.cpp:116
SingleWeapon weapon[16]
Definition: vehicletype.h:170
tunitattacksunit(Vehicle *&attackingunit, Vehicle *&attackedunit, bool respond=true, int weapon=-1, bool reactionfire=false)
Definition: attack.cpp:279
a single field of the map
Definition: mapfield.h:26
int getIconIndex(int experience, bool offensive)
Definition: attack.cpp:156
#define cwlasern
Definition: vehicletype.h:84
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
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 height
the current level of height ( BITMAPPED ! )
Definition: vehicle.h:118
int beeline(const Vehicle *a, const Vehicle *b)
returns the distance between the units a and b
int getWeather()
the weather that is on this field
Definition: mapfield.cpp:370
const int sidenum
the number of sides that a field has; is now fixed at 6;
Definition: typen.h:438
bool attackpossible2n(const Vehicle *attacker, const Vehicle *target, AttackWeap *atw)
Is attacker able to attack target ? Actual distance used.
Definition: attack.cpp:1026
bool attackpossible28(const Vehicle *attacker, const Vehicle *target, AttackWeap *atw, int targetHeight)
Is attacker able to attack target ? Distance is assumed one field.
Definition: attack.cpp:983
AttackFormula(GameMap *gamemap)
Definition: attack.cpp:49
int getScalarWeaponType(void) const
void setup(Vehicle *attackingunit, int x, int y, int weapon)
Definition: attack.cpp:516
bool fieldvisiblenow(const MapField *pe, Vehicle *veh, int player)
{@
Definition: spfst.cpp:399
void setresult(const Context &context)
Writes the result of the attack calculation to the actual units.
Definition: attack.cpp:815
GameMap * gamemap
Definition: attack.h:46
tunitattacksobject(Vehicle *attackingunit, int obj_x, int obj_y, int weapon=-1)
Definition: attack.cpp:726
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
class Vehicle::ReactionFire reactionfire
#define maxmalq
Constants that specify the layout of ASC.
Definition: typen.h:429
#define cwcannonn
Definition: vehicletype.h:79
int mindistance
the minimal distance the weapon can shoot
Definition: vehicletype.h:114
ActionResult execute(const Context &context)
Definition: action.cpp:41
int minstrength
strength of the weapon when fired over the maximum distance
Definition: vehicletype.h:123
tunitattacksbuilding(Vehicle *attackingunit, int x, int y, int weapon=-1)
Definition: attack.cpp:509
void log(const Vehicle *attacker, const Vehicle *attackee)
Definition: attack.cpp:417
void setresult(const Context &context)
Writes the result of the attack calculation to the actual units.
Definition: attack.cpp:693
const ObjectType * typ
Definition: objects.h:48
#define chtieffliegend
Definition: typen.h:414
Coordinate on the twodimensional map.
Definition: typen.h:202
MineTypes type
int dist
Definition: attack.h:86
int movemalustyp
The category of the unit. Original used only to distinguish only between different movement costs for...
Definition: vehicletype.h:206
void postAttack(bool reactionFire, const Context &context)
callback that is called after the unit has attacked
Definition: vehicle.cpp:1019
static float getWeaponStrength(const SingleWeapon *weap, int targetFieldWeather=0, int dist=-1, int attacker_height=-1, int defender_height=-1, int reldiff=-1)
Definition: attack.cpp:1092
Interface for all the fighting routines of ASC.
The interface for the buildingtype class.
float strength_experience(int experience)
Definition: attack.cpp:121
int getnextdx(int dir, int y)
Definition: mapalgorithms.h:77
int getEffectiveHeight() const
returns the level of height of this object in the normal 8 level scheme of asc (deep submerged...
Definition: objecttype.cpp:90
int maxdistance
the maximum distance the weapon can shoot
Definition: vehicletype.h:111
void setresult(const Context &context)
Writes the result of the attack calculation to the actual units.
Definition: attack.cpp:596
void setresult(const Context &context)
Writes the result of the attack calculation to the actual units.
Definition: attack.cpp:445
int strength
the effective punch of the mine
char * constructFileName(char *buf, int directoryLevel, const char *path, const char *filename)
Definition: basestrm.cpp:873
bool attackpossible2u(const Vehicle *attacker, const Vehicle *target, AttackWeap *atw, int targetheight)
Is attacker able to attack target ? Distance is not evaluated.
Definition: attack.cpp:939
A single weapon of a #Vehicletype.
Definition: vehicletype.h:100
int num[16]
Definition: attack.h:296
int targetingAccuracy[cmovemalitypenum]
the effectiveness of the weapon against different targets.
Definition: vehicletype.h:137
#define chfahrend
Definition: typen.h:413
#define cwminen
Definition: vehicletype.h:67
Player player[9]
Definition: gamemap.h:253
void errorMessage(const ASCString &string)
static CGameOptions * Instance()
returns the only Instance
Definition: gameoptions.cpp:38
#define chsatellit
Definition: typen.h:417
int getnextdy(int dir)
Definition: mapalgorithms.h:80
Vehicle * _attackingunit
Definition: attack.h:129
int ysize
Definition: gamemap.h:201
float strength_attackbonus(int abonus)
Definition: attack.cpp:143
MineContainer mines
Definition: mapfield.h:117
int getgameparameter(GameParameter num) const
Definition: gamemap.cpp:1047
int height
the levels of height which this unit can enter
bool hasMoved(void) const
did the unit move this turn
Definition: vehicle.cpp:552
const int maxunitexperience
The maximum experience value of a Vehicle.
Definition: typen.h:73
int color
The owner of the container.
Definition: attack.h:83
int xpos
the position on the map
Definition: vehicle.h:124
int count
Definition: attack.h:294
int typ[16]
Definition: attack.h:297
const VehicleType * typ
Definition: vehicle.h:83
bool attacked
did the unit already attack this turn
Definition: vehicle.h:109
Building * building
Definition: mapfield.h:102
bool offensive(void) const
AttackWeap * attackpossible(const Vehicle *attacker, int x, int y)
Is attacker able to attack anything in field x/y ?
Definition: attack.cpp:842
GameMap * getMap() const
int experience_defensive
Definition: attack.h:99
const T & min(const T &a, const T &b, const T &c)
Definition: misc.h:80
Status getStatus() const
for each player that can still be attacked one bit is set
Definition: vehicle.h:155
int maxstrength
strength of the weapon when fired over the minimal distance
Definition: vehicletype.h:120
static float getHemmingFactor(int relDir)
Definition: attack.cpp:79
A GameAction is an modification of something on a map.
Definition: action.h:45
int getdefensebonus(void)
the defense bonus that unit get when they are attacked
Definition: mapfield.cpp:506
void setup(const MapCoordinate &position, int minenum, Vehicle *&attackedunit)
Definition: attack.cpp:618
void setup(Vehicle *&attackingunit, Vehicle *&attackedunit, bool respond, int weapon)
Definition: attack.cpp:286
float defense_defensebonus(int defensebonus)
Definition: attack.cpp:150
#define cwtorpedon
Definition: vehicletype.h:75
Mine * getFirstMine()
Definition: attack.cpp:716
int ypos
Definition: vehicle.h:124
int getdirection(const MapCoordinate &start, const MapCoordinate &dest)
bool vehicleplattfahrbar(const Vehicle *vehicle, const MapField *field)
Can the vehicle drive across the field and destroy any unit there by moving over them?
Definition: attack.cpp:1069
int getArmor() const
returns the armor of the building.
Definition: buildings.cpp:393
const SingleWeapon * getWeapon(unsigned weaponNum) const
Returns the SingleWeapon corresponding to the weaponNum for this vehicle.
Definition: vehicle.cpp:1760
int networkid
a unique identification of the unit that is used everywhere in ASC (and not only the network protocol...
Definition: vehicle.h:140
float strength_hemming(int ax, int ay, Vehicle *d_eht)
Definition: attack.cpp:95
int armor
if an object should not be attackable, set armor to 0
Definition: objecttype.h:56
int weapstrength[16]
Definition: vehicle.h:90
#define cwlargemissilen
Definition: vehicletype.h:71
ASCString name
a short name, for example B-52
float defense_experience(int experience)
Definition: attack.cpp:132
const int cmm_trooper
the movemalus type of a trooper.
Definition: typen.h:390
#define minmalq
Definition: typen.h:430
GameTime time
the time in the game, mesured in a turns and moves
Definition: gamemap.h:235
ObjectContainer objects
Definition: mapfield.h:124
The map. THE central structure of ASC, which holds everything not globally available together...
Definition: gamemap.h:182
tmineattacksunit(const MapCoordinate &mineposition, int minenum, Vehicle *&attackedunit)
Definition: attack.cpp:612
MapField * getField(int x, int y)
Definition: gamemap.h:465
int getExperience_offensive() const
Definition: vehicle.cpp:253