Permalink
Browse files

Fixed up dispenser recipes a bit, and added fan/vacuum dispenser recipes

  • Loading branch information...
me4502 committed Dec 2, 2017
1 parent 8be9272 commit 3a821c99350bfd274fd88d264c04af68bfb930a3
@@ -17,10 +17,14 @@
package com.sk89q.craftbook.sponge.mechanics.dispenser;
import com.flowpowered.math.vector.Vector3d;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.tileentity.carrier.Dispenser;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.EntityTypes;
import org.spongepowered.api.entity.explosive.PrimedTNT;
import org.spongepowered.api.event.CauseStackManager;
import org.spongepowered.api.event.cause.EventContextKeys;
import org.spongepowered.api.event.cause.entity.spawn.SpawnTypes;
import org.spongepowered.api.item.ItemTypes;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.util.Direction;
@@ -43,8 +47,12 @@ public boolean doAction(Dispenser dispenser, ItemStack[] recipe, Vector3d veloci
if (face != Direction.NONE) {
Location<World> location = dispenser.getLocation().getRelative(face).add(0.5, 0.5, 0.5);
PrimedTNT tnt = (PrimedTNT) dispenser.getWorld().createEntity(EntityTypes.PRIMED_TNT, location.getPosition());
tnt.setVelocity(velocity.normalize().mul(2f));
dispenser.getWorld().spawnEntity(tnt);
Vector3d tntVelocity = face.asOffset().add(0, 0.1f, 0).normalize().mul(2f);
tnt.setVelocity(tntVelocity);
try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.CUSTOM);
dispenser.getWorld().spawnEntity(tnt);
}
return true;
}
@@ -24,7 +24,12 @@
import org.spongepowered.api.block.BlockTypes;
import org.spongepowered.api.block.tileentity.carrier.Dispenser;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.entity.ConstructEntityEvent;
import org.spongepowered.api.event.block.ChangeBlockEvent;
import org.spongepowered.api.event.cause.EventContextKeys;
import org.spongepowered.api.event.cause.entity.spawn.SpawnType;
import org.spongepowered.api.event.cause.entity.spawn.SpawnTypes;
import org.spongepowered.api.event.entity.SpawnEntityEvent;
import org.spongepowered.api.event.filter.cause.ContextValue;
import org.spongepowered.api.event.filter.cause.First;
import org.spongepowered.api.event.item.inventory.DropItemEvent;
import org.spongepowered.api.item.inventory.Inventory;
@@ -36,9 +41,10 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.annotation.Nullable;
@Module(id = "dispenserrecipes", name = "DispenserRecipes", onEnable = "onInitialize", onDisable = "onDisable")
public class DispenserRecipes extends SpongeBlockMechanic implements DocumentationProvider {
@@ -50,6 +56,7 @@ public void onInitialize() throws CraftBookException {
recipes.add(new Cannon());
recipes.add(new Fan());
recipes.add(new Vacuum());
}
@Override
@@ -75,20 +82,39 @@ public void onDispense(DropItemEvent.Dispense event, @First LocatableBlock dispe
}
@Listener
public void onCreateEntity(ConstructEntityEvent event, @First LocatableBlock dispenser) {
// TODO
public void onCreateEntity(SpawnEntityEvent event, @First LocatableBlock dispenser) {
event.getContext().get(EventContextKeys.SPAWN_TYPE).ifPresent(spawnType -> {
if (spawnType != SpawnTypes.DISPENSE || dispenser.getBlockState().getType() != BlockTypes.DISPENSER) {
return;
}
Dispenser dispenserTile = (Dispenser) dispenser.getLocation().getTileEntity().get();
if (handleDispenserAction(dispenserTile, event.getEntities().get(0).getVelocity())) {
event.setCancelled(true);
}
});
}
// TODO Water/Lava form
@Listener
public void onChangeBlock(ChangeBlockEvent event, @First LocatableBlock dispenser) {
if (dispenser.getBlockState().getType() != BlockTypes.DISPENSER) {
return;
}
Dispenser dispenserTile = (Dispenser) dispenser.getLocation().getTileEntity().get();
if (handleDispenserAction(dispenserTile, null)) {
event.setCancelled(true);
}
}
public boolean handleDispenserAction(Dispenser dispenser, Vector3d velocity) {
public boolean handleDispenserAction(Dispenser dispenser, @Nullable Vector3d velocity) {
for (DispenserRecipe recipe : recipes) {
ItemStack[] items = StreamSupport.stream(dispenser.getInventory().slots().spliterator(), false)
.map(Inventory::peek).filter(Optional::isPresent)
.map(Optional::get).toArray(ItemStack[]::new);
if (recipe.doesPass(items)) {
if (recipe.doAction(dispenser, items, velocity)) {
dispenser.getInventory().slots().forEach(Inventory::poll); // Take one of every stack.
dispenser.getInventory().slots().forEach(inv -> inv.poll(1)); // Take one of every stack.
return true;
}
@@ -17,9 +17,16 @@
package com.sk89q.craftbook.sponge.mechanics.dispenser;
import com.flowpowered.math.vector.Vector3d;
import com.sk89q.craftbook.sponge.util.LocationUtil;
import org.spongepowered.api.block.BlockTypes;
import org.spongepowered.api.block.tileentity.carrier.Dispenser;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.item.ItemTypes;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
public class Fan extends SimpleDispenserRecipe {
@@ -33,6 +40,19 @@ public Fan() {
@Override
public boolean doAction(Dispenser dispenser, ItemStack[] recipe, Vector3d velocity) {
Direction face = dispenser.getLocation().get(Keys.DIRECTION).orElse(Direction.NONE);
if (face != Direction.NONE) {
Location<World> offset = dispenser.getLocation().getRelative(face);
int distance = 0;
while (offset.getBlockType() == BlockTypes.AIR && distance < 5) {
for (Entity e : LocationUtil.getEntitiesAtLocation(offset)) {
e.setVelocity(face.asOffset().mul(5 - distance));
}
distance ++;
offset = offset.getRelative(face);
}
return true;
}
return false;
}
}
@@ -0,0 +1,42 @@
package com.sk89q.craftbook.sponge.mechanics.dispenser;
import com.flowpowered.math.vector.Vector3d;
import com.sk89q.craftbook.sponge.util.LocationUtil;
import org.spongepowered.api.block.BlockTypes;
import org.spongepowered.api.block.tileentity.carrier.Dispenser;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.item.ItemTypes;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
public class Vacuum extends SimpleDispenserRecipe {
public Vacuum() {
super(new ItemStack[]{
ItemStack.of(ItemTypes.WEB, 1), ItemStack.of(ItemTypes.LEAVES, 1), ItemStack.of(ItemTypes.WEB, 1),
ItemStack.of(ItemTypes.LEAVES, 1), ItemStack.of(ItemTypes.STICKY_PISTON, 1), ItemStack.of(ItemTypes.LEAVES, 1),
ItemStack.of(ItemTypes.WEB, 1), ItemStack.of(ItemTypes.LEAVES, 1), ItemStack.of(ItemTypes.WEB, 1),
});
}
@Override
public boolean doAction(Dispenser dispenser, ItemStack[] recipe, Vector3d velocity) {
Direction face = dispenser.getLocation().get(Keys.DIRECTION).orElse(Direction.NONE);
if (face != Direction.NONE) {
Location<World> offset = dispenser.getLocation().getRelative(face);
int distance = 0;
while (offset.getBlockType() == BlockTypes.AIR && distance < 5) {
for (Entity e : LocationUtil.getEntitiesAtLocation(offset)) {
e.setVelocity(face.asOffset().mul(5 - distance).mul(-1.0));
}
distance ++;
offset = offset.getRelative(face);
}
return true;
}
return false;
}
}
@@ -23,11 +23,14 @@
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.item.inventory.Carrier;
import org.spongepowered.api.item.inventory.Inventory;
import org.spongepowered.api.util.AABB;
import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.Chunk;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
@@ -106,7 +109,20 @@ public static boolean isWithinRadius(Location<World> location1, Location<World>
return radiusEntities;
}
public static boolean isLocationWithinWorld(Location location) {
public static boolean isEntityInLocation(Location<World> location, Entity entity) {
AABB boundingBox = entity.getBoundingBox().orElse(null);
return boundingBox != null && boundingBox.intersects(new AABB(location.getBlockPosition(), location.getBlockPosition().add(1, 1, 1)));
}
public static Collection<Entity> getEntitiesAtLocation(Location<World> location) {
Chunk chunk = location.getExtent().getChunk(location.getChunkPosition()).orElse(null);
if (chunk == null) {
return Collections.emptyList();
}
return chunk.getEntities(entity -> isEntityInLocation(location, entity));
}
public static boolean isLocationWithinWorld(Location<World> location) {
return location.getBlockY() < location.getExtent().getBlockMax().getY() && location.getBlockY() >= location.getExtent().getBlockMin().getY();
}

0 comments on commit 3a821c9

Please sign in to comment.