Koward Posted August 3, 2016 Posted August 3, 2016 Hi. I have an old problem I can never find a good fix for. I simply want to change the player's speed by a given float modifier. The field of view is however linked to the SharedMonsterAttribute.MOVEMENT_SPEED. Changing this attributes generates horrible zooms, and editing the FOVUpdateEvent is buggy because I don't want to cancel all FOV changes, I just want my speed variations to not trigger it. At the moment, it looks like this : /** * Edit the speed of an entity. * * @param entity * @param speedModifierUUID * Unique UUID for modification * @param name * Unique name for easier debugging * @param modifier * The speed will be multiplied by this number */ public static void changeSpeed(EntityLivingBase entity, UUID speedModifierUUID, String name, double modifier) { AttributeModifier speedModifier = (new AttributeModifier( speedModifierUUID, name, modifier - 1, 2)); IAttributeInstance attributeinstance = entity .getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); if (attributeinstance.getModifier(speedModifierUUID) != null) { attributeinstance.removeModifier(speedModifier); } attributeinstance.applyModifier(speedModifier); } Note my method takes a simple EntityLivingBase because I could, but all I need is something for EntityPlayer. I tried to apply a negative player.moveEntityWithHeading, it did not work (stuck effect). Any idea ? Quote
Animefan8888 Posted August 3, 2016 Posted August 3, 2016 You could just set it to the players set FOV by using Minecraft.getMinecraft().gameSettings.fovSetting; Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
Koward Posted August 3, 2016 Author Posted August 3, 2016 fovSetting does not vary with sprint & other effects. That would make everything look constant. I want only my changes to not be affected by FoV change. Quote
Animefan8888 Posted August 3, 2016 Posted August 3, 2016 Found this in AbstractClientPlayer public float getFovModifier() { float f = 1.0F; if (this.capabilities.isFlying) { f *= 1.1F; } IAttributeInstance iattributeinstance = this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); f = (float)((double)f * ((iattributeinstance.getAttributeValue() / (double)this.capabilities.getWalkSpeed() + 1.0D) / 2.0D)); if (this.capabilities.getWalkSpeed() == 0.0F || Float.isNaN(f) || Float.isInfinite(f)) { f = 1.0F; } if (this.isHandActive() && this.getActiveItemStack() != null && this.getActiveItemStack().getItem() == Items.BOW) { int i = this.getItemInUseMaxCount(); float f1 = (float)i / 20.0F; if (f1 > 1.0F) { f1 = 1.0F; } else { f1 = f1 * f1; } f *= 1.0F - f1 * 0.15F; } return net.minecraftforge.client.ForgeHooksClient.getOffsetFOV(this, f); } You could reverse engineer this and remove the speed modifier in the FOVUpdateEvent. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
Koward Posted August 3, 2016 Author Posted August 3, 2016 Done. Works well, thank you, I just divided the attribute value by the modifier (that I multiplied before) to get the old attribute value the fov was previously computed with. Quote
Animefan8888 Posted August 3, 2016 Posted August 3, 2016 So did you use SharedMonsterAttributes.MAX_SPEED or did you use your modification. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
Koward Posted August 3, 2016 Author Posted August 3, 2016 Both. At the moment I call changeSpeed(), which does attribute*modifier , the new FOV is calculated by AbstractClientPlayer and then a FOVUpdateEvent is triggered. I disregard the new FOV and instead I recalculate it with the value it had before my changes, attribute/modifier. /** * Edit the speed of an entity. * * @param entity * @param speedModifierUUID * Unique UUID for modification * @param name * Unique name for easier debugging * @param modifier * The speed will be multiplied by this number */ public static void changeSpeed(EntityLivingBase entity, UUID speedModifierUUID, String name, double modifier) { AttributeModifier speedModifier = (new AttributeModifier( speedModifierUUID, name, modifier - 1, 2)); IAttributeInstance attributeinstance = entity .getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); if (attributeinstance.getModifier(speedModifierUUID) != null) { attributeinstance.removeModifier(speedModifier); } attributeinstance.applyModifier(speedModifier); } /** * Cancel the FOV decrease caused by the decreasing speed due to player penalties. * Original FOV value given by the event is never used, we start from scratch 1.0F value. * Edited from AbstractClientPlayer.getFovModifier() * @param event */ @SubscribeEvent public void onFOVUpdate(FOVUpdateEvent event) { EntityPlayer player = event.getEntity(); float modifier = PenaltyManager.getHealthAndExhaustionModifier(player); float f = 1.0F; if (player.capabilities.isFlying) { f *= 1.1F; } IAttributeInstance iattributeinstance = player.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); double oldAttributeValue = iattributeinstance.getAttributeValue() / modifier; f = (float)((double)f * ((oldAttributeValue / (double)player.capabilities.getWalkSpeed() + 1.0D) / 2.0D)); if (player.capabilities.getWalkSpeed() == 0.0F || Float.isNaN(f) || Float.isInfinite(f)) { f = 1.0F; } if (player.isHandActive() && player.getActiveItemStack() != null && player.getActiveItemStack().getItem() == Items.BOW) { int i = player.getItemInUseMaxCount(); float f1 = (float)i / 20.0F; if (f1 > 1.0F) { f1 = 1.0F; } else { f1 = f1 * f1; } f *= 1.0F - f1 * 0.15F; } event.setNewfov(f); } There is still a small zoom in&zoom out effect for a brief time each time there's a change, but I guess it's the best we can achieve without coremod. Quote
Recommended Posts
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.