-
Notifications
You must be signed in to change notification settings - Fork 41
Variant Abilities
Transfurred players and latexes have access to unique abilities that they can use in-game in a variety of ways. In the definition of a TransfurVariant<?>
, you can specify which abilities a player will have as that variant. When a TransfurVariant<?>
is instanced, the abilities are too. Where an ability has a AbstractAbility<?>
definition type, and a AbstractAbilityInstance
instance type. This allows abilities to save and load it's own data as needed.
There's a plethora of properties that are already programmed in to be used, such as how the player uses the ability, cooldowns, network payloads, etc.
UseType
describes how an ability should behave upon a keypress.
-
INSTANT
- The ability immediately activates, deactivates, and applies its cooldown. Doesn't activate until cooled down, and the key has been released. -
CHARGE_TIME
- The ability needs to charge with the key down, untilgetChargeTime()
ticks have passed. After that time, it will immediately activate, deactivate, and apply the cooldown. -
CHARGE_RELEASE
- The ability willtickCharge()
when the key is down. When the key releases, the ability activates, deactivates, and applies its cooldown. -
HOLD
- The ability immediately activates on key press,tick()
s the ability each tick the key is down. Deactivates and applies cooldown upon release. -
MENU
- Special type that indicates the ability will bestartUsing()
when selected in the ability menu. Willtick()
until menu returns back to inventory (default menu)
Depending on how your ability functions, you either need to implement AbstractAbilityInstance
or you can just extend SimpleAbility
. Like TransfurVariant<?>
, AbstractAbility<?>
are not instantiated for each player. So implementations of AbstractAbility<?>
CANNOT keep user specific variables, and should be treated as final.
Ideal for abilities that don't need to keep their own variables, such as an ability that creates an item, or changes a property in TransfurVariantInstance
.
public class MyAbility extends SimpleAbility {
public void startUsing(IAbstractChangedEntity entity) {
entity.displayClientMessage(new TextComponent("Hello World!"), true);
}
}
When activated, this ability will display "Hello World!" on the player's screen. One instance of MyAbility
will be created, in the ability registry.
Used in any scenario not covered by SimpleAbility
, and has some functions that need to be defined.
public class MyAbility extends AbstractAbility<MyAbilityInstance> {
public MyAbility() {
super(MyAbilityInstance::new);
}
}
public class MyAbilityInstance extends AbstractAbilityInstance {
public ItemStack myExtraItem = ItemStack.EMPTY;
public MyAbilityInstance(AbstractAbility<?> ability, IAbstractChangedEntity entity) {
super(ability, entity);
}
...
public void onRemove() {
super.onRemove();
this.entity.addItem(myExtraItem);
}
public void saveData(CompoundTag tag) {
super.saveData(tag);
tag.put("myExtraItem", myExtraItem.serializeNBT());
}
public void readData(CompoundTag tag) {
super.readData(tag);
if (tag.contains("myExtraItem"))
myExtraItem = ItemStack.of(tag.getCompound("myExtraItem"));
}
}
The player will now have an instance of MyAbilityInstance
that saves with them. This example ability has an additional item slot, saves it, loads it, and returns it to the player when the ability is removed for any reason (untransfurred, died).
Abilities are registered objects, akin to variants. They should be added to the ChangedRegistry.ABILITY ("changed:ability") registry.
AbstractAbility
has two static functions to help get entity abilities (player/latex).
// Returns the player's summon sharks ability instance if present, or else null
AbstractAbility.getAbilityInstance(player, ChangedAbilities.SUMMON_SHARKS);
// Returns an optional wrapping the player's slither ability instance, or else empty
AbstractAbility.getAbilityInstanceSafe(player, ChangedAbilities.SLITHER);