Jump to content

Recommended Posts

Posted

Hi guys, today I learned about DW, I create a class that implements IExtendedEntityProperties and registered my DW.

After registering those in EntityConstructing event, they worked perfectly! Load and save are perfect!

But the problem is there......

The RenderGameOverlay, it crashes I think because of this cast

PlayerInformation props = PlayerInformation.get((EntityPlayer) this.mc.thePlayer);

There's always a problem with Player cast D:

Here's my PlayerInformation that implements IExtendedEntityProperties:

 

 

package it.exoworld_client.watcher;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.world.World;
import net.minecraftforge.common.IExtendedEntityProperties;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
import cpw.mods.fml.relauncher.Side;

public class PlayerInformation implements IExtendedEntityProperties {
/*
 * Here I create a constant EXT_PROP_NAME for this class of properties. You
 * need a unique name for every instance of IExtendedEntityProperties you
 * make, and doing it at the top of each class as a constant makes it very
 * easy to organize and avoid typos. It's easiest to keep the same constant
 * name in every class, as it will be distinguished by the class name:
 * ExtendedPlayer.EXT_PROP_NAME vs. ExtendedEntity.EXT_PROP_NAME
 * 
 * Note that a single entity can have multiple extended properties, so each
 * property should have a unique name. Try to come up with something more
 * unique than the tutorial example.
 */
public final static String EXT_PROP_NAME = "PlayerInformation";

// I always include the entity to which the properties belong for easy
// access
// It's final because we won't be changing which player it is
private final EntityPlayer player;

// Declare other variables you want to add here

// We're adding mana to the player, so we'll need current and max mana
private int currentXp, xpMax, currentLevel;
public static final int XPMAX_WATCHER = 20;
public static final int CURRENTXP_WATCHER = 21;
public static final int CURRENTLEVEL_WATCHER = 22;

/*
 * The default constructor takes no arguments, but I put in the Entity so I
 * can initialize the above variable 'player'
 * 
 * Also, it's best to initialize any other variables you may have added,
 * just like in any constructor.
 */
public PlayerInformation(EntityPlayer player) {
	this.player = player;
	// Start with max mana. Every player starts with the same amount.
	this.currentXp = 0;
	this.xpMax = 150;
	this.currentLevel = 1;
	this.player.getDataWatcher().addObject(XPMAX_WATCHER, this.xpMax);
	this.player.getDataWatcher().addObject(CURRENTXP_WATCHER, this.currentXp);
	this.player.getDataWatcher().addObject(CURRENTLEVEL_WATCHER, this.currentLevel);
}


/**
 * Used to register these extended properties for the player during
 * EntityConstructing event. This method is for convenience only; it will
 * make your code look nicer
 */
public static final void register(EntityPlayer player) {
	player.registerExtendedProperties(PlayerInformation.EXT_PROP_NAME,
			new PlayerInformation(player));
}

/**
 * Returns ExtendedPlayer properties for player This method is for
 * convenience only; it will make your code look nicer
 */
public static final PlayerInformation get(EntityPlayer player) {
	return (PlayerInformation) player.getExtendedProperties(EXT_PROP_NAME);
}

// Save any custom data that needs saving here
@Override
public void saveNBTData(NBTTagCompound compound) {
	// We need to create a new tag compound that will save everything for
	// our Extended Properties
	NBTTagCompound properties = new NBTTagCompound();

	// We only have 2 variables currently; save them both to the new tag
	properties.setInteger("CurrentXP", this.player.getDataWatcher().getWatchableObjectInt(CURRENTXP_WATCHER));
	properties.setInteger("XPMax", this.player.getDataWatcher().getWatchableObjectInt(XPMAX_WATCHER));
	properties.setInteger("CurrentLevel", this.player.getDataWatcher().getWatchableObjectInt(CURRENTLEVEL_WATCHER));

	/*
	 * Now add our custom tag to the player's tag with a unique name (our
	 * property's name). This will allow you to save multiple types of
	 * properties and distinguish between them. If you only have one type,
	 * it isn't as important, but it will still avoid conflicts between your
	 * tag names and vanilla tag names. For instance, if you add some
	 * "Items" tag, that will conflict with vanilla. Not good. So just use a
	 * unique tag name.
	 */
	compound.setTag(EXT_PROP_NAME, properties);
}

// Load whatever data you saved
@Override
public void loadNBTData(NBTTagCompound compound) {
	// Here we fetch the unique tag compound we set for this class of
	// Extended Properties
	NBTTagCompound properties = (NBTTagCompound) compound
			.getTag(EXT_PROP_NAME);
	// Get our data from the custom tag compound
	this.player.getDataWatcher().updateObject(CURRENTXP_WATCHER, properties.getInteger("CurrentXP"));
	this.player.getDataWatcher().updateObject(XPMAX_WATCHER, properties.getInteger("XPMax"));
	this.player.getDataWatcher().updateObject(CURRENTLEVEL_WATCHER, properties.getInteger("CurrentLevel"));
	// Just so you know it's working, add this line:
	System.out.println("[EXOWORLD PROPS] XP system from NBT: " + this.currentXp
			+ "/" + this.xpMax + " " + "Level:" + this.currentLevel);
}

/*
 * I personally have yet to find a use for this method. If you know of any,
 * please let me know and I'll add it in!
 */
@Override
public void init(Entity entity, World world) {
}

/*
 * That's it for the IExtendedEntityProperties methods, but we need to add a
 * few of our own in order to interact with our new variables. For now,
 * let's make one method to consume mana and one to replenish it.
 */

/**
 * Returns true if the amount of mana was consumed or false if the player's
 * current mana was insufficient
 */
public void addPlayerXP(int amount) {
	int currentXp = this.player.getDataWatcher().getWatchableObjectInt(CURRENTXP_WATCHER);
	int result = currentXp += amount;
	this.player.getDataWatcher().updateObject(CURRENTXP_WATCHER, result);
}

public void levelUp() {
	int currentXp = this.player.getDataWatcher().getWatchableObjectInt(CURRENTXP_WATCHER);
	int xpMax = this.player.getDataWatcher().getWatchableObjectInt(XPMAX_WATCHER);
	int currentLevel = this.player.getDataWatcher().getWatchableObjectInt(CURRENTLEVEL_WATCHER);
	if(currentXp >= xpMax) {
		int result = xpMax += 150;
		int updateLevel = currentLevel ++;
		int resetCurrentXp = currentXp = 0;
		this.player.getDataWatcher().updateObject(XPMAX_WATCHER, result);
		this.player.getDataWatcher().updateObject(CURRENTLEVEL_WATCHER, updateLevel);
		this.player.getDataWatcher().updateObject(CURRENTXP_WATCHER, resetCurrentXp);
	}
}

public final int getXPMax() {
	return this.player.getDataWatcher().getWatchableObjectInt(XPMAX_WATCHER);
}

public final int getCurrentXP() {
	return this.player.getDataWatcher().getWatchableObjectInt(CURRENTXP_WATCHER);
}

public final int getCurrentLevel() {
	return this.player.getDataWatcher().getWatchableObjectInt(CURRENTLEVEL_WATCHER);
}
}

 

 

 

Where it loads in EntityConstructing event:

 

 

package it.exoworld_client.event;

import it.exoworld_client.watcher.PlayerInformation;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.entity.EntityEvent.EntityConstructing;

public class ExoEntityPlayerEvent {

@ForgeSubscribe
public void onEntityConstructing(EntityConstructing event) {
	if (event.entity instanceof EntityPlayer
			&& PlayerInformation.get((EntityPlayer) event.entity) == null)
		PlayerInformation.register((EntityPlayer) event.entity);
	if (event.entity instanceof EntityPlayer
			&& event.entity
					.getExtendedProperties(PlayerInformation.EXT_PROP_NAME) == null)
		event.entity.registerExtendedProperties(
				PlayerInformation.EXT_PROP_NAME, new PlayerInformation(
						(EntityPlayer) event.entity));
}
}

 

 

 

Where it crashes in RenderGameOverlay event:

 

 

package it.exoworld_client.gui;

import it.exoworld_client.event.ExoEntityPlayerEvent;
import it.exoworld_client.watcher.PlayerInformation;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.event.EventPriority;
import net.minecraftforge.event.ForgeSubscribe;

import org.lwjgl.opengl.GL11;

public class ExoGuiStats extends Gui {
private Minecraft mc;
private EntityPlayer player;

public ExoGuiStats(Minecraft mc) {
	super();
	this.mc = mc;
}

@ForgeSubscribe(priority = EventPriority.NORMAL)
public void onRenderExperienceBar(RenderGameOverlayEvent event) {
	if (event.isCancelable() || event.type != ElementType.EXPERIENCE) {
		return;
	}
	if (this.mc.thePlayer.capabilities.isCreativeMode == false) {
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.mc.renderEngine
				.getTexture("/mods/exoworld/textures/gui/exoGuiIngame.png"));
		GL11.glEnable(GL11.GL_BLEND);
		GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
		GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
		GL11.glDisable(GL11.GL_ALPHA_TEST);
		EntityPlayer player = this.mc.thePlayer;
		this.drawTexturedModalRect(0, 0, 0, 0, 147, 51);
		this.renderHealthBar();
		this.renderExpBar();
		this.drawString(mc.fontRenderer, mc.thePlayer.username, 53, 5, 0xFFFFFF);
		// params: XPos, YPos, XStart, YStart, XFinish, YFinish
		// this.drawTexturedModalRect(0, 209, 0, 0, 182, 10);
	}
}

public void renderHealthBar() {
	int maxPlayerHealth = this.mc.thePlayer.getMaxHealth();
	int playerHealth = this.mc.thePlayer.getHealth();
	double multiplier = 4.65;
	if(maxPlayerHealth > 0) {
		short short1 = 93;
		int currentHealth = (int) (playerHealth * multiplier);
		this.drawTexturedModalRect(52, 16, 0, 52, currentHealth, 10);
	}
}

public void renderExpBar() {
	PlayerInformation props = PlayerInformation.get(player);
	int maxPlayerExp = props.getCurrentXP(); //Crash line
	int playerExp = props.getCurrentXP(); //Crash line
	if(maxPlayerExp > 0) {
		short short1 = 93;
		int currentExp = playerExp / maxPlayerExp;
		this.drawTexturedModalRect(52, 16, 0, 62, currentExp, 10);
	}
}
}

 

 

 

That's the crash log, it's a NullPointer:

 

 

2013-11-28 22:47:19 [iNFO] [sTDERR] java.lang.NullPointerException
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at it.exoworld_client.watcher.PlayerInformation.get(PlayerInformation.java:80)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at it.exoworld_client.gui.ExoGuiStats.renderExpBar(ExoGuiStats.java:58)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at it.exoworld_client.gui.ExoGuiStats.onRenderExperienceBar(ExoGuiStats.java:39)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at net.minecraftforge.event.ASMEventHandler_4_ExoGuiStats_onRenderExperienceBar_RenderGameOverlayEvent.invoke(.dynamic)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at net.minecraftforge.event.ASMEventHandler.invoke(ASMEventHandler.java:39)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at net.minecraftforge.event.EventBus.post(EventBus.java:108)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at net.minecraftforge.client.GuiIngameForge.post(GuiIngameForge.java:746)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at net.minecraftforge.client.GuiIngameForge.renderExperience(GuiIngameForge.java:486)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at net.minecraftforge.client.GuiIngameForge.renderGameOverlay(GuiIngameForge.java:130)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:999)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:871)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at net.minecraft.client.Minecraft.run(Minecraft.java:760)
2013-11-28 22:47:19 [iNFO] [sTDERR] 	at java.lang.Thread.run(Unknown Source)

 

 

 

Please help me, I need to release my mod next two months!

Posted

Is your extended properties registered ?

Does your onEntityConstructing get called ?

1)yes

2)yes

 

Edit: SOLVED! I didn't register the event in clientside too, only serverside! Thanks anyway!

Guest
This topic is now closed to further replies.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I have used mixins once before, and it was with @At RETURN, so it worked fine. Now im trying to use it as INVOKE, and the compilation is successful, but the client crashes almost on startup (just a couple seconds after running runClient)   Im trying to inject the method finishConversion inside the ZombieVillager class. This is my Mixin class important stuff:   import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.monster.ZombieVillager; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ZombieVillager.class) public class ZombieVillagerCures { @Inject(method = "finishConversion", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/entity/LivingEntity;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z")) private void addZombieVillagerCuredAmmount(ServerLevel level, CallbackInfo info) { System.out.println("The Mixin Worked!!! " + level); } // Lnet/minecraft/world/entity/LivingEntity;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z } I'm sure the issue lies in the @At cuz other @At values work fine. Its probably the fully qualified name thing. idk how to get it in VS code
    • I'm wayy less skilled than you i bet, but maybe u could try to just convert one into the other?
    • wildbackport is not working
    • Through Betafort Recovery, Bitcoin scam victims can retrieve their money. I recommend Betafort Recovery to anyone who has fallen victim to a scam and has been looking for methods and techniques to recover their lost cryptocurrency or wallets. Betafort Recovery is a reliable cryptocurrency recovery firm that assists victims in recovering their stolen cryptocurrency and offers secure solutions to protect your wallets from online scammers. I must admit that I was deeply melancholy and had given up on life until these experts could restore my $23,400 to my wallet. If you've lost your cryptocurrency and you are helpless about it, contact Betafort Recovery to get your money back. One key aspect that makes Betafort Recovery stand out is its focus on providing secure solutions to protect wallets from online scammers. It's not just about recovering lost funds; it's also about preventing future incidents and ensuring that clients' digital assets are safeguarded against potential threats. This proactive approach demonstrates their commitment to the long-term financial security of their clients. Furthermore, for individuals who have lost their cryptocurrency and are feeling helpless, reaching out to Betafort Recovery could be a turning point in their situation. The reassurance that they are legitimate for seeking help and recovering lost funds can provide much-needed relief and a sense of empowerment. Betafort Recovery as a reliable cryptocurrency recovery firm is certainly well-founded. Their ability to assist scam victims in recovering stolen cryptocurrency, their focus on providing secure solutions, and their commitment to supporting clients through challenging situations make them a valuable resource for individuals navigating the complex world of digital currencies. If you or someone you know has fallen victim to a cryptocurrency scam, contacting Betafort Recovery could be the first step towards reclaiming lost funds and regaining peace of mind.  
    • Idk how i didn't notice that, but I deleted it and fixed some other issues and now I get this https://mclo.gs/YsWacqq
  • Topics

×
×
  • Create New...

Important Information

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