提供: defeatedcrow mod wiki
Defeatedcrow (トーク | 投稿記録) (ページの作成:「=EntityFlame.class= <source lang="java"> package defeatedcrow.flamethrower.entity; import java.util.ArrayList; import java.util.List; import net.minecraft.block.Block;...」) |
Defeatedcrow (トーク | 投稿記録) |
||
(同じ利用者による、間の3版が非表示) | |||
1行目: | 1行目: | ||
+ | [[弾エンティティを作ってみる|Entity作成に戻る]] | ||
+ | |||
=EntityFlame.class= | =EntityFlame.class= | ||
36行目: | 38行目: | ||
import cpw.mods.fml.relauncher.SideOnly; | import cpw.mods.fml.relauncher.SideOnly; | ||
import defeatedcrow.flamethrower.FlameCore; | import defeatedcrow.flamethrower.FlameCore; | ||
− | |||
public class EntityFlame extends Entity implements IProjectile { | public class EntityFlame extends Entity implements IProjectile { | ||
185行目: | 186行目: | ||
if (livingTimeCount > 60) | if (livingTimeCount > 60) | ||
this.setDead(); | this.setDead(); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
// 激突したブロックを確認している | // 激突したブロックを確認している | ||
+ | // xyzTileには、前回処理時に当たったBlockの座標が記録されているので、継続して埋まったままか確認している。 | ||
Block i = this.worldObj.getBlock(this.xTile, this.yTile, this.zTile); | Block i = this.worldObj.getBlock(this.xTile, this.yTile, this.zTile); | ||
boolean air = this.worldObj.isAirBlock(xTile, yTile, zTile); | boolean air = this.worldObj.isAirBlock(xTile, yTile, zTile); | ||
− | // | + | // 空気じゃないブロックだった時(継続して埋まっている) |
if (i != null && i.getMaterial() != Material.air) { | if (i != null && i.getMaterial() != Material.air) { | ||
+ | // 非固形ブロックなど、当たり判定が立方体でないブロックのAABBに接触しているかチェックしている | ||
i.setBlockBoundsBasedOnState(this.worldObj, this.xTile, this.yTile, this.zTile); | i.setBlockBoundsBasedOnState(this.worldObj, this.xTile, this.yTile, this.zTile); | ||
AxisAlignedBB axisalignedbb = i.getCollisionBoundingBoxFromPool(this.worldObj, this.xTile, this.yTile, | AxisAlignedBB axisalignedbb = i.getCollisionBoundingBoxFromPool(this.worldObj, this.xTile, this.yTile, | ||
207行目: | 202行目: | ||
if (axisalignedbb != null | if (axisalignedbb != null | ||
&& axisalignedbb.isVecInside(Vec3.createVectorHelper(this.posX, this.posY, this.posZ))) { | && axisalignedbb.isVecInside(Vec3.createVectorHelper(this.posX, this.posY, this.posZ))) { | ||
+ | // 埋まり判定をtrueに | ||
this.inGround = true; | this.inGround = true; | ||
} | } | ||
223行目: | 219行目: | ||
++this.ticksInGround; | ++this.ticksInGround; | ||
// ブロック貫通の場合、20tick(1秒間)はブロック中にあっても消えないようになる。 | // ブロック貫通の場合、20tick(1秒間)はブロック中にあっても消えないようになる。 | ||
− | int limit = | + | int limit = 20; |
if (this.ticksInGround > limit) { | if (this.ticksInGround > limit) { | ||
234行目: | 230行目: | ||
this.ticksInAir = 0; | this.ticksInAir = 0; | ||
} | } | ||
− | } else// 埋まってない時。速度の更新。 | + | } else { |
− | + | // 埋まってない時。速度の更新。 | |
+ | |||
++this.ticksInAir; | ++this.ticksInAir; | ||
// ブロックとの衝突判定 | // ブロックとの衝突判定 | ||
245行目: | 242行目: | ||
vec31 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ | vec31 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ | ||
+ this.motionZ); | + this.motionZ); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
// ブロックに当たった | // ブロックに当たった | ||
258行目: | 250行目: | ||
// Entityとの衝突判定。 | // Entityとの衝突判定。 | ||
+ | // コンストラクタで入れたrangeの分だけ当たり判定を拡大し、接触しているEntityのリストを得ます。 | ||
List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, | List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, | ||
this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(range, range, range)); | this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(range, range, range)); | ||
267行目: | 260行目: | ||
// 1ブロック分の範囲内にいるエンティティ全てに対して繰り返す | // 1ブロック分の範囲内にいるエンティティ全てに対して繰り返す | ||
+ | // ここは、EntityArrowでは一体だけに対象を絞っているが、このMODでは全てを対象に取る | ||
for (l = 0; l < list.size(); ++l) { | for (l = 0; l < list.size(); ++l) { | ||
Entity entity1 = (Entity) list.get(l); | Entity entity1 = (Entity) list.get(l); | ||
Entity entity = null; | Entity entity = null; | ||
− | // | + | // 自傷防止のため、発射物自身or発射後5tick以外だとすりぬける |
if (entity1.canBeCollidedWith() && entity1 != this.shootingEntity) { | if (entity1.canBeCollidedWith() && entity1 != this.shootingEntity) { | ||
f1 = 0.5F; | f1 = 0.5F; | ||
295行目: | 289行目: | ||
*/ | */ | ||
if (entityList != null && !entityList.isEmpty()) { | if (entityList != null && !entityList.isEmpty()) { | ||
+ | // リストを回す | ||
for (int n = 0; n < entityList.size(); n++) { | for (int n = 0; n < entityList.size(); n++) { | ||
Entity target = entityList.get(n).entityHit; | Entity target = entityList.get(n).entityHit; | ||
314行目: | 309行目: | ||
} | } | ||
− | |||
float f3; | float f3; | ||
322行目: | 316行目: | ||
for (MovingObjectPosition target : entityList) { | for (MovingObjectPosition target : entityList) { | ||
if (target != null && target.entityHit != null) { | if (target != null && target.entityHit != null) { | ||
− | |||
− | |||
− | |||
// ダメージは固定 | // ダメージは固定 | ||
int i1 = MathHelper.ceiling_double_int(this.damage); | int i1 = MathHelper.ceiling_double_int(this.damage); | ||
// 0~2程度の乱数値を上乗せ | // 0~2程度の乱数値を上乗せ | ||
i1 += this.rand.nextInt(3); | i1 += this.rand.nextInt(3); | ||
− | + | // 別メソッドでダメージソースを確認 …ここでは、仮としてLavaに固定にしている | |
− | + | DamageSource damagesource = this.thisDamageSource(this.shootingEntity); | |
− | + | ||
− | // 別メソッドでダメージソースを確認 | + | |
− | damagesource = this.thisDamageSource(this.shootingEntity); | + | |
if (target.entityHit instanceof IProjectile && !(target.entityHit instanceof EntityFlame)) { | if (target.entityHit instanceof IProjectile && !(target.entityHit instanceof EntityFlame)) { | ||
340行目: | 328行目: | ||
} else { | } else { | ||
+ | // ダメージを与える | ||
if (target.entityHit.attackEntityFrom(damagesource, i1)) { | if (target.entityHit.attackEntityFrom(damagesource, i1)) { | ||
// ダメージを与えることに成功したら以下の処理を行う | // ダメージを与えることに成功したら以下の処理を行う | ||
345行目: | 334行目: | ||
EntityLivingBase living = (EntityLivingBase) target.entityHit; | EntityLivingBase living = (EntityLivingBase) target.entityHit; | ||
− | // | + | // 腐食による弱体化potion付与 |
if (this.isCorrosion) { | if (this.isCorrosion) { | ||
living.addPotionEffect(new PotionEffect(Potion.weakness.getId(), 200, 0)); | living.addPotionEffect(new PotionEffect(Potion.weakness.getId(), 200, 0)); | ||
371行目: | 360行目: | ||
} | } | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
381行目: | 366行目: | ||
} | } | ||
− | if (movingobjectposition != null)// | + | if (movingobjectposition != null)// blockの接触判定をとっておいたのをここで処理 |
{ | { | ||
+ | // 当たったブロックを記憶し、次Tickで上の方の埋まり判定に使う | ||
this.xTile = movingobjectposition.blockX; | this.xTile = movingobjectposition.blockX; | ||
this.yTile = movingobjectposition.blockY; | this.yTile = movingobjectposition.blockY; | ||
392行目: | 378行目: | ||
this.inTile.onEntityCollidedWithBlock(this.worldObj, this.xTile, this.yTile, this.zTile, this); | this.inTile.onEntityCollidedWithBlock(this.worldObj, this.xTile, this.yTile, this.zTile, this); | ||
+ | // 腐食属性の時 configでONならブロック破壊効果を起こす | ||
if (this.isCorrosion && FlameCore.meltBlock) { | if (this.isCorrosion && FlameCore.meltBlock) { | ||
if (inTile == Blocks.stone) { | if (inTile == Blocks.stone) { | ||
403行目: | 390行目: | ||
} | } | ||
+ | // フレイムエンチャント時にWood属性のブロックを破壊 | ||
if (this.isFire && FlameCore.meltBlock) { | if (this.isFire && FlameCore.meltBlock) { | ||
if (inTile instanceof BlockLeavesBase || inTile instanceof BlockBush) { | if (inTile instanceof BlockLeavesBase || inTile instanceof BlockBush) { | ||
418行目: | 406行目: | ||
} | } | ||
} | } | ||
+ | // 原木を破壊した時に木炭をドロップさせている | ||
if (b && !worldObj.isRemote) { | if (b && !worldObj.isRemote) { | ||
ItemStack c = new ItemStack(Items.coal, 1, 1); | ItemStack c = new ItemStack(Items.coal, 1, 1); | ||
432行目: | 421行目: | ||
} | } | ||
} | } | ||
− | } else { | + | } else { // どうもmovingobjectpositionで取りこぼすようなので、nullの場合も同じ事をしている。ひょっとしてすごく無駄なことしているのでは… |
+ | |||
+ | // inTile(埋まり判定)は更新しない。 | ||
int tarX = MathHelper.floor_double(this.posX); | int tarX = MathHelper.floor_double(this.posX); | ||
int tarY = MathHelper.floor_double(this.posY); | int tarY = MathHelper.floor_double(this.posY); | ||
439行目: | 430行目: | ||
if (target != null && target.getMaterial() != Material.air) { | if (target != null && target.getMaterial() != Material.air) { | ||
+ | // 上の処理より出来ることを少なめにしていたりする | ||
if (this.isCorrosion && FlameCore.meltBlock) { | if (this.isCorrosion && FlameCore.meltBlock) { | ||
if (inTile == Blocks.stone) { | if (inTile == Blocks.stone) { | ||
454行目: | 446行目: | ||
} | } | ||
} | } | ||
+ | // あらゆるブロックに着火 | ||
if (worldObj.isAirBlock(tarX, tarY + 1, tarZ) | if (worldObj.isAirBlock(tarX, tarY + 1, tarZ) | ||
/* && target.isFlammable(worldObj, tarX, tarY, tarZ, ForgeDirection.UP) */) { | /* && target.isFlammable(worldObj, tarX, tarY, tarZ, ForgeDirection.UP) */) { | ||
586行目: | 579行目: | ||
/* ダメージソースのタイプ */ | /* ダメージソースのタイプ */ | ||
public DamageSource thisDamageSource(Entity entity) { | public DamageSource thisDamageSource(Entity entity) { | ||
− | |||
− | |||
− | |||
− | |||
− | |||
return isCorrosion ? DamageSource.onFire : DamageSource.lava; | return isCorrosion ? DamageSource.onFire : DamageSource.lava; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
</source> | </source> |
2016年3月6日 (日) 14:10時点における最新版
EntityFlame.class
package defeatedcrow.flamethrower.entity; import java.util.ArrayList; import java.util.List; import net.minecraft.block.Block; import net.minecraft.block.BlockBush; import net.minecraft.block.BlockLeavesBase; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IProjectile; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.play.server.S2BPacketChangeGameState; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.oredict.OreDictionary; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import defeatedcrow.flamethrower.FlameCore; public class EntityFlame extends Entity implements IProjectile { /* 地中判定に使うもの */ protected int xTile = -1; protected int yTile = -1; protected int zTile = -1; protected Block inTile; protected int inData; protected boolean inGround; /* この弾を撃ったエンティティ */ public Entity shootingEntity; /* 地中・空中にいる時間 */ protected int ticksInGround; protected int ticksInAir; protected int livingTimeCount = 0; /* ダメージの大きさ */ protected final double damage; /* 前進速度 */ protected double speed = 1.0D; /* 幅 */ protected final double range; /* ノックバックの大きさ */ protected final int coolTime; protected boolean isCorrosion = false; protected boolean isFire = false; public EntityFlame(World par1World) { super(par1World); this.renderDistanceWeight = 10.0D; this.setSize(0.5F, 0.5F); this.damage = 10.0D; this.range = 4.0D; this.coolTime = 10; } public EntityFlame(World par1World, float size, double thisdamage, double thisrange, int thisCoolTime) { super(par1World); this.renderDistanceWeight = 10.0D; this.setSize(size, size); this.range = thisrange; this.damage = thisdamage; this.coolTime = thisCoolTime; } public EntityFlame(World par1World, EntityLivingBase par2EntityLivingBase, float speed, float speed2, double damage, double range, int cool) { this(par1World, 0.5F, damage, range, cool); this.renderDistanceWeight = 10.0D; this.shootingEntity = par2EntityLivingBase; this.yOffset = 0.0F; // 初期状態での向きの決定 this.setLocationAndAngles(par2EntityLivingBase.posX, par2EntityLivingBase.posY + par2EntityLivingBase.getEyeHeight() - 0.6D, par2EntityLivingBase.posZ, par2EntityLivingBase.rotationYaw, par2EntityLivingBase.rotationPitch); // 位置の調整 this.posX += (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI)); this.posZ += (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI)); this.setPosition(this.posX, this.posY, this.posZ); float f1 = worldObj.rand.nextFloat() * 0.1F - 0.05F; float f2 = worldObj.rand.nextFloat() * 0.1F - 0.05F; float f3 = worldObj.rand.nextFloat() * 0.1F - 0.05F; // 初速度 this.motionX = f1 + ((double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper .cos(this.rotationPitch / 180.0F * (float) Math.PI))); this.motionZ = f2 + ((double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper .cos(this.rotationPitch / 180.0F * (float) Math.PI))); this.motionY = f3 + ((double) (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI))); this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, speed, speed2); } @Override protected void entityInit() { } @Override public void setThrowableHeading(double par1, double par3, double par5, float par7, float par8) { float f2 = MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5); par1 /= f2; par3 /= f2; par5 /= f2; par1 += this.rand.nextGaussian() * (this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * par8; par3 += this.rand.nextGaussian() * (this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * par8; par5 += this.rand.nextGaussian() * (this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D * par8; par1 *= par7; par3 *= par7; par5 *= par7; this.motionX = par1; this.motionY = par3; this.motionZ = par5; float f3 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, f3) * 180.0D / Math.PI); this.ticksInGround = 0; } @Override @SideOnly(Side.CLIENT) public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { this.setPosition(par1, par3, par5); this.setRotation(par7, par8); } @Override @SideOnly(Side.CLIENT) public void setVelocity(double par1, double par3, double par5) { this.motionX = par1; this.motionY = par3; this.motionZ = par5; if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { float f = MathHelper.sqrt_double(par1 * par1 + par5 * par5); this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, f) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch; this.prevRotationYaw = this.rotationYaw; this.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); this.ticksInGround = 0; } } /* * Tick毎に呼ばれる更新処理。 * 速度の更新、衝突判定などをここで行う。 */ @Override public void onUpdate() { super.onUpdate(); livingTimeCount++; if (livingTimeCount > 60) this.setDead(); // 激突したブロックを確認している // xyzTileには、前回処理時に当たったBlockの座標が記録されているので、継続して埋まったままか確認している。 Block i = this.worldObj.getBlock(this.xTile, this.yTile, this.zTile); boolean air = this.worldObj.isAirBlock(xTile, yTile, zTile); // 空気じゃないブロックだった時(継続して埋まっている) if (i != null && i.getMaterial() != Material.air) { // 非固形ブロックなど、当たり判定が立方体でないブロックのAABBに接触しているかチェックしている i.setBlockBoundsBasedOnState(this.worldObj, this.xTile, this.yTile, this.zTile); AxisAlignedBB axisalignedbb = i.getCollisionBoundingBoxFromPool(this.worldObj, this.xTile, this.yTile, this.zTile); // 当たり判定に接触しているかどうか if (axisalignedbb != null && axisalignedbb.isVecInside(Vec3.createVectorHelper(this.posX, this.posY, this.posZ))) { // 埋まり判定をtrueに this.inGround = true; } } // 空気じゃないブロックに当たった if (this.inGround) { Block j = this.worldObj.getBlock(this.xTile, this.yTile, this.zTile); int k = this.worldObj.getBlockMetadata(this.xTile, this.yTile, this.zTile); /* * 前のTickに確認した埋まりブロックのIDとメタを照合している。違ったら埋まり状態を解除、一致したら埋まり状態を継続。 * /* 埋まり状態2tick継続でこのエンティティを消す */ if (j == this.inTile && k == this.inData) { ++this.ticksInGround; // ブロック貫通の場合、20tick(1秒間)はブロック中にあっても消えないようになる。 int limit = 20; if (this.ticksInGround > limit) { this.setDead(); } } else// 埋まり状態の解除処理 { this.inGround = false; this.ticksInGround = 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.func_147447_a(vec3, vec31, false, true, false); 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との衝突判定。 // コンストラクタで入れたrangeの分だけ当たり判定を拡大し、接触しているEntityのリストを得ます。 List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(range, range, range)); double d0 = 0.0D; int l; float f1; boolean isVillager = false; ArrayList<MovingObjectPosition> entityList = new ArrayList<MovingObjectPosition>(); // 1ブロック分の範囲内にいるエンティティ全てに対して繰り返す // ここは、EntityArrowでは一体だけに対象を絞っているが、このMODでは全てを対象に取る for (l = 0; l < list.size(); ++l) { Entity entity1 = (Entity) list.get(l); Entity entity = null; // 自傷防止のため、発射物自身or発射後5tick以外だとすりぬける if (entity1.canBeCollidedWith() && entity1 != this.shootingEntity) { f1 = 0.5F; // 上下方向は広めに見る AxisAlignedBB axisalignedbb1 = entity1.boundingBox.expand(f1, 1.0F, f1); MovingObjectPosition movingobjectposition1 = axisalignedbb1.calculateIntercept(vec3, vec31); if (movingobjectposition1 != null) { double d1 = vec3.distanceTo(movingobjectposition1.hitVec); if (d1 < d0 || d0 == 0.0D) { // arrowと異なり、あたったEntityすべてをリストに入れる entityList.add(new MovingObjectPosition(entity1)); d0 = d1; } } } } /* * 当たったエンティティそれそれについての判定部分。 * ここで特定の種類のエンティティに当たらないようにできる。 */ if (entityList != null && !entityList.isEmpty()) { // リストを回す for (int n = 0; n < entityList.size(); n++) { Entity target = entityList.get(n).entityHit; if (target instanceof EntityPlayer) { // プレイヤーに当たった時 EntityPlayer entityplayer = (EntityPlayer) target; if (entityplayer.capabilities.disableDamage || this.shootingEntity instanceof EntityPlayer && !((EntityPlayer) this.shootingEntity).canAttackPlayer(entityplayer)) { // PvPが許可されていないと当たらない entityList.remove(n); } } else if (target == this.shootingEntity) { // 対象が撃った本人の場合も当たらない entityList.remove(n); } } } float f3; // 当たったあとの処理 // まずはリストから if (entityList != null && !entityList.isEmpty()) { for (MovingObjectPosition target : entityList) { if (target != null && target.entityHit != null) { // ダメージは固定 int i1 = MathHelper.ceiling_double_int(this.damage); // 0~2程度の乱数値を上乗せ i1 += this.rand.nextInt(3); // 別メソッドでダメージソースを確認 …ここでは、仮としてLavaに固定にしている DamageSource damagesource = this.thisDamageSource(this.shootingEntity); if (target.entityHit instanceof IProjectile && !(target.entityHit instanceof EntityFlame)) { // 対象が矢などの飛翔Entityの場合、打ち消すことが出来る target.entityHit.setDead(); } else { // ダメージを与える if (target.entityHit.attackEntityFrom(damagesource, i1)) { // ダメージを与えることに成功したら以下の処理を行う if (target.entityHit instanceof EntityLivingBase) { EntityLivingBase living = (EntityLivingBase) target.entityHit; // 腐食による弱体化potion付与 if (this.isCorrosion) { living.addPotionEffect(new PotionEffect(Potion.weakness.getId(), 200, 0)); } // 着火 if (this.isFire) { // 着火はせず、アマ貫の炎属性ダメージが入る living.attackEntityFrom(DamageSource.onFire, 1.0F); } // 無敵時間 if (this.coolTime > 0) { target.entityHit.hurtResistantTime = coolTime; } else { target.entityHit.hurtResistantTime = 0; } // マルチプレイ時に、両者がプレイヤーだった時のパケット送信処理 if (this.shootingEntity != null && target.entityHit != this.shootingEntity && target.entityHit instanceof EntityPlayer && this.shootingEntity instanceof EntityPlayerMP) { ((EntityPlayerMP) this.shootingEntity).playerNetServerHandler .sendPacket(new S2BPacketChangeGameState(6, 0.0F)); } } } } } } } if (movingobjectposition != null)// blockの接触判定をとっておいたのをここで処理 { // 当たったブロックを記憶し、次Tickで上の方の埋まり判定に使う this.xTile = movingobjectposition.blockX; this.yTile = movingobjectposition.blockY; this.zTile = movingobjectposition.blockZ; this.inTile = this.worldObj.getBlock(this.xTile, this.yTile, this.zTile); this.inData = this.worldObj.getBlockMetadata(this.xTile, this.yTile, this.zTile); if (this.inTile != null) { this.inTile.onEntityCollidedWithBlock(this.worldObj, this.xTile, this.yTile, this.zTile, this); // 腐食属性の時 configでONならブロック破壊効果を起こす if (this.isCorrosion && FlameCore.meltBlock) { if (inTile == Blocks.stone) { this.worldObj.setBlock(xTile, yTile, zTile, Blocks.cobblestone); } else if (inTile == Blocks.grass) { this.worldObj.setBlock(xTile, yTile, zTile, Blocks.dirt); } else if (inTile == Blocks.cobblestone || inTile == Blocks.dirt || inTile == Blocks.gravel || inTile == Blocks.sand) { this.worldObj.setBlockToAir(xTile, yTile, zTile); } } // フレイムエンチャント時にWood属性のブロックを破壊 if (this.isFire && FlameCore.meltBlock) { if (inTile instanceof BlockLeavesBase || inTile instanceof BlockBush) { this.worldObj.setBlockToAir(xTile, yTile, zTile); } else if (inTile.getMaterial() == Material.wood) { this.worldObj.setBlockToAir(xTile, yTile, zTile); boolean b = false; ArrayList<ItemStack> ores = OreDictionary.getOres("logWood"); for (ItemStack log : ores) { if (log == null || log.getItem() == null) continue; if (log.getItem() == Item.getItemFromBlock(inTile)) { b = true; break; } } // 原木を破壊した時に木炭をドロップさせている if (b && !worldObj.isRemote) { ItemStack c = new ItemStack(Items.coal, 1, 1); EntityItem drop = new EntityItem(worldObj, xTile, yTile, zTile, c); worldObj.spawnEntityInWorld(drop); } } else if (inTile.getMaterial() == Material.snow || inTile.getMaterial() == Material.ice) { this.worldObj.setBlockToAir(xTile, yTile, zTile); } if (worldObj.isAirBlock(xTile, yTile + 1, zTile) && inTile.isFlammable(worldObj, xTile, yTile, zTile, ForgeDirection.UP)) { worldObj.setBlock(xTile, yTile + 1, zTile, Blocks.fire); } } } } else { // どうもmovingobjectpositionで取りこぼすようなので、nullの場合も同じ事をしている。ひょっとしてすごく無駄なことしているのでは… // inTile(埋まり判定)は更新しない。 int tarX = MathHelper.floor_double(this.posX); int tarY = MathHelper.floor_double(this.posY); int tarZ = MathHelper.floor_double(this.posZ); Block target = worldObj.getBlock(tarX, tarY, tarZ); if (target != null && target.getMaterial() != Material.air) { // 上の処理より出来ることを少なめにしていたりする if (this.isCorrosion && FlameCore.meltBlock) { if (inTile == Blocks.stone) { this.worldObj.setBlock(xTile, yTile, zTile, Blocks.cobblestone); } else if (inTile == Blocks.grass) { this.worldObj.setBlock(xTile, yTile, zTile, Blocks.dirt); } } if (this.isFire) { if (FlameCore.meltBlock) { if (inTile instanceof BlockLeavesBase || inTile instanceof BlockBush) { this.worldObj.setBlockToAir(xTile, yTile, zTile); } else if (target.getMaterial() == Material.snow || target.getMaterial() == Material.ice) { this.worldObj.setBlockToAir(tarX, tarY, tarZ); } } // あらゆるブロックに着火 if (worldObj.isAirBlock(tarX, tarY + 1, tarZ) /* && target.isFlammable(worldObj, tarX, tarY, tarZ, ForgeDirection.UP) */) { worldObj.setBlock(tarX, tarY + 1, tarZ, Blocks.fire); } } } } } // 改めてポジションに速度を加算。向きも更新。 this.posX += this.motionX; this.posY += this.motionY; this.posZ += this.motionZ; float f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); this.rotationPitch = (float) (Math.atan2(this.motionY, f2) * 180.0D / Math.PI); while (this.rotationPitch - this.prevRotationPitch < -180.0F) { this.prevRotationPitch -= 360.0F; } while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { this.prevRotationPitch += 360.0F; } while (this.rotationYaw - this.prevRotationYaw < -180.0F) { this.prevRotationYaw -= 360.0F; } while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { this.prevRotationYaw += 360.0F; } this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; // 徐々に減速する float f4 = 0.9F; // 水中に有る if (this.isInWater()) { if (this.isBurning()) { this.extinguish(); } // // 泡パーティクルが出る // for (int j1 = 0; j1 < 4; ++j1) { // float f3 = 0.25F; // this.worldObj.spawnParticle("bubble", this.posX - this.motionX * f3, this.posY - // this.motionY * f3, // this.posZ - this.motionZ * f3, this.motionX, this.motionY, this.motionZ); // } // 減速も大きくなる f4 = 0.1F; } this.motionX *= f4; this.motionY *= f4; this.motionZ *= f4; // 一定以上遅くなったら消える if (this.worldObj.isRemote && (this.motionX * this.motionX + this.motionZ * this.motionZ) < 0.001D) { this.setDead(); } this.setPosition(this.posX, this.posY, this.posZ); this.func_145775_I(); } @Override public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { par1NBTTagCompound.setShort("xTile", (short) this.xTile); par1NBTTagCompound.setShort("yTile", (short) this.yTile); par1NBTTagCompound.setShort("zTile", (short) this.zTile); par1NBTTagCompound.setByte("inTile", (byte) Block.getIdFromBlock(this.inTile)); par1NBTTagCompound.setByte("inData", (byte) this.inData); par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); } /* * (abstract) Protected helper method to read subclass entity data from NBT. */ @Override public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { this.xTile = par1NBTTagCompound.getShort("xTile"); this.yTile = par1NBTTagCompound.getShort("yTile"); this.zTile = par1NBTTagCompound.getShort("zTile"); this.inTile = Block.getBlockById(par1NBTTagCompound.getByte("inTile") & 255); this.inData = par1NBTTagCompound.getByte("inData") & 255; this.inGround = par1NBTTagCompound.getByte("inGround") == 1; } @Override protected boolean canTriggerWalking() { return false; } @Override @SideOnly(Side.CLIENT) public float getShadowSize() { return 0.0F; } @Override public boolean canAttackWithItem() { return false; } /* 落下速度 */ public float fallSpeed() { return 0.0F; } public void setCorrosion(boolean b) { this.isCorrosion = b; } public boolean getCorrosion() { return this.isCorrosion; } public void setAdvFire(boolean b) { this.isFire = b; } public boolean getAdvFire() { return this.isFire; } /* ダメージソースのタイプ */ public DamageSource thisDamageSource(Entity entity) { return isCorrosion ? DamageSource.onFire : DamageSource.lava; } }