Requirement System for Items

This commit is contained in:
Kam committed 2025-02-28 18:17:39 -05:00
1 parent 413236b0b5
commit 2d89b8d450
8 files changed
+170 -15

No files matched your search

@@ -3,6 +3,8 @@ package kamkeel.npcs;
import kamkeel.npcs.controllers.AttributeController;
import kamkeel.npcs.controllers.data.attribute.AttributeDefinition;
import kamkeel.npcs.controllers.data.attribute.AttributeValueType;
import kamkeel.npcs.controllers.data.attribute.requirement.QuestCompletedRequirement;
import kamkeel.npcs.controllers.data.attribute.requirement.RequirementCheckerRegistry;
/**
* ModAttributes registers the core attributes (both non–magic and magic–based).
@@ -52,5 +54,9 @@ public class CustomAttributes {
MAGIC_DEFENSE = AttributeController.registerAttribute(MAGIC_DEFENSE_KEY, "Magic Defense", 'b', AttributeValueType.MAGIC, AttributeDefinition.AttributeSection.BASE);
MAGIC_RESISTANCE = AttributeController.registerAttribute(MAGIC_RESISTANCE_KEY, "Magic Resistance", 'b', AttributeValueType.MAGIC, AttributeDefinition.AttributeSection.MODIFIER);
// Requirement
RequirementCheckerRegistry.registerChecker(new QuestCompletedRequirement());
}
}
@@ -5,7 +5,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.item.ItemStack;
@@ -195,17 +194,52 @@ public class AttributeCommand extends CommandKamkeelBase {
}
}
@Override
public List addTabCompletionOptions(ICommandSender sender, String[] args) {
// For the first parameter of the subcommand (apply or remove), list available attribute keys.
if(args.length == 1) {
List<String> keys = new ArrayList<>();
for (AttributeDefinition def : AttributeController.getAllAttributes()) {
keys.add(def.getKey());
}
return CommandBase.getListOfStringsMatchingLastWord(args, keys.toArray(new String[keys.size()]));
@SubCommand(
name = "requirement",
usage = "<apply|remove> <requirement> [value]",
desc = "Apply or remove a requirement from your held item."
)
public void requirement(ICommandSender sender, String[] args) throws CommandException {
if (!(sender instanceof EntityPlayer)) {
sendError(sender, "Only players can use this command.");
return;
}
EntityPlayer player = (EntityPlayer) sender;
ItemStack held = player.getHeldItem();
if (held == null) {
sendError(sender, "You are not holding an item.");
return;
}
if (args.length < 2) {
sendError(sender, "Usage: requirement <apply|remove> <requirementKey> [value]");
return;
}
String action = args[0];
String reqKey = args[1];
if (action.equalsIgnoreCase("apply")) {
if (args.length < 3) {
sendError(sender, "Usage: requirement apply <requirementKey> <value>");
return;
}
String valueStr = args[2];
Object value;
try {
value = Integer.parseInt(valueStr);
} catch (NumberFormatException e1) {
try {
value = Float.parseFloat(valueStr);
} catch (NumberFormatException e2) {
value = valueStr;
}
}
AttributeItemUtil.applyRequirement(held, reqKey, value);
sendResult(sender, "Applied requirement " + reqKey + " with value " + value + " to held item.");
} else if (action.equalsIgnoreCase("remove")) {
AttributeItemUtil.removeRequirement(held, reqKey);
sendResult(sender, "Removed requirement " + reqKey + " from held item.");
} else {
sendError(sender, "Invalid action. Use apply or remove.");
}
// If the attribute is magic and we are completing the magicID parameter, you could return dummy numbers.
return super.addTabCompletionOptions(sender, args);
}
}
@@ -1,5 +1,6 @@
package kamkeel.npcs.command;
import kamkeel.npcs.controllers.data.attribute.requirement.RequirementCheckerRegistry;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
@@ -119,6 +120,9 @@ public class CommandKamkeel extends CommandBase{
keys.add(def.getKey());
}
return CommandBase.getListOfStringsMatchingLastWord(args, keys.toArray(new String[keys.size()]));
} else if (usage.equals("<requirement>")) {
List<String> keys = new ArrayList<>(RequirementCheckerRegistry.getAllKeys());
return CommandBase.getListOfStringsMatchingLastWord(args, keys.toArray(new String[keys.size()]));
}
}
}
@@ -7,6 +7,11 @@ public interface IRequirementChecker {
public String getKey();
public String getTranslation();
String getTooltipValue(NBTTagCompound nbt);
void apply(NBTTagCompound nbt, Object value);
/**
* Checks the requirement in the provided NBT.
@@ -2,6 +2,7 @@ package kamkeel.npcs.controllers.data.attribute.requirement;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import noppes.npcs.controllers.QuestController;
import noppes.npcs.controllers.data.PlayerData;
public class QuestCompletedRequirement implements IRequirementChecker {
@@ -11,6 +12,29 @@ public class QuestCompletedRequirement implements IRequirementChecker {
return "cnpc_quest_completed";
}
@Override
public String getTranslation() {
return "quest.quest";
}
@Override
public String getTooltipValue(NBTTagCompound nbt) {
if(nbt.hasKey(getKey())) {
int questID = nbt.getInteger(getKey());
if(QuestController.Instance.get(questID) != null) {
return QuestController.Instance.get(questID).getName();
}
}
return "null";
}
@Override
public void apply(NBTTagCompound nbt, Object value) {
if(value instanceof Integer) {
nbt.setInteger(getKey(), (Integer) value);
}
}
@Override
public boolean check(EntityPlayer player, NBTTagCompound nbt) {
if(nbt.hasKey(getKey())) {
@@ -4,13 +4,14 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class RequirementCheckerRegistry {
private static final Map<String, IRequirementChecker> checkers = new HashMap<>();
public static void registerChecker(String key, IRequirementChecker checker) {
if (!checkers.containsKey(key)) {
checkers.put(key, checker);
public static void registerChecker(IRequirementChecker checker) {
if (!checkers.containsKey(checker.getKey())) {
checkers.put(checker.getKey(), checker);
}
}
@@ -29,4 +30,12 @@ public class RequirementCheckerRegistry {
}
return true;
}
public static Set<String> getAllKeys() {
return checkers.keySet();
}
public static IRequirementChecker getChecker(String key) {
return checkers.get(key);
}
}
@@ -10,6 +10,7 @@ import kamkeel.npcs.controllers.AttributeController;
import kamkeel.npcs.controllers.data.attribute.AttributeDefinition;
import kamkeel.npcs.controllers.data.attribute.ICustomAttribute;
import kamkeel.npcs.controllers.data.attribute.PlayerAttributeMap;
import kamkeel.npcs.controllers.data.attribute.requirement.RequirementCheckerRegistry;
import kamkeel.npcs.util.AttributeAttackUtil;
import kamkeel.npcs.util.AttributeItemUtil;
import net.minecraft.entity.SharedMonsterAttributes;
@@ -17,6 +18,7 @@ import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
public class PlayerAttributeTracker {
@@ -60,6 +62,16 @@ public class PlayerAttributeTracker {
ItemStack[] equipment = new ItemStack[] { currentEquip.heldItem, currentEquip.boots, currentEquip.leggings, currentEquip.chestplate, currentEquip.helmet };
for (ItemStack piece : equipment) {
if (piece != null) {
if (piece.stackTagCompound != null && piece.stackTagCompound.hasKey(AttributeItemUtil.TAG_RPGCORE)) {
NBTTagCompound rpgCore = piece.stackTagCompound.getCompoundTag(AttributeItemUtil.TAG_RPGCORE);
if (rpgCore.hasKey(AttributeItemUtil.TAG_REQUIREMENTS)) {
NBTTagCompound reqTag = rpgCore.getCompoundTag(AttributeItemUtil.TAG_REQUIREMENTS);
if (!RequirementCheckerRegistry.checkRequirements(player, reqTag)) {
continue;
}
}
}
for (Entry<String, Float> entry : AttributeItemUtil.readAttributes(piece).entrySet()) {
String key = entry.getKey();
float value = entry.getValue();
@@ -3,6 +3,10 @@ package kamkeel.npcs.util;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import kamkeel.npcs.controllers.AttributeController;
import kamkeel.npcs.controllers.data.attribute.requirement.IRequirementChecker;
import kamkeel.npcs.controllers.data.attribute.requirement.RequirementCheckerRegistry;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
@@ -178,6 +182,43 @@ public class AttributeItemUtil {
}
}
public static void applyRequirement(ItemStack item, String reqKey, Object value) {
if (item == null) return;
if (item.stackTagCompound == null)
item.stackTagCompound = new NBTTagCompound();
NBTTagCompound root = item.stackTagCompound;
// Get (or create) the RPGCore compound.
NBTTagCompound rpgCore = root.hasKey(TAG_RPGCORE) ? root.getCompoundTag(TAG_RPGCORE) : new NBTTagCompound();
// Get (or create) the Requirements compound.
NBTTagCompound reqTag = rpgCore.hasKey(TAG_REQUIREMENTS) ? rpgCore.getCompoundTag(TAG_REQUIREMENTS) : new NBTTagCompound();
// Retrieve the checker from the registry.
IRequirementChecker checker = RequirementCheckerRegistry.getChecker(reqKey);
if (checker != null) {
checker.apply(reqTag, value);
}
rpgCore.setTag(TAG_REQUIREMENTS, reqTag);
root.setTag(TAG_RPGCORE, rpgCore);
}
public static void removeRequirement(ItemStack item, String reqKey) {
if (item == null || item.stackTagCompound == null) return;
NBTTagCompound root = item.stackTagCompound;
if (root.hasKey(TAG_RPGCORE)) {
NBTTagCompound rpgCore = root.getCompoundTag(TAG_RPGCORE);
if (rpgCore.hasKey(TAG_REQUIREMENTS)) {
NBTTagCompound reqTag = rpgCore.getCompoundTag(TAG_REQUIREMENTS);
reqTag.removeTag(reqKey);
if (reqTag.func_150296_c().isEmpty()) {
rpgCore.removeTag(TAG_REQUIREMENTS);
} else {
rpgCore.setTag(TAG_REQUIREMENTS, reqTag);
}
root.setTag(TAG_RPGCORE, rpgCore);
}
}
}
// ----------------- Tooltip Generation with Custom Sorting -------------------
/**
@@ -252,6 +293,26 @@ public class AttributeItemUtil {
newTooltips.addAll(buildSection(infoList)); // alphabetical
newTooltips.addAll(buildSection(extraList)); // alphabetical
if (rpgCore.hasKey(TAG_REQUIREMENTS)) {
NBTTagCompound reqTag = rpgCore.getCompoundTag(TAG_REQUIREMENTS);
List<TooltipEntry> reqEntries = new ArrayList<>();
Minecraft mc = Minecraft.getMinecraft();
EntityPlayer clientPlayer = mc.thePlayer;
Set<String> requirements = reqTag.func_150296_c();
for (String reqKey : requirements) {
IRequirementChecker checker = RequirementCheckerRegistry.getChecker(reqKey);
if (checker != null) {
boolean met = clientPlayer != null && checker.check(clientPlayer, reqTag);
String tooltipValue = checker.getTooltipValue(reqTag);
String color = met ? EnumChatFormatting.GRAY.toString() : EnumChatFormatting.RED.toString();
String line = EnumChatFormatting.GRAY + StatCollector.translateToLocal(checker.getTranslation()) + ": " + color + tooltipValue;
reqEntries.add(new TooltipEntry(stripFormatting(StatCollector.translateToLocal(checker.getTranslation())), line));
}
}
newTooltips.addAll(buildSection(reqEntries));
}
tooltip = newTooltips;
} else {
String keyName = Keyboard.getKeyName(ClientProxy.NPCButton.getKeyCode());