Animatronic store

What it does
You click the placeable "container", the NPC comes over, says whateve speil you like and opens the store. The script also randomly generates the contents (5 types) and replenishes over time and if needed. It is compatible with regular merchants.

How it works
basically it uses the tag of the placeable to determine how to stock the nearest store. Since it uses the standard NwN treasure charts the class and level of the seller also affect stocking. Once the placeable is properly stocked, the nearest designated salesman is called over and his conversation starts. I found that I had to add an option in his conversation to ask him to back up, otherwise s/he tends to trap characters in corners.

The Script, part 1
This goes in the container's on_use (note the container will not have an inventory!)

// Generate treasure routine modified from guess where void GenerateStock(int nNumberItems, object oSeller, object oStore) { // there are 5 basic types of store. The tag should include one of the 5 words below int nType = 0; // defaults to class (personal items) if ( FindSubString( GetTag(oStore), "CLASS") >= 0 ) { nType=0; } else if (FindSubString( GetTag(oStore),"ARCANE")>=0) {nType=1;} else if (FindSubString(GetTag(oStore),"DIVINE")>=0) {nType=2;} else if (FindSubString(GetTag(oStore),"AMMO")>=0) {nType=3;} else if (FindSubString(GetTag(oStore),"POTION")>=0) {nType=4;} else if (FindSubString(GetTag(oStore),"KIT")>=0) {nType=5;} int i = 0; for (i = 1; i <= nNumberItems; i++) { switch(nType) { case 0:    {CreateTable2Item(oStore, oSeller, 0);  break; } case 1:    {CreateArcaneScroll(oStore, oSeller);   break; } case 2:    {CreateDivineScroll(oStore, oSeller);   break; } case 3:    {CreateAmmo(oStore, oSeller);           break; } case 4:    {CreatePotion(oStore, oSeller);         break; } case 5:    {CreateKit(oStore, oSeller);            break; } }  } //dbSpeak("Generate Treasure nSpecific = 0"); } void main { object oPC; oPC = GetLastUsedBy; if (!GetIsObjectValid(oPC)) { oPC = GetLastOpenedBy; } object oShelf = OBJECT_SELF; object oStore = GetNearestObject( OBJECT_TYPE_STORE, oShelf, 1 ); int nNth=1; object oSeller = GetNearestObject( OBJECT_TYPE_CREATURE, oShelf, nNth ); while ( GetIsObjectValid(oSeller) ) { if ( !GetIsPC(oSeller) ) {break;} nNth++; oSeller = GetNearestObject( OBJECT_TYPE_CREATURE, oShelf, nNth ); } // store merchant object SetLocalObject( oPC, "Store_at", oStore ); // * RESTOCK THE STORE (Simulates trade and over-ordering) // add lots if store has never been used before if ( GetLocalInt(oStore, "LastStocked") ==0 ) { GenerateStock( d10(1)+10, oSeller, oStore); } // get what day it is ////////////adjust (GetCalendarYear-##) ## should be your module's starting year int nTime = (GetCalendarYear-65)*365 + GetCalendarMonth*31 + GetCalendarDay; // restock fastest if low inventory nNth = 0; object oItem = GetFirstItemInInventory(oStore); while ( GetIsObjectValid(oItem) ) { nNth++; oItem = GetNextItemInInventory(oStore); } nTime = nTime + 5 / nNth; // add some stock every week or so if ( GetLocalInt(oStore, "LastStocked") < nTime-10 ) { GenerateStock( d4(1), oSeller, oStore); } // add some more stock every few days if ( GetLocalInt(oStore, "LastStocked") < nTime- 5) { GenerateStock( d4(1), oSeller, oStore); SetLocalInt( oStore, "LastStocked", nTime ); } // END RESTOCKING * // salesman comes over AssignCommand( oSeller, ActionMoveToObject(oShelf,FALSE,5.0) ); AssignCommand( oSeller, ActionStartConversation(oPC,"basic_merchant",TRUE) ); }
 * 1) include "nw_o2_coninclude"

The Script, Part 2
This goes in the conversation script. Note that the previous script will start the conversation. It is set up for a resref "basic_merchant" for the conversation.

void main { object oPC = GetPCSpeaker; object oStore = GetLocalObject( oPC, "Store_at" ); if ( GetDistanceToObject(oStore)<10.0 ) { OpenStore( oStore, oPC ); } }

Footnote
I should also mention that the merchant conversation this script uses isn't necessarily (and probably isn't) the conversation the Seller uses when you click on it. It's simply a script that says something like "Do you want to see these?" or some such generic store opening question. After using it awhile I'm sonsidering have it be a one-liner and use OpenStore immediately.