Work on mimics as well as some structure tinkering.
This commit is contained in:
parent
545b50ac82
commit
546215ab37
|
@ -146,6 +146,7 @@ d4e4cbb3a24e069a8e6c8e60764f8bbb7b3adb2b assets/bloodmagic/models/block/dungeon_
|
|||
3895234c0c49d936ad0ad420dedd3669999b8a81 assets/bloodmagic/models/block/dungeon_tilespecial.json
|
||||
81313327125e6e7396df0408595228bf0f63e1c9 assets/bloodmagic/models/block/duskritualstone.json
|
||||
c30064f4aa09c42d23e94d118ae5b148eadb3a6c assets/bloodmagic/models/block/earthritualstone.json
|
||||
44c4d3178261b3756987643b62f263c91fa74198 assets/bloodmagic/models/block/etherealopaquemimic.json
|
||||
4ff1cab1014cd8f655e5f032ecf60dd371f421c3 assets/bloodmagic/models/block/fireritualstone.json
|
||||
d6bf1482345199e7d056a60865024ea5d480b986 assets/bloodmagic/models/block/largebloodstonebrick.json
|
||||
2e1a81c758bfeec2aee807b48239f23241302268 assets/bloodmagic/models/block/lightritualstone.json
|
||||
|
@ -156,6 +157,10 @@ c3a813b735cd229f8597e41d04465926b2e65fe1 assets/bloodmagic/models/block/orbcapac
|
|||
9b2bf2a44b788cbaecbe63a3e085e8de76672e1b assets/bloodmagic/models/block/ritualstone.json
|
||||
a8a1d06fcc2f8395530c72d2846133fff37d5537 assets/bloodmagic/models/block/sacrificerune.json
|
||||
791c9f2e27215ff0a45eed7efe385276bfc09aed assets/bloodmagic/models/block/selfsacrificerune.json
|
||||
d6238c0661560abd991d534ef6c8836f4655a7e7 assets/bloodmagic/models/block/sentientmimic.json
|
||||
6556131b1aeb25dc67daf31a1ecdb3ce23e718d4 assets/bloodmagic/models/block/solidclearmimic.json
|
||||
88b9f25444280d323fff11046d4d3a3af11265e8 assets/bloodmagic/models/block/solidlightmimic.json
|
||||
23d937795efdb02507d301c459e52cd4b0cfa5cb assets/bloodmagic/models/block/solidopaquemimic.json
|
||||
65fe5e01ed2660e45a5c329ff2389a87e4d791ec assets/bloodmagic/models/block/speedrune.json
|
||||
c5d2b0e33500a5c51046cd606e0d1272ec0dddd6 assets/bloodmagic/models/block/stonebrickpath.json
|
||||
359e28e79778961f57c6369b5d1b68218972fccb assets/bloodmagic/models/block/stonetilepath.json
|
||||
|
@ -224,6 +229,7 @@ f3b763d6edc3c75655797481f05e02d409f481d9 assets/bloodmagic/models/item/dungeon_p
|
|||
5783901af844ab0a741958dbe684d668a9c293c4 assets/bloodmagic/models/item/duskscribetool.json
|
||||
4d56efd7fdbf430f49903ce201577047687c3804 assets/bloodmagic/models/item/earthritualstone.json
|
||||
98ee75786f9d0ab2a8c0835896d07d18df77de0f assets/bloodmagic/models/item/earthscribetool.json
|
||||
cdbaaf8662f2e855a34a66f28e49403c4ea9a45e assets/bloodmagic/models/item/ethereal_mimic.json
|
||||
4c39378f6c14dc243a7d52564e5a21df94683415 assets/bloodmagic/models/item/etherealslate.json
|
||||
6ccd9f4e27f43b7f30217e73e0cdfad3bc826b1e assets/bloodmagic/models/item/explosivepowder.json
|
||||
c36bde4f98c0aeb3bf0f369ad3bc067e5f0dc916 assets/bloodmagic/models/item/fireritualstone.json
|
||||
|
@ -245,6 +251,7 @@ ccbcba6e4a6450bb67f91ba17754d668ba64c0ac assets/bloodmagic/models/item/ironfragm
|
|||
15d8178b626da912334774142d40d1012fb21fa0 assets/bloodmagic/models/item/magicianbloodorb.json
|
||||
0a3566d3c86403f24c22977dd32ffaec727a9ad3 assets/bloodmagic/models/item/masterbloodorb.json
|
||||
9e377ab2c131993f96ab6fb544bda4dbba0ab87e assets/bloodmagic/models/item/masterritualstone.json
|
||||
3d5c71d1f24ebcc65db48765b56db60d64673a0d assets/bloodmagic/models/item/mimic.json
|
||||
7596826c5b40c2809eb0a42eb5f5f2089290e3e5 assets/bloodmagic/models/item/miningsigil.json
|
||||
eaa0548775c3d5839b46d333af33f815dc6dd0fe assets/bloodmagic/models/item/obsidianbrickpath.json
|
||||
cf066d15baae650a383240a91240abd335bbb0e3 assets/bloodmagic/models/item/obsidiantilepath.json
|
||||
|
@ -431,11 +438,13 @@ b6732b30df9e946739a1913671a60f56090679f8 data/bloodmagic/loot_tables/blocks/dung
|
|||
6381473b6e0bc7c16b8214eb083f5069622b4dd1 data/bloodmagic/loot_tables/blocks/dungeon_tilespecial.json
|
||||
26e3f34021426def32602e5ae7755e4672878320 data/bloodmagic/loot_tables/blocks/duskritualstone.json
|
||||
26e3f34021426def32602e5ae7755e4672878320 data/bloodmagic/loot_tables/blocks/earthritualstone.json
|
||||
2f27b244e5b3459408e9519dde05dc70cbb03998 data/bloodmagic/loot_tables/blocks/ethereal_mimic.json
|
||||
26e3f34021426def32602e5ae7755e4672878320 data/bloodmagic/loot_tables/blocks/fireritualstone.json
|
||||
59dd54a876b7ccd0b6c90f409753c2af2d687f03 data/bloodmagic/loot_tables/blocks/incensealtar.json
|
||||
462a82b07e7fe3e479a2c072c73507686c339346 data/bloodmagic/loot_tables/blocks/largebloodstonebrick.json
|
||||
26e3f34021426def32602e5ae7755e4672878320 data/bloodmagic/loot_tables/blocks/lightritualstone.json
|
||||
72610188b4538d98ffcd015c2813d63d19889d5f data/bloodmagic/loot_tables/blocks/masterritualstone.json
|
||||
ce5bf03f0ee03205ef6a1b6f512cb5da23addc57 data/bloodmagic/loot_tables/blocks/mimic.json
|
||||
3892d33bbef90db50034b1358d4a9ee8b731bc8d data/bloodmagic/loot_tables/blocks/obsidianbrickpath.json
|
||||
3576b2f9d92ab5bdc456cb904905fb5c969e55f3 data/bloodmagic/loot_tables/blocks/obsidiantilepath.json
|
||||
95442c1bb740fab2eb8ee051f7184813f6023afa data/bloodmagic/loot_tables/blocks/orbcapacityrune.json
|
||||
|
@ -454,6 +463,7 @@ f748a5ba8838b50de0502f132fe2a65f4726dae6 data/bloodmagic/loot_tables/blocks/soul
|
|||
2c471cedf5e3e39610821766609646698d2b47e3 data/bloodmagic/loot_tables/blocks/woodtilepath.json
|
||||
9ab0aac56f75e7811f9641a6a20ff8d9dd78876a data/bloodmagic/loot_tables/blocks/wornstonebrickpath.json
|
||||
4a7395079f874ae08af94f64a8a00211a56e906a data/bloodmagic/loot_tables/blocks/wornstonetilepath.json
|
||||
c95cd70b7ca320e18618c07827add555984b0e45 data/bloodmagic/loot_tables/test.json
|
||||
2df19ff659705a5408ce0819a947764673404388 data/bloodmagic/recipes/alchemy_table.json
|
||||
a343604b5a75e1b3810df97d024813fb041cffb6 data/bloodmagic/recipes/alchemytable/basic_cutting_fluid.json
|
||||
f86432e8fef0d6e140e27f575063704b7e843d75 data/bloodmagic/recipes/alchemytable/bread.json
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "bloodmagic:block/etherealopaquemimic"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "bloodmagic:block/sentientmimic"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "bloodmagic:block/solidclearmimic"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "bloodmagic:block/solidlightmimic"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "bloodmagic:block/solidopaquemimic"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "bloodmagic:block/etherealopaquemimic"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "bloodmagic:block/solidopaquemimic"
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "bloodmagic:ethereal_mimic"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "bloodmagic:mimic"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"type": "minecraft:chest",
|
||||
"pools": [
|
||||
{
|
||||
"name": "test",
|
||||
"rolls": 1.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"weight": 10,
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:enchant_with_levels",
|
||||
"levels": 30,
|
||||
"treasure": true
|
||||
}
|
||||
],
|
||||
"name": "minecraft:book"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -6,6 +6,8 @@ import org.apache.logging.log4j.Logger;
|
|||
import com.google.gson.Gson;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.RenderTypeLookup;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
|
@ -14,6 +16,8 @@ import net.minecraft.item.crafting.IRecipeSerializer;
|
|||
import net.minecraft.potion.Effect;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.client.model.generators.ItemModelProvider;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
|
@ -35,6 +39,8 @@ import wayoftime.bloodmagic.api.impl.BloodMagicAPI;
|
|||
import wayoftime.bloodmagic.api.impl.BloodMagicCorePlugin;
|
||||
import wayoftime.bloodmagic.client.ClientEvents;
|
||||
import wayoftime.bloodmagic.client.hud.Elements;
|
||||
import wayoftime.bloodmagic.client.model.MimicColor;
|
||||
import wayoftime.bloodmagic.client.model.MimicModelLoader;
|
||||
import wayoftime.bloodmagic.common.block.BloodMagicBlocks;
|
||||
import wayoftime.bloodmagic.common.data.GeneratorBaseRecipes;
|
||||
import wayoftime.bloodmagic.common.data.GeneratorBlockStates;
|
||||
|
@ -63,6 +69,7 @@ import wayoftime.bloodmagic.tile.TileDemonCrystal;
|
|||
import wayoftime.bloodmagic.tile.TileDemonCrystallizer;
|
||||
import wayoftime.bloodmagic.tile.TileIncenseAltar;
|
||||
import wayoftime.bloodmagic.tile.TileMasterRitualStone;
|
||||
import wayoftime.bloodmagic.tile.TileMimic;
|
||||
import wayoftime.bloodmagic.tile.TileSoulForge;
|
||||
import wayoftime.bloodmagic.util.handler.event.GenericHandler;
|
||||
import wayoftime.bloodmagic.util.handler.event.WillHandler;
|
||||
|
@ -108,6 +115,7 @@ public class BloodMagic
|
|||
modBus.addListener(this::processIMC);
|
||||
// Register the doClientStuff method for modloading
|
||||
modBus.addListener(this::doClientStuff);
|
||||
modBus.addListener(this::loadModels);
|
||||
modBus.addListener(this::gatherData);
|
||||
|
||||
modBus.addGenericListener(Fluid.class, this::registerFluids);
|
||||
|
@ -174,6 +182,7 @@ public class BloodMagic
|
|||
event.getRegistry().register(TileEntityType.Builder.create(TileDemonCrucible::new, BloodMagicBlocks.DEMON_CRUCIBLE.get()).build(null).setRegistryName("demoncrucible"));
|
||||
event.getRegistry().register(TileEntityType.Builder.create(TileDemonCrystallizer::new, BloodMagicBlocks.DEMON_CRYSTALLIZER.get()).build(null).setRegistryName("demoncrystallizer"));
|
||||
event.getRegistry().register(TileEntityType.Builder.create(TileIncenseAltar::new, BloodMagicBlocks.INCENSE_ALTAR.get()).build(null).setRegistryName("incensealtar"));
|
||||
event.getRegistry().register(TileEntityType.Builder.create(TileMimic::new, BloodMagicBlocks.MIMIC.get(), BloodMagicBlocks.ETHEREAL_MIMIC.get()).build(null).setRegistryName("mimic"));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -200,6 +209,12 @@ public class BloodMagic
|
|||
}
|
||||
}
|
||||
|
||||
private void loadModels(final ModelRegistryEvent event)
|
||||
{
|
||||
ModelLoaderRegistry.registerLoader(BloodMagic.rl("mimicloader"), new MimicModelLoader(BloodMagic.rl("block/solidopaquemimic")));
|
||||
ModelLoaderRegistry.registerLoader(BloodMagic.rl("mimicloader_ethereal"), new MimicModelLoader(BloodMagic.rl("block/etherealopaquemimic")));
|
||||
}
|
||||
|
||||
private void setup(final FMLCommonSetupEvent event)
|
||||
{
|
||||
// some preinit code
|
||||
|
@ -215,6 +230,8 @@ public class BloodMagic
|
|||
|
||||
ClientEvents.initClientEvents(event);
|
||||
Elements.registerElements();
|
||||
Minecraft.getInstance().getBlockColors().register(new MimicColor(), BloodMagicBlocks.MIMIC.get());
|
||||
RenderTypeLookup.setRenderLayer(BloodMagicBlocks.MIMIC.get(), (RenderType) -> true);
|
||||
}
|
||||
|
||||
private void enqueueIMC(final InterModEnqueueEvent event)
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
package wayoftime.bloodmagic.client.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.RenderTypeLookup;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
|
||||
import wayoftime.bloodmagic.common.block.BlockMimic;
|
||||
import wayoftime.bloodmagic.tile.TileMimic;
|
||||
|
||||
public class MimicBakedModel implements IDynamicBakedModel
|
||||
{
|
||||
public final ResourceLocation texture;
|
||||
|
||||
public MimicBakedModel(ResourceLocation texture)
|
||||
{
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
private TextureAtlasSprite getTexture()
|
||||
{
|
||||
return Minecraft.getInstance().getAtlasSpriteGetter(AtlasTexture.LOCATION_BLOCKS_TEXTURE).apply(texture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSideLit()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private void putVertex(BakedQuadBuilder builder, Vector3d normal, double x, double y, double z, float u, float v, TextureAtlasSprite sprite, float r, float g, float b)
|
||||
{
|
||||
ImmutableList<VertexFormatElement> elements = builder.getVertexFormat().getElements().asList();
|
||||
for (int j = 0; j < elements.size(); j++)
|
||||
{
|
||||
VertexFormatElement e = elements.get(j);
|
||||
switch (e.getUsage())
|
||||
{
|
||||
case POSITION:
|
||||
builder.put(j, (float) x, (float) y, (float) z, 1.0f);
|
||||
break;
|
||||
case COLOR:
|
||||
builder.put(j, r, g, b, 1.0f);
|
||||
break;
|
||||
case UV:
|
||||
switch (e.getIndex())
|
||||
{
|
||||
case 0:
|
||||
float iu = sprite.getInterpolatedU(u);
|
||||
float iv = sprite.getInterpolatedV(v);
|
||||
builder.put(j, iu, iv);
|
||||
break;
|
||||
case 2:
|
||||
builder.put(j, (short) 0, (short) 0);
|
||||
break;
|
||||
default:
|
||||
builder.put(j);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NORMAL:
|
||||
builder.put(j, (float) normal.x, (float) normal.y, (float) normal.z);
|
||||
break;
|
||||
default:
|
||||
builder.put(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BakedQuad createQuad(Vector3d v1, Vector3d v2, Vector3d v3, Vector3d v4, TextureAtlasSprite sprite)
|
||||
{
|
||||
Vector3d normal = v3.subtract(v2).crossProduct(v1.subtract(v2)).normalize();
|
||||
int tw = sprite.getWidth();
|
||||
int th = sprite.getHeight();
|
||||
|
||||
BakedQuadBuilder builder = new BakedQuadBuilder(sprite);
|
||||
builder.setQuadOrientation(Direction.getFacingFromVector(normal.x, normal.y, normal.z));
|
||||
putVertex(builder, normal, v1.x, v1.y, v1.z, 0, 0, sprite, 1.0f, 1.0f, 1.0f);
|
||||
putVertex(builder, normal, v2.x, v2.y, v2.z, 0, th, sprite, 1.0f, 1.0f, 1.0f);
|
||||
putVertex(builder, normal, v3.x, v3.y, v3.z, tw, th, sprite, 1.0f, 1.0f, 1.0f);
|
||||
putVertex(builder, normal, v4.x, v4.y, v4.z, tw, 0, sprite, 1.0f, 1.0f, 1.0f);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static Vector3d v(double x, double y, double z)
|
||||
{
|
||||
return new Vector3d(x, y, z);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData)
|
||||
{
|
||||
RenderType layer = MinecraftForgeClient.getRenderLayer();
|
||||
|
||||
BlockState mimic = extraData.getData(TileMimic.MIMIC);
|
||||
if (mimic != null && !(mimic.getBlock() instanceof BlockMimic))
|
||||
{
|
||||
if (layer == null || RenderTypeLookup.canRenderInLayer(mimic, layer))
|
||||
{
|
||||
IBakedModel model = Minecraft.getInstance().getBlockRendererDispatcher().getBlockModelShapes().getModel(mimic);
|
||||
try
|
||||
{
|
||||
return model.getQuads(mimic, side, rand, EmptyModelData.INSTANCE);
|
||||
} catch (Exception e)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (side != null || (layer != null && !layer.equals(RenderType.getSolid())))
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
TextureAtlasSprite texture = getTexture();
|
||||
List<BakedQuad> quads = new ArrayList<>();
|
||||
double l = 0;
|
||||
double r = 1;
|
||||
// double l = .2;
|
||||
// double r = 1 - .2;
|
||||
quads.add(createQuad(v(l, r, l), v(l, r, r), v(r, r, r), v(r, r, l), texture));
|
||||
quads.add(createQuad(v(l, l, l), v(r, l, l), v(r, l, r), v(l, l, r), texture));
|
||||
quads.add(createQuad(v(r, r, r), v(r, l, r), v(r, l, l), v(r, r, l), texture));
|
||||
quads.add(createQuad(v(l, r, l), v(l, l, l), v(l, l, r), v(l, r, r), texture));
|
||||
quads.add(createQuad(v(r, r, l), v(r, l, l), v(l, l, l), v(l, r, l), texture));
|
||||
quads.add(createQuad(v(l, r, r), v(l, l, r), v(r, l, r), v(r, r, r), texture));
|
||||
|
||||
return quads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return getTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return ItemOverrideList.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return ItemCameraTransforms.DEFAULT;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package wayoftime.bloodmagic.client.model;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.color.IBlockColor;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockDisplayReader;
|
||||
import wayoftime.bloodmagic.tile.TileMimic;
|
||||
|
||||
public class MimicColor implements IBlockColor
|
||||
{
|
||||
@Override
|
||||
public int getColor(BlockState blockState, @Nullable IBlockDisplayReader world, @Nullable BlockPos pos, int tint)
|
||||
{
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
if (te instanceof TileMimic)
|
||||
{
|
||||
TileMimic fancy = (TileMimic) te;
|
||||
BlockState mimic = fancy.getMimic();
|
||||
if (mimic != null)
|
||||
{
|
||||
return Minecraft.getInstance().getBlockColors().getColor(mimic, world, pos, tint);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package wayoftime.bloodmagic.client.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.IModelTransform;
|
||||
import net.minecraft.client.renderer.model.IUnbakedModel;
|
||||
import net.minecraft.client.renderer.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.model.ModelBakery;
|
||||
import net.minecraft.client.renderer.model.RenderMaterial;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModelConfiguration;
|
||||
import net.minecraftforge.client.model.geometry.IModelGeometry;
|
||||
|
||||
public class MimicModelGeometry implements IModelGeometry<MimicModelGeometry>
|
||||
{
|
||||
public final ResourceLocation texture;
|
||||
|
||||
public MimicModelGeometry(ResourceLocation texture)
|
||||
{
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, java.util.function.Function<RenderMaterial, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation)
|
||||
{
|
||||
return new MimicBakedModel(texture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<RenderMaterial> getTextures(IModelConfiguration owner, java.util.function.Function<ResourceLocation, IUnbakedModel> modelGetter, Set<com.mojang.datafixers.util.Pair<String, String>> missingTextureErrors)
|
||||
{
|
||||
return Collections.singletonList(new RenderMaterial(AtlasTexture.LOCATION_BLOCKS_TEXTURE, texture));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package wayoftime.bloodmagic.client.model;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModelLoader;
|
||||
|
||||
public class MimicModelLoader implements IModelLoader<MimicModelGeometry>
|
||||
{
|
||||
public final ResourceLocation texture;
|
||||
|
||||
public MimicModelLoader(ResourceLocation texture)
|
||||
{
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager resourceManager)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public MimicModelGeometry read(JsonDeserializationContext deserializationContext, JsonObject modelContents)
|
||||
{
|
||||
return new MimicModelGeometry(texture);
|
||||
}
|
||||
}
|
133
src/main/java/wayoftime/bloodmagic/common/block/BlockMimic.java
Normal file
133
src/main/java/wayoftime/bloodmagic/common/block/BlockMimic.java
Normal file
|
@ -0,0 +1,133 @@
|
|||
package wayoftime.bloodmagic.common.block;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import wayoftime.bloodmagic.tile.TileMimic;
|
||||
|
||||
public class BlockMimic extends Block
|
||||
{
|
||||
private static final VoxelShape SHAPE = VoxelShapes.create(0.01, 0, 0.01, 0.99, 1, 0.99);
|
||||
|
||||
public BlockMimic(Properties prop)
|
||||
{
|
||||
super(prop);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void addInformation(ItemStack stack, @Nullable IBlockReader reader, List<ITextComponent> list, ITooltipFlag flags)
|
||||
// {
|
||||
// list.add(new TranslationTextComponent("message.fancyblock"));
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public int getLightValue(BlockState state, IBlockReader world, BlockPos pos)
|
||||
// {
|
||||
// TileEntity te = world.getTileEntity(pos);
|
||||
// if (te instanceof TileMimic)
|
||||
// {
|
||||
// BlockState mimic = ((TileMimic) te).getMimic();
|
||||
// if (mimic != null && !(mimic.getBlock() instanceof BlockMimic))
|
||||
// {
|
||||
// return mimic.getLightValue(world, pos);
|
||||
// }
|
||||
// }
|
||||
// return super.getLightValue(state, world, pos);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext context)
|
||||
{
|
||||
TileEntity te = reader.getTileEntity(pos);
|
||||
if (te instanceof TileMimic)
|
||||
{
|
||||
BlockState mimic = ((TileMimic) te).getMimic();
|
||||
if (mimic != null && !(mimic.getBlock() instanceof BlockMimic))
|
||||
{
|
||||
return mimic.getShape(reader, pos, context);
|
||||
}
|
||||
}
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world)
|
||||
{
|
||||
return new TileMimic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult trace)
|
||||
{
|
||||
TileMimic mimic = (TileMimic) world.getTileEntity(pos);
|
||||
|
||||
return (mimic != null && mimic.onBlockActivated(world, pos, state, player, hand, player.getHeldItem(hand), trace.getFace()))
|
||||
? ActionResultType.SUCCESS
|
||||
: ActionResultType.FAIL;
|
||||
// ItemStack item = player.getHeldItem(hand);
|
||||
// if (!item.isEmpty() && item.getItem() instanceof BlockItem)
|
||||
// {
|
||||
// if (!world.isRemote)
|
||||
// {
|
||||
// TileEntity te = world.getTileEntity(pos);
|
||||
// if (te instanceof TileMimic)
|
||||
// {
|
||||
// BlockState mimicState = ((BlockItem) item.getItem()).getBlock().getDefaultState();
|
||||
// ((TileMimic) te).setMimic(mimicState);
|
||||
// }
|
||||
// }
|
||||
// return ActionResultType.SUCCESS;
|
||||
// }
|
||||
// return super.onBlockActivated(state, world, pos, player, hand, trace);
|
||||
}
|
||||
|
||||
// public boolean canMimicBlock(World world, BlockPos pos, BlockState state)
|
||||
// {
|
||||
// return state.getBlock()
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void onPlayerDestroy(IWorld world, BlockPos blockPos, BlockState blockState)
|
||||
{
|
||||
TileMimic altar = (TileMimic) world.getTileEntity(blockPos);
|
||||
if (altar != null)
|
||||
altar.dropItems();
|
||||
|
||||
super.onPlayerDestroy(world, blockPos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving)
|
||||
{
|
||||
if (!state.isIn(newState.getBlock()))
|
||||
{
|
||||
TileEntity tileentity = worldIn.getTileEntity(pos);
|
||||
if (tileentity instanceof TileMimic)
|
||||
{
|
||||
((TileMimic) tileentity).dropItems();
|
||||
}
|
||||
|
||||
super.onReplaced(state, worldIn, pos, newState, isMoving);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package wayoftime.bloodmagic.common.block;
|
|||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.AbstractBlock.Properties;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FenceGateBlock;
|
||||
import net.minecraft.block.FlowingFluidBlock;
|
||||
import net.minecraft.block.RotatedPillarBlock;
|
||||
|
@ -17,6 +18,8 @@ import net.minecraft.item.BucketItem;
|
|||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
import net.minecraftforge.common.extensions.IForgeContainerType;
|
||||
import net.minecraftforge.fluids.FluidAttributes;
|
||||
|
@ -98,6 +101,9 @@ public class BloodMagicBlocks
|
|||
public static final RegistryObject<Block> OBSIDIAN_PATH = BASICBLOCKS.register("obsidianbrickpath", () -> new BlockPath(8, AbstractBlock.Properties.create(Material.ROCK).hardnessAndResistance(2.0F, 5.0F).harvestTool(ToolType.PICKAXE).harvestLevel(3)));
|
||||
public static final RegistryObject<Block> OBSIDIAN_TILE_PATH = BASICBLOCKS.register("obsidiantilepath", () -> new BlockPath(8, AbstractBlock.Properties.create(Material.ROCK).hardnessAndResistance(2.0F, 5.0F).harvestTool(ToolType.PICKAXE).harvestLevel(3)));
|
||||
|
||||
public static final RegistryObject<Block> MIMIC = BLOCKS.register("mimic", () -> new BlockMimic(Properties.create(Material.IRON).sound(SoundType.METAL).hardnessAndResistance(2.0f).setOpaque(BloodMagicBlocks::isntSolid).setSuffocates(BloodMagicBlocks::isntSolid).setBlocksVision(BloodMagicBlocks::isntSolid).notSolid()));
|
||||
public static final RegistryObject<Block> ETHEREAL_MIMIC = BLOCKS.register("ethereal_mimic", () -> new BlockMimic(Properties.create(Material.IRON).sound(SoundType.METAL).hardnessAndResistance(2.0f).setOpaque(BloodMagicBlocks::isntSolid).setSuffocates(BloodMagicBlocks::isntSolid).setBlocksVision(BloodMagicBlocks::isntSolid).notSolid().doesNotBlockMovement()));
|
||||
|
||||
private static ForgeFlowingFluid.Properties makeProperties()
|
||||
{
|
||||
return new ForgeFlowingFluid.Properties(LIFE_ESSENCE_FLUID, LIFE_ESSENCE_FLUID_FLOWING, FluidAttributes.builder(FLUID_STILL, FLUID_FLOWING)).bucket(LIFE_ESSENCE_BUCKET).block(LIFE_ESSENCE_BLOCK);
|
||||
|
@ -142,6 +148,10 @@ public class BloodMagicBlocks
|
|||
public static final RegistryObject<Block> DUNGEON_BRICK_GATE = BLOCKS.register("dungeon_brick_gate", () -> new FenceGateBlock(Properties.create(Material.ROCK).hardnessAndResistance(2.0F, 5.0F).sound(SoundType.STONE).harvestTool(ToolType.PICKAXE).harvestLevel(2).setRequiresTool()));
|
||||
public static final RegistryObject<Block> DUNGEON_POLISHED_GATE = BLOCKS.register("dungeon_polished_gate", () -> new FenceGateBlock(Properties.create(Material.ROCK).hardnessAndResistance(2.0F, 5.0F).sound(SoundType.STONE).harvestTool(ToolType.PICKAXE).harvestLevel(2).setRequiresTool()));
|
||||
|
||||
private static boolean isntSolid(BlockState state, IBlockReader reader, BlockPos pos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//
|
||||
//// private static <T extends Block> RegistryObject<T> register(String name, Supplier<? extends T> sup, Function<RegistryObject<T>, Supplier<? extends Item>> itemCreator)
|
||||
//// {
|
||||
|
|
|
@ -79,6 +79,22 @@ public class GeneratorBlockStates extends BlockStateProvider
|
|||
buildPillarCap(BloodMagicBlocks.DUNGEON_PILLAR_CAP.get(), BloodMagic.rl("block/dungeon/dungeon_pillarheart"), BloodMagic.rl("block/dungeon/dungeon_pillarbottom"), BloodMagic.rl("block/dungeon/dungeon_pillartop"));
|
||||
|
||||
buildAssortedBlock(BloodMagicBlocks.DUNGEON_BRICK_ASSORTED.get(), modLoc("dungeon_brick1"), modLoc("dungeon_brick2"), modLoc("dungeon_brick3"));
|
||||
|
||||
buildCubeAllWithTextureName("etherealopaquemimic");
|
||||
buildCubeAllWithTextureName("sentientmimic");
|
||||
buildCubeAllWithTextureName("solidclearmimic");
|
||||
buildCubeAllWithTextureName("solidlightmimic");
|
||||
buildCubeAllWithTextureName("solidopaquemimic");
|
||||
}
|
||||
|
||||
// private void buildCustomLoader(Block block)
|
||||
// {
|
||||
// ModelFile modelFile = models().crop("", null);
|
||||
// }
|
||||
|
||||
private void buildCubeAllWithTextureName(String texture)
|
||||
{
|
||||
models().cubeAll(texture, BloodMagic.rl("block/" + texture)).assertExistence();
|
||||
}
|
||||
|
||||
private void buildAssortedBlock(Block block, ResourceLocation... modelResources)
|
||||
|
|
|
@ -82,6 +82,14 @@ public class GeneratorItemModels extends ItemModelProvider
|
|||
registerDemonTool(BloodMagicItems.SENTIENT_SHOVEL.get());
|
||||
registerSacrificialKnife(BloodMagicItems.SACRIFICIAL_DAGGER.get());
|
||||
|
||||
registerCustomFullTexture(BloodMagicBlocks.MIMIC.get(), "solidopaquemimic");
|
||||
registerCustomFullTexture(BloodMagicBlocks.ETHEREAL_MIMIC.get(), "etherealopaquemimic");
|
||||
}
|
||||
|
||||
private void registerCustomFullTexture(Block block, String texturePath)
|
||||
{
|
||||
String path = block.getRegistryName().getPath();
|
||||
getBuilder(path).parent(new ModelFile.UncheckedModelFile(modLoc("block/" + texturePath)));
|
||||
}
|
||||
|
||||
private void registerCustomBlockPath(Block block, String newPath)
|
||||
|
|
|
@ -15,7 +15,9 @@ import net.minecraft.block.Block;
|
|||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.LootTableProvider;
|
||||
import net.minecraft.data.loot.BlockLootTables;
|
||||
import net.minecraft.data.loot.ChestLootTables;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.loot.ConstantRange;
|
||||
import net.minecraft.loot.ItemLootEntry;
|
||||
import net.minecraft.loot.LootParameterSet;
|
||||
|
@ -26,6 +28,7 @@ import net.minecraft.loot.LootTableManager;
|
|||
import net.minecraft.loot.ValidationTracker;
|
||||
import net.minecraft.loot.conditions.BlockStateProperty;
|
||||
import net.minecraft.loot.conditions.ILootCondition;
|
||||
import net.minecraft.loot.functions.EnchantWithLevels;
|
||||
import net.minecraft.loot.functions.SetCount;
|
||||
import net.minecraft.state.Property;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
|
@ -47,7 +50,27 @@ public class GeneratorLootTable extends LootTableProvider
|
|||
@Override
|
||||
protected List<Pair<Supplier<Consumer<BiConsumer<ResourceLocation, LootTable.Builder>>>, LootParameterSet>> getTables()
|
||||
{
|
||||
return ImmutableList.of(Pair.of(BMBlocks::new, LootParameterSets.BLOCK));
|
||||
return ImmutableList.of(Pair.of(BMBlocks::new, LootParameterSets.BLOCK), Pair.of(BMLootTables::new, LootParameterSets.CHEST));
|
||||
}
|
||||
|
||||
private static class BMLootTables extends ChestLootTables
|
||||
{
|
||||
@Override
|
||||
public void accept(BiConsumer<ResourceLocation, LootTable.Builder> acceptor)
|
||||
{
|
||||
acceptor.accept(BloodMagic.rl("test"), testLootTableGeneration());
|
||||
}
|
||||
|
||||
private LootTable.Builder testLootTableGeneration()
|
||||
{
|
||||
LootTable.Builder table = LootTable.builder();
|
||||
LootPool.Builder pool = LootPool.builder().name("test").addEntry(ItemLootEntry.builder(Items.BOOK).weight(10).acceptFunction(EnchantWithLevels.func_215895_a(ConstantRange.of(30)).func_216059_e()));
|
||||
|
||||
table.addLootPool(pool);
|
||||
// table.build();
|
||||
|
||||
return table;
|
||||
}
|
||||
}
|
||||
|
||||
private static class BMBlocks extends BlockLootTables
|
||||
|
@ -100,6 +123,10 @@ public class GeneratorLootTable extends LootTableProvider
|
|||
registerDropSelfLootTable(BloodMagicBlocks.DUNGEON_POLISHED_WALL.get());
|
||||
registerDropSelfLootTable(BloodMagicBlocks.DUNGEON_BRICK_GATE.get());
|
||||
registerDropSelfLootTable(BloodMagicBlocks.DUNGEON_POLISHED_GATE.get());
|
||||
|
||||
registerDropSelfLootTable(BloodMagicBlocks.MIMIC.get());
|
||||
registerDropSelfLootTable(BloodMagicBlocks.ETHEREAL_MIMIC.get());
|
||||
|
||||
}
|
||||
|
||||
private void registerNoDropLootTable(Block block)
|
||||
|
|
|
@ -10,6 +10,7 @@ import wayoftime.bloodmagic.BloodMagic;
|
|||
import wayoftime.bloodmagic.common.block.BloodMagicBlocks;
|
||||
import wayoftime.bloodmagic.common.item.arc.ItemARCToolBase;
|
||||
import wayoftime.bloodmagic.common.item.block.ItemBlockAlchemyTable;
|
||||
import wayoftime.bloodmagic.common.item.block.ItemBlockMimic;
|
||||
import wayoftime.bloodmagic.common.item.sigil.ItemSigilAir;
|
||||
import wayoftime.bloodmagic.common.item.sigil.ItemSigilBloodLight;
|
||||
import wayoftime.bloodmagic.common.item.sigil.ItemSigilDivination;
|
||||
|
@ -90,6 +91,9 @@ public class BloodMagicItems
|
|||
public static final RegistryObject<Item> OBSIDIAN_PATH_ITEM = ITEMS.register("obsidianbrickpath", () -> new BlockItem(BloodMagicBlocks.OBSIDIAN_PATH.get(), new Item.Properties().group(BloodMagic.TAB)));
|
||||
public static final RegistryObject<Item> OBSIDIAN_TILE_PATH_ITEM = ITEMS.register("obsidiantilepath", () -> new BlockItem(BloodMagicBlocks.OBSIDIAN_TILE_PATH.get(), new Item.Properties().group(BloodMagic.TAB)));
|
||||
|
||||
public static final RegistryObject<Item> MIMIC_ITEM = ITEMS.register("mimic", () -> new ItemBlockMimic(BloodMagicBlocks.MIMIC.get(), new Item.Properties().group(BloodMagic.TAB)));
|
||||
public static final RegistryObject<Item> MIMIC_ETHEREAL_ITEM = ITEMS.register("ethereal_mimic", () -> new ItemBlockMimic(BloodMagicBlocks.ETHEREAL_MIMIC.get(), new Item.Properties().group(BloodMagic.TAB)));
|
||||
|
||||
// TODO: Need to rework the above instantiations for the ItemBlocks so that it's
|
||||
// done with the Blocks.
|
||||
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
package wayoftime.bloodmagic.common.item.block;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.ChestTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import wayoftime.bloodmagic.tile.TileMimic;
|
||||
|
||||
public class ItemBlockMimic extends BlockItem
|
||||
{
|
||||
public ItemBlockMimic(Block block, Properties prop)
|
||||
{
|
||||
super(block, prop);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType tryPlace(BlockItemUseContext context)
|
||||
{
|
||||
PlayerEntity player = context.getPlayer();
|
||||
ItemStack stack = player.getHeldItem(context.getHand());
|
||||
|
||||
// If not sneaking, do normal item use
|
||||
if (!player.isSneaking())
|
||||
{
|
||||
return super.tryPlace(context);
|
||||
}
|
||||
|
||||
BlockPos pos = context.getPos().offset(context.getFace().getOpposite());
|
||||
World world = context.getWorld();
|
||||
Direction direction = context.getFace();
|
||||
|
||||
// IF sneaking and player has permission, replace the targeted block
|
||||
if (player.canPlayerEdit(pos, direction, stack))
|
||||
{
|
||||
// Store information about the block being replaced and its appropriate
|
||||
// itemstack
|
||||
BlockState replacedBlockstate = world.getBlockState(pos);
|
||||
Block replacedBlock = replacedBlockstate.getBlock();
|
||||
ItemStack replacedStack = replacedBlock.getItem(world, pos, replacedBlockstate);
|
||||
|
||||
// Get the state for the mimic
|
||||
BlockState mimicBlockstate = this.getBlock().getDefaultState();
|
||||
|
||||
// Check if the block can be replaced
|
||||
|
||||
if (!canReplaceBlock(world, pos, replacedBlockstate))
|
||||
{
|
||||
return super.tryPlace(context);
|
||||
}
|
||||
|
||||
// Check if the tile entity, if any, can be replaced
|
||||
TileEntity tileReplaced = world.getTileEntity(pos);
|
||||
if (!canReplaceTile(tileReplaced))
|
||||
{
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
|
||||
// If tile can be replaced, store info about the tile
|
||||
CompoundNBT tileTag = getTagFromTileEntity(tileReplaced);
|
||||
if (tileReplaced != null)
|
||||
{
|
||||
CompoundNBT voidTag = new CompoundNBT();
|
||||
voidTag.putInt("x", pos.getX());
|
||||
voidTag.putInt("y", pos.getY());
|
||||
voidTag.putInt("z", pos.getZ());
|
||||
tileReplaced.deserializeNBT(voidTag);
|
||||
}
|
||||
|
||||
// Remove one item from stack
|
||||
stack.shrink(1);
|
||||
|
||||
// Replace the block
|
||||
world.setBlockState(pos, mimicBlockstate, 3);
|
||||
// Make placing sound
|
||||
SoundType soundtype = mimicBlockstate.getSoundType(world, pos, context.getPlayer());
|
||||
world.playSound(player, pos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F);
|
||||
|
||||
// Replace the tile entity
|
||||
TileEntity tile = world.getTileEntity(pos);
|
||||
if (tile instanceof TileMimic)
|
||||
{
|
||||
TileMimic mimic = (TileMimic) tile;
|
||||
mimic.tileTag = tileTag;
|
||||
// mimic.setReplacedState(replacedBlockstate);
|
||||
mimic.setMimic(replacedBlockstate);
|
||||
mimic.setInventorySlotContents(0, replacedStack);
|
||||
mimic.refreshTileEntity();
|
||||
|
||||
if (player.isCreative())
|
||||
{
|
||||
mimic.dropItemsOnBreak = false;
|
||||
}
|
||||
}
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
}
|
||||
|
||||
public boolean canReplaceTile(TileEntity tile)
|
||||
{
|
||||
if (tile instanceof ChestTileEntity)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return tile == null;
|
||||
}
|
||||
|
||||
public boolean canReplaceBlock(World world, BlockPos pos, BlockState state)
|
||||
{
|
||||
return state.getBlockHardness(world, pos) != -1.0F;
|
||||
}
|
||||
|
||||
public CompoundNBT getTagFromTileEntity(TileEntity tile)
|
||||
{
|
||||
CompoundNBT tag = new CompoundNBT();
|
||||
|
||||
if (tile != null)
|
||||
{
|
||||
return tile.write(tag);
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
}
|
|
@ -44,6 +44,8 @@ public class Dungeon
|
|||
settings.setIgnoreEntities(true);
|
||||
settings.setChunk(null);
|
||||
|
||||
settings.addProcessor(new StoneToOreProcessor(0.2f));
|
||||
|
||||
// settings.setReplacedBlock(null);
|
||||
|
||||
// settings.setIgnoreStructureBlock(false);
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package wayoftime.bloodmagic.structures;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.gen.feature.template.IStructureProcessorType;
|
||||
import net.minecraft.world.gen.feature.template.PlacementSettings;
|
||||
import net.minecraft.world.gen.feature.template.StructureProcessor;
|
||||
import net.minecraft.world.gen.feature.template.Template;
|
||||
import wayoftime.bloodmagic.common.block.BloodMagicBlocks;
|
||||
|
||||
public class StoneToOreProcessor extends StructureProcessor
|
||||
{
|
||||
public static final Codec<StoneToOreProcessor> field_237077_a_ = Codec.FLOAT.fieldOf("integrity").orElse(1.0F).xmap(StoneToOreProcessor::new, (p_237078_0_) -> {
|
||||
return p_237078_0_.integrity;
|
||||
}).codec();
|
||||
private final float integrity;
|
||||
|
||||
public StoneToOreProcessor(float integrity)
|
||||
{
|
||||
this.integrity = integrity;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Template.BlockInfo func_230386_a_(IWorldReader p_230386_1_, BlockPos p_230386_2_, BlockPos p_230386_3_, Template.BlockInfo p_230386_4_, Template.BlockInfo p_230386_5_, PlacementSettings p_230386_6_)
|
||||
{
|
||||
if (p_230386_5_.state.getBlock() != BloodMagicBlocks.DUNGEON_STONE.get())
|
||||
{
|
||||
return p_230386_5_;
|
||||
}
|
||||
Random random = p_230386_6_.getRandom(p_230386_5_.pos);
|
||||
return !(this.integrity >= 1.0F) && !(random.nextFloat() <= this.integrity)
|
||||
? new Template.BlockInfo(p_230386_5_.pos, BloodMagicBlocks.DUNGEON_ORE.get().getDefaultState(), p_230386_5_.nbt)
|
||||
: p_230386_5_;
|
||||
}
|
||||
|
||||
protected IStructureProcessorType<?> getType()
|
||||
{
|
||||
return IStructureProcessorType.BLOCK_ROT;
|
||||
}
|
||||
}
|
357
src/main/java/wayoftime/bloodmagic/tile/TileMimic.java
Normal file
357
src/main/java/wayoftime/bloodmagic/tile/TileMimic.java
Normal file
|
@ -0,0 +1,357 @@
|
|||
package wayoftime.bloodmagic.tile;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.InventoryHelper;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.potion.PotionUtils;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.ModelDataManager;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.registries.ObjectHolder;
|
||||
import wayoftime.bloodmagic.common.block.BloodMagicBlocks;
|
||||
import wayoftime.bloodmagic.util.ChatUtil;
|
||||
import wayoftime.bloodmagic.util.Utils;
|
||||
|
||||
public class TileMimic extends TileInventory
|
||||
{
|
||||
@ObjectHolder("bloodmagic:mimic")
|
||||
public static TileEntityType<TileMimic> TYPE;
|
||||
|
||||
public static final ModelProperty<BlockState> MIMIC = new ModelProperty<>();
|
||||
|
||||
private BlockState mimic;
|
||||
|
||||
public boolean dropItemsOnBreak = true;
|
||||
public CompoundNBT tileTag = new CompoundNBT();
|
||||
public TileEntity mimicedTile = null;
|
||||
|
||||
public int playerCheckRadius = 5;
|
||||
public int potionSpawnRadius = 5;
|
||||
public int potionSpawnInterval = 40;
|
||||
|
||||
private int internalCounter = 0;
|
||||
|
||||
public TileMimic(TileEntityType<?> type)
|
||||
{
|
||||
super(type, 2, "mimic");
|
||||
}
|
||||
|
||||
public TileMimic()
|
||||
{
|
||||
this(TYPE);
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World world, BlockPos pos, BlockState state, PlayerEntity player, Hand hand, ItemStack heldItem, Direction side)
|
||||
{
|
||||
if (!heldItem.isEmpty() && player.isCreative())
|
||||
{
|
||||
List<EffectInstance> list = PotionUtils.getEffectsFromStack(heldItem);
|
||||
if (!list.isEmpty())
|
||||
{
|
||||
if (!world.isRemote)
|
||||
{
|
||||
setInventorySlotContents(1, heldItem.copy());
|
||||
world.notifyBlockUpdate(pos, state, state, 3);
|
||||
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionSet"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// } else if (heldItem.getItem() == RegistrarBloodMagicItems.POTION_FLASK)
|
||||
// {
|
||||
// // The potion flask is empty, therefore we have to reset the stored potion.
|
||||
// if (!world.isRemote)
|
||||
// {
|
||||
// setInventorySlotContents(1, ItemStack.EMPTY);
|
||||
// world.notifyBlockUpdate(pos, state, state, 3);
|
||||
// ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionRemove"));
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
}
|
||||
|
||||
if (performSpecialAbility(player, side))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player.isSneaking())
|
||||
return false;
|
||||
|
||||
if (!player.getHeldItem(hand).isEmpty() && player.getHeldItem(hand).getItem() == new ItemStack(BloodMagicBlocks.MIMIC.get()).getItem())
|
||||
return false;
|
||||
|
||||
if (!getStackInSlot(0).isEmpty() && !player.getHeldItem(hand).isEmpty())
|
||||
return false;
|
||||
|
||||
if (!dropItemsOnBreak && !player.isCreative())
|
||||
return false;
|
||||
|
||||
Utils.insertItemToTile(this, player, 0);
|
||||
ItemStack stack = getStackInSlot(0);
|
||||
if (mimic == null || mimic == Blocks.AIR.getDefaultState())
|
||||
{
|
||||
if (!stack.isEmpty() && stack.getItem() instanceof BlockItem && !world.isRemote)
|
||||
{
|
||||
Block block = ((BlockItem) stack.getItem()).getBlock();
|
||||
this.setMimic(block.getDefaultState());
|
||||
// mimic = block.getDefaultState();
|
||||
// markDirty();
|
||||
}
|
||||
}
|
||||
this.refreshTileEntity();
|
||||
|
||||
if (player.isCreative())
|
||||
{
|
||||
dropItemsOnBreak = getStackInSlot(0).isEmpty();
|
||||
}
|
||||
|
||||
// world.notifyBlockUpdate(pos, state, state, 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean performSpecialAbility(PlayerEntity player, Direction sideHit)
|
||||
{
|
||||
if (!player.isCreative())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player.getActiveItemStack().isEmpty() && !getStackInSlot(1).isEmpty())
|
||||
{
|
||||
switch (sideHit)
|
||||
{
|
||||
case EAST: // When the block is clicked on the EAST or WEST side, potionSpawnRadius is
|
||||
// edited.
|
||||
case WEST:
|
||||
if (player.isSneaking())
|
||||
{
|
||||
potionSpawnRadius = Math.max(potionSpawnRadius - 1, 0);
|
||||
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionSpawnRadius.down", potionSpawnRadius));
|
||||
} else
|
||||
{
|
||||
potionSpawnRadius++;
|
||||
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionSpawnRadius.up", potionSpawnRadius));
|
||||
}
|
||||
break;
|
||||
case NORTH: // When the block is clicked on the NORTH or SOUTH side, detectRadius is edited.
|
||||
case SOUTH:
|
||||
if (player.isSneaking())
|
||||
{
|
||||
playerCheckRadius = Math.max(playerCheckRadius - 1, 0);
|
||||
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.detectRadius.down", playerCheckRadius));
|
||||
} else
|
||||
{
|
||||
playerCheckRadius++;
|
||||
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.detectRadius.up", playerCheckRadius));
|
||||
}
|
||||
break;
|
||||
case UP: // When the block is clicked on the UP or DOWN side, potionSpawnInterval is
|
||||
// edited.
|
||||
case DOWN:
|
||||
if (player.isSneaking())
|
||||
{
|
||||
potionSpawnInterval = Math.max(potionSpawnInterval - 1, 1);
|
||||
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionInterval.down", potionSpawnInterval));
|
||||
} else
|
||||
{
|
||||
potionSpawnInterval++;
|
||||
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionInterval.up", potionSpawnInterval));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void refreshTileEntity()
|
||||
{
|
||||
if (mimicedTile != null)
|
||||
{
|
||||
dropMimicedTileInventory();
|
||||
}
|
||||
mimicedTile = getTileFromStackWithTag(getWorld(), pos, getStackInSlot(0), tileTag, mimic);
|
||||
}
|
||||
|
||||
public void dropMimicedTileInventory()
|
||||
{
|
||||
if (!getWorld().isRemote && mimicedTile instanceof IInventory)
|
||||
{
|
||||
InventoryHelper.dropInventoryItems(getWorld(), getPos(), (IInventory) mimicedTile);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TileEntity getTileFromStackWithTag(World world, BlockPos pos, ItemStack stack, @Nullable CompoundNBT tag, BlockState replacementState)
|
||||
{
|
||||
if (!stack.isEmpty() && stack.getItem() instanceof BlockItem)
|
||||
{
|
||||
Block block = ((BlockItem) stack.getItem()).getBlock();
|
||||
BlockState state = replacementState;
|
||||
if (block.hasTileEntity(state))
|
||||
{
|
||||
TileEntity tile = block.createTileEntity(state, world);
|
||||
|
||||
if (tile == null)
|
||||
return null;
|
||||
|
||||
if (tag != null)
|
||||
{
|
||||
CompoundNBT copyTag = tag.copy();
|
||||
copyTag.putInt("x", pos.getX());
|
||||
copyTag.putInt("y", pos.getY());
|
||||
copyTag.putInt("z", pos.getZ());
|
||||
tile.deserializeNBT(copyTag);
|
||||
}
|
||||
|
||||
tile.setWorldAndPos(world, pos);
|
||||
|
||||
return tile;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setMimic(BlockState mimic)
|
||||
{
|
||||
this.mimic = mimic;
|
||||
markDirty();
|
||||
world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), Constants.BlockFlags.BLOCK_UPDATE + Constants.BlockFlags.NOTIFY_NEIGHBORS);
|
||||
}
|
||||
|
||||
public BlockState getMimic()
|
||||
{
|
||||
return mimic;
|
||||
}
|
||||
|
||||
// The getUpdateTag()/handleUpdateTag() pair is called whenever the client
|
||||
// receives a new chunk
|
||||
// it hasn't seen before. i.e. the chunk is loaded
|
||||
|
||||
@Override
|
||||
public CompoundNBT getUpdateTag()
|
||||
{
|
||||
CompoundNBT tag = super.getUpdateTag();
|
||||
writeMimic(tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
// The getUpdatePacket()/onDataPacket() pair is used when a block update happens
|
||||
// on the client
|
||||
// (a blockstate change or an explicit notificiation of a block update from the
|
||||
// server). It's
|
||||
// easiest to implement them based on getUpdateTag()/handleUpdateTag()
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SUpdateTileEntityPacket getUpdatePacket()
|
||||
{
|
||||
return new SUpdateTileEntityPacket(pos, 1, getUpdateTag());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt)
|
||||
{
|
||||
BlockState oldMimic = mimic;
|
||||
CompoundNBT tag = pkt.getNbtCompound();
|
||||
deserialize(tag);
|
||||
if (!Objects.equals(oldMimic, mimic))
|
||||
{
|
||||
ModelDataManager.requestModelDataRefresh(this);
|
||||
world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), Constants.BlockFlags.BLOCK_UPDATE + Constants.BlockFlags.NOTIFY_NEIGHBORS);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IModelData getModelData()
|
||||
{
|
||||
return new ModelDataMap.Builder().withInitial(MIMIC, mimic).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserialize(CompoundNBT tag)
|
||||
{
|
||||
super.deserialize(tag);
|
||||
|
||||
dropItemsOnBreak = tag.getBoolean("dropItemsOnBreak");
|
||||
tileTag = tag.getCompound("tileTag");
|
||||
// stateOfReplacedBlock = StateUtil.parseState(tag.getString("stateOfReplacedBlock"));
|
||||
readMimic(tag);
|
||||
mimicedTile = getTileFromStackWithTag(getWorld(), pos, getStackInSlot(0), tileTag, mimic);
|
||||
playerCheckRadius = tag.getInt("playerCheckRadius");
|
||||
potionSpawnRadius = tag.getInt("potionSpawnRadius");
|
||||
potionSpawnInterval = Math.max(1, tag.getInt("potionSpawnInterval"));
|
||||
}
|
||||
|
||||
private void readMimic(CompoundNBT tag)
|
||||
{
|
||||
if (tag.contains("mimic"))
|
||||
{
|
||||
mimic = NBTUtil.readBlockState(tag.getCompound("mimic"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT serialize(CompoundNBT tag)
|
||||
{
|
||||
tag.putBoolean("dropItemsOnBreak", dropItemsOnBreak);
|
||||
tag.put("tileTag", tileTag);
|
||||
tag.putInt("playerCheckRadius", playerCheckRadius);
|
||||
tag.putInt("potionSpawnRadius", potionSpawnRadius);
|
||||
tag.putInt("potionSpawnInterval", potionSpawnInterval);
|
||||
// tag.putString("stateOfReplacedBlock", stateOfReplacedBlock.toString());
|
||||
writeMimic(tag);
|
||||
return super.serialize(tag);
|
||||
}
|
||||
|
||||
private void writeMimic(CompoundNBT tag)
|
||||
{
|
||||
if (mimic != null)
|
||||
{
|
||||
tag.put("mimic", NBTUtil.writeBlockState(mimic));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropItems()
|
||||
{
|
||||
if (dropItemsOnBreak)
|
||||
{
|
||||
InventoryHelper.dropInventoryItems(getWorld(), getPos(), this);
|
||||
}
|
||||
|
||||
dropMimicedTileInventory();
|
||||
}
|
||||
}
|
|
@ -105,7 +105,7 @@ public abstract class TileBase extends TileEntity
|
|||
// }
|
||||
|
||||
@Override
|
||||
public final SUpdateTileEntityPacket getUpdatePacket()
|
||||
public SUpdateTileEntityPacket getUpdatePacket()
|
||||
{
|
||||
return new SUpdateTileEntityPacket(getPos(), -999, getUpdateTag());
|
||||
}
|
||||
|
@ -118,20 +118,20 @@ public abstract class TileBase extends TileEntity
|
|||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt)
|
||||
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt)
|
||||
{
|
||||
super.onDataPacket(net, pkt);
|
||||
handleUpdateTag(getBlockState(), pkt.getNbtCompound());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CompoundNBT getUpdateTag()
|
||||
public CompoundNBT getUpdateTag()
|
||||
{
|
||||
return write(new CompoundNBT());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void handleUpdateTag(BlockState state, CompoundNBT tag)
|
||||
public void handleUpdateTag(BlockState state, CompoundNBT tag)
|
||||
{
|
||||
read(state, tag);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "bloodmagic:block/ethereal_mimic" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "bloodmagic:block/opaquemimic" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"loader": "bloodmagic:mimicloader_ethereal"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"loader": "bloodmagic:mimicloader"
|
||||
}
|
Loading…
Reference in a new issue