Jump to content

Recommended Posts

Posted

I'll keep this short, the EntityLivingBase class has a protected variable protected float lastDamage. Is there a reason this is protected? I used this to calculate what the previous health was by adding this value to the current health. Since I wasn't using a class that extended this class, I used reflection to get this value. On that note, maybe even a lastHealth variable would be nice as well.

 

Another thing I noticed in that same class that anything that has to do with how potions are only handled on the server. For example, addPotionEffect calls onNewPotionEffect that will not apply the attribute modifiers on the client side as there is a check to see if the world is not remote. Same thing with updatePotionEffects. There is a check to ignore the changes and not add it to the active portion. But when the world is reloaded, the potions are then added to the client. Because it is not allowed to do anything regarding potions, the inactive potions are left in the entity potion map. This isn't a problem for the local player, but other entities will still return true for an expired potion effect (i.e. poison) until the next reload. This is a problem if you want to add a client-side gui of some kind. that displays the effects. I would suggest removing the check from the class.

Posted
10 minutes ago, ZDoctor said:

I would suggest removing the check from the class.

This will not happen, this is to ensure that potion effects are not changeable client side, for obvious reasons(it can and will be exploited).

 

12 minutes ago, ZDoctor said:

Is there a reason this is protected?

It is protected because Mojang had no use for it to be public, aka it wasn't intended to be used outside of an Entity.

14 minutes ago, ZDoctor said:

Since I wasn't using a class that extended this class, I used reflection to get this value.

What is it that you are getting this for?

15 minutes ago, ZDoctor said:

On that note, maybe even a lastHealth variable would be nice as well. 

This will not happen as this requires too much editing for a feature that will not really be used for much.

 

 

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.

Posted (edited)
10 hours ago, Animefan8888 said:

It is protected because Mojang had no use for it to be public, aka it wasn't intended to be used outside of an Entity.

What is it that you are getting this for?

 

I am getting the last damage to calculate what the last health was by adding the current health and last damage together. Could not a getter for this combination be added?

 

10 hours ago, Animefan8888 said:

This will not happen, this is to ensure that potion effects are not changeable client side, for obvious reasons(it can and will be exploited).

 

Here is what I did to prevent that abuse. I would be more than happy to add the relevant code if people think that it is a simple enough solution.

 

First I created a Potion Watcher (data parameter/watcher):

public static final DataParameter<NBTTagCompound> WATCHER_POTION_EFFECTS = EntityDataManager.createKey(EntittLivingBase.class, DataSerializers.COMPOUND_TAG);

Then overrode the entity init (to implement you would just add to the method):

@Override
protected void entityInit() {
	super.entityInit();
	this.dataManager.register(WATCHER_POTION_EFFECTS, new NBTTagCompound());
}

Then I overrode the notifyDataManagerChange and checked to see if the world was a client and if the parameter changed was the potion effect watcher:

@Override
public void notifyDataManagerChange(DataParameter<?> key) {
	super.notifyDataManagerChange(key);
	if (world.isRemote && WATCHER_POTION_EFFECTS.equals(key)) {
		NBTTagList nbttaglist = this.dataManager.get(WATCHER_POTION_EFFECTS).getTagList("ActiveEffects", 10);
		activePotionsMap.clear();
		for (int i = 0; i < nbttaglist.tagCount(); ++i) {
			NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
			PotionEffect potioneffect = PotionEffect.readCustomPotionEffectFromNBT(nbttagcompound);
			if (potioneffect != null) {
				addPotionEffect(potioneffect);
			}
		}
	}
}

Added this to the resetPotionEffectMetadata:

@Override
protected void resetPotionEffectMetadata() {
	super.resetPotionEffectMetadata();
	// So the data will sync
	this.dataManager.set(WATCHER_POTION_EFFECTS, new NBTTagCompound());
}

 

Added this to the updatePotionMetadata, making sure the server was the only one handling this kind of change for active potion effects:

@Override
protected void updatePotionMetadata() {
	super.updatePotionMetadata();
	// So only server can send updates, would cause recursion otherwise
	// Would potentially allow the client to add effects, and we wouldn't want that
	if (world.isRemote)
		return;

	NBTTagList nbttaglist = new NBTTagList();

	for (PotionEffect potioneffect : getActivePotionMap().values()) {
		nbttaglist.appendTag(potioneffect.writeCustomPotionEffectToNBT(new NBTTagCompound()));
	}

	NBTTagCompound compound = new NBTTagCompound();
	compound.setTag("ActiveEffects", nbttaglist);

	this.dataManager.set(WATCHER_POTION_EFFECTS, compound);
}

 

And that's it. It leaves the rest of the code as it is only added a couple dozen lines and ensures that only the server can add potion effects while making sure the client is aware of the changes. I think because potion effects are stuck on the client after reload until next reload that would be considered a memory leak and this will ensure that doesn't happen, but I could be wrong about the terminology. I've tested this on my own mod and it works as intended. Is there something I am missing?

Edited by ZDoctor
Fixed code
Posted
1 minute ago, ZDoctor said:

Could not a getter for this combination be added?

It could, but why you can do a simple addition yourself.

2 minutes ago, ZDoctor said:

I am getting the last damage to calculate what the last health was by adding the current health and last damage together.

I meant why do you need the health prior to the last damage.

 

5 minutes ago, ZDoctor said:

Is there something I am missing?

I'm not sure I understand why you are going about doing this. What is causing a problem about the vanilla implementation.

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.

Posted (edited)
1 hour ago, Animefan8888 said:

It could, but why you can do a simple addition yourself.

 

It's not that the addition that is making it difficult, but not being able to easily access the variable in the first place.

1 hour ago, Animefan8888 said:

I meant why do you need the health prior to the last damage.

 

People may find a variety of cases where they have the need for the last health of the entity and not know of a way to get it. For my case, I was making a simple Damage Indicator mod that when the health changed it displayed a certain effect if the health went down.

1 hour ago, Animefan8888 said:

I'm not sure I understand why you are going about doing this. What is causing a problem about the vanilla implementation.

2

 

As I said before, what is causing my problem is that the client is unaware of when potion effects are initially active on an entity.

 

Here are some pictures to help demonstrate my point.

Here are two entities after they are initially poisoned:

 

2018-09-13_11_00_36.thumb.png.83c4a631dfccf434f8207265c60045bf.png

Their hearts remain red. Then after leaving and reentering the world:

 

2018-09-13_11_01_29.thumb.png.58d8ff138380d26a7914820e7bca99f1.png

Then after the effect expires (you can tell because of lack of particles):

2018-09-13_11_01_53.thumb.png.4ec99f99444570c95c76ac020bc32baa.png

They are no longer poisoned, but they don't know it yet.

And it stays like that until the next reload:

2018-09-13_11_01_59.thumb.png.81db5e0b28c2037e9b80ffa22ac21110.png

As a technical note, the PotionEffect onUpdate is still called every tick like an active potion would, but does nothing but waste resources.

 

That is the problem I have with the vanilla version that I think can be easily solved with the solution that I added above.

Edited by ZDoctor
Better pictures
Posted

Where are the particles spawned? Wouldn't whatever class that is in know what the potion effect is?

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • the modpack keep crashing idk why,cause it never said anything about any mods causing it. crash log:https://drive.google.com/file/d/1iYKlUgvHUob8DjyRc3gqP_Viv_kSHO6L/view?usp=sharing mod list:https://drive.google.com/file/d/1MvMT-z9Jg2BITQ4uLshJ1uOh7q9EMBfC/view?usp=sharing but the server(anternos) works just fine
    • Hello, I am trying to make 2 recipes for a ruby. The first one is turning a block into a ruby and the other one is 9 nuggets into a ruby. But I keep on getting a error java.lang.IllegalStateException: Duplicate recipe rubymod:ruby   Any help would be great on how to fix it
    • Hello everyone, i'm new with programing Mods, and will need a lot of your help if possible,  Im trying to make a new GUI interface responsible to control the Droprate of game, it will control de loot drop and loot table for mobs and even blocks, but i try to make a simple Gui Screen, and wenever i try to use it, the game crash's with the error message in the subject, here is the code im using to:  IDE: IntelliJ Comunity - latest version Forge: 47.3.0 Minecraft version: 1.20.1 mapping_channel: parchment mapping_version=2023.09.03-1.20.1 Crash report link: https://pastebin.com/6dV8k1Fw   Code im using is:    package createchronical.droprateconfig; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import java.util.HashMap; import java.util.Map; public class ConfigScreen extends Screen { private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation("droprateconfig", "textures/gui/config_background.png"); // Mapa de mobs e itens com seus respectivos drop rates private final Map<String, Integer> dropRates = new HashMap<>(); public ConfigScreen() { super(Component.literal("Configurações de Drop Rate")); // Inicializa com valores de drop rate padrão dropRates.put("Zombie", 10); // Exemplo de mob dropRates.put("Creeper", 5); // Exemplo de mob dropRates.put("Iron Ore", 50); // Exemplo de item dropRates.put("Diamond", 2); // Exemplo de item } @Override protected void init() { // Cria um botão para cada mob/item e adiciona na tela int yOffset = this.height / 2 - 100; // Posicionamento inicial for (Map.Entry<String, Integer> entry : dropRates.entrySet()) { String itemName = entry.getKey(); int dropRate = entry.getValue(); // Cria um botão para cada mob/item this.addRenderableWidget(Button.builder( Component.literal(itemName + ": " + dropRate + "%"), button -> onDropRateButtonPressed(itemName) ).bounds(this.width / 2 - 100, yOffset, 200, 20).build()); yOffset += 25; // Incrementa a posição Y para o próximo botão } // Adiciona o botão de "Salvar Configurações" this.addRenderableWidget(Button.builder(Component.literal("Salvar Configurações"), button -> onSavePressed()) .bounds(this.width / 2 - 100, yOffset, 200, 20) .build()); } private void onDropRateButtonPressed(String itemName) { // Lógica para alterar o drop rate do item/mob selecionado // Aqui, vamos apenas incrementar o valor como exemplo int currentRate = dropRates.get(itemName); dropRates.put(itemName, currentRate + 5); // Aumenta o drop rate em 5% } private void onSavePressed() { // Lógica para salvar as configurações (temporariamente apenas na memória) // Vamos apenas imprimir para verificar dropRates.forEach((item, rate) -> { System.out.println("Item: " + item + " | Novo Drop Rate: " + rate + "%"); }); // Fecha a tela após salvar Screen pGuiScreen = null; assert this.minecraft != null; this.minecraft.setScreen(pGuiScreen); } @Override public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) { this.renderBackground(guiGraphics); guiGraphics.blit(BACKGROUND_TEXTURE, this.width / 2 - 128, this.height / 2 - 128, 0, 0, 256, 256, 256, 256); super.render(guiGraphics, mouseX, mouseY, partialTicks); } }  
    • Also add the latest.log from /logs/
  • Topics

×
×
  • Create New...

Important Information

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