/* * Copyright (c) 2015 NOVA, All rights reserved. * This library is free software, licensed under GNU Lesser General Public License version 3 * * This file is part of NOVA. * * NOVA is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NOVA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NOVA. If not, see <http://www.gnu.org/licenses/>. */package nova.core.item; import nova.core.block.Block; import nova.core.block.BlockFactory; import nova.core.block.component.BlockProperty; import nova.core.entity.Entity; import nova.core.util.Direction; import nova.core.world.World; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import java.util.Optional; /** * An ItemBlock is an Item that is meant to be used to place blocks. * * @author Calclavia */ public class ItemBlock extends Item { public final BlockFactory blockFactory; public ItemBlock(BlockFactory blockFactory) { this.blockFactory = blockFactory; events.on(UseEvent.class).bind(this::onUse); } @Override public String getUnlocalizedName() { return blockFactory.getLocalizedName(); } @Override public String getLocalizedName() { return blockFactory.getLocalizedName(); } protected void onUse(UseEvent evt) { Optional<Block> opBlock = evt.entity.world().getBlock(evt.position); if (opBlock.isPresent()) { Block block = opBlock.get(); Vector3D placePos = block.shouldDisplacePlacement() ? evt.position.add(evt.side.toVector()) : evt.position; if (onPrePlace(evt.entity, evt.entity.world(), placePos, evt.side, evt.hit)) { evt.action = onPostPlace(evt.entity, evt.entity.world(), placePos, evt.side, evt.hit); } } } protected boolean onPrePlace(Entity entity, World world, Vector3D placePos, Direction side, Vector3D hit) { Optional<Block> checkBlock = world.getBlock(placePos); if (checkBlock.isPresent() && checkBlock.get().canReplace()) { return world.setBlock(placePos, blockFactory); } return false; } protected boolean onPostPlace(Entity entity, World world, Vector3D placePos, Direction side, Vector3D hit) { Optional<Block> opBlock = world.getBlock(placePos); if (opBlock.isPresent() && opBlock.get().sameType(blockFactory)) { //TODO: What if the block is NOT placed by a player? opBlock.get().events.publish(new Block.PlaceEvent(entity, side, hit, this)); opBlock.get().components.getOp(BlockProperty.BlockSound.class) .flatMap(sound -> sound.getSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE)) .ifPresent(sound -> world.playSoundAtPosition(placePos, sound)); } addCount(-1); return true; } }