Open rihok opened 3 years ago
So to preface, I'm a newbie to the OSRS open-source community.
Pros:
Cons:
That being said: Here's my suggested initial refactoring. I've only taken a look at cook's assistant
so you can sort of already see how difficult this might end up being.
EXAMPLE DATA:
steps:
- type: "NPC"
header: "Bring the cook the cake ingredients"
steps:
- "Bring the cook the cake ingredients"
target: "COOK_4626"
location:
x: 3206
y: 3214
plane: 0
dialogue:
- "I'll get right on it."
required_items:
- name: "Egg"
itemID: "EGG"
tip: "You can find the egg in the farm north of Lumbridge."
- name: "Bucket of Milk"
itemID: "BUCKET_OF_MILK"
tip: "You can get a bucket from the Lumbridge General Store, then milk a Dairy Cow north-east of Lumbridge."
- name: "Pot of flour"
itemID: "POT_OF_FLOUR"
tip: "You can buy a pot from the Lumbridge General Store, collect some wheat from a field north of Lumbridge, then grind it in the Lumbridge Mill north of Lumbridge"
EXAMPLE LOADER:
package com.questhelper.steps.loader;
import com.questhelper.steps.DetailedQuestStep;
import java.util.ArrayList;
import java.util.List;
public class JsonOrYamlLoader {
public static List<DetailedQuestStep> loadSteps(String fileName) {
// load yaml e.g. SomeCommonDataStructure data = load_data(fileName);
List<String> data = null; // PLACEHOLDER
// determine type e.g. data.type
String type = "NPC"; // PLACEHOLDER
ArrayList<DetailedQuestStep> steps = new ArrayList<>();
for (String stepData : data) {
steps.add(loadOneStep(stepData));
}
return steps;
}
private static DetailedQuestStep loadOneStep(String step) {
// Strategy pattern, figure out what loader to use
AbstractStepLoader stepLoader = getLoader(type);
if (stepLoader == null) {
return null;
}
// delegate loading to loader
return stepLoader.load();
}
private static AbstractStepLoader getLoader(String type) {
if (type == "NPC") {
return new NpcStepLoader();
}
return null;
}
}
Thanks for sharing your thoughts. I can see some cases being pretty tricky in data. I wonder if a hybrid approach would make sense? In the example you showed, I could see the data driven model work nicely. Although I can imagine there being cases that require custom rendering, etc. where it breaks down.
Perhaps there could be a step type called "CUSTOM" or some such, which would have to be handled in code? This could maybe done in a way that would allow creating re-usable custom snippets also, to generalize it a bit further.
At the end of the day, I'm not one of the major contributors to this project so I don't think it's a good idea for me to prescribe a solution, only suggest one. The devil really is in the details.
The new abstractions are quite useful in the average, simple use case but how many quests are actually simple?
Because quests aren't released quite often (no need to continually crowdsource logic), I don't think it's a good idea to refactor everything to be data-driven because as always if it ain't broke.
Hey, this is an awesome plugin. It would be great if creating and editing quest guides would somehow be more data driven, so that people can easily edit and create new quest definitions and get more of them out there by the community through PRs or just sharing JSON files or some such. I'd imagine a set of tools in the plugin to be able to edit/create, load and save quest guides would also go a long way, with some in-game overlay to help create steps and mark positions, etc.
This would allow less tech savvy people to help out and get more quests in quicker.