Skip to content

Commit 445fdcc

Browse files
committed
Added post humous commeendations for excellent soldiers
1 parent 0e58cc3 commit 445fdcc

5 files changed

Lines changed: 98 additions & 3 deletions

File tree

bin/data/Ruleset/Commendations.rul

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,10 @@ extraStrings:
347347
STR_MEDAL_MEDIKIT_DESCRIPTION: "Given to a soldier who has made regular use of the medikit on the battlefield."
348348
STR_MEDAL_BRAVERYGAIN_NAME: "Medal of Bravery"
349349
STR_MEDAL_BRAVERYGAIN_DESCRIPTION: "Given to a soldier who is an example of bravery."
350+
STR_MEDAL_BESTOFRANK_NAME: "Best of Rank"
351+
STR_MEDAL_BESTOFRANK_DESCRIPTION: "Given post humously to a soldier who was a rising star in his or her respective rank."
352+
STR_MEDAL_BESTSOLDIER_NAME: "Best Soldier"
353+
STR_MEDAL_BESTSOLDIER_DESCRIPTION: "Given post humously to a soldier who was an example for all others."
350354
STR_AWARD_0: "First award"
351355
STR_AWARD_1: "Second award"
352356
STR_AWARD_2: "Third award"
@@ -525,6 +529,10 @@ extraStrings:
525529
STR_MEDAL_MEDIKIT_DESCRIPTION: "Given to a soldier who has made regular use of the medikit on the battlefield."
526530
STR_MEDAL_BRAVERYGAIN_NAME: "Medal of Bravery"
527531
STR_MEDAL_BRAVERYGAIN_DESCRIPTION: "Given to a soldier who is an example of bravery."
532+
STR_MEDAL_BESTOFRANK_NAME: "Best of Rank"
533+
STR_MEDAL_BESTOFRANK_DESCRIPTION: "Given post humously to a soldier who was a rising star in his or her respective rank."
534+
STR_MEDAL_BESTSOLDIER_NAME: "Best Soldier"
535+
STR_MEDAL_BESTSOLDIER_DESCRIPTION: "Given post humously to a soldier who was an example for all others."
528536
STR_AWARD_0: "First award"
529537
STR_AWARD_1: "Second award"
530538
STR_AWARD_2: "Third award"
@@ -1392,6 +1400,16 @@ commendations:
13921400
sprite: 00
13931401
criteria:
13941402
totalBraveryGain: [10, 10, 20, 20, 20, 20, 30, 30, 30, 30]
1403+
- type: STR_MEDAL_BESTOFRANK_NAME
1404+
description: STR_MEDAL_BESTOFRANK_DESCRIPTION
1405+
sprite: 00
1406+
criteria:
1407+
bestOfRank: [1, 2, 3, 4, 4, 5, 6, 6]
1408+
- type: STR_MEDAL_BESTSOLDIER_NAME
1409+
description: STR_MEDAL_BESTSOLDIER_DESCRIPTION
1410+
sprite: 00
1411+
criteria:
1412+
bestSoldier: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
13951413
ufopaedia:
13961414
- id: STR_MEDAL_MILITARY_CROSS_NAME
13971415
type_id: 7
@@ -1750,6 +1768,21 @@ ufopaedia:
17501768
text: STR_MEDAL_BRAVERYGAIN_MEDAL_UFOPEDIA
17511769
text_width: 164
17521770
listOrder: 6051
1771+
- id: STR_MEDAL_BESTOFRANK_NAME
1772+
type_id: 7
1773+
section: STR_HEAVY_WEAPONS_PLATFORMS
1774+
image_id: PLACEHOLDER #BESTOFRANK
1775+
text: STR_MEDAL_BESTOFRANK_MEDAL_UFOPEDIA
1776+
text_width: 164
1777+
listOrder: 6052
1778+
- id: STR_MEDAL_BESTSOLDIER_NAME
1779+
type_id: 7
1780+
section: STR_HEAVY_WEAPONS_PLATFORMS
1781+
image_id: PLACEHOLDER #BESTSOLDIER
1782+
text: STR_MEDAL_BESTSOLDIER_MEDAL_UFOPEDIA
1783+
text_width: 164
1784+
listOrder: 6053
1785+
17531786
# entries below move the HWPs to the Craft Section of the UFOPedia
17541787
- id: STR_TANK_CANNON
17551788
section: STR_XCOM_CRAFT_ARMAMENT

src/Battlescape/DebriefingState.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,37 @@ DebriefingState::DebriefingState() : _region(0), _country(0), _noContainment(fal
288288
// Set the UnitStats delta
289289
(*j)->getStatistics()->delta = *(*j)->getGeoscapeSoldier()->getCurrentStats() - *(*j)->getGeoscapeSoldier()->getInitStats();
290290

291+
std::map<SoldierRank, Soldier*> bestSoldierCandidates;
292+
int bestScore[7] = {0, 0, 0, 0, 0, 0, 0};
293+
int bestOverallScore = 0;
294+
// Check to see if any of the dead soldiers were exceptional.
295+
for (std::vector<Soldier*>::iterator deadUnit = _game->getSavedGame()->getDeadSoldiers()->begin(); deadUnit != _game->getSavedGame()->getDeadSoldiers()->end(); ++deadUnit)
296+
{
297+
// Find the best soldier per rank by comparing score
298+
int score = (*deadUnit)->getDiary()->getScoreTotal();
299+
SoldierRank rank = (*deadUnit)->getRank();
300+
301+
if (score > bestScore[rank])
302+
{
303+
bestSoldierCandidates[rank] = (*deadUnit);
304+
bestScore[rank] = score;
305+
if (score > bestOverallScore)
306+
{
307+
bestOverallScore = score;
308+
}
309+
}
310+
}
311+
// Now award those soldiers commendations!
312+
for (std::map<SoldierRank, Soldier*>::iterator bestSoldier = bestSoldierCandidates.begin(); bestSoldier != bestSoldierCandidates.end(); ++bestSoldier)
313+
{
314+
(*bestSoldier).second->getDiary()->awardBestOfRank((*bestSoldier).second->getRank());
315+
if ((*bestSoldier).second->getDiary()->getScoreTotal() == bestOverallScore)
316+
{
317+
(*bestSoldier).second->getDiary()->awardBestOverall();
318+
bestOverallScore++; // If there is a tie, first come first serve!
319+
}
320+
}
321+
291322
(*j)->getGeoscapeSoldier()->getDiary()->updateDiary((*j)->getStatistics(), _missionStatistics, _game->getRuleset());
292323
if ((*j)->getStatus() != STATUS_DEAD && (*j)->getGeoscapeSoldier()->getDiary()->manageCommendations(_game->getRuleset()))
293324
{

src/Ruleset/Ruleset.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,10 @@ SavedGame *Ruleset::newSave() const
792792
soldier->setCraft(base->getCrafts()->front());
793793
base->getSoldiers()->push_back(soldier);
794794
soldier->getDiary()->awardOriginalEightCommendation();
795+
for (std::vector<SoldierCommendations*>::iterator comm = soldier->getDiary()->getSoldierCommendations()->begin(); comm != soldier->getDiary()->getSoldierCommendations()->end(); ++comm)
796+
{
797+
(*comm)->makeOld(); // Soldier was already awarded these before arriving on base.
798+
}
795799
}
796800

797801
save->getBases()->push_back(base);

src/Savegame/SoldierDiary.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ SoldierDiary::SoldierDiary() : _killList(), _regionTotal(), _countryTotal(), _ty
4040
_totalShotByFriendlyCounter(0), _totalShotFriendlyCounter(0), _ironManTotal(0), _importantMissionTotal(0), _longDistanceHitCounterTotal(0),
4141
_lowAccuracyHitCounterTotal(0), _shotsFiredCounterTotal(0), _shotsLandedCounterTotal(0), _shotAtCounter10in1Mission(0), _hitCounter5in1Mission(0),
4242
_reactionFireTotal(0), _timesWoundedTotal(0), _valiantCruxTotal(0), _KIA(0), _trapKillTotal(0), _alienBaseAssaultTotal(0), _allAliensKilledTotal(0), _allAliensStunnedTotal(0),
43-
_woundsHealedTotal(0), _allUFOs(0), _allMissionTypes(0), _statGainTotal(0), _revivedUnitTotal(0), _wholeMedikitTotal(0), _braveryGainTotal(0)
43+
_woundsHealedTotal(0), _allUFOs(0), _allMissionTypes(0), _statGainTotal(0), _revivedUnitTotal(0), _wholeMedikitTotal(0), _braveryGainTotal(0), _bestOfRank(0),
44+
_bestSoldier(false)
4445
{
4546
}
4647
/**
@@ -116,6 +117,8 @@ void SoldierDiary::load(const YAML::Node& node)
116117
_revivedUnitTotal = node["_revivedUnitTotal"].as<int>(_revivedUnitTotal);
117118
_wholeMedikitTotal = node["_wholeMedikitTotal"].as<int>(_wholeMedikitTotal);
118119
_braveryGainTotal = node["_braveryGainTotal"].as<int>(_braveryGainTotal);
120+
_bestOfRank = node["_bestOfRank"].as<int>(_bestOfRank);
121+
_bestSoldier = node["_bestSoldier"].as<bool>(_bestSoldier);
119122
}
120123
/**
121124
* Saves the diary to a YAML file.
@@ -171,6 +174,8 @@ YAML::Node SoldierDiary::save() const
171174
if (_revivedUnitTotal) node["_revivedUnitTotal"] = _revivedUnitTotal;
172175
if(_wholeMedikitTotal) node["_wholeMedikitTotal"] = _wholeMedikitTotal;
173176
if(_braveryGainTotal) node["_braveryGainTotal"] = _braveryGainTotal;
177+
if (_bestOfRank) node["_bestOfRank"] = _bestOfRank;
178+
if (_bestSoldier) node["_bestSoldier"] = _bestSoldier;
174179
return node;
175180
}
176181
/**
@@ -363,7 +368,9 @@ bool SoldierDiary::manageCommendations(Ruleset *rules)
363368
((*j).first == "totalStatGain" && _statGainTotal < (*j).second.at(nextCommendationLevel["noNoun"])) ||
364369
((*j).first == "totalRevives" && _revivedUnitTotal < (*j).second.at(nextCommendationLevel["noNoun"])) ||
365370
((*j).first == "totalWholeMedikit" && _wholeMedikitTotal < (*j).second.at(nextCommendationLevel["noNoun"])) ||
366-
((*j).first == "totalBraveryGain" && _braveryGainTotal < (*j).second.at(nextCommendationLevel["noNoun"])) )
371+
((*j).first == "totalBraveryGain" && _braveryGainTotal < (*j).second.at(nextCommendationLevel["noNoun"])) ||
372+
((*j).first == "bestOfRank" && _bestOfRank < (*j).second.at(nextCommendationLevel["noNoun"])) ||
373+
((*j).first == "bestSoldier" && (int)_bestSoldier < (*j).second.at(nextCommendationLevel["noNoun"])) )
367374
{
368375
awardCommendationBool = false;
369376
break;
@@ -754,6 +761,21 @@ void SoldierDiary::awardOriginalEightCommendation()
754761
{
755762
_commendations.push_back(new SoldierCommendations("STR_MEDAL_ORIGINAL8_NAME", "NoNoun"));
756763
}
764+
/**
765+
* Award post-humous best-of commendation.
766+
*/
767+
void SoldierDiary::awardBestOfRank(SoldierRank rank)
768+
{
769+
_bestOfRank = (int)rank + 1;
770+
}
771+
/**
772+
* Award post-humous best-of commendation.
773+
*/
774+
void SoldierDiary::awardBestOverall()
775+
{
776+
_bestSoldier = true;
777+
}
778+
757779
/**
758780
* Initializes a new commendation entry from YAML.
759781
* @param node YAML node.

src/Savegame/SoldierDiary.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ class SoldierDiary
7676
_terrorMissionTotal, _nightMissionTotal, _nightTerrorMissionTotal, _monthsService, _unconciousTotal, _shotAtCounterTotal, _hitCounterTotal, _ironManTotal,
7777
_importantMissionTotal, _longDistanceHitCounterTotal, _lowAccuracyHitCounterTotal, _shotsFiredCounterTotal, _shotsLandedCounterTotal, _shotAtCounter10in1Mission,
7878
_hitCounter5in1Mission, _reactionFireTotal, _timesWoundedTotal, _valiantCruxTotal, _KIA, _trapKillTotal, _alienBaseAssaultTotal, _allAliensKilledTotal, _allAliensStunnedTotal,
79-
_woundsHealedTotal, _allUFOs, _allMissionTypes, _statGainTotal, _revivedUnitTotal, _wholeMedikitTotal, _braveryGainTotal;
79+
_woundsHealedTotal, _allUFOs, _allMissionTypes, _statGainTotal, _revivedUnitTotal, _wholeMedikitTotal, _braveryGainTotal, _bestOfRank;
80+
bool _bestSoldier;
8081
void manageModularCommendations(std::map<std::string, int> &nextCommendationLevel, std::map<std::string, int> &modularCommendations, std::pair<std::string, int> statTotal, int criteria);
8182
void awardCommendation(std::string type, std::string noun = "noNoun");
8283
public:
@@ -132,6 +133,10 @@ class SoldierDiary
132133
std::vector<BattleUnitKills*> &getKills();
133134
/// Award special commendation to the original 8 soldiers.
134135
void awardOriginalEightCommendation();
136+
/// Award post-humous best-of rank commendation.
137+
void awardBestOfRank(SoldierRank rank);
138+
/// Award post-humous best overall commendation.
139+
void awardBestOverall();
135140
};
136141
}
137142
#endif

0 commit comments

Comments
 (0)