Working requests!

This commit is contained in:
Lizbeth Rika committed 2015-02-15 19:06:12 +00:00
1 parent b80dbf8b08
commit d0236bec2d
3 files changed
+203 -46

No files matched your search

@@ -29,6 +29,15 @@ public final class CorporeaHelper {
private static final List<IInventory> empty = Collections.unmodifiableList(new ArrayList());
private static final WeakHashMap<List<ICorporeaSpark>, List<IInventory>> cachedNetworks = new WeakHashMap();
/**
* How many items were matched in the last request. If java had "out" params like C# this wouldn't be needed :V
*/
public static int lastRequestMatches = 0;
/**
* How many items were extracted in the last request.
*/
public static int lastRequestExtractions = 0;
/**
* Gets a list of all the inventories on this spark network. This list is cached for use once every tick,
* and if something changes during that tick it'll still have the first result.
@@ -113,7 +122,7 @@ public final class CorporeaHelper {
for(int i = 0; i < inv.getSizeInventory(); i++) {
if(!isValidSlot(inv, i))
continue;
ItemStack stackAt = inv.getStackInSlot(i);
if(stacksMatch(stack, stackAt, checkNBT))
count += stackAt.stackSize;
@@ -132,7 +141,7 @@ public final class CorporeaHelper {
public static List<ItemStack> requestItem(ItemStack stack, ICorporeaSpark spark, boolean checkNBT, boolean doit) {
return requestItem(stack, stack.stackSize, spark, checkNBT, doit);
}
/**
* Bridge for requestItem() using a String and an item count.
*/
@@ -152,35 +161,42 @@ public final class CorporeaHelper {
public static List<ItemStack> requestItem(Object matcher, int itemCount, ICorporeaSpark spark, boolean checkNBT, boolean doit) {
List<IInventory> inventories = getInventoriesOnNetwork(spark);
List<ItemStack> stacks = new ArrayList();
lastRequestMatches = 0;
lastRequestExtractions = 0;
int count = itemCount;
checkInvs : {
for(IInventory inv : inventories) {
for(int i = 0; i < inv.getSizeInventory(); i++) {
if(!isValidSlot(inv, i))
continue;
for(IInventory inv : inventories) {
for(int i = 0; i < inv.getSizeInventory(); i++) {
if(!isValidSlot(inv, i))
continue;
ItemStack stackAt = inv.getStackInSlot(i);
if(matcher instanceof ItemStack ? stacksMatch((ItemStack) matcher, stackAt, checkNBT) : matcher instanceof String ? stacksMatch(stackAt, (String) matcher) : false) {
int rem = Math.min(stackAt.stackSize, count);
stacks.add(stackAt.copy());
if(doit) {
stackAt.stackSize -= rem;
if(stackAt.stackSize == 0)
inv.setInventorySlotContents(i, null);
}
count -= rem;
ItemStack stackAt = inv.getStackInSlot(i);
if(matcher instanceof ItemStack ? stacksMatch((ItemStack) matcher, stackAt, checkNBT) : matcher instanceof String ? stacksMatch(stackAt, (String) matcher) : false) {
int rem = Math.min(stackAt.stackSize, count);
if(count <= 0)
break checkInvs;
if(rem > 0) {
ItemStack copy = stackAt.copy();
if(rem < copy.stackSize)
copy.stackSize = rem;
stacks.add(copy);
}
lastRequestMatches += stackAt.stackSize;
lastRequestExtractions += rem;
if(doit && rem > 0) {
stackAt.stackSize -= rem;
if(stackAt.stackSize == 0)
inv.setInventorySlotContents(i, null);
}
count -= rem;
}
}
}
return stacks;
}
/**
* Gets the spark attached to the block in the coords passed in. Note that the coords passed
* in are for the block that the spark will be on, not the coords of the spark itself.
@@ -189,7 +205,7 @@ public final class CorporeaHelper {
List<ICorporeaSpark> sparks = world.getEntitiesWithinAABB(ICorporeaSpark.class, AxisAlignedBB.getBoundingBox(x, y + 1, z, x + 1, y + 2, z + 1));
return sparks.isEmpty() ? null : sparks.get(0);
}
/**
* Gets if the block in the coords passed in has a spark attached. Note that the coords passed
* in are for the block that the spark will be on, not the coords of the spark itself.
@@ -197,28 +213,28 @@ public final class CorporeaHelper {
public static boolean doesBlockHaveSpark(World world, int x, int y, int z) {
return getSparkForBlock(world, x, y, z) != null;
}
/**
* Gets if the slot passed in can be extracted from by a spark.
*/
public static boolean isValidSlot(IInventory inv, int slot) {
return !(inv instanceof ISidedInventory) || arrayHas(((ISidedInventory) inv).getAccessibleSlotsFromSide(ForgeDirection.UP.ordinal()), slot);
}
/**
* Gets if two stacks match.
*/
public static boolean stacksMatch(ItemStack stack1, ItemStack stack2, boolean checkNBT) {
return stack1 != null && stack2 != null && stack1.isItemEqual(stack2) && (!checkNBT || ItemStack.areItemStackTagsEqual(stack1, stack2));
}
/**
* Gets if the name of a stack matches the string passed in.
*/
public static boolean stacksMatch(ItemStack stack, String s) {
if(stack == null)
return false;
String name = stack.getDisplayName().toLowerCase().trim();
return name.equals(s) || (name + "s").equals(s) || (name + "es").equals(s) || (name.endsWith("y") && (name.substring(0, name.length() - 1) + "ies").equals(s));
}
@@ -230,7 +246,7 @@ public final class CorporeaHelper {
public static void clearCache() {
cachedNetworks.clear();
}
/**
* Helper method to check if an int array contains an int.
*/
@@ -238,7 +254,7 @@ public final class CorporeaHelper {
for(int i = 0; i < arr.length; i++)
if(arr[i] == val)
return true;
return false;
}
}
@@ -12,43 +12,141 @@ package vazkii.botania.common.block.tile.corporea;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.ChatStyle;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.event.ServerChatEvent;
import vazkii.botania.api.corporea.CorporeaHelper;
import vazkii.botania.api.corporea.ICorporeaSpark;
import vazkii.botania.common.block.ModBlocks;
import vazkii.botania.common.core.helper.MathHelper;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
public class TileCorporeaIndex extends TileCorporeaBase {
public static final double RADIUS = 2.5;
public static final InputHandler input = new InputHandler();
public static final Set<TileCorporeaIndex> indexes = Collections.newSetFromMap(new WeakHashMap());
private static final Map<Pattern, IRegexStacker> patterns = new LinkedHashMap();
/**
* (name) = Item name, or "this" for the name of the item in your hand
* (n), (n1), (n2), etc = Numbers
* [text] = Optional
* <a/b> = Either a or b
*/
static {
// (name) = 1
addPattern("(.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 1; }
@Override public String getName(Matcher m) { return m.group(1); }
});
// [a][n] (name) = 1
addPattern("a??n?? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 1; }
@Override public String getName(Matcher m) { return m.group(1); }
});
//(n)[x][ of] (name) = n
addPattern("(\\d+)x?(?: of)? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return i(m, 1); }
@Override public String getName(Matcher m) { return m.group(2); }
});
// [a ]stack[ of] (name) = 64
addPattern("(?:a )?stack(?: of)? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 64; }
@Override public String getName(Matcher m) { return m.group(1); }
});
// (n)[x] stack[s][ of] (name) = n * 64
addPattern("(\\d+)x?? stacks?(?: of)? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 64 * i(m, 1); }
@Override public String getName(Matcher m) { return m.group(2); }
});
// [a ]stack <and/+> (n)[x][ of] (name) = 64 + n
addPattern("(?:a )?stack (?:(?:and)|(?:\\+)) (\\d+)(?: of)? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 64 + i(m, 1); }
@Override public String getName(Matcher m) { return m.group(2); }
});
// (n1)[x] stack[s] <and/+> (n2)[x][ of] (name) = n1 * 64 + n2
addPattern("(\\d+)x?? stacks? (?:(?:and)|(?:\\+)) (\\d+)x?(?: of)? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 64 * i(m, 1) + i(m, 2); }
@Override public String getName(Matcher m) { return m.group(3); }
});
// [a ]half [of ][a ]stack[ of] (name) = 32
addPattern("(?:a )?half (?:of )?(?:a )?stack(?: of)? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 32; }
@Override public String getName(Matcher m) { return m.group(1); }
});
// [a ]quarter [of ][a ]stack[ of] (name) = 16
addPattern("(?:a )?quarter (?:of )?(?:a )?stack(?: of)? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 16; }
@Override public String getName(Matcher m) { return m.group(1); }
});
// [a ]dozen[ of] (name) = 12
addPattern("(?:a )?dozen(?: of)? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 12; }
@Override public String getName(Matcher m) { return m.group(1); }
});
// (n)[x] dozen[s][ of] (name) = n * 12
addPattern("(\\d+)x?? dozens?(?: of)? (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 12 * i(m, 1); }
@Override public String getName(Matcher m) { return m.group(2); }
});
// <all/every> [<of/the> ](name) = 2147483647
addPattern("(?:all|every) (?:(?:of|the) )?(.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return Integer.MAX_VALUE; }
@Override public String getName(Matcher m) { return m.group(1); }
});
// [the ]answer to life[,] the universe and everything [of ](name) = 42
addPattern("(?:the )?answer to life,? the universe and everything (?:of )?(.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 42; }
@Override public String getName(Matcher m) { return m.group(1); }
});
// <count/show/display/tell> (name) = 0 (display only)
addPattern("(?:count|show|display|tell) (.+)", new IRegexStacker() {
@Override public int getCount(Matcher m) { return 0; }
@Override public String getName(Matcher m) { return m.group(1); }
});
}
public int ticks = 0;
public int ticksWithCloseby = 0;
public float closeby = 0F;
public boolean hasCloseby;
@Override
public void updateEntity() {
super.updateEntity();
double x = xCoord + 0.5;
double y = yCoord + 0.5;
double z = zCoord + 0.5;
List<EntityPlayer> players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(x - RADIUS, y - RADIUS, z - RADIUS, x + RADIUS, y + RADIUS, z + RADIUS));
hasCloseby = false;
for(EntityPlayer player : players)
@@ -56,7 +154,7 @@ public class TileCorporeaIndex extends TileCorporeaBase {
hasCloseby = true;
break;
}
float step = 0.2F;
ticks++;
if(hasCloseby) {
@@ -65,11 +163,11 @@ public class TileCorporeaIndex extends TileCorporeaBase {
closeby += step;
} else if(closeby > 0F)
closeby -= step;
if(!isInvalid() && !indexes.contains(this))
indexes.add(this);
}
@Override
public void invalidate() {
super.invalidate();
@@ -81,7 +179,7 @@ public class TileCorporeaIndex extends TileCorporeaBase {
super.onChunkUnload();
indexes.remove(this);
}
@Override
public int getSizeInventory() {
return 1;
@@ -91,13 +189,26 @@ public class TileCorporeaIndex extends TileCorporeaBase {
public String getInventoryName() {
return null;
}
public static boolean isInRangeOfIndex(EntityPlayer player, TileCorporeaIndex index) {
return MathHelper.pointDistanceSpace(index.xCoord + 0.5, index.yCoord + 0.5, index.zCoord + 0.5, player.posX, player.posY, player.posZ) < RADIUS;
}
public static void addPattern(String pattern, IRegexStacker stacker) {
patterns.put(Pattern.compile(pattern), stacker);
}
public static int i(Matcher m, int g) {
try {
int i = Math.abs(Integer.parseInt(m.group(g)));
return i;
} catch(NumberFormatException e) {
return 0;
}
}
public static final class InputHandler {
@SubscribeEvent
public void onChatMessage(ServerChatEvent event) {
List<TileCorporeaIndex> nearbyIndexes = getNearbyIndexes(event.player);
@@ -106,19 +217,40 @@ public class TileCorporeaIndex extends TileCorporeaBase {
for(TileCorporeaIndex index : nearbyIndexes) {
ICorporeaSpark spark = index.getSpark();
if(spark != null) {
List<ItemStack> stacks = CorporeaHelper.requestItem(msg, 64, spark, true);
String matchedPattern = "";
String name = "";
int count = 0;
for(Pattern pattern : patterns.keySet()) {
Matcher matcher = pattern.matcher(msg);
if(matcher.matches()) {
IRegexStacker stacker = patterns.get(pattern);
count = stacker.getCount(matcher);
name = stacker.getName(matcher).toLowerCase().trim();
matchedPattern = pattern.toString();
}
}
if(name.equals("this")) {
ItemStack stack = event.player.getCurrentEquippedItem();
if(stack != null)
name = stack.getDisplayName().toLowerCase().trim();
}
List<ItemStack> stacks = CorporeaHelper.requestItem(name, count, spark, true);
for(ItemStack stack : stacks)
if(stack != null) {
EntityItem item = new EntityItem(index.worldObj, index.xCoord + 0.5, index.yCoord + 1.5, index.zCoord + 0.5, stack);
index.worldObj.spawnEntityInWorld(item);
}
event.player.addChatMessage(new ChatComponentTranslation("botaniamisc.requestMsg", count, name, CorporeaHelper.lastRequestMatches, CorporeaHelper.lastRequestExtractions).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.LIGHT_PURPLE)));
}
}
event.setCanceled(true);
}
}
public List<TileCorporeaIndex> getNearbyIndexes(EntityPlayer player) {
List<TileCorporeaIndex> indexList = new ArrayList();
for(TileCorporeaIndex index : indexes)
@@ -126,7 +258,15 @@ public class TileCorporeaIndex extends TileCorporeaBase {
indexList.add(index);
return indexList;
}
}
public static interface IRegexStacker {
public int getCount(Matcher m);
public String getName(Matcher m);
}
}