Я начал заниматься моддингом 3 дня назад, поэтому я тут не особо шарю.
Я перерыл уже наверное всё, что только можно было, смотрел на гитхабе другие моды как это делают, но у меня не работает ничего.
В общем, у меня есть стол, в который надо положить кристалл, и сверху на него бросить что-нибудь. Стол зачарует предмет (ну на самом деле удалит предыдущий и создаст новый предмет), потратив при этом один кристалл. При этом зачаровании создаётся звук и частицы.
Со звуком проблем нет, но вот частицы спавнятся странным образом. Частицы при зачаровании спавнятся только у тех, кто поставил этот стол или открыл его. Вот видео:
.
Если даже забыть про то, что я сейчас сказал, то я хочу узнать, как спавнить частицы (не только из TileEntity, а вообще отовсюду, где только можно их заспавнить), чтобы они были видны у всех клиентов на сервере.
Вот мой код для блока стола и для TileEntity стола. (PS - Я юзаю mcreator, гореть мне в аду, наверное)
Я перерыл уже наверное всё, что только можно было, смотрел на гитхабе другие моды как это делают, но у меня не работает ничего.
В общем, у меня есть стол, в который надо положить кристалл, и сверху на него бросить что-нибудь. Стол зачарует предмет (ну на самом деле удалит предыдущий и создаст новый предмет), потратив при этом один кристалл. При этом зачаровании создаётся звук и частицы.
Со звуком проблем нет, но вот частицы спавнятся странным образом. Частицы при зачаровании спавнятся только у тех, кто поставил этот стол или открыл его. Вот видео:
Если даже забыть про то, что я сейчас сказал, то я хочу узнать, как спавнить частицы (не только из TileEntity, а вообще отовсюду, где только можно их заспавнить), чтобы они были видны у всех клиентов на сервере.
Вот мой код для блока стола и для TileEntity стола. (PS - Я юзаю mcreator, гореть мне в аду, наверное)
BlockMagicEnhancer.java:
package net.mcreator.substance_and_mind.block;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraft.world.World;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.NonNullList;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.tileentity.TileEntityLockableLoot;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.network.NetworkManager;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.Item;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.inventory.Container;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.material.Material;
import net.minecraft.block.SoundType;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.Block;
import net.mcreator.substance_and_mind.gui.GuiMagicEnhancerGUI;
import net.mcreator.substance_and_mind.creativetab.TabSubstanceAndMindTab;
import net.mcreator.substance_and_mind.SubstanceMind;
import net.mcreator.substance_and_mind.ElementsSubstanceMind;
import net.mcreator.substance_and_mind.TileEntityMagicEnhancer;
@ElementsSubstanceMind.ModElement.Tag
public class BlockMagicEnhancer extends ElementsSubstanceMind.ModElement {
@GameRegistry.ObjectHolder("substance_and_mind:magicenhancer")
public static final Block block = null;
public BlockMagicEnhancer(ElementsSubstanceMind instance) {
super(instance, 3);
}
@Override
public void initElements() {
elements.blocks.add(() -> new BlockCustom().setRegistryName("magicenhancer"));
elements.items.add(() -> new ItemBlock(block).setRegistryName(block.getRegistryName()));
}
@Override
public void init(FMLInitializationEvent event) {
GameRegistry.registerTileEntity(TileEntityMagicEnhancer.class, "substance_and_mind:tileentitymagicenhancer");
}
@SideOnly(Side.CLIENT)
@Override
public void registerModels(ModelRegistryEvent event) {
ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0,
new ModelResourceLocation("substance_and_mind:magicenhancer", "inventory"));
}
public static class BlockCustom extends Block implements ITileEntityProvider {
public BlockCustom() {
super(Material.WOOD);
setUnlocalizedName("magicenhancer");
setSoundType(SoundType.WOOD);
setHardness(2F);
setResistance(10F);
setLightLevel(0F);
setLightOpacity(255);
setCreativeTab(TabSubstanceAndMindTab.tab);
}
@Override
public TileEntity createNewTileEntity(World worldIn, int meta) {
return new TileEntityMagicEnhancer();
}
@Override
public boolean eventReceived(IBlockState state, World worldIn, BlockPos pos, int eventID, int eventParam) {
super.eventReceived(state, worldIn, pos, eventID, eventParam);
TileEntity tileentity = worldIn.getTileEntity(pos);
return tileentity == null ? false : tileentity.receiveClientEvent(eventID, eventParam);
}
@Override
public EnumBlockRenderType getRenderType(IBlockState state) {
return EnumBlockRenderType.MODEL;
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
TileEntity tileentity = world.getTileEntity(pos);
if (tileentity instanceof TileEntityMagicEnhancer)
InventoryHelper.dropInventoryItems(world, pos, (TileEntityMagicEnhancer) tileentity);
world.removeTileEntity(pos);
super.breakBlock(world, pos, state);
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer entity, EnumHand hand, EnumFacing direction,
float hitX, float hitY, float hitZ) {
super.onBlockActivated(world, pos, state, entity, hand, direction, hitX, hitY, hitZ);
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
if (entity instanceof EntityPlayer) {
((EntityPlayer) entity).openGui(SubstanceMind.instance, GuiMagicEnhancerGUI.GUIID, world, x, y, z);
}
return true;
}
}
}
TileEntityMagicEnhancer.java:
package net.mcreator.substance_and_mind;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.World;
import net.mcreator.substance_and_mind.TileEntityUtil;
import java.util.Random;
import net.minecraft.util.ITickable;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntityLockableLoot;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Container;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.entity.player.EntityPlayer;
import net.mcreator.substance_and_mind.gui.GuiMagicEnhancerGUI.GuiContainerMod;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import javax.annotation.Nullable;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraft.util.NonNullList;
import net.mcreator.substance_and_mind.gui.GuiMagicEnhancerGUI;
import net.mcreator.substance_and_mind.item.*;
import net.mcreator.substance_and_mind.block.*;
import net.mcreator.substance_and_mind.SaMSoundHandler;
import net.mcreator.substance_and_mind.ResourcePath;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.util.math.AxisAlignedBB;
import java.util.List;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.item.ItemBook;
import net.minecraft.block.material.Material;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.util.SoundCategory;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.SoundEvent;
public class TileEntityMagicEnhancer extends TileEntityLockableLoot implements ITickable {
private NonNullList<ItemStack> stacks = NonNullList.<ItemStack>withSize(1, ItemStack.EMPTY);
public Item nowCrafting = null; //Предмет, который сейчас создаётся на столе
public Item craftingFrom = null;
public int craftingCount = 0;
public int craftCounter = 0;
@Override
public void update()
{
ItemStack stack = getStackInSlot(0); //Берется ItemStack в слоте 0
List<EntityItem> list = this.world.getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(getPos()).expand(0, 0.5, 0).contract(0, -1, 0)); //Берутся EntityItem над столом
if(!(nowCrafting == null)) //Если что-то крафтится
{
if (craftCounter >= 20)
{
craftItem(list, stack);
}
else
{
craftCounter += 1;
spawnProcessingParticles();
}
}
else //Если идет простой
{
if(list.isEmpty() == false && stack.getItem() == new ItemStack(ItemPowerGem.block, 1).getItem()) //Если на столе лежат предмет или предметы и внутри стола есть powergem или powergem'ы
{
for (int i = 0; i < list.size(); i++) //Проходится по всем предметам в ItemStack'е
{
if((list.get(i).getItem()).getItem() == new ItemStack(Items.STICK, 1).getItem()) //Крафт стержня ифрита из палки
{
nowCrafting = Items.BLAZE_ROD;
craftingFrom = Items.STICK;
craftingCount = 1;
playMagicEnhancerCraftingSound();
}
}
}
else //Если на столе ничего не лежит или нет powergem'ов
{
}
}
}
public void spawnEnhanceParticles()
{
for (int i = 0; i < 10; i++)
{
world.spawnParticle(EnumParticleTypes.CRIT_MAGIC,
getPos().getX() + 1F - world.rand.nextFloat(),
getPos().getY() + 1.5F + 0.5F - world.rand.nextFloat(),
getPos().getZ() + 1F - world.rand.nextFloat(),
(0.5F - world.rand.nextFloat())/10,
(0.5F - world.rand.nextFloat())/10,
(0.5F - world.rand.nextFloat()/10));
}
for (int i = 0; i < 5; i++)
{
world.spawnParticle(EnumParticleTypes.CLOUD,
getPos().getX() + 1F - world.rand.nextFloat(),
getPos().getY() + 1.5F + 0.5F - world.rand.nextFloat(),
getPos().getZ() + 1F - world.rand.nextFloat(),
(0.5F - world.rand.nextFloat())/8,
(1F - world.rand.nextFloat())/6,
(0.5F - world.rand.nextFloat())/8);
}
}
public void spawnProcessingParticles()
{
float rand = world.rand.nextFloat();
if (rand < 0.25)
{
world.spawnParticle(EnumParticleTypes.END_ROD,
getPos().getX() + 1.0f - world.rand.nextFloat(),
getPos().getY() + 1.0f,
getPos().getZ() - 0.05f,
0.0f,
-0.01f,
0.0f);
}
else if(rand > 0.25 && rand < 0.5)
{
world.spawnParticle(EnumParticleTypes.END_ROD,
getPos().getX() + 1.05f,
getPos().getY() + 1.0f,
getPos().getZ() + 1.0f - world.rand.nextFloat(),
0.0f,
-0.01f,
0.0f);
}
else if(rand > 0.5 && rand < 0.75)
{
world.spawnParticle(EnumParticleTypes.END_ROD,
getPos().getX() + 1.0f - world.rand.nextFloat(),
getPos().getY() + 1.0f,
getPos().getZ() + 1.05f,
0.0f,
-0.01f,
0.0f);
}
else if(rand > 0.75)
{
world.spawnParticle(EnumParticleTypes.END_ROD,
getPos().getX() - 0.05f,
getPos().getY() + 1.0f,
getPos().getZ() + 1.0f - world.rand.nextFloat(),
0.0f,
-0.01f,
0.0f);
}
}
public void decrCraftingFromItemStack(EntityItem enItem)
{
if ((enItem.getItem()).getCount() > 1)
{
(enItem.getItem()).setCount((enItem.getItem()).getCount() - 1);
}
else
{
enItem.setDead();
}
}
public void resetCraftingValues()
{
nowCrafting = null;
craftingFrom = null;
craftingCount = 0;
}
public void craftItem(List<EntityItem> list, ItemStack stack)
{
for (int i = 0; i < list.size(); i++) //Перепроверяет, если предмет, из которого крафтят, всё ещё на месте; а то вдруг какой-нибудь шалун стырил его
{
if((list.get(i).getItem()).getItem() == new ItemStack(craftingFrom, 1).getItem())
{
if (stack.getCount() > 0)
{
spawnEnhanceParticles();
stack.setCount(stack.getCount() - 1);
decrCraftingFromItemStack(list.get(i));
if(world.isRemote == false)
{
world.spawnEntity(new EntityItem(world, pos.getX() + 0.5, pos.getY() + 1.05, pos.getZ() + 0.5, new ItemStack(nowCrafting, craftingCount)));
}
resetCraftingValues();
}
else
{
resetCraftingValues();
}
break;
}
}
resetCraftingValues();
craftCounter = 0;
}
public void playMagicEnhancerCraftingSound()
{
Random rand = new Random();
float randomVolume = rand.nextInt(50)/100f + 0.5f;
float randomPitch = rand.nextInt(20)/100f + 0.8f;
world.playSound(null, pos, SaMSoundHandler.magicEnhancerCrafting, SoundCategory.MASTER, randomVolume, randomPitch);
}
@Override
public int getSizeInventory() {
return 1;
}
@Override
public boolean isEmpty() {
for (ItemStack itemstack : this.stacks)
if (!itemstack.isEmpty())
return false;
return true;
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
return true;
}
@Override
public ItemStack getStackInSlot(int slot) {
return stacks.get(slot);
}
@Override
public String getName() {
return "container.magicenhancer";
}
@Override
public void readFromNBT(NBTTagCompound compound) {
super.readFromNBT(compound);
this.stacks = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
if (!this.checkLootAndRead(compound))
ItemStackHelper.loadAllItems(compound, this.stacks);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
super.writeToNBT(compound);
if (!this.checkLootAndWrite(compound))
ItemStackHelper.saveAllItems(compound, this.stacks);
return compound;
}
@Override
public SPacketUpdateTileEntity getUpdatePacket() {
return new SPacketUpdateTileEntity(this.pos, 0, this.getUpdateTag());
}
@Override
public NBTTagCompound getUpdateTag() {
return this.writeToNBT(new NBTTagCompound());
}
@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
this.readFromNBT(pkt.getNbtCompound());
}
@Override
public void handleUpdateTag(NBTTagCompound tag) {
this.readFromNBT(tag);
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public String getGuiID() {
return "substance_and_mind:magicenhancer";
}
@Override
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn) {
return new GuiMagicEnhancerGUI.GuiContainerMod(this.getWorld(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ(),
playerIn);
}
@Override
protected NonNullList<ItemStack> getItems() {
return this.stacks;
}
}