Shop: Difference between revisions

From The DarkMod Wiki
Jump to navigationJump to search
Thebigh (talk | contribs)
→‎Items for Sale: -add section for adding a map
 
(15 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{todo}} <!-- needs cleanign up talking about code changes and turn this into a proper step-by-step tutorial from the mappers point of view -->
''originally posted by joebarnin''
Click here for a [[default purchasable items]] template.
Click here for a [[default purchasable items]] template.


Line 8: Line 5:
  "shop_skip"  "1"
  "shop_skip"  "1"


==Notes==
== The Shop Entity ==
To define the available items in the shop of your map place an atdm:shop entity somewhere (a blue room maybe).
 
Once added to the map, you can define the shop items and starting equipment by adding spawnargs to this entity.
 
=== Notes ===
* It's possible to add multiple shop entities to your map, it might be convenient to have a separate shop entity for each difficulty level, in the end it's a matter of taste.
* It's also possible to define these spawnargs on the worldspawn entity - this was the original method (way back in about 2007/2008). It's still supported but I'd rather not do it that way.
 
== Starting Equipment ==
The spawnarg syntax to add starting equipment goes like this:
"startingItem_N_D_item"    "CLASSNAME"
"startingItem_N_D_qty"      "QUANTITY"
 
The number N is an index to separate the various starting items. The number D refers to the difficulty level this spawnarg is applying to (0, 1 or 2). the CLASSNAME is something like '''atdm:playertools_breath_potion''' and will point the shop to the item entityDef '''ShopItem_playertools_breath_potion'''.
 
The second key/value pair is the quantity of that item the player is given at map start.
 
=== Optional Spawnargs ===
It's possible to prevent the player from dropping a starting equipment item in the Shop by adding a spawnarg like this:
"startingItem_N_D_candrop"  "0"
By default all items are droppable, so set that argument to "0" to prevent that, for use with mission-critical items (like lockpicks) so full start equipment can be shown in the shop without risk the player will drop something crucial.


I added code support for shop entities to be placed the map, like difficulty settings or objectives entities.
=== Examples ===
"startingItem_1_item"      "atdm:weapon_broadsword"
"startingItem_1_qty"      "1"
"startingItem_2_item"      "atdm:weapon_blackjack"
"startingItem_2_qty"      "1"
"startingItem_3_item"      "atdm:playertools_health_potion"  // remove the spaces around the colon
"startingItem_3_0_qty"    "2"
"startingItem_3_1_qty"    "1"
"startingItem_3_2_qty"    "0"
"startingItem_3_2_candrop" "0"      // not droppable


- The entity is called atdm:shop.
=== Starting Equipment placed in the Map ===
- The spawnarg format is the same as for the worldspawn.
Many mappers follow the practice of placing the player's starting equipment in the map and set the "inv_map_start" spawnarg to "1" on them. This is ok of course, and the shop code will try to find these entities in the map and adds them to the list of starting equipment when displaying the shop. If an item placed in the map is not showing up in the starting equipment list, it's probably a custom item which doesn't have a  corresponding ShopItem_YYY entityDef (the shop needs such an entity to display the description and display the equipment images).
- Settings on Worldspawn are still supported, for "backwards" compatibility.
- Multiple atdm:shop entities can be added to the map, all of them are considered.


Additionally, I refactored the shop parsing code, so that a "gap" in the spawnarg numbering doesn't stop the parser. For instance, it's now possible to do something like this:
== Items for Sale==
The spawnarg syntax for shop items for sale goes like this:


  "shopItem_1_0_item" "atdm:weapon_broadhead"
  "shopItem_N_D_item" "ITEMCLASSNAME"   // which item
  "shopItem_1_0_qty" "10"
  "shopItem_N_D_qty"   "QUANTITY"         // amount for sale
"shopItem_3_0_item" "atdm:weapon_waterarrow"
 
"shopItem_3_0_qty" "10"
N refers is just an index to enumerate the various shop items. The number D is defining the difficulty level this shop item applies to (which can be 0, 1 or 2, with 0 being the lowest level "Easy"). The value ITEMCLASSNAME is usually a classname, which is referring to the shop item definition in tdm_shopitems.def, e.g. the value '''atdm:weapon_broadhead''' would be pointing to the shop item entityDef '''ShopItem_weapon_broadhead'''. The second key/value pair defines the amount of items that are for sale, e.g. "10".


Note the missing "2" in the indexing. The parser just continues, which should make prefabbing easier and set up more robust against user errors.
=== Optional Spawnargs ===
It's possible to override the cost of an item for sale, add this key/value pair to your shop entity:
"shopItem_N_D_price"  "PRICE"
Placing such a spawnarg will override the price of the item found on the ShopItem_YYY entityDef.


==Setting up the Shop==
There's another spawnarg affecting the item's persistency:
"shopItem_N_D_persistent"  "1"
Use that for items that are acquirable only in the shop, not while playing the mission. Otherwise I'd recommend setting the "inv_persistent" spawnarg on the inventory items in the map itself.


Add an atdm:shop entity to your map (probably in the "blue room").  You can add the following lines in the editor, but it might be easier to load up your map file in a text editor, find the adtm:shop entity, and cut and paste.
=== Map ===


"shop_gold_start" "700"
It is possible to have a map of the level for sale in the shop. Set up the image and inventory icon as you would for a map that starts in your inventory. Now place "shopItem_N_D" "atdm:map_of" spawnargs on the shop entity just as you did for all the other purchasable equipment. Override the price too if you like.
"shopItem_1_item" "atdm:playertools_flashbomb"
"shopItem_1_qty" "5"
"shopItem_2_item" "atdm:weapon_waterarrow"
"shopItem_2_0_qty" "5"
"shopItem_2_1_qty" "3"
"shopItem_2_2_qty" "1"
"shopItem_2_cost" "225"
"startingItem_1_item" "atdm:weapon_broadsword"
"startingItem_1_qty" "1"
"startingItem_2_item" "atdm:weapon_blackjack"
"startingItem_2_qty" "1"
"startingItem_3_item" "atdm : playertools_health_potion" (remove the spaces around the colon)
"startingItem_3_0_qty" "2"
"startingItem_3_1_qty" "1"
"startingItem_3_2_qty" "0"


_# : item number, starting from 1. No gaps.
If you run the mission now you will be able to buy the map and it'll work properly in your inventory but the in-game shop name, description, and graphic will be broken. To fix this, edit your mymapname/def/custom.def file (or create it if you don't already have one) and add the following:
_#_X: X is the skill (difficulty) level this value applies to. So in the above example, the shop contains 5 water arrows at
easy, 3 at medium, 1 at hard (difficulty goes from 0 (easy) to 2 (hard)). If you leave off a skill, quantity zero is assumed
(e.g., if there was no "shopItem_2_2_qty", then there would be zero arrows for sale at hard level). Note you can have cost
vary by difficulty as well. And starting item quantities too.
_item: the "classname" listed in the entitydef (see tdm_shopitems.def).
_qty: how many are for sale (or, if a starting item, how many to start with)
_cost field is optional (otherwise it uses the default cost defined in tdm shopitems.def).


Okay, now you've updated your map with something like this, so get back to the Shop and buy what you want. Start the mission. You should have the appropriate number of items.
    entityDef ShopItem_map_of
    {
        "inherit"          "atdm:shopitem_base"
        "itemClassname"    "atdm:map_of"
        "displayName"      "Map"
        "displayDesc"      "Your pal Sam can get you a map of Sebastian Creep's hovel... for a price."
        "image"            "guis/assets/game_maps/map_shop_icon"
    }


tdm-shopitems.def defines the list of the common items that can be purchased (or that can be in the Starting Items list). This file documents the format of ShopItem entityDefs, so if you want to add unique items to your own .def file, you can.
Create a map_shop_icon graphic file in the correct directory, or optionally comment this line out to omit the in-store icon entirely.


shop.cpp and shop.h are new files that define CShop and CShopItems, classes for dealing with the Shop screen.
== On Numbering ==
Unlike many other setup entities, you don't have to use a sequential numbering on atdm:shop. The code is able to handle gaps in the sequences, so you don't have to renumber everything each time you remove a shop item. For instance, it's now possible to do something like this:


player.cpp was updated to create the purchased items
"shopItem_1_0_item" "atdm:weapon_broadhead"
"shopItem_1_0_qty" "10"
"shopItem_3_0_item" "atdm:weapon_waterarrow"
"shopItem_3_0_qty" "10"


game_local.cpp was modified to handle the Main Menu commands. This was the only way I could figure out to have the shop talk to our code. Apparently the id code behaves differently when your in the main menu.
Note the missing "2" in the indexing. The parser just continues, which should make prefabbing easier and set up more robust against user errors.


==Preventing the player dropping critical items==
== Shop Budget ==
Use the spawnarg
"shop_gold_start"    "700"
to define how much gold the player can spend in the shop. Authors of multi-mission projects might want to look further down this page on controlling the player's budget with regard to their collected loot.


There is a cannot drop' option for start items, eg, a spawnarg, "startingitem_15_2_candrop" "0". For use with mission-critical items (like lockpicks) so full start equipment can be shown in the shop without risk the player will drop something crucial.
The above spawnarg applies to all difficulty levels, unless it's overridden by one or more of the spawnargs below:
"diff_0_shop_gold_start"  "600"
"diff_1_shop_gold_start"  "400"
"diff_2_shop_gold_start"   "200"
The number 0 in diff_0_shop_gold_start will refer to the easiest difficulty setting, e.g. "Easy".


== Limit the Loot from previous Missions ==
== Limiting the Loot from previous Missions ==
This section is applicable to campaigns or multi-mission setups: the mapper can define how much loot collected in Mission 1 will be usable in the shop before Mission 2. It's possible to define "conversion rates" for the various loot types (e.g. "10 goods are worth 1 gold"), absolute and relative gold losses as well as minimum and maximum values.
This section is applicable to campaigns or multi-mission setups: the mapper can define how much loot collected in Mission 1 will be usable in the shop before Mission 2. It's possible to define "conversion rates" for the various loot types (e.g. "10 goods are worth 1 gold"), absolute and relative gold losses as well as minimum and maximum values.


Line 85: Line 112:
After the loot type conversion the gold loss is applied, which can be specified in percent or absolute (even both if that makes sense for your setup). If both are specified, the percentile loss is applied first.
After the loot type conversion the gold loss is applied, which can be specified in percent or absolute (even both if that makes sense for your setup). If both are specified, the percentile loss is applied first.


TODO
"gold_loss_percent"  "20"    // 20% gold will be deducted
"gold_loss"          "200"  // 200 gold will be subtracted in any case
 
The default value for both loss spawnargs is "0", i.e. no loss.
 
=== Shop Starting Gold ===
After applying the loss, the starting gold defined on the atdm:shop entity (see above) is added.
 
=== Gold Cap ===
After applying the shop starting gold, the maximum gold value will be enforced (if defined):
"gold_cap"            "350"  // no more than 350 gold in any case
 
The default gold cap value is "-1" which means "no cap".
 
=== Minimum Gold ===
As final step (to ensure that the player has at least a minimum amount of gold to purchase the bare minimum equipment) the minimum gold value is ensured. It is applied if the above rules made the player's budget fall below that value.
"gold_min"            "50"    // at least 50 gold


The default value for "gold_min" is "0", so the player can never enter the shop with a negative amount of gold.


{{tutorial-scripting}}
{{editing}}
[[Category:Campaigns]]

Latest revision as of 22:00, 18 February 2022

Click here for a default purchasable items template.

How to NOT show the shop

The shop shows by default at mission start. If you don't want it then add this spawnarg and value to your map's worldspawn:

"shop_skip"   "1"

The Shop Entity

To define the available items in the shop of your map place an atdm:shop entity somewhere (a blue room maybe).

Once added to the map, you can define the shop items and starting equipment by adding spawnargs to this entity.

Notes

  • It's possible to add multiple shop entities to your map, it might be convenient to have a separate shop entity for each difficulty level, in the end it's a matter of taste.
  • It's also possible to define these spawnargs on the worldspawn entity - this was the original method (way back in about 2007/2008). It's still supported but I'd rather not do it that way.

Starting Equipment

The spawnarg syntax to add starting equipment goes like this:

"startingItem_N_D_item"     "CLASSNAME"
"startingItem_N_D_qty"      "QUANTITY"

The number N is an index to separate the various starting items. The number D refers to the difficulty level this spawnarg is applying to (0, 1 or 2). the CLASSNAME is something like atdm:playertools_breath_potion and will point the shop to the item entityDef ShopItem_playertools_breath_potion.

The second key/value pair is the quantity of that item the player is given at map start.

Optional Spawnargs

It's possible to prevent the player from dropping a starting equipment item in the Shop by adding a spawnarg like this:

"startingItem_N_D_candrop"  "0"

By default all items are droppable, so set that argument to "0" to prevent that, for use with mission-critical items (like lockpicks) so full start equipment can be shown in the shop without risk the player will drop something crucial.

Examples

"startingItem_1_item"      "atdm:weapon_broadsword"
"startingItem_1_qty"       "1"
"startingItem_2_item"      "atdm:weapon_blackjack"
"startingItem_2_qty"       "1"
"startingItem_3_item"      "atdm:playertools_health_potion"  // remove the spaces around the colon
"startingItem_3_0_qty"     "2"
"startingItem_3_1_qty"     "1"
"startingItem_3_2_qty"     "0"
"startingItem_3_2_candrop" "0"       // not droppable

Starting Equipment placed in the Map

Many mappers follow the practice of placing the player's starting equipment in the map and set the "inv_map_start" spawnarg to "1" on them. This is ok of course, and the shop code will try to find these entities in the map and adds them to the list of starting equipment when displaying the shop. If an item placed in the map is not showing up in the starting equipment list, it's probably a custom item which doesn't have a corresponding ShopItem_YYY entityDef (the shop needs such an entity to display the description and display the equipment images).

Items for Sale

The spawnarg syntax for shop items for sale goes like this:

"shopItem_N_D_item"  "ITEMCLASSNAME"    // which item
"shopItem_N_D_qty"   "QUANTITY"         // amount for sale

N refers is just an index to enumerate the various shop items. The number D is defining the difficulty level this shop item applies to (which can be 0, 1 or 2, with 0 being the lowest level "Easy"). The value ITEMCLASSNAME is usually a classname, which is referring to the shop item definition in tdm_shopitems.def, e.g. the value atdm:weapon_broadhead would be pointing to the shop item entityDef ShopItem_weapon_broadhead. The second key/value pair defines the amount of items that are for sale, e.g. "10".

Optional Spawnargs

It's possible to override the cost of an item for sale, add this key/value pair to your shop entity:

"shopItem_N_D_price"   "PRICE"

Placing such a spawnarg will override the price of the item found on the ShopItem_YYY entityDef.

There's another spawnarg affecting the item's persistency:

"shopItem_N_D_persistent"   "1"

Use that for items that are acquirable only in the shop, not while playing the mission. Otherwise I'd recommend setting the "inv_persistent" spawnarg on the inventory items in the map itself.

Map

It is possible to have a map of the level for sale in the shop. Set up the image and inventory icon as you would for a map that starts in your inventory. Now place "shopItem_N_D" "atdm:map_of" spawnargs on the shop entity just as you did for all the other purchasable equipment. Override the price too if you like.

If you run the mission now you will be able to buy the map and it'll work properly in your inventory but the in-game shop name, description, and graphic will be broken. To fix this, edit your mymapname/def/custom.def file (or create it if you don't already have one) and add the following:

   entityDef ShopItem_map_of
   {
       "inherit"           "atdm:shopitem_base"
       "itemClassname"     "atdm:map_of"
       "displayName"       "Map"
       "displayDesc"       "Your pal Sam can get you a map of Sebastian Creep's hovel... for a price."
       "image"             "guis/assets/game_maps/map_shop_icon"
   }

Create a map_shop_icon graphic file in the correct directory, or optionally comment this line out to omit the in-store icon entirely.

On Numbering

Unlike many other setup entities, you don't have to use a sequential numbering on atdm:shop. The code is able to handle gaps in the sequences, so you don't have to renumber everything each time you remove a shop item. For instance, it's now possible to do something like this:

"shopItem_1_0_item" "atdm:weapon_broadhead"
"shopItem_1_0_qty" "10"
"shopItem_3_0_item" "atdm:weapon_waterarrow"
"shopItem_3_0_qty" "10"

Note the missing "2" in the indexing. The parser just continues, which should make prefabbing easier and set up more robust against user errors.

Shop Budget

Use the spawnarg

"shop_gold_start"    "700"

to define how much gold the player can spend in the shop. Authors of multi-mission projects might want to look further down this page on controlling the player's budget with regard to their collected loot.

The above spawnarg applies to all difficulty levels, unless it's overridden by one or more of the spawnargs below:

"diff_0_shop_gold_start"   "600"
"diff_1_shop_gold_start"   "400"
"diff_2_shop_gold_start"   "200"

The number 0 in diff_0_shop_gold_start will refer to the easiest difficulty setting, e.g. "Easy".

Limiting the Loot from previous Missions

This section is applicable to campaigns or multi-mission setups: the mapper can define how much loot collected in Mission 1 will be usable in the shop before Mission 2. It's possible to define "conversion rates" for the various loot types (e.g. "10 goods are worth 1 gold"), absolute and relative gold losses as well as minimum and maximum values.

The following rules are applied in the specified order.

Conversion Rates

Since the shop doesn't care about goods, jewels or gold, each collected loot type will be converted into a gold value before proceeding. The conversion rates are numeric factors the collected value will be multiplied with to calculate the value in gold. The default conversion rates are defining a 1:1 exchange rate: 1 of each loot type will be worth 1 gold.

"loot_convrate_gold"    "1.0"   // 1:1 conversion rate for gold
"loot_convrate_jewels"  "0.5"   // 2 jewels are worth 1 gold
"loot_convrate_goods"   "0.2"   // 5 goods are worth 1 gold

The shop will only accept full rounded integer numbers, so if any conversion rate will produce decimals the number will be rounded towards the nearest lower integer number (they're "floor"ed).

Gold Loss

After the loot type conversion the gold loss is applied, which can be specified in percent or absolute (even both if that makes sense for your setup). If both are specified, the percentile loss is applied first.

"gold_loss_percent"   "20"    // 20% gold will be deducted
"gold_loss"           "200"   // 200 gold will be subtracted in any case

The default value for both loss spawnargs is "0", i.e. no loss.

Shop Starting Gold

After applying the loss, the starting gold defined on the atdm:shop entity (see above) is added.

Gold Cap

After applying the shop starting gold, the maximum gold value will be enforced (if defined):

"gold_cap"            "350"   // no more than 350 gold in any case

The default gold cap value is "-1" which means "no cap".

Minimum Gold

As final step (to ensure that the player has at least a minimum amount of gold to purchase the bare minimum equipment) the minimum gold value is ensured. It is applied if the above rules made the player's budget fall below that value.

"gold_min"            "50"    // at least 50 gold

The default value for "gold_min" is "0", so the player can never enter the shop with a negative amount of gold.