-
Notifications
You must be signed in to change notification settings - Fork 755
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement mob effect modifier and migrate sticky to dynamic with that
- Loading branch information
1 parent
ef65c78
commit 86c1af9
Showing
7 changed files
with
214 additions
and
52 deletions.
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
src/generated/resources/data/tconstruct/tinkering/modifiers/sticky.json
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"type": "tconstruct:mob_effect", | ||
"effect": "minecraft:slowness", | ||
"level": { | ||
"base": 0, | ||
"multiplier": 1 | ||
}, | ||
"time": { | ||
"base": 20, | ||
"multiplier_flat": 10 | ||
} | ||
} |
194 changes: 194 additions & 0 deletions
194
src/main/java/slimeknights/tconstruct/library/modifiers/dynamic/MobEffectModifier.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
package slimeknights.tconstruct.library.modifiers.dynamic; | ||
|
||
import com.google.gson.JsonObject; | ||
import lombok.AccessLevel; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.Setter; | ||
import lombok.experimental.Accessors; | ||
import net.minecraft.network.FriendlyByteBuf; | ||
import net.minecraft.util.GsonHelper; | ||
import net.minecraft.world.damagesource.DamageSource; | ||
import net.minecraft.world.effect.MobEffect; | ||
import net.minecraft.world.effect.MobEffectInstance; | ||
import net.minecraft.world.entity.Entity; | ||
import net.minecraft.world.entity.EquipmentSlot; | ||
import net.minecraft.world.entity.LivingEntity; | ||
import net.minecraft.world.entity.projectile.AbstractArrow; | ||
import net.minecraft.world.entity.projectile.Projectile; | ||
import net.minecraft.world.phys.EntityHitResult; | ||
import net.minecraftforge.registries.ForgeRegistries; | ||
import slimeknights.mantle.data.GenericLoaderRegistry.IGenericLoader; | ||
import slimeknights.mantle.util.JsonHelper; | ||
import slimeknights.tconstruct.library.modifiers.Modifier; | ||
import slimeknights.tconstruct.library.modifiers.ModifierEntry; | ||
import slimeknights.tconstruct.library.modifiers.TinkerHooks; | ||
import slimeknights.tconstruct.library.modifiers.hook.ProjectileHitModifierHook; | ||
import slimeknights.tconstruct.library.modifiers.hook.ProjectileLaunchModifierHook; | ||
import slimeknights.tconstruct.library.modifiers.impl.IncrementalModifier; | ||
import slimeknights.tconstruct.library.modifiers.util.ModifierHookMap; | ||
import slimeknights.tconstruct.library.tools.context.EquipmentContext; | ||
import slimeknights.tconstruct.library.tools.context.ToolAttackContext; | ||
import slimeknights.tconstruct.library.tools.helper.ToolDamageUtil; | ||
import slimeknights.tconstruct.library.tools.nbt.IToolStackView; | ||
import slimeknights.tconstruct.library.tools.nbt.ModifierNBT; | ||
import slimeknights.tconstruct.library.tools.nbt.NamespacedNBT; | ||
|
||
import javax.annotation.Nullable; | ||
import java.util.Objects; | ||
|
||
/** Modifier that applies an effect on hit. Supports melee, armor, and ranged */ | ||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class MobEffectModifier extends IncrementalModifier implements ProjectileHitModifierHook, ProjectileLaunchModifierHook { | ||
private final MobEffect effect; | ||
private final int levelBase; | ||
private final int levelMultiplier; | ||
private final int timeBase; | ||
private final int timeMultiplierFlat; | ||
private final int timeMultiplierRandom; | ||
|
||
/** Applies the effect for the given level */ | ||
private void applyEffect(@Nullable LivingEntity target, float scaledLevel) { | ||
if (target == null) { | ||
return; | ||
} | ||
int level = Math.round(levelBase + scaledLevel * levelMultiplier - 1); | ||
if (level < 0) { | ||
return; | ||
} | ||
float duration = timeBase + scaledLevel * timeMultiplierFlat; | ||
int randomBonus = (int)(timeMultiplierRandom * scaledLevel); | ||
if (randomBonus > 0) { | ||
duration += RANDOM.nextInt(randomBonus); | ||
} | ||
if (duration > 0) { | ||
target.addEffect(new MobEffectInstance(effect, (int)duration, level)); | ||
} | ||
} | ||
|
||
@Override | ||
public void onAttacked(IToolStackView tool, int level, EquipmentContext context, EquipmentSlot slotType, DamageSource source, float amount, boolean isDirectDamage) { | ||
Entity attacker = source.getEntity(); | ||
if (isDirectDamage && attacker instanceof LivingEntity living) { | ||
// 15% chance of working per level | ||
float scaledLevel = getEffectiveLevel(tool, level); | ||
if (RANDOM.nextFloat() < (scaledLevel * 0.25f)) { | ||
applyEffect(living, scaledLevel); | ||
ToolDamageUtil.damageAnimated(tool, 1, context.getEntity(), slotType); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public int afterEntityHit(IToolStackView tool, int level, ToolAttackContext context, float damageDealt) { | ||
applyEffect(context.getLivingTarget(), getEffectiveLevel(tool, level)); | ||
return 0; | ||
} | ||
|
||
@Override | ||
public void onProjectileLaunch(IToolStackView tool, ModifierEntry modifier, LivingEntity shooter, Projectile projectile, @Nullable AbstractArrow arrow, NamespacedNBT persistentData, boolean primary) { | ||
persistentData.putFloat(getId(), modifier.getEffectiveLevel(tool)); | ||
} | ||
|
||
@Override | ||
public boolean onProjectileHitEntity(ModifierNBT modifiers, NamespacedNBT persistentData, ModifierEntry modifier, Projectile projectile, EntityHitResult hit, @Nullable LivingEntity attacker, @Nullable LivingEntity target) { | ||
applyEffect(target, persistentData.getFloat(getId())); | ||
return false; | ||
} | ||
|
||
@Override | ||
protected void registerHooks(ModifierHookMap.Builder hookBuilder) { | ||
hookBuilder.addHook(this, TinkerHooks.PROJECTILE_LAUNCH, TinkerHooks.PROJECTILE_HIT); | ||
} | ||
|
||
@Override | ||
public IGenericLoader<? extends Modifier> getLoader() { | ||
return LOADER; | ||
} | ||
|
||
/** Loader for this modifier */ | ||
public static final IGenericLoader<MobEffectModifier> LOADER = new IGenericLoader<>() { | ||
@Override | ||
public MobEffectModifier deserialize(JsonObject json) { | ||
MobEffect effect = JsonHelper.getAsEntry(ForgeRegistries.MOB_EFFECTS, json, "effect"); | ||
int levelBase = 1; | ||
int levelMultiplier = 0; | ||
if (json.has("level")) { | ||
JsonObject level = GsonHelper.getAsJsonObject(json, "level"); | ||
levelBase = GsonHelper.getAsInt(level, "base", 0); | ||
levelMultiplier = GsonHelper.getAsInt(level, "multiplier", 0); | ||
} | ||
JsonObject time = GsonHelper.getAsJsonObject(json, "time"); | ||
int timeBase = GsonHelper.getAsInt(time, "base", 0); | ||
int timeMultiplierFlat = GsonHelper.getAsInt(time, "multiplier_flat", 0); | ||
int timeMultiplierRandom = GsonHelper.getAsInt(time, "multiplier_random", 0); | ||
return new MobEffectModifier(effect, levelBase, levelMultiplier, timeBase, timeMultiplierFlat, timeMultiplierRandom); | ||
} | ||
|
||
@Override | ||
public void serialize(MobEffectModifier object, JsonObject json) { | ||
json.addProperty("effect", Objects.requireNonNull(object.effect.getRegistryName()).toString()); | ||
JsonObject level = new JsonObject(); | ||
level.addProperty("base", object.levelBase); | ||
level.addProperty("multiplier", object.levelMultiplier); | ||
json.add("level", level); | ||
JsonObject time = new JsonObject(); | ||
time.addProperty("base", object.timeBase); | ||
time.addProperty("multiplier_flat", object.timeMultiplierFlat); | ||
time.addProperty("multiplier_flat", object.timeMultiplierRandom); | ||
json.add("time", time); | ||
} | ||
|
||
@Override | ||
public MobEffectModifier fromNetwork(FriendlyByteBuf buffer) { | ||
MobEffect effect = buffer.readRegistryIdUnsafe(ForgeRegistries.MOB_EFFECTS); | ||
int levelBase = buffer.readInt(); | ||
int levelMultiplier = buffer.readInt(); | ||
int timeBase = buffer.readInt(); | ||
int timeMultiplierFlat = buffer.readInt(); | ||
int timeMultiplierRandom = buffer.readInt(); | ||
return new MobEffectModifier(effect, levelBase, levelMultiplier, timeBase, timeMultiplierFlat, timeMultiplierRandom); | ||
} | ||
|
||
@Override | ||
public void toNetwork(MobEffectModifier object, FriendlyByteBuf buffer) { | ||
buffer.writeRegistryIdUnsafe(ForgeRegistries.MOB_EFFECTS, object.effect); | ||
buffer.writeInt(object.levelBase); | ||
buffer.writeInt(object.levelMultiplier); | ||
buffer.writeInt(object.timeBase); | ||
buffer.writeInt(object.timeMultiplierFlat); | ||
buffer.writeInt(object.timeMultiplierRandom); | ||
} | ||
}; | ||
|
||
/** Builder for this modifier in datagen */ | ||
@RequiredArgsConstructor(staticName = "effect") | ||
@Accessors(fluent = true) | ||
public static class Builder { | ||
private final MobEffect effect; | ||
private int levelBase = 1; | ||
private int levelMultiplier = 0; | ||
@Setter | ||
private int timeBase; | ||
@Setter | ||
private int timeMultiplierFlat; | ||
@Setter | ||
private int timeMultiplierRandom; | ||
|
||
/** | ||
* Sets the effect level | ||
* @param base Base level granted for the modifier | ||
* @param multiplier Bonus granted per level | ||
* @return Builder | ||
*/ | ||
public Builder level(int base, int multiplier) { | ||
levelBase = base; | ||
levelMultiplier = multiplier; | ||
return this; | ||
} | ||
|
||
/** Builds the finished modifier */ | ||
public MobEffectModifier build() { | ||
return new MobEffectModifier(effect, levelBase, levelMultiplier, timeBase, timeMultiplierFlat, timeMultiplierRandom); | ||
} | ||
} | ||
} |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
47 changes: 0 additions & 47 deletions
47
src/main/java/slimeknights/tconstruct/tools/modifiers/upgrades/armor/StickyModifier.java
This file was deleted.
Oops, something went wrong.