Updated How To Create a Custom Vendor (markdown)

This commit is contained in:
Cekis
2022-02-02 22:03:54 -08:00
parent 3bc3bfb8d2
commit 87df8a3233

View File

@@ -1,195 +1,493 @@
**_(submitted by HeronOfAlexandria)_**
# Overview
# Revision
Version 1.0 of the Guide to Creating Vendors.
# Introduction
This guide provides instructions for creating and stocking server vendors. These
instructions include the templates, strings, and tables containing the stock,
payment methods, and making an event to turn the vendors on and off.
In this example, we will be creating three vendors and a gift box, the latter
being a generic container that can hold simple items. The first vendor will sell
boxes of marauder tokens for cash, the second sells chronicler tokens in
exchange for marauder tokens, and the third sells heroic tokens in exchange for
chronicler tokens. This approach intends to demonstrate the payment methods,
which will become clear as you read this guide.
I provide a working example in my fork (HeronAlexandria · GitHub), and while I
have performed basic testing, I cannot guarantee that the example is bug-free.
Use my examples at your own risk, and remember, snapshot your VM before
beginning!
You will need Sitners, but we will not be building tre files. I will show you
how to place files in the client directory, so constructing a tre file is
unnecessary, making development much easier. Programming is required, but it is
all in Java, and for the most part, you will be able to use what others have
written and make some simple changes.
There are two commits for this guide. The first is [Vendor Demonstration ·
HeronAlexandria/dsrc@aa06fbf ·
GitHub](https://github.com/HeronAlexandria/dsrc/commit/aa06fbf460ea5c3b0963f4699ede6e1079552335),
which contains the code for the vendors and the gift box. The second is [Fixes
to vendor demo. Added event to turn vendors on and off ·
HeronAlexandria/dsrc@3e99932 ·
GitHub](https://github.com/HeronAlexandria/dsrc/commit/3e999320bf4036494d1b2d9836c0e46d50fa11ee),
which contains some minor fixes and changes to allow the vendors to be turned on
and off in server configuration.
# The Generic Gift Box
The vendors only sell one item at a time. For example, during a holiday event,
you earn tokens, and you trade those tokens in for a reward. You get a single
item from the vendor. Some things sold on vendors might be a small stack, but
that is one item with charges, and the object was defined that way. The generic
gift box allows the creation of multiple items without changing the time or
providing additional definitions.
A functioning gift box requires a script, an entry in the master items table, a
string file for the box, and an entry in the static items table. Since we added
an object, we will copy the CRC file from the server to the client. This is a
lot to take in, so lets go through it.
To make a gift box, you add an item to the master items table, attach the
script, and set the object variables. After compiling, you move the crc file
from the server to the client. To see strings for the responses from the box and
an actual name, you must change string files; we will go over that soon. When
the object gets created, the object variables are assigned to the object, and
the script is attached.
The box will not work without the script, so lets begin there. I have already
written the script, which you can find at
[dsrc/sku.0/sys.server/compiled/game/script/item/gift_boxes at master ·
HeronAlexandria/dsrc ·
GitHub](https://github.com/HeronAlexandria/dsrc/tree/master/sku.0/sys.server/compiled/game/script/item/gift_boxes).
The name of the script is generic_gift_box.java.
The gift box is modeled after the standard uniform box
(item_npe_uniform_crate_01_01). The model script is npe.uniform_crate. The
uniform box has a simple menu, including an open action. When opened, items are
created and placed in the characters inventory, and the box is destroyed. The
gift box works the same way, except that the contents are programmable.
The script expects strings to be stored in a file named generic_gift_box.stf. I
created this file with Sitners and placed it in the client folder in string/en.
While we are on this subject, lets take a quick look at where to store
client-side resources. You are probably familiar with tre files, but you do not
have to store assets in tre files; you can place them directly in the client
folder if you follow the file structure. Below is a partial screenshot of my
client folder. Any assets in this structure override tre files, so if you place
an asset in a tree file and it is not working, check the folder structure for a
copy of the file.
![](https://i.imgur.com/CeyxWuc.png)
The string file for the box is expected to be stored in the English string
folder, as shown below. I have placed this file in my client assets folder in my
fork; you can download it from there.
![](https://i.imgur.com/IlKNBSH.png)
The script adds the menu to take the string from the string file; you can see
this in OnObjectMenuRequest. When the box is used, OnObjectMenuSelect is called.
This method parses the object variables and checks for validity, and if the
variables are valid, the items are created, and the box is destroyed.
Take a look at the master items table located in
[dsrc/sku.0/sys.server/compiled/game/datatables/item/master_item at master ·
HeronAlexandria/dsrc
(github.com)](https://github.com/HeronAlexandria/dsrc/tree/master/sku.0/sys.server/compiled/game/datatables/item/master_item).
Find the entry for the item item_heron_gift_pgc_01_10. Note that this is
assigned the generic uniform template (column B), has some object variables
(column G), which we will discuss in a moment, and assigns the generic gift box
script (column K) to the object.
When the object is created, the object variables and script are assigned. Note
that you can edit the script, then reload the script, and you do not have to
update the object. If you edit the object variables, recompile the master items
table and reload the data table, this does not update any object variables for
existing objects. You would have to destroy any existing items and recreate them
or edit the object variables manually.
The provided script recognizes four object variables: mode, source, selections,
and items, and they are case sensitive. Mode, source, and selections have
defaults, but items must be defined. Mode is either “all” or “random” and
defaults to “all.” When mode is set to “all,” everything in the items list is
generated; when the value of selections defines “random”, the number of items
generated, selections are ignored if the mode is “all” and must be at least one
when the mode is “random.”
The value of source is either “list” or “table” and defaults to “list.” When the
value is “list,” the items are in a semi-colon delimited list. Take a look a the
object variables for item_heron_gift_pgc_01_10 for an example. Note the colon
after each entry; this tells the script to create 10 of the item. The script
will create ten copper, silver, and gold chronicler tokens in this example. Note
that mode is not defined, so it defaults to all.
If the source is “table,” items refer to a table. Placing items in a table
allows them to be restricted by class if desired. Refer to the object
item_heron_gift_test in the master item table for an example. For the most part,
a list will do what you need.
The procedure for creating a new gift box is simple. Copy one of the entries I
have made in the master items table, change the template in column B if you
like, and then change the object variables. Edit the table “static_item_n.sft”
located in the client directory string/en using Sitners and add your object name
and string description. The following screenshot shows the location of the
master items table:
This document provides instructions for creating vendors, assigning an
appearance, name, and title to the vendor, stocking the vendor, spawning the
vendor, and setting a flag to turn the vendor on and off. It also covers
different types of payment, such as credits and tokens.
![](https://i.imgur.com/3OPGz8b.png)
I placed my static items string file in [client-assets/string/en at master ·
HeronAlexandria/client-assets
(github.com)](https://github.com/HeronAlexandria/client-assets/tree/master/string/en),
named “heron_static_item_n.stf”for reference.
Recompile, start your server, and try creating the object you defined using the
createstaticitem command. You should be able to open the box and claim your
goodies.
The procedure for creating a vendor is to create the NPC, place the NPC, and
then provide a table of items for the vendor to sell.
# Creating the First Vendor
For this example, we will be creating a vendor that provides Mandalorian armor
schematics in exchange for Marauder tokens and credits.
The first vendor will offer a gift box containing marauder tokens for credits.
These tokens will be used to pay the second vendor, who will sell chronicler
tokens, and the third vendor will accept the chronicler tokens and sell heroic
tokens. Creating a vendor is not difficult, but there are a lot of steps, and it
is easy to make a mistake.
# What You Need
To create a vendor, we perform the following steps:
This is not complicated, but it does have a lot of steps. You will need to
understand how to get code from the source repository from GIT, and you will
need to install Sitners (SIE). I used version 3.709.95. I downloaded the source
code in a zip file, unzipped the files, then created the files I needed and
uploaded them to my VM, as the Windows tools are easier to use.
1. Create the templates for the NPC.
I used NotePad++ as my text editor and SIE to create and edit string and tre
files. You will need some familiarity with SIE. If this is your first-time using
SIE, you will figure it out. We will be using files from the DSRC, Server Data,
and Client Data repositories.
2. Create a conversation script for the NPC.
# Creating the NPC
3. Create the inventory.
The easiest way to create the NPC is to begin with a related NPC, copy the
necessary files, and modify to suit our needs. We are going to use the TCG
vendor for a template; you will find the template in
`dsrc\\sku.0\\sys.shared\\compiled\\game\\object\\mobile`”. The filename is
`shared_vendor_tcg_1.tpf`
4. Add the entry to the creatures table.
Copy this file and rename it to “`shared_vendor_tutorial.tpf`”. This is a text
file, so we can edit it with a text editor; do so now, and take note of the
screenshot below:
5. Add the spawner to the proper build-out file.
![](https://imgur.com/mYerDhc.png)
6. Recompile and copy the files.
We are going to change lines 6 and 9. The objectName entry on line six refers to
location of the string table and the key in the string table. This tells the
client what string to display for the vendor. The entry tells the client to look
in the string table “creature_names.stf” which is located in the mob directory
and use the key “vendor_tcg_1”to find the string to display for the vendor. You
will find this string table in the client assets repository (I used the client
assets master branch), in the directory “string/mob.”
## Creating the Templates
Below is a screenshot from SIE showing the key and the string value in the
creature_names.stf file. This is the name the client will display for the
vendor.
The first vendor is the marauder token vendor, which I named vendor_tok_m. There
are thus two template files to create: vendor_tok_m.tpf and
shared_vendor_tok_m.tpf. The first file, vendor_tok_m.tpf is located in
dsrc/sku.0/sys.server/compiled/game/object/mobile. I based this on
vendor_tcg_1.tpf; I copied the file and made the changes. You can use mine for a
template or copy another. The only information that you need to change is the
location of the shared template, as shown below:
![](https://imgur.com/Du44cOI.png)
![](https://i.imgur.com/MrSr8DY.png)
We are not going to edit this file; it is best that if you put your extensions
in their own file to avoid future merge errors. We use SIE to create a new
string table. We create the following entry, and save the file as
`vendor_tutorial.stf`
![](https://imgur.com/coR2zyx.png)
The reference to the shared template is the compiled file, which is named
shared_vendor_tok_m.iff, not shared_vendor_tok_m.tpf. Remember that file names
in the Linux world are case-sensitive.
Save the file somewhere that is easy to find; we will need it later when we
construct our tre file. Now change line six to match, like so:
The shared template file is located in
dsrc/sku.0/sys.shared/compiled/game/object/mobile. Below is a screenshot of
shared_vendor_tok_m.tpf:
![](https://imgur.com/ghyRmNi.png)
![](https://i.imgur.com/p3J9Ibs.png)
Line 9 is used to define the appearance. The appearance files are in the
“appearance” folder in the server data. We are going to leave this as it is; you
can experiment on your own and look at existing files to determine the values to
set.
# Pending
Take careful note of the objectName. This entry defines the name of the NPC in
the string file and the name of the string file to look in. I tried using a file
other than creature_names, but it would not work. This string file is built on
the client and copied to the server. Without the string file, the server will
randomly generate a name for the NPC. I have added my string file to
[client-assets/string/en/mob at master · HeronAlexandria/client-assets
(github.com)](https://github.com/HeronAlexandria/client-assets/tree/master/string/en/mob),
named heron_creature_names.stf for reference. Here is a screenshot and that
shows the names of the NPCs and their string names:
events.java, buildout, event controller, template
![](https://i.imgur.com/NBoMsRr.png)
# Assets
`shared_vendor_tok_x.tpf`
## Create the Conversation Script
`shared_vendor_tok_m.tpf`
The conversation scripts for vendors are straightforward. I used a TCG vendor
for the base, but you can use my token_m_vendor.java script. You will find the
conversation script at [dsrc/token_m_vendor.java at master ·
HeronAlexandria/dsrc
(github.com)](https://github.com/HeronAlexandria/dsrc/blob/master/sku.0/sys.server/compiled/game/script/conversation/token_m_vendor.java).
`shared_vendor_tok_c.tpf`
You need to change the reference to the conversation file on line 14 and change
everything named token_m_vendor to your vendors name. These references include
the method names, such as token_m_vendor_condition__defaultCondition on line 14
and the strings on line 30. Just use the find function of an editor to move
through the file and change the references. The string file referenced on line
14 goes in the client folder as shown below:
`game/object/mobile`
![](https://i.imgur.com/JMiBznO.png)
Template (server mobile):
I created these from a TCG vendor conversation, but you are welcome to use mine
and edit them as you wish. These files are included at
[client-assets/string/en/conversation at master · HeronAlexandria/client-assets
(github.com)](https://github.com/HeronAlexandria/client-assets/tree/master/string/en/conversation).
`vendor_tcg_1.tpf to vendor_tok_x.tpf`
I have different conversation files for my three vendors, but they are simple
enough to share the same conversation script and string files. Just copy files,
change the names, and make the changes you need.
`vendor_tcg_1.tpf to vendor_tok_m.tpf`
## Create Inventory
`vendor_tcg_1.tpf to vendor_tok_c.tpf`
The vendors inventory is stored in a data table. There are two steps for the
vendors inventory; the first is to create the gift box, and the second is to
add it to the vendors data table. Refer to the master item table I provided and
look for item_heron_gift_marauder_01_50. Take a look at the attached script and
the object variables. The object variables instruct the script to create
marauder tokens when the box is opened.
Server:
`datatables/mob/creatures.tab`
Now go look at the vendors data table token_m_vendor.tab, which you will find
in [dsrc/sku.0/sys.server/compiled/game/datatables/item/vendor at master ·
HeronAlexandria/dsrc
(github.com)](https://github.com/HeronAlexandria/dsrc/tree/master/sku.0/sys.server/compiled/game/datatables/item/vendor).
Here is a screenshot from my VM:
`creatures.tab` set the token type
`datatables/item/vendor`
![](https://i.imgur.com/g3r7TWh.png)
`token_x_vendor.tab`
![](https://i.imgur.com/XNiojCi.png)
`token_m_vendor.tab`
`token_c_vendor.tab`
This vendor only sells the marauder token box I defined in the master items
table for ten credits.
Conversations:
## Add the Vendor to the Creatures Table
`script/conversation`
The creatures table, creatures.tab, is located in
dsrc/sku.0/sys.server/compiled/game/datatables/mob; refer to
[dsrc/sku.0/sys.server/compiled/game/datatables/mob at master ·
HeronAlexandria/dsrc
(github.com)](https://github.com/HeronAlexandria/dsrc/tree/master/sku.0/sys.server/compiled/game/datatables/mob)
for mine.
`token_x_vendor.java`
There are many entries, so the easiest way to look at the vendor definition is
to look at my table. Find “vendor_tok_m.tab” Use this as a guide when making
your own. In general, you want to copy my entry, change the name in column A
then make changes to columns N (the NPC template), BM (sets the object
variables), BN (attaches the scripts).
`token_m_vendor.java`
The NPC template is the compiled template you defined above. The object
variables set the table name from which the vendors inventory is taken. The
scripts in column BN are the vendor script npc.vendor.vendor, which provides the
vendor functionality, and the conversation script we created earlier.
`token_c_vendor.java`
The creatures table entry binds the NPC template, vendor table, and the scripts
together.
String file
## Add Spawner
`conversation/token_x_vendor`
Now that we have the definitions done, we need to add the spawner so the NPC
will spawn. The NPC is created with an area spawner, but you must know which
build-out file to place the spawner in, the coordinates, and the facing.
Buildout coordiantes are not the same as world coordiantes. Fortunately, Aconite
has provided a utility for doing just that:
`conversation/token_m_vendor`
`conversation/token_c_vendor`
![](https://i.imgur.com/zU6dR8K.png)
Build out file
![](https://i.imgur.com/7FtxcRr.png)
Do not forget the shared file
The original link is found here:
<https://discord.com/channels/366560008068005892/366576100941234177/819406962613420062>.
`dsrc\\sku.0\\sys.server\\compiled\\game\\datatables\\buildout\\tatooine\\tatooine_6_2.tab`
Use the above script to get the build-out coordinates, the quaternion (facing),
and the build-out file. You will place the spawner in the build-out file. Take a
look at [dsrc/sku.0/sys.server/compiled/game/datatables/buildout/tatooine at
master · HeronAlexandria/dsrc
(github.com)](https://github.com/HeronAlexandria/dsrc/tree/master/sku.0/sys.server/compiled/game/datatables/buildout/tatooine),
and find the file vendor_demo_mos_eisley.tab. I placed the definitions for my
vendors in that file. If you treat this guide as a tutorial, the spawners go in
tatooine_6_2.tab. The file vendor_demo_mos_eisley.tab is a separate build-out
file used to turn the vendors on and off. I will cover that topic last. If you
plan to make your vendors switchable, I suggest getting them working and then
adding the configuration last.
Copy the string file to the server
Please take a look at the build-out file I provided and use it as a guide for
making your spawners.
Copy the crc file to the client
## Recompile and Copy Files
## To Do
Now recompile. Check the crc files. They are located in
swg-main/data/sku.0/sys.client/build/game/misc,
swg-main/data/sku.0/sys.server/build/game/misc, and
swg-main/data/sku.0/serverdata/misc. The files locate din client and
serverdata/misc are the same file. If the crc did not rebuild, then run run ant
build_object_template_crc to force a crc rebuild.
Object vars:
Copy the client crc file to the client directory as shown below:
`string:item.vendor.vendor_table=token_x_vendor,int:ai.noClap=1`
![](https://i.imgur.com/fxNkbGe.png)
in
If you do not copy the crc file, the client will not find the vendor, and it
will not spawn correctly.
`dsrc\\sku.0\\sys.server\\compiled\\game\\datatables\\item\\vendor`
Next, copy the shared vendor templates from the server to the client. You will
find them on the server here:
scripts:
![](https://i.imgur.com/GQM9Aur.png)
`npc.vendor.vendor,conversation.token_x_vendor`
They go in the client folder here:
`npc.vendor.vendor,conversation.tcg_vendor`
![](https://i.imgur.com/IlKNBSH.png)
the script is tcg_vendor.java located in
`dsrc\\sku.0\\sys.server\\compiled\\game\\script\\conversation\\tcg_vendor.java`
Set VENDOR_TOKEN_TYPE ("`item.token.type`") otherwise it uses heroic tokens
Remember, any files in the client folder override any entries in tre files. We
could put the shared vendor files in a tre file without fear of being overridden
since they do not exist, but it is easier to develop without making tre files.
# The Box
Finally, we want to copy the creature names string file from the client to the
server. If you do not do this, the random name generator will generate a name
for your vendor. The file is named creature_names.stf and is located in the
client folder here:
Open, Examine, Destroy
# Hiding Vendors
![](https://i.imgur.com/s00HScf.png)
`dsrc\\sku.0\\sys.server\\compiled\\game\\script\\event\\holiday_controller.java`
`dsrc\\sku.0\\sys.server\\compiled\\game\\script\\event\\planet_event_handler.java`
The file goes on the server, as shown below. Note that we only need the English
string file.
Shared Area file
# Broken Things
![](https://i.imgur.com/38KFTHA.png)
Slave I ITV
Bestine Election
## You are Done!
# Check This
Once the above steps are completed, start your server and test your vendor. If
you did everything correctly, it would work just fine. If not, go back through
the steps one at a time, or ask for help on Discord.
`item_reimbursement_list`
# Creating the Second Vendor
![](https://imgur.com/X0NcmVD.png)
The second vendor will offer chronicler tokens in exchange for marauder tokens.
Repeat the steps for the first vendor; remember that the vendors name is
vendor_tok_c. Note that in the creatures table, the object variable defines a
token type, which means that token0 in the vendor table refers to the marauder
token, and the others are unused. Even though the other tokens were not used, I
had to define through token4 to avoid an index exception.
![](https://imgur.com/OnwrNCK.png)
Refer to the files I provided in my fork as examples, using the steps to create
the first vendor as a guide.
@Contributors Upon request I've pushed a prototype of my buildout utility
script. It is a work in progress, but serves its simple purpose at this time. To
use, attach `developer.buildout_utility` to your player, spawn an object where you
want it all pretty with whatever rotation and whatever, and then target it and
say in spatial getBuildoutInfo and you'll get an SUI window with everything that
you need to put in a buildout data table for an object to spawn correctly. Feel
free to report any bugs to me. This is currently for exteriors only, but as
Elour will tell you, use a dungeon_spawner for an interior anyways.
# Creating the Third Vendor
`object/tangible/npe/npe_generic_uniform_box.iff`
The third vendor sells heroic tokens in exchange for chronicler tokens. You will
notice that I did not define boxes for the echo base tokens; I leave that as an
exercise for the reader. This vendor takes only tokens, not cash. The default
types are used since we did not define a token type. The default tokens are
defined in the file trail.java located in
dsrc/sku.0/sys.server/compiled/game/script. The default types are defined in the
array HEROIC_TOKENS. Thus, token0 is Axkva Min, token1 is Tusken, and so on.
`item_heron_gift_axkva_01_05`
Refer to the files I provided in my fork as examples, using the steps to create
the first vendor as a guide.
# Toggling Vendors
To toggle vendors on and off, like the holiday vendors, you have to place the
spawners in a standalone build-out file, add that build-out file to the planets
areas, and then bind that area to an event. You then update the holiday
controller to start and stop the event. Once this is done, you can turn the
vendors on and off in local options. It is not that complicated, but we will go
through the steps briefly.
Note that you should implement this functionality when you need to turn vendors
on and off. Remove the spawners if you want to remove vendors and never see
them, such as the TCG vendors. This approach really should only be used for
events, such as Halloween, Lifeday, or your server anniversary event.
1. Define the build-out file.
2. Add the build-out file to the areas.
3. Update the holiday controller.
4. Rebuild and copy the area file
5. Turn the event on or off in local options.
## Define Build-Out
Remember when we defined the vendor spawners and ignored the
vendor_demo_mos_eisley.tab file and placed the spawners in tatooine_6_2.tab? Now
you know why the spawners for my vendors are in a separate file. Take the
spawners out of tatooine_6_2.tab, and put them in vendor_demo_mos_eisley.tab.
You can find the build-out files in
dsrc/sku.0/sys.server/compiled/game/datatables/buildout/tatooine.
## Add the Area
The area file is shared (meaning it does on the client and server), which means
it is located in
dsrc/sku.0/sys.server/compiled/game/datatables/buildout/Tatooine. The area file
is named areas_tatooine.tab. Here is a screenshot of the relevant area:
![](https://i.imgur.com/SahnGpm.png)
I set the area for the vendor demo to be the same as the Halloween area. Note
column Y, which sets the name of the event. This means that “vendor_demo_event”
must be running for this area to be active.
## Update Holiday Controller
We need to update the holiday controller to create the vendor demo event. You
will find the holiday controller in
dsrc/sku.0/sys.server/compiled/game/script/event, named
holliday_controller.java. The link to my fork is
[dsrc/sku.0/sys.server/compiled/game/script/event at master ·
HeronAlexandria/dsrc
(github.com)](https://github.com/HeronAlexandria/dsrc/tree/master/sku.0/sys.server/compiled/game/script/event).
Look for the event I added, vendorDemoServer, and use it as a guide. There are a
few things that require an additional explanation. Take a look at the following
screenshot:
![](https://i.imgur.com/jCVlN1r.png)
See the messageTo calls on lines 20 and 29? Note the 120; this is the number of
seconds before the event starts. Vendors will not appear until the server runs
for two minutes. Note that the delays for the other events are much longer; I
set this demo to two minutes for easier testing.
An example of checking to see if the event is running appears on line 47 in the
following screenshot:
![](https://i.imgur.com/nz51275.png)
Note that these checks do appear in more than one place; search the script for
them to get a clear picture.
Finally, leave the OnHearSpeach method alone. In general, it does not work
correctly. You will turn your vendors on or off in a server restart, not talking
to the holiday controller.
## Rebuild and Copy
Now rebuild, and then find the area file and copy it to the client. In this
example, you will find the area file in the following location on the VM:
![](https://i.imgur.com/WamPQvE.png)
Copy that file to the following location on the client:
![](https://i.imgur.com/Ed6hAEz.png)
## Turn on the Event
To activate the event, add vendor_demo_event=1 or vendor_demo_event=true to your
localOptions.cfg, as you would any other event. The event will start when you
restart the server, and the vendors will respawn after the delay you specified
when you updated the holiday controller.