mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Merge pull request #3627 from IvanSavenko/random_town_names
Town names randomization fix
This commit is contained in:
commit
7c843ff0f7
@ -832,10 +832,7 @@ void CServerHandler::onPacketReceived(const std::shared_ptr<INetworkConnection>
|
||||
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
|
||||
|
||||
if(getState() == EClientState::DISCONNECTING)
|
||||
{
|
||||
assert(0); //Should not be possible - socket must be closed at this point
|
||||
return;
|
||||
}
|
||||
|
||||
CPack * pack = logicConnection->retrievePack(message);
|
||||
ServerHandlerCPackVisitor visitor(*this);
|
||||
|
@ -36,14 +36,18 @@ namespace RandomGeneratorUtil
|
||||
template<typename Container>
|
||||
auto nextItem(const Container & container, vstd::RNG & rand) -> decltype(std::begin(container))
|
||||
{
|
||||
assert(!container.empty());
|
||||
if(container.empty())
|
||||
throw std::runtime_error("Unable to select random item from empty container!");
|
||||
|
||||
return std::next(container.begin(), rand.getInt64Range(0, container.size() - 1)());
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
auto nextItem(Container & container, vstd::RNG & rand) -> decltype(std::begin(container))
|
||||
{
|
||||
assert(!container.empty());
|
||||
if(container.empty())
|
||||
throw std::runtime_error("Unable to select random item from empty container!");
|
||||
|
||||
return std::next(container.begin(), rand.getInt64Range(0, container.size() - 1)());
|
||||
}
|
||||
|
||||
|
@ -37,25 +37,25 @@ void CRandomGenerator::resetSeed()
|
||||
|
||||
TRandI CRandomGenerator::getIntRange(int lower, int upper)
|
||||
{
|
||||
assert(lower <= upper);
|
||||
return std::bind(TIntDist(lower, upper), std::ref(rand));
|
||||
if (lower <= upper)
|
||||
return std::bind(TIntDist(lower, upper), std::ref(rand));
|
||||
throw std::runtime_error("Invalid range provided: " + std::to_string(lower) + " ... " + std::to_string(upper));
|
||||
}
|
||||
|
||||
vstd::TRandI64 CRandomGenerator::getInt64Range(int64_t lower, int64_t upper)
|
||||
{
|
||||
assert(lower <= upper);
|
||||
return std::bind(TInt64Dist(lower, upper), std::ref(rand));
|
||||
if(lower <= upper)
|
||||
return std::bind(TInt64Dist(lower, upper), std::ref(rand));
|
||||
throw std::runtime_error("Invalid range provided: " + std::to_string(lower) + " ... " + std::to_string(upper));
|
||||
}
|
||||
|
||||
int CRandomGenerator::nextInt(int upper)
|
||||
{
|
||||
assert(0 <= upper);
|
||||
return getIntRange(0, upper)();
|
||||
}
|
||||
|
||||
int CRandomGenerator::nextInt(int lower, int upper)
|
||||
{
|
||||
assert(lower <= upper);
|
||||
return getIntRange(lower, upper)();
|
||||
}
|
||||
|
||||
@ -66,19 +66,19 @@ int CRandomGenerator::nextInt()
|
||||
|
||||
vstd::TRand CRandomGenerator::getDoubleRange(double lower, double upper)
|
||||
{
|
||||
assert(lower <= upper);
|
||||
return std::bind(TRealDist(lower, upper), std::ref(rand));
|
||||
if(lower <= upper)
|
||||
return std::bind(TRealDist(lower, upper), std::ref(rand));
|
||||
throw std::runtime_error("Invalid range provided: " + std::to_string(lower) + " ... " + std::to_string(upper));
|
||||
|
||||
}
|
||||
|
||||
double CRandomGenerator::nextDouble(double upper)
|
||||
{
|
||||
assert(0 <= upper);
|
||||
return getDoubleRange(0, upper)();
|
||||
}
|
||||
|
||||
double CRandomGenerator::nextDouble(double lower, double upper)
|
||||
{
|
||||
assert(lower <= upper);
|
||||
return getDoubleRange(lower, upper)();
|
||||
}
|
||||
|
||||
|
@ -243,11 +243,6 @@ CTown::~CTown()
|
||||
str.dellNull();
|
||||
}
|
||||
|
||||
std::string CTown::getRandomNameTranslated(size_t index) const
|
||||
{
|
||||
return VLC->generaltexth->translate(getRandomNameTextID(index));
|
||||
}
|
||||
|
||||
std::string CTown::getRandomNameTextID(size_t index) const
|
||||
{
|
||||
return TextIdentifier("faction", faction->modScope, faction->identifier, "randomName", index).get();
|
||||
|
@ -217,7 +217,6 @@ public:
|
||||
void setGreeting(BuildingSubID::EBuildingSubID subID, const std::string & message) const; //may affect only mutable field
|
||||
BuildingID getBuildingType(BuildingSubID::EBuildingSubID subID) const;
|
||||
|
||||
std::string getRandomNameTranslated(size_t index) const;
|
||||
std::string getRandomNameTextID(size_t index) const;
|
||||
size_t getRandomNamesCount() const;
|
||||
|
||||
|
@ -458,6 +458,11 @@ std::string FactionID::entityType()
|
||||
return "faction";
|
||||
}
|
||||
|
||||
const CFaction * FactionID::toFaction() const
|
||||
{
|
||||
return dynamic_cast<const CFaction*>(toEntity(VLC));
|
||||
}
|
||||
|
||||
const Faction * FactionID::toEntity(const Services * service) const
|
||||
{
|
||||
return service->factions()->getByIndex(num);
|
||||
|
@ -24,6 +24,7 @@ class CHero;
|
||||
class CHeroClass;
|
||||
class HeroClass;
|
||||
class HeroTypeService;
|
||||
class CFaction;
|
||||
class Faction;
|
||||
class Skill;
|
||||
class RoadType;
|
||||
@ -261,6 +262,7 @@ public:
|
||||
|
||||
static si32 decode(const std::string& identifier);
|
||||
static std::string encode(const si32 index);
|
||||
const CFaction * toFaction() const;
|
||||
const Faction * toEntity(const Services * service) const;
|
||||
static std::string entityType();
|
||||
|
||||
|
@ -222,6 +222,7 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, Load::Prog
|
||||
initHeroes();
|
||||
initStartingBonus();
|
||||
initTowns();
|
||||
initTownNames();
|
||||
placeHeroesInTowns();
|
||||
initMapObjects();
|
||||
buildBonusSystemTree();
|
||||
@ -763,6 +764,50 @@ void CGameState::initStartingBonus()
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::initTownNames()
|
||||
{
|
||||
std::map<FactionID, std::vector<int>> availableNames;
|
||||
for(const auto & faction : VLC->townh->getDefaultAllowed())
|
||||
{
|
||||
std::vector<int> potentialNames;
|
||||
if(faction.toFaction()->town->getRandomNamesCount() > 0)
|
||||
{
|
||||
for(int i = 0; i < faction.toFaction()->town->getRandomNamesCount(); ++i)
|
||||
potentialNames.push_back(i);
|
||||
|
||||
availableNames[faction] = potentialNames;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto & vti : map->towns)
|
||||
{
|
||||
assert(vti->town);
|
||||
|
||||
if(!vti->getNameTextID().empty())
|
||||
continue;
|
||||
|
||||
FactionID faction = vti->getFaction();
|
||||
|
||||
if(availableNames.empty())
|
||||
{
|
||||
logGlobal->warn("Failed to find available name for a random town!");
|
||||
vti->setNameTextId("core.genrltxt.508"); // Unnamed
|
||||
continue;
|
||||
}
|
||||
|
||||
// If town has no available names (for example - all were picked) - pick names from some other faction that still has names available
|
||||
if(!availableNames.count(faction))
|
||||
faction = RandomGeneratorUtil::nextItem(availableNames, getRandomGenerator())->first;
|
||||
|
||||
auto nameIt = RandomGeneratorUtil::nextItem(availableNames[faction], getRandomGenerator());
|
||||
vti->setNameTextId(faction.toFaction()->town->getRandomNameTextID(*nameIt));
|
||||
|
||||
availableNames[faction].erase(nameIt);
|
||||
if(availableNames[faction].empty())
|
||||
availableNames.erase(faction);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameState::initTowns()
|
||||
{
|
||||
logGlobal->debug("\tTowns");
|
||||
@ -776,20 +821,13 @@ void CGameState::initTowns()
|
||||
map->townUniversitySkills.push_back(SecondarySkill(SecondarySkill::WATER_MAGIC));
|
||||
map->townUniversitySkills.push_back(SecondarySkill(SecondarySkill::EARTH_MAGIC));
|
||||
|
||||
for (auto & elem : map->towns)
|
||||
for (auto & vti : map->towns)
|
||||
{
|
||||
CGTownInstance * vti =(elem);
|
||||
assert(vti->town);
|
||||
|
||||
if(vti->getNameTextID().empty())
|
||||
{
|
||||
size_t nameID = getRandomGenerator().nextInt(vti->getTown()->getRandomNamesCount() - 1);
|
||||
vti->setNameTextId(vti->getTown()->getRandomNameTextID(nameID));
|
||||
}
|
||||
|
||||
static const BuildingID basicDwellings[] = { BuildingID::DWELL_FIRST, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7 };
|
||||
static const BuildingID upgradedDwellings[] = { BuildingID::DWELL_UP_FIRST, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP, BuildingID::DWELL_LVL_4_UP, BuildingID::DWELL_LVL_5_UP, BuildingID::DWELL_LVL_6_UP, BuildingID::DWELL_LVL_7_UP };
|
||||
static const BuildingID hordes[] = { BuildingID::HORDE_PLACEHOLDER1, BuildingID::HORDE_PLACEHOLDER2, BuildingID::HORDE_PLACEHOLDER3, BuildingID::HORDE_PLACEHOLDER4, BuildingID::HORDE_PLACEHOLDER5, BuildingID::HORDE_PLACEHOLDER6, BuildingID::HORDE_PLACEHOLDER7 };
|
||||
constexpr std::array basicDwellings = { BuildingID::DWELL_FIRST, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7 };
|
||||
constexpr std::array upgradedDwellings = { BuildingID::DWELL_UP_FIRST, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP, BuildingID::DWELL_LVL_4_UP, BuildingID::DWELL_LVL_5_UP, BuildingID::DWELL_LVL_6_UP, BuildingID::DWELL_LVL_7_UP };
|
||||
constexpr std::array hordes = { BuildingID::HORDE_PLACEHOLDER1, BuildingID::HORDE_PLACEHOLDER2, BuildingID::HORDE_PLACEHOLDER3, BuildingID::HORDE_PLACEHOLDER4, BuildingID::HORDE_PLACEHOLDER5, BuildingID::HORDE_PLACEHOLDER6, BuildingID::HORDE_PLACEHOLDER7 };
|
||||
|
||||
//init buildings
|
||||
if(vstd::contains(vti->builtBuildings, BuildingID::DEFAULT)) //give standard set of buildings
|
||||
|
@ -212,6 +212,7 @@ private:
|
||||
void initFogOfWar();
|
||||
void initStartingBonus();
|
||||
void initTowns();
|
||||
void initTownNames();
|
||||
void initMapObjects();
|
||||
void initVisitingAndGarrisonedHeroes();
|
||||
void initCampaign();
|
||||
|
Loading…
Reference in New Issue
Block a user