1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-10 22:31:40 +02:00

Spell scrolls as a reward

This commit is contained in:
Ivan Savenko
2025-05-01 17:59:32 +03:00
parent 62e774c91e
commit 5dec3efa2f
5 changed files with 39 additions and 23 deletions

View File

@@ -206,6 +206,11 @@ int getDwellingArmyCost(const CGObjectInstance * target)
return cost;
}
static uint64_t evaluateSpellScrollArmyValue(const SpellID &)
{
return 1500;
}
static uint64_t evaluateArtifactArmyValue(const CArtifact * art)
{
if(art->getId() == ArtifactID::SPELL_SCROLL)
@@ -265,23 +270,14 @@ uint64_t RewardEvaluator::getArmyReward(
auto rewardValue = 0;
if(!info.reward.grantedArtifacts.empty())
{
for(auto artID : info.reward.grantedArtifacts)
{
const auto * art = artID.toArtifact();
for(auto artID : info.reward.grantedArtifacts)
rewardValue += evaluateArtifactArmyValue(artID.toArtifact());
rewardValue += evaluateArtifactArmyValue(art);
}
}
for(auto scroll : info.reward.scrolls)
rewardValue += evaluateSpellScrollArmyValue(scroll);
if(!info.reward.creatures.empty())
{
for(const auto & stackInfo : info.reward.creatures)
{
rewardValue += stackInfo.getType()->getAIValue() * stackInfo.getCount();
}
}
for(const auto & stackInfo : info.reward.creatures)
rewardValue += stackInfo.getType()->getAIValue() * stackInfo.getCount();
totalValue += rewardValue > 0 ? rewardValue / (info.reward.grantedArtifacts.size() + info.reward.creatures.size()) : 0;
}

View File

@@ -1130,13 +1130,16 @@ void CMapLoaderH3M::readBoxContent(CGPandoraBox * object, const int3 & mapPositi
size_t gart = reader->readUInt8(); //number of gained artifacts
for(size_t oo = 0; oo < gart; ++oo)
{
reward.grantedArtifacts.push_back(reader->readArtifact());
ArtifactID grantedArtifact = reader->readArtifact();
if (features.levelHOTA5)
{
SpellID scrollSpell = reader->readSpell16();
if (reward.grantedArtifacts.back() == ArtifactID::SPELL_SCROLL)
logGlobal->warn("Map '%s': Pandora/Event at %s Option to give spell scroll (%s) via event or pandora is not implemented!", mapName, mapPosition.toString(), scrollSpell.toEntity(LIBRARY)->getJsonKey());
if (grantedArtifact == ArtifactID::SPELL_SCROLL)
reward.scrolls.push_back(scrollSpell);
}
else
reward.grantedArtifacts.push_back(grantedArtifact);
}
size_t gspel = reader->readUInt8(); //number of gained spells
@@ -2334,15 +2337,15 @@ void CMapLoaderH3M::readSeerHutQuest(CGSeerHut * hut, const int3 & position, con
}
case ESeerHutRewardType::ARTIFACT:
{
reward.grantedArtifacts.push_back(reader->readArtifact());
ArtifactID grantedArtifact = reader->readArtifact();
if (features.levelHOTA5)
{
SpellID scrollSpell = reader->readSpell16();
if (reward.grantedArtifacts.back() == ArtifactID::SPELL_SCROLL)
logGlobal->warn("Map '%s': Seer Hut at %s: Option to give spell scroll (%s) as a reward is not implemented!", mapName, position.toString(), scrollSpell.toEntity(LIBRARY)->getJsonKey());
if (grantedArtifact == ArtifactID::SPELL_SCROLL)
reward.scrolls.push_back(scrollSpell);
}
else
reward.grantedArtifacts.push_back(grantedArtifact);
break;
}
case ESeerHutRewardType::SPELL:

View File

@@ -183,6 +183,7 @@ void Rewardable::Info::configureReward(Rewardable::Configuration & object, vstd:
reward.secondary = randomizer.loadSecondaries(source["secondary"], rng, variables);
reward.grantedArtifacts = randomizer.loadArtifacts(source["artifacts"], rng, variables);
reward.scrolls = randomizer.loadSpells(source["scrolls"], rng, variables);
reward.spells = randomizer.loadSpells(source["spells"], rng, variables);
reward.creatures = randomizer.loadCreatures(source["creatures"], rng, variables);
if(!source["spellCast"].isNull() && source["spellCast"].isStruct())
@@ -300,6 +301,12 @@ void Rewardable::Info::replaceTextPlaceholders(MetaString & target, const Variab
loot.replaceName(artifact);
}
for (const auto & scroll : info.reward.scrolls )
{
loot.appendRawString("%s");
loot.replaceName(scroll);
}
for (const auto & spell : info.reward.spells )
{
loot.appendRawString("%s");
@@ -319,6 +326,9 @@ void Rewardable::Info::replaceTextPlaceholders(MetaString & target, const Variab
for (const auto & artifact : info.reward.grantedArtifacts )
target.replaceName(artifact);
for (const auto & scroll : info.reward.scrolls )
target.replaceName(scroll);
for (const auto & spell : info.reward.spells )
target.replaceName(spell);

View File

@@ -166,6 +166,9 @@ void Rewardable::Interface::grantRewardAfterLevelup(const Rewardable::VisitInfo
for(const ArtifactID & art : info.reward.grantedArtifacts)
cb->giveHeroNewArtifact(hero, art, ArtifactPosition::FIRST_AVAILABLE);
for(const SpellID & spell : info.reward.scrolls)
cb->giveHeroNewScroll(hero, spell, ArtifactPosition::FIRST_AVAILABLE);
if(!info.reward.spells.empty())
{
std::set<SpellID> spellsToGive;

View File

@@ -114,6 +114,9 @@ void Rewardable::Reward::loadComponents(std::vector<Component> & comps, const CG
for(const auto & entry : grantedArtifacts)
comps.emplace_back(ComponentType::ARTIFACT, entry);
for(const SpellID & spell : scrolls)
comps.emplace_back(ComponentType::SPELL, spell);
for(const auto & entry : spells)
{
bool learnable = !h || h->canLearnSpell(entry.toEntity(LIBRARY), true);
@@ -142,6 +145,7 @@ void Rewardable::Reward::serializeJson(JsonSerializeFormat & handler)
handler.serializeInt("manaOverflowFactor", manaOverflowFactor);
handler.serializeInt("movePoints", movePoints);
handler.serializeIdArray("artifacts", grantedArtifacts);
handler.serializeIdArray("scrolls", scrolls);
handler.serializeIdArray("spells", spells);
handler.enterArray("creatures").serializeStruct(creatures);
handler.enterArray("primary").serializeArray(primary);