Jump to content

coolAlias

Members
  • Posts

    2805
  • Joined

  • Last visited

Posts posted by coolAlias

  1. If you're trying to spawn vanilla particles, you DO "initiate" the spawn on the server.

    No, you don't. World#spawnParticle calls IWorldAccess#spawnParticle, and the server implementation (in WorldManager) literally does nothing. If you try to spawn them on the server, nothing will happen.

     

    You either send a packet or spawn them directly on the client side, depending on the situation.

     

    There is IWorldAccess#playAuxSFX, and THIS one actually sends a packet to all around when called on the server, so you can play sound, spawn particles, or whatever else on the server as dictated by the specific SFX.

  2. The problem is that water and other fluids don't apply attribute modifiers, they modify the entity's motion directly in World#handleMaterialAcceleration.

     

    The only way I've found to counteract this is to literally reverse it every single tick using a static helper method:

     

    /**
     * Undoes whatever acceleration has been applied by materials such as flowing water (see {@link World#handleMaterialAcceleration})
     */
    public static boolean reverseMaterialAcceleration(World world, AxisAlignedBB aabb, Material material, Entity entity) {
    	int i = MathHelper.floor_double(aabb.minX);
    	int j = MathHelper.floor_double(aabb.maxX + 1.0D);
    	int k = MathHelper.floor_double(aabb.minY);
    	int l = MathHelper.floor_double(aabb.maxY + 1.0D);
    	int i1 = MathHelper.floor_double(aabb.minZ);
    	int j1 = MathHelper.floor_double(aabb.maxZ + 1.0D);
    	if (!WorldUtils.isAreaLoaded(world, i, k, i1, j, l, j1, true)) {
    		return false;
    	} else {
    		boolean flag = false;
    		Vec3 vec3 = new Vec3(0.0D, 0.0D, 0.0D);
    		for (int k1 = i; k1 < j; ++k1) {
    			for (int l1 = k; l1 < l; ++l1) {
    				for (int i2 = i1; i2 < j1; ++i2) {
    					BlockPos pos = new BlockPos(k1, l1, i2);
    					IBlockState state = world.getBlockState(pos);
    					Block block = state.getBlock();
    					if (block.getMaterial() == material) {
    						double liquidLevel = (double)((float)(l1 + 1) - BlockLiquid.getLiquidHeightPercent(((Integer) state.getValue(BlockLiquid.LEVEL)).intValue()));
    						if ((double)l >= liquidLevel) {
    							flag = true;
    							vec3 = block.modifyAcceleration(world, pos, entity, vec3);
    						}
    					}
    				}
    			}
    		}
    		if (vec3.lengthVector() > 0.0D && entity.isPushedByWater()) {
    			vec3 = vec3.normalize();
    			double d1 = 0.014D;
    			entity.motionX -= vec3.xCoord * d1;
    			entity.motionY -= vec3.yCoord * d1;
    			entity.motionZ -= vec3.zCoord * d1;
    			entity.motionX *= 0.85D;
    			entity.motionY *= 0.85D;
    			entity.motionZ *= 0.85D;
    		}
    		return flag;
    	}
    }
    

     

    That will let the player stand in any flowing liquid and be unmoved, but you do have to call it every tick for it to work, and let it run on both client and server side. In my own code for the heavy boots, I have it being called during Item#onArmorTick.

  3. @coolAlias: The logic in your code there is a bit flawed. If msg.requiresMainThread() returns true you go into checkThreadAndEnqueue. That method then checks if you are not on the main thread and if so, schedules a task. But if you are already on the main thread, it does nothing. Yes, this will never happen, but then you might as well not check for isCallingFromMinecraftThread at all.

    Ah yes, you're right. It's one of those 'copied vanilla, got it working, and never really thought about it again' kind of situations :P

     

    EDIT: Aaaaand just put you to 3000. Damn. xD

  4. Ignoring other things in your code for now, your problem is that the loaded entity List is a List of Entity objects, not Strings, so calling contains("someString") on it cannot possibly return true.

     

    You have to iterate through each entry and compare the entity's custom name tag (or command sender name, since you're dealing with players) to the name you expect.

     

    Also, if you are only interested in players, you should use the List referenced by worldObj.playerEntities, and if the player is in game already, you can use the World#getPlayerEntityByName method directly rather than iterating through a list yourself.

  5. Sorry about that :/ it's just this error is so strange and I'm quite confused by it. However, the last block I posted was what was causing it, unsure why though. What I was trying to do there was detect when a player was drinking from a water bottle.

    The last block you posted is extremely unlikely to be what caused the crash log that you first posted - that one was most definitely caused by you extending your main mod class and trying to make a new instance of it.

     

    If you are still getting a crash, post the crash log that points to a line in the code block you posted. Otherwise, and this is nothing against you, I will not believe a word you say. When dealing with errors, either there is a crash log or a very detailed explanation of how to reproduce the error; lacking either of those, the error doesn't exist.

  6. Dude you're jumping all over here - try to stick with one problem at a time. I don't see how that code you just posted could be causing an InstantiationException, unless there is some hidden code enforcing new potion ItemStacks to contain a valid potion - the one you made is basically pointless.

     

    Furthermore, you shouldn't compare ItemStacks with == or even .equals, but rather with ItemStack#areItemStacksEqual or something similar, or if you just want to compare the item, with stack.getItem() == Items.potionitem.

  7. NPE is not caused by conflicting DataWatcher IDs (that would give you a different error), it's caused by something actually being null.

     

    Put a break point on your line, or just break it up and let it crash again:

    this.
      player.
      getDataWatcher().
      updateObject(
      Fallout.
      RAD_WATCHER,
      properties.
      getInteger("CurrentRads"));
    

    That will tell you exactly what is null - my guess is 'properties', unless that's the NBT tag compound from the method parameter.

     

    As for your registry, what error message is appearing now? You said it doesn't happen when you load, but when you 'access certain parts of the mod' - which parts, exactly?

  8. Did you remove 'extends Fallout' from your FalloutEventHandler class? Because that is what is causing the error - when you create a new instance of that class, it's also trying to create a new instance of your mod container class and that is failing to instantiate (i.e. create a new instance).

     

    Usually, your event-handling classes will not extend anything at all, though you can register any class as an event handler.

  9. You actually can have the handler in the same class - the problem isn't race conditions, it is the fact that the message instance that gets sent / received is not the same one that is constructed to handle the message (if they are in the same class), so all of the message contents that you expect to be there when you are handling it are invalid.

     

    You can get around this by creating a separate method such as 'process' that you call from the handler using the received message instance.

     

    In fact, ALL of my messages use that same handler, and do whatever they need to do in the processing method. Makes registration easy ;)

  10. As Ernio said, we need more code in order to help you. Post your full packet handler class, common and client proxy, full message class, and the code where you send the packet.

     

    Also, what version of Minecraft are you on, 1.8? You have to be aware of thread issues, for example sending packets to the client player when they join the world will give you this kind of NPE when receiving the packet, because the client player doesn't yet exist.

  11. Metadata can represent up to 16 states, but when you start combining states you quickly lose that versatility. Since you already have a TileEntity and it already knows if it is burning or not, why not just use that?

    TileEntity te = world.getTileEntity(x, y, z);
    if (te instanceof MyTileEntity) {
      boolean isBurning = ((MyTileEntity) te).isBurning;
    }
    

    Just make sure that the client side also knows about the state - you can do so either by using your custom packets or marking the block for an update if you have overridden getDescriptionPacket.

  12. You are assuming that every mod that adds hammers and files wants them to remain on the crafting grid and allows them to be damaged. While this is probably a safe assumption, you should be aware that it IS an assumption and your mod will not necessarily work 100% of the time.

     

    Anyway, I think your recipe should work so long as the hammer and file items were registered correctly to the ore dictionary, i.e. using the WILDCARD_VALUE.

     

    Otherwise you may have to retrieve all of the hammer and file items from the OreDictionary and iterate over each one to manually adjust the damage value to WILDCARD_VALUE and registering a recipe with that, but that doesn't seem like a very optimal solution.

  13. That seems likely. Just like in 1.7 they passed 'x, x, z' to the Block#getExplosionResistance -.-

     

    I reported it when it was still 1.7.2 with the exact class and line of code needed to fix it; 6 months later they respond 'oh, it's not an issue anymore because we're working on 1.8, which doesn't use coordinates'... well you could have f-ing fixed it 6 months ago and it wouldn't be an issue in 1.7 either!

     

    Anyway, I have no interest in reporting bugs to Mojang. Just another one of those fun things we get to code around - pointless identity checks, here I come!

  14. Most damage in Minecraft is either 1.0 or 2.0 or some other whole number.

     

    This is what I get while punching a zombie burning in the sunlight:

    [21:01:16] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 19.08
    [21:01:16] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 17.58
    [21:01:17] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 16.08
    [21:01:17] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 14.58
    [21:01:17] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 13.08
    [21:01:18] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 11.58
    [21:01:20] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 10.66
    [21:01:20] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 9.16
    [21:01:20] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 8.24
    [21:01:21] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 6.74
    [21:01:22] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 5.8199997
    [21:01:22] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 4.8999996
    [21:01:23] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 3.9799995
    [21:01:24] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 2.4799995
    [21:01:25] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 1.5599995
    [21:01:25] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 0.059999466
    [21:01:25] [server thread/INFO] [sTDOUT]: [zeldaswordskills.handler.ZSSEntityEvents:onLivingUpdate:184]: Health: 0.0
    

    Clearly, those are not whole numbers. ;)

  15. What do you mean, how so? The player's health is a floating point number, so the player can actually receive 0.1 damage and such, not just 1/2 heart (1.0 damage) or 1 full heart (2.0 damage). But Minecraft only DISPLAYS health as if it were either full or half.

     

    Display of information does not always equate to the actual form of that information.

  16. I'm having some trouble understanding you, but you can not use a private field in the Item class as a timer - there is only ONE instance of your item, so if you have more than one stack with that item, each of those will be changing that same timer, and that's no good.

     

    You need to store any type of unique-per-stack information (e.g. enchantments, timers, etc.) in the stack's NBT compound. That is the only way (usually).

  17. 1. You only spawn the particles when the player STOPS using the item, which only happens once, yet you say "I want my item to spawn particles when its being used" - what you ask and what your code says you are trying to do are not the same, so which do you want?

     

    2. You are spawning the particles at player.posY - 5, which is 5 blocks BELOW the player... that's usually in the ground. Why are you spawning them there? Move them up, like at player.posY + player.getEyeHeight() or something like that.

  18. You won't need any events for the sword damage - Minecraft already tracks health down to far finer fractions than is shown on the health bar.

     

    I recommend you start with the Gui Overlay tutorial - though dated, it is still very relevant and will get you 85% of the way there.

  19. The idea is to require the player to open a specific chest in a world and then unlock a achievement- opening a different one would not unlock the achievement.

     

    This isnt important, but I though it could be fun to require the player to open the first crafted chest. :P

    Except that EVERY chest in the game uses the same instance, and you can't store the coordinates because the block isn't placed yet, not to mention players can move it around.

     

    Instead, what you may be able to do is store a flag in the ItemStack NBT, then whenever a player places a block with that NBT tag (you can probably use PlaceEvent), THEN store the current coordinates of the block.

     

    Next, subscribe to PlayerInteractEvent for RIGHT_CLICK_BLOCK and check if the coordinates match and the current block is still a chest - if so, grant the achievement.

×
×
  • Create New...

Important Information

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