mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Cleaned up dwelling randomization
This commit is contained in:
parent
dcb8f4fc7b
commit
7a09646009
@ -77,34 +77,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static CGObjectInstance * createObject(MapObjectID id, MapObjectSubID subid, const int3 & pos, const PlayerColor & owner)
|
||||
{
|
||||
CGObjectInstance * nobj;
|
||||
switch(id)
|
||||
{
|
||||
case Obj::HERO:
|
||||
{
|
||||
auto handler = VLC->objtypeh->getHandlerFor(id, VLC->heroh->objects[subid]->heroClass->getIndex());
|
||||
nobj = handler->create(handler->getTemplates().front());
|
||||
break;
|
||||
}
|
||||
case Obj::TOWN:
|
||||
nobj = new CGTownInstance();
|
||||
break;
|
||||
default: //rest of objects
|
||||
nobj = new CGObjectInstance();
|
||||
break;
|
||||
}
|
||||
nobj->ID = id;
|
||||
nobj->subID = subid;
|
||||
nobj->pos = pos;
|
||||
nobj->tempOwner = owner;
|
||||
if (id != Obj::HERO)
|
||||
nobj->appearance = VLC->objtypeh->getHandlerFor(id, subid)->getTemplates().front();
|
||||
|
||||
return nobj;
|
||||
}
|
||||
|
||||
HeroTypeID CGameState::pickNextHeroType(const PlayerColor & owner)
|
||||
{
|
||||
const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner);
|
||||
@ -547,44 +519,30 @@ void CGameState::initRandomFactionsForPlayers()
|
||||
void CGameState::randomizeMapObjects()
|
||||
{
|
||||
logGlobal->debug("\tRandomizing objects");
|
||||
for(CGObjectInstance *obj : map->objects)
|
||||
for(CGObjectInstance *object : map->objects)
|
||||
{
|
||||
if(!obj)
|
||||
if(!object)
|
||||
continue;
|
||||
|
||||
{
|
||||
std::pair<Obj,int> ran = pickObject(obj);
|
||||
if(ran.first == Obj::NO_OBJ || ran.second<0) //this is not a random object, or we couldn't find anything
|
||||
{
|
||||
if(obj->ID==Obj::TOWN || obj->ID==Obj::MONSTER)
|
||||
obj->setType(obj->ID, obj->subID); // update def, if necessary
|
||||
}
|
||||
else if(ran.first==Obj::HERO)//special code for hero
|
||||
{
|
||||
auto * h = dynamic_cast<CGHeroInstance *>(obj);
|
||||
obj->setType(ran.first, ran.second);
|
||||
map->heroesOnMap.emplace_back(h);
|
||||
}
|
||||
else if(ran.first==Obj::TOWN)//special code for town
|
||||
{
|
||||
auto * t = dynamic_cast<CGTownInstance *>(obj);
|
||||
obj->setType(ran.first, ran.second);
|
||||
map->towns.emplace_back(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj->setType(ran.first, ran.second);
|
||||
}
|
||||
}
|
||||
object->pickRandomObject(getRandomGenerator());
|
||||
|
||||
auto * hero = dynamic_cast<CGHeroInstance *>(object);
|
||||
auto * town = dynamic_cast<CGTownInstance *>(object);
|
||||
|
||||
if (hero)
|
||||
map->heroesOnMap.emplace_back(hero);
|
||||
|
||||
if (town)
|
||||
map->towns.emplace_back(town);
|
||||
|
||||
//handle Favouring Winds - mark tiles under it
|
||||
if(obj->ID == Obj::FAVORABLE_WINDS)
|
||||
if(object->ID == Obj::FAVORABLE_WINDS)
|
||||
{
|
||||
for (int i = 0; i < obj->getWidth() ; i++)
|
||||
for (int i = 0; i < object->getWidth() ; i++)
|
||||
{
|
||||
for (int j = 0; j < obj->getHeight() ; j++)
|
||||
for (int j = 0; j < object->getHeight() ; j++)
|
||||
{
|
||||
int3 pos = obj->pos - int3(i,j,0);
|
||||
int3 pos = object->pos - int3(i,j,0);
|
||||
if(map->isInTheMap(pos)) map->getTile(pos).extTileFlags |= 128;
|
||||
}
|
||||
}
|
||||
@ -617,7 +575,14 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
|
||||
}
|
||||
}
|
||||
|
||||
CGObjectInstance * hero = createObject(Obj::HERO, heroTypeId, townPos, playerColor);
|
||||
auto handler = VLC->objtypeh->getHandlerFor(Obj::HERO, VLC->heroh->objects[heroTypeId]->heroClass->getIndex());
|
||||
CGObjectInstance * hero = handler->create(handler->getTemplates().front());
|
||||
|
||||
hero->ID = Obj::HERO;
|
||||
hero->subID = VLC->heroh->objects[heroTypeId]->heroClass->getIndex();
|
||||
hero->tempOwner = playerColor;
|
||||
|
||||
hero->pos = townPos;
|
||||
hero->pos += hero->getVisitableOffset();
|
||||
map->getEditManager()->insertObject(hero);
|
||||
}
|
||||
|
@ -115,6 +115,8 @@ public:
|
||||
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
|
||||
|
||||
bool giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid);
|
||||
/// picks next free hero type of the H3 hero init sequence -> chosen starting hero, then unused hero type randomly
|
||||
HeroTypeID pickNextHeroType(const PlayerColor & owner);
|
||||
|
||||
void apply(CPack *pack);
|
||||
BattleField battleGetBattlefieldType(int3 tile, CRandomGenerator & rand);
|
||||
@ -214,7 +216,6 @@ private:
|
||||
bool isUsedHero(const HeroTypeID & hid) const; //looks in heroes and prisons
|
||||
std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
|
||||
HeroTypeID pickUnusedHeroTypeRandomly(const PlayerColor & owner); // picks a unused hero type randomly
|
||||
HeroTypeID pickNextHeroType(const PlayerColor & owner); // picks next free hero type of the H3 hero init sequence -> chosen starting hero, then unused hero type randomly
|
||||
UpgradeInfo fillUpgradeInfo(const CStackInstance &stack) const;
|
||||
|
||||
// ---- data -----
|
||||
|
@ -152,7 +152,6 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CreatureID CGCreature::getCreature() const
|
||||
|
@ -48,6 +48,10 @@ CGDwelling::~CGDwelling() = default;
|
||||
|
||||
FactionID CGDwelling::randomizeFaction(CRandomGenerator & rand)
|
||||
{
|
||||
if (ID == Obj::RANDOM_DWELLING_FACTION)
|
||||
return FactionID(subID);
|
||||
|
||||
assert(ID == Obj::RANDOM_DWELLING || ID == Obj::RANDOM_DWELLING_LVL);
|
||||
assert(randomizationInfo.has_value());
|
||||
if (!randomizationInfo)
|
||||
return FactionID::CASTLE;
|
||||
@ -102,6 +106,10 @@ FactionID CGDwelling::randomizeFaction(CRandomGenerator & rand)
|
||||
|
||||
int CGDwelling::randomizeLevel(CRandomGenerator & rand)
|
||||
{
|
||||
if (ID == Obj::RANDOM_DWELLING_LVL)
|
||||
return subID.getNum();
|
||||
|
||||
assert(ID == Obj::RANDOM_DWELLING || ID == Obj::RANDOM_DWELLING_FACTION);
|
||||
assert(randomizationInfo.has_value());
|
||||
|
||||
if (!randomizationInfo)
|
||||
|
@ -296,16 +296,6 @@ void CGHeroInstance::initHero(CRandomGenerator & rand, const HeroTypeID & SUBID)
|
||||
initHero(rand);
|
||||
}
|
||||
|
||||
void CGHeroInstance::setType(si32 ID, si32 subID)
|
||||
{
|
||||
assert(ID == Obj::HERO); // just in case
|
||||
type = VLC->heroh->objects[subID];
|
||||
|
||||
CGObjectInstance::setType(ID, type->heroClass->getIndex()); // to find object handler we must use heroClass->id
|
||||
this->subID = subID; // after setType subID used to store unique hero identify id. Check issue 2277 for details
|
||||
randomizeArmy(type->heroClass->faction);
|
||||
}
|
||||
|
||||
void CGHeroInstance::initHero(CRandomGenerator & rand)
|
||||
{
|
||||
assert(validTypes(true));
|
||||
@ -580,6 +570,14 @@ void CGHeroInstance::pickRandomObject(CRandomGenerator & rand)
|
||||
ID = Obj::HERO;
|
||||
subID = cb->gameState()->pickNextHeroType(getOwner());
|
||||
}
|
||||
type = VLC->heroh->objects[subID];
|
||||
|
||||
// to find object handler we must use heroClass->id
|
||||
// after setType subID used to store unique hero identify id. Check issue 2277 for details
|
||||
setType(ID, type->heroClass->getIndex());
|
||||
this->subID = subID;
|
||||
|
||||
randomizeArmy(type->heroClass->faction);
|
||||
}
|
||||
|
||||
void CGHeroInstance::initObj(CRandomGenerator & rand)
|
||||
|
@ -232,7 +232,6 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HeroTypeID getHeroType() const;
|
||||
void setType(si32 ID, si32 subID) override;
|
||||
|
||||
void initHero(CRandomGenerator & rand);
|
||||
void initHero(CRandomGenerator & rand, const HeroTypeID & SUBID);
|
||||
|
@ -106,10 +106,6 @@ public:
|
||||
virtual int getSightRadius() const;
|
||||
/// returns (x,y,0) offset to a visitable tile of object
|
||||
virtual int3 getVisitableOffset() const;
|
||||
/// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman")
|
||||
virtual void setType(si32 ID, si32 subID);
|
||||
|
||||
/// returns text visible in status bar with specific hero/player active.
|
||||
|
||||
/// Returns generic name of object, without any player-specific info
|
||||
virtual std::string getObjectName() const;
|
||||
@ -160,6 +156,9 @@ protected:
|
||||
/// virtual method that allows synchronously update object state on server and all clients
|
||||
virtual void setPropertyDer(ui8 what, ui32 val);
|
||||
|
||||
/// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman")
|
||||
void setType(si32 ID, si32 subID);
|
||||
|
||||
/// Gives dummy bonus from this object to hero. Can be used to track visited state
|
||||
void giveDummyBonus(const ObjectInstanceID & heroID, BonusDuration::Type duration = BonusDuration::ONE_DAY) const;
|
||||
|
||||
|
@ -486,6 +486,12 @@ void CGTownInstance::pickRandomObject(CRandomGenerator & rand)
|
||||
ID = MapObjectID::TOWN;
|
||||
subID = randomizeFaction(rand);
|
||||
}
|
||||
|
||||
assert(ID == Obj::TOWN); // just in case
|
||||
setType(ID, subID);
|
||||
town = (*VLC->townh)[subID]->town;
|
||||
randomizeArmy(subID);
|
||||
updateAppearance();
|
||||
}
|
||||
|
||||
void CGTownInstance::initObj(CRandomGenerator & rand) ///initialize town structures
|
||||
@ -779,15 +785,6 @@ std::vector<int> CGTownInstance::availableItemsIds(EMarketMode mode) const
|
||||
return IMarket::availableItemsIds(mode);
|
||||
}
|
||||
|
||||
void CGTownInstance::setType(si32 ID, si32 subID)
|
||||
{
|
||||
assert(ID == Obj::TOWN); // just in case
|
||||
CGObjectInstance::setType(ID, subID);
|
||||
town = (*VLC->townh)[subID]->town;
|
||||
randomizeArmy(subID);
|
||||
updateAppearance();
|
||||
}
|
||||
|
||||
void CGTownInstance::updateAppearance()
|
||||
{
|
||||
auto terrain = cb->gameState()->getTile(visitablePos())->terType->getId();
|
||||
|
@ -141,7 +141,6 @@ public:
|
||||
bool allowsTrade(EMarketMode mode) const override;
|
||||
std::vector<int> availableItemsIds(EMarketMode mode) const override;
|
||||
|
||||
void setType(si32 ID, si32 subID) override;
|
||||
void updateAppearance();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -46,6 +46,9 @@ void IObjectInterface::newTurn(CRandomGenerator & rand) const
|
||||
void IObjectInterface::initObj(CRandomGenerator & rand)
|
||||
{}
|
||||
|
||||
void IObjectInterface::pickRandomObject(CRandomGenerator & rand)
|
||||
{}
|
||||
|
||||
void IObjectInterface::setProperty( ui8 what, ui32 val )
|
||||
{}
|
||||
|
||||
|
@ -1336,12 +1336,19 @@ CGObjectInstance * CMapLoaderH3M::readDwellingRandom(const int3 & mapPosition, s
|
||||
if(object->randomizationInfo->identifier != 0)
|
||||
reader->readBitmaskFactions(object->randomizationInfo->allowedFactions, false);
|
||||
}
|
||||
else
|
||||
object->randomizationInfo->allowedFactions.insert(FactionID(objectTemplate->subid));
|
||||
|
||||
if(hasLevelInfo)
|
||||
{
|
||||
object->randomizationInfo->minLevel = std::max(reader->readUInt8(), static_cast<ui8>(0)) + 1;
|
||||
object->randomizationInfo->maxLevel = std::min(reader->readUInt8(), static_cast<ui8>(6)) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
object->randomizationInfo->minLevel = objectTemplate->subid;
|
||||
object->randomizationInfo->maxLevel = objectTemplate->subid;
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
@ -87,14 +87,6 @@ void Initializer::initialize(CGDwelling * o)
|
||||
if(!o) return;
|
||||
|
||||
o->tempOwner = defaultPlayer;
|
||||
|
||||
switch(o->ID)
|
||||
{
|
||||
case Obj::RANDOM_DWELLING:
|
||||
case Obj::RANDOM_DWELLING_LVL:
|
||||
case Obj::RANDOM_DWELLING_FACTION:
|
||||
o->initRandomObjectInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void Initializer::initialize(CGGarrison * o)
|
||||
@ -243,11 +235,8 @@ void Inspector::updateProperties(CGDwelling * o)
|
||||
|
||||
addProperty("Owner", o->tempOwner, false);
|
||||
|
||||
if(dynamic_cast<CCreGenAsCastleInfo*>(o->info))
|
||||
{
|
||||
auto * delegate = new PickObjectDelegate(controller, PickObjectDelegate::typedFilter<CGTownInstance>);
|
||||
addProperty("Same as town", PropertyEditorPlaceholder(), delegate, false);
|
||||
}
|
||||
auto * delegate = new PickObjectDelegate(controller, PickObjectDelegate::typedFilter<CGTownInstance>);
|
||||
addProperty("Same as town", PropertyEditorPlaceholder(), delegate, false);
|
||||
}
|
||||
|
||||
void Inspector::updateProperties(CGLighthouse * o)
|
||||
@ -641,12 +630,12 @@ void Inspector::setProperty(CGDwelling * o, const QString & key, const QVariant
|
||||
|
||||
if(key == "Same as town")
|
||||
{
|
||||
if(auto * info = dynamic_cast<CCreGenAsCastleInfo*>(o->info))
|
||||
{
|
||||
info->instanceId = "";
|
||||
if(CGTownInstance * town = data_cast<CGTownInstance>(value.toLongLong()))
|
||||
info->instanceId = town->instanceName;
|
||||
}
|
||||
if (!o->randomizationInfo.has_value())
|
||||
o->randomizationInfo = CGDwellingRandomizationInfo();
|
||||
|
||||
o->randomizationInfo->instanceId = "";
|
||||
if(CGTownInstance * town = data_cast<CGTownInstance>(value.toLongLong()))
|
||||
o->randomizationInfo->instanceId = town->instanceName;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user