Skip to content

Commit

Permalink
ai improvements to golems and crossbow guards
Browse files Browse the repository at this point in the history
bow guards are next
  • Loading branch information
seymourimadeit committed Apr 26, 2024
1 parent 939165b commit a731b24
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 27 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ minecraft_version=1.20.5
# as they do not follow standard versioning conventions.
minecraft_version_range=[1.20.5,1.21)
# The Neo version must agree with the Minecraft version to get a valid artifact
neo_version=20.5.3-beta
neo_version=20.5.5-beta
# The Neo version range can use any version of Neo as bounds
neo_version_range=[20.4,)
# The loader version range can only use the major version of FML as bounds
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/tallestegg/guardvillagers/HandlerEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.AvoidEntityGoal;
import net.minecraft.world.entity.ai.goal.FloatGoal;
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.Animal;
Expand All @@ -27,10 +29,7 @@
import net.neoforged.neoforge.event.entity.living.LivingHurtEvent;
import tallestegg.guardvillagers.configuration.GuardConfig;
import tallestegg.guardvillagers.entities.Guard;
import tallestegg.guardvillagers.entities.ai.goals.ArmorerRepairGuardArmorGoal;
import tallestegg.guardvillagers.entities.ai.goals.AttackEntityDaytimeGoal;
import tallestegg.guardvillagers.entities.ai.goals.HealGolemGoal;
import tallestegg.guardvillagers.entities.ai.goals.HealGuardAndPlayerGoal;
import tallestegg.guardvillagers.entities.ai.goals.*;

import java.util.List;

Expand Down Expand Up @@ -101,7 +100,7 @@ public static void onLivingSpawned(EntityJoinLevelEvent event) {
if (((Raider) mob).hasActiveRaid() && GuardConfig.COMMON.RaidAnimals.get())
mob.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(((Raider) mob), Animal.class, false));
}
if (GuardConfig.COMMON.AttackAllMobs.get()) {
if (GuardConfig.COMMON.MobsAttackGuards.get()) {
if (mob instanceof Enemy && !GuardConfig.COMMON.MobBlackList.get().contains(mob.getEncodeId())) {
if (!(mob instanceof Spider))
mob.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(mob, Guard.class, false));
Expand Down Expand Up @@ -136,6 +135,8 @@ public static void onLivingSpawned(EntityJoinLevelEvent event) {
golem.targetSelector.removeGoal(angerGoal);
golem.targetSelector.addGoal(2, tolerateFriendlyFire);
});
golem.goalSelector.addGoal(1, new FloatGoal(golem));
golem.goalSelector.addGoal(0, new GetOutOfWaterGoal(golem, 1.0D));
}

if (mob instanceof Zombie zombie) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public static class CommonConfig {
public final ModConfigSpec.BooleanValue WitchesVillager;
public final ModConfigSpec.BooleanValue IllusionerRaids;
public final ModConfigSpec.BooleanValue AttackAllMobs;
public final ModConfigSpec.BooleanValue MobsAttackGuards;
public final ModConfigSpec.BooleanValue VillagersRunFromPolarBears;
public final ModConfigSpec.BooleanValue IllagersRunFromPolarBears;
public final ModConfigSpec.BooleanValue GuardsRunFromPolarBears;
Expand Down Expand Up @@ -73,13 +74,14 @@ public static class CommonConfig {

public CommonConfig(ModConfigSpec.Builder builder) {
builder.push("raids and illagers");
RaidAnimals = builder.comment("Illagers In Raids Attack Animals?").translation(GuardVillagers.MODID + ".config.RaidAnimals").define("Illagers in raids attack animals?", false);
RaidAnimals = builder.comment("Illagers In Raids Attack Animals?").translation(GuardVillagers.MODID + ".config.RaidAnimals").define("Illagers in raids attack animals?", true);
WitchesVillager = builder.comment("Witches Attack Villagers?").translation(GuardVillagers.MODID + ".config.WitchesVillager").define("Witches attack villagers?", true);
IllusionerRaids = builder.comment("This will make Illusioners get involved in raids").translation(GuardVillagers.MODID + ".config.IllusionerRaids").define("Have Illusioners in raids?", false);
IllagersRunFromPolarBears = builder.comment("This makes Illagers run from polar bears, as anyone with common sense would.").translation(GuardVillagers.MODID + ".config.IllagersRunFromPolarBears").define("Have Illagers have some common sense?", true);
builder.pop();
builder.push("mob ai in general");
AttackAllMobs = builder.comment("Guards will attack all hostiles with this option, when set to false guards will only attack zombies and illagers.").translation(GuardVillagers.MODID + ".config.AttackAllMobs").define("Guards attack all mobs?", true);
MobsAttackGuards = builder.comment("Hostiles attack guards, by default only illagers and zombies will attack guards, the mob blacklist below will effect this option").define("All mobs attack guards", false);
MobBlackList = builder.comment("Guards won't attack mobs in this list at all, for example, putting \"minecraft:creeper\" in this list will make guards ignore creepers.").define("Mob Blacklist", Lists.newArrayList("minecraft:villager", "minecraft:iron_golem", "minecraft:wandering_trader", "guardvillagers:guard", "minecraft:creeper"));
MobWhiteList = builder.comment("Guards will additionally attack mobs ids put in this list, for example, putting \"minecraft:cow\" in this list will make guards attack cows.").define("Mob Whitelist", new ArrayList<>());
builder.pop();
Expand Down
20 changes: 14 additions & 6 deletions src/main/java/tallestegg/guardvillagers/entities/Guard.java
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ public void disableShield(boolean increase) {
if (this.random.nextFloat() < chance) {
this.shieldCoolDown = 100;
this.stopUsingItem();
level().broadcastEntityEvent(this, (byte) 30);
this.level().broadcastEntityEvent(this, (byte) 30);
}
}

Expand Down Expand Up @@ -688,6 +688,19 @@ public void performRangedAttack(LivingEntity target, float distanceFactor) {
}
}

@Override
public void performCrossbowAttack(LivingEntity p_32337_, float p_32338_) {
InteractionHand interactionhand = ProjectileUtil.getWeaponHoldingHand(p_32337_, item -> item instanceof CrossbowItem);
ItemStack itemstack = p_32337_.getItemInHand(interactionhand);
if (itemstack.getItem() instanceof CrossbowItem crossbowitem) {
crossbowitem.performShooting(
p_32337_.level(), p_32337_, interactionhand, itemstack, p_32338_, 1.0F, null
);
}

this.onCrossbowAttackPerformed();
}

@Override
public void setItemSlot(EquipmentSlot slotIn, ItemStack stack) {
super.setItemSlot(slotIn, stack);
Expand Down Expand Up @@ -775,11 +788,6 @@ public void gossip(Villager villager, long gameTime) {
}


@Override
public void performCrossbowAttack(LivingEntity p_32337_, float p_32338_) {
CrossbowAttackMob.super.performCrossbowAttack(p_32337_, p_32338_);
}

@Override
protected void blockedByShield(LivingEntity entityIn) {
if (this.isKicking()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package tallestegg.guardvillagers.entities.ai.goals;

import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal;
import net.minecraft.world.entity.ai.util.LandRandomPos;
import net.minecraft.world.phys.Vec3;

import javax.annotation.Nullable;

public class GetOutOfWaterGoal extends WaterAvoidingRandomStrollGoal {
public GetOutOfWaterGoal(PathfinderMob p_25987_, double p_25988_) {
super(p_25987_, p_25988_);
}

@Override
public boolean canUse() {
return this.mob.isInWaterOrBubble() && this.getPosition() != null;
}

@Nullable
@Override
protected Vec3 getPosition() {
if (this.mob.isInWaterOrBubble()) {
Vec3 vec3 = LandRandomPos.getPos(this.mob, 15, 7);
return vec3 == null ? super.getPosition() : vec3;
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public class RangedCrossbowAttackPassiveGoal<T extends PathfinderMob & RangedAtt
private int seeTime;
private int attackDelay;
private int updatePathDelay;
private int runTime;

public RangedCrossbowAttackPassiveGoal(T pMob, double pSpeedModifier, float pAttackRadius) {
this.mob = pMob;
Expand Down Expand Up @@ -112,7 +111,7 @@ public void tick() {
boolean canSee2 = (d0 > (double) this.attackRadiusSqr || this.seeTime < 5) && this.attackDelay == 0;
if (canSee2) {
--this.updatePathDelay;
if (this.updatePathDelay <= 0 && !((Guard)this.mob).isPatrolling()) {
if (this.updatePathDelay <= 0 && !((Guard) this.mob).isPatrolling()) {
this.mob.getNavigation().moveTo(livingentity, this.canRun() ? this.speedModifier : this.speedModifier * 0.5D);
this.updatePathDelay = PATHFINDING_DELAY_RANGE.sample(this.mob.getRandom());
}
Expand All @@ -131,7 +130,7 @@ public void tick() {
this.mob.getNavigation().moveTo(this.wantedX, this.wantedY, this.wantedZ, this.mob.isCrouching() ? 0.5F : 1.2D);
this.crossbowState = CrossbowState.UNCHARGED;
} else if (this.crossbowState == CrossbowState.UNCHARGED) {
if (hasSeenEntityRecently) {
if (!canSee2) {
this.mob.startUsingItem(ProjectileUtil.getWeaponHoldingHand(this.mob, item -> item instanceof CrossbowItem));
this.crossbowState = CrossbowState.CHARGING;
this.mob.setChargingCrossbow(true);
Expand All @@ -155,7 +154,6 @@ public void tick() {
}
} else if (this.crossbowState == CrossbowState.READY_TO_ATTACK && canSee) {
this.mob.performRangedAttack(livingentity, 1.0F);
ItemStack itemstack1 = this.mob.getItemInHand(ProjectileUtil.getWeaponHoldingHand(this.mob, item -> item instanceof CrossbowItem));
this.crossbowState = CrossbowState.UNCHARGED;
}
}
Expand All @@ -165,17 +163,17 @@ public void tick() {
private boolean friendlyInLineOfSight() {
List<Entity> list = this.mob.level().getEntities(this.mob, this.mob.getBoundingBox().inflate(5.0D));
for (Entity guard : list) {
if (guard != this.mob.getTarget()) {
boolean isVillager = ((Guard)this.mob).getOwner() == guard || guard.getType() == EntityType.VILLAGER || guard.getType() == GuardEntityType.GUARD.get() || guard.getType() == EntityType.IRON_GOLEM;
if (isVillager) {
Vec3 vector3d = this.mob.getLookAngle();
Vec3 vector3d1 = guard.position().vectorTo(this.mob.position()).normalize();
vector3d1 = new Vec3(vector3d1.x, vector3d1.y, vector3d1.z);
if (vector3d1.dot(vector3d) < 1.0D && this.mob.hasLineOfSight(guard) && guard.distanceTo(this.mob) <= 4.0D)
return true;
}
if (guard != this.mob.getTarget()) {
boolean isVillager = ((Guard) this.mob).getOwner() == guard || guard.getType() == EntityType.VILLAGER || guard.getType() == GuardEntityType.GUARD.get() || guard.getType() == EntityType.IRON_GOLEM;
if (isVillager) {
Vec3 vector3d = this.mob.getLookAngle();
Vec3 vector3d1 = guard.position().vectorTo(this.mob.position()).normalize();
vector3d1 = new Vec3(vector3d1.x, vector3d1.y, vector3d1.z);
if (vector3d1.dot(vector3d) < 1.0D && this.mob.hasLineOfSight(guard) && guard.distanceTo(this.mob) <= 4.0D)
return true;
}
}
}
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public boolean canUse() {
if (!list.isEmpty()) {
for (Villager mob : list) {
if (mob != null) {
if (mob.getVillagerData().getProfession() == VillagerProfession.CLERIC && guard.getHealth() < guard.getMaxHealth() && guard.getTarget() == null && !guard.hasEffect(MobEffects.REGENERATION)) {
if (mob.getVillagerData().getProfession() == VillagerProfession.CLERIC && guard.getHealth() < guard.getMaxHealth() && guard.getTarget() == null && !guard.hasEffect(MobEffects.REGENERATION) && !mob.isSleeping()) {
this.cleric = mob;
return GuardConfig.COMMON.ClericHealing.get();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"parent": "item/template_spawn_egg"
}

0 comments on commit a731b24

Please sign in to comment.