diff --git a/src/java/com/threerings/parlor/game/server/GameManager.java b/src/java/com/threerings/parlor/game/server/GameManager.java index 8aca2c6ea..6cab1fe9d 100644 --- a/src/java/com/threerings/parlor/game/server/GameManager.java +++ b/src/java/com/threerings/parlor/game/server/GameManager.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.Iterator; import com.samskivert.util.Interval; +import com.samskivert.util.IntListUtil; import com.samskivert.util.RepeatCallTracker; import com.samskivert.util.StringUtil; import com.threerings.util.Name; @@ -370,7 +371,8 @@ public class GameManager extends PlaceManager */ public boolean isActivePlayer (int pidx) { - return _gameobj.isActivePlayer(pidx); + return _gameobj.isActivePlayer(pidx) && + (getPlayerOid(pidx) > 0 || isAI(pidx)); } /** @@ -541,6 +543,12 @@ public class GameManager extends PlaceManager super.bodyLeft(bodyOid); // deal with disappearing players + int pidx = IntListUtil.indexOf(_playerOids, bodyOid); + if (pidx != -1 && _gameobj.isInPlay() && + _gameobj.isActivePlayer(pidx)) { + // end the player's game if they bail on an in-progress puzzle + endPlayerGame(pidx); + } } /** @@ -659,18 +667,6 @@ public class GameManager extends PlaceManager // TEMP: clear out our game end tracker _gameEndTracker.clear(); - // TODO: find the right place to put this - // any players who have not claimed that they are ready should now - // be given le boote royale - for (int ii = 0; ii < _playerOids.length; ii++) { - if (_playerOids[ii] == -1) { - Log.info("Booting no-show player [game=" + _gameobj.which() + - ", player=" + getPlayerName(ii) + "]."); - _playerOids[ii] = 0; // unfiddle the blank oid - endPlayerGame(ii); - } - } - // make sure everyone has turned up if (!allPlayersReady()) { Log.warning("Requested to start a game that is still " + @@ -756,6 +752,17 @@ public class GameManager extends PlaceManager if (_AIs != null && needsAITick()) { AIGameTicker.registerAIGame(this); } + + // any players who have not claimed that they are ready should now + // be given le boote royale + for (int ii = 0; ii < _playerOids.length; ii++) { + if (_playerOids[ii] == -1) { + Log.info("Booting no-show player [game=" + _gameobj.which() + + ", player=" + getPlayerName(ii) + "]."); + _playerOids[ii] = 0; // unfiddle the blank oid + endPlayerGame(ii); + } + } } /** @@ -791,14 +798,15 @@ public class GameManager extends PlaceManager // end the player's game if (_gameobj.playerStatus != null) { _gameobj.setPlayerStatusAt(GameObject.PLAYER_LEFT_GAME, pidx); - - // let derived classes do some business - playerGameDidEnd(pidx); } + // let derived classes do some business + playerGameDidEnd(pidx); + String message = MessageBundle.tcompose( "m.player_game_over", getPlayerName(pidx)); systemMessage(GAME_MESSAGE_BUNDLE, message); + } finally { _gameobj.commitTransaction(); } diff --git a/src/java/com/threerings/parlor/turn/server/TurnGameManagerDelegate.java b/src/java/com/threerings/parlor/turn/server/TurnGameManagerDelegate.java index 22824da26..22f357dfb 100644 --- a/src/java/com/threerings/parlor/turn/server/TurnGameManagerDelegate.java +++ b/src/java/com/threerings/parlor/turn/server/TurnGameManagerDelegate.java @@ -180,9 +180,14 @@ public class TurnGameManagerDelegate extends GameManagerDelegate protected void setFirstTurnHolder () { int size = _turnGame.getPlayers().length; - do { - _turnIdx = RandomUtil.getInt(size); - } while (_tgmgr.getPlayerName(_turnIdx) == null); + int firstPick = _turnIdx = RandomUtil.getInt(size); + while (!_tgmgr.isActivePlayer(_turnIdx)) { + _turnIdx = (_turnIdx + 1) % size; + if (_turnIdx == firstPick) { + Log.warning("No players eligible for first turn. Choking."); + return; + } + } } /** diff --git a/src/java/com/threerings/puzzle/data/PuzzleCodes.java b/src/java/com/threerings/puzzle/data/PuzzleCodes.java index 1b0628c2e..aa9cf0a34 100644 --- a/src/java/com/threerings/puzzle/data/PuzzleCodes.java +++ b/src/java/com/threerings/puzzle/data/PuzzleCodes.java @@ -34,14 +34,6 @@ public interface PuzzleCodes extends InvocationCodes /** The default puzzle difficulty level. */ public static final int DEFAULT_DIFFICULTY = 2; - /** The name of the message event to a placeObject that a player - * was knocked out of a puzzle. */ - public static final String PLAYER_KNOCKED_OUT = "playerKnocked"; - - /** The name of the message event to a placeObject that reports - * the winners and losers of a game. */ - public static final String WINNERS_AND_LOSERS = "winnersAndLosers"; - /** Whether to enable debug logging and assertions for puzzles. Note * that enabling this may result in the server or client exiting * unexpectedly if certain error conditions arise in order to diff --git a/src/java/com/threerings/puzzle/server/PuzzleManager.java b/src/java/com/threerings/puzzle/server/PuzzleManager.java index 2376327e5..491f0f67c 100644 --- a/src/java/com/threerings/puzzle/server/PuzzleManager.java +++ b/src/java/com/threerings/puzzle/server/PuzzleManager.java @@ -112,20 +112,16 @@ public abstract class PuzzleManager extends GameManager } } - /** - * Ends the game for the given player. - */ - public void endPlayerGame (int pidx) + // documentation inherited + protected void playerGameDidEnd (int pidx) { - // don't update board summaries for AI players since they keep - // their own board summary up to date + super.playerGameDidEnd(pidx); + if (!isAI(pidx)) { // update the board summary with the player's final board updateBoardSummary(pidx); } - super.endPlayerGame(pidx); - // force a status update updateStatus(); } @@ -459,18 +455,6 @@ public abstract class PuzzleManager extends GameManager return false; } - // documentation inherited - protected void bodyLeft (int bodyOid) - { - super.bodyLeft(bodyOid); - - int pidx = IntListUtil.indexOf(_playerOids, bodyOid); - if (pidx != -1 && _puzobj.isInPlay() && _puzobj.isActivePlayer(pidx)) { - // end the player's game if they bail on an in-progress puzzle - endPlayerGame(pidx); - } - } - /** * Overrides the game manager implementation to mark all active * players as winners. Derived classes may wish to override this