Exemple #1
0
  /**
   * Looks for an existing instance of <code>Player</code> for the given name, and creates one if an
   * instance doesn't already exist. This also takes care of registering the player.
   *
   * @param name the account name of the user
   * @return a reference to the <code>Player</code> with the given name
   */
  public static Player getInstance(String name) {
    DataManager dataManager = AppContext.getDataManager();

    // try to lookup the existing Player
    Player player = null;
    try {
      player = (Player) dataManager.getBinding(NAME_PREFIX + name);
    } catch (NameNotBoundException e) {
      player = new Player(name);
      dataManager.setBinding(NAME_PREFIX + name, player);
    }

    return player;
  }
 /**
  * Find or create the player object for the given session, and mark the player as logged in on
  * that session.
  *
  * @param session which session to find or create a player for
  * @return a player for the given session
  */
 public static SwordWorldPlayer loggedIn(ClientSession session) {
   String playerBinding = PLAYER_BIND_PREFIX + session.getName();
   // try to find player object, if non existent then create
   DataManager dataMgr = AppContext.getDataManager();
   SwordWorldPlayer player;
   try {
     player = (SwordWorldPlayer) dataMgr.getBinding(playerBinding);
   } catch (NameNotBoundException ex) {
     // this is a new player
     player = new SwordWorldPlayer(playerBinding);
     logger.log(Level.INFO, "New player created: {0}", player);
     dataMgr.setBinding(playerBinding, player);
   }
   player.setSession(session);
   return player;
 }
  /**
   * This method takes a <code>StreamTokenizer</code> that is setup at the start of a single dungeon
   * file, and loads all the data, creating the AIs, stitching together all connectors between
   * levels, etc. At the end a single <code>Connector</code> is provded as an entry point to the
   * dungeon.
   *
   * <p>FIXME: we should make the aggregator real, or remove it and go back to use of the PDTimer
   * directly.
   *
   * @param stok the stream to tokenize
   * @param gameName the name of the dungeon this is being loaded into
   * @param impassableSprites the set of identifiers that are impassable
   * @param lobbyRef a reference to the lobby
   * @param eventAg an aggreagator for all AI tasks
   * @return a reference to a <code>GameConnector</code> that is the connection between the dungeon
   *     and the lobby
   * @throws IOException if the stream isn't formatted correctly
   */
  public static GameConnector loadDungeon(
      StreamTokenizer stok, String gameName, Set<Integer> impassableSprites, Game lobby)
      throws IOException {
    DataManager dataManager = AppContext.getDataManager();

    // the prefix for all level names
    String levelPrefix = gameName + ":" + SimpleLevel.NAME_PREFIX;

    // details about where we enter the dungeon
    String entryLevel = null;
    int entryX = 0;
    int entryY = 0;

    // the collection of boards and levels
    HashMap<String, SimpleBoard> boards = new HashMap<String, SimpleBoard>();
    HashMap<String, ManagedReference<SimpleLevel>> levelRefs = // simplelevel
        new HashMap<String, ManagedReference<SimpleLevel>>();

    // the various kinds of connectors
    HashSet<ConnectionData> connections = new HashSet<ConnectionData>();
    HashSet<ConnectionData> oneWays = new HashSet<ConnectionData>();
    HashSet<ConnectionData> playerConnectors = new HashSet<ConnectionData>();

    // the collection of Monster (AI) and NPC characters
    // to AICharacterManager
    HashMap<String, HashSet<ManagedReference<AICharacterManager>>> npcMap =
        new HashMap<String, HashSet<ManagedReference<AICharacterManager>>>();
    HashMap<String, HashSet<ManagedReference<AICharacterManager>>> aiMap =
        new HashMap<String, HashSet<ManagedReference<AICharacterManager>>>();

    // first, parse the data file itself
    while (stok.nextToken() != StreamTokenizer.TT_EOF) {
      if (stok.sval.equals("EntryPoint")) {
        // an Entry is LEVEL X_POS Y_POS
        stok.nextToken();
        entryLevel = levelPrefix + stok.sval;
        stok.nextToken();
        entryX = (int) (stok.nval);
        stok.nextToken();
        entryY = (int) (stok.nval);
      } else if (stok.sval.equals("DefineLevel")) {
        // levels are handled separately by SimpleLevel
        stok.nextToken();
        String levelName = levelPrefix + stok.sval;
        boards.put(levelName, new SimpleBoard(stok, impassableSprites));
      } else if (stok.sval.equals("Connection")) {
        connections.add(readConnection(stok, levelPrefix));
      } else if (stok.sval.equals("OneWayConnection")) {
        oneWays.add(readConnection(stok, levelPrefix));
      } else if (stok.sval.equals("PlayerConnection")) {
        playerConnectors.add(readConnection(stok, levelPrefix));
      } else if (stok.sval.equals("NPC")) {
        // an NPC is LEVEL NAME ID MESSAGE_1 [ ... MESSAGE_N ]
        stok.nextToken();
        String levelName = levelPrefix + stok.sval;
        stok.nextToken();
        String npcName = stok.sval;
        stok.nextToken();
        int id = (int) (stok.nval);
        stok.nextToken();
        int count = (int) (stok.nval);
        String[] messages = new String[count];
        for (int i = 0; i < count; i++) {
          stok.nextToken();
          messages[i] = stok.sval;
        }

        // create the manager for the NPC and the NPC itself
        AICharacterManager aiCMR = AICharacterManager.newInstance();
        NPCharacter npc = new NPCharacter(id, npcName, messages, aiCMR);
        aiCMR.setCharacter(npc);

        // put it into a bucket for the given level, creating the
        // bucket if it doesn't already exist
        // to AICharacterManager
        HashSet<ManagedReference<AICharacterManager>> set = npcMap.get(levelName);
        if (set == null) {
          set = new HashSet<ManagedReference<AICharacterManager>>();
          npcMap.put(levelName, set);
        }
        set.add(dataManager.createReference(aiCMR));
      } else if (stok.sval.equals("Monster")) {
        // a Monster is LEVEL TYPE ID
        stok.nextToken();
        String levelName = levelPrefix + stok.sval;
        stok.nextToken();
        String type = stok.sval;
        stok.nextToken();
        int id = (int) (stok.nval);

        // create the manager and get the right instance
        AICharacterManager aiCMR = MonsterFactory.getMonster(id, type);

        // put the monster into a bucket for the given level, creating
        // the bucket if it doesn't already exist
        HashSet<ManagedReference<AICharacterManager>> set = aiMap.get(levelName);
        if (set == null) {
          set = new HashSet<ManagedReference<AICharacterManager>>();
          aiMap.put(levelName, set);
        }
        set.add(dataManager.createReference(aiCMR));
      } else {
        throw new IOException("Unknown type: " + stok.sval + " on line " + stok.lineno());
      }
    }

    // next, create a GLO for each of the levels
    for (String levelName : boards.keySet()) {
      SimpleLevel level = new SimpleLevel(levelName, gameName);
      String gloName = Game.NAME_PREFIX + levelName;
      dataManager.setBinding(gloName, level);
      levelRefs.put(levelName, dataManager.createReference(level));
    }

    // with the levels in place, we can generate the connectors and
    // assign them to their board spaces
    for (ConnectionData data : connections) {
      // create a connector and register it
      SimpleConnector connector =
          new SimpleConnector(
              levelRefs.get(data.level1).get(),
              data.level1X,
              data.level1Y,
              levelRefs.get(data.level2).get(),
              data.level2X,
              data.level2Y);

      // notify both boards of the connector
      boards.get(data.level1).setAsConnector(data.level1X, data.level1Y, connector);
      boards.get(data.level2).setAsConnector(data.level2X, data.level2Y, connector);
    }

    // we also get the player connectors
    for (ConnectionData data : playerConnectors) {
      // create a connector and register it
      PlayerConnector connector =
          new PlayerConnector(
              levelRefs.get(data.level1).get(),
              data.level1X,
              data.level1Y,
              levelRefs.get(data.level2).get(),
              data.level2X,
              data.level2Y);

      // notify both boards of the connector
      boards.get(data.level1).setAsConnector(data.level1X, data.level1Y, connector);
      boards.get(data.level2).setAsConnector(data.level2X, data.level2Y, connector);
    }

    // same for the one-ways, except that we only set one side
    for (ConnectionData data : oneWays) {
      // create the connector and register it
      OneWayConnector connector =
          new OneWayConnector(levelRefs.get(data.level2).get(), data.level2X, data.level2Y);

      // notify the source board of the connector
      boards.get(data.level1).setAsConnector(data.level1X, data.level1Y, connector);
    }

    // also generate the entry connector, register it, and set it for
    // the entry board
    GameConnector gameConnector =
        new GameConnector(lobby, levelRefs.get(entryLevel).get(), entryX, entryY);
    boards.get(entryLevel).setAsConnector(entryX, entryY, gameConnector);

    // with all the connectors in place, notify the levels
    for (ManagedReference<SimpleLevel> levelRef : levelRefs.values()) {
      SimpleLevel level = levelRef.get();
      level.setBoard(boards.get(level.getName()));
    }

    TaskManager taskManager = AppContext.getTaskManager();

    // now that the levels are all set, add the NPC characters to the
    // levels and the timer
    for (String levelName : npcMap.keySet()) {
      Level level = levelRefs.get(levelName).get();
      for (ManagedReference<AICharacterManager> mgrRef : npcMap.get(levelName)) {
        AICharacterManager mgr = mgrRef.get();
        taskManager.schedulePeriodicTask(mgr, 0, 1700);
        // eventAg.addCharacterMgr(mgr);
        level.addCharacter(mgr);
      }
    }

    // add the Monsters too
    for (String levelName : aiMap.keySet()) {
      Level level = levelRefs.get(levelName).get();
      for (ManagedReference<AICharacterManager> mgrRef : aiMap.get(levelName)) {
        AICharacterManager mgr = mgrRef.get();
        taskManager.schedulePeriodicTask(mgr, 0, 1100);
        // eventAg.addCharacterMgr(mgr);
        level.addCharacter(mgr);
      }
    }

    // finally add, the items
    // FIXME: support items in file format

    // return the game connector, which is all the Dungeon needs to
    // interact with everything we've setup here
    return gameConnector;
  }