Creating a custom Pointshop 2 Item: Part 2 - Creating an item base

In part two you will learn how to create a custom item base. The item base will allow you to customize
the icon of your items and create multiple gravity items that share common functionality in a base file.

For this purpose we create:

  • An item base that defines the item behaviour and the icon
  • A few item classes that use the base and can be bought separately in the shop

NOTE: This tutorial is the second part of a tutorial series to create a full blown pointshop 2 item creator.
In step 1 a simple item class and slot were created. Part 1, Part 2, Part 3

Prerequisites

You will need the code of part one of this tutorial: Download Part 1 Source

Step 1: Creating the item base

When we want to create a few items that do the same thing but a bit differently we would have to duplicate a lot of code if we use the approach from part one. Say you want to have two different items: A standard low gravity item that makes players jump twice as high and a premium low gravity items that makes VIPs jump four times as high. These items behave the same except for a different jump height multiplier (2x for the normal item, 4x for the VIP item).

To solve this problem you can create an item base. Create the file addons/ps2-lowgravity/lua/kinv/items/pointshop/sh_base_low_gravity.lua

sh_base_low_gravity.lua

ITEM.baseClass    = "base_pointshop_item"
ITEM.multiplier = 2

function ITEM:PlayerSpawn( ply )
    if ply != self:GetOwner() then
        return
    end

    local oldJumpPower = ply:GetJumpPower( )
    timer.Simple( 0.5, function ( ) 
        ply:SetJumpPower( oldJumpPower * self.multiplier )
    end )
end
Pointshop2.AddItemHook( "PlayerSpawn", ITEM )

We define a basic multiplier here that we will overwrite using our items in the next step.

Step 2: Create the item classes

Next we create two item classes: One for our VIP item (addons/ps2-lowgravity/lua/kinv/items/pointshop/sh_low_gravity_vip.lua), the other for our standard item (replace the contents here addons/ps2-lowgravity/lua/kinv/items/pointshop/sh_low_gravity.lua):

sh_low_gravity.lua
ITEM.baseClass    = "base_low_gravity"
ITEM.PrintName    = "Low Gravity"
ITEM.Description = "Equip this to get 2x Jump Power!"
ITEM.static.Price = {
    points = 100
}

-- Standard: Set the multiplier to 2
ITEM.multiplier = 2
sh_low_gravity_vip.lua
ITEM.baseClass    = "base_low_gravity"
ITEM.PrintName    = "VIP Low Gravity"
ITEM.Description = "Equip this to get 4x Jump Power!"
ITEM.static.Price = {
    premiumPoints = 100
}

-- VIP: We set the multiplier to 4
ITEM.multiplier = 4

Properties defined in item classes will always override the properties of the item base that it uses. Properties like PrintName or Price are defined in base_pointshop_item. This way we build an “inheritance chain”, our class inherits properties from the low gravity base, which inherits from the pointshop2 item base.

Step2

Change the map and open the shop, you now have two items in uncategorized:
Step2

Step 3: Updating the slot code

In step 1 we created a slot that accepts the low gravity item. If you try to equip the VIP gravity item you’ll see that the slot does not accept it.

Since now we can create as many low gravity items as needed we need to update the slot code to check for the item base. This is easy, change addons/ps2-lowgravity/lua/ps2/modules/lowgravity/sh_slot.lua:

sh_slot.lua
Pointshop2.AddEquipmentSlot( "Gravity", function( item )
    --Check if the item is a low_gravity item
    return instanceOf( Pointshop2.GetItemClassByName( "base_low_gravity" ), item )
end )

Now the code checks if the item is an instance of the base. The inheritance chain of the VIP item looks like this: VIP Item -> Low Gravity Base -> Pointshop Item Base. The code above checks if the Low Gravity Base is present in any place of the chain.

NOTE: If we would check for base_pointshop_item it would be possible to put every item in the shop into the slot.

Step 4: Using a material icon

The item of our new item isn’t very pretty yet. In the item base you can change the icon of an item, similarly to how you can change name and price. We overwrite three functions:

  • GetPointshopIconControl(): Determines the icon of an item in the shop
  • GetPointshopLowendIconControl(): Determines the icon of an item in the shop, if the user has lowend mode enabled
  • GetPointshopIconDimensions(): Dermines the size of an item icon in the shop
  • getIcon(): Determines the icon of the shop in the user’s inventory
sh_base_low_gravity.lua
ITEM.material = "pointshop2/winner2.png"

-- Returns a Derma Control Name used to create the shop icon in normal mode
function ITEM.static:GetPointshopIconControl( )
    return "DPointshopMaterialIcon"
end

-- Returns a Derma Control Name used to create the shop icon in lowend mode
function ITEM.static:GetPointshopLowendIconControl( )
    return "DPointshopMaterialIcon"
end

-- Returns a derma icon that ised in the inventory
function ITEM:getIcon( )
    self.icon = vgui.Create( "DPointshopMaterialInvIcon" )
    self.icon:SetItem( self )
    return self.icon
end

-- Returns a 4x4 dimensioned icon
function ITEM.static.GetPointshopIconDimensions( )
    -- GenerateIconSize multiplies the numbers by a constant factor
    return Pointshop2.GenerateIconSize( 4, 4 )
end

Here we use the Material icon that comes with Pointshop2. This icon type looks at the material property of the class and centers that material inside of the item icon. “DPointshopMaterialIcon” is a Derma Control (Derma Controls are things like DButton or DPanel. You can make your own using vgui.Register).

As we have not added any new files we can use the hot reload feature of gmod to reload our changes. Pointshop 2 supports reloading the entire shop (and all items) using a console command: pointshop2_reload. This works in debug mode and is superadmin only. After entering this command in console we can see the new item icons:

Step2

NOTE: You may notice the mixed use of ITEM and ITEM.static. Static properties generally belong to a Class, whereas normal properties belong to an instance of the class. Generally in the shop we use static properties for anything belonging to an item class (which is what you see in the shop) and normal properties for anything that belongs to an item instance (an item in a user’s inventory). Instance properties can also be accessed statically. Static properties cannot be overwritten by instances.



Browse Code


View all changes


Download full source