Pcontent
Parameterized content (or pcontent for short) is the mechanism that allows Dungeon Siege to provide a huge range of armor and weapon types from a relatively small set of templates. Each basic item can have its attributes (damage, defense, magical enhancements, etc) determined by a random choice within ranges that the template or skrit specifies.
Where do I define pcontent?
Note: This is the DS2 answer, DS1 has some differences.
Each item template contains two main sources. In the [common]
block
an item can be isolated from the pcontent system by setting
is_pcontent_allowed = false
, and if you don't do that, you
can have a [pcontent]
block that determines an item_level. This block can
define variants of the item that may be selected to further alter the item
level. In the example you can see the item_level
being used
to set the character requirements to equip the item.
[t:template,n:dg_1h_dg] { specializes = base_dagger_template; doc = "dagger"; [aspect] { . . . } [pcontent] { [base] { equip_requirements = uber:#item_level - 2.0, melee:#item_level - 2.0; item_level = 0.0; } [var1] { equip_requirements = uber:#item_level - 2.0, melee:#item_level - 4.0; item_level = 11.0; } . . . } } //Used in the Taar Secondary Quest [t:template,n:dg_1h_dg_unq_haku_quest] { specializes = base_dagger_template; doc = "dg_1h_dg_unq_haku_quest"; [aspect] { model = m_w_dag_haku; tracer_texture = b_sfx_tra_generic-20; } [attack] { damage_min = 2; damage_max = 5; } [common] { allow_modifiers = false; is_pcontent_allowed = false; screen_name = "Hak'u Ceremonial Blade"; base_screen_name = "Hak'u Ceremonial Blade"; rarity = unique; } ... }
item_level
is used in the _base templates to set such things
as the defense value for armor, and the max/min damage for weapons.
[attack] { attack_class = ac_sword; damage_min = 0.75 * (3.4 + 0.74 * #item_level); damage_max = 1.25 * (3.4 + 0.74 * #item_level); is_melee = true; reload_delay = 0.67; skill_class = melee; }
Pcontent actually goes one step further and allows the type of item to be randomly generated. This is typically used in drops from monsters and containers. Which brings us to...
How is pcontent used?
The easiest place to see pcontent use is in vendors' stores. If you look in the stores.gas file of any DS2 map, you will see examples of generating items for sale.
[act_1_weapon_store] { [melee] { [all*] { il_main = #dg_1h_dg:base; count = 1; world_specific = mercenary; } [all*] { il_main = #hm_1h_hm:base; count = 1; world_specific = mercenary; } [all*] { il_main = #st_mg_rs:base; count = 1; world_specific = mercenary; } // other stuff [all*] { il_main = #melee; count = 16; } [all*] { il_main = #melee/3-8; count = 8; world_specific = mercenary; } . . .
If we analyze the individual entries, we can learn a lot about how pcontent can be used. There are useful comments in some stores, too!
First thing to note is that an entry in a store's inventory can be either the name of a specific template, or a generic (i.e. pcontent) request. The latter have an initial "#' character. This tells the engine to select from the content database, items that match the specification given.
The next part can be a template name, or a macro that includes multiple templates at once. These can be followed by modifers that control the selection.
An entry of the form #templatename:xxxx
selects the "xxxx"
variant from the [pcontent]
block. In the example, the
base variants are explicitly requested. This is the first
weapon vendor you reach, and this ensures that you can buy at least some
weapons you can actually use! The rest of the melee weapons page is filled
with generic requests for any melee weapons, and some slots are also set
aside for a range of item levels using the format #macro/range
.
When the macros are used, a piece of skrit code comes in to play to choose the items, and their magical modifiers. Take a look at pcontent.skrit to see how the proportions of item types are determined. You may want to change the relative chances of swords versus axes or hammers, and this is the place to do that.
Another place that pcontent is used is in drops. Here the engine needs
to be able to select unique and rare items that the stores don't carry.
Take a look in the files in world/contentdb/pcontent/macros.
Here you will find item specifications like #/-rare
, which
has no template or macro name specified at all, and so it
means "any type of rare item", but there are additional lines of code that
set limits such as pcontent_min_level
or
pcontent_max_modifier
as well.
from a quest drop macro - item_level was calculated earlier: . . . [all*] // 4% Chance to drop a rare item { chance = 0.04 * (1 + (#magic_find * .01)); il_main = #/-rare; pcontent_min_level = #item_level - 5; pcontent_max_level = #item_level; pcontent_min_modifier = #item_level - 25; pcontent_max_modifier = #item_level + 5; } . . . [a1_pq3_dryad_outpost_celia] { [all*] { player_drop_type = all; il_main = #amr_hlm_dryad; il_main = #amr_glv_dryad; il_main = #amr_bot_dryad; il_main = #st_mg_rs:base; // restricted to base variant il_main = spell_jolt_1; // explicit template - no pcontent il_main = scroll_resurrect; il_main = #potion_health_small; // pcontent! il_main = #potion_mana_small; } } [a1_sq_armorer_apprentice_correct_lowlevel] { [all*] { player_drop_type = all; il_main = #amr_bdy_dryad/+ofsturdiness/+stable; } }
The last example shows explicit modifiers being attached. I'm not certain why potions are defined with pcontent - maybe the intent was that the bottle would not always be full?
Testing pcontent
If you just made a new weapon and you want to check out the pcontent attached to it, you can run DS(2/LOA)MOD and give it to a character. Even if they can't use it, it will appear in their inventory for you to check the modifiers and damage levels. When you use pcontent this way, you can specify the modifiers and variants, but the levels don't seem to work.