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 ?


  • Moddeurs confirmés Rédacteurs 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() 😉


Log in to reply