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