Skip to content

Commit

Permalink
WIP fixing beds in multiplayer
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisj42 committed Jun 9, 2018
1 parent 248fc0d commit 90bc4b9
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 65 deletions.
21 changes: 15 additions & 6 deletions src/minicraft/core/Renderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import minicraft.item.ToolType;
import minicraft.level.Level;
import minicraft.screen.LoadingDisplay;
import minicraft.screen.RelPos;

public class Renderer extends Game {
private Renderer() {}
Expand Down Expand Up @@ -164,12 +165,20 @@ private static void renderGui() {
//displays arrow icon
screen.render(10 * 8 + 4, Screen.h - 16, 13 + 5 * 32, Color.get(0, 111, 222, 430), 0);

ArrayList<String> permStatus = new ArrayList<>();
String msg = "";
if (Updater.saving) msg = "Saving... " + Math.round(LoadingDisplay.getPercentage()) + "%";
else if (Bed.inBed) msg = "Sleeping...";
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");
}

if(msg.length() > 0)
new FontStyle(Color.WHITE).setYPos(Screen.h / 2 - 20).setShadowType(Color.DARK_GRAY, false).draw(msg, screen);
if(permStatus.size() > 0) {
FontStyle style = new FontStyle(Color.WHITE).setYPos(Screen.h / 2 - 20, false).setRelTextPos(RelPos.TOP).setShadowType(Color.DARK_GRAY, false);
Font.drawParagraph(permStatus.toArray(new String[permStatus.size()]), screen, style, 1);
}

/// NOTIFICATIONS

Expand Down Expand Up @@ -282,7 +291,7 @@ private static void renderDebugInfo() {
ArrayList<String> info = new ArrayList<>();
info.add("VERSION " + Initializer.VERSION);
info.add(Initializer.fra + " fps");
info.add("day tiks " + Updater.tickCount);
info.add("day tiks " + Updater.tickCount+" ("+Updater.getTime()+")");
info.add((Updater.normSpeed * Updater.gamespeed) + " tik/sec");
if(!isValidServer()) {
info.add("walk spd " + player.moveSpeed);
Expand Down Expand Up @@ -327,7 +336,7 @@ private static void renderDebugInfo() {
private static void renderFocusNagger() {
String msg = "Click to focus!"; // the message when you click off the screen.
Updater.paused = true; //perhaps paused is only used for this.
int xx = Font.centerX(msg, 0, Screen.w); // the width of the box
int xx = (Screen.w - Font.textWidth(msg)) / 2; // the width of the box
int yy = (HEIGHT - 8) / 2; // the height of the box
int w = msg.length(); // length of message in characters.
int h = 1;
Expand Down
15 changes: 10 additions & 5 deletions src/minicraft/core/Updater.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public static void tick() {
Game.client.checkConnection();

Level level = levels[currentLevel];
if (Bed.inBed && !isValidClient()) {
if (Bed.sleeping() && !isValidClient()) {
// IN BED
//Bed.player.remove();
if(gamespeed != 20) {
Expand All @@ -91,18 +91,21 @@ public static void tick() {
}
}
if(tickCount > sleepEndTime) {
if(Game.debug) System.out.println(Network.onlinePrefix()+"passing midnight in bed");
pastDay1 = true;
tickCount = 0;
if(isValidServer())
server.updateGameVars();
}
if (tickCount <= sleepStartTime && tickCount >= sleepEndTime) { // it has reached morning.
if(Game.debug) System.out.println(Network.onlinePrefix()+"reached morning, getting out of bed");
gamespeed = 1;
if(isValidServer()) {
server.updateGameVars();
server.setBed(false);
//server.setBed(false);
}
else {
Bed.restorePlayers();
/*else {
Player playerInBed = Bed.restorePlayer();
// seems this removes all entities within a certain radius of the player when you get OUT of Bed.
Expand All @@ -116,7 +119,7 @@ public static void tick() {
}
}
}
}
}*/
}
}

Expand Down Expand Up @@ -195,7 +198,7 @@ else if(isValidServer())

if(!isValidServer()) {
//if player is alive, but no level change, nothing happens here.
if (player.isRemoved() && Renderer.readyToRenderGameplay && !Bed.inBed) {
if (player.isRemoved() && Renderer.readyToRenderGameplay && !Bed.inBed(player)) {
//makes delay between death and death menu.
World.playerDeadTime++;
if (World.playerDeadTime > 60) {
Expand All @@ -207,6 +210,8 @@ else if(isValidServer())
}

player.tick(); // ticks the player when there's no menu.
if(isValidClient() && Bed.inBed(player) && !Bed.sleeping() && input.getKey("exit").clicked)
Game.client.sendBedExitRequest();

if(level != null) {
level.tick(true);
Expand Down
2 changes: 1 addition & 1 deletion src/minicraft/core/World.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static void resetGame() {
PlayerDeathDisplay.shouldRespawn = false;
resetGame();
player = new Player(null, input);
Bed.inBed = false;
Bed.removePlayers();
Updater.gameTime = 0;
Updater.gamespeed = 1;

Expand Down
2 changes: 2 additions & 0 deletions src/minicraft/entity/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ public void remove() {
else
level.remove(this);
}

/** This should ONLY be called by the Level class. To properly remove an entity from a level, use level.remove(entity) */
public void remove(Level level) {
if(level != this.level) {
if(Game.debug) System.out.println("tried to remove entity " + this + " from level it is not in: " + level + "; in level " + this.level);
Expand Down
87 changes: 67 additions & 20 deletions src/minicraft/entity/furniture/Bed.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package minicraft.entity.furniture;

import java.util.HashMap;

import minicraft.core.Game;
import minicraft.core.Network;
import minicraft.core.Updater;
Expand All @@ -10,46 +12,61 @@
import minicraft.level.Level;

public class Bed extends Furniture {
public static boolean inBed = false; // If a player is in a bed.
private static Player player = null; // the player that is in bed.
private static Level playerLevel = null; // the player that is in bed.
//public static boolean inBed = false; // If a player is in a bed.

private static int playersAwake = 1;
private static final HashMap<Player, Bed> sleepingPlayers = new HashMap<>();

public Bed() {
super("Bed", new Sprite(16, 8, 2, 2, Color.get(-1, 100, 444, 400)), 3, 2);
}

/** Called when the player attempts to get in bed. */
public boolean use(Player player) {
if (checkCanSleep()) { // if it is late enough in the day to sleep...
if(Game.isValidServer()) {
if(inBed) return false;
Game.server.setBed(true);
if (checkCanSleep(player)) { // if it is late enough in the day to sleep...
/*if(Game.isValidServer()) {
// if(inBed) return false;
// Game.server.setBed(true);
return true;
}
}*/

// set the player spawn coord. to their current position, in tile coords (hence " >> 4")
player.spawnx = player.x >> 4;
player.spawny = player.y >> 4;

//player.bedSpawn = true; // the bed is now set as the player spawn point.
Bed.player = player;
Bed.playerLevel = player.getLevel();
Bed.inBed = true;
// this.player = player;
// this.playerLevel = player.getLevel();
sleepingPlayers.put(player, this);
if(Game.isConnectedClient() && player == Game.player) {
Game.client.sendBedRequest(player, this);
Game.client.sendBedRequest(this);
}
if (Game.debug) System.out.println(Network.onlinePrefix()+"player got in bed: " + player);
//else {
player.remove();
//if(Game.isValidServer() && player instanceof RemotePlayer)
// Game.server.getAssociatedThread((RemotePlayer)player).sendEntityRemoval(player.eid);
//}
player.remove();

if(!Game.ISONLINE)
playersAwake = 0;
else if(Game.isValidServer()) {
int total = Game.server.getNumPlayers();
playersAwake = total - sleepingPlayers.size();
Game.server.updateGameVars();
}
}

return true;
}

public static boolean checkCanSleep() {
public static int getPlayersAwake() { return playersAwake; }
public static void setPlayersAwake(int count) {
if(!Game.isValidClient())
throw new IllegalStateException("Bed.setPlayersAwake() can only be called on a client runtime");

playersAwake = count;
}

public static boolean checkCanSleep(Player player) {
if(inBed(player)) return false;

if(!(Updater.tickCount >= Updater.sleepStartTime || Updater.tickCount < Updater.sleepEndTime && Updater.pastDay1)) {
// it is too early to sleep; display how much time is remaining.
int sec = (int)Math.ceil((Updater.sleepStartTime - Updater.tickCount)*1.0 / Updater.normSpeed); // gets the seconds until sleeping is allowed. // normSpeed is in tiks/sec.
Expand All @@ -67,7 +84,37 @@ else if(player instanceof RemotePlayer)
return true;
}

public static Player restorePlayer() {
public static boolean sleeping() { return playersAwake == 0; }

public static boolean inBed(Player player) { return sleepingPlayers.containsKey(player); }

// get the player "out of bed"; used on the client only.
public static void removePlayer(Player player) {
sleepingPlayers.remove(player);
}

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

// client should not call this.
public static void restorePlayers() {
for(Player p: sleepingPlayers.keySet()) {
Bed bed = sleepingPlayers.get(p);
if(p instanceof RemotePlayer && Game.isValidServer() && !Game.server.getAssociatedThread((RemotePlayer)p).isConnected())
continue; // forget about it, don't add it to the level
bed.getLevel().add(p);
}

sleepingPlayers.clear();

if(!Game.ISONLINE)
playersAwake = 1;
else if(Game.isValidServer()) {
playersAwake = Game.server.getNumPlayers();
Game.server.updateGameVars();
}
}

/*public static Player restorePlayer() {
if(Bed.playerLevel != null) {
Bed.playerLevel.add(Bed.player); // this adds the player to all the other clients' levels
if(Game.isValidServer() && player instanceof RemotePlayer)
Expand All @@ -79,5 +126,5 @@ public static Player restorePlayer() {
Bed.player = null;
Bed.inBed = false;
return p;
}
}*/
}
2 changes: 1 addition & 1 deletion src/minicraft/entity/mob/EnemyMob.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void tick() {
super.tick();

Player player = getClosestPlayer();
if (player != null && !Bed.inBed && randomWalkTime <= 0) { // checks if player is on zombies level and if there is no time left on randonimity timer
if (player != null && !Bed.sleeping() && randomWalkTime <= 0) { // checks if player is on zombies level and if there is no time left on randonimity timer
int xd = player.x - x;
int yd = player.y - y;
if (xd * xd + yd * yd < detectDist * detectDist) {
Expand Down
8 changes: 4 additions & 4 deletions src/minicraft/entity/mob/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public void tick() {

super.tick(); // ticks Mob.java

if(potioneffects.size() > 0 && !Bed.inBed) {
if(potioneffects.size() > 0 && !Bed.inBed(this)) {
for(PotionType potionType: potioneffects.keySet().toArray(new PotionType[0])) {
if(potioneffects.get(potionType) <= 1) // if time is zero (going to be set to 0 in a moment)...
PotionItem.applyPotion(this, potionType, false); // automatically removes this potion effect.
Expand Down Expand Up @@ -245,7 +245,7 @@ public void tick() {
}

/// this if statement encapsulates the hunger system
if(!Bed.inBed) {
if(!Bed.inBed(this)) {
if(hungerChargeDelay > 0) { // if the hunger is recharging health...
stamHungerTicks -= 2+diffIdx; // penalize the hunger
if(hunger == maxHunger) stamHungerTicks -= diffIdx; // further penalty if at full hunger
Expand Down Expand Up @@ -306,7 +306,7 @@ public void tick() {
Updater.savecooldown--;


if (Game.getMenu() == null && !Bed.inBed) {
if (Game.getMenu() == null && !Bed.inBed(this)) {
// this is where movement detection occurs.
int xa = 0, ya = 0;
if (input.getKey("up").down) ya--;
Expand Down Expand Up @@ -829,7 +829,7 @@ public void hurt(Tnt tnt, int dmg) {
/** What happens when the player is hurt */
@Override
protected void doHurt(int damage, Direction attackDir) {
if (Game.isMode("creative") || hurtTime > 0 || Bed.inBed) return; // can't get hurt in creative, hurt cooldown, or while someone is in bed
if (Game.isMode("creative") || hurtTime > 0 || Bed.inBed(this)) return; // can't get hurt in creative, hurt cooldown, or while someone is in bed

if(Game.isValidServer() && this instanceof RemotePlayer) {
// let the clients deal with it.
Expand Down
2 changes: 1 addition & 1 deletion src/minicraft/level/Level.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ public void tick(boolean fullTick) {

if(!inLevel) {
if(Game.isValidServer())
Game.server.broadcastEntityAddition(entity);
Game.server.broadcastEntityAddition(entity, true);

if (!Game.isValidServer() || !(entity instanceof Particle)) {
if (Game.debug) printEntityStatus("Adding ", entity, "furniture.DungeonChest", "mob.AirWizard", "mob.Player");
Expand Down
20 changes: 11 additions & 9 deletions src/minicraft/network/MinicraftClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public boolean parsePacket(InputType inType, String alldata) {
case PING:
pingTimeout.restart();
missedPings = 0;
if(Game.debug) System.out.println("CLIENT: received server ping, reset missed ping count");
//if(Game.debug) System.out.println("CLIENT: received server ping, reset missed ping count");
sendData(InputType.PING, alldata);
return true;

Expand All @@ -214,6 +214,7 @@ public boolean parsePacket(InputType inType, String alldata) {
Updater.gamespeed = Float.parseFloat(data[2]);
Updater.pastDay1 = Boolean.parseBoolean(data[3]);
Updater.scoreTime = Integer.parseInt(data[4]);
Bed.setPlayersAwake(Integer.parseInt(data[5]));

if(Game.isMode("creative"))
Items.fillCreativeInv(Game.player.getInventory(), false);
Expand Down Expand Up @@ -323,7 +324,7 @@ public boolean parsePacket(InputType inType, String alldata) {
if(curState == State.LOADING)
System.out.println("CLIENT: received entity addition while loading level");

//if (Game.debug) System.out.println("CLIENT: received entity addition: " + alldata);
if (Game.debug) System.out.println("CLIENT: received entity addition: " + alldata);

if(alldata.length() == 0) {
System.err.println("CLIENT WARNING: received entity addition is blank...");
Expand All @@ -335,7 +336,7 @@ public boolean parsePacket(InputType inType, String alldata) {
if(addedEntity.eid == Game.player.eid/* && Game.player.getLevel() == null*/) {
if (Game.debug) System.out.println("CLIENT: added main game player back to level based on add packet");
World.levels[Game.currentLevel].add(Game.player);
Bed.inBed = false;
Bed.removePlayer(Game.player);
}

if(entityRequests.containsKey(addedEntity.eid))
Expand Down Expand Up @@ -494,8 +495,9 @@ else if(!((RemotePlayer)Game.player).shouldTrack(entity.x >> 4, entity.y >> 4, e
((Player)p).hurt(damage, attackDir);
return true;

case BED:
if (Game.debug) System.out.println("received bed request: " + alldata);
/*case BED:
Bed.setPlayersAwake(Integer.parseInt(alldata));
*//*if (Game.debug) System.out.println("received bed request: " + alldata);
boolean inBed = Boolean.parseBoolean(alldata);
if(Bed.inBed == inBed) return false; // no action needed.
Bed.inBed = inBed;
Expand All @@ -504,9 +506,8 @@ else if(!((RemotePlayer)Game.player).shouldTrack(entity.x >> 4, entity.y >> 4, e
else {
Game.levels[Game.currentLevel].add(Game.player);
move(Game.player);
}
return true;

}*//*
return true;*/
case STAMINA:
Game.player.payStamina(Integer.parseInt(alldata));
return true;
Expand Down Expand Up @@ -580,7 +581,8 @@ public void pickupItem(ItemEntity ie) {

public void sendShirtColor() { sendData(InputType.SHIRT, Game.player.shirtColor+""); }

public void sendBedRequest(Player player, Bed bed) { sendData(InputType.BED, String.valueOf(bed.eid)); }
public void sendBedRequest(Bed bed) { sendData(InputType.BED, "true;"+String.valueOf(bed.eid)); }
public void sendBedExitRequest() { sendData(InputType.BED, "false"); }

public void requestLevel(int lvlidx) {
Game.currentLevel = lvlidx; // just in case.
Expand Down
Loading

0 comments on commit 90bc4b9

Please sign in to comment.