-
Posts
2638 -
Joined
-
Last visited
-
Days Won
4
Everything posted by Ernio
-
GuiHandler methods do not require x/y/z. Pulled from other thread: Aditionally I must add: The "packet" that goes from server to client (when container is found) simply containes data: id, x, y, z; and while id is crucial to open proper gui on clinet - x/y/z are never used by internal code - which means that it is literally: "you have 3 ints here, use them if you want, but they can all be just random numbers."
-
Please learn more Java. Making "new Cow" != "spawn Cow". You need to call World#spawnEntityInWorld. Clean up useless code, learn to code properly.
-
You code has logical mistakes: 1st things 1st - why does "FindWand" starts with capital :C Back to case: Minecraft class is @SideOnly(Side.CLIENT) - therefore your item code will crash on dedicated.jar startup. I am refering to this: Minecraft.getMinecraft().objectMouseOver.entityHit - this is for client-only usage and only via proxy code. This is technical mistake. Based on this mistake you make next one: You are using Client-sided code from server logical thread (!world.isRemote). And calling data-changing methods from client logical side (data can be only manipulated on server thread) - I am talking about applying damage. Some reading: http://www.minecraftforge.net/forum/index.php/topic,33918.msg178740.html#msg178740 http://www.minecraftforge.net/forum/index.php/topic,22764.0.html Now: In common code (Item's methods) you can perform proxy calls that can use Minecraft class - but that won't give you shit, because you don't need and can't do anything from client logical thread (only server can actually edit real data, client only displays it). What you need is to inside (!world.isRemote) call a method that will obtain target entity using server logical code. To do that you could lookup e.g Arrow's code (for hitting targets) or you can almost literally copy client's method that does that, but do it on server thread.
-
[1.8.9] [Forge 11.15.1.1722] Having trouble with a GUI regarding block click
Ernio replied to Kel's topic in Modder Support
i am refering to Block's code - it is not called because it is not a real method: public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, int x, int y, int z) Go to your IDE preferences and set it to format your code on saving (Eclipse has it, idk about other). If you can't track mistakes like that (seems like part of copy-pasted code) then there is nothing bad in making IDE track them for you. Anyway - yeah, that is the main reason why nothing works. Also side note - your code is badly designed - no problems in that, but just pointing that out - get some more java exp and rewrite it (e.g: too many "ClientSideOnly" classes and other - thay can be packed together). -
1st of all - when code is used a lot, you make helpers for it: public static AAExtendedPlayer get(EntityPlayer player) { return player.getExtendedProperties(AAExtendedPlayer.EEPName); } And now you just call AAExtendedPlayer.get(player); 2nd: Like "get" is totally different than "set", same rule applies to "register"! "register" != "set". Again - make helper method in AAExtendedPlayer: public void copy(AAExtendedPlayer ieep) { this.mana = ieep.getMana(); this.soething = ieep.getSomething(); ... } Now: @SubscribeEvent public void persistMana(PlayerEvent.Clone event) { EntityPlayer playerOrig = event.original; EntityPlayer playerNew = event.entityPlayer; AAExtendedPlaye.get(playerNew).copy(AAExtendedPlaye.get(playerOrig)); } Registration should happen almost always only in entity's construction event. New player is created -> IEEP is registered -> old data is copied to new IEEP -> old entity is discarded -> new one is spawned -> JoinedWorldEvent calls sync methods and updates stuff from new IEEP.
-
[1.8.9] [Forge 11.15.1.1722] Having trouble with a GUI regarding block click
Ernio replied to Kel's topic in Modder Support
And this is why Java has @Override. You are not overriding "real" method. Then 2nd mistake: IGuiHandler works this way: (when you call player.openGUI) On Client: * Calls client method and opens Gui or null. On Server: * Calls server method and IF that method returns Container instance then: ** Container is opened on server. ** Packet is sent to client with data: id, x, y, z. ** Client calls client method and opens client Gui. If the server method will return NULL - nothing happends (on client too). Following that: When you call player.openGui(...) in onBlockActivated - call it on !world.isRemote! (otherwise you are opening gui twice which if not harmful - is still useless). -
1. Guis are client side only. It is safe to mark them with @SideOnly(Side.CLIENT). That said: ItemSkillChecker#onItemRightClick has logical mistake: if(!worldIn.isRemote) { // call on server Runecraft.proxy.openGui(); // call to proxy which on dedic does nothing and on client opens GUI. } Problem: while this will "kinda" work on SP (SP is Client.jar with integrated server), it will NOT work on dedicated MP. This might be source of problem since you are opening gui from server thread. Note: Move your Gui opening to GuiHandler - it is perfectly safe to return null on server and GuiScreen on client while calling player.openGui(...) 2. Well, I was expecting something more, but can't find shit. If error persists - resetup your workspace with latest forge and move over your sources. Cleanest way to go about it.
-
I can't tell you more without seeing all code, from registration and packet to calls and handling. Also your IEEP can be messed up.
-
I don't think I can help you, I'd need other classes (git?) to test it myself, but I can say that there is no such problem in my 1.8.9 project. Try removing everything from your methods and just leave them with super call. You either do some weird call somewhere else (doubt that) or your OS/workspace is somewhat messed up. Are you using some linux or mac by any chance?
-
You kinda picked to send "Signed" one and then you apply data onto #thePlayer. Signed case (can also be used for non-players): @Override public IMessage onMessage(MessageSyncManaRegen message, MessageContext ctx) { Entity e = Main.proxy.getClientWorld().getEntityByID(message.entityId); if (e instanceof EntityPlayer) { AAExtendedPlayer props = (AExtendedPlayer) ((EntityPlayer) e).getExtendedProperties(AAExtendedPlayer.EEPName); props.addMana(new Mana(ManaType.W, message.w)); props.addMana(new Mana(ManaType.U, message.u)); props.addMana(new Mana(ManaType.B, message.b)); props.addMana(new Mana(ManaType.G, message.g)); props.addMana(new Mana(ManaType.R, message.r)); } return null; } Unsigned packet (remove "entityId"): @Override public IMessage onMessage(MessageSyncManaRegen message, MessageContext ctx) { AAExtendedPlayer props = (AExtendedPlayer) (Main.proxy.getClientPlayer()).getExtendedProperties(AAExtendedPlayer.EEPName); props.addMana(new Mana(ManaType.W, message.w)); props.addMana(new Mana(ManaType.U, message.u)); props.addMana(new Mana(ManaType.B, message.b)); props.addMana(new Mana(ManaType.G, message.g)); props.addMana(new Mana(ManaType.R, message.r)); return null; } Now - the methods should be placed in your client proxy and should return Minecraft.getMinecrraft()#thePlayer or #theWorld.
-
You messed up. Code please.
-
Look at FakePlayer class. It tells you how to make instance of player. Note: FakePlayer is not designed to be spawned as entity in world. It is supposed to be used as server-side "acting" class on which you can (somehow) operate on data. Note 2: Consider making "special" player based on EntityLivingBase. Extending Player classes should happen only if you REALLy need them to be actual players, but then again - it is not as easy as jsut spawning them - fake-ish player entities don't work well with system. I can't really help without DIRECT questions. I was working on player-like NPCs like thrice (+currently) and I always ended up with extending EntityLivingBase. It's cleaner that way and it doesn't mess with internal systems.
-
How well are you with Java? Because that shit is harder than one would think it is. A lot of problems can come from it. Anyway - have actually tried ANYTHING?
-
If you go with TE, You Make TileEntity implements ITickable, you amke field int count. You make an if (count % 1000 ==0) in update(). Now you run your code once per 1000 ticks. If you don't want to use TileEntity - you can use this.worldObj.scheduleUpdate(pos, blockIn, delay); You simply make a call and after "delay" it will call Block#updateTick. In Block#updateTick you can re-call worldObj.scheduleUpdate and basically make infinite 1000tick-loop.
-
First of all: This is totally true - make TE with integer counter, fire code every if (count % 1000 == 0). The Block#tickRate method is actually never called by any internal MC system. It exists in Block class as a design choice (kind of an abstraction). Lookup its callbacks. Anyway - what you can do is use World#schedule(Block)Update on given blockpos and then when update is fired you can reschedule one after next 1000 ticks.
-
public class GuiTest extends GuiScreen { private GuiTextField idTextField; @Override public void initGui() { super.initGui(); this.idTextField = new GuiTextField(1, this.fontRendererObj, 40, 40, this.width - 80, 20); this.idTextField.setEnableBackgroundDrawing(true); this.idTextField.setMaxStringLength(400); this.idTextField.setVisible(true); this.idTextField.setEnabled(true); } @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { super.drawScreen(mouseX, mouseY, partialTicks); this.idTextField.drawTextBox(); } @Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { super.mouseClicked(mouseX, mouseY, mouseButton); this.idTextField.mouseClicked(mouseX, mouseX, mouseButton); } @Override protected void keyTyped(char typedChar, int keyCode) throws IOException { super.keyTyped(typedChar, keyCode); this.idTextField.textboxKeyTyped(typedChar, keyCode); } } This should do it. If you want more use-cases look at textBox's code (e.g: setCanLoseFocus() or setFocused()).
-
This looks outdated (unless you are yourself outdated). First: Please - use 1.8.9 If you do/will: (example) public class MyCommand extends CommandBase { @Override public String getCommandName() { return "mycommand"; } @Override public void processCommand(ICommandSender ics, String[] args) throws CommandException {} } public static void init(FMLServerStartingEvent event) { event.registerServerCommand(new MyCommand()); }
-
Bro, do you even reference? I can honestly say, while I've seen a lot of Java mistakes here, this one is genuinely new. It should be: newPlayer.setIEEP(oldPlayer.getIEEP()); As to second part: The logic is fairly simple: Each server and cleint holds its own EntityPlayer (call them: MP and SP). Each of those players have their own IEEPs assigned (it's even possible to have one-sided IEEP). Now - updates should ALWAYS travel from server to client one. Most of packets that way will look like: Server changes value -> Packet with update is sent to client. You can split them into 2 groups: 1. Direct packet to owner of data (you send data from MP IEEP to SP IEEP). * Packet contains ONLY data. * Receiving client reads data and applies it derectly onto Minecraft#thePlayer (himself). 2. "Signed" packet to few clients (you send data from MP IEEP to multiple SP receivers). * Packet contains data AND entityID. * Receiving client reads "entityID", gets entity from its client world and update that entity's data. How +/- it should look with your mana: 1. Click Key. 2. Send packet to server (can be empty or with some Id of key). 3. Senrver knows who sent data -> do security checks. 4. Change value in MP IEEP ---(Assume you have setter method)---> MP IEEP sends update packet to client or clients (like described above). 5. Done.
-
People should really start reading vanilla code. For future: when extending something, actually read its code. http://www.minecraftforge.net/forum/index.php/topic,31297.0.html Should help. EDIT - HOLD ON! Why are you using GuiContainer? My answer above is about placement of BG and slots in GuiContainer that actually corresponds with Container class. If you don't have Container for your Gui, you most likely don't need it - use (extend) GuiScreen!
-
[1.7.10] Having issues with getting the closest player.
Ernio replied to thatsimplekid's topic in Modder Support
Umm, how can distance be negative? Args are: x, y, z, distanceOfSearch. Probably your issue. -
You could use World#getClosestPlayer, but that won't work since you need to ignore yourself. Look at that method, do exacly same but ignore your own EntityPlayer.
-
[1.8.9] Detect when client connects to server [solved]
Ernio replied to JoelGodOfWar's topic in Modder Support
Did you register you event? Are you trying to catch connecting on server or client only? -
As to your question: "Can I hook up the very first function that receives data ?" What do you mean by that? Intercepting packets? As to personal experience and idea - this is totally possible and was alredy made in past (idk if updated now). If I remember correctly it was a mumble-based mod that connected world, players to mumble engine and you could talk in-game (yeah, with all that distance stuff). Why Mumble - it is open source and VERY GOOD at compressing voice, which when you have server with a lot of players is like SUPER important. As to personal experience - since mod mentioned (at that time) required mumble client and server somewhere running in background (it was more cross-application), my friend and I wanted to rewrite whole engine and place it into MC client mod and MC server mod. Long story short - had something working but there was so many unaccounted for errors that project slipped into abyss. Well, a lot of useless talking - but yeah, I do recommend using mumble voice engine.
-
When I was searching yesterday I don't know why I didn't catch this: https://www.opengl.org/sdk/docs/man2/xhtml/glBegin.xml Only thing questionable is why internal methods are public, and if they are not internal - how do they allow different outcome than ones provided (e.g: those in my prev post), but whatever. Oh and eventually - how do you use lightmap (yeah, there is a method now)?