hmmm... llCSV2List() isn't limited to only 8 entries AFAIK. Let's use it instead of llParseString2List() and let's add a price.
I kept Ruthven's method to use the name of the textures to store data but that can be easily adapted to use a notecard instead.
The working principle of the vendor is simple: When you see a texture you like, you click to freeze the slideshow and then you can pay.
Another click will resume the slideshow to the next texture. The same happens when you buy a texture or after a timeout (set to 4 minutes).
The unplanned feature: A double-click makes the slideshow jump to the next texture.
I would strongly suggest something more subtle than llWhisper() to warn the customer about what the vendor is doing.

(Just quote me to retrieve the formating of the script.)
----------------------------------------------------------------------
// Textures name: "whatever,x_size,y_size,rate,price"
//
float Delay = 20.0; // in seconds for each anim
integer Side = 0; // Which side? (Can be ALL_SIDES.)
//
string Name;
integer Texture = 0;
integer Price = 0;
uuFade(integer direction)
{
if (direction > 0)
{
float f = 0.0;
for (; f <= 1.0; f += 0.01)
{
llSetColor(<f, f, f>, Side);
}
}
else if (direction < 0)
{
float f = 1.0;
for (; f >= 0.0; f -= 0.01)
{
llSetColor(<f, f, f>, Side);
}
}
}
uuAnimateTexture()
{
integer num = llGetInventoryNumber(INVENTORY_TEXTURE);
if (num)
{
Name = llGetInventoryName(INVENTORY_TEXTURE, Texture);
list params = llCSV2List(Name);
if (llGetListLength(params) == 5)
{
Price = llList2Integer(params, 4);
uuFade(-1);
llSetTexture(Name, Side);
integer xx = llList2Integer(params, 1);
integer yy = llList2Integer(params, 2);
llSetTextureAnim(ANIM_ON | LOOP, Side, xx, yy,
0.0, (float)(xx * yy),
llList2Float(params, 3));
uuFade(1);
}
Texture = (Texture + 1) % num;
}
}
default
{
on_rez(integer param) { llResetScript(); }
state_entry()
{
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
run_time_permissions(integer perms)
{
if (perms & PERMISSION_DEBIT)
{
state slideshow;
}
else
{
llOwnerSay("Debit permission is mandatory!" + EOF);
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
}
}
state slideshow
{
on_rez(integer param) { llResetScript(); }
state_entry()
{
llSetTouchText("Buy"

;
llSetTimerEvent(Delay);
llWhisper(0, "Slideshow is running..."

;
uuAnimateTexture();
}
timer()
{
uuAnimateTexture();
}
touch_start(integer num)
{
//if (Price)
//{
llSetTimerEvent(0.0);
state buying;
//}
//else // Freebies?
//{
// llGiveInventory(llDetectedKey(0), Name);
//}
}
}
state buying
{
on_rez(integer param) { llResetScript(); }
state_entry()
{
llWhisper(0, "Richt-click to pay"

;
llSetTouchText("Slide"

;
llSetPayPrice(PAY_HIDE, [Price, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
llSetTimerEvent(240.0); // 4 minutes to buy
}
timer()
{
llSetTimerEvent(0.0); // Time Out!
Texture = (Texture + 1) % llGetInventoryNumber(INVENTORY_TEXTURE);
state slideshow; // Resume
}
money(key id, integer amount)
{
llSetTimerEvent(0.0);
if (amount < Price)
{
llGiveMoney(id, amount);
}
else if (amount > Price)
{
llGiveMoney(id, amount - Price);
}
llGiveInventory(id, Name);
Texture = (Texture + 1) % llGetInventoryNumber(INVENTORY_TEXTURE);
state slideshow; // Resume
}
touch_start(integer num)
{
llSetTimerEvent(0.0);
Texture = (Texture + 1) % llGetInventoryNumber(INVENTORY_TEXTURE);
state slideshow; // Resume
}
}
----------------------------------------------------------------------
Compiled and tested in world. Mono/Havok 4 compatible, etc, etc
