So my buddy SUCCESSOR metaphorically pours his sweat and blood into writing a script for me (which will eventually be released to the public as it is a general-use type script instead of something overly specific) and after much trial and error and goat sacrifices, it finally works! It works at last, it works at least. Thank god almighty, it works at last! Small problem though. I did not change a single thing (that I remember?) and the next day the script breaks for no reason. So!

Here's the script:

Code:
const int IT_BOTTLE1        = 90;//empty bottle item of Bottle Class 1    const int IT_ING_RED1    = 220;//ingredient item for red potion
    const int IT_ING_GRN1    = 221;//ingredient item for green potion
    const int IT_ING_BLU1    = 222;//ingredient item for blue potion
    const int IT_POT_RED1    = 231;//red potion item
    const int IT_POT_GRN1    = 230;//green potion item
    const int IT_POT_BLU1    = 229;//blue potion item
    const int IT_BOT_FAIR1    = -1;//Fairy in a bottle
const int IT_BOTTLE2        = 12;//repeat for bottle class 2
    const int IT_ING_RED2    = 241;
    const int IT_ING_GRN2    = 252;
    const int IT_ING_BLU2    = 240;
    const int IT_POT_RED2    = 237;
    const int IT_POT_GRN2    = 236;
    const int IT_POT_BLU2    = 225;
    const int IT_BOT_FAIR2    = -1;
const int IT_BOTTLE3        = 228;//bottle class 2
    const int IT_ING_RED3    = -1;
    const int IT_ING_GRN3    = -1;
    const int IT_ING_BLU3    = -1;
    const int IT_POT_RED3    = -1;
    const int IT_POT_GRN3    = -1;
    const int IT_POT_BLU3    = -1;
    const int IT_BOT_FAIR3    = -1;
const int IT_BOTTLE4        = 227;//bottle class 4
    const int IT_ING_RED4    = -1;
    const int IT_ING_GRN4    = -1;
    const int IT_ING_BLU4    = -1;
    const int IT_POT_RED4    = -1;
    const int IT_POT_GRN4    = -1;    
    const int IT_POT_BLU4    = -1;
    const int IT_BOT_FAIR4    = -1;
        
    //Bottle item constants set to negatives are ignored
    //leave constant at -1 if you are not using that item
    //item numbers do not need to be sequential
    
int bottles[32] = { 
    IT_BOTTLE1, IT_ING_RED1, IT_ING_GRN1, IT_ING_BLU1, 
        IT_POT_RED1, IT_POT_GRN1, IT_POT_BLU1, IT_BOT_FAIR1, 
    IT_BOTTLE2, IT_ING_RED2, IT_ING_GRN2, IT_ING_BLU2, 
        IT_POT_RED2, IT_POT_GRN2, IT_POT_BLU2, IT_BOT_FAIR2, 
    IT_BOTTLE3, IT_ING_RED3, IT_ING_GRN3, IT_ING_BLU3, 
        IT_POT_RED3, IT_POT_GRN3, IT_POT_BLU3, IT_BOT_FAIR3, 
    IT_BOTTLE4, IT_ING_RED4, IT_ING_GRN4, IT_ING_BLU4, 
        IT_POT_RED4, IT_POT_GRN4, IT_POT_BLU4, IT_BOT_FAIR4 };


    //constants for bottles[] array do not change    
    const int BOTT_1     = 0;
    const int BOTT_2     = 8;
    const int BOTT_3     = 16;
    const int BOTT_4     = 24;
    const int POTI_RED     = 4;
    const int POTI_GRN     = 5;
    const int POTI_BLU     = 6;




int EmptyBottle() //checks inventory for an empty bottle.
{
    for(int i = 31; i > -1; i--){
        //skip if value is not a valid item number
        if(!ValidItemNum(bottles[i])) continue;
        if(Link->Item[bottles[i]]) { //if item checked is in posession
            if(i>BOTT_4){ i = BOTT_4; continue;} //isn't empty bottle go to next bottle
            else if(i == BOTT_4) return i; //is empty bottle return value
            else if(i>BOTT_3){ i = BOTT_3; continue; }
            else if(i == BOTT_3) return i;
            else if(i>BOTT_2){ i = BOTT_2; continue; }
            else if(i == BOTT_2) return i;
            else if(i>BOTT_1) break;
            else if(i == BOTT_1) return i;
        }
    }
    return -1;
}
int HasIngred(int potion) //check to see if Link has the right potion ingredient
{
    int ingred = potion - 3;
    if(Link->Item[bottles[ingred + BOTT_4]] && ValidItemNum(bottles[ingred + BOTT_4])){ 
        return BOTT_4; }
    if(Link->Item[bottles[ingred + BOTT_3]] && ValidItemNum(bottles[ingred + BOTT_3])){ 
        return BOTT_3; }
    if(Link->Item[bottles[ingred + BOTT_2]] && ValidItemNum(bottles[ingred + BOTT_2])){ 
        return BOTT_2; }
    if(Link->Item[bottles[ingred]] && ValidItemNum(bottles[ingred])){ 
        return BOTT_1; }
    else { return -1;} //return no ingred
}


//potion use POTI_ constants for potion, disc is cheaper price with ingredient
void BuyPotion(int potion, int price, int disc, int stringNoBott, int stringNotEnough)
{
    bool discount;
    int bottle = HasIngred(potion);
    
    //if HasIngred returns -1 check for empty bottle
    if(bottle<0)bottle = EmptyBottle();
    else discount = true;
    
    //if EmptyBottle() returns -1 show No Empty Bottle string
    if(bottle<0){ //No empty bottle
        Screen->Message(stringNoBott); NoAction(); return; } 
    
    if(discount) {
        //Check to see if Player has enough rupees
        if(Game->Counter[CR_RUPEES] < disc){
            Screen->Message(stringNotEnough); 
            NoAction(); return; 
        }
        else {
            
            //take away the ingredient
            Link->Item[bottles[bottle + potion - 3]] = false;
            //Give link the potion
            GiveLinkItem(bottles[bottle + potion]);
            Deduct(CR_RUPEES, disc);
        }
    }
    else{
        //Check to see if Player has enough rupees
        if(Game->Counter[CR_RUPEES] < price){
            Screen->Message(stringNotEnough); 
            NoAction(); return;
        }
        else {
            //give link the potion
            GiveLinkItem(bottles[bottle + potion]);
            Deduct(CR_RUPEES, price);
        }
    }
}


//delete if you use a shop script with this function
bool ShopCanBuy(ffc buy) 
{
    return (Abs(Link->X-buy->X) < 8 && Abs(Link->Y-(buy->Y+8)) < 8 && Link->Dir == DIR_UP);
}
//end of ShopCanBuy


void GiveLinkItem(int itm)//Gives Link an item and makes him hold it up
{
    item make = Screen->CreateItem(itm);  
    make->HitWidth = 16; make->HitHeight = 16;
    make->X = Link->X; make->Y = Link->Y;
    Game->PlaySound(SFX_PICKUP);
    Link->Action = LA_HOLD2LAND;
    Link->HeldItem = itm;
    while(Link->HeldItem == itm && Link->Action == LA_HOLD2LAND)
        WaitNoAction();
}
void Deduct(int counter, int amount) //deduct amount from counter
{
    int comb0 = Screen->ComboT[0];
    Screen->ComboT[0] = CT_SCREENFREEZE;
    for(int i=0;i<amount;i++)
    {
        Game->PlaySound(SFX_MSG);
        Game->Counter[counter]--;
        WaitNoAction();
    }
    Screen->ComboT[0] = comb0;
}


//IF you use another script with these functions
//either delete these or the one in the other script
//these ones allows Ex buttons
//input great than 3 0r -4 allows any button
bool SelectPressInput(int input)
{
    if(input == 0) return Link->PressA;
    else if(input == 1) return Link->PressB;
    else if(input == 2) return Link->PressL;
    else if(input == 3) return Link->PressR;
    else if(input == -1) return Link->PressEx1;
    else if(input == -2) return Link->PressEx2;
    else if(input == -3) return Link->PressEx3;
    else if(input == -4) return Link->PressEx4;
    else return (Link->PressA || Link->PressB || Link->PressL || Link->PressR ||
            Link->PressEx1 || Link->PressEx3 || Link->PressEx3 || Link->PressEx4);
}
void SetInput(int input, bool state){
    if(input == 0) Link->InputA = state;
    else if(input == 1) Link->InputB = state;
    else if(input == 2) Link->InputL = state;
    else if(input == 3) Link->InputR = state;
    else if(input == -1) Link->PressEx1 = state;
    else if(input == -2) Link->PressEx2 = state;
    else if(input == -3) Link->PressEx3 = state;
    else if(input == -4) Link->PressEx4 = state;
    else if(!state) NoAction();
}


//^^^


bool ValidItemNum(int num)
{
    return num > -1 && num < 256;
}
//D0: The potion this cauldron sells see POTI_ constants (4 is RED, 5 is GREEN, 6 is BLUE)
//D1: The full price
//D2: The discounted price when player has ingredient for potion
//D3: button to press to buy 
//        0 is A, 1 is B, 2 is L, 3 is R, -1 is Ex1, -2 is Ex2, -3 is Ex3, -4 is Ex4
//        any other value allows any of the above
//D4: String that shows when Link approaches for info, price, price with ingred...
//D5: String that shows if Link has no empty bottles
//D6: String that shows if Link doesn't have enough rupees
ffc script Cauldron
{
    void run(int potion, int price, int disc, int input, int stringInfo, int stringNoBott, int stringNotEnough)
    {
        //whether or not info string is on screen
        bool info; 
        // Run continuously
        while(true)
        {
            // If Link is below the FFC facing up
            if(ShopCanBuy(this))
            {
                // If he hits the provided input button
                if(SelectPressInput(input))
                {
                    
                    BuyPotion(potion, price, disc, stringNoBott, stringNotEnough);
                    Waitframes(20);
                    info = false;
                }
                // Else Link is under the FFC but has not hit the correct button
                else
                {
                    // Do stuff here if you want something to happen when Link is under the item but hasn't hit the input button
                    if(!info){ Screen->Message(stringInfo); info = true; }
                }
            } //! End of if(ShopCanBuy(this))
            else if(info)info = false;
            
            Waitframe();
        } //! End of while(true)
    } //! End of void run(int itm, int price, int input)
}//! End of ffc script Shop
What this script is for is basically a bottles system like in the 3D zeldas. In this version, you must have a total of XY items where x is the number of bottles in the quest and y is the number of possible items that a bottle is required for. Then whenever you "talk" to an FFC with this script on it, it's a shop script basically. it checks link's inventory for bottle items (of unique item classes, in my case zz251-254) and either gives him the appropriate potion item, or tells him to stop being a punk-ass cheapskate, or tells him that he needs a bottle of potion-holding.

THE POINT IS. The script broke for no reason that I could think of. I tried recompiling it and nothing. The FFC would refuse to sell link any potions despite having something to carry them in and having the necessary amount of money. Then I look in allegro.log and I got this error:

Code:
Invalid index (25) to local array of size 4
Invalid index (25) to local array of size 4
Invalid index (17) to local array of size 4
Invalid index (17) to local array of size 4
Invalid index (9) to local array of size 4
Invalid index (9) to local array of size 4
Invalid index (31) to local array of size 4
Invalid index (30) to local array of size 4
Invalid index (29) to local array of size 4
Invalid index (28) to local array of size 4
Invalid index (27) to local array of size 4
Invalid index (26) to local array of size 4
Invalid index (25) to local array of size 4
Invalid index (24) to local array of size 4
Invalid index (23) to local array of size 4
Invalid index (22) to local array of size 4
Invalid index (21) to local array of size 4
Invalid index (20) to local array of size 4
Invalid index (19) to local array of size 4
Invalid index (18) to local array of size 4
Invalid index (17) to local array of size 4
Invalid index (16) to local array of size 4
Invalid index (15) to local array of size 4
Invalid index (14) to local array of size 4
Invalid index (13) to local array of size 4
Invalid index (12) to local array of size 4
Invalid index (11) to local array of size 4
Invalid index (10) to local array of size 4
Invalid index (9) to local array of size 4
Invalid index (8) to local array of size 4
Invalid index (7) to local array of size 4
Invalid index (6) to local array of size 4
Invalid index (5) to local array of size 4
Invalid index (4) to local array of size 4
I am working on reproducing this bug, and if I am able to I will post a test quest. But my hunches are that:

The script works as intended once more if you start a new file and begin the quest again. Once it stopped working, I restarted my quest and everything functioned as it should. The script, upon producing the above error, behaves as if Link no longer had any items to carry potions in) Some kind of information is being stored in the quest file in some way, and then some limit somewhere is being reached. In the vein of "you can only buy x number of potions in the entire quest". The script otherwise works beautifully. But I'm not a developer and much less a programmer in general so fuck if I know how the actual mechanics are. but hey, maybe it'll give the devs an idea of where to look maybe? Bleh.

Like I said, a test quest if I am able to reproduce it.