1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Split OBJECT bonus source into OBJECT_TYPE and OBJECT_INSTANCE

This commit is contained in:
Ivan Savenko 2023-10-21 15:06:18 +03:00
parent ac925bb786
commit 4f47555977
14 changed files with 34 additions and 25 deletions

View File

@ -153,7 +153,7 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier,
for(auto bonus : *bonusModifiers)
{
// army bonuses will change and object bonuses are temporary
if(bonus->source != BonusSource::ARMY && bonus->source != BonusSource::OBJECT)
if(bonus->source != BonusSource::ARMY && bonus->source != BonusSource::OBJECT_INSTANCE && bonus->source != BonusSource::OBJECT_TYPE)
{
newArmyInstance.addNewBonus(std::make_shared<Bonus>(*bonus));
}

View File

@ -583,7 +583,15 @@ static void loadBonusSourceInstance(BonusSourceID & sourceInstance, BonusSource
});
break;
}
case BonusSource::OBJECT:
case BonusSource::OBJECT_TYPE:
{
VLC->identifiers()->requestIdentifier( "object", node, [&sourceInstance](int32_t identifier)
{
sourceInstance = Obj(identifier);
});
break;
}
case BonusSource::OBJECT_INSTANCE:
case BonusSource::HERO_BASE_SKILL:
assert(0); // TODO
sourceInstance = ObjectInstanceID();

View File

@ -993,7 +993,7 @@ void GiveBonus::applyGs(CGameState *gs)
if(bdescr.empty() && (bonus.type == BonusType::LUCK || bonus.type == BonusType::MORALE))
{
if (bonus.source == BonusSource::OBJECT)
if (bonus.source == BonusSource::OBJECT_TYPE || bonus.source == BonusSource::OBJECT_INSTANCE)
{
descr = VLC->generaltexth->arraytxt[bonus.val > 0 ? 110 : 109]; //+/-%d Temporary until next battle"
}

View File

@ -175,7 +175,8 @@ class JsonNode;
#define BONUS_SOURCE_LIST \
BONUS_SOURCE(ARTIFACT)\
BONUS_SOURCE(ARTIFACT_INSTANCE)\
BONUS_SOURCE(OBJECT)\
BONUS_SOURCE(OBJECT_TYPE)\
BONUS_SOURCE(OBJECT_INSTANCE)\
BONUS_SOURCE(CREATURE_ABILITY)\
BONUS_SOURCE(TERRAIN_NATIVE)\
BONUS_SOURCE(TERRAIN_OVERLAY)\

View File

@ -49,7 +49,7 @@ void CRewardableConstructor::configureObject(CGObjectInstance * object, CRandomG
{
for (auto & bonus : rewardInfo.reward.bonuses)
{
bonus.source = BonusSource::OBJECT;
bonus.source = BonusSource::OBJECT_TYPE;
bonus.sid = BonusSourceID(rewardableObject->ID);
}
}

View File

@ -212,7 +212,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
GiveBonus gbonus;
gbonus.id = hero->id.getNum();
gbonus.bonus.duration = BonusDuration::ONE_BATTLE;
gbonus.bonus.source = BonusSource::OBJECT;
gbonus.bonus.source = BonusSource::OBJECT_TYPE;
gbonus.bonus.sid = BonusSourceID(ID);
gbonus.bonus.type = BonusType::MORALE;
gbonus.bonus.val = -1;
@ -239,7 +239,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
case Obj::PYRAMID:
{
GiveBonus gb;
gb.bonus = Bonus(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, -2, BonusSourceID(id), VLC->generaltexth->arraytxt[70]);
gb.bonus = Bonus(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT_INSTANCE, -2, BonusSourceID(id), VLC->generaltexth->arraytxt[70]);
gb.id = hero->id.getNum();
cb->giveHeroBonus(&gb);
textID = 107;

View File

@ -221,7 +221,7 @@ void CGObjectInstance::giveDummyBonus(const ObjectInstanceID & heroID, BonusDura
gbonus.bonus.type = BonusType::NONE;
gbonus.id = heroID.getNum();
gbonus.bonus.duration = duration;
gbonus.bonus.source = BonusSource::OBJECT;
gbonus.bonus.source = BonusSource::OBJECT_TYPE;
gbonus.bonus.sid = BonusSourceID(ID);
cb->giveHeroBonus(&gbonus);
}

View File

@ -227,11 +227,11 @@ void CGPandoraBox::serializeJsonOptions(JsonSerializeFormat & handler)
int val;
handler.serializeInt("morale", val, 0);
if(val)
vinfo.reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, BonusSourceID(id));
vinfo.reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT_INSTANCE, val, BonusSourceID(id));
handler.serializeInt("luck", val, 0);
if(val)
vinfo.reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, BonusSourceID(id));
vinfo.reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT_INSTANCE, val, BonusSourceID(id));
vinfo.reward.resources.serializeJson(handler, "resources");
{

View File

@ -143,10 +143,10 @@ void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
switch (this->bType)
{
case BuildingSubID::STABLES:
if(!h->hasBonusFrom(BonusSource::OBJECT, BonusSourceID(Obj(Obj::STABLES)))) //does not stack with advMap Stables
if(!h->hasBonusFrom(BonusSource::OBJECT_TYPE, BonusSourceID(Obj(Obj::STABLES)))) //does not stack with advMap Stables
{
GiveBonus gb;
gb.bonus = Bonus(BonusDuration::ONE_WEEK, BonusType::MOVEMENT, BonusSource::OBJECT, 600, BonusSourceID(Obj(Obj::STABLES)), BonusCustomSubtype::heroMovementLand, VLC->generaltexth->arraytxt[100]);
gb.bonus = Bonus(BonusDuration::ONE_WEEK, BonusType::MOVEMENT, BonusSource::OBJECT_TYPE, 600, BonusSourceID(Obj(Obj::STABLES)), BonusCustomSubtype::heroMovementLand, VLC->generaltexth->arraytxt[100]);
gb.id = heroID.getNum();
cb->giveHeroBonus(&gb);

View File

@ -676,9 +676,9 @@ void CGSeerHut::serializeJsonOptions(JsonSerializeFormat & handler)
if(metaTypeName == "mana")
reward.manaDiff = val;
if(metaTypeName == "morale")
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, BonusSourceID(id));
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT_INSTANCE, val, BonusSourceID(id));
if(metaTypeName == "luck")
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, BonusSourceID(id));
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT_INSTANCE, val, BonusSourceID(id));
if(metaTypeName == "resource")
{
auto rawId = *VLC->identifiers()->getIdentifier(ModScope::scopeMap(), fullIdentifier, false);

View File

@ -197,7 +197,7 @@ bool CRewardableObject::wasVisitedBefore(const CGHeroInstance * contextHero) con
case Rewardable::VISIT_PLAYER:
return vstd::contains(cb->getPlayerState(contextHero->getOwner())->visitedObjects, ObjectInstanceID(id));
case Rewardable::VISIT_BONUS:
return contextHero->hasBonusFrom(BonusSource::OBJECT, BonusSourceID(ID));
return contextHero->hasBonusFrom(BonusSource::OBJECT_TYPE, BonusSourceID(ID));
case Rewardable::VISIT_HERO:
return contextHero->visitedObjects.count(ObjectInstanceID(id));
case Rewardable::VISIT_LIMITER:
@ -234,7 +234,7 @@ bool CRewardableObject::wasVisited(const CGHeroInstance * h) const
switch (configuration.visitMode)
{
case Rewardable::VISIT_BONUS:
return h->hasBonusFrom(BonusSource::OBJECT, BonusSourceID(ID));
return h->hasBonusFrom(BonusSource::OBJECT_TYPE, BonusSourceID(ID));
case Rewardable::VISIT_HERO:
return h->visitedObjects.count(ObjectInstanceID(id));
case Rewardable::VISIT_LIMITER:

View File

@ -987,14 +987,14 @@ void CGSirens::initObj(CRandomGenerator & rand)
std::string CGSirens::getHoverText(const CGHeroInstance * hero) const
{
return getObjectName() + " " + visitedTxt(hero->hasBonusFrom(BonusSource::OBJECT, BonusSourceID(ID)));
return getObjectName() + " " + visitedTxt(hero->hasBonusFrom(BonusSource::OBJECT_TYPE, BonusSourceID(ID)));
}
void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
{
InfoWindow iw;
iw.player = h->tempOwner;
if(h->hasBonusFrom(BonusSource::OBJECT, BonusSourceID(ID))) //has already visited Sirens
if(h->hasBonusFrom(BonusSource::OBJECT_TYPE, BonusSourceID(ID))) //has already visited Sirens
{
iw.type = EInfoWindowMode::AUTO;
iw.text.appendLocalString(EMetaText::ADVOB_TXT,133);
@ -1179,7 +1179,7 @@ void CGLighthouse::onHeroVisit( const CGHeroInstance * h ) const
{
RemoveBonus rb(GiveBonus::ETarget::PLAYER);
rb.whoID = oldOwner.getNum();
rb.source = BonusSource::OBJECT;
rb.source = BonusSource::OBJECT_INSTANCE;
rb.id = BonusSourceID(id);
cb->sendAndApply(&rb);
}
@ -1202,7 +1202,7 @@ void CGLighthouse::giveBonusTo(const PlayerColor & player, bool onInit) const
gb.bonus.val = 500;
gb.id = player.getNum();
gb.bonus.duration = BonusDuration::PERMANENT;
gb.bonus.source = BonusSource::OBJECT;
gb.bonus.source = BonusSource::OBJECT_INSTANCE;
gb.bonus.sid = BonusSourceID(id);
gb.bonus.subtype = BonusCustomSubtype::heroMovementSea;

View File

@ -1040,9 +1040,9 @@ void CMapLoaderH3M::readBoxContent(CGPandoraBox * object, const int3 & mapPositi
reward.heroExperience = reader->readUInt32();
reward.manaDiff = reader->readInt32();
if(auto val = reader->readUInt8())
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, val, BonusSourceID(idToBeGiven));
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT_INSTANCE, val, BonusSourceID(idToBeGiven));
if(auto val = reader->readUInt8())
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, val, BonusSourceID(idToBeGiven));
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT_INSTANCE, val, BonusSourceID(idToBeGiven));
reader->readResourses(reward.resources);
for(int x = 0; x < GameConstants::PRIMARY_SKILLS; ++x)
@ -2008,12 +2008,12 @@ void CMapLoaderH3M::readSeerHutQuest(CGSeerHut * hut, const int3 & position, con
}
case ESeerHutRewardType::MORALE:
{
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT, reader->readUInt8(), BonusSourceID(idToBeGiven));
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::MORALE, BonusSource::OBJECT_INSTANCE, reader->readUInt8(), BonusSourceID(idToBeGiven));
break;
}
case ESeerHutRewardType::LUCK:
{
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT, reader->readUInt8(), BonusSourceID(idToBeGiven));
reward.bonuses.emplace_back(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT_INSTANCE, reader->readUInt8(), BonusSourceID(idToBeGiven));
break;
}
case ESeerHutRewardType::RESOURCES:

View File

@ -333,7 +333,7 @@ void RewardsWidget::saveCurrentVisitInfo(int index)
auto dur = bonusDurationMap.at(ui->bonuses->item(i, 0)->text().toStdString());
auto typ = bonusNameMap.at(ui->bonuses->item(i, 1)->text().toStdString());
auto val = ui->bonuses->item(i, 2)->data(Qt::UserRole).toInt();
vinfo.reward.bonuses.emplace_back(dur, typ, BonusSource::OBJECT, val, BonusSourceID(object.id));
vinfo.reward.bonuses.emplace_back(dur, typ, BonusSource::OBJECT_INSTANCE, val, BonusSourceID(object.id));
}
vinfo.limiter.dayOfWeek = ui->lDayOfWeek->currentIndex();