bumped required infinity version
fixed server client split issue fr this time Buffed frying pan Fixed prince princess anim bug
This commit is contained in:
1 parent
3316df7195
commit
5010b6b7e1
72 files changed
+595
-282
No files matched your search
@@ -18,7 +18,7 @@ tasks.named('jar').configure {
|
||||
|
||||
dependencies {
|
||||
compileOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_neoforge}")
|
||||
compileOnly(files("$rootDir/infinite_dimensions_jars/infinity-2.7.2+1.21.1-neoforge.jar"))
|
||||
compileOnly(files("$rootDir/infinite_dimensions_jars/infinity-2.7.3+1.21.1-neoforge.jar"))
|
||||
compileOnly(files("$rootDir/infinite_dimensions_jars/gravity-api-1.0.7-1.20.1.jar"))
|
||||
compileOnly(files("$rootDir/infinite_dimensions_jars/sable-neoforge-1.21.1-2.0.3.jar"))
|
||||
compileOnly(files("$rootDir/sizeable_foliage_jars/sizeable_foliage-neoforge-1.21.1-1.0.0.jar"))
|
||||
|
||||
@@ -11,6 +11,7 @@ public class Antarchy {
|
||||
public static final String MODID = "antarchy";
|
||||
public static final String MOD_VERSION = "2.0.0";
|
||||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
public static volatile boolean physicalClient;
|
||||
|
||||
public static void init() {
|
||||
AttributeRangeInit.apply();
|
||||
|
||||
@@ -232,6 +232,7 @@ public final class AntarchySettings {
|
||||
private static double royalAssailantBootsDoubleDamageChance = 0.05D;
|
||||
private static double royalGuardianSwordAttackDamage = 111.0D;
|
||||
private static double giantFryingPanAttackDamage = 50.0D;
|
||||
private static int giantFryingPanCookTimeTicks = 200;
|
||||
private static double royalGuardianSwordAttackSpeed = -2.5D;
|
||||
private static int royalGuardianSwordElementalCooldownTicks = 120;
|
||||
private static double royalGuardianSwordFirePrimaryDamage = 22.0D;
|
||||
@@ -2062,6 +2063,8 @@ public final class AntarchySettings {
|
||||
public static void setRoyalGuardianSwordAttackDamage(double v) { royalGuardianSwordAttackDamage = v; }
|
||||
public static double giantFryingPanAttackDamage() { return giantFryingPanAttackDamage; }
|
||||
public static void setGiantFryingPanAttackDamage(double v) { giantFryingPanAttackDamage = v; }
|
||||
public static int giantFryingPanCookTimeTicks() { return giantFryingPanCookTimeTicks; }
|
||||
public static void setGiantFryingPanCookTimeTicks(int v) { giantFryingPanCookTimeTicks = v; }
|
||||
|
||||
public static double royalGuardianSwordAttackSpeed() { return royalGuardianSwordAttackSpeed; }
|
||||
public static void setRoyalGuardianSwordAttackSpeed(double v) { royalGuardianSwordAttackSpeed = v; }
|
||||
|
||||
+1
-10
@@ -2,7 +2,6 @@ package com.craisinlord.antarchy.content.client;
|
||||
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.craisinlord.antarchy.content.item.NightmareSwordItem;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -16,14 +15,6 @@ public final class NightmareSwordTooltipHelper {
|
||||
float damage = player != null
|
||||
? NightmareSwordItem.calculateDamage(player)
|
||||
: (float) AntarchySettings.nightmareSwordBaseDamage();
|
||||
return Component.translatable("tooltip.antarchy.nightmare_sword_damage", formatDamage(damage)).withStyle(ChatFormatting.RED);
|
||||
}
|
||||
|
||||
private static String formatDamage(float damage) {
|
||||
float rounded = Math.round(damage * 10.0F) / 10.0F;
|
||||
if (rounded == (int) rounded) {
|
||||
return String.valueOf((int) rounded);
|
||||
}
|
||||
return String.valueOf(rounded);
|
||||
return NightmareSwordItem.damageLine(damage);
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -2,6 +2,7 @@ package com.craisinlord.antarchy.content.creative;
|
||||
|
||||
import com.craisinlord.antarchy.content.AntarchyObjects;
|
||||
import com.craisinlord.antarchy.content.entity.glimmer.GlimmerVariant;
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanToolHelper;
|
||||
import com.craisinlord.antarchy.content.item.GlimmerBottleItem;
|
||||
import com.craisinlord.antarchy.content.item.royal.RoyalGearHelper;
|
||||
import com.craisinlord.antarchy.content.item.ultimate.UltimateGearHelper;
|
||||
@@ -645,7 +646,7 @@ public final class CreativeTabContents {
|
||||
acceptPotionFamily(output, potionPath);
|
||||
}
|
||||
for (String diskId : List.of("antarchy:introduction", "antarchy:toreterror_arena", "antarchy:high_fructose_corn_syrup",
|
||||
"antarchy:elythia", "antarchy:flying_squirrel", "antarchy:cavaryn", "antarchy:thoraxis", "antarchy:temporal_fields", "antarchy:bloodglass", "antarchy:vortex")) {
|
||||
"antarchy:elythia", "antarchy:flying_squirrel", "antarchy:brutalfly", "antarchy:rainbow_ant", "antarchy:cavaryn", "antarchy:hercules_beetle", "antarchy:thoraxis", "antarchy:temporal_fields", "antarchy:bloodglass", "antarchy:vortex")) {
|
||||
ItemStack disk = new ItemStack(com.craisinlord.antos.content.AntOSObjects.FLOPPY_DISK.get());
|
||||
disk.set(com.craisinlord.antos.content.AntOSObjects.FLOPPY_DISK_COMPONENT.get(), ResourceLocation.parse(diskId));
|
||||
output.accept(disk);
|
||||
@@ -677,6 +678,10 @@ public final class CreativeTabContents {
|
||||
output.accept(RoyalGearHelper.createRoyalArmorStack(item(entry.path()), holders));
|
||||
continue;
|
||||
}
|
||||
if ("giant_frying_pan".equals(entry.path())) {
|
||||
output.accept(GiantFryingPanToolHelper.createStack(item(entry.path()), holders));
|
||||
continue;
|
||||
}
|
||||
if ("ultimate_bow".equals(entry.path())) {
|
||||
output.accept(UltimateGearHelper.createUltimateBowStack(item(entry.path()), holders));
|
||||
continue;
|
||||
|
||||
+64
-9
@@ -58,12 +58,14 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.pathfinder.PathType;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import software.bernie.geckolib.animatable.GeoEntity;
|
||||
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
|
||||
import software.bernie.geckolib.animation.Animation;
|
||||
import software.bernie.geckolib.animation.AnimatableManager;
|
||||
import software.bernie.geckolib.animation.AnimationController;
|
||||
import software.bernie.geckolib.animation.AnimationState;
|
||||
@@ -101,15 +103,17 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit
|
||||
SynchedEntityData.defineId(RoyalMountEntity.class, EntityDataSerializers.FLOAT);
|
||||
private static final EntityDataAccessor<Float> GROWTH_PROGRESS =
|
||||
SynchedEntityData.defineId(RoyalMountEntity.class, EntityDataSerializers.FLOAT);
|
||||
private static final EntityDataAccessor<Boolean> QUIRKING =
|
||||
SynchedEntityData.defineId(RoyalMountEntity.class, EntityDataSerializers.BOOLEAN);
|
||||
|
||||
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
|
||||
private static final RawAnimation QUIRK_ANIM = RawAnimation.begin().thenLoop("quirk");
|
||||
private static final RawAnimation WALK_ANIM = RawAnimation.begin().thenLoop("walk");
|
||||
private static final RawAnimation FLY_ANIM = RawAnimation.begin().thenLoop("fly");
|
||||
private static final RawAnimation BITE_ANIM = RawAnimation.begin().thenPlay("bite");
|
||||
private static final RawAnimation FLY_BITE_ANIM = RawAnimation.begin().thenPlay("fly_bite");
|
||||
private static final RawAnimation SHOOT_ANIM = RawAnimation.begin().thenPlay("shoot");
|
||||
private static final RawAnimation FLY_SHOOT_ANIM = RawAnimation.begin().thenPlay("fly_shoot");
|
||||
private static final RawAnimation BITE_ANIM = RawAnimation.begin().then("bite", Animation.LoopType.PLAY_ONCE);
|
||||
private static final RawAnimation FLY_BITE_ANIM = RawAnimation.begin().then("fly_bite", Animation.LoopType.PLAY_ONCE);
|
||||
private static final RawAnimation SHOOT_ANIM = RawAnimation.begin().then("shoot", Animation.LoopType.PLAY_ONCE);
|
||||
private static final RawAnimation FLY_SHOOT_ANIM = RawAnimation.begin().then("fly_shoot", Animation.LoopType.PLAY_ONCE);
|
||||
|
||||
private static final int ACTION_TICKS = 12;
|
||||
private static final int BITE_HIT_TICK = 6;
|
||||
@@ -271,6 +275,7 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit
|
||||
builder.define(BEAM_END_Y, 0.0F);
|
||||
builder.define(BEAM_END_Z, 0.0F);
|
||||
builder.define(GROWTH_PROGRESS, 0.0F);
|
||||
builder.define(QUIRKING, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -498,6 +503,7 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit
|
||||
}
|
||||
|
||||
if (this.actionTicks > 0) {
|
||||
this.entityData.set(QUIRKING, false);
|
||||
this.actionTicks--;
|
||||
if (!this.actionHit && this.actionTicks <= ACTION_TICKS - BITE_HIT_TICK
|
||||
&& (this.getAnimState() == ANIM_BITE || this.getAnimState() == ANIM_FLY_BITE)) {
|
||||
@@ -519,6 +525,7 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit
|
||||
if (this.getAnimState() == ANIM_IDLE && this.quirkTimer == 0 && this.random.nextInt(600) == 0) {
|
||||
this.quirkTimer = 80;
|
||||
}
|
||||
this.entityData.set(QUIRKING, this.quirkTimer > 0 && this.getAnimState() == ANIM_IDLE);
|
||||
}
|
||||
|
||||
private void tickRoyalAbilities() {
|
||||
@@ -783,6 +790,54 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit
|
||||
return this.isTame() && this.isOwnedBy(player) && this.getControllingPassenger() == player;
|
||||
}
|
||||
|
||||
public AABB assistedMountBox() {
|
||||
float scale = this.getGrowthScale();
|
||||
double half = Math.max(this.getBbWidth() * 0.5D, 2.2D * scale);
|
||||
double height = Math.max(this.getBbHeight(), 1.4D * scale);
|
||||
return new AABB(this.getX() - half, this.getY(), this.getZ() - half,
|
||||
this.getX() + half, this.getY() + height, this.getZ() + half);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static RoyalMountEntity findAssistedMountTarget(Player player, double extraReach) {
|
||||
if (player.isPassenger() || player.isSpectator() || !player.getMainHandItem().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Vec3 eye = player.getEyePosition();
|
||||
Vec3 end = eye.add(player.getViewVector(1.0F).scale(player.entityInteractionRange() + extraReach));
|
||||
RoyalMountEntity best = null;
|
||||
double bestDistance = Double.MAX_VALUE;
|
||||
for (RoyalMountEntity mount : player.level().getEntitiesOfClass(RoyalMountEntity.class, player.getBoundingBox().inflate(80.0D),
|
||||
mount -> mount.isAlive() && mount.isTame() && mount.isOwnedBy(player) && !mount.isVehicle())) {
|
||||
AABB box = mount.assistedMountBox();
|
||||
double distance;
|
||||
if (box.contains(eye)) {
|
||||
distance = 0.0D;
|
||||
} else {
|
||||
var hit = box.clip(eye, end);
|
||||
if (hit.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
distance = hit.get().distanceToSqr(eye);
|
||||
}
|
||||
if (distance < bestDistance) {
|
||||
bestDistance = distance;
|
||||
best = mount;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
public static boolean tryAssistedMount(ServerPlayer player) {
|
||||
RoyalMountEntity mount = findAssistedMountTarget(player, 2.0D);
|
||||
if (mount == null) {
|
||||
return false;
|
||||
}
|
||||
mount.setOrderedToSit(false);
|
||||
mount.setInSittingPose(false);
|
||||
return player.startRiding(mount);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public LivingEntity getControllingPassenger() {
|
||||
@@ -799,10 +854,10 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit
|
||||
if (!this.hasPassenger(passenger)) {
|
||||
return;
|
||||
}
|
||||
// Seat near the back of the torso, outside the scaled body instead of inside its growing hitbox.
|
||||
double yOffset = Math.max(this.getBbHeight() * 0.82D, this.getBbHeight() - passenger.getBbHeight() * 0.65D);
|
||||
double backDistance = this.getBbWidth() * 0.5D + passenger.getBbWidth() * 0.5D + 0.15D;
|
||||
Vec3 back = this.getLookAngle().scale(-backDistance);
|
||||
float scale = this.getGrowthScale();
|
||||
double yOffset = 1.3D * scale;
|
||||
double backDistance = 0.35D * scale;
|
||||
Vec3 back = Vec3.directionFromRotation(0.0F, this.getYRot()).scale(-backDistance);
|
||||
moveFunction.accept(passenger, this.getX() + back.x, this.getY() + yOffset, this.getZ() + back.z);
|
||||
}
|
||||
|
||||
@@ -884,7 +939,7 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit
|
||||
return switch (this.getAnimState()) {
|
||||
case ANIM_WALK -> state.setAndContinue(WALK_ANIM);
|
||||
case ANIM_FLY, ANIM_FLY_BITE, ANIM_FLY_SHOOT -> state.setAndContinue(FLY_ANIM);
|
||||
default -> state.setAndContinue(this.quirkTimer > 0 ? QUIRK_ANIM : IDLE_ANIM);
|
||||
default -> state.setAndContinue(this.entityData.get(QUIRKING) ? QUIRK_ANIM : IDLE_ANIM);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ public final class ComputerScientistTradeManager extends SimpleJsonResourceReloa
|
||||
private static final String DIRECTORY = "computer_scientist_trades";
|
||||
private static final List<ResourceLocation> GENERAL_DISKS = List.of(
|
||||
id("introduction"), id("high_fructose_corn_syrup"),
|
||||
id("elythia"), id("flying_squirrel"), id("cavaryn"), id("thoraxis"),
|
||||
id("elythia"), id("flying_squirrel"), id("rainbow_ant"), id("cavaryn"), id("thoraxis"),
|
||||
id("temporal_fields"), id("bloodglass"), id("vortex"));
|
||||
private static volatile List<TradeEntry> loadedTrades = List.of();
|
||||
|
||||
|
||||
+1
-8
@@ -3,7 +3,6 @@ package com.craisinlord.antarchy.content.item;
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil;
|
||||
import com.craisinlord.antarchy.content.network.ImpactShakePayload;
|
||||
import com.craisinlord.antarchy.content.network.ImpactShakeSync;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -280,13 +279,7 @@ public final class AttitudeAdjusterSlamManager {
|
||||
}
|
||||
|
||||
private static void shake(ServerLevel level, Vec3 pos, float intensity, int durationTicks) {
|
||||
ImpactShakePayload payload = new ImpactShakePayload(pos.x, pos.y, pos.z, intensity, durationTicks, IMPACT_SHAKE_RADIUS);
|
||||
double radiusSqr = IMPACT_SHAKE_RADIUS * IMPACT_SHAKE_RADIUS;
|
||||
for (ServerPlayer player : level.players()) {
|
||||
if (player.distanceToSqr(pos.x, pos.y, pos.z) <= radiusSqr) {
|
||||
ImpactShakeSync.send(player, payload);
|
||||
}
|
||||
}
|
||||
ImpactShakeSync.sendNearby(level, pos, intensity, durationTicks, IMPACT_SHAKE_RADIUS);
|
||||
}
|
||||
|
||||
private static Vec3 horizontalAway(Vec3 from, Vec3 to, Vec3 fallback) {
|
||||
|
||||
+38
-14
@@ -33,7 +33,9 @@ import net.minecraft.world.inventory.ClickAction;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import com.craisinlord.antarchy.Antarchy;
|
||||
import com.craisinlord.antarchy.content.menu.GiantFryingPanMenu;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import software.bernie.geckolib.animatable.GeoItem;
|
||||
import software.bernie.geckolib.animatable.client.GeoRenderProvider;
|
||||
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
|
||||
@@ -61,6 +63,8 @@ public class GiantFryingPanItem extends SwordItem implements GeoItem {
|
||||
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));
|
||||
tooltipComponents.add(Component.translatable("tooltip.antarchy.giant_frying_pan.dig").withStyle(ChatFormatting.GOLD));
|
||||
tooltipComponents.add(Component.translatable("tooltip.antarchy.giant_frying_pan.launch").withStyle(ChatFormatting.GOLD));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,29 +85,49 @@ public class GiantFryingPanItem extends SwordItem implements GeoItem {
|
||||
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;
|
||||
}
|
||||
GiantFryingPanToolHelper.launch(target, attacker);
|
||||
Level level = attacker.level();
|
||||
level.playSound(null, target.blockPosition(), SoundEvents.ANVIL_LAND, SoundSource.PLAYERS, 0.8F, 1.25F);
|
||||
return hurt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDestroySpeed(ItemStack stack, BlockState state) {
|
||||
return GiantFryingPanToolHelper.getDestroySpeed(this.tier, stack, state, super.getDestroySpeed(stack, state));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCorrectToolForDrops(ItemStack stack, BlockState state) {
|
||||
return GiantFryingPanToolHelper.isShovelBlock(state) || super.isCorrectToolForDrops(stack, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAttackBlock(BlockState state, Level level, BlockPos pos, Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mineBlock(ItemStack stack, Level level, BlockState state, BlockPos pos, LivingEntity miningEntity) {
|
||||
if (!level.isClientSide && state.getDestroySpeed(level, pos) != 0.0F) {
|
||||
stack.hurtAndBreak(1, miningEntity, EquipmentSlot.MAINHAND);
|
||||
}
|
||||
GiantFryingPanToolHelper.mineArea(stack, level, state, pos, miningEntity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@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 (!level.isClientSide) GiantFryingPanToolHelper.ensureEnchantments(stack, level.registryAccess());
|
||||
if (entity instanceof Player player) GiantFryingPanStorage.tick(player, stack, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCraftedBy(ItemStack stack, Level level, Player player) {
|
||||
super.onCraftedBy(stack, level, player);
|
||||
GiantFryingPanToolHelper.ensureEnchantments(stack, level.registryAccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
|
||||
ItemStack pan = player.getItemInHand(hand);
|
||||
@@ -169,7 +193,7 @@ public class GiantFryingPanItem extends SwordItem implements GeoItem {
|
||||
ItemStack food = slot.getItem();
|
||||
if (!GiantFryingPanStorage.isCampfireInput(player, food) || !slot.mayPickup(player)) return false;
|
||||
GiantFryingPanStorage storage = new GiantFryingPanStorage(pan, player);
|
||||
boolean inserted = storage.hasSpace() && storage.insertOne(slot.safeTake(1, 1, player));
|
||||
boolean inserted = storage.hasSpace(food) && storage.insertOne(slot.safeTake(1, 1, player));
|
||||
Antarchy.LOGGER.info("[FryingPan] cursor pan onto slot client={} food={} inserted={}", player.level().isClientSide, food.getItem(), inserted);
|
||||
if (inserted) player.playSound(SoundEvents.CAMPFIRE_CRACKLE, 0.8F, 1.0F);
|
||||
return true;
|
||||
|
||||
+25
-6
@@ -1,5 +1,6 @@
|
||||
package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
@@ -19,7 +20,7 @@ import net.minecraft.world.level.Level;
|
||||
|
||||
public final class GiantFryingPanStorage implements Container {
|
||||
public static final int SLOT_COUNT = 9;
|
||||
public static final int COOK_TIME = 600;
|
||||
public static final int MAX_STACK = 64;
|
||||
private static final String SLOTS = "antarchy.giant_frying_pan_slots";
|
||||
private static final String SLOT = "Slot";
|
||||
private static final String ITEM = "Item";
|
||||
@@ -84,7 +85,7 @@ public final class GiantFryingPanStorage implements Container {
|
||||
boolean changed = false;
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) {
|
||||
ItemStack input = storage.items.get(slot);
|
||||
if (input.isEmpty() || now - storage.startTimes[slot] < COOK_TIME) continue;
|
||||
if (input.isEmpty() || now - storage.startTimes[slot] < cookTime()) continue;
|
||||
Optional<RecipeHolder<CampfireCookingRecipe>> recipe = level.getRecipeManager().getRecipeFor(
|
||||
RecipeType.CAMPFIRE_COOKING, new SingleRecipeInput(input), level);
|
||||
if (recipe.isEmpty()) continue;
|
||||
@@ -111,6 +112,15 @@ public final class GiantFryingPanStorage implements Container {
|
||||
public boolean insertOne(ItemStack food) {
|
||||
if (!isCampfireInput(this.player, food)) return false;
|
||||
this.reloadIfChanged();
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) {
|
||||
ItemStack existing = this.items.get(slot);
|
||||
if (canMergeInto(existing, food)) {
|
||||
existing.grow(1);
|
||||
food.shrink(1);
|
||||
this.setChanged();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (int slot = 0; slot < SLOT_COUNT; slot++) {
|
||||
if (this.items.get(slot).isEmpty()) {
|
||||
this.setItem(slot, food.split(1));
|
||||
@@ -120,19 +130,28 @@ public final class GiantFryingPanStorage implements Container {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasSpace() {
|
||||
public boolean hasSpace(ItemStack food) {
|
||||
this.reloadIfChanged();
|
||||
for (ItemStack stack : this.items) {
|
||||
if (stack.isEmpty()) return true;
|
||||
if (stack.isEmpty() || canMergeInto(stack, food)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean canMergeInto(ItemStack existing, ItemStack food) {
|
||||
return !existing.isEmpty() && ItemStack.isSameItemSameComponents(existing, food)
|
||||
&& existing.getCount() < Math.min(MAX_STACK, existing.getMaxStackSize());
|
||||
}
|
||||
|
||||
public static int cookTime() {
|
||||
return Math.max(1, AntarchySettings.giantFryingPanCookTimeTicks());
|
||||
}
|
||||
|
||||
public float cookProgress(int slot) {
|
||||
this.reloadIfChanged();
|
||||
if (this.items.get(slot).isEmpty()) return 0.0F;
|
||||
long elapsed = this.player.level().getGameTime() - this.startTimes[slot];
|
||||
return Math.max(0.0F, Math.min(1.0F, elapsed / (float) COOK_TIME));
|
||||
return Math.max(0.0F, Math.min(1.0F, elapsed / (float) cookTime()));
|
||||
}
|
||||
|
||||
private void reloadIfChanged() {
|
||||
@@ -221,7 +240,7 @@ public final class GiantFryingPanStorage implements Container {
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return 1;
|
||||
return MAX_STACK;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import com.craisinlord.antarchy.content.item.ultimate.UltimateToolHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Tier;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.item.enchantment.ItemEnchantments;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public final class GiantFryingPanToolHelper {
|
||||
public static final int MINING_RADIUS = 2;
|
||||
public static final int FIRE_ASPECT_LEVEL = 2;
|
||||
private static final double HORIZONTAL_LAUNCH = 1.8D;
|
||||
private static final double MAX_HORIZONTAL_SPEED = 2.6D;
|
||||
private static final double VERTICAL_LAUNCH = 0.75D;
|
||||
|
||||
private GiantFryingPanToolHelper() {
|
||||
}
|
||||
|
||||
public static float getDestroySpeed(Tier tier, ItemStack stack, BlockState state, float defaultSpeed) {
|
||||
return UltimateToolHelper.getDestroySpeed(UltimateToolHelper.ToolKind.SHOVEL, tier, stack, state, defaultSpeed);
|
||||
}
|
||||
|
||||
public static boolean isShovelBlock(BlockState state) {
|
||||
return UltimateToolHelper.matchesToolKind(UltimateToolHelper.ToolKind.SHOVEL, state);
|
||||
}
|
||||
|
||||
public static void mineArea(ItemStack stack, Level level, BlockState state, BlockPos pos, LivingEntity miner) {
|
||||
if (miner instanceof ServerPlayer player) {
|
||||
UltimateToolHelper.mineArea(UltimateToolHelper.ToolKind.SHOVEL, stack, level, state, pos, player, MINING_RADIUS);
|
||||
}
|
||||
}
|
||||
|
||||
public static void launch(LivingEntity target, LivingEntity attacker) {
|
||||
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);
|
||||
}
|
||||
Vec3 motion = target.getDeltaMovement();
|
||||
double x = motion.x;
|
||||
double z = motion.z;
|
||||
if (direction.lengthSqr() >= 1.0E-4D) {
|
||||
direction = direction.normalize();
|
||||
x = Math.max(-MAX_HORIZONTAL_SPEED, Math.min(MAX_HORIZONTAL_SPEED, x + direction.x * HORIZONTAL_LAUNCH));
|
||||
z = Math.max(-MAX_HORIZONTAL_SPEED, Math.min(MAX_HORIZONTAL_SPEED, z + direction.z * HORIZONTAL_LAUNCH));
|
||||
}
|
||||
target.setDeltaMovement(x, Math.max(motion.y, 0.0D) + VERTICAL_LAUNCH, z);
|
||||
target.hasImpulse = true;
|
||||
target.hurtMarked = true;
|
||||
}
|
||||
|
||||
public static ItemStack createStack(Item item, HolderLookup.Provider registries) {
|
||||
ItemStack stack = new ItemStack(item);
|
||||
ensureEnchantments(stack, registries);
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static void ensureEnchantments(ItemStack stack, HolderLookup.Provider registries) {
|
||||
var fireAspect = registries.lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(Enchantments.FIRE_ASPECT);
|
||||
if (stack.getEnchantments().getLevel(fireAspect) >= FIRE_ASPECT_LEVEL) {
|
||||
return;
|
||||
}
|
||||
ItemEnchantments.Mutable enchantments = new ItemEnchantments.Mutable(stack.getEnchantments());
|
||||
enchantments.set(fireAspect, FIRE_ASPECT_LEVEL);
|
||||
EnchantmentHelper.setEnchantments(stack, enchantments.toImmutable());
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -1,5 +1,6 @@
|
||||
package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import com.craisinlord.antarchy.Antarchy;
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.craisinlord.antarchy.content.client.NightmareSwordTooltipHelper;
|
||||
import java.util.List;
|
||||
@@ -49,10 +50,18 @@ public class NightmareSwordItem extends SwordItem {
|
||||
return stack.getCount() == 1;
|
||||
}
|
||||
|
||||
public static Component damageLine(float damage) {
|
||||
float rounded = Math.round(damage * 10.0F) / 10.0F;
|
||||
String text = rounded == (int) rounded ? String.valueOf((int) rounded) : String.valueOf(rounded);
|
||||
return Component.translatable("tooltip.antarchy.nightmare_sword_damage", text).withStyle(ChatFormatting.RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(ItemStack stack, Item.TooltipContext context, List<Component> tooltipComponents, TooltipFlag tooltipFlag) {
|
||||
tooltipComponents.add(Component.translatable("tooltip.antarchy.nightmare_sword").withStyle(ChatFormatting.DARK_RED));
|
||||
tooltipComponents.add(NightmareSwordTooltipHelper.damageLine());
|
||||
tooltipComponents.add(Antarchy.physicalClient
|
||||
? NightmareSwordTooltipHelper.damageLine()
|
||||
: damageLine((float) AntarchySettings.nightmareSwordBaseDamage()));
|
||||
super.appendHoverText(stack, context, tooltipComponents, tooltipFlag);
|
||||
}
|
||||
}
|
||||
+5
@@ -4,6 +4,7 @@ import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.craisinlord.antarchy.content.effect.CommandedEntityAccess;
|
||||
import com.craisinlord.antarchy.content.AntarchySoundEvents;
|
||||
import com.craisinlord.antarchy.content.entity.royal.RoyalIceSpikeEntity;
|
||||
import com.craisinlord.antarchy.content.network.ImpactShakeSync;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -35,6 +36,9 @@ public final class RoyalGuardianSwordAbilities {
|
||||
private static final ThreadLocal<Integer> SECONDARY_DAMAGE_DEPTH = ThreadLocal.withInitial(() -> 0);
|
||||
private static final ThreadLocal<MeleeAttackContext> MELEE_ATTACK = new ThreadLocal<>();
|
||||
private static final DustParticleOptions FIRE_GOLD = new DustParticleOptions(new Vector3f(1.0F, 0.55F, 0.08F), 1.6F);
|
||||
private static final float FIRE_SHAKE_INTENSITY = 0.3F;
|
||||
private static final int FIRE_SHAKE_DURATION = 7;
|
||||
private static final float FIRE_SHAKE_RADIUS = 14.0F;
|
||||
private static final DustParticleOptions STORM_GOLD = new DustParticleOptions(new Vector3f(1.0F, 0.86F, 0.25F), 1.25F);
|
||||
|
||||
private RoyalGuardianSwordAbilities() {
|
||||
@@ -107,6 +111,7 @@ public final class RoyalGuardianSwordAbilities {
|
||||
level.sendParticles(FIRE_GOLD, center.x, center.y, center.z, 28, 1.1D, 0.8D, 1.1D, 0.04D);
|
||||
level.sendParticles(ParticleTypes.EXPLOSION, center.x, center.y, center.z, 3, 0.8D, 0.6D, 0.8D, 0.0D);
|
||||
level.playSound(null, BlockPos.containing(center), SoundEvents.GENERIC_EXPLODE.value(), SoundSource.PLAYERS, 1.0F, 1.05F);
|
||||
ImpactShakeSync.sendNearby(level, center, FIRE_SHAKE_INTENSITY, FIRE_SHAKE_DURATION, FIRE_SHAKE_RADIUS);
|
||||
}
|
||||
|
||||
private static void placeBoundedFire(ServerLevel level, Vec3 center, int cap) {
|
||||
|
||||
+29
-17
@@ -1,6 +1,8 @@
|
||||
package com.craisinlord.antarchy.content.item.ultimate;
|
||||
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanItem;
|
||||
import com.craisinlord.antarchy.content.item.GiantFryingPanToolHelper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
@@ -90,14 +92,18 @@ public final class UltimateToolHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canBreak(toolKind, player, stack, level, origin, originState)) {
|
||||
mineArea(toolKind, stack, level, originState, origin, player, 1);
|
||||
}
|
||||
|
||||
public static void mineArea(ToolKind toolKind, ItemStack stack, Level level, BlockState originState, BlockPos origin, ServerPlayer player, int radius) {
|
||||
if (level.isClientSide || BREAKING_EXTRA_BLOCKS.get() || !canBreak(toolKind, player, stack, level, origin, originState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Direction face = resolveMiningFace(player, origin);
|
||||
BREAKING_EXTRA_BLOCKS.set(true);
|
||||
try {
|
||||
for (BlockPos targetPos : getMiningPlane(origin, face)) {
|
||||
for (BlockPos targetPos : getPlane(origin, face, radius)) {
|
||||
if (!canBreak(toolKind, player, stack, level, targetPos, level.getBlockState(targetPos))) {
|
||||
continue;
|
||||
}
|
||||
@@ -117,11 +123,16 @@ public final class UltimateToolHelper {
|
||||
|
||||
|
||||
public static void broadcastAreaMiningProgress(ServerPlayer player, ServerLevel level, BlockPos origin, int stage) {
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (stack.getItem() instanceof GiantFryingPanItem) {
|
||||
broadcastPlaneProgress(ToolKind.SHOVEL, player, level, origin, stage, GiantFryingPanToolHelper.MINING_RADIUS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AntarchySettings.ultimateToolsThreeByThreeEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
if (stack.isEmpty() || !isThreeByThreeEnabled(stack)) {
|
||||
return;
|
||||
}
|
||||
@@ -131,13 +142,17 @@ public final class UltimateToolHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
broadcastPlaneProgress(kind, player, level, origin, stage, 1);
|
||||
}
|
||||
|
||||
private static void broadcastPlaneProgress(ToolKind kind, ServerPlayer player, ServerLevel level, BlockPos origin, int stage, int radius) {
|
||||
BlockState originState = level.getBlockState(origin);
|
||||
if (!matchesToolKind(kind, originState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Direction face = resolveMiningFace(player, origin);
|
||||
for (BlockPos targetPos : getPlane(origin, face)) {
|
||||
for (BlockPos targetPos : getPlane(origin, face, radius)) {
|
||||
BlockState state = level.getBlockState(targetPos);
|
||||
if (state.isAir() || state.hasBlockEntity() || state.getDestroySpeed(level, targetPos) < 0.0F) {
|
||||
continue;
|
||||
@@ -174,7 +189,7 @@ public final class UltimateToolHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
for (BlockPos targetPos : getPlane(context.getClickedPos(), context.getClickedFace())) {
|
||||
for (BlockPos targetPos : getPlane(context.getClickedPos(), context.getClickedFace(), 1)) {
|
||||
if (!canModify(player, context.getLevel(), targetPos, context.getClickedFace(), context.getItemInHand())) {
|
||||
continue;
|
||||
}
|
||||
@@ -285,16 +300,13 @@ public final class UltimateToolHelper {
|
||||
return best;
|
||||
}
|
||||
|
||||
private static List<BlockPos> getMiningPlane(BlockPos center, Direction face) {
|
||||
return getPlane(center, face);
|
||||
}
|
||||
|
||||
private static List<BlockPos> getPlane(BlockPos center, Direction face) {
|
||||
List<BlockPos> positions = new ArrayList<>(8);
|
||||
private static List<BlockPos> getPlane(BlockPos center, Direction face, int radius) {
|
||||
int size = radius * 2 + 1;
|
||||
List<BlockPos> positions = new ArrayList<>(size * size - 1);
|
||||
switch (face.getAxis()) {
|
||||
case Y -> {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
for (int z = -radius; z <= radius; z++) {
|
||||
if (x == 0 && z == 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -304,8 +316,8 @@ public final class UltimateToolHelper {
|
||||
}
|
||||
}
|
||||
case X -> {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
for (int y = -radius; y <= radius; y++) {
|
||||
for (int z = -radius; z <= radius; z++) {
|
||||
if (y == 0 && z == 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -315,8 +327,8 @@ public final class UltimateToolHelper {
|
||||
}
|
||||
}
|
||||
case Z -> {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
for (int y = -radius; y <= radius; y++) {
|
||||
if (x == 0 && y == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
-5
@@ -34,11 +34,6 @@ public final class GiantFryingPanMenu extends AbstractContainerMenu {
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return GiantFryingPanStorage.isCampfireInput(player, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (int row = 0; row < 3; row++) {
|
||||
|
||||
+12
@@ -1,7 +1,9 @@
|
||||
package com.craisinlord.antarchy.content.network;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public final class ImpactShakeSync {
|
||||
private static final BiConsumer<ServerPlayer, ImpactShakePayload> NOOP = (player, payload) -> {
|
||||
@@ -18,4 +20,14 @@ public final class ImpactShakeSync {
|
||||
public static void send(ServerPlayer player, ImpactShakePayload payload) {
|
||||
sink.accept(player, payload);
|
||||
}
|
||||
|
||||
public static void sendNearby(ServerLevel level, Vec3 pos, float intensity, int durationTicks, float radius) {
|
||||
ImpactShakePayload payload = new ImpactShakePayload(pos.x, pos.y, pos.z, intensity, durationTicks, radius);
|
||||
double radiusSqr = radius * radius;
|
||||
for (ServerPlayer player : level.players()) {
|
||||
if (player.distanceToSqr(pos.x, pos.y, pos.z) <= radiusSqr) {
|
||||
send(player, payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -11,6 +11,7 @@ public record RoyalMountActionPayload(int action) implements CustomPacketPayload
|
||||
public static final int FLIGHT_TOGGLE = 0;
|
||||
public static final int BITE = 1;
|
||||
public static final int SPIT = 2;
|
||||
public static final int MOUNT = 3;
|
||||
|
||||
public static final Type<RoyalMountActionPayload> TYPE =
|
||||
new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "royal_mount_action"));
|
||||
|
||||
-43
@@ -1,15 +1,11 @@
|
||||
package com.craisinlord.antarchy.content.portal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
@@ -17,9 +13,7 @@ import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class PermanentPortalManager {
|
||||
private static final int TELEPORT_DELAY_TICKS = 20;
|
||||
private static final int ACTIVATION_SEARCH_RADIUS = 2;
|
||||
private static final Map<UUID, PortalWarmup> WARMUPS = new HashMap<>();
|
||||
|
||||
private PermanentPortalManager() {
|
||||
}
|
||||
@@ -50,37 +44,6 @@ public final class PermanentPortalManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void handleEntityInsidePortal(Entity entity, PermanentPortalType type) {
|
||||
if (!(entity.level() instanceof ServerLevel serverLevel) || !type.isEnabled() || entity.isPassenger() || entity.isVehicle()) {
|
||||
return;
|
||||
}
|
||||
if (entity.isOnPortalCooldown()) {
|
||||
WARMUPS.remove(entity.getUUID());
|
||||
return;
|
||||
}
|
||||
|
||||
long gameTime = serverLevel.getGameTime();
|
||||
PortalWarmup warmup = WARMUPS.computeIfAbsent(entity.getUUID(), ignored -> new PortalWarmup());
|
||||
if (warmup.type != type || warmup.lastSeenTick < gameTime - 1) {
|
||||
warmup.ticks = 0;
|
||||
}
|
||||
warmup.type = type;
|
||||
if (warmup.lastSeenTick != gameTime) {
|
||||
warmup.ticks++;
|
||||
warmup.lastSeenTick = gameTime;
|
||||
}
|
||||
|
||||
if (warmup.ticks < TELEPORT_DELAY_TICKS) {
|
||||
return;
|
||||
}
|
||||
|
||||
WARMUPS.remove(entity.getUUID());
|
||||
PermanentPortalTeleporter.teleport(entity, type);
|
||||
if (entity.level() instanceof ServerLevel currentLevel) {
|
||||
currentLevel.playSound(null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.PORTAL_TRAVEL, SoundSource.PLAYERS, 0.8F, 1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPortalStillValid(ServerLevel level, BlockPos pos, PermanentPortalType type, Direction.Axis axis) {
|
||||
PermanentPortalShape shape = PermanentPortalShape.findActive(level, pos, type, axis);
|
||||
return shape != null && shape.contains(pos);
|
||||
@@ -137,10 +100,4 @@ public final class PermanentPortalManager {
|
||||
level.playSound(null, center.x, center.y, center.z, sound, SoundSource.BLOCKS, volume, pitch);
|
||||
spawnActivationParticles(level, type, center);
|
||||
}
|
||||
|
||||
private static final class PortalWarmup {
|
||||
private PermanentPortalType type;
|
||||
private long lastSeenTick;
|
||||
private int ticks;
|
||||
}
|
||||
}
|
||||
-21
@@ -19,7 +19,6 @@ public final class PermanentPortalShape {
|
||||
public static final int MIN_WIDTH = 2;
|
||||
public static final int MIN_HEIGHT = 3;
|
||||
public static final int MAX_SIZE = 21;
|
||||
public static final int ACTIVE_SEARCH_RADIUS = 128;
|
||||
|
||||
private final TagKey<Block> frameTag;
|
||||
private final Block portalBlock;
|
||||
@@ -78,26 +77,6 @@ public final class PermanentPortalShape {
|
||||
return find(level, interiorPos, type.frameTag(), portalBlock, axis, state -> state.is(portalBlock));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PermanentPortalShape findActiveNear(BlockGetter level, BlockPos center, PermanentPortalType type) {
|
||||
for (int x = center.getX() - ACTIVE_SEARCH_RADIUS; x <= center.getX() + ACTIVE_SEARCH_RADIUS; x++) {
|
||||
for (int y = center.getY() - ACTIVE_SEARCH_RADIUS; y <= center.getY() + ACTIVE_SEARCH_RADIUS; y++) {
|
||||
for (int z = center.getZ() - ACTIVE_SEARCH_RADIUS; z <= center.getZ() + ACTIVE_SEARCH_RADIUS; z++) {
|
||||
BlockPos candidate = new BlockPos(x, y, z);
|
||||
PermanentPortalShape xShape = findActive(level, candidate, type, Direction.Axis.X);
|
||||
if (xShape != null) {
|
||||
return xShape;
|
||||
}
|
||||
PermanentPortalShape zShape = findActive(level, candidate, type, Direction.Axis.Z);
|
||||
if (zShape != null) {
|
||||
return zShape;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PermanentPortalShape find(
|
||||
BlockGetter level,
|
||||
|
||||
+34
-64
@@ -1,7 +1,9 @@
|
||||
package com.craisinlord.antarchy.content.portal;
|
||||
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@@ -11,11 +13,14 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiManager;
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiRecord;
|
||||
import net.minecraft.world.entity.vehicle.DismountHelper;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.portal.DimensionTransition;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
@@ -29,18 +34,6 @@ public final class PermanentPortalTeleporter {
|
||||
private PermanentPortalTeleporter() {
|
||||
}
|
||||
|
||||
public static void teleport(Entity entity, PermanentPortalType type) {
|
||||
if (!(entity.level() instanceof ServerLevel sourceLevel) || !entity.isAlive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DimensionTransition transition = createTransition(sourceLevel, entity, entity.blockPosition(), type);
|
||||
Entity movedEntity = moveEntity(entity, transition);
|
||||
if (movedEntity != null) {
|
||||
movedEntity.setPortalCooldown();
|
||||
}
|
||||
}
|
||||
|
||||
public static DimensionTransition createTransition(ServerLevel sourceLevel, Entity entity, BlockPos portalPos, PermanentPortalType type) {
|
||||
ServerLevel destination = resolveDestination(sourceLevel, type);
|
||||
if (destination == null) {
|
||||
@@ -69,24 +62,14 @@ public final class PermanentPortalTeleporter {
|
||||
private static Vec3 findArrivalPosition(ServerLevel source, Entity entity, ServerLevel destination, BlockPos preferredPos, PermanentPortalType type) {
|
||||
double scale = DimensionType.getTeleportationScale(source.dimensionType(), destination.dimensionType());
|
||||
preferredPos = BlockPos.containing(preferredPos.getX() * scale, preferredPos.getY(), preferredPos.getZ() * scale);
|
||||
PermanentPortalShape active = PermanentPortalShape.findActiveNear(destination, preferredPos, type);
|
||||
if (active != null) {
|
||||
Vec3 safePortalPosition = tryFindSafePosition(entity, destination, BlockPos.containing(active.center()));
|
||||
if (safePortalPosition != null) {
|
||||
return safePortalPosition;
|
||||
}
|
||||
PermanentPortalShape existing = findExistingPortal(destination, preferredPos, type);
|
||||
if (existing != null) {
|
||||
Vec3 safePortalPosition = tryFindSafePosition(entity, destination, BlockPos.containing(existing.center()));
|
||||
return safePortalPosition != null ? safePortalPosition : existing.center();
|
||||
}
|
||||
|
||||
Vec3 safe = findSafeArrivalPosition(entity, destination, preferredPos, type);
|
||||
if (safe != null) {
|
||||
PermanentPortalShape nearbyActive = findActiveNearby(destination, BlockPos.containing(safe), type);
|
||||
if (nearbyActive != null) {
|
||||
Vec3 safePortalPosition = tryFindSafePosition(entity, destination, BlockPos.containing(nearbyActive.center()));
|
||||
if (safePortalPosition != null) {
|
||||
return safePortalPosition;
|
||||
}
|
||||
}
|
||||
|
||||
PermanentPortalShape created = createReturnPortal(destination, safe, type);
|
||||
if (created != null) {
|
||||
return created.center();
|
||||
@@ -98,32 +81,36 @@ public final class PermanentPortalTeleporter {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PermanentPortalShape findActiveNearby(ServerLevel level, BlockPos center, PermanentPortalType type) {
|
||||
for (int radius = 0; radius <= EXISTING_PORTAL_SEARCH_RADIUS; radius++) {
|
||||
for (int xOff = -radius; xOff <= radius; xOff++) {
|
||||
for (int yOff = -radius; yOff <= radius; yOff++) {
|
||||
for (int zOff = -radius; zOff <= radius; zOff++) {
|
||||
if (radius > 0 && Math.abs(xOff) != radius && Math.abs(yOff) != radius && Math.abs(zOff) != radius) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockPos candidate = center.offset(xOff, yOff, zOff);
|
||||
PermanentPortalShape xShape = PermanentPortalShape.findActive(level, candidate, type, Direction.Axis.X);
|
||||
if (xShape != null) {
|
||||
return xShape;
|
||||
}
|
||||
PermanentPortalShape zShape = PermanentPortalShape.findActive(level, candidate, type, Direction.Axis.Z);
|
||||
if (zShape != null) {
|
||||
return zShape;
|
||||
}
|
||||
}
|
||||
}
|
||||
private static PermanentPortalShape findExistingPortal(ServerLevel level, BlockPos center, PermanentPortalType type) {
|
||||
PoiManager poiManager = level.getPoiManager();
|
||||
poiManager.ensureLoadedAndValid(level, center, EXISTING_PORTAL_SEARCH_RADIUS);
|
||||
Block portalBlock = type.portalBlock();
|
||||
List<BlockPos> candidates = poiManager.getInSquare(
|
||||
holder -> holder.is(type.poiKey()), center, EXISTING_PORTAL_SEARCH_RADIUS, PoiManager.Occupancy.ANY)
|
||||
.map(PoiRecord::getPos)
|
||||
.filter(level.getWorldBorder()::isWithinBounds)
|
||||
.sorted(Comparator.<BlockPos>comparingDouble(pos -> horizontalDistanceSqr(pos, center))
|
||||
.thenComparingInt(pos -> Math.abs(pos.getY() - center.getY())))
|
||||
.toList();
|
||||
for (BlockPos pos : candidates) {
|
||||
BlockState state = level.getBlockState(pos);
|
||||
if (!state.is(portalBlock) || !state.hasProperty(BlockStateProperties.HORIZONTAL_AXIS)) {
|
||||
continue;
|
||||
}
|
||||
PermanentPortalShape shape = PermanentPortalShape.findActive(level, pos, type, state.getValue(BlockStateProperties.HORIZONTAL_AXIS));
|
||||
if (shape != null) {
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static double horizontalDistanceSqr(BlockPos a, BlockPos b) {
|
||||
double dx = a.getX() - b.getX();
|
||||
double dz = a.getZ() - b.getZ();
|
||||
return dx * dx + dz * dz;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Vec3 findSafeArrivalPosition(Entity entity, ServerLevel destination, BlockPos preferredPos, PermanentPortalType type) {
|
||||
int[] yRange = getDimensionYRange(destination, type);
|
||||
@@ -377,21 +364,4 @@ public final class PermanentPortalTeleporter {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Entity moveEntity(Entity entity, DimensionTransition transition) {
|
||||
ServerLevel destination = transition.newLevel();
|
||||
Vec3 destinationPos = transition.pos();
|
||||
if (entity instanceof ServerPlayer player) {
|
||||
player.teleportTo(destination, destinationPos.x, destinationPos.y, destinationPos.z, player.getYRot(), player.getXRot());
|
||||
return player;
|
||||
}
|
||||
|
||||
if (entity.level() == destination) {
|
||||
entity.teleportTo(destinationPos.x, destinationPos.y, destinationPos.z);
|
||||
return entity;
|
||||
}
|
||||
|
||||
return entity.changeDimension(transition);
|
||||
}
|
||||
}
|
||||
+24
@@ -5,13 +5,22 @@ import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.craisinlord.antarchy.content.entity.ant.BrownAntEntity;
|
||||
import com.craisinlord.antarchy.content.entity.ant.RedAntEntity;
|
||||
import com.craisinlord.antarchy.content.entity.ant.TermiteEntity;
|
||||
import com.craisinlord.antarchy.Antarchy;
|
||||
import com.craisinlord.antarchy.mixins.PoiTypesAccessor;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public enum PermanentPortalType {
|
||||
@@ -95,6 +104,21 @@ public enum PermanentPortalType {
|
||||
return this.primaryDimensionSupplier.get();
|
||||
}
|
||||
|
||||
public ResourceKey<PoiType> poiKey() {
|
||||
return ResourceKey.create(Registries.POINT_OF_INTEREST_TYPE, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, this.id + "_portal"));
|
||||
}
|
||||
|
||||
public static void registerPoiStates(Registry<PoiType> registry) {
|
||||
Map<BlockState, Holder<PoiType>> stateMap = PoiTypesAccessor.antarchy$getTypeByState();
|
||||
for (PermanentPortalType type : values()) {
|
||||
registry.getHolder(type.poiKey()).ifPresent(poi -> {
|
||||
for (BlockState state : type.portalBlock().getStateDefinition().getPossibleStates()) {
|
||||
stateMap.putIfAbsent(state, poi);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public TagKey<Block> frameTag() {
|
||||
return this.frameTag;
|
||||
}
|
||||
|
||||
+2
@@ -36,6 +36,8 @@ public final class VillagePoolAdditions {
|
||||
|
||||
public static void apply(MinecraftServer server) {
|
||||
registerComputerPoiStates(server);
|
||||
com.craisinlord.antarchy.content.portal.PermanentPortalType.registerPoiStates(
|
||||
server.registryAccess().registryOrThrow(Registries.POINT_OF_INTEREST_TYPE));
|
||||
Registry<StructureTemplatePool> pools = server.registryAccess().registryOrThrow(Registries.TEMPLATE_POOL);
|
||||
Registry<StructureProcessorList> processors = server.registryAccess().registryOrThrow(Registries.PROCESSOR_LIST);
|
||||
|
||||
|
||||
@@ -3062,7 +3062,6 @@
|
||||
}
|
||||
},
|
||||
"bite": {
|
||||
"loop": true,
|
||||
"animation_length": 0.5,
|
||||
"bones": {
|
||||
"torso": {
|
||||
@@ -4180,7 +4179,6 @@
|
||||
}
|
||||
},
|
||||
"fly_bite": {
|
||||
"loop": true,
|
||||
"animation_length": 0.7917,
|
||||
"bones": {
|
||||
"neck": {
|
||||
@@ -4922,7 +4920,6 @@
|
||||
}
|
||||
},
|
||||
"fly_shoot": {
|
||||
"loop": true,
|
||||
"animation_length": 0.7917,
|
||||
"bones": {
|
||||
"neck": {
|
||||
|
||||
@@ -3344,7 +3344,6 @@
|
||||
}
|
||||
},
|
||||
"bite": {
|
||||
"loop": true,
|
||||
"animation_length": 0.5,
|
||||
"bones": {
|
||||
"torso": {
|
||||
@@ -4538,7 +4537,6 @@
|
||||
}
|
||||
},
|
||||
"fly_bite": {
|
||||
"loop": true,
|
||||
"animation_length": 0.7917,
|
||||
"bones": {
|
||||
"neck": {
|
||||
@@ -5280,7 +5278,6 @@
|
||||
}
|
||||
},
|
||||
"fly_shoot": {
|
||||
"loop": true,
|
||||
"animation_length": 0.7917,
|
||||
"bones": {
|
||||
"neck": {
|
||||
|
||||
@@ -325,6 +325,8 @@
|
||||
"tooltip.antarchy.giant_frying_pan.insert": "Right-click with food in your other hand, or right-click food onto it in your inventory, to add it.",
|
||||
"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.",
|
||||
"tooltip.antarchy.giant_frying_pan.dig": "Digs shovel blocks in a 5x5 area.",
|
||||
"tooltip.antarchy.giant_frying_pan.launch": "Hits launch enemies into the air.",
|
||||
"item.antarchy.bluestone": "Bluestone Dust",
|
||||
"item.antarchy.wasp_nest": "Wasp Nest",
|
||||
"item.antarchy.stink_bug": "Stink Bug",
|
||||
@@ -1516,9 +1518,15 @@
|
||||
,"guide.antarchy.entry.introduction.subtitle": "A machine for remembering what should have stayed forgotten."
|
||||
,"guide.antarchy.entry.introduction.description": "Insert recovered floppy disks to expand this archive."
|
||||
,"guide.antarchy.entry.toreterror.title": "Toreterror"
|
||||
,"guide.antarchy.entry.toreterror_arena.subtitle": "Elythia Ocean boss"
|
||||
,"guide.antarchy.entry.toreterror_arena.description": "This archive can trace the nearest Toreterror Arena for you, always somewhere in an Elythia Ocean."
|
||||
,"guide.antarchy.entry.toreterror_arena.description2": "Toreterror is an ancient turtle that fights with a water cannon at range and a long spinning charge up close, ricocheting off obstacles until it connects."
|
||||
,"guide.antarchy.entry.toreterror_arena.subtitle": "Elythia Ocean boss record"
|
||||
,"guide.antarchy.entry.toreterror_arena.description": "A powerful creature of the Testudines taxonomic order. It dwells in a coliseum somewhere in an Elythia Ocean; this archive can trace the nearest one for you, and its coordinates are listed below."
|
||||
,"guide.antarchy.entry.toreterror_arena.description2": "Extremely territorial. A cannon mounted in its shell fires water at extremely high pressure, which makes it considerably dangerous to approach."
|
||||
,"guide.antarchy.disk.hercules_beetle.title": "HERCULES BEETLE FIELD NOTES"
|
||||
,"guide.antarchy.entry.hercules_beetle.title": "Hercules Beetle"
|
||||
,"guide.antarchy.entry.hercules_beetle.subtitle": "Cavaryn megafauna record"
|
||||
,"guide.antarchy.entry.hercules_beetle.description": "An enormous insect dwelling in Cavaryn. It is capable of a very powerful charge that can, and will, displace terrain."
|
||||
,"guide.antarchy.entry.hercules_beetle.description2": "Aggressive on sight and omnivorous."
|
||||
,"guide.antarchy.entry.hercules_beetle.description3": "Once injured in combat, the beast can be pacified with Broodfruit. When pacified, it bonds with the one who fed it, almost as if it respects them after the battle."
|
||||
,"guide.antarchy.entry.elythia.title": "Elythia"
|
||||
,"guide.antarchy.entry.elythia.subtitle": "Dimension and portal access record"
|
||||
,"guide.antarchy.entry.elythia.description": "Right-click a Brown Ant to teleport there directly, or sacrifice one inside a Mossy Ouranwood frame to light a permanent, reusable portal."
|
||||
@@ -1577,8 +1585,17 @@
|
||||
,"guide.antarchy.entry.high_fructose_corn_syrup.description2": "Drunk on its own, it causes four seconds of Nausea. A doctor would not recommend it."
|
||||
,"guide.antarchy.entry.high_fructose_corn_syrup.description3": "Used on any food in a crafting grid, it Americanizes it: extra nutrition, extra saturation, and a burst of Regeneration."
|
||||
,"guide.antarchy.entry.rainbow_ant.title": "Rainbow Ant"
|
||||
,"guide.antarchy.entry.rainbow_ant.subtitle": "Entity record"
|
||||
,"guide.antarchy.entry.rainbow_ant.description": "Feed a Rainbow Ant Rainbow Sugar to assign it a destination, then interact with it again to travel there. The destination is stored on that ant, so keep it alive."
|
||||
,"guide.antarchy.entry.rainbow_ant.subtitle": "Dimensional gateway record"
|
||||
,"guide.antarchy.entry.rainbow_ant.description": "A Rainbow Ant. It's your average dimensional ant... or so I thought at first. The Rainbow Ant doesn't lead to any dimension unless it is fed Rainbow Sugar."
|
||||
,"guide.antarchy.entry.rainbow_ant.description2": "I visited the dimension of the Rainbow Ant and returned, intending to note what I saw. When I went back to the ant's dimension later, I found it was a different dimension."
|
||||
,"guide.antarchy.entry.rainbow_ant.description3": "My previous notes on the Rainbow Ant have unfortunately been discarded, as I now know the dimension is different every time. For all I know, there could be millions of dimensions this fascinating creature acts as a gateway to."
|
||||
,"guide.antarchy.disk.rainbow_ant.title": "RAINBOW ANT FIELD NOTES"
|
||||
,"guide.antarchy.disk.brutalfly.title": "BRUTALFLY FIELD NOTES"
|
||||
,"guide.antarchy.entry.brutalfly.title": "Brutalfly"
|
||||
,"guide.antarchy.entry.brutalfly.subtitle": "Elythia hostile record"
|
||||
,"guide.antarchy.entry.brutalfly.description": "An oversized Elythian butterfly. Unlike its smaller counterparts, it is incredibly aggressive once out of its cocoon."
|
||||
,"guide.antarchy.entry.brutalfly.description2": "Like any butterfly, a Brutalfly begins in a cocoon. It is relatively safe to be near the cocoon as long as it remains undamaged."
|
||||
,"guide.antarchy.entry.brutalfly.description3": "If the Brutalfly is on the assault, all you can do is dispose of it."
|
||||
,"guide.antarchy.entry.easter_bunny.title": "Easter Bunny"
|
||||
,"guide.antarchy.entry.easter_bunny.subtitle": "Entity record"
|
||||
,"guide.antarchy.entry.easter_bunny.description": "The Easter Bunny lays spawn eggs for all sorts of creatures! Life is like an easter egg, you never know what you're gonna get."
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"category": "antarchy:elythia",
|
||||
"title": "guide.antarchy.disk.brutalfly.title",
|
||||
"entries": ["antarchy:brutalfly"]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"category": "antarchy:cavaryn",
|
||||
"title": "guide.antarchy.disk.hercules_beetle.title",
|
||||
"entries": ["antarchy:hercules_beetle"]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"category": "antarchy:general",
|
||||
"title": "guide.antarchy.disk.rainbow_ant.title",
|
||||
"entries": ["antarchy:rainbow_ant"]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"type": "mob",
|
||||
"category": "elythia",
|
||||
"title": "guide.antarchy.entry.brutalfly.title",
|
||||
"subtitle": "guide.antarchy.entry.brutalfly.subtitle",
|
||||
"description": ["guide.antarchy.entry.brutalfly.description", "guide.antarchy.entry.brutalfly.description2", "guide.antarchy.entry.brutalfly.description3"],
|
||||
"entity": "antarchy:brutalfly",
|
||||
"cover_entity": "antarchy:brutalfly",
|
||||
"rotation": 45,
|
||||
"render_scale": 0.6
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"type": "mob",
|
||||
"category": "cavaryn",
|
||||
"title": "guide.antarchy.entry.hercules_beetle.title",
|
||||
"subtitle": "guide.antarchy.entry.hercules_beetle.subtitle",
|
||||
"description": ["guide.antarchy.entry.hercules_beetle.description", "guide.antarchy.entry.hercules_beetle.description2", "guide.antarchy.entry.hercules_beetle.description3"],
|
||||
"entity": "antarchy:hercules_beetle",
|
||||
"cover_entity": "antarchy:hercules_beetle",
|
||||
"rotation": 45,
|
||||
"render_scale": 0.5
|
||||
}
|
||||
@@ -3,7 +3,11 @@
|
||||
"category": "general",
|
||||
"title": "guide.antarchy.entry.rainbow_ant.title",
|
||||
"subtitle": "guide.antarchy.entry.rainbow_ant.subtitle",
|
||||
"description": ["guide.antarchy.entry.rainbow_ant.description"],
|
||||
"description": [
|
||||
"guide.antarchy.entry.rainbow_ant.description",
|
||||
"guide.antarchy.entry.rainbow_ant.description2",
|
||||
"guide.antarchy.entry.rainbow_ant.description3"
|
||||
],
|
||||
"entity": "antarchy:rainbow_ant",
|
||||
"cover_entity": "antarchy:rainbow_ant",
|
||||
"rotation": 45
|
||||
|
||||
+13
@@ -174,6 +174,19 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antos:floppy_disk",
|
||||
"weight": 4,
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_components",
|
||||
"components": {
|
||||
"antos:floppy_disk": "antarchy:brutalfly"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"rolls": {
|
||||
|
||||
+13
@@ -43,6 +43,19 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antos:floppy_disk",
|
||||
"weight": 4,
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_components",
|
||||
"components": {
|
||||
"antos:floppy_disk": "antarchy:rainbow_ant"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antos:floppy_disk",
|
||||
|
||||
+13
@@ -237,6 +237,19 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antos:floppy_disk",
|
||||
"weight": 5,
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_components",
|
||||
"components": {
|
||||
"antos:floppy_disk": "antarchy:brutalfly"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"rolls": {
|
||||
|
||||
+13
@@ -167,6 +167,19 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "antos:floppy_disk",
|
||||
"weight": 4,
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_components",
|
||||
"components": {
|
||||
"antos:floppy_disk": "antarchy:hercules_beetle"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -16,6 +16,13 @@
|
||||
},
|
||||
"result": {
|
||||
"id": "antarchy:giant_frying_pan",
|
||||
"count": 1
|
||||
"count": 1,
|
||||
"components": {
|
||||
"minecraft:enchantments": {
|
||||
"levels": {
|
||||
"minecraft:fire_aspect": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -39,8 +39,8 @@
|
||||
],
|
||||
"placement": {
|
||||
"salt": 659843583,
|
||||
"spacing": 60,
|
||||
"separation": 50,
|
||||
"spacing": 42,
|
||||
"separation": 35,
|
||||
"type": "integrated_api:advanced_random_spread"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"antarchy:ultimate_shovel"
|
||||
"antarchy:ultimate_shovel",
|
||||
"antarchy:giant_frying_pan"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"antarchy:ultimate_shovel"
|
||||
"antarchy:ultimate_shovel",
|
||||
"antarchy:giant_frying_pan"
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user