[1.14.4] MinecraftForgeで独自の木を自然生成する方法教えてください。

Modやプラグインの制作/開発に関する質問はこちらへどうぞ。
アバター
Seaoftrees
ID: 2SX9F5XEFS
記事: 32
登録日時: 2019年9月05日(木) 00:31
お住まい: Japan, Osaka
Minecraft ID: Seaoftrees08
いいね: 1回
連絡する:

[1.14.4] MinecraftForgeで独自の木を自然生成する方法教えてください。

投稿記事 by Seaoftrees » 2019年10月19日(土) 21:14

MinecraftForgeで独自の木を自然生成する方法教えてください。
梅の原木、梅の葉、梅の苗木の実装は完了し、梅の苗木に骨粉をまけば木が生えるというところまで作成できています。
つぎに、ワールドを生成したときに、自然に梅の木が生えるようにしたいのですがその方法がわかりません。
おそらく、MainクラスのどっかでBiomes.各バイオーム.addFeature();するのだと思いますが、どこでやるのか、また引数をどうすればいいのかがわかりません。
一応メインクラス(JapaneseColor.java)、梅の木クラス(PlumTree.java)、梅の木を生やすロジックのクラス(PlumTreeFeature.java)を乗せておきます。

JapaneseColor.java

コード: 全て選択

package com.seatrees.japanesecolor.core;

import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;

import java.util.Map.Entry;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.seatrees.japanesecolor.init.BlockLists;
import com.seatrees.japanesecolor.init.ItemLists;

@Mod(Reference.MOD_ID)
public class JapaneseColor
{
    private static final Logger LOGGER = LogManager.getLogger();

    public JapaneseColor() {
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);
        MinecraftForge.EVENT_BUS.register(this);
    }

    private void setup(final FMLCommonSetupEvent event)
    {
        LOGGER.info("HELLO FROM PREINIT");
    }


    private void doClientStuff(final FMLClientSetupEvent event) {
        LOGGER.info("HELLO FROM Client Setup");
    }

    @SubscribeEvent
    public void onServerStarting(FMLServerStartingEvent event) {
        LOGGER.info("HELLO from server starting");
    }
    
    @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
    public static class RegistryEvents {
    	
    	
    	//registory Items
        @SubscribeEvent
        public static void onItemsRegistry(final RegistryEvent.Register<Item> event) {

        	ItemLists.initItemLists();
        	for(Entry<String, Item> entry : ItemLists.getHashMap().entrySet()) {
        		event.getRegistry().register(entry.getValue());
        	}
        }
    	
        //registory Blocks
        @SubscribeEvent
        public static void onBlocksRegistry(final RegistryEvent.Register<Block> event) {
  
        	BlockLists.initBlockLists();
        	for(Entry<String, Block> entry : BlockLists.getHashMap().entrySet()){
        		event.getRegistry().register(entry.getValue());
        	}
        }
        
    }
    
}

PlumTree.java

コード: 全て選択

package com.seatrees.japanesecolor.tree;

import java.util.Random;

import net.minecraft.block.trees.Tree;
import net.minecraft.world.gen.feature.AbstractTreeFeature;
import net.minecraft.world.gen.feature.NoFeatureConfig;

public class PlumTree extends Tree{

	@Override
	protected AbstractTreeFeature<NoFeatureConfig> getTreeFeature(Random random) {
		return new PlumTreeFeature(NoFeatureConfig::deserialize, true, false);
	}

}

PlumTreeFeature.java

コード: 全て選択

package com.seatrees.japanesecolor.tree;

import java.util.Random;
import java.util.Set;
import java.util.function.Function;

import com.mojang.datafixers.Dynamic;
import com.seatrees.japanesecolor.init.BlockLists;

import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.world.gen.IWorldGenerationReader;
import net.minecraft.world.gen.feature.AbstractTreeFeature;
import net.minecraft.world.gen.feature.NoFeatureConfig;

public class PlumTreeFeature extends AbstractTreeFeature<NoFeatureConfig>{
	
	   private static final BlockState LOG = BlockLists.getBlock(BlockLists.PLUM_LOG).getDefaultState();
	   private static final BlockState LEAF = BlockLists.getBlock(BlockLists.PLUM_LEAVES).getDefaultState();
	   private final boolean useExtraRandomHeight;
	   
	   public PlumTreeFeature(Function<Dynamic<?>, ? extends NoFeatureConfig> configIn, boolean doBlockNotifyIn,
			   boolean extraRandomHeightIn) {
		      super(configIn, doBlockNotifyIn);
		      this.useExtraRandomHeight = extraRandomHeightIn;
		      this.setSapling((net.minecraftforge.common.IPlantable)BlockLists.getBlock(BlockLists.PLUM_SAPLING));
		   }

	@Override
	public boolean place(Set<BlockPos> changedBlocks, IWorldGenerationReader worldIn, Random rand, BlockPos position,
			MutableBoundingBox p_208519_5_) {
	      int i = rand.nextInt(3) + 5;
	      if (this.useExtraRandomHeight) {
	         i += rand.nextInt(7);
	      }

	      boolean flag = true;
	      if (position.getY() >= 1 && position.getY() + i + 1 <= worldIn.getMaxHeight()) {
	         for(int j = position.getY(); j <= position.getY() + 1 + i; ++j) {
	            int k = 1;
	            if (j == position.getY()) {
	               k = 0;
	            }

	            if (j >= position.getY() + 1 + i - 2) {
	               k = 2;
	            }

	            BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();

	            for(int l = position.getX() - k; l <= position.getX() + k && flag; ++l) {
	               for(int i1 = position.getZ() - k; i1 <= position.getZ() + k && flag; ++i1) {
	                  if (j >= 0 && j < worldIn.getMaxHeight()) {
	                     if (!func_214587_a(worldIn, blockpos$mutableblockpos.setPos(l, j, i1))) {
	                        flag = false;
	                     }
	                  } else {
	                     flag = false;
	                  }
	               }
	            }
	         }

	         if (!flag) {
	            return false;
	         } else if ((isSoil(worldIn, position.down(), getSapling())) && position.getY() < worldIn.getMaxHeight() - i - 1) {
	            this.setDirtAt(worldIn, position.down(), position);

	            for(int l1 = position.getY() - 3 + i; l1 <= position.getY() + i; ++l1) {
	               int j2 = l1 - (position.getY() + i);
	               int k2 = 1 - j2 / 2;

	               for(int l2 = position.getX() - k2; l2 <= position.getX() + k2; ++l2) {
	                  int i3 = l2 - position.getX();

	                  for(int j1 = position.getZ() - k2; j1 <= position.getZ() + k2; ++j1) {
	                     int k1 = j1 - position.getZ();
	                     if (Math.abs(i3) != k2 || Math.abs(k1) != k2 || rand.nextInt(2) != 0 && j2 != 0) {
	                        BlockPos blockpos = new BlockPos(l2, l1, j1);
	                        if (isAirOrLeaves(worldIn, blockpos)) {
	                           this.setLogState(changedBlocks, worldIn, blockpos, LEAF, p_208519_5_);
	                        }
	                     }
	                  }
	               }
	            }

	            for(int i2 = 0; i2 < i; ++i2) {
	               if (isAirOrLeaves(worldIn, position.up(i2))) {
	                  this.setLogState(changedBlocks, worldIn, position.up(i2), LOG, p_208519_5_);
	               }
	            }

	            return true;
	         } else {
	            return false;
	         }
	      } else {
	         return false;
	      }
	   }
}

その他、コード内に不明な点があったら聞き返していただいて構いません。どうかご教授願います。
0


まったりいきましょ。

Coloneia
ID: 3C6DUHNQX7
記事: 34
登録日時: 2019年7月02日(火) 08:01
Minecraft ID: Coloneia
いいね: 15回
連絡する:

Re: [1.14.4] MinecraftForgeで独自の木を自然生成する方法教えてください。

投稿記事 by Coloneia » 2019年10月20日(日) 00:29

Coloneia@管理チーム [PMを作成]

本トピックをリソースパック/mod/その他ツール関係の質問に当てはまらないとみなした為mod/プラグイン制作関連の質問へ移動させました。

1
1 画像

アバター
Seaoftrees
ID: 2SX9F5XEFS
記事: 32
登録日時: 2019年9月05日(木) 00:31
お住まい: Japan, Osaka
Minecraft ID: Seaoftrees08
いいね: 1回
連絡する:

Re: [1.14.4] MinecraftForgeで独自の木を自然生成する方法教えてください。

投稿記事 by Seaoftrees » 2019年10月20日(日) 09:43

あ、作成関連こっちでしたね。トピ移動ありがとうございます。
1
1 画像
まったりいきましょ。

アバター
Seaoftrees
ID: 2SX9F5XEFS
記事: 32
登録日時: 2019年9月05日(木) 00:31
お住まい: Japan, Osaka
Minecraft ID: Seaoftrees08
いいね: 1回
連絡する:

Re: [1.14.4] MinecraftForgeで独自の木を自然生成する方法教えてください。

投稿記事 by Seaoftrees » 2019年10月20日(日) 09:52

自己解決したので、報告しておきます。
メインクラスに新しくFMLCommonSetupEventを引数に取るメソッドを作成し、

コード: 全て選択

FMLJavaModLoadingContext.get().getModEventBus().addListener(this::FMLCommonSetupEvent);
のようにしてeventの登録を行った後、作成したメソッド内で

コード: 全て選択

biome.addFeature(
         Decoration.VEGETAL_DECORATION,
         Biome.createDecoratedFeature(
            feature,
               IFeatureConfig.NO_FEATURE_CONFIG,
               Placement.COUNT_EXTRA_HEIGHTMAP,
               new AtSurfaceWithExtraConfig(count, extraChanceIn, extraCountIn))
);
とすれば、木の登録が行えました。(featureは木の生成ロジックを書いているAbstractTreeFeature<NoFeatureConfig>をextendsしているクラスをnewで呼び出しました。)
以下がメインクラスの全文になります。

コード: 全て選択

package com.seatrees.japanesecolor.core;

import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;

import java.util.Map.Entry;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.seatrees.japanesecolor.init.BlockLists;
import com.seatrees.japanesecolor.init.ItemLists;

@Mod(Reference.MOD_ID)
public class JapaneseColor
{
    private static final Logger LOGGER = LogManager.getLogger();

    public JapaneseColor() {
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::FMLCommonSetupEvent);
        MinecraftForge.EVENT_BUS.register(this);
    }

    private void setup(final FMLCommonSetupEvent event)
    {
    	
    //	Biome.getMutationForBiome((Biome) ForestBiome.BIOMES).addFeature(decorationStage, featureIn);
        LOGGER.info("HELLO FROM PREINIT");
    }


    private void doClientStuff(final FMLClientSetupEvent event) {
        LOGGER.info("HELLO FROM Client Setup");
    }

    @SubscribeEvent
    public void onServerStarting(FMLServerStartingEvent event) {
        LOGGER.info("HELLO from server starting");
    }
    
    //Tree Registry
    @SubscribeEvent
    public void FMLCommonSetupEvent(FMLCommonSetupEvent event) {
    	Biomes.FOREST.addFeature(
         Decoration.VEGETAL_DECORATION,
         Biome.createDecoratedFeature(
            new PlumTreeFeature(NoFeatureConfig::deserialize, true, false),
               IFeatureConfig.NO_FEATURE_CONFIG,
               Placement.COUNT_EXTRA_HEIGHTMAP,
               new AtSurfaceWithExtraConfig(5, 0.4F, 1))
         );
    }
    
    @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
    public static class RegistryEvents {
    	
    	
    	//registry Items
        @SubscribeEvent
        public static void onItemsRegistry(final RegistryEvent.Register<Item> event) {

        	ItemLists.initItemLists();
        	for(Entry<String, Item> entry : ItemLists.getHashMap().entrySet()) {
        		event.getRegistry().register(entry.getValue());
        	}
        }
    	
        //registry Blocks
        @SubscribeEvent
        public static void onBlocksRegistry(final RegistryEvent.Register<Block> event) {
  
        	BlockLists.initBlockLists();
        	for(Entry<String, Block> entry : BlockLists.getHashMap().entrySet()){
        		event.getRegistry().register(entry.getValue());
        	}
        }
        
    }
    
}
1
1 画像
まったりいきましょ。

アバター
Seaoftrees
ID: 2SX9F5XEFS
記事: 32
登録日時: 2019年9月05日(木) 00:31
お住まい: Japan, Osaka
Minecraft ID: Seaoftrees08
いいね: 1回
連絡する:

Re: [1.14.4] MinecraftForgeで独自の木を自然生成する方法教えてください。

投稿記事 by Seaoftrees » 2019年10月20日(日) 10:16

追記:

FMLCommonSetupEventはすでにsetupという名前で登録されているのでわざわざ新規にメソッド作らなくても
setupメソッド内で登録しちゃって大丈夫でしたテヘ
1
1 画像
まったりいきましょ。

返信する