1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-11 11:31:52 +02:00

It is now possible to configure what exactly will be reset in object

This commit is contained in:
Ivan Savenko 2023-01-24 13:54:03 +02:00
parent 0c70822928
commit ecbcafefbc
7 changed files with 112 additions and 32 deletions

View File

@ -115,22 +115,31 @@
"onVisitedMessage" : 56,
"visitMode" : "bonus",
"selectMode" : "selectRandom",
"selectMode" : "selectFirst",
"resetParameters" : {
"period" : 7,
"rewards" : true
},
"rewards" : [
{
"message" : 55,
"appearChance" : { "min" : 0, "max" : 25 },
"bonuses" : [ { "type" : "LUCK", "val" : -1, "duration" : "ONE_BATTLE", "desription" : 69 } ] // NOTE: strings has %s placeholder for morale value
},
{
"message" : 55,
"appearChance" : { "min" : 25, "max" : 50 },
"bonuses" : [ { "type" : "LUCK", "val" : 1, "duration" : "ONE_BATTLE", "desription" : 69 } ] // NOTE: strings has %s placeholder for morale value
},
{
"message" : 55,
"appearChance" : { "min" : 50, "max" : 75 },
"bonuses" : [ { "type" : "LUCK", "val" : 2, "duration" : "ONE_BATTLE", "desription" : 69 } ] // NOTE: strings has %s placeholder for morale value
},
{
"message" : 55,
"appearChance" : { "min" : 75, "max" : 100 },
"bonuses" : [ { "type" : "LUCK", "val" : 3, "duration" : "ONE_BATTLE", "desription" : 69 } ] // NOTE: strings has %s placeholder for morale value
},
]

View File

@ -1,6 +1,5 @@
{
/// These are objects that covered by concept of "configurable object" and have their entire configuration in this config
"magicWell" : {
"index" :49,
"handler" : "configurable",
@ -21,14 +20,14 @@
"onEmptyMessage" : 79,
"onVisitedMessage" : 78,
"resetDuration" : 1,
"visitMode" : "once",
"visitMode" : "bonus",
"selectMode" : "selectFirst",
"rewards" : [
{
"limiter" : {
"noneOf" : [ { "manaPercentage" : 100 } ]
},
"bonuses" : [ { "type" : "NONE", "duration" : "ONE_DAY"} ],
"message" : 77,
"manaPercentage" : 100
}
@ -58,7 +57,10 @@
"onEmptyMessage" : 76,
"onVisitedMessage" : 75,
"resetDuration" : 7,
"resetParameters" : {
"period" : 7,
"visitors" : true
},
"visitMode" : "once",
"selectMode" : "selectFirst",
"rewards" : [
@ -92,7 +94,11 @@
},
"onEmptyMessage" : 93,
"resetDuration" : 7,
"resetParameters" : {
"period" : 7,
"visitors" : true,
"rewards" : true
},
"visitMode" : "once",
"selectMode" : "selectFirst",
"rewards" : [
@ -129,7 +135,11 @@
},
"onEmptyMessage" : 169,
"resetDuration" : 7,
"resetParameters" : {
"period" : 7,
"visitors" : true,
"rewards" : true
},
"visitMode" : "once",
"selectMode" : "selectFirst",
"rewards" : [
@ -166,7 +176,10 @@
},
"onEmptyMessage" : 165,
"resetDuration" : 7,
"resetParameters" : {
"period" : 7,
"visitors" : true
},
"visitMode" : "once",
"selectMode" : "selectFirst",
"rewards" : [

View File

@ -1178,7 +1178,7 @@ namespace ObjProperty
BANK_DAYCOUNTER, BANK_RESET, BANK_CLEAR,
//object with reward
REWARD_RESET, REWARD_SELECT
REWARD_RANDOMIZE, REWARDS_CLEAR_GRANTS, REWARD_SELECT
};
}

View File

@ -119,8 +119,18 @@ void CRandomRewardObjectInfo::configureReward(CRewardableObject * object, CRando
reward.creatures = JsonRandom::loadCreatures(source["creatures"], rng);
}
void CRandomRewardObjectInfo::configureResetInfo(CRewardableObject * object, CRandomGenerator & rng, CRewardResetInfo & resetParameters, const JsonNode & source) const
{
resetParameters.period = static_cast<ui32>(source["period"].Float());
resetParameters.visitors = source["visitors"].Bool();
resetParameters.grants = source["grants"].Bool();
resetParameters.rewards = source["rewards"].Bool();
}
void CRandomRewardObjectInfo::configureObject(CRewardableObject * object, CRandomGenerator & rng) const
{
object->info.clear();
std::map<si32, si32> thrownDice;
for (const JsonNode & reward : parameters["rewards"].Vector())
@ -147,7 +157,7 @@ void CRandomRewardObjectInfo::configureObject(CRewardableObject * object, CRando
}
}
CVisitInfo info;
CRewardVisitInfo info;
configureLimiter(object, rng, info.limiter, reward["limiter"]);
configureReward(object, rng, info.reward, reward);
@ -168,7 +178,9 @@ void CRandomRewardObjectInfo::configureObject(CRewardableObject * object, CRando
object->onSelect = loadMessage(parameters["onSelectMessage"]);
object->onVisited = loadMessage(parameters["onVisitedMessage"]);
object->onEmpty = loadMessage(parameters["onEmptyMessage"]);
object->resetDuration = static_cast<ui16>(parameters["resetDuration"].Float());
configureResetInfo(object, rng, object->resetParameters, parameters["resetParameters"]);
object->canRefuse = parameters["canRefuse"].Bool();
auto visitMode = parameters["visitMode"].String();

View File

@ -24,6 +24,7 @@ class DLL_LINKAGE CRandomRewardObjectInfo : public IObjectInfo
TRewardLimitersList configureSublimiters(CRewardableObject * object, CRandomGenerator & rng, const JsonNode & source) const;
void configureReward(CRewardableObject * object, CRandomGenerator & rng, CRewardInfo & info, const JsonNode & source) const;
void configureResetInfo(CRewardableObject * object, CRandomGenerator & rng, CRewardResetInfo & info, const JsonNode & source) const;
public:
bool givesResources() const override;

View File

@ -102,7 +102,7 @@ std::vector<ui32> CRewardableObject::getAvailableRewards(const CGHeroInstance *
for(size_t i=0; i<info.size(); i++)
{
const CVisitInfo & visit = info[i];
const CRewardVisitInfo & visit = info[i];
if((visit.numOfGrantsAllowed == 0 || visit.numOfGrantsPerformed < visit.numOfGrantsAllowed) // reward has unlimited uses or some are still available
&& visit.limiter.heroAllowed(hero))
@ -114,7 +114,7 @@ std::vector<ui32> CRewardableObject::getAvailableRewards(const CGHeroInstance *
return ret;
}
CVisitInfo CRewardableObject::getVisitInfo(int index, const CGHeroInstance *) const
CRewardVisitInfo CRewardableObject::getVisitInfo(int index, const CGHeroInstance *) const
{
return info[index];
}
@ -250,7 +250,7 @@ void CRewardableObject::grantReward(ui32 rewardID, const CGHeroInstance * hero)
grantRewardBeforeLevelup(getVisitInfo(rewardID, hero), hero);
}
void CRewardableObject::grantRewardBeforeLevelup(const CVisitInfo & info, const CGHeroInstance * hero) const
void CRewardableObject::grantRewardBeforeLevelup(const CRewardVisitInfo & info, const CGHeroInstance * hero) const
{
assert(hero);
assert(hero->tempOwner.isValidPlayer());
@ -287,7 +287,7 @@ void CRewardableObject::grantRewardBeforeLevelup(const CVisitInfo & info, const
}
}
void CRewardableObject::grantRewardAfterLevelup(const CVisitInfo & info, const CGHeroInstance * hero) const
void CRewardableObject::grantRewardAfterLevelup(const CRewardVisitInfo & info, const CGHeroInstance * hero) const
{
if(info.reward.manaDiff || info.reward.manaPercentage >= 0)
{
@ -392,7 +392,7 @@ CRewardableObject::EVisitMode CRewardableObject::getVisitMode() const
ui16 CRewardableObject::getResetDuration() const
{
return resetDuration;
return resetParameters.period;
}
void CRewardInfo::loadComponents(std::vector<Component> & comps,
@ -468,7 +468,10 @@ void CRewardableObject::setPropertyDer(ui8 what, ui32 val)
{
switch (what)
{
case ObjProperty::REWARD_RESET:
case ObjProperty::REWARD_RANDOMIZE:
initObj(cb->gameState()->getRandomGenerator());
break;
case ObjProperty::REWARDS_CLEAR_GRANTS:
for (auto & visit : info)
visit.numOfGrantsPerformed = 0;
break;
@ -479,15 +482,27 @@ void CRewardableObject::setPropertyDer(ui8 what, ui32 val)
}
}
void CRewardableObject::triggerRewardReset() const
void CRewardableObject::triggerReset() const
{
cb->setObjProperty(id, ObjProperty::REWARD_RESET, 0);
if (resetParameters.rewards)
{
cb->setObjProperty(id, ObjProperty::REWARD_RANDOMIZE, 0);
}
if (resetParameters.grants)
{
cb->setObjProperty(id, ObjProperty::REWARDS_CLEAR_GRANTS, 0);
}
if (resetParameters.visitors)
{
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_CLEAR, id);
cb->sendAndApply(&cov);
}
}
void CRewardableObject::newTurn(CRandomGenerator & rand) const
{
if (resetDuration != 0 && cb->getDate(Date::DAY) > 1 && (cb->getDate(Date::DAY) % resetDuration) == 1)
triggerRewardReset();
if (resetParameters.period != 0 && cb->getDate(Date::DAY) > 1 && (cb->getDate(Date::DAY) % resetParameters.period) == 1)
triggerReset();
}
void CRewardableObject::initObj(CRandomGenerator & rand)
@ -499,7 +514,6 @@ CRewardableObject::CRewardableObject():
selectMode(0),
visitMode(0),
selectedReward(0),
resetDuration(0),
canRefuse(false)
{}

View File

@ -88,6 +88,37 @@ public:
}
};
class DLL_LINKAGE CRewardResetInfo
{
public:
CRewardResetInfo()
: period(0)
, visitors(false)
, grants(false)
, rewards(false)
{}
/// if above zero, object state will be reset each resetDuration days
ui32 period;
/// if true - reset list of visitors (heroes & players) on reset
bool visitors;
/// if true - reset number of grants of rewards on reset
bool grants;
/// if true - re-randomize rewards on a new week
bool rewards;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & period;
h & visitors;
h & grants;
h & rewards;
}
};
/// Reward that can be granted to a hero
/// NOTE: eventually should replace seer hut rewards and events/pandoras
class DLL_LINKAGE CRewardInfo
@ -170,7 +201,7 @@ public:
}
};
class DLL_LINKAGE CVisitInfo
class DLL_LINKAGE CRewardVisitInfo
{
public:
CRewardLimiter limiter;
@ -188,7 +219,7 @@ public:
/// How many times this reward has been granted since last reset
si32 numOfGrantsPerformed;
CVisitInfo():
CRewardVisitInfo():
selectChance(0),
numOfGrantsAllowed(0),
numOfGrantsPerformed(0)
@ -216,10 +247,10 @@ namespace Rewardable
class DLL_LINKAGE CRewardableObject : public CArmedInstance
{
/// function that must be called if hero got level-up during grantReward call
void grantRewardAfterLevelup(const CVisitInfo & reward, const CGHeroInstance * hero) const;
void grantRewardAfterLevelup(const CRewardVisitInfo & reward, const CGHeroInstance * hero) const;
/// grants reward to hero
void grantRewardBeforeLevelup(const CVisitInfo & reward, const CGHeroInstance * hero) const;
void grantRewardBeforeLevelup(const CRewardVisitInfo & reward, const CGHeroInstance * hero) const;
public:
enum EVisitMode
@ -245,12 +276,12 @@ protected:
virtual void grantReward(ui32 rewardID, const CGHeroInstance * hero) const;
virtual CVisitInfo getVisitInfo(int index, const CGHeroInstance *h) const;
virtual CRewardVisitInfo getVisitInfo(int index, const CGHeroInstance *h) const;
virtual void triggerRewardReset() const;
virtual void triggerReset() const;
/// Rewards that can be granted by an object
std::vector<CVisitInfo> info;
std::vector<CRewardVisitInfo> info;
/// MetaString's that contain text for messages for specific situations
MetaString onSelect;
@ -264,8 +295,8 @@ protected:
/// reward selected by player
ui16 selectedReward;
/// object visitability info will be reset each resetDuration days
ui16 resetDuration;
/// how and when should the object be reset
CRewardResetInfo resetParameters;
/// if true - player can refuse visiting an object (e.g. Tomb)
bool canRefuse;
@ -306,7 +337,7 @@ public:
h & static_cast<CArmedInstance&>(*this);
h & info;
h & canRefuse;
h & resetDuration;
h & resetParameters;
h & onSelect;
h & onVisited;
h & onEmpty;