+ rats & improvements; damaged items;
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
@@ -27,7 +27,8 @@ public abstract class BaseComponent extends AbstractRectCache implements Compone
|
|||||||
private int disableLevel = 0;
|
private int disableLevel = 0;
|
||||||
|
|
||||||
|
|
||||||
public BaseComponent() {
|
public BaseComponent()
|
||||||
|
{
|
||||||
enableCaching(false);
|
enableCaching(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,15 +105,17 @@ public abstract class LayoutComponent extends BaseComponent implements ClientHub
|
|||||||
subModule.removeChildClient(client);
|
subModule.removeChildClient(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enable(boolean yes)
|
public void enable(boolean yes)
|
||||||
{
|
{
|
||||||
super.enable(yes);
|
super.enable(yes);
|
||||||
for(Component c : components) {
|
for (final Component c : components) {
|
||||||
c.enable(yes);
|
c.enable(yes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// @Override
|
// @Override
|
||||||
// public void enable(boolean yes)
|
// public void enable(boolean yes)
|
||||||
// {
|
// {
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ public class TextPainter extends BaseComponent {
|
|||||||
/**
|
/**
|
||||||
* @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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +55,8 @@ public class TextPainter extends BaseComponent {
|
|||||||
* @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));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +69,8 @@ public class TextPainter extends BaseComponent {
|
|||||||
* @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;
|
||||||
@@ -80,7 +83,8 @@ public class TextPainter extends BaseComponent {
|
|||||||
* @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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,8 +96,8 @@ public class TextPainter extends BaseComponent {
|
|||||||
|
|
||||||
final String str = text.getString();
|
final String str = text.getString();
|
||||||
|
|
||||||
Num shrX = height().perc(xPaddingPerc);
|
final Num shrX = height().perc(xPaddingPerc);
|
||||||
Num shrY = height().perc(yPaddingPerc);
|
final Num shrY = height().perc(yPaddingPerc);
|
||||||
|
|
||||||
final Rect rect = getRect().shrink(shrX, shrY);
|
final Rect rect = getRect().shrink(shrX, shrY);
|
||||||
|
|
||||||
@@ -101,7 +105,7 @@ public class TextPainter extends BaseComponent {
|
|||||||
font.draw(str, rect.round(), align, shadowColor);
|
font.draw(str, rect.round(), align, shadowColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect r = (shadow ? rect.move(shadowOffset.neg()) : rect).round();
|
final Rect r = (shadow ? rect.move(shadowOffset.neg()) : rect).round();
|
||||||
font.draw(str, r, align, color);
|
font.draw(str, r, align, color);
|
||||||
|
|
||||||
if (Config.DEBUG_FONT_RENDER) Render.quadColor(r, RGB.PINK.withAlpha(0.4));
|
if (Config.DEBUG_FONT_RENDER) Render.quadColor(r, RGB.PINK.withAlpha(0.4));
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ 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, Enableable, 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 boolean enabled = true;
|
||||||
@@ -87,6 +88,7 @@ public abstract class Overlay extends AppSubModule implements Comparable<Overlay
|
|||||||
root.setVisible(visible);
|
root.setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enable(boolean yes)
|
public void enable(boolean yes)
|
||||||
{
|
{
|
||||||
@@ -94,12 +96,14 @@ public abstract class Overlay extends AppSubModule implements Comparable<Overlay
|
|||||||
root.enable(yes);
|
root.enable(yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled()
|
public boolean isEnabled()
|
||||||
{
|
{
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get rendering layer
|
* Get rendering layer
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +34,8 @@ 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,8 @@ 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +104,8 @@ 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;
|
||||||
@@ -163,7 +165,8 @@ 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();
|
||||||
@@ -299,7 +302,8 @@ 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()).put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData());
|
byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder())
|
||||||
|
.put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
byteBuffer.flip();
|
byteBuffer.flip();
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ public class NumBoundAdapter extends NumAdapter implements PluggableNumBound {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNum(NumBound rect)
|
public void setNum(NumBound num)
|
||||||
{
|
{
|
||||||
this.backing = rect;
|
this.backing = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public abstract class Animator extends Num implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
final double target = numAnim.getEnd();
|
final double target = numAnim.getEnd();
|
||||||
numAnim.setTo(Calc.clamp(value, lowValue, highValue));
|
numAnim.setTo(Calc.clamp(value, lowValue, highValue));
|
||||||
numAnim.animate(target, numAnim.getDefaultDuration());
|
numAnim.animate((target < value ? highValue : lowValue), target, numAnim.getDefaultDuration());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ 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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -108,7 +108,10 @@ public final class Res {
|
|||||||
texture = textures.loadTexture("/res/img/sprites.png", FilterMode.NEAREST, WrapMode.CLAMP);
|
texture = textures.loadTexture("/res/img/sprites.png", FilterMode.NEAREST, WrapMode.CLAMP);
|
||||||
grid = texture.grid(8, 8);
|
grid = texture.grid(8, 8);
|
||||||
textures.add("sprite.player", grid.makeSheet(0, 0, 4, 1));
|
textures.add("sprite.player", grid.makeSheet(0, 0, 4, 1));
|
||||||
textures.add("sprite.rat", grid.makeSheet(0, 1, 4, 1));
|
textures.add("sprite.rat.gray", grid.makeSheet(0, 1, 4, 1));
|
||||||
|
textures.add("sprite.rat.brown", grid.makeSheet(0, 2, 4, 1));
|
||||||
|
textures.add("sprite.rat.boss", grid.makeSheet(0, 3, 4, 1));
|
||||||
|
textures.add("sprite.zzz", grid.makeQuad(0, 7)); // sleep thingy
|
||||||
|
|
||||||
|
|
||||||
// logo
|
// logo
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ public class HeartBar extends BaseComponent {
|
|||||||
* @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;
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ 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;
|
||||||
|
|
||||||
@@ -55,13 +56,13 @@ public class HudLayer extends ScreenLayer {
|
|||||||
|
|
||||||
private void buildConsole()
|
private void buildConsole()
|
||||||
{
|
{
|
||||||
Num rh = root.height();
|
final Num rh = root.height();
|
||||||
Num rw = root.width();
|
final Num rw = root.width();
|
||||||
Rect consoleRect = root.shrink(rw.perc(2), Num.ZERO, rh.perc(6), rh.perc(16));
|
final 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);
|
final Num perRow = consoleRect.height().div(20).max(12).min(32);
|
||||||
|
|
||||||
WorldConsoleRenderer wcr = new WorldConsoleRenderer(perRow);
|
final WorldConsoleRenderer wcr = new WorldConsoleRenderer(perRow);
|
||||||
wcr.setRect(consoleRect);
|
wcr.setRect(consoleRect);
|
||||||
root.add(wcr);
|
root.add(wcr);
|
||||||
}
|
}
|
||||||
@@ -117,7 +118,7 @@ public class HudLayer extends ScreenLayer {
|
|||||||
NavButton btn;
|
NavButton btn;
|
||||||
|
|
||||||
nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.inventory")));
|
nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.inventory")));
|
||||||
btn.setAction(gameScreen.actionInv);
|
btn.setAction(gameScreen.actionToggleInv);
|
||||||
|
|
||||||
nav.addRight(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);
|
||||||
|
|||||||
@@ -87,12 +87,15 @@ public class InvLayer extends ScreenLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public InvLayer(final ScreenGame screen) {
|
public InvLayer(final ScreenGame screen)
|
||||||
|
{
|
||||||
super(screen);
|
super(screen);
|
||||||
|
|
||||||
final Rect fg = root.shrink(root.height().perc(15));
|
final Rect fg = root.shrink(root.height().perc(15));
|
||||||
|
|
||||||
final QuadPainter qp = new QuadPainter(RGB.BLACK_30, RGB.BLACK_30, RGB.BLACK_80, RGB.BLACK_80);
|
// darker down to cover console.
|
||||||
|
final QuadPainter qp = new QuadPainter(RGB.BLACK_30, RGB.BLACK_30, RGB.BLACK_90, RGB.BLACK_90);
|
||||||
|
|
||||||
qp.setRect(root);
|
qp.setRect(root);
|
||||||
root.add(qp);
|
root.add(qp);
|
||||||
|
|
||||||
@@ -137,19 +140,7 @@ public class InvLayer extends ScreenLayer {
|
|||||||
gl.put(txp2, pos, 0, 1, 1);
|
gl.put(txp2, pos, 0, 1, 1);
|
||||||
txp2.setPaddingHPerc(0, 25);
|
txp2.setPaddingHPerc(0, 25);
|
||||||
|
|
||||||
final Runnable leaveInv = new Runnable() {
|
bindKey(new KeyStroke(Keys.ESCAPE), screen.actionToggleInv);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
if(!isEnabled()) return;
|
|
||||||
|
|
||||||
screen.setState(GScrState.WORLD);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bindKey(new KeyStroke(Keys.ESCAPE), leaveInv);
|
|
||||||
//bindKey(new KeyStroke(Keys.I), leaveInv);
|
|
||||||
// TODO needs some rewrite of keys system
|
// TODO needs some rewrite of keys system
|
||||||
|
|
||||||
bindKey(new KeyStroke(Keys.E), new Runnable() {
|
bindKey(new KeyStroke(Keys.E), new Runnable() {
|
||||||
@@ -231,7 +222,7 @@ public class InvLayer extends ScreenLayer {
|
|||||||
{
|
{
|
||||||
if (!isEnabled()) return;
|
if (!isEnabled()) return;
|
||||||
|
|
||||||
int sel = getSelectedSlot();
|
final int sel = getSelectedSlot();
|
||||||
if (sel == -1) {
|
if (sel == -1) {
|
||||||
selectSlot(0);
|
selectSlot(0);
|
||||||
return;
|
return;
|
||||||
@@ -248,7 +239,7 @@ public class InvLayer extends ScreenLayer {
|
|||||||
{
|
{
|
||||||
if (!isEnabled()) return;
|
if (!isEnabled()) return;
|
||||||
|
|
||||||
int sel = getSelectedSlot();
|
final int sel = getSelectedSlot();
|
||||||
if (sel == -1) {
|
if (sel == -1) {
|
||||||
selectSlot(0);
|
selectSlot(0);
|
||||||
return;
|
return;
|
||||||
@@ -265,7 +256,7 @@ public class InvLayer extends ScreenLayer {
|
|||||||
{
|
{
|
||||||
if (!isEnabled()) return;
|
if (!isEnabled()) return;
|
||||||
|
|
||||||
int sel = getSelectedSlot();
|
final int sel = getSelectedSlot();
|
||||||
if (sel == -1) {
|
if (sel == -1) {
|
||||||
selectSlot(0);
|
selectSlot(0);
|
||||||
return;
|
return;
|
||||||
@@ -282,7 +273,7 @@ public class InvLayer extends ScreenLayer {
|
|||||||
{
|
{
|
||||||
if (!isEnabled()) return;
|
if (!isEnabled()) return;
|
||||||
|
|
||||||
int sel = getSelectedSlot();
|
final int sel = getSelectedSlot();
|
||||||
if (sel == -1) {
|
if (sel == -1) {
|
||||||
selectSlot(0);
|
selectSlot(0);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ 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.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.num.Num;
|
||||||
|
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;
|
||||||
import mightypork.rogue.Res;
|
import mightypork.rogue.Res;
|
||||||
import mightypork.rogue.world.World.PlayerFacade;
|
import mightypork.rogue.world.World.PlayerFacade;
|
||||||
@@ -41,8 +43,12 @@ public class InvSlot extends ClickableComponent {
|
|||||||
private final RectCache rbTxRect;
|
private final RectCache rbTxRect;
|
||||||
private final RectCache rtTxRect;
|
private final RectCache rtTxRect;
|
||||||
|
|
||||||
|
private final Rect usesRect;
|
||||||
|
private final Num hAlpha = Num.make(0.7);
|
||||||
|
|
||||||
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");
|
||||||
@@ -53,6 +59,8 @@ public class InvSlot extends ClickableComponent {
|
|||||||
this.uiRect = 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();
|
this.itemRect = uiRect.shrink(Num.ZERO, height().perc(14), height().perc(14), Num.ZERO).cached();
|
||||||
|
|
||||||
|
this.usesRect = uiRect.topLeft().startRect().grow(Num.ZERO, uiRect.width().perc(40), Num.ZERO, uiRect.height().perc(8));
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
this.rbTxRect = uiRect.bottomEdge()
|
this.rbTxRect = uiRect.bottomEdge()
|
||||||
.moveY(uiRect.height().perc(1*(30/7D)))
|
.moveY(uiRect.height().perc(1*(30/7D)))
|
||||||
@@ -134,11 +142,26 @@ public class InvSlot extends ClickableComponent {
|
|||||||
rtTxP.render();
|
rtTxP.render();
|
||||||
} else if (itm.getType() == ItemType.WEAPON) {
|
} else if (itm.getType() == ItemType.WEAPON) {
|
||||||
|
|
||||||
int atk = itm.getAttackPoints();
|
final int atk = itm.getAttackPoints();
|
||||||
rtTxP.setText((atk >= 0 ? "+" : "") + atk);
|
rtTxP.setText((atk >= 0 ? "+" : "") + atk);
|
||||||
rtTxP.setColor(RGB.CYAN);
|
rtTxP.setColor(RGB.CYAN);
|
||||||
rtTxP.render();
|
rtTxP.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (itm.isDamageable()) {
|
||||||
|
Color.pushAlpha(hAlpha);
|
||||||
|
|
||||||
|
Render.quadColor(usesRect, RGB.BLACK);
|
||||||
|
|
||||||
|
final double useRatio = (itm.getRemainingUses() / (double) itm.getMaxUses());
|
||||||
|
|
||||||
|
final 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ package mightypork.rogue.screens.game;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import mightypork.gamecore.app.AppAccess;
|
import mightypork.gamecore.app.AppAccess;
|
||||||
|
import mightypork.gamecore.eventbus.events.Updateable;
|
||||||
import mightypork.gamecore.gui.Action;
|
import mightypork.gamecore.gui.Action;
|
||||||
import mightypork.gamecore.gui.ActionGroup;
|
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.Config;
|
||||||
|
import mightypork.rogue.world.World.PlayerFacade;
|
||||||
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;
|
||||||
@@ -31,6 +33,8 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
private InvLayer invLayer;
|
private InvLayer invLayer;
|
||||||
private HudLayer hudLayer;
|
private HudLayer hudLayer;
|
||||||
|
|
||||||
|
private WorldLayer worldLayer;
|
||||||
|
|
||||||
private GScrState state = GScrState.WORLD;
|
private GScrState state = GScrState.WORLD;
|
||||||
|
|
||||||
private final ActionGroup worldActions = new ActionGroup();
|
private final ActionGroup worldActions = new ActionGroup();
|
||||||
@@ -40,16 +44,18 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
@Override
|
@Override
|
||||||
public void execute()
|
public void execute()
|
||||||
{
|
{
|
||||||
WorldProvider.get().getPlayer().tryToEatSomeFood();
|
final PlayerFacade pl = WorldProvider.get().getPlayer();
|
||||||
|
if (pl.isDead()) return;
|
||||||
|
pl.tryToEatSomeFood();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public Action actionInv = new Action() {
|
public Action actionToggleInv = new Action() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute()
|
public void execute()
|
||||||
{
|
{
|
||||||
setState(GScrState.INV);
|
setState(getState() == GScrState.INV ? GScrState.WORLD : GScrState.INV);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -80,8 +86,6 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private WorldLayer worldLayer;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set gui state (overlay)
|
* Set gui state (overlay)
|
||||||
@@ -122,7 +126,8 @@ 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));
|
||||||
@@ -152,7 +157,7 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
bindKey(new KeyStroke(Keys.PAUSE), actionTogglePause);
|
bindKey(new KeyStroke(Keys.PAUSE), actionTogglePause);
|
||||||
bindKey(new KeyStroke(Keys.SPACE), actionTogglePause);
|
bindKey(new KeyStroke(Keys.SPACE), actionTogglePause);
|
||||||
|
|
||||||
bindKey(new KeyStroke(Keys.I), actionInv);
|
bindKey(new KeyStroke(Keys.I), actionToggleInv);
|
||||||
bindKey(new KeyStroke(Keys.E), actionEat);
|
bindKey(new KeyStroke(Keys.E), actionEat);
|
||||||
bindKey(new KeyStroke(Keys.M), actionToggleMinimap);
|
bindKey(new KeyStroke(Keys.M), actionToggleMinimap);
|
||||||
bindKey(new KeyStroke(Keys.Z), actionToggleZoom);
|
bindKey(new KeyStroke(Keys.Z), actionToggleZoom);
|
||||||
@@ -162,7 +167,6 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
worldActions.add(hudLayer);
|
worldActions.add(hudLayer);
|
||||||
|
|
||||||
worldActions.add(actionEat);
|
worldActions.add(actionEat);
|
||||||
worldActions.add(actionInv);
|
|
||||||
worldActions.add(actionToggleMinimap);
|
worldActions.add(actionToggleMinimap);
|
||||||
worldActions.add(actionTogglePause);
|
worldActions.add(actionTogglePause);
|
||||||
worldActions.add(actionToggleZoom);
|
worldActions.add(actionToggleZoom);
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package mightypork.rogue.screens.game;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.ConcurrentModificationException;
|
import java.util.ConcurrentModificationException;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import mightypork.gamecore.gui.AlignX;
|
import mightypork.gamecore.gui.AlignX;
|
||||||
import mightypork.gamecore.gui.components.BaseComponent;
|
import mightypork.gamecore.gui.components.BaseComponent;
|
||||||
@@ -17,7 +15,6 @@ 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;
|
||||||
import mightypork.rogue.Res;
|
import mightypork.rogue.Res;
|
||||||
import mightypork.rogue.world.WorldConsole;
|
import mightypork.rogue.world.WorldConsole;
|
||||||
import mightypork.rogue.world.WorldConsole.Entry;
|
|
||||||
import mightypork.rogue.world.WorldProvider;
|
import mightypork.rogue.world.WorldProvider;
|
||||||
|
|
||||||
|
|
||||||
@@ -37,25 +34,25 @@ public class WorldConsoleRenderer extends BaseComponent {
|
|||||||
@Override
|
@Override
|
||||||
protected void renderComponent()
|
protected void renderComponent()
|
||||||
{
|
{
|
||||||
double rh = rowHeight.value();
|
final double rh = rowHeight.value();
|
||||||
|
|
||||||
Rect lowRow = bottomEdge().growUp(rowHeight);
|
final Rect lowRow = bottomEdge().growUp(rowHeight);
|
||||||
|
|
||||||
Collection<WorldConsole.Entry> entries = WorldProvider.get().getWorld().getConsole().getEntries();
|
final Collection<WorldConsole.Entry> entries = WorldProvider.get().getWorld().getConsole().getEntries();
|
||||||
|
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
NumVar alph = Num.makeVar();
|
final NumVar alph = Num.makeVar();
|
||||||
|
|
||||||
Color.pushAlpha(alph);
|
Color.pushAlpha(alph);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
for (WorldConsole.Entry entry : entries) {
|
for (final WorldConsole.Entry entry : entries) {
|
||||||
|
|
||||||
alph.setTo(entry.getAlpha());
|
alph.setTo(entry.getAlpha());
|
||||||
|
|
||||||
Rect rrr = lowRow.moveY(-rh * cnt);
|
final 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.move(rh / 12, rh / 12), AlignX.LEFT, RGB.BLACK_60);
|
||||||
fr.draw(entry.getMessage(), rrr, AlignX.LEFT, RGB.WHITE);
|
fr.draw(entry.getMessage(), rrr, AlignX.LEFT, RGB.WHITE);
|
||||||
@@ -63,7 +60,7 @@ public class WorldConsoleRenderer extends BaseComponent {
|
|||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (ConcurrentModificationException e) {
|
} catch (final ConcurrentModificationException e) {
|
||||||
Log.e(e); // this should not happen anymore
|
Log.e(e); // this should not happen anymore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +160,7 @@ public class Inventory implements IonObjBinary {
|
|||||||
public void clean()
|
public void clean()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < getSize(); i++) {
|
for (int i = 0; i < getSize(); i++) {
|
||||||
Item itm = getItem(i);
|
final Item itm = getItem(i);
|
||||||
if (itm == null) continue;
|
if (itm == null) continue;
|
||||||
if (itm.isEmpty()) setItem(i, null);
|
if (itm.isEmpty()) setItem(i, null);
|
||||||
}
|
}
|
||||||
@@ -175,10 +177,8 @@ public class Inventory implements IonObjBinary {
|
|||||||
s += i + ": ";
|
s += i + ": ";
|
||||||
final Item itm = getItem(i);
|
final Item itm = getItem(i);
|
||||||
|
|
||||||
if (itm == null)
|
if (itm == null) s += "<null>";
|
||||||
s += "<null>";
|
else s += itm;
|
||||||
else
|
|
||||||
s += itm;
|
|
||||||
}
|
}
|
||||||
s += "]";
|
s += "]";
|
||||||
return s;
|
return s;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import mightypork.rogue.world.entity.Entity;
|
|||||||
import mightypork.rogue.world.entity.EntityType;
|
import mightypork.rogue.world.entity.EntityType;
|
||||||
import mightypork.rogue.world.entity.modules.EntityMoveListener;
|
import mightypork.rogue.world.entity.modules.EntityMoveListener;
|
||||||
import mightypork.rogue.world.level.Level;
|
import mightypork.rogue.world.level.Level;
|
||||||
|
import mightypork.rogue.world.tile.Tile;
|
||||||
|
|
||||||
|
|
||||||
public abstract class PlayerControl {
|
public abstract class PlayerControl {
|
||||||
@@ -115,15 +116,20 @@ public abstract class PlayerControl {
|
|||||||
|
|
||||||
private boolean doClickTile(Vect pos)
|
private boolean doClickTile(Vect pos)
|
||||||
{
|
{
|
||||||
// 1st try to hit entity
|
//try to click tile
|
||||||
|
if (getLevel().getTile(Coord.fromVect(pos)).onClick()) return true;
|
||||||
|
|
||||||
|
final Tile t = getLevel().getTile(Coord.fromVect(pos));
|
||||||
|
if (!t.isPotentiallyWalkable()) return false; // no point in attacking entity thru wall, right?
|
||||||
|
|
||||||
|
//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) {
|
||||||
getPlayer().attack(prey);
|
getPlayer().attack(prey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//2nd try to click tile
|
return false;
|
||||||
return getLevel().getTile(Coord.fromVect(pos)).onClick();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
|||||||
|
|
||||||
public void tryToEatSomeFood()
|
public void tryToEatSomeFood()
|
||||||
{
|
{
|
||||||
List<Item> foods = new ArrayList<>();
|
final 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.getType() == ItemType.FOOD) {
|
if (itm != null && itm.getType() == ItemType.FOOD) {
|
||||||
@@ -247,7 +247,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (Item itm : foods) {
|
for (final Item itm : foods) {
|
||||||
if (eatFood(itm)) {
|
if (eatFood(itm)) {
|
||||||
getInventory().clean();
|
getInventory().clean();
|
||||||
return;
|
return;
|
||||||
@@ -264,7 +264,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
|||||||
|
|
||||||
public void attack(Entity prey)
|
public void attack(Entity prey)
|
||||||
{
|
{
|
||||||
int attackPoints = getAttackStrength();
|
final int attackPoints = getAttackStrength();
|
||||||
|
|
||||||
prey.receiveAttack(getPlayer().getEntity(), attackPoints);
|
prey.receiveAttack(getPlayer().getEntity(), attackPoints);
|
||||||
|
|
||||||
@@ -272,7 +272,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
|||||||
msgKill(prey);
|
msgKill(prey);
|
||||||
}
|
}
|
||||||
|
|
||||||
Item wpn = getSelectedWeapon();
|
final Item wpn = getSelectedWeapon();
|
||||||
|
|
||||||
if (wpn != null) {
|
if (wpn != null) {
|
||||||
wpn.use();
|
wpn.use();
|
||||||
@@ -293,7 +293,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
|||||||
{
|
{
|
||||||
if (getSelectedWeapon() != null) return;
|
if (getSelectedWeapon() != null) return;
|
||||||
|
|
||||||
List<Item> wpns = new ArrayList<>();
|
final List<Item> wpns = 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.getType() == ItemType.WEAPON) {
|
if (itm != null && itm.getType() == ItemType.WEAPON) {
|
||||||
@@ -311,7 +311,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (Item itm : wpns) {
|
for (final Item itm : wpns) {
|
||||||
for (int i = 0; i < getInventory().getSize(); i++) {
|
for (int i = 0; i < getInventory().getSize(); i++) {
|
||||||
final Item itm2 = getInventory().getItem(i);
|
final Item itm2 = getInventory().getItem(i);
|
||||||
if (itm2 == itm) {
|
if (itm2 == itm) {
|
||||||
@@ -584,6 +584,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea
|
|||||||
console.addMessage("You don't have any food!");
|
console.addMessage("You don't have any food!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void msgNotHungry()
|
public void msgNotHungry()
|
||||||
{
|
{
|
||||||
console.addMessage("You are not hungry.");
|
console.addMessage("You are not hungry.");
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package mightypork.rogue.world;
|
package mightypork.rogue.world;
|
||||||
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
|
|
||||||
import mightypork.gamecore.eventbus.events.Updateable;
|
import mightypork.gamecore.eventbus.events.Updateable;
|
||||||
import mightypork.gamecore.util.math.Easing;
|
import mightypork.gamecore.util.math.Easing;
|
||||||
@@ -22,7 +23,8 @@ public class WorldConsole implements Updateable {
|
|||||||
private double elapsed = 0;
|
private double elapsed = 0;
|
||||||
|
|
||||||
|
|
||||||
private Entry(String text) {
|
private Entry(String text)
|
||||||
|
{
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.fadeout = new NumAnimated(1, Easing.LINEAR);
|
this.fadeout = new NumAnimated(1, Easing.LINEAR);
|
||||||
this.fadeout.setDefaultDuration(0.5);
|
this.fadeout.setDefaultDuration(0.5);
|
||||||
@@ -76,8 +78,8 @@ public class WorldConsole implements Updateable {
|
|||||||
@Override
|
@Override
|
||||||
public void update(double delta)
|
public void update(double delta)
|
||||||
{
|
{
|
||||||
for (Iterator<Entry> iter = entries.iterator(); iter.hasNext();) {
|
for (final Iterator<Entry> iter = entries.iterator(); iter.hasNext();) {
|
||||||
Entry e = iter.next();
|
final Entry e = iter.next();
|
||||||
|
|
||||||
e.update(delta);
|
e.update(delta);
|
||||||
|
|
||||||
@@ -99,7 +101,9 @@ public class WorldConsole implements Updateable {
|
|||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
entries.clear();
|
entries.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package mightypork.rogue.world;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import mightypork.rogue.world.gen.LevelGenerator;
|
import mightypork.rogue.world.gen.LevelGenerator;
|
||||||
import mightypork.rogue.world.level.Level;
|
|
||||||
|
|
||||||
|
|
||||||
public class WorldCreator {
|
public class WorldCreator {
|
||||||
@@ -20,12 +19,15 @@ public class WorldCreator {
|
|||||||
final World w = new World();
|
final World w = new World();
|
||||||
w.setSeed(seed);
|
w.setSeed(seed);
|
||||||
|
|
||||||
final int count = 7;
|
// final int count = 7;
|
||||||
|
//
|
||||||
|
// for (int i = 1; i <= count; i++) {
|
||||||
|
// final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME, i == count);
|
||||||
|
// w.addLevel(l);
|
||||||
|
// }
|
||||||
|
|
||||||
for (int i = 1; i <= count; i++) {
|
w.addLevel(LevelGenerator.build(w, rand.nextLong(), 6, LevelGenerator.DUNGEON_THEME, false));
|
||||||
final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME, i == count);
|
w.addLevel(LevelGenerator.build(w, rand.nextLong(), 7, LevelGenerator.DUNGEON_THEME, true));
|
||||||
w.addLevel(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
w.createPlayer();
|
w.createPlayer();
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ 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.entity.entities.EntityBossRat;
|
||||||
|
import mightypork.rogue.world.entity.entities.EntityBrownRat;
|
||||||
|
import mightypork.rogue.world.entity.entities.EntityGrayRat;
|
||||||
import mightypork.rogue.world.entity.entities.PlayerEntity;
|
import mightypork.rogue.world.entity.entities.PlayerEntity;
|
||||||
import mightypork.rogue.world.entity.entities.RatEntity;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +22,9 @@ public final class Entities {
|
|||||||
private static final EntityModel[] entities = new EntityModel[256];
|
private static final EntityModel[] entities = new EntityModel[256];
|
||||||
|
|
||||||
public static final EntityModel PLAYER = new EntityModel(1, PlayerEntity.class);
|
public static final EntityModel PLAYER = new EntityModel(1, PlayerEntity.class);
|
||||||
public static final EntityModel RAT = new EntityModel(2, RatEntity.class);
|
public static final EntityModel RAT_GRAY = new EntityModel(2, EntityGrayRat.class);
|
||||||
|
public static final EntityModel RAT_BROWN = new EntityModel(3, EntityBrownRat.class);
|
||||||
|
public static final EntityModel RAT_BOSS = new EntityModel(4, EntityBossRat.class);
|
||||||
|
|
||||||
|
|
||||||
public static void register(int id, EntityModel model)
|
public static void register(int id, EntityModel model)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public abstract class Entity implements IonObjBundled, Updateable {
|
|||||||
protected final Random rand = new Random();
|
protected final Random rand = new Random();
|
||||||
|
|
||||||
/** Entity ID */
|
/** Entity ID */
|
||||||
private int entityId;
|
private int entityId = -1;
|
||||||
|
|
||||||
private final Map<String, EntityModule> modules = new HashMap<>();
|
private final Map<String, EntityModule> modules = new HashMap<>();
|
||||||
|
|
||||||
@@ -123,6 +123,10 @@ public abstract class Entity implements IonObjBundled, Updateable {
|
|||||||
|
|
||||||
public void setLevel(Level level)
|
public void setLevel(Level level)
|
||||||
{
|
{
|
||||||
|
if (level != null && entityId < 0) {
|
||||||
|
entityId = level.getWorld().getNewEID();
|
||||||
|
}
|
||||||
|
|
||||||
if (level != null) level.freeTile(getCoord());
|
if (level != null) level.freeTile(getCoord());
|
||||||
|
|
||||||
this.level = level;
|
this.level = level;
|
||||||
@@ -266,5 +270,6 @@ public abstract class Entity implements IonObjBundled, Updateable {
|
|||||||
return despawnDelay;
|
return despawnDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract String getVisualName();
|
public abstract String getVisualName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,18 @@ public final class EntityModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create entitiy without EID. EID will be assigned when the entity is added
|
||||||
|
* to a level.
|
||||||
|
*
|
||||||
|
* @return entity.
|
||||||
|
*/
|
||||||
|
public Entity createEntity()
|
||||||
|
{
|
||||||
|
return createEntity(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Entity loadEntity(IonInput in) throws IOException
|
public Entity loadEntity(IonInput in) throws IOException
|
||||||
{
|
{
|
||||||
final IonBundle bundle = in.readBundle();
|
final IonBundle bundle = in.readBundle();
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package mightypork.rogue.world.entity.entities;
|
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.world.entity.AiTimer;
|
||||||
|
import mightypork.rogue.world.entity.Entity;
|
||||||
|
|
||||||
|
|
||||||
|
public class BossRatAi extends GrayRatAi {
|
||||||
|
|
||||||
|
private final AiTimer healTimer = new AiTimer(0.5) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
entity.health.addHealth(1); // heal
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public BossRatAi(Entity entity)
|
||||||
|
{
|
||||||
|
super(entity);
|
||||||
|
|
||||||
|
setAttackTime(0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getAttackStrength()
|
||||||
|
{
|
||||||
|
return 5 + rand.nextInt(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getPreyAbandonDistance()
|
||||||
|
{
|
||||||
|
return 15 + rand.nextInt(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(double delta)
|
||||||
|
{
|
||||||
|
super.update(delta);
|
||||||
|
healTimer.update(delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package mightypork.rogue.world.entity.entities;
|
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.world.entity.Entity;
|
||||||
|
|
||||||
|
|
||||||
|
public class BrownRatAi extends GrayRatAi {
|
||||||
|
|
||||||
|
public BrownRatAi(Entity entity)
|
||||||
|
{
|
||||||
|
super(entity);
|
||||||
|
|
||||||
|
setAttackTime(0.8);
|
||||||
|
setScanTime(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double getScanRadius()
|
||||||
|
{
|
||||||
|
return isSleeping() ? 3 + rand.nextInt(3) : 5 + rand.nextInt(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getAttackStrength()
|
||||||
|
{
|
||||||
|
return 3 + rand.nextInt(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getPreyAbandonDistance()
|
||||||
|
{
|
||||||
|
return 11 + rand.nextInt(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package mightypork.rogue.world.entity.entities;
|
||||||
|
|
||||||
|
|
||||||
|
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
|
||||||
|
import mightypork.rogue.world.entity.Entity;
|
||||||
|
import mightypork.rogue.world.entity.EntityModel;
|
||||||
|
import mightypork.rogue.world.entity.EntityPathFinder;
|
||||||
|
import mightypork.rogue.world.entity.EntityRenderer;
|
||||||
|
import mightypork.rogue.world.entity.EntityType;
|
||||||
|
import mightypork.rogue.world.entity.render.EntityRendererMobLR;
|
||||||
|
import mightypork.rogue.world.item.Items;
|
||||||
|
|
||||||
|
|
||||||
|
public class EntityBossRat extends Entity {
|
||||||
|
|
||||||
|
private EntityRenderer renderer;
|
||||||
|
|
||||||
|
/** Navigation PFC */
|
||||||
|
private final PathFinder pathf = new EntityPathFinder(this);
|
||||||
|
|
||||||
|
private final BossRatAi ai = new BossRatAi(this);
|
||||||
|
|
||||||
|
|
||||||
|
public EntityBossRat(EntityModel model, int eid)
|
||||||
|
{
|
||||||
|
super(model, eid);
|
||||||
|
|
||||||
|
addModule("ai", ai);
|
||||||
|
pos.addMoveListener(ai);
|
||||||
|
|
||||||
|
pos.setStepTime(0.4);
|
||||||
|
setDespawnDelay(1);
|
||||||
|
|
||||||
|
health.setMaxHealth(80);
|
||||||
|
health.setHealth(80);
|
||||||
|
health.setHitCooldownTime(0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityRenderer getRenderer()
|
||||||
|
{
|
||||||
|
if (renderer == null) {
|
||||||
|
renderer = new EntityRendererMobLR(this, "sprite.rat.boss");
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType getType()
|
||||||
|
{
|
||||||
|
return EntityType.MONSTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathFinder getPathFinder()
|
||||||
|
{
|
||||||
|
return pathf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCorpseRemoved()
|
||||||
|
{
|
||||||
|
// TODO drop rare stuff & fire event.
|
||||||
|
|
||||||
|
if (rand.nextInt(8) == 0) {
|
||||||
|
getLevel().dropNear(getCoord(), Items.BONE.createItem());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rand.nextInt(3) == 0) {
|
||||||
|
getLevel().dropNear(getCoord(), Items.MEAT.createItem());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rand.nextInt(6) == 0) {
|
||||||
|
getLevel().dropNear(getCoord(), Items.CHEESE.createItem());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVisualName()
|
||||||
|
{
|
||||||
|
return "Rat Boss";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package mightypork.rogue.world.entity.entities;
|
||||||
|
|
||||||
|
|
||||||
|
import mightypork.gamecore.util.math.Calc;
|
||||||
|
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
|
||||||
|
import mightypork.rogue.world.entity.Entity;
|
||||||
|
import mightypork.rogue.world.entity.EntityModel;
|
||||||
|
import mightypork.rogue.world.entity.EntityPathFinder;
|
||||||
|
import mightypork.rogue.world.entity.EntityRenderer;
|
||||||
|
import mightypork.rogue.world.entity.EntityType;
|
||||||
|
import mightypork.rogue.world.entity.render.EntityRendererMobLR;
|
||||||
|
import mightypork.rogue.world.item.Items;
|
||||||
|
|
||||||
|
|
||||||
|
public class EntityBrownRat extends Entity {
|
||||||
|
|
||||||
|
private EntityRenderer renderer;
|
||||||
|
|
||||||
|
private final PathFinder pathf = new EntityPathFinder(this);
|
||||||
|
|
||||||
|
private final BrownRatAi ai = new BrownRatAi(this);
|
||||||
|
|
||||||
|
|
||||||
|
public EntityBrownRat(EntityModel model, int eid)
|
||||||
|
{
|
||||||
|
super(model, eid);
|
||||||
|
|
||||||
|
addModule("ai", ai);
|
||||||
|
pos.addMoveListener(ai);
|
||||||
|
|
||||||
|
pos.setStepTime(0.37); // faster than gray rat
|
||||||
|
setDespawnDelay(1);
|
||||||
|
|
||||||
|
health.setMaxHealth(14);
|
||||||
|
health.setHealth(Calc.randInt(rand, 8, 14)); // tougher to kill
|
||||||
|
health.setHitCooldownTime(0.35); // a bit longer than gray rat
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityRenderer getRenderer()
|
||||||
|
{
|
||||||
|
if (renderer == null) {
|
||||||
|
renderer = new EntityRendererMobLR(this, "sprite.rat.brown");
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType getType()
|
||||||
|
{
|
||||||
|
return EntityType.MONSTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathFinder getPathFinder()
|
||||||
|
{
|
||||||
|
return pathf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCorpseRemoved()
|
||||||
|
{
|
||||||
|
// drop rat stuff
|
||||||
|
|
||||||
|
if (rand.nextInt(8) == 0) {
|
||||||
|
getLevel().dropNear(getCoord(), Items.BONE.createItemDamaged(10));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rand.nextInt(3) == 0) {
|
||||||
|
getLevel().dropNear(getCoord(), Items.MEAT.createItem());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rand.nextInt(6) == 0) {
|
||||||
|
getLevel().dropNear(getCoord(), Items.CHEESE.createItem());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVisualName()
|
||||||
|
{
|
||||||
|
return "Brown Rat";
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
-22
@@ -12,17 +12,17 @@ import mightypork.rogue.world.entity.render.EntityRendererMobLR;
|
|||||||
import mightypork.rogue.world.item.Items;
|
import mightypork.rogue.world.item.Items;
|
||||||
|
|
||||||
|
|
||||||
public class RatEntity extends Entity {
|
public class EntityGrayRat extends Entity {
|
||||||
|
|
||||||
/** Navigation PFC */
|
private final PathFinder pathf = new EntityPathFinder(this);
|
||||||
private PathFinder pathf;
|
|
||||||
|
|
||||||
private final RatAi ai = new RatAi(this);
|
private final GrayRatAi ai = new GrayRatAi(this);
|
||||||
|
|
||||||
private EntityRenderer renderer;
|
private EntityRenderer renderer;
|
||||||
|
|
||||||
|
|
||||||
public RatEntity(EntityModel model, int eid) {
|
public EntityGrayRat(EntityModel model, int eid)
|
||||||
|
{
|
||||||
super(model, eid);
|
super(model, eid);
|
||||||
|
|
||||||
addModule("ai", ai);
|
addModule("ai", ai);
|
||||||
@@ -32,7 +32,7 @@ public class RatEntity extends Entity {
|
|||||||
setDespawnDelay(1);
|
setDespawnDelay(1);
|
||||||
|
|
||||||
health.setMaxHealth(5);
|
health.setMaxHealth(5);
|
||||||
health.setHealth(Calc.randInt(rand, 3, 5)); // fill health bar to max
|
health.setHealth(Calc.randInt(rand, 3, 5));
|
||||||
health.setHitCooldownTime(0.3);
|
health.setHitCooldownTime(0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,10 +40,6 @@ public class RatEntity extends Entity {
|
|||||||
@Override
|
@Override
|
||||||
public PathFinder getPathFinder()
|
public PathFinder getPathFinder()
|
||||||
{
|
{
|
||||||
if (pathf == null) {
|
|
||||||
pathf = new EntityPathFinder(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pathf;
|
return pathf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,41 +55,35 @@ public class RatEntity extends Entity {
|
|||||||
protected EntityRenderer getRenderer()
|
protected EntityRenderer getRenderer()
|
||||||
{
|
{
|
||||||
if (renderer == null) {
|
if (renderer == null) {
|
||||||
renderer = new EntityRendererMobLR(this, "sprite.rat");
|
renderer = new EntityRendererMobLR(this, "sprite.rat.gray");
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onKilled()
|
|
||||||
{
|
|
||||||
super.onKilled();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCorpseRemoved()
|
public void onCorpseRemoved()
|
||||||
{
|
{
|
||||||
// drop rat stuff
|
// drop rat stuff
|
||||||
|
|
||||||
if(rand.nextInt(7) == 0) {
|
if (rand.nextInt(6) == 0) {
|
||||||
getLevel().dropNear(getCoord(), Items.BONE.createItem());
|
getLevel().dropNear(getCoord(), Items.BONE.createItemDamaged(10));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rand.nextInt(3) == 0) {
|
if (rand.nextInt(7) == 0) {
|
||||||
getLevel().dropNear(getCoord(), Items.MEAT.createItem());
|
getLevel().dropNear(getCoord(), Items.MEAT.createItem());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rand.nextInt(2) == 0) {
|
if (rand.nextInt(3) == 0) {
|
||||||
getLevel().dropNear(getCoord(), Items.CHEESE.createItem());
|
getLevel().dropNear(getCoord(), Items.CHEESE.createItem());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVisualName()
|
public String getVisualName()
|
||||||
{
|
{
|
||||||
+2
-2
@@ -4,9 +4,9 @@ package mightypork.rogue.world.entity.entities;
|
|||||||
import mightypork.rogue.world.entity.Entity;
|
import mightypork.rogue.world.entity.Entity;
|
||||||
|
|
||||||
|
|
||||||
public class RatAi extends MonsterAi {
|
public class GrayRatAi extends MonsterAi {
|
||||||
|
|
||||||
public RatAi(Entity entity)
|
public GrayRatAi(Entity entity)
|
||||||
{
|
{
|
||||||
super(entity);
|
super(entity);
|
||||||
|
|
||||||
@@ -16,7 +16,8 @@ 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);
|
||||||
|
|
||||||
@@ -79,7 +80,8 @@ 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);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class LevelGenerator {
|
|||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("fallthrough")
|
@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) throws WorldGenError
|
||||||
{
|
{
|
||||||
Log.f3("Generating level of complexity: " + complexity);
|
Log.f3("Generating level of complexity: " + complexity);
|
||||||
|
|
||||||
@@ -31,7 +31,9 @@ public class LevelGenerator {
|
|||||||
final ScratchMap map = new ScratchMap(max_size, theme, rand);
|
final ScratchMap map = new ScratchMap(max_size, theme, rand);
|
||||||
|
|
||||||
// start
|
// start
|
||||||
map.addRoom(Rooms.ENTRANCE, true);
|
if (!map.addRoom(Rooms.ENTRANCE, true)) {
|
||||||
|
throw new WorldGenError("Could not place entrance room.");
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 1 + complexity / 2 + rand.nextInt((int) (1 + complexity * 0.2)); 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);
|
||||||
@@ -39,7 +41,18 @@ public class LevelGenerator {
|
|||||||
if (rand.nextInt(7) > 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) {
|
||||||
|
if (!map.addRoom(Rooms.EXIT, true)) {
|
||||||
|
throw new WorldGenError("Could not place exit room.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastLevel) {
|
||||||
|
if (!map.addRoom(Rooms.BOSS_ROOM, true)) {
|
||||||
|
throw new WorldGenError("Could not place boss room.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
map.buildCorridors();
|
map.buildCorridors();
|
||||||
|
|
||||||
@@ -47,43 +60,42 @@ public class LevelGenerator {
|
|||||||
default:
|
default:
|
||||||
case 3:
|
case 3:
|
||||||
case 2:
|
case 2:
|
||||||
if(rand.nextInt(2)==0) map.dropInMap(Items.CLUB.createItem(), 50);
|
if (rand.nextInt(2) == 0) map.dropInMap(Items.CLUB.createItemDamaged(60), 50);
|
||||||
case 1:
|
case 1:
|
||||||
case 0:
|
case 0:
|
||||||
if(rand.nextInt(2)==0) map.dropInMap(Items.ROCK.createItem(), 50);
|
if (rand.nextInt(2) == 0) map.dropInMap(Items.ROCK.createItemDamaged(10), 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (complexity == 6) {
|
if (complexity == 6) {
|
||||||
map.dropInMap(Items.SWORD.createItem(), 200);
|
map.dropInMap(Items.SWORD.createItemDamaged(40), 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (complexity == 5) {
|
if (complexity == 5) {
|
||||||
map.dropInMap(Items.HAMMER.createItem(), 100);
|
map.dropInMap(Items.HAMMER.createItemDamaged(40), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// entities - random rats
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < 3 + complexity + rand.nextInt(1 + complexity); i++) {
|
||||||
|
Entity e;
|
||||||
|
|
||||||
|
if (rand.nextInt((int) (complexity / 1.5) + 1) != 0) {
|
||||||
|
e = Entities.RAT_BROWN.createEntity();
|
||||||
|
} else {
|
||||||
|
e = Entities.RAT_GRAY.createEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
map.putEntityInMap(e, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
|
lvl.setWorld(world); // important for creating entities
|
||||||
|
|
||||||
map.writeToLevel(lvl);
|
map.writeToLevel(lvl);
|
||||||
|
|
||||||
// TODO tmp
|
|
||||||
// spawn rats
|
|
||||||
|
|
||||||
// TODO entities in ScratchMap itself
|
|
||||||
|
|
||||||
final Coord pos = Coord.make(0, 0);
|
|
||||||
for (int i = 0; i < 3 + complexity + rand.nextInt(1 + complexity); i++) {
|
|
||||||
|
|
||||||
final Entity e = Entities.RAT.createEntity(world);
|
|
||||||
|
|
||||||
for (int j = 0; j < 20; j++) {
|
|
||||||
pos.x = rand.nextInt(lvl.getWidth());
|
|
||||||
pos.y = rand.nextInt(lvl.getHeight());
|
|
||||||
|
|
||||||
if (lvl.addEntity(e, pos)) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lvl;
|
return lvl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,5 +13,5 @@ import mightypork.gamecore.util.math.algo.Coord;
|
|||||||
*/
|
*/
|
||||||
public interface RoomBuilder {
|
public interface RoomBuilder {
|
||||||
|
|
||||||
RoomDesc buildToFit(ScratchMap map, MapTheme theme, Random rand, Coord center);
|
RoomDesc buildToFit(ScratchMap map, MapTheme theme, Random rand, Coord center) throws WorldGenError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.entity.Entity;
|
||||||
import mightypork.rogue.world.item.Item;
|
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;
|
||||||
@@ -37,6 +38,9 @@ public class ScratchMap {
|
|||||||
/** Coords to connect with corridors */
|
/** Coords to connect with corridors */
|
||||||
private final List<Coord> nodes = new ArrayList<>();
|
private final List<Coord> nodes = new ArrayList<>();
|
||||||
|
|
||||||
|
private final List<Coord> occupied = new ArrayList<>();
|
||||||
|
private final List<Entity> entities = new ArrayList<>();
|
||||||
|
|
||||||
private final PathFinder pathf = new PathFinder() {
|
private final PathFinder pathf = new PathFinder() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -72,7 +76,7 @@ public class ScratchMap {
|
|||||||
return 100;
|
return 100;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unknown tile type: " + t.getType());
|
throw new WorldGenError("Unknown tile type: " + t.getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +136,7 @@ public class ScratchMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addRoom(RoomBuilder rb, boolean critical)
|
public boolean addRoom(RoomBuilder rb, boolean critical)
|
||||||
{
|
{
|
||||||
final Coord center = Coord.make(0, 0);
|
final Coord center = Coord.make(0, 0);
|
||||||
|
|
||||||
@@ -150,16 +154,16 @@ public class ScratchMap {
|
|||||||
|
|
||||||
switch (rand.nextInt(4)) {
|
switch (rand.nextInt(4)) {
|
||||||
case 0:
|
case 0:
|
||||||
center.x += 1 + (failed_total / 50);
|
center.x += (failed_total / 35);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
center.x -= 1 + (failed_total / 50);
|
center.x -= (failed_total / 35);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
center.y += 1 + (failed_total / 50);
|
center.y += (failed_total / 35);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
center.y -= 1 + (failed_total / 50);
|
center.y -= (failed_total / 35);
|
||||||
}
|
}
|
||||||
|
|
||||||
final RoomDesc rd = rb.buildToFit(this, theme, rand, center);
|
final RoomDesc rd = rb.buildToFit(this, theme, rand, center);
|
||||||
@@ -174,14 +178,18 @@ public class ScratchMap {
|
|||||||
clampBounds();
|
clampBounds();
|
||||||
|
|
||||||
nodes.add(center);
|
nodes.add(center);
|
||||||
Log.f3("Placed room on " + Calc.ordinal(1+failed_total) + " try.");
|
// Log.f3("Placed room (failed " + failed_total + " x).");
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
failed++;
|
failed++;
|
||||||
failed_total++;
|
failed_total++;
|
||||||
|
|
||||||
if (failed > 400) {
|
if (failed_total > 1000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed > 300) {
|
||||||
Log.w("Faild to build room.");
|
Log.w("Faild to build room.");
|
||||||
if (critical) {
|
if (critical) {
|
||||||
|
|
||||||
@@ -192,16 +200,13 @@ public class ScratchMap {
|
|||||||
clampBounds();
|
clampBounds();
|
||||||
|
|
||||||
failed = 0;
|
failed = 0;
|
||||||
|
Log.f3("Trying again.");
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failed_total > 1000) {
|
|
||||||
throw new RuntimeException("Generation error - could not place critical room.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +231,7 @@ public class ScratchMap {
|
|||||||
public Tile getTile(Coord pos)
|
public Tile getTile(Coord pos)
|
||||||
{
|
{
|
||||||
if (!isIn(pos)) {
|
if (!isIn(pos)) {
|
||||||
throw new IndexOutOfBoundsException("Tile not in map: " + pos);
|
throw new WorldGenError("Tile not in map: " + pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return map[pos.y][pos.x];
|
return map[pos.y][pos.x];
|
||||||
@@ -242,7 +247,7 @@ public class ScratchMap {
|
|||||||
public boolean set(Coord pos, Tile tile)
|
public boolean set(Coord pos, Tile tile)
|
||||||
{
|
{
|
||||||
if (!isIn(pos)) {
|
if (!isIn(pos)) {
|
||||||
throw new IndexOutOfBoundsException("Tile not in map: " + pos);
|
throw new WorldGenError("Tile not in map: " + pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
map[pos.y][pos.x] = tile;
|
map[pos.y][pos.x] = tile;
|
||||||
@@ -263,7 +268,7 @@ public class ScratchMap {
|
|||||||
|
|
||||||
public void protect(Coord min, Coord max, TileProtectLevel prot)
|
public void protect(Coord min, Coord max, TileProtectLevel prot)
|
||||||
{
|
{
|
||||||
if (!isIn(min) || !isIn(max)) throw new IndexOutOfBoundsException("Tile(s) not in map: " + min + " , " + max);
|
if (!isIn(min) || !isIn(max)) throw new WorldGenError("Tile(s) not in map: " + min + " , " + max);
|
||||||
|
|
||||||
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++)
|
||||||
@@ -274,7 +279,7 @@ public class ScratchMap {
|
|||||||
|
|
||||||
public void fill(Coord min, Coord max, TileModel tm)
|
public void fill(Coord min, Coord max, TileModel tm)
|
||||||
{
|
{
|
||||||
if (!isIn(min) || !isIn(max)) throw new IndexOutOfBoundsException("Tile(s) not in map: " + min + " , " + max);
|
if (!isIn(min) || !isIn(max)) throw new WorldGenError("Tile(s) not in map: " + min + " , " + max);
|
||||||
|
|
||||||
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++)
|
||||||
@@ -285,7 +290,7 @@ public class ScratchMap {
|
|||||||
|
|
||||||
public void border(Coord min, Coord max, TileModel tm)
|
public void border(Coord min, Coord max, TileModel tm)
|
||||||
{
|
{
|
||||||
if (!isIn(min) || !isIn(max)) throw new IndexOutOfBoundsException("Tile(s) not in map: " + min + " , " + max);
|
if (!isIn(min) || !isIn(max)) throw new WorldGenError("Tile(s) not in map: " + min + " , " + max);
|
||||||
|
|
||||||
final Coord c = Coord.make(0, 0);
|
final Coord c = Coord.make(0, 0);
|
||||||
|
|
||||||
@@ -543,6 +548,21 @@ public class ScratchMap {
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
for (final Entity e : entities) {
|
||||||
|
final Coord pos = e.getCoord().add(-genMin.x, -genMin.y);
|
||||||
|
if (!level.addEntityNear(e, pos)) {
|
||||||
|
final Tile t = level.getTile(pos);
|
||||||
|
//@formatter:off
|
||||||
|
throw new WorldGenError(
|
||||||
|
"Could not put entity into a level map: e_pos=" + pos
|
||||||
|
+ ", tile: " + Log.str(t)
|
||||||
|
+ ", t.wa " + t.isWalkable()
|
||||||
|
+ ", t.oc " + t.isOccupied()
|
||||||
|
+ ", ent.. " + e.getVisualName());
|
||||||
|
//@formatter:on
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -560,13 +580,14 @@ public class ScratchMap {
|
|||||||
|
|
||||||
public boolean dropInArea(Item item, Coord min, Coord max, int tries)
|
public boolean dropInArea(Item item, Coord min, Coord max, int tries)
|
||||||
{
|
{
|
||||||
Coord pos = Coord.zero();
|
final Coord pos = Coord.zero();
|
||||||
|
|
||||||
for (int i = 0; i < tries; i++) {
|
for (int i = 0; i < tries; i++) {
|
||||||
pos.x = min.x + rand.nextInt(max.x - min.x);
|
pos.x = min.x + rand.nextInt(max.x - min.x);
|
||||||
pos.y = min.y + rand.nextInt(max.y - min.y);
|
pos.y = min.y + rand.nextInt(max.y - min.y);
|
||||||
|
if (!isIn(pos)) continue;
|
||||||
|
|
||||||
Tile t = getTile(pos);
|
final Tile t = getTile(pos);
|
||||||
if (t.dropItem(item)) return true;
|
if (t.dropItem(item)) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,8 +595,49 @@ public class ScratchMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void dropInMap(Item item, int tries)
|
public boolean dropInMap(Item item, int tries)
|
||||||
{
|
{
|
||||||
dropInArea(item, genMin, genMax, tries);
|
return dropInArea(item, genMin, genMax, tries);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean putEntityInArea(Entity entity, Coord min, Coord max, int tries)
|
||||||
|
{
|
||||||
|
final 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);
|
||||||
|
if (!isIn(pos)) continue;
|
||||||
|
|
||||||
|
if (putEntity(entity, pos)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean putEntityInMap(Entity entity, int tries)
|
||||||
|
{
|
||||||
|
return putEntityInArea(entity, genMin, genMax, tries);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean putEntity(Entity entity, Coord pos)
|
||||||
|
{
|
||||||
|
if (!isIn(pos)) return false;
|
||||||
|
|
||||||
|
if (pos.dist(enterPoint) < 5) return false; // protected distance.
|
||||||
|
|
||||||
|
final Tile t = getTile(pos);
|
||||||
|
if (!t.isWalkable()) return false;
|
||||||
|
|
||||||
|
if (occupied.contains(pos)) return false;
|
||||||
|
|
||||||
|
occupied.add(pos.copy());
|
||||||
|
entity.setCoord(pos);
|
||||||
|
entities.add(entity);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package mightypork.rogue.world.gen;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error in world generation
|
||||||
|
*
|
||||||
|
* @author MightyPork
|
||||||
|
*/
|
||||||
|
public class WorldGenError extends RuntimeException {
|
||||||
|
|
||||||
|
public WorldGenError()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public WorldGenError(String message, Throwable cause)
|
||||||
|
{
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public WorldGenError(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public WorldGenError(Throwable cause)
|
||||||
|
{
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package mightypork.rogue.world.gen.rooms;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
|
import mightypork.rogue.world.entity.Entities;
|
||||||
|
import mightypork.rogue.world.entity.Entity;
|
||||||
|
import mightypork.rogue.world.gen.MapTheme;
|
||||||
|
import mightypork.rogue.world.gen.ScratchMap;
|
||||||
|
import mightypork.rogue.world.gen.WorldGenError;
|
||||||
|
|
||||||
|
|
||||||
|
public class BossRoom extends SecretRoom {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getDoorCount(Random rand)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max)
|
||||||
|
{
|
||||||
|
final Entity boss = Entities.RAT_BOSS.createEntity();
|
||||||
|
if (!map.putEntityInArea(boss, min, max, 100)) {
|
||||||
|
|
||||||
|
// just place it anywhere then
|
||||||
|
if (!map.putEntityInMap(boss, 100)) {
|
||||||
|
throw new WorldGenError("Could not place boss.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,4 +11,5 @@ public class Rooms {
|
|||||||
public static final RoomBuilder DEAD_END = new DeadEndRoom();
|
public static final RoomBuilder DEAD_END = new DeadEndRoom();
|
||||||
public static final RoomBuilder ENTRANCE = new EntranceRoom();
|
public static final RoomBuilder ENTRANCE = new EntranceRoom();
|
||||||
public static final RoomBuilder EXIT = new ExitRoom();
|
public static final RoomBuilder EXIT = new ExitRoom();
|
||||||
|
public static final RoomBuilder BOSS_ROOM = new BossRoom();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,18 +43,18 @@ public class SecretRoom extends AbstractRectRoom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) {
|
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) {
|
||||||
map.dropInArea(Items.BONE.createItem(), min, max, 50);
|
map.dropInArea(Items.BONE.createItemDamaged(20), min, max, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) {
|
for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) {
|
||||||
map.dropInArea(Items.ROCK.createItem(), min, max, 50);
|
map.dropInArea(Items.ROCK.createItemDamaged(30), min, max, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 0, 3); i++) {
|
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) {
|
||||||
map.dropInArea(Items.MEAT.createItem(), min, max, 50);
|
map.dropInArea(Items.MEAT.createItem(), min, max, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 0, 3); i++) {
|
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) {
|
||||||
map.dropInArea(Items.CHEESE.createItem(), min, max, 50);
|
map.dropInArea(Items.CHEESE.createItem(), min, max, 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,17 +161,24 @@ public abstract class Item implements IonObjBlob {
|
|||||||
return Log.str(getClass()) + " x " + getAmount();
|
return Log.str(getClass()) + " x " + getAmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRemainingUses() {
|
|
||||||
|
public int getRemainingUses()
|
||||||
|
{
|
||||||
return uses;
|
return uses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract int getMaxUses();
|
public abstract int getMaxUses();
|
||||||
|
|
||||||
public void setRemainingUses(int uses) {
|
|
||||||
|
public void setRemainingUses(int uses)
|
||||||
|
{
|
||||||
this.uses = Calc.clamp(uses, 0, getMaxUses());
|
this.uses = Calc.clamp(uses, 0, getMaxUses());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void use() {
|
|
||||||
|
public void use()
|
||||||
|
{
|
||||||
if (uses > 0) uses--;
|
if (uses > 0) uses--;
|
||||||
if (uses == 0) consume();
|
if (uses == 0) consume();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package mightypork.rogue.world.item;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
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.gamecore.util.math.Calc;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,8 +20,11 @@ public final class ItemModel {
|
|||||||
public final int id;
|
public final int id;
|
||||||
public final Class<? extends Item> itemClass;
|
public final Class<? extends Item> itemClass;
|
||||||
|
|
||||||
|
public static final Random rand = new Random();
|
||||||
|
|
||||||
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;
|
||||||
@@ -32,7 +37,7 @@ public final class ItemModel {
|
|||||||
public Item createItem()
|
public Item createItem()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Item itm = itemClass.getConstructor(ItemModel.class).newInstance(this);
|
final Item itm = itemClass.getConstructor(ItemModel.class).newInstance(this);
|
||||||
|
|
||||||
itm.setRemainingUses(itm.getMaxUses());
|
itm.setRemainingUses(itm.getMaxUses());
|
||||||
|
|
||||||
@@ -58,4 +63,12 @@ public final class ItemModel {
|
|||||||
|
|
||||||
tile.save(out);
|
tile.save(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Item createItemDamaged(int minimalHealthPercent)
|
||||||
|
{
|
||||||
|
final Item item = createItem();
|
||||||
|
item.setRemainingUses(Calc.randInt(rand, (int) Math.ceil(item.getMaxUses() * (minimalHealthPercent / 100D)), item.getMaxUses()));
|
||||||
|
return item;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,12 @@ public abstract class ItemRenderer {
|
|||||||
protected final Item item;
|
protected final Item item;
|
||||||
|
|
||||||
|
|
||||||
|
public ItemRenderer(Item item)
|
||||||
public ItemRenderer(Item item) {
|
{
|
||||||
this.item = item;
|
this.item = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public abstract void render(Rect r);
|
public abstract void render(Rect r);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,12 +34,14 @@ public abstract class ItemBaseFood extends Item {
|
|||||||
return ItemType.FOOD;
|
return ItemType.FOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDamageable()
|
public boolean isDamageable()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxUses()
|
public int getMaxUses()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public abstract class ItemBaseWeapon extends Item {
|
|||||||
return ItemType.WEAPON;
|
return ItemType.WEAPON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDamageable()
|
public boolean isDamageable()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mightypork.rogue.world.item.items.weapons;
|
package mightypork.rogue.world.item.items.weapons;
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -9,28 +10,33 @@ import mightypork.rogue.world.item.render.QuadItemRenderer;
|
|||||||
|
|
||||||
public class ItemBone extends ItemBaseWeapon {
|
public class ItemBone extends ItemBaseWeapon {
|
||||||
|
|
||||||
public ItemBone(ItemModel model) {
|
public ItemBone(ItemModel model)
|
||||||
|
{
|
||||||
super(model);
|
super(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.bone"));
|
return new QuadItemRenderer(this, Res.txq("item.bone"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAttackPoints()
|
public int getAttackPoints()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxUses()
|
public int getMaxUses()
|
||||||
{
|
{
|
||||||
return 15;
|
return 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVisualName()
|
public String getVisualName()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mightypork.rogue.world.item.items.weapons;
|
package mightypork.rogue.world.item.items.weapons;
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -9,28 +10,33 @@ import mightypork.rogue.world.item.render.QuadItemRenderer;
|
|||||||
|
|
||||||
public class ItemClub extends ItemBaseWeapon {
|
public class ItemClub extends ItemBaseWeapon {
|
||||||
|
|
||||||
public ItemClub(ItemModel model) {
|
public ItemClub(ItemModel model)
|
||||||
|
{
|
||||||
super(model);
|
super(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.club"));
|
return new QuadItemRenderer(this, Res.txq("item.club"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAttackPoints()
|
public int getAttackPoints()
|
||||||
{
|
{
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxUses()
|
public int getMaxUses()
|
||||||
{
|
{
|
||||||
return 25;
|
return 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVisualName()
|
public String getVisualName()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mightypork.rogue.world.item.items.weapons;
|
package mightypork.rogue.world.item.items.weapons;
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -9,28 +10,33 @@ import mightypork.rogue.world.item.render.QuadItemRenderer;
|
|||||||
|
|
||||||
public class ItemHammer extends ItemBaseWeapon {
|
public class ItemHammer extends ItemBaseWeapon {
|
||||||
|
|
||||||
public ItemHammer(ItemModel model) {
|
public ItemHammer(ItemModel model)
|
||||||
|
{
|
||||||
super(model);
|
super(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.hammer"));
|
return new QuadItemRenderer(this, Res.txq("item.hammer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAttackPoints()
|
public int getAttackPoints()
|
||||||
{
|
{
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxUses()
|
public int getMaxUses()
|
||||||
{
|
{
|
||||||
return 50;
|
return 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVisualName()
|
public String getVisualName()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mightypork.rogue.world.item.items.weapons;
|
package mightypork.rogue.world.item.items.weapons;
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -9,28 +10,33 @@ import mightypork.rogue.world.item.render.QuadItemRenderer;
|
|||||||
|
|
||||||
public class ItemStone extends ItemBaseWeapon {
|
public class ItemStone extends ItemBaseWeapon {
|
||||||
|
|
||||||
public ItemStone(ItemModel model) {
|
public ItemStone(ItemModel model)
|
||||||
|
{
|
||||||
super(model);
|
super(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.stone"));
|
return new QuadItemRenderer(this, Res.txq("item.stone"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAttackPoints()
|
public int getAttackPoints()
|
||||||
{
|
{
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxUses()
|
public int getMaxUses()
|
||||||
{
|
{
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVisualName()
|
public String getVisualName()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mightypork.rogue.world.item.items.weapons;
|
package mightypork.rogue.world.item.items.weapons;
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -9,31 +10,36 @@ import mightypork.rogue.world.item.render.QuadItemRenderer;
|
|||||||
|
|
||||||
public class ItemSword extends ItemBaseWeapon {
|
public class ItemSword extends ItemBaseWeapon {
|
||||||
|
|
||||||
public ItemSword(ItemModel model) {
|
public ItemSword(ItemModel model)
|
||||||
|
{
|
||||||
super(model);
|
super(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.sword"));
|
return new QuadItemRenderer(this, Res.txq("item.sword"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAttackPoints()
|
public int getAttackPoints()
|
||||||
{
|
{
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxUses()
|
public int getMaxUses()
|
||||||
{
|
{
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVisualName()
|
public String getVisualName()
|
||||||
{
|
{
|
||||||
return "Wooden Club";
|
return "Sword";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,11 +3,7 @@ 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.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.Item;
|
||||||
import mightypork.rogue.world.item.ItemRenderer;
|
import mightypork.rogue.world.item.ItemRenderer;
|
||||||
|
|
||||||
@@ -16,12 +12,9 @@ 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(Item item, TxQuad txq)
|
||||||
public QuadItemRenderer(Item item, TxQuad txq) {
|
{
|
||||||
super(item);
|
super(item);
|
||||||
this.txq = txq;
|
this.txq = txq;
|
||||||
}
|
}
|
||||||
@@ -31,23 +24,6 @@ public class QuadItemRenderer extends ItemRenderer {
|
|||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,11 +86,13 @@ 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();
|
||||||
}
|
}
|
||||||
@@ -308,6 +310,34 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to add entity at given pos, then near the pos.
|
||||||
|
*
|
||||||
|
* @param entity the entity
|
||||||
|
* @param pos pos
|
||||||
|
* @return true if added
|
||||||
|
*/
|
||||||
|
public boolean addEntityNear(Entity entity, Coord pos)
|
||||||
|
{
|
||||||
|
if (addEntity(entity, pos)) return true;
|
||||||
|
|
||||||
|
// closer
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
final Coord c = pos.add(-1 + rand.nextInt(3), -1 + rand.nextInt(3));
|
||||||
|
if (addEntity(entity, c)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// further
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
final Coord c = pos.add(-2 + rand.nextInt(5), -2 + rand.nextInt(5));
|
||||||
|
if (addEntity(entity, c)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to add entity at given pos
|
* Try to add entity at given pos
|
||||||
*
|
*
|
||||||
@@ -320,6 +350,9 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
|
|||||||
final Tile t = getTile(pos);
|
final Tile t = getTile(pos);
|
||||||
if (!t.isWalkable() || t.isOccupied()) return false;
|
if (!t.isWalkable() || t.isOccupied()) return false;
|
||||||
|
|
||||||
|
// set level to init EID
|
||||||
|
entity.setLevel(this);
|
||||||
|
|
||||||
if (entityMap.containsKey(entity.getEntityId())) {
|
if (entityMap.containsKey(entity.getEntityId())) {
|
||||||
Log.w("Entity already in level.");
|
Log.w("Entity already in level.");
|
||||||
return false;
|
return false;
|
||||||
@@ -330,7 +363,6 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
|
|||||||
if (entity instanceof PlayerEntity) playerCount++;
|
if (entity instanceof PlayerEntity) playerCount++;
|
||||||
|
|
||||||
// join to level & world
|
// join to level & world
|
||||||
entity.setLevel(this);
|
|
||||||
occupyTile(entity.getCoord());
|
occupyTile(entity.getCoord());
|
||||||
|
|
||||||
entity.setCoord(pos);
|
entity.setCoord(pos);
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
package mightypork.rogue.world.tile;
|
package mightypork.rogue.world.tile;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.Easing;
|
import mightypork.gamecore.util.math.Easing;
|
||||||
|
import mightypork.gamecore.util.math.constraints.num.Num;
|
||||||
|
import mightypork.gamecore.util.math.constraints.num.proxy.NumBoundAdapter;
|
||||||
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
||||||
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBoundAdapter;
|
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBoundAdapter;
|
||||||
import mightypork.gamecore.util.math.timing.Animator;
|
import mightypork.gamecore.util.math.timing.Animator;
|
||||||
@@ -12,27 +16,26 @@ import mightypork.rogue.world.level.render.TileRenderContext;
|
|||||||
|
|
||||||
public class DroppedItemRenderer {
|
public class DroppedItemRenderer {
|
||||||
|
|
||||||
private Animator itemAnim = new AnimatorBounce(2, Easing.SINE_BOTH);
|
private final Animator itemAnim = new AnimatorBounce(2, Easing.SINE_BOTH);
|
||||||
|
|
||||||
// prepared constraints, to avoid re-building each frame
|
// prepared constraints, to avoid re-building each frame
|
||||||
private final RectBoundAdapter tileRectAdapter = new RectBoundAdapter();
|
private final RectBoundAdapter tileRectAdapter = new RectBoundAdapter();
|
||||||
private final Rect itemRect = tileRectAdapter.shrink(tileRectAdapter.height().perc(10)).moveY(itemAnim.neg().mul(tileRectAdapter.height().mul(0.2)));
|
private final NumBoundAdapter offsAdapter = new NumBoundAdapter();
|
||||||
|
private final Rect itemRect = tileRectAdapter.shrink(tileRectAdapter.height().perc(12)).moveY(offsAdapter.neg().mul(tileRectAdapter.height().mul(0.2)));
|
||||||
|
|
||||||
|
|
||||||
public Animator getItemAnim()
|
public void render(Collection<Item> items, TileRenderContext context)
|
||||||
{
|
|
||||||
if (itemAnim == null) {
|
|
||||||
itemAnim = new AnimatorBounce(2, Easing.SINE_BOTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemAnim;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void render(Item item, TileRenderContext context)
|
|
||||||
{
|
{
|
||||||
tileRectAdapter.setRect(context);
|
tileRectAdapter.setRect(context);
|
||||||
item.render(itemRect);
|
int cnt = 0;
|
||||||
|
for (final Item i : items) {
|
||||||
|
|
||||||
|
offsAdapter.setNum(Num.make((itemAnim.value() + (cnt % 3) * 0.1)));
|
||||||
|
|
||||||
|
i.render(itemRect);
|
||||||
|
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ public abstract class TileWithItems extends Tile {
|
|||||||
public void renderExtra(TileRenderContext context)
|
public void renderExtra(TileRenderContext context)
|
||||||
{
|
{
|
||||||
if ((isExplored() || !Config.RENDER_UFOG) && !items.isEmpty()) {
|
if ((isExplored() || !Config.RENDER_UFOG) && !items.isEmpty()) {
|
||||||
itemRenderer.render(items.peek(), context);
|
itemRenderer.render(items, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user