Add lecterns

This commit is contained in:
Electroblob77
2020-04-08 00:16:12 +01:00
parent 938d0df95c
commit c5b5172481
79 changed files with 1534 additions and 211 deletions
@@ -17,6 +17,7 @@ import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
import electroblob.wizardry.util.ISpellSortable;
import electroblob.wizardry.util.WandHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
@@ -115,9 +116,9 @@ public class GuiArcaneWorkbench extends GuiContainer {
this.buttonList.clear();
this.buttonList.add(this.applyBtn = new GuiButtonApply(0, this.width / 2 + 64, this.height / 2 + 3));
this.buttonList.add(new GuiButtonSort(1, this.guiLeft - 44, this.guiTop + 8, ContainerArcaneWorkbench.SortType.TIER));
this.buttonList.add(new GuiButtonSort(2, this.guiLeft - 31, this.guiTop + 8, ContainerArcaneWorkbench.SortType.ELEMENT));
this.buttonList.add(new GuiButtonSort(3, this.guiLeft - 18, this.guiTop + 8, ContainerArcaneWorkbench.SortType.ALPHABETICAL));
this.buttonList.add(new GuiButtonSpellSort(1, this.guiLeft - 44, this.guiTop + 8, ISpellSortable.SortType.TIER, arcaneWorkbenchContainer, this));
this.buttonList.add(new GuiButtonSpellSort(2, this.guiLeft - 31, this.guiTop + 8, ISpellSortable.SortType.ELEMENT, arcaneWorkbenchContainer, this));
this.buttonList.add(new GuiButtonSpellSort(3, this.guiLeft - 18, this.guiTop + 8, ISpellSortable.SortType.ALPHABETICAL, arcaneWorkbenchContainer, this));
this.searchField = new GuiTextField(0, this.fontRenderer, this.guiLeft - 113, this.guiTop + 22, 104, this.fontRenderer.FONT_HEIGHT);
this.searchField.setMaxStringLength(50);
@@ -294,7 +295,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
// Scroll bar
DrawingUtils.drawTexturedRect(guiLeft - BOOKSHELF_UI_WIDTH + SCROLL_BAR_LEFT,
guiTop + SCROLL_BAR_TOP + (int)(scroll * (SCROLL_BAR_HEIGHT - SCROLL_HANDLE_HEIGHT) + 0.5f),
getMaxScrollRows() > 0 ? 30 : 30 + SCROLL_BAR_WIDTH, 476,
getMaxScrollRows() > 0 ? 0 : SCROLL_BAR_WIDTH, 476,
SCROLL_BAR_WIDTH, SCROLL_HANDLE_HEIGHT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
// Tooltip only drawn if there is a wand
@@ -507,7 +508,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
}
}
this.buttonList.forEach(b -> b.drawButtonForegroundLayer(mouseX, mouseY));
this.buttonList.forEach(b -> b.drawButtonForegroundLayer(mouseX - guiLeft, mouseY - guiTop));
}
// Controls
@@ -528,7 +529,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
animationTimer = 20;
}
if(button instanceof GuiButtonSort) this.arcaneWorkbenchContainer.setSortType(((GuiButtonSort)button).sortType);
if(button instanceof GuiButtonSpellSort) this.arcaneWorkbenchContainer.setSortType(((GuiButtonSpellSort)button).sortType);
}
}
@@ -587,45 +588,6 @@ public class GuiArcaneWorkbench extends GuiContainer {
}
}
// Nested classes
private class GuiButtonSort extends GuiButton {
private final ContainerArcaneWorkbench.SortType sortType;
public GuiButtonSort(int id, int x, int y, ContainerArcaneWorkbench.SortType sortType){
super(id, x, y, 10, 10, I18n.format("container." + Wizardry.MODID + ":arcane_workbench.sort_" + sortType.name));
this.sortType = sortType;
}
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
if(this.visible){
// Whether the button is highlighted
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
int k = 0;
int l = 476 + this.sortType.ordinal() * this.height;
if(sortType == GuiArcaneWorkbench.this.arcaneWorkbenchContainer.getSortType()){
k += this.width;
if(GuiArcaneWorkbench.this.arcaneWorkbenchContainer.isSortDescending()) k += this.width;
}
DrawingUtils.drawTexturedRect(this.x, this.y, k, l, this.width, this.height, TEXTURE_WIDTH, TEXTURE_HEIGHT);
}
}
@Override
public void drawButtonForegroundLayer(int mouseX, int mouseY){
if(hovered) drawHoveringText(this.displayString, mouseX - guiLeft, mouseY - guiTop);
}
}
private static class GuiButtonApply extends GuiButton {
public GuiButtonApply(int id, int x, int y){
@@ -0,0 +1,57 @@
package electroblob.wizardry.client.gui;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.DrawingUtils;
import electroblob.wizardry.util.ISpellSortable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
public class GuiButtonSpellSort extends GuiButton {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/spell_sort_buttons.png");
private static final int TEXTURE_WIDTH = 32;
private static final int TEXTURE_HEIGHT = 32;
public final ISpellSortable.SortType sortType;
private final ISpellSortable sortable;
private final GuiScreen parent;
public GuiButtonSpellSort(int id, int x, int y, ISpellSortable.SortType sortType, ISpellSortable sortable, GuiScreen parent){
super(id, x, y, 10, 10, I18n.format("container." + Wizardry.MODID + ":arcane_workbench.sort_" + sortType.name));
this.sortType = sortType;
this.sortable = sortable;
this.parent = parent;
}
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
if(this.visible){
// Whether the button is highlighted
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
int k = 0;
int l = this.sortType.ordinal() * this.height;
if(sortType == sortable.getSortType()){
k += this.width;
if(sortable.isSortDescending()) k += this.width;
}
parent.mc.getTextureManager().bindTexture(TEXTURE);
DrawingUtils.drawTexturedRect(this.x, this.y, k, l, this.width, this.height, TEXTURE_WIDTH, TEXTURE_HEIGHT);
}
}
@Override
public void drawButtonForegroundLayer(int mouseX, int mouseY){
if(hovered) parent.drawHoveringText(this.displayString, mouseX, mouseY);
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.client.gui.handbook;
package electroblob.wizardry.client.gui;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.DrawingUtils;
import electroblob.wizardry.registry.WizardrySounds;
import net.minecraft.client.Minecraft;
@@ -11,12 +10,12 @@ import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.ResourceLocation;
//@SideOnly(Side.CLIENT)
class GuiButtonTurnPage extends GuiButton {
public class GuiButtonTurnPage extends GuiButton {
static final int WIDTH = 20;
static final int HEIGHT = 12;
public static final int WIDTH = 20;
public static final int HEIGHT = 12;
enum Type {
public enum Type {
NEXT_PAGE(0, 196),
PREVIOUS_PAGE(0, 208),
@@ -34,11 +33,15 @@ class GuiButtonTurnPage extends GuiButton {
public final Type type;
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/handbook.png");
private final ResourceLocation texture;
private final int textureWidth, textureHeight;
public GuiButtonTurnPage(int id, int x, int y, Type type){
public GuiButtonTurnPage(int id, int x, int y, Type type, ResourceLocation texture, int textureWidth, int textureHeight){
super(id, x, y, WIDTH, HEIGHT, "");
this.type = type;
this.texture = texture;
this.textureWidth = textureWidth;
this.textureHeight = textureHeight;
}
@Override
@@ -50,12 +53,13 @@ class GuiButtonTurnPage extends GuiButton {
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
if(this.visible){
boolean flag = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
minecraft.getTextureManager().bindTexture(texture);
DrawingUtils.drawTexturedRect(this.x, this.y, flag ? type.u + width : type.u, type.v, width, height, 512, 256);
DrawingUtils.drawTexturedRect(this.x, this.y, flag ? type.u + width : type.u, type.v, width, height, textureWidth, textureHeight);
}
}
}
@@ -0,0 +1,467 @@
package electroblob.wizardry.client.gui;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.block.BlockBookshelf;
import electroblob.wizardry.client.DrawingUtils;
import electroblob.wizardry.client.gui.GuiButtonTurnPage.Type;
import electroblob.wizardry.data.SpellGlyphData;
import electroblob.wizardry.item.ItemSpellBook;
import electroblob.wizardry.packet.PacketLectern;
import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.tileentity.TileEntityLectern;
import electroblob.wizardry.util.ISpellSortable;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.play.client.CPacketCloseWindow;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
public class GuiLectern extends GuiSpellInfo implements ISpellSortable {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/lectern.png");
/** The distance of the page buttons from the bottom outside corners of the GUI. */
private static final int PAGE_BUTTON_INSET_X = 22, PAGE_BUTTON_INSET_Y = 13;
/** The distance between adjacent page turn buttons. */
private static final int PAGE_BUTTON_SPACING = 20;
/** The distance of the sort buttons from the top left corner of the GUI. */
private static final int SORT_BUTTON_INSET_X = 96, SORT_BUTTON_INSET_Y = 20;
/** The distance between adjacent sort buttons. */
private static final int SORT_BUTTON_SPACING = 13;
/** The distance of the spell buttons from the top outside corners of the GUI. */
private static final int SPELL_BUTTON_INSET_X = 23, SPELL_BUTTON_INSET_Y = 44;
/** The distance between adjacent spell buttons (in both x and y). */
private static final int SPELL_BUTTON_SPACING = 38;
private static final int SPELL_ROWS = 3, SPELL_COLUMNS = 3;
public static final int SPELL_BUTTON_COUNT = SPELL_ROWS * SPELL_COLUMNS * 2; // x2 because there are 2 pages
private final TileEntityLectern lectern;
private GuiButton nextPageButton;
private GuiButton prevPageButton;
private GuiButton lastPageButton;
private GuiButton firstPageButton;
private GuiButton indexButton;
private GuiButton locateButton;
private GuiButton[] sortButtons = new GuiButton[3];
private GuiButtonSpell[] spellButtons = new GuiButtonSpell[SPELL_BUTTON_COUNT];
/** The spell currently being viewed, or null if the index is being viewed. */
private Spell currentSpell;
/** The available spells in nearby bookshelves; should not contain duplicates. */
private List<Spell> availableSpells = new ArrayList<>();
/** The spells matching the current search criteria, sorted according to the current sort settings. Will be a subset
* of {@link GuiLectern#availableSpells}. */
private List<Spell> matchingSpells;
private ISpellSortable.SortType sortType = ISpellSortable.SortType.TIER;
private boolean sortDescending = false;
private GuiTextField searchField;
private boolean searchNeedsClearing;
private int currentPage = 0;
public GuiLectern(TileEntityLectern lectern){
super(288, 180);
this.lectern = lectern;
this.currentSpell = lectern.currentSpell;
this.setTextureSize(512, 512);
}
@Override
public Spell getSpell(){
return currentSpell;
}
@Override
public ResourceLocation getTexture(){
return TEXTURE;
}
@Override
public SortType getSortType(){
return sortType;
}
@Override
public boolean isSortDescending(){
return sortDescending;
}
private int getPageCount(){
return MathHelper.ceil((float)matchingSpells.size() / SPELL_BUTTON_COUNT);
}
private Spell getSpellForButton(GuiButtonSpell button){
return matchingSpells.get(currentPage * SPELL_BUTTON_COUNT + button.index);
}
@Override
public void initGui(){
super.initGui();
updateAvailableSpells();
final int left = this.width / 2 - this.xSize / 2;
final int top = this.height / 2 - this.ySize / 2;
int buttonID = 0;
// Page buttons
this.buttonList.add(nextPageButton = new GuiButtonTurnPage(buttonID++, left + xSize - PAGE_BUTTON_INSET_X - GuiButtonTurnPage.WIDTH,
top + ySize - PAGE_BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.NEXT_PAGE, TEXTURE, textureWidth, textureHeight));
this.buttonList.add(prevPageButton = new GuiButtonTurnPage(buttonID++, left + PAGE_BUTTON_INSET_X,
top + ySize - PAGE_BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.PREVIOUS_PAGE, TEXTURE, textureWidth, textureHeight));
this.buttonList.add(lastPageButton = new GuiButtonTurnPage(buttonID++, left + xSize - PAGE_BUTTON_INSET_X - GuiButtonTurnPage.WIDTH - PAGE_BUTTON_SPACING,
top + ySize - PAGE_BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.NEXT_SECTION, TEXTURE, textureWidth, textureHeight));
this.buttonList.add(firstPageButton = new GuiButtonTurnPage(buttonID++, left + PAGE_BUTTON_INSET_X + PAGE_BUTTON_SPACING,
top + ySize - PAGE_BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.PREVIOUS_SECTION, TEXTURE, textureWidth, textureHeight));
this.buttonList.add(indexButton = new GuiButtonTurnPage(buttonID++, left + xSize/2 - 23,
top + ySize - PAGE_BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.CONTENTS, TEXTURE, textureWidth, textureHeight));
this.buttonList.add(locateButton = new GuiButtonLocateBook(buttonID++, left + xSize/2 - 34,
top + ySize - PAGE_BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT));
// Sort buttons
for(SortType sortType : SortType.values()){
this.buttonList.add(sortButtons[sortType.ordinal()] = new GuiButtonSpellSort(buttonID++,
left + SORT_BUTTON_INSET_X + SORT_BUTTON_SPACING * sortType.ordinal(),
top + SORT_BUTTON_INSET_Y, sortType, this, this));
}
// Spell buttons
for(int i = 0; i < SPELL_BUTTON_COUNT; i++){
int row = i % SPELL_COLUMNS;
int column = (i / SPELL_COLUMNS) % SPELL_ROWS;
int x = i < SPELL_BUTTON_COUNT/2 ? SPELL_BUTTON_INSET_X + row * SPELL_BUTTON_SPACING
: xSize - SPELL_BUTTON_INSET_X - GuiButtonSpell.WIDTH - (2-row) * SPELL_BUTTON_SPACING;
int y = SPELL_BUTTON_INSET_Y + column * SPELL_BUTTON_SPACING;
this.buttonList.add(spellButtons[i] = new GuiButtonSpell(buttonID++, left + x, top + y, i));
}
this.searchField = new GuiTextField(0, this.fontRenderer, left + 157, top + 21, 106, this.fontRenderer.FONT_HEIGHT);
this.searchField.setMaxStringLength(50);
this.searchField.setEnableBackgroundDrawing(false);
this.searchField.setVisible(true);
this.searchField.setTextColor(16777215);
this.searchField.setCanLoseFocus(false);
this.searchField.setFocused(true);
updateMatchingSpells();
updateButtonVisiblity();
}
@Override
public void onGuiClosed(){
WizardryPacketHandler.net.sendToServer(new PacketLectern.Message(lectern.getPos(), currentSpell));
super.onGuiClosed();
}
@Override
protected void drawBackgroundLayer(int left, int top, int mouseX, int mouseY){
if(currentSpell == Spells.none){
drawIndexPage(left, top);
}else{
super.drawBackgroundLayer(left, top, mouseX, mouseY);
}
}
@Override
protected void drawForegroundLayer(int left, int top, int mouseX, int mouseY){
if(currentSpell == Spells.none){
this.fontRenderer.drawString(I18n.format("gui." + Wizardry.MODID + ":lectern.title"),
left + 20, top + SORT_BUTTON_INSET_Y, 0);
}else{
super.drawForegroundLayer(left, top, mouseX, mouseY);
}
this.buttonList.forEach(b -> b.drawButtonForegroundLayer(mouseX, mouseY));
}
private void drawIndexPage(int left, int top){
for(int i = 0; i < SPELL_BUTTON_COUNT; i++){
int index = currentPage * SPELL_BUTTON_COUNT + i;
Spell spell = index < matchingSpells.size() ? matchingSpells.get(index) : Spells.none;
boolean discovered = Wizardry.proxy.shouldDisplayDiscovered(spell, null);
Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon());
int row = i % SPELL_COLUMNS;
int column = (i / SPELL_COLUMNS) % SPELL_ROWS;
int x = i < SPELL_BUTTON_COUNT/2 ? SPELL_BUTTON_INSET_X + row * SPELL_BUTTON_SPACING
: xSize - SPELL_BUTTON_INSET_X - GuiButtonSpell.WIDTH - (2-row) * SPELL_BUTTON_SPACING;
int y = SPELL_BUTTON_INSET_Y + column * SPELL_BUTTON_SPACING;
DrawingUtils.drawTexturedRect(left + x + 1, top + y + 1, 0, 0, 32, 32, 32, 32);
}
mc.renderEngine.bindTexture(getTexture());
DrawingUtils.drawTexturedRect(left, top, 0, 256, xSize, ySize, textureWidth, textureHeight);
this.searchField.drawTextBox();
GlStateManager.color(1, 1, 1, 1);
mc.renderEngine.bindTexture(getTexture());
}
@Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton);
searchNeedsClearing = true;
}
@Override
protected void actionPerformed(GuiButton button){
int lastPage = getPageCount() - 1;
if(button == indexButton){
currentSpell = Spells.none;
currentPage = 0;
}else if(button == locateButton){
// Close the GUI
this.mc.player.connection.sendPacket(new CPacketCloseWindow(this.mc.player.openContainer.windowId));
this.mc.displayGuiScreen(null);
// Find the location(s) of the current spell's book(s) and highlight them
for(IInventory bookshelf : BlockBookshelf.findNearbyBookshelves(lectern.getWorld(), lectern.getPos())){
for(int i = 0; i < bookshelf.getSizeInventory(); i++){
ItemStack stack = bookshelf.getStackInSlot(i);
if(stack.getItem() instanceof ItemSpellBook){
Spell spell = Spell.byMetadata(stack.getMetadata());
if(spell == this.currentSpell){
BlockPos pos = (((TileEntity)bookshelf).getPos());
for(EnumFacing side : EnumFacing.VALUES){
ParticleBuilder.create(ParticleBuilder.Type.BLOCK_HIGHLIGHT).pos(
WizardryUtilities.getFaceCentre(pos, side)
.add(new Vec3d(side.getDirectionVec())
.scale(WizardryUtilities.ANTI_Z_FIGHTING_OFFSET)))
.face(side).clr(0.9f, 0.5f, 0.8f).fade(0.7f, 0, 1).spawn(mc.world);
}
break; // This bookshelf has the spell, skip to the next bookshelf
}
}
}
}
}else if(button == nextPageButton){
if(currentPage < lastPage) currentPage++;
}else if(button == prevPageButton){
if(currentPage > 0) currentPage--;
}else if(button == lastPageButton){
currentPage = lastPage;
}else if(button == firstPageButton){
currentPage = 0;
}else if(button instanceof GuiButtonSpell){
currentSpell = getSpellForButton((GuiButtonSpell)button);
}else if(button instanceof GuiButtonSpellSort){
SortType sortType = (((GuiButtonSpellSort)button).sortType);
if(this.sortType == sortType){
this.sortDescending = !this.sortDescending;
}else{
this.sortType = sortType;
this.sortDescending = false;
}
updateMatchingSpells();
}
updateButtonVisiblity();
}
@Override
protected void keyTyped(char typedChar, int keyCode) throws IOException {
if(this.searchNeedsClearing){
this.searchNeedsClearing = false;
this.searchField.setText("");
this.currentPage = 0;
}
if(this.searchField.textboxKeyTyped(typedChar, keyCode)){
this.currentPage = 0;
updateMatchingSpells();
updateButtonVisiblity();
}else{
super.keyTyped(typedChar, keyCode);
}
}
private void updateButtonVisiblity(){
if(currentSpell == Spells.none){
this.searchField.setVisible(true);
int lastPage = getPageCount() - 1;
prevPageButton.visible = currentPage > 0;
firstPageButton.visible = currentPage > 0;
nextPageButton.visible = currentPage < lastPage;
lastPageButton.visible = currentPage < lastPage;
indexButton.visible = false;
locateButton.visible = false;
for(GuiButton button : sortButtons) button.visible = true;
for(GuiButtonSpell button : spellButtons){
button.visible = currentPage * SPELL_BUTTON_COUNT + button.index < matchingSpells.size();
}
}else{
this.searchField.setVisible(false);
this.buttonList.forEach(b -> b.visible = false); // Hide all buttons...
indexButton.visible = true; // ... except the index button and locate button
locateButton.visible = true;
}
}
private void updateMatchingSpells(){
matchingSpells = availableSpells.stream()
.filter(s -> s.matches(searchField.getText().toLowerCase(Locale.ROOT)))
.sorted(sortDescending ? sortType.comparator.reversed() : sortType.comparator)
.collect(Collectors.toList());
}
// TODO: Call this when a bookshelf is added or removed
// TODO: Config option to always display all spells when in creative
private void updateAvailableSpells(){
availableSpells.clear();
// No need to exclude the lectern TE because it's not an IInventory!
for(IInventory bookshelf : BlockBookshelf.findNearbyBookshelves(lectern.getWorld(), lectern.getPos())){
for(int i=0; i<bookshelf.getSizeInventory(); i++){
ItemStack stack = bookshelf.getStackInSlot(i);
if(stack.getItem() instanceof ItemSpellBook){
Spell spell = Spell.byMetadata(stack.getMetadata());
if(!availableSpells.contains(spell)) availableSpells.add(spell);
}
}
}
if(!availableSpells.contains(currentSpell)) currentSpell = Spells.none; // TODO: Do we want this?
}
private class GuiButtonLocateBook extends GuiButton {
public GuiButtonLocateBook(int id, int x, int y){
super(id, x, y, 12, 12, "");
}
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
if(this.visible){
boolean flag = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
GlStateManager.color(1, 1, 1, 1);
minecraft.getTextureManager().bindTexture(TEXTURE);
DrawingUtils.drawTexturedRect(this.x, this.y, flag ? width : 0, 184, width, height, textureWidth, textureHeight);
}
}
}
private class GuiButtonSpell extends GuiButtonInvisible {
private static final int WIDTH = 34, HEIGHT = 34;
private final int index;
public GuiButtonSpell(int id, int x, int y, int index){
super(id, x, y, WIDTH, HEIGHT);
this.index = index;
}
@Override
public void playPressSound(SoundHandler soundHandler){
soundHandler.playSound(PositionedSoundRecord.getMasterRecord(WizardrySounds.MISC_PAGE_TURN, 1));
}
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
if(visible){
super.drawButton(minecraft, mouseX, mouseY, partialTicks);
if(hovered){
mc.renderEngine.bindTexture(getTexture());
DrawingUtils.drawTexturedRect(x, y, 40, 180, width, height, textureWidth, textureHeight);
}
}
}
@Override
public void drawButtonForegroundLayer(int mouseX, int mouseY){
if(visible && hovered){
Spell spell = getSpellForButton(this);
if(Wizardry.proxy.shouldDisplayDiscovered(spell, null)){
drawHoveringText(Collections.singletonList(spell.getDisplayName()), mouseX, mouseY, fontRenderer);
}else{
drawHoveringText(Collections.singletonList(SpellGlyphData.getGlyphName(spell, mc.world)),
mouseX, mouseY, mc.standardGalacticFontRenderer);
}
}
}
}
}
@@ -1,113 +1,35 @@
package electroblob.wizardry.client.gui;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.DrawingUtils;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.data.SpellGlyphData;
import electroblob.wizardry.data.WizardData;
import electroblob.wizardry.item.ItemSpellBook;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.Spell;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
import net.minecraft.util.ResourceLocation;
public class GuiSpellBook extends GuiScreen {
public class GuiSpellBook extends GuiSpellInfo {
private int xSize, ySize;
private ItemSpellBook book;
private Spell spell;
private final ItemSpellBook book;
private final Spell spell;
public GuiSpellBook(ItemStack stack){
super();
xSize = 288;
ySize = 180;
if(!(stack.getItem() instanceof ItemSpellBook)) throw new ClassCastException("Cannot create spell book GUI for item that does not extend ItemSpellBook!");
super(288, 180);
if(!(stack.getItem() instanceof ItemSpellBook)){
throw new ClassCastException("Cannot create spell book GUI for item that does not extend ItemSpellBook!");
}
this.book = (ItemSpellBook)stack.getItem();
this.spell = Spell.byMetadata(stack.getItemDamage());
this.spell = (Spell.byMetadata(stack.getItemDamage()));
}
@Override
public void drawScreen(int par1, int par2, float par3){
int xPos = this.width / 2 - xSize / 2;
int yPos = this.height / 2 - this.ySize / 2;
EntityPlayer player = Minecraft.getMinecraft().player;
boolean discovered = true;
if(Wizardry.settings.discoveryMode && !player.isCreative() && WizardData.get(player) != null
&& !WizardData.get(player).hasSpellBeenDiscovered(spell)){
discovered = false;
}
GlStateManager.color(1, 1, 1, 1); // Just in case
// Draws spell illustration on opposite page, underneath the book so it shows through the hole.
Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon());
DrawingUtils.drawTexturedRect(xPos + 146, yPos + 20, 0, 0, 128, 128, 128, 128);
Minecraft.getMinecraft().renderEngine.bindTexture(book.getGuiTexture(spell));
DrawingUtils.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256);
super.drawScreen(par1, par2, par3);
if(discovered){
this.fontRenderer.drawString(spell.getDisplayName(), xPos + 17, yPos + 15, 0);
this.fontRenderer.drawString(spell.getType().getDisplayName(), xPos + 17, yPos + 26, 0x777777);
}else{
this.mc.standardGalacticFontRenderer.drawString(SpellGlyphData.getGlyphName(spell, player.world), xPos + 17,
yPos + 15, 0);
this.mc.standardGalacticFontRenderer.drawString(spell.getType().getDisplayName(), xPos + 17, yPos + 26,
0x777777);
}
// Novice is usually white but this doesn't show up
String tier = I18n.format("gui.ebwizardry:spell_book.tier", spell.getTier() == Tier.NOVICE ?
"\u00A77" + spell.getTier().getDisplayName() : spell.getTier().getDisplayNameWithFormatting());
this.fontRenderer.drawString(tier, xPos + 17, yPos + 45, 0);
String element = I18n.format("gui.ebwizardry:spell_book.element", spell.getElement().getFormattingCode() + spell.getElement().getDisplayName());
if(!discovered) element = I18n.format("gui.ebwizardry:spell_book.element_undiscovered");
this.fontRenderer.drawString(element, xPos + 17, yPos + 57, 0);
String manaCost = I18n.format("gui.ebwizardry:spell_book.mana_cost", spell.getCost());
if(spell.isContinuous) manaCost = I18n.format("gui.ebwizardry:spell_book.mana_cost_continuous", spell.getCost());
if(!discovered) manaCost = I18n.format("gui.ebwizardry:spell_book.mana_cost_undiscovered");
this.fontRenderer.drawString(manaCost, xPos + 17, yPos + 69, 0);
if(discovered){
this.fontRenderer.drawSplitString(spell.getDescription(), xPos + 17, yPos + 83, 118, 0);
}else{
this.mc.standardGalacticFontRenderer.drawSplitString(
SpellGlyphData.getGlyphDescription(spell, player.world), xPos + 17, yPos + 83, 118, 0);
}
public Spell getSpell(){
return spell;
}
@Override
public void initGui(){
super.initGui();
Keyboard.enableRepeatEvents(true);
this.buttonList.clear();
this.mc.getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(WizardrySounds.MISC_BOOK_OPEN, 1));
}
@Override
public void onGuiClosed(){
super.onGuiClosed();
Keyboard.enableRepeatEvents(false);
}
@Override
public boolean doesGuiPauseGame(){
return Wizardry.settings.booksPauseGame;
public ResourceLocation getTexture(){
return book.getGuiTexture(spell);
}
}
@@ -0,0 +1,137 @@
package electroblob.wizardry.client.gui;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.DrawingUtils;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.data.SpellGlyphData;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.Spell;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
/** Abstract base class for both {@link GuiSpellBook} and {@link GuiLectern}. Centralises code common to both
* those classes. */
public abstract class GuiSpellInfo extends GuiScreen {
protected static final String TRANSLATION_KEY_PREFIX = "gui." + Wizardry.MODID + ":spell_book";
protected final int xSize, ySize;
protected int textureWidth = 512;
protected int textureHeight = 256;
public GuiSpellInfo(int xSize, int ySize){
super();
this.xSize = xSize;
this.ySize = ySize;
}
protected void setTextureSize(int width, int height){
this.textureWidth = width;
this.textureHeight = height;
}
/** Returns the spell to be displayed by this GUI. */
public abstract Spell getSpell();
/** Returns the main texture for the background of this GUI. */
public abstract ResourceLocation getTexture();
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks){
int left = this.width/2 - xSize/2;
int top = this.height/2 - this.ySize/2;
this.drawBackgroundLayer(left, top, mouseX, mouseY);
super.drawScreen(mouseX, mouseY, partialTicks); // Just draws the buttons
this.drawForegroundLayer(left, top, mouseX, mouseY);
}
/**
* Draws the background of the spell info GUI. This is called before buttons are drawn.
* @param left The x-coordinate of the left-hand edge of the GUI
* @param top The y-coordinate of the top edge of the GUI
* @param mouseX The current x position of the mouse pointer
* @param mouseY The current y position of the mouse pointer
*/
protected void drawBackgroundLayer(int left, int top, int mouseX, int mouseY){
boolean discovered = Wizardry.proxy.shouldDisplayDiscovered(getSpell(), null);
GlStateManager.color(1, 1, 1, 1); // Just in case
// Draws spell illustration on opposite page, underneath the book so it shows through the hole.
Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? getSpell().getIcon() : Spells.none.getIcon());
DrawingUtils.drawTexturedRect(left + 146, top + 20, 0, 0, 128, 128, 128, 128);
Minecraft.getMinecraft().renderEngine.bindTexture(getTexture());
DrawingUtils.drawTexturedRect(left, top, 0, 0, xSize, ySize, textureWidth, textureHeight);
}
/**
* Draws the foreground of the spell info GUI. This is called after buttons are drawn.
* @param left The x-coordinate of the left-hand edge of the GUI
* @param top The y-coordinate of the top edge of the GUI
* @param mouseX The current x position of the mouse pointer
* @param mouseY The current y position of the mouse pointer
*/
protected void drawForegroundLayer(int left, int top, int mouseX, int mouseY){
boolean discovered = Wizardry.proxy.shouldDisplayDiscovered(getSpell(), null);
if(discovered){
this.fontRenderer.drawString(getSpell().getDisplayName(), left + 17, top + 15, 0);
this.fontRenderer.drawString(getSpell().getType().getDisplayName(), left + 17, top + 26, 0x777777);
}else{
this.mc.standardGalacticFontRenderer.drawString(SpellGlyphData.getGlyphName(getSpell(), mc.world), left + 17,
top + 15, 0);
this.mc.standardGalacticFontRenderer.drawString(getSpell().getType().getDisplayName(), left + 17, top + 26,
0x777777);
}
// Novice is usually white but this doesn't show up
String tier = I18n.format(TRANSLATION_KEY_PREFIX + ".tier", getSpell().getTier() == Tier.NOVICE ?
"\u00A77" + getSpell().getTier().getDisplayName() : getSpell().getTier().getDisplayNameWithFormatting());
this.fontRenderer.drawString(tier, left + 17, top + 45, 0);
String element = I18n.format(TRANSLATION_KEY_PREFIX + ".element", getSpell().getElement().getFormattingCode() + getSpell().getElement().getDisplayName());
if(!discovered) element = I18n.format(TRANSLATION_KEY_PREFIX + ".element_undiscovered");
this.fontRenderer.drawString(element, left + 17, top + 57, 0);
String manaCost = I18n.format(TRANSLATION_KEY_PREFIX + ".mana_cost", getSpell().getCost());
if(getSpell().isContinuous) manaCost = I18n.format(TRANSLATION_KEY_PREFIX + ".mana_cost_continuous", getSpell().getCost());
if(!discovered) manaCost = I18n.format(TRANSLATION_KEY_PREFIX + ".mana_cost_undiscovered");
this.fontRenderer.drawString(manaCost, left + 17, top + 69, 0);
if(discovered){
this.fontRenderer.drawSplitString(getSpell().getDescription(), left + 17, top + 83, 118, 0);
}else{
this.mc.standardGalacticFontRenderer.drawSplitString(
SpellGlyphData.getGlyphDescription(getSpell(), mc.world), left + 17, top + 83, 118, 0);
}
}
@Override
public void initGui(){
super.initGui();
Keyboard.enableRepeatEvents(true);
this.buttonList.clear();
this.mc.getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(WizardrySounds.MISC_BOOK_OPEN, 1));
}
@Override
public void onGuiClosed(){
super.onGuiClosed();
Keyboard.enableRepeatEvents(false);
}
@Override
public boolean doesGuiPauseGame(){
return Wizardry.settings.booksPauseGame;
}
}
@@ -8,7 +8,8 @@ import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.ClientProxy;
import electroblob.wizardry.client.DrawingUtils;
import electroblob.wizardry.client.gui.GuiButtonInvisible;
import electroblob.wizardry.client.gui.handbook.GuiButtonTurnPage.Type;
import electroblob.wizardry.client.gui.GuiButtonTurnPage;
import electroblob.wizardry.client.gui.GuiButtonTurnPage.Type;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.Tier;
@@ -348,19 +349,19 @@ public class GuiWizardHandbook extends GuiScreen {
this.buttonList.clear();
this.buttonList.add(next = new GuiButtonTurnPage(nextButtonId++, left + GUI_WIDTH - BUTTON_INSET_X - GuiButtonTurnPage.WIDTH,
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.NEXT_PAGE));
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.NEXT_PAGE, texture, TEXTURE_WIDTH, TEXTURE_HEIGHT));
this.buttonList.add(previous = new GuiButtonTurnPage(nextButtonId++, left + BUTTON_INSET_X,
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.PREVIOUS_PAGE));
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.PREVIOUS_PAGE, texture, TEXTURE_WIDTH, TEXTURE_HEIGHT));
this.buttonList.add(nextSection = new GuiButtonTurnPage(nextButtonId++, left + GUI_WIDTH - BUTTON_INSET_X - GuiButtonTurnPage.WIDTH - BUTTON_SPACING,
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.NEXT_SECTION));
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.NEXT_SECTION, texture, TEXTURE_WIDTH, TEXTURE_HEIGHT));
this.buttonList.add(previousSection = new GuiButtonTurnPage(nextButtonId++, left + BUTTON_INSET_X + BUTTON_SPACING,
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.PREVIOUS_SECTION));
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.PREVIOUS_SECTION, texture, TEXTURE_WIDTH, TEXTURE_HEIGHT));
this.buttonList.add(menu = new GuiButtonTurnPage(nextButtonId++, left + GUI_WIDTH/2 - 28,
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.CONTENTS));
top + GUI_HEIGHT - BUTTON_INSET_Y - GuiButtonTurnPage.HEIGHT, Type.CONTENTS, texture, TEXTURE_WIDTH, TEXTURE_HEIGHT));
this.buttonList.add(bookmark = new GuiButtonInvisible(nextButtonId++, left + 130, top + 172, 11, 19) {
@Override