-
Posts
2638 -
Joined
-
Last visited
-
Days Won
4
Everything posted by Ernio
-
1. Item != ItemStack - Item is a SINGLETON describing what you are holding. - ItemStack is the thing that you are actually holding (it knows what Item it is, how many, and other data such as NBT). - Logically - you can't hold ANY data in Item, Only static or fields shared between all Items. - If you want item with data - you hold it in ItemStack's NBT. 2. Data held in NBT can be read directly (but like I mentioned - if you would use it per-tick and there is a lot to read, it is not very efficient). The other option is to read data once, deserialize it into @Capability and then operate on normal-java fields. Then when itemStack is saved back - you can serialize @Capability back to ItemStack's NBT. 3. If you would go after design you mentioned, you would need such (or similar) method: public boolean cast(EntityPlayer caster, ItemStack itemStack, Skill skillToCast); Now - to use a skill you would do: MyItemSingleton#cast(player, player#heldItemStack, letsSayFireball extending Skill). Skill would be a class having some methods such as execute(Entity, ItemStack), getCooldown(), isInterruptable(). What cast(...) would then do is grab @Capability of ItemStack assigned to passed ItemStack and set "currentlyCast" field to passed Skill, which would be only possible if it was null or currentlyCast.getCooldown() would be 0 or currentlyCast.isInterruptable() would be true (in which case you replace old cast). Now - since @Capability is serialized to ItemStack NBT - you would also need toNBT and fromNBT in your Skill class. This is not how I'd do it (since I have a LOT more extended casting on my own), but its a example. Hope it helped.
-
1. Item != ItemStack - Item is a SINGLETON describing what you are holding. - ItemStack is the thing that you are actually holding (it knows what Item it is, how many, and other data such as NBT). - Logically - you can't hold ANY data in Item, Only static or fields shared between all Items. - If you want item with data - you hold it in ItemStack's NBT. 2. Data held in NBT can be read directly (but like I mentioned - if you would use it per-tick and there is a lot to read, it is not very efficient). The other option is to read data once, deserialize it into @Capability and then operate on normal-java fields. Then when itemStack is saved back - you can serialize @Capability back to ItemStack's NBT. 3. If you would go after design you mentioned, you would need such (or similar) method: public boolean cast(EntityPlayer caster, ItemStack itemStack, Skill skillToCast); Now - to use a skill you would do: MyItemSingleton#cast(player, player#heldItemStack, letsSayFireball extending Skill). Skill would be a class having some methods such as execute(Entity, ItemStack), getCooldown(), isInterruptable(). What cast(...) would then do is grab @Capability of ItemStack assigned to passed ItemStack and set "currentlyCast" field to passed Skill, which would be only possible if it was null or currentlyCast.getCooldown() would be 0 or currentlyCast.isInterruptable() would be true (in which case you replace old cast). Now - since @Capability is serialized to ItemStack NBT - you would also need toNBT and fromNBT in your Skill class. This is not how I'd do it (since I have a LOT more extended casting on my own), but its a example. Hope it helped.
-
In both cases below you can use: http://mcforge.readthedocs.io/en/latest/datastorage/capabilities/ If cd should be per-entity (player): Assign integer to player, use it to define if player has cd on item. Note: You must take care of syncing if you want client to see value in ANY way. If cd should be per-itemstack - use either item's: 1. Only NBT (basically save cd in NBT, nothing else) 2. NBT + Capability - assign caps to ItemStack - once ItemStack is loaded (read NBT) it will create data-object which can hold integer cooldown. Then if item would be unloaded - that object can be serialized back to NBT. Second option is as efficient as it gets in per-item cases. Only difference between 1 and 2 is that you don't have to read NBT per-tick (which is kinda bad if you want to read A LOT of data, if you only read integer, it is not that bad). Note: ItemStack's NBT is auto-synced (you don't need syncing like in per-entity basis).
-
In both cases below you can use: http://mcforge.readthedocs.io/en/latest/datastorage/capabilities/ If cd should be per-entity (player): Assign integer to player, use it to define if player has cd on item. Note: You must take care of syncing if you want client to see value in ANY way. If cd should be per-itemstack - use either item's: 1. Only NBT (basically save cd in NBT, nothing else) 2. NBT + Capability - assign caps to ItemStack - once ItemStack is loaded (read NBT) it will create data-object which can hold integer cooldown. Then if item would be unloaded - that object can be serialized back to NBT. Second option is as efficient as it gets in per-item cases. Only difference between 1 and 2 is that you don't have to read NBT per-tick (which is kinda bad if you want to read A LOT of data, if you only read integer, it is not that bad). Note: ItemStack's NBT is auto-synced (you don't need syncing like in per-entity basis).
-
MinecraftServer#initiateShutdown(); // on 1.9 What version? Look for method that sets "this.serverRunning = false;".
-
MinecraftServer#initiateShutdown(); // on 1.9 What version? Look for method that sets "this.serverRunning = false;".
-
[1.8.9]Changing the display name of a user after log in
Ernio replied to theOriginalByte's topic in Modder Support
1. Wtf with your registering? Use MinecraftForge.EVENT_BUS only. 2. Is event called? 3. Does it reach you logging message? 4. Since you want client only mod (it seems) - use clientSideOnly = true in @Mod. 5. @SideOnly doesn't need to be everywhere when yo uare making Client side mod (read point 4). Also - you can apply it to classes, so no need to mark all methods in class. 6. I'd move registering events to preInit (i think it has no effect, I don't remember). 7. PlayerLoggedInEvent is server ONLY (server thread) event, it won't be called when e.g loggin onto dedicated server (but it will be called on SP - integrated one). -
[1.8.9]Changing the display name of a user after log in
Ernio replied to theOriginalByte's topic in Modder Support
1. Wtf with your registering? Use MinecraftForge.EVENT_BUS only. 2. Is event called? 3. Does it reach you logging message? 4. Since you want client only mod (it seems) - use clientSideOnly = true in @Mod. 5. @SideOnly doesn't need to be everywhere when yo uare making Client side mod (read point 4). Also - you can apply it to classes, so no need to mark all methods in class. 6. I'd move registering events to preInit (i think it has no effect, I don't remember). 7. PlayerLoggedInEvent is server ONLY (server thread) event, it won't be called when e.g loggin onto dedicated server (but it will be called on SP - integrated one). -
1. if (!world.isRemote) - setting blocks should happen on server. 2. Removing TE is handled internally, you don't need world.removeTileEntity(x, y, z); (I might be wrong coz 1.7.10 is ancient) 3. TileEntity will kill game after some time. Use normal blocks with schluded updates - lookup how plants grow. 4. You SHOULD REALLY start modding with 1.9+, 1.7.10 is so old now that you will get less and less support.
-
1. if (!world.isRemote) - setting blocks should happen on server. 2. Removing TE is handled internally, you don't need world.removeTileEntity(x, y, z); (I might be wrong coz 1.7.10 is ancient) 3. TileEntity will kill game after some time. Use normal blocks with schluded updates - lookup how plants grow. 4. You SHOULD REALLY start modding with 1.9+, 1.7.10 is so old now that you will get less and less support.
-
[1.8.9]Changing the display name of a user after log in
Ernio replied to theOriginalByte's topic in Modder Support
public void onNameFormat(NameFormat event) { event.setDisplayname("something"); } Call this to re-cache name. (It will call event for name). EntityPlayer#refreshDisplayName() -
[1.8.9]Changing the display name of a user after log in
Ernio replied to theOriginalByte's topic in Modder Support
public void onNameFormat(NameFormat event) { event.setDisplayname("something"); } Call this to re-cache name. (It will call event for name). EntityPlayer#refreshDisplayName() -
http://mcforge.readthedocs.io/en/latest/concepts/sides/ When in SP you are connected to integrated local server (basically multiplayer with one player). In SP you have access to your own MinecraftServer since it is the one you are running in background, thus this: MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance(); Will not be null (it will be your integrated server). Now when you connect to other server (LAN or dedic) you don't have server thread with you (thus your getMinecraftServerInstance() will be null). Read 1st link if you didn't catch the fact that there are 2 threads. Now - guts tell me that MinecraftServer#getMaxPlayerIdleMinutes() is for server-side only. This means you can't access it from client thread. To make it clear: - If you are on MP (outside server) you don't have server thread, thus you cannot access MinecraftServer#getMaxPlayerIdleMinutes(). - While you are on SP - you DO have your integrated server thread, BUT - while it is possible to access this value (you will be doing cross-thread calls), you generally shouldn't do so! Why? Exchanging data between threads directly is kind of bad design, because, as you should understand now - it is NOT universal (works only on SP, not on MP). How to deal with it? Unless "idleMinutes" are somehow sent to client internally (which I doubt) - only server thread can use this field, that is why you will need packets to share it with client. 1. Setup SimpleNetworkWrapper 2. Make packet which will send integer (only) 3. Make handler which will literally set some static field to integer received. 4. The packet can be sent from PlayerEvent.PlayerLoggedInEvent. 5. Use that integer in all of your rendering things. Links: SNW: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html Example: http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-x-1-8-customizing-packet-handling-with Thread safety: http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html Aside from that: (some recent quote that might be useful): Important thing are those so-called "scopes" - you shouldn't write code for one scope, but for all, and if you need such code, you use proxies. Note that it is not directly connected with current case.
-
http://mcforge.readthedocs.io/en/latest/concepts/sides/ When in SP you are connected to integrated local server (basically multiplayer with one player). In SP you have access to your own MinecraftServer since it is the one you are running in background, thus this: MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance(); Will not be null (it will be your integrated server). Now when you connect to other server (LAN or dedic) you don't have server thread with you (thus your getMinecraftServerInstance() will be null). Read 1st link if you didn't catch the fact that there are 2 threads. Now - guts tell me that MinecraftServer#getMaxPlayerIdleMinutes() is for server-side only. This means you can't access it from client thread. To make it clear: - If you are on MP (outside server) you don't have server thread, thus you cannot access MinecraftServer#getMaxPlayerIdleMinutes(). - While you are on SP - you DO have your integrated server thread, BUT - while it is possible to access this value (you will be doing cross-thread calls), you generally shouldn't do so! Why? Exchanging data between threads directly is kind of bad design, because, as you should understand now - it is NOT universal (works only on SP, not on MP). How to deal with it? Unless "idleMinutes" are somehow sent to client internally (which I doubt) - only server thread can use this field, that is why you will need packets to share it with client. 1. Setup SimpleNetworkWrapper 2. Make packet which will send integer (only) 3. Make handler which will literally set some static field to integer received. 4. The packet can be sent from PlayerEvent.PlayerLoggedInEvent. 5. Use that integer in all of your rendering things. Links: SNW: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html Example: http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-x-1-8-customizing-packet-handling-with Thread safety: http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html Aside from that: (some recent quote that might be useful): Important thing are those so-called "scopes" - you shouldn't write code for one scope, but for all, and if you need such code, you use proxies. Note that it is not directly connected with current case.
-
The singleotn you are talking about is Minecraft#thePlayer. Your player (you) is controlled by ClientPlayerController (not sure naming). To understand how the process works you can lookup how Minecraft handles input movement keys and sends those moves to server va packets.
-
The singleotn you are talking about is Minecraft#thePlayer. Your player (you) is controlled by ClientPlayerController (not sure naming). To understand how the process works you can lookup how Minecraft handles input movement keys and sends those moves to server va packets.
-
[1.8.9] [SOLVED] Custom log somehow gets wrong metadata
Ernio replied to Daeruin's topic in Modder Support
Blocks as x/y/z are saved in byte arrays to be cheap. TileEntity requires object and few references which cost memory, it also creates network overhead. If you are after such common blocks as wooden logs then no - TE is not a good tool for that. Use multiple blocks like vanilla does. -
[1.8.9] [SOLVED] Custom log somehow gets wrong metadata
Ernio replied to Daeruin's topic in Modder Support
Blocks as x/y/z are saved in byte arrays to be cheap. TileEntity requires object and few references which cost memory, it also creates network overhead. If you are after such common blocks as wooden logs then no - TE is not a good tool for that. Use multiple blocks like vanilla does. -
He means that we need code you say you tried to use to register events for us to be able to fix it for ya. No code = can't help. Proper way: MinecraftForge.EVENT_BUS.register(new EventClass()); Also - I am not sure if NBT accepts null values, maybe that was keys tho...
-
He means that we need code you say you tried to use to register events for us to be able to fix it for ya. No code = can't help. Proper way: MinecraftForge.EVENT_BUS.register(new EventClass()); Also - I am not sure if NBT accepts null values, maybe that was keys tho...
-
Well, how about actually having such variable? You are using name for variable that doesn't exist, what did you expect? Porgramming 101 (not even java).
-
Well, how about actually having such variable? You are using name for variable that doesn't exist, what did you expect? Porgramming 101 (not even java).
-
Dude, please don't treat words pouring on your like garbage. FOCUS I gave you a link - did you read and understand it? "Performing Side-Specific Operations" in particular? Then - did you actually googled tutorials on making such proxy? Did you try making it? Did you at least saw how the code look like (tutorials, open sources)? How are you planning on fixing your stuff if you don't listen to what I/We tell you? Before you read below, again read the link I gave you! http://mcforge.readthedocs.io/en/latest/concepts/sides/#performing-side-specific-operations If something is made with SideOnly it is ONLY viable to be referenced by other SideOnly thing. E.g: You can't reference client class from common/server code, in particular - you can't write "Minecraft#whatever" ANYWHERE outside client-only scope. Client-only scope are all other client-only things + mentioned Client Proxy which would be an extension to common proxy. If you want to reference anything that is reserved for particular side, you need proxy to do it. So instead of referencing given thing from your common code (e.g some Entity class which is common), you make a call to e.g: MyProxy#method(). Say that you want client-only stuff to be referenced - that example "method" will be abstract for common proxy, empty for server proxy (since server should not act upon it), and filled with client-only code on client proxy. This is precisely what you need to operate on Particles which are CLIENT ONLY. That said - since referencing scoped things requires you to be in that things scope - it is logical that if you want to extend a sided class (which referencing definition contains) - you also need to mark that class as sided and also reference it via proxy. Any questions?
-
Dude, please don't treat words pouring on your like garbage. FOCUS I gave you a link - did you read and understand it? "Performing Side-Specific Operations" in particular? Then - did you actually googled tutorials on making such proxy? Did you try making it? Did you at least saw how the code look like (tutorials, open sources)? How are you planning on fixing your stuff if you don't listen to what I/We tell you? Before you read below, again read the link I gave you! http://mcforge.readthedocs.io/en/latest/concepts/sides/#performing-side-specific-operations If something is made with SideOnly it is ONLY viable to be referenced by other SideOnly thing. E.g: You can't reference client class from common/server code, in particular - you can't write "Minecraft#whatever" ANYWHERE outside client-only scope. Client-only scope are all other client-only things + mentioned Client Proxy which would be an extension to common proxy. If you want to reference anything that is reserved for particular side, you need proxy to do it. So instead of referencing given thing from your common code (e.g some Entity class which is common), you make a call to e.g: MyProxy#method(). Say that you want client-only stuff to be referenced - that example "method" will be abstract for common proxy, empty for server proxy (since server should not act upon it), and filled with client-only code on client proxy. This is precisely what you need to operate on Particles which are CLIENT ONLY. That said - since referencing scoped things requires you to be in that things scope - it is logical that if you want to extend a sided class (which referencing definition contains) - you also need to mark that class as sided and also reference it via proxy. Any questions?
-
Usually I am not rude (I am still not, as of now), but what if I told you that I am writing 3rd post in this thread with SAME content. What do you not understand? Google on how to make proxy, post code, we will fix it if needed.