1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-20 20:23:03 +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);
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);
if(fort)
castleWalls->setValue(fort->fortLevel());

View File

@ -20,25 +20,6 @@
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)
{
auto cb = ai->cb.get();
@ -171,14 +152,11 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj)
case Obj::DRAGON_UTOPIA:
case Obj::SHIPWRECK: //shipwreck
case Obj::DERELICT_SHIP: //derelict ship
case Obj::PYRAMID:
{
const CArmedInstance * a = dynamic_cast<const CArmedInstance *>(obj);
return a->getArmyStrength();
}
case Obj::PYRAMID:
{
return estimateBankDanger(dynamic_cast<const CBank *>(obj));
}
default:
return 0;
}

View File

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

View File

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

View File

@ -219,12 +219,6 @@ float TacticalAdvantageEngine::getTacticalAdvantage(const CArmedInstance * we, c
enemyFlyers->setValue(enemyStructure.flyers);
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);
if(fort)
castleWalls->setValue(fort->fortLevel());

View File

@ -16,7 +16,6 @@
#include "../../lib/mapObjectConstructors/AObjectTypeHandler.h"
#include "../../lib/mapObjectConstructors/CObjectClassesHandler.h"
#include "../../lib/mapObjectConstructors/CBankInstanceConstructor.h"
#include "../../lib/mapObjects/CBank.h"
#include "../../lib/mapObjects/CGCreature.h"
#include "../../lib/mapObjects/CGDwelling.h"
#include "../../lib/gameState/InfoAboutArmy.h"
@ -62,25 +61,6 @@ Goals::TSubgoal FuzzyHelper::chooseSolution(Goals::TGoalVec vec)
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)
{
if(g.parent)
@ -302,7 +282,6 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj, const VCAI * ai)
return iat.army.getStrength();
}
case Obj::MONSTER:
case Obj::CRYPT:
{
//TODO!!!!!!!!
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);
return a->getArmyStrength();
}
case Obj::CRYPT:
case Obj::CREATURE_BANK: //crebank
case Obj::DRAGON_UTOPIA:
case Obj::SHIPWRECK: //shipwreck
case Obj::DERELICT_SHIP: //derelict ship
case Obj::PYRAMID:
return estimateBankDanger(dynamic_cast<const CBank *>(obj));
{
const CArmedInstance * a = dynamic_cast<const CArmedInstance *>(obj);
return a->getArmyStrength();
}
default:
return 0;
}

View File

@ -10,12 +10,6 @@
#pragma once
#include "FuzzyEngines.h"
VCMI_LIB_NAMESPACE_BEGIN
class CBank;
VCMI_LIB_NAMESPACE_END
class DLL_EXPORT FuzzyHelper
{
public:
@ -42,8 +36,6 @@ public:
float evaluate(Goals::AbstractGoal & g);
void setPriority(Goals::TSubgoal & g);
ui64 estimateBankDanger(const CBank * bank); //TODO: move to another class?
Goals::TSubgoal chooseSolution(Goals::TGoalVec 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))
return true;
if(dynamic_cast<const CBank *>(obj)) //banks tend to respawn often in mods
return true;
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 }
}
},
"guards" : {}, //TODO
"limiter" : { "$ref" : "#/definitions/limiter" },
"message" : { "$ref" : "#/definitions/message" },
"description" : { "$ref" : "#/definitions/message" },
@ -256,6 +259,9 @@
},
},
"onGuardedMessage" : {
"$ref" : "#/definitions/message"
},
"onSelectMessage" : {
"$ref" : "#/definitions/message"
},

View File

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

View File

@ -140,119 +140,28 @@ void CBank::onHeroVisit(const CGHeroInstance * h) const
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_PLAYER, id, h->id);
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);
bd.player = h->getOwner();
bd.text.appendLocalString(EMetaText::ADVOB_TXT, banktext);
bd.text.appendLocalString(EMetaText::ADVOB_TXT, 32);
bd.components = getPopupComponents(h->getOwner());
if (banktext == 32)
bd.text.replaceRawString(getObjectName());
bd.text.replaceRawString(getObjectName());
cb->showBlockingDialog(this, &bd);
}
void CBank::doVisit(const CGHeroInstance * hero) const
{
int textID = -1;
InfoWindow iw;
iw.type = EInfoWindowMode::AUTO;
iw.player = hero->getOwner();
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.replaceRawString(getObjectName());
}
if(textID != -1)
{
iw.text.appendLocalString(EMetaText::ADVOB_TXT, textID);
}
iw.text.appendRawString(VLC->generaltexth->advobtxt[33]);// This was X, now is completely empty
iw.text.replaceRawString(getObjectName());
cb->showInfoDialog(&iw);
}
//grant resources
if (bankConfig)
{
@ -278,17 +187,15 @@ void CBank::doVisit(const CGHeroInstance * hero) const
//display loot
if (!iw.components.empty())
{
iw.text.appendLocalString(EMetaText::ADVOB_TXT, textID);
if (textID == 34)
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 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();
})->type;
return a.type->getFightValue() < b.type->getFightValue();
})->type;
iw.text.replaceNamePlural(strongest->getId());
iw.text.replaceRawString(loot.buildList());
iw.text.replaceNamePlural(strongest->getId());
iw.text.replaceRawString(loot.buildList());
}
cb->showInfoDialog(&iw);
}
@ -301,10 +208,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
std::set<SpellID> spells;
bool noWisdom = false;
if(textID == 106)
{
iw.text.appendLocalString(EMetaText::ADVOB_TXT, textID); //pyramid
}
for(const SpellID & spellId : bankConfig->spells)
{
const auto * spell = spellId.toEntity(VLC);

View File

@ -100,13 +100,6 @@ public:
};
//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 CGKeymasterTent : public CGKeys
// class DLL_LINKAGE CGBorderGuard : public CGKeys, public IQuestObject

View File

@ -14,7 +14,6 @@
#include "CObjectHandler.h"
#include "CArmedInstance.h"
#include "CBank.h"
#include "CGDwelling.h"
#include "CGHeroInstance.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)
{
if(objectTemplate->subid == 0)
return new CBank(map->cb);
return readGeneric(mapPosition, objectTemplate);
return new CGObjectInstance(map->cb);
}