Last active
December 30, 2024 18:19
-
-
Save FireController1847/c7a50144f45806a996d13efcff468d1b to your computer and use it in GitHub Desktop.
Minecraft Forge 1.14.4 ~ LevelHearts Capability
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.firecontroller1847.levelhearts.capabilities; | |
public interface IMoreHealth { | |
byte getHeartContainers(); | |
byte getDefaultHealth(); | |
double getModifier(); | |
short getLevelRampPosition(); | |
void setHeartContainers(byte heartContainers); | |
void setDefaultHealth(byte defaultHealth); | |
void setModifier(double modifier); | |
void setLevelRampPosition(short levelRampPosition); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.firecontroller1847.levelhearts; | |
import org.apache.logging.log4j.LogManager; | |
import org.apache.logging.log4j.Logger; | |
import com.firecontroller1847.levelhearts.capabilities.IMoreHealth; | |
import com.firecontroller1847.levelhearts.capabilities.MoreHealth; | |
import com.firecontroller1847.levelhearts.capabilities.MoreHealthProvider; | |
import com.firecontroller1847.levelhearts.capabilities.MoreHealthStorage; | |
import net.minecraft.entity.Entity; | |
import net.minecraft.entity.player.PlayerEntity; | |
import net.minecraft.util.ResourceLocation; | |
import net.minecraftforge.common.capabilities.CapabilityManager; | |
import net.minecraftforge.event.AttachCapabilitiesEvent; | |
import net.minecraftforge.eventbus.api.SubscribeEvent; | |
import net.minecraftforge.fml.ModLoadingContext; | |
import net.minecraftforge.fml.common.Mod; | |
import net.minecraftforge.fml.config.ModConfig; | |
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; | |
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; | |
@Mod(LevelHearts.MOD_ID) | |
@Mod.EventBusSubscriber(modid = LevelHearts.MOD_ID) | |
public class LevelHearts { | |
public static final String MOD_ID = "levelhearts"; | |
public static final String MOD_NAME = "LevelHearts"; | |
public static final String MOD_VERSION = "2.0.0"; | |
public static Logger logger = LogManager.getLogger(LevelHearts.MOD_ID); | |
public LevelHearts() { | |
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, LevelHeartsConfig.COMMON, "levelhearts.toml"); | |
FMLJavaModLoadingContext.get().getModEventBus().addListener(LevelHearts::onCommonSetup); | |
} | |
@SubscribeEvent | |
public static void onCommonSetup(FMLCommonSetupEvent event) { | |
CapabilityManager.INSTANCE.register(IMoreHealth.class, new MoreHealthStorage(), MoreHealth::new); | |
} | |
@SubscribeEvent | |
public static void onAttachCapabilities(AttachCapabilitiesEvent<Entity> event) { | |
if (event.getObject() instanceof PlayerEntity) { | |
event.addCapability(new ResourceLocation(LevelHearts.MOD_ID, "morehealth"), new MoreHealthProvider()); | |
} | |
} | |
public static void debug(String message) { | |
if (LevelHeartsConfig.GENERAL.debug.get()) { | |
logger.info(message); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.firecontroller1847.levelhearts.capabilities; | |
import com.firecontroller1847.levelhearts.LevelHeartsConfig; | |
import net.minecraft.entity.SharedMonsterAttributes; | |
public class MoreHealth implements IMoreHealth { | |
private byte heartContainers; | |
private byte defaultHealth; | |
private double modifier; | |
private short levelRampPosition; | |
public MoreHealth() { | |
this.heartContainers = 0; | |
this.defaultHealth = LevelHeartsConfig.HEALTH.defHealth.get().byteValue(); | |
this.modifier = this.defaultHealth - SharedMonsterAttributes.MAX_HEALTH.getDefaultValue(); | |
this.levelRampPosition = 0; | |
} | |
@Override | |
public byte getHeartContainers() { | |
return this.heartContainers; | |
} | |
@Override | |
public byte getDefaultHealth() { | |
return this.defaultHealth; | |
} | |
@Override | |
public double getModifier() { | |
return this.modifier; | |
} | |
@Override | |
public short getLevelRampPosition() { | |
return this.levelRampPosition; | |
} | |
@Override | |
public void setHeartContainers(byte heartContainers) { | |
this.heartContainers = heartContainers; | |
} | |
@Override | |
public void setDefaultHealth(byte defaultHealth) { | |
this.defaultHealth = defaultHealth; | |
} | |
@Override | |
public void setModifier(double modifier) { | |
this.modifier = modifier; | |
} | |
@Override | |
public void setLevelRampPosition(short levelRampPosition) { | |
this.levelRampPosition = levelRampPosition; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.firecontroller1847.levelhearts.capabilities; | |
import net.minecraft.nbt.INBT; | |
import net.minecraft.util.Direction; | |
import net.minecraftforge.common.capabilities.Capability; | |
import net.minecraftforge.common.capabilities.CapabilityInject; | |
import net.minecraftforge.common.capabilities.ICapabilitySerializable; | |
import net.minecraftforge.common.util.LazyOptional; | |
public class MoreHealthProvider implements ICapabilitySerializable<INBT> { | |
@CapabilityInject(IMoreHealth.class) | |
public static final Capability<IMoreHealth> MORE_HEALTH_CAPABILITY = null; | |
private LazyOptional<IMoreHealth> instance = LazyOptional.of(MORE_HEALTH_CAPABILITY::getDefaultInstance); | |
@Override | |
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) { | |
return cap == MORE_HEALTH_CAPABILITY ? instance.cast() : LazyOptional.empty(); | |
} | |
@Override | |
public INBT serializeNBT() { | |
// @formatter:off | |
return MORE_HEALTH_CAPABILITY.getStorage().writeNBT(MORE_HEALTH_CAPABILITY, this.instance.orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!")), null); | |
// @formatter:on | |
} | |
@Override | |
public void deserializeNBT(INBT nbt) { | |
// @formatter:off | |
MORE_HEALTH_CAPABILITY.getStorage().readNBT(MORE_HEALTH_CAPABILITY, this.instance.orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!")), null, nbt); | |
// @formatter:on | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.firecontroller1847.levelhearts.capabilities; | |
import net.minecraft.nbt.CompoundNBT; | |
import net.minecraft.nbt.INBT; | |
import net.minecraft.util.Direction; | |
import net.minecraftforge.common.capabilities.Capability; | |
import net.minecraftforge.common.capabilities.Capability.IStorage; | |
public class MoreHealthStorage implements IStorage<IMoreHealth> { | |
@Override | |
public INBT writeNBT(Capability<IMoreHealth> capability, IMoreHealth instance, Direction side) { | |
CompoundNBT tag = new CompoundNBT(); | |
tag.putByte("heartContainers", instance.getHeartContainers()); | |
tag.putByte("minHealth", instance.getDefaultHealth()); | |
tag.putDouble("modifier", instance.getModifier()); | |
tag.putShort("levelRampPosition", instance.getLevelRampPosition()); | |
return tag; | |
} | |
@Override | |
public void readNBT(Capability<IMoreHealth> capability, IMoreHealth instance, Direction side, INBT nbt) { | |
CompoundNBT tag = (CompoundNBT) nbt; | |
instance.setHeartContainers(tag.getByte("heartContainers")); | |
instance.setDefaultHealth(tag.getByte("minHealth")); | |
instance.setModifier(tag.getDouble("modifier")); | |
instance.setLevelRampPosition(tag.getShort("levelRampPosition")); | |
} | |
} |
Thanks for putting this on GitHub, this is really helping me understand capabilities better. Forges documents on this kinda suck.
Glad I was able to be of help. Forge documentation relies heavily on a "trial-and-error" and a "figure it out" mentality which, in my opinion, is a terrible way to go about things. I'm very much so more of a "learn by example" type of guy, and so I wanted to share this so that there'd be at least one public example of capabilities working for 1.14. They've changed a little in 1.17 but not by much, so hopefully this example is still helpful
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for putting this on GitHub, this is really helping me understand capabilities better. Forges documents on this kinda suck.