Commit 7fc533f6 by Jonathan Thomas

Fixing crash when displaying message on LeadPlayerGoal, to run the…

Fixing crash when displaying message on LeadPlayerGoal, to run the generateMessage in a scheduler (after 1 tick), and not in the Goal's tick method.
parent 0d1aa055
Pipeline #12708 passed with stages
in 2 minutes 13 seconds
...@@ -263,89 +263,87 @@ public class ChatDataManager { ...@@ -263,89 +263,87 @@ public class ChatDataManager {
float entitySpeedFast = MathHelper.clamp(entitySpeed * 1.3F, 0.5f, 1.3f); float entitySpeedFast = MathHelper.clamp(entitySpeed * 1.3F, 0.5f, 1.3f);
// Apply behaviors (if any) // Apply behaviors (if any)
if (!is_auto_message) { for (Behavior behavior : result.getBehaviors()) {
for (Behavior behavior : result.getBehaviors()) { LOGGER.info("Behavior: " + behavior.getName() + (behavior.getArgument() != null ?
LOGGER.info("Behavior: " + behavior.getName() + (behavior.getArgument() != null ? ", Argument: " + behavior.getArgument() : ""));
", Argument: " + behavior.getArgument() : ""));
// Apply behaviors to entity
// Apply behaviors to entity if (behavior.getName().equals("FOLLOW")) {
if (behavior.getName().equals("FOLLOW")) { FollowPlayerGoal followGoal = new FollowPlayerGoal(player, entity, entitySpeedMedium);
FollowPlayerGoal followGoal = new FollowPlayerGoal(player, entity, entitySpeedMedium); EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class); EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.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("FLEE")) {
} else if (behavior.getName().equals("FLEE")) { float fleeDistance = 40F;
float fleeDistance = 40F; FleePlayerGoal fleeGoal = new FleePlayerGoal(player, entity, entitySpeedFast, fleeDistance);
FleePlayerGoal fleeGoal = new FleePlayerGoal(player, entity, entitySpeedFast, fleeDistance); EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class); EntityBehaviorManager.addGoal(entity, fleeGoal, GoalPriority.FLEE_PLAYER);
EntityBehaviorManager.addGoal(entity, fleeGoal, GoalPriority.FLEE_PLAYER);
} else if (behavior.getName().equals("UNFLEE")) {
} else if (behavior.getName().equals("UNFLEE")) { EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
} else if (behavior.getName().equals("ATTACK")) {
} else if (behavior.getName().equals("ATTACK")) { AttackPlayerGoal attackGoal = new AttackPlayerGoal(player, entity, entitySpeedFast);
AttackPlayerGoal attackGoal = new AttackPlayerGoal(player, entity, entitySpeedFast); EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class); EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class); EntityBehaviorManager.addGoal(entity, attackGoal, GoalPriority.ATTACK_PLAYER);
EntityBehaviorManager.addGoal(entity, attackGoal, GoalPriority.ATTACK_PLAYER);
} else if (behavior.getName().equals("PROTECT")) {
} else if (behavior.getName().equals("PROTECT")) { ProtectPlayerGoal protectGoal = new ProtectPlayerGoal(player, entity, 1.0);
ProtectPlayerGoal protectGoal = new ProtectPlayerGoal(player, entity, 1.0); EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
EntityBehaviorManager.addGoal(entity, protectGoal, GoalPriority.PROTECT_PLAYER);
} else if (behavior.getName().equals("UNPROTECT")) {
EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class);
} else if (behavior.getName().equals("LEAD")) {
LeadPlayerGoal leadGoal = new LeadPlayerGoal(player, entity, entitySpeedMedium);
EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
EntityBehaviorManager.addGoal(entity, leadGoal, GoalPriority.LEAD_PLAYER);
} else if (behavior.getName().equals("UNLEAD")) {
EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class);
} else if (behavior.getName().equals("FRIENDSHIP")) {
int new_friendship = Math.max(-3, Math.min(3, behavior.getArgument()));
if (new_friendship > 0) {
// positive friendship (apply friend goal)
((LivingEntityInterface) entity).setCanTargetPlayers(false);
} else if (new_friendship <= 0) {
// negative friendship (remove friend goal)
((LivingEntityInterface) entity).setCanTargetPlayers(true);
}
// Does friendship improve?
if (new_friendship > this.friendship) {
// Stop any attack/flee if friendship improves
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
EntityBehaviorManager.addGoal(entity, protectGoal, GoalPriority.PROTECT_PLAYER);
} else if (behavior.getName().equals("UNPROTECT")) {
EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class);
} else if (behavior.getName().equals("LEAD")) { if (entity instanceof EnderDragonEntity && new_friendship == 3) {
LeadPlayerGoal leadGoal = new LeadPlayerGoal(player, entity, entitySpeedMedium); // Trigger end of game (friendship always wins!)
EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class); EnderDragonEntity dragon = (EnderDragonEntity) entity;
EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class); dragon.getFight().dragonKilled(dragon);
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
EntityBehaviorManager.addGoal(entity, leadGoal, GoalPriority.LEAD_PLAYER);
} else if (behavior.getName().equals("UNLEAD")) {
EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class);
} else if (behavior.getName().equals("FRIENDSHIP")) {
int new_friendship = Math.max(-3, Math.min(3, behavior.getArgument()));
if (new_friendship > 0) {
// positive friendship (apply friend goal)
((LivingEntityInterface) entity).setCanTargetPlayers(false);
} else if (new_friendship <= 0) {
// negative friendship (remove friend goal)
((LivingEntityInterface) entity).setCanTargetPlayers(true);
}
// Does friendship improve?
if (new_friendship > this.friendship) {
// Stop any attack/flee if friendship improves
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
if (entity instanceof EnderDragonEntity && new_friendship == 3) {
// Trigger end of game (friendship always wins!)
EnderDragonEntity dragon = (EnderDragonEntity) entity;
dragon.getFight().dragonKilled(dragon);
}
} }
this.friendship = new_friendship;
} }
this.friendship = new_friendship;
} }
} }
......
...@@ -11,8 +11,10 @@ import java.util.concurrent.TimeUnit; ...@@ -11,8 +11,10 @@ import java.util.concurrent.TimeUnit;
*/ */
public class ChatDataSaverScheduler { public class ChatDataSaverScheduler {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private MinecraftServer server = null;
public void startAutoSaveTask(MinecraftServer server, long interval, TimeUnit timeUnit) { public void startAutoSaveTask(MinecraftServer server, long interval, TimeUnit timeUnit) {
this.server = server;
ChatDataAutoSaver saverTask = new ChatDataAutoSaver(server); ChatDataAutoSaver saverTask = new ChatDataAutoSaver(server);
scheduler.scheduleAtFixedRate(saverTask, 1, interval, timeUnit); scheduler.scheduleAtFixedRate(saverTask, 1, interval, timeUnit);
} }
...@@ -20,4 +22,9 @@ public class ChatDataSaverScheduler { ...@@ -20,4 +22,9 @@ public class ChatDataSaverScheduler {
public void stopAutoSaveTask() { public void stopAutoSaveTask() {
scheduler.shutdown(); scheduler.shutdown();
} }
// Schedule a task to run after 1 tick (basically immediately)
public void scheduleTask(Runnable task) {
scheduler.schedule(() -> server.execute(task), 50, TimeUnit.MILLISECONDS);
}
} }
...@@ -61,14 +61,16 @@ public class LeadPlayerGoal extends PlayerBaseGoal { ...@@ -61,14 +61,16 @@ public class LeadPlayerGoal extends PlayerBaseGoal {
foundWaypoint = true; foundWaypoint = true;
LOGGER.info("destination reached"); LOGGER.info("destination reached");
// Prepare a message about the interaction ServerPackets.scheduler.scheduleTask(() -> {
String arrivedMessage = "<You have arrived at your destination>"; // Prepare a message about the interaction
String arrivedMessage = "<You have arrived at your destination>";
ChatDataManager chatDataManager = ChatDataManager.getServerInstance();
ChatDataManager.EntityChatData chatData = chatDataManager.getOrCreateChatData(this.entity.getUuidAsString()); ChatDataManager chatDataManager = ChatDataManager.getServerInstance();
if (!chatData.characterSheet.isEmpty() && chatData.auto_generated < chatDataManager.MAX_AUTOGENERATE_RESPONSES) { ChatDataManager.EntityChatData chatData = chatDataManager.getOrCreateChatData(this.entity.getUuidAsString());
ServerPackets.generate_chat("N/A", chatData, (ServerPlayerEntity) this.targetEntity, this.entity, arrivedMessage, true); if (!chatData.characterSheet.isEmpty() && chatData.auto_generated < chatDataManager.MAX_AUTOGENERATE_RESPONSES) {
} ServerPackets.generate_chat("N/A", chatData, (ServerPlayerEntity) this.targetEntity, this.entity, arrivedMessage, true);
}
});
// Stop navigation // Stop navigation
this.entity.getNavigation().stop(); this.entity.getNavigation().stop();
......
...@@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit; ...@@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit;
public class ServerPackets { public class ServerPackets {
public static final Logger LOGGER = LoggerFactory.getLogger("creaturechat"); public static final Logger LOGGER = LoggerFactory.getLogger("creaturechat");
public static MinecraftServer serverInstance; public static MinecraftServer serverInstance;
private static ChatDataSaverScheduler scheduler = null; public static ChatDataSaverScheduler scheduler = null;
public static final Identifier PACKET_C2S_GREETING = new Identifier("creaturechat", "packet_c2s_greeting"); public static final Identifier PACKET_C2S_GREETING = new Identifier("creaturechat", "packet_c2s_greeting");
public static final Identifier PACKET_C2S_READ_NEXT = new Identifier("creaturechat", "packet_c2s_read_next"); public static final Identifier PACKET_C2S_READ_NEXT = new Identifier("creaturechat", "packet_c2s_read_next");
public static final Identifier PACKET_C2S_SET_STATUS = new Identifier("creaturechat", "packet_c2s_set_status"); public static final Identifier PACKET_C2S_SET_STATUS = new Identifier("creaturechat", "packet_c2s_set_status");
...@@ -295,10 +295,8 @@ public class ServerPackets { ...@@ -295,10 +295,8 @@ public class ServerPackets {
public static void generate_chat(String userLanguage, ChatDataManager.EntityChatData chatData, ServerPlayerEntity player, MobEntity entity, String message, boolean is_auto_message) { public static void generate_chat(String userLanguage, ChatDataManager.EntityChatData chatData, ServerPlayerEntity player, MobEntity entity, String message, boolean is_auto_message) {
// Set talk to player goal (prevent entity from walking off) // Set talk to player goal (prevent entity from walking off)
if (!is_auto_message) { TalkPlayerGoal talkGoal = new TalkPlayerGoal(player, entity, 3.5F);
TalkPlayerGoal talkGoal = new TalkPlayerGoal(player, entity, 3.5F); EntityBehaviorManager.addGoal(entity, talkGoal, GoalPriority.TALK_PLAYER);
EntityBehaviorManager.addGoal(entity, talkGoal, GoalPriority.TALK_PLAYER);
}
// Add new message // Add new message
LOGGER.info("Player message received: " + message + " | Entity: " + entity.getType().toString()); LOGGER.info("Player message received: " + message + " | Entity: " + entity.getType().toString());
......
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