refactor: Improved chest logic
This commit is contained in:
@@ -31,11 +31,19 @@ import java.util.List;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public final class Chest extends GameObject implements Interactable, UIClickHandler {
|
public final class Chest extends GameObject implements Interactable, UIClickHandler {
|
||||||
|
private static final TextColor BORDER_COLOR = new TextColor.RGB(0, 0, 0);
|
||||||
|
private static final TextColor TRANSPARENT_COLOR = new TextColor.RGB(255, 255, 255);
|
||||||
|
|
||||||
private final List<GameItem> items;
|
private final List<GameItem> items;
|
||||||
private final DependencyManager dependencyManager;
|
private final DependencyManager dependencyManager;
|
||||||
|
|
||||||
private int listenerHashCode;
|
private int listenerHashCode;
|
||||||
|
|
||||||
|
private int actualDisplayStartX;
|
||||||
|
private int actualDisplayStartY;
|
||||||
|
private int chestUISizeX;
|
||||||
|
private int chestUISizeY;
|
||||||
|
|
||||||
@InjectDependency
|
@InjectDependency
|
||||||
private StateManager sm;
|
private StateManager sm;
|
||||||
@InjectDependency
|
@InjectDependency
|
||||||
@@ -44,6 +52,7 @@ public final class Chest extends GameObject implements Interactable, UIClickHand
|
|||||||
private EventManager eventManager;
|
private EventManager eventManager;
|
||||||
@InjectDependency
|
@InjectDependency
|
||||||
private UIClickHandlerRepository uiClickHandlerRepository;
|
private UIClickHandlerRepository uiClickHandlerRepository;
|
||||||
|
|
||||||
@InjectState
|
@InjectState
|
||||||
private GameState gameState;
|
private GameState gameState;
|
||||||
@InjectState
|
@InjectState
|
||||||
@@ -57,11 +66,6 @@ public final class Chest extends GameObject implements Interactable, UIClickHand
|
|||||||
this.dependencyManager = dm;
|
this.dependencyManager = dm;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int actualDisplayStartX;
|
|
||||||
private int actualDisplayStartY;
|
|
||||||
private int chestUISizeX;
|
|
||||||
private int chestUISizeY;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void interact(DependencyManager dm) {
|
public void interact(DependencyManager dm) {
|
||||||
dm.inject(this);
|
dm.inject(this);
|
||||||
@@ -72,112 +76,180 @@ public final class Chest extends GameObject implements Interactable, UIClickHand
|
|||||||
private void render(boolean clear) {
|
private void render(boolean clear) {
|
||||||
GameRoom currentRoom = gameState.getCurrentRoom();
|
GameRoom currentRoom = gameState.getCurrentRoom();
|
||||||
Player player = gameState.getPlayer();
|
Player player = gameState.getPlayer();
|
||||||
BufferedImage playerTexture = RerenderUtils.getPlayer(resourceManager, player);
|
|
||||||
|
|
||||||
BufferedImage room = resourceManager.getResource(currentRoom.getTexture());
|
BufferedImage roomTexture = resourceManager.getResource(currentRoom.getTexture());
|
||||||
BufferedImage chest = getTexture();
|
BufferedImage playerTexture = RerenderUtils.getPlayer(resourceManager, player);
|
||||||
|
BufferedImage chestTexture = getTexture();
|
||||||
|
|
||||||
var buffer = screenBuffer.getRenderedBuffer();
|
var buffer = screenBuffer.getRenderedBuffer();
|
||||||
var overrideBuffer = currentRoom.getOverrideBuffer();
|
var overrideBuffer = currentRoom.getOverrideBuffer();
|
||||||
|
|
||||||
RoomCords start = RerenderUtils.getStart(room, terminalState.getTerminalScreen().getTerminalSize());
|
RoomCords start = RerenderUtils.getStart(
|
||||||
|
roomTexture,
|
||||||
|
terminalState.getTerminalScreen().getTerminalSize()
|
||||||
|
);
|
||||||
|
|
||||||
int itemCount = items.size();
|
int itemCount = items.size();
|
||||||
|
calculateUISize(itemCount);
|
||||||
|
|
||||||
int chestUIStartX = getCords().getX();
|
int chestUIStartX = getCords().getX();
|
||||||
int chestUIStartY = getCords().getY();
|
int chestUIStartY = getCords().getY();
|
||||||
|
|
||||||
chestUISizeY = 16 + 4;
|
int guiStartX = chestUIStartX + (chestTexture.getWidth() / 2) - (chestUISizeX / 2);
|
||||||
chestUISizeX = 4 + itemCount * 16 + (itemCount - 1) * 2;
|
int guiStartY = chestUIStartY - chestUISizeY - 1;
|
||||||
|
|
||||||
int chestGUIStartY = chestUIStartY - chestUISizeY - 1;
|
TerminalPosition guiStart = new TerminalPosition(guiStartX + start.getX(), guiStartY + start.getY());
|
||||||
int chestGUIStartX = chestUIStartX + (chest.getWidth() / 2) - (chestUISizeX / 2);
|
TerminalPosition guiEnd = new TerminalPosition(
|
||||||
|
(guiStartX + chestUISizeX - 1) + start.getX(),
|
||||||
|
(guiStartY + chestUISizeY - 1) + start.getY()
|
||||||
|
);
|
||||||
|
|
||||||
TerminalPosition guiStart = new TerminalPosition(chestGUIStartX / 2, chestGUIStartY);
|
actualDisplayStartX = guiStartX + start.getX() + 2;
|
||||||
TerminalPosition guiEnd = new TerminalPosition((chestGUIStartX + chestUISizeX - 1) / 2, ((chestGUIStartY + chestUISizeY - 1) / 2));
|
actualDisplayStartY = guiStartY + start.getY() + 2;
|
||||||
|
|
||||||
actualDisplayStartX = chestGUIStartX + start.getX() + 2;
|
|
||||||
actualDisplayStartY = chestGUIStartY + start.getY() + 2;
|
|
||||||
|
|
||||||
if (clear) {
|
if (clear) {
|
||||||
int chestUISizeX = 4 + (itemCount + 1) * 16 + (itemCount) * 2;
|
clearPreviousUI(
|
||||||
int chestGUIStartX2 = chestUIStartX + (chest.getWidth() / 2) - (chestUISizeX / 2);
|
currentRoom,
|
||||||
|
roomTexture,
|
||||||
|
player,
|
||||||
|
playerTexture,
|
||||||
|
buffer,
|
||||||
|
overrideBuffer,
|
||||||
|
start,
|
||||||
|
guiStartY,
|
||||||
|
chestUIStartX,
|
||||||
|
chestTexture.getWidth(),
|
||||||
|
itemCount
|
||||||
|
);
|
||||||
|
|
||||||
for (int y = chestGUIStartY; y < chestGUIStartY + chestUISizeY; y++) {
|
int clearWidth = 4 + (itemCount + 1) * 16 + itemCount * 2;
|
||||||
for (int x = chestGUIStartX2; x < chestGUIStartX2 + chestUISizeX; x++) {
|
int clearStartX = chestUIStartX + (chestTexture.getWidth() / 2) - (clearWidth / 2);
|
||||||
log.debug("{} {}", x, y);
|
|
||||||
|
|
||||||
int intPixel = RerenderUtils.getPixel(currentRoom, room, null, new HashSet<>(), player, playerTexture, x, y).pixel(); // This will never reach doors so no need to load texture
|
guiStart = new TerminalPosition(clearStartX + start.getX(), guiStartY + start.getY());
|
||||||
int red = (intPixel >> 16) & 0xff;
|
guiEnd = new TerminalPosition(clearStartX + start.getX() + clearWidth, (guiStartY + chestUISizeY - 1) + start.getY());
|
||||||
int green = (intPixel >> 8) & 0xff;
|
|
||||||
int blue = intPixel & 0xff;
|
|
||||||
|
|
||||||
Pixel pixel = new ColoredPixel(new TextColor.RGB(red, green, blue));
|
|
||||||
|
|
||||||
buffer[y + start.getY()][x + start.getX()] = pixel;
|
|
||||||
overrideBuffer[y][x] = new Empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
guiStart = new TerminalPosition(chestGUIStartX2 / 2, chestGUIStartY);
|
|
||||||
guiEnd = new TerminalPosition((chestGUIStartX2 + chestUISizeX - 1) / 2, ((chestGUIStartY + chestUISizeY - 1) / 2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!items.isEmpty()) {
|
if (!items.isEmpty()) {
|
||||||
for (int y = chestGUIStartY; y < chestGUIStartY + chestUISizeY; y++) {
|
drawUI(buffer, overrideBuffer, start, guiStartX, guiStartY);
|
||||||
for (int x = chestGUIStartX; x < chestGUIStartX + chestUISizeX; x++) {
|
|
||||||
int objectX = x - chestGUIStartX;
|
|
||||||
int objectY = y - chestGUIStartY;
|
|
||||||
|
|
||||||
Pixel pixel = getPixel(objectX, objectY, chestUISizeX, chestUISizeY);
|
|
||||||
|
|
||||||
buffer[y + start.getY()][x + start.getX()] = pixel;
|
|
||||||
overrideBuffer[y][x] = pixel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RerenderUtils.rerenderPart(guiStart.getColumn(), guiEnd.getColumn(), guiStart.getRow(), guiEnd.getRow(), start.getX(), start.getY(), currentRoom, room, player, playerTexture, screenBuffer, resourceManager);
|
RerenderUtils.rerenderPart(
|
||||||
|
guiStart.getColumn() - start.getX(),
|
||||||
|
guiEnd.getColumn() - start.getX(),
|
||||||
|
guiStart.getRow() - start.getY(),
|
||||||
|
guiEnd.getRow() - start.getY(),
|
||||||
|
start.getX(),
|
||||||
|
start.getY(),
|
||||||
|
currentRoom,
|
||||||
|
roomTexture,
|
||||||
|
player,
|
||||||
|
playerTexture,
|
||||||
|
screenBuffer,
|
||||||
|
resourceManager
|
||||||
|
);
|
||||||
|
|
||||||
this.listenerHashCode = uiClickHandlerRepository.registerCurrentRoomHandler(RerenderScreen.ScreenPart.full(terminalState.getTerminalScreen().getTerminalSize()), this);
|
RerenderScreen.ScreenPart sp = new RerenderScreen.ScreenPart(guiStart, guiEnd);
|
||||||
|
|
||||||
eventManager.emitEvent(RerenderScreen.full(terminalState.getTerminalScreen().getTerminalSize())); // TODO: Make this not rerender full screen
|
listenerHashCode = uiClickHandlerRepository.registerCurrentRoomHandler(sp, this);
|
||||||
|
|
||||||
|
//eventManager.emitEvent(RerenderScreen.full(terminalState.getTerminalScreen().getTerminalSize()));
|
||||||
|
|
||||||
|
eventManager.emitEvent(new RerenderScreen(sp));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add some padding on the item
|
private void calculateUISize(int itemCount) {
|
||||||
private Pixel getPixel(int objectX, int objectY, int chestUISizeX, int chestUISizeY) {
|
chestUISizeY = 20;
|
||||||
if (objectX >= 0 && objectX <= 1 || objectX >= chestUISizeX - 2 && objectX <= chestUISizeX - 1 || objectY >= 0 && objectY <= 1 || objectY >= chestUISizeY - 2 && objectY <= chestUISizeY - 1) {
|
chestUISizeX = 4 + itemCount * 16 + (itemCount - 1) * 2;
|
||||||
return new ColoredPixel(new TextColor.RGB(0, 0, 0));
|
}
|
||||||
|
|
||||||
|
private void clearPreviousUI(
|
||||||
|
GameRoom room,
|
||||||
|
BufferedImage roomTexture,
|
||||||
|
Player player,
|
||||||
|
BufferedImage playerTexture,
|
||||||
|
Pixel[][] buffer,
|
||||||
|
Pixel[][] overrideBuffer,
|
||||||
|
RoomCords start,
|
||||||
|
int guiStartY,
|
||||||
|
int chestUIStartX,
|
||||||
|
int chestTextureWidth,
|
||||||
|
int itemCount
|
||||||
|
) {
|
||||||
|
int clearWidth = 4 + (itemCount + 1) * 16 + itemCount * 2;
|
||||||
|
int clearStartX = chestUIStartX + (chestTextureWidth / 2) - (clearWidth / 2);
|
||||||
|
|
||||||
|
for (int y = guiStartY; y < guiStartY + chestUISizeY; y++) {
|
||||||
|
for (int x = clearStartX; x < clearStartX + clearWidth; x++) {
|
||||||
|
int pixel = RerenderUtils.getPixel(
|
||||||
|
room,
|
||||||
|
roomTexture,
|
||||||
|
null,
|
||||||
|
new HashSet<>(),
|
||||||
|
player,
|
||||||
|
playerTexture,
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
).pixel();
|
||||||
|
|
||||||
|
buffer[y + start.getY()][x + start.getX()] = pixelToColored(pixel);
|
||||||
|
overrideBuffer[y][x] = new Empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawUI(
|
||||||
|
Pixel[][] buffer,
|
||||||
|
Pixel[][] overrideBuffer,
|
||||||
|
RoomCords start,
|
||||||
|
int guiStartX,
|
||||||
|
int guiStartY
|
||||||
|
) {
|
||||||
|
for (int y = 0; y < chestUISizeY; y++) {
|
||||||
|
for (int x = 0; x < chestUISizeX; x++) {
|
||||||
|
Pixel pixel = getPixel(x, y, chestUISizeX, chestUISizeY);
|
||||||
|
buffer[guiStartY + y + start.getY()][guiStartX + x + start.getX()] = pixel;
|
||||||
|
overrideBuffer[guiStartY + y][guiStartX + x] = pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pixel pixelToColored(int argb) {
|
||||||
|
int r = (argb >> 16) & 0xff;
|
||||||
|
int g = (argb >> 8) & 0xff;
|
||||||
|
int b = argb & 0xff;
|
||||||
|
return new ColoredPixel(new TextColor.RGB(r, g, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pixel getPixel(int objectX, int objectY, int width, int height) {
|
||||||
|
if (isBorder(objectX, objectY, width, height)) {
|
||||||
|
return new ColoredPixel(BORDER_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
int screenX = objectX - 2;
|
int screenX = objectX - 2;
|
||||||
int screenY = objectY - 2;
|
int screenY = objectY - 2;
|
||||||
|
|
||||||
int part = screenX / 18;
|
int part = screenX / 18;
|
||||||
int rest = screenX % 18;
|
int rest = screenX % 18;
|
||||||
|
|
||||||
if (rest == 16 || rest == 17) {
|
if (rest >= 16) {
|
||||||
return new ColoredPixel(new TextColor.RGB(0, 0, 0));
|
return new ColoredPixel(BORDER_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
GameItem item = items.get(part);
|
GameItem item = items.get(part);
|
||||||
BufferedImage texture = item.getTexture();
|
BufferedImage texture = item.getTexture();
|
||||||
log.debug("{} {}", rest, screenY);
|
|
||||||
int pixel = texture.getRGB(rest, screenY);
|
|
||||||
|
|
||||||
|
int pixel = texture.getRGB(rest, screenY);
|
||||||
int alpha = (pixel >> 24) & 0xff;
|
int alpha = (pixel >> 24) & 0xff;
|
||||||
|
|
||||||
if (alpha == 0) {
|
if (alpha == 0) {
|
||||||
return new ColoredPixel(
|
return new ColoredPixel(TRANSPARENT_COLOR);
|
||||||
new TextColor.RGB(255, 255, 255)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int red = (pixel >> 16) & 0xff;
|
return pixelToColored(pixel);
|
||||||
int green = (pixel >> 8) & 0xff;
|
}
|
||||||
int blue = pixel & 0xff;
|
|
||||||
|
|
||||||
return new ColoredPixel(
|
private boolean isBorder(int x, int y, int width, int height) {
|
||||||
new TextColor.RGB(red, green, blue)
|
return x <= 1 || x >= width - 2 || y <= 1 || y >= height - 2;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -192,22 +264,25 @@ public final class Chest extends GameObject implements Interactable, UIClickHand
|
|||||||
|
|
||||||
log.debug("Screen: x: {}, y: {}", screenX, screenY);
|
log.debug("Screen: x: {}, y: {}", screenX, screenY);
|
||||||
|
|
||||||
int part = screenX / 18;
|
if (screenX < 0 || screenY < 0 || screenX > chestUISizeX || screenY > chestUISizeY) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (screenX < 0 || screenY < 0 || screenX > chestUISizeX || screenY > chestUISizeY || part >= items.size()) {
|
int part = screenX / 18;
|
||||||
|
if (part >= items.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rest = screenX % 18;
|
int rest = screenX % 18;
|
||||||
if (rest == 17 || rest == 16) {
|
if (rest >= 16) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameItem item = items.get(part);
|
|
||||||
items.remove(part);
|
items.remove(part);
|
||||||
|
|
||||||
// TODO: Add item to inventory
|
if (items.isEmpty()) {
|
||||||
|
uiClickHandlerRepository.removeHandlerForCurrentRoom(listenerHashCode, this);
|
||||||
|
}
|
||||||
render(true);
|
render(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,9 @@ public class UIClickHandlerRepository {
|
|||||||
for (var entry : handlers.entrySet()) {
|
for (var entry : handlers.entrySet()) {
|
||||||
RerenderScreen.ScreenPart part = entry.getKey();
|
RerenderScreen.ScreenPart part = entry.getKey();
|
||||||
UIClickHandler uiClickHandler = entry.getValue();
|
UIClickHandler uiClickHandler = entry.getValue();
|
||||||
|
TerminalPosition position = new TerminalPosition(mouseAction.getPosition().getColumn(), mouseAction.getPosition().getRow() * 2);
|
||||||
|
|
||||||
if (part.isWithin(mouseAction.getPosition())) {
|
if (part.isWithin(position)) {
|
||||||
uiClickHandler.handleClick(mouseAction);
|
uiClickHandler.handleClick(mouseAction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user