Package forestry.core.gadgets

Source Code of forestry.core.gadgets.NaturalistGame$GameToken

/*******************************************************************************
* Copyright (c) 2011-2014 SirSengir.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-3.0.txt
*
* Various Contributors including, but not limited to:
* SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges
******************************************************************************/
package forestry.core.gadgets;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;

import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;

import forestry.api.core.INBTTagable;
import forestry.api.genetics.AlleleManager;
import forestry.api.genetics.IIndividual;
import forestry.api.genetics.ISpeciesRoot;
import forestry.core.utils.StringUtil;
import forestry.core.utils.Utils;

public class NaturalistGame implements INBTTagable {

  public static final int BOUNTY_MAX = 16;

  public static class GameToken implements INBTTagable {

    private static final String[] OVERLAY_NONE = new String[0];
    private static final String[] OVERLAY_FAILED = new String[] { "errors/errored" };

    public ItemStack tokenStack;

    protected boolean isFailed = false;
    protected boolean isProbed = false;
    protected boolean isRevealed = false;

    public GameToken(ItemStack tokenStack) {
      this.tokenStack = tokenStack;
    }

    public GameToken(NBTTagCompound nbttagcompound) {
      readFromNBT(nbttagcompound);
    }

    @Override
    public void readFromNBT(NBTTagCompound nbttagcompound) {
      isFailed = nbttagcompound.getBoolean("isFailed");
      isProbed = nbttagcompound.getBoolean("isProbed");
      isRevealed = nbttagcompound.getBoolean("isRevealed");

      if(nbttagcompound.hasKey("tokenStack")) {
        tokenStack = ItemStack.loadItemStackFromNBT(nbttagcompound.getCompoundTag("tokenStack"));
      }
    }

    @Override
    public void writeToNBT(NBTTagCompound nbttagcompound) {
      nbttagcompound.setBoolean("isFailed", isFailed);
      nbttagcompound.setBoolean("isProbed", isProbed);
      nbttagcompound.setBoolean("isRevealed", isRevealed);

      if(tokenStack != null) {
        NBTTagCompound stackcompound = new NBTTagCompound();
        tokenStack.writeToNBT(stackcompound);
        nbttagcompound.setTag("tokenStack", stackcompound);
      }
    }

    public boolean isVisible() {
      return isRevealed;
    }

    public int getTokenColour() {
      if(tokenStack == null || !isVisible())
        return 0xffffff;

      if(isProbed)
        return Utils.multiplyRGBComponents(AlleleManager.alleleRegistry.getIndividual(tokenStack).getGenome().getPrimary().getIconColour(0), 0.7f);
      else
        return AlleleManager.alleleRegistry.getIndividual(tokenStack).getGenome().getPrimary().getIconColour(0);
    }

    public String getTooltip() {
      return tokenStack != null ? tokenStack.getDisplayName() : StringUtil.localize("gui.unknown");
    }

    public String[] getOverlayIcons() {
      return isFailed ? OVERLAY_FAILED : OVERLAY_NONE;
    }

    public boolean matches(GameToken other) {
      return tokenStack.isItemEqual(other.tokenStack) && ItemStack.areItemStackTagsEqual(tokenStack, other.tokenStack);
    }
  }

  private final Random rand = new Random();
  private GameToken[] gameTokens;
  private long lastUpdate;

  private boolean isEnded;
  private int bountyLevel;

  public long getLastUpdate() {
    return lastUpdate;
  }

  /* SAVING & LOADING */
  @Override
  public void writeToNBT(NBTTagCompound nbttagcompound) {
    nbttagcompound.setBoolean("isEnded", isEnded);
    nbttagcompound.setInteger("bountyLevel", bountyLevel);
    nbttagcompound.setLong("lastUpdate", lastUpdate);

    if(gameTokens != null) {
      nbttagcompound.setInteger("TokenCount", gameTokens.length);
      NBTTagList nbttaglist = new NBTTagList();

      for (int i = 0; i < gameTokens.length; i++) {
        if(gameTokens[i] == null)
          continue;

        NBTTagCompound nbttagcompound2 = new NBTTagCompound();
        nbttagcompound2.setByte("Slot", (byte) i);
        gameTokens[i].writeToNBT(nbttagcompound2);
        nbttaglist.appendTag(nbttagcompound2);
      }

      nbttagcompound.setTag("GameTokens", nbttaglist);
    } else
      nbttagcompound.setInteger("TokenCount", 0);

  }

  @Override
  public void readFromNBT(NBTTagCompound nbttagcompound) {
    isEnded = nbttagcompound.getBoolean("isEnded");
    bountyLevel = nbttagcompound.getInteger("bountyLevel");
    lastUpdate = nbttagcompound.getLong("lastUpdate");

    int tokenCount = nbttagcompound.getInteger("TokenCount");
    if(tokenCount > 0) {
      gameTokens = new GameToken[tokenCount];
      NBTTagList nbttaglist = nbttagcompound.getTagList("GameTokens", 10);

      for (int j = 0; j < nbttaglist.tagCount(); ++j) {
        NBTTagCompound nbttagcompound2 = nbttaglist.getCompoundTagAt(j);
        int index = nbttagcompound2.getByte("Slot");
        gameTokens[index] = new GameToken(nbttagcompound2);
      }
    }

    lastUpdate = System.currentTimeMillis();
  }

  /* INTERACTION */
  public void initialize(ItemStack specimen) {
    IIndividual individual = AlleleManager.alleleRegistry.getIndividual(specimen);
    if(individual == null) {
      return;
    }

    int boardSize = individual.getGenome().getPrimary().getComplexity() + individual.getGenome().getSecondary().getComplexity();
    if(boardSize % 2 != 0)
      boardSize = Math.round((float)boardSize / 2) * 2;
    boardSize = boardSize <= 22 ? boardSize >= 6 ? boardSize : 6 : 22;

    isEnded = false;
    bountyLevel = BOUNTY_MAX;
    gameTokens = new GameToken[boardSize];

    ISpeciesRoot root = individual.getGenome().getPrimary().getRoot();
    ArrayList<ItemStack> pairs = new ArrayList<ItemStack>();
    for(int i = 0; i < boardSize / 2; i++) {
      IIndividual token = root.templateAsIndividual(root.getRandomTemplate(rand));
      pairs.add(root.getMemberStack(token, 0));
    }

    boolean first = true;
    for(ItemStack pair : pairs) {
      if(first) {
        gameTokens[0] = new GameToken(pair.copy());
        first = false;
      } else
        gameTokens[getFreeTokenIndex()] = new GameToken(pair.copy());
      gameTokens[getFreeTokenIndex()] = new GameToken(pair.copy());
    }

    lastUpdate = System.currentTimeMillis();
  }

  private int getFreeTokenIndex() {
    while(true) {
      int probe = rand.nextInt(gameTokens.length);
      if(gameTokens[probe] == null)
        return probe;
    }
  }

  private int countUnrevealedTokens() {
    int count = 0;
    for(GameToken token : gameTokens)
      if(!token.isRevealed)
        count++;

    return count;
  }

  private int[] getUnrevealedTokens(int count) {
    ArrayList<Integer> existing = new ArrayList<Integer>();
    int remaining = countUnrevealedTokens();
    int[] unrevealed = new int[count < remaining ? count : remaining];

    for(int i = 0; i < unrevealed.length; i++) {

      int found = -1;
      while(found < 0) {
        int probe = rand.nextInt(gameTokens.length);
        if(gameTokens[probe].isRevealed)
          continue;

        boolean taken = false;
        for(int exist : existing) {
          if(exist == probe) {
            taken = true;
            break;
          }
        }
        if(!taken) {
          existing.add(probe);
          found = probe;
        }
      }
      unrevealed[i] = found;
    }

    return unrevealed;
  }

  public void probe(ItemStack specimen, IInventory inventory, int startSlot, int slotCount) {
    if(gameTokens == null)
      return;
    if(isEnded)
      return;
    IIndividual individual = AlleleManager.alleleRegistry.getIndividual(specimen);
    if(individual == null)
      return;

    hideProbedTokens();
    if(bountyLevel > 1)
      bountyLevel--;

    int[] tokenIndices = getUnrevealedTokens(getSampleSize() <= slotCount ? getSampleSize() : slotCount);
    int processedTokens = 0;

    for(int i = 0; i < slotCount; i++) {
      ItemStack sample = inventory.getStackInSlot(startSlot + i);
      if(sample == null || sample.stackSize <= 0)
        continue;

      sample = inventory.decrStackSize(startSlot + i, 1);
      if(rand.nextFloat() >= individual.getGenome().getPrimary().getResearchSuitability(sample)) {
        continue;
      }

      gameTokens[tokenIndices[processedTokens]].isProbed = true;
      gameTokens[tokenIndices[processedTokens]].isRevealed = true;

      processedTokens++;
      if(processedTokens >= tokenIndices.length)
        break;
    }

    lastUpdate = System.currentTimeMillis();
  }

  public void choose(int tokenIndex) {
    if(isEnded)
      return;
    if(gameTokens == null || tokenIndex >= gameTokens.length)
      return;
    if(gameTokens[tokenIndex].isRevealed && !gameTokens[tokenIndex].isProbed)
      return;
    hideProbedTokens();

    Collection<GameToken> singles = getRevealedSingles(gameTokens[tokenIndex]);
    if(singles.size() > 0) {
      boolean matched = false;
      for(GameToken single : singles) {
        if(single.matches(gameTokens[tokenIndex])) {
          matched = true;
          break;
        }
      }
      if(!matched) {
        gameTokens[tokenIndex].isFailed = true;
      }
    }
    gameTokens[tokenIndex].isRevealed = true;
    checkGameEnd();
    lastUpdate = System.currentTimeMillis();
  }

  public void reset() {
    gameTokens = null;
    lastUpdate = System.currentTimeMillis();
  }

  public boolean isInited() {
    return gameTokens != null;
  }

  public boolean isEnded() {
    return isEnded;
  }

  public int getBountyLevel() {
    return bountyLevel;
  }

  public boolean isWon() {
    if(!isEnded)
      return false;

    return !isLost();
  }

  private void checkGameEnd() {
    if(isLost())
      isEnded = true;
    if(isRevealed())
      isEnded = true;
  }

  private boolean isRevealed() {
    for(GameToken token : gameTokens)
      if(!token.isRevealed)
        return false;

    return true;
  }
  private boolean isLost() {
    for(GameToken token : gameTokens) {
      if(token.isFailed)
        return true;
    }

    return false;
  }

  private void hideProbedTokens() {
    for(GameToken token : gameTokens) {
      if(token.isProbed) {
        token.isRevealed = false;
        token.isProbed = false;
      }
    }
  }

  private Collection<GameToken> getRevealedSingles(GameToken exclude) {
    ArrayList<GameToken> singles = new ArrayList<GameToken>();

    for(GameToken token : gameTokens) {
      if(!token.isRevealed)
        continue;
      if(token == exclude)
        continue;

      GameToken matching = null;
      for(GameToken single : singles) {
        if(!single.matches(token))
          continue;
        matching = single;
        break;
      }

      if(matching == null)
        singles.add(token);
      else
        singles.remove(matching);
    }

    return singles;
  }

  /* RETRIEVAL */
  public int getBoardSize() {
    return gameTokens != null ? gameTokens.length : 0;
  }

  public int getSampleSize() {
    if(gameTokens == null)
      return 0;

    int samples = gameTokens.length / 4;
    return samples >= 2 ? samples : 2;
  }

  public GameToken getToken(int index) {
    return gameTokens != null ? index < gameTokens.length ? gameTokens[index] : null : null;
  }

  public void setToken(int index, NBTTagCompound nbttagcompound) {
    if(gameTokens == null)
      gameTokens = new GameToken[24];
    gameTokens[index] = new GameToken(nbttagcompound);
  }
}
TOP

Related Classes of forestry.core.gadgets.NaturalistGame$GameToken

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.