From 4f47555977f697cff6ad935a2fcf878569d83375 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 21 Oct 2023 15:06:18 +0300 Subject: [PATCH] Split OBJECT bonus source into OBJECT_TYPE and OBJECT_INSTANCE --- AI/Nullkiller/Analyzers/ArmyManager.cpp | 2 +- lib/JsonNode.cpp | 10 +++++++++- lib/NetPacksLib.cpp | 2 +- lib/bonuses/BonusEnum.h | 3 ++- lib/mapObjectConstructors/CRewardableConstructor.cpp | 2 +- lib/mapObjects/CBank.cpp | 4 ++-- lib/mapObjects/CGObjectInstance.cpp | 2 +- lib/mapObjects/CGPandoraBox.cpp | 4 ++-- lib/mapObjects/CGTownBuilding.cpp | 4 ++-- lib/mapObjects/CQuest.cpp | 4 ++-- lib/mapObjects/CRewardableObject.cpp | 4 ++-- lib/mapObjects/MiscObjects.cpp | 8 ++++---- lib/mapping/MapFormatH3M.cpp | 8 ++++---- mapeditor/inspector/rewardswidget.cpp | 2 +- 14 files changed, 34 insertions(+), 25 deletions(-) diff --git a/AI/Nullkiller/Analyzers/ArmyManager.cpp b/AI/Nullkiller/Analyzers/ArmyManager.cpp index 66a86592d..e0eb6333b 100644 --- a/AI/Nullkiller/Analyzers/ArmyManager.cpp +++ b/AI/Nullkiller/Analyzers/ArmyManager.cpp @@ -153,7 +153,7 @@ std::vector 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)); } diff --git a/lib/JsonNode.cpp b/lib/JsonNode.cpp index c312cdba7..b25116670 100644 --- a/lib/JsonNode.cpp +++ b/lib/JsonNode.cpp @@ -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(); diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 12f89f7e7..cf04905a8 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -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" } diff --git a/lib/bonuses/BonusEnum.h b/lib/bonuses/BonusEnum.h index 2118eaeec..06cdc8f96 100644 --- a/lib/bonuses/BonusEnum.h +++ b/lib/bonuses/BonusEnum.h @@ -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)\ diff --git a/lib/mapObjectConstructors/CRewardableConstructor.cpp b/lib/mapObjectConstructors/CRewardableConstructor.cpp index 1726b7beb..c8b802586 100644 --- a/lib/mapObjectConstructors/CRewardableConstructor.cpp +++ b/lib/mapObjectConstructors/CRewardableConstructor.cpp @@ -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); } } diff --git a/lib/mapObjects/CBank.cpp b/lib/mapObjects/CBank.cpp index 7e372b4cf..8b26f3655 100644 --- a/lib/mapObjects/CBank.cpp +++ b/lib/mapObjects/CBank.cpp @@ -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; diff --git a/lib/mapObjects/CGObjectInstance.cpp b/lib/mapObjects/CGObjectInstance.cpp index 7b95c108f..e4cda9ab0 100644 --- a/lib/mapObjects/CGObjectInstance.cpp +++ b/lib/mapObjects/CGObjectInstance.cpp @@ -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); } diff --git a/lib/mapObjects/CGPandoraBox.cpp b/lib/mapObjects/CGPandoraBox.cpp index 808088c36..81035cbb1 100644 --- a/lib/mapObjects/CGPandoraBox.cpp +++ b/lib/mapObjects/CGPandoraBox.cpp @@ -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"); { diff --git a/lib/mapObjects/CGTownBuilding.cpp b/lib/mapObjects/CGTownBuilding.cpp index 0c3851d35..1590985e3 100644 --- a/lib/mapObjects/CGTownBuilding.cpp +++ b/lib/mapObjects/CGTownBuilding.cpp @@ -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); diff --git a/lib/mapObjects/CQuest.cpp b/lib/mapObjects/CQuest.cpp index 09d98a063..d79549f04 100644 --- a/lib/mapObjects/CQuest.cpp +++ b/lib/mapObjects/CQuest.cpp @@ -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); diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 8eac99996..341318dbf 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -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: diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 0ae6b808e..c0c49975e 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -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; diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 750ea4dcb..49f12ebdd 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -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: diff --git a/mapeditor/inspector/rewardswidget.cpp b/mapeditor/inspector/rewardswidget.cpp index 661dbf0fd..6ec62d84b 100644 --- a/mapeditor/inspector/rewardswidget.cpp +++ b/mapeditor/inspector/rewardswidget.cpp @@ -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();