-
Notifications
You must be signed in to change notification settings - Fork 0
Abloom API Developer Guide
This guide explains how to use the Abloom API for mod development. The API provides programmatic control over elemental weapons, projectiles, armor resistances, and damage calculation.
The Abloom API supports 13 element types defined in ElementType:
| Element | Damage ID | Description |
|---|---|---|
| FIRE | fire_dmg |
Fire-based damage with burning effect |
| PHYSICAL | physical_dmg |
Standard physical damage |
| WIND | wind_dmg |
Wind-based damage with windswept effect |
| EARTH | earth_dmg |
Earth-based damage with stun effect |
| WATER | water_dmg |
Water-based damage with wetness effect |
| ICE | ice_dmg |
Ice-based damage with freeze effect |
| ELECTRIC | electric_dmg |
Electric damage with shock effect |
| ENERGY | energy_dmg |
Energy-based damage with overload effect |
| NATURAL | natural_dmg |
Natural damage with bloom effect |
| QUANTUM | quantum_dmg |
Quantum damage that ignores armor |
| ETHER | ether_dmg |
Ether damage with corruption effect |
| LIGHT | light_dmg |
Light damage with dispersion effect |
| SHADOW | shadow_dmg |
Shadow damage with eclipse effect |
- Base accumulation: 1 point per hit
- Activation threshold: 100 points
- Effect duration: Varies by element (see documentation)
Register weapons to make them elemental:
import com.auranite.abloom.ElementalWeaponRegistry;
import com.auranite.abloom.ElementType;
// Register a weapon with default multiplier (1.0)
ElementalWeaponRegistry.registerWeapon(myItem, ElementType.FIRE);
// Register a weapon with custom multiplier
ElementalWeaponRegistry.registerWeapon(myItem, ElementType.FIRE, 2.5f);Convenient utilities for elemental weapons:
import com.auranite.abloom.ElementalWeaponUtils;
import com.auranite.abloom.ElementType;
import net.minecraft.world.item.ItemStack;
// Register an item by registry name
ElementalWeaponUtils.registerItemById("mymod", "dragon_sword", ElementType.FIRE);
// Register multiple items at once
ElementalWeaponUtils.registerMultiple(ElementType.WATER, item1, item2, item3);
// Register multiple items with custom multiplier
ElementalWeaponUtils.registerMultiple(ElementType.WATER, 3.0f, item1, item2, item3);
// Check if item is elemental
boolean isElemental = ElementalWeaponUtils.isElemental(stack);
// Get element type from stack
ElementType element = ElementalWeaponUtils.getElementType(stack);
// Get accumulation multiplier
float multiplier = ElementalWeaponUtils.getAccumulationMultiplier(stack);
// Add element to existing item stack
ItemStack elementalStack = ElementalWeaponUtils.addElementToStack(stack, ElementType.FIRE);
// Add element with custom multiplier
ItemStack elementalStack = ElementalWeaponUtils.addElementToStackWithAccum(stack, ElementType.FIRE, 2.0f);
// Remove element from stack
ItemStack cleanStack = ElementalWeaponUtils.removeElementFromStack(stack);Low-level component API for direct NBT manipulation:
import com.auranite.abloom.ElementalWeaponComponent;
import net.minecraft.world.item.ItemStack;
import java.util.Optional;
// Check if item has elemental component
boolean hasElement = ElementalWeaponComponent.hasElement(stack);
// Get element from item
Optional<ElementType> element = ElementalWeaponComponent.getElement(stack);
// Get accumulation multiplier
float multiplier = ElementalWeaponComponent.getAccumMultiplier(stack);
// Create item with element
ItemStack elementalStack = ElementalWeaponComponent.withElement(stack, ElementType.FIRE);
// Create item with element and multiplier
ItemStack elementalStack = ElementalWeaponComponent.withElementAndAccum(stack, ElementType.FIRE, 2.5f);
// Remove elemental component
ItemStack cleanStack = ElementalWeaponComponent.removeElement(stack);Register projectiles to make them elemental:
import com.auranite.abloom.ElementalProjectileRegistry;
import com.auranite.abloom.ElementType;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
// Register projectile by entity type
ElementalProjectileRegistry.registerProjectile(EntityType.ARROW, ElementType.FIRE, 1.5f);
// Register projectile by class
ElementalProjectileRegistry.registerProjectileByClass(MyCustomProjectile.class, ElementType.ICE, 2.0f);
// Check if projectile is elemental
boolean isElemental = ElementalProjectileRegistry.isElementalProjectile(projectile);
// Get element from projectile
Optional<ElementType> element = ElementalProjectileRegistry.getElementForEntity(projectile);
// Get accumulation multiplier from projectile
Optional<Float> multiplier = ElementalProjectileRegistry.getAccumulationMultiplierForEntity(projectile);import com.auranite.abloom.ElementalProjectileRegistry;
import com.auranite.abloom.ElementType;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.LivingEntity;
// Create and launch elemental projectile
Arrow projectile = ElementalProjectileRegistry.createAndLaunchElementalProjectile(
level,
shooter,
EntityType.ARROW,
1.5f, // velocity
0.1f // inaccuracy
);
// Create projectile with forced element (overrides shooter's weapon)
Arrow projectile = ElementalProjectileRegistry.createElementalProjectileWithOverride(
level,
shooter,
EntityType.ARROW,
ElementType.FIRE, // forced element
1.5f, // velocity
0.1f // inaccuracy
);import com.auranite.abloom.ElementalProjectileRegistry;
// Enable inheriting element from shooter's weapon (default: true)
ElementalProjectileRegistry.setInheritElementFromShooter(true);
// Check if inheriting is enabled
boolean inherits = ElementalProjectileRegistry.getInheritElementFromShooter();Register armor with elemental resistances:
import com.auranite.abloom.ArmorResistanceRegistry;
import com.auranite.abloom.ElementType;
import java.util.Map;
// Register armor with single resistance
ArmorResistanceRegistry.registerArmor(myArmor, ElementType.FIRE, 0.3f);
// Register armor with multiple resistances
Map<ElementType, Float> resistances = Map.of(
ElementType.FIRE, 0.3f,
ElementType.WATER, 0.2f,
ElementType.ICE, 0.4f
);
ArmorResistanceRegistry.registerArmor(myArmor, resistances);Low-level component API for direct NBT manipulation:
import com.auranite.abloom.ElementalResistanceComponent;
import net.minecraft.world.item.ItemStack;
// Check if item has resistance component
boolean hasResistance = ElementalResistanceComponent.hasResistance(stack);
// Get resistance for specific element
float fireRes = ElementalResistanceComponent.getResistance(stack, ElementType.FIRE);
// Get all resistances
Map<ElementType, Float> allResistances = ElementalResistanceComponent.getAllResistances(stack);
// Create item with resistance
ItemStack resistantStack = ElementalResistanceComponent.withResistance(stack, ElementType.FIRE, 0.3f);
// Create item with multiple resistances
Map<ElementType, Float> resistances = Map.of(
ElementType.FIRE, 0.3f,
ElementType.ICE, 0.4f
);
ItemStack resistantStack = ElementalResistanceComponent.withResistances(stack, resistances);
// Remove resistance component
ItemStack cleanStack = ElementalResistanceComponent.removeResistance(stack);
// Remove specific resistance
ItemStack cleanStack = ElementalResistanceComponent.removeResistance(stack, ElementType.FIRE);Main API for dealing elemental damage:
import com.auranite.abloom.ElementDamageHandler;
import com.auranite.abloom.ElementType;
import net.minecraft.world.entity.Entity;
// Deal elemental damage to entity
ElementDamageHandler.dealElementDamage(target, ElementType.FIRE, 10.0f);
// Deal elemental damage with custom accumulation
ElementDamageHandler.dealElementDamage(target, ElementType.FIRE, 10.0f, 2.0f, attacker);
// Deal elemental damage with specific accumulation points
ElementDamageHandler.dealElementDamage(target, ElementType.FIRE, 10.0f, 50);
// Instant elemental damage (bypasses some modifiers)
ElementDamageHandler.applyElementalDamageInstant(target, source, ElementType.FIRE, 10.0f, 1.0f);import com.auranite.abloom.ElementDamageHandler;
import com.auranite.abloom.ElementType;
import net.minecraft.world.entity.LivingEntity;
// Add accumulation points
ElementDamageHandler.addElementPoints(entity, ElementType.FIRE, 25);
// Get current accumulation points
int points = ElementDamageHandler.getElementPoints(entity, ElementType.FIRE);
// Reset specific element points
ElementDamageHandler.resetElementPoints(entity, ElementType.FIRE);
// Reset all element points
ElementDamageHandler.resetAllElementPoints(entity);
// Get accumulation progress (0-100%)
int progress = ElementDamageHandler.getAccumulationProgress(entity, ElementType.FIRE);Check and modify entity resistances:
import com.auranite.abloom.ElementResistanceManager;
import com.auranite.abloom.ElementType;
import net.minecraft.world.entity.Entity;
// Get entity resistance
ElementResistanceManager.Resistance resistance = ElementResistanceManager.getResistance(entity, ElementType.FIRE);
// Check if entity has resistance
boolean hasResistance = ElementResistanceManager.hasResistanceFor(entity, ElementType.FIRE);
// Check if entity is weak to element
boolean isWeak = ElementResistanceManager.isWeakness(entity, ElementType.FIRE);
// Check if entity is immune
boolean isImmune = ElementResistanceManager.isImmune(entity, ElementType.FIRE);
// Calculate reduced damage (takes resistance into account)
float reducedDamage = ElementResistanceManager.calculateReducedDamage(entity, ElementType.FIRE, 10.0f);
// Calculate accumulation points (takes resistance into account)
int points = ElementResistanceManager.calculateAccumulationPoints(entity, ElementType.FIRE, 10);Register resistances programmatically:
import com.auranite.abloom.ElementResistanceRegistry;
import com.auranite.abloom.ElementType;
import com.auranite.abloom.ElementResistanceManager;
import net.minecraft.world.entity.EntityType;
// Register uniform resistance for multiple entities
ElementResistanceRegistry.registerUniform(ElementType.FIRE, 0.5f, EntityType.BLAZE, EntityType.MAGMA_CUBE);
// Register single entity resistance
ElementResistanceRegistry.registerSingle(EntityType.WITHER, ElementType.FIRE, 0.8f);
// Register multiple resistances for single entity
Map<ElementType, ElementResistanceManager.Resistance> resistances = Map.of(
ElementType.FIRE, ElementResistanceManager.Resistance.HALF_RESIST,
ElementType.WATER, ElementResistanceManager.Resistance.ZERO,
ElementType.ELECTRIC, ElementResistanceManager.Resistance.WEAKNESS
);
ElementResistanceRegistry.registerMultiple(EntityType.WITHER, resistances);
// Register resistance via tags (requires registry access)
// See ElementResistanceRegistry Tags section belowPredefined tag keys for entity resistance:
import com.auranite.abloom.ElementResistanceRegistry.Tags;
// Fire resistance tag
TagKey<EntityType<?>> fireResistance = Tags.FIRE_RESISTANCE;
// Fire weakness tag
TagKey<EntityType<?>> fireWeakness = Tags.FIRE_WEAKNESS;
// All element tags are available:
// WATER_RESISTANCE, WATER_WEAKNESS
// EARTH_RESISTANCE, EARTH_WEAKNESS
// WIND_RESISTANCE, WIND_WEAKNESS
// ICE_RESISTANCE, ICE_WEAKNESS
// ELECTRIC_RESISTANCE, ELECTRIC_WEAKNESS
// PHYSICAL_RESISTANCE, PHYSICAL_WEAKNESS
// SOURCE_RESISTANCE, SOURCE_WEAKNESS
// NATURAL_RESISTANCE, NATURAL_WEAKNESS
// QUANTUM_RESISTANCE, QUANTUM_WEAKNESS
// ETHER_RESISTANCE, ETHER_WEAKNESS
// LIGHT_RESISTANCE, LIGHT_WEAKNESS
// SHADOW_RESISTANCE, SHADOW_WEAKNESSManage damage numbers and status texts:
import com.auranite.abloom.ElementDamageDisplayManager;
import com.auranite.abloom.ElementType;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.LivingEntity;
// Check if damage numbers are enabled (from config)
boolean enabled = AbloomConfig.areDamageNumbersEnabled();
// Check if status texts are enabled (from config)
boolean statusEnabled = AbloomConfig.areStatusTextsEnabled();
// Spawn damage number
ElementDamageDisplayManager displayManager = new ElementDamageDisplayManager();
displayManager.spawnDamageNumber(entity, 10.5f, ElementType.FIRE);
// Spawn status text with component
displayManager.spawnStatusText(entity, Component.translatable("elemental.tooltip.overheating"), 0xFF5500);
// Spawn status text with string
displayManager.spawnStatusText(entity, "OVERHEATING!", 0xFF5500);Access configuration values:
import com.auranite.abloom.config.AbloomConfig;
// Check if damage numbers are enabled
boolean damageEnabled = AbloomConfig.areDamageNumbersEnabled();
// Check if status texts are enabled
boolean statusEnabled = AbloomConfig.areStatusTextsEnabled();
// Get damage number spawn radius
int spawnRadius = AbloomConfig.getDamageNumberSpawnRadius();
// Get spawn radius squared (for distance checks)
int spawnRadiusSq = AbloomConfig.getDamageNumberSpawnRadiusSq();package com.example.mymod;
import com.auranite.abloom.*;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Rarity;
public class MyModElements {
public static final Item DRAGON_SWORD = new Item(new Item.Properties().rarity(Rarity.RARE));
public static final Item ICE_BOW = new Item(new Item.Properties().rarity(Rarity.RARE));
public static final Item IRON_CHESTPLATE = new Item(new Item.Properties().rarity(Rarity.COMMON));
public static void init() {
// Register elemental weapons
registerElementalWeapons();
// Register armor resistances
registerArmorResistances();
// Register projectiles if needed
registerProjectiles();
}
private static void registerElementalWeapons() {
// Make dragon sword deal fire damage with 3x accumulation
ElementalWeaponUtils.registerItem(DRAGON_SWORD, ElementType.FIRE, 3.0f);
// Make ice bow deal ice damage with 2x accumulation
ElementalWeaponUtils.registerItem(ICE_BOW, ElementType.ICE, 2.0f);
}
private static void registerArmorResistances() {
// Make iron chestplate resistant to fire
ArmorResistanceRegistry.registerArmor(
IRON_CHESTPLATE,
ElementType.FIRE,
0.3f // 30% resistance
);
}
private static void registerProjectiles() {
// Make fireball projectiles fire-elemental
ElementalProjectileRegistry.registerProjectile(
EntityType.FIREBALL,
ElementType.FIRE,
1.5f // 1.5x accumulation
);
// Make arrows inherit element from shooter's weapon
ElementalProjectileRegistry.setInheritElementFromShooter(true);
}
}- Use ElementalWeaponUtils over ElementalWeaponRegistry for convenience
- Always check for null when getting elements from items
- Use config values instead of hardcoding display settings
- Register in common setup (not client or server only)
-
Test with
/reloadwhen using datapacks during development -
Clamp values between
-0.99and0.99for resistances
If upgrading from an older version:
- ElementalWeaponComponent - Already in place, no changes needed
- ElementalProjectileRegistry - New API for projectiles
- ElementResistanceManager - New resistance calculation
- Config API - Moved to AbloomConfig class
- Datapack Guide - Configuring datapacks
- ElementType.java - Complete element types
- README - Overview of features