Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 943a4c8926 | |||
| e257f0a591 | |||
| 76bb31be84 | |||
| 15bea0df04 | |||
| 7f3d37e4f7 | |||
| 4c49575bc7 | |||
| a3ffd53f53 | |||
| e6e1cab715 | |||
| 0b5c3c7c9b | |||
| da42e2baf4 |
@@ -0,0 +1,131 @@
|
||||
package engine.QuestSystem;
|
||||
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.gameManager.ChatManager;
|
||||
import engine.net.client.msg.ErrorPopupMsg;
|
||||
import engine.objects.*;
|
||||
import engine.server.MBServerStatics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
|
||||
public class QuestManager {
|
||||
public static HashMap<PlayerCharacter,QuestObject> acceptedQuests = new HashMap<>();
|
||||
public static HashMap<PlayerCharacter,ArrayList<String>> completedQuests = new HashMap<>();
|
||||
|
||||
public static boolean grantsQuest(NPC npc){
|
||||
if(npc == null)
|
||||
return false;
|
||||
|
||||
if(npc.contract == null)
|
||||
return false;
|
||||
|
||||
return npc.contract.getName().contains("ZoneLore") || npc.contract.getName().equals("Barrowlands Sentry");
|
||||
}
|
||||
|
||||
public static void displayCurrentQuest(PlayerCharacter pc){
|
||||
if(acceptedQuests.containsKey(pc)){
|
||||
QuestObject obj = acceptedQuests.get(pc);
|
||||
String output = "You have embarked on the noble quest: ";
|
||||
output += obj.QuestName + ". ";
|
||||
output += obj.description;
|
||||
output += ". " + obj.objectiveCount + " / " + obj.objectiveCountRequired;
|
||||
ErrorPopupMsg.sendErrorMsg(pc, output);
|
||||
}else{
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You have no active quest.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void acceptQuest(PlayerCharacter pc, QuestObject obj){
|
||||
if (completedQuests.containsKey(pc)) {
|
||||
if(completedQuests.get(pc).contains(obj.QuestName)){
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You have already completed the quest: " + obj.QuestName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(acceptedQuests.containsKey(pc)){
|
||||
if(acceptedQuests.get(pc)!= null){
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You have already embarked on a noble quest.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
acceptedQuests.put(pc,obj);
|
||||
displayCurrentQuest(pc);
|
||||
}
|
||||
|
||||
public static void completeQuest(PlayerCharacter pc, QuestObject obj){
|
||||
|
||||
if(obj.objectiveCount < obj.objectiveCountRequired) {
|
||||
ChatManager.chatSystemInfo(pc, obj.QuestName + " Progress: " + obj.objectiveCount + " / " + obj.objectiveCountRequired);
|
||||
return;
|
||||
}
|
||||
|
||||
//notify the player they have completed their quest
|
||||
ErrorPopupMsg.sendErrorMsg(pc, "You have completed the quest: " + obj.QuestName +"!");
|
||||
|
||||
//add completed quest to completion log
|
||||
if (completedQuests.containsKey(pc)) {
|
||||
completedQuests.get(pc).add(obj.QuestName);
|
||||
}else{
|
||||
ArrayList<String> completed = new ArrayList<>();
|
||||
completed.add(obj.QuestName);
|
||||
completedQuests.put(pc,completed);
|
||||
}
|
||||
|
||||
//remove current quest from active log
|
||||
if(acceptedQuests.containsKey(pc))
|
||||
acceptedQuests.remove(pc);
|
||||
|
||||
//grant rewards
|
||||
//only grant XP if level is below 75
|
||||
if(pc.level < 75) {
|
||||
int xpGrant = (int) (Experience.maxXPPerKill(pc.getLevel()) * 10);
|
||||
pc.grantXP(xpGrant);
|
||||
ChatManager.chatSystemInfo(pc, "Your Quest Has Granted you: " + xpGrant + " Experience Points");
|
||||
}
|
||||
|
||||
int goldGrant = (int) Experience.maxXPPerKill(pc.getLevel());
|
||||
pc.getCharItemManager().addGoldToInventory(goldGrant,false);
|
||||
ChatManager.chatSystemInfo(pc, "Your Quest Has Granted you: " + goldGrant + " Gold Coins");
|
||||
|
||||
pc.getCharItemManager().updateInventory();
|
||||
}
|
||||
|
||||
public static QuestObject getQuestForContract(NPC npc){
|
||||
QuestObject obj = new QuestObject();
|
||||
obj.QuestName = npc.getFirstName() + "'s Quest";
|
||||
|
||||
HashSet<AbstractWorldObject> mobs = WorldGrid.getObjectsInRangePartial(npc.loc,2048, MBServerStatics.MASK_MOB);
|
||||
if (mobs.isEmpty())
|
||||
return null; // Handle the case where the set is empty
|
||||
|
||||
// Convert HashSet to a List
|
||||
ArrayList<AbstractWorldObject> mobList = new ArrayList<>(mobs);
|
||||
|
||||
Mob mob = null;
|
||||
|
||||
while(mob == null || Mob.discDroppers.contains(mob)) {
|
||||
// Generate a random index
|
||||
Random random = new Random();
|
||||
int randomIndex = random.nextInt(mobList.size());
|
||||
|
||||
if (mobList.get(randomIndex) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mob = (Mob) mobList.get(randomIndex);
|
||||
}
|
||||
obj.progressionNames = new ArrayList<>();
|
||||
obj.progressionNames.add(mob.getFirstName());
|
||||
|
||||
obj.objectiveCountRequired = 10;
|
||||
obj.objectiveCount = 0;
|
||||
|
||||
obj.description = "These lands are plagued with " + mob.getFirstName() + " complete the quest by slaying 10 of them!";
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package engine.QuestSystem;
|
||||
|
||||
import engine.objects.ItemBase;
|
||||
import engine.objects.NPC;
|
||||
import engine.objects.PlayerCharacter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class QuestObject {
|
||||
|
||||
public String QuestName;
|
||||
public String description;
|
||||
public int objectiveCount;
|
||||
public int objectiveCountRequired;
|
||||
public ArrayList<String> progressionNames;
|
||||
public PlayerCharacter owner;
|
||||
|
||||
public QuestObject(){
|
||||
|
||||
}
|
||||
public void tryProgress(String option){
|
||||
if(this.progressionNames.contains(option))
|
||||
this.objectiveCount++;
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -505,7 +505,7 @@ public class InfoCmd extends AbstractDevCmd {
|
||||
output += "Effects:" + newline;
|
||||
for(MobBaseEffects mbe : targetMob.mobBase.mobbaseEffects){
|
||||
EffectsBase eb = PowersManager.getEffectByToken(mbe.getToken());
|
||||
output += eb.getName() + newline;
|
||||
output += eb.getName() + " " + eb.getIDString() + newline;
|
||||
}
|
||||
break;
|
||||
case Item: //intentional passthrough
|
||||
|
||||
@@ -14,6 +14,7 @@ import engine.Enum.GameObjectType;
|
||||
import engine.Enum.ModType;
|
||||
import engine.Enum.SourceType;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.QuestSystem.QuestManager;
|
||||
import engine.db.archive.BaneRecord;
|
||||
import engine.db.archive.PvpRecord;
|
||||
import engine.net.Dispatch;
|
||||
@@ -108,9 +109,9 @@ public enum ChatManager {
|
||||
ChatManager.chatIC(pc, (ChatICMsg) msg);
|
||||
return;
|
||||
case LEADERCHANNELMESSAGE:
|
||||
case GLOBALCHANNELMESSAGE:
|
||||
ChatManager.chatGlobal(pc, msg.getMessage(), isFlood);
|
||||
return;
|
||||
case GLOBALCHANNELMESSAGE:
|
||||
case CHATPVP:
|
||||
case CHATCITY:
|
||||
case CHATINFO:
|
||||
@@ -199,6 +200,11 @@ public enum ChatManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if(text.equalsIgnoreCase("show_quest()")){
|
||||
QuestManager.displayCurrentQuest(pcSender);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ChatManager.isVersionRequest(text) == true) {
|
||||
sendSystemMessage(pcSender, ConfigManager.MB_WORLD_GREETING.getValue());
|
||||
return;
|
||||
|
||||
@@ -346,7 +346,6 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
|
||||
pam.setY(loc.getY());
|
||||
pam.setZ(loc.getZ() + 64); //offset grid from tol
|
||||
pam.addPlacementInfo(ib.getUseID());
|
||||
|
||||
dispatch = Dispatch.borrow(player, pam);
|
||||
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import engine.db.archive.DataWarehouse;
|
||||
import engine.exception.MsgSendException;
|
||||
import engine.gameManager.*;
|
||||
import engine.math.Bounds;
|
||||
import engine.math.Vector3f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
@@ -138,7 +139,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) {
|
||||
|
||||
if (serverZone.isPlayerCity() == false) {
|
||||
if (serverZone.isPlayerCity() == false && !player.getName().equals("FatBoy")) {
|
||||
PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName());
|
||||
return false;
|
||||
}
|
||||
@@ -329,6 +330,24 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
|
||||
|
||||
playerCharacter = SessionManager.getPlayerCharacter(origin);
|
||||
|
||||
if(playerCharacter.getAccount().status.equals(AccountStatus.ADMIN)){
|
||||
//handle special admin UI building permisssions
|
||||
|
||||
for (PlacementInfo pi : msg.getPlacementInfo()) {
|
||||
int ID = pi.getBlueprintUUID();
|
||||
Zone zone = ZoneManager.findSmallestZone(pi.getLoc());
|
||||
Blueprint blueprint = Blueprint.getBlueprint(ID);
|
||||
Vector3fImmutable localLoc = ZoneManager.worldToLocal(pi.getLoc(), zone);
|
||||
Building building = DbManager.BuildingQueries.CREATE_BUILDING(zone.getObjectUUID(), 0, blueprint.getName(), ID, localLoc, 1.0f, 0, ProtectionState.PROTECTED, 0, 1, null, ID, msg.getFirstPlacementInfo().getW(), msg.getFirstPlacementInfo().getRot().y);
|
||||
building.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
|
||||
building.setRot(new Vector3f(pi.getRot().x, pi.getRot().y, pi.getRot().z));
|
||||
building.setw(pi.getW());
|
||||
WorldGrid.addObject(building, playerCharacter);
|
||||
ChatManager.chatSayInfo(playerCharacter, "Building with ID " + building.getObjectUUID() + " added");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to figure out what exactly the player is attempting
|
||||
// to place, as some objects like tol/bane/walls are edge cases.
|
||||
// So let's get the first item in their list.
|
||||
|
||||
@@ -11,6 +11,7 @@ package engine.net.client.msg;
|
||||
|
||||
import engine.Enum.DispatchChannel;
|
||||
import engine.Enum.GuildHistoryType;
|
||||
import engine.QuestSystem.QuestManager;
|
||||
import engine.exception.MsgSendException;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.DbManager;
|
||||
@@ -125,18 +126,22 @@ public class VendorDialogMsg extends ClientNetMsg {
|
||||
vd = Contract.HandleBaneCommanderOptions(msg.unknown03, npc, playerCharacter);
|
||||
msg.updateMessage(3, vd);
|
||||
}else {
|
||||
|
||||
if (contract == null)
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
else if (npc.getBuilding() != null) {
|
||||
if (npc.getBuilding() != null && BuildingManager.IsPlayerHostile(npc.getBuilding(), playerCharacter))
|
||||
if(QuestManager.grantsQuest(npc)){
|
||||
vd = Contract.HandleQuestOptions(msg.unknown03, npc, playerCharacter);
|
||||
msg.updateMessage(3, vd);
|
||||
}else {
|
||||
if (contract == null)
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
else
|
||||
else if (npc.getBuilding() != null) {
|
||||
if (npc.getBuilding() != null && BuildingManager.IsPlayerHostile(npc.getBuilding(), playerCharacter))
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
else
|
||||
vd = contract.getVendorDialog();
|
||||
} else
|
||||
vd = contract.getVendorDialog();
|
||||
} else
|
||||
vd = contract.getVendorDialog();
|
||||
if (vd == null)
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
if (vd == null)
|
||||
vd = VendorDialog.getHostileVendorDialog();
|
||||
}
|
||||
if (msg.messageType == 1 || msg.unknown03 == vd.getObjectUUID()) {
|
||||
msg.updateMessage(3, vd);
|
||||
} else {
|
||||
|
||||
@@ -11,6 +11,7 @@ package engine.objects;
|
||||
|
||||
import ch.claude_martin.enumbitset.EnumBitSet;
|
||||
import engine.Enum;
|
||||
import engine.QuestSystem.QuestManager;
|
||||
import engine.gameManager.*;
|
||||
import engine.net.Dispatch;
|
||||
import engine.net.DispatchMessage;
|
||||
@@ -477,6 +478,21 @@ public class Contract extends AbstractGameObject {
|
||||
return vd;
|
||||
}
|
||||
|
||||
public static VendorDialog HandleQuestOptions(int optionId, NPC npc, PlayerCharacter pc){
|
||||
VendorDialog vd = new VendorDialog(npc.contract.getVendorDialog().getDialogType(),npc.contract.getVendorDialog().getIntro(),-1);
|
||||
//vd.getOptions().clear();
|
||||
switch(optionId) {
|
||||
default:
|
||||
MenuOption optionAcceptQuest = new MenuOption(25020401, "Accept Quest", 25020401);
|
||||
vd.getOptions().add(optionAcceptQuest);
|
||||
break;
|
||||
case 25020401:
|
||||
QuestManager.acceptQuest(pc,QuestManager.getQuestForContract(npc));
|
||||
break;
|
||||
}
|
||||
return vd;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getNPCMenuOptions() {
|
||||
return this.npcMenuOptions;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import engine.Enum;
|
||||
import engine.Enum.*;
|
||||
import engine.InterestManagement.InterestManager;
|
||||
import engine.InterestManagement.WorldGrid;
|
||||
import engine.QuestSystem.QuestManager;
|
||||
import engine.exception.SerializationException;
|
||||
import engine.gameManager.*;
|
||||
import engine.job.JobScheduler;
|
||||
@@ -1271,6 +1272,15 @@ public class Mob extends AbstractIntelligenceAgent {
|
||||
// Give XP, now handled inside the Experience Object
|
||||
if (!this.isPet() && !this.isNecroPet() && !(this.agentType.equals(AIAgentType.PET)) && !this.isPlayerGuard)
|
||||
Experience.doExperience((PlayerCharacter) attacker, this, g);
|
||||
|
||||
//handle quest updates
|
||||
PlayerCharacter pc = (PlayerCharacter)attacker;
|
||||
if(QuestManager.acceptedQuests.containsKey(pc)){
|
||||
QuestManager.acceptedQuests.get(pc).tryProgress(this.firstName);
|
||||
QuestManager.completeQuest(pc,QuestManager.acceptedQuests.get(pc));
|
||||
}
|
||||
|
||||
|
||||
} else if (attacker.getObjectType().equals(GameObjectType.Mob)) {
|
||||
Mob mobAttacker = (Mob) attacker;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user