More stuff with ending player games:

- If a player leaves, handle the ending of their game in GameManager.
- don't start the turn first turn in turn-based games on a missing player
- Let derived classes get playerGameDidEnd() even if the game doesn't
  have statuses.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3640 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2005-07-01 23:56:54 +00:00
parent e1338dca1e
commit b603e6b051
4 changed files with 36 additions and 47 deletions
@@ -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();
}
@@ -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;
}
}
}
/**
@@ -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
@@ -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