diff --git a/src/action/action_upgradeto.cpp b/src/action/action_upgradeto.cpp index 4b2e6a63c..9cfead907 100644 --- a/src/action/action_upgradeto.cpp +++ b/src/action/action_upgradeto.cpp @@ -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 diff --git a/src/include/grand_strategy.h b/src/include/grand_strategy.h index 7dc2d8cc1..bc15455e0 100644 --- a/src/include/grand_strategy.h +++ b/src/include/grand_strategy.h @@ -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); @@ -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) { @@ -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; diff --git a/src/include/unit.h b/src/include/unit.h index 172b2d3ca..22d261fec 100644 --- a/src/include/unit.h +++ b/src/include/unit.h @@ -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); diff --git a/src/include/util.h b/src/include/util.h index b6f877a34..502ddbc0f 100644 --- a/src/include/util.h +++ b/src/include/util.h @@ -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__ */ diff --git a/src/stratagus/grand_strategy.cpp b/src/stratagus/grand_strategy.cpp index 95b6aa14a..7389899a7 100644 --- a/src/stratagus/grand_strategy.cpp +++ b/src/stratagus/grand_strategy.cpp @@ -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 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(&(*UnitTypes[unit_type_id])); + hero->Type = const_cast(&(*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() @@ -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) { @@ -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() @@ -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) { @@ -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]; diff --git a/src/stratagus/script.cpp b/src/stratagus/script.cpp index 082d1f2bb..f8367bdaa 100644 --- a/src/stratagus/script.cpp +++ b/src/stratagus/script.cpp @@ -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 diff --git a/src/stratagus/util.cpp b/src/stratagus/util.cpp index 6c4cef955..decdd2758 100644 --- a/src/stratagus/util.cpp +++ b/src/stratagus/util.cpp @@ -522,6 +522,10 @@ void PrintOnStdOut(const char *format, ...) } //Wyrmgus start +#include "editor.h" //for personal name generation +#include "player.h" //for personal name generation +#include "unittype.h" //for personal name generation + std::string FindAndReplaceString(std::string text, const std::string& find, const std::string& replace) { size_t pos = 0; while ((pos = text.find(find, pos)) != std::string::npos) { @@ -758,4 +762,245 @@ std::string SeparateCapitalizedStringElements(std::string text) } return text; } + +/** +** Generates a personal name. +*/ +std::string GeneratePersonalName(int civilization, int unit_type_id) +{ + if (civilization == -1) { + return ""; + } + + const CUnitType &type = *UnitTypes[unit_type_id]; + std::string personal_name; + + if (!type.DefaultName.empty() || Editor.Running == EditorEditing) { // always set the personal name to the default name if in the editor + personal_name = type.DefaultName; + } else if (!type.PersonalNames[0].empty() || !type.PersonalNamePrefixes[0].empty()) { + int PersonalNameCount = 0; + int PersonalNamePrefixCount = 0; + int PersonalNameSuffixCount = 0; + for (int i = 0; i < PersonalNameMax; ++i) { + if (!type.PersonalNames[i].empty()) { + PersonalNameCount += 1; + } + } + for (int i = 0; i < PersonalNameMax; ++i) { + if (!type.PersonalNamePrefixes[i].empty()) { + PersonalNamePrefixCount += 1; + } + } + for (int i = 0; i < PersonalNameMax; ++i) { + if (!type.PersonalNameSuffixes[i].empty()) { + PersonalNameSuffixCount += 1; + } + } + if (PersonalNameCount > 0 || PersonalNamePrefixCount > 0) { + int PersonalNameProbability = PersonalNameCount * 10000 / (PersonalNameCount + (PersonalNamePrefixCount * PersonalNameSuffixCount)); + if (SyncRand(10000) < PersonalNameProbability) { + personal_name = type.PersonalNames[SyncRand(PersonalNameCount)]; + } else { + personal_name = type.PersonalNamePrefixes[SyncRand(PersonalNamePrefixCount)]; + personal_name += type.PersonalNameSuffixes[SyncRand(PersonalNameSuffixCount)]; + } + } + } else if ( + type.BoolFlag[ORGANIC_INDEX].value + && !type.Civilization.empty() + && ( + !PlayerRaces.PersonalNames[civilization][0].empty() + || !PlayerRaces.PersonalNamePrefixes[civilization][0].empty() + || PlayerRaces.LanguageNouns[civilization][0] + || PlayerRaces.LanguageVerbs[civilization][0] + || PlayerRaces.LanguageAdjectives[civilization][0] + ) + ) { + int PersonalNameCount = 0; + std::string PersonalNames[PersonalNameMax]; + int PersonalNamePrefixCount = 0; + std::string PersonalNamePrefixes[PersonalNameMax]; + int PersonalNameSuffixCount = 0; + std::string PersonalNameSuffixes[PersonalNameMax]; + int PersonalNameInfixCount = 0; + std::string PersonalNameInfixes[PersonalNameMax]; + for (int i = 0; i < PersonalNameMax; ++i) { + if (PlayerRaces.PersonalNames[civilization][i].empty()) { + break; + } + PersonalNames[PersonalNameCount] = PlayerRaces.PersonalNames[civilization][i]; + PersonalNameCount += 1; + } + for (int i = 0; i < PersonalNameMax; ++i) { + if (PlayerRaces.PersonalNamePrefixes[civilization][i].empty()) { + break; + } + PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.PersonalNamePrefixes[civilization][i]; + PersonalNamePrefixCount += 1; + } + for (int i = 0; i < PersonalNameMax; ++i) { + if (PlayerRaces.PersonalNameSuffixes[civilization][i].empty()) { + break; + } + PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.PersonalNameSuffixes[civilization][i]; + PersonalNameSuffixCount += 1; + } + + for (int i = 0; i < LanguageWordMax; ++i) { + if (!PlayerRaces.LanguageNouns[civilization][i]) { + break; + } + if (PlayerRaces.LanguageNouns[civilization][i]->PersonalName) { // nouns which can be used as personal names without compounding + if (!PlayerRaces.LanguageNouns[civilization][i]->SingularNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->NameSingular) { + PersonalNames[PersonalNameCount] = PlayerRaces.LanguageNouns[civilization][i]->SingularNominative; + PersonalNameCount += 1; + } + if (!PlayerRaces.LanguageNouns[civilization][i]->PluralNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->NamePlural) { + PersonalNames[PersonalNameCount] = PlayerRaces.LanguageNouns[civilization][i]->PluralNominative; + PersonalNameCount += 1; + } + } + if (PlayerRaces.LanguageNouns[civilization][i]->PrefixPersonalName) { + if (!PlayerRaces.LanguageNouns[civilization][i]->SingularNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->PrefixSingular) { + PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageNouns[civilization][i]->SingularNominative; //using the nominative, is it always the best choice? + PersonalNamePrefixCount += 1; + } + if (!PlayerRaces.LanguageNouns[civilization][i]->PluralNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->PrefixPlural) { + PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageNouns[civilization][i]->PluralNominative; + PersonalNamePrefixCount += 1; + } + } + if (PlayerRaces.LanguageNouns[civilization][i]->SuffixPersonalName) { + if (!PlayerRaces.LanguageNouns[civilization][i]->SingularNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->SuffixSingular) { + PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageNouns[civilization][i]->SingularNominative; + PersonalNameSuffixCount += 1; + } + if (!PlayerRaces.LanguageNouns[civilization][i]->PluralNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->SuffixPlural) { + PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageNouns[civilization][i]->PluralNominative; + PersonalNameSuffixCount += 1; + } + } + if (PlayerRaces.LanguageNouns[civilization][i]->InfixPersonalName) { + if (!PlayerRaces.LanguageNouns[civilization][i]->SingularNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->InfixSingular) { + PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageNouns[civilization][i]->SingularNominative; + PersonalNameInfixCount += 1; + } + if (!PlayerRaces.LanguageNouns[civilization][i]->PluralNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->InfixPlural) { + PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageNouns[civilization][i]->PluralNominative; + PersonalNameInfixCount += 1; + } + } + } + + for (int i = 0; i < LanguageWordMax; ++i) { + if (!PlayerRaces.LanguageVerbs[civilization][i]) { + break; + } + if (PlayerRaces.LanguageVerbs[civilization][i]->PersonalName) { // only using verb participles for now; maybe should add more possibilities? + if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent.empty()) { + PersonalNames[PersonalNameCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent; + PersonalNameCount += 1; + } + if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast.empty()) { + PersonalNames[PersonalNameCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast; + PersonalNameCount += 1; + } + } + if (PlayerRaces.LanguageVerbs[civilization][i]->PrefixPersonalName) { // only using verb participles for now; maybe should add more possibilities? + if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent.empty()) { + PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent; + PersonalNamePrefixCount += 1; + } + if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast.empty()) { + PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast; + PersonalNamePrefixCount += 1; + } + } + if (PlayerRaces.LanguageVerbs[civilization][i]->SuffixPersonalName) { + if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent.empty()) { + PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent; + PersonalNameSuffixCount += 1; + } + if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast.empty()) { + PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast; + PersonalNameSuffixCount += 1; + } + } + if (PlayerRaces.LanguageVerbs[civilization][i]->InfixPersonalName) { + if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent.empty()) { + PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent; + PersonalNameInfixCount += 1; + } + if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast.empty()) { + PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast; + PersonalNameInfixCount += 1; + } + } + } + + for (int i = 0; i < LanguageWordMax; ++i) { + if (!PlayerRaces.LanguageAdjectives[civilization][i]) { + break; + } + if (PlayerRaces.LanguageAdjectives[civilization][i]->PersonalName) { + if (!PlayerRaces.LanguageAdjectives[civilization][i]->Word.empty()) { + PersonalNames[PersonalNameCount] = PlayerRaces.LanguageAdjectives[civilization][i]->Word; + PersonalNameCount += 1; + } + } + if (PlayerRaces.LanguageAdjectives[civilization][i]->PrefixPersonalName) { + if (!PlayerRaces.LanguageAdjectives[civilization][i]->Word.empty()) { + PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageAdjectives[civilization][i]->Word; + PersonalNamePrefixCount += 1; + } + } + if (PlayerRaces.LanguageAdjectives[civilization][i]->SuffixPersonalName) { + if (!PlayerRaces.LanguageAdjectives[civilization][i]->Word.empty()) { + PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageAdjectives[civilization][i]->Word; + PersonalNameSuffixCount += 1; + } + } + if (PlayerRaces.LanguageAdjectives[civilization][i]->InfixPersonalName) { + if (!PlayerRaces.LanguageAdjectives[civilization][i]->Word.empty()) { + PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageAdjectives[civilization][i]->Word; + PersonalNameInfixCount += 1; + } + } + } + + if (PersonalNameCount > 0 || PersonalNamePrefixCount > 0 || PersonalNameSuffixCount > 0) { + int random_number = SyncRand(PersonalNameCount + (PersonalNamePrefixCount * PersonalNameSuffixCount) + (((PersonalNamePrefixCount + PersonalNameSuffixCount) / 2) * PersonalNameInfixCount)); + if (random_number < PersonalNameCount) { //entire name + personal_name = PersonalNames[SyncRand(PersonalNameCount)]; + } else if (random_number < PersonalNameCount + (PersonalNamePrefixCount * PersonalNameSuffixCount)) { //prefix + suffix + personal_name = PersonalNamePrefixes[SyncRand(PersonalNamePrefixCount)]; + std::string suffix = PersonalNameSuffixes[SyncRand(PersonalNameSuffixCount)]; + suffix = DecapitalizeString(suffix); + personal_name += suffix; + } else if (random_number < PersonalNameCount + (PersonalNamePrefixCount * PersonalNameSuffixCount) + (((PersonalNamePrefixCount + PersonalNameSuffixCount) / 2) * PersonalNameInfixCount)) { //prefix + infix + suffix + std::string prefix = PersonalNamePrefixes[SyncRand(PersonalNamePrefixCount)]; + std::string infix = PersonalNameInfixes[SyncRand(PersonalNameInfixCount)]; + infix = DecapitalizeString(infix); + std::string suffix = PersonalNameSuffixes[SyncRand(PersonalNameSuffixCount)]; + suffix = DecapitalizeString(suffix); + if (prefix.substr(prefix.size() - 1, 1) == "d" && infix.substr(0, 1) == "d") { //if the prefix ends with "d" and the infix begins with "d", eliminate one instance of "d" + prefix = FindAndReplaceStringEnding(prefix, "d", ""); + } + if (infix.substr(infix.size() - 2, 2) == "th" && suffix.substr(0, 2) == "th") { //if the last two characters of the infix are "th", and the suffix begins with "th", then eliminate the infix's "th", to make this be just one instance of "th" + infix = FindAndReplaceStringEnding(infix, "th", ""); + } + if (infix.substr(infix.size() - 1, 1) == "d" && suffix.substr(0, 1) == "d") { //if the infix ends with "d" and the suffix begins with "d", eliminate one instance of "d" + infix = FindAndReplaceStringEnding(infix, "d", ""); + } + personal_name = prefix; + personal_name += infix; + personal_name += suffix; + } + } + } + + personal_name = TransliterateText(personal_name); + + return personal_name; +} //Wyrmgus end diff --git a/src/unit/script_unit.cpp b/src/unit/script_unit.cpp index a4d53a014..15dfb24d5 100644 --- a/src/unit/script_unit.cpp +++ b/src/unit/script_unit.cpp @@ -1675,6 +1675,8 @@ static int CclDefineGrandStrategyHero(lua_State *l) if (!strcmp(value, "Name")) { hero->Name = TransliterateText(LuaToString(l, -1)); + } else if (!strcmp(value, "ExtraName")) { + hero->ExtraName = TransliterateText(LuaToString(l, -1)); } else if (!strcmp(value, "Dynasty")) { hero->Dynasty = TransliterateText(LuaToString(l, -1)); } else if (!strcmp(value, "DefaultType")) { @@ -1721,6 +1723,8 @@ static int CclDefineGrandStrategyHero(lua_State *l) } } else if (!strcmp(value, "Gender")) { hero->Gender = GetGenderIdByName(LuaToString(l, -1)); + } else if (!strcmp(value, "Generated")) { + hero->Generated = LuaToBoolean(l, -1); } else { LuaError(l, "Unsupported tag: %s" _C_ value); } diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index 8fdcf9d7b..41cfeb3b8 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -495,243 +495,6 @@ void CUnit::Init() Goal = NULL; } -//Wyrmgus start -/** -** Generates the unit's personal name. -*/ -void CUnit::GeneratePersonalName() -{ - const CUnitType &type = *Type; - int civilization = PlayerRaces.GetRaceIndexByName(type.Civilization.c_str()); - - if (!type.DefaultName.empty() || Editor.Running == EditorEditing) { // always set the personal name to the default name if in the editor - Name = type.DefaultName; - } else if (!type.PersonalNames[0].empty() || !type.PersonalNamePrefixes[0].empty()) { - int PersonalNameCount = 0; - int PersonalNamePrefixCount = 0; - int PersonalNameSuffixCount = 0; - for (int i = 0; i < PersonalNameMax; ++i) { - if (!type.PersonalNames[i].empty()) { - PersonalNameCount += 1; - } - } - for (int i = 0; i < PersonalNameMax; ++i) { - if (!type.PersonalNamePrefixes[i].empty()) { - PersonalNamePrefixCount += 1; - } - } - for (int i = 0; i < PersonalNameMax; ++i) { - if (!type.PersonalNameSuffixes[i].empty()) { - PersonalNameSuffixCount += 1; - } - } - if (PersonalNameCount > 0 || PersonalNamePrefixCount > 0) { - int PersonalNameProbability = PersonalNameCount * 10000 / (PersonalNameCount + (PersonalNamePrefixCount * PersonalNameSuffixCount)); - if (SyncRand(10000) < PersonalNameProbability) { - Name = type.PersonalNames[SyncRand(PersonalNameCount)]; - } else { - Name = type.PersonalNamePrefixes[SyncRand(PersonalNamePrefixCount)]; - Name += type.PersonalNameSuffixes[SyncRand(PersonalNameSuffixCount)]; - } - } - } else if ( - type.BoolFlag[ORGANIC_INDEX].value - && !type.Civilization.empty() - && ( - !PlayerRaces.PersonalNames[civilization][0].empty() - || !PlayerRaces.PersonalNamePrefixes[civilization][0].empty() - || PlayerRaces.LanguageNouns[civilization][0] - || PlayerRaces.LanguageVerbs[civilization][0] - || PlayerRaces.LanguageAdjectives[civilization][0] - ) - ) { - int PersonalNameCount = 0; - std::string PersonalNames[PersonalNameMax]; - int PersonalNamePrefixCount = 0; - std::string PersonalNamePrefixes[PersonalNameMax]; - int PersonalNameSuffixCount = 0; - std::string PersonalNameSuffixes[PersonalNameMax]; - int PersonalNameInfixCount = 0; - std::string PersonalNameInfixes[PersonalNameMax]; - for (int i = 0; i < PersonalNameMax; ++i) { - if (PlayerRaces.PersonalNames[civilization][i].empty()) { - break; - } - PersonalNames[PersonalNameCount] = PlayerRaces.PersonalNames[civilization][i]; - PersonalNameCount += 1; - } - for (int i = 0; i < PersonalNameMax; ++i) { - if (PlayerRaces.PersonalNamePrefixes[civilization][i].empty()) { - break; - } - PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.PersonalNamePrefixes[civilization][i]; - PersonalNamePrefixCount += 1; - } - for (int i = 0; i < PersonalNameMax; ++i) { - if (PlayerRaces.PersonalNameSuffixes[civilization][i].empty()) { - break; - } - PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.PersonalNameSuffixes[civilization][i]; - PersonalNameSuffixCount += 1; - } - - for (int i = 0; i < LanguageWordMax; ++i) { - if (!PlayerRaces.LanguageNouns[civilization][i]) { - break; - } - if (PlayerRaces.LanguageNouns[civilization][i]->PersonalName) { // nouns which can be used as personal names without compounding - if (!PlayerRaces.LanguageNouns[civilization][i]->SingularNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->NameSingular) { - PersonalNames[PersonalNameCount] = PlayerRaces.LanguageNouns[civilization][i]->SingularNominative; - PersonalNameCount += 1; - } - if (!PlayerRaces.LanguageNouns[civilization][i]->PluralNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->NamePlural) { - PersonalNames[PersonalNameCount] = PlayerRaces.LanguageNouns[civilization][i]->PluralNominative; - PersonalNameCount += 1; - } - } - if (PlayerRaces.LanguageNouns[civilization][i]->PrefixPersonalName) { - if (!PlayerRaces.LanguageNouns[civilization][i]->SingularNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->PrefixSingular) { - PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageNouns[civilization][i]->SingularNominative; //using the nominative, is it always the best choice? - PersonalNamePrefixCount += 1; - } - if (!PlayerRaces.LanguageNouns[civilization][i]->PluralNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->PrefixPlural) { - PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageNouns[civilization][i]->PluralNominative; - PersonalNamePrefixCount += 1; - } - } - if (PlayerRaces.LanguageNouns[civilization][i]->SuffixPersonalName) { - if (!PlayerRaces.LanguageNouns[civilization][i]->SingularNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->SuffixSingular) { - PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageNouns[civilization][i]->SingularNominative; - PersonalNameSuffixCount += 1; - } - if (!PlayerRaces.LanguageNouns[civilization][i]->PluralNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->SuffixPlural) { - PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageNouns[civilization][i]->PluralNominative; - PersonalNameSuffixCount += 1; - } - } - if (PlayerRaces.LanguageNouns[civilization][i]->InfixPersonalName) { - if (!PlayerRaces.LanguageNouns[civilization][i]->SingularNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->InfixSingular) { - PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageNouns[civilization][i]->SingularNominative; - PersonalNameInfixCount += 1; - } - if (!PlayerRaces.LanguageNouns[civilization][i]->PluralNominative.empty() && PlayerRaces.LanguageNouns[civilization][i]->InfixPlural) { - PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageNouns[civilization][i]->PluralNominative; - PersonalNameInfixCount += 1; - } - } - } - - for (int i = 0; i < LanguageWordMax; ++i) { - if (!PlayerRaces.LanguageVerbs[civilization][i]) { - break; - } - if (PlayerRaces.LanguageVerbs[civilization][i]->PersonalName) { // only using verb participles for now; maybe should add more possibilities? - if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent.empty()) { - PersonalNames[PersonalNameCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent; - PersonalNameCount += 1; - } - if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast.empty()) { - PersonalNames[PersonalNameCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast; - PersonalNameCount += 1; - } - } - if (PlayerRaces.LanguageVerbs[civilization][i]->PrefixPersonalName) { // only using verb participles for now; maybe should add more possibilities? - if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent.empty()) { - PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent; - PersonalNamePrefixCount += 1; - } - if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast.empty()) { - PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast; - PersonalNamePrefixCount += 1; - } - } - if (PlayerRaces.LanguageVerbs[civilization][i]->SuffixPersonalName) { - if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent.empty()) { - PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent; - PersonalNameSuffixCount += 1; - } - if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast.empty()) { - PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast; - PersonalNameSuffixCount += 1; - } - } - if (PlayerRaces.LanguageVerbs[civilization][i]->InfixPersonalName) { - if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent.empty()) { - PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePresent; - PersonalNameInfixCount += 1; - } - if (!PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast.empty()) { - PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageVerbs[civilization][i]->ParticiplePast; - PersonalNameInfixCount += 1; - } - } - } - - for (int i = 0; i < LanguageWordMax; ++i) { - if (!PlayerRaces.LanguageAdjectives[civilization][i]) { - break; - } - if (PlayerRaces.LanguageAdjectives[civilization][i]->PersonalName) { - if (!PlayerRaces.LanguageAdjectives[civilization][i]->Word.empty()) { - PersonalNames[PersonalNameCount] = PlayerRaces.LanguageAdjectives[civilization][i]->Word; - PersonalNameCount += 1; - } - } - if (PlayerRaces.LanguageAdjectives[civilization][i]->PrefixPersonalName) { - if (!PlayerRaces.LanguageAdjectives[civilization][i]->Word.empty()) { - PersonalNamePrefixes[PersonalNamePrefixCount] = PlayerRaces.LanguageAdjectives[civilization][i]->Word; - PersonalNamePrefixCount += 1; - } - } - if (PlayerRaces.LanguageAdjectives[civilization][i]->SuffixPersonalName) { - if (!PlayerRaces.LanguageAdjectives[civilization][i]->Word.empty()) { - PersonalNameSuffixes[PersonalNameSuffixCount] = PlayerRaces.LanguageAdjectives[civilization][i]->Word; - PersonalNameSuffixCount += 1; - } - } - if (PlayerRaces.LanguageAdjectives[civilization][i]->InfixPersonalName) { - if (!PlayerRaces.LanguageAdjectives[civilization][i]->Word.empty()) { - PersonalNameInfixes[PersonalNameInfixCount] = PlayerRaces.LanguageAdjectives[civilization][i]->Word; - PersonalNameInfixCount += 1; - } - } - } - - if (PersonalNameCount > 0 || PersonalNamePrefixCount > 0 || PersonalNameSuffixCount > 0) { - int random_number = SyncRand(PersonalNameCount + (PersonalNamePrefixCount * PersonalNameSuffixCount) + (((PersonalNamePrefixCount + PersonalNameSuffixCount) / 2) * PersonalNameInfixCount)); - if (random_number < PersonalNameCount) { //entire name - Name = PersonalNames[SyncRand(PersonalNameCount)]; - } else if (random_number < PersonalNameCount + (PersonalNamePrefixCount * PersonalNameSuffixCount)) { //prefix + suffix - Name = PersonalNamePrefixes[SyncRand(PersonalNamePrefixCount)]; - std::string suffix = PersonalNameSuffixes[SyncRand(PersonalNameSuffixCount)]; - suffix = DecapitalizeString(suffix); - Name += suffix; - } else if (random_number < PersonalNameCount + (PersonalNamePrefixCount * PersonalNameSuffixCount) + (((PersonalNamePrefixCount + PersonalNameSuffixCount) / 2) * PersonalNameInfixCount)) { //prefix + infix + suffix - std::string prefix = PersonalNamePrefixes[SyncRand(PersonalNamePrefixCount)]; - std::string infix = PersonalNameInfixes[SyncRand(PersonalNameInfixCount)]; - infix = DecapitalizeString(infix); - std::string suffix = PersonalNameSuffixes[SyncRand(PersonalNameSuffixCount)]; - suffix = DecapitalizeString(suffix); - if (prefix.substr(prefix.size() - 1, 1) == "d" && infix.substr(0, 1) == "d") { //if the prefix ends with "d" and the infix begins with "d", eliminate one instance of "d" - prefix = FindAndReplaceStringEnding(prefix, "d", ""); - } - if (infix.substr(infix.size() - 2, 2) == "th" && suffix.substr(0, 2) == "th") { //if the last two characters of the infix are "th", and the suffix begins with "th", then eliminate the infix's "th", to make this be just one instance of "th" - infix = FindAndReplaceStringEnding(infix, "th", ""); - } - if (infix.substr(infix.size() - 1, 1) == "d" && suffix.substr(0, 1) == "d") { //if the infix ends with "d" and the suffix begins with "d", eliminate one instance of "d" - infix = FindAndReplaceStringEnding(infix, "d", ""); - } - Name = prefix; - Name += infix; - Name += suffix; - } - } - } - - Name = TransliterateText(Name); -} -//Wyrmgus end - /** ** Release an unit. ** @@ -864,7 +627,7 @@ void CUnit::Init(const CUnitType &type) } //set the unit's personal name, if applicable - GeneratePersonalName(); + Name = GeneratePersonalName(PlayerRaces.GetRaceIndexByName(Type->Civilization.c_str()), Type->Slot); //Wyrmgus end // Set a heading for the unit if it Handles Directions