diff --git a/src/api b/src/api index 911695647..5d059aea8 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 91169564745665d38d6f013871dda504b3e3a39f +Subproject commit 5d059aea800f572b7268ac679310ebc8b3d13f6c diff --git a/src/main/java/kamkeel/command/QuestCommand.java b/src/main/java/kamkeel/command/QuestCommand.java index 14c0a408f..887b5e47b 100644 --- a/src/main/java/kamkeel/command/QuestCommand.java +++ b/src/main/java/kamkeel/command/QuestCommand.java @@ -1,18 +1,24 @@ package kamkeel.command; +import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; import noppes.npcs.Server; +import noppes.npcs.api.handler.data.IQuestObjective; import noppes.npcs.constants.EnumPacketClient; import noppes.npcs.constants.EnumQuestCompletion; import noppes.npcs.constants.EnumQuestRepeat; import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.controllers.QuestController; import noppes.npcs.controllers.SyncController; +import noppes.npcs.controllers.data.Party; import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.controllers.data.Quest; import noppes.npcs.controllers.data.QuestData; +import noppes.npcs.util.ValueUtil; import java.util.Collection; import java.util.List; @@ -168,7 +174,7 @@ public class QuestCommand extends CommandKamkeelBase { Quest quest = QuestController.Instance.quests.get(questid); if (quest == null){ - sendError(sender, String.format("Unknown QuestID")); + sendError(sender, "Unknown QuestID"); return; } @@ -181,6 +187,94 @@ public class QuestCommand extends CommandKamkeelBase { } } + @SubCommand( + desc= "Get/Set objectives for quests progress", + usage = " [objective] [value]" + ) + public void objective(ICommandSender sender, String[] args) throws CommandException { + EntityPlayer player = CommandBase.getPlayer(sender, args[0]); + int questid; + try { + questid = Integer.parseInt(args[1]); + } catch (NumberFormatException ex) { + sendError(sender, "QuestID must be an integer: " + args[1]); + return; + } + + Quest quest = QuestController.Instance.quests.get(questid); + if (quest == null){ + sendError(sender, "Unknown QuestID"); + return; + } + + PlayerData data = PlayerDataController.Instance.getPlayerData(player); + if (data == null){ + sendError(sender, "No PlayerData found for:" + player); + return; + } + + Party party = data.getPlayerParty(); + boolean partyValid = party != null && party.getQuest() != null && party.getQuest().getId() == quest.id; + + if(!partyValid && !data.questData.activeQuests.containsKey(quest.id)) { + sendError(sender, "Player does not have quest active"); + return; + } + + IQuestObjective[] objectives; + if(partyValid) + objectives = quest.questInterface.getPartyObjectives(party); + else + objectives = quest.questInterface.getObjectives(player); + + if(args.length <= 2) { + if(partyValid) + sendResult(sender, "For Party: "); + for(IQuestObjective ob : objectives) { + sendResult(sender, ob.getText()); + } + return; + } + + int objective; + try { + objective = Integer.parseInt(args[2]); + } catch (NumberFormatException ex) { + sendError(sender, "Objective must be an integer. Most often 0, 1 or 2"); + return; + } + + if(objective < 0 || objective >= objectives.length) { + sendError(sender, "Invalid objective number was given"); + return; + } + + if(args.length <= 3) { + sendResult(sender, objectives[objective].getText()); + return; + } + + IQuestObjective object = objectives[objective]; + String s = args[3]; + int value; + try { + value = Integer.parseInt(args[3]); + } catch (NumberFormatException ex) { + sendError(sender, "Value must be an integer"); + return; + } + + if(s.startsWith("-") || s.startsWith("+")) { + value = ValueUtil.CorrectInt(object.getProgress() + value, 0, object.getMaxProgress()); + } + + if(partyValid) + object.setPlayerProgress(player.getCommandSenderName(), value); + else + object.setProgress(value); + sendResult(sender, "Successfully updated progress"); + } + @SubCommand( desc = "Find quest id number by its name", usage = "" diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuest.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuest.java index 482b04217..e1c32be0f 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuest.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuest.java @@ -7,6 +7,7 @@ import noppes.npcs.client.gui.global.GuiNPCManageQuest; import noppes.npcs.client.gui.questtypes.GuiNpcQuestTypeDialog; import noppes.npcs.client.gui.questtypes.GuiNpcQuestTypeKill; import noppes.npcs.client.gui.questtypes.GuiNpcQuestTypeLocation; +import noppes.npcs.client.gui.questtypes.GuiNpcQuestTypeManual; import noppes.npcs.client.gui.select.GuiQuestSelection; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.*; @@ -57,7 +58,7 @@ public class SubGuiNpcQuest extends SubGuiInterface implements ISubGuiListener, addButton(new GuiNpcButton(11, guiLeft + 303, guiTop + 52, 50, 20, "selectServer.edit")); addLabel(new GuiNpcLabel(6, "gui.type", guiLeft + 180, guiTop + 81)); - addButton(new GuiNpcButton(6, guiLeft + 240, guiTop + 76, 60, 20, new String[]{"quest.item","quest.dialog","quest.kill","quest.location","quest.areakill"},quest.type.ordinal())); + addButton(new GuiNpcButton(6, guiLeft + 240, guiTop + 76, 60, 20, new String[]{"quest.item","quest.dialog","quest.kill","quest.location","quest.areakill","quest.manual"},quest.type.ordinal())); addButton(new GuiNpcButton(7, guiLeft + 303, guiTop + 76,50, 20, "selectServer.edit")); addLabel(new GuiNpcLabel(17, "party.options", guiLeft + 180, guiTop + 135)); @@ -121,6 +122,9 @@ public class SubGuiNpcQuest extends SubGuiInterface implements ISubGuiListener, if(quest.type == EnumQuestType.AreaKill) setSubGui(new GuiNpcQuestTypeKill(npc, quest, this)); + + if(quest.type == EnumQuestType.Manual) + setSubGui(new GuiNpcQuestTypeManual(npc, quest, this)); } if(button.id == 8) { diff --git a/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeKill.java b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeKill.java index 6112b0c03..19ca84c53 100644 --- a/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeKill.java +++ b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeKill.java @@ -14,21 +14,22 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import java.util.TreeMap; public class GuiNpcQuestTypeKill extends SubGuiInterface implements ITextfieldListener, ICustomScrollListener { private GuiScreen parent; private GuiCustomScroll scroll; - + private QuestKill quest; - + private GuiNpcTextField lastSelected; public GuiNpcQuestTypeKill(EntityNPCInterface npc, Quest q, GuiScreen parent) { this.npc = npc; this.parent = parent; title = "Quest Kill Setup"; - + quest = (QuestKill) q.questInterface; setBackground("largebg.png"); @@ -54,7 +55,7 @@ public class GuiNpcQuestTypeKill extends SubGuiInterface implements ITextfieldLi this.getTextField(i+12).setMinMaxDefault(1, Integer.MAX_VALUE, 1); i++; } - + for(;i < 12; i++){ this.addTextField(new GuiNpcTextField(i, this, fontRendererObj, guiLeft + 4, guiTop + 40 + i * 22, 180, 20, "")); this.addTextField(new GuiNpcTextField(i + 12, this, fontRendererObj, guiLeft + 186, guiTop + 40 + i * 22, 24, 20, "1")); @@ -72,7 +73,7 @@ public class GuiNpcQuestTypeKill extends SubGuiInterface implements ITextfieldLi e.printStackTrace(); } catch (NoSuchMethodException e) { } - } + } if(scroll == null) scroll = new GuiCustomScroll(this,0); scroll.setList(list); @@ -122,7 +123,7 @@ public class GuiNpcQuestTypeKill extends SubGuiInterface implements ITextfieldLi saveTargets(); } private void saveTargets(){ - HashMap map = new HashMap(); + TreeMap map = new TreeMap(); for(int i = 0; i< 12; i++){ String name = getTextField(i).getText(); if(name.isEmpty()) diff --git a/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeManual.java b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeManual.java new file mode 100644 index 000000000..19f2293bb --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeManual.java @@ -0,0 +1,87 @@ +package noppes.npcs.client.gui.questtypes; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import noppes.npcs.client.gui.util.*; +import noppes.npcs.controllers.data.Quest; +import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.quests.QuestManual; + +import java.util.HashMap; +import java.util.TreeMap; + +public class GuiNpcQuestTypeManual extends SubGuiInterface implements ITextfieldListener +{ + private GuiScreen parent; + + private QuestManual quest; + + private GuiNpcTextField lastSelected; + + public GuiNpcQuestTypeManual(EntityNPCInterface npc, Quest q, GuiScreen parent) { + this.npc = npc; + this.parent = parent; + title = "Quest Manual Setup"; + + quest = (QuestManual) q.questInterface; + + setBackground("menubg.png"); + xSize = 356; + ySize = 216; + closeOnEsc = true; + } + + @Override + public void initGui() { + super.initGui(); + int i = 0; + addLabel(new GuiNpcLabel(0, "You can fill in npc or player names too", guiLeft + 4, guiTop + 50)); + for (String name : quest.manuals.keySet()) { + this.addTextField(new GuiNpcTextField(i, this, fontRendererObj, guiLeft + 4, guiTop + 70 + i * 22, 180, 20, name)); + this.addTextField(new GuiNpcTextField(i + 3, this, fontRendererObj, guiLeft + 186, guiTop + 70 + i * 22, 24, 20, quest.manuals.get(name) + "")); + this.getTextField(i+3).integersOnly = true; + this.getTextField(i+3).setMinMaxDefault(1, Integer.MAX_VALUE, 1); + i++; + } + + for(;i < 3; i++){ + this.addTextField(new GuiNpcTextField(i, this, fontRendererObj, guiLeft + 4, guiTop + 70 + i * 22, 180, 20, "")); + this.addTextField(new GuiNpcTextField(i + 3, this, fontRendererObj, guiLeft + 186, guiTop + 70 + i * 22, 24, 20, "1")); + this.getTextField(i+3).integersOnly = true; + this.getTextField(i+3).setMinMaxDefault(1, Integer.MAX_VALUE, 1); + } + this.addButton(new GuiNpcButton(0, guiLeft + 4, guiTop + 140, 98, 20, "gui.back")); + + } + + @Override + protected void actionPerformed(GuiButton guibutton) { + super.actionPerformed(guibutton); + if (guibutton.id == 0) { + close(); + } + } + + @Override + public void save() { + } + + @Override + public void unFocused(GuiNpcTextField guiNpcTextField) { + if(guiNpcTextField.id < 3) + lastSelected = guiNpcTextField; + + saveTargets(); + } + + private void saveTargets(){ + TreeMap map = new TreeMap(); + for(int i = 0; i< 3; i++){ + String name = getTextField(i).getText(); + if(name.isEmpty()) + continue; + map.put(name, getTextField(i+3).getInteger()); + } + quest.manuals = map; + } +} diff --git a/src/main/java/noppes/npcs/constants/EnumQuestType.java b/src/main/java/noppes/npcs/constants/EnumQuestType.java index 2ca6b0591..315fee0b8 100644 --- a/src/main/java/noppes/npcs/constants/EnumQuestType.java +++ b/src/main/java/noppes/npcs/constants/EnumQuestType.java @@ -1,5 +1,5 @@ package noppes.npcs.constants; public enum EnumQuestType { - Item, Dialog, Kill, Location, AreaKill; + Item, Dialog, Kill, Location, AreaKill, Manual; } diff --git a/src/main/java/noppes/npcs/controllers/data/Quest.java b/src/main/java/noppes/npcs/controllers/data/Quest.java index 5ffb91914..d780ee053 100644 --- a/src/main/java/noppes/npcs/controllers/data/Quest.java +++ b/src/main/java/noppes/npcs/controllers/data/Quest.java @@ -13,9 +13,14 @@ import noppes.npcs.constants.EnumQuestRepeat; import noppes.npcs.constants.EnumQuestType; import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.controllers.QuestController; -import noppes.npcs.quests.*; import noppes.npcs.scripted.CustomNPCsException; import noppes.npcs.scripted.NpcAPI; +import noppes.npcs.quests.QuestDialog; +import noppes.npcs.quests.QuestInterface; +import noppes.npcs.quests.QuestItem; +import noppes.npcs.quests.QuestKill; +import noppes.npcs.quests.QuestLocation; +import noppes.npcs.quests.QuestManual; public class Quest implements ICompatibilty, IQuest { public int version = VersionCompatibility.ModRev; @@ -87,6 +92,8 @@ public class Quest implements ICompatibilty, IQuest { questInterface = new QuestKill(); else if(type == EnumQuestType.Location) questInterface = new QuestLocation(); + else if(type == EnumQuestType.Manual) + questInterface = new QuestManual(); if(questInterface != null) questInterface.questId = id; diff --git a/src/main/java/noppes/npcs/quests/QuestDialog.java b/src/main/java/noppes/npcs/quests/QuestDialog.java index 30e9805ee..7a5e10a57 100644 --- a/src/main/java/noppes/npcs/quests/QuestDialog.java +++ b/src/main/java/noppes/npcs/quests/QuestDialog.java @@ -392,7 +392,79 @@ public class QuestDialog extends QuestInterface implements IQuestDialog { } } - public int getMaxProgress() { + @Override + public void setPlayerProgress(String playerName, int progress) { + if (progress >= 0 && progress <= 1) { + EntityPlayer foundplayer = NoppesUtilServer.getPlayerByName(playerName); + if(foundplayer != null && party == null){ + PlayerData data = PlayerDataController.Instance.getPlayerData(foundplayer); + boolean completed = data.dialogData.dialogsRead.contains(this.dialog.id); + if (progress == 0 && completed) { + data.dialogData.dialogsRead.remove(this.dialog.id); + data.questData.checkQuestCompletion(data, EnumQuestType.values()[1]); + data.updateClient = true; + data.save(); + } + + if (progress == 1 && !completed) { + data.dialogData.dialogsRead.add(this.dialog.id); + data.questData.checkQuestCompletion(data, EnumQuestType.values()[1]); + data.updateClient = true; + data.save(); + } + } else if (foundplayer != null){ + if(party.getObjectiveRequirement() != null){ + EnumPartyObjectives objectives = party.getObjectiveRequirement(); + if(objectives == EnumPartyObjectives.Leader){ + EntityPlayer leaderPlayer = NoppesUtilServer.getPlayer(party.getLeaderUUID()); + PlayerData leaderData; + if(leaderPlayer != null){ + leaderData = PlayerDataController.Instance.getPlayerData(leaderPlayer); + } + else { + leaderData = PlayerDataController.Instance.getPlayerDataCache(party.getLeaderUUID().toString()); + } + if(leaderData == null) + return; + + boolean completed = leaderData.dialogData.dialogsRead.contains(this.dialog.id); + if (progress == 0 && completed) { + leaderData.dialogData.dialogsRead.remove(this.dialog.id); + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.values()[1]); + leaderData.updateClient = true; + leaderData.save(); + } + if (progress == 1 && !completed) { + leaderData.dialogData.dialogsRead.add(this.dialog.id); + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.values()[1]); + leaderData.updateClient = true; + leaderData.save(); + } + } else { + PlayerData individualData = PlayerDataController.Instance.getPlayerData(foundplayer); + if(individualData != null){ + boolean completed = individualData.dialogData.dialogsRead.contains(this.dialog.id); + if (progress == 0 && completed) { + individualData.dialogData.dialogsRead.remove(this.dialog.id); + individualData.save(); + individualData.updateClient = true; + } + if (progress == 1 && !completed) { + individualData.dialogData.dialogsRead.add(this.dialog.id); + individualData.save(); + individualData.updateClient = true; + } + } + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.values()[1]); + } + } + } + } else { + throw new CustomNPCsException("Progress has to be 0 or 1", new Object[0]); + } + } + + public int getMaxProgress() { return 1; } diff --git a/src/main/java/noppes/npcs/quests/QuestItem.java b/src/main/java/noppes/npcs/quests/QuestItem.java index 90b9c9715..c864adad1 100644 --- a/src/main/java/noppes/npcs/quests/QuestItem.java +++ b/src/main/java/noppes/npcs/quests/QuestItem.java @@ -539,7 +539,12 @@ public class QuestItem extends QuestInterface implements IQuestItem { throw new CustomNPCsException("Cant set the progress of ItemQuests", new Object[0]); } - public int getMaxProgress() { + @Override + public void setPlayerProgress(String playerName, int progress) { + throw new CustomNPCsException("Cant set the progress of ItemQuests", new Object[0]); + } + + public int getMaxProgress() { if(party != null && party.getObjectiveRequirement() != null){ EnumPartyObjectives objectives = party.getObjectiveRequirement(); if(objectives == EnumPartyObjectives.All){ diff --git a/src/main/java/noppes/npcs/quests/QuestKill.java b/src/main/java/noppes/npcs/quests/QuestKill.java index a62a0f58d..1f6f4e3d4 100644 --- a/src/main/java/noppes/npcs/quests/QuestKill.java +++ b/src/main/java/noppes/npcs/quests/QuestKill.java @@ -3,6 +3,7 @@ package noppes.npcs.quests; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.NBTTags; +import noppes.npcs.NoppesUtilServer; import noppes.npcs.api.handler.data.IQuestKill; import noppes.npcs.api.handler.data.IQuestObjective; import noppes.npcs.constants.EnumPartyObjectives; @@ -18,7 +19,7 @@ import noppes.npcs.scripted.CustomNPCsException; import java.util.*; public class QuestKill extends QuestInterface implements IQuestKill { - public HashMap targets = new HashMap(); + public TreeMap targets = new TreeMap(); public int targetType = 0; public String customTargetType = "noppes.npcs.entity.EntityCustomNpc"; @@ -33,10 +34,10 @@ public class QuestKill extends QuestInterface implements IQuestKill { public void readEntityFromNBT(NBTTagCompound compound) { if(!compound.hasKey("QuestKills")) { targets.clear(); - HashMap oldTargets = NBTTags.getStringIntegerMap(compound.getTagList("QuestDialogs", 10)); + TreeMap oldTargets = new TreeMap(NBTTags.getStringIntegerMap(compound.getTagList("QuestDialogs", 10))); targets.putAll(oldTargets); } else { - targets = NBTTags.getStringIntegerMap(compound.getTagList("QuestKills", 10)); + targets = new TreeMap(NBTTags.getStringIntegerMap(compound.getTagList("QuestKills", 10))); } targetType = compound.getInteger("TargetType"); customTargetType = compound.getString("CustomTargetType"); @@ -235,6 +236,7 @@ public class QuestKill extends QuestInterface implements IQuestKill { this.targetType = type; } + public int getTargetType() { return this.targetType; } @@ -339,7 +341,54 @@ public class QuestKill extends QuestInterface implements IQuestKill { } } - public int getMaxProgress() { + @Override + public void setPlayerProgress(String playerName, int progress) { + if (progress >= 0 && progress <= this.amount) { + EntityPlayer foundplayer = NoppesUtilServer.getPlayerByName(playerName); + if(foundplayer != null && party == null){ + PlayerData data = PlayerDataController.Instance.getPlayerData(foundplayer); + PlayerQuestData playerdata = data.questData; + QuestData questdata = (QuestData)playerdata.activeQuests.get(this.parent.questId); + if(questdata != null){ + HashMap killed = this.parent.getKilled(questdata); + if (!killed.containsKey(this.entity) || (Integer)killed.get(this.entity) != progress) { + killed.put(this.entity, progress); + this.parent.setKilled(questdata, killed); + data.questData.checkQuestCompletion(data, EnumQuestType.values()[2]); + data.questData.checkQuestCompletion(data, EnumQuestType.values()[4]); + data.updateClient = true; + data.save(); + } + } + } else if (foundplayer != null){ + QuestData questdata = party.getQuestData(); + if(questdata != null){ + if(questdata.quest.partyOptions.objectiveRequirement == EnumPartyObjectives.All){ + HashMap killed = this.parent.getPlayerKilled(questdata, playerName); + if (!killed.containsKey(this.entity) || (Integer)killed.get(this.entity) != progress) { + killed.put(this.entity, progress); + this.parent.setPlayerKilled(questdata, killed, playerName); + } + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.values()[2]); + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.values()[4]); + } + else { + HashMap killed = this.parent.getKilled(questdata); + if (!killed.containsKey(this.entity) || (Integer)killed.get(this.entity) != progress) { + killed.put(this.entity, progress); + this.parent.setKilled(questdata, killed); + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.values()[2]); + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.values()[4]); + } + } + } + } + } else { + throw new CustomNPCsException("Progress has to be between 0 and " + this.amount, new Object[0]); + } + } + + public int getMaxProgress() { return this.amount; } @@ -376,7 +425,6 @@ public class QuestKill extends QuestInterface implements IQuestKill { } } } - return null; } } diff --git a/src/main/java/noppes/npcs/quests/QuestLocation.java b/src/main/java/noppes/npcs/quests/QuestLocation.java index 14b895855..85b09d1c0 100644 --- a/src/main/java/noppes/npcs/quests/QuestLocation.java +++ b/src/main/java/noppes/npcs/quests/QuestLocation.java @@ -4,6 +4,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; import noppes.npcs.NBTTags; +import noppes.npcs.NoppesUtilServer; import noppes.npcs.api.handler.data.IQuestLocation; import noppes.npcs.api.handler.data.IQuestObjective; import noppes.npcs.constants.EnumPartyObjectives; @@ -370,7 +371,45 @@ public class QuestLocation extends QuestInterface implements IQuestLocation { } } - public int getMaxProgress() { + @Override + public void setPlayerProgress(String playerName, int progress) { + if (progress >= 0 && progress <= 1) { + EntityPlayer foundplayer = NoppesUtilServer.getPlayerByName(playerName); + if(foundplayer != null && party == null){ + PlayerData data = PlayerDataController.Instance.getPlayerData(foundplayer); + QuestData questData = (QuestData)data.questData.activeQuests.get(this.parent.questId); + boolean completed = questData.extraData.getBoolean (this.nbtName); + if ((!completed || progress != 1) && (completed || progress != 0)) { + questData.extraData.setBoolean(this.nbtName, progress == 1); + data.questData.checkQuestCompletion(data, EnumQuestType.values()[3]); + data.save(); + data.updateClient = true; + } + } else if (foundplayer != null){ + QuestData questData = party.getQuestData(); + boolean completed = questData.extraData.getBoolean (this.nbtName); + if ((!completed || progress != 1) && (completed || progress != 0)) { + boolean setTo = progress == 1; + questData.extraData.setBoolean(this.nbtName, setTo); + if(questData.quest.partyOptions.objectiveRequirement == EnumPartyObjectives.All){ + if(setTo){ + if(!completedPlayers.contains(foundplayer.getCommandSenderName())) + completedPlayers.add(foundplayer.getCommandSenderName()); + } else { + completedPlayers.remove(foundplayer.getCommandSenderName()); + } + String locationKey = "Players" + nbtName; + questData.extraData.setTag(locationKey, NBTTags.nbtStringList(completedPlayers)); + } + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.values()[3]); + } + } + } else { + throw new CustomNPCsException("Progress has to be 0 or 1", new Object[0]); + } + } + + public int getMaxProgress() { return 1; } diff --git a/src/main/java/noppes/npcs/quests/QuestManual.java b/src/main/java/noppes/npcs/quests/QuestManual.java new file mode 100644 index 000000000..b4e680806 --- /dev/null +++ b/src/main/java/noppes/npcs/quests/QuestManual.java @@ -0,0 +1,380 @@ +package noppes.npcs.quests; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; +import noppes.npcs.NBTTags; +import noppes.npcs.NoppesUtilServer; +import noppes.npcs.api.handler.data.IQuestObjective; +import noppes.npcs.constants.EnumPartyObjectives; +import noppes.npcs.constants.EnumQuestType; +import noppes.npcs.controllers.PartyController; +import noppes.npcs.controllers.PlayerDataController; +import noppes.npcs.controllers.data.Party; +import noppes.npcs.controllers.data.PlayerData; +import noppes.npcs.controllers.data.PlayerQuestData; +import noppes.npcs.controllers.data.QuestData; +import noppes.npcs.scripted.CustomNPCsException; + +import java.util.*; +import java.util.Map.Entry; + +public class QuestManual extends QuestInterface{ + public TreeMap manuals = new TreeMap(); + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + manuals = new TreeMap<>(NBTTags.getStringIntegerMap(compound.getTagList("QuestManual", 10))); + } + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + compound.setTag("QuestManual", NBTTags.nbtStringIntegerMap(manuals)); + } + + @Override + public boolean isCompleted(PlayerData playerData) { + if(playerData == null) + return false; + + QuestData data = playerData.questData.activeQuests.get(questId); + if(data == null) + return false; + HashMap manual = getManual(data); + if (manuals.size() != manual.size()) + return false; + + for (String entity : manuals.keySet()) { + if (!manual.containsKey(entity) || manual.get(entity) < manuals.get(entity)) + return false; + } + + return true; + } + + @Override + public void handleComplete(EntityPlayer player) {} + + @Override + public Vector getQuestLogStatus(EntityPlayer player) { + Vector vec = new Vector(); + PlayerData playerdata = PlayerDataController.Instance.getPlayerData(player); + if (playerdata == null) + return vec; + + QuestData data = playerdata.questData.activeQuests.get(questId); + if (data == null) + return vec; + + HashMap manual = getManual(data); + for (String entity : manuals.keySet()) { + vec.add(entity + ": " + manual.getOrDefault(entity, 0) + "/" + manuals.get(entity)); + } + return vec; + } + + public HashMap getManual(QuestData data) { + return NBTTags.getStringIntegerMap(data.extraData.getTagList("Manual", 10)); + } + + public void setManual(QuestData data, HashMap manual) { + data.extraData.setTag("Manual", NBTTags.nbtStringIntegerMap(manual)); + } + + public HashMap getPlayerManual(QuestData data, String playerName) { + return NBTTags.getStringIntegerMap(data.extraData.getTagList(playerName + "Manual", 10)); + } + public void setPlayerManual(QuestData data, HashMap playerManual, String playerName) { + data.extraData.setTag(playerName + "Manual", NBTTags.nbtStringIntegerMap(playerManual)); + } + + @Override + public IQuestObjective[] getObjectives(EntityPlayer player) { + List list = new ArrayList(); + for(Entry entry : manuals.entrySet()){ + list.add(new QuestManualObjective(player, entry.getKey(), entry.getValue())); + } + return list.toArray(new IQuestObjective[list.size()]); + } + + @Override + public IQuestObjective[] getPartyObjectives(Party party){ + List list = new ArrayList(); + for(Entry entry : manuals.entrySet()){ + list.add(new QuestManualObjective(party, entry.getKey(), entry.getValue())); + } + return (IQuestObjective[])list.toArray(new IQuestObjective[list.size()]); + } + + @Override + public Vector getPartyQuestLogStatus(Party party) { + Vector vec = new Vector(); + QuestData data = party.getQuestData(); + if(data == null) + return vec; + + if(data.quest.partyOptions.objectiveRequirement == EnumPartyObjectives.All){ + for(String entityName : manuals.keySet()){ + String firstLine = entityName + ": " + manuals.get(entityName); + List playerResults = new ArrayList<>(); + for(String player : party.getPlayerNames()){ + HashMap playerManual = getPlayerManual(data, player); + int amount = 0; + if(playerManual.containsKey(entityName)) + amount = playerManual.get(entityName); + + if(amount < manuals.get(entityName)){ + String state = player + ": " + amount; + playerResults.add(state); + } + } + + if(!playerResults.isEmpty()){ + vec.add(firstLine); + vec.add("[" + String.join(", ", playerResults) + "]"); + } + else { + vec.add(firstLine + " (Done)"); + } + } + } + else { + HashMap manual = getManual(data); + for (String entity : manuals.keySet()) { + int amount = 0; + if(manual.containsKey(entity)) + amount = manual.get(entity); + String state = amount + "/" + manuals.get(entity); + vec.add(entity + ": " + state); + } + } + return vec; + } + + @Override + public boolean isPartyCompleted(Party party) { + if(party == null) + return false; + + QuestData data = party.getQuestData(); + if(data == null) + return false; + + if(data.quest.partyOptions.objectiveRequirement == EnumPartyObjectives.All){ + for(String entityName : manuals.keySet()){ + for(String player : party.getPlayerNames()){ + HashMap playerManual = getPlayerManual(data, player); + int amount = playerManual.getOrDefault(entityName, 0); + if(amount < manuals.get(entityName)){ + return false; + } + } + } + } + else { + int completed = 0; + HashMap playerManual = getManual(data); + for(String entityName : manuals.keySet()){ + int amount = 0; + if(playerManual.containsKey(entityName)) + amount = playerManual.get(entityName); + if(amount >= manuals.get(entityName)){ + completed++; + } + } + if(completed >= manuals.keySet().size()) + return true; + + if(playerManual.size() != manuals.size()) + return false; + for(String entity : playerManual.keySet()){ + if(!manuals.containsKey(entity) || manuals.get(entity) > playerManual.get(entity)) + return false; + } + } + return true; + } + + class QuestManualObjective implements IQuestObjective{ + private final EntityPlayer player; + private final String entity; + private final Party party; + private final int amount; + + public QuestManualObjective(EntityPlayer player, String entity, int amount) { + this.player = player; + this.entity = entity; + this.amount = amount; + this.party = null; + } + + public QuestManualObjective(Party party, String entity, int amount) { + this.party = party; + this.entity = entity; + this.amount = amount; + this.player = null; + } + + @Override + public int getProgress() { + if(player != null){ + PlayerData data = PlayerDataController.Instance.getPlayerData(player); + PlayerQuestData playerdata = data.questData; + QuestData questdata = (QuestData)playerdata.activeQuests.get(questId); + if(questdata != null){ + HashMap playerManual = getManual(questdata); + return !playerManual.containsKey(this.entity) ? 0 : (Integer)playerManual.get(this.entity); + } + } else if(party != null) { + QuestData questdata = party.getQuestData(); + if (questdata != null) { + if (questdata.quest.partyOptions.objectiveRequirement == EnumPartyObjectives.All) { + int progress = 0; + for (String player : party.getPlayerNames()) { + HashMap playerManual = getPlayerManual(questdata, player); + int currentProgress = !playerManual.containsKey(this.entity) ? 0 : (Integer) playerManual.get(this.entity); + if(currentProgress >= this.amount) + progress += 1; + } + return progress; + } else { + HashMap playerManual = getManual(questdata); + return !playerManual.containsKey(this.entity) ? 0 : (Integer) playerManual.get(this.entity); + } + } + } + return 0; + } + + @Override + public void setProgress(int progress) { + if (progress >= 0 && progress <= this.amount) { + if (player != null) { + PlayerData data = PlayerDataController.Instance.getPlayerData(player); + PlayerQuestData playerdata = data.questData; + QuestData questdata = (QuestData) playerdata.activeQuests.get(questId); + if (questdata != null) { + HashMap playerManual = getManual(questdata); + if (!playerManual.containsKey(this.entity) || (Integer) playerManual.get(this.entity) != progress) { + playerManual.put(this.entity, progress); + setManual(questdata, playerManual); + data.questData.checkQuestCompletion(data, EnumQuestType.Manual); + data.updateClient = true; + data.save(); + } + } + } else if (party != null) { + QuestData questdata = party.getQuestData(); + if (questdata != null) { + if (questdata.quest.partyOptions.objectiveRequirement == EnumPartyObjectives.All) { + for (String player : party.getPlayerNames()) { + HashMap playerManual = getPlayerManual(questdata, player); + if (!playerManual.containsKey(this.entity) || (Integer) playerManual.get(this.entity) != progress) { + playerManual.put(this.entity, progress); + setPlayerManual(questdata, playerManual, player); + } + } + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.Manual); + } else { + HashMap playerManual = getManual(questdata); + if (!playerManual.containsKey(this.entity) || (Integer) playerManual.get(this.entity) != progress) { + playerManual.put(this.entity, progress); + setManual(questdata, playerManual); + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.Manual); + } + } + } + } + } else { + throw new CustomNPCsException("Progress has to be between 0 and " + this.amount, new Object[0]); + } + } + + @Override + public void setPlayerProgress(String playerName, int progress) { + if (progress >= 0 && progress <= this.amount) { + EntityPlayer foundplayer = NoppesUtilServer.getPlayerByName(playerName); + if(foundplayer != null && party == null){ + PlayerData data = PlayerDataController.Instance.getPlayerData(foundplayer); + PlayerQuestData playerdata = data.questData; + QuestData questdata = (QuestData) playerdata.activeQuests.get(questId); + if (questdata != null) { + HashMap playerManual = getManual(questdata); + if (!playerManual.containsKey(this.entity) || (Integer) playerManual.get(this.entity) != progress) { + playerManual.put(this.entity, progress); + setManual(questdata, playerManual); + data.questData.checkQuestCompletion(data, EnumQuestType.Manual); + data.updateClient = true; + data.save(); + } + } + } else if (foundplayer != null){ + QuestData questdata = party.getQuestData(); + if (questdata != null) { + if (questdata.quest.partyOptions.objectiveRequirement == EnumPartyObjectives.All) { + HashMap playerManual = getPlayerManual(questdata, foundplayer.getCommandSenderName()); + if (!playerManual.containsKey(this.entity) || (Integer) playerManual.get(this.entity) != progress) { + playerManual.put(this.entity, progress); + setPlayerManual(questdata, playerManual, foundplayer.getCommandSenderName()); + } + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.Manual); + } else { + HashMap playerManual = getManual(questdata); + if (!playerManual.containsKey(this.entity) || (Integer) playerManual.get(this.entity) != progress) { + playerManual.put(this.entity, progress); + setManual(questdata, playerManual); + PartyController.Instance().checkQuestCompletion(party, EnumQuestType.Manual); + } + } + } + } + } else { + throw new CustomNPCsException("Progress has to be between 0 and " + this.amount, new Object[0]); + } + } + + @Override + public int getMaxProgress() { + return amount; + } + + @Override + public boolean isCompleted() { + return getProgress() >= amount; + } + + @Override + public String getText() { + if(party != null) { + if(party.getObjectiveRequirement() == EnumPartyObjectives.All ){ + return this.entity + ": " + this.getMaxProgress() + (isCompleted() ? " (Done)" : ""); + } + } + return this.entity + ": " + this.getProgress() + "/" + this.getMaxProgress(); + } + + @Override + public String getAdditionalText() { + if(party != null) { + List incompletePlayers = new ArrayList<>(); + QuestData questdata = party.getQuestData(); + if (questdata != null) { + if (questdata.quest.partyOptions.objectiveRequirement == EnumPartyObjectives.All) { + for (String player : party.getPlayerNames()) { + HashMap playerManual = getPlayerManual(questdata, player); + int currentProgress = !playerManual.containsKey(this.entity) ? 0 : (Integer) playerManual.get(this.entity); + if(currentProgress < this.amount){ + String state = player + ": " + currentProgress; + incompletePlayers.add(state); + } + } + if(!incompletePlayers.isEmpty()) + return "[" + String.join(", ", incompletePlayers) + "]"; + } + } + } + return null; + } + } + +} diff --git a/src/main/java/noppes/npcs/util/ValueUtil.java b/src/main/java/noppes/npcs/util/ValueUtil.java index 5f01534a3..1643accd2 100644 --- a/src/main/java/noppes/npcs/util/ValueUtil.java +++ b/src/main/java/noppes/npcs/util/ValueUtil.java @@ -32,4 +32,20 @@ public class ValueUtil { return min; return Math.min(given, max); } + + public static float correctFloat(float given, float min, float max){ + if(given < min) + return min; + if(given > max) + return max; + return given; + } + + public static int CorrectInt(int given, int min, int max) { + if(given < min) + return min; + if(given > max) + return max; + return given; + } } diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index a0a9c8883..32a33eacf 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -595,6 +595,7 @@ quest.kill=Kill quest.areakill=AreaKill quest.dialog=Dialog quest.location=Location +quest.manual=Manual quest.completedtext=Completed text quest.questlogtext=Questlog text quest.complete=Complete