Another in a long line of tutorials by ColJack
In this tutorial I shall attempt to explain how traders work and how to script you own. I will not be covering the actual script compiling or conversation nodes or basic script structure, just the trading part.
Traders don't carry their shop inventory, they store it in shelves or other containers, sometimes visible and sometimes not.
As we can see from Vault City, Randal and two others keep their stock in lockers that are outside the scroll edes of the map.
As seen in San Fransisco and other maps, traders can have several tables or shelves to choose from.
Traders actually use 2 boxes and 4 scripts to deal with swapping their inventory.
First create a container somewhere off the edge of the map and give it the script "ZITMPBOX.int". This is the temporary box for swapping the inventories. Think of it as the table you need to swap a glass of beer and a glass of wine between hands. You have to put down one glass to pass the other from hand to hand
To use this box, you must put the following line in the map script after the procedure list at the start:
export variable generic_temp_box;
Each trader will also need a variable for their store box such as these listed in the Den's map script for the various traders.
export variable den_flick_box_obj; export variable den_smitty_box_obj; export variable den_mom_box_obj; export variable den_metzger_box_obj; export variable den_tubby_box_obj;
For the sake of this tutorial we'll be using Tubby in the den as our example.
In the trader's script you need to import the variables for the temporary box and the store box(s). Add the following lines after the #DEFINE's but before the procedures.
import variable den_tubby_box_obj; import variable generic_temp_box;
This brings in pointers to the temporary box and Tubby's store box to this script.
To actually swap the contents of the trader's inventory with the store inventory, you use the following 2 lines (modified with the right variable name for the trader's box of course)
This (in order) moves the trader's personal inventory to the temporary box, and then moves the store box inventory to the trader. This is usually initiated as a conversation node, but can be done as soon as you talk to him before the nodes start! Next, once trading is complete and you say goodbye, the contents are swapped back by reversing the sequence like so:
This (in order) moves Tubby's inventory (which is his store inventory at this point) back to the store's box, and the contents of the temp box (Tubby's personal inventory) back to Tubby.
Swapping back is usually done as part of the exit node(s) of a conversation (there may be more than one exit node such as "Thanks, bye", where you walk away a happy customer, and "Screw you, you ripped me off" for example where he would end the conversation and start combat.)
This deals with the trader script and it would work at that, but the stores stock would be limited to whatever you put in the store box and/or sold to the trader and once depleted would not re-stock. For this you need a script on the store box to replenish the stock over time.
Here is Tubby's store box for example on re-stocking over time:
#include "..\headers\define.h" #define NAME SCRIPT_DITUBBOX #include "..\headers\command.h" #define LVAR_RESTOCK_TIME (0) import variable den_tubby_box_obj; procedure start; procedure map_enter_p_proc; procedure start begin den_tubby_box_obj := self_obj; end procedure map_enter_p_proc begin den_tubby_box_obj := self_obj; if (is_loading_game == false) then begin if (local_var(LVAR_RESTOCK_TIME) < game_time) then begin item_caps_adjust(self_obj, random(151, 161) - self_caps); check_restock_item(PID_JET, 5, 10, 100) check_restock_item(PID_PSYCHO, 0, 2, 100) check_restock_item(PID_BUFFOUT, 0, 1, 100) check_restock_item(PID_10MM_PISTOL, 1, 2, 100) check_restock_item(PID_10MM_JHP, 2, 4, 100) check_restock_item(PID_10MM_AP, 0, 2, 100) check_restock_item(PID_BRASS_KNUCKLES, 1, 1, 100) check_restock_item(PID_LEATHER_JACKET, 1, 1, 100) check_restock_item(PID_STIMPAK, 2, 5, 100) check_restock_item(PID_10MM_SMG, 0, 1, 100) check_restock_item(PID_DESERT_EAGLE, 1, 2, 100) check_restock_item(PID_SLEDGEHAMMER, 0, 1, 100) check_restock_item(PID_RADAWAY, 0, 3, 100) set_local_var(LVAR_RESTOCK_TIME, (random(1, 2) * ONE_GAME_DAY) + game_time); end end end
While I'm not fully conversant with scripting yet, I'll take a stab at what I think the above does.
The map_enter_p_proc gets called every time you enter the map. It looks to see if the restock time has elapsed (first time it's game_time + 0 so it must have) If it has then it adds a random amount of caps to the store (between 151 and 161 in this case?) and a quantity of the other items listed. The item is defined by the PID name, and the quantity is between the first number and the second.
The last number is the chance if it restocking, in this case all 100 percent. After it's finished restocking, it adds a random amount of time (in this case between 1 and 2 game days) to the game_time and sets that as the restock time. This makes it re-stock every time you come back if it's been more than 1 or 2 days (depending on the random roll).