Jump to content

[SOLVED] Changing eye height / camera render viewpoint


coolAlias

Recommended Posts

Hi all,

 

I've been messing around with changing the player's size, and I've run into a snag: I can't seem to figure out how to get the player's in-game viewpoint to render at what should be their current eye height.

 

Changing player.eyeHeight has no visible effect (and, quite counter-intuitively, the value appears to be zero by default on the client anyway).

 

Then I found that Minecraft.getMinecraft().renderViewEntity is what determines the camera position and angle, but the docs say it's not suitable for changing the viewpoint mid-render. Indeed, when I changed the y position of the renderViewEntity during either render tick or render game overlay events, not only does the game bounce up and down, but the player also renders as floating above the ground by whatever value I set, which makes sense when I think about it because mc.renderViewEntity is likely just pointing to mc.thePlayer's memory location.

 

So my question is, what's a good way to alter the in-game render position without also affecting the player's render position?

 

Cheers,

coolAlias

Link to comment
Share on other sites

Hi coolAlias

 

I think you may need to use reflection to modify the base class; the setting up of the viewpoint in EntityRenderer.setupCameraTransform and .orientCamera doesn't look like you can easily "intercept" it.

 

If you could find a way to add an extra GL11.glTranslatef after the setupCameraTransform and before the start of the rendering, that might do it.  Alternatively, you might be able to change the renderViewEntity to your own copy of the player, which you manually synchronise with the real player.  You're right that renderViewEntity refers to the player object, but perhaps it doesn't have to:

 

EntityRenderer.renderWorld:
        if (this.mc.renderViewEntity == null)
        {
            this.mc.renderViewEntity = this.mc.thePlayer;
        }

 

If necessary you might be able to change it immediately before render, then change it back immediately afterwards

 

-TGG

 

 

Link to comment
Share on other sites

Thanks TGG, that sounds reasonable. To change the player's render size, I did sneak in an extra glScalef using RenderPlayerEvent.Pre and Post, but that didn't work for the render view. Too bad there isn't a Forge hook in EntityRenderer#orientCamera :P

 

Anyway, I'll post back here after I've had a chance to try your suggestion. Thanks again.

 

EDIT: I tried creating a new EntityClientPlayerMP as a sort of fake player copy, and that kind of worked - the viewpoint was indeed where I put it, but the camera angle was freaking out between two different views. The same thing happened when I used a dummy extended EntityLivingBase, suggesting that the renderview entity is switching back and forth between the one I'm setting and mc.thePlayer.

 

I set the fake entity at the start of the render tick (only if it is null do I create a new one), and tried both leaving it set and setting mc.renderViewEntity back to mc.thePlayer or null at tick end; neither way prevents the camera from freaking out which is strange, since the renderViewEntity should only be set in EntityRenderer when null. At any rate, lots of bad stuff happens when the renderViewEntity isn't an instance of EntityPlayer, so looks like it's time to try the first suggestion ;)

 

EDIT 2: Turns out the camera freaking out was because I forgot to set the previous positions... oops xD So actually the fake player / entitylivingbase works pretty well for changing the viewpoint, though 3rd person is still a bit jittery while walking. Using RenderPlayerEvent.Pre was still funky, but moving it to RenderGameOverlayEvent.Pre (for element type HELMET) works very well for 1st person, and avoids the camera shake in 3rd person (player movement is jittery).

 

Interestingly, I don't have to explicitly set the camera height and it just works, even though I set the fakePlayer.posY to mc.thePlayer.posY (after resizing thePlayer, but not ever changing the position [due to Illegal Stance rubbish - same with trying to use yOffset]).

 

However, as soon as I try to left-click, even air, it kicks me from the game with the following message:

"[WARNING] [Minecraft-Server] Player coolAlias tried to attack an invalid entity"

 

I tried to set the renderViewEntity back to mc.thePlayer for all overlays except the HELMET overlay, with the effect that clicking worked, but the camera was back to the original position.

 

For context, here is my current code:

 

Resizing of the player is done using Entity#setSize using either magnified or original width/height values. Size is changed only when the special item is equipped or unequipped.

 

OverlayEvent

 

@ForgeSubscribe
public void onPreRenderGame(RenderGameOverlayEvent.Pre event) {
if (event.type == ElementType.HELMET) {
	ItemStack mask = mc.thePlayer.getCurrentArmor(ArmorIndex.WORN_HELM);
	if (mask != null && mask.getItem() == ZSSItems.maskGiants) {
		if (fakePlayer == null) {
			fakePlayer = new FakeClientPlayer(mc.thePlayer.worldObj);
		}
		// offset slightly so not looking at inside of player model:
		Vec3 vec3 = mc.thePlayer.getLookVec();
		double dx = (mc.gameSettings.thirdPersonView > 0 ? 0.0D : vec3.xCoord);
		double dz = (mc.gameSettings.thirdPersonView > 0 ? 0.0D : vec3.zCoord);

		// set position and angles; note that posY is not altered but camera still correct:
		fakePlayer.setLocationAndAngles(mc.thePlayer.posX + dx, mc.thePlayer.posY, mc.thePlayer.posZ + dz, mc.thePlayer.rotationYaw, mc.thePlayer.rotationPitch);

		// set previous values to prevent camera from freaking out:
		fakePlayer.prevRotationPitch = mc.thePlayer.prevRotationPitch;
		fakePlayer.prevRotationYaw = mc.thePlayer.prevRotationYaw;
		fakePlayer.rotationYawHead = mc.thePlayer.rotationYawHead;
		fakePlayer.prevPosX = mc.thePlayer.prevPosX + dx;
		fakePlayer.prevPosY = mc.thePlayer.prevPosY;
		fakePlayer.prevPosZ = mc.thePlayer.prevPosZ + dz;
		mc.renderViewEntity = fakePlayer;
	} else if (fakePlayer != null) {
		// not wearing the mask, back to regular camera view
		fakePlayer = null;
	}
} else {
	// ruins the camera effect
	// mc.renderViewEntity = mc.thePlayer;
}
}

 

 

FakeClientPlayer (nothing in it really specifies client only, but whatever)

 

public class FakeClientPlayer extends EntityLivingBase {

public FakeClientPlayer(World world) {
	super(world);//, "fakeClientPlayer");
}

@Override
public ItemStack getHeldItem() { return null; }
@Override
public ItemStack getCurrentItemOrArmor(int i) { return null; }
@Override
public void setCurrentItemOrArmor(int i, ItemStack itemstack) {}
@Override
public ItemStack[] getLastActiveItems() { return null; }
@Override
protected void updateFallState(double par1, boolean par3) {}
@Override
public void onEntityUpdate() {}
@Override
protected void onDeathUpdate() {}
@Override
protected int decreaseAirSupply(int amount) { return 0; }
@Override
public void setRevengeTarget(EntityLivingBase entity) {}
@Override
public void setLastAttacker(Entity entity) {}
@Override
public void writeEntityToNBT(NBTTagCompound compound) {}
@Override
public void readEntityFromNBT(NBTTagCompound compound) {}
@Override
protected void updatePotionEffects() {}
@Override
public void clearActivePotions() {}
@Override
public boolean isPotionActive(int par1) { return false; }
@Override
public boolean isPotionActive(Potion potion) { return false; }
@Override
public PotionEffect getActivePotionEffect(Potion potion) { return null; }
@Override
public void addPotionEffect(PotionEffect potion) {}
@Override
public boolean isPotionApplicable(PotionEffect potion) { return false; }
@Override
public void removePotionEffectClient(int id) {}
@Override
public void removePotionEffect(int id) {}
@Override
protected void onNewPotionEffect(PotionEffect potion) {}
@Override
protected void onChangedPotionEffect(PotionEffect potion, boolean par2) {}
@Override
protected void onFinishedPotionEffect(PotionEffect potion) {}
@Override
public void heal(float amount) {}
@Override
public boolean attackEntityFrom(DamageSource source, float amount) { return false; }
@Override
public void renderBrokenItemStack(ItemStack stack) {}
@Override
public void onDeath(DamageSource source) {}
@Override
public void knockBack(Entity entity, float f, double x, double z) {}
@Override
public boolean isOnLadder() { return false; }
@Override
protected void fall(float distance) {}
@Override
@SideOnly(Side.CLIENT)
public void performHurtAnimation() {}
@Override
public int getTotalArmorValue() { return 0; }
@Override
protected float applyArmorCalculations(DamageSource source, float amount) { return 0.0F; }
@Override
protected float applyPotionDamageCalculations(DamageSource source, float amount) { return 0.0F; }
@Override
protected void damageEntity(DamageSource source, float amount) {}
@Override
public EntityLivingBase func_94060_bK() { return null; }
@Override
public void swingItem() {}
@Override
@SideOnly(Side.CLIENT)
public void handleHealthUpdate(byte par1) {}
@Override
protected void kill() {}
@Override
protected void updateArmSwingProgress() {}
@Override
public void setSprinting(boolean isSprinting) {}
@Override
protected float getSoundPitch() { return 1.0F; }
@Override
protected boolean isMovementBlocked() { return false; }
@Override
public void dismountEntity(Entity entity) {}
@Override
protected void jump() {}
@Override
public void moveEntityWithHeading(float strafe, float forward) {}
@Override
public float getAIMoveSpeed() { return 0.1F; }
@Override
public boolean attackEntityAsMob(Entity entity) { return false; }
@Override
public void onUpdate() {}
@Override
public void onLivingUpdate() {}
@Override
protected void updateAITasks() {}
@Override
protected void collideWithNearbyEntities() {}
@Override
protected void collideWithEntity(Entity entity) {}
@Override
public void updateRidden() {}
@Override
protected void updateAITick() {}
@Override
protected void updateEntityActionState() {}
@Override
public void setJumping(boolean isJumping) {}
@Override
public void onItemPickup(Entity item, int stackSize) {}
//@Override
//@SideOnly(Side.CLIENT)
//public float getSwingProgress(float par1) { return 0.0F; }
@Override
public boolean canBeCollidedWith() { return false; }
@Override
public boolean canBePushed() { return false; }

public float getEyeHeight()
{
	return this.height * 0.85F;
}

@Override
protected void setBeenAttacked() {}
@Override
public void setAbsorptionAmount(float amount) {}
@Override
public boolean isOnSameTeam(EntityLivingBase entity) { return false; }
@Override
public boolean isOnTeam(Team team) { return false; }
@Override
public void curePotionEffects(ItemStack curativeItem) {}
/*
@Override
public void sendChatToPlayer(ChatMessageComponent chatmessagecomponent) {}

@Override
public boolean canCommandSenderUseCommand(int i, String s) { return false; }

@Override
public ChunkCoordinates getPlayerCoordinates() {
	return new ChunkCoordinates(MathHelper.floor_double(this.posX + 0.5D), MathHelper.floor_double(this.posY + 0.5D), MathHelper.floor_double(this.posZ + 0.5D));
}
 */
}

 

Link to comment
Share on other sites

It might be unstable if you changes the Camera Entity every time.

See EntityRenderer#orientCamera, which sets up the Camera.

You can see that 'f1' variable in the function is setting eye height,

and it was the entity's yOffset - 1.62F.

So you can do it by setting yOffset of the Entity!

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

It might be unstable if you changes the Camera Entity every time.

See EntityRenderer#orientCamera, which sets up the Camera.

You can see that 'f1' variable in the function is setting eye height,

and it was the entity's yOffset - 1.62F.

So you can do it by setting yOffset of the Entity!

If only it were that simple. Changing the yOffset of the player results in the game crashing due to "an Illegal Stance" - that was the first thing I tried ;)

Link to comment
Share on other sites

However, as soon as I try to left-click, even air, it kicks me from the game with the following message:

"[WARNING] [Minecraft-Server] Player coolAlias tried to attack an invalid entity"

Do you think the look vector, or whatever the server thinks you're looking at needs to be modified?  The render stuff you're doing presumably is client side, but at some point you have to translate what you're looking at into server side and maybe that is getting mucked up?  Although I'm not sure why that would actually crash though, you think it would just think you're looking at the wrong thing and process as a proper left-click on whatever it thought you were looking at.

 

I don't have Minecraft on this computer, but can't you look up that error message in the code and maybe figure out where it is going wrong based on the location of that message?

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

However, as soon as I try to left-click, even air, it kicks me from the game with the following message:

"[WARNING] [Minecraft-Server] Player coolAlias tried to attack an invalid entity"

Do you think the look vector, or whatever the server thinks you're looking at needs to be modified?  The render stuff you're doing presumably is client side, but at some point you have to translate what you're looking at into server side and maybe that is getting mucked up?  Although I'm not sure why that would actually crash though, you think it would just think you're looking at the wrong thing and process as a proper left-click on whatever it thought you were looking at.

 

I don't have Minecraft on this computer, but can't you look up that error message in the code and maybe figure out where it is going wrong based on the location of that message?

That is indeed the problem - Minecraft uses the renderViewEntity not just for camera position, but also for calculating various other things among which is the objectMouseOver (from EntityRenderer). Changing the renderViewEntity to my dummy entity living base works for changing the camera position, but breaks the mouse over calculations somehow, and probably breaks many other things as well that I have yet to notice.

 

It is possible to intercept mouse clicks, so it may also be possible to completely gloss over the vanilla objectMouseOver, using a custom one instead, but I am not a fan of that kind of solution in general.

 

One would think that adjusting the camera's render viewpoint would be a simple matter of adjusting a single Y value or the like, but it's turning out to be much more complicated than I expected >.<

 

Anyway, if I make any more progress on it, I will post it here. Until then, if anyone happens to know an easier way to accomplish this, I would be much obliged.

Link to comment
Share on other sites

There is a mod that allows the player to morph into creatures and mobs, such as a bat. The mod author must surely have solved this issue. I wonder if the author would share his experience.

Link to comment
Share on other sites

It might be unstable if you changes the Camera Entity every time.

See EntityRenderer#orientCamera, which sets up the Camera.

You can see that 'f1' variable in the function is setting eye height,

and it was the entity's yOffset - 1.62F.

So you can do it by setting yOffset of the Entity!

If only it were that simple. Changing the yOffset of the player results in the game crashing due to "an Illegal Stance" - that was the first thing I tried ;)

 

You can do that by setting yOffset on Render Tick Start, and return it to original yOffset on Render Tick End.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

You can do that by setting yOffset on Render Tick Start, and return it to original yOffset on Render Tick End.

Well look at that, so you can! :D hahaha, though it has the hilarious side effect of keeping the same bounding box for collisions, so most of the player's body is in the ground with just his giant head sticking out - at least it doesn't crash when I click on stuff xD

 

I could have sworn I tried setting the yOffset back to normal, but apparently I didn't, at least not every tick. Thanks for the tip!

 

EDIT: Actually, that doesn't work for changing the viewpoint of the camera - it actually ends up moving to the player's posY (not even normal eye height!), even after changing player.eyeHeight. The player's bounding box is correct, since I do not fall through the ground and cannot walk under trees and such (I made the player about 4-5 blocks tall), and I can easily fix the rendering of the player to match the bounding box position, but the camera stays at the ground... Looks like it's back to square one :(

 

@sequituri - iChun's Morph mod is indeed open source, and I've seen a video where the eye height moves higher or lower, so he certainly figured out how to do it. Hopefully it's not some crazy complicated mechanism like the rest of his code :P I'll have to poke around in there and see if I can find it.

Link to comment
Share on other sites

I'm not at a computer with Minecraft source on it right now, but have you looked at the code for when you change the viewpoint in vanilla Minecraft when you press F5?  If that can move the camera to behind / in front / or "in" your player while retaining all other gameplay, it seems that has got to give you some sort of clue.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

I'm not at a computer with Minecraft source on it right now, but have you looked at the code for when you change the viewpoint in vanilla Minecraft when you press F5?  If that can move the camera to behind / in front / or "in" your player while retaining all other gameplay, it seems that has got to give you some sort of clue.

The code for third person view just moves the camera to the looking direction, so it cannot give any clue for this case.

 

Btw, I think the ASM is necessary for this case.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

The code for third person view just moves the camera to the looking direction, so it cannot give any clue for this case.

 

Btw, I think the ASM is necessary for this case.

 

But isn't moving the camera pretty much what he's hoping to do?  Just move it to where the eyes are supposed to be, right?  If you can move it "to the looking direction" you should be able to figure out how to move it elsewhere.

 

In particular, if you look at the orientCamera() method of the EntityRenderer class, the description of the method says "sets up player's eye (or camera in third person mode)".  In fact the code for orientCamera() method includes changing camera for debug camera mode, for sleeping in bed, third person, etc.

 

So why isn't the OP's desire to move camera to different "eye height" pretty much the same as having a debug camera that is just at same level as the model's eye?

 

Here is the code from the orientCamera() class.  It seems to have a lot of examples of controlling the camera:

 

/**

    * sets up player's eye (or camera in third person mode)

    */

    private void orientCamera(float par1)

    {

        EntityLivingBase entitylivingbase = this.mc.renderViewEntity;

        float f1 = entitylivingbase.yOffset - 1.62F;

        double d0 = entitylivingbase.prevPosX + (entitylivingbase.posX - entitylivingbase.prevPosX) * (double)par1;

        double d1 = entitylivingbase.prevPosY + (entitylivingbase.posY - entitylivingbase.prevPosY) * (double)par1 - (double)f1;

        double d2 = entitylivingbase.prevPosZ + (entitylivingbase.posZ - entitylivingbase.prevPosZ) * (double)par1;

        GL11.glRotatef(this.prevCamRoll + (this.camRoll - this.prevCamRoll) * par1, 0.0F, 0.0F, 1.0F);

 

        if (entitylivingbase.isPlayerSleeping())

        {

            f1 = (float)((double)f1 + 1.0D);

            GL11.glTranslatef(0.0F, 0.3F, 0.0F);

 

            if (!this.mc.gameSettings.debugCamEnable)

            {

                ForgeHooksClient.orientBedCamera(mc, entitylivingbase);

                GL11.glRotatef(entitylivingbase.prevRotationYaw + (entitylivingbase.rotationYaw - entitylivingbase.prevRotationYaw) * par1 + 180.0F, 0.0F, -1.0F, 0.0F);

                GL11.glRotatef(entitylivingbase.prevRotationPitch + (entitylivingbase.rotationPitch - entitylivingbase.prevRotationPitch) * par1, -1.0F, 0.0F, 0.0F);

            }

        }

        else if (this.mc.gameSettings.thirdPersonView > 0)

        {

            double d7 = (double)(this.thirdPersonDistanceTemp + (this.thirdPersonDistance - this.thirdPersonDistanceTemp) * par1);

            float f2;

            float f6;

 

            if (this.mc.gameSettings.debugCamEnable)

            {

                f6 = this.prevDebugCamYaw + (this.debugCamYaw - this.prevDebugCamYaw) * par1;

                f2 = this.prevDebugCamPitch + (this.debugCamPitch - this.prevDebugCamPitch) * par1;

                GL11.glTranslatef(0.0F, 0.0F, (float)(-d7));

                GL11.glRotatef(f2, 1.0F, 0.0F, 0.0F);

                GL11.glRotatef(f6, 0.0F, 1.0F, 0.0F);

            }

            else

            {

                f6 = entitylivingbase.rotationYaw;

                f2 = entitylivingbase.rotationPitch;

 

                if (this.mc.gameSettings.thirdPersonView == 2)

                {

                    f2 += 180.0F;

                }

 

                double d3 = (double)(-MathHelper.sin(f6 / 180.0F * (float)Math.PI) * MathHelper.cos(f2 / 180.0F * (float)Math.PI)) * d7;

                double d4 = (double)(MathHelper.cos(f6 / 180.0F * (float)Math.PI) * MathHelper.cos(f2 / 180.0F * (float)Math.PI)) * d7;

                double d5 = (double)(-MathHelper.sin(f2 / 180.0F * (float)Math.PI)) * d7;

 

                for (int k = 0; k < 8; ++k)

                {

                    float f3 = (float)((k & 1) * 2 - 1);

                    float f4 = (float)((k >> 1 & 1) * 2 - 1);

                    float f5 = (float)((k >> 2 & 1) * 2 - 1);

                    f3 *= 0.1F;

                    f4 *= 0.1F;

                    f5 *= 0.1F;

                    MovingObjectPosition movingobjectposition = this.mc.theWorld.rayTraceBlocks(this.mc.theWorld.getWorldVec3Pool().getVecFromPool(d0 + (double)f3, d1 + (double)f4, d2 + (double)f5), this.mc.theWorld.getWorldVec3Pool().getVecFromPool(d0 - d3 + (double)f3 + (double)f5, d1 - d5 + (double)f4, d2 - d4 + (double)f5));

 

                    if (movingobjectposition != null)

                    {

                        double d6 = movingobjectposition.hitVec.distanceTo(this.mc.theWorld.getWorldVec3Pool().getVecFromPool(d0, d1, d2));

 

                        if (d6 < d7)

                        {

                            d7 = d6;

                        }

                    }

                }

 

                if (this.mc.gameSettings.thirdPersonView == 2)

                {

                    GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);

                }

 

                GL11.glRotatef(entitylivingbase.rotationPitch - f2, 1.0F, 0.0F, 0.0F);

                GL11.glRotatef(entitylivingbase.rotationYaw - f6, 0.0F, 1.0F, 0.0F);

                GL11.glTranslatef(0.0F, 0.0F, (float)(-d7));

                GL11.glRotatef(f6 - entitylivingbase.rotationYaw, 0.0F, 1.0F, 0.0F);

                GL11.glRotatef(f2 - entitylivingbase.rotationPitch, 1.0F, 0.0F, 0.0F);

            }

        }

        else

        {

            GL11.glTranslatef(0.0F, 0.0F, -0.1F);

        }

 

        if (!this.mc.gameSettings.debugCamEnable)

        {

            GL11.glRotatef(entitylivingbase.prevRotationPitch + (entitylivingbase.rotationPitch - entitylivingbase.prevRotationPitch) * par1, 1.0F, 0.0F, 0.0F);

            GL11.glRotatef(entitylivingbase.prevRotationYaw + (entitylivingbase.rotationYaw - entitylivingbase.prevRotationYaw) * par1 + 180.0F, 0.0F, 1.0F, 0.0F);

        }

 

        GL11.glTranslatef(0.0F, f1, 0.0F);

        d0 = entitylivingbase.prevPosX + (entitylivingbase.posX - entitylivingbase.prevPosX) * (double)par1;

        d1 = entitylivingbase.prevPosY + (entitylivingbase.posY - entitylivingbase.prevPosY) * (double)par1 - (double)f1;

        d2 = entitylivingbase.prevPosZ + (entitylivingbase.posZ - entitylivingbase.prevPosZ) * (double)par1;

        this.cloudFog = this.mc.renderGlobal.hasCloudFog(d0, d1, d2, par1);

    }

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

@jabelar You're correct that orientCamera is where F5 (i.e. 3rd person mode) and other camera-related effects are handled, but it's useless to me without using ASM as there is no Forge hook called from within that method (other than one for sleeping, for some reason). What this means is that trying to change any of the camera values from anywhere else will not have any effect since they are all handled locally within that method. Changing the player / render view entity's actual position or yOffset does have an effect, since that can be updated at any time before the camera orientation is determined, as has been mentioned and attempted.

 

@coolboy4531 Indeed he did, and I still need to do a more thorough study of his code and see if it's a simple solution or not. iChun's Morph mod is a real work of coding genius, to say the least :P I'm hoping it's not over my head lol.

 

In other news, I found out why using a dummy render view entity screws up object mouse over / left-click:

List list = this.mc.theWorld.getEntitiesWithinAABBExcludingEntity(this.mc.renderViewEntity, this.mc.renderViewEntity.boundingBox.addCoord(vec31.xCoord * d0, vec31.yCoord * d0, vec31.zCoord * d0).expand((double)f1, (double)f1, (double)f1));

 

Since the renderViewEntity is supposed to be the player, normally the player is excluded from the list of potential targets, but with the dummy entity, the player is included. Now it makes sense why I was getting "Invalid entity" errors - the player can't attack himself!

Link to comment
Share on other sites

@jabelar You're correct that orientCamera is where F5 (i.e. 3rd person mode) and other camera-related effects are handled, but it's useless to me without using ASM as there is no Forge hook called from within that method (other than one for sleeping, for some reason). What this means is that trying to change any of the camera values from anywhere else will not have any effect since they are all handled locally within that method.

 

Yeah, I figured would be hard to intercept this vanilla code if it didn't have the hooks.  Also, yeah it is wierd that sleeping case does have a hook.  Do think there is any hacky way to intercept the sleeping case?  Like what if you set the player as "sleeping" even though they weren't and then took control of the camera?

 

iChun's Morph mod is a real work of coding genius, to say the least :P I'm hoping it's not over my head lol.

 

I do have to say that that guy is a real programmer -- does some sophisticated stuff and apparently is pretty confident doing it.

 

I noticed that in his ModelMorph() class he has a render() method in which he has this one line (line #202) that looks related to maybe what you're trying to do:

 

double offset = (1.0F - scaleY) * Minecraft.getMinecraft().thePlayer.yOffset;

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Alright, I've gotten a solution from Noppes that I've modified to suit my needs. It involves extending EntityRenderer and switching to the alternate one when needed, and after changing some stuff I got it to return a correct mouse over object as well.

 

For those who may be interested in this particular solution, here is the current code. Lots of hard-coded stuff at the moment, but it works fairly well.

 

EntityRendererAlt

 

public class EntityRendererAlt extends EntityRenderer
{
private final Minecraft mc;
private float offsetY = 3.0F; // just for testing, should be based on actual render size

public EntityRendererAlt(Minecraft mc) {
	super(mc); //, mc.getResourceManager());
	this.mc = mc;
}

@Override
public void updateCameraAndRender(float partialTick) {
	if (mc.thePlayer == null || mc.thePlayer.isPlayerSleeping()){
		super.updateCameraAndRender(partialTick);
		return;
	}
	// this is what changes the actual camera height
	// but also seems to affect the player model render position
	mc.thePlayer.yOffset -= offsetY;
	super.updateCameraAndRender(partialTick);
	mc.thePlayer.yOffset = 1.62F;
}

@Override
public void getMouseOver(float partialTick) {
	if (mc.thePlayer == null || mc.thePlayer.isPlayerSleeping()){
		super.getMouseOver(partialTick);
		return;
	}
	// adjust the y position to get a mouseover at eye-level
	// not perfect, as the server posY does not match, meaning
	// that some block clicks do not process correctly
	// (distance check or something like that)
	mc.thePlayer.posY += offsetY;
	mc.thePlayer.prevPosY += offsetY;
	mc.thePlayer.lastTickPosY += offsetY;
	super.getMouseOver(partialTick);
	mc.thePlayer.posY -= offsetY;
	mc.thePlayer.prevPosY -= offsetY;
	mc.thePlayer.lastTickPosY -= offsetY;
}
}

 

 

RenderTickEvent / Handler

 

// class fields:
private final Minecraft mc;
private EntityRenderer renderer, prevRenderer;

// tick start:
if (the render view should be changed) {
if (renderer == null) {
	renderer = new EntityRendererAlt(mc);
}
if (mc.entityRenderer != renderer) {
	// be sure to store the previous renderer
	prevRenderer = mc.entityRenderer;
	mc.entityRenderer = renderer;
}
} else if (prevRenderer != null && mc.entityRenderer != prevRenderer) {
// reset the renderer
mc.entityRenderer = prevRenderer;
}

 

 

RenderPlayerEvent

 


public void onRenderPlayer(RenderPlayerEvent.Pre event) {
if (the render view should be changed) {
	// push the matrix to prevent everything from getting f-ed up
	GL11.glPushMatrix();
	// translate to get the render position to match the physical bounding box position
	GL11.glTranslatef(0.0F, -6.325F, 0.0F);
	// I'm rendering a giant, hard-coded for now
	GL11.glScalef(3.0F, 3.0F, 3.0F);
}
}

@ForgeSubscribe / @SubscribeEvent
public void onRenderPlayer(RenderPlayerEvent.Post event) {
// make sure to pop the matrix
if (the render view should be changed) {
	GL11.glPopMatrix();
}
}

 

  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.