The CustomMethods class provides a collection of static utility methods for common operations involving status effects, damage calculations, and entity attributes.
Source: net.more_rpg_classes.util.CustomMethods
Status Effect Management
clearNegativeEffects
public static void clearNegativeEffects(
LivingEntity entity,
boolean removeOne
)
Removes negative status effects from an entity, excluding Trial Omen.
The entity to remove effects from
If true, removes only the first negative effect found. If false, removes all negative effects.
Behavior:
- Iterates through all active status effects on the entity
- Identifies effects where
isBeneficial() returns false
- Skips
StatusEffects.TRIAL_OMEN even if harmful
- Removes effects based on
removeOne parameter
Example:
// Remove all negative effects from player
CustomMethods.clearNegativeEffects(player, false);
// Remove only one negative effect (useful for cleanse abilities with limited uses)
CustomMethods.clearNegativeEffects(player, true);
Source: CustomMethods.java:25-43
applyStatusEffect
public static void applyStatusEffect(
LivingEntity target,
int effectAmplifier,
int effectDurationSeconds,
RegistryEntry<StatusEffect> statusEffect,
int maxStackAmplifier,
boolean canStackAmplifier,
boolean showIcon,
boolean increaseDuration,
int increaseEffectDurationSeconds
)
Applies or stacks a status effect on an entity with extensive configuration options.
The entity to apply the effect to
Initial amplifier level (0 = level I, 1 = level II, etc.)
Initial duration in seconds (converted to ticks internally)
statusEffect
RegistryEntry<StatusEffect>
required
The status effect to apply
Maximum amplifier level allowed when stacking
Whether to increase amplifier when reapplied
Whether to display the effect icon in the HUD
Whether to extend duration when reapplied
increaseEffectDurationSeconds
Additional seconds to add when duration is increased
Behavior:
- If effect already exists on target:
- Optionally increases duration by
increaseEffectDurationSeconds
- Optionally increases amplifier by 1 (if
canStackAmplifier is true)
- Caps amplifier at
maxStackAmplifier
- If effect doesn’t exist:
- Applies new effect with specified parameters
Example:
// Apply stackable poison that increases in power
CustomMethods.applyStatusEffect(
target,
0, // Start at amplifier 0
10, // 10 seconds base duration
MRPGCEffects.FATAL_POISON.entry, // Effect type
5, // Max 5 stacks (amplifier 5)
true, // Can stack amplifier
true, // Show icon
true, // Increase duration on reapply
3 // Add 3 seconds each reapply
);
// Apply non-stacking buff with fixed duration
CustomMethods.applyStatusEffect(
player,
2, // Always amplifier 2
15, // 15 seconds
MRPGCEffects.COLLECTED_SOUL.entry, // Effect type
2, // Max amplifier 2
false, // Don't stack amplifier
true, // Show icon
true, // Refresh duration
0 // Don't add extra time
);
Source: CustomMethods.java:128-150
Freeze Mechanics
stackFreezeStacks
public static void stackFreezeStacks(
LivingEntity e,
int amount
)
Adds freeze ticks to an entity’s frozen state.
Number of freeze ticks to add
Behavior:
- Checks if entity can be frozen (
canFreeze())
- Calculates cap:
minFreezeDamageTicks + 5
- Adds ticks without exceeding cap
- Does nothing if entity is freeze-immune
Example:
// Add 40 freeze ticks from frost spell
CustomMethods.stackFreezeStacks(target, 40);
Source: CustomMethods.java:45-51
freezeDamageTicks
public static void freezeDamageTicks(LivingEntity e)
Adds 3 freeze ticks to an entity, typically called when dealing freeze damage.
Behavior:
- Identical to
stackFreezeStacks(e, 3)
- Adds exactly 3 freeze ticks
- Respects freeze cap and immunity
Example:
// Add freeze ticks when hitting with frost weapon
CustomMethods.freezeDamageTicks(target);
Source: CustomMethods.java:53-59
Damage Calculations
spellSchoolDamageCalculation
public static void spellSchoolDamageCalculation(
SpellSchool spellSchool,
float damageMultiplication,
LivingEntity target,
PlayerEntity attacker
)
Calculates and applies spell damage with critical hit chance.
The spell school (FIRE, FROST, ARCANE, etc.)
Multiplier applied to spell power
Entity receiving the damage
Calculation:
float spellPower = spellSchool.getValue(POWER, attacker);
float critChance = spellSchool.getValue(CRIT_CHANCE, attacker);
float critDamage = spellSchool.getValue(CRIT_DAMAGE, attacker);
float damage = spellPower * damageMultiplication;
// Roll for critical hit
if (random(0-1) < critChance) {
damage *= critDamage;
}
target.damage(SpellDamageSource.create(spellSchool, attacker), damage);
Example:
// Deal fire damage with 2.5x multiplier
CustomMethods.spellSchoolDamageCalculation(
SpellSchools.FIRE,
2.5F,
target,
player
);
// With player having:
// - Fire Power: 50
// - Crit Chance: 0.25 (25%)
// - Crit Damage: 1.5 (150%)
// Base damage = 50 * 2.5 = 125
// Crit damage = 125 * 1.5 = 187.5 (25% chance)
Source: CustomMethods.java:152-163
Attribute Queries
getHighestSpellSchoolPower
public static double getHighestSpellSchoolPower(LivingEntity entity)
Returns the highest spell power attribute value across all spell schools.
Returns: double - The highest spell power value found
Spell Schools Checked:
- Spell Power Mod: ARCANE, FIRE, FROST, HEALING, LIGHTNING, SOUL
- More RPG Library: EARTH, WATER, AIR, NATURE
Example:
double maxPower = CustomMethods.getHighestSpellSchoolPower(player);
// Returns 75.0 if player has:
// Fire: 75, Frost: 30, Arcane: 45, others: 0
Source: CustomMethods.java:165-182
getHighestDamageAttribute
public static double getHighestDamageAttribute(LivingEntity entity)
Returns the highest damage-dealing attribute, comparing melee, ranged, and spell power.
Returns: double - The highest damage attribute value
Attributes Compared:
- Highest spell school power (via
getHighestSpellSchoolPower)
GENERIC_ATTACK_DAMAGE (melee)
EntityAttributes_RangedWeapon.DAMAGE (if Ranged Weapon API mod loaded)
Example:
double damage = CustomMethods.getHighestDamageAttribute(entity);
// With entity having:
// - Melee damage: 10
// - Ranged damage: 15 (if mod loaded)
// - Fire power: 50
// Returns: 50.0
Mod Compatibility:
- Checks if
ranged_weapon_api mod is loaded before accessing ranged damage
- Falls back to melee damage if mod not present
Source: CustomMethods.java:183-191
getRangedDamageAttribute
public static double getRangedDamageAttribute(LivingEntity entity)
Returns ranged damage attribute, falling back to melee if Ranged Weapon API isn’t loaded.
Returns: double - Ranged damage if available, otherwise melee damage
Example:
double rangedDamage = CustomMethods.getRangedDamageAttribute(entity);
// If ranged_weapon_api loaded:
// Returns: entity.getAttributeValue(RANGED_DAMAGE)
// If not loaded:
// Returns: entity.getAttributeValue(GENERIC_ATTACK_DAMAGE)
Source: CustomMethods.java:208-215
Entity Relations
entityRelationCheck
public boolean entityRelationCheck(
LivingEntity owner,
Entity target
)
Checks if the target is friendly to the owner.
The entity checking the relation
The entity to check relation with
Returns: boolean
true if relation is ALLY or FRIENDLY
false if relation is MIXED, HOSTILE, NEUTRAL, or owner is null
Example:
if (entityRelationCheck(player, entity)) {
// Don't damage friendly entities
return;
}
// Proceed with attack
Note: This is an instance method, not static (unlike other methods in the class).
Source: CustomMethods.java:193-207
Area Effect Clouds
spawnCloudEntity
public static void spawnCloudEntity(
ParticleEffect particleType,
Entity owner,
float radiusCloud,
int durationSecondsCloud,
float radiusGrowthCloud,
RegistryEntry<StatusEffect> statusEffect,
int durationSecondsStatusEffect,
int amplifierStatusEffect
)
Spawns an area effect cloud that applies status effects to nearby entities.
The particle effect to display (e.g., ParticleTypes.EFFECT)
The entity spawning the cloud (used for positioning and ownership)
Initial radius of the cloud in blocks
How long the cloud exists in seconds
Final radius the cloud grows to
statusEffect
RegistryEntry<StatusEffect>
required
The status effect applied by the cloud
durationSecondsStatusEffect
Duration of the status effect applied in seconds
Amplifier level of the status effect
Behavior:
- Only spawns on server side (
!world.isClient)
- Searches for entities within 4 blocks to center cloud on
- Cloud grows linearly from
radiusCloud to radiusGrowthCloud
- If owner is
ProjectileEntity, uses projectile’s owner as cloud owner
- Cloud applies effect to entities that enter it
Example:
// Spawn poison cloud that grows over 10 seconds
CustomMethods.spawnCloudEntity(
ParticleTypes.EFFECT, // Green particles
casterEntity, // Caster owns the cloud
3.0F, // Start at 3 block radius
10, // Exists for 10 seconds
7.0F, // Grows to 7 blocks
MRPGCEffects.FATAL_POISON.entry, // Applies fatal poison
8, // Poison lasts 8 seconds
2 // Amplifier 2 (level III)
);
// Growth rate calculation:
// growth per tick = (7.0 - 3.0) / (10 * 20) = 0.02 blocks/tick
Source: CustomMethods.java:90-126
Usage Patterns
Implementing a Cleanse Ability
public void onCleanseAbilityUse(LivingEntity target) {
// Remove all negative effects
CustomMethods.clearNegativeEffects(target, false);
// Apply immunity buff
CustomMethods.applyStatusEffect(
target,
0, // No amplifier
5, // 5 seconds
StatusEffects.RESISTANCE, // Damage resistance
0, // Don't stack
false, // No stacking
true, // Show icon
false, // Don't extend
0 // No extra time
);
}
Building Frost Combo System
public void onFrostAttack(LivingEntity target, int frostPower) {
// Add freeze stacks
CustomMethods.stackFreezeStacks(target, frostPower);
// Apply Frosted effect
CustomMethods.applyStatusEffect(
target,
target.hasStatusEffect(MRPGCEffects.FROSTED.entry)
? target.getStatusEffect(MRPGCEffects.FROSTED.entry).getAmplifier() + 1
: 0,
6, // 6 seconds
MRPGCEffects.FROSTED.entry, // Frosted effect
4, // Max 4 stacks (converts to Frozen at 5)
true, // Stack amplifier
true, // Show icon
true, // Refresh duration
2 // Add 2 seconds per stack
);
}
Hybrid Damage Calculation
public void dealHybridDamage(LivingEntity target, PlayerEntity attacker) {
double highestDamage = CustomMethods.getHighestDamageAttribute(attacker);
if (highestDamage == CustomMethods.getHighestSpellSchoolPower(attacker)) {
// Player is spell-focused, use spell damage
SpellSchool bestSchool = findBestSpellSchool(attacker);
CustomMethods.spellSchoolDamageCalculation(
bestSchool,
1.5F,
target,
attacker
);
} else {
// Player is melee/ranged focused
target.damage(
attacker.getDamageSources().playerAttack(attacker),
(float)highestDamage * 1.5F
);
}
}
See Also