1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-18 03:21:27 +02:00

Converted all h3 banks to rewardable, remove most of hardcoded checks

This commit is contained in:
Ivan Savenko 2024-08-30 16:24:58 +00:00
parent cb5df096c1
commit 503b87561e
15 changed files with 633 additions and 876 deletions

View File

@ -208,12 +208,6 @@ float TacticalAdvantageEngine::getTacticalAdvantage(const CArmedInstance * we, c
enemyFlyers->setValue(enemyStructure.flyers); enemyFlyers->setValue(enemyStructure.flyers);
enemySpeed->setValue(enemyStructure.maxSpeed); enemySpeed->setValue(enemyStructure.maxSpeed);
bool bank = dynamic_cast<const CBank *>(enemy);
if(bank)
bankPresent->setValue(1);
else
bankPresent->setValue(0);
const CGTownInstance * fort = dynamic_cast<const CGTownInstance *>(enemy); const CGTownInstance * fort = dynamic_cast<const CGTownInstance *>(enemy);
if(fort) if(fort)
castleWalls->setValue(fort->fortLevel()); castleWalls->setValue(fort->fortLevel());

View File

@ -20,25 +20,6 @@
namespace NKAI namespace NKAI
{ {
ui64 FuzzyHelper::estimateBankDanger(const CBank * bank)
{
//this one is not fuzzy anymore, just calculate weighted average
auto objectInfo = bank->getObjectHandler()->getObjectInfo(bank->appearance);
CBankInfo * bankInfo = dynamic_cast<CBankInfo *>(objectInfo.get());
ui64 totalStrength = 0;
ui8 totalChance = 0;
for(auto config : bankInfo->getPossibleGuards(bank->cb))
{
totalStrength += config.second.totalStrength * config.first;
totalChance += config.first;
}
return totalStrength / std::max<ui8>(totalChance, 1); //avoid division by zero
}
ui64 FuzzyHelper::evaluateDanger(const int3 & tile, const CGHeroInstance * visitor, bool checkGuards) ui64 FuzzyHelper::evaluateDanger(const int3 & tile, const CGHeroInstance * visitor, bool checkGuards)
{ {
auto cb = ai->cb.get(); auto cb = ai->cb.get();
@ -171,14 +152,11 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj)
case Obj::DRAGON_UTOPIA: case Obj::DRAGON_UTOPIA:
case Obj::SHIPWRECK: //shipwreck case Obj::SHIPWRECK: //shipwreck
case Obj::DERELICT_SHIP: //derelict ship case Obj::DERELICT_SHIP: //derelict ship
case Obj::PYRAMID:
{ {
const CArmedInstance * a = dynamic_cast<const CArmedInstance *>(obj); const CArmedInstance * a = dynamic_cast<const CArmedInstance *>(obj);
return a->getArmyStrength(); return a->getArmyStrength();
} }
case Obj::PYRAMID:
{
return estimateBankDanger(dynamic_cast<const CBank *>(obj));
}
default: default:
return 0; return 0;
} }

View File

@ -10,12 +10,6 @@
#pragma once #pragma once
#include "FuzzyEngines.h" #include "FuzzyEngines.h"
VCMI_LIB_NAMESPACE_BEGIN
class CBank;
VCMI_LIB_NAMESPACE_END
namespace NKAI namespace NKAI
{ {
@ -30,8 +24,6 @@ private:
public: public:
FuzzyHelper(const Nullkiller * ai): ai(ai) {} FuzzyHelper(const Nullkiller * ai): ai(ai) {}
ui64 estimateBankDanger(const CBank * bank); //TODO: move to another class?
ui64 evaluateDanger(const CGObjectInstance * obj); ui64 evaluateDanger(const CGObjectInstance * obj);
ui64 evaluateDanger(const int3 & tile, const CGHeroInstance * visitor, bool checkGuards = true); ui64 evaluateDanger(const int3 & tile, const CGHeroInstance * visitor, bool checkGuards = true);
}; };

View File

@ -16,7 +16,6 @@
#include "../../lib/UnlockGuard.h" #include "../../lib/UnlockGuard.h"
#include "../../lib/CConfigHandler.h" #include "../../lib/CConfigHandler.h"
#include "../../lib/CHeroHandler.h" #include "../../lib/CHeroHandler.h"
#include "../../lib/mapObjects/CBank.h"
#include "../../lib/mapObjects/CGTownInstance.h" #include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/mapObjects/CQuest.h" #include "../../lib/mapObjects/CQuest.h"
#include "../../lib/mapping/CMapDefines.h" #include "../../lib/mapping/CMapDefines.h"

View File

@ -219,12 +219,6 @@ float TacticalAdvantageEngine::getTacticalAdvantage(const CArmedInstance * we, c
enemyFlyers->setValue(enemyStructure.flyers); enemyFlyers->setValue(enemyStructure.flyers);
enemySpeed->setValue(enemyStructure.maxSpeed); enemySpeed->setValue(enemyStructure.maxSpeed);
bool bank = dynamic_cast<const CBank *>(enemy);
if(bank)
bankPresent->setValue(1);
else
bankPresent->setValue(0);
const CGTownInstance * fort = dynamic_cast<const CGTownInstance *>(enemy); const CGTownInstance * fort = dynamic_cast<const CGTownInstance *>(enemy);
if(fort) if(fort)
castleWalls->setValue(fort->fortLevel()); castleWalls->setValue(fort->fortLevel());

View File

@ -16,7 +16,6 @@
#include "../../lib/mapObjectConstructors/AObjectTypeHandler.h" #include "../../lib/mapObjectConstructors/AObjectTypeHandler.h"
#include "../../lib/mapObjectConstructors/CObjectClassesHandler.h" #include "../../lib/mapObjectConstructors/CObjectClassesHandler.h"
#include "../../lib/mapObjectConstructors/CBankInstanceConstructor.h" #include "../../lib/mapObjectConstructors/CBankInstanceConstructor.h"
#include "../../lib/mapObjects/CBank.h"
#include "../../lib/mapObjects/CGCreature.h" #include "../../lib/mapObjects/CGCreature.h"
#include "../../lib/mapObjects/CGDwelling.h" #include "../../lib/mapObjects/CGDwelling.h"
#include "../../lib/gameState/InfoAboutArmy.h" #include "../../lib/gameState/InfoAboutArmy.h"
@ -62,25 +61,6 @@ Goals::TSubgoal FuzzyHelper::chooseSolution(Goals::TGoalVec vec)
return result; return result;
} }
ui64 FuzzyHelper::estimateBankDanger(const CBank * bank)
{
//this one is not fuzzy anymore, just calculate weighted average
auto objectInfo = bank->getObjectHandler()->getObjectInfo(bank->appearance);
CBankInfo * bankInfo = dynamic_cast<CBankInfo *>(objectInfo.get());
ui64 totalStrength = 0;
ui8 totalChance = 0;
for(auto config : bankInfo->getPossibleGuards(bank->cb))
{
totalStrength += config.second.totalStrength * config.first;
totalChance += config.first;
}
return totalStrength / std::max<ui8>(totalChance, 1); //avoid division by zero
}
float FuzzyHelper::evaluate(Goals::VisitTile & g) float FuzzyHelper::evaluate(Goals::VisitTile & g)
{ {
if(g.parent) if(g.parent)
@ -302,7 +282,6 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj, const VCAI * ai)
return iat.army.getStrength(); return iat.army.getStrength();
} }
case Obj::MONSTER: case Obj::MONSTER:
case Obj::CRYPT:
{ {
//TODO!!!!!!!! //TODO!!!!!!!!
const CGCreature * cre = dynamic_cast<const CGCreature *>(obj); const CGCreature * cre = dynamic_cast<const CGCreature *>(obj);
@ -320,12 +299,16 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj, const VCAI * ai)
const CArmedInstance * a = dynamic_cast<const CArmedInstance *>(obj); const CArmedInstance * a = dynamic_cast<const CArmedInstance *>(obj);
return a->getArmyStrength(); return a->getArmyStrength();
} }
case Obj::CRYPT:
case Obj::CREATURE_BANK: //crebank case Obj::CREATURE_BANK: //crebank
case Obj::DRAGON_UTOPIA: case Obj::DRAGON_UTOPIA:
case Obj::SHIPWRECK: //shipwreck case Obj::SHIPWRECK: //shipwreck
case Obj::DERELICT_SHIP: //derelict ship case Obj::DERELICT_SHIP: //derelict ship
case Obj::PYRAMID: case Obj::PYRAMID:
return estimateBankDanger(dynamic_cast<const CBank *>(obj)); {
const CArmedInstance * a = dynamic_cast<const CArmedInstance *>(obj);
return a->getArmyStrength();
}
default: default:
return 0; return 0;
} }

View File

@ -10,12 +10,6 @@
#pragma once #pragma once
#include "FuzzyEngines.h" #include "FuzzyEngines.h"
VCMI_LIB_NAMESPACE_BEGIN
class CBank;
VCMI_LIB_NAMESPACE_END
class DLL_EXPORT FuzzyHelper class DLL_EXPORT FuzzyHelper
{ {
public: public:
@ -42,8 +36,6 @@ public:
float evaluate(Goals::AbstractGoal & g); float evaluate(Goals::AbstractGoal & g);
void setPriority(Goals::TSubgoal & g); void setPriority(Goals::TSubgoal & g);
ui64 estimateBankDanger(const CBank * bank); //TODO: move to another class?
Goals::TSubgoal chooseSolution(Goals::TGoalVec vec); Goals::TSubgoal chooseSolution(Goals::TGoalVec vec);
//std::shared_ptr<AbstractGoal> chooseSolution (std::vector<std::shared_ptr<AbstractGoal>> & vec); //std::shared_ptr<AbstractGoal> chooseSolution (std::vector<std::shared_ptr<AbstractGoal>> & vec);

View File

@ -2750,8 +2750,6 @@ bool isWeeklyRevisitable(const CGObjectInstance * obj)
if(dynamic_cast<const CGDwelling *>(obj)) if(dynamic_cast<const CGDwelling *>(obj))
return true; return true;
if(dynamic_cast<const CBank *>(obj)) //banks tend to respawn often in mods
return true;
switch(obj->ID) switch(obj->ID)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -98,6 +98,9 @@
"max" : { "type" : "number", "exclusiveMinimum" : 0, "maximum" : 100 } "max" : { "type" : "number", "exclusiveMinimum" : 0, "maximum" : 100 }
} }
}, },
"guards" : {}, //TODO
"limiter" : { "$ref" : "#/definitions/limiter" }, "limiter" : { "$ref" : "#/definitions/limiter" },
"message" : { "$ref" : "#/definitions/message" }, "message" : { "$ref" : "#/definitions/message" },
"description" : { "$ref" : "#/definitions/message" }, "description" : { "$ref" : "#/definitions/message" },
@ -256,6 +259,9 @@
}, },
}, },
"onGuardedMessage" : {
"$ref" : "#/definitions/message"
},
"onSelectMessage" : { "onSelectMessage" : {
"$ref" : "#/definitions/message" "$ref" : "#/definitions/message"
}, },

View File

@ -26,7 +26,6 @@ class CGHeroInstance;
class CGMarket; class CGMarket;
class CHeroClass; class CHeroClass;
class CGCreature; class CGCreature;
class CBank;
class CGBoat; class CGBoat;
class CFaction; class CFaction;
class CStackBasicDescriptor; class CStackBasicDescriptor;

View File

@ -140,119 +140,28 @@ void CBank::onHeroVisit(const CGHeroInstance * h) const
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_PLAYER, id, h->id); ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_PLAYER, id, h->id);
cb->sendAndApply(&cov); cb->sendAndApply(&cov);
if(!bankConfig && (ID.toEnum() == Obj::CREATURE_BANK || ID.toEnum() == Obj::DRAGON_UTOPIA))
{
blockingDialogAnswered(h, 1);
return;
}
int banktext = 0;
switch (ID.toEnum())
{
case Obj::DERELICT_SHIP:
banktext = 41;
break;
case Obj::DRAGON_UTOPIA:
banktext = 47;
break;
case Obj::SHIPWRECK:
banktext = 122;
break;
case Obj::PYRAMID:
banktext = 105;
break;
default:
banktext = 32;
break;
}
BlockingDialog bd(true, false); BlockingDialog bd(true, false);
bd.player = h->getOwner(); bd.player = h->getOwner();
bd.text.appendLocalString(EMetaText::ADVOB_TXT, banktext); bd.text.appendLocalString(EMetaText::ADVOB_TXT, 32);
bd.components = getPopupComponents(h->getOwner()); bd.components = getPopupComponents(h->getOwner());
if (banktext == 32)
bd.text.replaceRawString(getObjectName()); bd.text.replaceRawString(getObjectName());
cb->showBlockingDialog(this, &bd); cb->showBlockingDialog(this, &bd);
} }
void CBank::doVisit(const CGHeroInstance * hero) const void CBank::doVisit(const CGHeroInstance * hero) const
{ {
int textID = -1;
InfoWindow iw; InfoWindow iw;
iw.type = EInfoWindowMode::AUTO; iw.type = EInfoWindowMode::AUTO;
iw.player = hero->getOwner(); iw.player = hero->getOwner();
MetaString loot; MetaString loot;
if (bankConfig) if (!bankConfig)
{ {
switch (ID.toEnum())
{
case Obj::DERELICT_SHIP:
textID = 43;
break;
case Obj::SHIPWRECK:
textID = 124;
break;
case Obj::PYRAMID:
textID = 106;
break;
default:
textID = 34;
break;
}
}
else
{
switch (ID.toEnum())
{
case Obj::SHIPWRECK:
case Obj::DERELICT_SHIP:
{
GiveBonus gbonus;
gbonus.id = hero->id;
gbonus.bonus.duration = BonusDuration::ONE_BATTLE;
gbonus.bonus.source = BonusSource::OBJECT_TYPE;
gbonus.bonus.sid = BonusSourceID(ID);
gbonus.bonus.type = BonusType::MORALE;
gbonus.bonus.val = -1;
switch (ID.toEnum())
{
case Obj::SHIPWRECK:
textID = 123;
gbonus.bonus.description = MetaString::createFromTextID("core.arraytxt.99");
break;
case Obj::DERELICT_SHIP:
textID = 42;
gbonus.bonus.description = MetaString::createFromTextID("core.arraytxt.101");
break;
}
cb->giveHeroBonus(&gbonus);
iw.components.emplace_back(ComponentType::MORALE, -1);
break;
}
case Obj::PYRAMID:
{
GiveBonus gb;
gb.bonus = Bonus(BonusDuration::ONE_BATTLE, BonusType::LUCK, BonusSource::OBJECT_INSTANCE, -2, BonusSourceID(id));
gb.bonus.description = MetaString::createFromTextID("core.arraytxt.70");
gb.id = hero->id;
cb->giveHeroBonus(&gb);
textID = 107;
iw.components.emplace_back(ComponentType::LUCK, -2);
break;
}
default:
iw.text.appendRawString(VLC->generaltexth->advobtxt[33]);// This was X, now is completely empty iw.text.appendRawString(VLC->generaltexth->advobtxt[33]);// This was X, now is completely empty
iw.text.replaceRawString(getObjectName()); iw.text.replaceRawString(getObjectName());
}
if(textID != -1)
{
iw.text.appendLocalString(EMetaText::ADVOB_TXT, textID);
}
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
} }
//grant resources //grant resources
if (bankConfig) if (bankConfig)
{ {
@ -278,9 +187,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
//display loot //display loot
if (!iw.components.empty()) if (!iw.components.empty())
{ {
iw.text.appendLocalString(EMetaText::ADVOB_TXT, textID); iw.text.appendLocalString(EMetaText::ADVOB_TXT, 34);
if (textID == 34)
{
const auto * strongest = boost::range::max_element(bankConfig->guards, [](const CStackBasicDescriptor & a, const CStackBasicDescriptor & b) const auto * strongest = boost::range::max_element(bankConfig->guards, [](const CStackBasicDescriptor & a, const CStackBasicDescriptor & b)
{ {
return a.type->getFightValue() < b.type->getFightValue(); return a.type->getFightValue() < b.type->getFightValue();
@ -288,7 +195,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
iw.text.replaceNamePlural(strongest->getId()); iw.text.replaceNamePlural(strongest->getId());
iw.text.replaceRawString(loot.buildList()); iw.text.replaceRawString(loot.buildList());
}
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
} }
@ -301,10 +208,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
std::set<SpellID> spells; std::set<SpellID> spells;
bool noWisdom = false; bool noWisdom = false;
if(textID == 106)
{
iw.text.appendLocalString(EMetaText::ADVOB_TXT, textID); //pyramid
}
for(const SpellID & spellId : bankConfig->spells) for(const SpellID & spellId : bankConfig->spells)
{ {
const auto * spell = spellId.toEntity(VLC); const auto * spell = spellId.toEntity(VLC);

View File

@ -100,13 +100,6 @@ public:
}; };
//TODO: //TODO:
// MAX
// class DLL_LINKAGE CBank : public CArmedInstance
// class DLL_LINKAGE CGPyramid : public CBank
// EXTRA
// class DLL_LINKAGE CTownBonus : public CGTownBuilding
// class DLL_LINKAGE CGKeys : public CGObjectInstance //Base class for Keymaster and guards // class DLL_LINKAGE CGKeys : public CGObjectInstance //Base class for Keymaster and guards
// class DLL_LINKAGE CGKeymasterTent : public CGKeys // class DLL_LINKAGE CGKeymasterTent : public CGKeys
// class DLL_LINKAGE CGBorderGuard : public CGKeys, public IQuestObject // class DLL_LINKAGE CGBorderGuard : public CGKeys, public IQuestObject

View File

@ -14,7 +14,6 @@
#include "CObjectHandler.h" #include "CObjectHandler.h"
#include "CArmedInstance.h" #include "CArmedInstance.h"
#include "CBank.h"
#include "CGDwelling.h" #include "CGDwelling.h"
#include "CGHeroInstance.h" #include "CGHeroInstance.h"
#include "CGMarket.h" #include "CGMarket.h"

View File

@ -1459,7 +1459,7 @@ CGObjectInstance * CMapLoaderH3M::readGeneric(const int3 & mapPosition, std::sha
CGObjectInstance * CMapLoaderH3M::readPyramid(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate) CGObjectInstance * CMapLoaderH3M::readPyramid(const int3 & mapPosition, std::shared_ptr<const ObjectTemplate> objectTemplate)
{ {
if(objectTemplate->subid == 0) if(objectTemplate->subid == 0)
return new CBank(map->cb); return readGeneric(mapPosition, objectTemplate);
return new CGObjectInstance(map->cb); return new CGObjectInstance(map->cb);
} }