/*
* 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 3 of the License, or (at your option) any later version. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If
* not, see <http://www.gnu.org/licenses/>.
*/
package silentium.scripts.handlers.skill;
import silentium.commons.utils.Rnd;
import silentium.gameserver.configs.MainConfig;
import silentium.gameserver.geo.GeoData;
import silentium.gameserver.handler.ISkillHandler;
import silentium.gameserver.instancemanager.ZoneManager;
import silentium.gameserver.model.L2ItemInstance;
import silentium.gameserver.model.L2Object;
import silentium.gameserver.model.L2Skill;
import silentium.gameserver.model.actor.L2Character;
import silentium.gameserver.model.actor.instance.L2PcInstance;
import silentium.gameserver.model.itemcontainer.Inventory;
import silentium.gameserver.model.zone.L2ZoneType;
import silentium.gameserver.model.zone.type.L2FishingZone;
import silentium.gameserver.model.zone.type.L2WaterZone;
import silentium.gameserver.network.SystemMessageId;
import silentium.gameserver.network.serverpackets.InventoryUpdate;
import silentium.gameserver.templates.item.L2Weapon;
import silentium.gameserver.templates.item.L2WeaponType;
import silentium.gameserver.templates.skills.L2SkillType;
import silentium.gameserver.utils.Util;
public class Fishing implements ISkillHandler {
private static final L2SkillType[] SKILL_IDS = { L2SkillType.FISHING };
@Override
public void useSkill(final L2Character activeChar, final L2Skill skill, final L2Object... targets) {
if (!(activeChar instanceof L2PcInstance))
return;
final L2PcInstance player = (L2PcInstance) activeChar;
/*
* If fishing is disabled, there isn't much point in doing anything else, unless you are GM. so this got moved up here, before anything
* else.
*/
if (!MainConfig.ALLOWFISHING) {
player.sendMessage("Fishing feature is disabled on this server.");
return;
}
if (player.isFishing()) {
if (player.getFishCombat() != null)
player.getFishCombat().doDie(false);
else
player.endFishing(false);
// Cancels fishing
player.sendPacket(SystemMessageId.FISHING_ATTEMPT_CANCELLED);
return;
}
// Fishing poles arent installed
final L2Weapon weaponItem = player.getActiveWeaponItem();
if (weaponItem == null || weaponItem.getItemType() != L2WeaponType.FISHINGROD) {
player.sendPacket(SystemMessageId.FISHING_POLE_NOT_EQUIPPED);
return;
}
// Baits arent equipped
final L2ItemInstance lure = player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
if (lure == null) {
player.sendPacket(SystemMessageId.BAIT_ON_HOOK_BEFORE_FISHING);
return;
}
player.setLure(lure);
L2ItemInstance lure2 = player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
// Not enough baits
if (lure2 == null || lure2.getCount() < 1) {
player.sendPacket(SystemMessageId.NOT_ENOUGH_BAIT);
return;
}
// You can't fish while you are on boat
if (player.isInBoat()) {
player.sendPacket(SystemMessageId.CANNOT_FISH_ON_BOAT);
return;
}
if (player.isInCraftMode() || player.isInStoreMode()) {
player.sendPacket(SystemMessageId.CANNOT_FISH_WHILE_USING_RECIPE_BOOK);
return;
}
// You can't fish in water
if (player.isInsideZone(L2Character.ZONE_WATER)) {
player.sendPacket(SystemMessageId.CANNOT_FISH_UNDER_WATER);
return;
}
/*
* If fishing is enabled, decide where will the hook be cast...
*/
final int rnd = Rnd.get(150) + 50;
final double angle = Util.convertHeadingToDegree(player.getHeading());
final double radian = Math.toRadians(angle);
final double sin = Math.sin(radian);
final double cos = Math.cos(radian);
final int x = player.getX() + (int) (cos * rnd);
final int y = player.getY() + (int) (sin * rnd);
int z = player.getZ() + 50;
/*
* ...and if the spot is in a fishing zone. If it is, it will position the hook on the water surface. If not, you have to be GM to
* proceed past here... in that case, the hook will be positioned using the old Z lookup method.
*/
L2FishingZone aimingTo = null;
L2WaterZone water = null;
boolean canFish = false;
for (final L2ZoneType zone : ZoneManager.getInstance().getZones(x, y)) {
if (zone instanceof L2FishingZone) {
aimingTo = (L2FishingZone) zone;
continue;
}
if (zone instanceof L2WaterZone)
water = (L2WaterZone) zone;
}
if (aimingTo != null) {
// fishing zone found, we can fish here
if (MainConfig.GEODATA > 0) {
// geodata enabled, checking if we can see end of the pole
if (GeoData.getInstance().canSeeTarget(player.getX(), player.getY(), z, x, y, z)) {
// finding z level for hook
if (water != null) {
// water zone exist
if (GeoData.getInstance().getHeight(x, y, z) < water.getWaterZ()) {
// water Z is higher than geo Z
z = water.getWaterZ() + 10;
canFish = true;
}
} else {
// no water zone, using fishing zone
if (GeoData.getInstance().getHeight(x, y, z) < aimingTo.getWaterZ()) {
// fishing Z is higher than geo Z
z = aimingTo.getWaterZ() + 10;
canFish = true;
}
}
}
}
// geodata disabled
else {
// if water zone exist using it, if not - using fishing zone
z = water != null ? water.getWaterZ() + 10 : aimingTo.getWaterZ() + 10;
canFish = true;
}
}
if (!canFish) {
// You can't fish here
player.sendPacket(SystemMessageId.CANNOT_FISH_HERE);
return;
}
// Has enough bait, consume 1 and update inventory. Start fishing follows.
lure2 = player.getInventory().destroyItem("Consume", player.getInventory().getPaperdollObjectId(Inventory.PAPERDOLL_LHAND), 1, player, null);
final InventoryUpdate iu = new InventoryUpdate();
iu.addModifiedItem(lure2);
player.sendPacket(iu);
// If everything else checks out, actually cast the hook and start fishing... :P
player.startFishing(x, y, z);
}
@Override
public L2SkillType[] getSkillIds() {
return SKILL_IDS;
}
}