-
Posts
2638 -
Joined
-
Last visited
-
Days Won
4
Everything posted by Ernio
-
[1.9][Solved] Capability isn't storing data between calls
Ernio replied to Snoopy_WWI_Ace's topic in Modder Support
1. No, you don't need to store Capability. 2. In packets client->server that are "acting upon" player who issending them, you don't need to send player. * Server knows who sent a packet to it. * ctx.getServerHandler().playerEntity * Only thing you need is rune pressed. 3. Your code is not thread safe: http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html * Whole thing in your handler should be in runnable. 4. I didn't look for Java mistakes, I will if above will not fix the problem. -
True dat, with @Capabilities and Events (Attack, Hurt, Death, etc. Events) you can hook and replace any part of attacking/damaging systems (with each and every, even smallest part of detail) - trust me, I am doing it. CoreMod = bleh.
-
How about some code? If this custom AI? You might be messing with sides or if by lagging you mean logic lagging (server) - your AI might be too heavy (but that would lag whole server).
-
Basically - you need to attach source, which should be provided with API itself. Note: If lib is also a @Mod, it cannot be in /mods/ folder.
-
Then nope - you should not do it that way. You are looking in the wrong way, use standard Java techiques. Use lazy inicialization technique. Something like: getStacksNBT() { if (nbt null) setNBT(some new NBT); return theNBT; } If null-checking is not enough (you can have more than null or non-null cases) you can hold e.g boolean like "has been just created"
-
Nope. Even if catching ItemStack's creation would be applied to vanilla (there are quite few places to cover), it would be impossible to catch it for all mods. What you can track is: * Joining ItemStack to world (joining in any way like dropping, spawning, etc.) * Change to Player's inventory (by checking last tick stacks with current ones) As to catching levels of creation you mentioned: 1. For command you might be able to catch commands themselves. 2. For creative inventory I don't think so. (but maybe) 3. Mentioned "Change to Player's inventory" will be able to track anything "new", but it won't recognise source of added ItemStack. Any particulat purpose? There might be some way around it.
-
If you are planning base/core modding: 1. Forge is not for you. 2. Modding is not for you. As to proper ways of doing stuff: http://mcforge.readthedocs.io/en/latest/datastorage/capabilities/ Note: Google Forge Events.
-
Why all the security questions in the forums?
Ernio replied to llanita's topic in General Discussion
Well, you could say that it might be discouraging, but main purpose for it is to not allow bots. As to Lex (Lexmanos) - it is the question about CREATOR of Forge (one of them) - kinda must-know stuff. As to bans - it is just a policy (I think) that basically says - don't ask stupid questions, most of them are alredy answered in some FAQ I guess. Also - warm welcome from me, have fun in MC. -
By looking at contents of linked sources and links they provide - I can say that from that you should be able to grasp basics of modding with introduction to intermidiate stuff. There is no such thing as tutorial on advanced stuff - that's why it's called advanced. Java knowledge and vanilla code-reading is key.
-
Oh, right: Golden rule - modid should be always lowercase. And by always I mean everywhere - including assets.
-
new ResourceLocation(ModID, "textures/gui/chestSlots.png"); // make it global static! Does this work? (background) this.mc.getTextureManager().bindTexture(your resource location); this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize); As to drawRect - try different color, the format is 0xAARRGGBB.
-
1. Minecraft colors and static GL modes are converted to integers e.g: 0xFFFFFF = white = 16777215 (MC) Or GL11.GL_QUADS = quads = 7 (MC) For your and clarity of your code's sake I'd recommend using left approach. 2. Lookup Gui#drawRect It takes left, top, right, bottom - those are positions of sides. So e.g right will be this.guiLeft + 256 (in your case).
-
Skype: ernio333 TeamViewer if you can so I can quickly explain code + examples. That is if earlier post are not enough (they should be, there is not much really to say, but only to show some things). And lol me - "dude, trust me, there are so many people who would know what to do with all that I wrote" it was supposed to be "who wouldn't" - I messed up, actually your code is (almost) good.
-
* Block - fine (aside from totally redundant overrides like destroyBlock). * IGuiHandler: 1. ChestGuiHandler - there is one IGuiHandler per mod, kinda bad name for something that will likely do more things than that. 2. Your docs are quite false. - getServerGuiElement - returns Container or null - getClientGuiElement - returns GuiScreen or GuiContainer, were it (GuiContainer) should only be returned when corresponding server's ID also returns Container of same type. * ContainerChestTileEntity - fine (I didn't check transfering and merging stacks, too hard to do without testing, make sure it works tho). * GuiChestTileEntity - fine. Notes: If you would override initGui() - remember to call super. As to rendering things, you can learn some GL (now VertexBuffer, old "tesselator") from Gui.class. I wouldn't really use it directly but rewrite it to static util class (in this case tho, I think GuiContainer extends Gui, so...). For future - remember that vertexes should be added anti-clockwise. * TileEntityRedChest - fine (no "deep" checks). * Main - fine. To be honest this is one of the better formatted sources I've seen here (tho the topic is not that hard) - god bless you for not posting mashed potatoes like some of ppl do. #anotherUselssPost #iWasExpectingSomeMistakes
-
Thread name says more than post itself. Anyway: * WorldSavedData (WSD) * WorldTickEvent (it is also kinda possible to do it with timestamps relative to World's total time, but I personally don't like that one). That's it. Increment time held in WSD that would be saved/loaded to world (event.world I guess). Remember to use event.phase (Phase), you probably want START in this case. As to WSD itself - I guess you know how to use NBT, so there is that. Additional notes: Do you also need times on clients? In that case - use EntityJoinedWorldEvent to send IMessage (SimpleNetworkWrapper) to client that will set value to server's one, then - increment on both sides. I am not sure if WorldTickEvent fires for client world, so if not - you can use ClientTickEvent and Minecraft#theWorld. Links: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html Notes: On client you can hold that value as static field anywhere really, in which case you will use ClientTickEvent to increment.
-
Server should return Container. Client should return GuiContainer that takes/creates corresponding Container within. Please post update code.
-
I belive list is of List<ItemStack>. Simply put new ItemStacks with stackSized fitting your needs. As to chances - use Random class. Generate nextDouble() and for e.g 20% do double < 0.2, for next 40% do 0.2 <= double < 0.6, etc.
-
The problem is that events should be used to alter vanilla/other things. When you have access to your own class you should utilize it. There is always only one optimized algorithm, all other are bad ones. In this case you should be using getDrops. List list = new List(); // +generics list.add(item); return list;
-
You code looks well (dude, trust me, there are so many people who wouldn't know what to do with all that I wrote, but that is what I got used to since a lot of ppl who come here don't know Java). Direct answers: 1. Yes, this is server side thingy that keeps track of which player should receive updates about which entity. Best design for those things is to make: @Override public final void updateTrackers(Entity entity, IMessage message) // method in my SimpleNetworkWrapper { EntityTracker et = ((WorldServer) entity.worldObj).getEntityTracker(); et.func_151248_b(entity, this.getInstance().getPacketFrom(message)); // this = SimpleNetworkWrapper } What this does is basically get "tracker" of "entity" and "func_151248_b" (note: maybe they finally renamed it) will send given IMessage to all EntityPlayer seeing this "entity". SNW#getPacketFrom(IMessage) converts IMessage to vanilla format Packet. How it should be used? Best design is probably something like sided setter in Entity class: private int something; public void setSomething(int value, boolean notify) { this.something = value; if (!this.worldObj.isRemote && notify) { SNW#updateTrackers(this, new IMessage(this.entityId, this.something)); // calls my method in SNW } } Some people do this using methods such as SimpleNetworkWrapper#sendToAllAround(IMessage message, NetworkRegistry.TargetPoint point) which is provided by Forge itself, but I think it is simply bad. EntityTracker is superior. So basically: * EntityTracker - solves existance updating (changes made to entity when someone sees (tracks) it alredy). Server only. * IEntityAdditionalSpawnData (IEASD) - solves spawn updating (data sent precisely when you start tracking entity). * PlayerEvent.StartTracking - like IEASD - allows doing the same for not your entities, it also allows other things (think about it). Not it fires server only. EDIT Bog note - my techniques regarding EntityTracker, while still good, might be outdated. Please lookup class itself as it now provides methods such as getTrackingPlayers and sendToAllTrackingEntity. As to one I have - func_151248_b is vanilla's one - also note that "tracking entities" are also the the entity itself (If passed Entity is EntityPlayer, it tracks itself). Additional info: I forgot to re-point out: This should be taken care of from server's point of view. How do you know the server will acceps sent values? And if not - it may lead to your client having bad data. EDIT 2 Just a reminder - not everything needs to be synced at all times. If all player seeing camera don't actually need some values, you can simply not update them with those. You could e.g send those values only when they will start interaction (just before you send openGui order-packet).
-
[1.9.4] getStateFromMeta(); Deprecated Replace by ???
Ernio replied to perromercenary00's topic in Modder Support
Mojang appears to be using @Deprecated as a mark of vanilla MC methods that should be used by internals and subclasses of Block. So nope - there is no replacement, this is just weird way of things. -
[1.9.4] getStateFromMeta(); Deprecated Replace by ???
Ernio replied to perromercenary00's topic in Modder Support
Mojang appears to be using @Deprecated as a mark of vanilla MC methods that should be used by internals and subclasses of Block. So nope - there is no replacement, this is just weird way of things. -
1. As you noticed from source (I guess): IGuHandler is mainly designed to connect Container with its GuiContainer. First, you probably understand sides, and if not: http://mcforge.readthedocs.io/en/latest/concepts/sides/ It is important to get that Entity object is on server and client, where they communicate with each other via entityId. Calling player.openGui will: (by thread) Server: * If Container is returned, it will be opened and packet will be sent to client (with world, id, x, y, z, where x/y/z can by anything). Packet will call client opening. * If null - nothing will happen. Client: * It will simply call Minecraft#displayGuiScreen (I might have messed up naming). Now - Container are ONLY ever used to display interactive Guis that hold/display ItemStacks. In this case you don't need that. And yes - in this case IGuiHandler should be only used to centralize code (meaning that you will open all your guis from player.openGui). And yes - you will retur null on server and normal GuiScreen on client. Now - since only client can open that gui (no container), you need to call opening from client thread (world.isRemote) - this is the 1st mistake you made there (in entity class). 2. Next - as one could guess - "client always lies" - if you would want to check (on client) if client can even open a gui, it can always lie. That is where you can implement request/order packet system. Basically - since Entity#processInteract is called on both sides, you can perform checks on server and then if passed - send packet to client to call player.openGui. Followup to this will be SimpleNetworkWrapper and thread safety: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html If you don't have those yet - you will be using them in future, so I recommend designing abstraction layer. 3. Okay, so now Gui itself: You simply make constructor have CameraEntity (why not EntityCamera? ) as arg. There are (as said) two options: * Open gui with IGuiHandler (player.openGui). - Then in your IGuiHandler you will be getting that entity using World#getEntityByID. As said - x/y/z can by anything, so it can also be that ID. * Open gui with Minecraft#displayGuiScreen. - In that case you can directly pass Entity instance to new Gui. (and instance you can again get from entityID). 4. Regarding request/order packets - you will need to send (server->client): 1st option: Only entityID (entity.getEntityId()) 2nd option: entityID and guiID (so you can use one packet for multiple guis). In Handler you will be calling opening gui mentioned in 3rd point. EDIT 5. Same rules (packets) apply when sending data from gui (client) to server. You will need thread safety and will need to send data (including entityId) that will (on server) apply that data onto server's entity (that you get from entityID). 6. Logically whenever you make such messaging you should do: * (request/order) clientRequest -> serverCheck -> serverChanges -> serverAnswer -> clientChanges or * (order/update) serverChanges -> serverAnswer -> clientChanges Where 1st one applies when client would want to change entity data. EDIT 2 7. Now synchronizing Entity itself: * EntityTracker - can be used to get all players tracking given entity. You can use that to update all players seeing it when you change value on server. Simply send packet to all those who track it. * PlayerEvent.StartTracking - when player starts tracking (seeing) entity, it will be called. event.target is entity being tracked. You can use this to sync data with player starting tracking about entity being tracked. This method should be only ever used to OTHER (not yours, eg vanilla) Entities or if you want to centralize your code (e.g you have same behavir for all entities because you assigned @Capability to all of them). * IEntityAdditionalSpawnData - implement this to your OWN entities - basically what StartTracking does, but more interanlly. * SimpleNetworkWrapper - send simple packet updates. NEVER FORGET about THREAD SAFETY. Note: Getting grasp of above allows you to pretty much start doing anything (intermidiate).
-
1. As you noticed from source (I guess): IGuHandler is mainly designed to connect Container with its GuiContainer. First, you probably understand sides, and if not: http://mcforge.readthedocs.io/en/latest/concepts/sides/ It is important to get that Entity object is on server and client, where they communicate with each other via entityId. Calling player.openGui will: (by thread) Server: * If Container is returned, it will be opened and packet will be sent to client (with world, id, x, y, z, where x/y/z can by anything). Packet will call client opening. * If null - nothing will happen. Client: * It will simply call Minecraft#displayGuiScreen (I might have messed up naming). Now - Container are ONLY ever used to display interactive Guis that hold/display ItemStacks. In this case you don't need that. And yes - in this case IGuiHandler should be only used to centralize code (meaning that you will open all your guis from player.openGui). And yes - you will retur null on server and normal GuiScreen on client. Now - since only client can open that gui (no container), you need to call opening from client thread (world.isRemote) - this is the 1st mistake you made there (in entity class). 2. Next - as one could guess - "client always lies" - if you would want to check (on client) if client can even open a gui, it can always lie. That is where you can implement request/order packet system. Basically - since Entity#processInteract is called on both sides, you can perform checks on server and then if passed - send packet to client to call player.openGui. Followup to this will be SimpleNetworkWrapper and thread safety: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html If you don't have those yet - you will be using them in future, so I recommend designing abstraction layer. 3. Okay, so now Gui itself: You simply make constructor have CameraEntity (why not EntityCamera? ) as arg. There are (as said) two options: * Open gui with IGuiHandler (player.openGui). - Then in your IGuiHandler you will be getting that entity using World#getEntityByID. As said - x/y/z can by anything, so it can also be that ID. * Open gui with Minecraft#displayGuiScreen. - In that case you can directly pass Entity instance to new Gui. (and instance you can again get from entityID). 4. Regarding request/order packets - you will need to send (server->client): 1st option: Only entityID (entity.getEntityId()) 2nd option: entityID and guiID (so you can use one packet for multiple guis). In Handler you will be calling opening gui mentioned in 3rd point. EDIT 5. Same rules (packets) apply when sending data from gui (client) to server. You will need thread safety and will need to send data (including entityId) that will (on server) apply that data onto server's entity (that you get from entityID). 6. Logically whenever you make such messaging you should do: * (request/order) clientRequest -> serverCheck -> serverChanges -> serverAnswer -> clientChanges or * (order/update) serverChanges -> serverAnswer -> clientChanges Where 1st one applies when client would want to change entity data. EDIT 2 7. Now synchronizing Entity itself: * EntityTracker - can be used to get all players tracking given entity. You can use that to update all players seeing it when you change value on server. Simply send packet to all those who track it. * PlayerEvent.StartTracking - when player starts tracking (seeing) entity, it will be called. event.target is entity being tracked. You can use this to sync data with player starting tracking about entity being tracked. This method should be only ever used to OTHER (not yours, eg vanilla) Entities or if you want to centralize your code (e.g you have same behavir for all entities because you assigned @Capability to all of them). * IEntityAdditionalSpawnData - implement this to your OWN entities - basically what StartTracking does, but more interanlly. * SimpleNetworkWrapper - send simple packet updates. NEVER FORGET about THREAD SAFETY. Note: Getting grasp of above allows you to pretty much start doing anything (intermidiate).
-
Are you calling this ONLY (!world.isRemote) server side?
-
Are you calling this ONLY (!world.isRemote) server side?