mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-03-03 16:51:28 +01:00
Re-implemented the crafting interface for spellbooks
This commit is contained in:
parent
b3e689d220
commit
1f433bf497
23 changed files with 1197 additions and 6 deletions
|
@ -33,11 +33,13 @@ import net.minecraft.item.crafting.IRecipe;
|
|||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.item.crafting.ShapedRecipes;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.ModelLoader;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
import static com.minelittlepony.unicopia.Predicates.*;
|
||||
|
||||
import com.minelittlepony.unicopia.forgebullshit.BuildInTexturesBakery;
|
||||
import com.minelittlepony.unicopia.forgebullshit.RegistryLockSpinner;
|
||||
|
||||
public class UItems {
|
||||
|
@ -153,6 +155,8 @@ public class UItems {
|
|||
registerAllVariants(tomato, "tomato", "rotten_tomato");
|
||||
registerAllVariants(cloudsdale_tomato, "cloudsdale_tomato", "rotten_cloudsdale_tomato");
|
||||
registerAllVariants(tomato_seeds, "tomato_seeds");
|
||||
|
||||
BuildInTexturesBakery.getBuiltInTextures().add(new ResourceLocation("unicopia", "items/empty_slot_gem"));
|
||||
}
|
||||
|
||||
registerFuels();
|
||||
|
|
|
@ -29,16 +29,23 @@ import net.minecraftforge.fml.common.Mod;
|
|||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event.Result;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
|
||||
import net.minecraftforge.fml.common.network.IGuiHandler;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.registry.EntityEntry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.jumpingcastle.api.IChannel;
|
||||
import com.minelittlepony.jumpingcastle.api.JumpingCastle;
|
||||
import com.minelittlepony.jumpingcastle.api.Target;
|
||||
|
@ -48,15 +55,19 @@ import com.minelittlepony.unicopia.client.particle.EntityMagicFX;
|
|||
import com.minelittlepony.unicopia.client.particle.EntityRaindropFX;
|
||||
import com.minelittlepony.unicopia.client.particle.Particles;
|
||||
import com.minelittlepony.unicopia.command.Commands;
|
||||
import com.minelittlepony.unicopia.enchanting.SpellRecipe;
|
||||
import com.minelittlepony.unicopia.forgebullshit.FBS;
|
||||
import com.minelittlepony.unicopia.hud.UHud;
|
||||
import com.minelittlepony.unicopia.input.Keyboard;
|
||||
import com.minelittlepony.unicopia.inventory.gui.ContainerSpellBook;
|
||||
import com.minelittlepony.unicopia.inventory.gui.GuiSpellBook;
|
||||
import com.minelittlepony.unicopia.network.MsgPlayerAbility;
|
||||
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
|
||||
import com.minelittlepony.unicopia.network.MsgRequestCapabilities;
|
||||
import com.minelittlepony.unicopia.player.IPlayer;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
import com.minelittlepony.unicopia.power.PowersRegistry;
|
||||
import com.minelittlepony.unicopia.util.crafting.CraftingManager;
|
||||
import com.minelittlepony.pony.data.IPony;
|
||||
|
||||
@Mod(
|
||||
|
@ -66,7 +77,7 @@ import com.minelittlepony.pony.data.IPony;
|
|||
dependencies = "required-after:jumpingcastle"
|
||||
)
|
||||
@EventBusSubscriber
|
||||
public class Unicopia {
|
||||
public class Unicopia implements IGuiHandler {
|
||||
public static final String MODID = "unicopia";
|
||||
public static final String NAME = "@NAME@";
|
||||
public static final String VERSION = "@VERSION@";
|
||||
|
@ -86,6 +97,8 @@ public class Unicopia {
|
|||
*/
|
||||
private static Race clientPlayerRace = getclientPlayerRace();
|
||||
|
||||
private static CraftingManager craftingManager;
|
||||
|
||||
@EventHandler
|
||||
public void preInit(FMLPreInitializationEvent event) {
|
||||
if (UClient.isClientSide()) {
|
||||
|
@ -117,6 +130,24 @@ public class Unicopia {
|
|||
UAdvancements.init();
|
||||
|
||||
FBS.init();
|
||||
|
||||
NetworkRegistry.INSTANCE.registerGuiHandler(this, this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void posInit(FMLPostInitializationEvent event) {
|
||||
craftingManager = new CraftingManager(MODID, "enchanting") {
|
||||
@Override
|
||||
protected void registerRecipeTypes(Map<String, Function<JsonObject, IRecipe>> types) {
|
||||
super.registerRecipeTypes(types);
|
||||
|
||||
types.put("unicopia:crafting_spell", SpellRecipe::deserialize);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static CraftingManager getCraftingManager() {
|
||||
return craftingManager;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -295,4 +326,20 @@ public class Unicopia {
|
|||
|
||||
event.setNewfov(fov);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
||||
switch (ID) {
|
||||
case 0: return new ContainerSpellBook(player.inventory, world, new BlockPos(x, y, z));
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
||||
switch (ID) {
|
||||
case 0: return new GuiSpellBook(player);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package com.minelittlepony.unicopia.enchanting;
|
||||
|
||||
import com.minelittlepony.unicopia.UItems;
|
||||
import com.minelittlepony.unicopia.enchanting.PagesList.IPageEvent;
|
||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* A basic event for unlocking a page when a gem is crafted for the given spell
|
||||
*/
|
||||
public class BasicCraftingEvent implements IPageEvent {
|
||||
|
||||
private final String matched;
|
||||
private final int pageIndex;
|
||||
|
||||
public BasicCraftingEvent(int page, String effectName) {
|
||||
matched = effectName;
|
||||
pageIndex = page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(IPageOwner prop, ItemStack stack) {
|
||||
return stack.getItem() == UItems.spell && SpellRegistry.getKeyFromStack(stack).equals(matched);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPage(int stackSize) {
|
||||
return pageIndex;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.minelittlepony.unicopia.enchanting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.minelittlepony.unicopia.network.ITransmittable;
|
||||
|
||||
public interface IPageOwner extends ITransmittable {
|
||||
|
||||
@Nonnull
|
||||
List<Integer> getUnlockedPages();
|
||||
|
||||
default boolean hasPageUnlock(int pageIndex) {
|
||||
return getUnlockedPages().contains(pageIndex);
|
||||
}
|
||||
|
||||
default boolean unlockPage(int pageIndex) {
|
||||
if (!hasPageUnlock(pageIndex)) {
|
||||
if (getUnlockedPages().add(pageIndex)) {
|
||||
sendCapabilities(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean hasUnlockedPages() {
|
||||
return getUnlockedPages().size() > 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.minelittlepony.unicopia.enchanting;
|
||||
|
||||
public interface IPageUnlockListener {
|
||||
public void onPageUnlocked();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.minelittlepony.unicopia.enchanting;
|
||||
|
||||
import com.minelittlepony.unicopia.enchanting.PagesList.IPageEvent;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* An unlock event that requires other pages to be unlocked before it too can be unlocked.
|
||||
*
|
||||
*/
|
||||
public class MultiPageUnlockEvent implements IPageEvent {
|
||||
|
||||
private final int pageIndex;
|
||||
|
||||
private final int[][] otherPageIndeces;
|
||||
|
||||
public MultiPageUnlockEvent(int page, int[]... otherPages) {
|
||||
pageIndex = page;
|
||||
otherPageIndeces = otherPages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(IPageOwner prop, ItemStack stack) {
|
||||
for (int i = 0; i < otherPageIndeces.length; i++) {
|
||||
if (!checkPageUnlockSet(prop, otherPageIndeces[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkPageUnlockSet(IPageOwner prop, int[] pages) {
|
||||
for (int i = 0; i < pages.length; i++) {
|
||||
if (prop.hasPageUnlock(pages[i])) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPage(int stackSize) {
|
||||
return pageIndex;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package com.minelittlepony.unicopia.enchanting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class PagesList {
|
||||
|
||||
private static final List<Integer> unreadPages = new ArrayList<Integer>();
|
||||
|
||||
private static final List<IPageEvent> pageEvents = new ArrayList<IPageEvent>();
|
||||
|
||||
private static int totalPages = 0;
|
||||
|
||||
/**
|
||||
* Sets the maximum number of pages displayed in the spellbook.
|
||||
* Only allows widening. Total pages cannot be reduced.
|
||||
*/
|
||||
public static void setTotalPages(int pages) {
|
||||
if (pages > totalPages) {
|
||||
totalPages = pages;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getTotalPages() {
|
||||
return totalPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an event for unlocking a page.
|
||||
*/
|
||||
public static void registerPageEvent(IPageEvent event) {
|
||||
pageEvents.add(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a page as read
|
||||
*/
|
||||
public static void readPage(int pageIndex) {
|
||||
unreadPages.remove(Integer.valueOf(pageIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are any pages after the given index that are unread
|
||||
* Only useful on the client
|
||||
*/
|
||||
public static boolean hasUnreadPagesAfter(int pageIndex) {
|
||||
for (Integer i : unreadPages) {
|
||||
if (i > pageIndex) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are any pages before the given index that are unread
|
||||
* Only useful on the client
|
||||
*/
|
||||
public static boolean hasUnreadPagesBefore(int pageIndex) {
|
||||
for (Integer i : unreadPages) {
|
||||
if (i < pageIndex) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given page has been read yet.
|
||||
* Only of use on the client
|
||||
*/
|
||||
public static boolean isPageUnread(int pageIndex) {
|
||||
return unreadPages.contains(pageIndex);
|
||||
}
|
||||
|
||||
private static boolean unlockPages(IPageOwner prop, ItemStack stack) {
|
||||
boolean result = false;
|
||||
if (stack != null && stack.getCount() > 0) {
|
||||
for (IPageEvent i : pageEvents) {
|
||||
if (i.matches(prop, stack)) {
|
||||
int page = i.getPage(stack.getCount());
|
||||
if (page >= 0 && prop.unlockPage(page)) {
|
||||
result |= unreadPages.add(page);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for, and unlocks any pages that can be unlocked by the given item for the given player
|
||||
* @return True if a page was unlocked, false otherwise
|
||||
*/
|
||||
public static boolean unlockPage(EntityPlayer player, ItemStack stack) {
|
||||
return unlockPages(PlayerSpeciesList.instance().getPlayer(player), stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* A PageEvent for determining when certain pages must be unlocked.
|
||||
*
|
||||
*/
|
||||
public static interface IPageEvent {
|
||||
/**
|
||||
* Checks if this event's conditions are met.
|
||||
* @param prop PlayerExtension for the player doing the crafting
|
||||
* @param stack ItemStack crafted
|
||||
*/
|
||||
public boolean matches(IPageOwner prop, ItemStack stack);
|
||||
|
||||
/**
|
||||
* Gets the page number corresponding to the given stack for this event
|
||||
*/
|
||||
public int getPage(int stackSize);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package com.minelittlepony.unicopia.enchanting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.UItems;
|
||||
import com.minelittlepony.unicopia.inventory.InventorySpellBook;
|
||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry.Impl;
|
||||
|
||||
public class SpellRecipe extends Impl<IRecipe> implements IRecipe {
|
||||
|
||||
private String spellId;
|
||||
|
||||
private final NonNullList<RecipeItem> ingredients;
|
||||
|
||||
public static IRecipe deserialize(JsonObject json) {
|
||||
|
||||
NonNullList<RecipeItem> ingredients = NonNullList.create();
|
||||
|
||||
for (JsonElement i : json.get("ingredients").getAsJsonArray()) {
|
||||
JsonObject o = i.getAsJsonObject();
|
||||
|
||||
Item item = Item.getByNameOrId(o.get("item").getAsString());
|
||||
|
||||
if (item != null) {
|
||||
int metadata = Math.max(0, o.has("data") ? o.get("data").getAsInt() : 0);
|
||||
int size = Math.max(1, o.has("count") ? o.get("count").getAsInt() : 1);
|
||||
|
||||
ingredients.add(new RecipeItem(new ItemStack(item, size, metadata), !o.has("data")));
|
||||
}
|
||||
}
|
||||
|
||||
json = json.get("result").getAsJsonObject();
|
||||
|
||||
String spellId = json.get("spell").getAsString();
|
||||
|
||||
return new SpellRecipe(spellId, ingredients);
|
||||
}
|
||||
|
||||
public SpellRecipe(String spellName, NonNullList<RecipeItem> ingredients) {
|
||||
spellId = spellName;
|
||||
this.ingredients = ingredients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(InventoryCrafting inv, World worldIn) {
|
||||
ItemStack enchantedStack = ((InventorySpellBook)inv).getCraftResultMatrix().getStackInSlot(0);
|
||||
|
||||
if (enchantedStack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int materialMult = enchantedStack.getCount();
|
||||
|
||||
ArrayList<RecipeItem> toMatch = Lists.newArrayList(ingredients);
|
||||
|
||||
for (int i = 0; i < inv.getSizeInventory(); i++) {
|
||||
ItemStack stack = inv.getStackInSlot(i);
|
||||
|
||||
if (!stack.isEmpty()) {
|
||||
if (toMatch.isEmpty() && !stack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!toMatch.isEmpty() && !toMatch.removeIf(s -> s.matches(stack, materialMult))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return toMatch.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getCraftingResult(InventoryCrafting inv) {
|
||||
return getRecipeOutput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFit(int width, int height) {
|
||||
return width * height < ingredients.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getRecipeOutput() {
|
||||
return SpellRegistry.instance().enchantStack(new ItemStack(UItems.spell, 1), spellId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NonNullList<ItemStack> getRemainingItems(InventoryCrafting inv) {
|
||||
NonNullList<ItemStack> remainers = NonNullList.<ItemStack>withSize(inv.getSizeInventory(), ItemStack.EMPTY);
|
||||
for (int i = 0; i < remainers.size(); i++) {
|
||||
ItemStack stack = inv.getStackInSlot(i);
|
||||
|
||||
if (stack != null && stack.getItem().hasContainerItem(stack)) {
|
||||
remainers.set(i, new ItemStack(stack.getItem().getContainerItem()));
|
||||
}
|
||||
}
|
||||
return remainers;
|
||||
}
|
||||
|
||||
private static class RecipeItem {
|
||||
|
||||
private final ItemStack contained;
|
||||
private final boolean ignoreMeta;
|
||||
|
||||
RecipeItem(ItemStack stack, boolean meta) {
|
||||
contained = stack;
|
||||
ignoreMeta = meta;
|
||||
}
|
||||
|
||||
boolean matches(ItemStack other, int materialMult) {
|
||||
if (other.isEmpty() != contained.isEmpty()) {
|
||||
return false;
|
||||
} else if (other.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (other.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (contained.getItem() == other.getItem()
|
||||
&& (ignoreMeta || other.getMetadata() == contained.getMetadata())) {
|
||||
|
||||
return other.getCount() >= (materialMult * contained.getCount());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,10 +2,12 @@ package com.minelittlepony.unicopia.entity;
|
|||
|
||||
import com.minelittlepony.unicopia.Predicates;
|
||||
import com.minelittlepony.unicopia.UItems;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
|
@ -130,7 +132,10 @@ public class EntitySpellbook extends EntityLiving implements IMagicals {
|
|||
}
|
||||
|
||||
if (Predicates.MAGI.test(player)) {
|
||||
//ApiGui.openContainer((EntityPlayerMP)player, new InterfaceBook());
|
||||
|
||||
player.playSound(SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, 2, 1);
|
||||
|
||||
player.openGui(Unicopia.MODID, 0, world, (int)posX, (int)posY, (int)posZ);
|
||||
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.minelittlepony.unicopia.forgebullshit;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.ModelBakery;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
|
||||
public final class BuildInTexturesBakery extends ModelBakery {
|
||||
private BuildInTexturesBakery() {
|
||||
super(null, null, null);
|
||||
}
|
||||
|
||||
public static Set<ResourceLocation> getBuiltInTextures() {
|
||||
return LOCATIONS_BUILTIN_TEXTURES;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.minelittlepony.unicopia.inventory;
|
||||
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
|
||||
public class InventorySpellBook extends InventoryCrafting {
|
||||
|
||||
private final IInventory craftResult;
|
||||
|
||||
public InventorySpellBook(IInventory resultMatrix, Container eventHandler, int width, int height) {
|
||||
super(eventHandler, width, height);
|
||||
craftResult = resultMatrix;
|
||||
}
|
||||
|
||||
public IInventory getCraftResultMatrix() {
|
||||
return craftResult;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
package com.minelittlepony.unicopia.inventory.gui;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.minelittlepony.unicopia.Predicates;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.enchanting.IPageUnlockListener;
|
||||
import com.minelittlepony.unicopia.inventory.InventorySpellBook;
|
||||
import com.minelittlepony.unicopia.inventory.slot.SlotEnchanting;
|
||||
import com.minelittlepony.unicopia.inventory.slot.SlotEnchantingResult;
|
||||
import com.minelittlepony.unicopia.item.ItemSpell;
|
||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.InventoryBasic;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ContainerSpellBook extends Container {
|
||||
|
||||
private final World worldObj;
|
||||
|
||||
private IInventory craftResult = new InventoryBasic("Spell Result", false, 1);
|
||||
|
||||
private InventorySpellBook craftMatrix = new InventorySpellBook(craftResult, this, 5, 1);
|
||||
|
||||
private IPageUnlockListener listener;
|
||||
|
||||
private SlotEnchantingResult resultSlot = null;
|
||||
|
||||
private final EntityPlayer player;
|
||||
|
||||
public ContainerSpellBook(InventoryPlayer inventory, World world, BlockPos pos) {
|
||||
super();
|
||||
worldObj = world;
|
||||
player = inventory.player;
|
||||
|
||||
initCraftingSlots();
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
addSlotToContainer(new Slot(inventory, i, 121 + i * 18, 195));
|
||||
}
|
||||
|
||||
onCraftMatrixChanged(craftMatrix);
|
||||
}
|
||||
|
||||
public void setListener(IPageUnlockListener listener) {
|
||||
this.listener = listener;
|
||||
|
||||
if (resultSlot != null) {
|
||||
resultSlot.setListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void initCraftingSlots() {
|
||||
addSlotToContainer(new SlotEnchanting(craftMatrix, 0, 180, 50));
|
||||
addSlotToContainer(new SlotEnchanting(craftMatrix, 1, 154, 94));
|
||||
addSlotToContainer(new SlotEnchanting(craftMatrix, 2, 180, 134));
|
||||
addSlotToContainer(new SlotEnchanting(craftMatrix, 3, 231, 120));
|
||||
addSlotToContainer(new SlotEnchanting(craftMatrix, 4, 232, 65));
|
||||
addSlotToContainer(resultSlot = new SlotEnchantingResult(listener, player, craftMatrix, craftResult, 0, 196, 92));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCraftMatrixChanged(IInventory inventoryIn) {
|
||||
ItemStack current = craftResult.getStackInSlot(0);
|
||||
|
||||
if (!current.isEmpty()) {
|
||||
ItemStack crafted = Unicopia.getCraftingManager().findMatchingResult(craftMatrix, worldObj);
|
||||
|
||||
if (!crafted.isEmpty()) {
|
||||
current = SpellRegistry.instance().enchantStack(current, crafted);
|
||||
|
||||
player.playSound(SoundEvents.BLOCK_NOTE_CHIME, 1, 1);
|
||||
} else {
|
||||
current = SpellRegistry.instance().disenchantStack(current);
|
||||
|
||||
player.playSound(SoundEvents.BLOCK_NOTE_BASS, 1, 1);
|
||||
}
|
||||
|
||||
craftResult.setInventorySlotContents(0, current);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
|
||||
ItemStack stack = ItemStack.EMPTY;
|
||||
Slot slot = inventorySlots.get(index);
|
||||
|
||||
if (slot != null && slot.getHasStack()) {
|
||||
ItemStack slotStack = slot.getStack();
|
||||
stack = slotStack.copy();
|
||||
|
||||
if (index > 5) {
|
||||
if (stack.getItem() instanceof ItemSpell) {
|
||||
if (!mergeItemStack(slotStack, 5, 6, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else if (!mergeItemStack(slotStack, 0, 5, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else {
|
||||
if (!mergeItemStack(slotStack, 6, 15, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
slot.onSlotChange(slotStack, stack);
|
||||
onCraftMatrixChanged(craftMatrix);
|
||||
}
|
||||
|
||||
if (slotStack.getCount() == stack.getCount()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
slot.onTake(playerIn, slotStack);
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContainerClosed(EntityPlayer player) {
|
||||
super.onContainerClosed(player);
|
||||
|
||||
for (int i = 0; i < craftMatrix.getSizeInventory(); i++) {
|
||||
if (craftMatrix.getStackInSlot(i) != null) {
|
||||
player.dropItem(craftMatrix.getStackInSlot(i), false);
|
||||
craftMatrix.setInventorySlotContents(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
if (craftResult.getStackInSlot(0) != null) {
|
||||
player.dropItem(craftResult.getStackInSlot(0), false);
|
||||
craftResult.setInventorySlotContents(0, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer player) {
|
||||
return Predicates.MAGI.test(player);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
package com.minelittlepony.unicopia.inventory.gui;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.minelittlepony.unicopia.enchanting.IPageUnlockListener;
|
||||
import com.minelittlepony.unicopia.enchanting.PagesList;
|
||||
import com.minelittlepony.unicopia.inventory.slot.SlotEnchanting;
|
||||
import com.minelittlepony.unicopia.player.IPlayer;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.texture.TextureUtil;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class GuiSpellBook extends GuiContainer implements IPageUnlockListener {
|
||||
private static int currentPage = 0;
|
||||
private static ResourceLocation spellBookPageTextures = new ResourceLocation("unicopia", "textures/gui/container/pages/page-" + currentPage + ".png");
|
||||
|
||||
private static final ResourceLocation spellBookGuiTextures = new ResourceLocation("unicopia", "textures/gui/container/book.png");
|
||||
|
||||
private IPlayer playerExtension;
|
||||
|
||||
private PageButton nextPage;
|
||||
private PageButton prevPage;
|
||||
|
||||
public GuiSpellBook(EntityPlayer player) {
|
||||
super(new ContainerSpellBook(player.inventory, player.world, new BlockPos(player)));
|
||||
player.openContainer = inventorySlots;
|
||||
((ContainerSpellBook)inventorySlots).setListener(this);
|
||||
xSize = 405;
|
||||
ySize = 219;
|
||||
allowUserInput = true;
|
||||
playerExtension = PlayerSpeciesList.instance().getPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
buttonList.clear();
|
||||
|
||||
int x = (width - xSize) / 2;
|
||||
int y = (height - ySize) / 2;
|
||||
|
||||
buttonList.add(nextPage = new PageButton(1, x + 360, y + 160, true));
|
||||
buttonList.add(prevPage = new PageButton(2, x + 20, y + 160, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton button) throws IOException {
|
||||
initGui();
|
||||
|
||||
if (button.id == 1) {
|
||||
nextPage();
|
||||
} else {
|
||||
prevPage();
|
||||
}
|
||||
}
|
||||
|
||||
public void nextPage() {
|
||||
if (currentPage == 0) {
|
||||
playerExtension.unlockPage(1);
|
||||
}
|
||||
if (currentPage < PagesList.getTotalPages() - 1) {
|
||||
currentPage++;
|
||||
spellBookPageTextures = new ResourceLocation("unicopia", "textures/gui/container/pages/page-" + currentPage + ".png");
|
||||
|
||||
onPageUnlocked();
|
||||
PagesList.readPage(currentPage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageUnlocked() {
|
||||
if (PagesList.hasUnreadPagesAfter(currentPage)) {
|
||||
nextPage.triggerShake();
|
||||
}
|
||||
|
||||
if (PagesList.hasUnreadPagesBefore(currentPage)) {
|
||||
prevPage.triggerShake();
|
||||
}
|
||||
}
|
||||
|
||||
public void prevPage() {
|
||||
if (currentPage > 0) {
|
||||
currentPage--;
|
||||
spellBookPageTextures = new ResourceLocation("unicopia", "textures/gui/container/pages/page-" + currentPage + ".png");
|
||||
|
||||
onPageUnlocked();
|
||||
PagesList.readPage(currentPage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGradientRect(int left, int top, int width, int height, int startColor, int endColor) {
|
||||
Slot slot = getSlotUnderMouse();
|
||||
if (slot == null || left != slot.xPos || top != slot.yPos || !drawSlotOverlay(slot)) {
|
||||
super.drawGradientRect(left, top, width, height, startColor, endColor);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean drawSlotOverlay(Slot slot) {
|
||||
if (slot instanceof SlotEnchanting) {
|
||||
GlStateManager.enableBlend();
|
||||
GL11.glDisable(GL11.GL_ALPHA_TEST);
|
||||
mc.getTextureManager().bindTexture(spellBookGuiTextures);
|
||||
drawModalRectWithCustomSizedTexture(slot.xPos - 1, slot.yPos - 1, 51, 223, 18, 18, 512, 256);
|
||||
GL11.glEnable(GL11.GL_ALPHA_TEST);
|
||||
GlStateManager.disableBlend();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
|
||||
renderHoveredToolTip(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
|
||||
if (PagesList.getTotalPages() > 0) {
|
||||
String text = (currentPage + 1) + "/" + PagesList.getTotalPages();
|
||||
fontRenderer.drawString(text, 203 - fontRenderer.getStringWidth(text)/2, 165, 0x0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
|
||||
GlStateManager.color(1, 1, 1, 1);
|
||||
|
||||
int left = (width - xSize) / 2;
|
||||
int top = (height - ySize) / 2;
|
||||
|
||||
mc.getTextureManager().bindTexture(spellBookGuiTextures);
|
||||
drawModalRectWithCustomSizedTexture(left, top, 0, 0, xSize, ySize, 512, 256);
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GL11.glDisable(GL11.GL_ALPHA_TEST);
|
||||
|
||||
if (playerExtension.hasPageUnlock(currentPage)) {
|
||||
if (mc.getTextureManager().getTexture(spellBookPageTextures) != TextureUtil.MISSING_TEXTURE) {
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
mc.getTextureManager().bindTexture(spellBookPageTextures);
|
||||
drawModalRectWithCustomSizedTexture(left, top, 0, 0, xSize, ySize, 512, 256);
|
||||
}
|
||||
}
|
||||
|
||||
mc.getTextureManager().bindTexture(spellBookGuiTextures);
|
||||
drawModalRectWithCustomSizedTexture(left + 152, top + 49, 407, 2, 100, 101, 512, 256);
|
||||
|
||||
GL11.glEnable(GL11.GL_ALPHA_TEST);
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
static class PageButton extends GuiButton {
|
||||
private final boolean direction;
|
||||
|
||||
private int shakesLeft = 0;
|
||||
private float shakeCount = 0;
|
||||
|
||||
public PageButton(int id, int x, int y, boolean direction) {
|
||||
super(id, x, y, 23, 13, "");
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) {
|
||||
if (visible) {
|
||||
int x = this.x;
|
||||
int y = this.y;
|
||||
if (shakesLeft > 0) {
|
||||
shakeCount += (float)Math.PI/2;
|
||||
if (shakeCount >= Math.PI * 2) {
|
||||
shakeCount %= Math.PI*2;
|
||||
shakesLeft--;
|
||||
}
|
||||
x += (int)(Math.sin(shakeCount)*3);
|
||||
y -= (int)(Math.sin(shakeCount)*3);
|
||||
}
|
||||
|
||||
boolean hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + width && mouseY < this.y + height;
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
mc.getTextureManager().bindTexture(spellBookGuiTextures);
|
||||
int u = 0;
|
||||
int v = 220;
|
||||
if (hovered) u += 23;
|
||||
if (!direction) v += 13;
|
||||
drawModalRectWithCustomSizedTexture(x, y, u, v, 23, 13, 512, 256);
|
||||
}
|
||||
}
|
||||
|
||||
public void triggerShake() {
|
||||
if (shakesLeft <= 0) {
|
||||
shakesLeft = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.minelittlepony.unicopia.inventory.slot;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
|
||||
public class SlotEnchanting extends Slot {
|
||||
|
||||
public SlotEnchanting(IInventory inventoryIn, int index, int xPosition, int yPosition) {
|
||||
super(inventoryIn, index, xPosition, yPosition);
|
||||
}
|
||||
|
||||
public boolean canBeHovered() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package com.minelittlepony.unicopia.inventory.slot;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.enchanting.IPageUnlockListener;
|
||||
import com.minelittlepony.unicopia.enchanting.PagesList;
|
||||
import com.minelittlepony.unicopia.inventory.InventorySpellBook;
|
||||
import com.minelittlepony.unicopia.item.ItemSpell;
|
||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
|
||||
public class SlotEnchantingResult extends SlotEnchanting {
|
||||
|
||||
private final EntityPlayer thePlayer;
|
||||
private final InventorySpellBook craftMatrix;
|
||||
|
||||
private IPageUnlockListener listener;
|
||||
|
||||
public SlotEnchantingResult(IPageUnlockListener listener, EntityPlayer player, InventorySpellBook craftMatric, IInventory inventory, int index, int xPosition, int yPosition) {
|
||||
super(inventory, index, xPosition, yPosition);
|
||||
thePlayer = player;
|
||||
this.listener = listener;
|
||||
craftMatrix = craftMatric;
|
||||
}
|
||||
|
||||
public void setListener(IPageUnlockListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack onTake(EntityPlayer player, ItemStack stack) {
|
||||
onCrafting(stack);
|
||||
|
||||
ItemStack current = craftMatrix.getCraftResultMatrix().getStackInSlot(0);
|
||||
craftMatrix.getCraftResultMatrix().setInventorySlotContents(0, stack);
|
||||
|
||||
NonNullList<ItemStack> remaining = Unicopia.getCraftingManager().getRemainingItems(craftMatrix, player.world);
|
||||
|
||||
craftMatrix.getCraftResultMatrix().setInventorySlotContents(0, current);
|
||||
|
||||
for (int i = 0; i < remaining.size(); ++i) {
|
||||
current = craftMatrix.getStackInSlot(i);
|
||||
ItemStack remainder = remaining.get(i);
|
||||
|
||||
if (!current.isEmpty()) {
|
||||
if (current.getCount() < stack.getCount()) {
|
||||
craftMatrix.setInventorySlotContents(i, ItemStack.EMPTY);
|
||||
} else {
|
||||
craftMatrix.decrStackSize(i, stack.getCount());
|
||||
}
|
||||
|
||||
if (!remainder.isEmpty()) {
|
||||
if (craftMatrix.getStackInSlot(i).isEmpty()) {
|
||||
craftMatrix.setInventorySlotContents(i, remainder);
|
||||
} else {
|
||||
remainder.setCount(stack.getCount());
|
||||
if (!player.inventory.addItemStackToInventory(remainder)) {
|
||||
player.dropItem(remainder, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.onTake(player, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCrafting(ItemStack stack, int amount) {
|
||||
onCrafting(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCrafting(ItemStack stack) {
|
||||
if (PagesList.unlockPage(thePlayer, stack) && listener != null) {
|
||||
listener.onPageUnlocked();
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.onPageUnlocked();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(ItemStack stack) {
|
||||
return stack.getItem() instanceof ItemSpell && !SpellRegistry.stackHasEnchantment(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSlotTexture() {
|
||||
return "unicopia:items/empty_slot_gem";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.minelittlepony.unicopia.network;
|
||||
|
||||
public interface ITransmittable {
|
||||
void sendCapabilities(boolean full);
|
||||
}
|
|
@ -3,6 +3,8 @@ package com.minelittlepony.unicopia.player;
|
|||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.model.anim.IInterpolator;
|
||||
import com.minelittlepony.unicopia.enchanting.IPageOwner;
|
||||
import com.minelittlepony.unicopia.network.ITransmittable;
|
||||
import com.minelittlepony.unicopia.spell.ICaster;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
@ -10,9 +12,7 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
|
||||
public interface IPlayer extends ICaster<EntityPlayer>, IRaceContainer<EntityPlayer> {
|
||||
|
||||
void sendCapabilities(boolean full);
|
||||
public interface IPlayer extends ICaster<EntityPlayer>, IRaceContainer<EntityPlayer>, ITransmittable, IPageOwner {
|
||||
|
||||
IAbilityReceiver getAbilities();
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
package com.minelittlepony.unicopia.player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.minelittlepony.model.anim.BasicEasingInterpolator;
|
||||
import com.minelittlepony.model.anim.IInterpolator;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
|
@ -17,6 +22,7 @@ import net.minecraft.entity.player.EntityPlayer;
|
|||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.init.MobEffects;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagIntArray;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
|
@ -29,12 +35,17 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
private static final DataParameter<Integer> PLAYER_RACE = EntityDataManager
|
||||
.createKey(EntityPlayer.class, DataSerializers.VARINT);
|
||||
|
||||
private static final DataParameter<Integer> ENERGY = EntityDataManager
|
||||
.createKey(EntityPlayer.class, DataSerializers.VARINT);
|
||||
|
||||
private static final DataParameter<Float> EXERTION = EntityDataManager
|
||||
.createKey(EntityPlayer.class, DataSerializers.FLOAT);
|
||||
|
||||
private static final DataParameter<NBTTagCompound> EFFECT = EntityDataManager
|
||||
.createKey(EntityPlayer.class, DataSerializers.COMPOUND_TAG);
|
||||
|
||||
private final List<Integer> pages = Lists.newArrayList();
|
||||
|
||||
private final PlayerAbilityDelegate powers = new PlayerAbilityDelegate(this);
|
||||
|
||||
private final PlayerGravityDelegate gravity = new PlayerGravityDelegate(this);
|
||||
|
@ -57,6 +68,7 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
player.getDataManager().register(PLAYER_RACE, Race.HUMAN.ordinal());
|
||||
player.getDataManager().register(EXERTION, 0F);
|
||||
player.getDataManager().register(EFFECT, new NBTTagCompound());
|
||||
player.getDataManager().register(ENERGY, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -159,7 +171,7 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
if (!getPlayerSpecies().canCast()) {
|
||||
setEffect(null);
|
||||
} else {
|
||||
if (entity.getEntityWorld().isRemote) { // && entity.getEntityWorld().getWorldTime() % 10 == 0
|
||||
if (entity.getEntityWorld().isRemote) {
|
||||
getEffect().renderOnPerson(this);
|
||||
}
|
||||
|
||||
|
@ -219,6 +231,10 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
compound.setTag("powers", powers.toNBT());
|
||||
compound.setTag("gravity", gravity.toNBT());
|
||||
|
||||
if (hasUnlockedPages()) {
|
||||
compound.setTag("pages", new NBTTagIntArray(pages));
|
||||
}
|
||||
|
||||
IMagicEffect effect = getEffect();
|
||||
|
||||
if (effect != null) {
|
||||
|
@ -236,6 +252,13 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
if (compound.hasKey("effect")) {
|
||||
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
|
||||
}
|
||||
|
||||
if (compound.hasKey("pages")) {
|
||||
pages.clear();
|
||||
for (int i : compound.getIntArray("pages")) {
|
||||
pages.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -274,4 +297,10 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
@Override
|
||||
public void setCurrentLevel(int level) {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<Integer> getUnlockedPages() {
|
||||
return pages;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
|
@ -82,6 +84,21 @@ public class SpellRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
public ItemStack disenchantStack(ItemStack stack) {
|
||||
if (stackHasEnchantment(stack)) {
|
||||
stack.getTagCompound().removeTag("spell");
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public ItemStack enchantStack(ItemStack stack, ItemStack from) {
|
||||
stack.setTagCompound(new NBTTagCompound());
|
||||
stack.getTagCompound().setString("spell", getKeyFromStack(from));
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public ItemStack enchantStack(ItemStack stack, String name) {
|
||||
stack.setTagCompound(new NBTTagCompound());
|
||||
stack.getTagCompound().setString("spell", name);
|
||||
|
@ -89,6 +106,7 @@ public class SpellRegistry {
|
|||
return stack;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String getKeyFromStack(ItemStack stack) {
|
||||
if (stack.isEmpty() || !stack.hasTagCompound() || !stack.getTagCompound().hasKey("spell")) {
|
||||
return "";
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
package com.minelittlepony.unicopia.util.crafting;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.client.resources.IResourceManagerReloadListener;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.ShapedRecipes;
|
||||
import net.minecraft.item.crafting.ShapelessRecipes;
|
||||
import net.minecraft.util.JsonUtils;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class CraftingManager implements IResourceManagerReloadListener {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private final Map<ResourceLocation, IRecipe> REGISTRY = Maps.newHashMap();
|
||||
|
||||
private final Map<String, Function<JsonObject, IRecipe>> JSON_PARSERS = Maps.newHashMap();
|
||||
|
||||
private static final Gson gson = new GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.disableHtmlEscaping()
|
||||
.create();
|
||||
|
||||
@Nonnull
|
||||
private final ResourceLocation crafting_id;
|
||||
|
||||
public CraftingManager(String modid, String resourcename) {
|
||||
this(new ResourceLocation(modid, resourcename + "/recipes"));
|
||||
}
|
||||
|
||||
public CraftingManager(@Nonnull ResourceLocation id) {
|
||||
crafting_id = id;
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
protected void registerRecipeTypes(Map<String, Function<JsonObject, IRecipe>> types) {
|
||||
types.put("crafting_shaped", ShapedRecipes::deserialize);
|
||||
types.put("crafting_shapeless", ShapelessRecipes::deserialize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager resourceManager) {
|
||||
load();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
JSON_PARSERS.clear();
|
||||
REGISTRY.clear();
|
||||
|
||||
registerRecipeTypes(JSON_PARSERS);
|
||||
|
||||
try {
|
||||
String loadLocation = "/assets/" + crafting_id.getNamespace() + "/" + crafting_id.getPath();
|
||||
|
||||
URL url = CraftingManager.class.getResource(loadLocation);
|
||||
|
||||
if (url == null) {
|
||||
LOGGER.error("Couldn't find .mcassetsroot");
|
||||
return;
|
||||
}
|
||||
|
||||
URI uri = url.toURI();
|
||||
|
||||
if ("file".equals(uri.getScheme())) {
|
||||
loadRecipesFrom(Paths.get(CraftingManager.class.getResource(loadLocation).toURI()));
|
||||
} else {
|
||||
if (!"jar".equals(uri.getScheme())) {
|
||||
LOGGER.error("Unsupported scheme " + uri + " trying to list all recipes");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try (FileSystem filesystem = FileSystems.newFileSystem(uri, Collections.emptyMap())) {
|
||||
loadRecipesFrom(filesystem.getPath(loadLocation));
|
||||
}
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
LOGGER.error("Couldn't get a list of all recipe files", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadRecipesFrom(@Nullable Path path) throws IOException {
|
||||
if (path == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<Path> iterator = Files.walk(path).iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Path i = iterator.next();
|
||||
|
||||
if ("json".equals(FilenameUtils.getExtension(i.toString()))) {
|
||||
ResourceLocation id = new ResourceLocation(FilenameUtils.removeExtension(path.relativize(i).toString()).replaceAll("\\\\", "/"));
|
||||
|
||||
try(BufferedReader bufferedreader = Files.newBufferedReader(i)) {
|
||||
REGISTRY.put(id, parseRecipeJson(JsonUtils.fromJson(gson, bufferedreader, JsonObject.class)));
|
||||
} catch (JsonParseException e) {
|
||||
LOGGER.error("Parsing error loading recipe " + id, e);
|
||||
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Couldn't read recipe " + id + " from " + i, e);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected IRecipe parseRecipeJson(JsonObject json) {
|
||||
String s = JsonUtils.getString(json, "type");
|
||||
|
||||
if (!JSON_PARSERS.containsKey(s)) {
|
||||
throw new JsonSyntaxException("Invalid or unsupported recipe type '" + s + "'");
|
||||
}
|
||||
|
||||
return JSON_PARSERS.get(s).apply(json);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public ItemStack findMatchingResult(InventoryCrafting craftMatrix, World worldIn) {
|
||||
IRecipe recipe = findMatchingRecipe(craftMatrix, worldIn);
|
||||
|
||||
if (recipe != null) {
|
||||
return recipe.getCraftingResult(craftMatrix);
|
||||
}
|
||||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IRecipe findMatchingRecipe(InventoryCrafting craftMatrix, World worldIn) {
|
||||
load();
|
||||
|
||||
for (IRecipe irecipe : REGISTRY.values()) {
|
||||
if (irecipe.matches(craftMatrix, worldIn)) {
|
||||
return irecipe;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public NonNullList<ItemStack> getRemainingItems(InventoryCrafting craftMatrix, World worldIn) {
|
||||
IRecipe recipe = findMatchingRecipe(craftMatrix, worldIn);
|
||||
|
||||
if (recipe != null) {
|
||||
return recipe.getRemainingItems(craftMatrix);
|
||||
}
|
||||
|
||||
return cloneInventoryContents(craftMatrix);
|
||||
}
|
||||
|
||||
public static NonNullList<ItemStack> cloneInventoryContents(InventoryCrafting craftMatrix) {
|
||||
NonNullList<ItemStack> result = NonNullList.withSize(craftMatrix.getSizeInventory(), ItemStack.EMPTY);
|
||||
|
||||
for (int i = 0; i < result.size(); ++i) {
|
||||
result.set(i, craftMatrix.getStackInSlot(i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"type": "unicopia:crafting_spell",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:apple",
|
||||
"data": 0
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"spell": "shield"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2 MiB |
Binary file not shown.
After Width: | Height: | Size: 439 B |
Loading…
Add table
Reference in a new issue