1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-13 11:40:38 +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, "onVisitedMessage" : 56,
"visitMode" : "bonus", "visitMode" : "bonus",
"selectMode" : "selectRandom", "selectMode" : "selectFirst",
"resetParameters" : {
"period" : 7,
"rewards" : true
},
"rewards" : [ "rewards" : [
{ {
"message" : 55, "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 "bonuses" : [ { "type" : "LUCK", "val" : -1, "duration" : "ONE_BATTLE", "desription" : 69 } ] // NOTE: strings has %s placeholder for morale value
}, },
{ {
"message" : 55, "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 "bonuses" : [ { "type" : "LUCK", "val" : 1, "duration" : "ONE_BATTLE", "desription" : 69 } ] // NOTE: strings has %s placeholder for morale value
}, },
{ {
"message" : 55, "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 "bonuses" : [ { "type" : "LUCK", "val" : 2, "duration" : "ONE_BATTLE", "desription" : 69 } ] // NOTE: strings has %s placeholder for morale value
}, },
{ {
"message" : 55, "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 "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 /// These are objects that covered by concept of "configurable object" and have their entire configuration in this config
"magicWell" : { "magicWell" : {
"index" :49, "index" :49,
"handler" : "configurable", "handler" : "configurable",
@ -21,14 +20,14 @@
"onEmptyMessage" : 79, "onEmptyMessage" : 79,
"onVisitedMessage" : 78, "onVisitedMessage" : 78,
"resetDuration" : 1, "visitMode" : "bonus",
"visitMode" : "once",
"selectMode" : "selectFirst", "selectMode" : "selectFirst",
"rewards" : [ "rewards" : [
{ {
"limiter" : { "limiter" : {
"noneOf" : [ { "manaPercentage" : 100 } ] "noneOf" : [ { "manaPercentage" : 100 } ]
}, },
"bonuses" : [ { "type" : "NONE", "duration" : "ONE_DAY"} ],
"message" : 77, "message" : 77,
"manaPercentage" : 100 "manaPercentage" : 100
} }
@ -58,7 +57,10 @@
"onEmptyMessage" : 76, "onEmptyMessage" : 76,
"onVisitedMessage" : 75, "onVisitedMessage" : 75,
"resetDuration" : 7, "resetParameters" : {
"period" : 7,
"visitors" : true
},
"visitMode" : "once", "visitMode" : "once",
"selectMode" : "selectFirst", "selectMode" : "selectFirst",
"rewards" : [ "rewards" : [
@ -92,7 +94,11 @@
}, },
"onEmptyMessage" : 93, "onEmptyMessage" : 93,
"resetDuration" : 7, "resetParameters" : {
"period" : 7,
"visitors" : true,
"rewards" : true
},
"visitMode" : "once", "visitMode" : "once",
"selectMode" : "selectFirst", "selectMode" : "selectFirst",
"rewards" : [ "rewards" : [
@ -129,7 +135,11 @@
}, },
"onEmptyMessage" : 169, "onEmptyMessage" : 169,
"resetDuration" : 7, "resetParameters" : {
"period" : 7,
"visitors" : true,
"rewards" : true
},
"visitMode" : "once", "visitMode" : "once",
"selectMode" : "selectFirst", "selectMode" : "selectFirst",
"rewards" : [ "rewards" : [
@ -166,7 +176,10 @@
}, },
"onEmptyMessage" : 165, "onEmptyMessage" : 165,
"resetDuration" : 7, "resetParameters" : {
"period" : 7,
"visitors" : true
},
"visitMode" : "once", "visitMode" : "once",
"selectMode" : "selectFirst", "selectMode" : "selectFirst",
"rewards" : [ "rewards" : [

View File

@ -1178,7 +1178,7 @@ namespace ObjProperty
BANK_DAYCOUNTER, BANK_RESET, BANK_CLEAR, BANK_DAYCOUNTER, BANK_RESET, BANK_CLEAR,
//object with reward //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); 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 void CRandomRewardObjectInfo::configureObject(CRewardableObject * object, CRandomGenerator & rng) const
{ {
object->info.clear();
std::map<si32, si32> thrownDice; std::map<si32, si32> thrownDice;
for (const JsonNode & reward : parameters["rewards"].Vector()) 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"]); configureLimiter(object, rng, info.limiter, reward["limiter"]);
configureReward(object, rng, info.reward, reward); configureReward(object, rng, info.reward, reward);
@ -168,7 +178,9 @@ void CRandomRewardObjectInfo::configureObject(CRewardableObject * object, CRando
object->onSelect = loadMessage(parameters["onSelectMessage"]); object->onSelect = loadMessage(parameters["onSelectMessage"]);
object->onVisited = loadMessage(parameters["onVisitedMessage"]); object->onVisited = loadMessage(parameters["onVisitedMessage"]);
object->onEmpty = loadMessage(parameters["onEmptyMessage"]); 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(); object->canRefuse = parameters["canRefuse"].Bool();
auto visitMode = parameters["visitMode"].String(); 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; TRewardLimitersList configureSublimiters(CRewardableObject * object, CRandomGenerator & rng, const JsonNode & source) const;
void configureReward(CRewardableObject * object, CRandomGenerator & rng, CRewardInfo & info, 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: public:
bool givesResources() const override; 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++) 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 if((visit.numOfGrantsAllowed == 0 || visit.numOfGrantsPerformed < visit.numOfGrantsAllowed) // reward has unlimited uses or some are still available
&& visit.limiter.heroAllowed(hero)) && visit.limiter.heroAllowed(hero))
@ -114,7 +114,7 @@ std::vector<ui32> CRewardableObject::getAvailableRewards(const CGHeroInstance *
return ret; return ret;
} }
CVisitInfo CRewardableObject::getVisitInfo(int index, const CGHeroInstance *) const CRewardVisitInfo CRewardableObject::getVisitInfo(int index, const CGHeroInstance *) const
{ {
return info[index]; return info[index];
} }
@ -250,7 +250,7 @@ void CRewardableObject::grantReward(ui32 rewardID, const CGHeroInstance * hero)
grantRewardBeforeLevelup(getVisitInfo(rewardID, hero), 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);
assert(hero->tempOwner.isValidPlayer()); 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) if(info.reward.manaDiff || info.reward.manaPercentage >= 0)
{ {
@ -392,7 +392,7 @@ CRewardableObject::EVisitMode CRewardableObject::getVisitMode() const
ui16 CRewardableObject::getResetDuration() const ui16 CRewardableObject::getResetDuration() const
{ {
return resetDuration; return resetParameters.period;
} }
void CRewardInfo::loadComponents(std::vector<Component> & comps, void CRewardInfo::loadComponents(std::vector<Component> & comps,
@ -468,7 +468,10 @@ void CRewardableObject::setPropertyDer(ui8 what, ui32 val)
{ {
switch (what) switch (what)
{ {
case ObjProperty::REWARD_RESET: case ObjProperty::REWARD_RANDOMIZE:
initObj(cb->gameState()->getRandomGenerator());
break;
case ObjProperty::REWARDS_CLEAR_GRANTS:
for (auto & visit : info) for (auto & visit : info)
visit.numOfGrantsPerformed = 0; visit.numOfGrantsPerformed = 0;
break; 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 void CRewardableObject::newTurn(CRandomGenerator & rand) const
{ {
if (resetDuration != 0 && cb->getDate(Date::DAY) > 1 && (cb->getDate(Date::DAY) % resetDuration) == 1) if (resetParameters.period != 0 && cb->getDate(Date::DAY) > 1 && (cb->getDate(Date::DAY) % resetParameters.period) == 1)
triggerRewardReset(); triggerReset();
} }
void CRewardableObject::initObj(CRandomGenerator & rand) void CRewardableObject::initObj(CRandomGenerator & rand)
@ -499,7 +514,6 @@ CRewardableObject::CRewardableObject():
selectMode(0), selectMode(0),
visitMode(0), visitMode(0),
selectedReward(0), selectedReward(0),
resetDuration(0),
canRefuse(false) 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 /// Reward that can be granted to a hero
/// NOTE: eventually should replace seer hut rewards and events/pandoras /// NOTE: eventually should replace seer hut rewards and events/pandoras
class DLL_LINKAGE CRewardInfo class DLL_LINKAGE CRewardInfo
@ -170,7 +201,7 @@ public:
} }
}; };
class DLL_LINKAGE CVisitInfo class DLL_LINKAGE CRewardVisitInfo
{ {
public: public:
CRewardLimiter limiter; CRewardLimiter limiter;
@ -188,7 +219,7 @@ public:
/// How many times this reward has been granted since last reset /// How many times this reward has been granted since last reset
si32 numOfGrantsPerformed; si32 numOfGrantsPerformed;
CVisitInfo(): CRewardVisitInfo():
selectChance(0), selectChance(0),
numOfGrantsAllowed(0), numOfGrantsAllowed(0),
numOfGrantsPerformed(0) numOfGrantsPerformed(0)
@ -216,10 +247,10 @@ namespace Rewardable
class DLL_LINKAGE CRewardableObject : public CArmedInstance class DLL_LINKAGE CRewardableObject : public CArmedInstance
{ {
/// function that must be called if hero got level-up during grantReward call /// 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 /// grants reward to hero
void grantRewardBeforeLevelup(const CVisitInfo & reward, const CGHeroInstance * hero) const; void grantRewardBeforeLevelup(const CRewardVisitInfo & reward, const CGHeroInstance * hero) const;
public: public:
enum EVisitMode enum EVisitMode
@ -245,12 +276,12 @@ protected:
virtual void grantReward(ui32 rewardID, const CGHeroInstance * hero) const; 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 /// 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's that contain text for messages for specific situations
MetaString onSelect; MetaString onSelect;
@ -264,8 +295,8 @@ protected:
/// reward selected by player /// reward selected by player
ui16 selectedReward; ui16 selectedReward;
/// object visitability info will be reset each resetDuration days /// how and when should the object be reset
ui16 resetDuration; CRewardResetInfo resetParameters;
/// if true - player can refuse visiting an object (e.g. Tomb) /// if true - player can refuse visiting an object (e.g. Tomb)
bool canRefuse; bool canRefuse;
@ -306,7 +337,7 @@ public:
h & static_cast<CArmedInstance&>(*this); h & static_cast<CArmedInstance&>(*this);
h & info; h & info;
h & canRefuse; h & canRefuse;
h & resetDuration; h & resetParameters;
h & onSelect; h & onSelect;
h & onVisited; h & onVisited;
h & onEmpty; h & onEmpty;