Skip to content

Commit

Permalink
Added ruler generation, if a faction has no preset ruler
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrettin committed Nov 17, 2015
1 parent 44029ce commit e80aeed
Show file tree
Hide file tree
Showing 9 changed files with 372 additions and 250 deletions.
2 changes: 1 addition & 1 deletion src/action/action_upgradeto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ static int TransformUnitIntoType(CUnit &unit, const CUnitType &newtype)
if (!new_personal_name.empty()) {
unit.Name = new_personal_name;
} else {
unit.GeneratePersonalName();
unit.Name = GeneratePersonalName(PlayerRaces.GetRaceIndexByName(unit.Type->Civilization.c_str()), unit.Type->Slot);
}
}
//Wyrmgus end
Expand Down
4 changes: 3 additions & 1 deletion src/include/grand_strategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ class CGrandStrategyFaction
void AcquireFactionTechnologies(int civilization, int faction);
void SetRuler(std::string hero_full_name);
void RulerSuccession();
void GenerateRuler();
bool IsAlive();
bool HasTechnologyClass(std::string technology_class_name);
bool CanFormFaction(int civilization, int faction);
Expand Down Expand Up @@ -302,7 +303,7 @@ class CGrandStrategyHero
CGrandStrategyHero() :
State(0), Year(0), DeathYear(0), Civilization(-1), Gender(0),
Generated(false),
Name(""), Dynasty(""), ProvinceOfOrigin(""),
Name(""), ExtraName(""), Dynasty(""), ProvinceOfOrigin(""),
DefaultType(NULL), Type(NULL), Province(NULL),
Father(NULL), Mother(NULL)
{
Expand All @@ -321,6 +322,7 @@ class CGrandStrategyHero
int Gender; /// Hero's gender
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 ExtraName; /// Extra given names of the hero (used if necessary to differentiate from existing heroes)
std::string Dynasty; /// Name of the hero's dynasty
std::string ProvinceOfOrigin; /// Province from which the hero originates
CUnitType *DefaultType;
Expand Down
4 changes: 0 additions & 4 deletions src/include/unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,6 @@ class CUnit
void AssignWorkerToMine(CUnit &mine);
void DeAssignWorkerFromMine(CUnit &mine);

//Wyrmgus start
void GeneratePersonalName();
//Wyrmgus end

/// Release a unit
void Release(bool final = false);

Expand Down
1 change: 1 addition & 0 deletions src/include/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ extern std::string TransliterateText(std::string text); /// Convert special c
extern std::string CapitalizeString(std::string text); /// Make the string become capitalized
extern std::string DecapitalizeString(std::string text); /// Make the string lose capitalization
extern std::string SeparateCapitalizedStringElements(std::string text); /// Make the string's capitalized elements become separated
extern std::string GeneratePersonalName(int civilization, int unit_type_id); /// Generates a personal name
//Wyrmgus end

#endif /* __UTIL_H__ */
84 changes: 78 additions & 6 deletions src/stratagus/grand_strategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3386,7 +3386,74 @@ void CGrandStrategyFaction::RulerSuccession()
return;
}

this->GenerateRuler(); //if all else failed, try to generate a ruler for the faction
}

void CGrandStrategyFaction::GenerateRuler()
{
this->Ruler = NULL;
std::vector<int> potential_ruler_unit_types;
if (PlayerRaces.Factions[this->Civilization][this->Faction]->Type == "tribe" || this->GovernmentType != GovernmentTypeTheocracy) { //exclude priests from ruling non-theocracies
if (PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("heroic-infantry")) != -1) {
potential_ruler_unit_types.push_back(PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("heroic-infantry")));
} else if (PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("veteran-infantry")) != -1) {
potential_ruler_unit_types.push_back(PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("veteran-infantry")));
} else if (PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("infantry")) != -1) {
potential_ruler_unit_types.push_back(PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("infantry")));
}
if (PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("shooter")) != -1) {
potential_ruler_unit_types.push_back(PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("shooter")));
}
if (PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("cavalry")) != -1) {
potential_ruler_unit_types.push_back(PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("cavalry")));
}
if (PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("flying-rider")) != -1) {
potential_ruler_unit_types.push_back(PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("flying-rider")));
}
} else { //only allow priests to rule theocracies
if (PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("priest")) != -1) {
potential_ruler_unit_types.push_back(PlayerRaces.GetFactionClassUnitType(this->Civilization, this->Faction, GetUnitTypeClassIndexByName("priest")));
}
}

int unit_type_id;
if (potential_ruler_unit_types.size() > 0) {
unit_type_id = potential_ruler_unit_types[SyncRand(potential_ruler_unit_types.size())];
} else {
return;
}

int civilization = PlayerRaces.GetRaceIndexByName(UnitTypes[unit_type_id]->Civilization.c_str()); //use unit type's civilization, so that names can be generated even for civilizations for which we don't have personal name language data defined
std::string hero_name = GeneratePersonalName(civilization, unit_type_id);

if (hero_name.empty()) { //if civilization can't generate personal names, return
return;
}

std::string hero_extra_name;
if (GrandStrategyGame.GetHero(hero_name) != NULL) { // generate extra given names if this name is already used by an existing hero
hero_extra_name = GeneratePersonalName(civilization, unit_type_id);
while (GrandStrategyGame.GetHero(hero_name + " " + hero_extra_name) != NULL) {
hero_extra_name += " " + GeneratePersonalName(civilization, unit_type_id);
}
}
CGrandStrategyHero *hero = new CGrandStrategyHero;
GrandStrategyGame.Heroes.push_back(hero);
hero->Name = hero_name;
hero->ExtraName = hero_extra_name;
hero->State = 2;
hero->Generated = true;
hero->DefaultType = const_cast<CUnitType *>(&(*UnitTypes[unit_type_id]));
hero->Type = const_cast<CUnitType *>(&(*UnitTypes[unit_type_id]));
hero->Year = GrandStrategyYear;
hero->DeathYear = GrandStrategyYear + (SyncRand(45) + 1); //average + 30 years after initially appearing
hero->Civilization = this->Civilization;
if (this->ProvinceCount == 0) {
fprintf(stderr, "Faction \"%s\" is generating a ruler, but has no provinces.\n", PlayerRaces.Factions[this->Civilization][this->Faction]->Name.c_str());
}
hero->ProvinceOfOrigin = GrandStrategyGame.Provinces[this->OwnedProvinces[SyncRand(this->ProvinceCount)]]->Name;
hero->Gender = MaleGender;
this->SetRuler(hero->GetFullName());
}

bool CGrandStrategyFaction::IsAlive()
Expand Down Expand Up @@ -3645,7 +3712,7 @@ void CGrandStrategyHero::Die()
this->Province = NULL;

this->State = 0;

//check if the hero is the ruler of a faction, and if so, remove it from that position
for (int i = 0; i < MAX_RACES; ++i) {
for (int j = 0; j < FactionMax; ++j) {
Expand Down Expand Up @@ -3673,11 +3740,14 @@ int CGrandStrategyHero::GetAdministrativeEfficiencyModifier()

std::string CGrandStrategyHero::GetFullName()
{
std::string full_name = this->Name;
if (!this->ExtraName.empty()) {
full_name += " " + this->ExtraName;
}
if (!this->Dynasty.empty()) {
return (this->Name + " " + this->Dynasty);
} else {
return this->Name;
full_name += " " + this->Dynasty;
}
return full_name;
}

std::string CGrandStrategyHero::GetRulerEffectsString()
Expand Down Expand Up @@ -5091,9 +5161,11 @@ 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) {
for (size_t j = 0; j < GrandStrategyGame.Heroes[i]->Children.size();) {
if (GrandStrategyGame.Heroes[i]->Children[j]->Generated) { //remove children generated during gameplay
GrandStrategyGame.Heroes[i]->Children.erase(GrandStrategyGame.Heroes[i]->Children.begin() + j);
} else {
++j;
}
}
if (GrandStrategyGame.Heroes[i]->Father && GrandStrategyGame.Heroes[i]->Father->Generated) {
Expand All @@ -5103,7 +5175,7 @@ void CleanGrandStrategyGame()
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];
Expand Down
39 changes: 39 additions & 0 deletions src/stratagus/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2807,6 +2807,45 @@ void SaveGrandStrategyGame(const std::string &filename)
}
}

for (size_t i = 0; i < GrandStrategyGame.Heroes.size(); ++i) { //save the generated heroes
if (GrandStrategyGame.Heroes[i]->Generated) {
fprintf(fd, "DefineGrandStrategyHero(\"%s\", {\n", GrandStrategyGame.Heroes[i]->GetFullName().c_str());
fprintf(fd, "\tName = \"%s\",\n", GrandStrategyGame.Heroes[i]->Name.c_str());
if (!GrandStrategyGame.Heroes[i]->ExtraName.empty()) {
fprintf(fd, "\tExtraName = \"%s\",\n", GrandStrategyGame.Heroes[i]->ExtraName.c_str());
}
if (!GrandStrategyGame.Heroes[i]->Dynasty.empty()) {
fprintf(fd, "\tExtraName = \"%s\",\n", GrandStrategyGame.Heroes[i]->Dynasty.c_str());
}
if (GrandStrategyGame.Heroes[i]->Gender != NoGender) {
fprintf(fd, "\tGender = \"%s\",\n", GetGenderNameById(GrandStrategyGame.Heroes[i]->Gender).c_str());
}
if (GrandStrategyGame.Heroes[i]->DefaultType != NULL) {
fprintf(fd, "\tDefaultType = \"%s\",\n", GrandStrategyGame.Heroes[i]->DefaultType->Ident.c_str());
}
if (GrandStrategyGame.Heroes[i]->Civilization != -1) {
fprintf(fd, "\tCivilization = \"%s\",\n", PlayerRaces.Name[GrandStrategyGame.Heroes[i]->Civilization].c_str());
}
if (!GrandStrategyGame.Heroes[i]->ProvinceOfOrigin.empty()) {
fprintf(fd, "\tProvinceOfOrigin = \"%s\",\n", GrandStrategyGame.Heroes[i]->ProvinceOfOrigin.c_str());
}
if (GrandStrategyGame.Heroes[i]->Year != 0) {
fprintf(fd, "\tYear = %d,\n", GrandStrategyGame.Heroes[i]->Year);
}
if (GrandStrategyGame.Heroes[i]->DeathYear != 0) {
fprintf(fd, "\tDeathYear = %d,\n", GrandStrategyGame.Heroes[i]->DeathYear);
}
if (GrandStrategyGame.Heroes[i]->Father != NULL) {
fprintf(fd, "\tFather = \"%s\",\n", GrandStrategyGame.Heroes[i]->Father->GetFullName().c_str());
}
if (GrandStrategyGame.Heroes[i]->Mother != NULL) {
fprintf(fd, "\tMother = \"%s\",\n", GrandStrategyGame.Heroes[i]->Mother->GetFullName().c_str());
}
fprintf(fd, "\tGenerated = \"true\"\n");
fprintf(fd, "})\n");
}
}

for (size_t i = 0; i < GrandStrategyGame.Heroes.size(); ++i) {
if (GrandStrategyGame.Heroes[i]->State != 0) {
fprintf(fd, "CreateGrandStrategyHero(\"%s\")\n", GrandStrategyGame.Heroes[i]->GetFullName().c_str()); //save existing heroes
Expand Down
Loading

0 comments on commit e80aeed

Please sign in to comment.