Difference between revisions of "User:Ivan/Configurable object"

From VCMI Project Wiki
Jump to: navigation, search
(Current version of JSON config: Throwing dice to make things complicated)
(Select chance (First mode))
 
(4 intermediate revisions by the same user not shown)
Line 40: Line 40:
  
 
/// Rewards that describes what can be granted and when. See below
 
/// Rewards that describes what can be granted and when. See below
"rewards" : [ { ... }, { ... } ]
+
"rewards" : { "arbitraryName1" : { ... }, "arbitraryName2" : { ... } }
 
}
 
}
  
Line 47: Line 47:
 
"message" : "You've found something!",
 
"message" : "You've found something!",
  
/// Random selection chance, only used if select mode set to "random". See below for details
+
/// Selection chance, only used if select mode set to "random" or to "first". See below for details
"selectChance" : 50,
+
"selectPriority" : 50,
  
 
/// Chances for this reward to be present in object. See below for details
 
/// Chances for this reward to be present in object. See below for details
Line 118: Line 118:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
==Randomization scheme==
 
==Randomization scheme==
===Select chance===
+
===Select chance (First mode)===
When hero visit object that have random select mode, granted reward will be selected among available rewards using this field. As result every time a hero visits this object reward received by him may be different.
+
When hero visit object with "first" selection mode, granted reward will be one with highest value of this field. If there are multiple rewards with same selection chance then reward is undefined.
 +
 
 +
===Select chance (Random mode)===
 +
When hero visit object that have random selection mode, granted reward will be selected using this field. As result every time a hero visits this object reward received by him may be different.
  
 
For example if hero visits object with 3 rewards with chances 20, 40 and 80, from which first one is not available due to limiter, hero will receive either reward #2 or (with twice bigger chance) reward #3.
 
For example if hero visits object with 3 rewards with chances 20, 40 and 80, from which first one is not available due to limiter, hero will receive either reward #2 or (with twice bigger chance) reward #3.
  
 
H3 objects that use this: Fountain of Fortune.
 
H3 objects that use this: Fountain of Fortune.
 +
 
===Appear chance===
 
===Appear chance===
 
Determines chance for this reward to appear in object during initialization (on day 1 or if "resetDuration" is negative).
 
Determines chance for this reward to appear in object during initialization (on day 1 or if "resetDuration" is negative).
Line 133: Line 137:
 
* Object B with two rewards (dice=0, min=1, max=50) and (dice=1, min=1, max=50)
 
* Object B with two rewards (dice=0, min=1, max=50) and (dice=1, min=1, max=50)
  
For Object A engine will generate one number (dice 0) and depending on its value will select either first or second reward. For Object B engine will generate two random numbers (dice 0 and dice 1) and will select rewards basesd on them. So object may have two rewards (if both dice 0 and dice 1 were below 50), one (if one of dice were below 50) or none (if all dices were above 50).
+
For Object A engine will generate one number (dice 0) and depending on its value will select either first or second reward. For Object B engine will generate two random numbers (dice 0 and dice 1) and will select rewards based on them. As result an object may have two rewards (if both dice 0 and dice 1 were below 50), one (if one of dice were below 50) or none (if both dices were above 50).
  
 
H3 objects that use this: Chest, Windmill, Tree of Knowledge, etc.
 
H3 objects that use this: Chest, Windmill, Tree of Knowledge, etc.
Line 144: Line 148:
 
* CGVisitableOPW
 
* CGVisitableOPW
 
* CGMagicSpring
 
* CGMagicSpring
= Reward limiters =
 
Requirements that must be fulfilled by visitor to receive reward
 
<syntaxhighlight lang="cpp">
 
/// how many times this reward can be granted, 0 for unlimited
 
int numOfGrants;
 
 
/// day of week, unused if 0, 1-7 will test for current day of week
 
int dayOfWeek;
 
 
/// resources player needs to have in order to trigger reward
 
TResources resources;
 
 
/// skills hero needs to have
 
std::vector<si32> primary;
 
std::map<SecondarySkill, si32> secondary;
 
 
/// artifacts that hero needs to have (equipped or in backpack) to trigger this
 
std::vector<ArtifactID> artifacts;
 
 
/// creatures that hero needs to have
 
std::vector<CStackBasicDescriptor> creatures;
 
</syntaxhighlight>
 
Note that right now limiter describes objects that visitor must have, these objects will not be removed unless removed as part of "reward" (or some other mechanism). So object that requires 1k gold for visit must check treasury via limiter and then remove gold in reward.
 
 
= Rewardables =
 
Object that visitor may receive (or lose, for negative amounts)
 
<syntaxhighlight lang="cpp">
 
/// resources that will be given to player
 
TResources resources;
 
 
/// received experience
 
ui32 gainedExp;
 
/// received levels (converted into XP during grant)
 
ui32 gainedLevels;
 
/// mana given to/taken from hero
 
si32 manaDiff;
 
/// movement points, only for current day. Bonuses should be used to grant MP on any other day
 
si32 movePoints;
 
/// list of bonuses, e.g. morale/luck
 
std::vector<Bonus> bonuses;
 
 
/// skills that hero may receive or lose
 
std::vector<si32> primary;
 
std::map<SecondarySkill, si32> secondary;
 
 
/// objects that hero may receive
 
std::vector<ArtifactID> artifacts;
 
std::vector<SpellID> spells;
 
std::vector<CStackBasicDescriptor> creatures;
 
</syntaxhighlight>
 
 
=Properties of rewardable object=
 
<syntaxhighlight lang="cpp">
 
enum ESelectMode
 
{
 
SELECT_FIRST,  // first reward that matches limiters
 
SELECT_PLAYER, // player can select from all allowed rewards
 
SELECT_RANDOM, // reward will be selected from allowed randomly
 
SELECT_ALL    // all available rewards will be granted to player
 
};
 
 
enum EVisitMode
 
{
 
VISIT_UNLIMITED, // any number of times
 
VISIT_ONCE,      // only once, first to visit get all the rewards
 
VISIT_HERO,      // every hero can visit object once
 
VISIT_PLAYER    // every player can visit object once
 
};
 
 
/// MetaString's that contain text for messages for specific situations
 
MetaString onGrant;
 
MetaString onVisited;
 
MetaString onEmpty;
 
 
/// sound that will be played alongside with *any* message
 
ui16 soundID;
 
  
/// how reward will be selected, uses ESelectMode enum
 
ui8 selectMode;
 
/// contols who can visit an object, uses EVisitMode enum
 
ui8 visitMode;
 
 
/// object visitability info will be reset each resetDuration days
 
ui16 resetDuration;
 
</syntaxhighlight>
 
Note: this does not includes some internal members - only those that may become configurable
 
 
= Not yet handled situations =
 
= Not yet handled situations =
 
* Some objects must be removed after visit
 
* Some objects must be removed after visit

Latest revision as of 16:52, 21 May 2014

This page describes work-in-progress draft of support for configurable object that should replace majority of bonusing objects

Current version of JSON config

Note: all entries are optional, unless stated othervice

{
	/// Various strings that will be displayed on visit.
	/// Can be either string or index of string in ADVOB.TXT

	/// Selection message, showed only if multiple rewards available or player can refuse
	"onSelectMessage" : "Please choose your reward",
	/// Visited message, will be displayed if object is already visited. If missing, onEmpty message will be used
	"onVisitedMessage" : "Sorry, you've already been here",
	/// This will be displayed if there are no available rewards. If missing - onVisited will be used
	"onEmptyMessage" : "You found already looted object or can not receive anything here",

	/// Hardcoded index of specific sound. TODO: allow custom sound files
	"soundID" : 123,

	/// Determines how reward will be chosen among those available to visitor
	/// first - first applicable reward will be granted
	/// player - visitor will be allowed to choose what he wants
	/// random - reward will be selected randomly
	"selectMode" : "first",

	/// Determines what makes object "visited". Possible values:
	/// unlimited - no limitations. Example: Idol of Fortune
	/// once - object can be visited only once. Example: Skeleton
	/// hero - each hero may visit object once. Example: Arena
	/// player - each player may visit once. Example: Keymaster
	"visitMode" : "unlimited",

	/// Describes how often object state will be reset. Possible values:
	/// 0 - object will never be reset
	/// positive - object visitors will be reset each N days
	/// negative - object state will be reinitialized (and all its rewards will be re-randomized)
	"resetDuration" : 0,

	/// If true, hero can refuse visiting an object (Tree or Tomb)
	"canRefuse" : false

	/// Rewards that describes what can be granted and when. See below
	"rewards" : { "arbitraryName1" : { ... }, "arbitraryName2" : { ... } }
}

{
	/// Message that will be displayed when reward is granted to hero
	"message" : "You've found something!",

	/// Selection chance, only used if select mode set to "random" or to "first". See below for details
	"selectPriority" : 50,

	/// Chances for this reward to be present in object. See below for details
	"appearChance" : { "dice" : 0, "min" : 10, "max" : 50 },

	/// Limiter. Rewards will be granted to hero only if he satisfies requirements
	/// Note: this is only a check - it won't remove anything from hero/player
	"limiter" : {
		/// how many times this reward can be granted before next reset, 0 for unlimited
		"numOfGrants" : 0, 	

		/// day of week, unused if 0, 1-7 will test for current day of week		
		"dayOfWeek" : 0,

		/// level that hero needs to have
		"minLevel" : 0,

		/// resources player needs to have in order to trigger reward
		"resources" : { "gold" : 500 },

		/// skills hero needs to have
		"primary" : { "attack" : 3 },
		"secondary" : { "diplomacy" : "basic" },

		/// artifacts that hero needs to have (equipped or in backpack) to trigger this
		/// Note: will fail when checking for multiple copies of the same art
		"artifacts" : [ "grail", "spellbook" ],

		/// creatures that hero needs to have
		"creatures" : { "angel" : 1 }
	},

	/// resources that will be given to player (or taken from)
	"resources" : { "gold" : -500 },

	/// received experience
	"gainedExp" : 1000,
	/// received levels (converted into XP during grant)
	"gainedLevels" : 1,

	/// mana given to/taken from hero, fixed value
	"manaPoints" : 10,
	/// fixed value, in form of percentage from max
	"manaPercentage" : 100,

	/// movement points, only for current day. ( base cost for moving across 1 tile is 100 points )
	"movePoints" : 1000,
	/// fixed value, in form of percentage from max
	"movePercentage" : 0,

	/// list of bonuses, e.g. morale/luck
	"bonuses" : [ { <bonus format> } ],

	/// skills that hero may receive or lose
	"primary" : { "attack" : 2 },
	"secondary" : { "diplomacy" : 1 },

	/// objects that hero may receive
	"artifacts" : [ "grail" ],
	"spells" : [ "iceBolt" ],
	"creatures" { "archer" : 10 },

	/// list of components that will be added to reward description.
	"extraComponents" : [ { "type" : "primarySkill", "subtype" : "attack", "value": 1} ],

	/// if set to true, object will be removed after granting this reward
	"removeObject" : true
}

Randomization scheme

Select chance (First mode)

When hero visit object with "first" selection mode, granted reward will be one with highest value of this field. If there are multiple rewards with same selection chance then reward is undefined.

Select chance (Random mode)

When hero visit object that have random selection mode, granted reward will be selected using this field. As result every time a hero visits this object reward received by him may be different.

For example if hero visits object with 3 rewards with chances 20, 40 and 80, from which first one is not available due to limiter, hero will receive either reward #2 or (with twice bigger chance) reward #3.

H3 objects that use this: Fountain of Fortune.

Appear chance

Determines chance for this reward to appear in object during initialization (on day 1 or if "resetDuration" is negative).

For each unique value of "dice" engine will generate a random number in range 1-100. If this value falls between "min" and "max" then this reward will be added to the object.

Examples:

  • Object A with two rewards (dice=0, min=1, max=50) and (dice=0, min=51, max=100)
  • Object B with two rewards (dice=0, min=1, max=50) and (dice=1, min=1, max=50)

For Object A engine will generate one number (dice 0) and depending on its value will select either first or second reward. For Object B engine will generate two random numbers (dice 0 and dice 1) and will select rewards based on them. As result an object may have two rewards (if both dice 0 and dice 1 were below 50), one (if one of dice were below 50) or none (if both dices were above 50).

H3 objects that use this: Chest, Windmill, Tree of Knowledge, etc.

Classes in process of replacing

  • CGPickable
  • CGBonusingObject
  • CGOnceVisitable
  • CGVisitableOPH
  • CGVisitableOPW
  • CGMagicSpring

Not yet handled situations

  • Some objects must be removed after visit
  • Some objects block movement to visitable tile (blockVisit property)
  • Different messages for different rewards (e.g. Stables)
  • Auto-upgrade for stables (or keep it hardcoded)
  • Possibility to refuse visit (e.g. Tomb)
  • Custom text describing object (xtrainfo strings)

Limitations

Known limitations of current approach, all of these are largely "works as intended", although may be changed in future if nice solution will be found.

  • As of now it is impossible to specify *ranges* of possible rewards - their values must be fixed. Situations like Windmill (3-6 of random resource) can be implemented as large list of every possible reward.
  • To properly handle cases like Tomb of Warrior and for H3-like selection of one reward from multiple (e.g. School of Magic) visitor will have to select reward based on one visible component of these rewards. This should result in behavior identical to H3 but may not work as desired for mod objects. Examples:
    • In Tomb visitor will have two "rewards": single-use "-3 morale + artifact" and multiple use "-3 morale". To hide actual reward from visitor only first component (-3 morale) will be visible in selection dialog for both cases.
    • In School of Magic player have two rewards to choice from "+1 to Spellpower and -1000 to gold" and "+1 to Knowledge and -1000 to gold". However only one component will be known to player (change to primary skill).
    • Note: AI will still be able to evaluate rewards properly based on generic object description, human player will be able to evaluate rewards only based on visit message and past experience.

Planned changes

Essential

  • Move some properties to rewards (e.g. grant message)
  • Finish rewrite of current set of objects
  • Proper support for AI

Planned

  • Extend system to support more objects:
    • Events/Pandora Boxes
    • Seer Huts/Quest Guards
    • Banks/Pyramid (at least for actual reward)

Possible

  • Extend for several related objects:
    • Keymaster/Border Guards
    • Town buildings