Custom shop

From Heroes of Hammerwatch wiki
Jump to: navigation, search

You can make custom shops using the ShopArea worldscript. Using that worldscript, you can select the level of the shop. Depending on the situation however, it might be more appropriate to use an OpenInterface worldscript instead, in the case you need both a custom GUI and you have no desire to have a shop level associated with it.

There are 2 types of custom shops you can make using the ShopArea worldscript:

1. A regular upgrade shop. This is what most upgrade shops in the town are using, such as the blacksmith. 2. A custom shop with a custom GUI frame.

Upgrade shop

The basic upgrade shops use a ShopArea worldscript with the type set to UpgradeShop. These shops use sval files to load "upgrades", which in turn load "upgrade steps", which can be owned, or be a one-off purchase. For example, let's take a look at how the blacksmith works in tweak/shops/blacksmith.sval:

	<string name="class">Upgrades::UpgradeShop</string>

	<string name="id">blacksmith</string>
	<string name="name">.shop.blacksmith</string>

	<array name="upgrades">

You can see that the sval file is using a loader function Upgrades::LoadShop. This will load the shop definition so that it can be used as a category in the ShopArea worldscript. The class is the basic UpgradeShop class, which simply provides a list of upgrades. The ID is set to blacksmith, which is what the "category" property must be set to in the ShopArea worldscript. The name is what is shown at the top of the UI.


Then we have a list of upgrades. Upgrades, by definition, are upgrades you can buy that can be owned by a player. But this doesn't necessarily mean they have to be owned, as key or item purchases for example are not actually owned upgrades, they're one-off upgrades that perform some temporary action on the player, such as giving a key, or giving an item. Keys and items are not permanent, they disappear after you die in a dungeon, so they're not remembered as being "owned" in your character.

Upgrades have upgrade "steps", which are basically the "levels" of the upgrades. If you buy an upgrade level 1, you own the first step in the upgrade, if you buy an upgrade level 2, you own the second step (but not the first), etc.

There's a number of upgrade classes built-in to the game:

  • ModifierUpgrade
    • ChapelUpgrade
  • BuildingUpgrade
  • KeyUpgrade
  • OreTraderUpgrade
  • RecordUpgrade
  • SingleStepUpgrade
    • DesertMapUpgrade
    • ItemUpgrade

For now, we're only going to take a look at ModifierUpgrade as its the most straight forward one.

Defining the upgrade

Let's take another look at the Blacksmith shop. You can see that the first upgrade in the list is the armor upgrade for tier 1:

	<string name="class">Upgrades::ModifierUpgrade</string>
	<string name="id">armor</string>
	<array name="icon">
		<string>gui/icons_others.png</string><int>100</int><vec4>24 48 24 24</vec4>
	<array name="steps">
			<int name="cost-gold">250</int>

			<string name="name"></string>
			<string name="desc">.shop.blacksmith.armor-1.desc</string>

			<dict name="modifier">
				<string name="class">Modifiers::Armor</string>
				<int name="armor">5</int>

Here, the class is defined as Upgrades::ModifierUpgrade, which lets you create an owned upgrade with a modifier that's applied on the player at all times. The tier is not shown in the example above, but for upgrade steps that requires a certain tier, you can add this line to the step dictionary:

<int name="restrict-shop-level-min">2</int>

Custom shop

To make a completely custom shop, you have to use the "Custom" shop type in the ShopArea worldscript. With that shop type, the "Category" property acts as the name of a class to instantiate that will be the frame of the shop menu. This class needs to inherit from ShopMenuContent, and then override string GetGuiFilename() to specify the gui file to use as the shop frame.

So, for example, to make a shop with a custom UI, you define your class like this:

class MyShopMenu : ShopMenuContent
	MyShopMenu(UnitPtr unit, SValue& params)

	string GetGuiFilename() override
		return "gui/shop/myshop.gui";