More items, bugfixes

This commit is contained in:
ondra
2014-05-11 18:47:16 +02:00
parent c67ab0cd4a
commit c13a624520
68 changed files with 1332 additions and 374 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 519 B

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
View File
Binary file not shown.
@@ -48,7 +48,7 @@ public abstract class BusNode implements BusAccess, ClientHub {
@Override @Override
public boolean isListening() public final boolean isListening()
{ {
return listening; return listening;
} }
@@ -1,6 +1,7 @@
package mightypork.gamecore.gui.components; package mightypork.gamecore.gui.components;
import mightypork.gamecore.gui.Enableable;
import mightypork.gamecore.gui.events.LayoutChangeEvent; import mightypork.gamecore.gui.events.LayoutChangeEvent;
import mightypork.gamecore.gui.events.LayoutChangeListener; import mightypork.gamecore.gui.events.LayoutChangeListener;
import mightypork.gamecore.input.InputSystem; import mightypork.gamecore.input.InputSystem;
@@ -18,14 +19,15 @@ import mightypork.gamecore.util.math.constraints.rect.proxy.RectBoundAdapter;
* *
* @author MightyPork * @author MightyPork
*/ */
public abstract class VisualComponent extends AbstractRectCache implements Component, LayoutChangeListener { public abstract class BaseComponent extends AbstractRectCache implements Component, LayoutChangeListener, Enableable {
private Rect source; private Rect source;
private boolean visible = true; private boolean visible = true;
private int disableLevel = 0;
public VisualComponent()
{ public BaseComponent() {
enableCaching(false); enableCaching(false);
} }
@@ -61,7 +63,7 @@ public abstract class VisualComponent extends AbstractRectCache implements Compo
@Override @Override
public final void render() public final void render()
{ {
if (!visible) return; if (!isVisible()) return;
renderComponent(); renderComponent();
} }
@@ -101,4 +103,22 @@ public abstract class VisualComponent extends AbstractRectCache implements Compo
public void updateLayout() public void updateLayout()
{ {
} }
@Override
public void enable(boolean yes)
{
if (yes) {
if (disableLevel > 0) disableLevel--;
} else {
disableLevel++;
}
}
@Override
public boolean isEnabled()
{
return disableLevel == 0;
}
} }
@@ -1,9 +1,8 @@
package mightypork.gamecore.gui.components; package mightypork.gamecore.gui.components;
import mightypork.gamecore.gui.Enableable;
import mightypork.gamecore.gui.Hideable; import mightypork.gamecore.gui.Hideable;
import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound;
/** /**
@@ -11,26 +10,7 @@ import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound;
* *
* @author MightyPork * @author MightyPork
*/ */
public interface Component extends Hideable, PluggableRenderable { public interface Component extends Enableable, Hideable, PluggableRenderable {
/**
* Set visible. When not visible, the component should not render.
*/
@Override
void setVisible(boolean yes);
@Override
boolean isVisible();
@Override
Rect getRect();
@Override
void setRect(RectBound rect);
/** /**
* Render the component, if it is visible. * Render the component, if it is visible.
@@ -5,24 +5,7 @@ import mightypork.gamecore.eventbus.clients.ToggleableClient;
import mightypork.gamecore.gui.Enableable; import mightypork.gamecore.gui.Enableable;
public abstract class InputComponent extends VisualComponent implements Enableable, ToggleableClient { public abstract class InputComponent extends BaseComponent implements Enableable, ToggleableClient {
private boolean enabled = true;
@Override
public void enable(boolean yes)
{
this.enabled = yes;
}
@Override
public boolean isEnabled()
{
return enabled && isVisible();
}
@Override @Override
public boolean isListening() public boolean isListening()
@@ -8,14 +8,13 @@ import mightypork.gamecore.app.AppAccess;
import mightypork.gamecore.app.AppSubModule; import mightypork.gamecore.app.AppSubModule;
import mightypork.gamecore.eventbus.EventBus; import mightypork.gamecore.eventbus.EventBus;
import mightypork.gamecore.eventbus.clients.ClientHub; import mightypork.gamecore.eventbus.clients.ClientHub;
import mightypork.gamecore.gui.Enableable;
import mightypork.gamecore.input.InputSystem; import mightypork.gamecore.input.InputSystem;
import mightypork.gamecore.render.DisplaySystem; import mightypork.gamecore.render.DisplaySystem;
import mightypork.gamecore.resources.audio.SoundSystem; import mightypork.gamecore.resources.audio.SoundSystem;
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound; import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound;
public abstract class LayoutComponent extends VisualComponent implements Enableable, ClientHub, AppAccess { public abstract class LayoutComponent extends BaseComponent implements ClientHub, AppAccess {
private boolean enabled; private boolean enabled;
@@ -106,21 +105,29 @@ public abstract class LayoutComponent extends VisualComponent implements Enablea
subModule.removeChildClient(client); subModule.removeChildClient(client);
} }
@Override @Override
public void enable(boolean yes) public void enable(boolean yes)
{ {
subModule.setDelegating(yes); super.enable(yes);
subModule.setListening(yes); for(Component c : components) {
enabled = yes; c.enable(yes);
}
} }
// @Override
@Override // public void enable(boolean yes)
public boolean isEnabled() // {
{ // subModule.setDelegating(yes);
return enabled; // subModule.setListening(yes);
} // enabled = yes;
// }
//
//
// @Override
// public boolean isEnabled()
// {
// return enabled;
// }
/** /**
@@ -1,7 +1,7 @@
package mightypork.gamecore.gui.components.painters; package mightypork.gamecore.gui.components.painters;
import mightypork.gamecore.gui.components.VisualComponent; import mightypork.gamecore.gui.components.BaseComponent;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;
import mightypork.gamecore.resources.textures.TxQuad; import mightypork.gamecore.resources.textures.TxQuad;
import mightypork.gamecore.util.math.constraints.num.Num; import mightypork.gamecore.util.math.constraints.num.Num;
@@ -13,7 +13,7 @@ import mightypork.gamecore.util.math.constraints.rect.Rect;
* *
* @author MightyPork * @author MightyPork
*/ */
public class ImagePainter extends VisualComponent { public class ImagePainter extends BaseComponent {
private final TxQuad txQuad; private final TxQuad txQuad;
private boolean aspratio = false; private boolean aspratio = false;
@@ -1,7 +1,7 @@
package mightypork.gamecore.gui.components.painters; package mightypork.gamecore.gui.components.painters;
import mightypork.gamecore.gui.components.VisualComponent; import mightypork.gamecore.gui.components.BaseComponent;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;
import mightypork.gamecore.util.annot.FactoryMethod; import mightypork.gamecore.util.annot.FactoryMethod;
import mightypork.gamecore.util.math.color.Color; import mightypork.gamecore.util.math.color.Color;
@@ -12,7 +12,7 @@ import mightypork.gamecore.util.math.color.Color;
* *
* @author MightyPork * @author MightyPork
*/ */
public class QuadPainter extends VisualComponent { public class QuadPainter extends BaseComponent {
@FactoryMethod @FactoryMethod
public static QuadPainter gradH(Color colorLeft, Color colorRight) public static QuadPainter gradH(Color colorLeft, Color colorRight)
@@ -2,15 +2,18 @@ package mightypork.gamecore.gui.components.painters;
import mightypork.gamecore.gui.AlignX; import mightypork.gamecore.gui.AlignX;
import mightypork.gamecore.gui.components.VisualComponent; import mightypork.gamecore.gui.components.BaseComponent;
import mightypork.gamecore.render.Render;
import mightypork.gamecore.resources.fonts.FontRenderer; import mightypork.gamecore.resources.fonts.FontRenderer;
import mightypork.gamecore.resources.fonts.GLFont; import mightypork.gamecore.resources.fonts.GLFont;
import mightypork.gamecore.util.math.color.Color; import mightypork.gamecore.util.math.color.Color;
import mightypork.gamecore.util.math.color.pal.RGB; import mightypork.gamecore.util.math.color.pal.RGB;
import mightypork.gamecore.util.math.constraints.num.Num;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.gamecore.util.math.constraints.vect.Vect;
import mightypork.gamecore.util.strings.StringProvider; import mightypork.gamecore.util.strings.StringProvider;
import mightypork.gamecore.util.strings.StringWrapper; import mightypork.gamecore.util.strings.StringWrapper;
import mightypork.rogue.Config;
/** /**
@@ -20,7 +23,7 @@ import mightypork.gamecore.util.strings.StringWrapper;
* *
* @author MightyPork * @author MightyPork
*/ */
public class TextPainter extends VisualComponent { public class TextPainter extends BaseComponent {
private final FontRenderer font; private final FontRenderer font;
private Color color; private Color color;
@@ -28,6 +31,9 @@ public class TextPainter extends VisualComponent {
private StringProvider text; private StringProvider text;
private boolean shadow; private boolean shadow;
private double yPaddingPerc = 0;
private double xPaddingPerc = 0;
private Color shadowColor = RGB.BLACK; private Color shadowColor = RGB.BLACK;
private Vect shadowOffset = Vect.make(2, 2); private Vect shadowOffset = Vect.make(2, 2);
@@ -35,8 +41,7 @@ public class TextPainter extends VisualComponent {
/** /**
* @param font font to use * @param font font to use
*/ */
public TextPainter(GLFont font) public TextPainter(GLFont font) {
{
this(font, AlignX.LEFT, RGB.WHITE); this(font, AlignX.LEFT, RGB.WHITE);
} }
@@ -49,8 +54,7 @@ public class TextPainter extends VisualComponent {
* @param color default color * @param color default color
* @param text drawn text * @param text drawn text
*/ */
public TextPainter(GLFont font, AlignX align, Color color, String text) public TextPainter(GLFont font, AlignX align, Color color, String text) {
{
this(font, align, color, new StringWrapper(text)); this(font, align, color, new StringWrapper(text));
} }
@@ -63,8 +67,7 @@ public class TextPainter extends VisualComponent {
* @param color default color * @param color default color
* @param text text provider * @param text text provider
*/ */
public TextPainter(GLFont font, AlignX align, Color color, StringProvider text) public TextPainter(GLFont font, AlignX align, Color color, StringProvider text) {
{
this.font = new FontRenderer(font); this.font = new FontRenderer(font);
this.color = color; this.color = color;
this.align = align; this.align = align;
@@ -77,8 +80,7 @@ public class TextPainter extends VisualComponent {
* @param align text align * @param align text align
* @param color default color * @param color default color
*/ */
public TextPainter(GLFont font, AlignX align, Color color) public TextPainter(GLFont font, AlignX align, Color color) {
{
this(font, align, color, (StringProvider) null); this(font, align, color, (StringProvider) null);
} }
@@ -89,13 +91,20 @@ public class TextPainter extends VisualComponent {
if (text == null) return; if (text == null) return;
final String str = text.getString(); final String str = text.getString();
final Rect rect = getRect();
Num shrX = height().perc(xPaddingPerc);
Num shrY = height().perc(yPaddingPerc);
final Rect rect = getRect().shrink(shrX, shrY);
if (shadow) { if (shadow) {
font.draw(str, rect.round(), align, shadowColor); font.draw(str, rect.round(), align, shadowColor);
} }
font.draw(str, rect.move(shadowOffset.neg()).round(), align, color); Rect r = (shadow ? rect.move(shadowOffset.neg()) : rect).round();
font.draw(str, r, align, color);
if (Config.DEBUG_FONT_RENDER) Render.quadColor(r, RGB.PINK.withAlpha(0.4));
} }
@@ -147,4 +156,11 @@ public class TextPainter extends VisualComponent {
{ {
this.text = text; this.text = text;
} }
public void setPaddingHPerc(double percX, double percY)
{
xPaddingPerc = percX;
yPaddingPerc = percY;
}
} }
@@ -16,6 +16,11 @@ import mightypork.gamecore.eventbus.clients.DelegatingClient;
*/ */
public abstract class LayeredScreen extends Screen { public abstract class LayeredScreen extends Screen {
/**
* Wrapper for delegating client, to use custom client ordering.
*
* @author MightyPork
*/
private class LayersClient implements DelegatingClient { private class LayersClient implements DelegatingClient {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -7,6 +7,7 @@ import java.util.LinkedHashSet;
import mightypork.gamecore.app.AppAccess; import mightypork.gamecore.app.AppAccess;
import mightypork.gamecore.app.AppSubModule; import mightypork.gamecore.app.AppSubModule;
import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.eventbus.events.Updateable;
import mightypork.gamecore.gui.Enableable;
import mightypork.gamecore.gui.Hideable; import mightypork.gamecore.gui.Hideable;
import mightypork.gamecore.gui.components.layout.ConstraintLayout; import mightypork.gamecore.gui.components.layout.ConstraintLayout;
import mightypork.gamecore.gui.events.LayoutChangeListener; import mightypork.gamecore.gui.events.LayoutChangeListener;
@@ -24,9 +25,11 @@ import mightypork.gamecore.util.math.constraints.vect.Vect;
* *
* @author MightyPork * @author MightyPork
*/ */
public abstract class Overlay extends AppSubModule implements Comparable<Overlay>, Updateable, Renderable, KeyBinder, Hideable, LayoutChangeListener { public abstract class Overlay extends AppSubModule implements Comparable<Overlay>, Updateable, Renderable, KeyBinder, Hideable, Enableable, LayoutChangeListener {
private boolean visible = true; private boolean visible = true;
private boolean enabled = true;
private final KeyBindingPool keybindings = new KeyBindingPool(); private final KeyBindingPool keybindings = new KeyBindingPool();
/** Root layout, rendered and attached to the event bus. */ /** Root layout, rendered and attached to the event bus. */
@@ -81,8 +84,21 @@ public abstract class Overlay extends AppSubModule implements Comparable<Overlay
public void setVisible(boolean visible) public void setVisible(boolean visible)
{ {
this.visible = visible; this.visible = visible;
root.setVisible(visible);
} }
@Override
public void enable(boolean yes)
{
this.enabled = yes;
root.enable(yes);
}
@Override
public boolean isEnabled()
{
return enabled;
}
/** /**
* Get rendering layer * Get rendering layer
@@ -110,6 +126,8 @@ public abstract class Overlay extends AppSubModule implements Comparable<Overlay
@Override @Override
public void render() public void render()
{ {
if(!isVisible()) return;
for (final Renderable r : rendered) { for (final Renderable r : rendered) {
r.render(); r.render();
} }
@@ -119,6 +137,8 @@ public abstract class Overlay extends AppSubModule implements Comparable<Overlay
@Override @Override
public void update(double delta) public void update(double delta)
{ {
if(!isEnabled()) return;
for (final Updateable u : updated) { for (final Updateable u : updated) {
u.update(delta); u.update(delta);
} }
@@ -24,8 +24,7 @@ public class FontRenderer {
/** /**
* @param font used font * @param font used font
*/ */
public FontRenderer(GLFont font) public FontRenderer(GLFont font) {
{
this(font, RGB.WHITE); this(font, RGB.WHITE);
} }
@@ -34,8 +33,7 @@ public class FontRenderer {
* @param font used font * @param font used font
* @param color drawing color * @param color drawing color
*/ */
public FontRenderer(GLFont font, Color color) public FontRenderer(GLFont font, Color color) {
{
this.font = font; this.font = font;
this.color = color; this.color = color;
} }
@@ -69,10 +67,7 @@ public class FontRenderer {
private double getScale(double height) private double getScale(double height)
{ {
final double fontHeight = font.getLineHeight(); return height / font.getLineHeight();
final double usefulHeight = fontHeight - fontHeight * font.getTopDiscardRatio() - fontHeight * font.getBottomDiscardRatio();
return height / usefulHeight;
} }
@@ -112,7 +107,7 @@ public class FontRenderer {
final double sc = getScale(height); final double sc = getScale(height);
Render.translate(pos.x(), pos.y() - font.getTopDiscardRatio() * sc); Render.translate(pos.x(), pos.y());
Render.scaleXY(sc); Render.scaleXY(sc);
font.draw(text, color); font.draw(text, color);
@@ -90,8 +90,7 @@ public class CachedFont implements GLFont {
* @param filter used Gl filter * @param filter used Gl filter
* @param chars chars to load * @param chars chars to load
*/ */
public CachedFont(java.awt.Font font, boolean antialias, FilterMode filter, String chars) public CachedFont(java.awt.Font font, boolean antialias, FilterMode filter, String chars) {
{
this(font, antialias, filter, (" " + chars).toCharArray()); this(font, antialias, filter, (" " + chars).toCharArray());
} }
@@ -104,8 +103,7 @@ public class CachedFont implements GLFont {
* @param filter used Gl filter * @param filter used Gl filter
* @param chars chars to load * @param chars chars to load
*/ */
public CachedFont(java.awt.Font font, boolean antialias, FilterMode filter, char[] chars) public CachedFont(java.awt.Font font, boolean antialias, FilterMode filter, char[] chars) {
{
GLUtils.checkGLContext(); GLUtils.checkGLContext();
this.font = font; this.font = font;
@@ -165,8 +163,7 @@ public class CachedFont implements GLFont {
public int height; public int height;
public LoadedGlyph(char c, BufferedImage image) public LoadedGlyph(char c, BufferedImage image) {
{
this.image = image; this.image = image;
this.c = c; this.c = c;
this.width = image.getWidth(); this.width = image.getWidth();
@@ -302,8 +299,7 @@ public class CachedFont implements GLFont {
byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(newI); byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(newI);
} else { } else {
byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()) byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData());
.put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData());
} }
byteBuffer.flip(); byteBuffer.flip();
@@ -363,7 +359,7 @@ public class CachedFont implements GLFont {
@Override @Override
public int getLineHeight() public int getLineHeight()
{ {
return fontHeight; return (int) Math.round(fontHeight * ((1 - discardTop) - discardBottom));
} }
@@ -416,7 +412,8 @@ public class CachedFont implements GLFont {
final float txmin = chtx.texPosX; final float txmin = chtx.texPosX;
final float tymin = chtx.texPosY; final float tymin = chtx.texPosY;
final float draw_width = minx + chtx.width - minx; final float draw_width = minx + chtx.width - minx;
final float draw_height = (float) (chtx.height) - (float) 0; final float draw_height = chtx.height;
final float drawy0 = (float) (0f - draw_height*discardTop);
final float txmin01 = txmin / textureWidth; final float txmin01 = txmin / textureWidth;
final float tymin01 = tymin / textureHeight; final float tymin01 = tymin / textureHeight;
@@ -424,18 +421,17 @@ public class CachedFont implements GLFont {
final float theight01 = ((chtx.texPosY + chtx.height - tymin) / textureHeight); final float theight01 = ((chtx.texPosY + chtx.height - tymin) / textureHeight);
glTexCoord2f(txmin01, tymin01); glTexCoord2f(txmin01, tymin01);
glVertex2f(minx, 0); glVertex2f(minx, drawy0);
glTexCoord2f(txmin01, tymin01 + theight01); glTexCoord2f(txmin01, tymin01 + theight01);
glVertex2f(minx, 0 + draw_height); glVertex2f(minx, drawy0 + draw_height);
glTexCoord2f(txmin01 + twidth01, tymin01 + theight01); glTexCoord2f(txmin01 + twidth01, tymin01 + theight01);
glVertex2f(minx + draw_width, 0 + draw_height); glVertex2f(minx + draw_width, drawy0 + draw_height);
glTexCoord2f(txmin01 + twidth01, tymin01); glTexCoord2f(txmin01 + twidth01, tymin01);
glVertex2f(minx + draw_width, 0); glVertex2f(minx + draw_width, drawy0);
minx += chtx.width; minx += chtx.width;
} }
} }
@@ -119,6 +119,7 @@ public class DeferredFont extends DeferredResource implements GLFont {
final Font awtFont = getAwtFont(path, (float) size, style.numval); final Font awtFont = getAwtFont(path, (float) size, style.numval);
font = new CachedFont(awtFont, antialias, filter, chars); font = new CachedFont(awtFont, antialias, filter, chars);
font.setDiscardRatio(discardTop, discardBottom);
} }
@@ -666,4 +666,51 @@ public class Calc {
{ {
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
} }
public static int randInt(Random rand, int low, int high)
{
int range = high - low + 1;
if(range < 1) range = 1;
return low + rand.nextInt(range);
}
/**
* Get ordinal version of numbers (1 = 1st, 5 = 5th etc.)
*
* @param number number
* @return ordinal, string
*/
public static String ordinal(int number)
{
if (number % 100 < 4 || number % 100 > 13) {
if (number % 10 == 1) return number + "st";
if (number % 10 == 2) return number + "nd";
if (number % 10 == 3) return number + "rd";
}
return number + "th";
}
/**
* Format number with thousands separated by a dot.
*
* @param number number
* @return string 12.004.225
*/
public static String formatInt(long number)
{
final String num = number + "";
String out = "";
final String dot = ".";
int cnt = 1;
for (int i = num.length() - 1; i >= 0; i--) {
out = num.charAt(i) + out;
if (cnt % 3 == 0 && i > 0) out = dot + out;
cnt++;
}
return out;
}
} }
@@ -474,7 +474,7 @@ public abstract class Rect implements RectBound, Digestable<RectDigest> {
public Rect shrinkRight(final double shrink) public Rect shrinkRight(final double shrink)
{ {
return growLeft(-shrink); return growRight(-shrink);
} }
@@ -100,45 +100,6 @@ public class StringUtils {
} }
/**
* Get ordinal version of numbers (1 = 1st, 5 = 5th etc.)
*
* @param number number
* @return ordinal, string
*/
public static String numberToOrdinal(int number)
{
if (number % 100 < 4 || number % 100 > 13) {
if (number % 10 == 1) return number + "st";
if (number % 10 == 2) return number + "nd";
if (number % 10 == 3) return number + "rd";
}
return number + "th";
}
/**
* Format number with thousands separated by a dot.
*
* @param number number
* @return string 12.004.225
*/
public static String formatInt(long number)
{
final String num = number + "";
String out = "";
final String dot = ".";
int cnt = 1;
for (int i = num.length() - 1; i >= 0; i--) {
out = num.charAt(i) + out;
if (cnt % 3 == 0 && i > 0) out = dot + out;
cnt++;
}
return out;
}
public static boolean isValidFilenameChar(char ch) public static boolean isValidFilenameChar(char ch)
{ {
return isValidFilenameString(Character.toString(ch)); return isValidFilenameString(Character.toString(ch));
+6
View File
@@ -26,6 +26,7 @@ public final class Config {
private static final String PK_START_IN_FS = "cfg.start_in_fullscreen"; private static final String PK_START_IN_FS = "cfg.start_in_fullscreen";
/** /**
* Prepare config manager and load user settings * Prepare config manager and load user settings
*/ */
@@ -76,4 +77,9 @@ public final class Config {
public static boolean LOG_TO_STDOUT = true; public static boolean LOG_TO_STDOUT = true;
public static boolean SINGLE_INSTANCE = true; public static boolean SINGLE_INSTANCE = true;
/** Render dark in unknown area & skip invisible stuff */
public static boolean RENDER_UFOG = true;
/** Render a font bounding box in text painters. */
public static boolean DEBUG_FONT_RENDER = false;
} }
+15 -3
View File
@@ -53,13 +53,18 @@ public final class Res {
//fonts.loadFont("polygon_pixel", new DeferredFont("/res/font/PolygonPixel5x7Standard.ttf", Glyphs.basic, 16)); //fonts.loadFont("polygon_pixel", new DeferredFont("/res/font/PolygonPixel5x7Standard.ttf", Glyphs.basic, 16));
fonts.loadFont("press_start", font = new DeferredFont("/res/font/PressStart2P.ttf", Glyphs.basic, 16)); fonts.loadFont("press_start", font = new DeferredFont("/res/font/PressStart2P.ttf", Glyphs.basic, 16));
fonts.loadFont("polygon_pixel", font = new DeferredFont("/res/font/Simpleton.ttf", Glyphs.basic, 16));
font.setDiscardRatio(5 / 16D, 2 / 16D); fonts.loadFont("battlenet", font = new DeferredFont("/res/font/battlenet.ttf", Glyphs.basic, 16));
font.setDiscardRatio(3 / 16D, 2 / 16D);
fonts.loadFont("tinyutf", font = new DeferredFont("/res/font/TinyUnicode2.ttf", Glyphs.basic, 16));
font.setDiscardRatio(6 / 16D, 2 / 16D);
// aliases based on concrete usage // aliases based on concrete usage
fonts.addAlias("thick", "press_start"); fonts.addAlias("thick", "press_start");
fonts.addAlias("thin", "polygon_pixel"); fonts.addAlias("thin", "battlenet");
fonts.addAlias("tiny", "tinyutf");
} }
@@ -152,6 +157,13 @@ public final class Res {
texture = textures.loadTexture("items", "/res/img/items.png", FilterMode.NEAREST, WrapMode.CLAMP); texture = textures.loadTexture("items", "/res/img/items.png", FilterMode.NEAREST, WrapMode.CLAMP);
grid = texture.grid(8, 8); grid = texture.grid(8, 8);
textures.add("item.meat", grid.makeQuad(0, 0)); textures.add("item.meat", grid.makeQuad(0, 0));
textures.add("item.club", grid.makeQuad(1, 0));
textures.add("item.sword", grid.makeQuad(2, 0));
textures.add("item.hammer", grid.makeQuad(3, 0));
textures.add("item.stone", grid.makeQuad(4, 0));
textures.add("item.bone", grid.makeQuad(5, 0));
textures.add("item.cheese", grid.makeQuad(6, 0));
textures.add("item.sandwich", grid.makeQuad(7, 0));
} }
@@ -2,15 +2,16 @@ package mightypork.rogue.screens.game;
import mightypork.gamecore.gui.AlignX; import mightypork.gamecore.gui.AlignX;
import mightypork.gamecore.gui.components.VisualComponent; import mightypork.gamecore.gui.components.BaseComponent;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;
import mightypork.gamecore.resources.textures.TxQuad; import mightypork.gamecore.resources.textures.TxQuad;
import mightypork.gamecore.util.math.color.pal.RGB;
import mightypork.gamecore.util.math.constraints.num.Num; import mightypork.gamecore.util.math.constraints.num.Num;
import mightypork.gamecore.util.math.constraints.num.mutable.NumVar; import mightypork.gamecore.util.math.constraints.num.mutable.NumVar;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
public class HeartBar extends VisualComponent { public class HeartBar extends BaseComponent {
private final TxQuad img_on; private final TxQuad img_on;
private final TxQuad img_off; private final TxQuad img_off;
@@ -18,8 +19,8 @@ public class HeartBar extends VisualComponent {
private final Num total; private final Num total;
private final Num active; private final Num active;
NumVar index = new NumVar(0); private final NumVar index = new NumVar(0);
Rect heart; private final Rect heart;
/** /**
@@ -30,8 +31,7 @@ public class HeartBar extends VisualComponent {
* @param img_off * @param img_off
* @param align * @param align
*/ */
public HeartBar(Num total, Num active, TxQuad img_on, TxQuad img_half, TxQuad img_off, AlignX align) public HeartBar(Num total, Num active, TxQuad img_on, TxQuad img_half, TxQuad img_off, AlignX align) {
{
super(); super();
this.total = total; this.total = total;
this.active = active; this.active = active;
@@ -52,6 +52,8 @@ public class HeartBar extends VisualComponent {
case CENTER: case CENTER:
heart = leftEdge().moveX(w.half().add(h.mul(total.half().neg()))).growRight(h).moveX(index.mul(h)); heart = leftEdge().moveX(w.half().add(h.mul(total.half().neg()))).growRight(h).moveX(index.mul(h));
break; break;
default:
heart = null; // impossible
} }
} }
@@ -64,7 +66,6 @@ public class HeartBar extends VisualComponent {
index.setTo(i); index.setTo(i);
final double rem = active.value() - i; final double rem = active.value() - i;
Render.quadTextured(heart, (rem > 0.6 ? img_on : rem > 0.25 ? img_half : img_off)); Render.quadTextured(heart, (rem > 0.6 ? img_on : rem > 0.25 ? img_half : img_off));
} }
} }
+30 -26
View File
@@ -39,8 +39,7 @@ public class HudLayer extends ScreenLayer {
private final ScreenGame gameScreen; private final ScreenGame gameScreen;
public HudLayer(ScreenGame screen) public HudLayer(ScreenGame screen) {
{
super(screen); super(screen);
this.gameScreen = screen; this.gameScreen = screen;
@@ -49,6 +48,22 @@ public class HudLayer extends ScreenLayer {
buildDisplays(); buildDisplays();
buildMinimap(); buildMinimap();
buildConsole();
}
private void buildConsole()
{
Num rh = root.height();
Num rw = root.width();
Rect consoleRect = root.shrink(rw.perc(2), Num.ZERO, rh.perc(6), rh.perc(16));
Num perRow = consoleRect.height().div(20).max(12).min(32);
WorldConsoleRenderer wcr = new WorldConsoleRenderer(perRow);
wcr.setRect(consoleRect);
root.add(wcr);
} }
@@ -64,8 +79,6 @@ public class HudLayer extends ScreenLayer {
{ {
final Num h = root.height(); final Num h = root.height();
final Num displays_height = h.perc(6);
//@formatter:off //@formatter:off
final HeartBar hearts = new HeartBar( final HeartBar hearts = new HeartBar(
playerHealthTotal, playerHealthTotal,
@@ -76,13 +89,11 @@ public class HudLayer extends ScreenLayer {
AlignX.LEFT); AlignX.LEFT);
//@formatter:on //@formatter:on
final Rect hearts_box = root.shrink(h.perc(3)).topEdge().growDown(h.perc(6));
final Rect hearts_box = root.shrink(h.perc(3)).topLeft().startRect().growDown(displays_height);
hearts.setRect(hearts_box); hearts.setRect(hearts_box);
root.add(hearts); root.add(hearts);
final TextPainter levelText = new TextPainter(Res.getFont("tiny"), AlignX.RIGHT, RGB.WHITE, new StringProvider() {
final TextPainter lvl = new TextPainter(Res.getFont("thick"), AlignX.RIGHT, RGB.WHITE, new StringProvider() {
@Override @Override
public String getString() public String getString()
@@ -92,15 +103,8 @@ public class HudLayer extends ScreenLayer {
} }
}); });
final Rect rr = root.shrink(h.perc(3)).topEdge().growDown(displays_height); levelText.setRect(hearts_box.moveY(hearts_box.height().mul(1/7D)));
lvl.setRect(rr.shrink(Num.ZERO, rr.height().perc(20))); root.add(levelText);
root.add(lvl);
/*final HeartBar experience = new HeartBar(6, 2, Res.getTxQuad("xp_on"), Res.getTxQuad("xp_off"), AlignX.RIGHT);
final Rect xp_box = shrunk.topRight().startRect().growDown(displays_height);
experience.setRect(xp_box);
root.add(experience);*/
} }
@@ -112,24 +116,24 @@ public class HudLayer extends ScreenLayer {
NavButton btn; NavButton btn;
// ltr nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.inventory")));
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.inventory")));
btn.setAction(gameScreen.actionInv); btn.setAction(gameScreen.actionInv);
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.eat"))); nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.eat")));
btn.setAction(gameScreen.actionEat); btn.setAction(gameScreen.actionEat);
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.pause"))); nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.pause")));
btn.setAction(gameScreen.actionTogglePause); btn.setAction(gameScreen.actionTogglePause);
// TODO actions
nav.addRight(new NavButton(Res.txq("nav.button.fg.options")));
nav.addRight(new NavButton(Res.txq("nav.button.fg.help")));
nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.map"))); // TODO actions
nav.addLeft(new NavButton(Res.txq("nav.button.fg.options")));
nav.addLeft(new NavButton(Res.txq("nav.button.fg.help")));
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.map")));
btn.setAction(gameScreen.actionToggleMinimap); btn.setAction(gameScreen.actionToggleMinimap);
nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.magnify"))); nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.magnify")));
btn.setAction(gameScreen.actionToggleZoom); btn.setAction(gameScreen.actionToggleZoom);
} }
+28 -18
View File
@@ -30,7 +30,7 @@ public class InvLayer extends ScreenLayer {
@Override @Override
public String getString() public String getString()
{ {
String s = "Esc - close"; String s = "ESC-close";
final int selected = getSelectedSlot(); final int selected = getSelectedSlot();
if (selected != -1) { if (selected != -1) {
@@ -49,6 +49,8 @@ public class InvLayer extends ScreenLayer {
s = "E-equip," + s; s = "E-equip," + s;
} }
} }
}else {
s = "Click-select,"+s;
} }
return s; return s;
@@ -76,18 +78,19 @@ public class InvLayer extends ScreenLayer {
final Rect fg = root.shrink(root.height().perc(15)); final Rect fg = root.shrink(root.height().perc(15));
final QuadPainter qp = new QuadPainter(Color.rgba(0, 0, 0, 0.5)); final QuadPainter qp = new QuadPainter(RGB.BLACK_30, RGB.BLACK_30, RGB.BLACK_80, RGB.BLACK_80);
qp.setRect(root); qp.setRect(root);
root.add(qp); root.add(qp);
int pos = 0; int pos = 0;
final GridLayout gl = new GridLayout(root, fg, 21, 1); final GridLayout gl = new GridLayout(root, fg, 10, 1);
root.add(gl); root.add(gl);
final TextPainter txp = new TextPainter(Res.getFont("thick"), AlignX.CENTER, RGB.YELLOW, "Inventory"); final TextPainter txp = new TextPainter(Res.getFont("thick"), AlignX.CENTER, RGB.YELLOW, "Inventory");
gl.put(txp, pos, 0, 2, 1); gl.put(txp, pos, 0, 1, 1);
pos += 3; txp.setPaddingHPerc(0, 5);
pos += 1;
final HorizontalFixedFlowLayout row1 = new HorizontalFixedFlowLayout(root, null, AlignX.LEFT); final HorizontalFixedFlowLayout row1 = new HorizontalFixedFlowLayout(root, null, AlignX.LEFT);
row1.setElementWidth(row1.height()); row1.setElementWidth(row1.height());
@@ -95,8 +98,8 @@ public class InvLayer extends ScreenLayer {
row1.setRect(cl1.axisV().grow(cl1.height().mul(2), Num.ZERO)); row1.setRect(cl1.axisV().grow(cl1.height().mul(2), Num.ZERO));
cl1.add(row1); cl1.add(row1);
gl.put(cl1, pos, 0, 8, 1); gl.put(cl1, pos, 0, 4, 1);
pos += 8; pos += 4;
row1.add(slots[0] = new InvSlot(0, slots)); row1.add(slots[0] = new InvSlot(0, slots));
row1.add(slots[1] = new InvSlot(1, slots)); row1.add(slots[1] = new InvSlot(1, slots));
@@ -109,25 +112,24 @@ public class InvLayer extends ScreenLayer {
final ConstraintLayout cl2 = new ConstraintLayout(root); final ConstraintLayout cl2 = new ConstraintLayout(root);
row2.setRect(cl2.axisV().grow(cl2.height().mul(2), Num.ZERO)); row2.setRect(cl2.axisV().grow(cl2.height().mul(2), Num.ZERO));
cl2.add(row2); cl2.add(row2);
gl.put(cl2, pos, 0, 8, 1); gl.put(cl2, pos, 0, 4, 1);
pos += 8; pos += 4;
row2.add(slots[4] = new InvSlot(4, slots)); row2.add(slots[4] = new InvSlot(4, slots));
row2.add(slots[5] = new InvSlot(5, slots)); row2.add(slots[5] = new InvSlot(5, slots));
row2.add(slots[6] = new InvSlot(6, slots)); row2.add(slots[6] = new InvSlot(6, slots));
row2.add(slots[7] = new InvSlot(7, slots)); row2.add(slots[7] = new InvSlot(7, slots));
final TextPainter txp2 = new TextPainter(Res.getFont("thin"), AlignX.CENTER, RGB.WHITE, contextStrProv); final TextPainter txp2 = new TextPainter(Res.getFont("thick"), AlignX.CENTER, RGB.WHITE, contextStrProv);
gl.put(txp2, pos + 1, 0, 1, 1); gl.put(txp2, pos, 0, 1, 1);
txp2.setPaddingHPerc(0, 25);
setVisible(false);
bindKey(new KeyStroke(Keys.ESCAPE), new Runnable() { bindKey(new KeyStroke(Keys.ESCAPE), new Runnable() {
@Override @Override
public void run() public void run()
{ {
if (!isVisible()) return; if(WorldProvider.get().getPlayer().isDead()) return;
screen.setState(GScrState.WORLD); screen.setState(GScrState.WORLD);
} }
@@ -138,7 +140,7 @@ public class InvLayer extends ScreenLayer {
@Override @Override
public void run() public void run()
{ {
if (!isVisible()) return; if(WorldProvider.get().getPlayer().isDead()) return;
final int selected = getSelectedSlot(); final int selected = getSelectedSlot();
if (selected != -1) { if (selected != -1) {
@@ -148,14 +150,13 @@ public class InvLayer extends ScreenLayer {
if (itm.getType() == ItemType.FOOD) { if (itm.getType() == ItemType.FOOD) {
if (pl.eatFood(itm)) { if (pl.eatFood(itm)) {
if (itm.consume()) { pl.getInventory().clean();
pl.getInventory().setItem(selected, null);
}
} }
} }
if (itm.getType() == ItemType.WEAPON) { if (itm.getType() == ItemType.WEAPON) {
pl.selectWeapon(selected); pl.selectWeapon(selected);
WorldProvider.get().getWorld().msgEquipWeapon(itm);
} }
} }
} }
@@ -194,4 +195,13 @@ public class InvLayer extends ScreenLayer {
return 200; return 200;
} }
@Override
public void onLayoutChanged()
{
// TODO Auto-generated method stub
super.onLayoutChanged();
System.out.println("LayoutChange @ invlayer");
}
} }
+48 -19
View File
@@ -7,12 +7,17 @@ import mightypork.gamecore.gui.components.ClickableComponent;
import mightypork.gamecore.gui.components.painters.TextPainter; import mightypork.gamecore.gui.components.painters.TextPainter;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;
import mightypork.gamecore.resources.textures.TxQuad; import mightypork.gamecore.resources.textures.TxQuad;
import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.color.Color;
import mightypork.gamecore.util.math.color.pal.RGB; import mightypork.gamecore.util.math.color.pal.RGB;
import mightypork.gamecore.util.math.constraints.num.Num;
import mightypork.gamecore.util.math.constraints.rect.caching.RectCache; import mightypork.gamecore.util.math.constraints.rect.caching.RectCache;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.World.PlayerFacade; import mightypork.rogue.world.World.PlayerFacade;
import mightypork.rogue.world.PlayerInfo;
import mightypork.rogue.world.WorldProvider; import mightypork.rogue.world.WorldProvider;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.item.ItemType;
/** /**
@@ -28,16 +33,18 @@ public class InvSlot extends ClickableComponent {
protected int index; protected int index;
private final RectCache itemRect; private final RectCache itemRect;
private final RectCache uiRect;
private final InvSlot[] slots; private final InvSlot[] slots;
private final TextPainter txt; private final TextPainter rbTxP;
private final TextPainter rtTxP;
private final RectCache txtRect; private final RectCache rbTxRect;
private final RectCache rtTxRect;
public InvSlot(int index, InvSlot[] allSlots) public InvSlot(int index, InvSlot[] allSlots) {
{
super(); super();
this.txBase = Res.txq("inv.slot.base"); this.txBase = Res.txq("inv.slot.base");
this.txSelected = Res.txq("inv.slot.selected"); this.txSelected = Res.txq("inv.slot.selected");
@@ -45,17 +52,27 @@ public class InvSlot extends ClickableComponent {
this.index = index; this.index = index;
this.slots = allSlots; this.slots = allSlots;
this.itemRect = getRect().shrink(height().perc(16)).cached(); this.uiRect = getRect().shrink(height().perc(16)).cached();
this.itemRect = uiRect.shrink(Num.ZERO, height().perc(14), height().perc(14), Num.ZERO).cached();
//@formatter:off //@formatter:off
this.txtRect = itemRect.bottomEdge() this.rbTxRect = uiRect.bottomEdge()
.move(itemRect.height().perc(5).neg(), itemRect.height().perc(10).neg()) .moveY(uiRect.height().perc(1*(30/7D)))
.growUp(itemRect.height().perc(35)).cached(); .growUp(uiRect.height().perc(30)).cached();
//@formatter:on //@formatter:on
txt = new TextPainter(Res.getFont("thin"), AlignX.RIGHT, RGB.WHITE); rbTxP = new TextPainter(Res.getFont("tiny"), AlignX.RIGHT, RGB.WHITE);
txt.setRect(txtRect); rbTxP.setRect(rbTxRect);
txt.setShadow(RGB.BLACK_60, txt.getRect().height().div(8).toVectXY()); rbTxP.setShadow(RGB.BLACK_70, rbTxP.getRect().height().div(7).toVectXY());
//@formatter:off
this.rtTxRect = uiRect.topEdge()
.growDown(uiRect.height().perc(30)).cached();
//@formatter:on
rtTxP = new TextPainter(Res.getFont("tiny"), AlignX.RIGHT, RGB.GREEN);
rtTxP.setRect(rtTxRect);
rtTxP.setShadow(RGB.BLACK_70, rtTxP.getRect().height().div(7).toVectXY());
setAction(new Action() { setAction(new Action() {
@@ -76,8 +93,10 @@ public class InvSlot extends ClickableComponent {
@Override @Override
public void updateLayout() public void updateLayout()
{ {
uiRect.poll();
itemRect.poll(); itemRect.poll();
txtRect.poll(); rbTxRect.poll();
rtTxRect.poll();
} }
@@ -100,18 +119,28 @@ public class InvSlot extends ClickableComponent {
if (itm != null && !itm.isEmpty()) { if (itm != null && !itm.isEmpty()) {
itm.render(itemRect); itm.render(itemRect);
if (itm.getAmount() > 1) { if (itm.getAmount() > 1) {
txt.setText("" + itm.getAmount()); rbTxP.setText("" + itm.getAmount());
txt.setColor(RGB.WHITE); rbTxP.setColor(RGB.WHITE);
txt.render(); rbTxP.render();
} }
if (pl.getSelectedWeapon() == index) { if (pl.getSelectedWeaponIndex() == index) {
txt.setText("*"); rbTxP.setText("*");
txt.setColor(RGB.YELLOW); rbTxP.setColor(RGB.YELLOW);
txt.render(); rbTxP.render();
} }
if (itm.getType() == ItemType.FOOD) {
rtTxP.setText(Calc.toString(itm.getFoodPoints() / 2D));
rbTxP.setColor(RGB.GREEN);
rtTxP.render();
} else if (itm.getType() == ItemType.WEAPON) {
int atk = itm.getAttackPoints();
rtTxP.setText((atk >= 0 ? "+" : "") + atk);
rtTxP.setColor(RGB.CYAN);
rtTxP.render();
}
} }
} }
@@ -40,6 +40,8 @@ public class NavButton extends ClickableComponent {
bg = base; bg = base;
} }
if(!isEnabled()) bg = base; // override effects
Render.quadTextured(this, bg); Render.quadTextured(this, bg);
Render.quadTextured(this, fg); Render.quadTextured(this, fg);
} }
@@ -9,6 +9,7 @@ import mightypork.gamecore.gui.ActionGroup;
import mightypork.gamecore.gui.screens.LayeredScreen; import mightypork.gamecore.gui.screens.LayeredScreen;
import mightypork.gamecore.input.KeyStroke; import mightypork.gamecore.input.KeyStroke;
import mightypork.gamecore.input.Keys; import mightypork.gamecore.input.Keys;
import mightypork.rogue.Config;
import mightypork.rogue.world.WorldProvider; import mightypork.rogue.world.WorldProvider;
import mightypork.rogue.world.events.WorldPauseRequest; import mightypork.rogue.world.events.WorldPauseRequest;
import mightypork.rogue.world.events.WorldPauseRequest.PauseAction; import mightypork.rogue.world.events.WorldPauseRequest.PauseAction;
@@ -26,7 +27,6 @@ public class ScreenGame extends LayeredScreen {
WORLD, INV; WORLD, INV;
} }
private final Random rand = new Random(); private final Random rand = new Random();
private InvLayer invLayer; private InvLayer invLayer;
private HudLayer hudLayer; private HudLayer hudLayer;
@@ -102,12 +102,14 @@ public class ScreenGame extends LayeredScreen {
getEventBus().send(new WorldPauseRequest(PauseAction.RESUME)); getEventBus().send(new WorldPauseRequest(PauseAction.RESUME));
invLayer.setVisible(false); // hide all extra layers invLayer.setVisible(false); // hide all extra layers
invLayer.enable(false);
worldActions.enable(true); worldActions.enable(true);
} }
if (nstate == GScrState.INV) { if (nstate == GScrState.INV) {
invLayer.setVisible(true); invLayer.setVisible(true);
invLayer.enable(true);
} }
this.state = nstate; this.state = nstate;
@@ -120,13 +122,20 @@ public class ScreenGame extends LayeredScreen {
} }
public ScreenGame(AppAccess app) public ScreenGame(AppAccess app) {
{
super(app); super(app);
addLayer(invLayer = new InvLayer(this)); addLayer(invLayer = new InvLayer(this));
invLayer.enable(false);
invLayer.setVisible(false);
addLayer(hudLayer = new HudLayer(this)); addLayer(hudLayer = new HudLayer(this));
hudLayer.enable(true);
hudLayer.setVisible(true);
addLayer(worldLayer = new WorldLayer(this)); addLayer(worldLayer = new WorldLayer(this));
worldLayer.enable(true);
worldLayer.setVisible(true);
// TODO temporary here ↓ // TODO temporary here ↓
bindKey(new KeyStroke(Keys.L_CONTROL, Keys.N), new Runnable() { bindKey(new KeyStroke(Keys.L_CONTROL, Keys.N), new Runnable() {
@@ -147,6 +156,10 @@ public class ScreenGame extends LayeredScreen {
bindKey(new KeyStroke(Keys.M), actionToggleMinimap); bindKey(new KeyStroke(Keys.M), actionToggleMinimap);
bindKey(new KeyStroke(Keys.Z), actionToggleZoom); bindKey(new KeyStroke(Keys.Z), actionToggleZoom);
// add as actions - enableables.
worldActions.add(worldLayer);
worldActions.add(hudLayer);
worldActions.add(actionEat); worldActions.add(actionEat);
worldActions.add(actionInv); worldActions.add(actionInv);
worldActions.add(actionToggleMinimap); worldActions.add(actionToggleMinimap);
@@ -154,6 +167,16 @@ public class ScreenGame extends LayeredScreen {
worldActions.add(actionToggleZoom); worldActions.add(actionToggleZoom);
worldActions.enable(true); worldActions.enable(true);
// TMP TODO remove
bindKey(new KeyStroke(Keys.X), new Runnable() {
@Override
public void run()
{
Config.RENDER_UFOG ^= true;
}
});
} }
@@ -0,0 +1,62 @@
package mightypork.rogue.screens.game;
import java.util.Collection;
import mightypork.gamecore.gui.AlignX;
import mightypork.gamecore.gui.components.BaseComponent;
import mightypork.gamecore.gui.components.painters.TextPainter;
import mightypork.gamecore.resources.fonts.FontRenderer;
import mightypork.gamecore.util.math.color.Color;
import mightypork.gamecore.util.math.color.pal.RGB;
import mightypork.gamecore.util.math.constraints.num.Num;
import mightypork.gamecore.util.math.constraints.num.mutable.NumVar;
import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.rogue.Res;
import mightypork.rogue.world.WorldConsole;
import mightypork.rogue.world.WorldConsole.Entry;
import mightypork.rogue.world.WorldProvider;
public class WorldConsoleRenderer extends BaseComponent {
private final Num rowHeight;
private final FontRenderer fr;
public WorldConsoleRenderer(Num rowHeight) {
this.rowHeight = rowHeight;
this.fr = new FontRenderer(Res.getFont("tiny"));
}
@Override
protected void renderComponent()
{
double rh = rowHeight.value();
Rect lowRow = bottomEdge().growUp(rowHeight);
Collection<Entry> entries = WorldProvider.get().getWorld().getConsole().getEntries();
int cnt = 0;
NumVar alph = Num.makeVar();
Color.pushAlpha(alph);
for (WorldConsole.Entry entry : entries) {
alph.setTo(entry.getAlpha());
Rect rrr = lowRow.moveY(-rh * cnt);
fr.draw(entry.getMessage(), rrr.move(rh / 12, rh / 12), AlignX.LEFT, RGB.BLACK_60);
fr.draw(entry.getMessage(), rrr, AlignX.LEFT, RGB.WHITE);
cnt++;
}
Color.popAlpha();
}
}
@@ -4,7 +4,7 @@ package mightypork.rogue.screens.test_bouncyboxes;
import java.util.Random; import java.util.Random;
import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.eventbus.events.Updateable;
import mightypork.gamecore.gui.components.VisualComponent; import mightypork.gamecore.gui.components.BaseComponent;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;
import mightypork.gamecore.util.math.Easing; import mightypork.gamecore.util.math.Easing;
import mightypork.gamecore.util.math.color.pal.RGB; import mightypork.gamecore.util.math.color.pal.RGB;
@@ -14,7 +14,7 @@ import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.rect.caching.RectCache; import mightypork.gamecore.util.math.constraints.rect.caching.RectCache;
public class BouncyBox extends VisualComponent implements Updateable { public class BouncyBox extends BaseComponent implements Updateable {
private final Random rand = new Random(); private final Random rand = new Random();
+19 -6
View File
@@ -16,14 +16,12 @@ public class Inventory implements IonObjBinary {
private Item[] items; private Item[] items;
public Inventory(int size) public Inventory(int size) {
{
this.items = new Item[size]; this.items = new Item[size];
} }
public Inventory() public Inventory() {
{
// ION constructor // ION constructor
} }
@@ -154,6 +152,19 @@ public class Inventory implements IonObjBinary {
} }
/**
* Clean empty items
*/
public void clean()
{
for (int i = 0; i < getSize(); i++) {
Item itm = getItem(i);
if (itm == null) continue;
if (itm.isEmpty()) setItem(i, null);
}
}
@Override @Override
public String toString() public String toString()
{ {
@@ -164,8 +175,10 @@ public class Inventory implements IonObjBinary {
s += i + ": "; s += i + ": ";
final Item itm = getItem(i); final Item itm = getItem(i);
if (itm == null) s += "<null>"; if (itm == null)
else s += itm; s += "<null>";
else
s += itm;
} }
s += "]"; s += "]";
return s; return s;
+10 -7
View File
@@ -99,20 +99,26 @@ public abstract class PlayerControl {
*/ */
public boolean clickTile(Step side) public boolean clickTile(Step side)
{ {
return clickTile(getPlayer().getCoord().add(side).toVect().add(0.5, 0.5)); return doClickTile(getPlayer().getCoord().add(side).toVect());
} }
public boolean clickTile(Vect pos) public boolean clickTile(Vect pos)
{ {
//if (pos.dist(getPlayer().getVisualPos()).value() > 8) return false; // too far
if (pos.dist(getPlayer().getVisualPos().add(0.5, 0.5)).value() < 1.5) { if (pos.dist(getPlayer().getVisualPos().add(0.5, 0.5)).value() < 1.5) {
return doClickTile(pos);
}
return false;
}
private boolean doClickTile(Vect pos)
{
// 1st try to hit entity // 1st try to hit entity
final Entity prey = getLevel().getClosestEntity(pos, EntityType.MONSTER, 1); final Entity prey = getLevel().getClosestEntity(pos, EntityType.MONSTER, 1);
if (prey != null) { if (prey != null) {
prey.receiveAttack(getPlayer().getEntity(), getPlayer().getAttackStrength()); getPlayer().attack(prey);
return true; return true;
} }
@@ -120,9 +126,6 @@ public abstract class PlayerControl {
return getLevel().getTile(Coord.fromVect(pos)).onClick(); return getLevel().getTile(Coord.fromVect(pos)).onClick();
} }
return false;
}
public void go(Step side) public void go(Step side)
{ {
+5 -1
View File
@@ -19,7 +19,7 @@ public class PlayerInfo implements IonObjBundled {
private static final int INV_SIZE = 8; private static final int INV_SIZE = 8;
/** Constant indicating that no weapon is selected. */ /** Constant indicating that no weapon is selected. */
private static final int NO_WEAPON = -1; public static final int NO_WEAPON = -1;
/** Attack str with bare hands */ /** Attack str with bare hands */
public static final int BARE_ATTACK = 1; public static final int BARE_ATTACK = 1;
@@ -106,6 +106,10 @@ public class PlayerInfo implements IonObjBundled {
public void selectWeapon(int selectedWeapon) public void selectWeapon(int selectedWeapon)
{ {
if(selectedWeapon<0||selectedWeapon>=getInventory().getSize()) {
selectedWeapon = NO_WEAPON;
}
this.selectedWeapon = selectedWeapon; this.selectedWeapon = selectedWeapon;
} }
+214 -13
View File
@@ -2,15 +2,15 @@ package mightypork.rogue.world;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Random;
import mightypork.gamecore.eventbus.BusAccess; import mightypork.gamecore.eventbus.BusAccess;
import mightypork.gamecore.eventbus.EventBus; import mightypork.gamecore.eventbus.EventBus;
import mightypork.gamecore.eventbus.clients.DelegatingClient; import mightypork.gamecore.eventbus.clients.DelegatingClient;
import mightypork.gamecore.eventbus.events.Updateable;
import mightypork.gamecore.util.ion.IonBundle; import mightypork.gamecore.util.ion.IonBundle;
import mightypork.gamecore.util.ion.IonObjBundled; import mightypork.gamecore.util.ion.IonObjBundled;
import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.algo.Coord;
import mightypork.gamecore.util.math.algo.Step; import mightypork.gamecore.util.math.algo.Step;
import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.gamecore.util.math.constraints.vect.Vect;
@@ -27,7 +27,7 @@ import mightypork.rogue.world.level.Level;
* *
* @author MightyPork * @author MightyPork
*/ */
public class World implements DelegatingClient, BusAccess, IonObjBundled, Pauseable { public class World implements DelegatingClient, BusAccess, IonObjBundled, Pauseable, Updateable {
/** /**
* Convenient access to player-related methods and data * Convenient access to player-related methods and data
@@ -36,7 +36,6 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
*/ */
public class PlayerFacade { public class PlayerFacade {
public boolean canAscend() public boolean canAscend()
{ {
return playerInfo.getLevelNumber() > 0; return playerInfo.getLevelNumber() > 0;
@@ -52,8 +51,11 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
playerInfo.setLevelNumber(lvl_num + 1); playerInfo.setLevelNumber(lvl_num + 1);
getLevel().forceFreeTile(getLevel().getEnterPoint());
getLevel().addEntity(playerEntity, getLevel().getEnterPoint()); getLevel().addEntity(playerEntity, getLevel().getEnterPoint());
getLevel().explore(getCoord()); getLevel().explore(getCoord());
msgEnterFloor(getLevelNumber());
} }
@@ -72,8 +74,11 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
playerInfo.setLevelNumber(lvl_num - 1); playerInfo.setLevelNumber(lvl_num - 1);
getLevel().forceFreeTile(getLevel().getExitPoint());
getLevel().addEntity(playerEntity, getLevel().getExitPoint()); getLevel().addEntity(playerEntity, getLevel().getExitPoint());
getLevel().explore(getCoord()); getLevel().explore(getCoord());
msgEnterFloor(getLevelNumber());
} }
@@ -176,10 +181,16 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
if (weapon == null) return PlayerInfo.BARE_ATTACK; if (weapon == null) return PlayerInfo.BARE_ATTACK;
return Math.min(weapon.getAttackPoints(), playerInfo.BARE_ATTACK); return PlayerInfo.BARE_ATTACK + weapon.getAttackPoints();
} }
/**
* Eat food.
*
* @param itm food item
* @return if something was eaten
*/
public boolean eatFood(Item itm) public boolean eatFood(Item itm)
{ {
if (itm == null || itm.isEmpty() || itm.getType() != ItemType.FOOD) return false; if (itm == null || itm.isEmpty() || itm.getType() != ItemType.FOOD) return false;
@@ -187,11 +198,13 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
if (getHealth() < getHealthMax()) { if (getHealth() < getHealthMax()) {
playerEntity.health.addHealth(itm.getFoodPoints()); playerEntity.health.addHealth(itm.getFoodPoints());
itm.consume();
msgEat(itm);
return true; return true;
} }
return false; return false;
} }
@@ -202,7 +215,13 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
} }
public int getSelectedWeapon() public Item getSelectedWeapon()
{
return playerInfo.getSelectedWeapon();
}
public int getSelectedWeaponIndex()
{ {
return playerInfo.getSelectedWeaponIndex(); return playerInfo.getSelectedWeaponIndex();
} }
@@ -210,17 +229,122 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
public void tryToEatSomeFood() public void tryToEatSomeFood()
{ {
List<Item> foods = new ArrayList<>();
for (int i = 0; i < getInventory().getSize(); i++) { for (int i = 0; i < getInventory().getSize(); i++) {
final Item itm = getInventory().getItem(i); final Item itm = getInventory().getItem(i);
if (itm == null || itm.isEmpty()) continue; if (itm != null && itm.getType() == ItemType.FOOD) {
foods.add(itm);
}
}
final Item slice = itm.split(1); // sort from smallest to biggest foods
if (!eatFood(slice)) itm.addItem(slice); Collections.sort(foods, new Comparator<Item>() {
if (itm.isEmpty()) getInventory().setItem(i, null);
@Override
public int compare(Item o1, Item o2)
{
return (o1.getFoodPoints() - o2.getFoodPoints());
}
});
for (Item itm : foods) {
if (eatFood(itm)) {
getInventory().clean();
return; return;
} }
} }
msgNoMoreFood();
}
public void attack(Entity prey)
{
int attackPoints = getAttackStrength();
prey.receiveAttack(getPlayer().getEntity(), attackPoints);
if (prey.isDead()) {
msgKill(prey);
}
Item wpn = getSelectedWeapon();
if (wpn != null) {
wpn.use();
if (wpn.isEmpty()) {
msgWeaponBreak(wpn);
getInventory().clean();
selectWeapon(-1);
pickBestWeaponIfNoneSelected();
}
}
}
private void pickBestWeaponIfNoneSelected()
{
if (getSelectedWeapon() != null) return;
List<Item> wpns = new ArrayList<>();
for (int i = 0; i < getInventory().getSize(); i++) {
final Item itm = getInventory().getItem(i);
if (itm != null && itm.getType() == ItemType.WEAPON) {
wpns.add(itm);
}
}
// sort from smallest to biggest foods
Collections.sort(wpns, new Comparator<Item>() {
@Override
public int compare(Item o1, Item o2)
{
return (o2.getAttackPoints() - o1.getAttackPoints());
}
});
for (Item itm : wpns) {
for (int i = 0; i < getInventory().getSize(); i++) {
final Item itm2 = getInventory().getItem(i);
if (itm2 == itm) {
selectWeapon(i);
break;
}
}
break; // just one cycle
}
msgEquipWeapon(getSelectedWeapon());
}
public boolean addItem(Item item)
{
if (!getInventory().addItem(item)) {
msgCannotPick();
return false;
}
msgPick(item);
if (item.getType() == ItemType.WEAPON) {
if (getSelectedWeapon() != null) {
if (item.getAttackPoints() > getSelectedWeapon().getAttackPoints()) {
selectWeapon(-1); // unselect to grab the best one
}
}
pickBestWeaponIfNoneSelected();
}
return true;
}
} }
// not saved stuffs // not saved stuffs
@@ -229,10 +353,10 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
private BusAccess bus; private BusAccess bus;
private int pauseDepth = 0; private int pauseDepth = 0;
private final ArrayList<Level> levels = new ArrayList<>(); private final ArrayList<Level> levels = new ArrayList<>();
private final PlayerInfo playerInfo = new PlayerInfo(); private final PlayerInfo playerInfo = new PlayerInfo();
private final WorldConsole console = new WorldConsole();
/** World seed */ /** World seed */
private long seed; private long seed;
@@ -342,6 +466,8 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
playerInfo.setLevelNumber(0); playerInfo.setLevelNumber(0);
playerInfo.setEID(playerEid); playerInfo.setEID(playerEid);
msgEnterFloor(0);
} }
@@ -390,4 +516,79 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
return player; return player;
} }
@Override
public void update(double delta)
{
if (isPaused()) return;
// update console timing
console.update(delta);
}
public WorldConsole getConsole()
{
return console;
}
public void msgPick(Item item)
{
console.addMessage("You've picked a " + item.getVisualName() + ".");
}
public void msgWeaponBreak(Item item)
{
console.addMessage("Your " + item.getVisualName() + " has broken!");
}
public void msgEquipWeapon(Item item)
{
console.addMessage("You're now wielding " + (item == null ? "NOTHING" : "a " + item.getVisualName()) + ".");
}
public void msgEat(Item item)
{
console.addMessage("You've eaten a " + item.getVisualName() + ".");
}
public void msgKill(Entity prey)
{
console.addMessage("You've killed a " + prey.getVisualName() + ".");
}
public void msgDie(Entity attacker)
{
console.addMessage("You've been defeated by a " + attacker.getVisualName() + "!");
}
public void msgDiscoverSecretDoor()
{
console.addMessage("You've discovered a secret door.");
}
public void msgNoMoreFood()
{
console.addMessage("You have no more food!");
}
public void msgCannotPick()
{
console.addMessage("Inventory is full.");
}
public void msgEnterFloor(int floor)
{
console.addMessage("~ " + Calc.ordinal(floor + 1) + " floor ~");
}
} }
@@ -0,0 +1,103 @@
package mightypork.rogue.world;
import java.util.*;
import mightypork.gamecore.eventbus.events.Updateable;
import mightypork.gamecore.util.math.Easing;
import mightypork.gamecore.util.math.constraints.num.mutable.NumAnimated;
public class WorldConsole implements Updateable {
private static final double DURATION = 5;
public class Entry implements Updateable {
private final String text;
private final NumAnimated fadeout;
private boolean fading = false;
private double elapsed = 0;
private Entry(String text) {
this.text = text;
this.fadeout = new NumAnimated(1, Easing.LINEAR);
this.fadeout.setDefaultDuration(0.5);
}
@Override
public void update(double delta)
{
elapsed += delta;
if (fading) {
fadeout.update(delta);
return;
}
if (elapsed > DURATION) {
fading = true;
fadeout.fadeOut();
}
}
private boolean canRemove()
{
return fading && fadeout.isFinished();
}
public double getAlpha()
{
return !fading ? 1 : fadeout.value();
}
public String getMessage()
{
return text;
}
public double getAge()
{
return elapsed;
}
}
private final Deque<Entry> entries = new LinkedList<>();
@Override
public void update(double delta)
{
for (Iterator<Entry> iter = entries.iterator(); iter.hasNext();) {
Entry e = iter.next();
e.update(delta);
if (e.canRemove()) {
iter.remove();
}
}
}
public void addMessage(String message)
{
entries.addFirst(new Entry(message));
}
public Collection<Entry> getEntries()
{
return entries;
}
public void clear() {
entries.clear();
}
}
+1 -1
View File
@@ -20,7 +20,7 @@ public class WorldCreator {
final World w = new World(); final World w = new World();
w.setSeed(seed); w.setSeed(seed);
final int count = 6; final int count = 7;
for (int i = 1; i <= count; i++) { for (int i = 1; i <= count; i++) {
final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME, i == count); final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME, i == count);
@@ -14,10 +14,10 @@ import mightypork.gamecore.util.ion.IonBundle;
import mightypork.gamecore.util.ion.IonObjBundled; import mightypork.gamecore.util.ion.IonObjBundled;
import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.algo.Coord;
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder; import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
import mightypork.rogue.Config;
import mightypork.rogue.world.World; import mightypork.rogue.world.World;
import mightypork.rogue.world.entity.modules.EntityModuleHealth; import mightypork.rogue.world.entity.modules.EntityModuleHealth;
import mightypork.rogue.world.entity.modules.EntityModulePosition; import mightypork.rogue.world.entity.modules.EntityModulePosition;
import mightypork.rogue.world.entity.render.EntityRenderer;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.level.render.MapRenderContext; import mightypork.rogue.world.level.render.MapRenderContext;
@@ -43,6 +43,7 @@ public abstract class Entity implements IonObjBundled, Updateable {
public final EntityModulePosition pos = new EntityModulePosition(this); public final EntityModulePosition pos = new EntityModulePosition(this);
public final EntityModuleHealth health = new EntityModuleHealth(this); public final EntityModuleHealth health = new EntityModuleHealth(this);
private double despawnDelay = 1; private double despawnDelay = 1;
protected Entity lastAttacker;
public Entity(EntityModel model, int eid) public Entity(EntityModel model, int eid)
@@ -154,7 +155,7 @@ public abstract class Entity implements IonObjBundled, Updateable {
@DefaultImpl @DefaultImpl
public final void render(MapRenderContext context) public final void render(MapRenderContext context)
{ {
if (context.getTile(getCoord()).isExplored()) { if (context.getTile(getCoord()).isExplored() || !Config.RENDER_UFOG) {
getRenderer().render(context); getRenderer().render(context);
} }
} }
@@ -244,6 +245,7 @@ public abstract class Entity implements IonObjBundled, Updateable {
*/ */
public void receiveAttack(Entity attacker, int attackStrength) public void receiveAttack(Entity attacker, int attackStrength)
{ {
this.lastAttacker = attacker;
health.receiveDamage(attackStrength); health.receiveDamage(attackStrength);
} }
@@ -264,4 +266,5 @@ public abstract class Entity implements IonObjBundled, Updateable {
return despawnDelay; return despawnDelay;
} }
public abstract String getVisualName();
} }
@@ -1,4 +1,4 @@
package mightypork.rogue.world.entity.render; package mightypork.rogue.world.entity;
import mightypork.rogue.world.level.render.MapRenderContext; import mightypork.rogue.world.level.render.MapRenderContext;
@@ -94,9 +94,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
{ {
if (entity.isDead()) return; if (entity.isDead()) return;
//System.out.println("monster ai step finished.");
if (chasing) { if (chasing) {
//System.out.println("chasing..");
final Entity prey = getPreyEntity(); final Entity prey = getPreyEntity();
if (!isPreyValid(prey)) { if (!isPreyValid(prey)) {
stopChasing(); stopChasing();
@@ -283,7 +281,6 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
return; return;
} }
//System.out.println("step to prey");
entity.pos.cancelPath(); entity.pos.cancelPath();
entity.pos.addSteps(preyPath); entity.pos.addSteps(preyPath);
} }
@@ -3,13 +3,8 @@ package mightypork.rogue.world.entity.entities;
import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.algo.Coord;
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder; import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.*;
import mightypork.rogue.world.entity.EntityModel;
import mightypork.rogue.world.entity.EntityModule;
import mightypork.rogue.world.entity.EntityPathFinder;
import mightypork.rogue.world.entity.EntityType;
import mightypork.rogue.world.entity.modules.EntityMoveListener; import mightypork.rogue.world.entity.modules.EntityMoveListener;
import mightypork.rogue.world.entity.render.EntityRenderer;
import mightypork.rogue.world.entity.render.EntityRendererMobLR; import mightypork.rogue.world.entity.render.EntityRendererMobLR;
import mightypork.rogue.world.events.PlayerKilledEvent; import mightypork.rogue.world.events.PlayerKilledEvent;
import mightypork.rogue.world.events.PlayerStepEndEvent; import mightypork.rogue.world.events.PlayerStepEndEvent;
@@ -21,8 +16,7 @@ public class PlayerEntity extends Entity {
class PlayerAi extends EntityModule implements EntityMoveListener { class PlayerAi extends EntityModule implements EntityMoveListener {
public PlayerAi(Entity entity) public PlayerAi(Entity entity) {
{
super(entity); super(entity);
setDespawnDelay(2); setDespawnDelay(2);
@@ -43,7 +37,7 @@ public class PlayerEntity extends Entity {
final Tile t = getLevel().getTile(getCoord()); final Tile t = getLevel().getTile(getCoord());
if (t.hasItem()) { if (t.hasItem()) {
final Item item = t.pickItem(); final Item item = t.pickItem();
if (getWorld().getPlayer().getInventory().addItem(item)) { if (getWorld().getPlayer().addItem(item)) {
// player picked item // player picked item
} else { } else {
t.dropItem(item); // put back. t.dropItem(item); // put back.
@@ -85,8 +79,7 @@ public class PlayerEntity extends Entity {
private final PlayerAi ai = new PlayerAi(this); private final PlayerAi ai = new PlayerAi(this);
public PlayerEntity(EntityModel model, int eid) public PlayerEntity(EntityModel model, int eid) {
{
super(model, eid); super(model, eid);
pos.setStepTime(0.25); pos.setStepTime(0.25);
@@ -141,5 +134,15 @@ public class PlayerEntity extends Entity {
{ {
// send kill event to listeners, after the entity has despawned (disappeared) // send kill event to listeners, after the entity has despawned (disappeared)
getWorld().getEventBus().sendDelayed(new PlayerKilledEvent(), getDespawnDelay()); getWorld().getEventBus().sendDelayed(new PlayerKilledEvent(), getDespawnDelay());
getWorld().msgDie(lastAttacker);
}
@Override
public String getVisualName()
{
return "Player";
} }
} }
@@ -1,14 +1,14 @@
package mightypork.rogue.world.entity.entities; package mightypork.rogue.world.entity.entities;
import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder; import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.entity.EntityModel; import mightypork.rogue.world.entity.EntityModel;
import mightypork.rogue.world.entity.EntityPathFinder; import mightypork.rogue.world.entity.EntityPathFinder;
import mightypork.rogue.world.entity.EntityRenderer;
import mightypork.rogue.world.entity.EntityType; import mightypork.rogue.world.entity.EntityType;
import mightypork.rogue.world.entity.render.EntityRenderer;
import mightypork.rogue.world.entity.render.EntityRendererMobLR; import mightypork.rogue.world.entity.render.EntityRendererMobLR;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.item.Items; import mightypork.rogue.world.item.Items;
@@ -22,8 +22,7 @@ public class RatEntity extends Entity {
private EntityRenderer renderer; private EntityRenderer renderer;
public RatEntity(EntityModel model, int eid) public RatEntity(EntityModel model, int eid) {
{
super(model, eid); super(model, eid);
addModule("ai", ai); addModule("ai", ai);
@@ -32,8 +31,8 @@ public class RatEntity extends Entity {
pos.setStepTime(0.5); pos.setStepTime(0.5);
setDespawnDelay(1); setDespawnDelay(1);
health.setMaxHealth(3 + rand.nextInt(3)); health.setMaxHealth(5);
health.fill(); // fill health bar to max health.setHealth(Calc.randInt(rand, 3, 5)); // fill health bar to max
health.setHitCooldownTime(0.3); health.setHitCooldownTime(0.3);
} }
@@ -77,10 +76,27 @@ public class RatEntity extends Entity {
@Override @Override
public void onCorpseRemoved() public void onCorpseRemoved()
{ {
// drop rat meat // drop rat stuff
final Item meat = Items.MEAT.createItem();
getLevel().dropNear(getCoord(), meat); if(rand.nextInt(7) == 0) {
getLevel().dropNear(getCoord(), Items.BONE.createItem());
return;
} }
if(rand.nextInt(3) == 0) {
getLevel().dropNear(getCoord(), Items.MEAT.createItem());
return;
}
if(rand.nextInt(2) == 0) {
getLevel().dropNear(getCoord(), Items.CHEESE.createItem());
return;
}
}
@Override
public String getVisualName()
{
return "Gray Rat";
}
} }
@@ -13,6 +13,7 @@ import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.gamecore.util.math.constraints.vect.Vect;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.entity.EntityRenderer;
import mightypork.rogue.world.level.render.MapRenderContext; import mightypork.rogue.world.level.render.MapRenderContext;
@@ -10,6 +10,7 @@ import mightypork.rogue.world.entity.Entities;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.gen.rooms.Rooms; import mightypork.rogue.world.gen.rooms.Rooms;
import mightypork.rogue.world.gen.themes.ThemeBrick; import mightypork.rogue.world.gen.themes.ThemeBrick;
import mightypork.rogue.world.item.Items;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
@@ -18,6 +19,7 @@ public class LevelGenerator {
public static final MapTheme DUNGEON_THEME = new ThemeBrick(); public static final MapTheme DUNGEON_THEME = new ThemeBrick();
@SuppressWarnings("fallthrough")
public static Level build(World world, long seed, int complexity, MapTheme theme, boolean lastLevel) public static Level build(World world, long seed, int complexity, MapTheme theme, boolean lastLevel)
{ {
Log.f3("Generating level of complexity: " + complexity); Log.f3("Generating level of complexity: " + complexity);
@@ -31,16 +33,34 @@ public class LevelGenerator {
// start // start
map.addRoom(Rooms.ENTRANCE, true); map.addRoom(Rooms.ENTRANCE, true);
for (int i = 0; i < 1 + complexity / 2 + rand.nextInt((int) (1 + complexity * 0.3)); i++) { for (int i = 0; i < 1 + complexity / 2 + rand.nextInt((int) (1 + complexity * 0.2)); i++) {
map.addRoom(Rooms.BASIC, false); map.addRoom(Rooms.BASIC, false);
if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET, false); if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET, false);
if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END, false); if (rand.nextInt(7) > 0) map.addRoom(Rooms.DEAD_END, false);
} }
if (!lastLevel) map.addRoom(Rooms.EXIT, true); if (!lastLevel) map.addRoom(Rooms.EXIT, true);
map.buildCorridors(); map.buildCorridors();
switch(complexity) {
default:
case 3:
case 2:
if(rand.nextInt(2)==0) map.dropInMap(Items.CLUB.createItem(), 50);
case 1:
case 0:
if(rand.nextInt(2)==0) map.dropInMap(Items.ROCK.createItem(), 50);
}
if(complexity == 6) {
map.dropInMap(Items.SWORD.createItem(), 200);
}
if(complexity == 5) {
map.dropInMap(Items.HAMMER.createItem(), 100);
}
final Coord size = map.getNeededSize(); final Coord size = map.getNeededSize();
final Level lvl = new Level(size.x, size.y); final Level lvl = new Level(size.x, size.y);
@@ -49,6 +69,8 @@ public class LevelGenerator {
// TODO tmp // TODO tmp
// spawn rats // spawn rats
// TODO entities in ScratchMap itself
final Coord pos = Coord.make(0, 0); final Coord pos = Coord.make(0, 0);
for (int i = 0; i < 3 + complexity + rand.nextInt(1 + complexity); i++) { for (int i = 0; i < 3 + complexity + rand.nextInt(1 + complexity); i++) {
@@ -62,20 +84,6 @@ public class LevelGenerator {
} }
} }
// for (int i = 0; i < 4 + complexity + rand.nextInt(1 + complexity); i++) {
//
// final Item meat = Items.MEAT.createItem();
//
// for (int j = 0; j < 20; j++) {
// pos.x = rand.nextInt(lvl.getWidth());
// pos.y = rand.nextInt(lvl.getHeight());
//
// final Tile t = lvl.getTile(pos);
// if (t.dropItem(meat)) break;
// }
// }
return lvl; return lvl;
} }
} }
+35 -13
View File
@@ -14,6 +14,7 @@ import mightypork.gamecore.util.math.algo.Sides;
import mightypork.gamecore.util.math.algo.Step; import mightypork.gamecore.util.math.algo.Step;
import mightypork.gamecore.util.math.algo.pathfinding.Heuristic; import mightypork.gamecore.util.math.algo.pathfinding.Heuristic;
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder; import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
@@ -42,7 +43,7 @@ public class ScratchMap {
public boolean isAccessible(Coord pos) public boolean isAccessible(Coord pos)
{ {
if (!isIn(pos)) return false; if (!isIn(pos)) return false;
final Tile t = get(pos); final Tile t = getTile(pos);
if (t.isStairs()) return false; if (t.isStairs()) return false;
return t.isPotentiallyWalkable() || (t.genData.protection != TileProtectLevel.STRONG); return t.isPotentiallyWalkable() || (t.genData.protection != TileProtectLevel.STRONG);
} }
@@ -51,7 +52,7 @@ public class ScratchMap {
@Override @Override
public int getCost(Coord last, Coord pos) public int getCost(Coord last, Coord pos)
{ {
final Tile t = get(pos); final Tile t = getTile(pos);
switch (t.getType()) { switch (t.getType()) {
case NULL: case NULL:
@@ -173,7 +174,7 @@ public class ScratchMap {
clampBounds(); clampBounds();
nodes.add(center); nodes.add(center);
// Log.f3("placed room: " + rd.min + " -> " + rd.max); Log.f3("Placed room on " + Calc.ordinal(1+failed_total) + " try.");
return; return;
} else { } else {
@@ -222,7 +223,7 @@ public class ScratchMap {
} }
public Tile get(Coord pos) public Tile getTile(Coord pos)
{ {
if (!isIn(pos)) { if (!isIn(pos)) {
throw new IndexOutOfBoundsException("Tile not in map: " + pos); throw new IndexOutOfBoundsException("Tile not in map: " + pos);
@@ -267,7 +268,7 @@ public class ScratchMap {
final Coord c = Coord.make(0, 0); final Coord c = Coord.make(0, 0);
for (c.x = min.x; c.x <= max.x; c.x++) for (c.x = min.x; c.x <= max.x; c.x++)
for (c.y = min.y; c.y <= max.y; c.y++) for (c.y = min.y; c.y <= max.y; c.y++)
get(c).genData.protection = prot; getTile(c).genData.protection = prot;
} }
@@ -357,7 +358,7 @@ public class ScratchMap {
genMax.y = Math.max(genMax.y, c.y); genMax.y = Math.max(genMax.y, c.y);
clampBounds(); clampBounds();
final Tile current = get(c); final Tile current = getTile(c);
if (!current.isNull() && (current.isPotentiallyWalkable() || current.isStairs())) continue; // floor already, let it be if (!current.isNull() && (current.isPotentiallyWalkable() || current.isStairs())) continue; // floor already, let it be
if (i == 0 && j == 0) { if (i == 0 && j == 0) {
@@ -394,7 +395,7 @@ public class ScratchMap {
final Coord cc = pos.add(Sides.get(i)); final Coord cc = pos.add(Sides.get(i));
if (!isIn(cc)) continue; if (!isIn(cc)) continue;
if (get(cc).isWall()) { if (getTile(cc).isWall()) {
walls |= Sides.bit(i); walls |= Sides.bit(i);
} }
} }
@@ -409,7 +410,7 @@ public class ScratchMap {
final Coord cc = pos.add(Sides.get(i)); final Coord cc = pos.add(Sides.get(i));
if (!isIn(cc)) continue; if (!isIn(cc)) continue;
if (get(cc).isFloor()) { if (getTile(cc).isFloor()) {
floors |= Sides.bit(i); floors |= Sides.bit(i);
} }
} }
@@ -424,7 +425,7 @@ public class ScratchMap {
final Coord cc = pos.add(Sides.get(i)); final Coord cc = pos.add(Sides.get(i));
if (!isIn(cc)) continue; if (!isIn(cc)) continue;
if (get(cc).isDoor()) { if (getTile(cc).isDoor()) {
doors |= Sides.bit(i); doors |= Sides.bit(i);
} }
} }
@@ -438,7 +439,7 @@ public class ScratchMap {
for (int i = 0; i <= 7; i++) { for (int i = 0; i <= 7; i++) {
final Coord cc = pos.add(Sides.get(i)); final Coord cc = pos.add(Sides.get(i));
if (!isIn(cc) || get(cc).isNull()) { if (!isIn(cc) || getTile(cc).isNull()) {
nils |= Sides.bit(i); nils |= Sides.bit(i);
} }
} }
@@ -459,7 +460,7 @@ public class ScratchMap {
for (c.x = 0; c.x < width; c.x++) { for (c.x = 0; c.x < width; c.x++) {
for (c.y = 0; c.y < height; c.y++) { for (c.y = 0; c.y < height; c.y++) {
final Tile t = get(c); final Tile t = getTile(c);
final boolean isNull = t.isNull(); final boolean isNull = t.isNull();
final boolean isDoor = !isNull && t.isDoor(); final boolean isDoor = !isNull && t.isDoor();
@@ -533,13 +534,12 @@ public class ScratchMap {
for (c.x = genMin.x, c1.x = 0; c.x <= genMax.x; c.x++, c1.x++) { for (c.x = genMin.x, c1.x = 0; c.x <= genMax.x; c.x++, c1.x++) {
for (c.y = genMin.y, c1.y = 0; c.y <= genMax.y; c.y++, c1.y++) { for (c.y = genMin.y, c1.y = 0; c.y <= genMax.y; c.y++, c1.y++) {
level.setTile(c1, get(c)); level.setTile(c1, getTile(c));
} }
} }
final Coord entrance = new Coord(enterPoint.x - genMin.x, enterPoint.y - genMin.y); final Coord entrance = new Coord(enterPoint.x - genMin.x, enterPoint.y - genMin.y);
level.setEnterPoint(entrance); level.setEnterPoint(entrance);
// System.out.println("Entrance = " + entrance + ", original: " + enterPoint + ", minG=" + genMin + ", maxG=" + genMax);
final Coord exit = new Coord(exitPoint.x - genMin.x, exitPoint.y - genMin.y); final Coord exit = new Coord(exitPoint.x - genMin.x, exitPoint.y - genMin.y);
level.setExitPoint(exit); level.setExitPoint(exit);
@@ -556,4 +556,26 @@ public class ScratchMap {
{ {
exitPoint.setTo(pos); exitPoint.setTo(pos);
} }
public boolean dropInArea(Item item, Coord min, Coord max, int tries)
{
Coord pos = Coord.zero();
for(int i=0; i<tries; i++) {
pos.x = min.x+rand.nextInt(max.x-min.x);
pos.y = min.y+rand.nextInt(max.y-min.y);
Tile t = getTile(pos);
if(t.dropItem(item)) return true;
}
return false;
}
public void dropInMap(Item item, int tries)
{
dropInArea(item, genMin, genMax, tries);
}
} }
@@ -3,15 +3,17 @@ package mightypork.rogue.world.gen.rooms;
import java.util.Random; import java.util.Random;
import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.algo.Coord;
import mightypork.rogue.world.gen.MapTheme; import mightypork.rogue.world.gen.MapTheme;
import mightypork.rogue.world.gen.ScratchMap;
import mightypork.rogue.world.gen.TileProtectLevel; import mightypork.rogue.world.gen.TileProtectLevel;
import mightypork.rogue.world.item.Items;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
public class SecretRoom extends AbstractRectRoom { public class SecretRoom extends AbstractRectRoom {
@Override @Override
protected TileModel getDoorType(MapTheme theme, Random rand) protected TileModel getDoorType(MapTheme theme, Random rand)
{ {
@@ -33,6 +35,31 @@ public class SecretRoom extends AbstractRectRoom {
} }
@Override
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max)
{
for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) {
map.dropInArea(Items.SANDWICH.createItem(), min, max, 50);
}
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) {
map.dropInArea(Items.BONE.createItem(), min, max, 50);
}
for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) {
map.dropInArea(Items.ROCK.createItem(), min, max, 50);
}
for (int i = 0; i < Calc.randInt(rand, 0, 3); i++) {
map.dropInArea(Items.MEAT.createItem(), min, max, 50);
}
for (int i = 0; i < Calc.randInt(rand, 0, 3); i++) {
map.dropInArea(Items.CHEESE.createItem(), min, max, 50);
}
}
@Override @Override
protected Coord getInnerSize(Random rand) protected Coord getInnerSize(Random rand)
{ {
@@ -128,12 +128,14 @@ public class MapView extends InputComponent implements DelegatingClient, MouseBu
{ {
if (!event.isOver(this)) return; if (!event.isOver(this)) return;
if(event.isButtonEvent()) {
for (final MapInteractionPlugin p : plugins) { for (final MapInteractionPlugin p : plugins) {
if (p.onClick(event.getPos(), event.getButton(), event.isDown())) { if (p.onClick(event.getPos(), event.getButton(), event.isDown())) {
event.consume(); event.consume();
break; break;
} }
} }
}
if (event.isWheelEvent()) { if (event.isWheelEvent()) {
final int delta = event.getWheelDelta(); final int delta = event.getWheelDelta();
@@ -16,7 +16,8 @@ import mightypork.rogue.world.tile.Tile;
public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListener, Updateable { public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListener, Updateable {
private static final int BTN = 0; // left private static final int LEFT = 0; // left
private static final int RIGHT = 1; // left
public MIPMouse(MapView mapView) public MIPMouse(MapView mapView)
@@ -33,7 +34,7 @@ public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListe
final Vect pos = InputSystem.getMousePos(); final Vect pos = InputSystem.getMousePos();
if (!pos.isInside(mapView)) return; if (!pos.isInside(mapView)) return;
if (InputSystem.isMouseButtonDown(BTN)) { if (InputSystem.isMouseButtonDown(LEFT)) {
if (mouseWalk(pos)) return; if (mouseWalk(pos)) return;
if (mapView.plc.getPlayer().isMoving() && troToNav(pos)) return; if (mapView.plc.getPlayer().isMoving() && troToNav(pos)) return;
} }
@@ -43,22 +44,20 @@ public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListe
@Override @Override
public boolean onClick(Vect mouse, int button, boolean down) public boolean onClick(Vect mouse, int button, boolean down)
{ {
if (isImmobile()) return false; if (isImmobile()) {
return false;
}
final Vect pos = mapView.toWorldPos(mouse); final Vect pos = mapView.toWorldPos(mouse);
if (button == BTN && !down) { if (button == LEFT && !down) {
// try to click tile // try to click tile
System.out.println("---");
System.out.println("Standing at: " + getPlayer().getCoord() + ", visual " + getPlayer().getVisualPos());
System.out.println("Click tile: " + pos + ", floored: " + pos.floor());
if (mapView.plc.clickTile(pos)) return true; if (mapView.plc.clickTile(pos)) return true;
} }
final Tile t = mapView.plc.getLevel().getTile(Coord.fromVect(pos)); final Tile t = mapView.plc.getLevel().getTile(Coord.fromVect(pos));
if (button == 1 && !down && t.isWalkable()) { if (button == RIGHT && !down && t.isWalkable()) {
if (troToNav(mouse)) return true; if (troToNav(mouse)) return true;
return mouseWalk(mouse); return mouseWalk(mouse);
} }
@@ -122,7 +121,7 @@ public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListe
final Vect pos = InputSystem.getMousePos(); final Vect pos = InputSystem.getMousePos();
if (!pos.isInside(mapView)) return; if (!pos.isInside(mapView)) return;
if (InputSystem.isMouseButtonDown(BTN)) { if (InputSystem.isMouseButtonDown(LEFT)) {
if (mouseWalk(pos)) return; if (mouseWalk(pos)) return;
if (mapView.plc.getPlayer().isMoving() && troToNav(pos)) return; if (mapView.plc.getPlayer().isMoving() && troToNav(pos)) return;
} }
+29 -5
View File
@@ -2,12 +2,14 @@ package mightypork.rogue.world.item;
import java.io.IOException; import java.io.IOException;
import java.util.Random;
import mightypork.gamecore.logging.Log; import mightypork.gamecore.logging.Log;
import mightypork.gamecore.util.annot.DefaultImpl; import mightypork.gamecore.util.annot.DefaultImpl;
import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonObjBlob; import mightypork.gamecore.util.ion.IonObjBlob;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
@@ -16,6 +18,9 @@ public abstract class Item implements IonObjBlob {
private final ItemModel model; private final ItemModel model;
private ItemRenderer renderer; private ItemRenderer renderer;
private int amount = 1; private int amount = 1;
private int uses = 1;
protected static final Random rand = new Random();
public Item(ItemModel model) public Item(ItemModel model)
@@ -68,11 +73,11 @@ public abstract class Item implements IonObjBlob {
public boolean canStackWith(Item other) public boolean canStackWith(Item other)
{ {
return (getModel().id == other.getModel().id) && isStackable(); return (getModel().id == other.getModel().id);
} }
public abstract boolean isStackable(); protected abstract boolean isStackable();
/** /**
@@ -113,13 +118,11 @@ public abstract class Item implements IonObjBlob {
* *
* @return true if the item is fully consumed and should be removed. * @return true if the item is fully consumed and should be removed.
*/ */
public boolean consume() public void consume()
{ {
if (isEmpty()) throw new RuntimeException("Item is empty, cannot consume."); if (isEmpty()) throw new RuntimeException("Item is empty, cannot consume.");
amount--; amount--;
return isEmpty();
} }
@@ -157,4 +160,25 @@ public abstract class Item implements IonObjBlob {
{ {
return Log.str(getClass()) + " x " + getAmount(); return Log.str(getClass()) + " x " + getAmount();
} }
public int getRemainingUses() {
return uses;
}
public abstract int getMaxUses();
public void setRemainingUses(int uses) {
this.uses = Calc.clamp(uses, 0, getMaxUses());
}
public void use() {
if(uses>0) uses--;
if(uses==0) consume();
}
public abstract boolean isDamageable();
public abstract String getVisualName();
} }
@@ -19,8 +19,7 @@ public final class ItemModel {
public final Class<? extends Item> itemClass; public final Class<? extends Item> itemClass;
public ItemModel(int id, Class<? extends Item> item) public ItemModel(int id, Class<? extends Item> item) {
{
Items.register(id, this); Items.register(id, this);
this.id = id; this.id = id;
this.itemClass = item; this.itemClass = item;
@@ -30,10 +29,15 @@ public final class ItemModel {
/** /**
* @return new item instance of this type * @return new item instance of this type
*/ */
public <T extends Item> T createItem() public Item createItem()
{ {
try { try {
return (T) itemClass.getConstructor(ItemModel.class).newInstance(this); Item itm = itemClass.getConstructor(ItemModel.class).newInstance(this);
itm.setRemainingUses(itm.getMaxUses());
return itm;
} catch (final Exception e) { } catch (final Exception e) {
throw new RuntimeException("Could not instantiate an item.", e); throw new RuntimeException("Could not instantiate an item.", e);
} }
@@ -6,6 +6,16 @@ import mightypork.gamecore.util.math.constraints.rect.Rect;
public abstract class ItemRenderer { public abstract class ItemRenderer {
protected final Item item;
public ItemRenderer(Item item) {
this.item = item;
}
public abstract void render(Rect r); public abstract void render(Rect r);
} }
+15 -1
View File
@@ -6,7 +6,14 @@ import java.util.Collection;
import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.rogue.world.item.items.ItemMeat; import mightypork.rogue.world.item.items.food.ItemCheese;
import mightypork.rogue.world.item.items.food.ItemMeat;
import mightypork.rogue.world.item.items.food.ItemSandwich;
import mightypork.rogue.world.item.items.weapons.ItemBone;
import mightypork.rogue.world.item.items.weapons.ItemClub;
import mightypork.rogue.world.item.items.weapons.ItemHammer;
import mightypork.rogue.world.item.items.weapons.ItemStone;
import mightypork.rogue.world.item.items.weapons.ItemSword;
/** /**
@@ -19,6 +26,13 @@ public final class Items {
private static final ItemModel[] items = new ItemModel[256]; private static final ItemModel[] items = new ItemModel[256];
public static final ItemModel MEAT = new ItemModel(1, ItemMeat.class); public static final ItemModel MEAT = new ItemModel(1, ItemMeat.class);
public static final ItemModel CHEESE = new ItemModel(2, ItemCheese.class);
public static final ItemModel BONE = new ItemModel(3, ItemBone.class);
public static final ItemModel SANDWICH = new ItemModel(4, ItemSandwich.class);
public static final ItemModel CLUB = new ItemModel(5, ItemClub.class);
public static final ItemModel HAMMER = new ItemModel(6, ItemHammer.class);
public static final ItemModel SWORD = new ItemModel(7, ItemSword.class);
public static final ItemModel ROCK = new ItemModel(8, ItemStone.class);
public static void register(int id, ItemModel model) public static void register(int id, ItemModel model)
@@ -34,4 +34,15 @@ public abstract class ItemBaseFood extends Item {
return ItemType.FOOD; return ItemType.FOOD;
} }
@Override
public boolean isDamageable()
{
return false;
}
@Override
public int getMaxUses()
{
return 1;
}
} }
@@ -34,4 +34,10 @@ public abstract class ItemBaseWeapon extends Item {
return ItemType.WEAPON; return ItemType.WEAPON;
} }
@Override
public boolean isDamageable()
{
return true;
}
} }
@@ -0,0 +1,38 @@
package mightypork.rogue.world.item.items.food;
import mightypork.rogue.Res;
import mightypork.rogue.world.item.ItemModel;
import mightypork.rogue.world.item.ItemRenderer;
import mightypork.rogue.world.item.items.ItemBaseFood;
import mightypork.rogue.world.item.render.QuadItemRenderer;
public class ItemCheese extends ItemBaseFood {
public ItemCheese(ItemModel model)
{
super(model);
}
@Override
protected ItemRenderer makeRenderer()
{
return new QuadItemRenderer(this, Res.txq("item.cheese"));
}
@Override
public int getFoodPoints()
{
return 2;
}
@Override
public String getVisualName()
{
return "Cheese";
}
}
@@ -1,9 +1,10 @@
package mightypork.rogue.world.item.items; package mightypork.rogue.world.item.items.food;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.item.ItemModel; import mightypork.rogue.world.item.ItemModel;
import mightypork.rogue.world.item.ItemRenderer; import mightypork.rogue.world.item.ItemRenderer;
import mightypork.rogue.world.item.items.ItemBaseFood;
import mightypork.rogue.world.item.render.QuadItemRenderer; import mightypork.rogue.world.item.render.QuadItemRenderer;
@@ -18,14 +19,20 @@ public class ItemMeat extends ItemBaseFood {
@Override @Override
protected ItemRenderer makeRenderer() protected ItemRenderer makeRenderer()
{ {
return new QuadItemRenderer(Res.txq("item.meat")); return new QuadItemRenderer(this, Res.txq("item.meat"));
} }
@Override @Override
public int getFoodPoints() public int getFoodPoints()
{ {
return 2; return 3;
} }
@Override
public String getVisualName()
{
return "Chunk Of Meat";
}
} }
@@ -0,0 +1,38 @@
package mightypork.rogue.world.item.items.food;
import mightypork.rogue.Res;
import mightypork.rogue.world.item.ItemModel;
import mightypork.rogue.world.item.ItemRenderer;
import mightypork.rogue.world.item.items.ItemBaseFood;
import mightypork.rogue.world.item.render.QuadItemRenderer;
public class ItemSandwich extends ItemBaseFood {
public ItemSandwich(ItemModel model)
{
super(model);
}
@Override
protected ItemRenderer makeRenderer()
{
return new QuadItemRenderer(this, Res.txq("item.sandwich"));
}
@Override
public int getFoodPoints()
{
return 6;
}
@Override
public String getVisualName()
{
return "Sandwich";
}
}
@@ -0,0 +1,39 @@
package mightypork.rogue.world.item.items.weapons;
import mightypork.rogue.Res;
import mightypork.rogue.world.item.ItemModel;
import mightypork.rogue.world.item.ItemRenderer;
import mightypork.rogue.world.item.items.ItemBaseWeapon;
import mightypork.rogue.world.item.render.QuadItemRenderer;
public class ItemBone extends ItemBaseWeapon {
public ItemBone(ItemModel model) {
super(model);
}
@Override
protected ItemRenderer makeRenderer()
{
return new QuadItemRenderer(this, Res.txq("item.bone"));
}
@Override
public int getAttackPoints()
{
return 1;
}
@Override
public int getMaxUses()
{
return 15;
}
@Override
public String getVisualName()
{
return "Bone";
}
}
@@ -0,0 +1,39 @@
package mightypork.rogue.world.item.items.weapons;
import mightypork.rogue.Res;
import mightypork.rogue.world.item.ItemModel;
import mightypork.rogue.world.item.ItemRenderer;
import mightypork.rogue.world.item.items.ItemBaseWeapon;
import mightypork.rogue.world.item.render.QuadItemRenderer;
public class ItemClub extends ItemBaseWeapon {
public ItemClub(ItemModel model) {
super(model);
}
@Override
protected ItemRenderer makeRenderer()
{
return new QuadItemRenderer(this, Res.txq("item.club"));
}
@Override
public int getAttackPoints()
{
return 3;
}
@Override
public int getMaxUses()
{
return 25;
}
@Override
public String getVisualName()
{
return "Wooden Club";
}
}
@@ -0,0 +1,39 @@
package mightypork.rogue.world.item.items.weapons;
import mightypork.rogue.Res;
import mightypork.rogue.world.item.ItemModel;
import mightypork.rogue.world.item.ItemRenderer;
import mightypork.rogue.world.item.items.ItemBaseWeapon;
import mightypork.rogue.world.item.render.QuadItemRenderer;
public class ItemHammer extends ItemBaseWeapon {
public ItemHammer(ItemModel model) {
super(model);
}
@Override
protected ItemRenderer makeRenderer()
{
return new QuadItemRenderer(this, Res.txq("item.hammer"));
}
@Override
public int getAttackPoints()
{
return 4;
}
@Override
public int getMaxUses()
{
return 50;
}
@Override
public String getVisualName()
{
return "Hammer";
}
}
@@ -0,0 +1,39 @@
package mightypork.rogue.world.item.items.weapons;
import mightypork.rogue.Res;
import mightypork.rogue.world.item.ItemModel;
import mightypork.rogue.world.item.ItemRenderer;
import mightypork.rogue.world.item.items.ItemBaseWeapon;
import mightypork.rogue.world.item.render.QuadItemRenderer;
public class ItemStone extends ItemBaseWeapon {
public ItemStone(ItemModel model) {
super(model);
}
@Override
protected ItemRenderer makeRenderer()
{
return new QuadItemRenderer(this, Res.txq("item.stone"));
}
@Override
public int getAttackPoints()
{
return 2;
}
@Override
public int getMaxUses()
{
return 20;
}
@Override
public String getVisualName()
{
return "Rock";
}
}
@@ -0,0 +1,39 @@
package mightypork.rogue.world.item.items.weapons;
import mightypork.rogue.Res;
import mightypork.rogue.world.item.ItemModel;
import mightypork.rogue.world.item.ItemRenderer;
import mightypork.rogue.world.item.items.ItemBaseWeapon;
import mightypork.rogue.world.item.render.QuadItemRenderer;
public class ItemSword extends ItemBaseWeapon {
public ItemSword(ItemModel model) {
super(model);
}
@Override
protected ItemRenderer makeRenderer()
{
return new QuadItemRenderer(this, Res.txq("item.sword"));
}
@Override
public int getAttackPoints()
{
return 6;
}
@Override
public int getMaxUses()
{
return 100;
}
@Override
public String getVisualName()
{
return "Wooden Club";
}
}
@@ -3,8 +3,12 @@ package mightypork.rogue.world.item.render;
import mightypork.gamecore.render.Render; import mightypork.gamecore.render.Render;
import mightypork.gamecore.resources.textures.TxQuad; import mightypork.gamecore.resources.textures.TxQuad;
import mightypork.gamecore.resources.textures.TxSheet; import mightypork.gamecore.util.math.color.Color;
import mightypork.gamecore.util.math.color.pal.RGB;
import mightypork.gamecore.util.math.constraints.num.Num;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.gamecore.util.math.constraints.rect.mutable.RectVar;
import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.item.ItemRenderer; import mightypork.rogue.world.item.ItemRenderer;
@@ -12,23 +16,38 @@ public class QuadItemRenderer extends ItemRenderer {
private final TxQuad txq; private final TxQuad txq;
private final RectVar rrect = Rect.makeVar();
private final Rect usesRect = rrect.topLeft().startRect().grow(Num.ZERO, rrect.width().perc(40), Num.ZERO, rrect.height().perc(8));
private final Num hAlpha = Num.make(0.7);
public QuadItemRenderer(TxQuad txq)
{ public QuadItemRenderer(Item item, TxQuad txq) {
super(item);
this.txq = txq; this.txq = txq;
} }
public QuadItemRenderer(TxSheet txs)
{
this.txq = txs.getQuad(0);
}
@Override @Override
public void render(Rect r) public void render(Rect r)
{ {
Render.quadTextured(r, txq); Render.quadTextured(r, txq);
if (item.isDamageable()) {
Color.pushAlpha(hAlpha);
rrect.setTo(r);
Render.quadColor(usesRect, RGB.BLACK);
double useRatio = (item.getRemainingUses() / (double)item.getMaxUses());
Color barColor = (useRatio > 0.6 ? RGB.GREEN : useRatio > 0.2 ? RGB.ORANGE : RGB.RED);
Render.quadColor(usesRect.shrinkRight(usesRect.width().value() * (1 - useRatio)), barColor);
Color.popAlpha();
}
} }
} }
+7 -4
View File
@@ -86,13 +86,11 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
private double timeSinceLastEntitySort; private double timeSinceLastEntitySort;
public Level() public Level() {
{
} }
public Level(int width, int height) public Level(int width, int height) {
{
size.setTo(width, height); size.setTo(width, height);
buildArray(); buildArray();
} }
@@ -589,6 +587,11 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
} }
} }
if (!getTile(pos).isWalkable()) {
// this should never happen.
setTile(pos, Tiles.BRICK_FLOOR.createTile());
}
} }
+2 -1
View File
@@ -12,6 +12,7 @@ import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonObjBlob; import mightypork.gamecore.util.ion.IonObjBlob;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.gamecore.util.math.color.Color; import mightypork.gamecore.util.math.color.Color;
import mightypork.rogue.Config;
import mightypork.rogue.world.World; import mightypork.rogue.world.World;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
@@ -56,7 +57,7 @@ public abstract class Tile implements BusAccess, IonObjBlob {
@DefaultImpl @DefaultImpl
public void renderTile(TileRenderContext context) public void renderTile(TileRenderContext context)
{ {
if (!isExplored()) return; if (!isExplored() && Config.RENDER_UFOG) return;
initRenderer(); initRenderer();
@@ -6,6 +6,7 @@ import mightypork.gamecore.render.Render;
import mightypork.gamecore.resources.textures.TxQuad; import mightypork.gamecore.resources.textures.TxQuad;
import mightypork.gamecore.util.math.algo.Sides; import mightypork.gamecore.util.math.algo.Sides;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.rogue.Config;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.render.NullTileRenderer; import mightypork.rogue.world.tile.render.NullTileRenderer;
@@ -104,6 +105,8 @@ public abstract class TileRenderer implements Updateable {
public void renderUnexploredFog(TileRenderContext context) public void renderUnexploredFog(TileRenderContext context)
{ {
if(!Config.RENDER_UFOG) return;
// TODO cache values, update neighbouring tiles upon "explored" flag changed. // TODO cache values, update neighbouring tiles upon "explored" flag changed.
byte ufog = 0; byte ufog = 0;
@@ -30,7 +30,10 @@ public abstract class TileBaseSecretDoor extends TileBaseDoor {
if (clicks > 0) clicks--; if (clicks > 0) clicks--;
if (clicks == 0) locked = false; if (clicks == 0) {
locked = false;
getWorld().msgDiscoverSecretDoor();
}
return true; return true;
} }
@@ -6,6 +6,7 @@ import java.util.Stack;
import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.rogue.Config;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.item.Items; import mightypork.rogue.world.item.Items;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
@@ -21,8 +22,7 @@ public abstract class TileWithItems extends Tile {
protected final Stack<Item> items = new Stack<>(); protected final Stack<Item> items = new Stack<>();
public TileWithItems(TileModel model) public TileWithItems(TileModel model) {
{
super(model); super(model);
} }
@@ -30,7 +30,7 @@ public abstract class TileWithItems extends Tile {
@Override @Override
public void renderExtra(TileRenderContext context) public void renderExtra(TileRenderContext context)
{ {
if (isExplored() && !items.isEmpty()) { if ((isExplored() || !Config.RENDER_UFOG) && !items.isEmpty()) {
itemRenderer.render(items.peek(), context); itemRenderer.render(items.peek(), context);
} }
} }
@@ -98,18 +98,18 @@ public abstract class TileWithItems extends Tile {
} }
@Override // @Override
public boolean onClick() // public boolean onClick()
{ // {
if (hasItem()) { // if (hasItem()) {
final Item item = pickItem(); // final Item item = pickItem();
if (getWorld().getPlayer().getInventory().addItem(item)) { // if (getWorld().getPlayer().addItem(item)) {
// player picked item // // player picked item
} else { // } else {
dropItem(item); // put back. // dropItem(item); // put back.
} // }
return true; // return true;
} // }
return false; // return false;
} // }
} }