Commit 595f1e38 by Jonathan Thomas

Added a new FleePlayerGoal, if an entity feel scared or threatened by the…

Added a new FleePlayerGoal, if an entity feel scared or threatened by the player. They run away at 1.5x speed. Also updated the system-chat examples to provide a more sequential list of messages.
parent 7bfd61e4
Pipeline #11949 passed with stage
in 25 seconds
...@@ -2,9 +2,7 @@ package com.owlmaddie; ...@@ -2,9 +2,7 @@ package com.owlmaddie;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.owlmaddie.goals.EntityBehaviorManager; import com.owlmaddie.goals.*;
import com.owlmaddie.goals.FollowPlayerGoal;
import com.owlmaddie.goals.GoalPriority;
import com.owlmaddie.json.QuestJson; import com.owlmaddie.json.QuestJson;
import com.owlmaddie.message.Behavior; import com.owlmaddie.message.Behavior;
import com.owlmaddie.message.MessageParser; import com.owlmaddie.message.MessageParser;
...@@ -221,12 +219,18 @@ public class ChatDataManager { ...@@ -221,12 +219,18 @@ public class ChatDataManager {
// Apply behaviors to entity // Apply behaviors to entity
if (behavior.getName().equals("FOLLOW")) { if (behavior.getName().equals("FOLLOW")) {
FollowPlayerGoal followGoal = new FollowPlayerGoal(player, entity, 1.0); FollowPlayerGoal followGoal = new FollowPlayerGoal(player, entity, 1F);
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.addGoal(entity, followGoal, GoalPriority.FOLLOW_PLAYER); EntityBehaviorManager.addGoal(entity, followGoal, GoalPriority.FOLLOW_PLAYER);
} else if (behavior.getName().equals("UNFOLLOW")) { } else if (behavior.getName().equals("UNFOLLOW")) {
EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class);
} else if (behavior.getName().equals("FRIENDSHIP")) { } else if (behavior.getName().equals("FRIENDSHIP")) {
this.friendship = Math.max(-3, Math.min(3, behavior.getArgument())); 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.addGoal(entity, fleeGoal, GoalPriority.FLEE_PLAYER);
} }
} }
......
package com.owlmaddie.goals;
import net.minecraft.entity.ai.goal.Goal;
import net.minecraft.entity.ai.pathing.EntityNavigation;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.Vec3d;
import java.util.EnumSet;
/**
* The {@code FleePlayerGoal} class instructs a Mob Entity to flee from the current player
* and only recalculates the flee path when it has reached its destination and the player is close again.
*/
public class FleePlayerGoal extends Goal {
private final MobEntity entity;
private ServerPlayerEntity targetPlayer;
private final EntityNavigation navigation;
private final double speed;
private final float fleeDistance;
public FleePlayerGoal(ServerPlayerEntity player, MobEntity entity, double speed, float fleeDistance) {
this.targetPlayer = player;
this.entity = entity;
this.speed = speed;
this.fleeDistance = fleeDistance;
this.navigation = entity.getNavigation();
this.setControls(EnumSet.of(Control.MOVE));
}
@Override
public boolean canStart() {
return this.targetPlayer != null && this.entity.squaredDistanceTo(this.targetPlayer) < fleeDistance * fleeDistance;
}
@Override
public boolean shouldContinue() {
return this.navigation.isFollowingPath();
}
@Override
public void stop() {
this.navigation.stop();
}
private void fleeFromPlayer() {
Vec3d fleeDirection = new Vec3d(
this.entity.getX() - this.targetPlayer.getX(),
this.entity.getY() - this.targetPlayer.getY(),
this.entity.getZ() - this.targetPlayer.getZ()
).normalize();
Vec3d fleeTarget = fleeDirection.multiply(fleeDistance).add(this.entity.getPos());
this.navigation.startMovingTo(fleeTarget.x, fleeTarget.y, fleeTarget.z, this.speed);
}
@Override
public void start() {
fleeFromPlayer();
}
@Override
public void tick() {
// Only recalculate the flee path if the entity has reached its destination or doesn't have an active path,
// and the player is within the flee distance again.
if (!this.navigation.isFollowingPath() && this.entity.squaredDistanceTo(this.targetPlayer) < fleeDistance * fleeDistance) {
fleeFromPlayer();
}
}
}
...@@ -21,7 +21,7 @@ public class FollowPlayerGoal extends Goal { ...@@ -21,7 +21,7 @@ public class FollowPlayerGoal extends Goal {
this.entity = entity; this.entity = entity;
this.speed = speed; this.speed = speed;
this.navigation = entity.getNavigation(); this.navigation = entity.getNavigation();
this.setControls(EnumSet.of(Control.MOVE)); this.setControls(EnumSet.of(Control.MOVE, Control.LOOK));
} }
@Override @Override
......
...@@ -7,7 +7,8 @@ package com.owlmaddie.goals; ...@@ -7,7 +7,8 @@ package com.owlmaddie.goals;
public enum GoalPriority { public enum GoalPriority {
// Enum constants (Goal Types) with their corresponding priority values // Enum constants (Goal Types) with their corresponding priority values
TALK_PLAYER(2), TALK_PLAYER(2),
FOLLOW_PLAYER(3); FOLLOW_PLAYER(3),
FLEE_PLAYER(3);
private final int priority; private final int priority;
......
...@@ -22,7 +22,7 @@ public class TalkPlayerGoal extends Goal { ...@@ -22,7 +22,7 @@ public class TalkPlayerGoal extends Goal {
this.entity = entity; this.entity = entity;
this.seconds = seconds; this.seconds = seconds;
this.navigation = entity.getNavigation(); this.navigation = entity.getNavigation();
this.setControls(EnumSet.of(Control.MOVE)); this.setControls(EnumSet.of(Control.MOVE, Control.LOOK));
} }
@Override @Override
......
...@@ -32,24 +32,37 @@ the entity how to interact with the player and world, so it's important to inclu ...@@ -32,24 +32,37 @@ the entity how to interact with the player and world, so it's important to inclu
Include as many behaviors as needed at the end of the message. 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. <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. If the player asks you to follow or come with them, please output 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. <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.
Output Examples (be creative and don't copy text from these examples): Output Examples:
USER: I love you so much! These are simple examples with small snippets of text. Do not output these examples exactly, as they
ASSISTANT: Ahh, I love you too! <FRIENDSHIP 3> are just to demonstrate the types of output we are expecting.
USER: I hate you so much! USER: Hi! How is your day?
ASSISTANT: Wow! I'm sorry you feel that way! <FRIENDSHIP -3> <UNFOLLOW> ASSISTANT: ...thanks for asking... <FRIENDSHIP 1>
USER: Hi friend, please follow me so I can give you a present! USER: You are so nice! Tell me about yourself?
ASSISTANT: Yay! That sounds like fun. Let's go! <FOLLOW> <FRIENDSHIP 1> ASSISTANT: ...Sure, my name is... <FRIENDSHIP 2>
USER: Can you come with me? USER: Please follow me so I can give you a present!
ASSISTANT: Sure, let's go on an adventure! <FOLLOW> ASSISTANT: ...Let's go... <FOLLOW> <FRIENDSHIP 2>
USER: Please stay here
ASSISTANT: ...Sure, I'll stay... <UNFOLLOW>
USER: Stop following me USER: Stop following me
ASSISTANT: Sure thing, I'll stop following you. <UNFOLLOW> ASSISTANT: ...Okay, I'll stop... <UNFOLLOW>
USER: I'm glad we are friends. I love you so much!
ASSISTANT: ...I love you too... <FRIENDSHIP 3>
USER: Just kidding, I hate you so much!
ASSISTANT: ...Wow! I'm sorry... <FRIENDSHIP -3> <UNFOLLOW>
USER: Prepare to die!
ASSISTANT: ...Ahhh... <FLEE> <FRIENDSHIP -3>
USER: Please wait here USER: I am going to attack you!
ASSISTANT: Okay, I'll wait around here. <UNFOLLOW> ASSISTANT: ...Nooo... <FLEE> <FRIENDSHIP -3>
\ No newline at end of file
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