Exemplo n.º 1
0
  /**
   * Called by the client to report its idleness state changing. We do not accumulate play time for
   * idle players.
   */
  public void setIdle(
      ClientObject caller, boolean nowIdle, InvocationService.ConfirmListener listener)
      throws InvocationException {
    verifyIsPlayer(caller);

    Player player = (caller != null) ? _players.get(caller.getOid()) : null;
    if (player == null) {
      throw new InvocationException(InvocationCodes.E_ACCESS_DENIED);
    }

    if (nowIdle) {
      player.pauseAccrual();
    } else {
      player.resumeAccrual();
    }

    // let the client know all went well
    listener.requestProcessed();
  }
Exemplo n.º 2
0
  /**
   * Notes that the supplied player completed the specified task. Computes a coin payout for the
   * player, transiently reports it to them and accumulates it to their stat record for actual
   * payout when they leave the game.
   */
  public void completeTask(
      PlayerObject plobj,
      String questId,
      float payoutLevel,
      InvocationService.ConfirmListener listener)
      throws InvocationException {
    // sanity check
    if (payoutLevel < 0 || payoutLevel > 1) {
      log.warning(
          "Invalid payout",
          "game",
          where(),
          "caller",
          plobj.who(),
          "quest",
          questId,
          "payout",
          payoutLevel);
      throw new InvocationException(InvocationCodes.INTERNAL_ERROR);
    }

    Player player = _players.get(plobj.getOid());
    if (player == null) {
      // cannot award players who are not currently in the game
      throw new InvocationException(InvocationCodes.E_ACCESS_DENIED);
    }

    // payout factor depends on accumulated play time -- if we've yet to accumulate enough data
    // for a calculation, guesstimate 5 mins (TODO: this should come from the default settings
    // in GameMetricsRecord)
    int flowPerHour = _runtime.money.hourlyAVRGameFlowRate;
    int payoutFactor =
        (_content.metrics.payoutFactor == 0)
            ? ((5 * flowPerHour) / 60)
            : _content.metrics.payoutFactor;

    // compute our quest payout; as a sanity check, cap it at one hour of payout
    int rawPayout = Math.round(payoutFactor * payoutLevel);
    int payout = Math.min(flowPerHour, rawPayout);
    if (payout != rawPayout) {
      log.warning(
          "Capped AVRG payout at one hour",
          "game",
          _gameId,
          "factor",
          payoutFactor,
          "level",
          payoutLevel,
          "wanted",
          rawPayout,
          "got",
          payout);
    }
    // possibly give the party bonus
    int partySize = _partyReg.lookupPartyPopulation(plobj);
    if (partySize > 0) {
      float partyBonus =
          (float)
              Math.pow(
                  _runtime.money.partyGameBonusFactor,
                  Math.min(partySize, _runtime.money.partyMaxBonusPopulation) - 1);
      payout = Math.round(payout * partyBonus);
    }

    // we don't actually award coins if we're the development version of the game
    final boolean actuallyAward = !_content.isDevelopmentVersion();

    // note that they completed this task
    if (actuallyAward) {
      player.taskCompleted(payout);

      // accumulate the flow for this quest (to be persisted later)
      if (payout > 0) {
        _gameReg.reportCoinAward(plobj.getMemberId(), payout);
      }
    }

    // report task completion to the game
    plobj.postMessage(AVRGameObject.TASK_COMPLETED_MESSAGE, questId, payout, actuallyAward);

    // tell the requester that we're groovy
    listener.requestProcessed();

    // finally, if we have pending coin awards that exceed our current coin budget, flush 'em
    // and trigger a recaculation of our payout rate
    if (actuallyAward) {
      int pendingCoins = 0;
      for (Player p : _players.values()) {
        pendingCoins += p.coinsAccrued;
      }
      if (pendingCoins >= _content.metrics.flowToNextRecalc) {
        flushAllPlayers();
      }
    }
  }