Monture Custom
-
Bonjour Bonsoir,
Ce serait pour savoir si il semble possible de faire un bateau ayant les propriétés d’un cheval?
Actuellement je m’amuse à faire des montures (avec plus ou moins de succès) comme ma moto (je poursuis actuellement sur un buggy):Et j’en viens à me/vous demander si je ne pourrais pas faire des montures allant sur ou sous l’eau.
Est-ce que je dois passer par un bateau ayant un model custom ou bien je peux rester sur mes acquis et donner ces propriétés à mes entity qui sont actuellement des chevaux?
Merci pour votre avis et/ou votre aide à ce sujet
-
Le mieux est de faire entité de 0, donc avec juste un extends Entity. Après tu peux t’inspirer du code du bateau et du code du cheval.
-
D’acc, je sens d’avance que je vais rencontrer 40 milles obstacles de code qui me dépassent, surtout que tout ce que je trouve est sur du 1.8
Déjà que j’ai mis deux semaines pour faire mes montures qui sont plutôt potables à part un ou deux petits inconvénients.Je laisse ce topic ouvert à qui aurait d’autres infos utiles.
-
Ce n’est pas un up pour la partie “bateau”. C’est juste que ça y touche donc pas besoin de faire un nouveau sujet.
Voilà, mes entités sont extend EntityHorse ce qui fait qu’avec un waila par exemple ça marque “Horse” au survol en jeu.
Ma question est de savoir si en assignant:
public boolean hasCustomNameTag() { return true; }
Je peux mettre un nom dans les NBTTag et si ça résoudra mon problème de “horse” qui associé à une moto, ne fait pas bon ménage.
Les tags de l’entité ressemblent à ça pour le moment:
public void writeEntityToNBT(NBTTagCompound nbt) { super.writeEntityToNBT(nbt); DataWatcher dw = this.getDataWatcher(); nbt.setString("EntityMotoTexture", dw.getWatchableObjectString(30)); } public void readEntityFromNBT(NBTTagCompound nbt) { super.readEntityFromNBT(nbt); DataWatcher dw = this.getDataWatcher(); dw.updateObject(30, nbt.getString("EntityMotoTexture")); }
Je précise que je ne sais tout simplement pas comment je dois écrire ça, si y’a moyen d’explicitement me l’expliquer svp
-
Suffit de chercher dans EntityHorse la fonction qui gère le nom :
public String getCommandSenderName() { if (this.hasCustomName()) { return this.getCustomNameTag(); } else { int i = this.getHorseType(); switch (i) { case 0: default: return StatCollector.translateToLocal("entity.horse.name"); case 1: return StatCollector.translateToLocal("entity.donkey.name"); case 2: return StatCollector.translateToLocal("entity.mule.name"); case 3: return StatCollector.translateToLocal("entity.zombiehorse.name"); case 4: return StatCollector.translateToLocal("entity.skeletonhorse.name"); } } }
Comme tu peux le voir si tu override hasCustomName (et non hasCustomNameTag) pour le mettre sur true il va cherche le nom dans getCustomNameTag. Qui par défaut fait ça :
public String getCustomNameTag() { return this.dataWatcher.getWatchableObjectString(2); }
Donc pour faire ce que tu veux tu dois ajouter ces deux méthodes :
public boolean hasCustomName() { return true; } public String getCustomNameTag() { return this.dataWatcher.getWatchableObjectString(30); }
(il faut bien sûr que ton entité est un data watcher de type string sur l’id 30).
Ou alors plus simple, il suffit d’override directement la fonction getCommandSenderName et retourner this.dataWatcher.getWatchableObjectString(30) (ça évite de faire une usine à gaz).
-
Good, ça marche, ça change de:
J’aurais une question concernant les bounds ou plutôt la hitBox d’une entité à rendu custom.
Je peux la changer avec quoi? AxistrucBB par exemple?Déjà j’aimerais que l’avant des véhicules ne s’enfoncent pas dans les décors mais plus important encore que les personnes dedans dépassent de la hitbox du véhicule pour ne pas bousiller le pvp.
-
par comtre à moins que tu veuilles passer ta vie pour chaque modèle, la hitbox sera carré. Je n’ai jamais travaillé avec une hitbox plus grande qu’un bloc mais regarde ça:
public void
-
J’ai pas tout compris avec ton “public void” =D
En tout cas, oui, je suis prêt à passer ma vie sur chaque modèle si ça solutionne la question de la hitbox.
Pour tout expliquer, mes entités étant extend EntityHorse et que le mod “plus d’aliments” fait drop de la viande à un cheval qui meurt, j’ai commencé par rendre invincible les montures et simplement les faire disparaitre au bout de 10 minutes.
Seulement pour mes modèles, les joueurs sont positionnés assez bas 0.15 à 0.4F max me semble donc ça fait des joueurs invincibles 10minutes, pour un serveur ouvert pvp sur 95% de la carte ça craint.
Edit: J’ai trouvé une façon toute bête de résoudre mon problème. A voir si ça vous semble “correct”.
public EntityBaignoire(World model) { super(model); this.setSize(2.0F, 0.5F); }
Quand on fait spawn l’entité la hitbox reste du 1 sur 1 par contre dès que je monte dessus celle-ci devient plus large et plus basse (2.0 sur 0.5 quoi).
Voilà, est ce trop simple pour fonctionner correctement? xDEdit2:
Ok ça fout en l’air les positions du joueur sur l’entité, il faut juste ajuster ça.
-
C’est bien le setSize qu’il faut utiliser et il faut le mettre dans le constructeur de l’entité. Par contre c’est sensé afficher la bonne box de collision dès que l’entité spawn.
-
Ok, alors malheureusement l’histoire de CustamName n’est pas résolue.
Sous Eclipse ça marche, mais une fois sur le serveur, ça ne fonctionne plus. C’est à dire que toutes les entités sont nommées “horse”.
-
Oulah, mon public vois n’avait rien à voir je crois que j’avais mal copié ^^.
Sinon, où es-tu rendu? As-tu réussi pour la hitbox ou le custom name?
-
Eh bien, pour la hitbox c’est good niveau serveur, même si apparement elle me fait des choses qu’elle ne devrait pas (genre être à 1.0/1.0 quand je fais spawn l’entité puis passer à la valeur voulue une fois montée)
Par contre, j’ai cru que tout était bon pour le CustomName mais non. Sous Eclipse ça affiche bien la valeur du Datawatcher d’ID 30, mais une fois sur le serveur, je retombe sur le bête “horse”.
Je crois que je vais devoir faire comme à dit Robin à la fin de son message à ce sujet, juste que je n’avais pas réussis à interpréter ça en java et j’en étais resté à la partie simple de son explication. Je me repenche sur ça et je vous tiens au courant.
Edit:
Au final je dois faire ça selon Robin tu crois?
public boolean hasCustomName() { return true; } @Override public String getCommandSenderName() { if (this.hasCustomName()) { return this.dataWatcher.getWatchableObjectString(30); } return null; }
Vais me renseigner sur l’Override, je ne connais pas son utilité, un truc d’inhéritence nan?
Edit2:
Ok alors les deux méthodes sont bonnes c’est juste qu’il manquait “Tag”
public boolean hasCustomNameTag() { return true; }
Car sinon pour régler ça il fallait utiliser une étiquette sur l’entité pour la renommer pour qu’elle passe en “true”.
Tout bête mais bon. Du coup j’ai pu faire selon robin, quelque chose qui ressemble moins à une “chambre à gaz”. -
@Override public String getCommandSenderName() { return this.dataWatcher.getWatchableObjectString(30); }
Ce n’est pas mieux comme ça non ? Car ton code actuel ça revient à faire if(true) … c’est pour ça que j’ai dit que ça fait usine à gaz.
Le @Override n’est pas nécessaire, mais il est pratique car si la fonction change de nom ou disparaît dans une future mise à jour tu aura une erreur. Alors que sans le @Override si la fonction change de nom ou disparaît ça va cesser de fonctionner sans qu’il n’y ait d’erreur. -
Ah ouais… Je n’y étais pas même à la fin =')
Le truc du Override ça me rappelle un technicien Microsoft qui disait un truc genre:
“Cette erreur je ne sais pas par quoi elle est causée alors je vais juste faire sauter le message d’erreur et personne ne se plaindra plus.”Merci en tout cas.
-
Re, les gens, je me heurte actuellement à un défi concernant les montures custom:
La position du joueur sur la monture. J’aimerais savoir comment modifier ce paramètre.
En regardant la classe du BlockBed je n’ai rien compris, pour être franc x]Concrètement j’aimerais faire la moto de Tron et donc il faudrait “allonger” le joueur dessus.
Suivant les possibilités que ce paramètre offre d’autres modèles seront envisagés évidemment. -
Si tu ne trouves vraiment pas dans la classe du lit, tu peux toujours te servir de l’event RenderPlayerEvent qui te permettra d’avoir une instance de la classe ModelPlayer et ainsi en fonction d’un boolean stocké dans le tag du joueur (ExtendedEntityProperties, tuto du gugu42), tu pourras faire varier les angles x, y et z de chacune des shapde du joueur, de sorte à ce qu’il soit allongé.
Pose-moi des questions si tu n’as pas tout compris, hein ! ^^’ -
Je suis presque sur qu’il y a une variable du genre riddingYcoord pour gérer la hauteur du joueur qui monte l’entité.
-
@‘robin4002’:
Je suis presque sur qu’il y a une variable du genre riddingYcoord pour gérer la hauteur du joueur qui monte l’entité.
Pour la hauteur du joueur c’est très simple comme la monture est un “cheval” donc avec:
public double getMountedYOffset() { return (double)this.height + 0.35D; }
Comme le suggère Julot, je veux modifier plus encore la position du joueur.
Maintenant ce que tu m’indiques Julot va me demander bien plus de travail que je ne pensais (comprendre et assimiler le tuto de Gugu, qui demande également de mettre un pied dans les packets).Alors merci pour les infos, je m’y pencherai seulement dans quelques temps, mon serveur va bientôt ouvrir, je cherchais un défi pour me détendre à côté de tout ça, mais là la barre est trop haute.
Petite question qui me vient dans tout ça, le fait que mes montures soient extends EntityHorse ne va pas créer des problèmes quant à la modification de la position du joueur à votre avis? (c’est peut-être pas évident comme question, mais évitera qu’on se rende tous compte que mon code est horrible et que j’aurais dû créer la monture en partant d’un simple “extends entity”)
Je sais qu’à un moment donné j’avais modifié la position “assise” pour debout et les montures ne répondaient plus du tout comme prévu.
-
Il est toujours mieux de partir d’un EntityAnimal plutôt que EntityHorse car Mojang code avec les pieds
-
Alors suite à la réponse de @Julot10085 sur le sujet Item qui a un cooldown je me suis dis que je pourrais peut-être “enfin” mettre un cooldown sur le klaxon de mes véhicules (ça spam bien les oreilles sinon).
Donc toujours sur ma base “extends EntityHorse” j’ai essayé d’appliquer les bouts de codes en suivant les indications d’Eclipse pour l’adapter, je pense que je n’ai pas bien régler les TagCompound, en tout cas ça ne crash pas.
Là où avant quand je voulais ouvrir l’inventaire de la monture ça ne produisait que le son du klaxon (sans GUI), maintenant ça ouvre le GUI du cheval, donc j’aimerais votre avis svp.
Le fonctionnement souhaité serait de pouvoir klaxonner seulement toutes les X secondes.:::
private Object stackTagCompound;
:::
:::
public void onLivingUpdate() { { if(this.hasTagCompound())//Si ton item n'a pas de tag alors on ne fait rien { if(((NBTTagCompound) this.stackTagCompound).getInteger("timer") > 0)//si ton timer est supérieur à 0 (après un clic droit logiquement) { ((NBTTagCompound) this.stackTagCompound).setInteger("timer", (int) (((NBTTagCompound) this.stackTagCompound).getInteger("timer") + 1));//On l'incrémente de 1 à chaque tick } if(((NBTTagCompound) this.stackTagCompound).getInteger("timer") >= (int) (6*20))//Remplace 6 par le nombre de secondes du timer souhaité { ((NBTTagCompound) this.stackTagCompound).setInteger("timer", 0);//On remet à 0 si le timer est arrivé à la limite souhaitée } } if(this.ticksExisted>=12000 && this.riddenByEntity == null) { this.setDead(); } else if (this.riddenByEntity == null) { motionX = motionY = motionZ = 0.0F; } else { super.onLivingUpdate(); this.worldObj.theProfiler.startSection("looting"); if (!this.worldObj.isRemote && this.canPickUpLoot() && !this.dead && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) {//[… la suite est du code du cheval]
:::
:::
public void openGUI(EntityPlayer p_110199_1_, World world) { if (!this.worldObj.isRemote && (this.riddenByEntity == null || this.riddenByEntity == p_110199_1_) && this.isTame() && p_110199_1_.inventory.getCurrentItem() == null) { if(!this.hasTagCompound())//Même condition, si ton item n'a pas de tag on lui en ajoute avec l'int timer en + { this.setTagCompound(new NBTTagCompound()); ((NBTTagCompound) this.stackTagCompound).setInteger("timer", 0); } if(((NBTTagCompound) this.stackTagCompound).getInteger("timer") == 0) { worldObj.playSoundAtEntity(this, "modpg:klaxon", 0.5F, 0.5F); ((NBTTagCompound) this.stackTagCompound).setInteger("timer", 1);//On le met à 1 pour pouvoir rentrer dans la condition de onUpdate() } else { if(world.isRemote) p_110199_1_.addChatComponentMessage(new ChatComponentTranslation("Attends encore un peu si tu veux re-klaxonner."));//On indique au joueur via ce message si le timer n'est pas encore arrivé à la limite souhaitée } } }
:::
:::
private boolean hasTagCompound() { return false; } private void setTagCompound(NBTTagCompound nbtTagCompound) { }
:::
:::
public void openGUI(EntityPlayer p_110199_1_) { if (!this.worldObj.isRemote && (this.riddenByEntity == null || this.riddenByEntity == p_110199_1_) && this.isTame() && p_110199_1_.inventory.getCurrentItem() == null) { worldObj.playSoundAtEntity(this, "modpg:sonnette", 0.5F, 0.5F); } }
:::