Setup: Put the item script in the pickup slot for the Whimsical Ring. On any screen where that ring should be deactivated, check the General Use 1 (scripts) box on the second page of the screen flags. The code in the global will check on screen load if that flag is active. If it is checked and you already have the ring, the ring will be deactivated. If you go to another screen and you had the ring previously, the ring will come back. If you've never picked up the ring, nothing will happen either way.
Thanks, this was clear and functional. I've tested it through a number of warp/death/continue situations, and it works in each one.
I have a question about "General Use # (Scripts)" flags though. I already have Moosh Pits using General Use 1, but his file has me enter "2" to use that flag, presumably because it's the third checkbox (0, 1, 2) under that specific screen flag section. But your script identifies that flag with a "9" and a "100b." It's not the 9th flag in any listing, and the only references I can find to 100b in any of the std* files are for usage with Link->Dir (that being up-left). If I wanted to change your script to use General Use 2 - or any other # really - how would I do that?
Are you using 2.55?
Unfortunately, no. This is a 2.53 update to a 2.50 project.
You want a system like that, for inventory management.
So after discussing this on Discord, this was the final solution reached for this method:
// Restores ring if player dies or uses F6 in item-disabled room
global script onExit
{
void run()
{
if ( OwnsItems[130] ) Link->Item[130] = true;
}
}
// Returns if there are enemy NPCs alive on the current screen
// Borrowed from ZC 2.53's std_functions.zh for compiling with ZC 2.50.2 - can be removed if using 2.53+ to compile
bool EnemiesAlive()
{
bool alive = false;
for ( int q = Screen->NumNPCs(); q > 0; --q )
{
npc n = Screen->LoadNPC(q);
if ( n->Type != NPCT_PROJECTILE )
{
if ( !(n->MiscFlags&NPCMF_NOT_BEATABLE) )
{
if ( n->Type != NPCT_FAIRY )
{
if ( n->Type != NPCT_GUY )
{
alive = true;
}
}
}
}
}
return alive;
}
// Inventory management system
int OwnsItems[256];
// Use as item pickup script to enter item into system
item script generalPickup
{
void run(int a, int id)
{
Screen->Message(a);
OwnsItems[id] = 1;
}
}
// Place on screen to disable item
ffc script noWhimRing
{
void run()
{
Link->Item[130] = false;
Waitframes(5);
while(EnemiesAlive())
{
if(Link->Action==LA_SCROLLING && OwnsItems[130]) Link->Item[130] = true;
Waitframe();
}
if ( OwnsItems[130] ) Link->Item[130] = true;
}
}
// Place on adjacent screens to restore item
ffc script restoreWhimRing
{
void run()
{
if ( OwnsItems[130] ) Link->Item[130] = true;
}
}
It's a bit more complicated than jsm's solution, but works equally well.
The first FFC disables the item in whatever room it's placed in, and the second FFC restores the item when you move to an adjacent room. The item script enters it into the inventory management system upon pickup so that the FFCs can identify it in the first place, and the global restores it in case the player dies or uses F6 in a room where it's disabled.
A potential problem, though, is that onExit scripts are broken in 2.50.2 (and earlier?), so this would require 2.53.0 to function properly when dying or saving/continuing.
Either way, both solutions have their benefits and drawbacks. jsm's is the easiest to configure and most simple to use, but costs an extremely limited resource (a "General Use #" flag), while Zoria's has more components to work with, but is a bit more flexible and spares that resource for more script-heavy quests. (And it caught the EnemiessAlive typo in 2.53+'s std_functions.zh.)
You can also put that fight on its own DMap, and disable the ring on that DMap, to avoid all of this fuss.
That was the problem, though. Scrolling warps were messing with continue points in unresolvable ways, so a scripting solution was the last solution.
And now we're set