mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-24 21:54:33 +01:00
Rewrote the spellbook pages system
This commit is contained in:
parent
fc26e84fa2
commit
8c3ad677b9
27 changed files with 706 additions and 360 deletions
|
@ -47,6 +47,7 @@ import com.minelittlepony.jumpingcastle.api.JumpingCastle;
|
||||||
import com.minelittlepony.unicopia.advancements.UAdvancements;
|
import com.minelittlepony.unicopia.advancements.UAdvancements;
|
||||||
import com.minelittlepony.unicopia.block.ITillable;
|
import com.minelittlepony.unicopia.block.ITillable;
|
||||||
import com.minelittlepony.unicopia.command.Commands;
|
import com.minelittlepony.unicopia.command.Commands;
|
||||||
|
import com.minelittlepony.unicopia.enchanting.Pages;
|
||||||
import com.minelittlepony.unicopia.enchanting.SpellRecipe;
|
import com.minelittlepony.unicopia.enchanting.SpellRecipe;
|
||||||
import com.minelittlepony.unicopia.forgebullshit.FBS;
|
import com.minelittlepony.unicopia.forgebullshit.FBS;
|
||||||
import com.minelittlepony.unicopia.inventory.gui.ContainerSpellBook;
|
import com.minelittlepony.unicopia.inventory.gui.ContainerSpellBook;
|
||||||
|
@ -112,6 +113,8 @@ public class Unicopia implements IGuiHandler {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Pages.instance().load();
|
||||||
|
|
||||||
Biome.REGISTRY.forEach(UEntities::registerSpawnEntries);
|
Biome.REGISTRY.forEach(UEntities::registerSpawnEntries);
|
||||||
UClient.instance().posInit(event);
|
UClient.instance().posInit(event);
|
||||||
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
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,56 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
public class CompoundCondition implements IUnlockCondition<IUnlockEvent> {
|
||||||
|
|
||||||
|
final Op operation;
|
||||||
|
|
||||||
|
final List<IUnlockCondition<IUnlockEvent>> conditions = Lists.newArrayList();
|
||||||
|
|
||||||
|
CompoundCondition(JsonObject json) {
|
||||||
|
require(json, "operation");
|
||||||
|
require(json, "conditions");
|
||||||
|
|
||||||
|
operation = Op.valueOf(json.get("operation").getAsString().toUpperCase());
|
||||||
|
|
||||||
|
json.get("conditions").getAsJsonArray().forEach(this::addElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addElement(JsonElement element) {
|
||||||
|
JsonObject obj = element.getAsJsonObject();
|
||||||
|
|
||||||
|
conditions.add(Pages.instance().createCondition(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accepts(IUnlockEvent event) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(IPageOwner owner, IUnlockEvent event) {
|
||||||
|
return operation.test.apply(conditions.stream(), condition -> condition.accepts(event) && condition.matches(owner, event));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Op {
|
||||||
|
AND(Stream::allMatch),
|
||||||
|
OR(Stream::anyMatch);
|
||||||
|
|
||||||
|
final Test test;
|
||||||
|
|
||||||
|
Op(Test test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Test {
|
||||||
|
boolean apply(Stream<IUnlockCondition<IUnlockEvent>> stream, Predicate<IUnlockCondition<IUnlockEvent>> predicate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface IConditionFactory {
|
||||||
|
IUnlockCondition<?> create(JsonObject json);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A spellbook page
|
||||||
|
*/
|
||||||
|
public interface IPage extends Comparable<IPage> {
|
||||||
|
/**
|
||||||
|
* Gets the index.
|
||||||
|
* This is the position the page appears in the book gui.
|
||||||
|
*/
|
||||||
|
int getIndex();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique name of this page.
|
||||||
|
*/
|
||||||
|
ResourceLocation getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests unlock conditions for this page.
|
||||||
|
* Returns true if the owner is permitted to read this page.
|
||||||
|
*/
|
||||||
|
boolean canUnlock(IPageOwner owner, IUnlockEvent event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the texture.
|
||||||
|
* This is what's shown when this page is opened in the book gui.
|
||||||
|
*/
|
||||||
|
ResourceLocation getTexture();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default state.
|
||||||
|
*/
|
||||||
|
PageState getDefaultState();
|
||||||
|
|
||||||
|
IPage next();
|
||||||
|
|
||||||
|
IPage prev();
|
||||||
|
}
|
|
@ -1,32 +1,32 @@
|
||||||
package com.minelittlepony.unicopia.enchanting;
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.network.ITransmittable;
|
import com.minelittlepony.unicopia.network.ITransmittable;
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for things that own and can unlock pages.
|
||||||
|
*
|
||||||
|
*/
|
||||||
public interface IPageOwner extends ITransmittable {
|
public interface IPageOwner extends ITransmittable {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
List<Integer> getUnlockedPages();
|
Map<ResourceLocation, PageState> getPageStates();
|
||||||
|
|
||||||
default boolean hasPageUnlock(int pageIndex) {
|
default void setPageState(IPage page, PageState state) {
|
||||||
return getUnlockedPages().contains(pageIndex);
|
if (state == PageState.LOCKED) {
|
||||||
}
|
getPageStates().remove(page.getName());
|
||||||
|
} else {
|
||||||
default boolean unlockPage(int pageIndex) {
|
getPageStates().put(page.getName(), state);
|
||||||
if (!hasPageUnlock(pageIndex)) {
|
|
||||||
if (getUnlockedPages().add(pageIndex)) {
|
|
||||||
sendCapabilities(true);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
sendCapabilities(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean hasUnlockedPages() {
|
default PageState getPageState(IPage page) {
|
||||||
return getUnlockedPages().size() > 0;
|
return getPageStates().getOrDefault(page.getName(), page.getDefaultState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
package com.minelittlepony.unicopia.enchanting;
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
public interface IPageUnlockListener {
|
public interface IPageUnlockListener {
|
||||||
public void onPageUnlocked();
|
/**
|
||||||
|
* Called when a page is unlocked.
|
||||||
|
*
|
||||||
|
* @param page The page that has been unlocked
|
||||||
|
* @return True to allow, false to block.
|
||||||
|
*/
|
||||||
|
boolean onPageUnlocked(IPage page);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A PageEvent for determining when certain pages must be unlocked.
|
||||||
|
*/
|
||||||
|
public interface IUnlockCondition<T extends IUnlockEvent> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if event instanceof T
|
||||||
|
*/
|
||||||
|
default boolean accepts(IUnlockEvent event) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this event's conditions are met.
|
||||||
|
* @param prop PlayerExtension for the player doing the crafting
|
||||||
|
* @param stack ItemStack crafted
|
||||||
|
*/
|
||||||
|
boolean matches(IPageOwner owner, T event);
|
||||||
|
|
||||||
|
default void require(JsonObject json, String memberName) {
|
||||||
|
if (!json.has(memberName)) {
|
||||||
|
throw new JsonParseException(String.format("%s condition must have a %s", getClass().getSimpleName(), memberName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
public interface IUnlockEvent {
|
||||||
|
|
||||||
|
}
|
|
@ -1,41 +0,0 @@
|
||||||
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,100 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
class PageInstance implements IPage {
|
||||||
|
|
||||||
|
int index;
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
ResourceLocation name;
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
ResourceLocation texture;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
IUnlockCondition<IUnlockEvent> condition;
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
PageState state = PageState.LOCKED;
|
||||||
|
|
||||||
|
PageInstance(ResourceLocation id, JsonObject json) {
|
||||||
|
this.name = id;
|
||||||
|
|
||||||
|
if (json.has("state")) {
|
||||||
|
state = PageState.of(json.get("state").getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json.has("condition")) {
|
||||||
|
condition = Pages.instance().createCondition(json.get("condition").getAsJsonObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
String full = json.get("texture").getAsString();
|
||||||
|
String[] loc = full.split(":");
|
||||||
|
if (loc.length < 2) {
|
||||||
|
loc = new String[] { "minecraft", full };
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("minecraft".equals(loc[0]) && !"minecraft".equals(id.getNamespace())) {
|
||||||
|
loc[0] = id.getNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
texture = new ResourceLocation(loc[0], String.format("textures/pages/%s.png", loc[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getTexture() {
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageState getDefaultState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUnlock(IPageOwner owner, IUnlockEvent event) {
|
||||||
|
return condition == null || condition.accepts(event) && condition.matches(owner, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage next() {
|
||||||
|
int i = Math.min(Pages.instance().getTotalPages() - 1, index + 1);
|
||||||
|
return Pages.instance().getByIndex(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage prev() {
|
||||||
|
if (index <= 0) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pages.instance().getByIndex(index - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(IPage o) {
|
||||||
|
return getIndex() - o.getIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o instanceof IPage && getName().equals(((IPage)o).getName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
public enum PageState {
|
||||||
|
LOCKED,
|
||||||
|
UNREAD,
|
||||||
|
READ;
|
||||||
|
|
||||||
|
public boolean isLocked() {
|
||||||
|
return this == LOCKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUnread() {
|
||||||
|
return this == UNREAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PageState of(String s) {
|
||||||
|
try {
|
||||||
|
if (s != null)
|
||||||
|
return valueOf(s.toUpperCase());
|
||||||
|
} catch (Throwable e) {}
|
||||||
|
|
||||||
|
return PageState.LOCKED;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
public class PageStateCondition implements IUnlockCondition<IUnlockEvent> {
|
||||||
|
|
||||||
|
ResourceLocation page;
|
||||||
|
|
||||||
|
PageState state;
|
||||||
|
|
||||||
|
PageStateCondition(JsonObject json) {
|
||||||
|
require(json, "page");
|
||||||
|
require(json, "state");
|
||||||
|
|
||||||
|
page = new ResourceLocation(json.get("page").getAsString());
|
||||||
|
state = PageState.of(json.get("state").getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(IPageOwner owner, IUnlockEvent event) {
|
||||||
|
IPage ipage = Pages.instance().getByName(page);
|
||||||
|
|
||||||
|
if (ipage != null) {
|
||||||
|
return owner.getPageState(ipage) == state;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.minelittlepony.util.AssetWalker;
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
public class Pages {
|
||||||
|
|
||||||
|
private static final Pages instance = new Pages();
|
||||||
|
|
||||||
|
public static Pages instance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<ResourceLocation, IPage> pages = Maps.newHashMap();
|
||||||
|
private final List<IPage> pagesByIndex = Lists.newArrayList();
|
||||||
|
|
||||||
|
private final Map<String, IConditionFactory> conditionFactories = Maps.newHashMap();
|
||||||
|
|
||||||
|
private final AssetWalker assets = new AssetWalker(new ResourceLocation("unicopia", "pages"), this::addPage);
|
||||||
|
|
||||||
|
Pages() {
|
||||||
|
registerConditionFactory("unicopia:compound_condition", CompoundCondition::new);
|
||||||
|
registerConditionFactory("unicopia:page_state", PageStateCondition::new);
|
||||||
|
registerConditionFactory("unicopia:spell_crafting", SpellCraftingEvent.Condition::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() {
|
||||||
|
pages.clear();
|
||||||
|
pagesByIndex.clear();
|
||||||
|
assets.walk();
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (IPage ipage : pages.values()) {
|
||||||
|
((PageInstance)ipage).index = index++;
|
||||||
|
pagesByIndex.add(ipage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPage(ResourceLocation id, JsonObject json) throws JsonParseException {
|
||||||
|
pages.put(id, new PageInstance(id, json));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
<T extends IUnlockEvent> IUnlockCondition<T> createCondition(JsonObject json) {
|
||||||
|
String key = json.get("key").getAsString();
|
||||||
|
|
||||||
|
return (IUnlockCondition<T>)conditionFactories.get(key).create(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public IPage getByName(ResourceLocation name) {
|
||||||
|
return pages.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public IPage getByIndex(int index) {
|
||||||
|
return pagesByIndex.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream<IPage> getUnlockablePages(Predicate<IPage> predicate) {
|
||||||
|
return pages.values().stream().filter(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void triggerUnlockEvent(IPageOwner owner, IUnlockEvent event, @Nullable IPageUnlockListener unlockListener) {
|
||||||
|
pages.values().stream()
|
||||||
|
.filter(page -> page.canUnlock(owner, event))
|
||||||
|
.forEach(page -> unlockPage(owner, page, unlockListener));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unlockPage(IPageOwner owner, IPage page, @Nullable IPageUnlockListener unlockListener) {
|
||||||
|
if (owner.getPageState(page).isLocked()) {
|
||||||
|
if (unlockListener == null || unlockListener.onPageUnlocked(page)) {
|
||||||
|
owner.setPageState(page, PageState.UNREAD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerConditionFactory(String conditionType, IConditionFactory factory) {
|
||||||
|
conditionFactories.put(conditionType, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalPages() {
|
||||||
|
return pages.size();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,117 +0,0 @@
|
||||||
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,61 @@
|
||||||
|
package com.minelittlepony.unicopia.enchanting;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.minelittlepony.unicopia.item.ItemSpell;
|
||||||
|
import com.minelittlepony.unicopia.spell.SpellAffinity;
|
||||||
|
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 SpellCraftingEvent {
|
||||||
|
|
||||||
|
public static void trigger(IPageOwner owner, ItemStack stack, @Nullable IPageUnlockListener unlockListener) {
|
||||||
|
Pages.instance().triggerUnlockEvent(owner, new Event(stack), unlockListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Event implements IUnlockEvent {
|
||||||
|
final ItemStack stack;
|
||||||
|
|
||||||
|
Event(ItemStack stack) {
|
||||||
|
this.stack = stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Condition implements IUnlockCondition<Event> {
|
||||||
|
@Nonnull
|
||||||
|
SpellAffinity affinity;
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
String spell;
|
||||||
|
|
||||||
|
Condition(JsonObject json) {
|
||||||
|
require(json, "affinity");
|
||||||
|
require(json, "spell");
|
||||||
|
|
||||||
|
affinity = SpellAffinity.of(json.get("affinity").getAsString());
|
||||||
|
spell = json.get("spell").getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accepts(IUnlockEvent event) {
|
||||||
|
return event instanceof Event;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(IPageOwner prop, Event event) {
|
||||||
|
if (!event.stack.isEmpty() && event.stack.getItem() instanceof ItemSpell) {
|
||||||
|
return ((ItemSpell)event.stack.getItem()).getAffinity() == affinity
|
||||||
|
&& SpellRegistry.getKeyFromStack(event.stack).equals(spell);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -114,7 +114,7 @@ public class EntitySpellbook extends EntityLiving implements IMagicals {
|
||||||
SoundType sound = SoundType.WOOD;
|
SoundType sound = SoundType.WOOD;
|
||||||
world.playSound(posX, posY, posZ, sound.getBreakSound(), SoundCategory.BLOCKS, sound.getVolume(), sound.getPitch(), true);
|
world.playSound(posX, posY, posZ, sound.getBreakSound(), SoundCategory.BLOCKS, sound.getVolume(), sound.getPitch(), true);
|
||||||
if (world.getGameRules().getBoolean("doTileDrops")) {
|
if (world.getGameRules().getBoolean("doTileDrops")) {
|
||||||
entityDropItem(new ItemStack(UItems.spellbook, 1), 0);
|
entityDropItem(new ItemStack(UItems.spellbook), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.inventory.InventorySpellBook;
|
||||||
import com.minelittlepony.unicopia.inventory.slot.SlotEnchanting;
|
import com.minelittlepony.unicopia.inventory.slot.SlotEnchanting;
|
||||||
import com.minelittlepony.unicopia.inventory.slot.SlotEnchantingResult;
|
import com.minelittlepony.unicopia.inventory.slot.SlotEnchantingResult;
|
||||||
import com.minelittlepony.unicopia.item.ItemSpell;
|
import com.minelittlepony.unicopia.item.ItemSpell;
|
||||||
|
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||||
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
@ -64,7 +65,7 @@ public class ContainerSpellBook extends Container {
|
||||||
addSlotToContainer(new SlotEnchanting(craftMatrix, 2, 180, 134));
|
addSlotToContainer(new SlotEnchanting(craftMatrix, 2, 180, 134));
|
||||||
addSlotToContainer(new SlotEnchanting(craftMatrix, 3, 231, 120));
|
addSlotToContainer(new SlotEnchanting(craftMatrix, 3, 231, 120));
|
||||||
addSlotToContainer(new SlotEnchanting(craftMatrix, 4, 232, 65));
|
addSlotToContainer(new SlotEnchanting(craftMatrix, 4, 232, 65));
|
||||||
addSlotToContainer(resultSlot = new SlotEnchantingResult(listener, player, craftMatrix, craftResult, 0, 196, 92));
|
addSlotToContainer(resultSlot = new SlotEnchantingResult(listener, PlayerSpeciesList.instance().getPlayer(player), craftMatrix, craftResult, 0, 196, 92));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,8 +4,11 @@ import java.io.IOException;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
|
import com.minelittlepony.unicopia.enchanting.IPage;
|
||||||
import com.minelittlepony.unicopia.enchanting.IPageUnlockListener;
|
import com.minelittlepony.unicopia.enchanting.IPageUnlockListener;
|
||||||
import com.minelittlepony.unicopia.enchanting.PagesList;
|
import com.minelittlepony.unicopia.enchanting.PageState;
|
||||||
|
import com.minelittlepony.unicopia.enchanting.Pages;
|
||||||
import com.minelittlepony.unicopia.inventory.slot.SlotEnchanting;
|
import com.minelittlepony.unicopia.inventory.slot.SlotEnchanting;
|
||||||
import com.minelittlepony.unicopia.player.IPlayer;
|
import com.minelittlepony.unicopia.player.IPlayer;
|
||||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||||
|
@ -21,20 +24,21 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
public class GuiSpellBook extends GuiContainer implements IPageUnlockListener {
|
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 IPage currentIPage;
|
||||||
|
|
||||||
private static final ResourceLocation spellBookGuiTextures = new ResourceLocation("unicopia", "textures/gui/container/book.png");
|
private static final ResourceLocation spellBookGuiTextures = new ResourceLocation("unicopia", "textures/gui/container/book.png");
|
||||||
|
|
||||||
private IPlayer playerExtension;
|
private IPlayer playerExtension;
|
||||||
|
|
||||||
|
|
||||||
private PageButton nextPage;
|
private PageButton nextPage;
|
||||||
private PageButton prevPage;
|
private PageButton prevPage;
|
||||||
|
|
||||||
public GuiSpellBook(EntityPlayer player) {
|
public GuiSpellBook(EntityPlayer player) {
|
||||||
super(new ContainerSpellBook(player.inventory, player.world, new BlockPos(player)));
|
super(new ContainerSpellBook(player.inventory, player.world, new BlockPos(player)));
|
||||||
player.openContainer = inventorySlots;
|
player.openContainer = inventorySlots;
|
||||||
((ContainerSpellBook)inventorySlots).setListener(this);
|
|
||||||
xSize = 405;
|
xSize = 405;
|
||||||
ySize = 219;
|
ySize = 219;
|
||||||
allowUserInput = true;
|
allowUserInput = true;
|
||||||
|
@ -51,6 +55,12 @@ public class GuiSpellBook extends GuiContainer implements IPageUnlockListener {
|
||||||
|
|
||||||
buttonList.add(nextPage = new PageButton(1, x + 360, y + 160, true));
|
buttonList.add(nextPage = new PageButton(1, x + 360, y + 160, true));
|
||||||
buttonList.add(prevPage = new PageButton(2, x + 20, y + 160, false));
|
buttonList.add(prevPage = new PageButton(2, x + 20, y + 160, false));
|
||||||
|
|
||||||
|
if (currentIPage == null) {
|
||||||
|
currentIPage = Pages.instance().getByIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPageChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,45 +68,37 @@ public class GuiSpellBook extends GuiContainer implements IPageUnlockListener {
|
||||||
initGui();
|
initGui();
|
||||||
|
|
||||||
if (button.id == 1) {
|
if (button.id == 1) {
|
||||||
nextPage();
|
currentIPage = currentIPage.next();
|
||||||
} else {
|
} else {
|
||||||
prevPage();
|
currentIPage = currentIPage.prev();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onPageChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void nextPage() {
|
protected void onPageChange() {
|
||||||
if (currentPage == 0) {
|
prevPage.visible = currentIPage.getIndex() > 0;
|
||||||
playerExtension.unlockPage(1);
|
nextPage.visible = currentIPage.getIndex() < Pages.instance().getTotalPages() - 1;
|
||||||
}
|
|
||||||
if (currentPage < PagesList.getTotalPages() - 1) {
|
|
||||||
currentPage++;
|
|
||||||
spellBookPageTextures = new ResourceLocation("unicopia", "textures/gui/container/pages/page-" + currentPage + ".png");
|
|
||||||
|
|
||||||
onPageUnlocked();
|
if (playerExtension.getPageState(currentIPage) == PageState.UNREAD) {
|
||||||
PagesList.readPage(currentPage);
|
playerExtension.setPageState(currentIPage, PageState.READ);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageUnlocked() {
|
|
||||||
if (PagesList.hasUnreadPagesAfter(currentPage)) {
|
|
||||||
nextPage.triggerShake();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PagesList.hasUnreadPagesBefore(currentPage)) {
|
|
||||||
prevPage.triggerShake();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prevPage() {
|
@Override
|
||||||
if (currentPage > 0) {
|
public boolean onPageUnlocked(IPage page) {
|
||||||
currentPage--;
|
int i = currentIPage.compareTo(page);
|
||||||
spellBookPageTextures = new ResourceLocation("unicopia", "textures/gui/container/pages/page-" + currentPage + ".png");
|
|
||||||
|
|
||||||
onPageUnlocked();
|
if (i <= 0) {
|
||||||
PagesList.readPage(currentPage);
|
prevPage.triggerShake();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (i >= 0) {
|
||||||
|
nextPage.triggerShake();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void drawGradientRect(int left, int top, int width, int height, int startColor, int endColor) {
|
protected void drawGradientRect(int left, int top, int width, int height, int startColor, int endColor) {
|
||||||
|
@ -128,10 +130,9 @@ public class GuiSpellBook extends GuiContainer implements IPageUnlockListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
|
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
|
||||||
if (PagesList.getTotalPages() > 0) {
|
String text = String.format("%d / %d", currentIPage.getIndex() + 1, Pages.instance().getTotalPages());
|
||||||
String text = (currentPage + 1) + "/" + PagesList.getTotalPages();
|
|
||||||
fontRenderer.drawString(text, 203 - fontRenderer.getStringWidth(text)/2, 165, 0x0);
|
fontRenderer.drawString(text, 203 - fontRenderer.getStringWidth(text)/2, 165, 0x0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -147,12 +148,18 @@ public class GuiSpellBook extends GuiContainer implements IPageUnlockListener {
|
||||||
GlStateManager.enableBlend();
|
GlStateManager.enableBlend();
|
||||||
GL11.glDisable(GL11.GL_ALPHA_TEST);
|
GL11.glDisable(GL11.GL_ALPHA_TEST);
|
||||||
|
|
||||||
if (playerExtension.hasPageUnlock(currentPage)) {
|
if (playerExtension.getPageState(currentIPage) != PageState.LOCKED) {
|
||||||
if (mc.getTextureManager().getTexture(spellBookPageTextures) != TextureUtil.MISSING_TEXTURE) {
|
ResourceLocation texture = currentIPage.getTexture();
|
||||||
|
|
||||||
|
if (mc.getTextureManager().getTexture(texture) != TextureUtil.MISSING_TEXTURE) {
|
||||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
mc.getTextureManager().bindTexture(spellBookPageTextures);
|
mc.getTextureManager().bindTexture(texture);
|
||||||
drawModalRectWithCustomSizedTexture(left, top, 0, 0, xSize, ySize, 512, 256);
|
drawModalRectWithCustomSizedTexture(left, top, 0, 0, xSize, ySize, 512, 256);
|
||||||
|
} else {
|
||||||
|
if (playerExtension.getWorld().rand.nextInt(100) == 0) {
|
||||||
|
Unicopia.log.fatal("Missing texture " + texture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package com.minelittlepony.unicopia.inventory.slot;
|
package com.minelittlepony.unicopia.inventory.slot;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
|
import com.minelittlepony.unicopia.enchanting.IPageOwner;
|
||||||
import com.minelittlepony.unicopia.enchanting.IPageUnlockListener;
|
import com.minelittlepony.unicopia.enchanting.IPageUnlockListener;
|
||||||
import com.minelittlepony.unicopia.enchanting.PagesList;
|
import com.minelittlepony.unicopia.enchanting.SpellCraftingEvent;
|
||||||
import com.minelittlepony.unicopia.inventory.InventorySpellBook;
|
import com.minelittlepony.unicopia.inventory.InventorySpellBook;
|
||||||
import com.minelittlepony.unicopia.item.ItemSpell;
|
import com.minelittlepony.unicopia.item.ItemSpell;
|
||||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||||
|
@ -14,14 +15,14 @@ import net.minecraft.util.NonNullList;
|
||||||
|
|
||||||
public class SlotEnchantingResult extends SlotEnchanting {
|
public class SlotEnchantingResult extends SlotEnchanting {
|
||||||
|
|
||||||
private final EntityPlayer thePlayer;
|
private final IPageOwner owner;
|
||||||
private final InventorySpellBook craftMatrix;
|
private final InventorySpellBook craftMatrix;
|
||||||
|
|
||||||
private IPageUnlockListener listener;
|
private IPageUnlockListener listener;
|
||||||
|
|
||||||
public SlotEnchantingResult(IPageUnlockListener listener, EntityPlayer player, InventorySpellBook craftMatric, IInventory inventory, int index, int xPosition, int yPosition) {
|
public SlotEnchantingResult(IPageUnlockListener listener, IPageOwner owner, InventorySpellBook craftMatric, IInventory inventory, int index, int xPosition, int yPosition) {
|
||||||
super(inventory, index, xPosition, yPosition);
|
super(inventory, index, xPosition, yPosition);
|
||||||
thePlayer = player;
|
this.owner = owner;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
craftMatrix = craftMatric;
|
craftMatrix = craftMatric;
|
||||||
}
|
}
|
||||||
|
@ -75,13 +76,7 @@ public class SlotEnchantingResult extends SlotEnchanting {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCrafting(ItemStack stack) {
|
protected void onCrafting(ItemStack stack) {
|
||||||
if (PagesList.unlockPage(thePlayer, stack) && listener != null) {
|
SpellCraftingEvent.trigger(owner, stack, listener);
|
||||||
listener.onPageUnlocked();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listener != null) {
|
|
||||||
listener.onPageUnlocked();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -56,7 +56,6 @@ public class ItemSpellbook extends ItemBook {
|
||||||
BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(this, dispenserBehavior);
|
BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(this, dispenserBehavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) {
|
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) {
|
||||||
|
|
||||||
if (!world.isRemote && Predicates.MAGI.test(player)) {
|
if (!world.isRemote && Predicates.MAGI.test(player)) {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package com.minelittlepony.unicopia.player;
|
package com.minelittlepony.unicopia.player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Maps;
|
||||||
import com.minelittlepony.model.anim.BasicEasingInterpolator;
|
import com.minelittlepony.model.anim.BasicEasingInterpolator;
|
||||||
import com.minelittlepony.model.anim.IInterpolator;
|
import com.minelittlepony.model.anim.IInterpolator;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.UEffects;
|
import com.minelittlepony.unicopia.UEffects;
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
|
import com.minelittlepony.unicopia.enchanting.PageState;
|
||||||
import com.minelittlepony.unicopia.network.EffectSync;
|
import com.minelittlepony.unicopia.network.EffectSync;
|
||||||
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
|
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
|
||||||
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
||||||
|
@ -24,13 +24,13 @@ import net.minecraft.init.MobEffects;
|
||||||
import net.minecraft.item.ItemFood;
|
import net.minecraft.item.ItemFood;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagIntArray;
|
|
||||||
import net.minecraft.network.datasync.DataParameter;
|
import net.minecraft.network.datasync.DataParameter;
|
||||||
import net.minecraft.network.datasync.DataSerializers;
|
import net.minecraft.network.datasync.DataSerializers;
|
||||||
import net.minecraft.network.datasync.EntityDataManager;
|
import net.minecraft.network.datasync.EntityDataManager;
|
||||||
import net.minecraft.network.play.server.SPacketSetPassengers;
|
import net.minecraft.network.play.server.SPacketSetPassengers;
|
||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
import net.minecraft.stats.StatList;
|
import net.minecraft.stats.StatList;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.EnumDifficulty;
|
import net.minecraft.world.EnumDifficulty;
|
||||||
|
|
||||||
class PlayerCapabilities implements IPlayer {
|
class PlayerCapabilities implements IPlayer {
|
||||||
|
@ -47,7 +47,7 @@ class PlayerCapabilities implements IPlayer {
|
||||||
private static final DataParameter<NBTTagCompound> EFFECT = EntityDataManager
|
private static final DataParameter<NBTTagCompound> EFFECT = EntityDataManager
|
||||||
.createKey(EntityPlayer.class, DataSerializers.COMPOUND_TAG);
|
.createKey(EntityPlayer.class, DataSerializers.COMPOUND_TAG);
|
||||||
|
|
||||||
private final List<Integer> pages = Lists.newArrayList();
|
private final Map<ResourceLocation, PageState> pageStates = Maps.newHashMap();
|
||||||
|
|
||||||
private final PlayerAbilityDelegate powers = new PlayerAbilityDelegate(this);
|
private final PlayerAbilityDelegate powers = new PlayerAbilityDelegate(this);
|
||||||
|
|
||||||
|
@ -289,15 +289,27 @@ class PlayerCapabilities implements IPlayer {
|
||||||
compound.setTag("powers", powers.toNBT());
|
compound.setTag("powers", powers.toNBT());
|
||||||
compound.setTag("gravity", gravity.toNBT());
|
compound.setTag("gravity", gravity.toNBT());
|
||||||
|
|
||||||
if (hasUnlockedPages()) {
|
|
||||||
compound.setTag("pages", new NBTTagIntArray(pages));
|
|
||||||
}
|
|
||||||
|
|
||||||
IMagicEffect effect = getEffect();
|
IMagicEffect effect = getEffect();
|
||||||
|
|
||||||
if (effect != null) {
|
if (effect != null) {
|
||||||
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(effect));
|
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(effect));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pageStates.isEmpty()) {
|
||||||
|
NBTTagCompound pages = new NBTTagCompound();
|
||||||
|
boolean written = false;
|
||||||
|
|
||||||
|
for (Map.Entry<ResourceLocation, PageState> entry : pageStates.entrySet()) {
|
||||||
|
if (entry.getValue() != PageState.LOCKED) {
|
||||||
|
pages.setString(entry.getKey().toString(), entry.getValue().name());
|
||||||
|
written = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (written) {
|
||||||
|
compound.setTag("pageStates", pages);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -311,17 +323,22 @@ class PlayerCapabilities implements IPlayer {
|
||||||
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
|
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compound.hasKey("pages")) {
|
pageStates.clear();
|
||||||
pages.clear();
|
if (compound.hasKey("pageStates")) {
|
||||||
for (int i : compound.getIntArray("pages")) {
|
NBTTagCompound pages = compound.getCompoundTag("pageStates");
|
||||||
pages.add(i);
|
|
||||||
|
for (String key : pages.getKeySet()) {
|
||||||
|
PageState state = PageState.of(pages.getString(key));
|
||||||
|
|
||||||
|
if (state != PageState.LOCKED) {
|
||||||
|
pageStates.put(new ResourceLocation(key), state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void copyFrom(IPlayer oldPlayer) {
|
public void copyFrom(IPlayer oldPlayer) {
|
||||||
pages.addAll(oldPlayer.getUnlockedPages());
|
|
||||||
setEffect(oldPlayer.getEffect());
|
setEffect(oldPlayer.getEffect());
|
||||||
setPlayerSpecies(oldPlayer.getPlayerSpecies());
|
setPlayerSpecies(oldPlayer.getPlayerSpecies());
|
||||||
}
|
}
|
||||||
|
@ -363,8 +380,8 @@ class PlayerCapabilities implements IPlayer {
|
||||||
public void setCurrentLevel(int level) {
|
public void setCurrentLevel(int level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Override
|
||||||
public List<Integer> getUnlockedPages() {
|
public Map<ResourceLocation, PageState> getPageStates() {
|
||||||
return pages;
|
return pageStates;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,4 +47,13 @@ public enum SpellAffinity {
|
||||||
|
|
||||||
return implications;
|
return implications;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SpellAffinity of(String s) {
|
||||||
|
try {
|
||||||
|
if (s != null)
|
||||||
|
return valueOf(s.toUpperCase());
|
||||||
|
} catch (Throwable e) {}
|
||||||
|
|
||||||
|
return SpellAffinity.NEUTRAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,16 @@
|
||||||
package com.minelittlepony.unicopia.util.crafting;
|
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.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
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.common.collect.Maps;
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
import com.minelittlepony.util.AssetWalker;
|
||||||
|
|
||||||
import net.minecraft.inventory.InventoryCrafting;
|
import net.minecraft.inventory.InventoryCrafting;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
@ -41,30 +24,30 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
public class CraftingManager {
|
public class CraftingManager {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
|
||||||
|
|
||||||
private final Map<ResourceLocation, IRecipe> REGISTRY = Maps.newHashMap();
|
private final Map<ResourceLocation, IRecipe> REGISTRY = Maps.newHashMap();
|
||||||
|
|
||||||
private final Map<String, Function<JsonObject, IRecipe>> JSON_PARSERS = Maps.newHashMap();
|
private final Map<String, Function<JsonObject, IRecipe>> JSON_PARSERS = Maps.newHashMap();
|
||||||
|
|
||||||
private static final Gson gson = new GsonBuilder()
|
|
||||||
.setPrettyPrinting()
|
|
||||||
.disableHtmlEscaping()
|
|
||||||
.create();
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final ResourceLocation crafting_id;
|
private final ResourceLocation crafting_id;
|
||||||
|
|
||||||
|
private final AssetWalker assets;
|
||||||
|
|
||||||
public CraftingManager(String modid, String resourcename) {
|
public CraftingManager(String modid, String resourcename) {
|
||||||
this(new ResourceLocation(modid, resourcename + "/recipes"));
|
this(new ResourceLocation(modid, resourcename + "/recipes"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CraftingManager(@Nonnull ResourceLocation id) {
|
public CraftingManager(@Nonnull ResourceLocation id) {
|
||||||
crafting_id = id;
|
crafting_id = id;
|
||||||
|
assets = new AssetWalker(id, this::handleJson);
|
||||||
|
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void handleJson(ResourceLocation id, JsonObject json) throws JsonParseException {
|
||||||
|
REGISTRY.put(id, parseRecipeJson(json));
|
||||||
|
}
|
||||||
|
|
||||||
protected void registerRecipeTypes(Map<String, Function<JsonObject, IRecipe>> types) {
|
protected void registerRecipeTypes(Map<String, Function<JsonObject, IRecipe>> types) {
|
||||||
types.put("crafting_shaped", ShapedRecipes::deserialize);
|
types.put("crafting_shaped", ShapedRecipes::deserialize);
|
||||||
types.put("crafting_shapeless", ShapelessRecipes::deserialize);
|
types.put("crafting_shapeless", ShapelessRecipes::deserialize);
|
||||||
|
@ -76,62 +59,7 @@ public class CraftingManager {
|
||||||
|
|
||||||
registerRecipeTypes(JSON_PARSERS);
|
registerRecipeTypes(JSON_PARSERS);
|
||||||
|
|
||||||
try {
|
assets.walk();
|
||||||
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) {
|
protected IRecipe parseRecipeJson(JsonObject json) {
|
||||||
|
|
110
src/main/java/com/minelittlepony/util/AssetWalker.java
Normal file
110
src/main/java/com/minelittlepony/util/AssetWalker.java
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
package com.minelittlepony.util;
|
||||||
|
|
||||||
|
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 javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.minelittlepony.unicopia.util.crafting.CraftingManager;
|
||||||
|
|
||||||
|
import net.minecraft.util.JsonUtils;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
public class AssetWalker {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
|
private static final Gson GSON = new GsonBuilder()
|
||||||
|
.setPrettyPrinting()
|
||||||
|
.disableHtmlEscaping()
|
||||||
|
.create();
|
||||||
|
|
||||||
|
private final String loadLocation;
|
||||||
|
|
||||||
|
private final JsonConsumer consumer;
|
||||||
|
|
||||||
|
public AssetWalker(ResourceLocation assetLocation, JsonConsumer consumer) {
|
||||||
|
this.consumer = consumer;
|
||||||
|
|
||||||
|
loadLocation = "/assets/" + assetLocation.getNamespace() + "/" + assetLocation.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void walk() {
|
||||||
|
try {
|
||||||
|
URL url = AssetWalker.class.getResource(loadLocation);
|
||||||
|
|
||||||
|
if (url == null) {
|
||||||
|
LOGGER.error("Couldn't find .mcassetsroot");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
URI uri = url.toURI();
|
||||||
|
|
||||||
|
if ("file".equals(uri.getScheme())) {
|
||||||
|
readFiles(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())) {
|
||||||
|
readFiles(filesystem.getPath(loadLocation));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
LOGGER.error("Couldn't get a list of all json files", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFiles(@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)) {
|
||||||
|
consumer.accept(id, 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface JsonConsumer {
|
||||||
|
void accept(ResourceLocation id, JsonObject json) throws JsonParseException;
|
||||||
|
}
|
||||||
|
}
|
8
src/main/resources/assets/unicopia/pages/preface.json
Normal file
8
src/main/resources/assets/unicopia/pages/preface.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"texture": "unicopia:preface",
|
||||||
|
"state": "unread",
|
||||||
|
"conditions": {
|
||||||
|
"type": "unicopia:compound_condition",
|
||||||
|
"conditions": []
|
||||||
|
}
|
||||||
|
}
|
BIN
src/main/resources/assets/unicopia/textures/pages/preface.png
Normal file
BIN
src/main/resources/assets/unicopia/textures/pages/preface.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Loading…
Reference in a new issue