package joshie.harvest.buildings; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import joshie.harvest.HarvestFestival; import joshie.harvest.api.HFApi; import joshie.harvest.api.buildings.Building; import joshie.harvest.api.core.ISpecialRules; import joshie.harvest.buildings.block.BlockInternalAir; import joshie.harvest.buildings.building.BuildingFestival; import joshie.harvest.buildings.item.ItemBlueprint; import joshie.harvest.buildings.item.ItemBuilding; import joshie.harvest.buildings.item.ItemCheat; import joshie.harvest.buildings.item.ItemCheat.Cheat; import joshie.harvest.buildings.loader.*; import joshie.harvest.buildings.placeable.Placeable; import joshie.harvest.buildings.render.BuildingItemRenderer; import joshie.harvest.buildings.render.BuildingItemRenderer.BuildingTile; import joshie.harvest.buildings.special.SpecialRuleBuildings; import joshie.harvest.buildings.special.SpecialRuleChurch; import joshie.harvest.buildings.special.SpecialRuleFestivals; import joshie.harvest.core.HFCore; import joshie.harvest.core.base.render.BuildingDefinition; import joshie.harvest.core.base.render.MeshIdentical; import joshie.harvest.core.proxy.HFClientProxy; import joshie.harvest.core.util.HFTemplate; import joshie.harvest.core.util.annotations.HFLoader; import joshie.harvest.npcs.HFNPCs; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.apache.logging.log4j.Level; import java.lang.reflect.InvocationTargetException; import static joshie.harvest.core.helpers.ConfigHelper.getBoolean; import static joshie.harvest.core.lib.LoadOrder.HFBUILDING; import static joshie.harvest.npcs.HFNPCs.CLOCKMAKER_CHILD; @HFLoader(priority = HFBUILDING) @SuppressWarnings("unchecked") public class HFBuildings { public static final ItemBuilding STRUCTURES = new ItemBuilding().register("structures"); public static final ItemBlueprint BLUEPRINTS = new ItemBlueprint().register("blueprint"); private static final ISpecialRules NEVER = (w, p, a) -> false; public static final Building BARN = registerBuilding("barn").setInhabitants(HFNPCs.BARN_OWNER).setOffset(6, -1, 8); public static final Building BLACKSMITH = registerBuilding("blacksmith").setRequirements("miningHill").setInhabitants(HFNPCs.BLACKSMITH).setOffset(3, -2, 6); public static final Building CAFE = registerBuilding("cafe").setRequirements("supermarket").setInhabitants(HFNPCs.CAFE_OWNER, HFNPCs.CAFE_GRANNY).setOffset(7, -1, 10); public static final Building CARPENTER = registerBuilding("carpenter").setSpecialRules(NEVER).setInhabitants(HFNPCs.CARPENTER, HFNPCs.FLOWER_GIRL).setOffset(3, -1, 8); public static final Building CHURCH = registerBuilding("church").setSpecialRules(new SpecialRuleChurch()).setOffset(6, -1, 13); public static final Building CLOCKMAKER = registerBuilding("clockmaker").setRequirements("festivals").setInhabitants(HFNPCs.CLOCKMAKER, CLOCKMAKER_CHILD).setOffset(3, -1, 10); public static final Building FISHING_HOLE = registerBuilding("fishingHole").setRequirements("fishingHut").setOffset(5, -5, 12); public static final Building FISHING_HUT = registerBuilding("fishingHut").setRequirements("barn", "poultryFarm").setInhabitants(HFNPCs.FISHERMAN).setOffset(6, -1, 8); public static final Building GODDESS_POND = registerBuilding("goddessPond").setSpecialRules(new SpecialRuleBuildings(5)).setInhabitants(HFNPCs.GODDESS).setOffset(11, -1, 20); public static final Building MINING_HILL = registerBuilding("miningHill").setRequirements("supermarket").setInhabitants(HFNPCs.MINER).setOffset(10, -3, 11); public static final Building POULTRY_FARM = registerBuilding("poultryFarm").setInhabitants(HFNPCs.POULTRY).setOffset(4, -1, 12); public static final Building SUPERMARKET = registerBuilding("supermarket").setInhabitants(HFNPCs.MILKMAID, HFNPCs.GS_OWNER).setOffset(7, -1, 12).setTickTime(5); public static final Building TOWNHALL = registerBuilding("townhall").setSpecialRules(new SpecialRuleBuildings(9)).setInhabitants(HFNPCs.MAYOR, HFNPCs.PRIEST, HFNPCs.DAUGHTER_ADULT, HFNPCs.DAUGHTER_CHILD).setOffset(10, -1, 17); public static final Building FESTIVAL_GROUNDS = registerBuilding("festivals", BuildingFestival.class).setSpecialRules(new SpecialRuleFestivals()).setInhabitants(HFNPCs.TRADER).setOffset(14, -1, 32); //Debug mode only blocks/items public static ItemCheat CHEAT; public static BlockInternalAir AIR; public static void preInit() { if (HFCore.DEBUG_MODE) { AIR = new BlockInternalAir().register("air"); CHEAT = new ItemCheat().register("cheat"); HFApi.npc.getGifts().addToBlacklist(CHEAT); } } @SideOnly(Side.CLIENT) public static void preInitClient() { ModelLoader.setCustomMeshDefinition(STRUCTURES, new BuildingDefinition(STRUCTURES)); ModelLoader.setCustomMeshDefinition(BLUEPRINTS, new MeshIdentical(BLUEPRINTS)); } public static void init() { HFApi.npc.getGifts().addToBlacklist(STRUCTURES, BLUEPRINTS); for (Building building: Building.REGISTRY.values()) { HFTemplate template = BuildingRegistry.INSTANCE.getTemplateForBuilding(building); if (template != null) template.initTemplate(); else HarvestFestival.LOGGER.log(Level.WARN, "Failed to load the template for the building: " + building.getResource().toString()); } } @SideOnly(Side.CLIENT) public static void initClient() { BuildingDefinition.registerEverything(); if (HFCore.DEBUG_MODE) { HFClientProxy.RENDER_MAP.put(CHEAT, BuildingTile.INSTANCE); ClientRegistry.bindTileEntitySpecialRenderer(BuildingTile.class, new BuildingItemRenderer()); ForgeHooksClient.registerTESRItemStack(CHEAT, Cheat.BUILDING_PREVIEW.ordinal(), BuildingTile.class); } } @SuppressWarnings("unchecked") public static <B extends Building> B registerBuilding(String name, Class<B>... clazzes) { Class<B> clazz = clazzes.length == 1 ? clazzes[0] : null; Building building = null; try { if (clazz != null) building = clazz.getConstructor(ResourceLocation.class).newInstance(new ResourceLocation("harvestfestival", name)); } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) { /**/} if (building == null) { building = new Building(new ResourceLocation("harvestfestival", name)); building.setRegistryName(new ResourceLocation("harvestfestival", name)); BuildingRegistry.REGISTRY.register(building); } return (B) building; } private static Gson gson; //Temporary public static Gson getGson() { //Create the gson if it's null if (gson == null) { GsonBuilder builder = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().setExclusionStrategies(new SuperClassExclusionStrategy()); builder.registerTypeAdapter(Placeable.class, new PlaceableAdapter()); builder.registerTypeAdapter(IBlockState.class, new StateAdapter()); builder.registerTypeAdapter(ItemStack.class, new StackAdapter()); builder.registerTypeAdapter(ResourceLocation.class, new ResourceAdapter()); builder.registerTypeAdapter(ITextComponent.class, new TextComponentAdapter()); builder.registerTypeAdapter(BlockPos.class, new BlockPosAdapter()); builder.registerTypeAdapter(EnumFacing.class, new FacingAdapter()); gson = builder.create(); } return gson; } private static class SuperClassExclusionStrategy implements ExclusionStrategy { @Override public boolean shouldSkipClass(Class<?> clazz) { return false; } @Override public boolean shouldSkipField(FieldAttributes field) { return field.getDeclaringClass().equals(Impl.class); } } //Configuration public static boolean FULL_BUILDING_RENDER; public static boolean CHEAT_BUILDINGS; public static boolean ENABLE_DEMOLITION; public static void configure() { FULL_BUILDING_RENDER = getBoolean("Use Full Building Render", true); CHEAT_BUILDINGS = getBoolean("Use Cheat Buildings", false); ENABLE_DEMOLITION = getBoolean("Enable demolition", true); } }