private void XOChange(World w, int x, int y, int z, int XO, int power) {

    if (!(worldObj.getBlock(x, y, z) instanceof ArenaCellBlock)
        || worldObj.getTileEntity(x, y, z) == null) // Not valid for testing
    return;
    ArenaCellEntity ace = (ArenaCellEntity) worldObj.getTileEntity(x, y, z);

    if (ace.stackIn == null) // Nothing here
    return;
    CardStruct csIn = Databank.getCard(CardStruct.getCdwd(ace.stackIn));

    if (csIn == null || csIn.getPower() == 0) { // Unregistered card or zero power
      invalidateField();
      return;
    }

    Logs.debug("XOC at " + x + "/" + y + "/" + z);
    Logs.debug("Entry power: " + power);

    if (power > csIn.getPower()) { // Raw power overwrite
      ace.XOwnership = XO;
      w.markBlockForUpdate(x, y, z);

      XOChange(w, x + 1, y, z, XO, csIn.getPower());
      XOChange(w, x - 1, y, z, XO, csIn.getPower());
      XOChange(w, x, y, z + 1, XO, csIn.getPower());
      XOChange(w, x, y, z - 1, XO, csIn.getPower());
    }
  }
  private boolean subAce(
      World w, int x1, int y1, int z1, int x2, int y2, int z2, int XO, int power) {
    ArenaCellEntity ace1, ace2;
    CardStruct cs1, cs2;
    int max, min;

    if (!(w.getBlock(x1, y1, z1) instanceof ArenaCellBlock)
        || !(w.getBlock(x2, y2, z2) instanceof ArenaCellBlock)) // Not an ACB
    return false;

    if ((ace1 = (ArenaCellEntity) w.getTileEntity(x1, y1, z1)) == null
        || (ace2 = (ArenaCellEntity) w.getTileEntity(x2, y2, z2)) == null) // Missing ACE
    return false;

    if (ace1.stackIn == null || ace2.stackIn == null) // No cards to compare to
    return false;

    if (ace1.XOwnership == XO || ace2.XOwnership == XO) // Only works with non XO cards
    return false;

    cs1 = Databank.getCard(CardStruct.getCdwd(ace1.stackIn));
    cs2 = Databank.getCard(CardStruct.getCdwd(ace2.stackIn));

    if (cs1 == null || cs2 == null || cs1.getPower() < 1 || cs2.getPower() < 1) {
      invalidateField();
      return false;
    }

    if (cs1.getPower() == cs2.getPower()) return false;

    min = cs1.getPower() < cs2.getPower() ? cs1.getPower() : cs2.getPower();
    max = cs1.getPower() > cs2.getPower() ? cs1.getPower() : cs2.getPower();

    Logs.debug("subAce: OK - XO " + XO);
    Logs.debug("1: " + x1 + "/" + y1 + "/" + z1);
    Logs.debug("2: " + x2 + "/" + y2 + "/" + z2);

    if (max - min == power) {
      return true;
    }

    return false;
  }
  private void XOForceChange(
      World w, int x, int y, int z, int XO) { // Been checked xms ago by subAce
    ArenaCellEntity ace = (ArenaCellEntity) worldObj.getTileEntity(x, y, z); // Overriden ace
    CardStruct csIn = Databank.getCard(CardStruct.getCdwd(ace.stackIn));

    ace.XOwnership = XO;
    w.markBlockForUpdate(x, y, z);
    Logs.debug("XOF cdwd: " + csIn.toString());

    XOChange(w, x + 1, y, z, XO, csIn.getPower());
    XOChange(w, x - 1, y, z, XO, csIn.getPower());
    XOChange(w, x, y, z + 1, XO, csIn.getPower());
    XOChange(w, x, y, z - 1, XO, csIn.getPower());
  }
  public boolean canAcceptStack(ItemStack stack) {
    CardStruct cs;

    if (stackIn != null
        || !CardStruct.isValidStack(stack)) // Got already a card stocked or the stack is invalid
    return false;
    cs = Databank.getCard(CardStruct.getCdwd(stack));

    if (cs == null || cs.getPower() < 1) // Zero power value
    return false;

    if (!gameUsable) // Can't be used by current game
    return false;

    return true;
  }
  public boolean put(ItemStack stack) {
    boolean subn = false, subs = false, subw = false, sube = false;

    if (!canAcceptStack(stack)) return false;

    NBTTagCompound cpy = new NBTTagCompound();
    CardStruct csIn =
        Databank.getCard(
            CardStruct.getCdwd(stack)); // Card exist when placed. No mistakes about here

    stack.writeToNBT(cpy); // Shaddy method to get a clean copy of the stack, shhh
    stackIn = ItemStack.loadItemStackFromNBT(cpy);
    stackIn.stackSize = 1;

    ownership = wft; // Telling who's owning the card
    XOwnership = wft; // Telling who's owning the card gameplay wise
    putLoop(
        worldObj, xCoord, yCoord, zCoord, wft == 1 ? 2 : 1); // Update next ownership for all tiles
    resetLoopControl();

    if (subAce(
        worldObj,
        xCoord,
        yCoord,
        zCoord - 1,
        xCoord,
        yCoord,
        zCoord + 1,
        XOwnership,
        csIn.getPower())) // NS
    subn = subs = true;
    if (subAce(
        worldObj,
        xCoord - 1,
        yCoord,
        zCoord,
        xCoord + 1,
        yCoord,
        zCoord,
        XOwnership,
        csIn.getPower())) // WE
    subw = sube = true;

    if (subAce(
        worldObj,
        xCoord,
        yCoord,
        zCoord - 1,
        xCoord - 1,
        yCoord,
        zCoord,
        XOwnership,
        csIn.getPower())) // NW
    subn = subw = true;
    if (subAce(
        worldObj,
        xCoord,
        yCoord,
        zCoord - 1,
        xCoord + 1,
        yCoord,
        zCoord,
        XOwnership,
        csIn.getPower())) // NE
    subn = sube = true;
    if (subAce(
        worldObj,
        xCoord,
        yCoord,
        zCoord + 1,
        xCoord - 1,
        yCoord,
        zCoord,
        XOwnership,
        csIn.getPower())) // SW
    subs = subw = true;
    if (subAce(
        worldObj,
        xCoord,
        yCoord,
        zCoord + 1,
        xCoord + 1,
        yCoord,
        zCoord,
        XOwnership,
        csIn.getPower())) // SE
    subs = sube = true;
    Logs.debug("Sub: N" + subn + "/S" + subs + "/W" + subw + "/E" + sube);

    if (subn) XOForceChange(worldObj, xCoord, yCoord, zCoord - 1, XOwnership);
    if (subs) XOForceChange(worldObj, xCoord, yCoord, zCoord + 1, XOwnership);

    if (subw) XOForceChange(worldObj, xCoord - 1, yCoord, zCoord, XOwnership);
    if (sube) XOForceChange(worldObj, xCoord + 1, yCoord, zCoord, XOwnership);

    XOChange(worldObj, xCoord + 1, yCoord, zCoord, XOwnership, csIn.getPower());
    XOChange(worldObj, xCoord - 1, yCoord, zCoord, XOwnership, csIn.getPower());
    XOChange(worldObj, xCoord, yCoord, zCoord + 1, XOwnership, csIn.getPower());
    XOChange(worldObj, xCoord, yCoord, zCoord - 1, XOwnership, csIn.getPower());

    return true;
  }