Improve blackhole explosion, rendering server responsive when one is collapsing
This commit is contained in:
parent
0d3e7c4112
commit
92f1219b6a
@ -12,6 +12,7 @@ import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityBlackHole;
|
||||
import ru.dbotthepony.mc.otm.capability.AndroidCapability;
|
||||
import ru.dbotthepony.mc.otm.capability.AndroidCapabilityPlayer;
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
||||
@ -53,6 +54,7 @@ public class OverdriveThatMatters {
|
||||
MinecraftForge.EVENT_BUS.register(AndroidCapability.class);
|
||||
MinecraftForge.EVENT_BUS.register(MatterGrid.class);
|
||||
MinecraftForge.EVENT_BUS.register(MatterRegistry.class);
|
||||
MinecraftForge.EVENT_BUS.register(BlockEntityBlackHole.BlackHoleExplosionQueue.class);
|
||||
|
||||
FMLJavaModLoadingContext.get().getModEventBus().register(Registry.Items.class);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().register(Registry.Blocks.class);
|
||||
|
@ -52,7 +52,7 @@ public class Registry {
|
||||
DAMAGE_BECOME_ANDROID.bypassArmor().bypassInvul().bypassMagic();
|
||||
DAMAGE_BECOME_HUMANE.bypassArmor().bypassInvul().bypassMagic();
|
||||
DAMAGE_EVENT_HORIZON.bypassMagic().bypassArmor();
|
||||
DAMAGE_HAWKING_RADIATION.bypassMagic().bypassArmor();
|
||||
// DAMAGE_HAWKING_RADIATION.bypassMagic().bypassArmor();
|
||||
}
|
||||
|
||||
public static final ForgeRegistry<AndroidFeatureType<?>> ANDROID_FEATURES;
|
||||
|
@ -3,10 +3,13 @@ package ru.dbotthepony.mc.otm.block.entity;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
@ -21,8 +24,11 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.saveddata.SavedData;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
||||
@ -30,6 +36,7 @@ import ru.dbotthepony.mc.otm.matter.MatterRegistry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BlockEntityBlackHole extends BlockEntity {
|
||||
@ -67,6 +74,179 @@ public class BlockEntityBlackHole extends BlockEntity {
|
||||
private static final BlackHoleExplosionDamageCalculator INSTANCE = new BlackHoleExplosionDamageCalculator();
|
||||
}
|
||||
|
||||
public static class BlackHoleExplosionQueue extends SavedData {
|
||||
private record QueuedExplosion(double x, double y, double z, float radius) {
|
||||
public CompoundTag serializeNBT() {
|
||||
var tag = new CompoundTag();
|
||||
|
||||
tag.putDouble("x", x);
|
||||
tag.putDouble("y", y);
|
||||
tag.putDouble("z", z);
|
||||
tag.putFloat("radius", radius);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static QueuedExplosion deserializeNBT(CompoundTag tag) {
|
||||
return new QueuedExplosion(tag.getDouble("x"), tag.getDouble("y"), tag.getDouble("z"), tag.getFloat("radius"));
|
||||
}
|
||||
|
||||
public void explode(Level level) {
|
||||
level.explode(
|
||||
null,
|
||||
Registry.DAMAGE_HAWKING_RADIATION,
|
||||
BlackHoleExplosionDamageCalculator.INSTANCE,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
radius,
|
||||
false,
|
||||
Explosion.BlockInteraction.DESTROY);
|
||||
}
|
||||
}
|
||||
|
||||
private record RingExplosion(double x, double y, double z, double radius, float strength) {
|
||||
public CompoundTag serializeNBT() {
|
||||
var tag = new CompoundTag();
|
||||
|
||||
tag.putDouble("x", x);
|
||||
tag.putDouble("y", y);
|
||||
tag.putDouble("z", z);
|
||||
tag.putDouble("radius", radius);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static RingExplosion deserializeNBT(CompoundTag tag) {
|
||||
return new RingExplosion(tag.getDouble("x"), tag.getDouble("y"), tag.getDouble("z"), tag.getDouble("radius"), tag.getFloat("strength"));
|
||||
}
|
||||
|
||||
public void explode(BlackHoleExplosionQueue queue) {
|
||||
final int fragments = (int) radius * 8;
|
||||
|
||||
final double stack_step = Math.PI / (double) fragments;
|
||||
final double sector_step = Math.PI / (double) fragments * 2;
|
||||
|
||||
for (int stack = 0; stack < fragments; stack++) {
|
||||
final double stack_angle = Math.PI / 2 - stack * stack_step;
|
||||
final double xy = radius * 15 * Math.cos(stack_angle);
|
||||
final double z = radius * 15 * Math.sin(stack_angle);
|
||||
|
||||
for (int sector = 0; sector < fragments; sector++) {
|
||||
final double sector_angle = sector * sector_step;
|
||||
|
||||
queue.explode(
|
||||
this.x + xy * Math.cos(sector_angle),
|
||||
this.y + xy * Math.sin(sector_angle),
|
||||
this.z + z,
|
||||
strength
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int index = 0;
|
||||
private int index_ring = 0;
|
||||
private final ArrayList<QueuedExplosion> explosions = new ArrayList<>();
|
||||
private final ArrayList<RingExplosion> rings = new ArrayList<>();
|
||||
private final ServerLevel level;
|
||||
|
||||
public BlackHoleExplosionQueue(ServerLevel level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag save(CompoundTag tag) {
|
||||
var list = new ListTag();
|
||||
var list_rings = new ListTag();
|
||||
|
||||
for (int i = index; i < explosions.size(); i++)
|
||||
list.add(explosions.get(i).serializeNBT());
|
||||
|
||||
for (int i = index_ring; i < rings.size(); i++)
|
||||
list_rings.add(rings.get(i).serializeNBT());
|
||||
|
||||
tag.put("explosions", list);
|
||||
tag.put("rings", list_rings);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void load(CompoundTag tag) {
|
||||
explosions.clear();
|
||||
rings.clear();
|
||||
index = 0;
|
||||
index_ring = 0;
|
||||
|
||||
for (var explosion : tag.getList("explosions", Tag.TAG_COMPOUND))
|
||||
explosions.add(QueuedExplosion.deserializeNBT((CompoundTag) explosion));
|
||||
|
||||
for (var ring : tag.getList("rings", Tag.TAG_COMPOUND))
|
||||
rings.add(RingExplosion.deserializeNBT((CompoundTag) ring));
|
||||
}
|
||||
|
||||
public static BlackHoleExplosionQueue factory(ServerLevel level) {
|
||||
return level.getDataStorage().computeIfAbsent(
|
||||
(tag) -> {
|
||||
var factory = new BlackHoleExplosionQueue(level);
|
||||
factory.load(tag);
|
||||
return factory;
|
||||
},
|
||||
|
||||
() -> new BlackHoleExplosionQueue(level),
|
||||
|
||||
"otm_blackhole_explosion_queue"
|
||||
);
|
||||
}
|
||||
|
||||
public void explode(double x, double y, double z, float radius) {
|
||||
explosions.add(new QueuedExplosion(x, y, z, radius));
|
||||
setDirty();
|
||||
}
|
||||
|
||||
public void explodeRing(double x, double y, double z, double radius, float strength) {
|
||||
rings.add(new RingExplosion(x, y, z, radius, strength));
|
||||
setDirty();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (explosions.size() != 0) {
|
||||
setDirty();
|
||||
|
||||
int iterations = 0;
|
||||
|
||||
for (int i = index; i < explosions.size(); i++) {
|
||||
explosions.get(i).explode(level);
|
||||
index++;
|
||||
|
||||
if (iterations++ == 4) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= explosions.size()) {
|
||||
index = 0;
|
||||
explosions.clear();
|
||||
}
|
||||
} else if (rings.size() != 0) {
|
||||
if (index_ring >= rings.size()) {
|
||||
index_ring = 0;
|
||||
rings.clear();
|
||||
} else {
|
||||
rings.get(index_ring++).explode(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onWorldTick(TickEvent.WorldTickEvent event) {
|
||||
if (event.phase == TickEvent.Phase.START && event.world instanceof ServerLevel level) {
|
||||
factory(level).tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void collapse() {
|
||||
level.setBlock(getBlockPos(), Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL);
|
||||
|
||||
@ -75,44 +255,24 @@ public class BlockEntityBlackHole extends BlockEntity {
|
||||
final double y0 = getBlockPos().getY() + 0.5;
|
||||
final double z0 = getBlockPos().getZ() + 0.5;
|
||||
|
||||
var queue = BlackHoleExplosionQueue.factory((ServerLevel) level);
|
||||
|
||||
for (int radius = 0; radius < Math.ceil(gravitation_strength * 4); radius++) {
|
||||
final int fragments = radius * 8;
|
||||
|
||||
final double stack_step = Math.PI / (double) fragments;
|
||||
final double sector_step = Math.PI / (double) fragments * 2;
|
||||
|
||||
for (int stack = 0; stack < fragments; stack++) {
|
||||
final double stack_angle = Math.PI / 2 - stack * stack_step;
|
||||
final double xy = radius * 20 * Math.cos(stack_angle);
|
||||
final double z = radius * 20 * Math.sin(stack_angle);
|
||||
|
||||
for (int sector = 0; sector < fragments; sector++) {
|
||||
final double sector_angle = sector * sector_step;
|
||||
|
||||
final double x = xy * Math.cos(sector_angle);
|
||||
final double y = xy * Math.sin(sector_angle);
|
||||
|
||||
level.explode(
|
||||
null,
|
||||
Registry.DAMAGE_HAWKING_RADIATION,
|
||||
BlackHoleExplosionDamageCalculator.INSTANCE,
|
||||
x0 + x,
|
||||
y0 + y,
|
||||
z0 + z,
|
||||
(float) Math.min(30, Math.max(1, (gravitation_strength * 4 - radius) * 30)),
|
||||
false,
|
||||
Explosion.BlockInteraction.DESTROY);
|
||||
}
|
||||
}
|
||||
queue.explodeRing(
|
||||
x0,
|
||||
y0,
|
||||
z0,
|
||||
radius,
|
||||
(float) Math.min(20, Math.max(1, (gravitation_strength * 4 - radius) * 20)));
|
||||
}
|
||||
} else {
|
||||
level.explode(
|
||||
null,
|
||||
Registry.DAMAGE_HAWKING_RADIATION,
|
||||
null,
|
||||
(double)getBlockPos().getX() + 0.5D,
|
||||
(double)getBlockPos().getY() + 0.5D,
|
||||
(double)getBlockPos().getZ() + 0.5D,
|
||||
getBlockPos().getX() + 0.5D,
|
||||
getBlockPos().getY() + 0.5D,
|
||||
getBlockPos().getZ() + 0.5D,
|
||||
(float) gravitation_strength * 60,
|
||||
false,
|
||||
Explosion.BlockInteraction.DESTROY);
|
||||
|
Loading…
Reference in New Issue
Block a user