Skip to content

Commit

Permalink
Updates to ruler/hero code
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrettin committed Nov 15, 2015
1 parent 52befec commit 845c81e
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 14 deletions.
15 changes: 11 additions & 4 deletions src/include/grand_strategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ class CGrandStrategyFaction
void FormFaction(int civilization, int faction);
void AcquireFactionTechnologies(int civilization, int faction);
void SetRuler(std::string hero_full_name);
void RulerSuccession();
bool IsAlive();
bool HasTechnologyClass(std::string technology_class_name);
bool CanFormFaction(int civilization, int faction);
Expand Down Expand Up @@ -298,8 +299,10 @@ class CGrandStrategyHero
public:
CGrandStrategyHero() :
State(0), Year(0), DeathYear(0), Civilization(-1),
Generated(false),
Name(""), Dynasty(""), ProvinceOfOrigin(""),
DefaultType(NULL), Type(NULL), Province(NULL)
DefaultType(NULL), Type(NULL), Province(NULL),
Father(NULL), Mother(NULL)
{
}

Expand All @@ -311,12 +314,16 @@ class CGrandStrategyHero
int Year; /// Year in which the hero historically starts being active
int DeathYear; /// Year in which the hero dies of natural causes
int Civilization; /// Culture to which the hero belongs
std::string Name; /// given name of the hero
std::string Dynasty; /// name of the hero's dynasty
std::string ProvinceOfOrigin; /// province from which the hero originates
bool Generated; /// Whether the hero has been generated during gameplay or is a preset hero
std::string Name; /// Given name of the hero
std::string Dynasty; /// Name of the hero's dynasty
std::string ProvinceOfOrigin; /// Province from which the hero originates
CUnitType *DefaultType;
CUnitType *Type;
CProvince *Province;
CGrandStrategyHero *Father; /// Hero's father
CGrandStrategyHero *Mother; /// Hero's mother
std::vector<CGrandStrategyHero *> Children; /// Children of the hero
};

/**
Expand Down
74 changes: 67 additions & 7 deletions src/stratagus/grand_strategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,10 @@ void CGrandStrategyGame::DrawInterface()
std::string ruler_name_string = GrandStrategyGame.Provinces[this->SelectedProvince]->Owner->Ruler->GetFullName();
CLabel(GetGameFont()).Draw(UI.InfoPanel.X + ((218 - 6) / 2) - (GetGameFont().Width(ruler_name_string) / 2), UI.InfoPanel.Y + 180 - 94 + (item_y * 23), ruler_name_string);
item_y += 1;

std::string ruler_class_string = "Class: " + GrandStrategyGame.Provinces[this->SelectedProvince]->Owner->Ruler->Type->Name;
CLabel(GetGameFont()).Draw(UI.InfoPanel.X + ((218 - 6) / 2) - (GetGameFont().Width(ruler_class_string) / 2), UI.InfoPanel.Y + 180 - 94 + (item_y * 23), ruler_class_string);
item_y += 1;
}
}

Expand Down Expand Up @@ -871,7 +875,7 @@ void CGrandStrategyGame::DoTurn()
}
}

//check if any heroes should begin activity or die in this year
//check if any heroes should begin activity this year
for (size_t i = 0; i < this->Heroes.size(); ++i) {
int province_of_origin_id = GetProvinceId(this->Heroes[i]->ProvinceOfOrigin);
if (
Expand All @@ -885,6 +889,10 @@ void CGrandStrategyGame::DoTurn()
//make heroes appear in their start year
this->Heroes[i]->Create();
}
}

//check if any heroes should die this year (this needs to be done as its own loop to allow new rulers to appear in the same year their predecessor dies, and succeede him)
for (size_t i = 0; i < this->Heroes.size(); ++i) {
if (
this->Heroes[i]->DeathYear == GrandStrategyYear
&& this->Heroes[i]->State != 0
Expand Down Expand Up @@ -3264,7 +3272,7 @@ void CGrandStrategyFaction::AcquireFactionTechnologies(int civilization, int fac
void CGrandStrategyFaction::SetRuler(std::string hero_full_name)
{
if (hero_full_name.empty()) {
this->Ruler = NULL;
this->RulerSuccession();
return;
}

Expand All @@ -3282,13 +3290,45 @@ void CGrandStrategyFaction::SetRuler(std::string hero_full_name)
char buf[256];
snprintf(
buf, sizeof(buf), "if (GenericDialog ~= nil) then GenericDialog(\"%s\", \"%s\") end;",
("Ruler " + this->GetFullName()).c_str(),
("A new ruler has come to power in our realm, " + this->GetFullName() + "!").c_str()
("Ruler " + this->Ruler->GetFullName()).c_str(),
("A new ruler has come to power in our realm, " + this->Ruler->GetFullName() + "!").c_str()
);
CclCommand(buf);
}
}

void CGrandStrategyFaction::RulerSuccession()
{
if (this->GovernmentType == GovernmentTypeMonarchy) { //if is a monarchy, put the next in line on the throne
for (size_t i = 0; i < this->Ruler->Children.size(); ++i) {
if (this->Ruler->Children[i]->State != 0) {
this->SetRuler(this->Ruler->Children[i]->GetFullName());
return;
}
}
}

std::vector<CGrandStrategyHero *> ruler_candidates;
for (size_t i = 0; i < GrandStrategyGame.Heroes.size(); ++i) {
int province_of_origin_id = GetProvinceId(GrandStrategyGame.Heroes[i]->ProvinceOfOrigin);
if (
GrandStrategyGame.Heroes[i]->State != 0
&& (
(GrandStrategyGame.Heroes[i]->Province != NULL && GrandStrategyGame.Heroes[i]->Province->Owner == this)
|| (GrandStrategyGame.Heroes[i]->Province == NULL && province_of_origin_id != -1 && GrandStrategyGame.Provinces[province_of_origin_id]->Owner == this)
)
) {
ruler_candidates.push_back(GrandStrategyGame.Heroes[i]);
}
}
if (ruler_candidates.size() > 0) {
this->SetRuler(ruler_candidates[SyncRand(ruler_candidates.size())]->GetFullName());
return;
}

this->Ruler = NULL;
}

bool CGrandStrategyFaction::IsAlive()
{
return this->ProvinceCount > 0;
Expand Down Expand Up @@ -3406,8 +3446,8 @@ void CGrandStrategyHero::Die()
char buf[256];
snprintf(
buf, sizeof(buf), "if (GenericDialog ~= nil) then GenericDialog(\"%s\", \"%s\") end;",
("Ruler" + this->GetFullName() + " Dies").c_str(),
("Our ruler " + this->GetFullName() + " has died! May his soul rest in peace!").c_str()
("Ruler " + this->GetFullName() + " Dies").c_str(),
("Tragic news spread throughout our realm. Our ruler, " + this->GetFullName() + ", has died! May his soul rest in peace.").c_str()
);
CclCommand(buf);
} else if (
Expand Down Expand Up @@ -3445,7 +3485,7 @@ void CGrandStrategyHero::Die()
for (int j = 0; j < FactionMax; ++j) {
if (GrandStrategyGame.Factions[i][j]) {
if (GrandStrategyGame.Factions[i][j]->Ruler == this) {
GrandStrategyGame.Factions[i][j]->Ruler = NULL;
GrandStrategyGame.Factions[i][j]->SetRuler("");
}
} else {
break;
Expand Down Expand Up @@ -4859,8 +4899,28 @@ void CleanGrandStrategyGame()
GrandStrategyGame.Heroes[i]->State = 0;
GrandStrategyGame.Heroes[i]->Province = NULL;
GrandStrategyGame.Heroes[i]->Type = NULL;
for (size_t j = 0; j < GrandStrategyGame.Heroes[i]->Children.size(); ++j) {
if (GrandStrategyGame.Heroes[i]->Children[j]->Generated) { //remove children generated during gameplay
GrandStrategyGame.Heroes[i]->Children.erase(GrandStrategyGame.Heroes[i]->Children.begin() + j);
}
}
if (GrandStrategyGame.Heroes[i]->Father && GrandStrategyGame.Heroes[i]->Father->Generated) {
GrandStrategyGame.Heroes[i]->Father = NULL;
}
if (GrandStrategyGame.Heroes[i]->Mother && GrandStrategyGame.Heroes[i]->Mother->Generated) {
GrandStrategyGame.Heroes[i]->Mother = NULL;
}
}

for (size_t i = 0; i < GrandStrategyGame.Heroes.size();) {
if (GrandStrategyGame.Heroes[i]->Generated) { //if hero was generated during the game, delete it
delete GrandStrategyGame.Heroes[i];
GrandStrategyGame.Heroes.erase(GrandStrategyGame.Heroes.begin() + i);
} else {
++i;
}
}

GrandStrategyGame.WorldMapWidth = 0;
GrandStrategyGame.WorldMapHeight = 0;
GrandStrategyGame.ProvinceCount = 0;
Expand Down
5 changes: 5 additions & 0 deletions src/stratagus/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,10 @@ std::string FindAndReplaceStringBeginning(std::string text, const std::string& f

std::string TransliterateText(std::string text) //convert special characters into ones more legible for English-speakers
{
text = FindAndReplaceString(text, "Á", "A");
text = FindAndReplaceString(text, "á", "a");
text = FindAndReplaceString(text, "À", "A");
text = FindAndReplaceString(text, "à", "a");
text = FindAndReplaceString(text, "Ä", "A");
text = FindAndReplaceString(text, "ä", "a");
text = FindAndReplaceString(text, "Ā", "A");
Expand Down Expand Up @@ -615,6 +619,7 @@ std::string TransliterateText(std::string text) //convert special characters int

//replace endings in -r after consonants (which happens in the nominative for Old Norse); Source: Henry Adams Bellows (transl.), "The Poetic Edda", p. xxviii.
text = FindAndReplaceStringEnding(text, "dr", "d");
text = FindAndReplaceStringEnding(text, "fr", "f");
text = FindAndReplaceStringEnding(text, "gr", "g");
text = FindAndReplaceStringEnding(text, "kr", "k");
text = FindAndReplaceStringEnding(text, "nr", "n");
Expand Down
24 changes: 21 additions & 3 deletions src/unit/script_unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1661,7 +1661,7 @@ static int CclDefineGrandStrategyHero(lua_State *l)
LuaError(l, "incorrect argument (expected table)");
}

std::string hero_full_name = LuaToString(l, 1);
std::string hero_full_name = TransliterateText(LuaToString(l, 1));
CGrandStrategyHero *hero = GrandStrategyGame.GetHero(hero_full_name);
if (!hero) {
hero = new CGrandStrategyHero;
Expand All @@ -1674,9 +1674,9 @@ static int CclDefineGrandStrategyHero(lua_State *l)
const char *value = LuaToString(l, -2);

if (!strcmp(value, "Name")) {
hero->Name = LuaToString(l, -1);
hero->Name = TransliterateText(LuaToString(l, -1));
} else if (!strcmp(value, "Dynasty")) {
hero->Dynasty = LuaToString(l, -1);
hero->Dynasty = TransliterateText(LuaToString(l, -1));
} else if (!strcmp(value, "DefaultType")) {
hero->DefaultType = const_cast<CUnitType *>(&(*UnitTypes[UnitTypeIdByIdent(LuaToString(l, -1))]));
} else if (!strcmp(value, "Year")) {
Expand All @@ -1687,6 +1687,24 @@ static int CclDefineGrandStrategyHero(lua_State *l)
hero->Civilization = PlayerRaces.GetRaceIndexByName(LuaToString(l, -1));
} else if (!strcmp(value, "ProvinceOfOrigin")) {
hero->ProvinceOfOrigin = LuaToString(l, -1);
} else if (!strcmp(value, "Father")) {
std::string father_name = TransliterateText(LuaToString(l, -1));
CGrandStrategyHero *father = GrandStrategyGame.GetHero(father_name);
if (father) {
hero->Father = const_cast<CGrandStrategyHero *>(&(*father));
father->Children.push_back(hero);
} else {
LuaError(l, "Hero \"%s\" doesn't exist." _C_ father_name.c_str());
}
} else if (!strcmp(value, "Mother")) {
std::string mother_name = TransliterateText(LuaToString(l, -1));
CGrandStrategyHero *mother = GrandStrategyGame.GetHero(mother_name);
if (mother) {
hero->Mother = const_cast<CGrandStrategyHero *>(&(*mother));
mother->Children.push_back(hero);
} else {
LuaError(l, "Hero \"%s\" doesn't exist." _C_ mother_name.c_str());
}
} else {
LuaError(l, "Unsupported tag: %s" _C_ value);
}
Expand Down

0 comments on commit 845c81e

Please sign in to comment.