package com.bioxx.tfc2;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.*;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import net.minecraftforge.fml.relauncher.Side;
import com.bioxx.jmapgen.dungeon.DungeonSchemManager;
import com.bioxx.jmapgen.dungeon.DungeonTheme.EntranceType;
import com.bioxx.tfc2.api.FoodRegistry;
import com.bioxx.tfc2.api.TFCOptions;
import com.bioxx.tfc2.api.interfaces.IFood;
import com.bioxx.tfc2.api.trees.TreeConfig;
import com.bioxx.tfc2.api.trees.TreeRegistry;
import com.bioxx.tfc2.api.trees.TreeSchematic;
import com.bioxx.tfc2.api.types.ClimateTemp;
import com.bioxx.tfc2.api.types.Moisture;
import com.bioxx.tfc2.api.types.WoodType;
import com.bioxx.tfc2.commands.*;
import com.bioxx.tfc2.core.PortalSchematic;
import com.bioxx.tfc2.core.util.FoodReader;
import com.bioxx.tfc2.core.util.FoodReader.FoodJSON;
import com.bioxx.tfc2.networking.client.CAnvilStrikePacket;
import com.bioxx.tfc2.networking.client.CFoodPacket;
import com.bioxx.tfc2.networking.client.CMapPacket;
import com.bioxx.tfc2.networking.server.SAnvilCraftingPacket;
import com.bioxx.tfc2.networking.server.SKnappingPacket;
import com.bioxx.tfc2.networking.server.SMapRequestPacket;
import com.bioxx.tfc2.world.WorldGen;
import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Mod(modid = Reference.ModID, name = Reference.ModName, version = Reference.ModVersion, useMetadata = false, dependencies = Reference.ModDependencies)
public class TFC
{
@Instance
public static TFC instance;
public static Logger log = LogManager.getLogger("TFC");
@SidedProxy(clientSide = Reference.CLIENT_PROXY_CLASS, serverSide = Reference.SERVER_PROXY_CLASS)
public static CommonProxy proxy;
public static SimpleNetworkWrapper network;
public TFC() {}
@EventHandler
public void preInit(FMLPreInitializationEvent event)
{
instance = this;
log = event.getModLog();
loadSettings();
proxy.preInit(event);
network = NetworkRegistry.INSTANCE.newSimpleChannel("TFC2");
network.registerMessage(CMapPacket.Handler.class, CMapPacket.class, 0, Side.CLIENT);
network.registerMessage(SMapRequestPacket.Handler.class, SMapRequestPacket.class, 1, Side.SERVER);
network.registerMessage(SKnappingPacket.Handler.class, SKnappingPacket.class, 2, Side.SERVER);
network.registerMessage(CAnvilStrikePacket.Handler.class, CAnvilStrikePacket.class, 3, Side.CLIENT);
network.registerMessage(SAnvilCraftingPacket.Handler.class, SAnvilCraftingPacket.class, 4, Side.SERVER);
network.registerMessage(CFoodPacket.Handler.class, CFoodPacket.class, 5, Side.CLIENT);
//Register tree types and load tree schematics
loadTrees();
loadDungeonSchems();
Core.PortalSchematic = new PortalSchematic("/assets/tfc2/schematics/portal.schematic", "portal");
Core.PortalSchematic.Load();
//Read our built in food values first
FoodReader reader = new FoodReader("/assets/tfc2/food.json");
if(reader.read())
{
applyFoodValues(reader);
}
//Now read from the user's mods folder
reader = new FoodReader("");
if(reader.read(new File(TFC.proxy.getMinecraftDir(), "/mods/tfc2/food.json")))
{
applyFoodValues(reader);
}
}
@EventHandler
public void init(FMLInitializationEvent event)
{
proxy.init(event);
}
@EventHandler
public void postInit(FMLPostInitializationEvent event)
{
proxy.postInit(event);
}
@EventHandler
public void modsLoaded(FMLPostInitializationEvent event)
{
ForgeModContainer.zombieBabyChance = 0;
}
@EventHandler
public void serverStarting(FMLServerStartingEvent evt)
{
evt.registerServerCommand(new PrintImageMapCommand());
evt.registerServerCommand(new TeleportInIslandCommand());
evt.registerServerCommand(new RemoveAreaCommand());
evt.registerServerCommand(new StripChunkCommand());
evt.registerServerCommand(new RegenChunkCommand());
}
@EventHandler
public void serverStarting(FMLServerStoppingEvent evt)
{
if(WorldGen.getInstance() != null)
{
WorldGen.getInstance().resetCache();
WorldGen.ClearInstances();
}
}
public void loadSettings()
{
Configuration config;
try
{
config = new Configuration(new File(TFC.proxy.getMinecraftDir(), "/config/TFCOptions.cfg"));
config.load();
} catch (Exception e) {
log.info(new StringBuilder().append("[TFC2] Error while trying to access settings configuration!").toString());
config = null;
}
log.info(new StringBuilder().append("[TFC2] Loading Settings").toString());
/**Start setup here*/
String GAMEL_HEADER = "Game";
String ENGINE_HEADER = "Engine";
String DEBUG_HEADER = "Debug";
//Game
TFCOptions.torchBurnTime = TFCOptions.getIntFor(config, GAMEL_HEADER, "torchBurnTime", 48, "This is how many in-game hours torches will last before burning out. Set to 0 for infinitely burning torches.");
//Engine
TFCOptions.maxThreadsForIslandGen = TFCOptions.getIntFor(config, ENGINE_HEADER, "maxThreadsForIslandGen", 1, "Maximum number of neighboring islands that can be pregenerated at once. Setting this higher may reduce performance.");
//Debug
TFCOptions.shouldGenTrees = TFCOptions.getBooleanFor(config, DEBUG_HEADER, "shouldGenTrees", true, "Setting to false will cause no trees to generate.");
TFCOptions.shouldStripChunks = TFCOptions.getBooleanFor(config, DEBUG_HEADER, "shouldStripChunks", false, "Setting to true will cause all land hexes to generated stripped.");
/**Always end with this*/
if (config != null)
config.save();
}
//*****************
// Private methods
//*****************
private void loadTrees()
{
TreeRegistry tr = TreeRegistry.instance;
String treePath = "/assets/tfc2/schematics/trees/";
log.info("Loading Trees");
tr.addTreeType(new TreeConfig(WoodType.Ash.getName(), Core.getNaturalLog(WoodType.Ash), Core.getLeaves(WoodType.Ash), Moisture.LOW, Moisture.MAX, ClimateTemp.POLAR, ClimateTemp.TEMPERATE, false)); //Ash
tr.addTreeType(new TreeConfig(WoodType.Aspen.getName(), Core.getNaturalLog(WoodType.Aspen), Core.getLeaves(WoodType.Aspen), Moisture.MEDIUM, Moisture.HIGH, ClimateTemp.POLAR, ClimateTemp.TEMPERATE, false)); //Aspen
tr.addTreeType(new TreeConfig(WoodType.Birch.getName(), Core.getNaturalLog(WoodType.Birch), Core.getLeaves(WoodType.Birch), Moisture.LOW, Moisture.MEDIUM, ClimateTemp.SUBPOLAR, ClimateTemp.TEMPERATE, false)); //Birch
tr.addTreeType(new TreeConfig(WoodType.Chestnut.getName(), Core.getNaturalLog(WoodType.Chestnut), Core.getLeaves(WoodType.Chestnut), Moisture.LOW, Moisture.HIGH, ClimateTemp.TEMPERATE, ClimateTemp.SUBTROPICAL, false)); //Chestnut
tr.addTreeType(new TreeConfig(WoodType.DouglasFir.getName(), Core.getNaturalLog(WoodType.DouglasFir), Core.getLeaves(WoodType.DouglasFir), Moisture.MEDIUM, Moisture.HIGH, ClimateTemp.SUBPOLAR, ClimateTemp.TEMPERATE, true)); //Douglas Fir
tr.addTreeType(new TreeConfig(WoodType.Hickory.getName(), Core.getNaturalLog(WoodType.Hickory), Core.getLeaves(WoodType.Hickory), Moisture.LOW, Moisture.HIGH, ClimateTemp.SUBPOLAR, ClimateTemp.TEMPERATE, false)); //Hickory
tr.addTreeType(new TreeConfig(WoodType.Maple.getName(), Core.getNaturalLog(WoodType.Maple), Core.getLeaves(WoodType.Maple), Moisture.LOW, Moisture.HIGH, ClimateTemp.SUBPOLAR, ClimateTemp.TEMPERATE, false)); //Maple
tr.addTreeType(new TreeConfig(WoodType.Oak.getName(), Core.getNaturalLog(WoodType.Oak), Core.getLeaves(WoodType.Oak), Moisture.MEDIUM, Moisture.HIGH, ClimateTemp.SUBPOLAR, ClimateTemp.SUBTROPICAL, false)); //Oak
tr.addTreeType(new TreeConfig(WoodType.Pine.getName(), Core.getNaturalLog(WoodType.Pine), Core.getLeaves(WoodType.Pine), Moisture.LOW, Moisture.VERYHIGH, ClimateTemp.POLAR, ClimateTemp.TEMPERATE, true)); //Pine
tr.addTreeType(new TreeConfig(WoodType.Sequoia.getName(), Core.getNaturalLog(WoodType.Sequoia), Core.getLeaves(WoodType.Sequoia), Moisture.HIGH, Moisture.MAX, ClimateTemp.SUBPOLAR, ClimateTemp.TEMPERATE, true)); //Sequoia
tr.addTreeType(new TreeConfig(WoodType.Spruce.getName(), Core.getNaturalLog(WoodType.Spruce), Core.getLeaves(WoodType.Spruce), Moisture.LOW, Moisture.MAX, ClimateTemp.POLAR, ClimateTemp.SUBTROPICAL, true)); //Spruce
tr.addTreeType(new TreeConfig(WoodType.Sycamore.getName(), Core.getNaturalLog(WoodType.Sycamore), Core.getLeaves(WoodType.Sycamore), Moisture.MEDIUM, Moisture.MAX, ClimateTemp.TEMPERATE, ClimateTemp.SUBTROPICAL, false)); //Sycamore
tr.addTreeType(new TreeConfig(WoodType.WhiteCedar.getName(), Core.getNaturalLog(WoodType.WhiteCedar), Core.getLeaves(WoodType.WhiteCedar), Moisture.LOW, Moisture.MAX, ClimateTemp.POLAR, ClimateTemp.SUBTROPICAL, true)); //White Cedar
tr.addTreeType(new TreeConfig(WoodType.Willow.getName(), Core.getNaturalLog(WoodType.Willow), Core.getLeaves(WoodType.Willow), Moisture.HIGH, Moisture.MAX, ClimateTemp.TEMPERATE, ClimateTemp.SUBTROPICAL, false)); //Willow
tr.addTreeType(new TreeConfig(WoodType.Kapok.getName(), Core.getNaturalLog(WoodType.Kapok), Core.getLeaves(WoodType.Kapok), Moisture.HIGH, Moisture.MAX, ClimateTemp.SUBTROPICAL, ClimateTemp.TROPICAL, false)); //Kapok
tr.addTreeType(new TreeConfig(WoodType.Acacia.getName(), Core.getNaturalLog(WoodType.Acacia), Core.getLeaves(WoodType.Acacia), Moisture.LOW, Moisture.LOW, ClimateTemp.SUBTROPICAL, ClimateTemp.TROPICAL, false)); //Acacia Umbrella
tr.addTreeType(new TreeConfig(WoodType.Rosewood.getName(), Core.getNaturalLog(WoodType.Rosewood), Core.getLeaves(WoodType.Rosewood), Moisture.MEDIUM, Moisture.MAX, ClimateTemp.SUBTROPICAL, ClimateTemp.TROPICAL, false)); //Rosewood
tr.addTreeType(new TreeConfig(WoodType.Blackwood.getName(), Core.getNaturalLog(WoodType.Blackwood), Core.getLeaves(WoodType.Blackwood), Moisture.LOW, Moisture.VERYHIGH, ClimateTemp.SUBTROPICAL, ClimateTemp.TROPICAL, false)); //Blackwood
tr.addTreeType(new TreeConfig(WoodType.Palm.getName(), Core.getNaturalLog(WoodType.Palm), Core.getLeaves(WoodType.Palm), Moisture.LOW, Moisture.MAX, ClimateTemp.SUBTROPICAL, ClimateTemp.TROPICAL, false)); //Palm
for (String s : tr.getTreeNames())
{
String tName = Core.textConvert(s);
for(int i = 0; i < 3; i++)
{
String size = i == 0 ? "Small" : i == 1 ? "Normal" : "Large";
for(int j = 0; j < 99; j++)
{
String p = treePath + tName + "/"+size+"_"+String.format("%02d", j)+".schematic";
TreeSchematic schem = new TreeSchematic(p, size+"_"+String.format("%02d", j), WoodType.getTypeFromString(s));
if(schem.Load())
{
schem.PostProcess();
TreeRegistry.instance.RegisterSchematic(schem, s);
}
else
break;
}
}
}
}
private void loadDungeonSchems()
{
log.info("Load Dungeon Schematics-Start");
DungeonSchemManager dsm = DungeonSchemManager.getInstance();
try
{
Gson gson = new Gson();
JsonReader reader = new JsonReader(new InputStreamReader(getClass().getResourceAsStream("/assets/tfc2/schematics/dungeons/themes.json")));
ArrayList<String> themes = new ArrayList<String>();
reader.beginObject();
while (reader.hasNext())
{
String arrayName = reader.nextName();
if(arrayName.equals("themes"))
{
reader.beginArray();
while (reader.hasNext())
{
themes.add(reader.nextString());
}
reader.endArray();
}
log.info("Loaded Dungeon Theme - " + arrayName);
}
reader.endObject();
reader.close();
for(String themeName : themes)
{
gson = new Gson();
reader = new JsonReader(new InputStreamReader(getClass().getResourceAsStream("/assets/tfc2/schematics/dungeons/themes/"+ themeName +".json")));
reader.beginObject();
while (reader.hasNext())
{
String nextName = reader.nextName();
if(nextName.equals("roomlist"))
{
ArrayList<String> rooms = new ArrayList<String>();
reader.beginArray();
while (reader.hasNext())
{
rooms.add(reader.nextString());
}
reader.endArray();
dsm.loadRooms(themeName, rooms, "/assets/tfc2/schematics/dungeons/"+themeName+"/");
}
else if(nextName.equals("canbemaindungeon"))
{
dsm.getTheme(themeName).setCanBeMainDungeon(reader.nextBoolean());
}
else if(nextName.equals("entrancetype"))
{
dsm.getTheme(themeName).setEntranceType(EntranceType.fromString(reader.nextString()));
}
}
reader.endObject();
reader.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
log.info("Load Dungeon Schematics-Finish");
}
private void applyFoodValues(FoodReader reader)
{
for(FoodJSON f : reader.foodList)
{
ResourceLocation rl = new ResourceLocation(f.itemName);
Item i = ForgeRegistries.ITEMS.getValue(rl);
if(i == null)
{
log.warn("Item not found when searching FoodRegistry for food object ->" + f.itemName);
continue;
}
if(!(i instanceof IFood))
{
log.warn("Item ->" + f.itemName + " is not of type IFood");
continue;
}
//IFood food = (IFood)i;
//food.setExpirationTimer(f.decayTime);
//food.setFoodGroup(f.foodGroup);
FoodRegistry.getInstance().registerFood(f);
}
}
}