i will be doing many things not 'armor' in the armor branch

This commit is contained in:
petrak@ 2023-05-03 14:21:03 -05:00
parent 1c1db918fe
commit 4a729ef2d8
25 changed files with 327 additions and 269 deletions

View file

@ -12,14 +12,20 @@ import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ArmorMaterial;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.phys.Vec3;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
@ -158,6 +164,54 @@ public interface HexAPI {
return FrozenPigment.DEFAULT.get();
}
ArmorMaterial DUMMY_ARMOR_MATERIAL = new ArmorMaterial() {
@Override
public int getDurabilityForSlot(@NotNull EquipmentSlot slot) {
return 0;
}
@Override
public int getDefenseForSlot(@NotNull EquipmentSlot slot) {
return 0;
}
@Override
public int getEnchantmentValue() {
return 0;
}
@NotNull
@Override
public SoundEvent getEquipSound() {
return SoundEvents.ARMOR_EQUIP_LEATHER;
}
@NotNull
@Override
public Ingredient getRepairIngredient() {
return Ingredient.EMPTY;
}
@Override
public String getName() {
return "missingno";
}
@Override
public float getToughness() {
return 0;
}
@Override
public float getKnockbackResistance() {
return 0;
}
};
default ArmorMaterial robesMaterial() {
return DUMMY_ARMOR_MATERIAL;
}
/**
* Location in the userdata of the ravenmind
*/

View file

@ -2,7 +2,6 @@ package at.petrak.hexcasting.api.client;
import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
@ -11,18 +10,12 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BeehiveBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -36,84 +29,6 @@ public final class ScryingLensOverlayRegistry {
// vectors are thread-safe!
private static final List<Pair<OverlayPredicate, OverlayBuilder>> PREDICATE_LOOKUP = new Vector<>();
// implemented as a map to allow for weak dereferencing
private static final Map<Player, Pair<BlockPos, Integer>> comparatorData = new WeakHashMap<>();
private static final Map<Player, Pair<BlockPos, Integer>> beeData = new WeakHashMap<>();
public static void receiveComparatorAndBeeValue(BlockPos pos, int comparator, int bee) {
Player player = Minecraft.getInstance().player;
if (player != null) {
if (pos == null || comparator == -1) {
comparatorData.remove(player);
} else {
comparatorData.put(player, new Pair<>(pos, comparator));
}
if (pos == null || bee == -1) {
beeData.remove(player);
} else {
beeData.put(player, new Pair<>(pos, bee));
}
}
}
public static int getComparatorValue(boolean onlyRealComparators) {
var mc = Minecraft.getInstance();
var player = mc.player;
var level = mc.level;
var result = mc.hitResult;
if (player == null || level == null || result == null || result.getType() != HitResult.Type.BLOCK) {
return -1;
}
var comparatorValue = comparatorData.get(player);
if (comparatorValue == null) {
return -1;
}
var pos = ((BlockHitResult) result).getBlockPos();
if (!pos.equals(comparatorValue.getFirst())) {
return -1;
}
var state = mc.level.getBlockState(pos);
if ((onlyRealComparators && !state.is(
Blocks.COMPARATOR)) || (!onlyRealComparators && !state.hasAnalogOutputSignal())) {
return -1;
}
return comparatorValue.getSecond();
}
public static int getBeeValue() {
var mc = Minecraft.getInstance();
var player = mc.player;
var level = mc.level;
var result = mc.hitResult;
if (player == null || level == null || result == null || result.getType() != HitResult.Type.BLOCK) {
return -1;
}
var beeValue = beeData.get(player);
if (beeValue == null) {
return -1;
}
var pos = ((BlockHitResult) result).getBlockPos();
if (!pos.equals(beeValue.getFirst())) {
return -1;
}
var state = mc.level.getBlockState(pos);
if (!(state.getBlock() instanceof BeehiveBlock)) {
return -1;
}
return beeValue.getSecond();
}
/**
* Add the block to display things when the player is holding a lens and looking at it.
*

View file

@ -8,7 +8,6 @@ import at.petrak.hexcasting.api.casting.math.HexAngle
import at.petrak.hexcasting.api.casting.math.HexCoord
import at.petrak.hexcasting.api.casting.math.HexDir
import at.petrak.hexcasting.api.casting.math.HexPattern
import at.petrak.hexcasting.api.misc.DiscoveryHandlers
import at.petrak.hexcasting.api.mod.HexConfig
import at.petrak.hexcasting.api.mod.HexTags
import at.petrak.hexcasting.api.utils.asTranslatedComponent
@ -17,6 +16,7 @@ import at.petrak.hexcasting.client.ShiftScrollListener
import at.petrak.hexcasting.client.ktxt.accumulatedScroll
import at.petrak.hexcasting.client.render.*
import at.petrak.hexcasting.client.sound.GridSoundInstance
import at.petrak.hexcasting.common.lib.HexAttributes
import at.petrak.hexcasting.common.lib.HexSounds
import at.petrak.hexcasting.common.msgs.MsgNewSpellPatternC2S
import at.petrak.hexcasting.xplat.IClientXplatAbstractions
@ -452,12 +452,12 @@ class GuiSpellcasting constructor(
/** Distance between adjacent hex centers */
fun hexSize(): Float {
val scaleModifier = DiscoveryHandlers.gridScaleModifier(Minecraft.getInstance().player)
val scaleModifier = Minecraft.getInstance().player!!.getAttributeValue(HexAttributes.GRID_ZOOM)
// Originally, we allowed 32 dots across. Assuming a 1920x1080 screen this allowed like 500-odd area.
// Let's be generous and give them 512.
val baseScale = sqrt(this.width.toDouble() * this.height / 512.0)
return baseScale.toFloat() * scaleModifier
return (baseScale / scaleModifier).toFloat()
}
fun coordsOffset(): Vec2 = Vec2(this.width.toFloat() * 0.5f, this.height.toFloat() * 0.5f)

View file

@ -1,4 +1,4 @@
package at.petrak.hexcasting.client.render;
package at.petrak.hexcasting.client.model;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import com.mojang.blaze3d.vertex.PoseStack;

View file

@ -1,4 +1,4 @@
package at.petrak.hexcasting.client.render;
package at.petrak.hexcasting.client.model;
import net.minecraft.client.model.ElytraModel;
import net.minecraft.client.model.geom.ModelLayerLocation;
@ -13,6 +13,8 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc;
public class HexModelLayers {
public static final ModelLayerLocation ALTIORA = make("altiora");
public static final ModelLayerLocation ROBES = make("robes");
private static ModelLayerLocation make(String name) {
return make(name, "main");
}
@ -23,8 +25,10 @@ public class HexModelLayers {
return new ModelLayerLocation(modLoc(name), layer);
}
// combine with https://github.com/VazkiiMods/Botania/blob/1.19.x/Xplat/src/main/java/vazkii/botania/client/model/BotaniaLayerDefinitions.java
// moving this stuff into the same file:
// https://github.com/VazkiiMods/Botania/blob/1.19.x/Xplat/src/main/java/vazkii/botania/client/model/BotaniaLayerDefinitions.java
public static void init(BiConsumer<ModelLayerLocation, Supplier<LayerDefinition>> consumer) {
consumer.accept(ALTIORA, ElytraModel::createLayer);
consumer.accept(ROBES, HexRobesModels::variant1);
}
}

View file

@ -0,0 +1,70 @@
package at.petrak.hexcasting.client.model;
// Made with Blockbench 4.6.1
// Exported for Minecraft version 1.17 or later with Mojang mappings
// Paste this class into your mod and generate all required imports
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.PartPose;
import net.minecraft.client.model.geom.builders.*;
import static at.petrak.hexcasting.api.HexAPI.modLoc;
public class HexRobesModels {
// This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into
// this model's constructor
public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(modLoc("robes"), "main");
public static LayerDefinition variant1() {
MeshDefinition meshdefinition = new MeshDefinition();
PartDefinition partdefinition = meshdefinition.getRoot();
PartDefinition Hood = partdefinition.addOrReplaceChild("Hood",
CubeListBuilder.create()
.texOffs(0, 0).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 8.0F, 8.0F, new CubeDeformation(0.0F))
.texOffs(0, 16).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 8.0F, 8.0F, new CubeDeformation(0.0F)),
PartPose.offset(4.0F, -8.0F, -4.0F));
PartDefinition Horns = partdefinition.addOrReplaceChild("Horns",
CubeListBuilder.create()
.texOffs(24, 0).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 4.0F, 0.0F, new CubeDeformation(0.0F))
.texOffs(24, 0).mirror().addBox(9.5F, 0.0F, 0.0F, 8.0F, 4.0F, 0.0F, new CubeDeformation(0.0F))
.mirror(false),
PartPose.offset(-4.8F, -8.2F, 0.0F));
PartDefinition Torso = partdefinition.addOrReplaceChild("Torso",
CubeListBuilder.create()
.texOffs(40, 0).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(40, 16).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)),
PartPose.offset(4.0F, 0.0F, -2.0F));
PartDefinition Arms = partdefinition.addOrReplaceChild("Arms",
CubeListBuilder.create()
.texOffs(0, 32).addBox(-4.0F, 0.0F, 0.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(0, 32).mirror().addBox(8.0F, 0.0F, 0.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.mirror(false),
PartPose.offset(-4.0F, 0.0F, -2.0F));
PartDefinition Skirt = partdefinition.addOrReplaceChild("Skirt", CubeListBuilder.create(),
PartPose.offset(0.0F, 12.0F, -2.0F));
PartDefinition Left_r1 = Skirt.addOrReplaceChild("Left_r1",
CubeListBuilder.create()
.texOffs(48, 32).mirror().addBox(0.1F, 0.0F, -4.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.mirror(false),
PartPose.offsetAndRotation(0.0F, 0.0F, 4.0F, 0.0F, 0.0F, -0.1309F));
PartDefinition Right_r1 = Skirt.addOrReplaceChild("Right_r1",
CubeListBuilder.create()
.texOffs(48, 32).addBox(-4.0F, 0.0F, -4.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)),
PartPose.offsetAndRotation(0.0F, 0.0F, 4.0F, 0.0F, 0.0F, 0.1309F));
PartDefinition Legs = partdefinition.addOrReplaceChild("Legs",
CubeListBuilder.create().texOffs(16, 41)
.addBox(-4.0F, 0.0F, 0.0F, 4.0F, 3.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(16, 41).addBox(0.0F, 0.0F, 0.0F, 4.0F, 3.0F, 4.0F, new CubeDeformation(0.0F)),
PartPose.offset(0.0F, 21.0F, -2.0F));
return LayerDefinition.create(meshdefinition, 64, 64);
}
}

View file

@ -1,4 +1,4 @@
package at.petrak.hexcasting.client.model.armor;
package at.petrak.hexcasting.client.model;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;

View file

@ -1,9 +1,9 @@
package at.petrak.hexcasting.client.render;
import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
import at.petrak.hexcasting.api.misc.DiscoveryHandlers;
import at.petrak.hexcasting.api.player.Sentinel;
import at.petrak.hexcasting.client.ClientTickCounter;
import at.petrak.hexcasting.common.lib.HexAttributes;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.platform.GlStateManager;
@ -157,7 +157,7 @@ public class HexAdditionalRenderers {
return;
}
if (!DiscoveryHandlers.hasLens(player))
if (player.getAttributeValue(HexAttributes.SCRY_SIGHT) <= 0.0)
return;
var hitRes = mc.hitResult;

View file

@ -6,7 +6,6 @@ import at.petrak.hexcasting.api.casting.iota.IotaType;
import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf;
import at.petrak.hexcasting.common.lib.HexBlocks;
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
import com.mojang.datafixers.util.Pair;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
@ -72,7 +71,7 @@ public class ScryingLensOverlays {
ScryingLensOverlayRegistry.addDisplayer(Blocks.COMPARATOR,
(lines, state, pos, observer, world, direction) -> {
int comparatorValue = ScryingLensOverlayRegistry.getComparatorValue(true);
int comparatorValue = state.getAnalogOutputSignal(world, pos);
lines.add(new Pair<>(
new ItemStack(Items.REDSTONE),
Component.literal(comparatorValue == -1 ? "" : String.valueOf(comparatorValue))
@ -101,17 +100,6 @@ public class ScryingLensOverlays {
Component.literal(String.valueOf(state.getValue(RepeaterBlock.DELAY)))
.withStyle(ChatFormatting.YELLOW))));
ScryingLensOverlayRegistry.addPredicateDisplayer(
(state, pos, observer, world, direction) -> state.getBlock() instanceof BeehiveBlock,
(lines, state, pos, observer, world, direction) -> {
int count = ScryingLensOverlayRegistry.getBeeValue();
lines.add(new Pair<>(new ItemStack(Items.BEE_NEST), count == -1 ? Component.empty() :
Component.translatable(
"hexcasting.tooltip.lens.bee" + (count == 1 ? ".single" : ""),
count
)));
});
ScryingLensOverlayRegistry.addPredicateDisplayer(
(state, pos, observer, world, direction) -> state.isSignalSource() && !state.is(
Blocks.COMPARATOR),
@ -130,17 +118,6 @@ public class ScryingLensOverlays {
Component.literal(String.valueOf(signalStrength))
.withStyle(redstoneColor(signalStrength))));
});
ScryingLensOverlayRegistry.addPredicateDisplayer(
(state, pos, observer, world, direction) -> state.hasAnalogOutputSignal(),
(lines, state, pos, observer, world, direction) -> {
int comparatorValue = ScryingLensOverlayRegistry.getComparatorValue(false);
lines.add(
new Pair<>(
new ItemStack(Items.COMPARATOR),
Component.literal(comparatorValue == -1 ? "" : String.valueOf(comparatorValue))
.withStyle(redstoneColor(comparatorValue))));
});
}
private static int getPoweredRailStrength(Level level, BlockPos pos, BlockState state) {

View file

@ -6,12 +6,18 @@ import at.petrak.hexcasting.api.pigment.FrozenPigment;
import at.petrak.hexcasting.api.player.Sentinel;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ArmorMaterial;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.ConcurrentHashMap;
@ -88,4 +94,53 @@ public class HexAPIImpl implements HexAPI {
public FrozenPigment getColorizer(Player player) {
return IXplatAbstractions.INSTANCE.getColorizer(player);
}
ArmorMaterial ARMOR_MATERIAL = new ArmorMaterial() {
@Override
public int getDurabilityForSlot(@NotNull EquipmentSlot slot) {
return 0;
}
@Override
public int getDefenseForSlot(@NotNull EquipmentSlot slot) {
return 0;
}
@Override
public int getEnchantmentValue() {
return 0;
}
@NotNull
@Override
public SoundEvent getEquipSound() {
return SoundEvents.ARMOR_EQUIP_LEATHER;
}
@NotNull
@Override
public Ingredient getRepairIngredient() {
return Ingredient.EMPTY;
}
@Override
public String getName() {
return "robes";
}
@Override
public float getToughness() {
return 0;
}
@Override
public float getKnockbackResistance() {
return 0;
}
};
@Override
public ArmorMaterial robesMaterial() {
return ARMOR_MATERIAL;
}
}

View file

@ -1,47 +1,33 @@
package at.petrak.hexcasting.common.items;
import at.petrak.hexcasting.annotations.SoftImplement;
import at.petrak.hexcasting.api.misc.DiscoveryHandlers;
import at.petrak.hexcasting.common.lib.HexItems;
import at.petrak.hexcasting.common.msgs.MsgUpdateComparatorVisualsS2C;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.BlockPos;
import at.petrak.hexcasting.common.lib.HexAttributes;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import net.minecraft.core.BlockSource;
import net.minecraft.core.dispenser.OptionalDispenseItemBehavior;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Wearable;
import net.minecraft.world.level.block.BeehiveBlock;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.UUID;
public class ItemLens extends Item implements Wearable {
static {
DiscoveryHandlers.addLensPredicate(player -> player.getItemBySlot(EquipmentSlot.MAINHAND).is(HexItems.SCRYING_LENS));
DiscoveryHandlers.addLensPredicate(player -> player.getItemBySlot(EquipmentSlot.OFFHAND).is(HexItems.SCRYING_LENS));
DiscoveryHandlers.addLensPredicate(player -> player.getItemBySlot(EquipmentSlot.HEAD).is(HexItems.SCRYING_LENS));
DiscoveryHandlers.addGridScaleModifier(player -> player.getItemBySlot(EquipmentSlot.MAINHAND).is(HexItems.SCRYING_LENS) ? 0.75f : 1);
DiscoveryHandlers.addGridScaleModifier(player -> player.getItemBySlot(EquipmentSlot.OFFHAND).is(HexItems.SCRYING_LENS) ? 0.75f : 1);
}
public static final AttributeModifier GRID_ZOOM = new AttributeModifier(
UUID.fromString("59d739b8-d419-45f7-a4ea-0efee0e3adf5"),
"Scrying Lens Zoom", 1.25, AttributeModifier.Operation.MULTIPLY_BASE);
public static final AttributeModifier SCRY_SIGHT = new AttributeModifier(
UUID.fromString("e2e6e5d4-f978-4c11-8fdc-82a5af83385c"),
"Scrying Lens Sight", 1.0, AttributeModifier.Operation.ADDITION);
public ItemLens(Properties pProperties) {
super(pProperties);
@ -54,6 +40,16 @@ public class ItemLens extends Item implements Wearable {
});
}
@Override
public Multimap<Attribute, AttributeModifier> getDefaultAttributeModifiers(EquipmentSlot slot) {
var out = HashMultimap.create(super.getDefaultAttributeModifiers(slot));
if (slot == EquipmentSlot.HEAD || slot == EquipmentSlot.MAINHAND || slot == EquipmentSlot.OFFHAND) {
out.put(HexAttributes.GRID_ZOOM, GRID_ZOOM);
out.put(HexAttributes.SCRY_SIGHT, SCRY_SIGHT);
}
return out;
}
// In fabric impled with extension property?
@Nullable
@SoftImplement("forge")
@ -61,67 +57,6 @@ public class ItemLens extends Item implements Wearable {
return EquipmentSlot.HEAD;
}
public static void tickAllPlayers(ServerLevel world) {
for (ServerPlayer player : world.players()) {
tickLens(player);
}
}
public static void tickLens(Entity pEntity) {
if (!pEntity.getLevel().isClientSide() && pEntity instanceof ServerPlayer player && DiscoveryHandlers.hasLens(player)) {
sendComparatorDataToClient(player);
}
}
private static final Map<ServerPlayer, Pair<BlockPos, Integer>> comparatorDataMap = new WeakHashMap<>();
private static final Map<ServerPlayer, Pair<BlockPos, Integer>> beeDataMap = new WeakHashMap<>();
private static void sendComparatorDataToClient(ServerPlayer player) {
double reachAttribute = IXplatAbstractions.INSTANCE.getReachDistance(player);
double distance = player.isCreative() ? reachAttribute : reachAttribute - 0.5;
var hitResult = player.pick(distance, 0, false);
if (hitResult.getType() == HitResult.Type.BLOCK) {
var pos = ((BlockHitResult) hitResult).getBlockPos();
var state = player.level.getBlockState(pos);
int bee = -1;
if (state.getBlock() instanceof BeehiveBlock && player.level.getBlockEntity(pos) instanceof BeehiveBlockEntity bees) {
bee = bees.getOccupantCount();
}
if (state.is(Blocks.COMPARATOR)) {
syncComparatorValue(player, pos,
state.getDirectSignal(player.level, pos, state.getValue(BlockStateProperties.HORIZONTAL_FACING)),
bee);
} else if (state.hasAnalogOutputSignal()) {
syncComparatorValue(player, pos, state.getAnalogOutputSignal(player.level, pos), bee);
} else {
syncComparatorValue(player, null, -1, bee);
}
} else {
syncComparatorValue(player, null, -1, -1);
}
}
private static void syncComparatorValue(ServerPlayer player, BlockPos pos, int comparator, int bee) {
var previousComparator = comparatorDataMap.get(player);
var previousBee = beeDataMap.get(player);
if (comparator == -1 && bee == -1) {
if (previousComparator != null || previousBee != null) {
comparatorDataMap.remove(player);
beeDataMap.remove(player);
IXplatAbstractions.INSTANCE.sendPacketToPlayer(player, new MsgUpdateComparatorVisualsS2C(null, -1, -1));
}
} else if (previousComparator == null || !pos.equals(previousComparator.getFirst()) || comparator != previousComparator.getSecond() ||
previousBee == null || !pos.equals(previousBee.getFirst()) || bee != previousBee.getSecond()) {
comparatorDataMap.put(player, new Pair<>(pos, comparator));
beeDataMap.put(player, new Pair<>(pos, bee));
IXplatAbstractions.INSTANCE.sendPacketToPlayer(player, new MsgUpdateComparatorVisualsS2C(pos, comparator,
bee));
}
}
@Nullable
@Override
public SoundEvent getEquipSound() {

View file

@ -0,0 +1,19 @@
package at.petrak.hexcasting.common.items.armor;
import at.petrak.hexcasting.api.HexAPI;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ArmorItem;
/**
* To get the armor model in;
* On forge: cursed self-mixin
* On fabric: hook in ClientInit
*/
public class ItemRobes extends ArmorItem {
public final EquipmentSlot slot;
public ItemRobes(EquipmentSlot slot, Properties properties) {
super(HexAPI.instance().robesMaterial(), slot, properties);
this.slot = slot;
}
}

View file

@ -0,0 +1,43 @@
package at.petrak.hexcasting.common.lib;
import at.petrak.hexcasting.api.HexAPI;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.RangedAttribute;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import static at.petrak.hexcasting.api.HexAPI.modLoc;
/**
* On forge: these are setup in ForgeHexInit
* On fabric: it's a mixin
*/
public class HexAttributes {
public static void register(BiConsumer<Attribute, ResourceLocation> r) {
for (var e : ATTRIBUTES.entrySet()) {
r.accept(e.getValue(), e.getKey());
}
}
private static final Map<ResourceLocation, Attribute> ATTRIBUTES = new LinkedHashMap<>();
public static final Attribute GRID_ZOOM = make("grid_zoom", new RangedAttribute(
HexAPI.MOD_ID + ".attributes.grid_zoom", 1.0, 0.5, 4.0)).setSyncable(true);
/**
* Whether you have the lens overlay when looking at something. 0 = no, > 0 = yes.
*/
public static final Attribute SCRY_SIGHT = make("scry_sight", new RangedAttribute(
HexAPI.MOD_ID + ".attributes.scry_sight", 0.0, 0.0, 1.0)).setSyncable(true);
private static <T extends Attribute> T make(String id, T attr) {
var old = ATTRIBUTES.put(modLoc(id), attr);
if (old != null) {
throw new IllegalArgumentException("Typo? Duplicate id " + id);
}
return attr;
}
}

View file

@ -4,6 +4,7 @@ import at.petrak.hexcasting.common.items.ItemJewelerHammer;
import at.petrak.hexcasting.common.items.ItemLens;
import at.petrak.hexcasting.common.items.ItemLoreFragment;
import at.petrak.hexcasting.common.items.ItemStaff;
import at.petrak.hexcasting.common.items.armor.ItemRobes;
import at.petrak.hexcasting.common.items.colorizer.ItemAmethystAndCopperColorizer;
import at.petrak.hexcasting.common.items.colorizer.ItemDyeColorizer;
import at.petrak.hexcasting.common.items.colorizer.ItemPrideColorizer;
@ -99,6 +100,9 @@ public class HexItems {
public static final Item DEFAULT_COLORIZER = make("default_colorizer",
new ItemAmethystAndCopperColorizer(unstackable()));
public static final ItemRobes ARMOR_HOOD = make("robes",
new ItemRobes(EquipmentSlot.HEAD, unstackable()));
// BUFF SANDVICH
public static final Item SUBMARINE_SANDWICH = make("sub_sandwich",
new Item(props().food(new FoodProperties.Builder().nutrition(14).saturationMod(1.2f).build())));

View file

@ -1,51 +0,0 @@
package at.petrak.hexcasting.common.msgs;
import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import static at.petrak.hexcasting.api.HexAPI.modLoc;
/**
* Sent server->client when a player is looking at a block through a lens whose comparator value is not the same as
* what they last saw.
*/
public record MsgUpdateComparatorVisualsS2C(BlockPos pos, int comparator, int bee) implements IMessage {
public static final ResourceLocation ID = modLoc("cmp");
@Override
public ResourceLocation getFabricId() {
return ID;
}
public static MsgUpdateComparatorVisualsS2C deserialize(ByteBuf buffer) {
var buf = new FriendlyByteBuf(buffer);
int comparator = buf.readInt();
int bee = buf.readInt();
BlockPos pos = comparator == -1 && bee == -1 ? null : buf.readBlockPos();
return new MsgUpdateComparatorVisualsS2C(pos, comparator, bee);
}
public void serialize(FriendlyByteBuf buf) {
buf.writeInt(this.comparator);
buf.writeInt(this.bee);
if (this.comparator != -1 || this.bee != -1) {
buf.writeBlockPos(this.pos);
}
}
public static void handle(MsgUpdateComparatorVisualsS2C msg) {
Minecraft.getInstance().execute(new Runnable() {
@Override
public void run() {
ScryingLensOverlayRegistry.receiveComparatorAndBeeValue(msg.pos(), msg.comparator(), msg.bee());
}
});
}
}

View file

@ -1,6 +1,6 @@
package at.petrak.hexcasting.mixin.client;
import at.petrak.hexcasting.client.render.AltioraLayer;
import at.petrak.hexcasting.client.model.AltioraLayer;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;

View file

@ -330,6 +330,12 @@
"flight.finish": "Flight ends",
},
attributes: {
grid_zoom: "Casting Grid Size",
// TODO: the +1 is kind of janky
scry_sight: "Scrying Sight"
},
// Actual hexcasting stuff
action: {

View file

@ -4,8 +4,8 @@ import at.petrak.hexcasting.client.ClientTickCounter
import at.petrak.hexcasting.client.RegisterClientStuff
import at.petrak.hexcasting.client.ShiftScrollListener
import at.petrak.hexcasting.client.gui.PatternTooltipComponent
import at.petrak.hexcasting.client.model.HexModelLayers
import at.petrak.hexcasting.client.render.HexAdditionalRenderers
import at.petrak.hexcasting.client.render.HexModelLayers
import at.petrak.hexcasting.common.casting.PatternRegistryManifest
import at.petrak.hexcasting.common.lib.HexParticles
import at.petrak.hexcasting.fabric.event.MouseScrollCallback

View file

@ -14,7 +14,6 @@ import at.petrak.hexcasting.common.casting.operators.spells.great.OpAltiora
import at.petrak.hexcasting.common.command.PatternResLocArgument
import at.petrak.hexcasting.common.entities.HexEntities
import at.petrak.hexcasting.common.items.ItemJewelerHammer
import at.petrak.hexcasting.common.items.ItemLens
import at.petrak.hexcasting.common.lib.*
import at.petrak.hexcasting.common.lib.hex.HexActions
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
@ -97,7 +96,6 @@ object FabricHexInitializer : ModInitializer {
}
ServerTickEvents.END_WORLD_TICK.register(PlayerPositionRecorder::updateAllPlayers)
ServerTickEvents.END_WORLD_TICK.register(ItemLens::tickAllPlayers)
ServerTickEvents.END_WORLD_TICK.register(OpFlight::tickAllPlayers)
ServerTickEvents.END_WORLD_TICK.register(OpAltiora::checkAllPlayers)
@ -129,6 +127,7 @@ object FabricHexInitializer : ModInitializer {
Registry.register(IngredientDeserializer.REGISTRY, FabricModConditionalIngredient.ID, FabricModConditionalIngredient.Deserializer.INSTANCE)
HexEntities.registerEntities(bind(Registry.ENTITY_TYPE))
HexAttributes.register(bind(Registry.ATTRIBUTE))
HexRecipeStuffRegistry.registerSerializers(bind(Registry.RECIPE_SERIALIZER))
HexRecipeStuffRegistry.registerTypes(bind(Registry.RECIPE_TYPE))

View file

@ -0,0 +1,26 @@
package at.petrak.hexcasting.fabric.mixin;
import at.petrak.hexcasting.common.lib.HexAttributes;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Player.class)
public abstract class FabricPlayerMixin extends LivingEntity {
protected FabricPlayerMixin(EntityType<? extends LivingEntity> entityType, Level level) {
super(entityType, level);
}
@Inject(at = @At("RETURN"), method = "createAttributes")
private static void hex$addAttributes(CallbackInfoReturnable<AttributeSupplier.Builder> cir) {
var out = cir.getReturnValue();
out.add(HexAttributes.GRID_ZOOM);
out.add(HexAttributes.SCRY_SIGHT);
}
}

View file

@ -35,8 +35,6 @@ public class FabricPacketHandler {
makeClientBoundHandler(MsgOpenSpellGuiS2C::deserialize, MsgOpenSpellGuiS2C::handle));
ClientPlayNetworking.registerGlobalReceiver(MsgBeepS2C.ID,
makeClientBoundHandler(MsgBeepS2C::deserialize, MsgBeepS2C::handle));
ClientPlayNetworking.registerGlobalReceiver(MsgUpdateComparatorVisualsS2C.ID,
makeClientBoundHandler(MsgUpdateComparatorVisualsS2C::deserialize, MsgUpdateComparatorVisualsS2C::handle));
ClientPlayNetworking.registerGlobalReceiver(MsgNewWallScrollS2C.ID,
makeClientBoundHandler(MsgNewWallScrollS2C::deserialize, MsgNewWallScrollS2C::handle));
ClientPlayNetworking.registerGlobalReceiver(MsgRecalcWallScrollDisplayS2C.ID,

View file

@ -12,6 +12,7 @@
"FabricLivingEntityMixin",
"FabricMixinReloadableServerResources",
"FabricMobMixin",
"FabricPlayerMixin",
"FabricVillagerTurnIntoWitchMixin"
],
"client": [

View file

@ -4,8 +4,8 @@ import at.petrak.hexcasting.client.ClientTickCounter;
import at.petrak.hexcasting.client.RegisterClientStuff;
import at.petrak.hexcasting.client.ShiftScrollListener;
import at.petrak.hexcasting.client.gui.PatternTooltipComponent;
import at.petrak.hexcasting.client.model.HexModelLayers;
import at.petrak.hexcasting.client.render.HexAdditionalRenderers;
import at.petrak.hexcasting.client.render.HexModelLayers;
import at.petrak.hexcasting.client.render.shader.HexShaders;
import at.petrak.hexcasting.common.casting.PatternRegistryManifest;
import at.petrak.hexcasting.common.lib.HexParticles;

View file

@ -11,7 +11,6 @@ import at.petrak.hexcasting.common.casting.operators.spells.OpFlight;
import at.petrak.hexcasting.common.casting.operators.spells.great.OpAltiora;
import at.petrak.hexcasting.common.entities.HexEntities;
import at.petrak.hexcasting.common.items.ItemJewelerHammer;
import at.petrak.hexcasting.common.items.ItemLens;
import at.petrak.hexcasting.common.lib.*;
import at.petrak.hexcasting.common.lib.hex.HexActions;
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds;
@ -41,6 +40,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity;
@ -52,6 +52,7 @@ import net.minecraftforge.common.ToolActions;
import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.EntityAttributeModificationEvent;
import net.minecraftforge.event.entity.living.LivingConversionEvent;
import net.minecraftforge.event.entity.living.LivingEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
@ -104,6 +105,7 @@ public class ForgeHexInitializer {
bind(Registry.RECIPE_TYPE_REGISTRY, HexRecipeStuffRegistry::registerTypes);
bind(Registry.ENTITY_TYPE_REGISTRY, HexEntities::registerEntities);
bind(Registry.ATTRIBUTE_REGISTRY, HexAttributes::register);
bind(Registry.PARTICLE_TYPE_REGISTRY, HexParticles::registerParticles);
@ -180,7 +182,6 @@ public class ForgeHexInitializer {
if (evt.getEntity() instanceof ServerPlayer splayer) {
OpFlight.tickDownFlight(splayer);
OpAltiora.checkPlayerCollision(splayer);
ItemLens.tickLens(splayer);
}
});
@ -239,6 +240,12 @@ public class ForgeHexInitializer {
modBus.register(ForgeCapabilityHandler.class);
evBus.register(CapSyncers.class);
modBus.addListener((EntityAttributeModificationEvent e) -> {
e.add(EntityType.PLAYER, HexAttributes.GRID_ZOOM);
e.add(EntityType.PLAYER, HexAttributes.SCRY_SIGHT);
});
if (ModList.get().isLoaded(HexInterop.Forge.CURIOS_API_ID)) {
modBus.addListener(CuriosApiInterop::onInterModEnqueue);
modBus.addListener(CuriosApiInterop::onClientSetup);

View file

@ -55,10 +55,6 @@ public class ForgePacketHandler {
MsgBeepS2C::deserialize, makeClientBoundHandler(MsgBeepS2C::handle));
NETWORK.registerMessage(messageIdx++, MsgBrainsweepAck.class, MsgBrainsweepAck::serialize,
MsgBrainsweepAck::deserialize, makeClientBoundHandler(MsgBrainsweepAck::handle));
NETWORK.registerMessage(messageIdx++, MsgUpdateComparatorVisualsS2C.class,
MsgUpdateComparatorVisualsS2C::serialize,
MsgUpdateComparatorVisualsS2C::deserialize,
makeClientBoundHandler(MsgUpdateComparatorVisualsS2C::handle));
NETWORK.registerMessage(messageIdx++, MsgNewWallScrollS2C.class,
MsgNewWallScrollS2C::serialize,
MsgNewWallScrollS2C::deserialize,