From 9d9d69a5abb7476073310f56684d70011305fdce Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 9 Nov 2013 14:08:35 -0500 Subject: [PATCH] Decide to work on a quick vehicle prefab EntityDrivable and its render are copies of the boat. I decide to dump my old code from 1.2.3 and start over. No point and trying to update code that was created from the boat as well. Though i might use that nice tractor model someone left. Anyway everything should be ready for testing. --- src/dark/core/client/ClientProxy.java | 3 + .../core/client/renders/RenderTestCar.java | 79 +++ src/dark/core/common/DarkMain.java | 4 + .../core/prefab/vehicles/EntityDrivable.java | 501 ++++++++++++++++++ .../prefab/vehicles/ItemVehicleSpawn.java | 121 +++++ 5 files changed, 708 insertions(+) create mode 100644 src/dark/core/client/renders/RenderTestCar.java create mode 100644 src/dark/core/prefab/vehicles/EntityDrivable.java create mode 100644 src/dark/core/prefab/vehicles/ItemVehicleSpawn.java diff --git a/src/dark/core/client/ClientProxy.java b/src/dark/core/client/ClientProxy.java index f8f3f91d3..39bf905bd 100644 --- a/src/dark/core/client/ClientProxy.java +++ b/src/dark/core/client/ClientProxy.java @@ -15,11 +15,13 @@ import dark.core.client.gui.GuiBatteryBox; import dark.core.client.gui.GuiCoalGenerator; import dark.core.client.gui.GuiElectricFurnace; import dark.core.client.renders.BlockRenderingHandler; +import dark.core.client.renders.RenderTestCar; import dark.core.common.CommonProxy; import dark.core.common.machines.TileEntityBatteryBox; import dark.core.common.machines.TileEntityCoalGenerator; import dark.core.common.machines.TileEntityElectricFurnace; import dark.core.prefab.ModPrefab; +import dark.core.prefab.vehicles.EntityDrivable; @SideOnly(Side.CLIENT) public class ClientProxy extends CommonProxy @@ -46,6 +48,7 @@ public class ClientProxy extends CommonProxy { RenderingRegistry.registerBlockHandler(new BlockRenderingHandler()); //MinecraftForge.EVENT_BUS.register(SoundHandler.INSTANCE); + RenderingRegistry.registerEntityRenderingHandler(EntityDrivable.class, new RenderTestCar()); } @Override diff --git a/src/dark/core/client/renders/RenderTestCar.java b/src/dark/core/client/renders/RenderTestCar.java new file mode 100644 index 000000000..22eb92c98 --- /dev/null +++ b/src/dark/core/client/renders/RenderTestCar.java @@ -0,0 +1,79 @@ +package dark.core.client.renders; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelBoat; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.entity.Entity; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import dark.core.prefab.vehicles.EntityDrivable; + +@SideOnly(Side.CLIENT) +public class RenderTestCar extends Render +{ + private static final ResourceLocation boatTextures = new ResourceLocation("textures/entity/boat.png"); + + /** instance of ModelBoat for rendering */ + protected ModelBase modelBoat; + + public RenderTestCar() + { + this.shadowSize = 0.0F; + this.modelBoat = new ModelBoat(); + } + + /** The render method used in RenderBoat that renders the boat model. */ + public void renderBoat(EntityDrivable par1EntityBoat, double par2, double par4, double par6, float par8, float par9) + { + GL11.glPushMatrix(); + GL11.glTranslatef((float) par2, (float) par4, (float) par6); + GL11.glRotatef(180.0F - par8, 0.0F, 1.0F, 0.0F); + float f2 = (float) par1EntityBoat.getTimeSinceHit() - par9; + float f3 = par1EntityBoat.getDamageTaken() - par9; + + if (f3 < 0.0F) + { + f3 = 0.0F; + } + + if (f2 > 0.0F) + { + GL11.glRotatef(MathHelper.sin(f2) * f2 * f3 / 10.0F * (float) par1EntityBoat.getForwardDirection(), 1.0F, 0.0F, 0.0F); + } + + float f4 = 0.75F; + GL11.glScalef(f4, f4, f4); + GL11.glScalef(1.0F / f4, 1.0F / f4, 1.0F / f4); + this.bindEntityTexture(par1EntityBoat); + GL11.glScalef(-1.0F, -1.0F, 1.0F); + this.modelBoat.render(par1EntityBoat, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F); + GL11.glPopMatrix(); + } + + protected ResourceLocation getBoatTextures(EntityDrivable par1EntityBoat) + { + return boatTextures; + } + + /** Returns the location of an entity's texture. Doesn't seem to be called unless you call + * Render.bindEntityTexture. */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.getBoatTextures((EntityDrivable) par1Entity); + } + + /** Actually renders the given argument. This is a synthetic bridge method, always casting down + * its argument and then handing it off to a worker function which does the actual work. In all + * probabilty, the class Render is generic (Render 40.0F) + { + if (this.riddenByEntity != null) + { + this.riddenByEntity.mountEntity(this); + } + + if (!flag) + { + this.dropItemWithOffset(Item.boat.itemID, 1, 0.0F); + } + + this.setDead(); + } + + return true; + } + else + { + return true; + } + } + + @Override + @SideOnly(Side.CLIENT) + public void performHurtAnimation() + { + this.setForwardDirection(-this.getForwardDirection()); + this.setTimeSinceHit(10); + this.setDamageTaken(this.getDamageTaken() * 11.0F); + } + + /** Returns true if other Entities should be prevented from moving through this Entity. */ + @Override + public boolean canBeCollidedWith() + { + return !this.isDead; + } + + @Override + @SideOnly(Side.CLIENT) + public void setPositionAndRotation2(double xx, double yy, double zz, float yaw, float pitch, int roll) + { + if (this.field_70279_a) + { + this.boatPosRotationIncrements = roll + 5; + } + else + { + double d3 = xx - this.posX; + double d4 = yy - this.posY; + double d5 = zz - this.posZ; + double d6 = d3 * d3 + d4 * d4 + d5 * d5; + + if (d6 <= 1.0D) + { + return; + } + + this.boatPosRotationIncrements = 3; + } + + this.boatX = xx; + this.boatY = yy; + this.boatZ = zz; + this.boatYaw = yaw; + this.boatPitch = pitch; + this.motionX = this.velocityX; + this.motionY = this.velocityY; + this.motionZ = this.velocityZ; + } + + @Override + @SideOnly(Side.CLIENT) + public void setVelocity(double motionX, double motionY, double motionZ) + { + this.velocityX = this.motionX = motionX; + this.velocityY = this.motionY = motionY; + this.velocityZ = this.motionZ = motionZ; + } + + /** Called to update the entity's position/logic. */ + @Override + public void onUpdate() + { + super.onUpdate(); + + if (this.getTimeSinceHit() > 0) + { + this.setTimeSinceHit(this.getTimeSinceHit() - 1); + } + + if (this.getDamageTaken() > 0.0F) + { + this.setDamageTaken(this.getDamageTaken() - 1.0F); + } + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + double d0 = 0.0D; + + double motionMag = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + double mX; + double mZ; + + if (motionMag > 0.26249999999999996D) + { + mX = Math.cos(this.rotationYaw * Math.PI / 180.0D); + mZ = Math.sin(this.rotationYaw * Math.PI / 180.0D); + } + + double d10; + double d11; + + if (this.worldObj.isRemote && this.field_70279_a) + { + if (this.boatPosRotationIncrements > 0) + { + mX = this.posX + (this.boatX - this.posX) / this.boatPosRotationIncrements; + mZ = this.posY + (this.boatY - this.posY) / this.boatPosRotationIncrements; + d11 = this.posZ + (this.boatZ - this.posZ) / this.boatPosRotationIncrements; + d10 = MathHelper.wrapAngleTo180_double(this.boatYaw - this.rotationYaw); + this.rotationYaw = (float) (this.rotationYaw + d10 / this.boatPosRotationIncrements); + this.rotationPitch = (float) (this.rotationPitch + (this.boatPitch - this.rotationPitch) / this.boatPosRotationIncrements); + --this.boatPosRotationIncrements; + this.setPosition(mX, mZ, d11); + this.setRotation(this.rotationYaw, this.rotationPitch); + } + else + { + mX = this.posX + this.motionX; + mZ = this.posY + this.motionY; + d11 = this.posZ + this.motionZ; + this.setPosition(mX, mZ, d11); + + if (this.onGround) + { + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } + + this.motionX *= 0.9900000095367432D; + this.motionY *= 0.949999988079071D; + this.motionZ *= 0.9900000095367432D; + } + } + else + { + if (d0 < 1.0D) + { + mX = d0 * 2.0D - 1.0D; + this.motionY += 0.03999999910593033D * mX; + } + else + { + if (this.motionY < 0.0D) + { + this.motionY /= 2.0D; + } + + this.motionY += 0.007000000216066837D; + } + + if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityLivingBase) + { + mX = ((EntityLivingBase) this.riddenByEntity).moveForward; + + if (mX > 0.0D) + { + mZ = -Math.sin((this.riddenByEntity.rotationYaw * (float) Math.PI / 180.0F)); + d11 = Math.cos((this.riddenByEntity.rotationYaw * (float) Math.PI / 180.0F)); + this.motionX += mZ * this.speedMultiplier * 0.05000000074505806D; + this.motionZ += d11 * this.speedMultiplier * 0.05000000074505806D; + } + } + + mX = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (mX > 0.35D) + { + mZ = 0.35D / mX; + this.motionX *= mZ; + this.motionZ *= mZ; + mX = 0.35D; + } + + if (mX > motionMag && this.speedMultiplier < 0.35D) + { + this.speedMultiplier += (0.35D - this.speedMultiplier) / 35.0D; + + if (this.speedMultiplier > 0.35D) + { + this.speedMultiplier = 0.35D; + } + } + else + { + this.speedMultiplier -= (this.speedMultiplier - 0.07D) / 35.0D; + + if (this.speedMultiplier < 0.07D) + { + this.speedMultiplier = 0.07D; + } + } + + if (this.onGround) + { + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.isCollidedHorizontally && motionMag > 0.2D) + { + //TODO damage the vehicle as the player just collide with a wall + } + else + { + //Slowly drop speed + this.motionX *= 0.9900000095367432D; + this.motionY *= 0.949999988079071D; + this.motionZ *= 0.9900000095367432D; + } + + this.rotationPitch = 0.0F; + mZ = this.rotationYaw; + d11 = this.prevPosX - this.posX; + d10 = this.prevPosZ - this.posZ; + + if (d11 * d11 + d10 * d10 > 0.001D) + { + mZ = ((float) (Math.atan2(d10, d11) * 180.0D / Math.PI)); + } + + double d12 = MathHelper.wrapAngleTo180_double(mZ - this.rotationYaw); + + if (d12 > 20.0D) + { + d12 = 20.0D; + } + + if (d12 < -20.0D) + { + d12 = -20.0D; + } + + this.rotationYaw = (float) (this.rotationYaw + d12); + this.setRotation(this.rotationYaw, this.rotationPitch); + + if (!this.worldObj.isRemote) + { + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + int l; + + if (list != null && !list.isEmpty()) + { + for (l = 0; l < list.size(); ++l) + { + Entity entity = (Entity) list.get(l); + + if (entity != this.riddenByEntity && entity.canBePushed() && entity instanceof EntityBoat) + { + entity.applyEntityCollision(this); + } + } + } + + for (l = 0; l < 4; ++l) + { + int i1 = MathHelper.floor_double(this.posX + ((l % 2) - 0.5D) * 0.8D); + int j1 = MathHelper.floor_double(this.posZ + ((l / 2) - 0.5D) * 0.8D); + + for (int k1 = 0; k1 < 2; ++k1) + { + int l1 = MathHelper.floor_double(this.posY) + k1; + int i2 = this.worldObj.getBlockId(i1, l1, j1); + + if (i2 == Block.snow.blockID) + { + this.worldObj.setBlockToAir(i1, l1, j1); + } + else if (i2 == Block.waterlily.blockID) + { + this.worldObj.destroyBlock(i1, l1, j1, true); + } + } + } + + if (this.riddenByEntity != null && this.riddenByEntity.isDead) + { + this.riddenByEntity = null; + } + } + } + } + + @Override + public void updateRiderPosition() + { + if (this.riddenByEntity != null) + { + double d0 = Math.cos(this.rotationYaw * Math.PI / 180.0D) * 0.4D; + double d1 = Math.sin(this.rotationYaw * Math.PI / 180.0D) * 0.4D; + this.riddenByEntity.setPosition(this.posX + d0, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + d1); + } + } + + /** (abstract) Protected helper method to write subclass entity data to NBT. */ + @Override + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) + { + } + + /** (abstract) Protected helper method to read subclass entity data from NBT. */ + @Override + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) + { + } + + @Override + @SideOnly(Side.CLIENT) + public float getShadowSize() + { + return 0.0F; + } + + /** First layer of player interaction */ + @Override + public boolean interactFirst(EntityPlayer player) + { + if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer && this.riddenByEntity != player) + { + return true; + } + else + { + if (!this.worldObj.isRemote) + { + player.mountEntity(this); + } + + return true; + } + } + + /** Sets the damage taken from the last hit. */ + public void setDamageTaken(float par1) + { + this.dataWatcher.updateObject(19, Float.valueOf(par1)); + } + + /** Gets the damage taken from the last hit. */ + public float getDamageTaken() + { + return this.dataWatcher.getWatchableObjectFloat(19); + } + + /** Sets the time to count down from since the last time entity was hit. */ + public void setTimeSinceHit(int par1) + { + this.dataWatcher.updateObject(17, Integer.valueOf(par1)); + } + + /** Gets the time since the last hit. */ + public int getTimeSinceHit() + { + return this.dataWatcher.getWatchableObjectInt(17); + } + + /** Sets the forward direction of the entity. */ + public void setForwardDirection(int par1) + { + this.dataWatcher.updateObject(18, Integer.valueOf(par1)); + } + + /** Gets the forward direction of the entity. */ + public int getForwardDirection() + { + return this.dataWatcher.getWatchableObjectInt(18); + } + + @SideOnly(Side.CLIENT) + public void func_70270_d(boolean par1) + { + this.field_70279_a = par1; + } + +} diff --git a/src/dark/core/prefab/vehicles/ItemVehicleSpawn.java b/src/dark/core/prefab/vehicles/ItemVehicleSpawn.java new file mode 100644 index 000000000..788e3f400 --- /dev/null +++ b/src/dark/core/prefab/vehicles/ItemVehicleSpawn.java @@ -0,0 +1,121 @@ +package dark.core.prefab.vehicles; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.EnumMovingObjectType; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; +import net.minecraft.world.World; +import dark.core.common.DarkMain; +import dark.core.helpers.MathHelper; + +/** Basic item used to spawn a vehicle + * + * @author DarkGuardsman */ +public class ItemVehicleSpawn extends Item +{ + public ItemVehicleSpawn() + { + super(DarkMain.getNextItemId()); + this.setUnlocalizedName("Vehicle"); + } + + @Override + public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) + { + float playerLook = 1.0F; + float playerPitch = player.prevRotationPitch + (player.rotationPitch - player.prevRotationPitch) * playerLook; + float playerYaw = player.prevRotationYaw + (player.rotationYaw - player.prevRotationYaw) * playerLook; + + //Find were the current player is looking at + double lookX = player.prevPosX + (player.posX - player.prevPosX) * playerLook; + double lookY = player.prevPosY + (player.posY - player.prevPosY) * playerLook + 1.62D - player.yOffset; + double lookZ = player.prevPosZ + (player.posZ - player.prevPosZ) * playerLook; + + Vec3 start = world.getWorldVec3Pool().getVecFromPool(lookX, lookY, lookZ); + + //Find the vector X blocks away from the player in the same direction as the player is looking + double searchRange = 5.0D; + float deltaX = MathHelper.sin(-playerYaw * 0.017453292F - (float) Math.PI) * -MathHelper.cos(-playerPitch * 0.017453292F); + float deltaY = MathHelper.sin(-playerPitch * 0.017453292F); + float deltaZ = MathHelper.cos(-playerYaw * 0.017453292F - (float) Math.PI) * -MathHelper.cos(-playerPitch * 0.017453292F); + + Vec3 end = start.addVector(deltaX * searchRange, deltaY * searchRange, deltaZ * searchRange); + + //Check for collision between player look, and player look expanded + MovingObjectPosition hitObj = world.clip(start, end, true); + + if (hitObj == null) + { + return itemStack; + } + else + { + //Check for collisions using the entities collision box against the spawn location + Vec3 playerView = player.getLook(playerLook); + boolean entityInTheWay = false; + final List entities = world.getEntitiesWithinAABBExcludingEntity(player, player.boundingBox.addCoord(playerView.xCoord * searchRange, playerView.yCoord * searchRange, playerView.zCoord * searchRange).expand(1f, 1f, 1f)); + + for (int i = 0; i < entities.size(); ++i) + { + Entity checkEntity = (Entity) entities.get(i); + + if (checkEntity.canBeCollidedWith()) + { + float entityBoarderSize = checkEntity.getCollisionBorderSize(); + AxisAlignedBB boundBox = checkEntity.boundingBox.expand(entityBoarderSize, entityBoarderSize, entityBoarderSize); + + if (boundBox.isVecInside(start)) + { + entityInTheWay = true; + } + } + } + //IF an entity is in the way return + if (entityInTheWay) + { + return itemStack; + } + else + { + //Else start to calculate placement + if (hitObj.typeOfHit == EnumMovingObjectType.TILE) + { + int y = hitObj.blockY; + + //Move down if snow + if (world.getBlockId(hitObj.blockX, hitObj.blockY, hitObj.blockZ) == Block.snow.blockID) + { + --y; + } + + EntityDrivable spawnedEntity = new EntityDrivable(world, hitObj.blockX + 0.5F, y + 1.0F, hitObj.blockZ + 0.5F); + + //Last collision check using the entities collision box + if (!world.getCollidingBoundingBoxes(spawnedEntity, spawnedEntity.boundingBox.expand(-0.1D, -0.1D, -0.1D)).isEmpty()) + { + return itemStack; + } + + if (!world.isRemote) + { + world.spawnEntityInWorld(spawnedEntity); + } + + if (!player.capabilities.isCreativeMode) + { + --itemStack.stackSize; + } + } + + return itemStack; + } + } + } +}