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_red.json
|
||||||
/src/main/resources/assets/overdrive_that_matters/models/block/crate_yellow.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/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 = [
|
const models = [
|
||||||
'android_station',
|
'android_station',
|
||||||
'battery_bank',
|
'battery_bank',
|
||||||
|
'black_hole',
|
||||||
['matter_scanner', 'matter_scanner_working'],
|
['matter_scanner', 'matter_scanner_working'],
|
||||||
'pattern_storage',
|
'pattern_storage',
|
||||||
['matter_replicator', 'matter_replicator_working'],
|
['matter_replicator', 'matter_replicator_working'],
|
||||||
@ -16,12 +17,143 @@ const root = _root + 'models/block/'
|
|||||||
|
|
||||||
const time = Date.now()
|
const time = Date.now()
|
||||||
process.stdout.write('Regenerating data files\n')
|
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')
|
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, '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, `// This file is regenerated on each gradle run. Do not edit it!\n`)
|
||||||
fs.writeSync(handle, 'public class BlockShapes {\n')
|
fs.writeSync(handle, 'public class BlockShapes {\n')
|
||||||
|
|
||||||
|
// модели блоков
|
||||||
for (const _model of models) {
|
for (const _model of models) {
|
||||||
let model, path
|
let model, path
|
||||||
|
|
||||||
@ -201,6 +333,8 @@ const facings = [
|
|||||||
'crate_black',
|
'crate_black',
|
||||||
'crate_pink',
|
'crate_pink',
|
||||||
'crate_purple',
|
'crate_purple',
|
||||||
|
|
||||||
|
'black_hole',
|
||||||
]
|
]
|
||||||
|
|
||||||
const blocks2 = [
|
const blocks2 = [
|
||||||
@ -224,6 +358,10 @@ const facings = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, null, '\t'))
|
}, null, '\t'))
|
||||||
|
|
||||||
|
fs.writeFileSync(_root + 'models/item/' + name + '.json', JSON.stringify({
|
||||||
|
"parent": "overdrive_that_matters:block/" + name
|
||||||
|
}, null, '\t'))
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const name of blocks2) {
|
for (const name of blocks2) {
|
||||||
|
@ -40,12 +40,14 @@ import ru.dbotthepony.mc.otm.screen.*;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
public class Registry {
|
public class Registry {
|
||||||
public static final DamageSource DAMAGE_BECOME_ANDROID = new DamageSource("otmBecomeAndroid");
|
public static final DamageSource DAMAGE_BECOME_ANDROID = new DamageSource("otm_become_android");
|
||||||
public static final DamageSource DAMAGE_BECOME_HUMANE = new DamageSource("otmBecomeHumane");
|
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 {
|
static {
|
||||||
DAMAGE_BECOME_ANDROID.bypassArmor().bypassInvul().bypassMagic();
|
DAMAGE_BECOME_ANDROID.bypassArmor().bypassInvul().bypassMagic();
|
||||||
DAMAGE_BECOME_HUMANE.bypassArmor().bypassInvul().bypassMagic();
|
DAMAGE_BECOME_HUMANE.bypassArmor().bypassInvul().bypassMagic();
|
||||||
|
DAMAGE_EVENT_HORIZON.bypassMagic().bypassArmor();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ForgeRegistry<AndroidFeatureType<?>> ANDROID_FEATURES;
|
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 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 DRIVE_VIEWER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "drive_viewer");
|
||||||
|
|
||||||
|
public static final ResourceLocation BLACK_HOLE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "black_hole");
|
||||||
|
|
||||||
// building blocks
|
// building blocks
|
||||||
public static final ResourceLocation TRITANIUM_BLOCK = new ResourceLocation(OverdriveThatMatters.MOD_ID, "tritanium_block");
|
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");
|
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 MATTER_BOTTLER = new BlockMatterBottler();
|
||||||
public static final Block DRIVE_VIEWER = new BlockDriveViewer();
|
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[] CRATES = new Block[Registry.CRATES.length];
|
||||||
|
|
||||||
public static final Block TRITANIUM_BLOCK = new Block(
|
public static final Block TRITANIUM_BLOCK = new Block(
|
||||||
@ -251,6 +257,7 @@ public class Registry {
|
|||||||
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
|
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
|
||||||
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
|
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
|
||||||
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
|
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
|
||||||
|
BLACK_HOLE.setRegistryName(Names.BLACK_HOLE);
|
||||||
|
|
||||||
TRITANIUM_BLOCK.setRegistryName(Names.TRITANIUM_BLOCK);
|
TRITANIUM_BLOCK.setRegistryName(Names.TRITANIUM_BLOCK);
|
||||||
TRITANIUM_STRIPED_BLOCK.setRegistryName(Names.TRITANIUM_STRIPED_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_BLOCK);
|
||||||
event.getRegistry().register(TRITANIUM_STRIPED_BLOCK);
|
event.getRegistry().register(TRITANIUM_STRIPED_BLOCK);
|
||||||
event.getRegistry().register(CARBON_FIBRE_BLOCK);
|
event.getRegistry().register(CARBON_FIBRE_BLOCK);
|
||||||
|
event.getRegistry().register(BLACK_HOLE);
|
||||||
|
|
||||||
for (var crate : CRATES) {
|
for (var crate : CRATES) {
|
||||||
event.getRegistry().register(crate);
|
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 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 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_ANDROID = new ItemPill(ItemPill.PillType.BECOME_ANDROID);
|
||||||
public static final ItemPill PILL_HUMANE = new ItemPill(ItemPill.PillType.BECOME_HUMANE);
|
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_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
|
||||||
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
|
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
|
||||||
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
|
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
|
||||||
|
BLACK_HOLE.setRegistryName(Names.BLACK_HOLE);
|
||||||
|
|
||||||
PILL_ANDROID.setRegistryName(Names.PILL_ANDROID);
|
PILL_ANDROID.setRegistryName(Names.PILL_ANDROID);
|
||||||
PILL_HUMANE.setRegistryName(Names.PILL_HUMANE);
|
PILL_HUMANE.setRegistryName(Names.PILL_HUMANE);
|
||||||
@ -377,6 +388,7 @@ public class Registry {
|
|||||||
event.getRegistry().register(MATTER_REPLICATOR);
|
event.getRegistry().register(MATTER_REPLICATOR);
|
||||||
event.getRegistry().register(MATTER_BOTTLER);
|
event.getRegistry().register(MATTER_BOTTLER);
|
||||||
event.getRegistry().register(DRIVE_VIEWER);
|
event.getRegistry().register(DRIVE_VIEWER);
|
||||||
|
event.getRegistry().register(BLACK_HOLE);
|
||||||
|
|
||||||
event.getRegistry().register(PILL_ANDROID);
|
event.getRegistry().register(PILL_ANDROID);
|
||||||
event.getRegistry().register(PILL_HUMANE);
|
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<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<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<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 {
|
static {
|
||||||
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
|
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
|
||||||
@ -434,6 +447,7 @@ public class Registry {
|
|||||||
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
|
MATTER_REPLICATOR.setRegistryName(Names.MATTER_REPLICATOR);
|
||||||
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
|
MATTER_BOTTLER.setRegistryName(Names.MATTER_BOTTLER);
|
||||||
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
|
DRIVE_VIEWER.setRegistryName(Names.DRIVE_VIEWER);
|
||||||
|
BLACK_HOLE.setRegistryName(Names.BLACK_HOLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
@ -449,6 +463,7 @@ public class Registry {
|
|||||||
event.getRegistry().register(MATTER_REPLICATOR);
|
event.getRegistry().register(MATTER_REPLICATOR);
|
||||||
event.getRegistry().register(MATTER_BOTTLER);
|
event.getRegistry().register(MATTER_BOTTLER);
|
||||||
event.getRegistry().register(DRIVE_VIEWER);
|
event.getRegistry().register(DRIVE_VIEWER);
|
||||||
|
event.getRegistry().register(BLACK_HOLE);
|
||||||
|
|
||||||
// OverdriveThatMatters.LOGGER.info("Registered block entities");
|
// OverdriveThatMatters.LOGGER.info("Registered block entities");
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,50 @@
|
|||||||
package ru.dbotthepony.mc.otm.block;
|
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.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.zepto": "%s z%s",
|
||||||
"otm.suffix.yocto": "%s y%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.android_station": "Android station",
|
||||||
"block.overdrive_that_matters.battery_bank": "Battery bank",
|
"block.overdrive_that_matters.battery_bank": "Battery bank",
|
||||||
"block.overdrive_that_matters.matter_decomposer": "Matter decomposer",
|
"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_replicator": "Matter replicator",
|
||||||
"block.overdrive_that_matters.matter_bottler": "Matter bottler",
|
"block.overdrive_that_matters.matter_bottler": "Matter bottler",
|
||||||
"block.overdrive_that_matters.drive_viewer": "Drive viewer",
|
"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",
|
"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