Résolu Problème de direction d'un projectile depuis un dispenser
-
Bonjour, depuis un petit moment je me suis lancé dans la création d’un mod pour lancer un projectile explosif depuis un dispenser. Le problème est que mon entité ne peut être lancée que vers le nord ou le sud sinon elle meure dès qu’elle spawn :
Classe du dispenser :```java
package fr.freshblock.freshrocket.common;import fr.freshblock.freshrocket.entity.projectile.EntityFreshRocket;
import net.minecraft.block.BlockDispenser;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.dispenser.IPosition;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;public final class BehaviorDefault extends BehaviorDefaultDispenseItem
{
@Override
protected ItemStack dispenseStack(IBlockSource source, ItemStack stack)
{
//Obtenir le mondeWorld world = source.getWorld();
EnumFacing enumfacing = BlockDispenser.func_149937_b(source.getBlockMetadata());
IPosition iposition = BlockDispenser.func_149939_a(source);//instancier l’entité
Entity entityfreshrocket = new EntityFreshRocket(world, iposition.getX(), iposition.getY(), iposition.getZ());
//vecteur x
double x = source.getX();
double x1 = iposition.getX();
double dirX = x1-x;//vecteur y
double y = source.getY();
double y1 = iposition.getY();
double dirY = y-y1;//vecteur z
double z = source.getZ();
double z1 = iposition.getZ();
double dirZ = z-z1;entityfreshrocket.motionX = dirX;
entityfreshrocket.motionY = dirY;
entityfreshrocket.motionZ = dirZ;world.spawnEntityInWorld(entityfreshrocket);
–stack.stackSize;
return stack;
}
}
Classe de l'entité:
java
package fr.freshblock.freshrocket.entity.projectile;import cpw.mods.fml.common.registry.EntityRegistry;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IProjectile;
import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.IProgressUpdate;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;public class EntityFreshRocket extends EntityThrowable
{
private static final Block obsidian = Blocks.obsidian;
private int xTile = -1; // Position X du projectile
private int yTile = -1; // Position Y du projectile
private int zTile = -1; // Postion Z du projectile
private Block inTile;
private int inData;
private boolean inGround; // Dans un bloc ou pas
public int arrowShake;
public Entity shootingEntity; // Le joueur qui a tiré le projectile
private int ticksInGround; // Je pense que c’est clair
private int ticksInAir; // Je pense que c’est clair également
private double damage = 6.0D; // Dégats du projectile
private int knockbackStrength; // Puissance du knockback
public int canBePickedUp;public void setThrowableHeading(double p_70186_1_, double p_70186_3_, double p_70186_5_, float p_70186_7_, float p_70186_8_)
{
this.renderDistanceWeight = 10.0D;
this.setSize(0.5F, 0.5F);
this.setPosition(p_70186_3_, p_70186_5_, p_70186_7_);
this.yOffset = 0.0F;
}public EntityFreshRocket(World worldIn)
{
super(worldIn);
this.renderDistanceWeight = 10.0D; // Si je comprend bien, la distance
// du render de la flèche
this.setSize(0.5F, 0.5F); // taille du projectile
}public EntityFreshRocket(World worldIn, double x, double y, double z)
{
super(worldIn);
this.renderDistanceWeight = 10.0D; // Pareil qu’au dessus
this.setSize(0.5F, 0.5F); // Pareil qu’au dessus
this.setPosition(x, y, z); // La position du projectile
}public EntityFreshRocket(World worldIn, EntityLivingBase shooter, EntityLivingBase p_i1755_3_, float p_i1755_4_, float p_i1755_5_)
{
super(worldIn);
this.renderDistanceWeight = 10.0D; // Toujours pareil
this.shootingEntity = shooter; // Qui a tiré le projectileif(shooter instanceof EntityPlayer)
{
this.canBePickedUp = 0; // Si le tireur peut ramasser le projectile
}
// Plein de méthode chelous…
this.posY = shooter.posY + (double)shooter.getEyeHeight() - 0.10000000149011612D;
double d0 = p_i1755_3_.posX - shooter.posX;
double d1 = p_i1755_3_.getBoundingBox().minY + (double)(p_i1755_3_.height / 3.0F) - this.posY;
double d2 = p_i1755_3_.posZ - shooter.posZ;
double d3 = (double)MathHelper.sqrt_double(d0 * d0 + d2 * d2);if(d3 >= 1.0E-7D)
{
float f2 = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
float f3 = (float)(-(Math.atan2(d1, d3) * 180.0D / Math.PI));
double d4 = d0 / d3;
double d5 = d2 / d3;
this.setLocationAndAngles(shooter.posX + d4, this.posY, shooter.posZ + d5, f2, f3);
float f4 = (float)(d3 * 0.20000000298023224D);
this.setThrowableHeading(d0, d1 + (double)f4, d2, p_i1755_4_, p_i1755_5_);
}
}public EntityFreshRocket(World worldIn, EntityLivingBase shooter, float p_i1756_3_) // Quasiment la mème qu’au dessus
{
super(worldIn);
this.renderDistanceWeight = 10.0D;
this.shootingEntity = shooter;if(shooter instanceof EntityPlayer)
{
this.canBePickedUp = 0;
}this.setSize(0.5F, 0.5F);
this.setLocationAndAngles(shooter.posX, shooter.posY + (double)shooter.getEyeHeight(), shooter.posZ, shooter.rotationYaw, shooter.rotationPitch);
this.posX -= (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F);
this.posY -= 0.10000000149011612D;
this.posZ -= (double)(MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F);
this.setPosition(this.posX, this.posY, this.posZ);
this.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI));
this.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI));
this.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI));
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, p_i1756_3_ * 1.5F, 1.0F);
}protected void onImpact(MovingObjectPosition EntityFreshRocket)
{
//If this hit’s a block, continue
if(EntityFreshRocket.typeOfHit == MovingObjectType.BLOCK)
{
/*
* You might be wondering what
* all these case and break are
* These are use to switch the number
* EntityFreshRocket.sideHit
*
* Example:
* If EntityFreshRocket.sideHit == 3 whatever is in
* case 3 Happens!
/
switch(EntityFreshRocket.sideHit)
{
case 0: //BOTTOM
EntityFreshRocket.blockY–;
break;
case 1: //TOP
EntityFreshRocket.blockY++;
break;
case 2: //EAST
EntityFreshRocket.blockZ–;
break;
case 3: //WEST
EntityFreshRocket.blockZ++;
break;
case 4: //NORTH
EntityFreshRocket.blockX–;
break;
case 5: //SOUTH
EntityFreshRocket.blockX++;
break;
}
/ This method creates the explosion!
* It uses the entity (Can be null)
* the three coordinates, the strength
* and if it should spawn smoke particles
* around after exploding, the last parameter
* is if it should set neighboring blocks on fire
*/this.worldObj.newExplosion(this, EntityFreshRocket.blockX, EntityFreshRocket.blockY, EntityFreshRocket.blockZ, 20.0F, false, true);
}if (EntityFreshRocket.typeOfHit != MovingObjectPosition.MovingObjectType.MISS)
{
if (EntityFreshRocket.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
{
if(EntityFreshRocket.hitInfo == obsidian)
{
this.obsidian.breakBlock(worldObj, canBePickedUp, canBePickedUp, canBePickedUp, obsidian, canBePickedUp);
}
if(EntityFreshRocket.entityHit != null)
{
byte b0 = 0;if(EntityFreshRocket.entityHit instanceof EntityBlaze)
{
b0 = 3;
}EntityFreshRocket.entityHit.attackEntityFrom(DamageSource.cactus, distanceWalkedModified);
}for(int i = 0; i < 8; ++i)
{
this.worldObj.spawnParticle(“largeexplode”, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
}if(!this.worldObj.isRemote)
{
this.setDead();
}
}
}
}
} -
Ta classe d’entité n’a pas l’air très propre, pourquoi il y a des setSize dans le setThrowableHeading ? Et pourquoi si peux de paramètres sont utilisés ?
Rajoute des logs dans ta fonction pour faire spawner l’entité pour voir si le problème vient avec les calculs pour faire spawner l’entité ou si le problème vient une fois le spawn fait.
-
Ok je up le post pour mettre à jour mes classes et mes problèmes.
Problème 1 :
En changeant quelques trucs dans la classe de l’entité mon projectile n’a plus de render en jeu -_-Problème 2 :
Le projectile ne peut être lancer que vers le nord ou le sud.classe de l’envoi du projectile :```java
package fr.freshblock.freshrocket.common;import cpw.mods.fml.relauncher.Side;
import fr.freshblock.freshrocket.entity.projectile.EntityFreshRocket;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDispenser;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.dispenser.IPosition;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Facing;
import net.minecraft.world.World;public final class BehaviorDefault extends BehaviorDefaultDispenseItem
{
@Override
protected ItemStack dispenseStack(IBlockSource source, ItemStack stack)
{
//Obtenir le mondeWorld world = source.getWorld();
IPosition iposition = BlockDispenser.func_149939_a(source);
EnumFacing enumfacing = BlockDispenser.func_149937_b(source.getBlockMetadata());//instancier l’entité
Entity entityfreshrocket = new EntityFreshRocket(world, iposition.getX(), iposition.getY(), iposition.getZ());
double x = source.getX();
double x1 = iposition.getX();
double dirX = x1-x;double y = source.getY();
double y1 = iposition.getY();
double dirY = y-y1;double z = source.getZ();
double z1 = iposition.getZ();
double dirZ = z-z1;entityfreshrocket.motionX = dirX;
entityfreshrocket.motionY = dirY;
entityfreshrocket.motionZ = dirZ;world.spawnEntityInWorld(entityfreshrocket);
–stack.stackSize;
return stack;
}
}
Classe de l'entité :
java
package fr.freshblock.freshrocket.entity.projectile;import java.util.List;
import cpw.mods.fml.common.registry.EntityRegistry;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IProjectile;
import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.IProgressUpdate;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;public class EntityFreshRocket extends Entity
{
private int xTile = -1;
private int yTile = -1;
private int zTile = -1;
private Block inTile;
private int ticksAlive;
private int inData;
private boolean inGround; // Dans un bloc ou pas
public int arrowShake;
public Entity shootingEntity; // Le joueur qui a tiré le projectile
private int ticksInGround; // Je pense que c’est clair
private int ticksInAir; // Je pense que c’est clair également
private double damage = 6.0D; // Dégats du projectile
private int knockbackStrength; // Puissance du knockback
public int canBePickedUp;public double accelerationX;
public double accelerationY;
public double accelerationZ;@Override
protected void entityInit()
{}
@Override
protected void readEntityFromNBT(NBTTagCompound p_70037_1_)
{}
@Override
protected void writeEntityToNBT(NBTTagCompound p_70014_1_)
{}
public void setThrowableHeading(double p_70186_1_, double x, double y, float z, float p_70186_8_)
{
this.renderDistanceWeight = 10.0D;
this.setSize(0.5F, 0.5F);
this.setPosition(x, y, z);
this.yOffset = 0.0F;}
public EntityFreshRocket(World worldIn)
{
super(worldIn);
this.renderDistanceWeight = 10.0D; // Si je comprend bien, la distance
// du render de la flèche
this.setSize(0.5F, 0.5F); // taille du projectile
}public EntityFreshRocket(World worldIn, double x, double y, double z)
{
super(worldIn);
this.renderDistanceWeight = 10.0D; // Pareil qu’au dessus
this.setSize(0.5F, 0.5F); // Pareil qu’au dessus
this.setPosition(x, y, z); // La position du projectile
this.motionX = this.motionY = this.motionZ = 0.0D;
x += this.rand.nextGaussian() * 0.4D;
y += this.rand.nextGaussian() * 0.4D;
z += this.rand.nextGaussian() * 0.4D;
double d3 = (double)MathHelper.sqrt_double(x * x + y * y + z * z);
this.accelerationX = x / d3 * 0.1D;
this.accelerationY = y / d3 * 0.1D;
this.accelerationZ = z / d3 * 0.1D;
}public EntityFreshRocket(World worldIn, EntityLivingBase shooter, EntityLivingBase p_i1755_3_, float p_i1755_4_, float p_i1755_5_)
{
super(worldIn);
this.renderDistanceWeight = 10.0D; // Toujours pareil
this.shootingEntity = shooter; // Qui a tiré le projectileif(shooter instanceof EntityPlayer)
{
this.canBePickedUp = 0; // Si le tireur peut ramasser le projectile
}
}public EntityFreshRocket(World worldIn, EntityLivingBase shooter, float p_i1756_3_) // Quasiment la mème qu’au dessus
{
super(worldIn);
this.renderDistanceWeight = 10.0D;
this.shootingEntity = shooter;if(shooter instanceof EntityPlayer)
{
this.canBePickedUp = 0;
}
}protected void onImpact(MovingObjectPosition EntityFreshRocket)
{
if(EntityFreshRocket.typeOfHit == MovingObjectType.BLOCK)
{
switch(EntityFreshRocket.sideHit)
{
case 0: //BOTTOM
EntityFreshRocket.blockY–;
case 1: //TOP
EntityFreshRocket.blockY++;
break;
case 2: //EAST
EntityFreshRocket.blockZ–;
break;
case 3: //WEST
EntityFreshRocket.blockZ++;
break;
case 4: //NORTH
EntityFreshRocket.blockX–;
break;
case 5: //SOUTH
EntityFreshRocket.blockX++;
break;
}this.worldObj.spawnParticle(“largeexplode”, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
}
if(!this.worldObj.isRemote)
{
this.worldObj.newExplosion(this, EntityFreshRocket.blockX, EntityFreshRocket.blockY, EntityFreshRocket.blockZ, 2F, false, true);
this.setDead();
}if (this.ticksInAir == 20 || !this.worldObj.isRemote && (this.shootingEntity != null && this.shootingEntity.isDead || !this.worldObj.blockExists((int)this.posX, (int)this.posY, (int)this.posZ)))
{
this.setDead();
}
else
{
super.onUpdate();if (this.inGround)
{
if (this.worldObj.getBlock(arrowShake, arrowShake, arrowShake) == this.inTile)
{
++this.ticksAlive;if (this.ticksAlive == 20)
{
this.setDead();
}
return;
}this.inGround = false;
this.ticksAlive = 0;
this.ticksInAir = 0;
}
else
{
++this.ticksInAir;
}Vec3 vec3 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ);
Vec3 vec31 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
MovingObjectPosition movingobjectposition = this.worldObj.rayTraceBlocks(vec3, vec31);
vec3 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ);
vec31 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);if (movingobjectposition != null)
{
vec31 = Vec3.createVectorHelper(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord);
}Entity entity = null;
List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox);
double d0 = 0.0D;for (int i = 0; i < list.size(); ++i)
{
Entity entity1 = (Entity)list.get(i);if (entity1.canBeCollidedWith() && (!entity1.isEntityEqual(this.shootingEntity) || this.ticksInAir >= 25))
{
float f = 0.3F;
AxisAlignedBB axisalignedbb = entity1.boundingBox.expand((double)f, (double)f, (double)f);
MovingObjectPosition movingobjectposition1 = axisalignedbb.calculateIntercept(vec3, vec31);if (movingobjectposition1 != null)
{
double d1 = vec3.distanceTo(movingobjectposition1.hitVec);if (d1 < d0 || d0 == 0.0D)
{
entity = entity1;
d0 = d1;
}
}
}
}if (entity != null)
{
movingobjectposition = new MovingObjectPosition(entity);
}if (movingobjectposition != null)
{
this.onImpact(movingobjectposition);
}this.posX += this.motionX;
this.posY += this.motionY;
this.posZ += this.motionZ;if (this.isInWater())
{
for (int j = 0; j < 4; ++j)
{
float f3 = 0.25F;
this.worldObj.spawnParticle(“bubble”, this.posX, this.posY, this.posZ, this.motionX, this.motionY, this.motionZ);
}
}
this.worldObj.spawnParticle(“smoke”, this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
this.setPosition(this.posX, this.posY, this.posZ);
}
for (int k = 0; k < 10; ++k)
{
if (k == 10)
{
this.setDead();
}
}
}
} -
Up j’ai résolu le problème de direction car si on regarde bien la classe BehaviorDefault aux lignes 41 - 45 les vecteurs y et z étaient inversés x).
Mais le problème de rendu est toujours d’actualité -
Je UP le post
-
Doucement, c’est 24h avant de up normalement. J’avais même pas vu pour les directions x)
Je vais regarder pour le rendu cette après-midi.
Bon, ton code était une vrai horreur.
J’ai changé pas mal de chose. -
OK mdr désolé pour le carnage x) MERCI beaucoup robin maintenant j’ai un rendu en jeu!