Package games.stendhal.server.maps.deathmatch

Source Code of games.stendhal.server.maps.deathmatch.DeathmatchEngine

/* $Id: DeathmatchEngine.java,v 1.43 2011/03/15 23:12:30 kymara Exp $ */
/***************************************************************************
*                   (C) Copyright 2003-2010 - Stendhal                    *
***************************************************************************
***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.server.maps.deathmatch;

import games.stendhal.server.core.engine.SingletonRepository;
import games.stendhal.server.core.events.TurnListener;
import games.stendhal.server.entity.creature.DeathMatchCreature;
import games.stendhal.server.entity.item.Item;
import games.stendhal.server.entity.npc.ConversationStates;
import games.stendhal.server.entity.npc.EventRaiser;
import games.stendhal.server.entity.player.Player;

import java.util.Date;

import org.apache.log4j.Logger;

/**
* this is the internal class which handles an active deathmatch session.
*/
class DeathmatchEngine implements TurnListener {
  /** The amount of milliseconds to wait before bail takes effect. */
  private static final long BAIL_DELAY = 600;

  private static Logger logger = Logger.getLogger(DeathmatchEngine.class);

  private final Player player;
  private final EventRaiser raiser;
 
  private final DeathmatchInfo dmInfo;

  private CreatureSpawner spawner;

  private boolean keepRunning = true;
 

  /**
   * Creates a new ScriptAction to handle the deathmatch logic.
   *
   * @param player
   *            Player for whom this match is created
   * @param deathmatchInfo
   *            Information about the place of the deathmatch
   */
  public DeathmatchEngine(final Player player, final DeathmatchInfo deathmatchInfo, final EventRaiser raiser) {
    this.dmInfo = deathmatchInfo;
    this.player = player;
    this.raiser = raiser;
    initialize();
  }

  protected void initialize() {
    spawner = new CreatureSpawner();
  }

  private boolean condition() {
    if ("cancel".equals(player.getQuest("deathmatch"))) {
      return false;
    }
    if (player.getQuest("deathmatch").startsWith("done")) {
      return false;
    }

    if (dmInfo.isInArena(player)) {
      return true;
    } else {
      player.setQuest("deathmatch", "cancel");
      return true;
    }
  }

  public void onTurnReached(final int currentTurn) {
    if (condition()) {
      action();
    }
    if (keepRunning) {
      SingletonRepository.getTurnNotifier().notifyInTurns(0, this);
    }
  }

  private void action() {

    final DeathmatchState deathmatchState = DeathmatchState.createFromQuestString(player.getQuest("deathmatch"));

    switch (deathmatchState.getLifecycleState()) {

    case BAIL:
      if (((new Date()).getTime() - deathmatchState.getStateTime() > BAIL_DELAY)) {
        handleBail();

        keepRunning = false;
        return;
      }
      break;

    case CANCEL:
      spawner.removePlayersMonsters();

      // and finally remove this ScriptAction
      keepRunning = false;
      return;
     
    default:
      //cannot happen we switch on a enum

    }

    // check whether the deathmatch was completed
    if (deathmatchState.getQuestLevel() >= player.getLevel()
        + CreatureSpawner.NUMBER_OF_CREATURES - 2) {
      // logger.info("May be done");
      if (spawner.areAllCreaturesDead()) {
        logger.info("Player " + player.getName()
            + " completed deathmatch");
        spawner.spawnDailyMonster(player, dmInfo);
        deathmatchState.setLifecycleState(DeathmatchLifecycle.VICTORY);
        player.setQuest("deathmatch", deathmatchState.toQuestString());

        // make the npc attend the player so they can say victory
        raiser.say(player.getName() + ", you have completed this deathmatch and can now claim #victory.");
          raiser.setCurrentState(ConversationStates.ATTENDING);
        raiser.setAttending(player);
       
        // remove this ScriptAction since we're done
        keepRunning = false;
      }
      // all creature are there
      return;
    }

    int numberPlayers = dmInfo.getArena().getPlayers().size();
    // spawn new monster, with the spawn delay proportional to player level
    // and inversely proportional to the number of players in the ring
    // and always spawning if there is no creature
    // for level 20 players it is always just 20 seconds
    if (((new Date()).getTime() - deathmatchState.getStateTime() > (300*(player.getLevel()-20)/(1+numberPlayers) + CreatureSpawner.SPAWN_DELAY)) || spawner.areAllCreaturesDead()) {
      final DeathMatchCreature mycreature = spawner.spawnNewCreature(
          deathmatchState.getQuestLevel(), player, dmInfo);
      // in case there is not enough space to place the creature,
      // mycreature is null
      if (mycreature != null) {

        deathmatchState.increaseQuestlevel();
      }

      deathmatchState.refreshTimestamp();
    }

    player.setQuest("deathmatch", deathmatchState.toQuestString());
  }

  private void handleBail() {
    player.setQuest("deathmatch", "cancel");
    final Item helmet = player.getFirstEquipped("trophy helmet");
    if (helmet != null) {
      int defense = 1;
      if (helmet.has("def")) {
        defense = helmet.getInt("def");
      }
      if (defense > 1) {
        defense--;
      } else {
        defense = 1;
      }
      helmet.put("def", "" + defense);
      player.updateItemAtkDef();
    } else {
      int xp = player.getLevel() * 80;
      if (xp > player.getXP()) {
        xp = player.getXP();
      }
      player.subXP(xp);
    }

    // send the player back to the entrance area
    player.teleport(dmInfo.getEntranceSpot().getZone(),
        dmInfo.getEntranceSpot().getX(),
        dmInfo.getEntranceSpot().getY(), null, null);

    spawner.removePlayersMonsters();
  }

}
TOP

Related Classes of games.stendhal.server.maps.deathmatch.DeathmatchEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.