/* * This file is part of the OdinMS Maple Story Server Copyright (C) 2008 ~ 2010 * Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan * Christian Meyer <vimes@odinms.de> * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by * the Free Software Foundation. You may not use, modify or distribute this * program under any other version of the GNU Affero General Public License. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package javastory.scripting; import java.awt.Point; import java.util.Iterator; import java.util.List; import com.google.common.collect.Lists; import javastory.channel.ChannelClient; import javastory.channel.ChannelServer; import javastory.channel.life.LifeFactory; import javastory.channel.maps.ItemDropType; import javastory.channel.maps.Reactor; import javastory.game.Equip; import javastory.game.GameConstants; import javastory.game.InventoryType; import javastory.game.Item; import javastory.game.data.ItemInfoProvider; import javastory.game.data.ReactorDropEntry; public class ReactorActionManager extends AbstractPlayerInteraction { private final Reactor reactor; public ReactorActionManager(final ChannelClient c, final Reactor reactor) { super(c); this.reactor = reactor; } // only used for meso = false, really. No minItems because meso is used to // fill the gap public void dropItems() { this.dropItems(false, 0, 0, 0, 0); } public void dropItems(final boolean meso, final int mesoChance, final int minMeso, final int maxMeso) { this.dropItems(meso, mesoChance, minMeso, maxMeso, 0); } public void dropItems(final boolean meso, final int mesoChance, final int minMeso, final int maxMeso, final int minItems) { final List<ReactorDropEntry> chances = ReactorScriptManager.getInstance().getDrops(this.reactor.getReactorId()); final List<ReactorDropEntry> items = Lists.newLinkedList(); if (meso) { if (Math.random() < 1 / (double) mesoChance) { items.add(new ReactorDropEntry(0, mesoChance, -1)); } } int numItems = 0; // narrow list down by chances final Iterator<ReactorDropEntry> iter = chances.iterator(); // for (DropEntry d : chances){ while (iter.hasNext()) { final ReactorDropEntry d = iter.next(); if (Math.random() < 1 / (double) d.chance) { numItems++; items.add(d); } } // if a minimum number of drops is required, add meso while (items.size() < minItems) { items.add(new ReactorDropEntry(0, mesoChance, -1)); numItems++; } final Point dropPos = this.reactor.getPosition(); dropPos.x -= 12 * numItems; int range, mesoDrop; final ItemInfoProvider ii = ItemInfoProvider.getInstance(); for (final ReactorDropEntry d : items) { if (d.itemId == 0) { range = maxMeso - minMeso; final double randomMeso = Math.random() * range + minMeso; final float mesoRate = ChannelServer.getInstance().getMesoRate(); mesoDrop = (int) (randomMeso * mesoRate); this.reactor.getMap().spawnMesoDrop(mesoDrop, dropPos, this.reactor, this.getPlayer(), false, ItemDropType.DEFAULT); } else { Item drop; if (GameConstants.getInventoryType(d.itemId) != InventoryType.EQUIP) { drop = new Item(d.itemId, (byte) 0, (short) 1, (byte) 0); } else { drop = ii.randomizeStats((Equip) ii.getEquipById(d.itemId)); } this.reactor.getMap().spawnItemDrop(this.reactor, this.getPlayer(), drop, dropPos, false, false); } dropPos.x += 25; } } // summon one monster on reactor location public void spawnMonster(final int id) { this.spawnMonster(id, 1, this.getPosition()); } // summon one monster, remote location public void spawnMonster(final int id, final int x, final int y) { this.spawnMonster(id, 1, new Point(x, y)); } // multiple monsters, reactor location public void spawnMonster(final int id, final int qty) { this.spawnMonster(id, qty, this.getPosition()); } // multiple monsters, remote location public void spawnMonster(final int id, final int qty, final int x, final int y) { this.spawnMonster(id, qty, new Point(x, y)); } // handler for all spawnMonster private void spawnMonster(final int id, final int qty, final Point pos) { for (int i = 0; i < qty; i++) { this.reactor.getMap().spawnMonsterOnGroundBelow(LifeFactory.getMonster(id), pos); } } @Override public void spawnNpc(final int npcId) { this.spawnNpc(npcId, this.getPosition()); } // returns slightly above the reactor's position for monster spawns public Point getPosition() { final Point pos = this.reactor.getPosition(); pos.y -= 10; return pos; } public Reactor getReactor() { return this.reactor; } public void spawnZakum() { this.reactor.getMap().spawnZakum(this.getPosition()); } public void spawnFakeMonster(final int id) { this.spawnFakeMonster(id, 1, this.getPosition()); } // summon one monster, remote location public void spawnFakeMonster(final int id, final int x, final int y) { this.spawnFakeMonster(id, 1, new Point(x, y)); } // multiple monsters, reactor location public void spawnFakeMonster(final int id, final int qty) { this.spawnFakeMonster(id, qty, this.getPosition()); } // multiple monsters, remote location public void spawnFakeMonster(final int id, final int qty, final int x, final int y) { this.spawnFakeMonster(id, qty, new Point(x, y)); } // handler for all spawnFakeMonster private void spawnFakeMonster(final int id, final int qty, final Point pos) { for (int i = 0; i < qty; i++) { this.reactor.getMap().spawnFakeMonsterOnGroundBelow(LifeFactory.getMonster(id), pos); } } public void killAll() { this.reactor.getMap().killAllMonsters(true); } public void killMonster(final int monsId) { this.reactor.getMap().killMonster(monsId); } }