Skip to content

Commit

Permalink
finished fixing beds
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisj42 committed Jun 9, 2018
1 parent 90bc4b9 commit 1d30138
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 31 deletions.
11 changes: 7 additions & 4 deletions src/minicraft/core/Renderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,16 @@ private static void renderGui() {
if (Updater.saving) permStatus.add("Saving... " + Math.round(LoadingDisplay.getPercentage()) + "%");
if (Bed.sleeping()) permStatus.add("Sleeping...");
else if (!Game.isValidServer() && Bed.inBed(Game.player)) {
permStatus.add(Bed.getPlayersAwake() + " players still awake");
permStatus.add("");
permStatus.add("Press "+input.getMapping("exit")+" to stop trying to sleep");
int numAwake = Bed.getPlayersAwake();
permStatus.add(numAwake + " player"+(numAwake==1?"":"s")+" still awake");
permStatus.add(" ");
permStatus.add("Press "+input.getMapping("exit")+" to cancel");
}

if(permStatus.size() > 0) {
FontStyle style = new FontStyle(Color.WHITE).setYPos(Screen.h / 2 - 20, false).setRelTextPos(RelPos.TOP).setShadowType(Color.DARK_GRAY, false);
// FIXME this is left-aligned for some reason, when it should be center-aligned.
FontStyle style = new FontStyle(Color.WHITE).setYPos(Screen.h / 2 - 20, false).setRelTextPos(RelPos.TOP, false).setShadowType(Color.DARK_GRAY, false);

Font.drawParagraph(permStatus.toArray(new String[permStatus.size()]), screen, style, 1);
}

Expand Down
24 changes: 24 additions & 0 deletions src/minicraft/entity/furniture/Bed.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ else if(player instanceof RemotePlayer)
public static boolean sleeping() { return playersAwake == 0; }

public static boolean inBed(Player player) { return sleepingPlayers.containsKey(player); }
public static Level getBedLevel(Player player) {
Bed bed = sleepingPlayers.get(player);
if(bed == null)
return null;
return bed.getLevel();
}

// get the player "out of bed"; used on the client only.
public static void removePlayer(Player player) {
Expand All @@ -95,6 +101,24 @@ public static void removePlayer(Player player) {

public static void removePlayers() { sleepingPlayers.clear(); }

// client should not call this.
public static void restorePlayer(Player player) {
Bed bed = sleepingPlayers.remove(player);
if(bed != null) {
if(bed.getLevel() == null)
Game.levels[Game.currentLevel].add(player);
else
bed.getLevel().add(player);

if(!Game.ISONLINE)
playersAwake = 1;
else if(Game.isValidServer()) {
int total = Game.server.getNumPlayers();
playersAwake = total - sleepingPlayers.size();
Game.server.updateGameVars();
}
}
}
// client should not call this.
public static void restorePlayers() {
for(Player p: sleepingPlayers.keySet()) {
Expand Down
4 changes: 2 additions & 2 deletions src/minicraft/entity/mob/Mob.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public boolean move(int xa, int ya) { // Move the mob, overrides from Entity

boolean checkPlayers = Game.isValidServer() && (xa != 0 || ya != 0);
List<RemotePlayer> prevPlayers = null;
if(checkPlayers) prevPlayers = MinicraftServer.getPlayersInRange(this, true);
if(checkPlayers) prevPlayers = Game.server.getPlayersInRange(this, true);

if(!(Game.isValidServer() && this instanceof RemotePlayer)) { // this will be the case when the client has sent a move packet to the server. In this case, we DO want to always move.
// these should return true b/c the mob is still technically moving; these are just to make it move *slower*.
Expand Down Expand Up @@ -103,7 +103,7 @@ public boolean move(int xa, int ya) { // Move the mob, overrides from Entity
}

if(checkPlayers) {
List<RemotePlayer> activePlayers = MinicraftServer.getPlayersInRange(this, true);
List<RemotePlayer> activePlayers = Game.server.getPlayersInRange(this, true);
for(int i = 0; i < prevPlayers.size(); i++) {
if(activePlayers.contains(prevPlayers.get(i))) {
activePlayers.remove(prevPlayers.remove(i));
Expand Down
2 changes: 1 addition & 1 deletion src/minicraft/entity/mob/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ protected boolean updateField(String field, String val) {
return false;
}

public String getPlayerData() {
public final String getPlayerData() {
List<String> datalist = new ArrayList<>();
StringBuilder playerdata = new StringBuilder();
playerdata.append(Game.VERSION).append("\n");
Expand Down
11 changes: 10 additions & 1 deletion src/minicraft/entity/mob/RemotePlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import minicraft.core.io.InputHandler;
import minicraft.entity.Direction;
import minicraft.entity.Entity;
import minicraft.entity.furniture.Bed;
import minicraft.gfx.Color;
import minicraft.gfx.Font;
import minicraft.gfx.FontStyle;
Expand Down Expand Up @@ -100,7 +101,15 @@ public boolean shouldTrack(int xt, int yt, Level level) {
return shouldSync(level, xt, yt, entityTrackingBuffer); /// this means that there is one tile past the syncRadii in all directions, which marks the distance at which entities are added or removed.
}
private boolean shouldSync(Level level, int xt, int yt, int offset) { // IDEA make this isWithin(). Decided not to b/c different x and y radii.
if(level == null || level != getLevel())
if(level == null)
return false;
if(getLevel() == null) {
if(!Bed.inBed(this))
return false; // no excuse
if(level != Bed.getBedLevel(this))
return false;
}
else if(level != getLevel())
return false;

int px = x >> 4, py = y >> 4;
Expand Down
22 changes: 15 additions & 7 deletions src/minicraft/gfx/FontStyle.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.Arrays;

import minicraft.core.Game;
import minicraft.core.Network;
import minicraft.screen.RelPos;

public class FontStyle {
Expand Down Expand Up @@ -60,7 +62,7 @@ shadow false (norm shadow)
private int shadowColor;
private String shadowType;
//private int anchorMinX, anchorMaxX, anchorMinY, anchorMaxY; // specifies the anchor pos as the center of the two bounds, while also specifying paragraph dimensions.
private Point anchor;
private Point anchor, lineAnchor;
//private int xPosition = -1, yPosition = -1;
private RelPos relTextPos = RelPos.CENTER; // aligns the complete block of text with the anchor.
private RelPos relLinePos = RelPos.CENTER; // when setup for a paragraph with multiple lines, this determines the alignment of each line within the bounds of the paragraph.
Expand Down Expand Up @@ -105,14 +107,14 @@ public void draw(String msg, Screen screen) {

Dimension size = new Dimension(Font.textWidth(msg), Font.textHeight());

Rectangle textBounds = relTextPos.positionRect(size, anchor, new Rectangle());
Rectangle textBounds = relTextPos.positionRect(size, lineAnchor, new Rectangle());

if(padX != 0 || padY != 0) {
size.width += padX;
size.height += padY;
Rectangle textBox = relTextPos.positionRect(size, anchor, new Rectangle());
Rectangle textBox = relTextPos.positionRect(size, lineAnchor, new Rectangle());

relLinePos.positionRect(size, textBox, textBounds);
relLinePos.positionRect(textBounds.getSize(), textBox, textBounds);
}

// account for anchor
Expand Down Expand Up @@ -151,7 +153,8 @@ public void configureForParagraph(String[] para, int spacing) {
// either way, the draw method needs to use a different position.

Dimension size = new Dimension(Font.textWidth(para), para.length*(Font.textHeight()+spacing));
paraBounds = relLinePos.positionRect(size, anchor, new Rectangle());
paraBounds = relTextPos.positionRect(size, anchor, new Rectangle());

/*
if(yPosition == -1) { // yPosition is auto-centered
int centerYDouble = anchorMinY + anchorMaxY;
Expand All @@ -174,9 +177,12 @@ public void setupParagraphLine(String[] para, int line, int spacing) {
configureForParagraph(para, spacing);

//setYPos(paraMinY + line*Font.textHeight() + line*spacing);
Rectangle textArea = new Rectangle(paraBounds.getLeft(), paraBounds.getTop() + line*(Font.textHeight()+spacing), paraBounds.getWidth(), Font.textHeight()+spacing, Rectangle.CORNER_DIMS);
Rectangle textArea = new Rectangle(paraBounds);
textArea.setSize(textArea.getWidth(), Font.textHeight()+spacing, RelPos.TOP_LEFT);
textArea.translate(0, line*textArea.getHeight());
//Rectangle textArea = new Rectangle(paraBounds.getLeft(), paraBounds.getTop() + line*(Font.textHeight()+spacing), paraBounds.getWidth(), Font.textHeight()+spacing, Rectangle.CORNER_DIMS);

anchor = textArea.getPosition(relTextPos);
lineAnchor = textArea.getPosition(relTextPos);

padX = paraBounds.getWidth() - Font.textWidth(para[line]);
padY = spacing;
Expand All @@ -201,6 +207,7 @@ public FontStyle setColor(int col) {
public FontStyle setXPos(int pos) { return setXPos(pos, true); }
public FontStyle setXPos(int pos, boolean resetAlignment) {
anchor.x = pos;
lineAnchor = new Point(anchor);
if(resetAlignment) {
relTextPos = RelPos.getPos(RelPos.RIGHT.xIndex, relTextPos.yIndex);
relLinePos = RelPos.getPos(RelPos.LEFT.xIndex, relLinePos.yIndex);
Expand All @@ -211,6 +218,7 @@ public FontStyle setXPos(int pos, boolean resetAlignment) {
public FontStyle setYPos(int pos) { return setYPos(pos, true); }
public FontStyle setYPos(int pos, boolean resetAlignment) {
anchor.y = pos;
lineAnchor = new Point(anchor);
if(resetAlignment) {
relTextPos = RelPos.getPos(relTextPos.xIndex, RelPos.BOTTOM.yIndex);
// relLinePos = RelPos.getPos(relLinePos.xIndex, RelPos.BOTTOM.yIndex);
Expand Down
8 changes: 4 additions & 4 deletions src/minicraft/network/MinicraftClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ private void login(String username) {
//return null;
}

private static String getPlayerData(Player player) {
/*static String getPlayerData(Player player) {
StringBuilder playerdata = new StringBuilder();
List<String> sdata = new ArrayList<>();
Save.writePlayer(player, sdata);
Expand All @@ -178,7 +178,7 @@ private static String getPlayerData(Player player) {
playerdata.append(String.join(",", sdata.toArray(new String[0])));
return playerdata.toString();
}
}*/

/** This method is responsible for parsing all data received by the socket. */
public boolean parsePacket(InputType inType, String alldata) {
Expand Down Expand Up @@ -424,7 +424,7 @@ else if(!((RemotePlayer)Game.player).shouldTrack(entity.x >> 4, entity.y >> 4, e
if (Game.debug) System.out.println("CLIENT: received save request");
// send back the player data.
if (Game.debug) System.out.println("CLIENT: sending save data");
sendData(InputType.SAVE, getPlayerData(Game.player));
sendData(InputType.SAVE, Game.player.getPlayerData());
return true;

case NOTIFY:
Expand Down Expand Up @@ -598,7 +598,7 @@ public boolean checkConnection() {

public void endConnection() {
if(isConnected() && curState == State.PLAY)
sendData(InputType.SAVE, getPlayerData(Game.player)); // try to make sure that the player's info is saved before they leave.
sendData(InputType.SAVE, Game.player.getPlayerData()); // try to make sure that the player's info is saved before they leave.

pingTimeout.stop();

Expand Down
25 changes: 17 additions & 8 deletions src/minicraft/network/MinicraftServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,20 @@ public String[] getClientInfo() {
return playerStrings.toArray(new String[0]);
}

public static List<RemotePlayer> getPlayersInRange(Entity e, boolean useTrackRange) {
public List<RemotePlayer> getPlayersInRange(Entity e, boolean useTrackRange) {
if(e == null || e.getLevel() == null) return new ArrayList<>();
int xt = e.x >> 4, yt = e.y >> 4;
return getPlayersInRange(e.getLevel(), xt, yt, useTrackRange); // NOTE if "e" is a RemotePlayer, the list returned *will* contain "e".
}
public static List<RemotePlayer> getPlayersInRange(Level level, int xt, int yt, boolean useTrackRange) {
public List<RemotePlayer> getPlayersInRange(Level level, int xt, int yt, boolean useTrackRange) {
List<RemotePlayer> players = new ArrayList<>();
//if(e == null || e.getLevel() == null) return players;
/// screen is 18 tiles hori, 14 tiles vert. So, rect is 20x16 tiles.
//List<Entity> entities = level.getEntitiesInTiles(xt - RemotePlayer.xSyncRadius, yt - RemotePlayer.ySyncRadius, xt + RemotePlayer.xSyncRadius, yt + RemotePlayer.ySyncRadius);
for(Entity e: level.getEntitiesOfClass(RemotePlayer.class)) {
if(e.isRemoved()) continue;
RemotePlayer rp = (RemotePlayer)e;
for(MinicraftServerThread thread: getThreads()) {
RemotePlayer rp = thread.getClient();
//if(p.isRemoved()) continue;
//RemotePlayer rp = (RemotePlayer)e;
if(useTrackRange && rp.shouldTrack(xt, yt, level) || !useTrackRange && rp.shouldSync(xt, yt, level))
players.add(rp);
}
Expand Down Expand Up @@ -280,8 +281,13 @@ public void broadcastEntityAddition(Entity e, boolean addSelf) {
List<RemotePlayer> players = getPlayersInRange(e, true);
if(!addSelf)
players.remove(getIfPlayer(e)); // if "e" is a player, this removes it from the list.
for(MinicraftServerThread thread: getAssociatedThreads(players))
int cnt = 0;
if(Game.debug && e instanceof Player) System.out.println("SERVER: broadcasting player addition of "+e);
for(MinicraftServerThread thread: getAssociatedThreads(players)) {
thread.sendEntityAddition(e);
cnt++;
}
if(Game.debug && e instanceof Player) System.out.println("SERVER: broadcasted player addition of "+e+" to "+cnt+" clients");
}

//public void sendEntityAddition(Entity e, RemotePlayer sender) { sendEntityAddition(e, sender, false); }
Expand Down Expand Up @@ -459,7 +465,7 @@ boolean parsePacket(MinicraftServerThread serverThread, InputType inType, String

if(Game.player != null) {
// save the player, and then remove it. It is leftover from when this was a single player world.
playerdata = Game.VERSION+"\n"+Game.player.getPlayerData();
playerdata = Game.player.getPlayerData();
//if (Game.debug) System.out.println("SERVER: setting main player as remote from login.");
Game.player.remove(); // all the important data has been saved.
Game.player = null;
Expand Down Expand Up @@ -493,6 +499,8 @@ boolean parsePacket(MinicraftServerThread serverThread, InputType inType, String
clientPlayer.findStartPos(World.levels[World.lvlIdx(0)]); // find a new start pos
// this is a new player.
playerdata = clientPlayer.getPlayerData();
// save the new player once, immediately.
serverThread.writeClientSave(playerdata);
}
serverThread.sendData(InputType.PLAYER, playerdata);

Expand Down Expand Up @@ -775,7 +783,8 @@ boolean parsePacket(MinicraftServerThread serverThread, InputType inType, String
}
else {
if(Bed.sleeping()) return false; // can't quit once everyone is in bed

// else, get the player out of bed
Bed.restorePlayer(clientPlayer);
}
// if(Bed.inBed(clientPlayer) || !Bed.checkCanSleep(clientPlayer))
// return false;
Expand Down
4 changes: 2 additions & 2 deletions src/minicraft/network/MinicraftServerThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public void sendEntityUpdate(Entity e, String updateString) {
}

public void sendEntityAddition(Entity e) {
if(Game.debug && e instanceof Player) System.out.println("");
if(Game.debug && e instanceof Player) System.out.println("SERVER: sending addition of player "+e+" to client through "+this);
if(Game.debug && e.eid == client.eid) System.out.println("SERVER: sending addition of player to itself");
String edata = Save.writeEntity(e, false);
if(edata.length() == 0)
Expand Down Expand Up @@ -288,7 +288,7 @@ protected void writeClientSave(String playerdata) {
filename = "RemotePlayer"+numFiles+Save.extension;
}

String filedata = String.join("\n", client.getUsername(), Game.VERSION, playerdata);
String filedata = String.join("\n", client.getUsername(), playerdata);

String filepath = serverInstance.getWorldPath()+"/"+filename;
try {
Expand Down
4 changes: 2 additions & 2 deletions src/minicraft/saveload/Load.java
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ public void loadPlayer(Player player, List<String> origData) {
Game.currentLevel = Integer.parseInt(data.remove(0));
Level level = World.levels[Game.currentLevel];
if(!player.isRemoved()) player.remove(); // removes the user player from the level, in case they would be added twice.
if(level != null)
if(level != null && !(Game.isValidServer() && player == Game.player))
level.add(player);
else if(Game.debug) System.out.println(Network.onlinePrefix()+"game level to add player " + player + " to is null.");
//Tile spawnTile = level.getTile(player.spawnx >> 4, player.spawny >> 4);
Expand Down Expand Up @@ -534,7 +534,7 @@ public static Entity loadEntity(String entityData, Version worldVer, boolean isL

if(Game.isValidClient()) {
if(eid == Game.player.eid)
return Game.player;
return Game.player; // don't reload the main player via an entity addition, though do add it to the level (will be done elsewhere)
if(Game.player instanceof RemotePlayer &&
!((RemotePlayer)Game.player).shouldTrack(x >> 4, y >> 4, World.levels[entityLevel])
) {
Expand Down

0 comments on commit 1d30138

Please sign in to comment.