3030#include " TerrainModifier.h"
3131#include " ActionMenuState.h"
3232#include " UnitInfoState.h"
33+ #include " UnitFallBState.h"
3334#include " InventoryState.h"
3435#include " ../Engine/Game.h"
3536#include " ../Engine/Music.h"
@@ -396,11 +397,11 @@ void BattlescapeState::mapClick(Action *action)
396397 _action.target = pos;
397398 _map->setCursorType (CT_NONE );
398399 _game->getCursor ()->setVisible (false );
399- _states.push_back (new ProjectileFlyBState (this ));
400- if (_action.type == BA_AUTOSHOT )
400+ _states.push_back (new ProjectileFlyBState (this , _action ));
401+ if (_action.type == BA_AUTOSHOT ) // TODO - this is not very good, an autoshot gets 3 reaction shots this way
401402 {
402- _states.push_back (new ProjectileFlyBState (this ));
403- _states.push_back (new ProjectileFlyBState (this ));
403+ _states.push_back (new ProjectileFlyBState (this , _action ));
404+ _states.push_back (new ProjectileFlyBState (this , _action ));
404405 }
405406 statePushFront (new UnitTurnBState (this ));
406407 }
@@ -501,6 +502,11 @@ void BattlescapeState::btnKneelClick(Action *action)
501502 bu->kneel (!bu->isKneeled ());
502503 _map->cacheUnits ();
503504 updateSoldierInfo (bu);
505+ BattleAction action;
506+ if (_battleGame->getTerrainModifier ()->checkReactionFire (bu, &action))
507+ {
508+ statePushBack (new ProjectileFlyBState (this , action));
509+ }
504510 }
505511 }
506512}
@@ -594,7 +600,7 @@ void BattlescapeState::endTurn()
594600 p.x = _battleGame->getTiles ()[i]->getPosition ().x *16 + 8 ;
595601 p.y = _battleGame->getTiles ()[i]->getPosition ().y *16 + 8 ;
596602 p.z = _battleGame->getTiles ()[i]->getPosition ().z *24 + _battleGame->getTiles ()[i]->getTerrainLevel ();
597- statePushNext (new ExplosionBState (this , p, (*it)));
603+ statePushNext (new ExplosionBState (this , p, (*it), (*it)-> getPreviousOwner () ));
598604 it = _battleGame->getTiles ()[i]->getInventory ()->erase (it);
599605 statePushBack (0 );
600606 return ;
@@ -617,7 +623,7 @@ void BattlescapeState::endTurn()
617623 p.x = (*i)->getPosition ().x *16 + 8 ;
618624 p.y = (*i)->getPosition ().y *16 + 8 ;
619625 p.z = (*i)->getPosition ().z *24 + 18 ;
620- statePushNext (new ExplosionBState (this , p, (*it)));
626+ statePushNext (new ExplosionBState (this , p, (*it), (*it)-> getPreviousOwner () ));
621627 it = _battleGame->getItems ()->erase (it);
622628 statePushBack (0 );
623629 return ;
@@ -635,6 +641,8 @@ void BattlescapeState::endTurn()
635641 }
636642
637643 _battleGame->endTurn ();
644+ checkForCasualties (0 , 0 );
645+
638646 updateSoldierInfo (_battleGame->getSelectedUnit ());
639647 if (_battleGame->getSelectedUnit ())
640648 {
@@ -643,6 +651,58 @@ void BattlescapeState::endTurn()
643651 _game->pushState (new NextTurnState (_game, _battleGame));
644652}
645653
654+
655+ /* *
656+ * Checks for casualties and adjusts morale accordingly.
657+ * @param murderweapon
658+ * @param murderer
659+ */
660+ void BattlescapeState::checkForCasualties (BattleItem *murderweapon, BattleUnit *murderer)
661+ {
662+ // TODO : include rank bonusses and penalties !!
663+ for (std::vector<BattleUnit*>::iterator j = _battleGame->getUnits ()->begin (); j != _battleGame->getUnits ()->end (); ++j)
664+ {
665+ if ((*j)->getHealth () == 0 && (*j)->getStatus () != STATUS_DEAD )
666+ {
667+ BattleUnit *victim = (*j);
668+
669+ if (murderer)
670+ {
671+ // if there is a known murderer, he will get a morale bonus if he is of a different faction (what with neutral?)
672+ if (victim->getFaction () == FACTION_PLAYER && murderer->getFaction () == FACTION_HOSTILE ||
673+ victim->getFaction () == FACTION_HOSTILE && murderer->getFaction () == FACTION_PLAYER )
674+ {
675+ murderer->moraleChange (+20 );
676+ }
677+ // murderer will get a penalty with friendly fire
678+ if (victim->getFaction () == murderer->getFaction ())
679+ {
680+ murderer->moraleChange (-20 );
681+ }
682+ }
683+
684+ for (std::vector<BattleUnit*>::iterator i = _battleGame->getUnits ()->begin (); i != _battleGame->getUnits ()->end (); ++i)
685+ {
686+ // the losing squad all get a morale loss
687+ if ((*i)->getFaction () == victim->getFaction ())
688+ {
689+ (*i)->moraleChange (-(22 - ((*i)->getUnit ()->getBravery () / 10 )*2 ));
690+ }
691+ // the winning squad all get a morale increase
692+ if ((*i)->getFaction () != victim->getFaction ())
693+ {
694+ (*i)->moraleChange (+10 );
695+ }
696+ }
697+
698+ if (murderweapon)
699+ statePushNext (new UnitFallBState (this , (*j), murderweapon->getRules ()->getDamageType () == DT_HE )); // explosions insta-kill a unit
700+ else
701+ statePushNext (new UnitFallBState (this , (*j), false ));
702+ }
703+ }
704+ }
705+
646706/* *
647707 * Abort game.
648708 * @param action Pointer to an action.
@@ -798,6 +858,8 @@ void BattlescapeState::updateSoldierInfo(BattleUnit *battleUnit)
798858 _barMorale->clear ();
799859 _btnLeftHandItem->clear ();
800860 _btnRightHandItem->clear ();
861+ _numAmmoLeft->clear ();
862+ _numAmmoRight->clear ();
801863 return ;
802864 }
803865
@@ -1089,7 +1151,7 @@ void BattlescapeState::popState()
10891151 {
10901152 if (_action.targeting && _battleGame->getSelectedUnit () && !actionFailed)
10911153 {
1092- _battleGame-> getSelectedUnit () ->spendTimeUnits (_action.TU , _battleGame->getDebugMode ());
1154+ _action. actor ->spendTimeUnits (_action.TU , _battleGame->getDebugMode ());
10931155 }
10941156 if (_action.type == BA_THROW && !actionFailed)
10951157 {
0 commit comments