private static void storeItem(PcInstance pc, ItemInstance item) {
    LsimulatorInventory inventory;

    if (pc.getInventory().checkAddItem(item, item.getCount()) == LsimulatorInventory.OK) {
      inventory = pc.getInventory();
    } else {
      // 持てない場合は地面に落とす 処理のキャンセルはしない(不正防止)
      inventory = LsimulatorWorld.getInstance().getInventory(pc.getLocation());
    }
    inventory.storeItem(item);
    pc.sendPackets(new S_ServerMessage(403, item.getLogName())); // %0を手に入れました。
  }
 private void buildPacket(SummonInstance pet, PcInstance pc, boolean isCheckMaster) {
   writeC(Opcodes.S_OPCODE_CHARPACK);
   writeH(pet.getX());
   writeH(pet.getY());
   writeD(pet.getId());
   writeH(pet.getGfxId()); // SpriteID in List.spr
   writeC(pet.getStatus()); // Modes in List.spr
   writeC(pet.getHeading());
   writeC(pet.getChaLightSize()); // (Bright) - 0~15
   writeC(pet.getMoveSpeed()); // スピード - 0:normal, 1:fast, 2:slow
   writeD(0);
   writeH(0);
   writeS(pet.getNameId());
   writeS(pet.getTitle());
   int status = 0;
   if (pet.getPoison() != null) { // 毒状態
     if (pet.getPoison().getEffectId() == 1) {
       status |= STATUS_POISON;
     }
   }
   writeC(status);
   writeD(0);
   writeS(null);
   if (isCheckMaster && pet.isExsistMaster()) {
     writeS(pet.getMaster().getName());
   } else {
     writeS("");
   }
   writeC(0); // ??
   // HPのパーセント
   if ((pet.getMaster() != null) && (pet.getMaster().getId() == pc.getId())) {
     int percent = pet.getMaxHp() != 0 ? 100 * pet.getCurrentHp() / pet.getMaxHp() : 100;
     writeC(percent);
   } else {
     writeC(0xFF);
   }
   writeC(0);
   writeC(pet.getLevel()); // PC = 0, Mon = Lv
   writeC(0);
   writeC(0xFF);
   writeC(0xFF);
 }
  public static void spawn(PcInstance pc, int npcId, int randomRange, int timeMillisToDelete) {
    try {
      NpcInstance npc = NpcTable.getInstance().newNpcInstance(npcId);
      npc.setId(IdFactory.getInstance().nextId());
      npc.setMap(pc.getMapId());
      if (randomRange == 0) {
        npc.getLocation().set(pc.getLocation());
        npc.getLocation().forward(pc.getHeading());
      } else {
        int tryCount = 0;
        do {
          tryCount++;
          npc.setX(pc.getX() + Random.nextInt(randomRange) - Random.nextInt(randomRange));
          npc.setY(pc.getY() + Random.nextInt(randomRange) - Random.nextInt(randomRange));
          if (npc.getMap().isInMap(npc.getLocation())
              && npc.getMap().isPassable(npc.getLocation())) {
            break;
          }
          Thread.sleep(1);
        } while (tryCount < 50);

        if (tryCount >= 50) {
          npc.getLocation().set(pc.getLocation());
          npc.getLocation().forward(pc.getHeading());
        }
      }

      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(pc.getHeading());
      // 紀錄龍之門扉編號
      if (npc.getNpcId() == 81273) {
        for (int i = 0; i < 6; i++) {
          if (!LsimulatorDragonSlayer.getInstance().getPortalNumber()[i]) {
            LsimulatorDragonSlayer.getInstance().setPortalNumber(i, true);
            // 重置副本
            LsimulatorDragonSlayer.getInstance().resetDragonSlayer(i);
            npc.setPortalNumber(i);
            LsimulatorDragonSlayer.getInstance().portalPack()[i] = npc;
            break;
          }
        }
      } else if (npc.getNpcId() == 81274) {
        for (int i = 6; i < 12; i++) {
          if (!LsimulatorDragonSlayer.getInstance().getPortalNumber()[i]) {
            LsimulatorDragonSlayer.getInstance().setPortalNumber(i, true);
            // 重置副本
            LsimulatorDragonSlayer.getInstance().resetDragonSlayer(i);
            npc.setPortalNumber(i);
            LsimulatorDragonSlayer.getInstance().portalPack()[i] = npc;
            break;
          }
        }
      }
      LsimulatorWorld.getInstance().storeObject(npc);
      LsimulatorWorld.getInstance().addVisibleObject(npc);

      if (npc.getTempCharGfx() == 7548
          || npc.getTempCharGfx() == 7550
          || npc.getTempCharGfx() == 7552
          || npc.getTempCharGfx() == 7554
          || npc.getTempCharGfx() == 7585
          || npc.getTempCharGfx() == 7591) {
        npc.broadcastPacket(new S_NPCPack(npc));
        npc.broadcastPacket(new S_DoActionGFX(npc.getId(), ActionCodes.ACTION_AxeWalk));
      } else if (npc.getTempCharGfx() == 7539
          || npc.getTempCharGfx() == 7557
          || npc.getTempCharGfx() == 7558
          || npc.getTempCharGfx() == 7864
          || npc.getTempCharGfx() == 7869
          || npc.getTempCharGfx() == 7870) {
        for (PcInstance _pc : LsimulatorWorld.getInstance().getVisiblePlayer(npc, 50)) {
          if (npc.getTempCharGfx() == 7539) {
            _pc.sendPackets(new S_ServerMessage(1570));
          } else if (npc.getTempCharGfx() == 7864) {
            _pc.sendPackets(new S_ServerMessage(1657));
          }
          npc.onPerceive(_pc);
          S_DoActionGFX gfx = new S_DoActionGFX(npc.getId(), ActionCodes.ACTION_AxeWalk);
          _pc.sendPackets(gfx);
        }
        npc.npcSleepTime(ActionCodes.ACTION_AxeWalk, NpcInstance.ATTACK_SPEED);
      } else if (npc.getTempCharGfx() == 145) { // 史巴托
        npc.setStatus(11);
        npc.broadcastPacket(new S_NPCPack(npc));
        npc.broadcastPacket(new S_DoActionGFX(npc.getId(), ActionCodes.ACTION_Appear));
        npc.setStatus(0);
        npc.broadcastPacket(new S_CharVisualUpdate(npc, npc.getStatus()));
      }

      npc.turnOnOffLight();
      npc.startChat(NpcInstance.CHAT_TIMING_APPEARANCE); // チャット開始
      if (0 < timeMillisToDelete) {
        LsimulatorNpcDeleteTimer timer = new LsimulatorNpcDeleteTimer(npc, timeMillisToDelete);
        timer.begin();
      }
    } catch (Exception e) {
      _log.log(Level.SEVERE, e.getLocalizedMessage(), e);
    }
  }
  /**
   * TreasureBoxを開けるPCにアイテムを入手させる。PCがアイテムを持ちきれなかった場合は アイテムは地面に落ちる。
   *
   * @param pc - TreasureBoxを開けるPC
   * @return 開封した結果何らかのアイテムが出てきた場合はtrueを返す。 持ちきれず地面に落ちた場合もtrueになる。
   */
  public boolean open(PcInstance pc) {
    ItemInstance item = null;

    if (getType().equals(TYPE.SPECIFIC)) {
      // 出るアイテムが決まっているもの
      for (Item each : getItems()) {
        item = ItemTable.getInstance().createItem(each.getItemId());
        item.setEnchantLevel(each.getEnchant()); // Enchant Feature for treasure_box
        if (item != null) {
          item.setCount(each.getCount());
          storeItem(pc, item);
        }
      }

    } else if (getType().equals(TYPE.RANDOM)) {
      // 出るアイテムがランダムに決まるもの
      int chance = 0;

      int r = Random.nextInt(getTotalChance());

      for (Item each : getItems()) {
        chance += each.getChance();

        if (r < chance) {
          item = ItemTable.getInstance().createItem(each.getItemId());
          item.setEnchantLevel(each.getEnchant()); // Enchant Feature for treasure_box
          if (item != null) {
            item.setCount(each.getCount());
            storeItem(pc, item);
          }
          break;
        }
      }
    }

    if (item == null) {
      return false;
    } else {
      int itemId = getBoxId();

      // 魂の結晶の破片、魔族のスクロール、ブラックエントの実
      if ((itemId == 40576)
          || (itemId == 40577)
          || (itemId == 40578)
          || (itemId == 40411)
          || (itemId == 49013)) {
        pc.death(null); // キャラクターを死亡させる
      }

      // 多魯嘉之袋
      if ((itemId == 46000)) {
        ItemInstance box = pc.getInventory().findItemId(itemId);
        box.setChargeCount(box.getChargeCount() - 1);
        pc.getInventory().updateItem(box, LsimulatorPcInventory.COL_CHARGE_COUNT);
        if (box.getChargeCount() < 1) {
          pc.getInventory().removeItem(box, 1);
        }
      }

      return true;
    }
  }
 @Override
 public void execute(PcInstance pc, String cmdName, String arg) {
   pc.setGm(!pc.isGm());
   pc.sendPackets(new S_SystemMessage("setGm = " + pc.isGm()));
 }