The first script below is a sample 'On Open Store' script. Each restocked store will need its own version of this script, with a suitably modified 'InitRestock' function. Items that are set to be restocked should have the 'Infinite' flag set to false in the Store blueprint. (Otherwise they will be ignored for restocking purposes.)
// restock_shop
/*
This is the On Open Store script for a sample
store. It performs restocking of inventory that
are frequently expended by the PCs, plus valued
items that need occasional replacement.
*/
// RJH 08jul11
#include "inc_restock_store"
// Store-specific restock tags
const string ARROW_P1_TAG = "nw_wammar009";
const string BOLT_P1_TAG = "nw_wammbo008";
const string CLUB_P1_TAG = "nw_wblmcl002";
const string COMP_LNGBOW_P1_TAG = "nw_wbwmln010";
const string HVY_SHIELD_P1_TAG = "nw_ashmlw002";
const string LGT_SHIELD_P1_TAG = "nw_ashmsw002";
const string QUARTRSTAFF_P1_TAG = "nw_wdbmq2002";
/* The following calls will establish the items that
will be restocked for this store.
Restocking occurs in two-day, four-day, one-week
and two-week intervals. The parameters passed to
each Add*StockRate call are the tag of the item
to be restocked, the number of the item to replace
following each interval, and the maximum number
of said items to allow. Hence:
AddTwoDayStockRate( "NW_WAXHN001", 2, 5 );
will set the restock to allow 2 copies of
"NW_WAXHN001" (Handaxe) to be added to the store
inventory every two days, up to a maximum of 5
copies in the inventory.
*/
void InitRestock()
{
AddTwoDayStockRate( ARROW_TAG, 1, 4 );
AddTwoDayStockRate( BOLT_TAG, 1, 4 );
AddTwoDayStockRate( LIGHT_CROSSBOW_TAG, 1, 1 );
AddTwoDayStockRate( LIGHT_SHIELD_TAG, 1, 2 );
AddTwoDayStockRate( SHORTBOW_TAG, 1, 1 );
AddTwoDayStockRate( POT_BARKSKIN_TAG, 1, 3 );
AddFourDayStockRate( HEAVY_SHIELD_TAG, 1, 1 );
AddFourDayStockRate( HEAVY_CROSSBOW_TAG, 1, 1 );
AddFourDayStockRate( LONGBOW_TAG, 1, 2 );
AddFourDayStockRate( TOWER_SHIELD_TAG, 1, 1 );
AddOneWeekStockRate( ARROW_P1_TAG, 1, 1 );
AddOneWeekStockRate( BOLT_P1_TAG, 1, 1 );
AddOneWeekStockRate( LGT_SHIELD_P1_TAG, 1, 1 );
AddTwoWeekStockRate( CLUB_P1_TAG, 1, 1 );
AddTwoWeekStockRate( COMP_LNGBOW_P1_TAG, 1, 1 );
AddTwoWeekStockRate( HVY_SHIELD_P1_TAG, 1, 1 );
AddTwoWeekStockRate( QUARTRSTAFF_P1_TAG, 1, 1 );
}
void main()
{
int bInitRestock = GetLocalInt( OBJECT_SELF, RS_INIT_RESTOCK );
if ( !bInitRestock ) {
/* Initialize the items to be restocked */
InitRestock();
// Only need to initialize once
SetLocalInt( OBJECT_SELF, RS_INIT_RESTOCK, TRUE );
}
// Restock the depleted inventory
RestockStore();
}
The include file below does all the donkey work for the restocking scripts. As a convenience, the top part of the file lists the tags of items that seem likely to be selected for restocking.
// inc_restock_store
/*
This file includes function calls that can be used to
perform restocking of a store. They should be called
from the 'On Open Store' script in a store blueprint.
The Add*StockRate routines perform the initialization
of the restocking rate information. Each visit
thereafter, RestockStore should be called to update
the store inventory.
Note that restock scripts are best used for items
that are frequently expended by the party or those
items that are sought by multiple party members and
have a non-trivial price tag, such as longswords or
bows. Low cost items such as clubs, daggers, torches
and clothing, are best handled with the 'Infinite'
setting in the store dialog.
*/
// RJH 07jul11
// Common armor and shield restock tags
const string CHAIN_SHIRT_TAG = "p_hhm_ch01";
const string CHAINMAIL_TAG = "nw_aarcl004";
const string HEAVY_SHIELD_TAG = "nw_ashlw001";
const string LEATHER_ARMOR_TAG = "nw_aarc001";
const string LIGHT_SHIELD_TAG = "nw_ashsw001";
const string SCALE_MAIL_TAG = "nw_aarcl003";
const string STUDDED_LEATHER_TAG = "nw_aarcl002";
const string TOWER_SHIELD_TAG = "nw_ashto001";
// Common potion restock tags
const string POT_ANTIDOTE = "nw_it_mpotion006";
const string POT_BARKSKIN_TAG = "nw_it_mpotion005";
const string POT_BLESS_TAG = "nw_it_mpotion009";
const string POT_CURE_LIGHT_WOUNDS_TAG = "nw_it_mpotion001";
const string HOLY_WATER_TAG = "x1_wmgrenade005";
// Common weapon restock tags
const string ARROW_TAG = "nw_wamar001";
const string BATTLEAXE_TAG = "nw_waxbt001";
const string BOLT_TAG = "nw_wambo001";
const string BULLET_TAG = "nw_wambu001";
const string DART_TAG = "nw_wthdt001";
const string HEAVY_CROSSBOW_TAG = "nw_wbwxh001";
const string LIGHT_CROSSBOW_TAG = "nw_wbwxl001";
const string LONGBOW_TAG = "nw_wbwmln006";
const string SHORTBOW_TAG = "nw_wbwsh001";
const string LONGSWORD_TAG = "nw_wswls001";
const string SHURIKEN_TAG = "nw_wthsh001";
const string THROWING_AXE_TAG = "nw_wthax001";
// Common miscellaneous restock tags
const string ACID_FLASK_TAG = "x1_wmgrenade001";
const string CHOKING_POWDER_TAG = "x1_wmgrenade004";
const string HEALERS_KIT_1_TAG = "nw_it_medkit001";
const string HEALERS_KIT_3_TAG = "nw_it_medkit002";
const string TANGLEFOOT_BAG_TAG = "x1_wmgrenade006";
const string THIEVES_TOOLS_1_TAG = "nw_it_picks001";
const string THIEVES_TOOLS_3_TAG = "nw_it_picks002";
const string THUNDERSTONE_TAG = "x1_xmgrenade007";
// Restock date tracking variables
const string RS_INIT_RESTOCK = "rs_init_restock";
const string RS_PRIOR_VISIT = "rs_prior_visit";
const string RS_TWODAY_DATE = "rs_twoday_date";
const string RS_FOURDAY_DATE = "rs_fourday_date";
const string RS_ONEWEEK_DATE = "rs_oneweek_date";
const string RS_TWOWEEK_DATE = "rs_twoweek_date";
// Inventory tracking variables
const string RS_NO_RESTOCK = "rs_no_restock_items";
const string RS_INVENTORY_TYPES = "rs_inventory_types";
// Prefixes used for creating unique local variable names
const string RS_ID_PREFIX = "rs_id_";
const string RS_NO_PREFIX = "rs_no_";
const string RS_PER_PREFIX = "rs_per_";
const string RS_TAG_PREFIX = "rs_tag_";
const string RS_CNT_PREFIX = "rs_cnt_";
const string RS_MAX_PREFIX = "rs_max_";
// Prototypes
// Initialization routines
void AddStockRate( int nPeriod, string sTag, int nCopies, int nMax );
void AddTwoDayStockRate( string sTag, int nCopies, int nMax );
void AddFourDayStockRate( string sTag, int nCopies, int nMax );
void AddOneWeekStockRate( string sTag, int nCopies, int nMax );
void AddTwoWeekStockRate( string sTag, int nCopies, int nMax );
// Calls that perform the inventory tracking and restocking
void UpdateInventory();
void RestockItem( string sTag, int nCopies, int nMax );
void RestockItems( int nPeriod, int nCount );
void RestockStore();
/* Add the item and its restocking parameters to the list
of items to be restocked. The nPeriod determines the
restocking interval, sTag is the tag of the item to be
restocked, nCopies is the number of copies to restock
after nPeriod, and nMax is the maximum inventory.
*/
void AddStockRate( int nPeriod, string sTag, int nCopies, int nMax )
{
string sTagLC = GetStringLowerCase( sTag );
int nNumRestock = GetLocalInt( OBJECT_SELF, RS_NO_RESTOCK ) + 1;
string sCount = IntToString( nNumRestock );
SetLocalInt( OBJECT_SELF, RS_PER_PREFIX + sCount, nPeriod );
SetLocalString( OBJECT_SELF, RS_TAG_PREFIX + sCount, sTagLC );
SetLocalInt( OBJECT_SELF, RS_CNT_PREFIX + sCount, nCopies );
SetLocalInt( OBJECT_SELF, RS_MAX_PREFIX + sCount, nMax );
SetLocalInt( OBJECT_SELF, RS_NO_RESTOCK, nNumRestock );
}
// Convenience call for AddStockRate with a two-day period
void AddTwoDayStockRate( string sTag, int nCopies, int nMax )
{
AddStockRate( 2, sTag, nCopies, nMax );
}
// Convenience call for AddStockRate with a four-day period
void AddFourDayStockRate( string sTag, int nCopies, int nMax )
{
AddStockRate( 4, sTag, nCopies, nMax );
}
// Convenience call for AddStockRate with a one-week period
void AddOneWeekStockRate( string sTag, int nCopies, int nMax )
{
AddStockRate( 7, sTag, nCopies, nMax );
}
// Convenience call for AddStockRate with a two-week period
void AddTwoWeekStockRate( string sTag, int nCopies, int nMax )
{
AddStockRate( 14, sTag, nCopies, nMax );
}
/* Clear the old inventory records, then cycle through the
inventory, saving information about each unique item type
as a pair of local variables on the store:
1) Stock count variable:
Name = RS_NO_PREFIX + item tag
Content = (int) item stock count
2) Stock index variable:
Name = RS_ID_PREFIX + incremental index (1, 2, ...)
Content = (string) item tag
Variable 1 is used for quick lookup of an item count when
the item tag is known. Variable 2 is used for fast cleanup
of Variable 1 when the inventory is being re-initialized.
*/
void UpdateInventory()
{
/* Incrementally clear the previous inventory by using
the stock ID variable to lookup the name of the stock
count variable, then initialize both.
*/
int i;
int nItemTypes = GetLocalInt( OBJECT_SELF, RS_INVENTORY_TYPES );
for ( i = 1; i <= nItemTypes; i++ ) {
string sStockID = RS_ID_PREFIX + IntToString( i );
string sTag = GetLocalString( OBJECT_SELF, sStockID );
SetLocalString( OBJECT_SELF, sStockID, "" );
string sStockCount = RS_NO_PREFIX + sTag;
SetLocalInt( OBJECT_SELF, sStockCount, 0 );
}
/* Cycle through the store inventory. If an item does not
have a stock count, set the stock ID variable to the
item tag and set the stock count variable to 1. Otherwise,
increment the stock count by 1.
*/
nItemTypes = 0;
object oInventory = GetFirstItemInInventory( OBJECT_SELF );
while( oInventory != OBJECT_INVALID ) {
string sTag = GetStringLowerCase( GetTag( oInventory ) );
string sStockCount = RS_NO_PREFIX + sTag;
int nStockCount = GetLocalInt( OBJECT_SELF, sStockCount );
if ( nStockCount > 0 ) {
// Increment the count
SetLocalInt( OBJECT_SELF, sStockCount, nStockCount + 1 );
} else {
// Check if the infinite flag is set
if ( GetInfiniteFlag( oInventory ) ) {
// Set to a large number
SetLocalInt( OBJECT_SELF, sStockCount, 10000 );
} else {
// Initialize the count
SetLocalInt( OBJECT_SELF, sStockCount, 1 );
}
// Store the tag
nItemTypes++;
string sStockID = RS_ID_PREFIX + IntToString( nItemTypes );
SetLocalString( OBJECT_SELF, sStockID, sTag );
}
oInventory = GetNextItemInInventory( OBJECT_SELF );
}
// Save a count of the inventory
SetLocalInt( OBJECT_SELF, RS_INVENTORY_TYPES, nItemTypes );
}
/* This function will add up to nCopies copies of the item with
the tag sTag to the current inventory, for a maximum limit
of nMax copies.
*/
void RestockItem( string sTag, int nCopies, int nMax )
{
string sStockCount = RS_NO_PREFIX + sTag;
int nStockCount = GetLocalInt( OBJECT_SELF, sStockCount );
// Check if the inventory is at the maximum
if ( nStockCount >= nMax ) {
return;
}
// Determine the amount to add
int nAdd = nCopies;
if ( nCopies > nMax - nStockCount ) {
nAdd = nMax - nStockCount;
}
// Add the copies
int i;
for ( i = 0; i < nAdd; i++ ) {
CreateItemOnObject( sTag, OBJECT_SELF );
}
}
/* The list of items to be restocked is searched for items that
are restocked on a time interval of nPeriod days. Each time
a matching item is found, that item is restocked with a call
to RestockItem. The nCount value determines the number of
restock intervals that have passed.
*/
void RestockItems( int nPeriod, int nCount )
{
int i;
// Run through the list of items to restock
int nNumRestock = GetLocalInt( OBJECT_SELF, RS_NO_RESTOCK );
for ( i = 1; i <= nNumRestock; i++ ) {
string sCount = IntToString( i );
int nRate = GetLocalInt( OBJECT_SELF, RS_PER_PREFIX + sCount );
if ( nRate == nPeriod ) {
/* The restock rate matches the selected period,
so obtain the stocking information.
*/
string sTag = GetLocalString( OBJECT_SELF, RS_TAG_PREFIX + sCount );
int nCopies = GetLocalInt( OBJECT_SELF, RS_CNT_PREFIX + sCount );
int nMax = GetLocalInt( OBJECT_SELF, RS_MAX_PREFIX + sCount );
// Restock the item
RestockItem( sTag, nCount * nCopies, nMax );
}
}
}
/* This is the main routine for performing restocking of a store.
The first time this is called, it stores the starting dates
for the restocking. Thereafter, the current date is compared
to the date of the last restocking. If two days have passed,
then the two-day restocking is performed. Likewise for
four-day, one-week and two-week restocking intervals.
To expedite the process, on the first used restocking interval,
an inventory is taken that puts a lookup list of the stock
information in local variables on the store object. That
inventory is reused for the other restocking intervals.
*/
void RestockStore()
{
int bHaveInventory = FALSE;
int i, nCount;
// Get a numerical date
int nDay = GetCalendarDay();
int nMonth = GetCalendarMonth();
int nYear = GetCalendarYear();
int nDate = nDay + (28 * (nMonth + (12 * nYear)));
// Check for a previous visit
int bPriorVisit = GetLocalInt( OBJECT_SELF, RS_PRIOR_VISIT );
if ( !bPriorVisit ) {
/* Initialize the restock trackers in such a manner
that four restock cycles will be performed. This
will ensure that the store is well stocked.
*/
SetLocalInt( OBJECT_SELF, RS_TWODAY_DATE, nDate - 8 );
SetLocalInt( OBJECT_SELF, RS_FOURDAY_DATE, nDate - 16 );
SetLocalInt( OBJECT_SELF, RS_ONEWEEK_DATE, nDate - 28 );
SetLocalInt( OBJECT_SELF, RS_TWOWEEK_DATE, nDate - 56 );
SetLocalInt( OBJECT_SELF, RS_PRIOR_VISIT, TRUE );
}
// Check for a two day restock
int nTwoDay = GetLocalInt( OBJECT_SELF, RS_TWODAY_DATE );
if ( ( nDate - nTwoDay ) >= 2 ) {
if ( bHaveInventory == FALSE ) {
// Build an updated inventory
UpdateInventory();
bHaveInventory = TRUE;
}
// 2+ days have passed since the last 2-day restock
RestockItems( 2, ( nDate - nTwoDay ) / 2 );
SetLocalInt( OBJECT_SELF, RS_TWODAY_DATE, nDate );
}
// Check for a four day restock
int nFourDay = GetLocalInt( OBJECT_SELF, RS_FOURDAY_DATE );
if ( ( nDate - nFourDay ) >= 4 ) {
if ( bHaveInventory == FALSE ) {
// Build an updated inventory
UpdateInventory();
bHaveInventory = TRUE;
}
// 4+ days have passed since the last 4-day restock
RestockItems( 4, ( nDate - nFourDay ) / 4 );
SetLocalInt( OBJECT_SELF, RS_FOURDAY_DATE, nDate );
}
// Check for a one week restock
int nOneWeek = GetLocalInt( OBJECT_SELF, RS_ONEWEEK_DATE );
if ( ( nDate - nOneWeek ) >= 7 ) {
if ( bHaveInventory == FALSE ) {
// Build an updated inventory
UpdateInventory();
bHaveInventory = TRUE;
}
// 1+ week has passed since the last 1-week restock
RestockItems( 7, ( nDate - nOneWeek ) / 7 );
SetLocalInt( OBJECT_SELF, RS_ONEWEEK_DATE, nDate );
}
// Check for a two week restock
int nTwoWeek = GetLocalInt( OBJECT_SELF, RS_TWOWEEK_DATE );
if ( ( nDate - nTwoWeek ) >= 14 ) {
if ( bHaveInventory == FALSE ) {
// Build an updated inventory
UpdateInventory();
// bHaveInventory = TRUE;
}
// 2+ weeks have passed since the last 2-week restock
RestockItems( 14, ( nDate - nOneWeek ) / 14 );
SetLocalInt( OBJECT_SELF, RS_TWOWEEK_DATE, nDate );
}
}
Modifié par rjshae, 12 juillet 2011 - 03:00 .





Retour en haut






