Package vazkii.botania.common.entity

Source Code of vazkii.botania.common.entity.EntitySpark

/**
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
* Botania is Open Source and distributed under a
* Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License
* (http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_GB)
*
* File Created @ [Aug 21, 2014, 5:43:44 PM (GMT)]
*/
package vazkii.botania.common.entity;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import vazkii.botania.api.mana.IManaItem;
import vazkii.botania.api.mana.IManaPool;
import vazkii.botania.api.mana.spark.ISparkAttachable;
import vazkii.botania.api.mana.spark.ISparkEntity;
import vazkii.botania.api.mana.spark.SparkHelper;
import vazkii.botania.common.Botania;
import vazkii.botania.common.core.helper.Vector3;
import vazkii.botania.common.item.ModItems;
import baubles.common.lib.PlayerHandler;

public class EntitySpark extends Entity implements ISparkEntity {

  private static final int TRANSFER_RATE = 1000;
  private static final String TAG_UPGRADE = "upgrade";
  int removeTransferants = 2;
  boolean didStartupParticles = false;

  public EntitySpark(World world) {
    super(world);
    isImmuneToFire = true;
  }

  @Override
  protected void entityInit() {
    setSize(0.5F, 0.5F);
    dataWatcher.addObject(28, 0);
    dataWatcher.addObject(29, "");

    dataWatcher.setObjectWatched(28);
    dataWatcher.setObjectWatched(29);
  }

  @Override
  public void onUpdate() {
    super.onUpdate();

    ISparkAttachable tile = getAttachedTile();
    if(tile == null) {
      if(!worldObj.isRemote)
        setDead();
      return;
    }


    List<ISparkEntity> allSparks = SparkHelper.getSparksAround(worldObj, posX, posY, posZ);
    if(worldObj.isRemote && !didStartupParticles) {
      for(ISparkEntity spark : allSparks) {
        Entity e = (Entity) spark;
        Vector3 orig = new Vector3(e.posX , e.posY + 0.25, e.posZ);
        Vector3 end = new Vector3(posX, posY + 0.25, posZ);
        Vector3 diff = end.copy().sub(orig);
        Vector3 movement = diff.copy().normalize().multiply(0.05);
        int iters = (int) (diff.mag() / movement.mag());
        float huePer = 1F / iters;
        float hueSum = (float) Math.random();

        Vector3 currentPos = orig.copy();
        for(int i = 0; i < iters; i++) {
          float hue = i * huePer + hueSum;
          Color color = Color.getHSBColor(hue, 1F, 1F);
          float r = Math.min(1F, color.getRed() / 255F + 0.4F);
          float g = Math.min(1F, color.getGreen() / 255F + 0.4F);
          float b = Math.min(1F, color.getBlue() / 255F + 0.4F);

          Botania.proxy.setSparkleFXNoClip(true);
          Botania.proxy.sparkleFX(worldObj, currentPos.x, currentPos.y, currentPos.z, r, g, b, 0.6F, 12);
          Botania.proxy.setSparkleFXNoClip(false);
          currentPos.add(movement);
        }
      }

      didStartupParticles = true;
    }

    Collection<ISparkEntity> transfers = getTransfers();

    int upgrade = getUpgrade();
    if(upgrade != 0) {
      switch(upgrade) {
      case 1 : { // Dispersive
        List<EntityPlayer> players = SparkHelper.getEntitiesAround(EntityPlayer.class, worldObj, posX, posY, posZ);

        Map<EntityPlayer, Map<ItemStack, Integer>> receivingPlayers = new HashMap();

        ItemStack input = new ItemStack(ModItems.spark);
        for(EntityPlayer player : players) {
          List<ItemStack> stacks = new ArrayList();
          stacks.addAll(Arrays.asList(player.inventory.mainInventory));
          stacks.addAll(Arrays.asList(player.inventory.armorInventory));
          stacks.addAll(Arrays.asList(PlayerHandler.getPlayerBaubles(player).stackList));

          for(ItemStack stack : stacks) {
            if(stack == null || !(stack.getItem() instanceof IManaItem))
              continue;

            IManaItem manaItem = (IManaItem) stack.getItem();
            if(manaItem.canReceiveManaFromItem(stack, input)) {
              Map receivingStacks;
              boolean add = false;
              if(!receivingPlayers.containsKey(player)) {
                add = true;
                receivingStacks = new HashMap();
              } else receivingStacks = receivingPlayers.get(player);

              int recv = Math.min(getAttachedTile().getCurrentMana(), Math.min(TRANSFER_RATE, manaItem.getMaxMana(stack) - manaItem.getMana(stack)));
              if(recv > 0) {
                receivingStacks.put(stack, recv);
                if(add)
                  receivingPlayers.put(player, receivingStacks);
              }
            }
          }
        }

        if(!receivingPlayers.isEmpty()) {
          List<EntityPlayer> keys = new ArrayList(receivingPlayers.keySet());
          Collections.shuffle(keys);
          EntityPlayer player = keys.iterator().next();

          Map<ItemStack, Integer> items = receivingPlayers.get(player);
          ItemStack stack = items.keySet().iterator().next();
          int cost = items.get(stack);
          int manaToPut = Math.min(getAttachedTile().getCurrentMana(), cost);
          ((IManaItem) stack.getItem()).addMana(stack, manaToPut);
          getAttachedTile().recieveMana(-manaToPut);
          particlesTowards(player);
        }

        break;
      }
      case 2 : { // Dominant
        for(ISparkEntity spark : allSparks) {
          if(spark == this)
            continue;

          int upgrade_ = spark.getUpgrade();
          if(upgrade_ == 0)
            spark.registerTransfer(this);
        }
        break;
      }
      case 3 : { // Recessive
        for(ISparkEntity spark : allSparks) {
          if(spark == this)
            continue;

          int upgrade_ = spark.getUpgrade();
          if(upgrade_ != 2 && upgrade_ != 3 && upgrade_ != 4)
            transfers.add(spark);
        }
        break;
      }
      }
    }

    if(!transfers.isEmpty()) {
      int manaTotal = Math.min(TRANSFER_RATE * transfers.size(), tile.getCurrentMana());
      int manaForEach = manaTotal / transfers.size();
      if(manaForEach > transfers.size()) {
        for(ISparkEntity spark : transfers) {
          if(spark.getAttachedTile() == null || spark.getAttachedTile().isFull() || spark.areIncomingTransfersDone()) {
            manaTotal -= manaForEach;
            continue;
          }

          ISparkAttachable attached = spark.getAttachedTile();
          attached.recieveMana(manaForEach);

          particlesTowards((Entity) spark);
        }
        tile.recieveMana(-manaTotal);
      }
    }

    if(removeTransferants > 0)
      removeTransferants--;
  }

  void particlesTowards(Entity e) {
    Vector3 thisVec = Vector3.fromEntityCenter(this).add(0, 0, 0);
    Vector3 receiverVec = Vector3.fromEntityCenter(e).add(0, 0, 0);

    double rc = 0.45;
    thisVec.add((Math.random() - 0.5) * rc, (Math.random() - 0.5) * rc, (Math.random() - 0.5) * rc);
    receiverVec.add((Math.random() - 0.5) * rc, (Math.random() - 0.5) * rc, (Math.random() - 0.5) * rc);

    Vector3 motion = receiverVec.copy().sub(thisVec);
    motion.multiply(0.04F);
    float r = 0.4F + 0.3F * (float) Math.random();
    float g = 0.4F + 0.3F * (float) Math.random();
    float b = 0.4F + 0.3F * (float) Math.random();
    float size = 0.125F + 0.125F * (float) Math.random();

    Botania.proxy.wispFX(worldObj, thisVec.x, thisVec.y, thisVec.z, r, g, b, size, (float) motion.x, (float) motion.y, (float) motion.z);
  }

  @Override
  public boolean canBeCollidedWith() {
    return true;
  }

  @Override
  public boolean interactFirst(EntityPlayer player) {
    ItemStack stack = player.getCurrentEquippedItem();
    if(stack != null) {
      int upgrade = getUpgrade();
      if(stack.getItem() == ModItems.twigWand) {
        if(player.isSneaking()) {
          if(upgrade > 0) {
            if(!worldObj.isRemote)
              entityDropItem(new ItemStack(ModItems.sparkUpgrade, 1, upgrade - 1), 0F);
            setUpgrade(0);

            dataWatcher.updateObject(29, "");
            removeTransferants = 2;
          } else setDead();
          if(player.worldObj.isRemote)
            player.swingItem();
          return true;
        } else {
          didStartupParticles = false;
          return true;
        }
      } else if(stack.getItem() == ModItems.sparkUpgrade && upgrade == 0) {
        int newUpgrade = stack.getItemDamage() + 1;
        setUpgrade(newUpgrade);
        stack.stackSize--;
        if(player.worldObj.isRemote)
          player.swingItem();
        return true;
      }
    }

    return false;
  }

  @Override
  protected void readEntityFromNBT(NBTTagCompound cmp) {
    setUpgrade(cmp.getInteger(TAG_UPGRADE));
  }

  @Override
  protected void writeEntityToNBT(NBTTagCompound cmp) {
    cmp.setInteger(TAG_UPGRADE, getUpgrade());
  }

  @Override
  public void setDead() {
    super.setDead();
    if(!worldObj.isRemote) {
      int upgrade = getUpgrade();
      entityDropItem(new ItemStack(ModItems.spark), 0F);
      if(upgrade > 0)
        entityDropItem(new ItemStack(ModItems.sparkUpgrade, 1, upgrade - 1), 0F);
    }
  }

  @Override
  public ISparkAttachable getAttachedTile() {
    int x = MathHelper.floor_double(posX);
    int y = MathHelper.floor_double(posY) - 1;
    int z = MathHelper.floor_double(posZ);
    TileEntity tile = worldObj.getTileEntity(x, y, z);
    if(tile != null && tile instanceof ISparkAttachable)
      return (ISparkAttachable) tile;

    return null;
  }


  @Override
  public Collection<ISparkEntity> getTransfers() {
    Collection<ISparkEntity> entities = new ArrayList();
    String transfers = dataWatcher.getWatchableObjectString(29);
    String[] tokens = transfers.split(";");
    List<String> removals = new ArrayList();

    for(String s : tokens) {
      if(s.isEmpty())
        continue;

      int id = Integer.parseInt(s);
      boolean added = false;
      Entity e = worldObj.getEntityByID(id);
      if(e != null && e instanceof ISparkEntity) {
        ISparkEntity spark = (ISparkEntity) e;
        if(spark != this && !spark.areIncomingTransfersDone() && spark.getAttachedTile() != null && !spark.getAttachedTile().isFull() && (getUpgrade() == 0 && spark.getUpgrade() == 2 || getUpgrade() == 3 && (spark.getUpgrade() == 0 || spark.getUpgrade() == 1) || !(spark.getAttachedTile() instanceof IManaPool))) {
          entities.add((ISparkEntity) e);
          added = true;
        }
      }

      if(!added)
        removals.add(s);
    }

    if(!removals.isEmpty()) {
      String newTranfers = "";
      for(String s : tokens)
        if(!removals.contains(s))
          newTranfers = newTranfers + (newTranfers.isEmpty() ? "" : ";") + s;
      dataWatcher.updateObject(29, newTranfers);

      removals.clear();
    }

    return entities;
  }

  @Override
  public void registerTransfer(ISparkEntity entity) {
    if(worldObj.isRemote || getTransfers().contains(entity))
      return;

    String transfers = dataWatcher.getWatchableObjectString(29);
    dataWatcher.updateObject(29, transfers + (transfers.isEmpty() ? "" : ";") + ((Entity) entity).getEntityId());
  }

  @Override
  public int getUpgrade() {
    return dataWatcher.getWatchableObjectInt(28);
  }

  @Override
  public void setUpgrade(int upgrade) {
    dataWatcher.updateObject(28, upgrade);
  }

  @Override
  public boolean areIncomingTransfersDone() {
    ISparkAttachable tile = getAttachedTile();
    if(tile instanceof IManaPool)
      return removeTransferants > 0;

      return tile != null && tile.areIncomingTranfersDone();
  }

}
TOP

Related Classes of vazkii.botania.common.entity.EntitySpark

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.