PageRenderTime 2ms CodeModel.GetById 49ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeAdapter.java

http://github.com/sk89q/worldedit
Java | 243 lines | 188 code | 28 blank | 27 comment | 20 complexity | 27e6d4fc4b5fb8700299ba99b641c656 MD5 | raw file
  1/*
  2 * WorldEdit, a Minecraft world manipulation toolkit
  3 * Copyright (C) sk89q <http://www.sk89q.com>
  4 * Copyright (C) WorldEdit team and contributors
  5 *
  6 * This program is free software: you can redistribute it and/or modify it
  7 * under the terms of the GNU Lesser General Public License as published by the
  8 * Free Software Foundation, either version 3 of the License, or
  9 * (at your option) any later version.
 10 *
 11 * This program is distributed in the hope that it will be useful, but WITHOUT
 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 14 * for more details.
 15 *
 16 * You should have received a copy of the GNU Lesser General Public License
 17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 18 */
 19
 20package com.sk89q.worldedit.forge;
 21
 22import com.google.common.collect.ImmutableList;
 23import com.sk89q.jnbt.CompoundTag;
 24import com.sk89q.jnbt.Tag;
 25import com.sk89q.worldedit.blocks.BaseItemStack;
 26import com.sk89q.worldedit.forge.internal.NBTConverter;
 27import com.sk89q.worldedit.math.BlockVector3;
 28import com.sk89q.worldedit.math.Vector3;
 29import com.sk89q.worldedit.registry.state.BooleanProperty;
 30import com.sk89q.worldedit.registry.state.DirectionalProperty;
 31import com.sk89q.worldedit.registry.state.EnumProperty;
 32import com.sk89q.worldedit.registry.state.IntegerProperty;
 33import com.sk89q.worldedit.registry.state.Property;
 34import com.sk89q.worldedit.util.Direction;
 35import com.sk89q.worldedit.world.World;
 36import com.sk89q.worldedit.world.biome.BiomeType;
 37import com.sk89q.worldedit.world.biome.BiomeTypes;
 38import com.sk89q.worldedit.world.block.BlockState;
 39import com.sk89q.worldedit.world.block.BlockType;
 40import com.sk89q.worldedit.world.block.BlockTypes;
 41import com.sk89q.worldedit.world.item.ItemType;
 42import com.sk89q.worldedit.world.item.ItemTypes;
 43import net.minecraft.block.Block;
 44import net.minecraft.entity.player.ServerPlayerEntity;
 45import net.minecraft.item.Item;
 46import net.minecraft.item.ItemStack;
 47import net.minecraft.nbt.CompoundNBT;
 48import net.minecraft.state.DirectionProperty;
 49import net.minecraft.state.IProperty;
 50import net.minecraft.state.StateContainer;
 51import net.minecraft.util.IStringSerializable;
 52import net.minecraft.util.ResourceLocation;
 53import net.minecraft.util.math.BlockPos;
 54import net.minecraft.util.math.Vec3d;
 55import net.minecraft.world.biome.Biome;
 56import net.minecraftforge.registries.ForgeRegistries;
 57
 58import java.util.Comparator;
 59import java.util.Map;
 60import java.util.TreeMap;
 61import java.util.stream.Collectors;
 62
 63import static com.google.common.base.Preconditions.checkNotNull;
 64
 65public final class ForgeAdapter {
 66
 67    private ForgeAdapter() {
 68    }
 69
 70    public static World adapt(net.minecraft.world.World world) {
 71        return new ForgeWorld(world);
 72    }
 73
 74    public static Biome adapt(BiomeType biomeType) {
 75        return ForgeRegistries.BIOMES.getValue(new ResourceLocation(biomeType.getId()));
 76    }
 77
 78    public static BiomeType adapt(Biome biome) {
 79        return BiomeTypes.get(biome.getRegistryName().toString());
 80    }
 81
 82    public static Vector3 adapt(Vec3d vector) {
 83        return Vector3.at(vector.x, vector.y, vector.z);
 84    }
 85
 86    public static BlockVector3 adapt(BlockPos pos) {
 87        return BlockVector3.at(pos.getX(), pos.getY(), pos.getZ());
 88    }
 89
 90    public static Vec3d toVec3(BlockVector3 vector) {
 91        return new Vec3d(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
 92    }
 93
 94    public static net.minecraft.util.Direction adapt(Direction face) {
 95        switch (face) {
 96            case NORTH: return net.minecraft.util.Direction.NORTH;
 97            case SOUTH: return net.minecraft.util.Direction.SOUTH;
 98            case WEST: return net.minecraft.util.Direction.WEST;
 99            case EAST: return net.minecraft.util.Direction.EAST;
100            case DOWN: return net.minecraft.util.Direction.DOWN;
101            case UP:
102            default:
103                return net.minecraft.util.Direction.UP;
104        }
105    }
106
107    public static Direction adaptEnumFacing(net.minecraft.util.Direction face) {
108        switch (face) {
109            case NORTH: return Direction.NORTH;
110            case SOUTH: return Direction.SOUTH;
111            case WEST: return Direction.WEST;
112            case EAST: return Direction.EAST;
113            case DOWN: return Direction.DOWN;
114            case UP:
115            default:
116                return Direction.UP;
117        }
118    }
119
120    public static BlockPos toBlockPos(BlockVector3 vector) {
121        return new BlockPos(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
122    }
123
124    public static Property<?> adaptProperty(IProperty<?> property) {
125        if (property instanceof net.minecraft.state.BooleanProperty) {
126            return new BooleanProperty(property.getName(), ImmutableList.copyOf(((net.minecraft.state.BooleanProperty) property).getAllowedValues()));
127        }
128        if (property instanceof net.minecraft.state.IntegerProperty) {
129            return new IntegerProperty(property.getName(), ImmutableList.copyOf(((net.minecraft.state.IntegerProperty) property).getAllowedValues()));
130        }
131        if (property instanceof DirectionProperty) {
132            return new DirectionalProperty(property.getName(), ((DirectionProperty) property).getAllowedValues().stream()
133                    .map(ForgeAdapter::adaptEnumFacing)
134                    .collect(Collectors.toList()));
135        }
136        if (property instanceof net.minecraft.state.EnumProperty) {
137            // Note: do not make x.getName a method reference.
138            // It will cause runtime bootstrap exceptions.
139            return new EnumProperty(property.getName(), ((net.minecraft.state.EnumProperty<?>) property).getAllowedValues().stream()
140                    .map(x -> x.getName())
141                    .collect(Collectors.toList()));
142        }
143        return new IPropertyAdapter<>(property);
144    }
145
146    public static Map<Property<?>, Object> adaptProperties(BlockType block, Map<IProperty<?>, Comparable<?>> mcProps) {
147        Map<Property<?>, Object> props = new TreeMap<>(Comparator.comparing(Property::getName));
148        for (Map.Entry<IProperty<?>, Comparable<?>> prop : mcProps.entrySet()) {
149            Object value = prop.getValue();
150            if (prop.getKey() instanceof DirectionProperty) {
151                value = adaptEnumFacing((net.minecraft.util.Direction) value);
152            } else if (prop.getKey() instanceof net.minecraft.state.EnumProperty) {
153                value = ((IStringSerializable) value).getName();
154            }
155            props.put(block.getProperty(prop.getKey().getName()), value);
156        }
157        return props;
158    }
159
160    private static net.minecraft.block.BlockState applyProperties(StateContainer<Block, net.minecraft.block.BlockState> stateContainer, net.minecraft.block.BlockState newState, Map<Property<?>, Object> states) {
161        for (Map.Entry<Property<?>, Object> state : states.entrySet()) {
162            IProperty property = stateContainer.getProperty(state.getKey().getName());
163            Comparable value = (Comparable) state.getValue();
164            // we may need to adapt this value, depending on the source prop
165            if (property instanceof DirectionProperty) {
166                Direction dir = (Direction) value;
167                value = adapt(dir);
168            } else if (property instanceof net.minecraft.state.EnumProperty) {
169                String enumName = (String) value;
170                value = ((net.minecraft.state.EnumProperty<?>) property).parseValue((String) value).orElseGet(() -> {
171                    throw new IllegalStateException("Enum property " + property.getName() + " does not contain " + enumName);
172                });
173            }
174
175            newState = newState.with(property, value);
176        }
177        return newState;
178    }
179
180    public static net.minecraft.block.BlockState adapt(BlockState blockState) {
181        Block mcBlock = adapt(blockState.getBlockType());
182        net.minecraft.block.BlockState newState = mcBlock.getDefaultState();
183        Map<Property<?>, Object> states = blockState.getStates();
184        return applyProperties(mcBlock.getStateContainer(), newState, states);
185    }
186
187    public static BlockState adapt(net.minecraft.block.BlockState blockState) {
188        BlockType blockType = adapt(blockState.getBlock());
189        return blockType.getState(adaptProperties(blockType, blockState.getValues()));
190    }
191
192    public static Block adapt(BlockType blockType) {
193        return ForgeRegistries.BLOCKS.getValue(new ResourceLocation(blockType.getId()));
194    }
195
196    public static BlockType adapt(Block block) {
197        return BlockTypes.get(ForgeRegistries.BLOCKS.getKey(block).toString());
198    }
199
200    public static Item adapt(ItemType itemType) {
201        return ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemType.getId()));
202    }
203
204    public static ItemType adapt(Item item) {
205        return ItemTypes.get(ForgeRegistries.ITEMS.getKey(item).toString());
206    }
207
208    public static ItemStack adapt(BaseItemStack baseItemStack) {
209        CompoundNBT forgeCompound = null;
210        if (baseItemStack.getNbtData() != null) {
211            forgeCompound = NBTConverter.toNative(baseItemStack.getNbtData());
212        }
213        final ItemStack itemStack = new ItemStack(adapt(baseItemStack.getType()), baseItemStack.getAmount());
214        itemStack.setTag(forgeCompound);
215        return itemStack;
216    }
217
218    public static BaseItemStack adapt(ItemStack itemStack) {
219        CompoundTag tag = NBTConverter.fromNative(itemStack.serializeNBT());
220        if (tag.getValue().isEmpty()) {
221            tag = null;
222        } else {
223            final Tag tagTag = tag.getValue().get("tag");
224            if (tagTag instanceof CompoundTag) {
225                tag = ((CompoundTag) tagTag);
226            } else {
227                tag = null;
228            }
229        }
230        return new BaseItemStack(adapt(itemStack.getItem()), tag, itemStack.getCount());
231    }
232
233    /**
234     * Get the WorldEdit proxy for the given player.
235     *
236     * @param player the player
237     * @return the WorldEdit player
238     */
239    public static ForgePlayer adaptPlayer(ServerPlayerEntity player) {
240        checkNotNull(player);
241        return new ForgePlayer(player);
242    }
243}