Ajouter un nouveau Golem



  • Bonjour à tous,

    je voudrais vous demander un peu d'aide: je voudrais ajouter des golems qui spawneraient "naturellement" dans les villages de PNJ, mais je n'ai pas trouvé comment faire 😞

    Classe du golem (EntityGoldGolem.java):

    package com.alphaswittle.mineventure.entity.monster;
    
    import net.minecraft.entity.SharedMonsterAttributes;
    import net.minecraft.world.World;
    
    import com.alphaswittle.mineventure.entity.EntityGolem;
    
    public class EntityGoldGolem extends EntityGolem {
    
        public EntityGoldGolem(World world) {
            super(world);
        }
    
        @Override
        protected void applyEntityAttributes() {
            super.applyEntityAttributes();
            getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(300.0D);
            getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.40D);
        }
    }
    

    Classe du Golem (EntityGolem):

    package com.alphaswittle.mineventure.entity;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.material.Material;
    import net.minecraft.entity.Entity;
    import net.minecraft.entity.EntityLiving;
    import net.minecraft.entity.EntityLivingBase;
    import net.minecraft.entity.ai.EntityAIAttackOnCollide;
    import net.minecraft.entity.ai.EntityAIHurtByTarget;
    import net.minecraft.entity.ai.EntityAILookIdle;
    import net.minecraft.entity.ai.EntityAIMoveThroughVillage;
    import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
    import net.minecraft.entity.ai.EntityAIMoveTowardsTarget;
    import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
    import net.minecraft.entity.ai.EntityAIWander;
    import net.minecraft.entity.ai.EntityAIWatchClosest;
    import net.minecraft.entity.monster.IMob;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.util.ChunkCoordinates;
    import net.minecraft.util.DamageSource;
    import net.minecraft.util.MathHelper;
    import net.minecraft.village.Village;
    import net.minecraft.world.World;
    
    import com.alphaswittle.mineventure.entity.ai.EntityAIGolemDefendVillage;
    import com.alphaswittle.mineventure.entity.ai.EntityAIGolemLookAtVillager;
    
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    
    public abstract class EntityGolem extends net.minecraft.entity.monster.EntityGolem {
        private int homeCheckTimer;
        Village villageObj;
        private int attackTimer;
        private int holdRoseTick;
    
        public EntityGolem(World world) {
            super(world);
            setSize(1.4F, 2.9F);
            getNavigator().setAvoidsWater(true);
            tasks.addTask(1, new EntityAIAttackOnCollide(this, 1.0D, true));
            tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.9D, 32.0F));
            tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.6D, true));
            tasks.addTask(4, new EntityAIMoveTowardsRestriction(this, 1.0D));
            tasks.addTask(5, new EntityAIGolemLookAtVillager(this));
            tasks.addTask(6, new EntityAIWander(this, 0.6D));
            tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
            tasks.addTask(8, new EntityAILookIdle(this));
            targetTasks.addTask(1, new EntityAIGolemDefendVillage(this));
            targetTasks.addTask(2, new EntityAIHurtByTarget(this, false));
            targetTasks.addTask(3, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, IMob.mobSelector));
        }
    
        @Override
        protected void entityInit() {
            super.entityInit();
            dataWatcher.addObject(16, Byte.valueOf((byte) 0));
        }
    
        @Override
        public boolean isAIEnabled() {
            return true;
        }
    
        @Override
        protected void updateAITick() {
            if (–homeCheckTimer <= 0) {
                homeCheckTimer = 70 + rand.nextInt(50);
                villageObj = worldObj.villageCollectionObj.findNearestVillage(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ), 32);
    
                if (villageObj == null) {
                    detachHome();
                } else {
                    final ChunkCoordinates chunkcoordinates = villageObj.getCenter();
                    setHomeArea(chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ, (int) (villageObj.getVillageRadius() * 0.6F));
                }
            }
            super.updateAITick();
        }
    
        @Override
        protected int decreaseAirSupply(int supply) {
            return supply;
        }
    
        @Override
        protected void collideWithEntity(Entity entity) {
            if ((entity instanceof IMob) && (getRNG().nextInt(20) == 0)) {
                setAttackTarget((EntityLivingBase) entity);
            }
            super.collideWithEntity(entity);
        }
    
        @Override
        public void onLivingUpdate() {
            super.onLivingUpdate();
    
            if (attackTimer > 0) {
                --attackTimer;
            }
    
            if (holdRoseTick > 0) {
                --holdRoseTick;
            }
    
            if ((((motionX * motionX) + (motionZ * motionZ)) > 2.500000277905201E-7D) && (rand.nextInt(5) == 0)) {
                final int i = MathHelper.floor_double(posX);
                final int j = MathHelper.floor_double(posY - 0.20000000298023224D - yOffset);
                final int k = MathHelper.floor_double(posZ);
                final Block block = worldObj.getBlock(i, j, k);
                if (block.getMaterial() != Material.air) {
                    worldObj.spawnParticle("blockcrack_" + Block.getIdFromBlock(block) + "_" + worldObj.getBlockMetadata(i, j, k), posX + ((rand.nextFloat() - 0.5D) * width), boundingBox.minY + 0.1D, posZ + ((rand.nextFloat() - 0.5D) * width), 4.0D * (rand.nextFloat() - 0.5D), 0.5D, (rand.nextFloat() - 0.5D) * 4.0D);
                }
            }
        }
    
        @Override
        public boolean canAttackClass(Class clazz) {
            return isPlayerCreated() && EntityPlayer.class.isAssignableFrom(clazz) ? false : super.canAttackClass(clazz);
        }
    
        @Override
        public void writeEntityToNBT(NBTTagCompound tagCompound) {
            super.writeEntityToNBT(tagCompound);
            tagCompound.setBoolean("PlayerCreated", isPlayerCreated());
        }
    
        @Override
        public void readEntityFromNBT(NBTTagCompound tagCompound) {
            super.readEntityFromNBT(tagCompound);
            setPlayerCreated(tagCompound.getBoolean("PlayerCreated"));
        }
    
        @Override
        public boolean attackEntityAsMob(Entity entity) {
            attackTimer = 10;
            worldObj.setEntityState(this, (byte) 4);
            final boolean flag = entity.attackEntityFrom(DamageSource.causeMobDamage(this), 7 + rand.nextInt(15));
            if (flag) {
                entity.motionY += 0.4000000059604645D;
            }
            playSound("mob.irongolem.throw", 1.0F, 1.0F);
            return flag;
        }
    
        @Override
        @SideOnly(Side.CLIENT)
        public void handleHealthUpdate(byte health) {
            if (health == 4) {
                attackTimer = 10;
                playSound("mob.irongolem.throw", 1.0F, 1.0F);
            } else if (health == 11) {
                holdRoseTick = 400;
            } else {
                super.handleHealthUpdate(health);
            }
        }
    
        public Village getVillage() {
            return villageObj;
        }
    
        @SideOnly(Side.CLIENT)
        public int getAttackTimer() {
            return attackTimer;
        }
    
        public void setHoldingRose(boolean isHoldingRose) {
            holdRoseTick = isHoldingRose ? 400 : 0;
            worldObj.setEntityState(this, (byte) 11);
        }
    
        @Override
        protected String getHurtSound() {
            return "mob.irongolem.hit";
        }
    
        @Override
        protected String getDeathSound() {
            return "mob.irongolem.death";
        }
    
        @Override
        protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_) {
            playSound("mob.irongolem.walk", 1.0F, 1.0F);
        }
    
        public int getHoldRoseTick() {
            return holdRoseTick;
        }
    
        public boolean isPlayerCreated() {
            return (dataWatcher.getWatchableObjectByte(16) & 1) != 0;
        }
    
        public void setPlayerCreated(boolean isPlayerCreated) {
            final byte b0 = dataWatcher.getWatchableObjectByte(16);
    
            if (isPlayerCreated) {
                dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 1)));
            } else {
                dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -2)));
            }
        }
    
        @Override
        public void onDeath(DamageSource source) {
            if (!isPlayerCreated() && (attackingPlayer != null) && (villageObj != null)) {
                villageObj.setReputationForPlayer(attackingPlayer.getCommandSenderName(), -5);
            }
            super.onDeath(source);
        }
    }
    

    Classe qui gère les entités (EntityHandler.java):

    package com.alphaswittle.mineventure.core;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    import com.alphaswittle.mineventure.entity.monster.EntityDiamondGolem;
    import com.alphaswittle.mineventure.entity.monster.EntityGoldGolem;
    import com.alphaswittle.mineventure.localization.Localization;
    import com.alphaswittle.mineventure.localization.LocalizationNode;
    
    import cpw.mods.fml.common.registry.EntityRegistry;
    
    public class EntityHandler {
        private final Logger logger = LogManager.getLogger("Mineventure/EntityHandler");
    
        public void load() {
            EntityRegistry.registerGlobalEntityID(EntityGoldGolem.class, "GoldGolem", EntityRegistry.findGlobalUniqueEntityId());
            Localization.addNode("en_US", new LocalizationNode("entity", "gold_golem", true));
            EntityRegistry.registerGlobalEntityID(EntityDiamondGolem.class, "DiamondGolem", EntityRegistry.findGlobalUniqueEntityId());
            Localization.addNode("en_US", new LocalizationNode("entity", "diamond_golem", true));
        }
    
        public Logger getLogger() {
            return logger;
        }
    }
    

    Merci d'avance 😄



  • Bah dans la classe Village tu as :

    public void tick(int par1)
    
        {
    
    int j = this.numVillagers / 10;
    
            if (this.numIronGolems < j && this.villageDoorInfoList.size() > 20 && this.worldObj.rand.nextInt(7000) == 0)
            {
                Vec3 vec3 = this.tryGetIronGolemSpawningLocation(MathHelper.floor_float((float)this.center.posX), MathHelper.floor_float((float)this.center.posY), MathHelper.floor_float((float)this.center.posZ), 2, 4, 2);
    
                if (vec3 != null)
                {
                    EntityIronGolem entityirongolem = new EntityIronGolem(this.worldObj);
                    entityirongolem.setPosition(vec3.xCoord, vec3.yCoord, vec3.zCoord);
                    this.worldObj.spawnEntityInWorld(entityirongolem);
                    ++this.numIronGolems;
                }
            }
    }
    
    

    Essaye de voir si tu peux pas faire en sorte de rajouter quelque chose là dedans (ou créer ta propres classe Village)



  • Merci, robin pourrais tu m'indiquer comment on pourrais patcher cette méthode ?


  • Administrateurs

    J'ai jamais utilisé la bibliothèque ASM, donc je ne peux pas vraiment t'aider.
    Ça serait limite plus simple de détecter qu'un golem de fer vient de spawner et du-coup de faire spawner le tient avec (voir cancel le spawn de l'autre pour n'avoir que le tient).



  • Ah oui bonne idée merci, je pourrais même utiliser la condition isPlayerCreated() 😉