Skip to content

Commit

Permalink
Add Furnace Golem
Browse files Browse the repository at this point in the history
Added Furnace Golem and its specs (config, loot table, texture, etc). Also added heal ability as referenced in Issue #39 . Improved some GolemBase logic and deprecated a couple things.
  • Loading branch information
skyjay1 committed Nov 3, 2019
1 parent 652b0aa commit 87baec8
Show file tree
Hide file tree
Showing 16 changed files with 437 additions and 90 deletions.
11 changes: 8 additions & 3 deletions src/main/java/com/golems/entity/EntityBedrockGolem.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.golems.main.GolemItems;
import com.golems.util.GolemNames;

import net.minecraft.block.Block;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
Expand All @@ -15,6 +16,7 @@
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
Expand All @@ -24,7 +26,6 @@ public final class EntityBedrockGolem extends GolemBase {

public EntityBedrockGolem(final World world) {
super(world);
this.setCreativeReturn(new ItemStack(GolemItems.spawnBedrockGolem));
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.24D);
}

Expand Down Expand Up @@ -53,8 +54,7 @@ protected boolean processInteract(final EntityPlayer player, final EnumHand hand
if (!this.world.isRemote) {
this.setDead();
} else {
ItemBedrockGolem.spawnParticles(this.world, this.posX - 0.5D, this.posY + 0.1D,
this.posZ - 0.5D, 0.1D);
ItemBedrockGolem.spawnParticles(this.world, this.posX, this.posY + 0.1D, this.posZ, 0.1D);
}
}

Expand All @@ -71,6 +71,11 @@ public SoundEvent getGolemSound() {
return SoundEvents.BLOCK_STONE_STEP;
}

@Override
public ItemStack getPickedResult(final RayTraceResult target) {
return new ItemStack(GolemItems.spawnBedrockGolem);
}

@Override
public List<String> addSpecialDesc(final List<String> list) {
list.add(TextFormatting.WHITE + "" + TextFormatting.BOLD + trans("entitytip.indestructible"));
Expand Down
270 changes: 270 additions & 0 deletions src/main/java/com/golems/entity/EntityFurnaceGolem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
package com.golems.entity;

import java.util.List;

import com.golems.items.ItemBedrockGolem;
import com.golems.main.ExtraGolems;
import com.golems.util.GolemNames;

import net.minecraft.client.gui.GuiScreen;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.ai.EntityAITempt;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.tileentity.TileEntityFurnace;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;

public final class EntityFurnaceGolem extends GolemBase {

private static final DataParameter<Integer> FUEL = EntityDataManager.createKey(EntityFurnaceGolem.class,
DataSerializers.VARINT);
private static final String KEY_FUEL = "FuelRemaining";

private static final ResourceLocation LIT = makeTexture(ExtraGolems.MODID, GolemNames.FURNACE_GOLEM + "_lit");
private static final ResourceLocation UNLIT = makeTexture(ExtraGolems.MODID, GolemNames.FURNACE_GOLEM + "_unlit");

public static final String FUEL_FACTOR = "Burn Time";
public static final int MAX_FUEL = 102400;
public final int fuelBurnFactor;

public EntityFurnaceGolem(final World world) {
super(world);
fuelBurnFactor = Math.max(1, getConfig(this).getInt(FUEL_FACTOR));
}

@Override
protected void entityInit() {
super.entityInit();
this.getDataManager().register(FUEL, Integer.valueOf(0));
}

@Override
protected void initEntityAI() {
super.initEntityAI();
this.tasks.addTask(0, new InertGoal(this));
this.tasks.addTask(1, new UseFuelGoal(this));
this.tasks.addTask(1, new EntityAITempt(this, 0.7D, Items.COAL, false));
}

@Override
public void onLivingUpdate() {
super.onLivingUpdate();
if(this.world.isRemote && rand.nextInt(24) == 0) {
// particle effects
final double pMotion = 0.03D;
world.spawnParticle(this.hasFuel() ? EnumParticleTypes.FLAME : EnumParticleTypes.SMOKE_NORMAL,
this.posX + world.rand.nextDouble() * 0.4D - 0.2D + this.motionX * 8,
this.posY + world.rand.nextDouble() * 0.5D + this.height / 3.0D,
this.posZ + world.rand.nextDouble() * 0.4D - 0.2D + this.motionZ * 8,
world.rand.nextDouble() * pMotion - pMotion * 0.5D,
world.rand.nextDouble() * pMotion * 0.75D,
world.rand.nextDouble() * pMotion - pMotion * 0.5D);
}
}

@Override
public void readEntityFromNBT(final NBTTagCompound tag) {
super.readEntityFromNBT(tag);
this.setFuel(tag.getInteger(KEY_FUEL));
}

@Override
public void writeEntityToNBT(final NBTTagCompound tag) {
super.writeEntityToNBT(tag);
tag.setInteger(KEY_FUEL, getFuel());
}

@Override
protected boolean processInteract(final EntityPlayer player, final EnumHand hand) {
// allow player to add fuel to the golem by clicking on them with a fuel item
ItemStack stack = player.getHeldItem(hand);
int burnTime = getBurnAmount(stack);
if(burnTime > 0 && getFuel() < MAX_FUEL) {
if(player.isSneaking()) {
// take entire ItemStack
this.addFuel(burnTime * stack.getCount());
stack = stack.getItem().getContainerItem(stack);
} else {
// take one item from ItemStack
this.addFuel(burnTime);
if(stack.getCount() > 1) {
stack.shrink(1);
} else {
stack = stack.getItem().getContainerItem(stack);
}
}
// update the player's held item
player.setHeldItem(hand, stack);
// add particles
ItemBedrockGolem.spawnParticles(this.world, this.posX, this.posY + this.height / 3.0D,
this.posZ, 0.03D, EnumParticleTypes.FLAME, 10);
return true;
}

// allow player to remove burn time by using a water bucket
if(stack.getItem() == Items.WATER_BUCKET) {
this.setFuel(0);
player.setHeldItem(hand, stack.getItem().getContainerItem(stack));
ItemBedrockGolem.spawnParticles(this.world, this.posX, this.posY + this.height / 3.0D,
this.posZ, 0.1D, EnumParticleTypes.SMOKE_LARGE, 15);
return true;
}

return super.processInteract(player, hand);
}

private static int getBurnAmount(final ItemStack i) {
return TileEntityFurnace.getItemBurnTime(i);
}

@Override
public ResourceLocation getTextureType() {
return hasFuel() ? LIT : UNLIT;
}

@Override
protected ResourceLocation applyTexture() {
// apply TEMPORARY texture to avoid NPE. Actual texture is first applied in
// onLivingUpdate
return makeTexture(ExtraGolems.MODID, GolemNames.CLAY_GOLEM);
}

@Override
public SoundEvent getGolemSound() {
return SoundEvents.BLOCK_STONE_STEP;
}

public boolean hasFuel() {
return getFuel() > 0;
}

/** @return the current fuel level as a number **/
public int getFuel() {
return this.getDataManager().get(FUEL).intValue();
}

/** @return a number between 0.0 and 1.0 to indicate fuel level **/
public float getFuelPercentage() {
return (float)getFuel() / (float)MAX_FUEL;
}

public void setFuel(final int fuel) {
if(getFuel() != fuel) {
this.getDataManager().set(FUEL, Integer.valueOf(fuel));
}
}

public void addFuel(final int toAdd) {
if(toAdd != 0) {
this.getDataManager().set(FUEL, getFuel() + toAdd);
}
}

@Override
public List<String> addSpecialDesc(final List<String> list) {
// add special
list.add(TextFormatting.GRAY + trans("entitytip.use_fuel"));
// add fuel amount to the tooltip
final int fuel = this.getFuel();
if(fuel > 0) {
final int percentFuel = (int)Math.ceil(this.getFuelPercentage() * 100F);
final TextFormatting color;
if(percentFuel < 6) {
color = TextFormatting.RED;
} else if(percentFuel < 16) {
color = TextFormatting.YELLOW;
} else {
color = TextFormatting.WHITE;
}
// if sneaking, show exact value, otherwise show percentage value
final String fuelString = GuiScreen.isShiftKeyDown() ? Integer.toString(fuel) : (Integer.toString(percentFuel) + "%");
// actually add the description
list.add(TextFormatting.GRAY + trans("entitytip.fuel") + ": " + color + fuelString);
}
return list;
}

class UseFuelGoal extends EntityAIBase {

private final EntityFurnaceGolem golem;

protected UseFuelGoal(final EntityFurnaceGolem entity) {
super();
golem = entity;
}

@Override
public boolean shouldExecute() {
// only uses fuel every X ticks
return golem.isServerWorld() && golem.getFuel() > 0 && golem.ticksExisted % golem.fuelBurnFactor == 0;
}

@Override
public boolean shouldContinueExecuting() {
return false;
}

@Override
public void startExecuting() {
golem.addFuel(-1);
}
}

class InertGoal extends EntityAIBase {

private final EntityFurnaceGolem golem;

protected InertGoal(final EntityFurnaceGolem entity) {
super();
this.setMutexBits(1 | 2 | 4);
golem = entity;
}

@Override
public boolean shouldExecute() {
return !golem.hasFuel();
}

@Override
public boolean shouldContinueExecuting() {
return false;
}

@Override
public void startExecuting() {
updateTask();
}

@Override
public void updateTask() {
// freeze the golem and ai tasks
golem.motionX = 0D;
golem.motionZ = 0D;
golem.setMoveForward(0F);
golem.setMoveStrafing(0F);
golem.getMoveHelper().setMoveTo(golem.posX, golem.posY, golem.posZ, 0.1D);
golem.setJumping(false);
golem.setAttackTarget(null);
golem.setRevengeTarget(null);
golem.getNavigator().clearPath();
golem.rotationPitch = golem.prevRotationPitch;
golem.rotationYaw = golem.prevRotationYaw;
// set looking down
final double lookX = golem.getLookVec().x;
final double lookY = Math.toRadians(-75D);
final double lookZ = golem.getLookVec().z;
golem.getLookHelper().setLookPosition(lookX, lookY, lookZ, golem.getHorizontalFaceSpeed(), golem.getVerticalFaceSpeed());
}
}
}
3 changes: 2 additions & 1 deletion src/main/java/com/golems/entity/EntityWoolGolem.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.init.Blocks;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.util.SoundEvent;
Expand Down Expand Up @@ -43,7 +44,7 @@ public void onLivingUpdate() {

@Override
public ItemStack getCreativeReturn() {
ItemStack woolStack = super.getCreativeReturn();
ItemStack woolStack = new ItemStack(Blocks.WOOL);
woolStack.setItemDamage(this.getTextureNum() % (coloredWoolTypes.length + 1));
return woolStack;
}
Expand Down
Loading

0 comments on commit 87baec8

Please sign in to comment.