Commit 458fdb2b by Jonathan Thomas

- Allow entity to generate text, if they already have a character sheet, and a player attacks them

parent 9871bbbe
Pipeline #12015 passed with stage
in 20 seconds
...@@ -83,6 +83,7 @@ public class ChatDataManager { ...@@ -83,6 +83,7 @@ public class ChatDataManager {
public String characterSheet; public String characterSheet;
public ChatSender sender; public ChatSender sender;
public int friendship; // -3 to 3 (0 = neutral) public int friendship; // -3 to 3 (0 = neutral)
public boolean auto_generated;
public EntityChatData(String entityId, String playerId) { public EntityChatData(String entityId, String playerId) {
this.entityId = entityId; this.entityId = entityId;
...@@ -94,6 +95,7 @@ public class ChatDataManager { ...@@ -94,6 +95,7 @@ public class ChatDataManager {
this.status = ChatStatus.NONE; this.status = ChatStatus.NONE;
this.sender = ChatSender.USER; this.sender = ChatSender.USER;
this.friendship = 0; this.friendship = 0;
this.auto_generated = false;
} }
// Light version with no 'previousMessages' attribute // Light version with no 'previousMessages' attribute
...@@ -203,8 +205,9 @@ public class ChatDataManager { ...@@ -203,8 +205,9 @@ public class ChatDataManager {
} }
// Generate greeting // Generate greeting
public void generateMessage(ServerPlayerEntity player, String systemPrompt, String userMessage) { public void generateMessage(ServerPlayerEntity player, String systemPrompt, String userMessage, boolean is_auto_message) {
this.status = ChatStatus.PENDING; this.status = ChatStatus.PENDING;
this.auto_generated = is_auto_message;
// Add USER Message // Add USER Message
if (systemPrompt == "system-character") { if (systemPrompt == "system-character") {
// Add message without playerId (so it does not display) // Add message without playerId (so it does not display)
......
package com.owlmaddie.mixin; package com.owlmaddie.mixin;
import com.owlmaddie.chat.ChatDataManager;
import com.owlmaddie.network.ServerPackets;
import com.owlmaddie.utils.LivingEntityInterface; import com.owlmaddie.utils.LivingEntityInterface;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(LivingEntity.class) @Mixin(LivingEntity.class)
public class MixinLivingEntity implements LivingEntityInterface { public class MixinLivingEntity implements LivingEntityInterface {
private boolean canTargetPlayers = true; // Default to true to maintain original behavior private boolean canTargetPlayers = true; // Default to true to maintain original behavior
...@@ -19,6 +27,40 @@ public class MixinLivingEntity implements LivingEntityInterface { ...@@ -19,6 +27,40 @@ public class MixinLivingEntity implements LivingEntityInterface {
} }
} }
@Inject(method = "damage", at = @At(value = "RETURN"))
private void onDamage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir) {
if (!cir.getReturnValue()) {
// If damage method returned false, it means the damage was not applied (possibly due to invulnerability).
return;
}
// Get attacker and entity objects
Entity attacker = source.getAttacker();
LivingEntity thisEntity = (LivingEntity) (Object) this;
// If PLAYER attacks MOB then
if (attacker instanceof PlayerEntity && thisEntity instanceof MobEntity && !thisEntity.isDead()) {
// Generate attacked message (only if the previous user message was not an attacked message)
// We don't want to constantly generate messages during a prolonged, multi-damage event
ChatDataManager chatDataManager = ChatDataManager.getServerInstance();
ChatDataManager.EntityChatData chatData = chatDataManager.getOrCreateChatData(thisEntity.getUuidAsString());
if (!chatData.characterSheet.isEmpty() && !chatData.auto_generated) {
// Only auto-generate a response to being attacked if chat data already exists
// and this is the first attack event.
ServerPlayerEntity player = (ServerPlayerEntity)attacker;
ItemStack weapon = player.getMainHandStack();
String weaponName = weapon.isEmpty() ? "with fists" : "with " + weapon.getItem().toString();
// Determine if the damage was indirect
boolean isIndirect = source.isIndirect();
String directness = isIndirect ? "indirectly" : "directly";
String attackedMessage = "<" + player.getName().getString() + " attacked you " + directness + " with " + weaponName + ">";
ServerPackets.generate_chat(chatData, player, (MobEntity)thisEntity, attackedMessage, true);
}
}
}
@Override @Override
public void setCanTargetPlayers(boolean canTarget) { public void setCanTargetPlayers(boolean canTarget) {
this.canTargetPlayers = canTarget; this.canTargetPlayers = canTarget;
......
...@@ -146,7 +146,7 @@ public class ServerPackets { ...@@ -146,7 +146,7 @@ public class ServerPackets {
if (chatData.characterSheet.isEmpty()) { if (chatData.characterSheet.isEmpty()) {
generate_character(chatData, player, entity); generate_character(chatData, player, entity);
} else { } else {
generate_chat(chatData, player, entity, message); generate_chat(chatData, player, entity, message, false);
} }
} }
}); });
...@@ -253,17 +253,17 @@ public class ServerPackets { ...@@ -253,17 +253,17 @@ public class ServerPackets {
userMessageBuilder.append("who lives near the ").append(player_biome).append("."); userMessageBuilder.append("who lives near the ").append(player_biome).append(".");
LOGGER.info(userMessageBuilder.toString()); LOGGER.info(userMessageBuilder.toString());
chatData.generateMessage(player, "system-character", userMessageBuilder.toString()); chatData.generateMessage(player, "system-character", userMessageBuilder.toString(), false);
} }
public static void generate_chat(ChatDataManager.EntityChatData chatData, ServerPlayerEntity player, MobEntity entity, String message) { public static void generate_chat(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)
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());
chatData.generateMessage(player, "system-chat", message); chatData.generateMessage(player, "system-chat", message, is_auto_message);
} }
// Send new message to all connected players // Send new message to all connected players
......
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