package ttftcuts.physis.common.story; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import ttftcuts.physis.common.file.IDataCallback; import ttftcuts.physis.common.file.PhysisWorldSavedData; public class StoryEngine { private static final String STORYTAG = "story"; private static final String SEEDTAG = "seed"; private static final String VARIABLETAG = "vars"; private static final String VARNAMETAG = "name"; private static final String VARVALTAG = "val"; private static IDataCallback dataCallback = new IDataCallback() { @Override public void dataPacketSending() { long s = instance(false).seed; PhysisWorldSavedData.getWorldTag(STORYTAG).setLong("seed", s); //Physis.logger.info("Adding story seed to packet: "+s); } @Override public void dataPacketReceived() { long s = PhysisWorldSavedData.getWorldTag(STORYTAG).getLong("seed"); StoryEngine.reload(s, true); //Physis.logger.info("Loaded story seed from packet: "+s); } @Override public void dataSaving() {} @Override public void dataLoaded() {} }; private static Map<String, Integer> registry = new HashMap<String, Integer>(); private static StoryEngine serverInstance; private static StoryEngine clientInstance; public final boolean client; public long seed; private Map<String, StoryVariable> storyVars = new HashMap<String, StoryVariable>(); public static StoryEngine instance(boolean client) { return client ? clientInstance : serverInstance; } public static void registerVariable(String name, int range) { registry.put(name, range); } public static void reload(long seed, boolean client) { StoryEngine newengine = new StoryEngine(seed, client); if (client) { clientInstance = newengine; } else { serverInstance = newengine; PhysisWorldSavedData.registerCallback(dataCallback); } } //---------------- public StoryEngine(long seed, boolean client) { this.seed = seed; this.client = client; this.storyVars.clear(); if (seed != -1) { NBTTagCompound data = PhysisWorldSavedData.getWorldTag(STORYTAG); this.loadFromNBT(data); if (!this.client) { this.writeToNBT(data); PhysisWorldSavedData.safeMarkDirty(); } } //Physis.logger.info("Starting Story Engine: "+seed); } public void loadFromNBT(NBTTagCompound tag) { boolean dirty = false; long loadedseed = tag.getLong(SEEDTAG); if (this.seed != loadedseed) { dirty = true; } if (loadedseed != 0) { this.seed = loadedseed; } NBTTagList list = tag.getTagList(VARIABLETAG, 10); for (int i=0; i<list.tagCount(); i++) { NBTTagCompound vartag = list.getCompoundTagAt(i); String name = vartag.getString(VARNAMETAG); if (name != null && registry.containsKey(name)) { int val = vartag.getInteger(VARVALTAG); this.storyVars.put(name, new StoryVariable(name, registry.get(name), val)); } } for(Entry<String, Integer> entry : registry.entrySet()) { String name = entry.getKey(); int max = entry.getValue(); if (!storyVars.containsKey(name)) { this.storyVars.put(name, new StoryVariable(name, max)); dirty = true; } } if (dirty && !this.client) { this.writeToNBT(tag); PhysisWorldSavedData.safeMarkDirty(); } } public void writeToNBT(NBTTagCompound tag) { tag.setLong(SEEDTAG, this.seed); NBTTagList list = new NBTTagList(); for(Entry<String, StoryVariable> entry : storyVars.entrySet()) { NBTTagCompound vartag = new NBTTagCompound(); vartag.setString(VARNAMETAG, entry.getKey()); vartag.setInteger(VARVALTAG, entry.getValue().value); list.appendTag(vartag); } tag.setTag(VARIABLETAG, list); } public static int get(String variable, boolean client) { StoryEngine e = instance(client); if (e != null) { return e.get(variable); } return -1; } public int get(String variable) { if (storyVars.containsKey(variable)) { return storyVars.get(variable).value; } return -1; } public static int getRange(String variable) { if (registry.containsKey(variable)) { return registry.get(variable); } return 0; } public String getVarString(String input, String varname) { int var = get(varname); if (var == -1) { return "[MISSING]"; } else { return input.replace("#", String.valueOf(var)); } } //---------------- private class StoryVariable { public String name; public int value; public int max; public StoryVariable(String name, int max) { this.name = name; this.max = max; long seed = StoryEngine.this.seed ^ this.name.hashCode(); Random rand = new Random(seed); this.value = rand.nextInt(this.max); //Physis.logger.info("StoryVariable "+this.name+": story seed: "+StoryEngine.this.seed+", seed: "+seed+", max: "+this.max+", val: "+this.value); } public StoryVariable(String name, int max, int value) { this.name = name; this.value = value; this.max = max; } } }