But that won't happen if I have the Remove Item When Used box checked in the item editor, right? That way I could still use non-custom classes, unless I'm overlooking something.
EDIT: Oh, that would remove the entire item when I used it a single time, even if it still had ammo left, wouldn't it?
EDIT 2: In that case, wouldn't a simpler scripting solution be to remove item when counter reaches 0, rather than rescripting an existing item?
[...]
You can do that, but it requires a slightly different hack.
You need a global array to store what items Link owns, and a function in your global loop (prior to Waitdraw) that enables, or disables them, based on the counters.
That would need to be somewhat hard-coded. To make this work, you need to flag an index of the global array using item pick-up scripts.
Note: In 2.50.x, you need to manually enter item editor args with the item ID and other fields.
Using 2.50.x int OwnsItems[256];
//For every item in the game, if it uses a counter, set the index that matches its ID to
//the desired counter. The pickup-script does this for you, but there is no way to read
//what counter an item would use in 2.50.x, so you need to use an InitD arg.
//I'm initialising this manually, because counte r0 is CR_LIFE, and if we initialised
//each index to '0', then items would all use HP. :D
int TieToCounter[256] =
{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1 };
//Likewise, this stores the minimum cost of every item.
//I'm initialising this manually so that it has a clear table, for hard-coding, if needed.
int ItemCounterCosts[256] =
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
int GetItemCounter(int itm_id) { return TieToCounter[itm_id]; }
int GetItemCost(int itm_id) { return ItemCounterCosts[itm_id]; }
//! Item Script Args :
//! These are shared between the pickup-script and the action-script, per item!
//! D0: The message to display, if any.
//! D1: The ID of the item. In 2.54, you could do this->ID, but in 2.50.x this is needed.
//! D2: The counter to use.
//! D3: The cost per use.
//Pick-Up Scriot
item script new_item
{
//D2 is the counter. Don't leave it at '0' unless you want the item
//to drain Link's HP!
//(If the cost value is also '0', then that would be safe, but it isn't a good idea.)
void run(int msg, int itm_id, int use_ctr, int cost)
{
OwnsItems[itm_id] = 1;
if ( msg > 0 ) Screen->Message(msg);
TieToCounter[itm_id] = use_ctr;
ItemCounterCosts[itm_id] = cost;
}
}
//Action Script
item script use_counter_cost
{
void run(int a, int itm_id, int c, int d)
//InitD args are shared between use and pickup scripts.
{
Game->DCounter[GetItemCounter(itm_id) -= GetItemCost(itm_id);
//Do other item stuff here if needed.
}
}
void EnableDisableItems()
{
int c;
for ( int q = 0; q < 256; ++q )
{
c = GetItemCounter(q);
if ( OwnsItem[q] )
{
if ( Link->Item[q] )
{
if ( c > 0 )
{
if ( Game->Counter[c] <= GetItemCost(q) )
{
Link->Item[q] = false;
}
}
}
if ( !Link->Item[q] )
{
//No counter assigned.
if ( c <= 0 ) { Link->Item[q] = true; }
//! Caution, this may interfere with other things that set items false.
if ( c > 0 )
{
if ( Game->Counter[c] >= GetItemCost(q) )
{
Link->Item[q] = true; //same possible problem.
//Multiple sources of setting/unsetting items can create script bugs.
}
}
}
}
}
}
global script test
{
void run()
{
while(true)
{
EnableDisableItems();
Waitdraw();
Waitframe();
}
}
}
Have fun!