Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Added synchronization for character selection in Multiplayer #718

Merged
merged 7 commits into from

2 participants

@GreenLightning

The character IDs are now saved in the player class and are now synchronized when the game is started!
This also fixes the issue that the wrong name was displayed on the game over screen!

@danielduner

@GreenLightning
There was a collision with the refactoring of the Level class in #713. Can you merge with HEAD to fix this?

@GreenLightning GreenLightning Merge remote branch 'original/develop' into develop
Conflicts:
	src/com/mojang/mojam/level/Level.java
6a45f32
@danielduner

You have proven reliable so far, so I'll just blindly merge these changes now. If something breaks, it's my fault! Banzai!

@danielduner danielduner merged commit 908dbcb into Maescool:develop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
80 src/com/mojang/mojam/MojamComponent.java
@@ -74,6 +74,7 @@
import com.mojang.mojam.network.packet.ChangeKeyCommand;
import com.mojang.mojam.network.packet.ChangeMouseButtonCommand;
import com.mojang.mojam.network.packet.ChangeMouseCoordinateCommand;
+import com.mojang.mojam.network.packet.CharacterCommand;
import com.mojang.mojam.network.packet.ChatCommand;
import com.mojang.mojam.network.packet.PingPacket;
import com.mojang.mojam.network.packet.StartGamePacket;
@@ -137,10 +138,10 @@
private boolean isServer;
private int localId;
public static int localTeam; //local team is the team of the client. This can be used to check if something should be only rendered on one person's screen
-
+
public int playerCharacter;
- public int opponentCharacter;
-
+ private boolean sendCharacter = false;
+
private Thread hostThread;
private static boolean fullscreen = false;
public static ISoundPlayer soundPlayer;
@@ -262,7 +263,6 @@ private void initInput(){
}
private void initCharacters(){
- opponentCharacter = Art.HERR_VON_SPECK;
if(!Options.isCharacterIDset()){
addMenu(new CharacterSelectionMenu());
}
@@ -274,10 +274,10 @@ public void showError(String s) {
addMenu(new GuiError(s));
}
- private synchronized void createLevel(String levelPath, GameMode mode) {
+ private synchronized void createLevel(String levelPath, GameMode mode, int characterID) {
LevelInformation li = LevelInformation.getInfoForPath(levelPath);
if (li != null) {
- createLevel(li, mode);
+ createLevel(li, mode, characterID);
return;
} else if (!isMultiplayer) {
showError("Missing map.");
@@ -285,37 +285,35 @@ private synchronized void createLevel(String levelPath, GameMode mode) {
showError("Missing map - Multiplayer");
}
- private synchronized void createLevel(LevelInformation li, GameMode mode) {
- if (!isMultiplayer)
- opponentCharacter = Art.NO_OPPONENT;
+ private synchronized void createLevel(LevelInformation li, GameMode mode, int characterID) {
try {
//level = Level.fromFile(li);
- level = mode.generateLevel(li, playerCharacter, opponentCharacter);
+ level = mode.generateLevel(li);
} catch (Exception ex) {
ex.printStackTrace();
showError("Unable to load map.");
return;
}
- initLevel();
+ initLevel(characterID);
paused = false;
}
- private synchronized void initLevel() {
+ private synchronized void initLevel(int characterID) {
if (level == null)
return;
- //level.init();
- players[0] = new Player(synchedKeys[0], synchedMouseButtons[0], level.width
- * Tile.WIDTH / 2 - 16, (level.height - 5 - 1) * Tile.HEIGHT
- - 16, Team.Team1, playerCharacter);
+ // level.init();
+ players[0] = new Player(synchedKeys[0], synchedMouseButtons[0], level.width * Tile.WIDTH
+ / 2 - 16, (level.height - 5 - 1) * Tile.HEIGHT - 16, Team.Team1, characterID);
players[0].setFacing(4);
level.addEntity(players[0]);
level.addEntity(new Base(34 * Tile.WIDTH, 7 * Tile.WIDTH, Team.Team1));
if (isMultiplayer) {
players[1] = new Player(synchedKeys[1], synchedMouseButtons[1], level.width
- * Tile.WIDTH / 2 - 16, 7 * Tile.HEIGHT - 16, Team.Team2, opponentCharacter);
+ * Tile.WIDTH / 2 - 16, 7 * Tile.HEIGHT - 16, Team.Team2, characterID);
level.addEntity(players[1]);
- level.addEntity(new Base(32 * Tile.WIDTH - 20,
- 32 * Tile.WIDTH - 20, Team.Team2));
+ level.addEntity(new Base(32 * Tile.WIDTH - 20, 32 * Tile.WIDTH - 20, Team.Team2));
+ } else {
+ players[1] = null;
}
player = players[localId];
player.setCanSee(true);
@@ -553,7 +551,8 @@ private void tick() {
if (level != null && level.victoryConditions != null) {
if(level.victoryConditions.isVictoryConditionAchieved()) {
int winner = level.victoryConditions.playerVictorious();
- int characterID = winner == MojamComponent.localTeam ? playerCharacter : opponentCharacter;
+ int characterID = winner == players[0].getTeam() ? players[0].getCharacterID()
+ : players[1].getCharacterID();
addMenu(new WinMenu(GAME_WIDTH, GAME_HEIGHT, winner, characterID));
level = null;
return;
@@ -582,7 +581,12 @@ private void tick() {
}
}
- if(level == null) {
+ if (sendCharacter) {
+ synchronizer.addCommand(new CharacterCommand(localId, playerCharacter));
+ sendCharacter = false;
+ }
+
+ if (level == null) {
mouseButtons.tick();
} else
if (level != null) {
@@ -651,15 +655,17 @@ private void tick() {
packetLink, localId, 2);
clearMenus();
- createLevel(TitleMenu.level, TitleMenu.defaultGameMode);
+ createLevel(TitleMenu.level, TitleMenu.defaultGameMode, playerCharacter);
synchronizer.setStarted(true);
if (TitleMenu.level.vanilla) {
- packetLink.sendPacket(new StartGamePacket(
- TurnSynchronizer.synchedSeed, TitleMenu.level.getUniversalPath(),DifficultyList.getDifficultyID(TitleMenu.difficulty)));
+ packetLink.sendPacket(new StartGamePacket(TurnSynchronizer.synchedSeed,
+ TitleMenu.level.getUniversalPath(), DifficultyList
+ .getDifficultyID(TitleMenu.difficulty), playerCharacter));
} else {
- packetLink.sendPacket(new StartGamePacketCustom(
- TurnSynchronizer.synchedSeed, level, DifficultyList.getDifficultyID(TitleMenu.difficulty), playerCharacter, opponentCharacter));
+ packetLink.sendPacket(new StartGamePacketCustom(TurnSynchronizer.synchedSeed,
+ level, DifficultyList.getDifficultyID(TitleMenu.difficulty),
+ playerCharacter));
}
packetLink.setPacketListener(MojamComponent.this);
@@ -758,6 +764,11 @@ public void handle(int playerId, NetworkCommand packet) {
chat.addMessage(cc.getMessage());
}
+ if (packet instanceof CharacterCommand) {
+ CharacterCommand charCommand = (CharacterCommand) packet;
+ players[charCommand.getPlayerID()].setCharacterID(charCommand.getCharacterID());
+ }
+
if (packet instanceof PauseCommand) {
PauseCommand pc = (PauseCommand) packet;
paused = pc.isPause();
@@ -773,21 +784,26 @@ public void handle(int playerId, NetworkCommand packet) {
public void handle(Packet packet) {
if (packet instanceof StartGamePacket) {
if (!isServer) {
+ sendCharacter = true;
StartGamePacket sgPacker = (StartGamePacket) packet;
synchronizer.onStartGamePacket(sgPacker);
- TitleMenu.difficulty = DifficultyList.getDifficulties().get(sgPacker.getDifficulty());
- createLevel(sgPacker.getLevelFile(), TitleMenu.defaultGameMode);
+ TitleMenu.difficulty = DifficultyList.getDifficulties().get(
+ sgPacker.getDifficulty());
+ createLevel(sgPacker.getLevelFile(), TitleMenu.defaultGameMode,
+ sgPacker.getOpponentCharacterID());
}
} else if (packet instanceof TurnPacket) {
synchronizer.onTurnPacket((TurnPacket) packet);
} else if (packet instanceof StartGamePacketCustom) {
if (!isServer) {
+ sendCharacter = true;
StartGamePacketCustom sgPacker = (StartGamePacketCustom) packet;
- synchronizer.onStartGamePacket((StartGamePacket)packet);
- TitleMenu.difficulty = DifficultyList.getDifficulties().get(sgPacker.getDifficulty());
+ synchronizer.onStartGamePacket((StartGamePacket) packet);
+ TitleMenu.difficulty = DifficultyList.getDifficulties().get(
+ sgPacker.getDifficulty());
level = sgPacker.getLevel();
paused = false;
- initLevel();
+ initLevel(sgPacker.getOpponentCharacterID());
}
} else if (packet instanceof PingPacket) {
PingPacket pp = (PingPacket)packet;
@@ -848,7 +864,7 @@ public void handleAction(int id) {
synchronizer = new TurnSynchronizer(this, null, 0, 1);
synchronizer.setStarted(true);
- createLevel(TitleMenu.level, TitleMenu.defaultGameMode);
+ createLevel(TitleMenu.level, TitleMenu.defaultGameMode, playerCharacter);
soundPlayer.stopBackgroundMusic();
break;
View
28 src/com/mojang/mojam/entity/Player.java
@@ -85,7 +85,7 @@
* @param y Initial y coordinate
* @param team Team number
*/
- public Player(Keys keys, MouseButtons mouseButtons, int x, int y, int team, int characterID) {
+ public Player(Keys keys, MouseButtons mouseButtons, int x, int y, int team, int characterID) {
super(x, y, team);
this.keys = keys;
this.mouseButtons = mouseButtons;
@@ -632,8 +632,12 @@ public void dropAllMoney() {
@Override
public void render(Screen screen) {
- Bitmap[][] sheet = Art.getPlayer(characterID);
-
+ Bitmap[][] sheet = Art.getPlayer(getCharacterID());
+
+ if(sheet == null){
+ return;
+ }
+
if (dead) {
// don't draw anything if we are dead (in a hole)
return;
@@ -663,6 +667,14 @@ public void render(Screen screen) {
screen.blit(Art.muzzle[muzzleImage][0], xmuzzle, ymuzzle);
}
}
+
+ public void setCharacterID(int characterID) {
+ this.characterID = characterID;
+ }
+
+ public int getCharacterID(){
+ return characterID;
+ }
@Override
public void renderTop(Screen screen) {
@@ -797,7 +809,7 @@ public void hurt(Entity source, float damage) {
* Revive the player. Carried items are lost, as is all the money.
*/
private void revive() {
- Notifications.getInstance().add(MojamComponent.texts.hasDiedCharacter(characterID));
+ Notifications.getInstance().add(MojamComponent.texts.hasDiedCharacter(getCharacterID()));
carrying = null;
dropAllMoney();
pos.set(startX, startY);
@@ -850,12 +862,4 @@ public Vec2 getPosition() {
return pos;
}
- /**
- * Get current player's characterID
- *
- * @return charakterID
- */
- public int getCharacterID() {
- return this.characterID;
- }
}
View
2  src/com/mojang/mojam/gui/CreditsScreen.java
@@ -59,7 +59,7 @@ public void render(Screen screen) {
drawNames(others, screen, 240);
// Back button character
- screen.blit(Art.getPlayer(MojamComponent.instance.playerCharacter)[0][6], (gameWidth - 128) / 2 - 40,
+ screen.blit(Art.getLocalPlayerArt()[0][6], (gameWidth - 128) / 2 - 40,
gameHeight - 50 - 20);
}
View
2  src/com/mojang/mojam/gui/LevelButton.java
@@ -75,7 +75,7 @@ private boolean buildMinimap(LevelInformation levelInfo) {
// Load level
Level l;
try {
- l = new GameMode().generateLevel(levelInfo, MojamComponent.instance.playerCharacter, MojamComponent.instance.opponentCharacter);
+ l = new GameMode().generateLevel(levelInfo);
} catch (IOException e) {
return false;
}
View
1  src/com/mojang/mojam/gui/WinMenu.java
@@ -15,6 +15,7 @@ public WinMenu(int gameWidth, int gameHeight, int winningPlayer, int characterID
super();
this.winningPlayer = winningPlayer;
this.gameWidth = gameWidth;
+ this.characterID = characterID;
addButton(new Button(TitleMenu.RETURN_TO_TITLESCREEN, "Ok", (gameWidth - 128) / 2, 200));
}
View
25 src/com/mojang/mojam/level/Level.java
@@ -42,17 +42,12 @@
public IVictoryConditions victoryConditions;
public int player1Score = 0;
public int player2Score = 0;
-
- public int player1Character;
- public int player2Character;
@SuppressWarnings("unchecked")
- public Level(int width, int height, int player1Character, int player2Character) {
+ public Level(int width, int height) {
neighbourOffsets = new int[] { -1, 1, -width, width };
this.width = width;
this.height = height;
- this.player1Character = player1Character;
- this.player2Character = player2Character;
minimap = new Bitmap(width, height);
@@ -320,14 +315,14 @@ private void renderTilesAndBases(Screen screen, int x0, int y0, int x1, int y1){
int xt = x - (width / 2) + 4;
int yt = y - 4;
if (xt >= 0 && yt >= 0 && xt < 7 && yt < 4 && (xt != 3 || yt < 3)) {
- screen.blit(Art.getPlayerBase(player2Character)[xt][yt], x * Tile.WIDTH, y
+ screen.blit(Art.getPlayerBase(getPlayerCharacterID(1))[xt][yt], x * Tile.WIDTH, y
* Tile.HEIGHT);
continue;
}
yt = y - (height - 8);
if (xt >= 0 && yt >= 0 && xt < 7 && yt < 4 && (xt != 3 || yt > 0)) {
- screen.blit(Art.getPlayerBase(player1Character)[xt][yt], x * Tile.WIDTH, y * Tile.HEIGHT);
+ screen.blit(Art.getPlayerBase(getPlayerCharacterID(0))[xt][yt], x * Tile.WIDTH, y * Tile.HEIGHT);
if ((xt == 0 || xt == 1 || xt == 5 || xt == 6) && yt == 0) {
screen.blit(Art.shadow_north, x * Tile.WIDTH, y * Tile.HEIGHT);
}
@@ -345,6 +340,10 @@ private void renderTilesAndBases(Screen screen, int x0, int y0, int x1, int y1){
}
}
}
+
+ private int getPlayerCharacterID(int playerID){
+ return MojamComponent.instance.players[playerID].getCharacterID();
+ }
private void renderTopOfWalls(Screen screen, int x0, int y0, int x1, int y1){
for (int y = y0; y <= y1; y++) {
@@ -563,13 +562,13 @@ private Bitmap calculateSmallMapDisplay() {
private void renderPlayerScores(Screen screen){
- String player1score = MojamComponent.texts.scoreCharacter(player1Character, player1Score * 100 / TARGET_SCORE);
+ String player1score = MojamComponent.texts.scoreCharacter(getPlayerCharacterID(0), player1Score * 100 / TARGET_SCORE);
Font.defaultFont().draw(screen, player1score, 280-player1score.length()*10, screen.h - 20); //adjust so it fits in the box
- screen.blit(Art.getPlayer(player1Character)[0][2], 262, screen.h-42);
+ screen.blit(Art.getPlayer(getPlayerCharacterID(0))[0][2], 262, screen.h-42);
- if (player2Character != Art.NO_OPPONENT) {
- Font.defaultFont().draw(screen, MojamComponent.texts.scoreCharacter(player2Character, player2Score * 100 / TARGET_SCORE), 56, screen.h - 36);
- screen.blit(Art.getPlayer(player2Character)[0][6], 19, screen.h-42);
+ if (MojamComponent.instance.players[1] != null && getPlayerCharacterID(1) != Art.NO_OPPONENT) {
+ Font.defaultFont().draw(screen, MojamComponent.texts.scoreCharacter(getPlayerCharacterID(1), player2Score * 100 / TARGET_SCORE), 56, screen.h - 36);
+ screen.blit(Art.getPlayer(getPlayerCharacterID(1))[0][6], 19, screen.h-42);
}
}
View
4 src/com/mojang/mojam/level/gamemode/GameMode.java
@@ -28,7 +28,7 @@
protected Level newLevel;
- public Level generateLevel(LevelInformation li, int player1Character, int player2Character) throws IOException {
+ public Level generateLevel(LevelInformation li) throws IOException {
BufferedImage bufferedImage;
//System.out.println("Loading level from file: "+li.getPath());
if(li.vanilla){
@@ -39,7 +39,7 @@ public Level generateLevel(LevelInformation li, int player1Character, int playe
int w = bufferedImage.getWidth() + LEVEL_BORDER_SIZE;
int h = bufferedImage.getHeight() + LEVEL_BORDER_SIZE;
- newLevel = new Level(w, h, player1Character, player2Character);
+ newLevel = new Level(w, h);
processLevelImage(bufferedImage, w, h);
darkenMap(w, h);
View
2  src/com/mojang/mojam/network/Packet.java
@@ -10,6 +10,7 @@
import com.mojang.mojam.network.packet.ChangeKeyCommand;
import com.mojang.mojam.network.packet.ChangeMouseButtonCommand;
import com.mojang.mojam.network.packet.ChangeMouseCoordinateCommand;
+import com.mojang.mojam.network.packet.CharacterCommand;
import com.mojang.mojam.network.packet.ChatCommand;
import com.mojang.mojam.network.packet.PingPacket;
import com.mojang.mojam.network.packet.StartGamePacket;
@@ -40,6 +41,7 @@ static void map(int id, Class<? extends Packet> clazz) {
map(104, ChangeMouseButtonCommand.class);
map(105, ChangeMouseCoordinateCommand.class);
map(106, ChatCommand.class);
+ map(107, CharacterCommand.class);
}
public final int getId() {
View
41 src/com/mojang/mojam/network/packet/CharacterCommand.java
@@ -0,0 +1,41 @@
+package com.mojang.mojam.network.packet;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import com.mojang.mojam.network.NetworkCommand;
+
+public class CharacterCommand extends NetworkCommand {
+
+ private int playerID;
+ private int characterID;
+
+ public CharacterCommand() {}
+
+ public CharacterCommand(int playerID, int characterID) {
+ this.playerID = playerID;
+ this.characterID = characterID;
+ }
+
+ public int getPlayerID() {
+ return playerID;
+ }
+
+ public int getCharacterID() {
+ return characterID;
+ }
+
+ @Override
+ public void read(DataInputStream dis) throws IOException {
+ playerID = dis.readInt();
+ characterID = dis.readInt();
+ }
+
+ @Override
+ public void write(DataOutputStream dos) throws IOException {
+ dos.writeInt(playerID);
+ dos.writeInt(characterID);
+ }
+
+}
View
17 src/com/mojang/mojam/network/packet/StartGamePacket.java
@@ -1,6 +1,8 @@
package com.mojang.mojam.network.packet;
-import java.io.*;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
import com.mojang.mojam.network.Packet;
@@ -9,14 +11,15 @@
private long gameSeed;
private String levelFile;
private int difficulty;
+ private int opponentCharacterID;
- public StartGamePacket() {
- }
+ public StartGamePacket() {}
- public StartGamePacket(long gameSeed, String levelFile, int difficulty) {
+ public StartGamePacket(long gameSeed, String levelFile, int difficulty, int opponentCharacterID) {
this.gameSeed = gameSeed;
this.levelFile = levelFile;
this.difficulty = difficulty;
+ this.opponentCharacterID = opponentCharacterID;
}
@Override
@@ -24,6 +27,7 @@ public void read(DataInputStream dis) throws IOException {
gameSeed = dis.readLong();
levelFile = dis.readUTF();
difficulty = dis.readInt();
+ opponentCharacterID = dis.readInt();
}
@Override
@@ -31,6 +35,7 @@ public void write(DataOutputStream dos) throws IOException {
dos.writeLong(gameSeed);
dos.writeUTF(levelFile);
dos.writeInt(difficulty);
+ dos.writeInt(opponentCharacterID);
}
public long getGameSeed() {
@@ -44,4 +49,8 @@ public String getLevelFile() {
public int getDifficulty() {
return difficulty;
}
+
+ public int getOpponentCharacterID() {
+ return opponentCharacterID;
+ }
}
View
47 src/com/mojang/mojam/network/packet/StartGamePacketCustom.java
@@ -10,21 +10,19 @@
public class StartGamePacketCustom extends StartGamePacket {
private long gameSeed;
- public Level level;
- public int levelWidth, levelHeight;
- public Short[] shorts;
- public int difficulty;
- public int player1Character, player2Character;
-
- public StartGamePacketCustom() {
- }
+ private Level level;
+ private int levelWidth, levelHeight;
+ private Short[] shorts;
+ private int difficulty;
+ private int opponentCharacterID;
+
+ public StartGamePacketCustom() {}
- public StartGamePacketCustom(long gameSeed, Level level, int difficulty, int player1Character, int player2Character) {
+ public StartGamePacketCustom(long gameSeed, Level level, int difficulty, int opponentCharacterID) {
this.gameSeed = gameSeed;
this.level = level;
this.difficulty = difficulty;
- this.player1Character = player1Character;
- this.player2Character = player2Character;
+ this.opponentCharacterID = opponentCharacterID;
}
@Override
@@ -32,11 +30,10 @@ public void read(DataInputStream dis) throws IOException {
gameSeed = dis.readLong();
levelWidth = dis.readInt();
levelHeight = dis.readInt();
- player1Character = dis.readInt();
- player2Character = dis.readInt();
-
+ opponentCharacterID = dis.readInt();
+
shorts = new Short[levelWidth * levelHeight];
- for(int i = 0; i < shorts.length; i++){
+ for (int i = 0; i < shorts.length; i++) {
shorts[i] = dis.readShort();
}
this.difficulty = dis.readInt();
@@ -47,22 +44,22 @@ public void write(DataOutputStream dos) throws IOException {
dos.writeLong(gameSeed);
dos.writeInt(level.width);
dos.writeInt(level.height);
- dos.writeInt(player1Character);
- dos.writeInt(player2Character);
- for(int i = 0; i < level.tiles.length; i++){
+ dos.writeInt(opponentCharacterID);
+ for (int i = 0; i < level.tiles.length; i++) {
dos.writeShort(TileID.tileToShort(level.tiles[i]));
}
dos.writeInt(difficulty);
}
+ @Override
public long getGameSeed() {
return gameSeed;
}
-
+
public Level getLevel() {
- level = new Level(levelWidth, levelHeight, player1Character, player2Character);
- for(int x = 0; x < level.width; x++){
- for(int y = 0; y < level.width; y++){
+ level = new Level(levelWidth, levelHeight);
+ for (int x = 0; x < level.width; x++) {
+ for (int y = 0; y < level.width; y++) {
int index = x + y * level.width;
level.setTile(x, y, TileID.shortToTile(shorts[index], level, x, y));
}
@@ -70,8 +67,14 @@ public Level getLevel() {
return level;
}
+ @Override
public int getDifficulty() {
return difficulty;
}
+ @Override
+ public int getOpponentCharacterID() {
+ return opponentCharacterID;
+ }
+
}
Something went wrong with that request. Please try again.