-
Posts
2638 -
Joined
-
Last visited
-
Days Won
4
Everything posted by Ernio
-
Okay, so this is getting pretty nice. The vertex format is actually short code for: POSITION: #pos(x,y,z) TEX: #tex(u,v) COLOR: #color(r,g,b,a) Whenever you want to apply one of those, you need to use proper vertex format (e.g: POSITION_TEX for pos and tex). Then you close vertex with #endVertex(). Anyway, that was easy (I guess I just was lazy). So where can I read about those types? I am GL noob in terms of conventions. Everything I know i learned from scratch (a lot actually).
-
First of all - loving 1.8.9. Back to the case - I want to know every trick regarding WorldRenderer. In particular: * mode and format params in "#begin" - what and when are they used? * Is there some one-time color-setting method or from now on everything should be kinda like this: #pos(x,y,z).endVertex(); #pos(x,y,z).color(r,g,b,a).endVertex(); What other methods are useful, yeah - I could read source but vertex formats are the worst.
-
[1.8.8] Updating a Packet System from 1.6.1, need help
Ernio replied to Boyde712's topic in Modder Support
As said - the code you posted is bad in more than just sync way. Difference between 1.6 and 1.8.9 is like having shovel and a damn bulldozer - sure they do same thing, but hell - one is thousands years more advanced and more efficiend than other. Aside from that - the code from that old mod is simply bad (if you read 1st 2 links I gave you see for e.g that you are using "Minecraft.class" which is client only thing in Entity code). I wouldn't be surprised if it was crashing back then (tho back then there was less safety checks). What I am saying - yeah, get the idea of mod from old one, write one as new project. I am not sure if you know how data is stored in memory. Yeah, sure you can serialize everything into a String like (example) "3424,human,8,Joe the Killer" and then decode it, but why the hell you'd do that... Any data is just bytes saved (in case of packets) in Buffer. You simply write and read values. Read implementation link. -
[1.8.8] Updating a Packet System from 1.6.1, need help
Ernio replied to Boyde712's topic in Modder Support
Okay, I am but a fish in a sea, but hell - just write everything from scratch. This code is not only outdated, but bad. You are referencing client only classes in common code without proxies. You have tons of bad practices. Whole old code will only mess up your thinking. I am posting this more and more often (obviously can be written better): http://www.minecraftforge.net/forum/index.php/topic,33918.msg178740.html#msg178740 Very important: http://www.minecraftforge.net/forum/index.php/topic,22764.0.html SNW: Template: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html Implementation: http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-2-customizing-packet-handling-with You REALLY should start from total scratch. System does everything for you, none of that Buffers you do is neccesary. Points of interest: Everything (almost) regarding built-in sync code (meaning "not SNW" stuff): http://www.minecraftforge.net/forum/index.php/topic,36213.msg190583.html#msg190583 + There is PlayerEvent.StartTracking and EntityTracker - those 2 are VERY important when designing dynamic synchronizations (top notch). Note: After understanding system, I reccomend designing abstracition layer before even starting writing rest of mod. Example of what I mean is in 4th link in post (Implementation). Other useful shit: Recommend reading some of TheGreyGhost pages on how MC works. -
Well, you have your buttons. You simply send packet to server when button is pressed. Packet will contain x/y/z and data you want to send. On server you know who is sending packet (from MessageContext), then you get world of player and get TileEntity is x/y/z. Update your data in server's TileEntity (1st always check if it is "legal", e.g if player is actually near TE and stuff). After server's data is updated - send update packets back to all clients that need it (again with x/y/z system). Note: That is if you are using TE + Gui (client). Addition: If your TileEntity uses Container (has slots), the server knows when player has Container opened (you know, server's one corresponds with client's one). If your container is bound to TileEntity (has reference when opened) you don't need to send x/y/z in packet. That is just another way to get TE on server (not really popular), but 1st one (x/y/z) is better.
-
Bytecode (ASM). Only way to alter this on such "level". There is good info - you need only one insertion which is relatively easy, bad info - ASM is still pretty fkd up. Are you sure you cannot work with what is public? I mean... private methods must be called by methods inside ItemRenderer itself, so why not just override those public ones which use private ones and make them use your code? (not in IDE now).
-
[SOLVED] [1.8.9] java.lang.ClassNotFoundException SideOnly Client Code
Ernio replied to Zetal's topic in Modder Support
If you'd post whole code (event class) and crash log. I'd be so happy. -
In simple words: On screen you make a "border" from some left-right and top-bottom. Background is creatd by bunch of textures that use some "random" blocks and you start drawing them on this "bordered" area using repeating pattern. (Not qute what I would call it - it actually uses some of Biome mechanics, I don't really remember right now). You render as many background blocks as possible and those which are standing out of bordered area you cover with .png frame-like image. Rest is simple dragging-coordinate system you can find in most scrollable guis. As to understanding it - you can't without taking a piece of whatever gives you power to imagine and compute (paper, paint, brain maybe) and thinking the idea thorough. Seriosuly, I could understand anyone not being able to write it themselves, but you have a code - LOOK at it, analyse it. And I am not being rude, that is a simple and useful truth.
-
You are making your life harder but whatever. I can only suggest this approach: Setup normal dev environment. Create 2 mods - server and client one. Proxify EVERYTHING - Client mod will fire everything it has in ClientProxy, Server will setup everything (databases, engines) in ServerProxy. Write 2 different mods. that will somehow correspond to each other. Why 2 mods, one workspace - well, easier to maintain - you can launch Dedic and Client at once and connect to test it. Now where are main problems: - You still need a lot of common code, since most stuff needs to be handled on both sides (e.g you send quest data, you recreate object on client, thus you need all quest classes). - Client will NOT work on SP - since you don't have server's code (integrated), you need to take care of your shit when playing on SP (when using some client-event, you need to make if(sp) and then proceed with acting). - Packets are "the shit" - your problem is with implementations that Forge alredy provides. SimpleNetworkWrapper and actually whole system requires you to have IMessage and MessageHandler. What you want to do is to make: Dedic only have IMessage and Client only have MessageHandler or other way around. Problem is actually that when you receive message, it will be recreated and passed to MessageHandler (that's why packts need empty constructor). How to pass this? Well, you can't (if you want to use forge). You will need sided implementation of packets. Next: SimpleNetworkWrapper allows you to register packets in PACKET<->HANDLER manner. You want to have INCOMING<->OUTGOING. To resolve this you need to either write your own implementations (of networking) or "inject" your packets without pairing (meaning you register PACKET but not HANDLER). You can do this like this: SimpleIndexedCodec codec = ReflectionHelper.getPrivateValue(SimpleNetworkWrapper.class, this.getInstance(), "packetCodec"); // instance is ofc of your SNW codec.addDiscriminator(packetId, message); This way you can have OUTGOING packet with some ID. Now on receiving side you need to have both HANDLER and PACKET to receive (you also need to have same ID as incoming packet). That you register like any other packet. Seriously, don't do that, just proxify your code and make one mod. Oh and mark EVERYTHING (that is not common code) in your code with SideOnly: http://www.minecraftforge.net/forum/index.php/topic,22764.0.html EDIT Additional shit: if you started modding/this is your first. DON'T do that. Without proper understanding of MC, you will most likely have a lot of problems.
-
I'd like to make a mod that handles client stuff for modded client, and a mod that handles server stuff (including quest system and database system) for the modded server : in itself, it is the same mod but separated in two versions: one for the client and one for the server. The thing that I would like to achieve is to separate the tasks so that the dedicated server hasn't the client code and the modded client haven't the server part. The client shouldn't have the packet handling that the dedicated server do. The server aswell shouldn't have the client handling (like input or gui rendering) that is reserved for clients. Hell, well you gave your explanation, my prev post is quite irrelevand aside from fact that modding has been made SIDE-UNIVERSAL. Do tell - do you want to achieve what you want to achieve because: 1. Privatization of code (e.g coding for private server). 2. Lowering size of files for players to download. 3. Don't know why and you think that it will be better, when in reality - it really won't. 4. When you say "database" you actually mean embedded DB engine that you think is useless for clients, thus you go back to point 2. with addition of "useless code".
-
I am not sure what exacly you want to know because 1st you claim that you found good explanation for sides and then you seem to think that server and client mod is something different. Well, since about 1.2 (around, I don't remember) modding has been redesigned to be compiled as one universal mod for both client and server. Before going further: Client = client.jar Dedic = dedicated.jar client-side = logical server side server-side = logical server side When: 1. Dedic is running - it runs server-side. 2. Client it running - it runs client-side and: 2.1. Nothing else on MP (server-side is handled by Dedic). 2.2. server-side on SP (integrated server-side) 2.3. When in LAN - one client will run integrated server, other clients will connect to LAN server like to Dedic. Having Mod written as an universal jar - it doesn't matter where you run it. Data should be always handled on server-side, thus if you have any database it will always be loaded on server-side, which is Dedic OR integrated server. Packets are still being "sent", even when you are on SP connected to your integrated server.
-
So, do you have a GUI or a GUI+Container (GuiContainer.class)? There is a "nice" abstraction layer that allows you to send integer values when player opens container (gui). This is specially designed to send progress bars to clients that open containers. Will your "fuel status" fit into integer? If not - you need packets that will be sent to player that opens gui (you can literally send apcket with data to player (and update his opened container) whenever he opens it and then re-update him when he has it opened. To do that - you want what I linked earlier. If yes - have look at those methods: (container) On client: @Override @SideOnly(Side.CLIENT) public void updateProgressBar(int id, int data) { // fired on client. Id is of the field you want to update, data is obvioudly integer I was talking about. } On server: for (int i = 0; i < this.crafters.size(); ++i) // this = container { ICrafting iCrafting = (ICrafting) this.crafters.get(i); // crafters are "entites" (players) that opened this container. iCrafting.sendProgressBarUpdate(this, id, data); // send update with some "id" and some "data". } This one might be usefule, but not really: public void detectAndSendChanges() To actually learn how it works - you need to readup some vanilla code. Nasty stuff But I receommend reading callbacks. Point of interest: There is an "usefule" abstraction layer in TileEntity: getField setFiled Those can be used within methods in container class to make something (both use id/integer system). If you have problems with anything, post code and errors. Most can be resolved on your own by experimenting. (I gave you tools).
-
1. Regarding SideOnly: http://www.minecraftforge.net/forum/index.php/topic,22764.0.html 2. Do you actually need those values on client? 2.1. When? In container, rendered on block, on interaction? Anyway - there are few ways to approach this. You will need (if not here, then in future) packets: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html You need to send value from server to client and update TileEntity at x/y/z. Packet wil contain x/y/z and new value. If you need values in e.g Gui there is other way. That later.
-
[1.8.9] Rendering an Entity that implements IProjectile?
Ernio replied to paradoxbomb's topic in Modder Support
I STRONGLY recommend looking into vanilla renderers. 1. Google Entity rendering. What you are looking for is "how to register renderer". 2. Copy code from RenderSnowball - it's a goood start. 3. Have fun with examples vanilla gives. Points of interest: Minecraft.getMinecraft().getRenderManager(); RenderingRegistry.registerEntityRenderingHandler(MyEntity.class, new RenderMyEntity()); Rendering goes in init(). -
[1.8] Custom p-plate does not see POWERED state on client
Ernio replied to jeffryfisher's topic in Modder Support
Without overthinking - you have too many states. I mean. 0-15 for your signal, and where goes the boolean POWERED? Lookup BlockPressurePlateWeighted which uses POWER to measure power strengh from 0-15. It uses 0 value as replacement for POWERED=false. This is probably why client can't decode it. Idk why server says otherwise. -
I don't think there is any easier/nicer way to do it. You most certainly want to use FontRenderer and to do that you need something to draw on - plane. GL11.glTranslatef((float) (x - Minecraft#getRenderManager().viewerPosX), (float) (y - Minecraft#getRenderManager().viewerPosYt), (float) (z - Minecraft#getRenderManager().viewerPosZ)); That's how you get x/y/z. You need few rotations and little translation to fit your plane (block walls) and draw using: Tessellator tess = Tessellator.getInstance(); WorldRenderer wr = tess.getWorldRenderer(); wr.addVertex ... and next, and next, and next. and then draw sting with FontRenderer.
-
Particles are client side. You need to call code on client or send packet from server to client saying to do it.
-
http://greyminecraftcoder.blogspot.com.au/2013/08/the-tessellator.html You can draw string onto tess-drawn box in x/y/z. For real examples you could look how entity names are rendered above head.
-
If this is your whole code, then you are doing nothing to make entity face player. @Override onUpdate() method. Since rotation will be always the same (facing player), you can do it on both client and server. Rotate entity every tick to face player (simply change rotation or use method like setRotationAndAngles I think, idk naming). Now harder part: You need to save reference to player in NBT. In write/readNBT you need to store an UUID of player. UUID is saved in 128bits, so 2 longs. Use those to save/load UUID: uuid.getMostSignificantBits() / uuid.getLeastSignificantBits() / new UUID(least, most). Now that you have persistant UUID - you need to convert it to EntityPlayer reference. To do that - on server you will use ((WorldServer) world).getPlayerByUUID(uuid) (not sure naming). When you have converted UUID to EntityPlayerMP (on server) AND if that was possible (player can be offline, so you probably want to retry converting whenever PlayerLoggedInEvent occurs for all "your" entities OR every few ticks in each entity's onUpdate() method), you have 2 options: 1. Rotate entity from server and make vanilla do adjustments on client. Use setPositionAndUpdate(); every few ticks (3-10?). 2. Rotate on both sides (mentioned at start of post) without using vanilla packets. You can do this by sending reference to player via SimpleNetworkWrapper or DataWatcher (send player.entityId()). Then retrieve EntityPlayerSP on client reference from world.getEntityById(idSent). In this case you don't have to use setPositionAndUpdate(), but can operate directly on entity's fields.
-
I don't think there is "insert line of code" hook to look for in this case. You will need some heavy replacements to renderer. I strongly suggest looking up ANY shaders mod source. I doubt this is doable without at least some ASM or lot of instance replacements. I also doubt that this was helpful.
-
[1.8.9] Multiblocks structures and OBJ models: is it possible?
Ernio replied to ZeroNoRyouki's topic in Modder Support
Not my profession for a long time now, but in past I think I stumbled upon something like this. Design was pretty much: Place one block (center) which renders whole thing and fill air around with special invisible blocks. I am unsure if it was in Entity or Block class, but I remember there is a method that allows you to change rendering distance hit-box (meaning you start seeing (render) block before you actually see central-block). But as said - this might have been method for Entity (that was like a year ago, idk). Note that you will need some pretty big recursion to break such a structure. Way I would do it is to make that one of those structures (when trying to place them) cannot ever be in 1-block contact with other. Then (since "invisible block" is of your design) you can NOT care about checking whether your recursion is removing structure wanted or passed onto another one next to it, and just make tail call. Just an idea. Hope anything here is helpful, but you got to do the actual research (or wait for someone else). -
Basically - paintball. Way I see it, you would need to make some universal TileEntity which would be able to mimic (render) block that is at its coords and use data saved in TE (colorization values) to manipulate colors of faces. Problem is - every damn block can have ANY-damn face (model). Even stupid dirt block can be made to be e.g stairs or some other sphere-like shit (by changing its .json file). This leads me to belive that the only way to achieve SAFE for use block-painting is to make some kind of special "painting block". Eventually you could alter other blocks, but as said - any block can have any model so I don't think it will be easy to do this for any side of block (you could maybe paint all quads facing some direction, but then BAM - any block can also use OTHER model than .json, and then BAM - it can even be .obj). What is alredy done (as mod) is painting mod that allows you to "paint" whole block of wood or wool to other color, but that one uses block replacement (metadata of both wool and wood are literally "colors". If you were to colorize WHOLE block (no matter what format), that would be infinitely easier, just call GL to alter rendering. But that has to be done in places beyond reach of the mortals, meaning - ASM hook. (I don't think there is a way to manipulate other ppls/vanilla models without having to write code for every possible block). Therefore I conclude - Without some hi-tech coding, rendering redesign, probably ASM and other shit - there is no way to do this NICELY (universal). Well... that's VERY pessimistic. I guess I had a bad day
-
Yup.
-
Everything works fine as long as modders followed good modding practices and didn't fuck with data, especially manipulating things per-ID (where per-instance is preferred since 1.7). This question is too broad to be answered without actually testing it, so my answer is: Update to latest and work with that. Even if there are errors - they can be fixed with Events and if not with events - you can manipulate world data on loading.
-
I had my fun with hitboxes and EVERYTHING worked. Since right now I have no clue what might be wrong (unless your event is somehow not called on server), I can only note few things: 1. ObfuscationReflectionHelper - it does whole reflection part for you. 2. When using reflection - get field/method once. Point of interest: Java 7 - MethodHandle (and yes, don't bother with java 6 compatibility, users should update their shit, seriously). 3. TickEvents have 2 phases, pick one (code will be ran twice otherwise) - if (event.phase == Phase.START). 4. It is entirely possible (and should be done that way) to setSize once, not every tick, but I understand this is a test code. 5. Finally - look for solution in PlayerAPI, more exact - SmartMoving mod. It allows players to crawl, so basically what you want.