diff --git a/build.gradle b/build.gradle index 93366c8b5..6daf20a52 100644 --- a/build.gradle +++ b/build.gradle @@ -3,17 +3,17 @@ import net.darkhax.curseforgegradle.TaskPublishCurseForge import java.text.SimpleDateFormat plugins { - id "maven-publish" + id 'checkstyle' + id 'com.github.breadmoirai.github-release' version '2.5.2' + id 'com.modrinth.minotaur' version '2.+' + id 'java' + id 'maven-publish' id 'net.darkhax.curseforgegradle' version '1.1.16' - id 'org.jetbrains.changelog' version '1.2.1' - id "com.modrinth.minotaur" version "2.+" - id "org.jetbrains.kotlin.jvm" version "1.6.10" id 'net.minecraftforge.gradle' version '[6.0.18,6.2)' + id 'org.jetbrains.changelog' version '1.2.1' + id 'org.jetbrains.kotlin.jvm' version '1.6.10' id 'org.parchmentmc.librarian.forgegradle' version '1.+' id 'org.spongepowered.mixin' version '0.7.+' - id "com.github.breadmoirai.github-release" version "2.5.2" - id 'checkstyle' - id 'java' } java { diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataEntityHandPlugin.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataEntityHandPlugin.java index b7ab0aba4..2139e4ab5 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataEntityHandPlugin.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataEntityHandPlugin.java @@ -76,7 +76,7 @@ public final MethodResult inspectAnimal(@NotNull IArguments arguments) throws Lu if (!(entity instanceof Animal animal)) return MethodResult.of(null, "Well, entity is not animal entity, but how?"); - return MethodResult.of(LuaConverter.animalToLua(animal, owner.getToolInMainHand(), true)); + return MethodResult.of(LuaConverter.completeEntityToLua(animal, owner.getToolInMainHand(), true)); } @LuaFunction(mainThread = true) diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/LuaConverter.java b/src/main/java/de/srendi/advancedperipherals/common/util/LuaConverter.java index 4c0dd08ad..aa9690e88 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/LuaConverter.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/LuaConverter.java @@ -22,6 +22,7 @@ import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.phys.Vec3; +import net.minecraft.world.scores.Team; import net.minecraftforge.common.IForgeShearable; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidType; @@ -45,75 +46,87 @@ public class LuaConverter { private static final CompoundTag EMPTY_TAG = new CompoundTag(); + private static final Map, List>> ENTITY_CONVERTERS = new HashMap<>(); - public static Map entityToLua(Entity entity) { - Map data = new HashMap<>(); - data.put("id", entity.getId()); - data.put("uuid", entity.getStringUUID()); - if (entity.hasCustomName()) - data.put("customName", entity.getCustomName().getString()); - EntityType type = entity.getType(); - data.put("displayName", type.getDescription().getString()); - data.put("name", type.builtInRegistryHolder().key().location().toString()); - data.put("type", type.getDescriptionId()); - data.put("category", type.getCategory()); - data.put("canBurn", entity.fireImmune()); - data.put("canFreeze", entity.canFreeze()); - data.put("isGlowing", entity.isCurrentlyGlowing()); - data.put("isUnderWater", entity.isUnderWater()); - data.put("isInLava", entity.isInLava()); - data.put("isInWall", entity.isInWall()); - return data; + /** + * registerEntityConverter register a converter for a type of entity. + * If an old converter exists, it will invoke the old one first before invoke the new converter. + * + * @param clazz The entity's class + * @param converter The {@link EntityConverter} + */ + public static void registerEntityConverter(Class clazz, EntityConverter converter) { + ENTITY_CONVERTERS.computeIfAbsent(clazz, (k) -> new ArrayList<>(1)).add(converter); } - public static Map livingEntityToLua(LivingEntity entity, boolean detailed) { - Map data = entityToLua(entity); - data.put("baby", entity.isBaby()); - data.put("health", entity.getHealth()); - data.put("maxHealth", entity.getMaxHealth()); - data.put("lastDamageSource", entity.getLastDamageSource() == null ? null : entity.getLastDamageSource().toString()); - if (detailed) { - Map effMap = new HashMap<>(); - entity.getActiveEffectsMap().forEach((key, value) -> { - effMap.put(key.getDescriptionId(), effectToObject(value)); - }); - data.put("effects", effMap); - } - return data; + // register default entity converters + static { + registerEntityConverter(Entity.class, (entity, data, ctx) -> { + data.put("id", entity.getId()); + data.put("uuid", entity.getStringUUID()); + if (entity.hasCustomName()) + data.put("customName", entity.getCustomName().getString()); + EntityType type = entity.getType(); + data.put("displayName", type.getDescription().getString()); + data.put("name", type.builtInRegistryHolder().key().location().toString()); + if (ctx.detailed()) { + data.put("type", type.getDescriptionId()); + data.put("category", type.getCategory().getName()); + data.put("canBurn", entity.fireImmune()); + data.put("canFreeze", entity.canFreeze()); + data.put("tags", entity.getTags()); + data.put("isGlowing", entity.isCurrentlyGlowing()); + data.put("isUnderWater", entity.isUnderWater()); + data.put("isInLava", entity.isInLava()); + data.put("isInWall", entity.isInWall()); + data.put("team", teamToLua(entity.getTeam())); + } + }); + registerEntityConverter(LivingEntity.class, (entity, data, ctx) -> { + data.put("baby", entity.isBaby()); + data.put("health", entity.getHealth()); + data.put("maxHealth", entity.getMaxHealth()); + if (ctx.detailed()) { + data.put("lastDamageSource", entity.getLastDamageSource() == null ? null : entity.getLastDamageSource().toString()); + Map effMap = new HashMap<>(); + entity.getActiveEffectsMap().forEach((key, value) -> { + effMap.put(key.getDescriptionId(), effectToLua(value)); + }); + data.put("effects", effMap); + } + }); + registerEntityConverter(Mob.class, (entity, data, ctx) -> { + data.put("aggressive", entity.isAggressive()); + }); + registerEntityConverter(Animal.class, (entity, data, ctx) -> { + data.put("inLove", entity.isInLove()); + if (ctx.detailed() && !ctx.itemInHand().isEmpty() && entity instanceof IForgeShearable shareable) { + data.put("shareable", shareable.isShearable(ctx.itemInHand(), entity.level, entity.blockPosition())); + } + }); + registerEntityConverter(Player.class, (entity, data, ctx) -> { + data.put("score", entity.getScore()); + data.put("luck", entity.getLuck()); + Inventory inv = entity.getInventory(); + data.put("handSlot", inv.selected); + if (ctx.detailed()) { + Map invMap = new HashMap<>(); + for (int slot = 0; slot < inv.getContainerSize(); slot++) { + ItemStack item = inv.getItem(slot); + if (!item.isEmpty()) { + invMap.put(slot, itemStackToObject(item)); + } + } + data.put("inventory", invMap); + } + }); } - public static Map mobToLua(Mob animal, boolean detailed) { - Map data = livingEntityToLua(animal, detailed); - data.put("aggressive", animal.isAggressive()); - return data; - } + @FunctionalInterface + public interface EntityConverter { + void entityToMap(T entity, Map data, Context ctx); - public static Map animalToLua(Animal animal, ItemStack itemInHand, boolean detailed) { - Map data = mobToLua(animal, detailed); - data.put("inLove", animal.isInLove()); - if (animal instanceof IForgeShearable shareable && !itemInHand.isEmpty()) { - data.put("shareable", shareable.isShearable(itemInHand, animal.level, animal.blockPosition())); - } - return data; - } - - public static Map playerToLua(Player player, boolean detailed) { - Map data = livingEntityToLua(player, detailed); - data.put("score", player.getScore()); - data.put("luck", player.getLuck()); - Inventory inv = player.getInventory(); - data.put("handSlot", inv.selected); - if (detailed) { - Map invMap = new HashMap<>(); - for (int slot = 0; slot < inv.getContainerSize(); slot++) { - ItemStack item = inv.getItem(slot); - if (!item.isEmpty()) { - invMap.put(slot, itemStackToObject(item)); - } - } - data.put("inventory", invMap); - } - return data; + record Context(boolean detailed, ItemStack itemInHand) {} } public static Map completeEntityToLua(Entity entity) { @@ -129,11 +142,20 @@ public static Map completeEntityToLua(Entity entity, ItemStack i } public static Map completeEntityToLua(Entity entity, ItemStack itemInHand, boolean detailed) { - if (entity instanceof Player player) return playerToLua(player, detailed); - if (entity instanceof Animal animal) return animalToLua(animal, itemInHand, detailed); - if (entity instanceof Mob mob) return mobToLua(mob, detailed); - if (entity instanceof LivingEntity livingEntity) return livingEntityToLua(livingEntity, detailed); - return entityToLua(entity); + if (entity == null) { + return null; + } + EntityConverter.Context ctx = new EntityConverter.Context(detailed, itemInHand); + Map data = new HashMap<>(); + for (Class entityClass = entity.getClass(); Entity.class.isAssignableFrom(entityClass); entityClass = entityClass.getSuperclass()) { + List> converters = ENTITY_CONVERTERS.get((Class) entityClass); + if (converters != null) { + for (EntityConverter converter : converters) { + ((EntityConverter) converter).entityToMap(entity, data, ctx); + } + } + } + return data; } public static Map completeEntityWithPositionToLua(Entity entity, BlockPos pos) { @@ -303,7 +325,7 @@ public static BlockPos convertToBlockPos(BlockPos center, Map table) throw return new BlockPos(center.getX() + relative.getX(), center.getY() + relative.getY(), center.getZ() + relative.getZ()); } - public static Object effectToObject(MobEffectInstance effect) { + public static Map effectToLua(MobEffectInstance effect) { Map map = new HashMap<>(); map.put("name", effect.getDescriptionId()); map.put("duration", effect.getDuration()); @@ -311,6 +333,16 @@ public static Object effectToObject(MobEffectInstance effect) { return map; } + public static Map teamToLua(Team team) { + if (team == null) { + return null; + } + Map map = new HashMap<>(); + map.put("name", team.getName()); + map.put("color", team.getColor()); + return map; + } + public static Map shipToObject(ServerShip ship) { return shipToObject(ship, null); }