Skip to content

Commit

Permalink
Make Sunken variants data-driven (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugman76 authored Apr 6, 2024
2 parents 7c1a774 + 8603b38 commit bf4d60a
Show file tree
Hide file tree
Showing 16 changed files with 468 additions and 248 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package fr.hugman.promenade.client.render.entity;

import fr.hugman.promenade.Promenade;
import fr.hugman.promenade.client.render.entity.model.PromenadeEntityModelLayers;
import fr.hugman.promenade.client.render.entity.model.SunkenModel;
import fr.hugman.promenade.entity.SunkenEntity;
Expand Down Expand Up @@ -64,6 +63,6 @@ protected void setupTransforms(SunkenEntity sunkenEntity, MatrixStack matrixStac

@Override
public Identifier getTexture(SunkenEntity entity) {
return Promenade.id("textures/entity/sunken/" + entity.getVariant().getName() + ".png");
return entity.getTexture();
}
}
2 changes: 2 additions & 0 deletions src/main/java/fr/hugman/promenade/entity/CapybaraEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ protected void initDataTracker(DataTracker.Builder builder) {
builder.add(LAST_STATE_TICK, -WAKE_UP_LENGTH);
}

@Override
public void writeCustomDataToNbt(NbtCompound nbt) {
super.writeCustomDataToNbt(nbt);
nbt.putString(VARIANT_KEY, (this.getVariant().getKey().orElse(CapybaraVariants.BROWN)).getValue().toString());
Expand All @@ -455,6 +456,7 @@ public void writeCustomDataToNbt(NbtCompound nbt) {
nbt.putBoolean(SLEEPING_KEY, this.isAsleep());
}

@Override
public void readCustomDataFromNbt(NbtCompound nbt) {
super.readCustomDataFromNbt(nbt);

Expand Down
7 changes: 4 additions & 3 deletions src/main/java/fr/hugman/promenade/entity/CapybaraVariant.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ public CapybaraVariant(
int spawnWeight
) {
this.smallEyesTexture = smallEyesTexture;
this.smallEyesTexturePath = getTexturePath(smallEyesTexture);
this.largeEyesTexture = largeEyesTexture;
this.largeEyesTexturePath = getTexturePath(largeEyesTexture);
this.closedEyesTexture = closedEyesTexture;
this.closedEyesTexturePath = getTexturePath(closedEyesTexture);
this.spawnWeight = spawnWeight;

this.smallEyesTexturePath = getTexturePath(smallEyesTexture);
this.largeEyesTexturePath = getTexturePath(largeEyesTexture);
this.closedEyesTexturePath = getTexturePath(closedEyesTexture);
}

public Identifier smallEyesTexture() {
Expand Down
96 changes: 41 additions & 55 deletions src/main/java/fr/hugman/promenade/entity/SunkenEntity.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package fr.hugman.promenade.entity;

import fr.hugman.promenade.entity.data.PromenadeTrackedData;
import fr.hugman.promenade.registry.PromenadeRegistryKeys;
import fr.hugman.promenade.sound.PromenadeSoundEvents;
import net.minecraft.entity.*;
import net.minecraft.entity.ai.NoPenaltyTargeting;
Expand All @@ -25,10 +27,14 @@
import net.minecraft.entity.projectile.PersistentProjectileEntity;
import net.minecraft.entity.projectile.ProjectileUtil;
import net.minecraft.item.*;
import net.minecraft.loot.LootTable;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.FluidTags;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
Expand All @@ -37,17 +43,17 @@
import net.minecraft.world.*;

import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.stream.Collectors;

public class SunkenEntity extends AbstractSkeletonEntity implements CrossbowUser {
//TODO: make a registry for types
private static final TrackedData<Integer> SUNKEN_TYPE = DataTracker.registerData(SunkenEntity.class, TrackedDataHandlerRegistry.INTEGER);
import java.util.Optional;

public class SunkenEntity extends AbstractSkeletonEntity implements CrossbowUser, VariantHolder<RegistryEntry<SunkenVariant>> {
private static final TrackedData<RegistryEntry<SunkenVariant>> VARIANT = DataTracker.registerData(SunkenEntity.class, PromenadeTrackedData.SUNKEN_VARIANT);
private static final TrackedData<Boolean> CHARGING = DataTracker.registerData(SunkenEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
private static final TrackedData<Boolean> SWIMMING = DataTracker.registerData(SunkenEntity.class, TrackedDataHandlerRegistry.BOOLEAN);

public static final String VARIANT_KEY = "variant";

private final static EntityDimensions SWIMMING_DIMENSIONS = EntityDimensions.fixed(0.6F, 0.6F);

protected final SwimNavigation waterNavigation;
protected final MobNavigation landNavigation;
private final CrossbowAttackGoal<SunkenEntity> crossbowAttackGoal = new CrossbowAttackGoal<>(this, 1.0D, 20.0F);
Expand Down Expand Up @@ -148,14 +154,14 @@ protected PersistentProjectileEntity createArrowProjectile(ItemStack arrow, floa
@Nullable
@Override
public EntityData initialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData) {
this.setVariant(Type.fromId(world.getRandom().nextInt(Type.values().length)));
world.getRegistryManager().get(PromenadeRegistryKeys.SUNKEN_VARIANT).getRandom(random).ifPresent(this::setVariant);
return super.initialize(world, difficulty, spawnReason, entityData);
}

@Override
protected void initDataTracker(DataTracker.Builder builder) {
super.initDataTracker(builder);
builder.add(SUNKEN_TYPE, 0);
builder.add(VARIANT, this.getRegistryManager().get(PromenadeRegistryKeys.SUNKEN_VARIANT).entryOf(SunkenVariants.BUBBLE));
builder.add(CHARGING, false);
builder.add(SWIMMING, false);
}
Expand Down Expand Up @@ -244,23 +250,29 @@ public void updateAttackType() {
}

@Override
public void writeCustomDataToNbt(NbtCompound compound) {
super.writeCustomDataToNbt(compound);
compound.putString("Type", this.getVariant().getName());
public void writeCustomDataToNbt(NbtCompound nbt) {
super.writeCustomDataToNbt(nbt);
nbt.putString(VARIANT_KEY, (this.getVariant().getKey().orElse(SunkenVariants.BUBBLE)).getValue().toString());
}

@Override
public void readCustomDataFromNbt(NbtCompound compound) {
super.readCustomDataFromNbt(compound);
this.setVariant(SunkenEntity.Type.byName(compound.getString("Type")));
public void readCustomDataFromNbt(NbtCompound nbt) {
super.readCustomDataFromNbt(nbt);

Optional.ofNullable(Identifier.tryParse(nbt.getString(VARIANT_KEY)))
.map(variantId -> RegistryKey.of(PromenadeRegistryKeys.SUNKEN_VARIANT, variantId))
.flatMap(variantKey -> this.getRegistryManager().get(PromenadeRegistryKeys.SUNKEN_VARIANT).getEntry(variantKey))
.ifPresent(this::setVariant);
}

public SunkenEntity.Type getVariant() {
return SunkenEntity.Type.fromId(this.dataTracker.get(SUNKEN_TYPE));
@Override
public RegistryEntry<SunkenVariant> getVariant() {
return this.dataTracker.get(VARIANT);
}

private void setVariant(SunkenEntity.Type type) {
this.dataTracker.set(SUNKEN_TYPE, type.getIndex());
@Override
public void setVariant(RegistryEntry<SunkenVariant> variant) {
this.dataTracker.set(VARIANT, variant);
}

public boolean isCharging() {
Expand Down Expand Up @@ -336,6 +348,15 @@ public void setTargetingUnderwater(boolean targetingUnderwater) {
this.targetingUnderwater = targetingUnderwater;
}

public Identifier getTexture() {
return this.getVariant().value().texture();
}

@Override
protected RegistryKey<LootTable> getLootTableId() {
return this.getVariant().value().lootTable();
}

public enum State {
CROSSBOW_HOLD,
CROSSBOW_CHARGE,
Expand All @@ -344,41 +365,6 @@ public enum State {
NEUTRAL
}

public enum Type {
BUBBLE(0, "bubble"),
FIRE(1, "fire"),
HORN(2, "horn");

private static final SunkenEntity.Type[] typeList = Arrays.stream(values()).sorted(Comparator.comparing(SunkenEntity.Type::getIndex)).toArray(SunkenEntity.Type[]::new);
private static final Map<String, SunkenEntity.Type> TYPES_BY_NAME = Arrays.stream(values()).collect(Collectors.toMap(SunkenEntity.Type::getName, (type) -> type));
private final int index;
private final String name;

Type(int indexIn, String nameIn) {
this.index = indexIn;
this.name = nameIn;
}

public static SunkenEntity.Type byName(String name) {
return TYPES_BY_NAME.getOrDefault(name, BUBBLE);
}

public static SunkenEntity.Type fromId(int index) {
if (index < 0 || index > typeList.length) {
index = 0;
}
return typeList[index];
}

public String getName() {
return this.name;
}

public int getIndex() {
return this.index;
}
}

static class SunkenMoveControl extends MoveControl {
private final SunkenEntity sunken;

Expand Down
54 changes: 54 additions & 0 deletions src/main/java/fr/hugman/promenade/entity/SunkenVariant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package fr.hugman.promenade.entity;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.loot.LootTable;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;

import java.util.Objects;

public final class SunkenVariant {
public static final Codec<SunkenVariant> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Identifier.CODEC.fieldOf("texture").forGetter(sunken -> sunken.texture),
RegistryKey.createCodec(RegistryKeys.LOOT_TABLE).fieldOf("loot_table").forGetter(sunken -> sunken.lootTable)
).apply(instance, SunkenVariant::new));

private final Identifier texture;
private final RegistryKey<LootTable> lootTable;

private final Identifier texturePath;

public SunkenVariant(Identifier texture, RegistryKey<LootTable> lootTable) {
this.texture = texture;
this.lootTable = lootTable;

this.texturePath = getTexturePath(texture);
}

public Identifier texture() {
return texturePath;
}

public RegistryKey<LootTable> lootTable() {
return lootTable;
}

private static Identifier getTexturePath(Identifier id) {
return id.withPath(oldPath -> "textures/" + oldPath + ".png");
}

@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (SunkenVariant) obj;
return Objects.equals(this.texture, that.texture);
}

@Override
public int hashCode() {
return Objects.hash(texture);
}
}
18 changes: 18 additions & 0 deletions src/main/java/fr/hugman/promenade/entity/SunkenVariants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package fr.hugman.promenade.entity;

import fr.hugman.promenade.Promenade;
import fr.hugman.promenade.registry.PromenadeRegistryKeys;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier;

public class SunkenVariants {
public static final RegistryKey<SunkenVariant> BUBBLE = of("bubble");

private static RegistryKey<SunkenVariant> of(String path) {
return of(Promenade.id(path));
}

public static RegistryKey<SunkenVariant> of(Identifier id) {
return RegistryKey.of(PromenadeRegistryKeys.SUNKEN_VARIANT, id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import fr.hugman.promenade.entity.CapybaraEntity;
import fr.hugman.promenade.entity.CapybaraVariant;
import fr.hugman.promenade.entity.SunkenVariant;
import fr.hugman.promenade.registry.PromenadeRegistryKeys;
import net.minecraft.entity.data.TrackedDataHandler;
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
Expand All @@ -12,6 +13,7 @@

public class PromenadeTrackedData {
public static final TrackedDataHandler<RegistryEntry<CapybaraVariant>> CAPYBARA_VARIANT = of(PacketCodecs.registryEntry(PromenadeRegistryKeys.CAPYBARA_VARIANT));
public static final TrackedDataHandler<RegistryEntry<SunkenVariant>> SUNKEN_VARIANT = of(PacketCodecs.registryEntry(PromenadeRegistryKeys.SUNKEN_VARIANT));
public static final TrackedDataHandler<CapybaraEntity.State> CAPYBARA_STATE = of(CapybaraEntity.State.PACKET_CODEC);

public static <T> TrackedDataHandler<T> of(PacketCodec<? super RegistryByteBuf, T> codec) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package fr.hugman.promenade.registry;

import fr.hugman.promenade.entity.CapybaraVariant;
import fr.hugman.promenade.entity.SunkenVariant;
import net.fabricmc.fabric.api.event.registry.DynamicRegistries;

public class PromenadeRegistries {
public static void register() {
DynamicRegistries.registerSynced(PromenadeRegistryKeys.CAPYBARA_VARIANT, CapybaraVariant.CODEC);
DynamicRegistries.registerSynced(PromenadeRegistryKeys.SUNKEN_VARIANT, SunkenVariant.CODEC);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import fr.hugman.promenade.Promenade;
import fr.hugman.promenade.entity.CapybaraVariant;
import fr.hugman.promenade.entity.SunkenVariant;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;

public class PromenadeRegistryKeys {
public static final RegistryKey<Registry<CapybaraVariant>> CAPYBARA_VARIANT = RegistryKey.ofRegistry(Promenade.id("capybara_variant"));
public static final RegistryKey<Registry<SunkenVariant>> SUNKEN_VARIANT = RegistryKey.ofRegistry(Promenade.id("sunken_variant"));
}
Loading

0 comments on commit bf4d60a

Please sign in to comment.