diff --git a/src/java/com/threerings/parlor/game/GameCodes.java b/src/java/com/threerings/parlor/game/GameCodes.java
new file mode 100644
index 000000000..42403411c
--- /dev/null
+++ b/src/java/com/threerings/parlor/game/GameCodes.java
@@ -0,0 +1,17 @@
+//
+// $Id: GameCodes.java,v 1.1 2001/10/11 03:12:38 mdb Exp $
+
+package com.threerings.parlor.client;
+
+import com.threerings.cocktail.cher.client.InvocationCodes;
+
+/**
+ * Contains codes used by the game services.
+ */
+public interface GameCodes extends InvocationCodes
+{
+ /** The message identifier for a player ready notification. This is
+ * delivered by the game controller when the client has loaded the
+ * user interface for the game and is ready to play. */
+ public static final String PLAYER_READY_NOTIFICATION = "PlayerReady";
+}
diff --git a/src/java/com/threerings/parlor/game/GameController.java b/src/java/com/threerings/parlor/game/GameController.java
index 53e2a76b4..ea8db219d 100644
--- a/src/java/com/threerings/parlor/game/GameController.java
+++ b/src/java/com/threerings/parlor/game/GameController.java
@@ -1,5 +1,5 @@
//
-// $Id: GameController.java,v 1.4 2001/10/09 17:20:39 mdb Exp $
+// $Id: GameController.java,v 1.5 2001/10/11 03:12:38 mdb Exp $
package com.threerings.parlor.client;
@@ -29,7 +29,7 @@ import com.threerings.parlor.util.ParlorContext;
* distributed object events.
*/
public abstract class GameController
- extends PlaceController implements Subscriber
+ extends PlaceController implements Subscriber, GameCodes
{
/**
* Initializes this game controller with the game configuration that
@@ -63,6 +63,11 @@ public abstract class GameController
// and add ourselves as a subscriber
_gobj.addSubscriber(this);
+
+ // finally let the game manager know that we're ready to roll
+ MessageEvent mevt = new MessageEvent(
+ _gobj.getOid(), PLAYER_READY_NOTIFICATION, null);
+ _ctx.getDObjectManager().postEvent(mevt);
}
// documentation inherited
diff --git a/src/java/com/threerings/parlor/game/GameManager.java b/src/java/com/threerings/parlor/game/GameManager.java
index e8b3f4c04..8766e9059 100644
--- a/src/java/com/threerings/parlor/game/GameManager.java
+++ b/src/java/com/threerings/parlor/game/GameManager.java
@@ -1,13 +1,18 @@
//
-// $Id: GameManager.java,v 1.5 2001/10/09 18:18:07 mdb Exp $
+// $Id: GameManager.java,v 1.6 2001/10/11 03:12:38 mdb Exp $
package com.threerings.parlor.server;
+import com.threerings.cocktail.cher.dobj.MessageEvent;
+
import com.threerings.cocktail.party.data.BodyObject;
+import com.threerings.cocktail.party.data.PlaceObject;
import com.threerings.cocktail.party.server.PlaceManager;
import com.threerings.cocktail.party.server.PartyServer;
+import com.threerings.cocktail.party.server.PartyServer;
import com.threerings.parlor.Log;
+import com.threerings.parlor.client.GameCodes;
import com.threerings.parlor.client.ParlorCodes;
import com.threerings.parlor.data.GameConfig;
import com.threerings.parlor.data.GameObject;
@@ -22,7 +27,7 @@ import com.threerings.parlor.data.GameObject;
* bodies in that location.
*/
public class GameManager
- extends PlaceManager implements ParlorCodes
+ extends PlaceManager implements ParlorCodes, GameCodes
{
// documentation inherited
protected Class getPlaceObjectClass ()
@@ -37,6 +42,10 @@ public class GameManager
// cast our configuration object (do we need to do this?)
_gconfig = (GameConfig)_config;
+
+ // register our message handlers
+ MessageHandler handler = new PlayerReadyHandler();
+ registerMessageHandler(PLAYER_READY_NOTIFICATION, handler);
}
/**
@@ -51,6 +60,9 @@ public class GameManager
{
// keep this info for later
_players = players;
+
+ // instantiate a player oid array which we'll fill in later
+ _playerOids = new int[_players.length];
}
// documentation inherited
@@ -81,6 +93,106 @@ public class GameManager
// documentation inherited
protected void bodyLeft (int bodyOid)
{
+ // deal with disappearing players
+ }
+
+ /**
+ * This is called when the game is ready to start (all players
+ * involved have delivered their "am ready" notifications). It calls
+ * {@link #gameWillStart}, sets the necessary wheels in motion and
+ * then calls {@link #gameDidStart}. Derived classes should override
+ * one or both of the calldown functions (rather than this function)
+ * if they need to do things before or after the game starts.
+ */
+ protected void startGame ()
+ {
+ // let the derived class do its pre-start stuff
+ gameWillStart();
+
+ // transition the game to started
+ _gameobj.setState(GameObject.IN_PLAY);
+
+ // and let the derived class do its post-start stuff
+ gameDidStart();
+ }
+
+ /**
+ * Called when the game is about to start, but before the game start
+ * notification has been delivered to the players. Derived classes
+ * should override this if they need to perform some pre-start
+ * activities.
+ */
+ protected void gameWillStart ()
+ {
+ }
+
+ /**
+ * Called right after the game start notification was delivered.
+ * Derived classes should override this to perform whatever
+ * machinations are necessary to start the game in motion (if anything
+ * other than issuing the game start notification is necessary).
+ */
+ protected void gameDidStart ()
+ {
+ }
+
+ /**
+ * Called when the game is known to be over. This will call some
+ * calldown functions to determine the winner of the game and then
+ * transition the game to the GAME_OVER state.
+ */
+ protected void endGame ()
+ {
+ // figure out who won...
+
+ // transition to the game over state
+ _gameobj.setState(GameObject.GAME_OVER);
+
+ // do our post-game stuff
+ gameDidEnd();
+ }
+
+ /**
+ * Called after the game has transitioned to the
+ * GAME_OVER state. Derived classes should override this
+ * to perform any post-game activities.
+ */
+ protected void gameDidEnd ()
+ {
+ // calculate ratings and all that...
+ }
+
+ /** Handles player ready notifications. */
+ protected class PlayerReadyHandler implements MessageHandler
+ {
+ public void handleEvent (MessageEvent event, PlaceObject target)
+ {
+ int cloid = event.getSourceOid();
+ BodyObject body = (BodyObject)
+ PartyServer.omgr.getObject(cloid);
+ if (body == null) {
+ Log.warning("Player sent am ready notification and then " +
+ "disappeared [event=" + event + "].");
+ return;
+ }
+
+ // make a note of this player's oid and check to see if we're
+ // all set at the same time
+ boolean allSet = true;
+ for (int i = 0; i < _players.length; i++) {
+ if (_players[i].equals(body.username)) {
+ _playerOids[i] = body.getOid();
+ }
+ if (_playerOids[i] == 0) {
+ allSet = false;
+ }
+ }
+
+ // if everyone is now ready to go, start up the game
+ if (allSet) {
+ startGame();
+ }
+ }
}
/** A reference to our game configuration. */
@@ -91,4 +203,7 @@ public class GameManager
/** A reference to our game object. */
protected GameObject _gameobj;
+
+ /** The oids of our player's body objects. */
+ protected int[] _playerOids;
}