This is a tutorial on how to add new item types (item tags). Throughout the tutorial, I will also walk through the creation of the Box item type in the blue boxes, which was also implemented using this method.
First, let's define what a box type item is/does:
Find the config file: config/lorekeeper/item_tags.php
Add a row inside the array, in the format:
'tag_name' => [
'name' => 'Tag Name',
'text_color' => '#000000',
'background_color' => '#000000'
],
Where text_color and background_color are hexadecimal colour codes excluding the #. These colours will be used in displaying the tag label.
Replace tag_name and Tag Name as well, following those capitalisation/punctuation rules.
tag_name must be a unique key (all small letters, underscores instead of spaces), but Tag Name (any capitalisation, any formatting) does not have to be. The latter will be used in displaying tag names on user-facing pages.
Adding our box item type, which will be an orange tag label with white text.
'box' => [
'name' => 'Box',
'text_color' => '#ffffff',
'background_color' => '#f6993f'
],
This class will help us process the data and get relevant information for our form.
Create a file called [ItemTag]Service.php in app/Services/Item. The capitalisation is important!
These are the required functions:
Here is a blank template for the file:
You can also add any additional functions that you may need in order to process the data.
As we haven't started creating the form, we probably aren't entirely sure what data we'll need at this point, so we will just create app/Services/Item/BoxService.php for now and move on to the next step.
We need to create a form in the admin panel so we can edit the item data.
Go to the admin panel for the item you want to tag (your-site-url.com/admin/data/items/edit/[item_id]), and add the item tag you want to edit in the Item Tags section. Doing so should bring you to the tag settings page, but only the "Active" toggle will be visible. If you only want this tag to be cosmetic, you can stop here.
Add a new file in resources/views/admin/items/tags named [tag_name].blade.php, where [tag_name] is as you specified in the config file (no square brackets). This will contain the form HTML for our other fields.
A few other optional sections can be added to allow you to insert data into the page in various locations.
We'll add 3 files:
As they rely heavily on pre-existing code, I would recommend going through the files to see how they're set up.
These contain the code that will allow us to select assets using Javascript. The code in these files is fairly simple as I've made selectors that are easy to include.
However, for the select inputs, we need to be able to retrieve the item/currency/loot table data to fill them out, so we'll do that in BoxService:
Now that we're done with editing the item in the admin panel, let's look at how the user will see and interact with the item.
If you look at the item in your inventory (click on it to show the modal), you will see that it now displays the tag under the name. Let's add a new feature above the "Transfer Item" and "Delete Item" options.
Create a file named _[tag_name].blade.php (note the underscore in front) in resources/views/inventory. Add any additional options to the list in this file. Sample code:
<li class="list-group-item">
<a class="card-title h5 collapse-title" data-toggle="collapse" href="#customForm"> Action Name</a>
{!! Form::open(['url' => 'inventory/act/'.$stack->id.'/'.$tag->tag, 'id' => 'customForm', 'class' => 'collapse']) !!}
<!-- You can add more form fields in this space. -->
<div class="text-right">
{!! Form::submit('Action Name', ['class' => 'btn btn-primary']) !!}
</div>
{!! Form::close() !!}
</li>
Some notes:
As no other information is required in the form, we'll simply put in a note to the user that this action is irreversible. This functions as a confirmation screen for using the item.
<li class="list-group-item">
<a class="card-title h5 collapse-title" data-toggle="collapse" href="#openBoxForm"> Open Box</a>
{!! Form::open(['url' => 'inventory/act/'.$stack->id.'/'.$tag->tag, 'id' => 'openBoxForm', 'class' => 'collapse']) !!}
<p>This action is not reversible. Are you sure you want to open this box?</p>
<div class="text-right">
{!! Form::submit('Open', ['class' => 'btn btn-primary']) !!}
</div>
{!! Form::close() !!}
</li>
We now need to write the back-end code for handling what happens when you use the item.
Back in [ItemName]Service.php from step 3, one of the functions we created was act($stack, $user, $data). Inside that function, if you have only one possible action, you can directly write the handling code. If you have multiple possible actions, you can write a switch/case statement that checks $data and calls a different function depending on the intended usage.
Note that $stack refers to the user-held item stack, while $stack->item refers to the actual item data itself.
We don't want any other user except for the owner to open a box, so the first thing we do is check that the box belongs to the owner. Following that, we remove the box and distribute the associated rewards (with logging).
public function act($stack, $user, $data)
{
DB::beginTransaction();
try {
// We don't want to let anyone who isn't the owner of the box open it,
// so do some validation...
if($stack->user_id != $user->id) throw new \Exception("This item does not belong to you.");
// Next, try to delete the box item. If successful, we can start distributing rewards.
if((new InventoryManager)->debitStack($stack->user, 'Box Opened', ['data' => ''], $stack)) {
// Distribute user rewards
if(!$rewards = fillUserAssets(parseAssetData($stack->item->tag('box')->data), $user, $user, 'Box Rewards', [
'data' => 'Received rewards from opening <a href="#" class="inventory-log-stack" data-id="'.$stack->id.'" data-name="'.$stack->item->name.'">'.$stack->item->name.'</a>'
])) throw new \Exception("Failed to open box.");
}
return $this->commitReturn(true);
} catch(\Exception $e) {
$this->setError('error', $e->getMessage());
}
return $this->rollbackReturn(false);
}
The whole process consists of 5 steps: