Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detach modded attribute modifications to data-packs for better customization #26

Merged
merged 8 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ jobs:
changelog-file: CHANGELOG.md

game-versions: "${{ steps.minecraft_version.outputs.minecraft_version }}"
java: "${{ matrix.java }}"
java: "${{ matrix.java }}"
12 changes: 10 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
## Changes ⚙️
- Now using `WrapMethod` on computation of modifier(s) to avoid unneeded recalculation.
## Additions 🍎
- Implemented a feature that reads data-packs and applies attribute modifications to the world based on order.
- More documentation on this feature will come as the mod stabilizes.
- For now, if you want to be aware of how to format your data-pack(s), look towards the source code of the next builds of PlayerEX/WizardEX.
## Changes 🌽
- Changed how configs and modded entries are applied.
- Your config will appear sparse on startup, but when you go to a world (in an integrated server), it will show the extra modifications provided by loaded packs and mods.
- You can overwrite these, and they will appear in your actual config. Your config will **overwrite** any data-pack or modded pack.
- The UI will be overhauled to better assist in knowing what is supplied by datapacks/mods, but that will be in the later future.
- Deprecated the `DefaultAttributeRegistry` to keep previous versions functional, but it will be removed before release.
11 changes: 11 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id("fabric-loom")
kotlin("jvm") version "2.0.0"
kotlin("plugin.serialization") version "2.0.0"
java
`maven-publish`
id("com.google.devtools.ksp") version "2.0.0-1.0.21"
Expand All @@ -23,13 +24,23 @@ repositories {
maven("https://maven.terraformersmc.com")
maven("https://api.modrinth.com/maven")
maven("https://maven.kosmx.dev/")
maven("https://maven.parchmentmc.org")
maven("https://maven.quiltmc.org/repository/release/")
}

dependencies {
minecraft("com.mojang:minecraft:${properties["minecraft_version"]}")

mappings("net.fabricmc:yarn:${properties["yarn_mappings"]}:v2")

// mappings {
// loom.layered {
// mappings("org.quiltmc:quilt-mappings:${properties["minecraft_version"]}+build.${properties["quilt_mappings_version"]}:intermediary-v2")
// officialMojangMappings()
// parchment("org.parchmentmc.data:parchment-${properties["parchment_version"]}@zip")
// }
// }

modImplementation("net.fabricmc:fabric-loader:${properties["loader_version"]}")
modImplementation("net.fabricmc:fabric-language-kotlin:${properties["fabric_kotlin_version"]}")
modImplementation("net.fabricmc.fabric-api:fabric-api:${properties["fabric_api_version"]}")
Expand Down
15 changes: 10 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
org.gradle.jvmargs=-Xmx4000m
org.gradle.parallel=true

kotlin.code.style=official

ksp_version=2.0.0-1.0.21
kotlinpoet_version=1.17.0

Expand All @@ -7,12 +11,16 @@ maven_group=com.bibireden.data_attributes
loom_version=1.7-SNAPSHOT

minecraft_version=1.20.1
fabric_kotlin_version=1.11.0+kotlin.2.0.0
fabric_kotlin_version=1.12.0+kotlin.2.0.10
fabric_api_version=0.92.2+1.20.1
mod_version=2.0.0-beta.8+1.20.1
mod_version=2.0.0+1.20.1-beta.9
loader=fabric

# Mappings
parchment_version=1.20.1:2023.09.03
quilt_mappings_version=23
yarn_mappings=1.20.1+build.10

loader_version=0.15.11

modmenu_version=7.2.2
Expand All @@ -24,6 +32,3 @@ endec_version=0.1.7
endec_netty_version=0.1.3

mixinextras_version=0.5.0-beta.1

org.gradle.jvmargs=-Xmx4000m
org.gradle.parallel=true
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.bibireden.data_attributes.api.attribute;

import com.bibireden.data_attributes.config.functions.AttributeFunction;
import org.apache.commons.lang3.NotImplementedException;

import java.util.HashMap;
import java.util.Map;

/**
Expand All @@ -15,36 +17,36 @@ public interface IEntityAttribute {
/**
* @return The minimum value of the attribute.
*/
double data_attributes$min();
default Double data_attributes$min() { return null; }

/**
* @return The maximum value of the attribute.
*/
double data_attributes$max();
default Double data_attributes$max() { return null; }

/** Returns the intended minimum fallback of this attribute. */
double data_attributes$min_fallback();
default Double data_attributes$min_fallback() { return null; }

/** Returns the intended maximum fallback of this attribute. */
double data_attributes$max_fallback(); /** Returns the intended maximum fallback of this attribute. */
default Double data_attributes$max_fallback() { return null; }

/** Returns the smoothness of this attribute. */
double data_attributes$smoothness();
default Double data_attributes$smoothness() { return null; }

/**
* @return The attribute's {@link StackingFormula}.
*/
StackingFormula data_attributes$formula();
default StackingFormula data_attributes$formula() { return null; }

/**
* @return An immutable map of the function-parents attached to this attribute.
* @since 1.4.0
*/
Map<IEntityAttribute, AttributeFunction> data_attributes$parents();
default Map<IEntityAttribute, AttributeFunction> data_attributes$parents() { return null; }

/**
* @return An immutable map of the function-children attached to this attribute.
* @since 1.4.0
*/
Map<IEntityAttribute, AttributeFunction> data_attributes$children();
default Map<IEntityAttribute, AttributeFunction> data_attributes$children() { return null; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ public interface IEntityAttributeInstance {
* @param uuid The uuid of the modifier.
* @param value The value to change the modifier to.
*/
void updateModifier(final UUID uuid, final double value);
default void data_attributes$updateModifier(final UUID uuid, final double value) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public final class EntityAttributeModifiedEvents {

/**
* Fired after the attribute instance value was calculated, but before it was output. This offers one last chance to alter the
* value in some way (for example round a decimal to an integer).
* value in some way (for example, rounding a decimal to an integer).
*/
public static final Event<Clamped> CLAMPED = EventFactory.createArrayBacked(Clamped.class, callbacks -> (attribute, value) -> {
double cache = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import com.bibireden.data_attributes.api.event.EntityAttributeModifiedEvents;
import com.bibireden.data_attributes.mutable.MutableAttributeContainer;
import com.bibireden.data_attributes.mutable.MutableAttributeInstance;
import com.google.common.collect.Multimap;

import net.minecraft.entity.LivingEntity;
Expand Down Expand Up @@ -53,7 +52,7 @@ private void updateTrackedStatus(EntityAttributeInstance instance) {}

@Inject(method = "updateTrackedStatus", at = @At("HEAD"), cancellable = true)
private void data_attributes$updateTrackedStatus(EntityAttributeInstance instance, CallbackInfo ci) {
Identifier identifier = ((MutableAttributeInstance) instance).data_attributes$get_id();
Identifier identifier = instance.data_attributes$get_id();
if (identifier != null) {
this.data_attributes$tracked.put(identifier, instance);
}
Expand All @@ -74,16 +73,15 @@ private void updateTrackedStatus(EntityAttributeInstance instance) {}
Identifier identifier = Registries.ATTRIBUTE.getId(attribute2);
if (identifier == null) return original;

EntityAttributeInstance entityAttributeInstance = this.data_attributes$custom.computeIfAbsent(identifier, id -> this.fallback.createOverride(this::updateTrackedStatus, attribute2));
if (entityAttributeInstance != null) {
MutableAttributeInstance mutable = (MutableAttributeInstance) entityAttributeInstance;
mutable.data_attributes$setContainerCallback((AttributeContainer) (Object) this);
if (mutable.data_attributes$get_id() == null) {
mutable.data_attributes$updateId(identifier);
EntityAttributeInstance instance = this.data_attributes$custom.computeIfAbsent(identifier, id -> this.fallback.createOverride(this::updateTrackedStatus, attribute2));
if (instance != null) {
instance.data_attributes$setContainerCallback((AttributeContainer) (Object) this);
if (instance.data_attributes$get_id() == null) {
instance.data_attributes$updateId(identifier);
}
}

return entityAttributeInstance;
return instance;
}

@ModifyReturnValue(method = "hasAttribute(Lnet/minecraft/entity/attribute/EntityAttribute;)Z", at = @At("RETURN"))
Expand Down Expand Up @@ -136,7 +134,7 @@ private void updateTrackedStatus(EntityAttributeInstance instance) {}

@Inject(method = "setFrom", at = @At("HEAD"), cancellable = true)
private void data_attributes$setFrom(AttributeContainer other, CallbackInfo ci) {
((MutableAttributeContainer) other).data_attributes$custom().values().forEach(attributeInstance -> {
other.data_attributes$custom().values().forEach(attributeInstance -> {
EntityAttribute entityAttribute = attributeInstance.getAttribute();
EntityAttributeInstance entityAttributeInstance = this.getCustomInstance(entityAttribute);

Expand Down Expand Up @@ -177,9 +175,7 @@ private void updateTrackedStatus(EntityAttributeInstance instance) {}

@Override
public void data_attributes$refresh() {
for (EntityAttributeInstance instance : this.data_attributes$custom.values()) {
((MutableAttributeInstance) instance).data_attributes$refresh();
}
this.data_attributes$custom.values().forEach(EntityAttributeInstance::data_attributes$refresh);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.bibireden.data_attributes.mixin;

import com.bibireden.data_attributes.config.models.OverridesConfigModel;
import com.bibireden.data_attributes.config.models.OverridesConfigModel.AttributeOverride;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.sugar.Local;
import org.spongepowered.asm.mixin.Final;
Expand All @@ -26,7 +26,7 @@ abstract class ClampedEntityAttributeMixin extends EntityAttributeMixin {

@Inject(method = "<init>", at = @At("TAIL"))
private void data_attributes$init(String translationKey, double fallback, double min, double max, CallbackInfo ci) {
this.data_attributes$override(new OverridesConfigModel.AttributeOverride(false, minValue, maxValue, min, max, 0.0, StackingFormula.Flat));
this.data_attributes$override(new AttributeOverride(false, minValue, maxValue, min, max, 0.0, StackingFormula.Flat));
}

@ModifyReturnValue(method = "getMinValue", at = @At("RETURN"))
Expand All @@ -45,17 +45,15 @@ abstract class ClampedEntityAttributeMixin extends EntityAttributeMixin {
}

@Override
public double data_attributes$smoothness() { return this.data_attributes$smoothness; }
public Double data_attributes$smoothness() { return this.data_attributes$smoothness; }

@Override
public double data_attributes$min_fallback() {
public Double data_attributes$min_fallback() {
return this.minValue;
}

@Override
public double data_attributes$max_fallback() {
return this.maxValue;
}
public Double data_attributes$max_fallback() { return this.maxValue; }

@Override
public void data_attributes$clear() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
Expand All @@ -23,10 +21,7 @@
import com.bibireden.data_attributes.api.attribute.StackingFormula;
import com.bibireden.data_attributes.api.event.EntityAttributeModifiedEvents;
import com.bibireden.data_attributes.api.util.VoidConsumer;
import com.bibireden.data_attributes.mutable.MutableAttributeContainer;
import com.bibireden.data_attributes.mutable.MutableAttributeInstance;
import com.bibireden.data_attributes.mutable.MutableAttributeModifier;
import com.bibireden.data_attributes.mutable.MutableEntityAttribute;

import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.AttributeContainer;
Expand All @@ -35,6 +30,7 @@
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.util.Identifier;
import net.minecraft.registry.Registries;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(EntityAttributeInstance.class)
abstract class EntityAttributeInstanceMixin implements MutableAttributeInstance, IEntityAttributeInstance {
Expand Down Expand Up @@ -84,13 +80,13 @@ protected void onUpdate() {}
}

@SuppressWarnings("UnreachableCode")
@WrapMethod(method = "computeValue")
private double data_attributes$computeValue(Operation<Double> original) {
MutableEntityAttribute attribute = (MutableEntityAttribute) this.getAttribute();
@Inject(method = "computeValue", at = @At("HEAD"), cancellable = true)
private void data_attributes$computeValue(CallbackInfoReturnable<Double> cir) {
EntityAttribute attribute = this.getAttribute();
StackingFormula formula = attribute.data_attributes$formula();

// If the formula is set to Flat and there is no associated container, provide original.
if (formula == StackingFormula.Flat && this.data_attributes$container == null) return original.call();
// If the formula is set to Flat and there is no associated container, drop out early.
if (formula == StackingFormula.Flat && this.data_attributes$container == null) return;

AtomicReference<Double> k = new AtomicReference<>(0.0D);
AtomicReference<Double> v = new AtomicReference<>(0.0D);
Expand Down Expand Up @@ -158,12 +154,11 @@ protected void onUpdate() {}
});
}

return ((EntityAttribute) attribute).clamp(e.get());
cir.setReturnValue(attribute.clamp(e.get()));
}

@Inject(method = "addModifier", at = @At("HEAD"), cancellable = true)
private void data_attributes$addModifier(EntityAttributeModifier modifier, CallbackInfo ci) {
EntityAttributeInstance instance = (EntityAttributeInstance) (Object) this;
UUID key = modifier.getId();
EntityAttributeModifier entityAttributeModifier = this.idToModifiers.get(key);

Expand All @@ -173,8 +168,8 @@ protected void onUpdate() {}
this.data_attributes$actionModifier(
() -> {
this.idToModifiers.put(key, modifier);
instance.getModifiers(modifier.getOperation()).add(modifier);
}, instance, modifier, true
this.getModifiers(modifier.getOperation()).add(modifier);
}, (EntityAttributeInstance) (Object) this, modifier, true
);
}

Expand Down Expand Up @@ -211,10 +206,9 @@ protected void onUpdate() {}
public void data_attributes$actionModifier(final VoidConsumer consumerIn, final EntityAttributeInstance instanceIn, final EntityAttributeModifier modifierIn, final boolean isWasAdded) {
if (this.data_attributes$container == null) return;

EntityAttribute parentAttribute = this.getAttribute();
MutableEntityAttribute mutableParentAttribute = (MutableEntityAttribute) this.getAttribute();
EntityAttribute parent = this.getAttribute();

for (IEntityAttribute child : mutableParentAttribute.data_attributes$childrenMutable().keySet()) {
for (IEntityAttribute child : parent.data_attributes$childrenMutable().keySet()) {
EntityAttributeInstance instance = this.data_attributes$container.getCustomInstance((EntityAttribute) child);
if (instance != null) instance.getValue();
}
Expand All @@ -225,14 +219,14 @@ protected void onUpdate() {}

this.onUpdate();

LivingEntity livingEntity = ((MutableAttributeContainer) this.data_attributes$container).data_attributes$getLivingEntity();
LivingEntity livingEntity = this.data_attributes$container.data_attributes$getLivingEntity();

EntityAttributeModifiedEvents.MODIFIED.invoker().onModified(parentAttribute, livingEntity, modifierIn, value, isWasAdded);
EntityAttributeModifiedEvents.MODIFIED.invoker().onModified(parent, livingEntity, modifierIn, value, isWasAdded);

for (IEntityAttribute child : mutableParentAttribute.data_attributes$childrenMutable().keySet()) {
for (IEntityAttribute child : parent.data_attributes$childrenMutable().keySet()) {
EntityAttributeInstance instance = this.data_attributes$container.getCustomInstance((EntityAttribute) child);
if (instance != null) {
((MutableAttributeInstance) instance).data_attributes$actionModifier(() -> {}, instance, modifierIn, isWasAdded);
instance.data_attributes$actionModifier(() -> {}, instance, modifierIn, isWasAdded);
}
}
}
Expand All @@ -248,11 +242,11 @@ protected void onUpdate() {}
}

@Override
public void updateModifier(final UUID uuid, final double value) {
public void data_attributes$updateModifier(final UUID uuid, final double value) {
EntityAttributeModifier modifier = this.getModifier(uuid);
if (modifier == null) return;

this.data_attributes$actionModifier(() -> ((MutableAttributeModifier) modifier).data_attributes$updateValue(value), (EntityAttributeInstance) (Object) this, modifier, false);
this.data_attributes$actionModifier(() -> modifier.data_attributes$updateValue(value), (EntityAttributeInstance) (Object) this, modifier, false);
}

@Override
Expand Down
Loading
Loading