Jump to content

jeffryfisher

Members
  • Posts

    1283
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by jeffryfisher

  1. Actually, it looks like he should be using PropertyBoolean FERMENTED, which could be true or false (default false). Is there any need for an enum that has only two values?
  2. Your table probably needs a new column for metadata value. It would not only distinguish between colors of things but also some orientations. Do your structures also need to store tile entity data? Or will you either accept defaults or simply not use block types needing tile entities?
  3. I think that English translation is an issue. Please bring in a native English speaker/writer. Server is always the canonical authority on block values. A client may only tell its server what its player has attempted to do. Does that help? To summarize: Player acts, client tells server of action, server changes blocks/data (and server automatically tells client of block changes). If you are rigidly methodical, then your code should work both SP and MP.
  4. Because of the subtle distinction between them, there's probably a combination of SideOnly and isRemote that would distinguish between SP and MP. However, mods load before a player even chooses how and where to play. The trick would be for the mod to ignore itself if/when an SP world is created or loaded.
  5. OK, I finally, begrudgingly, under duress, bit the bullet and spewed out five blockstates.json files, each with the same horribly ugly, embarrassingly inelegant, exhaustive variants section. Here's one: { "forge_marker" : 1, "defaults": { "textures" : { "texture": "blocks/quartz_ore" } }, "variants": { "power=0": { "model": "pressure_plate_up" }, "power=1": { "model": "pressure_plate_down" }, "power=2": { "model": "pressure_plate_down" }, "power=3": { "model": "pressure_plate_down" }, "power=4": { "model": "pressure_plate_down" }, "power=5": { "model": "pressure_plate_down" }, "power=6": { "model": "pressure_plate_down" }, "power=7": { "model": "pressure_plate_down" }, "power=8": { "model": "pressure_plate_down" }, "power=9": { "model": "pressure_plate_down" }, "power=10": { "model": "pressure_plate_down" }, "power=11": { "model": "pressure_plate_down" }, "power=12": { "model": "pressure_plate_down" }, "power=13": { "model": "pressure_plate_down" }, "power=14": { "model": "pressure_plate_down" }, "power=15": { "model": "pressure_plate_down" } } } Ugly yes, but at least it now works. I love Big Brother! No not really... In my heart, I am still plotting revolution. I will live for the day when a default model can fill the gaps among sparse variants. Viva defaults! I'd even be willing to take a swing at the coding such a feature if anyone can point me to the relevant method(s).
  6. Right: The file log will contain more messages than the console output.
  7. 1) In future work on json files, use a tool like JSONLint to error-check your json files. They're painful enough even after the syntax passes as "valid json". 2) When you say "untextured block", do you really mean untextured inventory-item or block-in-hand?
  8. OK, I can understand that the inequality won't work. But what about having a model in the default section? How do I get that work? The example shows a model in a defaults section, but I haven't found any way to get any states to use any default model. What is wrong with my model in the defaults section? As for magic, some code is enough aware of the possible states to complain about each and every one of them. What would be really useful is if, on its way to the warning message, that code looked at the default model and used it. Alternatively, when a default model is first read in, populate the block's state map with it. When the variants are read, only replace models in the variants' declared cases, leaving other defaults undisturbed. Either way, one would end up with a table having models for all the states.
  9. For starters: Go back to your OP and replace [Help] with [version]. Every post in this forum is supposed to be help. However, little help can be offered unless the version is known. Second: Show as much code as possible. Often, the problem is a little beyond what you thought was relevant (or else you would have seen it yourself).
  10. I just can't seem to wrap my head around the rules for the blockstates json file. I have the Forge Blockstates doc open, and I am copying the example almost verbatim, but every permutation I try just ignores any mention of "model" in the default section, resulting in hundreds of model-not-found errors on launch. And yes, I am using JSON-lint to validate my json scripts. My situation is that I have 7 blocks, each of which has the same 16 states. In one state, they use one model. In all other states, they use a different model. My trouble is my various attempts to define the default model shared by the 15 states. Even more frustrating, I can't even define a default model when I leave out the variants completely. Here are some of my attempts, all of which seemed perfectly valid at the time. Every single one of these is valid JSON according to jsonlint.com so why don't they work??? First, the example in the Forge doc that I am attempting to adapt: { "defaults": { "textures": { "all": "blocks/dirt" }, "model": "cube_all", "uvlock": true } } Testing a default model with no variants: { "forge_marker" : 1, "defaults": { "textures" : { "texture": "blocks/quartz_ore" }, "model" : "pressure_plate_down" } } Result: Mega spew of exceptions because the "variants" block is missing. Don't try this at home Testing a default model with only a "normal" variant: { "forge_marker" : 1, "defaults": { "textures" : { "texture": "blocks/quartz_ore" }, "model" : "pressure_plate_down" }, "variants": { "normal": [{ }] } } Result: Missing model warnings for every possible state 0..15 Using a default model with one odd-ball variant to replace the model for just one state: { "forge_marker" : 1, "defaults": { "textures" : { "texture": "blocks/hay_block_side" }, "model" : "pressure_plate_down" }, "variants": { "power=0": {"model" : "pressure_plate_up"} } } Result: Missing model warnings for states 1..15 Using an inequality expression in the variants frame (between =0 and >0, I cover every possible state, so why doesn't this work???): { "forge_marker" : 1, "defaults": { "textures" : { "texture": "blocks/grass_top" } }, "variants": { "power=0": {"model" : "pressure_plate_up"}, "power>0": {"model" : "pressure_plate_down"} } } Result: Missing model warnings for states 1..15 My conclusions: 1) The documentation for default models is inaccurate or obsolete. How do I set a default model so I need only define the oddball(s) in the variants frame? 2) I don't understand how to state an inequality to cover a range of variants. Can anyone provide an example and/or rules? 3) This would be so f*kking easier if I were allowed to write my own predicate in Java! Just pass me a state and let me return a class instance that can answer calls to getModel, getTexture etc. I understand that MC wants to "bake" the final images ahead of display, but it should be possible for a block to provide a closed set and a method to choose among the set's entries.
  11. Maybe... If my 32 permutations map to only 16 metadata values, would they occupy 16 slots or 32? I'll try to create my blockstate with only SIGNAL, but some of the vanilla code might then break (POWERED runs like a rash through the vanilla p-plate class). Maybe I'll end up extending the p-plate's base class instead. I'll also look at weighted p-plates to see how they manage both redstone strength and on/off rendering. Come to think of it, perhaps that's where I should have started. So far it's working like a charm, even after closing and reopening the world. There are only 16 possible meta values, so what's the worst that could happen? On the client side, the getActualState method was being called with a state that had non-zero SIGNAL but false POWERED. Based on Choonster's explanation, the POWERED=false permutation of that signal strength must have been added to the map after its true permutation, clobbering it. I'd ask why Netty uses the mapping instead of calling the state-to-meta and meta-to-state methods, but I hope I never need to know. I vaguely recall something about Netty being a separate thread, so I'll guess that it has something to do with thread-safe programming. In any case, it is what it is, and now I can see how it tripped up the rendering on the client.
  12. Weak Reference itself is a generic, but the example of code using it looks like an opportunity to code something reusable. I learned something about interfaces. I've coded classes implementing them, but I've never designed one. I am now bummed that I can't put instance methods into one. This leaves me wishing that Java would allow multiple inheritance. Alas, the code to manage a weak reference to a player/owner must either be replicated where used or else embodied in a class. I'm going to set it aside until my mod (a pressure plate that only triggers when stepped on by the player who placed it) is ready. Then I'll have a better idea how and where it might fit. Maybe then I'll try to design something that can be reused.
  13. A year ago, in another thread, D7 posted this not quite compilation-ready suggestion: Basically instead of having a field of type EntityPlayer in your class you have a WeakReference<EntityPlayer> and a UUID like this: private final WeakReference<EntityPlayer> ownerEntity = new WeakReference<EntityPlayer>(); private UUID ownerID; public void setOwner(EntityPlayer owner) { this.ownerID = owner.getUniqueID(); this.ownerEntity.set(owner); } public EntityPlayer getOwnerEntity() { EntityPlayer owner = ownerEntity.get(); if (owner == null || owner.isDead) { owner = lookupOwner(); } return owner; } public UUID getOwnerID() { return ownerID; } private EntityPlayer lookupOwner() { if (ownerID == null) { return null; } List<EntityPlayerMP> allPlayers = MinecraftServer.getServer().getConfigurationManager().playerEntityList; for (EntityPlayerMP player : allPlayers) { if (player.getUniqueID().equals(ownerID)) { ownerEntity.set(player); return player; } } return player; } And then whenever you need the player, use getOwnerEntity. It will return null if the player is not online. And save the UUID to NBT of course. This smacks of a reusable interface (e.g. "IWeakOwnerID"). Does such an interface exist in Forge that my class could implement? Or am I imagining things; should I copy-paste and tailor the example to suit the mod I am about to make? If the answer is "not yet", then I'll make the attempt to first generalize an interface and then implement it. In that case, would anyone be interested in seeing the interface's code if I succeed?
  14. The part I don't understand is what happens when Netty's serial arrives on the client. If Netty has a block ID and meta value, then what is it doing instead of calling the block's getStateFromMeta? @D7: My conversions are symmetrical for all valid block states. Because one property depends on the other, POWERED should never be zero when SIGNAL is non-zero (and vice-versa). Maybe I was supposed to take a different approach when I wanted to expand a vanilla boolean into an integer? Should I have junked the vanilla boolean entirely and then written all 16 states in my blockstates.json file, choosing one model for zero and another model for each of the 15 levels of positive signal?
  15. I don't know IntelliJ, but I do know that the stock gradle.build file has some lines in it about ignoring mcmod.info. You might look at that and then post in the Gradle child forum if you want to change it.
  16. Oooh... I just had another idea: Generation depends on some randomness. If you accidentally start each ore's randomness from the same constant seed, then they'll all try to generate in the same place, so only the first will succeed (the later ores unable to replace it). Watch your randomization in the debugger. Is it progressing as it should from ore to ore?
  17. I make mine the old-fashioned way: I build a jar, move it to another folder, then delete bulky resources, then build the "lightweight" jar, then rename it and move it too. I get 2 versions in 2 minutes without needing to learn advanced gradle/maven mechanics. It works for my simple situation. My project switching (from one mod to another) is similarly primitive.
  18. What's horrible is that getActualState is somehow being called with a state that's NOT the product of my own class's getStateFromMeta. State arrives having only one of its properties set (Choonster mentioned "serialization", which I did not fully understand). My getActual method converts back to meta so it can use my own meta-to-state method to make the complete state that I had expected in the first place. Here's my state def and the conversion methods: public static final PropertyInteger SIGNAL = PropertyInteger.create ("signal", 0, 15); /** * SIGNAL is the metadata value that becomes redstone strength via * abstract methods that insist on using block states instead of raw metadata. * * POWERED is super-class's derived boolean that controls rendering. */ @Override protected BlockState createBlockState() { return new BlockState (this, new IProperty[] { POWERED, SIGNAL }); } /** * Convert the given metadata into a BlockState for this Block. * The super's simple boolean and our own finer signal are each derived independently from the same meta. */ @Override public IBlockState getStateFromMeta(int meta) { return this.getDefaultState () // We can't use super because of its "== 1" .withProperty (POWERED, Boolean.valueOf (meta > 0)) // So we write the more intelligent inequality. .withProperty (SIGNAL, Integer.valueOf (meta)); } /** * Convert the BlockState into the correct metadata value. * We don't use super.POWERED, simply storing SIGNAL from which POWERED can be derived. */ @Override public int getMetaFromState(IBlockState state) { return ((Integer) state.getValue (SIGNAL)).intValue (); } As you can see, the extended class's SIGNAL property is an integer expansion of the super-class's boolean POWERED property. SIGNAL equates to metadata, and POWERED has become a derived property (is the SIGNAL non-zero?). As described by the comments, the SIGNAL becomes the redstone power on the server, while POWERED controls rendering (p-plate up versus depressed) on the client. The one other factor one might care about is that (in client proxy) SIGNAL is ignored for rendering: ...StateMap.Builder ().addPropertiesToIgnore (classSmartPPlate.SIGNAL...
  19. If your item is activated against what appears to be water but really has your bridge on it, then it will probably be activating against your invisible bridge block (not the water beneath). That's possibly the case you want to detect, at which point you want to lookup the TE at that bridge's pos, validate it, and fix its ticks.
  20. Well I'll be hog-tied! Here I thought the meta value would be passed from server to client where getStateFromMeta would be called. I programmed that method to handle this exact situation. Adding an override of getActualState does the trick. My p-plate was already able to produce its redstone power on the server. Now it visually sinks 1/16 of a block when activated. Here's my seemingly paradoxical code for getActualState: @Override public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { return getStateFromMeta (getMetaFromState (state)); // Believe it or not, this is NOT a no-op! }
  21. @SideOnly=Server will prove that a section of code can be left out of the public version (before it's actually removed from the src tree). "Use case" is geek speak for "an example that shows how this feature could be useful". Use cases often drive product design, but they also help students to cement lessons about the features of complex tools (such as Minecraft + Forge).
  22. And what does the debugger show you while you step through all of your methods? I have a suspicion: The static section in your enum might be running before your enum's constructor, calling getMetadata before the member metadata has been initialized. This could inject random garbage. Also, getMetadata should probably return this.metadata, since it is an instance member, not static. Step through the initialization of your BlockOre's enum to see what's set when.
  23. How do xp orbs get drawn toward a player? Even if the movement is calculated by each orb itself, you should see useful examples of vector math and entity search there that you can adapt to your tile entity.
  24. Wow, you might finally have created a use-case for @SideOnly server files and a serverProxy to ref them. If you set them up right, you should be able to build your project twice, first with all pieces in place for yourself, and then with the server-only pieces deleted from your src tree to produce a version for public release. To that end, you might want to organize your files to place all server-only classes into a separate package for quick removal or replacement. Make sure to keep a master elsewhere. I do a similar thing with resources in my alt paintings mod, deleting the rather large graphics files before building a lightweight version of the mod for dedicated servers.
  25. I've seen vanilla code that marks tile entities as dirty so that they get saved. Hunt down an example and either imitate it or make sure that your TE calls a method that does it for you. I've also run into default TE cleanup that deletes existing TE's and instantiates fresh replacements for trivial blockstate changes. Check to see if that's happening to you, and if it is, change the class member controlling that level of cleanup aggression. You might need to step through your TE code in a debugger to see what's really happening.
×
×
  • Create New...

Important Information

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