Modified the way locations are assigned when entering a scene. The

SpotSceneManager now actually does the proper assignment in
populateOccupantInfo and it does so having been warned that a body is
entering via a particular location by the SpotProvider when it processes a
traversePortal request. If the user enters a scene via some other
mechanism (like a zoned moveTo request), they will be assigned to the
default entrance for the scene, which is what we want. We also avoid the
extra occupant update that was necessary with the previous method. Yay!


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@788 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2001-12-16 05:15:27 +00:00
parent 750ff00b3d
commit e7b7364141
2 changed files with 63 additions and 11 deletions
@@ -1,5 +1,5 @@
//
// $Id: SpotProvider.java,v 1.2 2001/12/14 23:12:39 mdb Exp $
// $Id: SpotProvider.java,v 1.3 2001/12/16 05:15:27 mdb Exp $
package com.threerings.whirled.spot.server;
@@ -95,8 +95,9 @@ public class SpotProvider extends InvocationProvider
SceneRegistry.ResolutionListener rl =
new SceneRegistry.ResolutionListener() {
public void sceneWasResolved (SceneManager scmgr) {
SpotSceneManager sscmgr = (SpotSceneManager)scmgr;
finishTraversePortalRequest(
fsource, finvid, scmgr, fsceneVer,
fsource, finvid, sscmgr, fsceneVer,
fportalId, destLocId);
}
@@ -125,12 +126,13 @@ public class SpotProvider extends InvocationProvider
* to have been loaded into the server.
*/
protected void finishTraversePortalRequest (
BodyObject source, int invid, SceneManager scmgr,
BodyObject source, int invid, SpotSceneManager scmgr,
int sceneVer, int exitPortalId, int destLocId)
{
// move to the place object associated with this scene
PlaceObject plobj = scmgr.getPlaceObject();
int ploid = plobj.getOid();
int bodyOid = source.getOid();
// if they were in a scene (and at a location) prior to issuing
// this traverse portal request, we need to send a notification to
@@ -144,17 +146,15 @@ public class SpotProvider extends InvocationProvider
// ripping apart moveTo and restructuring the code with this
// requirement in mind
int oldLocId =
updateLocation(source.location, source.getOid(), exitPortalId);
updateLocation(source.location, bodyOid, exitPortalId);
// let the destination scene manager know that we're coming in
scmgr.mapEnteringBody(bodyOid, destLocId);
try {
// try doing the actual move
PlaceConfig config = LocationProvider.moveTo(source, ploid);
// now that the move succeeded, we need to update the occupant
// info in the new place object with this user's entry
// location
updateLocation(ploid, source.getOid(), destLocId);
// check to see if they need a newer version of the scene data
SceneModel model = scmgr.getSceneModel();
if (sceneVer < model.version) {
@@ -173,7 +173,11 @@ public class SpotProvider extends InvocationProvider
// we need to undo the move to the exit portal location that
// we enacted earlier
updateLocation(source.location, source.getOid(), oldLocId);
updateLocation(source.location, bodyOid, oldLocId);
// and let the destination scene manager know that we're no
// longer coming in
scmgr.clearEnteringBody(bodyOid);
}
}
@@ -1,8 +1,10 @@
//
// $Id: SpotSceneManager.java,v 1.1 2001/12/14 00:12:32 mdb Exp $
// $Id: SpotSceneManager.java,v 1.2 2001/12/16 05:15:27 mdb Exp $
package com.threerings.whirled.spot.server;
import com.samskivert.util.IntIntMap;
import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.Subscriber;
import com.threerings.presents.dobj.ObjectAccessException;
@@ -10,6 +12,7 @@ import com.threerings.presents.server.ServiceFailedException;
import com.threerings.crowd.chat.ChatProvider;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.data.OccupantInfo;
import com.threerings.whirled.server.SceneManager;
import com.threerings.whirled.spot.Log;
@@ -24,6 +27,26 @@ import com.threerings.whirled.spot.data.SpotOccupantInfo;
public class SpotSceneManager extends SceneManager
implements SpotCodes
{
/**
* Prepares a mapping for an entering body, indicating that they will
* be entering at the specified location id. When the time comes to
* prepare that body's occupant info, we will use the supplied
* location id as their starting location.
*/
public void mapEnteringBody (int bodyOid, int locationId)
{
_entering.put(bodyOid, locationId);
}
/**
* If scene entry fails, this can be called to undo a scene entry
* mapping.
*/
public void clearEnteringBody (int bodyOid)
{
_entering.remove(bodyOid);
}
// documentation inherited
protected void gotSceneData ()
{
@@ -62,6 +85,27 @@ public class SpotSceneManager extends SceneManager
_locationOccs = new int[_sscene.getLocationCount()];
}
/**
* When a user is entering a scene, we populate their occupant info
* with the location prepared by the portal traversal code or with the
* default entrance for the scene if no preparation was done.
*/
protected void populateOccupantInfo (OccupantInfo info, BodyObject body)
{
super.populateOccupantInfo(info, body);
// we have a table for tracking the locations of entering bodies
// which is populated by the portal traversal code when a body
// requests to enter our scene. if there's a mapped entrance
// location for this body, use it, otherwise assume they're coming
// in at the default entrance
int entryLocId = _entering.remove(body.getOid());
if (entryLocId == -1) {
entryLocId = _sscene.getDefaultEntranceId();
}
((SpotOccupantInfo)info).locationId = entryLocId;
}
/**
* Called by the {@link SpotProvider} when we receive a request by a
* user to occupy a particular location.
@@ -169,4 +213,8 @@ public class SpotSceneManager extends SceneManager
/** Oids of the bodies that occupy each of our locations. */
protected int[] _locationOccs;
/** A table of mappings from body oids to entry location ids for
* bodies that are entering our scene. */
protected IntIntMap _entering = new IntIntMap();
}