Jump to content

jeffryfisher

Members
  • Posts

    1283
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by jeffryfisher

  1. If I were developing inside minecraft, I might imitate minecart programming by having World class start my continuous sound for me. Alas, I don't have that option, so I must work around it and create something else that has World's server and client versions. Right now that's my TE class, but it may end up being a new proxy for my TE to call. I am up against more than methods. I am facing a client-only class (PositionedSound), and that prevents me from even having its import statement on the server side. That would be fine for execution, but it won't save my program when the import statement on the server throws a class-not-found exception. I thought about that, but then this mod would no longer be able to re-use the proxy-setup code I developed for my earlier mods. Rather than monkeying with that setup, I opted to add what is in effect a 2nd proxy pair. Don't worry, I only use them where they make sense (or where Minecraft uses them). I mentioned static references as part of the reason for my idiosyncratic class naming -- I like to remind myself that a class is a class, not an instance. And if static references are uncommon, then I need the reminder even more. When I find that trouble, I'll create a special proxy just for my TE to call. The TE class will again be unified, and a new pair of classes will handle server/client divergence. I'll also add a note here to tell future adventurers how much trouble I found. Thanks for the advance warning.
  2. Thanks, the debugger must have shown me the server doing its registration and then the client blowing up. I'm still wrapping my head around running client-server in the debugger, not always aware of which is which when I hit a break. I'll make sure that the client-side TE class is what gets registered in the client. Yes, my naming convention is archaic. I like to keep classes very distinct from instances and variables so I instantly know what I am seeing wherever any are used to refer to static methods and members. My tile entity is following the pattern of proxies, with the client-only TE making a continuous custom sound using classes that can't even be imported server-side. I couldn't exactly follow the minecart's sound example because it depends on World/WorldClient which doesn't even know I exist. I needed to create my own class that has a client version to do that. It starts the sound at itself during setPosition. I programmed the sound to terminate itself (donePlaying=true) when its TE becomes invalid during removal.
  3. Even after I register my tile entity, classToNameMap comes up dry. What obvious thing am I missing? Console Output: [17:30:28] [server thread/INFO]: Saving and pausing game... [17:30:28] [server thread/INFO]: Saving chunks for level 'Blower Test'/Overworld [17:30:29] [server thread/ERROR] [FML]: A TileEntity type jrfinventions.classBlowerTEClient has throw an exception trying to write state. It will not persist. Report this to the mod author java.lang.RuntimeException: class jrfinventions.classBlowerTEClient is missing a mapping! This is a bug! at net.minecraft.tileentity.TileEntity.writeToNBT(TileEntity.java:94) ~[TileEntity.class:?] at jrfinventions.classBlowerTE.writeToNBT(classBlowerTE.java:52) ~[classBlowerTE.class:?] at net.minecraft.world.chunk.storage.AnvilChunkLoader.writeChunkToNBT(AnvilChunkLoader.java:410) [AnvilChunkLoader.class:?] at net.minecraft.world.chunk.storage.AnvilChunkLoader.saveChunk(AnvilChunkLoader.java:193) [AnvilChunkLoader.class:?] at net.minecraft.world.gen.ChunkProviderServer.saveChunkData(ChunkProviderServer.java:266) [ChunkProviderServer.class:?] at net.minecraft.world.gen.ChunkProviderServer.saveChunks(ChunkProviderServer.java:332) [ChunkProviderServer.class:?] at net.minecraft.world.WorldServer.saveAllChunks(WorldServer.java:976) [WorldServer.class:?] at net.minecraft.server.MinecraftServer.saveAllWorlds(MinecraftServer.java:419) [MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:147) [integratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:540) [MinecraftServer.class:?] at java.lang.Thread.run(Unknown Source) [?:1.7.0_55] [17:30:29] [server thread/INFO]: Saving chunks for level 'Blower Test'/Nether [17:30:29] [server thread/INFO]: Saving chunks for level 'Blower Test'/The End [17:30:31] [server thread/INFO]: Stopping server [17:30:31] [server thread/INFO]: Saving players [17:30:31] [server thread/INFO]: Saving worlds [17:30:31] [server thread/INFO]: Saving chunks for level 'Blower Test'/Overworld [17:30:31] [server thread/INFO]: Saving chunks for level 'Blower Test'/Nether [17:30:31] [server thread/INFO]: Saving chunks for level 'Blower Test'/The End The throw at line 94: public void writeToNBT(NBTTagCompound compound) { String s = (String)classToNameMap.get(this.getClass()); if (s == null) { throw new RuntimeException(this.getClass() + " is missing a mapping! This is a bug!"); The mapping: public class classBlockBlower extends BlockDirectional implements ITileEntityProvider { private boolean firstTime = true; // TODO: Remove debug var // public static final PropertyDirection FACING = PropertyDirection.create ("facing"); public static final PropertyInteger FANSPEED = PropertyInteger.create ("fanspeed", 0, 3); public static final int tickPeriod = 10; // Update block once every x ticks (at 20 ticks per second) protected final String mod; protected boolean clean; // Debug: Send one tick warning public classBlockBlower(String n) { super (Material.iron); this.setDefaultState (this.blockState.getBaseState ().withProperty (FACING, EnumFacing.NORTH)); this.setUnlocalizedName (n); // Used in regBlock this.setStepSound (soundTypeMetal); this.setHardness (0.5F); this.setCreativeTab (CreativeTabs.tabRedstone); // May be superseded by regBlock classInventionsMod.regBlock (this); // Not ticking until speed fixed when placed. mod = classInventionsMod.MODID; GameRegistry.registerTileEntity (classBlowerTE.class, "classBlowerTE"); } ... } I've stepped through in the debugger, and the registerTileEntity call (which adds to the map) is made before the classToNameMap.get. I am bamboozeled. What am I missing?
  4. I've been working in sound recently, so I think I get what you're asking. Simply playing a sound server-side will send a message to every WorldAccess (player). If I understand you, you want to alert only a specific player. To do this, you need to trace the call into World.playSound, see how it iterates the world accesses, and then do that work yourself so you can choose the WorldAccess that you care about. OTOH, if you are also writing your players' client-side code, then you can talk straight to each individual (and decide at the client what sounds are played). There are some additional sound methods available through WorldClient that don't exist on the server. Search for "sound" in vanilla class WorldClient. It's difficult to wrap one's brain around this server-client system and its one-to-many relationship (I'm still struggling), but if you take time to tease it apart, you'll find the right control lever(s) for what you want to do. PS: All sounds are played "just on the client", even if the call is from the server (it causes messages to be sent to all clients currently accessing). If what you were really asking was how to make a sound exist in the world so that all players would hear it, then have your server (!isRemote) call w.playSoundEffect.
  5. It depends how distinctive these ores and their behaviors are. If you have a very systematic way of programming them, then look into metadata and setting up sets of 16 ingots for 16 ores. Above all of the sets would be an abstract class with all of the common code. Then again, metadata might not work for what you might want to do, but an abstract class can still hold all your common code so that the many ore classes are tiny things. And if your ores sort into a few broad categories with systematic features, you could even have an intermediate layer with ore-category abstract classes.
  6. You are instantiating your items and blocks in your main init method. I do mine in my preInit method so they'll exist prior to the call to proxy.init() that uses some of them.
  7. Sorry, I saw the word "renderer" in the main class and commented. My own style is to call proxy.init (or preInit) and not have any mention of client-only features until inside my client proxy. In my own code, calls like ItemRenderer.registerItemRender() and proxy.registerRenderInfo() would be red flags. Incidentally, your ItemRenderer class has "import net.minecraft.client.Minecraft". Isn't that a client-only class (hence "client" in its path)?
  8. All things for rendering (e.g.meshing and renderers) are client-only. The server doesn't do display.
  9. In general, when you intuit that "there ought to be a vanilla function for that", you should look in the vanilla source code. Look in EntityPlayer and classes both above and below it in its lineage. By the time you post here, you should be telling us where you looked, what you found/tried, and why you still need help. For my own curiosity, I just did that myself. I see a method in class Entity that may help you. However, I am using mc-1.8, so what you find (and how it's used) might be a little different than what I see. I'll give you the keywords "horizontal", "yaw" and "facing" to start your search.
  10. You have a bunch of undeclared variables in your program. Vars like loopingsoundposition need to be declared somewhere, but I don't see them.
  11. Have you used log output or the debugger to verify that methods like getNameForObject(item).toString() give output that matches labels used in json files and meshing? And where are your json files? Have you validated them in jsonlint? Those json files are very fragile and prone to frustrating, hard to see errors. Capitalization, pluralization and even underscores can ruin your day. Finally, I don't see an item model mesher in an init method in your client proxy IIRC, You can't texture items without item models, and you can't mesh item models before TheMinecraft instance is constructed during the init phase (Your static call to getMinecraft() is probably premature and should return null).
  12. Set a breakpoint in there and walk through in the debugger. If it never even hits your breakpoint, then your problem is elsewhere.
  13. If you're willing to entertain a paradigm shift: Create an enchantment that consumes levels to charge your item, then destroys the item to give levels to the player using the item (like bottle o'enchanting that can be bought from villagers). Allow many levels of the enchantment. However, what would be even more useful (and somewhat OP) is if you extended magic books to say, 16 colors of books, each of which would be offered a distinct enchantment when placed in an enchantment table (not sure how to spin that dial). This would not only store magic in the form of spells, it would give a player more rolls of the dice to gain a coveted enchantment.
  14. Note the FML. That means it is like the preInit, init and postInit in your mod's main class and handled by yet another similar method. It is not subscribed on a bus like in-game "events" (an unfortunate coincidence of naming).
  15. I have a suspicion... that I misunderstood how flexible bounding boxes could be. Based on how I am seeing them used by EntityItem, BlockHopper and their own expand method, it appears that it is not good enough to simply pick any two opposing vertices to define a box (as in all the graphics programs that have spoiled me). When passing aa and bb into the constructor, I had imagined that it would sort out each axis' min and max if necessary. Looking inside, I see that it assumes aa to be min values and bb to be max values. Since I used offsets and rotateYCCW to produce my aa and bb, most facings of my block will invert min and max on either the X or Z axis. I now suspect that such an inverted bounding box will malfunction. I'll sort out my mins and maxes and let you know if that solves my problem. EDIT: Indeed, that was my problem. My bounding box looked okay to me because it fit my own bad assumptions. The examples I was working from were all block-centered, whereas my fan is directional, so I was offsetting off-center, and it wasn't quite obvious that the box wasn't sorted right. Here's my sorting correction: aa = new BlockPos (Math.min (near.getX (), far.getX ()), near.getY (), Math.min (near.getZ (), far.getZ ())); bb = new BlockPos (Math.max (near.getX (), far.getX ()), far.getY (), Math.max (near.getZ (), far.getZ ())); And its 4 lines in the log : [11:44:17] [server thread/INFO] [sTDOUT]: [jrfinventions.classBlockBlower:windField:203]: near = 238, 64, 202 [11:44:17] [server thread/INFO] [sTDOUT]: [jrfinventions.classBlockBlower:windField:204]: far = 232, 66, 200 [11:44:17] [server thread/INFO] [sTDOUT]: [jrfinventions.classBlockBlower:windField:205]: aa = 232, 64, 200 [11:44:17] [server thread/INFO] [sTDOUT]: [jrfinventions.classBlockBlower:windField:206]: bb = 238, 66, 202 [11:44:17] [server thread/INFO] [sTDOUT]: [jrfinventions.classBlockBlower:updateTick:244]: Found entity = item.item.sulphur with motion 3.0027303737907635E-38, -0.0, -3.2726263473873886E-38 [11:44:17] [server thread/INFO] [sTDOUT]: [jrfinventions.classBlockBlower:updateTick:244]: Found entity = item.item.redstone with motion 2.9882014093001097E-96, -0.0, -2.795579597995496E-96
  16. Oooh... I hadn't thought of that, but (I think) I see what you mean. Will do.
  17. Both methods return empty. I stepped through getEntitiesWithinAABB in the debugger (because that's the one that is supposed to give me the type of entities I am interested in). It started to find all of the EntityItem entities, but then it filtered them all out when a multimap method called func_180215_b called iterators.filter (iterator, clazz). What's weird is that the iterator had EntityItem entities in it, and it was supposedly filtering for EntityItem class, but it eliminated everything and returned an empty iterator. I then ran using getEntitiesWithinAABBExcludingEntity(null, yourAABB). It too returned empty. However, I verified that my bounding box has correct world coords. I am beginning to worry that item drops are undetectable. When I leave my breakpoints active, I see these functions used only to detect mobs. It might be an unstated rule that they ignore debris. Does anyone know how a mob picks up a loose EntityItem? Is it the mob that scans for the item, or the EntityItem that scans for a mob to pick it up? If the latter, then I may be looking at things the wrong way. I may need to find a way for drops to detect my fan and react to it. Such a burden would probably kill my mod. However, before I give up, I am going to revisit the low-level method where I thought I saw my drops get filtered out. If there's public method I can call to bypass the filter, I may have an out.
  18. Aha -- First try to get all entities and then discriminate. I like that strategy. I'll give it a go today and post my results when I learn more.
  19. That was exactly my thinking leading up to my OP. Printed aabb looks right, but I'll double check to see if the numbers are shifted somehow. What I'm wondering is if I'm passing the right class. To detect drops, is EntityItem.class the right argument?
  20. I'm trying to design a block (redstone device) that will affect drops that are floating near it. Unfortunately, it is not detecting them. My bounding box looks right, but the entity list is coming back empty. This is the call I made; what bad assumption did I make? ArrayList<Entity> entityList = (ArrayList<Entity>) world.getEntitiesWithinAABB (EntityItem.class, aabb); Is there an example I can see of a mod that acts upon drops in an area? When I search for one, I get so many hits about dropping items that I haven't found blocks that detect the drops after they're dropped.
  21. Find the method where vanilla tools or swords take extra damage when breaking the "wrong" kinds of blocks. Make your tool take 2 damage every time it breaks a block.
  22. Did you look inside the vanilla ItemSword class? It has this method in it (overriding the default behavior in class Item): public float getStrVsBlock(ItemStack stack, Block block) { if (block == Blocks.web) { return 15.0F; } else { Material material = block.getMaterial(); return material != Material.plants && material != Material.vine && material != Material.coral && material != Material.leaves && material != Material.gourd ? 1.0F : 1.5F; } }
  23. Where is "Reference", and what all is in it?
×
×
  • Create New...

Important Information

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