Did away with PartyGameConfig, added getGameType() to GameConfig.

Changed the names of the 3 standard game types, but I could be convinced
of better names:

SEATED_GAME: normal match-made game, a game with a set list of players that
             does not change.
SEATED_CONTINUOUS: the game starts immediately, but people join the room
             and then choose a place to sit to become a player.
PARTY: no seats, anyone that enters is a player.

Also, changed SEATED_CONTINUOUS to create an occupants array and auto-sit
the creator, since I'm pretty sure we'll want to show seating in the lobby
for those types of games (but it actually does neither right now, code
needs to be written either way, depending on UI decisions.)


git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@182 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
Ray Greenwell
2007-02-13 00:50:29 +00:00
parent 400389ca03
commit de354c0e7b
18 changed files with 122 additions and 248 deletions
@@ -13,8 +13,6 @@ import com.threerings.crowd.client.PlaceController;
import com.threerings.parlor.game.client.GameConfigurator;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.parlor.game.data.PartyGameConfig;
import com.threerings.parlor.game.data.PartyGameCodes;
import com.threerings.ezgame.client.EZGameController;
@@ -22,7 +20,7 @@ import com.threerings.ezgame.client.EZGameController;
* A game config for a simple multiplayer ez game.
*/
public class EZGameConfig extends GameConfig
implements PartyGameConfig, Hashable
implements Hashable
{
// TODO: this will eventually contain various XML configuration bits,
// or we'll expand this to contain other information.
@@ -30,8 +28,8 @@ public class EZGameConfig extends GameConfig
public var configData :String;
// TODO: this is separate right now, but may eventually be extracted
// from configData? Do not read this value, use getPartyGameType()
public var partyGameType :int = PartyGameCodes.NOT_PARTY_GAME;
// from configData? Do not read this value, use getGameType()
public var gameType :int = SEATED_GAME;
/** If non-zero, a game id used to persistently identify the game.
* This could be thought of as a new-style rating id. */
@@ -42,6 +40,11 @@ public class EZGameConfig extends GameConfig
// nothing needed
}
override public function getGameType () :int
{
return gameType;
}
// from abstract GameConfig
override public function getBundleName () :String
{
@@ -69,12 +72,6 @@ public class EZGameConfig extends GameConfig
throw new Error("Not implemented.");
}
// from PartyGameConfig
public function getPartyGameType () :int
{
return partyGameType;
}
override public function hashCode () :int
{
return super.hashCode(); // TODO: incorporate configData?
@@ -96,7 +93,7 @@ public class EZGameConfig extends GameConfig
super.readObject(ins);
configData = (ins.readField(String) as String);
partyGameType = ins.readByte();
gameType = ins.readByte();
persistentGameId = ins.readInt();
}
@@ -106,7 +103,7 @@ public class EZGameConfig extends GameConfig
super.writeObject(out);
out.writeField(configData);
out.writeByte(partyGameType);
out.writeByte(gameType);
out.writeInt(persistentGameId);
}
}
@@ -312,7 +312,7 @@ public class TableDirector extends BasicDirector
log.warning("Table created, but where is it? [tableId=" + tableId + "]");
return;
}
if (table.gameOid != 0 && table.isPartyGame()) {
if (table.gameOid != -1 && (table.occupants == null)) {
// let's boogie!
_pctx.getParlorDirector().gameIsReady(table.gameOid);
}
+21 -33
View File
@@ -38,8 +38,6 @@ import com.threerings.crowd.data.BodyObject;
import com.threerings.parlor.data.ParlorCodes;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.parlor.game.data.PartyGameCodes;
import com.threerings.parlor.game.data.PartyGameConfig;
/**
* This class represents a table that is being used to matchmake a game by
@@ -152,28 +150,6 @@ public class Table
return newTeams;
}
/**
* Return true if the game is a party game.
*/
public function isPartyGame () :Boolean
{
return (PartyGameCodes.NOT_PARTY_GAME != getPartyGameType());
}
/**
* Get the type of party game being played at this table, or
* PartyGameCodes.NOT_PARTY_GAME.
*/
public function getPartyGameType () :int
{
if (config is PartyGameConfig) {
return (config as PartyGameConfig).getPartyGameType();
} else {
return PartyGameCodes.NOT_PARTY_GAME;
}
}
// /**
// * Requests to seat the specified user at the specified position in
// * this table.
@@ -265,6 +241,12 @@ public class Table
*/
public function mayBeStarted () :Boolean
{
switch (config.getGameType()) {
case GameConfig.SEATED_CONTINUOUS:
case GameConfig.PARTY:
return true;
}
if (tconfig.teamMemberIndices == null) {
// for a normal game, just check to see if we're past the minimum
return tconfig.minimumPlayerCount <= getOccupiedCount();
@@ -288,15 +270,21 @@ public class Table
}
}
/**
* Returns true if sufficient seats are occupied that the game should
* be automatically started.
*/
public function shouldBeStarted () :Boolean
{
return isPartyGame() ||
(tconfig.desiredPlayerCount <= getOccupiedCount());
}
// /**
// * Returns true if sufficient seats are occupied that the game should
// * be automatically started.
// */
// public function shouldBeStarted () :Boolean
// {
// switch (config.getGameType()) {
// case GameConfig.SEATED_CONTINUOUS:
// case GameConfig.PARTY:
// return true;
//
// default:
// return (tconfig.desiredPlayerCount <= getOccupiedCount());
// }
// }
/**
* Returns true if this table is in play, false if it is still being
@@ -33,8 +33,6 @@ import com.threerings.crowd.util.CrowdContext;
import com.threerings.parlor.game.data.GameCodes;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.parlor.game.data.GameObject;
import com.threerings.parlor.game.data.PartyGameCodes;
import com.threerings.parlor.game.data.PartyGameConfig;
import com.threerings.parlor.util.ParlorContext;
/**
@@ -294,13 +292,11 @@ public /*abstract*/ class GameController extends PlaceController
}
/**
* Used to determine if this game is a party game.
* Convenience method to determine the type of game.
*/
protected function isPartyGame () :Boolean
protected function getGameType () :int
{
return (_gconfig is PartyGameConfig) &&
(PartyGameConfig(_gconfig).getPartyGameType() !=
PartyGameCodes.NOT_PARTY_GAME);
return _gconfig.getGameType();
}
/** A reference to the active parlor context. */
@@ -55,6 +55,19 @@ import com.threerings.parlor.game.client.GameConfigurator;
public /*abstract*/ class GameConfig extends PlaceConfig
implements Cloneable, Hashable
{
/** Game type constant: a game that is started with a list of players,
* and those are the only players that may play. */
public static const SEATED_GAME :int = 0;
/** Game type constant: a game that starts immediately, but only has
* a certain number of player slots. Users enter the game room, and
* then choose where to sit. */
public static const SEATED_CONTINUOUS :int = 1;
/** Game type constant: a game that starts immediately, and every
* user that enters is a player. */
public static const PARTY :int = 2;
/** The usernames of the players involved in this game, or an empty
* array if such information is not needed by this particular game. */
public var players :TypedArray = TypedArray.create(Name);
@@ -73,6 +86,14 @@ public /*abstract*/ class GameConfig extends PlaceConfig
// nothing needed
}
/**
* Get the type of game.
*/
public function getGameType () :int
{
return SEATED_GAME;
}
/**
* Returns the message bundle identifier for the bundle that should be
* used to translate the translatable strings used to describe the
@@ -226,15 +226,6 @@ public class GameObject extends PlaceObject
return ArrayUtil.indexOf(winners, true);
}
/**
* Returns the type of party game being played or NOT_PARTY_GAME.
* {@link PartyGameConfig}.
*/
public function getPartyGameType () :int
{
return PartyGameCodes.NOT_PARTY_GAME;
}
/**
* Used by {@link #isActivePlayer} to determine if the supplied status is
* associated with an active player (one that has not resigned from the
@@ -1,19 +0,0 @@
package com.threerings.parlor.game.data {
public class PartyGameCodes
{
/** Party game constant indicating that this game, while it does
* implement PartyGameConfig, is not currently being played in party
* mode. */
public static const NOT_PARTY_GAME :int = 0;
/** Party game constant indicating that we're in a party game in which
* players must sit at an available seat to play, otherwise they're
* an observer. */
public static const SEATED_PARTY_GAME :int = 1;
/** Party game constant indicating that everyone in the game place is
* a "player", meaning that they do not need to claim a seat to play. */
public static const FREE_FOR_ALL_PARTY_GAME :int = 2;
}
}
@@ -1,37 +0,0 @@
//
// $Id: PartyGameConfig.java 3804 2006-01-13 01:52:36Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.parlor.game.data {
/**
* Provides additional information for party games.
* A party game is a game in which the players are not set prior to starting,
* but players can come and go at will during the normal progression of
* the game.
*/
public interface PartyGameConfig
{
/**
* Get the type of party game being played.
*/
function getPartyGameType () :int;
}
}
@@ -9,7 +9,6 @@ import com.threerings.crowd.client.PlaceController;
import com.threerings.parlor.game.client.GameConfigurator;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.parlor.game.data.PartyGameConfig;
import com.threerings.ezgame.client.EZGameController;
@@ -17,7 +16,6 @@ import com.threerings.ezgame.client.EZGameController;
* A game config for a simple multiplayer game.
*/
public class EZGameConfig extends GameConfig
implements PartyGameConfig
{
// TODO: this will eventually contain various XML configuration bits,
// or we'll expand this to contain other information.
@@ -25,13 +23,19 @@ public class EZGameConfig extends GameConfig
public String configData;
// TODO: this is separate right now, but may eventually be extracted
// from configData? Do not read this value, use getPartyGameType()
public byte partyGameType = NOT_PARTY_GAME;
// from configData? Do not read this value, use getGameType()
public byte gameType = SEATED_GAME;
/** If non-zero, a game id used to persistently identify the game.
* This could be thought of as a new-style rating id. */
public int persistentGameId;
@Override
public byte getGameType ()
{
return gameType;
}
// from abstract GameConfig
public String getBundleName ()
{
@@ -63,12 +67,6 @@ public class EZGameConfig extends GameConfig
return "com.threerings.ezgame.server.EZGameManager";
}
// from PartyGameConfig
public byte getPartyGameType ()
{
return partyGameType;
}
@Override
public boolean equals (Object other)
{
@@ -32,7 +32,8 @@ import com.threerings.crowd.data.PlaceObject;
import com.threerings.crowd.server.CrowdServer;
import com.threerings.parlor.game.data.PartyGameConfig;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.parlor.game.server.GameManager;
import com.threerings.parlor.turn.server.TurnGameManager;
@@ -404,8 +405,8 @@ public class EZGameManager extends GameManager
protected void validateUser (ClientObject caller)
throws InvocationException
{
switch (getPartyGameType()) {
case PartyGameConfig.FREE_FOR_ALL_PARTY_GAME:
switch (getGameType()) {
case GameConfig.PARTY:
return; // always validate.
default:
@@ -447,7 +448,8 @@ public class EZGameManager extends GameManager
_gameObj.setEzGameService(
(EZGameMarshaller) CrowdServer.invmgr.registerDispatcher(new EZGameDispatcher(this)));
if (isPartyGame()) {
// if we don't need the no-show timer, start.
if (!needsNoShowTimer()) {
startGame();
}
}
@@ -308,7 +308,7 @@ public class TableDirector extends BasicDirector
Log.warning("Table created, but where is it? [tableId=" + tableId + "]");
return;
}
if (table.gameOid != 0 && table.isPartyGame()) {
if (table.gameOid != -1 && table.occupants.length == 0) {
// let's boogie!
_ctx.getParlorDirector().gameIsReady(table.gameOid);
}
+16 -27
View File
@@ -34,7 +34,6 @@ import com.threerings.crowd.data.BodyObject;
import com.threerings.parlor.data.ParlorCodes;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.parlor.game.data.PartyGameConfig;
/**
* This class represents a table that is being used to matchmake a game by
@@ -106,7 +105,7 @@ public class Table
this.config = config;
// make room for the maximum number of players
if (!isPartyGame()) {
if (config.getGameType() != GameConfig.PARTY) {
occupants = new Name[tconfig.desiredPlayerCount];
bodyOids = new int[occupants.length];
@@ -158,7 +157,7 @@ public class Table
public Name[] getPlayers ()
{
// seated party games need a spot for every seat
if (PartyGameConfig.SEATED_PARTY_GAME == getPartyGameType()) {
if (GameConfig.SEATED_CONTINUOUS == config.getGameType()) {
return new Name[tconfig.desiredPlayerCount];
}
@@ -205,28 +204,6 @@ public class Table
return newTeams;
}
/**
* Return true if the game is a party game.
*/
public boolean isPartyGame ()
{
return (PartyGameConfig.NOT_PARTY_GAME != getPartyGameType());
}
/**
* Get the type of party game being played at this table, or
* PartyGameConfig.NOT_PARTY_GAME.
*/
public byte getPartyGameType ()
{
if (config instanceof PartyGameConfig) {
return ((PartyGameConfig) config).getPartyGameType();
} else {
return PartyGameConfig.NOT_PARTY_GAME;
}
}
/**
* Requests to seat the specified user at the specified position in
* this table.
@@ -324,6 +301,12 @@ public class Table
*/
public boolean mayBeStarted ()
{
switch (config.getGameType()) {
case GameConfig.SEATED_CONTINUOUS:
case GameConfig.PARTY:
return true;
}
if (tconfig.teamMemberIndices == null) {
// for a normal game, just check to see if we're past the minimum
return tconfig.minimumPlayerCount <= getOccupiedCount();
@@ -352,8 +335,14 @@ public class Table
*/
public boolean shouldBeStarted ()
{
return isPartyGame() ||
(tconfig.desiredPlayerCount <= getOccupiedCount());
switch (config.getGameType()) {
case GameConfig.SEATED_CONTINUOUS:
case GameConfig.PARTY:
return true;
default:
return (tconfig.desiredPlayerCount <= getOccupiedCount());
}
}
/**
@@ -37,7 +37,6 @@ import com.threerings.parlor.Log;
import com.threerings.parlor.game.data.GameCodes;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.parlor.game.data.GameObject;
import com.threerings.parlor.game.data.PartyGameConfig;
import com.threerings.parlor.util.ParlorContext;
/**
@@ -305,13 +304,11 @@ public abstract class GameController extends PlaceController
}
/**
* Used to determine if this game is a party game.
* Convenience method to determine the type of game.
*/
protected boolean isPartyGame ()
protected byte getGameType ()
{
return (_config instanceof PartyGameConfig) &&
(((PartyGameConfig)_config).getPartyGameType() !=
PartyGameConfig.NOT_PARTY_GAME);
return _config.getGameType();
}
/** A reference to the active parlor context. */
@@ -48,6 +48,19 @@ import com.threerings.parlor.game.client.GameConfigurator;
*/
public abstract class GameConfig extends PlaceConfig implements Cloneable
{
/** Game type constant: a game that is started with a list of players,
* and those are the only players that may play. */
public static final byte SEATED_GAME = 0;
/** Game type constant: a game that starts immediately, but only has
* a certain number of player slots. Users enter the game room, and
* then choose where to sit. */
public static final byte SEATED_CONTINUOUS = 1;
/** Game type constant: a game that starts immediately, and every
* user that enters is a player. */
public static final byte PARTY = 2;
/** The usernames of the players involved in this game, or an empty
* array if such information is not needed by this particular game. */
public Name[] players = new Name[0];
@@ -61,6 +74,14 @@ public abstract class GameConfig extends PlaceConfig implements Cloneable
* at all. */
public GameAI[] ais = new GameAI[0];
/**
* Get the type of game.
*/
public byte getGameType ()
{
return SEATED_GAME;
}
/**
* Returns the message bundle identifier for the bundle that should be
* used to translate the translatable strings used to describe the
@@ -231,15 +231,6 @@ public class GameObject extends PlaceObject
return -1;
}
/**
* Returns the type of party game being played or NOT_PARTY_GAME.
* {@link PartyGameConfig}.
*/
public byte getPartyGameType ()
{
return PartyGameConfig.NOT_PARTY_GAME;
}
/**
* Used by {@link #isActivePlayer} to determine if the supplied status is
* associated with an active player (one that has not resigned from the
@@ -1,50 +0,0 @@
//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.parlor.game.data;
/**
* Provides additional information for party games.
* A party game is a game in which the players are not set prior to starting,
* but players can come and go at will during the normal progression of
* the game.
*/
public interface PartyGameConfig
{
/** Party game constant indicating that this game, while it does
* implement PartyGameConfig, is not currently being played in party
* mode. */
public static final byte NOT_PARTY_GAME = 0;
/** Party game constant indicating that we're in a party game in which
* players must sit at an available seat to play, otherwise they're
* an observer. */
public static final byte SEATED_PARTY_GAME = 1;
/** Party game constant indicating that everyone in the game place is
* a "player", meaning that they do not need to claim a seat to play. */
public static final byte FREE_FOR_ALL_PARTY_GAME = 2;
/**
* Get the type of party game being played.
*/
public byte getPartyGameType ();
}
@@ -53,7 +53,6 @@ import com.threerings.parlor.game.data.GameAI;
import com.threerings.parlor.game.data.GameCodes;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.parlor.game.data.GameObject;
import com.threerings.parlor.game.data.PartyGameConfig;
import com.threerings.parlor.server.ParlorSender;
import com.threerings.util.MessageBundle;
@@ -80,23 +79,11 @@ public class GameManager extends PlaceManager
}
/**
* Used to determine if this game is a party game.
* A convenience method for getting the game type.
*/
public boolean isPartyGame ()
public byte getGameType ()
{
return (getPartyGameType() != PartyGameConfig.NOT_PARTY_GAME);
}
/**
* Get the type of party game being played.
*/
public byte getPartyGameType ()
{
if (_gameconfig instanceof PartyGameConfig) {
return ((PartyGameConfig) _gameconfig).getPartyGameType();
} else {
return PartyGameConfig.NOT_PARTY_GAME;
}
return _gameconfig.getGameType();
}
/**
@@ -622,7 +609,7 @@ public class GameManager extends PlaceManager
// perfectly normal to receive a player ready notification
// from a user entering a party game in which they're not yet
// a participant
if (!isPartyGame()) {
if (needsNoShowTimer()) {
Log.warning("Received playerReady() from non-player? " +
"[game=" + where() + ", who=" + caller.who() + "].");
}
@@ -672,7 +659,7 @@ public class GameManager extends PlaceManager
*/
protected boolean needsNoShowTimer ()
{
return !isPartyGame();
return (getGameType() == GameConfig.SEATED_GAME);
}
/**
@@ -891,7 +878,7 @@ public class GameManager extends PlaceManager
{
// start up the game if we're not a party game and if we haven't
// already done so
if (!isPartyGame() && _gameobj.state == GameObject.PRE_GAME) {
if (needsNoShowTimer() && _gameobj.state == GameObject.PRE_GAME) {
startGame();
}
}
@@ -128,8 +128,7 @@ public class TableManager
}
table.init(_plobj.getOid(), tableConfig, config);
boolean isParty = table.isPartyGame();
if (!isParty) {
if (table.bodyOids != null && table.bodyOids.length > 0) {
// stick the creator into the first non-AI position
int cpos = (config.ais == null) ? 0 : config.ais.length;
String error = table.setOccupant(cpos, creator);
@@ -350,7 +349,7 @@ public class TableManager
// configure the privacy of the game
gameobj.setIsPrivate(table.tconfig.privateTable);
if (!table.isPartyGame()) {
if (table.bodyOids != null) {
// clear the occupant to table mappings as this game is underway
for (int i = 0; i < table.bodyOids.length; i++) {
_boidMap.remove(table.bodyOids[i]);
@@ -399,6 +398,9 @@ public class TableManager
// TODO: this will become more complicated
// As we separate watchers and players
// TODO: for SEATED_CONTINUOUS, we will probably be showing the
// folks in the game...
// finally, update the table
_tlobj.updateTables(table);
}