Esempio n. 1
0
/**
 * This class is representing movable objects, its base class for all in game objects that may move
 *
 * @author -Nemesiss-
 */
public abstract class Creature extends VisibleObject {

  private static final Logger log = LoggerFactory.getLogger(Creature.class);

  protected AI2 ai2;
  private boolean isDespawnDelayed = false;

  private CreatureLifeStats<? extends Creature> lifeStats;
  private CreatureGameStats<? extends Creature> gameStats;

  private EffectController effectController;
  protected MoveController moveController;

  private int state = CreatureState.ACTIVE.getId();
  private int visualState = CreatureVisualState.VISIBLE.getId();
  private int seeState = CreatureSeeState.NORMAL.getId();

  private Skill castingSkill;
  private FastMap<Integer, Long> skillCoolDowns;
  private FastMap<Integer, Long> skillCoolDownsBase;
  private ObserveController observeController;
  private TransformModel transformModel;

  private final AggroList aggroList;

  private byte adminFlags = 0;

  private Item usingItem;

  private final transient byte[] zoneTypes = new byte[ZoneType.values().length];

  private int skillNumber;
  private int attackedCount;
  private long spawnTime = System.currentTimeMillis();
  protected int type = CreatureType.NULL.getId();
  private TribeClass tribe = TribeClass.GENERAL;

  /**
   * @param objId
   * @param controller
   * @param spawnTemplate
   * @param objectTemplate
   * @param position
   */
  public Creature(
      int objId,
      CreatureController<? extends Creature> controller,
      SpawnTemplate spawnTemplate,
      VisibleObjectTemplate objectTemplate,
      WorldPosition position) {
    super(objId, controller, spawnTemplate, objectTemplate, position);
    this.observeController = new ObserveController();
    this.setTransformModel(new TransformModel(this));
    if (spawnTemplate != null && spawnTemplate.getModel() != null) {
      if (spawnTemplate.getModel().getTribe() != null)
        getTransformModel().setTribe(spawnTemplate.getModel().getTribe(), true);
    }
    this.aggroList = createAggroList();
  }

  public MoveController getMoveController() {
    return this.moveController;
  }

  protected AggroList createAggroList() {
    return new AggroList(this);
  }

  /**
   * Return CreatureController of this Creature object.
   *
   * @return CreatureController.
   */
  @Override
  public CreatureController<? extends Creature> getController() {
    return (CreatureController<?>) super.getController();
  }

  /** @return the lifeStats */
  public CreatureLifeStats<? extends Creature> getLifeStats() {
    return lifeStats;
  }

  /** @param lifeStats the lifeStats to set */
  public void setLifeStats(CreatureLifeStats<? extends Creature> lifeStats) {
    this.lifeStats = lifeStats;
  }

  /** @return the gameStats */
  public CreatureGameStats<? extends Creature> getGameStats() {
    return gameStats;
  }

  /** @param gameStats the gameStats to set */
  public void setGameStats(CreatureGameStats<? extends Creature> gameStats) {
    this.gameStats = gameStats;
  }

  public abstract byte getLevel();

  /** @return the effectController */
  public EffectController getEffectController() {
    return effectController;
  }

  /** @param effectController the effectController to set */
  public void setEffectController(EffectController effectController) {
    this.effectController = effectController;
  }

  public AI2 getAi2() {
    return ai2 != null ? ai2 : AI2Engine.getInstance().setupAI("dummy", this);
  }

  public void setAi2(AI2 ai2) {
    this.ai2 = ai2;
  }

  public boolean isDeleteDelayed() {
    return isDespawnDelayed;
  }

  public void setDespawnDelayed(boolean delayed) {
    isDespawnDelayed = delayed;
  }

  public boolean isFlag() {
    return false;
  }

  /**
   * Is creature casting some skill
   *
   * @return
   */
  public boolean isCasting() {
    return castingSkill != null;
  }

  /**
   * Set current casting skill or null when skill ends
   *
   * @param castingSkill
   */
  public void setCasting(Skill castingSkill) {
    if (castingSkill != null) skillNumber++;
    this.castingSkill = castingSkill;
  }

  /**
   * Current casting skill id
   *
   * @return
   */
  public int getCastingSkillId() {
    return castingSkill != null ? castingSkill.getSkillTemplate().getSkillId() : 0;
  }

  /**
   * Current casting skill
   *
   * @return
   */
  public Skill getCastingSkill() {
    return castingSkill;
  }

  public int getSkillNumber() {
    return skillNumber;
  }

  public void setSkillNumber(int skillNumber) {
    this.skillNumber = skillNumber;
  }

  public int getAttackedCount() {
    return this.attackedCount;
  }

  public void incrementAttackedCount() {
    this.attackedCount++;
  }

  public void clearAttackedCount() {
    attackedCount = 0;
  }

  /**
   * Is using item
   *
   * @return
   */
  public boolean isUsingItem() {
    return usingItem != null;
  }

  /**
   * Set using item
   *
   * @param usingItem
   */
  public void setUsingItem(Item usingItem) {
    this.usingItem = usingItem;
  }

  /**
   * get Using ItemId
   *
   * @return
   */
  public int getUsingItemId() {
    return usingItem != null ? usingItem.getItemTemplate().getTemplateId() : 0;
  }

  /**
   * Using Item
   *
   * @return
   */
  public Item getUsingItem() {
    return usingItem;
  }

  /**
   * All abnormal effects are checked that disable movements
   *
   * @return
   */
  public boolean canPerformMove() {
    return !(getEffectController().isAbnormalState(AbnormalState.CANT_MOVE_STATE)
        || !isSpawned()
        || !canUseSkillInMove());
  }

  private boolean canUseSkillInMove() {
    if (castingSkill != null) {
      SkillTemplate st = DataManager.SKILL_DATA.getSkillTemplate(castingSkill.getSkillId());
      if (st.getStartconditions() != null && st.getMovedCondition() != null) {
        if (!st.getMovedCondition().isAllow()) return false;
      }
    }
    return true;
  }

  /**
   * All abnormal effects are checked that disable attack
   *
   * @return
   */
  public boolean canAttack() {
    return !(getEffectController().isAbnormalState(AbnormalState.CANT_ATTACK_STATE)
        || isCasting()
        || isInState(CreatureState.RESTING)
        || isInState(CreatureState.PRIVATE_SHOP));
  }

  /** @return state */
  public int getState() {
    return state;
  }

  /** @param state the state to set */
  public void setState(CreatureState state) {
    this.state |= state.getId();
  }

  /** @param state taken usually from templates */
  public void setState(int state) {
    this.state = state;
  }

  public void unsetState(CreatureState state) {
    this.state &= ~state.getId();
  }

  public boolean isInState(CreatureState state) {
    int isState = this.state & state.getId();

    if (isState == state.getId()) return true;

    return false;
  }

  /** @return visualState */
  public int getVisualState() {
    return visualState;
  }

  /** @param visualState the visualState to set */
  public void setVisualState(CreatureVisualState visualState) {
    this.visualState |= visualState.getId();
  }

  public void unsetVisualState(CreatureVisualState visualState) {
    this.visualState &= ~visualState.getId();
  }

  public boolean isInVisualState(CreatureVisualState visualState) {
    int isVisualState = this.visualState & visualState.getId();

    if (isVisualState == visualState.getId()) return true;

    return false;
  }

  /** @return seeState */
  public int getSeeState() {
    return seeState;
  }

  /** @param seeState the seeState to set */
  public void setSeeState(CreatureSeeState seeState) {
    this.seeState |= seeState.getId();
  }

  public void unsetSeeState(CreatureSeeState seeState) {
    this.seeState &= ~seeState.getId();
  }

  public boolean isInSeeState(CreatureSeeState seeState) {
    int isSeeState = this.seeState & seeState.getId();

    if (isSeeState == seeState.getId()) return true;

    return false;
  }

  /** @return the transformModel */
  public TransformModel getTransformModel() {
    return transformModel;
  }

  /** @param transformModel the transformedModel to set */
  public final void setTransformModel(TransformModel model) {
    this.transformModel = model;
  }

  /** @return the aggroList */
  public final AggroList getAggroList() {
    return aggroList;
  }

  /** PacketBroadcasterMask */
  private volatile byte packetBroadcastMask;

  /** This is adding broadcast to player. */
  public final void addPacketBroadcastMask(BroadcastMode mode) {
    packetBroadcastMask |= mode.mask();

    PacketBroadcaster.getInstance().add(this);

    // Debug
    if (log.isDebugEnabled())
      log.debug("PacketBroadcaster: Packet " + mode.name() + " added to player " + this.getName());
  }

  /** This is removing broadcast from player. */
  public final void removePacketBroadcastMask(BroadcastMode mode) {
    packetBroadcastMask &= ~mode.mask();

    // Debug
    if (log.isDebugEnabled())
      log.debug(
          "PacketBroadcaster: Packet "
              + mode.name()
              + " removed from player "
              + this.getName()); // fix
    // ClassCastException
  }

  /** Broadcast getter. */
  public final byte getPacketBroadcastMask() {
    return packetBroadcastMask;
  }

  /** @return the observeController */
  public ObserveController getObserveController() {
    return observeController;
  }

  /**
   * Double dispatch like method
   *
   * @param creature
   * @return
   */
  public boolean isEnemy(Creature creature) {
    return creature.isEnemyFrom(this);
  }

  /** @param creature */
  public boolean isEnemyFrom(Creature creature) {
    return false;
  }

  /**
   * @param player
   * @return
   */
  public boolean isEnemyFrom(Player player) {
    return false;
  }

  /**
   * @param npc
   * @return
   */
  public boolean isEnemyFrom(Npc npc) {
    return false;
  }

  public TribeClass getTribe() {
    return tribe;
  }

  public void setTribe(TribeClass tribe) {
    this.tribe = tribe;
  }

  public TribeClass getBaseTribe() {
    return TribeClass.GENERAL;
  }

  @Override
  public boolean canSee(Creature creature) {
    if (creature == null) return false;

    return creature.getVisualState() <= getSeeState();
  }

  public boolean isSeeObject(VisibleObject object) {
    return getKnownList().getVisibleObjects().containsKey(object.getObjectId());
  }

  public boolean isSeePlayer(Player player) {
    return getKnownList().getVisiblePlayers().containsKey(player.getObjectId());
  }

  /** @return NpcObjectType.NORMAL */
  public NpcObjectType getNpcObjectType() {
    return NpcObjectType.NORMAL;
  }

  /**
   * For summons and different kind of servants<br>
   * it will return currently acting player.<br>
   * This method is used for duel and enemy relations,<br>
   * rewards<br>
   *
   * @return Master of this creature or self
   */
  public Creature getMaster() {
    return this;
  }

  /**
   * For summons it will return summon object and for <br>
   * servants - player object.<br>
   * Used to find attackable target for npcs.<br>
   *
   * @return acting master - player in case of servants
   */
  public Creature getActingCreature() {
    return this;
  }

  /**
   * @param cooldownId
   * @return
   */
  public boolean isSkillDisabled(SkillTemplate template) {

    if (skillCoolDowns == null) return false;

    int cooldownId = template.getCooldownId();
    Long coolDown = skillCoolDowns.get(cooldownId);
    if (coolDown == null) {
      return false;
    }

    if (coolDown < System.currentTimeMillis()) {
      removeSkillCoolDown(cooldownId);
      return false;
    }

    /*
     * Some shared cooldown skills have indipendent and different cooldown they must not be blocked
     */
    if (skillCoolDownsBase != null && skillCoolDownsBase.get(cooldownId) != null) {
      if ((template.getDuration()
              + template.getCooldown() * 100
              + skillCoolDownsBase.get(cooldownId))
          < System.currentTimeMillis()) return false;
    }

    return true;
  }

  /**
   * @param cooldownId
   * @return
   */
  public long getSkillCoolDown(int cooldownId) {
    if (skillCoolDowns == null || !skillCoolDowns.containsKey(cooldownId)) return 0;

    return skillCoolDowns.get(cooldownId);
  }

  /**
   * @param cooldownId
   * @param time
   */
  public void setSkillCoolDown(int cooldownId, long time) {

    if (cooldownId == 0) {
      return;
    }

    if (skillCoolDowns == null) skillCoolDowns = new FastMap<Integer, Long>().shared();
    skillCoolDowns.put(cooldownId, time);
  }

  /** @return the skillCoolDowns */
  public FastMap<Integer, Long> getSkillCoolDowns() {
    return skillCoolDowns;
  }

  /** @param cooldownId */
  public void removeSkillCoolDown(int cooldownId) {
    if (skillCoolDowns == null) return;
    skillCoolDowns.remove(cooldownId);
    if (skillCoolDownsBase != null) skillCoolDownsBase.remove(cooldownId);
  }

  /**
   * This function saves the currentMillis of skill that generated the cooldown of an entire
   * cooldownGroup
   *
   * @param cooldownId
   * @param baseTime
   */
  public void setSkillCoolDownBase(int cooldownId, long baseTime) {

    if (cooldownId == 0) {
      return;
    }

    if (skillCoolDownsBase == null) skillCoolDownsBase = new FastMap<Integer, Long>().shared();
    skillCoolDownsBase.put(cooldownId, baseTime);
  }

  /** @return isAdminNeutral value */
  public int getAdminNeutral() {
    return adminFlags >> 4;
  }

  /** @param newValue */
  public void setAdminNeutral(int newValue) {
    adminFlags = (byte) ((adminFlags & 0xF) | (newValue & 0xF) << 4);
  }

  /** @return isAdminEnmity value */
  public int getAdminEnmity() {
    return adminFlags & 0xF;
  }

  /** @param newValue */
  public void setAdminEnmity(int newValue) {
    adminFlags = (byte) ((adminFlags & 0xF0) | (newValue & 0xF));
  }

  public float getCollision() {
    return getObjectTemplate().getBoundRadius().getCollision();
  }

  /** @return */
  public boolean isAttackableNpc() {
    return false;
  }

  public ItemAttackType getAttackType() {
    return ItemAttackType.PHYSICAL;
  }

  /** Creature is flying (FLY or GLIDE states) */
  public boolean isFlying() {
    return (isInState(CreatureState.FLYING) && !isInState(CreatureState.RESTING))
        || isInState(CreatureState.GLIDING);
  }

  public boolean isInFlyingState() {
    return isInState(CreatureState.FLYING) && !isInState(CreatureState.RESTING);
  }

  public byte isPlayer() {
    return 0;
  }

  public boolean isPvpTarget(Creature creature) {
    return getActingCreature() instanceof Player && creature.getActingCreature() instanceof Player;
  }

  public void revalidateZones() {
    MapRegion mapRegion = this.getPosition().getMapRegion();
    if (mapRegion != null) mapRegion.revalidateZones(this);
  }

  public boolean isInsideZone(ZoneName zoneName) {
    if (!isSpawned()) return false;
    return getPosition().getMapRegion().isInsideZone(zoneName, this);
  }

  public boolean isInsideItemUseZone(ZoneName zoneName) {
    if (!isSpawned()) return false;
    return getPosition().getMapRegion().isInsideItemUseZone(zoneName, this);
  }

  public void setInsideZoneType(ZoneType zoneType) {
    byte current = zoneTypes[zoneType.getValue()];
    zoneTypes[zoneType.getValue()] = (byte) (current + 1);
  }

  public void unsetInsideZoneType(ZoneType zoneType) {
    byte current = zoneTypes[zoneType.getValue()];
    zoneTypes[zoneType.getValue()] = (byte) (current - 1);
  }

  public boolean isInsideZoneType(ZoneType zoneType) {
    return zoneTypes[zoneType.getValue()] > 0;
  }

  public Race getRace() {
    return Race.NONE;
  }

  public int getType(Creature creature) {
    return type;
  }

  public int getSkillCooldown(SkillTemplate template) {
    return template.getCooldown();
  }

  public int getItemCooldown(ItemTemplate template) {
    return template.getUseLimits().getDelayTime();
  }

  public boolean isNewSpawn() {
    return System.currentTimeMillis() - spawnTime < 1500;
  }
}
Esempio n. 2
0
/**
 * This class is representing movable objects, its base class for all in game objects that may move
 *
 * @author -Nemesiss-
 */
public abstract class Creature extends VisibleObject {
  private static final Logger log = Logger.getLogger(Creature.class);

  /** Reference to AI */
  protected AI<? extends Creature> ai;

  private CreatureLifeStats<? extends Creature> lifeStats;
  private CreatureGameStats<? extends Creature> gameStats;

  private EffectController effectController;
  private MoveController moveController;

  private int state = CreatureState.ACTIVE.getId();
  private int visualState = CreatureVisualState.VISIBLE.getId();
  private int seeState = CreatureSeeState.NORMAL.getId();

  private Skill castingSkill;
  private Map<Integer, Long> skillCoolDowns;
  private int transformedModelId;
  private ObserveController observeController;

  private AggroList aggroList;

  /**
   * @param objId
   * @param controller
   * @param spawnTemplate
   * @param objectTemplate
   * @param position
   */
  public Creature(
      int objId,
      CreatureController<? extends Creature> controller,
      SpawnTemplate spawnTemplate,
      VisibleObjectTemplate objectTemplate,
      WorldPosition position) {
    super(objId, controller, spawnTemplate, objectTemplate, position);
    initializeAi();
    this.moveController = new MoveController(this);
    this.observeController = new ObserveController();

    this.aggroList = new AggroList(this);
  }

  /**
   * Return CreatureController of this Creature object.
   *
   * @return CreatureController.
   */
  @SuppressWarnings("unchecked")
  @Override
  public CreatureController getController() {
    return (CreatureController) super.getController();
  }

  /** @return the lifeStats */
  public CreatureLifeStats<? extends Creature> getLifeStats() {
    return lifeStats;
  }

  /** @param lifeStats the lifeStats to set */
  public void setLifeStats(CreatureLifeStats<? extends Creature> lifeStats) {
    this.lifeStats = lifeStats;
  }

  /** @return the gameStats */
  public CreatureGameStats<? extends Creature> getGameStats() {
    return gameStats;
  }

  /** @param gameStats the gameStats to set */
  public void setGameStats(CreatureGameStats<? extends Creature> gameStats) {
    this.gameStats = gameStats;
  }

  public abstract byte getLevel();

  public abstract void initializeAi();

  /** @return the effectController */
  public EffectController getEffectController() {
    return effectController;
  }

  /** @param effectController the effectController to set */
  public void setEffectController(EffectController effectController) {
    this.effectController = effectController;
  }

  /** @return the npcAi */
  public AI<? extends Creature> getAi() {
    return ai != null ? ai : AI.dummyAi();
  }

  /** @param ai the ai to set */
  public void setAi(AI<? extends Creature> ai) {
    this.ai = ai;
  }

  /**
   * Is creature casting some skill
   *
   * @return
   */
  public boolean isCasting() {
    return castingSkill != null;
  }

  /**
   * Set current casting skill or null when skill ends
   *
   * @param castingSkill
   */
  public void setCasting(Skill castingSkill) {
    this.castingSkill = castingSkill;
  }

  /**
   * Current casting skill id
   *
   * @return
   */
  public int getCastingSkillId() {
    return castingSkill != null ? castingSkill.getSkillTemplate().getSkillId() : 0;
  }

  /**
   * Current casting skill
   *
   * @return
   */
  public Skill getCastingSkill() {
    return castingSkill;
  }

  /**
   * All abnormal effects are checked that disable movements
   *
   * @return
   */
  public boolean canPerformMove() {
    return !(getEffectController().isAbnormalState(EffectId.CANT_MOVE_STATE) || !isSpawned());
  }

  /**
   * All abnormal effects are checked that disable attack
   *
   * @return
   */
  public boolean canAttack() {
    return !(getEffectController().isAbnormalState(EffectId.CANT_ATTACK_STATE)
        || isCasting()
        || isInState(CreatureState.RESTING)
        || isInState(CreatureState.PRIVATE_SHOP));
  }

  /** @return state */
  public int getState() {
    return state;
  }

  /** @param state the state to set */
  public void setState(CreatureState state) {
    this.state |= state.getId();
  }

  /** @param state taken usually from templates */
  public void setState(int state) {
    this.state = state;
  }

  public void unsetState(CreatureState state) {
    this.state &= ~state.getId();
  }

  public boolean isInState(CreatureState state) {
    int isState = this.state & state.getId();

    if (isState == state.getId()) return true;

    return false;
  }

  /** @return visualState */
  public int getVisualState() {
    return visualState;
  }

  /** @param visualState the visualState to set */
  public void setVisualState(CreatureVisualState visualState) {
    this.visualState |= visualState.getId();
  }

  public void unsetVisualState(CreatureVisualState visualState) {
    this.visualState &= ~visualState.getId();
  }

  public boolean isInVisualState(CreatureVisualState visualState) {
    int isVisualState = this.visualState & visualState.getId();

    if (isVisualState == visualState.getId()) return true;

    return false;
  }

  /** @return seeState */
  public int getSeeState() {
    return seeState;
  }

  /** @param seeState the seeState to set */
  public void setSeeState(CreatureSeeState seeState) {
    this.seeState |= seeState.getId();
  }

  public void unsetSeeState(CreatureSeeState seeState) {
    this.seeState &= ~seeState.getId();
  }

  public boolean isInSeeState(CreatureSeeState seeState) {
    int isSeeState = this.seeState & seeState.getId();

    if (isSeeState == seeState.getId()) return true;

    return false;
  }

  /** @return the transformedModelId */
  public int getTransformedModelId() {
    return transformedModelId;
  }

  /** @param transformedModelId the transformedModelId to set */
  public void setTransformedModelId(int transformedModelId) {
    this.transformedModelId = transformedModelId;
  }

  /** @return the moveController */
  public MoveController getMoveController() {
    return moveController;
  }

  /** @return the aggroList */
  public AggroList getAggroList() {
    return aggroList;
  }

  /** PacketBroadcasterMask */
  private volatile byte packetBroadcastMask;

  /** This is adding broadcast to player. */
  public final void addPacketBroadcastMask(BroadcastMode mode) {
    packetBroadcastMask |= mode.mask();

    PacketBroadcaster.getInstance().add(this);

    // Debug
    if (log.isDebugEnabled())
      log.debug(
          "PacketBroadcaster: Packet "
              + mode.name()
              + " added to player "
              + ((Player) this).getName());
  }

  /** This is removing broadcast from player. */
  public final void removePacketBroadcastMask(BroadcastMode mode) {
    packetBroadcastMask &= ~mode.mask();

    // Debug
    if (log.isDebugEnabled())
      log.debug(
          "PacketBroadcaster: Packet "
              + mode.name()
              + " removed from player "
              + ((Player) this).getName());
  }

  /** Broadcast getter. */
  public final byte getPacketBroadcastMask() {
    return packetBroadcastMask;
  }

  /** @return the observeController */
  public ObserveController getObserveController() {
    return observeController;
  }

  /**
   * @param visibleObject
   * @return
   */
  public boolean isEnemy(VisibleObject visibleObject) {
    if (visibleObject instanceof Npc) return isEnemyNpc((Npc) visibleObject);
    else if (visibleObject instanceof Player) return isEnemyPlayer((Player) visibleObject);
    else if (visibleObject instanceof Summon) return isEnemySummon((Summon) visibleObject);

    return false;
  }

  /**
   * @param summon
   * @return
   */
  protected boolean isEnemySummon(Summon summon) {
    return false;
  }

  /**
   * @param player
   * @return
   */
  protected boolean isEnemyPlayer(Player player) {
    return false;
  }

  /**
   * @param npc
   * @return
   */
  protected boolean isEnemyNpc(Npc npc) {
    return false;
  }

  public String getTribe() {
    return StringUtils.EMPTY;
  }

  /**
   * @param creature
   * @return
   */
  public boolean isAggressiveTo(Creature creature) {
    return false;
  }

  /**
   * @param npc
   * @return
   */
  public boolean isAggroFrom(Npc npc) {
    return false;
  }

  /**
   * @param npc
   * @return
   */
  public boolean isHostileFrom(Npc npc) {
    return false;
  }

  public boolean isSupportFrom(Npc npc) {
    return false;
  }
  /**
   * @param player
   * @return
   */
  public boolean isAggroFrom(Player player) {
    return false;
  }

  /**
   * @param summon
   * @return
   */
  public boolean isAggroFrom(Summon summon) {
    return isAggroFrom(summon.getMaster());
  }
  /**
   * @param visibleObject
   * @return
   */
  public boolean canSee(VisibleObject visibleObject) {
    if (visibleObject instanceof Npc) return canSeeNpc((Npc) visibleObject);
    else if (visibleObject instanceof Player) return canSeePlayer((Player) visibleObject);

    return true;
  }

  /**
   * @param visibleObject
   * @return
   */
  protected boolean canSeePlayer(Player visibleObject) {
    return true;
  }

  /**
   * @param visibleObject
   * @return
   */
  protected boolean canSeeNpc(Npc visibleObject) {
    return true;
  }

  /** @return NpcObjectType.NORMAL */
  public NpcObjectType getNpcObjectType() {
    return NpcObjectType.NORMAL;
  }

  /**
   * For summons and different kind of servants<br>
   * it will return currently acting player.<br>
   * This method is used for duel and enemy relations,<br>
   * rewards<br>
   *
   * @return Master of this creature or self
   */
  public Creature getMaster() {
    return this;
  }

  /**
   * For summons it will return summon object and for <br>
   * servants - player object.<br>
   * Used to find attackable target for npcs.<br>
   *
   * @return acting master - player in case of servants
   */
  public Creature getActingCreature() {
    return this;
  }

  /**
   * @param skillId
   * @return
   */
  public boolean isSkillDisabled(int skillId) {
    if (skillCoolDowns == null) return false;

    Long coolDown = skillCoolDowns.get(skillId);
    if (coolDown == null) return false;

    if (coolDown < System.currentTimeMillis()) {
      skillCoolDowns.remove(skillId);
      return false;
    }

    return true;
  }

  /**
   * @param skillId
   * @return
   */
  public long getSkillCoolDown(int skillId) {
    if (skillCoolDowns == null || !skillCoolDowns.containsKey(skillId)) return 0;

    return skillCoolDowns.get(skillId);
  }

  /**
   * @param skillId
   * @param time
   */
  public void setSkillCoolDown(int skillId, long time) {
    if (skillCoolDowns == null) skillCoolDowns = new FastMap<Integer, Long>().shared();

    skillCoolDowns.put(skillId, time);
  }

  /** @return the skillCoolDowns */
  public Map<Integer, Long> getSkillCoolDowns() {
    return skillCoolDowns;
  }

  /** @param skillId */
  public void removeSkillCoolDown(int skillId) {
    if (skillCoolDowns == null) return;
    skillCoolDowns.remove(skillId);
  }
}