Problèmes avec un véhicule
-
Si le bateau ne bouge pas, c’est surement que les variable “forwardInputDown”, “leftInputDown” , … sont toujours à false (coté serveur) donc regarde si la fonction “updateInputs” est bien appelée. Si elle est bien appelée, il faut surement envoyer les info au serveur je ne sait pas si il y as une fonction pour faire ça mais sinon, il faut surement passer par un packet. (je ne m’y connais pas trop en entité donc c’est peut-être pas ça le problème mais c’est ce qui me parait le plus probable)
-
Salut
Désolé pour le temps de la réponse, j’essayait d’ajouter un inventaire au traîneau, qui veut pas s’ouvrir.Bref. J’avais vu un packet dans la classe de l’entité, je suis allé à l’intérieur et j’ai vu qu’il servait aux mouvements. Je m’étais dit que ça pouvait l’utiliser. On dirait bien que non. Je vais en faire un autre et je reviens.
Comme dit ci-dessus, j’ai essayer d’ajouter un inventaire (donc un gui, un container et un inventaire) à mon traîneau, mais il veut pas s’ouvrir. J’y ai passé toute l’après-midi à lire le tuto, le comprendre et tout. J’ai également dû “bidouiller” quelques trucs pour l’adapter à mon traîneau vu que le tuto à été créer pour un block.
Voici les classes :
Ce qui sert à ouvrir le gui dans la classe de l’entité :else if (!this.worldObj.isRemote && player.isSneaking() && this.outOfControlTicks < 60.0F) { System.out.println("must open GUI"); player.openGui(ThisisChristmas.instance, 0, this.worldObj, (int)this.posX, (int)this.posY, (int)this.posZ); }Mon GuiHandler
package This_is_Christmas; import This_is_Christmas.Entity.EntitySleigh; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; import net.minecraftforge.fml.common.network.IGuiHandler; public class GuiHandlerChristmas implements IGuiHandler { @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { if(ID == 0) { System.out.println("must call container"); EntitySleigh sleigh = new EntitySleigh(world); InventorySleigh invSleigh = new InventorySleigh(world); return new ContainerSleigh(player.inventory, invSleigh, sleigh, player); } return null; } @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { if(ID == 0) { System.out.println("must call GUI"); EntitySleigh sleigh = new EntitySleigh(world); InventorySleigh invSleigh = new InventorySleigh(world); return new GuiSleigh(player.inventory, invSleigh, sleigh, player); } return null; } }Mon GUI :
package This_is_Christmas; import org.lwjgl.opengl.GL11; import This_is_Christmas.Entity.EntitySleigh; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.util.ResourceLocation; public class GuiSleigh extends GuiContainer{ private static final ResourceLocation texture = new ResourceLocation(ThisisChristmas.MODID + ":" + "textures/gui/inventorySleigh"); private IInventory playerInv; private EntitySleigh theSleigh; private InventorySleigh sleighInventory; public GuiSleigh(InventoryPlayer inventory, InventorySleigh invSleigh, EntitySleigh sleigh, EntityPlayer player) { super(new ContainerSleigh(inventory, invSleigh, sleigh, player)); System.out.println("GUI has been call"); this.theSleigh = sleigh; this.playerInv = inventory; this.sleighInventory = invSleigh; this.allowUserInput = false; this.xSize = 176; this.ySize = 222; System.out.println("GUI has been initialize"); } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { System.out.println("drawGuiContainerBackgroundLayer has been call"); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); this.mc.getTextureManager().bindTexture(texture); int k = (this.width - this.xSize) / 2; int l = (this.height - this.ySize) / 2; this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize); System.out.println("GUI has been draw"); } protected void drawGuiContainerForegroundLayer(int x, int y) { String invSleighName = this.sleighInventory.hasCustomName() ? this.sleighInventory.getName() : I18n.format(this.sleighInventory.getName()); this.fontRendererObj.drawStringWithShadow(invSleighName, (this.xSize - this.fontRendererObj.getStringWidth(invSleighName)) / 2, 6, 0); String invPlayerName = this.playerInv.hasCustomName() ? this.playerInv.getName() : I18n.format(this.playerInv.getName()); this.fontRendererObj.drawStringWithShadow(invPlayerName, (this.xSize - this.fontRendererObj.getStringWidth(invPlayerName)) / 2, this.ySize - 96, 0); } }Mon Container :
package This_is_Christmas; import This_is_Christmas.Entity.EntitySleigh; import net.minecraft.entity.passive.EntityHorse; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; public class ContainerSleigh extends Container{ private InventorySleigh sleighInventory; private EntitySleigh theSleigh; public ContainerSleigh(IInventory playerInventory, final InventorySleigh sleighInventoryIn, final EntitySleigh sleigh, EntityPlayer player) { System.out.println("Container has been call"); sleighInventory = sleighInventoryIn; theSleigh = sleigh; sleighInventoryIn.openInventory(player); for(int i=0; i < 3; i++) { for(int j = 0; j < 9; j++) { this.addSlotToContainer(new Slot(sleighInventoryIn, j + i * 9, 8 + j * 18, 18 + i * 18)); } } this.bindPlayerInventory(player.inventory); } @Override public boolean canInteractWith(EntityPlayer playerIn) { return this.sleighInventory.isUseableByPlayer(playerIn) && this.theSleigh.isEntityAlive() && this.theSleigh.getDistanceToEntity(playerIn) < 8.0F; } private void bindPlayerInventory(InventoryPlayer inventory) { int i; for(i = 0; i < 3; i++) { for(int j = 0; j < 9; j++) { this.addSlotToContainer(new Slot(inventory, j + i * 9 + 9, 8 + j * 18, 86 + i * 18)); } } for(i = 0; i < 9; i++) { this.addSlotToContainer(new Slot(inventory, i, 8 + i * 18, 144)); } } public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack itemstack = null; Slot slot = (Slot)this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (index < this.sleighInventory.getSizeInventory()) { if (!this.mergeItemStack(itemstack1, this.sleighInventory.getSizeInventory(), this.inventorySlots.size(), true)) { return null; } } else if (this.getSlot(1).isItemValid(itemstack1) && !this.getSlot(1).getHasStack()) { if (!this.mergeItemStack(itemstack1, 1, 2, false)) { return null; } } else if (this.getSlot(0).isItemValid(itemstack1)) { if (!this.mergeItemStack(itemstack1, 0, 1, false)) { return null; } } else if (this.sleighInventory.getSizeInventory() <= 2 || !this.mergeItemStack(itemstack1, 2, this.sleighInventory.getSizeInventory(), false)) { return null; } if (itemstack1.stackSize == 0) { slot.putStack((ItemStack)null); } else { slot.onSlotChanged(); } } return itemstack; } }Et mon Inventaire :
package This_is_Christmas; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; public class InventorySleigh extends Entity implements IInventory{ public InventorySleigh(World worldIn) { super(worldIn); System.out.println("Inventory has been call"); } private ItemStack[] contents = new ItemStack[54]; private String customName; @Override public String getName() { return this.hasCustomName() ? this.customName : "entity.sleigh"; } @Override public boolean hasCustomName() { // TODO Auto-generated method stub return false; } @Override public ITextComponent getDisplayName() { // TODO Auto-generated method stub return null; } @Override public int getSizeInventory() { return this.contents.length; } @Override public ItemStack getStackInSlot(int slotIndex) { return this.contents[slotIndex]; } @Override public ItemStack decrStackSize(int slotIndex, int count) { if(this.contents[slotIndex] != null) { ItemStack itemStack; if(this.contents[slotIndex].stackSize <= count) { itemStack = this.contents[slotIndex]; this.contents[slotIndex] = null; this.markDirty(); return itemStack; } else { itemStack = this.contents[slotIndex].splitStack(count); if(this.contents[slotIndex].stackSize == 0) { this.contents[slotIndex] = null; } this.markDirty(); return itemStack; } } else { return null; } } @Override public ItemStack removeStackFromSlot(int slotIndex) { if(this.contents[slotIndex] != null) { ItemStack itemStack = this.contents[slotIndex]; this.contents[slotIndex] = null; return itemStack; } return null; } @Override public void setInventorySlotContents(int slotIndex, ItemStack stack) { this.contents[slotIndex] = stack; if(stack != null && stack.stackSize > this.getInventoryStackLimit()) { stack.stackSize = this.getInventoryStackLimit(); } this.markDirty(); } @Override public int getInventoryStackLimit() { return 64; } @Override public void markDirty() { // TODO Auto-generated method stub } @Override public boolean isUseableByPlayer(EntityPlayer player) { if(player.getDistanceSq((double)this.posX + 0.5D, (double)this.posY + 0.5D, (double)this.posZ + 0.5D) <= 64.0D) { return true; } else { return false; } } @Override public void openInventory(EntityPlayer player) { } @Override public void closeInventory(EntityPlayer player) { } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return true; } @Override public int getField(int id) { // TODO Auto-generated method stub return 0; } @Override public void setField(int id, int value) { // TODO Auto-generated method stub } @Override public int getFieldCount() { // TODO Auto-generated method stub return 0; } @Override public void clear() { // TODO Auto-generated method stub } public void setCustomName(String customName) { this.customName = customName; } @Override protected void entityInit() { // TODO Auto-generated method stub } @Override protected void readEntityFromNBT(NBTTagCompound compound) { // TODO Auto-generated method stub } @Override protected void writeEntityToNBT(NBTTagCompound compound) { // TODO Auto-generated method stub } }Je sais pas pourquoi mais j’ai l’impression qu’il y a des erreurs dans l’inventaire. Mais c’est pas là le problème. Comme vous voyez, dans chaque classe j’ai mis des sytem.out.println pour voir si c’est appelé ou pas. Voilà ce que j’obtient :
[17:42:26] [Server thread/INFO] [STDOUT]: [This_is_Christmas.Entity.EntitySleigh:processInitialInteract:851]: must open GUI [17:42:26] [Server thread/INFO] [STDOUT]: [This_is_Christmas.GuiHandlerChristmas:getServerGuiElement:15]: must call container [17:42:26] [Server thread/INFO] [STDOUT]: [This_is_Christmas.InventorySleigh:<init>:16]: Inventory has been call [17:42:26] [Server thread/INFO] [STDOUT]: [This_is_Christmas.ContainerSleigh:<init>:19]: Container has been call [17:42:26] [Client thread/INFO] [STDOUT]: [This_is_Christmas.GuiHandlerChristmas:getClientGuiElement:28]: must call GUI [17:42:26] [Client thread/INFO] [STDOUT]: [This_is_Christmas.InventorySleigh:<init>:16]: Inventory has been call [17:42:26] [Client thread/INFO] [STDOUT]: [This_is_Christmas.ContainerSleigh:<init>:19]: Container has been call [17:42:26] [Client thread/INFO] [STDOUT]: [This_is_Christmas.GuiSleigh:<init>:23]: GUI has been call [17:42:26] [Client thread/INFO] [STDOUT]: [This_is_Christmas.GuiSleigh:<init>:30]: GUI has been initializeOn peut voir que tout est appelé à l’exception d’une fonction : la fonction drawGuiContainerBackgroundLayer de la classe Gui. Je sais pas pourquoi ça ne marche pas, pourtant le gui est bien initialisé.
Si vous avez une idée, n’hsitez pas

C’est peut-être le fait que j’ai bidouillé quelques trucs pour l’adapter à une entité qui fait foirer quelque choseMerci d’avance
EDIT : Pour le mouvement du traîneau, ce n’est pas un packet en fait, parce qu’il a des paramètres en rapport avec les palles. Pour être sûr, j’ai ouvert un src 1.8, et il n’y a pas de packet.</init></init></init></init></init></init>
-
Ton gui se referme car la condition suivante :
return this.sleighInventory.isUseableByPlayer(playerIn) && this.theSleigh.isEntityAlive() && this.theSleigh.getDistanceToEntity(playerIn) < 8.0F;n’est pas satisfaite (canInteractWith du container).
Car ici :
EntitySleigh sleigh = new EntitySleigh(world); InventorySleigh invSleigh = new InventorySleigh(world); return new GuiSleigh(player.inventory, invSleigh, sleigh, player);Tu créés une nouvelle instance au lieu de get l’entité existante.
Utilises Entity entity = world.getEntityById(x) pour get l’entité, et lors du openGui utilise ça :player.openGui(ThisisChristmas.instance, 0, this.worldObj, this.getEntityId(), 0, 0);x, y et z n’ont pas forcement besoin d’être des coordonnées, et c’est seulement utile dans le cas d’un bloc.
Pour une entité faire passer l’id de l’entité suffit.Et pour ton inventaire, au lieu de créer une classe à part (qui te fait encore une instance de plus que tu gère déjà mal) fusionne-le dans la classe de l’entité. Ça sera beaucoup plus simple pour gérer l’instance et pour l’enregistrement des items dans le nbt de l’entité (d’ailleurs on fait exactement la même chose avec les tile entity, l’inventaire est dans la classe même et non dans une classe à part).
-
Salut
J’ai tout fait et ça marche bien, à part les slots qui étaient décalés. Je pensais que ça serait chaud de les déplacer, mais non : une fois qu’on a compris le calcul, c’est simple. Là, tout est bien positionné. Voilà le résultat :

Il me reste plus que le problème que je ne peux pas bouger avec. A mon avis, la solution au problème doit être la même que mon problème de Renne que je ne peux pas contrôler non plus.
Merci d’avance
-
Salut
Ce n’est pas la même solution que mon problème de renne, le renne étant extend de EntityAnimal. Mais je pense avoir trouvé. J’ai essayé de voir où était appelé ma classe entity, elle est appelé dans l’itemSleigh (en gros, c’est l’item pour le faire spawn). J’ai comparé à l’entityBoat, elle est appelé à trois endroits : dans l’item (comme pour moin traîneau, il sert a le faire spawn), dans la sous-classe BehaviorDispenseBoat de la classe Bootstrap et dans la classe NetHandlerPlayClient. Pour la sous-classe BehaviorDispenseBoat, si je comprend bien le commentaire (le voici : Dispense the specified stack, play the dispense sound and spawn particles.), ça sert pour le dispenser. Dans la classe NetHandlerPlayClient, je pense que c’est des packets vu que ça concerne le réseau. En tout cas, si c’est ça, tu avais raison LeBossMax2. Mais je suis pas sûr, voici la classe (je met juste ce qui est utile, demandez moi si vous voulez la classe en entière, elle est dans le package net/minecraft/client/network) :package net.minecraft.client.network; […] @SideOnly(Side.CLIENT) public class NetHandlerPlayClient implements INetHandlerPlayClient { […] private WorldClient clientWorldController; […] /** * Spawns an instance of the objecttype indicated by the packet and sets its position and momentum */ public void handleSpawnObject(SPacketSpawnObject packetIn) { PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.gameController); double d0 = packetIn.getX(); double d1 = packetIn.getY(); double d2 = packetIn.getZ(); Entity entity = null; […] else if (packetIn.getType() == 1) { entity = new EntityBoat(this.clientWorldController, d0, d1, d2); } […] if (entity != null) { EntityTracker.updateServerPosition(entity, d0, d1, d2); entity.rotationPitch = (float)(packetIn.getPitch() * 360) / 256.0F; entity.rotationYaw = (float)(packetIn.getYaw() * 360) / 256.0F; Entity[] aentity = entity.getParts(); if (aentity != null) { int i = packetIn.getEntityID() - entity.getEntityId(); for (int j = 0; j < aentity.length; ++j) { aentity[j].setEntityId(aentity[j].getEntityId() + i); } } entity.setEntityId(packetIn.getEntityID()); entity.setUniqueId(packetIn.getUniqueId()); this.clientWorldController.addEntityToWorld(packetIn.getEntityID(), entity); if (packetIn.getData() > 0) { if (packetIn.getType() == 60 || packetIn.getType() == 91) { Entity entity2 = this.clientWorldController.getEntityByID(packetIn.getData() - 1); if (entity2 instanceof EntityLivingBase && entity instanceof EntityArrow) { ((EntityArrow)entity).shootingEntity = entity2; } } entity.setVelocity((double)packetIn.getSpeedX() / 8000.0D, (double)packetIn.getSpeedY() / 8000.0D, (double)packetIn.getSpeedZ() / 8000.0D); } } } […] }Merci d’avance
-
Salut
J’ai enfin réussi. J’ai mis :Entity player = this.getControllingPassenger(); EntityTracker.updateServerPosition(this, this.posX, this.posY, this.posZ); this.rotationPitch = (float)((MathHelper.floor_float(player.rotationPitch * 256.0F / 360.0F)) * 360) / 256.0F; this.rotationYaw = (float)((MathHelper.floor_float(player.rotationYaw * 256.0F / 360.0F)) * 360) / 256.0F; Entity[] aentity = this.getParts(); if(aentity != null) { int i = player.getEntityId() - this.getEntityId(); for(int j=0; j < aentity.length; ++j) { aentity[j].setEntityId(aentity[j].getEntityId() + i); } } this.setVelocity((double)((int)(MathHelper.clamp_double(player.motionX, -3.9D, 3.9D) * 8000.0D)) / 500.0D, (double)((int)(MathHelper.clamp_double(player.motionY, -3.9D, 3.9D) * 8000.0D)) / 500.0D, (double)((int)(MathHelper.clamp_double(player.motionZ, -3.9D, 3.9D) * 8000.0D)) / 500.0D); ``` dans la fonction controlBoat. Je me suis inspiré de la fonction que j'ai donné dans le post précédent. Par contre, j'ai un autre problème et une question. Mon autre problème concerne la hitbox. Je l'ai modifié et ça met fait ça : [](http://www.noelshack.com/2016-43-1477837960-2016-10-30-15-06-51.png) (j'ai mis la hitbox en rouge pour bien la voir) Comme vous voyez, elle est trop grande. J'ai essayé de la réduire, mais le problème c'est que ça la réduit des 4 côtés. Je pense qu'il y a une fonction pour repositionner la hitbox mais je ne la trouve pas. Ce que je pensais faire, c'est placer le traîneau centre de la hitbox pour ensuite la réduire. Et ma question, c'est que je vais faire d'autres modifs assez dur selon moi (pouvoir accroché des rennes aux traîneau et ne pouvoir avancer seulement si il y a des rennes). J'ai une petite idée mais si je n'y arrive pas, je demande ici ou je créer un nouveau sujet ? -
En effet ton rendu n’est pas centré par rapport à la boite de collision, il faut adapter le code du rendu avec un petit glTranslate.
(et du-coup il faudra aussi adapter tes valeurs pour la position de l’entité qui monte le traineau).Pour les rennes, il serait mieux de créer une nouvelle discussion.
-
Je n’arrive pas à bien positionner le rendu par rapport à la hitbox. Je sais pas trop comment expliquer, je met des images (ça me fait pareil que quand j’ai voulu positionner le joueur)
Quand je ne touche à rien :
Quand je décale de 1 sur l’axe Z :
Je pense que je vais modifier le model, ça sera sans doute plus rapide. Mais j’ai juste une question : je ne vois pas de différence entre ces deux fonctions :
GL11.glTranslated(x, y, z); GL11.glTranslatef(x, y, z);Pourquoi avoir mis deux fonctions qui font la même chose ?
-
Le premier prend un argument des doubles, l’autre des float.
Donc l’une permet plus de précision que l’autre mais est plus lourde. -
Salut
Merci de ces précisions
J’ai modifié le model. C’est bien positionner maintenantMerci à tous