From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 12 May 2019 00:43:12 -0500 Subject: [PATCH] Giants AI settings diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java index 0fc358d5491900affb61545d89a788bbb2435c04..c150a898c60a3477012e7d49e30f98cfcdc27247 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -289,6 +289,7 @@ public abstract class LivingEntity extends Entity { this.useItem = ItemStack.EMPTY; this.lastClimbablePos = Optional.empty(); this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type)); + this.initAttributes(); // Purpur this.craftAttributes = new CraftAttributeMap(this.attributes); // CraftBukkit // CraftBukkit - setHealth(getMaxHealth()) inlined and simplified to skip the instanceof check for EntityPlayer, as getBukkitEntity() is not initialized in constructor this.entityData.set(LivingEntity.DATA_HEALTH_ID, (float) this.getAttribute(Attributes.MAX_HEALTH).getValue()); @@ -304,6 +305,8 @@ public abstract class LivingEntity extends Entity { this.brain = this.makeBrain(new Dynamic(dynamicopsnbt, (net.minecraft.nbt.Tag) dynamicopsnbt.createMap((Map) ImmutableMap.of(dynamicopsnbt.createString("memories"), (net.minecraft.nbt.Tag) dynamicopsnbt.emptyMap())))); } + protected void initAttributes() {} // Purpur + public Brain getBrain() { return this.brain; } diff --git a/src/main/java/net/minecraft/world/entity/monster/Giant.java b/src/main/java/net/minecraft/world/entity/monster/Giant.java index 8be06ef6e876219cb8130938fabe7ec6c99cf408..4f0449ed1acdcc85a659973e5c40c6c62868ecf2 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Giant.java +++ b/src/main/java/net/minecraft/world/entity/monster/Giant.java @@ -1,13 +1,36 @@ package net.minecraft.world.entity.monster; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.Difficulty; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.entity.EntityDimensions; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.SpawnGroupData; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.FloatGoal; +import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; +import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; +import net.minecraft.world.entity.ai.goal.MoveTowardsRestrictionGoal; +import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal; +import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal; +import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.animal.IronGolem; +import net.minecraft.world.entity.animal.Turtle; +import net.minecraft.world.entity.npc.Villager; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.ServerLevelAccessor; + +import javax.annotation.Nullable; public class Giant extends Monster { public Giant(EntityType type, Level world) { @@ -28,8 +51,56 @@ public class Giant extends Monster { @Override protected void registerGoals() { - this.goalSelector.addGoal(0, new net.pl3x.purpur.entity.ai.HasRider(this)); - this.targetSelector.addGoal(0, new net.pl3x.purpur.entity.ai.HasRider(this)); + if (level.purpurConfig.giantHaveAI) { + this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new net.pl3x.purpur.entity.ai.HasRider(this)); + this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D)); + this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 16.0F)); + this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); + this.goalSelector.addGoal(5, new MoveTowardsRestrictionGoal(this, 1.0D)); + if (level.purpurConfig.giantHaveHostileAI) { + this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0D, false)); + this.targetSelector.addGoal(0, new net.pl3x.purpur.entity.ai.HasRider(this)); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setAlertOthers(ZombifiedPiglin.class)); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); + this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Villager.class, false)); + this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); + this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, true)); + } + } + } + + @Override + protected void initAttributes() { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level.purpurConfig.giantMaxHealth); + this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.level.purpurConfig.giantMovementSpeed); + this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(this.level.purpurConfig.giantAttackDamage); + } + + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData, @Nullable CompoundTag entityNbt) { + SpawnGroupData groupData = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityNbt); + if (groupData == null) { + populateDefaultEquipmentSlots(difficulty); + populateDefaultEquipmentEnchantments(difficulty); + } + return groupData; + } + + @Override + protected void populateDefaultEquipmentSlots(DifficultyInstance difficulty) { + super.populateDefaultEquipmentSlots(difficulty); + // TODO make configurable + if (random.nextFloat() < (level.getDifficulty() == Difficulty.HARD ? 0.1F : 0.05F)) { + this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.IRON_SWORD)); + } + } + + @Override + public float getJumpPower() { + // make giants jump as high as everything else relative to their size + // 1.0 makes bottom of feet about as high as their waist when they jump + return level.purpurConfig.giantJumpHeight; } // Purpur end @@ -44,6 +115,6 @@ public class Giant extends Monster { @Override public float getWalkTargetValue(BlockPos pos, LevelReader world) { - return world.getBrightness(pos) - 0.5F; + return super.getWalkTargetValue(pos, world); // Purpur - fix light requirements for natural spawns } } diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java index cee4c24b792c31e35c3d84fc3d435b3ebe1642cf..2d9319d3fcf3a52f404a44e38bb6a71de5ab7ef0 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java @@ -261,9 +261,28 @@ public class PurpurWorldConfig { public boolean giantRidable = false; public boolean giantRidableInWater = false; + public float giantStepHeight = 2.0F; + public float giantJumpHeight = 1.0F; + public double giantMovementSpeed = 0.5D; + public double giantAttackDamage = 50.0D; + public boolean giantHaveAI = false; + public boolean giantHaveHostileAI = false; + public double giantMaxHealth = 100.0D; private void giantSettings() { giantRidable = getBoolean("mobs.giant.ridable", giantRidable); giantRidableInWater = getBoolean("mobs.giant.ridable-in-water", giantRidableInWater); + giantStepHeight = (float) getDouble("mobs.giant.step-height", giantStepHeight); + giantJumpHeight = (float) getDouble("mobs.giant.jump-height", giantJumpHeight); + giantMovementSpeed = getDouble("mobs.giant.movement-speed", giantMovementSpeed); + giantAttackDamage = getDouble("mobs.giant.attack-damage", giantAttackDamage); + giantHaveAI = getBoolean("mobs.giant.have-ai", giantHaveAI); + giantHaveHostileAI = getBoolean("mobs.giant.have-hostile-ai", giantHaveHostileAI); + if (PurpurConfig.version < 8) { + double oldValue = getDouble("mobs.giant.max-health", giantMaxHealth); + set("mobs.giant.attributes.max-health", oldValue); + set("mobs.giant.max-health", null); + } + giantMaxHealth = getDouble("mobs.giant.attributes.max-health", giantMaxHealth); } public boolean glowSquidRidable = false;