Black holes
This commit is contained in:
parent
ac7bcc0f75
commit
8fe2d8daa8
13
.gitignore
vendored
13
.gitignore
vendored
@ -100,3 +100,16 @@ forge*changelog.txt
|
||||
/src/main/resources/assets/overdrive_that_matters/models/block/crate_red.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/block/crate_yellow.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/block/tritanium_block.json
|
||||
/src/main/resources/assets/overdrive_that_matters/blockstates/black_hole.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/block/black_hole.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/black_hole.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/carbon_fibre_block.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/crate_black.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/crate_blue.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/crate_green.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/crate_pink.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/crate_purple.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/crate_red.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/crate_yellow.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/tritanium_block.json
|
||||
/src/main/resources/assets/overdrive_that_matters/models/item/tritanium_striped_block.json
|
||||
|
138
shapenator.js
138
shapenator.js
@ -2,6 +2,7 @@
|
||||
const models = [
|
||||
'android_station',
|
||||
'battery_bank',
|
||||
'black_hole',
|
||||
['matter_scanner', 'matter_scanner_working'],
|
||||
'pattern_storage',
|
||||
['matter_replicator', 'matter_replicator_working'],
|
||||
@ -16,12 +17,143 @@ const root = _root + 'models/block/'
|
||||
|
||||
const time = Date.now()
|
||||
process.stdout.write('Regenerating data files\n')
|
||||
|
||||
// "модель" горизонта событий / черной дыры
|
||||
{
|
||||
const elements = []
|
||||
|
||||
// сфера
|
||||
const layers = 32
|
||||
const radius = 16
|
||||
const checked = new Array(Math.pow(layers, 3))
|
||||
|
||||
// создание + слияние вдоль Y
|
||||
for (let y = -layers / 2; y < layers / 2; y++) {
|
||||
for (let x = -layers / 2; x < layers / 2; x++) {
|
||||
for (let z = -layers / 2; z < layers / 2; z++) {
|
||||
const dist1 = Math.sqrt(x * x + y * y + z * z)
|
||||
|
||||
if (dist1 <= radius) {
|
||||
const index1 = x + layers / 2 + (z + layers / 2) * layers + (y + layers / 2) * layers * layers
|
||||
|
||||
if (!checked[index1]) {
|
||||
let height = 0
|
||||
let index
|
||||
|
||||
for (let y2 = 0; y2 < layers; y2++) {
|
||||
const dist = Math.sqrt(x * x + (y + y2) * (y + y2) + z * z)
|
||||
const index2 = x + layers / 2 + (z + layers / 2) * layers + (y + y2 + layers / 2) * layers * layers
|
||||
|
||||
if (dist <= radius && !checked[index2]) {
|
||||
height = y2
|
||||
index = index2
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (height > 0) {
|
||||
checked[index] = {
|
||||
"from": [4 + (x + layers / 2) / layers * 8, 4 + (y + layers / 2) / layers * 8, 4 + (z + layers / 2) / layers * 8],
|
||||
"to": [4 + (x + layers / 2 + 1) / layers * 8, 4 + (y + layers / 2 + height) / layers * 8, 4 + (z + layers / 2 + 1) / layers * 8],
|
||||
"faces": {
|
||||
"down": { "texture": "#black_hole" },
|
||||
"up": { "texture": "#black_hole" },
|
||||
"north": { "texture": "#black_hole" },
|
||||
"south": { "texture": "#black_hole" },
|
||||
"west": { "texture": "#black_hole" },
|
||||
"east": { "texture": "#black_hole" }
|
||||
}
|
||||
}
|
||||
|
||||
elements.push(checked[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// слияние вдоль X
|
||||
for (let y = -layers / 2; y < layers / 2; y++) {
|
||||
for (let z = -layers / 2; z < layers / 2; z++) {
|
||||
let last_element = null
|
||||
|
||||
for (let x = -layers / 2; x < layers / 2; x++) {
|
||||
const index = x + layers / 2 + (z + layers / 2) * layers + (y + layers / 2) * layers * layers
|
||||
|
||||
if (checked[index]) {
|
||||
if (last_element) {
|
||||
const from1 = checked[index].from
|
||||
const from2 = last_element.from
|
||||
|
||||
if (from1[1] == from2[1] && from1[2] == from2[2]) {
|
||||
last_element.to[0] = checked[index].to[0]
|
||||
checked[index] = last_element
|
||||
} else {
|
||||
last_element = checked[index]
|
||||
}
|
||||
} else {
|
||||
last_element = checked[index]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const merged_z = []
|
||||
|
||||
// слияние вдоль Z
|
||||
for (let y = -layers / 2; y < layers / 2; y++) {
|
||||
for (let x = -layers / 2; x < layers / 2; x++) {
|
||||
let last_element = null
|
||||
|
||||
for (let z = -layers / 2; z < layers / 2; z++) {
|
||||
const index = x + layers / 2 + (z + layers / 2) * layers + (y + layers / 2) * layers * layers
|
||||
|
||||
if (checked[index]) {
|
||||
if (last_element) {
|
||||
const from1 = checked[index].from
|
||||
const from2 = last_element.from
|
||||
|
||||
if (from1[0] == from2[0] && from1[1] == from2[1]) {
|
||||
last_element.to[2] = checked[index].to[2]
|
||||
checked[index] = last_element
|
||||
} else {
|
||||
if (!merged_z.includes(last_element)) {
|
||||
merged_z.push(last_element)
|
||||
}
|
||||
|
||||
last_element = checked[index]
|
||||
}
|
||||
} else {
|
||||
last_element = checked[index]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last_element && !merged_z.includes(last_element)) {
|
||||
merged_z.push(last_element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(root + 'black_hole.json', JSON.stringify({
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"black_hole": "overdrive_that_matters:block/black_hole"
|
||||
},
|
||||
"elements": merged_z
|
||||
}, null, '\t'))
|
||||
}
|
||||
|
||||
const handle = fs.openSync('./src/main/java/ru/dbotthepony/mc/otm/shapes/BlockShapes.java', 'w')
|
||||
|
||||
fs.writeSync(handle, 'package ru.dbotthepony.mc.otm.shapes;\n\n\n')
|
||||
fs.writeSync(handle, `// This file is regenerated on each gradle run. Do not edit it!\n`)
|
||||
fs.writeSync(handle, 'public class BlockShapes {\n')
|
||||
|
||||
// модели блоков
|
||||
for (const _model of models) {
|
||||
let model, path
|
||||
|
||||
@ -201,6 +333,8 @@ const facings = [
|
||||
'crate_black',
|
||||
'crate_pink',
|
||||
'crate_purple',
|
||||
|
||||
'black_hole',
|
||||
]
|
||||
|
||||
const blocks2 = [
|
||||
@ -224,6 +358,10 @@ const facings = [
|
||||
}
|
||||
}
|
||||
}, null, '\t'))
|
||||
|
||||
fs.writeFileSync(_root + 'models/item/' + name + '.json', JSON.stringify({
|
||||
"parent": "overdrive_that_matters:block/" + name
|
||||
}, null, '\t'))
|
||||
}
|
||||
|
||||
for (const name of blocks2) {
|
||||
|
@ -40,12 +40,14 @@ import ru.dbotthepony.mc.otm.screen.*;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class Registry {
|
||||
public static final DamageSource DAMAGE_BECOME_ANDROID = new DamageSource("otmBecomeAndroid");
|
||||
public static final DamageSource DAMAGE_BECOME_HUMANE = new DamageSource("otmBecomeHumane");
|
||||
public static final DamageSource DAMAGE_BECOME_ANDROID = new DamageSource("otm_become_android");
|
||||
public static final DamageSource DAMAGE_BECOME_HUMANE = new DamageSource("otm_become_humane");
|
||||
public static final DamageSource DAMAGE_EVENT_HORIZON = new DamageSource("otm_event_horizon");
|
||||
|
||||
static {
|
||||
DAMAGE_BECOME_ANDROID.bypassArmor().bypassInvul().bypassMagic();
|
||||
DAMAGE_BECOME_HUMANE.bypassArmor().bypassInvul().bypassMagic();
|
||||
DAMAGE_EVENT_HORIZON.bypassMagic().bypassArmor();
|
||||
}
|
||||
|
||||
private static ForgeRegistry<AndroidFeatureType<?>> ANDROID_FEATURES;
|
||||
@ -109,6 +111,8 @@ public class Registry {
|
||||
public static final ResourceLocation MATTER_BOTTLER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_bottler");
|
||||
public static final ResourceLocation DRIVE_VIEWER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "drive_viewer");
|
||||
|
||||
public static final ResourceLocation BLACK_HOLE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "black_hole");
|
||||
|
||||
// building blocks
|
||||
public static final ResourceLocation TRITANIUM_BLOCK = new ResourceLocation(OverdriveThatMatters.MOD_ID, "tritanium_block");
|
||||
public static final ResourceLocation TRITANIUM_STRIPED_BLOCK = new ResourceLocation(OverdriveThatMatters.MOD_ID, "tritanium_striped_block");
|
||||
@ -204,6 +208,8 @@ public class Registry {
|
||||
public static final Block MATTER_BOTTLER = new BlockMatterBottler();
|
||||
public static final Block DRIVE_VIEWER = new BlockDriveViewer();
|
||||
|
||||
public static final Block BLACK_HOLE = new BlockBlackHole();
|
||||
|
||||
public static final Block[] CRATES = new Block[Registry.CRATES.length];
|
||||
|
||||
public static final Block TRITANIUM_BLOCK = new Block(
|
||||
@ -251,6 +257,7 @@ public class Registry {
|
||||
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
|
||||
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
|
||||
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
|
||||
BLACK_HOLE.setRegistryName(Names.BLACK_HOLE);
|
||||
|
||||
TRITANIUM_BLOCK.setRegistryName(Names.TRITANIUM_BLOCK);
|
||||
TRITANIUM_STRIPED_BLOCK.setRegistryName(Names.TRITANIUM_STRIPED_BLOCK);
|
||||
@ -273,6 +280,7 @@ public class Registry {
|
||||
event.getRegistry().register(TRITANIUM_BLOCK);
|
||||
event.getRegistry().register(TRITANIUM_STRIPED_BLOCK);
|
||||
event.getRegistry().register(CARBON_FIBRE_BLOCK);
|
||||
event.getRegistry().register(BLACK_HOLE);
|
||||
|
||||
for (var crate : CRATES) {
|
||||
event.getRegistry().register(crate);
|
||||
@ -295,6 +303,8 @@ public class Registry {
|
||||
public static final Item MATTER_BOTTLER = new BlockItem(Blocks.MATTER_BOTTLER, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
|
||||
public static final Item DRIVE_VIEWER = new BlockItem(Blocks.DRIVE_VIEWER, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
|
||||
|
||||
public static final Item BLACK_HOLE = new BlockItem(Blocks.BLACK_HOLE, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
|
||||
|
||||
public static final ItemPill PILL_ANDROID = new ItemPill(ItemPill.PillType.BECOME_ANDROID);
|
||||
public static final ItemPill PILL_HUMANE = new ItemPill(ItemPill.PillType.BECOME_HUMANE);
|
||||
|
||||
@ -339,6 +349,7 @@ public class Registry {
|
||||
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
|
||||
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
|
||||
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
|
||||
BLACK_HOLE.setRegistryName(Names.BLACK_HOLE);
|
||||
|
||||
PILL_ANDROID.setRegistryName(Names.PILL_ANDROID);
|
||||
PILL_HUMANE.setRegistryName(Names.PILL_HUMANE);
|
||||
@ -377,6 +388,7 @@ public class Registry {
|
||||
event.getRegistry().register(MATTER_REPLICATOR);
|
||||
event.getRegistry().register(MATTER_BOTTLER);
|
||||
event.getRegistry().register(DRIVE_VIEWER);
|
||||
event.getRegistry().register(BLACK_HOLE);
|
||||
|
||||
event.getRegistry().register(PILL_ANDROID);
|
||||
event.getRegistry().register(PILL_HUMANE);
|
||||
@ -421,6 +433,7 @@ public class Registry {
|
||||
public static final BlockEntityType<BlockEntityMatterReplicator> MATTER_REPLICATOR = BlockEntityType.Builder.of(BlockEntityMatterReplicator::new, Blocks.MATTER_REPLICATOR).build(null);
|
||||
public static final BlockEntityType<BlockEntityMatterBottler> MATTER_BOTTLER = BlockEntityType.Builder.of(BlockEntityMatterBottler::new, Blocks.MATTER_BOTTLER).build(null);
|
||||
public static final BlockEntityType<BlockEntityDriveViewer> DRIVE_VIEWER = BlockEntityType.Builder.of(BlockEntityDriveViewer::new, Blocks.DRIVE_VIEWER).build(null);
|
||||
public static final BlockEntityType<BlockEntityBlackHole> BLACK_HOLE = BlockEntityType.Builder.of(BlockEntityBlackHole::new, Blocks.BLACK_HOLE).build(null);
|
||||
|
||||
static {
|
||||
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
|
||||
@ -434,6 +447,7 @@ public class Registry {
|
||||
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
|
||||
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
|
||||
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
|
||||
BLACK_HOLE.setRegistryName(Names.BLACK_HOLE);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@ -449,6 +463,7 @@ public class Registry {
|
||||
event.getRegistry().register(MATTER_REPLICATOR);
|
||||
event.getRegistry().register(MATTER_BOTTLER);
|
||||
event.getRegistry().register(DRIVE_VIEWER);
|
||||
event.getRegistry().register(BLACK_HOLE);
|
||||
|
||||
// OverdriveThatMatters.LOGGER.info("Registered block entities");
|
||||
}
|
||||
|
@ -1,6 +1,50 @@
|
||||
package ru.dbotthepony.mc.otm.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityBlackHole;
|
||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes;
|
||||
|
||||
public class BlockBlackHole extends Block {
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BlockBlackHole extends Block implements EntityBlock {
|
||||
public BlockBlackHole() {
|
||||
super(Properties.of(
|
||||
new Material.Builder(MaterialColor.COLOR_BLACK).noCollider().nonSolid().build()
|
||||
).strength(-1, 7200000.0F));
|
||||
}
|
||||
|
||||
public static final VoxelShape SHAPE = BlockShapes.BLACK_HOLE.computeShape();
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) {
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return new BlockEntityBlackHole(blockPos, blockState);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) {
|
||||
if (p_153214_ != Registry.BlockEntities.BLACK_HOLE)
|
||||
return null;
|
||||
|
||||
return p_153212_.isClientSide ? BlockEntityBlackHole::clientTicker : BlockEntityBlackHole::ticker;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,205 @@
|
||||
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.StringTag;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
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.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
||||
import ru.dbotthepony.mc.otm.matter.MatterRegistry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class BlockEntityBlackHole extends BlockEntity {
|
||||
public BlockEntityBlackHole(BlockPos p_155229_, BlockState p_155230_) {
|
||||
super(Registry.BlockEntities.BLACK_HOLE, p_155229_, p_155230_);
|
||||
setMass(mass);
|
||||
}
|
||||
|
||||
public static final BigDecimal NORMAL_MASS = new BigDecimal(10_000);
|
||||
private BigDecimal mass = NORMAL_MASS;
|
||||
private double gravitation_strength = 1;
|
||||
private boolean suppress_updates = true;
|
||||
|
||||
public void collapse() {
|
||||
|
||||
}
|
||||
|
||||
public void addMass(BigDecimal mass) {
|
||||
setMass(this.mass.add(mass));
|
||||
}
|
||||
|
||||
public void setMass(BigDecimal mass) {
|
||||
if (mass.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
collapse();
|
||||
return;
|
||||
}
|
||||
|
||||
this.mass = mass;
|
||||
setChanged();
|
||||
gravitation_strength = mass.divide(NORMAL_MASS, MatteryCapability.ROUND_RULES).doubleValue();
|
||||
|
||||
if (level != null && !level.isClientSide && !suppress_updates)
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), Block.UPDATE_CLIENTS);
|
||||
|
||||
affected_bounds = new BoundingBox(
|
||||
(int) (-30 * gravitation_strength),
|
||||
(int) (-30 * gravitation_strength),
|
||||
(int) (-30 * gravitation_strength),
|
||||
(int) (30 * gravitation_strength),
|
||||
(int) (30 * gravitation_strength),
|
||||
(int) (30 * gravitation_strength)
|
||||
).move(getBlockPos());
|
||||
|
||||
affected_bounds_aabb = AABB.of(affected_bounds);
|
||||
}
|
||||
|
||||
// shared functions
|
||||
public CompoundTag writeBlackHoleData(CompoundTag tag) {
|
||||
tag.putString("mass", mass.toString());
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void readBlackHoleData(CompoundTag tag) {
|
||||
if (tag.get("mass") instanceof StringTag str)
|
||||
setMass(new BigDecimal(str.getAsString()));
|
||||
}
|
||||
|
||||
// disk io
|
||||
@Override
|
||||
public CompoundTag save(CompoundTag tag) {
|
||||
writeBlackHoleData(tag);
|
||||
return super.save(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag tag) {
|
||||
super.load(tag);
|
||||
readBlackHoleData(tag);
|
||||
}
|
||||
|
||||
// received either by game engine (from getUpdateTag on ClientLevelPacket)
|
||||
// or by onDataPacket
|
||||
@Override
|
||||
public void handleUpdateTag(CompoundTag tag) {
|
||||
super.handleUpdateTag(tag);
|
||||
readBlackHoleData(tag);
|
||||
}
|
||||
|
||||
// called by game engine for ClientLevelPacket
|
||||
@Override
|
||||
public CompoundTag getUpdateTag() {
|
||||
return writeBlackHoleData(super.getUpdateTag());
|
||||
}
|
||||
|
||||
// called by game engine on block updsates
|
||||
@Nullable
|
||||
@Override
|
||||
public ClientboundBlockEntityDataPacket getUpdatePacket() {
|
||||
return new ClientboundBlockEntityDataPacket(getBlockPos(), 0, writeBlackHoleData(new CompoundTag()));
|
||||
}
|
||||
|
||||
// called by game engine by forge patches when ClientboundBlockEntityDataPacket is received
|
||||
@Override
|
||||
public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) {
|
||||
super.onDataPacket(net, pkt);
|
||||
|
||||
if (net.getReceiving() == PacketFlow.CLIENTBOUND) {
|
||||
handleUpdateTag(pkt.getTag());
|
||||
}
|
||||
}
|
||||
|
||||
private BoundingBox affected_bounds;
|
||||
private AABB affected_bounds_aabb;
|
||||
|
||||
public BoundingBox affectedBounds() {
|
||||
return affected_bounds;
|
||||
}
|
||||
|
||||
public AABB affectedBoundsAABB() {
|
||||
return affected_bounds_aabb;
|
||||
}
|
||||
|
||||
private void setDeltaMovement(Entity living, Vec3 center, double distance) {
|
||||
//final double mult = Math.min(2, (30 * this.gravitation_strength) / Math.max(1, Math.pow(distance, 2)));
|
||||
final double mult = Math.pow(1 - distance / (30 * this.gravitation_strength), 2) * this.gravitation_strength / 8;
|
||||
|
||||
final var delta = living.position().vectorTo(center).normalize();
|
||||
living.setDeltaMovement(living.getDeltaMovement().add(delta.multiply(mult, mult, mult)));
|
||||
}
|
||||
|
||||
public static <T extends BlockEntity> void clientTicker(Level level, BlockPos blockPos, BlockState blockState, T t) {
|
||||
if (t instanceof BlockEntityBlackHole tile) {
|
||||
var ply = Minecraft.getInstance().player;
|
||||
final var center = Vec3.atCenterOf(tile.getBlockPos());
|
||||
|
||||
if (!ply.getAbilities().mayfly) {
|
||||
final double distance = ply.position().distanceTo(center);
|
||||
tile.setDeltaMovement(ply, center, distance);
|
||||
}
|
||||
|
||||
for (var item : tile.level.getEntitiesOfClass(ItemEntity.class, tile.affected_bounds_aabb)) {
|
||||
final double distance = item.position().distanceTo(center);
|
||||
tile.setDeltaMovement(item, center, distance);
|
||||
|
||||
if (distance < tile.gravitation_strength * 2) {
|
||||
if (item.hurt(Registry.DAMAGE_EVENT_HORIZON, (float) (tile.gravitation_strength / distance)) && item.isRemoved()) {
|
||||
var mass = MatterRegistry.getMatterValue(item.getItem());
|
||||
|
||||
if (mass.compareTo(BigDecimal.ZERO) > 0)
|
||||
tile.addMass(mass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends BlockEntity> void ticker(Level level, BlockPos blockPos, BlockState blockState, T t) {
|
||||
if (t instanceof BlockEntityBlackHole tile) {
|
||||
tile.suppress_updates = false;
|
||||
|
||||
final var center = Vec3.atCenterOf(tile.getBlockPos());
|
||||
|
||||
for (var living : tile.level.getEntitiesOfClass(LivingEntity.class, tile.affected_bounds_aabb)) {
|
||||
final double distance = living.position().distanceTo(center);
|
||||
|
||||
if (!(living instanceof Player ply) || !ply.getAbilities().mayfly) {
|
||||
tile.setDeltaMovement(living, center, distance);
|
||||
}
|
||||
|
||||
if (distance < tile.gravitation_strength * 2) {
|
||||
living.hurt(Registry.DAMAGE_EVENT_HORIZON, (float) (tile.gravitation_strength / distance));
|
||||
}
|
||||
}
|
||||
|
||||
for (var item : tile.level.getEntitiesOfClass(ItemEntity.class, tile.affected_bounds_aabb)) {
|
||||
final double distance = item.position().distanceTo(center);
|
||||
tile.setDeltaMovement(item, center, distance);
|
||||
|
||||
if (distance < tile.gravitation_strength * 2) {
|
||||
if (item.hurt(Registry.DAMAGE_EVENT_HORIZON, (float) (tile.gravitation_strength / distance)) && item.isRemoved()) {
|
||||
var mass = MatterRegistry.getMatterValue(item.getItem());
|
||||
|
||||
if (mass.compareTo(BigDecimal.ZERO) > 0)
|
||||
tile.addMass(mass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -111,6 +111,14 @@
|
||||
"otm.suffix.zepto": "%s z%s",
|
||||
"otm.suffix.yocto": "%s y%s",
|
||||
|
||||
"death.attack.otm_become_android": "%1$s lost their humanity",
|
||||
"death.attack.otm_become_humane": "%1$s gained their humanity",
|
||||
"death.attack.otm_event_horizon": "%1$s never crossed event horizon",
|
||||
|
||||
"death.attack.otm_become_android.player": "%1$s lost their humanity whilst %2$s tried to reason with them",
|
||||
"death.attack.otm_become_humane.player": "%1$s gained their humanity whilst %2$s tried to reason with them",
|
||||
"death.attack.otm_event_horizon.player": "%1$s tried to cross event horizon whilst trying to escape %2$s",
|
||||
|
||||
"block.overdrive_that_matters.android_station": "Android station",
|
||||
"block.overdrive_that_matters.battery_bank": "Battery bank",
|
||||
"block.overdrive_that_matters.matter_decomposer": "Matter decomposer",
|
||||
@ -122,6 +130,7 @@
|
||||
"block.overdrive_that_matters.matter_replicator": "Matter replicator",
|
||||
"block.overdrive_that_matters.matter_bottler": "Matter bottler",
|
||||
"block.overdrive_that_matters.drive_viewer": "Drive viewer",
|
||||
"block.overdrive_that_matters.black_hole": "Miniature Event Horizon",
|
||||
|
||||
"otm.container.matter_panel.number_input": "Input replication task count",
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 141 B |
Loading…
Reference in New Issue
Block a user