Giant frying pan
Many fixes Boogaloo prep Underside eye stars and moon Commanded vfx effect icons fabric crash fixes
No files matched your search
@@ -4,6 +4,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
public interface InfinityCompatBridge {
|
||||
@@ -26,6 +27,10 @@ public interface InfinityCompatBridge {
|
||||
return InfinityWarpResult.REJECTED;
|
||||
}
|
||||
|
||||
default InfinityWarpResult requestDimensionCreation(MinecraftServer server, ResourceLocation dimensionId) {
|
||||
return InfinityWarpResult.REJECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an already-ignited vanilla Nether portal frame at {@code anyPortalBlockPos} into a real, permanent
|
||||
* Infinite Dimensions portal to {@code dimensionId}, generating the dimension first if it doesn't exist yet.
|
||||
|
||||
@@ -156,6 +156,7 @@ public final class AntarchyConfigCatalog {
|
||||
private static boolean isToolSetting(String name) {
|
||||
return name.equals("sizeChangingRaysEnabled")
|
||||
|| name.startsWith("sizeRay")
|
||||
|| name.startsWith("temporalTuner")
|
||||
|| name.equals("shrinkingPotionDelta")
|
||||
|| name.equals("growthPotionDelta")
|
||||
|| name.startsWith("ultimate")
|
||||
|
||||
@@ -30,6 +30,8 @@ public final class AntarchySettings {
|
||||
private static double sizeRayMinScale = 0.1D;
|
||||
private static double sizeRayMaxScale = 10.0D;
|
||||
private static double sizeRayDeltaPerHit = 0.25D;
|
||||
private static double temporalTunerMinRate = 0.1D;
|
||||
private static double temporalTunerMaxRate = 3.0D;
|
||||
private static double shrinkingPotionDelta = 0.3D;
|
||||
private static double growthPotionDelta = 0.5D;
|
||||
private static double antDanceRadius = 5.0D;
|
||||
@@ -229,6 +231,7 @@ public final class AntarchySettings {
|
||||
private static double royalAssailantLeggingsDoubleDamageChance = 0.07D;
|
||||
private static double royalAssailantBootsDoubleDamageChance = 0.05D;
|
||||
private static double royalGuardianSwordAttackDamage = 111.0D;
|
||||
private static double giantFryingPanAttackDamage = 80.0D;
|
||||
private static double royalGuardianSwordAttackSpeed = -2.5D;
|
||||
private static int royalGuardianSwordElementalCooldownTicks = 120;
|
||||
private static double royalGuardianSwordFirePrimaryDamage = 22.0D;
|
||||
@@ -758,6 +761,14 @@ public final class AntarchySettings {
|
||||
return sizeRayDeltaPerHit;
|
||||
}
|
||||
|
||||
public static double temporalTunerMinRate() {
|
||||
return temporalTunerMinRate;
|
||||
}
|
||||
|
||||
public static double temporalTunerMaxRate() {
|
||||
return temporalTunerMaxRate;
|
||||
}
|
||||
|
||||
public static double shrinkingPotionDelta() {
|
||||
return shrinkingPotionDelta;
|
||||
}
|
||||
@@ -1385,6 +1396,14 @@ public final class AntarchySettings {
|
||||
sizeRayDeltaPerHit = value;
|
||||
}
|
||||
|
||||
public static void setTemporalTunerMinRate(double value) {
|
||||
temporalTunerMinRate = value;
|
||||
}
|
||||
|
||||
public static void setTemporalTunerMaxRate(double value) {
|
||||
temporalTunerMaxRate = value;
|
||||
}
|
||||
|
||||
public static void setShrinkingPotionDelta(double value) {
|
||||
shrinkingPotionDelta = value;
|
||||
}
|
||||
@@ -2041,6 +2060,8 @@ public final class AntarchySettings {
|
||||
|
||||
public static double royalGuardianSwordAttackDamage() { return royalGuardianSwordAttackDamage; }
|
||||
public static void setRoyalGuardianSwordAttackDamage(double v) { royalGuardianSwordAttackDamage = v; }
|
||||
public static double giantFryingPanAttackDamage() { return giantFryingPanAttackDamage; }
|
||||
public static void setGiantFryingPanAttackDamage(double v) { giantFryingPanAttackDamage = v; }
|
||||
|
||||
public static double royalGuardianSwordAttackSpeed() { return royalGuardianSwordAttackSpeed; }
|
||||
public static void setRoyalGuardianSwordAttackSpeed(double v) { royalGuardianSwordAttackSpeed = v; }
|
||||
|
||||
@@ -210,6 +210,8 @@ public final class AntarchyObjects {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Supplier<MenuType<com.craisinlord.antarchy.content.menu.RoyalJudgmentMenu>> ROYAL_JUDGMENT_MENU = (Supplier<MenuType<com.craisinlord.antarchy.content.menu.RoyalJudgmentMenu>>) UNBOUND;
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Supplier<MenuType<com.craisinlord.antarchy.content.menu.GiantFryingPanMenu>> GIANT_FRYING_PAN_MENU = (Supplier<MenuType<com.craisinlord.antarchy.content.menu.GiantFryingPanMenu>>) UNBOUND;
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Supplier<net.minecraft.world.item.Item> CHEEP_ITEM = (Supplier<net.minecraft.world.item.Item>) UNBOUND;
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Supplier<Block> DUPLICATOR_LOG = (Supplier<Block>) UNBOUND;
|
||||
@@ -321,6 +323,10 @@ public final class AntarchyObjects {
|
||||
public static Supplier<Holder<MobEffect>> GLIMMERING_EFFECT = (Supplier<Holder<MobEffect>>) UNBOUND;
|
||||
public static Supplier<Holder<MobEffect>> ROYAL_VITALITY_PENALTY_EFFECT = (Supplier<Holder<MobEffect>>) UNBOUND;
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Supplier<Holder<MobEffect>> BLEEDING_EFFECT = (Supplier<Holder<MobEffect>>) UNBOUND;
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Supplier<Holder<MobEffect>> BLOOD_MOON_EFFECT = (Supplier<Holder<MobEffect>>) UNBOUND;
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Supplier<Fluid> LUMEN = (Supplier<Fluid>) UNBOUND;
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Supplier<Fluid> FLOWING_LUMEN = (Supplier<Fluid>) UNBOUND;
|
||||
@@ -824,6 +830,14 @@ public final class AntarchyObjects {
|
||||
ROYAL_VITALITY_PENALTY_EFFECT = supplier;
|
||||
}
|
||||
|
||||
public static void setBleedingEffect(Supplier<Holder<MobEffect>> supplier) {
|
||||
BLEEDING_EFFECT = supplier;
|
||||
}
|
||||
|
||||
public static void setBloodMoonEffect(Supplier<Holder<MobEffect>> supplier) {
|
||||
BLOOD_MOON_EFFECT = supplier;
|
||||
}
|
||||
|
||||
public static void setElka(Supplier<EntityType<com.craisinlord.antarchy.content.entity.ElkaEntity>> supplier) {
|
||||
ELKA = supplier;
|
||||
}
|
||||
@@ -916,6 +930,10 @@ public final class AntarchyObjects {
|
||||
ROYAL_JUDGMENT_MENU = supplier;
|
||||
}
|
||||
|
||||
public static void setGiantFryingPanMenu(Supplier<MenuType<com.craisinlord.antarchy.content.menu.GiantFryingPanMenu>> supplier) {
|
||||
GIANT_FRYING_PAN_MENU = supplier;
|
||||
}
|
||||
|
||||
public static void setAmericanComponent(Supplier<net.minecraft.core.component.DataComponentType<net.minecraft.util.Unit>> supplier) {
|
||||
AMERICAN_COMPONENT = supplier;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ public final class UnderVaultBlockEntity extends BlockEntity {
|
||||
@Override
|
||||
protected void loadAdditional(CompoundTag tag, net.minecraft.core.HolderLookup.Provider registries) {
|
||||
vaultData.loadCustomOnly(tag, registries);
|
||||
vaultData.setConfig(createConfig());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.craisinlord.antarchy.content.client;
|
||||
|
||||
import com.craisinlord.antarchy.content.effect.RoyalEffectHooks;
|
||||
import com.craisinlord.antarchy.content.item.TemporalTunerItem;
|
||||
import com.craisinlord.antarchy.content.time.TimeDilationApi;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
@@ -22,22 +24,19 @@ public final class ContractionAfterimages {
|
||||
}
|
||||
|
||||
public static void tick(ClientLevel level) {
|
||||
Holder<MobEffect> holder = RoyalEffectHooks.contractedHolder();
|
||||
int now = (int) (level.getGameTime() & 0x7fffffffL);
|
||||
|
||||
Iterator<Map.Entry<LivingEntity, Deque<Sample>>> iterator = HISTORY.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
LivingEntity tracked = iterator.next().getKey();
|
||||
if (tracked == null || holder == null || tracked.isRemoved() || !tracked.isAlive()
|
||||
|| !tracked.hasEffect(holder)) {
|
||||
if (tracked == null || tracked.isRemoved() || !tracked.isAlive() || !isActive(tracked)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void observe(LivingEntity living) {
|
||||
Holder<MobEffect> holder = RoyalEffectHooks.contractedHolder();
|
||||
if (holder == null || living.isInvisible() || !living.hasEffect(holder)) {
|
||||
if (!isActive(living)) {
|
||||
return;
|
||||
}
|
||||
int now = (int) (living.level().getGameTime() & 0x7fffffffL);
|
||||
@@ -52,6 +51,15 @@ public final class ContractionAfterimages {
|
||||
return HISTORY.get(entity);
|
||||
}
|
||||
|
||||
public static boolean isActive(LivingEntity living) {
|
||||
Holder<MobEffect> holder = RoyalEffectHooks.contractedHolder();
|
||||
boolean contracted = holder != null && living.hasEffect(holder);
|
||||
boolean tuned = living instanceof net.minecraft.world.entity.player.Player player
|
||||
&& TemporalTunerItem.isAvailable(player)
|
||||
&& TimeDilationApi.getRate(living) > 1.0D;
|
||||
return !living.isInvisible() && (contracted || tuned);
|
||||
}
|
||||
|
||||
public static float fade(Sample sample, int now) {
|
||||
float elapsed = now - sample.recordedTick;
|
||||
return Math.max(0.0F, 1.0F - elapsed / SAMPLE_LIFETIME_TICKS);
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.craisinlord.antarchy.content.client.renderer;
|
||||
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanItem;
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanStorage;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import software.bernie.geckolib.cache.object.BakedGeoModel;
|
||||
import software.bernie.geckolib.model.GeoModel;
|
||||
import software.bernie.geckolib.renderer.GeoItemRenderer;
|
||||
|
||||
public final class GiantFryingPanRenderer extends GeoItemRenderer<GiantFryingPanItem> {
|
||||
public GiantFryingPanRenderer(GeoModel<GiantFryingPanItem> model) {
|
||||
super(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actuallyRender(
|
||||
PoseStack poseStack,
|
||||
GiantFryingPanItem animatable,
|
||||
BakedGeoModel model,
|
||||
net.minecraft.client.renderer.RenderType renderType,
|
||||
MultiBufferSource bufferSource,
|
||||
com.mojang.blaze3d.vertex.VertexConsumer buffer,
|
||||
boolean isReRender,
|
||||
float partialTick,
|
||||
int packedLight,
|
||||
int packedOverlay,
|
||||
int colour
|
||||
) {
|
||||
super.actuallyRender(poseStack, animatable, model, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, colour);
|
||||
if (isReRender || this.renderPerspective == ItemDisplayContext.GUI) return;
|
||||
ItemStack pan = this.getCurrentItemStack();
|
||||
if (!(Minecraft.getInstance().player instanceof net.minecraft.world.entity.player.Player player)) return;
|
||||
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
|
||||
for (int slot = 0; slot < GiantFryingPanStorage.SLOT_COUNT; slot++) {
|
||||
ItemStack stack = storage.getItem(slot);
|
||||
if (stack.isEmpty()) continue;
|
||||
int row = slot / 3;
|
||||
int column = slot % 3;
|
||||
poseStack.pushPose();
|
||||
poseStack.translate((column - 1) * 0.42D, 1.72D, (row - 1) * 0.42D);
|
||||
poseStack.scale(0.24F, 0.24F, 0.24F);
|
||||
Minecraft.getInstance().getItemRenderer().renderStatic(stack, ItemDisplayContext.FIXED, packedLight, packedOverlay, poseStack, bufferSource, Minecraft.getInstance().level, 0);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,15 @@ package com.craisinlord.antarchy.content.client.renderer;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
|
||||
public final class RoyalIndicatorRenderer {
|
||||
private static final ResourceLocation COMMANDED_CROWN_TEXTURE = ResourceLocation.fromNamespaceAndPath(
|
||||
com.craisinlord.antarchy.Antarchy.MODID, "textures/vfx/commanded_vfx_side.png");
|
||||
|
||||
private RoyalIndicatorRenderer() {
|
||||
}
|
||||
|
||||
@@ -25,7 +30,7 @@ public final class RoyalIndicatorRenderer {
|
||||
|
||||
if (commanded) {
|
||||
ring(lines, pose, radius, spin, 0.95F, 0.63F, 0.10F, 0.95F, 36);
|
||||
crownPoints(lines, pose, radius, spin, 1.0F, 0.80F, 0.22F, 0.95F);
|
||||
crownTexture(poseStack, buffers, LightTexture.FULL_BRIGHT, radius, spin);
|
||||
}
|
||||
if (judged) {
|
||||
float markY = commanded ? -0.13F : 0.08F;
|
||||
@@ -48,23 +53,38 @@ public final class RoyalIndicatorRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private static void crownPoints(VertexConsumer out, PoseStack.Pose pose, float radius, float rotation,
|
||||
float r, float g, float b, float a) {
|
||||
final int spikes = 5;
|
||||
float innerRadius = radius * 0.72F;
|
||||
for (int i = 0; i < spikes; i++) {
|
||||
double outerAngle = rotation + Math.PI * 2.0D * i / spikes;
|
||||
double innerAngle = rotation + Math.PI * 2.0D * (i + 0.5D) / spikes;
|
||||
float outerX = (float) Math.cos(outerAngle) * radius;
|
||||
float outerZ = (float) Math.sin(outerAngle) * radius;
|
||||
float innerX = (float) Math.cos(innerAngle) * innerRadius;
|
||||
float innerZ = (float) Math.sin(innerAngle) * innerRadius;
|
||||
float nextOuterX = (float) Math.cos(rotation + Math.PI * 2.0D * (i + 1) / spikes) * radius;
|
||||
float nextOuterZ = (float) Math.sin(rotation + Math.PI * 2.0D * (i + 1) / spikes) * radius;
|
||||
line(out, pose, outerX, 0.0F, outerZ, innerX, 0.34F, innerZ, r, g, b, a);
|
||||
line(out, pose, innerX, 0.34F, innerZ, nextOuterX, 0.0F, nextOuterZ, r, g, b, a);
|
||||
line(out, pose, outerX, 0.0F, outerZ, nextOuterX, 0.0F, nextOuterZ, r, g, b, a);
|
||||
private static void crownTexture(PoseStack poseStack, MultiBufferSource buffers, int packedLight,
|
||||
float radius, float rotation) {
|
||||
VertexConsumer crown = buffers.getBuffer(RenderType.entityTranslucentEmissive(COMMANDED_CROWN_TEXTURE));
|
||||
float halfWidth = radius * 0.78F;
|
||||
float bottom = 0.02F;
|
||||
float top = 0.40F;
|
||||
|
||||
poseStack.pushPose();
|
||||
poseStack.mulPose(com.mojang.math.Axis.YP.rotation(rotation));
|
||||
for (int side = 0; side < 4; side++) {
|
||||
poseStack.pushPose();
|
||||
poseStack.mulPose(com.mojang.math.Axis.YP.rotationDegrees(side * 90.0F));
|
||||
PoseStack.Pose pose = poseStack.last();
|
||||
quad(crown, pose, -halfWidth, bottom, halfWidth, top, halfWidth, packedLight);
|
||||
poseStack.popPose();
|
||||
}
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
private static void quad(VertexConsumer out, PoseStack.Pose pose, float left, float bottom,
|
||||
float right, float top, float depth, int packedLight) {
|
||||
out.addVertex(pose, left, bottom, depth).setUv(0.0F, 1.0F).setOverlay(0).setLight(packedLight).setNormal(pose, 0.0F, 0.0F, 1.0F);
|
||||
out.addVertex(pose, right, bottom, depth).setUv(1.0F, 1.0F).setOverlay(0).setLight(packedLight).setNormal(pose, 0.0F, 0.0F, 1.0F);
|
||||
out.addVertex(pose, right, top, depth).setUv(1.0F, 0.0F).setOverlay(0).setLight(packedLight).setNormal(pose, 0.0F, 0.0F, 1.0F);
|
||||
out.addVertex(pose, left, top, depth).setUv(0.0F, 0.0F).setOverlay(0).setLight(packedLight).setNormal(pose, 0.0F, 0.0F, 1.0F);
|
||||
|
||||
// Emit the reverse winding as well. The crown is viewed from every angle, and
|
||||
// a single-sided quad can vanish when the renderer's culling state rejects it.
|
||||
out.addVertex(pose, left, top, depth).setUv(0.0F, 0.0F).setOverlay(0).setLight(packedLight).setNormal(pose, 0.0F, 0.0F, -1.0F);
|
||||
out.addVertex(pose, right, top, depth).setUv(1.0F, 0.0F).setOverlay(0).setLight(packedLight).setNormal(pose, 0.0F, 0.0F, -1.0F);
|
||||
out.addVertex(pose, right, bottom, depth).setUv(1.0F, 1.0F).setOverlay(0).setLight(packedLight).setNormal(pose, 0.0F, 0.0F, -1.0F);
|
||||
out.addVertex(pose, left, bottom, depth).setUv(0.0F, 1.0F).setOverlay(0).setLight(packedLight).setNormal(pose, 0.0F, 0.0F, -1.0F);
|
||||
}
|
||||
|
||||
private static void brackets(VertexConsumer out, PoseStack.Pose pose, float radius, float rotation) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.craisinlord.antarchy.content.client.renderer;
|
||||
|
||||
import com.craisinlord.antarchy.content.client.ContractionAfterimages;
|
||||
import com.craisinlord.antarchy.content.effect.RoyalEffectHooks;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import java.util.Deque;
|
||||
@@ -30,8 +29,7 @@ public final class TemporalContractionAfterimageLayer<T extends LivingEntity, M
|
||||
public void render(PoseStack poseStack, MultiBufferSource buffer, int packedLight, T entity,
|
||||
float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw,
|
||||
float headPitch) {
|
||||
if (entity.isSpectator() || entity.isInvisible() || RoyalEffectHooks.contractedHolder() == null
|
||||
|| !entity.hasEffect(RoyalEffectHooks.contractedHolder())) {
|
||||
if (entity.isSpectator() || !ContractionAfterimages.isActive(entity)) {
|
||||
return;
|
||||
}
|
||||
Deque<ContractionAfterimages.Sample> samples = ContractionAfterimages.samples(entity);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.craisinlord.antarchy.content.client.renderer;
|
||||
|
||||
import com.craisinlord.antarchy.content.client.ContractionAfterimages;
|
||||
import com.craisinlord.antarchy.content.effect.RoyalEffectHooks;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import java.util.Deque;
|
||||
@@ -32,8 +31,7 @@ public final class TemporalContractionGeoLayer<T extends GeoAnimatable> extends
|
||||
MultiBufferSource bufferSource, @Nullable VertexConsumer buffer, float partialTick,
|
||||
int packedLight, int packedOverlay) {
|
||||
if (!(animatable instanceof Entity entity) || !(entity instanceof LivingEntity living)
|
||||
|| living.isInvisible() || RoyalEffectHooks.contractedHolder() == null
|
||||
|| !living.hasEffect(RoyalEffectHooks.contractedHolder())) {
|
||||
|| !ContractionAfterimages.isActive(living)) {
|
||||
return;
|
||||
}
|
||||
Deque<ContractionAfterimages.Sample> samples = ContractionAfterimages.samples(living);
|
||||
|
||||
@@ -31,8 +31,16 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
Registries.DIMENSION,
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "thoraxis")
|
||||
);
|
||||
private static final ResourceLocation SUN_TEXTURE = ResourceLocation.withDefaultNamespace("textures/environment/sun.png");
|
||||
private static final ResourceLocation SUN_TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_moon.png");
|
||||
private static final ResourceLocation MOON_TEXTURE = ResourceLocation.withDefaultNamespace("textures/environment/moon_phases.png");
|
||||
private static final ResourceLocation[] EYE_STAR_TEXTURES = {
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_star1.png"),
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_star2.png"),
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_star3.png"),
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_star4.png"),
|
||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/environment/eye_star5.png")
|
||||
};
|
||||
private static final float[] EYE_STAR_SCALES = {1.0F, 0.86F, 0.72F, 0.58F, 0.46F};
|
||||
private static final float SKY_RADIUS = 100.0F;
|
||||
private static final float BODY_SIZE = 32.0F;
|
||||
private static final float SKY_RED = 0.015F;
|
||||
@@ -40,7 +48,7 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
private static final float SKY_BLUE = 0.035F;
|
||||
|
||||
@org.jetbrains.annotations.Nullable
|
||||
private static VertexBuffer redStarBuffer = null;
|
||||
private static VertexBuffer[] eyeStarBuffers = null;
|
||||
|
||||
private ThoraxisUndersideSkyRenderer() {
|
||||
}
|
||||
@@ -73,37 +81,57 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
|
||||
float timeOfDay = 0.72F + partialTick * 0.0F;
|
||||
renderCelestialBodies(poseStack.last().pose(), projectionMatrix, timeOfDay);
|
||||
renderRedStars(poseStack.last().pose(), projectionMatrix);
|
||||
renderEyeStars(poseStack.last().pose(), projectionMatrix);
|
||||
|
||||
RenderSystem.depthMask(true);
|
||||
}
|
||||
|
||||
private static void renderRedStars(Matrix4f modelViewMatrix, Matrix4f projectionMatrix) {
|
||||
if (redStarBuffer == null) {
|
||||
redStarBuffer = buildRedStarBuffer();
|
||||
private static void renderEyeStars(Matrix4f modelViewMatrix, Matrix4f projectionMatrix) {
|
||||
if (eyeStarBuffers == null) {
|
||||
eyeStarBuffers = buildEyeStarBuffers();
|
||||
}
|
||||
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.setShaderColor(0.95F, 0.95F, 0.95F, 0.95F);
|
||||
redStarBuffer.bind();
|
||||
redStarBuffer.drawWithShader(modelViewMatrix, projectionMatrix, GameRenderer.getPositionColorShader());
|
||||
VertexBuffer.unbind();
|
||||
RenderSystem.blendFuncSeparate(
|
||||
GlStateManager.SourceFactor.ONE,
|
||||
GlStateManager.DestFactor.ONE,
|
||||
GlStateManager.SourceFactor.ONE,
|
||||
GlStateManager.DestFactor.ZERO
|
||||
);
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderColor(1.0F, 0.015F, 0.02F, 1.0F);
|
||||
RenderSystem.backupProjectionMatrix();
|
||||
RenderSystem.setProjectionMatrix(projectionMatrix, VertexSorting.DISTANCE_TO_ORIGIN);
|
||||
|
||||
for (int i = 0; i < eyeStarBuffers.length; i++) {
|
||||
RenderSystem.setShaderTexture(0, EYE_STAR_TEXTURES[i]);
|
||||
eyeStarBuffers[i].bind();
|
||||
eyeStarBuffers[i].drawWithShader(modelViewMatrix, projectionMatrix, GameRenderer.getPositionTexShader());
|
||||
VertexBuffer.unbind();
|
||||
}
|
||||
RenderSystem.restoreProjectionMatrix();
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
private static VertexBuffer buildRedStarBuffer() {
|
||||
Random random = new Random(552031L);
|
||||
BufferBuilder builder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
||||
private static VertexBuffer[] buildEyeStarBuffers() {
|
||||
VertexBuffer[] buffers = new VertexBuffer[EYE_STAR_TEXTURES.length];
|
||||
for (int textureIndex = 0; textureIndex < EYE_STAR_TEXTURES.length; textureIndex++) {
|
||||
Random random = new Random(552031L);
|
||||
BufferBuilder builder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);
|
||||
|
||||
for (int i = 0; i < 1800; i++) {
|
||||
double x = random.nextFloat() * 2.0F - 1.0F;
|
||||
double y = random.nextFloat() * 2.0F - 1.0F;
|
||||
double z = random.nextFloat() * 2.0F - 1.0F;
|
||||
double size = (0.52F + random.nextFloat() * 0.36F) * EYE_STAR_SCALES[textureIndex];
|
||||
double rot = random.nextDouble() * Math.PI * 2.0D;
|
||||
double lenSq = x * x + y * y + z * z;
|
||||
if (i % EYE_STAR_TEXTURES.length != textureIndex || lenSq >= 1.0D || lenSq <= 0.01D) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1800; i++) {
|
||||
double x = random.nextFloat() * 2.0F - 1.0F;
|
||||
double y = random.nextFloat() * 2.0F - 1.0F;
|
||||
double z = random.nextFloat() * 2.0F - 1.0F;
|
||||
double size = 0.13F + random.nextFloat() * 0.12F;
|
||||
double lenSq = x * x + y * y + z * z;
|
||||
if (lenSq < 1.0D && lenSq > 0.01D) {
|
||||
double len = 1.0D / Math.sqrt(lenSq);
|
||||
x *= len;
|
||||
y *= len;
|
||||
@@ -117,12 +145,8 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
double pitch = Math.atan2(Math.sqrt(x * x + z * z), y);
|
||||
double sinPitch = Math.sin(pitch);
|
||||
double cosPitch = Math.cos(pitch);
|
||||
double rot = random.nextDouble() * Math.PI * 2.0D;
|
||||
double sinRot = Math.sin(rot);
|
||||
double cosRot = Math.cos(rot);
|
||||
float red = 0.75F + random.nextFloat() * 0.25F;
|
||||
float green = 0.02F + random.nextFloat() * 0.05F;
|
||||
float blue = 0.04F + random.nextFloat() * 0.08F;
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
double u = (j & 2) - 1;
|
||||
@@ -133,24 +157,26 @@ public final class ThoraxisUndersideSkyRenderer {
|
||||
double qy = -px * cosPitch;
|
||||
double rx = qy * sinYaw - py * cosYaw;
|
||||
double ry = py * sinYaw + qy * cosYaw;
|
||||
float quadU = (j == 0 || j == 1) ? 0.0F : 1.0F;
|
||||
float quadV = (j == 0 || j == 3) ? 0.0F : 1.0F;
|
||||
builder.addVertex((float) (sx + rx * size), (float) (sy + qx * size), (float) (sz + ry * size))
|
||||
.setColor(red, green, blue, 1.0F);
|
||||
.setUv(quadU, quadV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MeshData mesh = builder.buildOrThrow();
|
||||
VertexBuffer buffer = new VertexBuffer(VertexBuffer.Usage.STATIC);
|
||||
buffer.bind();
|
||||
buffer.upload(mesh);
|
||||
VertexBuffer.unbind();
|
||||
return buffer;
|
||||
MeshData mesh = builder.buildOrThrow();
|
||||
buffers[textureIndex] = new VertexBuffer(VertexBuffer.Usage.STATIC);
|
||||
buffers[textureIndex].bind();
|
||||
buffers[textureIndex].upload(mesh);
|
||||
VertexBuffer.unbind();
|
||||
}
|
||||
return buffers;
|
||||
}
|
||||
|
||||
private static void renderCelestialBodies(Matrix4f modelViewMatrix, Matrix4f projectionMatrix, float timeOfDay) {
|
||||
float t = timeOfDay * 360.0F;
|
||||
renderBodyGlow(modelViewMatrix, projectionMatrix, t, -10.0F, 0xFF1F18, 86.0F);
|
||||
renderTexturedBody(modelViewMatrix, projectionMatrix, t, -10.0F, 42.0F, 0xFF1F18, SUN_TEXTURE, false, 0, t * 0.6F);
|
||||
renderTexturedBody(modelViewMatrix, projectionMatrix, t, -10.0F, 42.0F, 0xFF1F18, SUN_TEXTURE, false, 0, t * 0.6F + 90.0F);
|
||||
|
||||
float moonOrbit = t + 180.0F;
|
||||
renderBodyGlow(modelViewMatrix, projectionMatrix, moonOrbit, 24.0F, 0x8F30FF, 76.0F);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.craisinlord.antarchy.content.client.screen;
|
||||
|
||||
import com.craisinlord.antarchy.content.menu.GiantFryingPanMenu;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
|
||||
public final class GiantFryingPanScreen extends AbstractContainerScreen<GiantFryingPanMenu> {
|
||||
private static final ResourceLocation INVENTORY_TEXTURE = ResourceLocation.withDefaultNamespace("textures/gui/container/inventory.png");
|
||||
|
||||
public GiantFryingPanScreen(GiantFryingPanMenu menu, Inventory inventory, Component title) {
|
||||
super(menu, inventory, title);
|
||||
imageWidth = 176;
|
||||
imageHeight = 132;
|
||||
inventoryLabelY = 40;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBg(GuiGraphics graphics, float partialTick, int mouseX, int mouseY) {
|
||||
graphics.blit(INVENTORY_TEXTURE, leftPos, topPos, 0, 0, imageWidth, imageHeight);
|
||||
}
|
||||
}
|
||||
@@ -409,6 +409,7 @@ public final class CreativeTabContents {
|
||||
entry("ultimate_hoe", "tools_and_utilities"),
|
||||
entry("battle_axe", "combat"),
|
||||
entry("big_bertha", "combat"),
|
||||
entry("giant_frying_pan", "combat"),
|
||||
entry("basilisk_dagger", "combat"),
|
||||
entry("ultimate_helmet", "combat"),
|
||||
entry("ultimate_chestplate", "combat"),
|
||||
@@ -437,6 +438,7 @@ public final class CreativeTabContents {
|
||||
entry("nightmare_leggings", "combat"),
|
||||
entry("nightmare_boots", "combat"),
|
||||
entry("nightmare_sword", "combat"),
|
||||
entry("blood_gods_blade", "combat"),
|
||||
entry("blood_crystal_katana", "combat"),
|
||||
entry("blood_crystal_helmet", "combat"),
|
||||
entry("blood_crystal_chestplate", "combat"),
|
||||
@@ -490,6 +492,7 @@ public final class CreativeTabContents {
|
||||
entry("mud_pie", "ingredients"),
|
||||
entry("lucid_eye", "ingredients"),
|
||||
entry("blood_crystal_shard", "ingredients"),
|
||||
entry("temporal_tuner", "ingredients"),
|
||||
entry("tigers_eye", "ingredients"),
|
||||
entry("tigers_eye_block", "building_blocks"),
|
||||
entry("blood_crystal_apple", "ingredients"),
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.craisinlord.antarchy.content.effect;
|
||||
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectCategory;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
|
||||
public final class BleedingMobEffect extends MobEffect {
|
||||
public BleedingMobEffect() {
|
||||
super(MobEffectCategory.HARMFUL, 0x8F1020);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyEffectTick(LivingEntity entity, int amplifier) {
|
||||
entity.hurt(entity.damageSources().magic(), 1.0F + amplifier);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) {
|
||||
return duration % 20 == 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.craisinlord.antarchy.content.effect;
|
||||
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectCategory;
|
||||
|
||||
public final class BloodMoonMobEffect extends MobEffect {
|
||||
public BloodMoonMobEffect() {
|
||||
super(MobEffectCategory.BENEFICIAL, 0xB51B2D);
|
||||
}
|
||||
}
|
||||
@@ -93,6 +93,7 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
|
||||
private UUID staffOwnerId;
|
||||
private int staffManticoreCount;
|
||||
private boolean staffManticoreSpawned;
|
||||
private boolean gauntletVisualOnly;
|
||||
|
||||
public DimensionalTearEntity(EntityType<? extends DimensionalTearEntity> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -109,6 +110,12 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
|
||||
return tear;
|
||||
}
|
||||
|
||||
public static DimensionalTearEntity createGauntletVisual(ServerLevel level, Vec3 pos, float yaw, int lifetimeTicks) {
|
||||
DimensionalTearEntity tear = create(level, pos, yaw, lifetimeTicks);
|
||||
tear.gauntletVisualOnly = true;
|
||||
return tear;
|
||||
}
|
||||
|
||||
public static DimensionalTearEntity createQueenManticoreTear(ServerLevel level, Vec3 pos, float yaw,
|
||||
int lifetimeTicks, UUID queenId, int count) {
|
||||
DimensionalTearEntity tear = create(level, pos, yaw, lifetimeTicks);
|
||||
@@ -161,7 +168,15 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
|
||||
this.setTearState(TearState.NORMAL);
|
||||
}
|
||||
if (this.ageTicks >= this.lifetimeTicks) {
|
||||
this.removeLinkedPair();
|
||||
if (this.gauntletVisualOnly) {
|
||||
this.discard();
|
||||
} else {
|
||||
this.removeLinkedPair();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.gauntletVisualOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -500,6 +515,7 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
|
||||
tag.putInt("EventTicks", this.eventTicks);
|
||||
tag.putInt("NextEventTicks", this.nextEventTicks);
|
||||
tag.putInt("PendingEvent", this.pendingEvent.ordinal());
|
||||
tag.putBoolean("GauntletVisualOnly", this.gauntletVisualOnly);
|
||||
if (this.linkedTearId != null) {
|
||||
tag.putUUID("LinkedTearId", this.linkedTearId);
|
||||
}
|
||||
@@ -522,6 +538,7 @@ public class DimensionalTearEntity extends Entity implements GeoEntity {
|
||||
int event = tag.getInt("PendingEvent");
|
||||
TearState[] states = TearState.values();
|
||||
this.pendingEvent = event >= 0 && event < states.length ? states[event] : TearState.NORMAL;
|
||||
this.gauntletVisualOnly = tag.getBoolean("GauntletVisualOnly");
|
||||
if (tag.hasUUID("LinkedTearId")) {
|
||||
this.linkedTearId = tag.getUUID("LinkedTearId");
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntitySelector;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
@@ -28,7 +29,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class RoyalBeamController {
|
||||
private static final int INITIAL_TRACKING_DELAY_TICKS = 8;
|
||||
private final Mob owner;
|
||||
private final LivingEntity owner;
|
||||
private Vec3 serverTarget;
|
||||
private Vec3 beamEndPosition;
|
||||
private int beamTicks;
|
||||
@@ -39,10 +40,14 @@ public final class RoyalBeamController {
|
||||
private static final int ICE_MUTATIONS_PER_TICK = 3;
|
||||
private static final float ICE_IMPACT_RADIUS = 2.0F;
|
||||
|
||||
public RoyalBeamController(Mob owner) {
|
||||
public RoyalBeamController(LivingEntity owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public RoyalBeamController(Mob owner) {
|
||||
this((LivingEntity) owner);
|
||||
}
|
||||
|
||||
public boolean isFiring() {
|
||||
return this.beamTicks > 0;
|
||||
}
|
||||
@@ -164,7 +169,9 @@ public final class RoyalBeamController {
|
||||
) {
|
||||
Vec3 direction = beamEnd.subtract(shootFrom).normalize();
|
||||
double distance = shootFrom.distanceTo(beamEnd);
|
||||
DamageSource damageSource = this.owner.damageSources().mobAttack(this.owner);
|
||||
DamageSource damageSource = this.owner instanceof Player player
|
||||
? player.damageSources().playerAttack(player)
|
||||
: this.owner.damageSources().mobAttack(this.owner);
|
||||
this.damagedThisTick.clear();
|
||||
boolean pathMutates = terrainMode == RoyalBeamTerrainMode.DESTROY;
|
||||
for (double walked = settings.pathStep(); walked < Math.min(distance, settings.range()); walked += settings.pathStep()) {
|
||||
@@ -224,7 +231,7 @@ public final class RoyalBeamController {
|
||||
for (LivingEntity living : entities) {
|
||||
if (living.is(this.owner)
|
||||
|| this.owner.isAlliedTo(living)
|
||||
|| living.getType() == this.owner.getType()
|
||||
|| !(this.owner instanceof Player) && living.getType() == this.owner.getType()
|
||||
|| this.owner instanceof RoyalBossEntity royalBoss && !royalBoss.canDamageWithRoyalAttack(living)
|
||||
|| living.distanceToSqr(center) > radius * radius
|
||||
|| damagedThisTick.contains(living.getId())
|
||||
|
||||
@@ -22,6 +22,16 @@ public record RoyalBeamSettings(
|
||||
boolean terrainEnabled,
|
||||
boolean requireLineOfSightForDamage
|
||||
) {
|
||||
public static RoyalBeamSettings gauntletPower() {
|
||||
return new RoyalBeamSettings(64.0D, 0.0D, 2.0D, 18, 4, 50, 0.9F, 1.8F,
|
||||
9.0F, 0.8F, 1, 64.0D, 0.8F, 1.8F, 6, 1.0F, 1.0F, 50.0F, true, false);
|
||||
}
|
||||
|
||||
public static RoyalBeamSettings gauntletInfinity() {
|
||||
return new RoyalBeamSettings(64.0D, 0.0D, 1.5D, 24, 4, 1200, 1.25F, 2.5F,
|
||||
28.0F, 1.8F, 1, 64.0D, 1.0F, 2.0F, 0, 0.0F, 0.0F, 0.0F, false, false);
|
||||
}
|
||||
|
||||
public static RoyalBeamSettings tremorzillaLike(float damage, boolean terrainEnabled) {
|
||||
return new RoyalBeamSettings(
|
||||
100.0D,
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import com.craisinlord.antarchy.content.AntarchyObjects;
|
||||
import java.util.List;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.particles.DustParticleOptions;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.SwordItem;
|
||||
import net.minecraft.world.item.Tier;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.item.component.ItemAttributeModifiers;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public final class BloodGodsBladeItem extends SwordItem {
|
||||
private static final int BLEEDING_TICKS = 100;
|
||||
private static final int BLOOD_MOON_TICKS = 200;
|
||||
private static final int BLOOD_MOON_MAX_TICKS = 300;
|
||||
private static final int BLOOD_MOON_COOLDOWN_TICKS = 1200;
|
||||
private static final double BLOOD_MOON_RADIUS = 12.0D;
|
||||
private static final DustParticleOptions BLOOD_PARTICLES = new DustParticleOptions(new Vector3f(0.65F, 0.02F, 0.05F), 1.6F);
|
||||
|
||||
private final Tier tier;
|
||||
private final int attackDamage;
|
||||
private final float attackSpeed;
|
||||
|
||||
public BloodGodsBladeItem(Tier tier, Item.Properties properties, int attackDamage, float attackSpeed) {
|
||||
super(tier, properties);
|
||||
this.tier = tier;
|
||||
this.attackDamage = attackDamage;
|
||||
this.attackSpeed = attackSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemAttributeModifiers getDefaultAttributeModifiers() {
|
||||
return SwordItem.createAttributes(this.tier, this.attackDamage, this.attackSpeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
|
||||
boolean result = super.hurtEnemy(stack, target, attacker);
|
||||
if (!attacker.level().isClientSide()) {
|
||||
target.addEffect(new MobEffectInstance(AntarchyObjects.BLEEDING_EFFECT.get(), BLEEDING_TICKS, 0, false, true, true));
|
||||
if (attacker instanceof Player player && player.hasEffect(AntarchyObjects.BLOOD_MOON_EFFECT.get())) {
|
||||
player.heal(1.0F);
|
||||
if (target.isDeadOrDying()) {
|
||||
MobEffectInstance bloodMoon = player.getEffect(AntarchyObjects.BLOOD_MOON_EFFECT.get());
|
||||
if (bloodMoon != null) {
|
||||
player.addEffect(new MobEffectInstance(AntarchyObjects.BLOOD_MOON_EFFECT.get(), Math.min(BLOOD_MOON_MAX_TICKS, bloodMoon.getDuration() + 20), bloodMoon.getAmplifier(), false, true, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
|
||||
ItemStack stack = player.getItemInHand(hand);
|
||||
if (player.getCooldowns().isOnCooldown(this)) {
|
||||
return InteractionResultHolder.fail(stack);
|
||||
}
|
||||
if (!level.isClientSide() && level instanceof ServerLevel serverLevel) {
|
||||
player.getCooldowns().addCooldown(this, BLOOD_MOON_COOLDOWN_TICKS);
|
||||
player.addEffect(new MobEffectInstance(AntarchyObjects.BLOOD_MOON_EFFECT.get(), BLOOD_MOON_TICKS, 0, false, true, true));
|
||||
player.addEffect(new MobEffectInstance(MobEffects.DAMAGE_BOOST, BLOOD_MOON_TICKS, 0, false, false, true));
|
||||
for (LivingEntity entity : level.getEntitiesOfClass(LivingEntity.class, player.getBoundingBox().inflate(BLOOD_MOON_RADIUS), entity -> entity != player && entity.isAlive() && !player.isAlliedTo(entity))) {
|
||||
entity.addEffect(new MobEffectInstance(MobEffects.GLOWING, BLOOD_MOON_TICKS, 0, false, true, true));
|
||||
entity.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, BLOOD_MOON_TICKS, 0, false, true, true));
|
||||
}
|
||||
serverLevel.sendParticles(BLOOD_PARTICLES, player.getX(), player.getY() + 1.0D, player.getZ(), 160, 2.5D, 1.2D, 2.5D, 0.08D);
|
||||
serverLevel.sendParticles(BLOOD_PARTICLES, player.getX(), player.getY() + 8.0D, player.getZ(), 80, 5.0D, 0.2D, 5.0D, 0.02D);
|
||||
}
|
||||
return InteractionResultHolder.sidedSuccess(stack, level.isClientSide());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(ItemStack stack, Item.TooltipContext context, List<Component> tooltipComponents, TooltipFlag tooltipFlag) {
|
||||
tooltipComponents.add(Component.translatable("tooltip.antarchy.blood_gods_blade.bleeding").withStyle(ChatFormatting.DARK_RED));
|
||||
tooltipComponents.add(Component.translatable("tooltip.antarchy.blood_gods_blade.blood_moon").withStyle(ChatFormatting.RED));
|
||||
super.appendHoverText(stack, context, tooltipComponents, tooltipFlag);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.craisinlord.antarchy.content.client.model.ResourceBackedGeoItemModel;
|
||||
import com.craisinlord.antarchy.content.client.renderer.AnimatedHeldItemRenderer;
|
||||
import com.craisinlord.antarchy.content.client.renderer.GiantFryingPanRenderer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.List;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.entity.EquipmentSlotGroup;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.SwordItem;
|
||||
import net.minecraft.world.item.Tier;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.item.component.ItemAttributeModifiers;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import software.bernie.geckolib.animatable.GeoItem;
|
||||
import software.bernie.geckolib.animatable.client.GeoRenderProvider;
|
||||
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
|
||||
import software.bernie.geckolib.animation.AnimatableManager;
|
||||
import software.bernie.geckolib.util.GeckoLibUtil;
|
||||
|
||||
public class GiantFryingPanItem extends SwordItem implements GeoItem {
|
||||
private static final ResourceLocation MODEL_LOCATION = ResourceLocation.fromNamespaceAndPath("antarchy", "geo/giant_frying_pan.geo.json");
|
||||
private static final ResourceLocation TEXTURE_LOCATION = ResourceLocation.fromNamespaceAndPath("antarchy", "textures/item/giant_frying_pan/giant_frying_pan_model.png");
|
||||
private static final ResourceLocation ANIMATION_LOCATION = ResourceLocation.fromNamespaceAndPath("antarchy", "animations/static_item.animation.json");
|
||||
private static final ResourceLocation REACH_MODIFIER_ID = ResourceLocation.fromNamespaceAndPath("antarchy", "giant_frying_pan_reach");
|
||||
private static final ResourceLocation KNOCKBACK_MODIFIER_ID = ResourceLocation.fromNamespaceAndPath("antarchy", "giant_frying_pan_knockback");
|
||||
private final Tier tier;
|
||||
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
|
||||
|
||||
public GiantFryingPanItem(Tier tier, Item.Properties properties) {
|
||||
super(tier, properties);
|
||||
this.tier = tier;
|
||||
GeoItem.registerSyncedAnimatable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(ItemStack stack, Item.TooltipContext context, List<net.minecraft.network.chat.Component> tooltipComponents, TooltipFlag tooltipFlag) {
|
||||
super.appendHoverText(stack, context, tooltipComponents, tooltipFlag);
|
||||
tooltipComponents.add(Component.translatable("tooltip.antarchy.giant_frying_pan.insert").withStyle(ChatFormatting.GRAY));
|
||||
tooltipComponents.add(Component.translatable("tooltip.antarchy.giant_frying_pan.gui").withStyle(ChatFormatting.GRAY));
|
||||
tooltipComponents.add(Component.translatable("tooltip.antarchy.giant_frying_pan.campfire").withStyle(ChatFormatting.DARK_GRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemAttributeModifiers getDefaultAttributeModifiers() {
|
||||
return SwordItem.createAttributes(this.tier, (int) Math.round(AntarchySettings.giantFryingPanAttackDamage()), -3.8F)
|
||||
.withModifierAdded(Attributes.ENTITY_INTERACTION_RANGE,
|
||||
new AttributeModifier(REACH_MODIFIER_ID, 6.0D, AttributeModifier.Operation.ADD_VALUE),
|
||||
EquipmentSlotGroup.MAINHAND)
|
||||
.withModifierAdded(Attributes.ATTACK_KNOCKBACK,
|
||||
new AttributeModifier(KNOCKBACK_MODIFIER_ID, 2.0D, AttributeModifier.Operation.ADD_VALUE),
|
||||
EquipmentSlotGroup.MAINHAND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
|
||||
boolean hurt = super.hurtEnemy(stack, target, attacker);
|
||||
if (!hurt || attacker.level().isClientSide) {
|
||||
return hurt;
|
||||
}
|
||||
|
||||
Vec3 direction = target.position().subtract(attacker.position()).multiply(1.0D, 0.0D, 1.0D);
|
||||
if (direction.lengthSqr() < 1.0E-4D) {
|
||||
direction = attacker.getLookAngle().multiply(1.0D, 0.0D, 1.0D);
|
||||
}
|
||||
if (direction.lengthSqr() >= 1.0E-4D) {
|
||||
direction = direction.normalize();
|
||||
Vec3 motion = target.getDeltaMovement();
|
||||
double x = Math.max(-2.6D, Math.min(2.6D, motion.x + direction.x * 1.8D));
|
||||
double z = Math.max(-2.6D, Math.min(2.6D, motion.z + direction.z * 1.8D));
|
||||
target.setDeltaMovement(x, motion.y, z);
|
||||
target.hurtMarked = true;
|
||||
}
|
||||
Level level = attacker.level();
|
||||
level.playSound(null, target.blockPosition(), SoundEvents.ANVIL_LAND, SoundSource.PLAYERS, 0.8F, 1.25F);
|
||||
return hurt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inventoryTick(ItemStack stack, Level level, net.minecraft.world.entity.Entity entity, int slotId, boolean isSelected) {
|
||||
super.inventoryTick(stack, level, entity, slotId, isSelected);
|
||||
if (entity instanceof Player player) GiantFryingPanStorage.tick(player, stack, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.world.InteractionResultHolder<ItemStack> use(Level level, Player player, net.minecraft.world.InteractionHand hand) {
|
||||
ItemStack pan = player.getItemInHand(hand);
|
||||
if (player.isShiftKeyDown()) {
|
||||
if (!level.isClientSide) {
|
||||
player.openMenu(new SimpleMenuProvider(
|
||||
(containerId, inventory, ignored) -> new com.craisinlord.antarchy.content.menu.GiantFryingPanMenu(containerId, inventory),
|
||||
Component.translatable("item.antarchy.giant_frying_pan")));
|
||||
}
|
||||
return net.minecraft.world.InteractionResultHolder.sidedSuccess(pan, level.isClientSide);
|
||||
}
|
||||
net.minecraft.world.InteractionHand foodHand = hand == net.minecraft.world.InteractionHand.MAIN_HAND
|
||||
? net.minecraft.world.InteractionHand.OFF_HAND : net.minecraft.world.InteractionHand.MAIN_HAND;
|
||||
ItemStack food = player.getItemInHand(foodHand);
|
||||
if (!GiantFryingPanStorage.isCampfireInput(player, food)) return net.minecraft.world.InteractionResultHolder.pass(pan);
|
||||
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
|
||||
for (int slot = 0; slot < GiantFryingPanStorage.SLOT_COUNT; slot++) {
|
||||
if (storage.getItem(slot).isEmpty()) {
|
||||
if (!level.isClientSide) {
|
||||
storage.setItem(slot, food.copyWithCount(1));
|
||||
food.shrink(1);
|
||||
level.playSound(null, player.blockPosition(), SoundEvents.CAMPFIRE_CRACKLE, SoundSource.PLAYERS, 0.8F, 1.0F);
|
||||
}
|
||||
return net.minecraft.world.InteractionResultHolder.sidedSuccess(pan, level.isClientSide);
|
||||
}
|
||||
}
|
||||
return net.minecraft.world.InteractionResultHolder.fail(pan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnimatableInstanceCache getAnimatableInstanceCache() {
|
||||
return this.geoCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createGeoRenderer(Consumer<GeoRenderProvider> consumer) {
|
||||
consumer.accept(new GeoRenderProvider() {
|
||||
private GiantFryingPanRenderer renderer;
|
||||
|
||||
@Override
|
||||
public net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer getGeoItemRenderer() {
|
||||
if (this.renderer == null) {
|
||||
this.renderer = new GiantFryingPanRenderer(new ResourceBackedGeoItemModel<>(MODEL_LOCATION, TEXTURE_LOCATION, ANIMATION_LOCATION));
|
||||
}
|
||||
return this.renderer;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import java.util.Optional;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.CampfireCookingRecipe;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.item.crafting.SingleRecipeInput;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public final class GiantFryingPanStorage implements Container {
|
||||
public static final int SLOT_COUNT = 9;
|
||||
private static final String SLOTS = "antarchy.giant_frying_pan_slots";
|
||||
private static final String SLOT = "Slot";
|
||||
private static final String ITEM = "Item";
|
||||
private static final String TIME = "Time";
|
||||
private final ItemStack pan;
|
||||
private final Player player;
|
||||
|
||||
public GiantFryingPanStorage(ItemStack pan, Player player) {
|
||||
this.pan = pan;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public static ItemStack findPan(Player player) {
|
||||
ItemStack selected = player.getMainHandItem();
|
||||
if (selected.getItem() instanceof GiantFryingPanItem) return selected;
|
||||
ItemStack offhand = player.getOffhandItem();
|
||||
if (offhand.getItem() instanceof GiantFryingPanItem) return offhand;
|
||||
for (ItemStack stack : player.getInventory().items) {
|
||||
if (stack.getItem() instanceof GiantFryingPanItem) return stack;
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public static int findPanSlot(Player player) {
|
||||
if (player.getMainHandItem().getItem() instanceof GiantFryingPanItem) return player.getInventory().selected;
|
||||
if (player.getOffhandItem().getItem() instanceof GiantFryingPanItem) return 40;
|
||||
for (int i = 0; i < player.getInventory().items.size(); i++) {
|
||||
if (player.getInventory().items.get(i).getItem() instanceof GiantFryingPanItem) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void tick(Player player, ItemStack pan, Level level) {
|
||||
if (level.isClientSide || !(pan.getItem() instanceof GiantFryingPanItem)) return;
|
||||
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) {
|
||||
ItemStack input = storage.getItem(slot);
|
||||
if (input.isEmpty()) continue;
|
||||
Optional<RecipeHolder<CampfireCookingRecipe>> recipe = level.getServer().getRecipeManager().getRecipeFor(
|
||||
RecipeType.CAMPFIRE_COOKING, new SingleRecipeInput(input), level);
|
||||
if (recipe.isEmpty()) {
|
||||
storage.setCookTime(slot, 0);
|
||||
continue;
|
||||
}
|
||||
int time = storage.getCookTime(slot) + 1;
|
||||
if (time < 600) {
|
||||
storage.setCookTime(slot, time);
|
||||
continue;
|
||||
}
|
||||
ItemStack cooked = recipe.get().value().assemble(new SingleRecipeInput(input), level.registryAccess());
|
||||
input.shrink(1);
|
||||
storage.setItem(slot, input);
|
||||
storage.setCookTime(slot, 0);
|
||||
if (!cooked.isEmpty()) {
|
||||
var output = new net.minecraft.world.entity.item.ItemEntity(level, player.getX(), player.getY() + 1.2D, player.getZ(), cooked);
|
||||
output.setDeltaMovement(player.getLookAngle().scale(0.35D).add(0.0D, 0.2D, 0.0D));
|
||||
output.setPickUpDelay(10);
|
||||
level.addFreshEntity(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCampfireInput(Player player, ItemStack stack) {
|
||||
return !stack.isEmpty() && (player.getServer() == null || player.getServer().getRecipeManager().getRecipeFor(
|
||||
RecipeType.CAMPFIRE_COOKING, new SingleRecipeInput(stack), player.level()).isPresent());
|
||||
}
|
||||
|
||||
private ListTag slotList() {
|
||||
return pan.getOrDefault(net.minecraft.core.component.DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY)
|
||||
.copyTag().getList(SLOTS, Tag.TAG_COMPOUND);
|
||||
}
|
||||
|
||||
private CompoundTag slotTag(int slot) {
|
||||
for (Tag raw : slotList()) {
|
||||
CompoundTag tag = (CompoundTag) raw;
|
||||
if (tag.getInt(SLOT) == slot) return tag;
|
||||
}
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putInt(SLOT, slot);
|
||||
return tag;
|
||||
}
|
||||
|
||||
private void writeSlot(int slot, ItemStack stack, int cookTime) {
|
||||
HolderLookup.Provider registries = player.registryAccess();
|
||||
net.minecraft.world.item.component.CustomData.update(net.minecraft.core.component.DataComponents.CUSTOM_DATA, pan, root -> {
|
||||
ListTag list = root.getList(SLOTS, Tag.TAG_COMPOUND);
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
if (list.getCompound(i).getInt(SLOT) == slot) list.remove(i);
|
||||
}
|
||||
if (!stack.isEmpty()) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putInt(SLOT, slot);
|
||||
tag.putInt(TIME, cookTime);
|
||||
tag.put(ITEM, stack.save(registries));
|
||||
list.add(tag);
|
||||
}
|
||||
root.put(SLOTS, list);
|
||||
});
|
||||
}
|
||||
|
||||
public int getCookTime(int slot) {
|
||||
return slotTag(slot).getInt(TIME);
|
||||
}
|
||||
|
||||
public void setCookTime(int slot, int value) {
|
||||
ItemStack stack = getItem(slot);
|
||||
if (!stack.isEmpty()) writeSlot(slot, stack, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContainerSize() { return SLOT_COUNT; }
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (int i = 0; i < SLOT_COUNT; i++) if (!getItem(i).isEmpty()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(int slot) {
|
||||
CompoundTag tag = slotTag(slot);
|
||||
if (!tag.contains(ITEM, Tag.TAG_COMPOUND)) return ItemStack.EMPTY;
|
||||
return ItemStack.parseOptional(player.registryAccess(), tag.getCompound(ITEM));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(int slot, int amount) {
|
||||
ItemStack stack = getItem(slot);
|
||||
if (stack.isEmpty()) return ItemStack.EMPTY;
|
||||
ItemStack result = stack.split(amount);
|
||||
writeSlot(slot, stack, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate(int slot) {
|
||||
ItemStack result = getItem(slot);
|
||||
writeSlot(slot, ItemStack.EMPTY, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(int slot, ItemStack stack) { writeSlot(slot, stack, 0); }
|
||||
|
||||
@Override
|
||||
public void setChanged() { }
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) { return player.isAlive(); }
|
||||
|
||||
@Override
|
||||
public void clearContent() {
|
||||
for (int i = 0; i < SLOT_COUNT; i++) writeSlot(i, ItemStack.EMPTY, 0);
|
||||
}
|
||||
}
|
||||
@@ -78,10 +78,15 @@ public final class RoyalGuardianSwordAbilities {
|
||||
|| !(swordStack.getItem() instanceof RoyalGuardianSwordItem)
|
||||
|| !RoyalGuardianSwordItem.isDischargeReady(swordStack, level.getGameTime())) return;
|
||||
|
||||
switch (RoyalGuardianSwordItem.getMode(swordStack)) {
|
||||
RoyalGuardianSwordItem.Mode mode = RoyalGuardianSwordItem.getMode(swordStack);
|
||||
if (mode == RoyalGuardianSwordItem.Mode.NONE) return;
|
||||
|
||||
switch (mode) {
|
||||
case FIRE -> fireImpact(level, owner, primary);
|
||||
case FROST -> frostFan(level, owner, primary);
|
||||
case STORM -> chainLightning(level, owner, primary);
|
||||
case NONE -> {
|
||||
}
|
||||
}
|
||||
RoyalGuardianSwordItem.startDischargeCooldown(swordStack, level.getGameTime());
|
||||
}
|
||||
|
||||
@@ -94,8 +94,8 @@ public class RoyalGuardianSwordItem extends SwordItem implements GeoItem {
|
||||
|
||||
private static void setMode(ItemStack stack, Mode mode) {
|
||||
CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> {
|
||||
if (mode == Mode.FIRE) tag.remove(MODE_TAG);
|
||||
else tag.putInt(MODE_TAG, mode.ordinal());
|
||||
if (mode == Mode.NONE) tag.remove(MODE_TAG);
|
||||
else tag.putInt(MODE_TAG, mode.id);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -115,8 +115,8 @@ public class RoyalGuardianSwordItem extends SwordItem implements GeoItem {
|
||||
}
|
||||
|
||||
public static Mode getMode(ItemStack stack) {
|
||||
int value = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag().getInt(MODE_TAG);
|
||||
return Mode.values()[Math.floorMod(value, Mode.values().length)];
|
||||
net.minecraft.nbt.CompoundTag tag = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
||||
return tag.contains(MODE_TAG) ? Mode.fromId(tag.getInt(MODE_TAG)) : Mode.NONE;
|
||||
}
|
||||
|
||||
public static boolean isDischargeReady(ItemStack stack, long gameTime) {
|
||||
@@ -130,20 +130,37 @@ public class RoyalGuardianSwordItem extends SwordItem implements GeoItem {
|
||||
}
|
||||
|
||||
public enum Mode {
|
||||
FIRE("tooltip.antarchy.royal_guardian_sword.mode.fire", "tooltip.antarchy.royal_guardian_sword.fire"),
|
||||
FROST("tooltip.antarchy.royal_guardian_sword.mode.frost", "tooltip.antarchy.royal_guardian_sword.frost"),
|
||||
STORM("tooltip.antarchy.royal_guardian_sword.mode.storm", "tooltip.antarchy.royal_guardian_sword.storm");
|
||||
NONE(-1, "tooltip.antarchy.royal_guardian_sword.mode.none", "tooltip.antarchy.royal_guardian_sword.none"),
|
||||
FIRE(0, "tooltip.antarchy.royal_guardian_sword.mode.fire", "tooltip.antarchy.royal_guardian_sword.fire"),
|
||||
FROST(1, "tooltip.antarchy.royal_guardian_sword.mode.frost", "tooltip.antarchy.royal_guardian_sword.frost"),
|
||||
STORM(2, "tooltip.antarchy.royal_guardian_sword.mode.storm", "tooltip.antarchy.royal_guardian_sword.storm");
|
||||
|
||||
private final int id;
|
||||
private final String translationKey;
|
||||
private final String tooltipKey;
|
||||
|
||||
Mode(String translationKey, String tooltipKey) {
|
||||
Mode(int id, String translationKey, String tooltipKey) {
|
||||
this.id = id;
|
||||
this.translationKey = translationKey;
|
||||
this.tooltipKey = tooltipKey;
|
||||
}
|
||||
|
||||
public Mode next() {
|
||||
return values()[(this.ordinal() + 1) % values().length];
|
||||
return switch (this) {
|
||||
case NONE -> FIRE;
|
||||
case FIRE -> FROST;
|
||||
case FROST -> STORM;
|
||||
case STORM -> NONE;
|
||||
};
|
||||
}
|
||||
|
||||
private static Mode fromId(int id) {
|
||||
for (Mode mode : values()) {
|
||||
if (mode.id == id) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.craisinlord.antarchy.content.time.TemporalTunerAccess;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class TemporalTunerItem extends Item {
|
||||
public static final double STEP = 0.1D;
|
||||
private static final String RATE_TAG = "TemporalTunerRate";
|
||||
|
||||
public TemporalTunerItem(Properties properties) {
|
||||
super(properties.stacksTo(1));
|
||||
}
|
||||
|
||||
public static boolean isAvailable(Player player) {
|
||||
return player.getInventory().contains(stack -> stack.getItem() instanceof TemporalTunerItem)
|
||||
&& (player.getMainHandItem().getItem() instanceof TemporalTunerItem
|
||||
|| player.getOffhandItem().getItem() instanceof TemporalTunerItem
|
||||
|| hasHotbarTuner(player));
|
||||
}
|
||||
|
||||
private static boolean hasHotbarTuner(Player player) {
|
||||
for (int slot = 0; slot < 9; slot++) {
|
||||
if (player.getInventory().getItem(slot).getItem() instanceof TemporalTunerItem) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static double clampRate(double rate) {
|
||||
return Math.max(AntarchySettings.temporalTunerMinRate(), Math.min(AntarchySettings.temporalTunerMaxRate(), rate));
|
||||
}
|
||||
|
||||
public static void adjust(Player player, double delta) {
|
||||
if (!(player instanceof TemporalTunerAccess access) || !isAvailable(player)) {
|
||||
return;
|
||||
}
|
||||
double previousRate = getRate(player);
|
||||
double updatedRate = clampRate(previousRate + delta);
|
||||
access.antarchy$setTemporalTunerRate(updatedRate);
|
||||
if (Math.abs(updatedRate - previousRate) >= 0.001D) {
|
||||
player.playSound(SoundEvents.NOTE_BLOCK_HAT.value(), 0.6F, 1.0F);
|
||||
}
|
||||
syncTooltipRate(player, getRate(player));
|
||||
}
|
||||
|
||||
public static double getRate(Player player) {
|
||||
return player instanceof TemporalTunerAccess access ? clampRate(access.antarchy$getTemporalTunerRate()) : 1.0D;
|
||||
}
|
||||
|
||||
public static void syncTooltipRate(Player player, double rate) {
|
||||
for (int slot = 0; slot < 9; slot++) {
|
||||
updateStackRate(player.getInventory().getItem(slot), rate);
|
||||
}
|
||||
updateStackRate(player.getOffhandItem(), rate);
|
||||
}
|
||||
|
||||
private static void updateStackRate(ItemStack stack, double rate) {
|
||||
if (stack.getItem() instanceof TemporalTunerItem) {
|
||||
CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> tag.putDouble(RATE_TAG, rate));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> tooltip, TooltipFlag flag) {
|
||||
tooltip.add(Component.translatable("tooltip.antarchy.temporal_tuner.description").withStyle(ChatFormatting.RED));
|
||||
double rate = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag().getDouble(RATE_TAG);
|
||||
if (rate <= 0.0D) {
|
||||
rate = 1.0D;
|
||||
}
|
||||
tooltip.add(Component.translatable("tooltip.antarchy.temporal_tuner.speed", (int) Math.round(rate * 100.0D)).withStyle(ChatFormatting.GRAY));
|
||||
tooltip.add(Component.translatable("tooltip.antarchy.temporal_tuner.controls", (int) (AntarchySettings.temporalTunerMinRate() * 100), (int) (AntarchySettings.temporalTunerMaxRate() * 100)).withStyle(ChatFormatting.GRAY));
|
||||
tooltip.add(Component.translatable("tooltip.antarchy.temporal_tuner.availability").withStyle(ChatFormatting.RED));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.craisinlord.antarchy.content.menu;
|
||||
|
||||
import com.craisinlord.antarchy.content.AntarchyObjects;
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanItem;
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanStorage;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public final class GiantFryingPanMenu extends AbstractContainerMenu {
|
||||
private final GiantFryingPanStorage panStorage;
|
||||
|
||||
public GiantFryingPanMenu(int containerId, Inventory inventory) {
|
||||
super(AntarchyObjects.GIANT_FRYING_PAN_MENU.get(), containerId);
|
||||
ItemStack pan = GiantFryingPanStorage.findPan(inventory.player);
|
||||
this.panStorage = new GiantFryingPanStorage(pan, inventory.player);
|
||||
for (int slot = 0; slot < GiantFryingPanStorage.SLOT_COUNT; slot++) {
|
||||
this.addSlot(new Slot(panStorage, slot, 8 + slot * 18, 18) {
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return GiantFryingPanStorage.isCampfireInput(inventory.player, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() { return 1; }
|
||||
});
|
||||
}
|
||||
for (int row = 0; row < 3; row++) {
|
||||
for (int col = 0; col < 9; col++) {
|
||||
this.addSlot(new Slot(inventory, col + row * 9 + 9, 8 + col * 18, 50 + row * 18));
|
||||
}
|
||||
}
|
||||
for (int col = 0; col < 9; col++) this.addSlot(new Slot(inventory, col, 8 + col * 18, 108));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) { return player.isAlive() && !panStorage.isEmpty() || GiantFryingPanStorage.findPan(player).getItem() instanceof GiantFryingPanItem; }
|
||||
|
||||
@Override
|
||||
public ItemStack quickMoveStack(Player player, int index) {
|
||||
if (index < 0 || index >= slots.size()) return ItemStack.EMPTY;
|
||||
Slot slot = slots.get(index);
|
||||
if (!slot.hasItem()) return ItemStack.EMPTY;
|
||||
ItemStack original = slot.getItem().copy();
|
||||
if (index < GiantFryingPanStorage.SLOT_COUNT) {
|
||||
if (!moveItemStackTo(slot.getItem(), GiantFryingPanStorage.SLOT_COUNT, slots.size(), true)) return ItemStack.EMPTY;
|
||||
} else if (!moveItemStackTo(slot.getItem(), 0, GiantFryingPanStorage.SLOT_COUNT, false)) return ItemStack.EMPTY;
|
||||
if (slot.getItem().isEmpty()) slot.setByPlayer(ItemStack.EMPTY);
|
||||
else slot.setChanged();
|
||||
return original;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.craisinlord.antarchy.content.network;
|
||||
|
||||
import com.craisinlord.antarchy.Antarchy;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public record TemporalTunerScrollPayload(double delta) implements CustomPacketPayload {
|
||||
public static final Type<TemporalTunerScrollPayload> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "temporal_tuner_scroll"));
|
||||
public static final StreamCodec<ByteBuf, TemporalTunerScrollPayload> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.DOUBLE, TemporalTunerScrollPayload::delta, TemporalTunerScrollPayload::new);
|
||||
|
||||
@Override
|
||||
public Type<TemporalTunerScrollPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.craisinlord.antarchy.content.portal;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.vehicle.DismountHelper;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.portal.DimensionTransition;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class CrossDimensionTravelApi {
|
||||
private static final int HORIZONTAL_SEARCH_RADIUS = 8;
|
||||
private static final int VERTICAL_SEARCH_RADIUS = 8;
|
||||
|
||||
private CrossDimensionTravelApi() {
|
||||
}
|
||||
|
||||
public static boolean transferToSafePosition(Entity entity, ServerLevel destination, BlockPos preferred) {
|
||||
if (!entity.isAlive() || !(entity.level() instanceof ServerLevel source)) {
|
||||
return false;
|
||||
}
|
||||
Vec3 arrival = findSafePosition(entity, destination, preferred);
|
||||
if (arrival == null) {
|
||||
return false;
|
||||
}
|
||||
if (entity instanceof ServerPlayer player) {
|
||||
player.teleportTo(destination, arrival.x, arrival.y, arrival.z, player.getYRot(), player.getXRot());
|
||||
player.setPortalCooldown();
|
||||
return true;
|
||||
}
|
||||
if (source == destination) {
|
||||
entity.teleportTo(arrival.x, arrival.y, arrival.z);
|
||||
entity.setPortalCooldown();
|
||||
return true;
|
||||
}
|
||||
Entity moved = entity.changeDimension(new DimensionTransition(
|
||||
destination,
|
||||
arrival,
|
||||
Vec3.ZERO,
|
||||
entity.getYRot(),
|
||||
entity.getXRot(),
|
||||
DimensionTransition.PLAY_PORTAL_SOUND
|
||||
));
|
||||
if (moved != null) {
|
||||
moved.setPortalCooldown();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Vec3 findSafePosition(Entity entity, ServerLevel destination, BlockPos preferred) {
|
||||
Set<BlockPos> candidates = new LinkedHashSet<>();
|
||||
candidates.add(preferred);
|
||||
for (int radius = 0; radius <= HORIZONTAL_SEARCH_RADIUS; radius++) {
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
for (int z = -radius; z <= radius; z++) {
|
||||
if (radius > 0 && Math.abs(x) != radius && Math.abs(z) != radius) {
|
||||
continue;
|
||||
}
|
||||
BlockPos column = preferred.offset(x, 0, z);
|
||||
if (destination.hasChunkAt(column)) {
|
||||
BlockPos surface = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, column);
|
||||
candidates.add(surface);
|
||||
candidates.add(surface.above());
|
||||
}
|
||||
for (int y = 0; y <= VERTICAL_SEARCH_RADIUS; y++) {
|
||||
candidates.add(column.above(y));
|
||||
if (y > 0) {
|
||||
candidates.add(column.below(y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (BlockPos candidate : candidates) {
|
||||
if (!isAreaLoaded(destination, candidate)) {
|
||||
continue;
|
||||
}
|
||||
Vec3 safe = DismountHelper.findSafeDismountLocation(entity.getType(), destination, candidate, true);
|
||||
if (safe != null && isValidPosition(destination, safe)) {
|
||||
return safe;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isAreaLoaded(ServerLevel level, BlockPos center) {
|
||||
if (center.getY() <= level.getMinBuildHeight() || center.getY() >= level.getMaxBuildHeight() - 1
|
||||
|| !level.getWorldBorder().isWithinBounds(center)) {
|
||||
return false;
|
||||
}
|
||||
for (Direction direction : Direction.values()) {
|
||||
if (!level.hasChunkAt(center.relative(direction))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return level.hasChunkAt(center) && level.hasChunkAt(center.above());
|
||||
}
|
||||
|
||||
private static boolean isValidPosition(ServerLevel level, Vec3 position) {
|
||||
BlockPos feet = BlockPos.containing(position);
|
||||
BlockPos head = feet.above();
|
||||
BlockState feetState = level.getBlockState(feet);
|
||||
BlockState headState = level.getBlockState(head);
|
||||
return feetState.getFluidState().isEmpty() && headState.getFluidState().isEmpty()
|
||||
&& feetState.getCollisionShape(level, feet).isEmpty()
|
||||
&& headState.getCollisionShape(level, head).isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.craisinlord.antarchy.content.time;
|
||||
|
||||
public interface TemporalTunerAccess {
|
||||
double antarchy$getTemporalTunerRate();
|
||||
|
||||
void antarchy$setTemporalTunerRate(double rate);
|
||||
}
|
||||
@@ -12,6 +12,8 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import com.craisinlord.antarchy.content.item.TemporalTunerItem;
|
||||
import com.craisinlord.antarchy.content.effect.DilatedMobEffect;
|
||||
import com.craisinlord.antarchy.content.effect.ContractedMobEffect;
|
||||
import com.craisinlord.antarchy.content.effect.RoyalEffectEligibility;
|
||||
@@ -35,6 +37,9 @@ public final class TimeDilationManager {
|
||||
}
|
||||
}
|
||||
TrackingState tracking = TRACKING.get(level);
|
||||
for (ServerPlayer player : level.players()) {
|
||||
trackPotentiallyAffected(player);
|
||||
}
|
||||
if (activeFields == null && (tracking == null || tracking.entities.isEmpty())) {
|
||||
continue;
|
||||
}
|
||||
@@ -64,13 +69,15 @@ public final class TimeDilationManager {
|
||||
if (!(entity.level() instanceof ServerLevel level) || entity instanceof TimeDilationFieldEntity) {
|
||||
return;
|
||||
}
|
||||
boolean hasTuner = entity instanceof Player player && TemporalTunerItem.isAvailable(player);
|
||||
boolean hasEffect = entity instanceof net.minecraft.world.entity.LivingEntity living
|
||||
&& ((RoyalEffectHooks.dilatedHolder() != null && living.hasEffect(RoyalEffectHooks.dilatedHolder()))
|
||||
|| (RoyalEffectHooks.contractedHolder() != null && living.hasEffect(RoyalEffectHooks.contractedHolder())));
|
||||
if (entity instanceof TimeDilationEntityAccess access
|
||||
&& Math.abs(access.antarchy$getTimeDilationRate() - TimeDilationMath.NORMAL_RATE) < 0.001D
|
||||
&& Math.abs(access.antarchy$getInheritedTimeDilationRate() - TimeDilationMath.NORMAL_RATE) < 0.001D
|
||||
&& Math.abs(TimeDilationApi.getVehicleRate(entity) - TimeDilationMath.NORMAL_RATE) < 0.001D
|
||||
&& (!(entity instanceof net.minecraft.world.entity.LivingEntity living)
|
||||
|| ((RoyalEffectHooks.dilatedHolder() == null || !living.hasEffect(RoyalEffectHooks.dilatedHolder()))
|
||||
&& (RoyalEffectHooks.contractedHolder() == null || !living.hasEffect(RoyalEffectHooks.contractedHolder()))))) {
|
||||
&& !hasTuner && !hasEffect) {
|
||||
return;
|
||||
}
|
||||
TRACKING.computeIfAbsent(level, ignored -> new TrackingState()).entities.add(entity);
|
||||
@@ -165,6 +172,15 @@ public final class TimeDilationManager {
|
||||
effectRate = Math.max(effectRate, ContractedMobEffect.rateForAmplifier(effect.getAmplifier()));
|
||||
}
|
||||
}
|
||||
double tunerRate = TimeDilationMath.NORMAL_RATE;
|
||||
if (entity instanceof Player player && player instanceof TemporalTunerAccess tunerAccess) {
|
||||
if (TemporalTunerItem.isAvailable(player)) {
|
||||
tunerRate = TemporalTunerItem.getRate(player);
|
||||
} else {
|
||||
tunerAccess.antarchy$setTemporalTunerRate(TimeDilationMath.NORMAL_RATE);
|
||||
TemporalTunerItem.syncTooltipRate(player, TimeDilationMath.NORMAL_RATE);
|
||||
}
|
||||
}
|
||||
double inheritedRate = access.antarchy$getInheritedTimeDilationRate();
|
||||
double vehicleRate = TimeDilationApi.getVehicleRate(entity);
|
||||
if (vehicleRate < TimeDilationMath.NORMAL_RATE) {
|
||||
@@ -190,6 +206,11 @@ public final class TimeDilationManager {
|
||||
} else {
|
||||
fastRate = Math.max(fastRate, effectRate);
|
||||
}
|
||||
if (tunerRate < TimeDilationMath.NORMAL_RATE) {
|
||||
slowRate = Math.min(slowRate, tunerRate);
|
||||
} else {
|
||||
fastRate = Math.max(fastRate, tunerRate);
|
||||
}
|
||||
if (inheritedRate < TimeDilationMath.NORMAL_RATE) {
|
||||
slowRate = Math.min(slowRate, inheritedRate);
|
||||
} else {
|
||||
|
||||
@@ -16,7 +16,8 @@ public abstract class AlexsCavesDepthChargeMixin {
|
||||
@ModifyArg(
|
||||
method = "tick",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/Vec3;add(DDD)Lnet/minecraft/world/phys/Vec3;"),
|
||||
index = 1
|
||||
index = 1,
|
||||
require = 0
|
||||
)
|
||||
private double antarchy$invertManualGravity(double y) {
|
||||
Projectile self = (Projectile) (Object) this;
|
||||
|
||||
@@ -18,7 +18,7 @@ public abstract class LivingEntityTimeDilationMixin {
|
||||
private void antarchy$trackTemporalEffects(CallbackInfo ci) {
|
||||
Entity entity = (Entity) (Object) this;
|
||||
TimeDilationManager.trackPotentiallyAffected(entity);
|
||||
if (entity.level().isClientSide && RoyalEffectHooks.contractedHolder() != null) {
|
||||
if (entity.level().isClientSide) {
|
||||
ContractionAfterimages.observe((LivingEntity) entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.craisinlord.antarchy.mixins.time;
|
||||
|
||||
import com.craisinlord.antarchy.content.time.TimeDilationMath;
|
||||
import com.craisinlord.antarchy.content.time.TemporalTunerAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Player.class)
|
||||
public abstract class PlayerTemporalTunerMixin implements TemporalTunerAccess {
|
||||
@Unique
|
||||
private double antarchy$temporalTunerRate = TimeDilationMath.NORMAL_RATE;
|
||||
|
||||
@Override
|
||||
public double antarchy$getTemporalTunerRate() {
|
||||
return antarchy$temporalTunerRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void antarchy$setTemporalTunerRate(double rate) {
|
||||
antarchy$temporalTunerRate = TimeDilationMath.clampRate(rate);
|
||||
}
|
||||
|
||||
@Inject(method = "addAdditionalSaveData", at = @At("TAIL"))
|
||||
private void antarchy$saveTemporalTunerRate(CompoundTag tag, CallbackInfo ci) {
|
||||
tag.putDouble("AntarchyTemporalTunerRate", antarchy$temporalTunerRate);
|
||||
}
|
||||
|
||||
@Inject(method = "readAdditionalSaveData", at = @At("TAIL"))
|
||||
private void antarchy$loadTemporalTunerRate(CompoundTag tag, CallbackInfo ci) {
|
||||
antarchy$temporalTunerRate = TimeDilationMath.clampRate(tag.getDouble("AntarchyTemporalTunerRate"));
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,7 @@
|
||||
"time.EntityDeltaMovementTimeDilationMixin",
|
||||
"time.EntityMoveTimeDilationMixin",
|
||||
"time.EntityTimeDilationStateMixin",
|
||||
"time.PlayerTemporalTunerMixin",
|
||||
"time.EntityRotationTimeDilationMixin",
|
||||
"time.EntityCrouchTimeDilationMixin",
|
||||
"time.LivingEntityKnockbackTimeDilationMixin",
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
{
|
||||
"format_version": "1.21.110",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.unknown",
|
||||
"texture_width": 128,
|
||||
"texture_height": 128,
|
||||
"visible_bounds_width": 4,
|
||||
"visible_bounds_height": 6,
|
||||
"visible_bounds_offset": [0, 2, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
"name": "giant_frying_pan",
|
||||
"pivot": [0, -2, 0],
|
||||
"cubes": [
|
||||
{"origin": [-1, 0, -1], "size": [2, 20, 2], "uv": [16, 0]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "handle",
|
||||
"parent": "giant_frying_pan",
|
||||
"pivot": [0, -2, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-2, -16, -2],
|
||||
"size": [4, 16, 4],
|
||||
"uv": {
|
||||
"north": {"uv": [4, 4], "uv_size": [4, 16]},
|
||||
"east": {"uv": [8, 4], "uv_size": [-4, 16]},
|
||||
"south": {"uv": [4, 4], "uv_size": [4, 16]},
|
||||
"west": {"uv": [8, 4], "uv_size": [-4, 16]},
|
||||
"up": {"uv": [4, 0], "uv_size": [4, 4]},
|
||||
"down": {"uv": [8, 4], "uv_size": [4, -4]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pan_base",
|
||||
"parent": "giant_frying_pan",
|
||||
"pivot": [0, 38, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-18, 22, 1],
|
||||
"size": [36, 36, 2],
|
||||
"uv": {
|
||||
"north": {"uv": [0, 22], "uv_size": [36, 36]},
|
||||
"east": {"uv": [26, 66], "uv_size": [2, 36]},
|
||||
"south": {"uv": [36, 0], "uv_size": [36, 36]},
|
||||
"west": {"uv": [28, 66], "uv_size": [2, 36]},
|
||||
"up": {"uv": [102, 64], "uv_size": [-36, -2]},
|
||||
"down": {"uv": [102, 66], "uv_size": [-36, -2]}
|
||||
}
|
||||
},
|
||||
{
|
||||
"origin": [18, 22, -3],
|
||||
"size": [2, 36, 6],
|
||||
"uv": {
|
||||
"north": {"uv": [64, 62], "uv_size": [2, 36]},
|
||||
"east": {"uv": [0, 58], "uv_size": [6, 36]},
|
||||
"south": {"uv": [24, 66], "uv_size": [2, 36]},
|
||||
"west": {"uv": [38, 54], "uv_size": [36, -6], "uv_rotation": 90},
|
||||
"up": {"uv": [26, 10], "uv_size": [-2, -6]},
|
||||
"down": {"uv": [26, 16], "uv_size": [-2, -6]}
|
||||
}
|
||||
},
|
||||
{
|
||||
"origin": [-20, 20, -3],
|
||||
"size": [40, 2, 6],
|
||||
"uv": {
|
||||
"north": {"uv": [24, 60], "uv_size": [40, 2]},
|
||||
"east": {"uv": [74, 48], "uv_size": [2, 6], "uv_rotation": 90},
|
||||
"south": {"uv": [24, 62], "uv_size": [40, 2]},
|
||||
"west": {"uv": [38, 54], "uv_size": [-2, -6], "uv_rotation": 90},
|
||||
"up": {"uv": [76, 42], "uv_size": [-40, -6]},
|
||||
"down": {"uv": [76, 48], "uv_size": [-40, 6]}
|
||||
}
|
||||
},
|
||||
{
|
||||
"origin": [-20, 22, -3],
|
||||
"size": [2, 36, 6],
|
||||
"uv": {
|
||||
"north": {"uv": [30, 66], "uv_size": [2, 36]},
|
||||
"east": {"uv": [38, 48], "uv_size": [36, 6], "uv_rotation": 90},
|
||||
"south": {"uv": [32, 66], "uv_size": [2, 36]},
|
||||
"west": {"uv": [18, 58], "uv_size": [6, 36]},
|
||||
"up": {"uv": [26, 22], "uv_size": [-2, -6]},
|
||||
"down": {"uv": [28, 10], "uv_size": [-2, -6]}
|
||||
}
|
||||
},
|
||||
{
|
||||
"origin": [-20, 58, -3],
|
||||
"size": [40, 2, 6],
|
||||
"uv": {
|
||||
"north": {"uv": [24, 64], "uv_size": [40, 2]},
|
||||
"east": {"uv": [36, 48], "uv_size": [2, 6], "uv_rotation": 90},
|
||||
"south": {"uv": [64, 60], "uv_size": [40, 2]},
|
||||
"west": {"uv": [36, 54], "uv_size": [2, -6], "uv_rotation": 90},
|
||||
"up": {"uv": [76, 54], "uv_size": [-40, -6]},
|
||||
"down": {"uv": [76, 60], "uv_size": [-40, -6]}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "antarchy:item/blood_gods_blade"
|
||||
}
|
||||
}
|
||||
@@ -321,6 +321,10 @@
|
||||
"subtitles.antarchy.mantis_attack": "Mantis snaps",
|
||||
"subtitles.antarchy.mantis_fly_loop": "Mantis wings buzz",
|
||||
"item.antarchy.big_bertha": "Big Bertha",
|
||||
"item.antarchy.giant_frying_pan": "Giant Frying Pan",
|
||||
"tooltip.antarchy.giant_frying_pan.insert": "Right-click with food to add it to the pan.",
|
||||
"tooltip.antarchy.giant_frying_pan.gui": "Shift-right-click to open the cooking slots.",
|
||||
"tooltip.antarchy.giant_frying_pan.campfire": "Cooks campfire recipes without fuel.",
|
||||
"item.antarchy.bluestone": "Bluestone Dust",
|
||||
"item.antarchy.wasp_nest": "Wasp Nest",
|
||||
"item.antarchy.stink_bug": "Stink Bug",
|
||||
@@ -528,6 +532,11 @@
|
||||
"item.antarchy.blood_crystal_shard": "Blood Crystal Shard",
|
||||
"item.antarchy.blood_crystal_apple": "Blood Crystal Apple",
|
||||
"item.antarchy.blood_crystal_katana": "Blood Crystal Katana",
|
||||
"item.antarchy.blood_gods_blade": "Blood God’s Blade",
|
||||
"tooltip.antarchy.blood_gods_blade.bleeding": "Hits inflict Bleeding",
|
||||
"tooltip.antarchy.blood_gods_blade.blood_moon": "Right-click: Summon Blood Moon",
|
||||
"effect.antarchy.bleeding": "Bleeding",
|
||||
"effect.antarchy.blood_moon": "Blood Moon",
|
||||
"item.antarchy.blood_crystal_helmet": "Blood Crystal Helmet",
|
||||
"item.antarchy.blood_crystal_chestplate": "Blood Crystal Chestplate",
|
||||
"item.antarchy.blood_crystal_leggings": "Blood Crystal Leggings",
|
||||
@@ -548,9 +557,11 @@
|
||||
"item.antarchy.royal_guardian_sword": "Royal Guardian Sword",
|
||||
"item.antarchy.royal_guardian_shield": "Royal Guardian Shield",
|
||||
"tooltip.antarchy.royal_guardian_sword.mode": "Mode: %s",
|
||||
"tooltip.antarchy.royal_guardian_sword.mode.none": "None",
|
||||
"tooltip.antarchy.royal_guardian_sword.mode.fire": "Fire",
|
||||
"tooltip.antarchy.royal_guardian_sword.mode.frost": "Frost",
|
||||
"tooltip.antarchy.royal_guardian_sword.mode.storm": "Storm",
|
||||
"tooltip.antarchy.royal_guardian_sword.none": "Fully charged hits use the sword's normal damage without an elemental discharge.",
|
||||
"tooltip.antarchy.royal_guardian_sword.fire": "Fully charged hits erupt in royal flame, burning the target and nearby enemies.",
|
||||
"tooltip.antarchy.royal_guardian_sword.frost": "Fully charged hits freeze the target and raise a fan of royal ice spikes.",
|
||||
"tooltip.antarchy.royal_guardian_sword.storm": "Fully charged hits call royal lightning that chains between nearby enemies.",
|
||||
@@ -577,6 +588,11 @@
|
||||
"tooltip.antarchy.mantis_claw.wall_cling": "Dual wield to cling to walls and jump upward.",
|
||||
"item.antarchy.king_scale": "King Scale",
|
||||
"item.antarchy.queen_scale": "Queen Scale",
|
||||
"item.antarchy.temporal_tuner": "Temporal Tuner",
|
||||
"tooltip.antarchy.temporal_tuner.description": "Adjusts your personal time dilation.",
|
||||
"tooltip.antarchy.temporal_tuner.speed": "Current speed: %s%%",
|
||||
"tooltip.antarchy.temporal_tuner.controls": "Shift + scroll: %s%% to %s%% speed",
|
||||
"tooltip.antarchy.temporal_tuner.availability": "Resets when removed from your hotbar and offhand.",
|
||||
"item.antarchy.jerry_nucleus": "Jerry Nucleus",
|
||||
"tooltip.antarchy.jerry_nucleus.hatch": "While holding, interact with any bug egg or turtle egg to hatch it instantly.",
|
||||
"key.antarchy.mount_special": "Mount: Special / Charge",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/handheld",
|
||||
"textures": {
|
||||
"layer0": "antarchy:item/blood_gods_blade"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"gui_light": "front",
|
||||
"textures": {
|
||||
"layer0": "antarchy:item/giant_frying_pan/giant_frying_pan_in_hand"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "builtin/entity",
|
||||
"texture_size": [
|
||||
128,
|
||||
128
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [
|
||||
-25,
|
||||
-180,
|
||||
0
|
||||
],
|
||||
"translation": [
|
||||
0,
|
||||
-4,
|
||||
3
|
||||
],
|
||||
"scale": [
|
||||
1.2,
|
||||
1.2,
|
||||
1.2
|
||||
]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [
|
||||
-25,
|
||||
-180,
|
||||
0
|
||||
],
|
||||
"translation": [
|
||||
0,
|
||||
-4,
|
||||
3
|
||||
],
|
||||
"scale": [
|
||||
1.2,
|
||||
1.2,
|
||||
1.2
|
||||
]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [
|
||||
-75,
|
||||
-180,
|
||||
15
|
||||
],
|
||||
"translation": [
|
||||
10,
|
||||
-5,
|
||||
10
|
||||
],
|
||||
"scale": [
|
||||
0.68,
|
||||
0.68,
|
||||
0.68
|
||||
]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [
|
||||
-75,
|
||||
-180,
|
||||
15
|
||||
],
|
||||
"translation": [
|
||||
10,
|
||||
-5,
|
||||
10
|
||||
],
|
||||
"scale": [
|
||||
0.68,
|
||||
0.68,
|
||||
0.68
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [
|
||||
0,
|
||||
2,
|
||||
0
|
||||
],
|
||||
"scale": [
|
||||
0.2,
|
||||
0.2,
|
||||
0.2
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "antarchy:item/temporal_tuner"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 8.8 KiB |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"animation": {
|
||||
"frametime": 5,
|
||||
"interpolate": true
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"animation": {
|
||||
"frametime": 5,
|
||||
"interpolate": true
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1002 B |
|
After Width: | Height: | Size: 270 B |
|
After Width: | Height: | Size: 219 B |
|
After Width: | Height: | Size: 181 B |
|
After Width: | Height: | Size: 176 B |
|
After Width: | Height: | Size: 140 B |
|
After Width: | Height: | Size: 489 B |
|
Before Width: | Height: | Size: 335 B After Width: | Height: | Size: 509 B |
|
Before Width: | Height: | Size: 348 B After Width: | Height: | Size: 509 B |
|
After Width: | Height: | Size: 395 B |
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 544 B |
|
Before Width: | Height: | Size: 312 B After Width: | Height: | Size: 369 B |
|
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 440 B |
|
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 447 B |
|
After Width: | Height: | Size: 192 B |
@@ -124,6 +124,11 @@
|
||||
"name": "antarchy:music_disc_verdance",
|
||||
"weight": 2
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antarchy:blood_gods_blade",
|
||||
"weight": 1
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antos:floppy_disk",
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "equipment",
|
||||
"pattern": [
|
||||
"NNN",
|
||||
"NNN",
|
||||
" S "
|
||||
],
|
||||
"key": {
|
||||
"N": {
|
||||
"item": "minecraft:netherite_block"
|
||||
},
|
||||
"S": {
|
||||
"item": "antarchy:ultimate_shovel"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"id": "antarchy:giant_frying_pan",
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"category": "misc",
|
||||
"pattern": [
|
||||
"QSQ",
|
||||
"QCQ",
|
||||
"QQQ"
|
||||
],
|
||||
"key": {
|
||||
"S": {
|
||||
"item": "antarchy:blood_crystal_shard"
|
||||
},
|
||||
"Q": {
|
||||
"item": "antarchy:queen_scale"
|
||||
},
|
||||
"C": {
|
||||
"item": "minecraft:compass"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"id": "antarchy:temporal_tuner",
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"antarchy:ultimate_sword",
|
||||
"antarchy:battle_axe",
|
||||
"antarchy:big_bertha",
|
||||
"antarchy:giant_frying_pan",
|
||||
"antarchy:nightmare_sword",
|
||||
"antarchy:basilisk_dagger",
|
||||
"antarchy:ultimate_bow",
|
||||
@@ -23,6 +24,7 @@
|
||||
"antarchy:nightmare_boots",
|
||||
"antarchy:moggles",
|
||||
"antarchy:blood_crystal_katana",
|
||||
"antarchy:blood_gods_blade",
|
||||
"antarchy:mantis_claw",
|
||||
"antarchy:krakens_grasp",
|
||||
"antarchy:blood_crystal_helmet",
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
"antarchy:ultimate_axe",
|
||||
"antarchy:ultimate_sword",
|
||||
"antarchy:big_bertha",
|
||||
"antarchy:giant_frying_pan",
|
||||
"antarchy:nightmare_sword",
|
||||
"antarchy:basilisk_dagger",
|
||||
"antarchy:blood_crystal_katana",
|
||||
"antarchy:blood_gods_blade",
|
||||
"antarchy:mantis_claw",
|
||||
"antarchy:royal_guardian_sword",
|
||||
"antarchy:royal_assailant_battleaxe"
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
"antarchy:nightmare_sword",
|
||||
"antarchy:basilisk_dagger",
|
||||
"antarchy:big_bertha",
|
||||
"antarchy:giant_frying_pan",
|
||||
"antarchy:blood_crystal_katana",
|
||||
"antarchy:blood_gods_blade",
|
||||
"antarchy:mantis_claw",
|
||||
"antarchy:royal_guardian_sword"
|
||||
]
|
||||
|
||||