Résolu Changer la texture d'un block en fonction d'une variable
-
Bonjour,
Je souhaite faire un block qui change de texture en fonction d’une variable (un peu comme le four quand il contient du charbon). Mais je n’arrive pas à changer la texture du block quand la valeur de la variable (state) change.
Block:
package com.aetio.morei2.blocks; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.World; import com.aetio.morei2.MoreIlluminations; import com.aetio.morei2.tiles.TileProjector; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralProvider; public class Projector extends Block implements IPeripheralProvider{ private int state = 0; private IIcon[] icons = new IIcon[4]; public Projector() { super(Material.rock); setBlockName("projector"); setCreativeTab(CreativeTabs.tabBlock); setLightLevel(1.0F); setHardness(0.6F); } @SideOnly(Side.CLIENT) public IIcon getIcon(int side, int metadata){ return this.icons[state]; } @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister icon){ for(int i = 0; i < icons.length; i++){ icons* = icon.registerIcon(MoreIlluminations.MODID + ":projector_" + state); } } @Override public TileEntity createTileEntity(World world, int metadata){ return new TileProjector(this); } @Override public boolean hasTileEntity(int metadata){ return true; } @Override public IPeripheral getPeripheral(World world, int x, int y, int z, int side) { TileEntity tile = world.getTileEntity(x, y, z); if (tile == null) return null; if (tile instanceof TileProjector) { return (TileProjector)tile; } return null; } public void updateState(int state){ this.state = state; setBlockTextureName(MoreIlluminations.MODID + ":projector_" + state); System.out.println(this.state); } }
TileEntity:
package com.aetio.morei2.tiles; import com.aetio.morei2.MoreIlluminations; import com.aetio.morei2.blocks.Projector; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; import net.minecraft.tileentity.TileEntity; public class TileProjector extends TileEntity implements IPeripheral{ private int state = 0; private Projector block; public TileProjector(Projector block) { super(); this.block = block; } @Override public String getType() { return "projector"; } @Override public String[] getMethodNames() { return new String[] {"getColor", "setColor"}; } @Override public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException { switch(method){ case(0): return new Object[] {"Color is: " + state}; case(1): double color = (Double) arguments[0]; this.state = (int) color; block.updateState(state); return new Object[] {"Color is set to " + state}; } return null; } @Override public void attach(IComputerAccess computer) { } @Override public void detach(IComputerAccess computer) { } @Override public boolean equals(IPeripheral other) { return false; } public int getState() { return state; } public void setState(int state) { this.state = state; } }
Merci d’avance.
-
Enregistre les icones que tu veux, et ensuite ré-écris la fonction getIcon(IBlockAccess, int, int, int, int) qui te permettra d’appeler ta tile entity, liste des paramètres :
- IBlockAccess : world
- int : x
- int : y
- int : z
- int : side
-
Surement un problème de valeur client serveur, utilise la fonction que SCAREX t’as donné et regarde dans le tutoriel sur les blocs directionnels la partie avec le tile entity, je donne les deux fonctions pour synchro un tile entity.
Après faut juste faire un world.markBlockForUpdate(x, y, z) pour lancer la syncho. -
J’ai essayé ça, m’ai je ne suis pas du tout sûr d’avoir fais correctement car cela ne fonctionne pas.
@SideOnly(Side.CLIENT) public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side){ TileEntity tile = world.getTileEntity(x, y, z); if(tile instanceof TileProjector){ return this.icons[((TileProjector) tile).getState()]; } return this.icons[0]; } @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister icon){ for(int i = 0; i < icons.length; i++){ icons* = icon.registerIcon(MoreIlluminations.MODID + ":projector_" + i); } }
-
Fait attention : tu risque un ArrayOutOfBoundException.
Rajoute un System.out.println de la méthode getState pour voir ce qu’elle contient.
PS : si tu veux faire un block coloré, il existe des méthodes pour obtenir la couleur d’un block, je crois que c’est getColorForRenderPass.
-
J’ai ajouté le println, mais ça sa valeur s’affiche un certain nombres de fois au début puis plus jamais.
[23:12:35] [Server thread/INFO]: Player498 joined the game 0 0 0 0 0 0 0 0 0 0 [23:12:53] [Server thread/INFO]: Saving and pausing game…
De plus la valeur de state dans le TileEntity est correcte.
-
Le code semble bon côté bloc, donc ça doit être côté tile entity que tu ne synchro pas.
-
vérifie que la méthode soit bien appelée et que la couleur est bien mise depuis l’ordinateur. Par exemple en mettant un System.out.println dans le bloque switch.
-
La méthode est bien appelé car il retourne le message “Color is: x” et l’ancienne méthode updateState dans le block affichait bien la valeur de state.
-
block ne doit pas être une variable locel : block.updateState(state);
utilise plutot this.worldObj.getBlock(x, y, z).updateState -
De toute façon la méthode updateState n’est plus utilisé.
Voici les class retouché :
Block:
package com.aetio.morei2.blocks; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import com.aetio.morei2.MoreIlluminations; import com.aetio.morei2.tiles.TileProjector; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralProvider; public class Projector extends Block implements IPeripheralProvider{ private IIcon[] icons = new IIcon[4]; public Projector() { super(Material.rock); setBlockName("projector"); setCreativeTab(CreativeTabs.tabBlock); setLightLevel(1.0F); setHardness(0.6F); } @SideOnly(Side.CLIENT) public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side){ TileEntity tile = world.getTileEntity(x, y, z); if(tile instanceof TileProjector){ System.out.println(((TileProjector) tile).getState()); return this.icons[((TileProjector) tile).getState()]; } return this.icons[0]; } @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister icon){ for(int i = 0; i < icons.length; i++){ icons* = icon.registerIcon(MoreIlluminations.MODID + ":projector_" + i); } } @Override public TileEntity createTileEntity(World world, int metadata){ return new TileProjector(); } @Override public boolean hasTileEntity(int metadata){ return true; } @Override public IPeripheral getPeripheral(World world, int x, int y, int z, int side) { TileEntity tile = world.getTileEntity(x, y, z); if (tile == null) return null; if (tile instanceof TileProjector) { return (TileProjector)tile; } return null; } }
TileEntity:
package com.aetio.morei2.tiles; import com.aetio.morei2.MoreIlluminations; import com.aetio.morei2.blocks.Projector; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; import net.minecraft.tileentity.TileEntity; public class TileProjector extends TileEntity implements IPeripheral{ private int state = 0; @Override public String getType() { return "projector"; } @Override public String[] getMethodNames() { return new String[] {"getColor", "setColor"}; } @Override public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException { switch(method){ case(0): return new Object[] {"Color is: " + state}; case(1): double color = (Double) arguments[0]; this.state = (int) color; return new Object[] {"Color is set to " + state}; } return null; } @Override public void attach(IComputerAccess computer) { } @Override public void detach(IComputerAccess computer) { } @Override public boolean equals(IPeripheral other) { return false; } public int getState() { return state; } public void setState(int state) { this.state = state; } }
-
On va m’écouter oui ou non ?!? –’
C’est un problème de synchro client / serveur.
Dans le code du bloc la variable private int state = 0; et la fonction updateState ne devrait même pas exister. -
Comment puis-je resynchroniser la texture?
-
http://www.minecraftforgefrance.fr/showthread.php?tid=1304#partie3-1
Je donne tout pour synchro les tile entity dans ce tuto.
La fonction
this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord);
Signale un changement.
getDescriptionPacket et onDataPacket font la synchro.
Il faut que ta variable state soit enregistré dans le read from et le write to nbt. -
Merci, je vois clairement que les données se synchronisent, mais la variable change de valeur puis pour une raison incompréhensible reprened la valeur 0 à l’arrivé dans le block puis dans le TileEntity également.___Merci beaucoup, ça marche parfaitement.
-
Merci beaucoup, ça marche parfaitement.