待解决【7月8日下午更新】7月6日捉虫报告 计12个潜在问题,剩余1个

7月8日下午更新:

除第4条后续处理以外;其他问题均于服务器环境下确认已修复。

第4条(派对树)在服务器环境下测试尚无效果,骨粉和自然生长暂时仍无法生长出原版三种派对树。请求进一步核验

2026-07-08_13.21.33

 

猜测可能是原版单树苗的判定优先级高于新添加的代码,需要在中州维度下@override对树苗方块的生长方法进行重写。

这是传承版中生成树木的代码。(可以观察到对原版橡木的世界生成进行了重构)

package lotr.common.world.feature;

import java.util.Random;

import lotr.common.LOTRMod;
import net.minecraft.init.Blocks;
import net.minecraft.util.WeightedRandom;
import net.minecraft.world.gen.feature.*;

public enum LOTRTreeType {
	OAK(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			if (rand.nextInt(4) == 0) {
				return new LOTRWorldGenGnarledOak(flag);
			}
			return new LOTRWorldGenSimpleTrees(flag, 4, 6, Blocks.log, 0, Blocks.leaves, 0);
		}
	}), OAK_TALL(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			if (rand.nextInt(4) == 0) {
				return new LOTRWorldGenGnarledOak(flag).setMinMaxHeight(6, 10);
			}
			return new LOTRWorldGenSimpleTrees(flag, 8, 12, Blocks.log, 0, Blocks.leaves, 0);
		}
	}), OAK_TALLER(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 12, 16, Blocks.log, 0, Blocks.leaves, 0);
		}
	}), OAK_ITHILIEN_HIDEOUT(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 6, 6, Blocks.log, 0, Blocks.leaves, 0);
		}
	}), OAK_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenBigTrees(flag, Blocks.log, 0, Blocks.leaves, 0);
		}
	}), OAK_PARTY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPartyTrees(Blocks.log, 0, Blocks.leaves, 0);
		}
	}), OAK_FANGORN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenFangornTrees(flag, Blocks.log, 0, Blocks.leaves, 0);
		}
	}), OAK_FANGORN_DEAD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenFangornTrees(flag, Blocks.log, 0, Blocks.leaves, 0).setNoLeaves();
		}
	}), OAK_SWAMP(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenSwamp();
		}
	}), OAK_DEAD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDeadTrees(Blocks.log, 0);
		}
	}), OAK_DESERT(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDesertTrees(flag, Blocks.log, 0, Blocks.leaves, 0);
		}
	}), OAK_SHRUB(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenShrub(Blocks.log, 0, Blocks.leaves, 0);
		}
	}), BIRCH(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			if (rand.nextInt(3) != 0) {
				return new LOTRWorldGenAspen(flag).setBlocks(Blocks.log, 2, Blocks.leaves, 2).setMinMaxHeight(8, 16);
			}
			return new LOTRWorldGenSimpleTrees(flag, 5, 7, Blocks.log, 2, Blocks.leaves, 2);
		}
	}), BIRCH_TALL(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 8, 11, Blocks.log, 2, Blocks.leaves, 2);
		}
	}), BIRCH_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenBigTrees(flag, Blocks.log, 2, Blocks.leaves, 2);
		}
	}), BIRCH_PARTY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPartyTrees(Blocks.log, 2, Blocks.leaves, 2);
		}
	}), BIRCH_FANGORN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenFangornTrees(flag, Blocks.log, 2, Blocks.leaves, 2);
		}
	}), BIRCH_DEAD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDeadTrees(Blocks.log, 2);
		}
	}), SPRUCE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenTaiga2(flag);
		}
	}), SPRUCE_THIN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenTaiga1();
		}
	}), SPRUCE_MEGA(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenMegaPineTree(flag, true);
		}
	}), SPRUCE_MEGA_THIN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenMegaPineTree(flag, false);
		}
	}), SPRUCE_DEAD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDeadTrees(Blocks.log, 1);
		}
	}), JUNGLE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenTrees(flag, 7, 3, 3, true);
		}
	}), JUNGLE_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenMegaJungle(flag, 10, 20, 3, 3);
		}
	}), JUNGLE_CLOUD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenMegaJungle(flag, 30, 30, 3, 3);
		}
	}), JUNGLE_SHRUB(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenShrub(Blocks.log, 3, Blocks.leaves, 3);
		}
	}), JUNGLE_FANGORN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenFangornTrees(flag, Blocks.log, 3, Blocks.leaves, 3).setHeightFactor(1.5f);
		}
	}), ACACIA(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenSavannaTree(flag);
		}
	}), ACACIA_DEAD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDeadTrees(Blocks.log2, 0);
		}
	}), DARK_OAK(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new WorldGenCanopyTree(flag);
		}
	}), DARK_OAK_PARTY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPartyTrees(Blocks.log2, 1, Blocks.leaves2, 1);
		}
	}), SHIRE_PINE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenShirePine(flag);
		}
	}), MALLORN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 6, 9, LOTRMod.wood, 1, LOTRMod.leaves, 1);
		}
	}), MALLORN_BOUGHS(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMallorn(flag);
		}
	}), MALLORN_PARTY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPartyTrees(LOTRMod.wood, 1, LOTRMod.leaves, 1);
		}
	}), MALLORN_EXTREME(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMallornExtreme(flag);
		}
	}), MALLORN_EXTREME_SAPLING(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMallornExtreme(flag).setSaplingGrowth();
		}
	}), MIRK_OAK(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMirkOak(flag, 4, 7, 0, true);
		}
	}), MIRK_OAK_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMirkOak(flag, 12, 16, 1, true);
		}
	}), MIRK_OAK_DEAD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMirkOak(flag, 4, 7, 0, true).setDead();
		}
	}), RED_OAK(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMirkOak(flag, 6, 9, 0, false).setRedOak();
		}
	}), RED_OAK_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMirkOak(flag, 12, 17, 1, false).setRedOak();
		}
	}), RED_OAK_WEIRWOOD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMirkOak(flag, 12, 20, 1, false).setBlocks(LOTRMod.wood9, 0, LOTRMod.leaves, 3);
		}
	}), CHARRED(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenCharredTrees();
		}
	}), CHARRED_FANGORN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenFangornTrees(flag, LOTRMod.wood, 3, Blocks.air, 0).setNoLeaves();
		}
	}), APPLE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 4, 7, LOTRMod.fruitWood, 0, LOTRMod.fruitLeaves, 0);
		}
	}), PEAR(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 4, 5, LOTRMod.fruitWood, 1, LOTRMod.fruitLeaves, 1);
		}
	}), CHERRY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 4, 8, LOTRMod.fruitWood, 2, LOTRMod.fruitLeaves, 2);
		}
	}), CHERRY_MORDOR(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPartyTrees(LOTRMod.fruitWood, 2, LOTRMod.fruitLeaves, 2).disableRestrictions();
		}
	}), MANGO(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			if (rand.nextInt(3) == 0) {
				return new LOTRWorldGenOlive(flag).setBlocks(LOTRMod.fruitWood, 3, LOTRMod.fruitLeaves, 3);
			}
			return new LOTRWorldGenDesertTrees(flag, LOTRMod.fruitWood, 3, LOTRMod.fruitLeaves, 3);
		}
	}), LEBETHRON(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 5, 9, LOTRMod.wood2, 0, LOTRMod.leaves2, 0);
		}
	}), LEBETHRON_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenBigTrees(flag, LOTRMod.wood2, 0, LOTRMod.leaves2, 0);
		}
	}), LEBETHRON_PARTY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPartyTrees(LOTRMod.wood2, 0, LOTRMod.leaves2, 0);
		}
	}), LEBETHRON_DEAD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDeadTrees(LOTRMod.wood2, 0);
		}
	}), BEECH(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 5, 9, LOTRMod.wood2, 1, LOTRMod.leaves2, 1);
		}
	}), BEECH_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenBigTrees(flag, LOTRMod.wood2, 1, LOTRMod.leaves2, 1);
		}
	}), BEECH_PARTY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPartyTrees(LOTRMod.wood2, 1, LOTRMod.leaves2, 1);
		}
	}), BEECH_FANGORN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenFangornTrees(flag, LOTRMod.wood2, 1, LOTRMod.leaves2, 1);
		}
	}), BEECH_FANGORN_DEAD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenFangornTrees(flag, LOTRMod.wood2, 1, LOTRMod.leaves2, 1).setNoLeaves();
		}
	}), BEECH_DEAD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDeadTrees(LOTRMod.wood2, 1);
		}
	}), HOLLY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenHolly(flag);
		}
	}), HOLLY_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenHolly(flag).setLarge();
		}
	}), BANANA(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenBanana(flag);
		}
	}), MAPLE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 4, 8, LOTRMod.wood3, 0, LOTRMod.leaves3, 0);
		}
	}), MAPLE_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenBigTrees(flag, LOTRMod.wood3, 0, LOTRMod.leaves3, 0);
		}
	}), MAPLE_PARTY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPartyTrees(LOTRMod.wood3, 0, LOTRMod.leaves3, 0);
		}
	}), LARCH(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenLarch(flag);
		}
	}), DATE_PALM(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPalm(flag, LOTRMod.wood3, 2, LOTRMod.leaves3, 2).setMinMaxHeight(5, 8).setDates();
		}
	}), MANGROVE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMangrove(flag);
		}
	}), CHESTNUT(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 5, 7, LOTRMod.wood4, 0, LOTRMod.leaves4, 0);
		}
	}), CHESTNUT_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenBigTrees(flag, LOTRMod.wood4, 0, LOTRMod.leaves4, 0);
		}
	}), CHESTNUT_PARTY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPartyTrees(LOTRMod.wood4, 0, LOTRMod.leaves4, 0);
		}
	}), BAOBAB(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenBaobab(flag);
		}
	}), CEDAR(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenCedar(flag);
		}
	}), CEDAR_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenCedar(flag).setMinMaxHeight(15, 30);
		}
	}), FIR(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenFir(flag);
		}
	}), PINE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPine(flag);
		}
	}), PINE_SHRUB(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenShrub(LOTRMod.wood5, 0, LOTRMod.leaves5, 0);
		}
	}), LEMON(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			if (rand.nextInt(3) == 0) {
				return new LOTRWorldGenOlive(flag).setBlocks(LOTRMod.wood5, 1, LOTRMod.leaves5, 1);
			}
			return new LOTRWorldGenDesertTrees(flag, LOTRMod.wood5, 1, LOTRMod.leaves5, 1);
		}
	}), ORANGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			if (rand.nextInt(3) == 0) {
				return new LOTRWorldGenOlive(flag).setBlocks(LOTRMod.wood5, 2, LOTRMod.leaves5, 2);
			}
			return new LOTRWorldGenDesertTrees(flag, LOTRMod.wood5, 2, LOTRMod.leaves5, 2);
		}
	}), LIME(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			if (rand.nextInt(3) == 0) {
				return new LOTRWorldGenOlive(flag).setBlocks(LOTRMod.wood5, 3, LOTRMod.leaves5, 3);
			}
			return new LOTRWorldGenDesertTrees(flag, LOTRMod.wood5, 3, LOTRMod.leaves5, 3);
		}
	}), MAHOGANY(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenCedar(flag).setBlocks(LOTRMod.wood6, 0, LOTRMod.leaves6, 0).setHangingLeaves();
		}
	}), MAHOGANY_FANGORN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenFangornTrees(flag, LOTRMod.wood6, 0, LOTRMod.leaves6, 0).setHeightFactor(1.5f);
		}
	}), WILLOW(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenWillow(flag);
		}
	}), WILLOW_WATER(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenWillow(flag).setNeedsWater();
		}
	}), CYPRESS(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenCypress(flag);
		}
	}), CYPRESS_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenCypress(flag).setLarge();
		}
	}), OLIVE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenOlive(flag);
		}
	}), OLIVE_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenOlive(flag).setMinMaxHeight(5, 8).setExtraTrunkWidth(1);
		}
	}), ASPEN(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenAspen(flag);
		}
	}), ASPEN_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenAspen(flag).setExtraTrunkWidth(1).setMinMaxHeight(14, 25);
		}
	}), GREEN_OAK(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMirkOak(flag, 4, 7, 0, false).setGreenOak();
		}
	}), GREEN_OAK_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMirkOak(flag, 12, 16, 1, false).setGreenOak();
		}
	}), GREEN_OAK_EXTREME(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenMirkOak(flag, 25, 45, 2, false).setGreenOak();
		}
	}), LAIRELOSSE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenLairelosse(flag);
		}
	}), LAIRELOSSE_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenLairelosse(flag).setExtraTrunkWidth(1).setMinMaxHeight(8, 12);
		}
	}), ALMOND(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenAlmond(flag);
		}
	}), PLUM(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenSimpleTrees(flag, 4, 6, LOTRMod.wood8, 0, LOTRMod.leaves8, 0);
		}
	}), REDWOOD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenRedwood(flag);
		}
	}), REDWOOD_2(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenRedwood(flag).setExtraTrunkWidth(1);
		}
	}), REDWOOD_3(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenRedwood(flag).setTrunkWidth(1);
		}
	}), REDWOOD_4(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenRedwood(flag).setTrunkWidth(1).setExtraTrunkWidth(1);
		}
	}), REDWOOD_5(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenRedwood(flag).setTrunkWidth(2);
		}
	}), POMEGRANATE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			if (rand.nextInt(3) == 0) {
				return new LOTRWorldGenOlive(flag).setBlocks(LOTRMod.wood8, 2, LOTRMod.leaves8, 2);
			}
			return new LOTRWorldGenDesertTrees(flag, LOTRMod.wood8, 2, LOTRMod.leaves8, 2);
		}
	}), PALM(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenPalm(flag, LOTRMod.wood8, 3, LOTRMod.leaves8, 3).setMinMaxHeight(6, 11);
		}
	}), DRAGONBLOOD(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDragonblood(flag, 3, 7, 0);
		}
	}), DRAGONBLOOD_LARGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDragonblood(flag, 6, 10, 1);
		}
	}), DRAGONBLOOD_HUGE(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenDragonblood(flag, 8, 16, 2);
		}
	}), KANUKA(new ITreeFactory() {

		@Override
		public WorldGenAbstractTree createTree(boolean flag, Random rand) {
			return new LOTRWorldGenKanuka(flag);
		}
	}), NULL(null);

	public ITreeFactory treeFactory;

	LOTRTreeType(ITreeFactory factory) {
		treeFactory = factory;
	}

	public WorldGenAbstractTree create(boolean flag, Random rand) {
		return treeFactory.createTree(flag, rand);
	}

	public static interface ITreeFactory {
		WorldGenAbstractTree createTree(boolean var1, Random var2);
	}

	public static class WeightedTreeType extends WeightedRandom.Item {
		public LOTRTreeType treeType;

		public WeightedTreeType(LOTRTreeType tree, int i) {
			super(i);
			treeType = tree;
		}
	}

}

这是树苗生长的算法,其中findSaplingSquare函数是mod使用的多树苗判定的独立算法。

package lotr.common.block;

import java.util.*;

import cpw.mods.fml.relauncher.*;
import lotr.common.LOTRCreativeTabs;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.*;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
import net.minecraftforge.event.terraingen.TerrainGen;

public abstract class LOTRBlockSaplingBase extends LOTRBlockFlower {
	@SideOnly(value = Side.CLIENT)
	public IIcon[] saplingIcons;
	public String[] saplingNames;

	public LOTRBlockSaplingBase() {
		float f = 0.4f;
		setBlockBounds(0.5f - f, 0.0f, 0.5f - f, 0.5f + f, f * 2.0f, 0.5f + f);
		setCreativeTab(LOTRCreativeTabs.tabDeco);
	}

	@Override
	public int damageDropped(int i) {
		return i & 7;
	}

	@Override
	@SideOnly(value = Side.CLIENT)
	public IIcon getIcon(int i, int j) {
		j &= 7;
		if (j >= saplingNames.length) {
			j = 0;
		}
		return saplingIcons[j];
	}

	@Override
	public int getRenderType() {
		return 1;
	}

	@Override
	@SideOnly(value = Side.CLIENT)
	public void getSubBlocks(Item item, CreativeTabs tab, List list) {
		for (int i = 0; i < saplingNames.length; ++i) {
			list.add(new ItemStack(item, 1, i));
		}
	}

	public abstract void growTree(World var1, int var2, int var3, int var4, Random var5);

	public void incrementGrowth(World world, int i, int j, int k, Random random) {
		int meta = world.getBlockMetadata(i, j, k);
		if ((meta & 8) == 0) {
			world.setBlockMetadataWithNotify(i, j, k, meta | 8, 4);
		} else {
			if (!TerrainGen.saplingGrowTree(world, random, i, j, k)) {
				return;
			}
			growTree(world, i, j, k, random);
		}
	}

	public boolean isSameSapling(World world, int i, int j, int k, int meta) {
		return LOTRBlockSaplingBase.isSameSapling(world, i, j, k, this, meta);
	}

	@Override
	@SideOnly(value = Side.CLIENT)
	public void registerBlockIcons(IIconRegister iconregister) {
		saplingIcons = new IIcon[saplingNames.length];
		for (int i = 0; i < saplingNames.length; ++i) {
			saplingIcons[i] = iconregister.registerIcon(getTextureName() + "_" + saplingNames[i]);
		}
	}

	public void setSaplingNames(String... s) {
		saplingNames = s;
	}

	@Override
	public void updateTick(World world, int i, int j, int k, Random random) {
		if (!world.isRemote) {
			super.updateTick(world, i, j, k, random);
			if (world.getBlockLightValue(i, j + 1, k) >= 9 && random.nextInt(7) == 0) {
				incrementGrowth(world, i, j, k, random);
			}
		}
	}

	public static int[] findCrossShape(World world, int i, int j, int k, Block block, int meta) {
		for (int i1 = -2; i1 <= 2; ++i1) {
			for (int k1 = -2; k1 <= 2; ++k1) {
				if (Math.abs(i1) != 0 && Math.abs(k1) != 0) {
					continue;
				}
				boolean canGenerate = true;
				block2: for (int i2 = -1; i2 <= 1; ++i2) {
					for (int k2 = -1; k2 <= 1; ++k2) {
						if (Math.abs(i2) != 0 && Math.abs(k2) != 0 || LOTRBlockSaplingBase.isSameSapling(world, i + i1 + i2, j, k + k1 + k2, block, meta)) {
							continue;
						}
						canGenerate = false;
						break block2;
					}
				}
				if (!canGenerate) {
					continue;
				}
				return new int[] { i1, k1 };
			}
		}
		return null;
	}

	public static int[] findPartyTree(World world, int i, int j, int k, Block block, int meta) {
		return LOTRBlockSaplingBase.findSaplingSquare(world, i, j, k, block, meta, -1, 1, -2, 2);
	}

	public static int[] findSaplingSquare(World world, int i, int j, int k, Block block, int meta, int squareMin, int squareMax, int searchMin, int searchMax) {
		for (int i1 = searchMin; i1 <= searchMax; ++i1) {
			for (int k1 = searchMin; k1 <= searchMax; ++k1) {
				boolean canGenerate = true;
				block2: for (int i2 = squareMin; i2 <= squareMax; ++i2) {
					for (int k2 = squareMin; k2 <= squareMax; ++k2) {
						int i3 = i + i1 + i2;
						int k3 = k + k1 + k2;
						if (LOTRBlockSaplingBase.isSameSapling(world, i3, j, k3, block, meta)) {
							continue;
						}
						canGenerate = false;
						break block2;
					}
				}
				if (!canGenerate) {
					continue;
				}
				return new int[] { i1, k1 };
			}
		}
		return null;
	}

	public static boolean isSameSapling(World world, int i, int j, int k, Block block, int meta) {
		if (world.getBlock(i, j, k) == block) {
			int blockMeta = world.getBlockMetadata(i, j, k);
			return (blockMeta & 7) == meta;
		}
		return false;
	}
}

7月8日上午更新:

已修复关于第3条:生成【精灵战士】的触发代码,在传承版中位于\src\main\java\lotr\common\block\LOTRBlockWood.class的类文件中。

经查证,1.12重制版该方块类文件中的类似代码缺失,然而【精灵战士】实体类中仍留有DefendTrees相关判定、对话库也未删除,因此认为可能是代码复制遗漏而非重制版团队有意移除机制。

以下贴出传承版中的该部分代码供您参考,其中 public boolean removedByPlayer函数定义了玩家破坏瑁珑木触发战士生成行为的具体判定和生成机制:

package lotr.common.block;

import lotr.common.LOTRLevelData;
import lotr.common.entity.npc.LOTREntityGaladhrimWarrior;
import lotr.common.fac.LOTRFaction;
import lotr.common.world.biome.LOTRBiomeGenLothlorien;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

public class LOTRBlockWood extends LOTRBlockWoodBase {
	public LOTRBlockWood() {
		setWoodNames("shirePine", "mallorn", "mirkOak", "charred");
	}

	@Override
	public boolean removedByPlayer(World world, EntityPlayer entityplayer, int i, int j, int k, boolean willHarvest) {
		if (!world.isRemote && (world.getBlockMetadata(i, j, k) & 3) == 1 && world.rand.nextInt(3) == 0 && world.getBiomeGenForCoords(i, k) instanceof LOTRBiomeGenLothlorien && LOTRLevelData.getData(entityplayer).getAlignment(LOTRFaction.LOTHLORIEN) < 0.0f && !entityplayer.capabilities.isCreativeMode) {
			int elves = 4 + world.rand.nextInt(3);
			boolean sentMessage = false;
			for (int l = 0; l < elves; ++l) {
				int j1;
				int k1;
				LOTREntityGaladhrimWarrior elfWarrior = new LOTREntityGaladhrimWarrior(world);
				int i1 = MathHelper.floor_double(entityplayer.posX) - 6 + world.rand.nextInt(12);
				if (!world.getBlock(i1, (j1 = world.getTopSolidOrLiquidBlock(i1, k1 = MathHelper.floor_double(entityplayer.posZ) - 6 + world.rand.nextInt(12))) - 1, k1).isSideSolid(world, i1, j1 - 1, k1, ForgeDirection.UP) || world.getBlock(i1, j1, k1).isNormalCube() || world.getBlock(i1, j1 + 1, k1).isNormalCube()) {
					continue;
				}
				elfWarrior.setLocationAndAngles(i1 + 0.5, j1, k1 + 0.5, 0.0f, 0.0f);
				if (!elfWarrior.getCanSpawnHere()) {
					continue;
				}
				elfWarrior.spawnRidingHorse = false;
				elfWarrior.onSpawnWithEgg(null);
				world.spawnEntityInWorld(elfWarrior);
				elfWarrior.isDefendingTree = true;
				elfWarrior.setAttackTarget(entityplayer);
				if (sentMessage) {
					continue;
				}
				elfWarrior.sendSpeechBank(entityplayer, "galadhrim/warrior/defendTrees");
				sentMessage = true;
			}
		}
		return super.removedByPlayer(world, entityplayer, i, j, k, willHarvest);
	}
}

1、已修复关于武器的【迅捷】词条未生效代码层面的调查。

由于该问题已经持续存在数月,急需修复,故做了少许查证,仅供参考。

以下是lotr/common/item/weapon/weapon/LOTRWeaponStats中的代码片段

image

上述这两段分别是控制武器长度和速度的代码。

控制速度的上面那一段代码里面Enchantment的MeleeSpeedFactor乘数直接失踪了、返回的是原值。这导致武器的迅捷和迟缓词条完全被排除在算法之外;

而控制长度的下面一段代码里面,返回值的时候乘算了MeleeReachFactor的长度。

因此,上方红色框内的代码

       return factor.floatValue();

应当改为

       speed = factor.floatValue();

       return speed *= LOTREnchantmentHelper.calcMeleeSpeedFactor(itemstack);

2、已修复【各种杯具】(装满的和未装满的)依附的底座方块被破坏后,杯子会直接消失而不是以物品形式掉落。

3、已修复经测试,砍伐【瑁珑树】生成【精灵战士】的机制未正常生效。

该机制为传承版设计,条件为:【洛斯罗瑞恩】派系声望<0的玩家,在【洛斯罗瑞恩】生物群系内(包括边缘)破坏【瑁珑原木】方块时,有概率在周围的【草方块】上强制生成数个【洛斯罗瑞恩精灵战士(Galadhrim Warrior)】并立即攻击玩家。

Mod文件中,专门在assets/lotr/speech/galadhrim/warrior/defendTrees.txt目录下定义了精灵战士该行为的对话库。

注:代码层面的执行方法和【多温尼安守卫】生成并攻击偷盗葡萄的玩家类似。

参考文献:https://lotrminecraftmod.fandom.com/wiki/Galadhrim_Warrior#Spawning

image

4、【待修复】几种原版的树木无法种植3*3的大型【派对树】。

受影响的树苗包括【橡树树苗】、【白桦树苗】、【深色橡木树苗】。其他Mod树苗的派对树,如瑁珑等目前测试正常,因此疑似为代码未覆盖导致的遗漏

传承版中这几种树的派对树,均存在结构生成定义。

根据参考文献:Vanilla Trees | The Lord of the Rings Minecraft Mod Wiki | Fandom,原版树苗当中仅上述三种可以种植派对树。

image

5、已修复原版的【橡木树叶】和【深色橡木树叶】方块被破坏或凋落时,如果其维度在【中州】,不应当掉落【红色苹果】。该特性Mevans曾特别提及。

image

6、已修复部分爆炸物的引爆机制疑似存在问题:

6种【奥克炸弹】、【可哈穆尔之炎】、【古尔都利尔炸弹】无法被红石信号引爆;

6种【奥克炸弹】、【可哈穆尔之炎】、【古尔都利尔炸弹】无法被着火的弹射物引爆;

【古尔都利尔炸弹】无法被奥克火把引爆(即该炸弹只能被其他爆炸引爆)。

(注:上述二、三条的触发条件应为炸弹未受到旗帜保护时)

7、已修复北方永冻(即夏季仍会降雪)的生物群系,其地表水在世界生成时最表层初始是未结冰状态,只有世界加载后才会逐渐冻结。

       已确认的受影响的群系包括:

       【Forodwaith】及其子类(Mountains,Glacier,etc.)

       【Forochel】及其子类

       【Tundra】及其子类(包括Taiga)

       【EasternTundra】及其子类(包括Taiga)

       【Angmar】及其子类

       【Ettenmoors】

       【Coldfells】

       【MistyMountains】及其子类

       【GrayMountains】及其子类

8、已修复【椰子树】在种植时,由于其树叶生成结构问题,部分叶片缺少与主干原木方块的直接连接、会迅速凋落;

可能需要修改树结构生成方式,或者强制为生成的树叶添加手动放置的NBT数据防止凋落。

9、已修复【芦苇】、【干芦苇】水下部分的贴图和水上部分存在45°角的错位:

图中可发现水上部分为对角线渲染(正常),水下贴图与x/z轴平行渲染(错位)

image

10、已修复【矮人门】、【伊希而丁矮人门】在打开状态下,背面的材质存在问题(正面材质正常):

A1J8TKO0D]_EPV54]IT2EP8

左:错误的材质(背面)右:正常的材质(正面)

11、已修复Mod钻石物品的的材质出现异常;可能是由于符文系统框架的影响导致的。

image

12、已修复对【炼药锅】使用【水桶】装水时,水桶中的水不会被消耗。

请登录后发表评论