Commit 2fe926ad by Jonathan Thomas

Added new ATTACK goal, to attack the player until friendship improves.

parent 8cacdff3
Pipeline #11951 passed with stage
in 37 seconds
......@@ -224,13 +224,25 @@ public class ChatDataManager {
EntityBehaviorManager.addGoal(entity, followGoal, GoalPriority.FOLLOW_PLAYER);
} else if (behavior.getName().equals("UNFOLLOW")) {
EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class);
} else if (behavior.getName().equals("FRIENDSHIP")) {
this.friendship = Math.max(-3, Math.min(3, behavior.getArgument()));
} else if (behavior.getName().equals("FLEE")) {
FleePlayerGoal fleeGoal = new FleePlayerGoal(player, entity, 1.5F, 20F);
EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
EntityBehaviorManager.addGoal(entity, fleeGoal, GoalPriority.FLEE_PLAYER);
} else if (behavior.getName().equals("ATTACK")) {
AttackPlayerGoal attackGoal = new AttackPlayerGoal(player, entity, 1.5F);
EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.addGoal(entity, attackGoal, GoalPriority.ATTACK_PLAYER);
} else if (behavior.getName().equals("FRIENDSHIP")) {
int new_friendship = Math.max(-3, Math.min(3, behavior.getArgument()));
if (new_friendship > this.friendship) {
// Stop any attack if friendship improves
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
}
this.friendship = new_friendship;
}
}
......
package com.owlmaddie.goals;
import net.minecraft.entity.ai.RangedAttackMob;
import net.minecraft.entity.ai.goal.Goal;
import net.minecraft.entity.ai.pathing.EntityNavigation;
import net.minecraft.entity.mob.Angerable;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.Vec3d;
import java.util.EnumSet;
/**
* The {@code AttackPlayerGoal} class instructs a Mob Entity to show aggression towards the current player.
* For passive entities like chickens, this could manifest as humorous behaviors rather than actual damage.
*/
public class AttackPlayerGoal extends Goal {
private final MobEntity entity;
private ServerPlayerEntity targetPlayer;
private final EntityNavigation navigation;
private final double speed;
private int aggressionTimer;
public AttackPlayerGoal(ServerPlayerEntity player, MobEntity entity, double speed) {
this.targetPlayer = player;
this.entity = entity;
this.speed = speed;
this.navigation = entity.getNavigation();
this.setControls(EnumSet.of(Control.MOVE, Control.LOOK));
this.aggressionTimer = 0; // Initialize the timer used to control aggression intervals.
}
@Override
public boolean canStart() {
// Can start showing aggression if the player is within a certain range.
double squaredDistanceToPlayer = this.entity.squaredDistanceTo(this.targetPlayer);
return squaredDistanceToPlayer < 25; // Example range: within 5 blocks.
}
@Override
public boolean shouldContinue() {
// Continue showing aggression as long as the player is alive and within range.
return this.targetPlayer.isAlive() && this.entity.squaredDistanceTo(this.targetPlayer) < 25;
}
@Override
public void stop() {
this.navigation.stop();
this.aggressionTimer = 0; // Reset the aggression timer.
}
@Override
public void tick() {
this.entity.getLookControl().lookAt(this.targetPlayer, 30.0F, 30.0F); // Make the entity face the player
double squaredDistanceToPlayer = this.entity.squaredDistanceTo(this.targetPlayer);
// Check if the entity is close enough to 'attack'
if (squaredDistanceToPlayer < 3.0D) { // Using a smaller range for direct attacks
if (--this.aggressionTimer <= 0) {
this.aggressionTimer = 20; // Reset the timer; 'attack' every second
if (this.entity instanceof HostileEntity ||
this.entity instanceof Angerable ||
this.entity instanceof RangedAttackMob) {
// Entity is capable of attacking
this.entity.tryAttack(this.targetPlayer);
} else {
// For passive entities, apply minimal damage and simulate a 'leap'
this.targetPlayer.damage(this.entity.getDamageSources().generic(), 1.0F);
// Leap towards the player to simulate the 'attack'
Vec3d leapDirection = new Vec3d(this.targetPlayer.getX() - this.entity.getX(), 0.0D, this.targetPlayer.getZ() - this.entity.getZ()).normalize().multiply(0.5);
this.entity.setVelocity(leapDirection);
this.entity.velocityModified = true;
// Spawn red particles to simulate 'injury'
((ServerWorld)this.entity.getWorld()).spawnParticles(ParticleTypes.DAMAGE_INDICATOR,
this.targetPlayer.getX(),
this.targetPlayer.getBodyY(0.5D),
this.targetPlayer.getZ(),
10, // number of particles
0.1, 0.1, 0.1, 0.2); // speed and randomness
}
}
} else {
// Move towards the player if not in attack range
this.navigation.startMovingTo(this.targetPlayer, this.speed);
}
}
}
......@@ -8,7 +8,8 @@ public enum GoalPriority {
// Enum constants (Goal Types) with their corresponding priority values
TALK_PLAYER(2),
FOLLOW_PLAYER(3),
FLEE_PLAYER(3);
FLEE_PLAYER(3),
ATTACK_PLAYER(3);
private final int priority;
......
......@@ -34,11 +34,12 @@ Include as many behaviors as needed at the end of the message.
<FRIENDSHIP 0> Friendship starts as neutral (0 value). The range of friendship values is -3 to 3. If the player gains (or loses) your trust & friendship, output a new friendship value with this behavior.
<FOLLOW> Follow the player location. If the player asks you to follow or come with them, please output this behavior.
<UNFOLLOW> Stop following the player location. If the player asks you to stay, wait, or stop following them, please output this behavior.
<FLEE> Flee from the player. If the player threatens or scares you, please output this behavior to stay away from the player.
<FLEE> Flee from the player (if you are weak or timid). If the player threatens or scares you, please output this behavior to stay away from the player.
<ATTACK> Attack the player (if you are strong and brave). If the player threatens or scares you, please output this behavior to attack the player and defend yourself.
Output Examples:
These are simple examples with small snippets of text. Do not output these examples exactly, as they
are just to demonstrate the types of output we are expecting.
These are simple examples with small ...snippets... of text. Do not output these examples exactly, as they
are just to demonstrate the types of output we are expecting. Generate creative and unique responses.
USER: Hi! How is your day?
ASSISTANT: ...thanks for asking... <FRIENDSHIP 1>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment