Posted June 26, 20205 yr I'm trying to determine if there's a firework with particular colors/effects/shapes near a player. This is what I have so far: double ax, ay, az, bx, by, bz; double range = 32; ax = player.getPosX() - range; ay = player.getPosY() - range; az = player.getPosZ() - range; bx = player.getPosX() + range; by = player.getPosY() + range; bz = player.getPosZ() + range; AxisAlignedBB boundingBox = new AxisAlignedBB(ax, ay, az, bx, by, bz); List<FireworkRocketEntity> rocketsLotsOfRockets = world.getEntitiesWithinAABB(FireworkRocketEntity.class, boundingBox, null); for(FireworkRocketEntity rocket : rocketsLotsOfRockets) { Set<String> tags = rocket.getTags(); if(player.isSneaking()) { SSoMM.PAUL_BUNYAN.log(Level.DEBUG, "Rocket data: " + tags.size() + " tags"); for(String tag : tags) { SSoMM.PAUL_BUNYAN.log(Level.DEBUG, "\t" + tag); } } } But looking at the logs, all I get is (a spam of) "Rocket data: 0 tags". This is because rocket.getTags() is returning an (empty) array of Tag-system tags, not NBT tags, right? How do I get the NBT data containing the colors and effects and so forth? Edited June 26, 20205 yr by Fractangle Solved!
June 26, 20205 yr Author I'm not sure I understand what you mean by "replicate it" on the server side. For context, I only care about the firework data on the server side - my use case is for the presence of a correctly-colored-patterned-etc firework to trigger the spawning of a mob, hence why I ruled out sending a custom packet from client to server. (Don't want a client spoofing the firework presence!)
June 26, 20205 yr Author Ah okay, that makes sense! Thank you! I've got something that works, but it's a little gross (due to FireworkRocketEntity.FIREWORK_ITEM being private): double ax, ay, az, bx, by, bz; double range = 32; ax = player.getPosX() - range; ay = player.getPosY() - range; az = player.getPosZ() - range; bx = player.getPosX() + range; by = player.getPosY() + range; bz = player.getPosZ() + range; AxisAlignedBB boundingBox = new AxisAlignedBB(ax, ay, az, bx, by, bz); List<FireworkRocketEntity> rocketsLotsOfRockets = world.getEntitiesWithinAABB(FireworkRocketEntity.class, boundingBox, null); for(FireworkRocketEntity rocket : rocketsLotsOfRockets) { List<EntityDataManager.DataEntry<?>> allRocketData = rocket.getDataManager().getAll(); if(allRocketData == null) { SSoMM.PAUL_BUNYAN.log(Level.DEBUG, "Rocket data had no data"); return false; } for(EntityDataManager.DataEntry<?> datum : allRocketData) { Object value = datum.getValue(); if(value instanceof ItemStack) { ItemStack stack = (ItemStack) value; CompoundNBT tag = stack.getTag(); SSoMM.PAUL_BUNYAN.log(Level.DEBUG, tag); } } } Might be a bit niche, but I figured I'd throw it out there in case anybody else can use it.
June 26, 20205 yr Author Good point! (I've never done that before, hence why I overlooked it. Back in a bit with cleaner code once I've done some Learning™!) Edit: As promised, the working reflection-based code: double ax, ay, az, bx, by, bz; double range = 32; ax = player.getPosX() - range; ay = player.getPosY() - range; az = player.getPosZ() - range; bx = player.getPosX() + range; by = player.getPosY() + range; bz = player.getPosZ() + range; AxisAlignedBB boundingBox = new AxisAlignedBB(ax, ay, az, bx, by, bz); List<FireworkRocketEntity> rocketsLotsOfRockets = world.getEntitiesWithinAABB(FireworkRocketEntity.class, boundingBox, null); for(FireworkRocketEntity rocket : rocketsLotsOfRockets) { EntityDataManager rocketDataManager = rocket.getDataManager(); Field fireworkItemField; try { fireworkItemField = FireworkRocketEntity.class.getDeclaredField("FIREWORK_ITEM"); fireworkItemField.setAccessible(true); DataParameter<ItemStack> FIREWORK_ITEM = (DataParameter<ItemStack>)fireworkItemField.get(null); ItemStack stack = rocketDataManager.get(FIREWORK_ITEM); SSoMM.PAUL_BUNYAN.log(Level.DEBUG, stack.getTag()); } catch(NoSuchFieldException e) { throw new WTFException("FireworkRocketEntity class was missing the FIREWORK_ITEM field...?!"); } catch(IllegalAccessException e) { throw new WTFException("I literally just called setAccessible(true)"); } } Edited June 26, 20205 yr by Fractangle Added cleaner code than last time
June 26, 20205 yr Author Whew, thanks for that one! I've got it using the SRG name now, and looking the field up only once. public static final DataParameter<ItemStack> FIREWORK_ITEM = ObfuscationReflectionHelper.getPrivateValue(FireworkRocketEntity.class, null, "field_184566_a"); Edited June 26, 20205 yr by Fractangle Accidental copypasta error semicolon
June 26, 20205 yr Author Like this? public static final String FIREWORK_ITEM_SRG = "field_184566_a"; // [a bunch of unrelated stuff in the class] DataParameter<ItemStack> FIREWORK_ITEM = ObfuscationReflectionHelper.getPrivateValue(FireworkRocketEntity.class, null, FIREWORK_ITEM_SRG); CompoundNBT fireworkData = rocketDataManager.get(FIREWORK_ITEM).getTag();
June 26, 20205 yr Author Sixth time's the charm? 🤣 public static final String FIREWORK_ITEM_SRG = "field_184566_a"; public static final Field FIREWORK_ITEM_FIELD = ObfuscationReflectionHelper.findField(FireworkRocketEntity.class, FIREWORK_ITEM_SRG); // [stuff] DataParameter<ItemStack> FIREWORK_ITEM; FIREWORK_ITEM_FIELD.setAccessible(true); try { FIREWORK_ITEM = (DataParameter<ItemStack>) FIREWORK_ITEM_FIELD.get(rocket); } catch(IllegalAccessException e) { throw new WTFException("I literally just called setAccessible(true)"); }
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.