Jump to content

Need help with modifying some vanilla rendering [1.16.4]


Tavi007

Recommended Posts

Hello!

I'm modifying the damage calculation by subscribing to LivingHurtEvent and scaling the damage value. This works fine, but now I also want to change the rendering a bit. My current LivingHurtEvent looks like this (I removed some unnecessary stuff)

@SubscribeEvent
	public static void elementifyLivingHurtEvent(LivingHurtEvent event)
	{
		// compute new damage value  
		....

		// heals the target, if damage is lower than 0. This can happen with my modification
		if(damageAmount <= 0)
		{
			target.heal(-damageAmount);
			event.setCanceled(true); //does this even do something?
			damageAmount = 0;
		}
		event.setAmount(damageAmount);
	}

 

1. I want to change the red texture (an OverlayTexture?) to a green one, if the targets is healed. But I don't really know, where I should start with this task. I couldn't even find the code, that applies the red texture. So which Event do I need to hook in, so I can change this texture? Is it RenderLivingEvent? I also would like to read the vanilla code. I'm assuming, that the red overlayTexture is applied as long as hurttime>0, and that I might need to work around this with capabilities.

2. I also would like to reduce the screen shake (or at least disable it, when no damage has been dealt). Here I got the same question as 1. As you can see, I'm not really experienced with all the render stuff. It's my first time working with it.

 

3. Not really a question about rendering, but I didn't want to create a new thread for a single problem. I would also like to prevent the hurt-sound from firing, if no damage has been dealt and instead play another sound. Again I have no idea, where I would have to start looking in the vanilla code or which event I should use.

 

So yeah, I'm quite clueless and I hope you can help me out. Here is my repository, if you need more informations: https://github.com/Tavi007/ElementalCombat

Edited by Tavi007
Link to comment
Share on other sites

Thank you poopoodice for leading me in the right direction. I could figure out quite a bit by myself and I'm going to explain what I did, so you guys can tell me, if it is a good solution or not. Generally both the screen shake and the red overlay texture are bound to the hurttime of the entity. I would have loved to change the hurttime directly, but the used forge event hook (LivingHurtEvent) happens before the hurttime gets its value. So i needed work around this problem.

 

Problem 1: disabling the red flash.
My solution was to temporarly set the hurttime of the entity to zero using RenderLivingEvent.Pre and Post. I added a capability for livingEntities, that holds a copy of the hurt time and a flag, that is set to true, when I want to disable the overlay texture. I also needed to send a message, because the server side event decides, when the entity (on the client side) should be rendered differently.
With this capability in place I could do the following events:

 

@SubscribeEvent
	public static void onRenderLivingEventPre(RenderLivingEvent.Pre<LivingEntity, EntityModel<LivingEntity>> event) {
		LivingEntity entityIn = event.getEntity();
		HurtRenderData data = (HurtRenderData) entityIn.getCapability(HurtRenderDataCapability.HURT_RENDER_CAPABILITY, null).orElse(new HurtRenderData());
		if(entityIn.hurtTime > 0) {
			if (data.disableFlag) {
				data.setHurtTime(entityIn.hurtTime);
				entityIn.hurtTime = 0; //desync client and server hurtTime. Is this a problem?

				//to do: add green overlay texture
			}
		}
		else {
			data.disableFlag = false;
		}

	}

	@SubscribeEvent
	public static void onRenderLivingEventPost(RenderLivingEvent.Post<LivingEntity, EntityModel<LivingEntity>> event) {
		LivingEntity entityIn = event.getEntity();
		HurtRenderData data = (HurtRenderData) entityIn.getCapability(HurtRenderDataCapability.HURT_RENDER_CAPABILITY, null).orElse(new HurtRenderData());
		if (data.disableFlag && data.getHurtTime() > 0) {
			entityIn.hurtTime = data.getHurtTime();
			data.setHurtTime(0);
		}
	}

I desyncronize the hurttime on client and server on purpose for a short amount of time, so that when the game renders the entity, with a hurttime of 0. To minimize the time, that client and server are desyncronized I reset the hurttime in the post event. It might be sufficient to set the hurttime to zero once and be done with it. However I do not know, if this can cause problems.

Problem 2: disabling the screenshake
Since there isn't a pre and post event for the EntityViewRenderEvent, I needed to trick the game differently. I had 2 options: Either remove the right matrix from the matrixstack or roll the camera back into the normal position. I assume, that removing the right matrixstack is the efficient solution, but I didn't know how I could do it. Instead I went with rolling the camera back into position.
 

@SubscribeEvent
	public static void onEntityViewRenderEvent(CameraSetup event) {
		Minecraft mc = Minecraft.getInstance();
		if(mc.player != null) {
			if (mc.player.hurtTime > 0) {
				HurtRenderData data = (HurtRenderData) mc.player.getCapability(HurtRenderDataCapability.HURT_RENDER_CAPABILITY, null).orElse(new HurtRenderData());
				if(data.disableFlag) {
					// Use the same calculation as in GameRenderer#hurtCameraEffect.
					float f = (float) (mc.player.hurtTime - event.getRenderPartialTicks());
					f = f / (float) mc.player.maxHurtTime;
					f = MathHelper.sin(f * f * f * f * (float)Math.PI);
					event.setRoll(f * 14.0F); // counter acts the screen shake. Only the hand is moving now.
				}
			}
		}
	}

Again I use the flag from the capability to check, if I even want the roll back. Now I only need to do the same calculation as in GameRenderer#hurtCameraEffect, but instead of rolling to the left (hurtCameraEffect uses -f * 14.0F to roll the camera) I roll to the right. The result is a canceled animation (Tho the arm still twitches, because that is a different render. But I'm okay with this).

I still have some question left:

-How can I add a green overlay texture? I could add a LayerRender, which is just a slightly transparent green color, but I do not understand how I can do this.
-As for disabling the hurt sound, I probably just need the right sound event. I haven't started to look into this yet, but If someone has an idea, which event could be the right one, plesae tell me. The help is appreciated.

Edited by Tavi007
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.