【解決済】【1.11.2】Mobからの発射体(Entityのスポーン)について

Modding・サーバPlugin制作・ツール制作など、開発関連の質問があればこちらにお願い致します。
フォーラムルール
質問関連フォーラムで質問する時は、必ず次のトピックを一読/厳守お願い致します。
viewtopic.php?f=5&t=999
  • (PostNo.304390)

【解決済】【1.11.2】Mobからの発射体(Entityのスポーン)について

投稿記事by Velc » 2017年7月05日(水) 14:24

FlyingCrystalというMobを作成して、LaserというEntityをスポーンさせようとしたいのですが、
Laserクラスの初期化の時点でエラーを吐いてクラッシュしてしまいます。
ブレイズのEntityのソースを元にAIを実装したのですが、うまく動きません。
LaserのソースはFireBallのEntityのソースを元にしています。
解決策がわかる方ご教授ください。

FlyingCrystal.java(Entity)
コード: 全て選択
package velc.mandw.entity.mobs;

import net.minecraft.block.Block;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.pathfinding.PathNodeType;
import net.minecraft.world.World;
import velc.mandw.ai.FlyingCrystalAI;

public class FlyingCrystal extends EntityMob{
   
   public FlyingCrystal(World world) {
      super(world);
      this.setPathPriority(PathNodeType.DANGER_FIRE, 0.0F);
      this.setPathPriority(PathNodeType.DAMAGE_FIRE, 0.0F);
      this.isImmuneToFire = true;

      this.tasks.addTask(4, new FlyingCrystalAI.AILaserAttack(this));
      this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 0.5D));
      this.tasks.addTask(7, new EntityAIWanderAvoidWater(this, 1.0D, 0.0F));
        this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
        this.tasks.addTask(8, new EntityAILookIdle(this));
        this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true, new Class[0]));
        this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, true));
        }
   
   
    public boolean isAIEnabled() { return true; }

    public boolean isCollidead(){return true;}
   
//    public String getLivingSound() { return /* MOBが生きている時の音のファイルパスを返す。 */ ; }
 
//    public SoundEvent getHurtSound() { return /* MOBがダメージを受けた時の音のファイルパスを返す。 */ ; }
 
//    public SoundEvent getDeathSound() { return /* MOBが死亡した時の音のファイルパスを返す。*/ ; }
 
    /*
    * このMobが動いているときの音のファイルパスを返す.
    * 引数のblockはMobの下にあるBlock.
    */
    protected void func_145780_a(int x, int y, int z, Block block)
    {
       //this.playSound("mob.skeleton.step", 0.15F, 1.0F);
    }
 
@Override
    public EnumCreatureAttribute getCreatureAttribute() { return EnumCreatureAttribute.UNDEFINED; }
 
    //@Override
    //public Item getDropItem() { return /* ドロップするアイテム */ ; }
}


FlyingcCrystalAI.java (ブレイズのAIのほぼコピペ)
コード: 全て選択
package velc.mandw.ai;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import velc.mandw.entity.mobs.FlyingCrystal;
import velc.mandw.entity.object.Laser;


public class FlyingCrystalAI {
   
    public static class AILaserAttack extends EntityAIBase
    {
        private final FlyingCrystal fc;
        private int attackStep;
        private int attackTime;

        public AILaserAttack(FlyingCrystal fcIn)
        {
            this.fc = fcIn;
            this.setMutexBits(3);
        }

        /**
         * Returns whether the EntityAIBase should begin execution.
         */
        public boolean shouldExecute()
        {
            EntityLivingBase entitylivingbase = this.fc.getAttackTarget();
//System.out.println("entitylivingbase:"+entitylivingbase);
            return entitylivingbase != null && entitylivingbase.isEntityAlive();
        }

        /**
         * Execute a one shot task or start executing a continuous task
         */
        public void startExecuting()
        {
            this.attackStep = 0;
        }

        /**
         * Resets the task
         */
        public void resetTask()
        {
        }

        /**
         * Updates the task
         */
        public void updateTask()
        {
            --this.attackTime;
            EntityLivingBase entitylivingbase = this.fc.getAttackTarget();
            double d0 = this.fc.getDistanceSqToEntity(entitylivingbase);

            if (d0 < 4.0D)
            {
                if (this.attackTime <= 0)
                {
                    this.attackTime = 20;
                    this.fc.attackEntityAsMob(entitylivingbase);
                }

                this.fc.getMoveHelper().setMoveTo(entitylivingbase.posX, entitylivingbase.posY, entitylivingbase.posZ, 1.0D);
            }
            else if (d0 < this.func_191523_f() * this.func_191523_f())
            {
                double d1 = entitylivingbase.posX - this.fc.posX;
                double d2 = entitylivingbase.getEntityBoundingBox().minY + (double)(entitylivingbase.height / 2.0F) - (this.fc.posY + (double)(this.fc.height / 2.0F));
                double d3 = entitylivingbase.posZ - this.fc.posZ;

                if (this.attackTime <= 0)
                {
                    ++this.attackStep;

                    if (this.attackStep == 1)
                    {
                        this.attackTime = 60;
                    }
                    else if (this.attackStep <= 4)
                    {
                        this.attackTime = 6;
                    }
                    else
                    {
                        this.attackTime = 100;
                        this.attackStep = 0;
                    }

                    if (this.attackStep > 1)
                    {
                        float f = MathHelper.sqrt(MathHelper.sqrt(d0)) * 0.5F;
                        this.fc.world.playEvent((EntityPlayer)null, 1018, new BlockPos((int)this.fc.posX, (int)this.fc.posY, (int)this.fc.posZ), 0);

                        for (int i = 0; i < 1; ++i)
                        {
System.out.println("world:"+this.fc.world);
                            Laser entitylaser = new Laser(this.fc.world, this.fc, d1 + this.fc.getRNG().nextGaussian() * (double)f, d2, d3 + this.fc.getRNG().nextGaussian() * (double)f);
                            entitylaser.posY = this.fc.posY + (double)(this.fc.height / 2.0F) + 0.5D;
                            this.fc.world.spawnEntity(entitylaser);
                        }
                    }
                }

                this.fc.getLookHelper().setLookPositionWithEntity(entitylivingbase, 10.0F, 10.0F);
            }
            else
            {
                this.fc.getNavigator().clearPathEntity();
                this.fc.getMoveHelper().setMoveTo(entitylivingbase.posX, entitylivingbase.posY, entitylivingbase.posZ, 1.0D);
            }

            super.updateTask();
        }

        private double func_191523_f()
        {
            IAttributeInstance iattributeinstance = this.fc.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE);
            return iattributeinstance == null ? 16.0D : iattributeinstance.getAttributeValue();
        }
    }
}


Laser.java (EntityFireBallのほぼコピペ)
コード: 全て選択
package velc.mandw.entity.object;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.projectile.ProjectileHelper;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class Laser extends EntityMob{
    public EntityLivingBase shootingEntity;
    private int ticksAlive;
    private int ticksInAir;
    public double accelerationX;
    public double accelerationY;
    public double accelerationZ;

   
    public Laser(World worldIn)
    {
        super(worldIn);
        this.setSize(1.0F, 1.0F);
       
       
    }

    protected void entityInit()
    {
    }

    /**
     * Checks if the entity is in range to render.
     */
    @SideOnly(Side.CLIENT)
    public boolean isInRangeToRenderDist(double distance)
    {
        double d0 = this.getEntityBoundingBox().getAverageEdgeLength() * 4.0D;

        if (Double.isNaN(d0))
        {
            d0 = 4.0D;
        }

        d0 = d0 * 64.0D;
        return distance < d0 * d0;
    }

    public Laser(World worldIn, double x, double y, double z, double accelX, double accelY, double accelZ)
    {
        super(worldIn);
        this.setSize(1.0F, 1.0F);
        this.setLocationAndAngles(x, y, z, this.rotationYaw, this.rotationPitch);
        this.setPosition(x, y, z);
        double d0 = (double)MathHelper.sqrt(accelX * accelX + accelY * accelY + accelZ * accelZ);
        this.accelerationX = accelX / d0 * 0.1D;
        this.accelerationY = accelY / d0 * 0.1D;
        this.accelerationZ = accelZ / d0 * 0.1D;
    }

    public Laser(World worldIn, EntityLivingBase shooter, double accelX, double accelY, double accelZ)
    {
        super(worldIn);
        this.shootingEntity = shooter;
        this.setSize(1.0F, 1.0F);
        this.setLocationAndAngles(shooter.posX, shooter.posY, shooter.posZ, shooter.rotationYaw, shooter.rotationPitch);
        this.setPosition(this.posX, this.posY, this.posZ);
        this.motionX = 0.0D;
        this.motionY = 0.0D;
        this.motionZ = 0.0D;
        accelX = accelX + this.rand.nextGaussian() * 0.4D;
        accelY = accelY + this.rand.nextGaussian() * 0.4D;
        accelZ = accelZ + this.rand.nextGaussian() * 0.4D;
        double d0 = (double)MathHelper.sqrt(accelX * accelX + accelY * accelY + accelZ * accelZ);
        this.accelerationX = accelX / d0 * 0.1D;
        this.accelerationY = accelY / d0 * 0.1D;
        this.accelerationZ = accelZ / d0 * 0.1D;
    }

    /**
     * Called to update the entity's position/logic.
     */
    public void onUpdate()
    {
        if (this.world.isRemote || (this.shootingEntity == null || !this.shootingEntity.isDead) && this.world.isBlockLoaded(new BlockPos(this)))
        {
            super.onUpdate();

            ++this.ticksInAir;
            RayTraceResult raytraceresult = ProjectileHelper.forwardsRaycast(this, true, this.ticksInAir >= 25, this.shootingEntity);

            if (raytraceresult != null)
            {
                this.onImpact(raytraceresult);
            }

            this.posX += this.motionX;
            this.posY += this.motionY;
            this.posZ += this.motionZ;
            ProjectileHelper.rotateTowardsMovement(this, 0.2F);
            float f = this.getMotionFactor();

            if (this.isInWater())
            {
                for (int i = 0; i < 4; ++i)
                {
                    float f1 = 0.25F;
                    this.world.spawnParticle(EnumParticleTypes.WATER_BUBBLE, this.posX - this.motionX * 0.25D, this.posY - this.motionY * 0.25D, this.posZ - this.motionZ * 0.25D, this.motionX, this.motionY, this.motionZ, new int[0]);
                }

                f = 0.8F;
            }

            this.motionX += this.accelerationX;
            this.motionY += this.accelerationY;
            this.motionZ += this.accelerationZ;
            this.motionX *= (double)f;
            this.motionY *= (double)f;
            this.motionZ *= (double)f;
            this.setPosition(this.posX, this.posY, this.posZ);
        }
        else
        {
            this.setDead();
        }
    }

    /**
     * Return the motion factor for this projectile. The factor is multiplied by the original motion.
     */
    protected float getMotionFactor()
    {
        return 0.95F;
    }

    /**
     * Called when this EntityFireball hits a block or entity.
     */
    protected void onImpact(RayTraceResult result)
    {
        if (!this.world.isRemote)
        {
            this.setDead();
        }
    }

    public static void registerLaser(DataFixer fixer, String name)
    {
        Laser.registerLaser(fixer, "laser");
    }

    /**
     * (abstract) Protected helper method to write subclass entity data to NBT.
     */
    public void writeEntityToNBT(NBTTagCompound compound)
    {
        compound.setTag("direction", this.newDoubleNBTList(new double[] {this.motionX, this.motionY, this.motionZ}));
        compound.setTag("power", this.newDoubleNBTList(new double[] {this.accelerationX, this.accelerationY, this.accelerationZ}));
        compound.setInteger("life", this.ticksAlive);
    }

    /**
     * (abstract) Protected helper method to read subclass entity data from NBT.
     */
    public void readEntityFromNBT(NBTTagCompound compound)
    {
        if (compound.hasKey("power", 9))
        {
            NBTTagList nbttaglist = compound.getTagList("power", 6);

            if (nbttaglist.tagCount() == 3)
            {
                this.accelerationX = nbttaglist.getDoubleAt(0);
                this.accelerationY = nbttaglist.getDoubleAt(1);
                this.accelerationZ = nbttaglist.getDoubleAt(2);
            }
        }

        this.ticksAlive = compound.getInteger("life");

        if (compound.hasKey("direction", 9) && compound.getTagList("direction", 6).tagCount() == 3)
        {
            NBTTagList nbttaglist1 = compound.getTagList("direction", 6);
            this.motionX = nbttaglist1.getDoubleAt(0);
            this.motionY = nbttaglist1.getDoubleAt(1);
            this.motionZ = nbttaglist1.getDoubleAt(2);
        }
        else
        {
            this.setDead();
        }
    }

    /**
     * Returns true if other Entities should be prevented from moving through this Entity.
     */
    public boolean canBeCollidedWith()
    {
        return true;
    }

    public float getCollisionBorderSize()
    {
        return 1.0F;
    }

    /**
     * Called when the entity is attacked.
     */
    public boolean attackEntityFrom(DamageSource source, float amount)
    {
        if (this.isEntityInvulnerable(source))
        {
            return false;
        }
        else
        {
            this.setBeenAttacked();

            if (source.getEntity() != null)
            {
                Vec3d vec3d = source.getEntity().getLookVec();

                if (vec3d != null)
                {
                    this.motionX = vec3d.xCoord;
                    this.motionY = vec3d.yCoord;
                    this.motionZ = vec3d.zCoord;
                    this.accelerationX = this.motionX * 0.1D;
                    this.accelerationY = this.motionY * 0.1D;
                    this.accelerationZ = this.motionZ * 0.1D;
                }

                if (source.getEntity() instanceof EntityLivingBase)
                {
                    this.shootingEntity = (EntityLivingBase)source.getEntity();
                }

                return true;
            }
            else
            {
                return false;
            }
        }
    }

    /**
     * Gets how bright this entity is.
     */
    public float getBrightness(float partialTicks)
    {
        return 1.0F;
    }
   
    @SideOnly(Side.CLIENT)
    public int getBrightnessForRender(float partialTicks)
    {
        return 15728880;
    }
   
}


クラッシュレポート
コード: 全て選択
---- Minecraft Crash Report ----
// Everything's going to plan. No, really, that was supposed to happen.

Time: 7/5/17 2:13 PM
Description: Ticking entity

java.lang.NullPointerException: Ticking entity
   at net.minecraft.network.datasync.EntityDataManager.set(EntityDataManager.java:156)
   at net.minecraft.entity.EntityLivingBase.setHealth(EntityLivingBase.java:929)
   at net.minecraft.entity.EntityLivingBase.<init>(EntityLivingBase.java:200)
   at net.minecraft.entity.EntityLiving.<init>(EntityLiving.java:102)
   at net.minecraft.entity.EntityCreature.<init>(EntityCreature.java:22)
   at net.minecraft.entity.monster.EntityMob.<init>(EntityMob.java:26)
   at velc.mandw.entity.object.Laser.<init>(Laser.java:71)
   at velc.mandw.ai.FlyingCrystalAI$AILaserAttack.updateTask(FlyingCrystalAI.java:104)
   at net.minecraft.entity.ai.EntityAITasks.onUpdateTasks(EntityAITasks.java:114)
   at net.minecraft.entity.EntityLiving.updateEntityActionState(EntityLiving.java:846)
   at net.minecraft.entity.EntityLivingBase.onLivingUpdate(EntityLivingBase.java:2470)
   at net.minecraft.entity.EntityLiving.onLivingUpdate(EntityLiving.java:640)
   at net.minecraft.entity.monster.EntityMob.onLivingUpdate(EntityMob.java:49)
   at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2296)
   at net.minecraft.entity.EntityLiving.onUpdate(EntityLiving.java:344)
   at net.minecraft.entity.monster.EntityMob.onUpdate(EntityMob.java:57)
   at net.minecraft.world.World.updateEntityWithOptionalForce(World.java:2119)
   at net.minecraft.world.WorldServer.updateEntityWithOptionalForce(WorldServer.java:876)
   at net.minecraft.world.World.updateEntity(World.java:2085)
   at net.minecraft.world.World.updateEntities(World.java:1896)
   at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:648)
   at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:795)
   at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:699)
   at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156)
   at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:548)
   at java.lang.Thread.run(Unknown Source)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Server thread
Stacktrace:
   at net.minecraft.network.datasync.EntityDataManager.set(EntityDataManager.java:156)
   at net.minecraft.entity.EntityLivingBase.setHealth(EntityLivingBase.java:929)
   at net.minecraft.entity.EntityLivingBase.<init>(EntityLivingBase.java:200)
   at net.minecraft.entity.EntityLiving.<init>(EntityLiving.java:102)
   at net.minecraft.entity.EntityCreature.<init>(EntityCreature.java:22)
   at net.minecraft.entity.monster.EntityMob.<init>(EntityMob.java:26)
   at velc.mandw.entity.object.Laser.<init>(Laser.java:71)
   at velc.mandw.ai.FlyingCrystalAI$AILaserAttack.updateTask(FlyingCrystalAI.java:104)
   at net.minecraft.entity.ai.EntityAITasks.onUpdateTasks(EntityAITasks.java:114)
   at net.minecraft.entity.EntityLiving.updateEntityActionState(EntityLiving.java:846)
   at net.minecraft.entity.EntityLivingBase.onLivingUpdate(EntityLivingBase.java:2470)
   at net.minecraft.entity.EntityLiving.onLivingUpdate(EntityLiving.java:640)
   at net.minecraft.entity.monster.EntityMob.onLivingUpdate(EntityMob.java:49)
   at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2296)
   at net.minecraft.entity.EntityLiving.onUpdate(EntityLiving.java:344)
   at net.minecraft.entity.monster.EntityMob.onUpdate(EntityMob.java:57)
   at net.minecraft.world.World.updateEntityWithOptionalForce(World.java:2119)
   at net.minecraft.world.WorldServer.updateEntityWithOptionalForce(WorldServer.java:876)
   at net.minecraft.world.World.updateEntity(World.java:2085)

-- Entity being ticked --
Details:
   Entity Type: mandw:flyingcrystal (velc.mandw.entity.mobs.FlyingCrystal)
   Entity ID: 228
   Entity Name: entity.flyingcrystal.name
   Entity's Exact location: -183.45, 64.00, 233.36
   Entity's Block location: World: (-184,64,233), Chunk: (at 8,4,9 in -12,14; contains blocks -192,0,224 to -177,255,239), Region: (-1,0; contains chunks -32,0 to -1,31, blocks -512,0,0 to -1,255,511)
   Entity's Momentum: 0.00, -0.08, 0.00
   Entity's Passengers: []
   Entity's Vehicle: ~~ERROR~~ NullPointerException: null
Stacktrace:
   at net.minecraft.world.World.updateEntities(World.java:1896)
   at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:648)

-- Affected level --
Details:
   Level name: 新規ワールド2
   All players: 1 total; [EntityPlayerMP['Velc'/341, l='新規ワールド2', x=-175.85, y=64.00, z=229.93]]
   Chunk stats: ServerChunkCache: 631 Drop: 0
   Level seed: 1486612449391222533
   Level generator: ID 00 - default, ver 1. Features enabled: true
   Level generator options:
   Level spawn location: World: (-232,64,256), Chunk: (at 8,4,0 in -15,16; contains blocks -240,0,256 to -225,255,271), Region: (-1,0; contains chunks -32,0 to -1,31, blocks -512,0,0 to -1,255,511)
   Level time: 20417 game time, 7489 day time
   Level dimension: 0
   Level storage version: 0x04ABD - Anvil
   Level weather: Rain time: 121863 (now: false), thunder time: 138412 (now: false)
   Level game mode: Game mode: survival (ID 0). Hardcore: false. Cheats: true
Stacktrace:
   at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:795)
   at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:699)
   at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156)
   at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:548)
   at java.lang.Thread.run(Unknown Source)

-- System Details --
Details:
   Minecraft Version: 1.11.2
   Operating System: Windows 7 (amd64) version 6.1
   Java Version: 1.8.0_131, Oracle Corporation
   Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
   Memory: 2824570216 bytes (2693 MB) / 4116185088 bytes (3925 MB) up to 4116185088 bytes (3925 MB)
   JVM Flags: 4 total; -Xms4G -Xmx4G -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M
   IntCache: cache: 1, tcache: 1, allocated: 12, tallocated: 94
   FML: MCP 9.38 Powered by Forge 13.20.0.2311 5 mods loaded, 5 mods active
   States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
   UCHIJAAAA   minecraft{1.11.2} [Minecraft] (minecraft.jar)
   UCHIJAAAA   mcp{9.19} [Minecraft Coder Pack] (minecraft.jar)
   UCHIJAAAA   FML{8.0.99.99} [Forge Mod Loader] (forgeSrc-1.11.2-13.20.0.2311.jar)
   UCHIJAAAA   forge{13.20.0.2311} [Minecraft Forge] (forgeSrc-1.11.2-13.20.0.2311.jar)
   UCHIJAAAA   mandw{1.11.2-1.0.0} [MandW] (bin)
   Loaded coremods (and transformers):
   GL info: ~~ERROR~~ RuntimeException: No OpenGL context found in the current thread.
   Profiler Position: N/A (disabled)
   Player Count: 1 / 8; [EntityPlayerMP['Velc'/341, l='新規ワールド2', x=-175.85, y=64.00, z=229.93]]
   Type: Integrated Server (map_client.txt)
   Is Modded: Definitely; Client brand changed to 'fml,forge'
最後に編集したユーザー Velc [ 2017年7月07日(金) 00:07 ], 累計 1 回
Velc
ID:386be01c
木を殴ってる
 
記事: 17
登録日時: 2017年6月07日(水) 12:04

  • (PostNo.304392)

Re: 【1.11.2】Mobからの発射体(Entityのスポーン)について

投稿記事by elise_blacklab » 2017年7月05日(水) 17:07

そらFireBallはEntityMobじゃないですもんね…飛び道具(projectile)として実装したものをそのまんま生物にしようとしてもうまくいかないのは当然ですね.
Laserは飛び道具?モブ?その辺しっかりしないと話が全然違います.
JDなんかを入れてたどっていけばわかりますが,存在するはずのないHEALTHのデータを読もうとしてエラーを起こしています.
メイドつくってたりします.http://el-blacklab.net/
アバター
elise_blacklab
ID:54a74201
掘り廃人
 
記事: 2405
登録日時: 2014年6月25日(水) 18:30

  • (PostNo.304394)

Re: 【1.11.2】Mobからの発射体(Entityのスポーン)について

投稿記事by Velc » 2017年7月05日(水) 18:16

FireballはEntityを継承してたので最初そうしたのですけども、Laser用のモデルを用意したのでそれが原因でエラーを出したためEntityMobに変更しました。
イメージとしてはLaserというMobをプレイヤー座標に向けて射出する感じになります。
書き込んだ後自分でも試してNBTからの読み込みが原因というのはわかったのですが、
Mobを生成するのではなくてprojecttileとして生成するのが本来正しいやり方なんでしょうか。
追記:EntityFireballのソースみるとticksAliveの値が設定されてないんですよね・・・。そもそもlifeをNBTに書き込む必要はあるんでしょうか。
Velc
ID:2d74aa8a
木を殴ってる
 
記事: 17
登録日時: 2017年6月07日(水) 12:04

  • (PostNo.304416)

Re: 【1.11.2】Mobからの発射体(Entityのスポーン)について

投稿記事by elise_blacklab » 2017年7月05日(水) 22:02

Velc さんが書きました:FireballはEntityを継承してたので最初そうしたのですけども、Laser用のモデルを用意したのでそれが原因でエラーを出したためEntityMobに変更しました。

描画系はClientOnlyなRenderに依存しますから通常はそちらを調整すべきですし,わざわざServer処理に干渉する形に(LaserをEntityMobに)変更する理由がわかりません.
モデルが原因でエラーと仰っていますが,書き方を見ていると何か勘違いをされていそうですし,そちらのソースも貼るようにしないと根本的な原因は分かりません.
Velc さんが書きました:追記:EntityFireballのソースみるとticksAliveの値が設定されてないんですよね・・・。そもそもlifeをNBTに書き込む必要はあるんでしょうか。

http://www.minecraftforum.net/forums/mi ... itherSkull
こちらにも記載がありますがlifeタグの値は現在使用されておらず,代わりにticksInAirフィールドが消滅判定に使用されるようですね.
メイドつくってたりします.http://el-blacklab.net/
アバター
elise_blacklab
ID:100bccbd
掘り廃人
 
記事: 2405
登録日時: 2014年6月25日(水) 18:30

  • (PostNo.304418)

Re: 【1.11.2】Mobからの発射体(Entityのスポーン)について

投稿記事by Velc » 2017年7月05日(水) 22:43

elise_blacklab さんが書きました:
Velc さんが書きました:FireballはEntityを継承してたので最初そうしたのですけども、Laser用のモデルを用意したのでそれが原因でエラーを出したためEntityMobに変更しました。

描画系はClientOnlyなRenderに依存しますから通常はそちらを調整すべきですし,わざわざServer処理に干渉する形に(LaserをEntityMobに)変更する理由がわかりません.
モデルが原因でエラーと仰っていますが,書き方を見ていると何か勘違いをされていそうですし,そちらのソースも貼るようにしないと根本的な原因は分かりません.

お返事ありがとうございます。Renderのソースですが
RenderLaser.java
コード: 全て選択
package velc.mandw.render.projectile;

import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import velc.mandw.model.objcet.LaserModel;

@SideOnly(Side.CLIENT)
public class RenderLaser  extends RenderLiving{
   public RenderLaser(RenderManager renderManagerIn) {
      super(renderManagerIn, new LaserModel(),0.1F);
   }
 
   /**テクスチャを登録するメソッド*/
   @Override
   protected ResourceLocation getEntityTexture(Entity entity) {
      return new ResourceLocation("mandw:textures/mobs/laser.png");
   }

}

RenderLivingを継承してモデルを描画しているため、Laserの継承をEntityにするとEntityをEntityLivingにキャストできないといったエラーを吐かれたのでEntityMobに変更しました。Renderで描画をする場合は自分でdoRenderの処理を作成するということになりますか?
Velc
ID:2d74aa8a
木を殴ってる
 
記事: 17
登録日時: 2017年6月07日(水) 12:04

  • (PostNo.304455)

Re: 【1.11.2】Mobからの発射体(Entityのスポーン)について

投稿記事by Velc » 2017年7月07日(金) 00:06

RenderLaserをチュートリアルを参考にRender継承で以下のように修正したところ、Entityのまま射出することができました。
ありがとうございました。
コード: 全て選択
package velc.mandw.render.projectile;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;

import net.minecraft.client.model.ModelBase;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import velc.mandw.entity.projectile.Laser;
import velc.mandw.model.projectile.LaserModel;

@SideOnly(Side.CLIENT)
public class RenderLaser  extends Render<Laser>{
    protected ModelBase modelBullet;
       
   public RenderLaser(RenderManager renderManagerIn) {
      super(renderManagerIn);
      this.modelBullet = new LaserModel();
      this.shadowSize = 0.0F;
      }
 
   public void renderLaser(Laser par1Entity, double par2, double par4, double par6, float par8, float par9)
    {
        LaserModel model = (LaserModel) this.modelBullet;
 
      this.bindEntityTexture(par1Entity);
        GL11.glPushMatrix();
        GL11.glDisable(GL11.GL_LIGHTING);
        GL11.glEnable(GL12.GL_RESCALE_NORMAL);
        GL11.glColor4f(2.0F, 2.0F, 2.0F, 1.0F);
        GL11.glTranslatef((float)par2, (float)par4 + 1.0F, (float)par6);
        GL11.glRotatef(par1Entity.prevRotationYaw + (par1Entity.rotationYaw - par1Entity.prevRotationYaw) * par9, 0.0F, 1.0F, 0.0F);
        GL11.glRotatef(par1Entity.prevRotationPitch + (par1Entity.rotationPitch - par1Entity.prevRotationPitch) * par9, 0.0F, 0.0F, 1.0F);
        GL11.glScalef(1.0F, -1.0F, -1.0F);
        model.render((Entity)null, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F);
        GL11.glDisable(GL12.GL_RESCALE_NORMAL);
        GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glPopMatrix();
    }
 
 
    public void doRender(Laser par1Entity, double par2, double par4, double par6, float par8, float par9)
    {
        this.renderLaser(par1Entity, par2, par4, par6, par8, par9);
    }   
   
   /**テクスチャを登録するメソッド*/
   //@Override
   //protected ResourceLocation getEntityTexture(Entity entity) {
   //   return new ResourceLocation("mandw:textures/mobs/laser.png");
   //}

   @Override
   protected ResourceLocation getEntityTexture(Laser entity) {
      return new ResourceLocation("mandw:textures/mobs/laser.png");
   }

}
Velc
ID:2d74aa8a
木を殴ってる
 
記事: 17
登録日時: 2017年6月07日(水) 12:04


Return to 質問:開発・制作関連

x