RPG - Scriptable Items Approach?

What would be the best approach to create a system to allow for custom item scripts?

Nethack example, Lets say I want to create an item: “Potion of Raise Level”. When user consumes this item, it raises the characters level. However, if it’s cursed, it actually raises the character itself up a physical dungeon level. But, lets say the function SendPlayerTo(‘Space Right Above Player’) returns “That space is blocked, epic fail”. I don’t want the potion to be “consumed”. Instead DisplayMessage("Newb, you can’t do that).

I thought about doing this with interfaces, and then creating each item as it’s own class, but that seems ugly.

It seems impossible to have this kind of “flexibility” by hard coding item definitions. My other idea was to create a List drinkActions;

and I would iterate through the actions and execute each one by one, but that doesn’t give me to oppurtunity to do like “If this action fails, do this instead”. But it does allow me to create items in XML, or a Unity Editor Extension.

Anyone else have any ideas?

I would make a class called “Consumables” and derive a class called “Potions” from that.

The Consumables class would contain all the common methods and data members that involve
items which the user can consume, such as potions and food. The Potion class would contain methods
and data members specific to the potions, such as buff up, and advance level. Potion class may include
a method that checks for blockage when the user drinks it.

For example:

bool CheckForBlockage() {

     // Do your blockage check code here and either set a bool value for wayIsBlocked
     // or more concisely, return from the method with true when it finds a block.
     // Return false as a default result after the check.
     // This code block demonstrates the idea:

     if(wayIsBlocked) { 
          
          return true;
     }

     else {
          
          return false;
     }
}

If you have other uses for blockage checks, you may consider putting that method into another class
that is attached to a common object (like the player). That way, all objects that want to know if there
is blockage could call the method.