Jump to content

shadowmage4513

Forge Modder
  • Posts

    157
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by shadowmage4513

  1. Closer examination of ICraftingHandler shows that while it does give a player reference, it does not allow one to change or nullify the crafting result. It is more of an informative callback than a crafting-event mechanism. I will continue looking around a bit...thanks for the info anyway -- I might be able to use this elsewhere..but it does not solve the current problem =\
  2. Ahh..on further examination, I see you are referring to ICraftingHandler....which might just give me the player reference I need. Thanks for the tip, I will investigate this path a bit, and see what I can come up with.
  3. I have the list of players/research already. The problem is that there is no player reference passed anywhere to the recipes. I have no way to tell which player to examine the research tree for.
  4. Hi all, I'm trying to streamline the crafting process in my mod a bit. I use a research system to prevent certain items from being crafted until players have done the requisite research. Currently any recipe requiring research must be crafted at a special crafting table -- not because I want it this way, but because I could not find a way to deny crafting of normal crafting-bench recipes based on the player crafting the item. My question is this: Is anyone aware of a method to change the crafting outcome from a recipe dynamically dependent upon the player doing the crafting, at a normal crafting bench? My first thought would be a creating a subclass of ShapedRecipes, and return 'false' from matches() for players that have not done the requisite research...but I cannot find a way to get a reference from the crafting player from InventoryCrafting. I might be able to pull 'some players' from the containers crafters list from InventoryCrafting (would need some reflection at least to get at some private fields), but I cannot see a way to guarantee that any of these 'players' are in-fact THE crafting player. Any thoughts? Thanks in advance, Shadowmage
  5. from a brief look it appears that you are either: A: not recompiling and reobfuscating (you cannot use the eclipse generated .class files, they need to be reobfuscated by MCP) (you need to run recompile in the MCP directory, then reobfuscate (either one), then grab your finished .class files from the reobf directory, add any assets/etc and pack into your distribution format (.jar/.zip)) or... B: are trying to access client-only methods from server-side (you have to proxy those calls, or not access client-only methods from server)
  6. this is caused by Mojang changing their default download locations. there are a couple of solution posts on the forum here, but they've been pushed down onto page2+. see: http://www.minecraftforge.net/forum/index.php/topic,14567.0.html
  7. You need to implement the tile entity method of getDescriptionPacket() in order to send your data to client. I bet the data is read properly on server, but the client never sees it -- it gets a blank tile-entity with the default initialized values for those fields. --edit oh: you will also need to implement the packet-reading methods.... public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt)
  8. Thanks for the info -- I will take a look into this shortly, it sounds like that may just be the missing link I was looking for
  9. Hi all, I'm trying to add a semi-block-protection feature to my mod. The idea is that there will be a control block/TE in an area, which will 'reinforce' blocks in its chunk (or otherwise designated bounds). This will be based on a teams system, where players not on the controlling team for the chunk/controlled area will have a much harder time breaking blocks within that designated area. (the goal is for siege warfare -- to remove the ability to just pick-axe through your enemies defenses in mere seconds -- but not completely remove the ability to break, merely make it take longer...tunneling should be a valid tactic, but not the _only_ tactic as it currently is ) Setting up the control block/TE is fairly simple/standard stuff...where I'm getting stuck is dynamically altering the block-hardness or break speed of the player -- based on location --. I see there is the BreakSpeed event...which does pass a player reference, however, it does not give any target block location reference. Is there a super-secret hidden event that I'm not seeing that contains this information, or should I re-ray-trace to get the target block? Has anyone else done a similar feature without resorting to a core-mod? Thanks in advance, Shadowmage
  10. I had a similar issue awhile back, caused by reobfuscation of a field I had named the same as one of MCs fields. (I think my issue was actually with a method name, but the same/similar probably applies) Be careful with extending classes that you don't try and use duplicate field names from the parent classes (the fields may be private in the parent and not visible in the child). What will happen is MC will obfuscate your field name in the class (because it thinks it is an vanilla MC field), but none of the references to that field (for some reason it doesn't pick up the references to the field correctly, and they retain the original name as you specified). When it goes to call your field from one of your classes, you get the no-field found error, as that field was re-named obfuscated. In short -- check your naming, make sure you don't have any duplicate named fields/methods in your classes.
  11. Thanks for the responses guys...I found the cause of the issue though after a bit of extra investigation. Essentially it boiled down to me having an extra '/' at the start of the path when I was creating the resource locations for model textures. Not precisely sure why it would work fine in eclipse and not when packaged, but changing '/textures/' to 'textures/' on my bind call eliminated the issue.
  12. Hi all... More strange issues with updating to 1.6... My textures work/bind fine while in eclipse, but in the released mod loaded into a MC instance, they don't load properly. output error is as follows: Client> 2013-09-21 19:32:04 [WARNING] [Minecraft-Client] Failed to load texture: ancientwarfare:/textures/models/crafting/teCivilEngineeringStation.png Client> java.io.FileNotFoundException: ancientwarfare:/textures/models/crafting/teCivilEngineeringStation.png Even stranger...it is only textures that are used for models, and not blocks/icons... textures are located in the .zip at assets/ancientwarfare/textures/* I can verify that the textures are in the zip, in the proper locations -- they just won't load properly with the released/obfuscated mod. Any ideas? Thanks, Shadowmage
  13. ^^^ Thanks for the tip -- exactly what I was looking for I figured there was a method to accomplish it, I just haven't had the time yet to read through the updated/changed source in 1.6.
  14. Thats pretty much what I'm thinking at this point. I registered the same icons as item icons (after copying the textures to the /items/ path), and the blocks register just fine. Going to have to find a different method though, as I don't like having to duplicate resources to work around a bug. I should probably just create a proper ItemBlock for the thing, as my other ItemBlock stuff renders fine pulling in block icons/textures. Any way to manually set what texture sheet the render-engine pulls from? Thanks for the input -- one more problem solved/figured out (at least for now) for all types but FIRST_PERSON_MAP it will execute the rest code block following the if/return block. No need to check explicitly for the INVENTORY type, as that is included in the set of remaining render types. The problem isn't that its not rendering, merely that it was binding textures from the wrong texture sheet for the passed in icon.
  15. A: You cannot rely upon EntityID on the client side until AFTER that entity has been fully setup. The entity spawn packet/data will force-set that client-side entity to use the same entityID as the server-side copy of that entity -- but only AFTER it has received all of its spawn data. E.g. you cannot rely upon client-side entityID in the constructor for that entity. (as entityInit gets called in the entity constructor, it is not yet fully setup at that point). Also, as others point out, you should be sending information from server -> client in most cases. Only rarely would you need to send client->server data from an entity -- it is usually better to handle the player interaction logic server side and use the normal server-> client update channels. The proper method to setup a client-side entity is to use the IEntityAdditionalSpawnData interface to load the initial client-side entity with data. After that, a data-watcher is probably the best built-in method to keep things synched. It has less overhead than you seem to think -- the data-watcher is already being synched to client-- adding in a few more bits (ints) of data is small compared to the overhead of a complete packet for only sending 1/2 ints -- data watchers also only update/send data when their data has changed.
  16. Yes, the blocks return an icon from that method. The blocks themselves render fine in the world once placed. Only the IItemRenderer is binding icons from the item sheet with the same texture UV as the block icons that I am actually using to render. I have a feeling its just a context problem -- e.g. IItemRenderer is called when the render-engine is setup to render items, and has the item texture sheet bound, with no easy way to force it to use the block texture sheet. (Hence, I give it an icon...it pulls the UV from the icon, but never binds the texture-sheet the icon belongs to)
  17. Further testing reveals that if I register the same icon names as item icons (and duplicate all of my block textures =\ ), the IItemRenderer will render the block as intended. More and more it is looking like the IItemRenderer is for some reason not checking the type/origin of the icon to bind the proper texture sheet. Not sure why it worked in 1.5.2. I will update with more information as I come across it.
  18. So, finally updating my mod to 1.6.2. Most things went as smooth as they could, but I've been banging my head against a problem for a few hours now, something that makes absolutely no sense. What changed with IItemRenders between 1.5 and 1.6? I had an item that rendered as a block in 1.5.2, but in 1.6.2 it refuses to bind the block icons. It instead renders a random icon off of the items icon sheet -- it seems completely random as I get fish, golden carrots, and icons from my own mod used, though it is consistent for a give id/meta. I'm guessing its not switching the base-texture sheet from the item sheet but still using the UV from my block Icon. Any way to force it to use the block texture sheet? Should I just double-register all of my icons for use as an item icon (no clue if this will work...)? Any other simple methods for rendering an item as a block? (the item is not an ItemBlock -- the Item and Block are completely separate for whatever reason I designed it that way....NFC anymore, and will probably just end up rewriting the whole system if I can't get this weird shit figured out) Strangely, if I pull the icon instance out and query it for iconName -- it returns the proper icon path for what I would expect, only the texture that is rendered is wrong. Anyhow..here is the render code. Its pretty standard, taken almost exactly from the RenderBlocks methods. It worked fine in 1.5.2. (i have the par2/meta value set to 0 until I figure out the icon issues -- 0 is a valid meta and should be pulling up the same icon as the block uses to render) @Override public void renderItem(ItemRenderType type, ItemStack item, Object... data) { if(type==ItemRenderType.FIRST_PERSON_MAP) { return; } RenderBlocks render = (RenderBlocks)data[0]; int blockNum = item.getItemDamage()/16; Block blk = null; switch(blockNum) { case 0: blk = BlockLoader.civicBlock1; break; case 1: blk = BlockLoader.civicBlock2; break; case 2: blk = BlockLoader.civicBlock3; break; case 3: blk = BlockLoader.civicBlock4; break; default: blk = BlockLoader.civicBlock1; break; } GL11.glPushMatrix(); if(type!=ItemRenderType.ENTITY) { GL11.glTranslatef(0.5f, 0.5f, 0.5f); GL11.glRotatef(180, 0, 1, 0); } else { GL11.glScalef(0.5f, 0.5f, 0.5f); } int par2 = 0;//meta value Block par1Block = blk; Tessellator tessellator = Tessellator.instance; par1Block.setBlockBoundsForItemRender(); render.setRenderBoundsFromBlock(par1Block); GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); GL11.glTranslatef(-0.5F, -0.5F, -0.5F); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, -1.0F, 0.0F); render.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, render.getBlockIconFromSideAndMetadata(par1Block, 0, par2)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, 1.0F, 0.0F); render.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, render.getBlockIconFromSideAndMetadata(par1Block, 1, par2)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, 0.0F, -1.0F); render.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, render.getBlockIconFromSideAndMetadata(par1Block, 2, par2)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, 0.0F, 1.0F); render.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, render.getBlockIconFromSideAndMetadata(par1Block, 3, par2)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(-1.0F, 0.0F, 0.0F); render.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, render.getBlockIconFromSideAndMetadata(par1Block, 4, par2)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(1.0F, 0.0F, 0.0F); render.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, render.getBlockIconFromSideAndMetadata(par1Block, 5, par2)); tessellator.draw(); GL11.glTranslatef(0.5F, 0.5F, 0.5F); GL11.glPopMatrix(); }
  19. I have not personally tried this, but it should be possible to track the position of where the entity was frozen, and then on world tick, force-set the entity back to that position (updating both posX and prevPosX, possibly even lastTickPosX as well). Try force-setting motionX,Y,Z as well to 0. (you can synch entity with position using a WeakHashMap with entity as key and the position as value -- use a weak map so as not to leak references) You need to track the freeze position yourself, trying to use the entities own position variables will not work very well because the AI/move methods will adjust those themselves every tick.
  20. I have had to solve this issue myself awhile back -- I started by using the vanilla code for entity interaction, but extending the interaction range. Essentially, it boils down to a roll-your-own ray-tracer with entity collision detection. I have found many other uses for it since writing it. you will need to determine the start and end points/vectors through some trig (take the players pitch, yaw, and x,y,z , offset for your desired 'search' length to get your tx coordinates) /** * * @param world * @param x startX * @param y startY * @param z startZ * @param tx endX * @param ty endY * @param tz endZ * @param borderSize extra area to examine around line for entities * @param excluded any excluded entities (the player, etc) * @return a MovingObjectPosition of either the block hit (no entity hit), the entity hit (hit an entity), or null for nothing hit */ public static MovingObjectPosition tracePath(World world, float x, float y, float z, float tx, float ty, float tz, float borderSize, HashSet<Entity> excluded) { Vec3 startVec = Vec3.fakePool.getVecFromPool(x, y, z); Vec3 lookVec = Vec3.fakePool.getVecFromPool(tx-x, ty-y, tz-z); Vec3 endVec = Vec3.fakePool.getVecFromPool(tx, ty, tz); float minX = x < tx ? x : tx; float minY = y < ty ? y : ty; float minZ = z < tz ? z : tz; float maxX = x > tx ? x : tx; float maxY = y > ty ? y : ty; float maxZ = z > tz ? z : tz; AxisAlignedBB bb = AxisAlignedBB.getAABBPool().getAABB(minX, minY, minZ, maxX, maxY, maxZ).expand(borderSize, borderSize, borderSize); List<Entity> allEntities = world.getEntitiesWithinAABBExcludingEntity(null, bb); MovingObjectPosition blockHit = world.rayTraceBlocks(startVec, endVec); startVec = Vec3.fakePool.getVecFromPool(x, y, z); endVec = Vec3.fakePool.getVecFromPool(tx, ty, tz); float maxDistance = (float) endVec.distanceTo(startVec); if(blockHit!=null) { maxDistance = (float) blockHit.hitVec.distanceTo(startVec); } Entity closestHitEntity = null; float closestHit = Float.POSITIVE_INFINITY; float currentHit = 0.f; AxisAlignedBB entityBb;// = ent.getBoundingBox(); MovingObjectPosition intercept; for(Entity ent : allEntities) { if(ent.canBeCollidedWith() && !excluded.contains(ent)) { float entBorder = ent.getCollisionBorderSize(); entityBb = ent.boundingBox; if(entityBb!=null) { entityBb = entityBb.expand(entBorder, entBorder, entBorder); intercept = entityBb.calculateIntercept(startVec, endVec); if(intercept!=null) { currentHit = (float) intercept.hitVec.distanceTo(startVec); if(currentHit < closestHit || currentHit==0) { closestHit = currentHit; closestHitEntity = ent; } } } } } if(closestHitEntity!=null) { blockHit = new MovingObjectPosition(closestHitEntity); } return blockHit; }
  21. It is firing once on server, and once on client
  22. if (this.currentFlightTarget == null || this.rand.nextInt(30) == 0 || this.currentFlightTarget.getDistanceSquared((int)this.posX, (int)this.posY, (int)this.posZ) < 4.0F) { if(this.entityToAttack != null) { //HERE IS THE PROBLEM this.currentFlightTarget.set((int)this.entityToAttack.posX, (int)(this.entityToAttack.posY + 0.5F), (int)this.entityToAttack.posZ); } else { this.currentFlightTarget = new ChunkCoordinates((int)this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int)this.posY + this.rand.nextInt(5) - 2, (int)this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7)); } } so, you indicated the problem line the reason it is sometimes null, is because you are explicitly executing that branch when the target IS null with the first bit...so you need to check if it executed that branch because of null, and un-nullifiy it (give it a reference to SOMETHING), such as: if (this.currentFlightTarget == null || this.rand.nextInt(30) == 0 || this.currentFlightTarget.getDistanceSquared((int)this.posX, (int)this.posY, (int)this.posZ) < 4.0F) { if(this.entityToAttack != null) { if(this.currentFlightTarget==null) { this.currentFlightTarget = new ChunkCoordinantes(0,0,0); } this.currentFlightTarget.set((int)this.entityToAttack.posX, (int)(this.entityToAttack.posY + 0.5F), (int)this.entityToAttack.posZ); } else { this.currentFlightTarget = new ChunkCoordinates((int)this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int)this.posY + this.rand.nextInt(5) - 2, (int)this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7)); } }
  23. Well, for my scenario, ALL of my motion is calculated server side. It needs to calculate rotation because the forward motion/direction depends on the rotation. You don't necessarily need to calc rotation server side (can interpolate from the motion vector on the client side), but in my case, my vehicles have forward and reverse, which necessitated using rotation in the basic motion calculations, and synching this rotation to clients (they don't calculate based on it, merely display whatever the server tells them) As to the other...how do you _not_ calculate motion server side? If the entity on the server doesn't calculate motion (and move), the client side entities certainly won't move (or will be out of position client side, and then collision detection wont work properly). Essentially I moved over to a completely server-authenticated/calculated vehicle movement system, though it is probably overkill for most peoples purposes (I required smooth and (mostly) synched motion between server/clients, and that is the most reliable way I found to achieve it). Anyway, I'm not meaning to argue on it, there are lots of ways to handle motion/synching depending upon your needs (dead reckoning, predictive, checked, lots of others) -- I was merely wanting to point out that you can indeed separate the code for client/server, for both easier reading of code, and possibly increased performance -- after all, why calculate something twice (or more, in the case of multiple clients), when once will do.
  24. Most of those things (world, player...) are not needed to be sent in the event, as there exist only a single one for each client. E.G each client only has a single world object, and is responsible for the position of a single player. As such, these fields are accessible directly from the Minecraft class, in the form of Minecraft.getMinecraft().thePlayer and Minecraft.getMinecraft().theWorld .. These are a global reference can be accessed from anywhere (as long as it is client side, trying to use either on server side will crash with a ClassNotFound exception for Minecraft.class) That gets you the 'controlling' client player, and the world he/she is currently residing in. From there you can easily poll the player.posX/etc to get your positioning to calculate your chunks
  25. In my vehicle implementation, my onClientUpdate is pretty small -- it just applies any motion that it had received from the server. Thats it--little/no calculation, no collision checks, just blindly/dumbly apply what the server sent. My server-side calculates motion, applies collision, applies rotation, applies user input, and sends update-packets to client side with the intended positioning. Client side takes that information and figures out how to be where the server says it should be within the allotted time (3-5 ticks generally) (very similar to the vanilla boat rotation-delta updating methods). How much needs to be done client side will mostly depend on how you are calculating motion, and where you are doing collision checking at. At the minimum-- you will need to update any movement/animation variables -- e.g. leg position, wheel rotation, as well as applying any motion you had calculated (you can techincally do motion calculations client side as well and use position synch packets to keep things lined up...but I figured...why calculate something twice?). Mew has the correct approach though -- think exactly what is needed client side? You need to know where it is at, how it is moving (both how it is rotating and moving in the world), possibly the health value (for health bars), and any other information needed for client-rendering. Pretty much everything else can be server-side only. (I can provide links to source examples if needed)
×
×
  • Create New...

Important Information

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