Jump to content

Forge Event for EXP Orb Pickup


charsmud

Recommended Posts

Hello!  I am trying to do something when the player picks up an XP orb.  I am using the following Event code for detecting XP orbs:

 

@ForgeSubscribe
public void onPlayerEntityInteract(EntityItemPickupEvent event)
{
	System.out.println("");
	if(event.entity instanceof EntityXPOrb)
	{
		System.out.println(" :D");
		int xpAmt = ((EntityXPOrb)event.entity).getXpValue();
		int amtOfEnhance = 0;
		if(event.entityPlayer.inventory.hasItem(TimeTraveler.expEnhance.itemID))
		{
			ItemStack[] items = event.entityPlayer.inventory.mainInventory;
			for(int i = 0; i < 35; i++)
			{
				if(items[i].getItem() instanceof ItemExpEnhance)
				{
					amtOfEnhance++;
				}
			}
		}
		System.out.println(amtOfEnhance);
		int newXpAmt = (amtOfEnhance * 2) * (xpAmt);
		event.entityPlayer.experience = event.entityPlayer.experience + newXpAmt;
	}
}
}

 

however, ":D :D" never prints and amtOfEnhance does not print as well.  Any idea?

Link to comment
Share on other sites

Do this:

		System.out.println(event.entity);
	if(event.entity instanceof EntityXPOrb)

 

That'll tell you what's going on.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

One way would be to intercept EntityXPOrb when they join the world and spawn a new xp orb in its place:

@ForgeSubscribe
public void onEntityJoin(EntityJoinWorldEvent event) {
if (event.entity instanceof EntityXPOrb) {
// first spawn a new xp orb entity with amount of xp you want
event.entity.setDead(); // kill the old xp orb
}
}

You don't even have to make a new class, just use the vanilla xp orb's constructor:

public EntityXPOrb(World world, double x, double y, double z, int xpAmount);

You can see from that how easy this should be to adjust the amount. It doesn't looked like it is capped at any max value other than the limits of Short values.

 

Link to comment
Share on other sites

One way would be to intercept EntityXPOrb when they join the world and spawn a new xp orb in its place:

@ForgeSubscribe
public void onEntityJoin(EntityJoinWorldEvent event) {
if (event.entity instanceof EntityXPOrb) {
// first spawn a new xp orb entity with amount of xp you want
event.entity.setDead(); // kill the old xp orb
}
}

You don't even have to make a new class, just use the vanilla xp orb's constructor:

public EntityXPOrb(World world, double x, double y, double z, int xpAmount);

You can see from that how easy this should be to adjust the amount. It doesn't looked like it is capped at any max value other than the limits of Short values.

 

The new one would then throw its OWN EntityJoinWorldEvent, which would be bad.  You'd be better off modifying the properties of the one that joined the world.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Excellent point. I was just showing that it's possible. Anyway, as Draco said you should just use reflection API or some other method of changing the private xpValue field. If you don't want to do it that way, then your best bet would be what I showed, but use a custom entity that extends xp orb instead so you avoid the nasty recursion when the entity joins the world (unless you are familiar with ASM, then you can do as diesieben pointed out and make a core mod).

Link to comment
Share on other sites

You can modify the values in xp orb without reflection. Just use the NBT methods:

 

NBTTagCompound nbt = new NBTTagCompound();
xpOrb.writeEntityToNBT(nbt);
nbt.setShort("Value", nbt.getShort("Value")*2);//beware out of Short range values 
xpOrb.readEntityFromNBT(nbt);

 

I'd recommend using the LivingUpdateEvent and perform collision detection for xp orb around the player. This way you can be player specific ;)

Link to comment
Share on other sites

    public void onCollideWithPlayer(EntityPlayer par1EntityPlayer)
    {
        if (!this.worldObj.isRemote)
        {
            if (this.field_70532_c == 0 && par1EntityPlayer.xpCooldown == 0)
            {
                par1EntityPlayer.xpCooldown = 2;
                this.playSound("random.orb", 0.1F, 0.5F * ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.8F));
                par1EntityPlayer.onItemPickup(this, 1);
                par1EntityPlayer.addExperience(this.xpValue);
                this.setDead();
            }
        }
    }

 

There's no hook there.  I don't think you'll be able to do what you want to be able to do.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

With a player instance taken from LivingUpdateEvent:

            AxisAlignedBB aabb= null;
            if (player.ridingEntity != null && !player.ridingEntity.isDead)
            {
                aabb= player.boundingBox.func_111270_a(player.ridingEntity.boundingBox).expand(1.0D, 0.0D, 1.0D);
            }
            else
            {
                aabb= player.boundingBox.expand(1.0D, 0.5D, 1.0D);
            }

            List list = player.worldObj.getEntitiesWithinAABB(EntityXPOrb.class, aabb);

            if (list != null)
            {
                for (int i = 0; i < list.size(); ++i)
                {
                    EntityXPOrb xpOrb = (EntityXPOrb)list.get(i);

                    if (!xpOrb.isDead)
                    {
                        //We are sure the xp orb is colliding here
                    }
                }
            }

Link to comment
Share on other sites

Would that actually work in LivingUpdateEvent? There is a lot of stuff that is updated between when your code runs and when the xpOrbs do their thing in onCollideWithPlayer. Depending on what is updated there might be a difference in what orbs you collide with and what orbs are actually picked up.

 

 

If you are targeting 1.7.2, I'd add a hook to onCollideWithPlayer that fires an XpOrbPickedUpEvent. If you get it pulled now, it'll be in when the recommended build is set. That way you'll be all set going forward, not to mention any other mods that may want to mess with xpOrb pickups.

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Add necronomicon https://www.curseforge.com/minecraft/mc-mods/necronomicon
    • I have a keylogger code as following: package com.key_logger_mod; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.minecraft.client.Minecraft; import org.lwjgl.glfw.GLFW; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.HashMap; import java.util.Map; @Mod.EventBusSubscriber(modid = "key_logger_mod", bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT) public class KeyboardLogger {     private static final Logger LOGGER = LogManager.getLogger();     private static final Gson gson = new GsonBuilder().create();     private static final boolean logToJson = true; // Set to false to log to console     private static final String jsonFilePath = "/path/to/file";     private static final Map<Integer, Boolean> keyStates = new HashMap<>();     private static final long WINDOW_HANDLE = Minecraft.getInstance().getWindow().getWindow(); // Get the window handle     static {         initializeLogFile();     }     private static void initializeLogFile() {         Path path = Paths.get(jsonFilePath);         try {             Files.write(path, "[".getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);         } catch (IOException e) {             LOGGER.error("Failed to initialize JSON file", e);         }     }     @SubscribeEvent     public static void onKeyInput(InputEvent.Key event) {         if (Minecraft.getInstance().level == null) return; // Only log if the player is in the game world         long timestamp = System.currentTimeMillis();         int key = event.getKey();         int action = event.getAction();         int mods = event.getModifiers();         synchronized (keyStates) {             if (action == GLFW.GLFW_PRESS) {                 if (!keyStates.getOrDefault(key, false)) {                     keyStates.put(key, true);                     logKeyAction(timestamp, key, "PRESS");                 }             } else if (action == GLFW.GLFW_RELEASE) {                 if (keyStates.getOrDefault(key, false)) {                     keyStates.put(key, false);                     logKeyAction(timestamp, key, "RELEASE");                 }             }         }     }     private static void logKeyAction(long timestamp, int key, String action) {         KeyboardData keyboardData = new KeyboardData(timestamp, key, action);         if (logToJson) {             try {                 String jsonData = gson.toJson(keyboardData) + ",";                 Files.writeString(Paths.get(jsonFilePath), jsonData + System.lineSeparator(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);             } catch (IOException e) {                 LOGGER.error("Failed to write keyboard event to JSON file", e);             }         } else {             LOGGER.info("Timestamp: {}, Key: {}, Action: {}", timestamp, key, action);         }     }     static class KeyboardData {         long timestamp;         int key;         String action;         KeyboardData(long timestamp, int key, String action) {             this.timestamp = timestamp;             this.key = key;             this.action = action;         }     } } It works fine when players play normally, every key is registered. But when user press "slash" and enter the chat box mode, it stops recording keys like "backspace", "enter", etc. But still registering characters and number keys. Why is this happening?  
    • It happened on a snowy mountain in the overworld. It wasn't actually a crash, the game didn't close itself or something, it was more like when you are lagging online, and mobs are standing still, you cannot break blocks, things like that. Hope you'll find a solution Madz.
    • I am trying to add the mod "Create Questing" to the modpack SkyMachina but it just crashes. My log : https://pastebin.com/rq2jpph4   Please help, create is hard 
  • Topics

×
×
  • Create New...

Important Information

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