Merge branch 'main' of https://git.thelordofembers.com/shinare/CinderLoE
@ -0,0 +1,91 @@
|
||||
package com.zivilon.cinder_loe.client.model;
|
||||
// Made with Blockbench 4.11.1
|
||||
// Exported for Minecraft version 1.7 - 1.12
|
||||
// Paste this class into your mod and generate all required imports
|
||||
|
||||
|
||||
import lotr.client.model.LOTRModelBiped;
|
||||
import net.minecraft.client.model.ModelBox;
|
||||
import net.minecraft.client.model.ModelRenderer;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public class ModelGalvornHelmet extends LOTRModelBiped {
|
||||
private final ModelRenderer crest;
|
||||
private final ModelRenderer shape12;
|
||||
private final ModelRenderer shape3;
|
||||
private final ModelRenderer shape4;
|
||||
private final ModelRenderer shape5;
|
||||
private final ModelRenderer shape6;
|
||||
|
||||
public ModelGalvornHelmet(float f) {
|
||||
super(f);
|
||||
this.textureWidth = 64;
|
||||
this.textureHeight = 32;
|
||||
|
||||
crest = new ModelRenderer(this);
|
||||
crest.setRotationPoint(0.0F, -1.0F, 0.55F);
|
||||
|
||||
shape12 = new ModelRenderer(this);
|
||||
shape12.setRotationPoint(0.5F, -4.0F, -6.35F);
|
||||
setRotationAngle(shape12, 1.5708F, 0.0F, 0.0F);
|
||||
shape12.cubeList.add(new ModelBox(shape12, 43, 22, -1.0F, 0.0F, -1.5F, 1, 1, 9, 0.0F));
|
||||
|
||||
shape3 = new ModelRenderer(this);
|
||||
shape3.setRotationPoint(0.0F, 0.0F, 0.0F);
|
||||
setRotationAngle(shape3, 0.0F, -0.2276F, 0.0F);
|
||||
shape3.cubeList.add(new ModelBox(shape3, 0, 25, -1.0F, 0.1F, 0.0F, 1, 0, 6, 0.0F));
|
||||
|
||||
shape4 = new ModelRenderer(this);
|
||||
shape4.setRotationPoint(0.0F, 0.0F, 0.0F);
|
||||
setRotationAngle(shape4, 0.0F, -0.2731F, 0.0F);
|
||||
shape4.cubeList.add(new ModelBox(shape4, 16, 23, -1.0F, 0.2F, 0.0F, 1, 0, 5, 0.0F));
|
||||
|
||||
shape5 = new ModelRenderer(this);
|
||||
shape5.setRotationPoint(-1.0F, 0.0F, 0.0F);
|
||||
setRotationAngle(shape5, 0.0F, 0.2276F, 0.0F);
|
||||
shape5.cubeList.add(new ModelBox(shape5, 50, 3, 0.0F, 0.1F, 0.0F, 1, 0, 6, 0.0F));
|
||||
|
||||
shape6 = new ModelRenderer(this);
|
||||
shape6.setRotationPoint(0.0F, 0.0F, 0.0F);
|
||||
|
||||
setRotationAngle(shape6, 0.0F, 0.2731F, 0.0F);
|
||||
shape6.cubeList.add(new ModelBox(shape6, 49, 13, 0.0F, 0.2F, 0.0F, 1, 0, 5, 0.0F));
|
||||
|
||||
this.bipedHead.cubeList.clear();
|
||||
|
||||
bipedHead = new ModelRenderer(this);
|
||||
bipedHead.setRotationPoint(0.0F, 0.0F, 0.0F);
|
||||
bipedHead.cubeList.add(new ModelBox(bipedHead, 0, 0, -4.0F, -8.0F, -4.0F, 8, 8, 8, 1.0F));
|
||||
|
||||
// this.crest.addChild(this.shape12);
|
||||
// this.crest.addChild(this.shape3);
|
||||
// this.crest.addChild(this.shape4);
|
||||
// this.crest.addChild(this.shape5);
|
||||
// this.crest.addChild(this.shape6);
|
||||
crest.addChild(shape12);
|
||||
shape12.addChild(shape3);
|
||||
shape3.addChild(shape4);
|
||||
shape12.addChild(shape5);
|
||||
shape5.addChild(shape6);
|
||||
this.bipedHead.addChild(this.crest);
|
||||
|
||||
this.bipedHeadwear.cubeList.clear();
|
||||
this.bipedBody.cubeList.clear();
|
||||
this.bipedRightArm.cubeList.clear();
|
||||
this.bipedLeftArm.cubeList.clear();
|
||||
this.bipedRightLeg.cubeList.clear();
|
||||
this.bipedLeftLeg.cubeList.clear();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) {
|
||||
bipedHead.render(f5);
|
||||
}
|
||||
|
||||
public void setRotationAngle(ModelRenderer modelRenderer, float x, float y, float z) {
|
||||
modelRenderer.rotateAngleX = x;
|
||||
modelRenderer.rotateAngleY = y;
|
||||
modelRenderer.rotateAngleZ = z;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.zivilon.cinder_loe.client.render;
|
||||
|
||||
import com.zivilon.cinder_loe.entity.Wraith;
|
||||
import com.zivilon.cinder_loe.entity.boss.CryptBoss;
|
||||
import lotr.client.model.LOTRModelMarshWraith;
|
||||
import net.minecraft.client.model.ModelBase;
|
||||
import net.minecraft.client.renderer.entity.RenderLiving;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class RenderCryptBoss extends RenderLiving {
|
||||
private static ResourceLocation skin = new ResourceLocation("cinder_loe:mob/wraith/wraith.png");
|
||||
|
||||
public RenderCryptBoss() {
|
||||
super((ModelBase)new LOTRModelMarshWraith(), 0.5F);
|
||||
}
|
||||
|
||||
protected ResourceLocation getEntityTexture(Entity entity) {
|
||||
return skin;
|
||||
}
|
||||
|
||||
protected void preRenderCallback(EntityLivingBase entity, float f) {
|
||||
super.preRenderCallback(entity, f);
|
||||
float f1 = 0.9375F;
|
||||
float hover = MathHelper.sin((((Entity)entity).ticksExisted + f) * 0.15F) * 0.2F - 0.5F;
|
||||
GL11.glScalef(f1, f1, f1);
|
||||
GL11.glTranslatef(0.0F, hover, 0.0F);
|
||||
CryptBoss wraith = (CryptBoss)entity;
|
||||
if (wraith.getDeathFadeTime() > 0) {
|
||||
GL11.glEnable(3042);
|
||||
GL11.glBlendFunc(770, 771);
|
||||
GL11.glEnable(3008);
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, wraith.getDeathFadeTime() / 30.0F);
|
||||
}
|
||||
}
|
||||
|
||||
protected float getDeathMaxRotation(EntityLivingBase entity) {
|
||||
return 0.0F;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.zivilon.cinder_loe.client.render.projectile;
|
||||
|
||||
import net.minecraft.client.renderer.entity.RenderArrow;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class RenderElvenArrow extends RenderArrow {
|
||||
private static final ResourceLocation arrowPoisonTexture = new ResourceLocation("lotr:item/arrowPoisoned.png");
|
||||
|
||||
protected ResourceLocation getEntityTexture(Entity entity) {
|
||||
return arrowPoisonTexture;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.zivilon.cinder_loe.client.render.projectile;
|
||||
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class RenderMorgulBlast extends Render {
|
||||
protected ResourceLocation getEntityTexture(Entity entity) {
|
||||
return TextureMap.locationBlocksTexture;
|
||||
}
|
||||
|
||||
public void doRender(Entity entity, double d, double d1, double d2, float f, float f1) {
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package com.zivilon.cinder_loe.client.render;
|
||||
package com.zivilon.cinder_loe.client.render.projectile;
|
||||
|
||||
import lotr.client.LOTRClientProxy;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.entity.Entity;
|
||||
@ -1,6 +1,5 @@
|
||||
package com.zivilon.cinder_loe.client.render;
|
||||
package com.zivilon.cinder_loe.client.render.projectile;
|
||||
|
||||
import lotr.client.LOTRClientProxy;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.entity.Entity;
|
||||
@ -0,0 +1,214 @@
|
||||
package com.zivilon.cinder_loe.entity.boss;
|
||||
|
||||
import com.zivilon.cinder_loe.entity.projectile.EntityMorgulBlast;
|
||||
import lotr.common.LOTRMod;
|
||||
import lotr.common.enchant.LOTREnchantment;
|
||||
import lotr.common.enchant.LOTREnchantmentHelper;
|
||||
import lotr.common.entity.ai.*;
|
||||
import lotr.common.entity.npc.LOTREntityMarshWraith;
|
||||
import lotr.common.entity.npc.LOTREntityNPC;
|
||||
import lotr.common.fac.LOTRFaction;
|
||||
import lotr.common.quest.LOTRMiniQuest;
|
||||
import lotr.common.world.structure.LOTRChestContents;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.*;
|
||||
import net.minecraft.entity.ai.*;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class CryptBoss extends LOTREntityNPC {
|
||||
|
||||
private EntityAIBase meleeAttackAI = new LOTREntityAIAttackOnCollide(this, 2.0, false);
|
||||
private EntityAIBase rangedAttackAI = new LOTREntityAIRangedAttack(this, 1.5, 30, 50, 60.0f);
|
||||
|
||||
//Copying Wraith temporarily
|
||||
public CryptBoss(World world) {
|
||||
super(world);
|
||||
setSize(0.8F, 2.5F);
|
||||
this.tasks.taskEntries.clear();
|
||||
this.tasks.addTask(0, (EntityAIBase)new EntityAISwimming((EntityLiving)this));
|
||||
//Causes crash
|
||||
//this.tasks.addTask(0, (EntityAIBase)new LOTREntityAIBossJumpAttack(this, 1.5, 0.02f));
|
||||
this.tasks.addTask(2, (EntityAIBase)new EntityAIWander((EntityCreature)this, 1.0));
|
||||
this.tasks.addTask(3, (EntityAIBase)new EntityAIWatchClosest2((EntityLiving)this, EntityPlayer.class, 12.0f, 0.02f));
|
||||
this.tasks.addTask(3, (EntityAIBase)new EntityAIWatchClosest2((EntityLiving)this, LOTREntityNPC.class, 8.0f, 0.02f));
|
||||
this.tasks.addTask(4, (EntityAIBase)new EntityAIWatchClosest((EntityLiving)this, EntityLiving.class, 10.0f, 0.02f));
|
||||
this.tasks.addTask(5, (EntityAIBase)new EntityAILookIdle((EntityLiving)this));
|
||||
addTargetTasks(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSpeechBank(EntityPlayer entityplayer, String speechBank) {
|
||||
this.sendSpeechBank(entityplayer, speechBank, (LOTRMiniQuest)null);
|
||||
}
|
||||
|
||||
protected void entityInit() {
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(17, Integer.valueOf(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(300.0);
|
||||
this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(32.0);
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.0);
|
||||
this.getEntityAttribute(npcAttackDamage).setBaseValue(16.0);
|
||||
}
|
||||
|
||||
public int getDeathFadeTime() {
|
||||
return this.dataWatcher.getWatchableObjectInt(17);
|
||||
}
|
||||
|
||||
public void setDeathFadeTime(int i) {
|
||||
this.dataWatcher.updateObject(17, Integer.valueOf(i));
|
||||
}
|
||||
|
||||
public LOTRFaction getFaction() {
|
||||
return LOTRFaction.UTUMNO;
|
||||
}
|
||||
|
||||
public void writeEntityToNBT(NBTTagCompound nbt) {
|
||||
super.writeEntityToNBT(nbt);
|
||||
nbt.setInteger("DeathFadeTime", getDeathFadeTime());
|
||||
}
|
||||
|
||||
public void readEntityFromNBT(NBTTagCompound nbt) {
|
||||
super.readEntityFromNBT(nbt);
|
||||
setDeathFadeTime(nbt.getInteger("DeathFadeTime"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveEntityWithHeading(float strafe, float forward) {
|
||||
// First, call the super method to preserve normal movement behavior
|
||||
super.moveEntityWithHeading(strafe, forward);
|
||||
|
||||
// Check for water at the entity's feet
|
||||
int x = MathHelper.floor_double(this.posX);
|
||||
int y = MathHelper.floor_double(this.posY);
|
||||
int z = MathHelper.floor_double(this.posZ);
|
||||
|
||||
boolean isWater = this.worldObj.getBlock(x, y, z).getMaterial() == Material.water ||
|
||||
this.worldObj.getBlock(x, y - 1, z).getMaterial() == Material.water; // Check below the entity too
|
||||
|
||||
if (isWater) {
|
||||
this.onGround = true; // Treat water as solid ground
|
||||
this.motionY = 0.0; // Stop falling/sinking
|
||||
this.setPosition(this.posX, y + 1, this.posZ); // Adjust position to stay on top of the water
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setInWeb() {}
|
||||
|
||||
@Override
|
||||
public void onLivingUpdate() {
|
||||
super.onLivingUpdate();
|
||||
if (this.worldObj.isRemote) {
|
||||
for (int l = 0; l < 1; ++l) {
|
||||
double d = this.posX + (double)this.width * MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.5, (double)0.5);
|
||||
double d1 = this.posY + (double)this.height * MathHelper.getRandomDoubleInRange((Random)this.rand, (double)0.4, (double)0.8);
|
||||
double d2 = this.posZ + (double)this.width * MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.5, (double)0.5);
|
||||
double d3 = MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.1, (double)0.1);
|
||||
double d4 = MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.2, (double)-0.05);
|
||||
double d5 = MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.1, (double)0.1);
|
||||
if (this.rand.nextBoolean()) {
|
||||
LOTRMod.proxy.spawnParticle("morgulPortal", d, d1, d2, d3, d4, d5);
|
||||
continue;
|
||||
}
|
||||
this.worldObj.spawnParticle("smoke", d, d1, d2, d3, d4, d5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttackModeChange(LOTREntityNPC.AttackMode mode, boolean mounted) {
|
||||
if (mode == LOTREntityNPC.AttackMode.IDLE) {
|
||||
this.tasks.removeTask(this.meleeAttackAI);
|
||||
this.tasks.removeTask(this.rangedAttackAI);
|
||||
this.tasks.addTask(1, this.meleeAttackAI);
|
||||
}
|
||||
if (mode == LOTREntityNPC.AttackMode.MELEE) {
|
||||
this.tasks.removeTask(this.meleeAttackAI);
|
||||
this.tasks.removeTask(this.rangedAttackAI);
|
||||
this.tasks.addTask(1, this.meleeAttackAI);
|
||||
}
|
||||
if (mode == LOTREntityNPC.AttackMode.RANGED) {
|
||||
this.tasks.removeTask(this.meleeAttackAI);
|
||||
this.tasks.removeTask(this.rangedAttackAI);
|
||||
this.tasks.addTask(1, this.rangedAttackAI);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attackEntityWithRangedAttack(EntityLivingBase target, float f) {
|
||||
EntityMorgulBlast projectile = new EntityMorgulBlast(this.worldObj, (EntityLivingBase)this, target);
|
||||
projectile.leavesDamage = 16.0f;
|
||||
this.worldObj.spawnEntityInWorld((Entity)projectile);
|
||||
this.playSound("lotr:wraith.marshWraith_shoot", this.getSoundVolume(), this.getSoundPitch());
|
||||
this.swingItem();
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource damagesource, float f) {
|
||||
boolean vulnerable = false;
|
||||
Entity entity = damagesource.getEntity();
|
||||
if (entity instanceof EntityLivingBase && entity == damagesource.getSourceOfDamage()) {
|
||||
ItemStack itemstack = ((EntityLivingBase)entity).getHeldItem();
|
||||
if (itemstack != null && LOTREnchantmentHelper.hasEnchant(itemstack, LOTREnchantment.baneWight))
|
||||
vulnerable = true;
|
||||
}
|
||||
if (vulnerable && getDeathFadeTime() == 0) {
|
||||
boolean flag = super.attackEntityFrom(damagesource, f);
|
||||
return flag;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onDeath(DamageSource damagesource) {
|
||||
super.onDeath(damagesource);
|
||||
if (!((Entity)this).worldObj.isRemote)
|
||||
setDeathFadeTime(30);
|
||||
}
|
||||
|
||||
protected void dropFewItems(boolean flag, int i) {
|
||||
super.dropFewItems(flag, i);
|
||||
int flesh = 1 + rand.nextInt(3) + rand.nextInt(i + 1);
|
||||
for (int l = 0; l < flesh; l++)
|
||||
dropItem(Items.rotten_flesh, 1);
|
||||
dropChestContents(LOTRChestContents.MARSH_REMAINS, 1, 3 + i);
|
||||
}
|
||||
|
||||
public EnumCreatureAttribute getCreatureAttribute() {
|
||||
return EnumCreatureAttribute.UNDEAD;
|
||||
}
|
||||
|
||||
protected String getHurtSound() {
|
||||
return "lotr:wight.hurt";
|
||||
}
|
||||
|
||||
protected String getDeathSound() {
|
||||
return "lotr:wight.death";
|
||||
}
|
||||
|
||||
public boolean handleWaterMovement() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void func_145780_a(int i, int j, int k, Block block) {}
|
||||
|
||||
@Override
|
||||
public String getSpeechBank(EntityPlayer entityplayer) {
|
||||
if (this.isFriendlyAndAligned(entityplayer)) {
|
||||
return "corruptSpeak/all/neutral";
|
||||
}
|
||||
return "corruptSpeak/all/hostile";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package com.zivilon.cinder_loe.entity.projectile;
|
||||
|
||||
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityElvenArrow extends EntityArrow implements IEntityAdditionalSpawnData {
|
||||
public EntityElvenArrow(World world) {
|
||||
super(world);
|
||||
}
|
||||
|
||||
public EntityElvenArrow(World world, double d, double d1, double d2) {
|
||||
super(world, d, d1, d2);
|
||||
}
|
||||
|
||||
public EntityElvenArrow(World world, EntityLivingBase shooter, EntityLivingBase target, float charge, float inaccuracy) {
|
||||
super(world, shooter, target, charge, inaccuracy);
|
||||
}
|
||||
|
||||
public EntityElvenArrow(World world, EntityLivingBase shooter, float charge) {
|
||||
super(world, shooter, charge);
|
||||
}
|
||||
|
||||
public void writeSpawnData(ByteBuf data) {
|
||||
data.writeDouble(this.motionX);
|
||||
data.writeDouble(this.motionY);
|
||||
data.writeDouble(this.motionZ);
|
||||
data.writeInt(this.shootingEntity == null ? -1 : this.shootingEntity.getEntityId());
|
||||
}
|
||||
|
||||
public void readSpawnData(ByteBuf data) {
|
||||
Entity entity;
|
||||
this.motionX = data.readDouble();
|
||||
this.motionY = data.readDouble();
|
||||
this.motionZ = data.readDouble();
|
||||
int id = data.readInt();
|
||||
if (id >= 0 && (entity = this.worldObj.getEntityByID(id)) != null) {
|
||||
this.shootingEntity = entity;
|
||||
}
|
||||
}
|
||||
|
||||
public void onCollideWithPlayer(EntityPlayer entityplayer) {
|
||||
boolean isInGround;
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
this.writeEntityToNBT(nbt);
|
||||
boolean bl = isInGround = nbt.getByte("inGround") == 1;
|
||||
if (!this.worldObj.isRemote && isInGround && this.arrowShake <= 0) {
|
||||
boolean pickup;
|
||||
boolean bl2 = pickup = this.canBePickedUp == 1 || this.canBePickedUp == 2 && entityplayer.capabilities.isCreativeMode;
|
||||
//Need to add it as an item first
|
||||
// if (this.canBePickedUp == 1 && !entityplayer.inventory.addItemStackToInventory(new ItemStack(LOTRMod.arrowPoisoned, 1))) {
|
||||
// pickup = false;
|
||||
// }
|
||||
if (pickup) {
|
||||
this.playSound("random.pop", 0.2f, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7f + 1.0f) * 2.0f);
|
||||
entityplayer.onItemPickup((Entity)this, 1);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,174 @@
|
||||
package com.zivilon.cinder_loe.entity.projectile;
|
||||
|
||||
import lotr.common.LOTRMod;
|
||||
import lotr.common.entity.npc.LOTREntityNPC;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.projectile.EntityThrowable;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntityMorgulBlast extends EntityThrowable {
|
||||
private UUID throwerUUID;
|
||||
private int leavesAge;
|
||||
private static int MAX_LEAVES_AGE = 200;
|
||||
public float leavesDamage;
|
||||
|
||||
|
||||
public EntityMorgulBlast(World world) {
|
||||
super(world);
|
||||
this.setSize(2.0f, 2.0f);
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
}
|
||||
|
||||
public EntityMorgulBlast(World world, EntityLivingBase thrower, EntityLivingBase target) {
|
||||
super(world, thrower);
|
||||
this.setSize(2.0f, 2.0f);
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
this.throwerUUID = thrower.getUniqueID();
|
||||
this.posY = thrower.posY + (double)thrower.getEyeHeight() - 0.1;
|
||||
double dx = target.posX - thrower.posX;
|
||||
double dy = target.boundingBox.minY + (double)(target.height / 3.0f) - this.posY;
|
||||
double dz = target.posZ - thrower.posZ;
|
||||
double dxz = MathHelper.sqrt_double((double)(dx * dx + dz * dz));
|
||||
if (dxz >= 1.0E-7) {
|
||||
float f2 = (float)(Math.atan2(dz, dx) * 180.0 / Math.PI) - 90.0f;
|
||||
float f3 = (float)(-(Math.atan2(dy, dxz) * 180.0 / Math.PI));
|
||||
double d4 = dx / dxz;
|
||||
double d5 = dz / dxz;
|
||||
this.setLocationAndAngles(thrower.posX + d4, this.posY, thrower.posZ + d5, f2, f3);
|
||||
this.yOffset = 0.0f;
|
||||
this.setThrowableHeading(dx, dy, dz, this.func_70182_d(), 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityMorgulBlast(World world, double d, double d1, double d2) {
|
||||
super(world, d, d1, d2);
|
||||
this.setSize(2.0f, 2.0f);
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
}
|
||||
|
||||
public void writeEntityToNBT(NBTTagCompound nbt) {
|
||||
super.writeEntityToNBT(nbt);
|
||||
nbt.setInteger("LeavesAge", this.leavesAge);
|
||||
nbt.setFloat("LeavesDamage", this.leavesDamage);
|
||||
if (this.throwerUUID != null) {
|
||||
nbt.setString("ThrowerUUID", this.throwerUUID.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void readEntityFromNBT(NBTTagCompound nbt) {
|
||||
super.readEntityFromNBT(nbt);
|
||||
this.leavesAge = nbt.getInteger("LeavesAge");
|
||||
this.leavesDamage = nbt.getFloat("LeavesDamage");
|
||||
if (nbt.hasKey("ThrowerUUID")) {
|
||||
this.throwerUUID = UUID.fromString(nbt.getString("ThrowerUUID"));
|
||||
}
|
||||
}
|
||||
|
||||
protected void onImpact(MovingObjectPosition m) {
|
||||
if (!this.worldObj.isRemote) {
|
||||
Entity entity;
|
||||
if (m.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
|
||||
this.explode(null);
|
||||
} else if (m.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && this.isEntityVulnerable(entity = m.entityHit)) {
|
||||
this.explode(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void explode(Entity target) {
|
||||
if (!this.worldObj.isRemote) {
|
||||
double range = 3.0;
|
||||
List entities = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, this.boundingBox.expand(range, range, range));
|
||||
if (!entities.isEmpty()) {
|
||||
for (int i = 0; i < entities.size(); ++i) {
|
||||
float damage;
|
||||
EntityLivingBase entity = (EntityLivingBase)entities.get(i);
|
||||
if (!this.isEntityVulnerable((Entity)entity) || !((damage = this.leavesDamage / Math.max(1.0f, this.getDistanceToEntity((Entity)entity))) > 0.0f)) continue;
|
||||
entity.attackEntityFrom(DamageSource.causeMobDamage((EntityLivingBase)this.getThrower()), damage);
|
||||
}
|
||||
}
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
private boolean isEntityVulnerable(Entity target) {
|
||||
if (target == this.getThrower()) {
|
||||
return false;
|
||||
}
|
||||
if (target instanceof EntityLivingBase) {
|
||||
EntityLivingBase livingTarget = (EntityLivingBase)target;
|
||||
EntityLivingBase thrower = this.getThrower();
|
||||
if (thrower instanceof LOTREntityNPC) {
|
||||
((LOTREntityNPC)thrower).getJumpHelper().doJump();
|
||||
return LOTRMod.canNPCAttackEntity((LOTREntityNPC)thrower, livingTarget, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
super.onUpdate();
|
||||
if (!this.worldObj.isRemote) {
|
||||
++this.leavesAge;
|
||||
if (this.leavesAge >= MAX_LEAVES_AGE) {
|
||||
this.explode(null);
|
||||
}
|
||||
} else {
|
||||
Vec3 axis = Vec3.createVectorHelper((double)(-this.motionX), (double)(-this.motionY), (double)(-this.motionZ));
|
||||
int leaves = 20;
|
||||
for (int l = 0; l < leaves; ++l) {
|
||||
float angle = (float)l / (float)leaves * 2.0f * (float)Math.PI;
|
||||
Vec3 rotate = Vec3.createVectorHelper((double)1.0, (double)1.0, (double)1.0);
|
||||
rotate.rotateAroundX((float)Math.toRadians(40.0));
|
||||
rotate.rotateAroundY(angle);
|
||||
float dot = (float)rotate.dotProduct(axis);
|
||||
Vec3 parallel = Vec3.createVectorHelper((double)(axis.xCoord * (double)dot), (double)(axis.yCoord * (double)dot), (double)(axis.zCoord * (double)dot));
|
||||
Vec3 perp = parallel.subtract(rotate);
|
||||
Vec3 cross = rotate.crossProduct(axis);
|
||||
float sin = MathHelper.sin((float)(-angle));
|
||||
float cos = MathHelper.cos((float)(-angle));
|
||||
Vec3 crossSin = Vec3.createVectorHelper((double)(cross.xCoord * (double)sin), (double)(cross.yCoord * (double)sin), (double)(cross.zCoord * (double)sin));
|
||||
Vec3 perpCos = Vec3.createVectorHelper((double)(perp.xCoord * (double)cos), (double)(perp.yCoord * (double)cos), (double)(perp.zCoord * (double)cos));
|
||||
Vec3 result = parallel.addVector(crossSin.xCoord + perpCos.xCoord, crossSin.yCoord + perpCos.yCoord, crossSin.zCoord + perpCos.zCoord);
|
||||
double d = this.posX;
|
||||
double d1 = this.posY;
|
||||
double d2 = this.posZ;
|
||||
double d3 = result.xCoord / 10.0;
|
||||
double d4 = result.yCoord / 10.0;
|
||||
double d5 = result.zCoord / 10.0;
|
||||
LOTRMod.proxy.spawnParticle("morgulPortal", d, d1, d2, d3, d4, d5);
|
||||
// LOTRMod.proxy.spawnParticle("smoke", d, d1, d2, d3 * 0.5, d4 * 0.5, d5 * 0.5);
|
||||
worldObj.spawnParticle("smoke", d, d1, d2, d3 * 0.5, d4 * 0.5, d5 * 0.5);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public EntityLivingBase getThrower() {
|
||||
if (this.throwerUUID != null) {
|
||||
for (Object obj : this.worldObj.loadedEntityList) {
|
||||
Entity entity = (Entity)obj;
|
||||
if (!(entity instanceof EntityLivingBase) || !entity.getUniqueID().equals(this.throwerUUID)) continue;
|
||||
return (EntityLivingBase)entity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected float func_70182_d() {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
protected float getGravityVelocity() {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.zivilon.cinder_loe.mixins.overrides;
|
||||
|
||||
import lotr.common.enchant.LOTREnchantment;
|
||||
import lotr.common.enchant.LOTREnchantmentHelper;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(LOTREnchantmentHelper.class)
|
||||
public class MixinLOTREnchantmenHelper {
|
||||
|
||||
/**
|
||||
* Prevent negative modifiers (weak or detrimental enchants) from being applied.
|
||||
*/
|
||||
@Redirect(
|
||||
method = "applyRandomEnchantments(Lnet/minecraft/item/ItemStack;Ljava/util/Random;ZZ)V",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Llotr/common/enchant/LOTREnchantmentHelper;setHasEnchant(Lnet/minecraft/item/ItemStack;Llotr/common/enchant/LOTREnchantment;)V"
|
||||
),
|
||||
remap = false
|
||||
)
|
||||
private static void skipNegativeEnchant(ItemStack itemstack, LOTREnchantment ench) {
|
||||
// Only apply if enchant is beneficial
|
||||
if (ench.isBeneficial()) {
|
||||
LOTREnchantmentHelper.setHasEnchant(itemstack, ench);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.zivilon.cinder_loe.util;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
||||
|
||||
public class RangedDamageUtil {
|
||||
public static void applyExtraDamage(LivingHurtEvent event, float multiplier) {
|
||||
EntityLivingBase target = event.entityLiving;
|
||||
float base = event.ammount;
|
||||
float extra = base * multiplier;
|
||||
float currentHealth = target.getHealth();
|
||||
if (currentHealth > extra) {
|
||||
target.setHealth(currentHealth - extra);
|
||||
event.setCanceled(true);
|
||||
} else {
|
||||
event.ammount = currentHealth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
package com.zivilon.cinder_loe.world;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import lotr.common.LOTRDimension;
|
||||
import lotr.common.LOTRMod;
|
||||
import lotr.common.world.biome.LOTRBiome;
|
||||
import lotr.common.world.genlayer.LOTRGenLayerWorld;
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class CinderGenLayerWorld extends LOTRGenLayerWorld {
|
||||
private static byte[] biomeImageData;
|
||||
|
||||
public CinderGenLayerWorld() {
|
||||
super();
|
||||
if (!LOTRGenLayerWorld.loadedBiomeImage()) {
|
||||
try {
|
||||
BufferedImage biomeImage = null;
|
||||
String imageName = "assets/lotr/map/map.png";
|
||||
ModContainer mc = LOTRMod.getModContainer();
|
||||
if (mc.getSource().isFile()) {
|
||||
ZipFile zip = new ZipFile(mc.getSource());
|
||||
Enumeration<? extends ZipEntry> entries = zip.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if (!entry.getName().equals(imageName)) continue;
|
||||
biomeImage = ImageIO.read(zip.getInputStream(entry));
|
||||
}
|
||||
zip.close();
|
||||
} else {
|
||||
File file = new File(LOTRMod.class.getResource("/" + imageName).toURI());
|
||||
biomeImage = ImageIO.read(new FileInputStream(file));
|
||||
}
|
||||
if (biomeImage == null) {
|
||||
throw new RuntimeException("Could not load Cinder biome map image");
|
||||
}
|
||||
imageWidth = biomeImage.getWidth();
|
||||
imageHeight = biomeImage.getHeight();
|
||||
int[] colors = biomeImage.getRGB(0, 0, imageWidth, imageHeight, null, 0, imageWidth);
|
||||
biomeImageData = new byte[imageWidth * imageHeight];
|
||||
for (int i = 0; i < colors.length; ++i) {
|
||||
int color = colors[i];
|
||||
Integer biomeID = LOTRDimension.MIDDLE_EARTH.colorsToBiomeIDs.get(color);
|
||||
if (biomeID != null) {
|
||||
CinderGenLayerWorld.biomeImageData[i] = (byte)biomeID.intValue();
|
||||
continue;
|
||||
}
|
||||
FMLLog.log((Level) Level.ERROR, (String)("Found unknown biome on map " + Integer.toHexString(color)), (Object[])new Object[0]);
|
||||
CinderGenLayerWorld.biomeImageData[i] = (byte) LOTRBiome.ocean.biomeID;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package com.zivilon.cinder_loe.world;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import lotr.common.*;
|
||||
import lotr.common.world.LOTRWorldChunkManager;
|
||||
import lotr.common.world.LOTRWorldProvider;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraftforge.client.IRenderHandler;
|
||||
|
||||
public abstract class CinderWorldProvider extends LOTRWorldProvider {
|
||||
public static int MOON_PHASES = 8;
|
||||
@SideOnly(value= Side.CLIENT)
|
||||
private IRenderHandler lotrSkyRenderer;
|
||||
@SideOnly(value=Side.CLIENT)
|
||||
private IRenderHandler lotrCloudRenderer;
|
||||
@SideOnly(value=Side.CLIENT)
|
||||
private IRenderHandler lotrWeatherRenderer;
|
||||
private boolean spawnHostiles = true;
|
||||
private boolean spawnPeacefuls = true;
|
||||
private double cloudsR;
|
||||
private double cloudsG;
|
||||
private double cloudsB;
|
||||
private double fogR;
|
||||
private double fogG;
|
||||
private double fogB;
|
||||
|
||||
public abstract LOTRDimension getLOTRDimension();
|
||||
|
||||
public void registerWorldChunkManager() {
|
||||
this.worldChunkMgr = new LOTRWorldChunkManager(this.worldObj, this.getLOTRDimension());
|
||||
this.dimensionId = this.getLOTRDimension().dimensionID;
|
||||
}
|
||||
|
||||
public String getWelcomeMessage() {
|
||||
return StatCollector.translateToLocalFormatted((String)"lotr.dimension.enter", (Object[])new Object[]{this.getLOTRDimension().getDimensionName()});
|
||||
}
|
||||
|
||||
public String getDepartMessage() {
|
||||
return StatCollector.translateToLocalFormatted((String)"lotr.dimension.exit", (Object[])new Object[]{this.getLOTRDimension().getDimensionName()});
|
||||
}
|
||||
|
||||
public String getSaveFolder() {
|
||||
return this.getLOTRDimension().dimensionName;
|
||||
}
|
||||
|
||||
public String getDimensionName() {
|
||||
return this.getLOTRDimension().dimensionName;
|
||||
}
|
||||
|
||||
public boolean canRespawnHere() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public BiomeGenBase getBiomeGenForCoords(int i, int k) {
|
||||
Chunk chunk;
|
||||
if (this.worldObj.blockExists(i, 0, k) && (chunk = this.worldObj.getChunkFromBlockCoords(i, k)) != null) {
|
||||
int chunkX = i & 0xF;
|
||||
int chunkZ = k & 0xF;
|
||||
int biomeID = chunk.getBiomeArray()[chunkZ << 4 | chunkX] & 0xFF;
|
||||
if (biomeID == 255) {
|
||||
BiomeGenBase biomegenbase = this.worldChunkMgr.getBiomeGenAt((chunk.xPosition << 4) + chunkX, (chunk.zPosition << 4) + chunkZ);
|
||||
biomeID = biomegenbase.biomeID;
|
||||
chunk.getBiomeArray()[chunkZ << 4 | chunkX] = (byte)(biomeID & 0xFF);
|
||||
}
|
||||
LOTRDimension dim = this.getLOTRDimension();
|
||||
return dim.biomeList[biomeID] == null ? dim.biomeList[0] : dim.biomeList[biomeID];
|
||||
}
|
||||
return this.worldChunkMgr.getBiomeGenAt(i, k);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 636 B |
|
After Width: | Height: | Size: 936 B |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 546 B |
|
After Width: | Height: | Size: 378 B |
|
After Width: | Height: | Size: 840 B |
|
After Width: | Height: | Size: 440 B |
|
After Width: | Height: | Size: 387 B |