Skip to content

Commit

Permalink
Tropical (palm) and Willow tree generators. Palm uses a TreeGenVarian…
Browse files Browse the repository at this point in the history
…ts, Willow is a custom generator. Structure template files are moved to /structure_templates/ These are oak tree variants used by python to generate actual trees, they are not to be used included in TFC. Also added a new anvil model thanks to RedRam on discord.
  • Loading branch information
alcatrazEscapee committed Jul 19, 2018
1 parent 44b221e commit 4437651
Show file tree
Hide file tree
Showing 85 changed files with 893 additions and 129 deletions.
54 changes: 34 additions & 20 deletions generateTrees.py
@@ -1,8 +1,8 @@
import os

from nbtlib import nbt
from nbtlib.tag import *

os.chdir('src/main/resources/assets/tfc/structures/')

def tree(origin, wood, nameout):
f = nbt.load(origin + '.nbt')
Expand All @@ -24,45 +24,59 @@ def tree(origin, wood, nameout):
'check_decay': String('true'),
'decayable': String('true')
})
if not os.path.exists(wood):
os.mkdir(wood)
f.save(wood + '/' + nameout + '.nbt')
if not os.path.exists('src/main/resources/assets/tfc/structures/' + wood):
os.makedirs('src/main/resources/assets/tfc/structures/' + wood)
f.save('src/main/resources/assets/tfc/structures/' + wood + '/' + nameout + '.nbt')


WOOD_TYPES = {
'acacia': 'normal',
'ash': 'normal',
'aspen': 'normal',
'birch': 'normal',
'blackwood': 'normal'
'blackwood': 'normal',
'chestnut': 'normal',
'douglas_fir': 'tall',
'hickory': 'normal',
'maple': 'normal',
'oak': 'normal',
'palm': 'palm'
'pine': 'conifer',
'rosewood': 'tall'
'palm': 'tropical',
'pine': 'conifer',
'rosewood': 'tall',
'sequoia': 'normal',
'spruce': 'conifer',
'spruce': 'conifer',
'sycamore': 'normal',
'white_cedar': 'tall',
'willow': 'normal',
'kapok': 'normal'
'willow': 'willow',
'kapok': 'normal'
}

for wood, key in WOOD_TYPES.items():
# normal
# normal (vanilla oak)
if key == 'normal':
tree('base/normal', wood, 'base')
tree('base/normal_overlay', wood, 'overlay')
tree('structure_templates/normal', wood, 'base')
tree('structure_templates/normal_overlay', wood, 'overlay')

# tall (douglas fir)
if key == 'tall':
tree('base/tall', wood, 'base')
tree('base/tall_overlay', wood, 'overlay')
# todo: palm trees
tree('structure_templates/tall', wood, 'base')
tree('structure_templates/tall_overlay', wood, 'overlay')

# overhang (willow)
if key == 'willow':
tree('structure_templates/w1', wood, 'base')
tree('structure_templates/w2', wood, 'overlay')

# conifer (vanilla spruce)
if key == 'conifer':
for s in ['1', '2', '3', '4', '5', '6', '7']:
tree('base/conifer' + s, wood, s)
# todo: 2x2 coniferous trees
# todo: willow trees
tree('structure_templates/conifer' + s, wood, s)

# palm like trees
if key == 'tropical':
for s in ['1', '2', '3', '4', '5', '6', '7']:
tree('structure_templates/t' + s, wood, s)

# todo: 2x2 coniferous trees (built in parts)
# todo: acacia trees (vanilla style, but bigger?)
# todo: kapok trees (vanilla style jungle, built in parts)
14 changes: 11 additions & 3 deletions src/main/java/net/dries007/tfc/objects/Wood.java
Expand Up @@ -8,6 +8,7 @@
import net.dries007.tfc.objects.trees.ITreeGenerator;
import net.dries007.tfc.objects.trees.TreeGenNormal;
import net.dries007.tfc.objects.trees.TreeGenVariants;
import net.dries007.tfc.objects.trees.TreeGenWillow;

public enum Wood
{
Expand Down Expand Up @@ -42,9 +43,11 @@ public static Wood get(int i)
}

private static ITreeGenerator genNormal = new TreeGenNormal(1, 3); // Short trees. For oak style
private static ITreeGenerator genFixed = new TreeGenNormal(0, 0); // Fixed height. For douglas fir style
private static ITreeGenerator genFixed = new TreeGenNormal(0, 2); // Short height range For douglas fir style
private static ITreeGenerator genTall = new TreeGenNormal(3, 3); // Tall trees. For oak style
private static ITreeGenerator genPineVariant = new TreeGenVariants(false, "1", "2", "3", "4", "5", "6", "7");
private static ITreeGenerator genVariant7 = new TreeGenVariants(false, "1", "2", "3", "4", "5", "6", "7"); // 7 Variants. Conifer
private static ITreeGenerator genVariant7WithRotation = new TreeGenVariants(true, "1", "2", "3", "4", "5", "6", "7"); // 7 Variants. Tropical
private static ITreeGenerator genWillow = new TreeGenWillow(); // Special builder for willow trees

public int getRadiusForGrowth() { return 2; } // todo: make this a property of each tree

Expand All @@ -59,10 +62,15 @@ public ITreeGenerator getTreeGenerator()
case ASH:
case ASPEN:
case HICKORY:
case BIRCH:
return genTall;
case PINE:
case SPRUCE:
return genPineVariant;
return genVariant7;
case PALM:
return genVariant7WithRotation;
case WILLOW:
return genWillow;
default:
return genNormal;
}
Expand Down
Expand Up @@ -56,11 +56,11 @@ public void generateTree(TemplateManager manager, World world, BlockPos pos, Woo
PlacementSettings settings = WorldGenTrees.getDefaultSettings();
int height = heightMin + (heightRange > 0 ? rand.nextInt(heightRange) : 0);

BlockPos size = structureBase.getSize();
pos = pos.add(-size.getX() / 2, height, -size.getZ() / 2);

if (WorldGenTrees.canGenerateTree(world, pos.down(height), structureBase, settings, tree))
if (WorldGenTrees.canGenerateTree(world, pos, structureBase, settings, tree))
{
BlockPos size = structureBase.getSize();
pos = pos.add(-size.getX() / 2, height, -size.getZ() / 2);

structureBase.addBlocksToWorld(world, pos, settings);
structureOverlay.addBlocksToWorld(world, pos, settings.setIntegrity(0.5f));

Expand Down
Expand Up @@ -49,13 +49,13 @@ public void generateTree(TemplateManager manager, World world, BlockPos pos, Woo
return;
}

PlacementSettings settings = WorldGenTrees.getDefaultSettings();
// do rotation things. Keep block pos in mind
BlockPos size = structureBase.getSize();
pos = pos.add(-size.getX() / 2, 0, -size.getZ() / 2);
PlacementSettings settings = useRotation ? WorldGenTrees.getRandomSettings(rand) : WorldGenTrees.getDefaultSettings();

if (WorldGenTrees.canGenerateTree(world, pos, structureBase, settings, tree))
{
BlockPos size = structureBase.getSize().rotate(settings.getRotation());
// Begin rotation things
pos = pos.add(-size.getX() / 2, 0, -size.getZ() / 2);
structureBase.addBlocksToWorld(world, pos, settings);
}
}
Expand Down
107 changes: 107 additions & 0 deletions src/main/java/net/dries007/tfc/objects/trees/TreeGenWillow.java
@@ -0,0 +1,107 @@
/*
* Work under Copyright. Licensed under the EUPL.
* See the project README.md and LICENSE.txt for more information.
*
*/

package net.dries007.tfc.objects.trees;

import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.block.BlockLog;
import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.structure.template.PlacementSettings;
import net.minecraft.world.gen.structure.template.Template;
import net.minecraft.world.gen.structure.template.TemplateManager;

import net.dries007.tfc.Constants;
import net.dries007.tfc.TerraFirmaCraft;
import net.dries007.tfc.objects.Wood;
import net.dries007.tfc.objects.blocks.wood.BlockLeavesTFC;
import net.dries007.tfc.objects.blocks.wood.BlockLogTFC;
import net.dries007.tfc.world.classic.worldgen.WorldGenTrees;

import static net.minecraft.block.BlockLog.LOG_AXIS;

public class TreeGenWillow implements ITreeGenerator
{
private Template structureBase;
private Template structureOverlay;
private PlacementSettings settingsWeak;
private PlacementSettings settingsFull;

@Override
public void generateTree(TemplateManager manager, World world, BlockPos pos, Wood tree, Random rand)
{
ResourceLocation base = new ResourceLocation(Constants.MOD_ID, tree + "/base");
ResourceLocation overlay = new ResourceLocation(Constants.MOD_ID, tree + "/overlay");

structureBase = manager.get(world.getMinecraftServer(), base);
structureOverlay = manager.get(world.getMinecraftServer(), overlay);

if (structureBase == null || structureOverlay == null)
{
TerraFirmaCraft.getLog().warn("Unable to find a template for " + base.toString() + " or " + overlay.toString());
return;
}
settingsFull = WorldGenTrees.getDefaultSettings();
settingsWeak = WorldGenTrees.getDefaultSettings().setIntegrity(0.5F);

if (!WorldGenTrees.canGenerateTree(world, pos, structureBase, settingsFull, tree))
return;

int height = 3 + rand.nextInt(3), branches = 2 + rand.nextInt(3), x1, z1, y1;
for (int n = 0; n <= height; n++)
{
tryPlaceLog(world, pos.up(n), tree, BlockLog.EnumAxis.Y);
if (n >= 3)
createLeafGroup(world, pos.up(n));
}

for (int n = 0; n < branches; n++)
{
x1 = (rand.nextBoolean() ? 1 : -1) * (1 + rand.nextInt(3));
z1 = (rand.nextBoolean() ? 1 : -1) * (1 + rand.nextInt(3));
y1 = 1 + rand.nextInt(2);
createBranch(world, pos.up(n + 1), x1, y1, z1, rand, tree);
createLeafGroup(world, pos.add(x1, y1, z1));
}
}

private void createBranch(World world, BlockPos pos1, int x, int y, int z, Random rand, Wood tree)
{
int x1 = x / Math.abs(x), z1 = z / Math.abs(z);
do
{
if (x != 0 && rand.nextBoolean())
x -= x1;
if (z != 0 && rand.nextBoolean())
z -= z1;
tryPlaceLog(world, pos1.add(x, y, z), tree, rand.nextBoolean() ? BlockLog.EnumAxis.X : BlockLog.EnumAxis.Z);
if (rand.nextBoolean())
createLeafGroup(world, pos1.add(x, y, z));
}
while (Math.abs(x) + Math.abs(z) > 1);
}

private void createLeafGroup(World world, BlockPos pos)
{

BlockPos size = structureBase.getSize();
pos = pos.add(-size.getX() / 2, 0, -size.getZ() / 2);

structureBase.addBlocksToWorld(world, pos, settingsFull);
structureOverlay.addBlocksToWorld(world, pos, settingsWeak);
}

private void tryPlaceLog(World world, BlockPos pos, Wood tree, BlockLog.EnumAxis axis)
{
Block block = world.getBlockState(pos).getBlock();
if (block == Blocks.AIR || block instanceof BlockLeavesTFC)
world.setBlockState(pos, BlockLogTFC.get(tree).getDefaultState().withProperty(LOG_AXIS, axis));
}
}
Expand Up @@ -9,8 +9,6 @@
import java.util.Random;

import net.minecraft.init.Blocks;
import net.minecraft.util.Mirror;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
Expand All @@ -23,7 +21,6 @@
import net.minecraft.world.gen.structure.template.TemplateManager;
import net.minecraftforge.fml.common.IWorldGenerator;

import net.dries007.tfc.Constants;
import net.dries007.tfc.objects.Wood;
import net.dries007.tfc.objects.biomes.BiomeTFC;
import net.dries007.tfc.objects.biomes.BiomesTFC;
Expand All @@ -38,12 +35,16 @@ public class WorldGenTrees implements IWorldGenerator
public static PlacementSettings getDefaultSettings()
{
return new PlacementSettings()
//.setMirror(Mirror.values()[rand.nextInt(Mirror.values().length)])
//.setRotation(Rotation.values()[rand.nextInt(Rotation.values().length)])
.setIgnoreEntities(false)
.setIgnoreStructureBlock(false)
.setReplacedBlock(Blocks.AIR);
}

public static PlacementSettings getRandomSettings(Random rand)
{
return getDefaultSettings()
//.setMirror(Mirror.values()[rand.nextInt(Mirror.values().length)])
.setRotation(Rotation.values()[rand.nextInt(Rotation.values().length)]);
}

public static boolean canGenerateTree(World world, BlockPos pos, Template tree, PlacementSettings settings, Wood treeType)
Expand Down Expand Up @@ -109,24 +110,4 @@ else if(rng < 0.8)
}

}

public void generateTree(TemplateManager manager, World world, BlockPos pos, Wood tree, Random rand)
{
// todo: change this to use some number somewhere of tree structure names
ResourceLocation loc = new ResourceLocation(Constants.MOD_ID, tree.name().toLowerCase() + "/" + "ashlarge1");
Template template = manager.getTemplate(world.getMinecraftServer(), loc);
BlockPos size = template.getSize();
pos = pos.add(-size.getX() / 2, 0, -size.getY() / 2);
PlacementSettings settings = new PlacementSettings()
.setMirror(Mirror.values()[rand.nextInt(Mirror.values().length)])
.setRotation(Rotation.values()[rand.nextInt(Rotation.values().length)])
.setIgnoreEntities(false)
.setIgnoreStructureBlock(false)
.setReplacedBlock(Blocks.AIR);

//if (canGenerateTree(world, pos, template, settings, tree))
{
template.addBlocksToWorld(world, pos, settings);
}
}
}

0 comments on commit 4437651

Please sign in to comment.