Did a lot of work on the behaviour of the Inversion Pillar. Also added a Corrupted Zombie for later testing.
This commit is contained in:
parent
d1455920ec
commit
e9549fd9db
|
@ -0,0 +1,15 @@
|
||||||
|
package WayofTime.bloodmagic.client.render.entity;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.entity.Render;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderManager;
|
||||||
|
import net.minecraftforge.fml.client.registry.IRenderFactory;
|
||||||
|
import WayofTime.bloodmagic.entity.mob.EntityCorruptedZombie;
|
||||||
|
|
||||||
|
public class CorruptedZombieRenderFactory implements IRenderFactory<EntityCorruptedZombie>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Render<? super EntityCorruptedZombie> createRenderFor(RenderManager manager)
|
||||||
|
{
|
||||||
|
return new RenderCorruptedZombie(manager);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
package WayofTime.bloodmagic.client.render.entity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.ModelBiped;
|
||||||
|
import net.minecraft.client.model.ModelZombie;
|
||||||
|
import net.minecraft.client.model.ModelZombieVillager;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderBiped;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderManager;
|
||||||
|
import net.minecraft.client.renderer.entity.layers.LayerBipedArmor;
|
||||||
|
import net.minecraft.client.renderer.entity.layers.LayerCustomHead;
|
||||||
|
import net.minecraft.client.renderer.entity.layers.LayerHeldItem;
|
||||||
|
import net.minecraft.client.renderer.entity.layers.LayerRenderer;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
import WayofTime.bloodmagic.entity.mob.EntityCorruptedZombie;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public class RenderCorruptedZombie extends RenderBiped<EntityCorruptedZombie>
|
||||||
|
{
|
||||||
|
private static final ResourceLocation ZOMBIE_TEXTURES = new ResourceLocation("bloodmagic", "textures/entities/zombie_raw.png");
|
||||||
|
private final ModelBiped defaultModel;
|
||||||
|
private final ModelZombieVillager zombieVillagerModel;
|
||||||
|
private final List<LayerRenderer<EntityCorruptedZombie>> defaultLayers;
|
||||||
|
|
||||||
|
public RenderCorruptedZombie(RenderManager renderManagerIn)
|
||||||
|
{
|
||||||
|
super(renderManagerIn, new ModelZombie(), 0.5F, 1.0F);
|
||||||
|
LayerRenderer<?> layerrenderer = (LayerRenderer) this.layerRenderers.get(0);
|
||||||
|
this.defaultModel = this.modelBipedMain;
|
||||||
|
this.zombieVillagerModel = new ModelZombieVillager();
|
||||||
|
this.addLayer(new LayerHeldItem(this));
|
||||||
|
LayerBipedArmor layerbipedarmor = new LayerBipedArmor(this)
|
||||||
|
{
|
||||||
|
protected void initArmor()
|
||||||
|
{
|
||||||
|
this.modelLeggings = new ModelZombie(0.5F, true);
|
||||||
|
this.modelArmor = new ModelZombie(1.0F, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.addLayer(layerbipedarmor);
|
||||||
|
this.defaultLayers = Lists.newArrayList(this.layerRenderers);
|
||||||
|
|
||||||
|
if (layerrenderer instanceof LayerCustomHead)
|
||||||
|
{
|
||||||
|
this.removeLayer(layerrenderer);
|
||||||
|
this.addLayer(new LayerCustomHead(this.zombieVillagerModel.bipedHead));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.removeLayer(layerbipedarmor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the render to do state modifications necessary before the model is
|
||||||
|
* rendered.
|
||||||
|
*/
|
||||||
|
protected void preRenderCallback(EntityCorruptedZombie entitylivingbaseIn, float partialTickTime)
|
||||||
|
{
|
||||||
|
super.preRenderCallback(entitylivingbaseIn, partialTickTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the desired {@code T} type Entity.
|
||||||
|
*/
|
||||||
|
public void doRender(EntityCorruptedZombie entity, double x, double y, double z, float entityYaw, float partialTicks)
|
||||||
|
{
|
||||||
|
this.swapArmor(entity);
|
||||||
|
super.doRender(entity, x, y, z, entityYaw, partialTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the location of an entity's texture. Doesn't seem to be called
|
||||||
|
* unless you call Render.bindEntityTexture.
|
||||||
|
*/
|
||||||
|
protected ResourceLocation getEntityTexture(EntityCorruptedZombie entity)
|
||||||
|
{
|
||||||
|
|
||||||
|
{
|
||||||
|
return ZOMBIE_TEXTURES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void swapArmor(EntityCorruptedZombie zombie)
|
||||||
|
{
|
||||||
|
|
||||||
|
{
|
||||||
|
this.mainModel = this.defaultModel;
|
||||||
|
this.layerRenderers = this.defaultLayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.modelBipedMain = (ModelBiped) this.mainModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void rotateCorpse(EntityCorruptedZombie entityLiving, float p_77043_2_, float p_77043_3_, float partialTicks)
|
||||||
|
{
|
||||||
|
|
||||||
|
super.rotateCorpse(entityLiving, p_77043_2_, p_77043_3_, partialTicks);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,227 @@
|
||||||
|
package WayofTime.bloodmagic.entity.mob;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.SharedMonsterAttributes;
|
||||||
|
import net.minecraft.entity.ai.EntityAIAttackMelee;
|
||||||
|
import net.minecraft.entity.monster.EntityCreeper;
|
||||||
|
import net.minecraft.entity.monster.EntityGhast;
|
||||||
|
import net.minecraft.init.SoundEvents;
|
||||||
|
import net.minecraft.item.ItemBow;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.SoundEvent;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.EnumDifficulty;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import WayofTime.bloodmagic.api.Constants;
|
||||||
|
import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
|
||||||
|
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
|
||||||
|
import WayofTime.bloodmagic.entity.ai.EntityAIAttackRangedBow;
|
||||||
|
|
||||||
|
public class EntityCorruptedZombie extends EntityDemonBase
|
||||||
|
{
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
protected EnumDemonWillType type = EnumDemonWillType.DEFAULT;
|
||||||
|
|
||||||
|
private final EntityAIAttackRangedBow aiArrowAttack = new EntityAIAttackRangedBow(this, 1.0D, 20, 15.0F);
|
||||||
|
private final EntityAIAttackMelee aiAttackOnCollide = new EntityAIAttackMelee(this, 1.0D, false);
|
||||||
|
|
||||||
|
private final int attackPriority = 3;
|
||||||
|
|
||||||
|
public EntityCorruptedZombie(World worldIn)
|
||||||
|
{
|
||||||
|
super(worldIn);
|
||||||
|
this.setSize(0.6F, 1.95F);
|
||||||
|
// ((PathNavigateGround) getNavigator()).setCanSwim(false);
|
||||||
|
|
||||||
|
this.setCombatTask();
|
||||||
|
// this.targetTasks.addTask(8, new EntityAINearestAttackableTarget<EntityMob>(this, EntityMob.class, 10, true, false, new TargetPredicate(this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyEntityAttributes()
|
||||||
|
{
|
||||||
|
super.applyEntityAttributes();
|
||||||
|
getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(40.0D);
|
||||||
|
getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(6.0D);
|
||||||
|
getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.27D);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCombatTask()
|
||||||
|
{
|
||||||
|
if (this.worldObj != null && !this.worldObj.isRemote)
|
||||||
|
{
|
||||||
|
this.tasks.removeTask(this.aiAttackOnCollide);
|
||||||
|
this.tasks.removeTask(this.aiArrowAttack);
|
||||||
|
ItemStack itemstack = this.getHeldItemMainhand();
|
||||||
|
|
||||||
|
if (itemstack != null && itemstack.getItem() instanceof ItemBow)
|
||||||
|
{
|
||||||
|
int i = 20;
|
||||||
|
|
||||||
|
if (this.worldObj.getDifficulty() != EnumDifficulty.HARD)
|
||||||
|
{
|
||||||
|
i = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.aiArrowAttack.setAttackCooldown(i);
|
||||||
|
this.tasks.addTask(attackPriority, this.aiArrowAttack);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
this.tasks.addTask(attackPriority, this.aiAttackOnCollide);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attackEntityFrom(DamageSource source, float amount)
|
||||||
|
{
|
||||||
|
return this.isEntityInvulnerable(source) ? false : super.attackEntityFrom(source, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redone from EntityMob to prevent despawning on peaceful.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean attackEntityAsMob(Entity attackedEntity)
|
||||||
|
{
|
||||||
|
boolean flag = super.attackEntityAsMob(attackedEntity);
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
//EMPTY
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param toHeal
|
||||||
|
* @return Amount of Will consumed from the Aura to heal
|
||||||
|
*/
|
||||||
|
public double absorbWillFromAuraToHeal(double toHeal)
|
||||||
|
{
|
||||||
|
if (worldObj.isRemote)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double healthMissing = this.getMaxHealth() - this.getHealth();
|
||||||
|
if (healthMissing <= 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double will = WorldDemonWillHandler.getCurrentWill(worldObj, getPosition(), getType());
|
||||||
|
|
||||||
|
toHeal = Math.min(healthMissing, Math.min(toHeal, will / getWillToHealth()));
|
||||||
|
if (toHeal > 0)
|
||||||
|
{
|
||||||
|
this.heal((float) toHeal);
|
||||||
|
return WorldDemonWillHandler.drainWill(worldObj, getPosition(), getType(), toHeal * getWillToHealth(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getWillToHealth()
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canDespawn()
|
||||||
|
{
|
||||||
|
return !this.isTamed() && super.canDespawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onUpdate()
|
||||||
|
{
|
||||||
|
if (!this.worldObj.isRemote && this.ticksExisted % 20 == 0)
|
||||||
|
{
|
||||||
|
absorbWillFromAuraToHeal(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeEntityToNBT(NBTTagCompound tag)
|
||||||
|
{
|
||||||
|
super.writeEntityToNBT(tag);
|
||||||
|
|
||||||
|
tag.setString(Constants.NBT.WILL_TYPE, type.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readEntityFromNBT(NBTTagCompound tag)
|
||||||
|
{
|
||||||
|
super.readEntityFromNBT(tag);
|
||||||
|
|
||||||
|
if (!tag.hasKey(Constants.NBT.WILL_TYPE))
|
||||||
|
{
|
||||||
|
type = EnumDemonWillType.DEFAULT;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
type = EnumDemonWillType.valueOf(tag.getString(Constants.NBT.WILL_TYPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setCombatTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Change to fit the given AI
|
||||||
|
@Override
|
||||||
|
public boolean shouldAttackEntity(EntityLivingBase attacker, EntityLivingBase owner)
|
||||||
|
{
|
||||||
|
if (!(attacker instanceof EntityCreeper) && !(attacker instanceof EntityGhast))
|
||||||
|
{
|
||||||
|
return super.shouldAttackEntity(attacker, owner);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getAmbientSound()
|
||||||
|
{
|
||||||
|
return SoundEvents.ENTITY_COW_AMBIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getHurtSound()
|
||||||
|
{
|
||||||
|
return SoundEvents.ENTITY_COW_HURT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getDeathSound()
|
||||||
|
{
|
||||||
|
return SoundEvents.ENTITY_COW_DEATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void playStepSound(BlockPos pos, Block block)
|
||||||
|
{
|
||||||
|
this.playSound(SoundEvents.ENTITY_COW_STEP, 0.15F, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the volume for the sounds this mob makes.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected float getSoundVolume()
|
||||||
|
{
|
||||||
|
return 0.4F;
|
||||||
|
}
|
||||||
|
}
|
|
@ -198,4 +198,52 @@ public class InversionPillarHandler
|
||||||
|
|
||||||
return new ArrayList<BlockPos>();
|
return new ArrayList<BlockPos>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<BlockPos> getAllConnectedPillars(World world, EnumDemonWillType type, BlockPos pos)
|
||||||
|
{
|
||||||
|
List<BlockPos> checkedPosList = new ArrayList<BlockPos>();
|
||||||
|
List<BlockPos> uncheckedPosList = new ArrayList<BlockPos>(); //Positions where we did not check their connections.
|
||||||
|
|
||||||
|
uncheckedPosList.add(pos);
|
||||||
|
|
||||||
|
int dim = world.provider.getDimension();
|
||||||
|
if (nearPillarMap.containsKey(dim))
|
||||||
|
{
|
||||||
|
Map<EnumDemonWillType, Map<BlockPos, List<BlockPos>>> willMap = nearPillarMap.get(dim);
|
||||||
|
if (willMap.containsKey(type))
|
||||||
|
{
|
||||||
|
Map<BlockPos, List<BlockPos>> posMap = willMap.get(type);
|
||||||
|
// This is where the magic happens.
|
||||||
|
|
||||||
|
while (!uncheckedPosList.isEmpty())
|
||||||
|
{
|
||||||
|
//Positions that are new this iteration and need to be dumped into uncheckedPosList next iteration.
|
||||||
|
List<BlockPos> newPosList = new ArrayList<BlockPos>();
|
||||||
|
|
||||||
|
Iterator<BlockPos> itr = uncheckedPosList.iterator();
|
||||||
|
while (itr.hasNext())
|
||||||
|
{
|
||||||
|
BlockPos checkPos = itr.next();
|
||||||
|
List<BlockPos> posList = posMap.get(checkPos);
|
||||||
|
if (posList != null)
|
||||||
|
{
|
||||||
|
for (BlockPos testPos : posList)
|
||||||
|
{
|
||||||
|
//Check if the position has already been checked, is scheduled to be checked, or is already found it needs to be checked.
|
||||||
|
if (!checkedPosList.contains(testPos) && !uncheckedPosList.contains(testPos) && !newPosList.contains(testPos))
|
||||||
|
{
|
||||||
|
newPosList.add(testPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedPosList.addAll(uncheckedPosList);
|
||||||
|
uncheckedPosList = newPosList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkedPosList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,12 @@ import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import net.minecraft.util.text.TextComponentTranslation;
|
import net.minecraft.util.text.TextComponentTranslation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.WorldServer;
|
|
||||||
import WayofTime.bloodmagic.api.altar.IBloodAltar;
|
import WayofTime.bloodmagic.api.altar.IBloodAltar;
|
||||||
import WayofTime.bloodmagic.api.iface.IAltarReader;
|
import WayofTime.bloodmagic.api.iface.IAltarReader;
|
||||||
import WayofTime.bloodmagic.api.util.helper.NetworkHelper;
|
import WayofTime.bloodmagic.api.util.helper.NetworkHelper;
|
||||||
import WayofTime.bloodmagic.api.util.helper.PlayerHelper;
|
import WayofTime.bloodmagic.api.util.helper.PlayerHelper;
|
||||||
import WayofTime.bloodmagic.structures.DungeonTester;
|
|
||||||
import WayofTime.bloodmagic.tile.TileIncenseAltar;
|
import WayofTime.bloodmagic.tile.TileIncenseAltar;
|
||||||
|
import WayofTime.bloodmagic.tile.TileInversionPillar;
|
||||||
import WayofTime.bloodmagic.util.ChatUtil;
|
import WayofTime.bloodmagic.util.ChatUtil;
|
||||||
import WayofTime.bloodmagic.util.helper.NumeralHelper;
|
import WayofTime.bloodmagic.util.helper.NumeralHelper;
|
||||||
|
|
||||||
|
@ -38,6 +37,13 @@ public class ItemSigilDivination extends ItemSigilBase implements IAltarReader
|
||||||
//// BuildTestStructure s = new BuildTestStructure();
|
//// BuildTestStructure s = new BuildTestStructure();
|
||||||
//// s.placeStructureAtPosition(new Random(), Rotation.CLOCKWISE_180, (WorldServer) world, player.getPosition(), 0);
|
//// s.placeStructureAtPosition(new Random(), Rotation.CLOCKWISE_180, (WorldServer) world, player.getPosition(), 0);
|
||||||
// DungeonTester.testDungeonElementWithOutput((WorldServer) world, player.getPosition());
|
// DungeonTester.testDungeonElementWithOutput((WorldServer) world, player.getPosition());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!world.isRemote)
|
||||||
|
// {
|
||||||
|
// EntityCorruptedZombie fred = new EntityCorruptedZombie(world);
|
||||||
|
// fred.setPosition(player.posX, player.posY, player.posZ);
|
||||||
|
// world.spawnEntityInWorld(fred);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (!world.isRemote)
|
if (!world.isRemote)
|
||||||
|
@ -74,7 +80,13 @@ public class ItemSigilDivination extends ItemSigilBase implements IAltarReader
|
||||||
altar.recheckConstruction();
|
altar.recheckConstruction();
|
||||||
double tranquility = altar.tranquility;
|
double tranquility = altar.tranquility;
|
||||||
ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentTranquility", (int) ((100D * (int) (100 * tranquility)) / 100d)), new TextComponentTranslation(tooltipBase + "currentBonus", (int) (100 * altar.incenseAddition)));
|
ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentTranquility", (int) ((100D * (int) (100 * tranquility)) / 100d)), new TextComponentTranslation(tooltipBase + "currentBonus", (int) (100 * altar.incenseAddition)));
|
||||||
|
} else if (tile != null && tile instanceof TileInversionPillar)
|
||||||
|
{
|
||||||
|
TileInversionPillar pillar = (TileInversionPillar) tile;
|
||||||
|
double inversion = pillar.getCurrentInversion();
|
||||||
|
ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentInversion", ((int) (10 * inversion)) / 10d));
|
||||||
} else
|
} else
|
||||||
|
|
||||||
{
|
{
|
||||||
int currentEssence = NetworkHelper.getSoulNetwork(getOwnerUUID(stack)).getCurrentEssence();
|
int currentEssence = NetworkHelper.getSoulNetwork(getOwnerUUID(stack)).getCurrentEssence();
|
||||||
ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentEssence", currentEssence));
|
ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentEssence", currentEssence));
|
||||||
|
|
|
@ -35,11 +35,13 @@ import WayofTime.bloodmagic.client.render.RenderDemonCrucible;
|
||||||
import WayofTime.bloodmagic.client.render.RenderItemRoutingNode;
|
import WayofTime.bloodmagic.client.render.RenderItemRoutingNode;
|
||||||
import WayofTime.bloodmagic.client.render.block.RenderMimic;
|
import WayofTime.bloodmagic.client.render.block.RenderMimic;
|
||||||
import WayofTime.bloodmagic.client.render.entity.BloodLightRenderFactory;
|
import WayofTime.bloodmagic.client.render.entity.BloodLightRenderFactory;
|
||||||
|
import WayofTime.bloodmagic.client.render.entity.CorruptedZombieRenderFactory;
|
||||||
import WayofTime.bloodmagic.client.render.entity.MeteorRenderFactory;
|
import WayofTime.bloodmagic.client.render.entity.MeteorRenderFactory;
|
||||||
import WayofTime.bloodmagic.client.render.entity.MimicRenderFactory;
|
import WayofTime.bloodmagic.client.render.entity.MimicRenderFactory;
|
||||||
import WayofTime.bloodmagic.client.render.entity.SentientArrowRenderFactory;
|
import WayofTime.bloodmagic.client.render.entity.SentientArrowRenderFactory;
|
||||||
import WayofTime.bloodmagic.client.render.entity.SentientSpecterRenderFactory;
|
import WayofTime.bloodmagic.client.render.entity.SentientSpecterRenderFactory;
|
||||||
import WayofTime.bloodmagic.client.render.entity.SoulSnareRenderFactory;
|
import WayofTime.bloodmagic.client.render.entity.SoulSnareRenderFactory;
|
||||||
|
import WayofTime.bloodmagic.entity.mob.EntityCorruptedZombie;
|
||||||
import WayofTime.bloodmagic.entity.mob.EntityMimic;
|
import WayofTime.bloodmagic.entity.mob.EntityMimic;
|
||||||
import WayofTime.bloodmagic.entity.mob.EntitySentientSpecter;
|
import WayofTime.bloodmagic.entity.mob.EntitySentientSpecter;
|
||||||
import WayofTime.bloodmagic.entity.projectile.EntityBloodLight;
|
import WayofTime.bloodmagic.entity.projectile.EntityBloodLight;
|
||||||
|
@ -104,6 +106,7 @@ public class ClientProxy extends CommonProxy
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityMeteor.class, new MeteorRenderFactory());
|
RenderingRegistry.registerEntityRenderingHandler(EntityMeteor.class, new MeteorRenderFactory());
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntitySentientSpecter.class, new SentientSpecterRenderFactory());
|
RenderingRegistry.registerEntityRenderingHandler(EntitySentientSpecter.class, new SentientSpecterRenderFactory());
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityMimic.class, new MimicRenderFactory());
|
RenderingRegistry.registerEntityRenderingHandler(EntityMimic.class, new MimicRenderFactory());
|
||||||
|
RenderingRegistry.registerEntityRenderingHandler(EntityCorruptedZombie.class, new CorruptedZombieRenderFactory());
|
||||||
|
|
||||||
ShaderHelper.init();
|
ShaderHelper.init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package WayofTime.bloodmagic.registry;
|
||||||
|
|
||||||
import net.minecraftforge.fml.common.registry.EntityRegistry;
|
import net.minecraftforge.fml.common.registry.EntityRegistry;
|
||||||
import WayofTime.bloodmagic.BloodMagic;
|
import WayofTime.bloodmagic.BloodMagic;
|
||||||
|
import WayofTime.bloodmagic.entity.mob.EntityCorruptedZombie;
|
||||||
import WayofTime.bloodmagic.entity.mob.EntityMimic;
|
import WayofTime.bloodmagic.entity.mob.EntityMimic;
|
||||||
import WayofTime.bloodmagic.entity.mob.EntitySentientSpecter;
|
import WayofTime.bloodmagic.entity.mob.EntitySentientSpecter;
|
||||||
import WayofTime.bloodmagic.entity.projectile.EntityBloodLight;
|
import WayofTime.bloodmagic.entity.projectile.EntityBloodLight;
|
||||||
|
@ -21,5 +22,6 @@ public class ModEntities
|
||||||
EntityRegistry.registerModEntity(EntityMeteor.class, "Meteor", id++, BloodMagic.instance, 64, 1, true);
|
EntityRegistry.registerModEntity(EntityMeteor.class, "Meteor", id++, BloodMagic.instance, 64, 1, true);
|
||||||
EntityRegistry.registerModEntity(EntitySentientSpecter.class, "SentientSpecter", id++, BloodMagic.instance, 64, 1, true);
|
EntityRegistry.registerModEntity(EntitySentientSpecter.class, "SentientSpecter", id++, BloodMagic.instance, 64, 1, true);
|
||||||
EntityRegistry.registerModEntity(EntityMimic.class, "Mimic", id++, BloodMagic.instance, 64, 1, true);
|
EntityRegistry.registerModEntity(EntityMimic.class, "Mimic", id++, BloodMagic.instance, 64, 1, true);
|
||||||
|
EntityRegistry.registerModEntity(EntityCorruptedZombie.class, "CorruptedZombie", id++, BloodMagic.instance, 64, 1, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package WayofTime.bloodmagic.tile;
|
package WayofTime.bloodmagic.tile;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -8,7 +9,10 @@ import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import WayofTime.bloodmagic.api.Constants;
|
import WayofTime.bloodmagic.api.Constants;
|
||||||
import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
|
import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
|
||||||
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
|
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
|
||||||
|
@ -25,10 +29,15 @@ public class TileInversionPillar extends TileTicking
|
||||||
public static double inversionToIncreaseRadius = 100;
|
public static double inversionToIncreaseRadius = 100;
|
||||||
public static double inversionToAddPillar = 200;
|
public static double inversionToAddPillar = 200;
|
||||||
public static double operationThreshold = 20;
|
public static double operationThreshold = 20;
|
||||||
|
public static double inversionToSpreadWill = 200;
|
||||||
|
public static double willPushRate = 3;
|
||||||
|
public static double inversionCostPerWillSpread = 4;
|
||||||
|
public static double minimumWillForChunkWhenSpreading = 100;
|
||||||
|
|
||||||
public EnumDemonWillType type;
|
public EnumDemonWillType type;
|
||||||
public double currentInversion = 0;
|
public double currentInversion = 0;
|
||||||
public int consecutiveFailedChecks = 0; //If you fail enough checks, increase the radius.
|
public int consecutiveFailedChecks = 0; //If you fail enough checks, increase the radius.
|
||||||
|
public int consecutiveFailedAirChecks = 0;
|
||||||
public int currentInfectionRadius = 1;
|
public int currentInfectionRadius = 1;
|
||||||
|
|
||||||
public int counter = 0;
|
public int counter = 0;
|
||||||
|
@ -76,9 +85,19 @@ public class TileInversionPillar extends TileTicking
|
||||||
if (pollute == 1)
|
if (pollute == 1)
|
||||||
{
|
{
|
||||||
consecutiveFailedChecks++;
|
consecutiveFailedChecks++;
|
||||||
|
} else if (pollute == 3)
|
||||||
|
{
|
||||||
|
consecutiveFailedAirChecks++;
|
||||||
} else if (pollute == 0)
|
} else if (pollute == 0)
|
||||||
{
|
{
|
||||||
|
//We successfully found a block to replace!
|
||||||
consecutiveFailedChecks = 0;
|
consecutiveFailedChecks = 0;
|
||||||
|
consecutiveFailedAirChecks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentInversion >= inversionToSpreadWill)
|
||||||
|
{
|
||||||
|
spreadWillToSurroundingChunks();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consecutiveFailedChecks > 5 * currentInfectionRadius && currentInversion >= inversionToIncreaseRadius)
|
if (consecutiveFailedChecks > 5 * currentInfectionRadius && currentInversion >= inversionToIncreaseRadius)
|
||||||
|
@ -91,7 +110,97 @@ public class TileInversionPillar extends TileTicking
|
||||||
|
|
||||||
if (currentInfectionRadius >= 10 && currentInversion >= inversionToAddPillar)
|
if (currentInfectionRadius >= 10 && currentInversion >= inversionToAddPillar)
|
||||||
{
|
{
|
||||||
//TODO: Spawn pillar
|
//TODO: Improve algorithm
|
||||||
|
List<BlockPos> allConnectedPos = InversionPillarHandler.getAllConnectedPillars(worldObj, type, pos);
|
||||||
|
BlockPos candidatePos = findCandidatePositionForPillar(worldObj, type, pos, allConnectedPos, 5, 10);
|
||||||
|
if (!candidatePos.equals(BlockPos.ORIGIN))
|
||||||
|
{
|
||||||
|
currentInversion -= inversionToAddPillar;
|
||||||
|
IBlockState pillarState = ModBlocks.INVERSION_PILLAR.getStateFromMeta(type.ordinal());
|
||||||
|
IBlockState bottomState = ModBlocks.INVERSION_PILLAR_END.getStateFromMeta(type.ordinal() * 2);
|
||||||
|
IBlockState topState = ModBlocks.INVERSION_PILLAR_END.getStateFromMeta(type.ordinal() * 2 + 1);
|
||||||
|
worldObj.setBlockState(candidatePos, pillarState);
|
||||||
|
worldObj.setBlockState(candidatePos.down(), bottomState);
|
||||||
|
worldObj.setBlockState(candidatePos.up(), topState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BlockPos findCandidatePositionForPillar(World world, EnumDemonWillType type, BlockPos pos, List<BlockPos> posList, double tooCloseDistance, double wantedAverageDistance)
|
||||||
|
{
|
||||||
|
int maxIterations = 100;
|
||||||
|
int heightCheckRange = 3;
|
||||||
|
|
||||||
|
for (int i = 0; i < maxIterations; i++)
|
||||||
|
{
|
||||||
|
Collections.shuffle(posList);
|
||||||
|
BlockPos pillarPos = posList.get(0);
|
||||||
|
|
||||||
|
Vec3d vec = new Vec3d(world.rand.nextDouble() * 2 - 1, world.rand.nextDouble() * 2 - 1, world.rand.nextDouble() * 2 - 1).normalize().scale(wantedAverageDistance);
|
||||||
|
|
||||||
|
BlockPos centralPos = pillarPos.add(vec.xCoord, vec.yCoord, vec.zCoord);
|
||||||
|
BlockPos testPos = null;
|
||||||
|
candidateTest: for (int h = 0; h <= heightCheckRange; h++)
|
||||||
|
{
|
||||||
|
for (int sig = -1; sig <= 1; sig += (h > 0 ? 2 : 3))
|
||||||
|
{
|
||||||
|
BlockPos candidatePos = centralPos.add(0, sig * h, 0);
|
||||||
|
IBlockState candidateState = world.getBlockState(candidatePos);
|
||||||
|
if (world.isAirBlock(candidatePos) && world.isAirBlock(candidatePos.up()) && world.isAirBlock(candidatePos.down()) && !world.isAirBlock(candidatePos.down(2)))
|
||||||
|
{
|
||||||
|
testPos = candidatePos;
|
||||||
|
break candidateTest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (testPos != null)
|
||||||
|
{
|
||||||
|
boolean isValid = true;
|
||||||
|
for (BlockPos pillarTestPos : posList)
|
||||||
|
{
|
||||||
|
if (pillarTestPos.distanceSq(testPos) <= tooCloseDistance * tooCloseDistance)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid)
|
||||||
|
{
|
||||||
|
return testPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return BlockPos.ORIGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void spreadWillToSurroundingChunks()
|
||||||
|
{
|
||||||
|
double currentAmount = WorldDemonWillHandler.getCurrentWill(worldObj, pos, type);
|
||||||
|
if (currentAmount <= minimumWillForChunkWhenSpreading)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (EnumFacing side : EnumFacing.HORIZONTALS)
|
||||||
|
{
|
||||||
|
BlockPos offsetPos = pos.offset(side, 16);
|
||||||
|
double sideAmount = WorldDemonWillHandler.getCurrentWill(worldObj, offsetPos, type);
|
||||||
|
if (currentAmount > sideAmount)
|
||||||
|
{
|
||||||
|
double drainAmount = Math.min((currentAmount - sideAmount) / 2, willPushRate);
|
||||||
|
if (drainAmount < willPushRate / 2)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double drain = WorldDemonWillHandler.drainWill(worldObj, pos, type, drainAmount, true);
|
||||||
|
drain = WorldDemonWillHandler.fillWillToMaximum(worldObj, offsetPos, type, drain, maxWillForChunk, true);
|
||||||
|
|
||||||
|
currentInversion -= drain * inversionCostPerWillSpread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,14 +285,15 @@ public class TileInversionPillar extends TileTicking
|
||||||
* @param currentWillInChunk
|
* @param currentWillInChunk
|
||||||
* @return 0 if the block is successfully placed, 1 if the block is not
|
* @return 0 if the block is successfully placed, 1 if the block is not
|
||||||
* placed due to the selected place being invalid, 2 if the block is
|
* placed due to the selected place being invalid, 2 if the block is
|
||||||
* not placed due to there not being enough Will or Inversion
|
* not placed due to there not being enough Will or Inversion, 3 if
|
||||||
|
* the block is not placed due to the selected block being air.
|
||||||
*/
|
*/
|
||||||
public int polluteNearbyBlocks(double currentWillInChunk)
|
public int polluteNearbyBlocks(double currentWillInChunk)
|
||||||
{
|
{
|
||||||
// System.out.println("Hai! :D Current Inversion: " + currentInversion + ", Current Will: " + currentWillInChunk);
|
// System.out.println("Hai! :D Current Inversion: " + currentInversion + ", Current Will: " + currentWillInChunk);
|
||||||
if (currentWillInChunk < operationThreshold || currentInversion < inversionPerOperation)
|
if (currentWillInChunk < operationThreshold || currentInversion < inversionPerOperation)
|
||||||
{
|
{
|
||||||
return 2;
|
return 2; //Not enough Will or Inversion available
|
||||||
}
|
}
|
||||||
|
|
||||||
double xOff = worldObj.rand.nextGaussian() * currentInfectionRadius;
|
double xOff = worldObj.rand.nextGaussian() * currentInfectionRadius;
|
||||||
|
@ -202,7 +312,7 @@ public class TileInversionPillar extends TileTicking
|
||||||
BlockPos offsetPos = pos.add(xOff + 0.5, yOff + 0.5, zOff + 0.5);
|
BlockPos offsetPos = pos.add(xOff + 0.5, yOff + 0.5, zOff + 0.5);
|
||||||
if (offsetPos.equals(pos))
|
if (offsetPos.equals(pos))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1; //Invalid block (itself!)
|
||||||
}
|
}
|
||||||
|
|
||||||
IBlockState state = worldObj.getBlockState(offsetPos);
|
IBlockState state = worldObj.getBlockState(offsetPos);
|
||||||
|
@ -218,13 +328,13 @@ public class TileInversionPillar extends TileTicking
|
||||||
WorldDemonWillHandler.drainWill(worldObj, pos, type, willPerOperation, true);
|
WorldDemonWillHandler.drainWill(worldObj, pos, type, willPerOperation, true);
|
||||||
currentInversion -= inversionPerOperation;
|
currentInversion -= inversionPerOperation;
|
||||||
|
|
||||||
return 0;
|
return 0; //Successfully placed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1; //Invalid block
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 3; //The block was air
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -383,6 +383,7 @@ tooltip.BloodMagic.sigil.divination.currentAltarTier=Current Tier: %d
|
||||||
tooltip.BloodMagic.sigil.divination.currentEssence=Current Essence: %d LP
|
tooltip.BloodMagic.sigil.divination.currentEssence=Current Essence: %d LP
|
||||||
tooltip.BloodMagic.sigil.divination.currentAltarCapacity=Current Capacity: %d LP
|
tooltip.BloodMagic.sigil.divination.currentAltarCapacity=Current Capacity: %d LP
|
||||||
tooltip.BloodMagic.sigil.divination.currentTranquility=Current Tranquility: %d
|
tooltip.BloodMagic.sigil.divination.currentTranquility=Current Tranquility: %d
|
||||||
|
tooltip.BloodMagic.sigil.divination.currentInversion=Current Inversion: %d
|
||||||
tooltip.BloodMagic.sigil.divination.currentBonus=Current Bonus: +%d%%
|
tooltip.BloodMagic.sigil.divination.currentBonus=Current Bonus: +%d%%
|
||||||
tooltip.BloodMagic.sigil.water.desc=&oInfinite water, anyone?
|
tooltip.BloodMagic.sigil.water.desc=&oInfinite water, anyone?
|
||||||
tooltip.BloodMagic.sigil.lava.desc=&oHOT! DO NOT EAT
|
tooltip.BloodMagic.sigil.lava.desc=&oHOT! DO NOT EAT
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
Loading…
Reference in a new issue