2024-08-23 14:12:59 -04:00
|
|
|
package noppes.npcs.controllers;
|
|
|
|
|
|
2025-02-27 00:48:10 -05:00
|
|
|
import net.minecraft.item.ItemStack;
|
2024-08-23 14:12:59 -04:00
|
|
|
import net.minecraft.nbt.CompressedStreamTools;
|
|
|
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
|
|
|
import net.minecraft.nbt.NBTTagList;
|
2025-02-27 00:48:10 -05:00
|
|
|
import noppes.npcs.CustomItems;
|
2024-08-23 14:12:59 -04:00
|
|
|
import noppes.npcs.CustomNpcs;
|
|
|
|
|
import noppes.npcs.LogWriter;
|
|
|
|
|
import noppes.npcs.controllers.data.Magic;
|
2025-02-24 02:57:43 -05:00
|
|
|
import noppes.npcs.controllers.data.MagicCategory;
|
|
|
|
|
import noppes.npcs.controllers.data.MagicAssociation;
|
|
|
|
|
|
|
|
|
|
import java.io.BufferedInputStream;
|
|
|
|
|
import java.io.DataInputStream;
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.util.HashMap;
|
2024-08-23 14:12:59 -04:00
|
|
|
import java.util.zip.GZIPInputStream;
|
|
|
|
|
|
|
|
|
|
public class MagicController {
|
2025-02-24 02:57:43 -05:00
|
|
|
public HashMap<Integer, Magic> magics = new HashMap<>();
|
|
|
|
|
public HashMap<Integer, Magic> magicSync = new HashMap<>();
|
2024-08-23 14:12:59 -04:00
|
|
|
|
2025-02-24 02:57:43 -05:00
|
|
|
public HashMap<Integer, MagicCategory> categories = new HashMap<>();
|
2025-02-24 15:37:39 -05:00
|
|
|
public HashMap<Integer, MagicCategory> categoriesSync = new HashMap<>();
|
2024-08-23 14:12:59 -04:00
|
|
|
|
2025-02-24 15:37:39 -05:00
|
|
|
public int lastUsedCategoryID = 0;
|
2025-02-03 16:59:06 -05:00
|
|
|
private int lastUsedID = 0;
|
2025-02-24 15:37:39 -05:00
|
|
|
|
2025-02-24 02:57:43 -05:00
|
|
|
private static MagicController instance;
|
2024-08-23 14:12:59 -04:00
|
|
|
|
2025-02-03 16:59:06 -05:00
|
|
|
public MagicController() {
|
|
|
|
|
instance = this;
|
|
|
|
|
}
|
2024-08-23 14:12:59 -04:00
|
|
|
|
2025-02-03 16:59:06 -05:00
|
|
|
public static MagicController getInstance() {
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
2024-08-23 14:12:59 -04:00
|
|
|
|
2025-02-24 02:57:43 -05:00
|
|
|
public Magic getMagic(int magicId) {
|
|
|
|
|
return magics.get(magicId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MagicCategory getCategory(int categoryId) {
|
|
|
|
|
return categories.get(categoryId);
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
2024-08-23 14:12:59 -04:00
|
|
|
|
2025-02-03 16:59:06 -05:00
|
|
|
public void load() {
|
|
|
|
|
File saveDir = CustomNpcs.getWorldSaveDirectory();
|
2025-02-24 02:57:43 -05:00
|
|
|
if (saveDir == null) return;
|
2025-02-03 16:59:06 -05:00
|
|
|
try {
|
|
|
|
|
File file = new File(saveDir, "magic.dat");
|
|
|
|
|
if (file.exists()) {
|
|
|
|
|
loadMagicFile(file);
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
try {
|
|
|
|
|
File file = new File(saveDir, "magic.dat_old");
|
|
|
|
|
if (file.exists()) {
|
|
|
|
|
loadMagicFile(file);
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ee) { }
|
|
|
|
|
}
|
2025-02-27 00:48:10 -05:00
|
|
|
|
|
|
|
|
if (magics.isEmpty()) {
|
|
|
|
|
// Create default magics
|
|
|
|
|
Magic earth = new Magic(0, "Earth", 0x00DD00);
|
|
|
|
|
earth.setIconItem(new ItemStack(CustomItems.earthElement));
|
|
|
|
|
|
|
|
|
|
Magic water = new Magic(1, "Water", 0xF2DD00);
|
|
|
|
|
water.setIconItem(new ItemStack(CustomItems.waterElement));
|
|
|
|
|
|
|
|
|
|
Magic fire = new Magic(2, "Fire", 0xDD0000);
|
|
|
|
|
fire.setIconItem(new ItemStack(CustomItems.spellFire));
|
|
|
|
|
|
|
|
|
|
Magic air = new Magic(3, "Air", 0xDD0000);
|
|
|
|
|
air.setIconItem(new ItemStack(CustomItems.airElement));
|
|
|
|
|
|
|
|
|
|
Magic dark = new Magic(4, "Dark", 0xDD0000);
|
|
|
|
|
dark.setIconItem(new ItemStack(CustomItems.spellDark));
|
|
|
|
|
|
|
|
|
|
Magic holy = new Magic(5, "Holy", 0xDD0000);
|
|
|
|
|
holy.setIconItem(new ItemStack(CustomItems.spellHoly));
|
|
|
|
|
|
|
|
|
|
Magic nature = new Magic(6, "Nature", 0xDD0000);
|
|
|
|
|
nature.setIconItem(new ItemStack(CustomItems.spellNature));
|
|
|
|
|
|
|
|
|
|
Magic arcane = new Magic(7, "Arcane", 0xDD0000);
|
|
|
|
|
arcane.setIconItem(new ItemStack(CustomItems.spellArcane));
|
|
|
|
|
|
|
|
|
|
// Insiders
|
|
|
|
|
earth.interactions.put(air.id, 0.60f);
|
|
|
|
|
water.interactions.put(earth.id, 0.60f);
|
|
|
|
|
fire.interactions.put(water.id, 0.60f);
|
|
|
|
|
air.interactions.put(fire.id, 0.60f);
|
|
|
|
|
|
|
|
|
|
// Outsiders
|
|
|
|
|
dark.interactions.put(nature.id, 0.60f);
|
|
|
|
|
nature.interactions.put(holy.id, 0.60f);
|
|
|
|
|
holy.interactions.put(arcane.id, 0.60f);
|
|
|
|
|
arcane.interactions.put(dark.id, 0.60f);
|
|
|
|
|
|
|
|
|
|
// Cross Interactions
|
|
|
|
|
earth.interactions.put(nature.id, 0.30f);
|
|
|
|
|
water.interactions.put(holy.id, 0.30f);
|
|
|
|
|
fire.interactions.put(arcane.id, 0.30f);
|
|
|
|
|
air.interactions.put(dark.id, 0.30f);
|
|
|
|
|
dark.interactions.put(fire.id, 0.30f);
|
|
|
|
|
nature.interactions.put(air.id, 0.30f);
|
|
|
|
|
holy.interactions.put(earth.id, 0.30f);
|
|
|
|
|
arcane.interactions.put(water.id, 0.30f);
|
|
|
|
|
|
|
|
|
|
// Add them to the registry
|
|
|
|
|
magics.put(earth.id, earth);
|
|
|
|
|
magics.put(water.id, water);
|
|
|
|
|
magics.put(fire.id, fire);
|
|
|
|
|
magics.put(air.id, air);
|
|
|
|
|
magics.put(dark.id, dark);
|
|
|
|
|
magics.put(holy.id, holy);
|
|
|
|
|
magics.put(nature.id, nature);
|
|
|
|
|
magics.put(arcane.id, arcane);
|
|
|
|
|
}
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void loadMagicFile(File file) throws IOException {
|
|
|
|
|
DataInputStream stream = new DataInputStream(
|
|
|
|
|
new BufferedInputStream(new GZIPInputStream(new FileInputStream(file)))
|
|
|
|
|
);
|
|
|
|
|
loadMagic(stream);
|
|
|
|
|
stream.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void loadMagic(DataInputStream stream) throws IOException {
|
2025-02-24 02:57:43 -05:00
|
|
|
NBTTagCompound compound = CompressedStreamTools.read(stream);
|
|
|
|
|
lastUsedID = compound.getInteger("lastID");
|
2025-02-24 15:37:39 -05:00
|
|
|
lastUsedCategoryID = compound.getInteger("lastCatID");
|
2025-02-03 16:59:06 -05:00
|
|
|
|
2025-02-24 02:57:43 -05:00
|
|
|
// Load magics
|
|
|
|
|
magics.clear();
|
|
|
|
|
NBTTagList magicList = compound.getTagList("Magics", 10);
|
|
|
|
|
for (int i = 0; i < magicList.tagCount(); i++) {
|
|
|
|
|
NBTTagCompound magCompound = magicList.getCompoundTagAt(i);
|
|
|
|
|
Magic mag = new Magic();
|
|
|
|
|
mag.readNBT(magCompound);
|
|
|
|
|
magics.put(mag.id, mag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Load categories
|
|
|
|
|
categories.clear();
|
|
|
|
|
NBTTagList catList = compound.getTagList("Categories", 10);
|
|
|
|
|
for (int i = 0; i < catList.tagCount(); i++) {
|
|
|
|
|
NBTTagCompound catCompound = catList.getCompoundTagAt(i);
|
|
|
|
|
MagicCategory cat = new MagicCategory();
|
|
|
|
|
cat.readNBT(catCompound);
|
|
|
|
|
categories.put(cat.id, cat);
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public NBTTagCompound getNBT() {
|
2025-02-24 02:57:43 -05:00
|
|
|
NBTTagList magicList = new NBTTagList();
|
|
|
|
|
for (Magic mag : magics.values()) {
|
|
|
|
|
NBTTagCompound magCompound = new NBTTagCompound();
|
|
|
|
|
mag.writeNBT(magCompound);
|
|
|
|
|
magicList.appendTag(magCompound);
|
|
|
|
|
}
|
|
|
|
|
NBTTagList catList = new NBTTagList();
|
|
|
|
|
for (MagicCategory cat : categories.values()) {
|
|
|
|
|
NBTTagCompound catCompound = new NBTTagCompound();
|
|
|
|
|
cat.writeNBT(catCompound);
|
|
|
|
|
catList.appendTag(catCompound);
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
2025-02-24 02:57:43 -05:00
|
|
|
NBTTagCompound compound = new NBTTagCompound();
|
|
|
|
|
compound.setInteger("lastID", lastUsedID);
|
2025-02-24 15:37:39 -05:00
|
|
|
compound.setInteger("lastCatID", lastUsedCategoryID);
|
2025-02-24 02:57:43 -05:00
|
|
|
compound.setTag("Magics", magicList);
|
|
|
|
|
compound.setTag("Categories", catList);
|
|
|
|
|
return compound;
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
|
|
|
|
|
2025-02-24 02:57:43 -05:00
|
|
|
public void saveMagicData() {
|
2025-02-03 16:59:06 -05:00
|
|
|
try {
|
|
|
|
|
File saveDir = CustomNpcs.getWorldSaveDirectory();
|
2025-02-24 02:57:43 -05:00
|
|
|
File fileNew = new File(saveDir, "magic.dat_new");
|
|
|
|
|
File fileOld = new File(saveDir, "magic.dat_old");
|
|
|
|
|
File fileCurrent = new File(saveDir, "magic.dat");
|
|
|
|
|
CompressedStreamTools.writeCompressed(getNBT(), new FileOutputStream(fileNew));
|
|
|
|
|
if (fileOld.exists()) fileOld.delete();
|
|
|
|
|
fileCurrent.renameTo(fileOld);
|
|
|
|
|
if (fileCurrent.exists()) fileCurrent.delete();
|
|
|
|
|
fileNew.renameTo(fileCurrent);
|
|
|
|
|
if (fileNew.exists()) fileNew.delete();
|
2025-02-03 16:59:06 -05:00
|
|
|
} catch (Exception e) {
|
|
|
|
|
LogWriter.except(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void saveMagic(Magic mag) {
|
|
|
|
|
if (mag.id < 0) {
|
|
|
|
|
mag.id = getUnusedId();
|
|
|
|
|
while (hasName(mag.name))
|
|
|
|
|
mag.name += "_";
|
|
|
|
|
} else {
|
|
|
|
|
Magic existing = magics.get(mag.id);
|
|
|
|
|
if (existing != null && !existing.name.equals(mag.name))
|
|
|
|
|
while (hasName(mag.name))
|
|
|
|
|
mag.name += "_";
|
|
|
|
|
}
|
|
|
|
|
magics.put(mag.id, mag);
|
2025-02-24 02:57:43 -05:00
|
|
|
saveMagicData();
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int getUnusedId() {
|
|
|
|
|
if (lastUsedID == 0) {
|
2025-02-24 02:57:43 -05:00
|
|
|
for (int id : magics.keySet())
|
|
|
|
|
if (id > lastUsedID)
|
|
|
|
|
lastUsedID = id;
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
|
|
|
|
lastUsedID++;
|
|
|
|
|
return lastUsedID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean hasName(String newName) {
|
2025-02-24 02:57:43 -05:00
|
|
|
if (newName.trim().isEmpty()) return true;
|
2025-02-03 16:59:06 -05:00
|
|
|
for (Magic mag : magics.values())
|
|
|
|
|
if (mag.name.equals(newName))
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-24 02:57:43 -05:00
|
|
|
// === Category management methods ===
|
2025-02-03 16:59:06 -05:00
|
|
|
|
2025-02-24 02:57:43 -05:00
|
|
|
public void addCategory(MagicCategory category) {
|
|
|
|
|
if (category.id < 0) {
|
|
|
|
|
lastUsedCategoryID++;
|
|
|
|
|
category.id = lastUsedCategoryID;
|
2025-02-03 16:59:06 -05:00
|
|
|
} else {
|
2025-02-24 02:57:43 -05:00
|
|
|
while (containsCategoryName(category.title))
|
|
|
|
|
category.title += "_";
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
2025-02-24 02:57:43 -05:00
|
|
|
categories.put(category.id, category);
|
|
|
|
|
saveMagicData();
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
|
|
|
|
|
2025-02-24 02:57:43 -05:00
|
|
|
public boolean containsCategoryName(String title) {
|
|
|
|
|
title = title.toLowerCase();
|
|
|
|
|
for (MagicCategory cat : categories.values()) {
|
|
|
|
|
if (cat.title.toLowerCase().equals(title))
|
|
|
|
|
return true;
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
2025-02-24 02:57:43 -05:00
|
|
|
return false;
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
|
|
|
|
|
2025-02-24 02:57:43 -05:00
|
|
|
public void removeCategory(int categoryId) {
|
|
|
|
|
if (categories.containsKey(categoryId)) {
|
|
|
|
|
categories.remove(categoryId);
|
|
|
|
|
saveMagicData();
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-02-24 02:57:43 -05:00
|
|
|
* Associates a magic with a category along with its per-category ordering data.
|
2025-02-03 16:59:06 -05:00
|
|
|
*/
|
2025-02-24 02:57:43 -05:00
|
|
|
public void addMagicToCategory(int magicId, int categoryId, int index, int priority) {
|
|
|
|
|
MagicCategory cat = categories.get(categoryId);
|
|
|
|
|
if (cat == null) return;
|
|
|
|
|
MagicAssociation assoc = new MagicAssociation();
|
|
|
|
|
assoc.magicId = magicId;
|
|
|
|
|
assoc.index = index;
|
|
|
|
|
assoc.priority = priority;
|
|
|
|
|
cat.associations.put(magicId, assoc);
|
|
|
|
|
saveMagicData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void removeMagicFromCategory(int magicId, int categoryId) {
|
|
|
|
|
MagicCategory cat = categories.get(categoryId);
|
|
|
|
|
if (cat == null) return;
|
|
|
|
|
cat.associations.remove(magicId);
|
|
|
|
|
saveMagicData();
|
2025-02-03 16:59:06 -05:00
|
|
|
}
|
2024-08-23 14:12:59 -04:00
|
|
|
}
|